/* ONE THEME FOR THE DOCUMENT PAGES — /system-card/, /contact/, /case-studies/.
 *
 * WHY THIS FILE EXISTS. Until 2026-08-18 the site shipped two visual identities.
 * `/` and `/model/` are a phosphor terminal in mono; /contact/ and /case-studies/
 * were "Nocturne" — #0B0F17 navy, Inter, 11px rounded corners. One click from the
 * top bar crossed between them, and a visitor who lands on a different-looking
 * page reads it as a different company. The system card was migrated first
 * (Aidan's call, that day); this file is that migration finished, and factored
 * out so the next page cannot re-fork it.
 *
 * Aidan, 2026-08-18: *"get the system card, contact, and case studies pages onto
 * a consistent website design that matches our homepage."* The homepage is the
 * reference, not an average of the four.
 *
 * THE TOKEN VALUES ARE COPIED FROM website/index.html's :root, deliberately, and
 * that page keeps its own copy. It is generated by scripts/build_platform.py and
 * pinned byte-for-byte by tests/test_platform_matches_approved_spec.py — making
 * it depend on a stylesheet it does not control would put an approved artifact at
 * the mercy of this file. So: the homepage owns the palette, this file mirrors it
 * for everything downstream of it. If they ever disagree, index.html is right.
 *
 * HOW A PAGE USES IT. Link it, then write only page-specific rules inline. The
 * `--color-*` aliases below exist because /contact/ and /case-studies/ were built
 * against that naming; keeping the alias layer meant their retheme moved token
 * VALUES and nothing else, which is the whole point of having a token layer.
 */

:root {
  /* ── the phosphor palette, mirrored from website/index.html ── */
  --ground: #000C07;
  --surface: #00110A;
  --raised: #001D10;
  --line: #0C3A26;
  --line-soft: #072418;
  --phos: #00FF7F;
  --phos-dim: #8CFFC4;
  --ink: #B9E8CF;
  --muted: #5E8874;
  --faint: #3D6154;
  --amber: #E0A458;
  --gold: #F5C518;
  --hot: #FF8A2B;
  --crit: #FCA5A5;

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
          "Roboto Mono", "DejaVu Sans Mono", monospace;

  /* The desktop step, mirrored from website/index.html's `:root` under the same
     name and moved by the one block at the bottom of this file. Declared as 1
     here even though nothing in this file divides by it yet: `/`'s stylesheet has
     a rule that must cancel the zoom (`.rail`, a `100vh` length), and the next
     page that needs one should find the same variable waiting rather than invent
     a second name for the same number. */
  --zoom: 1;

  /* ── the alias layer the document pages were written against ──
     Nocturne's names, pointed at terminal values. Nothing downstream had to
     change when the palette did. */
  --bg: var(--ground);
  --panel: var(--surface);
  --panel-2: var(--raised);
  --text: var(--ink);
  --dim: var(--faint);
  --em: var(--phos);
  --em-deep: #0B7D48;
  --em-glow: rgba(0, 255, 127, .10);

  --color-bg: var(--ground);
  --color-surface: var(--surface);
  --color-text: var(--ink);
  --color-accent: var(--phos);
  --color-divider: var(--line);
  --color-neutral-200: var(--phos-dim);
  --color-neutral-300: var(--phos-dim);
  --color-neutral-400: var(--muted);
  /* 500 AND 600 POINT AT --muted, NOT --faint, and this is load-bearing rather
     than lazy. Both names are used for 9–12.5px labels, and --faint measures
     2.80:1 against --surface — under the 4.5:1 AA floor. --muted is 4.84:1.
     /contact/'s old token block carried this same note against Nocturne's --dim
     ("9-12.5px labels — --dim is 3.73:1, under AA"), and /model/ shipped two nav
     labels unreadable for an hour by making exactly this substitution the other
     way. Keep --faint for rules, borders and placeholders; never for text. */
  --color-neutral-500: var(--muted);
  --color-neutral-600: var(--muted);
  --color-neutral-900: var(--ground);
  --color-accent-100: var(--phos-dim);
  --color-accent-300: var(--phos-dim);
  --color-accent-800: rgba(0, 255, 127, .28);

  --font-heading: var(--mono);
  --font-body: var(--mono);

  /* Square, like every surface on `/`. A rounded panel inside a terminal is the
     half-migration the colours used to be. */
  --radius-md: 0px;
  /* A hairline, not a shadow. The terminal draws structure with rules. */
  --shadow-sm: 0 0 0 1px var(--line);
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  font-family: var(--mono);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: .01em;
  margin: 0;
}
p { margin: 0; }
a { color: var(--phos); text-underline-offset: 3px; }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--phos); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--phos) 30%, transparent); }

/* ── the top bar, matched to the homepage's ──
   Same height, same background, same rule, same brand treatment. The homepage
   spends the middle of the row on a dataset search; a document page has nothing
   to search, so the nav takes that slot. Identical chrome, different payload —
   which is what makes the click between them feel like one site. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  padding: 11px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.tb-brand {
  color: var(--phos);
  font-weight: 700;
  letter-spacing: .1em;
  font-size: 13.5px;
  flex: none;
  text-decoration: none;
}
.tb-what { color: var(--muted); font-size: 11.5px; flex: none; }
.tb-nav { display: flex; align-items: center; gap: 16px; margin-left: auto; flex: none; }
.tb-nav a {
  /* --muted, where `/`'s single `.beta` link uses --faint. A three-item nav is
     the page's only means of navigation and has to clear AA; see the note on the
     neutral tokens above. */
  color: var(--muted);
  font-size: 11.5px;
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 1px solid transparent;
}
.tb-nav a:hover { color: var(--phos-dim); border-bottom-color: var(--muted); }
/* The current page is stated, not just highlighted — `aria-current` is the
   source of truth and the colour is downstream of it, so the two cannot drift. */
.tb-nav a[aria-current="page"] { color: var(--phos-dim); border-bottom-color: var(--line); }

/* ── the two doors (scripts/nav_links.py) ──
   The nav names what a visitor GETS, not what they ARE. `.sell` is the one paid
   destination on the site and the only filled element in any chrome on any page;
   that singularity is the point, so do not add a second one. */
.tb-nav a.sell {
  color: #04120c;
  background: var(--phos);
  border-bottom: 0;
  border-radius: 6px;
  padding: 5px 11px;
  font-weight: 700;
}
.tb-nav a.sell:hover { filter: brightness(1.08); border-bottom-color: transparent; }
.tb-nav a.sell[aria-current="page"] { border-bottom-color: transparent; }
.nav-short { display: none; }

/* Below 720px the two doors keep the bar and the secondary pair leaves it — a
   phone is the stated median viewport, and four items plus a wordmark do not
   fit one line at 390px without shrinking the doors to nothing. */
@media (max-width: 720px) {
  .tb-what { display: none; }
  .tb-nav { gap: 10px; flex-wrap: wrap; row-gap: 6px; }
  /* not display:none — that left /system-card/ and /contact/ with no route for a
     thumb. They wrap to a second row instead. */
  /* no opacity — dimming measured 3.49:1 here, under the 4.5 AA wants, and on a
     phone this pair is the only route to those two pages. */
  .tb-nav a.secondary { display: inline; font-size: 11px; opacity: 1; }
  .tb-nav a.secondary:first-of-type { margin-left: auto; }
  .nav-long { display: none; }
  .nav-short { display: inline; }
}

/* ── the footer ──
   `/` has none: it is an application shell and ends in the pane. A document ends,
   so it gets one line saying who wrote it. */
.docfoot {
  border-top: 1px solid var(--line);
  padding: 22px 20px 30px;
  text-align: center;
  color: var(--muted);
  font-size: 11.5px;
}
.docfoot a { color: var(--muted); text-decoration: none; border-bottom: 1px dotted var(--faint); }
.docfoot a:hover { color: var(--phos-dim); border-bottom-color: var(--phos-dim); }

/* ── the column ──
   Overridable per page: the system card sets its own width because it carries a
   limitation paragraph under every layer. */
main.doc { width: 100%; max-width: 720px; margin: 0 auto; padding: 0 20px 72px; }

/* ── shared furniture ──
   A panel is a hairline box on --surface. Every card class on the three pages
   resolves to this; they keep their own names so page CSS stays readable. */
.panel {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  padding: 15px 16px;
}

/* The section label: uppercase, letterspaced, phosphor-dim. Same register as the
   rail headings on `/`. */
.seclabel {
  font-size: 11.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--phos-dim);
}

@media (max-width: 700px) {
  /* Exactly what `/` does at this width, and for the same reason: the context
     line is the first thing worth spending to keep the nav on one row. */
  .tb-what { display: none; }
  .topbar { padding: 9px 14px; gap: 12px; }
  .tb-nav { gap: 13px; }
  main.doc { padding-left: 16px; padding-right: 16px; }
}

/* ── the desktop step ──
   Aidan, 2026-08-19: *"can we zoom in our website UX on desktop by say, 25%?"*
   Same one line, same 1080 gate and the same reasoning as the block at the end of
   scripts/build_platform.py's stylesheet, which is where that reasoning is written
   down in full. It is one gate for the whole site on purpose: a visitor who steps
   from `/` to /system-card/ at the same window width must not cross a type-size
   boundary, for the same reason this file exists at all.

   IT COSTS NOTHING HERE. These three pages carry no viewport-relative length and
   nothing `position: fixed`, so there is no `.rail` divide and no tooltip
   arithmetic to follow it — the whole change is the two declarations below. What
   the reader gets is 25% larger type down a column whose MEASURE does not change:
   `main.doc` stays 720px of layout, so the line length that was set for
   readability holds and only the glyphs grow. */
@media (min-width: 1080px) {
  :root { --zoom: 1.25; }
  body { zoom: var(--zoom); }
}
