/* Shared by every page: the scrolling name rows behind, and the centre band. */

:root {
  --bg: #0a0a0a;
  --ink: #f2f2f0;
  --muted: #b9b9b4;
  --line: #1c1c1b;
  --ghost: #232322;
  --accent: #3dff8f;
  --row: clamp(72px, 15vh, 128px);
}
* { box-sizing: border-box; }
html { background: var(--bg); color-scheme: dark; }
body {
  margin: 0; min-height: 100vh; min-height: 100dvh;
  background: var(--bg); color: var(--ink); font-family: Nunito, system-ui, sans-serif;
  /* The band sits in normal flow (not position: fixed) so a short landscape phone can
     still scroll to the links instead of losing them off-screen. */
  display: grid; align-items: center; overflow-x: hidden;
}

/* background rows */
.rows { position: fixed; inset: 0; display: flex; flex-direction: column; justify-content: center; pointer-events: none; overflow: hidden; }
.row { white-space: nowrap; font-weight: 900; font-size: var(--row); line-height: 1.08; }
.row span {
  display: inline-block;
  color: var(--bg);                        /* fill = background, so glyph interiors are one flat colour */
  -webkit-text-stroke: 3px var(--ghost);   /* half of this sits outside the fill */
  paint-order: stroke fill;                /* stroke first, fill on top: hides the overlaps inside x */
  animation: left 60s linear infinite;
}
.row:nth-child(even) span { animation-name: right; }
@keyframes left  { from { transform: translateX(0); }    to { transform: translateX(-50%); } }
@keyframes right { from { transform: translateX(-50%); } to { transform: translateX(0); } }
/* No prefers-reduced-motion rule, on purpose: Windows reports reduced motion whenever
   "Animation effects" is off, which hid the rows on the owner's machine. */

/* centre band */
.band {
  position: relative;
  min-height: 300px; padding: 40px 24px;
  background: var(--bg); border-block: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center; gap: 44px; flex-wrap: wrap;
}
.head {
  width: 190px; height: 190px; border-radius: 50%; object-fit: cover;
  background: #151514; border: 2px solid var(--accent);
}
h1 { margin: 0; }
.wordmark, .mark-host .mark { width: min(420px, 80vw); height: auto; display: block; }
.divider { width: 1px; height: 150px; background: #262624; }
nav { display: flex; flex-direction: column; gap: 12px; font-size: 20px; font-weight: 800; }
nav a { color: var(--muted); text-decoration: none; white-space: nowrap; transition: color .2s; }
nav a:hover, nav a:focus-visible { color: var(--accent); }
nav a:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 4px; }

@media (max-width: 900px) {
  .band { flex-direction: column; gap: 22px; }
  .head { width: 140px; height: 140px; }
  .divider { display: none; }
  nav { flex-direction: row; gap: 28px; font-size: 18px; }
}
@media (max-width: 400px) {
  nav { gap: 20px; font-size: 17px; }
}

/* 404 */
.code {
  font-size: clamp(120px, 22vw, 190px); font-weight: 900; line-height: .9; letter-spacing: -.02em;
}
.code span { color: var(--accent); }
.lost { display: flex; flex-direction: column; gap: 14px; }
.lost p { margin: 0; font-size: 22px; font-weight: 800; color: var(--ink); }
.lost nav { flex-direction: column; gap: 10px; }
@media (max-width: 900px) {
  .lost { align-items: center; text-align: center; }
  .lost nav { flex-direction: row; }
}

/* ---------- wordmark animations (driven by /js/wordmark.js + /js/intro.js) ---------- */

/* Hidden until the script takes over, so the first show starts from nothing. If the
   script never runs, the static wordmark appears after 2.5s anyway. */
.mark-host:not(.live) { opacity: 0; animation: mark-failsafe 0s 2.5s forwards; }
@keyframes mark-failsafe { to { opacity: 1; } }

.mark { overflow: visible; }
.mark .l, .mark .dot, .mark .o { transform-box: fill-box; transform-origin: 50% 100%; }
.mark .dot { transform-origin: 50% 50%; }
.mark .extra { display: none; }
.mark.wild .l, .mark.wild .dot, .mark.wild .word, .mark.wild .fx *, .mark.wild .under * {
  transform-box: fill-box; transform-origin: 50% 50%;
}

/* The two CSS-only variants on the site: Draw (B) and Ghost (H). The design page has all ten. */
/* B · Draw */
.vB .l { stroke: var(--ink); stroke-width: 12; stroke-opacity: 0; stroke-dasharray: 1; }
.vB.play .l   { animation: b-draw 1.5s cubic-bezier(.45,0,.25,1) both; animation-delay: calc(var(--i) * 70ms); }
.vB.play .dot { animation: b-pop .55s cubic-bezier(.34,1.56,.64,1) both; animation-delay: calc(1.05s + var(--d) * 90ms); }
@keyframes b-draw {
  0%   { stroke-dashoffset: 1; stroke-opacity: 1; fill-opacity: 0; }
  62%  { stroke-dashoffset: 0; stroke-opacity: 1; fill-opacity: 0; }
  100% { stroke-dashoffset: 0; stroke-opacity: 0; fill-opacity: 1; }
}
@keyframes b-pop { from { opacity: 0; transform: scale(0); } }

/* H · Ghost (starts as the background rows' outline, then fills) */
.vH .extra { display: inline; }
.vH .o { fill: var(--bg); stroke: var(--ghost); stroke-width: 24; paint-order: stroke fill; opacity: 0; }
.vH.play .o   { animation: h-outline 1.7s ease both; animation-delay: calc(var(--i) * 40ms); }
.vH.play .l   { animation: h-fill .9s cubic-bezier(.65,0,.35,1) both; animation-delay: calc(450ms + var(--i) * 70ms); }
.vH.play .dot { animation: h-dot .6s cubic-bezier(.34,1.56,.64,1) both; animation-delay: calc(1.1s + var(--d) * 90ms); }
@keyframes h-outline {
  0%   { opacity: 0; stroke: var(--ghost); }
  15%  { opacity: 1; }
  40%  { stroke: #4a4a46; }
  75%  { opacity: 1; }
  100% { opacity: 0; stroke: #4a4a46; }
}
@keyframes h-fill { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes h-dot { from { opacity: 0; transform: scale(.3); } }

/* B · fill falls back to an outline, which then un-draws */
.vB.hide .dot { animation: b-unpop .35s cubic-bezier(.5,0,.75,0) both; animation-delay: calc(var(--d) * 60ms); }
.vB.hide .l   { animation: b-undraw 1.1s cubic-bezier(.45,0,.25,1) both; animation-delay: calc(150ms + var(--i) * 50ms); }
@keyframes b-unpop { to { opacity: 0; transform: scale(0); } }
@keyframes b-undraw {
  0%   { stroke-dashoffset: 0;  stroke-opacity: 0; fill-opacity: 1; }
  35%  { stroke-dashoffset: 0;  stroke-opacity: 1; fill-opacity: 0; }
  100% { stroke-dashoffset: -1; stroke-opacity: 1; fill-opacity: 0; }
}

/* H · the fill drains down, leaving the ghost outline, which fades */
.vH.hide .dot { animation: h-undot .35s ease-in both; animation-delay: calc(var(--d) * 60ms); }
.vH.hide .l   { animation: h-drain .7s cubic-bezier(.65,0,.35,1) both; animation-delay: calc(200ms + var(--i) * 60ms); }
.vH.hide .o   { animation: h-outline-out 1.5s ease both; animation-delay: calc(var(--i) * 40ms); }
@keyframes h-undot { to { opacity: 0; transform: scale(.3); } }
@keyframes h-drain { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(100% 0 0 0); } }
@keyframes h-outline-out {
  0%   { opacity: 0; stroke: #4a4a46; }
  12%  { opacity: 1; }
  60%  { opacity: 1; stroke: #4a4a46; }
  100% { opacity: 0; stroke: var(--ghost); }
}
