/* ==========================================================================
   goodngrowth, Quantum Mint Site System
   Tokens, motion engine, navigation, footer, buttons, forms, primitives.
   Loaded by every page. Page-specific styling lives in its own stylesheet.

   Aesthetic: warm editorial paper, obsidian contrast, Inter display,
   Newsreader prose and Geist Mono status labels. Rounded surfaces approved
   in the atomic-wombat plan; no glow, glass, chrome or added hue.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Fonts. self-hosted variable faces. No third-party request, no render block.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-var.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Newsreader';
  src: url('/fonts/newsreader-var.woff2') format('woff2-variations');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Geist Mono';
  src: url('/fonts/geistmono-var.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ── Surfaces ─────────────────────────────────────────────────────────────
     Inverted from the near-black world to the paper one BRAND.md specifies.
     The layering direction is unchanged: base -> elevated -> floating. On
     paper, elevated means LIGHTER (toward white) and recessed means warmer,
     which is the opposite of how it read on the dark ground. */
  --canvas: #F9F9F8;                        /* warm bone, the page ground */
  --canvas-deep: #F2F1ED;                   /* recessed: wells, insets */
  --gray-dark: #ECECEC;                     /* the banded section tone */
  --surface: #FFFFFF;                       /* cards lift toward white */
  --input: #FFFFFF;
  --border: #E2E1DC;
  --border-soft: rgba(17, 17, 17, 0.07);
  --border-strong: rgba(17, 17, 17, 0.14);

  /* Contrast surfaces. BRAND.md keeps obsidian, but as the EXCEPTION rather
     than the ground: sections that need to land hard, and nothing else. */
  --obsidian: #0C0C0C;
  --obsidian-2: #0E0E10;
  --charcoal: #1C1C1E;

  /* ── Accent ───────────────────────────────────────────────────────────────
     Was a bone white sitting one step ABOVE --text so emphasis read brighter.
     On paper the same logic runs downward: the accent is ink sitting one step
     BELOW --text, so emphasis reads as darker rather than as another hue.
     Still carried by fill and stroke, never by tinting a word in a sentence. */
  --accent: #111111;
  --accent-hi: #000000;                     /* hover and active on filled things */
  --accent-line: rgba(17, 17, 17, 0.28);
  --accent-dim: rgba(17, 17, 17, 0.10);
  --accent-glow: rgba(17, 17, 17, 0.10);
  --accent-wash: rgba(17, 17, 17, 0.04);

  /* Retired: --mint (#2DD4BF) carried the mark in the nav, footer and favicon.
     BRAND.md names no accent hue, and that value is Tailwind's teal-400 — one
     of the most common tells of a generated palette. The mark takes ink. */
  --mint: #111111;

  /* ── Text ─────────────────────────────────────────────────────────────────
     Straight from BRAND.md. Headers #111111, body #555555-#666666. Neutral,
     not warm-tinted: warmth lives in the paper, the ink stays achromatic.
     Measured on --canvas: 18.07:1, 7.07:1, 5.45:1. All clear AA.
     --micro is 3.10:1 — BELOW the 4.5:1 body floor. It is legal only on
     large text and on labels redundant with something else on screen. */
  --text: #111111;
  --muted: #555555;
  --muted-dim: #666666;
  /* BRAND.md names #8E8E93 for micro-labels. Measured, it is 3.09:1 on paper
     and 2.76:1 on the banded sections — below the 4.5:1 floor for small text
     and, on the band, below even the 3:1 large-text floor. It is therefore
     kept for NON-TEXT marks only (dots, hairlines, tick rules). Micro-labels
     themselves take --muted-dim, which clears AA on every surface we ship;
     the size, tracking and uppercase already separate them from body copy
     without needing the tonal step to do it. */
  --micro: #8E8E93;

  /* Warm tints, for panels that need to lift off the ground. */
  --warm-line: var(--accent-dim);
  --warm-wash: var(--accent-wash);

  /* ── Status ───────────────────────────────────────────────────────────────
     BRAND.md, Cognitive Ergonomics: no jarring red alert badges, no alarmist
     banners. Urgent states are a quiet dot and a plain-text line. So --alert
     drops from #F43F5E (a shout) to a deep madder that reads as ink with
     blood in it, and --warn loses its amber entirely: an amber pill IS the
     alarmist banner the doc rules out, and warm orange is off the palette. */
  --alert: #A32B41;
  --alert-dim: rgba(163, 43, 65, 0.10);
  --alert-line: rgba(163, 43, 65, 0.22);
  --warn: #6E6E73;
  --warn-dim: rgba(17, 17, 17, 0.06);

  /* ── Type ─────────────────────────────────────────────────────────────────
     Three faces, one job each, replacing Manrope doing display and body at
     once. Inter is the tight geometric neo-grotesque BRAND.md asks for and
     runs to wght 100 for display. Newsreader carries reading text: a warm
     serif against a hairline grotesque is the contrast that stops the page
     reading as generated. Geist Mono was already self-hosted and stays, for
     status lines and figures only. */
  --font-display: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-body: 'Newsreader', Georgia, 'Times New Roman', Times, serif;
  --font-mono: 'Geist Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

  /* Optical weight. Inter Thin is only structurally sound at size; below
     ~48px the stems thin out to nothing. Weight is therefore a function of
     size, not a free choice. */
  --w-display: 100;                         /* >= 48px only */
  --w-heading: 200;                         /* 29-40px */
  --w-sub: 400;                             /* below 29px */

  /* Optical sizing: the bigger the type, the tighter it is set. -0.02em at
     heading scale is BRAND.md's figure; display goes tighter because thin
     strokes make the counters read wider than they measure. */
  --track-xl: -0.03em;
  --track-lg: -0.02em;
  --track-md: -0.01em;
  --track-data: 0.08em;

  /* Spacing. Unchanged: the two section steps sit deliberately far above the
     rest of the ladder, which is what buys a section room to breathe. */
  --space-1: 0.5rem;
  --space-2: 0.75rem;
  --space-3: 1rem;
  --space-4: 1.5rem;
  --space-5: 2rem;
  --space-6: 3rem;
  --space-7: clamp(4rem, 8vw, 6.5rem);
  --space-8: clamp(5rem, 10vw, 8.5rem);

  /* Section scale. One pair of values for every section on every page. */
  --h1-size: clamp(2.6rem, 6vw, 4.5rem);
  --h2-size: clamp(2.1rem, 4.4vw, 3.6rem);
  --lede-size: clamp(1.05rem, 1.5vw, 1.3rem);

  /* Geometry: rounded surfaces approved in the atomic-wombat plan.
     This deliberately retires the square rule; app-icon geometry stays intact. */
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-pill: 999px;

  /* Paper elevation. One light source, above and slightly left.
     Wells use fill alone; cards sit lightly; featured surfaces float. */
  --card-border: rgba(28, 26, 22, 0.06);
  --shadow-sm: 0 2px 6px -2px rgba(28, 26, 22, 0.06);
  --shadow-md: 1px 8px 28px -12px rgba(28, 26, 22, 0.12);
  --shadow-float: 1px 8px 20px -8px rgba(28, 26, 22, 0.10),
                  3px 28px 56px -22px rgba(28, 26, 22, 0.16);
  --shadow-glow: 0 0 0 1px var(--border-strong), 0 12px 40px rgba(17, 17, 17, 0.10);
  --specular: inset 0 1px 0 rgba(255, 255, 255, 0.92);

  --nav-h: 4.25rem;

  /* Motion. One curve, an ease-out-expo. */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /* ── Layout measure ───────────────────────────────────────────────────────
     Promoted out of landing.css so the page backdrop can draw column guides
     that land on the real columns instead of an arbitrary interval.
     12 columns + 11 gaps span the wrap, so one column pitch is
     (wrap + gap) / 12. Verified: (1160 + 24) / 12 = 98.67px pitch,
     74.67px column. */
  --wrap-w: min(1160px, calc(100% - var(--space-6)));
  --col-gap: var(--space-4);
  --col-pitch: calc((var(--wrap-w) + var(--col-gap)) / 12);

  /* The guides themselves, declared once and used by both the page backdrop
     (for pages whose sections have no ground) and the section grounds
     themselves (for pages whose sections are opaque). */
  --col-guides: repeating-linear-gradient(to right,
                  rgba(17, 17, 17, 0.044) 0 1px,
                  transparent 1px var(--col-pitch));
}



/* --------------------------------------------------------------------------
   Legacy token aliases.
   The sibling pages carry inline styles written against the previous
   blue/emerald palette. Rather than rewrite every declaration, the old names
   are re-pointed at the Quantum Mint values so those pages rebrand with the
   shell. New work should use the tokens above, not these.
   -------------------------------------------------------------------------- */
:root {
  --bg-dark: var(--canvas);
  --bg-darker: var(--canvas-deep);
  --bg-surface: var(--surface);
  --bg-card: var(--surface);
  --bg-card-hover: var(--input);

  --light-bg: var(--canvas);
  --light-surface: var(--surface);
  --light-card: var(--surface);

  --brand-blue: var(--accent);
  --light-blue: var(--accent);
  --light-blue-dim: var(--accent-dim);
  --sky-accent: var(--accent-hi);

  --neon-lime: var(--accent);
  --neon-lime-glow: var(--accent-glow);
  --neon-lime-dim: var(--accent-dim);

  /* These four were referenced by use-cases.html but never defined anywhere, so
     24 declarations there were invalid at computed-value time: the colours fell
     back to `inherit` and `border: 1px solid var(--border-color)` rendered no
     border at all. Defining them is the fix; the page has never seen them. */
  --neon-green: var(--accent);
  --neon-green-dim: var(--accent-dim);
  --neon-green-glow: var(--accent-glow);
  --border-color: var(--border);
  --shadow-lg: var(--shadow-float);

  --status-watch: var(--warn);
  --status-watch-dim: var(--warn-dim);
  --status-critical: var(--alert);
  --status-critical-dim: var(--alert-dim);

  --gradient-primary: linear-gradient(135deg, var(--accent), var(--accent-hi));
  --gradient-soft: linear-gradient(135deg, var(--accent-dim), var(--accent-wash));
  --gradient-dark-glow: radial-gradient(circle at 50% 0%, var(--accent-glow), transparent 70%);

  --text-main: var(--text);
  --text-muted: var(--muted);
  --text-light: var(--text);
  --text-dim: var(--muted);

  --border-light: var(--border);
  --border-dark: var(--border);
  --border-glow: var(--accent-line);

  --shadow-brand: 0 8px 24px rgba(0, 0, 0, 0.5);
  --font-mono: 'Geist Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
}

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */
* { margin: 0; padding: 0; box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 6.5rem;
  background: var(--canvas);
  /* Was `dark`, left over from the near-black design. On a paper site it
     renders native scrollbars, form controls and the overscroll rubber-band
     gutter dark, so the page had a black edge above the nav and below the
     footer on macOS and iOS. */
  color-scheme: light;
}

/* --------------------------------------------------------------------------
   PAGE BACKDROP
   One fixed layer behind everything, driven by --page-progress. Sections paint
   translucent grounds over it, so scrolling moves light through the whole page
   rather than lighting each section separately. No JS: the progress value is
   already published to :root by the scroll bus.
   -------------------------------------------------------------------------- */
html::before {
  content: '';
  position: fixed;
  inset: -10vh -10vw;
  z-index: -2;
  pointer-events: none;
  --p: var(--page-progress, 0);
  /* Three blooms at 0.220-0.385 alpha. Those numbers were lifts on a
     near-black ground; repointed at rgba(17,17,17,...) over paper they are
     smears, and they cost a full-viewport blur(30px) every frame. Same idea,
     survivable alpha, and no blur filter -- the gradients are already soft.
     Stays achromatic: per the file header the backdrop is "a faint lift in the
     black, never a wash of colour", and the warmth belongs to the paper. */
  background:
    radial-gradient(72vw 60vw at calc(18% + var(--p) * 34%) calc(4% + var(--p) * 30%),
                    rgba(17, 17, 17, 0.028), transparent 68%),
    radial-gradient(64vw 56vw at calc(84% - var(--p) * 40%) calc(82% - var(--p) * 34%),
                    rgba(17, 17, 17, 0.020), transparent 66%);
}

/* A hairline grid that is always present, so no section is ever flat black.
   It drifts a little over the full scroll rather than animating on a timer.

   This is the ONLY grid on the site. There used to be a second one, .grid-canvas
   at 56px, absolutely positioned inside the hero. 56 and 76 share no useful
   factor and one scrolled while the other did not, so where they overlapped they
   produced an interference pattern that moved as you scrolled. */
html::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -3;
  pointer-events: none;
  /* Column guides, not a blueprint grid.
     This layer used to be a 76px square grid at rgba(17,17,17,0.413) — a 41%
     black hairline. That alpha was a faint lift on the old near-black ground;
     on paper it is a hard dark grid, and 76px shared no factor with anything
     in the layout, so the lines never landed on a column. Two changes: the
     weight drops to something a warm ground can carry, and the horizontal
     lines go entirely. A square grid reads as a dashboard; vertical guides at
     the real column pitch read as a typeset page, which is the brand.
     The tile is exactly one wrap wide and centred, so the twelve lines sit on
     the twelve column starts at every viewport width. Fixed, so the guides run
     unbroken from the hero to the footer and no section seam interrupts them. */
  background-image: var(--col-guides);
  background-size: var(--wrap-w) 100%;
  background-repeat: no-repeat;
  background-position: center top;
  mask-image: linear-gradient(180deg, transparent, #000 14%, #000 86%, transparent);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 14%, #000 86%, transparent);
}

/* Paper tooth. One fixed layer for the whole document rather than a per-section
   .grain, so the texture is continuous across every ground and never restarts
   at a seam. Sits above content but takes no pointer events. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 400;
  pointer-events: none;
  opacity: 0.030;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

body {
  background-color: transparent;
  color: var(--text);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.7;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* The ladder. Weight and tracking carry the hierarchy, so the thin end of the
   axis is reserved for large display sizes and never reaches body copy. */
h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  color: var(--text);
  text-wrap: balance;
}
h1 { font-weight: 200; line-height: 1.02; letter-spacing: var(--track-xl); }
h2 { font-weight: 300; line-height: 1.08; letter-spacing: var(--track-lg); }
h3 { font-weight: 500; line-height: 1.2;  letter-spacing: var(--track-md); }
h4, h5 { font-weight: 600; line-height: 1.3; letter-spacing: -0.01em; }

/* The bold end of the axis, for emphasis inside running text. */
strong, b { font-weight: 700; }

p { text-wrap: pretty; }

img, svg, video { max-width: 100%; display: block; }

::selection { background: var(--accent); color: var(--canvas); }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--canvas); }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: var(--r-pill); border: 2px solid var(--canvas); }
::-webkit-scrollbar-thumb:hover { background: var(--muted); }

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

.skip-link {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -140%);
  z-index: 2000;
  background: var(--accent);
  color: var(--canvas);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.75rem 1.5rem;
  border-radius: 0;
  text-decoration: none;
  transition: transform 0.25s var(--ease-out);
}
.skip-link:focus { transform: translate(-50%, 0); }

.container { max-width: 1240px; margin: 0 auto; padding: 0 2rem; }
.container-narrow { max-width: 880px; margin: 0 auto; padding: 0 2rem; }
.section { padding: var(--space-8) 0; position: relative; }
.section-sm { padding: var(--space-7) 0; position: relative; }

/* Ground shifts between sections so the page reads in movements. */
.on-canvas { background: rgba(8, 10, 11, 0.70); }
.on-deep   { background: rgba(3, 5, 7, 0.78); }
.on-gray   { background: rgba(16, 22, 25, 0.68); }
.on-surface{ background: var(--surface); }
.ruled-top { border-top: 1px solid var(--border); }
.ruled-btm { border-bottom: 1px solid var(--border); }

/* ==========================================================================
   MOTION ENGINE
   Everything here animates transform/opacity/filter only. The `.js` gate
   means a no-JS visitor gets fully visible content, never a blank page.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Entrance reveals.

   Two families. The translate variants move an element a short distance in
   place. The `in-*` and `mask-*` variants travel further and arrive behind a
   mask, so the element reads as moving INTO frame rather than fading up where
   it already sat : which is the difference between a page that animates and a
   page that feels shot.
   -------------------------------------------------------------------------- */
.js [data-reveal] {
  opacity: 0;
  transition:
    opacity 0.85s var(--ease-out),
    transform 0.85s var(--ease-out),
    clip-path 0.9s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms);
  will-change: opacity, transform;
}
.js [data-reveal="up"]    { transform: translate3d(0, 42px, 0); }
.js [data-reveal="down"]  { transform: translate3d(0, -28px, 0); }
.js [data-reveal="left"]  { transform: translate3d(-46px, 0, 0); }
.js [data-reveal="right"] { transform: translate3d(46px, 0, 0); }
.js [data-reveal="scale"] { transform: scale(0.93); }
.js [data-reveal="fade"]  { transform: none; }
.js [data-reveal="clip"]  { clip-path: inset(0 100% 0 0); opacity: 1; }
.js [data-reveal="rise"]  { transform: translate3d(0, 100%, 0); }

/* Arrives from beyond the frame edge. The mask travels with the element, so
   nothing is visible until it has crossed into view. */
.js [data-reveal="in-left"] {
  transform: translate3d(-14vw, 0, 0);
  clip-path: inset(0 0 0 100%);
  opacity: 1;
}
.js [data-reveal="in-right"] {
  transform: translate3d(14vw, 0, 0);
  clip-path: inset(0 100% 0 0);
  opacity: 1;
}
/* A wipe from the baseline up. Pairs with data-split for line-by-line. */
.js [data-reveal="mask-up"] {
  clip-path: inset(100% 0 0 0);
  transform: translate3d(0, 14px, 0);
  opacity: 1;
}
.js [data-reveal="mask-down"] {
  clip-path: inset(0 0 100% 0);
  transform: translate3d(0, -14px, 0);
  opacity: 1;
}

/* The travelling variants need longer to read as a move rather than a jump. */
.js [data-reveal^="in-"],
.js [data-reveal^="mask-"] {
  transition-duration: 1.15s;
}

.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0);
  will-change: auto;
}

/* --------------------------------------------------------------------------
   Contents perform.

   The frame holds still and the things inside it arrive in order, which is
   what makes a product visual read as software running rather than as a
   picture of software. Put [data-cast] and [data-stagger] on the container:
   the stagger writes --i onto each child (initReveals already does this for
   every [data-stagger] on the page), and this turns that index into a beat.

   Sequenced to start AFTER the frame has landed, hence the lead.
   -------------------------------------------------------------------------- */
.js [data-cast] > * {
  opacity: 0;
  transform: translate3d(var(--cast-x, 0), var(--cast-y, 14px), 0);
  transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out);
  transition-delay: calc(var(--cast-lead, 260ms) + var(--i, 0) * var(--cast-step, 120ms));
}
/* Lit either by an ancestor frame revealing, or by the container itself. */
.js [data-reveal].is-in [data-cast] > *,
.js [data-cast].is-in > *,
.js .is-active [data-cast] > * {
  opacity: 1;
  transform: none;
}

/* Legacy `.reveal` from the previous build still works. */
.js .reveal { opacity: 0; transform: translateY(40px); transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out); }
.js .reveal.active, .js .reveal.is-in { opacity: 1; transform: none; }

/* Word-level headline stagger. JS splits the text into .word spans. */
.js .split-line { display: block; overflow: hidden; }
.js .word {
  display: inline-block;
  transform: translate3d(0, 105%, 0);
  transition: transform 0.9s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 45ms);
}
.js [data-reveal].is-in .word,
.js .split.is-in .word { transform: none; }

/* Depth. Three planes drifting at different rates off the same --sp value, so
   a section has foreground and background rather than one flat layer. */
.depth-near { transform: translate3d(0, calc(var(--sp, 0) * -46px), 0); }
.depth-mid  { transform: translate3d(0, calc(var(--sp, 0) * -24px), 0); }
.depth-far  { transform: translate3d(0, calc(var(--sp, 0) *  18px), 0); }

/* --------------------------------------------------------------------------
   2. Scroll scrubbing : JS writes --sp (0 -> 1) as the element crosses the
   viewport. Everything downstream is pure CSS reading that one number.
   -------------------------------------------------------------------------- */
[data-scrub] { --sp: 0; }

/* A rule that draws itself left-to-right as you scroll past it. */
.draw-line {
  transform: scaleX(var(--sp, 0));
  transform-origin: left center;
  will-change: transform;
}
.draw-line-y { transform: scaleY(var(--sp, 0)); transform-origin: top center; }

/* Slow drift for atmosphere layers. */
.parallax { transform: translate3d(0, calc(var(--sp, 0) * -70px), 0); }
.parallax-soft { transform: translate3d(0, calc(var(--sp, 0) * -34px), 0); }

/* --------------------------------------------------------------------------
   3. Aurora : the colourful ground behind hero and CTA sections.
   Layered radial blooms on a transform-animated layer, plus SVG grain.
   -------------------------------------------------------------------------- */
.aurora {
  position: absolute;
  inset: -20% -10%;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.aurora::before,
.aurora::after {
  content: '';
  position: absolute;
  filter: blur(90px);
  opacity: 0.5;
  will-change: transform;
}
.aurora::before {
  width: 46vw;
  height: 46vw;
  min-width: 380px;
  min-height: 380px;
  top: -8%;
  left: 8%;
  background: radial-gradient(circle, rgba(17, 17, 17, 0.072), transparent 66%);
  animation: auroraDriftA 22s cubic-bezier(0.45, 0, 0.55, 1) infinite alternate;
}
.aurora::after {
  width: 38vw;
  height: 38vw;
  min-width: 320px;
  min-height: 320px;
  bottom: -12%;
  right: 4%;
  background: radial-gradient(circle, rgba(17, 17, 17, 0.055), transparent 68%);
  animation: auroraDriftB 28s cubic-bezier(0.45, 0, 0.55, 1) infinite alternate;
}
/* Third bloom, cooler and slower, so the field never reads as a single blob. */
.aurora > i {
  position: absolute;
  top: 28%;
  left: 46%;
  width: 34vw;
  height: 34vw;
  min-width: 300px;
  min-height: 300px;
  background: radial-gradient(circle, rgba(17, 17, 17, 0.330), transparent 70%);
  filter: blur(100px);
  opacity: 0.42;
  animation: auroraDriftC 34s cubic-bezier(0.45, 0, 0.55, 1) infinite alternate;
  will-change: transform;
}
@keyframes auroraDriftC {
  from { transform: translate3d(-10%, 6%, 0) scale(0.9); }
  to   { transform: translate3d(12%, -12%, 0) scale(1.25); }
}
@keyframes auroraDriftA {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(14%, 10%, 0) scale(1.18); }
}
@keyframes auroraDriftB {
  from { transform: translate3d(0, 0, 0) scale(1.1); }
  to   { transform: translate3d(-16%, -8%, 0) scale(0.9); }
}

/* A bloom that rises as you scroll into a section. */
.aurora-rise {
  position: absolute;
  left: 50%;
  bottom: -14%;
  width: 130%;
  height: 72%;
  transform: translate3d(-50%, calc((1 - var(--sp, 0)) * 26%), 0);
  background: radial-gradient(ellipse at 50% 100%, rgba(17, 17, 17, 0.248), transparent 64%);
  filter: blur(110px);
  opacity: calc(0.25 + var(--sp, 0) * 0.35);
  pointer-events: none;
  z-index: 0;
}

/* Grain : SVG fractal noise, no image request. */
.grain::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.035;
  mix-blend-mode: overlay;
  /* The feColorMatrix is load-bearing. feTurbulence generates independent R, G
     and B channels, so without desaturating it the grain is coloured speckle,
     and `overlay` then pushes that colour into the ground. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   4. Marquee : seamless 50% translate, pauses on hover, masked at the edges.
   -------------------------------------------------------------------------- */
.marquee {
  overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee 34s linear infinite;
  will-change: transform;
}
.marquee:hover .marquee-track,
.marquee:focus-within .marquee-track { animation-play-state: paused; }
@keyframes marquee {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* --------------------------------------------------------------------------
   5. Ambient signals
   -------------------------------------------------------------------------- */
/* A 4px square that breathes in opacity. No expanding halo. */
.pulse-dot {
  position: relative;
  width: 4px;
  height: 4px;
  background: var(--accent);
  flex-shrink: 0;
}
.pulse-dot::after {
  content: '';
  position: absolute;
  inset: -3px;
  border: 1px solid currentColor;
  color: var(--accent);
  opacity: 0.35;
  animation: pulseRing 2.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.pulse-dot.alert::after { color: var(--alert); }
.pulse-dot.warn::after  { color: var(--warn); }
@keyframes pulseRing {
  0%, 100% { opacity: 0.12; }
  50%      { opacity: 0.45; }
}
.pulse-dot.alert { background: var(--alert); }
.pulse-dot.warn  { background: var(--warn); }

/* Numbers driven by data-countup. Tabular so they never reflow while ticking. */
.num, [data-countup] {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ==========================================================================
   NAVIGATION. floating dark-glass pill with a scroll-progress hairline
   ========================================================================== */
.site-nav {
  position: fixed;
  top: 1.25rem;
  left: 50%;
  width: calc(100% - 3rem);
  max-width: 1180px;
  z-index: 1000;
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md);
  transform: translate3d(-50%, 0, 0);
  transition: transform 0.4s var(--ease-out), box-shadow 0.3s ease, background-color 0.3s ease;
}
.site-nav.is-scrolled { background: rgba(255, 255, 255, 0.92); }
.site-nav.is-scrolled {
  box-shadow: var(--shadow-float), 0 0 0 1px var(--border-soft);
}
/* Hides on scroll-down, returns on scroll-up. */
.site-nav.is-hidden { transform: translate3d(-50%, calc(-100% - 1.5rem), 0); }

/* Reading-progress hairline hugging the bottom of the pill. */
.nav-progress {
  position: absolute;
  left: 1.25rem;
  right: 1.25rem;
  bottom: 0;
  height: 1.5px;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--accent), var(--accent-hi));
  transform: scaleX(var(--page-progress, 0));
  transform-origin: left center;
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.site-nav.is-scrolled .nav-progress { opacity: 1; }

.nav-inner {
  padding: 0.6rem 0.7rem 0.6rem 1.25rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

.logo {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 1.05rem;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  letter-spacing: -0.04em;
  flex-shrink: 0;
  transition: opacity 0.2s ease;
}
.logo:hover { opacity: 0.72; }
.logo:active { transform: translateY(1px); }

/* The G7 mark. Lives here, not in landing.css, because the nav and footer
   partials are on every page. */
.logo-mark {
  width: 21px;
  height: auto;
  color: var(--mint);
  flex-shrink: 0;
  display: block;
}
.footer-brand .logo-mark { width: 24px; }

.nav-links { display: flex; gap: 1.75rem; align-items: center; list-style: none; }
.nav-links a {
  text-decoration: none;
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  white-space: nowrap;
  position: relative;
  transition: color 0.22s ease;
}
.nav-links a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -6px;
  width: 100%;
  height: 1.5px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.32s var(--ease-out);
}
.nav-links a:hover { color: var(--text); }
.nav-links a:hover::after { transform: scaleX(1); }
.nav-links a[aria-current="page"],
.nav-links a.is-active { color: var(--text); }
.nav-links a[aria-current="page"]::after,
.nav-links a.is-active::after { transform: scaleX(1); }

.nav-actions { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; }

.nav-toggle {
  display: none;
  width: 40px;
  height: 40px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--input);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 5px;
  flex-shrink: 0;
  transition: background-color 0.2s ease, transform 0.15s ease;
}
.nav-toggle:hover { background: var(--border); }
.nav-toggle:active { transform: scale(0.94); }
.nav-toggle span {
  display: block;
  width: 15px;
  height: 1.5px;
  background: var(--text);
  transition: transform 0.3s var(--ease-out), opacity 0.2s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

.nav-drawer {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 999;
  background: rgba(5, 6, 7, 0.7);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.28s ease;
}
.nav-drawer.is-open { opacity: 1; pointer-events: auto; }
.nav-drawer-panel {
  position: absolute;
  top: 0;
  right: 0;
  width: min(340px, 86vw);
  height: 100%;
  background: var(--surface);
  border-left: 1px solid var(--border);
  padding: 6rem 1.75rem 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  box-shadow: -20px 0 60px rgba(0, 0, 0, 0.6);
  transform: translateX(100%);
  transition: transform 0.35s var(--ease-out);
  overflow-y: auto;
}
.nav-drawer.is-open .nav-drawer-panel { transform: translateX(0); }
.nav-drawer-panel > a:not(.btn) {
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--text);
  text-decoration: none;
  padding: 0.9rem 0.25rem;
  border-bottom: 1px solid var(--border);
  transition: color 0.2s ease, transform 0.25s var(--ease-out);
}
.nav-drawer-panel > a:not(.btn):hover { color: var(--accent); transform: translateX(6px); }
.nav-drawer-panel .btn { margin-top: 1.5rem; width: 100%; }
.nav-drawer-contact {
  margin-top: auto;
  padding-top: 2rem;
  font-family: var(--font-body);
  font-size: 0.78rem;
  color: var(--muted);
  line-height: 2;
}
.nav-drawer-contact a { color: var(--muted); text-decoration: none; border-bottom: 1px solid var(--border); }
.nav-drawer-contact a:hover { color: var(--accent); }

body.nav-open { overflow: hidden; }

/* ==========================================================================
   BUTTONS
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.95rem 1.85rem;
  text-decoration: none;
  cursor: pointer;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  gap: 0.55rem;
  line-height: 1.2;
  text-align: center;
  position: relative;
  transition:
    transform 0.25s var(--ease-out),
    box-shadow 0.25s var(--ease-out),
    background-color 0.25s ease,
    color 0.2s ease,
    border-color 0.2s ease,
    opacity 0.2s ease;
}
.btn-primary {
  background: var(--accent);
  color: var(--canvas);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}
.btn-primary:hover {
  background: var(--accent-hi);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
}
.btn-primary:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); }

.btn-secondary {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border);
}
.btn-secondary:hover { background: var(--input); transform: translateY(-2px); border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.btn-secondary:active { transform: translateY(0); box-shadow: none; }

.btn-ghost { background: transparent; color: var(--muted); border-color: var(--border); }
.btn-ghost:hover { color: var(--text); border-color: var(--accent-line); transform: translateY(-2px); }
.btn-ghost:active { transform: translateY(0); }

/* Kept as aliases so older markup keeps working. */
.btn-on-dark { background: var(--surface); color: var(--text); border-color: var(--border); }
.btn-on-dark:hover { background: var(--input); transform: translateY(-2px); border-color: var(--border-strong); }
.btn-on-dark:active { transform: translateY(0); }

.btn-sm { padding: 0.6rem 1.25rem; font-size: 0.7rem; }
.btn-lg { padding: 1.1rem 2.4rem; font-size: 0.85rem; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.5; pointer-events: none; }

/* ==========================================================================
   SHARED PRIMITIVES
   ========================================================================== */


.lede { font-size: 1.05rem; color: var(--muted); line-height: 1.75; max-width: 62ch; font-weight: 300; }
.hairline { height: 1px; background: var(--border); border: 0; }

/* The two-tone statement. The claim and the sentence that elaborates it are one
   block at one size, and the elaboration is simply greyer. That collapses a
   heading and its standfirst into a single element, which is a whole layer of
   hierarchy the page no longer has to render. Both halves live inside the real
   <h2>, so the document outline is unchanged. */
.statement {
  font-family: var(--font-display);
  font-size: var(--h2-size);
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: var(--track-lg);
  /* Measured in em, not ch: Manrope's zero is narrow enough that a ch-based
     measure ran the statement to the full container and it read as a
     paragraph rather than as a statement. */
  max-width: 16em;
  margin-bottom: var(--space-6);
  text-wrap: pretty;
}
.statement > span { color: var(--muted); }
.statement.is-wide { max-width: 19em; }

/* A short mono label sitting above a figure or a column, the way a plate number
   sits above a diagram. Small, spaced, and never coloured. */
.fig-k {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: var(--track-data);
  text-transform: uppercase;
  color: var(--muted-dim);
}
.mono-note { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted-dim); }

/* ==========================================================================
   FORMS
   ========================================================================== */
.field { display: flex; flex-direction: column; gap: 0.45rem; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }

.field label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
}
.field .hint { font-size: 0.78rem; color: var(--muted-dim); line-height: 1.5; }
.field .req { color: var(--accent); }

.input, .select, .textarea {
  width: 100%;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 0.95rem;
  color: var(--text);
  background: var(--input);
  border: 1px solid var(--border);
  padding: 0.85rem 1rem;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}
.input::placeholder, .textarea::placeholder { color: var(--muted-dim); }
.input:hover, .select:hover, .textarea:hover { border-color: var(--border-strong); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-dim);
}
.textarea { min-height: 140px; resize: vertical; line-height: 1.65; }
.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238C9AAE' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  padding-right: 2.5rem;
}

.field .error-text { font-size: 0.78rem; font-weight: 400; color: var(--alert); display: none; }
.field.has-error .input,
.field.has-error .select,
.field.has-error .textarea { border-color: var(--alert); box-shadow: 0 0 0 3px var(--alert-dim); }
.field.has-error .error-text { display: block; }

.form-note { font-size: 0.8rem; color: var(--muted-dim); text-align: center; line-height: 1.6; }

.form-success { display: none; text-align: center; padding: 1rem 0 0.5rem; }
.form-success.is-visible { display: block; animation: successIn 0.55s var(--ease-out) both; }
@keyframes successIn {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: none; }
}
.form-success .tick {
  width: 54px;
  height: 54px;
  margin: 0 auto 1.25rem;
  border-radius: var(--r-pill);
  background: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--canvas);
  font-size: 1.4rem;
}

/* ==========================================================================
   FOOTER
   ========================================================================== */
.site-footer {
  background: var(--canvas-deep);
  color: var(--muted);
  padding: 5rem 0 2rem;
  border-top: 1px solid var(--border);
  font-size: 0.9rem;
  position: relative;
  overflow: hidden;
}
.site-footer::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -60%;
  width: 90%;
  height: 120%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 50% 100%, rgba(17, 17, 17, 0.165), transparent 60%);
  pointer-events: none;
}
.footer-grid {
  position: relative;
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: 3rem;
  padding-bottom: 3rem;
}
.footer-brand .logo { color: var(--text); margin-bottom: 1rem; }
.footer-blurb { color: var(--muted); font-size: 0.88rem; line-height: 1.75; max-width: 32ch; font-weight: 300; }
.footer-contact { margin-top: 1.5rem; display: flex; flex-direction: column; gap: 0.45rem; font-family: var(--font-mono); font-size: 0.8rem; }
.footer-contact a { color: var(--muted); text-decoration: none; transition: color 0.2s ease; }
.footer-contact a:hover { color: var(--accent); }

.footer-col h4 {
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--muted-dim);
  margin-bottom: 1.25rem;
}
.footer-col ul { list-style: none; display: flex; flex-direction: column; gap: 0.7rem; }
.footer-col a {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.88rem;
  transition: color 0.2s ease, transform 0.25s var(--ease-out);
  display: inline-block;
}
.footer-col a:hover { color: var(--accent); transform: translateX(3px); }

.footer-bottom {
  position: relative;
  border-top: 1px solid var(--border);
  padding-top: 1.75rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  font-family: var(--font-body);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--muted-dim);
}
.footer-social { display: flex; gap: 0.6rem; }
.footer-social a {
  width: 34px;
  height: 34px;
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  transition: color 0.2s ease, border-color 0.2s ease, transform 0.25s var(--ease-out);
}
.footer-social a:hover { color: var(--accent); border-color: var(--accent-line); transform: translateY(-2px); }
.footer-social a:active { transform: translateY(0); }
.footer-social svg { width: 15px; height: 15px; }

/* ==========================================================================
   ACCORDION. sub-agent list and FAQ
   ========================================================================== */
.accordion-list { display: flex; flex-direction: column; border-top: 1px solid var(--border); }
.accordion-item { border-bottom: 1px solid var(--border); }

.accordion-trigger {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1.5rem;
  padding: 1.6rem 0;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 300;
  letter-spacing: -0.03em;
  color: var(--muted);
  line-height: 1.3;
  transition: color 0.25s ease;
}
.accordion-trigger:hover { color: var(--text); }
.accordion-title { transition: transform 0.25s var(--ease-out); display: block; }
.accordion-trigger:active .accordion-title { transform: translateX(2px); }
.accordion-item.is-open .accordion-trigger { color: var(--text); }

.accordion-icon { position: relative; width: 16px; height: 16px; flex-shrink: 0; }
.accordion-icon::before,
.accordion-icon::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 1.5px;
  background: var(--muted-dim);
  transition: transform 0.4s var(--ease-out), background-color 0.25s ease;
}
.accordion-icon::before { transform: translateY(-50%); }
.accordion-icon::after { transform: translateY(-50%) rotate(90deg); }
.accordion-trigger:hover .accordion-icon::before,
.accordion-trigger:hover .accordion-icon::after,
.accordion-item.is-open .accordion-icon::before,
.accordion-item.is-open .accordion-icon::after { background: var(--accent); }
.accordion-item.is-open .accordion-icon::after { transform: translateY(-50%) rotate(0deg); }

.accordion-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.45s var(--ease-out);
}
.accordion-item.is-open .accordion-panel { grid-template-rows: 1fr; }
.accordion-panel > * { overflow: hidden; min-height: 0; }
.accordion-panel-inner { max-width: 64ch; }
.accordion-panel-inner > *:last-child { margin-bottom: 1.85rem; }
.accordion-panel-inner p { color: var(--muted); font-size: 0.95rem; line-height: 1.75; margin-bottom: 1rem; font-weight: 300; }
.accordion-panel-inner ul { list-style: none; display: flex; flex-direction: column; gap: 0.7rem; }
.accordion-panel-inner li { position: relative; padding-left: 1.4rem; color: var(--muted); font-size: 0.9rem; line-height: 1.65; font-weight: 300; }
.accordion-panel-inner li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: var(--r-pill);
  background: var(--accent);
}
.accordion-list.on-light { border-top-color: var(--border); }
.accordion-list.on-light .accordion-item { border-bottom-color: var(--border); }

/* ==========================================================================
   LONG-FORM / LEGAL
   ========================================================================== */
.prose { max-width: 72ch; }
.prose h2 { font-size: 1.5rem; margin: 3rem 0 1rem; scroll-margin-top: 7rem; }
.prose h2:first-child { margin-top: 0; }
.prose h3 { font-size: 1.05rem; margin: 2rem 0 0.6rem; }
.prose p { margin-bottom: 1.1rem; color: var(--muted); }
.prose ul, .prose ol { margin: 0 0 1.25rem 1.25rem; color: var(--muted); }
.prose li { margin-bottom: 0.55rem; }
/* The underline is the identifier, not the colour: at this luminance an
   accent-coloured link is only a shade off the body text around it. */
.prose a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { color: var(--accent-hi); text-decoration-thickness: 2px; }
.prose strong { color: var(--text); font-weight: 500; }

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width: 900px) {
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 2.5rem; }
  .footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 860px) {
  .nav-links { display: none; }
  .nav-actions .btn { display: none; }
  .nav-toggle { display: flex; }
  .nav-drawer { display: block; }
  .nav-inner { padding: 0.55rem 0.55rem 0.55rem 1.1rem; }
}
@media (max-width: 640px) {
  :root { --space-8: 4.5rem; --space-7: 3.25rem; }
  .container, .container-narrow { padding: 0 1.25rem; }
  .site-nav { top: 0.75rem; width: calc(100% - 1.5rem); }
  .logo { font-size: 0.98rem; }
  .field-row { grid-template-columns: 1fr; }
  .btn { width: 100%; }
  .btn-lg { font-size: 0.78rem; padding: 1rem 1.5rem; }
  .footer-grid { grid-template-columns: 1fr; gap: 2.25rem; }
  .footer-bottom { flex-direction: column; align-items: flex-start; }
  .site-footer { padding: 3.5rem 0 1.5rem; }
  .accordion-trigger { font-size: 1rem; gap: 1rem; padding: 1.25rem 0; }
  .aurora::before, .aurora::after { filter: blur(60px); }
}

/* ==========================================================================
   MOTION PREFERENCES. one global escape hatch, no exceptions
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }
  /* Every progressive-enhancement hidden state resolves to fully visible. */
  .js [data-reveal],
  .js .reveal {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }
  .js .word { transform: none !important; }
  /* The two choreography mechanisms hide their subjects until a class lands.
     Both have to resolve to visible here, or the hero rail and every product
     visual render empty under reduced motion. */
  .js [data-cast] > *,
  .js .hero-rail > * { opacity: 1 !important; transform: none !important; }
  .draw-line, .draw-line-y { transform: none !important; }
  .parallax, .parallax-soft { transform: none !important; }
  .depth-near, .depth-mid, .depth-far { transform: none !important; }
  .drift { --settle: 1 !important; }
  .drift-field span { animation: none !important; }
  .meter > i { transform: scaleX(var(--fill, 1)) !important; }
  .aurora-rise { transform: translateX(-50%) !important; opacity: 0.5 !important; }
  .marquee-track { animation: none !important; }
  .pulse-dot::after { animation: none !important; opacity: 0 !important; }
  .nav-drawer-panel { transition: none; }
  .site-nav.is-hidden { transform: translate3d(-50%, 0, 0) !important; }
}

/* ==========================================================================
   COMPONENTS ADAPTED FROM 21st.dev / Magic UI
   Ported from React + Tailwind to vanilla CSS, re-tinted to the bone accent
   (the aurora and background paths keep the mint, being backdrop), and given
   reduced-motion guards. Technique credited in each block.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Background Paths. 21st.dev. Slow-drifting stroked curves. Pure SVG,
   animated with stroke-dashoffset so nothing reflows.
   -------------------------------------------------------------------------- */
/* Neutral, and much fainter than the mint version: a stroked line reads as
   content in a way a blurred bloom does not, and these cross the CTA heading. */
.bg-paths { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; opacity: 0.22; }
.bg-paths path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1;
  stroke-dasharray: 190 260;
  opacity: 0.5;
  animation: pathRun 14s linear infinite;
}
.bg-paths path:nth-child(2) { animation-duration: 19s; animation-delay: -4s; opacity: 0.28; }
.bg-paths path:nth-child(3) { animation-duration: 24s; animation-delay: -9s; opacity: 0.2; }
@keyframes pathRun {
  from { stroke-dashoffset: 450; }
  to   { stroke-dashoffset: 0; }
}

/* Shimmer sweep across a surface : used on the featured pricing card. */
.sheen { position: relative; overflow: hidden; }
.sheen::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(17, 17, 17, 0.385) 50%, transparent 62%);
  transform: translateX(-100%);
  animation: sheenRun 6.5s cubic-bezier(0.5, 0, 0.2, 1) infinite;
}
@keyframes sheenRun {
  0%, 55% { transform: translateX(-100%); }
  85%, 100% { transform: translateX(100%); }
}

@media (prefers-reduced-motion: reduce) {
  .shiny { animation: none !important; background-image: none !important; }
  .bg-paths path { animation: none !important; }
  .sheen::after { animation: none !important; opacity: 0 !important; }
}

/* A form that cannot deliver must say so. Never hide a failure behind the
   success panel: an applicant who is told it worked does not email instead. */
.form-error {
  margin: var(--space-3) 0 0;
  padding: var(--space-3);
  border: 1px solid var(--alert-line);
  background: var(--alert-dim);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 0.875rem;
  line-height: 1.6;
}
.form-error a { color: var(--alert); }
.form-error:focus-visible { outline: 2px solid var(--alert); outline-offset: 2px; }

/* Approved soft-card system. App unread badges are deliberately excluded. */
.card { background: var(--surface); border: 1px solid var(--card-border);
  border-radius: var(--r-lg); padding: var(--space-4); box-shadow: var(--shadow-md); min-width: 0; }
.card-well { background: var(--canvas-deep); border: 0; border-radius: var(--r-md);
  aspect-ratio: 4 / 3; display: grid; align-content: center; overflow: hidden; }
.card-title { font: var(--w-sub) 1rem/1.4 var(--font-display); letter-spacing: var(--track-md); color: var(--text); }
.card-body { font: .8125rem/1.7 var(--font-body); color: var(--muted); }
.card--dark { background: var(--obsidian); color: var(--canvas); border-color: transparent; box-shadow: none; }
.card--feature { border: 0; box-shadow: var(--shadow-float); transform: scale(1.06); }
.badge:not(.tile > .badge) { display: inline-flex; align-items: center; gap: var(--space-1);
  border-radius: var(--r-pill); background: var(--surface); color: var(--muted);
  padding: .5rem .875rem; font: .625rem/1.4 var(--font-mono); letter-spacing: var(--track-data); }
.badge:not(.tile > .badge)::before { content: ''; width: 4px; height: 4px; flex: none;
  border-radius: 50%; background: currentColor; }
@media (max-width: 860px) { .card--feature { transform: none; } }

/* Shared shell and controls: opaque paper, restrained elevation. */
.site-nav, .site-nav.is-scrolled { background: var(--surface); backdrop-filter: none; -webkit-backdrop-filter: none;
 border-radius: var(--r-pill); border-color: var(--card-border); box-shadow: var(--shadow-md); }
.nav-drawer-panel { border-radius: var(--r-lg); }
.input, .textarea, .select { border-radius: var(--r-sm); background-color: var(--canvas-deep); }
.input:hover, .textarea:hover, .select:hover { border-color: var(--border-strong); }
.input:active, .textarea:active, .select:active { border-color: var(--text); }
:where(a, button, summary):focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
a:not(.btn):hover { text-decoration-thickness: 2px; text-underline-offset: .2em; }
a:not(.btn):active { opacity: .7; }
.site-footer .logo { font-family: var(--font-display); }
