/* Visualizer lab page. Page chrome uses the site's look tokens (themes.css);
   the stage keeps its own dark palette in every look, like the Snake AI board. */

/* ---------- stage ---------- */
.viz-stage {
  --viz-ink: #f1f5fb;
  --viz-ink-2: #c4cfdf;
  --viz-glass: rgb(8 12 28 / 0.72);
  --viz-glass-hover: rgb(20 28 52 / 0.85);
  --viz-edge: rgb(255 255 255 / 0.24);
  --viz-accent: var(--accent);
  --viz-accent-fg: var(--button-fg, #fff);
  position: relative; isolation: isolate; overflow: hidden;
  /* fill the window under the site header, leaving a strip for the look switcher; the floor
     keeps room for the intro and controls but never runs past the window, so on a short
     screen the controls are still on it */
  height: calc(100vh - var(--viz-top, 4.5rem) - 4.5rem);
  height: calc(100svh - var(--viz-top, 4.5rem) - 4.5rem);
  min-height: min(24rem, 100vh - var(--viz-top, 4.5rem));
  min-height: min(24rem, 100svh - var(--viz-top, 4.5rem));
  color: var(--viz-ink);
  background-color: #050510;
  /* the no-WebGL fallback (and what shows before the script runs) */
  background-image: linear-gradient(-45deg, #050510, #16213e, #0f3460, #1a1a2e);
  background-size: 400% 400%;
  background-position: 0% 50%;
  cursor: crosshair; touch-action: pan-y;
  -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent;
  border-bottom: var(--rule, 1px solid var(--line));
}
.viz-stage.no-gl { animation: viz-gradient 15s ease infinite; }
.viz-stage.no-gl.is-paused { animation-play-state: paused; }
@keyframes viz-gradient {
  0% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

.viz-gl, .viz-fx, .viz-scan { position: absolute; inset: 0; width: 100%; height: 100%; }
/* the canvas is opaque: it fades in over the gradient once the shader has compiled */
.viz-gl { display: block; z-index: 0; transition: opacity 0.6s ease; }
.viz-stage:not(.has-gl) .viz-gl { opacity: 0; }
.viz-fx { display: block; z-index: 1; pointer-events: none; }
/* scanlines: a soft 4px period (hard 1px lines band on scaled displays) */
.viz-scan {
  z-index: 2; pointer-events: none; display: none;
  background: repeating-linear-gradient(to bottom, rgb(0 0 0 / 0) 0, rgb(0 0 0 / 0.3) 2px, rgb(0 0 0 / 0) 4px);
}
.viz-stage.fx-scanlines .viz-scan { display: block; }

/* ---------- slim intro over the top of the stage ---------- */
.viz-head {
  position: absolute; z-index: 3; inset: 0 0 auto 0; pointer-events: none;
  padding: clamp(1rem, 3vw, 1.9rem) 0 3rem;
  background: linear-gradient(to bottom, rgb(5 5 16 / 0.8), rgb(5 5 16 / 0.5) 62%, rgb(5 5 16 / 0));
}
.viz-head h1 {
  margin: 0 0 0.3rem; color: #fff; font-size: clamp(2rem, 1.35rem + 2.4vw, 3.2rem);
  text-shadow: 0 2px 18px rgb(0 0 0 / 0.55);
}
.viz-head p { margin: 0; max-width: 44rem; }
.viz-head .crumbs { margin-bottom: 0.5rem; color: var(--viz-ink-2); text-shadow: 0 1px 8px rgb(0 0 0 / 0.8); }
.viz-head .crumbs a { color: inherit; }
.viz-head .viz-intro { font-size: clamp(1rem, 0.95rem + 0.3vw, 1.15rem); line-height: 1.5; color: var(--viz-ink-2); text-shadow: 0 1px 10px rgb(0 0 0 / 0.7); }
.viz-head .viz-note { margin-top: 0.55rem; font-size: 0.92rem; color: #ffd58f; text-shadow: 0 1px 8px rgb(0 0 0 / 0.8); }
.viz-note[hidden] { display: none; }
.viz-head .viz-readout {
  display: flex; align-items: center; gap: 0.45rem; margin-top: 0.6rem;
  font-family: ui-monospace, "IBM Plex Mono", Consolas, monospace; font-size: 0.75rem; line-height: 1.3;
  color: rgb(225 232 244 / 0.78); text-shadow: 0 1px 6px rgb(0 0 0 / 0.9);
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.viz-readout[hidden] { display: none; }
.viz-readout > span:last-child { overflow: hidden; text-overflow: ellipsis; }
.viz-dot { flex: none; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: #7d8796; }
.viz-readout[data-kind="gpu"] .viz-dot { background: #4cc38a; box-shadow: 0 0 6px rgb(76 195 138 / 0.8); }
.viz-readout[data-kind="software"] .viz-dot { background: #f4b740; box-shadow: 0 0 6px rgb(244 183 64 / 0.7); }

/* ---------- control bar along the bottom ---------- */
.viz-bar {
  position: absolute; z-index: 3; inset: auto 0 0 0; pointer-events: none;
  padding: 2.6rem 0 0.9rem;
  background: linear-gradient(to top, rgb(5 5 16 / 0.72), rgb(5 5 16 / 0));
  transition: opacity 0.4s ease;
}
.viz-bar[hidden] { display: none; }
.viz-bar-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1.2rem; }
.viz-group { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
.viz-btn, .viz-chip, .viz-select { pointer-events: auto; }
.viz-label { margin-right: 0.15rem; color: var(--viz-ink-2); font-size: 0.8rem; text-shadow: 0 1px 6px rgb(0 0 0 / 0.9); pointer-events: auto; }

.viz-btn, .viz-chip, .viz-select {
  cursor: pointer; font: inherit; line-height: 1.2; color: var(--viz-ink);
  background-color: var(--viz-glass); border: 1px solid var(--viz-edge);
}
.viz-btn {
  display: inline-flex; align-items: center; gap: 0.45rem;
  min-height: 2.4rem; padding: 0.4rem 0.85rem; font-size: 0.9rem; font-weight: 600;
  border-radius: var(--button-radius, 6px);
}
.viz-btn[hidden], .viz-chip[hidden] { display: none; }
.viz-chip {
  min-height: 2.1rem; padding: 0.25rem 0.65rem; font-size: 0.82rem; color: var(--viz-ink-2);
  border-radius: var(--chip-radius, 999px);
}
.viz-select {
  min-height: 2.1rem; padding: 0.25rem 0.5rem; font-size: 0.82rem;
  border-radius: var(--chip-radius, 999px);
}
.viz-select option { color: #10151f; background: #fff; }
.viz-btn:hover, .viz-chip:hover, .viz-select:hover { border-color: var(--viz-accent); background-color: var(--viz-glass-hover); }
.viz-chip[aria-pressed="true"] { background: var(--viz-accent); border-color: var(--viz-accent); color: var(--viz-accent-fg); }
.viz-chip[aria-pressed="true"]::before { content: "✓ "; content: "✓ " / ""; }
.viz-stage :focus-visible { outline: 2px solid #fff; outline-offset: 2px; box-shadow: 0 0 0 5px rgb(0 0 0 / 0.55); }

/* play / pause glyphs drawn in CSS so they look the same in every font */
#viz-play::before {
  content: ""; display: inline-block; width: 0.62rem; height: 0.72rem; box-sizing: border-box;
  border-left: 0.2rem solid currentColor; border-right: 0.2rem solid currentColor;
}
#viz-play[data-state="paused"]::before {
  width: 0; height: 0; border-style: solid; border-color: transparent;
  border-width: 0.38rem 0 0.38rem 0.62rem; border-left-color: currentColor; border-right: 0;
}

/* ---------- full screen (Fullscreen API or the fixed fallback) ---------- */
.viz-stage.is-fullscreen { height: 100%; min-height: 0; border: 0; touch-action: none; }
.viz-stage.is-pseudo-fs { position: fixed; inset: 0; z-index: 100; height: auto; }
html.viz-lock, html.viz-lock body { overflow: hidden; }
.viz-stage.is-fullscreen .viz-head { padding-bottom: 1.5rem; background: none; }
.viz-stage.is-fullscreen .viz-head h1,
.viz-stage.is-fullscreen .viz-intro,
.viz-stage.is-fullscreen .viz-note { display: none; }
.viz-stage.is-fullscreen.is-idle { cursor: none; }
.viz-stage.is-fullscreen.is-idle .viz-bar,
.viz-stage.is-fullscreen.is-idle .viz-readout { opacity: 0; }

/* ---------- how it works ---------- */
.viz-how { padding-block: clamp(2rem, 5vw, 3rem) 3.5rem; }
.viz-how-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem 2.2rem; }
.viz-how h3 { margin-bottom: 0.35rem; font-size: 1.1rem; }
.viz-how-grid p { margin: 0; }
.viz-small { margin: 1.4rem 0 0; color: var(--muted); font-size: 0.92rem; }

/* ---------- per-look touches ---------- */
[data-theme="ops"] .viz-readout, [data-theme="ops"] .viz-label { font-family: var(--font-display); }
[data-theme="editorial"] .viz-stage { --viz-accent: #4fb8de; --viz-accent-fg: #062330; }
[data-theme="editorial"] .viz-btn, [data-theme="editorial"] .viz-chip,
[data-theme="editorial"] .viz-select, [data-theme="editorial"] .viz-label { font-family: system-ui, sans-serif; }
[data-theme="print"] .viz-stage { border-bottom: 2px solid #000; }
[data-theme="print"] .viz-how-grid > div { border-top: 4px solid var(--m); padding-top: 0.7rem; }
[data-theme="print"] .viz-how-grid > div:nth-child(2) { border-top-color: var(--c); }
[data-theme="print"] .viz-how-grid > div:nth-child(3) { border-top-color: var(--y); }

/* ---------- responsive + accessibility ---------- */
@media (max-width: 860px) {
  .viz-how-grid { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .viz-stage { min-height: min(30rem, 100vh - var(--viz-top, 4.5rem)); min-height: min(30rem, 100svh - var(--viz-top, 4.5rem)); }
  .viz-head { padding-bottom: 2rem; }
  .viz-head .viz-intro { font-size: 0.98rem; }
  .viz-bar { padding-bottom: 0.75rem; }
  .viz-bar-row { gap: 0.4rem 0.8rem; }
  .viz-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .viz-btn { min-height: 2.25rem; padding: 0.35rem 0.7rem; font-size: 0.85rem; }
}
/* short windows (phones held sideways): the stage is the whole window under the header, and
   the intro paragraph gives its room to the controls (How it works below says the same) */
@media (max-height: 500px) {
  .viz-stage { height: calc(100vh - var(--viz-top, 4.5rem)); height: calc(100svh - var(--viz-top, 4.5rem)); min-height: 0; }
  .viz-head { padding-bottom: 1.5rem; }
  .viz-head .viz-intro { display: none; }
}
/* where the stage can reach the bottom of the window, an empty spacer at the far end of the
   last control row keeps the floating look switcher (a 2.75rem circle on phones, about 9.5rem
   wide with its label) from covering a control */
@media (max-width: 640px), (max-height: 500px) {
  .viz-bar-row::after { content: ""; flex: 0 0 var(--viz-switcher-room, 2.75rem); height: 2.25rem; margin-left: auto; }
}
@media (min-width: 641px) and (max-height: 500px) {
  .viz-bar-row { --viz-switcher-room: 9.5rem; }
}
@media (forced-colors: active) {
  .viz-chip[aria-pressed="true"] { outline: 2px solid CanvasText; outline-offset: 1px; }
}
/* printing: the animation can't be printed, so the page prints as text (title, intro, How it works) */
@media print {
  .viz-stage { height: auto; min-height: 0; overflow: visible; color: #000; border: 0; }
  .viz-gl, .viz-fx, .viz-scan, .viz-bar, .viz-readout, .viz-note { display: none !important; }
  .viz-head { position: static; padding: 1rem 0 0; }
  .viz-head h1, .viz-head .viz-intro { display: block; color: #000; }
  .viz-how { padding-block: 1rem; }
  .viz-how-grid { grid-template-columns: 1fr; }
  .viz-how-grid > div { border-top: 1px solid #000 !important; padding-top: 0.5rem; break-inside: avoid; }
}
