html, body {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
    background: #150b07;
    color: #f2ece3;
    font-family: system-ui, -apple-system, sans-serif;
    overflow: hidden;
    touch-action: none;
}

/* Author `display` values override the UA's [hidden] rule — without
   this the game div can cover the page while "hidden" (the launch
   black-screen bug). The site-select landing screen was removed
   2026-07-09 — boot goes straight into the sim. */
#game-root[hidden] {
    display: none !important;
}

#game-root {
    position: relative;
    width: 100vw;
    height: 100vh;
}

#mc-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    /* Plan 26: subtle cinematic colour grade (screen-space, same canvas-filter
       route as night vision — this project has no EffectComposer by design).
       A light contrast/saturation lift + a hair of warmth. Kept gentle so the
       real-DEM Mars palette still reads true. NV's #mc-canvas.is-nv rule has
       higher specificity and fully replaces this filter, so the two never mix. */
    filter: saturate(1.09) contrast(1.05) brightness(1.02);
}

/* Plan 26: cinematic vignette — focuses the frame, sits above the canvas and
   below the HUD, and is pointer-transparent so it never blocks controls. */
#mc-vignette {
    position: absolute;
    inset: 0;
    z-index: 5;
    pointer-events: none;
    background: radial-gradient(ellipse 82% 82% at 50% 46%,
            transparent 58%, rgba(18, 7, 3, 0.32) 100%);
}

/* ---- Night vision (Wave 9.7) ----
   An image intensifier, done as a CSS filter on the canvas rather than a
   post-processing pass: this project has no EffectComposer (effects.js is
   blob shadows + dust + tracks, deliberately unlit fakes), and adding a
   whole render-target pipeline to tint the frame would be a heavy way to
   pay for one toggle. Filtering the canvas ELEMENT also leaves the HUD
   untouched — telemetry and the minimap stay legible in their own colours,
   which is what a real NVG rig does too (the optic is intensified, the
   instruments are not).

   Chain: strip the Mars rust (grayscale) -> lift the black night floor
   (brightness) -> re-tint to phosphor green (sepia + hue-rotate + saturate).
   The lift IS the gameplay: at daylight() = 0 the terrain sits around 12/255
   and this is what makes it navigable.

   NO contrast() in the chain. It was there and it silently defeated the
   whole feature: contrast maps v -> (v - 0.5) * c + 0.5, so at 1.15 a lifted
   night pixel (0.067) lands back at 0.002 — blacker than it started. Caught
   by measuring pixels, not by reading the computed style.

   --nv-gain is the tube's automatic gain control, driven from env.daylight()
   by main.js: wide open in the dark, stopped down in daylight so a player who
   leaves NV on at noon gets a bright green view, not a white blowout. Real
   intensifiers do exactly this. */
#mc-canvas.is-nv {
    filter: grayscale(1) brightness(var(--nv-gain, 8)) sepia(1) hue-rotate(62deg) saturate(3.6);
}

/* Scanlines + tube vignette over the (filtered) image, under the HUD. Sells
   the optic and hides how flat a brightness-lifted night actually is. */
.mars-hud__nv-overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background:
        repeating-linear-gradient(to bottom,
            rgba(120, 255, 170, 0.05) 0 1px,
            rgba(0, 0, 0, 0.10) 1px 3px),
        radial-gradient(ellipse at center,
            rgba(0, 0, 0, 0) 42%,
            rgba(0, 20, 6, 0.55) 78%,
            rgba(0, 12, 4, 0.9) 100%);
}

.mars-hud__nv-overlay[data-visible="false"] {
    display: none;
}

/* The top-bar NV button is a DESKTOP affordance. Measured at 390px: the bar
   already runs SWITCH UNIT + unit label + MENU + SFX to 335px of the 366px
   available, and a fifth button pushed SFX off the screen entirely (to
   407px). Phones toggle night vision from the menu instead — the same one
   switch, two taps. A proper mobile home for it comes with Wave 10's HUD
   reshuffle. */
/* .mars-btn--nv alone ties .mars-btn on specificity and loses on cascade
   order (the base button rule is declared later), so the hide must outrank
   it — scope both rules to the bar. */
.mars-hud__top .mars-btn--nv {
    display: none;
}

@media (min-width: 900px) {
    .mars-hud--desktop .mars-hud__top .mars-btn--nv {
        display: flex;
    }
}

/* Wave 10 carry-over: landscape phones have bar room the 390px portrait
   bar never did — NV gets its mobile home there. Portrait keeps the
   menu-only path (and the rotate prompt pushes landscape anyway). */
@media (orientation: landscape) and (pointer: coarse) and (min-width: 700px) {
    .mars-hud__top .mars-btn--nv {
        display: flex;
    }
}

/* Wave 10.1 (#13): phones play landscape. screen.orientation.lock() is
   unsupported on iOS Safari and fullscreen-gated elsewhere, so the
   dependable path is this CSS-only prompt: portrait touch viewports get
   a dimmed rotate card that blocks input; rotating the phone hides it
   with no JS involved. */
.mars-hud__rotate {
    display: none;
    position: absolute;
    inset: 0;
    z-index: 40;
    background: rgba(10, 6, 4, 0.88);
    align-items: center;
    justify-content: center;
    text-align: center;
    pointer-events: auto;
}

@media (orientation: portrait) and (pointer: coarse) and (max-width: 899px) {
    .mars-hud__rotate {
        display: flex;
    }
}

.mars-hud__rotate-card b {
    display: block;
    letter-spacing: 0.14em;
    font-size: 0.95rem;
    color: #e0b95e;
}

.mars-hud__rotate-card p {
    margin: 8px 0 0;
    font-size: 0.75rem;
    opacity: 0.75;
}

.mars-hud__rotate-glyph {
    font-size: 2.4rem;
    line-height: 1;
    margin-bottom: 10px;
    color: #2ec4d6;
}

/* Wave 10.4: top-bar OVERLAYS dropdown — desktop-only fast path to the
   menu's SCIENCE OVERLAYS plus a live sample tally (the menu section
   stays; redundant access is deliberate, same as GEAR/dronectl). Hidden
   on phones: the 390px bar is already full (see the NV note above). */
.mars-hud__drop {
    position: relative;
    display: none;
}

@media (min-width: 900px) {
    .mars-hud--desktop .mars-hud__drop {
        display: block;
    }
}

.mars-hud__drop-panel {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    min-width: 200px;
    background: rgba(20, 12, 8, 0.92);
    border: 1px solid #7a4f30;
    border-radius: 8px;
    padding: 10px 12px;
    pointer-events: auto;
    z-index: 25;
}

.mars-hud__drop-panel[data-open="true"] {
    display: block;
}

.mars-hud__drop-title {
    font-size: 0.58rem;
    letter-spacing: 0.14em;
    opacity: 0.6;
    margin-bottom: 6px;
}

.mars-hud__drop-modes {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.mars-hud__drop-modes .mars-btn {
    padding: 6px 10px;
    font-size: 0.7rem;
}

.mars-hud__drop-modes .mars-btn.is-active {
    border-color: #e0b95e;
    color: #e0b95e;
}

.mars-hud__drop-samples {
    margin-top: 8px;
    font-size: 0.62rem;
    letter-spacing: 0.08em;
    color: #e0b95e;
    opacity: 0.9;
}

/* top-bar NV button lights up in its own phosphor while the mode is live */
.mars-btn--nv[data-on="true"] {
    border-color: #5ee08a;
    color: #a8f5c6;
    background: rgba(12, 46, 26, 0.75);
}

.mars-menu__section .mars-btn.is-active {
    border-color: #5ee08a;
    color: #a8f5c6;
}

/* ---- HUD ---- */

#mc-hud {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.mars-hud__top {
    position: absolute;
    top: max(12px, env(safe-area-inset-top));
    left: 12px;
    right: 12px;
    display: flex;
    align-items: center;
    gap: 12px;
    pointer-events: none;
}

.mars-btn {
    pointer-events: auto;
    background: rgba(20, 12, 8, 0.75);
    border: 1px solid #7a4f30;
    color: #f2ece3;
    border-radius: 6px;
    padding: 10px 16px;
    font-size: 0.85rem;
    letter-spacing: 0.05em;
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
}

.mars-btn__hint {
    opacity: 0.55;
    font-size: 0.75em;
    display: none;
}

.mars-hud--desktop .mars-btn__hint {
    display: inline;
}

.mars-hud__unit {
    pointer-events: none;
    background: rgba(20, 12, 8, 0.6);
    padding: 6px 14px;
    border-radius: 6px;
    font-size: 0.8rem;
    letter-spacing: 0.1em;
}

.mars-hud__minimap {
    position: absolute;
    top: max(70px, calc(env(safe-area-inset-top) + 60px));
    right: 12px;
    width: 140px;
    height: 140px;
    border: 1px solid #7a4f30;
    border-radius: 8px;
    overflow: hidden;
}

.mars-minimap-canvas {
    width: 100%;
    height: 100%;
    display: block;
}

/* Mars clock (Wave 9.6): sol + local time-of-sol, docked as a footer strip
   across the bottom of the minimap. That slot is the only one free on BOTH
   viewports — the top bar cannot take another chip at 390px and every rail
   is spoken for. It rides along when the map moves left in Wave 10. */
.mars-hud__clock {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 6px;
    background: linear-gradient(to top, rgba(20, 12, 8, 0.92), rgba(20, 12, 8, 0.62));
    border-top: 1px solid rgba(122, 79, 48, 0.7);
    font-family: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
    font-size: 0.56rem;
    letter-spacing: 0.06em;
    pointer-events: none;
}

.mars-hud__clock b {
    font-weight: 600;
    color: #e0b95e;
}

.mars-hud__clock span {
    opacity: 0.85;
}

.mars-hud__clock i {
    margin-left: auto;
    font-style: normal;
    color: #ffd9a0;
}

/* after dark the strip's sun glyph goes cold, like the world it reports */
.mars-hud__clock[data-night="true"] i {
    color: #8fb4d8;
}

.mars-btn--menu {
    margin-left: auto;
}

/* ---- Compass (nose bearing) — docked under the minimap ---- */

.mars-hud__compass {
    position: absolute;
    top: max(218px, calc(env(safe-area-inset-top) + 208px));
    right: 12px;
    width: 44px;
    height: 44px;
    border: 1px solid #7a4f30;
    border-radius: 50%;
    background: rgba(20, 12, 8, 0.75);
    pointer-events: none;
}

.mars-compass__cardinal {
    position: absolute;
    top: 1px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.5rem;
    letter-spacing: 0.08em;
    color: #e0b95e;
    opacity: 0.75;
}

.mars-compass__needle {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 1.05rem;
    line-height: 1;
    color: #e0b95e;
    text-shadow: 0 0 4px rgba(0, 0, 0, 0.8);
}

/* Wave 6 wind arrow: teal, rides the dial rim on the wind's bearing
   side (nose needle keeps the center). Hidden in calm air. */
.mars-compass__wind {
    position: absolute;
    top: 50%;
    left: 50%;
    font-size: 0.6rem;
    line-height: 1;
    color: #2ec4d6;
    text-shadow: 0 0 4px rgba(0, 0, 0, 0.8);
}

/* GPS ticks (Wave 9.4): one dot per tracked asset, riding the dial rim at
   that asset's ABSOLUTE bearing (the dial is N-up). Colors come from
   comms.js TRACK_COLORS — never the needle's amber, which is your own
   nose. No transition: a tween spins the long way round on every 359->0
   wrap, same rule as the needles. */
.mars-compass__gps {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.mars-compass__tick {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: currentColor;
    box-shadow: 0 0 4px currentColor, 0 0 2px rgba(0, 0, 0, 0.9);
}

/* GPS RELAY card — the readable half of the same data (name + steer arrow
   + range). Desktop only: the phone rails are full (minimap -> compass ->
   gear -> drone board) and the dial ticks carry it there. */
.mars-hud__gps {
    display: none;
    position: absolute;
    top: max(272px, calc(env(safe-area-inset-top) + 262px));
    right: 12px;
    width: 140px;
    box-sizing: border-box;
    background: rgba(20, 12, 8, 0.75);
    border: 1px solid #7a4f30;
    border-radius: 8px;
    padding: 8px 10px;
    font-family: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
    pointer-events: none;
}

@media (min-width: 900px) and (pointer: fine) {
    .mars-hud__gps {
        display: block;
    }
}

/* Wave 10 carry-over: landscape phones dock the GPS card BESIDE the
   right-rail minimap — landscape has horizontal room where the vertical
   rails are full. Portrait keeps the compass ticks as the only carrier. */
@media (orientation: landscape) and (pointer: coarse) and (min-width: 700px) {
    .mars-hud__gps {
        display: block;
        right: 160px;
        top: max(70px, calc(env(safe-area-inset-top) + 60px));
    }
}

.mars-hud__gps-title {
    font-size: 0.58rem;
    letter-spacing: 0.14em;
    opacity: 0.6;
    margin-bottom: 5px;
}

.mars-hud__gps ul {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 0.62rem;
}

.mars-hud__gps li {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 1px 0;
}

.mars-hud__gps li b {
    font-weight: 500;
    letter-spacing: 0.04em;
    opacity: 0.85;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mars-hud__gps li span {
    margin-left: auto;
    color: #e0b95e;
    white-space: nowrap;
}

/* steer arrow: 0deg = dead ahead (same convention as the TGT arrow) */
.mars-gps__arrow {
    flex: none;
    display: inline-block;
    font-style: normal;
    font-size: 0.6rem;
    line-height: 1;
    transition: transform 0.2s linear;
}

/* ---- Telemetry readout ---- */

.mars-hud__telemetry {
    position: absolute;
    right: 12px;
    bottom: max(12px, env(safe-area-inset-bottom));
    background: rgba(20, 12, 8, 0.75);
    border: 1px solid #7a4f30;
    border-radius: 8px;
    padding: 10px 14px;
    font-family: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
    font-size: 0.72rem;
    min-width: 180px;
    pointer-events: none;
}

.mars-tele__site {
    letter-spacing: 0.08em;
    opacity: 0.7;
    font-size: 0.62rem;
    margin-bottom: 6px;
    white-space: nowrap;
}

.mars-tele__grid {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px 12px;
}

.mars-tele__grid span {
    opacity: 0.6;
    letter-spacing: 0.08em;
}

.mars-tele__grid b {
    font-weight: 500;
    text-align: right;
    color: #e0b95e;
}

.mars-tele__clock {
    letter-spacing: 0.06em;
    font-size: 0.66rem;
    color: #e0b95e;
    opacity: 0.9;
    margin-bottom: 6px;
}

.mars-tele__grid b.is-low {
    color: #e0885e;
}

.mars-tele__grid b.is-crit {
    color: #e05e5e;
}

/* docked on a chargepad — fast, station-powered, works after dark */
.mars-tele__grid b.is-charging {
    color: #5ee08a;
}

/* steer arrow inside the TGT row — rotated via inline transform */
.mars-tele__arrow {
    display: inline-block;
    margin-right: 5px;
    color: #e0b95e;
    transition: transform 0.2s linear;
}

/* collapse toggle — only surfaced on phones (see the coarse media query) */
.mars-tele__toggle {
    display: none;
    position: absolute;
    top: 2px;
    right: 4px;
    background: none;
    border: none;
    color: #e0b95e;
    font-size: 0.85rem;
    padding: 4px 8px;
    pointer-events: auto;
    cursor: pointer;
}

#mc-telemetry[data-collapsed="true"] .mars-tele__clock,
#mc-telemetry[data-collapsed="true"] .mars-tele__grid {
    display: none;
}

/* On phones the joystick zones own the bottom corners and the chase cam
   frames the unit near screen center — lifting the card above the look
   zone parked it right on top of the unit. Dock it top-left under the
   top bar instead (mirroring the minimap on the right), compacted. */
@media (max-width: 899px), (pointer: coarse) {
    .mars-hud__telemetry {
        right: auto;
        bottom: auto;
        left: 12px;
        top: max(70px, calc(env(safe-area-inset-top) + 60px));
        min-width: 132px;
        max-width: 186px;
        font-size: 0.6rem;
        padding: 8px 10px;
    }

    /* the nowrap site line otherwise stretches the card across the screen */
    .mars-hud__telemetry .mars-tele__site {
        white-space: normal;
        padding-right: 22px; /* clear the collapse toggle */
    }

    .mars-tele__toggle {
        display: block;
    }

    .mars-hud__telemetry .mars-tele__grid b {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* four top-bar buttons have to fit a phone width */
    .mars-btn {
        padding: 8px 10px;
        font-size: 0.72rem;
    }

    .mars-hud__unit {
        padding: 6px 8px;
        font-size: 0.72rem;
    }

}

/* ---- In-game menu ---- */

.mars-menu {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(10, 6, 4, 0.82);
    pointer-events: auto;
    z-index: 20;
}

.mars-menu[data-open="true"] {
    display: flex;
}

.mars-menu__panel {
    background: #1d110a;
    border: 1px solid #7a4f30;
    border-radius: 12px;
    padding: 24px 28px;
    max-width: 420px;
    width: calc(100vw - 48px);
    max-height: 82vh;
    overflow-y: auto;
}

.mars-menu__panel h2 {
    margin: 0 0 14px;
    font-size: 1.1rem;
    letter-spacing: 0.12em;
}

.mars-menu__section h3 {
    font-size: 0.72rem;
    letter-spacing: 0.12em;
    opacity: 0.6;
    margin: 16px 0 8px;
}

/* OPEN MISSION MAP — returns to the globe hub (plan 22-C). Gold accent so it
   reads as the primary navigation out of the in-game menu. Replaced the old
   per-site landing-site link list. */
.mars-btn--map {
    justify-content: center;
    width: 100%;
    box-sizing: border-box;
    border-color: #e0b95e;
    color: #ffe9bf;
    background: rgba(224, 185, 94, 0.14);
    letter-spacing: 0.1em;
}

.mars-btn--map:hover, .mars-btn--map:active {
    background: rgba(224, 185, 94, 0.26);
}

.mars-menu__missions {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.mars-menu__overlays {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.mars-menu__overlays .mars-btn.is-active {
    border-color: #e0b95e;
    color: #e0b95e;
}

.mars-menu__mission {
    text-align: left;
}

/* BASES — TRAVEL (Wave 9.3): name + live range on the left, action on the
   right. Same card language as .mars-menu__site, but a row, not a link. */
.mars-menu__bases {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.mars-menu__base {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 12px;
    border: 1px solid #5a3a26;
    border-radius: 8px;
    background: rgba(90, 58, 38, 0.15);
}

.mars-menu__base b {
    display: block;
    font-size: 0.85rem;
}

.mars-menu__base span {
    font-size: 0.72rem;
    opacity: 0.7;
}

.mars-menu__travel {
    flex: none;
    padding: 6px 12px;
    font-size: 0.72rem;
    border-color: #59d8c9;
    color: #a6f2e8;
}

.mars-menu__mission.is-done {
    border-color: #59d8c9;
    color: #59d8c9;
}

.mars-menu__note {
    margin: 8px 0 0;
    font-size: 0.7rem;
    line-height: 1.5;
    opacity: 0.6;
}

.mars-menu__lab {
    list-style: none;
    margin: 0;
    padding: 0;
}

.mars-menu__lab li {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 6px 0;
    border-bottom: 1px solid rgba(122, 79, 48, 0.35);
}

.mars-menu__lab li b {
    font-size: 0.85rem;
}

.mars-menu__lab li span {
    font-size: 0.72rem;
    opacity: 0.7;
}

.mars-menu__lab-empty {
    font-size: 0.78rem;
    opacity: 0.6;
}

/* archive entry meta line: site + analysis date, dimmer than the finding
   (li span selector needed to outrank the generic .mars-menu__lab li span) */
.mars-menu__lab li span.mars-menu__lab-meta {
    font-size: 0.66rem;
    opacity: 0.45;
    letter-spacing: 0.06em;
}

/* Wave 12.13: SURVEY IMAGING album — captured-frame thumbnails grid */
.mars-menu__photos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px;
}

.mars-menu__photos figure {
    margin: 0;
}

.mars-menu__photos img {
    display: block;
    width: 100%;
    border: 1px solid rgba(46, 196, 214, 0.35);
    border-radius: 4px;
}

.mars-menu__photos figcaption {
    display: flex;
    flex-direction: column;
    margin-top: 4px;
}

.mars-menu__photos figcaption b {
    font-size: 0.72rem;
    letter-spacing: 0.08em;
}

.mars-menu__photos figcaption span {
    font-size: 0.62rem;
    opacity: 0.5;
    letter-spacing: 0.06em;
}

/* ---- FLEET DOSSIER (plan 24) ------------------------------------- */
/* Top-bar chip beside the active unit's name. Hidden unless the unit
   has a dossier; background image is set inline by the HUD. */
.mars-hud__dossier {
    display: none;
    position: relative;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 1px solid rgba(46, 196, 214, 0.55);
    border-radius: 6px;
    background-size: cover;
    background-position: center;
    background-color: rgba(20, 12, 8, 0.6);
    cursor: pointer;
    pointer-events: auto;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4);
}

.mars-hud__dossier[data-visible="true"] {
    display: block;
}

.mars-hud__dossier-glyph {
    position: absolute;
    right: -2px;
    bottom: -3px;
    font-size: 0.7rem;
    line-height: 1;
    color: #0a0604;
    background: rgba(46, 196, 214, 0.9);
    border-radius: 3px;
    padding: 1px 2px;
}

/* Full-screen lightbox — above the menu (z-20) and everything else. */
.mars-dossier-lightbox {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 4vmin;
    background: rgba(6, 4, 3, 0.9);
    pointer-events: auto;
    z-index: 60;
}

.mars-dossier-lightbox[data-open="true"] {
    display: flex;
}

.mars-dossier-lightbox__fig {
    margin: 0;
    max-width: 92vw;
    max-height: 92vh;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.mars-dossier-lightbox__fig img {
    display: block;
    max-width: 100%;
    max-height: 82vh;
    border: 1px solid rgba(46, 196, 214, 0.4);
    border-radius: 6px;
    box-shadow: 0 8px 40px rgba(0, 0, 0, 0.6);
}

.mars-dossier-lightbox__fig figcaption {
    margin-top: 10px;
    text-align: center;
    max-width: 70ch;
}

.mars-dossier-lightbox__fig figcaption b {
    display: block;
    font-size: 0.82rem;
    letter-spacing: 0.1em;
    color: #2ec4d6;
}

.mars-dossier-lightbox__fig figcaption span {
    display: block;
    margin-top: 4px;
    font-size: 0.7rem;
    opacity: 0.7;
    letter-spacing: 0.04em;
}

.mars-dossier-lightbox__close {
    position: absolute;
    top: 3vmin;
    right: 3vmin;
    width: 40px;
    height: 40px;
    border: 1px solid rgba(46, 196, 214, 0.55);
    border-radius: 6px;
    background: rgba(20, 12, 8, 0.7);
    color: #e6e2d8;
    font-size: 1rem;
    cursor: pointer;
    pointer-events: auto;
}

/* Menu dossier grid — clickable concept cards. */
.mars-menu__dossier {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 12px;
}

.mars-menu__dossier-card {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 0;
    padding: 0;
    border: 1px solid rgba(46, 196, 214, 0.35);
    border-radius: 6px;
    background: rgba(20, 12, 8, 0.4);
    color: #e6e2d8;
    cursor: pointer;
    overflow: hidden;
    text-align: left;
}

.mars-menu__dossier-card img {
    display: block;
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
}

.mars-menu__dossier-card span {
    font-size: 0.68rem;
    letter-spacing: 0.06em;
    padding: 0 8px 8px;
}

.mars-menu__controls {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 0.8rem;
    opacity: 0.85;
}

.mars-menu__controls li {
    padding: 3px 0;
}

.mars-btn--resume {
    margin-top: 18px;
    width: 100%;
    justify-content: center;
}

.mars-hud__prompt {
    position: absolute;
    bottom: max(140px, calc(env(safe-area-inset-bottom) + 130px));
    left: 50%;
    transform: translateX(-50%);
}

/* ---- mission-boundary warning (units clamped at the DEM edge) ---- */

.mars-hud__boundary {
    position: absolute;
    top: max(64px, calc(env(safe-area-inset-top) + 56px));
    left: 50%;
    transform: translateX(-50%);
    padding: 8px 16px;
    border: 1px solid #e07b39;
    background: rgba(46, 20, 8, 0.85);
    color: #ffb27a;
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    white-space: nowrap;
    pointer-events: none;
    z-index: 20;
    animation: mars-boundary-pulse 1.1s ease-in-out infinite;
}

.mars-hud__boundary[data-visible="false"] {
    display: none;
}

/* Environmental hazard banner (Wave 4): boundary's idiom, one slot
   below it so both warnings can stack without colliding. Steadier
   pulse — it's ambient state, not an edge violation. */
.mars-hud__hazard {
    position: absolute;
    top: max(104px, calc(env(safe-area-inset-top) + 96px));
    left: 50%;
    transform: translateX(-50%);
    padding: 8px 16px;
    border: 1px solid #d8a13f;
    background: rgba(44, 30, 8, 0.85);
    color: #ffd27a;
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    white-space: nowrap;
    pointer-events: none;
    z-index: 20;
    animation: mars-boundary-pulse 2.2s ease-in-out infinite;
}

.mars-hud__hazard[data-visible="false"] {
    display: none;
}

@keyframes mars-boundary-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.55; }
}

/* Build toast (Wave 7): third slot in the top banner stack, teal =
   good news (objective idiom). One-shot — hud.js self-hides it, so no
   pulse; a single ease-in reads as an announcement, not an alarm. */
.mars-hud__toast {
    position: absolute;
    top: max(144px, calc(env(safe-area-inset-top) + 136px));
    left: 50%;
    transform: translateX(-50%);
    padding: 8px 16px;
    border: 1px solid #59d8c9;
    background: rgba(8, 38, 36, 0.88);
    color: #a6f2e8;
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    white-space: nowrap;
    pointer-events: none;
    z-index: 20;
    animation: mars-toast-in 0.35s ease-out;
}

.mars-hud__toast[data-visible="false"] {
    display: none;
}

@keyframes mars-toast-in {
    from { opacity: 0; transform: translateX(-50%) translateY(-8px); }
    to { opacity: 1; transform: translateX(-50%); }
}

/* Next-step guidance (Wave 9.8): 4th slot in the top banner stack — its own,
   because a step completion and a build toast can fire in the same breath
   (analyzing a sample does both) and one slot would eat one of them. Amber
   = "what to do next" (the objective/waypoint language), against the toast's
   teal "this happened". Two lines: what you just finished, what follows. */
.mars-hud__guide {
    position: absolute;
    top: max(184px, calc(env(safe-area-inset-top) + 176px));
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 8px 18px;
    border: 1px solid #e0b95e;
    background: rgba(42, 30, 10, 0.9);
    font-size: 0.78rem;
    letter-spacing: 0.1em;
    white-space: nowrap;
    pointer-events: none;
    z-index: 20;
    animation: mars-toast-in 0.35s ease-out;
}

.mars-hud__guide[data-visible="false"] {
    display: none;
}

.mars-hud__guide b {
    font-weight: 600;
    color: #7ee0a8;
    font-size: 0.72rem;
}

.mars-hud__guide span {
    color: #ffd98f;
}

@media (max-width: 899px), (pointer: coarse) {
    .mars-hud__guide {
        font-size: 0.64rem;
        max-width: 92vw;
        white-space: normal;
        text-align: center;
    }
}

@media (max-width: 899px), (pointer: coarse) {
    .mars-hud__boundary, .mars-hud__hazard, .mars-hud__toast {
        font-size: 0.64rem;
        max-width: 92vw;
        white-space: normal;
        text-align: center;
    }
}

/* ---- tutorial objective banner (same idiom as the boundary warning,
   bottom-placed + teal so it never collides with it) ---- */

.mars-hud__objective {
    position: absolute;
    bottom: max(96px, calc(env(safe-area-inset-bottom) + 88px));
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    border: 1px solid #59d8c9;
    background: rgba(8, 38, 36, 0.85);
    color: #a6f2e8;
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    /* Ariana's briefing lines (sites.js `briefing`) run ~160 chars — as an
       unbounded nowrap row they ran off both edges of any window narrower
       than ~1280px. Same wrap idiom the mobile breakpoint already used,
       just applied at every width; short objective steps still sit on one
       line, only long dialogue wraps. */
    max-width: min(92vw, 1180px);
    white-space: normal;
    text-align: center;
    pointer-events: none;
    z-index: 20;
}

.mars-hud__objective[data-visible="false"] {
    display: none;
}

.mars-objective__skip {
    pointer-events: auto;
    font-size: 0.68rem;
    padding: 3px 8px;
    /* Never let the wrapping text squeeze SKIP onto two lines. */
    flex-shrink: 0;
    white-space: nowrap;
}

@media (max-width: 899px), (pointer: coarse) {
    .mars-hud__objective {
        font-size: 0.64rem;
    }
}

/* ---- tutorial overview card (all steps up front, START to begin) ---- */

.mars-tutorial__steps {
    margin: 0 0 10px;
    padding-left: 1.4em;
    display: flex;
    flex-direction: column;
    gap: 6px;
    color: #a6f2e8;
    font-size: 0.82rem;
    letter-spacing: 0.06em;
}

.mars-tutorial__steps li::marker {
    color: #59d8c9;
}

#mc-tutorial-overview .mars-btn {
    margin-right: 8px;
}

/* ---- SKIP INTRO — visible only during the landing-drop cinematic ---- */

.mars-hud__skip-intro {
    position: absolute;
    bottom: max(24px, env(safe-area-inset-bottom));
    right: max(16px, env(safe-area-inset-right));
    z-index: 21;
}

.mars-hud__skip-intro[data-visible="false"] {
    display: none;
}

/* ---- RESET MISSION (menu SIM section, arm/confirm) ---- */

.mars-btn--reset {
    margin-top: 10px;
}

.mars-btn--reset[data-armed="true"] {
    border-color: #e05959;
    color: #ff9d9d;
    background: rgba(70, 18, 14, 0.6);
}

/* ---- GEAR button (rover + drones; hidden for the humanoid) ---- */

/* Sits in the bottom-right column ABOVE the telemetry card. The card is
   ~231 px tall (bottom: 12px => its top edge lands 243 px up), so the old
   215px offset dropped the gear straight onto it. Keep a margin over the
   measured height: a wrapped site line can add a row. */
.mars-hud__gear {
    position: absolute;
    right: 12px;
    bottom: 285px;
    z-index: 15;
}

.mars-hud__gear[data-visible="false"] {
    display: none;
}

/* Wave 12: van DEPLOY/PACK UP button — same slot as the gear button (the
   van has no gears, so the two are never visible at the same time). */
.mars-hud__van {
    position: absolute;
    right: 12px;
    bottom: 285px;
    z-index: 15;
}

.mars-hud__van[data-visible="false"] {
    display: none;
}

@media (max-width: 899px), (pointer: coarse) {
    /* Right rail, stacked under the minimap (70-212) and compass (218-264):
       gear 272-302, then the drone board below it. The old 222px offset
       landed the gear on top of the compass. */
    .mars-hud__gear,
    .mars-hud__van {
        bottom: auto;
        top: max(272px, calc(env(safe-area-inset-top) + 262px));
    }
}

/* ---- drone control board (visible only while a drone is active) ---- */

.mars-hud__dronectl {
    position: absolute;
    bottom: max(14px, env(safe-area-inset-bottom));
    left: 50%;
    transform: translateX(-50%);
    display: none;
    /* center, NOT stretch — stretch ballooned the stat panel and LAND
       button to the alt slider column's full height (mobile bug) */
    align-items: center;
    gap: 10px;
    max-width: calc(100vw - 16px);
    pointer-events: none;
    z-index: 15; /* above the touch zones so the LAND button stays tappable */
}

.mars-hud__dronectl[data-visible="true"] {
    display: flex;
}

.mars-dronectl__stat {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    background: rgba(20, 12, 8, 0.75);
    border: 1px solid #7a4f30;
    border-radius: 6px;
    padding: 6px 14px;
    font-family: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
    font-size: 0.68rem;
    text-align: center;
}

.mars-dronectl__stat b {
    color: #e0b95e;
    letter-spacing: 0.1em;
    font-weight: 600;
}

.mars-dronectl__stat span {
    opacity: 0.75;
    white-space: nowrap; /* "ALT 12.3 m" must not wrap in the compact mobile chip */
}

.mars-btn--land {
    min-width: 110px;
    justify-content: center;
}

/* Wave 12.13: recon survey-imaging button (dronectl cluster). Hidden for
   every unit but the recon; the label carries the in-range target name. */
.mars-btn--photo {
    min-width: 110px;
    justify-content: center;
}

.mars-btn--photo[data-visible="false"] {
    display: none;
}

/* board fold toggle: mobile-only affordance (desktop has room) */
.mars-dronectl__toggle {
    display: none;
}

/* vertical altitude slider: bottom = land, top = ceiling */
.mars-dronectl__alt {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    background: rgba(20, 12, 8, 0.75);
    border: 1px solid #7a4f30;
    border-radius: 6px;
    padding: 8px 6px;
    pointer-events: auto;
    font-family: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
    font-size: 0.58rem;
    color: #f2ece3;
    opacity: 0.9;
}

#mc-alt-slider {
    writing-mode: vertical-lr;
    direction: rtl;
    width: 22px;
    height: 92px;
    accent-color: #e0b95e;
    cursor: ns-resize;
    touch-action: none;
}

/* phones: dock the board on the RIGHT rail below the GEAR button
   (minimap -> GEAR -> drone controls) as a right-aligned column —
   bottom-center put it exactly over the chase-cam-framed drone, and
   compact everything — full-size it covered half a small portrait
   screen and buried the sticks. (Must come after the base rule above —
   same specificity, cascade order decides.) */
@media (max-width: 899px), (pointer: coarse) {
    .mars-hud__dronectl {
        left: auto;
        right: 12px;
        bottom: auto;
        /* last in the right rail: minimap -> compass -> gear (272-302) */
        top: max(310px, calc(env(safe-area-inset-top) + 300px));
        transform: none;
        flex-direction: column;
        align-items: flex-end;
        gap: 6px;
    }

    .mars-dronectl__alt {
        padding: 5px 4px;
        gap: 2px;
        font-size: 0.5rem;
    }

    #mc-alt-slider {
        height: 62px;
        width: 18px;
    }

    .mars-dronectl__stat {
        font-size: 0.6rem;
        padding: 4px 8px;
    }

    .mars-btn--land {
        min-width: 84px;
    }

    /* folded by default on phones (hud.js sets data-collapsed): the full
       board sits exactly where the chase cam frames the drone. The chip
       shows the live altitude and expands on tap. */
    .mars-dronectl__toggle {
        display: flex;
        align-items: center;
        justify-content: center;
        pointer-events: auto;
        background: rgba(20, 12, 8, 0.75);
        border: 1px solid #7a4f30;
        border-radius: 6px;
        color: #e0b95e;
        font-family: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
        font-size: 0.66rem;
        letter-spacing: 0.08em;
        padding: 7px 10px;
        min-height: 32px;
    }

    .mars-hud__dronectl[data-collapsed="true"] .mars-dronectl__alt,
    .mars-hud__dronectl[data-collapsed="true"] .mars-dronectl__stat,
    .mars-hud__dronectl[data-collapsed="true"] .mars-btn--land,
    .mars-hud__dronectl[data-collapsed="true"] .mars-btn--photo {
        display: none;
    }
}

.mars-hud__inventory {
    position: absolute;
    bottom: max(12px, env(safe-area-inset-bottom));
    left: 12px;
    background: rgba(20, 12, 8, 0.7);
    border: 1px solid #7a4f30;
    border-radius: 8px;
    padding: 10px 14px;
    pointer-events: auto;
    max-width: 200px;
    max-height: 120px;
    overflow-y: auto;
}

.mars-hud__inventory-title {
    font-size: 0.75rem;
    letter-spacing: 0.1em;
    opacity: 0.8;
    margin-bottom: 4px;
}

.mars-hud__inventory ul {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 0.8rem;
}

/* live edge-node readout ("NODE ▸ ROCHETTE 42%") under the LAB count */
.mars-hud__node {
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    color: #e0b95e;
    margin-bottom: 4px;
    white-space: nowrap;
}

.mars-hud__node.is-idle {
    opacity: 0.4;
    color: inherit;
}

/* phones: inventory shrinks to a counts-only chip lifted above the left
   stick zone — at the bottom corner it sat right on the resting pad.
   (Must come AFTER the base rules above — same specificity, cascade
   order decides; the dronectl media block is too early in the file.) */
@media (max-width: 899px), (pointer: coarse) {
    .mars-hud__inventory {
        left: 8px;
        bottom: calc(min(45vw, 260px) + 10px);
        padding: 5px 6px;
        max-width: 84px;
        opacity: 0.85;
    }

    .mars-hud__inventory ul {
        display: none;
    }

    /* counts-only chip: no room for the live node line */
    .mars-hud__node {
        display: none;
    }

    .mars-hud__inventory-title {
        font-size: 0.62rem;
        margin-bottom: 2px;
    }
}

/* Landscape phones: the portrait lift (45vw above the stick zone) puts
   the chip ON the telemetry card when the viewport is wider than tall —
   dock it beside the telemetry instead, above the stick zones' reach. */
@media (orientation: landscape) and (pointer: coarse) and (min-width: 700px) {
    .mars-hud__inventory {
        bottom: auto;
        top: max(70px, calc(env(safe-area-inset-top) + 60px));
        /* the telemetry card renders 208px wide (186 max-width is
           content-box + 20 padding + 2 border) — clear its real edge */
        left: 228px;
    }
}

/* ---- Wave 10 desktop reshuffle (#14/#15) ----
   The map column moves LEFT (minimap -> compass -> GPS, today's right
   stack mirrored, clock strip rides inside the minimap), telemetry takes
   the vacated top-right, GEAR drops into the freed bottom-right corner,
   and the drone board docks bottom-left above the inventory — clearing
   bottom-center, where the chase cam frames the unit. Mobile keeps its
   right-rail layout from the coarse media block above; must stay LAST in
   the HUD cascade so it outranks every base dock. */
@media (min-width: 900px) and (pointer: fine) {
    .mars-hud__minimap {
        right: auto;
        left: 12px;
    }

    .mars-hud__compass {
        right: auto;
        left: 12px;
    }

    .mars-hud__gps {
        right: auto;
        left: 12px;
    }

    .mars-hud__telemetry {
        bottom: auto;
        top: max(70px, calc(env(safe-area-inset-top) + 60px));
    }

    .mars-hud__gear {
        bottom: max(12px, env(safe-area-inset-bottom));
    }

    /* GEAR is rover-only and the drone board drone-only, so the two
       docks never show together — but the board still avoids the
       bottom-right corner so it can't shadow the gear's muscle memory. */
    .mars-hud__dronectl {
        left: 12px;
        transform: none;
        bottom: max(148px, calc(env(safe-area-inset-bottom) + 136px));
    }
}

/* ---- Touch controls ---- */

.mars-touch-zone {
    position: absolute;
    bottom: 0;
    width: 45vw;
    max-width: 260px;
    height: 45vw;
    max-height: 260px;
    touch-action: none;
}

.mars-touch-zone--left {
    left: 0;
}

.mars-touch-zone--right {
    right: 0;
}

/* zones the current unit doesn't use are hidden (touch.js setHidden) */
.mars-touch-zone[data-off="true"] {
    display: none;
}

.joy-base {
    position: absolute;
    width: 100px;
    height: 100px;
    margin-left: -50px;
    margin-top: -50px;
    border-radius: 50%;
    background: rgba(224, 185, 94, 0.12);
    border: 1px solid rgba(224, 185, 94, 0.4);
    opacity: 0.3; /* resting pad stays visible; touch.js brightens it */
    transition: opacity 0.1s;
    pointer-events: none;
}

.joy-label {
    position: absolute;
    top: 6px;
    left: 0;
    width: 100%;
    text-align: center;
    font-size: 0.58rem;
    letter-spacing: 0.14em;
    color: #e0b95e;
    opacity: 0.6;
    pointer-events: none;
}

.joy-nub {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 44px;
    height: 44px;
    margin-left: -22px;
    margin-top: -22px;
    border-radius: 50%;
    background: rgba(224, 185, 94, 0.55);
}

@media (min-width: 900px) and (pointer: fine) {
    .mars-touch-zone {
        display: none;
    }
}

/* ============================================================
   ONGAK soundtrack player (plan 27). Opens from the ♪ button in
   the top bar. Left-middle: the right rail is fully spoken for
   (minimap / compass / GPS / telemetry) and the inventory owns
   bottom-left, so this floats clear of both.
   ============================================================ */
.mars-hud__music {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    width: 208px;
    max-height: 70vh;
    overflow-y: auto;
    display: none;
    flex-direction: column;
    gap: 8px;
    background: rgba(20, 12, 8, 0.88);
    border: 1px solid #7a4f30;
    border-radius: 8px;
    padding: 10px;
    font-family: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
    font-size: 0.68rem;
    pointer-events: auto;
    z-index: 16;
}

.mars-hud__music[data-open="true"] {
    display: flex;
}

.mars-music__head {
    display: flex;
    align-items: baseline;
    gap: 6px;
}

.mars-music__head b {
    color: #e0b95e;
    letter-spacing: 0.08em;
    font-weight: 600;
    flex: 1;
    /* long AI-generated track titles must not stretch the panel */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mars-music__head span {
    opacity: 0.6;
    font-size: 0.58rem;
    letter-spacing: 0.1em;
}

.mars-music__close {
    background: none;
    border: none;
    color: #b9a894;
    cursor: pointer;
    padding: 0 2px;
    font-size: 0.75rem;
}

.mars-music__close:hover {
    color: #f2ece3;
}

/* VU meter — bars scale from the bottom, driven per frame by
   setMusicLevel(). transform only: no layout on the hot path. */
.mars-music__meter {
    display: flex;
    align-items: flex-end;
    gap: 3px;
    height: 26px;
}

.mars-music__meter i {
    flex: 1;
    height: 100%;
    background: linear-gradient(to top, #7a4f30, #e0b95e);
    border-radius: 1px;
    transform: scaleY(0.08);
    transform-origin: bottom;
    transition: transform 60ms linear;
}

.mars-music__transport {
    display: flex;
    gap: 4px;
}

.mars-music__transport .mars-btn {
    flex: 1;
    justify-content: center;
    padding: 5px 4px;
}

.mars-btn--play {
    flex: 2 !important;
}

.mars-music__vol {
    display: flex;
    align-items: center;
    gap: 6px;
    opacity: 0.75;
    letter-spacing: 0.08em;
}

.mars-music__vol input {
    flex: 1;
    accent-color: #e0b95e;
}

/* Makadane rock action — sits above the gear/van button slot so it can
   coexist with the COLLECT prompt (both can be live at once). */
.mars-hud__rock {
    position: absolute;
    bottom: max(64px, calc(env(safe-area-inset-bottom) + 58px));
    left: 50%;
    transform: translateX(-50%);
    z-index: 15;
}

.mars-hud__rock[data-visible="false"] {
    display: none;
}

/* Plan 28: DANCE button — rides just above the rock button slot, warm-lit
   so it reads as a "for fun" control rather than another mission verb. */
.mars-hud__dance {
    position: absolute;
    bottom: max(104px, calc(env(safe-area-inset-bottom) + 98px));
    left: 50%;
    transform: translateX(-50%);
    z-index: 15;
    border-color: #d98cc4;
    color: #f0c8e6;
}

.mars-hud__dance[data-visible="false"] {
    display: none;
}

.mars-hud__dance[data-on="true"] {
    background: rgba(217, 140, 196, 0.22);
    border-color: #f0a8dc;
    color: #ffd8f2;
}

.mars-music__bot {
    display: flex;
    gap: 4px;
    align-items: center;
    flex-wrap: wrap;
}

.mars-music__bot-state {
    flex-basis: 100%;
    font-size: 0.64rem;
    letter-spacing: 0.06em;
    color: #e0b95e;
}

.mars-music__bot .mars-btn {
    flex: 1;
    justify-content: center;
    padding: 5px 4px;
    font-size: 0.62rem;
}

/* deployed reads as the "held" state, like the van's PACK UP */
#mc-ongak-deploy[data-deployed="true"] {
    border-color: #e0b95e;
    color: #e0b95e;
}

.mars-music__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.mars-music__list .mars-btn {
    width: 100%;
    justify-content: flex-start;
    padding: 5px 8px;
    font-size: 0.65rem;
}

.mars-music__list li[data-active="true"] .mars-btn {
    border-color: #e0b95e;
    color: #e0b95e;
}

.mars-music__list li[data-active="true"] .mars-btn::before {
    content: "▸ ";
}

.mars-music__note {
    margin: 0;
    opacity: 0.5;
    font-size: 0.58rem;
    line-height: 1.4;
}

.mars-menu__music {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
}

.mars-menu__music b {
    color: #e0b95e;
    flex: 1;
}

/* Mobile: a centered sheet — a 208px rail on the left collides with
   the MOVE joystick zone on a phone. */
@media (max-width: 899px), (pointer: coarse) {
    .mars-hud__music {
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: min(280px, calc(100vw - 32px));
        max-height: 78vh;
    }
}

/* ============================================================
   Site Hub — the 3D Mars globe (plan 22-B/C). Fullscreen canvas
   with a non-blocking UI overlay; pin cards / reset buttons are
   added by later steps. Shares the sim's palette (gold #e0b95e,
   dust-brown #7a4f30, panel rgba(20,12,8,.75)).
   ============================================================ */
#hub-root[hidden] {
    display: none !important;
}

#hub-root {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    background: #07040a;
}

#hub-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    touch-action: none;
    cursor: grab;
}

#hub-canvas:active {
    cursor: grabbing;
}

/* Overlay: passes gestures through to the canvas; only interactive
   children (pins, cards, buttons) opt back into pointer events. */
#hub-ui {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 2;
}

#hub-title {
    position: absolute;
    top: max(28px, env(safe-area-inset-top));
    left: 50%;
    transform: translateX(-50%);
    text-align: center;
    text-shadow: 0 2px 18px rgba(0, 0, 0, 0.7);
}

#hub-title h1 {
    margin: 0;
    font-size: clamp(1.4rem, 4vw, 2.2rem);
    letter-spacing: 0.28em;
    font-weight: 600;
    color: #f2ece3;
}

#hub-title p {
    margin: 6px 0 0;
    font-size: clamp(0.7rem, 2vw, 0.85rem);
    letter-spacing: 0.32em;
    color: #e0b95e;
    opacity: 0.85;
}

/* Pin card — the panel that appears when a site pin is picked. Docked
   bottom-centre (desktop) / full-width bottom sheet (mobile). Only the card
   opts back into pointer events; the rest of #hub-ui stays click-through. */
#hub-card[hidden] {
    display: none !important;
}

#hub-card {
    pointer-events: auto;
    position: absolute;
    left: 50%;
    bottom: max(28px, env(safe-area-inset-bottom));
    transform: translateX(-50%);
    width: min(420px, calc(100vw - 32px));
    box-sizing: border-box;
    background: rgba(20, 12, 8, 0.9);
    border: 1px solid #7a4f30;
    border-radius: 12px;
    padding: 18px 20px 20px;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.55);
    animation: hub-card-in 0.22s ease-out;
}

@keyframes hub-card-in {
    from { opacity: 0; transform: translate(-50%, 12px); }
    to { opacity: 1; transform: translate(-50%, 0); }
}

#hub-card-close {
    position: absolute;
    top: 8px;
    right: 10px;
    width: 30px;
    height: 30px;
    background: none;
    border: none;
    color: #b9a894;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
}

#hub-card-close:hover {
    color: #f2ece3;
}

.hub-card__progress {
    font-family: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    color: #ffcf6a;
    margin-bottom: 6px;
}

#hub-card h2 {
    margin: 0;
    font-size: 1.35rem;
    letter-spacing: 0.06em;
    color: #f2ece3;
}

.hub-card__mission {
    margin-top: 3px;
    font-size: 0.82rem;
    letter-spacing: 0.03em;
    color: #c9b8a4;
}

.hub-card__coords {
    margin-top: 8px;
    font-family: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
    font-size: 0.78rem;
    letter-spacing: 0.05em;
    color: #9fb0a6;
}

.hub-card__actions {
    display: flex;
    gap: 10px;
    margin-top: 16px;
}

.hub-card__enter {
    flex: 1;
    justify-content: center;
    border-color: #e0b95e;
    color: #ffe9bf;
    background: rgba(224, 185, 94, 0.14);
    letter-spacing: 0.12em;
}

.hub-card__enter:hover {
    background: rgba(224, 185, 94, 0.26);
}

.hub-card__locked {
    margin: 14px 0 0;
    font-size: 0.8rem;
    letter-spacing: 0.06em;
    color: #8a97a8;
}

/* RESET SITE sits beside ENTER in the card action row (overrides the menu
   variant's top margin so the two buttons align). */
.hub-card__reset {
    margin-top: 0;
    justify-content: center;
}

.hub-card__reset[hidden] {
    display: none !important;
}

/* Hub-level RESET GAME — a quiet corner button so it never competes with the
   pins; only reads loud once armed (via .mars-btn--reset[data-armed]). */
.hub-reset-game {
    pointer-events: auto;
    position: absolute;
    left: max(16px, env(safe-area-inset-left));
    bottom: max(16px, env(safe-area-inset-bottom));
    margin-top: 0;
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    opacity: 0.7;
}

.hub-reset-game:hover {
    opacity: 1;
}

/* Cloud save widget (plan 23) — top-right, opposite RESET GAME. Inert
   (hidden) until GOOGLE_CLIENT_ID is set in cloudsync.js. */
#hub-cloud[hidden] {
    display: none !important;
}

#hub-cloud {
    pointer-events: auto;
    position: absolute;
    top: max(16px, env(safe-area-inset-top));
    right: max(16px, env(safe-area-inset-right));
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
}

.hub-cloud__signin {
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    border-color: #7a4f30;
}

.hub-cloud__signin::before {
    content: "☁";
    margin-right: 6px;
    color: #e0b95e;
}

.hub-cloud__signin[hidden] {
    display: none !important;
}

.hub-cloud__status {
    display: flex;
    align-items: center;
    gap: 10px;
    background: rgba(20, 12, 8, 0.75);
    border: 1px solid #7a4f30;
    border-radius: 6px;
    padding: 6px 12px;
}

.hub-cloud__status[hidden] {
    display: none !important;
}

.hub-cloud__chip {
    font-family: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
}

.hub-cloud__chip[data-state="synced"] {
    color: #7fdca0;
}

.hub-cloud__chip[data-state="syncing"] {
    color: #e0b95e;
}

.hub-cloud__chip[data-state="offline"] {
    color: #e0a06a;
}

.hub-cloud__signout {
    background: none;
    border: none;
    color: #b9a894;
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    cursor: pointer;
    padding: 0;
}

.hub-cloud__signout:hover {
    color: #f2ece3;
}

/* Live-update banner (plan 30, js/update-check.js) — standalone, injected
   into <body> rather than the HUD's template, since it must show on both
   the hub screen and mid-sim. High z-index so it sits above the HUD's
   own top banner stack (which tops out at z-index: 20). */
.mc-update-banner {
    position: fixed;
    top: 0;
    left: 50%;
    transform: translateX(-50%) translateY(-100%);
    margin-top: max(10px, env(safe-area-inset-top));
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    border: 1px solid #e0b95e;
    border-radius: 6px;
    background: rgba(29, 17, 10, 0.95);
    color: #f2ece3;
    font-size: 0.8rem;
    letter-spacing: 0.05em;
    z-index: 500;
    transition: transform 0.35s ease-out;
}

.mc-update-banner[data-visible="true"] {
    transform: translateX(-50%) translateY(0);
}

.mc-update-banner__reload {
    padding: 6px 12px;
    font-size: 0.75rem;
    border-color: #e0b95e;
    color: #e0b95e;
}

.mc-update-banner__reload:hover {
    background: rgba(224, 185, 94, 0.15);
}
