/* =====================================================================
   GeekHuang Lab — secret 8-bit mode (Konami code easter egg)
   Every rule is scoped to html.gh-8bit → this file is inert unless the
   class is present (toggled by js/modules/konami.js; sessionStorage only).
   System monospace fonts only — no webfonts, no libraries.
   Works with both palettes ([data-theme="light|dark"]); it only re-uses
   the site tokens from css/style.css and never changes them for normal mode.
   ===================================================================== */

html.gh-8bit {
  --gh8-font: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, "Liberation Mono",
              "DejaVu Sans Mono", "Courier New", "PingFang SC", "Microsoft YaHei", monospace;
  --font-sans: var(--gh8-font);
  --font-mono: var(--gh8-font);
  --radius: 0px;
  --radius-sm: 0px;
  --gh8-bw: 2px;
  --gh8-line: color-mix(in srgb, var(--text) 28%, transparent);
  --gh8-shadow: color-mix(in srgb, var(--cyan) 42%, transparent);
  --gh8-accent: var(--cyan);
  --gh8-tshadow: color-mix(in srgb, var(--cyan) 42%, transparent);   /* text drop-shadow: always soft/legible */
  --glow: 6px 6px 0 0 var(--gh8-accent);
  scroll-behavior: auto;
}
html.gh-8bit[data-theme="light"] {
  --gh8-line: color-mix(in srgb, var(--text) 45%, transparent);
  --gh8-shadow: color-mix(in srgb, var(--text) 78%, transparent);
}

/* ---------- base ---------- */
html.gh-8bit body {
  font-family: var(--gh8-font);
  letter-spacing: 0;
  -webkit-font-smoothing: none;
  -moz-osx-font-smoothing: auto;
  text-rendering: optimizeSpeed;
}
html.gh-8bit *,
html.gh-8bit *::before,
html.gh-8bit *::after { border-radius: 0 !important; }          /* stepped corners everywhere */

html.gh-8bit img,
html.gh-8bit canvas { image-rendering: pixelated; }
html.gh-8bit svg { shape-rendering: crispEdges; }

html.gh-8bit ::selection { background: var(--gh8-accent); color: var(--bg); }
html.gh-8bit :focus-visible { outline: 2px dashed var(--gh8-accent); outline-offset: 3px; }
html.gh-8bit .cmd__input:focus-visible { outline: none; }            /* palette field keeps its own look */

/* CRT scanlines (purely decorative, never intercepts input) */
html.gh-8bit body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  background: repeating-linear-gradient(to bottom, transparent 0 2px, rgba(0, 0, 0, 0.07) 2px 3px);
}
html.gh-8bit[data-theme="light"] body::after {
  background: repeating-linear-gradient(to bottom, transparent 0 2px, rgba(11, 16, 32, 0.035) 2px 3px);
}

/* chunkier blueprint grid, no drifting */
html.gh-8bit .bg-grid {
  background-size: 128px 128px, 128px 128px, 16px 16px, 16px 16px;
  animation: none;
}
html.gh-8bit .hero::before,
html.gh-8bit .svc::after { display: none; }

/* ---------- headings: hard pixel drop-shadow (large type only, stays legible) ---------- */
html.gh-8bit .hero__title {
  font-size: clamp(34px, 7vw, 120px);
  letter-spacing: 0;
  margin-left: 0;
  text-shadow: max(2px, 0.035em) max(2px, 0.035em) 0 var(--gh8-tshadow);
}
html.gh-8bit .about__name { letter-spacing: 0; text-shadow: 2px 2px 0 var(--gh8-tshadow); }
html.gh-8bit .section-head__title { letter-spacing: 0.04em; }
html.gh-8bit .svc__name,
html.gh-8bit .note__title,
html.gh-8bit .exp__title { letter-spacing: 0; }
html.gh-8bit .hero__slogan,
html.gh-8bit .cmd__input { letter-spacing: 0; }

/* ---------- navbar ---------- */
html.gh-8bit .nav {
  background: var(--bg);
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
  border-bottom: var(--gh8-bw) solid var(--gh8-line);
}
html.gh-8bit .brand__name { letter-spacing: 0; }
html.gh-8bit .brand__mark { image-rendering: pixelated; }

/* ---------- blocky boxes ---------- */
html.gh-8bit .svc,
html.gh-8bit .note,
html.gh-8bit .about,
html.gh-8bit .spec-plate,
html.gh-8bit .status-grid,
html.gh-8bit .btn,
html.gh-8bit .icon-btn,
html.gh-8bit .cmd-launch,
html.gh-8bit .cmd-launch__kbd,
html.gh-8bit .pill,
html.gh-8bit .svc__icon,
html.gh-8bit .about__photo-frame,
html.gh-8bit .about__qr,
html.gh-8bit .about__contact,
html.gh-8bit .skip-link {
  border-width: var(--gh8-bw);
  border-color: var(--gh8-line);
}
html.gh-8bit .svc,
html.gh-8bit .note,
html.gh-8bit .about,
html.gh-8bit .spec-plate,
html.gh-8bit .status-grid,
html.gh-8bit .btn,
html.gh-8bit .cmd-launch { box-shadow: 4px 4px 0 0 var(--gh8-shadow); }

html.gh-8bit .svc,
html.gh-8bit .note,
html.gh-8bit .btn,
html.gh-8bit .icon-btn,
html.gh-8bit .cmd-launch { transition-timing-function: steps(2, end); }

html.gh-8bit a.svc:hover,
html.gh-8bit a.svc:focus-visible,
html.gh-8bit .note:hover,
html.gh-8bit .note:focus-visible,
html.gh-8bit .btn:hover {
  transform: translate(-2px, -2px);
  border-color: var(--gh8-accent);
  box-shadow: 6px 6px 0 0 var(--gh8-accent);
}
html.gh-8bit a.svc:active,
html.gh-8bit .note:active,
html.gh-8bit .btn:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 0 var(--gh8-shadow); }
html.gh-8bit .btn--primary { border-color: var(--text); }
html.gh-8bit .icon-btn:hover,
html.gh-8bit .cmd-launch:hover { border-color: var(--gh8-accent); color: var(--text); }

/* ---------- status ---------- */
html.gh-8bit .status-grid { gap: var(--gh8-bw); background: var(--gh8-line); }
html.gh-8bit .status-card__value { letter-spacing: 0; }
html.gh-8bit .status-card__bar {
  height: 4px;
  opacity: 0.6;
  background: repeating-linear-gradient(90deg, var(--ok) 0 6px, transparent 6px 9px);
}
html.gh-8bit .status-card[data-state="warn"] .status-card__bar { background: repeating-linear-gradient(90deg, var(--warn) 0 6px, transparent 6px 9px); }
html.gh-8bit .status-card[data-state="down"] .status-card__bar { background: repeating-linear-gradient(90deg, var(--down) 0 6px, transparent 6px 9px); }
html.gh-8bit .dot--ok { box-shadow: 0 0 0 2px color-mix(in srgb, var(--ok) 22%, transparent); }
html.gh-8bit .live { animation-timing-function: steps(2, end); }
html.gh-8bit .eyebrow__rule,
html.gh-8bit .section-head__rule { height: 2px; }

/* ---------- experiments / notes / about ---------- */
html.gh-8bit .experiment-list,
html.gh-8bit .exp { border-width: var(--gh8-bw); border-color: var(--gh8-line); }
html.gh-8bit .exp__tags .sep { color: var(--gh8-accent); }
html.gh-8bit .about__photo-frame::before { border-width: var(--gh8-bw); }

/* ---------- command palette ---------- */
html.gh-8bit .cmd__backdrop {
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
}
html.gh-8bit .cmd__panel {
  border: var(--gh8-bw) solid var(--gh8-line);
  box-shadow: 6px 6px 0 0 var(--gh8-shadow);
}
html.gh-8bit .cmd__head,
html.gh-8bit .cmd__foot { border-width: var(--gh8-bw); border-color: var(--gh8-line); }
html.gh-8bit .cmd__item:hover,
html.gh-8bit .cmd__item.is-active { box-shadow: inset 0 0 0 2px var(--gh8-accent); }

/* =====================================================================
   小黄 runner (created by konami.js only while the mode is on)
   ===================================================================== */
html.gh-8bit .gh8-runner {
  --gh8-size: 72px;
  --pet-line:   #3B2A14;
  --pet-body:   #F4C542;
  --pet-hi:     #FFE48A;
  --pet-shade:  #D9A227;
  --pet-belly:  #FFF0B8;
  --pet-beak:   #F29A38;
  --pet-beak-d: #C9681C;
  --pet-eye:    #1A1D26;
  --pet-cheek:  #F59AA8;
  --pet-heart:  #F0648C;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  height: calc(var(--gh8-size) + 130px);
  z-index: 70;                                  /* above navbar (50), below Command Palette (80) */
  pointer-events: none;
  overflow: hidden;                             /* never causes horizontal scroll */
  contain: layout paint;
}
html.gh-8bit[data-theme="dark"] .gh8-runner { --pet-line: #1E1408; }
html.gh-8bit .gh8-pet {
  position: absolute;
  left: 0; bottom: 12px;
  width: var(--gh8-size);
  height: var(--gh8-size);
  will-change: transform;
}
html.gh-8bit .gh8-pet::after {                  /* pixel ground shadow */
  content: "";
  position: absolute;
  left: 22%; right: 22%; bottom: -4px;
  height: 4px;
  background: rgba(0, 0, 0, 0.28);
}
html.gh-8bit .gh8-pet__sprite { position: absolute; inset: 0; }
html.gh-8bit .gh8-pet__svg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  overflow: visible;
  image-rendering: pixelated;
}
html.gh-8bit .gh8-pet__svg--b { visibility: hidden; }
html.gh-8bit .gh8-runner.is-running .gh8-pet__svg--a { animation: gh8-frame-a 0.28s steps(1, end) infinite; }
html.gh-8bit .gh8-runner.is-running .gh8-pet__svg--b { animation: gh8-frame-b 0.28s steps(1, end) infinite; }
html.gh-8bit .gh8-runner.is-running .gh8-pet__sprite { animation: gh8-hop 0.28s steps(1, end) infinite; }
@keyframes gh8-frame-a { 0% { visibility: visible; } 50% { visibility: hidden; } 100% { visibility: hidden; } }
@keyframes gh8-frame-b { 0% { visibility: hidden; } 50% { visibility: visible; } 100% { visibility: visible; } }
@keyframes gh8-hop { 0% { transform: translateY(0); } 50% { transform: translateY(calc(var(--gh8-size) / -16)); } 100% { transform: translateY(calc(var(--gh8-size) / -16)); } }

/* sprite palette (same colours as lab/pet/pet.css; happy face only) */
html.gh-8bit .gh8-runner .px-line   { fill: var(--pet-line); }
html.gh-8bit .gh8-runner .px-body   { fill: var(--pet-body); }
html.gh-8bit .gh8-runner .px-hi     { fill: var(--pet-hi); }
html.gh-8bit .gh8-runner .px-shade  { fill: var(--pet-shade); }
html.gh-8bit .gh8-runner .px-belly  { fill: var(--pet-belly); }
html.gh-8bit .gh8-runner .px-slot   { fill: var(--pet-shade); }
html.gh-8bit .gh8-runner .px-beak   { fill: var(--pet-beak); }
html.gh-8bit .gh8-runner .px-beak-d { fill: var(--pet-beak-d); }
html.gh-8bit .gh8-runner .px-mouth  { fill: var(--pet-line); }
html.gh-8bit .gh8-runner .px-eye    { fill: var(--pet-eye); }
html.gh-8bit .gh8-runner .px-glint  { fill: #FFFFFF; }
html.gh-8bit .gh8-runner .px-cheek  { fill: var(--pet-cheek); opacity: 0.85; }
html.gh-8bit .gh8-runner .px-led    { fill: var(--ok); }
html.gh-8bit .gh8-runner .px-led-glint { fill: #FFFFFF; opacity: 0.7; }
html.gh-8bit .gh8-runner .px-bled   { fill: var(--ok); }
html.gh-8bit .gh8-runner .px-bled--a { animation: gh8-led 0.6s steps(1, end) infinite; }
@keyframes gh8-led { 50% { opacity: 0.25; } }

/* speech bubble */
html.gh-8bit .gh8-bubble {
  --gh8-tail: 50%;
  position: absolute;
  left: 0;
  bottom: calc(100% + 16px);
  width: max-content;
  max-width: min(280px, calc(100vw - 16px));
  padding: 8px 12px;
  background: var(--surface);
  color: var(--text);
  border: var(--gh8-bw) solid var(--text);
  box-shadow: 4px 4px 0 0 var(--gh8-shadow);
  font: 400 12px/1.45 var(--gh8-font);
  text-align: center;
  visibility: hidden;
}
html.gh-8bit .gh8-bubble strong {
  display: block;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--gh8-accent);
}
html.gh-8bit .gh8-bubble span { display: block; margin-top: 2px; color: var(--text-2); }
html.gh-8bit .gh8-bubble::before,
html.gh-8bit .gh8-bubble::after {               /* stepped pixel tail */
  content: "";
  position: absolute;
  left: var(--gh8-tail);
  background: var(--text);
}
html.gh-8bit .gh8-bubble::before { top: 100%; width: 10px; height: 5px; margin-left: -5px; }
html.gh-8bit .gh8-bubble::after  { top: calc(100% + 5px); width: 5px; height: 5px; margin-left: -2px; }
html.gh-8bit .gh8-runner.is-talking .gh8-bubble { visibility: visible; animation: gh8-pop 0.24s steps(3, end); }
@keyframes gh8-pop { 0% { transform: scale(0.4); } 100% { transform: scale(1); } }

/* reduced motion: 小黄 just appears (no running, hopping, blinking or pop) */
html.gh-8bit .gh8-runner.is-static *,
html.gh-8bit .gh8-runner.is-static *::before,
html.gh-8bit .gh8-runner.is-static *::after { animation: none !important; transition: none !important; }
@media (prefers-reduced-motion: reduce) {
  html.gh-8bit .gh8-runner * { animation: none !important; transition: none !important; }
}
