/* =============================================================================
   jiaenchai.com — page shell
   Dark editorial layout around a pixel-art game canvas.
   No external requests: system fonts only, all texture is CSS or inline SVG.
   ============================================================================= */

/* ---- Tokens --------------------------------------------------------------- */

:root {
  /* Surfaces — near-black with a faint cool cast so the gold accent reads warm */
  --ink-900: #08090b;
  --ink-850: #0b0d10;
  --ink-800: #101317;
  --ink-750: #14181d;
  --ink-700: #1b2027;

  /* Ink */
  --text:    #e9e7e2;
  --text-2:  #b4b2ab;
  --text-3:  #86847d;

  /* Lines */
  --line:        rgba(233, 231, 226, 0.10);
  --line-soft:   rgba(233, 231, 226, 0.06);
  --line-strong: rgba(233, 231, 226, 0.20);

  /* One accent, used sparingly */
  --accent:      #d9a441;
  --accent-lift: #f0bd63;
  --accent-dim:  rgba(217, 164, 65, 0.16);
  --accent-haze: rgba(217, 164, 65, 0.10);

  /* Type */
  --font-display: ui-serif, "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, Cambria, "Times New Roman", serif;
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", "Courier New", monospace;

  --step--1: 0.8125rem;
  --step-0:  1rem;
  --step-1:  clamp(1.0625rem, 0.99rem + 0.35vw, 1.1875rem);
  --step-2:  clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);
  --step-3:  clamp(1.625rem, 1.4rem + 1.1vw, 2.25rem);
  --step-4:  clamp(2.5rem, 1.6rem + 4.4vw, 5.25rem);

  /* Space & measure */
  --gutter: clamp(1.25rem, 5vw, 3.5rem);
  --wrap: 74rem;
  --measure: 68ch;
  --rule: 1px solid var(--line);
}

/* ---- Reset ---------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  color-scheme: dark;
}

body {
  margin: 0;
  background-color: var(--ink-900);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.65;
  letter-spacing: 0.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* Very soft light source at the top of the page, behind everything. */
body::before {
  content: "";
  position: fixed;
  inset: -20vh -10vw auto;
  height: 90vh;
  background:
    radial-gradient(60% 55% at 50% 0%, rgba(217, 164, 65, 0.09), transparent 70%),
    radial-gradient(90% 60% at 50% 0%, rgba(120, 150, 190, 0.06), transparent 75%);
  pointer-events: none;
  z-index: 0;
}

h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg, canvas { display: block; max-width: 100%; }

a {
  color: inherit;
  /* The underline is the only thing separating a link from body text, so it
     has to be visible on its own — a 20%-alpha rule (~1.7:1) is not. */
  text-decoration-color: rgba(217, 164, 65, 0.75);
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
  transition: color 0.18s ease, text-decoration-color 0.18s ease;
}
a:hover { color: var(--accent-lift); text-decoration-color: currentColor; }

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

::selection { background: rgba(217, 164, 65, 0.28); color: #fff; }

/* ---- Layout primitives ---------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

main { position: relative; z-index: 1; }

.section {
  border-top: var(--rule);
  padding-block: clamp(3rem, 7vw, 6rem);
  position: relative;
  z-index: 1;
}

/* Editorial two-column grid: label rail on the left, content on the right. */
.rgrid { display: grid; gap: 1.25rem 3rem; }

@media (min-width: 62rem) {
  .rgrid { grid-template-columns: 13rem minmax(0, 1fr); }
  .rgrid__side { position: sticky; top: 5.5rem; align-self: start; }
}

.rgrid--block {
  padding-top: clamp(2.25rem, 5vw, 3.5rem);
  margin-top: clamp(2.25rem, 5vw, 3.5rem);
  border-top: 1px solid var(--line-soft);
}

/* ---- Type ----------------------------------------------------------------- */

.eyebrow,
.index,
.chip,
.role__period,
.bezel__label,
.bezel__meta,
.chapters__n,
.contact__k,
.legend__title,
.nav__list,
.mark__name,
kbd {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.eyebrow {
  color: var(--accent);
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  margin-bottom: clamp(1rem, 2.5vw, 1.75rem);
}

.index {
  color: var(--text-3);
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  margin-bottom: 0.5rem;
}

.display {
  font-family: var(--font-display);
  font-size: var(--step-4);
  line-height: 0.94;
  letter-spacing: -0.025em;
  font-weight: 400;
  margin: 0;
}

h2 {
  font-family: var(--font-display);
  font-size: var(--step-3);
  line-height: 1.1;
  letter-spacing: -0.015em;
  font-weight: 400;
}

.sub {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 400;
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: var(--text);
}

.lead {
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.45;
  letter-spacing: -0.005em;
  color: var(--text);
  max-width: 34ch;
  text-wrap: balance;
}

.lead--sm {
  font-size: var(--step-1);
  line-height: 1.62;
  max-width: var(--measure);
  color: var(--text-2);
  text-wrap: pretty;
}

.note {
  color: var(--text-3);
  font-size: var(--step--1);
  line-height: 1.7;
  max-width: 56ch;
  letter-spacing: 0.01em;
}

/* ---- Skip link ------------------------------------------------------------ */

.skip-link {
  position: fixed;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 100;
  padding: 0.6rem 1rem;
  background: var(--accent);
  color: #14100a;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  text-decoration: none;
  border-radius: 4px;
  transform: translateY(-160%);
  transition: transform 0.18s ease;
}
.skip-link:focus { transform: translateY(0); color: #14100a; }

/* ---- Top bar -------------------------------------------------------------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--ink-900) 78%, transparent);
  backdrop-filter: saturate(140%) blur(12px);
  -webkit-backdrop-filter: saturate(140%) blur(12px);
  border-bottom: var(--rule);
}

.topbar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 3.5rem;
}

.mark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--text);
}
.mark__glyph { color: var(--accent); flex: none; }
.mark__name { font-size: 0.75rem; letter-spacing: 0.18em; }
.mark:hover { color: var(--text); }
.mark:hover .mark__glyph { color: var(--accent-lift); }

.nav__list { display: flex; gap: clamp(0.9rem, 3vw, 1.75rem); }
.nav__list a {
  color: var(--text-3);
  text-decoration: none;
  font-size: 0.6875rem;
  padding-block: 0.35rem;
}
.nav__list a:hover { color: var(--text); }

/* ---- Hero ----------------------------------------------------------------- */

.hero { padding-block: clamp(3rem, 9vw, 7rem) clamp(2.5rem, 6vw, 4.5rem); }

.hero__head { max-width: var(--wrap); }

.hero__head .lead { margin-top: clamp(1.25rem, 3vw, 1.75rem); }

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  margin-top: 1.5rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--text-3);
}
.hero__meta li { display: flex; align-items: center; }
.hero__meta li:not(:last-child)::after {
  content: "";
  width: 3px;
  height: 3px;
  margin-left: 1.5rem;
  margin-right: -0.75rem;
  background: var(--line-strong);
  border-radius: 50%;
}
.hero__meta a { color: var(--text-2); text-decoration-color: rgba(217, 164, 65, 0.75); }

/* ---- The cabinet (game hero) ---------------------------------------------- */

.cabinet {
  position: relative;
  margin: clamp(2.5rem, 6vw, 4rem) 0 0;
}

/* Ambient glow spilling out from behind the screen */
.cabinet::before {
  content: "";
  position: absolute;
  inset: 4% -4% 18%;
  background: radial-gradient(60% 60% at 50% 40%, var(--accent-haze), transparent 72%);
  filter: blur(48px);
  pointer-events: none;
}

.cabinet > * { position: relative; }

.cabinet__glass {
  padding: clamp(0.5rem, 1.4vw, 1rem);
  border-radius: 14px;
  border: 1px solid var(--line-strong);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0) 32%),
    linear-gradient(180deg, var(--ink-750), var(--ink-850) 70%, var(--ink-900));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 2px 4px rgba(0, 0, 0, 0.4),
    0 42px 80px -46px rgba(0, 0, 0, 0.95);
}

.screen {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
  overflow: hidden;
  border-radius: 7px;
  background: #05070a;
  display: grid;
  place-items: center;
  /* place-items alone only centres the canvas inside its auto-sized grid row;
     the row itself would still be start-aligned, parking the canvas against the
     top of the bezel whenever the renderer picks a smaller integer scale. */
  place-content: center;
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.9),
    inset 0 0 44px rgba(0, 0, 0, 0.75);
}

/* The renderer may set explicit pixel dimensions for integer scaling; the
   max-* clamps keep it inside the bezel and object-fit keeps 16:9 either way. */
#game {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  background: #05070a;
  image-rendering: crisp-edges;
  image-rendering: pixelated;
  touch-action: manipulation;
}
#game:focus-visible { outline-offset: -4px; }

/* Fallback text if canvas is unsupported */
#game p {
  color: var(--text-2);
  font-size: var(--step--1);
  padding: 2rem;
  text-align: center;
}

/* Sized to the *picture*, not to the whole bezel: integer scaling leaves black
   letterbox bars inside .screen and the scanlines must not run over them.
   render.js publishes --cq-screen-w/h whenever it resizes the canvas. */
.crt {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: var(--cq-screen-w, 100%);
  height: var(--cq-screen-h, 100%);
  max-width: 100%;
  max-height: 100%;
  pointer-events: none;
}

.crt--scan {
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.34) 0px,
    rgba(0, 0, 0, 0.34) 1px,
    rgba(0, 0, 0, 0) 1px,
    rgba(0, 0, 0, 0) 3px
  );
  background-size: 100% 3px;
  opacity: 0.55;
  animation: scan-drift 9s linear infinite;
}

.crt--vignette {
  background:
    radial-gradient(115% 115% at 50% 50%, rgba(0, 0, 0, 0) 42%, rgba(0, 0, 0, 0.55) 100%),
    radial-gradient(140% 90% at 50% 0%, rgba(255, 255, 255, 0.04), transparent 55%);
}

.crt--glare {
  background: linear-gradient(
    158deg,
    rgba(255, 255, 255, 0.10) 0%,
    rgba(255, 255, 255, 0.035) 16%,
    rgba(255, 255, 255, 0) 42%
  );
  mix-blend-mode: screen;
  opacity: 0.85;
}

@keyframes scan-drift {
  from { background-position: 0 0; }
  to   { background-position: 0 3px; }
}

.cabinet__bezel {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.7rem 0.35rem 0.15rem;
  color: var(--text-3);
}
.bezel__label {
  font-size: 0.625rem;
  letter-spacing: 0.18em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bezel__meta {
  margin-left: auto;
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  /* --line-strong is a 20%-alpha *line* token: ~1.7:1 as text. --text-3 is the
     dimmest ink that still clears WCAG 1.4.3 (≈5.3:1) on this backdrop. */
  color: var(--text-3);
  white-space: nowrap;
}
.led {
  width: 6px; height: 6px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px rgba(217, 164, 65, 0.9);
  animation: led-pulse 3.2s ease-in-out infinite;
}
@keyframes led-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

/* Sound switch + focus hint sitting under the cabinet. The in-canvas pause
   menu is not a discoverable audio control on its own (WCAG 1.4.2). */
.cabinet__tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1rem;
  margin-top: 1rem;
}
.switch {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-2);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.4rem 0.9rem;
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
.switch:hover { color: var(--text); border-color: var(--accent); }
.switch[aria-pressed="true"] { color: var(--accent); border-color: var(--accent-dim); }
.cabinet__hint {
  color: var(--text-3);
  font-size: var(--step--1);
  line-height: 1.6;
  max-width: 54ch;
}

.cabinet__cap {
  margin-top: 1.25rem;
  color: var(--text-3);
  font-size: var(--step--1);
  line-height: 1.7;
  max-width: 62ch;
}

/* Touch controls mount point — the input module injects buttons in here and
   only shows them on coarse pointers. Kept out of the way otherwise. */
#touch-controls {
  position: relative;
  display: none;
  margin-top: 0.75rem;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}
@media (pointer: coarse) {
  #touch-controls { display: block; }
}
#touch-controls:empty { display: none; }

/* ---- Fullscreen ------------------------------------------------------------
   main.js puts `cq-fs` on <body> and that is the entire mechanism — the
   Fullscreen API is deliberately not used, so the browser keeps its chrome and
   the behaviour is the same on every platform. The cabinet is pinned over the
   viewport, the page around it is stripped, and the picture takes every pixel
   left after the D-pad. */

body.cq-fs { overflow: hidden; }

/* Everything the cabinet is covering is also removed from the tab order and
   from the scroll, so a fullscreen player cannot fall out of the game. */
body.cq-fs .skip-link,
body.cq-fs .topbar,
body.cq-fs .hero__head,
body.cq-fs .chapters,
body.cq-fs .section,
body.cq-fs .footer,
body.cq-fs .cabinet__bezel,
body.cq-fs .cabinet__cap,
body.cq-fs .cabinet__hint,
body.cq-fs::before { display: none; }

/* With everything else gone, collapsing the hero's padding leaves the document
   barely a pixel tall — belt and braces against iOS Safari, which does not
   always honour `overflow: hidden` on <body>. */
body.cq-fs .hero { padding-block: 0; }

body.cq-fs .cabinet {
  position: fixed;
  inset: 0;
  z-index: 100;
  margin: 0;
  display: flex;
  flex-direction: column;
  background: #05070a;
  padding:
    env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px)
    env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}
body.cq-fs .cabinet::before { display: none; }

body.cq-fs .cabinet__glass {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: #05070a;
  box-shadow: none;
}

/* The screen keeps its 16:9 shape rather than swallowing the whole column. On a
   portrait phone the picture is limited by width — a 390px viewport can only
   ever be 219px of picture — so letting .screen grow would just bank 400px of
   black bar. Capping it hands that height to the D-pad instead. In landscape
   max-height takes over and the picture fills the viewport. */
body.cq-fs .screen {
  flex: 0 1 auto;
  width: 100%;
  height: auto;
  max-height: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 0;
  box-shadow: none;
}

/* The sound and fullscreen switches stay reachable (WCAG 1.4.2 / no trap),
   floated over the top-right corner of the picture rather than under it. */
body.cq-fs .cabinet__tools {
  position: absolute;
  top: 0.5rem;
  right: 0.6rem;
  z-index: 3;
  margin: 0;
  gap: 0.4rem;
}
body.cq-fs .switch {
  font-size: 0.625rem;
  padding: 0.3rem 0.7rem;
  background: rgba(6, 8, 12, 0.78);
  backdrop-filter: blur(4px);
}

body.cq-fs #touch-controls {
  flex: none;
  margin: 0;
  padding: 0 clamp(0.5rem, 3vw, 1.5rem);
}

/* Portrait phone: the space the 16:9 cap freed up goes to the controls, which
   grow with it. This is the layout the fullscreen switch exists for. */
@media (orientation: portrait) and (pointer: coarse) {
  /* The controls keep their natural height at the bottom of the phone and the
     glass takes the rest, which centres the picture in the space above them.
     Widths are viewport-relative so the pad and the A/B pair always fit on one
     row — a capped pixel size overflows and pushes A off a narrow screen. */
  body.cq-fs #cq-touch {
    min-height: 0;
    padding: 44px 0 max(24px, env(safe-area-inset-bottom, 0px));
  }
  body.cq-fs #cq-touch .cq-pad { width: min(40vw, 200px); height: min(40vw, 200px); }
  body.cq-fs #cq-touch .cq-round {
    width: min(19vw, 88px);
    height: min(19vw, 88px);
    font-size: min(5.5vw, 26px);
  }
  body.cq-fs #cq-touch .cq-b { margin-bottom: min(8vw, 34px); }
  body.cq-fs #cq-touch .cq-pause { width: 54px; height: 38px; }
}

/* Landscape on a phone has no vertical room to stack the pad under the picture,
   so the controls float over it instead. #cq-touch is already pointer-events:
   none apart from the buttons themselves, so the picture stays untouched. */
@media (orientation: landscape) and (pointer: coarse) {
  body.cq-fs #touch-controls {
    position: absolute;
    inset: auto 0 0 0;
    z-index: 2;
  }
  body.cq-fs #cq-touch {
    padding: 0 0 max(6px, env(safe-area-inset-bottom, 0px));
    min-height: 0;
  }
  body.cq-fs #cq-touch .cq-pad { width: 128px; height: 128px; }
  body.cq-fs #cq-touch .cq-round { width: 58px; height: 58px; font-size: 18px; }
  body.cq-fs #cq-touch .cq-b { margin-bottom: 22px; }
  /* Top-right belongs to the sound/fullscreen switches now; drop pause into the
     gap between the pad and the A/B pair rather than the middle of the picture. */
  body.cq-fs #cq-touch .cq-pause {
    top: auto;
    bottom: 0;
    right: auto;
    left: 50%;
    transform: translateX(-50%);
  }
}

/* ---- Chapter rail --------------------------------------------------------- */

.chapters {
  margin-top: clamp(2rem, 5vw, 3rem);
  border-top: var(--rule);
  padding-top: 1rem;
}
.chapters__list {
  display: flex;
  gap: 0.4rem;
  overflow-x: auto;
  scrollbar-width: thin;
  padding-bottom: 0.5rem;
  -webkit-overflow-scrolling: touch;
}
.chapters__list a {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  white-space: nowrap;
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  font-size: 0.75rem;
  color: var(--text-3);
  text-decoration: none;
  transition: border-color 0.18s ease, color 0.18s ease, background-color 0.18s ease;
}
.chapters__list a:hover {
  color: var(--text);
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.03);
}
.chapters__n {
  font-size: 0.625rem;
  color: var(--accent);
  letter-spacing: 0.12em;
}

/* ---- Controls legend ------------------------------------------------------ */

.legend {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3rem);
  margin-top: 1.75rem;
}
@media (min-width: 48rem) {
  .legend { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

.legend__title {
  font-size: 0.6875rem;
  color: var(--accent);
  letter-spacing: 0.2em;
  margin-bottom: 1rem;
  font-weight: 400;
}
.legend__col p { color: var(--text-2); font-size: var(--step--1); line-height: 1.75; }
.legend__col p + p { margin-top: 0.85rem; }
.legend__col strong { color: var(--text); font-weight: 600; }

.keys { display: grid; gap: 0; }
.keys__row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding-block: 0.6rem;
  border-bottom: 1px solid var(--line-soft);
}
.keys__row dt {
  flex: 1 1 9rem;
  color: var(--text-2);
  font-size: var(--step--1);
}
.keys__row dd { display: flex; align-items: center; flex-wrap: wrap; gap: 0.3rem; margin: 0; }

kbd {
  display: inline-block;
  min-width: 1.8rem;
  padding: 0.2rem 0.45rem;
  text-align: center;
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: none;
  color: var(--text);
  background: var(--ink-750);
  border: 1px solid var(--line-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
  line-height: 1.4;
}
.keys__or {
  font-family: var(--font-sans);
  font-size: 0.6875rem;
  color: var(--text-3);
  padding-inline: 0.15rem;
}

/* ---- Résumé --------------------------------------------------------------- */

.role {
  display: grid;
  gap: 0.85rem 2.5rem;
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  border-top: 1px solid var(--line-soft);
}
.role:first-child { border-top: 0; padding-top: 0; }

@media (min-width: 48rem) {
  .role { grid-template-columns: 11.5rem minmax(0, 1fr); }
}

.role__meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.9rem; }
@media (min-width: 48rem) {
  .role__meta { display: block; padding-top: 0.3rem; }
}

.role__period {
  color: var(--accent);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  white-space: nowrap;
}
.role__loc {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--text-3);
  letter-spacing: 0;
  text-transform: none;
  margin-top: 0.25rem;
}
.chip {
  display: inline-block;
  margin-top: 0.6rem;
  padding: 0.1rem 0.4rem;
  font-size: 0.5625rem;
  letter-spacing: 0.16em;
  color: var(--text-3);
  border: 1px solid var(--line-soft);
  border-radius: 3px;
}

.role__title {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: -0.005em;
  color: var(--text);
}
.role__company {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  color: var(--text-2);
  margin-top: 0.3rem;
}

.bullets {
  margin-top: 1.1rem;
  display: grid;
  gap: 0.7rem;
  max-width: var(--measure);
}
.bullets li {
  position: relative;
  padding-left: 1.15rem;
  color: var(--text-2);
  font-size: 0.9375rem;
  line-height: 1.7;
  text-wrap: pretty;
}
.bullets li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 5px;
  height: 5px;
  background: var(--accent);
  opacity: 0.75;
}

/* ---- Skills / tags -------------------------------------------------------- */

.skills { display: grid; gap: 1.75rem; }
@media (min-width: 48rem) {
  .skills { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem 3rem; }
}

.skills__title {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.9rem;
}

.tags { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.tags li {
  padding: 0.32rem 0.65rem;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--text-2);
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
}

.pair { display: grid; gap: 1.75rem; }
@media (min-width: 48rem) {
  .pair { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 3rem; }
}

/* ---- Contact -------------------------------------------------------------- */

.contact { display: grid; gap: 0; max-width: 34rem; }
.contact li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1.5rem;
  padding-block: 0.85rem;
  border-bottom: 1px solid var(--line-soft);
}
.contact__k {
  flex: 0 0 6rem;
  font-size: 0.625rem;
  color: var(--text-3);
  letter-spacing: 0.18em;
}
.contact__v {
  font-family: var(--font-display);
  font-size: var(--step-1);
  color: var(--text);
}

/* ---- Footer --------------------------------------------------------------- */

.footer {
  border-top: var(--rule);
  padding-block: 2.5rem 3.5rem;
  position: relative;
  z-index: 1;
}
.footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2rem;
  justify-content: space-between;
  align-items: baseline;
}
.footer__note {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: var(--text-3);
}

/* ---- Anchor offset (sticky header) ---------------------------------------- */

[id] { scroll-margin-top: 5.5rem; }

/* ---- Narrow screens ------------------------------------------------------- */

@media (max-width: 26rem) {
  :root { --gutter: 1.125rem; }
  .mark__name { display: none; }
  .hero__meta { gap: 0.25rem 1rem; }
  .cabinet__glass { border-radius: 11px; }
  .bezel__meta { display: none; }
}

/* ---- Reduced motion ------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .crt--scan { animation: none; opacity: 0.4; }
  .led { animation: none; opacity: 0.9; }
}

/* ---- Print (a clean, ink-friendly résumé) --------------------------------- */

@media print {
  :root { --text: #000; --text-2: #1a1a1a; --text-3: #4a4a4a; --accent: #000; }
  body { background: #fff; color: #000; font-size: 10.5pt; line-height: 1.4; }
  body::before, .topbar, .cabinet, .chapters, #play, .skip-link, .footer__note a { display: none !important; }
  .section { border-top: 0; padding-block: 0; }
  .hero { padding-block: 0 0.5rem; }
  .rgrid { display: block; }
  .rgrid--block { margin-top: 1rem; padding-top: 0.75rem; border-top: 1px solid #ccc; }
  .rgrid__side { position: static; margin-bottom: 0.5rem; }
  .role { display: block; border-top: 0; padding-block: 0 0.75rem; page-break-inside: avoid; }
  .role__meta { display: block; }
  .chip { display: none; }
  .tags li { border-color: #bbb; background: none; }
  a { text-decoration: none; }
  .display { font-size: 24pt; }
}
