/* ═══════════════════════════════════════════════════════════════════════════
   tokens.css - the design system.

   The neutral half of this file (ink ramp, type/space/radius scales, shadow
   recipe, layout constants, motion) is measured from fanout.sh's shipped
   stylesheet rather than eyeballed. That layer is a quality bar, not an
   identity - it is the part worth matching exactly.

   The accent layer below it is deliberately NOT theirs. Same structure and
   proportion, Klay's own colour, so the result reads as a peer product rather
   than a clone. See the ACCENT block.

   Naming follows fanout's --ga-* convention because the existing
   course/course.css already half-speaks it; keeping the names means the
   legacy static pages and the new app can share one vocabulary during the
   cutover instead of drifting apart.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── ink ramp ─────────────────────────────────────────────────────────── */
  --ga-ink-50: #fbfbfb;
  --ga-ink-100: #f3f3f3;
  --ga-ink-200: #e1e1e1;
  --ga-ink-300: #cfcfcf;
  --ga-ink-400: #adadad;
  --ga-ink-500: #929292;
  --ga-ink-600: #6e6e6e;
  --ga-ink-700: #4a4a4a;
  --ga-ink-800: #272727;
  --ga-ink-900: #1d1d1d;
  --ga-black: #000;

  /* ── surfaces (light) ─────────────────────────────────────────────────── */
  --ga-bg: #f7f7f8;
  --ga-surface: #fff;
  --ga-sidebar: #fafafa;
  --ga-hover: #f0f0f2;
  --ga-chip: #f4f4f5;
  --ga-divider: #e8e8ea;
  --ga-border: #dedee2;
  --ga-border-strong: #c9c9cf;

  /* ── foreground, derived from the ramp ──────────────────────────────────
     Each role sits ONE STEP DARKER than fanout's equivalent. Theirs maps
     fg2→ink-600 and fg3→ink-500, which puts fg3 at 2.83:1 on a chip and
     2.91:1 on the page background - below WCAG AA for the 12-13px eyebrow and
     caption text it is actually used for.

     Darkening fg3 alone is not available: fg2 only clears 4.5 by 0.14, so a
     lighter-than-fg2 value that still passes does not exist. Shifting both
     roles down one rung keeps the three-step hierarchy intact and puts the
     worst pairing at 4.64:1. Measured, not guessed - see the contrast table
     in the build notes. */
  --ga-fg1: var(--ga-ink-800); /* 13.59 : 1 worst case */
  --ga-fg2: var(--ga-ink-700); /*  8.06 : 1 worst case */
  --ga-fg3: var(--ga-ink-600); /*  4.64 : 1 worst case - AA floor */
  --ga-fg-inv: #fff;

  /* Aliases kept so course/course.css and the 290 generated pages keep
     rendering while they are migrated. Remove once nothing reads them. */
  --ga-text: var(--ga-fg1);
  --ga-muted: var(--ga-fg2);
  --ga-subtle: var(--ga-fg3);

  /* ── ACCENT - Klay's, not theirs ──────────────────────────────────────── */
  /* Anchored on the blue the site already ships (#2f7cf6) and extended into a
     full ramp. The signature gradient runs blue → teal; fanout's runs
     violet → indigo. Structurally the same slot, unmistakably a different
     product. */
  --ga-accent-50: #eef5ff;
  --ga-accent-100: #d9e8ff;
  --ga-accent-200: #b6d3ff;
  --ga-accent-300: #85b6ff;
  --ga-accent-400: #5494fb;
  --ga-accent-500: #2f7cf6;
  --ga-accent-600: #1d6de2;
  --ga-accent-700: #1857b6;
  --ga-accent-800: #17488f;
  --ga-accent-900: #163d72;

  /* accent-500 (#2f7cf6) is the brand blue, but as text it lands at 3.68:1 on
     the page background and only carries white at 3.94:1 - both short of AA
     for the link and button labels it is used for. The interactive accent is
     therefore -600; -500 stays available for large type and fills, where 3:1
     is the correct bar. */
  --ga-accent: var(--ga-accent-600); /* 4.52 : 1 as text on --ga-bg */
  --ga-accent-hover: var(--ga-accent-700);
  --ga-accent-soft: var(--ga-accent-50);

  /* What goes ON the accent. Flips with the theme: dark mode lightens the
     accent to clear AA as text, which then makes white illegible on top of it
     (3.00 : 1), so the button label goes dark instead. */
  --ga-on-accent: #fff; /* 4.84 : 1 on accent-600 */

  /* For labels sitting on a saturated status or category fill. White on
     --ga-success is 3.51 : 1 and on --ga-cat-red 4.14 : 1 - both short of AA
     at the 10-12px these badges actually use. Dark ink clears it on every
     fill in the palette, in both themes, so it does not flip. */
  --ga-on-bright: #111213;

  /* What goes on --ga-accent-soft. The obvious pairing (accent on accent-soft)
     measures 4.41 : 1 - under AA at the 13px a selected chip or toggle uses,
     which is exactly where soft fills show up. */
  --ga-on-accent-soft: var(--ga-accent-700); /* 6.22 : 1 on accent-soft */

  /* ── THE KEY: the green ramp for a control that commits to something ──────
     The buy button on /pricing, and the action buttons on /aptitude. Green
     marks the ACTION here; it does not replace the accent, which still carries
     links, focus rings and hover borders on the same pages.

     EVERY VALUE IS DERIVED FROM --ga-success, NOT TYPED, and that is what makes
     one set of declarations work in both themes: --ga-success flips from a dark
     green (#00a63e) to a light one (#4ed08a), so mixing toward black keeps the
     face darker than the token either way, and --ga-on-accent is white in light
     and near-black in dark. Do not replace any of them with a literal.

     RE-TUNED when --ga-success brightened to #00a63e. These percentages are not
     decoration - they are the only thing holding the face above AA, and a
     brighter base makes every stop lighter. Measured on the LIGHTEST stop of
     each gradient, which is the worst case because the label sits over the
     whole face: rest 5.22 : 1 light / 5.61 : 1 dark, hover 4.77 : 1 light /
     6.15 : 1 dark. The old percentages (84/78/90/84) against the new base give
     4.43 : 1 and 4.00 : 1, both under. If --ga-success moves again, RE-MEASURE
     these rather than assuming they still hold.

     Lifted out of pricing/CheckoutPanel.css, which held the only copy, when
     /aptitude needed the same button. Two hand-kept copies of a measured ramp is
     how one of them drifts. */
  --ga-key-edge: color-mix(in srgb, var(--ga-success) 64%, #000);
  --ga-key-face-from: color-mix(in srgb, var(--ga-success) 76%, #000);
  --ga-key-face-to: color-mix(in srgb, var(--ga-success) 72%, #000);
  --ga-key-face-hover-from: color-mix(in srgb, var(--ga-success) 80%, #000);
  --ga-key-face-hover-to: color-mix(in srgb, var(--ga-success) 76%, #000);
  --ga-key-lip: color-mix(in srgb, var(--ga-success) 52%, #000);

  /* ── the direction "more prominent than the page behind it" ───────────────
     Read this before touching any hover stop below.

     A key shades in TWO different directions and they are not the same thing.
     SHADING - edge, face-to, lip - is a light source: always toward #000, in
     both themes, because that is what a bevel is. PROMINENCE - rest to hover -
     is relative to the PAGE: darker on a light one, lighter on a dark one.

     Green and accent get away with mixing hover toward #000 as well, but only
     by accident: their base token itself flips light-to-dark, so the mix lands
     the right way round twice. --ga-fg1 does not have that property. It runs
     #272727 -> #f2f4f7, so an ink keycap hovered toward #000 in dark mode turns
     from white to grey - which every user reads as DISABLED, not as hovered.

     Hence one token, used by the hover pair and by nothing else. */
  --ga-key-emph: #000;

  /* ── the other four tones ─────────────────────────────────────────────────
     Same physical key as the green above, same six-stop contract, different
     base. Every stop is measured rather than eyeballed, by the same ruler that
     produced the green's numbers: `python3 scripts/contrast-check.py`, which
     reproduces the 5.22 / 5.61 / 4.77 / 6.15 figures recorded above to two
     decimals. It exits non-zero if any face or hover stop drops under AA.
     RUN IT after changing any percentage here, or after moving --ga-accent,
     --ga-fg1, --ga-danger or --ga-fg3 - four ramps hang off those and they all
     shift at once with no error anywhere.

     The EDGE and the LIP are deliberately not held to 4.5:1. Neither is ever
     behind text: the label is centred in a >=32px box and never crosses a
     0.5px border or a 3px band. What they are held to is different and is also
     checked - the edge has to give the cap a SILHOUETTE against the page (WCAG
     1.4.11's 3:1 for a control boundary), and the lip has to give it THICKNESS
     against its own face, measured against the green's depth rather than
     against an absolute. */

  /* ACCENT. Base --ga-accent, which is already AA as a label background at
     4.84:1 raw - so unlike green, whose face darkens to 76/72 to get there,
     this one barely shades at all.
       rest 5.16 light / 5.80 dark      hover 6.14 / 7.40
     This REPLACES the hand-picked 500/600/700/800 stops in ui/Button.css and
     the html.dark block under them - the last ramp in the codebase chosen by
     eye rather than measured. */
  --ga-key-accent-edge: color-mix(in srgb, var(--ga-accent) 78%, #000);
  --ga-key-accent-face-from: color-mix(in srgb, var(--ga-accent) 96%, #000);
  --ga-key-accent-face-to: color-mix(in srgb, var(--ga-accent) 92%, #000);
  --ga-key-accent-face-hover-from: color-mix(in srgb, var(--ga-accent) 86%, var(--ga-key-emph));
  --ga-key-accent-face-hover-to: color-mix(in srgb, var(--ga-accent) 80%, var(--ga-key-emph));
  --ga-key-accent-lip: color-mix(in srgb, var(--ga-accent) 68%, #000);

  /* INK. Base --ga-fg1, label --ga-bg. The face is the base ITSELF, unmixed -
     an ink keycap is already as dark as the ramp goes - and what little
     shading there is comes from face-to and the lip.
       rest 13.95 light / 17.02 dark    hover 14.86 / 17.20
     Contrast is never the constraint on this tone. The constraint is that rest
     and hover differ by 5/255 in light and 3/255 in dark, i.e. invisibly, and
     no percentage fixes that - it is what a near-black or near-white face IS.
     So ink is the one tone whose hover signal is ELEVATION rather than colour;
     see --key-hover-shadow in styles/keys.css. That is not a workaround, it is
     what .klay-hero-primary already did (Hero.css shadow-md -> shadow-lg)
     before the recipe absorbed it.
     Its LIP is the one stop in the system with a per-theme percentage - see
     the html.dark block for why. */
  --ga-key-ink-edge: var(--ga-fg1);
  --ga-key-ink-face-from: var(--ga-fg1);
  --ga-key-ink-face-to: color-mix(in srgb, var(--ga-fg1) 90%, #000);
  --ga-key-ink-face-hover-from: color-mix(in srgb, var(--ga-fg1) 88%, var(--ga-key-emph));
  --ga-key-ink-face-hover-to: color-mix(in srgb, var(--ga-fg1) 78%, var(--ga-key-emph));
  --ga-key-ink-lip: color-mix(in srgb, var(--ga-fg1) 30%, #000);

  /* DANGER. Base --ga-danger, label --ga-on-accent.
       rest 5.19 light / 6.25 dark      hover 6.17 / 7.79
     No destructive control on the site is a key today - .pr-coupon-btn--clear
     and .apt-confirm-delete are both outlines. This exists so that the first
     one that is does not get invented at its call site. */
  --ga-key-danger-edge: color-mix(in srgb, var(--ga-danger) 76%, #000);
  --ga-key-danger-face-from: color-mix(in srgb, var(--ga-danger) 96%, #000);
  --ga-key-danger-face-to: color-mix(in srgb, var(--ga-danger) 92%, #000);
  --ga-key-danger-face-hover-from: color-mix(in srgb, var(--ga-danger) 86%, var(--ga-key-emph));
  --ga-key-danger-face-hover-to: color-mix(in srgb, var(--ga-danger) 80%, var(--ga-key-emph));
  --ga-key-danger-lip: color-mix(in srgb, var(--ga-danger) 66%, #000);

  /* NEUTRAL - the outlined secondary, and the one tone whose EDGE is
     load-bearing rather than decorative. Its face is --ga-surface on --ga-bg,
     which is 1.07 : 1: the cap has no silhouette of its own, so the hairline is
     the only thing separating the button from the page.

     It is therefore NOT --ga-border-strong, which is what every secondary
     button on the site uses today and which measures 1.54 : 1 against the page
     in light and 2.26 : 1 in dark - both under WCAG 1.4.11's 3:1 for a control
     boundary. An outlined button nobody can find the outline of is an invisible
     box with a label in it. 84% off --ga-fg3 is the lowest step that clears 3:1
     in BOTH themes (4.05 light, 3.63 dark) while staying clear of the face.

     The rest of the tone is expressed inline in keys.css - a token that
     resolves to var(--ga-surface) adds a name and no information. */
  --ga-key-neutral-edge: color-mix(in srgb, var(--ga-fg3) 84%, var(--ga-surface));

  /* The one green that is safe as TEXT or a border on the page background.
     --ga-success itself measures 3.22 : 1 on --ga-bg - under AA for the 13px
     labels an outlined control uses, and for the small "Live"/status labels
     across the site that now point here. This clears it: 5.55 : 1 light,
     4.53 : 1 dark.

     ITS OWN MIX, no longer an alias of --ga-key-edge. The edge moved to 64% so
     the border still reads against a lighter face; following it down would have
     taken this to 4.14 : 1 in DARK mode, where the mix runs against #111213 and
     darkening the green is the wrong direction to begin with. Held at the 70%
     that was measured for the TEXT role itself.

     RENAMED from --ga-key-ink, and the old name is kept below only so nothing
     breaks mid-migration. "Key ink" used to mean "the ink you write the green
     KEY's caption in". The moment an INK TONE existed it also parsed as "the
     ink tone's key colour", and --ga-key-ink sitting four lines from
     --ga-key-ink-face-from is a wrong-paste that no test and no reviewer would
     catch - both are valid CSS, both resolve, and one of them silently paints a
     status label the colour of a black button. */
  --ga-green-text: color-mix(in srgb, var(--ga-success) 70%, #000);
  /* DEPRECATED alias. Do not use in new code; delete once nothing reads it. */
  --ga-key-ink: var(--ga-green-text);

  /* Sequential scale for heatmaps and density plots: ramp from --ga-surface to
     this. Deliberately NOT --ga-accent - that lands mid-range around 3:1 and
     the number printed inside the cell stops being readable. Chosen so
     --ga-fg1 clears 7:1 at full intensity in both themes. The labs need one
     each (attention weights, cache hit rate, bloom false positives, gradient
     contours), so it belongs here rather than being re-derived four times. */
  --ga-heat-end: var(--ga-accent-300);

  --ga-signature-from: #2f7cf6;
  --ga-signature-to: #17c3a8;
  --ga-signature: linear-gradient(135deg, var(--ga-signature-from), var(--ga-signature-to));

  /* ── categorical (course folders, roadmap nodes, chart series) ────────── */
  --ga-cat-blue: #2f7cf6;
  --ga-cat-green: #2ab673;
  --ga-cat-purple: #6e56cf;
  --ga-cat-orange: #e8822a;
  --ga-cat-yellow: #e9b949;
  --ga-cat-red: #e4402c;
  --ga-cat-teal: #17c3a8;

  /* ── status ───────────────────────────────────────────────────────────── */
  /* THE BRAND GREEN, and it is measured off the reference rather than guessed.
     fanout's audience band paints Tailwind's green-600 - `bg-green-600`, i.e.
     oklch(0.627 0.194 149.214), which rasterises to THIS. It is NOT the
     `--ga-success: #0f9d58` their token file also declares; that token is not
     what the band uses, and reading their stylesheet instead of their rendered
     page is how this was got wrong once already.

     #0f9d58 was rgb(15,157,88); this is rgb(0,166,62). The blue channel is what
     carries the difference - 88 against 62 - and that is the whole of "theirs
     is bright, ours is dark".

     It is a FILL colour. As TEXT it measures 3.22 : 1 on --ga-bg, so anything
     setting `color:` on a small label wants --ga-key-ink above, not this. */
  --ga-success: #00a63e;
  --ga-warning: #e8822a;
  --ga-danger: #dc2626;
  --ga-info: #2f7cf6;

  /* ── type ─────────────────────────────────────────────────────────────── */
  --ga-font-sans: "Overused Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --ga-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --ga-font-display: "Departure Mono", ui-monospace, monospace;
  /* legacy alias */
  --ga-font: var(--ga-font-sans);
  --ga-mono: var(--ga-font-mono);

  /* xs..xl are FIXED. 12-18px is already phone-legible, and shrinking body copy
     on a narrow column makes it harder to read, not easier - the thing that
     needs to give on a phone is display type, not paragraphs. */
  --ga-text-xs: 12px;
  --ga-text-sm: 13px;
  --ga-text-md: 14px;
  --ga-text-lg: 16px;
  --ga-text-xl: 18px;

  /* 2xl..4xl are FLUID, and each max is the value it used to be pinned at, so
     nothing changes above the crossover width. Roughly 25 stylesheets had each
     re-invented a clamp of their own to dodge the fixed sizes; those keep
     working - composing a clamp() inside another clamp() is legal, and every
     such site here moves in the right direction because both its ends shrink.
       4xl   32px -> 24px below 462px
       3xl   24px -> 20px below 476px
       2xl   20px -> 18px below 529px */
  --ga-text-2xl: clamp(18px, 3.4vw, 20px);
  --ga-text-3xl: clamp(20px, 4.2vw, 24px);
  --ga-text-4xl: clamp(24px, 5.2vw, 32px);

  /* --ga-text-hero STAYS FIXED, and that is deliberate. Hero.css derives a
     whole ladder from it - `--klay-hero-min: calc(var(--ga-text-hero) * 0.68)`
     and two clamps built on that - so making this one fluid would have fed a
     clamp into its own multiplier and dropped the homepage headline from 31px
     to 20px at 390px. It is a REFERENCE value, not a size anything should set
     directly.

     Use --ga-text-display for a display heading that has to survive a phone.
     Its max is the same 56px, so nothing changes above 778px; below that it
     tracks the viewport down to 30px. `.kc-title` - every course, module and
     lesson title, the highest-traffic page type on the site - was the one
     place setting --ga-text-hero raw, which is how a 56px headline ended up
     over a 327px column at about eleven characters to the line. */
  --ga-text-hero: 56px;
  --ga-text-display: clamp(30px, 7.2vw, 56px);

  /* FORM CONTROLS ONLY, and it is a floor rather than a preference. Safari on
     iOS zooms the viewport when a focused input computes under 16px, and it
     does not zoom back out afterwards. Every input on the site was 13-14px, so
     tapping the email field on /pricing or /signin - the exact moment of
     highest intent - threw the buyer into a zoomed, horizontally-panning page. */
  --ga-text-input: 16px;

  --ga-weight-regular: 400;
  --ga-weight-medium: 500;
  --ga-weight-semibold: 600;
  --ga-weight-bold: 700;

  --ga-lh-tight: 100%;
  --ga-lh-snug: 1.25;
  --ga-lh-normal: 1.5;

  /* ── space ────────────────────────────────────────────────────────────── */
  --ga-space-1: 4px;
  --ga-space-2: 8px;
  --ga-space-3: 12px;
  --ga-space-4: 16px;
  --ga-space-5: 20px;
  --ga-space-6: 24px;
  --ga-space-8: 32px;
  --ga-space-10: 40px;
  --ga-space-12: 48px;
  --ga-space-16: 64px;
  --ga-space-20: 80px;

  /* ── radius ───────────────────────────────────────────────────────────── */
  --ga-r-xs: 4px;
  --ga-r-sm: 6px;
  --ga-r-md: 8px;
  --ga-r-lg: 12px;
  --ga-r-xl: 16px;
  --ga-r-2xl: 20px;
  --ga-r-full: 999px;

  /* ── elevation ────────────────────────────────────────────────────────── */
  /* Each level ends in a 0 0 0 1px hairline ring. That ring - not the blur -
     is what makes these cards read as crisp instead of soft. The old Klay
     shadows omitted it. */
  --ga-shadow-sm: 0 1px 2px #3b3b3b17, 0 0 0 1px #3b3b3b03;
  --ga-shadow-md: 0 1px 2px #3b3b3b17, 0 2px 4px #3b3b3b0d, 0 0 0 1px #3b3b3b03;
  --ga-shadow-lg: 0 2px 4px #3b3b3b0d, 0 4px 8px #3b3b3b17, 0 8px 16px #3b3b3b1a, 0 0 0 1px #3b3b3b03;

  /* ── layout ───────────────────────────────────────────────────────────── */
  --ga-topbar-h: 72px;
  --ga-sidebar-w: 248px;
  /* The page gutter. ONE source of truth, because two things have to agree:
     the padding on .ga-container/.ga-reading, and the negative margin any
     full-bleed child uses to cancel it. styles/mobile.css steps this down to
     16px at <=600 and 12px at <=400; a component that hard-codes 24px (or 16px)
     to break out will be four pixels wrong on a 375px phone and push the page
     sideways - which is exactly what the video card did. */
  --ga-gutter: var(--ga-space-6);
  --ga-content-max: 1280px;
  /* The TOP BAR is wider than the content column, and only the top bar.
     It carries the wordmark, nine nav links, the search field and the
     account corner in one un-wrapping row; the page below carries prose.
     Holding both to 1280 is what put the last nav link underneath the
     account chip - see the measured table in components/Header.css. */
  --ga-topbar-max: 1536px;
  --ga-reading-max: 1000px;
  /* WCAG 2.2 pointer target floor. Every button, link-as-button and control
     hits this; it was being hand-typed as a bare 44px in three stylesheets. */
  --ga-target-min: 44px;

  /* ── glass ────────────────────────────────────────────────────────────── */
  --ga-topbar-glass: #f7f7f8e6;
  --ga-panel-glass: #fffffff0;
  --ga-launcher-glass: #ffffff9e;
  --ga-launcher-border: #ffffff8c;
  --ga-launcher-active: #ffffffd9;
  --ga-launcher-hover: #ffffff8c;
  --ga-modal-scrim: #00000040;

  /* ── motion ───────────────────────────────────────────────────────────── */
  --ga-ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ga-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --ga-dur-fast: 0.15s;
  --ga-dur-base: 0.2s;
  --ga-dur-slow: 0.25s;
}

html.dark {
  --ga-bg: #111213;
  --ga-surface: #191a1c;
  --ga-sidebar: #151617;
  --ga-hover: #242527;
  --ga-chip: #202123;
  --ga-divider: #2a2b2e;
  --ga-border: #36373b;
  --ga-border-strong: #4c4e54;

  --ga-fg1: #f2f4f7;
  --ga-fg2: #a9b0ba;
  /* fanout's #747d89 measures 3.87 : 1 on a dark chip. Lightened to clear AA
     at the caption sizes this token is used for. */
  --ga-fg3: #8b939d; /* 5.19 : 1 worst case */
  --ga-fg-inv: #111213;

  /* Lift the accent so it clears AA as text against the dark surface. */
  --ga-accent: var(--ga-accent-400); /* 6.26 : 1 on --ga-bg */
  --ga-accent-hover: var(--ga-accent-300);
  --ga-accent-soft: #14243d;
  /* White on the lifted accent is only 3.00 : 1 - the label goes dark. */
  --ga-on-accent: var(--ga-fg-inv); /* 6.26 : 1 on accent-400 */
  --ga-on-accent-soft: var(--ga-accent-300); /* 7.51 : 1 on the dark soft fill */
  /* Ramps the other way in dark: surface is near-black, so full intensity is a
     deep blue with light ink on top. */
  --ga-heat-end: var(--ga-accent-800);

  --ga-success: #4ed08a;
  --ga-warning: #f0a45b;
  --ga-danger: #f87171;
  --ga-info: #6ea2ff;

  /* Prominence is LIGHTER than the page here, where in light mode it is darker.
     See the note beside the light-mode declaration - this is the only reason
     the ink tone's hover does not read as "disabled" in dark. Every OTHER mix
     in the key ramps stays pointed at #000 in both themes, because shading a
     bevel is a light source and not a theme. */
  --ga-key-emph: #fff;

  /* The one stop in the whole key system with a per-theme percentage.
     --ga-fg1 swings the full width of the ramp between themes - #272727 to
     #f2f4f7 - so a single number cannot serve both. In light, 30% is as dark as
     a near-black cap's lip can usefully go (pure black is the ceiling, at
     1.34 : 1 against the face; 30% reaches 1.24 and keeps a trace of hue). Reuse
     that 30% against a near-WHITE base and it lands at 6.5 : 1 against its own
     face - four times the depth the green reference has, which stops reading as
     thickness and starts reading as a black bar under a white button. 64%
     brings it to 1.9 : 1, next to green's 1.71.
     Every other tone's base moves inside a narrow band, which is why this is
     the only override. */
  --ga-key-ink-lip: color-mix(in srgb, var(--ga-fg1) 64%, #000);

  /* The categoricals were the one ramp left un-themed. Tuned for a light
     background, they sit around 4:1 as small text on a dark surface - fine as
     a dot or a tint, marginal the moment one is used as a label. Lifted here
     so any of them can carry text in either theme. */
  --ga-cat-blue: #6ea2ff;
  --ga-cat-green: #4ed08a;
  --ga-cat-purple: #a996f0;
  --ga-cat-orange: #f0a45b;
  --ga-cat-yellow: #e9c46a;
  --ga-cat-red: #f87171;
  --ga-cat-teal: #45d6bd;

  --ga-shadow-sm: 0 1px 2px #00000057, 0 0 0 1px #ffffff06;
  --ga-shadow-md: 0 1px 2px #00000061, 0 4px 10px #00000029, 0 0 0 1px #ffffff06;
  --ga-shadow-lg: 0 2px 4px #0000006b, 0 8px 20px #0000003d, 0 0 0 1px #ffffff09;

  --ga-topbar-glass: #111213e6;
  --ga-panel-glass: #191a1cf5;
  --ga-launcher-glass: #191c20c2;
  --ga-launcher-border: #ffffff1a;
  --ga-launcher-active: #ffffff17;
  --ga-launcher-hover: #ffffff0f;
  --ga-modal-scrim: #00000094;
}
