/* The shell: a full-bleed stage, quiet page furniture, and the click spark. */

@view-transition { navigation: auto; }

:root {
  color-scheme: dark;
  --bg: #000;
  --fg: #fff;
  --dim: #8a8a8a;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --display: "Archivo", "Arial Black", "Helvetica Neue", system-ui, sans-serif;
  --gutter: max(16px, 4.5vw);
}
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #fff;
  --fg: #000;
  --dim: #767676;
}

/* Reveal (three quick taps): the whole page inverts, and the poster draws what it is made of over it. */
html { transition: filter 0.45s ease; }
html.revealed { filter: invert(1); }
@media (prefers-reduced-motion: reduce) { html { transition: none; } }

*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  background: var(--bg);
  color: var(--fg);
  font: 400 12px/1.5 var(--mono);
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
  -webkit-user-select: none; user-select: none;      /* a long press on a poster must not select the page */
  -webkit-touch-callout: none;
}
.tune, .tune textarea, .tune input { -webkit-user-select: text; user-select: text; }

.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- stage ---------- */
.stage {
  position: fixed; inset: 0;
  overflow: hidden;
  touch-action: none;
  cursor: crosshair;
  background: var(--bg);
  transition: opacity 180ms ease;
}
.stage.swap { opacity: 0; transition-duration: 90ms; }
.poster-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* Shown when WebGL is unavailable or a poster fails: the words, set big, no tricks. */
.fallback {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: flex-start;
  padding: var(--gutter) var(--gutter) 120px;
  font: 900 min(26vw, 30vh)/0.86 var(--display);
  letter-spacing: -0.01em;
  color: var(--fg);
  text-transform: uppercase;
  pointer-events: none;
}

/* ---------- page furniture ---------- */
.chrome {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  padding: 0 var(--gutter) calc(max(14px, 2vh) + env(safe-area-inset-bottom, 0px));
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas: "id links actions";
  align-items: end;
  gap: 6px 20px;
  color: var(--dim);
  pointer-events: none;
}
.chrome > * { pointer-events: auto; }
.id { grid-area: id; display: flex; flex-direction: column; gap: 0; min-width: 0; }
/* the page's own words can be selected and copied; the controls and the poster cannot */
.id, .links { -webkit-user-select: text; user-select: text; cursor: text; }
.links a { cursor: pointer; }
.chrome button { -webkit-user-select: none; user-select: none; }
.id b { color: var(--fg); font-weight: 500; }
.id .role { color: var(--dim); }
#tagline { color: var(--dim); opacity: 0.78; }
.folio { opacity: 0.9; }
.links { grid-area: links; display: flex; gap: 18px; justify-content: center; }
.actions { grid-area: actions; display: flex; gap: 6px; justify-content: flex-end; }

.chrome a, .chrome button {
  font: inherit; color: inherit; background: none; border: 0; padding: 8px 0; margin: 0;
  text-decoration: none; cursor: pointer; line-height: 1.2;
}
.actions button { padding: 8px 10px; margin: -8px -4px; }
.chrome a:hover, .chrome button:hover { color: var(--fg); }
.chrome a:focus-visible, .chrome button:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; color: var(--fg); }

.hint {
  position: fixed; z-index: 30; left: 50%; bottom: calc(112px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  color: var(--dim);
  opacity: 0; transition: opacity 600ms ease;
  pointer-events: none;
  white-space: nowrap;
}
.hint.on { opacity: 1; }

#toast {
  position: fixed; z-index: 40; top: calc(max(14px, 2vh) + env(safe-area-inset-top, 0px)); right: var(--gutter);
  color: var(--dim); opacity: 0; transition: opacity 400ms ease; pointer-events: none;
}
#toast.on { opacity: 1; }

/* ---------- click spark: ascii glyphs that pop and fade ---------- */
.spark {
  position: fixed; z-index: 25; pointer-events: none;
  font: 700 14px var(--mono);
  color: var(--fg);
  will-change: transform, opacity;
}

/* ---------- tuning panel (dev) ---------- */
.tune {
  position: fixed; z-index: 60; top: 12px; right: 12px; width: min(300px, calc(100vw - 24px)); max-height: calc(100dvh - 24px);
  overflow: auto; padding: 10px 12px 12px; color: #d9d9d9; background: rgba(8, 8, 8, 0.92);
  border: 1px solid #2d2d2d; backdrop-filter: blur(8px); font: 11px/1.4 var(--mono); cursor: default; touch-action: pan-y;
}
.tune * { box-sizing: border-box; }
.tune-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.tune-head b { font-weight: 500; color: #fff; }
.tune button { font: inherit; color: #d9d9d9; background: none; border: 1px solid #3a3a3a; padding: 4px 8px; margin: 0 4px 4px 0; cursor: pointer; }
.tune button:hover { border-color: #888; color: #fff; }
.tune button:focus-visible { outline: 2px solid #fff; outline-offset: 1px; }
.tune-actions { margin-bottom: 6px; }
.tune.folded > :not(.tune-head) { display: none; }
.tune.folded .tune-head { margin-bottom: 0; }
.tune.folded { overflow: hidden; }
.tune details { border-top: 1px solid #262626; padding: 6px 0 2px; }
.tune summary { cursor: pointer; color: #9a9a9a; padding: 2px 0 6px; }
.tune-row { display: grid; grid-template-columns: 1fr auto; gap: 2px 8px; align-items: baseline; margin-bottom: 8px; }
.tune-row output { color: #fff; font-variant-numeric: tabular-nums; }
.tune-row input[type="range"] { grid-column: 1 / -1; width: 100%; accent-color: #fff; height: 18px; margin: 0; }
.tune-toggle input[type="checkbox"] { grid-column: 1 / -1; justify-self: start; width: 18px; height: 18px; margin: 2px 0 0; accent-color: #fff; }
.tune-text textarea { grid-column: 1 / -1; width: 100%; font: inherit; color: #fff; background: #000; border: 1px solid #3a3a3a; padding: 6px; resize: vertical; }

@media (max-width: 720px) {
  .chrome {
    grid-template-columns: 1fr auto;
    grid-template-areas: "id actions" "links folio";
    align-items: end;
  }
  .id { display: contents; }
  .id .who { grid-area: id; }
  .id .folio { grid-area: folio; text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .folio .count { display: none; }
  .links { justify-content: flex-start; gap: 16px; }
  .hint { bottom: calc(132px + env(safe-area-inset-bottom, 0px)); }
}

@media (pointer: coarse) {
  .chrome a, .chrome button { padding-block: 13px; }
  .actions button { margin-block: -13px; }
}

/* Shuffle breathes slowly, like an AI "thinking" cursor, so it is not missed. Still on hover/focus. */
@keyframes breathe { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
#btn-shuffle { animation: breathe 2.4s ease-in-out infinite; }
#btn-shuffle:hover, #btn-shuffle:focus-visible, #btn-shuffle:active { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .stage, .hint, #toast { transition: none; }
  #btn-shuffle { animation: none; }
}

noscript .plain {
  position: fixed; inset: 0; z-index: 50; background: #000; color: #fff;
  padding: var(--gutter); font: 900 18vw/0.9 var(--display); text-transform: uppercase;
}

/* the `hidden` attribute must win over the display rules above */
.chrome [hidden] { display: none !important; }

/* The panel on a phone: a sheet along the bottom (the poster stays above it), roomy tap targets, Hide folds it to its title bar. */
@media (max-width: 720px), (pointer: coarse) {
  .tune { top: auto; right: 0; bottom: 0; left: 0; width: 100%; max-height: 46dvh; padding: 8px 14px calc(12px + env(safe-area-inset-bottom)); font-size: 13px; border-width: 1px 0 0; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
  .tune-head { position: sticky; top: -8px; z-index: 1; margin: -8px -14px 8px; padding: 8px 14px; background: rgba(8, 8, 8, 0.96); }
  .tune.folded .tune-head { position: static; margin: -8px -14px 0; }
  .tune button { padding: 9px 12px; margin: 0 6px 6px 0; min-height: 40px; }
  .tune-head button { margin: 0 0 0 6px; }
  .tune-actions { display: flex; flex-wrap: nowrap; overflow-x: auto; gap: 0; margin: 0 -14px 8px; padding: 0 14px; scrollbar-width: none; }
  .tune-actions::-webkit-scrollbar { display: none; }
  .tune-actions button { flex: none; white-space: nowrap; }
  .tune summary { padding: 8px 0; min-height: 36px; }
  .tune-row { margin-bottom: 12px; }
  .tune-row input[type="range"] { height: 30px; }
  .tune-toggle input[type="checkbox"] { width: 26px; height: 26px; }
}
