/* NoBrainer pre-launch marketing site.
 *
 * Tokens are lifted verbatim from the design canvas (board 2a) — see
 * design-reference in the handoff. Day values on :root, dark values under
 * [data-theme="dark"] on <html>, because the site chooses the theme by LOCAL
 * TIME rather than by the OS setting (19:00–07:00 is dark), with a user
 * override. prefers-color-scheme is therefore not the switch; it is only the
 * first guess before the clock is read.
 */
:root {
  --bg: #FAF7F2;
  --card: #fff;
  --line: #EAE4DA;
  --txt: #1C1B26;
  --txt2: #5B5766;
  --cta-bg: #1C1B26;
  --cta-txt: #FAF7F2;
  --price: #FFC529;
  --badge-bg: #1C1B26;
  --badge-txt: #FAF7F2;
  --tick-bg: #1C1B26;
  --tint-l: #EAF6FB;
  --tint-c: #F2EFFE;
  --tint-p: #FDF1E5;
  --tint-b: #FBEDF0;
  --acc-c: #7A5AF8;
  --acc-p: #E8842C;
  --acc-b: #C94B62;
  --pillbg: #F3EFE8;
  /* Drawer row numbers (board 5a): zest-deep on cream, zest on ink. Zest
     itself fails contrast on the light background, hence the deeper tone. */
  --num: #8A6400;
  --cursor: rgba(28, 27, 38, .85);
  --foot: #1C1B26;
  --foot-line: #34323F;
  --hero-glow: transparent;
  --shadow: rgba(28, 27, 38, .16);

  /* Constant across both themes. */
  --zest: #FFC529;
  --zest-deep: #8A6400;
  --ok: #2E9E63;
  --danger: #D6455D;
  /* MUST equal the active service's `accent` in content/site/services.json.
     It is a literal here because the stylesheet is not templated — lint rule
     9 fails the build if the two drift, so the comment is enforced rather
     than merely asserted. */
  --svc-accent: #2E9BC4;

  --font-display: "Bricolage Grotesque", "Segoe UI", system-ui, sans-serif;
  --font-ui: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
}

html[data-theme="dark"] {
  --bg: #17161F;
  --card: #201F2B;
  --line: #2B2A38;
  --txt: #FAF7F2;
  --txt2: #A9A5B4;
  --cta-bg: #FFC529;
  --cta-txt: #1C1B26;
  --price: #1C1B26;
  --badge-bg: #FAF7F2;
  --badge-txt: #1C1B26;
  --tick-bg: #121118;
  --tint-l: #1D2A33;
  --tint-c: #241F3A;
  --tint-p: #2E2117;
  --tint-b: #2C181D;
  --acc-c: #B9A8FF;
  --acc-p: #F4B183;
  --acc-b: #F093A6;
  --pillbg: #26252F;
  --num: #FFC529;
  --cursor: rgba(250, 247, 242, .9);
  --foot: #121118;
  --foot-line: #24232E;
  --hero-glow: radial-gradient(closest-side, rgba(255, 197, 41, .13), transparent);
  --shadow: rgba(0, 0, 0, .45);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--txt);
  font-family: var(--font-ui);
  font-size: 15px;
  line-height: 1.5;
}

/* The design's 0.4s theme cross-fade, scoped to the properties that change.
   Transitioning `all` would animate layout on every hover. */
body, header, section, footer, div, a, span, h1, h2, h3, p, input, button {
  transition: background-color .4s ease, color .4s ease, border-color .4s ease;
}

a { color: var(--txt); text-decoration: none; }
a:hover { color: var(--zest-deep); }
html[data-theme="dark"] a:hover { color: var(--zest); }

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

h1, h2, h3 { font-family: var(--font-display); margin: 0; text-wrap: balance; }
p { margin: 0; }
img, svg { display: block; max-width: 100%; }

.shell { max-width: 1440px; margin-inline: auto; }

/* Screen-reader-only, for the skip link and the labels the design shows as
   placeholder text only. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip:focus {
  position: fixed; inset-inline-start: 16px; inset-block-start: 16px;
  width: auto; height: auto; clip: auto; margin: 0; padding: 12px 18px;
  background: var(--cta-bg); color: var(--cta-txt); border-radius: 14px;
  z-index: 100; font-weight: 700;
}

@keyframes nb-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes nb-bob { 0%, 100% { transform: rotate(-6deg) translateY(0); } 50% { transform: rotate(-6deg) translateY(-14px); } }
/* The mobile phone bobs on the vertical only — board 3a stands it upright. */
@keyframes nb-bob2 { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
@keyframes nb-glow { 0%, 100% { box-shadow: 0 0 90px rgba(255, 197, 41, .18); } 50% { box-shadow: 0 0 150px rgba(255, 197, 41, .38); } }

/* The handoff is explicit: reduced motion disables the marquee scroll, the bob
   and the glow, and shows them static rather than hiding them. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }

  /* THE TILT LIVES INSIDE THE KEYFRAMES. nb-bob is
     `rotate(-6deg) translateY(...)`, so killing the animation leaves the phone
     bolt upright — a different composition, not a stiller one. Re-declared
     here so the reduced-motion view is the design standing still. */
  .phone { transform: rotate(-6deg) !important; }
  /* ...but board 3a's phone is upright, so the mobile one stands still
     straight rather than acquiring a tilt it never had. */
  @media (max-width: 860px) { .phone { transform: none !important; } }

  /* The marquee is the other one: frozen mid-scroll it shows a half-word at
     the seam, so it is reset to the start of the loop. */
  .ticker-track { animation: none !important; transform: none !important; }
}

/* ── Topbar ─────────────────────────────────────────────────────────────── */
/* --tick-bg, not a literal. The desktop board hard-codes #1C1B26 in both
   themes while BOTH mobile boards darken it to #121118 — the boards
   contradict each other on the identical element, so "recreate the board"
   does not decide it. Tokenised to match the mobile boards and the ticker
   strip directly below it, which uses the same token. Flagged for sign-off. */
.topbar {
  background: var(--tick-bg);
  color: #FAF7F2;
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  padding: 9px 20px;
  letter-spacing: .03em;
}

/* ── Nav ────────────────────────────────────────────────────────────────── */
.nav { display: flex; align-items: center; justify-content: space-between; padding: 20px 48px; gap: 20px; }
.brand { display: flex; align-items: center; gap: 10px; }
.brand svg { width: 34px; height: 34px; }
.wordmark {
  font-family: var(--font-display);
  font-weight: 800; font-size: 22px; letter-spacing: -.02em; color: var(--txt);
}
.wordmark i { color: var(--zest); font-style: normal; }
.nav-links { display: flex; gap: 28px; font-size: 13.5px; font-weight: 600; }
/* The desktop nav does not fit between 861 and 940px — it wrapped to two lines
   in the first 80px above the breakpoint, which is where a small laptop and
   most tablets in landscape sit. Tighten rather than move the breakpoint, so
   the mobile block below stays authoritative under 861. */
@media (min-width: 861px) and (max-width: 940px) {
  .nav { padding: 20px 24px; gap: 14px; }
  .nav-links { gap: 16px; }
}
.nav-actions { display: flex; gap: 10px; align-items: center; }

.pill-ghost {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1.5px solid var(--line); background: var(--card);
  border-radius: 999px; padding: 9px 16px; font-size: 12.5px; font-weight: 700;
  color: var(--txt);
}
.pill-ghost:hover { color: var(--txt); border-color: var(--txt2); }
.btn-primary {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--cta-bg); color: var(--cta-txt);
  border-radius: 14px; padding: 11px 18px;
  font-size: 13.5px; font-weight: 700; border: 0; cursor: pointer;
  font-family: var(--font-ui);
}
.btn-primary:hover { color: var(--cta-txt); filter: brightness(.94); }
.nav .btn-primary { font-size: 13px; padding: 11px 20px; box-shadow: 0 8px 20px var(--shadow); }
.nav-toggle { display: none; }

/* ── Hero ───────────────────────────────────────────────────────────────── */
/* overflow: clip keeps the 1000px glow box from adding horizontal scroll on
   viewports narrower than it. */
.hero { position: relative; overflow: clip; display: grid; grid-template-columns: 1.05fr .95fr; gap: 24px; padding: 48px 48px 64px; align-items: center; }
.hero::before {
  content: ""; position: absolute; top: -140px; left: 50%;
  transform: translateX(-50%); width: 1000px; height: 640px;
  background: var(--hero-glow); pointer-events: none; z-index: 0;
}
.hero > * { position: relative; z-index: 1; }

.eyebrow {
  display: inline-block; background: var(--zest); color: #1C1B26;
  font-size: 10.5px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .1em; padding: 6px 14px; border-radius: 999px;
}
.hero h1 {
  font-size: 104px; font-weight: 800; line-height: .92; letter-spacing: -.03em;
  margin: 22px 0 0;
}
.hero h1 .dot { color: var(--zest); }
.hero-sub { margin-top: 26px; font-size: 18px; line-height: 1.65; color: var(--txt2); max-width: 44ch; }

.badges { display: flex; gap: 12px; align-items: center; margin-top: 32px; flex-wrap: wrap; }
/* Pre-launch: these are NOT links. 60% opacity and no href, per the handoff —
   faking a store link before the app exists is the one thing it forbids. */
.badge {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--badge-bg); color: var(--badge-txt);
  border-radius: 14px; padding: 10px 16px; opacity: .6; cursor: default;
}
.badge .glyph { display: flex; align-items: center; line-height: 1; }
.badge .glyph svg { width: 19px; height: 22px; fill: currentColor; }
.badge small { display: block; font-size: 9px; font-weight: 600; opacity: .85; }
.badge strong { display: block; font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
.sticker {
  /* Inter, not the display face: the board inherits the body font here, and
     the tracking is what makes it read as a stamped sticker. */
  font-family: var(--font-ui); font-weight: 800; font-size: 11px; letter-spacing: .08em;
  background: var(--zest); color: #1C1B26; padding: 8px 14px; border-radius: 999px;
  transform: rotate(-3deg); white-space: nowrap;
  box-shadow: 0 8px 20px rgba(138, 100, 0, .2);
}
.hero-caption { margin-top: 16px; font-size: 12px; color: var(--txt2); max-width: 46ch; }
/* Ink text on a 2px zest bar, not a browser underline — a brand detail the
   board is specific about. */
.hero-caption a {
  color: var(--txt); font-weight: 700; text-decoration: none;
  box-shadow: inset 0 -2px 0 var(--zest);
}
html[data-theme="dark"] .hero-caption a { color: var(--txt); }

/* ── Phone mockup ───────────────────────────────────────────────────────── */
.phone-col { display: flex; justify-content: center; position: relative; }
.phone {
  width: 300px; background: #1C1B26; border-radius: 44px; padding: 10px;
  box-shadow: 0 50px 90px var(--shadow);
  /* board 3a's phone sits lower — see the mobile override below */
  transform: rotate(-6deg);
  animation: nb-bob 7s ease-in-out infinite;
}
/* Board 2a bobs in BOTH themes and uses nb-glow nowhere; the pulsing glow is a
   MOBILE-dark treatment (3a-mobile-dark), applied in the media query below. */
/* overflow: hidden because the demo's tab bar is full-bleed (margin: 0 -14px
   -14px) and square-cornered, so without a clip it paints straight over the
   screen's rounded bottom corners. Every board wrapper carries this. */
.phone-screen { background: #FAF7F2; border-radius: 36px; padding: 0 14px 14px; color: #1C1B26; overflow: hidden; }
/* The desktop screen stays light in both themes (board 2a pins it), so its
   tint chips must too — they were following the dark theme inside a light
   phone, which put dark-mode tints behind light-mode content. */
.stub-title {
  margin-top: 18px; font-family: var(--font-display); font-weight: 800;
  font-size: 44px; line-height: 1.05; letter-spacing: -.02em;
}
@media (max-width: 860px) { .stub-title { font-size: 34px; } }
.phone-static { --tint-l: #EAF6FB; --tint-c: #F2EFFE; --tint-p: #FDF1E5; --tint-b: #FBEDF0; }
.phone-status {
  display: flex; justify-content: space-between;
  padding: 14px 6px 4px; font-size: 11.5px; font-weight: 700;
}
.phone-status span + span { letter-spacing: 2px; font-size: 9px; }
.phone-sticker {
  position: absolute; top: -6px; right: 28px; transform: rotate(7deg);
  font-family: var(--font-display); font-weight: 800; font-size: 16px;
  background: var(--zest); color: #1C1B26; padding: 12px 18px; border-radius: 14px;
  box-shadow: 0 12px 30px rgba(138, 100, 0, .25); z-index: 2;
}
/* The QUESTION is the headline and the greeting the quiet line above it —
   these two were the wrong way round against board 2a. */
.phone-greet { font-size: 11px; color: #5B5766; font-weight: 500; }
.phone-ask {
  font-family: var(--font-display); font-weight: 800; font-size: 17px;
  letter-spacing: -.01em; margin-top: 3px;
}
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 14px; }
.tile { background: #fff; border: 1px solid #EAE4DA; border-radius: 16px; padding: 12px; position: relative; }
.tile .icon {
  width: 32px; height: 32px; border-radius: 11px;
  background: var(--tile-tint, var(--tint-l));
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; margin-bottom: 7px;
}
.tile .name { font-size: 12px; font-weight: 700; margin-top: 6px; }
.tile .meta { font-size: 10px; color: #5B5766; }
/* The three unlaunched verticals: locked, greyed, and their icons BLURRED so
   the shape gives nothing away. Never named. */
.tile.locked { opacity: .55; filter: grayscale(.35); }
/* Blur the GLYPH, not the chip: the board keeps the tinted square crisp and
   only the emoji inside it is unreadable. */
.tile.locked .icon span { filter: blur(6px); }
.tile .soon {
  position: absolute; top: 8px; right: 8px;
  font-size: 7.5px; font-weight: 800; letter-spacing: .08em;
  background: #F3EFE8; border: 1px solid #EAE4DA; color: #5B5766;
  padding: 2px 7px; border-radius: 999px;
}
.order-card { background: #fff; border: 1px solid #EAE4DA; border-radius: 16px; padding: 12px; margin-top: 10px; }
.order-head { display: flex; justify-content: space-between; align-items: center; font-size: 11.5px; font-weight: 700; }
.order-status {
  font-size: 8.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  background: var(--tint-l); color: var(--svc-accent); border-radius: 999px; padding: 3px 8px;
}
/* One shared 4-column grid: the dots were a 6px-gapped flex row while the
   labels were space-between, so no dot sat above the label it belonged to. */
.dots, .dots-labels { display: grid; grid-template-columns: repeat(4, 1fr); justify-items: center; }
.dots { gap: 0; align-items: center; margin-top: 10px; }
.dots span { width: 9px; height: 9px; border-radius: 999px; background: #EAE4DA; }
/* The completed step is the SAME blue as the active one so the row reads as
   one track. Green split it into two colours. The timeline's .dot.done below
   IS green and correctly so — different component, different board. */
.dots span.done { background: var(--svc-accent); }
.dots span.now { background: var(--svc-accent); box-shadow: 0 0 0 3px var(--tint-l); }
.dots-labels { font-size: 8.5px; color: #5B5766; margin-top: 6px; }
.phone-cta {
  display: flex; justify-content: space-between; align-items: center;
  background: #1C1B26; color: #FAF7F2; border-radius: 14px;
  padding: 13px 16px; font-size: 13px; font-weight: 700; margin-top: 8px;
  box-shadow: 0 10px 26px rgba(28, 27, 38, .22);
}
.phone-cta-arrow { color: var(--zest); }
.tabbar { display: flex; justify-content: space-around; margin-top: 0; padding: 10px 0 14px; border-top: 1px solid #EAE4DA; font-size: 8px; color: #5B5766; text-align: center; }
.tabbar span { flex: 1; }
.tabbar span.active { color: #1C1B26; font-weight: 700; }
.tabbar span i { display: block; font-style: normal; font-size: 15px; margin-bottom: 1px; }

/* ── Ticker ─────────────────────────────────────────────────────────────── */
.ticker { background: var(--tick-bg); overflow: hidden; padding: 13px 0; }
.ticker-track { display: flex; width: max-content; animation: nb-marquee 22s linear infinite; }
.ticker-track span {
  font-family: var(--font-display); font-weight: 800; font-size: 15px;
  color: var(--zest); letter-spacing: .14em; white-space: nowrap; padding-right: 0;
}

/* ── Steps ──────────────────────────────────────────────────────────────── */
.section { padding: 64px 48px; }
.section h2 { font-size: 44px; font-weight: 800; letter-spacing: -.02em; }
.section .lede { color: var(--txt2); font-size: 16px; margin-top: 12px; max-width: 60ch; }
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 34px; }
.step {
  background: var(--card); border: 1px solid var(--line); border-radius: 20px;
  padding: 28px; transition: transform .25s ease, box-shadow .25s ease, background-color .4s ease, border-color .4s ease;
}
.step:nth-child(1) { transform: rotate(-1.2deg); }
.step:nth-child(2) { transform: rotate(.9deg); }
.step:nth-child(3) { transform: rotate(-.6deg); }
.step:hover { transform: rotate(0); box-shadow: 0 10px 26px var(--shadow); }
.step .num {
  width: 44px; height: 44px; border-radius: 999px; background: var(--zest); color: #1C1B26;
  font-family: var(--font-display); font-weight: 800; font-size: 18px;
  display: grid; place-items: center;
}
.step h3 { font-size: 22px; font-weight: 800; margin-top: 16px; }
.step p { font-size: 14px; color: var(--txt2); margin-top: 8px; }

/* ── Active-service panel ──────────────────────────────────────────────────────── */
.svc { display: grid; grid-template-columns: 1.15fr .85fr; gap: 20px; }
.svc-left { background: var(--tint-l); border-radius: 24px; padding: 44px; }
.pill-launch {
  display: inline-block; background: var(--svc-accent); color: #fff;
  font-size: 10.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  padding: 7px 14px; border-radius: 999px;
}
.svc-left h2 { font-size: 38px; margin-top: 18px; }
.svc-left h2 .dot { color: var(--svc-accent); }
.svc-left p { color: var(--txt2); font-size: 15px; margin-top: 14px; max-width: 52ch; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px; }
.chip {
  background: var(--card); border: 1px solid var(--line); border-radius: 999px;
  padding: 8px 14px; font-size: 12.5px; font-weight: 600; color: var(--txt);
}
.svc-cta { display: inline-block; margin-top: 24px; }
.timeline-card { background: var(--card); border: 1px solid var(--line); border-radius: 24px; padding: 32px; }
.timeline-card h3 { font-size: 18px; font-weight: 800; }
.timeline { list-style: none; margin: 20px 0 0; padding: 0; }
.timeline li { display: flex; gap: 14px; align-items: flex-start; padding-bottom: 22px; position: relative; }
.timeline li:last-child { padding-bottom: 0; }
.timeline li::after {
  content: ""; position: absolute; left: 5px; top: 16px; bottom: 0; width: 2px; background: var(--line);
}
.timeline li:last-child::after { display: none; }
.timeline .dot { width: 12px; height: 12px; border-radius: 999px; background: var(--line); flex: none; margin-top: 3px; position: relative; z-index: 1; }
.timeline .dot.done { background: var(--ok); }
.timeline .dot.now { background: var(--svc-accent); box-shadow: 0 0 0 5px rgba(46, 155, 196, .18); }
.timeline .label { font-size: 14px; font-weight: 700; }
.timeline .note { font-size: 12.5px; color: var(--txt2); }

/* ── Mystery teasers ────────────────────────────────────────────────────── */
.teasers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 34px; }
.teaser { border-radius: 24px; padding: 36px; text-align: center; position: relative; }
.teaser.c { background: var(--tint-c); }
.teaser.p { background: var(--tint-p); }
.teaser.b { background: var(--tint-b); }
/* Blurred, and that is the point — the shape must not identify the vertical. */
.teaser .emoji { font-size: 64px; filter: blur(12px); line-height: 1; user-select: none; }
.teaser h3 { font-family: var(--font-display); font-weight: 800; font-size: 22px; margin-top: 18px; }
.teaser.c h3 { color: var(--acc-c); }
.teaser.p h3 { color: var(--acc-p); }
.teaser.b h3 { color: var(--acc-b); }
.teaser p { font-size: 13.5px; color: var(--txt2); margin-top: 8px; }
.teaser .soon {
  position: absolute; top: 16px; right: 16px;
  font-size: 9px; font-weight: 800; letter-spacing: .08em;
  /* Ink chip in BOTH themes. --cta-bg flips to zest in dark, which turned this
     quiet "soon" marker into a loud yellow badge — the boards draw it the same
     restrained way in both. */
  background: #1C1B26; color: #FAF7F2; padding: 4px 9px; border-radius: 999px;
}

/* ── Why grid ───────────────────────────────────────────────────────────── */
.why { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 34px; }
.why-card { background: var(--card); border: 1px solid var(--line); border-radius: 20px; padding: 24px; }
.why-card .icon { font-size: 22px; }
.why-card h3 { font-size: 15.5px; font-weight: 800; margin-top: 12px; }
.why-card p { font-size: 13px; color: var(--txt2); margin-top: 6px; }

/* ── Waitlist band ──────────────────────────────────────────────────────── */
/* Zest in BOTH themes — the handoff calls this out explicitly. */
.waitlist { background: var(--zest); color: #1C1B26; padding: 64px 48px; }
.waitlist h2 { font-size: 40px; font-weight: 800; color: #1C1B26; }
.waitlist h2 .dot { color: #FAF7F2; }
.waitlist p { margin-top: 12px; font-size: 16px; color: #1C1B26; max-width: 56ch; }
.waitlist-form { display: flex; gap: 10px; margin-top: 24px; flex-wrap: wrap; }
.waitlist input {
  width: 300px; max-width: 100%; background: #FAF7F2; border: 0; border-radius: 16px;
  padding: 15px 18px; font-size: 15px; font-family: var(--font-ui); color: #1C1B26;
}
.waitlist button { background: #1C1B26; color: #FAF7F2; border-radius: 16px; padding: 15px 24px; font-size: 15px; }
.waitlist button:hover { filter: brightness(1.15); color: #FAF7F2; }
/* The global focus ring is zest, and this band IS zest — the indicator was
   invisible exactly where the only form on the site lives. Ink is ~9:1 here. */
.waitlist :focus-visible { outline-color: #1C1B26; }
.waitlist-note { margin-top: 12px; font-size: 13px; min-height: 1.2em; }
.waitlist-note[data-state="error"] { font-weight: 700; }

/* ── Footer ─────────────────────────────────────────────────────────────── */
.footer { background: var(--foot); color: #FAF7F2; padding: 56px 48px 28px; }
.footer a { color: #FAF7F2; }
.footer a:hover { color: var(--zest); }
.footer-cols { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: 32px; }
/* display:contents so the two link columns become direct grid items of
   .footer-cols and the desktop row is four columns, not three.
   IN CSS, NOT INLINE: an inline display:contents cannot be overridden by the
   mobile media query below, which left the columns stacked full-width and made
   the footer 974px tall on a 375px screen — three times the design. */
.footer-links-grid { display: contents; }
.footer h4 { font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: #A9A5B4; margin: 0 0 14px; }
.footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; font-size: 13.5px; }
.footer-blurb { font-size: 13.5px; color: #A9A5B4; margin-top: 14px; max-width: 34ch; }
.pill-whatsapp {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 16px;
  background: var(--ok); color: #fff; border-radius: 999px; padding: 10px 16px;
  font-size: 13px; font-weight: 700;
}
.pill-whatsapp:hover { color: #fff; filter: brightness(1.08); }
.footer-badges { display: grid; gap: 8px; }
.footer-badge {
  display: inline-flex; align-items: center; gap: 8px; opacity: .55;
  border: 1px solid var(--foot-line); border-radius: 12px; padding: 8px 12px; font-size: 12px;
}
.footer-join { display: inline-block; margin-top: 10px; color: var(--zest); font-weight: 700; font-size: 13px; }
.footer-bottom {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  border-top: 1px solid var(--foot-line); margin-top: 36px; padding-top: 20px;
  font-size: 12px; color: #A9A5B4;
}

/* ── Overlays ───────────────────────────────────────────────────────────── */
.wa-bubble {
  /* ── Overlay stacking order, in one place ────────────────────────────────
     40  WhatsApp bubble      page furniture
     41  cookie bar           above the bubble, which it would otherwise cover
     45  drawer scrim         dims the page INCLUDING the cookie bar
     46  drawer               above everything it dims
     47  topbar               board 5a keeps the strip visible above the drawer
     The cookie bar used to sit at 45 — above the drawer — so opening the menu
     with consent still pending painted the banner across the drawer's footer,
     hiding the teaser pills and half the legal links. */
  position: fixed; right: 22px; bottom: 22px; z-index: 40;
  width: 58px; height: 58px; border-radius: 999px; background: var(--ok);
  display: grid; place-items: center; font-size: 26px;
  box-shadow: 0 10px 26px rgba(28, 27, 38, .22);
  transition: transform .2s ease;
}
.wa-bubble:hover { transform: scale(1.08); }
/* Until a number is configured, app.js marks every WhatsApp control
   aria-disabled and swallows the click. Nothing showed that, so all four read
   as live buttons that silently do nothing. Same dimmed-until-live convention
   the pre-launch store badges already use. */
[data-wa][aria-disabled="true"] { opacity: .55; cursor: default; }
[data-wa][aria-disabled="true"]:hover { transform: none; filter: none; }
.cookie {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 22px; z-index: 41;
  background: #1C1B26; color: #FAF7F2; border-radius: 18px; border: 1px solid var(--foot-line);
  padding: 16px 20px; display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .45); max-width: calc(100vw - 32px);
}
.cookie p { font-size: 13px; }
.cookie button { border: 0; cursor: pointer; font-family: var(--font-ui); font-size: 13px; font-weight: 700; border-radius: 12px; padding: 10px 16px; }
.cookie .ghost { background: transparent; color: #FAF7F2; border: 1px solid #34323F; }
.cookie .ok { background: var(--zest); color: #1C1B26; }
[hidden] { display: none !important; }

/* ── Mobile (board 3a, design width 390) ────────────────────────────────── */
@media (max-width: 860px) {
  .topbar { font-size: 10.5px; }
  .nav { padding: 14px 18px; }
  .nav-links { display: none; }
  .nav-actions .pill-ghost { display: none; }
  /* Board 3a's nav CTA is COMPACT — 11.5px in an 8x14 box, not the desktop
     13px/11x20. At desktop size it wrapped to two lines at every mobile width
     including the 390px design width, swallowing the row and squeezing the
     burger. nowrap so it can never wrap again; flex: none on the brand mark so
     the fixed-size items stop absorbing the row's overflow. */
  .nav .btn-primary {
    font-size: 11.5px; padding: 8px 14px; border-radius: 12px;
    white-space: nowrap; flex: none; box-shadow: none;
  }
  .brand svg { flex: none; }
  .brand { flex: none; min-width: 0; }
  .nav-toggle {
    /* flex: none, or the two fixed-size items absorb the row's overflow and
       the 44px tap target shrinks to 31px below 398px — breaking the minimum
       this stylesheet declares for every other control. */
    flex: none;
    display: grid; place-items: center; width: 44px; height: 44px;
    background: var(--card); border: 1.5px solid var(--line); border-radius: 14px;
    font-size: 18px; cursor: pointer; color: var(--txt); padding: 0;
  }
  /* The button holds BOTH glyphs and shows one, so the swap costs no reflow —
     but only if something actually hides the other. Without these two rules
     the grid stacked them and the closed button rendered a bars-over-cross.
     Keyed on aria-expanded so the visual state cannot drift from the state
     assistive tech is told: there is one source of truth, not two. */
  .nav-toggle .ex { display: none; }
  .nav-toggle[aria-expanded="true"] .bars { display: none; }
  .nav-toggle[aria-expanded="true"] .ex { display: block; }
  header { position: relative; }

  /* The MOBILE phone follows the theme, the desktop one does not. That is not
     an inconsistency in this stylesheet, it is what the two boards say: the 3a
     dark phone screen carries color:#FAF7F2 and a dark ground, while 2a pins
     #FAF7F2/#1C1B26 as literals in both themes. The demo spec is explicit that
     "in dark mode the app itself renders dark", and the demo is mobile-only.
     Without this the demo painted var(--bg) #17161F under inherited #1C1B26
     text — near-black on near-black. */
  .phone-screen {
    /* The APP's ground, not the site's. The status strip lives here, outside
       .nbd, so painting it with the site's --bg (#17161F) left a hard seam
       above an app screen painted #121118 — the app appeared to start a third
       of the way down the device. Board 3a paints one ground for the whole
       screen, status row included. */
    background: var(--app-bg); color: var(--app-tx);
    /* The mobile hero centres its column, and that inherited into every demo
       screen — the boards keep the app's content left-aligned. .nbd-screen
       .centred re-declares center on screens 3 and 5, so those still centre. */
    text-align: start;
  }
  /* The demo sits inside .phone-screen's 14px side padding AND adds its own,
     leaving 194px of content where the board has 224 — enough to wrap "3 kg"
     and the WhatsApp toast. Cancel the outer one for the demo only. */
  .nbd { margin-inline: -14px; }
  /* .phone-greet is the ONE element shared by both phone screens that pins a
     day literal (#5B5766). On the desktop screen that is right — that screen
     stays light in both themes — but the mobile screen darkens under it, and
     the greeting was rendering at 2.56:1 against #17161F. Scoped here rather
     than tokenised at the source, for exactly the same reason .phone-screen is. */
  .phone-greet { color: var(--txt2); }

  .hero { grid-template-columns: 1fr; text-align: center; padding: 32px 18px 44px; gap: 32px; }
  .hero::before { top: -90px; width: 420px; height: 380px; }
  /* 3a-mobile-dark: on a phone the glow replaces the bob. */
  /* Board 3a's phone sits STRAIGHT and bobs on the vertical only (nb-bob2);
     the -6deg tilt is the desktop board's treatment. Its frame is tighter too:
     40/9/33 against the desktop's 44/10/36. */
  .phone {
    transform: none; border-radius: 40px; padding: 9px;
    /* 0 40px 70px, not the desktop board's 0 50px 90px — a 270px phone under a
       300px phone's shadow reads as floating off the page. */
    box-shadow: 0 40px 70px var(--shadow);
    animation: nb-bob2 7s ease-in-out infinite;
  }
  /* The floating "Consider it done." sticker is a DESKTOP treatment — board 2a
     has it, both 3a boards have none. On a 270px phone it covered the app bar
     and the first line of the screen it was decorating. The phrase still
     appears in the demo's own confirm screen, which is where 3a puts it. */
  .phone-sticker { display: none; }
  .phone-screen { border-radius: 33px; position: relative; }
  /* Board 3a dark rings the screen with a 1px #2C2A38 hairline — the app's own
     midnight `line` token. Without it a #121118 screen inside a #000 bezel has
     no edge and the device reads as one soft mass. An overlay ring rather than
     an inset shadow, so the full-bleed tab bar cannot paint over it. */
  html[data-theme="dark"] .phone-screen::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit;
    box-shadow: inset 0 0 0 1px var(--app-line); pointer-events: none; z-index: 1;
  }
  /* Black, not ink. Board 3a dark builds the device on #000; at #1C1B26 the
     bezel was LIGHTER than the midnight page around it, so the phone read as a
     grey slab rather than a device. (No hairline ring here — nb-glow writes
     box-shadow on every keyframe and would erase it.) */
  html[data-theme="dark"] .phone { background: #000; animation: nb-glow 5s ease-in-out infinite; }
  .hero-sub, .hero-caption { margin-inline: auto; }
  .hero h1 { font-size: 56px; }
  .badges { flex-direction: column; align-items: center; }
  .badge { width: 200px; justify-content: center; }
  .phone { width: 270px; }

  .ticker { padding: 10px 0; }
  .ticker-track span { font-size: 12px; }

  .section { padding: 44px 18px; }
  .section h2 { font-size: 30px; }
  .steps { grid-template-columns: 1fr; gap: 14px; }
  .step { transform: none !important; display: grid; grid-template-columns: 44px 1fr; gap: 16px; align-items: start; padding: 20px; }
  .step h3 { margin-top: 0; }
  .step .num { grid-row: span 2; }

  .svc { grid-template-columns: 1fr; }
  .svc-left { padding: 26px; }
  .svc-left h2 { font-size: 28px; }
  .timeline-card { padding: 24px; }

  .teasers { grid-template-columns: 1fr; gap: 12px; }
  .teaser .emoji { grid-row: span 2; }
  .teaser { display: grid; grid-template-columns: 54px 1fr; gap: 16px; text-align: start; padding: 20px; align-items: center; }
  .teaser .emoji { font-size: 34px; filter: blur(9px); }
  .tile.locked .icon { filter: blur(5px); }
  .teaser h3 { margin-top: 0; font-size: 18px; }

  .why { grid-template-columns: 1fr 1fr; gap: 12px; }
  .why-card { padding: 18px; }

  .waitlist { padding: 44px 18px; }
  .waitlist h2 { font-size: 28px; }
  .waitlist-form { flex-direction: column; }
  .waitlist input, .waitlist button { width: 100%; }

  .footer { padding: 40px 18px 24px; }
  .footer-cols { grid-template-columns: 1fr; gap: 28px; }
  /* Board 3a: "footer single column with 2-col link grid". The two link
     columns pair up instead of each taking a full-width row. */
  .footer-links-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
  /* Board 3a's mobile footer is FLATTER than the desktop one, and that is what
     keeps it short: no section headings, and no app column at all. The store
     badges are decorative pre-launch spans and the waitlist band sits directly
     above this footer on mobile, so neither is lost — but stacked, they were
     most of the footer's height. */
  .footer-links-grid h4 { display: none; }
  .footer-app { display: none; }

  /* Leaves room for the 48px bubble, per the handoff. */
  .wa-bubble { width: 48px; height: 48px; font-size: 22px; right: 14px; bottom: 14px; }
  .cookie { left: 14px; right: 76px; transform: none; bottom: 14px; max-width: none; padding: 12px 14px; }
  .cookie p { font-size: 12px; }

  /* Tap targets >= 44px. */
  .nav-links a, .footer ul a { min-height: 44px; display: flex; align-items: center; }
}

/* Per-breakpoint copy. Both strings ship in the document — they are short, and
   hiding one is cheaper and more honest than swapping text in JS after paint. */
.only-narrow { display: none; }
/* Flex variants: the ticker track must stay a flex row when shown, so it
   cannot use the `inline` value the text spans use. */
.only-narrow-flex { display: none; }
.only-wide-flex { display: flex; }
/* Block variants, for the two hero phone screens. */
.only-narrow-block { display: none; }
.only-wide-block { display: block; }
@media (max-width: 860px) {
  .only-wide { display: none; }
  .only-narrow { display: inline; }
  .only-wide-flex { display: none; }
  .only-narrow-flex { display: flex; }
  .only-wide-block { display: none; }
  .only-narrow-block { display: block; }
}

/* ── Theme override ─────────────────────────────────────────────────────── */
/* The handoff makes the control optional and puts it in the footer; the drawer
   copy is there because the burger is where a phone reaches for settings.
   Both are the same component and both write the same localStorage key. */
.footer-theme { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 32px; }
.footer-theme-label { font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: #A9A5B4; }
.theme-switch { display: inline-flex; gap: 4px; background: var(--card); border: 1px solid var(--line); border-radius: 999px; padding: 4px; }
.footer .theme-switch { background: transparent; border-color: var(--foot-line); }
.theme-switch button {
  border: 0; cursor: pointer; font-family: var(--font-ui);
  font-size: 11.5px; font-weight: 700; border-radius: 999px; padding: 8px 14px;
  background: transparent; color: var(--txt2); min-height: 36px;
}
.footer .theme-switch button { color: #A9A5B4; }
.theme-switch button[aria-pressed="true"] { background: var(--zest); color: #1C1B26; }
.footer .theme-switch button[aria-pressed="true"] { background: var(--zest); color: #1C1B26; }
.drawer-theme { display: none; }
@media (max-width: 860px) {
  /* Inside the drawer only — the desktop nav has no room and the footer
     control already covers it. */
  .drawer .drawer-theme { display: inline-flex; justify-content: center; }
  .theme-switch button { min-height: 44px; }
}


/* ── Mobile burger drawer (board 5a) ──────────────────────────────────────
   A full-screen drawer on --bg, NOT a partial sheet. It sits outside <header>
   so the topbar strip stays visible above it, which is what the board shows.

   [hidden] is the closed state and is authoritative: the element is out of the
   accessibility tree and untabbable when shut. .open is added a frame later so
   the transition has a from-state to animate out of — setting both in one tick
   makes the drawer appear instantly with no slide. */
.drawer,
.drawer-scrim { display: none; }

@media (max-width: 860px) {
  .drawer-scrim {
    display: block; position: fixed; inset: var(--drawer-top, 0px) 0 0 0; z-index: 45;
    background: rgba(0, 0, 0, .4); opacity: 0;
    transition: opacity 280ms ease-out;
  }
  .drawer-scrim.open { opacity: 1; }
  .drawer-scrim[hidden] { display: none; }

  .drawer {
    display: flex; flex-direction: column;
    /* Starts BELOW the topbar, not behind it. The topbar paints above it
       — above the drawer, by design, because board 5a keeps the strip visible
       — so a drawer at top:0 had its header row (mark + close) cropped by it.
       --drawer-top is measured from the topbar's live bottom edge in app.js,
       which also handles the half-scrolled case; 0 is the correct fallback if
       the script never runs, since then nothing is painted over it either. */
    position: fixed; top: var(--drawer-top, 0px); right: 0; bottom: 0;
    width: 100%; max-width: 430px; z-index: 46;
    background: var(--bg); color: var(--txt);
    transform: translateX(100%);
    transition: transform 280ms ease-out;
    /* SCROLLS. Every child is flex: 0 0 auto and the stack is ~830px tall, so
       on any viewport shorter than that the bottom simply vanished: at 375x667
       the Appearance switch was cut in half and the whole footer was gone, and
       in landscape two nav rows and the primary CTA were unreachable. There was
       no scrollbar and no touch scroll — only Tab scrolled the container, so the
       drawer jumped for keyboard users and was truncated for everyone else.
       margin-top:auto on .drawer-foot still pins the footer on tall viewports,
       because auto margins only consume FREE space. */
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  .drawer.open { transform: none; }
  .drawer[hidden] { display: none; }

  /* The topbar strip stays visible above the drawer (board 5a). */
  .topbar { position: relative; z-index: 47; }

  /* Scroll lock. position:fixed on <body> would jump the page to the top on
     open and lose the reading position on close; overflow:hidden holds it. */
  body.drawer-open { overflow: hidden; }

  .drawer-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 18px 18px; flex: 0 0 auto;
  }
  .drawer-head .brand svg { width: 26px; height: 26px; }
  .drawer-head .wordmark { font-size: 17px; }
  .drawer-close { color: var(--txt); }

  .drawer-links { display: flex; flex-direction: column; padding: 10px 22px 0; flex: 0 0 auto; }
  .drawer-links a {
    display: flex; align-items: center; justify-content: space-between;
    padding: 19px 2px; min-height: 56px;
    border-bottom: 1px solid var(--line); color: var(--txt);
  }
  .drawer-links a:last-child { border-bottom: 0; }
  .drawer-row-l { display: flex; align-items: baseline; gap: 12px; }
  .drawer-row-r { display: flex; align-items: center; gap: 8px; }
  .drawer-num {
    font-size: 10px; font-weight: 800; font-variant-numeric: tabular-nums;
    color: var(--num); letter-spacing: .02em;
  }
  .drawer-label {
    font-family: var(--font-display); font-weight: 700;
    font-size: 26px; letter-spacing: -.02em;
  }
  .drawer-pill {
    font-size: 9px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
    background: var(--tint-l); color: #2E9BC4; border-radius: 999px; padding: 3px 8px;
    white-space: nowrap;
  }
  .drawer-arrow { color: var(--zest); font-size: 18px; font-weight: 700; line-height: 1; }

  .drawer-ctas { display: flex; flex-direction: column; gap: 10px; padding: 18px 22px 0; flex: 0 0 auto; }
  .drawer-cta {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    background: var(--cta-bg); color: var(--cta-txt); border-radius: 16px;
    padding: 16px 0; font-size: 14.5px; font-weight: 700;
    box-shadow: 0 10px 26px var(--shadow); min-height: 44px;
  }
  .drawer-cta span { color: var(--price); }
  .drawer-wa {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    background: #2E9E63; color: #fff; border-radius: 16px;
    padding: 15px 0; font-size: 13.5px; font-weight: 700; min-height: 44px;
  }

  /* margin-top:auto pins the footer to the bottom without position:absolute,
     so a short viewport pushes it down instead of overlapping the CTAs. */
  .drawer-theme-row {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 18px 22px 0; flex: 0 0 auto;
  }
  .drawer-theme-row .footer-theme-label { color: var(--txt2); }

  .drawer-foot { margin-top: auto; flex: 0 0 auto; }
  .drawer-foot-row {
    display: flex; justify-content: space-between; align-items: flex-end;
    padding: 0 22px 16px; gap: 16px;
    /* At 320px the pills and the legal links together exceed the row and
       "Privacy" was clipped off the edge. Wrap instead of overflow. */
    flex-wrap: wrap;
  }
  .drawer-legal { flex: none; }
  .drawer-soon { display: flex; gap: 6px; margin-bottom: 10px; }
  .drawer-soon-pill {
    display: flex; align-items: center; gap: 5px;
    font-size: 9px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
    background: var(--pillbg); border: 1px solid var(--line); color: var(--txt2);
    border-radius: 999px; padding: 4px 9px;
  }
  .drawer-soon-pill .blur { filter: blur(4px); font-size: 11px; }
  .drawer-soon-cap { font-size: 10.5px; color: var(--txt2); font-weight: 500; }
  .drawer-legal { display: flex; gap: 12px; font-size: 11px; font-weight: 600; flex: 0 0 auto; }
  .drawer-legal a { color: var(--txt2); }
  .drawer-ticker { border: 0; border-radius: 0; }

  /* Rows stagger in 40ms apart (fade + 12px rise). --i is set in app.js from
     the row's index; the delay is only paid on OPEN. */
  .drawer.open .drawer-links a,
  .drawer.open .drawer-ctas > * {
    animation: nb-drawer-row 260ms ease-out backwards;
    animation-delay: calc(120ms + var(--i, 0) * 40ms);
  }
}

@keyframes nb-drawer-row {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

/* prefers-reduced-motion: plain fade, no slide and no stagger. */
@media (prefers-reduced-motion: reduce) {
  .drawer { transition: opacity 160ms ease-out; transform: none; opacity: 0; }
  .drawer.open { opacity: 1; }
  .drawer.open .drawer-links a,
  .drawer.open .drawer-ctas > * { animation: none; }
}


/* ── Hero phone demo loop (handoff v5, sections 4 + 5) ────────────────────
   Home -> Book -> Confirm -> Track -> Done -> Home on a 16s cycle. Five
   screens stacked absolutely; nbd-s1..s5 cross-fade them and nbd-cursor walks
   a dot between four taps.

   These screens depict the SHIPPED FLUTTER APP, not the website, so they carry
   the app's OWN tokens — Thread v0.3 "midnight" in dark, which is a deeper
   ground than the site's (#121118 vs #17161F). That is deliberate: the handoff
   pins both, and reusing the site's dark set here would make the phone look
   like a hole in the page rather than a screen. Everything below reads these
   local tokens, so one markup serves both themes. */
.nbd,
.nbd-tabbar,
.phone-screen {
  --app-bg: #FAF7F2;
  --app-card: #fff;
  --app-line: #EAE4DA;
  --app-line2: #D8D2C8;
  --app-tx: #1C1B26;
  --app-tx2: #5B5766;
  --app-tx3: #8B8695;
  --app-cta-bg: #1C1B26;
  --app-cta-tx: #FAF7F2;
  --app-zest-tx: #8A6400;
  --app-cursor: rgba(28, 27, 38, .85);
}
.nbd { display: none; position: relative; height: 452px; overflow: hidden; }
html[data-theme="dark"] .nbd,
html[data-theme="dark"] .nbd-tabbar,
html[data-theme="dark"] .phone-screen {
  --app-bg: #121118;
  --app-card: #1A1922;
  --app-line: #2C2A38;
  --app-line2: #4A4658;
  --app-tx: #FAF7F2;
  --app-tx2: #8B8695;
  /* Board 3a dark gives the SERVICES eyebrow, the ghost SOON pill and the
     footer caption #5F5B6B — a level BELOW tx2. Setting them equal flattened
     the screen's three text levels into two. */
  --app-tx3: #5F5B6B;
  --app-cta-bg: #FFC529;
  --app-cta-tx: #1C1B26;
  --app-zest-tx: #FFC529;
  --app-cursor: rgba(250, 247, 242, .9);
}
@media (max-width: 860px) { .nbd { display: block; } }

/* App chrome under the demo. Shown only where the demo is, and it must set its
   OWN display — reusing .only-narrow-block gave it `display: block` and stacked
   the three tabs vertically down the phone. */
.nbd-tabbar { display: none; }
@media (max-width: 860px) {
  .nbd-tabbar {
    /* Sibling of .nbd, so it cannot inherit .nbd's local app tokens — it takes
       them from .phone-screen, which the mobile block already themes. */
    display: flex; justify-content: space-around;
    border-top: 1px solid var(--app-line);
    padding: 8px 0 12px; margin: 0 -14px -14px;
    background: var(--app-bg); color: var(--app-tx2);
    font-size: 7.5px; text-align: center;
  }
  .nbd-tabbar span { flex: none; font-weight: 600; }
  .nbd-tabbar span.active { color: var(--app-tx); font-weight: 700; }
  /* .tabbar span i (the desktop screen's rule) is more specific, so the demo
     bar inherited its 15px. Matched here rather than loosened there, so the
     desktop screen keeps its own size. */
  .nbd-tabbar span i { display: block; font-style: normal; font-size: 13px; margin-bottom: 1px; }
  /* The active tab carries a 4px zest dot; the others reserve the space so the
     labels stay on one baseline. */
  .nbd-tabbar b { display: block; width: 4px; height: 4px; border-radius: 50%; margin: 2px auto 0; background: transparent; }
  .nbd-tabbar span.active b { background: var(--zest); }
}

.nbd-screen {
  position: absolute; inset: 0; padding: 10px 14px;
  background: var(--app-bg); color: var(--app-tx);
}
.nbd-screen.centred {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; text-align: center; padding: 20px;
}
.nbd-s1 { animation: nbd-s1 16s linear infinite; }
.nbd-s2 { opacity: 0; padding: 14px; animation: nbd-s2 16s linear infinite; }
.nbd-s3 { opacity: 0; animation: nbd-s3 16s linear infinite; }
.nbd-s4 { opacity: 0; animation: nbd-s4 16s linear infinite; }
.nbd-s5 { opacity: 0; animation: nbd-s5 16s linear infinite; }

/* ── Screen 1: Home ─────────────────────────────────────────────────────── */
.nbd-appbar { display: flex; align-items: center; gap: 6px; }
.nbd-appbar svg { width: 14px; height: 14px; flex: none; }
.nbd-wordmark { font-family: var(--font-display); font-weight: 800; font-size: 10px; letter-spacing: -.02em; }
.nbd-wordmark i { font-style: normal; color: var(--zest); }
.nbd-spacer { flex: 1; }
.nbd-address { font-size: 7.5px; color: var(--app-tx2); font-weight: 500; }
.nbd-bell { position: relative; font-size: 10px; line-height: 1; }
.nbd-bell-dot {
  position: absolute; top: -1px; right: -2px; width: 4px; height: 4px;
  border-radius: 50%; background: var(--zest);
}
.nbd .phone-greet { font-size: 8px; color: var(--app-tx2); font-weight: 600; margin-top: 12px; }
.nbd .phone-ask {
  font-family: var(--font-display); font-weight: 800; font-size: 14.5px;
  letter-spacing: -.01em; line-height: 1.08; margin-top: 2px; color: var(--app-tx);
}
.nbd-q { color: var(--app-zest-tx); }

/* The thread stroke. Two passes of one path — a blurred glow under a crisp
   line — dash-drawn in after a beat. A straight underline is the thing this
   deliberately is not. */
.nbd-thread { display: block; width: 195px; max-width: 100%; height: 16px; margin-top: 5px; overflow: visible; }
.nbd-thread path { animation: nbd-under 16s linear infinite; }
.nbd-thread .glow { filter: blur(2.5px); opacity: .85; }

.nbd-promo {
  display: flex; align-items: center; gap: 7px;
  background: var(--app-card); border: 1px solid var(--app-line);
  border-radius: 13px; padding: 8px; margin-top: 10px;
}
.nbd-promo-badge {
  width: 22px; height: 22px; border-radius: 7px; background: var(--zest); color: #1C1B26;
  display: flex; align-items: center; justify-content: center;
  font-size: 7px; font-weight: 800; flex: none;
}
.nbd-promo-title { display: block; font-size: 8.5px; font-weight: 700; }
.nbd-promo-body { display: block; font-size: 7px; color: var(--app-tx2); margin-top: 1px; }

.nbd-eyebrow {
  font-size: 8px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--app-tx2); margin: 12px 0 6px;
}
.nbd-eyebrow.services { font-size: 7.5px; letter-spacing: .1em; color: var(--app-tx3); margin: 11px 0 6px; }
/* The board tightens the SECOND slot group so the two rails read as one unit
   rather than two stacked sections. */
.nbd-eyebrow.tight { margin-top: 10px; }

.nbd-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.nbd-tile {
  position: relative; background: var(--app-card);
  border: 1px solid var(--app-line); border-radius: 13px; padding: 9px;
}
.nbd-tile.locked { opacity: .45; }
/* An orb WELL, not a rounded chip: circular, tinted, and lit from within on
   the live service. */
.nbd-orb {
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--tile-tint, var(--tint-l));
  display: flex; align-items: center; justify-content: center; font-size: 11px;
}
.nbd-tile:not(.locked) .nbd-orb { box-shadow: 0 0 12px color-mix(in srgb, var(--tile-accent, #2E9BC4) 30%, transparent); }
/* Lit harder against midnight — README section 5: "tint + glow, midnight full
   alpha / daylight .3". Scoped to the theme so it cannot reach the desktop
   screen, which stays daylight. */
html[data-theme="dark"] .nbd-tile:not(.locked) .nbd-orb { box-shadow: 0 0 12px color-mix(in srgb, var(--tile-accent, #2E9BC4) 50%, transparent); }
.nbd-tile.locked .nbd-orb span { filter: blur(5px); }
.nbd-tile-name { font-weight: 700; font-size: 9px; margin-top: 6px; }
.nbd-tile-tag { font-size: 7px; color: var(--app-tx2); margin-top: 1px; }
/* Ghost outline, not a solid chip — the app draws it as a hint, not a badge. */
.nbd-soon {
  position: absolute; top: 7px; right: 7px;
  font-size: 6px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  border: 1px solid var(--app-line); color: var(--app-tx3);
  border-radius: 999px; padding: 1.5px 6px; background: transparent;
}
.nbd-home-foot { text-align: center; font-size: 7px; color: var(--app-tx3); margin-top: 10px; }

/* ── Screen 2: the Thread Rail ──────────────────────────────────────────── */
.nbd-head { display: flex; align-items: center; gap: 7px; }
.nbd-back { font-size: 13px; color: var(--app-tx2); }
.nbd-title { font-family: var(--font-display); font-weight: 700; font-size: 14px; }
.nbd-status {
  margin-left: auto; font-size: 7.5px; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; background: var(--tint-l); color: var(--svc-accent);
  border-radius: 999px; padding: 2px 7px;
}
.nbd-steps { display: flex; gap: 5px; margin-top: 10px; }
.nbd-steps i { flex: 1; height: 3px; border-radius: 99px; background: var(--app-line); }
.nbd-steps i.on { background: var(--zest); }

/* Stations on a glowing vertical rail. The lit segment runs from the top down
   to the furthest SELECTED station; everything past it stays hairline. */
.nbd-rail { position: relative; }
.nbd-rail-line { position: absolute; left: 12px; top: 5px; bottom: 12px; width: 2px; background: var(--app-line); }
.nbd-rail-lit {
  position: absolute; left: 12px; top: 5px; width: 2px; height: 12px;
  background: var(--zest); box-shadow: 0 0 6px rgba(255, 197, 41, .8);
  opacity: 0; animation: 16s linear infinite;
}
.nbd-station {
  position: absolute; left: 9px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--app-line); animation: 16s linear infinite;
}
.nbd-slot {
  margin-left: 26px; display: flex; justify-content: space-between; align-items: center;
  background: var(--app-card); border: 1px solid var(--app-line); border-radius: 12px;
  padding: 8px 10px; margin-bottom: 6px;
  /* Explicit line-height. The 36px station pitch is the board's, and it assumes
     the board's ~1.2 default; inheriting body's 1.5 made each card 32px and the
     real pitch 38px, so the dots walked off their cards down the group. */
  font-size: 9.5px; line-height: 12px; font-weight: 500; color: var(--app-tx2);
}
.nbd-slot.picking { animation: 16s linear infinite; }
.nbd-check { font-size: 9px; font-weight: 800; color: var(--app-zest-tx); opacity: 0; animation: 16s linear infinite; }
.nbd-note-field {
  border: 1px dashed var(--app-line2); border-radius: 10px; padding: 7px 9px;
  margin-top: 10px; font-size: 8.5px; color: var(--app-tx2);
}
.nbd-cta {
  background: var(--app-cta-bg); border-radius: 12px; padding: 11px 14px; margin-top: 7px;
  display: flex; justify-content: space-between; align-items: center;
  color: var(--app-cta-tx); font-size: 11.5px; font-weight: 700;
}
/* Disabled until both legs are picked, which is what the rail is for. */
.nbd-cta.pinned {
  position: absolute; left: 14px; right: 14px; bottom: 14px; margin-top: 0;
  opacity: .45; animation: nbd-cta 16s linear infinite;
}
.nbd-arrow { color: var(--zest); }
html[data-theme="dark"] .nbd-arrow { color: #1C1B26; }

/* ── Screen 3: Confirm ──────────────────────────────────────────────────── */
.nbd-tick path { animation: nbd-tick 16s linear infinite; }
.nbd-big { font-family: var(--font-display); font-weight: 800; font-size: 19px; margin-top: 6px; }
.nbd-sub { font-size: 10px; color: var(--app-tx2); margin-top: 6px; line-height: 1.6; }

/* ── Screen 4: Track ────────────────────────────────────────────────────── */
.nbd-toast {
  background: var(--app-card); border: 1px solid var(--app-line); border-radius: 12px;
  padding: 9px 10px; margin-top: 9px; opacity: 0; animation: nbd-toast 16s linear infinite;
}
.nbd-toast-from { display: flex; align-items: center; gap: 6px; font-size: 8.5px; font-weight: 700; color: var(--app-tx2); }
.nbd-wa {
  width: 18px; height: 18px; border-radius: 50%; background: #2E9E63;
  display: flex; align-items: center; justify-content: center; font-size: 9px;
}
.nbd-toast-body { font-size: 9.5px; font-weight: 600; margin-top: 4px; }
.nbd-eta { background: var(--tint-l); border-radius: 12px; padding: 11px; margin-top: 8px; }
.nbd-eta-t { font-size: 10.5px; font-weight: 700; color: var(--svc-accent); }
.nbd-eta-s { font-size: 8.5px; color: var(--app-tx2); margin-top: 2px; }
.nbd-bar { height: 5px; background: var(--app-card); border-radius: 999px; margin-top: 8px; overflow: hidden; }
.nbd-bar i { display: block; width: 22%; height: 100%; background: var(--svc-accent); border-radius: 999px; animation: nbd-bar 16s linear infinite; }
.nbd-track { margin-top: 12px; }
.nbd-track-step { display: flex; gap: 9px; align-items: flex-start; }
.nbd-track-rail { display: flex; flex-direction: column; align-items: center; }
.nbd-track-rail i { display: block; width: 2px; height: 16px; background: var(--app-line); }
.nbd-track-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--app-line); }
.nbd-track-dot.done { background: var(--ok); }
.nbd-track-dot.now { background: var(--svc-accent); box-shadow: 0 0 0 3px var(--tint-l); }
.nbd-track-label { font-size: 9.5px; font-weight: 600; margin-top: -2px; }
/* The step in progress is heavier — the app weights current AND done at 700,
   the board weights the current one 700 against 600 for the two behind it.
   One rule for all three made the timeline read as having no present tense. */
.nbd-track-step.now .nbd-track-label { font-weight: 700; }
.nbd-track-label span { color: var(--app-tx2); font-weight: 500; }
.nbd-actions { position: absolute; left: 14px; right: 14px; bottom: 14px; display: flex; gap: 6px; }
.nbd-act {
  flex: 1; border: 1.5px solid var(--app-line); background: var(--app-card); color: var(--app-tx);
  border-radius: 10px; padding: 9px 0; text-align: center; font-size: 9.5px; font-weight: 700;
}
.nbd-act.primary { background: #2E9E63; color: #fff; border-color: #2E9E63; }

/* ── Screen 5: Done ─────────────────────────────────────────────────────── */
.nbd-emoji { font-size: 30px; }
.nbd-stars { display: flex; gap: 5px; margin-top: 10px; }
.nbd-stars span {
  font-size: 19px; color: var(--zest); display: inline-block; transform: scale(0);
  animation: nbd-star 16s linear infinite; animation-delay: calc(var(--i) * .12s);
}

/* ── The cursor ─────────────────────────────────────────────────────────── */
.nbd-cursor {
  position: absolute; left: 0; top: 0; width: 26px; height: 26px; border-radius: 50%;
  background: var(--app-cursor); border: 2.5px solid #FFC529;
  box-shadow: 0 8px 20px rgba(28, 27, 38, .35); opacity: 0;
  animation: nbd-cursor 16s cubic-bezier(.4, 0, .2, 1) infinite;
}

@keyframes nbd-s1 { 0%,20% { opacity: 1 } 23%,94% { opacity: 0 } 97%,100% { opacity: 1 } }
@keyframes nbd-s2 { 0%,20% { opacity: 0; transform: translateY(18px) } 23%,40% { opacity: 1; transform: translateY(0) } 43%,100% { opacity: 0; transform: translateY(0) } }
@keyframes nbd-s3 { 0%,40% { opacity: 0 } 43%,60% { opacity: 1 } 63%,100% { opacity: 0 } }
@keyframes nbd-s4 { 0%,60% { opacity: 0; transform: translateY(18px) } 63%,80% { opacity: 1; transform: translateY(0) } 83%,100% { opacity: 0; transform: translateY(0) } }
@keyframes nbd-s5 { 0%,80% { opacity: 0 } 83%,95% { opacity: 1 } 98%,100% { opacity: 0 } }

/* Four taps now: the category tile, the pickup station, the return station,
   and Review & pay. Targets are MEASURED into these variables by app.js —
   the board's absolute offsets were read off a phone of the board's width. */
@keyframes nbd-cursor {
  0%,6%       { transform: translate(var(--c0x, 180px), var(--c0y, 360px)) scale(1); opacity: 0 }
  11%,15.5%   { transform: translate(var(--c1x, 68px),  var(--c1y, 185px)) scale(1); opacity: 1 }
  17%         { transform: translate(var(--c1x, 68px),  var(--c1y, 185px)) scale(.78); opacity: 1 }
  19%         { transform: translate(var(--c1x, 68px),  var(--c1y, 185px)) scale(1); opacity: 1 }
  25%,27.5%   { transform: translate(var(--c2x, 139px), var(--c2y, 82px))  scale(1); opacity: 1 }
  29%         { transform: translate(var(--c2x, 139px), var(--c2y, 82px))  scale(.78); opacity: 1 }
  30.5%       { transform: translate(var(--c2x, 139px), var(--c2y, 82px))  scale(1); opacity: 1 }
  33%,33.5%   { transform: translate(var(--c3x, 139px), var(--c3y, 214px)) scale(1); opacity: 1 }
  35%         { transform: translate(var(--c3x, 139px), var(--c3y, 214px)) scale(.78); opacity: 1 }
  36.5%       { transform: translate(var(--c3x, 139px), var(--c3y, 214px)) scale(1); opacity: 1 }
  39%,39.5%   { transform: translate(var(--c4x, 126px), var(--c4y, 419px)) scale(1); opacity: 1 }
  40.5%       { transform: translate(var(--c4x, 126px), var(--c4y, 419px)) scale(.78); opacity: 1 }
  42%,100%    { transform: translate(var(--c4x, 126px), var(--c4y, 419px)) scale(1); opacity: 0 }
}
@keyframes nbd-under { 0%,2% { stroke-dashoffset: 160 } 9%,100% { stroke-dashoffset: 0 } }
@keyframes nbd-tick { 0%,43% { stroke-dashoffset: 120 } 53%,100% { stroke-dashoffset: 0 } }
/* The rail's selection beats. Card border, then dot, then rail, then check —
   each on its own frame so the selection lands rather than snapping. */
@keyframes nbd-card1 { 0%,28%   { border-color: var(--app-line); box-shadow: none } 30%,100% { border-color: #FFC529; box-shadow: 0 0 20px rgba(255,197,41,.25) } }
@keyframes nbd-card2 { 0%,34%   { border-color: var(--app-line); box-shadow: none } 36%,100% { border-color: #FFC529; box-shadow: 0 0 20px rgba(255,197,41,.25) } }
@keyframes nbd-node1 { 0%,29.5% { background: var(--app-line); box-shadow: none } 31%,100% { background: #FFC529; box-shadow: 0 0 10px rgba(255,197,41,.9) } }
@keyframes nbd-node2 { 0%,35.5% { background: var(--app-line); box-shadow: none } 37%,100% { background: #FFC529; box-shadow: 0 0 10px rgba(255,197,41,.9) } }
@keyframes nbd-rail1 { 0%,29.5% { opacity: 0 } 31%,100% { opacity: 1 } }
@keyframes nbd-rail2 { 0%,35.5% { opacity: 0 } 37%,100% { opacity: 1 } }
@keyframes nbd-ck1   { 0%,29.5% { opacity: 0 } 31%,100% { opacity: 1 } }
@keyframes nbd-ck2   { 0%,35.5% { opacity: 0 } 37%,100% { opacity: 1 } }
@keyframes nbd-cta   { 0%,36%   { opacity: .45 } 38%,100% { opacity: 1 } }
@keyframes nbd-bar { 0%,63% { width: 22% } 78%,100% { width: 76% } }
@keyframes nbd-toast { 0%,66% { opacity: 0; transform: translateY(10px) } 69%,80% { opacity: 1; transform: translateY(0) } 83%,100% { opacity: 0; transform: translateY(0) } }
@keyframes nbd-star { 0%,84% { transform: scale(0) } 88%,100% { transform: scale(1) } }

/* Off-viewport, the loop is paused by app.js adding this class — sixteen
   seconds of compositing for a phone nobody is looking at is battery someone
   else is paying for. */
.nbd.paused *, .nbd.paused { animation-play-state: paused !important; }

/* prefers-reduced-motion: the static Home screen only, per the handoff. Not
   "slower" and not "fade between screens" — a demo that still changes what it
   says is still motion to someone who asked for none. */
@media (prefers-reduced-motion: reduce) {
  /* Everything animated in the demo, listed so a new moving part cannot be
     added without deciding what it does here. */
  .nbd-screen, .nbd-cursor, .nbd-tick path, .nbd-thread path,
  .nbd-slot.picking, .nbd-station, .nbd-rail-lit, .nbd-check, .nbd-cta.pinned,
  .nbd-bar i, .nbd-toast, .nbd-stars span { animation: none !important; }
  .nbd-s2, .nbd-s3, .nbd-s4, .nbd-s5, .nbd-cursor { display: none; }
  .nbd-s1 { opacity: 1; }
  .nbd-stars span { transform: scale(1); }
  /* The thread is DRAWN by its dash animation; with the animation off it would
     never appear, so it is shown complete. */
  .nbd-thread path { stroke-dashoffset: 0; }
}

/* ══════════════════════════════════════════════════════════════════════════
   v6 inner pages — boards 6a service / 6b about+FAQ / 6c contact / 6d legal
   ══════════════════════════════════════════════════════════════════════════
   Logical properties throughout (inline-start/-end), because Arabic RTL is a
   priced option the structure has to be ready for even though it is not built.
   Every interactive element carries the full state set — hover, focus-visible,
   active, disabled — since the inner pages introduce the site's first real
   forms and a keyboard user meeting an unstyled focus ring is a bug. */

.page-hero { padding-block: 56px 24px; }
.page-hero h1 { font-size: clamp(34px, 7vw, 54px); line-height: 1.03; letter-spacing: -.02em; }
.page-hero .lede { max-width: 58ch; }
.lede-tail { margin-block-start: 14px; }
.section-title { font-size: clamp(24px, 4vw, 32px); margin-block-end: 22px; }
.page-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-block-start: 26px; }

.btn-ghost {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 15px 22px; border-radius: 16px;
  border: 1px solid var(--line); background: var(--card); color: var(--txt);
  font-weight: 700; font-size: 15px; text-decoration: none;
  transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
.btn-ghost:hover { border-color: var(--txt2); transform: translateY(-1px); }
.btn-ghost:active { transform: translateY(0); }

/* ── 6a: pricing honesty. Numbers are the STEP index, never a price. ─────── */
.price-steps { list-style: none; display: grid; gap: 14px; padding: 0; margin: 0; }
.price-step {
  display: flex; gap: 16px; align-items: flex-start;
  background: var(--card); border: 1px solid var(--line);
  border-radius: 20px; padding: 20px 22px;
}
.price-num {
  flex: 0 0 auto; inline-size: 30px; block-size: 30px; border-radius: 999px;
  display: grid; place-items: center;
  background: var(--cta-bg); color: var(--cta-txt);
  font-weight: 800; font-size: 13px; font-variant-numeric: tabular-nums;
}
.price-step h3 { font-size: 17px; font-weight: 700; margin: 0 0 4px; }
.price-step p { margin: 0; color: var(--txt2); font-size: 15px; }

.svc-grid {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.svc-card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 20px; padding: 22px;
  transition: border-color .18s ease, transform .18s ease;
}
.svc-card:hover { border-color: var(--txt2); transform: translateY(-2px); }
.svc-icon { font-size: 26px; line-height: 1; display: block; margin-block-end: 12px; }
.svc-card h3 { font-size: 17px; font-weight: 700; margin: 0 0 6px; }
.svc-card p { margin: 0; color: var(--txt2); font-size: 14.5px; }
.rate-note { margin-block-start: 18px; color: var(--txt2); font-size: 13.5px; max-width: 62ch; }

.promises, .principles {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.promise, .principle { background: var(--card); border: 1px solid var(--line); border-radius: 20px; padding: 22px; }
.promise-icon, .principle-icon { font-size: 22px; display: block; margin-block-end: 10px; }
.promise h3, .principle h3 { font-size: 16px; font-weight: 700; margin: 0 0 6px; }
.promise p, .principle p { margin: 0; color: var(--txt2); font-size: 14.5px; }

/* ── 6b: the model card is the argument the business rests on ───────────── */
.model-card {
  background: var(--tint-l); border-radius: 24px; padding: 30px;
  border: 1px solid var(--line);
}
.model-card h2 { font-size: clamp(22px, 3.4vw, 30px); margin: 10px 0 12px; line-height: 1.12; }
.model-card p { margin: 0; color: var(--txt2); max-width: 62ch; }

/* ── 6b: FAQ. A question with no answer yet is DISABLED, not an empty panel. */
.faq { list-style: none; padding: 0; margin: 0; border-block-start: 1px solid var(--line); }
.faq-item { border-block-end: 1px solid var(--line); }
.faq-item h3 { margin: 0; font-size: inherit; font-weight: inherit; }
.faq-q {
  inline-size: 100%; display: flex; align-items: center; justify-content: space-between; gap: 16px;
  background: none; border: 0; cursor: pointer; text-align: start;
  padding: 20px 4px; color: var(--txt);
  font-family: inherit; font-size: 17px; font-weight: 700;
  transition: color .18s ease;
}
.faq-q:hover { color: var(--zest-deep, #8A6400); }
.faq-mark { font-size: 20px; color: var(--txt2); flex: 0 0 auto; }
.faq-a { padding: 0 4px 22px; color: var(--txt2); max-width: 68ch; }
.faq-a p { margin: 0; }
.faq-item.is-pending .faq-q { opacity: .45; cursor: not-allowed; }
.faq-item.is-pending .faq-q:hover { color: var(--txt); }

/* ── 6c: WhatsApp first. It is the fastest channel, so it leads. ─────────── */
.reach { display: grid; gap: 14px; margin-block-end: 18px; }
.reach-wa, .reach-mail {
  display: flex; align-items: center; gap: 16px;
  border-radius: 20px; padding: 20px 22px; text-decoration: none;
  border: 1px solid var(--line); background: var(--card); color: var(--txt);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.reach-wa { background: #2E9E63; border-color: #2E9E63; color: #fff; }
.reach-wa:hover, .reach-mail:hover { transform: translateY(-2px); }
.reach-mail:hover { border-color: var(--txt2); }
.reach-icon { font-size: 24px; flex: 0 0 auto; }
.reach-text { display: grid; gap: 3px; }
.reach-text strong { font-size: 17px; font-weight: 800; }
.reach-text span { font-size: 13.5px; opacity: .85; }
.reach-mail .reach-text span { color: var(--txt2); opacity: 1; }
.reach-arrow { margin-inline-start: auto; font-size: 20px; }

.partner-card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 24px; padding: 28px;
}
.partner-card h2 { font-size: clamp(21px, 3.2vw, 28px); margin: 8px 0 10px; }
.partner-card p { margin: 0; color: var(--txt2); max-width: 60ch; }

/* ── 6c: the lead form. Topic chips are what route the enquiry. ──────────── */
.lead-form { display: grid; gap: 16px; max-width: 560px; }
.topics { display: flex; flex-wrap: wrap; gap: 8px; border: 0; padding: 0; margin: 0 0 4px; }
.topic-chip { position: relative; }
.topic-chip input {
  position: absolute; opacity: 0; inline-size: 100%; block-size: 100%;
  margin: 0; cursor: pointer;
}
.topic-chip span {
  display: inline-block; padding: 9px 15px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card); color: var(--txt2);
  font-size: 13.5px; font-weight: 700; transition: all .16s ease;
}
.topic-chip input:checked + span {
  background: var(--cta-bg); color: var(--cta-txt); border-color: var(--cta-bg);
}
.topic-chip input:focus-visible + span { outline: 2px solid #FFC529; outline-offset: 2px; }
.topic-chip:hover span { border-color: var(--txt2); }

.field { display: grid; gap: 6px; }
.field label { font-size: 13px; font-weight: 800; letter-spacing: .02em; }
.field .hint { font-weight: 500; color: var(--txt2); letter-spacing: 0; }
.field input, .field textarea {
  font-family: inherit; font-size: 15px; color: var(--txt);
  background: var(--card); border: 1px solid var(--line);
  border-radius: 14px; padding: 13px 15px;
  transition: border-color .16s ease, box-shadow .16s ease;
}
.field textarea { resize: vertical; min-block-size: 96px; }
.field input::placeholder, .field textarea::placeholder { color: var(--txt2); opacity: .75; }
.field input:hover, .field textarea:hover { border-color: var(--txt2); }
.field input:focus-visible, .field textarea:focus-visible {
  outline: none; border-color: #FFC529; box-shadow: 0 0 0 3px rgba(255, 197, 41, .28);
}
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-color: #D6455D; }
.lead-privacy { font-size: 13px; color: var(--txt2); margin: 0; }
.lead-note { margin-block-start: 14px; font-weight: 700; min-block-size: 1.4em; }
.lead-form button[disabled] { opacity: .45; cursor: not-allowed; }

/* ── 6d: one legal template, two documents ──────────────────────────────── */
.legal-wrap { display: grid; gap: 34px; padding-block: 46px 30px; }
.legal-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-block-end: 20px; }
.legal-tab {
  padding: 9px 15px; border-radius: 999px; text-decoration: none;
  border: 1px solid var(--line); background: var(--card); color: var(--txt2);
  font-size: 13.5px; font-weight: 700; transition: all .16s ease;
}
.legal-tab:hover { border-color: var(--txt2); }
.legal-tab.is-current { background: var(--cta-bg); color: var(--cta-txt); border-color: var(--cta-bg); }
.legal-rail ol { list-style: none; padding: 0; margin: 0; display: grid; gap: 2px; }
.legal-rail a {
  display: block; padding: 8px 12px; border-radius: 10px;
  color: var(--txt2); text-decoration: none; font-size: 13.5px;
  border-inline-start: 2px solid var(--line);
  transition: color .16s ease, border-color .16s ease, background .16s ease;
}
.legal-rail a:hover { color: var(--txt); border-inline-start-color: #FFC529; background: var(--card); }
.legal-body { max-width: 68ch; }
.legal-meta { color: var(--txt2); font-size: 13.5px; margin-block: 8px 22px; }
.legal-draft {
  display: inline-block; padding: 3px 9px; border-radius: 999px;
  background: var(--pillbg); color: var(--txt2);
  font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
}
.legal-summary {
  background: rgba(255, 197, 41, .14); border: 1px solid rgba(255, 197, 41, .4);
  border-radius: 18px; padding: 18px 20px; margin-block-end: 30px;
}
.summary-label {
  display: block; font-size: 10.5px; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; color: var(--zest-deep, #8A6400);
  margin-block-end: 6px;
}
.legal-summary p { margin: 0; font-size: 15px; }
.legal-section { margin-block-end: 26px; }
.legal-section h2 { font-size: 18px; font-weight: 800; margin: 0 0 8px; }
.legal-section p { margin: 0; color: var(--txt2); font-size: 15px; line-height: 1.65; }
.legal-todo { font-style: italic; opacity: .7; }

@media (min-width: 860px) {
  .legal-wrap { grid-template-columns: 250px 1fr; align-items: start; }
  .legal-side { position: sticky; inset-block-start: 90px; }
  .reach { grid-template-columns: 1fr 1fr; }
}
