/* ============================================================
   monCAPTCHA — style.css
   "Golden Hour Field Guide" HUD
   Walnut wood chips for in-game HUD, warm parchment cards for
   modal moments. Amber / coral / pond accents over the dusk
   voxel diorama. Fraunces display + Nunito body.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,600;0,9..144,800;0,9..144,900;1,9..144,600&family=Nunito:wght@400;600;700;800&display=swap');

/* ---------- Design tokens ---------- */
:root {
    --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
    --font-body: 'Nunito', 'Segoe UI', system-ui, -apple-system, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace;

    --ink: #35241a;
    --ink-deep: #241610;
    --ink-soft: #6b5040;
    --paper: #f9efdb;
    --cream: #ffe9c6;
    --amber: #f2a33c;
    --amber-bright: #ffb84d;
    --amber-deep: #cf7a1d;
    --coral: #e2654e;
    --leaf: #5d9c4f;
    --leaf-deep: #47803c;
    --pond: #3e8e7e;

    --paper-tex:
        radial-gradient(130% 60% at 50% 0%, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0) 55%),
        repeating-linear-gradient(-3deg, rgba(122, 80, 42, 0.035) 0 3px, rgba(255, 255, 255, 0) 3px 7px),
        linear-gradient(180deg, #fbf2e0, #f3e3c4);

    --card-shadow:
        0 7px 0 rgba(36, 22, 16, 0.8),
        0 30px 60px -18px rgba(20, 8, 2, 0.65);

    --chip-shadow:
        inset 0 1px 0 rgba(255, 214, 158, 0.28),
        inset 0 0 0 1px rgba(255, 214, 158, 0.06),
        0 3px 0 rgba(20, 10, 6, 0.4),
        0 12px 26px -10px rgba(20, 10, 6, 0.55);
}

/* ---------- Reset ---------- */
*,
*::before,
*::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html,
body {
    height: 100%;
    width: 100%;
    overflow: hidden;
    background: #191014;
    font-family: var(--font-body);
    color: var(--cream);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overscroll-behavior: none;
    touch-action: none;
}

::selection {
    background: var(--amber);
    color: var(--ink-deep);
}

button:focus-visible {
    outline: 3px solid var(--amber);
    outline-offset: 2px;
}

/* ---------- Canvas host ---------- */
#captcha-container {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
}

/* item 421: brightness slider — set on <html> by the accessibility panel so it
   cascades here without touching engine.js/renderer code.
   PERF: this used to be an UNCONDITIONAL `filter: brightness(...)` on the
   element that hosts the WebGL canvas. A CSS filter — even brightness(1),
   which is a visual no-op — forces the compositor to route the full-viewport
   canvas through a filter step every composited frame instead of presenting it
   directly, so every player paid for a control almost none of them touch.
   ui.js now sets data-brightness on <html> only while the value is actually
   off 1, so the default session composites the canvas untouched. */
html[data-brightness] #captcha-container {
    filter: brightness(var(--scene-brightness, 1));
    transition: filter 0.15s ease;
}

/* item 410: brief golden wash for a legendary capture, toggled by ui.js's
   pulseLegendaryHud(). Pure CSS animation — no extra DOM node needed. */
#captcha-container.legendary-pulse::after {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 5;
    background: radial-gradient(ellipse at center, rgba(255, 215, 94, 0.32), rgba(255, 215, 94, 0) 68%);
    animation: legendary-pulse-fade 0.8s ease forwards;
}

@keyframes legendary-pulse-fade {
    0% { opacity: 0; }
    25% { opacity: 1; }
    100% { opacity: 0; }
}

#captcha-container canvas {
    display: block;
    width: 100% !important;
    height: 100% !important;
}

/* ---------- HUD overlay ---------- */
#hud {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10;
    pointer-events: none;
}

/* Painterly vignette framing the diorama (never blocks input) */
#hud::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(118% 92% at 50% 44%, rgba(0, 0, 0, 0) 60%, rgba(46, 22, 10, 0.26) 100%);
}

/* ---------- Top-left HUD column (counter badge + instructions chip) ---------- */
.hud-corner {
    position: absolute;
    top: max(env(safe-area-inset-top), 14px);
    left: max(env(safe-area-inset-left), 14px);
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    max-width: min(72vw, 460px);
    pointer-events: none;
    /* item 428: adjustable HUD scale, set by the accessibility panel */
    transform: scale(var(--hud-scale, 1));
    transform-origin: top left;
}

.hud-corner > * {
    animation: hud-drop 0.6s cubic-bezier(0.2, 0.9, 0.3, 1.2) backwards;
}

.hud-corner > :nth-child(2) {
    animation-delay: 0.12s;
}

@keyframes hud-drop {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }
}

/* Walnut wood chip — shared base for small HUD elements */
.hud-chip {
    width: fit-content;
    padding: 9px 14px;
    background:
        repeating-linear-gradient(105deg, rgba(255, 205, 140, 0.045) 0 9px, rgba(255, 205, 140, 0) 9px 20px),
        linear-gradient(180deg, rgba(66, 41, 28, 0.88), rgba(40, 24, 16, 0.88));
    border: 1px solid rgba(20, 10, 6, 0.85);
    border-radius: 12px;
    box-shadow: var(--chip-shadow);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: var(--cream);
    font-size: clamp(12px, 2.1vw, 14.5px);
    font-weight: 600;
    line-height: 1.65;
    letter-spacing: 0.01em;
    text-shadow: 0 1px 0 rgba(20, 10, 6, 0.55);
}

/* Keycap hints inside chips */
.hud-chip kbd {
    display: inline-block;
    padding: 0 7px 1px;
    margin: 0 1px;
    border-radius: 7px;
    background: linear-gradient(180deg, #fff4de, #ecd9b4);
    border: 1px solid rgba(36, 22, 16, 0.95);
    box-shadow: 0 2px 0 rgba(36, 22, 16, 0.95);
    color: var(--ink-deep);
    font-family: var(--font-body);
    font-size: 0.82em;
    font-weight: 800;
    line-height: 1.5;
    letter-spacing: 0.02em;
    text-shadow: none;
    vertical-align: baseline;
    white-space: nowrap;
}

#instructions {
    max-width: 100%;
}

/* item 409: recedes (not removed — still peekable) after the player's
   first successful capture, set by ui.js's updateCounterUI() */
#instructions.instructions-faded {
    opacity: 0.16;
    transition: opacity 1s ease;
}

/* ---------- Capture counter badge ---------- */
#counter {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 9px 17px 9px 12px;
    font-size: clamp(15px, 2.6vw, 19px);
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
    color: #ffe3b3;
    border-radius: 14px;
    background:
        repeating-linear-gradient(105deg, rgba(255, 205, 140, 0.05) 0 9px, rgba(255, 205, 140, 0) 9px 20px),
        linear-gradient(180deg, rgba(86, 50, 27, 0.92), rgba(46, 26, 15, 0.92));
    border: 1px solid rgba(20, 10, 6, 0.9);
    box-shadow:
        inset 0 1px 0 rgba(255, 214, 158, 0.35),
        inset 0 0 0 1px rgba(244, 163, 73, 0.22),
        0 3px 0 rgba(20, 10, 6, 0.4),
        0 12px 26px -10px rgba(20, 10, 6, 0.55);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    text-shadow: 0 1px 0 rgba(20, 10, 6, 0.6);
}

/* Capture-ball emblem (survives JS textContent updates) */
#counter::before {
    content: "";
    flex: 0 0 auto;
    width: 1.15em;
    height: 1.15em;
    border-radius: 50%;
    background: linear-gradient(to bottom, var(--coral) 0 42%, var(--ink-deep) 42% 58%, var(--paper) 58% 100%);
    border: 2px solid var(--ink-deep);
    box-shadow:
        inset -2px -2px 0 rgba(0, 0, 0, 0.16),
        0 2px 0 rgba(20, 10, 6, 0.45);
}

/* Progress-ring border (item 404) — a conic-gradient ring drawn as an
   annulus via mask-composite so it hugs the chip's own rounded corners.
   ui.js sets --progress (0-100) each time updateCounterUI() runs. */
#counter::after {
    content: "";
    position: absolute;
    inset: -4px;
    border-radius: 17px;
    padding: 3px;
    background: conic-gradient(from -90deg, var(--leaf) calc(var(--progress, 0) * 1%), rgba(255, 255, 255, 0.14) 0);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
    transition: background 0.4s ease;
}

/* ---------- Reticle (CSS-only) ---------- */
#crosshair {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 34px;
    height: 34px;
    /* hud-scale (item 428) multiplies the base size; pref-large-crosshair
       (item 423) overrides width/height directly, below */
    transform: translate(-50%, -50%) scale(var(--hud-scale, 1));
    pointer-events: none;
    border: 2px solid rgba(255, 243, 221, 0.92);
    border-radius: 50%;
    box-shadow:
        0 0 0 1.5px rgba(36, 22, 16, 0.55),
        inset 0 0 0 1.5px rgba(36, 22, 16, 0.55),
        0 0 14px rgba(255, 200, 110, 0.25);
    opacity: 0.9;
    transition:
        transform 0.22s cubic-bezier(0.175, 0.885, 0.32, 1.4),
        border-color 0.18s ease,
        box-shadow 0.22s ease,
        opacity 0.2s ease;
}

/* Center dot */
#crosshair::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: #fff3dd;
    box-shadow:
        0 0 0 1.5px rgba(36, 22, 16, 0.6),
        0 0 10px rgba(255, 220, 150, 0.6);
    transform: translate(-50%, -50%);
    transition: transform 0.18s cubic-bezier(0.175, 0.885, 0.32, 1.4), background 0.18s ease;
}

/* Slow-turning dashed compass ring */
#crosshair::after {
    content: "";
    position: absolute;
    inset: -9px;
    border: 2px dashed rgba(255, 243, 221, 0.55);
    border-radius: 50%;
    animation: reticle-turn 7s linear infinite;
    transition: border-color 0.18s ease;
}

@keyframes reticle-turn {
    to {
        transform: rotate(360deg);
    }
}

/* Creature in range: warm up, tighten, spin faster. This IS the hook for
   item 405 — targeting.js toggles this class once per frame based on its
   own hover+range+alive+capturing check, so "valid target in CAPTURE_RANGE"
   already drives crosshair color/scale/glow with zero coupling. What it
   does NOT do yet: shade continuously between RING_RISKY/RING_SURE with the
   live capture-% the way the 3D ring does — targeting.js would need to also
   write something like `ui.crosshair.style.setProperty('--chance', chance)`
   (or a data-chance attribute) alongside classList.add('hovering') for that
   finer gradient; out of this pass's file scope (targeting.js untouched). */
#crosshair.hovering {
    opacity: 1;
    border-color: var(--amber-bright);
    transform: translate(-50%, -50%) scale(calc(1.2 * var(--hud-scale, 1)));
    box-shadow:
        0 0 0 1.5px rgba(36, 22, 16, 0.6),
        inset 0 0 0 1.5px rgba(36, 22, 16, 0.6),
        0 0 20px rgba(255, 184, 77, 0.55);
}

#crosshair.hovering::before {
    background: var(--amber-bright);
    transform: translate(-50%, -50%) scale(1.5);
}

#crosshair.hovering::after {
    border-color: rgba(255, 184, 77, 0.9);
    animation-duration: 1.8s;
}

/* item 423: large, high-contrast crosshair mode */
html.pref-large-crosshair #crosshair {
    width: 50px;
    height: 50px;
    border-width: 3px;
    border-color: #fff;
    opacity: 1;
}

html.pref-large-crosshair #crosshair::before {
    width: 7px;
    height: 7px;
}

html.pref-large-crosshair #crosshair.hovering {
    border-color: #fff2a8;
    box-shadow:
        0 0 0 2px rgba(36, 22, 16, 0.75),
        inset 0 0 0 2px rgba(36, 22, 16, 0.75),
        0 0 26px rgba(255, 226, 130, 0.85);
}

/* item 417: colorblind-safe accent — swaps the hover tint from amber to a
   blue/cyan already used by RING_SURE, keeping the amber<->cyan axis (never
   a red/green pair) but adding a second cue (thicker ring) for redundancy */
html.pref-colorblind #crosshair.hovering {
    border-color: #5ff0d0;
    box-shadow:
        0 0 0 1.5px rgba(36, 22, 16, 0.6),
        inset 0 0 0 1.5px rgba(36, 22, 16, 0.6),
        0 0 20px rgba(95, 240, 208, 0.6);
}

html.pref-colorblind #crosshair.hovering::before {
    background: #5ff0d0;
}

/* ---------- Parchment card (shared: title, pause, success) ---------- */
#click-to-play-card,
#pause-overlay .card,
#success-card {
    position: relative;
    width: min(90vw, 460px);
    padding: clamp(26px, 6vw, 44px) clamp(22px, 5vw, 38px);
    background: var(--paper-tex);
    border: 2px solid var(--ink-deep);
    border-radius: 22px;
    box-shadow: var(--card-shadow);
    text-align: center;
    color: var(--ink);
    animation: card-pop 0.55s cubic-bezier(0.2, 0.9, 0.3, 1.25) backwards;
}

/* Stitched inner border — cozy quilted detail */
#click-to-play-card::before,
#pause-overlay .card::before,
#success-card::before {
    content: "";
    position: absolute;
    inset: 9px;
    border: 2px dashed rgba(93, 60, 35, 0.22);
    border-radius: 14px;
    pointer-events: none;
}

#click-to-play-card h1,
#pause-overlay .card h1,
#success-card h1 {
    font-family: var(--font-display);
    font-weight: 900;
    font-size: clamp(32px, 7.5vw, 52px);
    line-height: 1.05;
    letter-spacing: -0.015em;
    color: var(--ink-deep);
    margin-bottom: 8px;
}

/* Amber underline flourish (persists when JS swaps the h1 text) */
#click-to-play-card h1::after,
#pause-overlay .card h1::after,
#success-card h1::after {
    content: "";
    display: block;
    width: 76px;
    height: 4px;
    margin: 14px auto 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, rgba(242, 163, 60, 0) 0%, var(--amber) 22% 78%, rgba(242, 163, 60, 0) 100%);
}

#click-to-play-card p,
#pause-overlay .card p,
#success-card p {
    font-size: clamp(14px, 2.3vw, 16.5px);
    font-weight: 600;
    color: var(--ink-soft);
    line-height: 1.6;
    margin: 6px 0 0;
}

@keyframes card-pop {
    0% {
        transform: scale(0.82) translateY(14px);
        opacity: 0;
    }
    70% {
        transform: scale(1.02) translateY(-2px);
        opacity: 1;
    }
    100% {
        transform: scale(1) translateY(0);
        opacity: 1;
    }
}

/* ---------- Title screen (click-to-play / paused) ---------- */
#click-to-play {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    /* item 431: full-screen overlays clear notches/rounded corners in
       landscape too, not just the edge-anchored HUD chips */
    padding: max(env(safe-area-inset-top), 20px) max(env(safe-area-inset-right), 20px)
             max(env(safe-area-inset-bottom), 20px) max(env(safe-area-inset-left), 20px);
    background:
        radial-gradient(120% 100% at 50% 18%, rgba(58, 32, 16, 0.1), rgba(28, 14, 8, 0.58) 88%),
        rgba(38, 20, 10, 0.32);
    -webkit-backdrop-filter: blur(7px) saturate(1.1);
    backdrop-filter: blur(7px) saturate(1.1);
    pointer-events: auto;
    opacity: 1;
    transition: opacity 0.3s ease;
}

/* PERF: opacity:0 alone left this full-viewport overlay — and its
   backdrop-filter: blur(7px) saturate(1.1), plus the infinite CSS animations
   on the card inside it — live over the canvas for the whole session. The
   delayed `visibility` step takes it out of rendering entirely once the fade
   has finished, while the 0.3s opacity transition still plays exactly as
   before (visibility flips at the END of the fade on hide, and immediately on
   show, which is what the 0s/0.3s delay pair encodes). */
#click-to-play {
    transition: opacity 0.3s ease, visibility 0s linear 0s;
}

#click-to-play.hidden {
    opacity: 0;
    pointer-events: none;
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0s linear 0.3s;
}

#click-to-play-card {
    z-index: 1;
}

/* Decorative sky behind the title card */
.ctp-scene {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
}

/* Rotating golden-hour sunburst */
.ctp-scene .sunburst {
    position: absolute;
    left: 50%;
    top: 50%;
    width: min(150vmin, 980px);
    height: min(150vmin, 980px);
    border-radius: 50%;
    background: repeating-conic-gradient(from 0deg, rgba(255, 196, 110, 0.11) 0deg 8deg, rgba(255, 196, 110, 0) 8deg 16deg);
    -webkit-mask-image: radial-gradient(circle, #000 24%, transparent 66%);
    mask-image: radial-gradient(circle, #000 24%, transparent 66%);
    transform: translate(-50%, -50%);
    animation: ray-turn 90s linear infinite;
}

@keyframes ray-turn {
    to {
        transform: translate(-50%, -50%) rotate(360deg);
    }
}

/* Drifting beveled voxel cubes */
.ctp-scene .voxel {
    position: absolute;
    border-radius: 5px;
    border: 2px solid rgba(30, 15, 8, 0.55);
    box-shadow:
        inset -5px -7px 0 rgba(30, 10, 0, 0.22),
        inset 4px 5px 0 rgba(255, 245, 215, 0.3);
    animation: voxel-drift 7s ease-in-out infinite;
}

.ctp-scene .v1 {
    width: 26px;
    height: 26px;
    left: 12%;
    top: 22%;
    background: var(--amber);
    animation-duration: 8s;
}

.ctp-scene .v2 {
    width: 18px;
    height: 18px;
    right: 14%;
    top: 30%;
    background: var(--pond);
    animation-delay: 1.2s;
}

.ctp-scene .v3 {
    width: 22px;
    height: 22px;
    left: 17%;
    bottom: 20%;
    background: var(--coral);
    animation-delay: 2s;
    animation-duration: 9s;
}

.ctp-scene .v4 {
    width: 14px;
    height: 14px;
    right: 19%;
    bottom: 27%;
    background: var(--paper);
    animation-delay: 0.6s;
}

@keyframes voxel-drift {
    0%,
    100% {
        transform: translateY(0) rotate(-6deg);
    }
    50% {
        transform: translateY(-18px) rotate(8deg);
    }
}

/* Small-caps kicker above the title (div — JS only touches h1/p) */
.ctp-kicker {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 14px;
    font-family: var(--font-body);
    font-size: clamp(10.5px, 1.8vw, 12.5px);
    font-weight: 800;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--amber-deep);
}

.ctp-kicker::before,
.ctp-kicker::after {
    content: "";
    width: 26px;
    height: 2px;
    border-radius: 1px;
    background: currentColor;
    opacity: 0.55;
}

/* "Click anywhere" hint styled as a bobbing amber pill */
#click-to-play-card .hint {
    display: inline-block;
    margin-top: 18px;
    padding: 9px 20px;
    border-radius: 999px;
    background: linear-gradient(180deg, #ffd489, #f4a949);
    border: 2px solid var(--ink-deep);
    box-shadow: 0 3px 0 var(--ink-deep);
    color: var(--ink-deep);
    font-size: clamp(12.5px, 2vw, 14.5px);
    font-weight: 800;
    line-height: 1.4;
    animation: hint-bob 2.2s ease-in-out infinite;
}

@keyframes hint-bob {
    0%,
    100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-3px);
    }
}

/* Secondary "Accessibility" entry point (items 415/417/418/421/423/428) —
   lives on the shared title/pause card, so the pointer is always free when
   it's reachable (never fights Pointer Lock). Deliberately lower-key than
   the amber .hint pill: an outline chip, not a second call to action. */
#a11y-open-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 14px;
    padding: 7px 16px;
    border-radius: 999px;
    background: rgba(53, 36, 26, 0.08);
    border: 2px solid rgba(53, 36, 26, 0.35);
    color: var(--ink-soft);
    font-family: var(--font-body);
    font-size: clamp(11.5px, 1.8vw, 13px);
    font-weight: 800;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

#a11y-open-btn:hover {
    background: rgba(53, 36, 26, 0.14);
    border-color: var(--ink-soft);
    color: var(--ink);
}

/* ---------- Pause overlay ---------- */
#pause-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: none;
    align-items: center;
    justify-content: center;
    padding: max(env(safe-area-inset-top), 20px) max(env(safe-area-inset-right), 20px)
             max(env(safe-area-inset-bottom), 20px) max(env(safe-area-inset-left), 20px);
    background:
        radial-gradient(120% 100% at 50% 18%, rgba(58, 32, 16, 0.1), rgba(28, 14, 8, 0.58) 88%),
        rgba(38, 20, 10, 0.32);
    -webkit-backdrop-filter: blur(7px) saturate(1.1);
    backdrop-filter: blur(7px) saturate(1.1);
    pointer-events: auto;
    opacity: 0;
    transition: opacity 0.3s ease;
}

#pause-overlay.visible {
    display: flex;
    opacity: 1;
}

/* ---------- Success modal ---------- */
#success-modal {
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    align-items: center;
    justify-content: center;
    padding: max(env(safe-area-inset-top), 20px) max(env(safe-area-inset-right), 20px)
             max(env(safe-area-inset-bottom), 20px) max(env(safe-area-inset-left), 20px);
    background:
        radial-gradient(120% 100% at 50% 20%, rgba(70, 40, 16, 0.12), rgba(24, 11, 6, 0.6) 90%),
        rgba(30, 15, 8, 0.4);
    -webkit-backdrop-filter: blur(7px) saturate(1.1);
    backdrop-filter: blur(7px) saturate(1.1);
    pointer-events: none;
}

#success-modal.visible {
    display: flex;
    pointer-events: auto;
}

#success-card {
    width: min(88vw, 430px);
    z-index: 1;
}

#success-card h1 {
    font-size: clamp(26px, 5.5vw, 38px);
    margin-top: 18px;
}

#success-card h1::after {
    background: linear-gradient(90deg, rgba(93, 156, 79, 0) 0%, var(--leaf) 22% 78%, rgba(93, 156, 79, 0) 100%);
}

/* Verified seal */
#success-check {
    position: relative;
    width: clamp(64px, 14vw, 84px);
    height: clamp(64px, 14vw, 84px);
    margin: 0 auto;
    border-radius: 50%;
    background: radial-gradient(120% 120% at 30% 25%, #8cc47a, var(--leaf) 55%, var(--leaf-deep));
    border: 3px solid var(--ink-deep);
    box-shadow:
        0 5px 0 rgba(36, 22, 16, 0.35),
        inset 0 -6px 0 rgba(0, 0, 0, 0.14);
    animation: check-pop 0.6s cubic-bezier(0.2, 1.2, 0.35, 1.3) 0.1s backwards;
}

/* Radiating amber ring */
#success-check::before {
    content: "";
    position: absolute;
    inset: -3px;
    border-radius: 50%;
    border: 3px solid var(--amber);
    opacity: 0;
    animation: check-ring 1.5s ease-out 0.5s 2;
}

/* Check mark */
#success-check::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 52%;
    width: 46%;
    height: 24%;
    border-left: 5px solid #fff8ea;
    border-bottom: 5px solid #fff8ea;
    transform: translate(-50%, -62%) rotate(-45deg);
    animation: check-draw 0.35s cubic-bezier(0.2, 1.4, 0.4, 1.4) 0.4s backwards;
}

@keyframes check-pop {
    from {
        transform: scale(0.3);
        opacity: 0;
    }
}

@keyframes check-ring {
    0% {
        transform: scale(0.8);
        opacity: 0.9;
    }
    100% {
        transform: scale(1.7);
        opacity: 0;
    }
}

@keyframes check-draw {
    from {
        transform: translate(-50%, -62%) rotate(-45deg) scale(0);
    }
}

/* Chunky game button */
#success-continue {
    margin-top: 26px;
    padding: 13px 38px;
    font-family: var(--font-body);
    font-size: clamp(14px, 2.2vw, 17px);
    font-weight: 800;
    letter-spacing: 0.02em;
    color: var(--ink-deep);
    background: linear-gradient(180deg, #ffc169, var(--amber) 55%, #e8922e);
    border: 2px solid var(--ink-deep);
    border-radius: 14px;
    box-shadow: 0 5px 0 var(--ink-deep), 0 12px 22px -8px rgba(36, 22, 16, 0.5);
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.12s ease, filter 0.12s ease;
}

#success-continue:hover {
    transform: translateY(-2px);
    box-shadow: 0 7px 0 var(--ink-deep), 0 16px 26px -8px rgba(36, 22, 16, 0.55);
    filter: brightness(1.05);
}

#success-continue:active {
    transform: translateY(3px);
    box-shadow: 0 2px 0 var(--ink-deep), 0 8px 16px -8px rgba(36, 22, 16, 0.5);
}

/* Confetti burst (decorative markup, hidden from AT) */
#success-modal .confetti {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
}

.confetti i {
    position: absolute;
    top: -4vh;
    width: 9px;
    height: 15px;
    border-radius: 2px;
    opacity: 0;
    animation: confetti-fall var(--dur, 3.4s) linear var(--delay, 0s) infinite;
}

.confetti i:nth-child(4n + 1) { background: var(--amber); }
.confetti i:nth-child(4n + 2) { background: var(--pond); }
.confetti i:nth-child(4n + 3) { background: var(--coral); }
.confetti i:nth-child(4n + 4) { background: var(--paper); }

.confetti i:nth-child(even) {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.confetti i:nth-child(1)  { left: 4%;  --delay: 0s;    --dur: 3.1s; --sway: 34px; }
.confetti i:nth-child(2)  { left: 11%; --delay: 0.5s;  --dur: 3.7s; --sway: -42px; }
.confetti i:nth-child(3)  { left: 18%; --delay: 1.1s;  --dur: 2.9s; --sway: 26px; }
.confetti i:nth-child(4)  { left: 26%; --delay: 0.2s;  --dur: 3.4s; --sway: -30px; }
.confetti i:nth-child(5)  { left: 33%; --delay: 0.9s;  --dur: 3.9s; --sway: 44px; }
.confetti i:nth-child(6)  { left: 41%; --delay: 0.4s;  --dur: 3.0s; --sway: -24px; }
.confetti i:nth-child(7)  { left: 49%; --delay: 1.4s;  --dur: 3.6s; --sway: 30px; }
.confetti i:nth-child(8)  { left: 56%; --delay: 0.1s;  --dur: 3.2s; --sway: -38px; }
.confetti i:nth-child(9)  { left: 63%; --delay: 0.8s;  --dur: 3.8s; --sway: 28px; }
.confetti i:nth-child(10) { left: 71%; --delay: 0.3s;  --dur: 2.8s; --sway: -26px; }
.confetti i:nth-child(11) { left: 78%; --delay: 1.2s;  --dur: 3.5s; --sway: 40px; }
.confetti i:nth-child(12) { left: 85%; --delay: 0.6s;  --dur: 3.1s; --sway: -34px; }
.confetti i:nth-child(13) { left: 91%; --delay: 1.0s;  --dur: 3.7s; --sway: 24px; }
.confetti i:nth-child(14) { left: 96%; --delay: 0.35s; --dur: 3.3s; --sway: -20px; }

@keyframes confetti-fall {
    0% {
        transform: translate3d(0, 0, 0) rotate(0turn);
        opacity: 0;
    }
    6% {
        opacity: 1;
    }
    100% {
        transform: translate3d(var(--sway, 24px), 108vh, 0) rotate(2.2turn);
        opacity: 0.85;
    }
}

/* ---------- Play hint pill ---------- */
#play-hint {
    position: absolute;
    bottom: max(env(safe-area-inset-bottom), 22px);
    left: 50%;
    transform: translateX(-50%) scale(var(--hud-scale, 1));
    padding: 10px 20px;
    white-space: nowrap;
    border-radius: 999px;
    opacity: 0;
    transition: opacity 0.3s ease;
}

#play-hint.visible {
    opacity: 1;
}

/* ---------- Touch controls (mobile) ---------- */
#touch-controls {
    display: none;
    position: absolute;
    inset: 0;
}

body.touch-mode #touch-controls {
    display: block;
}

/* Invisible drag-to-look surface, layered under the joystick/buttons */
#touch-look-zone {
    position: absolute;
    inset: 0;
    pointer-events: none;
    touch-action: none;
}

#touch-controls.visible #touch-look-zone {
    pointer-events: auto;
}

/* item 433: subtle glow dot that follows the look-drag finger, positioned
   by touch-controls.js; fades out on release so new mobile players can see
   the input model tracking their thumb */
#touch-look-indicator {
    position: absolute;
    left: 0;
    top: 0;
    width: 54px;
    height: 54px;
    margin: -27px 0 0 -27px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 214, 158, 0.32), rgba(255, 214, 158, 0) 68%);
    opacity: 0;
    transform: scale(0.6);
    pointer-events: none;
    transition: opacity 0.35s ease, transform 0.35s ease;
    will-change: transform, opacity;
}

#touch-look-indicator.active {
    opacity: 1;
    transform: scale(1);
    transition: opacity 0.08s ease, transform 0.08s ease;
}

/* Move joystick + action buttons: hidden until play actually starts,
   faded in alongside #play-hint on lock. Orientation changes (item 434)
   just reflow these percentages/env() insets instantly since nothing here
   is JS-computed pixel geometry — the short transition below only smooths
   the (rare) case of the safe-area insets themselves changing mid-session. */
#touch-move-zone,
.touch-btn {
    position: absolute;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.1s ease, background 0.15s ease,
        border-color 0.15s ease, box-shadow 0.15s ease, left 0.2s ease, right 0.2s ease, bottom 0.2s ease;
    touch-action: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
}

#touch-controls.visible #touch-move-zone,
#touch-controls.visible .touch-btn {
    opacity: 1;
    pointer-events: auto;
}

#touch-move-zone {
    position: absolute;
    left: max(env(safe-area-inset-left), 24px);
    bottom: max(env(safe-area-inset-bottom), 24px);
    width: 110px;
    height: 110px;
    border-radius: 50%;
    background: radial-gradient(circle at 40% 35%, rgba(255, 214, 158, 0.16), rgba(20, 10, 6, 0.4) 72%);
    border: 2px solid rgba(255, 214, 158, 0.3);
    box-shadow: var(--chip-shadow);
}

/* item 436: a dashed ring at the joystick's actual live drag radius
   (CONFIG.TOUCH_JOYSTICK_RADIUS, written to --joystick-radius by
   touch-controls.js) so the knob's travel distance is discoverable at a
   glance instead of implied by the outer zone's unrelated 55px radius */
#touch-move-zone::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: calc(var(--joystick-radius, 36px) * 2);
    height: calc(var(--joystick-radius, 36px) * 2);
    margin: calc(var(--joystick-radius, 36px) * -1) 0 0 calc(var(--joystick-radius, 36px) * -1);
    border-radius: 50%;
    border: 1.5px dashed rgba(255, 214, 158, 0.45);
    pointer-events: none;
    animation: joystick-radius-breathe 2.6s ease-in-out infinite;
}

@keyframes joystick-radius-breathe {
    0%, 100% { opacity: 0.35; }
    50% { opacity: 0.8; }
}

#touch-move-knob {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 46px;
    height: 46px;
    margin: -23px 0 0 -23px;
    border-radius: 50%;
    background: linear-gradient(180deg, #ffd489, #f4a949);
    border: 2px solid var(--ink-deep);
    box-shadow: 0 3px 0 var(--ink-deep), 0 8px 16px -6px rgba(20, 10, 6, 0.6);
    will-change: transform;
    transition: box-shadow 0.12s ease;
}

/* item 413: glow-on-press feedback (touch-controls.js toggles this class
   in onMoveStart/onMoveEnd — added to the KNOB itself, not just the CSS
   :active pseudo-class, since touches land on the wider zone) */
#touch-move-knob.pressed {
    box-shadow:
        0 3px 0 var(--ink-deep),
        0 8px 16px -6px rgba(20, 10, 6, 0.6),
        0 0 0 6px rgba(255, 196, 110, 0.32),
        0 0 22px rgba(255, 196, 110, 0.6);
}

.touch-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background:
        repeating-linear-gradient(105deg, rgba(255, 205, 140, 0.05) 0 9px, rgba(255, 205, 140, 0) 9px 20px),
        linear-gradient(180deg, rgba(66, 41, 28, 0.92), rgba(40, 24, 16, 0.92));
    border: 2px solid rgba(20, 10, 6, 0.9);
    box-shadow: var(--chip-shadow);
    color: var(--cream);
    font-family: var(--font-body);
    font-size: 11px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    text-shadow: 0 1px 0 rgba(20, 10, 6, 0.55);
}

.touch-btn:active {
    transform: scale(0.9);
    box-shadow: var(--chip-shadow), 0 0 16px rgba(255, 196, 110, 0.5);
}

#touch-throw-btn {
    right: max(env(safe-area-inset-right), 26px);
    bottom: max(env(safe-area-inset-bottom), 52px);
    width: 82px;
    height: 82px;
    font-size: 13px;
    background: linear-gradient(180deg, rgba(226, 101, 78, 0.4), rgba(66, 41, 28, 0.92) 65%);
}

#touch-jump-btn {
    right: max(env(safe-area-inset-right), 128px);
    bottom: max(env(safe-area-inset-bottom), 116px);
    width: 54px;
    height: 54px;
}

#touch-crouch-btn {
    right: max(env(safe-area-inset-right), 20px);
    bottom: max(env(safe-area-inset-bottom), 148px);
    width: 54px;
    height: 54px;
}

#touch-crouch-btn.active {
    background: linear-gradient(180deg, rgba(93, 156, 79, 0.6), rgba(40, 24, 16, 0.92) 65%);
    border-color: var(--leaf);
}

#touch-pause-btn {
    top: max(env(safe-area-inset-top), 14px);
    right: max(env(safe-area-inset-right), 14px);
    width: 38px;
    height: 38px;
    font-size: 13px;
}

/* ---------- Loading screen (dusk diorama) ---------- */
#loading {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 20;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    background:
        radial-gradient(140% 70% at 16% 110%, #241812 32%, rgba(36, 24, 18, 0) 62%),
        radial-gradient(140% 70% at 86% 114%, #241812 34%, rgba(36, 24, 18, 0) 64%),
        radial-gradient(90% 55% at 50% 92%, rgba(255, 171, 64, 0.5), rgba(255, 171, 64, 0) 70%),
        linear-gradient(180deg, #191014 0%, #33201a 45%, #6e3a20 80%, #a05a24 100%);
    color: var(--cream);
    transition: opacity 0.4s ease, visibility 0s linear 0s;
}

/* PERF: same as #click-to-play — without the delayed `visibility` step this
   full-viewport layered-gradient panel, and the infinite voxel-hop/voxel-shadow
   animations on the spinner inside it, stayed live over the canvas for the
   entire session after loading finished. */
#loading.hidden {
    opacity: 0;
    pointer-events: none;
    visibility: hidden;
    transition: opacity 0.4s ease, visibility 0s linear 0.4s;
}

#loading p {
    font-size: clamp(14px, 2.2vw, 17px);
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--cream);
    text-shadow: 0 2px 8px rgba(20, 8, 2, 0.6);
}

/* Hopping voxel cube stand-in for the spinner (element stays static;
   pseudo-elements carry the cube + its ground shadow) */
.spinner {
    position: relative;
    width: 72px;
    height: 88px;
}

.spinner::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 4px;
    width: 42px;
    height: 42px;
    margin-left: -21px;
    border-radius: 9px;
    background: linear-gradient(135deg, #ffc169, var(--amber) 50%, var(--amber-deep));
    border: 2px solid var(--ink-deep);
    box-shadow:
        inset -6px -8px 0 rgba(90, 40, 10, 0.35),
        inset 4px 5px 0 rgba(255, 240, 200, 0.5);
    animation: voxel-hop 1.5s cubic-bezier(0.45, 0.02, 0.35, 1) infinite;
}

.spinner::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: 4px;
    width: 46px;
    height: 12px;
    margin-left: -23px;
    border-radius: 50%;
    background: rgba(20, 8, 4, 0.5);
    filter: blur(2px);
    animation: voxel-shadow 1.5s cubic-bezier(0.45, 0.02, 0.35, 1) infinite;
}

@keyframes voxel-hop {
    0%,
    100% {
        transform: translateY(28px) rotate(0deg) scale(1.16, 0.82);
    }
    35% {
        transform: translateY(-4px) rotate(7deg) scale(0.94, 1.08);
    }
    50% {
        transform: translateY(-8px) rotate(0deg) scale(1, 1);
    }
    65% {
        transform: translateY(-4px) rotate(-7deg) scale(0.94, 1.08);
    }
}

@keyframes voxel-shadow {
    0%,
    100% {
        transform: scaleX(1);
        opacity: 0.55;
    }
    50% {
        transform: scaleX(0.55);
        opacity: 0.28;
    }
}

/* ---------- WebGL error fallback ---------- */
#error-message {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(26, 12, 6, 0.62);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    pointer-events: auto;
}

#error-message.visible {
    display: flex;
}

#error-message p {
    width: min(88vw, 430px);
    padding: clamp(24px, 5vw, 36px);
    background: var(--paper-tex);
    color: var(--ink);
    font-size: clamp(14px, 2.2vw, 16.5px);
    font-weight: 600;
    line-height: 1.6;
    text-align: center;
    border: 2px solid var(--ink-deep);
    border-radius: 18px;
    box-shadow: var(--card-shadow);
    animation: card-pop 0.55s cubic-bezier(0.2, 0.9, 0.3, 1.25) backwards;
}

#error-message p::before {
    content: "!";
    display: block;
    width: 46px;
    height: 46px;
    margin: 0 auto 14px;
    border-radius: 14px;
    background: linear-gradient(180deg, #f08a70, var(--coral));
    border: 2px solid var(--ink-deep);
    box-shadow: 0 3px 0 var(--ink-deep);
    color: #fff6ea;
    font-family: var(--font-display);
    font-size: 26px;
    font-weight: 800;
    line-height: 42px;
    text-align: center;
}

/* ---------- Weather condition badge (item 408) ---------- */
#weather-badge {
    display: flex;
    align-items: center;
    gap: 7px;
}

#weather-icon {
    font-size: 1.05em;
}

/* ---------- Zone compass (item 403) ---------- */
#compass {
    position: absolute;
    top: max(env(safe-area-inset-top), 14px);
    right: max(env(safe-area-inset-right), 14px);
    width: 52px;
    height: 52px;
    border-radius: 50%;
    /* fallback for browsers without color-mix(), overridden below where supported */
    background: radial-gradient(circle at 35% 30%, rgba(93, 156, 79, 0.35), rgba(40, 24, 16, 0.92) 78%);
    background:
        radial-gradient(circle at 35% 30%, color-mix(in srgb, var(--zone-color, var(--leaf)) 55%, transparent), rgba(40, 24, 16, 0.92) 78%);
    border: 2px solid rgba(20, 10, 6, 0.9);
    box-shadow: var(--chip-shadow);
    pointer-events: none;
    transition: background 0.9s ease;
    z-index: 2;
}

/* Touch mode also shows #touch-pause-btn at this same top-right corner
   (38px) — drop the compass below it so they never overlap. */
body.touch-mode #compass {
    top: calc(max(env(safe-area-inset-top), 14px) + 50px);
}

#compass-needle {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 3px;
    height: 20px;
    margin: -20px 0 0 -1.5px;
    border-radius: 2px 2px 0 0;
    background: linear-gradient(180deg, #fff3dd 0%, rgba(255, 243, 221, 0.1) 100%);
    transform-origin: 50% 100%;
    pointer-events: none;
    transition: transform 0.15s linear;
}

/* ---------- Off-screen legendary-creature indicator (item 416) ---------- */
#legendary-radar {
    position: fixed;
    left: 0;
    top: 0;
    width: 30px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    font-size: 18px;
    color: #ffd75e;
    text-shadow: 0 0 10px rgba(255, 215, 94, 0.85), 0 2px 2px rgba(20, 10, 6, 0.6);
    opacity: 0;
    pointer-events: none;
    z-index: 15;
    transition: opacity 0.3s ease;
}

/* ---------- Capture-ball cooldown radial wipe (item 414) ---------- */
#cooldown-wipe {
    position: absolute;
    right: 12%;
    bottom: 24%;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: conic-gradient(from -90deg, var(--amber-bright) calc(var(--wipe, 0) * 360deg), rgba(20, 10, 6, 0.55) 0);
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 4px));
    mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 4px));
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
    z-index: 3;
}

/* ---------- Accessibility & comfort panel (items 415/417/418/421/423/428) ---------- */
.a11y-panel {
    display: none;
    position: absolute;
    inset: 0;
    align-items: center;
    justify-content: center;
    padding: max(env(safe-area-inset-top), 20px) max(env(safe-area-inset-right), 20px)
             max(env(safe-area-inset-bottom), 20px) max(env(safe-area-inset-left), 20px);
    background:
        radial-gradient(120% 100% at 50% 20%, rgba(58, 32, 16, 0.14), rgba(24, 11, 6, 0.62) 90%),
        rgba(30, 15, 8, 0.42);
    -webkit-backdrop-filter: blur(7px) saturate(1.1);
    backdrop-filter: blur(7px) saturate(1.1);
    pointer-events: none;
    z-index: 50;
    outline: none;
}

.a11y-panel.visible {
    display: flex;
    pointer-events: auto;
}

.a11y-card {
    position: relative;
    width: min(90vw, 420px);
    max-height: 86vh;
    overflow-y: auto;
    padding: clamp(22px, 5vw, 34px);
    background: var(--paper-tex);
    border: 2px solid var(--ink-deep);
    border-radius: 22px;
    box-shadow: var(--card-shadow);
    color: var(--ink);
    animation: card-pop 0.4s cubic-bezier(0.2, 0.9, 0.3, 1.25) backwards;
}

.a11y-card h2 {
    font-family: var(--font-display);
    font-weight: 900;
    font-size: clamp(20px, 4vw, 26px);
    color: var(--ink-deep);
    margin-bottom: 16px;
    text-align: center;
}

.a11y-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 10px 0;
    border-bottom: 1px dashed rgba(93, 60, 35, 0.22);
}

.a11y-row:last-of-type {
    border-bottom: none;
}

.a11y-row label {
    font-size: clamp(13px, 2vw, 14.5px);
    font-weight: 700;
    color: var(--ink);
    flex: 1 1 auto;
}

/* Custom checkbox toggle — walnut track, amber-pill knob */
.a11y-row input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    flex: 0 0 auto;
    width: 42px;
    height: 24px;
    border-radius: 999px;
    background: rgba(53, 36, 26, 0.25);
    border: 2px solid var(--ink-deep);
    position: relative;
    cursor: pointer;
    transition: background 0.15s ease;
}

.a11y-row input[type="checkbox"]::before {
    content: "";
    position: absolute;
    left: 2px;
    top: 2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: linear-gradient(180deg, #fff4de, #ecd9b4);
    transition: transform 0.15s ease;
}

.a11y-row input[type="checkbox"]:checked {
    background: var(--leaf);
}

.a11y-row input[type="checkbox"]:checked::before {
    transform: translateX(18px);
}

.a11y-row-slider {
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
}

.a11y-row-slider label {
    flex: none;
}

.a11y-row-slider input[type="range"] {
    width: 100%;
    accent-color: var(--amber-deep);
}

/* item 395: shareable ?seed=N link row — same stacked layout as the sliders
   above, but the second line is a readonly URL field + copy button instead
   of a range input. */
.a11y-row-share {
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
}

.a11y-row-share label {
    flex: none;
}

.share-seed-controls {
    display: flex;
    gap: 8px;
}

.share-seed-controls input[type="text"] {
    flex: 1 1 auto;
    min-width: 0;
    padding: 8px 10px;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 600;
    color: var(--ink);
    background: rgba(255, 255, 255, 0.35);
    border: 2px solid var(--ink-deep);
    border-radius: 10px;
    text-overflow: ellipsis;
}

.share-seed-controls button {
    flex: 0 0 auto;
    padding: 8px 14px;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--ink-deep);
    background: linear-gradient(180deg, #ffc169, var(--amber) 55%, #e8922e);
    border: 2px solid var(--ink-deep);
    border-radius: 10px;
    box-shadow: 0 3px 0 var(--ink-deep);
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.share-seed-controls button:hover {
    transform: translateY(-1px);
}

.share-seed-controls button:active {
    transform: translateY(2px);
    box-shadow: 0 1px 0 var(--ink-deep);
}

#a11y-close-btn {
    display: block;
    width: 100%;
    margin-top: 20px;
    padding: 12px;
    font-family: var(--font-body);
    font-size: clamp(14px, 2.2vw, 16px);
    font-weight: 800;
    letter-spacing: 0.02em;
    color: var(--ink-deep);
    background: linear-gradient(180deg, #ffc169, var(--amber) 55%, #e8922e);
    border: 2px solid var(--ink-deep);
    border-radius: 14px;
    box-shadow: 0 4px 0 var(--ink-deep);
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.12s ease;
}

#a11y-close-btn:hover {
    transform: translateY(-1px);
}

#a11y-close-btn:active {
    transform: translateY(2px);
    box-shadow: 0 1px 0 var(--ink-deep);
}

/* ---------- High-contrast HUD mode (items 415/407) ---------- */
html.pref-high-contrast .hud-chip,
html.pref-high-contrast #counter,
html.pref-high-contrast #weather-badge {
    background: linear-gradient(180deg, #050505, #1a1008);
    border-color: #fff;
    border-width: 2px;
    color: #fff;
    text-shadow: none;
}

html.pref-high-contrast .hud-chip kbd {
    background: #fff;
    border-color: #000;
    color: #000;
}

html.pref-high-contrast #crosshair {
    border-color: #fff;
}

/* ---------- Manual reduced-motion toggle (item 418) ----------
   Mirrors the OS-level @media (prefers-reduced-motion: reduce) block
   below, but as an opt-in class so players can ask for it even when their
   OS-level setting is left alone. HUD-scoped: screen-shake/view-bob/bloom
   are 3D effects in engine.js/viewmodel.js/quality.js (out of this file's
   scope) — they'd need to read a shared flag (e.g. state.prefsReducedMotion)
   to fully honor this toggle too. */
html.pref-reduced-motion *,
html.pref-reduced-motion *::before,
html.pref-reduced-motion *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.15s !important;
}

html.pref-reduced-motion .confetti {
    display: none;
}

html.pref-reduced-motion .spinner::before {
    transform: translateY(12px);
}

/* ---------- Small screens ---------- */
@media (max-width: 560px) {
    .hud-corner {
        gap: 8px;
        max-width: min(80vw, 460px);
    }

    .ctp-scene .voxel {
        display: none;
    }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.15s !important;
    }

    .confetti {
        display: none;
    }

    .spinner::before {
        transform: translateY(12px);
    }
}
