
/* ===== BEGIN fonts (Source Serif 4 / Public Sans / IBM Plex Mono, OFL 1.1) =====
   Subsets from brand-v2/fonts, embedded as data: URIs by build.sh. */
@font-face{font-family:"Source Serif 4";font-style:normal;font-weight:300;font-display:swap;src:url("/assets/inline/media/cdf2b72b63792326.woff2") format("woff2")}
@font-face{font-family:"Source Serif 4";font-style:normal;font-weight:400;font-display:swap;src:url("/assets/inline/media/bd9bc27ba5a928d2.woff2") format("woff2")}
@font-face{font-family:"Public Sans";font-style:normal;font-weight:400;font-display:swap;src:url("/assets/inline/media/eb1b9b0565c94804.woff2") format("woff2")}
@font-face{font-family:"Public Sans";font-style:normal;font-weight:500;font-display:swap;src:url("/assets/inline/media/b04a1b7041c31fe4.woff2") format("woff2")}
@font-face{font-family:"Public Sans";font-style:normal;font-weight:600;font-display:swap;src:url("/assets/inline/media/61cd2e2ff98c8e55.woff2") format("woff2")}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url("/assets/inline/media/b6cc822907611633.woff2") format("woff2")}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url("/assets/inline/media/9f807267e7eb436d.woff2") format("woff2")}

/* ===== BEGIN brand-v2/tokens/tokens.css (inlined verbatim by build.sh) ===== */
/* ============================================================================
   FORTOXA — brand tokens, v2
   Source of truth for colour, surface, glass, type, space, radius, elevation
   and motion. Every value carries a role comment: what it is FOR, not just
   what it is.

   v2 IS A LIGHT-GROUND SYSTEM. v1 was #050505 with teal #00E5D1 and Inter /
   JetBrains Mono; all four of those are RETIRED and appear nowhere here.
   Basis: the measured vanta reference (see reference/README.md) plus the
   owner's palette GO in .briefs/brand-v2-owner-go.md. Measured evidence for
   every claim in this file lives in spec.md and work/contrast.json — no number
   in this system is typed by hand.

   Contrast tags are QUALITATIVE on purpose ((AAA), (AA), (LARGE), NON-TEXT
   ONLY): the decimal ratio is measured by tools/contrast.py and printed in
   spec.md and the styleguide, so a moved value can never leave a stale
   decimal behind in a comment.

   Offline by design: this file references no network resource. The v2 web
   fonts are embedded in the page artefact by tools/build_fonts.py and declared
   in fonts.css; this file only names the stacks.
   ========================================================================= */

:root {
  /* ------------------------------------------------------------------ ground
     The light canvas is the v2 default. 49.5% of the reference capture is
     this value; it is not a "paper" texture, it is the page. */
  --ground: #FCFCFA;                 /* role: default page ground, the v2 canvas (AAA base for --ink) */
  --surface: #FFFFFF;                /* role: raised card / sheet on the ground — the ONLY sanctioned pure white */
  --surface-2: #F6F7F9;              /* role: sunken wells, table stripes, inset panels, quiet chips */
  --tint: #F5F0FF;                   /* role: accent-tinted fill — selected rows, quiet accent chips */
  --tint-warm: #F8F4F3;              /* role: warm neutral panel, alternating editorial band */
  --line: #DFDFE9;                   /* role: NON-TEXT — hairlines, dividers, card borders (measured 1.29:1, by design) */
  --line-strong: #C7C7D6;            /* role: NON-TEXT — input borders, rules that must survive a compress thumbnail */

  /* ------------------------------------------------------------------- ink
     The light-ground ink ladder. --faint is the FLOOR: nothing smaller than
     body copy may sit lighter than this. Ratios are measured on --ground. */
  --ink: #181822;                    /* role: primary text, headings, marks on the ground (AAA) */
  --ink-2: #2B2C3F;                  /* role: secondary text, dense UI labels, table heads (AAA) */
  --muted: #484960;                  /* role: supporting copy, captions, table values (AAA) */
  --faint: #6D6E87;                  /* role: smallest meta only — the floor of the ink ladder (AA) */

  /* --------------------------------------------------------------- accent
     Brand accent. #5E05C4 is the reference action purple and the anchor; the
     rest of the ramp exists so hover, pressed, tinted and on-band states stay
     in-palette instead of drifting. */
  --accent: #5E05C4;                 /* role: BRAND ACCENT — links, primary CTA, key data, focus ring (AAA on ground) */
  --accent-hover: #4B049E;           /* role: hover for accent fills and links (AAA on ground) */
  --accent-press: #3A0379;           /* role: pressed state (AAA on ground) */
  --accent-deep: #240642;            /* role: deepest accent fill — CTA on a light band, footer edge (AAA for --on-accent) */
  --accent-soft: #C2BEFF;            /* role: accent ON the dark band, illustration line work, chart series 2 (NON-TEXT on the light ground) */
  --accent-lift: #D8CFFC;            /* role: lavender field / band 2 ground (NON-TEXT; pair with --ink) */
  --accent-100: #EDE4FF;             /* role: accent chips, badge grounds, hover wash on --tint (NON-TEXT; pair with --accent-deep) */
  --accent-bright: #8A3BF0;          /* role: mid stop of --grad-accent only — never a fill, text or border by itself */
  --on-accent: #FFFFFF;              /* role: text and icons ON --accent / --accent-deep fills (AAA) */

  /* -------------------------------------------------------------- dark band
     Full-bleed deep-purple bands and the footer. Not the default ground: the
     reference uses 1–2 of these down a page, plus a lavender band. */
  --band: #260048;                   /* role: full-bleed dark band and footer ground, dark product-UI chrome */
  --band-mid: #4A0A8A;               /* role: mid stop of --grad-band only — never a fill on its own */
  --band-raised: #35105C;            /* role: NON-TEXT — cards and wells sitting on --band (surface lift, below text contrast by design) */
  --band-line: #4A2A6E;              /* role: NON-TEXT — hairlines and chart grid on --band */
  --on-band: #F4F2F5;                /* role: primary text on --band (AAA) */
  --on-band-muted: #B6ACC0;          /* role: secondary text on --band (AAA) */
  --on-band-accent: #C2BEFF;         /* role: accent, links and key data on --band (AAA) */

  /* ---------------------------------------------------------------- signals
     Status colour. The green is 2.23:1 on --ground: it is a FILL, never type,
     unless the darker ink step is used. Amber / red / bronze are fills only. */
  --signal-green: #09C639;           /* role: NON-TEXT FILL — pass, live, healthy chips and dots (2.23:1 on --ground) */
  --signal-green-ink: #067A24;       /* role: the pass signal when it must be TYPE on the ground (AA) */
  --signal-red: #F45B5B;             /* role: NON-TEXT FILL — fail, error, over-budget chips and bars */
  --signal-red-ink: #B02323;         /* role: the fail signal when it must be TYPE on the ground (AA) */
  --signal-amber: #FFBE0F;           /* role: NON-TEXT FILL — warn, pending, in-review (pair with --ink, never type on --ground) */
  --signal-bronze: #C5A27B;          /* role: NON-TEXT FILL — editorial / craft category marker */
  --signal-ink-on-fill: #181822;     /* role: text ON any signal fill (AAA on green, amber and red) */

  /* -------------------------------------------------------------- gradients
     Used sparingly and never on body text: one headline phrase, the CTA, a
     1px card border, the band edge. */
  --grad-accent: linear-gradient(135deg, #5E05C4 0%, var(--accent-bright) 55%, #C2BEFF 100%);
                                     /* role: primary CTA fill, one headline phrase, gradient card border */
  --grad-band: linear-gradient(155deg, #260048 0%, var(--band-mid) 62%, #5E05C4 100%);
                                     /* role: dark band and footer ground — depth without a flat fill */
  --grad-bloom: radial-gradient(58% 62% at 18% 8%, rgba(94,5,196,0.30) 0%, rgba(94,5,196,0) 68%),
                radial-gradient(50% 54% at 88% 22%, rgba(194,190,255,0.62) 0%, rgba(194,190,255,0) 70%);
                                     /* role: hero and section bloom on the light ground — the v2 "light" device */
  --grad-field: linear-gradient(180deg, #D8CFFC 0%, #EDE4FF 100%);
                                     /* role: lavender editorial field, band 2 ground (pair with --ink) */

  /* -------------------------------------------------------------- glass
     The light-ground glass: a frosted WHITE panel over a bloom or a tint, not
     a translucent black one. v1's rgba(255,255,255,.05) fill does not read on
     a light ground and is retired with it. */
  --glass-fill: rgba(255,255,255,0.62);   /* role: floating nav, stat chips, window chrome over colour */
  --glass-line: rgba(24,24,34,0.10);      /* role: 1px glass border */
  --glass-inner: inset 0 1px 0 rgba(255,255,255,0.85); /* role: inner top highlight on glass */
  --glass-blur: 20px;                     /* role: backdrop-filter blur radius for every glass panel */
  --glass-fill-band: rgba(255,255,255,0.08); /* role: glass panel sitting ON --band */
  --glass-line-band: rgba(255,255,255,0.16); /* role: 1px glass border on --band */

  /* ----------------------------------------------------- surfaces on colour
     One wash ladder for anything that sits on the band or on a tinted field:
     a UI shell, its rows, and a hover step. Keeping them as tokens is what
     lets the verifier reject a stray rgba in the page CSS. */
  --wash-1: rgba(255,255,255,0.05);       /* role: NON-TEXT — UI shells, rows and chart fields on --band */
  --wash-2: rgba(255,255,255,0.10);       /* role: NON-TEXT — raised rows and buttons on --band */
  --wash-3: rgba(255,255,255,0.16);       /* role: NON-TEXT — hover step for a wash surface */
  --hairline-soft: rgba(24,24,34,0.10);   /* role: NON-TEXT — 1px outline for chips, plates and swatches on light */
  --grad-panel: radial-gradient(closest-side, rgba(194,190,255,0.42), rgba(194,190,255,0));
                                          /* role: periwinkle bloom inside the hero panel */

  /* -------------------------------------------------------------- elevation
     Restrained on purpose: the reference measures 8px radii and small shadows,
     not a glow on every card. */
  --shadow-card: 0 1px 2px rgba(24,24,34,0.05), 0 12px 32px rgba(24,24,34,0.07);
  --shadow-lift: 0 2px 4px rgba(24,24,34,0.06), 0 28px 64px rgba(38,0,72,0.16);
  --shadow-band: 0 24px 60px rgba(38,0,72,0.28);
  --glow-accent: 0 0 60px rgba(94,5,196,0.22);

  /* ------------------------------------------------------------------ type
     Display is a serif, body a neutral grotesque, mono only for micro-labels
     and data. Inter and JetBrains Mono are RETIRED. */
  --font-display: "Source Serif 4", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
                                     /* role: h1/h2/h3, pull quotes, wordmark */
  --font-body: "Public Sans", "Helvetica Neue", Arial, system-ui, sans-serif;
                                     /* role: body copy, UI text, buttons, labels */
  --font-mono: "IBM Plex Mono", "SFMono-Regular", Menlo, Consolas, monospace;
                                     /* role: micro-labels, token names, data, ratios — never body copy */

  --size-mono-cap: 11px;             /* role: mono micro-label, token name, eyebrow */
  --size-mono: 12px;                 /* role: mono label, table caption, code */
  --size-meta: 13px;                 /* role: meta, figure captions, footnotes */
  --size-small: 14px;                /* role: dense UI text, secondary list items */
  --size-body: 16px;                 /* role: BODY — the reference base size (4188 elements of it) */
  --size-body-lg: 18px;              /* role: lead paragraph, card body on wide screens */
  --size-h4: 20px;                   /* role: card titles, UI section heads */
  --size-h3: 24px;                   /* role: subsection heads, specimen labels */
  --size-h2-sm: 28px;                /* role: h2 on phones */
  --size-h2: 40px;                   /* role: h2 at tablet */
  --size-h2-lg: 56px;                /* role: h2 at desktop (reference: 56px / 61.6 lh, weight 400, ls -2%) */
  --size-display: clamp(48px, 6.2vw, 88px); /* role: h1 (reference: 88px, weight 300, ls -3%) */

  --weight-light: 300;               /* role: display serif — the reference h1 weight */
  --weight-regular: 400;             /* role: body, display serif at h2, wordmark */
  --weight-medium: 500;              /* role: UI emphasis, buttons, table heads */
  --weight-semi: 600;                /* role: card titles, strong labels */
  --weight-bold: 700;                /* role: rare — small-caps section heads on --surface */

  --tracking-display: -0.03em;       /* role: h1 (measured on the reference) */
  --tracking-h2: -0.02em;            /* role: h2 (measured on the reference) */
  --tracking-tight: -0.01em;         /* role: h3/h4 */
  --tracking-caps: 0.08em;           /* role: mono micro-labels in caps — the only positive tracking (0.08em standardised 2026-10-07) */
  --leading-display: 1.02;           /* role: display lines */
  --leading-h2: 1.10;                /* role: 56/61.6 on the reference */
  --leading-body: 1.62;              /* role: body copy — generous, the reference is airy */
  --leading-tight: 1.30;             /* role: UI text, labels */
  --measure: 68ch;                   /* role: maximum line length for body copy */

  /* ------------------------------------------------------------------ form
     Radii, spacing and motion. 8px is the reference's dominant radius (139
     uses); the pill is for chips and badges. */
  --radius-xs: 4px;                  /* role: inline code, mono chips */
  --radius-sm: 8px;                  /* role: buttons, inputs, small cards — the reference default */
  --radius-md: 12px;                 /* role: panels, nested cards */
  --radius-lg: 16px;                 /* role: primary cards, product-UI window */
  --radius-xl: 24px;                 /* role: hero panels, editorial blocks */
  --radius-pill: 999px;              /* role: chips, badges, pills, avatars */

  --space-1: 4px;                    /* role: hairline gaps */
  --space-2: 8px;                    /* role: icon-to-label */
  --space-3: 12px;                   /* role: inside chips */
  --space-4: 16px;                   /* role: inside cards, dense stacks */
  --space-5: 24px;                   /* role: card padding */
  --space-6: 32px;                   /* role: block gaps */
  --space-7: 48px;                   /* role: subsection rhythm */
  --space-8: 64px;                   /* role: section inner padding */
  --space-9: clamp(72px, 8vw, 120px);/* role: SECTION rhythm — the page's main breathing room */
  --space-10: clamp(96px, 11vw, 160px); /* role: hero and closing-band padding */

  --dur-fast: 140ms;                 /* role: hover, focus, colour change */
  --dur-base: 240ms;                 /* role: reveal, translate, panel open */
  --dur-slow: 520ms;                 /* role: hero bloom drift, image settle */
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1); /* role: standard motion curve */
  --ease-inout: cubic-bezier(0.65, 0.05, 0.36, 1); /* role: reversible / looping motion */

  --focus-ring: 0 0 0 3px rgba(94,5,196,0.35); /* role: focus-visible ring on any interactive element */
  --hairline: 1px solid var(--line);           /* role: the standard divider */
}

/* ===== BEGIN page layer - FORTOXA agency site v3 =====
   Built to the FORTOXA fleet design standard v2: a light #FCFCFA ground, one
   deep-purple accent, a serif display face. Everything below is composed from
   the brand tokens above; no page rule carries a colour value of its own, and
   tools/verify.py fails the build if one does. Devices on this page: light
   bloom, glass panels, a real product-UI window on the band, gradient accents,
   depth, staggered motion, one 24x24 icon set, and four type tiers. ===== */
/* ============================================================================
   00-base.css - reset, type roles, shared primitives: shell, buttons, chips,
   glass, tick lists.
   Owner: this file. Values: brand-v2/tokens/tokens.css only - no rule below
   carries a colour, radius, size or motion value of its own. The two page-local
   custom properties are compositions of var()s, which is why verify.py reads
   every literal in this layer and demands it appear in tokens.css.
   ========================================================================= */

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

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

body{
  margin:0;
  color:var(--ink);
  font-family:var(--font-body);
  font-size:var(--size-body);
  font-weight:var(--weight-regular);
  line-height:var(--leading-body);
  -webkit-font-smoothing:antialiased;
  /* The canvas itself carries light. A single flat fill is the v1 failure mode
     this brand was built to avoid, so the ground is a long, quiet tone walk
     (ground -> sunken -> accent tint -> sunken -> warm) with the brand bloom
     laid over the top of the document. Both layers are compositions of token
     values: the stops are var()s, so no literal colour enters the page layer. */
  background-color:var(--ground);
  background-image:
    var(--grad-bloom),
    linear-gradient(180deg,
      var(--ground) 0%, var(--surface-2) 16%, var(--tint) 38%,
      var(--surface-2) 62%, var(--ground) 84%, var(--tint-warm) 100%);
  background-repeat:no-repeat,no-repeat;
  background-position:50% 0,0 0;
  background-size:100% var(--space-10),100% 100%;
}

h1,h2,h3,h4,p,ul,ol,figure,pre{margin:0}
ul,ol{padding:0;list-style:none}
svg{display:block}
img{max-width:100%}

a{color:var(--accent);text-decoration:none}
a:hover{color:var(--accent-hover);text-decoration:underline;text-underline-offset:3px}
::selection{background:var(--accent-lift);color:var(--ink)}
/* The indicator has to survive the components it lands on. The ring below is
   painted by every focusable stop, verified with real Tab key events. The ring
   token itself sits at 35% alpha and measures 2.05:1 against --ground, below the
   3:1 that 1.4.11 asks of a focus indicator, so this rule also sets a solid accent
   outline: 8.91:1 against --ground, and that outline is what carries the
   requirement. Element-qualified selectors outrank a plain class whatever the
   order, so a component rule cannot cancel either property.
   Note for anyone re-measuring this in a headless browser: .btn-primary
   transitions box-shadow, and on a hidden page the document timeline is frozen, so
   getComputedStyle hands back the transition's start value (the resting elevation)
   on that one element even though the ring applied. The probe that resolves it is
   written up in evidence/polish-verify.md. */
a:focus-visible,button:focus-visible,summary:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;
  box-shadow:var(--focus-ring);border-radius:var(--radius-sm)}

/* ---------- shell ---------- */
.wrap{width:100%;max-width:1264px;margin-inline:auto;padding-inline:clamp(18px,4vw,40px)}

/* Off-canvas skip link: moved up out of the viewport, never left/-9999px, so it
   cannot show up as a horizontal overflow. */
.skip{position:absolute;left:0;top:0;z-index:60;transform:translateY(-160%);
  background:var(--surface);color:var(--ink);border:1px solid var(--line-strong);
  border-radius:var(--radius-sm);padding:10px 14px;font-weight:var(--weight-medium)}
.skip:focus{transform:translateY(0)}

/* The icon sprite is inlined so <use href="#id"> resolves; it draws nothing and
   occupies nothing. */
.sprite{position:absolute;width:0;height:0;overflow:hidden}

/* ---------- icons - one grid, one stroke, currentColor ---------- */
.i{width:20px;height:20px;flex:0 0 auto}
.i-sm{width:16px;height:16px}
.i-lg{width:24px;height:24px}

/* ---------- type roles ---------- */
.eyebrow{
  font-family:var(--font-mono);font-size:var(--size-mono-cap);
  font-weight:var(--weight-semi);letter-spacing:var(--tracking-caps);
  text-transform:uppercase;color:var(--accent);display:block;
}
h1{
  font-family:var(--font-display);font-weight:var(--weight-light);
  font-size:var(--size-display);line-height:var(--leading-display);
  letter-spacing:var(--tracking-display);color:var(--ink);
  text-wrap:balance;
}
h2{
  font-family:var(--font-display);font-weight:var(--weight-regular);
  font-size:var(--size-h2-sm);line-height:var(--leading-h2);
  letter-spacing:var(--tracking-h2);color:var(--ink);text-wrap:balance;
}
h3{
  font-family:var(--font-display);font-weight:var(--weight-regular);
  font-size:var(--size-h3);line-height:var(--leading-tight);
  letter-spacing:var(--tracking-tight);color:var(--ink);
}
h4{
  font-family:var(--font-body);font-weight:var(--weight-semi);
  font-size:var(--size-h4);line-height:var(--leading-tight);
  letter-spacing:var(--tracking-tight);color:var(--ink);
}
@media (min-width:760px){ h2{font-size:var(--size-h2)} }
@media (min-width:1100px){ h2{font-size:var(--size-h2-lg)} }

.lede{font-size:var(--size-body-lg);line-height:var(--leading-body);color:var(--muted);max-width:var(--measure)}
.meta{font-size:var(--size-meta);color:var(--muted)}
.small{font-size:var(--size-small);color:var(--muted)}
.mono{font-family:var(--font-mono);font-size:var(--size-mono);letter-spacing:0.01em}

/* The one gradient-accent phrase. A gradient-clipped phrase is invisible to a
   contrast walker (computed colour is transparent), so its stops are listed in
   tools/raw-measurements.json and checked stop by stop against --ground: the
   declared --grad-accent ends on #C2BEFF, which the token file itself marks
   NON-TEXT on a light ground (1.69:1), so this phrase and the primary action
   use --gr-deep instead - same family, every stop >= 5.17:1. */
.grad-text{background:var(--gr-deep);-webkit-background-clip:text;background-clip:text;color:transparent}

:root{
  /* page-local, composition only: not one colour value is introduced here. */
  --gr-deep:linear-gradient(115deg,var(--accent-deep) 0%,var(--accent) 46%,var(--accent-bright) 100%);
  --shell:1264px;
}

/* ---------- actions ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);
  min-height:48px;padding:0 var(--space-5);
  font-family:var(--font-body);font-size:var(--size-body);font-weight:var(--weight-medium);
  line-height:var(--leading-tight);letter-spacing:var(--tracking-tight);
  border-radius:var(--radius-sm);border:1px solid transparent;cursor:pointer;
  transition:transform var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out),
             background-color var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out);
}
.btn:hover{text-decoration:none}
.btn-primary{
  /* background-color is the darkest stop of the gradient on purpose: a gradient
     that failed to paint would still leave 9.14:1 white type, and the contrast
     walker samples this colour rather than guessing at the image. */
  background-color:var(--accent);background-image:var(--gr-deep);
  color:var(--on-accent);box-shadow:var(--shadow-lift);
}
.btn-primary:hover{transform:translateY(-2px);color:var(--on-accent);box-shadow:var(--glow-accent),var(--shadow-lift)}
.btn-glass{
  background-color:var(--glass-fill);background-image:none;
  color:var(--ink);border-color:var(--glass-line);box-shadow:var(--glass-inner);
  backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
}
.btn-glass:hover{transform:translateY(-2px);color:var(--ink);border-color:var(--line-strong)}
.btn-onband{background-color:var(--wash-2);color:var(--on-band);border-color:var(--glass-line-band)}
.btn-onband:hover{background-color:var(--wash-3);color:var(--on-band);transform:translateY(-2px)}
.btn-quiet{background-color:transparent;color:var(--accent);border-color:var(--line-strong);min-height:44px}
.btn-quiet:hover{background-color:var(--tint);color:var(--accent-press)}

/* ---------- glass panel (device: glass, inverted for a light ground) ---------- */
.glass{
  background-color:var(--glass-fill);
  border:1px solid var(--glass-line);
  box-shadow:var(--glass-inner);
  backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
}
/* the same panel sitting on the dark band */
.glass-band{
  background-color:var(--glass-fill-band);
  border:1px solid var(--glass-line-band);
  backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
}

/* ---------- tick lists - the shared "what you get" row ---------- */
.ticks{display:flex;flex-direction:column;gap:var(--space-3);margin-top:var(--space-5)}
.ticks li{display:grid;grid-template-columns:auto minmax(0,1fr);gap:var(--space-3);
  font-size:var(--size-small);line-height:var(--leading-tight);color:var(--ink-2)}
.ticks .i{margin-top:3px;color:var(--accent)}
.ticks strong{color:var(--ink);font-weight:var(--weight-semi)}

/* ---------- chips ---------- */
.chip{
  display:inline-flex;align-items:center;gap:var(--space-2);
  padding:var(--space-1) var(--space-3);border-radius:var(--radius-pill);
  font-family:var(--font-mono);font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;white-space:nowrap;
}
.chip-tint{background-color:var(--tint);color:var(--accent-deep);border:1px solid var(--accent-100)}
.chip-soft{background-color:var(--accent-100);color:var(--accent-deep)}
.chip-onband{background-color:var(--wash-2);color:var(--on-band-accent)}

/* ---------- section rhythm ---------- */
.section{padding-block:var(--space-9)}
.sec-head{display:flex;flex-direction:column;gap:var(--space-4);max-width:var(--measure);margin-bottom:var(--space-8)}
.sec-head .lede{max-width:60ch}

/* ---------- status pips: fills, never type ---------- */
.pip{width:9px;height:9px;border-radius:var(--radius-pill);flex:0 0 auto}
.pip-live{background-color:var(--signal-green)}
.pip-build{background-color:var(--signal-amber)}
.pip-held{background-color:var(--signal-red)}
/* ============================================================================
   10-head.css - the sticky glass header and the brand lockup.
   Device: glass (62% white fill, 1px dark hairline, blur(20px), inner highlight)
   over the page bloom. The mark is the brand's plate + bars, drawn from the v2
   logo geometry (100x100 grid, inset 26, plate radius 24).

   One row at every width. The four sections live in one <nav> inside one
   <details>: on a wide screen the panel is re-opened by CSS alone
   (::details-content), so the row looks exactly as it always has; on a narrow
   screen the summary is the menu control and the panel hangs below the bar.
   No state here needs a script, and a browser that cannot re-open a closed
   panel for the wide layout keeps the wrapped row it had before.
   ========================================================================= */

.site-head{
  position:sticky;top:0;z-index:40;
  background-color:var(--glass-fill);
  border-bottom:1px solid var(--glass-line);
  box-shadow:var(--glass-inner);
  backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
}
.head-row{display:flex;align-items:center;gap:var(--space-5);min-height:72px;flex-wrap:wrap;padding-block:var(--space-2)}

.brand{display:inline-flex;align-items:center;gap:var(--space-3);flex:0 0 auto;min-height:44px;
  color:var(--ink);font-family:var(--font-display);font-size:var(--size-h4);
  font-weight:var(--weight-regular);letter-spacing:var(--tracking-tight)}
.brand:hover{color:var(--ink);text-decoration:none}
.mark{width:32px;height:32px;flex:0 0 auto;border-radius:var(--radius-sm);overflow:hidden}
.mark svg{width:100%;height:100%}

.nav{display:flex;gap:var(--space-5);margin-left:auto;flex-wrap:wrap;justify-content:flex-end}
.nav a{font-size:var(--size-small);font-weight:var(--weight-medium);color:var(--ink-2);
  display:inline-flex;align-items:center;min-height:44px}
.nav a:hover{color:var(--accent)}
.nav a[aria-current]{color:var(--accent)}
.nav a[aria-current]::after{content:"";width:5px;height:5px;border-radius:var(--radius-pill);
  background-color:var(--accent);margin-left:var(--space-2)}
.head-cta{flex:0 0 auto}

/* ---------- the drawer: one nav, one control, no script ---------- */
.nav-drawer{margin-left:auto;min-width:0}
/* wide: the row itself is the nav, so the control is not drawn at all */
.nav-drawer > summary{display:none}
@media (min-width:1024px){
  @supports selector(::details-content){
    .nav-drawer::details-content{content-visibility:visible;display:block}
  }
  /* A browser that cannot re-open a closed panel cannot carry the drawer: the
     bar keeps the wrapped nav row it has always had rather than losing links. */
  @supports not selector(::details-content){
    .nav-drawer{display:contents}
    .nav-drawer > .nav{margin-left:auto}
  }
}

/* The wide row is 127 (brand) + 555 (nav) + 273 (action) + 2 x 24 (row gaps) =
   1003px of content, and the wrap adds 80px of page gutter and a 15px scrollbar
   - so it only holds from 1098px of viewport up. Between 1024 and 1098 the rule
   above wrapped the bar onto a second row: the header measured 133px instead of
   73px and the action sat alone under the brand (the captured live site does the
   same, so this is the site's own defect, not the rebuild's). Trimming the two
   inner gaps inside the measured band - 96px, leaving 22px of slack at 1024 -
   keeps the one row this file's contract promises without moving the drawer
   breakpoint, so no width has to give up its inline nav. */
@media (min-width:1024px) and (max-width:1099px){
  .head-row{gap:var(--space-2)}
  .nav{gap:var(--space-2)}
}

@media (max-width:1023px){
  /* one row: mark, action, menu - the menu control last, where a menu control
     belongs. The panel hangs under the bar, so opening it cannot move anything
     above the fold and nothing above it changes height. */
  .head-row{min-height:60px;flex-wrap:nowrap;gap:var(--space-3);padding-block:var(--space-2)}
  .brand{font-size:var(--size-body-lg);order:1}
  .head-cta{margin-left:auto;order:2}
  .nav-drawer{margin-left:0;flex:0 0 auto;order:3}
  .nav-drawer > summary{display:flex;align-items:center;justify-content:center;
    width:44px;height:44px;flex:0 0 auto;cursor:pointer;
    color:var(--ink);background-color:transparent;
    border:1px solid var(--glass-line);border-radius:var(--radius-sm);
    list-style:none;-webkit-tap-highlight-color:transparent}
  .nav-drawer > summary::-webkit-details-marker{display:none}
  .nav-drawer > summary::marker{content:""}
  .nav-drawer[open] > summary{border-color:var(--ink)}
  .nav-bars{display:block;width:18px;height:18px}
  .nav-bars .i{width:18px;height:18px}
  .nav-drawer > .nav{position:absolute;left:0;right:0;top:100%;margin-left:0;gap:0;
    display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;
    background-color:var(--surface);border-bottom:1px solid var(--glass-line);
    box-shadow:var(--glass-inner);
    padding:var(--space-2) clamp(18px,4vw,40px) var(--space-3)}
  .nav-drawer > .nav a{width:100%;min-height:48px;color:var(--ink);
    border-top:1px solid var(--glass-line)}
  .nav-drawer > .nav a[aria-current]::after{margin-left:auto}
}
@media (max-width:430px){
  /* The action's label ("Book an Architecture Audit", 26 characters) is three
     longer again than the 23-character label this rule was trimmed for, and at
     360px the drawer control was pushed 16px past the viewport (measured:
     scrollWidth 376 against innerWidth 360, offender details.nav-drawer). The
     row's gaps and the button's inline padding are trimmed to the 4px step
     rather than the label or the button's own words: the 44px menu control
     keeps its place at the end of the row and the action keeps every word.
     (letter-spacing is not the lever - .btn carries none - so the width comes
     out of the spacing, not the type.) */
  .head-row{gap:var(--space-1)}
  .head-cta{padding-inline:var(--space-1);font-size:var(--size-meta)}
  .head-cta .i{display:none}
}
/* ============================================================================
   20-hero.css - hero: bloom, announcement pill, display headline, the keyword
   row, the gate field (one slow loop) and the product-UI window on the band.
   Devices: light (bloom), depth (window over the band + a glass chip over the
   window), product UI (rail + trace + code + meter, all real HTML), gradient
   accent (headline phrase, primary action, meter), motion (the gate field).
   Every value below is a var() from brand-v2/tokens.css or a composition of
   one; this layer introduces no colour of its own.
   ========================================================================= */

.hero{position:relative;isolation:isolate;padding-block:var(--space-9);overflow:hidden}

/* Device: light. Two soft radials (the brand's own --grad-bloom) behind the
   headline. The section clips its own decoration: a bloom drawn past the edge
   contributes to the document's scrollWidth, and clipping the ONE decorative
   parent is the honest fix - body{overflow-x:hidden} would fake the
   responsive check instead of passing it. */
.hero::before{
  content:"";position:absolute;z-index:-1;inset:-18% -12% -10% -14%;
  background-image:var(--grad-bloom);pointer-events:none;
}

.hero-grid{display:grid;gap:var(--space-7);grid-template-columns:minmax(0,1fr)}
@media (min-width:1000px){
  .hero-grid{grid-template-columns:minmax(0,0.92fr) minmax(0,1.08fr);align-items:start;gap:var(--space-7)}
}
/* The headline runs the full shell width on every viewport: a long headline at
   the standard's 88px cap in a half-width column wraps to short ragged lines,
   and the mockup needs its rail+pane width more than the headline needs a
   column. Measured line counts per breakpoint: tools/shots/hero-evidence.json
   (reported in design-report.md). */
.hero-head{grid-column:1 / -1;display:flex;flex-direction:column;gap:var(--space-5)}
.hero-copy{display:flex;flex-direction:column;gap:var(--space-6);min-width:0}
/* One short line, seven words: the promise the old lede spent sixty words on. */
.hero-note{font-size:var(--size-body-lg);line-height:var(--leading-body);
  color:var(--muted);max-width:var(--measure)}

.pill{
  display:inline-flex;align-items:center;gap:var(--space-3);width:fit-content;
  max-width:100%;padding:var(--space-2) var(--space-4);
  border-radius:var(--radius-pill);
  background-color:var(--glass-fill);border:1px solid var(--glass-line);
  box-shadow:var(--glass-inner);
  backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
  font-size:var(--size-small);font-weight:var(--weight-medium);color:var(--ink-2);
}
.pulse{position:relative;width:9px;height:9px;border-radius:var(--radius-pill);
  background-color:var(--signal-green);flex:0 0 auto}
.pulse::after{content:"";position:absolute;inset:0;border-radius:var(--radius-pill);
  background-color:var(--signal-green);animation:pulse 2.8s var(--ease-inout) infinite}
@keyframes pulse{
  0%{transform:scale(1);opacity:.7}
  70%{transform:scale(2.7);opacity:0}
  100%{transform:scale(2.7);opacity:0}
}

/* ---------- the keyword row: 5 chips, each a claim and a service line ---------- */
.kws{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-3)}
.kws li{
  display:inline-flex;align-items:center;
  padding:var(--space-2) var(--space-4);border-radius:var(--radius-pill);
  background-color:var(--tint);border:1px solid var(--accent-100);
  font-size:var(--size-small);font-weight:var(--weight-medium);color:var(--accent-deep);
}

/* ============================================================================
   The pipeline field. AMENDED 2026-10-07: five nodes of the platform's
   execution pipeline (trigger -> pipeline orchestration -> agentic execution ->
   human approval gate -> verified action) on the same geometry, replacing the
   six decorative gates that used to echo the build card's rail. Two loops: the SLOW trace (22 s) runs the whole
   path by stroke-dashoffset and each node wakes as the trace's leading edge
   reaches it, and an accent head rides just ahead of it on the SAME 22 s loop,
   so the field reads as live at a glance without a second clock. The base spine is NOT animated, so the field is complete
   and readable with the animation gone (reduced motion, print) or the script
   absent; the loops only ever touch transform, opacity and stroke-dashoffset.
   Geometry: authored in the 1200x160 user space and mapped with
   preserveAspectRatio="none", so node i sits at the centre of cell i of
   .gf-nodes (grid-template-columns:repeat(5,1fr) -> (i+0.5)/5*1200 = 120+240i).
   With "none" a round <circle> would render as an ellipse, so the dots, rings
   and labels are HTML, and every stroke carries non-scaling-stroke.
   Timing: the delays below are the arc-length arrival times of the trace's
   leading edge at each node (t = (fraction - 0.14) * 22 s), and
   tools/hero_probe.js re-derives the fractions from the built page's live path
   with getPointAtLength and asserts they agree. Nothing here is tuned by eye.
   The nodes are content, not decoration: each carries a .gf-spec revealed on
   hover AND on focus, and the SVG above them stays aria-hidden.
   ========================================================================= */
.gfield{
  grid-column:1 / -1;
  /* FULL BLEED. The band breaks its own column: 100vw wide, pulled back to the
     viewport's left edge. The paths already run from x=-240 to x=1460 in the
     1200-unit user space, so at this width the ribbon runs off both edges of the
     SCREEN rather than stopping at the shell - which is the difference between a
     field and a chart. .hero clips the excess, so the document never gains a
     horizontal scrollbar from it. */
  width:100vw;margin-inline:calc(50% - 50vw);
  --gf-h:clamp(110px,12vw,132px);   /* band height; the dot line is 55% down */
  --gf-dot:55%;                     /* y=88 of 160 in the user space */
  position:relative;height:var(--gf-h);
}
/* overflow:visible lets the paths paint outside the band's own box (they are
   drawn to x=-240 and x=1460 in a 1200-wide user space); .hero clips them. */
.gf-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.gf-spine,.gf-echo{fill:none;vector-effect:non-scaling-stroke}
.gf-trace,.gf-glow,.gf-trace-fast{fill:none}
.gf-echo{stroke:var(--accent-soft);stroke-width:1}
.gf-echo-a{stroke-opacity:.9}      /* the ribbon's near line, 22 units above */
.gf-echo-b{stroke-opacity:.6}      /* its far line, 42 units above */
.gf-spine{stroke:var(--accent);stroke-opacity:.38;stroke-width:1.25}
/* The two DASH paths deliberately do NOT carry non-scaling-stroke. A dash whose
   length is measured in the host (screen) space is not scaled the way the path is
   scaled by the non-uniform stretch of preserveAspectRatio="none", and the
   measured consequence was that the trace left the visible field for most of the
   loop at 390px (tools/shots/hero-pixels.json, hero-loop-390-*.png). Keeping the
   dash in USER units makes it a fixed fraction of the path at every width, so the
   loop traverses the path in 22 s at 1440 and at 390 alike. The apparent
   thickness is then kept at ~1.5 px (and the head at 7x that) by setting the
   stroke width in user units against the band's own y-scale - the band is
   clamp(110px,12vw,132px) tall over a 160-unit user space, which is where those
   three numbers come from. */
.gf-trace{stroke:var(--accent);stroke-width:2.2;stroke-dasharray:140 860;
  animation:gf-travel 22s linear infinite}
/* The pulse's soft head: a wider, fainter dash held 35 units ahead of the
   trace's leading edge (35/1000 of 22 s = 0.77 s; 140-35 = 105 -> -2.31 s). */
.gf-glow{stroke:var(--accent);stroke-opacity:.12;stroke-width:10;
  stroke-dasharray:70 930;
  animation:gf-travel 22s linear infinite;animation-delay:-2.31s}
/* The accent head: same keyframes, same user-unit dash rule, and the SAME 22 s
   loop as the trace, so the band has one clock and reads at the tempo the live
   device ships. It rides just ahead of the base head as a brighter, shorter
   highlight. It briefly ran on its own 3.4 s loop (a head every ~3 s); next to
   the 22 s pass that read as a racing line, so it was pulled back onto the loop
   the delays are derived from. */
.gf-trace-fast{stroke:var(--accent);stroke-opacity:.30;stroke-width:5;
  stroke-dasharray:90 910;
  animation:gf-travel 22s linear infinite;animation-delay:-0.6s}
@media (min-width:640px){
  .gf-trace{stroke-width:2.4}
  .gf-glow{stroke-width:11}
}
@media (min-width:1000px){
  .gf-trace{stroke-width:1.8}
  .gf-glow{stroke-width:8.5}
}
@keyframes gf-travel{from{stroke-dashoffset:0}to{stroke-dashoffset:-1000}}

.gf-nodes{position:absolute;inset:0;display:grid;grid-template-columns:repeat(5,1fr)}
.gf-nodes li{position:relative}
.gf-dot{position:absolute;left:50%;top:var(--gf-dot);transform:translate(-50%,-50%);
  width:9px;height:9px;border-radius:var(--radius-pill);background-color:var(--accent)}
.gf-ring{position:absolute;inset:0;border-radius:var(--radius-pill);
  border:1px solid var(--accent);opacity:0;
  animation:gf-wake 22s linear infinite}
/* 1.4% in, 7% out: a 1.2 s flare in a 22 s loop, in step with the trace. */
@keyframes gf-wake{
  0%{opacity:0;transform:scale(1)}
  1.4%{opacity:.6;transform:scale(1.5)}
  7%{opacity:0;transform:scale(2.8)}
  100%{opacity:0;transform:scale(2.8)}
}
/* negative delay = already running, so node i flares when the trace arrives:
   arrival times 1.63 / 4.77 / 7.92 / 11.04 / 14.19 s of the 22 s loop (the
   arc-length fractions 0.2142 / 0.3566 / 0.5000 / 0.6420 / 0.7852 minus the
   0.14 dash lead, times 22 s). tools/hero_probe.js asserts both the delays and
   the geometry they came from. */
.gf-nodes li:nth-child(1) .gf-ring{animation-delay:-1.63s}
.gf-nodes li:nth-child(2) .gf-ring{animation-delay:-4.77s}
.gf-nodes li:nth-child(3) .gf-ring{animation-delay:-7.92s}
.gf-nodes li:nth-child(4) .gf-ring{animation-delay:-11.04s}
.gf-nodes li:nth-child(5) .gf-ring{animation-delay:-14.19s}
.gf-lab{position:absolute;left:0;right:0;top:calc(var(--gf-dot) + 14px);
  display:flex;gap:var(--space-2);justify-content:center;align-items:baseline;
  font-family:var(--font-mono);font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);text-transform:uppercase}
.gf-lab b{font-weight:var(--weight-medium);color:var(--accent-deep)}
.gf-name{color:var(--faint);white-space:normal;max-width:100%;line-height:1.15;
  text-align:center;overflow-wrap:break-word}
/* A 390px column leaves 78px for a node: the two-digit number still reads, a
   two-word stage name does not, so the name steps out rather than wrap to three
   lines or shrink past legibility. Above 640px the cell is at least 128px, and
   the longest stage name ("Pipeline Orchestration", 11px mono at .14em tracking)
   wraps to two centred lines rather than crossing the viewport edge. */
@media (max-width:639px){ .gf-name{display:none} }

/* The node's tech spec. AMENDED 2026-10-07: the field is content now, so each
   node owns a focusable box and the spec is attached to it with aria-describedby
   in the markup. It is display:none at rest - that is what keeps the band at
   zero overflow and zero layout shift - and it appears on hover and on
   :focus-visible, so a keyboard user reads exactly what a mouse user sees. Only
   the chevron between nodes is generated content; the spec is real text. */
.gf-spec{display:none;position:absolute;z-index:4;top:calc(var(--gf-dot) + 42px);
  left:50%;transform:translateX(-50%);width:max-content;max-width:min(230px,70vw);
  padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);
  background-color:var(--tint);border:1px solid var(--accent-100);
  font-family:var(--font-mono);font-size:var(--size-meta);line-height:var(--leading-tight);
  letter-spacing:0;text-transform:none;text-align:left;color:var(--accent-deep)}
.gf-nodes li:first-child .gf-spec{left:0;transform:none}
.gf-nodes li:last-child .gf-spec{left:auto;right:0;transform:none}
.gf-nodes li:hover .gf-spec,.gf-nodes li:focus-visible .gf-spec{display:block}
.gf-nodes li:focus-visible{outline:2px solid var(--accent);outline-offset:6px;
  border-radius:var(--radius-sm)}
/* The connector between nodes: a chevron on the dot line, generated content so
   it is never part of the hero's prose. */
.gf-nodes li:not(:last-child)::after{content:"\2192";position:absolute;right:0;
  top:var(--gf-dot);transform:translateY(-50%);font-family:var(--font-mono);
  font-size:var(--size-mono-cap);color:var(--accent);opacity:.45;pointer-events:none}
/* The loop pauses when the hero is off-screen (IntersectionObserver in
   src/sections/90-script.html). Pausing is NOT load-bearing: it is an economy,
   and the field is identical whether or not the observer ever fires. */
.hero[data-field-paused] .gf-anim{animation-play-state:paused}

.cta-row{display:flex;flex-wrap:wrap;gap:var(--space-4);align-items:center}
/* The secondary action is an inline text link, not a second button (the brief
   asks for "an inline text link next to primary button"). 44px minimum hit
   height is kept the way the buttons keep it. */
.cta-link{display:inline-flex;align-items:center;gap:var(--space-2);min-height:44px;
  padding-block:var(--space-2);font-family:var(--font-mono);font-size:var(--size-small);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;
  color:var(--accent-deep);text-decoration:none;border-bottom:1px solid var(--accent-100)}
/* The trust row: what the stack is, under the two actions. Same field style as
   the keyword row, one line per claim. */
.trust{display:flex;flex-wrap:wrap;gap:var(--space-3) var(--space-5);
  margin:0;padding:0;list-style:none}
.trust li{display:flex;flex-direction:column;gap:2px;min-width:0}
.trust b{font-family:var(--font-mono);font-size:var(--size-mono-cap);
  font-weight:var(--weight-medium);letter-spacing:var(--tracking-caps);
  text-transform:uppercase;color:var(--accent-deep)}
.trust span{font-size:var(--size-meta);color:var(--muted)}

/* ---------- the stage: window + glass gate chip ---------- */
.stage{position:relative;min-width:0;display:flex;flex-direction:column;gap:var(--space-5)}
/* The bloom sits INSIDE the stage box: it is light behind the window, not a
   layer drawn past the viewport edge. */
.stage::before{
  content:"";position:absolute;z-index:-1;inset:0;
  background-image:var(--grad-panel);pointer-events:none;
}

.window{
  margin:0;border-radius:var(--radius-lg);overflow:hidden;
  background-color:var(--band);background-image:var(--grad-band);
  border:1px solid var(--band-line);box-shadow:var(--shadow-band);
}
.chrome{display:flex;align-items:center;gap:var(--space-3);
  padding:var(--space-3) var(--space-4);
  border-bottom:1px solid var(--band-line);background-color:var(--wash-1)}
.dots-set{display:flex;gap:var(--space-1);flex:0 0 auto}
.dots-set i{width:9px;height:9px;border-radius:var(--radius-pill);background-color:var(--band-line)}
.dots-set i:first-child{background-color:var(--accent-soft)}
.omni{display:inline-flex;align-items:center;gap:var(--space-2);margin-right:auto;
  font-family:var(--font-mono);font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--on-band-muted);
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.omni .i{color:var(--on-band-muted)}

.app{display:grid;grid-template-columns:minmax(0,1fr)}
@media (min-width:560px){ .app{grid-template-columns:198px minmax(0,1fr)} }

.rail{display:flex;flex-direction:column;gap:var(--space-2);
  padding:var(--space-4);background-color:var(--wash-1);border-bottom:1px solid var(--band-line)}
@media (min-width:560px){ .rail{border-bottom:0;border-right:1px solid var(--band-line)} }
.rail-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-2)}
.label{font-family:var(--font-mono);font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--on-band-muted)}
.count{font-family:var(--font-mono);font-size:var(--size-mono);color:var(--on-band-accent)}
.gstep{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-1) 0;
  font-size:var(--size-small);color:var(--on-band-muted)}
.gstep b{font-family:var(--font-mono);font-size:var(--size-mono-cap);
  font-weight:var(--weight-medium);color:var(--on-band-accent)}
.gstep.done,.gstep.on{color:var(--on-band)}
.gstep.on{font-weight:var(--weight-medium)}
.gstep.on b{color:var(--on-band)}
.rail-foot{margin-top:var(--space-3);padding-top:var(--space-3);
  border-top:1px solid var(--band-line);
  font-family:var(--font-mono);font-size:var(--size-mono-cap);
  line-height:var(--leading-body);color:var(--on-band-muted)}

.pane{display:flex;flex-direction:column;gap:var(--space-4);padding:var(--space-5);min-width:0}
.pane-head{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap}
.pane-title{margin-right:auto;font-family:var(--font-display);
  font-size:var(--size-h4);line-height:var(--leading-tight);color:var(--on-band)}

.trace{display:flex;flex-direction:column;gap:var(--space-2)}
.trace li{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:var(--space-3);
  align-items:center;padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);
  background-color:var(--wash-1);font-size:var(--size-small);color:var(--on-band)}
.trace li.is-warn{background-color:var(--band-raised)}
.trace code{font-family:var(--font-mono);font-size:var(--size-mono-cap);color:var(--on-band-accent)}
.bullet{width:22px;height:22px;border-radius:var(--radius-pill);display:grid;place-items:center;flex:0 0 auto}
.bullet svg{width:13px;height:13px;fill:none;stroke-width:2.6;color:var(--signal-ink-on-fill)}
.bullet-ok{background-color:var(--signal-green)}
.bullet-held{background-color:var(--signal-amber)}

.code{border-radius:var(--radius-sm);background-color:var(--band-raised);border:1px solid var(--band-line);overflow:hidden}
.code-bar{display:flex;justify-content:space-between;gap:var(--space-3);
  padding:var(--space-2) var(--space-3);border-bottom:1px solid var(--band-line);
  font-family:var(--font-mono);font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--on-band-muted)}
.code pre{margin:0;padding:var(--space-4);overflow-x:auto;
  font-family:var(--font-mono);font-size:var(--size-mono);line-height:1.7;color:var(--on-band)}
.code .c{color:var(--on-band-accent)}
.code .k{color:var(--on-band-accent)}
.code .s{color:var(--accent-soft)}

.meter{height:6px;border-radius:var(--radius-pill);background-color:var(--wash-2);overflow:hidden}
.meter i{display:block;height:100%;width:62%;border-radius:var(--radius-pill);
  background-color:var(--accent);background-image:var(--grad-accent)}

.gate{display:flex;gap:var(--space-3);padding:var(--space-4);
  border-radius:var(--radius-md);box-shadow:var(--shadow-card);color:var(--ink)}
.gate .i{color:var(--accent);flex:0 0 auto}
.gate-title{font-weight:var(--weight-semi);font-size:var(--size-small);margin-bottom:var(--space-1)}
.gate p{font-size:var(--size-meta);line-height:var(--leading-tight);color:var(--muted)}
/* `.code` is a hard clip (overflow:hidden) and the pre scrolls sideways, but a
   phone draws no scrollbar and nobody swipes a code block inside a hero - so the
   longest line, hold(reason="check 12 failed"), simply arrived cut mid-token at
   the right edge (39px short at 360px, 79px at 320px). Below the phone
   breakpoint the line wraps instead; the block is one or two lines taller and
   nothing above 480px changes. */
@media (max-width:480px){
  .code pre{white-space:pre-wrap;overflow-wrap:anywhere}
}

/* Overlaps the window's corner only where there is room for it: on a phone this
   would be the one element crossing the viewport edge, so it sits in flow. */
@media (min-width:1000px){
  .gate{position:absolute;right:calc(-1 * var(--space-4));bottom:calc(-1 * var(--space-5));
    width:min(330px,80%)}
  .stage{padding-bottom:var(--space-5)}
}

/* ---- visitor router under the hero (added 2026-09-29) ----
   Three fragment links to the service lines. Deliberately NOT a <nav>: the page
   keeps exactly one nav landmark, and the hero's own keyword row is the label. */
.router{grid-column:1 / -1;display:flex;flex-direction:column;gap:var(--space-4);padding:var(--space-5);
  border:1px solid var(--line);border-radius:var(--radius-sm);background-color:var(--ground)}
.router-q{font-family:var(--font-mono);font-size:var(--size-mono-cap);letter-spacing:var(--tracking-caps);
  text-transform:uppercase;color:var(--muted)}
.router-list{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--space-3)}
@media (min-width:820px){ .router-list{grid-template-columns:repeat(3,minmax(0,1fr))} }
.router-link{display:flex;flex-direction:column;gap:var(--space-2);min-height:44px;padding:var(--space-4);
  border:1px solid var(--line);border-radius:var(--radius-sm);background-color:var(--surface-2);
  text-decoration:none;color:var(--ink)}
.router-link:hover{border-color:var(--accent-100)}
.router-t{font-family:var(--font-display);font-weight:var(--weight-semi);font-size:var(--size-small);color:var(--ink)}
.router-d{font-size:var(--size-meta);line-height:var(--leading-tight);color:var(--muted)}
/* 21-hero-facts.css — the three-line "who / what / what you get" block. */

.hero-facts{
  display:grid;
  gap:var(--space-2);
  margin:var(--space-6) 0 0;
  padding:var(--space-5);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  background-color:var(--surface);
  background-image:var(--grad-panel);
  box-shadow:var(--shadow-card);
  max-width:56ch;
}
.hero-facts dt{
  font-family:var(--font-mono);
  font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);
  text-transform:uppercase;
  color:var(--faint);
}
.hero-facts dd{
  margin:0 0 var(--space-3);
  font-size:var(--size-body);
  line-height:var(--leading-body);
  color:var(--ink);
}
.hero-facts dd:last-child{margin-bottom:0}
@media (min-width:720px){
  .hero-facts{grid-template-columns:auto minmax(0,1fr);column-gap:var(--space-5);align-items:baseline}
  .hero-facts dd{margin-bottom:0}
}
/* ============================================================================
   30-field.css - the lavender editorial field and the marquee on it.
   Device: light (a second tone field down the page, --accent-lift / --grad-field,
   the v2 way of breaking a long light page), motion (one slow loop).
   The field pairs with --ink: 11.95:1, printed by the brand's contrast tool as
   the pairing for this exact ground.
   ========================================================================= */

.field{
  background-color:var(--accent-lift);
  background-image:var(--grad-field);
  border-block:1px solid var(--accent-100);
  padding-block:var(--space-7);
}
.ticker{overflow:hidden;position:relative}
/* A mask on the field's own values only - no colour is introduced.
   8% per edge, not 12%: at 12% the last glyphs sat under 85-90% field blend
   (measured 1.57:1 at 88-95% of the width) which read as grey text rather than
   a fade. The band is narrower so the ink holds to the crop; still a 115px
   smooth ramp at 1440, so no hard cut at either edge. */
.ticker::after{content:"";position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(90deg,var(--accent-lift) 0%,transparent 8%,transparent 92%,var(--accent-lift) 100%)}
.marquee{display:flex;width:max-content;
  animation:slide 42s linear infinite;will-change:transform}
/* Two identical halves, so translateX(-50%) is an exact loop with no seam
   drift from a flex gap sitting between them. The second half is aria-hidden in
   the markup: a screen reader hears the list once. */
.m-half{display:flex;gap:var(--space-7);padding-right:var(--space-7)}
.marquee span{display:inline-flex;align-items:center;gap:var(--space-7);
  font-family:var(--font-display);font-size:var(--size-h3);line-height:var(--leading-tight);
  letter-spacing:var(--tracking-tight);color:var(--ink);white-space:nowrap}
.marquee .sep{display:block;width:7px;height:7px;border-radius:var(--radius-pill);
  background-color:var(--accent);flex:0 0 auto}
@keyframes slide{
  from{transform:translate3d(0,0,0)}
  to{transform:translate3d(-50%,0,0)}
}
@media (prefers-reduced-motion:reduce){
  .marquee{animation:none}
}
/* ============================================================================
   40-services.css - 01: the three service lines as surface cards.
   Device: depth (raised cards, one panel bloom behind the grid), iconography
   (the 24x24 sprite on a tinted plate), hierarchy (eyebrow -> h2 -> h3 -> body
   -> limit note: four tiers per card).
   ========================================================================= */

.services{position:relative}
.cards{display:grid;gap:var(--space-5);grid-template-columns:minmax(0,1fr)}
@media (min-width:820px){ .cards{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (min-width:1100px){ .cards{grid-template-columns:repeat(3,minmax(0,1fr))} }

.card{
  position:relative;display:flex;flex-direction:column;
  padding:var(--space-6) var(--space-5) var(--space-5);
  border-radius:var(--radius-lg);
  background-color:var(--surface);border:1px solid var(--line);
  box-shadow:var(--shadow-card);
  transition:transform var(--dur-base) var(--ease-out),box-shadow var(--dur-base) var(--ease-out);
}
.card:hover{transform:translateY(-4px);box-shadow:var(--shadow-lift)}
.card-feature{border-color:var(--accent-100)}
.badge{
  position:absolute;top:calc(-1 * var(--space-3));left:var(--space-5);
  display:inline-flex;align-items:center;
  padding:var(--space-1) var(--space-3);border-radius:var(--radius-pill);
  background-color:var(--accent-100);color:var(--accent-deep);
  font-family:var(--font-mono);font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;
}
.ico-plate{
  width:48px;height:48px;border-radius:var(--radius-md);
  background-color:var(--accent-100);display:grid;place-items:center;margin-bottom:var(--space-5);
}
.ico-plate .i{width:24px;height:24px;color:var(--accent)}
.card h3{margin-bottom:var(--space-3)}
.what{font-size:var(--size-body);color:var(--muted)}
.limit{margin-top:auto;padding-top:var(--space-5);border-top:1px solid var(--line);
  font-size:var(--size-small);color:var(--ink-2)}
.limit .label{font-family:var(--font-mono);font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--accent);
  margin-right:var(--space-2)}

/* the panel bloom behind the grid: depth without a second accent */
.services::before{
  content:"";position:absolute;z-index:-1;left:24%;right:24%;top:6%;height:420px;
  background-image:var(--grad-panel);pointer-events:none;
}

/* ---- outcome sentence + "How we're different" (added 2026-09-29) ---- */
.outcome{margin-top:var(--space-4);font-size:var(--size-small);line-height:var(--leading-body);color:var(--ink-2)}
.limit .label{font-weight:400;text-transform:none;letter-spacing:normal;color:var(--muted)}
.diff{margin-top:var(--space-8)}
.diff-title{font-size:var(--size-h4);margin-bottom:var(--space-5)}
.diff-grid{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--radius-sm);overflow:hidden}
.diff-row{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--space-3);padding:var(--space-5);
  border-top:1px solid var(--line);background-color:var(--surface-2)}
@media (min-width:900px){ .diff-row{grid-template-columns:170px repeat(3,minmax(0,1fr));align-items:start} }
.diff-row:first-child{border-top:0}
.diff-head{background-color:var(--accent-lift)}
.diff-k{font-family:var(--font-mono);font-size:var(--size-mono-cap);letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.diff-c{font-size:var(--size-small);line-height:var(--leading-tight);color:var(--ink-2)}
.diff-who{font-family:var(--font-body);font-weight:var(--weight-semi);color:var(--ink)}
.diff-note{margin-top:var(--space-4);max-width:78ch;font-size:var(--size-meta);color:var(--muted)}
/* 45-demo.css — the release-gate demo. Tokens only, no literals. */

.demo{
  margin-top:var(--space-8);
  padding:var(--space-6);
  border:1px solid var(--line);
  border-radius:var(--radius-xl);
  background-color:var(--surface);
  background-image:var(--grad-panel);
  box-shadow:var(--shadow-card);
}

.demo-head{display:grid;gap:var(--space-4);align-items:start}

.demo-steps{
  display:grid;
  gap:var(--space-2);
  grid-template-columns:repeat(2,minmax(0,1fr));
  counter-reset:gate;
  margin:0;
  padding:0;
  list-style:none;
}
.demo-steps li{
  position:relative;
  padding:var(--space-3) var(--space-3) var(--space-3) calc(var(--space-6) + var(--space-1));
  border:1px solid var(--line);
  border-radius:var(--radius-md);
  background:var(--surface-2);
  color:var(--muted);
  font-size:var(--size-meta);
  line-height:var(--leading-body);
  transition:border-color var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out);
}
.demo-steps li::before{
  counter-increment:gate;
  content:counter(gate);
  position:absolute;
  left:var(--space-3);
  top:var(--space-3);
  font-family:var(--font-mono);
  font-size:var(--size-mono-cap);
  color:var(--faint);
}
.demo-steps li[data-done]{border-color:var(--accent);color:var(--ink)}
.demo-steps li[data-done]::before{color:var(--accent)}

.demo-state{
  margin:0;
  font-family:var(--font-mono);
  font-size:var(--size-mono);
  letter-spacing:var(--tracking-caps);
  text-transform:uppercase;
  color:var(--muted);
}
.demo-state[data-tone="running"]{color:var(--accent)}
.demo-state[data-tone="held"]{color:var(--signal-red-ink)}
.demo-state[data-tone="approved"]{color:var(--signal-green-ink)}

.demo-body{display:grid;gap:var(--space-6);margin-top:var(--space-6)}
.demo-checks h3,.demo-gate h3{
  margin:0 0 var(--space-3);
  font-family:var(--font-mono);
  font-size:var(--size-mono);
  font-weight:var(--weight-medium);
  letter-spacing:var(--tracking-caps);
  text-transform:uppercase;
  color:var(--faint);
}

.demo-list{margin:0;padding:0;list-style:none;display:grid;gap:var(--space-2)}
.demo-check{
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;
  gap:var(--space-3);
  padding:var(--space-3);
  border:1px solid var(--line);
  border-radius:var(--radius-md);
  background:var(--surface-2);
  font-size:var(--size-small);
  color:var(--ink-2);
}
.demo-dot{
  width:var(--space-2);
  height:var(--space-2);
  border-radius:var(--radius-pill);
  border:1px solid var(--line-strong);
  background:transparent;
  transition:background-color var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.demo-check[data-result="pass"] .demo-dot{background:var(--signal-green);border-color:var(--signal-green)}
.demo-check[data-result="fail"] .demo-dot{background:var(--signal-red);border-color:var(--signal-red)}
.demo-check[data-result="pass"]{color:var(--ink)}
.demo-check[data-result="fail"]{border-color:var(--signal-red);color:var(--ink)}
.demo-check-state{
  font-family:var(--font-mono);
  font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);
  text-transform:uppercase;
  color:var(--faint);
}
.demo-check[data-result="pass"] .demo-check-state{color:var(--signal-green-ink)}
.demo-check[data-result="fail"] .demo-check-state{color:var(--signal-red-ink)}

.demo-finding{
  margin:var(--space-4) 0 0;
  padding:var(--space-3) var(--space-4);
  border-left:3px solid var(--signal-red);
  border-radius:var(--radius-sm);
  background:var(--surface-2);
  color:var(--ink-2);
  font-size:var(--size-small);
  line-height:var(--leading-body);
}

.demo-gate{padding:var(--space-4);border:1px solid var(--line);border-radius:var(--radius-lg);background:var(--surface-2)}
.demo-gate-line{margin:0 0 var(--space-4);color:var(--ink-2);font-size:var(--size-body);line-height:var(--leading-body)}
.demo[data-demo-state="held"] .demo-gate-line{color:var(--ink);font-weight:var(--weight-medium)}

.demo-approval{margin:0 0 var(--space-4);padding:var(--space-4);border:1px solid var(--accent-100);border-radius:var(--radius-md);background:var(--surface)}
.demo-who{display:flex;align-items:center;gap:var(--space-3);margin:0 0 var(--space-3);font-size:var(--size-small);color:var(--ink);font-weight:var(--weight-medium)}
.demo-avatar{
  display:grid;
  place-items:center;
  width:var(--space-7);
  height:var(--space-7);
  border-radius:var(--radius-pill);
  background:var(--accent);
  color:var(--on-accent);
  font-family:var(--font-mono);
  font-size:var(--size-mono);
}
.demo-role{color:var(--faint);font-weight:var(--weight-regular);font-family:var(--font-mono);font-size:var(--size-mono-cap);letter-spacing:var(--tracking-caps);text-transform:uppercase}
.demo-confirm{display:flex;align-items:flex-start;gap:var(--space-2);margin:0 0 var(--space-4);font-size:var(--size-small);color:var(--ink-2);line-height:var(--leading-body);cursor:pointer}
.demo-confirm input{flex:0 0 auto;width:var(--space-4);height:var(--space-4);margin:0;accent-color:var(--accent)}

.demo-log{
  margin:0 0 var(--space-4);
  font-family:var(--font-mono);
  font-size:var(--size-mono);
  line-height:var(--leading-body);
  color:var(--signal-green-ink);
}
.demo .btn[disabled]{opacity:.55;cursor:not-allowed}

@media (max-width:559px){
  .demo-steps{grid-template-columns:minmax(0,1fr)}
  .demo{padding:var(--space-4)}
}
@media (min-width:720px){
  .demo-steps{grid-template-columns:repeat(4,minmax(0,1fr))}
  .demo-head{grid-template-columns:minmax(0,1fr);gap:var(--space-3)}
}
@media (min-width:900px){
  .demo-body{grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:start}
}

/* Post-demo contextual enquiry CTA: sits after the simulated release continues. */
.demo-next{
  margin:var(--space-4) 0 var(--space-3);
  padding:var(--space-4);
  border:1px solid var(--accent-100);
  border-radius:var(--radius-md);
  background:var(--surface);
}
.demo-next-title{
  margin:0 0 var(--space-2);
  font-family:var(--font-display);
  font-size:var(--size-h3);
  line-height:var(--leading-h2);
  color:var(--ink);
}
.demo-next-copy{
  margin:0 0 var(--space-3);
  max-width:var(--measure);
  color:var(--ink-2);
}
/* ============================================================================
   50-band.css - 02: the delivery process trace, the page's ONE dark band.
   Device: depth (the band is a surface step, not a panel colour), hierarchy
   (on-band ink ladder: --on-band, --on-band-muted, --on-band-accent), motion
   (staggered reveal of the rows), plus a six-step track built in HTML.
   Pairings used here and measured: --on-band 16.04:1 on --band, --on-band-muted
   and --on-band-accent both AAA on the band. Nothing on this band is below its
   floor, and no signal colour is used as type.
   ========================================================================= */

.band{
  background-color:var(--band);background-image:var(--grad-band);
  padding-block:var(--space-9);
}
.band h2, .band h3{color:var(--on-band)}
.band .eyebrow{color:var(--on-band-accent)}
.band .lede{color:var(--on-band-muted)}
.band .sec-head{max-width:66ch}
.band a{color:var(--on-band-accent)}
.band a:hover{color:var(--on-band)}

/* ---------- the six-step track ---------- */
.pipe{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-4);
  margin-bottom:var(--space-8)}
@media (min-width:700px){ .pipe{grid-template-columns:repeat(6,minmax(0,1fr))} }
.pipe-step{display:flex;flex-direction:column;gap:var(--space-2)}
.pipe-step .n{font-family:var(--font-mono);font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);color:var(--on-band-accent)}
.pipe-step .t{font-family:var(--font-body);font-size:var(--size-small);
  font-weight:var(--weight-medium);color:var(--on-band)}
.pipe-step .bar{height:4px;border-radius:var(--radius-pill);background-color:var(--wash-1);overflow:hidden}
.pipe-step .bar i{display:block;height:100%;width:100%;border-radius:var(--radius-pill);
  background-color:var(--on-band-accent);opacity:.55}
.pipe-step.is-gate .bar i{background-color:var(--accent-soft);opacity:1}
/* the gate step is the one the whole track exists for: it gets the accent, and
   the six rows below say who clears it. */

/* ---------- the stage rows ---------- */
.stages{display:flex;flex-direction:column;gap:var(--space-4);position:relative}
.stage-row{
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:var(--space-4) var(--space-6);
  padding:var(--space-5);border-radius:var(--radius-lg);
}
@media (min-width:900px){
  .stage-row{grid-template-columns:auto minmax(0,1fr) minmax(0,300px);align-items:start}
}
/* Below the three-column breakpoint the meta block spans the full row. Without
   this it lands in the `auto` track beside the number and that track inflates to
   the block's min-content, squeezing the stage text to ~17px and pushing the
   document 50px wider than a 360px viewport. */
@media (max-width:899px){
  .stage-row .meta{grid-column:1 / -1}
}
.stage-row .num{
  width:44px;height:44px;border-radius:var(--radius-sm);
  display:grid;place-items:center;
  background-color:var(--wash-2);color:var(--on-band);
  font-family:var(--font-mono);font-size:var(--size-mono);font-weight:var(--weight-medium);
}
.stage-row h3{margin-bottom:var(--space-3);font-size:var(--size-h4);
  font-family:var(--font-display);color:var(--on-band)}
.stage-row p{font-size:var(--size-small);line-height:var(--leading-body);color:var(--on-band-muted)}
.stage-row .meta{display:flex;flex-direction:column;gap:var(--space-3);
  border-top:1px solid var(--band-line);padding-top:var(--space-4)}
@media (min-width:900px){ .stage-row .meta{border-top:0;padding-top:0;border-left:1px solid var(--band-line);padding-left:var(--space-5)} }
.stage-row .meta span{display:block;font-size:var(--size-small);line-height:var(--leading-tight);color:var(--on-band)}
.stage-row .meta .k{display:block;font-family:var(--font-mono);font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--on-band-accent);
  margin-bottom:var(--space-1)}

.band-note{margin-top:var(--space-7);display:flex;gap:var(--space-4);align-items:flex-start;
  padding:var(--space-5);border-radius:var(--radius-lg);max-width:78ch}
.band-note .i{color:var(--on-band-accent);flex:0 0 auto}
.band-note p{font-size:var(--size-small);color:var(--on-band-muted)}
.band-note b{color:var(--on-band);font-weight:var(--weight-medium)}

/* ---- six stages, horizontal step timeline (added 2026-09-29) ----
   Same copy, same order, same "You get / Gate" meta: the rows become six columns
   at the wide end, three at the middle, one on a phone. One small sprite icon
   per stage, decorative, so the heading still carries the meaning. */
.stages{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--space-5)}
@media (min-width:700px){ .stages{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media (min-width:1100px){ .stages{grid-template-columns:repeat(6,minmax(0,1fr));gap:var(--space-4)} }
.stage-row{display:flex !important;flex-direction:column;gap:var(--space-3);min-width:0}
.stage-row .meta{margin-top:auto;border-top:1px solid var(--band-line);padding-top:var(--space-4);
  border-left:0 !important;padding-left:0 !important}
.stage-ico{width:36px;height:36px;display:grid;place-items:center;border-radius:var(--radius-sm);
  background-color:var(--wash-1);border:1px solid var(--band-line)}
.stage-ico .i{width:18px;height:18px;color:var(--on-band-accent)}
@media (min-width:1100px){ .stage-row h3{font-size:var(--size-small)} }
/* ============================================================================
   55-explainer.css - 02b: the short film. A LIGHT section on purpose: there is
   one dark band on this page (02, How we deliver) and the film sits beside it as
   its moving counterpart, not as a second band. The stage is tinted, not white,
   so the section is not another flat white field; the type on it is --ink/--muted
   (above 8:1) and the only signal colours are fills.
   ========================================================================= */

.xp-section{position:relative;isolation:isolate}
/* the same periwinkle bloom the work rows sit on: the section is lit, not plain */
.xp-section::before{
  content:"";position:absolute;z-index:-1;left:6%;right:6%;top:3%;height:74%;
  background-image:var(--grad-panel);pointer-events:none;
}

.xp-tag{
  display:inline-flex;align-items:center;gap:var(--space-2);
  padding:var(--space-1) var(--space-3);border-radius:var(--radius-pill);
  background-color:var(--surface-2);border:1px solid var(--accent-100);
  color:var(--ink-2);font-family:var(--font-mono);font-size:var(--size-mono-cap);
  font-weight:var(--weight-semi);letter-spacing:var(--tracking-caps);text-transform:uppercase;white-space:nowrap;
}

.xp-stage{
  margin-top:var(--space-6);margin-bottom:0;
  display:flex;flex-direction:column;gap:var(--space-3);
}
/* the frame: the film's own black, so the letterbox is the page's ink and not a
   white gap, with the card radius and hairline the rest of the page uses. */
.xp-video{
  display:block;width:100%;height:auto;aspect-ratio:16 / 9;
  border-radius:var(--radius-lg);border:1px solid var(--line);
  background-color:var(--ink);box-shadow:var(--shadow-card);
}
.xp-note{
  font-family:var(--font-mono);font-size:var(--size-mono);line-height:var(--leading-body);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--muted);
  max-width:78ch;
}
.xp-fallback{color:var(--ink-2);font-size:var(--size-small);padding:var(--space-5)}
.xp-fallback a{color:var(--accent)}
/* ============================================================================
   60-work.css - 03: the work rows, each carrying the status the work actually
   has. Status is a FILL (the pip) plus a word in text-grade colour: --signal-green
   and --signal-amber are fills only (2.23:1 / amber is never type), and the
   words use --signal-green-ink (5.36:1) or --ink.
   ========================================================================= */

.work{display:flex;flex-direction:column;gap:var(--space-4)}
/* Rows are TINTED, not white: five white cards stacked down a light page is how
   a section ends up a flat white field (measured: 67% one value before this).
   --tint keeps the row quiet, --accent-100 is its hairline, and the text on it
   is --ink/--muted, both above 8:1. */
.wrow{
  display:grid;gap:var(--space-3) var(--space-6);
  grid-template-columns:minmax(0,1fr);
  padding:var(--space-5);border-radius:var(--radius-lg);
  background-color:var(--tint);border:1px solid var(--accent-100);
  /* the fill stays --tint, but a tint -> accent-100 wash runs down each row:
     five FLAT tint rows stacked measured 59.31% one value inside a 900x900
     slice (over the 55% ceiling) whenever a slice boundary phased onto them.
     Same two token roles the file already uses, just lit rather than flat. */
  background-image:linear-gradient(180deg,var(--tint) 0%,var(--accent-100) 100%);
  box-shadow:var(--shadow-card);
  transition:transform var(--dur-base) var(--ease-out);
}
/* a periwinkle bloom behind the list, so the section is lit rather than plain */
.work-section{position:relative;isolation:isolate}
.work-section::before{
  content:"";position:absolute;z-index:-1;left:8%;right:8%;top:2%;height:70%;
  background-image:var(--grad-panel);pointer-events:none;
}
@media (min-width:900px){ .wrow{grid-template-columns:minmax(0,340px) minmax(0,1fr);align-items:start} }
.wrow:hover{transform:translateY(-3px)}
.wrow h3{font-size:var(--size-h4);font-family:var(--font-display);margin-bottom:var(--space-3)}
.tags{display:flex;flex-wrap:wrap;gap:var(--space-2);align-items:center}
.status{display:inline-flex;align-items:center;gap:var(--space-2);
  padding:var(--space-1) var(--space-3);border-radius:var(--radius-pill);
  font-family:var(--font-mono);font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;white-space:nowrap}
.status-shipped{background-color:var(--surface-2);color:var(--signal-green-ink)}
.status-build{background-color:var(--surface-2);color:var(--ink-2)}
.line-tag{display:inline-flex;align-items:center;padding:var(--space-1) var(--space-3);
  border-radius:var(--radius-pill);border:1px solid var(--line-strong);
  font-size:var(--size-meta);color:var(--muted);white-space:nowrap}
.ev{font-size:var(--size-small);line-height:var(--leading-body);color:var(--muted)}
.work-note{margin-top:var(--space-7);max-width:78ch;font-size:var(--size-small);color:var(--muted);
  border-left:2px solid var(--accent);padding-left:var(--space-5)}

/* ---- the vacated case-studies slot (added 2026-09-29, reworded 2026-10-10) ----
   The two uncommissioned rebuilds moved to their own page (/rebuilds); the
   homepage slot they used to occupy now carries only the note saying where they
   went. It holds no action of its own: the placeholder button that sent a
   reader back to #work was removed in the 2026-10-10 copy audit, because this
   block already sits inside Selected Work - a link from a block to the section
   that contains it is a loop, not a route. The class name .cs-moved is kept as
   it stands, since the section markup and this sheet both name it. */
.cs-moved{margin-top:var(--space-8);padding:var(--space-6,var(--space-5));border:1px solid var(--line);
  border-radius:var(--radius-sm);background-color:var(--surface-2);display:flex;flex-direction:column;
  gap:var(--space-4);align-items:flex-start}
.cs-moved h3{font-size:var(--size-h4)}
.cs-moved p{max-width:78ch;font-size:var(--size-small);line-height:var(--leading-body);color:var(--muted)}
.cs-moved code{font-family:var(--font-mono);font-size:var(--size-mono);color:var(--ink-2)}

/* Concept artwork for the three reference builds; embedded WebP images. */
.w-shot{grid-column:1/-1;border:1px solid var(--line);border-radius:var(--radius-md);
  overflow:hidden;background-color:var(--surface-2)}
.w-shot img,.w-shot video{display:block;width:100%;height:auto;background-color:var(--surface-2)}
.w-shot figcaption{padding:var(--space-3) var(--space-4);border-top:1px solid var(--line);
  font-size:var(--size-meta);line-height:var(--leading-tight);color:var(--muted)}
/* only ever seen by a browser that cannot play the capture: the same courtesy the
   explainer film extends, in the section's own class rather than that section's */
.w-fallback{padding:var(--space-5);font-size:var(--size-small);line-height:var(--leading-body);color:var(--muted)}
/* section: 04 technical questions (own file: src/styles/65-faq.css) */
.faq-list{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--space-5)}
@media (min-width:900px){ .faq-list{grid-template-columns:repeat(2,minmax(0,1fr))} }
.faq-item{padding:var(--space-5);border:1px solid var(--line);border-radius:var(--radius-sm);background-color:var(--surface-2)}
.faq-item h3{font-size:var(--size-h4);margin-bottom:var(--space-3)}
.faq-item p{font-size:var(--size-small);line-height:var(--leading-body);color:var(--muted)}

/* The FAQ sits on the lavender field (a .field device), so its supporting copy
   uses the ink ladder's stronger step rather than --muted: the field pairs with
   --ink at 11.95:1 and this keeps every line of it above the 4.5:1 floor. */
.faq{padding-block:var(--space-8)}
.faq .lede,.faq .faq-item p{color:var(--ink-2)}
.faq .faq-item{border-color:var(--accent-100)}
/* 69-enquire.css — the visible enquiry form and the direct email route. */

.enquiry-grid{display:grid;gap:var(--space-6);margin-top:var(--space-8);grid-template-columns:minmax(0,1fr)}
@media (min-width:900px){
  .enquiry-grid{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);align-items:start}
}

.enquiry{
  padding:var(--space-5);
  border:1px solid var(--line);
  border-radius:var(--radius-xl);
  background-color:var(--surface);
  background-image:var(--grad-panel);
  box-shadow:var(--shadow-card);
}
.enquiry-form{display:grid;gap:var(--space-4)}
.eq-field{display:grid;gap:var(--space-2)}
.eq-field label{
  font-family:var(--font-mono);
  font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);
  text-transform:uppercase;
  color:var(--ink-2);
}
.eq-field .opt{color:var(--faint);text-transform:none;letter-spacing:0}
.eq-field input,.eq-field textarea,.eq-field select{
  width:100%;
  font:inherit;
  font-size:var(--size-body);
  color:var(--ink);
  background:var(--surface-2);
  border:1px solid var(--line-strong);
  border-radius:var(--radius-sm);
  padding:var(--space-3);
  min-height:44px;
}
.eq-field select{appearance:auto}
.eq-field textarea{resize:vertical;line-height:var(--leading-body)}
.eq-field input::placeholder,.eq-field textarea::placeholder{color:var(--faint)}
.eq-field input:focus-visible,.eq-field textarea:focus-visible,.eq-field select:focus-visible{outline:none;box-shadow:var(--focus-ring);border-color:var(--accent)}
.eq-field input:user-invalid,.eq-field textarea:user-invalid{border-color:var(--signal-red)}

.eq-fields[hidden]{display:none}
.eq-received{margin-top:var(--space-4);padding:var(--space-4);border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface-2)}
.eq-received .cta-row{margin-top:var(--space-3)}

.form-status{margin:0;font-size:var(--size-small);line-height:var(--leading-body);color:var(--accent)}
.form-status:empty{display:none}
.form-status.is-error{color:var(--signal-red)}
.eq-ref{font-family:var(--font-mono);font-size:.9em;white-space:nowrap}

.enquiry-side{padding:var(--space-5);border:1px solid var(--line);border-radius:var(--radius-xl);background:var(--surface-2)}
.enquiry-side h3{
  margin:0 0 var(--space-3);
  font-family:var(--font-mono);
  font-size:var(--size-mono-cap);
  font-weight:var(--weight-medium);
  letter-spacing:var(--tracking-caps);
  text-transform:uppercase;
  color:var(--faint);
}
.enquiry-side h3 + *{margin-top:0}
.enquiry-side .addr{margin:0 0 var(--space-5);font-size:var(--size-body-lg)}
/* The direct-email fallback is a real link again (2026-10-24), but it is the
   secondary route: the address keeps the .addr voice and the underline is the
   only thing that marks it as clickable. */
.enquiry-side .addr a{color:inherit;text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--accent-100)}
.enquiry-side .addr a:hover{text-decoration-color:var(--accent)}
.enquiry-steps{margin:0 0 var(--space-4);padding-left:var(--space-5);display:grid;gap:var(--space-2)}
.enquiry-steps li{font-size:var(--size-small);line-height:var(--leading-body);color:var(--ink-2)}
/* ============================================================================
   70-contact.css - 04: the closing CTA panel and the two contact panels.
   Device: gradient accent as a 1px card border (used only as a border, never
   as type of its own, over --grad-accent), glass panels, hierarchy (eyebrow -> h2 -> h3 -> body).
   ========================================================================= */

.cta-panel{
  position:relative;overflow:hidden;
  border-radius:var(--radius-xl);
  border:1px solid transparent;
  padding:var(--space-9) var(--space-6);
  /* the gradient reads as a 1px border: a tinted-to-surface fill in the padding
     box, the accent gradient in the border box. Both layers are token values.
     The fill is tinted rather than plain white because a full-height white panel
     measured as a flat white field (67% of one slice). */
  background-color:var(--tint);
  background-image:linear-gradient(178deg,var(--tint) 0%,var(--accent-100) 100%),var(--grad-accent);
  background-origin:border-box;
  background-clip:padding-box,border-box;
  box-shadow:var(--shadow-card);
}
.cta-panel::after{
  content:"";position:absolute;z-index:0;right:-12%;top:-46%;width:620px;height:620px;
  background-image:var(--grad-panel);pointer-events:none;
}
.cta-panel > *{position:relative;z-index:1}
.cta-panel .cta-row{margin-top:var(--space-6)}
.cta-panel h2{max-width:26ch}

.contact-grid{display:grid;gap:var(--space-5);margin-top:var(--space-8);
  grid-template-columns:minmax(0,1fr)}
@media (min-width:820px){ .contact-grid{grid-template-columns:repeat(2,minmax(0,1fr))} }
.contact-card{padding:var(--space-5);border-radius:var(--radius-lg)}
.contact-card h3{font-size:var(--size-h4);font-family:var(--font-body);
  font-weight:var(--weight-semi);margin-bottom:var(--space-3)}
.contact-card p{font-size:var(--size-small);line-height:var(--leading-body);color:var(--muted)}
.addr{
  display:inline-flex;align-items:center;gap:var(--space-3);min-height:44px;
  margin-top:var(--space-4);font-family:var(--font-mono);font-size:var(--size-small);
  color:var(--accent);word-break:break-word;
}
.addr .i{color:var(--accent)}
.note{margin-top:var(--space-4);font-size:var(--size-meta);color:var(--muted)}
.contact-card .ticks{margin-top:var(--space-4)}
/* ============================================================================
   80-footer.css - the footer on the dark band: the measured-facts panel, the
   four spec columns, the lockup row and the honesty note.
   Mono micro-labels are used here as the data tier (one place on the page),
   never as body copy.
   ========================================================================= */

.site-foot{
  background-color:var(--band);background-image:var(--grad-band);
  padding-block:var(--space-9) var(--space-8);color:var(--on-band-muted);
}
.site-foot a{color:var(--on-band-accent)}
.site-foot a:hover{color:var(--on-band)}
.site-foot h3, .site-foot h4{color:var(--on-band)}

/* ---------- measured facts ---------- */
.factband{padding:var(--space-5);border-radius:var(--radius-lg);margin-bottom:var(--space-7)}
.factband-head{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-5);
  align-items:baseline;margin-bottom:var(--space-4)}
.factband-k{font-family:var(--font-mono);font-size:var(--size-mono-cap);
  letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--on-band)}
.factband-h{font-family:var(--font-mono);font-size:var(--size-mono-cap);color:var(--on-band-muted)}
.facts{display:grid;gap:var(--space-3);grid-template-columns:minmax(0,1fr)}
@media (min-width:640px){ .facts{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (min-width:1000px){ .facts{grid-template-columns:repeat(3,minmax(0,1fr))} }
.facts span{display:flex;align-items:baseline;gap:var(--space-2);flex-wrap:wrap;
  font-size:var(--size-small);line-height:var(--leading-tight);color:var(--on-band-accent)}
.facts b{font-family:var(--font-mono);font-size:var(--size-mono);
  font-weight:var(--weight-medium);color:var(--on-band)}

.foot-rule{border:0;border-top:1px solid var(--band-line);margin:0 0 var(--space-8)}

/* ---------- four spec columns ---------- */
.foot-cols{display:grid;gap:var(--space-7) var(--space-6);grid-template-columns:minmax(0,1fr)}
@media (min-width:700px){ .foot-cols{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (min-width:1100px){ .foot-cols{grid-template-columns:repeat(4,minmax(0,1fr))} }
.fcol-h{font-family:var(--font-mono);font-size:var(--size-mono-cap);
  font-weight:var(--weight-medium);letter-spacing:var(--tracking-caps);
  text-transform:uppercase;color:var(--on-band-accent);margin-bottom:var(--space-4)}
.fcol ul, .fcol ol{display:flex;flex-direction:column;gap:var(--space-4)}
.fcol li{font-size:var(--size-small);line-height:var(--leading-tight);color:var(--on-band)}
.fcol b{font-weight:var(--weight-medium);display:block;margin-bottom:var(--space-1)}
.fcol .spec{display:block;font-size:var(--size-meta);line-height:var(--leading-body);color:var(--on-band-muted)}
.fcol .num{font-family:var(--font-mono);font-size:var(--size-mono-cap);
  color:var(--on-band-accent);margin-right:var(--space-3)}
.fcol b + .spec{margin-top:var(--space-1)}
.fcol a{display:inline-flex;align-items:center;gap:var(--space-2);min-height:44px;
  margin-bottom:var(--space-2);word-break:break-word}

/* ---------- lockup row ---------- */
.foot-row{display:flex;flex-wrap:wrap;gap:var(--space-4) var(--space-6);
  align-items:center;justify-content:space-between;margin-top:var(--space-8)}
.foot-row .brand{color:var(--on-band);font-size:var(--size-body-lg)}
.foot-row .brand:hover{color:var(--on-band)}
.foot-meta{font-size:var(--size-meta);color:var(--on-band-muted)}

/* ---------- the honesty note: what this artefact is, in plain words ---------- */
.foot-note{margin-top:var(--space-6);max-width:82ch;font-size:var(--size-meta);
  line-height:var(--leading-body);color:var(--on-band-muted)}
.foot-note b{color:var(--on-band);font-weight:var(--weight-medium)}
/* ============================================================================
   85-assistant.css - the Fortoxa assistant: launcher, greeting card, panel.

   Layout follows the support-widget pattern LangChain ships: one circular
   launcher in the bottom-right corner, a short greeting card above it, and a
   fixed panel with a text header, welcome line, two shortcut links, a bordered
   composer and a privacy line.

   Every colour, radius, size and motion value below is a var() from
   brand-v2/tokens/tokens.css. The only literals are layout geometry (widths,
   heights, insets, stacking), the same class of value 69-enquire.css carries.

   The launcher and greeting are revealed by 85-assistant.html's script five
   seconds after the page is visited. This section is the page's one sanctioned
   interactive surface that is not the enquiry form; the amendment that admits
   its endpoint is recorded in config/verify_build.py (law 3c).
   ========================================================================= */

.assistant{position:relative}

/* ---------- launcher: one circular, branded button ---------- */
.assistant-launch{
  position:fixed;
  right:24px;
  bottom:24px;
  z-index:70;
  display:inline-flex;align-items:center;justify-content:center;
  width:56px;height:56px;padding:0;
  border:0;border-radius:var(--radius-pill);
  background:var(--accent);
  color:var(--on-accent);
  box-shadow:var(--shadow-lift);
  cursor:pointer;
  opacity:0;
  transform:translateY(12px) scale(.96);
  transition:opacity var(--dur-base) var(--ease-out),transform var(--dur-base) var(--ease-out),background-color var(--dur-fast) ease;
}
.assistant-launch[hidden]{display:none}
.assistant-launch.is-in{opacity:1;transform:none}
.assistant-launch:hover{background:var(--accent-hover);transform:translateY(-1px)}
.assistant-launch:active{background:var(--accent-press)}
.assistant-launch:focus-visible{outline:0;box-shadow:var(--focus-ring),var(--shadow-lift)}
.assistant-launch-face{
  display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;
  border-radius:var(--radius-pill);
  background:var(--on-accent);
  font-size:var(--size-h3);
  line-height:1;
}

/* ---------- greeting card: the collapsed, proactive state ---------- */
.assistant-greeting{
  position:fixed;
  right:24px;
  bottom:92px;
  z-index:70;
  display:flex;align-items:flex-start;gap:0;
  width:min(19.5rem,calc(100vw - 48px));
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  background:var(--surface);
  box-shadow:var(--shadow-lift);
  opacity:0;
  transform:translateY(10px);
  transition:opacity var(--dur-base) var(--ease-out),transform var(--dur-base) var(--ease-out);
}
.assistant-greeting[hidden]{display:none}
.assistant-greeting.is-in{opacity:1;transform:none}
.assistant-greeting-open{
  display:flex;align-items:flex-start;gap:10px;
  flex:1 1 auto;min-width:0;
  padding:14px 30px 14px 14px;
  border:0;background:none;text-align:left;cursor:pointer;
  font-family:var(--font-body);
  color:var(--ink);
}
.assistant-greeting-face{
  flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:26px;height:26px;border-radius:var(--radius-pill);
  background:var(--accent-100);
  font-size:var(--size-small);line-height:1;
}
.assistant-greeting-txt{
  font-size:var(--size-meta);
  line-height:var(--leading-body);
  color:var(--muted);
}
.assistant-greeting-shut{
  position:absolute;top:4px;right:4px;
  width:22px;height:22px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  border:0;border-radius:var(--radius-pill);
  background:transparent;color:var(--faint);
  font-size:var(--size-mono-cap);line-height:1;cursor:pointer;
}
.assistant-greeting-shut:hover{background:var(--surface-2);color:var(--ink)}

/* ---------- panel ---------- */
.assistant-panel{
  position:fixed;
  right:24px;
  bottom:24px;
  z-index:71;
  display:flex;flex-direction:column;
  width:min(26.5rem,calc(100vw - 48px));
  height:min(46rem,calc(100dvh - 48px));
  overflow:hidden;
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  background:var(--surface);
  box-shadow:var(--shadow-lift);
  font-family:var(--font-body);
  color:var(--ink);
}
.assistant-panel[hidden]{display:none}

/* the open panel replaces the launcher and the card, as the reference widget does */
.assistant.is-open .assistant-launch,
.assistant.is-open .assistant-greeting{display:none}

.assistant-head{
  display:flex;align-items:flex-start;gap:var(--space-3);
  flex:none;
  padding:18px 18px 10px 20px;
}
.assistant-head-txt{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 auto}
.assistant-title{
  margin:0;
  font-size:var(--size-body);
  line-height:var(--leading-tight);
  font-weight:var(--weight-semi);
  letter-spacing:var(--tracking-tight);
  color:var(--ink);
}
.assistant-role{
  margin:0;
  font-size:var(--size-mono);
  line-height:var(--leading-tight);
  color:var(--faint);
}
.assistant-shut{
  flex:none;
  width:28px;height:28px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  border:0;border-radius:var(--radius-pill);
  background:transparent;color:var(--faint);
  font-size:var(--size-small);line-height:1;cursor:pointer;
}
.assistant-shut:hover{background:var(--surface-2);color:var(--ink)}
.assistant-shut:focus-visible{outline:0;box-shadow:var(--focus-ring)}

.assistant-log{
  flex:1 1 auto;
  display:flex;flex-direction:column;gap:var(--space-2);
  padding:0 20px var(--space-3);
  overflow-y:auto;
  overscroll-behavior:contain;
}
.assistant-pill{
  align-self:flex-start;
  display:inline-flex;align-items:center;gap:var(--space-2);
  margin:var(--space-1) 0 0;
  padding:5px 12px 5px 5px;
  border:1px solid var(--line);
  border-radius:var(--radius-pill);
  background:var(--ground);
  font-size:var(--size-mono);
  line-height:var(--leading-tight);
  color:var(--ink-2);
}
.assistant-pill-face{
  display:inline-flex;align-items:center;justify-content:center;
  width:22px;height:22px;border-radius:var(--radius-pill);
  background:var(--accent-100);
  font-size:var(--size-mono);line-height:1;
}
.assistant-welcome{
  margin:0;
  font-size:var(--size-meta);
  line-height:var(--leading-body);
  color:var(--muted);
}
.assistant-msg{
  max-width:88%;
  padding:9px 12px;
  border-radius:var(--radius-md);
  font-size:var(--size-meta);
  line-height:var(--leading-body);
}
.assistant-msg.is-bot{align-self:flex-start;background:var(--surface-2);color:var(--ink-2)}
.assistant-msg.is-you{align-self:flex-end;background:var(--accent);color:var(--on-accent)}
.assistant-msg.is-err{align-self:flex-start;background:var(--tint-warm);color:var(--ink);border-left:2px solid var(--signal-red)}
.assistant-msg a{color:inherit;text-decoration:underline;text-underline-offset:2px}

.assistant-shortcuts{
  flex:none;
  display:flex;flex-wrap:wrap;gap:var(--space-2);
  padding:0 20px var(--space-3);
}
.assistant-shortcut{
  display:inline-flex;align-items:center;
  padding:7px 11px;
  border:1px solid var(--line);
  border-radius:var(--radius-sm);
  background:var(--ground);
  color:var(--ink-2);
  font-size:var(--size-mono);
  font-weight:var(--weight-medium);
  line-height:var(--leading-tight);
  text-decoration:none;
  transition:border-color var(--dur-fast) ease,color var(--dur-fast) ease,background-color var(--dur-fast) ease;
}
.assistant-shortcut:hover{border-color:var(--accent);color:var(--accent);background:var(--tint)}

.assistant-compose{
  flex:none;
  padding:0 var(--space-4);
}
.assistant-field{
  display:flex;align-items:flex-end;gap:var(--space-2);
  padding:7px 7px 7px 12px;
  border:1px solid var(--line-strong);
  border-radius:var(--radius-md);
  background:var(--surface);
  transition:border-color var(--dur-fast) ease,box-shadow var(--dur-fast) ease;
}
.assistant-field:focus-within{border-color:var(--accent);box-shadow:var(--focus-ring)}
.assistant-input{
  flex:1 1 auto;min-width:0;
  min-height:24px;max-height:96px;
  padding:3px 0;
  border:0;background:transparent;
  color:var(--ink);
  font-family:var(--font-body);
  font-size:var(--size-meta);
  line-height:var(--leading-body);
  resize:none;
  outline:0;
}
.assistant-input::placeholder{color:var(--faint)}
.assistant-send{
  flex:none;
  width:30px;height:30px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  border:0;border-radius:var(--radius-sm);
  background:var(--accent);color:var(--on-accent);
  font-size:var(--size-mono);line-height:1;cursor:pointer;
  transition:background-color var(--dur-fast) ease,opacity var(--dur-fast) ease;
}
.assistant-send:hover{background:var(--accent-hover)}
.assistant-send[disabled]{opacity:.45;cursor:progress}
.assistant-send:focus-visible{outline:0;box-shadow:var(--focus-ring)}

.assistant-legal{
  flex:none;
  margin:0;
  padding:10px 0 14px;
  text-align:center;
  font-size:var(--size-mono-cap);
  line-height:var(--leading-tight);
  color:var(--faint);
}
.assistant-legal a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.assistant-legal a:hover{color:var(--accent)}

.assistant-sr{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.assistant-noscript{
  margin:0;padding:var(--space-4);
  font-size:var(--size-meta);color:var(--muted);text-align:center;
}
.assistant-noscript a{color:var(--accent)}

@media (max-width:30rem){
  .assistant-launch{right:16px;bottom:16px;width:52px;height:52px}
  .assistant-launch-face{width:38px;height:38px}
  .assistant-greeting{right:16px;bottom:80px;width:calc(100vw - 32px)}
  .assistant-panel{
    right:12px;left:12px;bottom:12px;
    width:auto;
    height:calc(100dvh - 24px);
    border-radius:var(--radius-lg);
  }
}

@media (prefers-reduced-motion:reduce){
  .assistant-launch,.assistant-greeting{transition:none;transform:none;opacity:1}
}
/* ============================================================================
   90-motion.css - device: motion, progressive and opt-in.
   The .js class is set in <head> only when the browser has an
   IntersectionObserver AND the visitor has not asked for reduced motion, so
   with script absent, disabled or reduced-motion on, every element is simply
   visible. Nothing here is load-bearing: the page reads the same either way.
   Nothing above the fold carries data-reveal, so a screenshot taken before the
   observer settles still measures the hero as painted.
   ========================================================================= */

.js [data-reveal]{
  opacity:0;transform:translate3d(0,20px,0);
  transition:opacity var(--dur-slow) var(--ease-out),transform var(--dur-slow) var(--ease-out);
}
.js [data-reveal].is-in{opacity:1;transform:none}

@media (prefers-reduced-motion:reduce){
  .js [data-reveal]{opacity:1;transform:none;transition:none}
  .marquee{animation:none}
  .pulse::after{animation:none;opacity:0}
  /* The gate field collapses to a static field: the base spine, the ribbon and
     the five pipeline nodes and their names are not animated in the first place, and the
     two dash paths - the travelling trace and its head glow - are removed
     outright rather than left parked, so nothing of the loop is painted at all
     (a parked dash still draws a 240-unit segment somewhere on the path, and a
     static hero should carry none of it). Reported by name rather than left to
     the 1ms rule below, so animation-name is measurably 'none' and the probe
     asserts it instead of assuming it; tools/hero_pixels.py then proves in the
     saved PNG that the only accent-strength ink left is the five node dots. */
  .gf-trace,.gf-glow,.gf-trace-fast{animation:none;display:none}
  .gf-ring{animation:none}
  *{transition-duration:1ms !important;animation-duration:1ms !important;
    animation-iteration-count:1 !important;scroll-behavior:auto !important}
}

/* Print: the page must not depend on script or motion to be readable. */
@media print{
  .js [data-reveal]{opacity:1;transform:none}
  .site-head{position:static}
  .marquee{animation:none}
  .gf-trace,.gf-glow,.gf-trace-fast{animation:none;display:none}
  .gf-ring{animation:none}
}
/* Review redesign: existing brand tokens, simpler hierarchy and robust reading. */
html{scroll-padding-top:96px;scroll-behavior:smooth}
body{background:var(--ground)}
.wrap{max-width:1280px}
.site-head{background:var(--ground);backdrop-filter:none;border-bottom:1px solid var(--line)}
.head-row{min-height:80px}
.nav{gap:24px}
.nav a[aria-current]::after{display:none}
.btn{min-height:48px;border-radius:8px}
.btn-primary{background:var(--accent);box-shadow:none}
.btn-primary:hover{background:var(--accent-hover);box-shadow:var(--shadow-card)}
.hero{padding:80px 0 32px;overflow:clip}
.hero::before{inset:0;background:radial-gradient(ellipse at 85% 35%,var(--tint) 0%,transparent 65%)}
.hero-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:48px;align-items:start}
.hero-message{display:flex;flex-direction:column;align-items:flex-start;gap:26px;min-width:0}
.hero h1{font-size:clamp(48px,5vw,72px);line-height:1.06;letter-spacing:-.045em;text-wrap:initial}
.grad-text{background:none;color:var(--accent)}
.hero-note{font-size:18px;max-width:48ch;line-height:1.7}
.hero-proof{display:flex;flex-wrap:wrap;gap:10px 20px;color:var(--muted);font-size:12px}
.hero-proof li::before{content:'✓';color:var(--accent);margin-right:6px}
.hero .stage{grid-column:2;grid-row:1;min-width:0;padding:0;position:relative}
.hero .window{transform:none;box-shadow:var(--shadow-lift);border-radius:16px;overflow:hidden}
.hero .gate{position:relative;right:auto;bottom:auto;width:calc(100% - 32px);margin:16px auto 0;background:var(--surface);box-shadow:var(--shadow-card)}
.hero .app{grid-template-columns:110px minmax(0,1fr)}
.hero .pane{padding:18px;gap:16px}
.hero .rail{padding:18px 12px}
.hero .code pre{font-size:11px;white-space:pre-wrap;overflow-wrap:anywhere}
.hero .trace li{font-size:11px;gap:7px}
.hero .trace code{font-size:9px}
.hero .pane-title{font-size:19px}
.hero .omni{font-size:10px}
.hero .meter i{width:50%}
.hero-process{grid-column:1/-1;border-top:1px solid var(--line);padding-top:24px;margin-top:16px}
.hero-process>.eyebrow{font-size:10px;color:var(--muted)}
.hero .gfield{width:100%;margin-inline:0;--gf-h:120px}
.hero .gf-name{font-size:11px}
.hero .gf-spec{z-index:5}
.section{padding-block:88px}
.sec-head{max-width:760px;margin-bottom:40px;gap:16px}
h2{font-size:clamp(34px,3.7vw,50px);line-height:1.12;letter-spacing:-.03em}
h3{line-height:1.25}
.lede{font-size:17px;line-height:1.7}
.services::before,.work-section::before{display:none}
.card{padding:32px 26px;box-shadow:none;border-radius:12px}
.card:hover,.wrow:hover{transform:none}
.card h3{font-size:27px}
.card .what{font-size:15px;line-height:1.7}
.diff{margin-top:48px}
.wrow{padding:32px;background:var(--surface);box-shadow:none;border:1px solid var(--line);border-radius:12px;gap:24px 40px}
.work{gap:24px}
.work-section{background:var(--surface-2)}
.wrow h3{font-size:27px}
.wrow .ev{font-size:15px;line-height:1.75}
.w-shot{overflow:hidden;border-radius:8px}
.w-shot img,.w-shot video{display:block;width:100%;height:auto}
.contact-card{box-shadow:none;background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:28px}
.cta-panel{background:var(--tint);border:1px solid var(--accent-100);border-radius:16px;box-shadow:none;padding:48px}
.cta-panel::before{display:none}
.cta-panel .note{margin-top:22px;max-width:65ch}
#audit .note{margin-top:20px}
#audit .cta-row{margin-top:24px}
.site-foot{padding:48px 0 32px;background:var(--band)}
.footer-links{display:flex;flex-wrap:wrap;gap:16px 28px;margin:30px 0;font-size:14px}
.footer-links a{color:var(--on-band)}
/* Content remains readable even if an observer or animation fails. */
.js [data-reveal]{opacity:1;transform:none;transition:none}
@media(min-width:1024px){.nav-drawer[open] .nav{display:flex}.nav-drawer:not([open])::details-content{content-visibility:visible}}
@media(max-width:1023px){.hero-grid{grid-template-columns:1fr;gap:36px}.hero .stage{grid-column:1;grid-row:auto;width:100%;max-width:620px;margin:auto}.hero-message{max-width:700px}.hero{padding-top:48px}.hero h1{font-size:clamp(48px,7.5vw,68px)}.hero-process{margin-top:0}.head-row{min-height:68px}}
@media(max-width:600px){.section{padding-block:56px}.hero{padding-top:36px}.hero h1{font-size:48px}.hero-message{gap:20px}.hero-note{font-size:16px}.hero-proof{font-size:11px;gap:8px 14px}.hero .app{grid-template-columns:1fr}.hero .rail{display:none}.hero .pane{padding:18px}.hero .trace li{font-size:11px}.hero .gate{width:100%}.hero-process{padding-top:20px}.hero .gfield{height:auto;margin-top:18px}.hero .gf-svg{display:none}.hero .gf-nodes{position:static;display:grid;grid-template-columns:1fr;gap:0;height:auto}.hero .gf-nodes li{position:relative;display:flex;align-items:center;gap:14px;min-height:52px;padding:12px 0;border-bottom:1px solid var(--line)}.hero .gf-dot{position:static;transform:none;width:8px;height:8px;flex:0 0 8px}.hero .gf-ring{display:none}.hero .gf-lab{position:static;display:flex;flex-direction:row;gap:12px;transform:none;width:auto;text-align:left}.hero .gf-name{font-size:13px}.hero .gf-spec{left:0;right:0;top:100%;width:auto;transform:none}.card,.wrow{padding:24px}.cta-panel{padding:28px 22px}.head-cta{font-size:12px;padding-inline:12px}.brand{font-size:18px}.head-row{gap:10px}.hero .chrome{gap:8px;padding:12px}.hero .chrome .chip{display:none}.hero .omni{font-size:10px}footer-links{gap:16px 22px}}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}.hero *{animation:none!important}}
.hero .gf-name{display:block}
.hero .stage{gap:0}
@media(max-width:600px){.hero .gf-name{text-align:left}.hero .gf-nodes li::after{display:none}.hero .gf-lab{letter-spacing:0}.hero .gf-spec{max-width:100%}.head-cta{white-space:nowrap}.brand .mark{width:26px;height:26px}.head-row{gap:8px}}

/* Content upgrade and animated project artwork, 2026-10-16. */
.cards .eyebrow{margin-bottom:22px;font-size:10px}
.cards .cta-link{margin-top:22px;align-self:flex-start}
.service-points{margin:24px 0;display:grid;gap:12px;font-size:14px;color:var(--muted)}
.service-points li{padding-left:18px;position:relative}
.service-points li::before{content:'·';position:absolute;left:0;color:var(--accent);font-weight:600}
.commitments{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:32px;margin-top:40px;padding-top:32px;border-top:1px solid var(--line)}
.commitments h3{font-size:23px;margin-bottom:10px}
.commitments p{font-size:14px;color:var(--muted)}
.delivery-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:32px}
.delivery-grid li{padding-top:24px;border-top:1px solid var(--band-line)}
.delivery-grid h3{font-size:28px;color:var(--on-band);margin:20px 0 14px}
.delivery-grid p{font-size:15px;color:var(--on-band-muted);line-height:1.7}
.delivery-grid b{display:block;font-size:13px;color:var(--on-band);margin-top:24px}
.delivery-grid .eyebrow{color:var(--on-band-accent)}
.project-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;align-items:start}
.project-card{min-width:0;border:1px solid var(--line);border-radius:14px;background:var(--surface);overflow:hidden;transition:transform .3s ease,box-shadow .3s ease}
.project-card:hover{transform:translateY(-5px);box-shadow:var(--shadow-card)}
.project-media{aspect-ratio:3/2;overflow:hidden;position:relative;background:var(--tint)}
.project-media img{display:block;width:100%;height:100%;object-fit:cover;transform-origin:center;animation:project-art-drift 14s ease-in-out infinite alternate;animation-play-state:paused}
.project-media[data-motion="active"] img{animation-play-state:running}
.project-card:nth-child(2) img{animation-delay:-5s;transform-origin:60% 45%}
.project-card:nth-child(3) img{animation-delay:-9s;transform-origin:40% 55%}
@keyframes project-art-drift{from{transform:scale(1.015) translate3d(-.3%,0,0)}to{transform:scale(1.085) translate3d(.3%,-.5%,0)}}
.project-body{padding:26px}
.project-body>.eyebrow{font-size:10px;margin-bottom:16px}
.project-body h3{font-size:28px;margin-bottom:14px}
.project-body p{font-size:14px;line-height:1.7;color:var(--muted)}
.project-detail{margin-top:22px;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.project-detail summary,.faq-accordion summary{cursor:pointer;padding:18px 0;font-size:14px;font-weight:500;min-height:48px}
.project-detail dl{font-size:13px;margin:0 0 20px}
.project-detail dt{font-weight:600;margin-top:14px}
.project-detail dd{margin:6px 0;color:var(--muted)}
.project-detail .note{padding-bottom:20px;font-size:12px}
.project-body>.cta-link{margin-top:20px;font-size:10px;letter-spacing:.04em}
.faq-accordion{max-width:850px;border-top:1px solid var(--line)}
.faq-accordion details{border-bottom:1px solid var(--line)}
.faq-accordion summary{font-size:18px;padding:24px 0}
.faq-accordion p{max-width:72ch;padding:0 0 24px;color:var(--muted);font-size:15px}
.audit-layout{display:grid;grid-template-columns:1fr 1fr;gap:60px;align-items:start}
.audit-layout .note{font-size:12px;line-height:1.6}
@media(max-width:1000px){.project-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.project-card:last-child{grid-column:1/-1;max-width:620px}.delivery-grid{gap:24px}}
@media(max-width:700px){.project-grid,.delivery-grid,.commitments,.audit-layout{grid-template-columns:1fr}.project-card:last-child{grid-column:auto;max-width:none}.audit-layout{gap:24px}.project-body{padding:24px}.commitments{gap:24px}.delivery-grid{gap:30px}}
@media(prefers-reduced-motion:reduce){.project-media img{animation:none!important;transform:none!important}.project-card{transition:none}.project-card:hover{transform:none}}
@media print{.project-media img{animation:none!important;transform:none!important}}

.motion-toggle{margin:0 0 24px;font-size:12px;cursor:pointer}
@media(prefers-reduced-motion:reduce){.motion-toggle{display:none}}

/* Real animated explanations replace decorative image transforms. */
.project-grid{grid-template-columns:1fr;gap:28px}
.project-card{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);align-items:center;transition:none}
.project-card:hover{transform:none;box-shadow:none}
.project-media{aspect-ratio:3/2;background:var(--ground);border-right:1px solid var(--line)}
.workflow-demo{display:block;width:100%;height:100%;object-fit:contain;background:var(--ground)}
.project-card:last-child{max-width:none;grid-column:auto}
.project-body{padding:30px}
@media(max-width:800px){.project-card{grid-template-columns:1fr}.project-media{border-right:0;border-bottom:1px solid var(--line)}.project-body{padding:24px}}
@media(prefers-reduced-motion:reduce){.motion-toggle{display:inline-flex}}

/* ---- hero fold + labels, 2026-10-24 -------------------------------------
   The message column is top-aligned (above) so the primary action stays under
   the explanation instead of being pushed below a short viewport by vertical
   centring against the taller sample window. On a 720px-high desktop the
   heading steps down one size and the note tightens, which keeps headline,
   explanation and the "Discuss your workflow" button in the first viewport.
   On a phone the primary action owns the full width and the secondary link
   sits under it as its own 44px row. */
@media (min-width:1000px) and (max-height:780px){
  .hero{padding-top:48px}
  .hero-message{gap:20px}
  .hero h1{font-size:clamp(44px,4.4vw,64px)}
  .hero-note{font-size:17px;line-height:1.55}
}
@media (max-width:600px){
  .hero .cta-row{display:grid;gap:12px;justify-items:stretch;align-self:stretch;width:100%}
  .hero .cta-row .btn{width:100%}
  .hero .cta-row .cta-link{justify-content:flex-start;width:fit-content}
}
/* What each animation is, next to its card: only the enquiry intake is a
   working internal build; the other two are illustrations. No video is a
   recording of a client system. */
.project-flag{margin:10px 0 0;font:400 12px/1.5 var(--font-mono);
  letter-spacing:.02em;color:var(--faint)}
.project-flag::before{content:'▸ ';color:var(--accent)}
.demo-flag{margin:14px 0 0;font:400 12px/1.5 var(--font-mono);
  letter-spacing:.02em;color:var(--faint);max-width:72ch}
.demo-flag::before{content:'▸ ';color:var(--accent)}


/* ---- sitelink pages: composition only, tokens come from the block above ---- */
.page-head{padding:clamp(34px,4.5vw,62px) 0 clamp(22px,3vw,34px);border-bottom:1px solid var(--line);background:var(--surface)}
.page-head .wrap{display:grid;gap:var(--space-3)}
.page-head h1{font-family:var(--font-display);font-size:clamp(1.9rem,3.6vw,3rem);line-height:var(--leading-tight);letter-spacing:var(--tracking-tight);margin:0;color:var(--ink);max-width:24ch}
.page-head .lede{max-width:64ch;color:var(--muted);margin:0}
.page-meta{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-5);margin-top:var(--space-2);font-family:var(--font-mono);font-size:var(--size-mono);letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--muted)}
.page-meta span{display:inline-flex;align-items:center;gap:8px}
.page-meta span::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--accent)}
.nav a[aria-current="page"]{color:var(--ink);box-shadow:inset 0 -2px 0 var(--accent)}
.cards .card .cta-link{margin-top:auto}
.contact-layout{display:grid;grid-template-columns:1.25fr .78fr;gap:clamp(22px,4vw,54px);align-items:start}
.cform{display:grid;gap:var(--space-4);background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:clamp(18px,3vw,30px);box-shadow:var(--shadow-card)}
.cform .cf-field{display:grid;gap:6px}
.cform label{font-family:var(--font-mono);font-size:var(--size-mono-cap);letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--muted)}
.cform label .req{color:var(--accent)}
.cform input,.cform select,.cform textarea{width:100%;font:inherit;color:var(--ink);background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--radius-sm);padding:12px 14px}
.cform textarea{min-height:104px;resize:vertical}
.cform input:focus-visible,.cform select:focus-visible,.cform textarea:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.cform .row{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-4)}
.cform .cform-note{font-size:var(--size-small);color:var(--muted)}
.cform-status{margin:0;padding:12px 14px;border-radius:var(--radius-sm);border:1px solid var(--line);font-size:var(--size-small);color:var(--muted)}
.cform-status[data-state="ok"]{border-color:var(--accent);color:var(--ink);background:var(--accent-soft)}
.cform-status[data-state="err"]{border-color:var(--accent-deep);color:var(--ink)}
.cform-status[hidden]{display:none}
.cf-field-error{margin:6px 0 0;color:#7a1020;font-size:var(--size-small);line-height:1.4}
.cform [aria-invalid="true"]{border-color:#7a1020}
.cform .btn[disabled]{opacity:.6;cursor:progress}
.aside-card{display:grid;gap:var(--space-3);background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius-lg);padding:clamp(18px,3vw,28px)}
.aside-card h2{font-family:var(--font-display);font-size:var(--size-h4);margin:0;color:var(--ink)}
.aside-card ol,.aside-card ul{margin:0;padding-left:1.1em;color:var(--muted);display:grid;gap:10px}
.aside-card .who{font-family:var(--font-mono);font-size:var(--size-mono);color:var(--muted)}
.principles .card p{color:var(--muted)}
@media (max-width:900px){.contact-layout{grid-template-columns:1fr}.cform .row{grid-template-columns:1fr}}
