/* ─────────────────────────────────────────────────────────────────────────────
 * investrello-tokens.css — THE design tokens. One file, twelve surfaces.
 *
 * WHY THIS FILE EXISTS (D-012, TASK-014). It did not, until 2026-07-30. The same
 * token block was COPIED into twelve independent HTML files — app, tenant, signup,
 * login, onboarding, checkout, pay, contractor, bank-callback, privacy, terms, 404
 * — and every copy drifted. In one week the estate carried four values of `--dim`,
 * four of `--muted`, three of `--green-lo` and two each of `--hover`, `--border-hi`,
 * `--gold-lo`, `--red-lo`, `--blue`, `--blue-lo` and `--r`. Each copy was
 * individually plausible; the divergence was only ever visible from above.
 *
 * The cost was not tidiness. `--dim` at 0.24 alpha renders at 1.98:1 — below the
 * 4.5 floor for body text — and it shipped live on the whole acquisition and
 * payment path while the gate that should have caught it was looking at two of the
 * twelve. It took three separate passes to fix ten files, and it was found by
 * accident.
 *
 * So: a fix now lands once, and the failure mode changes from "one page quietly
 * disagrees for months" to "the stylesheet 404s and everybody notices immediately".
 * `contrast.js` follows the `<link>` and treats an unresolvable one as a failure.
 *
 * ─── HOW TO CHANGE ANYTHING HERE ────────────────────────────────────────────
 *
 * 1. This file is CACHE-FIRST in the service worker, exactly like the shared JS.
 *    Change it and you MUST bump `const CACHE` in `build/app/sw.js` AND roll the
 *    `?v=ivNN` stamp on ALL TWELVE pages that link it. `predeploy.ps1` check 4b
 *    treats a split stamp as a hard FAIL, because a half-rolled stamp pins one page
 *    to a stale copy — which is worse than not rolling at all.
 * 2. Every token must have a value in EVERY theme it can be seen in. A token
 *    missing from a variant falls through to the base value; that is how light
 *    `--dim` and light `--gold` both went wrong, twice, in two days.
 * 3. Measure both themes. Never infer one from the other: dark ink at 50% on paper
 *    is not light ink at 50% on black. `node scripts/verify/contrast.js`.
 *
 * ─── WHERE THE LIGHT THEME LIVES, AND WHY IT IS NOT HERE ────────────────────
 *
 * `:root.light` stays inline in `build/app/index.html`. The `light` class is set by
 * one pre-paint script, which exists on one surface: the app is the only page with
 * an appearance setting. Declaring a light theme in a file the other eleven load
 * would declare a theme they cannot enter — and it would make `contrast.js` measure
 * eleven more copies of the app's twelve known light-theme failures, turning a
 * twelve-row register with a named owner into a ~130-row one. That is D-013's
 * "exemption wearing a register's clothes", arrived at by accident.
 *
 * There is no divergence risk in that, because there is exactly one light block.
 *
 * ─── WHERE PHASE 1 PUT ITS BLOCKS (DONE — TASK-015) ─────────────────────────
 *
 * `:root.v3`        → HERE, after `:root`. Reaches all twelve surfaces, which is
 *                     the entire reason this file was created before Phase 1 ran.
 * `:root.v3.light`  → `app/index.html`, beside `:root.light`, for the same reason.
 *
 * THE FLAG IS `?design=v3`, PERSISTED IN `localStorage` AND SET PRE-PAINT ON ALL
 * TWELVE SURFACES. `?design=v2` clears it. v2 is still the default and stays the
 * default until Caden approves the preview (D-014).
 *
 * THE SPECIFICITY, SETTLED (D-018). This arithmetic has now been got wrong four
 * times in two days — including once in this very header — and every instance
 * reached a CORRECT conclusion, because in each case the two selectors compared were
 * EQUAL and equality survives the error. A wrong number that produces right answers
 * is invisible to review. These are the values:
 *
 *   :root            (0,1,0)   a pseudo-class counts in the CLASS column
 *   :root.light      (0,2,0)   pseudo-class + class
 *   :root.v3         (0,2,0)   pseudo-class + class
 *   :root.v3.light   (0,3,0)   pseudo-class + two classes
 *
 * This file is linked BEFORE each page's inline `<style>`, so resolution goes:
 *   dark  + v2 : `:root`                                     (here)
 *   dark  + v3 : `:root` then `:root.v3` — (0,2,0) beats (0,1,0)
 *   light + v2 : `:root.light` (0,2,0) beats `:root` (0,1,0)
 *   light + v3 : `:root.v3.light` (0,3,0) beats every other block outright
 *
 * ⚠ THE SPLIT INVERTED §8.2'S TRAP, AND INVERTED IT INTO THE WORSE DIRECTION.
 * `:root.v3.light` must still redeclare EVERY token `:root.v3` declares — but the
 * consequence of omitting one has changed. When both v3 blocks lived in one file,
 * an omitted token fell through to a v3 DARK value: dark ink on paper, which
 * SCREAMS. Now `:root.v3` is here and `:root.light` is inline and therefore later,
 * so an omitted token falls through to the v2 LIGHT value — a plausible-looking
 * wrong colour, in the right theme, on a preview flag Caden judges BY EYE. Verified
 * in a browser, not reasoned. `contrast.js` asserts the two name sets are exactly
 * equal (`variantParityCheck`); that assertion is vacuous until these blocks exist
 * and activates on its own when they do.
 *
 * ─── PAGE-LOCAL OVERRIDES ───────────────────────────────────────────────────
 *
 * A page may declare its own `:root` block after this link; being later at equal
 * specificity, it wins. That is a supported mechanism, not a workaround — but every
 * such override is REGISTERED in `scripts/verify/contrast.js` (`PAGE_OVERRIDES`)
 * with a reason, an owner and a date. The gate fails on an override that is not
 * registered, on a registered override that no longer exists, and on one that is
 * declared but does not actually win. An unregistered page-local value is the exact
 * defect this file was created to end.
 *
 * ⚠ THAT CONTRACT EXPIRED IN PHASE 1, AND HERE IS WHAT REPLACED IT. "Later at
 * equal specificity" holds only while the two blocks ARE equal. A page-local
 * `:root` is (0,1,0) and `:root.v3` here is (0,2,0), so under `?design=v3` the
 * shared value wins on specificity REGARDLESS of source order. TASK-015 resolved
 * the two live overrides differently, because they had different causes:
 *
 *   contractor `--blue`  RE-HOMED. The page now declares `:root, :root.v3` — a
 *                        page-local `:root.v3` is (0,2,0), equal to this file's,
 *                        and later in source, so it wins again.
 *   tenant     `--r`     UNTOUCHED, because `:root.v3` below declares NO radius
 *                        token at all. Radius is TASK-016's scale; declaring it
 *                        here would have moved the portal's geometry under a
 *                        COLOUR flag, which is not what the flag is for.
 *
 * And the register no longer relies on anyone remembering: `crossBlockCheck`
 * resolves every registered override under EVERY theme selector the page carries,
 * so an override that survives `:root` and dies under `:root.v3` fails the build.
 * Adding `--r` to `:root.v3` would break tenant's row on the next run.
 * ───────────────────────────────────────────────────────────────────────────── */

:root {
  --bg:        #0A0A0C;
  --surface:   #0E0E11;
  --raised:    #131316;
  --hover:     #1B1B1F;
  --border:    rgba(255,255,255,0.08);
  --border-hi: rgba(255,255,255,0.16);
  --text:      #F5F5F3;
  /* --muted / --dim raised for WCAG AA: at the old 0.24, --dim rendered ~1.9:1 on
     --bg (fails AA and the 3:1 UI floor). --dim 0.50 ≈ 4.8:1 on --bg / 4.5:1 on
     --hover (passes AA); --muted lifted in step to keep three distinct text tiers. */
  --muted:     rgba(245,245,243,0.66);
  --dim:       rgba(245,245,243,0.50);
  --gold:      #E8C06A;
  /* secondary-emphasis gold: a desaturated tint of --gold for "needs attention"
     accents, distinct from the primary CTA gold without being a new hue. */
  --gold-2:    #C9A867;
  --gold-2-lo: rgba(201,168,103,0.12);
  --gold-hi:   #F5D98A;
  --gold-lo:   rgba(232,192,106,0.09);
  --gold-glow: rgba(232,192,106,0.22);
  --gold-brd:  rgba(232,192,106,0.38);
  --green:     #2DD4A0;
  --green-lo:  rgba(45,212,160,0.08);
  --red:       #F87171;
  --red-lo:    rgba(248,113,113,0.09);
  --blue:      #5B9AF8;
  --blue-lo:   rgba(91,154,248,0.08);
  /* Interaction washes + the white primary pill, tokenised (2026-07-24)
     so the light theme can invert them in one place. */
  --wash-lo:   rgba(255,255,255,0.04);
  --wash:      rgba(255,255,255,0.07);
  --wash-hi:   rgba(255,255,255,0.12);
  --pill:      #FFFFFF;
  --pill-ink:  #0A0A0C;
  /* Scrims, shadows and fills, tokenised (2026-07-30, TASK-011 phase 0).
     These carried hardcoded literals until then, so a theme block could not
     reach them — a var() is the only thing a token block can restyle.

     --scrim / --shadow / --hero-scrim are CHANNEL TRIPLETS, consumed as
     rgba(var(--scrim),0.66). Deliberate: seven distinct scrim alphas are in
     use (0.55 0.62 0.66×3 0.72 0.82 0.94) and folding them into one rgba
     token would change how the app looks. The triplet swaps the hue and
     leaves each alpha exactly as it was.

     They hold identical values today and are still three tokens, because
     they diverge the moment a light/v3 theme lands: paper wants an
     ink-tinted scrim but a SOFTER shadow, and .pd-hero is a deliberate dark
     brand panel in BOTH themes, so its gradient must not follow --scrim when
     --scrim inverts.

     PHASE 1 MUST CHANGE --shadow's SHAPE, NOT JUST ITS VALUE (D1/C6). A channel
     triplet carries HUE ONLY, but "softer on paper" is an ALPHA and BLUR change,
     and the four alphas (0.45 / 0.55 / 0.6 / 0.7) are baked at the call sites.
     Give light --shadow an ink triplet and you get a 0.7-alpha ink smear on
     paper — worse than the navy it replaced. It needs promoting to complete
     elevation tokens. Do NOT collapse it into --scrim: that folds four elevation
     sites into a suppression token and makes the separation more expensive later,
     not less. */
  --scrim:         3,7,20;
  --shadow:        3,7,20;
  --hero-scrim:    3,7,20;
  --pill-hi:       #E8E8E5;
  /* ink that sits ON a gold fill — gold is gold in both themes, so this is
     correctly theme-blind; tokenised so phase 1 changes it once. */
  --gold-fill-ink: #0A0A0C;
  /* GOLD SPLITS IN TWO IN v3, AND THESE TWO EXIST SO THE SPLIT COSTS NOTHING IN v2
     (TASK-015 C1). In v3 `--gold` becomes the INK-safe value (light #7A5A0E, 5.84:1
     on --bg) and `--gold-fill` the decorative one, because the failure being designed
     out is "someone reaches for --gold and it is a fill value". Every site that paints
     gold and puts something on top of it now reads --gold-fill / --gold-fill-hi. Here
     in v2 they are BYTE-EQUAL to --gold / --gold-hi in each theme, so the swap renders
     identically until the flag is on. --gold-fill must never sit on --hover (2.75:1,
     under the 3:1 non-text floor); on --bg/--surface/--raised it is 2.98/3.15/3.25, so
     it is a fill for filled pills with dark ink, never a backdrop for gold text. */
  --gold-fill:     #E8C06A;
  --gold-fill-hi:  #F5D98A;
  /* The focus ring, decoupled from --gold so it can never become a fill value.
     Theme-blind in v2 ON PURPOSE: it carries exactly the #E8C06A that eleven
     surfaces hardcoded until TASK-015, so swapping the literal for the token
     changed nothing. It is a known light-theme failure in v2 (1.72:1 on --bg,
     PINNED) and v3 fixes it — dark #F5D98A 14.37:1, light #7A5A0E 5.84:1. */
  --focus:         #E8C06A;
  --select-bg:     rgba(232,192,106,0.3);
  --select-ink:    #F5F5F3;
  /* The property hero is a DELIBERATE dark brand panel in BOTH themes — its
     ambient type-gradient and darkening scrim are designed for white type, and a
     light variant turned it into a cream-to-black smear. It used to be half
     tokenised: the darkening gradient read --hero-scrim while the panel fill, its
     ink and its secondary ink stayed literals inside a `:root.light .pd-hero`
     escape. Half is the least legible state, because the next reader assumes the
     token controls the panel (D6/C7). These three are theme-blind on purpose, so
     the component needs no theme escape at all.
     WHEN D-010's COOL CAST LANDS, --hero-bg must follow the new dark base: it is
     #0A0A0C because --bg is, not by independent choice. */
  --hero-bg:       #0A0A0C;
  --hero-ink:      #F5F5F3;
  --hero-ink-2:    rgba(245,245,243,0.66);
  /* THE PANEL WAS THEME-BLIND; WHAT IS DRAWN INSIDE IT WAS NOT (TASK-015 D2b, from
     TASK-014 Design D2/D3). Measured in light theme on --hero-bg: `.badge.red`
     "Vacancy" 3.97:1 — the status a landlord most needs to see — `.badge.green`
     4.22:1, `.badge.attention` 3.26:1, and the `.pd-hero-grid` dots 1.00:1, i.e.
     invisible. The badges read --red/--green/--gold and their washes, which invert
     for paper while the panel underneath does not.
     The fix is a SCOPED TOKEN ISLAND, not another `:root.light .pd-hero` escape —
     `.pd-hero` re-declares these names as local custom properties that every
     descendant inherits, so one rule covers all four theme/flag combinations and
     `contrast.js` can READ it. A specificity escape it cannot read.
     Declared HERE ONLY, once: they are theme-blind, so `:root.light`, `:root.v3` and
     `:root.v3.light` all inherit them, and there is no fourth place to get wrong. */
  --hero-red:      #F87171;
  --hero-red-lo:   rgba(248,113,113,0.09);
  --hero-green:    #2DD4A0;
  --hero-green-lo: rgba(45,212,160,0.08);
  --hero-gold:     #E8C06A;
  --hero-gold-lo:  rgba(232,192,106,0.09);
  --hero-gold-2:   #C9A867;
  --hero-gold-2-lo: rgba(201,168,103,0.12);
  --hero-blue:     #5B9AF8;
  --hero-blue-lo:  rgba(91,154,248,0.08);
  --hero-muted:    rgba(245,245,243,0.66);
  --hero-hover:    #1B1B1F;
  --hero-wash-lo:  rgba(255,255,255,0.04);
  --r: 8px; --r-lg: 14px;
}

/* ═══ v3 — THE PHASE 1 PREVIEW PALETTE, DARK ═══════════════════════════════════
 *
 * Reached by `?design=v3` (persisted; `?design=v2` clears it). v2 is the DEFAULT
 * and stays the default until Caden approves the preview — D-014, which exists
 * because the last canvas-level redesign was reverted the day it shipped.
 *
 * Every value below is FROM §2.5 of `strategy/app-redesign-foundation-2026-07-30.md`,
 * where each one was measured in both themes. They are not re-derived here and they
 * are not rounded. `node scripts/verify/contrast.js` measures `:root.v3` and
 * `:root.v3.light` as first-class theme blocks; TASK-013's twelve pinned failures are
 * v2-light rows and v3 is expected to pass clean.
 *
 * WHAT CHANGED, IN ONE PARAGRAPH. The dark surfaces take a COOL cast (D-010 Q1) so an
 * app screenshot reads as a panel ON the marketing canvas rather than as the canvas —
 * `#08090E` is a 6-point blue spread, a cool neutral, NOT the retired navy `#030714`
 * (a 17-point spread). Gold splits into ink (`--gold`) and fill (`--gold-fill`). The
 * light theme's semantic four are darkened so all four clear 4.5:1 on paper, which
 * they do not today. Five new hues arrive as `--iri-1…5` — sampled from the landing
 * coin material, category only, never severity. And `--focus`, `--border-strong`,
 * `--sunken`, `--overlay`, `--field*` and `--disabled` are new tokens that fix classes
 * of bug rather than restyling anything.
 *
 * ⚠ ANYTHING DECLARED HERE MUST ALSO BE DECLARED IN `:root.v3.light`
 * (`app/index.html`). Not by care — `variantParityCheck()` asserts the two name sets
 * are EXACTLY equal and fails the build otherwise, because after TASK-014's split an
 * omission no longer screams (dark ink on paper) but WHISPERS: it falls through to the
 * v2 LIGHT value, a plausible-looking wrong colour on a flag judged by eye.
 *
 * ⚠ NO RADIUS, TYPE, SPACING OR MOTION TOKEN APPEARS HERE. Those are TASK-016 and are
 * not tokenised yet. Two consequences, both deliberate: `--r-md` — read at `app:1214`
 * and `:1240` and declared NOWHERE, so both sites silently take the `10px` fallback —
 * must NOT be declared here, or two radii would change under a colour flag and nowhere
 * else, which reads as a bug. And tenant's registered `--r: 10px` override keeps
 * winning precisely because this block declares no `--r`.
 * ════════════════════════════════════════════════════════════════════════════════ */

:root.v3 {
  /* Surfaces — the cool cast. Free on contrast: --text 18.12 → 18.22, --gold
     11.47 → 11.54, --dim 5.01 → 4.98. Nothing crosses a threshold. */
  --bg:        #08090E;
  --surface:   #0C0D13;
  --raised:    #111219;
  --hover:     #191B23;
  /* new: table headers and inset wells, so "recessed" stops being a border trick */
  --sunken:    #050609;
  /* new: the one modal/drawer scrim, replacing twelve retired-navy literals */
  --overlay:   rgba(5,6,14,0.72);
  --border:    rgba(255,255,255,0.08);
  --border-hi: rgba(255,255,255,0.16);
  /* new: any boundary that CARRIES MEANING — input outlines, overlay edges, table
     grid lines that separate data. 3.02:1, so it meets 1.4.11 where --border (1.18)
     and --border-hi (1.52) never could. A dark modal over --bg measures 1.04:1
     against its own surface: without this it reads as a floating hole. */
  --border-strong: rgba(255,255,255,0.34);
  --text:      #F5F5F3;
  --muted:     rgba(245,245,243,0.66);
  --dim:       rgba(245,245,243,0.50);
  --gold:      #E8C06A;
  --gold-2:    #C9A867;
  --gold-2-lo: rgba(201,168,103,0.12);
  --gold-hi:   #F5D98A;
  --gold-lo:   rgba(232,192,106,0.09);
  --gold-glow: rgba(232,192,106,0.22);
  --gold-brd:  rgba(232,192,106,0.38);
  --gold-fill:    #E8C06A;
  --gold-fill-hi: #F5D98A;
  --green:     #2DD4A0;
  --green-lo:  rgba(45,212,160,0.08);
  --red:       #F87171;
  --red-lo:    rgba(248,113,113,0.09);
  --blue:      #5B9AF8;
  --blue-lo:   rgba(91,154,248,0.08);
  /* THE ALPHAS ARE UNCHANGED, AND THAT IS A DECISION MADE IN PHASE 1 RATHER THAN AN
     INHERITANCE (D2c, from TASK-014 Design D9). All seven of TASK-014's convergences
     moved to the fainter value on the ground that "the app's block is canonical",
     which is not a measurement. So the washes were re-measured here against the ink
     that sits on them, which is the pair that actually matters: dark gold-on-gold-lo
     10.11, gold-2 7.49, green 9.43, red 6.57, blue 6.48; light 5.20 / 4.99 / 5.08 /
     5.09 / 4.84. Every one clears 4.5:1. `.badge.gold` measures 2.86:1 in v2 light —
     the live failure §2.5 flags — and it is fixed by the INK moving to #7A5A0E, not
     by the wash moving. Changing an alpha would have been a change with no argument
     behind it; these have one. */
  --wash-lo:   rgba(255,255,255,0.04);
  --wash:      rgba(255,255,255,0.07);
  --wash-hi:   rgba(255,255,255,0.12);
  --pill:      #FFFFFF;
  --pill-ink:  #08090E;
  --pill-hi:   #E8E8E5;
  /* The scrim/shadow/hero triplets follow the cool base: #05060E is brand.md's
     marketing base, which is what --overlay above is an alpha of.
     STILL OWED, AND NOT ATTEMPTED HERE (C6): light --shadow needs an ALPHA and BLUR
     change, not a hue change — the four alphas (0.45/0.55/0.6/0.7) are baked at the
     call sites, so an ink triplet on paper is a 0.7-alpha smear. That is a shape
     change to the token, i.e. component work, and it belongs with TASK-016's
     elevation scale. Keeping the dark triplet in BOTH v3 blocks is what stops this
     task shipping the smear. */
  --scrim:      5,6,14;
  --shadow:     5,6,14;
  --hero-scrim: 5,6,14;
  --gold-fill-ink: #0A0A0C;
  /* new: the ring colour, decoupled from --gold so it can never be a fill value.
     A SINGLE-COLOUR RING IS NOT ENOUGH ON ITS OWN — it measures 1.38:1 against the
     white pill and 1.25:1 against the gold fill, so the three-layer indicator in
     `app/index.html` adds a --bg separator band (19.89:1 and 11.47:1). */
  --focus:      #F5D98A;
  /* new: input surface + input border. --field-brd is --border-strong's value under
     its own name because an input's boundary IS the sole indicator of the control
     (1.4.11), where a card's hairline is decorative. Two names, two contracts. */
  --field:      #0C0D13;
  --field-brd:  rgba(255,255,255,0.34);
  /* new. 1.4.3 exempts disabled text, so this is not a contrast row — but it must
     NEVER be the only signal that a control is unavailable. */
  --disabled:   rgba(245,245,243,0.42);
  --select-bg:  rgba(232,192,106,0.3);
  --select-ink: #F5F5F3;
  /* ─── THE IRIDESCENT RAMP — NEW, AND FENCED ────────────────────────────────
     Sampled from `design/assets/landing-coins-4k.png`: 138,810 chroma-carrying
     pixels, 77% of them between 200° and 250°. "Iridescent" in this brand means
     BLUE — a blue→indigo→lilac dispersion with an amber specular rim, not a rainbow.

     AXIS RULE, HARD. `--gold`/`--green`/`--red`/`--blue` and ONLY those four may
     encode state, severity or judgement. The ramp encodes CATEGORY, SERIES or
     IDENTITY only, and is forbidden from carrying severity, sign or pass/fail. It
     never appears in a badge, a status dot or a verdict. That is what makes "more
     colours" safe: the colours that carry meaning did not multiply.

     Assignment, so it is not decoration looking for a job:
       --iri-1  the portfolio / "yours" / actuals      --iri-4  time / scheduled
       --iri-2  comparison / benchmark / market        --iri-5  secondary category
       --iri-3  modelled / projected / not-yet-real
     Chart rule: sign uses --green/--red, category uses the ramp, never both in one.

     ⚠ THESE VALUES ARE NOT FREE-FLOATING AND YOU MAY NOT NUDGE ONE. The lightnesses
     are deliberately STAGGERED rather than following the coin's natural gradient,
     because the first ramp tried — the raw sampled lightnesses — produced two pairs
     that failed colour-vision separation (azure↔indigo, lilac↔ice). Changing any
     value requires re-running the separation check, which is why it is now a check
     and not a sentence: `contrast.js` enforces a 1.25 floor on the best of
     {luminance, deuteranopia, protanopia} for all ten pairs, in both themes.

     TWO MEASURED CVD CONSTRAINTS THAT ARE RULES, NOT ADVICE (C5), recorded here
     because this is the file the next person opens: under simulated deuteranopia
     light --gold vs --red separate by 1.18 and light --green vs --blue by 1.13,
     both under the 1.25 floor. So GREEN AND BLUE MUST NEVER BE THE TWO SERIES IN
     ONE CHART, and GOLD AND RED STATUS MUST DIFFER IN SHAPE AS WELL AS HUE — the
     rotated diamond on `.badge.st-cmp` is the existing precedent to generalise.

     The `-ink` variants exist because --iri-1 (3.51) and --iri-3 (4.07) are
     MARK-ONLY in light: fine for a 1.4.11 mark, under the 4.5 floor for a coloured
     series LABEL. Where the mark already clears 4.5 the ink is the mark, declared
     rather than omitted so nobody reaches for --iri-2-ink and gets nothing. */
  --iri-1: #F7CB9C;  --iri-1-ink: #F7CB9C;
  --iri-2: #5286DD;  --iri-2-ink: #5286DD;
  --iri-3: #CDB3EF;  --iri-3-ink: #CDB3EF;
  --iri-4: #45B4C6;  --iri-4-ink: #45B4C6;
  --iri-5: #8C7FE8;  --iri-5-ink: #8C7FE8;
  /* --hero-bg follows the new dark base, exactly as the note beside its v2
     declaration says it must: it is the base colour, not an independent choice. */
  --hero-bg:    #08090E;
  --hero-ink:   #F5F5F3;
  --hero-ink-2: rgba(245,245,243,0.66);
}
