/* ==========================================================================
   4ewdsr5y — BASE
   Reset, typography, page chrome (header / status bar / overlays), layout.
   No colour literals below this line — everything comes from theme.css.
   ========================================================================== */

/* --------------------------------------------------------------- 1. RESET */

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

/* The `hidden` attribute must always win. A UA stylesheet's
   [hidden]{display:none} loses to ANY author `display` rule, so a component
   that sets display:flex and hides itself with [hidden] stays laid out —
   invisible, but still capturing every click on the page. That is exactly
   what the loadout screen did. Author-level and !important so it cannot
   happen again. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scrollbar-color: var(--rule-mid) transparent;
  overflow-x: clip;
  /* Safari's grey box behind whatever is tapped, which on the corridor's
     floating words read as a glitch. Inherited, so this covers every link
     and button; the keyboard's focus rings are not affected. */
  -webkit-tap-highlight-color: transparent;
}

body {
  margin: 0;
  min-height: 100svh;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  font-variant-ligatures: none;
  -webkit-font-smoothing: antialiased;

  /* No overflow-x here. `html` already carries `overflow-x: clip`, which
     stops sideways scrolling without turning the element into a scroll
     container. `overflow-x: hidden` on body DOES create one, and a scroll
     container silently breaks `position: sticky` for everything inside it —
     which is exactly what happened: the sticky header scrolled away to
     top:-2984 on a long page and the sticky status bar only appeared once
     you reached the very bottom, taking the home mark, the cart trigger and
     the theme switch with them. Clip here, never hidden. */
}

h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }

img, svg, video { display: block; max-width: 100%; height: auto; }

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

a {
  color: inherit;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}

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

/* Focus is never removed — only restyled. Keyboard users must be able to
   see where they are, which is doubly true on a keyboard-driven interface. */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

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

/* ---------------------------------------------------------- 2. TYPOGRAPHY */

.t-2xs  { font-size: var(--fs-2xs); letter-spacing: var(--tr-wide); }
.t-xs   { font-size: var(--fs-xs);  letter-spacing: var(--tr-wide); }
.t-sm   { font-size: var(--fs-sm); }
.t-md   { font-size: var(--fs-md); }
.t-lg   { font-size: var(--fs-lg);  line-height: var(--lh-snug); }
.t-xl   { font-size: var(--fs-xl);  line-height: var(--lh-tight); }
.t-2xl  { font-size: var(--fs-2xl); line-height: var(--lh-tight); }

/* Display tier. Set tight and negatively tracked so a long word still holds
   together as one block of texture rather than drifting apart. */
.display {
  font-size: var(--fs-display);
  font-weight: 700;
  line-height: 0.86;
  letter-spacing: -0.045em;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}
.display-sm {
  font-size: var(--fs-display-sm);
  font-weight: 700;
  line-height: 0.92;
  letter-spacing: -0.035em;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}

.t-dim   { color: var(--fg-dim); }
.t-faint { color: var(--fg-faint); }
.t-sig   { color: var(--signal); }
.t-alert { color: var(--alert); }

.t-up    { text-transform: uppercase; letter-spacing: var(--tr-wide); }
.t-track { letter-spacing: var(--tr-wider); }
.t-tab   { font-variant-numeric: tabular-nums; }

/* Ambient telemetry. The ONLY place 11px is permitted. */
.t-telemetry {
  font-size: var(--fs-2xs);
  letter-spacing: var(--tr-wide);
  color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
  text-transform: uppercase;
}

/* A label above a block of content: "─── SPECIFICATION ───" */
.rule-label {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-xs);
  letter-spacing: var(--tr-wider);
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-bottom: var(--sp-4);
}
.rule-label::after {
  content: "";
  flex: 1;
  border-top: 1px solid var(--rule);
}

/* ------------------------------------------------------------- 3. LAYOUT */

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

/* Page shell: header, main, status bar. Main is what scrolls.

   position/z-index are load-bearing: a positioned layer such as
   .field-damage paints above non-positioned block content, so without a
   stacking context here the damage vignette would tint the copy at the
   screen edges. z-index:2 puts all shell content above it (the field layers
   sit at 0-1) while leaving the .hud corner telemetry at 4 on top, where it
   belongs. */
.shell {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}
.shell > main { flex: 1 0 auto; }

.stack > * + * { margin-top: var(--sp-4); }
.stack-lg > * + * { margin-top: var(--sp-6); }

.section { padding-block: var(--sp-8); }
.section-sm { padding-block: var(--sp-6); }

/* ------------------------------------------------- 4. BACKGROUND TEXTURE */

/* Fixed, non-interactive, painted behind everything. */
.field {
  position: fixed;
  inset: 0;
  z-index: var(--z-base);
  pointer-events: none;
}

/* CRT scanlines. Static — it does not animate, so there is no flicker to
   trip anyone up, and no continuous repaint cost. */
.field-scan {
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.22) 0px,
    rgba(0, 0, 0, 0.22) 1px,
    transparent 1px,
    transparent 3px
  );
  opacity: 0.5;
  mix-blend-mode: multiply;
}
:root[data-theme="light"] .field-scan { opacity: 0.22; }

/* The tape's tracking: one bright band sweeping down the picture, rarely.
   It is mostly absent — the keyframes hold it off-screen for the first 92%
   of the cycle and let it cross once — because a band that swept constantly
   would stop reading as a fault and start reading as a pattern.

   Landing only, and opt-in rather than a reduce override, so a visitor who
   asked for less motion is never handed an animation to override. */
.field-track {
  background-image: linear-gradient(
    to bottom,
    transparent 0%,
    rgba(255, 255, 255, 0.030) 38%,
    rgba(255, 255, 255, 0.065) 50%,
    rgba(255, 255, 255, 0.030) 62%,
    transparent 100%
  );
  background-repeat: no-repeat;
  background-size: 100% 190px;
  background-position: 0 -260px;
  mix-blend-mode: screen;
}

@media (prefers-reduced-motion: no-preference) {
  body:has(.stage) .field-track {
    animation: vhs-track 17s linear infinite;
  }
}

@keyframes vhs-track {
  0%, 92% { background-position: 0 -260px; }
  100%    { background-position: 0 115vh; }
}

.field-vig {
  background: radial-gradient(
    ellipse 100% 80% at 50% 45%,
    transparent 40%,
    var(--bg) 100%
  );
  opacity: 0.85;
}

/* --------------------------------------------------------- 5. HEADER BAR */

.hdr {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rule);
}

.hdr-in {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  height: 56px;
}

/* The minimal header is [mark][spacer][inventory]; without this the spacer
   does not grow and the inventory button collapses against the wordmark. */
.hdr-in > .spacer { margin-left: auto; }

.hdr-mark {
  font-size: var(--fs-md);
  letter-spacing: var(--tr-wide);
  font-weight: 700;
  white-space: nowrap;
}
.hdr-mark:hover { color: var(--signal); }

/* Blinking block cursor after the wordmark. */
.caret {
  display: inline-block;
  width: 0.55em;
  height: 1em;
  margin-left: 0.15em;
  background: var(--signal);
  vertical-align: -0.13em;
  animation: caret-blink 1.1s steps(1) infinite;
}
@keyframes caret-blink { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }

.hdr-nav {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  margin-left: auto;
}
.hdr-link {
  font-size: var(--fs-sm);
  letter-spacing: var(--tr-wide);
  color: var(--fg-dim);
  padding-block: var(--sp-2);
  position: relative;
}
.hdr-link:hover { color: var(--fg); }
.hdr-link[aria-current="page"] { color: var(--fg); }
.hdr-link[aria-current="page"]::before {
  content: "";
  position: absolute;
  left: -10px;
  top: 50%;
  transform: translateY(-50%);
  width: 4px; height: 4px;
  background: var(--signal);
}

.icon-btn {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border: 1px solid var(--rule);
  color: var(--fg-dim);
  transition: color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.icon-btn:hover { color: var(--fg); border-color: var(--rule-strong); }
.icon-btn svg { width: 15px; height: 15px; }

/* Mobile nav toggle is hidden until the breakpoint. */
.hdr-toggle { display: none; }

/* --------------------------------------------------------- 6. STATUS BAR */

.statusbar {
  position: sticky;
  bottom: 0;
  z-index: var(--z-header);
  border-top: 1px solid var(--rule);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(10px);
}
.statusbar-in {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  height: 34px;
  overflow: hidden;
  white-space: nowrap;
}
.statusbar-in > .spacer { margin-left: auto; }

/* Status-bar control. 24px tall to clear the WCAG minimum target size
   inside a 34px bar. */
.sb-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  height: 24px;
  padding-inline: var(--sp-3);
  border: 1px solid var(--rule);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tr-wide);
  color: var(--fg-dim);
  flex: none;
  transition: color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease);
}
.sb-btn:hover {
  color: var(--fg);
  border-color: var(--rule-strong);
  background: var(--signal-soft);
}
.sb-pip {
  width: 7px;
  height: 7px;
  flex: none;
  border: 1px solid currentColor;
  /* Half-filled disc: reads as a light/dark split. */
  background: linear-gradient(to right, currentColor 50%, transparent 50%);
  border-radius: 50%;
}

/* The tilt switch (only ever built on touch devices). The pip is empty when
   off, filled blood when live, and struck through when the device cannot
   supply motion at all. */
.sb-tilt .sb-pip { background: transparent; }
.sb-tilt[data-state="on"] { color: var(--fg); border-color: var(--signal-edge); }
.sb-tilt[data-state="on"] .sb-pip { background: var(--signal); border-color: var(--signal); }
.sb-tilt[data-state="unavailable"] { color: var(--fg-faint); }
.sb-tilt[data-state="unavailable"] .sb-pip {
  background: linear-gradient(135deg, transparent 45%, currentColor 45%, currentColor 55%, transparent 55%);
}

/* The switch costs the bar ~90px, and on a 375px phone that pushed the
   clock 7px off the right edge. .statusbar-in is overflow:hidden with
   nowrap, so it was clipped silently rather than wrapping — the digits were
   just cut off. The clock is ambient telemetry; the two switches are
   controls. It gives way, but only where the switch exists, so a desktop
   window at any width keeps its clock — and only beside the THEME switch
   too: with the dark theme switched off (js/theme-boot.js) there is none,
   and the clock fits beside MOTION even at 320 wide (measured 0px over). */
@media (max-width: 440px) {
  .statusbar-in:has(.sb-tilt):has([data-theme-toggle]) [data-clock] { display: none; }
}
/* NO MOTION is 32px wider than MOTION: on the narrowest phones the clock
   then ran 13px past the bar's edge (320 wide, measured), so there, and only
   while the switch says so, it gives way. */
@media (max-width: 340px) {
  .statusbar-in:has(.sb-tilt[data-state="unavailable"]) [data-clock] { display: none; }
}

.dot {
  display: inline-block;
  width: 6px; height: 6px;
  background: var(--ok);
  margin-right: var(--sp-2);
  vertical-align: 0.05em;
}

/* ------------------------------------------------------------- 7. FOOTER */

.ftr {
  border-top: 1px solid var(--rule);
  padding-block: var(--sp-7) var(--sp-6);
}
.ftr-grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5) var(--sp-7);
  align-items: flex-start;
}
.ftr-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
}
.ftr-links a { font-size: var(--fs-sm); color: var(--fg-dim); }
.ftr-links a:hover { color: var(--signal); }

/* ------------------------------------------------------- 8. RESPONSIVE */

@media (max-width: 860px) {
  .hdr-in { height: 52px; gap: var(--sp-3); }

  .hdr-toggle { display: grid; }

  /* Nav collapses into a panel dropped from the header. */
  .hdr-nav {
    position: fixed;
    inset: 52px 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin: 0;
    padding: var(--sp-2) var(--gutter) var(--sp-5);
    background: var(--bg-raised);
    border-bottom: 1px solid var(--rule);
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--dur) var(--ease),
                transform var(--dur) var(--ease),
                visibility var(--dur);
  }
  .hdr-nav[data-open="true"] {
    transform: none;
    opacity: 1;
    visibility: visible;
  }
  .hdr-link {
    font-size: var(--fs-md);
    padding-block: var(--sp-4);
    border-bottom: 1px solid var(--rule);
  }
  .hdr-link[aria-current="page"]::before { left: -12px; }

  .hdr-actions { margin-left: auto; display: flex; gap: var(--sp-2); }

  .statusbar-in { gap: var(--sp-4); }
}

/* ------------------------------------------------- 9. REDUCED MOTION */

/* Every animation this site defines is switched off here — not just the
   third-party ones. Transitions are collapsed rather than removed so
   state changes still register. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .caret { animation: none; opacity: 1; }
  .field-scan { display: none; }
  .pcard-plate::after { display: none; }
  .menu-item { transform: none !important; }
}

/* ------------------------------------------------------ 10. UTILITIES */

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Skip link — first tab stop on every page. */
.skip {
  position: absolute;
  left: var(--sp-4);
  top: -60px;
  z-index: var(--z-modal);
  background: var(--signal-fill);
  color: var(--signal-ink);
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm);
  letter-spacing: var(--tr-wide);
  transition: top var(--dur) var(--ease);
}
.skip:focus-visible { top: var(--sp-4); }

.flow-tight > * + * { margin-top: var(--sp-2); }
.measure { max-width: 62ch; }
