@charset "utf-8";
/* ============================================================================
   eyadasfahani.com — styles.css
   Implements BUILD CONTRACT §3 tokens, §4 type, §5 header lockup, §6 components,
   §7 hero + full-bleed board stage, §9 board states, §11 a11y / motion / reflow.

   Architecture notes (contract §1.1):
     · ONE continuous field, top to bottom. There is no dark-hero / light-body
       split, no .seam, no --surface-hero.
     · NO token is re-declared inside a component scope. Every custom property
       in this file is declared in a :root block and nowhere else.
     · There is no red token and no --fault. --rail amber is the only
       attention colour on the page.
   Vocabulary is PCB fabrication: soldermask / silkscreen / trace / copper /
   via / rail / ground / pad / perf / well.
   ========================================================================= */


/* ============================================================================
   1. FACES — contract §4.1
   Seven declarations. Space Grotesk 400 is deliberately NOT declared: nothing
   uses it. All vendored locally, no network at runtime, all font-display: swap.
   ========================================================================= */

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/space-grotesk-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/space-grotesk-latin-700-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/ibm-plex-sans-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/ibm-plex-sans-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/ibm-plex-sans-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* ============================================================================
   2. TOKENS — contract §3 / TOKENS.css, verbatim
   ========================================================================= */

:root {
  /* ── families ── */
  --f-display: "Space Grotesk", ui-sans-serif, system-ui, sans-serif;
  --f-sans:    "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --f-mono:    "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  /* ── geometry (flat, milled — not consumer SaaS) ── */
  --r-card:  8px;
  --r-chip:  4px;
  --r-badge: 3px;
  --r-pill:  999px;              /* skip-link + toast ONLY */
  --measure: 1120px;
  --gutter:  clamp(20px, 4vw, 64px);

  /* ── spacing: every margin/padding/gap is one of these ── */
  --s1:  4px;  --s2:  8px;  --s3: 12px;  --s4: 16px;  --s5:  24px;
  --s6: 32px;  --s7: 48px;  --s8: 64px;  --s9: 96px;  --s10:128px;

  /* ── motion ── */
  --ease:    cubic-bezier(.22, 1, .36, 1);
  --ease-io: cubic-bezier(.4, 0, .2, 1);
  --t-fast:  140ms;
  --t-base:  220ms;
  --t-slow:  380ms;
}

/* ══════════════ DARK (default) ══════════════ */
:root,
:root[data-theme="dark"] {
  color-scheme: dark;

  /* surfaces */
  --ground:        #04070a;
  --soldermask:    #06090d;
  --soldermask-2:  #0d151e;
  --well:          #111b26;
  --scrim:         rgba(4, 7, 10, .72);

  /* ink — the silkscreen legend */
  --silkscreen:    #e6edf3;   /* 16.9:1 */
  --silkscreen-2:  #a9bacb;   /*  9.4:1 */
  --silkscreen-3:  #6b7f92;   /*  4.82:1 — floor, never lighten */

  /* lines */
  --trace:         #1c2b3a;
  --trace-2:       #26394c;
  --perf:          rgba(0, 229, 160, .045);

  /* accents */
  --signal:        #00e5a0;   /* 12.6:1 — identity, unchanged */
  --signal-ink:    #04150d;
  --signal-dim:    rgba(0, 229, 160, .12);
  --signal-halo:   rgba(0, 229, 160, .26);
  --copper:        #d08a4e;
  --pad:           #d9b25a;
  --via:           #35a2ff;
  --rail:          #ffb547;   /* the ONLY attention colour. No red token exists. */

  /* elevation */
  --lift:          0 6px 22px rgba(0, 0, 0, .40);
  --lift-2:        0 24px 70px rgba(0, 0, 0, .58);

  /* 3D board art direction (read by readThemeTokens()) */
  --board-mask:    #0b1f1a;
  --board-core:    #c8a86a;
  --board-silk:    #cfe6dc;
  --board-copper:  #1f6f57;
  --board-gold:    #d9b25a;
  --board-ic:      #101317;
  --board-metal:   #b9bfc6;
  --board-key:     #ffffff;
  --board-env-sky: #223140;
  --board-env-hi:  #2e4152;
  --board-env-lo:  #121a22;
  --board-env-gnd: #05080b;
}

/* ══════════════ LIGHT ══════════════ */
/* Accents are the AA-passing versions of the current build's values.
   --signal is hue 163 vs #00e5a0's hue 162 — the same colour darkened for
   legibility, not a different colour. Never restore #00a173 (3.05:1),
   #1d7fd6 (3.82:1), #c4820b (2.95:1) or #6b8096 (3.75:1). */
:root[data-theme="light"] {
  color-scheme: light;

  --ground:        #e3eaf1;
  --soldermask:    #f2f6f9;
  --soldermask-2:  #ffffff;
  --well:          #e8eef4;
  --scrim:         rgba(13, 27, 38, .55);

  --silkscreen:    #0d1b26;   /* 16.1:1 */
  --silkscreen-2:  #3d5266;   /*  7.44:1 */
  --silkscreen-3:  #5a6d7e;   /*  4.93:1 — floor, never lighten */

  --trace:         #d5e0ea;
  --trace-2:       #bccbd9;
  --perf:          rgba(0, 90, 66, .055);

  --signal:        #007a58;   /* 4.93:1 */
  --signal-ink:    #ffffff;   /* 5.35:1 on --signal */
  --signal-dim:    rgba(0, 122, 88, .10);
  --signal-halo:   rgba(0, 122, 88, .20);
  --copper:        #9a5a2b;   /* 4.74:1 */
  --pad:           #8a6512;   /* 4.89:1 */
  --via:           #1466ad;   /* 5.47:1 */
  --rail:          #8a5a00;   /* 5.46:1 */

  --lift:          0 6px 20px rgba(16, 42, 64, .10);
  --lift-2:        0 24px 60px rgba(16, 42, 64, .16);

  --board-mask:    #16352c;
  --board-core:    #d8bb7e;
  --board-silk:    #e6f2ec;
  --board-copper:  #2a8a6c;
  --board-gold:    #cfa64c;
  --board-ic:      #171b20;
  --board-metal:   #aab1b8;
  --board-key:     #ffffff;
  --board-env-sky: #dfe9f1;
  --board-env-hi:  #cdd9e3;
  --board-env-lo:  #9fadb8;
  --board-env-gnd: #b9c4cd;
}

/* No-JS / first-visit default follows the OS, because <html> ships with no
   data-theme attribute. The light block is repeated verbatim here — contract §3. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    color-scheme: light;

    --ground:        #e3eaf1;
    --soldermask:    #f2f6f9;
    --soldermask-2:  #ffffff;
    --well:          #e8eef4;
    --scrim:         rgba(13, 27, 38, .55);

    --silkscreen:    #0d1b26;
    --silkscreen-2:  #3d5266;
    --silkscreen-3:  #5a6d7e;

    --trace:         #d5e0ea;
    --trace-2:       #bccbd9;
    --perf:          rgba(0, 90, 66, .055);

    --signal:        #007a58;
    --signal-ink:    #ffffff;
    --signal-dim:    rgba(0, 122, 88, .10);
    --signal-halo:   rgba(0, 122, 88, .20);
    --copper:        #9a5a2b;
    --pad:           #8a6512;
    --via:           #1466ad;
    --rail:          #8a5a00;

    --lift:          0 6px 20px rgba(16, 42, 64, .10);
    --lift-2:        0 24px 60px rgba(16, 42, 64, .16);

    --board-mask:    #16352c;
    --board-core:    #d8bb7e;
    --board-silk:    #e6f2ec;
    --board-copper:  #2a8a6c;
    --board-gold:    #cfa64c;
    --board-ic:      #171b20;
    --board-metal:   #aab1b8;
    --board-key:     #ffffff;
    --board-env-sky: #dfe9f1;
    --board-env-hi:  #cdd9e3;
    --board-env-lo:  #9fadb8;
    --board-env-gnd: #b9c4cd;
  }
}


/* ============================================================================
   3. RESET + BASE
   ========================================================================= */

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

html {
  /* Root stays at the browser default 16px — contract §4.2. Never set font-size. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: var(--s5);          /* 24px — no fixed header to clear */
  scrollbar-color: var(--trace-2) var(--ground);
  scrollbar-width: thin;
}

html, body { overflow-x: clip; }          /* backstop, not the mechanism (§11.4) */

body {
  margin: 0;
  min-height: 100%;
  font-family: var(--f-sans);
  font-weight: 400;
  font-size: clamp(.9375rem, .25vw + .875rem, 1.0625rem);
  line-height: 1.6;
  color: var(--silkscreen-2);
  background-color: var(--soldermask);
  /* The perfboard: a STATIC dot grid at ~0.1in (9.6px) pitch. No canvas,
     no JS, reduced-motion-safe by construction — contract §1.7. */
  background-image: radial-gradient(circle at 1px 1px, var(--perf) 1px, transparent 1.5px);
  background-size: 9.6px 9.6px;
  background-position: 0 0;
  background-repeat: repeat;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-variant-ligatures: none;
}

[hidden] { display: none !important; }

img, svg, canvas, video { display: block; max-width: 100%; }
svg { fill: currentColor; }

ul, ol, dl, dd, figure { margin: 0; padding: 0; }
li { list-style: none; }

a { color: var(--signal); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { text-decoration-thickness: 2px; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
  margin: 0;
}
button { background: none; border: 0; padding: 0; cursor: pointer; }

table { border-collapse: collapse; border-spacing: 0; }

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


/* ============================================================================
   4. TYPE SCALE — contract §4.2
   ========================================================================= */

h1, h2, h3 { font-family: var(--f-display); margin: 0; text-wrap: balance; }
h4, h5, h6 { font-family: var(--f-sans); margin: 0; }

p { margin: 0 0 var(--s4); text-wrap: pretty; max-width: 68ch; }
p:last-child { margin-bottom: 0; }

strong { font-family: var(--f-sans); font-weight: 600; letter-spacing: 0; color: var(--silkscreen); }
em { font-style: italic; }

code, pre, kbd, samp { font-family: var(--f-mono); font-size: .9em; }

.mono,
.silkscreen,
.meta,
.chip,
.filter,
.sec__kind,
.sec__num,
kbd { font-family: var(--f-mono); }

/* Structural mono voice — uppercase, tracked out hard. */
.silkscreen {
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .65625rem;
  letter-spacing: .18em;
  line-height: 1;
  text-transform: uppercase;
}

/* Meta / dates. */
.meta {
  font-family: var(--f-mono);
  font-weight: 400;
  font-size: .71875rem;
  letter-spacing: .04em;
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--silkscreen-3);
}

.dim { color: var(--silkscreen-3); }

/* Section lede. */
.lede {
  font-family: var(--f-sans);
  font-weight: 400;
  font-size: clamp(1rem, .3vw + .94rem, 1.125rem);
  letter-spacing: 0;
  line-height: 1.55;
  color: var(--silkscreen-2);
  max-width: 62ch;
  margin: 0 0 28px;
}

kbd {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 var(--s1);
  border: 1px solid var(--trace-2);
  border-radius: var(--r-badge);
  background: var(--well);
  font-weight: 500;
  font-size: .625rem;
  letter-spacing: .04em;
  line-height: 1;
  color: var(--silkscreen-2);
  white-space: nowrap;
}

/* Inline SVG arrow — every → and ↗ on the page (contract §1.13). */
/* .ext is the external-link arrow that main.js builds at runtime. It MUST be
   sized here: the global `svg { display:block; max-width:100% }` reset turns an
   unsized inline SVG into a block replaced element that fills its container and
   then squares itself off the 0 0 16 16 viewBox — a 12px glyph becomes ~544px. */
.arw,
.ext { width: 12px; height: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; }

/* Utilities */
.vh {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
html:not(.js) .js-only { display: none !important; }

/* Controls that only JS can service. With scripting off the theme follows
   prefers-color-scheme and every .card__detail is already rendered inline,
   so leaving these visible would offer buttons that do nothing when pressed. */
html:not(.js) #theme-toggle,
html:not(.js) .card__open { display: none !important; }


/* ============================================================================
   5. LAYOUT PRIMITIVES
   ========================================================================= */

.wrap {
  width: 100%;
  max-width: calc(var(--measure) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.sec {
  padding-block: clamp(56px, 8vw, 112px);
  border-top: 1px solid var(--trace);
}
.sec:first-of-type { border-top: 0; }

/* ── Section header lockup — contract §5 ── */
.sec__head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  column-gap: var(--s4);
  padding-bottom: var(--s4);
  border-bottom: 1px solid var(--trace);   /* rule runs UNDER the whole lockup */
  margin-bottom: var(--s6);
}
.sec__desig {
  display: grid;
  place-items: center;
  min-width: 34px;
  height: 26px;
  padding: 0 7px;
  border: 1px solid var(--trace-2);
  border-radius: var(--r-badge);
  background: var(--well);
  color: var(--copper);
}
.sec__num {
  font-weight: 500;
  font-size: .6875rem;
  letter-spacing: .10em;
  line-height: 1;
}
.sec__lock { min-width: 0; }
.sec__title {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: clamp(1.375rem, 1.2vw + 1.05rem, 1.75rem);
  letter-spacing: -.01em;
  line-height: 1.1;
  text-transform: none;                    /* sentence case — never uppercase */
  color: var(--silkscreen);
}
.sec__kind {
  font-family: var(--f-mono);
  font-weight: 400;
  font-size: .71875rem;
  letter-spacing: .02em;
  line-height: 1;
  text-transform: lowercase;
  color: var(--silkscreen-3);
  margin: 5px 0 0;
  max-width: none;
}


/* ============================================================================
   6. SKIP LINK · PROGRESS · CONTROL CLUSTER
   ========================================================================= */

.skip {
  position: fixed;
  top: 0;
  left: var(--s3);
  z-index: 999;
  translate: 0 -140%;
  padding: 10px var(--s4);
  border-radius: 0 0 var(--r-pill) var(--r-pill);
  background: var(--signal);
  color: var(--signal-ink);
  font-family: var(--f-sans);
  font-weight: 600;
  font-size: .8125rem;
  line-height: 1;
  text-decoration: none;
  transition: translate var(--t-base) var(--ease);
}
.skip:focus { translate: 0 0; }

/* 2px fixed scroll-progress bar. main.js sets the inline width (0–100%). */
.progress {
  position: fixed;
  inset: 0 auto auto 0;
  z-index: 95;
  width: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--copper), var(--signal));
  pointer-events: none;
  will-change: width;
}

/* Top-right control cluster — opaque from first paint, no scroll-state
   transition, no hamburger, no nav strip (contract §1.8). */
.controls {
  position: fixed;
  top: var(--s3);
  right: var(--s3);
  z-index: 100;
  display: flex;
  align-items: center;
  gap: var(--s2);
}
@media (min-width: 768px) {
  .controls { top: var(--s4); right: var(--s4); }
}

.controls button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--trace-2);
  border-radius: var(--r-badge);
  background: var(--well);
  color: var(--silkscreen-2);
  transition: color var(--t-fast) linear,
              border-color var(--t-fast) linear,
              background-color var(--t-fast) linear;
}
.controls button:hover { color: var(--signal); border-color: var(--signal); }
.controls button svg { width: 16px; height: 16px; }

.ctrl__label {
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .65625rem;
  letter-spacing: .18em;
  line-height: 1;
  text-transform: uppercase;
}

/* <768px the console trigger is a 36×36 icon button with a visually hidden
   label. It is NOT hidden on mobile. */
@media (max-width: 767px) {
  #console-trigger .ctrl__label,
  #console-trigger kbd {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}
@media (min-width: 768px) {
  /* Wide "pill" form. Radius stays --r-badge: --r-pill is reserved for the
     skip link and the toast (contract §3). */
  #console-trigger {
    width: auto;
    padding-inline: var(--s3);
  }
}

/* Theme toggle icon swap — the two glyphs live in the button, CSS picks one. */
#theme-toggle .i-moon { display: none; }
#theme-toggle .i-sun  { display: block; }
:root[data-theme="light"] #theme-toggle .i-moon { display: block; }
:root[data-theme="light"] #theme-toggle .i-sun  { display: none; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) #theme-toggle .i-moon { display: block; }
  :root:not([data-theme]) #theme-toggle .i-sun  { display: none; }
}


/* ============================================================================
   7. HERO — contract §7.1
   ========================================================================= */

.hero {
  position: relative;
  isolation: isolate;
  overflow: clip;
  padding-block: clamp(72px, 9vw, 128px) clamp(56px, 7vw, 96px);
  border-bottom: 1px solid var(--trace);
  background:
    radial-gradient(120% 90% at 10% 0%,  var(--signal-dim), transparent 58%),
    radial-gradient(90% 70% at 92% 88%,  rgba(208, 138, 78, .06), transparent 62%);
}
.hero__inner { display: grid; grid-template-columns: 1fr; gap: 40px; }
.hero__text  { position: relative; z-index: 2; max-width: 46rem; min-width: 0; }
.hero__index { position: relative; z-index: 2; min-width: 0; }

@media (min-width: 1024px) {
  .hero__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 38%); }
  .hero__text  { grid-column: 1; }
  /* Column 1 only, and capped short of the board's horizontal span.
     Column 1 alone is not enough: the board element starts around 46% of the
     hero and its bright masked edge reaches back into column 1, washing out
     whichever item lands there (05 Contact at 1600px). Capping the width makes
     the strip wrap instead, so every item stays on clean background. */
  .hero__index { grid-column: 1; max-width: 30rem; }
}

/* Kicker + LED. Static glow, no unrequested motion. */
.hero__kicker {
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex-wrap: wrap;
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .6875rem;
  letter-spacing: .16em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--silkscreen-3);
  margin: 0 0 var(--s5);
  max-width: none;
}
.led {
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 0 3px var(--signal-dim), 0 0 10px var(--signal-halo);
}

/* H1 — sentence case, two forced block lines (contract §1.5). */
.hero__name {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: clamp(2.75rem, 8.4vw, 5.25rem);
  letter-spacing: -.01em;
  line-height: .92;
  text-transform: none;
  color: var(--silkscreen);
  margin: 0 0 var(--s5);
  overflow-wrap: break-word;
}
.hero__name > span { display: block; }

.hero__role {
  font-family: var(--f-mono);
  font-weight: 400;
  font-size: .8125rem;
  letter-spacing: .02em;
  line-height: 1.5;
  color: var(--silkscreen-2);
  margin: 0 0 var(--s5);
  max-width: none;
}
.hero__role > :first-child { color: var(--signal); }
.hero__role .sep { color: var(--trace-2); margin: 0 6px; }

.hero__blurb {
  font-family: var(--f-sans);
  font-weight: 400;
  font-size: clamp(1.0625rem, .4vw + .96rem, 1.25rem);
  letter-spacing: 0;
  line-height: 1.55;
  color: var(--silkscreen-2);
  max-width: 40ch;
  margin: 0 0 var(--s6);
}
.hero__blurb strong { color: var(--silkscreen); }

/* Link row — EMAIL · LINKEDIN · GITHUB · RÉSUMÉ
   Bordered pills, sized as real tap targets (>= 44px tall) and free to wrap
   down to 320px: each <li> may shrink, and the pill fills the cell it gets. */
.hero__links {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: var(--s3);
  margin: 0;
}
.hero__links li { min-width: 0; }
.hero__links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 12px clamp(14px, 2.4vw, 22px);
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .8125rem;
  letter-spacing: .14em;
  line-height: 1.1;
  text-transform: uppercase;
  color: var(--silkscreen);
  text-decoration: none;
  background: var(--well);
  border: 1px solid var(--trace-2);
  /* --r-pill is reserved for the skip link and the toast (contract §3). */
  border-radius: var(--r-chip);
  transition: color var(--t-fast) linear,
              border-color var(--t-fast) linear,
              background-color var(--t-fast) linear;
}
.hero__links a:hover,
.hero__links a:focus-visible {
  color: var(--signal);
  border-color: var(--signal);
  background: var(--soldermask-2);
}
.hero__links a .arw {
  width: 14px;
  height: 14px;
  color: var(--via);
  transition: color var(--t-fast) linear;
}
.hero__links a:hover .arw,
.hero__links a:focus-visible .arw { color: var(--signal); }

/* ── The index strip. Navigation, board legend and keyboard interface in one
      element (contract §7.3). Separators are hairline pseudo-elements. ── */
.hero__index {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  margin: 0;
}
.hero__index a {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .65625rem;
  letter-spacing: .18em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--silkscreen-3);
  text-decoration: none;
  padding-block: 6px;
  transition: color var(--t-fast) linear;
}
.hero__index a::before {
  content: "";
  width: 16px;
  height: 1px;
  flex: none;
  background: var(--trace-2);
  transition: background-color var(--t-fast) linear;
}
.hero__index a b { font-weight: 500; color: var(--copper); }
.hero__index a:hover,
.hero__index a:focus-visible { color: var(--signal); }
.hero__index a:hover::before,
.hero__index a:focus-visible::before { background: var(--signal); }
.hero__index a:hover b,
.hero__index a:focus-visible b { color: var(--signal); }


/* ============================================================================
   8. BOARD STAGE — contract §7.2 and §9
   Full-bleed background layer of the hero. No border, no radius, no visible
   bounding box in any state.
   ========================================================================= */

.board {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;          /* decoration by default */
  opacity: .34;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 46%, #000 92%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 46%, #000 92%, transparent 100%);
}
.board__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: pan-y;
}

@media (min-width: 1024px) {
  .board {
    inset: 0 -8vw 0 46%;         /* bleeds off the right edge, no border, no box */
    opacity: 1;
    pointer-events: auto;
    cursor: grab;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 22%, #000 86%, transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 22%, #000 86%, transparent 100%);
  }
  .board:active { cursor: grabbing; }
}

.board__still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--board-copper);
  transition: opacity .4s var(--ease), visibility .4s;
}

.board__hint {
  position: absolute;
  left: 50%;
  bottom: var(--s5);
  translate: -50% 0;
  margin: 0;
  max-width: none;
  opacity: 0;
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .65625rem;
  letter-spacing: .18em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--silkscreen-3);
  white-space: nowrap;
  pointer-events: none;
  transition: opacity var(--t-base) var(--ease);
  display: none;
}
@media (min-width: 1024px) {
  .board[data-board-state="live"] .board__hint { display: block; }
}

/* Test-pad label injected and positioned by the 3D module. */
.board__label {
  position: absolute;
  z-index: 3;
  padding: var(--s1) var(--s2);
  border: 1px solid var(--trace-2);
  border-radius: var(--r-badge);
  background: var(--well);
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .625rem;
  letter-spacing: .08em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--silkscreen);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--t-fast) linear;
}
.board__label[data-visible="true"] { opacity: 1; }

/* The module builds the label from three spans: the designator (U1), the part
   name, and an optional note. Without these they run together as one blob. */
.board__label-ref  { color: var(--pad); margin-right: var(--s2); }
.board__label-name { color: var(--silkscreen); }
.board__label-note {
  display: block;
  margin-top: 3px;
  font-size: .5625rem;
  letter-spacing: .06em;
  text-transform: none;
  color: var(--silkscreen-3);
}

/* ── State machine (contract §9) ── */
.board[data-board-state="live"]   .board__still { opacity: 0; visibility: hidden; }
.board[data-board-state="live"]   .board__hint  { opacity: 1; }
.board[data-board-state="static"] .board__hint  { display: none; }
.board[data-board-state="static"] .board__still { opacity: 1; visibility: visible; }
.board[data-board-state="still"]  { background: var(--board-still) center/cover no-repeat; }
.board[data-board-state="still"]  .board__still { opacity: 0; visibility: hidden; }
.board[data-board-state="still"]  .board__hint  { display: none; }

@media (prefers-reduced-motion: reduce) {
  .board__still { transition-duration: .01ms; }
}


/* ============================================================================
    9. 01 EXPERIENCE — timeline (never collapsible, contract §1.10)
   ========================================================================= */

.timeline { list-style: none; margin: 0; padding: 0; }

.tl {
  position: relative;
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  column-gap: 28px;
  padding: 0 0 40px;
}
.tl:last-child { padding-bottom: 0; }

.tl__body {
  min-width: 0;
  border-left: 1px solid var(--trace);
  padding-left: 28px;
}
.tl:last-child .tl__body { border-left-color: transparent; }

.tl__via {
  position: absolute;
  left: 118px;                    /* 96 + 28 − 6 */
  top: 5px;
  width: 11px;
  height: 11px;
  border: 2px solid var(--signal);
  border-radius: 50%;
  background: var(--soldermask);
  box-shadow: 0 0 0 0 var(--signal-dim);
  transition: box-shadow var(--t-base) var(--ease);
}
.tl:hover .tl__via,
.tl:focus-within .tl__via { box-shadow: 0 0 0 4px var(--signal-dim); }

.tl__when { color: var(--silkscreen-3); padding-top: var(--s1); margin: 0; max-width: none; }
.tl__when .now { color: var(--rail); }        /* "Present" marker — §6.1 */

.tl__role {
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(1.0625rem, .45vw + .98rem, 1.25rem);
  letter-spacing: -.01em;
  line-height: 1.2;
  color: var(--silkscreen);
  margin: 0 0 var(--s1);
}
.tl__org {
  font-family: var(--f-sans);
  font-size: .90625rem;
  font-weight: 500;
  color: var(--silkscreen-2);
  margin: 0 0 var(--s4);
  max-width: none;
}
.tl__loc { color: var(--silkscreen-3); font-weight: 400; }

/* Square copper pad markers, rotated 45° — a pad, not a dot. */
.tl__pts,
.pts {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
  display: grid;
  gap: 10px;
}
.tl__pts li,
.pts li {
  position: relative;
  padding-left: 18px;
  color: var(--silkscreen-2);
  max-width: 68ch;
}
.tl__pts li::before,
.pts li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .62em;
  width: 6px;
  height: 6px;
  border-radius: 1px;
  background: var(--copper);
  rotate: 45deg;
}
.tl__pts strong,
.pts strong { color: var(--silkscreen); font-weight: 600; }

@media (max-width: 639px) {
  .tl { grid-template-columns: minmax(0, 1fr); row-gap: var(--s2); padding-bottom: var(--s6); }
  .tl__body { border-left: 0; padding-left: 18px; }
  .tl__via  { left: 0; top: 34px; }
  .tl::after {                    /* rail moves to far left */
    content: "";
    position: absolute;
    left: 5px; top: 46px; bottom: var(--s2);
    width: 1px;
    background: var(--trace);
  }
  .tl:last-child::after { display: none; }
}


/* ============================================================================
   10. 02 PROJECTS — card grid, teardown control, pipeline
   ========================================================================= */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}
@media (max-width: 699px) {
  .grid { grid-template-columns: minmax(0, 1fr); }
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: var(--s5);
  border: 1px solid var(--trace);
  border-radius: var(--r-card);
  background: var(--soldermask-2);
  box-shadow: none;
  overflow: hidden;
  transition: border-color var(--t-fast) linear,
              translate    var(--t-base) var(--ease),
              box-shadow   var(--t-base) var(--ease);
}
@media (min-width: 720px) { .card { padding: 28px; } }

/* --signal left edge trace, 0 → 100% over 380ms. */
.card::before {
  content: "";
  position: absolute;
  left: -1px; top: 0;
  width: 2px; height: 0;
  background: var(--signal);
  transition: height var(--t-slow) var(--ease);
}
.card:hover,
.card:focus-within {
  border-color: var(--trace-2);
  translate: 0 -2px;
  box-shadow: var(--lift);
}
.card:hover::before,
.card:focus-within::before { height: 100%; }

.card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s4);
}
.card__idx {
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .6875rem;
  letter-spacing: .10em;
  line-height: 1;
  color: var(--copper);
}
.card__top .meta { text-align: right; margin: 0; }

.card__title {
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(1.1875rem, .7vw + 1.05rem, 1.5rem);
  letter-spacing: -.015em;
  line-height: 1.15;
  color: var(--silkscreen);
  margin: 0;
}
.card__role { color: var(--signal); margin: 6px 0 var(--s3); max-width: none; }
.card__desc { color: var(--silkscreen-2); margin: 0 0 18px; flex: 1 1 auto; }
.card .chips { margin-bottom: 18px; }

.card__open {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  align-self: flex-start;
  margin-top: auto;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .65625rem;
  letter-spacing: .18em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--silkscreen-3);
  transition: color var(--t-fast) linear;
}
.card:hover .card__open,
.card__open:hover,
.card__open:focus-visible { color: var(--signal); }

/* Repo / external link on a project card. Sits under the teardown affordance
   and deliberately reads quieter than it: the teardown is the primary action,
   this is a secondary escape hatch to the source. --via keeps it distinct from
   the signal-green used for the in-page action. */
.card__link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  align-self: flex-start;
  margin-top: var(--s2);
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .65625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--silkscreen-3);
  text-decoration: none;
  transition: color var(--t-fast) var(--ease);
  word-break: break-all;
}
.card__link .ext { color: var(--via); flex: none; transition: translate var(--t-base) var(--ease); }
.card__link:hover,
.card__link:focus-visible { color: var(--via); }
.card__link:hover .ext { translate: 2px -2px; }
.card__open .arw { transition: translate var(--t-base) var(--ease); }
.card:hover .card__open .arw { translate: 3px 0; }

/* Detail block: visible inline in the HTML; main.js adds [hidden] and clones
   it into the dialog on open. Never author display:none here. */
.card__detail {
  margin-top: var(--s5);
  padding-top: var(--s5);
  border-top: 1px solid var(--trace);
}
.card__detail > :last-child { margin-bottom: 0; }

/* Pipeline strip — its own overflow-x container, never the page's. */
.pipeline {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin: var(--s4) 0 0;
  padding-bottom: var(--s2);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  list-style: none;
}
.pipeline__step {
  flex: none;
  padding: 6px 10px;
  border: 1px solid var(--trace);
  border-radius: var(--r-chip);
  background: var(--well);
  font-family: var(--f-mono);
  font-size: .6875rem;
  letter-spacing: .02em;
  line-height: 1;
  color: var(--silkscreen-2);
  white-space: nowrap;
}
.pipeline__arrow { flex: none; color: var(--silkscreen-3); }


/* ============================================================================
   11. CHIPS — shared by timeline, cards and 03 Stack
   Non-interactive: no hover, no links, no monogram badges (contract §1.12).
   ========================================================================= */

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 9px;
  border: 1px solid var(--trace);
  border-radius: var(--r-chip);
  background: var(--well);
  font-family: var(--f-mono);
  font-weight: 400;
  font-size: .75rem;
  letter-spacing: .01em;
  line-height: 1;
  text-transform: none;             /* preserve casing: C++, ESP-IDF, openFrameworks */
  color: var(--silkscreen-2);
  white-space: nowrap;
}


/* ============================================================================
   12. 03 STACK — filter bar + grouped chip clouds
   ========================================================================= */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 28px;
}
.filter {
  height: 30px;
  padding: 0 var(--s3);
  border: 1px solid var(--trace);
  border-radius: var(--r-chip);
  background: var(--well);
  color: var(--silkscreen-2);
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .6875rem;
  letter-spacing: .14em;
  line-height: 1;
  text-transform: uppercase;
  cursor: pointer;
  transition: color var(--t-fast) linear,
              border-color var(--t-fast) linear,
              background-color var(--t-fast) linear;
}
.filter:hover { color: var(--signal); border-color: var(--signal); }
.filter[aria-pressed="true"] {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--signal-ink);
}

.bom__group + .bom__group { margin-top: 28px; }
.bom__head {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin: 0 0 var(--s3);
}
.bom__name {
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .65625rem;
  letter-spacing: .18em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--silkscreen-3);
  flex: none;
}
.bom__rule { flex: 1 1 auto; height: 1px; background: var(--trace); }
.bom__count {
  font-family: var(--f-mono);
  font-weight: 400;
  font-size: .65625rem;
  line-height: 1;
  color: var(--silkscreen-3);
  flex: none;
}


/* ============================================================================
   13. 04 EDUCATION — the spec sheet
   ========================================================================= */

.sheet {
  display: grid;
  grid-template-columns: 160px minmax(0, 1fr);
  margin: 0;
  border-top: 1px solid var(--trace);
}
.sheet dt {
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .65625rem;
  letter-spacing: .18em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--silkscreen-3);
  padding: 18px var(--s4) 18px 0;
  border-bottom: 1px solid var(--trace);
  align-self: center;
}
.sheet dd {
  margin: 0;
  min-width: 0;
  padding: var(--s4) 0;
  color: var(--silkscreen);
  border-bottom: 1px solid var(--trace);
  overflow-wrap: break-word;
}

@media (max-width: 559px) {
  .sheet { grid-template-columns: minmax(0, 1fr); }
  .sheet dt {
    padding: var(--s4) 0 var(--s1);
    border-bottom: 0;
  }
  .sheet dd { padding: 0 0 var(--s4); }
}


/* ============================================================================
   14. 05 CONTACT — the pinout
   ========================================================================= */

.pinout {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--trace);
}
.pin {
  display: grid;
  grid-template-columns: 28px 108px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s4);
  min-height: 56px;
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--trace);
}
.pin:hover { background: var(--soldermask-2); }

.pin__no {
  font-family: var(--f-mono);
  font-weight: 400;
  font-size: .71875rem;
  letter-spacing: .04em;
  line-height: 1;
  color: var(--silkscreen-3);
  font-variant-numeric: tabular-nums;
}
.pin__sig {
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .65625rem;
  letter-spacing: .18em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--silkscreen-3);
}
.pin__val {
  min-width: 0;
  color: var(--silkscreen);
  overflow-wrap: break-word;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.pin__val a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--signal);
  overflow-wrap: anywhere;
}
.pin__val a .arw { color: var(--via); }
.pin__val .mask {
  font-family: var(--f-mono);
  letter-spacing: .12em;
  color: var(--silkscreen-3);
}
.pin__note { color: var(--silkscreen-3); }

.pin__act { justify-self: end; display: flex; gap: var(--s2); }

.pin__btn,
.copy {
  height: 28px;
  padding: 0 10px;
  border: 1px solid var(--trace-2);
  border-radius: var(--r-chip);
  background: var(--well);
  color: var(--silkscreen-2);
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .625rem;
  letter-spacing: .12em;
  line-height: 1;
  text-transform: uppercase;
  cursor: pointer;
  transition: color var(--t-fast) linear, border-color var(--t-fast) linear;
}
.pin__btn:hover,
.copy:hover { color: var(--signal); border-color: var(--signal); }

@media (max-width: 519px) {
  .pin {
    grid-template-columns: 28px minmax(0, 1fr) auto;
    row-gap: var(--s2);
    padding: var(--s4) 0;
    align-items: center;
  }
  .pin__no  { grid-column: 1; grid-row: 1; }
  .pin__sig { grid-column: 2 / -1; grid-row: 1; }
  .pin__val { grid-column: 2; grid-row: 2; }
  .pin__act { grid-column: 3; grid-row: 2; }
}


/* ============================================================================
   15. FOOTER
   ========================================================================= */

.foot {
  border-top: 1px solid var(--trace);
  background: var(--ground);
  padding-block: var(--s6);
  font-family: var(--f-mono);
  font-weight: 400;
  font-size: .6875rem;
  letter-spacing: .06em;
  line-height: 1.5;
  color: var(--silkscreen-3);
}
.foot__boot {
  display: grid;
  gap: var(--s1);
  margin: 0 0 var(--s5);
  color: var(--silkscreen-3);
}
.foot__boot li,
.foot__boot p { margin: 0; max-width: none; overflow-wrap: break-word; }

.foot__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3) var(--s5);
}
.foot a { color: var(--silkscreen-2); text-decoration: none; }
.foot a:hover { color: var(--signal); text-decoration: underline; }


/* ============================================================================
   16. DIALOGS — teardown + console (contract §10)
   ========================================================================= */

dialog {
  padding: 0;
  border: 1px solid var(--trace-2);
  border-radius: var(--r-card);
  background: var(--soldermask-2);
  color: var(--silkscreen-2);
  box-shadow: var(--lift-2);
  overflow: hidden;
}
dialog::backdrop { background: var(--scrim); }
dialog[open] { animation: dlg-in 180ms var(--ease-io) both; }
dialog[open]::backdrop { animation: dlg-fade 180ms var(--ease-io) both; }

@keyframes dlg-in {
  from { opacity: 0; translate: 0 8px; }
  to   { opacity: 1; translate: 0 0; }
}
@keyframes dlg-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ── Teardown dialog ── */
#teardown-dialog {
  width: min(640px, calc(100vw - 32px));
  max-height: min(80vh, 720px);
}
/* Scoped to [open]: a bare `display: flex` here would beat the UA
   `dialog:not([open]) { display: none }` and leave the dialog on screen. */
#teardown-dialog[open] { display: flex; flex-direction: column; }
.dlg__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s5);
  border-bottom: 1px solid var(--trace);
  background: var(--well);
  flex: none;
}
.dlg__idx {
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .6875rem;
  letter-spacing: .10em;
  line-height: 1;
  color: var(--copper);
  margin: 0 0 var(--s2);
  max-width: none;
}
.dlg__title {
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(1.1875rem, .7vw + 1.05rem, 1.5rem);
  letter-spacing: -.015em;
  line-height: 1.15;
  color: var(--silkscreen);
  margin: 0;
}
.dlg__role { color: var(--signal); margin: 6px 0 0; max-width: none; }
.dlg__close {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--trace-2);
  border-radius: var(--r-badge);
  background: var(--soldermask-2);
  color: var(--silkscreen-2);
  transition: color var(--t-fast) linear, border-color var(--t-fast) linear;
}
.dlg__close:hover { color: var(--signal); border-color: var(--signal); }
.dlg__close svg { width: 14px; height: 14px; }
.dlg__body {
  padding: var(--s5);
  overflow-y: auto;
  overscroll-behavior: contain;
  flex: 1 1 auto;
}
.dlg__body > :last-child { margin-bottom: 0; }
.dlg__body .card__detail {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* ── Console ── */
#console {
  width: min(560px, calc(100vw - 32px));
  max-height: min(76vh, 640px);
  margin: 12vh auto auto;
}
#console[open] { display: flex; flex-direction: column; }
.console__form { display: block; flex: none; }
#console-input {
  width: 100%;
  height: 52px;
  padding: 0 var(--s4);
  border: 0;
  border-bottom: 1px solid var(--trace);
  border-radius: 0;
  background: var(--well);
  color: var(--silkscreen);
  font-family: var(--f-sans);
  font-size: 16px;              /* prevents the iOS zoom-on-focus */
  line-height: 1;
  outline-offset: -2px;
}
#console-input::placeholder { color: var(--silkscreen-3); opacity: 1; }

.console__list,
#console-list {
  list-style: none;
  margin: 0;
  padding: var(--s2) 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  flex: 1 1 auto;
}
.console__group {
  padding: var(--s3) var(--s4) 6px;
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .59375rem;
  letter-spacing: .18em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--silkscreen-3);
}
.console__item,
.console__opt {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: 10px var(--s4);
  cursor: pointer;
  color: var(--silkscreen-2);
  box-shadow: inset 2px 0 0 transparent;
  transition: background-color var(--t-fast) linear, color var(--t-fast) linear;
}
.console__label,
.console__opt-label { flex: 1 1 auto; min-width: 0; font-size: .90625rem; }
.console__meta,
.console__opt-hint {
  flex: none;
  font-family: var(--f-mono);
  font-size: .65625rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--silkscreen-3);
}
.console__item .arw,
.console__item .ext,
.console__opt .arw { color: var(--via); }
.console__item:hover,
.console__item.is-active,
.console__item[aria-selected="true"],
.console__opt:hover,
.console__opt.is-active,
.console__opt[aria-selected="true"] {
  background: var(--signal-dim);
  color: var(--silkscreen);
  box-shadow: inset 2px 0 0 var(--signal);
}
.console__empty {
  padding: var(--s5) var(--s4);
  color: var(--silkscreen-3);
  margin: 0;
}
.console__hint {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4);
  margin: 0;
  padding: var(--s2) var(--s4);
  border-top: 1px solid var(--trace);
  background: var(--well);
  color: var(--silkscreen-3);
  flex: none;
  max-width: none;
}

@media (max-width: 767px) {
  #console {
    inset: 0;
    width: 100%;
    max-width: none;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    border: 0;
    border-radius: 0;
  }
}


/* ============================================================================
   17. TOAST
   ========================================================================= */

#toast,
.toast {
  position: fixed;
  left: 50%;
  bottom: var(--s5);
  translate: -50% var(--s3);
  z-index: 200;
  max-width: calc(100vw - 32px);
  padding: 10px var(--s4);
  border: 1px solid var(--trace-2);
  border-radius: var(--r-pill);
  background: var(--well);
  color: var(--silkscreen);
  font-family: var(--f-mono);
  font-size: .75rem;
  letter-spacing: .04em;
  line-height: 1;
  box-shadow: var(--lift);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--t-base) var(--ease),
              translate var(--t-base) var(--ease),
              visibility var(--t-base);
}
#toast.is-on,
.toast.is-on {
  opacity: 1;
  visibility: visible;
  translate: -50% 0;
}
/* The only failure state on the page. --rail amber; there is no red token.
   main.js emits `is-warn`; both names are honoured. */
#toast.is-warn,
.toast.is-warn,
#toast.is-err,
.toast.is-err {
  border-color: var(--rail);
  color: var(--rail);
}


/* ============================================================================
   18. REVEAL — JS-on initial state authored under html.js (contract §11.1)
   Never author opacity: 0 unconditionally: with JS off the page must be whole.
   ========================================================================= */

.reveal { opacity: 1; }
html.js .reveal {
  opacity: 0;
  translate: 0 12px;
  transition: opacity 480ms var(--ease), translate 480ms var(--ease);
}
html.js .reveal.is-in {
  opacity: 1;
  translate: 0 0;
}


/* ============================================================================
   19. FOCUS · SELECTION · SCROLLBARS
   ========================================================================= */

:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
  border-radius: 3px;
}
/* Never `outline: none` anywhere. Non-keyboard focus simply gets no ring. */
:focus:not(:focus-visible) { outline: none; }

.board__canvas:focus-visible { outline-offset: -4px; }

::selection { background: var(--signal); color: var(--signal-ink); text-shadow: none; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--ground); }
::-webkit-scrollbar-thumb {
  background: var(--trace-2);
  border: 3px solid var(--ground);
  border-radius: var(--r-pill);
}
::-webkit-scrollbar-thumb:hover { background: var(--silkscreen-3); }
::-webkit-scrollbar-corner { background: var(--ground); }


/* ============================================================================
   20. 404 PAGE
   ========================================================================= */

.e404 {
  min-height: 100svh;
  display: grid;
  place-items: center;
  text-align: center;
  padding: var(--s7) 0;
}
.e404 .wrap { display: grid; justify-items: center; gap: var(--s5); }
.e404__kicker {
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: .65625rem;
  letter-spacing: .18em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--silkscreen-3);
  margin: 0;
  max-width: none;
}
.e404__code {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: clamp(3.5rem, 16vw, 8rem);
  letter-spacing: -.02em;
  line-height: 1;
  color: var(--signal);
  margin: 0;
}
.e404__msg {
  color: var(--silkscreen-2);
  max-width: 46ch;
  margin: 0;
}
.e404__hint {
  font-family: var(--f-mono);
  font-size: .6875rem;
  letter-spacing: .06em;
  line-height: 1.5;
  color: var(--silkscreen-3);
  margin: 0;
  max-width: none;
}

/* Shared button — used by the 404 return link. Radius matches chips/filters. */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  height: 40px;
  padding: 0 18px;
  border: 1px solid var(--trace-2);
  border-radius: var(--r-chip);
  background: var(--well);
  color: var(--silkscreen);
  font-family: var(--f-sans);
  font-weight: 500;
  font-size: .875rem;
  letter-spacing: .01em;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: color var(--t-fast) linear,
              border-color var(--t-fast) linear,
              background-color var(--t-fast) linear,
              translate var(--t-base) var(--ease);
}
.btn:hover { color: var(--signal); border-color: var(--signal); translate: 0 -1px; }
.btn--primary {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--signal-ink);
  font-weight: 600;
}
.btn--primary:hover { color: var(--signal-ink); filter: brightness(1.08); }


/* ============================================================================
   21. REDUCED MOTION — contract §11.3
   A backstop, not the mechanism: main.js reads the query once and branches.
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal,
  html.js .reveal { opacity: 1 !important; translate: none !important; }
}


/* ============================================================================
   22. PRINT
   ========================================================================= */

@media print {
  html, body {
    background: #fff !important;
    background-image: none !important;
    color: #000;
  }
  .skip,
  .progress,
  .controls,
  .board,
  .filters,
  .card__open,
  .pin__act,
  .pipeline,
  #toast,
  dialog { display: none !important; }

  main, .foot { position: static; }

  .hero { padding-block: 0 24pt; border-bottom: 1px solid #999; background: none; }
  .hero__name { font-size: 28pt; color: #000; }
  .hero__index { display: none; }

  .sec { padding-block: 18pt; border-top: 1px solid #999; break-inside: avoid; }
  .sec__title, .card__title, .tl__role { color: #000; }
  .sec__desig { border-color: #999; background: none; color: #000; }
  .sec__kind, .meta, .silkscreen, .dim { color: #444; }

  .card {
    border: 1px solid #999;
    background: none;
    box-shadow: none;
    break-inside: avoid;
  }
  .card::before { display: none; }
  .card__detail { display: block !important; }

  .chip { border-color: #999; background: none; color: #000; }
  .pin, .sheet dt, .sheet dd { border-color: #999; color: #000; }
  .hero__links a { border-color: #999; background: none; color: #000; }

  a { color: #000; text-decoration: underline; }
  .reveal, html.js .reveal { opacity: 1 !important; translate: none !important; }

  .foot { background: none; border-top: 1px solid #999; color: #444; }
}
