html, body {
  margin: 0; padding: 0;
  background: #000;
  font-family: 'Hiragino Maru Gothic Pro', 'Yu Gothic', 'MS Gothic', monospace;
  /* iOS Safari fights with horizontal touch gestures unless we tell it the
     page is purely vertical-scrollable. Also kills pinch-to-zoom flicker on
     the fixed canvas which causes momentary black flashes on iPhone. */
  touch-action: pan-y;
  /* Block Android Chrome pull-to-refresh and the iOS bounce-into-blank-space
     at the page boundaries — both visually break the matrix-rain illusion. */
  overscroll-behavior: none;
  /* Browsers that support it: smoother iOS momentum scroll. */
  -webkit-overflow-scrolling: touch;
}
/* Body height drives scroll. With 5 viewports, scrollable range = 4 viewports.
   The canvas is position:fixed, so scrolling reveals shape morphs without
   any actual content moving on screen. */
body { height: 500vh; }
body.hide-ui .ui, body.hide-ui .hint, body.hide-ui .dev-panel, body.hide-ui .dev-toggle { display: none; }
canvas {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 1;
}
.vignette {
  position: fixed; inset: 0; pointer-events: none; z-index: 2;
  background: radial-gradient(ellipse at center,
    transparent var(--vignette-inner, 50%),
    rgba(0,0,0, var(--vignette-alpha, 0.65)) var(--vignette-outer, 100%));
  mix-blend-mode: multiply;
  opacity: var(--vignette-opacity, 1);
  transition: opacity 0.4s ease;
}
/* Auto-fade vignette in focus mode so it doesn't darken focused-card edges. */
body.focus-mode .vignette { opacity: 0; }
/* Scroll-lock fallback. The JS in enterFocus attaches wheel + touchmove
   preventDefault handlers (which allow scroll within .focus-detail), but
   this CSS rule catches any path the JS might miss — e.g. keyboard nav
   keys typed when the focused element doesn't bubble them, or browsers
   that ignore preventDefault for synthetic gestures. The body's overflow
   was 'visible' (since body IS the scrolling container) — switching it to
   hidden during focus freezes the document at its current scrollY, which
   means the matrix shape state stays exactly where the user left it. */
body.focus-mode {
  overflow: hidden !important;
}
.ui {
  position: fixed; top: 16px; right: 16px;
  display: flex; gap: 8px; z-index: 4;
}
button {
  padding: 8px 14px;
  background: rgba(0, 20, 0, 0.55);
  color: #6cff8a;
  border: 1px solid rgba(0, 255, 65, 0.55);
  font-family: 'Courier New', monospace;
  font-size: 12px;
  letter-spacing: 0.18em;
  cursor: pointer;
  text-shadow: 0 0 8px rgba(0,255,65,0.8);
  box-shadow: 0 0 12px rgba(0,255,65,0.25);
  backdrop-filter: blur(2px);
  transition: background 0.15s ease;
}
button:hover { background: rgba(0, 40, 0, 0.75); }
/* SHOP nav anchor — styled to match the .ui buttons exactly so the row reads
   as one cohesive set. Uses an anchor instead of a button because it leads
   to a different URL (Wix shop, eventually). */
.ui a#navShop {
  padding: 8px 14px;
  background: rgba(0, 20, 0, 0.55);
  color: #6cff8a;
  border: 1px solid rgba(0, 255, 65, 0.55);
  font-family: 'Courier New', monospace;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-decoration: none;
  text-shadow: 0 0 8px rgba(0,255,65,0.8);
  box-shadow: 0 0 12px rgba(0,255,65,0.25);
  backdrop-filter: blur(2px);
  transition: background 0.15s ease;
}
.ui a#navShop:hover { background: rgba(0, 40, 0, 0.75); color: #b8ffc8; }
.hint {
  position: fixed; bottom: 14px; left: 16px;
  color: rgba(120, 255, 140, 0.5);
  font-family: 'Courier New', monospace;
  font-size: 10px; letter-spacing: 0.25em;
  text-shadow: 0 0 6px rgba(0,255,65,0.5);
  pointer-events: none; z-index: 4;
}
.progress {
  position: fixed;
  top: 50%; right: 28px;
  transform: translateY(-50%);
  z-index: 4;
  display: flex; flex-direction: column; gap: 28px;
}
.progress .stop {
  display: flex; align-items: center; gap: 16px; cursor: pointer;
  color: rgba(150, 255, 170, 0.35);
  font-family: 'Courier New', monospace;
  font-size: 12px; letter-spacing: 0.3em;
  transition: color 0.3s ease;
  user-select: none;
}
.progress .stop:hover { color: rgba(180, 255, 200, 0.7); }
.progress .stop .dot {
  width: 11px; height: 11px;
  border: 1px solid rgba(0, 255, 65, 0.4);
  background: rgba(0, 255, 65, 0.05);
  transform: rotate(45deg);
  transition: all 0.3s ease;
}
.progress .stop.active { color: #f0fff5; }
.progress .stop.active .dot {
  background: rgba(0, 255, 65, 0.95);
  box-shadow: 0 0 18px rgba(0, 255, 65, 0.95);
  border-color: rgba(0, 255, 65, 0.95);
}
.nav-menu {
  position: fixed; inset: 0; z-index: 9;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.78);
  backdrop-filter: blur(8px);
  opacity: 0; pointer-events: none;
  transition: opacity 0.35s ease;
}
.nav-menu.visible { opacity: 1; pointer-events: auto; }
.nav-content {
  text-align: center;
  color: #b8ffc8;
  font-family: 'Courier New', monospace;
  padding: 40px;
  border: 1px solid rgba(0, 255, 65, 0.35);
  background: rgba(0, 12, 0, 0.55);
  box-shadow: 0 0 40px rgba(0, 255, 65, 0.18);
  min-width: 360px;
}
.nav-content h1 {
  font-size: 36px; letter-spacing: 0.55em;
  margin: 0 0 6px 0;
  color: #e8ffee;
  text-shadow: 0 0 20px rgba(0, 255, 65, 0.95), 0 0 40px rgba(0, 255, 65, 0.55);
}
.nav-content .tag {
  font-size: 10px; letter-spacing: 0.4em;
  color: rgba(150, 255, 170, 0.55);
  margin-bottom: 36px;
}
.nav-menu nav { display: flex; flex-direction: column; gap: 14px; margin-bottom: 32px; }
.nav-menu nav a {
  color: #9cffb0; text-decoration: none;
  font-size: 14px; letter-spacing: 0.35em;
  padding: 10px 20px;
  border: 1px solid transparent;
  transition: all 0.2s ease;
  text-shadow: 0 0 8px rgba(0, 255, 65, 0.5);
}
.nav-menu nav a:hover {
  color: #f0fff5;
  border-color: rgba(0, 255, 65, 0.6);
  background: rgba(0, 255, 65, 0.08);
  text-shadow: 0 0 12px rgba(0, 255, 65, 1);
}
.nav-close { font-size: 9px; letter-spacing: 0.4em; color: rgba(150, 255, 170, 0.4); }
