:root {
    /* Shared corner radii — every panel/button/badge picks one of these two,
       instead of ad hoc per-element values. */
    --radius: 10px;
    --radius-pill: 999px;
    /* Room for notches and home indicators (viewport-fit=cover). */
    --safe-top: env(safe-area-inset-top, 0px);
    --safe-right: env(safe-area-inset-right, 0px);
    --safe-bottom: env(safe-area-inset-bottom, 0px);
    --safe-left: env(safe-area-inset-left, 0px);
}

/* Buttons don't inherit the page font by default. */
button {
    font-family: inherit;
}

[hidden] {
    display: none !important;
}

/* The page itself never scrolls, zooms or rubber-bands: on iOS a stray double
   tap or swipe used to shift it and push the HUD strip off screen. Menus
   scroll inside their own panels (.menu-page), not the page. */
html {
    height: 100%;
    overflow: hidden;
    overscroll-behavior: none;
}

body {
    position: fixed;
    inset: 0;
    margin: 0;
    overflow: hidden;
    overscroll-behavior: none;
    background: #050505;
    font-family: 'Orbitron', 'Courier New', monospace;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
    touch-action: none;
}

#game-container {
    position: relative;
    width: 100vw;
    height: 100vh;
    /* Mobile browsers' vh includes the area behind their toolbars. */
    height: 100dvh;
    display: flex;
    justify-content: center;
    align-items: center;
    background: #000;
    /* Where the HUD's corners are, as offsets in from the container's edges.
       Zero means the window corners. Renderer.resize() picks a data-layout
       and publishes the playfield's box (--pf-left/top/right/w/h), and the
       layouts below move the HUD onto it. */
    --hud-left: 0px;
    --hud-right: 0px;
    --hud-top: 0px;
    /* Height of the phone HUD strip, not counting the notch. */
    --hud-strip-h: 88px;
}

/* A 3:4 column too narrow to have the HUD beside it: the HUD sits in the
   column's own top corners. */
#game-container[data-layout="overlay"] {
    --hud-left: var(--pf-left, 0px);
    --hud-right: var(--pf-right, 0px);
    --hud-top: var(--pf-top, 0px);
}

/* Phones: the playfield runs from under the HUD strip to the bottom edge
   (under the home indicator too). */
#game-container[data-layout="strip"] {
    align-items: flex-end;
}

canvas {
    background: #080808;
    /* A frame that takes no layout space (a border would push the canvas
       past its fitted size). */
    box-shadow: 0 0 0 1px #2a2a2a, 0 0 60px #000;
    max-width: 100%;
    max-height: 100%;
}

#game-container[data-layout="strip"] canvas {
    box-shadow: none;
}

#hud-strip {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: calc(var(--hud-strip-h) + var(--safe-top));
    background: #000;
    pointer-events: none;
    /* Always laid out so the Renderer can measure it, only shown on phones. */
    visibility: hidden;
}

#game-container[data-layout="strip"] #hud-strip {
    visibility: visible;
}

/* ---------- Themed sides ----------
   Around the 3:4 column (flank and overlay layouts), the window takes on the
   current biome: its background colour, a soft glow in its platform colour,
   a still star field and a vignette, and a glowing edge on the column.
   Renderer.themeSides() sets the three colours when the biome changes;
   registering them lets the CSS cross-fade between biomes. */
@property --biome-bg {
    syntax: '<color>';
    inherits: true;
    initial-value: #050505;
}

@property --biome-glow {
    syntax: '<color>';
    inherits: true;
    initial-value: rgba(0, 255, 204, 0.09);
}

@property --biome-edge {
    syntax: '<color>';
    inherits: true;
    initial-value: rgba(0, 255, 204, 0.35);
}

#game-container:not([data-layout="strip"]) {
    /* A stacking context, so the star layer below can sit behind the canvas. */
    isolation: isolate;
    background:
        radial-gradient(ellipse 70% 90% at 50% 45%, var(--biome-glow), transparent 70%),
        var(--biome-bg);
    transition: --biome-bg 1.5s ease, --biome-glow 1.5s ease, --biome-edge 1.5s ease;
}

#game-container:not([data-layout="strip"])::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(ellipse at center, transparent 45%, rgba(0, 0, 0, 0.65) 100%),
        radial-gradient(1px 1px at 12% 18%, rgba(255, 255, 255, 0.45), transparent) 0 0 / 230px 230px,
        radial-gradient(1px 1px at 68% 42%, rgba(255, 255, 255, 0.3), transparent) 0 0 / 230px 230px,
        radial-gradient(1.5px 1.5px at 33% 77%, rgba(255, 255, 255, 0.35), transparent) 0 0 / 310px 310px,
        radial-gradient(1px 1px at 86% 64%, rgba(255, 255, 255, 0.25), transparent) 0 0 / 310px 310px,
        radial-gradient(1px 1px at 51% 9%, rgba(255, 255, 255, 0.3), transparent) 0 0 / 170px 170px;
}

#game-container:not([data-layout="strip"]) canvas {
    box-shadow: 0 0 0 1px var(--biome-edge), 0 0 50px var(--biome-glow), 0 0 90px #000;
}

@media (prefers-reduced-motion: reduce) {
    #game-container {
        transition: none;
    }
}

/* UI LAYOUT - Absolute positioning relative to the container */
#ui-layer {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
}

/* HUD */
#hud {
    position: relative;
    width: 100%;
    height: 100px;
    box-sizing: border-box;
    opacity: 0;
    transition: opacity 0.5s;
    z-index: 10;
}

#score-display {
    position: absolute;
    top: calc(var(--hud-top) + 20px + var(--safe-top));
    left: calc(var(--hud-left) + 20px + var(--safe-left));
    white-space: nowrap;
    font-size: clamp(26px, 8vw, 50px);
    font-weight: 900;
    color: #fff;
    text-shadow: 0 0 15px rgba(255, 255, 255, 0.5);
    letter-spacing: -2px;
}

#best-display-hud {
    position: absolute;
    top: calc(var(--hud-top) + 20px + var(--safe-top));
    left: 50%;
    transform: translateX(-50%);
    white-space: nowrap;
    font-size: clamp(16px, 4.5vw, 28px);
    color: #ff3366;
    text-shadow: 0 0 10px rgba(255, 51, 102, 0.6);
    font-weight: bold;
    text-align: center;
}

#gem-display {
    position: absolute;
    top: calc(var(--hud-top) + 8px + var(--safe-top));
    right: calc(var(--hud-right) + 8px + var(--safe-right));
    white-space: nowrap;
    font-size: clamp(20px, 6.5vw, 40px);
    line-height: 1;
    color: #00ffff;
    font-weight: bold;
    text-shadow: 0 0 15px rgba(0, 255, 255, 0.6);
    transform-origin: center;
    /* Persistent across every screen (menu/shop/gameplay), so it must sit
       above #menus-wrapper (20), #shop-menu-layer (25) and .nav-btn /
       .mode-switch-arrow (30). */
    z-index: 40;
}

@keyframes gem-collect-pop {
    0% {
        transform: scale(1);
        text-shadow: 0 0 15px rgba(0, 255, 255, 0.6);
    }

    40% {
        transform: scale(1.35);
        text-shadow: 0 0 28px rgba(0, 255, 255, 1), 0 0 40px rgba(150, 255, 255, 0.8);
    }

    100% {
        transform: scale(1);
        text-shadow: 0 0 15px rgba(0, 255, 255, 0.6);
    }
}

#gem-display.gem-pop {
    animation: gem-collect-pop 0.35s ease-out;
}

/* Banked hearts, right under the gem counter (and just as persistent).
   Dimmed at zero: that's when heart pickups show up in the level. */
#life-display {
    position: absolute;
    top: calc(var(--hud-top) + 8px + clamp(20px, 6.5vw, 40px) + 6px + var(--safe-top));
    right: calc(var(--hud-right) + 8px + var(--safe-right));
    white-space: nowrap;
    font-size: clamp(20px, 6.5vw, 40px);
    line-height: 1;
    color: #ff3366;
    font-weight: bold;
    text-shadow: 0 0 12px rgba(255, 51, 102, 0.6);
    z-index: 40;
    transition: opacity 0.2s;
}

#life-display.empty {
    opacity: 0.4;
}

@keyframes life-pop {
    0% { transform: scale(1); }
    40% { transform: scale(1.35); }
    100% { transform: scale(1); }
}

#life-display.life-pop {
    animation: life-pop 0.35s ease-out;
}

/* Narrow screens: three numbers don't fit on one row, so BEST tucks under
   the score. */
@media (max-width: 480px) {
    #best-display-hud {
        top: calc(var(--hud-top) + 62px + var(--safe-top));
        left: calc(var(--hud-left) + 20px + var(--safe-left));
        transform: none;
        font-size: 14px;
        text-align: left;
    }

    #score-display {
        font-size: clamp(24px, 7.5vw, 34px);
    }

    #gem-display {
        font-size: clamp(18px, 6vw, 28px);
    }

    #life-display {
        top: calc(var(--hud-top) + 8px + clamp(18px, 6vw, 28px) + 6px + var(--safe-top));
        font-size: clamp(18px, 6vw, 28px);
    }

    .hud-btn {
        top: calc(var(--hud-top) + 78px + var(--safe-top));
    }

    #system-alert {
        padding: 8px 14px;
        gap: 8px;
        font-size: 13px;
        letter-spacing: 0.3px;
    }
}

/* Phones (the strip layout): the numbers live in the black HUD strip above
   the playfield. Score with BEST under it on the left, gems over hearts on
   the right, pause in the middle. Run-time pills (power-up bar, target,
   spectating, alerts) pin to the top of the playfield instead. */
#game-container[data-layout="strip"] #hud {
    height: calc(var(--hud-strip-h) + var(--safe-top));
}

#game-container[data-layout="strip"] #score-display {
    top: calc(10px + var(--safe-top));
    left: calc(16px + var(--safe-left));
    font-size: clamp(26px, 8.5vw, 38px);
}

#game-container[data-layout="strip"] #best-display-hud {
    top: calc(56px + var(--safe-top));
    left: calc(16px + var(--safe-left));
    transform: none;
    font-size: 14px;
    text-align: left;
}

#game-container[data-layout="strip"] #gem-display,
#game-container[data-layout="strip"] #life-display {
    right: calc(16px + var(--safe-right));
    font-size: 26px;
}

#game-container[data-layout="strip"] #gem-display {
    top: calc(12px + var(--safe-top));
}

#game-container[data-layout="strip"] #life-display {
    top: calc(48px + var(--safe-top));
}

#game-container[data-layout="strip"] .hud-btn {
    top: calc((var(--hud-strip-h) - 40px) / 2 + var(--safe-top));
    right: auto;
    left: 50%;
    transform: translateX(-50%);
}

#game-container[data-layout="strip"] #system-alert {
    margin-top: 10px;
}

#game-container[data-layout="strip"] #power-hud {
    top: calc(var(--pf-top, 0px) + 56px);
}

#game-container[data-layout="strip"] #challenge-hud,
#game-container[data-layout="strip"] #spectate-hud {
    top: calc(var(--pf-top, 0px) + 12px);
}

/* Wide windows (the flank layout): the HUD sits beside the column instead of
   in the window corners. Score and BEST are against its left edge; gems,
   hearts and pause are against its right. Sizes follow the gutter, so the
   numbers fit however narrow it gets. This block is its own commit:
   reverting it puts the HUD back in the window corners. */
#game-container[data-layout="flank"] {
    --flank-gap: 24px;
    --flank-num: min(50px, calc(var(--pf-left, 350px) / 7));
    --flank-count: min(40px, calc(var(--pf-left, 350px) / 8));
}

#game-container[data-layout="flank"] #score-display,
#game-container[data-layout="flank"] #best-display-hud {
    left: auto;
    right: calc(var(--pf-right, 0px) + var(--pf-w, 0px) + var(--flank-gap));
    transform: none;
    text-align: right;
}

#game-container[data-layout="flank"] #score-display {
    top: calc(var(--pf-top, 0px) + 16px + var(--safe-top));
    font-size: var(--flank-num);
}

#game-container[data-layout="flank"] #best-display-hud {
    top: calc(var(--pf-top, 0px) + 28px + var(--flank-num) + var(--safe-top));
    font-size: min(24px, calc(var(--pf-left, 350px) / 14));
}

#game-container[data-layout="flank"] #gem-display,
#game-container[data-layout="flank"] #life-display,
#game-container[data-layout="flank"] .hud-btn {
    right: auto;
    left: calc(var(--pf-left, 0px) + var(--pf-w, 0px) + var(--flank-gap));
}

#game-container[data-layout="flank"] #gem-display,
#game-container[data-layout="flank"] #life-display {
    font-size: var(--flank-count);
}

#game-container[data-layout="flank"] #gem-display {
    top: calc(var(--pf-top, 0px) + 20px + var(--safe-top));
}

#game-container[data-layout="flank"] #life-display {
    top: calc(var(--pf-top, 0px) + 30px + var(--flank-count) + var(--safe-top));
}

#game-container[data-layout="flank"] .hud-btn {
    top: calc(var(--pf-top, 0px) + 44px + 2 * var(--flank-count) + var(--safe-top));
}

/* POWER UP HUD */
#power-hud {
    position: absolute;
    top: calc(var(--hud-top) + 80px + var(--safe-top));
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    opacity: 0;
    transition: opacity 0.2s;
    z-index: 10;
}

#power-text {
    font-size: 18px;
    font-weight: bold;
    margin-bottom: 5px;
    text-shadow: 0 0 8px #000;
    color: #fff;
}

#power-bar-bg {
    width: 200px;
    height: 10px;
    background: #222;
    border: 1px solid #fff;
    border-radius: var(--radius-pill);
    overflow: hidden;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}

#power-bar-fill {
    height: 100%;
    width: 100%;
    background: #fff;
    transition: width 0.1s linear, background-color 0.2s;
}

/* SYSTEM ALERT - centralized notification for status/revive/reward messages */
#system-alert {
    display: flex;
    align-items: center;
    gap: 10px;
    background: rgba(10, 10, 14, 0.85);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    border: 1px solid rgba(0, 204, 255, 0.35);
    border-left: 4px solid #00ccff;
    border-radius: var(--radius);
    padding: 10px 22px;
    /* Below the HUD row (and the notch), and never wide enough to reach the
       pause button in the top-right corner. */
    margin-top: calc(var(--hud-top) + 20px + var(--safe-top));
    font-weight: bold;
    font-size: 15px;
    width: fit-content;
    max-width: min(500px, calc(100% - 2 * (60px + max(var(--safe-left), var(--safe-right)))));
    box-sizing: border-box;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-align: center;
    color: #00ccff;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 16px rgba(0, 204, 255, 0.15);
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity 0.35s ease, transform 0.35s ease, border-color 0.3s, color 0.3s, box-shadow 0.3s;
}

#system-alert.alert-visible {
    opacity: 1;
    transform: translateY(0);
}

#system-alert-icon {
    font-size: 17px;
    line-height: 1;
    flex-shrink: 0;
}

/* Two eyes on a DOM-drawn Pixel (skin picker, gem shop, unlock notices),
   placed like drawPixel() places them on the canvas. */
.pixel-eye {
    position: absolute;
    top: 30%;
    width: 20%;
    height: 20%;
    background: white;
}

.pixel-eye-l {
    left: 20%;
}

.pixel-eye-r {
    right: 20%;
}

/* A tiny Pixel in place of the icon (unlock notices). The faint outline keeps
   near-black Pixels (The Void, The End) visible on the dark alert. */
.alert-pixel {
    display: block;
    position: relative;
    width: 18px;
    height: 18px;
    border-radius: 8%; /* PIXEL_CORNER_RADIUS / 26, like the in-game Pixel */
    outline: 1px solid rgba(255, 255, 255, 0.35);
}

#system-alert.alert-unlock .alert-pixel {
    box-shadow: 0 0 8px rgba(255, 215, 0, 0.5);
}

/* Type variants */
#system-alert.alert-success {
    border-color: rgba(0, 255, 170, 0.4);
    border-left-color: #00ffaa;
    color: #00ffaa;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 16px rgba(0, 255, 170, 0.2);
}

#system-alert.alert-warning {
    border-color: rgba(255, 170, 0, 0.4);
    border-left-color: #ffaa00;
    color: #ffaa00;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 16px rgba(255, 170, 0, 0.2);
}

#system-alert.alert-danger {
    border-color: rgba(255, 51, 102, 0.4);
    border-left-color: #ff3366;
    color: #ff5c85;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 16px rgba(255, 51, 102, 0.2);
}

#system-alert.alert-reward {
    border-color: rgba(255, 215, 0, 0.45);
    border-left-color: #ffd700;
    color: #ffd700;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 18px rgba(255, 215, 0, 0.25);
}

/* A newly unlocked Pixel */
#system-alert.alert-unlock {
    border-color: rgba(255, 215, 0, 0.45);
    border-left-color: #ffd700;
    color: #ffe766;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 18px rgba(255, 215, 0, 0.3);
}

/* A life was spent or a heart picked up */
#system-alert.alert-life,
#system-alert.alert-heart {
    border-color: rgba(255, 51, 102, 0.4);
    border-left-color: #ff3366;
    color: #ff5c85;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 16px rgba(255, 51, 102, 0.2);
}

/* Urgent, attention-grabbing pulse (co-op respawn countdown) */
#system-alert.alert-pulse {
    border-color: rgba(192, 77, 255, 0.5);
    border-left-color: #c04dff;
    color: #d896ff;
    font-size: 18px;
    text-shadow: 0 0 8px #c04dff, 0 0 18px #a020f0;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 20px rgba(192, 77, 255, 0.3);
}

/* Only animate while actually shown, so hiding it doesn't get fought by the keyframe's own opacity */
#system-alert.alert-pulse.alert-visible {
    animation: alertPulse 0.9s ease-in-out infinite;
}

@keyframes alertPulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.6; }
}

/* MENU SYSTEM - Slide transition */
#menus-wrapper {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    z-index: 20;
    pointer-events: none;
}

.menu-page {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    padding: calc(12px + var(--safe-top)) calc(12px + var(--safe-right)) calc(12px + var(--safe-bottom)) calc(12px + var(--safe-left));
    display: flex;
    flex-direction: column;
    /* Centred when the content fits, scrollable (from the top) when it
       doesn't: the grow-able ::before/::after spacers do the centring and
       shrink to nothing on overflow, where justify-content: center would
       clip the top out of reach. */
    justify-content: flex-start;
    align-items: center;
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: pan-y;
    background: rgba(5, 5, 5, 0.95);
    transition: transform 0.4s ease-in-out, opacity 0.3s;
    pointer-events: auto;
    /* Each page is its own stacking context, so a high z-index button on one
       page (e.g. .nav-btn / .mode-switch-arrow at 30) can never bleed on top
       of a sibling page regardless of that page's own z-index. */
    isolation: isolate;
}

.menu-page::before,
.menu-page::after {
    content: "";
    flex: 1 0 0;
}

#mp-menu-layer {
    transform: translateX(100%);
    background: rgba(5, 10, 20, 0.95);
}

/* Shop slides up on its own (vertical) axis so it can't collide with the
   SP<->MP horizontal slide — it opens as an overlay on top of the SP menu. */
#shop-menu-layer {
    transform: translateY(100%);
    /* Fully opaque (unlike the other .menu-page backgrounds) — this one
       overlays the SP menu in place rather than sliding apart from it, so
       any transparency here would let the menu underneath ghost through. */
    background: #0a0710;
    z-index: 25;
    padding-top: calc(30px + var(--safe-top));
}

.mode-switch-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    padding: 6px;
    font-size: 40px;
    line-height: 1;
    color: #8a8a8a;
    cursor: pointer;
    text-align: center;
    transition: color 0.2s, transform 0.2s;
    user-select: none;
    z-index: 30;
}

.mode-switch-label {
    font-size: 12px;
    display: block;
    margin-top: 5px;
    font-weight: bold;
}

.mode-switch-arrow.right { right: calc(20px + var(--safe-right)); }
.mode-switch-arrow.left { left: calc(20px + var(--safe-left)); }

@media (hover: hover) {
    .mode-switch-arrow:hover {
        color: #00ffff;
        transform: translateY(-50%) scale(1.1);
    }
}

/* The way into co-op is a glowing magenta card (the shop is cyan), with a
   slow pulse so it reads as a button rather than a hint. The way back to
   solo gets the same card, without the pulse. */
#to-mp-btn,
#to-sp-btn {
    --mode-rgb: 255, 0, 255;
    color: rgb(var(--mode-rgb));
    border: 2px solid rgb(var(--mode-rgb));
    border-radius: var(--radius);
    background: rgba(var(--mode-rgb), 0.1);
    box-shadow: 0 0 12px rgba(var(--mode-rgb), 0.35);
    text-shadow: 0 0 8px rgba(var(--mode-rgb), 0.6);
    padding: 10px 10px 8px;
    font-size: 30px;
}

#to-sp-btn {
    --mode-rgb: 0, 255, 255;
}

#to-mp-btn .mode-switch-label,
#to-sp-btn .mode-switch-label {
    font-size: 13px;
    letter-spacing: 1px;
}

#to-mp-btn {
    animation: mode-pulse 2.4s ease-in-out infinite;
}

@keyframes mode-pulse {
    0%, 100% { box-shadow: 0 0 12px rgba(var(--mode-rgb), 0.35); }
    50% { box-shadow: 0 0 26px rgba(var(--mode-rgb), 0.9); }
}

@media (hover: hover) {
    #to-mp-btn:hover,
    #to-sp-btn:hover {
        color: #fff;
        background: rgba(var(--mode-rgb), 0.25);
    }
}

@media (prefers-reduced-motion: reduce) {
    #to-mp-btn { animation: none; }
}

/* Phones: the side arrows would sit on top of the cards, so they move down
   to the bottom corners. */
@media (max-width: 520px) {
    .mode-switch-arrow {
        top: auto;
        bottom: calc(12px + var(--safe-bottom));
        transform: none;
        font-size: 26px;
    }

    .mode-switch-label {
        font-size: 10px;
    }

    #to-mp-btn,
    #to-sp-btn {
        display: flex;
        align-items: center;
        gap: 6px;
        padding: 8px 12px;
        font-size: 20px;
    }

    #to-mp-btn .mode-switch-label,
    #to-sp-btn .mode-switch-label {
        margin-top: 0;
        font-size: 12px;
    }

    /* Arrow on the outside edge, pointing the way. */
    #to-mp-btn { flex-direction: row-reverse; }
}

/* MP UI Styles — built from the same card / button / section-label pieces as
   the shop, so co-op reads as part of the same menu family. Each card sets
   --accent (and --accent-rgb for the tints); everything else keys off it. */
.mp-box {
    --accent: #00ffff;
    --accent-rgb: 0, 255, 255;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid #333;
    border-radius: var(--radius);
    padding: 16px 18px;
    margin-bottom: 12px;
    width: min(320px, 85vw);
    box-sizing: border-box;
    text-align: center;
}

.mp-box--join {
    --accent: #ffaa00;
    --accent-rgb: 255, 170, 0;
}

.mp-box--host {
    --accent: #00ffaa;
    --accent-rgb: 0, 255, 170;
}

/* Same tinted-panel treatment as .shop-card, in the card's own accent. */
.mp-box--join,
.mp-box--host {
    background: linear-gradient(160deg, rgba(var(--accent-rgb), 0.1), rgba(255, 255, 255, 0.03));
    border-color: rgba(var(--accent-rgb), 0.4);
    box-shadow: 0 0 22px rgba(var(--accent-rgb), 0.1);
}

.mp-box label,
.mp-box-title {
    display: block;
    color: #fff;
    font-size: 15px;
    font-weight: 900;
    letter-spacing: 2px;
    margin-bottom: 10px;
}

.mp-box--join label,
.mp-box--host .mp-box-title {
    color: var(--accent);
    text-shadow: 0 0 12px rgba(var(--accent-rgb), 0.45);
}

.mp-box input[type="text"] {
    width: 100%;
    background: rgba(0, 0, 0, 0.6);
    border: 1px solid #444;
    border-radius: var(--radius);
    color: #fff;
    padding: 10px;
    font-family: inherit;
    font-size: 16px;
    font-weight: bold;
    letter-spacing: 2px;
    text-align: center;
    text-transform: uppercase;
    box-sizing: border-box;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.mp-box input[type="text"]::placeholder {
    color: #7a7a7a;
}

.mp-box input[type="text"]:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 12px rgba(var(--accent-rgb), 0.3);
}

/* Solid primary action, matching .shop-card-btn / .gem-skin-buy-btn. */
.mp-box button {
    width: 100%;
    margin-top: 10px;
    background: var(--accent);
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    color: #0a0a0a;
    padding: 11px 15px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 900;
    letter-spacing: 1px;
    cursor: pointer;
    transition: 0.2s;
}

@media (hover: hover) {
    .mp-box button:hover:not(:disabled) {
        filter: brightness(1.15);
        box-shadow: 0 0 18px rgba(var(--accent-rgb), 0.5);
    }
}

/* In flight (connecting / code already generated): ghosted like the shop's
   unaffordable state, so it plainly can't be pressed again. */
.mp-box button:disabled {
    background: transparent;
    color: var(--accent);
    border-color: rgba(var(--accent-rgb), 0.35);
    opacity: 0.6;
    cursor: default;
}

/* ---- Lobby setup <-> party view ----
   Hosting or joining adds .in-party to #mp-menu-layer: the setup cards
   evaporate (fade, blur, lift, collapse) and the party panel rises in. */
.mp-setup {
    display: flex;
    flex-direction: column;
    align-items: center;
    max-height: 600px;
    transition: opacity 0.45s ease, filter 0.45s ease, transform 0.45s ease,
        max-height 0.5s ease 0.15s;
}

#mp-menu-layer.in-party .mp-setup {
    opacity: 0;
    filter: blur(8px);
    transform: translateY(-16px) scale(0.94);
    max-height: 0;
    overflow: hidden;
    pointer-events: none;
}

.mp-party-view {
    display: none;
    flex-direction: column;
    align-items: center;
}

#mp-menu-layer.in-party .mp-party-view {
    display: flex;
    animation: mp-party-in 0.5s ease 0.2s both;
}

@keyframes mp-party-in {
    from {
        opacity: 0;
        filter: blur(4px);
        transform: translateY(14px) scale(0.97);
    }

    to {
        opacity: 1;
        filter: none;
        transform: none;
    }
}

.mp-box--party {
    --accent: #00ffff;
    --accent-rgb: 0, 255, 255;
}

/* The leave "panel" is just its button, drawn as a tinted card. */
.mp-box--leave {
    --accent: #ff3366;
    --accent-rgb: 255, 51, 102;
    padding: 0;
    border: none;
    background: none;
}

.mp-box--party,
.mp-box--leave button {
    background: linear-gradient(160deg, rgba(var(--accent-rgb), 0.1), rgba(255, 255, 255, 0.03));
    border-color: rgba(var(--accent-rgb), 0.4);
    box-shadow: 0 0 22px rgba(var(--accent-rgb), 0.1);
}

.mp-box--party .mp-box-title {
    color: var(--accent);
    text-shadow: 0 0 12px rgba(var(--accent-rgb), 0.45);
}

/* Outlined rather than solid — leaving is the secondary action. */
.mp-box--leave button {
    margin-top: 0;
    padding: 14px 15px;
    color: var(--accent);
}

#mp-party-count {
    color: #888;
    font-size: 12px;
    margin-left: 6px;
    text-shadow: none;
}

/* Room code, so anyone in the party can keep sharing it. */
.mp-party-code {
    /* letter-spacing trails the last glyph; the extra left padding evens it. */
    padding: 6px 0 6px 8px;
    margin-bottom: 4px;
    border: 1px solid rgba(var(--accent-rgb), 0.5);
    border-radius: var(--radius);
    background: rgba(0, 0, 0, 0.4);
    color: var(--accent);
    font-size: 22px;
    font-weight: 900;
    letter-spacing: 8px;
    text-shadow: 0 0 14px rgba(var(--accent-rgb), 0.6);
    user-select: text;
    -webkit-user-select: text;
}

.mp-party-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Each row sets --slot to that player's in-game name-tag colour. */
.mp-party-row {
    --slot: #555;
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 6px;
    padding: 8px 10px;
    border: 1px solid #2a2a2a;
    border-left: 3px solid var(--slot);
    border-radius: var(--radius);
    background: rgba(0, 0, 0, 0.35);
    color: #fff;
    font-size: 14px;
    font-weight: bold;
    letter-spacing: 1px;
    text-align: left;
}

.mp-party-row.is-leader {
    margin-top: 10px;
    padding: 11px 12px;
    font-size: 16px;
    border-color: rgba(255, 215, 0, 0.35);
    border-left-color: var(--slot);
    background: linear-gradient(90deg, rgba(255, 215, 0, 0.1), rgba(0, 0, 0, 0.35));
}

/* Separate the leader from the members listed under them. */
.mp-party-row.is-leader + .mp-party-row {
    margin-top: 12px;
}

.mp-party-chip {
    flex: none;
    width: 14px;
    height: 14px;
    box-sizing: border-box;
    background: var(--slot);
    box-shadow: 0 0 8px var(--slot);
}

.mp-party-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mp-party-tag {
    flex: none;
    font-size: 10px;
    letter-spacing: 1px;
    color: #888;
}

.mp-party-row.is-leader .mp-party-tag {
    color: #ffd700;
    text-shadow: 0 0 8px rgba(255, 215, 0, 0.5);
}

.mp-party-row.is-empty {
    border-style: dashed;
    background: transparent;
    color: #8a8a8a;
    font-size: 12px;
}

.mp-party-row.is-empty .mp-party-chip {
    background: transparent;
    border: 1px dashed #444;
    box-shadow: none;
}

/* Connection status — a pill in the #system-alert palette. app.js sets
   data-state; no state means idle. */
#mp-status {
    --status: #888;
    --status-rgb: 136, 136, 136;
    margin-top: 4px;
    padding: 6px 16px;
    max-width: min(320px, 85vw);
    box-sizing: border-box;
    border: 1px solid rgba(var(--status-rgb), 0.4);
    border-radius: var(--radius-pill);
    background: rgba(var(--status-rgb), 0.08);
    color: var(--status);
    font-size: 12px;
    font-weight: bold;
    letter-spacing: 1px;
    text-align: center;
    transition: color 0.3s, border-color 0.3s, background 0.3s;
}

#mp-status[data-state="pending"] {
    --status: #ffaa00;
    --status-rgb: 255, 170, 0;
}

#mp-status[data-state="success"] {
    --status: #00ffaa;
    --status-rgb: 0, 255, 170;
}

#mp-status[data-state="danger"] {
    --status: #ff5c85;
    --status-rgb: 255, 51, 102;
}

/* Like the main menu, this page is one non-scrolling column: on short
   viewports tighten the cards so the host's start button stays on screen. */
@media (max-height: 760px) {
    .mp-box {
        padding: 10px 14px;
        margin-bottom: 8px;
    }

    .mp-box label,
    .mp-box-title {
        font-size: 13px;
        margin-bottom: 6px;
    }

    .mp-box input[type="text"] {
        padding: 8px;
        font-size: 14px;
    }

    .mp-box button {
        margin-top: 6px;
        padding: 8px 12px;
    }

    .mp-party-code {
        padding: 4px 0 4px 8px;
        font-size: 20px;
    }

    .mp-party-row {
        padding: 6px 10px;
    }

    .mp-party-row.is-leader {
        padding: 8px 12px;
    }
}

.page-title {
    font-family: 'Orbitron', 'Courier New', monospace;
    font-size: clamp(28px, 9vw, 56px);
    color: #fff;
    letter-spacing: clamp(1px, 0.8vw, 4px);
    margin-bottom: 20px;
    text-shadow: 0 0 14px #a020f0, 0 0 28px #c04dff;
    font-weight: 900;
    text-align: center;
}

.page-title--mp {
    text-shadow: 0 0 14px #00ccff, 0 0 28px #00ffff;
}

.page-title--shop {
    text-shadow: 0 0 14px #00ffaa, 0 0 28px #00ffaa;
    margin-bottom: 4px;
    /* Paired with the auto margin on #gem-shop-dots (the last child): the shop
       contents sit centered when they fit and fall back to top-aligned when
       they overflow, since auto margins resolve to 0 with no free space —
       unlike `justify-content: center`, which would clip the top on overflow. */
    margin-top: auto;
}

/* SKIN SELECTOR */
#skin-container {
    display: flex;
    align-items: center;
    margin-bottom: 20px;
    background: rgba(255, 255, 255, 0.05);
    padding: 20px;
    max-width: 100%;
    box-sizing: border-box;
    border-radius: var(--radius);
    border: 1px solid #333;
    cursor: default;
}

.nav-btn {
    background: none;
    border: 1px solid #555;
    border-radius: var(--radius);
    color: #fff;
    font-size: 20px;
    cursor: pointer;
    padding: 10px 20px;
    transition: 0.2s;
    pointer-events: auto;
    z-index: 30;
    user-select: none;
}

@media (hover: hover) {
    .nav-btn:hover {
        background: #333;
        border-color: #fff;
    }
}

.nav-btn:active {
    background: #555;
}

#skin-display {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 200px;
}

/* Phones: the pickers (menu and shop) must fit inside the screen. */
@media (max-width: 400px) {
    #skin-container,
    #gem-shop-carousel {
        padding: 14px 10px;
    }

    .nav-btn {
        padding: 10px 12px;
    }

    #skin-display,
    #gem-skin-shop {
        width: min(200px, calc(100vw - 150px));
    }
}

#skin-preview-box {
    width: 50px;
    height: 50px;
    border-radius: 8%; /* PIXEL_CORNER_RADIUS / 26, like the in-game Pixel */
    margin-bottom: 10px;
    position: relative;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
    transition: transform 0.2s;
}

#skin-name {
    font-size: 18px;
    color: #fff;
    font-weight: bold;
    margin-bottom: 5px;
}

#skin-status {
    font-size: 12px;
    color: #888;
    letter-spacing: 1px;
}

#skin-ability {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    margin-top: 8px;
    min-height: 20px;
}

/* PERK TAGS — one short chip per perk in the perk's own colour (--perk, set
   inline from PERKS). The full stat text sits in .perk-tip, shown on hover or
   when a tap toggles .open (see Game.bindEvents). Shared by menu and shop. */
.perk-tag {
    position: relative;
    display: inline-block;
    padding: 3px 7px;
    border: 1px solid var(--perk);
    color: var(--perk);
    background: color-mix(in srgb, var(--perk) 12%, transparent);
    font-size: 10px;
    font-weight: bold;
    letter-spacing: 1px;
    line-height: 1.2;
    cursor: help;
    pointer-events: auto;
    user-select: none;
    outline: none;
}

.perk-tag:focus-visible,
.perk-tag.open {
    background: color-mix(in srgb, var(--perk) 25%, transparent);
    box-shadow: 0 0 10px color-mix(in srgb, var(--perk) 50%, transparent);
}

.perk-tip {
    display: none;
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    width: max-content;
    max-width: 180px;
    padding: 6px 9px;
    background: #0b0b0b;
    border: 1px solid var(--perk);
    color: #fff;
    font-size: 11px;
    /* Only Orbitron 700/900 are loaded; say so rather than ask for a weight
       the browser would substitute anyway. */
    font-weight: 700;
    letter-spacing: 0.3px;
    line-height: 1.35;
    text-align: center;
    white-space: normal;
    z-index: 50;
    pointer-events: none;
}

.perk-tip::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: var(--perk);
}

.perk-tag:focus-visible .perk-tip,
.perk-tag.open .perk-tip {
    display: block;
}

/* Touch has no hover, and a tapped element keeps a "sticky" :hover, so the
   hover tooltip is for real pointers only (taps toggle .open instead). */
@media (hover: hover) {
    .perk-tag:hover {
        background: color-mix(in srgb, var(--perk) 25%, transparent);
        box-shadow: 0 0 10px color-mix(in srgb, var(--perk) 50%, transparent);
    }

    .perk-tag:hover .perk-tip {
        display: block;
    }
}

.perk-none {
    font-size: 10px;
    color: #8a8a8a;
    letter-spacing: 1px;
}

/* SHOP TRIGGER (main menu) */
.shop-trigger-btn {
    display: flex;
    align-items: center;
    gap: 12px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid #333;
    border-radius: var(--radius);
    color: #fff;
    font-weight: bold;
    padding: 10px 18px;
    margin-bottom: 15px;
    cursor: pointer;
    transition: 0.2s;
}

@media (hover: hover) {
    .shop-trigger-btn:hover {
        border-color: #00ffaa;
        background: rgba(0, 255, 170, 0.08);
    }
}

/* SHOP SCREEN */
.shop-back-btn {
    position: absolute;
    top: 20px;
    left: 20px;
    background: none;
    border: 1px solid #555;
    border-radius: var(--radius);
    color: #fff;
    font-weight: bold;
    font-size: 13px;
    padding: 8px 16px;
    cursor: pointer;
    transition: 0.2s;
    z-index: 1;
}

@media (hover: hover) {
    .shop-back-btn:hover {
        border-color: #00ffaa;
        color: #00ffaa;
    }
}

/* Phones: BACK gets its own row instead of overlapping the SHOP title. */
@media (max-width: 520px) {
    .shop-back-btn {
        position: static;
        align-self: flex-start;
        margin-bottom: 6px;
    }
}

/* Section headers inside the shop — quiet rules that separate the
   consumables block from the pixel carousel without competing with either. */
.shop-section-label {
    width: min(320px, 85vw);
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 18px 0 10px;
    color: #8c8c8c;
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 3px;
}

.shop-section-label::after {
    content: "";
    flex: 1;
    height: 1px;
    background: linear-gradient(to right, #333, transparent);
}

/* CONSUMABLES CARD (heart) */
.shop-card {
    position: relative;
    background: linear-gradient(160deg, rgba(255, 51, 102, 0.12), rgba(255, 255, 255, 0.03));
    border: 1px solid rgba(255, 51, 102, 0.45);
    border-radius: var(--radius);
    box-shadow: 0 0 22px rgba(255, 51, 102, 0.12);
    padding: 18px;
    width: min(320px, 85vw);
    box-sizing: border-box;
    text-align: center;
}

.shop-card-icon {
    font-size: 26px;
    line-height: 1;
    color: #ff3366;
    text-shadow: 0 0 14px rgba(255, 51, 102, 0.8);
    margin-bottom: 8px;
}

.shop-card-title {
    color: #fff;
    font-weight: 900;
    font-size: 17px;
    letter-spacing: 2px;
    margin-bottom: 6px;
}

.shop-card-desc {
    color: #999;
    font-size: 12px;
    line-height: 1.5;
    margin-bottom: 12px;
}

.shop-card-stock {
    color: #ff7799;
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 2px;
    margin-bottom: 12px;
}

.shop-card-stock span {
    color: #fff;
    font-size: 14px;
}

/* Solid fill rather than a thin outline: this is the screen's primary action
   and the old ghost button read as decoration against the dark panel. */
.shop-card-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    background: #ff3366;
    border: 1px solid #ff3366;
    border-radius: var(--radius);
    color: #12000a;
    padding: 12px 15px;
    font-weight: 900;
    font-size: 13px;
    letter-spacing: 1px;
    cursor: pointer;
    transition: 0.2s;
}

/* Hover never dresses an unaffordable button up as buyable. */
@media (hover: hover) {
    .shop-card-btn:hover:not(:disabled):not(.unaffordable) {
        background: #ff5c85;
        border-color: #ff5c85;
        box-shadow: 0 0 18px rgba(255, 51, 102, 0.55);
    }
}

.shop-card-btn .btn-cost {
    background: rgba(0, 0, 0, 0.28);
    border-radius: var(--radius-pill);
    padding: 2px 10px;
    color: #fff;
}

/* Can't afford it yet: stays legible, but clearly not ready to press. */
.shop-card-btn.unaffordable {
    background: transparent;
    color: #ff6688;
    border-color: rgba(255, 51, 102, 0.4);
    opacity: 0.75;
}

.shop-card-btn.unaffordable .btn-cost {
    background: rgba(255, 51, 102, 0.15);
    color: #ff6688;
}

.shop-card-btn.maxed {
    background: transparent;
    border-color: #00ffaa;
    color: #00ffaa;
    cursor: default;
}

.shop-card-btn.maxed .btn-cost {
    display: none;
}

/* PIXEL CAROUSEL (shop) — same shape as the main-menu skin picker so the two
   pickers read as one component in two places. */
#gem-shop-carousel {
    display: flex;
    align-items: center;
    background: rgba(255, 255, 255, 0.05);
    padding: 20px;
    border-radius: var(--radius);
    border: 1px solid #333;
    cursor: default;
}

#gem-skin-shop {
    width: 200px;
}

.gem-skin-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 6px;
}

.gem-skin-preview {
    width: 50px;
    height: 50px;
    border-radius: 8%;
    position: relative;
    margin-bottom: 4px;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
}

.gem-skin-name {
    font-size: 18px;
    font-weight: bold;
}

/* Tier ladder: every card glows in its own colour, harder the higher the tier
   (--tier runs 0→1, set inline), and tiers with a unique perk get a framed
   "premium" treatment so the jump in value reads before you read the tags. */
.gem-skin-card {
    padding: 12px 10px;
    border: 1px solid color-mix(in srgb, var(--skin) calc(var(--tier) * 70%), #2a2a2a);
    border-radius: var(--radius);
    box-shadow: 0 0 calc(var(--tier) * 26px) color-mix(in srgb, var(--skin) calc(var(--tier) * 55%), transparent);
}

.gem-skin-card.premium {
    background: linear-gradient(160deg, color-mix(in srgb, var(--skin) 14%, transparent), rgba(255, 255, 255, 0.02));
}

.gem-skin-tier {
    font-size: 10px;
    font-weight: bold;
    letter-spacing: 2px;
    color: #777;
}

.gem-skin-card.premium .gem-skin-tier {
    color: #ffd700;
    text-shadow: 0 0 8px rgba(255, 215, 0, 0.6);
}

.gem-skin-perks {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    min-height: 20px;
}

.gem-skin-buy-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    margin-top: 4px;
    background: #00ffff;
    border: 1px solid #00ffff;
    border-radius: var(--radius);
    color: #001416;
    padding: 9px 10px;
    font-size: 12px;
    font-weight: 900;
    letter-spacing: 1px;
    white-space: nowrap;
    cursor: pointer;
    transition: 0.2s;
}

.gem-skin-buy-btn .btn-cost {
    background: rgba(0, 0, 0, 0.25);
    border-radius: var(--radius-pill);
    padding: 2px 8px;
    color: #003b3d;
}

@media (hover: hover) {
    .gem-skin-buy-btn:hover:not(:disabled):not(.unaffordable):not(.owned) {
        background: #66ffff;
        border-color: #66ffff;
        box-shadow: 0 0 18px rgba(0, 255, 255, 0.45);
    }
}

.gem-skin-buy-btn.unaffordable {
    background: transparent;
    color: #00cccc;
    border-color: rgba(0, 255, 255, 0.35);
    opacity: 0.75;
}

.gem-skin-buy-btn.unaffordable .btn-cost {
    background: rgba(0, 255, 255, 0.12);
    color: #00cccc;
}

/* Owned but not worn: a quieter outline button that equips it. */
.gem-skin-buy-btn.owned {
    background: transparent;
    border-color: #00ffaa;
    color: #00ffaa;
}

@media (hover: hover) {
    .gem-skin-buy-btn.owned:hover:not(:disabled) {
        background: rgba(0, 255, 170, 0.12);
        border-color: #00ffaa;
        box-shadow: 0 0 14px rgba(0, 255, 170, 0.35);
    }
}

.gem-skin-buy-btn:disabled {
    background: transparent;
    border-color: #00ffaa;
    color: #00ffaa;
    cursor: default;
}

/* Carousel position markers — squares, not circles, to stay on-theme. */
#gem-shop-dots {
    display: flex;
    gap: 0;
    margin-top: 12px;
    /* See .page-title--shop: this auto margin is the other half of the
       "center when it fits, top-align when it overflows" pair. */
    margin-bottom: auto;
    padding-bottom: 20px;
}

/* Each dot is a 24px button (a comfortable tap target) drawing an 8px
   square marker. */
.gem-dot {
    width: 24px;
    height: 24px;
    padding: 0;
    background: none;
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.gem-dot::before {
    content: "";
    width: 8px;
    height: 8px;
    background: #333;
    border: 1px solid #555;
    transition: 0.2s;
}

.gem-dot.owned::before {
    background: #00ffaa;
    border-color: #00ffaa;
}

.gem-dot.active::before {
    background: #fff;
    border-color: #fff;
    box-shadow: 0 0 10px rgba(255, 255, 255, 0.7);
}

/* The framed card may also be one you already own — keep the owned tint and
   mark "current" with the ring instead, so the two states stay distinct. */
.gem-dot.owned.active::before {
    background: #00ffaa;
    border-color: #fff;
    box-shadow: 0 0 10px rgba(0, 255, 170, 0.8);
}

#menu-lastscore {
    font-size: 18px;
    color: #fff;
    margin-bottom: 5px;
    font-weight: bold;
    opacity: 0.7;
}

#menu-highscore {
    font-size: 18px;
    color: #ff3366;
    margin-bottom: 40px;
    font-weight: bold;
}

/* ABOUT · PRIVACY under the start prompt: quiet, but there for anyone looking. */
.menu-links {
    display: flex;
    gap: 18px;
    margin-top: 6px;
}

.menu-links a {
    font-size: 11px;
    letter-spacing: 1px;
    color: #8a8a96;
    text-decoration: none;
    padding: 4px 2px;
}

.menu-links a:hover,
.menu-links a:focus-visible {
    color: #fff;
    text-decoration: underline;
}

/* Shared by the solo and co-op start prompts so both screens end the same way. */
#start-prompt,
#mp-start-prompt {
    font-size: 20px;
    color: #fff;
    animation: blink 1s infinite;
    letter-spacing: 2px;
    padding: 15px 40px;
    border: none;
    background: transparent;
    /* The solo prompt lets clicks through to the menu layer, which starts
       the run (co-op's re-enables them below). */
    pointer-events: none;
}

/* Unlike solo (click anywhere), co-op only starts from this button, which
   stays hidden until a partner has connected. */
#mp-start-prompt {
    display: none;
    margin-top: 12px;
    pointer-events: auto;
}

/* No hover effect needed for start-prompt */

/* "Can't do that" feedback on whatever was pressed (see Game.shakeUI). */
.shake {
    animation: shake 0.4s ease-in-out;
}

@keyframes shake {

    0%,
    100% {
        transform: translateX(0);
    }

    25% {
        transform: translateX(-5px);
    }

    75% {
        transform: translateX(5px);
    }
}

@keyframes blink {
    50% {
        opacity: 0.5;
    }
}

#revive-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.85);
    z-index: 50;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    pointer-events: auto;
    /* Enable clicks */
}

#revive-box {
    background: #111;
    border: 2px solid #ff3366;
    border-radius: var(--radius);
    padding: 30px;
    text-align: center;
    box-shadow: 0 0 30px rgba(255, 51, 102, 0.3);
    max-width: 300px;
}

#revive-title {
    color: #fff;
    font-size: 24px;
    margin-bottom: 8px;
    font-weight: bold;
}

#revive-note {
    color: #aaa;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-size: 14px;
    line-height: 1.4;
    margin: 0 0 18px;
}

/* Both choices the same size and shape, so it's plain the ad is optional
   (CrazyGames asks for exactly that). */
.revive-choice {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    padding: 14px 20px;
    border-radius: var(--radius);
    border: 2px solid #ff3366;
    font-family: inherit;
    font-size: 15px;
    font-weight: bold;
    letter-spacing: 1px;
    cursor: pointer;
    transition: 0.2s;
}

#revive-btn {
    background: #ff3366;
    color: #12000a;
}

#revive-skip {
    margin-top: 10px;
    background: transparent;
    color: #ff6688;
}

@media (hover: hover) {
    #revive-btn:hover {
        background: #ff5588;
        border-color: #ff5588;
    }

    #revive-skip:hover {
        color: #fff;
        border-color: #fff;
    }
}

/* The ▶ that marks every "watch an ad" choice. */
.ad-icon {
    font-size: 0.85em;
}

/* The 2x gems booster, with the gem and heart counters (under the pause
   button): a small offer between runs, a countdown while it runs (then it
   can't be pressed). Each HUD layout places it below. */
.gem-boost {
    position: absolute;
    top: calc(var(--hud-top) + 152px + var(--safe-top));
    right: calc(var(--hud-right) + 10px + var(--safe-right));
    padding: 5px 10px;
    border: 1px solid rgba(0, 255, 255, 0.6);
    border-radius: var(--radius-pill);
    background: rgba(0, 20, 22, 0.8);
    color: #00ffff;
    font-family: inherit;
    font-size: 12px;
    font-weight: bold;
    letter-spacing: 1px;
    white-space: nowrap;
    cursor: pointer;
    z-index: 40;
    /* #ui-layer lets clicks through to the game; this one is a button. */
    pointer-events: auto;
    box-shadow: 0 0 10px rgba(0, 255, 255, 0.25);
}

.gem-boost.is-active {
    cursor: default;
    pointer-events: none;
    border-color: rgba(0, 255, 255, 0.35);
    box-shadow: none;
}

@media (hover: hover) {
    .gem-boost:not(.is-active):hover {
        background: rgba(0, 255, 255, 0.15);
    }
}

@media (max-width: 480px) {
    .gem-boost {
        top: calc(var(--hud-top) + 128px + var(--safe-top));
    }
}

/* Phones: just inside the playfield's top-right corner, under the strip. */
#game-container[data-layout="strip"] .gem-boost {
    top: calc(var(--pf-top, 0px) + 10px);
    right: calc(16px + var(--safe-right));
}

/* Wide windows: beside the column, under the pause button. */
#game-container[data-layout="flank"] .gem-boost {
    right: auto;
    left: calc(var(--pf-left, 0px) + var(--pf-w, 0px) + var(--flank-gap));
    top: calc(var(--pf-top, 0px) + 96px + 2 * var(--flank-count) + var(--safe-top));
}

/* ---------- Pixel of the Hour (js/hourly.js) ----------
   The button under the Pixel picker, and the card it opens. */
.hourly-open-btn {
    margin-top: 8px;
    max-width: 100%;
    padding: 4px 10px;
    border: 1px solid rgba(255, 170, 0, 0.55);
    border-radius: var(--radius-pill);
    background: rgba(255, 170, 0, 0.08);
    color: #ffaa00;
    font-family: inherit;
    font-size: 10px;
    font-weight: bold;
    letter-spacing: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}

@media (hover: hover) {
    .hourly-open-btn:hover {
        background: rgba(255, 170, 0, 0.18);
        color: #fff;
    }
}

#hourly-preview {
    display: flex;
    justify-content: center;
    margin: 2px 0;
}

.hourly-pixel {
    display: block;
    position: relative;
    width: 72px;
    height: 72px;
    border-radius: 8%; /* PIXEL_CORNER_RADIUS / 26, like the in-game Pixel */
    box-shadow: 0 0 24px rgba(255, 255, 255, 0.15);
}

.hourly-name {
    font-size: 18px;
    font-weight: bold;
    color: #fff;
}

.hourly-perks {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
}

.hourly-owned {
    font-size: 12px;
    font-weight: bold;
    letter-spacing: 1px;
    color: #00ffaa;
}

.overlay-btn.hourly-gem-btn {
    border-color: rgba(0, 255, 255, 0.6);
    color: #00ffff;
}

.overlay-btn.cant-afford {
    opacity: 0.45;
}

/* The run card's booster offer. */
.overlay-btn.ad-offer-btn {
    border-color: rgba(0, 255, 255, 0.6);
    color: #00ffff;
}

/* FAKE AD VIDEO UI */
#ad-video-mock {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #000;
    z-index: 110;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    pointer-events: auto;
    /* Enable interaction */
}

#ad-countdown {
    position: absolute;
    top: 20px;
    right: 20px;
    color: #fff;
    font-size: 20px;
    font-weight: bold;
    background: rgba(0, 0, 0, 0.5);
    padding: 10px 20px;
    border-radius: var(--radius-pill);
}

#ad-content {
    color: #fff;
    font-size: 30px;
    font-weight: bold;
    animation: pulse 1s infinite;
}

@keyframes pulse {
    0% {
        opacity: 0.8;
    }

    50% {
        opacity: 1;
    }

    100% {
        opacity: 0.8;
    }
}

/* Below the HUD rows (score, BEST, power-up bar) and the system-message box,
   so a badge and a notice can show at the same time. */
/* Sits in the #ui-layer column right under #system-alert (which always
   keeps its space), so a badge never lands on top of a notice. */
#achievement-pop {
    position: relative;
    margin-top: 10px;
    background: #ffd700;
    color: #000;
    padding: 10px 20px;
    font-weight: bold;
    border-radius: var(--radius-pill);
    box-shadow: 0 0 20px #ffd700;
    display: none;
    z-index: 100;
    animation: slideIn 0.5s forwards;
}

@keyframes slideIn {
    0% {
        opacity: 0;
        transform: translateY(-10px);
    }

    100% {
        opacity: 1;
        transform: translateY(0);
    }
}

/* HALL OF FAME — same card shell as .shop-card / .gem-skin-row so the menu
   reads as one family, and sized to match their min(340px, 85vw). */
#fame-container {
    background: rgba(255, 255, 255, 0.05);
    padding: 16px 14px;
    border: 1px solid #333;
    border-radius: var(--radius);
    margin-bottom: 18px;
    width: min(340px, 85vw);
    box-sizing: border-box;
    text-align: center;
}

.fame-heading {
    color: #ffd700;
    font-size: 17px;
    font-weight: 900;
    letter-spacing: 2px;
    text-shadow: 0 0 12px rgba(255, 215, 0, 0.55);
    padding-bottom: 8px;
    margin-bottom: 8px;
    border-bottom: 1px solid #333;
}

#fame-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.fame-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 7px;
    border: 1px solid transparent;
    border-radius: var(--radius);
    text-align: left;
}

/* Rank chip — gold/silver/bronze on the podium, neutral below it. */
.fame-rank {
    flex: none;
    width: 20px;
    height: 20px;
    line-height: 20px;
    border-radius: var(--radius-pill);
    background: #222;
    color: #888;
    font-size: 11px;
    font-weight: bold;
    text-align: center;
}

.fame-swatch {
    flex: none;
    width: 14px;
    height: 14px;
    background: #555;
    box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
}

/* The skin name takes the slack, so the score stays hard right and the digits
   line up down the column. */
.fame-skin {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 12px;
    color: #bbb;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fame-date {
    flex: none;
    font-size: 10px;
    color: #8c8c8c;
}

.fame-score {
    flex: none;
    font-size: 16px;
    font-weight: bold;
    color: #fff;
}

.fame-row--1 {
    background: rgba(255, 215, 0, 0.08);
    border-color: rgba(255, 215, 0, 0.45);
}

.fame-row--1 .fame-rank {
    background: #ffd700;
    color: #000;
}

.fame-row--1 .fame-score {
    color: #ffd700;
    text-shadow: 0 0 10px rgba(255, 215, 0, 0.5);
}

.fame-row--2 .fame-rank {
    background: #c0c0c0;
    color: #000;
}

.fame-row--3 .fame-rank {
    background: #cd7f32;
    color: #000;
}

.fame-empty {
    font-size: 12px;
    color: #8c8c8c;
    letter-spacing: 1px;
    padding: 6px 0;
}

/* The main menu is one non-scrolling flex column, so the roomy card above only
   fits on tall viewports. Below that, tighten the card (never the legibility of
   the score itself) so it can't push the start button off screen. */
@media (max-height: 820px) {
    #fame-container {
        padding: 10px 12px;
        margin-bottom: 10px;
    }

    .fame-heading {
        font-size: 15px;
        padding-bottom: 5px;
        margin-bottom: 5px;
    }

    #fame-list {
        gap: 3px;
    }

    .fame-row {
        padding: 3px 6px;
    }

    .fame-rank {
        width: 18px;
        height: 18px;
        line-height: 18px;
        font-size: 10px;
    }

    .fame-score {
        font-size: 14px;
    }
}

/* Very short viewports: the date is the first thing worth losing, then all the
   remaining chrome, so the card costs about what the old one did. */
@media (max-height: 680px) {
    #fame-container {
        padding: 6px 10px;
        margin-bottom: 6px;
    }

    .fame-heading {
        font-size: 13px;
        padding-bottom: 3px;
        margin-bottom: 3px;
    }

    #fame-list {
        gap: 2px;
    }

    .fame-date {
        display: none;
    }

    .fame-row {
        padding: 1px 6px;
    }

    .fame-rank {
        width: 14px;
        height: 14px;
        line-height: 14px;
        font-size: 9px;
    }

    .fame-score {
        font-size: 13px;
    }
}

/* Landscape windows about 510px tall (the smallest CrazyGames desktop
   frame): trim the spacing around the menu so CLICK TO START still shows
   without scrolling. */
@media (max-height: 580px) {
    .page-title {
        font-size: clamp(28px, 7vh, 44px);
        margin-bottom: 8px;
    }

    #skin-container {
        padding: 10px 20px;
        margin-bottom: 10px;
    }

    #skin-preview-box {
        margin-bottom: 6px;
    }

    .menu-actions {
        margin-bottom: 8px;
    }

    #menu-highscore {
        margin-bottom: 4px;
    }

    #start-prompt {
        padding: 8px 40px;
    }
}
/* The shortest windows CrazyGames checks (821x462, 800x450): tighter still,
   so CLICK TO START and the PRIVACY link stay on screen. */
@media (max-height: 480px) {
    .page-title {
        margin-bottom: 4px;
    }

    #fame-container {
        margin-bottom: 6px;
    }

    #skin-container {
        padding: 6px 20px;
        margin-bottom: 6px;
    }

    #skin-preview-box {
        width: 40px;
        height: 40px;
        margin-bottom: 4px;
    }

    .menu-actions {
        margin-bottom: 4px;
    }

    #start-prompt {
        padding: 4px 40px;
    }

    .menu-links {
        margin-top: 0;
    }
}
/* Respect "reduce motion": no blinking, pulsing or sliding. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* ---------- In-run HUD button (pause) ---------- */
.hud-btn {
    position: absolute;
    /* Below the gem and heart counters in the top-right corner. */
    top: calc(var(--hud-top) + 102px + var(--safe-top));
    right: calc(var(--hud-right) + 10px + var(--safe-right));
    width: 40px;
    height: 40px;
    padding: 0;
    background: rgba(10, 10, 14, 0.6);
    border: 1px solid #444;
    border-radius: var(--radius);
    color: #ddd;
    font-size: 14px;
    letter-spacing: -2px;
    cursor: pointer;
    pointer-events: auto;
}

/* The pause icon's two bars, drawn rather than a glyph (Orbitron has none). */
#pause-btn::before,
#pause-btn::after {
    content: "";
    position: absolute;
    top: 12px;
    width: 5px;
    height: 16px;
    background: currentColor;
}

#pause-btn::before { left: 13px; }
#pause-btn::after { right: 13px; }

@media (hover: hover) {
    .hud-btn:hover {
        border-color: #00ffff;
        color: #00ffff;
    }
}

/* ---------- Shared modal overlays: pause, settings, run card ---------- */
.overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: calc(16px + var(--safe-top)) 16px calc(16px + var(--safe-bottom));
    box-sizing: border-box;
    background: rgba(0, 0, 0, 0.78);
    pointer-events: auto;
    z-index: 60;
}

#run-card {
    /* Above the menus it opens over, below the persistent gem counter. */
    z-index: 35;
}

.overlay-box {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    width: min(320px, 100%);
    max-height: 100%;
    overflow-y: auto;
    padding: 22px 20px;
    box-sizing: border-box;
    background: #0d0b14;
    border: 1px solid #3a2a55;
    border-radius: var(--radius);
    box-shadow: 0 0 30px rgba(160, 32, 240, 0.25);
    text-align: center;
}

.overlay-title {
    font-size: 24px;
    font-weight: 900;
    letter-spacing: 3px;
    color: #fff;
    text-shadow: 0 0 12px #a020f0, 0 0 24px #c04dff;
    margin-bottom: 6px;
}

.overlay-note {
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 1px;
    color: #ffaa00;
}

.overlay-btn {
    padding: 12px 14px;
    background: transparent;
    border: 1px solid #555;
    border-radius: var(--radius);
    color: #fff;
    font-size: 14px;
    font-weight: 900;
    letter-spacing: 1px;
    cursor: pointer;
    transition: 0.2s;
}

.overlay-btn.primary {
    background: #00ffff;
    border-color: #00ffff;
    color: #001416;
}

.overlay-btn.danger {
    border-color: rgba(255, 51, 102, 0.6);
    color: #ff6688;
}

@media (hover: hover) {
    .overlay-btn:hover {
        border-color: #fff;
    }

    .overlay-btn.primary:hover {
        background: #66ffff;
        border-color: #66ffff;
    }
}

/* Settings rows: label left, control right. */
.setting-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 4px;
    border-bottom: 1px solid #222;
    color: #ddd;
    font-size: 13px;
    font-weight: bold;
    letter-spacing: 1px;
    cursor: pointer;
}

.setting-row input[type="range"] {
    width: 55%;
    accent-color: #00ffff;
}

.setting-row input[type="checkbox"] {
    width: 20px;
    height: 20px;
    accent-color: #00ffff;
}

/* ---------- End-of-run card ---------- */
.run-card-distance {
    font-size: 44px;
    font-weight: 900;
    color: #fff;
    text-shadow: 0 0 16px rgba(255, 255, 255, 0.45);
}

.run-card-best {
    color: #ffd700;
    font-size: 14px;
    font-weight: 900;
    letter-spacing: 2px;
    text-shadow: 0 0 10px rgba(255, 215, 0, 0.6);
}

.run-card-stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    margin: 6px 0;
}

.run-stat {
    padding: 8px 6px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid #2a2a2a;
    border-radius: var(--radius);
}

.run-stat-value {
    display: block;
    color: #fff;
    font-size: 16px;
    font-weight: 900;
}

.run-stat-label {
    display: block;
    margin-top: 2px;
    color: #8c8c8c;
    font-size: 9px;
    font-weight: bold;
    letter-spacing: 1px;
}

.run-card-unlocks:empty {
    display: none;
}

.run-card-unlocks {
    display: flex;
    flex-direction: column;
    gap: 4px;
    color: #ffd700;
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 1px;
}

.run-card-actions {
    display: flex;
    gap: 8px;
    margin-top: 4px;
}

.run-card-actions .overlay-btn {
    flex: 1;
}

/* ---------- Main menu action row ---------- */
.menu-actions {
    display: flex;
    gap: 8px;
    margin-bottom: 15px;
}

.menu-actions .shop-trigger-btn {
    margin-bottom: 0;
}

/* Keyboard focus in the shop (arrow keys browse, Enter buys). */
.nav-btn:focus-visible,
.gem-skin-buy-btn:focus-visible,
.gem-dot:focus-visible,
.mode-switch-arrow:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 3px;
}

/* The shop is the main thing to do between runs: gem-cyan and glowing,
   and it pulses with a BUY badge whenever something new is affordable. */
#shop-open-btn {
    position: relative;
    color: #00ffff;
    border-color: #00ffff;
    background: rgba(0, 255, 255, 0.1);
    box-shadow: 0 0 12px rgba(0, 255, 255, 0.35);
    text-shadow: 0 0 8px rgba(0, 255, 255, 0.6);
    font-size: 1.1em;
    padding-left: 22px;
    padding-right: 22px;
}

@media (hover: hover) {
    #shop-open-btn:hover {
        border-color: #00ffff;
        background: rgba(0, 255, 255, 0.2);
    }
}

@keyframes shop-pulse {
    0%, 100% { box-shadow: 0 0 12px rgba(0, 255, 255, 0.35); }
    50% { box-shadow: 0 0 26px rgba(0, 255, 255, 0.9); }
}

#shop-open-btn.can-buy {
    animation: shop-pulse 1.6s ease-in-out infinite;
}

.shop-badge {
    position: absolute;
    top: -9px;
    right: -9px;
    padding: 2px 6px;
    border-radius: 8px;
    background: #ff3366;
    color: #fff;
    font-size: 10px;
    letter-spacing: 1px;
    text-shadow: none;
    box-shadow: 0 0 8px rgba(255, 51, 102, 0.8);
}

.icon-btn {
    padding: 10px 14px;
    font-size: 16px;
}

/* ---------- Records ---------- */
#records-menu-layer {
    transform: translateY(100%);
    background: #0a0710;
    z-index: 25;
    padding-top: calc(30px + var(--safe-top));
}

.page-title--records {
    text-shadow: 0 0 14px #ffd700, 0 0 28px #ffaa00;
    margin-bottom: 4px;
}

.records-stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    width: min(320px, 85vw);
}

.records-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: min(320px, 85vw);
    padding-bottom: 20px;
}

.achievement-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border: 1px solid #2a2a2a;
    border-radius: var(--radius);
    background: rgba(255, 255, 255, 0.03);
    text-align: left;
}

.achievement-row.earned {
    border-color: rgba(255, 215, 0, 0.45);
    background: rgba(255, 215, 0, 0.06);
}

.achievement-icon {
    flex: none;
    width: 22px;
    text-align: center;
    font-size: 16px;
    filter: grayscale(1);
    opacity: 0.5;
}

.achievement-row.earned .achievement-icon {
    filter: none;
    opacity: 1;
}

.achievement-name {
    display: block;
    color: #bbb;
    font-size: 13px;
    font-weight: bold;
}

.achievement-row.earned .achievement-name {
    color: #ffd700;
}

.achievement-desc {
    display: block;
    color: #8c8c8c;
    font-size: 10px;
    letter-spacing: 0.5px;
}

#records-count {
    color: #ffd700;
    letter-spacing: 1px;
}

/* Reduced motion chosen in Settings: same as the OS-level preference. */
body.reduce-motion *,
body.reduce-motion *::before,
body.reduce-motion *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
}

/* ---------- On-screen touch bar (phones) ----------
   #touch-controls is laid over the canvas by Game.layoutTouchControls(). The
   bar runs along its bottom edge, split exactly like InputHandler.zoneAt():
   ◀ is the left quarter, ▶ the second quarter, ▲ (jump) the right half. */
#touch-controls {
    position: absolute;
    pointer-events: none;
    z-index: 11;
}

.touch-bar {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    /* About an inch, plus room for the home indicator. */
    height: calc(clamp(56px, 9vh, 96px) + var(--safe-bottom));
    padding-bottom: var(--safe-bottom);
    box-sizing: border-box;
    border-top: 2px solid rgba(255, 255, 255, 0.22);
    background: rgba(0, 0, 0, 0.28);
}

.touch-pad {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 25%;
    box-sizing: border-box;
    color: rgba(255, 255, 255, 0.55);
    transition: background 0.08s, color 0.08s;
}

/* A thin line between ◀ and ▶ (the ⇆ badge sits on it); a firmer one
   between moving and jumping. */
.touch-pad--right { border-left: 1px solid rgba(255, 255, 255, 0.16); }

.touch-pad--jump {
    flex-basis: 50%;
    border-left: 2px solid rgba(255, 255, 255, 0.28);
}

.touch-pad.is-active {
    background: rgba(0, 255, 255, 0.2);
    color: #fff;
}

/* Arrows are CSS triangles, not ◀ ▶ ▲ glyphs: those come out at different
   sizes per font, and iOS can draw ▶ as an emoji. */
.touch-arrow {
    width: 20px;
    height: 22px;
    background: currentColor;
    clip-path: polygon(100% 0, 100% 100%, 0 50%);
}

.touch-pad--right .touch-arrow { clip-path: polygon(0 0, 100% 50%, 0 100%); }

.touch-pad--jump .touch-arrow {
    width: 26px;
    height: 22px;
    clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

.touch-slide {
    position: absolute;
    left: 25%;
    top: calc(50% - var(--safe-bottom) / 2);
    transform: translate(-50%, -50%);
    padding: 1px 7px 3px;
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: var(--radius-pill);
    background: #0b0b12;
    color: rgba(255, 255, 255, 0.7);
    font-family: system-ui, -apple-system, sans-serif;
    font-size: 16px;
    line-height: 1.2;
}

/* ---------- Daily challenge target (from a shared link) ---------- */
#challenge-hud {
    position: absolute;
    top: calc(var(--hud-top) + 116px + var(--safe-top));
    left: 50%;
    transform: translateX(-50%);
    padding: 3px 10px;
    border: 1px solid rgba(255, 215, 0, 0.5);
    border-radius: var(--radius-pill);
    background: rgba(0, 0, 0, 0.5);
    color: #ffd700;
    font-size: 12px;
    font-weight: bold;
    letter-spacing: 1px;
    white-space: nowrap;
}

#challenge-hud.beaten {
    border-color: #00ffaa;
    color: #00ffaa;
}

/* Phones: BEST sits under the score, so the top centre is free (the old spot
   is where alerts and achievement pops appear). */
@media (max-width: 480px) {
    #challenge-hud {
        top: calc(var(--hud-top) + 26px + var(--safe-top));
        font-size: 11px;
    }
}

/* ---------- Share ---------- */
.share-btn {
    border-color: rgba(255, 215, 0, 0.6);
    color: #ffd700;
}

#share-toast {
    color: #00ffaa;
    word-break: break-all;
}

/* ---------- Co-op: spectating while dead, room code sharing ---------- */
#spectate-hud {
    position: absolute;
    top: calc(var(--hud-top) + 116px + var(--safe-top));
    left: 50%;
    transform: translateX(-50%);
    padding: 4px 12px;
    border: 1px solid rgba(192, 77, 255, 0.5);
    border-radius: var(--radius-pill);
    background: rgba(0, 0, 0, 0.55);
    color: #d896ff;
    font-size: 12px;
    font-weight: bold;
    letter-spacing: 1px;
    white-space: nowrap;
}

.mp-box .mp-code-btn {
    margin: 2px 0 8px;
    padding: 6px 10px;
    background: transparent;
    color: var(--accent);
    border-color: rgba(var(--accent-rgb), 0.45);
    font-size: 11px;
}

/* Phone and tablet browser tabs: install steps cover everything. */
#install-gate {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: calc(24px + var(--safe-top)) calc(16px + var(--safe-right)) calc(24px + var(--safe-bottom)) calc(16px + var(--safe-left));
    background: #050505;
    color: #fff;
    overflow-y: auto;
}

.install-card {
    max-width: 360px;
    text-align: center;
}

.install-pixel {
    position: relative;
    width: 48px;
    height: 48px;
    margin: 0 auto 16px;
    background: #ff3366;
    box-shadow: 0 0 24px rgba(255, 51, 102, 0.7);
}

.install-pixel span {
    position: absolute;
    top: 14px;
    width: 10px;
    height: 10px;
    background: #fff;
}

.install-pixel span:first-child { left: 10px; }
.install-pixel span:last-child { right: 10px; }

#install-gate h1 {
    margin: 0 0 12px;
    font-size: 30px;
    letter-spacing: 2px;
    color: #00ffcc;
    text-shadow: 0 0 12px rgba(0, 255, 204, 0.6);
}

.install-lead {
    margin: 0 0 18px;
    font-size: 15px;
    line-height: 1.5;
    color: #ddd;
}

.install-note {
    margin: 0 0 16px;
    padding: 10px 12px;
    border: 1px solid #ffcc00;
    border-radius: var(--radius);
    color: #ffcc00;
    font-size: 14px;
}

.install-steps {
    margin: 0 0 18px;
    padding: 0;
    list-style: none;
    counter-reset: step;
    text-align: left;
}

.install-steps li {
    counter-increment: step;
    position: relative;
    margin-bottom: 10px;
    padding: 12px 12px 12px 48px;
    border: 1px solid rgba(0, 255, 255, 0.35);
    border-radius: var(--radius);
    background: rgba(0, 255, 255, 0.06);
    font-size: 15px;
    line-height: 1.4;
}

.install-steps li::before {
    content: counter(step);
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    width: 24px;
    height: 24px;
    border-radius: var(--radius-pill);
    background: #00ffff;
    color: #000;
    font-weight: bold;
    font-size: 14px;
    line-height: 24px;
    text-align: center;
}

.install-steps b {
    color: #00ffff;
}

.install-btn {
    display: block;
    width: 100%;
    margin: 0 0 18px;
    padding: 16px;
    border: 2px solid #00ffcc;
    border-radius: var(--radius);
    background: rgba(0, 255, 204, 0.15);
    color: #00ffcc;
    font: inherit;
    font-size: 18px;
    font-weight: bold;
    letter-spacing: 1px;
    box-shadow: 0 0 18px rgba(0, 255, 204, 0.45);
    cursor: pointer;
}

.install-btn:active {
    background: rgba(0, 255, 204, 0.3);
}

.install-btn:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 3px;
}

.install-done {
    border-color: #00ffcc;
    color: #00ffcc;
}

.install-done b {
    color: #fff;
}

.install-share {
    width: 20px;
    height: 20px;
    vertical-align: -4px;
    color: #00a8ff;
}

.install-foot {
    margin: 0;
    font-size: 12px;
    color: #8a8a8a;
}
