/* ============================================================
   console.css — "The Live Ops Console"
   The homepage rendered as a running game's live-operations
   dashboard. Light data-terminal: near-white ground, hairline
   grid, dense tabular numbers, one hot signal-red.
   See DESIGN.md — this is the authoritative visual world.
   ============================================================ */

:root {
  --bg:        #F4F5F7;   /* calibrated near-white screen ground */
  --panel:     #FFFFFF;
  --panel-alt: #FAFBFC;   /* header bars, inset rows */
  --ink:       #0B0E14;   /* phosphor near-black */
  --ink2:      #3A4150;
  --ink3:      #616977;   /* mono labels/units — ≥4.5:1 on ground (#F4F5F7) AND panels */
  --grid:      #E3E6EB;   /* hairline rule */
  --grid2:     #D2D7DF;   /* stronger rule */
  /* ACHROMATIC CHROME (2026-07-27). The console used to spend signal red on
     chrome — markers, labels, tags, rules. It read as busy rather than
     considered, so the accent tokens now resolve to INK and the red survives
     only as --signal, on the single primary action per page. The token names
     are kept because ~100 references across the site route through them;
     what changed is what they mean. See DESIGN.md → The Signal Rule. */
  --hot:       #21232A;   /* accent FILLS / rules / segments — now ink */
  --hot-deep:  #000000;
  --hot-text:  #2B2D35;   /* accent as READABLE TEXT — 13.7:1 on panel white */
  --signal:      #FF4D2E; /* the one red left: the primary action, and focus */
  --signal-deep: #D93417;
  --live:      #0E9F6E;   /* operational green — the LED and dots only */
  /* On-scrim text. The lightbox and the cover HUD sit on a fixed dark scrim in
     BOTH themes, so their type cannot follow --ink. These two never remap. */
  --on-scrim:   #EDEFF3;
  --on-scrim-2: #C6CBD4;
  --live-text: #0A7C55;   /* green as READABLE TEXT — #0E9F6E is only 3.3:1 on white */
  --amber:     #C77A0A;
  --cyan:      #1273C4;

  /* Radius (2026-07-27). Owner call: the orthogonal instrument softens.
     One radius, one small radius, nothing else. */
  --r:    6px;
  --r-sm: 4px;

  --display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --mono:    'Space Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --body:    'Newsreader', Georgia, serif;

  --max: 1320px;
  --gut: 24px;
  --hair: 1px solid var(--grid);
  --hair2: 1px solid var(--grid2);
  --s-section: 104px;   /* the interval between sections — the page's main breath */

  /* Type ladder — a documented 8-step scale (see DESIGN.md typography.ui-scale).
     Dense instrument UI: micro labels → readout. Every font-size in this file
     resolves to one of these steps; no loose literals. */
  --fs-0: 8px;     /* micro: sprocket/frame ticks, slot cat/open tags */
  --fs-1: 9.5px;   /* small labels, units, cat tags, status */
  --fs-2: 10.5px;  /* default mono label / metadata */
  --fs-3: 11px;    /* tab + control text */
  --fs-4: 12px;    /* readable mono: stats, table cells, inputs */
  --fs-5: 14.5px;  /* serif prose (dev-log excerpt, notes) */
  --fs-6: 17px;    /* body prose / larger serif */
  --fs-7: 20px;    /* small heavy readout (studio metric) */
  --fs-8: clamp(26px, 2.5vw, 34px);      /* big readout: track record, section metrics */
  --fs-9: clamp(21px, 2.5vw, 29px);      /* section head — lighter and smaller than the readout */
  --fs-lead: clamp(18.5px, 1.5vw, 21px); /* serif LEAD statement — the one mid-tier voice */
  --fs-read: 18.5px;  /* long-form article reading measure (blog posts) */
  --fs-read-h: 21px;  /* in-article H3 */
}

html[data-theme="dark"] {
  --bg:        #0B0E14;
  --panel:     #121722;
  --panel-alt: #0F131C;
  --ink:       #E7EAF0;
  --ink2:      #AEB6C6;
  --ink3:      #7E879A;   /* ≥4.5:1 on dark panels */
  --grid:      #1E2634;
  --grid2:     #2A3547;
  /* the achromatic accent lightens rather than darkens on the dark terminal */
  --hot:       #D5DAE4;
  --hot-deep:  #FFFFFF;
  --hot-text:  #D5DAE4;   /* 12.1:1 on the dark panel */
  --signal:      #FF5A3C;
  --signal-deep: #FF7256;
  --live:      #26C08A;
  --live-text: #26C08A;   /* already 8:1 on the dark panel — no darkening needed */
}

* , *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { max-width: 100%; overflow-x: hidden; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  font-family: var(--body);
  background: var(--bg);
  color: var(--ink);
  font-size: var(--fs-6);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
::selection { background: var(--hot); color: #fff; }

/* ── Keyboard focus: one visible ring across every control ── */
/* focus keeps the red: it is the one place a signal still has to interrupt */
.cmd:focus-visible, .tbar-nav a:focus-visible, .tbar-theme:focus-visible,
.filt:focus-visible, .pc:focus-visible, .plink:focus-visible,
.sub:focus-visible, .foot-mail:focus-visible, .foot-links a:focus-visible,
.cm-x:focus-visible, .build-status a:focus-visible, .cap:focus-visible {
  outline: 2px solid var(--signal); outline-offset: 2px;
}
.cm-f input:focus, .cm-f textarea:focus, .ctoolbar .csearch input:focus { outline: none; border-color: var(--signal); box-shadow: inset 0 0 0 1px var(--signal); }

/* ── Press feedback ── controls nudge down 1px on press and spring back —
   tactile, not a lift (No-Float Rule is about resting/hover state; a press
   is the one moment something is allowed to move, a finger is on it).
   Cards use a brightness dip instead: they already own `transform` for the
   scroll-reveal stagger below, and a second, faster transform on the same
   property would fight it. A content dim reads as "pressed" just as well. */
.cmd:active, .filt:active, .tbar-nav a:active, .tbar-theme:active {
  transform: translateY(1px);
}
.pc:active, .slot:active, .cap:active, .res-row:active {
  filter: brightness(.96);
}

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.wrap { max-width: var(--max); margin: 0 auto; padding: 0 var(--gut); }
.tnum { font-variant-numeric: tabular-nums; }
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ══════════════ TOP STATUS BAR (nav) ══════════════ */
.tbar {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  backdrop-filter: blur(6px);
  border-bottom: var(--hair2);
}
.tbar-in {
  max-width: var(--max); margin: 0 auto; padding: 0 var(--gut);
  height: 46px; display: flex; align-items: center; gap: 18px;
}
.tbar-id { display: flex; align-items: baseline; gap: 9px; white-space: nowrap; }
.tbar-id b { font-family: var(--display); font-weight: 800; font-size: var(--fs-5); letter-spacing: -0.02em; }
.tbar-id .sys { font-family: var(--display); font-weight: 500; font-size: var(--fs-2); letter-spacing: 0.14em; color: var(--ink3); text-transform: uppercase; }
.tbar-led { display: inline-flex; align-items: center; gap: 6px; font-family: var(--display); font-weight: 500; font-size: var(--fs-2); letter-spacing: 0.12em; color: var(--ink3); text-transform: uppercase; }
.led { width: 7px; height: 7px; border-radius: 999px; background: var(--live); box-shadow: 0 0 0 0 color-mix(in srgb, var(--live) 60%, transparent); animation: pulse 2.4s ease-out infinite; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--live) 55%, transparent); } 70%,100% { box-shadow: 0 0 0 6px transparent; } }
.tbar-nav { margin-left: auto; display: flex; align-items: stretch; }
.tbar-nav a {
  font-family: var(--display); font-size: var(--fs-3); font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink3); padding: 0 12px; display: inline-flex; align-items: center;
  border-left: var(--hair); transition: color .15s, background .15s, transform .08s ease-out;
}
.tbar-nav a:first-child { border-left: none; }
.tbar-nav a:hover { color: var(--ink); }
.tbar-nav a.on { background: var(--ink); color: var(--bg); }
.tbar-clock { font-family: var(--mono); font-size: var(--fs-2); letter-spacing: 0.06em; color: var(--ink3); padding-left: 14px; border-left: var(--hair); white-space: nowrap; }
.tbar-theme { background: none; border: none; cursor: pointer; color: var(--ink3); width: 30px; height: 30px; display: inline-grid; place-items: center; border-left: var(--hair); transition: color .15s, transform .08s ease-out; }
.tbar-theme:hover { color: var(--hot); }
/* both icons stack in the same grid cell; the swap crossfades + gives the
   entering icon a small settle-in rotation instead of an instant display flip */
.tbar-theme svg { grid-area: 1 / 1; width: 15px; height: 15px; transition: opacity .2s ease, transform .2s ease; }
html[data-theme="dark"] .tbar-theme .i-sun { opacity: 0; transform: rotate(-35deg) scale(.6); }
html:not([data-theme="dark"]) .tbar-theme .i-moon { opacity: 0; transform: rotate(35deg) scale(.6); }

@media (max-width: 860px) {
  .tbar-in { height: auto; flex-wrap: wrap; padding-top: 6px; padding-bottom: 0; gap: 10px; }
  .tbar-nav { order: 3; flex: 1 1 100%; overflow-x: auto; scrollbar-width: none; border-top: var(--hair); }
  .tbar-nav::-webkit-scrollbar { display: none; }
  .tbar-nav a { padding: 10px 12px; }
  .tbar-clock { display: none; }
}

/* ══════════════ PANEL — the core container ══════════════ */
/* A panel is drawn, not furnished. Its header is a ruled label — no filled
   bar, no glyph marker, no status dot. Structure comes from the rule. */
.panel { border: 1px solid var(--grid); border-radius: var(--r); overflow: hidden;
  background: var(--panel); position: relative; display: flex; flex-direction: column; }
.panel + .panel { border-top: none; }
.phead {
  display: flex; align-items: center; gap: 10px;
  background: none; border-bottom: 1px solid var(--grid);
  padding: 18px 22px 15px; min-height: 0;
}
.phead h2, .phead h3 { font-family: var(--display); font-weight: 500; font-size: var(--fs-5); letter-spacing: 0.005em; text-transform: none; }
.phead .pstat { margin-left: auto; font-family: var(--display); font-weight: 500; font-size: var(--fs-3); letter-spacing: 0.12em; color: var(--ink3); text-transform: uppercase; display: inline-flex; align-items: center; gap: 7px; }
.phead .plink { margin-left: auto; font-family: var(--display); font-size: var(--fs-3); font-weight: 500; letter-spacing: 0.12em; color: var(--hot-text); text-transform: uppercase; }
.phead .plink:hover { color: var(--hot-deep); text-decoration: underline; text-underline-offset: 3px; }
.phead .pstat + .plink { margin-left: 14px; }
.pbody { padding: 26px 22px; }
/* Deploy notes — give the prose room to breathe */
.pbody-notes { padding: 22px 22px 24px; }
.notes-lead { font-family: var(--body); font-size: var(--fs-6); line-height: 1.65; color: var(--ink2); }
.notes-lead b { color: var(--ink); font-weight: 600; }
/* Deploy log — a real aligned readout: [key] [value] [status badge] columns.
   No &nbsp; padding; the grid keeps every column flush so it scans instantly. */
.notes-table { margin-top: 20px; border-top: var(--hair); }
.notes-row { display: grid; grid-template-columns: 108px 1fr auto; gap: 10px 14px; align-items: baseline; padding: 8px 0; border-bottom: var(--hair); font-family: var(--mono); font-size: var(--fs-2); letter-spacing: 0.02em; }
.notes-row .nk { color: var(--ink3); }
.notes-row .nk::before { content: "› "; color: var(--hot); }
.notes-row .nv { color: var(--ink); overflow-wrap: anywhere; }
.notes-row .ns { font-weight: 700; letter-spacing: 0.08em; color: var(--live-text); white-space: nowrap; display: inline-flex; align-items: center; gap: 6px; }
.notes-row .ns::before { content: ""; width: 6px; height: 6px; border-radius: 999px; background: var(--live); display: inline-block; }
.notes-foot { font-family: var(--body); font-size: var(--fs-5); font-style: italic; line-height: 1.55; color: var(--ink2); margin-top: 18px; padding-top: 16px; border-top: var(--hair); }
.panel.live::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px; background: var(--ink); z-index: 1; }

/* ══════════════ DASHBOARD GRID ══════════════ */
.grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--gut); margin: var(--gut) 0 0; }
.col-12 { grid-column: span 12; }
.col-8  { grid-column: span 8; }
.col-6  { grid-column: span 6; }
.col-5  { grid-column: span 5; }
.col-4  { grid-column: span 4; }
.col-7  { grid-column: span 7; }
@media (max-width: 980px) { .col-8,.col-7,.col-6,.col-5,.col-4 { grid-column: span 12; } }

/* ── LABELLED RULE — a mono key that runs a hairline to the edge.
   The console's way of titling a block without inventing another eyebrow. ── */
.keyrule { display: flex; align-items: center; gap: 14px; font-family: var(--display); font-size: var(--fs-3);
  font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink3); }
.keyrule::after { content: ""; flex: 1; height: 1px; background: var(--grid2); }

/* ── LEAD statement — the one mid-tier voice. Serif, because it is prose
   (Two-Voice Rule): the machine hands you a book face for the actual claim. ── */
.lead { font-family: var(--body); font-size: var(--fs-lead); line-height: 1.6; color: var(--ink2); max-width: 60ch; }
.lead b { color: var(--ink); font-weight: 500; }
.op-lead { margin-top: 18px; }
.op-key { margin-top: 46px; }

/* command buttons */
.cmd { font-family: var(--display); font-weight: 500; font-size: var(--fs-3); letter-spacing: 0.1em; text-transform: uppercase;
  padding: 12px 18px; border: 1px solid var(--ink); border-radius: var(--r-sm); cursor: pointer; background: none; color: var(--ink);
  display: inline-flex; align-items: center; gap: 8px; transition: background .15s, color .15s, border-color .15s, transform .08s ease-out; }
.cmd.hot { background: var(--signal); border-color: var(--signal); color: #fff; }
.cmd.hot:hover { background: var(--signal-deep); border-color: var(--signal-deep); }
.cmd.ghost:hover { border-color: var(--ink); background: var(--panel-alt); }

/* ══════════════ SYSTEM RAIL — four systems, one operator ══════════════
   The positioning claim as an instrument instead of a sentence: the four
   disciplines a studio normally splits across four teams, each with the real
   depth of ownership. Single row, so it adds structure without adding bulk. */
.sysrail { border: 1px solid var(--grid); border-radius: var(--r); overflow: hidden; background: var(--panel); margin-top: var(--gut); }
.sysrail-h { display: flex; align-items: center; gap: 12px; padding: 16px 20px 13px; background: none; border-bottom: 1px solid var(--grid); }
.sysrail-h .k { font-family: var(--display); font-size: var(--fs-3); font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink3); }
.sysrail-h .n { margin-left: auto; font-family: var(--display); font-weight: 500; font-size: var(--fs-3); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink3); font-variant-numeric: tabular-nums; }
.sysrail-cells { display: grid; grid-template-columns: repeat(4, 1fr); }
.syscell { padding: 14px 16px 15px; border-left: var(--hair); }
.syscell:first-child { border-left: none; }
.sys-l { display: block; font-family: var(--display); font-weight: 500; font-size: var(--fs-5); letter-spacing: -0.01em; color: var(--ink); }
.syscell .meter-seg { margin-top: 11px; }
.sys-v { display: block; margin-top: 9px; font-family: var(--display); font-size: var(--fs-2); font-weight: 500; letter-spacing: 0.1em; color: var(--ink3); }
.sys-v.core { color: var(--hot-text); }

/* ══════════════ CREDENTIAL LINE ══════════════
   The homepage is a writing front door, so the proof does NOT get a dashboard
   here — it gets one line. Who is writing this, what they've actually done,
   and a door to the full record. One rule, three facts, no readout scale. */
.credline { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 22px;
  margin-top: 38px; padding: 20px 0 0; border-top: 1px solid var(--grid); font-family: var(--display); }
.credline .role { font-weight: 500; font-size: var(--fs-3); letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink2); }
.credline .stats { font-size: var(--fs-2); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink3); font-variant-numeric: tabular-nums; }
.credline .stats b { color: var(--ink); font-weight: 700; }
.credline .go { margin-left: auto; font-size: var(--fs-3); font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--hot-text); white-space: nowrap; }
.credline .go:hover { text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 640px) { .credline .go { margin-left: 0; } }

/* Masthead of the writing front door — the name is a publication title here,
   so it keeps display scale, but nothing below it competes. */
.masthead { padding: 76px 0 4px; }

/* The name plate. At weight 400 the strokes are much lighter than the old 800,
   so the plate is set LARGER to keep the same optical presence — a light face
   at the old size reads as a smaller name, not a quieter one. */
.op-name { font-family: var(--display); font-weight: 400; font-size: clamp(54px, 10vw, 128px);
  line-height: 0.92; letter-spacing: -0.034em; color: var(--ink); }
.op-name .amp { color: var(--hot); }

.op-tag { font-family: var(--display); font-weight: 500; font-size: var(--fs-3); letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--ink3); display: flex; align-items: center; gap: 9px; margin-bottom: 18px; }
.op-tag .led { width: 7px; height: 7px; }

.op-role { font-family: var(--body); font-style: italic; font-size: clamp(20px, 2.7vw, 29px);
  color: var(--ink2); margin-top: 16px; line-height: 1.3; }
.masthead .op-role { max-width: 34ch; }
@media (max-width: 720px) {
  .sysrail-cells { grid-template-columns: 1fr 1fr; }
  .syscell:nth-child(3) { border-left: none; }
  .syscell:nth-child(n+3) { border-top: var(--hair); }
}

/* ══════════════ SECTION HEAD ══════════════
   No 01/02/03 — the sequence carries no information a reader needs. The
   interval above it does the separating; the rule below it does the framing. */
.plate { display: flex; align-items: baseline; gap: 14px; padding: 0 0 20px; border-bottom: 1px solid var(--grid); margin-top: var(--s-section); }
.plate h2 { font-family: var(--display); font-weight: 500; font-size: var(--fs-9); letter-spacing: -0.018em; line-height: 1.05; }
.plate .sub { font-family: var(--display); font-weight: 500; font-size: var(--fs-3); letter-spacing: 0.12em; color: var(--ink3); margin-left: auto; text-transform: uppercase; }

/* ══════════════ SHIPPED BUILDS (work) ══════════════ */
.studio + .studio { margin-top: var(--gut); }
/* Studio monogram badge — a crafted wordmark chip (no logo assets; the design
   system bans stock logos). Sits at the left of the panel header. */
.studio-badge { width: 26px; height: 26px; border-radius: var(--r-sm); flex: none; display: inline-grid; place-items: center;
  font-family: var(--display); font-weight: 800; font-size: var(--fs-4); line-height: 1; letter-spacing: -0.02em;
  color: var(--bg); background: var(--ink); border: 1px solid var(--ink); }
.studio-badge.hot { background: var(--hot); border-color: var(--hot); color: #fff; }
.studio-badge.ghost { background: none; color: var(--ink3); border-color: var(--ink3); }
.build-row {
  display: grid; grid-template-columns: 34px 1fr auto auto; align-items: center; gap: 16px;
  padding: 15px 16px; border-top: var(--hair); transition: background .13s;
}
.build-row:first-child { border-top: none; }
.build-row:hover { background: var(--panel-alt); }
.build-ic { width: 34px; height: 34px; border: 1px solid var(--grid); border-radius: var(--r-sm); object-fit: cover; background: var(--panel-alt); }
.build-main { min-width: 0; }
.build-name { font-family: var(--display); font-weight: 500; font-size: var(--fs-5); letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.build-role { font-family: var(--display); font-weight: 500; font-size: var(--fs-2); letter-spacing: 0.04em; color: var(--ink3); text-transform: uppercase; margin-top: 2px; }
.build-stat { font-family: var(--mono); font-size: var(--fs-4); color: var(--ink2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.build-status { font-family: var(--display); font-weight: 500; font-size: var(--fs-2); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink3); display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.build-status .dot { width: 6px; height: 6px; border-radius: 999px; background: var(--live); }
.build-status.beta .dot { background: var(--amber); }
.build-status a { color: var(--hot-text); }
.build-status a:hover { text-decoration: underline; text-underline-offset: 2px; }
.studio-metrics { display: grid; grid-template-columns: repeat(4, 1fr); border-top: var(--hair2); margin-top: auto; }
.studio-metrics .m { padding: 12px 14px; border-left: var(--hair); }
.studio-metrics .m:first-child { border-left: none; }
.studio-metrics .m b { font-family: var(--mono); font-weight: 700; font-size: var(--fs-7); letter-spacing: -0.01em; display: block; font-variant-numeric: tabular-nums; }
.studio-metrics .m span { font-family: var(--mono); font-size: var(--fs-1); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink3); }
@media (max-width: 620px) {
  .build-row { grid-template-columns: 30px 1fr auto; }
  .build-stat { display: none; }
  .studio-metrics { grid-template-columns: 1fr 1fr; }
  .studio-metrics .m:nth-child(3) { border-left: none; } .studio-metrics .m:nth-child(3), .studio-metrics .m:nth-child(4) { border-top: var(--hair); }
}

/* Stack — grouped tool tags (no fake bars; each tag is a real fact) */
.stack-groups { padding: 4px 0; }
.stack-grp { display: grid; grid-template-columns: 104px 1fr; gap: 16px; align-items: baseline; padding: 14px 16px; border-top: var(--hair); }
.stack-grp:first-child { border-top: none; }
.stack-lbl { font-family: var(--display); font-size: var(--fs-2); font-weight: 500; letter-spacing: 0.1em; line-height: 1.35; text-transform: uppercase; color: var(--ink3); }
.tagrow { display: flex; flex-wrap: wrap; gap: 8px; }
.tag { font-family: var(--mono); font-size: var(--fs-2); letter-spacing: 0.02em; color: var(--ink); background: var(--panel-alt); border: 1px solid var(--grid); border-radius: var(--r-sm); padding: 5px 10px; white-space: nowrap; }

.meter-seg { display: flex; gap: 4px; }
.meter-seg i { width: 100%; min-width: 14px; height: 9px; background: var(--panel-alt); border: var(--hair); transition: background .5s ease, border-color .5s ease; }
.meter-seg i.on { background: var(--hot); border-color: var(--hot); }
/* Progressive-enhancement fill-in: JS adds .seg-anim, resetting lit segments
   to empty so they light up on reveal. No-JS clients see them already lit. */
.seg-anim .meter-seg i.on { background: var(--panel-alt); border-color: var(--grid2); }
.seg-anim.lit .meter-seg i.on { background: var(--hot); border-color: var(--hot); }
/* segments light left-to-right, one system after another */
.seg-anim.lit .meter-seg i:nth-child(2) { transition-delay: .07s; }
.seg-anim.lit .meter-seg i:nth-child(3) { transition-delay: .14s; }
.seg-anim.lit .meter-seg i:nth-child(4) { transition-delay: .21s; }
.seg-anim.lit .meter-seg i:nth-child(5) { transition-delay: .28s; }
/* ══════════════ ROLE TRACK — four roles on one line ══════════════
   A drawn timeline: hairline spine, one node per role, hot node = current.
   Structure comes from the rule, not from a card per entry. */
.track { list-style: none; padding: 2px 0; }
.trow { display: grid; grid-template-columns: 62px 12px 1fr; gap: 0 13px; align-items: start; padding: 13px 16px; border-top: var(--hair); }
.trow:first-child { border-top: none; }
.t-date { font-family: var(--mono); font-size: var(--fs-2); letter-spacing: 0.04em; color: var(--ink3); white-space: nowrap; font-variant-numeric: tabular-nums; padding-top: 1px; }
.t-node { position: relative; align-self: stretch; }
.t-node::before { content: ""; position: absolute; left: 5px; top: -14px; bottom: -14px; width: 1px; background: var(--grid2); }
.trow:first-child .t-node::before { top: 8px; }
.trow:last-child .t-node::before { bottom: calc(100% - 8px); }
.t-node::after { content: ""; position: absolute; left: 1px; top: 4px; width: 9px; height: 9px; border-radius: 999px; background: var(--panel); border: 1px solid var(--ink3); }
.trow.now .t-node::after { background: var(--hot); border-color: var(--hot); }
.t-main { min-width: 0; }
.t-role { display: block; font-family: var(--display); font-weight: 500; font-size: var(--fs-5); line-height: 1.2; letter-spacing: -0.01em; color: var(--ink); }
.trow.now .t-role { color: var(--ink); }
.t-org { display: block; font-family: var(--display); font-weight: 500; font-size: var(--fs-2); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink3); margin-top: 4px; }
.trow.now .t-org { color: var(--hot-text); }

/* ══════════════ DEV LOG (writing) — entry cards ══════════════
   Each entry is a panel with a real cover frame: image when the post has one,
   an authored console plate when it doesn't. The cover leads, then a mono
   ident strip, then the title in Archivo and the excerpt in serif prose. */
.filt { font-family: var(--display); font-size: var(--fs-3); font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink3);
  border: 1px solid var(--grid2); border-radius: var(--r-sm); background: none; padding: 6px 11px; cursor: pointer; transition: color .13s, border-color .13s, background .13s, transform .08s ease-out; }
.filt:hover { color: var(--ink); border-color: var(--ink3); }
.filt.on { background: var(--ink); border-color: var(--ink); color: var(--bg); }

.pcards { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gut); }
.pc { border: 1px solid var(--grid); border-radius: var(--r); overflow: hidden; background: var(--panel); display: flex; flex-direction: column; position: relative;
  transition: border-color .16s, filter .1s ease-out, opacity .45s ease, transform .5s cubic-bezier(.2,.8,.2,1); min-width: 0; }
.pc:hover { border-color: var(--ink3); }
.pc:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
.pc::before { content: ""; position: absolute; top: -1px; left: -1px; right: -1px; height: 2px; background: var(--hot); opacity: 0; transition: opacity .16s; }
.pc:hover::before, .pc:focus-visible::before { opacity: 1; }

/* cover frame */
.pc-cover { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: var(--panel-alt); border-bottom: var(--hair2); }
.pc-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(0.14) contrast(1.04); transition: transform .55s cubic-bezier(.2,.7,.2,1), filter .3s, opacity .4s ease; }
.pc:hover .pc-cover img { transform: scale(1.035); filter: grayscale(0) contrast(1.04); }
/* real content fades in as it decodes rather than popping in raw; gated under
   html.js so a no-JS visitor (who never gets the .loaded class) still sees it */
html.js .pc-cover img { opacity: 0; }
html.js .pc-cover img.loaded { opacity: 1; }
/* authored plate for entries with no photograph — a console test card, not a
   stock stand-in: hairline graticule, the topic glyph struck large, corner ticks. */
.pc-plate { position: absolute; inset: 0; background:
  repeating-linear-gradient(0deg, transparent 0 23px, var(--grid) 23px 24px),
  repeating-linear-gradient(90deg, transparent 0 23px, var(--grid) 23px 24px), var(--panel-alt); }
.pc-plate .g { position: absolute; inset: 0; display: grid; place-items: center; }
.pc-plate .g svg { width: 34%; height: auto; max-width: 96px; color: var(--hot); opacity: .3; }
.pc-plate .tick { position: absolute; width: 9px; height: 9px; border: 1px solid var(--grid2); }
.pc-plate .tick.tl { top: 9px; left: 9px; border-right: none; border-bottom: none; }
.pc-plate .tick.tr { top: 9px; right: 9px; border-left: none; border-bottom: none; }
.pc-plate .tick.bl { bottom: 9px; left: 9px; border-right: none; border-top: none; }
.pc-plate .tick.br { bottom: 9px; right: 9px; border-left: none; border-top: none; }
.pc-plate .id { position: absolute; left: 12px; bottom: 10px; font-family: var(--mono); font-size: var(--fs-0);
  font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink3); }

/* ident strip + body */
.pc-ident { display: flex; align-items: center; gap: 10px; padding: 11px 20px; background: none; border-bottom: 1px solid var(--grid); }
.pc-cat { font-family: var(--display); font-size: var(--fs-2); font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--hot-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pc-cat.life { color: var(--hot-text); }
.pc-ts { margin-left: auto; font-family: var(--mono); font-size: var(--fs-1); letter-spacing: 0.1em; color: var(--ink3); white-space: nowrap; font-variant-numeric: tabular-nums; }
.pc-body { padding: 18px 20px 20px; display: flex; flex-direction: column; flex: 1; }
.pc-t { font-family: var(--display); font-weight: 500; font-size: var(--fs-7); line-height: 1.14; letter-spacing: -0.02em; color: var(--ink); transition: color .13s; }
.pc:hover .pc-t { color: var(--hot-text); }
.pc-ex { font-family: var(--body); font-size: var(--fs-5); line-height: 1.55; color: var(--ink2); margin-top: 9px;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.pc-foot { display: flex; align-items: center; gap: 10px; margin-top: auto; padding-top: 16px;
  font-family: var(--display); font-size: var(--fs-2); font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink3); }
.pc-foot .go { margin-left: auto; color: var(--hot-text); }

/* lead card — the newest entry, cover beside the type */
.pc-lead { grid-column: 1 / -1; }
.pc-lead .pc-in { display: grid; grid-template-columns: 1.15fr 1fr; }
.pc-lead .pc-cover { aspect-ratio: auto; height: 100%; min-height: 300px; border-bottom: none; border-right: var(--hair2); }
.pc-lead .pc-side { display: flex; flex-direction: column; min-width: 0; }
.pc-lead .pc-body { padding: 26px 26px 28px; }
.pc-lead .pc-t { font-size: var(--fs-8); line-height: 1.06; }
.pc-lead .pc-ex { font-size: var(--fs-6); -webkit-line-clamp: 4; margin-top: 12px; }
@media (max-width: 900px) {
  .pcards { grid-template-columns: repeat(2, 1fr); }
  .pc-lead .pc-in { grid-template-columns: 1fr; }
  .pc-lead .pc-cover { aspect-ratio: 16 / 9; min-height: 0; border-right: none; border-bottom: var(--hair2); }
}
@media (max-width: 560px) { .pcards { grid-template-columns: 1fr; } }
.cempty { font-family: var(--mono); font-size: var(--fs-4); color: var(--ink3); padding: 22px 16px; }

/* ══════════════ LOADOUT (books) ══════════════ */
.loadout { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 22px 18px; padding: 20px; }
.slot { position: relative; background: none; cursor: pointer; display: flex; flex-direction: column; border: none; padding: 0; text-align: left; transition: filter .1s ease-out, opacity .45s ease, transform .5s cubic-bezier(.2,.8,.2,1); }
.slot-cover { position: relative; aspect-ratio: 5 / 7; overflow: hidden; border-radius: var(--r); background: var(--c, var(--ink2)); border: 1px solid var(--grid); }
.slot-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; transition: opacity .4s ease; }
html.js .slot-img { opacity: 0; }
html.js .slot-img.loaded { opacity: 1; }
/* Fallback plate when a book has no cover art. --c is the book's own colour, so
   the fallback and the shadow both resolve to system ink rather than raw black. */
.slot-plate { position: absolute; inset: 0; background: var(--c, var(--ink2)); display: flex; flex-direction: column; justify-content: flex-end; padding: 12px; }
.slot-plate .pt { font-family: var(--display); font-weight: 700; font-size: var(--fs-4); color: #fff; line-height: 1.08; text-shadow: 0 1px 2px rgba(11,14,20,.5); }
.slot-hud { position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; justify-content: space-between; padding: 8px 9px;
  background: linear-gradient(180deg, rgba(11,14,20,.55), transparent 38%, transparent 60%, rgba(11,14,20,.7)); opacity: 0; transition: opacity .16s; }
.slot:hover .slot-hud, .slot:focus-visible .slot-hud { opacity: 1; }
.slot:hover .slot-cover { border-color: var(--ink3); }
.slot:focus-visible .slot-cover { outline: 2px solid var(--signal); outline-offset: 1px; }
.slot:focus-visible { outline: none; }
.slot-cat { font-family: var(--mono); font-size: var(--fs-0); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #fff; }
.slot-open { align-self: flex-start; font-family: var(--mono); font-size: var(--fs-0); font-weight: 700; letter-spacing: 0.06em; color: #fff; background: var(--hot); padding: 2px 6px; }
/* persistent rating strip BELOW the cover — always visible so you can rank */
.slot-meta { padding: 8px 1px 0; }
.slot-stars { font-family: var(--mono); font-size: var(--fs-2); letter-spacing: 1px; color: var(--hot); line-height: 1; font-variant-numeric: tabular-nums; }
.slot-stars .off { color: var(--grid2); }
.slot-title { font-family: var(--display); font-weight: 500; font-size: var(--fs-4); line-height: 1.2; color: var(--ink); margin-top: 5px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.slot-auth { font-family: var(--mono); font-size: var(--fs-1); letter-spacing: 0.03em; color: var(--ink3); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.slot:hover .slot-title { color: var(--hot-text); }

/* ══════════════ CAPTURE BUFFER (photos) ══════════════ */
/* Medium plates, two up, with the caption set beneath the frame rather than
   burned across the bottom of the photograph. */
.buffer { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 30px var(--gut); padding: 26px 22px 28px; }
.cap { position: relative; background: none; cursor: zoom-in; border: none; padding: 0; display: block; text-align: left; transition: filter .1s ease-out, opacity .45s ease, transform .5s cubic-bezier(.2,.8,.2,1); }
.cap img { width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; border-radius: var(--r); background: var(--panel-alt); transition: opacity .4s ease; }
html.js .cap img { opacity: 0; }
html.js .cap img.loaded { opacity: 1; }
.cap-meta { display: flex; justify-content: flex-start; gap: 14px; padding: 12px 0 0; font-family: var(--display); }
.cap-t { font-weight: 500; font-size: var(--fs-4); letter-spacing: 0.02em; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cap-n { font-family: var(--mono); font-size: var(--fs-3); letter-spacing: 0.06em; color: var(--ink3); white-space: nowrap; }
.cap:hover .cap-t { color: var(--ink3); }
@media (max-width: 900px) { .buffer { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .buffer { grid-template-columns: 1fr; } }

/* ══════════════ FOOTER — session end ══════════════ */
.foot { border-top: 1px solid var(--grid); margin-top: 120px; }
.foot-in { display: grid; grid-template-columns: 1fr auto; gap: 26px; padding: 34px 0 26px; align-items: start; }
.foot-say { font-family: var(--display); font-weight: 500; font-size: var(--fs-3); letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink3); margin-bottom: 10px; }
.foot-mail { font-family: var(--display); font-weight: 400; font-size: clamp(24px, 4vw, 40px); letter-spacing: -0.025em; }
.foot-mail:hover { color: var(--hot); }
.foot-links { display: flex; flex-direction: column; gap: 8px; text-align: right; }
.foot-links a { font-family: var(--display); font-weight: 500; font-size: var(--fs-3); letter-spacing: 0.06em; color: var(--ink2); }
.foot-links a:hover { color: var(--hot-text); }
.foot-copy { font-family: var(--display); font-weight: 500; font-size: var(--fs-2); letter-spacing: 0.05em; color: var(--ink3); padding: 14px 0 40px; display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap; border-top: var(--hair); }
.foot-copy .live-t { color: var(--live-text); }
@media (max-width: 640px) { .foot-in { grid-template-columns: 1fr; } .foot-links { text-align: left; flex-direction: row; flex-wrap: wrap; gap: 16px; } }

/* ══════════════ CONTACT MODAL (command channel) ══════════════
   Also the shell books.html's note viewer reuses — one open/close
   treatment covers both. Animating a display:none swap needs the
   discrete-property transition + @starting-style pair below; browsers
   without it just keep today's instant show/hide, nothing breaks. */
.cm { position: fixed; inset: 0; z-index: 220; display: none; align-items: center; justify-content: center; padding: 24px;
  opacity: 0; pointer-events: none; transition: opacity .16s ease, display .16s allow-discrete; }
.cm.open { display: flex; opacity: 1; pointer-events: auto; }
@starting-style { .cm.open { opacity: 0; } }
.cm-back { position: absolute; inset: 0; background: rgba(11,14,20,.62); }
.cm-card { position: relative; z-index: 1; width: min(500px, 94vw); max-height: 90vh; overflow: auto; border-radius: var(--r); background: var(--panel); border: 1px solid var(--grid);
  transition: opacity .2s ease, transform .22s cubic-bezier(.2,.8,.2,1); }
@starting-style { .cm.open .cm-card { opacity: 0; transform: translateY(8px); } }
.cm-card .phead { position: sticky; top: 0; }
.cm-x { background: none; border: none; cursor: pointer; font-family: var(--mono); font-size: var(--fs-6); color: var(--ink3); margin-left: auto; line-height: 1; }
.cm-x:hover { color: var(--hot); }
.cm-body { padding: var(--gut); }
.cm-f { display: block; margin-bottom: 14px; }
.cm-f span { display: block; font-family: var(--mono); font-size: var(--fs-1); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink3); margin-bottom: 6px; }
.cm-f input, .cm-f textarea { width: 100%; font-family: var(--body); font-size: var(--fs-5); color: var(--ink); background: var(--panel-alt); border: 1px solid var(--grid2); border-radius: var(--r-sm); padding: 11px 13px; }
.cm-f textarea { resize: vertical; line-height: 1.5; font-family: var(--body); font-size: var(--fs-5); }
.cm-f input:focus, .cm-f textarea:focus { outline: none; border-color: var(--signal); }
.cm-status { font-family: var(--mono); font-size: var(--fs-3); color: var(--ink3); margin-top: 10px; min-height: 1em; }
.cm-status.ok { color: var(--live-text); }
.cm-status.err { color: var(--hot); }

/* ══════════════ PHOTO LIGHTBOX ══════════════ */
.lb { position: fixed; inset: 0; z-index: 230; display: none; align-items: center; justify-content: center; padding: 28px;
  opacity: 0; pointer-events: none; transition: opacity .16s ease, display .16s allow-discrete; }
.lb.open { display: flex; opacity: 1; pointer-events: auto; }
@starting-style { .lb.open { opacity: 0; } }
.lb-back { position: absolute; inset: 0; background: rgba(11,14,20,.9); }
.lb-x { position: absolute; top: 12px; right: 18px; z-index: 2; background: none; border: none; cursor: pointer; font-family: var(--mono); font-size: var(--fs-7); line-height: 1; color: var(--on-scrim); }
.lb-x:hover { color: var(--hot); }
.lb-fig { position: relative; z-index: 1; margin: 0; display: flex; flex-direction: column; align-items: center; gap: 10px; max-width: min(1100px, 92vw); max-height: 88vh;
  transition: opacity .2s ease, transform .22s cubic-bezier(.2,.8,.2,1); }
@starting-style { .lb.open .lb-fig { opacity: 0; transform: translateY(8px); } }
.lb-img { max-width: 100%; max-height: 82vh; object-fit: contain; border-radius: var(--r); border: 1px solid rgba(255,255,255,.12); }
.lb-cap { font-family: var(--mono); font-size: var(--fs-3); letter-spacing: 0.05em; color: var(--on-scrim-2); }

/* ══════════════ SCAN CURSOR ══════════════ */
.cursor { display: inline-block; width: 0.5em; height: 1em; background: var(--hot); margin-left: 2px; vertical-align: -0.12em; animation: blink 1.05s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* ══════════════ PAGE TRANSITIONS ══════════════
   Native cross-document view transitions: a short fade with a few px of
   translateY, never rotate/scale on the page shell (a full 3D page rotate
   here once caused horizontal overflow — see CLAUDE.md). Progressive
   enhancement only: unsupported browsers get today's instant navigation,
   nothing breaks. Off entirely under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .22s; animation-timing-function: ease; }
::view-transition-old(root) { animation-name: page-fade-out; }
::view-transition-new(root) { animation-name: page-fade-in; }
@keyframes page-fade-out { to { opacity: 0; transform: translateY(-6px); } }
@keyframes page-fade-in { from { opacity: 0; transform: translateY(6px); } }

/* ══════════════ REVEAL ══════════════ */
.rv { opacity: 0; transform: translateY(10px); transition: opacity .5s ease, transform .55s cubic-bezier(.2,.8,.2,1); }
.rv.in { opacity: 1; transform: none; }

/* Per-item stagger inside a revealed grid. .rv sometimes sits on the grid
   itself (.pcards) and sometimes on a .panel wrapping it (.loadout/.buffer/
   .reslist all live inside .panel.rv) — .rv.in is the one thing both cases
   share, so it's the anchor here rather than the grid class. Capped at 8
   items so a long list doesn't crawl; it's a stagger, not a queue. */
:is(.pc, .slot, .cap, .res-row) { opacity: 0; transform: translateY(8px);
  transition: opacity .45s ease, transform .5s cubic-bezier(.2,.8,.2,1); }
.rv.in :is(.pc, .slot, .cap, .res-row) { opacity: 1; transform: none; }
.rv.in :is(.pc, .slot, .cap, .res-row):nth-child(2) { transition-delay: .03s; }
.rv.in :is(.pc, .slot, .cap, .res-row):nth-child(3) { transition-delay: .06s; }
.rv.in :is(.pc, .slot, .cap, .res-row):nth-child(4) { transition-delay: .09s; }
.rv.in :is(.pc, .slot, .cap, .res-row):nth-child(5) { transition-delay: .12s; }
.rv.in :is(.pc, .slot, .cap, .res-row):nth-child(6) { transition-delay: .15s; }
.rv.in :is(.pc, .slot, .cap, .res-row):nth-child(7) { transition-delay: .18s; }
.rv.in :is(.pc, .slot, .cap, .res-row):nth-child(n+8) { transition-delay: .21s; }

/* CV metrics / byline stats arrive the same way — considered a literal
   digit count-up instead, but the values are mixed formats (×9, 100M+,
   >200%, 5–10) and DESIGN.md already rules out rounding or embellishing
   them; a stagger gets the "instrument coming online" feeling without
   ever risking a wrong intermediate number. */
:is(.cv-metrics .m, .byline-stats > div) { opacity: 0; transform: translateY(6px);
  transition: opacity .4s ease, transform .45s cubic-bezier(.2,.8,.2,1); }
.rv.in :is(.cv-metrics .m, .byline-stats > div) { opacity: 1; transform: none; }
.rv.in :is(.cv-metrics .m, .byline-stats > div):nth-child(2) { transition-delay: .04s; }
.rv.in :is(.cv-metrics .m, .byline-stats > div):nth-child(3) { transition-delay: .08s; }
.rv.in :is(.cv-metrics .m, .byline-stats > div):nth-child(4) { transition-delay: .12s; }
.rv.in :is(.cv-metrics .m, .byline-stats > div):nth-child(5) { transition-delay: .16s; }
.rv.in :is(.cv-metrics .m, .byline-stats > div):nth-child(n+6) { transition-delay: .2s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .led, .cursor { animation: none !important; transition: none !important; }
  .rv { opacity: 1; transform: none; transition: none; }
  .meter-seg i { transition: none !important; }
  .pc-cover img { transition: none !important; }
  .pc:hover .pc-cover img { transform: none; }
  /* press feedback, theme-icon crossfade, image fade-in, card stagger: keep
     the end state (pressed = pressed, loaded = visible, current theme icon
     shown, cards visible), drop only the animated transition between states */
  .cmd, .filt, .pc, .slot, .cap, .tbar-nav a, .tbar-theme, .res-row,
  .tbar-theme svg, .pc-cover img, .slot-img, .cap img,
  :is(.pc, .slot, .cap, .res-row), :is(.cv-metrics .m, .byline-stats > div) { transition: none !important; }
  .cmd:active, .filt:active, .tbar-nav a:active, .tbar-theme:active { transform: none; }
  .pc:active, .slot:active, .cap:active, .res-row:active { filter: none; }
  :is(.pc, .slot, .cap, .res-row), :is(.cv-metrics .m, .byline-stats > div) { opacity: 1; transform: none; }
  /* modal / lightbox open-close: back to an instant display swap */
  .cm, .cm-card, .lb, .lb-fig { transition: none !important; }
}
