/* ============================================================
   Theme: phosphor-blueprint — product archetype, TOKEN VOCABULARY.

   This file is custom-property definitions and nothing else. No element
   selectors, no class selectors, no media queries, no @import. That is a
   contract, enforced by scripts/theme-doctor.py's
   check_token_css_declares_only_tokens(), not a convention — see below
   for why it has to be.

   ── Who reads it ──────────────────────────────────────────────────────
   1. conundrum.html and rororo-plugins.html LINK it, via the renderer-
      owned "theme-css" zone that scripts/render-hub.py repoints at the
      active theme on every run. Both pages used to carry a private :root
      copy of these values, which no monthly rotation could reach.
   2. scripts/render-plugin-pages.py CONCATENATES it after
      archetypes/product.css and inlines the result into the 15 generated
      product pages, so the vocabulary and the dress that spends it stay
      one artifact from those pages' point of view. After, not before:
      product.css opens with an @import, which CSS requires to lead the
      sheet. See that renderer's STYLE comment for the measurement.

   ── Why it is separate from product.css, which is the load-bearing part ─
   The two bespoke pages above are hand-authored. They keep their own
   layout: the approved spec says these pages RECOLOR monthly, they do not
   RE-LAYOUT. A token file is a recolor. product.css is an element dress —
   it styles `body`, `a`, `a:hover`, `h1, h2, h3`, `section.hero`, `.card`,
   `.btn`, `.brand img`, `footer` — written for markup
   render-plugin-pages.py owns.

   Linking that dress into a bespoke page and then neutralising it
   property-by-property was tried, measured, and rejected. It was the worst
   of both: the pages took every risk of the dress while eleven page-side
   neutralisers cancelled its benefit. It also shipped a live regression
   that no resting-state gate could see — `a:hover { text-decoration:
   underline }` at specificity (0,1,1) outranks `.merch-card`,
   `.shop-cta`, `.repo-cta` and `footer a`, so 14 links on the shop page
   and 18 on the marketplace page grew a magenta underline on hover that
   origin/main never had. A pixel harness samples the resting state; hover
   is out of frame by construction. The split closes that class of bug
   structurally rather than one neutraliser at a time, and the token-only
   gate is what keeps it closed for every future theme.

   ── What the values are ───────────────────────────────────────────────
   The two pages' rendering as shipped, drift and all — same posture
   archetypes/utility.css documents for press.html. The text ramp here is
   NOT product.css's --ink-* ramp: these pages run #ffffff / #c4cdda /
   #a4aebd / #99a4b4, matching archetypes/reading.css, where the generated
   pages run #e8eef7 / #c0cad8 / #a4afbf / #97a4b5. --fg-2 therefore
   derives through --text-sec and never through --ink-200, so the two
   ramps cannot cross-contaminate. Names this file shares with
   product.css's own :root (--cyan, --navy-deep, --r-md, …) carry
   product.css's exact values — all 11 of them, asserted by
   test_product_css_and_tokens_agree_on_every_shared_name — so the
   concatenation order cannot change what those 15 pages render.

   This block is COMPLETE against archetypes.REQUIRED_TOKENS, and
   scripts/theme-doctor.py enforces that on every theme. It has to be:
   neither linking page keeps a local fallback, so a name missing here is
   an unresolved var() on a live page, not a stale-but-valid color.

   That completeness is why the spacing scale appears even though neither
   page spends a single step of it. The theme OFFERS a scale; the pages
   decline it. Every padding, gap, and margin stays a literal in the page
   that owns its layout.
   ============================================================ */
:root {
  /* Palette — values shared with product.css's own :root, byte-for-byte. */
  --navy-deep: #0f1f31;
  --navy-mid:  #192e44;
  --navy-hi:   #223a54;
  --cyan:      #17d4fa;
  --cyan-pale: #5ce6ff;
  --magenta:   #f22f89;
  --magenta-pale: #ff66a8;
  --ink-950:   #050c18;
  --ok:        #2bd99a;

  --text:      #ffffff;
  --text-sec:  #c4cdda;
  --text-dim:  #a4aebd;
  --text-mute: #99a4b4;

  --bg-0: var(--navy-deep);
  --bg-1: var(--navy-mid);
  --bg-2: var(--navy-hi);
  --fg-1: var(--text);
  --fg-2: var(--text-sec);
  --fg-3: var(--text-dim);
  --fg-muted: var(--text-mute);

  --border-1: rgba(255,255,255,.08);
  --border-2: rgba(255,255,255,.14);
  --border-accent: rgba(23,212,250,.45);

  --brand-gradient: linear-gradient(135deg, var(--cyan) 0%, var(--magenta) 100%);
  --brand-gradient-soft: linear-gradient(135deg, rgba(23,212,250,.18) 0%, rgba(242,47,137,.18) 100%);
  --inner-stroke: inset 0 0 0 1px rgba(255,255,255,.06);
  --shadow-2: 0 4px 16px rgba(0,0,0,.45);

  --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px;
  --s-6: 24px; --s-8: 32px; --s-10: 40px; --s-12: 48px; --s-16: 64px;

  --r-xs: 4px; --r-sm: 6px; --r-md: 10px; --r-lg: 14px; --r-xl: 20px;
  --r-pill: 999px;

  --font-display: 'Space Grotesk', 'Inter', system-ui, sans-serif;
  --font-body:    'Inter', system-ui, -apple-system, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --ease-out: cubic-bezier(.2,.7,.2,1);
  --dur-fast: 120ms;
  --dur-med: 220ms;
}

/* ============================================================
   Phosphor Blueprint — treatment layer tokens (adopted 2026-07-07).

   These are THIS THEME's bespoke names, not base vocabulary, and they are
   deliberately NOT in archetypes.REQUIRED_TOKENS — the same documented
   posture press.html's var(--pb-field) and thesis.html/workflow.html's
   --pb-* reads already carry. They live here rather than in product.css
   because conundrum.html reads nine of them in its own treatment rules
   and links only this file. product.css's own treatment section spends
   the same names on its own selectors; both resolve from this one
   definition, so a theme changing the treatment changes it once.

   A theme built by mirroring themes/phosphor-blueprint/ (what the build
   instructions say to do) inherits these. One written from scratch has to
   define them or restyle conundrum.html's treatment block.
   ============================================================ */
:root {
  --pb-field: rgb(0,0,0);
  --pb-grid-fine: rgba(23,212,250,.05);
  --pb-grid-coarse: rgba(23,212,250,.11);
  --pb-scanline: rgba(0,0,0,.42);
  --pb-panel: rgba(0,0,0,.72);
  --pb-panel-border: rgba(23,212,250,.25);
  --pb-bloom-cyan: 0 0 14px rgba(23,212,250,.5);
  --pb-trail: 0 0 6px rgba(23,212,250,.9), 0 0 28px rgba(23,212,250,.5), 12px 0 24px rgba(23,212,250,.25);
  /* The treatment's hairline. This exact value was hardcoded on
     .card/.mini/.family-card in product.css; naming it is what lets a page
     that wears this treatment (conundrum.html) read it instead of copying
     the number into its own :root. */
  --pb-hairline: rgba(23,212,250,.14);
}
