/* Hallmark · pre-emit critique: P5 H4 E4 S5 R4 V5
 * Hallmark · route: custom (bespoke) · structure: "the portfolio is a television" — full-viewport channels,
 * no page scroll, bottom channel deck, real static zapping between channels
 * idea: "cambias de canal y sale otra sección" · studied lineage: press-01 anaglyph DNA (kept)
 * paper: oklch(13% 0.006 260) · accent: signal red oklch(62% 0.19 25) · anaglyph inks red/cyan
 * display: Bricolage Grotesque variable · numerals: Fraunces · machine: JetBrains Mono
 * axes: dark / display-heavy / warm+cool anaglyph · gates: pass (user-mandated: no-scroll TV structure)
 * contrast: pass (40–41) · honest: pass (46 — cert/xp slots labelled) · tokens: pass (48)
 */
@import url("tokens.css");

/* ————— base · the set is a television ————— */
*, *::before, *::after { box-sizing: border-box; }

html, body {
  height: 100%;
  overflow: clip;
}

body {
  margin: 0;
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.6;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  font-style: normal;
  line-height: 1.08;
  letter-spacing: -0.015em;
  margin: 0;
  overflow-wrap: anywhere;
  min-width: 0;
}

p { margin: 0; }

a {
  color: var(--color-ink);
  text-decoration-color: var(--color-rule);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color var(--dur-micro) var(--ease-out),
              text-decoration-color var(--dur-micro) var(--ease-out);
}
a:hover { color: var(--color-accent); text-decoration-color: var(--color-accent); }
a:active { color: var(--color-neutral); }

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

::selection { background: var(--color-accent); color: var(--color-accent-ink); }

/* ————— the static — an always-on canvas of TV snow ————— */
.static {
  position: fixed;
  inset: 0;
  z-index: var(--z-toast);
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0.022;
  mix-blend-mode: screen;
  image-rendering: pixelated;
  transition: opacity 80ms linear;
}
body.is-zapping .static { opacity: 0.6; }

/* ————— on-screen display ————— */
.osd {
  position: fixed;
  top: var(--space-md);
  right: var(--space-lg);
  z-index: var(--z-raised);
  font-family: var(--font-outlier);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--color-ink);
  pointer-events: none;
}

/* ————— the screen and its channels ————— */
.screen {
  position: fixed;
  inset: 0 0 var(--deck-h) 0;
}
.channel {
  position: absolute;
  inset: 0;
  display: none;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.channel.is-live { display: block; }

.channel { scroll-snap-type: y proximity; }

.channel__inner {
  position: relative;
  max-width: 72rem;
  margin-inline: auto;
  padding: var(--space-2xl) calc(var(--page-gutter) + var(--film-rail) + var(--space-md));
  min-height: 100%;
}

/* ————— the filmstrip — sprocket rails that travel with the content,
   visible only while the reel rolls ————— */
:root { --film-rail: 3rem; }
.channel__inner::before,
.channel__inner::after {
  content: "";
  position: absolute;
  inset-block: 0;
  width: var(--film-rail);
  opacity: 0;
  background-color: var(--color-paper-2);
  background-image: radial-gradient(
    ellipse 34% 22% at 50% 50%,
    var(--color-paper) 96%,
    transparent 100%
  );
  background-size: 100% 42px;
  background-repeat: repeat-y;
  border-inline: var(--rule-hair) solid var(--color-rule);
  transition: opacity 650ms var(--ease-out);
  pointer-events: none;
}
.channel__inner::before { inset-inline-start: calc(var(--page-gutter) - var(--space-md)); }
.channel__inner::after  { inset-inline-end: calc(var(--page-gutter) - var(--space-md)); }

/* rolling: the strip fades in fast; when the reel stops it dissolves away */
body.rolling .channel__inner::before,
body.rolling .channel__inner::after {
  opacity: 1;
  transition-duration: 110ms;
}

/* frames advance with a gentle magnetic snap — like pulling film through a gate */
.lib, .essays li, .xp__row, .stack__group, .cert, .webcard, .portrait {
  scroll-snap-align: start;
  scroll-margin-top: var(--space-xl);
}

/* while the reel is rolling, the projector breathes */
body.rolling .static { opacity: 0.05; }

/* zapping — quick and soft: the picture dissolves into blurred snow, the next one condenses out of it */
.channel.zap-out {
  display: block;
  animation: zap-out 130ms var(--ease-in) forwards;
}
.channel.zap-in {
  display: block;
  animation: zap-in 200ms var(--ease-out);
}
@keyframes zap-out {
  0%   { filter: none; opacity: 1; transform: none; }
  55%  { transform: translateY(-8px) skewX(-0.8deg); }         /* vertical hold slips */
  100% { filter: blur(7px) brightness(1.35) saturate(1.5); opacity: 0; transform: scale(1.01) translate(-4px, 14px); }
}
@keyframes zap-in {
  0%   { filter: blur(8px) brightness(1.5) saturate(1.6); opacity: 0; transform: scale(1.015) translate(4px, -12px); }
  40%  { transform: translateY(6px) skewX(0.6deg); }           /* the frame overshoots, then locks */
  55%  { filter: blur(2px) brightness(1.1) saturate(1.1); opacity: 1; }
  100% { filter: none; transform: none; }
}

/* the elements themselves glitch into place while the channel lands */
.channel.zap-in .channel__inner > *,
.channel.zap-in .specimen__center > * {
  animation: elem-glitch 260ms steps(3);
}
.channel.zap-in .channel__inner > *:nth-child(even),
.channel.zap-in .specimen__center > *:nth-child(even) {
  animation-name: elem-glitch-rev;
  animation-duration: 300ms;
}
@keyframes elem-glitch {
  0%   { transform: translateX(-7px); }
  40%  { transform: translateX(5px) skewX(-0.6deg); }
  75%  { transform: translateX(-2px); }
  100% { transform: none; }
}
@keyframes elem-glitch-rev {
  0%   { transform: translateX(8px); }
  40%  { transform: translateX(-5px) skewX(0.6deg); }
  75%  { transform: translateX(2px); }
  100% { transform: none; }
}

/* display heads land with their plates blown apart, then register */
.channel.zap-in .plate__title,
.channel.zap-in .specimen__name {
  animation: head-split 300ms steps(3);
}

/* ambient misbehaviour — JS taps a random element every few seconds */
.tic { animation: elem-glitch 240ms steps(3); }
.tic-split { animation: head-split 300ms steps(3); }
/* a reception hiccup: the whole screen shudders and the snow thickens for a blink */
body.hiccup .static { opacity: 0.16; }
body.hiccup .screen { transform: translateX(2px); }
@keyframes head-split {
  0%   { text-shadow: 10px 0 0 var(--ghost-red), -10px 0 0 var(--ghost-cyan); }
  50%  { text-shadow: -7px 0 0 var(--ghost-red), 7px 0 0 var(--ghost-cyan); }
  100% { text-shadow: 0 0 0 var(--ghost-red), 0 0 0 var(--ghost-cyan); }
}

/* ————— CH 00 · the specimen ————— */
#ch0 {
  overflow: hidden;
  display: none;
  place-items: center;
}
#ch0.is-live, #ch0.zap-out, #ch0.zap-in { display: grid; }

.orbs {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.orb {
  position: absolute;
  top: 50%;
  left: 50%;
  width: clamp(19rem, 54vmin, 32rem);
  aspect-ratio: 1;
  border-radius: 50%;
  mix-blend-mode: screen;
}
.orb::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
}
.orb--red { transform: translate(calc(-50% - 34% + var(--ox, 0px)), -58%); }
.orb--red::before {
  background: color-mix(in oklch, var(--ghost-red) 46%, transparent);
  animation: orb-path-a 26s var(--ease-in-out) infinite;
}
.orb--cyan { transform: translate(calc(-50% + 34% - var(--ox, 0px)), -42%); }
.orb--cyan::before {
  background: color-mix(in oklch, var(--ghost-cyan) 46%, transparent);
  animation: orb-path-b 34s var(--ease-in-out) infinite;
}
@keyframes orb-path-a {
  0%   { translate: 0 0;        scale: 1;    }
  25%  { translate: 70px 30px;  scale: 1.06; }
  50%  { translate: 90px -30px; scale: 1.1;  }
  75%  { translate: 20px -55px; scale: 1.04; }
  100% { translate: 0 0;        scale: 1;    }
}
@keyframes orb-path-b {
  0%   { translate: 0 0;          scale: 1;    }
  25%  { translate: -60px -40px;  scale: 1.08; }
  50%  { translate: -95px 20px;   scale: 1.02; }
  75%  { translate: -30px 55px;   scale: 1.09; }
  100% { translate: 0 0;          scale: 1;    }
}
.ring {
  position: absolute;
  top: 48%;
  left: 50%;
  width: clamp(30rem, 86vmin, 52rem);
  aspect-ratio: 1 / 0.82;
  translate: -50% -50%;
  border-radius: 50%;
  border: 1.5px solid color-mix(in oklch, var(--ghost-red) 55%, transparent);
  opacity: 0.5;
  animation: ring-turn 42s linear infinite;
}
.ring::before {
  content: "";
  position: absolute;
  inset: -1.5px;
  translate: 5px 3px;
  border-radius: 50%;
  border: 1.5px solid color-mix(in oklch, var(--ghost-cyan) 55%, transparent);
}
@keyframes ring-turn { to { rotate: 360deg; } }

.specimen__center {
  position: relative;
  z-index: 1;
  text-align: center;
  max-width: 46rem;
  padding-inline: var(--page-gutter);
}
.specimen__plate {
  font-family: var(--font-outlier);
  font-size: var(--text-xs);
  color: var(--color-neutral);
}
.specimen__name {
  margin-top: var(--space-lg);
  font-size: var(--text-specimen);
  line-height: 1.06;
  letter-spacing: -0.025em;
  font-variation-settings: "wght" var(--spec-wght), "wdth" var(--spec-wdth), "opsz" var(--spec-opsz);
  /* clean at rest — the plates only pull apart under the pointer lean and glitches */
  text-shadow:
    calc(var(--ax, 0px))      calc(var(--ay, 0px))       0 var(--ghost-red),
    calc(-1 * var(--ax, 0px)) calc(-1 * var(--ay, 0px))  0 var(--ghost-cyan);
  animation: name-float 9s var(--ease-in-out) infinite alternate;
  cursor: default;
  user-select: none;
}
@keyframes name-float {
  from { transform: translateY(-6px); }
  to   { transform: translateY(7px); }
}
.specimen__role {
  margin-top: var(--space-lg);
  margin-inline: auto;
  color: var(--color-neutral);
  font-size: var(--text-md);
  max-width: 52ch;
}

/* ————— plate furniture (shared by channels) ————— */
.plate__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin-bottom: var(--space-xl);
}
.plate-num {
  font-family: var(--font-numeral);
  font-weight: 600;
  font-size: var(--text-lg);
  line-height: 1;
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
}
.specimen__plate .plate-num { display: inline; font-size: inherit; margin-inline-end: var(--space-sm); }
.plate__title { font-size: var(--text-2xl); }
.plate__note { color: var(--color-neutral); max-width: 58ch; }

/* the 3D-glasses register — clean at rest; the plates pull apart on touch and glitch */
.lib__name a:hover,
.webcard:hover .webcard__name {
  text-shadow: 4px 0 0 var(--ghost-red), -4px 0 0 var(--ghost-cyan);
  transition: text-shadow var(--dur-short) var(--ease-out);
}
.portrait__slot { transition: box-shadow var(--dur-short) var(--ease-out); }
.portrait__slot:hover {
  box-shadow: 3px 0 0 -1px var(--ghost-red), -3px 0 0 -1px var(--ghost-cyan);
}

/* ————— CH 01 · libraries ————— */
.lib {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
  gap: var(--space-lg) var(--space-2xl);
  align-items: center;
  padding-block: var(--space-xl);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.lib--flip { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
.lib--flip .lib__fig { order: 2; }
.lib--flip .lib__body { order: 1; }

.lib__fig {
  display: block;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-md);
  background: var(--color-paper-2);
  padding: var(--space-lg);
  transition: border-color var(--dur-short) var(--ease-out);
}
.lib__fig:hover, .lib__fig:focus-visible {
  border-color: var(--color-accent);
  box-shadow: 4px 0 0 -1px var(--ghost-red), -4px 0 0 -1px var(--ghost-cyan);
}

.fig { display: block; width: 100%; height: auto; }
.ana { transition: transform var(--dur-long) var(--ease-out); }
.ana--red  { fill: var(--ghost-red);  transform: translateX(0); }
.ana--cyan { fill: var(--ghost-cyan); transform: translateX(0); }
.ana--main { fill: var(--color-ink); }
.ana--main .cut { fill: var(--color-paper-2); }

.lib__fig:hover .ana--red,
.lib__fig:focus-visible .ana--red  { transform: translateX(-7px); }
.lib__fig:hover .ana--cyan,
.lib__fig:focus-visible .ana--cyan { transform: translateX(7px); }

.fig--merge .ana--red,
.fig--merge .ana--cyan { mix-blend-mode: screen; }
.lib__fig:hover .fig--merge .ana--red,
.lib__fig:focus-visible .fig--merge .ana--red  { transform: translateX(14px); }
.lib__fig:hover .fig--merge .ana--cyan,
.lib__fig:focus-visible .fig--merge .ana--cyan { transform: translateX(-14px); }

.fig--stroke .ana { fill: none; stroke-width: 10; stroke-linecap: round; }
.fig--stroke .ana--red  { stroke: var(--ghost-red); }
.fig--stroke .ana--cyan { stroke: var(--ghost-cyan); }
.fig--stroke .ana--main { stroke: var(--color-ink); }

.lib__name { font-size: var(--text-xl); }
.lib__name a { text-decoration: none; }
.lib__name a:hover { color: var(--color-accent); }
.lib__meta {
  font-family: var(--font-outlier);
  font-size: var(--text-xs);
  color: var(--color-neutral);
  margin-top: var(--space-xs);
  font-variant-numeric: tabular-nums;
}
.lib__desc { color: var(--color-neutral); margin-top: var(--space-sm); max-width: 58ch; }
.lib__links { display: flex; flex-wrap: wrap; gap: var(--space-lg); margin-top: var(--space-md); }
.lib__links a { font-size: var(--text-sm); white-space: nowrap; }

/* ————— CH 06 · articles ————— */
.essays {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 62rem;
  border-top: var(--rule-hair) solid var(--color-rule);
}
.essays li { border-bottom: var(--rule-hair) solid var(--color-rule); }
.essay {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--space-lg);
  min-height: 44px;
  padding: var(--space-md) var(--space-2xs);
  text-decoration: none;
}
.essay__idx {
  font-family: var(--font-numeral);
  font-size: var(--text-md);
  color: var(--color-neutral);
  font-variant-numeric: tabular-nums;
}
.essay__title {
  display: block;
  font-weight: 600;
  font-size: var(--text-md);
  line-height: 1.3;
  transition: color var(--dur-micro) var(--ease-out), text-shadow var(--dur-short) var(--ease-out);
}
.essay__meta {
  display: block;
  margin-top: var(--space-2xs);
  font-family: var(--font-outlier);
  font-size: var(--text-xs);
  color: var(--color-neutral);
}
.essay__arrow {
  color: var(--color-neutral);
  font-size: var(--text-sm);
  transition: transform 200ms ease, color 200ms ease;
}
.essay:hover .essay__title { color: var(--color-accent); text-shadow: 3px 0 0 var(--ghost-red), -3px 0 0 var(--ghost-cyan); }
.essay:hover .essay__arrow { color: var(--color-accent); transform: translate(2px, -2px); }
.more { display: inline-block; margin-top: var(--space-lg); font-size: var(--text-sm); white-space: nowrap; }

/* ————— CH 03 · webs ————— */
.webs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: var(--space-md);
}
.webcard {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-lg);
  background: var(--color-paper-2);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-md);
  text-decoration: none;
  transition: border-color var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out);
}
.webcard:hover {
  border-color: var(--color-accent);
  transform: translateY(-2px);
  box-shadow: 4px 0 0 -1px var(--ghost-red), -4px 0 0 -1px var(--ghost-cyan);
}
.webcard__name { font-family: var(--font-display); font-weight: 700; font-size: var(--text-md); color: var(--color-ink); }
.webcard__url { font-family: var(--font-outlier); font-size: var(--text-xs); color: var(--color-neutral); }
.webcard__desc { color: var(--color-neutral); font-size: var(--text-sm); max-width: 40ch; }

/* ————— CH 04 · experience ————— */
.xp { max-width: 62ch; }
.xp__row { padding-block: var(--space-lg); border-top: var(--rule-hair) solid var(--color-rule); }
.xp__row:last-child { border-bottom: var(--rule-hair) solid var(--color-rule); }
.xp__role { font-size: var(--text-md); }
.xp__desc { color: var(--color-neutral); margin-top: var(--space-xs); }
.xp__row--slot .xp__role { color: var(--color-neutral); text-shadow: none; }
.xp__row--slot .xp__desc { font-family: var(--font-outlier); font-size: var(--text-xs); }

/* ————— CH 05 · stack ————— */
.stack { display: flex; flex-direction: column; gap: var(--space-xl); }
.stack__label {
  font-family: var(--font-outlier);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--color-neutral);
  margin-bottom: var(--space-sm);
}
.stack__chips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}
.stack__chips li {
  font-family: var(--font-outlier);
  font-size: var(--text-sm);
  color: var(--color-muted);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: 999px;
  padding: var(--space-2xs) var(--space-md);
  min-height: 2.25rem;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  transition: border-color var(--dur-micro) var(--ease-out), color var(--dur-micro) var(--ease-out);
}
.stack__chips li:hover { border-color: var(--color-accent); color: var(--color-ink); }

/* ————— CH 06 · certificates ————— */
.certs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
  gap: var(--space-md);
  max-width: 60rem;
}
.cert--slot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-lg);
  min-height: 8rem;
  border: var(--rule-hair) dashed var(--color-rule);
  border-radius: var(--radius-md);
}
.cert__dash { font-family: var(--font-numeral); font-size: var(--text-xl); color: var(--color-neutral); }
.cert__hint { font-family: var(--font-outlier); font-size: var(--text-xs); color: var(--color-neutral); }

/* ————— dead channels — nothing airing, the set fills with snow ————— */
.nosignal {
  min-height: 55vh;
  display: grid;
  place-content: center;
  text-align: center;
  gap: var(--space-md);
}
.nosignal__sign {
  font-family: var(--font-outlier);
  font-weight: 700;
  font-size: var(--text-xl);
  letter-spacing: 0.35em;
  padding-inline-start: 0.35em; /* optical centre against the tracking */
  color: var(--color-ink);
  animation: ns-blink 1.7s steps(2) infinite;
}
@keyframes ns-blink { 50% { opacity: 0.25; } }
.nosignal__note { font-family: var(--font-outlier); font-size: var(--text-xs); color: var(--color-neutral); }
/* while a dead channel is on air the snow takes the screen */
body.is-dead .static { opacity: 0.3; }
@media (prefers-reduced-motion: reduce) {
  .nosignal { background: var(--color-paper-2); border-radius: var(--radius-md); padding: var(--space-2xl); }
}

/* ————— CH 07 · portrait & contact ————— */
.portrait {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr);
  gap: var(--space-2xl);
  align-items: start;
}
.portrait__frame { margin: 0; max-width: 22rem; }
.portrait__slot {
  position: relative;
  aspect-ratio: 4 / 5;
  display: grid;
  place-items: center;
  background: var(--color-paper-2);
  border: var(--rule-hair) dashed var(--color-rule);
  border-radius: var(--radius-sm);
}
.portrait__img {
  width: 100%;
  height: auto;
  display: block;
  filter: grayscale(1) contrast(1.05);
  border-radius: var(--radius-sm);
}
.portrait__mark { position: absolute; top: var(--space-xs); left: var(--space-xs); color: var(--color-neutral); font-size: var(--text-md); }
.portrait__mark--tr { left: auto; right: var(--space-xs); }
.portrait__mark--bl { top: auto; bottom: var(--space-xs); }
.portrait__mark--br { top: auto; bottom: var(--space-xs); left: auto; right: var(--space-xs); }
.portrait__hint {
  font-family: var(--font-outlier);
  font-size: var(--text-xs);
  color: var(--color-neutral);
  padding: var(--space-md);
  text-align: center;
}
.portrait__cap { font-family: var(--font-outlier); font-size: var(--text-xs); color: var(--color-neutral); margin-top: var(--space-sm); }
.portrait__copy { color: var(--color-neutral); max-width: 48ch; }
.portrait__links { display: flex; flex-wrap: wrap; gap: var(--space-lg); margin-top: var(--space-lg); }
.portrait__links a { font-weight: 600; white-space: nowrap; }
.portrait__links a:hover,
.more:hover { text-shadow: 2px 0 0 var(--ghost-red), -2px 0 0 var(--ghost-cyan); }
.portrait__colophon {
  margin-top: var(--space-2xl);
  font-size: var(--text-sm);
  color: var(--color-neutral);
  max-width: 60ch;
}
.portrait__colophon a { white-space: nowrap; }

/* ————— the deck — channel controls ————— */
:root { --deck-h: 4.25rem; }
.deck {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  height: var(--deck-h);
  z-index: var(--z-sticky-nav);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);
  padding-inline: var(--space-md);
  background: color-mix(in oklch, var(--color-paper-2) 88%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.deck__step {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  line-height: 1;
  color: var(--color-neutral);
  background: none;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: 999px;
  min-width: 44px;
  min-height: 44px;
  cursor: pointer;
  transition: color var(--dur-micro) var(--ease-out), border-color var(--dur-micro) var(--ease-out);
}
.deck__step:hover {
  color: var(--color-ink);
  border-color: var(--color-accent);
  box-shadow: 2px 0 0 0 var(--ghost-red), -2px 0 0 0 var(--ghost-cyan);
}
.deck__step:active { color: var(--color-accent); }
.deck__step:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.deck__step:disabled { opacity: 0.55; cursor: not-allowed; }

.deck__chs { display: flex; gap: var(--space-2xs); }
.deck__ch {
  font-family: var(--font-outlier);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral);
  background: none;
  border: var(--rule-hair) solid transparent;
  border-radius: var(--radius-sm);
  min-width: 40px;
  min-height: 40px;
  cursor: pointer;
  transition: color var(--dur-micro) var(--ease-out), border-color var(--dur-micro) var(--ease-out);
}
.deck__ch:hover { color: var(--color-ink); border-color: var(--color-rule); }
.deck__ch:active { color: var(--color-accent); }
.deck__ch:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.deck__ch:disabled { opacity: 0.55; cursor: not-allowed; }
.deck__ch.is-on {
  color: var(--color-ink);
  border-color: var(--color-accent);
}
.deck__label {
  font-family: var(--font-outlier);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-neutral);
  min-width: 8ch;
  white-space: nowrap;
}

/* ————— CRT power-on — the dot, the line, the picture ————— */
.boot {
  position: fixed;
  inset: 0;
  z-index: var(--z-tooltip);
  background: #000;
  display: grid;
  place-items: center;
  pointer-events: none;
  animation: boot-fade 950ms var(--ease-out) forwards;
}
.boot::before {
  content: "";
  background: #fff;
  border-radius: 2px;
  box-shadow: 0 0 24px 6px rgba(255, 255, 255, 0.9);
  animation: boot-tube 900ms var(--ease-out) forwards;
}
@keyframes boot-tube {
  0%   { width: 0;     height: 4px; opacity: 0; }
  12%  { width: 6px;   height: 6px; opacity: 1; }               /* the dot */
  45%  { width: 100vw; height: 3px; opacity: 1; }               /* the line */
  78%  { width: 100vw; height: 100vh; opacity: 0.9; }           /* the picture */
  100% { width: 100vw; height: 100vh; opacity: 0; }
}
@keyframes boot-fade {
  0%, 82% { opacity: 1; }
  100%    { opacity: 0; visibility: hidden; }
}

/* ————— the glass — scanlines and a breath of vignette ————— */
.crt {
  position: fixed;
  inset: 0;
  z-index: var(--z-toast);
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.16) 0 1px,
    transparent 1px 3px
  );
  opacity: 0.45;
}
.crt::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 90% 90% at 50% 50%, transparent 62%, rgba(0, 0, 0, 0.32) 100%);
}

/* ————— the chyron — a broadcast lower third on CH 00 ————— */
.chyron {
  position: absolute;
  left: clamp(1.25rem, 6vw, 5rem);
  bottom: var(--space-2xl);
  z-index: 1;
  padding: var(--space-sm) var(--space-lg) var(--space-sm) var(--space-md);
  border-inline-start: 3px solid var(--color-accent);
  background: color-mix(in oklch, var(--color-paper-2) 90%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: chyron-in 600ms var(--ease-out) 350ms backwards;
}
.channel.zap-in .chyron { animation: chyron-in 500ms var(--ease-out) 180ms backwards; }
@keyframes chyron-in {
  from { transform: translateX(-18px); opacity: 0; }
}
.chyron__live {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-outlier);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.22em;
  color: var(--color-accent);
}
.chyron__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-accent);
  animation: rec-blink 1.4s steps(2) infinite;
}
@keyframes rec-blink { 50% { opacity: 0.2; } }
.chyron__name { font-family: var(--font-display); font-weight: 700; font-size: var(--text-md); margin-top: var(--space-2xs); }
.chyron__role { font-family: var(--font-outlier); font-size: var(--text-xs); color: var(--color-neutral); margin-top: var(--space-3xs); }

/* ————— footage counter — frames tick past while the reel rolls ————— */
.footage {
  position: fixed;
  left: var(--space-md);
  bottom: calc(var(--deck-h) + var(--space-sm));
  z-index: var(--z-raised);
  font-family: var(--font-outlier);
  font-size: var(--text-xs);
  color: var(--color-neutral);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  opacity: 0;
  transition: opacity 650ms var(--ease-out);
  pointer-events: none;
}
body.rolling .footage { opacity: 1; transition-duration: 110ms; }

/* ————— CH 99 · the test card ————— */
.testcard {
  position: fixed;
  inset: 0 0 var(--deck-h) 0;
  z-index: var(--z-sticky);
  display: grid;
  place-items: center;
  background: oklch(75% 0.02 260);
}
.testcard[hidden] { display: none; }
.testcard__bars {
  position: absolute;
  inset: 0;
  display: flex;
}
.testcard__bars span { flex: 1; }
.testcard__bars span:nth-child(1) { background: oklch(88% 0.01 260); }
.testcard__bars span:nth-child(2) { background: oklch(84% 0.16 100); }
.testcard__bars span:nth-child(3) { background: oklch(80% 0.13 210); }
.testcard__bars span:nth-child(4) { background: oklch(74% 0.19 145); }
.testcard__bars span:nth-child(5) { background: oklch(64% 0.24 335); }
.testcard__bars span:nth-child(6) { background: oklch(58% 0.21 27);  }
.testcard__bars span:nth-child(7) { background: oklch(44% 0.19 262); }
.testcard__circle {
  position: relative;
  width: min(58vmin, 26rem);
  aspect-ratio: 1;
  border-radius: 50%;
  border: 3px solid oklch(15% 0 0);
  background: oklch(20% 0.005 260);
  display: grid;
  place-content: center;
  text-align: center;
  gap: var(--space-xs);
}
.testcard__circle::before,
.testcard__circle::after {
  content: "";
  position: absolute;
  background: oklch(88% 0.01 260 / 0.25);
}
.testcard__circle::before { inset: 50% 6% auto; height: 1px; }
.testcard__circle::after  { inset: 6% auto auto 50%; width: 1px; height: 88%; }
.testcard__ch {
  font-family: var(--font-numeral);
  font-weight: 600;
  font-size: var(--text-3xl);
  color: oklch(92% 0.01 260);
}
.testcard__name {
  font-family: var(--font-outlier);
  font-size: var(--text-sm);
  letter-spacing: 0.3em;
  color: oklch(75% 0.01 260);
}
.testcard__hint {
  font-family: var(--font-outlier);
  font-size: var(--text-xs);
  color: oklch(60% 0.01 260);
}
body.is-test .static { opacity: 0.06; }

/* ————— teletext — the manuals, page by page ————— */
.txt {
  position: fixed;
  inset: 0 0 var(--deck-h) 0;
  z-index: var(--z-modal);
  overflow-y: auto;
  background: #0a0a0c;
  font-family: var(--font-outlier);
  color: #e8e8ea;
  padding: var(--space-lg) clamp(1.25rem, 6vw, 6rem) var(--space-2xl);
  line-height: 1.75;
}
.txt[hidden] { display: none; }
.txt__head {
  display: flex;
  justify-content: space-between;
  gap: var(--space-md);
  font-weight: 700;
  font-size: var(--text-sm);
  letter-spacing: 0.12em;
  margin-bottom: var(--space-xl);
}
.txt__pageno { color: #ffee00; }
.txt__brand { color: #0a0a0c; background: #2244ee; padding-inline: var(--space-sm); }
.txt__clock { color: #00e64d; font-variant-numeric: tabular-nums; }
.txt__title {
  font-family: var(--font-outlier);
  font-weight: 700;
  font-size: var(--text-lg);
  letter-spacing: 0.14em;
  color: #ffee00;
  background: #16161c;
  display: inline-block;
  padding-inline: var(--space-sm);
  margin-bottom: var(--space-lg);
}
.txt__row { max-width: 68ch; margin-top: var(--space-sm); font-size: var(--text-sm); }
.txt__row .txt-y { font-weight: 700; margin-inline-end: var(--space-sm); }
.txt__note { margin-top: var(--space-xl); font-size: var(--text-xs); letter-spacing: 0.1em; }
.txt-y { color: #ffee00; }
.txt-c { color: #00eaff; }
.txt-g { color: #00e64d; }
.txt code {
  font-family: inherit;
  color: #00eaff;
  background: none;
  border: none;
  padding: 0;
}
.txt a { color: #00eaff; text-decoration-color: #00eaff; }
.txt a:hover { color: #ffee00; text-decoration-color: #ffee00; }
.txt__fastext {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-top: var(--space-2xl);
}
.txt__fkey {
  font-family: var(--font-outlier);
  font-weight: 700;
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  color: #0a0a0c;
  border: none;
  padding: var(--space-xs) var(--space-md);
  min-height: 40px;
  cursor: pointer;
}
.txt__fkey--r { background: #ff3322; }
.txt__fkey--g { background: #00e64d; }
.txt__fkey--y { background: #ffee00; }
.txt__fkey--c { background: #00eaff; }
.txt__fkey:hover { filter: brightness(1.2); }
body.is-txt .static { opacity: 0.05; }

/* ————— deck extras — teletext & sound ————— */
.deck__txt {
  font-family: var(--font-outlier);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--color-neutral);
  background: none;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-sm);
  min-width: 44px;
  min-height: 40px;
  cursor: pointer;
  transition: color var(--dur-micro) var(--ease-out), border-color var(--dur-micro) var(--ease-out);
}
.deck__txt:hover { color: var(--color-ink); border-color: var(--color-accent); }
.deck__txt[aria-pressed="true"] { color: var(--color-ink); border-color: var(--color-accent); }
.deck__snd {
  font-family: var(--font-display);
  font-size: var(--text-base);
  color: var(--color-neutral);
  background: none;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: 999px;
  min-width: 40px;
  min-height: 40px;
  cursor: pointer;
  transition: color var(--dur-micro) var(--ease-out), border-color var(--dur-micro) var(--ease-out), opacity var(--dur-micro) var(--ease-out);
}
.deck__snd:hover { color: var(--color-ink); border-color: var(--color-accent); }
.deck__snd.is-off { opacity: 0.45; text-decoration: line-through; }

/* ————— responsive ————— */
@media (max-width: 64rem) {
  .portrait { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 40rem) {
  :root { --film-rail: 1.4rem; }
  .lib, .lib--flip { grid-template-columns: minmax(0, 1fr); }
  .lib--flip .lib__fig { order: 1; }
  .lib--flip .lib__body { order: 2; }
  .channel__inner { padding-block: var(--space-xl); }
  .deck { gap: var(--space-xs); }
  .deck__label { display: none; }
  .deck__ch { min-width: 34px; }
  .osd { font-size: var(--text-xs); }
  .chyron { left: var(--space-md); right: var(--space-md); bottom: var(--space-lg); }
  .footage { display: none; }
  .deck__snd { display: none; }
  .deck__txt { min-width: 36px; }
}
@media (pointer: coarse) {
  .lib__links a, .portrait__links a, .more { min-height: 44px; display: inline-flex; align-items: center; }
}

/* ————— reduced motion — the set stands still, channels cut instantly ————— */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 150ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 150ms !important;
  }
  .specimen__name { animation: none; --ax: 0px; --ay: 0px; }
  .orb::before, .ring { animation: none !important; }
  .ana { transition: none; }
  .static { display: none; }
  .channel.zap-out, .channel.zap-in { animation: none; }
  .boot { display: none; }
  .nosignal__sign, .chyron__dot { animation: none; }
  .footage { display: none; }
}
