/* ============================================================
   JLM Booking — Pass 2 design
   Two fully designed themes driven by CSS custom properties:
   - Light: warm paper + deep leaf green (default / system light)
   - Dark:  deep-forest theme (designed, not an inversion)
   Theme resolution:
   - No data-theme on <html>  -> follows prefers-color-scheme
   - data-theme="light"      -> light, overrides the media query
   - data-theme="dark"       -> dark,  overrides the media query
   The saved choice ("jlm-theme" in localStorage: system|light|dark)
   is applied before first paint by the inline script in index.html.
   Gold (--accent) is decorative only: rules, rings and badges.
   It is never used for body text.
   ============================================================ */

/* ---------- Light theme (tokens) — re-based on Jamie's logo,
   Oct 25, 2026: deep #002C27, leaf deepened for AA #4C7C3E,
   highlight tint #E7F0DC. Mirrors the app's ThemePalette. ---------- */
:root,
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #F7F5EF;
  --surface: #FFFFFF;
  --surface-alt: #E7F0DC;
  --primary: #002C27;
  --action: #3E6B31;
  --on-action: #FFFFFF;
  --accent: #C29B3C;
  --ink: #14231C;
  --ink-2: #44563C;
  --divider: #D8E2CC;
  --err: #B00020;
  --success: #2E6B30;
  --header-bg: #002C27;
  --header-ink: #FFFFFF;
  --sel: #DCEBD2;
  --shadow: 0 1px 2px rgba(20, 35, 28, 0.05), 0 10px 30px rgba(20, 35, 28, 0.08);
  --shadow-hover: 0 2px 4px rgba(20, 35, 28, 0.07), 0 14px 36px rgba(20, 35, 28, 0.12);
}

/* ---------- Dark theme (tokens) — the logo's layered greens ---------- */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #03120E;
  --surface: #073428;
  --surface-alt: #0C4634;
  --primary: #B6D7A5;
  --action: #3F7031;
  --on-action: #FFFFFF;
  --accent: #D9B45C;
  --ink: #F2F7EC;
  --ink-2: #B9C9A8;
  --divider: #1E4A3A;
  --err: #DE7A8D;
  --success: #8FCB8F;
  --header-bg: #002C27;
  --header-ink: #F2F7EC;
  --sel: #0E4A35;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 10px 30px rgba(0, 0, 0, 0.35);
  --shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.4), 0 14px 36px rgba(0, 0, 0, 0.45);
}

/* System dark — only when no explicit theme is set, so an explicit
   data-theme="light" always overrides the media query. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #03120E;
    --surface: #073428;
    --surface-alt: #0C4634;
    --primary: #B6D7A5;
    --action: #3F7031;
    --on-action: #FFFFFF;
    --accent: #D9B45C;
    --ink: #F2F7EC;
    --ink-2: #B9C9A8;
    --divider: #1E4A3A;
    --err: #DE7A8D;
    --success: #8FCB8F;
    --header-bg: #002C27;
    --header-ink: #F2F7EC;
    --sel: #0E4A35;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 10px 30px rgba(0, 0, 0, 0.35);
    --shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.4), 0 14px 36px rgba(0, 0, 0, 0.45);
  }
}

/* ---------- Base ---------- */
* { box-sizing: border-box; }

:root {
  --font-display: "Iowan Old Style", Palatino, "Palatino Linotype", Georgia, serif;
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --radius: 14px;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--bg);
  transition: background-color 0.25s ease, color 0.25s ease;
  /* FULL REVIEW C (half-loaded footer): the page is a full-height
     column and <main> grows, so on a short or still-loading screen
     the footer sits at the bottom of the window instead of floating
     mid-page over an empty void. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

::selection { background: var(--surface-alt); color: var(--ink); }

[hidden] { display: none !important; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.2;
  color: var(--primary);
}

h2 {
  font-size: 24px;
  margin: 28px 0 12px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--accent);
}

a { color: var(--primary); }
a:hover { color: var(--action); }

:focus { outline: none; }
:focus-visible {
  outline: 3px solid var(--action);
  outline-offset: 2px;
  border-radius: 6px;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* ---------- Header ---------- */
header {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  padding: 24px 20px;
  background: var(--header-bg);
  color: var(--header-ink);
  border-bottom: 3px solid var(--accent);
  box-shadow: var(--shadow);
}

/* Platform mark floats on the brand colour — NO square/background
   box. Small in the header (0.3.6): the header is the JLB platform
   layer only; the business's own branding lives in .biz-banner. */
header .logo {
  width: 52px;
  height: 52px;
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  object-fit: contain;
  flex: none;
}

header h1 {
  margin: 0;
  font-size: 26px;
  color: var(--header-ink);
}

header .tag {
  margin: 5px 0 0;
  font-size: 15px;
  color: var(--header-ink);
  opacity: 0.88;
  max-width: 46ch;
}

/* Theme toggle — pill sitting on the header in both themes */
.theme-toggle {
  margin-left: auto;
  align-self: flex-start;
  flex: none;
  background: var(--surface-alt);
  color: var(--ink);
  border: 1px solid var(--divider);
  border-radius: 999px;
  padding: 9px 16px;
  font-size: 14px;
  font-weight: 600;
  box-shadow: var(--shadow);
}
.theme-toggle:hover { border-color: var(--accent); }
.theme-toggle:active { transform: translateY(1px); }

/* ---------- Layout ---------- */
main {
  max-width: 720px;
  margin: 0 auto;
  padding: 24px 20px 8px;
  flex: 1 0 auto;
  width: 100%;
  box-sizing: border-box;
}

section { margin-bottom: 8px; }

footer {
  max-width: 720px;
  margin: 32px auto 0;
  padding: 20px;
  font-size: 14px;
  color: var(--ink-2);
  border-top: 1px solid var(--divider);
}
footer a { color: var(--primary); }

/* ---------- Progress ---------- */
#progressWrap {
  position: relative;
  margin: 4px 0 14px;
}
/* Track — a full-width rail behind the fill */
#progressWrap::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 8px;
  background: var(--surface-alt);
  border: 1px solid var(--divider);
  border-radius: 999px;
}
#progressBar {
  position: relative;
  z-index: 1;
  height: 8px;
  background: var(--action);
  border-radius: 999px;
  width: 5%;
  transition: width 0.3s ease;
}
#stepLabel {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 19px;
  color: var(--primary);
  margin: 14px 0 6px;
}

#error {
  color: var(--err);
  /* Reserve ONE line (FULL REVIEW C): the two-line reserve left a
     permanent empty hole under the steps even when nothing was
     wrong. One line keeps most appearances jump-free without the
     standing gap; a longer error still grows the page once. */
  min-height: 1.35em;
  font-weight: 600;
  margin: 4px 0 10px;
}

/* ---------- Buttons ---------- */
button {
  background: var(--action);
  color: var(--on-action);
  border: 1px solid var(--action);
  border-radius: 999px;
  padding: 12px 22px;
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  margin: 6px 6px 6px 0;
  transition: background-color 0.15s ease, color 0.15s ease,
              border-color 0.15s ease, transform 0.1s ease;
}
button:hover { filter: brightness(1.06); }
button:active { transform: translateY(1px); }
/* Disabled (0.3.63, the app's button rule): a genuinely disabled
   button wears the pale tint + secondary ink — unmistakably
   different from the strong action fill, never a faded twin. */
button:disabled { background: var(--surface-alt); border-color: var(--surface-alt); color: var(--ink-2); cursor: default; }
button:disabled:hover { filter: none; }
button:disabled:active { transform: none; }

/* Secondary / unselected picker buttons */
button.ghost {
  background: var(--surface);
  color: var(--primary);
  border: 1px solid var(--divider);
  box-shadow: var(--shadow);
}
button.ghost:hover { border-color: var(--action); filter: none; }

/* Day + time pickers */
button.day,
button.slot {
  border-radius: 999px;
  padding: 10px 18px;
}

/* Selected state — filled, unmistakable, not just an outline */
button.slot[aria-pressed="true"],
button.day[aria-pressed="true"] {
  background: var(--action);
  color: var(--on-action);
  border-color: var(--action);
  box-shadow: var(--shadow);
}

/* Group headcount stepper + promo row + labelled waitlist fields
   (audit round 2): real 48px touch targets, same pill language. */
.spotsstep { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.spotsstep button { min-width: 48px; min-height: 48px; padding: 8px 14px; font-size: 20px; }
.spotsstep button:disabled { opacity: 0.4; cursor: default; }
.spotscount { font-weight: 700; }
.spotslabel { font-weight: 600; }
.promorow { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.promorow input { flex: 1 1 160px; min-height: 48px; }
.promorow button { min-height: 48px; }
label.wlfield { display: block; margin: 8px 0; }
label.wlfield span { display: block; font-weight: 600; margin-bottom: 4px; }
label.wlfield input, label.wlfield select { width: 100%; min-height: 48px; }

/* ---------- Forms ---------- */
fieldset {
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px 20px 14px;
  margin: 14px 0;
}
legend {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 17px;
  color: var(--primary);
  padding: 2px 10px;
  background: var(--surface);
  border: 1px solid var(--divider);
  border-bottom: 2px solid var(--accent);
  border-radius: 999px;
}

label {
  display: block;
  margin: 10px 0;
  font-size: 15px;
  color: var(--ink);
}
label.check {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  color: var(--ink-2);
  font-size: 15px;
}

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="password"],
input[type="search"],
textarea,
select {
  width: 100%;
  padding: 11px 13px;
  font-family: inherit;
  font-size: 16px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: 10px;
  margin-top: 5px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
input[type="text"]:hover,
input[type="email"]:hover,
input[type="tel"]:hover,
input[type="password"]:hover,
input[type="search"]:hover,
textarea:hover,
select:hover { border-color: var(--action); }

/* AUDIT2 F6 (B4): the Step 4 missing-field highlight — the exact
   box submitRequest named gets a clear red frame until it is typed in. */
input.field-bad {
  border: 2px solid #C0392B;
  box-shadow: 0 0 0 3px rgba(192, 57, 43, 0.25);
}

/* W7 (Oct 31, 2026): the Step 4 client-details box — a quiet frame
   once every required detail is filled, a BRIGHT amber outline
   while anything required is still missing, so an un-done required
   step draws the eye before Send is ever tapped. */
.details-box {
  border: 2px solid var(--line, #D8E2CC);
  border-radius: 12px;
  padding: 14px 16px 6px;
  margin: 0 0 14px;
}
.details-box-open {
  border: 3px solid #FFB020;
  box-shadow: 0 0 0 4px rgba(255, 176, 32, 0.35);
}
.details-box-hint { font-weight: 700; margin-top: 0; }

input[type="checkbox"],
input[type="radio"] {
  accent-color: var(--action);
  width: 19px;
  height: 19px;
  flex: none;
  margin-top: 2px;
}
input[type="range"] { accent-color: var(--action); margin-top: 5px; }

/* ---------- Booking-page banner (owner setting, Oct 28, 2026):
   the business's own urgent line at the VERY TOP of the page,
   above the launch ribbon. It must be unmissable: full-width band,
   bold large text, dark words on a high-contrast warm amber —
   readable at phone width without zooming. Rendered only when the
   company profile carries the string; [hidden] otherwise, so an
   absent banner leaves no band and no layout placeholder. */
.page-banner {
  background: #FFB020;
  color: #2B1500;
  text-align: center;
  font-size: 19px;
  font-weight: 800;
  line-height: 1.35;
  letter-spacing: .01em;
  padding: 14px 16px;
  border-bottom: 3px solid #B45309;
  overflow-wrap: break-word;
}
.page-banner[hidden] { display: none; }
/* Dark theme (FULL REVIEW C): the same amber, deepened, so the
   banner sits with the dark palette instead of shouting over it. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .page-banner { background: #7A5200; color: #FFE9B8; border-bottom-color: #FFB020; }
}
:root[data-theme="dark"] .page-banner { background: #7A5200; color: #FFE9B8; border-bottom-color: #FFB020; }

/* ---------- Business banner: the tenant's brand, top of the page
   (0.3.6) — profile picture large, business name, tagline ---------- */
.biz-banner {
  display: flex;
  align-items: center;
  gap: 16px;
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px 18px;
  margin: 14px 0 6px;
}
.biz-banner .biz-logo {
  width: 84px;
  height: 84px;
  object-fit: contain;
  flex: none;
  /* Fix 6 (Oct 26, 2026): tenant logos render on the surface
     colour inside the shared 14px radius — never sharp corners,
     never a white box on the dark UI. */
  border-radius: var(--radius);
  background: var(--surface);
}
.biz-banner .biz-name {
  margin: 0;
  font-size: 22px;
}
.biz-banner .tag {
  margin: 3px 0 0;
  font-size: 14px;
  color: var(--ink-2);
}

/* Step 1 (0.3.6): live search + category headings over the cards */
.svcsearch {
  width: 100%;
  box-sizing: border-box;
  margin: 8px 0 4px;
}
.catch {
  margin: 20px 0 4px;
  font-size: 17px;
}

/* ---------- Cards: services, bookings, quote ---------- */
.svc {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin: 10px 0;
  cursor: pointer;
  transition: box-shadow 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.svc:hover { box-shadow: var(--shadow-hover); border-color: var(--action); }
.svc small {
  display: block;
  font-weight: 400;
  color: var(--ink-2);
  margin-top: 3px;
  line-height: 1.45;
}

.card {
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px 20px;
  margin: 12px 0;
  white-space: pre-line;
}

.quote {
  background: var(--surface);
  border: 1px solid var(--divider);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px 20px;
  margin: 14px 0;
  white-space: pre-line;
  line-height: 1.65;
}

.price {
  font-weight: 700;
  white-space: nowrap;
  color: var(--primary);
  font-size: 17px;
}

.policy {
  white-space: pre-line;
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink-2);
  background: var(--surface-alt);
  border-radius: var(--radius);
  padding: 16px 18px;
  margin: 14px 0;
}

/* ---------- Misc hooks (kept for app.js / index.html) ---------- */
.big {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  color: var(--primary);
}
.fine { font-size: 13px; color: var(--ink-2); opacity: 0.85; }

#wlDone { color: var(--success); font-weight: 600; }

#myBookings .card p { margin: 0 0 8px; }

/* Success wording rendered inline by app.js uses no extra hooks;
   error text is handled by #error above. */

/* ---------- Small screens ---------- */
@media (max-width: 560px) {
  header { padding: 18px 16px; }
  header h1 { font-size: 22px; }
  header .logo { width: 48px; height: 48px; }
  .theme-toggle { margin-left: 0; }
  main { padding: 18px 14px 4px; }
  .svc { padding: 14px; }
}

/* ============================================================
   0.3.0 — settled flow additions
   ============================================================ */

/* Keep content clear of the fixed bottom bar */
body { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
footer { margin-bottom: 24px; }

/* ---------- 3-step indicator ---------- */
#steps {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 2px 0 10px;
}
.stepdot {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-2);
  background: var(--surface-alt);
  border: 1px solid var(--divider);
  border-radius: 999px;
  padding: 6px 12px;
}
.stepdot.current {
  background: var(--action);
  color: var(--on-action);
  border-color: var(--action);
}
.stepdot.done { color: var(--primary); border-color: var(--action); }

/* ---------- Fixed bottom action bar (every step, safe-area aware) ---------- */
#actionBar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
  background: var(--surface);
  border-top: 2px solid var(--action);
  box-shadow: 0 -6px 24px rgba(28, 36, 23, 0.14);
}
#barSummary {
  flex: 1 1 auto;
  min-width: 0;
  /* Shrink-first (MEGA PASS, Oct 31, 2026): the font SHRINKS with
     narrow screens before anything is allowed to truncate — the
     chosen service's name in the sticky bar was being ellipsized
     (W-07). The 2-line clamp below is now the last resort only. */
  font-size: clamp(12px, 3.4vw, 14px);
  font-weight: 600;
  color: var(--primary);
  line-height: 1.35;
  overflow: hidden;
  /* Audit fix (Oct 27, 2026): the summary wrapped to a 3rd line as
     add-ons were toggled and the fixed bar GREW under the user's
     finger (measured 106 -> 123 -> 140px across states, overrunning
     the body's 96px bottom padding and covering page content). Two
     lines max, ellipsis beyond — the bar's height is now stable. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
#barAction { flex: none; margin: 0; }
#barBack { flex: none; margin: 0; }

/* ---------- Home ---------- */
.lede { font-size: 17px; color: var(--ink); }
.bigbook {
  display: block;
  width: 100%;
  font-size: 19px;
  padding: 16px 22px;
  margin: 14px 0 6px;
}
button.svcbtn {
  display: flex;
  width: 100%;
  text-align: left;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin: 10px 0;
  font-weight: 600;
}
button.svcbtn:hover { border-color: var(--action); box-shadow: var(--shadow-hover); filter: none; }
button.svcbtn small {
  display: block;
  font-weight: 400;
  color: var(--ink-2);
  margin-top: 3px;
  line-height: 1.45;
}
button.small { padding: 7px 14px; font-size: 14px; margin: 0; }

/* ---------- Remembered pick ---------- */
.yourpick {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--surface-alt);
  border: 1px solid var(--action);
  border-radius: var(--radius);
  padding: 12px 16px;
  margin: 10px 0 14px;
  font-weight: 700;
  color: var(--primary);
}
/* Audit fix (Oct 27, 2026): the "Pick your massage…" hint line and
   the your-pick banner swap in the same slot; the banner measured
   18px taller, so every pick/unpick shoved the whole list by 18px.
   Same box, same minimum height — the swap is now shift-free. */
.pickhint {
  display: flex;
  align-items: center;
  min-height: 72px;
  box-sizing: border-box;
  margin: 10px 0 14px;
  padding: 12px 2px;
}
.yourpick { min-height: 72px; box-sizing: border-box; }
.yourpick-line { font-weight: 600; color: var(--primary); }

/* ---------- Calendar (colour + words, never colour alone) ---------- */
.legend { font-size: 14px; color: var(--ink-2); margin: 10px 0; }
.legend .dot, .daycell::before {
  display: inline-block;
  width: 11px; height: 11px;
  border-radius: 50%;
  vertical-align: -1px;
}
.legend .dot.open { background: #2E7D32; }
.legend .dot.few { background: #D9A21B; }
.legend .dot.full { background: #B00020; }
.calgrid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  margin: 10px 0 16px;
}
button.daycell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 9px 2px 8px;
  margin: 0;
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--divider);
  box-shadow: none;
  font-size: 13px;
}
button.daycell .dlabel { font-weight: 700; line-height: 1.25; text-align: center; }
button.daycell .dword { font-size: 12px; color: var(--ink-2); }
button.daycell.open::before { content: ""; background: #2E7D32; }
button.daycell.few::before { content: ""; background: #D9A21B; }
button.daycell.full::before { content: ""; background: #B00020; }
button.daycell.closed::before { content: ""; background: #9AA39B; }
button.daycell.full, button.daycell.closed { opacity: 0.75; }
button.daycell[aria-pressed="true"] {
  background: var(--action);
  color: var(--on-action);
  border-color: var(--action);
}
button.daycell[aria-pressed="true"] .dword { color: var(--on-action); }
/* MEGA PASS (W-09): a SELECTED full/closed day keeps its own
   identity — the green fill contradicted its red/grey dot and
   its "Full"/"Closed" word. Selection reads as a strong outline
   on those cells instead. */
button.daycell.full[aria-pressed="true"],
button.daycell.closed[aria-pressed="true"] {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--action);
  outline: 2px solid var(--action);
  outline-offset: -2px;
  opacity: 1;
}
button.daycell.full[aria-pressed="true"] .dword,
button.daycell.closed[aria-pressed="true"] .dword { color: var(--ink-2); }
.slots { display: flex; flex-wrap: wrap; gap: 4px; }
.waitlist-join input { margin-bottom: 8px; }

/* ---------- Auth (password OR code) ---------- */
/* Segmented control (speed pass, Oct 30, 2026): ONE rounded
   outline, segments clipped inside it — the filled segment's
   corners can never poke past the outline or its neighbour.
   Used by the sign-in method tabs and the shop period/billing
   rows (both render into .auth-tabs). */
.auth-tabs {
  display: flex; gap: 0; margin-bottom: 10px;
  border: 2px solid var(--divider); border-radius: 12px;
  overflow: hidden; padding: 2px; background: var(--surface);
}
.auth-tabs button {
  flex: 1 1 0; border: 0; border-radius: 0; background: transparent;
  margin: 0;
}
.auth-tabs button.on {
  background: var(--action);
  color: var(--on-action);
  border-color: var(--action);
  border-radius: 9px;
}

/* ---------- Business hours: today's row (speed pass) ---------- */
.hours-row { padding: 3px 8px; border-radius: 8px; }
.hours-row.today {
  font-weight: 700;
  background: var(--surface-alt);
  outline: 2px solid var(--action);
}

/* ---------- Directory (speed pass) ---------- */
.dir-logo { max-height: 56px; max-width: 160px; object-fit: contain; display: block; margin-bottom: 6px; }
.authbox input { margin-bottom: 8px; }
/* SIGN-IN REDESIGN (Nov 1, 2026): visible field labels (A4), the
   Stay signed in boxed toggle (A3 — label + switch in one faint
   outline box), quiet text links + method rows (A1/A2 — no fill),
   and the inline code error line (V3). */
.field-label { display: block; font-weight: 600; margin: 10px 0 4px; }
.stay-box {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border: 1px solid var(--divider); border-radius: 12px;
  padding: 10px 12px; margin: 8px 0 12px; background: var(--surface);
  cursor: pointer;
}
.stay-box input[type="checkbox"] { width: 24px; height: 24px; flex: none; margin: 0; }
button.textlink {
  background: transparent; border: 0; box-shadow: none; color: var(--primary);
  text-decoration: underline; padding: 8px 4px; margin: 2px 0;
}
.auth-methods { display: flex; flex-direction: column; align-items: flex-start; }
button.method-row {
  background: transparent; border: 0; box-shadow: none; color: var(--primary);
  text-align: left; padding: 10px 4px; margin: 0; font-weight: 600;
}
.inline-err { color: var(--error, #b3261e); font-weight: 600; }
.addr-confirm { border-color: var(--action); }

/* ---------- Pay-ahead button (only rendered when payAhead.url exists) ---------- */
a.paybtn {
  display: inline-block;
  background: var(--action);
  color: var(--on-action);
  font-weight: 700;
  text-decoration: none;
  /* Published radius scale (FULL REVIEW C): pills are for chips and
     toggles only — a button takes the 12px button radius. */
  border-radius: var(--radius-btn, 12px);
  padding: 11px 20px;
  margin: 6px 6px 6px 0;
}
a.paybtn:hover { filter: brightness(1.08); color: var(--on-action); }

/* FULL REVIEW C / WAVE-2 CW-7: on narrow phones the week stays a
   week — seven narrow columns (smaller type, status dot only)
   instead of collapsing to 4 + 3 rows that stop reading as a week. */
@media (max-width: 560px) {
  .calgrid { grid-template-columns: repeat(7, 1fr); gap: 3px; }
  button.daycell { padding: 6px 0 5px; font-size: 12px; border-radius: 9px; }
  /* Size-and-device pass (0.3.64): the availability WORD stays
     on small phones — it used to be display:none here, leaving
     colour + a dot as the only signal, which the app's own rule
     forbids. Shrink-first instead: 10px, centred, allowed to
     wrap inside its cell (cells grow a little taller; the week
     still reads as a week). */
  button.daycell .dword { display: block; font-size: 10px; line-height: 1.15; }
  #barSummary { font-size: 13px; }
  header .logo { width: 48px; height: 48px; }
}

/* 0.3.4 referral share */
.sharelink { word-break: break-all; font-weight: 600; }

/* ============================================================
   Redesign (Oct 25, 2026) — Cojilio's structure, the app's colours
   Jamie's recipe: the Cojilio booking page's LOOK (wide centred
   column, header bar, two-column hero, category menu + service
   rows + summary rail, dark-green footer) rebuilt BETTER in the
   JLB Booking palette — deep #002C27 / surface #073428 / leaf
   #5B944E / highlight #B6D7A5 — with real per-service photos, a
   search box (Cojilio has none) and our clearer cards.
   ============================================================ */

main { max-width: 1120px; }

/* ---------- Header nav (Book / My bookings / account) ---------- */
.topnav {
  margin-left: auto;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}
button.navlink, a.navlink {
  background: transparent;
  color: var(--header-ink);
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 9px 14px;
  margin: 0;
  font-size: 15px;
  text-decoration: none;
  display: inline-block;
}
button.navlink:hover, a.navlink:hover { border-color: var(--accent); filter: none; }
header .theme-toggle { margin-left: 0; }

/* ---------- Hero photo slider (Jamie, Oct 28, 2026) ----------
   The pictures lead the page. One dot per picture, the lit dot
   follows the show; tap = next, swipe/drag/arrows move too. */
.hero-slider { margin: 18px 0 10px; }
.hero-slider .hero-media { position: relative; }
.hero-slider .hero-media.slides { cursor: pointer; touch-action: pan-y; }
.hero-slider .hero-media.slides img { user-select: none; -webkit-user-drag: none; }
.hero-dots { display: flex; gap: 2px; justify-content: center; align-items: center; padding: 4px 0 0; }
.hero-dots:empty { display: none; }
/* FULL REVIEW 🔴-38: the dot LOOKS 9px but the BUTTON is a 40px
   hit box — the 9px circle is drawn centred inside it, so a thumb
   can actually land on it. */
.hero-dot {
  width: 40px; height: 40px; border-radius: 999px; border: none; padding: 0;
  background: transparent; cursor: pointer; position: relative; flex: none;
}
.hero-dot::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 9px; height: 9px; border-radius: 999px; background: #B9C4AC;
  transform: translate(-50%, -50%);
  transition: transform .25s ease, background .25s ease;
}
.hero-dot.active::after { background: var(--primary); transform: translate(-50%, -50%) scale(1.45); }

/* ---------- Hero (Cojilio two-column, our colours) ---------- */
.hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: 28px;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 28px;
  margin: 18px 0 10px;
}
/* Identity row (Jamie, Oct 28, 2026): round business picture,
   name beside it, the full About underneath. */
.hero-id { display: flex; gap: 18px; align-items: center; }
.hero-text .biz-logo {
  width: 112px;
  height: 112px;
  /* MEGA PASS (W-01): a LOGO is never cropped — contain keeps
     the whole mark inside the disc (cover cut wide logos off). */
  object-fit: contain;
  padding: 8px;
  background: var(--surface-alt);
  border-radius: 50%;
  border: 3px solid var(--surface-alt);
  box-shadow: var(--shadow);
  flex: none;
}
.hero-id-text .biz-name { margin-top: 0; }
/* Optional homepage blocks (Jamie, Oct 28, 2026): the business's
   own chosen sections, after the About card. */
.home-block {
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 20px 28px;
  margin: 10px 0;
}
.home-block h3 { margin: 0 0 8px; color: var(--primary); font-size: 19px; }
.home-block p { margin: 2px 0; color: var(--ink-2); line-height: 1.55; }
.hero-text h2.biz-name {
  border-bottom: none;
  padding-bottom: 0;
  margin: 10px 0 2px;
  font-size: 34px;
}
.hero-sub { font-weight: 700; color: var(--primary); margin: 2px 0; font-size: 17px; }
.hero-city { margin: 2px 0; color: var(--ink-2); }
.hero-hours { margin: 6px 0; font-weight: 600; color: var(--success); }
.hero .tag { margin: 6px 0 4px; color: var(--ink-2); max-width: 46ch; }
/* Owner-written About (Oct 27, 2026): a short bio paragraph under
   the tagline; the tenant's own words, line breaks kept. */
.hero .biz-about { margin: 4px 0 2px; color: var(--ink-2); font-size: 15px; line-height: 1.55; max-width: 52ch; }
/* Structured About (0.3.63 visual parity with the Booking app):
   the owner's own headings, bullet rows and label/price rows —
   never one flat dash-list wall. */
.biz-about-h { color: var(--primary); font-size: 17px; margin: 16px 0 4px; }
.biz-about-h:first-child { margin-top: 2px; }
.biz-about-p { margin: 6px 0; }
.biz-about-list { margin: 4px 0 6px; padding-left: 20px; }
.biz-about-list li { margin: 3px 0; }
.biz-about-list li::marker { color: var(--primary); font-weight: 700; }
.biz-about-price { display: flex; justify-content: space-between; gap: 16px; padding: 7px 0; border-top: 1px solid var(--divider); }
.biz-about-price:first-of-type { border-top: none; }
.biz-about-price-label { color: var(--ink); }
.biz-about-price-value { color: var(--primary); font-weight: 700; font-size: 16px; white-space: nowrap; }
/* Service detail on home (0.3.63): the Read more panel under a
   service row — description in full + every length with its
   price as its own tappable row. */
.svcdetail { border: 1px solid var(--divider); border-radius: var(--radius); padding: 6px 16px 12px; margin: 2px 0 10px; background: var(--surface); }
.svcdetail-desc { color: var(--ink-2); line-height: 1.5; margin: 8px 0 4px; }
.svcdetail-h { color: var(--primary); font-size: 16px; margin: 10px 0 2px; }
button.svclen { display: flex; justify-content: space-between; gap: 16px; width: 100%; background: none; border: none; border-top: 1px solid var(--divider); color: var(--ink); padding: 12px 0; margin: 0; font-size: 15px; text-align: left; border-radius: 0; }
button.svclen:hover { filter: none; }
.svclen-price { color: var(--primary); font-weight: 700; font-size: 16px; white-space: nowrap; }
.svcdetail-toggle { margin: 0 0 8px 4px; }
.hero-cta { width: auto; margin-top: 12px; }
/* Audit fix (Oct 27, 2026): the img IS the hero box — a fixed 16/10
   aspect reserves its height before any picture loads, so the page
   never grows/shrinks when the picture arrives or rotates. Tenant
   photos (.cover) fill the box — no empty side bars; the badge/logo
   keeps contain so a logo is never cropped. object-position biases
   the photo crop up a little so faces near the top survive it. */
.hero-media img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  object-fit: contain;
  object-position: center 35%;
  background: var(--surface-alt);
  border-radius: 14px;
  box-shadow: var(--shadow);
  display: block;
}
.hero-media img.cover { object-fit: cover; }
/* Tenant branding hold (Nov 1, 2026): [hidden] must beat the
   display:block above, or a held image would paint anyway. */
.hero-media img[hidden] { display: none; }
/* The deliberate no-logo fallback + the neutral hold while tenant
   branding resolves: the EXACT hero box (16/10, same radius and
   surface), carrying the business's own name once known — never a
   platform mark, never a different size, so nothing jumps. */
.hero-name-fallback {
  width: 100%;
  aspect-ratio: 16 / 10;
  background: var(--surface-alt);
  border-radius: 14px;
  box-shadow: var(--shadow);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 20px;
  box-sizing: border-box;
  color: var(--primary);
  font-size: clamp(22px, 5vw, 40px);
  font-weight: 800;
  line-height: 1.2;
}
.hero-name-fallback[hidden] { display: none; }
/* Round tenant-logo hold: same disc the logo paints into (the
   .biz-logo sizing above), neutral until the tenant logo loads;
   a logo-less business's disc then carries its own initials. */
.biz-logo-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--primary);
  font-size: 34px;
  font-weight: 800;
}
.biz-logo-fallback[hidden] { display: none; }
img.biz-logo[hidden] { display: none; }

/* ---------- Step 1: three columns (menu / cards / summary) ---------- */
.booking-layout {
  display: grid;
  grid-template-columns: 228px minmax(0, 1fr) 300px;
  gap: 20px;
  align-items: start;
  margin-top: 8px;
}
.catmenu {
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 10px;
  position: sticky;
  top: 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.catmenu-title { margin: 4px 6px 8px; font-size: 16px; border: none; padding: 0; }
button.catbtn {
  background: transparent;
  color: var(--ink);
  border: 1px solid transparent;
  text-align: left;
  border-radius: 10px;
  padding: 10px 12px;
  margin: 0;
  font-size: 15px;
  font-weight: 600;
}
button.catbtn:hover { border-color: var(--action); filter: none; }
button.catbtn.on {
  background: var(--action);
  color: var(--on-action);
  border-color: var(--action);
}
.booking-centre { min-width: 0; }
.booking-centre > .catch:first-of-type { margin-top: 6px; }

/* Summary rail — Cojilio's card with the overlapping badge, but
   live: picked items, taxes-in total, service count. */
.summary-card {
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 0 18px 16px;
  position: sticky;
  top: 14px;
}
.summary-badge {
  display: inline-block;
  transform: translateY(-11px);
  background: var(--header-bg);
  color: #B6D7A5;
  border: 1px solid var(--divider);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 6px 12px;
  border-radius: 999px;
}
.summary-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 19px;
  color: var(--primary);
  margin: 0 0 2px;
}
.summary-empty { font-style: italic; color: var(--ink-2); }
.summary-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin: 8px 0;
  font-size: 15px;
}
.summary-total {
  border-top: 1px solid var(--divider);
  padding-top: 10px;
  font-weight: 700;
  color: var(--primary);
  font-size: 16px;
}
.summary-count { margin-top: 12px; }

/* ---------- Service cards with photos ---------- */
div.svccard {
  display: block;
  padding: 0;
  overflow: hidden;
  cursor: default;
}
button.svccard {
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  text-align: left;
}
.svc-top {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  margin: 0;
  cursor: pointer;
}
.svcphoto {
  width: 76px;
  height: 76px;
  /* Fix 6 (Oct 26, 2026): service photos follow the one corner
     standard — the shared 14px radius token, same as the apps. */
  border-radius: var(--radius);
  object-fit: cover;
  background: var(--surface-alt);
  flex: none;
}
.svcphoto.islogo { object-fit: contain; padding: 6px; }
/* Add-on rows carry the add-on's own photo at the app's row size
   (48dp in the app's pick cards) — smaller than a service card's. */
.addonrow { align-items: center; }
.addonrow .svcphoto { width: 48px; height: 48px; }
.svcbody { flex: 1 1 auto; min-width: 0; display: block; }
.svcname { display: block; font-weight: 700; font-size: 17px; color: var(--ink); }
.svcmeta {
  display: block;
  color: var(--ink-2);
  font-size: 14px;
  margin-top: 2px;
  font-weight: 600;
}
button.svccard .svcbody small {
  /* MEGA PASS: no clamp — descriptions render in full instead of
     truncating into "…." (W-05); long text wraps, the card grows. */
  display: block;
  overflow: visible;
}
.svcdesc { padding: 0 16px 14px; }
.svcdesc small { color: var(--ink-2); line-height: 1.45; display: block; }
.svcdesc small.clamp {
  /* MEGA PASS shrink-first: three lines show before the clamp,
     and the clamp is never the end of the road — the Read more
     button (.clamp.open) expands it in place. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.svcdesc small.clamp.open { display: block; }
button.readmore {
  background: none;
  border: none;
  color: var(--primary);
  text-decoration: underline;
  padding: 4px 0 0;
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  border-radius: 4px;
}
button.readmore:hover { filter: none; }
.svc.selected { background: var(--sel); border-color: var(--action); }

/* ---------- Step panels (day/time + details) ---------- */
.panel {
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
  margin: 12px 0;
}
.panel .quote, .panel .policy { box-shadow: none; }
.addr-card {
  border: 1px solid var(--action);
  background: var(--surface-alt);
  border-radius: var(--radius);
  padding: 14px 18px;
  margin: 14px 0;
}
.addr-card p { margin: 4px 0; }

/* ---------- Footer: full-width deep green, three columns ---------- */
footer {
  max-width: none;
  margin: 40px 0 0;
  padding: 0;
  background: var(--header-bg);
  color: #F2F7EC;
  border-top: 3px solid var(--accent);
}
.foot-cols {
  max-width: 1120px;
  margin: 0 auto;
  padding: 30px 20px 36px;
  display: grid;
  grid-template-columns: 1fr 1fr 1.2fr;
  gap: 26px;
}
footer h3 { color: #B6D7A5; font-size: 18px; margin: 0 0 8px; }
footer p { margin: 5px 0; }
footer a { color: #B6D7A5; }
footer a:hover { color: #FFFFFF; }
footer .fine { color: #B9C9A8; opacity: 1; }

/* ---------- Redesign responsive ---------- */
@media (max-width: 1020px) {
  .booking-layout { grid-template-columns: minmax(0, 1fr) 290px; }
  .catmenu {
    grid-column: 1 / -1;
    position: static;
    flex-direction: row;
    /* MEGA PASS (W-07): the category row WRAPS — it used to run
       off the screen edge in a nowrap strip. */
    flex-wrap: wrap;
    overflow-x: visible;
    align-items: center;
  }
  .catmenu-title { margin: 0 6px 0 2px; flex: none; }
  button.catbtn { white-space: nowrap; flex: none; }
}
/* FULL REVIEW C: the header row is over-full well before the
   760px layout breakpoint — the nav takes its own row from 860px
   down, so logo, switch and sign-in stop competing for one row. */
@media (max-width: 860px) {
  .topnav { order: 3; width: 100%; margin-left: 0; }
}
@media (max-width: 760px) {
  .booking-layout { grid-template-columns: minmax(0, 1fr); }
  .summary-card { position: static; }
  .hero { grid-template-columns: 1fr; padding: 20px; }
  .foot-cols { grid-template-columns: 1fr; gap: 18px; }
  .svcphoto { width: 64px; height: 64px; }
}

/* ============================================================
   0.3.10 — Shop + profile assets (gift cards with scannable QR)
   ============================================================ */

/* Home gift-card banner: the shop's front door on the home view */
.giftbanner {
  border: 1px solid var(--accent);
  background: var(--surface-alt);
  white-space: normal;
}
.giftbanner .big { margin: 0 0 4px; }
.giftbanner p { margin: 4px 0; }

/* Promo card picture (Jamie, Oct 27, 2026, 22:56): a real picture
   area across the top of the card — the owner's chosen photo, or
   the bundled default art for the card — never a tiny icon and
   never a bare card. */
.promocard { overflow: hidden; }
.promopic {
  display: block;
  width: 100%;
  height: 150px;
  object-fit: cover;
  border-radius: 10px;
  margin: 0 0 10px;
  background: var(--surface);
}

/* One owned gift card / invoice inside the profile assets box */
.giftcard {
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  padding: 12px 14px;
  margin: 10px 0;
  white-space: normal;
}
.giftcard p { margin: 4px 0; }

/* The scannable redeem code: QR (white quiet zone baked into the
   canvas by qr.js) + the same code as readable text underneath */
.qrwrap { text-align: center; margin: 8px 0 2px; }
.qrwrap canvas {
  width: 200px;
  height: 200px;
  border-radius: 10px;
  box-shadow: var(--shadow);
}
.giftcode {
  text-align: center;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--primary);
  margin: 6px 0 2px;
  user-select: all;
}

/* UX pass (Oct 26, 2026): the radius token scale (C2) + the B19
   anchor pulse — the My bookings section rings when the footer
   jump lands on it; static outline under reduced motion. */
:root { --radius-card: 14px; --radius-btn: 12px; --radius-field: 10px; }
button, .bigbook { border-radius: var(--radius-btn); }
input, select, textarea { border-radius: var(--radius-field); }
.lookingfor a { font-weight: 600; }
@keyframes jlb-target-pulse {
  0% { outline: 3px solid var(--action); outline-offset: 3px; }
  100% { outline: 3px solid transparent; outline-offset: 3px; }
}
#myBookings:target { animation: jlb-target-pulse 1.2s ease-out 2; border-radius: var(--radius-card); }
@media (prefers-reduced-motion: reduce) {
  #myBookings:target { animation: none; outline: 3px solid var(--action); outline-offset: 3px; }
}
/* jlb-web 2026-10-26-r3 — fix pass: rotating top pictures (crossfade),
   header language switch, "Follow me" row */
.hero-media img { transition: opacity .4s ease; }
.hero-media img.fadeout { opacity: 0; }
.langswitch { display: inline-flex; gap: 4px; align-items: center; }
.langbtn {
  background: transparent; color: inherit; border: 1px solid currentColor;
  border-radius: 999px; padding: 2px 10px; font-size: 13px; font-weight: 600;
  cursor: pointer; opacity: .75;
}
/* Gold discipline (FULL REVIEW C §4), completed Oct 28, 2026: the
   active language is a dark fill inside the outline with light-gold
   text — gold itself is the outline/accent, never the fill (the
   same treatment the help and signup pages now use). */
.langbtn.on { opacity: 1; background: #0B4238; border-color: var(--accent); color: #FFE9A8; }
.socialrow { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 10px; }
.social-label { font-weight: 700; }
.socialbtn {
  display: inline-flex; align-items: center; gap: 8px; padding: 5px 14px 5px 11px;
  border: 1px solid currentColor;
  border-radius: 999px; text-decoration: none; font-weight: 600; font-size: 14px;
}
.socialbtn svg { width: 18px; height: 18px; flex: none; fill: currentColor; }

/* ---------- Audit pass (Oct 27, 2026 — swarm fixes) ---------- */
/* B7/M101-adjacent: the step holds its ground from first paint, and
   view changes land just under the sticky header (M108). */
#step { min-height: 480px; scroll-margin-top: 76px; }
/* MEGA PASS (W-04): the first-paint skeleton is a labelled
   loading state — a spinning ring and the word "Loading…". */
.skel-spin {
  width: 34px; height: 34px; margin: 18px 0 8px;
  border-radius: 50%; border: 4px solid var(--surface-alt);
  border-top-color: var(--action);
  animation: skel-spin 0.9s linear infinite;
}
@keyframes skel-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .skel-spin { animation: none; } }
.skel-label { font-weight: 700; color: var(--ink-2); margin: 0 0 6px; }
/* MEGA PASS (W-06): the waitlist Join button spans the form. */
#waitlistForm button[type="submit"] { width: 100%; }
/* MEGA PASS (W-08): add-on checkboxes are real tap targets. */
.addonrow input[type="checkbox"] { width: 22px; height: 22px; flex: none; }
.skel-line { height: 22px; border-radius: 6px; background: var(--surface-alt); margin: 14px 0; }
.skel-line.w50 { width: 50%; }
.skel-card { height: 92px; border-radius: var(--radius-card, 14px); background: var(--surface-alt); margin: 12px 0; animation: skel-pulse 1.4s ease-in-out infinite; }
@keyframes skel-pulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .skel-card { animation: none; } }
/* m18: success line — its own colour, reserved height so it never
   shoves the page when it appears. */
#notice { color: var(--success); font-weight: 600; min-height: 1.5em; margin: 6px 0 0; }
/* m56: the bar's money figure, visually distinct from the summary. */
.bartotal { font-weight: 800; }
.bartotal::before { content: ' · '; font-weight: 600; }
/* M107: the language switch holds its width across EN/FR labels. */
.langswitch { min-width: 118px; justify-content: flex-end; }
/* m132/m134/m135: comfortable tap targets. */
button.small { min-height: 44px; }
.langbtn { padding: 6px 12px; min-height: 44px; min-width: 44px; } /* polish-3: 44px touch guideline */
.socialbtn { min-height: 44px; }
/* M99: hero text lines keep their height while the profile lands. */
.biz-name { min-height: 1.15em; }
.hero-city, .hero-hours { min-height: 1.4em; }
/* M55/M63: checkbox rows (policy agreement, waitlist consent). */
.polrow { display: flex; gap: 8px; align-items: flex-start; cursor: pointer; font-weight: 600; }
.polrow input[type="checkbox"] { width: 20px; height: 20px; flex: none; margin-top: 2px; }
details summary { cursor: pointer; font-weight: 600; margin-top: 8px; }
.noscript-note { background: var(--surface-alt); padding: 12px 16px; border-radius: 10px; font-weight: 600; }

/* ---------- Header first row (Jamie, Oct 28, 2026) ----------
   The account control (#accountBtn — "Sign in" / "My account",
   the .theme-toggle pill) shares the FIRST header row with the
   logo, the title and the language switch: [logo] JLB Booking …
   EN · FR · Sign in. It used to wrap onto a row of its own under
   the title row and waste a full row of header height. The nav
   keeps its own full-width row below (the ≤860px rule above);
   the wide one-row layout is untouched. The tightening below is
   scoped to the widths where the first row was over-full, and
   covers the signed-in labels too ("Mon compte" / "My account"
   are both shorter than the widest case, French "Se connecter"). */
@media (max-width: 860px) {
  /* M107's fixed switch width was sized for the roomy layout;
     on the shared first row the switch hugs its two buttons. */
  .langswitch { min-width: 0; }
  header .theme-toggle { align-self: center; white-space: nowrap; }
}
@media (max-width: 560px) {
  header { gap: 6px; padding: 14px 10px; }
  header .logo { width: 40px; height: 40px; }
  header h1 { font-size: 19px; white-space: nowrap; }
  .langbtn { min-width: 38px; padding: 6px 7px; }
  header .theme-toggle { padding: 8px 10px; font-size: 13px; }
}

/* Waitlist doors (Oct 31, 2026): the home "Just opened" board —
   one row per freed spot (day + time range, the words "Just
   opened", a Book button). Rows wrap instead of squeezing: on a
   narrow phone the button drops to its own line at full tap size
   rather than clipping the day/time text (shrink-first rule). */
.home-block h2 { margin: 0 0 8px; color: var(--primary); font-size: 19px; }
.opening-row {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px 14px; padding: 10px 0;
  border-top: 1px solid var(--divider);
}
.opening-row:first-child { border-top: none; padding-top: 2px; }
.opening-when { font-weight: 700; color: var(--primary); min-width: 0; }
.opening-just { font-weight: 700; color: var(--success); font-size: 13px; letter-spacing: 0.02em; }
.opening-row button { flex: none; margin: 0 0 0 auto; }
@media (max-width: 560px) {
  .opening-row button { margin-left: 0; }
}

/* Settings search + organization (Oct 30, 2026): group headers,
   the account view's search box, and the jump flash. */
.setgroup { margin: 26px 0 6px; font-size: 20px; }
.setsearch input { width: 100%; box-sizing: border-box; padding: 11px 14px; font-size: 16px; }
.setresult { display: block; width: 100%; text-align: left; margin: 6px 0; }
.setflash { outline: 3px solid var(--accent, #2b6cb0); outline-offset: 2px; }

/* Tester banner + demo strip + lit remedy (SIGN-IN REDO, Nov 1, 2026) */
.tester-banner { display:block; background:#FFD21F; color:#201A00; text-align:center;
  padding:12px 16px; text-decoration:none; border-bottom:3px solid #B45309; }
.tester-banner[hidden] { display:none; }
.tester-banner-head { display:block; font-size:18px; font-weight:800; }
.tester-banner-sub { display:block; font-size:14px; }
.demo-strip { background:#571C15; color:#FFD9CF; text-align:center; padding:8px 12px; font-weight:700; }
.demo-strip[hidden] { display:none; }
.demo-strip a { color:#FFE9B8; margin-left:10px; }
button.glow-btn { background:var(--action, #2E7D32); color:#fff; border:3px solid #F2B705;
  font-weight:800; box-shadow:0 0 0 3px rgba(242,183,5,.35); }
button.glow-btn:disabled { opacity:.65; box-shadow:none; }
.mbcal { display:grid; grid-template-columns:repeat(7,1fr); gap:4px; margin:10px 0; }
.mbcal button { min-height:40px; padding:4px 0; font-size:14px; }
.mbcal button.closed { opacity:.45; }
.mbcal button.marked { font-weight:800; border-color:#F2B705; }
