/* ═══════════════════════════════════════════════════════════════════════════
   Jordan Clemons Coaching
   Generated by the Frontend Wireframe Engine, Phase 4
   DNA hash: 32d80d98074c

   Axes:
     typography  variable-optical-expressive   Fraunces + Figtree
     components  slide-underline               rules, never boxes
     layout      alternating-full-contained    flat bands at hard lines
     hero        hover-reactive-field          the relationship constellation
     button      fill-slide-left               zero radius, horizontal fill
     imagery     text-dominant-typographic     + duotone portraits
     animation   hover-magnetic-cursor         16px fade up, 450ms, 60ms stagger
     spacing     airy
     color       color-blocking-alternating-solids
     navigation  progress-bar-header
     texture     geometric-overlay             constellation lattice, low opacity

   Do not edit by hand. Regenerate through the engine.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Tokens ──────────────────────────────────────────────────────────────── */
:root {
  /* Brand palette. Locked by the client, palette_intent: logo. */
  --ink:         #071A12;   /* near black green, primary text on light        */
  --forest:      #0D2E22;   /* primary brand green, dark surfaces             */
  --moss:        #17493A;   /* secondary green, cards on dark, borders        */
  --link:        #0A66C2;   /* accent on LIGHT grounds only. 5.13:1 on paper. */
  --link-bright: #4FA8E8;   /* accent on DARK grounds only. 5.66:1 on forest. */
  --sage:        #B9CFC5;   /* dividers, secondary text on dark. 8.94:1.      */
  --paper:       #F5F3EE;   /* primary light background, never pure white     */
  --bone:        #E9E5DC;   /* secondary warm neutral, alternating bands      */
  --gold:        #C8862F;   /* the opportunity colour. DARK GROUNDS ONLY:     */
                            /* 4.83:1 on forest, but only 2.74:1 on paper.    */
  --gold-bright: #DBA451;   /* gold for SMALL TEXT on dark, and for anything   */
                            /* sitting over the photograph. 6.60:1 on forest   */
                            /* against the base gold's 4.83, which leaves no   */
                            /* headroom once a photo is behind it. This is the */
                            /* same accommodation the brief mandates for blue  */
                            /* (--link vs --link-bright), applied to gold.     */
  --alarm:       #A8321F;   /* form errors, harmonised with the palette       */

  /* SURFACE tokens. These name a painted surface, never a text colour, and
     nothing anywhere is allowed to redefine them. The colour tokens above are
     ROLE tokens and dark sections DO redefine those, so a background painted
     with a role token resolves against the redefinition made on the very same
     element. That is not theoretical: `.ftr { background: var(--ink) }` beside
     `--ink: var(--paper)` rendered the entire footer paper on sage at 1.48:1.
     Backgrounds use these. Text uses the roles. Never the other way round. */
  --surface-ink:    #071A12;
  --surface-forest: #0D2E22;
  --surface-moss:   #17493A;
  --surface-paper:  #F5F3EE;
  --surface-bone:   #E9E5DC;

  /* Typography. Cinzel carries display, and it is the same Roman inscriptional
     face the JC monogram is cut from, so the mark and the headlines are one
     voice rather than two. Source Sans 3 carries everything that is read and
     every control: quiet, highly legible, and deliberately not quirky.

     Cinzel is a display face and gets clumsy small, so it is held to h1, h2 and
     the large display moments. h3, h4 and all UI run in the body face. */
  /* Headlines are Archivo, the same family as the JORDAN CLEMONS wordmark, so
     the logo and the page speak one voice. Set at 800 and slightly expanded so
     the headline still leads the wordmark rather than matching it.
     Cinzel is kept for the big display FIGURES only, which is the thread back
     to the JC badge, and it is the face the badge is cut from. */
  --font-display: 'Archivo', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-figure:  'Cinzel', 'Iowan Old Style', Georgia, serif;
  --font-body:    'Source Sans 3', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --scale-ratio: 1.333;
  --heading-weight: 800;
  --heading-tracking: -0.028em;
  --heading-leading: 1.0;
  --body-size: 17.5px;
  --body-leading: 1.66;
  --measure: 68ch;               /* the brief's 62 to 72 character comfort */

  /* Fluid display scale. clamp() so nothing is sized off the viewport alone. */
  --t-hero:    clamp(2.05rem, 1.15rem + 4vw, 4rem);
  --t-section: clamp(1.6rem, 0.95rem + 2.2vw, 2.4rem);  /* >=12px under the h1 */
  --t-sub:     clamp(1.45rem, 1.1rem + 1.5vw, 2.2rem);
  --t-card:    clamp(1.25rem, 1.05rem + 0.85vw, 1.65rem);
  --t-lede:    clamp(1.06rem, 1.0rem + 0.4vw, 1.28rem);
  --t-stat:    clamp(2.6rem, 1.6rem + 4.2vw, 4.6rem);

  /* Spacing. airy. */
  --band:        clamp(5rem, 3.4rem + 6.4vw, 9.5rem);
  --band-tight:  clamp(3.4rem, 2.4rem + 4vw, 6rem);
  --gutter:      clamp(1.25rem, 0.6rem + 2.6vw, 3rem);
  --stack:       clamp(1.5rem, 1.2rem + 1.1vw, 2.4rem);
  --max:         1220px;
  /* Distance from the viewport edge to the content rail. Full-bleed sections
     use this so their content starts on the same vertical as every contained
     section. The split band was starting at the gutter, 63px left of
     everything else on the page. */
  --rail-inset:  max(var(--gutter), calc((100vw - var(--max)) / 2));
  --max-narrow:  820px;

  /* Motion. hover-magnetic-cursor, plus the craft floor's strong easings. */
  --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-entrance: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --dur-entrance: 450ms;
  --dur-hover: 250ms;
  --dur-control: 160ms;
  --stagger: 60ms;
  --rise: 16px;
}

/* ── Reset ───────────────────────────────────────────────────────────────── */
/* Written by hand because the Tailwind Play CDN injects its preflight AFTER
   this file at runtime, which would reset every heading to inherit. Preflight
   is disabled in each page's head; this replaces the parts we need. */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body, h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
ul, ol { list-style: none; padding: 0; }
img, svg, video, canvas { display: block; max-width: 100%; }
img, video { height: auto; }
img[width][height] { height: auto; }   /* a width with no height renders at the attribute height */
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; }
table { border-collapse: collapse; }
/* Only fill an SVG that has not said otherwise. A presentation attribute
   (fill="none" on a line-art icon) loses to ANY css rule, including a
   zero-specificity :where(), so a blanket fill here turns every stroked icon
   into a solid blob. Measured: all six resource icons rendered as filled
   squares before this. */
:where(svg:not([fill])) { fill: currentColor; }

/* ── Base ────────────────────────────────────────────────────────────────── */
body {
  font-family: var(--font-body);
  font-size: var(--body-size);
  line-height: var(--body-leading);
  font-weight: 400;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;             /* safety net; the real fix is per element */
}

/* Scoped to `body` deliberately, giving these rules specificity (0,0,2).
   The Tailwind Play CDN injects its preflight into the document AFTER this
   stylesheet, and preflight resets h1..h6 to `font-size: inherit;
   font-weight: inherit` at specificity (0,0,1). Bare `h2 {}` here loses that
   fight on source order and every heading on the page collapses to body size.
   Measured: h2 and h3 rendered at 17px/400 before this change. */
body h1, body h2 {
  font-family: var(--font-display);
  font-weight: var(--heading-weight);
  line-height: var(--heading-leading);
  letter-spacing: var(--heading-tracking);
  font-variation-settings: 'wdth' 115;
  text-wrap: balance;
}
body h1 { font-size: var(--t-hero); }
body h2 { font-size: var(--t-section); }
body h3 {
  font-family: var(--font-body); font-weight: 700;
  font-size: var(--t-card); line-height: 1.2; letter-spacing: -0.015em;
}
body h4 {
  font-family: var(--font-body); font-weight: 700;
  font-size: 1.12rem; line-height: 1.3; letter-spacing: -0.01em;
}

p { max-width: var(--measure); }
p + p { margin-top: 1.05em; }

/* A measure in ch resolves against the element's OWN font. Never put a ch
   max-width on a wrapper that contains display type. */
.lede { font-size: var(--t-lede); line-height: 1.62; max-width: 60ch; }

.skip {
  position: absolute; left: 0; top: 0; z-index: 999;
  background: var(--ink); color: var(--paper);
  padding: 0.85rem 1.4rem; font-weight: 600;
  transform: translateY(-120%);
  transition: transform 180ms var(--ease-out);
}
.skip:focus { transform: translateY(0); }

/* ── Focus. Visible on every interactive element, both grounds. ──────────── */
:focus-visible {
  outline: 3px solid var(--link);
  outline-offset: 3px;
  border-radius: 0;
}
.band--dark :focus-visible, .drawer :focus-visible, .navmenu :focus-visible {
  outline-color: var(--link-bright);
}

/* ═══════════════════════════════════════════════════════════════════════════
   LAYOUT: alternating-full-contained
   Every section is a full-bleed band of one flat colour. Transitions happen at
   hard horizontal lines. Content sits in a contained rail inside the band.
   ═══════════════════════════════════════════════════════════════════════════ */
.band { padding-block: var(--band); position: relative; }
/* Alternating band height. Three consecutive sections at the same padding
   reads as one undifferentiated column no matter what is inside them. */
main > section.band:nth-of-type(even) { padding-block: calc(var(--band) * 0.72); }
main > section.band:nth-of-type(3n) { padding-block: calc(var(--band) * 0.88); }
/* Jordan read the offerings-to-flywheel gap as too spacious on a desktop
   screen. Where one band ends and the next begins the two paddings add up, so
   the seam is trimmed from both sides rather than shrinking any band alone. */
main > section.band + section.band { padding-top: calc(var(--band) * 0.58); }
main > section.band:has(+ section.band) { padding-bottom: calc(var(--band) * 0.66); }
.band--tight { padding-block: var(--band-tight); }
.band--paper  { background: var(--surface-paper); color: var(--ink); }
.band--bone   { background: var(--surface-bone);  color: var(--ink); }
.band--forest { background: var(--surface-forest); color: var(--paper); }
.band--ink    { background: var(--surface-ink);   color: var(--paper); }

/* Invert by REDEFINING the tokens, never by colouring descendants. A dark band
   that recolours its children leaks into every nested light card inside it. */
/* Every dark surface redefines the tokens. The hero and the header are dark
   grounds too, and a button that only checked for .band--forest rendered
   forest-on-forest and vanished. */
.band--forest, .band--ink, .hero, .hdr, .claim-is, .navmenu {
  --ink: var(--paper);
  --moss: var(--sage);
  --link: var(--link-bright);
  --rule: rgba(185, 207, 197, 0.30);
  --rule-strong: var(--sage);
  --surface: #123A2C;
  --surface-line: rgba(185, 207, 197, 0.22);
}
.band--paper, .band--bone, .claim-not {
  --rule: rgba(7, 26, 18, 0.16);
  --rule-strong: var(--forest);
  --surface: transparent;
  --surface-line: rgba(7, 26, 18, 0.18);
}

.rail { width: min(100% - (var(--gutter) * 2), var(--max)); margin-inline: auto; }
.rail--narrow { width: min(100% - (var(--gutter) * 2), var(--max-narrow)); margin-inline: auto; }

/* section_rhythm: the composition changes band to band rather than repeating
   one centred column. These are the four postures used across the page. */
.posture-lead    { display: grid; gap: var(--stack); }
.posture-split   { display: grid; gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
.posture-offset  { display: grid; gap: var(--stack); }
@media (min-width: 900px) {
  .posture-split  { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  .posture-split--flip { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .posture-offset { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .posture-offset > .col-main { grid-column: 3 / span 8; }
  .posture-offset > .col-wide { grid-column: 2 / span 10; }
  .posture-offset > .col-left { grid-column: 1 / span 7; }
  .posture-offset > .col-right{ grid-column: 6 / span 7; }
}

/* ── The rule. The logo's single stroke, carried into the page. ──────────── */
/* Never place a short horizontal rule to the LEFT of a label: at that size and
   position it reads as an em dash, which the copy rules forbid outright. */
.rule { border: 0; height: 2px; background: var(--rule-strong); width: 100%; }
.rule--sage { background: var(--sage); }
.section-rule { border: 0; height: 1px; background: var(--rule); margin: 0; }

/* custom-divider mutation: the band seam is the mark's stroke, not a gap. */
.seam { position: relative; height: 0; }
.seam::after {
  content: ""; position: absolute; left: 50%; top: 0;
  width: min(100% - (var(--gutter) * 2), var(--max));
  transform: translateX(-50%);
  height: 3px; background: var(--sage);
}

.eyebrow {
  font-family: var(--font-body);
  font-size: 0.8rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--moss); margin-bottom: 1rem;
}

/* ═══════════════════════════════════════════════════════════════════════════
   COMPONENTS: slide-underline
   Zero radius. No shadows. Single rules in place of four sided boxes.
   ═══════════════════════════════════════════════════════════════════════════ */
.card {
  background: var(--surface);
  border: 0;
  border-top: 2px solid var(--rule-strong);
  border-radius: 0;
  box-shadow: none;
  padding: clamp(1.6rem, 1.1rem + 1.6vw, 2.6rem) 0 clamp(1.6rem, 1.1rem + 1.4vw, 2.4rem);
  position: relative;
}
.card--inset { padding-inline: clamp(1.4rem, 1rem + 1.4vw, 2.2rem); }
.card--filled { background: var(--surface-forest); color: var(--paper);
  --ink: var(--paper); --moss: var(--sage); --link: var(--link-bright);
  --rule: rgba(185,207,197,0.30); --rule-strong: var(--sage);
  border-top-color: var(--gold);
}
/* The card's own sliding rule: the top rule extends on hover. */
.card::after {
  content: ""; position: absolute; left: 0; top: -2px; height: 2px; width: 0;
  background: var(--link); transition: width 320ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .card:hover::after, .card:focus-within::after { width: 100%; }
}

/* Client feedback: a single baseline rule did not read as a form field, on
   the contact page and on the free checklist's email capture. Inputs are now
   a real box: full border, background lifted off the page. */
.field { display: grid; gap: 0.35rem; margin-bottom: 0.9rem; }
.field > label { font-size: 0.9rem; font-weight: 600; letter-spacing: 0.01em; }
.field > .hint { font-size: 0.82rem; color: var(--moss); }
input[type="text"], input[type="email"], input[type="tel"], input[type="url"],
input[type="number"], select, textarea {
  width: 100%;
  /* Never inherit. A .card--filled remaps --ink to --paper, so an inherited
     colour puts near-white text in a near-white field. */
  color: #071A12;
  background: var(--surface);
  border: 1px solid var(--surface-line);
  border-radius: 0;
  padding: 0.65rem 0.8rem;
  transition: border-color var(--dur-hover) var(--ease-out);
}
.band--forest input[type="text"], .band--forest input[type="email"], .band--forest input[type="tel"],
.band--forest input[type="url"], .band--forest input[type="number"], .band--forest select, .band--forest textarea,
.band--ink input[type="text"], .band--ink input[type="email"], .band--ink input[type="tel"],
.band--ink input[type="url"], .band--ink input[type="number"], .band--ink select, .band--ink textarea {
  background: rgba(245,243,238,0.06); border-color: rgba(185,207,197,0.34);
  color: #F5F3EE;
}
/* Client feedback (v14): the checklist email field on a light band read as
   nothing at all. The base rule's background is `var(--surface)`, which is
   `transparent` on band--paper/band--bone, INCLUDING inside a .card--filled
   sitting on one of those bands: the card paints its own dark background as
   a literal declaration, but never redefines --surface, so the field's
   background stayed transparent and its border stayed the near-black 18%
   used for light grounds. On the paper/bone form fields it blended into the
   page; on a filled dark card it was a near-invisible dark-on-dark box.
   Both need a background that reads as lifted regardless of what card, if
   any, they sit inside. */
.band--paper input[type="text"], .band--paper input[type="email"], .band--paper input[type="tel"],
.band--paper input[type="url"], .band--paper input[type="number"], .band--paper select, .band--paper textarea {
  background: #FFFFFF; border-color: rgba(7,26,18,0.3);
  color: #071A12;
}
.band--bone input[type="text"], .band--bone input[type="email"], .band--bone input[type="tel"],
.band--bone input[type="url"], .band--bone input[type="number"], .band--bone select, .band--bone textarea {
  background: var(--surface-paper); border-color: rgba(7,26,18,0.3);
  color: #071A12;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--link);
  outline: 2px solid transparent; outline-offset: 2px;
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--link); outline-offset: 3px;
}
select { appearance: none; padding-right: 2rem;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 0.7rem center, right 0.35rem center;
  background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; }
textarea { resize: vertical; min-height: 5.5rem; }
.field.is-invalid input, .field.is-invalid select, .field.is-invalid textarea {
  border-color: var(--alarm);
}
.err { color: var(--alarm); font-size: 0.85rem; font-weight: 600; min-height: 1.2em; }
.err:empty { display: none; }
.band--forest .err, .band--ink .err, .drawer .err { color: #F0A79A; }

/* ═══════════════════════════════════════════════════════════════════════════
   CONTACT WAYS
   Client feedback (v14): "Just talk to me" was a bare list of three links.
   Icons, one per channel, on the rule pattern the rest of the site already
   uses instead of a box.
   ═══════════════════════════════════════════════════════════════════════════ */
.contact-ways { margin-top: 2rem; display: grid; gap: 1.3rem; }
.contact-way { display: flex; align-items: flex-start; gap: 1rem;
  padding-top: 1.1rem; border-top: 1px solid var(--rule); }
.contact-way:first-child { border-top: 0; padding-top: 0; }
.contact-way__icon { width: 26px; height: 26px; flex: none; color: var(--link); margin-top: .15rem; }
.contact-way__label { font-size: .8rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--moss); margin-bottom: .25rem; }
.contact-way .link-slide { font-size: 1.05rem; font-weight: 600; }

/* ═══════════════════════════════════════════════════════════════════════════
   BUTTONS: fill-slide-left
   Zero radius, uppercase, the fill travels horizontally, matching the
   direction the component system's underline slides.
   ═══════════════════════════════════════════════════════════════════════════ */
.btn {
  --btn-ink: var(--paper);
  --btn-bg: var(--forest);
  position: relative; display: inline-flex; align-items: center; gap: 0.6rem;
  isolation: isolate;
  font-family: var(--font-body);
  font-size: 0.875rem; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  padding: 1.05rem 1.9rem;
  border-radius: 0; border: 2px solid var(--btn-bg);
  background: var(--btn-bg); color: var(--btn-ink);
  text-decoration: none; overflow: hidden;
  transition: transform var(--dur-control) var(--ease-out),
              color var(--dur-hover) var(--ease-out),
              border-color var(--dur-hover) var(--ease-out);
}
.btn::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--btn-ink);
  transform: translateX(-101%);
  transition: transform 320ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover::before { transform: translateX(0); }
  .btn:hover { color: var(--btn-bg); }
}
.btn:active { transform: scale(0.97); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.btn:disabled::before { transform: translateX(-101%); }

.band--forest .btn, .band--ink .btn, .drawer .btn,
.hero .btn, .hdr .btn, .claim-is .btn, .navmenu .btn, .card--filled .btn {
  --btn-bg: var(--paper); --btn-ink: var(--forest);
}
.btn--ghost {
  background: transparent; color: var(--btn-bg); border-color: var(--btn-bg);
}
.band--forest .btn--ghost, .band--ink .btn--ghost, .drawer .btn--ghost,
.hero .btn--ghost, .card--filled .btn--ghost {
  color: var(--paper); border-color: var(--sage); --btn-ink: var(--paper); --btn-bg: var(--forest);
}
.band--forest .btn--ghost::before, .band--ink .btn--ghost::before,
.hero .btn--ghost::before, .card--filled .btn--ghost::before { background: var(--paper); }
@media (hover: hover) and (pointer: fine) {
  .band--forest .btn--ghost:hover, .band--ink .btn--ghost:hover,
  .hero .btn--ghost:hover, .card--filled .btn--ghost:hover { color: var(--forest); }
}

/* Tertiary: the sliding underline itself. */
.link-slide {
  position: relative; display: inline-flex; align-items: center; gap: 0.5rem;
  font-weight: 600; text-decoration: none; color: var(--link);
  padding: 0.35rem 0.1rem;
}
.link-slide::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 2px; width: 0;
  background: currentColor; transition: width var(--dur-hover) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) { .link-slide:hover::after { width: 100%; } }
.link-slide:focus-visible::after { width: 100%; }
.link-slide .arw { transition: transform var(--dur-hover) var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .link-slide:hover .arw { transform: translateX(5px); } }

/* Body prose links stay underlined so colour is never the only signal. */
.prose a:not(.btn) { color: var(--link); text-underline-offset: 3px; text-decoration-thickness: 1px; }

/* ═══════════════════════════════════════════════════════════════════════════
   NAVIGATION: progress-bar-header
   ═══════════════════════════════════════════════════════════════════════════ */
.hdr {
  position: fixed; inset-block-start: 0; inset-inline: 0; z-index: 90;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background var(--dur-hover) var(--ease-out),
              border-color var(--dur-hover) var(--ease-out);
}
.hdr[data-stuck="true"] {
  background: rgba(13, 46, 34, 0.86);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border-bottom-color: rgba(185, 207, 197, 0.24);
}
/* Pages that open on a light band need the header legible from the first pixel. */
.hdr--solid { background: rgba(13, 46, 34, 0.94); border-bottom-color: rgba(185,207,197,0.24); }
.hdr__bar { height: 2px; background: var(--link-bright); width: var(--progress, 0%); }
.hdr__in {
  width: min(100% - (var(--gutter) * 2), var(--max)); margin-inline: auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; padding-block: 0.85rem;
}
.hdr__logo { display: flex; align-items: center; text-decoration: none; }
.hdr__logo img { height: 50px; width: auto; }
.navlinks { display: none; }
@media (min-width: 1000px) {
  .navlinks { display: flex; align-items: center; gap: clamp(1.2rem, 2.2vw, 2.4rem); }
}
.navlinks a {
  position: relative; text-decoration: none; color: var(--paper);
  font-size: 0.95rem; font-weight: 500; padding: 0.4rem 0.1rem;
  white-space: nowrap;
}
.navlinks a::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 2px; width: 0;
  background: var(--link-bright); transition: width var(--dur-hover) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) { .navlinks a:hover::after { width: 100%; } }
.navlinks a:focus-visible::after, .navlinks a[aria-current="page"]::after { width: 100%; }
/* A short CTA label is one unit to a reader. Without nowrap it broke to
   "LET'S / TALK" at 375px, which made the fixed header taller than the hero's
   top padding and put a paper-white button directly on top of the kicker. */
.hdr .btn { padding: 0.78rem 1.35rem; font-size: 0.8rem; white-space: nowrap; }
/* On a phone the CTA stays and the LOGO gives way instead: the lockup drops to
   the badge alone, which is what the small-size masters were drawn for. The
   call to action is the point of the header, so it is the last thing to go. */
.hdr__logo-badge, .hdr__logo-text { display: none; }
/* Set in the wordmark's own face at the lockup's own proportions, so the two
   renderings read as one logo. The badge keeps the serif initials and the sage
   rule; the name outside it stays sans. */
.hdr__logo-text {
  flex-direction: column; line-height: 1;
  gap: 0.28em; font-family: var(--font-body);
}
.hdr__logo-text b {
  font-family: var(--font-display); font-weight: 600;
  font-size: 0.86rem; letter-spacing: -0.005em; color: var(--paper);
  font-variation-settings: 'wdth' 100;
}
.hdr__logo-text i {
  font-style: normal; font-weight: 600; font-size: 0.5rem;
  letter-spacing: 0.3em; text-transform: uppercase; color: var(--sage);
}
@media (max-width: 619px) {
  /* Dropping to the badge alone left the header reading as two initials with
     no name on it. The full lockup cannot simply be scaled down: its
     descriptor is 15 units on a 96 badge, which is under 6px at any height a
     header can carry. So the badge stays vector and the name is set as live
     text, where the two lines can be sized independently and stay legible. */
  .hdr__logo-full { display: none; }
  .hdr__logo-badge { display: block; height: 36px; width: 36px; }
  .hdr__logo-text { display: flex; }
  .hdr__logo { gap: 0.52rem; }
  .hdr .btn--linkedin { padding: 0.55rem 1rem; font-size: 0.84rem; }
  .hdr__in { gap: 0.6rem; }
  .burger { padding: 0.7rem 0.25rem; }
}
@media (max-width: 389px) {
  .hdr__logo-badge { height: 32px; width: 32px; }
  .hdr__logo-text b { font-size: 0.78rem; }
  .hdr__logo-text i { font-size: 0.46rem; letter-spacing: 0.22em; }
  .hdr__logo { gap: 0.42rem; }
  .hdr .btn--linkedin { padding: 0.52rem 0.85rem; font-size: 0.8rem; }
  .hdr__in { gap: 0.45rem; }
}

.burger {
  display: inline-flex; flex-direction: column; gap: 5px;
  padding: 0.7rem 0.5rem; color: var(--paper);
}
@media (min-width: 1000px) { .burger { display: none; } }
.burger span { display: block; width: 26px; height: 2px; background: currentColor;
  transition: transform 260ms var(--ease-out), opacity 160ms linear; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Full screen overlay menu. Explicit width AND height: a fixed inset:0 flex
   column collapses to its content height and covers only the top of the page. */
.navmenu {
  position: fixed; top: 0; left: 0;
  width: 100vw; height: 100vh; height: 100dvh;
  display: flex; flex-direction: column; overflow-y: auto;
  background: var(--surface-forest); z-index: 95;
  padding: 6rem var(--gutter) 3rem;
  opacity: 0; visibility: hidden;
  transition: opacity 280ms var(--ease-out), visibility 0s linear 280ms;
}
.navmenu[data-open="true"] { opacity: 1; visibility: visible; transition-delay: 0s; }
.navmenu a {
  color: var(--paper); text-decoration: none;
  font-family: var(--font-display); font-size: clamp(1.9rem, 8vw, 2.9rem);
  font-weight: 700; letter-spacing: -0.02em; line-height: 1.1;
  padding: 0.55rem 0; border-bottom: 1px solid rgba(185,207,197,0.2);
  opacity: 0; transform: translateY(14px);
  transition: opacity 320ms var(--ease-entrance), transform 320ms var(--ease-entrance);
}
.navmenu[data-open="true"] a { opacity: 1; transform: none; }
.navmenu[data-open="true"] a:nth-child(1) { transition-delay: 60ms; }
.navmenu[data-open="true"] a:nth-child(2) { transition-delay: 120ms; }
.navmenu[data-open="true"] a:nth-child(3) { transition-delay: 180ms; }
.navmenu[data-open="true"] a:nth-child(4) { transition-delay: 240ms; }
.navmenu[data-open="true"] a:nth-child(5) { transition-delay: 300ms; }
.navmenu[data-open="true"] a:nth-child(6) { transition-delay: 360ms; }
.navmenu[data-open="true"] a:nth-child(7) { transition-delay: 420ms; }
body[data-lock="true"] { overflow: hidden; }

/* ═══════════════════════════════════════════════════════════════════════════
   HERO: hover-reactive-field
   ═══════════════════════════════════════════════════════════════════════════ */
.hero {
  position: relative; min-height: 100svh; display: flex; align-items: center;
  background: var(--surface-forest); color: var(--paper);
  padding-top: clamp(7rem, 6rem + 4vw, 9rem);   /* header clearance, under the pt-24 cap */
  padding-bottom: clamp(4rem, 3rem + 4vw, 6rem);
  overflow: hidden;
}
.hero__canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
.hero__in { position: relative; z-index: 1; }
.hero h1 { max-width: 16ch; font-size: var(--t-hero); }
.hero__sub { font-size: clamp(1.15rem, 1rem + 0.85vw, 1.6rem); color: var(--sage);
  max-width: 34ch; margin-top: 1.4rem; line-height: 1.45; font-weight: 400; }
.hero__cta { display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(1rem, 2vw, 2rem); margin-top: clamp(2rem, 4vw, 3rem); }
.hero .link-slide { color: var(--link-bright); }

/* The scroll cue is a drifting rule, not the word "scroll". */
.cue { position: absolute; left: 50%; bottom: 1.9rem; z-index: 1;
  width: 1px; height: 46px; background: linear-gradient(var(--sage), transparent);
  transform: translateX(-50%); opacity: 0.75; }
.cue::after { content: ""; position: absolute; left: -1px; top: 0; width: 3px; height: 14px;
  background: var(--sage); animation: cue-drift 2.6s var(--ease-in-out) infinite; }
@keyframes cue-drift { 0% { transform: translateY(0); opacity: 0 }
  30% { opacity: 1 } 100% { transform: translateY(32px); opacity: 0 } }

/* ── geometric-overlay texture: the constellation lattice, very low opacity ─ */
.band--forest.has-lattice::before, .band--ink.has-lattice::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.5;
  background-image: radial-gradient(circle at 12% 18%, rgba(185,207,197,0.10) 0 1.5px, transparent 1.6px),
                    radial-gradient(circle at 64% 42%, rgba(185,207,197,0.09) 0 1.5px, transparent 1.6px),
                    radial-gradient(circle at 33% 77%, rgba(185,207,197,0.08) 0 1.5px, transparent 1.6px),
                    radial-gradient(circle at 88% 82%, rgba(185,207,197,0.07) 0 1.5px, transparent 1.6px);
  background-size: 190px 170px, 260px 220px, 310px 280px, 230px 250px;
}
.band > .rail, .band > .rail--narrow { position: relative; z-index: 1; }

/* ═══════════════════════════════════════════════════════════════════════════
   REVEAL
   Visible by default. The hiding rule is only ever applied by script, and only
   to elements that are genuinely below the fold, so a failure of the script
   can never leave content invisible.
   ═══════════════════════════════════════════════════════════════════════════ */
[data-reveal] { opacity: 1; transform: none; }
html[data-reveal-armed="true"] [data-reveal]:not([data-shown]) {
  opacity: 0; transform: translateY(var(--rise));
}
html[data-reveal-armed="true"] [data-reveal] {
  transition: opacity var(--dur-entrance) var(--ease-entrance),
              transform var(--dur-entrance) var(--ease-entrance);
}
[data-shown] { opacity: 1 !important; transform: none !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   THE OPPORTUNITY PATH
   Scroll progress drives the draw. The page is never pinned.
   ═══════════════════════════════════════════════════════════════════════════ */
.path { margin-top: clamp(2.5rem, 5vw, 4rem); }
.path__track { position: relative; }
.path__line { position: absolute; background: var(--rule); }
.path__fill { position: absolute; background: var(--link); }
.path__stages { display: grid; gap: clamp(1.6rem, 3vw, 2.4rem); }
.stage { position: relative; padding-left: 3.4rem; }
.stage__dot {
  position: absolute; left: 0; top: 0.15rem;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--paper); border: 3px solid var(--rule-strong);
  transition: background var(--dur-hover) var(--ease-out),
              border-color var(--dur-hover) var(--ease-out),
              transform var(--dur-hover) var(--ease-out);
}
.stage[data-active="true"] .stage__dot { background: var(--link); border-color: var(--link); transform: scale(1.12); }
.stage--goal[data-active="true"] .stage__dot { background: var(--gold); border-color: var(--gold); }
.stage__n { font-family: var(--font-display); font-size: 0.95rem; font-weight: 700;
  color: var(--moss); display: block; margin-bottom: 0.3rem; }
.stage h3 { margin-bottom: 0.5rem; }
.stage p { color: var(--moss); max-width: 46ch; }
@media (min-width: 960px) {
  .path__stages { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: clamp(1rem, 2vw, 2rem); }
  .stage { padding-left: 0; padding-top: 3.2rem; }
  .stage__dot { top: 0; left: 0; }
  .path__line { left: 10px; right: 10px; top: 8px; height: 3px; }
  .path__fill { left: 10px; top: 8px; height: 3px; width: var(--path-progress, 0%); }
}
@media (max-width: 959px) {
  .path__line { left: 9px; top: 10px; bottom: 10px; width: 3px; }
  .path__fill { left: 9px; top: 10px; width: 3px; height: var(--path-progress, 0%); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE INTENTIONALITY CHECK
   ═══════════════════════════════════════════════════════════════════════════ */
.quiz { --surface: #123A2C; margin-top: clamp(2rem, 4vw, 3rem); }
.quiz__frame { border-top: 3px solid var(--sage); padding-top: clamp(1.6rem, 3vw, 2.4rem); }
.quiz__meta { display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1.1rem; }
.quiz__count { font-size: 0.82rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--sage); }
.quiz__bar { height: 3px; background: rgba(185,207,197,0.24); margin-bottom: clamp(1.6rem,3vw,2.4rem); }
.quiz__bar i { display: block; height: 100%; background: var(--link-bright);
  width: var(--quiz-progress, 0%); transition: width 320ms var(--ease-out); }
.quiz__q { font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.35rem, 1.05rem + 1.5vw, 2.15rem); line-height: 1.18;
  letter-spacing: -0.015em; max-width: 24ch; min-height: 3.4em; }
.quiz__opts { display: grid; gap: 0.7rem; margin-top: clamp(1.4rem, 3vw, 2rem); }
@media (min-width: 720px) { .quiz__opts { grid-template-columns: repeat(4, 1fr); } }
.opt {
  position: relative; text-align: left; padding: 1rem 1.1rem;
  background: transparent; color: var(--paper);
  border: 0; border-top: 2px solid rgba(185,207,197,0.34);
  font-weight: 600; font-size: 0.98rem;
  transition: color var(--dur-hover) var(--ease-out),
              border-color var(--dur-hover) var(--ease-out),
              transform var(--dur-control) var(--ease-out);
}
.opt::after { content: ""; position: absolute; left: 0; top: -2px; height: 2px; width: 0;
  background: var(--link-bright); transition: width 260ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .opt:hover::after { width: 100%; } }
.opt:active { transform: scale(0.97); }
.opt[aria-pressed="true"]::after, .opt[data-chosen="true"]::after { width: 100%; }
.opt[data-chosen="true"] { color: var(--link-bright); }
.quiz__nav { display: flex; justify-content: space-between; align-items: center;
  gap: 1rem; margin-top: clamp(1.6rem, 3vw, 2.2rem); flex-wrap: wrap; }
.quiz__panel[hidden] { display: none; }

.dial { display: grid; place-items: center; }
.dial svg { width: clamp(160px, 40vw, 220px); height: auto; }
.dial__val { font-family: var(--font-display); font-weight: 800; fill: var(--paper); }
.dial__of { fill: var(--sage); font-family: var(--font-body); font-weight: 600; }
.result__band { font-family: var(--font-display);
  font-size: clamp(1.9rem, 1.3rem + 2.6vw, 3.1rem); font-weight: 800;
  letter-spacing: -0.02em; line-height: 1.08; }

/* ═══════════════════════════════════════════════════════════════════════════
   OFFERINGS
   ═══════════════════════════════════════════════════════════════════════════ */
.offers { display: grid; gap: clamp(1.8rem, 3vw, 2.6rem); margin-top: clamp(2.4rem, 5vw, 3.6rem); }
@media (min-width: 1000px) {
  .offers { grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: stretch; }
  /* Stretch is what lands the three buttons on one baseline while the cards are
     closed, but a grid row is one height for every cell in it, so opening ONE
     disclosure grew all three cards by the height of the opened panel. Measured
     at 627px: the client read it as one card dragging the other two down, which
     is exactly what it was.

     So stretch applies only while everything is closed. The moment any button
     reports expanded, the row stops equalising and each card takes its own
     height, which means an open card grows alone. */
  .offers:has(.disclose__btn[aria-expanded="true"]) { align-items: start; }
}
/* The three cards carry very different amounts of copy (774, 1049 and 1144px
   before this), and one of them is filled, so the shortest card left a hole and
   the filled one read as a floating slab. Cards now share a height and the
   closing group is pushed to the foot, so every "what we cover" row and every
   button lands on the same line. */
.offer { display: flex; flex-direction: column; }
/* Client feedback: these are price boxes and wanted a hover effect, on top
   of the sliding top rule every .card already gets, for a more professional
   feel and clearer mouseover focus. A lift, not a shadow (no shadows on this
   build). Re-flagged on v14: a 6px lift with nothing else changing was too
   subtle to register as "focus" at a glance. The top rule now lights up in
   the accent colour at the same time as the lift, on all three cards
   (including the filled one, which needed its own gold-on-dark version), so
   the hovered card visibly separates from the other two instead of only
   moving slightly. */
.offer { transition: transform var(--dur-hover) var(--ease-out),
  border-top-color var(--dur-hover) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  /* !important, matching the entrance system's own [data-shown] rule (which
     also carries !important): without it, any offer card already marked
     data-shown by the scroll reveal (i.e. every card a visitor has actually
     scrolled to) has its transform pinned to none and the lift never shows,
     even though the border-colour half of this same rule still applies.
     Measured: border-top-color changed on hover, transform stayed "none". */
  .offer:hover, .offer:focus-within { transform: translateY(-8px) !important; border-top-color: var(--link); }
  .offer.card--filled:hover, .offer.card--filled:focus-within { border-top-color: var(--gold-bright); }
}
/* 'Best for' anchors to the closing group, so the extra room in the shorter
   card collects as one block of air after the body copy instead of an odd
   gap above a short line, and the three 'Best for' blocks sit on the same
   rule. */
/* The description now folds away, so the closing group anchors to the first
   disclosure instead of to 'Best for'. Adjacent disclosures collapse their
   margin so the two rows read as one stack of rules, not two loose blocks. */
.offer > .offer__more { margin-top: auto; }
.offer .disclose + .disclose { margin-top: 0; }
/* Client feedback: opening "What this is" left its closing sentence sitting
   right against the next disclosure's rule. That 0 margin is only right for
   two closed rows stacking into one rule; give the rule room once there is
   actual prose above it. */
.offer .offer__more + .disclose { margin-top: 1.2rem; }
.disclose__prose { display: grid; gap: 0.85rem; padding: 0.3rem 0 1.3rem; }
.disclose__prose .offer__for { margin-top: 0; }
/* Two published rates on one line, split by a rule rather than a bullet, and
   set on the same line-height as a single price so the three card headings
   still land on one baseline. */
.offer__price--pair { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.35rem;
  font-size: clamp(1.15rem, 0.95rem + 0.7vw, 1.5rem); }
.offer__price--pair i { font-style: normal; font-family: var(--font-body);
  font-size: 0.88rem; font-weight: 600; letter-spacing: 0; color: var(--moss); }
.offer__price--pair em { width: 2px; align-self: stretch; min-height: 1em;
  background: var(--sage); margin: 0 0.5rem; }
/* One card's label fits a line where the others wrap to two, which offset
   the whole closing group by 23px. A shared minimum height lands every
   button, and therefore every disclosure row above it, on one line. */
.offer .btn { margin-top: 1.4rem; min-height: 5.25rem; }
.offer__note { margin-top: 0.9rem; font-size: 0.86rem; }
.offer__price { font-family: var(--font-display); font-size: clamp(1.6rem,1.2rem + 1.6vw,2.3rem);
  font-weight: 800; letter-spacing: -0.02em; line-height: 1; margin-bottom: 0.45rem; }
/* Client feedback: price moved from the top of the card to the foot, under the
   disclosure, so people read the offer before the number. It stays large and
   bold; the card name takes over the size it used to carry at the top. */
.offer__price--foot { margin-top: 1.6rem; margin-bottom: 0; }
.offer h3 { font-size: clamp(1.6rem,1.2rem + 1.6vw,2.3rem); }
.offer__tag { color: var(--moss); font-weight: 600; margin-bottom: 1rem; }
.offer__for { font-size: 0.94rem; color: var(--moss); margin-top: 1.2rem; }
.offer__for b { color: var(--ink); }
.offer .btn { margin-top: 1.5rem; width: 100%; justify-content: center; text-align: center; }
.pull {
  font-family: var(--font-display); font-weight: 700; font-style: normal;
  font-size: clamp(1.15rem, 1rem + 0.8vw, 1.5rem); line-height: 1.24;
  letter-spacing: -0.025em; border-left: 3px solid var(--gold);
  padding-left: 1.1rem; margin: 1.3rem 0; max-width: 40ch;
}
.tags { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.tag { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  border: 1px solid var(--surface-line); padding: 0.4rem 0.7rem; color: var(--moss); }

/* Disclosure: real height transition, pushing content down. No modal. */
.disclose { margin-top: 1.4rem; border-top: 1px solid var(--rule); }
.disclose__btn { display: flex; width: 100%; align-items: center; justify-content: space-between;
  gap: 1rem; padding: 0.95rem 0; font-weight: 700; font-size: 0.92rem;
  letter-spacing: 0.05em; text-transform: uppercase; text-align: left; }
.disclose__btn .chev { transition: transform 300ms var(--ease-out); flex: none; }
.disclose__btn[aria-expanded="true"] .chev { transform: rotate(180deg); }
.disclose__panel { display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 380ms var(--ease-out); }
.disclose__panel > div { overflow: hidden; }
.disclose__btn[aria-expanded="true"] + .disclose__panel { grid-template-rows: 1fr; }
.disclose ul { display: grid; gap: 0.6rem; padding: 0.3rem 0 1.3rem; }
.disclose li { position: relative; padding-left: 1.5rem; font-size: 0.97rem; line-height: 1.55; }
.disclose li::before { content: ""; position: absolute; left: 0; top: 0.72em;
  width: 10px; height: 2px; background: var(--link); }

/* ═══════════════════════════════════════════════════════════════════════════
   THE FLYWHEEL
   The client's own draft put body copy inside six coloured wedges, which is
   why it needed a drop shadow behind the text to stay readable. Here the copy
   lives outside the ring, so nothing sits over a colour and nothing needs a
   shadow. It runs on ink because gold is a dark-ground colour on this site and
   a light travelling a dark ring is the whole argument made visible.

   The six cards, six badges and the light share one 18 second clock and stay in
   step because they share the duration. Card delays are negative so the
   sequence is already running on first paint. Hovering or focusing any card
   pins the wheel to that stage; leaving resumes it.
   ═══════════════════════════════════════════════════════════════════════════ */
.fly { display: grid; gap: clamp(2rem, 4vw, 3.4rem); margin-top: clamp(2rem, 4vw, 3rem); }
@media (min-width: 1000px) { .fly { grid-template-columns: minmax(0, clamp(420px, 40vw, 640px)) minmax(0, 1fr); align-items: center; } }
/* Client feedback: the intro copy read left-justified against the dark band.
   It now centers on the page. Later feedback: with the wheel and the cards
   stacked, moving the slider hid whichever half you were not looking at.
   The cards now sit to the left of the wheel at desktop widths, both visible
   at once; each fly-card keeps its own left rule internally (rules, not
   boxes). Below 1000px there is only room to stack, wheel first. */
#flywheel .posture-lead { text-align: center; max-width: 54ch; margin-inline: auto; }
@media (min-width: 1000px) {
  #flywheel .fly { grid-template-columns: minmax(0, 1fr) minmax(0, clamp(380px, 36vw, 520px)); align-items: center; }
  #flywheel .fly-cards { order: -1; }
  #flywheel .fly__svg { max-width: 520px; margin-inline: auto; }
}

.fly__svg { width: 100%; height: auto; display: block; overflow: visible;
  max-width: 560px; margin-inline: auto; }

/* The hub copy, as real text, for viewports where the wheel is too small to
   carry it. Above the breakpoint the SVG keeps it and this is hidden. */
.fly__hub-copy { display: none; }
@media (max-width: 999px) {
  .fly__hub-copy { display: block; text-align: center; margin-top: 1.2rem; max-width: 40ch;
    margin-inline: auto; }
  .fly__hub-copy p { color: var(--sage); font-size: 1rem; line-height: 1.55; }
  .fly__hub-copy p + p { margin-top: .8rem; }
  .fly__hub-last { color: var(--gold-bright); font-weight: 700; }
  /* the same words are already in the SVG; only one set should be visible */
  .fly__mid--eye, .fly__mid--say { display: none; }
}
.fly__track { fill: none; stroke: rgba(185,207,197,0.10); stroke-width: 32; }
.fly__segs  { fill: none; stroke: rgba(185,207,197,0.30); stroke-width: 32; }

.fly__spark, .fly__trail {
  fill: none; stroke: var(--link-bright); stroke-width: 32; stroke-linecap: butt;
  animation: fly-travel 18s linear infinite, fly-hue 18s linear infinite;
}
@keyframes fly-hue {
  0%   { stroke: var(--link-bright); }
  38%  { stroke: var(--link-bright); }
  50%  { stroke: var(--gold-bright); }
  88%  { stroke: var(--gold-bright); }
  100% { stroke: var(--link-bright); }
}
.fly__spark { filter: drop-shadow(0 0 14px rgba(219,164,81,0.45)); }
.fly__trail--1 { opacity: 0.34; }
.fly__trail--2 { opacity: 0.14; }
@keyframes fly-travel { to { stroke-dashoffset: -1168.67; } }

.fly__badge { fill: var(--surface-ink, #071A12); stroke: rgba(185,207,197,0.5); stroke-width: 2;
  animation: fly-badge 18s linear infinite calc((var(--i) * 3s) - 18s); }
@keyframes fly-badge {
  0%     { fill: var(--lit); stroke: var(--lit); }
  16.66% { fill: var(--lit); stroke: var(--lit); }
  17.5%  { fill: #071A12; stroke: rgba(185,207,197,0.5); }
  100%   { fill: #071A12; stroke: rgba(185,207,197,0.5); }
}
.fly__num { fill: var(--paper); font-family: var(--font-body); font-weight: 700;
  font-size: 15px; text-anchor: middle; }
.fly__badge[data-on="true"] + .fly__num { fill: #071A12; }
.fly__lab { fill: var(--sage); font-family: var(--font-body); font-weight: 700;
  font-size: 15px; letter-spacing: 0.07em; text-anchor: middle; text-transform: uppercase; }

.fly__mid { text-anchor: middle; fill: var(--paper); font-family: var(--font-body); }
.fly__mid--eye { font-size: 12px; font-weight: 700; letter-spacing: 0.2em; fill: var(--sage); }
.fly__mid--big { font-family: var(--font-display); font-weight: 800; font-size: 34px;
  letter-spacing: -0.02em; }
.fly__mid--say { font-size: 14px; fill: var(--sage); }
.fly__mid--last { fill: var(--gold-bright); font-weight: 700; }
.fly__mid-rule { stroke: var(--gold); stroke-width: 3; }

.fly-cards { display: grid; gap: 0; }
.fly-card { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.2rem 0.9rem;
  padding: 0.85rem 0 0.85rem 1.1rem; border-left: 3px solid rgba(185,207,197,0.22);
  cursor: default; transition: border-left-color 200ms linear, transform 260ms var(--ease-out);
  animation: fly-lit 18s linear infinite calc((var(--i) * 3s) - 18s); }
@keyframes fly-lit {
  0%     { border-left-color: var(--lit); }
  16.66% { border-left-color: var(--lit); }
  17.5%  { border-left-color: rgba(185,207,197,0.22); }
  100%   { border-left-color: rgba(185,207,197,0.22); }
}
.fly-card__n { grid-row: span 2; font-family: var(--font-display); font-weight: 800;
  font-size: 1.15rem; color: var(--lit); font-variant-numeric: tabular-nums; line-height: 1.3; }
.fly-card h3 { font-size: 1.1rem; font-family: var(--font-body); font-weight: 700;
  letter-spacing: 0; color: var(--paper); }
.fly-card p { margin-top: 0.25rem; color: var(--sage); font-size: 1.01rem; line-height: 1.55; max-width: 46ch; }
.fly-card:focus-visible { outline: 2px solid var(--link-bright); outline-offset: 3px; }

/* Pinned: the clock stops everywhere at once and the chosen stage is the only
   thing lit, so the ring and the list can never disagree about which it is. */
.fly[data-pinned="true"] .fly__spark,
.fly[data-pinned="true"] .fly__trail,
.fly[data-pinned="true"] .fly__badge,
.fly[data-pinned="true"] .fly-card { animation-play-state: paused; }
.fly[data-pinned="true"] .fly__trail { opacity: 0; }
.fly[data-pinned="true"] .fly__badge { fill: #071A12; stroke: rgba(185,207,197,0.5); }
.fly[data-pinned="true"] .fly__badge[data-on="true"] { fill: var(--lit); stroke: var(--lit); }
.fly[data-pinned="true"] .fly-card { border-left-color: rgba(185,207,197,0.22); }
.fly[data-pinned="true"] .fly-card[data-on="true"] { border-left-color: var(--lit); transform: translateX(4px); }
.fly[data-pinned="true"] .fly__lab[data-on="true"] { fill: var(--gold-bright); }

/* Nothing here may depend on movement to be understood: at rest every arc,
   every badge and every rule sits lit and all six read at once. */
@media (prefers-reduced-motion: reduce) {
  .fly__spark, .fly__trail { display: none; }
  .fly__segs { stroke: var(--gold); }
  .fly__badge { animation: none; fill: var(--lit); stroke: var(--lit); }
  .fly__num { fill: #071A12; }
  .fly-card { animation: none; border-left-color: var(--lit); transition: none; }
}
@media print {
  .fly__spark, .fly__trail { display: none; }
  .fly__badge, .fly-card { animation: none; }
  .fly-card { border-left-color: var(--gold); break-inside: avoid; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE TIME OBJECTION: routine builder
   ═══════════════════════════════════════════════════════════════════════════ */
/* Client feedback: no visible cue that the slider is draggable, and it was
   easy to lose track of the routine list changing on the right when you
   moved it. The pair is now framed as one card (routine-frame in the
   markup), and the drag hint that used to be screen-reader only is visible
   to everyone. */
.routine-frame { margin-top: clamp(2rem, 4vw, 3rem); }
.slider-wrap { max-width: 640px; }
input[type="range"] { width: 100%; appearance: none; background: transparent; padding: 1rem 0; cursor: grab; }
input[type="range"]:active { cursor: grabbing; }
input[type="range"]::-webkit-slider-runnable-track { height: 3px; background: rgba(185,207,197,0.3); }
input[type="range"]::-moz-range-track { height: 3px; background: rgba(185,207,197,0.3); }
input[type="range"]::-webkit-slider-thumb { appearance: none; width: 26px; height: 26px;
  border-radius: 50%; background: var(--link-bright); margin-top: -11.5px;
  border: 3px solid var(--forest); transition: transform var(--dur-control) var(--ease-out); }
input[type="range"]::-moz-range-thumb { width: 20px; height: 20px; border-radius: 50%;
  background: var(--link-bright); border: 3px solid var(--forest); }
input[type="range"]:active::-webkit-slider-thumb { transform: scale(1.15); }
.ticks { display: flex; justify-content: space-between; font-size: 0.78rem;
  color: var(--sage); font-weight: 600; letter-spacing: 0.04em; }
.budget { font-family: var(--font-display); font-weight: 800; letter-spacing: -0.02em;
  font-size: clamp(2.4rem, 1.6rem + 3.4vw, 4rem); line-height: 1; }
.alloc { display: flex; height: 12px; margin: 1.6rem 0 0.8rem; gap: 2px; }
.alloc i { display: block; transition: flex-grow 380ms var(--ease-out); }
.routine__list { display: grid; gap: 0; margin-top: 1.4rem; }
.routine__item { display: grid; grid-template-columns: auto 1fr; gap: 1rem 1.1rem;
  align-items: baseline; padding: 0.95rem 0; border-top: 1px solid rgba(185,207,197,0.2); }
.routine__item b { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem;
  white-space: nowrap; color: var(--sage); }
.routine__item.is-new { animation: item-in 380ms var(--ease-entrance) both; }
@keyframes item-in { from { opacity: 0; transform: translateY(10px) } to { opacity: 1; transform: none } }

/* ═══════════════════════════════════════════════════════════════════════════
   THIS IS NOT / THIS IS
   ═══════════════════════════════════════════════════════════════════════════ */
.split-claim { display: grid; }
@media (min-width: 940px) { .split-claim { grid-template-columns: 5fr 7fr; } }
/* Client feedback: "This is not" and "This is" render at different heights.
   The two panels had different vertical padding (2.2rem vs 2.6rem clamps),
   so the headings never lined up. Same top and bottom padding on both. */
.claim-not {
  background: var(--surface-bone); color: var(--ink);
  padding: clamp(2.4rem,4.5vw,4rem) clamp(1.5rem,3vw,2.5rem) clamp(2.4rem,4.5vw,4rem) var(--rail-inset);
}
.claim-is {
  background: var(--surface-forest); color: var(--paper);
  padding: clamp(2.4rem,4.5vw,4rem) var(--rail-inset) clamp(2.4rem,4.5vw,4rem) clamp(2rem,4vw,3.4rem);
  --ink: var(--paper); --moss: var(--sage);
}
.claim-not li { padding: 0.85rem 0; font-size: clamp(1rem,0.95rem + 0.3vw,1.15rem);
  color: #5C6660; border-bottom: 1px solid rgba(7,26,18,0.12); }
.claim-not li > span { position: relative; display: inline; }
.claim-not li > span::after {
  content: ""; position: absolute; left: 0; top: 50%;
  height: 2px; background: #6E7570; width: 0;
  transition: width 520ms var(--ease-out);
}
.claim-not li[data-struck="true"] > span::after { width: 100%; }
.claim-is p { font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.5rem, 1.05rem + 2.1vw, 2.6rem); line-height: 1.22;
  letter-spacing: -0.015em; max-width: 22ch; }

/* ═══════════════════════════════════════════════════════════════════════════
   PROOF, STATS, PORTRAIT
   ═══════════════════════════════════════════════════════════════════════════ */
.stats { display: grid; gap: clamp(1.6rem,3vw,2.4rem); margin-top: clamp(2rem,4vw,3rem); }
@media (min-width: 760px) { .stats { grid-template-columns: repeat(3, minmax(0,1fr)); } }
.stat { border-top: 2px solid var(--rule-strong); padding-top: 1.1rem; }
.stat b { display: block; font-family: var(--font-display); font-weight: 800;
  font-size: var(--t-stat); line-height: 0.98; letter-spacing: -0.03em; }
.stat span { display: block; margin-top: 0.7rem; font-size: 0.82rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--moss); max-width: 26ch; }

/* duotone-image mutation: photography enters the colour system rather than
   sitting on top of it. */
.duo { position: relative; overflow: hidden; background: var(--forest); }
.duo img { width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(100%) contrast(1.06) brightness(0.92); mix-blend-mode: luminosity; }
.duo::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(150deg, rgba(23,73,58,0.55), rgba(7,26,18,0.35));
  mix-blend-mode: multiply; }
.portrait { aspect-ratio: 4 / 5; border-top: 3px solid var(--gold); }
.portrait--soft { border-radius: 0; }
.ph {
  display: grid; place-items: center; text-align: center; gap: 0.5rem;
  background: var(--surface-moss); color: var(--sage); min-height: 260px; height: 100%;
  font-size: 0.8rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 1.5rem;
}

.quotes { display: grid; gap: clamp(1.6rem,3vw,2.4rem); margin-top: clamp(2rem,4vw,3rem); }
@media (min-width: 860px) { .quotes { grid-template-columns: repeat(3, minmax(0,1fr)); } }
.quote { border-top: 2px solid var(--rule-strong); padding-top: 1.2rem; }
.quote blockquote { font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.08rem,1rem + 0.5vw,1.32rem); line-height: 1.32; letter-spacing: -0.02em; }
.quote figcaption { margin-top: 1rem; font-size: 0.86rem; color: var(--moss); font-weight: 600; }

/* ═══════════════════════════════════════════════════════════════════════════
   RESOURCES
   ═══════════════════════════════════════════════════════════════════════════ */
/* Six resources: one free, five paid. In a three column grid that leaves a
   single card stranded in the last row beside two empty cells. A six column
   track lets the rows divide evenly instead: the free one takes the full
   width, then three, then two at wider spans. Every row is full. */
.res-grid { display: grid; gap: clamp(1.2rem,2.2vw,1.8rem); margin-top: clamp(2rem,3.4vw,2.6rem); }
@media (min-width: 680px) {
  .res-grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .res--free { grid-column: 1 / -1; }
  .res:nth-last-child(1) { grid-column: 1 / -1; }
}
@media (min-width: 1040px) {
  .res-grid { grid-template-columns: repeat(6, minmax(0,1fr)); align-items: stretch; }
  .res { grid-column: span 2; }
  .res--free { grid-column: 1 / -1; }
  .res:nth-last-child(-n+2):not(.res--free) { grid-column: span 3; }
}
/* With the paid guides held back the checklist is the only card left, and the
   span-3 rule above would leave it stranded in half a row. Equal specificity to
   that rule, so this has to stay below it. */
.res-grid > .res:only-child { grid-column: 1 / -1; }
.res { display: flex; flex-direction: column; }
.res__icon { width: 34px; height: 34px; color: var(--moss); margin-bottom: 0.7rem; }
.res h3 { font-size: clamp(1.1rem, 1rem + 0.5vw, 1.32rem); }
.res > p { font-size: 0.97rem; line-height: 1.5; }
/* The price rode above the button AND inside its label. Once is enough, and
   the button is where it does work. */
.res__price { display: none; }
.res .btn {
  margin-top: auto; align-self: stretch; justify-content: center;
  padding: 0.85rem 1.2rem; min-height: 0;
}
/* The free card runs the full width, so its form sits beside the copy rather
   than under it. */
@media (min-width: 860px) {
  /* The free checklist card carries a rendering of the cover, so the download is
   a thing you can see before you hand over an email. Drawn, not photographed:
   assets are served immutable, and this has to restyle with the palette. */
.dl-cover { display: grid; place-items: center; padding: .4rem 0; }
.dl-cover__page {
  width: min(232px, 100%); aspect-ratio: 8.5 / 11; background: var(--paper);
  color: var(--ink); transform: rotate(-2.2deg); border: 1px solid rgba(7,26,18,.18);
  box-shadow: 0 18px 34px rgba(7,26,18,.34), 0 2px 6px rgba(7,26,18,.22);
  display: flex; flex-direction: column; overflow: hidden;
}
.dl-cover__top { background: var(--forest); color: var(--paper); padding: .85rem .8rem .9rem; }
.dl-cover__eyebrow {
  font-size: .5rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--sage); margin: 0;
}
.dl-cover__title {
  font-family: var(--font-display, inherit); font-size: .98rem; font-weight: 800;
  line-height: 1.05; letter-spacing: -.02em; margin: .38rem 0 0;
}
.dl-cover__sub { font-size: .52rem; line-height: 1.35; color: var(--sage); margin: .4rem 0 0; }
.dl-cover__body { flex: 1; padding: .75rem .8rem; display: flex; flex-direction: column; gap: .42rem; }
.dl-cover__rule { height: 2px; background: rgba(7,26,18,.5); width: 42%; }
.dl-cover__rule--head { width: 58%; }
.dl-cover__line { display: flex; align-items: center; gap: .34rem; }
.dl-cover__line i { width: .42rem; height: .42rem; border: 1px solid rgba(7,26,18,.45); flex: none; }
.dl-cover__line i.is-on { background: var(--link); border-color: var(--link); }
.dl-cover__line b { height: 2px; background: rgba(7,26,18,.2); flex: 1; }
.dl-cover__line b.is-short { flex: 0 0 62%; }
@media (prefers-reduced-motion: reduce) { .dl-cover__page { transform: none; } }

.res--free { display: grid; grid-template-columns: minmax(0,1fr) auto minmax(0,1fr);
    gap: clamp(1.6rem,3vw,3rem); align-items: center; }
  .res--free > form, .res--free > [data-done-panel] { margin-top: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DRAWER
   ═══════════════════════════════════════════════════════════════════════════ */
.scrim { position: fixed; inset: 0; background: rgba(7,26,18,0.62); z-index: 100;
  opacity: 0; visibility: hidden; transition: opacity 300ms var(--ease-out), visibility 0s linear 300ms; }
.scrim[data-open="true"] { opacity: 1; visibility: visible; transition-delay: 0s; }
.drawer {
  position: fixed; top: 0; right: 0; z-index: 101;
  width: min(100vw, 460px); height: 100vh; height: 100dvh;
  display: flex; flex-direction: column; overflow-y: auto;
  background: var(--surface-forest); color: var(--paper);
  --ink: var(--paper); --moss: var(--sage); --link: var(--link-bright);
  --rule: rgba(185,207,197,0.3); --rule-strong: var(--sage);
  --surface-line: rgba(185,207,197,0.28);
  padding: 1.4rem var(--gutter) 2.4rem;
  transform: translateX(101%);
  transition: transform 380ms var(--ease-drawer);
}
.drawer[data-open="true"] { transform: none; }
.drawer h2 { font-size: clamp(1.5rem,1.2rem + 1.2vw,2rem); }
.drawer__close { align-self: flex-end; padding: 0.6rem; color: var(--sage); }
.line-item { display: flex; justify-content: space-between; gap: 1rem;
  padding: 0.9rem 0; border-top: 1px solid var(--rule); }
.line-item__total { border-top: 2px solid var(--sage); font-weight: 700; }
.notice { border-left: 3px solid var(--gold); padding: 0.75rem 0 0.75rem 1rem;
  font-size: 0.9rem; color: var(--sage); margin: 1.2rem 0; }
.notice--err { border-left-color: #F0A79A; color: #F0A79A; }

/* What a form says when it could not deliver. These forms sit on paper, bone,
   ink and forest, so it takes its colours from the band's own tokens rather
   than picking one ground and failing contrast on the other three. */
.form-note { border-left: 3px solid var(--link); padding: 0.7rem 0 0.7rem 1rem;
  margin-top: 1.1rem; font-size: 0.92rem; line-height: 1.5;
  color: var(--ink); max-width: 54ch; }
.form-note:empty { display: none; }
.form-note a { color: inherit; text-decoration: underline; text-underline-offset: 0.18em; }
.form-note--err { border-left-color: var(--alarm); }
.band--forest .form-note--err, .band--ink .form-note--err,
.drawer .form-note--err { border-left-color: #F0A79A; }

/* ── Sessions ────────────────────────────────────────────────────────────── */
.sessions { display: grid; gap: 0; margin-top: clamp(1.6rem,3vw,2.4rem); }
.session { display: grid; gap: 0.9rem 1.6rem; padding: clamp(1.3rem,2.4vw,1.9rem) 0;
  border-top: 1px solid var(--rule); align-items: start; }
@media (min-width: 860px) { .session { grid-template-columns: minmax(0,2fr) minmax(0,4fr) auto; } }
.session__when { font-family: var(--font-display); font-weight: 700; font-size: 1.15rem; letter-spacing: -0.01em; }
.session__meta { font-size: 0.9rem; color: var(--moss); }
.session__copy { display: grid; gap: 0.7rem; max-width: 62ch; }
.session__copy > p { margin: 0; }
.session__hook { font-size: 1.05rem; font-style: italic; }
.session__seats { font-size: 0.84rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.session--full .session__seats { color: var(--moss); }
.session--low .session__seats { color: var(--alarm); }

/* ── Steps ───────────────────────────────────────────────────────────────── */
.steps { display: flex; gap: 0.4rem; margin-bottom: 0.7rem; }
.steps i { flex: 1; height: 3px; background: var(--rule); }
.steps i[data-done="true"] { background: var(--link); }
/* The bar alone told sighted visitors less than the live region told screen
   reader users. This says how far along they are, in words. */
.steps__label { font-size: 0.82rem; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--moss); margin: 0 0 2rem; }
.step[hidden] { display: none; }

/* ── Footer ──────────────────────────────────────────────────────────────── */
.ftr { background: var(--surface-ink); color: var(--paper); padding-block: clamp(2.4rem,3.4vw,3.4rem) 1.4rem;
  --ink: var(--paper); --moss: var(--sage); --link: var(--link-bright);
  --rule: rgba(185,207,197,0.22); --rule-strong: var(--sage); }
.ftr__top { display: grid; gap: clamp(1.6rem,2.6vw,2.4rem); }
@media (min-width: 880px) { .ftr__top { grid-template-columns: minmax(0,4fr) minmax(0,3fr) minmax(0,3fr); } }
.ftr img { height: 52px; width: auto; }
.ftr a { color: var(--sage); text-decoration: none; }
body .ftr .ftr-h { font-family: var(--font-body); font-size: 0.8rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--sage); margin-bottom: 1rem;
  line-height: 1.4; }
.ftr ul { display: grid; gap: 0.28rem; }
/* Footer navigation is a reference, not reading matter: it sits a step below
   body size and loses the generous tap padding the in-page links carry, which
   was making each row 51px tall. */
.ftr ul a, .ftr ul li { font-size: 0.95rem; line-height: 1.5; }
.ftr ul .link-slide { padding: 0.2rem 0.06rem; }
.ftr__base { margin-top: clamp(1.6rem,2.6vw,2.2rem); padding-top: 1.1rem;
  border-top: 1px solid var(--rule); display: flex; flex-wrap: wrap;
  gap: 0.5rem 2rem; justify-content: space-between; font-size: 0.82rem; color: var(--sage); }
.dba { font-size: 0.82rem; color: rgba(185,207,197,0.7); }

.nowrap { white-space: nowrap; }   /* phone numbers and prices only, never sentences */
.sr, input.sr { position: absolute !important; width: 1px !important; height: 1px !important;
  padding: 0 !important; margin: -1px; overflow: hidden; clip: rect(0 0 0 0);
  clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   REDUCED MOTION
   Gentler, not zero: colour and opacity stay, movement goes.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* Scroll-driven and looping rules are not duration based. Null them. */
  .cue::after { animation: none !important; opacity: 1; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
  .claim-not li::after { width: 100% !important; }
  .routine__item.is-new { animation: none !important; }
}

@media print {
  .hdr, .navmenu, .scrim, .drawer, .cue, .hero__canvas { display: none !important; }
  body { background: #fff; color: #000; font-size: 12pt; }
  .band { padding-block: 1.2rem; background: #fff !important; color: #000 !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE DIAGNOSTIC FRONT DOOR
   The assessment is the hero. A visitor answers question one within about two
   seconds of landing, and the whole page below then rebuilds around the score.
   Everything here degrades: with no script the hero is a normal headline hero
   and every section below reads at its default, complete state.
   ═══════════════════════════════════════════════════════════════════════════ */
.hero--front { min-height: 100svh; align-items: center; }
.hero__grid { display: grid; gap: clamp(2rem, 4vw, 3.4rem); align-items: center; width: 100%; }
@media (min-width: 1020px) {
  .hero__grid { grid-template-columns: minmax(0, 47fr) minmax(0, 53fr); gap: clamp(2.5rem, 5vw, 5rem); }
}
.hero--front h1 { font-size: clamp(1.85rem, 1.05rem + 2.8vw, 3.2rem); max-width: 24ch; }
/* Three separate lines rather than one block, with a gap the leading alone
   could not give. Each arrives a beat after the one above it. */
.hero--front h1 .hl { display: block; }
.hero--front h1 .hl + .hl { margin-top: clamp(.28rem, .5vw, .62rem); }
@media (prefers-reduced-motion: no-preference) {
  .hero--front h1 .hl { animation: hl-in 900ms cubic-bezier(.22,.61,.36,1) backwards; }
  .hero--front h1 .hl:nth-child(1) { animation-delay: 120ms; }
  .hero--front h1 .hl:nth-child(2) { animation-delay: 420ms; }
  .hero--front h1 .hl:nth-child(3) { animation-delay: 720ms; }
}
@keyframes hl-in { from { opacity: 0; transform: translateY(.42em); } to { opacity: 1; transform: none; } }
.hero__kick {
  font-family: var(--font-body); font-weight: 700;
  margin-bottom: 0.6rem;
  /* 19.2px at 700 clears WCAG's large-text threshold (18.66px bold), where the
     floor is 3:1. Measured over the photograph it lands at 3.68, which is
     comfortable. At the old 15px it needed 4.5 and failed at 2.33. It is the
     brand line, so more prominence is the right answer anyway. */
  font-size: 1.2rem; line-height: 1.25;
  letter-spacing: 0.005em; color: var(--link-bright); margin-bottom: 0.9rem;
}
.hero--front .hero__sub { font-size: clamp(1rem, .95rem + 0.38vw, 1.15rem); max-width: 44ch;
  margin-top: 0.75rem; line-height: 1.5; }

/* The instrument itself. */
.qcard {
  background: rgba(7, 26, 18, 0.72);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 0; border-top: 4px solid var(--gold);
  padding: clamp(1.5rem, 1.1rem + 1.7vw, 2.4rem);
}
.qcard__top { display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 0.9rem; }
.qcard__step { font-size: 0.76rem; font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--gold-bright); }
.qcard__free { font-size: 0.76rem; font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--sage); }
.qcard__bar { display: flex; gap: 3px; margin-bottom: clamp(1.2rem, 2.4vw, 1.8rem); }
.qcard__bar i { flex: 1; height: 4px; background: rgba(185, 207, 197, 0.22);
  transition: background 260ms var(--ease-out); }
.qcard__bar i[data-on="true"] { background: var(--link-bright); }
.qcard__q {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.18rem, 1rem + 1.05vw, 1.72rem); line-height: 1.16;
  letter-spacing: -0.03em; min-height: 4.1em;
}
.qcard__opts { display: grid; gap: 0.5rem; margin-top: clamp(1.2rem, 2.4vw, 1.7rem); }
@media (min-width: 560px) { .qcard__opts { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1020px) and (min-height: 760px) { .qcard__opts { grid-template-columns: repeat(4, 1fr); } }
.qopt {
  position: relative; text-align: left; padding: 0.85rem 0.9rem;
  color: var(--paper); background: rgba(185, 207, 197, 0.07);
  border: 0; border-top: 2px solid rgba(185, 207, 197, 0.5);
  font-weight: 600; font-size: 0.95rem; letter-spacing: -0.005em;
  transition: color 200ms var(--ease-out), transform var(--dur-control) var(--ease-out);
}
.qopt::after { content: ""; position: absolute; left: 0; top: -2px; height: 2px; width: 0;
  background: var(--link-bright); transition: width 240ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .qopt:hover::after { width: 100%; }
  .qopt:hover { color: var(--link-bright); background: rgba(185, 207, 197, 0.13); }
}
.qopt:active { transform: scale(0.97); }
.qopt[data-chosen="true"]::after { width: 100%; }
.qopt[data-chosen="true"] { color: var(--link-bright); }
.qcard__foot { display: flex; justify-content: space-between; align-items: center;
  gap: 1rem; flex-wrap: wrap; margin-top: clamp(1.1rem, 2.2vw, 1.5rem); }
.qcard__note { font-size: 0.8rem; color: var(--sage); }
.qback { font-size: 0.85rem; font-weight: 600; color: var(--sage); padding: 0.4rem 0.1rem; }
.qback:disabled { opacity: 0.4; cursor: not-allowed; }

/* ── The result band. Absent entirely until there is a result. ───────────── */
#result { display: none; }
html[data-quiz-done="true"] #result { display: block; }
.result__grid { display: grid; gap: clamp(2rem, 4vw, 3.4rem); align-items: start; }
@media (min-width: 940px) { .result__grid { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); } }
.result__name { font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2.1rem, 1.4rem + 2.9vw, 3.6rem); letter-spacing: -0.035em; line-height: 0.98; }
.gaps { display: grid; gap: 0; margin-top: 1.6rem; }
.gaps li { display: grid; grid-template-columns: auto 1fr; gap: 0.9rem;
  padding: 0.85rem 0; border-top: 1px solid var(--rule); align-items: baseline; }
.gaps b { font-family: var(--font-display); font-weight: 800; color: var(--gold); font-size: 0.95rem; }

/* ── The recommendation flag, written onto the matching offer card ───────── */
.flag { display: none; }
.offer[data-recommended="true"] .flag {
  display: inline-block; background: var(--gold); color: var(--ink);
  font-size: 0.72rem; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 0.4rem 0.7rem; margin-bottom: 0.9rem;
}
.offer[data-recommended="true"] { border-top-color: var(--gold); border-top-width: 4px; }

/* ── Real photography ───────────────────────────────────────────────────── */
.photo { position: relative; overflow: hidden; background: var(--surface-forest); }
.photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* A grade, not a filter. He stays a real person: slightly cooled, shadows
   pulled toward the brand green, highlights left alone. */
.photo--graded img { filter: saturate(0.72) contrast(1.06); }
.photo--graded::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(155deg, rgba(13, 46, 34, 0.34), rgba(7, 26, 18, 0.10) 55%, rgba(200, 134, 47, 0.10));
  mix-blend-mode: multiply;
}
.photo--tall { aspect-ratio: 4 / 5; }
.photo--wide { aspect-ratio: 3 / 2; }
.photo--rule { border-top: 4px solid var(--gold); }
figure.photo figcaption { position: absolute; left: 0; right: 0; bottom: 0;
  padding: 2.4rem 1.2rem 1rem; font-size: 0.82rem; color: var(--paper); font-weight: 500;
  background: linear-gradient(transparent, rgba(7, 26, 18, 0.88)); }

/* Halo, not a scrim: density goes onto the glyphs so the picture survives. */
.on-photo { text-shadow: 0 1px 2px rgba(7,26,18,.9), 0 2px 14px rgba(7,26,18,.7); }

/* ── Bricolage is a wide face. Buttons need a touch more room. ──────────── */
.btn { letter-spacing: 0.05em; }

/* ── Proof strip. Real figures, above the fold, where a funnel needs them. ─ */
.provebar { border-top: 1px solid rgba(185,207,197,.24); margin-top: 0;
  padding-top: 1rem; display: flex; flex-wrap: wrap; gap: 0.6rem clamp(1.4rem,3vw,3rem); }
.provebar li { display: flex; align-items: baseline; gap: .5rem; font-size: .84rem; color: var(--sage); }
.provebar b { font-family: var(--font-display); font-weight: 800; font-size: 1.2rem;
  letter-spacing: -.03em; color: var(--paper); }
/* Client feedback: label the hero metrics as his own results and center the
   whole strip instead of leaving it to read as an unattributed stat block. */
.provebar-wrap { text-align: center; border-top: 1px solid rgba(185,207,197,.24);
  padding-top: .85rem; }
.provebar--nolead { border-top: 0; }
.provebar-wrap .provebar { justify-content: center; }
.provebar__kicker { font-size: .68rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--sage); margin-bottom: .5rem; max-width: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   TONE: LIGHTER
   The page is already 69% light by scroll height, so weight was never the
   page, it was the entry: a full dark hero followed immediately by a dark
   result band, with no tonal or chromatic relief inside either.

   This lifts the entry without moving the palette ratio. Green still carries
   the brand by area; blue is promoted from a link colour to a structural one,
   which is a different job, not a bigger share.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1. Land on light straight after the assessment. */
html[data-tone="light"] #result.band--ink {
  background: var(--surface-paper); color: var(--ink);
  --ink: #071A12; --moss: #17493A; --link: #0A66C2;
  --rule: rgba(7,26,18,0.16); --rule-strong: var(--forest);
  --surface: transparent; --surface-line: rgba(7,26,18,0.18);
}
html[data-tone="light"] #result .qcard__step { color: #8A5E1F; }   /* gold, AA on paper */
html[data-tone="light"] #result .dial__val { fill: var(--forest); }
html[data-tone="light"] #result .dial__of { fill: var(--moss); }
html[data-tone="light"] #result .dial svg circle:first-of-type { stroke: rgba(7,26,18,.13); }
html[data-tone="light"] #result [data-r="ring"] { stroke: #0A66C2; }
html[data-tone="light"] #result .card--inset { background: var(--surface-bone); }
html[data-tone="light"] #result .lede,
html[data-tone="light"] #result .card--inset p { color: var(--moss) !important; }
html[data-tone="light"] #result .gaps b { color: #8A5E1F; }
html[data-tone="light"] #result [data-q="restart"] { color: var(--moss) !important; }
html[data-tone="light"] #result .card--inset h3 { color: var(--ink); }
/* The opt-in label inherited sage, which is a dark-ground colour, onto the
   paper the result band actually lands on: 1.48:1. */
html[data-tone="light"] #result .optin { color: var(--moss); }

/* 2. A static tonal lift inside the dark surfaces, derived from the brand.
      Nothing moves: a drifting gradient is the 2021 generative-tool tell. */
html[data-tone="light"] .hero,
html[data-tone="light"] .band--forest {
  background-image: linear-gradient(168deg, #0B2A1F 0%, #0D2E22 42%, #143A2C 100%);
}
html[data-tone="light"] .band--ink {
  background-image: linear-gradient(172deg, #071A12 0%, #0C2519 100%);
}

/* 3. Blue as structure. It marks progress, position and state, which is a
      different job from decoration and reads as engineering rather than brand. */
html[data-tone="light"] .qcard { border-top-color: var(--link-bright); }
html[data-tone="light"] .seam::after { background: var(--link-bright); }
html[data-tone="light"] .band--paper .stat,
html[data-tone="light"] .band--bone .stat { border-top-color: var(--link); }
html[data-tone="light"] .card:not(.card--filled) { border-top-color: var(--link); }
html[data-tone="light"] .quote { border-top-color: var(--link); }
html[data-tone="light"] .provebar b { color: var(--link-bright); }
html[data-tone="light"] .hero__kick { color: var(--link-bright); }
/* The result band is a .band--ink whose tone is overridden to light, so the
   dark-ground button rule still matched and rendered paper on paper. Buttons
   follow the surface they are actually on, never the class they inherit. */
html[data-tone="light"] #result .btn {
  --btn-bg: var(--surface-forest); --btn-ink: var(--surface-paper);
}
html[data-tone="light"] #result .btn--ghost {
  color: var(--surface-forest); border-color: var(--surface-forest);
}
html[data-tone="light"] #result .btn--ghost::before { background: var(--surface-forest); }

/* ── The figures keep Cinzel ──────────────────────────────────────────────
   44%, $530K, #12, the score dial, the price on each card. These are the
   moments a serif earns, and they are the thread back to the JC badge. */
.stat b, .budget, .offer__price, .dial__val, .result__name {
  font-family: var(--font-figure); font-weight: 700; letter-spacing: -0.004em;
}
.navmenu a { font-family: var(--font-display); font-weight: 800; letter-spacing: -0.028em; }
/* Read, not looked at. Cinzel small caps at length is a wall. */
.qcard__q, .claim-is p, .pull, .quote blockquote, .hero__sub {
  font-family: var(--font-body); font-weight: 600; letter-spacing: -0.012em;
}
.qcard__q { font-weight: 700; line-height: 1.24; }
.claim-is p { font-weight: 600; line-height: 1.28; }
.pull, .quote blockquote { font-weight: 600; }
/* Cinzel has no true lowercase personality at small sizes, so anything under
   about 20px stays in the body face. */
.session__when, .routine__item b, .stage__n { font-family: var(--font-body); font-weight: 700; }
body h1, body h2 { font-variation-settings: 'wdth' 115; }
.eyebrow, .hero__kick, .qcard__step, .quiz__count { font-family: var(--font-body); }

/* ═══════════════════════════════════════════════════════════════════════════
   HERO, REBUILT AROUND A PERSON
   Three rejections told the same story: a flat colour field with a dark panel
   on it is two boxes, and no amount of repainting fixes a composition problem.
   A practice whose argument is "relationships first" should open on a human
   being, not on a rectangle.

   Jordan bleeds off the right and bottom edges, so nothing in the hero has
   four sides. The network grows out of him. The assessment sits on the ground
   under a single rule rather than inside a card.
   ═══════════════════════════════════════════════════════════════════════════ */
.hero--person {
  min-height: 100svh; display: flex; align-items: stretch;
  padding: 0; overflow: hidden; position: relative;
  background: var(--surface-forest);
}
.hero__photo {
  position: absolute; inset: 0 0 0 auto;
  width: min(66%, 1080px); z-index: 0; pointer-events: none;
}
.hero__photo img {
  width: 100%; height: 100%; object-fit: cover; object-position: 42% 18%;
  /* Graded, not duotoned. He stays a real person: desaturated toward the
     palette, lifted rather than crushed, so the picture ADDS luminance to a
     composition that was reading heavy. */
  filter: saturate(0.55) contrast(1.04) brightness(1.06);
}
/* The left edge dissolves into the ground, so the photograph has no seam and
   the headline always sits on solid colour. Extended 3px past the container's
   own left edge (not the container itself, which would rescale the photo) so
   a compositor antialiasing seam at that boundary has nothing to catch on. */
.hero__photo::after {
  content: ""; position: absolute; inset: 0 0 0 -3px;
  background:
    linear-gradient(90deg, var(--surface-forest) 0%, rgba(13,46,34,.96) 14%,
                    rgba(13,46,34,.74) 32%, rgba(13,46,34,.34) 58%,
                    rgba(13,46,34,.08) 84%, rgba(13,46,34,.02) 100%),
    linear-gradient(0deg, var(--surface-forest) 0%, rgba(13,46,34,.35) 22%, transparent 55%),
    linear-gradient(180deg, rgba(13,46,34,.65) 0%, transparent 28%);
}
@media (max-width: 900px) {
  /* The photograph takes the lower two thirds rather than sitting behind
     everything. Text and picture stop fighting for the same pixels, so the
     veil can come almost entirely off and Jordan reads at full strength. */
  .hero__photo {
    inset: auto 0 0 0; width: 100%; height: 82%; opacity: 1; overflow: hidden;
  }
  /* The container is taller than the source's aspect, so object-fit had no
     vertical crop left to work with and object-position did nothing: the whole
     portrait was pinned to the top of the box, putting his head back against
     the headline. Insetting the image inside the taller container keeps the
     long fade AND drops him. The exposed strip above is under the opaque part
     of the gradient, so it is never seen. */
  .hero__photo img {
    position: absolute; inset: 15% 0 0 0;
    width: 100%; height: 85%; object-fit: cover; object-position: 50% 6%;
    /* The visible seam was never the scrim, it was the TOP EDGE OF THE IMAGE.
       The image begins 15% into the container, where the scrim is still
       near-opaque forest. A few percent of a bright sky is only a few levels of
       luminance, but against near-black green a few levels resolve as a ruled
       line. Fading the picture's own alpha in removes the edge entirely.

       The ramp is short on purpose. His hairline sits about 6% into the
       picture, so a long fade spends itself on his head rather than on the sky
       above it: the first version cleared at 33%, which left the mask at 0.06
       across his hair while the scrim was still 0.90, and the two compounded
       into a green haze over his face. Eleven percent puts the whole blend in
       the sky and hands his head over clear. */
    -webkit-mask-image: linear-gradient(180deg,
      rgba(0,0,0,0)    0%,   rgba(0,0,0,0.02) 1.0%, rgba(0,0,0,0.07) 2.0%,
      rgba(0,0,0,0.15) 2.8%, rgba(0,0,0,0.27) 3.6%, rgba(0,0,0,0.42) 4.4%,
      rgba(0,0,0,0.58) 5.2%, rgba(0,0,0,0.73) 6.0%, rgba(0,0,0,0.85) 6.8%,
      rgba(0,0,0,0.93) 7.6%, rgba(0,0,0,0.975) 8.6%, rgba(0,0,0,0.995) 9.8%,
      #000 11%);
            mask-image: linear-gradient(180deg,
      rgba(0,0,0,0)    0%,   rgba(0,0,0,0.02) 1.0%, rgba(0,0,0,0.07) 2.0%,
      rgba(0,0,0,0.15) 2.8%, rgba(0,0,0,0.27) 3.6%, rgba(0,0,0,0.42) 4.4%,
      rgba(0,0,0,0.58) 5.2%, rgba(0,0,0,0.73) 6.0%, rgba(0,0,0,0.85) 6.8%,
      rgba(0,0,0,0.93) 7.6%, rgba(0,0,0,0.975) 8.6%, rgba(0,0,0,0.995) 9.8%,
      #000 11%);
  }
  .hero__photo::after {
    background:
      /* Opaque only across the strip above the picture, where it is painting
         forest on forest and cannot be seen, then off almost immediately. It is
         clear by 28% of the container, which is above his forehead. */
      linear-gradient(180deg,
        var(--surface-forest) 0%,
        rgba(13,46,34,.999) 14%,
        rgba(13,46,34,.99)  15.5%,
        rgba(13,46,34,.95)  16.6%,
        rgba(13,46,34,.88)  17.6%,
        rgba(13,46,34,.78)  18.6%,
        rgba(13,46,34,.66)  19.6%,
        rgba(13,46,34,.54)  20.6%,
        rgba(13,46,34,.43)  21.6%,
        rgba(13,46,34,.33)  22.6%,
        rgba(13,46,34,.25)  23.6%,
        rgba(13,46,34,.18)  24.6%,
        rgba(13,46,34,.125) 25.7%,
        rgba(13,46,34,.085) 26.8%,
        rgba(13,46,34,.055) 28.0%,
        rgba(13,46,34,.033) 29.4%,
        rgba(13,46,34,.018) 31.0%,
        rgba(13,46,34,.008) 33.0%,
        rgba(13,46,34,.002) 35.5%,
        rgba(13,46,34,0)    38%,
        rgba(13,46,34,0)    84%,
        rgba(13,46,34,.02)  92%,
        rgba(13,46,34,.05)  100%);
  }
}
.hero__in--person {
  position: relative; z-index: 2;              /* width comes from .rail */
  display: flex; flex-direction: column; justify-content: center;
  gap: clamp(0.7rem, 1.4vw, 1.25rem);
  padding-block: clamp(6.2rem, 5rem + 3vw, 6.6rem) clamp(1rem, 1.8vw, 1.6rem);
}
.hero__copy { max-width: min(100%, 40rem); }
@media (min-width: 901px) { .hero__copy { max-width: 50%; } }

/* The assessment on the ground: one rule, no box. */
.ask {
  position: relative; border-top: 0;
  padding-top: clamp(0.9rem, 1.6vw, 1.3rem);
}
.ask::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg,
    var(--link-bright) 0%, var(--link-bright) 38%,
    rgba(79, 168, 232, 0.45) 55%, rgba(79, 168, 232, 0.12) 70%, transparent 82%);
}
@media (max-width: 900px) {
  /* Stacked, so the photograph is behind everything and the rule can run. */
  .ask::before { background: linear-gradient(90deg,
    var(--link-bright) 0%, var(--link-bright) 72%, rgba(79,168,232,.3) 92%, transparent 100%); }
}
.ask__top { display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 0.7rem; }
.ask__grid { display: grid; gap: clamp(1rem, 2.4vw, 2.4rem); align-items: start; }
@media (min-width: 860px) { .ask__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.ask .qcard__q { min-height: 0; margin-bottom: 0;
  font-size: clamp(1.05rem, 0.95rem + 0.7vw, 1.45rem); }
.ask .qcard__opts { margin-top: 0; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 560px) { .ask .qcard__opts { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 860px) { .ask .qcard__opts { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1200px) { .ask .qcard__opts { grid-template-columns: repeat(4, 1fr); } }
.ask .qopt { background: rgba(7,26,18,.42); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
@media (hover: hover) and (pointer: fine) {
  .ask .qopt:hover { background: rgba(7,26,18,.62); }
}
/* Client feedback: "a lot going on" here, with the trust badge floating on
   its own axis above and the Back button and privacy line stranded in a
   flex row that matched neither column. Back now sits under the question,
   the privacy line under the responses: content and responses each carry
   their own footnote instead of sharing one lopsided strip. */
.ask__grid .qback { margin-top: clamp(1rem, 2.4vw, 1.6rem); }

/* Type over a photograph carries its own density, so the picture survives. */
.hero--person h1, .hero--person .hero__sub, .hero--person .hero__kick,
.hero--person .qcard__q, .hero--person .provebar b, .hero--person .provebar li,
.hero--person .qcard__step, .hero--person .qcard__free, .hero--person .link-slide {
  text-shadow: 0 1px 2px rgba(7,26,18,.62), 0 2px 18px rgba(7,26,18,.5);
}
.hero--person .hero__kick, .hero--person .qcard__step,
.hero--person .ask__label, .hero--person .ask__title, .hero--person .ask__how {
  text-shadow: 0 1px 2px rgba(7,26,18,.9), 0 0 12px rgba(7,26,18,.85),
               0 0 26px rgba(7,26,18,.7);
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE ASSESSMENT, ANNOUNCED
   It was legible but anonymous: nothing named it, nothing invited an answer,
   and the four options read as labels in a grid rather than controls. A module
   that is the front door of the whole funnel has to say what it is.
   ═══════════════════════════════════════════════════════════════════════════ */
.ask__label {
  display: flex; align-items: center; gap: 0.7rem;
  font-family: var(--font-body); font-weight: 700;
  font-size: 0.78rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold-bright); margin-bottom: 0.55rem;
}
.ask__label::before {
  content: ""; width: 26px; height: 26px; flex: none; border-radius: 50%;
  border: 2px solid var(--gold-bright);
  background:
    linear-gradient(var(--gold-bright), var(--gold-bright)) center/9px 2px no-repeat,
    linear-gradient(var(--gold-bright), var(--gold-bright)) center/2px 9px no-repeat;
}
.ask__title {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.35rem, 1.1rem + 1.1vw, 2rem); line-height: 1.1;
  letter-spacing: -0.004em; margin-bottom: 0.35rem;
}
.ask__how {
  font-size: 0.92rem; font-weight: 600; color: var(--sage);
  margin-bottom: 0.55rem;
}
/* The step count rides alongside the bar rather than above it: same
   information, one row instead of two, which is 24px of fold back. */
.ask__prog { display: flex; align-items: center; gap: 0.9rem; margin-bottom: clamp(.9rem, 1.8vw, 1.4rem); }
@media (min-width: 860px) { .ask__prog { max-width: 52%; } }
.ask__prog .qcard__bar { flex: 1; margin-bottom: 0; }
.ask__prog .qcard__step { flex: none; white-space: nowrap; order: -1; }

/* Options that look like controls. A marker that fills, a real hover lift, and
   a left rule that runs on selection. */
.qopt { display: flex; align-items: center; gap: 0.6rem; cursor: pointer; }
.qopt__dot {
  flex: none; width: 17px; height: 17px; border-radius: 50%;
  border: 2px solid rgba(185, 207, 197, 0.62);
  position: relative;
  transition: border-color 200ms var(--ease-out), background 200ms var(--ease-out);
}
.qopt__dot::after {
  content: ""; position: absolute; inset: 3px; border-radius: 50%;
  background: var(--link-bright); transform: scale(0);
  transition: transform 200ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .qopt:hover .qopt__dot { border-color: var(--link-bright); }
}
.qopt[data-chosen="true"] .qopt__dot { border-color: var(--link-bright); }
.qopt[data-chosen="true"] .qopt__dot::after { transform: scale(1); }

/* The progress bar reads as progress: the current step is called out. */
.qcard__bar i[data-now="true"] {
  background: var(--gold-bright);
}

/* Anchor landing clearance. Without this an in-page link puts its target's
   heading directly under the fixed header. */
:target, [id] { scroll-margin-top: clamp(5.5rem, 5rem + 2vw, 7rem); }

/* ═══════════════════════════════════════════════════════════════════════════
   THE ASSESSMENT AS ITS OWN BAND
   Inside the hero it was camouflaged: dark type language on a dark ground,
   competing with a photograph. It now sits on warm bone, immediately below,
   which is the strongest break available in the palette and makes it read as
   an instrument rather than more hero.

   Gold cannot come with it. Gold is 2.42:1 on bone, which fails even the
   non-text floor, so blue carries the accent here exactly as the palette rules
   require on a light ground.
   ═══════════════════════════════════════════════════════════════════════════ */
.band--bone .ask, .band--paper .ask { border-top: 0; padding-top: 0; }
.band--bone .ask::before, .band--paper .ask::before { display: none; }

/* Client feedback (v15): "not liking that" on the v14 pass. The framed card,
   the fully-bordered Back button and the per-option filled pills all broke
   this site's own stated component rule -- rules, never boxes, no shadows
   -- which is exactly the "square boxes, standard look" failure this DNA
   exists to avoid (see rules-not-boxes). Reworked as an actual segmented
   control: the four answers sit on ONE shared hairline instead of four
   separate bordered/filled pills, dimmed until hovered or chosen, and the
   chosen one gets full colour plus a 2px rule that slides in under it --
   the exact mechanism .navlinks a and .link-slide already use everywhere
   else on the site, reused rather than reinvented. The Back control drops
   its box for the same sliding-underline treatment. */
/* An author display value beats the hidden attribute's UA rule, so Back
   stayed on screen for question one where there is nothing to go back to.
   Needs to out-specify the band rule below, not just precede it. */
.band--bone .qback[hidden], .band--paper .qback[hidden], .qback[hidden] { display: none; }
.band--bone .qback, .band--paper .qback {
  display: inline-flex; align-items: center; gap: 0.5rem;
  color: var(--moss); font-weight: 600; padding: 0.3rem 0.1rem;
  border-bottom: 2px solid transparent;
  transition: color var(--dur-hover) var(--ease-out), border-color var(--dur-hover) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .band--bone .qback:not(:disabled):hover, .band--paper .qback:not(:disabled):hover {
    color: var(--link); border-color: var(--link);
  }
}

/* Answers have to look like answers. The previous treatment removed the fill,
   the border and the marker, leaving four words in a row that read as a table
   header rather than four choices. */
.band--bone .qcard__opts--rules, .band--paper .qcard__opts--rules {
  border-top: 0;
  display: grid; gap: 0.7rem; margin-top: 0.9rem;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 720px) {
  .band--bone .qcard__opts--rules, .band--paper .qcard__opts--rules {
    grid-template-columns: 1fr;
  }
}
.band--bone .qcard__opts--rules .qopt, .band--paper .qcard__opts--rules .qopt {
  background: var(--paper);
  border: 1px solid rgba(7, 26, 18, 0.22);
  color: var(--ink);
  padding: 0.95rem 1rem;
  min-height: 56px;
}
/* The marker is the thing that says "pick one", so it comes back. */
.qcard__opts--rules .qopt__dot { display: block; }
/* A filled selected state replaces the sliding hairline. */
.qcard__opts--rules .qopt::after { display: none; }

/* Never to Consistently is an ordered scale; the marker weight says so before
   the labels are read. */
.qcard__opts--rules .qopt[data-level="1"] .qopt__dot { border-color: rgba(7, 26, 18, 0.26); }
.qcard__opts--rules .qopt[data-level="2"] .qopt__dot { border-color: rgba(7, 26, 18, 0.42); }
.qcard__opts--rules .qopt[data-level="3"] .qopt__dot { border-color: rgba(7, 26, 18, 0.60); }
.qcard__opts--rules .qopt[data-level="4"] .qopt__dot { border-color: rgba(7, 26, 18, 0.80); }

.qcard__opts--rules .qopt:focus-visible { outline: 3px solid var(--link); outline-offset: 2px; }

@media (hover: hover) and (pointer: fine) {
  .band--bone .qcard__opts--rules .qopt:hover, .band--paper .qcard__opts--rules .qopt:hover {
    color: var(--ink); background: #fff; border-color: var(--link);
    transform: translateY(-1px);
  }
  .band--bone .qcard__opts--rules .qopt:hover .qopt__dot,
  .band--paper .qcard__opts--rules .qopt:hover .qopt__dot { border-color: var(--link); }
}

.band--bone .qcard__opts--rules .qopt[data-chosen="true"],
.band--paper .qcard__opts--rules .qopt[data-chosen="true"] {
  background: var(--forest); border-color: var(--forest); color: var(--paper);
}
.band--bone .qcard__opts--rules .qopt[data-chosen="true"] .qopt__dot,
.band--paper .qcard__opts--rules .qopt[data-chosen="true"] .qopt__dot { border-color: var(--paper); }
.band--bone .qcard__opts--rules .qopt[data-chosen="true"] .qopt__dot::after,
.band--paper .qcard__opts--rules .qopt[data-chosen="true"] .qopt__dot::after {
  background: var(--paper); transform: scale(1);
}

/* One column. The question and its answers belong in the same eyeline. */
.ask--solo { max-width: 64ch; }
.ask--solo .qcard__q { margin-top: 1.4rem; }
.qcard__hint { font-size: 0.82rem; color: var(--moss); margin-top: 0.9rem; }
.qcard__hint kbd {
  font: inherit; font-weight: 600; background: rgba(7, 26, 18, 0.07);
  border: 1px solid rgba(7, 26, 18, 0.18); border-radius: 3px; padding: 0.05em 0.4em;
}
.ask--solo .qcard__foot { margin-top: 1.5rem; }

/* The progress line stays what it already was -- flat rule segments, not
   boxes -- just slightly more present now that it is the only progress cue
   left once the framing card is gone. */
.qcard__bar--steps { gap: 4px; }
.qcard__bar--steps i { height: 5px; }

.band--bone .ask__label, .band--paper .ask__label { color: var(--moss); }
.band--bone .ask__label::before, .band--paper .ask__label::before {
  border-color: var(--moss);
  background:
    linear-gradient(var(--moss), var(--moss)) center/9px 2px no-repeat,
    linear-gradient(var(--moss), var(--moss)) center/2px 9px no-repeat;
}
.band--bone .ask__title, .band--paper .ask__title { color: var(--ink); }
.band--bone .qcard__free, .band--paper .qcard__free { color: var(--moss); }
.band--bone .qcard__step, .band--paper .qcard__step { color: var(--link); }
.band--bone .ask__how, .band--paper .ask__how { color: var(--moss); }
.band--bone .qcard__q, .band--paper .qcard__q { color: var(--ink); }
.band--bone .qback, .band--paper .qback { color: var(--moss); }

.band--bone .qcard__bar, .band--paper .qcard__bar { background: transparent; }
.band--bone .qcard__bar i, .band--paper .qcard__bar i { background: rgba(7, 26, 18, 0.14); }
.band--bone .qcard__bar i[data-on="true"], .band--paper .qcard__bar i[data-on="true"] { background: var(--link); }
.band--bone .qcard__bar i[data-now="true"], .band--paper .qcard__bar i[data-now="true"] { background: var(--forest); }

.band--bone .qopt, .band--paper .qopt {
  color: var(--ink); background: var(--surface-paper);
  border-top: 2px solid rgba(7, 26, 18, 0.22);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
.band--bone .qopt__dot, .band--paper .qopt__dot { border-color: rgba(7, 26, 18, 0.42); }
.band--bone .qopt__dot::after, .band--paper .qopt__dot::after { background: var(--link); }
.band--bone .qopt::after, .band--paper .qopt::after { background: var(--link); }
@media (hover: hover) and (pointer: fine) {
  .band--bone .qopt:hover, .band--paper .qopt:hover { color: var(--link); background: #fff; }
  .band--bone .qopt:hover .qopt__dot, .band--paper .qopt:hover .qopt__dot { border-color: var(--link); }
}
.band--bone .qopt[data-chosen="true"], .band--paper .qopt[data-chosen="true"] { color: var(--link); }
.band--bone .qopt[data-chosen="true"] .qopt__dot,
.band--paper .qopt[data-chosen="true"] .qopt__dot { border-color: var(--link); }

/* Client feedback: the trust badge used to sit in its own grid column,
   floating disconnected from the intro copy under it. One column now, one
   line of read order: label, title, lede, trust line. */
.check__head { max-width: 56ch; }
/* Client feedback: the intro on the left, the questions on the right. Only
   where the right column still holds four answers across without clipping
   "Consistently"; narrower, it stacks as before. */
@media (min-width: 1080px) {
  .check__split {
    display: grid; align-items: start; gap: clamp(2.5rem, 5vw, 5rem);
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  }
  .check__split .ask--solo { max-width: none; }
  .check__split .ask__prog { max-width: none; }
}
.band--bone .ask__grid, .band--paper .ask__grid { margin-top: clamp(1.4rem, 3vw, 2.2rem); }
.band--bone .qcard__q, .band--paper .qcard__q {
  font-size: clamp(1.2rem, 1rem + 1.1vw, 1.85rem); line-height: 1.22;
}

/* The hero gets a real call to action back, now that the form has moved out. */
.hero__cta { display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(1rem, 2.2vw, 1.8rem); margin-top: clamp(1.4rem, 2.6vw, 2rem); }

/* ═══════════════════════════════════════════════════════════════════════════
   THE LINKEDIN BUTTON
   One deliberate quote of the platform this practice is about: LinkedIn's own
   button shape and colour. --link is #0A66C2, which is LinkedIn's brand blue
   exactly, so the quote was already in the palette.

   This is the single pill on the site. Everything else stays zero radius, which
   is what makes this one read as a reference rather than as drift: the
   "Rounded Rectangle Convention" anti-pattern is about UNIFORM soft radii, and
   explicitly permits deliberate mixing with clear visual logic.

   White on #0A66C2 is 5.69:1 and on the hover blue 10.1:1, both AA. The pill
   against the dark header is only 2.58:1, so it carries a hairline ring: a
   component boundary needs 3:1 to be identifiable, and the fill alone misses.
   ═══════════════════════════════════════════════════════════════════════════ */
.btn--linkedin {
  --btn-bg: #0A66C2;
  --btn-ink: #FFFFFF;
  background: #0A66C2; color: #FFFFFF;
  border: 0; border-radius: 999px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.34);
  font-family: var(--font-body);
  font-weight: 600; font-size: 0.92rem;
  letter-spacing: 0.005em; text-transform: none;
  padding: 0.62rem 1.35rem;
  transition: background 180ms var(--ease-out), transform var(--dur-control) var(--ease-out),
              box-shadow 180ms var(--ease-out);
}
.btn--linkedin::before { display: none; }        /* no slide fill on this one */
@media (hover: hover) and (pointer: fine) {
  .btn--linkedin:hover {
    background: #004182; color: #FFFFFF;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.55);
  }
}
.btn--linkedin:active { transform: scale(0.97); }
.btn--linkedin:focus-visible { outline: 3px solid var(--link-bright); outline-offset: 3px; }
.btn--linkedin .in {
  width: 17px; height: 17px; flex: none; margin-right: 0.1rem;
}
/* Header sizing stays compact, but the pill keeps its own shape. */
.hdr .btn--linkedin { padding: 0.62rem 1.3rem; font-size: 0.88rem; }

/* ── Footer, tightened ───────────────────────────────────────────────────── */
.ftr .lede { font-size: 1.02rem; line-height: 1.45; }
.ftr__top > div > p { font-size: 0.92rem; line-height: 1.5; }
body .ftr .ftr-h { margin-bottom: 0.5rem; }

/* ═══════════════════════════════════════════════════════════════════════════
   PHONE CORRECTIONS
   From a real device rather than an emulator. Four faults a width-only check
   never surfaced.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
  /* 1. The proof strip is a flex row that wrapped into a ragged three lines,
        with two figures sharing the middle one. A two column grid with the
        figure over its label stacks evenly at any label length. */
  .provebar {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.85rem 1rem; align-items: start;
  }
  .provebar li { display: block; }
  .provebar b { display: block; font-size: 1.15rem; line-height: 1.15; }
  .provebar li { font-size: 0.78rem; line-height: 1.35; color: var(--sage); }

  /* 2. The arrow is a flex sibling, so when the label wrapped it was pushed to
        the far right of the second line, reading as a stray mark. The
        underline already signals the link. */
  .hero__cta .link-slide .arw { display: none; }
  .hero__cta .link-slide { font-size: 1rem; line-height: 1.4; }

  /* 3. The hero was centring its content inside a full viewport, which left a
        large empty field under the proof strip. It now sits to the top of a
        shorter box and ends where the content ends. */
  /* The hero keeps real height on a phone so the photograph has somewhere to
     live below the copy. Collapsing it to content height cropped Jordan to
     a band between his hairline and his chin. */
  .hero--person { min-height: 94svh; }
  .hero__in--person {
    justify-content: flex-start;
    padding-block: clamp(5.6rem, 5rem + 3vw, 6.4rem) clamp(1.6rem, 4vw, 2.4rem);
  }
  .cue { display: none; }

  /* 4. The primary call to action was nearly full width with a long label. */
  .hero__cta .btn { width: 100%; justify-content: center; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PHONE: PICTURE, NETWORK, HEADLINE
   Three things and nothing else. Every extra line was competing with the
   photograph for the same pixels, which is what forced the heavy veil, and the
   veil is what was hiding Jordan. Strip the hero and both problems go.

   The assessment sits immediately below, so the call to action has not been
   lost, it has been moved one thumb-flick down onto its own band where it is
   legible on a light ground.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
  .hero .provebar,
  .hero .provebar-wrap,
  .hero--person .hero__kick,
  .hero--person .hero__sub,
  .hero--person .hero__cta .link-slide { display: none; }

  /* The call to action returns, sat low over the flat of his sweater rather
     than in the flow under the headline. It is a solid fill, so unlike the
     text it does not need the picture veiled to stay legible, and it sits
     where the thumb is. */
  .hero--person .hero__cta {
    display: flex; margin-top: auto;
    margin-bottom: clamp(4.5rem, 13vw, 7rem);
    padding-inline: 0;
  }
  .hero--person .hero__cta .btn {
    width: 100%; justify-content: center;
    padding: 1.05rem 1.2rem; font-size: 0.86rem;
    box-shadow: 0 10px 40px rgba(7, 26, 18, 0.45);
  }

  /* The headline is the only thing over the picture, so it can be bigger and
     the picture can have most of the screen. */
  .hero--person { min-height: 100svh; }
  .hero--front h1 {
    font-size: clamp(1.72rem, 1rem + 2.8vw, 2.35rem);
    max-width: none; line-height: 1.08; text-wrap: balance;
    text-shadow: 0 1px 3px rgba(7,26,18,.8), 0 0 20px rgba(7,26,18,.6);
  }
  .hero__in--person {
    justify-content: flex-start;
    /* The header measures 80px. This leaves roughly 60px of clear air beneath
       it before the headline starts, rather than the 30px it had. */
    padding-block: clamp(8.5rem, 7rem + 4vw, 9.5rem) 0;
  }
  .hero__copy { position: relative; z-index: 3; }

  .cue { display: none; }   /* the call to action is the prompt now */
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE HERO BETWEEN 701 AND 900: TABLET PORTRAIT
   Every iPad in portrait is 744, 820 or 834 wide, so all of them land in this
   band, and the band had no rules of its own. The photograph took the lower
   82% from the max-width:900 block, while the copy kept the desktop's centred
   vertical alignment and none of the phone's protections. The result: the
   headline sat across his forehead, the skip link ran over his cheek, the
   proof strip wrapped into his beard, and the halo that keeps type readable
   over a picture showed up as grey fog because it was over a face rather than
   over dark green.

   The band is wide enough to keep the kicker, the standfirst and the proof
   strip, which the phone has to drop. It just needs the copy at the top and
   the picture lower, so the two stop sharing pixels.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 701px) and (max-width: 900px) {
  /* The copy needs about 570px and his head needs about 700px of picture. On
     a 1080 tall iPad those do not both fit in one screen, and the loser was
     his face: the hero ended at his mouth. A hero may be taller than the
     viewport. A portrait cut through the middle of a face may not. */
  .hero--person { min-height: max(100svh, 1300px); }

  /* Copy to the top, under the header, instead of centred in the viewport. */
  .hero__in--person {
    justify-content: flex-start;
    padding-block: clamp(6.5rem, 5.4rem + 4vw, 8rem) 0;
  }
  .hero__copy { position: relative; z-index: 3; }

  /* Enough of the frame for the copy to finish before the picture starts. */
  .hero__photo { height: max(40%, calc(100% - 600px)); }

  .hero--front h1 { font-size: clamp(2.1rem, 1.2rem + 3.4vw, 2.9rem); max-width: 18ch; }

  /* Four figures never fitted one row here and wrapped three-then-one. Two
     columns with the number over its label is even at any label length. */
  .provebar {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.9rem 1.6rem; align-items: start; max-width: 34rem;
  }
  .provebar li { display: block; font-size: 0.82rem; line-height: 1.35; color: var(--sage); }
  .provebar b { display: block; font-size: 1.25rem; line-height: 1.15; }

  /* The button and the skip link sat on one line that reached across his
     face. Stacked, both stay on the dark side of the frame. */
  .hero--person .hero__cta { flex-direction: column; align-items: flex-start; gap: 0.9rem; }

  /* With the copy off the picture there is nothing left for a halo to protect,
     and over dark green it only reads as fog. */
  .hero--person h1, .hero--person .hero__kick,
  .hero--person .provebar b, .hero--person .provebar li,
  .hero--person .link-slide { text-shadow: 0 1px 2px rgba(7,26,18,.55); }
}

/* ── The small print ────────────────────────────────────────────────────────
   Three summary blocks on the contact page, and the full policies on their own
   pages. Legal copy is long and unloved, so it gets a real measure and real
   leading rather than being squeezed into a footer. */
.optin { display: flex; gap: .6rem; align-items: flex-start; margin: 1rem 0 1.2rem;
  cursor: pointer; font-size: .88rem; line-height: 1.45; color: var(--sage); max-width: 44ch; }
.optin input { appearance: none; flex: none; width: 1.05rem; height: 1.05rem; margin-top: .12rem;
  border: 2px solid rgba(185,207,197,.5); background: transparent; cursor: pointer; }
.optin input:checked { background: var(--link-bright); border-color: var(--link-bright); }
.optin input:checked::after { content: ""; display: block; width: .28rem; height: .56rem;
  margin: .02rem auto 0; border: solid var(--forest); border-width: 0 2.5px 2.5px 0; transform: rotate(42deg); }
.optin input:focus-visible { outline: 2px solid var(--link-bright); outline-offset: 2px; }

.legal-briefs { display: grid; gap: clamp(1.8rem,3vw,2.6rem); margin-top: clamp(2rem,3.4vw,2.8rem); }
@media (min-width: 900px) { .legal-briefs { grid-template-columns: repeat(3, minmax(0,1fr)); } }
.legal-brief { border-top: 2px solid var(--sage); padding-top: 1.1rem; }
.legal-brief h3 { font-size: 1.12rem; letter-spacing: -0.01em; }
.legal-brief p { margin-top: .7rem; color: var(--sage); font-size: .95rem; line-height: 1.6; max-width: 46ch; }

.legal { max-width: 68ch; }
.legal h2 {
  font-size: clamp(1.15rem, 1.05rem + 0.5vw, 1.4rem); letter-spacing: -0.012em;
  margin-top: clamp(2.2rem,3.4vw,3rem);
}
.legal h2:first-child { margin-top: 0; }
.legal p { margin-top: 1rem; line-height: 1.7; }
.legal p:first-child { margin-top: 0; }
.legal-meta { color: var(--moss); font-size: .92rem; }
.legal-contact { font-weight: 600; }
.legal-list { margin: 1rem 0 0; padding-left: 1.3rem; display: grid; gap: .45rem;
  list-style: disc outside; }
.legal-list li::marker { color: var(--moss); }
.legal-list li { line-height: 1.6; }

/* ═══════════════════════════════════════════════════════════════════════════
   ABOUT HERO
   The left column ran 230px against an 837px portrait, leaving 607px of empty
   green. The credential figures move up into the column, where they belong on
   a page about whether to trust him, and the portrait is capped so the two
   sides are of a similar order.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 900px) {
  .about-hero__grid { align-items: center; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); }
  .about-hero .photo--tall { aspect-ratio: 4 / 5; max-height: 560px; }
}
.provebar--stack {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem 1.6rem; margin-top: clamp(1.8rem, 3vw, 2.6rem);
  border-top: 1px solid rgba(185,207,197,.24); padding-top: 1.3rem;
}
.provebar--stack li { display: block; font-size: 0.84rem; line-height: 1.4; }
.provebar--stack b { display: block; font-size: 1.5rem; line-height: 1.1; margin-bottom: 0.15rem; }


/* The drawer is not a band, so a band-scoped rule never reaches it and the
   base dark colour landed on its own dark field. Any dark surface that is not
   a band needs saying explicitly. */
.drawer input[type="text"], .drawer input[type="email"], .drawer input[type="tel"],
.drawer input[type="url"], .drawer input[type="number"], .drawer select, .drawer textarea {
  background: rgba(245, 243, 238, 0.06); border-color: rgba(185, 207, 197, 0.34);
  color: #F5F3EE;
}
.drawer input::placeholder, .drawer textarea::placeholder { color: rgba(245, 243, 238, 0.58); }

/* Placeholders follow the field, not the ancestor, for the same reason. */
.band--bone input::placeholder, .band--paper input::placeholder,
.band--bone textarea::placeholder, .band--paper textarea::placeholder { color: rgba(7, 26, 18, 0.62); }
.band--forest input::placeholder, .band--ink input::placeholder,
.band--forest textarea::placeholder, .band--ink textarea::placeholder { color: rgba(245, 243, 238, 0.58); }
