/* Three Questions: Pearlescent Night. Tokens, type, the night sky, the
   shared controls and the static pages. Dark first; the light theme
   ("pearl morning") follows prefers-color-scheme. See DESIGN.md. */

@font-face {
  font-family: 'Cormorant';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url(/fonts/cormorant-italic.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(/fonts/cormorant-normal.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(/fonts/figtree-normal.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: dark;
  --bg: #0A0C16;
  --bg-2: #121528;
  --ink: #ECEAF4;
  /* lifted from #B4B3CA so small text clears AA 4.5:1 on the rendered glass (design review H2),
     and a notch more for the clear glass of the night window (measured: 4.42:1 at the brightest pool) */
  --ink-soft: #D5D4E5;
  --line: rgba(255, 255, 255, .13);
  --glass: rgba(255, 255, 255, .055);
  --glass-hi: rgba(255, 255, 255, .1);
  --glass-solid: rgba(22, 25, 46, .96);
  /* night window glass (round 3): a clear pane with a very slight, even
     tint inside its edge (--glass-dim, David, 27 October 2026: "a very
     slight tint to improve readability", then "The glass is still probably a little too
     see through too"), light enough that the night
     shows straight through; the 2 px backdrop blur on the tinted middle is
     not frost: nothing sharp is behind it (the sharp night stops at the
     pane's edge and the pane draws its own copy of it, game.css THE BEND),
     so it only smooths the film grain, as a polished surface would. The
     edge (--edge wide) carries no tint and no blur at all */
  --glass-dim: rgba(9, 10, 22, .26);
  --glass-sheen: rgba(255, 255, 255, .045);
  --glass-flip: rgba(14, 16, 32, .16);
  /* the Fresnel edge: the glass brightest in its last few pixels */
  --fres-1: rgba(255, 255, 255, .34);
  --fres-2: rgba(203, 190, 245, .08);
  /* the edge's own body, seen through its thickness: clear, a touch lighter
     than the tinted middle, with a breath of cool green-blue as thick glass has */
  --edge-body: rgba(214, 228, 255, .055);
  --edge-tint: rgba(170, 226, 230, .12);
  /* the inner reflection: the lit rim seen again from inside the glass, at
     the edge's inner face, a faint glint at the corner toward the pearl only */
  --ref-hi: rgba(255, 255, 255, .26);
  --ref-lo: rgba(255, 255, 255, .05);
  /* the catchlight: where the rim faces the pearl, the glass's edge is lit by
     it and carries the light a little way along itself, as a glass plate's
     edge does under a lamp */
  --glint: rgba(255, 255, 255, .85);
  --glint-bloom: rgba(255, 255, 255, .2);
  --edge-in: rgba(6, 7, 16, .34);
  /* the halo shaped to the words: with the slight tint doing part of the
     work, the lighter three-layer halo (round 2's --halo-lite) carries every
     text style past its floor, measured on the rendered pixels (DESIGN.md) */
  --halo: 0 0 1px rgba(6, 7, 16, .9), 0 0 3px rgba(6, 7, 16, .75), 0 0 9px rgba(6, 7, 16, .6);
  --rim-hi: rgba(255, 255, 255, .78);
  --rim-mid: rgba(255, 255, 255, .20);
  --rim-lo: rgba(255, 255, 255, .06);
  --rim-glint: rgba(255, 255, 255, .22);
  --rim-rose: rgba(243, 198, 217, .12);
  --rim-sky: rgba(185, 216, 245, .12);
  --bevel-hi: rgba(255, 255, 255, .16);
  --bevel-lo: rgba(4, 5, 14, .30);
  --edge-out: transparent;
  --glass-blur: 2px;
  --glass-sat: 135%;
  /* the glass beads: the buttons carry the look of glass without a filter of their own */
  --bead-hi: rgba(255, 255, 255, .22);
  --bead-top: rgba(203, 190, 245, .30);
  --bead-foot: rgba(203, 190, 245, .16);
  --bead-rim: rgba(255, 255, 255, .55);
  --bead-shade: rgba(4, 5, 14, .35);
  --bead-glow: rgba(203, 190, 245, .28);
  /* the bead's own depth: clear glass gives it no veil to sit on, so it carries a thin night of its own (direction 2's graft) */
  --bead-base: rgba(10, 10, 28, .34);
  --ghost-body: rgba(255, 255, 255, .04);
  --ghost-rim: rgba(255, 255, 255, .28);
  --ghost-line: rgba(255, 255, 255, .12);
  --surface: #161A2E;
  --field: rgba(8, 9, 20, .16);
  --field-line: rgba(226, 218, 255, .9);
  --focus: #D9CCFF;
  --danger: #FFB3BF;
  --ok: #A8E8D2;
  --grid: rgba(255, 255, 255, .16);
  --grid-strong: rgba(255, 255, 255, .42);
  --muted-mark: #4F5470;

  --pearl-rose: #F3C6D9;
  --pearl-lilac: #CBBEF5;
  --pearl-sky: #B9D8F5;
  --pearl-mint: #BFEBDD;
  --pearl-gold: #F2DFB0;
  --beam: #FFF7E6;
  --beam-glow: rgba(203, 190, 245, .55);

  --hue-colour: #D66F4F;
  --hue-animal: #8C7BEA;
  --hue-water: #2BA59B;

  --iris: linear-gradient(100deg, #F6D3E3, #D9CCFF 22%, #C4E3FF 44%, #CFF3E6 66%, #F6E6BF 84%, #F6D3E3);
  --strike: linear-gradient(90deg, var(--pearl-rose), var(--pearl-lilac), var(--pearl-sky), var(--pearl-mint));
  --btn-bg: linear-gradient(110deg, var(--pearl-rose), var(--pearl-lilac) 45%, var(--pearl-sky));
  --btn-ink: #14122A;
  --shadow: 0 30px 80px -30px rgba(0, 0, 0, .7);
  --pool-a: rgba(140, 118, 230, .30);
  --pool-b: rgba(232, 140, 180, .18);
  --pool-c: rgba(120, 210, 190, .14);
  --grain-opacity: .07;
  /* the small "more below" chevron at the foot of a card that scrolls (game.css) */
  --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 12'%3E%3Cpath d='M2 2l8 8 8-8' fill='none' stroke='%23CFCEE0' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --bk-mid: rgba(185, 216, 245, .08);
  --bk-warm: rgba(243, 198, 217, .07);
  --bk-near: rgba(203, 190, 245, .055);
  /* the sharp night the glass shows itself against (game.css): plain points
     of light and nothing else (no lines, no rings, never joined), full
     outside the pane and in its edge, a finer copy held to 30% beside the
     words and none under them (--star-in) (img/night-points.svg, img/night-points-fine.svg, masks) */
  --star: #F1EEFF;
  --star-o: .5;
  --star-in: .3;
  /* in the edge the glass gathers the light it bends: brighter than the open sky */
  --star-rim: 1;

  --display: "Cormorant", "Iowan Old Style", Georgia, serif;
  --body: "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;
  --ease-light: cubic-bezier(.45, 0, .2, 1);
  --ease-spring: cubic-bezier(.3, 1.4, .5, 1);
  --radius: 28px;
}

@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;
    --bg: #F6F3EF;
    --bg-2: #EEEAF4;
    --ink: #1B1930;
    --ink-soft: #4E4B66;
    --line: rgba(27, 25, 48, .14);
    --glass: rgba(255, 255, 255, .62);
    --glass-hi: rgba(255, 255, 255, .9);
    --glass-solid: rgba(252, 251, 253, .98);
    /* morning glass: the slight tint is pearl white, and the middle's
       backdrop is flattened (--glass-sat under 100%), so the pink and mint
       blooms lie even behind the text column; the edge keeps the morning's
       full colour and reads by its thickness, a cool shade with a white lip */
    --glass-dim: rgba(248, 245, 255, .3);
    --glass-sheen: rgba(255, 255, 255, .3);
    --glass-flip: rgba(250, 249, 252, .3);
    --fres-1: rgba(255, 255, 255, .95);
    --fres-2: rgba(255, 255, 255, .3);
    --edge-body: rgba(52, 84, 118, .075);
    --edge-tint: rgba(70, 150, 165, .14);
    --ref-hi: rgba(255, 255, 255, .6);
    --ref-lo: rgba(255, 255, 255, .14);
    --glint: rgba(255, 255, 255, .95);
    --glint-bloom: rgba(255, 255, 255, .6);
    --edge-in: rgba(60, 50, 110, .1);
    --halo: 0 0 1px rgba(255, 255, 255, .9), 0 0 3px rgba(255, 255, 255, .78), 0 0 9px rgba(255, 255, 255, .68);
    --rim-hi: rgba(255, 255, 255, .95);
    --rim-mid: rgba(255, 255, 255, .6);
    --rim-lo: rgba(255, 255, 255, .35);
    --rim-glint: rgba(255, 255, 255, .7);
    --rim-rose: rgba(214, 130, 170, .12);
    --rim-sky: rgba(90, 150, 210, .12);
    --bevel-hi: rgba(255, 255, 255, .7);
    --bevel-lo: rgba(60, 50, 110, .10);
    --edge-out: rgba(60, 50, 110, .2);
    --glass-sat: 85%;
    --bead-hi: rgba(255, 255, 255, .6);
    --bead-top: rgba(203, 190, 245, .78);
    --bead-foot: rgba(185, 170, 240, .6);
    --bead-rim: rgba(255, 255, 255, .9);
    --bead-shade: rgba(60, 50, 110, .22);
    --bead-glow: rgba(255, 255, 255, .35);
    --bead-base: rgba(255, 255, 255, .28);
    --ghost-body: rgba(255, 255, 255, .4);
    --ghost-rim: rgba(255, 255, 255, .9);
    --ghost-line: rgba(60, 50, 110, .2);
    --surface: #FBFAFC;
    --field: rgba(255, 255, 255, .8);
    --field-line: rgba(60, 50, 110, .86);
    --focus: #5B3FD0;
    --danger: #A3202E;
    --ok: #1F6B52;
    --grid: rgba(27, 25, 48, .16);
    --grid-strong: rgba(27, 25, 48, .45);
    --muted-mark: #C9C5D6;
    --beam: #FFFFFF;
    --beam-glow: rgba(106, 63, 201, .45);
    --hue-colour: #B5562F;
    --hue-animal: #6A4FD0;
    --hue-water: #00907A;
    /* the jewels a notch deeper than before: through clear glass the lilac
       morning shows at its full depth behind the words (4.5:1 or more on it) */
    --iris: linear-gradient(100deg, #52299F, #8E2A61 25%, #145570 50%, #1D5C46 72%, #52299F);
    --strike: linear-gradient(90deg, #B03A7A, #6A3FC9, #1D6F8F);
    --btn-bg: linear-gradient(110deg, #1B1930, #2D2650 60%, #1B1930);
    --btn-ink: #FFFFFF;
    --shadow: 0 30px 70px -35px rgba(60, 50, 110, .38);
    --pool-a: rgba(203, 190, 245, .65);
    --pool-b: rgba(243, 198, 217, .6);
    --pool-c: rgba(191, 235, 221, .6);
    --grain-opacity: .05;
    --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 12'%3E%3Cpath d='M2 2l8 8 8-8' fill='none' stroke='%234E4B66' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --bk-mid: rgba(185, 216, 245, .22);
    --bk-warm: rgba(243, 198, 217, .22);
    --bk-near: rgba(203, 190, 245, .13);
    /* morning: violet points, darker in the edge where the glass bends them,
       so the bend survives a pale ground */
    --star: #5B45B8;
    --star-o: .36;
    --star-in: .26;
    --star-rim: .95;
  }
}

*, *::before, *::after { box-sizing: border-box; }
/* The page's own ground is the sky's foot colour (design review M4), so a
   phone's rubber-band past the foot of the page shows no band: the sky
   (.sky, fixed) paints everything inside the window. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; background: var(--bg-2); }
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: transparent;
  color: var(--ink);
  font: 400 1rem/1.6 var(--body);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  touch-action: manipulation;
  /* no automatic hyphenation anywhere: a word breaks only where it is
     written with a hyphen (the welcome once showed "an-swers") */
  -webkit-hyphens: manual;
  hyphens: manual;
}
img, svg, canvas { display: block; max-width: 100%; }
a { color: inherit; text-underline-offset: .2em; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }
button, input, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
[hidden] { display: none !important; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; margin: -1px; padding: 0; border: 0;
}

/* --- the night sky: light pools and film grain --- */
.sky { position: fixed; inset: 0; z-index: -2; overflow: hidden; background: linear-gradient(180deg, var(--bg), var(--bg-2)); }
/* the fixed sky is one large box, the window at its tallest (100lvh), so a
   phone's toolbar sliding away never resizes it and nothing in it moves */
@supports (height: 100lvh) { .sky { bottom: auto; height: 100lvh; } }
/* the sky's two paces (THE SLOW SKY below): --sky-pace for the pools and
   the discs, 3, and --points-pace for the sharp points (game.css), 5, the
   pace David picked from four in a lab page of the real welcome ("Lively",
   28 October 2026). Every duration is its base over its knob and every
   delay a fraction of that, so a knob of 2 doubles a layer's pace and sends
   it nowhere new. */
:root { --sky-pace: 3; --points-pace: 5; }
/* the pools are soft by their own gradient, not by a 70 px filter: the same
   light, and no blur for the phone's GPU to run on every frame of the drift */
.pool {
  position: absolute; border-radius: 50%; will-change: transform;
  background: radial-gradient(closest-side, var(--c), transparent);
  background: radial-gradient(closest-side, var(--c) 0 34%, color-mix(in srgb, var(--c) 62%, transparent) 60%, color-mix(in srgb, var(--c) 22%, transparent) 82%, transparent);
}
.pool--a { --c: var(--pool-a); width: 72vmax; height: 72vmax; left: -27vmax; top: -31vmax; animation: drift-a calc(92s / var(--sky-pace)) ease-in-out calc(92s / var(--sky-pace) / -2) infinite alternate; animation-play-state: var(--motion, running); }
.pool--b { --c: var(--pool-b); width: 54vmax; height: 54vmax; right: -22vmax; top: calc(28vh - 4vmax); animation: drift-b calc(100s / var(--sky-pace)) ease-in-out calc(100s / var(--sky-pace) / -2) infinite alternate; animation-play-state: var(--motion, running); }
.pool--c { --c: var(--pool-c); width: 61vmax; height: 61vmax; left: calc(8vw - 4.5vmax); bottom: -36.5vmax; animation: drift-c calc(80s / var(--sky-pace)) ease-in-out calc(80s / var(--sky-pace) / -2) infinite alternate; animation-play-state: var(--motion, running); }
@keyframes drift-a { to { transform: translate(8vmax, 6vmax) scale(1.08); } }
@keyframes drift-b { to { transform: translate(-6vmax, -8vmax) scale(.94); } }
@keyframes drift-c { to { transform: translate(-4vmax, -6vmax) scale(1.1); } }
/* Cinematic's floating discs of light, made quieter and set drifting (David,
   23 October 2026: "can they move slightly and be more subtle visually"):
   five, at two depths, each wandering a slow loop of a few vmax over a
   minute and a half or more; under reduced motion they hold still.
   THE SLOW SKY (David, 27 October 2026: "can the background have some very
   slow motion to help sell that glass effect please? different things moving
   at different paces please?"): the night drifts in layers, the nearest
   fastest. At their quickest at David's "Lively" (28 October 2026, the
   knobs above), measured in Chromium: at 1280 by 800 the sharp points 4.5
   px/s (game.css, the one edge the eye can follow), the pools 6.0 to 7.2,
   the middle discs 8.0 to 9.3, the near discs 10.1 to 11.7; at 390 by 844
   the points the same (they travel in px) and the soft layers two thirds
   of theirs, the pools 4.0 to 4.8, the middle discs 5.3 to 6.1, the near
   discs 6.7 to 7.7. Only the durations and
   the starting moments were changed: every place a pool or a disc visits is
   where it was, so the glass's measured contrast holds (--ink-soft above,
   GLASS_WORST in fx.js). Transform alone.
   NONE FROM REST (David, 28 October 2026, on his iPhone: "It doesn't animate
   on my phone."): every layer used to start each load from rest, a pixel or
   two in its first ten seconds, so each now starts part way through its
   travel, the pools halfway (their quickest) and each disc mid-leg or
   already partway along one. */
.bokeh { position: absolute; inset: 0; pointer-events: none; }
.bk {
  position: absolute; display: block; border-radius: 50%; aspect-ratio: 1; width: var(--s);
  animation: var(--path, bk-a) calc(var(--d, 44s) / var(--sky-pace)) ease-in-out calc(var(--dl, 0s) / var(--sky-pace)) infinite;
  animation-play-state: var(--motion, running);
}
.bk--mid { background: radial-gradient(circle, var(--bk-mid) 0 30%, transparent 70%); }
.bk--near { background: radial-gradient(circle, var(--bk-near) 0 18%, transparent 68%); filter: blur(2px); }
/* each disc placed by its place among its own kind, so every page puts the
   same light in the same place; the delays (--dl, a time at --sky-pace 1,
   scaled with --d) start each disc moving: the first middle disc in the
   middle of bk-a's last leg, the near ones in the middle of bk-c's second
   leg and bk-a's first, the other two already partway along a leg (the
   legs: bk-a 0-33-66-100, bk-b 0-30-70-100, bk-c 0-40-75-100) */
.bk:nth-child(1 of .bk--mid) { left: 58%; top: 26%; --s: 12vmax; --d: 106s; --dl: calc(-.83 * var(--d)); }
.bk:nth-child(2 of .bk--mid) { left: 18%; top: 40%; --s: 14vmax; --d: 116s; --dl: -25s; --path: bk-c; background: radial-gradient(circle, var(--bk-warm) 0 30%, transparent 70%); }
.bk:nth-child(3 of .bk--mid) { left: 44%; top: 70%; --s: 10vmax; --d: 100s; --dl: -56s; --path: bk-b; }
.bk:nth-child(1 of .bk--near) { left: -10%; top: -12%; --s: 34vmax; --d: 92s; --dl: calc(-.575 * var(--d)); --path: bk-c; }
.bk:nth-child(2 of .bk--near) { left: 68%; top: 64%; --s: 30vmax; --d: 94s; --dl: calc(-.165 * var(--d)); }
@keyframes bk-a { 0%, 100% { transform: none; } 33% { transform: translate(3vmax, -2vmax); } 66% { transform: translate(-1.5vmax, -3.5vmax); } }
@keyframes bk-b { 0%, 100% { transform: none; } 30% { transform: translate(-2.5vmax, 1.5vmax); } 70% { transform: translate(2vmax, 3vmax); } }
@keyframes bk-c { 0%, 100% { transform: none; } 40% { transform: translate(2.5vmax, 2.5vmax); } 75% { transform: translate(-3vmax, 1vmax); } }
/* the sky holds still where the glass is made solid or the colours are
   forced (the points are not drawn there at all, game.css) and on the
   pearl's low-power signals (power.js, one class at boot: main.js on the
   game, footer.js on the static pages); while a dialog is open it pauses,
   every layer at once, so the night and its copies stay in step and the
   dialog's blurred backdrop is not drawn again every frame */
@media (prefers-contrast: more), (prefers-reduced-transparency: reduce), (forced-colors: active) {
  .sky :is(.pool, .bk) { animation: none; }
}
.sky-still :is(.pool, .bk, .night > i, .lens-sky > i) { animation: none; }
:root:has(dialog[open]) :is(.pool, .bk, .night > i, .lens-sky > i) { animation-play-state: paused; }
/* THE PAUSE (the footer's "Pause motion", js/motion.js; WCAG 2.2.2): every
   endless animation on every page reads animation-play-state from --motion,
   so one attribute on <html> holds each where it is and lets it go on from
   there. Only the endless ones: an entrance or a press (the nudge, a step's
   dot, the Turnstile slot) still plays out, as each is over within a second
   and, held at its first frame, would hide what it brings in. A dialog's
   pause above holds the sky on its own, so a manual pause outlasts it. */
:root[data-motion="paused"] { --motion: paused; }
.grain {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image: url(/img/grain.svg); background-size: 220px 220px;
  opacity: var(--grain-opacity); mix-blend-mode: overlay;
}

/* --- page frame --- */
.page { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; }
.masthead {
  width: min(100% - 2rem, 1120px); margin-inline: auto;
  padding-block: max(.9rem, env(safe-area-inset-top)) .4rem;
  display: flex; align-items: center; justify-content: center;
}
.brand { display: inline-flex; align-items: center; gap: .6rem; min-height: 44px; text-decoration: none; }
/* the brand line's mark: a small CSS pearl, or the live pearl when it docks here */
.brand-slot { position: relative; display: grid; place-items: center; width: 34px; height: 34px; flex: none; }
.brand-slot > * { grid-area: 1 / 1; }
.brand-slot .brand-mark { transition: opacity .3s ease; }
.brand-slot.has-pearl .brand-mark { opacity: 0; }
/* one pearl at a time: while the big pearl lights the welcome or the wait, the brand line's mark stands aside (design review L1) */
body[data-screen="welcome"] .brand-mark, body[data-screen="loading"] .brand-mark { opacity: 0; }
.brand-mark {
  width: 22px; height: 22px; border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #fff 0 8%, transparent 30%), conic-gradient(from 30deg, var(--pearl-rose), var(--pearl-lilac), var(--pearl-sky), var(--pearl-mint), var(--pearl-gold), var(--pearl-rose));
  box-shadow: 0 0 14px 1px var(--beam-glow), inset -3px -4px 6px rgba(20, 16, 40, .35);
}
.brand-word { font: italic 600 1.35rem/1 var(--display); letter-spacing: .005em; }

/* --- type --- */
.eyebrow, .cap {
  margin: 0; font: 600 .875rem/1.3 var(--body); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft);
}
.display { margin: 0; font: italic 600 clamp(2rem, 7vw, 3rem)/1.05 var(--display); letter-spacing: -.005em; text-wrap: balance; }
.lede-sm { margin: .8rem 0 0; font-size: 1.08rem; color: var(--ink-soft); max-width: 46ch; }
.iris-text {
  background: var(--iris); background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* --- glass: NIGHT WINDOW, round 3 (David, 26 October 2026: "The frosted
   glass looks dreadful, I was hoping for proper glass effect"; 27 October
   2026: "A, made bolder however I don't like those lines in the
   background" and "The glass I think just needs to have a very slight tint
   to improve readability"). Clear glass, not frost, and thick enough to
   see. Three parts:
   1. THE EDGE, the outer --edge of the pane (14 px on a phone, 16 px on a
      tablet, 18 px on a laptop): no tint and no blur at all, a touch
      lighter than the middle (--edge-body), a Fresnel ramp that brightens
      over its last few pixels (inset shadows, so it follows the corners),
      a thin dark line just inside the rim, and the points of light gathered
      brighter in it; once the player has touched or typed they bend and
      split into a small soft spectrum there (game.css THE BEND);
   2. THE MIDDLE (.pane in a card, the pane's own background on a page): a
      very slight even tint (--glass-dim) with a 2 px blur that only
      smooths the film grain, and the pane's own finer copy of the points
      showing straight through it, sharp;
   3. THE LIGHT: a 1.5 px specular rim whose bright side faces the pearl
      (the pearl is the lamp: --light is set from where it sits, fx.js
      aimLight), a catchlight where the rim faces it, and one faint glint
      of inner reflection at the edge's inner face, at the corner toward the
      pearl (--kx, --ky), gone within a few pixels along both sides, so it
      never reads as a second drawn line (David, 27 October 2026: "I don't
      like those lines").
   The words keep their contrast by the tint and a halo shaped to the words
   themselves (--halo, a text shadow wide enough to count as background:
   WCAG technique G18). In the game the glass is the card's face (flip.js).
   Solid where blur is missing, where less see-through or more contrast is
   asked for, and in forced colours. --- */
@property --light { syntax: '<angle>'; inherits: true; initial-value: 0deg; }
.glass, .face {
  --light: 0deg;
  --lx: 50%; --ly: -10%;
  --kx: 0%; --ky: 0%;
  --bx: 0px; --by: 1px;
  --edge: 16px;
  position: relative; isolation: isolate;
  border: 0; border-radius: var(--radius);
  background: radial-gradient(52% 34% at var(--lx) var(--ly), var(--glass-sheen), transparent 72%);
  box-shadow:
    0 0 0 1px var(--edge-out),
    var(--shadow),
    inset var(--bx) var(--by) 0 0 var(--bevel-hi),
    inset 0 0 2px 1px var(--edge-in),
    inset 0 0 6px var(--fres-1),
    inset 0 0 calc(var(--edge) * .9) calc(var(--edge) * .3) var(--edge-body),
    inset 0 0 calc(var(--edge) * 1.1) calc(var(--edge) * -.25) var(--edge-tint),
    inset 0 0 34px -8px var(--fres-2),
    inset calc(var(--bx) * -10) calc(var(--by) * -14) 28px -14px var(--bevel-lo);
  text-shadow: var(--halo);
  transition: --light .6s var(--ease-light);
}
@media (max-width: 480px) { .glass, .face { --edge: 14px; } }
@media (min-width: 900px) { .glass, .face { --edge: 18px; } }
/* the middle: the very slight tint and the 2 px blur, inside the edge only.
   On a page (.glass) it is the pane's own ground; a card (.face) carries it
   as its own layer (.pane, made by fx.js makeLens), so the edge stays clear
   and the blur never reaches the bent edge (and in WebKit the bend's
   filter: url() never sits under a backdrop filter) */
.glass {
  background:
    radial-gradient(52% 34% at var(--lx) var(--ly), var(--glass-sheen), transparent 72%),
    linear-gradient(var(--glass-dim), var(--glass-dim));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
}
.face > .pane {
  position: absolute; inset: var(--edge); z-index: -3; pointer-events: none;
  border-radius: max(6px, calc(var(--radius) - var(--edge)));
  background: linear-gradient(var(--glass-dim), var(--glass-dim));
  /* its rim feathered a few pixels into the edge, so the edge's inner face is a change of light, never a drawn line */
  box-shadow: 0 0 7px 1px var(--glass-dim);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
}
/* where the page scrolls (a phone, a tablet, a short window) a face can be
   several screens tall, and a backdrop filter that tall is drawn as a band
   with a hard top edge, a lighter rectangle across the card (design review,
   27 October 2026): there the middle is the flat tint alone. A laptop's card
   is never taller than the window and keeps its blur. */
@media not all and (min-width: 900px) and (min-height: 560px) {
  .face > .pane { -webkit-backdrop-filter: none; backdrop-filter: none; }
}
/* words painted by a background clipped to the text carry no text shadow
   (it would paint over them); they are display sizes, held at 3:1 */
.glass :is(.iris-text, .title-rest, .num-word, .new, .mirror-own),
.face :is(.iris-text, .title-rest, .num-word, .new, .mirror-own),
.face .mirror.is-inked .mirror-line { text-shadow: none; }
/* a numbered point's badge is its own ground (--btn-ink on --btn-bg): the
   halo, made for words on the glass, would smudge its digit */
.face .point::before { text-shadow: none; }
/* the specular rim: a conic gradient shown only in a 1.5 px ring */
.glass::before, .face::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; padding: 1.5px;
  pointer-events: none;
  background: conic-gradient(from var(--light),
    var(--rim-hi) 0deg, var(--rim-sky) 14deg, var(--rim-mid) 40deg, var(--rim-lo) 100deg,
    var(--rim-glint) 180deg,
    var(--rim-lo) 260deg, var(--rim-mid) 320deg, var(--rim-rose) 346deg, var(--rim-hi) 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
}
/* the inner reflection: thick glass shows its lit rim a second time, at its
   back face, where the edge meets the middle; a faint 1 px glint at the
   corner toward the pearl, gone within a few pixels along both sides, so it
   reads as light caught inside the glass, never as a frame or an arc */
.glass::after, .face::after {
  content: ""; position: absolute; inset: calc(var(--edge) - 1px); z-index: -1; pointer-events: none;
  border-radius: max(6px, calc(var(--radius) - var(--edge) + 1px)); padding: 1px;
  background: radial-gradient(22px 18px at var(--kx) var(--ky), var(--ref-hi), var(--ref-lo) 45%, transparent);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
}
.svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .glass, .face { background: var(--glass-solid); }
  .face > .pane { display: none; }
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  .glass, .face { background: var(--glass-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .face > .pane { display: none; }
  .glass, .face { text-shadow: none; }
  .glass::before, .face::before { background: var(--rim-hi); }
  .glass::after, .face::after { display: none; }
}

/* --- buttons --- */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  min-height: 52px; min-width: 44px; padding: .8rem 1.7rem; border-radius: 999px; cursor: pointer;
  font: 600 1.02rem/1.15 var(--body); text-decoration: none; text-align: center;
  border: 1px solid transparent; background: none; isolation: isolate; overflow: hidden;
  transform: scale(var(--press, 1));
  transition: transform .2s ease, box-shadow .3s ease, background-color .2s ease, border-color .2s ease;
  -webkit-tap-highlight-color: transparent;
}
.btn:active { transform: scale(.97); transition-duration: .08s; }
/* With motion allowed, playful's damped spring (js/fx.js, toned right down)
   owns the press: one gentle give and release, no lean, no hop. */
.is-springy .btn { transition: box-shadow .3s ease, background-color .2s ease, border-color .2s ease; }
.is-springy .btn:active { transform: scale(var(--press, 1)); }
/* Glass beads (research-look 1.5): the buttons sit on the card, whose glass
   is already blurred, so they carry the look of glass with no filter of their
   own: a lit body, a bright rim at the top, a shade at the foot, an inner
   glow. No pastel fill, no sheen sweep, no hover glow (audit S8): a hover
   lifts the inner glow a little and nothing moves. */
.btn--primary {
  color: var(--ink);
  background:
    radial-gradient(90% 120% at 30% 0%, var(--bead-hi), transparent 60%),
    linear-gradient(180deg, var(--bead-top), var(--bead-foot)),
    linear-gradient(var(--bead-base), var(--bead-base));
  box-shadow:
    inset 0 1px 0 var(--bead-rim), inset 0 -1px 0 var(--bead-shade),
    inset 0 0 18px var(--bead-glow), 0 8px 24px -12px var(--beam-glow);
}
.btn--primary:hover {
  box-shadow:
    inset 0 1px 0 var(--bead-rim), inset 0 -1px 0 var(--bead-shade),
    inset 0 0 26px var(--bead-glow), 0 8px 24px -12px var(--beam-glow);
}
.btn--ghost {
  color: var(--ink); background: var(--ghost-body);
  box-shadow: inset 0 1px 0 var(--ghost-rim), inset 0 0 0 1px var(--ghost-line);
}
.btn--ghost:hover { box-shadow: inset 0 1px 0 var(--ghost-rim), inset 0 0 0 1px var(--grid-strong), inset 0 0 14px var(--bead-glow); }
.btn--text {
  min-height: 44px; padding: .5rem .6rem; border-radius: 12px; color: var(--ink-soft);
  text-decoration: underline; text-underline-offset: .22em;
}
.btn--text:hover { color: var(--ink); }
.btn-arrow { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform .3s var(--ease-spring); }
.btn:hover .btn-arrow { transform: translateX(4px); }

/* --- fields --- */
.field { display: grid; gap: .4rem; }
label { font-weight: 600; }
.hint { margin: 0; font-size: .92rem; color: var(--ink-soft); }
input[type="text"], input[type="email"], textarea {
  width: 100%; min-height: 52px; padding: .8rem 1rem; border-radius: 16px;
  border: 1px solid var(--field-line); background: var(--field); color: var(--ink);
  font-size: 1.0625rem; line-height: 1.5;
  transition: border-color .2s ease, box-shadow .25s ease, background-color .2s ease;
}
/* on morning glass a dark hairline on a 1x screen lands across two pixels and
   greys out; a hair wider, it keeps 3:1 against the glass on both sides */
@media (prefers-color-scheme: light) { input[type="text"], input[type="email"], textarea { border-width: 1.5px; } }
input[type="text"]:hover, input[type="email"]:hover, textarea:hover { border-color: var(--grid-strong); }
input[type="text"]:focus-visible, input[type="email"]:focus-visible, textarea:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-color: transparent; box-shadow: 0 0 0 6px var(--beam-glow); }
[aria-invalid="true"] { border-color: var(--danger) !important; }
.field-error { margin: 0; min-height: 0; font-size: .95rem; font-weight: 600; color: var(--danger); }
.field-error:empty { display: none; }
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

/* --- footer --- */
.site-foot {
  width: min(100% - 2rem, 1120px); margin: auto auto 0; padding: 2.4rem 0 max(1.6rem, env(safe-area-inset-bottom));
  display: grid; justify-items: center; gap: .35rem; text-align: center; font-size: .875rem; color: var(--ink-soft);
}
.site-foot p { margin: 0; overflow-wrap: anywhere; }
.foot-links { display: flex; gap: .4rem 1.2rem; flex-wrap: wrap; justify-content: center; }
/* the links' own landmark inside the row, laid out as the row is, so the row
   reads Privacy, Credits, the pause, spaced alike (final review, 28 October 2026) */
.foot-nav { display: flex; gap: .4rem 1.2rem; flex-wrap: wrap; justify-content: center; }
.foot-links a, .foot-credit a { display: inline-flex; align-items: center; min-height: 44px; padding-inline: .2rem; }
/* the pause (js/motion.js): a quiet button beside the links, in their words'
   size and colour, no underline (it is not a link), its small mark what a
   press does next: two bars, or a play triangle while the motion is paused
   (read from <html>, as the button carries no aria-pressed) */
.foot-motion {
  display: inline-flex; align-items: center; gap: .45rem; min-height: 44px; min-width: 44px; padding: 0 .45rem;
  border: 0; border-radius: 12px; background: none; color: inherit; font: inherit; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.foot-motion::before { content: ""; flex: none; width: 8px; height: 10px; border-inline: 3px solid currentColor; }
:root[data-motion="paused"] .foot-motion::before { width: 0; height: 0; border-style: solid; border-width: 5px 0 5px 9px; border-color: transparent transparent transparent currentColor; }
.foot-motion:hover { color: var(--ink); }
@media (prefers-reduced-motion: reduce) { .foot-motion { display: none; } }
.foot-small { max-width: 52ch; }
.ai-line { margin: 0; font-size: .875rem; color: var(--ink-soft); letter-spacing: .01em; }
/* on a laptop the footer is one quiet band, so the whole screen fits */
@media (min-width: 900px) {
  .site-foot { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; column-gap: 1.4rem; row-gap: 0; padding-top: .6rem; padding-bottom: max(.7rem, env(safe-area-inset-bottom)); }
  .foot-small { max-width: none; }
}

/* --- static pages: privacy, credits, 404 --- */
.doc {
  width: min(100% - 2rem, 780px); margin: 1.2rem auto 0; padding: clamp(1.4rem, 5vw, 3rem);
}
.doc h1 { margin: .4rem 0 1rem; font: italic 600 clamp(2.4rem, 8vw, 3.6rem)/1.02 var(--display); }
.doc h2 { margin: 2.2rem 0 .6rem; font: 600 1.5rem/1.2 var(--display); }
.doc h3 { margin: 1.4rem 0 .4rem; font-size: 1.05rem; }
.doc p, .doc li { max-width: 66ch; }
.doc ul { padding-left: 1.2rem; }
.doc li + li { margin-top: .35rem; }
.doc .draft { padding: .8rem 1rem; border-radius: 14px; border: 1px dashed var(--line); color: var(--ink-soft); font-size: .92rem; }
.signup-page form { margin: 1.4rem 0 1rem; }
.doc .back { display: inline-flex; align-items: center; gap: .4rem; min-height: 44px; font-weight: 600; }
.doc pre { white-space: pre-wrap; font-size: .82rem; color: var(--ink-soft); max-height: 22rem; overflow: auto; padding: 1rem; border-radius: 14px; border: 1px solid var(--line); }
.doc-pearl {
  width: 72px; height: 72px; border-radius: 50%; margin-bottom: .6rem;
  background: radial-gradient(circle at 34% 30%, #fff 0 6%, rgba(255,255,255,.4) 14%, transparent 32%), conic-gradient(from 30deg, var(--pearl-rose), var(--pearl-lilac), var(--pearl-sky), var(--pearl-mint), var(--pearl-gold), var(--pearl-rose));
  box-shadow: 0 0 50px 4px var(--beam-glow), inset -10px -14px 22px rgba(20, 16, 40, .35);
}

@media (forced-colors: active) {
  .glass, .face { background: Canvas; border: 1px solid CanvasText; -webkit-backdrop-filter: none; backdrop-filter: none; }
  .glass::before, .face::before, .glass::after, .face::after, .face > .pane { display: none; }
  .iris-text, .title, .title-rest, .num-word, .new { color: CanvasText !important; background: none !important; }
  .bokeh { display: none !important; }
  .glass, .face { text-shadow: none; }
  .btn { border: 1px solid ButtonText; }
  .foot-motion { border: 1px solid ButtonText; color: ButtonText; }
  .foot-motion::before { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}
