/* ============================================================================
   GLEE DESIGN SYSTEM — v2 "Sovereign Precisionism"        (2026-08-19)
   ----------------------------------------------------------------------------
   WHAT THIS IS
   The site's visual language, taken from the 13 GLEE design boards in
   the GLEE design board set (Visual System Plan, Foundations, Shared
   Components, UI Component System, System Architecture, GLEE Local,
   gleephoenix.com,
   Truth+Authority, Object Model, Workflow+Navigation).

   The boards state one rule above all the others: ONE SYSTEM, TWO INTERFACES,
   ONE LANGUAGE. GLEE Local (private, operational) and gleephoenix.com (public,
   federated) are different scopes and different permissions, never a different
   look. This file is the shared half.

   HOW IT LOADS
   After glee-tokens.css, which it does not replace. glee-tokens.css still owns
   the token NAMES and the legacy aliases that 46 public pages resolve through;
   this file re-points those names at the board palette. That is the whole
   leverage: a page that already says var(--sand) or var(--panel) inherits the
   board language without being edited.

   Reversible: remove the <link> and every page reverts to the v1 BIOS canon.

   THE PALETTE IS MEASURED, NOT INVENTED
   Ground, surface and accent values were sampled from the board PNGs
   (dominant-colour and saturation-clustered), not eyeballed:
     canvas   #00080E   (art11 modal ground, 120,753 px) — SAMPLED, NOT SHIPPED:
                        Captain kept pure #000. See --gd-canvas below.
     card     #090D11   (art03 data-table panel, 3,861 px)
     accent   hue 24-47 warm gold, ~6,500 px in art11 — by a wide margin the
              single dominant accent in every board. Gold is authority, and the
              boards spend it sparingly.
   The seven semantic hues are the boards' own stated hexes (art03 §01).

   D-001 STILL HOLDS — COLOUR MAY NOT BE THE ONLY CHANNEL
   The 2026-08-18 audit found state encoded by hue alone on shipped surfaces.
   The boards independently reach the same rule: every status chip in art03 §04
   and art07 carries a glyph AND a word AND a colour. .gd-status enforces it —
   the glyph is a generated ::before, so a status cannot be authored without
   one, and the eight states are separated in luminance as well as hue.

   THE v1/v2 "PALETTE CONFLICT" WAS A NAMING DIFFERENCE
   The open question in scope glee-ui-design-system was: the shipped palette
   uses hue for CONTROL TYPE (gold focus / green action / teal move / lavender
   speculative / coral edit) while the boards use hue for STATE. Mapped by the
   job each variable actually does, they are the same system:
     --sand  focus/brand   -> Attention / Focus        var(--c-warn)
     --act   action/live   -> Success / Verified       var(--c-teal)   (SEE BELOW)
     --move  move/flow     -> Information / Flow       var(--c-link)
     --tab   speculative   -> Speculation / Discovery  var(--c-violet-soft)
     --util  edit/warn     -> Warning / Risk           var(--c-warn)
     --rose  stop          -> Danger / Fail            var(--c-danger)
     (new)                 -> Unknown / Uncertain      var(--c-slate)
   Six of the seven carry over cleanly, plus one state the v1 canon had no
   colour for at all.

   ONE OF THEM IS A HOMONYM, AND SAYING OTHERWISE WOULD BE THE EASY LIE
   --act is not one role. Measured across 191 uses: most are status
   (.st-live, .st-verified, .truthpill.live, .pill.g, .chip.good), but a
   handful are the fill of a primary button (.go, .button.primary, .route
   button, .ddetail .open, .mg-go). v1's one token was doing both "verified"
   and "go". The boards separate them — art04's semantic key reads
   "Success / Verified" for green and "Action / Authority" for gold, and
   art08 §07 draws the primary button in gold.
   Left as-is, a page shows a teal CTA sitting beside teal LIVE labels, and
   the reader cannot tell an action from a state. That is precisely the
   failure "Legibility is Power" names. So --act keeps the status meaning it
   mostly has, and the CTA half is repainted gold by the enumerated list in
   CONTROLS below. The list is short and named on purpose: it is the debt v1
   left, not a pattern to extend.
   ============================================================================ */

:root {
  /* ---- 1. TYPE: three voices, one system -------------------------------
     The boards are explicit: "Serif for Authority — titles, brand, statements,
     timeless, precise, stable" / "Sans for Clarity — interface, labels, data,
     clean, neutral, legible" / mono for data. v1 collapsed --sans into --mono,
     so every paragraph on the site rendered as terminal output. That single
     line is the largest reason the site does not look designed. Split back. */
  --gd-display: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --gd-ui: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --gd-data: ui-monospace, "Cascadia Code", "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;

  /* type scale — board art11 (48/56, 32/40, 20/28, 14/22, 12/18, 11/16),
     fluid between mobile and 1280 so the ratio survives both UVP viewports */
  --gd-h1: clamp(2.0rem, 1.30rem + 2.6vw, 3.0rem);   --gd-h1-lh: 1.14;
  --gd-h2: clamp(1.5rem, 1.15rem + 1.4vw, 2.0rem);   --gd-h2-lh: 1.22;
  --gd-h3: clamp(1.1rem, 0.98rem + 0.5vw, 1.25rem);  --gd-h3-lh: 1.38;
  --gd-body: 0.9375rem;  --gd-body-lh: 1.62;
  --gd-small: 0.8125rem; --gd-small-lh: 1.52;
  --gd-micro: 0.6875rem; --gd-micro-lh: 1.45;
  --gd-eyebrow-ls: .16em;

  /* ---- 2. SURFACE LADDER (sampled from the boards) ---------------------
     "Calm surfaces with depth and intention." Deep canvas has low reflect;
     each step up is a small, even lift. Edges are lines, not boxes. */
  /* CAPTAIN 2026-08-19: "i prefer the black". His 2026-07-21 call stands —
     pure var(--c-ink) ground, never blue-tinted. The boards' measured canvas was
     #00080E and I had followed the artwork; asked, and the earlier ruling wins.
     Everything else from the boards is unchanged: the three type voices, gold
     as authority, the seven semantic hues, the mark, the status language.
     The lift steps above the ground stay, because a card still has to separate
     itself from the canvas — they just start from true black now. */
  --gd-canvas:  #000000;
  --gd-deep:    #05080B;
  --gd-panel:   #090F14;
  --gd-card:    #0D141A;
  --gd-raised:  #121A21;
  --gd-hairline:      #1C252C;
  --gd-hairline-soft: #141C22;
  --gd-hairline-gold: rgba(201, 169, 107, .26);

  /* ---- 3. INK LADDER — cool bone, matching the boards' cool ground ---- */
  --gd-ink:    #E9E7E2;
  --gd-ink-2:  #BAC1C9;
  /* faint was var(--c-muted-2) and muted var(--c-slate). Measured on the render, the 10.9px
     hint line on the home and opener surfaces came out at 4.22:1 and 3.83:1 —
     under AA for body text. Raising faint alone would have collapsed it into
     muted, so both step up together and the ladder keeps a real interval.
     Solved against the background luminance implied by the measured ratios,
     not picked by eye: faint clears 5.00 / 4.54. */
  --gd-muted:  #98A2AE;
  --gd-faint:  #859099;

  /* ---- 4. GOLD — authority accent, spent sparingly -------------------- */
  --gd-gold-hi:  #E4CFA1;
  --gd-gold:     #C9A96B;
  --gd-gold-dim: #8C6A3F;

  /* ---- 5. SEMANTIC HUES — board art03 §01, verbatim -------------------
     All seven clear AA body contrast (>=4.5:1) on both --gd-canvas and
     --gd-card; measured, not assumed. Accents communicate state. They never
     decorate, and they are never the only channel. */
  --gd-success: #3ECFB6;   /* Success / Verified      */
  --gd-focus:   #F5B74E;   /* Attention / Focus       */
  --gd-warning: #F59C42;   /* Warning / Risk          */
  --gd-danger:  #E15A5A;   /* Danger / Fail           */
  --gd-info:    #4A8CFF;   /* Information / Flow      */
  --gd-spec:    #A86CFF;   /* Speculation / Discovery */
  --gd-unknown: #7A7FB7;   /* Unknown / Uncertain     */

  /* tinted grounds, sampled from the board badges (var(--c-ink-2) pass, var(--c-ink-2) fail) */
  --gd-success-bg: rgba(62, 207, 182, .09);
  --gd-focus-bg:   rgba(245, 183, 78, .10);
  --gd-warning-bg: rgba(245, 156, 66, .10);
  --gd-danger-bg:  rgba(225, 90, 90, .11);
  --gd-info-bg:    rgba(74, 140, 255, .10);
  --gd-spec-bg:    rgba(168, 108, 255, .10);
  --gd-unknown-bg: rgba(122, 127, 183, .11);

  /* ---- 6. SPACE — 8pt grid (board art11 "consistent grid, 8pt system") - */
  --gd-1: 4px;  --gd-2: 8px;  --gd-3: 12px; --gd-4: 16px;
  --gd-5: 24px; --gd-6: 32px; --gd-7: 48px; --gd-8: 64px; --gd-9: 96px;
  --gd-radius:    10px;
  --gd-radius-sm: 6px;
  --gd-measure:   68ch;

  /* ---- 7. MOTION — "movement communicates real system activity" -------
     Board art11 motion language: enter = soft fade + slight rise; update =
     subtle cross-fade; transfer = directional slide; progress = linear steady;
     complete = settle + affirm; alert = pulse + draw focus. */
  --gd-ease:      cubic-bezier(.22, .61, .36, 1);
  --gd-ease-out:  cubic-bezier(.16, 1, .3, 1);
  --gd-t-fast: 140ms;
  --gd-t-base: 220ms;
  --gd-t-slow: 420ms;

  --gd-shadow-card:   0 1px 0 rgba(255,255,255,.03) inset, 0 12px 30px -18px rgba(0,0,0,.9);
  --gd-shadow-raised: 0 1px 0 rgba(255,255,255,.04) inset, 0 22px 48px -22px rgba(0,0,0,.95);

  /* ======================================================================
     REMAP: the v1 token names, re-pointed at the board language.
     This is what carries the whole site over without touching 46 pages.
     ====================================================================== */
  --mono:  var(--gd-data);
  --serif: var(--gd-display);
  --sans:  var(--gd-ui);            /* was: var(--mono) — the collapse, undone */

  --bg:     var(--gd-canvas);
  --panel:  var(--gd-panel);
  --panel2: var(--gd-card);
  --surf:   var(--gd-panel);
  --line:   var(--gd-hairline);
  --edge:   var(--gd-hairline);
  --edge2:  #26313A;

  --ink:   var(--gd-ink);
  --mist:  var(--gd-ink-2);
  --muted: var(--gd-muted);
  --faint: var(--gd-faint);

  --sand:    var(--gd-gold);      --sand-hi: var(--gd-gold-hi);
  --act:     var(--gd-success);   /* action / go / live / verified */
  --move:    var(--gd-info);      /* move / navigation / route-flow */
  --tab:     var(--gd-spec);      /* dream / speculative */
  --util:    var(--gd-warning);   /* edit / warn */
  --num:     var(--gd-gold);
  --rose:    var(--gd-danger);
  --amber:   var(--gd-focus);

  --gold:        var(--gd-gold);
  --green:       var(--gd-success);
  --blue:        var(--gd-info);
  --violet:      var(--gd-spec);
  --violet-soft: #BC93FF;
  --bone-hi:     #F3F1EC;
  --rose-soft:   #F07B76;
  --ground-deep: var(--gd-canvas);
  --ink-on-act:  #00201B;
  --line-cool:   var(--gd-hairline);
  --red:         var(--gd-danger);

  --text: var(--gd-ink);
  --text-soft: var(--gd-ink-2);
  --void: var(--gd-canvas);
  --graphite: var(--gd-panel);
  --surface: var(--gd-panel);
  --amber-hot: var(--gd-gold-hi);
  --accent: var(--gd-gold);
  --accent2: var(--gd-info);
  --page-accent: var(--gd-gold);
  --page-accent-2: var(--gd-info);

  --glee-bg: var(--gd-canvas);
  --glee-bg-paper: var(--gd-panel);
  --glee-void-black: var(--gd-canvas);
  --glee-graphite-steel: var(--gd-panel);
  --glee-canvas-bg: var(--gd-canvas);
  --glee-forged-gray: var(--gd-hairline);
  --glee-line: var(--gd-hairline);
  --glee-gold: var(--gd-gold);
  --glee-gold-dim: var(--gd-gold-dim);
  --glee-gold-sem: var(--gd-gold);
  --glee-amber: var(--gd-focus);
  --glee-receipt-amber: var(--gd-focus);
  --glee-green: var(--gd-success);
  --glee-verified-green: var(--gd-success);
  --glee-blue: var(--gd-info);
  --glee-intelligence-blue: var(--gd-info);
  --glee-purple: var(--gd-spec);
  --glee-speculative-violet: var(--gd-spec);
  --glee-red: var(--gd-danger);
  --glee-hard-stop-red: var(--gd-danger);
  --glee-bone: var(--gd-ink);
  --glee-bone-white: var(--gd-ink);
}

/* keep-list pages scope their tokens to the body, so re-declare at that
   selector — same reason glee-tokens.css does. */
body.glee-visual-site {
  --vs-bg: var(--gd-canvas);
  --vs-panel: rgba(9, 15, 20, .90);
  --vs-panel-strong: rgba(13, 20, 26, .96);
  --vs-line: var(--gd-hairline-gold);
  --vs-line-soft: rgba(233, 231, 226, .10);
  --vs-text: var(--gd-ink);
  --vs-dim: var(--gd-ink-2);
  --vs-muted: var(--gd-muted);
  --vs-accent: var(--gd-gold);
  --vs-accent-2: var(--gd-info);
  --vs-safe: var(--gd-success);
  --vs-grid: rgba(233, 231, 226, .028);
}

/* ============================================================================
   BASE
   ============================================================================ */

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

body {
  background: var(--gd-canvas);
  color: var(--gd-ink);
  /* "Minimal noise — quiet textures." A near-invisible 8pt field plus a soft
     overhead light, so the deep ground reads as a surface and not as a void.
     Both are fixed and non-scrolling; neither is a page element. */
  background-image:
    radial-gradient(90rem 50rem at 50% -18%, rgba(201, 169, 107, .040), transparent 62%),
    linear-gradient(rgba(233, 231, 226, .009) 1px, transparent 1px),
    linear-gradient(90deg, rgba(233, 231, 226, .009) 1px, transparent 1px);
  background-size: 100% 100%, 64px 64px, 64px 64px;
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

::selection { background: rgba(201, 169, 107, .26); color: var(--gd-ink); }

:where(a, button, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--gd-focus);
  outline-offset: 2px;
  border-radius: var(--radius-2);
}

* { scrollbar-width: thin; scrollbar-color: var(--gd-hairline) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--gd-hairline); border-radius: var(--radius-8); border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--c-surface-3); background-clip: content-box; }

/* ============================================================================
   TYPE — "Legibility is Power. Clarity before cleverness."
   Body copy moves off monospace onto the UI sans. Data, IDs, hashes, receipts
   and terminal output stay monospace, because there the character grid IS the
   information. Display headings stay serif: authority.
   ============================================================================ */

body, p, li, dd, blockquote, figcaption, label, input, textarea, select, button {
  font-family: var(--gd-ui);
}

p, li, dd {
  font-size: var(--gd-body);
  line-height: var(--gd-body-lh);
  color: var(--gd-ink-2);
}
p { max-width: var(--gd-measure); }

h1, h2, h3, .gd-display {
  font-family: var(--gd-display);
  font-weight: 500;
  letter-spacing: -.01em;
  color: var(--gd-ink);
  text-wrap: balance;
}
h1, .gd-h1 { font-size: var(--gd-h1); line-height: var(--gd-h1-lh); }
h2, .gd-h2 { font-size: var(--gd-h2); line-height: var(--gd-h2-lh); }
h3, .gd-h3 { font-size: var(--gd-h3); line-height: var(--gd-h3-lh); font-family: var(--gd-ui); font-weight: 600; letter-spacing: 0; }

h4, h5, h6 {
  font-family: var(--gd-ui);
  font-weight: 600;
  color: var(--gd-ink);
  letter-spacing: 0;
}

/* the gold display line — the one place the site speaks in the brand voice */
.gd-lede, .promise {
  font-family: var(--gd-display);
  color: var(--gd-gold-hi);
  font-size: var(--gd-h2);
  line-height: 1.3;
  max-width: 34ch;
}

/* eyebrow / section label — uppercase, tracked, small. Never gold by default;
   gold is authority, and a section label is not an authority claim. */
.gd-eyebrow, .intent-label, .glee-eyebrow {
  font-family: var(--gd-ui);
  font-size: var(--gd-micro);
  letter-spacing: var(--gd-eyebrow-ls);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--gd-muted);
}

code, kbd, samp, pre, .gd-data, .mono,
[class*="hash"], [class*="receipt-id"], [class*="-id"], time {
  font-family: var(--gd-data);
  font-variant-numeric: tabular-nums;
}
code, kbd, samp {
  font-size: var(--text-14);
  background: var(--gd-panel);
  border: 1px solid var(--gd-hairline-soft);
  border-radius: var(--radius-2);
  padding: var(--space-2) var(--space-8);
  color: var(--gd-ink-2);
}
pre {
  background: var(--gd-panel);
  border: 1px solid var(--gd-hairline);
  border-radius: var(--gd-radius-sm);
  padding: var(--gd-4);
  overflow-x: auto;
  font-size: var(--gd-small);
  line-height: 1.6;
}
pre code { background: none; border: 0; padding: 0; }

/* numbers are data: tabular everywhere so columns line up */
.ledger-value, .gd-metric, [class*="stat"] strong, [class*="metric"] strong {
  font-family: var(--gd-data);
  font-variant-numeric: tabular-nums;
}

a { color: var(--gd-gold-hi); text-underline-offset: .18em; text-decoration-thickness: 1px; }
a:hover { color: var(--gd-gold); }

hr { border: 0; border-top: 1px solid var(--gd-hairline); margin: var(--gd-6) 0; }

/* ============================================================================
   THE MARK — sacred geometry replaces the placeholder diamond
   The nav brand is authored as `<a class="gbrand"><i>◆</i> GLEE</a>` on 31
   pages. Rather than rewrite 31 files, the glyph is swapped in place: the
   character is hidden and the mark is painted as a mask, so it inherits
   currentColor and stays crisp at any size.
   ============================================================================ */
.gbrand i,
.gw-bar .gw-brand::before {
  display: inline-block;
  /* Sized in rem, NOT em: the ◆ underneath is hidden with font-size:0, and an
     em box on a zero font-size collapses the mark to nothing. Measured — the
     first cut of this rule shipped an invisible brand on all 31 nav pages. */
  width: var(--text-20);
  height: 1.4rem;
  vertical-align: -.32rem;
  color: var(--gd-gold);
  background-color: currentColor;
  /* small-size cut: the full mark closes up below ~40px. See glee-mark-sm.svg. */
  -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%20role%3D%22img%22%20aria-label%3D%22GLEE%22%3E%20%3Cg%20stroke%3D%22currentColor%22%20fill%3D%22none%22%20stroke-linejoin%3D%22miter%22%3E%20%3Ccircle%20cx%3D%2216%22%20cy%3D%2216%22%20r%3D%2214.4%22%20stroke-width%3D%221.9%22%2F%3E%20%3Crect%20x%3D%225.4%22%20y%3D%225.4%22%20width%3D%2221.2%22%20height%3D%2221.2%22%20stroke-width%3D%221.7%22%2F%3E%20%3Crect%20x%3D%225.4%22%20y%3D%225.4%22%20width%3D%2221.2%22%20height%3D%2221.2%22%20stroke-width%3D%221.7%22%20transform%3D%22rotate%2845%2016%2016%29%22%2F%3E%20%3C%2Fg%3E%20%3Ccircle%20cx%3D%2216%22%20cy%3D%2216%22%20r%3D%222.9%22%20fill%3D%22currentColor%22%2F%3E%20%3C%2Fsvg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%20role%3D%22img%22%20aria-label%3D%22GLEE%22%3E%20%3Cg%20stroke%3D%22currentColor%22%20fill%3D%22none%22%20stroke-linejoin%3D%22miter%22%3E%20%3Ccircle%20cx%3D%2216%22%20cy%3D%2216%22%20r%3D%2214.4%22%20stroke-width%3D%221.9%22%2F%3E%20%3Crect%20x%3D%225.4%22%20y%3D%225.4%22%20width%3D%2221.2%22%20height%3D%2221.2%22%20stroke-width%3D%221.7%22%2F%3E%20%3Crect%20x%3D%225.4%22%20y%3D%225.4%22%20width%3D%2221.2%22%20height%3D%2221.2%22%20stroke-width%3D%221.7%22%20transform%3D%22rotate%2845%2016%2016%29%22%2F%3E%20%3C%2Fg%3E%20%3Ccircle%20cx%3D%2216%22%20cy%3D%2216%22%20r%3D%222.9%22%20fill%3D%22currentColor%22%2F%3E%20%3C%2Fsvg%3E") no-repeat center / contain;
  font-size: 0;
  margin-right: var(--space-4);
  transition: transform var(--gd-t-slow) var(--gd-ease-out), color var(--gd-t-base) var(--gd-ease);
}
.gw-bar .gw-brand::before { content: ""; }
.gbrand:hover i,
.gw-bar .gw-brand:hover::before { color: var(--gd-gold-hi); transform: rotate(45deg); }

.gbrand {
  font-family: var(--gd-display);
  font-size: var(--text-16);
  letter-spacing: .28em;
  font-weight: 500;
  text-transform: uppercase;
}

/* ============================================================================
   NAV + TRAIL — same shell, board surfacing
   ============================================================================ */
.gnav {
  background: color-mix(in srgb, var(--gd-canvas) 82%, transparent);
  backdrop-filter: blur(14px) saturate(120%);
  border-bottom: 1px solid var(--gd-hairline);
}
.gnav-in { min-height: 58px; }
.ggrp > summary, .gw-nav > a, .gw-more > summary {
  font-family: var(--gd-ui);
  font-size: var(--gd-micro);
  letter-spacing: .14em;
  font-weight: 600;
}
.ggrp > summary:hover, .gw-nav > a:hover { background: rgba(201, 169, 107, .07); }
.gtrail {
  font-family: var(--gd-ui);
  font-size: var(--gd-micro);
  letter-spacing: .06em;
  border-bottom: 1px solid var(--gd-hairline-soft);
  /* Opaque, not tinted: the homepage runs a full-bleed character-rain canvas
     behind the chrome, and a translucent trail let stray glyphs bleed through
     the breadcrumb at 390px. Chrome sits ON the page, never in it. */
  background: var(--gd-deep);
}

/* ============================================================================
   SURFACES — "Edge definition: lines, not boxes."
   Applied to the card shapes the site already authors, so existing pages gain
   depth without new markup.
   ============================================================================ */
.gd-card, .intent-card, .ledger-strip, .glee-card,
[class$="-card"]:not([class*="agent"]):not([class*="seat"]) {
  background: var(--gd-card);
  border: 1px solid var(--gd-hairline);
  border-radius: var(--gd-radius);
  box-shadow: var(--gd-shadow-card);
}

.gd-card {
  padding: var(--gd-5);
  transition: border-color var(--gd-t-base) var(--gd-ease),
              transform var(--gd-t-base) var(--gd-ease-out),
              box-shadow var(--gd-t-base) var(--gd-ease);
}
a.gd-card, .gd-card--link { display: block; text-decoration: none; color: inherit; }
a.gd-card:hover, .gd-card--link:hover, .intent-card:hover {
  border-color: var(--gd-hairline-gold);
  box-shadow: var(--gd-shadow-raised);
  transform: translateY(-2px);
}

.gd-panel {
  background: var(--gd-panel);
  border: 1px solid var(--gd-hairline);
  border-radius: var(--gd-radius);
  padding: var(--gd-5);
}

/* object header — board art08 §05: mark, title, status, meta line */
.gd-object-head {
  display: flex; align-items: flex-start; gap: var(--gd-3);
  padding-bottom: var(--gd-4);
  border-bottom: 1px solid var(--gd-hairline);
  margin-bottom: var(--gd-5);
}
.gd-object-head h1, .gd-object-head h2 { margin: 0; }
.gd-object-head .gd-meta { margin-top: var(--gd-1); }
.gd-meta {
  font-family: var(--gd-ui);
  font-size: var(--gd-small);
  color: var(--gd-muted);
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--gd-2);
}
.gd-meta > * + *::before { content: "·"; margin-right: var(--gd-2); color: var(--gd-faint); }

/* ============================================================================
   STATUS — the universal state language (board art07)
   Eight states. Each is colour + GLYPH + WORD, never colour alone: the glyph is
   a generated ::before, so the channel cannot be dropped by an author who only
   sets a class. Luminance is separated too, so the set survives greyscale.
   ============================================================================ */
.gd-status {
  display: inline-flex; align-items: center; gap: var(--space-8);
  /* inline-flex is not enough on its own: as a child of a flex column or a grid
     cell, the default stretch alignment makes the chip span the full cross-axis
     and it renders as a full-width bar. Caught on projects/tree, the component's
     first real caller — which is the argument for giving a component a caller
     before calling it done. */
  align-self: flex-start;
  justify-self: start;
  width: fit-content;
  max-width: 100%;
  font-family: var(--gd-ui);
  font-size: var(--gd-micro);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: var(--space-4) var(--space-12) var(--space-4) var(--space-8);
  border-radius: var(--radius-pill);
  border: 1px solid currentColor;
  white-space: nowrap;
  line-height: 1.4;
}
.gd-status::before { font-size: var(--text-16); line-height: 1; font-weight: 400; }

/* Glyphs are chosen for legibility at 11px, which is the size a status chip
   actually renders at — not for how they look in a specimen. Rendered all
   candidates in the three live font stacks and looked: ⦸ ⊘ ∅ ⛨ are present in
   every stack but draw at roughly half the optical size of the solid forms, so
   at chip size they read as a smudge or a box. The set below is solid shapes,
   a check, a cross and a question mark — each unmistakable at 11px and each
   distinct in silhouette, not just in hue. */
.gd-status--pass,     .gd-status--verified { color: var(--gd-success); background: var(--gd-success-bg); }
.gd-status--pass::before     { content: "✓"; }
.gd-status--verified::before { content: "✔"; }
.gd-status--working   { color: var(--gd-info);    background: var(--gd-info-bg); }
.gd-status--working::before  { content: "◐"; }
.gd-status--fail      { color: var(--gd-danger);  background: var(--gd-danger-bg); }
.gd-status--fail::before     { content: "✖"; }
.gd-status--blocked   { color: var(--gd-warning); background: var(--gd-warning-bg); }
.gd-status--blocked::before  { content: "■"; }
.gd-status--proposed  { color: var(--gd-spec);    background: var(--gd-spec-bg); }
.gd-status--proposed::before { content: "◇"; }
.gd-status--unknown   { color: var(--gd-unknown); background: var(--gd-unknown-bg); }
.gd-status--unknown::before  { content: "?"; }
.gd-status--historical { color: var(--gd-faint);  background: rgba(120, 131, 143, .10); }
.gd-status--historical::before { content: "●"; }

/* the site already authors bare state words in several places; give them the
   same shape without requiring new markup */
.badge, .chip, .pill {
  font-family: var(--gd-ui);
  font-size: var(--gd-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 600;
  border-radius: var(--radius-pill);
  border: 1px solid var(--gd-hairline);
  padding: var(--space-4) var(--space-12);
  color: var(--gd-ink-2);
}

/* --- D-001: the glyph channel, on surfaces that already shipped -----------
   CORRECTION TO MY FIRST CUT. That version said this "adds the missing second
   channel" and applied glyphs to the Bridge .st-* pills too. Both halves were
   wrong, and looking at the render is what showed it.

   Wrong claim: these public surfaces were not hue-only. `<span class="status">
   Live</span>` and the Bridge pills both print the state WORD, so text+colour
   was already two channels — D-001 was satisfied here before I arrived. The
   2026-08-18 hue-only finding was against command_deck.html, a different
   surface. What this adds is the THIRD channel the boards specify (art07:
   colour AND glyph AND word), not a missing second one.

   Wrong change: the Bridge pills already carry a leading dot, so the glyph
   made them read "◐ ● BUILDING" — two marks and a word in a small pill. That
   is clutter bought with no legibility, so .st-* is left alone. The card
   status labels have no glyph of their own and gain a clean one.

   Anything authored from here uses .gd-status, which enforces all three.

   STATUS 2026-08-19: both known callers of this rule — projects/index.html and
   projects/tree/index.html — were migrated to .gd-status, so this is now a
   fallback for surfaces not yet migrated rather than the live path. Kept, not
   deleted: 12 files still contain a `class="status` somewhere (form messages and
   game HUDs among them), and I did not exhaustively prove none of them is a
   card-context state label. Deleting on an unproven absence is how the
   `_missing_markers` regression happened one directory over. */
:is(.card, a.card) > .status::before {
  margin-right: var(--space-8);
  font-weight: 400;
  display: inline-block;
}
:is(.card, a.card) > .status::before          { content: "\2713"; }   /* live     */
:is(.card, a.card) > .status.soft::before     { content: "\25D0"; }   /* building */
:is(.card, a.card) > .status.research::before { content: "\25C7"; }   /* research */

/* ============================================================================
   CONTROLS — board art08 §07/§09
   Primary = the ordinary forward action. Authority = an action that needs
   consent; it is deliberately heavier, because the boards put human authority
   first and an irreversible action should not look like a link.
   ============================================================================ */
.gd-btn, .gd-btn:link, .gd-btn:visited {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-8);
  font-family: var(--gd-ui);
  font-size: var(--gd-small);
  font-weight: 600;
  letter-spacing: .02em;
  padding: var(--space-8) var(--space-16);
  border-radius: var(--gd-radius-sm);
  border: 1px solid var(--gd-hairline);
  background: var(--gd-raised);
  color: var(--gd-ink);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--gd-t-fast) var(--gd-ease),
              border-color var(--gd-t-fast) var(--gd-ease),
              transform var(--gd-t-fast) var(--gd-ease);
}
.gd-btn:hover { background: #182129; border-color: #2C3945; }
.gd-btn:active { transform: translateY(1px); }

.gd-btn--primary {
  background: linear-gradient(180deg, #D8BC85, #C9A96B);
  border-color: #D8BC85;
  color: #1A1305;
  font-weight: 700;
}
.gd-btn--primary:hover { background: linear-gradient(180deg, #E4CFA1, #D4B77C); border-color: #E4CFA1; }

.gd-btn--authority {
  background: var(--gd-focus-bg);
  border-color: var(--gd-focus);
  color: var(--gd-focus);
}
.gd-btn--authority::before { content: "⛨"; font-weight: 400; }
.gd-btn--authority:hover { background: rgba(245, 183, 78, .17); }

.gd-btn--ghost { background: transparent; border-color: transparent; color: var(--gd-ink-2); }
.gd-btn--ghost:hover { background: rgba(233, 231, 226, .05); color: var(--gd-ink); }

/* --- the --act homonym, resolved (see the header note) --------------------
   These six selectors are every non-game primary CTA on the live site that
   fills with var(--act) or var(--green). They are enumerated rather than
   matched by pattern because CSS cannot select "element whose background
   resolves to this token", and because an explicit list is auditable: if a
   new CTA appears and is not here, it stays teal and the drift is visible.
   Verified by sweep 2026-08-19 over 46 surfaces; games are excluded, their
   interiors are deliberately their own. */
.go,
.button.primary,
.route button,
.ddetail .open,
.mobile-gate .mg-go,
a.open {
  background: linear-gradient(180deg, #D8BC85, #C9A96B) !important;
  border-color: #D8BC85 !important;
  color: #1A1305 !important;
}
.go:hover,
.button.primary:hover,
.route button:hover,
.ddetail .open:hover,
.mobile-gate .mg-go:hover,
a.open:hover {
  background: linear-gradient(180deg, #E4CFA1, #D4B77C) !important;
  border-color: #E4CFA1 !important;
}

.gd-btn[disabled], .gd-btn--disabled {
  opacity: .45; cursor: not-allowed; transform: none;
  background: var(--gd-panel); border-color: var(--gd-hairline); color: var(--gd-muted);
}

/* ============================================================================
   LISTS + TABLES — board art03 §09
   ============================================================================ */
.gd-table { width: 100%; border-collapse: collapse; font-size: var(--gd-small); }
.gd-table th {
  font-family: var(--gd-ui);
  font-size: var(--gd-micro);
  letter-spacing: .12em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--gd-muted);
  text-align: left;
  padding: var(--gd-2) var(--gd-3);
  border-bottom: 1px solid var(--gd-hairline);
}
.gd-table td {
  padding: var(--gd-3);
  border-bottom: 1px solid var(--gd-hairline-soft);
  color: var(--gd-ink-2);
  vertical-align: middle;
}
.gd-table tbody tr { transition: background var(--gd-t-fast) var(--gd-ease); }
.gd-table tbody tr:hover { background: rgba(233, 231, 226, .022); }
.gd-table td:where([class*="id"], [class*="hash"], [class*="time"]) { font-family: var(--gd-data); }

/* ============================================================================
   EMPTY + ALERT — board art03 §16 / §13
   An empty state says what would be here and how to get it. It never reads as
   a failure, because "no results" and "lookup failed" are different facts.
   ============================================================================ */
.gd-empty {
  text-align: center;
  padding: var(--gd-8) var(--gd-5);
  border: 1px dashed var(--gd-hairline);
  border-radius: var(--gd-radius);
  color: var(--gd-muted);
}
.gd-empty::before {
  content: "";
  display: block; width: 44px; height: 44px; margin: 0 auto var(--gd-4);
  background-color: var(--gd-hairline);
  -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%20fill%3D%22none%22%20role%3D%22img%22%20aria-label%3D%22GLEE%22%3E%20%3Cg%20stroke%3D%22currentColor%22%20fill%3D%22none%22%20stroke-linejoin%3D%22miter%22%3E%20%3Ccircle%20cx%3D%2232%22%20cy%3D%2232%22%20r%3D%2229%22%20stroke-width%3D%222.6%22%2F%3E%20%3Crect%20x%3D%2211.5%22%20y%3D%2211.5%22%20width%3D%2241%22%20height%3D%2241%22%20stroke-width%3D%222.4%22%2F%3E%20%3Crect%20x%3D%2211.5%22%20y%3D%2211.5%22%20width%3D%2241%22%20height%3D%2241%22%20stroke-width%3D%222.4%22%20transform%3D%22rotate%2845%2032%2032%29%22%2F%3E%20%3Ccircle%20cx%3D%2232%22%20cy%3D%2232%22%20r%3D%2211%22%20stroke-width%3D%222.2%22%2F%3E%20%3C%2Fg%3E%20%3Ccircle%20cx%3D%2232%22%20cy%3D%2232%22%20r%3D%224.2%22%20fill%3D%22currentColor%22%2F%3E%20%3C%2Fsvg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%20fill%3D%22none%22%20role%3D%22img%22%20aria-label%3D%22GLEE%22%3E%20%3Cg%20stroke%3D%22currentColor%22%20fill%3D%22none%22%20stroke-linejoin%3D%22miter%22%3E%20%3Ccircle%20cx%3D%2232%22%20cy%3D%2232%22%20r%3D%2229%22%20stroke-width%3D%222.6%22%2F%3E%20%3Crect%20x%3D%2211.5%22%20y%3D%2211.5%22%20width%3D%2241%22%20height%3D%2241%22%20stroke-width%3D%222.4%22%2F%3E%20%3Crect%20x%3D%2211.5%22%20y%3D%2211.5%22%20width%3D%2241%22%20height%3D%2241%22%20stroke-width%3D%222.4%22%20transform%3D%22rotate%2845%2032%2032%29%22%2F%3E%20%3Ccircle%20cx%3D%2232%22%20cy%3D%2232%22%20r%3D%2211%22%20stroke-width%3D%222.2%22%2F%3E%20%3C%2Fg%3E%20%3Ccircle%20cx%3D%2232%22%20cy%3D%2232%22%20r%3D%224.2%22%20fill%3D%22currentColor%22%2F%3E%20%3C%2Fsvg%3E") no-repeat center / contain;
}

.gd-alert {
  display: flex; gap: var(--gd-3); align-items: flex-start;
  padding: var(--gd-3) var(--gd-4);
  border: 1px solid var(--gd-hairline);
  border-left-width: 3px;
  border-radius: var(--gd-radius-sm);
  background: var(--gd-panel);
  font-size: var(--gd-small);
  color: var(--gd-ink-2);
}
.gd-alert--warning { border-left-color: var(--gd-warning); }
.gd-alert--danger  { border-left-color: var(--gd-danger); }
.gd-alert--info    { border-left-color: var(--gd-info); }
.gd-alert--success { border-left-color: var(--gd-success); }

/* ============================================================================
   HOME SURFACE — the front door, where the language has to land first
   Two fixes, both read off the render at 1280x800 rather than off the source.
   ============================================================================ */

/* 1. The terminal pane scrolls (457px of viewport over 2,411px of content) but
   showed no affordance, so content was severed mid-glyph at a hard edge and
   the page read as broken rather than as scrollable. A short bottom fade says
   "continues below" — progressive disclosure, board art11. Kept to 30px so at
   scroll-end only the last sliver softens. */
.glee-term[data-convo] > .glee-body > .glee-pane.on {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 30px), transparent 100%);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 30px), transparent 100%);
}
/* the pane is the one place a scrollbar is load-bearing: make it visible */
.glee-term[data-convo] > .glee-body > .glee-pane.on::-webkit-scrollbar-thumb {
  background: #33414D; background-clip: content-box;
}

/* 2. The dock's topic keys were browser-default buttons crowded onto the
   bottom edge in two ragged rows. Same chip shape as the rest of the system,
   with the shortcut number as data (mono, gold) and the label as UI text. */
.dock { padding-top: var(--gd-3); border-top: 1px solid var(--gd-hairline); }
#doors.files { display: flex; flex-wrap: wrap; gap: var(--gd-2); }
#doors .fbtn {
  display: inline-flex; align-items: center; gap: var(--space-8);
  padding: var(--space-8) var(--space-12);
  background: var(--gd-panel);
  border: 1px solid var(--gd-hairline);
  border-radius: var(--radius-pill);
  color: var(--gd-ink-2);
  font-family: var(--gd-ui);
  font-size: var(--gd-small);
  line-height: 1.3;
  cursor: pointer;
  transition: border-color var(--gd-t-fast) var(--gd-ease),
              background var(--gd-t-fast) var(--gd-ease),
              transform var(--gd-t-fast) var(--gd-ease);
}
#doors .fbtn:hover {
  background: var(--gd-raised);
  border-color: var(--gd-hairline-gold);
  color: var(--gd-ink);
  transform: translateY(-1px);
}
#doors .fbtn > .n {
  font-family: var(--gd-data);
  font-size: var(--gd-micro);
  color: var(--gd-gold);
  min-width: 1.1em;
  text-align: center;
  opacity: .85;
}

/* ============================================================================
   GLEE LOCAL — the second interface
   "One system, two interfaces, one language" is the boards' first claim, and
   until this file it was true of the public site only: the palette sweep
   measured 3 of 4 GLEE Local surfaces off-canon. The same sheet is symlinked
   into glee_pkg/dashboard/glee-dashboard/static, which carries the ground,
   ink ladder and type voices across by itself.

   What it could NOT carry are the accents those pages hard-code rather than
   tokenise — a Tailwind sky/indigo wordmark gradient and a Tailwind emerald
   action button, neither of which exists anywhere in the board palette. A
   remap cannot reach a literal, so they are named here. Captain reads this
   desk daily; a private surface being private is not a licence for it to be
   a different product.
   ============================================================================ */

/* the wordmark: sky-to-indigo gradient -> the brand's own gold + the mark */
.brand-logo {
  background: none !important;
  -webkit-background-clip: border-box !important;
  -webkit-text-fill-color: currentColor !important;
  color: var(--gd-gold) !important;
  font-family: var(--gd-display) !important;
  font-weight: 500 !important;
  letter-spacing: .26em !important;
  display: inline-flex;
  align-items: center;
}
.brand-logo::before {
  content: "";
  display: inline-block;
  width: 1.35rem; height: 1.35rem;
  margin-right: var(--space-8);
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%20role%3D%22img%22%20aria-label%3D%22GLEE%22%3E%20%3Cg%20stroke%3D%22currentColor%22%20fill%3D%22none%22%20stroke-linejoin%3D%22miter%22%3E%20%3Ccircle%20cx%3D%2216%22%20cy%3D%2216%22%20r%3D%2214.4%22%20stroke-width%3D%221.9%22%2F%3E%20%3Crect%20x%3D%225.4%22%20y%3D%225.4%22%20width%3D%2221.2%22%20height%3D%2221.2%22%20stroke-width%3D%221.7%22%2F%3E%20%3Crect%20x%3D%225.4%22%20y%3D%225.4%22%20width%3D%2221.2%22%20height%3D%2221.2%22%20stroke-width%3D%221.7%22%20transform%3D%22rotate%2845%2016%2016%29%22%2F%3E%20%3C%2Fg%3E%20%3Ccircle%20cx%3D%2216%22%20cy%3D%2216%22%20r%3D%222.9%22%20fill%3D%22currentColor%22%2F%3E%20%3C%2Fsvg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%20role%3D%22img%22%20aria-label%3D%22GLEE%22%3E%20%3Cg%20stroke%3D%22currentColor%22%20fill%3D%22none%22%20stroke-linejoin%3D%22miter%22%3E%20%3Ccircle%20cx%3D%2216%22%20cy%3D%2216%22%20r%3D%2214.4%22%20stroke-width%3D%221.9%22%2F%3E%20%3Crect%20x%3D%225.4%22%20y%3D%225.4%22%20width%3D%2221.2%22%20height%3D%2221.2%22%20stroke-width%3D%221.7%22%2F%3E%20%3Crect%20x%3D%225.4%22%20y%3D%225.4%22%20width%3D%2221.2%22%20height%3D%2221.2%22%20stroke-width%3D%221.7%22%20transform%3D%22rotate%2845%2016%2016%29%22%2F%3E%20%3C%2Fg%3E%20%3Ccircle%20cx%3D%2216%22%20cy%3D%2216%22%20r%3D%222.9%22%20fill%3D%22currentColor%22%2F%3E%20%3C%2Fsvg%3E") no-repeat center / contain;
}

/* Continue is an ACTION, and the boards paint action gold (art04 semantic key,
   art08 §07). Emerald here also collided with the success green used by the
   RECENTLY DONE column two rows below it — action and outcome in one hue. */
.btn-continue-hero {
  background: linear-gradient(180deg, var(--c-gold-mid), var(--c-gold)) !important;
  color: var(--c-ink-2) !important;
  box-shadow: 0 4px 14px rgba(201, 169, 107, .22) !important;
}
.btn-continue-hero:hover {
  background: linear-gradient(180deg, var(--c-gold-hi), var(--c-gold-mid)) !important;
  box-shadow: 0 6px 20px rgba(201, 169, 107, .30) !important;
}

/* command deck's brand tile */
.brand-icon {
  background: var(--gd-focus-bg) !important;
  border: 1px solid var(--gd-hairline-gold) !important;
  color: var(--gd-gold) !important;
  font-family: var(--gd-display) !important;
}

/* ============================================================================
   MOTION — "Movement communicates real system activity."
   Enter = soft fade + slight rise. Nothing loops; nothing moves for decoration.
   ============================================================================ */
@keyframes gd-enter { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.gd-enter { animation: gd-enter var(--gd-t-slow) var(--gd-ease-out) both; }
.gd-enter-2 { animation-delay: 60ms; }
.gd-enter-3 { animation-delay: 120ms; }
.gd-enter-4 { animation-delay: 180ms; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .gbrand:hover i { transform: none; }
}

/* ============================================================================
   RESPONSIVE — the second UVP viewport is a design target, not a fallback
   ============================================================================ */
/* The nav wrapped to three rows at 390px, pushing content below the fold on
   every page. Board art05 §14 keeps mobile chrome to one band: the menu
   scrolls sideways instead of stacking. */
@media (max-width: 720px) {
  .gnav-in { min-height: 50px; gap: var(--space-8); padding: 0 var(--space-12); flex-wrap: nowrap; max-width: 100%; }
  /* min-width:0 is load-bearing, not tidiness. A flex item defaults to
     min-width:auto, so a nowrap scroller refuses to shrink below its content
     and pushes the BAR wider than the viewport instead of scrolling inside
     itself. Measured: without it the DS added 36-75px of horizontal page
     scroll at 390px on five pages that had none before. */
  .gnav-in > * { min-width: 0; }
  .gmenu {
    flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
    min-width: 0; flex: 1 1 auto;
  }
  .gmenu::-webkit-scrollbar { display: none; }
  .ggrp > summary { padding: var(--space-8) var(--space-8); letter-spacing: .1em; }
  .gtrail-what { display: none; }
}

@media (max-width: 720px) {
  :root { --gd-measure: 100%; }
  .gd-card, .gd-panel { padding: var(--gd-4); }
  .gd-object-head { flex-direction: column; gap: var(--gd-2); }
  .gbrand { letter-spacing: .18em; font-size: var(--text-16); }
  body { background-size: 100% 100%, 40px 40px, 40px 40px; }
}

@media print {
  body { background: var(--c-paper-hi); color: var(--c-ink); }
  .gnav, .gtrail { display: none; }
}
