    /* home polish: never cut words, fit phones, no sideways scroll */
    html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
    body { overflow-x: hidden; }
    h1, h2, h3, p, li, label, button, a, figcaption { overflow-wrap: anywhere; }
    img, video, canvas, iframe { max-width: 100%; }
    :root {
      color-scheme: dark;
      --bg: #050505;
      --fg: #e8e8e8;
      --muted: #8a8a8a; /* 5.6:1 on the void: readable (WCAG AA) */
      --line: #1a1a1a;
      --accent: #cfcfcf;
    }
    * { box-sizing: border-box; }
    html, body {
      margin: 0; height: 100%;
      background: var(--bg); color: var(--fg);
      font: 15px/1.45 ui-sans-serif, system-ui, -apple-system, Segoe UI, sans-serif;
    }
    #stage {
      position: fixed; inset: 0 0 72px 0;
      overflow: hidden;
    }
    /* home stage: the empty void, in the first stylesheet */
    #dock {
      position: fixed; left: 0; right: 0; bottom: 0;
      padding: 12px 16px 18px;
      background: linear-gradient(to top, #050505 60%, transparent);
    }
    #row {
      max-width: 720px; margin: 0 auto;
      display: flex; gap: 8px; align-items: center;
      border: 1px solid var(--line);
      border-radius: 999px;
      padding: 8px 10px 8px 18px;
      background: rgba(12,12,12,0.92);
    }
    #input {
      flex: 1; border: 0; outline: 0; background: transparent;
      color: var(--fg); font: inherit; min-width: 0;
    }
    #input::placeholder { color: var(--muted); }
    /* the ask bar's round keys (mic, sound, send): one dark style, here in the first stylesheet and in verse-critical, never in the card
       sheet that loads with the first ask (owner, 2026-11-06: the empty stage showed the mic and the speaker as the browser's grey buttons) */
    #go, #mic, #sound { appearance: none; -webkit-appearance: none; border: 0; border-radius: 999px; background: #1c2030; color: #f2f4fb;
      min-width: 44px; min-height: 44px; padding: 0 12px; font: inherit; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; flex: none; }
    #mic, #sound { width: 44px; padding: 0; color: #c9cee0; }
    #sound[hidden] { display: none; } /* a fresh visit is the void: the speaker appears with the first touch, move or key */
    #mic svg, #sound svg { width: 18px; height: 18px; display: block; flex: none; }
    #mic.listening { color: #fff; background: #26304a; }
    #void-glow { position: fixed; inset: 0; pointer-events: none; z-index: 0;
      background: radial-gradient(circle at 50% 45%, var(--void-glow, var(--sky-glow, #0b0b10)), transparent 70%);
      opacity: 0; transition: opacity 1.5s ease; }
    body.void-entered #void-glow, html.void-entered #void-glow { opacity: 1; }
    html.sky-on #void-glow { opacity: 1; } /* the real sky tints the empty stage too (skills/sky-rules.js); a look the visitor chose still wins */
    html.void-first, html.void-first #void-glow, html.void-first #void-stars { transition: none !important; }
    html.void-first body { background: var(--void-bg, var(--sky-bg, #050505)); }
    #void-stars { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0;
      opacity: 0; transition: opacity 1.5s ease; }
    #void-stars.on { opacity: 1; }
    /* your drawing behind your Verse (skills/draw.js, "make it my backdrop"): kept in the look, synced with the passkey */
    #void-backdrop { position: fixed; inset: 0; z-index: 0; pointer-events: none; background: center / contain no-repeat; opacity: 0; transition: opacity 1.2s ease; }
    #void-backdrop.on { opacity: 1; }
    #stage, #dock { z-index: 1; }
    html.dragging, html.dragging * { user-select: none !important; -webkit-user-select: none !important; cursor: grabbing !important; }
    #void-swarm { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; opacity: 0; transition: opacity 1.2s ease; }
    #void-swarm.on { opacity: 1; }
    body.void-quiet { font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, sans-serif; font-weight: 300; }
    /* ---- Atmosphere + depth (the void stays empty; it just breathes) ---- */
    #void-aura { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; opacity: 0; transition: opacity 2.4s ease; }
    #void-aura.on { opacity: 1; }
    html.no-gl[data-fx="nebula"] body::before { content: ''; position: fixed; inset: -20%; z-index: 0; pointer-events: none;
      background: radial-gradient(40% 35% at 30% 40%, color-mix(in srgb, var(--void-glow, var(--sky-glow, #0b0b10)) 70%, #1a1030), transparent 70%),
                  radial-gradient(35% 30% at 70% 60%, color-mix(in srgb, var(--void-glow, var(--sky-glow, #0b0b10)) 60%, #06202a), transparent 70%);
      filter: blur(40px); opacity: .7; animation: auraDrift 60s ease-in-out infinite alternate; }
    @keyframes auraDrift { to { transform: translate(3%, -2%) scale(1.08); } }
    #stage { perspective: 1400px; }
    #stage > .shrunk, #stage > .shrunk * { cursor: zoom-in; } /* a board shrunk beside a newer one: a tap brings it back */
    .thing:focus-visible { outline: 2px solid rgba(170,190,255,.85); outline-offset: 3px; } /* a card the keyboard reached shows it */
    /* Accessibility modes (tools pack 7, owner 2026-10-18; skills/accessibility-modes.js). Each switch is a class on <html>, put on by the first-frame script above
       before the first paint and by the skill. Nothing here changes the look unless a class is on. */

    /* reduced motion, the hard switch: nothing animates or eases; the worlds and figures also read the same switch (a2m.void.motion.v1) */
    html.a11y-motion *, html.a11y-motion *::before, html.a11y-motion *::after {
      animation-duration: 0.001ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important;
      transition-duration: 0.001ms !important; transition-delay: 0s !important; scroll-behavior: auto !important;
    }

    /* dyslexia-friendly: a clearer face and wider spacing; code stays monospace */
    html.a11y-dyslexia body, html.a11y-dyslexia body *:not(pre):not(code):not(kbd):not(samp):not(.mono) {
      font-family: "OpenDyslexic", "Atkinson Hyperlegible", "Lexend", "Verdana", "Trebuchet MS", sans-serif !important;
      letter-spacing: 0.04em; word-spacing: 0.1em;
    }
    html.a11y-dyslexia body { line-height: 1.6; }

    /* colorblind-safe: the Okabe-Ito blue and orange for ok / not ok, and a mark as well as a colour */
    html.a11y-cb { --a11y-ok: #56b4e9; --a11y-bad: #e69f00; --a11y-warn: #f0e442; --a11y-accent: #0072b2; }
    html.a11y-cb .sc-result[data-ok="1"]::before { content: "\2713\00a0"; }
    html.a11y-cb .sc-result[data-ok="0"]::before, html.a11y-cb .dt-err::before { content: "\2717\00a0"; }

    /* click targets of at least 44 by 44 pixels */
    html.a11y-targets button, html.a11y-targets [role="button"], html.a11y-targets select, html.a11y-targets summary,
    html.a11y-targets input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), html.a11y-targets textarea { min-height: 44px !important; min-width: 44px !important; } /* !important: cards set a smaller inline size */
    html.a11y-targets input[type="checkbox"], html.a11y-targets input[type="radio"] { width: 24px; height: 24px; margin: 10px; }
    html.a11y-targets .vc[role="button"], html.a11y-targets a[href] { display: inline-block; padding: 10px 6px; }

    /* a focus outline that stays, however focus arrived (mouse, touch or keyboard) */
    html.a11y-outline :focus, html.a11y-outline :focus-visible, html.a11y-outline .thing:focus-within {
      outline: 3px solid #ffd166 !important; outline-offset: 3px !important; box-shadow: 0 0 0 6px rgba(0, 0, 0, 0.85) !important;
    }

    /* a card the keyboard can move says so */
    html.a11y-keys .thing:focus { cursor: move; }

    /* captions for system speech */
    #a11y-caption {
      position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); max-width: min(92vw, 720px); z-index: 2147483000;
      background: rgba(0, 0, 0, 0.9); color: #fff; font: 18px/1.4 system-ui, sans-serif; padding: 10px 16px; border-radius: 12px; pointer-events: none;
    }
    #stage > .thing.shrunk:focus-visible { outline: calc(3px / var(--sc, 1)) solid #ffe2a1; outline-offset: calc(4px / var(--sc, 1)); } /* the outline shrinks with the board: divided by its scale, it shows at 3px */
    .thing { transform-style: preserve-3d; transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateZ(var(--tz, 0px));
      transition: transform .35s cubic-bezier(.2,.7,.2,1), filter .35s ease; filter: drop-shadow(0 14px 28px rgba(0,0,0,.45)) drop-shadow(0 0 1px rgba(160,190,255,.25)); }
    .thing.lift { --tz: 18px; filter: drop-shadow(0 26px 40px rgba(0,0,0,.55)) drop-shadow(0 0 14px rgba(140,170,255,.18)); }
    .thing.arrive { animation: summon .75s cubic-bezier(.16,1,.3,1) both; }
    @keyframes summon { from { opacity: 0; transform: perspective(900px) translateZ(-320px) rotateX(14deg) scale(.92); filter: blur(12px); }
      55% { opacity: 1; filter: blur(1.5px); } to { filter: drop-shadow(0 14px 28px rgba(0,0,0,.45)) drop-shadow(0 0 1px rgba(160,190,255,.25)); } }
    /* volumetric darkness: the homepage is a deep space, not a flat colour. Two slow layers; one eases after the cursor. CSS only. */
    #void-depth { position: fixed; inset: -10%; z-index: 0; pointer-events: none;
      background:
        radial-gradient(38vmax 30vmax at var(--dx, 50%) var(--dy, 42%), color-mix(in srgb, var(--void-glow, var(--sky-glow, #0b0b10)) 55%, #1a2350 45%) 0%, transparent 70%),
        radial-gradient(60vmax 45vmax at 50% 118%, rgba(40,52,110,.16), transparent 70%),
        radial-gradient(50vmax 40vmax at 12% -10%, rgba(70,40,120,.10), transparent 70%);
      opacity: .55; animation: depthBreath 14s steps(70) infinite alternate; will-change: transform, opacity; } /* steps: ~5 redraws a second, too slow a drift to see the steps; a smooth 60 fps breath made every keystroke wait an extra frame (2026-10-10) */
    @keyframes depthBreath { to { opacity: .8; transform: scale(1.04); } }
    /* film grain dithers the dark gradient so it never bands into rings */
    #void-depth::after { content: ''; position: absolute; inset: 0; opacity: .07; mix-blend-mode: overlay;
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
    /* the anchor: a frosted edge, a caret that breathes instead of blinking, a focus ring that snaps in */
    #row { background: linear-gradient(180deg, rgba(22,24,32,.78), rgba(10,11,16,.86)); backdrop-filter: blur(18px) saturate(1.3); -webkit-backdrop-filter: blur(18px) saturate(1.3);
      box-shadow: inset 0 1px 0 rgba(255,255,255,.07), inset 0 -1px 0 rgba(0,0,0,.4), 0 18px 50px rgba(0,0,0,.45);
      transition: box-shadow .42s cubic-bezier(.34,1.56,.64,1), border-color .3s ease, transform .42s cubic-bezier(.34,1.56,.64,1); }
    #row:focus-within { transform: translateY(-1px) scale(1.006); }
    #input { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; caret-color: #cfd8ff; } /* the caret blinks the browser's way: a breathing caret-color repainted the input 60 times a second, forever, 16% of a phone's main thread at rest and half of each keystroke's delay (2026-10-10) */
    .vpage { transform: translate(-50%, -46%) perspective(1200px) rotateX(calc(var(--rx, 0deg) + 10deg)) rotateY(var(--ry, 0deg)) translateZ(-140px);
      transition: opacity .5s ease, transform .6s cubic-bezier(.2,.8,.2,1), filter .6s ease; filter: blur(4px);
      background: linear-gradient(160deg, rgba(34,38,56,0.82), rgba(12,13,20,0.86) 45%, rgba(20,24,44,0.84)); backdrop-filter: blur(22px) saturate(1.2);
      box-shadow: 0 40px 120px rgba(0,0,0,.65), 0 0 0 1px rgba(255,255,255,.06), inset 0 1px 0 rgba(255,255,255,.10), 0 0 60px rgba(110,140,255,.06); }
    .vpage.on { transform: translate(-50%, -46%) perspective(1200px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateZ(0); filter: none; }
    /* a phone draws no backdrop blur under a card (owner, 2026-10-14: the weather card lagged): the stars move behind it every frame,
       and a blurred backdrop over a moving canvas makes the browser blur the whole card again each frame; nearly opaque instead */
    /* a card holding a 3D miniature draws no filter shadow on a touch screen: a drop-shadow filter is recomputed over the whole card each time the canvas inside it changes, every 3D frame */
    @media (pointer: coarse) { .thing:has(.void-mini), .thing.lift:has(.void-mini) { filter: none; transition: transform .35s cubic-bezier(.2,.7,.2,1); } } /* no filter fade either: a fading shadow is the same per-frame recompute for .35 s */
    @media (max-width: 700px), (pointer: coarse) { .vpage, html.has-world .vpage { backdrop-filter: none; -webkit-backdrop-filter: none;
      background: linear-gradient(160deg, rgba(30,34,50,.96), rgba(12,13,20,.97) 45%, rgba(20,24,44,.96)); } }
    .vpage::before { content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none;
      background: conic-gradient(from var(--rim, 210deg), rgba(140,170,255,.45), rgba(255,255,255,.04) 25%, rgba(200,140,255,.30) 55%, rgba(255,255,255,.04) 80%, rgba(140,170,255,.45));
      -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: .8; }
    .vpage::after { content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
      background: radial-gradient(600px 200px at var(--gx, 30%) -10%, rgba(255,255,255,.07), transparent 60%); }
    /* the ask bar itself is the focus ring: no square outline inside the rounded bar, and a border bright enough to see (>= 3:1) */
    #input:focus, #input:focus-visible { outline: none; }
    #row:focus-within { border-color: rgba(150,175,255,.6); box-shadow: 0 0 0 1px rgba(150,175,255,.10), 0 0 40px rgba(110,140,255,.12), 0 20px 60px rgba(0,0,0,.5); }
    #dock { background: linear-gradient(to top, color-mix(in srgb, var(--void-bg, var(--sky-bg, #050505)) 92%, transparent) 55%, transparent); z-index: 5; }
    /* the dock's top is a fade you see through: a card's button showing there takes the click; only what is in the dock
       (the suggestions, the ask bar, the status lines) catches the pointer */
    #dock { pointer-events: none; }
    #dock > * { pointer-events: auto; }
    #hints { backdrop-filter: blur(10px); }
    /* the same ask again: the page that is already open answers with a brief glow instead of a second fetch */
    @keyframes vpage-again { 0% { box-shadow: 0 0 0 1px rgba(150,175,255,.45), 0 0 60px rgba(110,140,255,.30); } 100% { box-shadow: none; } }
    .vpage.again { animation: vpage-again .9s ease-out; }
    .vpage .choices { list-style: none; padding: 0; margin: 8px 0 0; }
    .vpage .choices li { margin: 2px 0; }
    .vpage .choices a { display: block; padding: 7px 10px; border-radius: 8px; color: var(--fg); text-decoration: none; }
    .vpage .choices a:hover, .vpage .choices a:focus-visible { background: rgba(255,255,255,.06); }
    .vpage .choices small { color: #8a8a8a; }
    .vpage .wclock { display: grid; gap: 2px; margin-top: 8px; }
    .vpage .wrow { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 8px 2px; border-top: 1px solid rgba(255,255,255,.06); }
    .vpage .wrow.you { color: var(--muted); }
    .vpage .wtime { font-size: 30px; font-weight: 300; font-variant-numeric: tabular-nums; white-space: nowrap; }
    .vpage .tr-copy { font: inherit; font-size: 13px; color: var(--fg); background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.12); border-radius: 999px; padding: 5px 14px; cursor: pointer; }
    .vpage .tr-copy:hover, .vpage .tr-copy:focus-visible { background: rgba(255,255,255,.12); }
    /* presence: the pill's rim catches light as the pointer nears, and a question sinks into the void (nebula look only) */
    html[data-fx="nebula"] #row { position: relative; --near: 0; --ang: 0deg; }
    html[data-fx="nebula"] #row::before { content: ''; position: absolute; inset: -1px; border-radius: inherit; padding: 1.5px; pointer-events: none;
      background: conic-gradient(from var(--ang), #3fb4ff, #9a7bff, #ff6fb1, #45e8c8, #3fb4ff);
      -webkit-mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
      opacity: calc(var(--near) * .6); filter: saturate(1.4); }
    .void-eaten { position: fixed; z-index: 5; pointer-events: none; white-space: nowrap; color: #cfd8f0; transform-origin: center; }
    @media (prefers-reduced-motion: reduce) { html[data-fx="nebula"] #row::before { opacity: 0; } }
    #void-syn { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; opacity: 0; transition: opacity 2.4s ease; }
    #void-syn.on { opacity: 1; }
    @media (prefers-reduced-motion: reduce) {
      .thing, .vpage, .thing.arrive { animation: none !important; transition: opacity .2s ease !important; }
      .vpage, .vpage.on { transform: translate(-50%, -50%); filter: none; }
      html.no-gl[data-fx="nebula"] body::before { animation: none; }
      html, #void-glow, #void-stars, #void-aura, #void-swarm, #row { transition: none !important; }
      #void-depth, #input { animation: none !important; }
    }
    /* the text box shows focus through the ask bar's own glow (#row:focus-within); the round buttons keep a ring */
    #mic:focus-visible,
    #go:focus-visible {
      outline: 2px solid rgba(170,190,255,.85);
      outline-offset: 2px;
    }
    #mic, #go {
      min-width: 44px;
      min-height: 44px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
    }
    #dock {
      padding: 12px 16px calc(18px + env(safe-area-inset-bottom, 0px));
    }
    #stage {
      inset: 0 0 calc(72px + env(safe-area-inset-bottom, 0px)) 0;
    }
    @media (max-width: 480px) {
      #dock { padding: 10px 10px calc(14px + env(safe-area-inset-bottom, 0px)); }
      #row { padding: 6px 8px 6px 14px; max-width: none; }
      .vpage {
        width: calc(100vw - 20px);
        max-height: calc(100vh - 120px - env(safe-area-inset-bottom, 0px));
        max-height: calc(100dvh - 120px - env(safe-area-inset-bottom, 0px));
        top: 44%;
      }
    }
    #void-stars-far { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; opacity: 0; }
    /* a world: one full-stage layer a skill draws behind every card (stageApi.setWorld), above the nebula */
    #void-world { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; opacity: 0; transition: opacity 1.2s ease; }
    #void-world.on { opacity: 1; }
    #void-stars-far.on { opacity: .9; }
    /* ---- polish (2026-10-07): one type scale, calm cards that never sit under the ask bar ---- */
    :root {
      --font: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", Inter, Roboto, "Helvetica Neue", system-ui, sans-serif;
      --fs-xs: 12px; --fs-s: 13px; --fs-m: 15px; --fs-l: 17px; --fs-xl: 22px;
      --ink: #e9ebf2; --ink-2: #b9bdcb; --ink-3: #8b90a0;
      --card-bg: linear-gradient(160deg, rgba(36,40,58,.90), rgba(14,15,24,.94) 48%, rgba(22,26,46,.92));
      --card-line: rgba(255,255,255,.08);
      --card-shadow: 0 30px 70px rgba(0,0,0,.55), 0 6px 18px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.07);
      --radius: 20px;
      --ease: cubic-bezier(.2,.8,.2,1);
      --dock-space: calc(118px + env(safe-area-inset-bottom, 0px)); /* measured live from the ask bar (script below) */
    }
    html, body, body.void-quiet, #input, button, .vpage, .thing { font-family: var(--font); }
    body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; }
    /* answer pages: centred in the space above the ask bar, scroll inside instead of running under it */
    .vpage {
      top: calc((100vh - var(--dock-space)) / 2 + 4px);
      top: calc((100dvh - var(--dock-space)) / 2 + 4px);
      max-height: calc(100vh - var(--dock-space) - 40px);
      max-height: calc(100dvh - var(--dock-space) - 40px);
      width: min(560px, calc(100vw - 24px));
      padding: 24px 26px 20px; border-radius: var(--radius);
      font-size: var(--fs-m); line-height: 1.55; color: var(--ink);
      scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.18) transparent; overscroll-behavior: contain;
      transform: translate(-50%, -50%) perspective(1200px) rotateX(calc(var(--rx, 0deg) + 6deg)) rotateY(var(--ry, 0deg)) translateZ(-90px);
    }
    .vpage.on { transform: translate(-50%, -50%) perspective(1200px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateZ(0); }
    .vpage.vp-tight { width: min(440px, calc(100vw - 24px)); }
    .vpage h2 { font-size: var(--fs-xl); font-weight: 600; letter-spacing: -.005em; line-height: 1.25; margin: 0 0 4px; }
    .vpage .sub { font-size: var(--fs-s); color: var(--ink-3); margin-bottom: 14px; }
    .vpage p, .vpage ul { color: #d5d8e2; }
    .vpage .src { font-size: var(--fs-xs); color: var(--ink-2); } /* "written by Verse, from what it knows": ink-2 on the card, ~9:1 (it was ink-3, 5.7:1 and read as too dark; owner, 2026-10-18); the answer stays brighter and larger */
    /* Verse's reflection card (showVoice): section heads in the one accent, the built-of-asked bar, asks that open */
    .vpage .vh { font-size: 11px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: rgb(var(--d-key, 158 178 255)); margin: 18px 0 6px; }
    .vpage .v-bar { height: 6px; border-radius: 999px; background: rgba(255,255,255,.08); overflow: hidden; margin: 6px 0 8px; }
    .vpage .v-bar > i { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, rgb(var(--d-key, 158 178 255) / .55), rgb(var(--d-key, 158 178 255))); }
    .vpage .v-num { font-size: 28px; font-weight: 300; letter-spacing: -.03em; font-variant-numeric: tabular-nums; color: var(--ink); }
    .vpage .v-asks { list-style: none; padding: 0; margin: 0; }
    .vpage .v-asks li { border-top: 1px solid rgba(255,255,255,.06); }
    .vpage .v-asks summary { cursor: pointer; padding: 8px 0; list-style-position: outside; }
    .vpage .v-asks .v-meta { font-size: var(--fs-s); color: var(--ink-3); padding: 0 0 10px; }
    /* the self card (lib/self-blocks.js): headings you can scan, one bullet per ask with its dates beneath, paragraphs with air between them,
       Verse's own words in the reading font and the changelog (what got built) in monospace inside its own darker box */
    .vpage.vc-self .vs-sec { margin-top: 18px; }
    /* the owner's redesign (2026-10-18): Verse's words as a quotation with an accent bar, sub-headings inside a block, a muted count in each heading */
    .vpage.vc-self .vs-voice { margin: 14px 0 6px; padding: 4px 0 4px 16px; border-left: 4px solid rgb(var(--d-key, 158 178 255) / .9); }
    .vpage.vc-self .vs-voice p { font-size: 17.5px; line-height: 1.6; color: var(--ink); margin: 0 0 6px; }
    .vpage.vc-self .vs-voice .vs-cite { font-size: 12px; }
    .vpage.vc-self .vs-h4 { font-size: 14px; font-weight: 700; letter-spacing: .02em; color: var(--ink); margin: 10px 0 4px; }
    .vpage.vc-self .vs-n { font-weight: 500; font-size: 13px; color: var(--ink-3); }
    .vpage.vc-self details.vs-sec { margin-top: 10px; }
    .vpage.vc-self [data-v-conf] { margin-top: 14px; }
    .vpage.vc-self details.vs-log:not([open]) { background: none; border: 0; padding: 0; font-family: inherit; } /* closed, the changelog block looks like the others; its box shows when it is open */
    .vpage.vc-self .vc-share { gap: 6px; } .vpage.vc-self .vc-share .vc-grp::before { content: none; } /* the footer: one wrapping row of buttons */
    .vpage.vc-self .vs-sum { display: block; list-style: none; cursor: pointer; border-radius: 6px; }
    .vpage.vc-self .vs-sum::-webkit-details-marker { display: none; }
    .vpage.vc-self .vs-sum:focus-visible { outline: 2px solid rgba(170,190,255,.85); outline-offset: 2px; }
    .vpage.vc-self .vs-sum .vs-h { display: flex; align-items: baseline; gap: 8px; }
    .vpage.vc-self .vs-sum .vs-h::after { content: ""; margin-left: auto; width: 7px; height: 7px; border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3); transform: translateY(-3px) rotate(45deg); transition: transform .15s ease; }
    .vpage.vc-self details.vs-sec:not([open]) > .vs-sum .vs-h::after { transform: rotate(-45deg); }
    .vpage.vc-self details.vs-sec:not([open]) > .vs-sum .vs-h { margin-bottom: 0; }
    .vpage.vc-self .vs-more { margin-top: 6px; }
    /* the speaker sits as far in from the right border as the title does from the left (owner, 2026-10-18): no negative margin, and the scrollbar's
       gutter is kept on both edges so a classic scrollbar does not push the speaker further in than the title */
    .vpage.vc-self { scrollbar-gutter: stable both-edges; }
    .vpage.vc-self.vcard > .vread { right: 16px !important; } /* the title's margin (lib/card-frame.js: 16 px, no border or padding since #2336): the speaker's right inset is the title text's left one */
    @media (max-width: 520px) { .vpage.vc-self.vcard > .vread { right: 6px !important; } } /* the title's phone margin, 6 px */
    .vpage.vc-self .src { padding-bottom: 10px; }
    .vpage.vc-self .vs-h { font-size: 17px; font-weight: 700; line-height: 1.3; letter-spacing: 0; color: var(--ink); margin: 0 0 8px; padding-bottom: 5px; border-bottom: 1px solid rgb(var(--d-key, 158 178 255) / .35); box-shadow: 0 1px 0 rgba(255, 210, 122, .18); }
    .vpage.vc-self .vs-sec p { margin: 0 0 10px; }
    .vpage.vc-self .vs-sec p:last-child { margin-bottom: 0; }
    .vpage.vc-self .vs-lead { font-size: 16px; line-height: 1.6; color: var(--ink); }
    .vpage.vc-self .vs-note { margin: 0 0 10px; }
    .vpage.vc-self .vs-note[data-tight] { margin-bottom: 6px; }
    .vpage.vc-self .vs-list { list-style: none; margin: 0; padding: 0; }
    .vpage.vc-self .vs-list > li { position: relative; padding: 6px 0 6px 22px; border-top: 0; }
    .vpage.vc-self .vs-list > li::before { content: ""; position: absolute; left: 6px; top: 15px; width: 6px; height: 6px; border-radius: 50%; background: rgb(255 210 122 / .85); }
    .vpage.vc-self .vs-list summary { padding: 0; list-style: none; cursor: pointer; }
    .vpage.vc-self .vs-list summary::-webkit-details-marker { display: none; }
    .vpage.vc-self .vs-list .v-meta, .vpage.vc-self .vs-sub { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; line-height: 1.45; color: var(--ink-3); padding: 2px 0 0; }
    .vpage.vc-self .vs-list details:not([open]) .v-meta { display: none; }
    .vpage.vc-self .vs-log { background: rgba(0, 0, 0, .28); border: 1px solid rgba(255, 255, 255, .12); border-radius: 8px; padding: 12px 14px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
    .vpage.vc-self .vs-log .vs-h { font-family: inherit; }
    .vpage.vc-self .vs-log .vs-note, .vpage.vc-self .vs-log .vs-of, .vpage.vc-self .vs-log summary { font-size: 13px; }
    .vpage.vc-self .vs-of { color: var(--ink-3); }
    /* the growth velocity (asked by Verse): a week of builds as one small line in Verse's violet, the latest day a dot, a muted monospace label beside it */
    .vpage.vc-self .vs-velocity { display: flex; align-items: center; gap: 10px; margin: 0 0 8px; color: rgb(170 140 255 / .95); }
    .vpage.vc-self .vs-velocity .vs-spark { flex: none; display: block; overflow: visible; }
    .vpage.vc-self .vs-vel-label { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; color: var(--ink-3); }
    .vpage.vc-self .vs-overdue { color: rgba(214,178,92,.95); } /* friction (asked by Verse): " · N overdue" in the warning amber; the red segments are in the svg itself */
    @media (prefers-reduced-motion: no-preference) { .vpage.vc-self .vs-sec { animation: vs-in .35s ease both; } @keyframes vs-in { from { opacity: 0; transform: translateY(4px); } } }
    .vpage::-webkit-scrollbar { width: 8px; } .vpage::-webkit-scrollbar-thumb { background: rgba(255,255,255,.14); border-radius: 8px; }
    /* the browser's own look stays out: selected text takes Verse's violet, every scrolling
 box gets a thin translucent pill with no arrows, and a toggle pill that is on looks on */
    ::selection { background: rgba(150,110,255,.42); color: #fff; }
    * { scrollbar-width: thin; scrollbar-color: rgba(190,170,255,.22) transparent; }
    ::-webkit-scrollbar { width: 6px; height: 6px; background: transparent; }
    ::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
    ::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: transparent; }
    ::-webkit-scrollbar-thumb { background: rgba(190,170,255,.22); border-radius: 6px; }
    ::-webkit-scrollbar-thumb:hover { background: rgba(190,170,255,.4); }
    /* asked by Verse (2026-10-18): the pressed pill sinks 2px and keeps a soft violet halo; a scrollbar stays a hairline until the pointer is on it */
    .vpage .tr-copy { transition: transform .12s ease, box-shadow .2s ease, background-color .2s ease; }
    .vpage .tr-copy[aria-pressed="true"] { background: rgba(150,110,255,.28); border-color: rgba(190,170,255,.6); color: #fff; transform: translateY(2px); box-shadow: 0 0 10px rgba(150,110,255,.45), inset 0 1px 2px rgba(0,0,0,.35); }
    .vpage .tr-copy:active { transform: translateY(2px); }
    @media (prefers-reduced-motion: reduce) { .vpage .tr-copy { transition: none; } }
    ::-webkit-scrollbar { width: 4px; height: 4px; } :hover::-webkit-scrollbar { width: 10px; height: 10px; }
    ::-webkit-scrollbar-thumb { border: 2px solid transparent; background-clip: padding-box; }
    :hover::-webkit-scrollbar-thumb { border-width: 1px; }
    *:hover { scrollbar-color: rgba(190,170,255,.55) transparent; } /* Chrome draws the standard bar (thin or full only; a width change on hover would reflow the text): it brightens instead */
    @media (max-width: 480px) {
      .vpage { width: calc(100vw - 20px); padding: 20px 18px 16px; }
      .vpage h2 { font-size: 20px; }
    }
    /* the status line under the ask bar: a quiet, centred caption that fades, never a stray left-aligned word */
    #whisper { text-align: center; font-size: var(--fs-xs); color: var(--ink-3); letter-spacing: .01em; min-height: 18px; margin-top: 8px; transition: opacity .25s ease; }
    #whisper:empty { opacity: 0; }
    /* someone else in your Verse (frontier #11): their cursor, a faint glow that follows them */
    .void-presence { position: fixed; z-index: 40; width: 18px; height: 18px; margin: -9px 0 0 -9px; border-radius: 50%; pointer-events: none; background: radial-gradient(circle, color-mix(in srgb, var(--fg) 45%, transparent) 0%, transparent 70%); box-shadow: 0 0 14px color-mix(in srgb, var(--fg) 25%, transparent); transition: left .08s linear, top .08s linear; }
    #away-note { text-align: center; font-size: var(--fs-xs); color: var(--ink-3); letter-spacing: .01em; min-height: 18px; transition: opacity .25s ease; }
    #away-note:empty { opacity: 0; }
    #away-note .away-see { color: var(--fg); text-underline-offset: 2px; }
    /* smooth background: the grain lives on its own unscaled layer, so the dark gradient dithers instead of banding or streaking */
    #void-depth::after { content: none; }
    body::after { content: ''; position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: .05; mix-blend-mode: overlay;
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
      background-size: 200px 200px; }
    /* cards on the stage share one look: rounded, softly lit, a gentle shadow */
    .thing.kept-card:not(.game-card):not(.cartoon-card):not(.free-board) { border-radius: 16px !important; border-color: var(--card-line) !important;
      background: var(--card-bg) !important; box-shadow: var(--card-shadow); padding: 14px 16px !important; font-size: var(--fs-s) !important; }
    .thing.game-card { position: absolute; padding: 18px 18px 16px; border-radius: var(--radius); background: var(--card-bg); border: 1px solid var(--card-line);
      box-shadow: var(--card-shadow); color: var(--ink); font-size: var(--fs-s); line-height: 1.45; text-align: left; user-select: none; filter: none; max-width: calc(100vw - 20px); }
    .thing.game-card.lift { filter: none; box-shadow: 0 40px 90px rgba(0,0,0,.6), 0 0 0 1px rgba(150,175,255,.18), inset 0 1px 0 rgba(255,255,255,.08); }
    .thing.game-card.arrive { animation: gameArrive .6s var(--ease) both; }
    @keyframes gameArrive { from { opacity: 0; transform: translateY(14px) scale(.97); } to { opacity: 1; transform: none; } }
    .g-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; cursor: grab; }
    .g-title { font-size: var(--fs-l); font-weight: 600; letter-spacing: -.005em; color: var(--ink); }
    .g-sub { font-size: var(--fs-xs); color: var(--ink-3); }
    .g-board { display: flex; justify-content: center; margin: 14px 0 14px; }
    .g-bar { display: flex; align-items: center; gap: 12px; min-height: 36px; }
    .g-status { flex: 1; display: flex; align-items: center; gap: 8px; font-size: var(--fs-s); color: var(--ink-2); min-width: 0; }
    .g-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; box-shadow: 0 0 0 2px rgba(255,255,255,.1), 0 0 10px currentColor; }
    .g-btn { font: inherit; font-size: var(--fs-s); color: var(--ink); background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.13);
      border-radius: 999px; padding: 7px 16px; cursor: pointer; transition: background .2s ease, transform .2s var(--ease), opacity .2s ease; white-space: nowrap; }
    .g-btn:hover:not(:disabled) { background: rgba(255,255,255,.13); }
    .g-btn:active:not(:disabled) { transform: scale(.97); }
    /* inside a card (.thing is preserve-3d and tilts toward the pointer) a shrinking button moves its own hit area, so a press near
       the bottom of a tall card was released on the parent and the click was lost: there a press darkens instead of shrinking */
    .thing .g-btn:active:not(:disabled) { transform: none; box-shadow: inset 0 0 0 99px rgba(0,0,0,.18); }
    .g-btn:disabled { opacity: .38; cursor: default; }
    .g-btn:focus-visible, .g-seg button:focus-visible, .ttt-cell:focus-visible, .oth-cell:focus-visible, .mc-pit:focus-visible { outline: 2px solid rgba(170,190,255,.85); outline-offset: 2px; }
    .g-primary { background: linear-gradient(180deg, #f1f3ff, #c9d0f2); color: #141622; border-color: transparent; font-weight: 600; box-shadow: 0 4px 14px rgba(120,140,255,.25); }
    .g-primary:hover:not(:disabled) { background: linear-gradient(180deg, #fff, #d6dcf7); }
    .g-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
    .g-seg { display: inline-flex; align-items: center; gap: 2px; padding: 3px; border-radius: 999px; background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.08); }
    .g-seg span { color: var(--ink-3); font-size: var(--fs-xs); padding: 0 6px 0 8px; }
    .g-seg button { font: inherit; font-size: var(--fs-xs); color: var(--ink-2); background: none; border: 0; border-radius: 999px; padding: 5px 11px; cursor: pointer; }
    .g-seg button.on { background: rgba(255,255,255,.14); color: var(--ink); }
    .g-rules { margin-top: 12px; font-size: var(--fs-xs); line-height: 1.5; color: var(--ink-3); }
    /* tic-tac-toe: a carved maple board, lacquered pieces */
    .tictactoe-card { width: min(330px, calc(100vw - 20px)); }
    .ttt-board { --cell: min(96px, calc((100vw - 76px) / 3)); display: grid; grid-template-columns: repeat(3, var(--cell)); grid-template-rows: repeat(3, var(--cell)); padding: 0; border-radius: 18px; overflow: hidden;
      background:
        linear-gradient(90deg, transparent calc(var(--cell) - 2px), #4a2a12 calc(var(--cell) - 2px), #4a2a12 calc(var(--cell) + 2px), rgba(255,225,180,.35) calc(var(--cell) + 2px), transparent calc(var(--cell) + 3px),
          transparent calc(2 * var(--cell) - 2px), #4a2a12 calc(2 * var(--cell) - 2px), #4a2a12 calc(2 * var(--cell) + 2px), rgba(255,225,180,.35) calc(2 * var(--cell) + 2px), transparent calc(2 * var(--cell) + 3px)),
        linear-gradient(180deg, transparent calc(var(--cell) - 2px), #4a2a12 calc(var(--cell) - 2px), #4a2a12 calc(var(--cell) + 2px), rgba(255,225,180,.35) calc(var(--cell) + 2px), transparent calc(var(--cell) + 3px),
          transparent calc(2 * var(--cell) - 2px), #4a2a12 calc(2 * var(--cell) - 2px), #4a2a12 calc(2 * var(--cell) + 2px), rgba(255,225,180,.35) calc(2 * var(--cell) + 2px), transparent calc(2 * var(--cell) + 3px)),
        repeating-linear-gradient(95deg, rgba(120,70,30,.10) 0 2px, transparent 2px 9px, rgba(90,50,20,.08) 9px 10px, transparent 10px 23px),
        radial-gradient(120% 90% at 30% 20%, #e2b47c, #c48a4f 55%, #9a6332);
      box-shadow: 0 14px 30px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,240,210,.5), inset 0 -3px 6px rgba(70,35,10,.45); }
    .ttt-cell { padding: 10%; border: 0; background: none; cursor: pointer; border-radius: 12px; transition: background .2s ease; }
    .ttt-cell:hover:not(:disabled) { background: rgba(255,240,215,.16); }
    .ttt-cell:disabled { cursor: default; }
    .ttt-cell svg { display: block; width: 100%; height: 100%; filter: drop-shadow(0 2px 2px rgba(60,30,10,.35)); }
    .ttt-cell.placed svg { animation: piecePop .32s var(--ease) both; }
    .ttt-cell.win { background: radial-gradient(closest-side, rgba(255,250,220,.55), transparent); }
    @keyframes piecePop { from { transform: scale(.6); opacity: 0; } to { transform: none; opacity: 1; } }
    /* othello: green baize in a walnut frame */
    .othello-card { width: min(408px, calc(100vw - 20px)); }
    .oth-frame { padding: 10px; border-radius: 14px; background: linear-gradient(145deg, #6b4428, #3d2414); box-shadow: 0 14px 30px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,220,180,.3), inset 0 -2px 4px rgba(0,0,0,.4); }
    .oth-board { --cell: min(42px, calc((100vw - 92px) / 8)); display: grid; grid-template-columns: repeat(8, var(--cell)); grid-template-rows: repeat(8, var(--cell)); border-radius: 4px; overflow: hidden;
      background: radial-gradient(120% 100% at 35% 25%, #2f9a5c, #1f7445 55%, #165a35); box-shadow: inset 0 0 0 1px rgba(0,0,0,.5), inset 0 2px 8px rgba(0,0,0,.35); }
    .oth-cell { padding: 0; border: 0; background: transparent; box-shadow: inset 0 0 0 .5px rgba(5,40,20,.75); display: flex; align-items: center; justify-content: center; cursor: default; perspective: 300px; }
    .oth-cell.legal { cursor: pointer; }
    .oth-cell.legal:hover { background: rgba(255,255,255,.08); }
    .oth-disc { width: 80%; height: 80%; border-radius: 50%; }
    .oth-disc.black { background: radial-gradient(circle at 35% 30%, #5a5d66, #1b1c21 45%, #050506); box-shadow: 0 2px 0 #000, 0 4px 6px rgba(0,0,0,.45); }
    .oth-disc.white { background: radial-gradient(circle at 35% 30%, #ffffff, #eceae4 45%, #c7c3b8); box-shadow: 0 2px 0 #8f8a7f, 0 4px 6px rgba(0,0,0,.4); }
    .oth-disc.flip { animation: discFlip .45s var(--ease); }
    .oth-disc.drop { animation: piecePop .3s var(--ease); }
    @keyframes discFlip { 0% { transform: rotateY(0); } 50% { transform: rotateY(90deg); } 100% { transform: rotateY(0); } }
    .oth-hint { width: 26%; height: 26%; border-radius: 50%; background: rgba(0,0,0,.28); box-shadow: 0 0 0 1.5px rgba(255,255,255,.25); }
    .oth-score { display: flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--ink); }
    .oth-chip { width: 14px; height: 14px; border-radius: 50%; margin-left: 4px; }
    .oth-chip.black { background: radial-gradient(circle at 35% 30%, #5a5d66, #050506); box-shadow: 0 0 0 1px rgba(255,255,255,.2); }
    .oth-chip.white { background: radial-gradient(circle at 35% 30%, #fff, #c7c3b8); }
    /* mancala: a carved board with glass beads */
    .mancala-card { width: min(476px, calc(100vw - 20px)); }
    .mc-board { --pit: min(46px, calc((100vw - 124px) / 8)); display: grid; grid-template-columns: calc(var(--pit) * 1.05) repeat(6, var(--pit)) calc(var(--pit) * 1.05); grid-template-rows: var(--pit) var(--pit);
      gap: calc(var(--pit) * .16); padding: calc(var(--pit) * .28); border-radius: calc(var(--pit) * .9);
      background: repeating-linear-gradient(90deg, rgba(110,60,25,.10) 0 2px, transparent 2px 11px, rgba(80,40,15,.08) 11px 12px, transparent 12px 27px), radial-gradient(120% 120% at 30% 20%, #d6a066, #b27840 55%, #8a5428);
      box-shadow: 0 14px 30px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,235,200,.45), inset 0 -3px 6px rgba(60,30,10,.45); }
    .mc-pit { position: relative; padding: 0; border: 0; border-radius: 50%; cursor: pointer; color: inherit;
      background: radial-gradient(circle at 50% 38%, #3b2010, #5e3519 62%, #8a5527 92%); box-shadow: inset 0 3px 7px rgba(0,0,0,.65), 0 1px 0 rgba(255,230,190,.35); transition: box-shadow .2s ease, transform .2s var(--ease); }
    .mc-pit:hover:not(:disabled) { box-shadow: inset 0 3px 7px rgba(0,0,0,.65), 0 0 0 2px rgba(255,236,200,.7); }
    .mc-pit:disabled { cursor: default; }
    .mc-store { grid-row: span 2; border-radius: 999px; }
    .mc-seeds { position: absolute; inset: 12%; }
    .mc-seeds i { position: absolute; width: calc(var(--pit) * .2); height: calc(var(--pit) * .2); margin: calc(var(--pit) * -.1) 0 0 calc(var(--pit) * -.1); border-radius: 50%;
      background: radial-gradient(circle at 35% 30%, rgba(255,255,255,.9), var(--b) 40%, color-mix(in srgb, var(--b) 55%, #000)); box-shadow: 0 1px 2px rgba(0,0,0,.6); }
    .mc-n { position: absolute; left: 50%; bottom: calc(var(--pit) * -.3); transform: translateX(-50%); min-width: 18px; padding: 0 5px; border-radius: 999px; font: 600 11px/16px var(--font);
      font-variant-numeric: tabular-nums; color: #2b1607; background: rgba(255,236,205,.85); box-shadow: 0 1px 2px rgba(0,0,0,.35); pointer-events: none; }
    .mc-store .mc-n { bottom: 6px; }
    .mc-board > .mc-pit:nth-child(-n+7):not(.mc-store) .mc-n { bottom: auto; top: calc(var(--pit) * -.3); }
    /* aggravation */
    .ag-wrap svg { display: block; width: min(100%, max(260px, calc(100dvh - var(--dock-space, 120px) - 270px))); height: auto; border-radius: 18px; box-shadow: 0 16px 34px rgba(0,0,0,.55); }
    .ag-marble { transition: transform .42s var(--ease); }
    .ag-marble .ag-ring { stroke: transparent; stroke-width: 2.2; }
    .ag-marble.can { cursor: pointer; }
    .ag-marble.can .ag-ring { stroke: rgba(255,255,255,.9); animation: agPulse 1.1s ease-in-out infinite; }
    .ag-marble.picked .ag-ring { stroke: #fff; stroke-width: 3; animation: none; }
    .ag-target { fill: rgba(255,255,255,.22); stroke: #fff; stroke-width: 2.2; cursor: pointer; animation: agPulse 1.1s ease-in-out infinite; }
    @keyframes agPulse { 50% { opacity: .35; } }
    /* one "working" look, shared: a chess card while Verse thinks and an approve card while the confirm line waits (skills/approve-card.js) */
    .vc-stale { margin-top: 8px; padding: 4px 8px; border-left: 3px solid #e0a030; background: rgba(224,160,48,.1); color: #f0c060; font-size: 13px; border-radius: 0 6px 6px 0; }
    .vc-working { position: relative; }
    .vc-working::after { content: ''; display: block; height: 3px; margin-top: 5px; border-radius: 2px; background: linear-gradient(90deg, rgba(150,110,255,.08), rgba(150,110,255,.55) 50%, rgba(150,110,255,.08)); background-size: 200% 100%; animation: vcShimmer 1.4s linear infinite, agPulse 1.1s ease-in-out infinite; }
    @keyframes vcShimmer { to { background-position: -200% 0; } }
    .ag-die { width: 42px; height: 42px; flex: none; display: grid; grid-template: repeat(3, 1fr) / repeat(3, 1fr); padding: 7px; gap: 1px; border-radius: 10px;
      background: linear-gradient(145deg, #ffffff, #e2e3ea); box-shadow: 0 0 0 2px var(--ag-col, #888), 0 6px 14px rgba(0,0,0,.45), inset 0 -2px 3px rgba(0,0,0,.12); }
    .ag-die i { border-radius: 50%; }
    .ag-die i.on { background: radial-gradient(circle at 40% 35%, #4a4d5a, #111218); }
    .ag-die.blank { opacity: .6; }
    .ag-die.tumble { animation: dieTumble .5s var(--ease); }
    @keyframes dieTumble { 0% { transform: rotate(-200deg) scale(.6); } 70% { transform: rotate(12deg) scale(1.06); } 100% { transform: none; } }
    @media (prefers-reduced-motion: reduce) {
      .thing.game-card.arrive, .ttt-cell.placed svg, .oth-disc.flip, .oth-disc.drop, .ag-die.tumble, .ag-marble.can .ag-ring, .ag-target, #whisper { animation: none !important; }
      .ag-marble, .mc-pit, .g-btn { transition: none !important; }
      .vc-working::after { animation: none; opacity: .6; }
    }
    @media (max-width: 480px) {
      .thing.game-card { padding: 16px 14px 14px; }
      .g-board { margin: 12px 0; }
    }
    /* Verse's startup intro: once a visit, about 1.5 s, the
 0 drawn as a ring of light; it never takes a click or a key, so the input works underneath from the first frame */
    #v01d { position: fixed; inset: 0; z-index: 2147483000; display: grid; place-content: center; justify-items: center; gap: 18px; pointer-events: none;
      background: radial-gradient(60% 50% at 50% 45%, #14112c 0%, #050505 72%); animation: v01d-out .5s ease 1.25s forwards; }
    /* VERSE: the letters arrive one by one and the ring of light (the 0 of Verse) is drawn as an orbit round the word */
    #v01d .v01d-mark { position: relative; display: flex; align-items: center; gap: .06em; font: 200 clamp(48px, 13vw, 112px)/1 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; letter-spacing: .04em; color: #f4f2ff; }
    #v01d .v01d-mark > * { opacity: 0; transform: translateY(10px); animation: v01d-in .55s cubic-bezier(.2, .7, .2, 1) forwards; }
    #v01d .v01d-mark > :nth-child(3) { animation-delay: .07s; } #v01d .v01d-mark > :nth-child(4) { animation-delay: .14s; } #v01d .v01d-mark > :nth-child(5) { animation-delay: .21s; } #v01d .v01d-mark > :nth-child(6) { animation-delay: .28s; }
    #v01d .v01d-o { position: absolute; left: -14%; top: -28%; width: 128%; height: 156%; overflow: visible; opacity: 1; transform: none; animation: none; }
    #v01d .v01d-o ellipse { fill: none; stroke: #fff; stroke-width: 1.4; stroke-linecap: round; stroke-dasharray: 520; stroke-dashoffset: 520; vector-effect: non-scaling-stroke;
      filter: drop-shadow(0 0 6px rgba(255, 61, 127, .85)) drop-shadow(0 0 14px rgba(122, 92, 255, .8)); animation: v01d-draw .75s cubic-bezier(.6, 0, .2, 1) .1s forwards; }
    #v01d .v01d-line { width: min(240px, 52vw); height: 1px; background: linear-gradient(90deg, transparent, #ff3d7f, #7a5cff, transparent); transform: scaleX(0); animation: v01d-line .6s ease .45s forwards; }
    #v01d .v01d-by { font: 500 11px/1 system-ui, -apple-system, sans-serif; letter-spacing: .48em; padding-left: .48em; color: #8d89a6; opacity: 0; animation: v01d-fade .5s ease .6s forwards; }
    @keyframes v01d-in { to { opacity: 1; transform: none; } }
    @keyframes v01d-draw { to { stroke-dashoffset: 0; } }
    @keyframes v01d-line { to { transform: scaleX(1); } }
    @keyframes v01d-fade { to { opacity: 1; } }
    @keyframes v01d-out { to { opacity: 0; visibility: hidden; } }
    /* ---- design phase 1 (docs/design.md, 2026-10-15): the stage, the ask bar and the answer card shell ----
       One light source (top centre, cool), one floor (a horizon of light the stage stands on), glass with a lit rim.
       CSS only: no new requests, no new scripts, nothing animated at rest except one slow compositor-only drift. */
    :root {
      --d-ink: #f2f4fb; --d-ink-2: #c3c8d8; --d-ink-3: #8e94a8;
      --d-key: 158 178 255; --d-warm: 255 170 214; --d-teal: 92 232 205;      /* light colours as rgb triplets */
      --d-glass: linear-gradient(165deg, rgba(40,46,70,.80) 0%, rgba(16,18,28,.88) 46%, rgba(20,22,40,.90) 100%);
      --d-rim: conic-gradient(from 200deg, rgb(var(--d-key) / .55), rgba(255,255,255,.05) 22%, rgb(var(--d-warm) / .32) 50%, rgba(255,255,255,.05) 74%, rgb(var(--d-teal) / .38) 90%, rgb(var(--d-key) / .55));
      --d-lift: 0 1px 0 rgba(255,255,255,.10) inset, 0 -1px 0 rgba(0,0,0,.5) inset, 0 2px 6px rgba(0,0,0,.30), 0 18px 40px rgba(0,0,0,.42), 0 60px 120px rgba(0,0,0,.55);
      --d-ease-out: cubic-bezier(.16,1,.3,1); --d-spring: cubic-bezier(.34,1.56,.64,1);
    }
    /* the default void:
 deep space, a slowly breathing event-horizon glow at the centre, a soft oval pool of light where cards arrive, star dust from the
 two star canvases. Transforms and opacity only (GPU-composited, no layout, no per-frame JS); CSS animations pause with the tab. */
    /* celestial-sync: the nebula and ring tint follow the visitor's local hour (set on <html> by the script below, on the device only, no
       network, nothing stored) and the real sky's glow when sky-rules has one (--sky-glow) */
    :root { --neb-a: 92 70 190; --neb-b: 40 130 170; --ring: 1; }
    html[data-phase="dawn"] { --neb-a: 190 90 140; --neb-b: 230 150 90; }
    html[data-phase="day"]  { --neb-a: 70 120 210; --neb-b: 60 170 200; --ring: .9; }
    html[data-phase="dusk"] { --neb-a: 200 80 120; --neb-b: 120 70 200; }
    html[data-phase="night"]{ --neb-a: 92 70 190; --neb-b: 40 130 170; --ring: 1.08; }
    #void-depth::before { content: ''; position: absolute; left: 50%; top: 44%; width: min(118vmin, 1100px); aspect-ratio: 1; pointer-events: none;
      transform: translate(-50%, -50%); border-radius: 50%;
      background:
        radial-gradient(closest-side, #000 0 32.5%, rgba(255,255,255,.75) 34.2%, rgb(var(--d-key) / .85) 35%, rgb(var(--d-warm) / .32) 39%, rgb(var(--d-key) / .12) 47%, transparent 62%),
        conic-gradient(from 210deg, rgb(var(--d-teal) / .30), rgb(var(--d-key) / .05) 15%, rgb(var(--d-key) / .45) 36%, rgb(255 236 210 / .40) 47%, transparent 60%, rgb(var(--d-warm) / .36) 78%, rgb(var(--d-teal) / .30));
      -webkit-mask: radial-gradient(closest-side, #000 50%, transparent 100%); mask: radial-gradient(closest-side, #000 50%, transparent 100%);
      opacity: calc(.9 * var(--ring)); animation: d-breathe 11s ease-in-out infinite, d-turn 160s linear infinite; }
    /* the gravitational lens: a thin bright arc that shimmers just outside the horizon, and the event horizon's own shadow on top */
    #void-lens { position: absolute; left: 50%; top: 44%; width: min(118vmin, 1100px); aspect-ratio: 1; z-index: 0; pointer-events: none; border-radius: 50%;
      transform: translate(-50%, -50%);
      background: radial-gradient(closest-side, transparent 35.2%, rgba(255,255,255,.16) 36%, transparent 38.4%);
      animation: d-lens 7s ease-in-out infinite; }
    @keyframes d-lens { 0%,100% { scale: 1; opacity: .75; } 50% { scale: 1.012; opacity: 1; } }
    #void-depth::after { content: ''; position: absolute; inset: auto; opacity: 1; mix-blend-mode: screen; background-image: none; left: 50%; top: 44%; width: 160vmax; height: 90vmax; pointer-events: none; transform: translate(-50%, -50%) rotate(-14deg);
      background: radial-gradient(28% 22% at 36% 46%, rgb(var(--neb-a) / .30), transparent 70%), radial-gradient(24% 18% at 66% 56%, rgb(var(--neb-b) / .24), transparent 70%),
        radial-gradient(40% 12% at 50% 50%, rgb(var(--d-warm) / .10), transparent 70%), radial-gradient(18% 14% at 24% 62%, color-mix(in srgb, var(--sky-glow, #20306a) 60%, transparent), transparent 70%);
      animation: d-drift 70s ease-in-out infinite alternate; }
    @keyframes d-breathe { 0%,100% { opacity: calc(.78 * var(--ring)); scale: 1; } 50% { opacity: var(--ring); scale: 1.015; } }
    @keyframes d-turn { to { rotate: 360deg; } }
    @keyframes d-drift { to { translate: 2.5vmax -1.5vmax; scale: 1.06; } }
    /* the light pool: a soft oval where answers stand, and a shadow under the active card (its light on the floor) */
    #void-glow::after { content: ''; position: absolute; left: 50%; top: 74%; width: min(760px, 110vw); height: min(150px, 22vw); transform: translate(-50%, -50%);
      border-radius: 50%; background: radial-gradient(closest-side, rgb(var(--d-key) / .12), rgb(var(--d-key) / .04) 60%, transparent);
      transition: opacity 1.2s var(--d-ease-out), scale 1.2s var(--d-ease-out); opacity: .85; }
    #void-glow::before { content: ''; position: absolute; left: 50%; top: -30vh; width: 90vmax; height: 70vh; transform: translateX(-50%);
      background: radial-gradient(closest-side, rgb(var(--d-key) / .08), transparent); }
    /* the void wakes when you start to ask, leans in while a card is up, and spins up while Verse is thinking */
    html:has(#input:focus) #void-depth::before { animation-duration: 6s, 160s; }
    html:has(.vpage.on) #void-depth::before { animation-duration: 5s, 120s; }
    html:has(.vpage.on) #void-glow::after { opacity: 1; scale: 1.08; background: radial-gradient(closest-side, rgb(var(--d-key) / .16), rgb(0 0 0 / .35) 55%, transparent); }
    html.void-thinking #void-depth::before { animation-duration: 1.6s, 14s; --ring: 1.35; }
    html.void-thinking #void-lens { animation-duration: 1.8s; }
    /* light-reactive cards: the horizon light rims the card's top edge and blooms beneath it in the nebula's colour, stronger while thinking */
    .vpage.on { box-shadow: var(--d-lift), 0 -1px 0 0 rgb(var(--d-key) / .35), 0 -24px 60px -30px rgb(var(--neb-a) / .55), 0 70px 140px -50px rgb(var(--neb-b) / .30); transition: box-shadow .9s var(--d-ease-out); }
    html.void-thinking .vpage.on { box-shadow: var(--d-lift), 0 -1px 0 0 rgb(var(--d-key) / .6), 0 -30px 80px -26px rgb(var(--neb-a) / .8), 0 80px 160px -50px rgb(var(--neb-b) / .45); }
    @media (prefers-reduced-motion: reduce) { #void-depth::before, #void-depth::after, #void-lens { animation: none; } }
    /* the ask bar: deeper glass, a lit rim that wakes on focus, a bigger calmer type size, a send key that glows when there is text */
    #row { border-radius: 22px; background: var(--d-glass); box-shadow: var(--d-lift); position: relative; isolation: isolate; }
    #row::after { content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none; z-index: -1;
      background: var(--d-rim); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude;
      opacity: .45; transition: opacity .35s ease; }
    #row:focus-within::after { opacity: 1; }
    #row:focus-within { box-shadow: var(--d-lift), 0 0 0 4px rgb(var(--d-key) / .10), 0 0 60px rgb(var(--d-key) / .16); }
    /* the ask bar's focus glow in the card's own palette (owner, 2026-10-18): a purple rim with a faint gold bloom and an inner shadow; only the glow eases in, and not at all for reduced motion */
    #row { transition: box-shadow .3s ease, border-color .3s ease; }
    #row:focus-within { border-color: rgba(190,150,255,.78); box-shadow: var(--d-lift), inset 0 0 16px rgba(167,120,255,.20), 0 0 0 3px rgba(167,120,255,.18), 0 0 34px rgba(167,120,255,.30), 0 0 72px rgba(255,210,122,.12); }
    @media (prefers-reduced-motion: reduce) { #row { transition: none; } }
    #input { font-size: 17px; letter-spacing: -.005em; color: var(--d-ink); }
    #input::placeholder { color: var(--d-ink-3); }
    #go { transition: background .25s ease, box-shadow .25s ease, color .25s ease; }
    #row:has(#input:not(:placeholder-shown)) #go { background: linear-gradient(180deg, rgb(var(--d-key) / .95), rgb(118 138 240)); color: #0a0c18;
      box-shadow: 0 0 0 1px rgba(255,255,255,.25) inset, 0 6px 20px rgb(var(--d-key) / .35); }
    /* the answer card shell: the same glass, a brighter top edge (light from above), a contact shadow on the floor, display numerals */
    .vpage { background: var(--d-glass); border-radius: 24px;
      box-shadow: 0 1px 0 rgba(255,255,255,.12) inset, 0 0 0 1px rgba(255,255,255,.05), 0 24px 60px rgba(0,0,0,.55), 0 80px 160px -40px rgb(var(--d-key) / .14); }
    .vpage::before { background: var(--d-rim); opacity: .7; }
    .vpage h2 { color: var(--d-ink); letter-spacing: -.015em; font-weight: 600; }
    .vpage .sub { color: var(--d-ink-3); }
    .vpage .big, .vpage .calc-big, .vpage .result { font-weight: 250; letter-spacing: -.03em; font-variant-numeric: tabular-nums;
      background: linear-gradient(180deg, #fff 30%, rgb(var(--d-key) / .85)); -webkit-background-clip: text; background-clip: text; color: transparent; }
    .vpage.on { animation: d-arrive .7s var(--d-ease-out) both; }
    @keyframes d-arrive { from { opacity: 0; filter: blur(8px); } to { opacity: 1; filter: none; } }
    @media (max-width: 480px) {
      #row { border-radius: 20px; }
      #input { font-size: 16px; } /* 16px: iOS never zooms the page when the ask bar takes focus */
      #void-depth::before, #void-lens { top: 40%; width: 128vmin; }
      .vpage { border-radius: 22px; }
    }
    @media (prefers-reduced-motion: reduce) { .vpage.on { animation: none; } #row::after { transition: none; } }
    @media (forced-colors: active) { #void-depth::before, #void-depth::after, #void-lens, #void-glow::before, #void-glow::after, #row::after { display: none; } }
    /* ---- the empty stage and the ask bar (owner, 2026-10-18; lib/empty-state.js, tools/empty-state.test.mjs) ---- */
    /* legible over anything bright behind it (a planet rim, the sun, a nebula): an opacity floor of .96 and a deeper blur, so the placeholder and the typed
       text measure at least 4.5:1 against even a white backdrop (the browser suite renders the bar over #fff and measures it) */
    #row { background: linear-gradient(165deg, rgba(40,46,70,.96) 0%, rgba(16,18,28,.97) 46%, rgba(20,22,40,.97) 100%);
      backdrop-filter: blur(26px) saturate(1.3); -webkit-backdrop-filter: blur(26px) saturate(1.3); }
    #input { color: #f2f4fb; caret-color: rgb(var(--d-key)); text-shadow: 0 1px 2px rgba(0,0,0,.55); }
    #input::placeholder { color: #b4b9cb; opacity: 1; }
    /* a ready bar: on a mouse the ask bar already has focus, and its glow (#row:focus-within) shows it */
    /* the round keys say what state they are in: on is lit (purple), off is quiet, listening pulses gold; every one has a hover and a focus ring */
    #mic, #go, #sound { transition: background .2s ease, box-shadow .2s ease, color .2s ease; }
    #mic:hover, #go:hover, #sound:hover { background: #2f3550; color: #fff; }
    #mic:focus-visible, #go:focus-visible, #sound:focus-visible { outline: 2px solid rgb(var(--d-key)); outline-offset: 2px; }
    #sound[aria-pressed="false"] { color: var(--d-ink-3); }
    #sound[aria-pressed="true"], #mic[aria-pressed="true"] { color: #fff; background: #3a2f6e; box-shadow: 0 0 0 1px rgb(var(--d-key) / .7), 0 0 18px rgb(var(--d-key) / .45); }
    #mic.listening { box-shadow: 0 0 0 2px rgb(255 205 110 / .9), 0 0 20px rgb(255 190 90 / .5); animation: v-listen 1.4s ease-in-out infinite; }
    @keyframes v-listen { 50% { box-shadow: 0 0 0 2px rgb(255 205 110 / .5), 0 0 8px rgb(255 190 90 / .25); } }
    @media (prefers-reduced-motion: reduce) { #mic.listening { animation: none; } }
    /* offline: calm, not alarming. The halo takes a faint amber tint; asks that need no network keep working */
    html.void-offline #void-lens { background: radial-gradient(closest-side, transparent 35.2%, rgba(255,190,100,.30) 36.4%, rgba(255,160,70,.12) 46%, transparent 60%); }
    html.void-offline #void-depth::before { opacity: calc(.62 * var(--ring)); }
    /* the corner anchor (asked by Verse, 2026-10-18, after the text link went: "a subtle, ghosted icon that only becomes fully opaque when the user's
       mouse approaches the edge of the stage"): a ghost of a heart at the bottom right that opens the store; it wakes when the pointer comes within
       90 px of the corner (html.void-edge), on hover, or on keyboard focus. The store still answers "open the store", "support void", "tip", "buy". */
    #void-anchor { position: fixed; right: 12px; bottom: 12px; z-index: 6; width: 28px; height: 28px; display: grid; place-items: center; color: #d7d2ff;
      opacity: .12; transition: opacity .2s ease, transform .2s ease; border-radius: 50%; text-decoration: none; }
    #void-anchor svg { width: 16px; height: 16px; display: block; }
    /* the heart fills from the bottom with how much is on your stage to go back to (asked by Verse, 2026-10-18, lib/anchor-density.js: "navigation
       depth"): violet by the share of the goal, the quiet green of the list bar when the goal is met; nothing else about the anchor changes */
    #void-anchor .void-anchor-fill { fill: rgba(150,120,255,.95); }
    #void-anchor[data-state="met"] .void-anchor-fill { fill: rgba(120,200,150,.9); }
    html.void-edge #void-anchor, #void-anchor:hover, #void-anchor:focus-visible { opacity: 1; transform: scale(1.1); }
    #void-anchor:focus-visible { outline: 2px solid rgb(var(--d-key)); outline-offset: 2px; }
    @media (prefers-reduced-motion: reduce) { #void-anchor { transition: none; } html.void-edge #void-anchor, #void-anchor:hover { transform: none; } }
    /* the MultiVerse mark (members perk, 2026-10-30): a paid Verse's stage shows it beside the anchor; it opens /members/. Never shown signed out */
    #void-member { position: fixed; right: 46px; bottom: 14px; z-index: 6; height: 24px; padding: 0 10px; display: inline-flex; align-items: center; gap: 5px; border-radius: 999px;
      border: 1px solid rgba(150,120,255,.55); background: rgba(20,18,34,.72); color: #d7d2ff; font: 600 11px/1 system-ui, sans-serif; letter-spacing: .04em; text-decoration: none; opacity: .7; transition: opacity .2s; }
    #void-member::before { content: "\2726"; color: rgba(170,140,255,.95); }
    #void-member:hover, #void-member:focus-visible { opacity: 1; }
    #void-member:focus-visible { outline: 2px solid rgb(var(--d-key)); outline-offset: 2px; }
    @media (max-width: 700px) { #void-member { right: 40px; bottom: calc(8px + env(safe-area-inset-bottom, 0px)); opacity: .45; } }
    @media (max-width: 700px) { #void-anchor { right: 8px; bottom: calc(6px + env(safe-area-inset-bottom, 0px)); opacity: .22; } #dock { padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px)); } }
