/* ==========================================================================
   components.css — buttons, cards, callouts, stats, badges

   Every component is designed to live in both dark and light contexts;
   they read from active-mode tokens (--bg, --text-primary, --border-*)
   and adapt automatically when wrapped in [data-mode="light"].

   Conventions
   - Block: .component
   - Modifier: .component--variant
   - State: native :hover / :focus-visible (no .is-* state classes)
   - Comments above each component describe variants, states, and intent.
   ========================================================================== */


/* ==========================================================================
   1. Buttons

   Three variants:
   - .btn-primary    Solid primary blue. The page's main CTA. Hover lifts +
                     ember glow shadow (rare functional ember use — earned
                     because it signals "high-energy moment").
   - .btn-secondary  Transparent with emphasis border. For secondary CTAs
                     ("See how it works"). No ember.
   - .btn-ghost      No border, hover background tint only. For tertiary
                     in-flow links that should still feel like buttons
                     (FAQ "Read more", footer actions).

   States: rest, hover, focus-visible (keyboard ring), active, disabled.
   Min-height 48px is the WCAG-friendly tap target.
   ========================================================================== */
.btn {
  /* Base — every button variant inherits these. Never used standalone. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 48px;
  padding-inline: var(--space-4);
  padding-block: var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-family: var(--font-display);
  font-size: var(--text-body-md);
  font-weight: var(--weight-medium);
  line-height: 1;
  letter-spacing: var(--tracking-heading-tight);
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition:
    transform var(--motion-fast) var(--easing),
    box-shadow var(--motion-fast) var(--easing),
    background-color var(--motion-fast) var(--easing),
    border-color var(--motion-fast) var(--easing),
    color var(--motion-fast) var(--easing);
}

.btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* Primary CTA — solid blue, ember glow on hover.
   The ember shadow is the only place ember is allowed to register at
   surface-area scale, and only because hover is transient. */
.btn-primary {
  background-color: var(--primary);
  color: var(--text-primary-dark);
  border-color: var(--primary);
}

.btn-primary:hover {
  background-color: var(--primary-hover);
  border-color: var(--primary-hover);
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg), var(--shadow-ember);
  color: var(--text-primary-dark);   /* override base <a:hover> ember color shift */
}

.btn-primary:active {
  transform: translateY(0);
  box-shadow: var(--shadow-md);
}

/* Secondary CTA — quieter; reads as a real button, not a link. */
.btn-secondary {
  background-color: transparent;
  color: var(--text-primary);
  border-color: var(--border-emphasis);
}

.btn-secondary:hover {
  background-color: var(--bg-elevated);
  border-color: var(--text-secondary);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  color: var(--text-primary);
}

.btn-secondary:active {
  transform: translateY(0);
  box-shadow: none;
}

/* Ghost — minimal; for in-flow CTAs that need button affordance but not
   button presence. */
.btn-ghost {
  background-color: transparent;
  color: var(--text-primary);
  border-color: transparent;
  padding-inline: var(--space-3);
}

.btn-ghost:hover {
  background-color: var(--bg-elevated);
  color: var(--text-primary);
}

[data-mode="light"] .btn-ghost:hover {
  /* On light surfaces, --bg-elevated is white; tint slightly darker. */
  background-color: rgba(14, 16, 20, 0.04);
}


/* ==========================================================================
   2. Card

   .card             Resting card — used for capabilities, FAQ items, etc.
   .card--interactive Adds hover lift; signals clickable.
   .card--bordered   Stronger border emphasis (used in dense grids where
                     the subtle border doesn't separate enough).

   Padding scales with content density; default is comfortable. Override
   --card-padding via inline custom property if a section needs to compress.
   ========================================================================== */
.card {
  --card-padding: var(--space-5);
  background-color: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--card-padding);
  color: var(--text-primary);
  transition:
    transform var(--motion-fast) var(--easing),
    box-shadow var(--motion-fast) var(--easing),
    border-color var(--motion-fast) var(--easing);
}

.card--bordered {
  border-color: var(--border-emphasis);
}

.card--interactive {
  cursor: pointer;
}

.card--interactive:hover {
  transform: translateY(-2px);
  border-color: var(--border-emphasis);
  box-shadow: var(--shadow-lg);
}

.card--interactive:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
}


/* ==========================================================================
   3. Big-stat callout

   .stat             Wrapper.
   .stat__number     The big number — Display Lg/XL, weight 500.
                     Ember underline applied here. Size override via the
                     --stat-size custom property:
                     <div class="stat" style="--stat-size: var(--text-display-xl)">
   .stat__label      Muted label below.
   .stat__icon       Optional icon slot (left of number, vertical-aligned).

   Ember underline = the deck slide-11 motif, refined. The number gets the
   underline; the label below stays muted. Don't apply to anything else.
   ========================================================================== */
.stat {
  --stat-size: var(--text-display-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-start;
}

.stat__icon {
  width: 32px;
  height: 32px;
  color: var(--text-tertiary);
  margin-bottom: var(--space-2);
}

.stat__number {
  font-family: var(--font-display);
  font-size: var(--stat-size);
  font-weight: var(--weight-medium);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display-tight);
  color: var(--text-primary);
  /* Ember underline — gradient pseudo-border that doesn't disturb baseline */
  background-image: linear-gradient(to right, var(--ember), var(--ember-glow));
  background-size: 100% 3px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  padding-bottom: var(--space-2);
}

.stat__label {
  font-family: var(--font-body);
  font-size: var(--text-body-md);
  font-weight: var(--weight-regular);
  color: var(--text-secondary);
  line-height: var(--leading-body);
  max-width: 32ch;
}


/* ==========================================================================
   4. Mono badge

   .badge-mono       Small uppercase mono pill. Used for clause IDs
                     (21 CFR 820.30), requirement numbers, citation badges.
                     Subtle background tint reads on dark and light alike.
   ========================================================================== */
.badge-mono {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-caption);
  color: var(--text-secondary);
  background-color: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: 2px var(--space-2);
  white-space: nowrap;
}

[data-mode="light"] .badge-mono {
  background-color: rgba(14, 16, 20, 0.04);
}


/* ==========================================================================
   5. Callout / quote block

   .callout          Verbatim discovery-quote container. Generous padding,
                     ember left-border, mono-font attribution. Used to drop
                     real-buyer language into Problem / Differentiation /
                     FAQ sections.
   .callout__quote   The quote itself — body Lg, primary text.
   .callout__cite    Attribution — mono, secondary text.
                     Use sparingly; a wall of callouts loses the moment.
   ========================================================================== */
.callout {
  background-color: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-left: 3px solid var(--ember);
  border-radius: var(--radius-md);
  padding: var(--space-5) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.callout__quote {
  font-family: var(--font-display);
  font-size: var(--text-body-lg);
  font-weight: var(--weight-regular);
  line-height: var(--leading-body);
  color: var(--text-primary);
  font-style: normal;  /* never italic — feels marketing */
  max-width: 60ch;
}

.callout__cite {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-caption);
  color: var(--text-tertiary);
  font-style: normal;
}

.callout__cite::before {
  content: "— ";
}


/* ==========================================================================
   6. Hero

   Section 1 of the page. Dark-primary. Locked copy: see voice-and-tone.md.

   Layout
   - Full-bleed dark surface, vertical centering, generous padding.
   - A full-bleed SVG PCG network sits behind the content (low opacity,
     pointer-events:none). The .hero__inner container has z-index above it.

   Type rhythm
   - Headline scales: display-md (<640px) → display-lg (640–1023px)
     → display-xl (≥1024px). Weight 500 per design-system discipline.
   - Subhead body-lg, secondary text color, measure capped at 56ch.

   Motion
   - Hero text fades up on initial paint (200ms delay, 400ms duration).
     Reads as "breathing in" rather than popping. Reduced-motion drops
     the transition; the SVG's JS animation pauses separately in pcg.js.
   ========================================================================== */
.hero {
  /* Override the global --space-8 default; hero earns a taller hold. */
  min-height: min(100vh, 900px);
  padding-block: var(--space-9);
  display: flex;
  align-items: center;
  justify-content: center;
}

.hero__pcg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.35;
  pointer-events: none;
  z-index: 0;
  /* PCG nodes/edges use currentColor so the tertiary tone tracks the
     active mode (dark/light). Energy nodes override to ember in JS. */
  color: var(--text-tertiary);
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  text-align: center;
  /* Fade-up entry — 200ms delay so first paint is the empty stage,
     then the content breathes in. Skipped under prefers-reduced-motion. */
  opacity: 0;
  transform: translateY(8px);
  animation: hero-fade-in var(--motion-default) var(--easing) 200ms forwards;
}

@keyframes hero-fade-in {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero__inner {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

.hero__eyebrow {
  margin-bottom: 0;
}

.hero__headline {
  font-size: var(--text-display-md);
  font-weight: var(--weight-medium);
  line-height: var(--leading-display-loose);
  letter-spacing: var(--tracking-display-tight);
  color: var(--text-primary);
  /* Centred + max-width-controlled wrap. At desktop sizes the natural
     break lands the locked copy on roughly three lines; mobile may wrap
     to four or five and that's fine. */
  max-width: 22ch;
  margin-inline: auto;
}

.hero__headline br {
  display: none;
}

@media (min-width: 640px) {
  .hero__headline {
    font-size: var(--text-display-lg);
  }
}

@media (min-width: 1024px) {
  .hero__headline {
    font-size: var(--text-display-xl);
  }
}

.hero__subhead {
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  /* Capped narrower than the headline so the eye doesn't scan a 100ch
     horizontal sliver — centred body copy reads cleanly inside ~60ch. */
  max-width: 60ch;
  margin-inline: auto;
}

.hero__ctas {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

@media (max-width: 479px) {
  .hero__ctas {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }
  .hero__ctas .btn {
    width: 100%;
  }
}


/* ==========================================================================
   7. Problem

   Section 2. Text-heavy by design — feels like a peer's diagnosis. No
   chart, no illustration, no metric callouts (those belong to Section 3).

   Layout
   - Heading + eyebrow stacked.
   - Two columns ≥1024px (each pairs a quote with a framing paragraph);
     single column below. Gap is generous so the columns read as parallel
     diagnoses, not as a tight grid.
   - Closing line full-width, top-margin space-7, tertiary tone.

   Semantics: blockquote + cite. cite is styled mono per design-system
   discipline (mono = code-shaped identifier). The opening dialog-quote
   characters are baked into the locked copy as &ldquo;/&rdquo;.
   ========================================================================== */
.problem__heading {
  font-size: var(--text-heading-lg);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  color: var(--text-primary);
  max-width: 22ch;
  margin-bottom: var(--space-7);
}

@media (min-width: 1024px) {
  .problem__heading {
    font-size: var(--text-display-md);
    line-height: var(--leading-display-loose);
    letter-spacing: var(--tracking-display);
  }
}

.problem__columns {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-7);
}

@media (min-width: 1024px) {
  .problem__columns {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-8);
  }
}

.problem__col {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  /* Ember left-border lives on the column wrapper (not the quote) so
     both columns' borders extend to the same height — matching the
     taller of the two columns when grid `align-items: stretch` is in
     effect (the default for CSS Grid). */
  border-left: 3px solid var(--ember);
  padding-left: var(--space-4);
}

/* Quote callout — sits inside the column; no longer carries the border,
   that's the column wrapper's job now. */
.problem__quote {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.problem__quote p {
  font-family: var(--font-display);
  font-size: var(--text-body-lg);
  font-weight: var(--weight-regular);
  line-height: 1.5;
  color: var(--text-primary);
  max-width: 56ch;
  margin: 0;
}

/* cite is inline by default; force block so the byline sits on its own line. */
.problem__cite {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-style: normal;          /* HTML default for <cite> is italic — override */
  letter-spacing: var(--tracking-caption);
  color: var(--text-tertiary);
}

.problem__cite::before {
  content: "— ";
}

.problem__body {
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  max-width: 60ch;
}

.problem__body em {
  /* The emphasised in-house-tool clause — keep italics but bump to primary
     text so the line lands with weight, not just slant. */
  font-style: italic;
  color: var(--text-primary);
}

.problem__closer {
  margin-top: var(--space-7);
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-tertiary);
  font-style: italic;
  text-align: center;
  max-width: 60ch;
  margin-inline: auto;
}


/* ==========================================================================
   8. Stats — light section

   Section 3 — the strategic light moment in the dark cadence. Three deck
   stats; numbers do the work; ember underline reinforces the brand motif.

   Layout
   - Three-column grid ≥768px; single column below.
   - No card chrome (no border, no shadow): the section's light surface
     and the ember underline are enough visual structure. Cards on light
     would feel like a SaaS dashboard, not a reading room.

   Counter
   - Each .stats__number wraps two .stats__num spans (low, high) and an
     en-dash separator. JS animates from 0 to data-target on viewport
     entry. The aria-label on the parent paragraph announces the final
     range so screen readers ignore intermediate values.

   Ember underline
   - Implemented per .stats__num via a linear-gradient background that
     paints the bottom 4px of the line. Same pattern as the reusable
     .stat__number callout component (section 3 of this file) but scoped
     here so the per-digit underline tracks each animated number cleanly.
     Class name is fully namespaced (.stats__*) to avoid colliding with
     the section-3 .stat component.
   ========================================================================== */
.stats__heading {
  font-size: var(--text-heading-lg);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  color: var(--text-primary);
  max-width: 22ch;
  margin-bottom: var(--space-7);
}

@media (min-width: 1024px) {
  .stats__heading {
    font-size: var(--text-display-md);
    line-height: var(--leading-display-loose);
    letter-spacing: var(--tracking-display);
  }
}

.stats__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-7);
}

@media (min-width: 768px) {
  .stats__grid {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-6);
  }
}

@media (min-width: 1024px) {
  .stats__grid {
    gap: var(--space-7);
  }
}

.stats__card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Number row — display-md on mobile, display-lg on ≥1024px. Weight 500,
   tight tracking, primary text. Wraps the two .stats__num animated spans. */
.stats__number {
  font-family: var(--font-display);
  font-size: var(--text-display-md);
  font-weight: var(--weight-medium);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display-tight);
  color: var(--text-primary);
  margin: 0;
  display: flex;
  align-items: baseline;
  flex-wrap: nowrap;
  white-space: nowrap;
}

@media (min-width: 1024px) {
  .stats__number {
    font-size: var(--text-display-lg);
  }
}

/* Each animated digit-span gets its own ember underline. linear-gradient
   draws a 4px ember stripe at the bottom edge; padding-bottom reserves
   space so the underline never overlaps the descender of the next line. */
.stats__num {
  display: inline-block;
  padding-bottom: var(--space-1);
  background-image: linear-gradient(to right, var(--ember), var(--ember-glow));
  background-size: 100% 4px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  font-variant-numeric: tabular-nums;  /* digits don't jiggle during counter */
  min-width: 1ch;
}

.stats__sep {
  color: var(--text-tertiary);
  padding-inline: 0.1em;
}

.stats__unit {
  color: var(--text-primary);
}

.stats__unit--prefix {
  /* "$" sits flush with the first number, no gap. */
  margin-right: 0;
}

.stats__label {
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  max-width: 32ch;
  margin: 0;
}

.stats__source {
  font-size: var(--text-caption);
  line-height: var(--leading-caption);
  color: var(--text-tertiary);
  margin: var(--space-2) 0 0 0;
  max-width: 36ch;
}

.stats__closer {
  margin-top: var(--space-7);
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  font-style: italic;
  text-align: center;
  max-width: 60ch;
  margin-inline: auto;
}


/* ==========================================================================
   9. How it works

   Section 4 — dark. Three beats:
     (a) intro (eyebrow + locked H2 + lead paragraph) — centered, capped
     (b) case-law callout — ember left-border, subtle elevated background,
         italicises only the verbatim phrase "a little bit like case law"
         (italicising the whole quote would mute the load-bearing words)
     (c) ordered list of four steps in a 2x2 grid on desktop, single col
         below. Numbers are visually rendered via .step__num (mono, ember)
         and the <ol> is the screen-reader anchor.

   No icons, no diagrams. The PCG hero owns the visual product thesis;
   this section is words.
   ========================================================================== */
.how__intro {
  text-align: center;
  /* No max-width here — body readability caps live on .how__lead.
     Letting the wrapper open up lets the heading stay on one line at
     desktop while the lead paragraph still keeps a 64ch measure. */
}

.how__heading {
  font-size: var(--text-heading-lg);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  color: var(--text-primary);
  margin: var(--space-2) 0 var(--space-4) 0;
}

@media (min-width: 1024px) {
  .how__heading {
    font-size: var(--text-display-md);
    line-height: var(--leading-display-loose);
    letter-spacing: var(--tracking-display);
  }
}

.how__lead {
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  max-width: 64ch;
  margin-inline: auto;
}

/* Direct product-claim callout — ember left-border + subtle elevated tint.
   Sits between the intro and the steps grid as a confident statement,
   not a manufactured quote: no italic, no attribution byline. */
.how__claim {
  margin: var(--space-8) auto;
  max-width: 64ch;
  background-color: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-left: 3px solid var(--ember);
  border-radius: var(--radius-md);
  padding: var(--space-5) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.how__claim-line {
  font-family: var(--font-display);
  font-size: var(--text-heading-md);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading-loose);
  letter-spacing: var(--tracking-heading);
  color: var(--text-primary);
  margin: 0;
}

/* Steps — semantic <ol>. The default list-marker would compete with our
   bespoke .step__num, so reset list styles. */
.steps {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}

/* Tablet — step 2 takes a full-width row at the top with its mono code
   snippet; steps 1, 3, 4 share a 3-column row below. */
@media (min-width: 640px) and (max-width: 1023px) {
  .steps {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-4) var(--space-5);
  }
  .step--feature {
    grid-column: 1 / -1;
  }
}

/* Desktop — asymmetric layout. Step 2 spans 3 rows on the left at ~60%
   width, with its mono code snippet visible; steps 1, 3, 4 stack on the
   right at ~40%, condensed. The DOM order stays 1→2→3→4 so screen
   readers announce the steps semantically. */
@media (min-width: 1024px) {
  .steps {
    grid-template-columns: 1.5fr 1fr;
    grid-auto-rows: auto;
    gap: var(--space-5) var(--space-6);
    align-items: stretch;
  }
  .step--feature {
    grid-column: 1;
    grid-row: 1 / span 3;
  }
  .step:not(.step--feature) {
    grid-column: 2;
  }
}

/* Featured step card — visually weighted. Elevated surface, ember accent
   stripe on the left, more padding. The mono code snippet inside reads
   as a real terminal query, not a marketing illustration. */
.step--feature {
  background-color: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-left: 2px solid var(--ember);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.step--feature .step__title {
  font-size: var(--text-display-sm);
  letter-spacing: var(--tracking-display);
}

/* Compact peripheral cards (steps 1, 3, 4) — same visual family, less
   bulk so step 2 reads as the primary statement. */
.step:not(.step--feature) {
  background-color: transparent;
  padding: var(--space-3) 0;
}

@media (min-width: 1024px) {
  .step:not(.step--feature) {
    padding: var(--space-4);
    background-color: transparent;
    border-top: 1px solid var(--border-subtle);
  }
  .step:not(.step--feature) .step__title {
    font-size: var(--text-heading-sm);
  }
  .step:not(.step--feature) .step__body {
    font-size: var(--text-body-sm);
    /* No line-clamp — peripheral cards size to their content. Step 2
       still dominates via the elevated card chrome, larger heading,
       ember accent, and the mono code snippet underneath. */
  }
}

/* Terminal-style code snippet inside step 2 */
.code-snippet {
  margin: var(--space-4) 0 0;
  padding: var(--space-4) var(--space-4);
  background-color: var(--bg-dark);
  border: 1px solid var(--border-subtle);
  border-left: 2px solid var(--ember-glow);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  line-height: 1.5;
  color: var(--text-secondary);
  white-space: pre;
  overflow-x: auto;
}

/* Per-line colouring inside the terminal-style snippet.
   [FORGE] output lines stay muted; user query lines (prefixed with ">")
   get full contrast so the interaction reads as a real terminal trace. */
.cs-line {
  display: block;
}

.cs-line--forge {
  color: var(--text-secondary);
}

.cs-line--user {
  color: var(--text-primary);
}

.step {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Numeric prefix — mono caption-large with ember-glow color. Stays small;
   the step title carries the visual weight. */
.step__num {
  font-family: var(--font-mono);
  font-size: var(--text-body-sm);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-caption);
  color: var(--ember-glow);
  line-height: 1;
}

.step__title {
  font-size: var(--text-heading-md);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  color: var(--text-primary);
  margin: 0;
}

.step__body {
  font-size: var(--text-body-md);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  max-width: 56ch;
  margin: 0;
}

.step__body strong {
  /* The "probabilistic risk values, not binary verdicts" pivot — primary
     text + medium weight to land it without resorting to bold-heavy. */
  font-weight: var(--weight-medium);
  color: var(--text-primary);
}


/* ==========================================================================
   10. Capabilities

   Section 5 — dark. Six capability cards in a responsive grid:
     - 3 cols ≥1024px (3x2)
     - 2 cols 640–1024px (2x3)
     - 1 col below (1x6)

   Card chrome
   - Subtle elevated background, --border-subtle, --radius-lg.
   - Hover lift: translateY(-3px) + shadow-md. Earns its place because
     these cards are tappable on touch devices (informational, but they
     anchor the demo expectation).
   - Icons inline-SVG, currentColor stroke. Color is --text-tertiary so
     they sit quieter than the title; on hover the card lifts and the
     icon stays the same tone (intentional — the lift is the affordance).

   No icon backgrounds, no icon-in-a-circle treatment, no colored icons.
   ========================================================================== */
.capabilities__intro {
  text-align: center;
  margin-bottom: var(--space-7);
}

.capabilities__heading {
  font-size: var(--text-heading-lg);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  color: var(--text-primary);
  margin: var(--space-2) 0 var(--space-4) 0;
}

@media (min-width: 1024px) {
  .capabilities__heading {
    font-size: var(--text-display-md);
    line-height: var(--leading-display-loose);
    letter-spacing: var(--tracking-display);
  }
}

.capabilities__lead {
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  max-width: 64ch;
  margin-inline: auto;
}

.capabilities__closer {
  margin: var(--space-7) auto 0 auto;
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-tertiary);
  font-style: italic;
  text-align: center;
  max-width: 64ch;
}

/* --------------------------------------------------------------------------
   Connected-graph capability layout

   Desktop: six labelled nodes arranged in a hexagon around a central hub
   ("Product Context Graph"). The SVG draws the geometry; the <ol> beside
   it carries the semantic content and is absolutely positioned over the
   SVG so each label sits at its node coordinate. Aspect ratio is locked
   to the SVG viewBox so labels stay aligned at any container width.

   Mobile (<768px): the SVG and hub label hide; the list collapses to a
   vertical column with a small node marker on each item and a thin spine
   connecting them — implying the same graph metaphor at small widths
   without trying to render a hex that doesn't fit.
   -------------------------------------------------------------------------- */
.cap-graph {
  position: relative;
  width: 100%;
  max-width: 900px;
  margin: var(--space-7) auto 0;
  aspect-ratio: 800 / 720;
}

.cap-graph__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.cap-graph__edges line {
  /* Ember stroke ties each line back to the central ember-glowing hub
     and reads the "connected graph" metaphor clearly at a glance. */
  stroke: rgba(249, 115, 22, 0.35);
  stroke-width: 0.75;
  opacity: 1;
}

.cap-graph__hub {
  fill: var(--bg-elevated);
  stroke: var(--ember);
  stroke-width: 0.8;
  filter: drop-shadow(0 0 8px rgba(249, 115, 22, 0.25));
}

.cap-graph__nodes circle {
  fill: var(--bg-elevated);
  stroke: var(--text-primary);
  stroke-width: 1.2;
}

.cap-graph__hub-label {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-caption);
  line-height: 1.25;
  text-align: center;
  text-transform: uppercase;
  color: var(--ember-glow);
  pointer-events: none;
  width: 88px;
}

.cap-graph__items {
  position: absolute;
  inset: 0;
  list-style: none;
  margin: 0;
  padding: 0;
}

.cap-graph__item {
  position: absolute;
  max-width: 200px;
}

.cap-graph__title {
  font-family: var(--font-display);
  font-size: var(--text-heading-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-heading-tight);
  color: var(--text-primary);
  margin: 0 0 var(--space-1);
  line-height: var(--leading-heading);
}

.cap-graph__body {
  font-family: var(--font-body);
  font-size: var(--text-body-sm);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  margin: 0;
}

/* Node-anchored placement.
   Each item is positioned at the matching node coordinate (as a % of the
   800×540 viewBox), then translated outward so it sits clear of the node
   and line. Top three labels grow upward (bottom-anchored), bottom three
   grow downward (top-anchored). */
/* Coordinates correspond to the hex laid out at radius=180 inside the
   800×720 viewBox (centre at 400/360). The hex is intentionally tight
   so the composition reads as a dense connected graph, not six things
   floating in a void. */
.cap-graph__item[data-pos="top"] {
  left: 50%;
  top: 25%;
  transform: translate(-50%, calc(-100% - 22px));
  text-align: center;
}
.cap-graph__item[data-pos="upper-right"] {
  left: 69.5%;
  top: 37.5%;
  transform: translate(22px, calc(-100% - 8px));
  text-align: left;
}
.cap-graph__item[data-pos="lower-right"] {
  left: 69.5%;
  top: 62.5%;
  transform: translate(22px, 8px);
  text-align: left;
}
.cap-graph__item[data-pos="bottom"] {
  left: 50%;
  top: 75%;
  transform: translate(-50%, 22px);
  text-align: center;
}
.cap-graph__item[data-pos="lower-left"] {
  left: 30.5%;
  top: 62.5%;
  transform: translate(calc(-100% - 22px), 8px);
  text-align: right;
}
.cap-graph__item[data-pos="upper-left"] {
  left: 30.5%;
  top: 37.5%;
  transform: translate(calc(-100% - 22px), calc(-100% - 8px));
  text-align: right;
}

/* Tablet — compress the hex into a tighter aspect so labels still fit */
@media (max-width: 1023px) and (min-width: 768px) {
  .cap-graph {
    max-width: 720px;
  }
  .cap-graph__item {
    max-width: 160px;
  }
  .cap-graph__body {
    font-size: var(--text-body-sm);
  }
}

/* Mobile — collapse to a stacked list with a left-spine marker.
   The SVG and hub label hide; the <ol> takes over as a linear sequence.
   The vertical line on the container implies the same graph spine the
   desktop visual is built on. */
@media (max-width: 767px) {
  .cap-graph {
    aspect-ratio: auto;
    max-width: none;
    margin-top: var(--space-6);
    padding-left: var(--space-5);
    border-left: 1px solid var(--border-subtle);
  }
  .cap-graph__svg,
  .cap-graph__hub-label {
    display: none;
  }
  .cap-graph__items {
    position: static;
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
  }
  .cap-graph__item,
  .cap-graph__item[data-pos] {
    position: relative;
    left: auto;
    top: auto;
    transform: none;
    text-align: left;
    max-width: none;
    padding-left: var(--space-3);
  }
  /* Small node marker dotting onto the left spine */
  .cap-graph__item::before {
    content: "";
    position: absolute;
    left: calc(-1 * var(--space-5) - 4px - 1px);
    top: 10px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--bg-elevated);
    border: 1.2px solid var(--text-primary);
  }
}

/* Hover — line connecting the hovered node to centre brightens, and the
   node itself grows ~10%. Uses :has() so a hover on the label propagates
   to the matching SVG node + edge. */
@media (hover: hover) {
  .cap-graph:has(.cap-graph__item[data-pos="top"]:hover)         .cap-graph__edges line[data-pos="top"],
  .cap-graph:has(.cap-graph__item[data-pos="upper-right"]:hover) .cap-graph__edges line[data-pos="upper-right"],
  .cap-graph:has(.cap-graph__item[data-pos="lower-right"]:hover) .cap-graph__edges line[data-pos="lower-right"],
  .cap-graph:has(.cap-graph__item[data-pos="bottom"]:hover)      .cap-graph__edges line[data-pos="bottom"],
  .cap-graph:has(.cap-graph__item[data-pos="lower-left"]:hover)  .cap-graph__edges line[data-pos="lower-left"],
  .cap-graph:has(.cap-graph__item[data-pos="upper-left"]:hover)  .cap-graph__edges line[data-pos="upper-left"] {
    stroke: var(--text-primary);
    opacity: 0.9;
  }
  .cap-graph:has(.cap-graph__item[data-pos="top"]:hover)         .cap-graph__nodes circle[data-pos="top"],
  .cap-graph:has(.cap-graph__item[data-pos="upper-right"]:hover) .cap-graph__nodes circle[data-pos="upper-right"],
  .cap-graph:has(.cap-graph__item[data-pos="lower-right"]:hover) .cap-graph__nodes circle[data-pos="lower-right"],
  .cap-graph:has(.cap-graph__item[data-pos="bottom"]:hover)      .cap-graph__nodes circle[data-pos="bottom"],
  .cap-graph:has(.cap-graph__item[data-pos="lower-left"]:hover)  .cap-graph__nodes circle[data-pos="lower-left"],
  .cap-graph:has(.cap-graph__item[data-pos="upper-left"]:hover)  .cap-graph__nodes circle[data-pos="upper-left"] {
    r: 11;
    fill: var(--text-primary);
  }
  .cap-graph__edges line,
  .cap-graph__nodes circle {
    transition: stroke var(--motion-fast) var(--easing),
                opacity var(--motion-fast) var(--easing),
                fill var(--motion-fast) var(--easing),
                r var(--motion-fast) var(--easing);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cap-graph__edges line,
  .cap-graph__nodes circle {
    transition: none;
  }
}


/* ==========================================================================
   11. Differentiation — light section

   Section 6 — the second strategic light moment. Three-column comparison.
   Column 3 (.compare__col--forge) is visually distinguished by ember
   border + soft ember glow shadow; columns 1–2 share neutral chrome so
   the visual hierarchy mirrors the rhetorical hierarchy.

   Copy discipline: columns 1–2 frame *categories*, not named competitors.
   The visual treatment must not push column 3 into "billboard ad" — it's
   the conclusion the reader arrives at, not an interruption shouting at
   them.

   Layout
   - 3 cols ≥768px, 1 col below. Gap space-5.
   - Each column is an <article> so AT announces "Article" and reads the
     header + list cleanly.

   List items: subtle delimiter via ::before — muted dash on cols 1–2,
   ember square on col 3.
   ========================================================================== */
.differentiation__intro {
  text-align: center;
  margin-bottom: var(--space-7);
}

.differentiation__heading {
  font-size: var(--text-heading-lg);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  color: var(--text-primary);
  margin: var(--space-2) 0 var(--space-4) 0;
}

@media (min-width: 1024px) {
  .differentiation__heading {
    font-size: var(--text-display-md);
    line-height: var(--leading-display-loose);
    letter-spacing: var(--tracking-display);
  }
}

.differentiation__lead {
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  max-width: 64ch;
  margin-inline: auto;
}

.compare__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  align-items: stretch;
}

@media (min-width: 768px) {
  .compare__grid {
    /* Column 3 (ForgeComply) gets 25% extra width on top of the ember
       border — visual privilege through layout, not just color. */
    grid-template-columns: 1fr 1fr 1.25fr;
  }
}

.compare__col {
  background-color: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin: 0;
}

/* Column 3 — ember border, soft glow shadow. The glow is dialed down
   from --shadow-ember so it reads as "attention," not "alarm." */
.compare__col--forge {
  border: 1px solid var(--ember);
  box-shadow: 0 0 0 1px rgba(194, 65, 12, 0.18), 0 8px 24px rgba(249, 115, 22, 0.10);
}

.compare__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.compare__title {
  font-size: var(--text-heading-sm);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading-tight);
  color: var(--text-primary);
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* Small ember dot next to "ForgeComply" in column 3 — a quiet brand mark
   that ties to the PCG energy nodes from the hero. */
.compare__forge-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--ember-glow);
  box-shadow: 0 0 8px rgba(249, 115, 22, 0.6);
  flex-shrink: 0;
}

.compare__subtitle {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-style: italic;
  letter-spacing: var(--tracking-caption);
  color: var(--text-tertiary);
  margin: 0;
}

.compare__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.compare__list li {
  position: relative;
  padding-left: var(--space-4);
  font-size: var(--text-body-md);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  margin: 0;
}

/* Muted dash delimiter for columns 1–2; matches the section's tertiary tone. */
.compare__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.7em;
  width: 8px;
  height: 1px;
  background-color: var(--text-tertiary);
}

/* Ember square delimiter for column 3 — small, exact, brand-coded. */
.compare__col--forge .compare__list li::before {
  top: 0.55em;
  width: 4px;
  height: 4px;
  background-color: var(--ember);
  border-radius: 1px;
}

.compare__col--forge .compare__list li em {
  font-style: italic;
  color: var(--text-primary);
}

/* Emphasised closer bullet — sits at the bottom of column 3 only, set
   apart with a top border + slightly heavier weight. Carries the seal
   line for the column without needing extra color. */
.compare__col--forge .compare__list-emphasis {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-emphasis);
  font-weight: var(--weight-medium);
}

.compare__col--forge .compare__list-emphasis strong {
  font-weight: var(--weight-medium);
}

.differentiation__closer {
  margin: var(--space-7) auto 0 auto;
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-tertiary);
  font-style: italic;
  text-align: center;
  max-width: 64ch;
}


/* ==========================================================================
   12. Founder placeholder

   Section 7 — a deliberately quiet beat between the loud differentiation
   grid and the FAQ. Narrow column (800px max), everything centered. One
   paragraph under 80 words; one neutral avatar placeholder (no stock
   photo — empty is more honest than fake).

   This whole block is swappable to a named founder bio in one edit when
   the IP/non-compete clearance lands. The placeholder body copy and the
   <section> wrapper survive that swap; the photo placeholder is replaced
   by a real headshot.
   ========================================================================== */
.founder__inner {
  max-width: 800px;
  margin-inline: auto;
  padding-inline: var(--space-5);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}

.founder__heading {
  font-size: var(--text-heading-md);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  color: var(--text-primary);
  max-width: 28ch;
  margin: 0;
}

.founder__body {
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  max-width: 60ch;
  margin: 0;
}



/* ==========================================================================
   13. FAQ

   Section 8 — slightly elevated dark (--bg-subtle vs the section-default
   --bg-dark). Seven <details>/<summary> accordions; native HTML handles
   open/close + keyboard + screen-reader semantics — zero JS.

   Layout
   - max-width 800px, centered single column.
   - 16px gap between items (space-3); each item is a rounded card with
     a subtle border that emphasises on hover/open.

   Chevron
   - Implemented as a CSS-drawn caret on `summary::after`. Rotates 180°
     when [open]. No SVG sprite, no JS, no image request.

   Hover/focus
   - Hover: summary text shifts to --ember-glow (the rare functional
     ember use that's earned — affordance-confirming on a question that
     responds to interaction).
   - Focus-visible: --primary outline ring (matches base.css default).
   ========================================================================== */
.faq {
  background-color: var(--bg-subtle);
}

.faq__intro {
  text-align: center;
  max-width: 800px;
  margin: 0 auto var(--space-7) auto;
}

.faq__heading {
  font-size: var(--text-heading-lg);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  color: var(--text-primary);
  margin: var(--space-2) 0 0 0;
}

@media (min-width: 1024px) {
  .faq__heading {
    font-size: var(--text-display-md);
    line-height: var(--leading-display-loose);
    letter-spacing: var(--tracking-display);
  }
}

.faq__list {
  max-width: 800px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.faq__item {
  /* On --bg-subtle, the card surface drops back to --bg-dark so the
     accordion reads as inset, not stacked-elevated. */
  background-color: var(--bg-dark);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: 0 var(--space-5);
  transition:
    border-color var(--motion-fast) var(--easing),
    background-color var(--motion-fast) var(--easing);
}

.faq__item:hover {
  border-color: var(--border-emphasis);
}

.faq__item[open] {
  border-color: var(--border-emphasis);
}

/* Strip the default disclosure triangle (browser-prefixed forms covered). */
.faq__q {
  list-style: none;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: var(--text-heading-xs);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading-loose);
  letter-spacing: var(--tracking-heading-tight);
  color: var(--text-primary);
  /* Vertical padding lives here (not on .faq__item) so the summary's
     tap target is ≥ 44px tall, satisfying WCAG 2.5.5. */
  padding: var(--space-4) var(--space-5) var(--space-4) 0;
  position: relative;
  display: block;
  transition: color var(--motion-fast) var(--easing);
}

.faq__q::-webkit-details-marker { display: none; }
.faq__q::marker { display: none; }

.faq__q:hover {
  color: var(--ember-glow);
}

.faq__q:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 4px;
  border-radius: var(--radius-sm);
}

/* CSS-drawn chevron — two 1.5px strokes meeting at a 45deg angle on the
   right edge. Rotates 180deg when the <details> opens. */
.faq__q::after {
  content: "";
  position: absolute;
  right: 0;
  top: 50%;
  width: 10px;
  height: 10px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-70%) rotate(45deg);
  transition: transform var(--motion-fast) var(--easing);
  color: var(--text-tertiary);
}

.faq__item[open] .faq__q::after {
  transform: translateY(-20%) rotate(-135deg);
  color: var(--ember-glow);
}

.faq__a {
  padding-top: var(--space-3);
  padding-bottom: var(--space-4);
}

.faq__a p {
  font-size: var(--text-body-md);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  max-width: none;
  margin: 0;
}

.faq__a em {
  font-style: italic;
  color: var(--text-primary);
}


/* ==========================================================================
   14. Final CTA + demo form

   Section 9 — page terminus. Discovery-instrumented form: name / email /
   company / role / regime(s) / submission status / free-text. Submits
   via main.js to a placeholder console.log handler.

   Form discipline
   - Label above input, never placeholder-as-label.
   - Required fields carry HTML5 `required` AND `aria-required="true"`.
   - Checkbox/radio groups wrapped in <fieldset><legend>.
   - Native checkbox + radio appearance preserved — engineers trust the
     native control. We style only the wrapping <label> for a clickable
     row, not the control itself.
   ========================================================================== */
.final-cta__intro {
  text-align: center;
  max-width: 720px;
  margin: 0 auto var(--space-7) auto;
}

.final-cta__heading {
  font-size: var(--text-heading-lg);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  color: var(--text-primary);
  margin: var(--space-2) 0 var(--space-4) 0;
}

@media (min-width: 1024px) {
  .final-cta__heading {
    font-size: var(--text-display-md);
    line-height: var(--leading-display-loose);
    letter-spacing: var(--tracking-display);
  }
}

.final-cta__lead {
  font-size: var(--text-body-lg);
  line-height: var(--leading-body);
  color: var(--text-secondary);
  max-width: 60ch;
  margin-inline: auto;
}

/* ----- Demo form ----- */
.demo-form {
  max-width: 640px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.fieldset {
  /* native <fieldset> ships with a border + min-width:min-content; reset. */
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.field__label {
  font-family: var(--font-display);
  font-size: var(--text-body-md);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  letter-spacing: var(--tracking-body);
  /* legend rendering inherits this; padding: 0 keeps it flush. */
  padding: 0;
}

.field__hint {
  font-weight: var(--weight-regular);
  font-style: italic;
  font-size: var(--text-caption);
  color: var(--text-tertiary);
}

.field__input {
  background-color: var(--bg-subtle);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  color: var(--text-primary);
  font-family: inherit;
  font-size: var(--text-body-md);
  line-height: var(--leading-heading-loose);
  transition:
    border-color var(--motion-fast) var(--easing),
    box-shadow var(--motion-fast) var(--easing);
  /* iOS Safari adds inset shadow on inputs; reset to keep the dark surface clean. */
  -webkit-appearance: none;
  appearance: none;
}

.field__input:hover {
  border-color: var(--border-emphasis);
}

.field__input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.18);
}

.field__input::placeholder {
  color: var(--text-tertiary);
}

.field__select {
  /* Re-add an arrow since `appearance: none` removes the native one. SVG is
     inlined as a data URI so no extra request. */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23A1A1AA' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  padding-right: var(--space-6);
  cursor: pointer;
}

.field__textarea {
  resize: vertical;
  min-height: 96px;
}

/* Checkbox / radio rows — make the whole label clickable; keep the native
   control visible and accessible. */
.regimes {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

@media (min-width: 640px) {
  .regimes {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-4);
  }
}

.status {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

@media (min-width: 640px) {
  .status {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-4);
  }
  /* Odd-count radio: last item spans both columns so it doesn't dangle */
  .radio--span {
    grid-column: 1 / -1;
  }
}

.check,
.radio {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: var(--text-body-md);
  color: var(--text-secondary);
  transition: background-color var(--motion-fast) var(--easing);
}

.check:hover,
.radio:hover {
  background-color: rgba(255, 255, 255, 0.03);
  color: var(--text-primary);
}

.check input,
.radio input {
  /* Keep native control, give it a small accent-color so check/radio fills
     in primary blue rather than browser default. */
  accent-color: var(--primary);
  margin-top: 0.25em;
  flex-shrink: 0;
}

.demo-form__submit {
  width: 100%;
  min-height: 56px;
  font-weight: var(--weight-semibold);
  font-size: var(--text-body-lg);
  margin-top: var(--space-2);
}

.demo-form__submit[disabled] {
  opacity: 0.6;
  cursor: not-allowed;
}

/* Error banner — inserted by main.js above the submit button if the
   Formspree POST fails. Quiet semantic-error styling, no shouty red. */
.demo-form__error {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  background-color: rgba(239, 68, 68, 0.08);
  border: 1px solid rgba(239, 68, 68, 0.35);
  border-radius: var(--radius-md);
  font-size: var(--text-body-sm);
  color: var(--error);
  line-height: var(--leading-body);
}

.btn-large {
  /* Modifier consumed by both .btn-primary and standalone uses. */
  min-height: 56px;
  font-size: var(--text-body-lg);
}

.demo-form__disclaimer {
  font-size: var(--text-caption);
  color: var(--text-tertiary);
  text-align: center;
  margin: 0;
  max-width: 60ch;
  margin-inline: auto;
}

/* ----- Confirmation state (toggled by main.js) ----- */
.demo-form__confirmation {
  max-width: 640px;
  margin: 0 auto;
  padding: var(--space-6);
  background-color: var(--bg-subtle);
  border: 1px solid var(--ember);
  border-radius: var(--radius-lg);
  text-align: center;
  box-shadow: 0 0 0 1px rgba(194, 65, 12, 0.18), 0 8px 24px rgba(249, 115, 22, 0.10);
}

.demo-form__confirm-heading {
  font-size: var(--text-heading-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  margin: 0 0 var(--space-3) 0;
  line-height: var(--leading-heading);
}

.demo-form__confirm-body {
  font-size: var(--text-body-md);
  color: var(--text-secondary);
  margin: 0;
}

/* ==========================================================================
   Floating-pill header

   Three free-floating elements at the top of the viewport: logo (left),
   nav pill (centre), CTA pill (right). The header itself has no
   background — the empty space between elements lets the page show
   through. data-mode is updated by motion.js as the user scrolls so the
   pills swap between dark glass (over dark sections) and light glass
   (over the strategic light moments: stats, differentiation).

   The active-item underlight glow is the signature visual move: a soft
   ember radial-gradient leaks out beneath the currently-visible section's
   nav item.
   ========================================================================== */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  display: grid;
  /* 1fr auto 1fr forces the left and right columns to equal width
     regardless of their content widths, so the centre nav pill sits
     at the true page centre rather than drifting toward whichever
     side has the heavier element. */
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-3) var(--space-5);

  /* No background on the header itself — pills carry the glass. The
     empty space between the three pills lets the page show through, so
     clicks must pass through. Pointer events are re-enabled on the
     interactive children only. */
  background: transparent;
  pointer-events: none;

  transition: color var(--motion-default) var(--easing);
}

.site-header > * {
  pointer-events: auto;
}

/* Adaptive pill tokens — dark vs light surface below the header */
.site-header[data-mode="dark"] {
  color: var(--text-primary-dark);
  --pill-bg: rgba(14, 16, 20, 0.55);
  --pill-border: rgba(255, 255, 255, 0.10);
  --pill-text: var(--text-primary-dark);
  --pill-text-muted: rgba(250, 250, 251, 0.55);
  --pill-dot-muted: rgba(250, 250, 251, 0.25);
}

.site-header[data-mode="light"] {
  color: var(--text-primary-light);
  --pill-bg: rgba(247, 247, 248, 0.65);
  --pill-border: rgba(0, 0, 0, 0.08);
  --pill-text: var(--text-primary-light);
  --pill-text-muted: rgba(14, 16, 20, 0.55);
  --pill-dot-muted: rgba(14, 16, 20, 0.25);
}

/* Logo — Forge mark only, free-floating (no container/pill).
   Inline SVG with fill="currentColor" — adapts to the header's text
   color automatically as data-mode flips between dark and light.
   The <a> wrapper has min-width/height ≥44px so the tap target meets
   WCAG 2.5.5 on touch devices; the mark itself stays at 28px. */
.site-header__logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  color: inherit;
  justify-self: start;
  min-width: 44px;
  min-height: 44px;
  margin-inline-start: -8px;   /* nudge so the visual mark aligns to the section gutter, not the padded hit area */
}

.site-header__logomark {
  display: block;
  width: 28px;
  height: 28px;
  color: inherit;
}

/* Slightly larger mark on small viewports where the logo is the only
   visual anchor in the header (nav pill + CTA pill collapse into the
   hamburger). Touch-target wrapper stays 44×44. */
@media (max-width: 1023px) {
  .site-header__logomark {
    width: 32px;
    height: 32px;
  }
}

.site-header__logo:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 4px;
  border-radius: 8px;
}

/* Nav pill (centre) */
.site-header__nav-pill {
  justify-self: center;
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--pill-bg);
  border: 1px solid var(--pill-border);
  backdrop-filter: blur(12px) saturate(180%);
  -webkit-backdrop-filter: blur(12px) saturate(180%);
  position: relative;
  transition: background-color var(--motion-default) var(--easing),
              border-color var(--motion-default) var(--easing);
}

.nav-pill__item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 999px;
  color: var(--pill-text-muted);
  text-decoration: none;
  font-size: var(--text-body-sm);
  font-weight: var(--weight-medium);
  transition: color var(--motion-fast) var(--easing),
              background-color var(--motion-fast) var(--easing);
  position: relative;
}

.nav-pill__dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--pill-dot-muted);
  transition: background-color var(--motion-fast) var(--easing),
              box-shadow var(--motion-fast) var(--easing);
  flex-shrink: 0;
}

.nav-pill__item:hover,
.nav-pill__item:focus-visible {
  color: var(--pill-text);
}

.nav-pill__item:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.nav-pill__item[data-active="true"] {
  color: var(--pill-text);
  background: rgba(255, 255, 255, 0.05);
}

.site-header[data-mode="light"] .nav-pill__item[data-active="true"] {
  background: rgba(0, 0, 0, 0.04);
}

.nav-pill__item[data-active="true"] .nav-pill__dot {
  background: var(--ember-glow);
  box-shadow: 0 0 8px rgba(249, 115, 22, 0.6);
}

/* Active-item underlight — the signature move. Soft ember glow
   shining up from below the active nav item, set just outside the
   pill so it reads as ambient rather than a visual chip. */
.nav-pill__item[data-active="true"]::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -16px;
  transform: translateX(-50%);
  width: 60%;
  height: 24px;
  background: radial-gradient(ellipse at center top, rgba(249, 115, 22, 0.35), transparent 70%);
  pointer-events: none;
  filter: blur(4px);
}

/* CTA pill (right) */
.site-header__cta-pill {
  justify-self: end;
  display: inline-flex;
  align-items: center;
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--pill-bg);
  border: 1px solid var(--pill-border);
  backdrop-filter: blur(12px) saturate(180%);
  -webkit-backdrop-filter: blur(12px) saturate(180%);
  color: var(--pill-text);
  text-decoration: none;
  font-size: var(--text-body-sm);
  font-weight: var(--weight-medium);
  position: relative;
  transition: background-color var(--motion-default) var(--easing),
              border-color var(--motion-default) var(--easing),
              box-shadow var(--motion-default) var(--easing);
}

/* Subtle top-edge highlight — the inside-light effect from the reference */
.site-header__cta-pill::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.08), transparent 30%);
  pointer-events: none;
}

.site-header__cta-pill:hover {
  border-color: var(--ember-glow);
  box-shadow: var(--shadow-ember);
}

.site-header__cta-pill:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
}

/* Mobile hamburger — hidden on desktop, shown <1024px */
.site-header__menu-toggle {
  display: none;
  justify-self: end;
  background: var(--pill-bg);
  border: 1px solid var(--pill-border);
  border-radius: 999px;
  width: 44px;
  height: 44px;
  padding: 0;
  cursor: pointer;
  color: var(--pill-text);
  backdrop-filter: blur(12px) saturate(180%);
  -webkit-backdrop-filter: blur(12px) saturate(180%);
  align-items: center;
  justify-content: center;
  transition: border-color var(--motion-fast) var(--easing);
}

.site-header__menu-toggle:hover,
.site-header__menu-toggle:focus-visible {
  border-color: var(--ember-glow);
}

.site-header__menu-toggle:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.menu-toggle__icon {
  display: inline-flex;
  flex-direction: column;
  gap: 4px;
  width: 18px;
}

.menu-toggle__icon span {
  display: block;
  height: 1.5px;
  background: currentColor;
  border-radius: 1px;
}

/* Mobile menu overlay — hidden by default, shown when toggle is open */
.mobile-menu {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(14, 16, 20, 0.92);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  opacity: 0;
  transition: opacity var(--motion-default) var(--easing);
}

.mobile-menu[data-open="true"] {
  display: flex;
  opacity: 1;
}

.mobile-menu__inner {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: var(--space-4) var(--space-5) var(--space-7);
  gap: var(--space-5);
}

.mobile-menu__header {
  display: flex;
  justify-content: flex-end;
}

.mobile-menu__close {
  background: transparent;
  border: 1px solid var(--border-subtle-dark);
  border-radius: 50%;
  width: 44px;
  height: 44px;
  padding: 0;
  cursor: pointer;
  color: var(--text-primary-dark);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: border-color var(--motion-fast) var(--easing);
}

.mobile-menu__close:hover,
.mobile-menu__close:focus-visible {
  border-color: var(--ember-glow);
}

.mobile-menu__close:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.mobile-menu__nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  flex: 1;
  align-items: stretch;
  margin-top: var(--space-6);
}

.mobile-nav__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  color: var(--text-secondary-dark);
  text-decoration: none;
  font-family: var(--font-display);
  font-size: var(--text-heading-sm);
  font-weight: var(--weight-medium);
  min-height: 44px;
  transition: color var(--motion-fast) var(--easing),
              background-color var(--motion-fast) var(--easing);
}

.mobile-nav__item:hover,
.mobile-nav__item:focus-visible {
  color: var(--text-primary-dark);
  background: rgba(255, 255, 255, 0.04);
}

.mobile-nav__item:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.mobile-nav__item[data-active="true"] {
  color: var(--text-primary-dark);
  background: rgba(255, 255, 255, 0.04);
}

/* The inactive dot inside the mobile overlay can't read --pill-dot-muted
   (that token is scoped to .site-header). Set the dark-mode muted value
   here so the dot remains visible. Active state is overridden below. */
.mobile-nav__item .nav-pill__dot {
  background: rgba(250, 250, 251, 0.25);
}

.mobile-nav__item[data-active="true"] .nav-pill__dot {
  background: var(--ember-glow);
  box-shadow: 0 0 8px rgba(249, 115, 22, 0.6);
}

.mobile-menu__cta {
  width: 100%;
  justify-content: center;
  margin-top: var(--space-4);
}

@media (max-width: 1023px) {
  .site-header__nav-pill,
  .site-header__cta-pill {
    display: none;
  }
  .site-header__menu-toggle {
    display: inline-flex;
  }
}

/* Lock body scroll while the mobile menu is open */
body[data-menu-open="true"] {
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .site-header,
  .site-header__nav-pill,
  .nav-pill__item,
  .nav-pill__dot,
  .site-header__cta-pill {
    transition: none;
  }
  .nav-pill__item[data-active="true"]::after {
    display: none;
  }
}
