﻿/* ============================================================
   ChairHog — custom styles on top of the Valex template.
   This is the ONLY custom stylesheet. Never edit styles.min.css.
   Load after styles.min.css:
     <link href="../assets/css/chairhog.css" rel="stylesheet">
   ============================================================ */

/* ------------------------------------------------------------
   1. Brand palette
   ------------------------------------------------------------
   Master brand colours (brand-kit/README.md):
     green #98C11D · ink #23272B · dark #1E1F20

   The brand green is a bright yellow-green: white text on it is
   only 2.1:1, so it cannot drive the template's --primary, whose
   solid surfaces (.btn-primary, .bg-primary + .text-fixed-white)
   hardcode white text. The palette therefore splits in two:

     --primary-rgb  #5E7D0E  deep green for SOLID surfaces
                             white text 4.76:1 (WCAG AA) and
                             as text on white 4.76:1 (AA)
     --ch-green     #98C11D  the true brand green, used where it
                             is legible: on dark surfaces (7.7:1),
                             as a fill behind ink text (7.2:1),
                             and as the primary chart series
   ------------------------------------------------------------ */

:root {
  /* brand masters */
  --ch-green: #98C11D;
  --ch-green-rgb: 152, 193, 29;
  --ch-green-deep: #5E7D0E;
  --ch-ink: #23272B;
  --ch-dark: #1E1F20;

  /* drive the template's primary from the brand */
  --primary-rgb: 94, 125, 14;
}

/* Bright brand green reads well on dark surfaces, so promote it
   to the text/icon accent once the app is in dark mode. Solid
   surfaces keep --primary-rgb so .btn-primary's white text stays
   legible in both modes. */
[data-theme-mode="dark"] .text-primary,
[data-theme-mode="dark"] a.text-primary:hover {
  color: var(--ch-green) !important;
}

/* Brand-green accent helpers. Always pair the green fill with ink
   text — never white. */
.bg-ch-green {
  background-color: var(--ch-green) !important;
  color: var(--ch-ink) !important;
}

.text-ch-green {
  color: var(--ch-green-deep) !important;
}

[data-theme-mode="dark"] .text-ch-green {
  color: var(--ch-green) !important;
}

/* ------------------------------------------------------------
   2. Booking status colours
   ------------------------------------------------------------
   One vocabulary shared by the dashboard, today's service list,
   the bookings table and the calendar, so a status is the same
   colour everywhere. Soft tints (10% fill + saturated text) keep
   contrast in both light and dark mode.
   ------------------------------------------------------------ */

:root {
  --ch-status-booked-rgb: 1, 98, 232;     /* confirmed, not yet arrived */
  --ch-status-seated-rgb: 94, 125, 14;    /* in service now             */
  --ch-status-finished-rgb: 95, 109, 136; /* table turned               */
  --ch-status-cancelled-rgb: 238, 51, 94; /* guest cancelled            */
  --ch-status-noshow-rgb: 253, 126, 20;   /* never arrived              */
  --ch-status-pending-rgb: 156, 39, 176;  /* private hire, awaiting the guest's email */
  --ch-status-expired-rgb: 108, 117, 125; /* private hire request that lapsed         */
}

[data-theme-mode="dark"] {
  /* lift the darker hues so they stay readable on the dark body */
  --ch-status-seated-rgb: var(--ch-green-rgb);
  --ch-status-finished-rgb: 148, 160, 182;
}

.ch-status {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .25rem .55rem;
  border-radius: .25rem;
  font-size: .75rem;
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
}

.ch-status::before {
  content: "";
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background-color: currentColor;
  flex-shrink: 0;
}

.ch-status-booked {
  background-color: rgba(var(--ch-status-booked-rgb), .12);
  color: rgb(var(--ch-status-booked-rgb));
}

.ch-status-seated {
  background-color: rgba(var(--ch-status-seated-rgb), .14);
  color: rgb(var(--ch-status-seated-rgb));
}

.ch-status-finished {
  background-color: rgba(var(--ch-status-finished-rgb), .14);
  color: rgb(var(--ch-status-finished-rgb));
}

.ch-status-cancelled {
  background-color: rgba(var(--ch-status-cancelled-rgb), .12);
  color: rgb(var(--ch-status-cancelled-rgb));
}

.ch-status-noshow {
  background-color: rgba(var(--ch-status-noshow-rgb), .14);
  color: rgb(var(--ch-status-noshow-rgb));
}

.ch-status-pending {
  background-color: rgba(var(--ch-status-pending-rgb), .12);
  color: rgb(var(--ch-status-pending-rgb));
}

.ch-status-expired {
  background-color: rgba(var(--ch-status-expired-rgb), .14);
  color: rgb(var(--ch-status-expired-rgb));
}

/* ------------------------------------------------------------
   3. Chrome tweaks
   ------------------------------------------------------------ */

/* Keep focus rings visible on the brand green for keyboard users. */
.btn:focus-visible,
.header-link:focus-visible,
.side-menu__item:focus-visible {
  outline: 2px solid var(--ch-green);
  outline-offset: 2px;
}

/* ------------------------------------------------------------
   4. Floor designer (floor-designer.html)
   ------------------------------------------------------------
   The floor is a fixed 1000x720 design space scaled to fit its
   container, so table x/y coordinates in the mock data mean the
   same thing at every screen size.
   ------------------------------------------------------------ */

.ch-floor {
  position: relative;
  width: 100%;
  aspect-ratio: 1000 / 720;
  border: 1px solid var(--default-border);
  border-radius: .5rem;
  background-color: var(--custom-white);
  background-image:
    linear-gradient(to right, rgba(128, 128, 128, .12) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(128, 128, 128, .12) 1px, transparent 1px);
  background-size: 5% 6.94%;
  overflow: hidden;
  container-type: inline-size;
}

.ch-table {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--ch-green-deep);
  background-color: rgba(var(--ch-green-rgb), .16);
  color: var(--ch-ink);
  cursor: grab;
  user-select: none;
  line-height: 1.1;
  text-align: center;
  transition: box-shadow .15s ease, border-color .15s ease;
}

[data-theme-mode="dark"] .ch-table {
  color: rgba(255, 255, 255, .9);
  border-color: var(--ch-green);
  background-color: rgba(var(--ch-green-rgb), .22);
}

.ch-table:hover { box-shadow: 0 4px 14px rgba(0, 0, 0, .18); }
.ch-table:focus-visible,
.ch-table.is-selected {
  outline: none;
  border-color: var(--ch-green);
  box-shadow: 0 0 0 3px rgba(var(--ch-green-rgb), .5);
}
.ch-table.is-dragging { cursor: grabbing; opacity: .75; }

/* Shapes: round tables are circles, rectangles keep a soft corner. */
.ch-table[data-shape="round-sm"],
.ch-table[data-shape="round-lg"] { border-radius: 50%; }
.ch-table[data-shape="square"],
.ch-table[data-shape="rect"] { border-radius: .375rem; }

.ch-table .ch-table-name { font-weight: 600; font-size: clamp(9px, 1.4cqw, 14px); }
.ch-table .ch-table-seats { font-size: clamp(8px, 1.1cqw, 12px); opacity: .75; }

/* Palette of draggable shapes */
.ch-palette { display: grid; grid-template-columns: repeat(2, 1fr); gap: .5rem; }

.ch-palette-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .25rem;
  padding: .75rem .5rem;
  border: 1px dashed var(--default-border);
  border-radius: .375rem;
  background: none;
  color: inherit;
  cursor: grab;
  font-size: .75rem;
}

.ch-palette-item:hover,
.ch-palette-item:focus-visible {
  border-color: var(--ch-green);
  background-color: rgba(var(--ch-green-rgb), .1);
}

.ch-palette-swatch {
  border: 2px solid var(--ch-green-deep);
  background-color: rgba(var(--ch-green-rgb), .18);
}
[data-theme-mode="dark"] .ch-palette-swatch { border-color: var(--ch-green); }
.ch-palette-swatch[data-shape="round-sm"],
.ch-palette-swatch[data-shape="round-lg"] { border-radius: 50%; }
.ch-palette-swatch[data-shape="square"],
.ch-palette-swatch[data-shape="rect"] { border-radius: .25rem; }

/* ------------------------------------------------------------
   5. Guest booking widget (widget.html)
   ------------------------------------------------------------
   This is the only ChairHog surface a guest ever sees, and it sits
   inside the client's own website. It therefore does NOT use the
   admin theme: its tokens are the ones the AI style scan produced
   for The Copper Fork (see widget-style.html), so the two pages
   agree. In the real product this block is generated per client.

   Design is mobile-first: the layout is built for 375px and simply
   gains breathing room above 480px.
   ------------------------------------------------------------ */

/* The widget page (_WidgetLayout) loads no framework CSS, so the browser default is
   content-box — and a width:100% input plus its padding and border then overflows the
   card it sits in (the guest-details step showed it). Border-box everywhere inside the
   widget keeps every control contained, exactly as Bootstrap does for the admin. */
.ch-widget,
.ch-widget *,
.ch-widget *::before,
.ch-widget *::after {
  box-sizing: border-box;
}

.ch-widget {
  /* tokens the style scan produced for this client */
  --w-accent: #7A4B2A;
  --w-accent-ink: #FFFFFF;
  --w-surface: #FBF9F6;
  --w-card: #FFFFFF;
  --w-text: #2B2621;
  --w-muted: #8A7F73;
  --w-border: #E2DAD0;
  --w-radius: 8px;
  --w-serif: Georgia, "Times New Roman", serif;
  --w-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  min-height: 100dvh;
  margin: 0;
  background: var(--w-surface);
  color: var(--w-text);
  font-family: var(--w-sans);
  -webkit-font-smoothing: antialiased;
}

/* A client with a dark site gets the dark variant of the same palette. */
@media (prefers-color-scheme: dark) {
  .ch-widget {
    --w-surface: #1A1613;
    --w-card: #241E1A;
    --w-text: #F2EBE4;
    --w-muted: #A9998A;
    --w-border: #3A302A;
    --w-accent: #C08457;
    --w-accent-ink: #1A1613;
  }
}

.ch-widget-shell { max-width: 480px; margin: 0 auto; padding: 20px 16px 40px; }

.ch-widget-head { text-align: center; margin-bottom: 20px; }
.ch-widget-head h1 { font-family: var(--w-serif); font-size: 22px; font-weight: 600; margin: 0 0 2px; }
.ch-widget-head p { font-size: 13px; color: var(--w-muted); margin: 0; }

/* Progress: a plain bar plus a step count, not a numbered stepper */
.ch-widget-progress { height: 3px; background: var(--w-border); border-radius: 999px; overflow: hidden; margin-bottom: 8px; }
.ch-widget-progress span { display: block; height: 100%; background: var(--w-accent); transition: width .35s cubic-bezier(.16,1,.3,1); }
.ch-widget-stepline { display: flex; justify-content: space-between; font-size: 11px; color: var(--w-muted); margin-bottom: 18px; }

.ch-widget-card {
  background: var(--w-card);
  border: 1px solid var(--w-border);
  border-radius: var(--w-radius);
  padding: 18px 16px;
}

.ch-widget h2 { font-family: var(--w-serif); font-size: 17px; font-weight: 600; margin: 0 0 4px; }
.ch-widget .ch-widget-hint { font-size: 12.5px; color: var(--w-muted); margin: 0 0 16px; }

/* Option rows (sites, tables) */
.ch-opt {
  display: flex; align-items: center; gap: 12px; width: 100%;
  background: none; border: 1px solid var(--w-border); border-radius: var(--w-radius);
  padding: 12px 14px; margin-bottom: 8px; text-align: left; color: inherit;
  font: inherit; cursor: pointer; transition: border-color .15s ease, background-color .15s ease;
}
.ch-opt:hover { border-color: var(--w-accent); }
.ch-opt[aria-pressed="true"] { border-color: var(--w-accent); background: color-mix(in srgb, var(--w-accent) 8%, transparent); }
.ch-opt strong { display: block; font-size: 14px; font-weight: 600; }
.ch-opt small { display: block; font-size: 12px; color: var(--w-muted); }

/* Chips (party size, time slots) */
.ch-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ch-chip {
  min-width: 56px; padding: 10px 12px; border: 1px solid var(--w-border); border-radius: var(--w-radius);
  background: none; color: inherit; font: inherit; font-size: 13.5px; cursor: pointer; text-align: center;
  transition: border-color .15s ease, background-color .15s ease, color .15s ease;
}
.ch-chip:hover:not(:disabled) { border-color: var(--w-accent); }
.ch-chip[aria-pressed="true"] { background: var(--w-accent); border-color: var(--w-accent); color: var(--w-accent-ink); }
.ch-chip:disabled { opacity: .35; cursor: not-allowed; text-decoration: line-through; }

.ch-slot-group { margin-bottom: 16px; }
.ch-slot-group h3 { font-size: 12px; font-weight: 600; color: var(--w-muted); margin: 0 0 8px; }

/* Fields */
.ch-field { margin-bottom: 14px; }
.ch-field label { display: block; font-size: 12.5px; font-weight: 600; margin-bottom: 5px; }
.ch-field input, .ch-field textarea, .ch-field select {
  width: 100%; padding: 11px 12px; font: inherit; font-size: 14px;
  color: var(--w-text); background: var(--w-card);
  border: 1px solid var(--w-border); border-radius: var(--w-radius);
}
.ch-field input:focus-visible, .ch-field textarea:focus-visible, .ch-field select:focus-visible {
  outline: 2px solid var(--w-accent); outline-offset: 1px; border-color: var(--w-accent);
}
.ch-field .ch-help { font-size: 11.5px; color: var(--w-muted); margin: 4px 0 0; }
.ch-field .ch-error { font-size: 11.5px; color: #B3261E; margin: 4px 0 0; }
@media (prefers-color-scheme: dark) { .ch-field .ch-error { color: #F2B8B5; } }
.ch-field.is-invalid input, .ch-field.is-invalid textarea { border-color: #B3261E; }

.ch-check { display: flex; gap: 9px; align-items: flex-start; font-size: 12.5px; margin-bottom: 14px; }
.ch-check input { width: 16px; height: 16px; margin-top: 2px; flex-shrink: 0; accent-color: var(--w-accent); }

/* Buttons */
.ch-btn {
  width: 100%; padding: 13px; border: 0; border-radius: var(--w-radius);
  background: var(--w-accent); color: var(--w-accent-ink);
  font: inherit; font-size: 14px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  cursor: pointer; transition: transform .1s ease, opacity .15s ease;
}
.ch-btn:active { transform: translateY(1px); }
.ch-btn:disabled { opacity: .4; cursor: not-allowed; }
.ch-btn-quiet {
  background: none; color: var(--w-muted); border: 1px solid var(--w-border);
  text-transform: none; letter-spacing: 0; font-weight: 500;
}
.ch-btn-row { display: flex; gap: 8px; margin-top: 16px; }
.ch-btn-row .ch-btn { flex: 1; }
.ch-btn-row .ch-btn-quiet { flex: 0 0 96px; }

/* Summary strip that follows the guest down the flow */
.ch-summary {
  display: flex; flex-wrap: wrap; gap: 6px 14px;
  font-size: 12px; color: var(--w-muted); margin-bottom: 14px;
}
.ch-summary b { color: var(--w-text); font-weight: 600; }

/* Mini floor plan for the optional table pick */
.ch-mini-floor {
  position: relative; width: 100%; aspect-ratio: 1000 / 720;
  border: 1px solid var(--w-border); border-radius: var(--w-radius);
  background: var(--w-surface); overflow: hidden; margin-bottom: 12px;
}
.ch-mini-table {
  position: absolute; display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--w-border); background: var(--w-card); color: var(--w-text);
  font-size: 9px; font-weight: 600; cursor: pointer; padding: 0;
}
.ch-mini-table[data-shape="round-sm"], .ch-mini-table[data-shape="round-lg"] { border-radius: 50%; }
.ch-mini-table[data-shape="square"], .ch-mini-table[data-shape="rect"] { border-radius: 4px; }
.ch-mini-table:disabled { opacity: .3; cursor: not-allowed; }
.ch-mini-table[aria-pressed="true"] { background: var(--w-accent); border-color: var(--w-accent); color: var(--w-accent-ink); }
.ch-mini-table:focus-visible { outline: 2px solid var(--w-accent); outline-offset: 2px; }

/* Confirmation */
.ch-done { text-align: center; }
.ch-done-mark {
  width: 52px; height: 52px; border-radius: 50%; margin: 0 auto 14px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--w-accent) 14%, transparent); color: var(--w-accent); font-size: 24px;
}
.ch-ref {
  display: inline-block; font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 13px; letter-spacing: .08em;
  background: var(--w-surface); border: 1px dashed var(--w-border);
  border-radius: var(--w-radius); padding: 7px 12px; margin: 4px 0 16px;
}
.ch-detail-list { list-style: none; margin: 0 0 18px; padding: 0; text-align: left; }
.ch-detail-list li { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--w-border); font-size: 13px; }
.ch-detail-list li:last-child { border-bottom: 0; }
.ch-detail-list span { color: var(--w-muted); }

/* The demo's "your booking has been made" pop (chairhog-widget.js, demo mode
   only). Fixed to the widget's own viewport, so it covers the iframe the
   snippet created, wherever that iframe is. */
.ch-demo-pop {
  position: fixed; inset: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, .45);
}
.ch-demo-pop-card {
  max-width: 380px; width: 100%;
  background: var(--w-card); color: var(--w-text);
  border: 1px solid var(--w-border); border-radius: var(--w-radius);
  padding: 26px 22px; text-align: center;
  box-shadow: 0 18px 48px rgba(0, 0, 0, .35);
  animation: ch-demo-pop-in .25s cubic-bezier(.16, 1, .3, 1);
}
.ch-demo-pop-card h2 { font-family: var(--w-serif); font-size: 19px; font-weight: 600; margin: 0 0 8px; }
.ch-demo-pop-card p { font-size: 13px; color: var(--w-muted); margin: 0 0 18px; }
@keyframes ch-demo-pop-in {
  from { opacity: 0; transform: translateY(8px) scale(.97); }
  to { opacity: 1; transform: none; }
}

.ch-widget-foot { text-align: center; font-size: 11px; color: var(--w-muted); margin-top: 20px; }
.ch-widget-foot a { color: inherit; }

/* Preview-only bar: hidden when the widget is inside an iframe.
   The [hidden] rule must come after (and match) .ch-preview-bar, otherwise
   this class's `display: flex` overrides the browser's [hidden] default and
   the bar leaks into the embedded copy. */
.ch-preview-bar {
  background: var(--ch-dark); color: #fff; font-size: 12px;
  padding: 8px 14px; display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.ch-preview-bar[hidden] { display: none; }
.ch-preview-bar a { color: var(--ch-green); }

/* Each step moves focus to its heading so screen readers announce the change.
   That focus is programmatic, so only show a ring for real keyboard users. */
.ch-widget h2:focus:not(:focus-visible) { outline: none; }
.ch-widget h2:focus-visible { outline: 2px solid var(--w-accent); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  .ch-widget-progress span, .ch-opt, .ch-chip, .ch-btn { transition: none; }
  .ch-demo-pop-card { animation: none; }
}

/* ------------------------------------------------------------
   6. Fake client website (embed-preview.html)
   ------------------------------------------------------------
   A stand-in for the restaurant's own site, so the client can see
   the widget in context. Its palette matches the one the AI style
   scan produced, not the ChairHog admin theme.
   ------------------------------------------------------------ */

.ch-fakesite {
  border: 1px solid var(--default-border);
  border-radius: .5rem;
  overflow: hidden;
  background: #FBF9F6;
  color: #2B2621;
  font-family: Georgia, "Times New Roman", serif;
}

.ch-fakesite-nav {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .75rem;
  padding: .875rem 1.25rem; border-bottom: 1px solid #E2DAD0;
}
.ch-fakesite-brand { font-size: 1.05rem; font-weight: 600; letter-spacing: .01em; }
.ch-fakesite-nav nav { display: flex; gap: 1.1rem; flex-wrap: wrap; }
.ch-fakesite-nav a {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: .78rem; color: #8A7F73; text-decoration: none;
}
.ch-fakesite-nav a:hover { color: #7A4B2A; }
.ch-fakesite-nav a.is-cta {
  color: #fff; background: #7A4B2A; padding: .3rem .7rem; border-radius: 8px;
}

.ch-fakesite-hero { padding: 2.25rem 1.25rem 1.5rem; max-width: 46rem; }
.ch-fakesite-kicker {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: .7rem; letter-spacing: .12em; text-transform: uppercase; color: #8A7F73; margin: 0 0 .5rem;
}
.ch-fakesite-hero h2 { font-size: clamp(1.35rem, 3.2vw, 2rem); line-height: 1.2; margin: 0 0 .6rem; font-weight: 600; }
.ch-fakesite-lede {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: .875rem; color: #6B6158; margin: 0; max-width: 34rem; line-height: 1.6;
}

.ch-fakesite-embed { padding: 0 1.25rem 1.25rem; }
.ch-fakesite-embed iframe {
  width: 100%; height: 640px; border: 1px solid #E2DAD0; border-radius: 8px; background: #FBF9F6;
  display: block;
}

.ch-fakesite-foot {
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: .5rem;
  padding: .875rem 1.25rem; border-top: 1px solid #E2DAD0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: .72rem; color: #8A7F73;
}

/* ------------------------------------------------------------
   7. Authentication pages (Auth/*, _AuthLayout.cshtml)
   ------------------------------------------------------------
   Split screen: a dark brand panel on the left (hidden below lg,
   where the form takes the full width) and the form on the right.

   The brand panel is one of the few places the true brand green
   is used at full strength — it sits on --ch-dark at 7.7:1, well
   clear of AA. The form side stays on template tokens so dark
   mode comes for free.
   ------------------------------------------------------------ */

.ch-auth {
  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
}

/* ---- brand panel ---- */
.ch-auth__aside {
  display: none;
  flex: 0 0 42%;
  max-width: 42%;
  position: relative;
  padding: 3rem;
  background-color: var(--ch-dark);
  color: #fff;
  overflow: hidden;
}

@media (min-width: 992px) {
  .ch-auth__aside { display: flex; flex-direction: column; }
}

/* Soft green glow, purely decorative. */
.ch-auth__aside::after {
  content: "";
  position: absolute;
  inset: auto -30% -35% auto;
  width: 34rem;
  height: 34rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--ch-green-rgb), .22) 0%, rgba(var(--ch-green-rgb), 0) 70%);
  pointer-events: none;
}

/* The pitch sits under the logo at the top of the panel (not pushed to the bottom of
   the column), so it reads first however tall the form beside it is. */
.ch-auth__aside-inner { position: relative; z-index: 1; margin-top: 3rem; }

/* The lockup is built from the two separate files rather than taken from
   chairhog-logo-*.svg: that one stacks the pig above the wordmark into a nearly
   square block (1983x1936), so at header height its wordmark is illegible. Side
   by side, the pig reads at 2.5rem and the wordmark keeps the 1.75rem it has
   everywhere else. align-self stops the flex column stretching the link full width. */
.ch-auth__logo {
  display: flex;
  align-items: center;
  gap: .75rem;
  align-self: flex-start;
  text-decoration: none;
  border-radius: .5rem;
}

.ch-auth__logo-mark { height: 2.5rem; width: auto; }
.ch-auth__logo-word { height: 1.5rem; width: auto; }

.ch-auth__logo:focus-visible { outline: 2px solid var(--ch-green); outline-offset: .375rem; }

.ch-auth__pitch {
  margin: 0 0 .75rem;
  font-size: 1.75rem;
  line-height: 1.25;
  font-weight: 600;
  color: #fff;
  max-width: 22ch;
}

.ch-auth__pitch em { font-style: normal; color: var(--ch-green); }

.ch-auth__sub { color: rgba(255, 255, 255, .72); font-size: .875rem; max-width: 44ch; }

.ch-auth__points { list-style: none; margin: 2rem 0 0; padding: 0; }

.ch-auth__points li {
  display: flex;
  align-items: flex-start;
  gap: .625rem;
  margin-bottom: .875rem;
  font-size: .8125rem;
  color: rgba(255, 255, 255, .8);
}

.ch-auth__points i { color: var(--ch-green); font-size: 1rem; line-height: 1.25; }

/* ---- form side ---- */

/* The way back out to the public site, on every auth page at every width. The
   brand panel links home too, but it is hidden below lg. */
.ch-auth__top { display: flex; justify-content: flex-end; }

.ch-auth__main {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  padding: 1.5rem;
  background-color: rgb(var(--body-bg-rgb));
}

.ch-auth__body {
  margin: auto;
  width: 100%;
  max-width: 26rem;
}

/* The lockup above the form, shown only when the brand panel is not. Same pig +
   wordmark pairing as the panel, a shade smaller. */
.ch-auth__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .625rem;
  margin-bottom: 1.5rem;
}

.ch-auth__mark-pig { height: 2.25rem; width: auto; }
.ch-auth__mark-word { height: 1.375rem; width: auto; }

/* This side follows the theme, so the ink half of the lockup has to as well —
   the -light files are inked #23272B and would all but vanish on the dark body.
   Swapping the file through `content` keeps it to two lines and one <img> each. */
[data-theme-mode="dark"] .ch-auth__mark-pig { content: url("../images/brand-kit/svg/chairhog-mark-dark.svg"); }
[data-theme-mode="dark"] .ch-auth__mark-word { content: url("../images/brand-kit/svg/chairhog-wordmark-dark.svg"); }

@media (min-width: 992px) { .ch-auth__mark { display: none; } }

/* Anchors the form against the body tint, and matches the card language the
   rest of the app is built from. */
.ch-auth__card {
  padding: 2rem;
  border: 1px solid var(--default-border);
  border-radius: .75rem;
  background-color: var(--custom-white);
  box-shadow: 0 .25rem 1rem rgba(0, 0, 0, .04);
}

@media (max-width: 575.98px) {
  .ch-auth__card { padding: 1.5rem; border: 0; background-color: transparent; box-shadow: none; }
}

.ch-auth__title { font-size: 1.375rem; font-weight: 600; margin-bottom: .25rem; }
.ch-auth__lede { color: var(--text-muted); font-size: .8125rem; margin-bottom: 1.75rem; }

.ch-auth__foot {
  margin-top: 1.75rem;
  text-align: center;
  font-size: .8125rem;
  color: var(--text-muted);
}

.ch-auth__legal {
  padding-top: 1rem;
  text-align: center;
  font-size: .75rem;
  color: var(--text-muted);
}

/* ---- the account being signed in to, shown on the password/MFA steps ---- */
.ch-auth__who {
  display: flex;
  align-items: center;
  gap: .625rem;
  padding: .625rem .875rem;
  margin-bottom: 1.25rem;
  border: 1px solid var(--default-border);
  border-radius: .5rem;
  background-color: var(--primary005);
  font-size: .8125rem;
}

.ch-auth__who i { color: rgb(var(--primary-rgb)); font-size: 1rem; }

/* ---- password field with a reveal button ---- */
.ch-pass { position: relative; }
.ch-pass .form-control { padding-inline-end: 2.75rem; }

.ch-pass__toggle {
  position: absolute;
  inset-inline-end: 0;
  top: 0;
  height: 100%;
  width: 2.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
}

.ch-pass__toggle:hover { color: rgb(var(--primary-rgb)); }

/* ---- one-time code ---- */
.ch-otp {
  font-size: 1.5rem;
  letter-spacing: .5em;
  text-align: center;
  text-indent: .5em;   /* re-centres: letter-spacing pads the right of the last digit */
  font-variant-numeric: tabular-nums;
  padding-block: .625rem;
}

/* ---- MFA setup: QR code ----
   Big enough to scan from a phone held at arm's length: 17rem (272px) on desktop, the
   full card width on a phone. Crisp edges — the PNG is generated at 20px per module and
   must not be smoothed when scaled. (The hosted booking page's QR is .ch-qr-hosted, a
   separate rule; sharing the class once shrank this one to 140px.) */
.ch-qr {
  display: block;
  width: 100%;
  max-width: 17rem;
  height: auto;
  margin: 0 auto;
  padding: .75rem;
  border: 1px solid var(--default-border);
  border-radius: .625rem;
  background-color: #fff;   /* the QR needs a white quiet zone in both themes */
  image-rendering: pixelated;
}

.ch-secret {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem .75rem;
  border: 1px dashed var(--default-border);
  border-radius: .5rem;
  background-color: var(--primary005);
}

.ch-secret code {
  flex: 1 1 auto;
  font-size: .8125rem;
  letter-spacing: .08em;
  word-break: break-all;
  color: var(--default-text-color);
}

/* ---- steps ---- */
.ch-steps { counter-reset: ch-step; list-style: none; margin: 0 0 1.25rem; padding: 0; }

.ch-steps li {
  counter-increment: ch-step;
  position: relative;
  padding-inline-start: 2rem;
  margin-bottom: .625rem;
  font-size: .8125rem;
  color: var(--text-muted);
}

.ch-steps li::before {
  content: counter(ch-step);
  position: absolute;
  inset-inline-start: 0;
  top: -.0625rem;
  width: 1.375rem;
  height: 1.375rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background-color: rgb(var(--primary-rgb));
  color: #fff;
  font-size: .6875rem;
  font-weight: 600;
}


/* ==========================================================================
   8. Icon-font fallbacks
   --------------------------------------------------------------------------
   styles.min.css draws a few pseudo-element glyphs from icon webfonts that
   ChairHog does not ship (see assets/css/icons.css for the five it does).
   Without these overrides those glyphs render as missing-character boxes.

   Dropping the fonts was deliberate: tabler-icons alone is ~68MB and no page
   uses a ti-* class. Only these CSS-internal glyph references needed cover.
   ========================================================================== */

/* Breadcrumb divider — Valex uses tabler glyph \ea65. Every page header has
   one, so this is the visible one. Plain "»" needs no webfont at all. */
.breadcrumb-item + .breadcrumb-item::before,
.page-header-breadcrumb .breadcrumb-item + .breadcrumb-item::before,
.breadcrumb-example1 .breadcrumb-item + .breadcrumb-item::before,
.breadcrumb-style1 .breadcrumb-item + .breadcrumb-item::before,
.breadcrumb-style2 .breadcrumb-item + .breadcrumb-item::before {
    content: "\00bb" !important;   /* » */
    font-family: inherit !important;
}

/* Accordion chevrons — Valex uses remixicon \ea78 / \ea13 / \f1af. No ChairHog
   page uses an accordion yet; these keep it correct if one is added, using
   Bootstrap Icons, which ChairHog does ship. */
.accordion-button::after {
    content: "\f282" !important;                 /* bi-chevron-down */
    font-family: "bootstrap-icons" !important;
}
.accordion.accordion-customicon1 .accordion-button::after {
    content: "\f4fe" !important;                 /* bi-plus */
    font-family: "bootstrap-icons" !important;
}
.accordion.accordion-customicon1 .accordion-button:not(.collapsed)::after {
    content: "\f2ea" !important;                 /* bi-dash */
    font-family: "bootstrap-icons" !important;
}


/* ==========================================================================
   9. Public website (Marketing/*, _MarketingLayout.cshtml)
   --------------------------------------------------------------------------
   www.chairhog.com — the landing page and the legal pages. This is the only
   part of ChairHog a person can read without signing in, so it is deliberately
   not the admin: wider measure, larger type, no cards-in-a-grid density.

   It is a fixed LIGHT design (the layout pins data-theme-mode="light"), so
   nothing here needs a [data-theme-mode="dark"] counterpart. The dark bands
   are the design, not the theme: --ch-dark grounds the hero, the closing call
   to action and the footer, and those are the three places the true brand
   green is used at full strength, where it clears AA on dark (7.7:1).

   Everything is prefixed .ch-site- so it can never collide with the admin.
   ========================================================================== */

.ch-site {
  background-color: var(--custom-white);
  color: var(--default-text-color);
  /* The admin runs at 14px, which is right for a dense dashboard and wrong for
     a page someone reads on a phone. 16px is the mobile-legibility floor. */
  font-size: 1rem;
  line-height: 1.6;
}

/* ---- shell ---- */
.ch-site-container {
  width: 100%;
  max-width: 71.25rem;
  margin-inline: auto;
  padding-inline: 1.25rem;
}

.ch-site-container--narrow { max-width: 48rem; }

/* Keyboard users get to the content without tabbing the whole menu. */
/* Hidden by moving it UP, never sideways: an element parked at a negative
   inline offset still counts as page content on some engines and can widen the
   document. Vertical is always safe. */
.ch-site-skip {
  position: absolute;
  inset-inline-start: .75rem;
  top: -4rem;
  z-index: 1080;
  padding: .625rem 1rem;
  border-radius: .375rem;
  background-color: var(--ch-dark);
  color: #fff;
  font-size: .875rem;
  text-decoration: none;
}

.ch-site-skip:focus { top: .5rem; color: #fff; }

/* ---- header ---- */
.ch-site-header {
  position: sticky;
  top: 0;
  z-index: 1030;
  background-color: rgba(255, 255, 255, .92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease, box-shadow .2s ease;
}

/* Only once the page has moved — a border under a header sitting on the very
   top of the hero looks like a mistake. Toggled by chairhog-site.js. */
.ch-site-header.is-scrolled {
  border-bottom-color: var(--default-border);
  box-shadow: 0 .125rem .75rem rgba(3, 27, 78, .06);
}

.ch-site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  min-height: 4.5rem;
}

.ch-site-brand { display: inline-flex; align-items: center; margin-inline-end: auto; }
.ch-site-brand img { height: 1.75rem; width: auto; }

.ch-site-burger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;    /* 44px -- the touch-target floor */
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--default-border);
  border-radius: .375rem;
  background: none;
  color: var(--default-text-color);
  font-size: 1.25rem;
}

.ch-site-nav { flex-basis: 100%; }

.ch-site-nav__list {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .25rem;
}

.ch-site-nav__list a {
  display: block;
  padding: .5rem 0;
  color: var(--default-text-color);
  font-size: .9375rem;
  font-weight: 500;
  text-decoration: none;
}

.ch-site-nav__list a:hover { color: rgb(var(--primary-rgb)); }

.ch-site-nav__actions {
  display: flex;
  gap: .5rem;
  margin: 1rem 0;
}

.ch-site-nav__actions .btn { flex: 1 1 auto; }

/* Log out is a POST, so it arrives wrapped in a form. display:contents lifts the
   button into the flex row as if the form were not there. */
.ch-site-nav__actions form { display: contents; }

@media (min-width: 992px) {
  /* Beat .collapse{display:none} — above lg the menu is always on show and the
     burger is gone, so Bootstrap's collapse never runs. */
  .ch-site-nav.collapse:not(.show) { display: flex !important; }

  /* Brand hard left, the menu beside it, the two buttons hard right. */
  .ch-site-nav {
    display: flex;
    flex: 1 1 auto;
    flex-basis: auto;
    align-items: center;
    gap: 2rem;
  }

  .ch-site-nav__actions { margin-inline-start: auto; }

  .ch-site-burger { display: none; }
  .ch-site-brand { margin-inline-end: 0; }
  .ch-site-nav__list { flex-direction: row; gap: 1.75rem; margin: 0; }
  .ch-site-nav__list a { padding: 0; font-size: .875rem; }
  .ch-site-nav__actions { margin-block: 0; }
  .ch-site-nav__actions .btn { flex: 0 0 auto; }
}

/* ---- shared section furniture ---- */
.ch-site-section { padding-block: 3.5rem; }

.ch-site-section--tint { background-color: rgb(var(--body-bg-rgb)); }

@media (min-width: 768px) {
  .ch-site-section { padding-block: 5rem; }
}

.ch-site-eyebrow {
  margin-bottom: .5rem;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ch-green-deep);
}

.ch-site-heading {
  max-width: 44rem;
  margin: 0 auto 2.75rem;
  text-align: center;
}

.ch-site-heading h2 {
  margin-bottom: .75rem;
  font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2.25rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.02em;
}

.ch-site-heading p { margin-bottom: 0; color: var(--text-muted); font-size: 1.0625rem; }

/* Bootstrap's default .btn lands at ~34px, under the 44px touch-target floor,
   and a marketing page is read on a phone more often than not. This puts a
   floor under every button here without disturbing the admin's denser buttons. */
.ch-site .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem;
}

/* A light-on-dark button for the bands where .btn-outline-primary would
   disappear. Never filled — the filled button on a dark band is .btn-primary. */
.ch-site-btn-ghost {
  border: 1px solid rgba(255, 255, 255, .35);
  color: #fff;
  background-color: transparent;
}

.ch-site-btn-ghost:hover,
.ch-site-btn-ghost:focus-visible {
  border-color: var(--ch-green);
  background-color: rgba(255, 255, 255, .08);
  color: #fff;
}

/* Green ticks, used by the widget section and the price card. */
.ch-site-ticks { list-style: none; margin: 0 0 1.75rem; padding: 0; }

.ch-site-ticks li {
  display: flex;
  align-items: flex-start;
  gap: .625rem;
  margin-bottom: .75rem;
  font-size: 1rem;
  line-height: 1.5;
}

.ch-site-ticks i {
  flex-shrink: 0;
  margin-top: .1875rem;
  color: var(--ch-green-deep);
  font-size: 1rem;
}

/* ---- hero ---- */
.ch-site-hero {
  position: relative;
  overflow: hidden;
  padding-block: 3.5rem;
  background-color: var(--ch-dark);
  color: #fff;
}

/* Decorative glow, the same one the sign-in panel uses. */
.ch-site-hero::after {
  content: "";
  position: absolute;
  inset: -20% -25% auto auto;
  width: 44rem;
  height: 44rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--ch-green-rgb), .18) 0%, rgba(var(--ch-green-rgb), 0) 70%);
  pointer-events: none;
}

.ch-site-hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 3rem;
  align-items: center;
}

.ch-site-hero .ch-site-eyebrow { color: var(--ch-green); }

.ch-site-hero__title {
  margin-bottom: 1rem;
  font-size: clamp(2rem, 1.35rem + 3vw, 3.25rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.03em;
  color: #fff;
}

.ch-site-hero__title em { font-style: normal; color: var(--ch-green); }

.ch-site-hero__lede {
  max-width: 34rem;
  margin-bottom: 2rem;
  font-size: 1.0625rem;
  line-height: 1.65;
  color: rgba(255, 255, 255, .74);
}

.ch-site-hero__actions { display: flex; flex-wrap: wrap; gap: .75rem; }

.ch-site-hero__points {
  list-style: none;
  display: flex;
  flex-direction: column;  /* one point per line, never wrapped side by side */
  gap: .625rem;
  margin: 2rem 0 0;
  padding: 0;
  font-size: .875rem;
  color: rgba(255, 255, 255, .78);
}

.ch-site-hero__points li { display: flex; align-items: center; gap: .4375rem; }
.ch-site-hero__points i { color: var(--ch-green); }

@media (min-width: 992px) {
  .ch-site-hero { padding-block: 5.5rem; }
  .ch-site-hero__inner { grid-template-columns: 1fr 1fr; gap: 4rem; }
}

/* ---- hero product illustration ----
   Drawn in markup rather than shipped as a screenshot: it never goes stale as
   the app changes, it costs no bytes, and it stays sharp at any density. It is
   aria-hidden in the view — everything it shows is said in the copy. */
.ch-site-hero__visual { position: relative; }

.ch-site-preview {
  border-radius: .875rem;
  overflow: hidden;
  background-color: #fff;
  color: var(--ch-ink);
  box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, .35);
}

.ch-site-preview__bar {
  display: flex;
  align-items: center;
  gap: .375rem;
  padding: .75rem 1rem;
  background-color: #f4f5f7;
  border-bottom: 1px solid #e6e8ec;
}

.ch-site-preview__bar span {
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background-color: #cdd2da;
}

.ch-site-preview__bar p {
  margin: 0 0 0 .75rem;
  font-size: .75rem;
  font-weight: 500;
  color: #6b7280;
}

.ch-site-preview__stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-bottom: 1px solid #eef0f3;
}

.ch-site-preview__stats div { padding: 1rem; text-align: center; }
.ch-site-preview__stats div + div { border-inline-start: 1px solid #eef0f3; }

.ch-site-preview__stats strong {
  display: block;
  font-size: 1.375rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--ch-ink);
}

.ch-site-preview__stats span { font-size: .6875rem; color: #6b7280; }

.ch-site-preview__list { list-style: none; margin: 0; padding: .5rem; }

.ch-site-preview__list li {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .625rem .75rem;
  border-radius: .5rem;
  font-size: .8125rem;
}

.ch-site-preview__list li:nth-child(odd) { background-color: #fafbfc; }

.ch-site-preview__time {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--ch-ink);
}

.ch-site-preview__who {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #55606f;
}

.ch-site-preview__who strong { color: var(--ch-ink); font-weight: 600; }

/* The "a booking just came in" card, tucked against the lower corner. Kept
   inside the container's own padding so it can never widen the page. */
.ch-site-preview__float {
  position: absolute;
  inset-inline-end: -1rem;
  bottom: -2.75rem;   /* mostly below the card: it must not sit on a status chip */
  padding: .75rem 1rem;
  border-radius: .625rem;
  border-inline-start: 3px solid var(--ch-green);
  background-color: #fff;
  box-shadow: 0 .75rem 1.75rem rgba(0, 0, 0, .28);
}

.ch-site-preview__float-title {
  margin: 0;
  font-size: .8125rem;
  font-weight: 600;
  color: var(--ch-ink);
}

.ch-site-preview__float-body { margin: 0; font-size: .6875rem; color: #6b7280; }

@media (max-width: 575.98px) {
  .ch-site-preview__float { display: none; }
}

/* ---- how it works ---- */
.ch-site-steps {
  list-style: none;
  display: grid;
  gap: 1.5rem;
  margin: 0;
  padding: 0;
  counter-reset: none;
}

.ch-site-steps li {
  padding: 1.75rem;
  border: 1px solid var(--default-border);
  border-radius: .875rem;
  background-color: var(--custom-white);
}

.ch-site-steps__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  margin-bottom: 1rem;
  border-radius: 50%;
  background-color: var(--ch-green);
  color: var(--ch-ink);
  font-weight: 700;
}

.ch-site-steps h3 { margin-bottom: .5rem; font-size: 1.125rem; font-weight: 600; }
.ch-site-steps p { margin-bottom: 0; color: var(--text-muted); font-size: 1rem; line-height: 1.65; }

@media (min-width: 768px) {
  .ch-site-steps { grid-template-columns: repeat(3, 1fr); }
}

/* ---- two-column section (the widget) ---- */
.ch-site-split { display: grid; gap: 2.5rem; align-items: center; }

/* A grid item's min-width is auto, so the code block below would refuse to
   shrink past its longest line and widen the whole page on a phone. This lets
   it shrink; the <pre> then scrolls inside its own box. */
.ch-site-split > * { min-width: 0; }

.ch-site-split__copy h2 {
  margin-bottom: 1rem;
  font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2.125rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.02em;
}

.ch-site-split__copy > p { margin-bottom: 1.75rem; color: var(--text-muted); font-size: 1rem; line-height: 1.65; }

@media (min-width: 992px) {
  .ch-site-split { grid-template-columns: 1fr 1fr; gap: 4rem; }
}

.ch-site-code {
  margin: 0;
  border-radius: .875rem;
  overflow: hidden;
  background-color: var(--ch-dark);
  box-shadow: 0 1rem 2.5rem rgba(3, 27, 78, .12);
}

.ch-site-code figcaption {
  padding: .75rem 1.25rem;
  border-bottom: 1px solid rgba(255, 255, 255, .1);
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .55);
}

.ch-site-code pre {
  margin: 0;
  padding: 1.25rem;
  overflow-x: auto;
}

.ch-site-code code {
  font-size: .8125rem;
  line-height: 1.7;
  color: var(--ch-green);
  white-space: pre;
}

/* ---- feature grid ---- */
.ch-site-grid {
  display: grid;
  gap: 1.25rem;
  /* 19rem lands on three columns at the container's width, so the nine feature
     cards fill 3x3 exactly instead of leaving one orphan on a fourth row. */
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
}

.ch-site-grid > *,
.ch-site-pricing > *,
.ch-site-hero__inner > * { min-width: 0; }

.ch-site-card {
  padding: 1.5rem;
  border: 1px solid var(--default-border);
  border-radius: .875rem;
  background-color: var(--custom-white);
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}

.ch-site-card:hover {
  border-color: rgba(var(--ch-green-rgb), .55);
  transform: translateY(-.125rem);
  box-shadow: 0 .75rem 1.5rem rgba(3, 27, 78, .07);
}

.ch-site-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin-bottom: 1rem;
  border-radius: .625rem;
  background-color: rgba(var(--ch-green-rgb), .18);
  color: var(--ch-green-deep);
  font-size: 1.25rem;
}

.ch-site-card h3 { margin-bottom: .5rem; font-size: 1.0625rem; font-weight: 600; }
.ch-site-card p { margin-bottom: 0; color: var(--text-muted); font-size: .9375rem; line-height: 1.6; }

/* ---- pricing ---- */
.ch-site-pricing { display: grid; gap: 1.5rem; align-items: start; }

@media (min-width: 992px) {
  .ch-site-pricing { grid-template-columns: 1fr 1fr; gap: 2rem; }
}

.ch-site-price {
  position: relative;
  padding: 2rem;
  border: 1px solid var(--default-border);
  border-radius: 1rem;
  background-color: var(--custom-white);
  box-shadow: 0 1rem 2.5rem rgba(3, 27, 78, .07);
}

/* Brand green as a rule across the top of the card — a fill, not a text colour,
   so its contrast never has to carry any words. */
.ch-site-price::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: .25rem;
  border-radius: 1rem 1rem 0 0;
  background-color: var(--ch-green);
}

.ch-site-price__label {
  margin-bottom: .25rem;
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.ch-site-price__figure {
  display: flex;
  align-items: flex-start;
  gap: .125rem;
  margin-bottom: 0;
  line-height: 1;
  color: var(--ch-ink);
}

.ch-site-price__currency { font-size: 1.75rem; font-weight: 600; margin-top: .5rem; }
.ch-site-price__amount { font-size: 4rem; font-weight: 700; letter-spacing: -.04em; }

.ch-site-price__unit {
  margin-bottom: 1.75rem;
  font-size: .9375rem;
  font-weight: 500;
  color: var(--text-muted);
}

.ch-site-price__foot { margin: .75rem 0 0; text-align: center; font-size: .75rem; color: var(--text-muted); }

.ch-site-calc {
  padding: 2rem;
  border: 1px solid var(--default-border);
  border-radius: 1rem;
  background-color: var(--custom-white);
}

.ch-site-calc h3 { margin-bottom: .375rem; font-size: 1.125rem; font-weight: 600; }
.ch-site-calc > p { margin-bottom: 1.75rem; color: var(--text-muted); font-size: .9375rem; }

/* ---- the slider ----
   The native control is restyled rather than replaced, so it keeps its keyboard
   behaviour (arrows, Home/End) and its screen-reader semantics for free. The
   filled part of the track is a gradient driven by --ch-fill, which
   chairhog-site.js sets as the value changes. */
.ch-site-slider { margin-bottom: 1.5rem; }

.ch-site-slider__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: .875rem;
}

.ch-site-slider__label { margin: 0; font-size: .8125rem; font-weight: 500; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); }

.ch-site-slider__value {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ch-ink);
}

.ch-site-slider input[type="range"] {
  --ch-fill: 0%;
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 1.5rem;              /* a 24px hit area around a 6px track */
  margin: 0;
  padding: 0;
  background: none;
  cursor: pointer;
}

.ch-site-slider input[type="range"]::-webkit-slider-runnable-track {
  height: .375rem;
  border-radius: 999px;
  background: linear-gradient(to right,
              var(--ch-green-deep) var(--ch-fill),
              rgba(var(--ch-green-rgb), .18) var(--ch-fill));
}

.ch-site-slider input[type="range"]::-moz-range-track {
  height: .375rem;
  border-radius: 999px;
  background: rgba(var(--ch-green-rgb), .18);
}

.ch-site-slider input[type="range"]::-moz-range-progress {
  height: .375rem;
  border-radius: 999px;
  background: var(--ch-green-deep);
}

.ch-site-slider input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 1.375rem;
  height: 1.375rem;
  margin-top: -.5rem;          /* centres a 22px thumb on a 6px track */
  border: 3px solid #fff;
  border-radius: 50%;
  background-color: var(--ch-green-deep);
  box-shadow: 0 .125rem .5rem rgba(3, 27, 78, .25);
}

.ch-site-slider input[type="range"]::-moz-range-thumb {
  width: 1.375rem;
  height: 1.375rem;
  border: 3px solid #fff;
  border-radius: 50%;
  background-color: var(--ch-green-deep);
  box-shadow: 0 .125rem .5rem rgba(3, 27, 78, .25);
}

.ch-site-slider input[type="range"]:focus-visible { outline: none; }

.ch-site-slider input[type="range"]:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 .25rem rgba(var(--ch-green-rgb), .5);
}

.ch-site-slider input[type="range"]:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 .25rem rgba(var(--ch-green-rgb), .5);
}

.ch-site-slider__scale {
  display: flex;
  justify-content: space-between;
  margin-top: .375rem;
  font-size: .75rem;
  color: var(--text-muted);
}

/* ---- the total ---- */
.ch-site-calc__readout {
  margin-bottom: 1.75rem;
  padding: 1.5rem 1.25rem;
  border-radius: .875rem;
  background-color: var(--ch-dark);
  color: #fff;
  text-align: center;
}

.ch-site-calc__label {
  margin-bottom: .625rem;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .55);
}

/* Baseline-aligned so the currency mark, the figure and the unit sit on one
   line however many digits the total runs to. Tabular figures stop the number
   jittering sideways while the slider is being dragged. */
.ch-site-calc__money {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: .125rem;
  margin-bottom: .5rem;
  line-height: 1;
  color: #fff;
}

.ch-site-calc__cur { font-size: 1.5rem; font-weight: 600; color: var(--ch-green); }

.ch-site-calc__amount {
  font-size: clamp(2.75rem, 2.2rem + 2vw, 3.5rem);
  font-weight: 700;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}

.ch-site-calc__per { font-size: 1rem; font-weight: 500; color: rgba(255, 255, 255, .6); margin-inline-start: .25rem; }

.ch-site-calc__users { margin-bottom: 0; font-size: .8125rem; color: rgba(255, 255, 255, .7); }
.ch-site-calc__users strong { color: var(--ch-green); font-weight: 600; }

.ch-site-calc__nots h4 {
  margin-bottom: .875rem;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.ch-site-calc__nots ul { list-style: none; margin: 0; padding: 0; }

.ch-site-calc__nots li {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .5rem;
  font-size: .9375rem;
  color: var(--default-text-color);
}

.ch-site-calc__nots i { color: rgb(var(--ch-status-cancelled-rgb)); font-size: .75rem; }

/* ---- FAQ ---- */
.ch-site-faq .accordion-item {
  margin-bottom: .75rem;
  border: 1px solid var(--default-border);
  border-radius: .75rem;
  overflow: hidden;
  background-color: var(--custom-white);
}

.ch-site-faq .accordion-button {
  font-size: 1rem;
  font-weight: 600;
  background-color: var(--custom-white);
  box-shadow: none;
}

.ch-site-faq .accordion-button:not(.collapsed) { color: rgb(var(--primary-rgb)); }
.ch-site-faq .accordion-body { font-size: .9375rem; line-height: 1.65; color: var(--text-muted); }

/* ---- closing call to action ---- */
.ch-site-cta {
  position: relative;
  overflow: hidden;
  padding-block: 4rem;
  background-color: var(--ch-dark);
  color: #fff;
  text-align: center;
}

.ch-site-cta::after {
  content: "";
  position: absolute;
  inset: auto auto -60% 50%;
  transform: translateX(-50%);
  width: 40rem;
  height: 40rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--ch-green-rgb), .2) 0%, rgba(var(--ch-green-rgb), 0) 70%);
  pointer-events: none;
}

.ch-site-cta .ch-site-container { position: relative; z-index: 1; }

.ch-site-cta h2 {
  margin-bottom: .75rem;
  font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2.125rem);
  font-weight: 700;
  letter-spacing: -.02em;
  color: #fff;
}

.ch-site-cta > .ch-site-container > p {
  max-width: 36rem;
  margin: 0 auto 2rem;
  color: rgba(255, 255, 255, .72);
}

.ch-site-cta__actions { display: flex; flex-wrap: wrap; gap: .75rem; justify-content: center; }

/* ---- footer ---- */
.ch-site-footer {
  padding-block: 3rem 1.5rem;
  background-color: #161718;   /* a shade under --ch-dark, so the CTA band above it reads as a separate surface */
  color: rgba(255, 255, 255, .68);
  font-size: .875rem;
}

.ch-site-footer__top { display: grid; gap: 2.5rem; padding-bottom: 2.5rem; }

.ch-site-footer__brand img { height: 1.75rem; width: auto; margin-bottom: 1rem; }
.ch-site-footer__brand p { max-width: 26rem; margin-bottom: 0; font-size: .875rem; line-height: 1.65; }

.ch-site-footer__links { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); }

.ch-site-footer__links h2 {
  margin-bottom: .875rem;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #fff;
}

.ch-site-footer__links ul { list-style: none; margin: 0; padding: 0; }
.ch-site-footer__links li { margin-bottom: .5rem; }

.ch-site-footer__links a { color: rgba(255, 255, 255, .68); text-decoration: none; }
.ch-site-footer__links a:hover { color: var(--ch-green); }

/* The footer's log-out button, dressed as one of the links around it. */
.ch-site-footer__linkbtn {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: rgba(255, 255, 255, .68);
  cursor: pointer;
}

.ch-site-footer__linkbtn:hover,
.ch-site-footer__linkbtn:focus-visible { color: var(--ch-green); }

.ch-site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1.5rem;
  justify-content: space-between;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(255, 255, 255, .1);
  font-size: .75rem;
  color: rgba(255, 255, 255, .5);
}

.ch-site-footer__bottom p { margin: 0; }

@media (min-width: 992px) {
  .ch-site-footer__top { grid-template-columns: 1.25fr 2fr; gap: 4rem; }
}

/* ---- legal pages (Privacy, Terms) ---- */
.ch-site-legal { padding-block: 3rem 4rem; }

.ch-site-legal__head { margin-bottom: 2.5rem; }

.ch-site-legal__head h1 {
  margin-bottom: .5rem;
  font-size: clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem);
  font-weight: 700;
  letter-spacing: -.02em;
}

.ch-site-legal__meta { margin-bottom: 0; font-size: .8125rem; color: var(--text-muted); }

/* A one-line summary above each policy. It has no legal effect and says so —
   it is there because nobody reads a wall of clauses cold. */
.ch-site-legal__summary {
  padding: 1.25rem 1.5rem;
  margin-bottom: 2.5rem;
  border: 1px solid var(--default-border);
  border-inline-start: 3px solid var(--ch-green);
  border-radius: .75rem;
  background-color: rgb(var(--body-bg-rgb));
}

.ch-site-legal__summary p:last-child { margin-bottom: 0; }

.ch-site-legal h2 {
  margin: 2.5rem 0 .875rem;
  font-size: 1.25rem;
  font-weight: 600;
  scroll-margin-top: 6rem;
}

.ch-site-legal h3 { margin: 1.75rem 0 .625rem; font-size: 1rem; font-weight: 600; }

.ch-site-legal p,
.ch-site-legal li { font-size: .9375rem; line-height: 1.7; color: var(--default-text-color); }

.ch-site-legal p { margin-bottom: 1rem; }

.ch-site-legal a {
  color: rgb(var(--primary-rgb));
  text-decoration: underline;
  text-underline-offset: .15em;
}

.ch-site-legal a:hover { color: var(--ch-green-deep); }

/* The contents list is already obviously a list of links; underlining all
   fourteen of them just makes noise. */
.ch-site-legal__toc a { text-decoration: none; }
.ch-site-legal__toc a:hover { text-decoration: underline; }
.ch-site-legal ul { margin-bottom: 1.25rem; padding-inline-start: 1.25rem; }
.ch-site-legal li { margin-bottom: .5rem; }

.ch-site-legal table {
  width: 100%;
  margin-bottom: 1.5rem;
  border-collapse: collapse;
  font-size: .875rem;
}

.ch-site-legal th,
.ch-site-legal td {
  padding: .75rem;
  border: 1px solid var(--default-border);
  text-align: start;
  vertical-align: top;
}

.ch-site-legal th { background-color: rgb(var(--body-bg-rgb)); font-weight: 600; }

/* Wide tables scroll inside their own box rather than widening the page. */
.ch-site-legal__table { overflow-x: auto; }

/* Contents list at the top of a long policy. */
.ch-site-legal__toc {
  padding: 1.25rem 1.5rem;
  margin-bottom: 2.5rem;
  border: 1px solid var(--default-border);
  border-radius: .75rem;
}

.ch-site-legal__toc h2 { margin: 0 0 .75rem; font-size: .75rem; letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); }
.ch-site-legal__toc ol { margin: 0; padding-inline-start: 1.25rem; columns: 2; column-gap: 2rem; }
.ch-site-legal__toc li { margin-bottom: .375rem; font-size: .875rem; }

@media (max-width: 575.98px) {
  .ch-site-legal__toc ol { columns: 1; }
}


/* ==========================================================================
   10. Public website — the widget example, brand moments and flourishes
   --------------------------------------------------------------------------
   Added after the first pass on the landing page. Three jobs:

     - the demo band, which holds a worked example of the guest booking widget
       — self-contained test data, no link into the app;
     - the two places the full ChairHog lockup appears at size (the closing
       band, and as a watermark behind the hero);
     - the small motion and gradient touches that stop a one-plan, one-price
       page reading as a plain document.

   All of it respects prefers-reduced-motion — see the bottom of this section.
   ========================================================================== */

/* ---- brand lockup in the closing band ---- */
.ch-site-cta__logo {
  display: block;
  width: auto;
  height: clamp(8rem, 5rem + 10vw, 13rem);
  margin: 0 auto 2rem;
  filter: drop-shadow(0 .75rem 2rem rgba(0, 0, 0, .45));
}

/* ---- the mark, oversized and barely there, behind the hero ---- */
.ch-site-hero__watermark {
  position: absolute;
  inset-inline-start: -6rem;
  bottom: -8rem;
  width: 30rem;
  height: auto;
  opacity: .06;
  pointer-events: none;
  user-select: none;
}

@media (max-width: 991.98px) {
  .ch-site-hero__watermark { display: none; }
}

/* ---- the demo band ----
   Dark, like the hero and the closing band, so the three dark surfaces read as
   the spine of the page and the white sections as the detail between them.
   Holds the worked example of the booking widget. */
.ch-site-demo {
  position: relative;
  overflow: hidden;
  padding-block: 3.5rem;
  background-color: var(--ch-dark);
  color: #fff;
}

.ch-site-demo::after {
  content: "";
  position: absolute;
  inset: auto -20% -50% auto;
  width: 40rem;
  height: 40rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--ch-green-rgb), .16) 0%, rgba(var(--ch-green-rgb), 0) 70%);
  pointer-events: none;
}

.ch-site-demo__inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 3rem;
  align-items: center;
}

@media (min-width: 992px) {
  .ch-site-demo { padding-block: 5.5rem; }
  .ch-site-demo__inner { grid-template-columns: 1fr 1fr; gap: 4rem; }
  .ch-site-demo__inner > * { min-width: 0; }
}

.ch-site-demo .ch-site-eyebrow { color: var(--ch-green); }

.ch-site-demo h2 {
  margin-bottom: 1rem;
  font-size: clamp(1.75rem, 1.3rem + 2vw, 2.5rem);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.02em;
  color: #fff;
}

.ch-site-demo h2 em { font-style: normal; color: var(--ch-green); }

.ch-site-demo__lede {
  margin-bottom: 1.75rem;
  font-size: 1.0625rem;
  line-height: 1.65;
  color: rgba(255, 255, 255, .74);
}

/* The three inputs the model reads, as labelled chips. */
.ch-site-demo__inputs {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin: 0 0 1.75rem;
  padding: 0;
}

.ch-site-demo__inputs li {
  display: inline-flex;
  align-items: center;
  gap: .4375rem;
  padding: .4375rem .75rem;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 999px;
  background-color: rgba(255, 255, 255, .05);
  font-size: .8125rem;
  color: rgba(255, 255, 255, .85);
}

.ch-site-demo__inputs i { color: var(--ch-green); font-size: .9375rem; }

.ch-site-demo__uses { list-style: none; margin: 0 0 1.75rem; padding: 0; }

.ch-site-demo__uses li {
  display: flex;
  align-items: flex-start;
  gap: .625rem;
  margin-bottom: .75rem;
  font-size: 1rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, .82);
}

.ch-site-demo__uses i { flex-shrink: 0; margin-top: .1875rem; color: var(--ch-green); }

.ch-site-demo__note {
  margin: 0;
  padding-inline-start: .875rem;
  border-inline-start: 2px solid rgba(var(--ch-green-rgb), .5);
  font-size: .875rem;
  color: rgba(255, 255, 255, .6);
}

/* ---- the worked example of the guest booking widget ----
   A self-contained demo: its own test venue, its own tables, driven by
   chairhog-site.js. It deliberately shares no data and no route with the
   real widget under /Widget — a visitor can play with this without anything
   behind a sign-in being exposed.

   Styled to look like the widget rather than reusing the .ch-widget block from
   section 5: that block is a full-page mobile layout with its own token set,
   and dropping it inside a marketing section would fight both. */
.ch-site-widget {
  border-radius: .875rem;
  overflow: hidden;
  background-color: #fff;
  color: var(--ch-ink);
  box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, .35);
}

.ch-site-widget__head {
  padding: 1.25rem;
  border-bottom: 1px solid #eef0f3;
  text-align: center;
}

.ch-site-widget__venue {
  margin-bottom: .125rem;
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ch-ink);
}

.ch-site-widget__tagline { margin-bottom: 0; font-size: .8125rem; color: #6b7280; }

.ch-site-widget__body { padding: 1.25rem; }

.ch-site-widget__group { border: 0; padding: 0; margin: 0 0 1.25rem; }
.ch-site-widget__group:last-child { margin-bottom: 0; }

.ch-site-widget__legend {
  float: none;                /* Bootstrap makes legends full-width blocks */
  width: auto;
  margin-bottom: .5rem;
  padding: 0;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #6b7280;
}

.ch-site-widget__chips { display: flex; flex-wrap: wrap; gap: .5rem; }

.ch-site-widget__chip {
  min-width: 2.75rem;
  min-height: 2.75rem;        /* 44px touch target */
  padding: .5rem .875rem;
  border: 1px solid #dfe3e8;
  border-radius: .5rem;
  background-color: #fff;
  color: var(--ch-ink);
  font-size: .875rem;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease, color .15s ease;
}

.ch-site-widget__chip:hover:not(:disabled) { border-color: var(--ch-green-deep); }

.ch-site-widget__chip:focus-visible {
  outline: 2px solid var(--ch-green-deep);
  outline-offset: 2px;
}

.ch-site-widget__chip[aria-pressed="true"] {
  border-color: var(--ch-green-deep);
  background-color: var(--ch-green-deep);
  color: #fff;
}

/* Taken: struck through and unclickable, not merely faded — a guest has to be
   able to tell at a glance, and so does anyone who cannot see the colour. */
.ch-site-widget__chip:disabled {
  border-color: #eceff2;
  background-color: #f6f7f9;
  color: #a6adb8;
  cursor: not-allowed;
  text-decoration: line-through;
}

/* ---- tables ---- */
.ch-site-widget__tables { display: grid; grid-template-columns: repeat(2, 1fr); gap: .5rem; }

@media (min-width: 480px) {
  .ch-site-widget__tables { grid-template-columns: repeat(3, 1fr); }
}

.ch-site-widget__table {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .125rem;
  min-height: 3.5rem;
  padding: .625rem .75rem;
  border: 1px solid #dfe3e8;
  border-radius: .5rem;
  background-color: #fff;
  color: var(--ch-ink);
  text-align: start;
  cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease;
}

.ch-site-widget__table:hover:not(:disabled) { border-color: var(--ch-green-deep); }

.ch-site-widget__table:focus-visible {
  outline: 2px solid var(--ch-green-deep);
  outline-offset: 2px;
}

.ch-site-widget__table[aria-pressed="true"] {
  border-color: var(--ch-green-deep);
  background-color: rgba(var(--ch-green-rgb), .14);
}

.ch-site-widget__table:disabled {
  border-color: #eceff2;
  background-color: #f6f7f9;
  color: #a6adb8;
  cursor: not-allowed;
}

.ch-site-widget__table-name { font-size: .875rem; font-weight: 600; line-height: 1.2; }
.ch-site-widget__table-note { font-size: .6875rem; color: #6b7280; }
.ch-site-widget__table:disabled .ch-site-widget__table-note { color: #a6adb8; }

/* ---- foot ---- */
.ch-site-widget__foot { padding: 1rem 1.25rem 1.25rem; border-top: 1px solid #eef0f3; background-color: #fafbfc; }

.ch-site-widget__summary {
  margin-bottom: .75rem;
  font-size: .8125rem;
  color: #55606f;
  text-align: center;
  min-height: 1.25rem;
}

.ch-site-widget__summary strong { color: var(--ch-ink); font-weight: 600; }

.ch-site-widget__cta {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 2.75rem;
  padding: .625rem 1rem;
  border: 0;
  border-radius: .5rem;
  background-color: var(--ch-green-deep);
  color: #fff;
  font-size: .9375rem;
  font-weight: 600;
  cursor: pointer;
}

.ch-site-widget__cta:disabled { background-color: #c9cfd6; cursor: not-allowed; }
.ch-site-widget__cta:focus-visible { outline: 2px solid var(--ch-green); outline-offset: 2px; }

/* ---- the confirmed state ---- */
.ch-site-widget__done { padding: 2.5rem 1.5rem; text-align: center; }

.ch-site-widget__done-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  height: 3.25rem;
  margin-bottom: 1rem;
  border-radius: 50%;
  background-color: rgba(var(--ch-green-rgb), .18);
  color: var(--ch-green-deep);
  font-size: 1.5rem;
}

.ch-site-widget__done h3 { margin-bottom: .375rem; font-size: 1.125rem; font-weight: 700; }
.ch-site-widget__done p { margin-bottom: 1.25rem; font-size: .875rem; color: #55606f; }

.ch-site-widget__again {
  min-height: 2.75rem;
  padding: .5rem 1rem;
  border: 1px solid #dfe3e8;
  border-radius: .5rem;
  background: none;
  color: var(--ch-ink);
  font-size: .875rem;
  font-weight: 600;
  cursor: pointer;
}

.ch-site-widget__again:hover { border-color: var(--ch-green-deep); }

/* A demo has to say so. */
.ch-site-widget__note {
  margin: .875rem 0 0;
  font-size: .75rem;
  text-align: center;
  color: rgba(255, 255, 255, .5);
}

/* ---- the one-liner, given its own moment ---- */
.ch-site-oneliner {
  position: relative;
  padding-block: 3rem;
  background-color: var(--ch-ink);
  color: #fff;
  text-align: center;
  overflow: hidden;
}

.ch-site-oneliner p {
  max-width: 40rem;
  margin: 0 auto 1.5rem;
  font-size: clamp(1.25rem, 1rem + 1.2vw, 1.75rem);
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -.01em;
  color: #fff;
}

.ch-site-oneliner p em { font-style: normal; color: var(--ch-green); }

/* ---- the one-liner band's supporting bits ---- */
.ch-site-code--center { max-width: 40rem; margin-inline: auto; text-align: start; }

.ch-site-oneliner__ticks {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .625rem 1.75rem;
  margin: 1.75rem 0;
  padding: 0;
  font-size: .875rem;
  color: rgba(255, 255, 255, .75);
}

.ch-site-oneliner__ticks li { display: flex; align-items: center; gap: .4375rem; }
.ch-site-oneliner__ticks i { color: var(--ch-green); }

/* "Test it out" under the snippet — plain body copy, not the band's big line. */
.ch-site-oneliner p.ch-site-oneliner__try {
  margin: 1.25rem auto .875rem;
  font-size: .9375rem;
  font-weight: 400;
  letter-spacing: 0;
  color: rgba(255, 255, 255, .75);
}

/* ---- motion ----
   Sections lift in as they arrive. chairhog-site.js adds .is-in with an
   IntersectionObserver; if the script never runs, .ch-site-reveal is still
   fully visible, so nothing can leave the page blank. */
@media (prefers-reduced-motion: no-preference) {
  .ch-site-reveal {
    opacity: 0;
    transform: translateY(1.25rem);
    transition: opacity .5s ease, transform .5s ease;
  }

  .ch-site-reveal.is-in { opacity: 1; transform: none; }
}


/* ==========================================================================
   11. Public website — the lockup at the top, registration, cookie consent
   ========================================================================== */

/* ---- the lockup above the headline ----
   The header carries the wordmark; this is the full stacked lockup, and it is
   the first thing on the page. Kept off the headline's own leading so the two
   read as separate things rather than one crowded block. */
.ch-site-hero__logo {
  display: block;
  width: auto;
  height: clamp(4.5rem, 3rem + 4vw, 6.5rem);
  margin-bottom: 1.5rem;
  filter: drop-shadow(0 .5rem 1.5rem rgba(0, 0, 0, .4));
}

/* ---- registration ---- */
.ch-site-register { padding-block: 3rem 4rem; }

.ch-site-register__inner { display: grid; gap: 3rem; align-items: start; }

@media (min-width: 992px) {
  .ch-site-register { padding-block: 4.5rem 5.5rem; }
  .ch-site-register__inner { grid-template-columns: 1fr 1fr; gap: 5rem; }
  .ch-site-register__inner > * { min-width: 0; }
}

.ch-site-register__form h1 {
  margin-bottom: .625rem;
  font-size: clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem);
  font-weight: 700;
  letter-spacing: -.02em;
}

.ch-site-register__lede { margin-bottom: 2rem; font-size: 1.0625rem; line-height: 1.6; color: var(--text-muted); }

.ch-site-field { margin-bottom: 1.5rem; }

.ch-site-field .form-label { margin-bottom: .375rem; font-size: .9375rem; font-weight: 600; }

/* form-control-lg on the template lands a little tight for a two-field form
   that is the whole point of the page. */
.ch-site-register .form-control-lg { padding: .75rem 1rem; font-size: 1rem; }

.ch-site-field__hint { margin: .4375rem 0 0; font-size: .8125rem; color: var(--text-muted); }

.ch-site-register__terms {
  margin: 1.25rem 0 0;
  font-size: .8125rem;
  line-height: 1.6;
  color: var(--text-muted);
  text-align: center;
}

.ch-site-register__signin {
  margin: 2rem 0 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--default-border);
  font-size: .9375rem;
  color: var(--text-muted);
  text-align: center;
}

.ch-site-register a { color: rgb(var(--primary-rgb)); }

/* ---- what happens next ---- */
.ch-site-register__aside {
  padding: 2rem;
  border: 1px solid var(--default-border);
  border-radius: 1rem;
  background-color: rgb(var(--body-bg-rgb));
}

.ch-site-register__aside h2 {
  margin-bottom: 1.5rem;
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.ch-site-next { list-style: none; margin: 0 0 2rem; padding: 0; counter-reset: none; }

.ch-site-next li { display: flex; gap: 1rem; margin-bottom: 1.5rem; }
.ch-site-next li:last-child { margin-bottom: 0; }

.ch-site-next__num {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.875rem;
  height: 1.875rem;
  border-radius: 50%;
  background-color: var(--ch-green);
  color: var(--ch-ink);
  font-size: .875rem;
  font-weight: 700;
}

.ch-site-next h3 { margin-bottom: .25rem; font-size: 1rem; font-weight: 600; }
.ch-site-next p { margin-bottom: 0; font-size: .9375rem; line-height: 1.6; color: var(--text-muted); }

.ch-site-register__price {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--default-border);
}

.ch-site-register__price-figure {
  flex-shrink: 0;
  margin: 0;
  font-size: 2.25rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.03em;
  color: var(--ch-ink);
}

.ch-site-register__price-figure span { font-size: 1.25rem; font-weight: 600; vertical-align: .35em; }
.ch-site-register__price-unit { margin-bottom: .25rem; font-size: .9375rem; font-weight: 600; }
.ch-site-register__price-note { margin-bottom: 0; font-size: .8125rem; line-height: 1.55; color: var(--text-muted); }

/* ---- cookie consent ----
   A bar across the foot of the window rather than a full-screen interstitial:
   it must not be one of the intrusive interstitials that page-experience
   guidance penalises, and the page behind it stays readable and usable. */
.ch-site-cookies {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 1060;
  padding: 1rem 1.25rem;
  max-height: 60vh;
  overflow-y: auto;
  background-color: var(--ch-dark);
  color: rgba(255, 255, 255, .82);
  border-top: 3px solid var(--ch-green);
  box-shadow: 0 -.5rem 2rem rgba(0, 0, 0, .3);
}

.ch-site-cookies[hidden] { display: none; }

.ch-site-cookies__inner {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  width: 100%;
  max-width: 71.25rem;
  margin-inline: auto;
}

@media (min-width: 992px) {
  .ch-site-cookies__inner { flex-direction: row; align-items: center; gap: 2.5rem; }
  .ch-site-cookies__copy { flex: 1 1 auto; }
}

.ch-site-cookies__title {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .5rem;
  font-size: 1rem;
  font-weight: 600;
  color: #fff;
}

.ch-site-cookies__title i { color: var(--ch-green); font-size: 1.125rem; }

.ch-site-cookies p { margin-bottom: .5rem; font-size: .875rem; line-height: 1.6; }
.ch-site-cookies__links { margin-bottom: 0 !important; font-size: .8125rem; }
.ch-site-cookies a { color: var(--ch-green); text-decoration: underline; text-underline-offset: .15em; }

.ch-site-cookies__actions {
  display: flex;
  flex-direction: column;
  gap: .625rem;
  flex-shrink: 0;
}

@media (min-width: 576px) {
  .ch-site-cookies__actions { flex-direction: row; }
  .ch-site-cookies__actions .btn { flex: 1 1 auto; white-space: nowrap; }
}

@media (min-width: 992px) {
  .ch-site-cookies__actions .btn { flex: 0 0 auto; }
}

/* Both choices are given equal visual weight — a refusal that is harder to see
   than an acceptance is not a free choice. Same size, same shape, one filled. */
.ch-site .ch-site-btn-outline {
  border: 1px solid rgba(255, 255, 255, .4);
  background-color: transparent;
  color: #fff;
  font-weight: 500;
}

.ch-site .ch-site-btn-outline:hover,
.ch-site .ch-site-btn-outline:focus-visible {
  border-color: var(--ch-green);
  background-color: rgba(255, 255, 255, .08);
  color: #fff;
}


/* ==========================================================================
   12. Public website — how the data is looked after, and the closed-account
       notice
   ========================================================================== */

/* ---- the trust band ----
   Ink rather than --ch-dark, so it separates the two light sections it sits
   between without reading as another hero. */
.ch-site-trust {
  padding-block: 3.5rem;
  background-color: var(--ch-ink);
  color: rgba(255, 255, 255, .78);
}

@media (min-width: 768px) {
  .ch-site-trust { padding-block: 4.5rem; }
}

.ch-site-trust__head { max-width: 44rem; margin: 0 auto 2.5rem; text-align: center; }

.ch-site-trust .ch-site-eyebrow { color: var(--ch-green); }

.ch-site-trust__head h2 {
  margin-bottom: 0;
  font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2.125rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.02em;
  color: #fff;
}

.ch-site-trust__grid {
  display: grid;
  gap: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}

.ch-site-trust__grid > * { min-width: 0; }

.ch-site-trust__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin-bottom: 1rem;
  border-radius: .625rem;
  background-color: rgba(var(--ch-green-rgb), .18);
  color: var(--ch-green);
  font-size: 1.25rem;
}

.ch-site-trust h3 { margin-bottom: .5rem; font-size: 1.0625rem; font-weight: 600; color: #fff; }
.ch-site-trust p { margin-bottom: 0; font-size: .9375rem; line-height: 1.65; }

/* ---- the notice panel on a page whose main action is not available yet ---- */
.ch-site-notice {
  padding: 1.5rem;
  border: 1px solid var(--default-border);
  border-inline-start: 3px solid var(--ch-green);
  border-radius: .875rem;
  background-color: rgb(var(--body-bg-rgb));
}

.ch-site-notice__title {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .5rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--ch-ink);
}

.ch-site-notice__title i { color: var(--ch-green-deep); font-size: 1.125rem; }
.ch-site-notice p { font-size: .9375rem; line-height: 1.6; color: var(--text-muted); }
.ch-site-notice .btn { margin-top: .75rem; }

/* ==========================================================================
   Validation messages (asp-validation-for spans)
   Written into by jquery.validate.unobtrusive and by ModelState on redisplay.
   Always a block line of its own directly under the control it belongs to —
   after an .input-group or .ch-pass wrapper when the control sits in one —
   and gone entirely when there is nothing to say.
   ========================================================================== */
.field-validation-error { display: block; margin-top: .25rem; line-height: 1.35; }
.field-validation-valid { display: none; }

/* ==========================================================================
   Dashboard KPI row (Views/Dashboard/_DashboardContent.cshtml)
   Five of the six summary cards close on a line of small print; the occupancy
   card closes on a progress bar, which is shorter, so the row used to sit at
   six different heights. .h-100 evens the cards up wherever two or more share
   a flex line, and .ch-kpi-foot gives the bar the same closing band so they
   match when they stack one per row too.
   ========================================================================== */
.ch-kpi-foot {
  display: flex;
  align-items: center;
  min-height: 1.625rem;   /* .fs-12 line box (1.125rem) + .pt-2 (0.5rem) */
  padding-top: .5rem;
}

/* The content rows below the KPIs: every card in a row is .h-100 so the row sits at one
   height, and a card body that lists an open-ended number of rows scrolls inside that
   height instead of stretching its neighbours. */
.ch-dash-scroll {
  max-height: 380px;
  overflow-y: auto;
}

/* A numeric input whose value is driven by its own +/- buttons (the plan's site count):
   the browser's spin buttons would be a second, competing control. */
.ch-no-spin::-webkit-outer-spin-button,
.ch-no-spin::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.ch-no-spin {
  -moz-appearance: textfield;
  appearance: textfield;
}

/* ==========================================================================
   Select2 — the ChairHog skin
   Every dropdown in the admin is a Select2 (assets/js/chairhog-select.js), so
   it has to sit on the theme's own tokens rather than the Bootstrap defaults
   the select2-bootstrap-5-theme package was compiled against. Those tokens
   already flip with data-theme-mode, which is what makes the control follow
   light and dark without a second rule set.
   ========================================================================== */

/* The closed control: same surface, border and ink as a native .form-select.
   The theme package ships its own metrics, which are not Valex's — so the box
   model is restated here as well, and a Select2 ends up exactly the height, pad
   and radius of the .form-control sitting next to it in the same row. */
.select2-container--bootstrap-5 .select2-selection {
  background-color: var(--form-control-bg);
  border: 1px solid var(--input-border);
  /* 3px, not Bootstrap's .375rem — Valex overrides the radius on .form-control and
     the Select2 next to one has to match it, not the framework default. */
  border-radius: 3px;
  color: var(--default-text-color);
  font-size: .875rem;
  line-height: 1.5;
  min-height: calc(1.5em + .75rem + 2px);
  padding: .375rem .75rem;
  box-shadow: none;
}

/* Single: the rendered value and the arrow have to sit inside that padding
   rather than adding their own, or the control grows a few pixels taller than
   the inputs beside it. */
.select2-container--bootstrap-5 .select2-selection--single {
  display: flex;
  align-items: center;
  /* The theme draws the arrow as a background image at the right edge and keeps
     2.25rem of end padding clear for it; the shared .select2-selection rule above
     resets the padding and lost that, which on a content-hugging (w-auto) select —
     the site picker on Venue/Tables — put the arrow on top of the site's name. */
  padding-inline-end: 2.25rem;
}

/* The site pickers on Venue/Tables and Venue/FloorDesigner hug their content; a short
   site name made them stubs. Select2 puts its container straight after the <select>. */
#tables-site + .select2-container,
#floor-site + .select2-container { min-width: 15rem; }

.select2-container--bootstrap-5 .select2-selection--single .select2-selection__rendered {
  padding: 0;
  line-height: 1.5;
}

/* Multiple: the same outer box as a .form-control, with the chips laid out
   inside it. Without this the tag picker on Team/Invite renders as a tall,
   loosely-padded block that matches nothing else on the form. */
.select2-container--bootstrap-5 .select2-selection--multiple {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .25rem;
  /* Slightly tighter than the single, so a row of chips lands on the same 35px
     box as the .form-control beside it rather than a pixel or two taller. */
  padding: .25rem .5rem;
}

.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered {
  display: contents;
  padding: 0;
  margin: 0;
}

.select2-container--bootstrap-5 .select2-selection--multiple .select2-search--inline {
  display: flex;
  flex: 1 1 4rem;
}

/* The inline search field is also what carries the placeholder while nothing is
   chosen, so where it sits IS where "Choose the sites they can work at" sits.
   styles.min.css pushes it down with `margin-block-start: .5rem !important`,
   which on an empty control drops the placeholder half a line below the middle
   of the box and out of the bottom of it — the only rule in this file that has
   to answer !important with !important, because there is no selector that
   outranks it. With chips in the control the field wraps onto its own line and
   the push never shows, which is why it only ever looked wrong when empty. */
.select2-container--bootstrap-5 .select2-selection--multiple .select2-search--inline .select2-search__field {
  margin: 0 !important;
  height: 1.5rem;
  font-size: .875rem;
  line-height: 1.5;
}

/* The clear-all cross sits with the chips, not floated above them. */
.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__clear {
  order: 99;
  margin: 0 0 0 auto;
}

.select2-container--bootstrap-5.select2-container--focus .select2-selection,
.select2-container--bootstrap-5.select2-container--open .select2-selection {
  border-color: var(--ch-green-deep);
  box-shadow: 0 0 0 .2rem rgba(var(--ch-green-rgb), .18);
}

.select2-container--bootstrap-5 .select2-selection--single .select2-selection__rendered {
  color: var(--default-text-color);
}

.select2-container--bootstrap-5 .select2-selection--single .select2-selection__placeholder,
.select2-container--bootstrap-5 .select2-search--inline .select2-search__field::placeholder {
  color: var(--text-muted);
}

/* The open menu. */
.select2-container--bootstrap-5 .select2-dropdown {
  background-color: var(--custom-white);
  border-color: var(--input-border);
  color: var(--default-text-color);
}

.select2-container--bootstrap-5 .select2-dropdown .select2-search .select2-search__field {
  background-color: var(--form-control-bg);
  border-color: var(--input-border);
  color: var(--default-text-color);
  font-size: .875rem;
}

.select2-container--bootstrap-5 .select2-dropdown .select2-search .select2-search__field:focus {
  border-color: var(--ch-green-deep);
  box-shadow: 0 0 0 .2rem rgba(var(--ch-green-rgb), .18);
}

/* The options in the open menu.
   Every rule from here down repeats `.select2-results__options` in the selector
   even though nothing in the markup needs it. That is deliberate: the
   select2-bootstrap-5-theme package writes its option rules through that class,
   so a three-class selector of ours loses to it however late this file loads.
   Matching its shape puts us on equal specificity, and later wins. Without it
   an option came out at 1rem — two pixels larger than every other control on
   the form and reading as bolder for it — and a chosen one came out in
   Bootstrap's own #0d6efd blue, which belongs to no part of this brand. */
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option {
  color: var(--default-text-color);
  font-size: .875rem;
  font-weight: 400;
}

/* Hover and keyboard focus: the theme's own hover surface, not the package's
   fixed light grey, which stayed light grey in dark mode with black text on it. */
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option.select2-results__option--highlighted {
  background-color: var(--default-background);
  color: var(--default-text-color);
}

/* Chosen: the same soft brand green as the chip the choice becomes, rather than
   a solid fill. It has to read as "already picked" beside the hover state, not
   shout over it. */
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option.select2-results__option--selected,
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option[aria-selected="true"]:not(.select2-results__option--highlighted) {
  background-color: rgba(var(--ch-green-rgb), .16);
  color: var(--default-text-color);
  font-weight: 500;
}

/* Chosen and under the pointer at the same time — one step deeper, so moving
   down the list still tells you where you are. */
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option.select2-results__option--selected.select2-results__option--highlighted {
  background-color: rgba(var(--ch-green-rgb), .28);
  color: var(--default-text-color);
}

.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option.select2-results__option--disabled,
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option[aria-disabled="true"] {
  color: var(--text-muted);
}

/* Multiple: one chip per choice, in the brand's own soft green.
   The selector has to carry .select2-selection__rendered as well, because that is
   what the select2-bootstrap-5-theme package's own chip rule does — three classes
   loses to four however late this file loads. Its metrics (.35em/.65em padding,
   1rem type, a .375rem margin on every side) are what made the tag picker tower
   over the inputs beside it; the gap on the selection does the spacing now, so the
   chip's own margin comes off. */
.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice {
  background-color: rgba(var(--ch-green-rgb), .16);
  border: 1px solid rgba(var(--ch-green-rgb), .35);
  border-radius: .25rem;
  color: var(--default-text-color);
  font-size: .8125rem;
  line-height: 1.4;
  margin: 0;
  padding: .0625rem .375rem;
  display: inline-flex;
  align-items: center;
}

.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice .select2-selection__choice__display {
  font-size: .8125rem;
  padding-inline-start: 0;
}

[data-theme-mode="dark"] .select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice {
  color: var(--default-text-color);
}

/* The remove control is a background-image cross in this theme, not a glyph, so
   only its box is ours to set. */
.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice .select2-selection__choice__remove {
  width: .625rem;
  height: .625rem;
  padding: 0;
  margin-inline-end: .375rem;
  background-size: .625rem auto;
}

/* Sizes, so a Select2 in a filter bar matches the .form-select-sm it replaced. */
.select2-container--bootstrap-5 .select2-selection.form-select-sm,
.select2-container--bootstrap-5 .form-select-sm .select2-selection {
  min-height: calc(1.5em + .5rem + 2px);
  padding: .25rem .5rem;
  font-size: .8125rem;
}

/* The small single keeps room for its arrow too (the rule above resets all four
   sides; the arrow sits in the end padding). */
.select2-container--bootstrap-5 .select2-selection--single.form-select-sm,
.select2-container--bootstrap-5 .form-select-sm .select2-selection--single {
  padding-inline-end: 2rem;
}

/* Same specificity trick as the options above — chairhog-select.js puts the size
   class on the dropdown itself, so the package's own `.form-select-sm ~ …`
   sibling rule never reaches it and its 1rem base rule would otherwise stand. */
.select2-container--bootstrap-5 .select2-dropdown.form-select-sm .select2-results__options .select2-results__option {
  font-size: .8125rem;
}

/* Validation. jQuery Validation puts .is-invalid on the original <select>,
   which Select2 hides and then inserts its container directly after — so the
   adjacent-sibling selector is the one that reaches the visible control. */
select.is-invalid + .select2-container--bootstrap-5 .select2-selection {
  border-color: rgb(var(--danger-rgb));
}

select.is-invalid + .select2-container--bootstrap-5.select2-container--focus .select2-selection,
select.is-invalid + .select2-container--bootstrap-5.select2-container--open .select2-selection {
  box-shadow: 0 0 0 .2rem rgba(var(--danger-rgb), .18);
}

/* Inside an off-canvas or a modal the dropdown is rendered into that panel, so
   it has to clear the panel's own stacking context. */
.offcanvas .select2-container--open .select2-dropdown,
.modal .select2-container--open .select2-dropdown { z-index: 1056; }

/* ==========================================================================
   Back-to-top vs. an open panel
   custom.js writes .scrollToTop's display inline on every scroll event, so the
   only way to take it out while an off-canvas or modal is open is to outrank
   that inline style. chairhog-ui.js puts the class on <body>.
   ========================================================================== */
body.ch-overlay-open .scrollToTop { display: none !important; }

/* SweetAlert marks the body itself while a dialog is up, and the button floats
   over that too. Same rule, its own class. */
body.swal2-shown .scrollToTop { display: none !important; }

/* ==========================================================================
   Role picker (Views/Team/Invite.cshtml, rendered by chairhog-invite.js)
   Three cards, one radio each. The state has to be readable from across the
   room, so the whole card carries it — brand border, tinted panel, filled icon
   and a tick — rather than a 1em radio dot in the corner. The input stays a
   real radio (arrow keys, screen readers); it is only moved out of sight.
   ========================================================================== */
.ch-role-cards { display: grid; gap: .75rem; }

.ch-role-card { position: relative; }

.ch-role-card__input {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  width: 1px;
  height: 1px;
  opacity: 0;
  margin: 0;
}

.ch-role-card__body {
  display: flex;
  align-items: flex-start;
  gap: .875rem;
  width: 100%;
  margin: 0;
  padding: 1rem;
  cursor: pointer;
  border: 2px solid var(--default-border);
  border-radius: .5rem;
  background-color: var(--custom-white);
  transition: border-color .15s ease, background-color .15s ease;
}

.ch-role-card__body:hover { border-color: rgba(var(--ch-green-rgb), .55); }

.ch-role-card__input:focus-visible + .ch-role-card__body {
  outline: 2px solid var(--ch-green);
  outline-offset: 2px;
}

.ch-role-card__input:checked + .ch-role-card__body {
  border-color: var(--ch-green-deep);
  background-color: rgba(var(--ch-green-rgb), .10);
}

.ch-role-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 2.5rem;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  font-size: 1.125rem;
  background-color: var(--default-background);
  color: var(--text-muted);
}

.ch-role-card__input:checked + .ch-role-card__body .ch-role-card__icon {
  background-color: var(--ch-green-deep);
  color: #fff;
}

.ch-role-card__text { flex: 1 1 auto; min-width: 0; }
.ch-role-card__name { display: block; font-size: .9375rem; font-weight: 600; }
.ch-role-card__summary { display: block; font-size: .75rem; color: var(--text-muted); margin-bottom: .5rem; }

.ch-role-card__list { list-style: none; margin: 0; padding: 0; font-size: .75rem; color: var(--text-muted); }
.ch-role-card__list li { display: flex; align-items: flex-start; gap: .375rem; margin-bottom: .125rem; }
.ch-role-card__list i { flex: 0 0 auto; line-height: 1.5; }
.ch-role-card__cannot { color: rgb(var(--danger-rgb)); opacity: .8; }

/* The tick only exists once the card is the chosen one. */
.ch-role-card__tick {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 1.5rem;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background-color: var(--ch-green-deep);
  color: #fff;
  font-size: .8125rem;
  opacity: 0;
  transform: scale(.7);
  transition: opacity .15s ease, transform .15s ease;
}

.ch-role-card__input:checked + .ch-role-card__body .ch-role-card__tick { opacity: 1; transform: none; }

@media (min-width: 992px) {
  .ch-role-cards { grid-template-columns: repeat(3, 1fr); }
  .ch-role-card__body { flex-direction: column; }
  .ch-role-card__tick { position: absolute; inset-block-start: .75rem; inset-inline-end: .75rem; }
}

/* ==========================================================================
   Covers heatmap (Views/Bookings/Today.cshtml, drawn by chairhog-today.js)
   Seven day rows against ~40 fifteen-minute columns. The grid scrolls inside
   its own box so the page itself never scrolls sideways, and the day column
   stays stuck to the left edge while you scroll through the service.
   The five levels are tints of the brand green, defined once here so light and
   dark mode both come off the same tokens.
   ========================================================================== */
.ch-heatmap { position: relative; }

.ch-heatmap__scroll {
  overflow-x: auto;
  overflow-y: hidden;
  padding-block-start: .25rem;
  /* overflow:auto clips what you see, but the grid is a table wider than the box
     and the browser still counted it in the ancestors' scrollWidth — which put a
     horizontal scrollbar on the whole page at phone widths. contain:paint keeps
     the overflow to this box, where it belongs. The tooltip is a sibling of this
     element rather than a child, so it is not affected. */
  contain: paint;
}

/* One size for every slot column, stated once. The table is exactly as wide as its
   content: stretched to the card (min-width: 100%) the browser shared the spare width
   out unevenly, and the hour labels — real text inside a 14px column — made their
   columns wider still, so the blocks came out in three or four different sizes. */
.ch-heatmap { --ch-heat-cell: 16px; --ch-heat-row: 22px; }

.ch-heatmap__table {
  border-collapse: separate;
  border-spacing: 2px;
  table-layout: fixed;
  width: max-content;
  margin: 0;
}

.ch-heatmap__day {
  position: sticky;
  inset-inline-start: 0;
  z-index: 2;
  background-color: var(--custom-white);
  padding-inline-end: .625rem;
  text-align: start;
  font-weight: 500;
  white-space: nowrap;
}

.ch-heatmap__day-name { display: block; font-size: .75rem; line-height: 1.2; }
.ch-heatmap__day-date { display: block; font-size: .6875rem; color: var(--text-muted); line-height: 1.2; }

.ch-heatmap__table tr.is-today .ch-heatmap__day-name { color: var(--ch-green-deep); font-weight: 600; }
[data-theme-mode="dark"] .ch-heatmap__table tr.is-today .ch-heatmap__day-name { color: var(--ch-green); }

.ch-heatmap__slot-head {
  position: relative;
  width: var(--ch-heat-cell);
  min-width: var(--ch-heat-cell);
  max-width: var(--ch-heat-cell);
  height: 1rem;
  padding: 0;
  font-size: .625rem;
  font-weight: 500;
  color: var(--text-muted);
  text-align: start;
  white-space: nowrap;
}

/* Only the on-the-hour columns carry a visible label. It is taken out of the flow
   (absolute) so it overhangs the columns after it without widening its own — the
   cells are 16px wide and "19:00" is not. */
.ch-heatmap__slot-head.is-hour > span:first-child {
  position: absolute;
  left: 0;
  top: 0;
  line-height: 1;
}

.ch-heatmap__cell {
  width: var(--ch-heat-cell);
  min-width: var(--ch-heat-cell);
  max-width: var(--ch-heat-cell);
  height: var(--ch-heat-row);
  padding: 0;
  border-radius: 2px;
  background-color: var(--default-background);
  cursor: default;
}

.ch-heatmap__cell[data-level="1"] { background-color: rgba(var(--ch-green-rgb), .25); }
.ch-heatmap__cell[data-level="2"] { background-color: rgba(var(--ch-green-rgb), .50); }
.ch-heatmap__cell[data-level="3"] { background-color: rgba(var(--ch-green-rgb), .75); }
.ch-heatmap__cell[data-level="4"] { background-color: var(--ch-green-deep); }

[data-theme-mode="dark"] .ch-heatmap__cell[data-level="4"] { background-color: var(--ch-green); }

.ch-heatmap__cell:hover { outline: 2px solid var(--ch-ink); outline-offset: -1px; }
[data-theme-mode="dark"] .ch-heatmap__cell:hover { outline-color: #fff; }

.ch-heatmap__total {
  position: sticky;
  inset-inline-end: 0;
  z-index: 2;
  background-color: var(--custom-white);
  padding-inline-start: .625rem;
  font-size: .75rem;
  font-weight: 600;
  text-align: end;
  white-space: nowrap;
}

/* Legend, in the card header. */
.ch-heatmap__legend {
  display: flex;
  align-items: center;
  gap: .25rem;
  font-size: .6875rem;
  color: var(--text-muted);
}

.ch-heatmap__swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 2px;
  background-color: var(--default-background);
}

.ch-heatmap__swatch[data-level="1"] { background-color: rgba(var(--ch-green-rgb), .25); }
.ch-heatmap__swatch[data-level="2"] { background-color: rgba(var(--ch-green-rgb), .50); }
.ch-heatmap__swatch[data-level="3"] { background-color: rgba(var(--ch-green-rgb), .75); }
.ch-heatmap__swatch[data-level="4"] { background-color: var(--ch-green-deep); }
[data-theme-mode="dark"] .ch-heatmap__swatch[data-level="4"] { background-color: var(--ch-green); }

/* One shared tooltip, positioned over the cell the pointer is on. */
.ch-heatmap__tip {
  position: absolute;
  z-index: 5;
  transform: translate(-50%, calc(-100% - 6px));
  padding: .375rem .625rem;
  border-radius: .375rem;
  background-color: var(--ch-dark);
  color: #fff;
  font-size: .6875rem;
  line-height: 1.35;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .25);
}

.ch-heatmap__tip[hidden] { display: none; }
.ch-heatmap__tip-when { display: block; opacity: .75; }
.ch-heatmap__tip-covers { display: block; font-size: .8125rem; font-weight: 600; }
.ch-heatmap__tip-sub { display: block; opacity: .75; }

/* ==========================================================================
   The header and the menu bar meet
   Both are position:fixed, and the template gave each of them its own idea of
   where the header ends. The header's height is whatever its tallest child is —
   the logo, at 2rem between .85rem of padding, so 3.7625rem with its border —
   while the menu bar below it is pinned at a flat 3.95rem. That leaves about
   three pixels of daylight between the two, and the page scrolls behind it: the
   content flickers through the slot on every scroll.

   One token now fixes the header's height and starts the menu bar at exactly
   that line, so the pair cannot drift apart again. 3.75rem is the number the
   template itself already assumes for the header (.main-content offsets by it);
   the logo's own vertical padding is what made it that odd fraction taller, and
   the flex row it sits in centres it perfectly well without any.
   ========================================================================== */
:root {
  --ch-header-height: 3.75rem;
}

.app-header {
  height: var(--ch-header-height);
}

.app-header .horizontal-logo {
  padding-block: 0;
}

@media (min-width: 992px) {
  [data-nav-layout="horizontal"] .app-sidebar {
    inset-block-start: var(--ch-header-height);
  }
}

/* ==========================================================================
   Text areas
   One size everywhere: as wide as whatever holds it, tall enough to write a
   paragraph into without scrolling, and never tall enough to push the buttons
   under it off the screen. Between those two bounds it is still the reader's
   to drag, which is why the resize handle stays — vertical only, because a
   textarea wider than its column breaks the form around it.

   The exception is the one textarea nobody writes a paragraph into: Select2
   builds its inline search box out of one rather than an <input>, so a blanket
   rule turns every tag picker in the admin into a 150px-tall block. Same
   principle as the SKIP list in chairhog-select.js — a control another library
   owns is that library's to size.
   ========================================================================== */
textarea:not(.select2-search__field) {
  width: 100%;
  min-height: 150px;
  max-height: 300px;
  resize: vertical;
}

/* ==========================================================================
   A dialog on top of an open panel
   The other half of the same job chairhog-ui.js does for the focus trap: a
   modal opened over an off-canvas has to be in front of it, and out of the box
   it is behind.

   Bootstrap layers the two deliberately — off-canvas backdrop 1040, off-canvas
   1045, modal backdrop 1050, modal 1055 — so a dialog opened over a panel lands
   on top of it and the panel dims behind. styles.min.css drops the modal to 105
   and its backdrop to 104, which is enough to clear the template's own header
   and menu bar and nothing else: with a panel open, the panel's backdrop sat
   over the dialog and swallowed every click aimed at it.

   Restoring Bootstrap's own two numbers is all it takes. Nothing else in the
   app lives between them and the header — SweetAlert (1060), tooltips and
   popovers all still come out in front.
   ========================================================================== */
.modal { z-index: 1055; }
.modal-backdrop { z-index: 1050; }

/* ------------------------------------------------------------
   Venue/SiteEdit — split shifts
   ------------------------------------------------------------ */

/* The second pair of opening times only exists for a site that closes during the
   day and opens again. chairhog-site-edit.js toggles [hidden] on those cells; a
   UA's [hidden] rule and the table's own display rules are close enough in
   specificity to be worth saying out loud rather than relying on. */
#hours-table .ch-split-shift[hidden] {
  display: none;
}

/* ------------------------------------------------------------
   Widget admin — Widget/DomainVerification, Widget/Style, Widget/EmbedPreview
   ------------------------------------------------------------ */

/* The verification history: a dot per check and a line joining them. */
.ch-timeline-dot {
  display: block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex: 0 0 auto;
  margin-top: 4px;
}
.ch-timeline-line {
  display: block;
  flex: 1 1 auto;
  width: 2px;
  min-height: 12px;
  background: var(--default-border);
}

/* A colour the scan found. */
.ch-swatch {
  width: 56px;
  height: 56px;
}

/* The custom CSS box on Widget/Style — code, so a monospace face and no wrapping surprises. */
.ch-css-editor {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 12px;
  line-height: 1.5;
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
  tab-size: 2;
}

/* The live preview on Widget/Style is the real widget markup (.ch-widget and its parts)
   with the draft's tokens set on #widget-preview as --ch-widget-*, the way _WidgetLayout
   sets them on <body>, so the custom CSS box applies to it exactly as it will inside the
   iframe. The widget root is written for a whole page; inside a card it is boxed. */
#widget-preview .ch-widget {
  min-height: 0;
  border: 1px solid var(--w-border);
  border-radius: var(--w-radius);
  overflow: hidden;
}
#widget-preview .ch-widget-shell { padding: 18px 14px 22px; }
#widget-preview .ch-widget-foot { margin-top: 14px; }

/* The current widget logo beside the upload control. */
.ch-logo-preview {
  width: 64px;
  height: 64px;
  flex: 0 0 auto;
  overflow: hidden;
  background: #fff;
}
.ch-logo-preview img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

/* The hosted booking page's QR code on Widget/EmbedPreview — a preview beside its
   download button, not something anyone scans off the screen. Its own class: the MFA
   setup code (.ch-qr) must stay large. */
.ch-qr-hosted {
  width: 140px;
  height: 140px;
  image-rendering: pixelated;
}

/* The example site's menu is decoration: spans, not links, so nothing dead is focusable. */
.ch-fakesite-nav nav span {
  font-size: .85rem;
  color: inherit;
  opacity: .85;
}
.ch-fakesite-nav nav span.is-cta {
  padding: .3rem .8rem;
  border: 1px solid currentColor;
  border-radius: 999px;
  opacity: 1;
}

/* ------------------------------------------------------------
   Settings/Invoice, Settings/Invoices — printing
   ------------------------------------------------------------ */

/* The invoice pages are ordinary admin pages on screen and a sheet of paper when
   printed: the header, menu bar, footer, breadcrumb and buttons go, the content takes
   the whole page, and each invoice in the "all invoices" list starts a new sheet.
   "Print or save as PDF" is window.print() (chairhog-invoice.js) — there is no PDF
   library, because the browser's own dialog already makes one. */
@media print {
  .ch-invoice-page ~ *,
  .app-header,
  .app-sidebar,
  .footer,
  .scrollToTop,
  .ch-no-print {
    display: none !important;
  }

  .main-content,
  .app-content,
  .container-fluid {
    margin: 0 !important;
    padding: 0 !important;
  }

  .ch-invoice-page > [class*="col-"] {
    flex: 0 0 100%;
    max-width: 100%;
  }

  .ch-invoice {
    border: 0;
    box-shadow: none;
    page-break-after: always;
    break-after: page;
  }

  .ch-invoice:last-child {
    page-break-after: auto;
    break-after: auto;
  }
}

/* ==========================================================================
   Guest booking widget — the published style (Widget/Preview, 2026-08-22)
   ==========================================================================
   Section 5 above is the widget's layout and its tokens as they were for the
   prototype; those values are now the fallbacks. _WidgetLayout.cshtml writes
   the style the venue published on Widget/Style (site, falling back to
   company, falling back to the defaults) onto <body> as --ch-widget-*
   custom properties, and this block maps them onto the --w-* tokens the
   .ch-widget block is built from. It has to come last to outrank section 5.

   Two things are decided here on purpose:
   - the prefers-color-scheme swap in section 5 no longer fires for the
     widget. A form carrying a venue's own colours should look the same in a
     dark-mode browser as in a light one; the venue chose the colours.
   - a dark published background gets light text and a slightly lighter
     card, from .ch-widget-dark, which the layout adds when the background's
     luminance says so (StaticWidgetColours.IsDark). */
.ch-widget {
  --w-accent: var(--ch-widget-accent, #5E7D0E);
  --w-accent-ink: var(--ch-widget-accent-ink, #FFFFFF);
  --w-surface: var(--ch-widget-surface, #FFFFFF);
  --w-radius: var(--ch-widget-radius, 8px);
  --w-sans: var(--ch-widget-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
  --w-serif: var(--ch-widget-font, Georgia, "Times New Roman", serif);
  --w-card: #FFFFFF;
  --w-text: #23272B;
  --w-muted: #6B7280;
  --w-border: #E3E6EA;
}

.ch-widget-dark {
  --w-card: color-mix(in srgb, var(--w-surface) 86%, #FFFFFF);
  --w-text: #F3F4F6;
  --w-muted: #B7BDC7;
  --w-border: color-mix(in srgb, var(--w-surface) 68%, #FFFFFF);
}

/* The card sits on the surface; on a white background it needs its border to
   read as a card at all, and on a tinted one it reads by its fill. */
.ch-widget-card { background: var(--w-card); }

/* The venue's logo above the name — a fixed box, whatever was uploaded. */
.ch-widget-logo {
  display: block;
  max-height: 56px;
  max-width: 200px;
  width: auto;
  height: auto;
  margin: 0 auto 10px;
}

/* Option rows carry their text in one block so the chevron stays put. */
.ch-opt-body { flex: 1; min-width: 0; }

/* Date chips: day name above the number, month below it. */
.ch-chip-date { min-width: 52px; padding: 7px 8px; line-height: 1.25; }
.ch-chip-day, .ch-chip-mon { display: block; font-size: 10px; opacity: .7; }

/* The "choose a table" step is a two-up grid of option rows. */
.ch-table-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-bottom: 4px; }
.ch-table-grid .ch-opt { margin-bottom: 0; padding: 10px 12px; }
.ch-table-grid .ch-opt:disabled { opacity: .4; cursor: not-allowed; }
.ch-table-grid .ch-opt:disabled:hover { border-color: var(--w-border); }

/* A number box for a party range too wide for chips. */
.ch-field input[type="number"] { max-width: 140px; }

/* Help text that carries a warning — the large-party message. */
.ch-help-alert { color: var(--w-text); font-weight: 500; }
.ch-help-spaced { margin-bottom: 12px; }
.ch-optional { font-weight: 400; color: var(--w-muted); }
.ch-nowrap { white-space: nowrap; }

/* Errors that belong to the whole form, and the notice that a slot went
   while the guest was typing. */
.ch-form-error { font-size: 12.5px; color: #B3261E; margin: 0 0 12px; }
.ch-widget-dark .ch-form-error { color: #F2B8B5; }
.ch-notice {
  font-size: 12.5px; margin: 0 0 14px; padding: 10px 12px;
  border: 1px solid var(--w-accent); border-radius: var(--w-radius);
  background: color-mix(in srgb, var(--w-accent) 10%, transparent);
}

/* Buttons that stand alone under a message, and the "show more dates" link. */
.ch-btn-wide { flex: 1 1 auto; }
.ch-btn-inline { width: auto; padding: 8px 12px; margin-top: 8px; font-size: 12.5px; }

/* Private hire (chairhog-widget.js). The switch between "a table" and "the
   venue" at the top of the date step is a two-way segmented control; the terms
   the guest has to accept sit in their own box above the tick. */
.ch-seg {
  display: flex; gap: 4px; padding: 4px; margin-bottom: 16px;
  border: 1px solid var(--w-border); border-radius: var(--w-radius);
  background: color-mix(in srgb, var(--w-border) 35%, transparent);
}
.ch-seg button {
  flex: 1 1 0; padding: 9px 10px; border: 0; border-radius: calc(var(--w-radius) - 3px);
  background: transparent; color: var(--w-muted); font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer; transition: background-color .15s ease, color .15s ease;
}
.ch-seg button[aria-pressed="true"] { background: var(--w-card); color: var(--w-text); box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.ch-seg button:focus-visible { outline: 2px solid var(--w-accent); outline-offset: -2px; }
.ch-terms {
  font-size: 12.5px; line-height: 1.5; margin: 0 0 10px; padding: 12px 14px; max-height: 220px; overflow: auto;
  border: 1px solid var(--w-border); border-radius: var(--w-radius); white-space: pre-line;
  background: color-mix(in srgb, var(--w-border) 25%, transparent);
}
.ch-terms-title { display: block; font-weight: 600; margin-bottom: 4px; }
.ch-opt-seats { font-size: 12px; color: var(--w-muted); white-space: nowrap; }

/* The honeypot. Out of sight, out of the tab order, out of the accessibility
   tree — a person never meets it. Not display:none, which some bots skip. */
.ch-hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* The widget's own focus rings follow the accent, whatever it is. */
.ch-widget .ch-btn:focus-visible, .ch-widget .ch-opt:focus-visible, .ch-widget .ch-chip:focus-visible {
  outline: 2px solid var(--w-accent); outline-offset: 2px;
}

/* ==========================================================================
   Organisation switcher (Views/Shared/Components/OrganizationSwitcher/Default.cshtml)
   The header pill that says which organisation every page is showing, and the
   dropdown that switches to another. A person can belong to several
   organisations — a developer looking after several clients — so this has to be
   readable at a glance in both header modes: a bordered pill on the template's
   own surface tokens, the brand green only for the "current" marks. Below the
   md breakpoint the words go and the avatar alone stays, next to the bell.
   ========================================================================== */
.ch-org-switcher__toggle {
  /* .header-link is written for an <a>; this is a <button>, for the keyboard. */
  background: none;
  border: 0;
  color: var(--default-text-color);
  cursor: pointer;
  padding-inline: .35rem;
}

.ch-org-switcher__toggle:focus-visible {
  outline: 2px solid rgb(var(--primary-rgb));
  outline-offset: -2px;
  border-radius: .5rem;
}

.ch-org-switcher__pill {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  min-width: 15rem;
  max-width: 20rem;
  padding: .3rem .6rem .3rem .4rem;
  border: 1px solid var(--default-border);
  border-radius: 2rem;
  background: rgba(var(--primary-rgb), .06);
  line-height: 1.15;
  text-align: start;
  transition: background-color .15s ease, border-color .15s ease;
}

.ch-org-switcher__toggle:hover .ch-org-switcher__pill,
.ch-org-switcher__toggle[aria-expanded="true"] .ch-org-switcher__pill {
  background: rgba(var(--primary-rgb), .12);
  border-color: rgba(var(--primary-rgb), .35);
}

.ch-org-switcher__avatar {
  flex-shrink: 0;
}

.ch-org-switcher__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.ch-org-switcher__label {
  font-size: .625rem;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* The pill's identity line — the verified website, or the organisation's name when it
   has no domain yet. The dropdown rows keep their own name/meta classes below. */
.ch-org-switcher__domain {
  font-size: .8125rem;
  font-weight: 600;
  color: var(--default-text-color);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ch-org-switcher__chevron {
  flex-shrink: 0;
  /* Pushed to the pill's right edge — the pill has a min-width, so without this
     the chevron would sit in the middle when the organisation name is short. */
  margin-inline-start: auto;
  font-size: .9rem;
  color: var(--text-muted);
}

/* The dropdown: one row per organisation, each a <button> in a form. A person can
   manage a hundred or more, so the menu scrolls rather than outgrowing the screen. */
.ch-org-switcher__menu {
  width: 22rem;
  max-width: calc(100vw - 1.5rem);
  max-height: min(70vh, 32rem);
  overflow-y: auto;
}

/* The filter above the rows (rendered past a handful of organisations). It stays
   put while the rows scroll underneath it. */
.ch-org-switcher__search {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: .5rem .75rem;
  background: var(--custom-white);
  border-bottom: 1px solid var(--default-border);
}

.ch-org-switcher__item {
  width: 100%;
  border: 0;
  background: none;
  text-align: start;
  padding-block: .55rem;
}

.ch-org-switcher__item.is-current {
  background: rgba(var(--ch-green-rgb), .12);
  cursor: default;
}

.ch-org-switcher__item:not(.is-current):hover,
.ch-org-switcher__item:not(.is-current):focus-visible {
  background: rgba(var(--primary-rgb), .08);
}

.ch-org-switcher__item:focus-visible {
  outline: 2px solid rgb(var(--primary-rgb));
  outline-offset: -2px;
}

.ch-org-switcher__row-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  margin-inline-end: .5rem;
}

.ch-org-switcher__row-name {
  font-size: .8125rem;
  font-weight: 600;
  color: var(--default-text-color);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ch-org-switcher__row-meta {
  font-size: .6875rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ch-org-switcher__dot {
  margin-inline: .3rem;
}

/* Organization/Index: the row you are working in. */
.ch-org-current-row > td {
  background: rgba(var(--ch-green-rgb), .08);
}

@media (max-width: 767.98px) {
  .ch-org-switcher__text,
  .ch-org-switcher__chevron {
    display: none;
  }

  .ch-org-switcher__pill {
    min-width: 0;
    padding: .25rem;
    gap: 0;
  }
}

/* ==========================================================================
   Settings/Billing — the two "how you pay" tiles (monthly / yearly).
   Buttons that behave as radios: a border that thickens and takes the brand
   colour when selected, the same in both themes. Figures inside are plain
   spans so the whole tile is one click target.
   ========================================================================== */
.ch-plan-tile {
  display: block;
  padding: 14px 16px;
  border: 2px solid rgba(var(--ch-status-finished-rgb), .35);
  border-radius: 8px;
  background: transparent;
  color: inherit;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.ch-plan-tile:hover { border-color: rgba(var(--ch-green-rgb), .6); }
.ch-plan-tile.is-selected {
  border-color: rgb(var(--ch-green-rgb));
  box-shadow: 0 0 0 3px rgba(var(--ch-green-rgb), .15);
}
.ch-plan-tile:focus-visible { outline: 2px solid rgb(var(--ch-green-rgb)); outline-offset: 2px; }
.ch-plan-tile s { opacity: .6; margin-left: 4px; }

/* ==========================================================================
   Settings/Billing — the plan. One card: the sites, then how you pay, then
   "what you pay today". The trial notice is a brand callout rather than the
   template's cyan info alert, so it sits with the rest of the page.
   ========================================================================== */
.ch-callout {
  display: flex;
  align-items: flex-start;
  gap: .75rem;
  padding: .875rem 1rem;
  border: 1px solid rgba(var(--ch-green-rgb), .35);
  border-left: 4px solid rgb(var(--ch-green-rgb));
  border-radius: .5rem;
  background: rgba(var(--ch-green-rgb), .08);
  color: inherit;
}
.ch-callout__icon {
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(var(--ch-green-rgb), .18);
  color: var(--ch-green-deep);
  font-size: 1rem;
}
[data-theme-mode="dark"] .ch-callout__icon { color: var(--ch-green); }
.ch-plan-step {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .5rem;
}
.ch-plan-step__n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: rgb(var(--primary-rgb));
  color: #fff;
  font-size: .75rem;
  font-weight: 600;
}
.ch-plan-quote {
  border: 1px solid rgba(var(--ch-green-rgb), .45);
  border-radius: .5rem;
  background: rgba(var(--ch-green-rgb), .06);
}
.ch-plan-quote__total { font-size: 1.375rem; font-weight: 600; line-height: 1.2; }
.ch-plan-sites label { cursor: pointer; }

/* ==========================================================================
   Card bodies that can outgrow their neighbours (Analytics: cards in a row
   share one height, so a long list scrolls inside its card instead of
   stretching the whole row).
   ========================================================================== */
.ch-card-scroll {
  max-height: 24rem;
  overflow-y: auto;
}

/* ---- Flush tables in cards ----
   A card whose body is p-0 with a table in it (Team/Users, the invoices on
   Settings/Billing, …): the header's title sits 1.25rem in, but Valex pads table
   cells 6px, so the first column started 14px to the left of the title and the
   last ended short of the right edge. The outer columns take the card's inset;
   !important because Valex sets the cell padding with it. */
.card-body.p-0 .table > :not(caption) > * > :first-child { padding-inline-start: 1.25rem !important; }
.card-body.p-0 .table > :not(caption) > * > :last-child { padding-inline-end: 1.25rem !important; }
