/* GENERATED FROM tokens.json — do not hand-edit.
   
   The Property Platform — master design tokens.
   
   Source of truth: tokens/tokens.json (light + all non-colour tiers) and
   tokens/tokens.dark.json (dark-theme semantic overrides), both in the
   Design Tokens Community Group format. Edit those, then run `npm run build`
   (or `node tools/build.mjs`). Any edit made here is lost on the next build.
   
   Three tiers per the canonical Design System page:
   primitive (palette + scales) -> semantic (jobs) -> component (bounded
   overrides). Components reference --tpp-<semantic> or --tpp-<component>-*
   only — never --tpp-palette-* and never a raw value.
*/

:root {
  /* ---- primitive: palette ---- */
  /* Raw values. Never reference these directly in a component — use the
     semantic layer. */
  --tpp-palette-brand-50: #ecf6fd;
  --tpp-palette-brand-100: #d7edfb;
  --tpp-palette-brand-200: #b5ddf6;
  --tpp-palette-brand-300: #7bc5ef;
  --tpp-palette-brand-400: #00aae9;  /* Supplied by TPP — appears in the logo artwork. Do not alter. */
  --tpp-palette-brand-500: #028dc5;  /* Supplied by TPP — appears in the logo artwork. Do not alter. */
  --tpp-palette-brand-600: #0370a0;  /* Supplied by TPP — appears in the logo artwork. Do not alter. */
  --tpp-palette-brand-700: #05527c;  /* Supplied by TPP — appears in the logo artwork. Do not alter. */
  --tpp-palette-brand-800: #063557;  /* Supplied by TPP — appears in the logo artwork. Do not alter. */
  --tpp-palette-brand-900: #081833;  /* Supplied by TPP — appears in the logo artwork. Do not alter. */
  --tpp-palette-brand-950: #02091d;
  --tpp-palette-neutral-0: #ffffff;
  --tpp-palette-neutral-50: #f5f7f9;
  --tpp-palette-neutral-100: #edf1f3;
  --tpp-palette-neutral-200: #e1e5e9;
  --tpp-palette-neutral-300: #ced3d8;
  --tpp-palette-neutral-400: #abb2b8;
  --tpp-palette-neutral-500: #858d94;
  --tpp-palette-neutral-600: #646d74;
  --tpp-palette-neutral-700: #475056;
  --tpp-palette-neutral-800: #2d373e;
  --tpp-palette-neutral-900: #19232a;
  --tpp-palette-neutral-950: #06121a;
  --tpp-palette-success-400: #4dbf74;
  --tpp-palette-success-600: #137d41;
  --tpp-palette-warning-400: #f2b036;
  --tpp-palette-warning-600: #a46400;
  /* Added 14 September 2026 (kit decision D30): the dark theme's
     status.danger. danger-400 measured 4.22:1 as message text on the dark
     raised surface (neutral-800), under the 4.5:1 floor; this step measures
     5.22:1 there and 6.85:1 on the dark page. Not used in the light theme. */
  --tpp-palette-danger-300: #fa8a80;
  --tpp-palette-danger-400: #f66d62;
  --tpp-palette-danger-600: #c33530;

  /* ---- semantic: light theme (default) ---- */
  --tpp-surface-page: var(--tpp-palette-neutral-0);
  --tpp-surface-raised: var(--tpp-palette-neutral-0);
  --tpp-surface-sunken: var(--tpp-palette-neutral-50);
  /* One step below surface.sunken in the light theme: the deeper of the two
     tonal chapter grounds a marketing page may use (kit D26 item 2a, 10
     September 2026, lane-owner word). Neutral in both themes; blue never
     grounds a surface (D18). In the dark theme it resolves to neutral-950,
     the same step as surface.sunken, because the ramp has no deeper step and
     neutral-800 fails link contrast. Text roles on it are contrast-enforced.
     No control sits on it: it is a ground for prose and images, so the
     interactive border is not enforced there (it measures 2.96:1). */
  --tpp-surface-sunken-deep: var(--tpp-palette-neutral-100);
  /* The ground behind a person's own turn in the talk panel (component map
     entry 6, kit D35 decision 1, ruled A on 21 September 2026: the person's
     turn takes a blue fill). It is a role rather than a reuse of
     color.brand.subtle because the two themes need different steps: brand-50
     reads on the light panel at 1.10:1, but brand-800, which brand.subtle
     resolves to in the dark theme, measures 1.04:1 against surface.raised
     and the plate all but vanishes. The dark value is brand-700, the
     adjacent locked ramp step (D3), at 1.45:1. Blue does not ground a
     surface here (D18): this is a turn's plate inside a panel, not a page
     ground, and the page's one filled interactive area is unaffected. */
  --tpp-surface-turn: var(--tpp-palette-brand-50);
  --tpp-surface-inverse: var(--tpp-palette-brand-900);
  /* The brand panel: the one navy block a marketing page may carry (D18),
     and the ground of a web page's artwork band (D47). Does NOT flip in the
     dark theme, unlike surface.inverse. Added 10 September 2026 (kit D25
     item 5, closing O24) by lane-owner word: the footer band stays navy in
     dark mode. */
  --tpp-surface-panel: var(--tpp-palette-brand-900);
  --tpp-text-primary: var(--tpp-palette-neutral-900);
  --tpp-text-secondary: var(--tpp-palette-neutral-700);
  --tpp-text-muted: var(--tpp-palette-neutral-600);
  --tpp-text-inverse: var(--tpp-palette-neutral-0);
  /* Secondary text on the inverse surface (the navy block in light, white in
     dark). Added 9 September 2026 (D23 item 5) for lower-third role lines
     and band captions; before it, surfaces reached for an opacity, which is
     a raw value. */
  --tpp-text-inverse-secondary: var(--tpp-palette-neutral-300);
  --tpp-text-on-brand: var(--tpp-palette-neutral-0);
  --tpp-text-on-panel: var(--tpp-palette-neutral-0);  /* Text on surface.panel, both themes. Added 10 September 2026 (D25). */
  /* Secondary text on surface.panel, both themes. Added 10 September 2026
     (D25). */
  --tpp-text-on-panel-secondary: var(--tpp-palette-neutral-300);
  --tpp-border-subtle: var(--tpp-palette-neutral-200);
  --tpp-border-default: var(--tpp-palette-neutral-300);
  --tpp-border-interactive: var(--tpp-palette-neutral-500);
  --tpp-border-strong: var(--tpp-palette-neutral-600);
  --tpp-brand-default: var(--tpp-palette-brand-600);
  --tpp-brand-hover: var(--tpp-palette-brand-700);
  --tpp-brand-active: var(--tpp-palette-brand-800);
  --tpp-brand-subtle: var(--tpp-palette-brand-50);
  --tpp-brand-accent: var(--tpp-palette-brand-400);
  --tpp-focus-ring: var(--tpp-palette-brand-600);
  --tpp-status-success: var(--tpp-palette-success-600);
  --tpp-status-warning: var(--tpp-palette-warning-600);
  --tpp-status-danger: var(--tpp-palette-danger-600);
  --tpp-status-info: var(--tpp-palette-brand-600);

  /* ---- marketing layer (D67): light theme — public marketing surfaces only ---- */
  /* The hero aurora's linear ground, top. The aurora is board L of the
     homepage canvas as picked on AA2 (D68): pale by day, deep by night. */
  --tpp-mkt-aurora-ground-1: var(--tpp-palette-neutral-0);
  /* The aurora's linear ground, middle. */
  --tpp-mkt-aurora-ground-2: var(--tpp-palette-neutral-50);
  /* The aurora's linear ground, foot. */
  --tpp-mkt-aurora-ground-3: var(--tpp-palette-brand-100);
  /* The aurora's lowest blob, centred below the band's foot on the left. It
     lies under the plates and below the copy, never behind text. */
  --tpp-mkt-aurora-1: var(--tpp-palette-brand-300);
  /* The aurora's strongest blob, below the band's foot. Below the copy,
     never behind text. */
  --tpp-mkt-aurora-2: var(--tpp-palette-brand-200);
  /* The aurora's blob at the lower right, behind the plates. Brand-700 by
     night: on a phone the hero's secondary button sits at its edge, and its
     blue label measured 4.29:1 over brand-500. */
  --tpp-mkt-aurora-3: var(--tpp-palette-brand-100);
  /* The aurora's blob at the upper left, behind the headline. */
  --tpp-mkt-aurora-4: var(--tpp-palette-brand-50);
  /* The blended ground under the moments and the section after them (D68),
     at its top and foot. */
  --tpp-mkt-ground-1: var(--tpp-palette-neutral-50);
  /* The blended ground's second stop. */
  --tpp-mkt-ground-2: var(--tpp-palette-neutral-50);
  /* The blended ground's deepest stop in the dark theme, and its white foot
     in the light theme. */
  --tpp-mkt-ground-3: var(--tpp-palette-neutral-0);
  /* The blended ground's glow at the left. */
  --tpp-mkt-ground-glow-1: var(--tpp-palette-brand-200);
  /* The blended ground's glow at the upper right. */
  --tpp-mkt-ground-glow-2: var(--tpp-palette-brand-100);
  /* The blended ground's glow at the lower right. */
  --tpp-mkt-ground-glow-3: var(--tpp-palette-brand-50);
  /* The tinted band behind Built for where you sit (D68): its linear
     ground's start, along the mark's lean. */
  --tpp-mkt-band-from: var(--tpp-palette-brand-50);
  /* The tinted band's linear ground's end. */
  --tpp-mkt-band-to: var(--tpp-palette-brand-100);
  /* The tinted band's glow at the upper right. */
  --tpp-mkt-band-glow-1: var(--tpp-palette-brand-200);
  /* The tinted band's glow at the lower left. */
  --tpp-mkt-band-glow-2: var(--tpp-palette-brand-100);
  /* The blue panel inside the tinted band: its gradient's start, at the
     upper right. White text only. */
  --tpp-mkt-panel-from: var(--tpp-palette-brand-600);
  /* The blue panel's gradient end, at the lower left. */
  --tpp-mkt-panel-to: var(--tpp-palette-brand-900);
  /* The blue panel's glow in its lower right corner. No text sits on it
     unplated: the points there ride on panel-plate. */
  --tpp-mkt-panel-glow: var(--tpp-palette-brand-400);
  /* The small glass plates carrying the panel's points over its glow; dark
     enough that white text holds 4.5:1 over the brightest blue. */
  --tpp-mkt-panel-plate: color-mix(in srgb, var(--tpp-palette-brand-900) 72%, transparent);
  /* The questions section's ground (D68). */
  --tpp-mkt-corner-ground: var(--tpp-palette-neutral-50);
  /* The questions section's one glow, in its lower left corner. */
  --tpp-mkt-corner-glow: var(--tpp-palette-brand-100);
  /* The plain sections' ground on a marketing page: white by day, the ramp's
     deepest navy by night (D68, amending D18's neutral dark surfaces for
     public marketing pages). */
  --tpp-mkt-page: var(--tpp-palette-neutral-0);
  /* The footer's navy ground (board X). */
  --tpp-mkt-foot: var(--tpp-palette-brand-900);
  /* Headline and body text on every marketing ground above. */
  --tpp-mkt-text: var(--tpp-palette-neutral-900);
  /* Secondary text, captions and the illustrative labels on every marketing
     ground. Neutral-200 by night, because neutral-300 falls to 4.24:1 on
     glass over the strongest glow. */
  --tpp-mkt-text-secondary: var(--tpp-palette-neutral-700);
  /* Text on the blue panel and the footer, both themes. */
  --tpp-mkt-text-on-blue: var(--tpp-palette-neutral-0);
  /* Secondary text on the blue panel and the footer. */
  --tpp-mkt-text-on-blue-secondary: var(--tpp-palette-neutral-100);
  /* Icons, the moments' tags and a filled bar: blue at text weight (D18). */
  --tpp-mkt-accent: var(--tpp-palette-brand-600);
  /* The list numbers and the one coloured phrase in a heading. Brand-700 by
     day and brand-200 by night: brand-600 and brand-400 fall below 4.5:1
     where the ground's glows lie. */
  --tpp-mkt-accent-strong: var(--tpp-palette-brand-700);
  /* A tag's label on its tint. White by night, because no blue step holds
     4.5:1 on the tint over the strongest glow. */
  --tpp-mkt-tag-text: var(--tpp-palette-brand-600);
  /* A tag's or an outgoing message's tint; never a filled action (D65). */
  --tpp-mkt-tint: var(--tpp-palette-brand-100);
  /* Hairlines and chip edges on the marketing grounds. */
  --tpp-mkt-line: var(--tpp-palette-neutral-200);
  /* A glass card's fill, top (D68: the moments, the questions, the tab rail,
     the small plates). */
  --tpp-mkt-glass-top: color-mix(in srgb, var(--tpp-palette-neutral-0) 66%, transparent);
  /* A glass card's fill, foot. */
  --tpp-mkt-glass-bottom: color-mix(in srgb, var(--tpp-palette-neutral-0) 66%, transparent);
  /* A glass card's one-pixel edge. */
  --tpp-mkt-glass-edge: color-mix(in srgb, var(--tpp-palette-neutral-0) 95%, transparent);
  /* The inset highlight along a glass card's top edge. */
  --tpp-mkt-glass-highlight: var(--tpp-palette-neutral-0);
  /* A chip or message inside a glass card. */
  --tpp-mkt-chip: color-mix(in srgb, var(--tpp-palette-neutral-0) 85%, transparent);
  /* The ring and glow a glass card takes on hover or focus. Faded in by
     opacity; nothing lifts (D33). */
  --tpp-mkt-hover-ring: color-mix(in srgb, var(--tpp-palette-brand-600) 35%, transparent);
  /* The chosen tab's fill in a marketing tab rail: navy by day, white by
     night. Not the interactive blue, so D18's one filled blue area stays the
     hero's primary button. */
  --tpp-mkt-button: var(--tpp-palette-brand-900);
  /* The chosen tab's label. */
  --tpp-mkt-button-ink: var(--tpp-palette-neutral-0);
  /* The illustrative product card in How joining works: light in both
     themes, because it depicts a screen. */
  --tpp-mkt-card: color-mix(in srgb, var(--tpp-palette-neutral-0) 96%, transparent);
  /* A row inside the product card. */
  --tpp-mkt-card-row: var(--tpp-palette-neutral-50);
  /* Text on the product card. */
  --tpp-mkt-card-text: var(--tpp-palette-neutral-900);
  /* Secondary text on the product card. */
  --tpp-mkt-card-text-secondary: var(--tpp-palette-neutral-600);
  /* An icon or action word on the product card. */
  --tpp-mkt-card-accent: var(--tpp-palette-brand-600);
  /* An unfilled progress dot on the product card. */
  --tpp-mkt-card-dot: var(--tpp-palette-neutral-200);
  /* A filled progress dot on the product card. */
  --tpp-mkt-card-dot-on: var(--tpp-palette-brand-500);
  /* The hero set-piece's top plate, a gradient along the mark's lean (D42,
     D47); it fades toward its foot. */
  --tpp-mkt-plate-1-from: var(--tpp-palette-brand-300);
  --tpp-mkt-plate-1-to: color-mix(in srgb, var(--tpp-palette-brand-400) 40%, transparent);
  /* The middle plate, the one that turns in the Set motion's Register cue
     (D13). */
  --tpp-mkt-plate-2-from: var(--tpp-palette-brand-400);
  --tpp-mkt-plate-2-to: color-mix(in srgb, var(--tpp-palette-brand-500) 30%, transparent);
  /* The bottom plate. */
  --tpp-mkt-plate-3-from: var(--tpp-palette-brand-500);
  --tpp-mkt-plate-3-to: color-mix(in srgb, var(--tpp-palette-brand-700) 40%, transparent);
  /* The sticky header's glass, once the page has scrolled. Opaque enough
     that its text passes 4.5:1 over the darkest thing behind it. */
  --tpp-mkt-glass-fill: color-mix(in srgb, var(--tpp-palette-neutral-0) 90%, transparent);
  /* The hero's aurora (board L, D68). The lower blobs sit below the copy;
     the copy sits in the upper half of the band. */
  --tpp-mkt-gradient-aurora: radial-gradient(55% 60% at 30% 118%, var(--tpp-mkt-aurora-1) 0%, transparent 55%), radial-gradient(70% 80% at 45% 110%, var(--tpp-mkt-aurora-2) 0%, transparent 62%), radial-gradient(80% 70% at 85% 95%, var(--tpp-mkt-aurora-3) 0%, transparent 65%), radial-gradient(90% 70% at 10% 20%, var(--tpp-mkt-aurora-4) 0%, transparent 70%), linear-gradient(180deg, var(--tpp-mkt-aurora-ground-1) 0%, var(--tpp-mkt-aurora-ground-2) 45%, var(--tpp-mkt-aurora-ground-3) 100%);
  /* The blended ground from the moments to the office list (D68), one
     continuous field with no hard edge. */
  --tpp-mkt-gradient-ground: radial-gradient(900px 640px at 8% 61%, var(--tpp-mkt-ground-glow-1), transparent 70%), radial-gradient(760px 560px at 95% 0%, var(--tpp-mkt-ground-glow-2), transparent 70%), radial-gradient(700px 520px at 100% 83%, var(--tpp-mkt-ground-glow-3), transparent 70%), linear-gradient(180deg, var(--tpp-mkt-ground-1) 0%, var(--tpp-mkt-ground-2) 52%, var(--tpp-mkt-ground-3) 100%);
  /* The tinted band behind Built for where you sit (D68). */
  --tpp-mkt-gradient-band: radial-gradient(60% 70% at 100% 0%, var(--tpp-mkt-band-glow-1) 0%, transparent 70%), radial-gradient(55% 65% at 0% 100%, var(--tpp-mkt-band-glow-2) 0%, transparent 70%), linear-gradient(216.26deg, var(--tpp-mkt-band-from) 0%, var(--tpp-mkt-band-to) 100%);
  /* The blue panel inside the tinted band. White text only; its points ride
     on panel-plate. */
  --tpp-mkt-gradient-panel: radial-gradient(60% 80% at 100% 100%, var(--tpp-mkt-panel-glow) 0%, transparent 60%), linear-gradient(216.26deg, var(--tpp-mkt-panel-from) 0%, var(--tpp-mkt-panel-to) 100%);
  /* The questions section's ground: one glow in the lower left. */
  --tpp-mkt-gradient-corner: radial-gradient(45% 55% at 0% 100%, var(--tpp-mkt-corner-glow) 0%, transparent 70%), var(--tpp-mkt-corner-ground);
  /* A glass card's fill. */
  --tpp-mkt-gradient-glass: linear-gradient(180deg, var(--tpp-mkt-glass-top), var(--tpp-mkt-glass-bottom));
  /* The small artwork band on the moments' presentation card. */
  --tpp-mkt-gradient-thumb: linear-gradient(216.26deg, var(--tpp-palette-brand-500), var(--tpp-palette-brand-800));
  --tpp-mkt-gradient-plate-1: linear-gradient(216.26deg, var(--tpp-mkt-plate-1-from) 0%, var(--tpp-mkt-plate-1-to) 100%);
  --tpp-mkt-gradient-plate-2: linear-gradient(216.26deg, var(--tpp-mkt-plate-2-from) 0%, var(--tpp-mkt-plate-2-to) 100%);
  --tpp-mkt-gradient-plate-3: linear-gradient(216.26deg, var(--tpp-mkt-plate-3-from) 0%, var(--tpp-mkt-plate-3-to) 100%);
  --tpp-mkt-shadow-glass: 0 30px 60px -36px rgba(8, 24, 51, 0.28);
  /* The glow under a glass card on hover, drawn on a pseudo-element and
     faded in by opacity. */
  --tpp-mkt-shadow-glow: 0 30px 80px -40px rgba(3, 112, 160, 0.35);

  /* ---- component tier: colour, theme-scoped (D76) ---- */
  /* Interactive boundary — must hold ≥3:1. Never border.default on an input. */
  --tpp-input-border-color: var(--tpp-border-interactive);
  /* RULED (kit D33 decision 2 E, 21 September 2026): the card-link's hover
     is this translucent wash of the surface's own text colour over the card,
     plus the hairline stepping from border.subtle to border.default; the
     card darkens a step in the light theme, lightens a step in the dark one,
     and stays distinct on every ground; the title does not change and
     nothing lifts (D22). A CSS expression filed as a string; the renderer
     passes it through. The strength is a token value, never set on a page. */
  --tpp-card-hover-overlay: color-mix(in srgb, var(--tpp-text-primary) 6%, transparent);
  /* The card's hairline, and since decision 1 (RULED B, 21 September 2026)
     its whole boundary at rest. Per theme since D76 (1 October 2026,
     amending D33's 'never border.default' note): border.default in the light
     theme, so a white card reads against a white page, and border.subtle in
     the dark theme (tokens.dark.json). Decorative, so no contrast floor; the
     build records both readings. Emitted in every theme block, so a surface
     forced to a theme resolves its own step. */
  --tpp-card-border-color: var(--tpp-border-default);
  /* The stage is a ground, never an object: no hairline, no shadow
     (elevation-0). */
  --tpp-stage-fill: var(--tpp-surface-sunken);
  /* The plate behind a person's own turn, right-aligned, the spoken corner
     stepped to radius.sm (D35 decision 1, ruled A). TPP's own turn keeps
     color.surface.sunken. */
  --tpp-talk-turn-fill: var(--tpp-surface-turn);
}

/* ---- semantic: dark theme ---- */
@media (prefers-color-scheme: dark) {
  :root {
    /* Dark theme overrides. Same semantic keys as tokens.json, remapped onto
       the same palette. Since D18 the dark surfaces come from the neutral
       ramp, not the brand ramp: navy is an accent in this theme, not the
       substrate. */
    --tpp-surface-page: var(--tpp-palette-neutral-900);
    --tpp-surface-raised: var(--tpp-palette-neutral-800);
    --tpp-surface-sunken: var(--tpp-palette-neutral-950);
    /* The dark ramp has no step below neutral-950, and neutral-800 fails
       link contrast (brand-400 at 4.4:1), so both chapter grounds resolve to
       950 in the dark theme; the chapters read against the page, not against
       each other. */
    --tpp-surface-sunken-deep: var(--tpp-palette-neutral-950);
    /* Not brand-800. brand.subtle resolves to brand-800 in this theme and
       measures 1.04:1 against surface.raised, so the turn's plate is
       invisible and ruling A silently becomes ruling C for every dark-theme
       viewer. brand-700 measures 1.45:1, slightly more separation than the
       light theme's own 1.10:1, and carries text.primary at 7.12:1. */
    --tpp-surface-turn: var(--tpp-palette-brand-700);
    --tpp-surface-inverse: var(--tpp-palette-neutral-0);
    /* Stays navy in the dark theme by ruling (D25 item 5): the panel is a
       decorative brand block, not a themed surface. */
    --tpp-surface-panel: var(--tpp-palette-brand-900);
    --tpp-text-primary: var(--tpp-palette-neutral-100);
    --tpp-text-secondary: var(--tpp-palette-neutral-300);
    --tpp-text-muted: var(--tpp-palette-neutral-400);
    --tpp-text-inverse: var(--tpp-palette-neutral-900);
    /* Secondary text on the inverse surface, which is white in the dark
       theme (D23 item 5 ruled neutral-300 on navy, neutral-700 on white).
       Repaired 14 September 2026: the override had been filed under
       color.surface.inverse-secondary, a token the base set does not define,
       so the role stayed at neutral-300 and measured 1.51:1 on the dark
       theme's white inverse plate. */
    --tpp-text-inverse-secondary: var(--tpp-palette-neutral-700);
    --tpp-text-on-brand: var(--tpp-palette-brand-900);
    --tpp-text-on-panel: var(--tpp-palette-neutral-0);
    --tpp-text-on-panel-secondary: var(--tpp-palette-neutral-300);
    --tpp-border-subtle: var(--tpp-palette-neutral-700);
    --tpp-border-default: var(--tpp-palette-neutral-600);
    --tpp-border-interactive: var(--tpp-palette-neutral-500);
    --tpp-border-strong: var(--tpp-palette-neutral-400);
    --tpp-brand-default: var(--tpp-palette-brand-400);
    --tpp-brand-hover: var(--tpp-palette-brand-300);
    --tpp-brand-active: var(--tpp-palette-brand-200);
    --tpp-brand-subtle: var(--tpp-palette-brand-800);
    --tpp-brand-accent: var(--tpp-palette-brand-400);
    --tpp-focus-ring: var(--tpp-palette-brand-400);
    --tpp-status-success: var(--tpp-palette-success-400);
    --tpp-status-warning: var(--tpp-palette-warning-400);
    /* danger-300 since 14 September 2026 (D30): danger-400 fails 4.5:1 as
       message text on surface.raised in this theme (4.22:1); 300 measures
       5.22:1 there. */
    --tpp-status-danger: var(--tpp-palette-danger-300);
    --tpp-status-info: var(--tpp-palette-brand-400);
    --tpp-mkt-aurora-ground-1: var(--tpp-palette-brand-950);
    --tpp-mkt-aurora-ground-2: var(--tpp-palette-brand-900);
    --tpp-mkt-aurora-ground-3: var(--tpp-palette-brand-800);
    --tpp-mkt-aurora-1: var(--tpp-palette-brand-200);
    --tpp-mkt-aurora-2: var(--tpp-palette-brand-400);
    --tpp-mkt-aurora-3: var(--tpp-palette-brand-700);
    --tpp-mkt-aurora-4: var(--tpp-palette-brand-800);
    --tpp-mkt-ground-1: var(--tpp-palette-brand-950);
    --tpp-mkt-ground-2: var(--tpp-palette-brand-900);
    --tpp-mkt-ground-3: var(--tpp-palette-brand-800);
    --tpp-mkt-ground-glow-1: color-mix(in srgb, var(--tpp-palette-brand-400) 30%, transparent);
    --tpp-mkt-ground-glow-2: color-mix(in srgb, var(--tpp-palette-brand-500) 35%, transparent);
    --tpp-mkt-ground-glow-3: color-mix(in srgb, var(--tpp-palette-brand-500) 22%, transparent);
    --tpp-mkt-band-from: var(--tpp-palette-brand-800);
    --tpp-mkt-band-to: var(--tpp-palette-brand-900);
    --tpp-mkt-band-glow-1: color-mix(in srgb, var(--tpp-palette-brand-400) 30%, transparent);
    --tpp-mkt-band-glow-2: color-mix(in srgb, var(--tpp-palette-brand-500) 28%, transparent);
    --tpp-mkt-panel-to: var(--tpp-palette-brand-950);
    --tpp-mkt-corner-ground: var(--tpp-palette-brand-900);
    --tpp-mkt-corner-glow: color-mix(in srgb, var(--tpp-palette-brand-400) 20%, transparent);
    --tpp-mkt-page: var(--tpp-palette-brand-950);
    --tpp-mkt-foot: var(--tpp-palette-brand-950);
    --tpp-mkt-text: var(--tpp-palette-neutral-0);
    --tpp-mkt-text-secondary: var(--tpp-palette-neutral-200);
    --tpp-mkt-accent: var(--tpp-palette-brand-300);
    --tpp-mkt-accent-strong: var(--tpp-palette-brand-200);
    --tpp-mkt-tag-text: var(--tpp-palette-neutral-0);
    --tpp-mkt-tint: color-mix(in srgb, var(--tpp-palette-brand-400) 18%, transparent);
    --tpp-mkt-line: color-mix(in srgb, var(--tpp-palette-neutral-0) 12%, transparent);
    --tpp-mkt-glass-top: color-mix(in srgb, var(--tpp-palette-neutral-0) 8%, transparent);
    --tpp-mkt-glass-bottom: color-mix(in srgb, var(--tpp-palette-neutral-0) 3%, transparent);
    --tpp-mkt-glass-edge: color-mix(in srgb, var(--tpp-palette-neutral-0) 11%, transparent);
    --tpp-mkt-glass-highlight: color-mix(in srgb, var(--tpp-palette-neutral-0) 10%, transparent);
    --tpp-mkt-chip: color-mix(in srgb, var(--tpp-palette-neutral-0) 6%, transparent);
    --tpp-mkt-hover-ring: color-mix(in srgb, var(--tpp-palette-brand-300) 45%, transparent);
    --tpp-mkt-button: var(--tpp-palette-neutral-0);
    --tpp-mkt-button-ink: var(--tpp-palette-brand-900);
    --tpp-mkt-glass-fill: color-mix(in srgb, var(--tpp-palette-neutral-900) 90%, transparent);
    --tpp-mkt-gradient-ground: radial-gradient(900px 640px at 8% 61%, var(--tpp-mkt-ground-glow-1), transparent 70%), radial-gradient(760px 560px at 95% 3%, var(--tpp-mkt-ground-glow-2), transparent 70%), radial-gradient(700px 520px at 100% 83%, var(--tpp-mkt-ground-glow-3), transparent 70%), linear-gradient(180deg, var(--tpp-mkt-ground-1) 0%, var(--tpp-mkt-ground-2) 37%, var(--tpp-mkt-ground-3) 59%, var(--tpp-mkt-ground-2) 78%, var(--tpp-mkt-ground-1) 100%);
    --tpp-mkt-shadow-glass: none;
    --tpp-mkt-shadow-glow: 0 30px 80px -40px rgba(123, 197, 239, 0.45);
    --tpp-input-border-color: var(--tpp-border-interactive);
    --tpp-card-hover-overlay: color-mix(in srgb, var(--tpp-text-primary) 6%, transparent);
    --tpp-card-border-color: var(--tpp-border-subtle);
    --tpp-stage-fill: var(--tpp-surface-sunken);
    --tpp-talk-turn-fill: var(--tpp-surface-turn);
  }
}

/* An explicit [data-theme] choice must beat the media query. Both themes are
   restated here at :root specificity but later in source order, so forcing
   light under a dark system preference works as well as the reverse. */
[data-theme='light'] {
  --tpp-surface-page: var(--tpp-palette-neutral-0);
  --tpp-surface-raised: var(--tpp-palette-neutral-0);
  --tpp-surface-sunken: var(--tpp-palette-neutral-50);
  /* One step below surface.sunken in the light theme: the deeper of the two
     tonal chapter grounds a marketing page may use (kit D26 item 2a, 10
     September 2026, lane-owner word). Neutral in both themes; blue never
     grounds a surface (D18). In the dark theme it resolves to neutral-950,
     the same step as surface.sunken, because the ramp has no deeper step and
     neutral-800 fails link contrast. Text roles on it are contrast-enforced.
     No control sits on it: it is a ground for prose and images, so the
     interactive border is not enforced there (it measures 2.96:1). */
  --tpp-surface-sunken-deep: var(--tpp-palette-neutral-100);
  /* The ground behind a person's own turn in the talk panel (component map
     entry 6, kit D35 decision 1, ruled A on 21 September 2026: the person's
     turn takes a blue fill). It is a role rather than a reuse of
     color.brand.subtle because the two themes need different steps: brand-50
     reads on the light panel at 1.10:1, but brand-800, which brand.subtle
     resolves to in the dark theme, measures 1.04:1 against surface.raised
     and the plate all but vanishes. The dark value is brand-700, the
     adjacent locked ramp step (D3), at 1.45:1. Blue does not ground a
     surface here (D18): this is a turn's plate inside a panel, not a page
     ground, and the page's one filled interactive area is unaffected. */
  --tpp-surface-turn: var(--tpp-palette-brand-50);
  --tpp-surface-inverse: var(--tpp-palette-brand-900);
  /* The brand panel: the one navy block a marketing page may carry (D18),
     and the ground of a web page's artwork band (D47). Does NOT flip in the
     dark theme, unlike surface.inverse. Added 10 September 2026 (kit D25
     item 5, closing O24) by lane-owner word: the footer band stays navy in
     dark mode. */
  --tpp-surface-panel: var(--tpp-palette-brand-900);
  --tpp-text-primary: var(--tpp-palette-neutral-900);
  --tpp-text-secondary: var(--tpp-palette-neutral-700);
  --tpp-text-muted: var(--tpp-palette-neutral-600);
  --tpp-text-inverse: var(--tpp-palette-neutral-0);
  /* Secondary text on the inverse surface (the navy block in light, white in
     dark). Added 9 September 2026 (D23 item 5) for lower-third role lines
     and band captions; before it, surfaces reached for an opacity, which is
     a raw value. */
  --tpp-text-inverse-secondary: var(--tpp-palette-neutral-300);
  --tpp-text-on-brand: var(--tpp-palette-neutral-0);
  --tpp-text-on-panel: var(--tpp-palette-neutral-0);  /* Text on surface.panel, both themes. Added 10 September 2026 (D25). */
  /* Secondary text on surface.panel, both themes. Added 10 September 2026
     (D25). */
  --tpp-text-on-panel-secondary: var(--tpp-palette-neutral-300);
  --tpp-border-subtle: var(--tpp-palette-neutral-200);
  --tpp-border-default: var(--tpp-palette-neutral-300);
  --tpp-border-interactive: var(--tpp-palette-neutral-500);
  --tpp-border-strong: var(--tpp-palette-neutral-600);
  --tpp-brand-default: var(--tpp-palette-brand-600);
  --tpp-brand-hover: var(--tpp-palette-brand-700);
  --tpp-brand-active: var(--tpp-palette-brand-800);
  --tpp-brand-subtle: var(--tpp-palette-brand-50);
  --tpp-brand-accent: var(--tpp-palette-brand-400);
  --tpp-focus-ring: var(--tpp-palette-brand-600);
  --tpp-status-success: var(--tpp-palette-success-600);
  --tpp-status-warning: var(--tpp-palette-warning-600);
  --tpp-status-danger: var(--tpp-palette-danger-600);
  --tpp-status-info: var(--tpp-palette-brand-600);
  /* The hero aurora's linear ground, top. The aurora is board L of the
     homepage canvas as picked on AA2 (D68): pale by day, deep by night. */
  --tpp-mkt-aurora-ground-1: var(--tpp-palette-neutral-0);
  /* The aurora's linear ground, middle. */
  --tpp-mkt-aurora-ground-2: var(--tpp-palette-neutral-50);
  /* The aurora's linear ground, foot. */
  --tpp-mkt-aurora-ground-3: var(--tpp-palette-brand-100);
  /* The aurora's lowest blob, centred below the band's foot on the left. It
     lies under the plates and below the copy, never behind text. */
  --tpp-mkt-aurora-1: var(--tpp-palette-brand-300);
  /* The aurora's strongest blob, below the band's foot. Below the copy,
     never behind text. */
  --tpp-mkt-aurora-2: var(--tpp-palette-brand-200);
  /* The aurora's blob at the lower right, behind the plates. Brand-700 by
     night: on a phone the hero's secondary button sits at its edge, and its
     blue label measured 4.29:1 over brand-500. */
  --tpp-mkt-aurora-3: var(--tpp-palette-brand-100);
  /* The aurora's blob at the upper left, behind the headline. */
  --tpp-mkt-aurora-4: var(--tpp-palette-brand-50);
  /* The blended ground under the moments and the section after them (D68),
     at its top and foot. */
  --tpp-mkt-ground-1: var(--tpp-palette-neutral-50);
  /* The blended ground's second stop. */
  --tpp-mkt-ground-2: var(--tpp-palette-neutral-50);
  /* The blended ground's deepest stop in the dark theme, and its white foot
     in the light theme. */
  --tpp-mkt-ground-3: var(--tpp-palette-neutral-0);
  /* The blended ground's glow at the left. */
  --tpp-mkt-ground-glow-1: var(--tpp-palette-brand-200);
  /* The blended ground's glow at the upper right. */
  --tpp-mkt-ground-glow-2: var(--tpp-palette-brand-100);
  /* The blended ground's glow at the lower right. */
  --tpp-mkt-ground-glow-3: var(--tpp-palette-brand-50);
  /* The tinted band behind Built for where you sit (D68): its linear
     ground's start, along the mark's lean. */
  --tpp-mkt-band-from: var(--tpp-palette-brand-50);
  /* The tinted band's linear ground's end. */
  --tpp-mkt-band-to: var(--tpp-palette-brand-100);
  /* The tinted band's glow at the upper right. */
  --tpp-mkt-band-glow-1: var(--tpp-palette-brand-200);
  /* The tinted band's glow at the lower left. */
  --tpp-mkt-band-glow-2: var(--tpp-palette-brand-100);
  /* The blue panel inside the tinted band: its gradient's start, at the
     upper right. White text only. */
  --tpp-mkt-panel-from: var(--tpp-palette-brand-600);
  /* The blue panel's gradient end, at the lower left. */
  --tpp-mkt-panel-to: var(--tpp-palette-brand-900);
  /* The blue panel's glow in its lower right corner. No text sits on it
     unplated: the points there ride on panel-plate. */
  --tpp-mkt-panel-glow: var(--tpp-palette-brand-400);
  /* The small glass plates carrying the panel's points over its glow; dark
     enough that white text holds 4.5:1 over the brightest blue. */
  --tpp-mkt-panel-plate: color-mix(in srgb, var(--tpp-palette-brand-900) 72%, transparent);
  /* The questions section's ground (D68). */
  --tpp-mkt-corner-ground: var(--tpp-palette-neutral-50);
  /* The questions section's one glow, in its lower left corner. */
  --tpp-mkt-corner-glow: var(--tpp-palette-brand-100);
  /* The plain sections' ground on a marketing page: white by day, the ramp's
     deepest navy by night (D68, amending D18's neutral dark surfaces for
     public marketing pages). */
  --tpp-mkt-page: var(--tpp-palette-neutral-0);
  /* The footer's navy ground (board X). */
  --tpp-mkt-foot: var(--tpp-palette-brand-900);
  /* Headline and body text on every marketing ground above. */
  --tpp-mkt-text: var(--tpp-palette-neutral-900);
  /* Secondary text, captions and the illustrative labels on every marketing
     ground. Neutral-200 by night, because neutral-300 falls to 4.24:1 on
     glass over the strongest glow. */
  --tpp-mkt-text-secondary: var(--tpp-palette-neutral-700);
  /* Text on the blue panel and the footer, both themes. */
  --tpp-mkt-text-on-blue: var(--tpp-palette-neutral-0);
  /* Secondary text on the blue panel and the footer. */
  --tpp-mkt-text-on-blue-secondary: var(--tpp-palette-neutral-100);
  /* Icons, the moments' tags and a filled bar: blue at text weight (D18). */
  --tpp-mkt-accent: var(--tpp-palette-brand-600);
  /* The list numbers and the one coloured phrase in a heading. Brand-700 by
     day and brand-200 by night: brand-600 and brand-400 fall below 4.5:1
     where the ground's glows lie. */
  --tpp-mkt-accent-strong: var(--tpp-palette-brand-700);
  /* A tag's label on its tint. White by night, because no blue step holds
     4.5:1 on the tint over the strongest glow. */
  --tpp-mkt-tag-text: var(--tpp-palette-brand-600);
  /* A tag's or an outgoing message's tint; never a filled action (D65). */
  --tpp-mkt-tint: var(--tpp-palette-brand-100);
  /* Hairlines and chip edges on the marketing grounds. */
  --tpp-mkt-line: var(--tpp-palette-neutral-200);
  /* A glass card's fill, top (D68: the moments, the questions, the tab rail,
     the small plates). */
  --tpp-mkt-glass-top: color-mix(in srgb, var(--tpp-palette-neutral-0) 66%, transparent);
  /* A glass card's fill, foot. */
  --tpp-mkt-glass-bottom: color-mix(in srgb, var(--tpp-palette-neutral-0) 66%, transparent);
  /* A glass card's one-pixel edge. */
  --tpp-mkt-glass-edge: color-mix(in srgb, var(--tpp-palette-neutral-0) 95%, transparent);
  /* The inset highlight along a glass card's top edge. */
  --tpp-mkt-glass-highlight: var(--tpp-palette-neutral-0);
  /* A chip or message inside a glass card. */
  --tpp-mkt-chip: color-mix(in srgb, var(--tpp-palette-neutral-0) 85%, transparent);
  /* The ring and glow a glass card takes on hover or focus. Faded in by
     opacity; nothing lifts (D33). */
  --tpp-mkt-hover-ring: color-mix(in srgb, var(--tpp-palette-brand-600) 35%, transparent);
  /* The chosen tab's fill in a marketing tab rail: navy by day, white by
     night. Not the interactive blue, so D18's one filled blue area stays the
     hero's primary button. */
  --tpp-mkt-button: var(--tpp-palette-brand-900);
  /* The chosen tab's label. */
  --tpp-mkt-button-ink: var(--tpp-palette-neutral-0);
  /* The illustrative product card in How joining works: light in both
     themes, because it depicts a screen. */
  --tpp-mkt-card: color-mix(in srgb, var(--tpp-palette-neutral-0) 96%, transparent);
  /* A row inside the product card. */
  --tpp-mkt-card-row: var(--tpp-palette-neutral-50);
  /* Text on the product card. */
  --tpp-mkt-card-text: var(--tpp-palette-neutral-900);
  /* Secondary text on the product card. */
  --tpp-mkt-card-text-secondary: var(--tpp-palette-neutral-600);
  /* An icon or action word on the product card. */
  --tpp-mkt-card-accent: var(--tpp-palette-brand-600);
  /* An unfilled progress dot on the product card. */
  --tpp-mkt-card-dot: var(--tpp-palette-neutral-200);
  /* A filled progress dot on the product card. */
  --tpp-mkt-card-dot-on: var(--tpp-palette-brand-500);
  /* The hero set-piece's top plate, a gradient along the mark's lean (D42,
     D47); it fades toward its foot. */
  --tpp-mkt-plate-1-from: var(--tpp-palette-brand-300);
  --tpp-mkt-plate-1-to: color-mix(in srgb, var(--tpp-palette-brand-400) 40%, transparent);
  /* The middle plate, the one that turns in the Set motion's Register cue
     (D13). */
  --tpp-mkt-plate-2-from: var(--tpp-palette-brand-400);
  --tpp-mkt-plate-2-to: color-mix(in srgb, var(--tpp-palette-brand-500) 30%, transparent);
  /* The bottom plate. */
  --tpp-mkt-plate-3-from: var(--tpp-palette-brand-500);
  --tpp-mkt-plate-3-to: color-mix(in srgb, var(--tpp-palette-brand-700) 40%, transparent);
  /* The sticky header's glass, once the page has scrolled. Opaque enough
     that its text passes 4.5:1 over the darkest thing behind it. */
  --tpp-mkt-glass-fill: color-mix(in srgb, var(--tpp-palette-neutral-0) 90%, transparent);
  /* The hero's aurora (board L, D68). The lower blobs sit below the copy;
     the copy sits in the upper half of the band. */
  --tpp-mkt-gradient-aurora: radial-gradient(55% 60% at 30% 118%, var(--tpp-mkt-aurora-1) 0%, transparent 55%), radial-gradient(70% 80% at 45% 110%, var(--tpp-mkt-aurora-2) 0%, transparent 62%), radial-gradient(80% 70% at 85% 95%, var(--tpp-mkt-aurora-3) 0%, transparent 65%), radial-gradient(90% 70% at 10% 20%, var(--tpp-mkt-aurora-4) 0%, transparent 70%), linear-gradient(180deg, var(--tpp-mkt-aurora-ground-1) 0%, var(--tpp-mkt-aurora-ground-2) 45%, var(--tpp-mkt-aurora-ground-3) 100%);
  /* The blended ground from the moments to the office list (D68), one
     continuous field with no hard edge. */
  --tpp-mkt-gradient-ground: radial-gradient(900px 640px at 8% 61%, var(--tpp-mkt-ground-glow-1), transparent 70%), radial-gradient(760px 560px at 95% 0%, var(--tpp-mkt-ground-glow-2), transparent 70%), radial-gradient(700px 520px at 100% 83%, var(--tpp-mkt-ground-glow-3), transparent 70%), linear-gradient(180deg, var(--tpp-mkt-ground-1) 0%, var(--tpp-mkt-ground-2) 52%, var(--tpp-mkt-ground-3) 100%);
  /* The tinted band behind Built for where you sit (D68). */
  --tpp-mkt-gradient-band: radial-gradient(60% 70% at 100% 0%, var(--tpp-mkt-band-glow-1) 0%, transparent 70%), radial-gradient(55% 65% at 0% 100%, var(--tpp-mkt-band-glow-2) 0%, transparent 70%), linear-gradient(216.26deg, var(--tpp-mkt-band-from) 0%, var(--tpp-mkt-band-to) 100%);
  /* The blue panel inside the tinted band. White text only; its points ride
     on panel-plate. */
  --tpp-mkt-gradient-panel: radial-gradient(60% 80% at 100% 100%, var(--tpp-mkt-panel-glow) 0%, transparent 60%), linear-gradient(216.26deg, var(--tpp-mkt-panel-from) 0%, var(--tpp-mkt-panel-to) 100%);
  /* The questions section's ground: one glow in the lower left. */
  --tpp-mkt-gradient-corner: radial-gradient(45% 55% at 0% 100%, var(--tpp-mkt-corner-glow) 0%, transparent 70%), var(--tpp-mkt-corner-ground);
  /* A glass card's fill. */
  --tpp-mkt-gradient-glass: linear-gradient(180deg, var(--tpp-mkt-glass-top), var(--tpp-mkt-glass-bottom));
  /* The small artwork band on the moments' presentation card. */
  --tpp-mkt-gradient-thumb: linear-gradient(216.26deg, var(--tpp-palette-brand-500), var(--tpp-palette-brand-800));
  --tpp-mkt-gradient-plate-1: linear-gradient(216.26deg, var(--tpp-mkt-plate-1-from) 0%, var(--tpp-mkt-plate-1-to) 100%);
  --tpp-mkt-gradient-plate-2: linear-gradient(216.26deg, var(--tpp-mkt-plate-2-from) 0%, var(--tpp-mkt-plate-2-to) 100%);
  --tpp-mkt-gradient-plate-3: linear-gradient(216.26deg, var(--tpp-mkt-plate-3-from) 0%, var(--tpp-mkt-plate-3-to) 100%);
  --tpp-mkt-shadow-glass: 0 30px 60px -36px rgba(8, 24, 51, 0.28);
  /* The glow under a glass card on hover, drawn on a pseudo-element and
     faded in by opacity. */
  --tpp-mkt-shadow-glow: 0 30px 80px -40px rgba(3, 112, 160, 0.35);
  --tpp-input-border-color: var(--tpp-border-interactive);
  --tpp-card-hover-overlay: color-mix(in srgb, var(--tpp-text-primary) 6%, transparent);
  --tpp-card-border-color: var(--tpp-border-default);
  --tpp-stage-fill: var(--tpp-surface-sunken);
  --tpp-talk-turn-fill: var(--tpp-surface-turn);
}

[data-theme='dark'] {
  --tpp-surface-page: var(--tpp-palette-neutral-900);
  --tpp-surface-raised: var(--tpp-palette-neutral-800);
  --tpp-surface-sunken: var(--tpp-palette-neutral-950);
  /* The dark ramp has no step below neutral-950, and neutral-800 fails
       link contrast (brand-400 at 4.4:1), so both chapter grounds resolve to
       950 in the dark theme; the chapters read against the page, not against
       each other. */
  --tpp-surface-sunken-deep: var(--tpp-palette-neutral-950);
  /* Not brand-800. brand.subtle resolves to brand-800 in this theme and
       measures 1.04:1 against surface.raised, so the turn's plate is
       invisible and ruling A silently becomes ruling C for every dark-theme
       viewer. brand-700 measures 1.45:1, slightly more separation than the
       light theme's own 1.10:1, and carries text.primary at 7.12:1. */
  --tpp-surface-turn: var(--tpp-palette-brand-700);
  --tpp-surface-inverse: var(--tpp-palette-neutral-0);
  /* Stays navy in the dark theme by ruling (D25 item 5): the panel is a
       decorative brand block, not a themed surface. */
  --tpp-surface-panel: var(--tpp-palette-brand-900);
  --tpp-text-primary: var(--tpp-palette-neutral-100);
  --tpp-text-secondary: var(--tpp-palette-neutral-300);
  --tpp-text-muted: var(--tpp-palette-neutral-400);
  --tpp-text-inverse: var(--tpp-palette-neutral-900);
  /* Secondary text on the inverse surface, which is white in the dark
       theme (D23 item 5 ruled neutral-300 on navy, neutral-700 on white).
       Repaired 14 September 2026: the override had been filed under
       color.surface.inverse-secondary, a token the base set does not define,
       so the role stayed at neutral-300 and measured 1.51:1 on the dark
       theme's white inverse plate. */
  --tpp-text-inverse-secondary: var(--tpp-palette-neutral-700);
  --tpp-text-on-brand: var(--tpp-palette-brand-900);
  --tpp-text-on-panel: var(--tpp-palette-neutral-0);
  --tpp-text-on-panel-secondary: var(--tpp-palette-neutral-300);
  --tpp-border-subtle: var(--tpp-palette-neutral-700);
  --tpp-border-default: var(--tpp-palette-neutral-600);
  --tpp-border-interactive: var(--tpp-palette-neutral-500);
  --tpp-border-strong: var(--tpp-palette-neutral-400);
  --tpp-brand-default: var(--tpp-palette-brand-400);
  --tpp-brand-hover: var(--tpp-palette-brand-300);
  --tpp-brand-active: var(--tpp-palette-brand-200);
  --tpp-brand-subtle: var(--tpp-palette-brand-800);
  --tpp-brand-accent: var(--tpp-palette-brand-400);
  --tpp-focus-ring: var(--tpp-palette-brand-400);
  --tpp-status-success: var(--tpp-palette-success-400);
  --tpp-status-warning: var(--tpp-palette-warning-400);
  /* danger-300 since 14 September 2026 (D30): danger-400 fails 4.5:1 as
       message text on surface.raised in this theme (4.22:1); 300 measures
       5.22:1 there. */
  --tpp-status-danger: var(--tpp-palette-danger-300);
  --tpp-status-info: var(--tpp-palette-brand-400);
  --tpp-mkt-aurora-ground-1: var(--tpp-palette-brand-950);
  --tpp-mkt-aurora-ground-2: var(--tpp-palette-brand-900);
  --tpp-mkt-aurora-ground-3: var(--tpp-palette-brand-800);
  --tpp-mkt-aurora-1: var(--tpp-palette-brand-200);
  --tpp-mkt-aurora-2: var(--tpp-palette-brand-400);
  --tpp-mkt-aurora-3: var(--tpp-palette-brand-700);
  --tpp-mkt-aurora-4: var(--tpp-palette-brand-800);
  --tpp-mkt-ground-1: var(--tpp-palette-brand-950);
  --tpp-mkt-ground-2: var(--tpp-palette-brand-900);
  --tpp-mkt-ground-3: var(--tpp-palette-brand-800);
  --tpp-mkt-ground-glow-1: color-mix(in srgb, var(--tpp-palette-brand-400) 30%, transparent);
  --tpp-mkt-ground-glow-2: color-mix(in srgb, var(--tpp-palette-brand-500) 35%, transparent);
  --tpp-mkt-ground-glow-3: color-mix(in srgb, var(--tpp-palette-brand-500) 22%, transparent);
  --tpp-mkt-band-from: var(--tpp-palette-brand-800);
  --tpp-mkt-band-to: var(--tpp-palette-brand-900);
  --tpp-mkt-band-glow-1: color-mix(in srgb, var(--tpp-palette-brand-400) 30%, transparent);
  --tpp-mkt-band-glow-2: color-mix(in srgb, var(--tpp-palette-brand-500) 28%, transparent);
  --tpp-mkt-panel-to: var(--tpp-palette-brand-950);
  --tpp-mkt-corner-ground: var(--tpp-palette-brand-900);
  --tpp-mkt-corner-glow: color-mix(in srgb, var(--tpp-palette-brand-400) 20%, transparent);
  --tpp-mkt-page: var(--tpp-palette-brand-950);
  --tpp-mkt-foot: var(--tpp-palette-brand-950);
  --tpp-mkt-text: var(--tpp-palette-neutral-0);
  --tpp-mkt-text-secondary: var(--tpp-palette-neutral-200);
  --tpp-mkt-accent: var(--tpp-palette-brand-300);
  --tpp-mkt-accent-strong: var(--tpp-palette-brand-200);
  --tpp-mkt-tag-text: var(--tpp-palette-neutral-0);
  --tpp-mkt-tint: color-mix(in srgb, var(--tpp-palette-brand-400) 18%, transparent);
  --tpp-mkt-line: color-mix(in srgb, var(--tpp-palette-neutral-0) 12%, transparent);
  --tpp-mkt-glass-top: color-mix(in srgb, var(--tpp-palette-neutral-0) 8%, transparent);
  --tpp-mkt-glass-bottom: color-mix(in srgb, var(--tpp-palette-neutral-0) 3%, transparent);
  --tpp-mkt-glass-edge: color-mix(in srgb, var(--tpp-palette-neutral-0) 11%, transparent);
  --tpp-mkt-glass-highlight: color-mix(in srgb, var(--tpp-palette-neutral-0) 10%, transparent);
  --tpp-mkt-chip: color-mix(in srgb, var(--tpp-palette-neutral-0) 6%, transparent);
  --tpp-mkt-hover-ring: color-mix(in srgb, var(--tpp-palette-brand-300) 45%, transparent);
  --tpp-mkt-button: var(--tpp-palette-neutral-0);
  --tpp-mkt-button-ink: var(--tpp-palette-brand-900);
  --tpp-mkt-glass-fill: color-mix(in srgb, var(--tpp-palette-neutral-900) 90%, transparent);
  --tpp-mkt-gradient-ground: radial-gradient(900px 640px at 8% 61%, var(--tpp-mkt-ground-glow-1), transparent 70%), radial-gradient(760px 560px at 95% 3%, var(--tpp-mkt-ground-glow-2), transparent 70%), radial-gradient(700px 520px at 100% 83%, var(--tpp-mkt-ground-glow-3), transparent 70%), linear-gradient(180deg, var(--tpp-mkt-ground-1) 0%, var(--tpp-mkt-ground-2) 37%, var(--tpp-mkt-ground-3) 59%, var(--tpp-mkt-ground-2) 78%, var(--tpp-mkt-ground-1) 100%);
  --tpp-mkt-shadow-glass: none;
  --tpp-mkt-shadow-glow: 0 30px 80px -40px rgba(123, 197, 239, 0.45);
  --tpp-input-border-color: var(--tpp-border-interactive);
  --tpp-card-hover-overlay: color-mix(in srgb, var(--tpp-text-primary) 6%, transparent);
  --tpp-card-border-color: var(--tpp-border-subtle);
  --tpp-stage-fill: var(--tpp-surface-sunken);
  --tpp-talk-turn-fill: var(--tpp-surface-turn);
}

:root {
  /* ---- primitive: type — families ---- */
  /* System family — CONFIRMED 27 Aug 2026. Carries everything on product
     surfaces, page titles included, plus UI, body, email and generated
     documents. Manrope, SIL Open Font Licence, self-hosted. Since the M3
     rebase (D8) there is NO weight ladder: every heading role is regular 400
     and hierarchy comes from size. Only 400 and 500 are in use. */
  --tpp-font-sans: 'Manrope', system-ui, -apple-system, 'Segoe UI', sans-serif;
  /* DECIDED 27 Aug 2026 — Tomorrow, SIL Open Font Licence 1.1, self-hosted,
     weight 400 only. BRAND AND MARKETING SURFACES ONLY: never on a product
     surface, never in a generated document or presentation, never in body
     copy, never a full sentence. Always paired with the sans family for
     supporting text. Emphasis is achieved by scale, not weight — no bolder
     cut is held in the kit. Reached only through text-style.display; no
     component may reference this family directly. Set with
     letter-spacing.tighter (-0.02em) — see the amendment to D7. */
  --tpp-font-display: 'Tomorrow', system-ui, -apple-system, 'Segoe UI', sans-serif;
  /* Substitutes for the sans family in Word, PowerPoint and Outlook where
     Manrope is unavailable, following the same size-driven hierarchy (every
     heading regular 400, per D8); the display family needs no fallback
     because it never appears in those applications. */
  --tpp-font-fallback: Arial, Helvetica, sans-serif;
  /* Figures-and-code family. Cascadia Code, SIL Open Font Licence 1.1,
     self-hosted as a variable face; the rest of the stack is the system
     fallback for surfaces that do not load it. Added 1 September 2026.
     Reordered 18 September 2026 (kit D32, finding 3): the stack had listed
     SF Mono first, so a Mac rendered the system face even where Cascadia
     Code was loaded, and the shipped face was never seen on the device the
     kit is judged on. */
  --tpp-font-mono: 'Cascadia Code', 'SF Mono', Consolas, monospace;

  /* ---- primitive: type — weights ---- */
  /* All heading and body roles. M3 md.ref.typeface.weight-regular — M3 takes
     hierarchy from size, not weight. */
  --tpp-font-weight-regular: 400;
  --tpp-font-weight-medium: 500;  /* Labels and buttons. M3 md.ref.typeface.weight-medium. */
  /* M3 label-*-weight-prominent — the optional heavier label cut. Use
     sparingly. */
  --tpp-font-weight-prominent: 700;
  /* RETAINED, UNUSED. No filed text style reaches this since the M3 rebase
     (D8). */
  --tpp-font-weight-semibold: 600;
  /* RETAINED, UNUSED. No filed text style reaches this since the M3 rebase
     (D8). */
  --tpp-font-weight-bold: 700;
  /* RETAINED, UNUSED. Carried heading-1 until the M3 rebase (D8), which
     moved every heading to regular 400. */
  --tpp-font-weight-extrabold: 800;
  /* The only permitted weight on font.family.display, locked to match the
     wordmark; do not add cuts. */
  --tpp-font-weight-display: 400;

  /* ---- primitive: type — size ladder ---- */
  /* Rem scale on a 16px root, rebased on the Material 3 (md.sys.typescale,
     material-web tokens v0_192) ladder. Absolute sizes, not a geometric
     ratio. M3's label-small (0.6875rem) has no TPP step. */
  --tpp-font-size-xs: 0.75rem;  /* M3 body-small, label-medium. */
  --tpp-font-size-sm: 0.875rem;  /* M3 body-medium, label-large. */
  --tpp-font-size-base: 1rem;  /* M3 body-large, title-medium. */
  --tpp-font-size-lg: 1.375rem;  /* M3 title-large. */
  --tpp-font-size-xl: 1.5rem;  /* M3 headline-small. */
  --tpp-font-size-2xl: 1.75rem;  /* M3 headline-medium. */
  --tpp-font-size-3xl: 2rem;  /* M3 headline-large. */
  --tpp-font-size-4xl: 2.25rem;  /* M3 display-small. */
  --tpp-font-size-5xl: 2.8125rem;  /* M3 display-medium. */
  --tpp-font-size-6xl: 3.5625rem;  /* M3 display-large. */
  /* DEVIATION from the M3 ladder and from the DTCG dimension shape, ruled 10
     September 2026 (kit D26 item 4a): the marketing headline is fluid, from
     display-large (3.5625rem, the floor on laptops up to about 1370 px) to
     4.5rem, reached at 1867 px (3.7rem at 1440, 4rem at 1600). Re-tuned the
     same day on the lane owner's word that the first ramp (0.75rem + 4.5vw,
     4.5rem at 1440) read too large on a laptop. A CSS expression filed as a
     string; the renderer passes it through. Marketing pages only, through
     text-style.headline; product surfaces never reach it. */
  --tpp-font-size-fluid-headline: clamp(3.5625rem, 1rem + 3vw, 4.5rem);

  /* ---- primitive: type — line heights ---- */
  /* Rebased on Material 3 (md.sys.typescale, material-web tokens v0_192). M3
     line heights are absolute per role; these are the ratios they resolve
     to. */
  --tpp-line-height-tight: 1.16;  /* Display. M3 display-medium 3.25/2.8125. */
  /* Headings and titles. M3 headline-medium 2.25/1.75; the M3 heading band
     runs 1.25-1.33. */
  --tpp-line-height-snug: 1.28;
  --tpp-line-height-base: 1.5;  /* Body. M3 body-large 1.5/1, exact. */
  /* DEVIATION: retained outside the M3 ladder. M3 has no long-form reading
     role and nothing looser than body-large. Long-form editorial only. */
  --tpp-line-height-relaxed: 1.65;

  /* ---- primitive: type — tracking ---- */
  /* Em multipliers (rendered as em in CSS). M3 tracking is absolute rem per
     role; converted to em at the size it applies to. Note that M3 body text
     carries POSITIVE tracking. */
  /* M3 display-large -0.015625rem / 3.5625rem. Negative, but only barely —
     the display face takes `tighter` instead. */
  --tpp-letter-spacing-tight: -0.004em;
  /* DEVIATION from M3, added 1 September 2026: text-style.display only.
     Tomorrow reads loose at display size on M3 tracking, whose values are
     tuned for Roboto. Amends D7, which had barred tight tracking on the
     display face. */
  --tpp-letter-spacing-tighter: -0.02em;
  --tpp-letter-spacing-normal: 0;  /* M3 headline-* and title-large. */
  --tpp-letter-spacing-label: 0.007em;  /* M3 label-large 0.00625rem / 0.875rem. */
  /* M3 title-medium 0.15px / 16px. Product surfaces only, through
     text-style.title-md (D29, 11 September 2026). */
  --tpp-letter-spacing-title: 0.009em;
  /* DEVIATION from M3, 10 September 2026 (kit D25 item 3, closing O9): zero.
     M3's value (M3 body-medium 0.015625rem / 0.875rem) is tuned for Roboto;
     Manrope judged by the lane owner on the Stage 2 page as reading better
     at zero. Amends D8. */
  --tpp-letter-spacing-body-sm: 0;
  /* DEVIATION from M3, 10 September 2026 (kit D25 item 3, closing O9): zero.
     M3's value (M3 body-large 0.03125rem / 1rem) is tuned for Roboto;
     Manrope judged by the lane owner on the Stage 2 page as reading better
     at zero. Amends D8. */
  --tpp-letter-spacing-body: 0;
  /* DEVIATION from M3, 10 September 2026 (kit D25 item 3, closing O9): zero.
     M3's value (M3 body-small 0.025rem / 0.75rem) is tuned for Roboto;
     Manrope judged by the lane owner on the Stage 2 page as reading better
     at zero. Amends D8. */
  --tpp-letter-spacing-caption: 0;
  --tpp-letter-spacing-wide: 0.042em;  /* M3 label-medium 0.03125rem / 0.75rem. All-caps labels. */

  /* ---- primitive: space ---- */
  /* 4px base grid, expressed in rem. Token n = n × 0.25rem. */
  --tpp-space-0: 0;
  --tpp-space-1: 0.25rem;
  --tpp-space-2: 0.5rem;
  --tpp-space-3: 0.75rem;
  --tpp-space-4: 1rem;
  --tpp-space-5: 1.25rem;
  --tpp-space-6: 1.5rem;
  --tpp-space-8: 2rem;
  --tpp-space-10: 2.5rem;
  --tpp-space-12: 3rem;
  --tpp-space-16: 4rem;
  --tpp-space-20: 5rem;
  --tpp-space-24: 6rem;

  /* ---- primitive: radius ---- */
  /* Corner radii. Bounded per-brand variation is allowed on this scale only,
     within the conformance layer's density/radius bounds. */
  --tpp-radius-none: 0;
  --tpp-radius-sm: 0.25rem;
  --tpp-radius-md: 0.5rem;
  --tpp-radius-lg: 0.75rem;
  --tpp-radius-xl: 1rem;
  /* M3 corner-extra-large (28px). Added with the M3 adoption (D8); no
     component uses it yet. */
  --tpp-radius-2xl: 1.75rem;
  --tpp-radius-full: 9999px;  /* Pills and circular elements. */

  /* ---- primitive: border width ---- */
  --tpp-border-hairline: 1px;
  --tpp-border-thick: 2px;

  /* ---- primitive: elevation ---- */
  /* Navy-tinted shadows (brand-900 at low alpha) so elevation reads as brand
     atmosphere, not grey smoke. Level 0 is none. */
  /* Flat — no shadow. The proof tile and other deliberately flat surfaces
     reference this rather than hard-coding `none`. */
  --tpp-elevation-0: none;
  --tpp-elevation-1: 0 1px 2px rgba(8, 24, 51, 0.06), 0 1px 3px rgba(8, 24, 51, 0.08);  /* Subtle lift — cards at rest. */
  /* Raised — dropdowns, popovers, and a card layered over another surface
     inside a composition: the hero's talk panel over the hero's artwork band
     (D47; it was the crop until 24 September 2026), the showcase's detail
     panel over the screen (component map entry 5, D33, proposed 20 September
     2026). Never a card on hover: the description used to say "cards on
     hover", and D22 (8 September 2026) bars hover lifts; corrected with
     entry 5. */
  --tpp-elevation-2: 0 2px 4px -1px rgba(8, 24, 51, 0.07), 0 4px 8px -2px rgba(8, 24, 51, 0.09);
  --tpp-elevation-3: 0 8px 16px -4px rgba(8, 24, 51, 0.10), 0 12px 24px -6px rgba(8, 24, 51, 0.12);  /* Overlay — drawers, sticky bars. */
  --tpp-elevation-4: 0 16px 32px -8px rgba(8, 24, 51, 0.14), 0 24px 48px -12px rgba(8, 24, 51, 0.18);  /* Modal — dialogs and full takeovers. */

  /* ---- primitive: motion — durations ---- */
  --tpp-duration-instant: 75ms;  /* @kind other */  /* Micro state changes — hover tints, focus rings. */
  --tpp-duration-fast: 150ms;  /* @kind other */  /* Small movements — toggles, checkboxes. */
  --tpp-duration-base: 200ms;  /* @kind other */  /* Default — most transitions. */
  --tpp-duration-slow: 300ms;  /* @kind other */  /* Larger movements — panels, accordions. */
  --tpp-duration-deliberate: 450ms;  /* @kind other */  /* Full-surface moves — drawers, page-level reveals. */

  /* ---- primitive: motion — easings ---- */
  --tpp-ease-standard: cubic-bezier(0.2, 0, 0, 1);  /* @kind other */  /* Default for on-screen movement. */
  --tpp-ease-enter: cubic-bezier(0, 0, 0.2, 1);  /* @kind other */  /* Elements arriving. */
  --tpp-ease-exit: cubic-bezier(0.4, 0, 1, 1);  /* @kind other */  /* Elements leaving. */

  /* ---- semantic: focus geometry ---- */
  --tpp-focus-ring-width: 2px;
  /* Focus visibility is an accessibility affordance — no brand theme may
     reduce or remove it. */
  --tpp-focus-ring-offset: 2px;

  /* ---- component tier: bounded overrides (its colours ride in the theme blocks, D76) ---- */
  /* Component tokens — bounded overrides only, referencing semantic tokens.
     A component token exists only where a variant needs it; this tier never
     introduces new raw values. */
  --tpp-button-radius: var(--tpp-radius-md);
  --tpp-button-height-sm: 2rem;
  --tpp-button-height-md: 2.5rem;
  --tpp-button-height-lg: 3rem;  /* 48px — mobile tap-target floor for primary actions. */
  --tpp-button-padding-x: var(--tpp-space-5);
  --tpp-button-font-weight: var(--tpp-font-weight-medium);  /* M3 label-large weight. Dropped semibold 600 -> medium 500 by D8. */
  --tpp-input-radius: var(--tpp-radius-md);
  --tpp-input-height: 2.75rem;  /* 44px — tap-target minimum. */
  /* 80px — the ruled site header: the 280px lockup (33.5px tall) centred in
     space.6 above and below. */
  --tpp-nav-height-marketing: 5rem;
  /* 56px — the app shell bar; a 44px target clears it with space.1 above and
     below. */
  --tpp-nav-height-product: 3.5rem;

  /* The navigation bar (component map entry 3, MKT-538). Heights and the
     lockup widths are the values the ruled Stage 2 header renders at (D25
     R4: the wide lockup at 280px in the header; 200px is that lockup's filed
     minimum and the width the site already falls to below 40rem). */
  /* 280px — ruled 10 September 2026 (D25 R4), wordmark capitals at 13.4px. */
  --tpp-nav-lockup-width: 17.5rem;
  /* 200px — the wide lockup's filed minimum; the narrow-viewport width. */
  --tpp-nav-lockup-width-compact: 12.5rem;
  --tpp-nav-gap: var(--tpp-space-8);  /* 32px between navigation links, as the ruled header renders. */

  /* The card (component map entry 5, kit D33, RULED 21 September 2026 by
     lane-owner word: 1 B, 2 E, 3 A, 4 A): a container that groups one thing.
     radius.lg, space.6 inside a hairline (space.4 on a dense product panel),
     no shadow at rest; a layered card at elevation-2; on hover a wash of the
     text colour and one step of hairline. */
  --tpp-card-radius: var(--tpp-radius-lg);
  --tpp-card-padding: var(--tpp-space-6);  /* 24px — the default card padding (entry 5 size md). */
  /* 16px — RULED (entry 5, decision 4 A, 21 September 2026): the compact
     card for dense product panels (D29 density: a figure tile, a side-column
     list, anything under 20rem), where 24px spends a fifth of a narrow panel
     on air. Never on a marketing page. The Lightning card's own inset. */
  --tpp-card-padding-compact: var(--tpp-space-4);
  /* A card at rest carries no shadow: the hairline is its whole boundary
     (kit D33 decision 1, RULED B by lane-owner word, 21 September 2026: a
     raised card on every panel reads dated; shadows are for what floats).
     Was elevation.level-1 from 20 August to 21 September 2026. */
  --tpp-card-elevation: var(--tpp-elevation-0);
  /* RULED (entry 5, decision 3 A, 21 September 2026): the one shadow a card
     may carry, only when it sits over another surface inside a composition —
     the hero's talk panel over the hero's artwork band (D47; ruled at
     elevation-2 on 11 September 2026, over the crop it replaced) and the
     showcase's detail panel over the screen (built at elevation-3, now 2).
     None at rest; elevation-3 is for what floats over the page and can be
     dismissed; 4 for a modal. */
  --tpp-card-elevation-layered: var(--tpp-elevation-2);

  /* The stage (component map entry 5, D33, proposed 20 September 2026): the
     sunken container that holds a composed product shot or a live component,
     from the website ruling (D25: a surface-sunken stage at radius.xl in the
     right eight columns). None of these is a new value: the site's showcase
     and the proofs' specimen stages already render them. */
  /* 16px — one step above the card's radius.lg, so a card inside a stage
     reads as nested rather than as the same object (D25). */
  --tpp-stage-radius: var(--tpp-radius-xl);
  --tpp-stage-padding: var(--tpp-space-6);  /* 24px — the showcase stage on the site (D25). */
  /* 40px — the specimen stage on a proof page, so a live component sits
     clear of the stage's edge (its cut corner was retired by D47, 24
     September 2026). */
  --tpp-stage-padding-wide: var(--tpp-space-10);

  /* ---- marketing layer (D67, D68): motion, display type, glass, radius — public marketing surfaces only ---- */
  /* The expressive marketing layer (kit D67, rebuilt to the homepage
     canvas's AA2 by D68, 29 September 2026). PUBLIC MARKETING SURFACES ONLY:
     the public recruitment and customer sites, decks and social video. Never
     the partner site, the customer app, a sign-in page or any email, which
     keep the core tiers above unchanged. Every name is --tpp-mkt-*, so a
     stray use on a core surface is visible and the brand grill fails it. The
     rules are guidelines/expressive-layer.md; the reference implementation
     is identity/motion/. Colours are built only from the locked ramp and the
     neutral ramp; every text pairing on a gradient or glass is enforced by
     the build in both themes. */
  /* A glass card's hover ring fading in. */
  --tpp-mkt-duration-instant: 100ms;  /* @kind other */
  /* A tab's panel changing. */
  --tpp-mkt-duration-quick: 200ms;  /* @kind other */
  /* The hero aurora's one slow settle, on load. Under five seconds, so it
     needs no pause control (WCAG 2.2.2); it never loops. */
  --tpp-mkt-duration-drift: 4800ms;  /* @kind other */
  /* A beat of a product moment arriving: decelerating on the emphasised
     curve, no bounce. */
  --tpp-mkt-duration-arrive: 640ms;  /* @kind other */
  /* A product moment's beats leaving at the end of its cycle, and a card
     changing place in a stack. */
  --tpp-mkt-duration-leave: 420ms;  /* @kind other */
  /* The default cycle of a product moment. Each tile runs its own cycle,
     starting when it comes into view, so no two tiles land together; always
     with a pause control. */
  --tpp-mkt-duration-loop: 9000ms;  /* @kind other */
  /* The aurora's settle and the hover ring; the core's standard curve. */
  --tpp-mkt-ease-standard: cubic-bezier(0.2, 0, 0, 1);  /* @kind other */
  /* Expo-out: a beat of the moments arriving. Decelerates hard, no bounce
     (D65). */
  --tpp-mkt-ease-emphasised: cubic-bezier(0.16, 1, 0.3, 1);  /* @kind other */
  /* How far a moment's beat rises as it arrives. Zero under reduced motion. */
  --tpp-mkt-arrival-distance: 12px;  /* @kind other */
  /* The hero headline: 36 px on a 390 px phone, capped at 4.5rem (72 px)
     from 1280 px, so 72 px on a 1440 px screen (D68: 80 px or less). A CSS
     expression filed as a string, as the fluid headline is (D26). */
  --tpp-mkt-font-size-hero: clamp(2.25rem, 1.3rem + 4vw, 4.5rem);
  /* Section headlines: 32 px on a phone, the display-medium role (2.8125rem,
     45 px) from 1313 px. */
  --tpp-mkt-font-size-section: clamp(2rem, 1.5rem + 1.6vw, 2.8125rem);
  /* The display line height (1.16). */
  --tpp-mkt-line-height-hero: var(--tpp-line-height-tight);
  /* The heading line height (1.28, D32). */
  --tpp-mkt-line-height-section: var(--tpp-line-height-snug);
  /* The display tracking. */
  --tpp-mkt-letter-spacing-hero: var(--tpp-letter-spacing-tight);
  /* The heading tracking. */
  --tpp-mkt-letter-spacing-section: var(--tpp-letter-spacing-normal);
  /* The backdrop blur behind every glass surface: the sticky header and the
     glass cards (D68). */
  --tpp-mkt-glass-blur: 16px;
  /* Glass cards, panels and the product stage on marketing surfaces: M3
     corner-extra-large (28 px). Pills take radius.full; controls keep
     radius.md. */
  --tpp-mkt-radius: var(--tpp-radius-2xl);
}

/* ---- dark theme: elevation deepens (shadows on navy need more weight) ---- */
@media (prefers-color-scheme: dark) {
  :root {
    --tpp-elevation-1: 0 1px 2px rgba(6, 18, 26, 0.30), 0 1px 3px rgba(6, 18, 26, 0.36);
    --tpp-elevation-2: 0 2px 4px -1px rgba(6, 18, 26, 0.34), 0 4px 8px -2px rgba(6, 18, 26, 0.40);
    --tpp-elevation-3: 0 8px 16px -4px rgba(6, 18, 26, 0.40), 0 12px 24px -6px rgba(6, 18, 26, 0.46);
    --tpp-elevation-4: 0 16px 32px -8px rgba(6, 18, 26, 0.48), 0 24px 48px -12px rgba(6, 18, 26, 0.55);
  }
}

[data-theme='light'] {
  --tpp-elevation-1: 0 1px 2px rgba(8, 24, 51, 0.06), 0 1px 3px rgba(8, 24, 51, 0.08);  /* Subtle lift — cards at rest. */
  --tpp-elevation-2: 0 2px 4px -1px rgba(8, 24, 51, 0.07), 0 4px 8px -2px rgba(8, 24, 51, 0.09);
  --tpp-elevation-3: 0 8px 16px -4px rgba(8, 24, 51, 0.10), 0 12px 24px -6px rgba(8, 24, 51, 0.12);  /* Overlay — drawers, sticky bars. */
  --tpp-elevation-4: 0 16px 32px -8px rgba(8, 24, 51, 0.14), 0 24px 48px -12px rgba(8, 24, 51, 0.18);  /* Modal — dialogs and full takeovers. */
}

[data-theme='dark'] {
  --tpp-elevation-1: 0 1px 2px rgba(6, 18, 26, 0.30), 0 1px 3px rgba(6, 18, 26, 0.36);
  --tpp-elevation-2: 0 2px 4px -1px rgba(6, 18, 26, 0.34), 0 4px 8px -2px rgba(6, 18, 26, 0.40);
  --tpp-elevation-3: 0 8px 16px -4px rgba(6, 18, 26, 0.40), 0 12px 24px -6px rgba(6, 18, 26, 0.46);
  --tpp-elevation-4: 0 16px 32px -8px rgba(6, 18, 26, 0.48), 0 24px 48px -12px rgba(6, 18, 26, 0.55);
}

/* ---- motion: reduced-motion is a floor, not a preference hint ---- */
@media (prefers-reduced-motion: reduce) {
  :root {
    --tpp-duration-instant: 0ms;  /* @kind other */
    --tpp-duration-fast: 0ms;  /* @kind other */
    --tpp-duration-base: 0ms;  /* @kind other */
    --tpp-duration-slow: 0ms;  /* @kind other */
    --tpp-duration-deliberate: 0ms;  /* @kind other */
    --tpp-mkt-duration-instant: 0ms;  /* @kind other */
    --tpp-mkt-duration-quick: 0ms;  /* @kind other */
    --tpp-mkt-duration-drift: 0ms;  /* @kind other */
    --tpp-mkt-duration-arrive: 0ms;  /* @kind other */
    --tpp-mkt-duration-leave: 0ms;  /* @kind other */
    --tpp-mkt-duration-loop: 0ms;  /* @kind other */
    --tpp-mkt-arrival-distance: 0;  /* @kind other */
  }
}

/* ---- self-hosted faces ---- */
@font-face {
  font-family: 'Manrope';
  src: url('../identity/type/manrope-variable.woff2') format('woff2');
  font-weight: 200 800;                 /* variable axis, the full range the face carries */
  font-display: swap;
}
@font-face {
  font-family: 'Tomorrow';
  src: url('../identity/type/tomorrow-regular.woff2') format('woff2');
  font-weight: 400;                 /* one weight only — do not add cuts (D7) */
  font-display: swap;
}
@font-face {
  font-family: 'Cascadia Code';
  src: url('../identity/type/cascadia-code-variable.woff2') format('woff2');
  font-weight: 200 700;                 /* variable axis — figures and code only */
  font-display: swap;
}
