/* ── In-play HUD: mission readouts, queue, control bar, inspector ─────── */

.hud-stack {
    position: absolute;
    top: 78px;
    right: 14px;
    width: 288px;
    /* Percentages, not vh: the shell is already the height of the viewport the
       player can see, and vh on a phone is the taller one behind the browser
       chrome. */
    max-height: calc(100% - 210px);
    overflow-y: auto;
    overscroll-behavior: contain;
    z-index: 15;
    display: flex;
    flex-direction: column;
    gap: 10px;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}

/* Wrapper for the two mission readouts. It generates no box on a desktop, so
   the queue and the HUD keep their own corners of the screen; below the mobile
   breakpoint it becomes the sheet that #mission-strip pulls up. */
.mission-sheet { display: contents; }

/* Phone only — see the responsive block at the foot of this file. */
.mobile-strip { display: none; }

.hud-stack::-webkit-scrollbar { width: 6px; }
.hud-stack::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.18); border-radius: 3px; }

.hud-card {
    background: var(--bg-card);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius);
    padding: 14px;
    box-shadow: var(--shadow);
}

.hud-card-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}

.hud-card-header h3 {
    font-family: var(--font-heading);
    font-size: 0.92rem;
    font-weight: 600;
    flex: 1;
}

.hud-tagline {
    font-size: 0.8rem;
    color: var(--text-sub);
    margin-bottom: 10px;
    line-height: 1.45;
}

.metric-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 10px;
    font-size: 0.82rem;
    padding: 2px 0;
}

.metric-label { color: var(--text-sub); }

.metric-val {
    font-family: var(--font-heading);
    font-weight: 600;
    color: var(--text-main);
    text-align: right;
}

.metric-row.big .metric-val { font-size: 1.22rem; color: var(--accent-cyan); }

.status-good { color: var(--accent-green); }
.status-warn { color: var(--accent-amber); }
.status-bad  { color: var(--accent-red); }

/* Physics tower run state — the one line that says whether it is still standing. */
.run-status { font-size: 0.78rem; }
.run-status.settling  { color: var(--accent-amber); }
.run-status.stable    { color: var(--accent-green); }
.run-status.collapsed { color: var(--accent-red); }

.mix-row {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 10px;
}

.mix-pill {
    font-size: 0.7rem;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 5px;
    background: rgba(99, 102, 241, 0.18);
    border: 1px solid rgba(99, 102, 241, 0.32);
    color: #c7d2fe;
}

/* medal progress track — fill grows as the envelope grows */
.medal-track {
    --fill: 0%;
    --gold: 30%;
    --silver: 55%;
    --bronze: 80%;
    position: relative;
    height: 8px;
    border-radius: 99px;
    margin: 12px 0 8px;
    background:
        linear-gradient(90deg,
            rgba(251, 191, 36, 0.35) 0 var(--gold),
            rgba(203, 213, 225, 0.30) var(--gold) var(--silver),
            rgba(217, 119, 6, 0.30) var(--silver) var(--bronze),
            rgba(239, 68, 68, 0.22) var(--bronze) 100%);
    overflow: hidden;
}

.medal-track .track-fill {
    position: absolute;
    inset: 0 auto 0 0;
    width: var(--fill);
    background: rgba(248, 250, 252, 0.85);
    border-right: 2px solid #fff;
    transition: width 0.25s ease;
}

.medal-pill {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 700;
    padding: 3px 10px;
    border-radius: 99px;
    margin-bottom: 8px;
    background: rgba(255, 255, 255, 0.08);
    color: var(--text-sub);
}

.medal-pill.medal-gold   { background: rgba(251, 191, 36, 0.2); color: var(--gold); }
.medal-pill.medal-silver { background: rgba(203, 213, 225, 0.18); color: var(--silver); }
.medal-pill.medal-bronze { background: rgba(217, 119, 6, 0.2); color: #fbbf90; }
.medal-pill.medal-none   { background: rgba(239, 68, 68, 0.16); color: #fca5a5; }

.rule-list, .def-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.rule-list li, .def-list li {
    display: flex;
    flex-direction: column;
    gap: 1px;
    font-size: 0.78rem;
    line-height: 1.4;
}

.rule-list strong, .def-list strong {
    font-family: var(--font-heading);
    font-size: 0.8rem;
    color: var(--accent-cyan);
}

.rule-list span, .def-list span { color: var(--text-sub); }

.stuck-warning {
    margin-top: 10px;
    font-size: 0.76rem;
    color: #fca5a5;
    background: rgba(239, 68, 68, 0.12);
    border: 1px solid rgba(239, 68, 68, 0.3);
    border-radius: 8px;
    padding: 7px 9px;
    line-height: 1.4;
}

/* ── queue bar ───────────────────────────────────────────────────────── */

.queue-bar {
    position: absolute;
    top: 78px;
    left: 14px;
    z-index: 15;
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 264px;
}

.queue-slot {
    background: var(--bg-card);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius);
    padding: 11px 12px;
    box-shadow: var(--shadow);
}

.queue-now { border-color: rgba(56, 189, 248, 0.42); }

.queue-label {
    display: block;
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--text-muted);
    font-weight: 700;
    margin-bottom: 7px;
}

.unit-chip {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 0;
}

.unit-chip + .unit-chip { border-top: 1px solid rgba(255, 255, 255, 0.06); }

.chip-swatch {
    width: 10px;
    height: 26px;
    border-radius: 3px;
    flex: none;
}

.chip-lg .chip-swatch { height: 34px; width: 12px; }

.chip-body { display: flex; flex-direction: column; flex: 1; min-width: 0; }

.chip-title {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 0.85rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.chip-lg .chip-title { font-size: 1rem; }

.chip-meta { font-size: 0.7rem; color: var(--text-sub); }

.chip-badges { display: flex; gap: 3px; flex: none; }

.trait {
    font-size: 0.66rem;
    font-weight: 700;
    padding: 2px 5px;
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.1);
    color: var(--text-sub);
}

.trait-reefer  { background: rgba(56, 189, 248, 0.22); color: #7dd3fc; }
.trait-hazmat  { background: rgba(245, 158, 11, 0.22); color: #fcd34d; }
.trait-fragile { background: rgba(167, 139, 250, 0.22); color: #ddd6fe; }
.trait-heavy   { background: rgba(239, 68, 68, 0.22); color: #fca5a5; }
.trait-day     { background: rgba(16, 185, 129, 0.2); color: #6ee7b7; }

/* ── control bar ─────────────────────────────────────────────────────── */

.control-bar {
    position: absolute;
    bottom: 16px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 15;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 12px 16px;
    background: var(--bg-card);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--glass-border);
    border-radius: 16px;
    padding: 9px 16px;
    box-shadow: var(--shadow);
    max-width: calc(100vw - 28px);
}

.toolbar-section { display: flex; flex-direction: column; gap: 4px; flex: none; }

.section-title {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--text-muted);
    font-weight: 700;
}

.button-group { display: flex; gap: 5px; }

/* What a collapsed section is set to. Only the narrow layout collapses, so on
   a desktop the value is redundant with the buttons themselves. */
.section-value { display: none; }

/* ── X/Y/Z console ───────────────────────────────────────────────────────
   Three axis pairs and a commit. A pointer aims to within a fingertip; this
   is how you place a container to within a slot, and the only way to place
   one accurately at all on a phone.
*/
.nudge-pad {
    display: grid;
    grid-template-columns: repeat(3, auto) 1fr;
    align-items: center;
    gap: 4px 6px;
}

.nudge-btn {
    justify-content: center;
    padding: 6px 10px;
    font-size: 0.78rem;
    line-height: 1;
}

.nudge-axis {
    font-family: var(--font-heading);
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-muted);
    text-align: center;
    min-width: 14px;
}

.drop-btn {
    grid-row: 1 / span 3;
    grid-column: 4;
    justify-content: center;
    align-self: stretch;
    margin-left: 6px;
    font-weight: 600;
    color: var(--text-main);
    background: rgba(56, 189, 248, 0.16);
    border-color: rgba(56, 189, 248, 0.4);
}

.drop-btn:hover {
    background: rgba(56, 189, 248, 0.3);
    border-color: rgba(56, 189, 248, 0.6);
}

.nudge-readout {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.68rem;
    color: var(--text-muted);
    text-align: center;
    padding-top: 3px;
    white-space: nowrap;
}

/* Held by the console against the pointer — worth saying, since a mouse move
   would otherwise be expected to take the aim back. */
.nudge-readout.locked { color: var(--accent-cyan); }

.tool-btn, .palette-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 7px 11px;
    border-radius: 9px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-sub);
    font-family: var(--font-body);
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.16s ease, color 0.16s ease, border-color 0.16s ease;
}

.tool-btn:hover, .palette-btn:hover {
    background: rgba(255, 255, 255, 0.1);
    color: var(--text-main);
    border-color: rgba(255, 255, 255, 0.18);
}

.tool-btn.active, .palette-btn.active {
    background: rgba(56, 189, 248, 0.18);
    color: #fff;
    border-color: rgba(56, 189, 248, 0.5);
    box-shadow: 0 0 12px rgba(56, 189, 248, 0.22);
}

.tool-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.tool-btn.danger:hover { background: rgba(239, 68, 68, 0.2); color: #fca5a5; border-color: rgba(239, 68, 68, 0.45); }

.color-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; flex: none; }

.select-input {
    padding: 7px 10px;
    border-radius: 9px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: rgba(15, 23, 42, 0.85);
    color: var(--text-main);
    font-family: var(--font-body);
    font-size: 0.8rem;
    cursor: pointer;
}

.cursor-note {
    font-size: 0.78rem;
    color: var(--text-muted);
    min-width: 190px;
    padding-left: 12px;
    border-left: 1px solid rgba(255, 255, 255, 0.1);
    line-height: 1.35;
}

.cursor-note.ok  { color: #6ee7b7; }
.cursor-note.bad { color: #fca5a5; }

/* ── rejection flash ─────────────────────────────────────────────────── */

/* A toast, not a curtain: it used to sit dead-centre on the yard, which meant
   every rejection or collapse notice hid the very stack it was reporting on.
   Anchored under the top bar instead, it stays legible without ever covering
   the thing the player just asked to look at. */
.reason-flash {
    position: absolute;
    top: 82px;
    left: 50%;
    transform: translate(-50%, -10px) scale(0.94);
    z-index: 18;
    max-width: min(90vw, 460px);
    text-align: center;
    background: rgba(127, 29, 29, 0.9);
    border: 1px solid rgba(248, 113, 113, 0.55);
    color: #fee2e2;
    font-weight: 600;
    font-size: 0.92rem;
    padding: 11px 20px;
    border-radius: 11px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.18s ease, transform 0.18s ease;
    box-shadow: 0 10px 34px rgba(0, 0, 0, 0.5);
}

.reason-flash.visible { opacity: 1; transform: translate(-50%, 0) scale(1); }

.reason-flash.good {
    background: rgba(6, 78, 59, 0.92);
    border-color: rgba(52, 211, 153, 0.55);
    color: #d1fae5;
}

/* ── contracts (sandbox job board) ───────────────────────────────────── */

.metric-val.gold { color: var(--gold); }

.contract-box {
    margin: 12px 0 10px;
    padding: 11px;
    border-radius: 10px;
    background: rgba(56, 189, 248, 0.07);
    border: 1px solid rgba(56, 189, 248, 0.22);
}

.contract-box h4 {
    font-family: var(--font-heading);
    font-size: 0.86rem;
    font-weight: 700;
    margin-bottom: 5px;
    line-height: 1.35;
}

.contract-box p {
    font-size: 0.75rem;
    color: var(--text-sub);
    line-height: 1.45;
    margin-bottom: 9px;
}

.contract-meta {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    font-size: 0.72rem;
    font-weight: 700;
}

.tag-reward { color: var(--accent-green); }
.tag-timer { color: var(--text-sub); }
.tag-timer.urgent { color: #fca5a5; }

.contract-progress {
    height: 4px;
    border-radius: 99px;
    background: rgba(255, 255, 255, 0.09);
    margin-top: 8px;
    overflow: hidden;
}

.contract-progress span {
    display: block;
    height: 100%;
    width: 100%;
    background: linear-gradient(90deg, var(--accent-cyan), var(--accent-indigo));
    transition: width 0.3s linear;
}

.upgrade-grid {
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin-top: 6px;
}

.upgrade-btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 9px;
    border-radius: 8px;
    border: 1px solid var(--glass-border);
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-main);
    font-family: var(--font-body);
    font-size: 0.75rem;
    cursor: pointer;
    transition: background 0.15s ease;
}

.upgrade-btn:hover:not(:disabled) { background: rgba(56, 189, 248, 0.16); }
.upgrade-btn:disabled { opacity: 0.45; cursor: not-allowed; }

.upgrade-btn.owned {
    border-color: rgba(16, 185, 129, 0.4);
    background: rgba(16, 185, 129, 0.12);
    opacity: 0.85;
}

.up-label { font-weight: 600; }
.up-cost { font-family: var(--font-heading); font-weight: 700; color: var(--gold); }
.upgrade-btn.owned .up-cost { color: var(--accent-green); }

/* ── inspector ───────────────────────────────────────────────────────── */

/* Sandbox keeps its stats (and the job board) on the right, so the inspector
   takes the left column that the mission queue would otherwise occupy. */
.inspector-card {
    position: absolute;
    top: 78px;
    left: 14px;
    width: 268px;
    z-index: 16;
}

.inspector-badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 6px;
    font-size: 0.74rem;
    font-weight: 600;
    background: rgba(56, 189, 248, 0.2);
    color: var(--accent-cyan);
    margin-bottom: 10px;
}

.inspector-grid {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 0.8rem;
    margin-bottom: 12px;
}

.inspector-grid > div { display: flex; justify-content: space-between; gap: 10px; }

.ins-label { color: var(--text-sub); }

.inspector-actions { display: flex; gap: 8px; }

#sandbox-hud { top: 78px; }

/* ── responsive ──────────────────────────────────────────────────────── */

@media (max-width: 1100px) {
    .hud-stack { width: 244px; }
    .queue-bar { width: 226px; }
    .cursor-note { display: none; }
}

@media (max-width: 820px), (max-height: 500px) {
    /* Yard statistics and the job board are a column of numbers with nowhere to
       go on a phone, and nothing in the sandbox depends on reading them. */
    #sandbox-hud { display: none; }

    /*
     * The mission readouts used to be hidden here too, which left a phone
     * playing blind: no manifest, no envelope, no medal, and no way to read the
     * regulation that just refused a move. They fold into one sheet instead —
     * closed by default so the yard is clear, with #mission-strip as its handle
     * and its summary.
     */
    .mission-sheet {
        display: flex;
        flex-direction: column;
        gap: 8px;
        position: absolute;
        top: calc(104px + var(--safe-top));
        left: calc(8px + var(--safe-left));
        right: calc(8px + var(--safe-right));
        bottom: calc(8px + var(--safe-bottom));
        z-index: 17;
        padding: 8px;
        border-radius: 14px;
        background: rgba(2, 6, 23, 0.8);
        backdrop-filter: blur(12px);
        -webkit-backdrop-filter: blur(12px);
        border: 1px solid var(--glass-border);
        box-shadow: var(--shadow);
        overflow-y: auto;
        overscroll-behavior: contain;
        touch-action: pan-y;
        opacity: 0;
        visibility: hidden;
        transform: translateY(-8px);
        transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
    }

    .mission-sheet.open { opacity: 1; visibility: visible; transform: none; }

    /* Inside the sheet the two panels are ordinary stacked blocks again. */
    .mission-sheet > .queue-bar,
    .mission-sheet > .hud-stack {
        position: static;
        width: auto;
        max-height: none;
        overflow: visible;
    }

    /* The strip: what is landing, how far in, and whether the envelope is still
       inside a medal — the four things a placement decision needs. */
    .mobile-strip {
        display: flex;
        align-items: center;
        gap: 8px;
        position: absolute;
        top: calc(60px + var(--safe-top));
        left: calc(8px + var(--safe-left));
        right: calc(8px + var(--safe-right));
        z-index: 18;
        min-height: 40px;
        padding: 6px 10px;
        border-radius: 12px;
        border: 1px solid var(--glass-border);
        background: var(--bg-card);
        backdrop-filter: blur(16px);
        -webkit-backdrop-filter: blur(16px);
        box-shadow: var(--shadow);
        color: var(--text-main);
        font-family: var(--font-body);
        font-size: 0.76rem;
        text-align: left;
        cursor: pointer;
    }

    .strip-now {
        display: flex;
        align-items: center;
        gap: 6px;
        flex: 1;
        min-width: 0;
        font-family: var(--font-heading);
        font-weight: 600;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* The queue chip's swatch is sized for a card; here it is a bar of colour
       beside one line of text. */
    .strip-now .chip-swatch { height: 17px; width: 6px; }

    .strip-stat { flex: none; color: var(--text-sub); }
    .strip-medal { flex: none; font-size: 0.95rem; line-height: 1; }

    .strip-caret {
        flex: none;
        color: var(--text-muted);
        font-size: 0.9rem;
        line-height: 0.7;
        transition: transform 0.16s ease;
    }

    .mobile-strip[aria-expanded="true"] { border-color: rgba(56, 189, 248, 0.45); }
    .mobile-strip[aria-expanded="true"] .strip-caret { transform: rotate(180deg); }

    /* Nothing legal left for this unit — the same warning the sheet spells out. */
    .mobile-strip.stuck { border-color: rgba(239, 68, 68, 0.55); }

    /* Below the mobile strip here, not the 82px desktop offset — the strip
       already occupies that band on a phone. */
    .reason-flash {
        top: calc(108px + var(--safe-top));
        max-width: none;
        left: calc(8px + var(--safe-left));
        right: calc(8px + var(--safe-right));
        transform: translateY(-10px) scale(0.94);
    }

    .reason-flash.visible { transform: translateY(0) scale(1); }

    /*
     * Selecting a container in the sandbox is pointless if the panel that
     * rotates or removes it is hidden, so the inspector keeps its buttons and
     * loses the layout it cannot afford: one strip under the top bar, two
     * columns of read-outs.
     */
    .inspector-card {
        display: block;
        top: calc(60px + var(--safe-top));
        left: calc(8px + var(--safe-left));
        right: calc(8px + var(--safe-right));
        width: auto;
        padding: 9px 11px;
    }

    .inspector-card .hud-card-header { margin-bottom: 7px; padding-bottom: 6px; }
    .inspector-card .inspector-badge { display: none; }

    .inspector-card .inspector-grid {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 6px 12px;
        font-size: 0.72rem;
        margin-bottom: 9px;
    }

    /* Label above value. Side by side, a container's dimensions and position
       are each long enough to wrap on their own, which reads as two ragged
       columns of fragments. */
    .inspector-card .inspector-grid > div {
        display: flex;
        flex-direction: column;
        gap: 0;
    }

    .inspector-card .inspector-grid strong { font-size: 0.78rem; }
    .inspector-card .btn-sm { padding: 10px; }

    /*
     * The bar was centred at a fixed width, so any group wider than the screen
     * — the six-button cargo palette, for one — overflowed both edges at once
     * and the first and last buttons could not be reached at all. Pin it to
     * both margins instead and let the sections collapse (see ui/toolbars.js),
     * so the bar is a strip of chips plus whichever one group is open.
     */
    .control-bar {
        left: calc(8px + var(--safe-left));
        right: calc(8px + var(--safe-right));
        bottom: calc(10px + var(--safe-bottom));
        transform: none;
        max-width: none;
        /* Of the shell, which is the visible viewport — see tokens.css. */
        max-height: 42%;
        overflow-y: auto;
        /* This is the scroller the player's thumb lands on. Contain it, or a
           swipe that reaches the end of the bar carries on into the page. */
        overscroll-behavior: contain;
        touch-action: pan-y;
        padding: 8px;
        gap: 6px;
        align-items: flex-start;
    }

    /* Collapsed sections are chips sized by their own text, so they pair up two
       or three to a row and a long one takes the space it needs; the open one
       takes a row of its own, which keeps the bar off the yard the tower is
       trying to grow into. */
    .toolbar-section { flex: 1 1 auto; min-width: 0; align-items: stretch; gap: 6px; }
    .toolbar-section.is-open { flex: 1 1 100%; }
    .button-group { flex-wrap: wrap; justify-content: center; }

    /* Chip-sized, but still a comfortable thumb target. */
    .toolbar-section.collapsible > .section-title {
        display: flex;
        align-items: center;
        gap: 6px;
        min-height: 34px;
        padding: 6px 9px;
        border-radius: 10px;
        /* Tighter than the desktop caption so two chips still share a row on a
           360px screen — the value beside it has to fit as well. */
        letter-spacing: 0.03em;
        border: 1px solid rgba(255, 255, 255, 0.08);
        background: rgba(255, 255, 255, 0.04);
        color: var(--text-sub);
        cursor: pointer;
        overflow: hidden;
        white-space: nowrap;
    }

    .toolbar-section.collapsible > .section-title::after {
        content: '⌄';
        margin-left: auto;
        font-size: 0.9rem;
        line-height: 0.7;
        color: var(--text-muted);
        transform: rotate(-90deg);
        transition: transform 0.16s ease;
    }

    .toolbar-section.is-open > .section-title {
        background: rgba(56, 189, 248, 0.14);
        border-color: rgba(56, 189, 248, 0.4);
        color: var(--text-main);
    }

    .toolbar-section.is-open > .section-title::after { transform: none; }

    .toolbar-section.collapsible > .section-title:focus-visible {
        outline: 2px solid var(--accent-cyan);
        outline-offset: 1px;
    }

    /* The state the section is set to, so a folded control is still readable. */
    .toolbar-section.collapsible .section-value {
        display: flex;
        align-items: center;
        gap: 5px;
        min-width: 0;
        font-size: 0.72rem;
        font-weight: 600;
        text-transform: none;
        letter-spacing: 0;
        color: var(--text-main);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* A section with nothing to report gets no separator dangling after it. */
    .toolbar-section.collapsible .section-value:not(:empty)::before {
        content: '·';
        color: var(--text-muted);
    }

    .toolbar-section.is-open .section-value { display: none; }

    .toolbar-section.collapsible:not(.is-open) > .button-group,
    .toolbar-section.collapsible:not(.is-open) > .nudge-readout,
    .toolbar-section.collapsible:not(.is-open) > .select-input { display: none; }

    /* The console is the section you keep open while you play, so it gets the
       room: the axis pairs stretch across the row and Drop takes the end. */
    /* The axis pairs stretch to a thumb's width, not to the bar's: on a phone
       held sideways the row is 800px wide and a full-width arrow is a worse
       target than a normal one, not a better one. */
    .nudge-pad {
        grid-template-columns: 1fr auto 1fr auto;
        gap: 6px;
        width: 100%;
        max-width: 420px;
        margin: 0 auto;
    }

    .nudge-btn { padding: 10px 8px; }
    .drop-btn { min-width: 84px; }

    /* Fingers, not a mouse pointer. */
    .tool-btn, .palette-btn { padding: 9px 12px; font-size: 0.82rem; }
    .select-input { width: 100%; padding: 9px 12px; }

    /*
     * The tower challenge is unplayable blind: height, best and whether the
     * stack is standing are the entire feedback loop. The full card does not
     * fit a phone, so the same numbers become a compact strip under the top bar.
     */
    #physics-hud {
        display: block;
        top: calc(60px + var(--safe-top));
        left: calc(8px + var(--safe-left));
        right: calc(8px + var(--safe-right));
        width: auto;
        max-height: none;
        overflow: visible;
    }

    #physics-hud .hud-card-header,
    #physics-hud .hud-tagline { display: none; }

    #physics-hud .hud-card { padding: 7px 10px; }

    #physics-hud .hud-card,
    #physics-hud #ph-tower-rows {
        display: flex;
        flex-wrap: wrap;
        gap: 2px 14px;
    }

    #physics-hud .metric-row { gap: 6px; padding: 0; font-size: 0.74rem; }
    #physics-hud .metric-label { font-size: 0.68rem; }

    /*
     * Cascade folds the same way, and for the same reason: score, tier fill and
     * what is coming next are the entire loop. The queue's chips are what goes —
     * a column of cards down the left edge of a falling yard is unreadable, and
     * the card's one-line "Next" row carries the lookahead instead.
     */
    #cascade-queue { display: none; }

    #cascade-hud {
        display: block;
        top: calc(60px + var(--safe-top));
        left: calc(8px + var(--safe-left));
        right: calc(8px + var(--safe-right));
        width: auto;
        max-height: none;
        overflow: visible;
    }

    #cascade-hud .hud-card-header,
    #cascade-hud .hud-tagline { display: none; }

    #cascade-hud .hud-card {
        padding: 7px 10px;
        display: flex;
        flex-wrap: wrap;
        gap: 2px 14px;
    }

    #cascade-hud .metric-row { gap: 6px; padding: 0; font-size: 0.74rem; }
    #cascade-hud .metric-label { font-size: 0.68rem; }
    #cascade-hud .metric-row.big .metric-val { font-size: 0.95rem; }
}

/* ── phone, landscape ────────────────────────────────────────────────────
   See tokens.css for why this is a separate block from the one above: same
   phone, but the top bar shrank, so every band anchored under it moves up to
   match, and every fixed-height bar gives back some of the padding a portrait
   layout could afford. */
@media (max-height: 500px) and (orientation: landscape) {
    .mobile-strip {
        top: calc(48px + var(--safe-top));
        min-height: 32px;
        padding: 4px 9px;
    }

    .mission-sheet {
        top: calc(84px + var(--safe-top));
        padding: 6px;
        background: rgba(2, 6, 23, 0.6);
    }

    .reason-flash { top: calc(88px + var(--safe-top)); }

    #physics-hud,
    #cascade-hud,
    .inspector-card {
        top: calc(46px + var(--safe-top));
    }

    .hud-card { padding: 10px 12px; }
    .hud-card-header { margin-bottom: 6px; padding-bottom: 5px; }

    #physics-hud .hud-card,
    #cascade-hud .hud-card { padding: 5px 9px; }

    .inspector-card { padding: 7px 10px; }
    .inspector-card .hud-card-header { margin-bottom: 4px; padding-bottom: 4px; }

    /* The bar itself: less air around a shorter row of chips, and a lower
       ceiling so an open section can't eat the yard the player is placing
       into. */
    .control-bar {
        bottom: calc(6px + var(--safe-bottom));
        padding: 6px 8px;
        gap: 4px 8px;
        max-height: 34%;
    }

    .toolbar-section.collapsible > .section-title {
        min-height: 28px;
        padding: 4px 8px;
    }

    .tool-btn, .palette-btn { padding: 6px 10px; font-size: 0.78rem; }
    .nudge-btn { padding: 7px 6px; }
    .select-input { padding: 6px 10px; }
}
