/* =============================================================
   pixel-mode.css — shared 8-bit "void world" theme layer.
   Activates ONLY when the root carries data-pixel="1" (set by the
   Konami code via void-mode.js), so default paint is untouched.

   Brand-consistency calls (ties go to brand):
   - The rainbow rule + purple accent tokens stay exactly as-is.
   - Body copy uses VT323 (legible pixel face); Press Start 2P is
     reserved for SHORT strings (nav, wordmark, pagination) where it
     won't overflow or break glyphs.
   ============================================================= */
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=VT323&display=swap');

/* ---- pixel shadow color, flips with theme ---- */
.vd[data-pixel="1"]              { --pxsh:#1C1917; --scan:rgba(0,0,0,.08); --line:var(--color-line); --accent:var(--color-accent); }
.vd[data-theme="dark"][data-pixel="1"] { --pxsh:#000;   --scan:rgba(255,255,255,.05); --line:var(--color-line); --accent:var(--color-accent); }

/* ---- type: VT323 everywhere, slightly looser tracking ----
   VT323 has a small x-height, so it reads smaller than IBM Plex at the same px.
   font-size-adjust scales the glyphs up to match a normal x-height ratio for
   legibility WITHOUT touching any of the px font-size values (layout stays put). */
.vd[data-pixel="1"],
.vd[data-pixel="1"] body,
.vd[data-pixel="1"] input,
.vd[data-pixel="1"] button,
.vd[data-pixel="1"] textarea {
  font-family:'VT323', ui-monospace, monospace !important;
  font-size-adjust:0.54;
  letter-spacing:.3px;
}

/* short strings only → Press Start 2P (already sized deliberately, don't auto-scale) */
.vd[data-pixel="1"] .navitem,
.vd[data-pixel="1"] .pixmark {
  font-family:'Press Start 2P', ui-monospace, monospace !important;
  font-size-adjust:none;
}
.vd[data-pixel="1"] .navitem { font-size:9px !important; line-height:1.4 !important; }

/* ---- hard edges: square everything ---- */
.vd[data-pixel="1"] * { border-radius:0 !important; }

/* ---- chunky pixel portraits / illustrations ---- */
.vd[data-pixel="1"] img { image-rendering:pixelated; }

/* ---- cards & panels: thick border + hard offset shadow ---- */
.vd[data-pixel="1"] .pcard,
.vd[data-pixel="1"] .osscard,
.vd[data-pixel="1"] [class*="card"],
.vd[data-pixel="1"] .feat {
  border:3px solid var(--line) !important;
  box-shadow:6px 7px 0 0 var(--pxsh) !important;
  transition:transform .1s steps(2), box-shadow .1s steps(2), border-color .12s !important;
}
.vd[data-pixel="1"] .pcard:hover,
.vd[data-pixel="1"] .osscard:hover,
.vd[data-pixel="1"] [class*="card"]:hover,
.vd[data-pixel="1"] .feat:hover {
  transform:translate(-2px,-2px) !important;
  box-shadow:10px 12px 0 0 var(--pxsh) !important;
  border-color:var(--accent) !important;
}

/* ---- small controls: chips, buttons, pager, search, toggle ---- */
.vd[data-pixel="1"] .chip,
.vd[data-pixel="1"] .btn,
.vd[data-pixel="1"] .pgbtn,
.vd[data-pixel="1"] .navtoggle,
.vd[data-pixel="1"] .search-label,
.vd[data-pixel="1"] .coord,
.vd[data-pixel="1"] .mark {
  border:2px solid var(--line) !important;
  box-shadow:3px 3px 0 0 var(--pxsh) !important;
  transition:transform .08s steps(1), box-shadow .08s steps(1), background .12s, color .12s !important;
}
.vd[data-pixel="1"] .chip:hover,
.vd[data-pixel="1"] .btn:hover,
.vd[data-pixel="1"] .pgbtn:hover,
.vd[data-pixel="1"] .navtoggle:hover {
  transform:translate(-1px,-1px) !important;
  box-shadow:4px 4px 0 0 var(--pxsh) !important;
}
.vd[data-pixel="1"] .chip:active,
.vd[data-pixel="1"] .btn:active,
.vd[data-pixel="1"] .pgbtn:active,
.vd[data-pixel="1"] .navtoggle:active {
  transform:translate(3px,3px) !important;
  box-shadow:0 0 0 0 var(--pxsh) !important;
}
.vd[data-pixel="1"] .search-label:focus-within {
  border-color:var(--accent) !important;
  box-shadow:3px 3px 0 0 var(--accent) !important;
}

/* search field rounded pill → square slab */
.vd[data-pixel="1"] .search-label input { letter-spacing:.4px; }

/* VT323 sits low in its line box; give body copy a steady rhythm so nothing crowds */
.vd[data-pixel="1"] p,
.vd[data-pixel="1"] li { line-height:1.5 !important; }

/* ---- CRT overlay: scanlines + vignette + faint flicker ---- */
.vd[data-pixel="1"]::after {
  content:"";
  position:fixed; inset:0;
  pointer-events:none; z-index:9999;
  background:repeating-linear-gradient(0deg, var(--scan) 0 1px, transparent 1px 3px);
  box-shadow:inset 0 0 140px rgba(0,0,0,.42);
  animation:voidFlicker 6s steps(1) infinite;
}
.vd[data-theme="dark"][data-pixel="1"]::after { box-shadow:inset 0 0 170px rgba(0,0,0,.72); }
/* light: the base .42 black inset reads as a gray dirty-screen haze + tonal seam
   on a white page; a much lighter inset keeps a subtle CRT curve without the muck. */
.vd[data-theme="light"][data-pixel="1"]::after { box-shadow:inset 0 0 120px rgba(0,0,0,.12); }

@keyframes voidFlicker {
  0%, 96%, 100% { opacity:1; }
  97% { opacity:.86; }
  98% { opacity:.97; }
  99% { opacity:.9; }
}
@media (prefers-reduced-motion: reduce) {
  .vd[data-pixel="1"]::after { animation:none; }
}

/* hero mascot bob (index) — only the chosen ghost variant, only in pixel mode */
@keyframes voidBob { 0%,100% { transform:translateY(0); } 50% { transform:translateY(-6px); } }
.vd[data-pixel="1"] .voidbob { animation:voidBob 2.1s steps(8) infinite; }
@media (prefers-reduced-motion: reduce) { .vd[data-pixel="1"] .voidbob { animation:none; } }
