/* =============================================================================
   KAMIZAN AMIRUDIN — ARCADE PORTFOLIO
   A side-scrolling, playable version of the CV at ../index.html

   The palette is deliberately the same as the main site — deep slate ground,
   "run green" accent, signal cyan — so the two pages read as one person's
   work rather than two unrelated experiments. What changes here is the
   register: Press Start 2P for the machine chrome (HUD, labels, buttons),
   VT323 for anything you actually read at length, and a night sky the world
   scrolls through instead of a flat page.
   ========================================================================== */

/* ================= TOKENS ================= */
:root {
    /* Shared with ../styles.css — one identity across both pages */
    --bg: #070A10;
    --bg-elev: #0B0F17;
    --panel-bg: #0E1421;
    --accent: #3DDC97;
    --accent-deep: #17A673;
    --accent-ink: #041710;
    --accent-2: #4CC9F0;
    --accent-3: #A78BFA;
    --danger: #FF5F57;
    --warn: #FEBC2E;

    --text: #EDF2F8;
    --text-soft: #B7C3D3;
    --text-dim: #8A99AD;

    --line: rgba(255, 255, 255, 0.10);
    --line-strong: rgba(255, 255, 255, 0.22);
    --surface: rgba(255, 255, 255, 0.045);

    /* Press Start 2P is ~2x the width of a normal face per glyph, so it is
       only ever used at chrome sizes. VT323 carries every reading surface. */
    --font-pixel: 'Press Start 2P', 'VT323', monospace;
    --font-body: 'VT323', 'Courier New', monospace;

    --ground-h: 74px;
    --hud-h: 60px;

    --ease: cubic-bezier(0.16, 1, 0.3, 1);
    --t-fast: 140ms;
    --t-mid: 260ms;

    /* One hard pixel shadow, the way a sprite sits on a background */
    --pixel-shadow: 6px 6px 0 rgba(0, 0, 0, 0.55);
}

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

html,
body {
    height: 100%;
    /* hidden first as the fallback; clip also blocks programmatic and
       focus-driven scrolling, which hidden does not. */
    overflow: hidden;
    overflow: clip;
}

body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-body);
    /* VT323 runs small for its point size; 20px here reads like 16px Inter. */
    font-size: 20px;
    line-height: 1.4;
    overflow: hidden;
    -webkit-font-smoothing: antialiased;
    -webkit-touch-callout: none;
    overscroll-behavior: none;
    touch-action: none;
}

/* The only scrollable surfaces in the game — these keep vertical panning */
.panel,
.sheet-list,
.overlay-card {
    touch-action: pan-y;
}

/* Selection is disabled only on the play surface, never on readable copy —
   a visitor must still be able to copy an email address out of a panel. */
.no-select {
    user-select: none;
    -webkit-user-select: none;
}

img {
    display: block;
    max-width: 100%;
}

a {
    color: var(--accent);
    text-decoration: none;
}

button {
    font: inherit;
    color: inherit;
    background: none;
    border: none;
    cursor: pointer;
}

ul {
    list-style: none;
}

:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Keyboard users land here first: an escape hatch out of the game and into
   the plain-HTML CV. A game that traps a screen reader is not a portfolio. */
.skip-link {
    position: fixed;
    top: 8px;
    left: 8px;
    z-index: 3000;
    transform: translateY(-160%);
    background: var(--accent);
    color: var(--accent-ink);
    font-family: var(--font-pixel);
    font-size: 10px;
    padding: 14px 18px;
    border-radius: 6px;
    transition: transform var(--t-fast) var(--ease);
}

.skip-link:focus {
    transform: none;
}

/* ================= SKY & PARALLAX =================
   Four fixed layers behind the world. They translate on the same camera X as
   the world but at a fraction of its speed, which is what sells depth for
   almost no cost — no extra DOM per frame, just three transforms.
   ================================================== */
.sky {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background: linear-gradient(180deg,
            #04060B 0%,
            #070C18 28%,
            #0D1830 55%,
            #17324F 78%,
            #2A5A6E 92%,
            #3C7F72 100%);
}

.stars,
.hills-far,
.hills-near {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    will-change: transform;
}

.stars {
    /* Static field, tiled — cheaper and steadier than animating dozens of nodes */
    background-image:
        radial-gradient(1.5px 1.5px at 12% 18%, rgba(255, 255, 255, 0.65), transparent),
        radial-gradient(1.5px 1.5px at 34% 42%, rgba(61, 220, 151, 0.5), transparent),
        radial-gradient(1px 1px at 58% 12%, rgba(255, 255, 255, 0.5), transparent),
        radial-gradient(1.5px 1.5px at 77% 33%, rgba(76, 201, 240, 0.5), transparent),
        radial-gradient(1px 1px at 90% 9%, rgba(255, 255, 255, 0.45), transparent),
        radial-gradient(1px 1px at 22% 60%, rgba(255, 255, 255, 0.3), transparent);
    background-size: 420px 380px;
    background-repeat: repeat;
    opacity: 0.9;
}

.hills-far,
.hills-near {
    bottom: 0;
    top: auto;
    height: 46vh;
    background-repeat: repeat-x;
    background-position: bottom left;
}

.hills-far {
    height: 38vh;
    background-image:
        repeating-linear-gradient(135deg, transparent 0 58px, rgba(20, 44, 62, 0.9) 58px 60px),
        linear-gradient(180deg, transparent 0%, #0E2438 40%, #122B40 100%);
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 200' preserveAspectRatio='none'%3E%3Cpath d='M0 200 L0 120 L80 60 L160 120 L240 40 L320 110 L400 70 L480 130 L560 55 L640 115 L720 75 L800 130 L800 200 Z' fill='%23000'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 200' preserveAspectRatio='none'%3E%3Cpath d='M0 200 L0 120 L80 60 L160 120 L240 40 L320 110 L400 70 L480 130 L560 55 L640 115 L720 75 L800 130 L800 200 Z' fill='%23000'/%3E%3C/svg%3E");
    -webkit-mask-size: 1400px 100%;
    mask-size: 1400px 100%;
    -webkit-mask-repeat: repeat-x;
    mask-repeat: repeat-x;
    opacity: 0.75;
}

.hills-near {
    height: 26vh;
    background: linear-gradient(180deg, #102A38 0%, #0A1B26 100%);
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 200' preserveAspectRatio='none'%3E%3Cpath d='M0 200 L0 150 L60 150 L60 90 L110 90 L110 150 L200 150 L200 70 L260 70 L260 150 L360 150 L360 110 L420 110 L420 150 L520 150 L520 60 L580 60 L580 150 L680 150 L680 120 L740 120 L740 150 L800 150 L800 200 Z' fill='%23000'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 200' preserveAspectRatio='none'%3E%3Cpath d='M0 200 L0 150 L60 150 L60 90 L110 90 L110 150 L200 150 L200 70 L260 70 L260 150 L360 150 L360 110 L420 110 L420 150 L520 150 L520 60 L580 60 L580 150 L680 150 L680 120 L740 120 L740 150 L800 150 L800 200 Z' fill='%23000'/%3E%3C/svg%3E");
    -webkit-mask-size: 900px 100%;
    mask-size: 900px 100%;
    -webkit-mask-repeat: repeat-x;
    mask-repeat: repeat-x;
    opacity: 0.9;
}

/* ---- Ground ---- */
.ground {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    height: var(--ground-h);
    z-index: 40;
    background:
        repeating-linear-gradient(90deg,
            #143024 0 30px,
            #10281E 30px 60px);
    border-top: 4px solid var(--accent-deep);
    box-shadow: 0 -6px 24px rgba(23, 166, 115, 0.18);
}

.ground::after {
    /* Grass fringe — one gradient, no extra element */
    content: '';
    position: absolute;
    top: -3px;
    left: 0;
    right: 0;
    height: 8px;
    background: repeating-linear-gradient(90deg,
            var(--accent) 0 6px,
            transparent 6px 14px);
    opacity: 0.55;
}

/* ================= HUD =================
   Three jobs, in priority order: tell you where you are, let you jump
   somewhere else, and stay out of the way of the world behind it.
   ======================================= */
.hud {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 600;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 10px max(14px, env(safe-area-inset-right)) 10px max(14px, env(safe-area-inset-left));
    background: linear-gradient(180deg, rgba(7, 10, 16, 0.94), rgba(7, 10, 16, 0.72) 70%, transparent);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.hud-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

.hud-badge {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    background: linear-gradient(135deg, var(--accent), var(--accent-deep));
    color: var(--accent-ink);
    font-family: var(--font-pixel);
    font-size: 10px;
}

.hud-name {
    font-family: var(--font-pixel);
    font-size: 10px;
    letter-spacing: 0.02em;
    line-height: 1.5;
}

.hud-name span {
    display: block;
    color: var(--accent);
    font-size: 8px;
    margin-top: 3px;
}

/* ---- Zone rail: the map, and the fast-travel control ----
   The single most important addition. Nobody hiring is going to walk 12,000
   pixels to find the experience section; this lets them jump straight there
   while leaving the walk intact for anyone who wants it. */
.rail {
    flex: 1;
    min-width: 0;
    position: relative;
    height: 34px;
    display: flex;
    align-items: center;
    padding-inline: 22px;
}

.rail-track {
    position: absolute;
    left: 22px;
    right: 22px;
    height: 4px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.10);
    overflow: hidden;
}

.rail-fill {
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--accent), var(--accent-2));
    transition: width 90ms linear;
}

.rail-marks {
    position: relative;
    width: 100%;
    height: 100%;
}

.rail-mark {
    position: absolute;
    top: 50%;
    /* 44px hit area centred on a 14px dot — the target is the button, the
       dot is only what you see. */
    width: 44px;
    height: 44px;
    margin: -22px 0 0 -22px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    color: var(--text-dim);
}

.rail-mark::before {
    content: '';
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: var(--bg-elev);
    border: 3px solid currentColor;
    transition: transform var(--t-fast) var(--ease),
        background var(--t-fast) var(--ease),
        border-color var(--t-fast) var(--ease);
}

.rail-mark:hover::before {
    transform: scale(1.35);
    border-color: var(--accent);
}

.rail-mark.is-passed {
    color: var(--accent-deep);
}

.rail-mark.is-current {
    color: var(--accent);
}

.rail-mark.is-current::before {
    background: var(--accent);
    transform: scale(1.35);
    box-shadow: 0 0 0 5px rgba(61, 220, 151, 0.2);
}

/* Label rides under its own mark, so the rail doubles as a legend */
.rail-mark span {
    position: absolute;
    top: 30px;
    left: 50%;
    transform: translateX(-50%);
    font-family: var(--font-pixel);
    font-size: 7px;
    letter-spacing: 0.04em;
    white-space: nowrap;
    color: var(--text-dim);
    transition: color var(--t-fast) var(--ease);
    pointer-events: none;
}

.rail-mark.is-current span {
    color: var(--accent);
}

.hud-stats {
    display: flex;
    gap: 8px;
    flex-shrink: 0;
}

.stat {
    min-width: 74px;
    padding: 5px 9px;
    border: 2px solid var(--line-strong);
    border-radius: 6px;
    background: rgba(0, 0, 0, 0.45);
    text-align: center;
}

.stat b {
    display: block;
    font-family: var(--font-pixel);
    font-size: 7px;
    color: var(--text-dim);
    font-weight: 400;
    letter-spacing: 0.06em;
}

.stat i {
    display: block;
    font-style: normal;
    font-family: var(--font-pixel);
    font-size: 10px;
    color: var(--accent);
    margin-top: 5px;
}

.hud-actions {
    display: flex;
    gap: 8px;
    flex-shrink: 0;
}

.icon-btn {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: 8px;
    border: 2px solid var(--line-strong);
    background: rgba(0, 0, 0, 0.45);
    color: var(--text-soft);
    font-size: 15px;
    transition: color var(--t-fast) var(--ease),
        border-color var(--t-fast) var(--ease),
        background var(--t-fast) var(--ease);
}

.icon-btn:hover {
    color: var(--accent);
    border-color: var(--accent);
    background: rgba(61, 220, 151, 0.12);
}

.icon-btn--app {
    color: #3DDCFF;
    border-color: rgba(61, 220, 255, 0.45);
    background: rgba(61, 220, 255, 0.08);
}

.icon-btn--app:hover {
    color: #FFFFFF;
    border-color: #3DDCFF;
    background: rgba(61, 220, 255, 0.25);
    box-shadow: 0 0 15px rgba(61, 220, 255, 0.4);
}

.btn-hud-app {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 44px;
    padding: 0 14px;
    border-radius: 8px;
    border: 2px solid rgba(0, 242, 254, 0.5);
    background: rgba(0, 242, 254, 0.08);
    color: #00F2FE;
    font-family: var(--font-pixel);
    font-size: 9px;
    text-decoration: none;
    letter-spacing: 0.5px;
    transition: all var(--t-fast) var(--ease);
}

.btn-hud-app:hover {
    color: #FFFFFF;
    border-color: #00F2FE;
    background: rgba(0, 242, 254, 0.25);
    box-shadow: 0 0 15px rgba(0, 242, 254, 0.45);
    transform: translateY(-1px);
}

.btn-hud-app i {
    font-size: 13px;
    color: #00F5A0;
}

@media (max-width: 600px) {
    .btn-hud-app span {
        display: none;
    }
    .btn-hud-app {
        padding: 0 12px;
    }
}

/* ================= OVERLAYS (start / pause) ================= */
.overlay {
    position: fixed;
    inset: 0;
    z-index: 1500;
    display: grid;
    place-items: center;
    padding: 24px;
    background: radial-gradient(ellipse at center, rgba(7, 10, 16, 0.86), rgba(4, 6, 10, 0.97));
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    transition: opacity var(--t-mid) var(--ease), visibility var(--t-mid);
}

.overlay[hidden] {
    display: none;
}

.overlay.is-hiding {
    opacity: 0;
    visibility: hidden;
}

.overlay-card {
    width: min(620px, 100%);
    max-height: 88vh;
    overflow-y: auto;
    text-align: center;
    padding: 34px 30px;
    border: 3px solid var(--accent-deep);
    border-radius: 14px;
    background: var(--panel-bg);
    box-shadow: var(--pixel-shadow), 0 0 60px rgba(23, 166, 115, 0.18);
}

.overlay-card h1 {
    font-family: var(--font-pixel);
    font-size: clamp(15px, 4vw, 22px);
    line-height: 1.7;
    color: var(--accent);
    margin-bottom: 8px;
}

.overlay-card .sub {
    font-family: var(--font-pixel);
    font-size: 9px;
    color: var(--text-dim);
    line-height: 1.9;
    margin-bottom: 22px;
}

.overlay-card p {
    color: var(--text-soft);
    margin-bottom: 20px;
}

/* ---- Control legend ---- */
.keys {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 10px;
    margin: 22px 0;
    text-align: left;
}

.key-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 2px solid var(--line);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.03);
}

kbd {
    display: inline-grid;
    place-items: center;
    min-width: 30px;
    height: 28px;
    padding: 0 7px;
    border-radius: 5px;
    border: 2px solid var(--line-strong);
    border-bottom-width: 4px;
    background: #1A2233;
    font-family: var(--font-pixel);
    font-size: 8px;
    color: var(--text);
}

.key-row small {
    font-family: var(--font-body);
    font-size: 17px;
    color: var(--text-soft);
}

/* ---- Buttons ---- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 50px;
    padding: 0 24px;
    border-radius: 8px;
    font-family: var(--font-pixel);
    font-size: 10px;
    letter-spacing: 0.03em;
    line-height: 1.6;
    text-align: center;
    border: 3px solid transparent;
    transition: transform var(--t-fast) var(--ease),
        box-shadow var(--t-fast) var(--ease),
        background var(--t-fast) var(--ease);
}

.btn--primary {
    background: var(--accent);
    color: var(--accent-ink);
    box-shadow: 0 5px 0 var(--accent-deep);
}

.btn--primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 7px 0 var(--accent-deep);
}

.btn--primary:active {
    transform: translateY(3px);
    box-shadow: 0 2px 0 var(--accent-deep);
}

.btn--ghost {
    border-color: var(--line-strong);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text);
}

.btn--ghost:hover {
    border-color: var(--accent);
    color: var(--accent);
}

.btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
}

.btn-row .btn {
    flex: 1 1 auto;
}

/* ================= WORLD & HERO ================= */
#world {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    z-index: 20;
    will-change: transform;
}

#hero {
    position: fixed;
    left: 200px;
    bottom: var(--ground-h);
    /* Matches the drawn sprite exactly: 24 x 40 unscaled at 2.4x. */
    width: 58px;
    height: 96px;
    z-index: 100;
    pointer-events: none;
    transition: opacity 200ms var(--ease), filter 200ms var(--ease);
    will-change: transform;
    /* Transform with jump, facing, warp scale, and giant power-up scale */
    --size: 1;
    --pipe-y: 0px;
    transform: translateY(calc((var(--jump, 0px) - var(--pipe-y, 0px)) * -1)) scale(calc(var(--warp, 1) * var(--size, 1))) scaleX(var(--face, 1));
    transform-origin: bottom center;
}

#hero.is-giant {
    --size: 1.85;
    filter: drop-shadow(0 0 16px rgba(0, 245, 160, 0.9)) drop-shadow(0 0 28px rgba(61, 220, 255, 0.75));
}

#hero.is-giant-warning {
    animation: giantBlink 180ms infinite alternate;
}

@keyframes giantBlink {
    0% { filter: drop-shadow(0 0 18px rgba(255, 77, 141, 0.95)); }
    100% { filter: drop-shadow(0 0 10px rgba(255, 183, 3, 0.9)); }
}

#hero.is-invulnerable {
    animation: invulnerableFlash 140ms infinite alternate;
}

@keyframes invulnerableFlash {
    0% { opacity: 0.25; }
    100% { opacity: 0.95; }
}

/* Sprite drawn in box-shadow pixels: no image request, scales cleanly, and
   recolours with the palette instead of fighting it. Green hoodie, dark
   trousers — the site's own colours rather than borrowed plumber red. */
#hero-sprite {
    width: 4px;
    height: 4px;
    background: transparent;
    transform: scale(2.4);
    transform-origin: top left;
    box-shadow:
        /* hair */
        8px 0 #1B2230, 12px 0 #1B2230, 16px 0 #1B2230, 20px 0 #1B2230,
        4px 4px #1B2230, 8px 4px #F0C9A0, 12px 4px #F0C9A0, 16px 4px #F0C9A0, 20px 4px #1B2230,
        /* face */
        4px 8px #F0C9A0, 8px 8px #0B0F17, 12px 8px #F0C9A0, 16px 8px #0B0F17, 20px 8px #F0C9A0,
        8px 12px #F0C9A0, 12px 12px #F0C9A0, 16px 12px #F0C9A0,
        /* hoodie */
        4px 16px #3DDC97, 8px 16px #3DDC97, 12px 16px #3DDC97, 16px 16px #3DDC97, 20px 16px #3DDC97,
        0 20px #3DDC97, 4px 20px #17A673, 8px 20px #3DDC97, 12px 20px #3DDC97, 16px 20px #17A673, 20px 20px #3DDC97,
        4px 24px #3DDC97, 8px 24px #3DDC97, 12px 24px #3DDC97, 16px 24px #3DDC97,
        /* legs */
        4px 28px #1E2A3D, 8px 28px #1E2A3D, 12px 28px #1E2A3D, 16px 28px #1E2A3D,
        4px 32px #1E2A3D, 16px 32px #1E2A3D,
        /* shoes */
        0 36px #4CC9F0, 4px 36px #4CC9F0, 16px 36px #4CC9F0, 20px 36px #4CC9F0;
}

#hero.is-walking #hero-sprite {
    animation: bob 260ms steps(2) infinite;
}

@keyframes bob {
    50% {
        margin-top: -3px;
    }
}

/* Soft contact shadow so the hero sits on the ground rather than over it */
#hero::after {
    content: '';
    position: absolute;
    bottom: -5px;
    left: 50%;
    transform: translateX(-50%);
    width: 46px;
    height: 8px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.45);
    filter: blur(3px);
}

/* ================= OBSTACLES & DECOR ================= */
.obstacle {
    position: absolute;
    bottom: var(--ground-h);
    z-index: 30;
}

.pipe {
    width: 84px;
    background: linear-gradient(90deg, var(--accent-deep) 0%, #0F7C57 45%, #0A5C40 100%);
    border: 4px solid #063827;
    border-radius: 3px;
}

.pipe::before {
    content: '';
    position: absolute;
    top: -22px;
    left: -12px;
    width: calc(100% + 24px);
    height: 22px;
    background: inherit;
    border: 4px solid #063827;
    border-radius: 4px;
}

/* Warp Pipe Indicator */
.warp-pipe {
    cursor: pointer;
}

.warp-pipe::after {
    content: '';
    position: absolute;
    top: -24px;
    left: -14px;
    width: calc(100% + 28px);
    height: 6px;
    background: linear-gradient(90deg, #00F2FE, #00F5A0);
    box-shadow: 0 0 15px rgba(0, 245, 160, 0.85);
    border-radius: 3px;
    animation: warpGlow 1.6s ease-in-out infinite alternate;
}

@keyframes warpGlow {
    0% { opacity: 0.5; filter: drop-shadow(0 0 4px #00F2FE); }
    100% { opacity: 1; filter: drop-shadow(0 0 12px #00F5A0); }
}

.warp-prompt {
    position: absolute;
    top: -64px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(5, 14, 28, 0.92);
    border: 2px solid var(--accent);
    border-radius: 6px;
    padding: 4px 8px;
    font-family: var(--font-pixel);
    font-size: 8px;
    color: #FFFFFF;
    white-space: nowrap;
    box-shadow: 0 0 15px rgba(61, 220, 255, 0.5);
    pointer-events: none;
    animation: bouncePrompt 1.2s ease-in-out infinite alternate;
    z-index: 40;
}

@keyframes bouncePrompt {
    0% { transform: translateX(-50%) translateY(0); }
    100% { transform: translateX(-50%) translateY(-6px); }
}

/* ================= ARCADE SCORE & HUD ================= */
.stat--score b {
    color: #FFB703 !important;
}
.stat--score i {
    color: #FFD166 !important;
    text-shadow: 0 0 8px rgba(255, 183, 3, 0.6);
    font-family: var(--font-pixel);
    letter-spacing: 1px;
}

/* ================= ARCADE ENEMIES ================= */
.arcade-enemy {
    position: absolute;
    bottom: var(--ground-h);
    width: 36px;
    height: 36px;
    z-index: 35;
    pointer-events: none;
    transform-origin: bottom center;
    transition: transform 0.15s ease, opacity 0.3s ease;
}

.arcade-enemy .enemy-body {
    width: 100%;
    height: 100%;
    background: #D90429;
    border: 3px solid #6A040F;
    border-radius: 14px 14px 6px 6px;
    box-shadow: 0 4px 0 #370617;
    position: relative;
}

.arcade-enemy .enemy-eyes {
    position: absolute;
    top: 8px;
    left: 4px;
    right: 4px;
    display: flex;
    justify-content: space-between;
}

.arcade-enemy .enemy-eye {
    width: 6px;
    height: 9px;
    background: #FFF;
    border: 1px solid #000;
    border-radius: 2px;
    position: relative;
}

.arcade-enemy .enemy-eye::after {
    content: '';
    position: absolute;
    bottom: 1px;
    left: 1px;
    width: 3px;
    height: 5px;
    background: #000;
    border-radius: 1px;
}

.arcade-enemy .enemy-teeth {
    position: absolute;
    bottom: 4px;
    left: 8px;
    right: 8px;
    display: flex;
    justify-content: space-between;
}

.arcade-enemy .enemy-tooth {
    width: 4px;
    height: 4px;
    background: #FFF;
    clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

.arcade-enemy .enemy-feet {
    position: absolute;
    bottom: -6px;
    left: 2px;
    right: 2px;
    display: flex;
    justify-content: space-between;
}

.arcade-enemy .enemy-foot {
    width: 12px;
    height: 6px;
    background: #2B0904;
    border-radius: 3px;
}

.arcade-enemy.walk-step-1 .enemy-feet .enemy-foot:first-child {
    transform: translateY(-3px);
}

.arcade-enemy.walk-step-2 .enemy-feet .enemy-foot:last-child {
    transform: translateY(-3px);
}

.arcade-enemy.is-stomped {
    transform: scaleY(0.2) translateY(28px) !important;
    opacity: 0 !important;
}

.arcade-enemy.is-blasted {
    transform: translateY(-180px) rotate(420deg) scale(0.6) !important;
    opacity: 0 !important;
}

/* ================= INTERACTIVE BLOCKS & BRICKS ================= */
.interactive-block {
    position: absolute;
    width: 44px;
    height: 44px;
    z-index: 32;
    border-radius: 4px;
    transition: transform 0.12s cubic-bezier(0.16, 1, 0.3, 1);
    box-shadow: 0 4px 0 rgba(0, 0, 0, 0.4);
}

.interactive-block.is-bumped {
    transform: translateY(-16px);
}

/* Mystery ? Block */
.block-mystery {
    background: linear-gradient(135deg, #FFD166 0%, #FFB703 50%, #FB8500 100%);
    border: 3px solid #6E4003;
    display: flex;
    align-items: center;
    justify-content: center;
    animation: mysteryGlow 1.8s ease-in-out infinite alternate;
}

@keyframes mysteryGlow {
    0% { filter: brightness(1) drop-shadow(0 0 4px rgba(255, 183, 3, 0.4)); }
    100% { filter: brightness(1.25) drop-shadow(0 0 14px rgba(255, 183, 3, 0.8)); }
}

.block-mystery::before {
    content: '?';
    font-family: var(--font-pixel);
    font-size: 16px;
    font-weight: bold;
    color: #432800;
    text-shadow: 1px 1px 0 #FFF;
    animation: questionBlink 1.4s steps(2) infinite;
}

@keyframes questionBlink {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.7; transform: scale(0.9); }
}

/* Empty Solid Block */
.block-mystery.is-empty {
    background: #5E503F;
    border-color: #221A12;
    animation: none;
    box-shadow: 0 3px 0 #1A130B;
}

.block-mystery.is-empty::before {
    display: none;
}

/* Breakable Brick Block */
.block-brick {
    background: #8A4F3D;
    border: 3px solid #47261B;
    background-image: 
        linear-gradient(to right, #47261B 2px, transparent 2px),
        linear-gradient(to bottom, #47261B 2px, transparent 2px);
    background-size: 20px 14px;
}

/* Shattered Brick Shard */
.brick-shard {
    position: absolute;
    width: 18px;
    height: 18px;
    background: #8A4F3D;
    border: 2px solid #47261B;
    border-radius: 2px;
    z-index: 33;
    pointer-events: none;
    animation: shardFly 0.65s cubic-bezier(0.25, 1, 0.5, 1) forwards;
}

@keyframes shardFly {
    0% { transform: translate(0, 0) rotate(0deg); opacity: 1; }
    100% { transform: translate(var(--dx, 30px), var(--dy, 80px)) rotate(540deg); opacity: 0; }
}

/* ================= SUPER MUSHROOM ================= */
.super-mushroom {
    position: absolute;
    width: 36px;
    height: 36px;
    z-index: 34;
    cursor: pointer;
    animation: mushroomEmerge 0.4s ease-out forwards;
    filter: drop-shadow(0 0 10px rgba(0, 242, 254, 0.8));
}

@keyframes mushroomEmerge {
    0% { transform: translateY(20px) scale(0.4); opacity: 0; }
    60% { transform: translateY(-8px) scale(1.1); opacity: 1; }
    100% { transform: translateY(0) scale(1); opacity: 1; }
}

.super-mushroom .shroom-cap {
    width: 36px;
    height: 22px;
    background: linear-gradient(135deg, #FF4D8D 0%, #E63946 100%);
    border: 3px solid #590D22;
    border-radius: 18px 18px 4px 4px;
    position: relative;
    overflow: hidden;
}

.super-mushroom .shroom-spot {
    position: absolute;
    background: #FFFFFF;
    border-radius: 50%;
}
.super-mushroom .spot-center {
    width: 10px;
    height: 12px;
    top: 4px;
    left: 10px;
}
.super-mushroom .spot-left {
    width: 8px;
    height: 10px;
    top: 6px;
    left: -2px;
}
.super-mushroom .spot-right {
    width: 8px;
    height: 10px;
    top: 6px;
    right: -2px;
}

.super-mushroom .shroom-stem {
    width: 20px;
    height: 14px;
    background: #FEE440;
    border: 3px solid #856E00;
    border-top: none;
    border-radius: 0 0 6px 6px;
    margin: -2px auto 0;
    position: relative;
}

.super-mushroom .shroom-eye {
    width: 3px;
    height: 6px;
    background: #000;
    position: absolute;
    top: 2px;
    border-radius: 1px;
}
.super-mushroom .shroom-eye.left { left: 4px; }
.super-mushroom .shroom-eye.right { right: 4px; }

/* ================= FLOATING SCORE POPUPS ================= */
.score-popup {
    position: absolute;
    font-family: var(--font-pixel);
    font-size: 11px;
    font-weight: bold;
    color: #FFD166;
    text-shadow: 1px 1px 0 #000, 0 0 10px rgba(255, 209, 102, 0.8);
    pointer-events: none;
    z-index: 50;
    animation: floatScore 0.85s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.score-popup.giant-popup {
    color: #00F5A0;
    font-size: 13px;
    text-shadow: 1px 1px 0 #000, 0 0 14px rgba(0, 245, 160, 0.9);
}

@keyframes floatScore {
    0% { transform: translateY(0) scale(0.7); opacity: 0; }
    20% { transform: translateY(-15px) scale(1.2); opacity: 1; }
    100% { transform: translateY(-55px) scale(1); opacity: 0; }
}

/* ================= DOWN TOUCH BUTTON ================= */
.pad-btn--down {
    background: rgba(61, 220, 255, 0.15);
    border-color: rgba(61, 220, 255, 0.4);
    color: #3DDCFF;
}
.pad-btn--down:hover, .pad-btn--down.is-down {
    background: rgba(61, 220, 255, 0.35);
    border-color: #3DDCFF;
    color: #FFFFFF;
}

.block {
    width: 210px;
    background: #16202F;
    border: 4px solid #0A121D;
    border-radius: 4px;
    background-image:
        linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px);
    background-size: 26px 26px;
}

.tower {
    background: #101825;
    border-color: #070C14;
}

.win {
    position: absolute;
    width: 34px;
    height: 40px;
    border-radius: 3px;
    background: rgba(76, 201, 240, 0.22);
    border: 3px solid #0A121D;
    box-shadow: inset 0 0 12px rgba(76, 201, 240, 0.35);
}

.win.lit {
    background: rgba(254, 188, 46, 0.3);
    box-shadow: inset 0 0 14px rgba(254, 188, 46, 0.5);
}

/* Signpost telling you what is coming, so the world is navigable by sight */
.marker {
    position: absolute;
    bottom: var(--ground-h);
    z-index: 25;
    display: flex;
    flex-direction: column;
    align-items: center;
    pointer-events: none;
}

.marker-plate {
    font-family: var(--font-pixel);
    font-size: 8px;
    letter-spacing: 0.05em;
    color: var(--accent);
    background: var(--panel-bg);
    border: 3px solid var(--accent-deep);
    border-radius: 6px;
    padding: 9px 12px;
    white-space: nowrap;
    box-shadow: var(--pixel-shadow);
}

.marker-post {
    width: 8px;
    height: 44px;
    background: linear-gradient(180deg, #2A3345, #16202F);
    border-left: 2px solid rgba(255, 255, 255, 0.12);
}

/* ================= ZONE PANELS ================= */
.zone {
    position: absolute;
    z-index: 60;
    bottom: calc(var(--ground-h) + 26px);
    display: flex;
    justify-content: center;
    /* Panels re-enable selection: an email address has to be copyable. */
    user-select: text;
    -webkit-user-select: text;
}

.panel {
    width: min(760px, 92vw);
    /* Never taller than the play area, and scrollable when it would be. */
    max-height: calc(100vh - var(--ground-h) - var(--hud-h) - 90px);
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--panel-bg);
    border: 3px solid var(--line-strong);
    border-radius: 12px;
    box-shadow: var(--pixel-shadow);
}

.panel--wide {
    width: min(980px, 94vw);
}

.panel--narrow {
    width: min(520px, 92vw);
}

.panel-head {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 13px 16px;
    background: linear-gradient(90deg, #0C6647, #0A5C40);
    border-bottom: 3px solid #063827;
    font-family: var(--font-pixel);
    font-size: 10px;
    letter-spacing: 0.04em;
    color: #EAFFF6;
}

.panel-head .idx {
    padding: 4px 7px;
    border-radius: 4px;
    background: rgba(0, 0, 0, 0.35);
    font-size: 8px;
    color: var(--accent);
}

.panel-body {
    padding: 20px;
}

.panel h3 {
    font-family: var(--font-pixel);
    font-size: 11px;
    line-height: 1.8;
    color: var(--accent);
    margin-bottom: 10px;
}

.panel p {
    color: var(--text-soft);
    margin-bottom: 14px;
}

.panel p:last-child {
    margin-bottom: 0;
}

.panel strong {
    color: var(--text);
}

/* ---- Intro signboard ---- */
.hero-card {
    display: flex;
    gap: 20px;
    align-items: center;
}

.hero-card img {
    width: 96px;
    height: 96px;
    flex-shrink: 0;
    border-radius: 10px;
    border: 3px solid var(--accent-deep);
    object-fit: cover;
    image-rendering: auto;
}

.hero-card h2 {
    font-family: var(--font-pixel);
    font-size: 13px;
    line-height: 1.8;
    margin-bottom: 8px;
}

.hero-card .role {
    font-family: var(--font-pixel);
    font-size: 8px;
    line-height: 2;
    color: var(--accent);
    margin-bottom: 12px;
}

.tag-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.tag {
    font-family: var(--font-pixel);
    font-size: 7px;
    letter-spacing: 0.04em;
    padding: 6px 8px;
    border-radius: 5px;
    border: 2px solid var(--line);
    background: rgba(255, 255, 255, 0.035);
    color: var(--text-soft);
}

.tag--on {
    border-color: var(--accent-deep);
    background: rgba(61, 220, 151, 0.12);
    color: var(--accent);
}

.tag--gov {
    border-color: rgba(76, 201, 240, 0.4);
    background: rgba(76, 201, 240, 0.12);
    color: var(--accent-2);
}

.tag--own {
    border-color: rgba(167, 139, 250, 0.4);
    background: rgba(167, 139, 250, 0.12);
    color: var(--accent-3);
}

/* ---- Stat tiles ---- */
.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
    gap: 10px;
    margin-top: 16px;
}

.tile {
    padding: 13px 10px;
    border: 2px solid var(--line);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.03);
    text-align: center;
}

.tile b {
    display: block;
    font-family: var(--font-pixel);
    font-size: 15px;
    color: var(--accent);
    font-weight: 400;
}

.tile span {
    display: block;
    margin-top: 8px;
    font-family: var(--font-pixel);
    font-size: 7px;
    line-height: 1.8;
    color: var(--text-dim);
}

/* ---- Inventory grid (stack zone) ---- */
.inv {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}

.inv-slot {
    padding: 14px;
    border: 2px solid var(--line);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.03);
}

.inv-slot h4 {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-pixel);
    font-size: 8px;
    line-height: 1.9;
    color: var(--accent-2);
    margin-bottom: 10px;
}

.inv-slot ul {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}

.inv-slot li {
    font-size: 17px;
    line-height: 1.2;
    padding: 4px 8px;
    border-radius: 5px;
    border: 1px solid var(--line);
    background: rgba(255, 255, 255, 0.03);
    color: var(--text-soft);
}

/* Proficiency is stated, not drawn as an invented percentage bar. */
.inv-slot li.max {
    border-color: var(--accent-deep);
    background: rgba(61, 220, 151, 0.13);
    color: var(--accent);
}

.legend {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin-top: 14px;
    font-size: 17px;
    color: var(--text-dim);
}

.legend span {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.swatch {
    width: 11px;
    height: 11px;
    border-radius: 3px;
    background: var(--accent);
}

.swatch--dim {
    background: #2A3345;
    border: 1px solid var(--line-strong);
}

/* ---- Quest log (experience) ---- */
.quests {
    display: grid;
    gap: 10px;
}

.quest {
    position: relative;
    padding: 14px 16px 14px 42px;
    border: 2px solid var(--line);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.03);
}

/* A ticked checkbox reads "completed" faster than any wording could */
.quest::before {
    content: '\2713';
    position: absolute;
    left: 13px;
    top: 15px;
    display: grid;
    place-items: center;
    width: 18px;
    height: 18px;
    border-radius: 4px;
    border: 2px solid var(--accent-deep);
    background: rgba(61, 220, 151, 0.12);
    color: var(--accent);
    font-size: 13px;
    line-height: 1;
}

.quest--active {
    border-color: rgba(61, 220, 151, 0.42);
    background: rgba(61, 220, 151, 0.06);
}

.quest--active::before {
    content: '\25B6';
    font-size: 9px;
    background: var(--accent);
    color: var(--accent-ink);
}

.q-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 3px;
}

.q-title {
    font-family: var(--font-pixel);
    font-size: 9px;
    line-height: 1.8;
    color: var(--text);
}

.q-when {
    font-family: var(--font-pixel);
    font-size: 7px;
    color: var(--accent);
    margin-left: auto;
}

.q-org {
    display: block;
    font-size: 18px;
    color: var(--text-soft);
    margin-bottom: 6px;
}

.quest p {
    font-size: 18px;
    color: var(--text-dim);
    margin-bottom: 8px;
}

.q-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}

.q-tags span {
    font-size: 15px;
    padding: 2px 7px;
    border-radius: 4px;
    border: 1px solid var(--line);
    color: var(--text-dim);
}

.earlier {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 2px dashed var(--line);
}

.earlier h4 {
    font-family: var(--font-pixel);
    font-size: 8px;
    color: var(--text-dim);
    margin-bottom: 10px;
}

.earlier li {
    position: relative;
    padding: 0 92px 8px 0;
    margin-bottom: 8px;
    border-bottom: 1px solid var(--line);
    font-size: 18px;
    color: var(--text-soft);
}

.earlier li:last-child {
    border-bottom: 0;
    margin-bottom: 0;
}

.earlier li b {
    color: var(--text);
}

.earlier li i {
    position: absolute;
    right: 0;
    top: 2px;
    font-style: normal;
    font-family: var(--font-pixel);
    font-size: 7px;
    color: var(--accent);
}

/* ---- Loot / project gallery ---- */
.filters {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}

.filter-btn {
    min-height: 40px;
    padding: 0 14px;
    border-radius: 6px;
    border: 2px solid var(--line-strong);
    background: rgba(255, 255, 255, 0.03);
    color: var(--text-soft);
    font-family: var(--font-pixel);
    font-size: 8px;
    letter-spacing: 0.04em;
    transition: color var(--t-fast) var(--ease),
        border-color var(--t-fast) var(--ease),
        background var(--t-fast) var(--ease);
}

.filter-btn:hover {
    color: var(--accent);
    border-color: var(--accent-deep);
}

.filter-btn[aria-pressed="true"] {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-ink);
}

.loot {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px;
}

.loot-item {
    display: flex;
    flex-direction: column;
    gap: 9px;
    padding: 14px;
    border: 2px solid var(--line);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.03);
    transition: transform var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}

.loot-item:hover {
    transform: translateY(-3px);
    border-color: var(--accent-deep);
}

.loot-item[hidden] {
    display: none;
}

.loot-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.loot-mark {
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    flex-shrink: 0;
    border-radius: 8px;
    border: 2px solid var(--line);
    background: rgba(255, 255, 255, 0.05);
    color: var(--accent);
    font-size: 17px;
    overflow: hidden;
}

.loot-mark img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    padding: 5px;
}

.loot-item h4 {
    font-family: var(--font-pixel);
    font-size: 9px;
    line-height: 1.8;
}

.loot-item .sub {
    font-size: 16px;
    color: var(--text-dim);
}

.loot-item p {
    font-size: 17px;
    color: var(--text-soft);
    margin-bottom: 0;
}

.loot-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: auto;
}

.loot-tags span {
    font-size: 14px;
    padding: 2px 6px;
    border-radius: 4px;
    border: 1px solid var(--line);
    color: var(--text-dim);
}

.loot-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    min-height: 40px;
    padding: 0 12px;
    border-radius: 6px;
    border: 2px solid var(--accent-deep);
    background: rgba(61, 220, 151, 0.1);
    color: var(--accent);
    font-family: var(--font-pixel);
    font-size: 8px;
    transition: background var(--t-fast) var(--ease);
}

.loot-link:hover {
    background: rgba(61, 220, 151, 0.22);
}

.loot-link--play {
    border-color: #3DDCFF;
    background: rgba(61, 220, 255, 0.12);
    color: #3DDCFF;
}

.loot-link--play:hover {
    background: rgba(61, 220, 255, 0.25);
    box-shadow: 0 0 10px rgba(61, 220, 255, 0.3);
}

.loot-locked {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-pixel);
    font-size: 7px;
    color: var(--text-dim);
}

/* ---- Education ---- */
.certs {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}

.cert {
    display: flex;
    flex-direction: column;
    padding: 14px;
    border: 2px solid var(--line);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.03);
}

.cert h4 {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    font-family: var(--font-pixel);
    font-size: 8px;
    line-height: 1.9;
    color: var(--text);
    margin-bottom: 7px;
}

.cert h4 i {
    color: var(--accent-2);
    font-size: 13px;
    flex-shrink: 0;
    margin-top: 1px;
}

.cert .org {
    font-size: 17px;
    color: var(--text-soft);
}

.cert .note {
    font-size: 16px;
    color: var(--text-dim);
    margin-top: 5px;
}

.cert .when {
    margin-top: auto;
    padding-top: 12px;
    font-family: var(--font-pixel);
    font-size: 7px;
    color: var(--accent);
}

.langs {
    display: grid;
    gap: 5px;
    margin-top: 8px;
}

.langs li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    font-size: 18px;
    color: var(--text-soft);
}

.langs li [lang="ja"] {
    font-size: 20px;
}

.langs em {
    font-style: normal;
    font-family: var(--font-pixel);
    font-size: 6px;
    letter-spacing: 0.05em;
    color: var(--text-dim);
    white-space: nowrap;
}

/* ---- Contact ---- */
.contact-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
}

.field {
    margin-bottom: 12px;
}

.field label {
    display: block;
    font-family: var(--font-pixel);
    font-size: 7px;
    letter-spacing: 0.05em;
    color: var(--text-dim);
    margin-bottom: 6px;
}

.field input,
.field textarea {
    width: 100%;
    /* 16px floor stops iOS zooming the viewport on focus, which would break
       the fixed-camera layout completely. */
    font-size: 16px;
    font-family: var(--font-body);
    padding: 11px 12px;
    color: var(--text);
    background: rgba(255, 255, 255, 0.04);
    border: 2px solid var(--line-strong);
    border-radius: 6px;
    resize: vertical;
}

.field textarea {
    min-height: 92px;
}

.field input:focus,
.field textarea:focus {
    outline: none;
    border-color: var(--accent);
    background: rgba(61, 220, 151, 0.05);
}

.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
    border-color: var(--danger);
}

/* Error sits under its own field, never collected at the top of the form */
.err {
    display: block;
    margin-top: 5px;
    font-family: var(--font-pixel);
    font-size: 7px;
    line-height: 1.8;
    color: var(--danger);
}

.err:empty {
    display: none;
}

@keyframes shake {

    10%,
    90% {
        transform: translateX(-1px);
    }

    20%,
    80% {
        transform: translateX(2px);
    }

    30%,
    50%,
    70% {
        transform: translateX(-4px);
    }

    40%,
    60% {
        transform: translateX(4px);
    }
}

.shake {
    animation: shake 400ms cubic-bezier(.36, .07, .19, .97) both;
}

.links {
    display: grid;
    gap: 9px;
    align-content: start;
}

.link-btn {
    display: flex;
    align-items: center;
    gap: 11px;
    min-height: 50px;
    padding: 0 14px;
    border-radius: 8px;
    border: 2px solid var(--line-strong);
    background: rgba(255, 255, 255, 0.03);
    color: var(--text);
    font-family: var(--font-pixel);
    font-size: 8px;
    line-height: 1.7;
    transition: border-color var(--t-fast) var(--ease),
        background var(--t-fast) var(--ease),
        transform var(--t-fast) var(--ease);
}

.link-btn i {
    color: var(--accent);
    font-size: 15px;
    width: 20px;
    text-align: center;
    flex-shrink: 0;
}

.link-btn:hover {
    border-color: var(--accent-deep);
    background: rgba(61, 220, 151, 0.08);
    transform: translateX(3px);
}

/* ---- Balloon ---- */
#balloon {
    position: absolute;
    bottom: var(--ground-h);
    width: 150px;
    height: 190px;
    /* Below the zone panels: while you're reading, the panel is the subject
       and the balloon is scenery. */
    z-index: 10;
    pointer-events: none;
}

.balloon-envelope {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 120px;
    height: 132px;
    border-radius: 50% 50% 46% 46% / 62% 62% 38% 38%;
    background:
        linear-gradient(90deg,
            var(--accent-deep) 0 25%,
            var(--accent) 25% 50%,
            var(--accent-2) 50% 75%,
            var(--accent-deep) 75% 100%);
    border: 3px solid #063827;
    box-shadow: inset -12px -8px 22px rgba(0, 0, 0, 0.35);
}

.balloon-basket {
    position: absolute;
    bottom: 6px;
    left: 50%;
    transform: translateX(-50%);
    width: 54px;
    height: 38px;
    border-radius: 4px 4px 8px 8px;
    background: repeating-linear-gradient(90deg, #6B4A2A 0 6px, #5A3D22 6px 12px);
    border: 3px solid #3B2715;
}

/* Passenger: head and shoulders above the basket rim, in the same palette as
   the walking sprite so it's recognisably the same character. */
.balloon-rider {
    position: absolute;
    bottom: 46px;
    left: 50%;
    width: 4px;
    height: 4px;
    margin-left: -13px;
    background: transparent;
    box-shadow:
        4px 0 #1B2230, 8px 0 #1B2230, 12px 0 #1B2230,
        0 4px #1B2230, 4px 4px #F0C9A0, 8px 4px #F0C9A0, 12px 4px #1B2230,
        4px 8px #F0C9A0, 8px 8px #F0C9A0,
        0 12px #3DDC97, 4px 12px #3DDC97, 8px 12px #3DDC97, 12px 12px #3DDC97;
    transform: scale(1.5);
    transform-origin: bottom center;
}

.balloon-rope {
    position: absolute;
    bottom: 42px;
    left: 50%;
    transform: translateX(-50%);
    width: 46px;
    height: 26px;
    border-left: 3px solid #3B2715;
    border-right: 3px solid #3B2715;
}

.balloon-float {
    position: absolute;
    inset: 0;
    animation: float 3.4s ease-in-out infinite;
}

@keyframes float {

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

    50% {
        transform: translateY(-9px);
    }
}

/* ---- Finish flag ---- */
.flag {
    position: absolute;
    bottom: var(--ground-h);
    z-index: 30;
    width: 8px;
    height: 190px;
    background: linear-gradient(180deg, #3A4557, #1A2233);
}

.flag::after {
    content: '';
    position: absolute;
    top: 8px;
    left: 8px;
    width: 62px;
    height: 42px;
    background: var(--accent);
    clip-path: polygon(0 0, 100% 22%, 0 44%, 0 0);
}

/* ================= TOUCH CONTROLS =================
   Pointer Events, not touch events, so the same buttons work under a mouse,
   a stylus and a finger. The old build bound touchstart only, which meant the
   on-screen pad did nothing at all on a laptop.
   ================================================== */
#pad {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 700;
    display: none;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
    padding: 0 max(16px, env(safe-area-inset-left)) max(18px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-right));
    pointer-events: none;
}

#pad.is-on {
    display: flex;
}

.pad-group {
    display: flex;
    gap: 12px;
    pointer-events: auto;
}

.pad-btn {
    display: grid;
    place-items: center;
    /* Comfortably past the 44px floor — this is the primary control */
    width: 66px;
    height: 66px;
    border-radius: 14px;
    border: 3px solid var(--line-strong);
    background: rgba(10, 15, 24, 0.72);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    color: var(--text);
    font-size: 21px;
    touch-action: none;
}

.pad-btn--jump {
    width: 92px;
    font-family: var(--font-pixel);
    font-size: 9px;
    border-color: var(--accent-deep);
    background: rgba(61, 220, 151, 0.16);
    color: var(--accent);
}

.pad-btn.is-down {
    background: rgba(61, 220, 151, 0.4);
    color: var(--accent-ink);
    transform: scale(0.94);
}

/* Only lift the panels when the thumb pad is actually on screen. */
body.has-pad .zone {
    bottom: calc(var(--ground-h) + 100px);
}

body.has-pad .panel {
    max-height: calc(100vh - var(--ground-h) - var(--hud-h) - 156px);
}

body.has-pad .hint {
    bottom: calc(var(--ground-h) + 104px);
}

/* ---- First-run nudge ---- */
.hint {
    position: fixed;
    left: 50%;
    bottom: calc(var(--ground-h) + 26px);
    transform: translateX(-50%);
    z-index: 500;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 16px;
    border-radius: 999px;
    border: 2px solid var(--accent-deep);
    background: rgba(10, 15, 24, 0.9);
    font-family: var(--font-pixel);
    font-size: 8px;
    color: var(--accent);
    white-space: nowrap;
    transition: opacity var(--t-mid) var(--ease);
}

.hint[hidden] {
    display: none;
}

.hint.is-fading {
    opacity: 0;
}

.hint i {
    animation: nudge 1.1s ease-in-out infinite;
}

@keyframes nudge {

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

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

/* ---- Live region for zone announcements (screen readers) ---- */
.announce {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
}

/* ================= RESPONSIVE ================= */
@media (max-width: 1024px) {
    .rail-mark span {
        display: none;
    }

    .rail {
        height: 26px;
    }
}

@media (max-width: 860px) {
    :root {
        --hud-h: 54px;
    }

    .inv,
    .certs {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .hud-stats .stat:nth-child(n+3) {
        display: none;
    }

    .contact-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 600px) {
    :root {
        --ground-h: 62px;
    }

    body {
        font-size: 19px;
    }

    .hud {
        gap: 10px;
        padding-block: 8px;
    }

    .hud-name {
        display: none;
    }

    .hud-stats {
        display: none;
    }

    .panel-body {
        padding: 14px;
    }

    .hero-card {
        flex-direction: column;
        text-align: center;
        align-items: center;
    }

    .inv,
    .certs,
    .loot {
        grid-template-columns: minmax(0, 1fr);
    }

    #hero {
        left: 42px;
    }

    .marker-plate {
        font-size: 7px;
    }

    .overlay-card {
        padding: 24px 18px;
    }
}

/* ================= REDUCED MOTION =================
   The world still moves — it has to, it is the navigation — but every purely
   decorative loop stops, and fast-travel jumps instead of gliding.
   ================================================== */
@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }

    .balloon-float,
    #hero.is-walking #hero-sprite,
    .hint i {
        animation: none !important;
    }
}

/* ================= PORTAL =================
   Spawned in front of the character when PLAY AGAIN is pressed. Screen-fixed
   rather than world-placed: at the end zone the camera is already clamped, so
   the character walks across the screen into it instead of the world scrolling.
   ========================================== */
#portal {
    position: fixed;
    bottom: var(--ground-h);
    /* Above the world and its panels, below the start overlay (1500). */
    z-index: 1200;
    width: 128px;
    height: 172px;
    pointer-events: none;
    transform: scale(0.1);
    opacity: 0;
    transition: transform 420ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 260ms var(--ease);
}

#portal[hidden] {
    display: none;
}

#portal.is-open {
    transform: scale(1);
    opacity: 1;
}

/* Outer ring — a conic sweep through the site's three accents, rotating */
.portal-ring {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: conic-gradient(from 0deg,
            var(--accent) 0deg,
            var(--accent-2) 90deg,
            var(--accent-3) 180deg,
            var(--accent-2) 270deg,
            var(--accent) 360deg);
    /* Ring, not disc: punch the middle out so the core shows through */
    -webkit-mask: radial-gradient(closest-side, transparent 66%, #000 68%);
    mask: radial-gradient(closest-side, transparent 66%, #000 68%);
    animation: portal-spin 2.6s linear infinite;
    filter: drop-shadow(0 0 14px rgba(61, 220, 151, 0.6));
}

/* Inner void, pulsing so it reads as active rather than painted on */
.portal-core {
    position: absolute;
    inset: 12%;
    border-radius: 50%;
    background:
        radial-gradient(circle at 50% 45%,
            rgba(167, 139, 250, 0.55) 0%,
            rgba(76, 201, 240, 0.35) 35%,
            rgba(7, 10, 16, 0.95) 72%);
    box-shadow: inset 0 0 30px rgba(61, 220, 151, 0.5);
    animation: portal-pulse 1.5s ease-in-out infinite;
}

/* Ground glow under the mouth */
.portal-spark {
    position: absolute;
    left: 50%;
    bottom: -8px;
    width: 150px;
    height: 22px;
    margin-left: -75px;
    border-radius: 50%;
    background: radial-gradient(ellipse, rgba(61, 220, 151, 0.55), transparent 70%);
    filter: blur(4px);
    animation: portal-pulse 1.5s ease-in-out infinite;
}

@keyframes portal-spin {
    to {
        transform: rotate(360deg);
    }
}

@keyframes portal-pulse {

    0%,
    100% {
        opacity: 0.75;
        transform: scale(1);
    }

    50% {
        opacity: 1;
        transform: scale(1.06);
    }
}

/* While the portal sequence runs, the panel you just pressed the button on
   steps out of the way — otherwise the character walks behind a wall of text. */
body.is-warping .zone,
body.is-warping .marker {
    opacity: 0;
    transition: opacity 320ms var(--ease);
    pointer-events: none;
}

/* ---- Warp flash ---- */
#flash {
    position: fixed;
    inset: 0;
    z-index: 1400;
    pointer-events: none;
    opacity: 0;
    background: radial-gradient(circle at center, #EAFFF6 0%, var(--accent) 45%, rgba(7, 10, 16, 0) 78%);
    transition: opacity 220ms var(--ease);
}

#flash.is-on {
    opacity: 1;
}

/* The character is scaled and faded frame-by-frame in JS rather than by a CSS
   transition, because its transform is rewritten every frame by the game loop
   and a transition on that would fight the camera. */

/* ================= ZONE SHEET =================
   The rail is a good desktop control and a bad phone one: at 320px its eight
   markers sit 2px apart with 44px hit areas stacked on top of each other. On
   small screens the markers are hidden, the bar stays as a progress readout,
   and this sheet takes over the jumping.
   ============================================== */
.icon-btn--zones {
    display: none;
    width: auto;
    min-width: 44px;
    gap: 7px;
    padding-inline: 10px;
}

.zone-count {
    font-family: var(--font-pixel);
    font-size: 8px;
    color: var(--accent);
}

.sheet {
    position: fixed;
    inset: 0;
    z-index: 1600;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgba(4, 6, 10, 0.72);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

.sheet[hidden] {
    display: none;
}

.sheet-panel {
    width: min(520px, 100%);
    max-height: 82dvh;
    display: flex;
    flex-direction: column;
    border: 3px solid var(--accent-deep);
    border-bottom: 0;
    border-radius: 16px 16px 0 0;
    background: var(--panel-bg);
    padding-bottom: env(safe-area-inset-bottom);
    animation: sheet-up 260ms var(--ease);
}

@keyframes sheet-up {
    from {
        transform: translateY(100%);
    }
}

.sheet-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 14px 12px;
    border-bottom: 2px solid var(--line);
}

.sheet-head h2 {
    font-family: var(--font-pixel);
    font-size: 10px;
    color: var(--accent);
}

.sheet-list {
    overflow-y: auto;
    padding: 10px;
    display: grid;
    gap: 8px;
}

.sheet-row {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    /* Comfortably past the 44px floor — this is the primary way to navigate */
    min-height: 56px;
    padding: 0 14px;
    border-radius: 10px;
    border: 2px solid var(--line);
    background: rgba(255, 255, 255, 0.03);
    color: var(--text);
    text-align: left;
}

.sheet-row b {
    font-family: var(--font-pixel);
    font-size: 9px;
    color: var(--text-dim);
    font-weight: 400;
    min-width: 22px;
}

.sheet-row span {
    font-family: var(--font-pixel);
    font-size: 9px;
    line-height: 1.6;
}

.sheet-row i {
    margin-left: auto;
    color: var(--accent);
    font-size: 13px;
    opacity: 0;
}

.sheet-row[aria-current="true"] {
    border-color: var(--accent-deep);
    background: rgba(61, 220, 151, 0.1);
}

.sheet-row[aria-current="true"] i,
.sheet-row.is-passed i {
    opacity: 1;
}

.sheet-row.is-passed i {
    color: var(--accent-deep);
}

/* ================= MOBILE PASS =================
   Measured on real device metrics (320/375/390/412 portrait and 844x390
   landscape), not guessed from breakpoints.
   =============================================== */

/* Every interactive thing clears 44px once there's a finger on the screen
   rather than a cursor. On desktop the tighter sizes are kept. */
@media (hover: none) and (pointer: coarse) {

    .filter-btn,
    .loot-link,
    .link-btn,
    .rail-mark {
        min-height: 44px;
    }

    .skip-link {
        padding: 16px 18px;
    }

    .hud-brand {
        min-height: 44px;
        min-width: 44px;
        justify-content: center;
    }

    .icon-btn {
        min-height: 44px;
    }

    /* 42px at the default padding — under the floor by a hair */
    .field input,
    .field textarea {
        min-height: 46px;
    }
}

/* Below 700px the rail becomes a read-only progress bar and the sheet takes
   over navigation. Its markers were 2-9px apart here — untappable. */
@media (max-width: 700px) {
    .rail-mark {
        display: none;
    }

    .rail {
        padding-inline: 0;
        height: 12px;
        flex: 1;
    }

    .rail-track {
        left: 0;
        right: 0;
    }

    .icon-btn--zones {
        display: flex;
    }
}

@media (max-width: 600px) {

    /* 100vh is the *largest* viewport on mobile browsers, so a panel measured
       against it overflows whenever the URL bar is showing. dvh tracks the
       viewport that is actually visible. */
    .panel {
        max-height: calc(100dvh - var(--ground-h) - var(--hud-h) - 96px);
    }

    body.has-pad .panel {
        max-height: calc(100dvh - var(--ground-h) - var(--hud-h) - 168px);
    }

    :root {
        /* Matches the measured HUD height, so the panel maths is honest */
        --hud-h: 60px;
    }
}

/* ---- Landscape phones ----
   At 844x390 the quest panel came out 106px tall, which is unreadable. The
   HUD and pad give back their padding so the panel can have the room. */
@media (orientation: landscape) and (max-height: 460px) {
    :root {
        --ground-h: 44px;
        --hud-h: 50px;
    }

    .hud {
        padding-block: 5px;
    }

    .hud-stats {
        display: none;
    }

    .panel {
        max-height: calc(100dvh - var(--ground-h) - var(--hud-h) - 22px);
    }

    body.has-pad .panel {
        max-height: calc(100dvh - var(--ground-h) - var(--hud-h) - 38px);
    }

    .zone {
        bottom: calc(var(--ground-h) + 10px);
    }

    body.has-pad .zone {
        bottom: calc(var(--ground-h) + 26px);
    }

    .panel--wide,
    .panel {
        width: min(620px, 62vw);
    }

    .pad-btn {
        width: 56px;
        height: 56px;
        font-size: 18px;
    }

    .pad-btn--jump {
        width: 76px;
        font-size: 8px;
    }

    #pad {
        padding-bottom: max(6px, env(safe-area-inset-bottom));
    }

    .scroll-cue,
    .hint {
        display: none;
    }
}

/* ================= WARP DESTINATION MODAL ================= */
.warp-dialog {
    max-width: 520px;
    border-color: #00F2FE;
    box-shadow: 0 0 35px rgba(0, 242, 254, 0.35), var(--pixel-shadow);
}

.warp-grid {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 16px 0;
}

.warp-dest-btn {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    border-radius: 8px;
    border: 2px solid rgba(0, 242, 254, 0.35);
    background: rgba(0, 242, 254, 0.08);
    color: var(--text);
    cursor: pointer;
    text-align: left;
    transition: all var(--t-fast) var(--ease);
}

.warp-dest-btn:hover, .warp-dest-btn:focus-visible {
    border-color: #00F2FE;
    background: rgba(0, 242, 254, 0.22);
    box-shadow: 0 0 16px rgba(0, 242, 254, 0.45);
    transform: translateX(4px);
}

.dest-badge {
    padding: 4px 8px;
    border-radius: 4px;
    background: #00F2FE;
    color: #040810;
    font-family: var(--font-pixel);
    font-size: 8px;
    font-weight: bold;
}

.dest-info {
    flex: 1;
}

.dest-info strong {
    display: block;
    font-family: var(--font-pixel);
    font-size: 10px;
    color: #00F5A0;
    margin-bottom: 2px;
}

.dest-info small {
    display: block;
    color: var(--text-dim);
    font-size: 11px;
}

.warp-dest-btn i {
    color: var(--neon-cyan);
    font-size: 14px;
}

/* ================= CYBER CLOUD FOR GIANT MODE ================= */
#cyber-cloud {
    position: absolute;
    width: 200px;
    height: 70px;
    z-index: 95;
    pointer-events: none;
    animation: cloudBob 2.6s ease-in-out infinite alternate;
}

@keyframes cloudBob {
    0% { transform: translateY(0px) rotate(0deg); }
    50% { transform: translateY(-16px) rotate(1.5deg); }
    100% { transform: translateY(-28px) rotate(-1deg); }
}

.cloud-body {
    position: relative;
    width: 100%;
    height: 100%;
    filter: drop-shadow(0 0 20px rgba(0, 242, 254, 0.9)) drop-shadow(0 0 35px rgba(255, 214, 10, 0.75));
}

.cloud-puff {
    position: absolute;
    background: linear-gradient(180deg, #FFFFFF 0%, #E0F7FF 40%, #70D6FF 100%);
    border: 3px solid #005F73;
    border-radius: 50%;
    box-shadow: inset 0 -6px 12px rgba(0, 119, 182, 0.45);
}

.puff-1 {
    width: 70px;
    height: 70px;
    left: 8px;
    bottom: 0;
}

.puff-2 {
    width: 96px;
    height: 96px;
    left: 48px;
    bottom: 4px;
}

.puff-3 {
    width: 76px;
    height: 76px;
    right: 12px;
    bottom: 0;
}

.puff-4 {
    width: 50px;
    height: 50px;
    left: 130px;
    bottom: 12px;
}

/* Glowing deck where Giant stands */
.cloud-deck {
    position: absolute;
    top: -4px;
    left: 30px;
    right: 30px;
    height: 8px;
    background: linear-gradient(90deg, transparent, #FFD166, #00F5A0, transparent);
    border-radius: 4px;
    box-shadow: 0 0 12px #FFD166;
}

.cloud-aura {
    position: absolute;
    bottom: -12px;
    left: 15px;
    right: 15px;
    height: 20px;
    background: radial-gradient(ellipse at center, rgba(0, 245, 160, 0.9), rgba(0, 242, 254, 0.6), transparent);
    filter: blur(6px);
    border-radius: 50%;
}

.cloud-lightning {
    position: absolute;
    top: -16px;
    right: 28px;
    font-size: 20px;
    color: #FFD166;
    text-shadow: 0 0 12px #FFD166, 0 0 24px #FFB703;
    animation: lightningSpark 0.7s steps(2) infinite alternate;
}

@keyframes lightningSpark {
    0% { opacity: 0.3; transform: scale(0.85) rotate(-10deg); }
    100% { opacity: 1; transform: scale(1.35) rotate(10deg); }
}

/* ================= IN-PIPE TRANSIT & PEEK HUD ================= */
.pipe-transit-hud {
    position: fixed;
    bottom: calc(var(--ground-h) + 140px);
    left: 50%;
    transform: translateX(-50%);
    background: rgba(4, 9, 20, 0.94);
    border: 2px solid #00F2FE;
    border-radius: 12px;
    padding: 12px 20px;
    box-shadow: 0 0 25px rgba(0, 242, 254, 0.6), 0 8px 30px rgba(0, 0, 0, 0.8);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    z-index: 200;
    pointer-events: auto;
    animation: peekHudPulse 1.4s ease-in-out infinite alternate;
}

@keyframes peekHudPulse {
    0% { box-shadow: 0 0 15px rgba(0, 242, 254, 0.4); }
    100% { box-shadow: 0 0 30px rgba(0, 245, 160, 0.8); }
}

.transit-title {
    font-family: var(--font-pixel);
    font-size: 10px;
    color: #00F5A0;
    letter-spacing: 0.5px;
    display: flex;
    align-items: center;
    gap: 6px;
}

.transit-controls-row {
    display: flex;
    align-items: center;
    gap: 12px;
}

.transit-btn {
    padding: 6px 14px;
    border-radius: 6px;
    border: 2px solid var(--accent);
    background: rgba(61, 220, 151, 0.15);
    color: #FFFFFF;
    font-family: var(--font-pixel);
    font-size: 9px;
    cursor: pointer;
    transition: all 0.15s ease;
}

.transit-btn:hover {
    background: var(--accent);
    color: #000000;
    box-shadow: 0 0 12px var(--accent);
}

.transit-emerge-btn {
    background: linear-gradient(135deg, #00F2FE, #00F5A0);
    border-color: #00F5A0;
    color: #040810;
    font-weight: bold;
}

.transit-emerge-btn:hover {
    background: #FFFFFF;
    color: #000000;
    box-shadow: 0 0 18px #00F5A0;
}

/* Glowing beam above the peeking destination pipe */
.warp-pipe.is-peeking::before {
    box-shadow: 0 0 25px #00F5A0, 0 -15px 40px #00F2FE;
    filter: brightness(1.4);
}

.warp-pipe.is-peeking::after {
    height: 14px;
    background: linear-gradient(90deg, #FFD166, #00F5A0, #00F2FE);
    box-shadow: 0 0 25px rgba(0, 245, 160, 1);
    animation: peekPipeGlow 0.6s infinite alternate;
}

@keyframes peekPipeGlow {
    0% { transform: scaleY(1); filter: brightness(1); }
    100% { transform: scaleY(1.8); filter: brightness(1.6); }
}

/* Screen shake for brick crush */
#world.is-shaking {
    animation: screenShake 0.18s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

@keyframes screenShake {
    10%, 90% { transform: translate3d(-3px, 1px, 0); }
    20%, 80% { transform: translate3d(3px, -2px, 0); }
    30%, 50%, 70% { transform: translate3d(-4px, 2px, 0); }
    40%, 60% { transform: translate3d(4px, -1px, 0); }
}
