/* ===========================================================================
   Minefield Navigation Simulator — styles
   A clean, technical "sensor instrument" look: dark field, paper-white panels,
   monospace telemetry. No decorative cards or emoji; the data is the design.
   =========================================================================== */

:root {
    --bg:        #12151b;
    --panel:     #1c2129;
    --panel-2:   #232a34;
    --ink:       #e8edf2;
    --muted:     #8b97a7;
    --line:      #2c333f;
    --accent:    #c4f000;   /* lime instrument accent */

    /* Signal level colors (shared by JS for markers + heatmap legend) */
    --lvl-1: #3fbf6f;   /* green       */
    --lvl-2: #9ad035;   /* light green  */
    --lvl-3: #f2c12e;   /* yellow      */
    --lvl-4: #f08a2e;   /* orange      */
    --lvl-5: #e0473b;   /* red         */

    --field-w: 1000px;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

.app {
    max-width: 1040px;
    margin: 0 auto;
    padding: 24px 20px 48px;
}

/* ---- Header ------------------------------------------------------------- */
.app-header { margin-bottom: 18px; }

.app-header h1 {
    margin: 0;
    font-size: 1.5rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-weight: 700;
}

.tagline {
    margin: 4px 0 0;
    color: var(--muted);
    font-size: 0.9rem;
}

/* ---- Top telemetry panel ------------------------------------------------ */
.top-panel {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    margin-bottom: 14px;
}

.stat {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 10px 14px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.stat-label {
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}

.stat-value {
    font-family: "Consolas", "SF Mono", Menlo, monospace;
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.1;
}

.stat-value.coords { font-size: 1.1rem; }

.stat-sub {
    font-size: 0.75rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/* The signal stat recolors itself by level via an inline custom property. */
.stat-signal {
    border-color: var(--sig-color, var(--line));
    box-shadow: inset 0 0 0 1px var(--sig-color, transparent);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.stat-signal .stat-value,
.stat-signal .stat-sub { color: var(--sig-color, var(--ink)); }

/* ---- Scoreboard (Head-to-Head) ----------------------------------------- */
.scoreboard {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 10px 18px;
}
.scoreboard[hidden] { display: none; }
.score-team {
    display: flex;
    align-items: center;
    gap: 10px;
}
.score-team:last-child { justify-content: flex-end; }
.score-name {
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}
.score-num {
    font-family: "Consolas", monospace;
    font-size: 1.8rem;
    font-weight: 700;
}
.score-team.is-active .score-name { color: var(--accent); }
.score-team.is-active .score-num  { color: var(--accent); }
.score-mid {
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.score-round {
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
}
.score-role {
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--ink);
}

/* ---- Placement bar (Head-to-Head) -------------------------------------- */
.place-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 14px;
    background: var(--panel-2);
    border: 1px solid var(--accent);
    border-radius: 8px;
    padding: 10px 16px;
    flex-wrap: wrap;
}
.place-bar[hidden] { display: none; }
.place-msg { font-weight: 700; letter-spacing: 0.02em; }
.place-count {
    font-family: "Consolas", monospace;
    color: var(--muted);
    margin-right: auto;
}

/* ---- Health bar --------------------------------------------------------- */
.health-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 8px 14px;
}
.health-row[hidden] { display: none; }
.health-label {
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    min-width: 52px;
}
.health-track {
    position: relative;
    flex: 1;
    height: 14px;
    background: #0e1116;
    border: 1px solid var(--line);
    border-radius: 7px;
    overflow: hidden;
}
.health-fill {
    height: 100%;
    width: 100%;
    background: var(--lvl-1);
    transition: width 0.12s linear, background-color 0.25s ease;
}
.health-row.draining .health-fill { animation: healthPulse 0.6s ease-in-out infinite; }
@keyframes healthPulse { 50% { opacity: 0.55; } }
.health-pct {
    font-family: "Consolas", monospace;
    font-weight: 700;
    font-size: 0.95rem;
    min-width: 46px;
    text-align: right;
}
.lives-pips { display: inline-flex; align-items: center; gap: 4px; margin-left: 10px; }
.lives-pips[hidden] { display: none; }
.lives-pips .lp-label {
    font-size: 0.62rem; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--muted); margin-right: 3px;
}
.lives-pips .pip {
    width: 9px; height: 9px; border-radius: 50%;
    background: var(--lvl-5); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45);
}
.lives-pips .pip.off { background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }

/* ---- Field -------------------------------------------------------------- */
.field-wrap {
    display: flex;
    justify-content: center;
}

.field {
    position: relative;
    width: var(--field-w);
    /* Keep the 1000:600 ratio so the field scales uniformly (no horizontal
       squish, no oval mines) on viewports narrower than the field. */
    aspect-ratio: 5 / 3;
    max-width: 100%;
    /* Strict, screen-independent grid: a FIXED 25 x 15 cells (the 1000x600
       model at 40px cells), sized as fractions of the field so every screen
       shows the same grid. 100%/25 = 4% wide, 100%/15 = 6.6667% tall; at the
       5:3 box those work out square. (Was a fixed 40px, so the cell COUNT grew
       with the screen.) */
    background:
        linear-gradient(var(--line) 1px, transparent 1px) 0 0 / 4% 6.6667%,
        linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0 / 4% 6.6667%,
        #0e1116;
    border: 1px solid var(--line);
    border-radius: 10px;
    overflow: hidden;
    cursor: grab;            /* grab-and-drag the marker to move */
    touch-action: none;      /* the drag owns touch input — no scroll/zoom steal */
    user-select: none;       /* dragging must never select the START/END labels */
    -webkit-user-select: none;
}
.field:active { cursor: grabbing; }
/* Grab handle: a small knob at the marker's lower-right. Grabbing here (the
   anchored drag never jumps the marker) keeps your fingertip down-right of the
   marker, so the level number it displays stays visible up-left of your finger. */
#player::after {
    content: "";
    position: absolute;
    left: 50%; top: 50%;
    width: 12px; height: 12px;
    /* Sit clear of the marker body (radius ~14px) so the knob never crowds the
       centred level number. */
    transform: translate(19px, 19px);
    border-radius: 50%;
    background: rgba(236, 240, 245, 0.92);
    border: 1.5px solid rgba(0, 0, 0, 0.55);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
    pointer-events: none;
}
/* In portrait the marker spawns hard against the bottom (the START edge), so a
   down-right handle gets clipped by the field's overflow:hidden and "vanishes".
   Flip it up-right, where there's always room, so it stays visible at the start. */
body.is-portrait #player::after { transform: translate(19px, -19px); }
/* A small pop while dragging makes the marker read as the thing you're holding. */
.field.dragging #player { transform: scale(1.12); transition: transform 0.06s ease; }
/* During Head-to-Head placement the cursor is a crosshair so mines can be aimed. */
.field.placing { cursor: crosshair; }

.zone {
    position: absolute;
    top: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}
.zone span {
    writing-mode: vertical-rl;
    text-orientation: upright;
    letter-spacing: 0.3em;
    font-size: 0.75rem;
    font-weight: 700;
    color: rgba(255, 255, 255, 0.75);
}
.zone-start {
    left: 0;
    width: var(--zs-w, 80px);
    background: linear-gradient(90deg, rgba(46, 184, 92, 0.45), rgba(46, 184, 92, 0.10));
    border-right: 1px dashed rgba(46, 184, 92, 0.7);
}
.zone-end {
    right: 0;
    width: var(--ze-w, 80px);
    background: linear-gradient(270deg, rgba(53, 132, 224, 0.5), rgba(53, 132, 224, 0.12));
    border-left: 1px dashed rgba(53, 132, 224, 0.8);
}

/* ---- Portrait: the corridor stands up — START at the bottom, END at the top.
   Server geometry is unchanged; this only re-skins zones/edges to match the
   rotated view the canvas + JS transform produce. -------------------------- */
body.is-portrait .field {
    /* HEIGHT-driven (not width) so the standing corridor can never overflow the
       viewport — that overflow is what pushed the START end (and the mines near
       it) below the fold, so they read as "missing". The dvh cap keeps the board
       inside the *visible* height even as the mobile address bar collapses;
       150vw (== 90vw * 5/3) caps the width on narrow phones. width derives from
       the height via aspect-ratio, so the 3:5 box never distorts. */
    aspect-ratio: 3 / 5;
    width: auto;
    height: min(52vh, 150vw);
    height: min(52dvh, 150vw);
    margin: 0 auto;
    /* Same strict grid, rotated for the standing 3:5 board: 15 cols x 25 rows. */
    background-size: 6.6667% 4%, 6.6667% 4%;
}
body.is-portrait .zone { left: 0; right: 0; top: auto; bottom: auto; }
body.is-portrait .zone-start {
    bottom: 0; height: var(--zs-h); width: auto;
    background: linear-gradient(0deg, rgba(46, 184, 92, 0.45), rgba(46, 184, 92, 0.10));
    border-right: none; border-top: 1px dashed rgba(46, 184, 92, 0.7);
}
body.is-portrait .zone-end {
    top: 0; height: var(--ze-h); width: auto;
    background: linear-gradient(180deg, rgba(53, 132, 224, 0.5), rgba(53, 132, 224, 0.12));
    border-left: none; border-bottom: 1px dashed rgba(53, 132, 224, 0.8);
}
body.is-portrait .zone span { writing-mode: horizontal-tb; }
/* Deadly edges become the LEFT/RIGHT bands, spanning between the two zones. */
body.is-portrait .hazard {
    left: auto; right: auto; top: var(--ze-h); bottom: var(--zs-h);
    width: var(--edge-band); height: auto;
}
body.is-portrait .hazard-top    { left: 0;  right: auto; border-bottom: none; border-right: 1px dashed rgba(224, 71, 59, 0.65); }
body.is-portrait .hazard-bottom { right: 0; left: auto;  border-top: none;    border-left: 1px dashed rgba(224, 71, 59, 0.65); }

#overlay {
    position: absolute;
    inset: 0;
    /* A <canvas> is a REPLACED element, so inset:0 alone does NOT stretch it —
       it would render at its intrinsic buffer size (600x1000 portrait / 1000x600
       landscape) and get clipped by the field's overflow:hidden whenever the
       field is smaller than the buffer (every phone; any window < 1000px wide).
       width/height:100% makes the canvas SCALE its buffer to the field box, so
       the mine layout always fills the field instead of spilling out of view. */
    width: 100%;
    height: 100%;
    display: block;
    pointer-events: none;     /* canvas never steals mouse events */
}

/* Deadly edge hazard strips — the top/bottom band of the open corridor.
   Positioned from CSS vars set in JS so they track the server's edgeMargin
   and zone widths. Sit under the canvas so markers/path draw over them. */
.hazard {
    position: absolute;
    left: var(--zone-left, 8%);
    right: var(--zone-right, 8%);
    height: var(--edge-band, 6.6%);
    pointer-events: none;
    background: repeating-linear-gradient(
        45deg,
        rgba(224, 71, 59, 0.30) 0 9px,
        rgba(224, 71, 59, 0.08) 9px 18px);
}
.hazard-top    { top: 0;    border-bottom: 1px dashed rgba(224, 71, 59, 0.65); }
.hazard-bottom { bottom: 0; border-top:    1px dashed rgba(224, 71, 59, 0.65); }

/* The player marker doubles as the live signal readout: a level-colored dot
   with the current signal number inside. Color is set from JS per level. */
.player {
    position: absolute;
    width: 28px;
    height: 28px;
    margin: -14px 0 0 -14px;   /* center on the coordinate */
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: "Consolas", monospace;
    font-weight: 700;
    font-size: 0.95rem;
    color: #10130a;            /* set per-level from JS */
    background: var(--lvl-1);  /* set per-level from JS */
    border: 2px solid #fff;    /* constant ring so "you" always stands out */
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.55), 0 0 12px rgba(0, 0, 0, 0.55);
    pointer-events: none;
    z-index: 5;
}

/* Transient in-run message (respawn after death, etc.). */
.run-toast {
    position: absolute;
    top: 18px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 7;
    background: rgba(224, 71, 59, 0.94);
    color: #fff;
    font-family: "Consolas", monospace;
    font-weight: 700;
    font-size: 0.9rem;
    letter-spacing: 0.02em;
    padding: 8px 16px;
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, 0.25);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
    pointer-events: none;
    max-width: 80%;
    text-align: center;
    animation: runToastIn 0.18s ease;
}
.run-toast[hidden] { display: none; }
@keyframes runToastIn { from { opacity: 0; } }

/* Start / Pause overlay. Anchored to the viewport (not the field) so the
   dialog centers on the page and can use the full window height — this gives
   the settings room to breathe and keeps scrolling inside the card minimal. */
.start-overlay {
    position: fixed;
    inset: 0;
    z-index: 8;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(10, 12, 16, 0.72);
    backdrop-filter: blur(2px);
    cursor: default;   /* the field hides the cursor; restore it over the dialog */
}
.start-overlay[hidden] { display: none; }

.start-card {
    width: min(820px, 100%);
    max-height: 92vh;
    overflow-y: auto;
    text-align: center;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 18px 22px;
    box-shadow: 0 16px 44px rgba(0, 0, 0, 0.55);
}

/* Settings embedded in the Start modal. */
.start-settings { margin: 2px 0 12px; }
.start-settings .settings-grid {
    grid-template-columns: 1fr 1fr;
    gap: 10px 16px;
    text-align: left;
    padding: 0;
}
.start-settings[hidden] { display: none; }

/* Primary "Game Mode" selector — full width and a touch larger so it reads as
   the first decision, not just another field in the grid. */
.mode-row {
    text-align: left;
    margin-bottom: 10px;
}
.mode-row label,
.mode-label {
    display: block;
    font-size: 0.72rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 5px;
}
.mode-row select {
    font: inherit;
    width: 100%;
    background: var(--panel-2);
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 9px 10px;
    accent-color: var(--accent);
}
/* Game-mode chips — three equal, tappable options instead of a dropdown. */
.mode-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.mode-chip {
    flex: 1 1 0; min-width: 110px;
    font: inherit; font-weight: 600;
    background: var(--panel-2); color: var(--ink);
    border: 1px solid var(--line); border-radius: 8px;
    padding: 11px 12px; cursor: pointer; text-align: center;
    transition: border-color 0.12s ease, box-shadow 0.12s ease, color 0.12s ease;
}
.mode-chip:hover { border-color: var(--muted); }
.mode-chip.is-active { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); color: var(--accent); }

/* vs CPU "Random puzzle" quick-play row. */
.coop-quick {
    display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
    background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
    padding: 8px 10px; margin: 0 0 12px;
}
.coop-quick[hidden] { display: none; }
.coop-quick .dq-label {
    font-size: 0.66rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
.cq-hint { font-size: 0.72rem; color: var(--muted); margin-left: auto; }

/* Two-column setup body: preview on the left, field controls on the right so
   the dialog stays short. Collapses to a single column on narrow screens. */
.setup-cols {
    display: grid;
    grid-template-columns: minmax(0, 380px) 1fr;
    gap: 18px;
    align-items: start;
}
/* Stack the four field controls in the right column so they read top-to-bottom
   alongside the preview and fill the column width comfortably. */
.setup-cols .manual-grid { grid-template-columns: 1fr; gap: 12px; }
@media (max-width: 620px) {
    .setup-cols { grid-template-columns: 1fr; }
    /* Back to two-up once the columns stack, to keep the list short. */
    .setup-cols .manual-grid { grid-template-columns: 1fr 1fr; }
}
/* On the narrowest phones two selects per row get cramped — go single column. */
@media (max-width: 400px) {
    .setup-cols .manual-grid { grid-template-columns: 1fr; }
}

/* Live field preview inside the Start modal. */
.preview-wrap { margin: 0; }
.preview-canvas {
    display: block;
    width: 100%;
    max-width: 380px;          /* keep it compact so settings stay in view */
    margin: 0 auto;
    height: auto;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: #0e1116;
}
.preview-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: 6px auto 0;
    max-width: 380px;
    font-size: 0.74rem;
    color: var(--muted);
}
.btn-sm { padding: 5px 12px; font-size: 0.8rem; }

/* Visible keyboard focus across all interactive controls (none existed). */
.btn:focus-visible,
.btn-sm:focus-visible,
.daily-level:focus-visible,
.setting select:focus-visible,
.setting input:focus-visible,
.advanced > summary:focus-visible,
.debug-toggle input:focus-visible,
a:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Advanced (collapsed) settings group. */
.advanced {
    margin-top: 8px;
    border-top: 1px solid var(--line);
    padding-top: 6px;
    text-align: left;
}
.advanced > summary {
    cursor: pointer;
    font-size: 0.78rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
    padding: 4px 2px;
    user-select: none;
}
.advanced > summary:hover { color: var(--ink); }
.advanced[open] > .settings-grid { margin-top: 8px; }
/* The 8 advanced options flow into as many columns as the wider card allows. */
.start-settings .advanced .settings-grid {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.start-card h2 {
    margin: 0 0 6px;
    font-size: 1.2rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--accent);
}
.start-card p {
    margin: 0 0 10px;
    color: var(--muted);
    font-size: 0.86rem;
    line-height: 1.4;
}
.btn-start { font-size: 1.05rem; padding: 12px 28px; }
.start-foot {
    margin: 10px 0 0 !important;
    font-size: 0.74rem;
}
.start-card kbd {
    font-family: "Consolas", monospace;
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 4px;
    padding: 1px 6px;
    color: var(--ink);
}

/* Start-card action row: primary Start + a secondary How-to-Play. */
.start-actions {
    display: flex;
    gap: 10px;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
}
.btn-howto { font-size: 0.95rem; padding: 12px 20px; }

/* ---- How-to-play (instructions) modal ----------------------------------- */
.howto-backdrop {
    position: fixed;
    inset: 0;
    z-index: 9000;             /* above the Start overlay (8), below Exit-FS (9999) */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(8, 10, 14, 0.82);
    backdrop-filter: blur(2px);
}
.howto-backdrop[hidden] { display: none; }
.howto-card {
    width: min(540px, 100%);
    max-height: 90vh;
    overflow-y: auto;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 22px 24px;
    box-shadow: 0 16px 44px rgba(0, 0, 0, 0.6);
}
.howto-card h2 {
    margin: 0 0 14px;
    font-size: 1.25rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--accent);
}
.howto-list { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 11px; }
.howto-list li { display: grid; grid-template-columns: 64px 1fr; gap: 12px; align-items: start; }
.howto-list span:last-child { font-size: 0.9rem; line-height: 1.4; color: var(--ink); }
.howto-tag {
    font-size: 0.62rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--muted);
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 4px;
    padding: 4px 0;
    text-align: center;
}
.howto-list .chip { padding: 1px 7px; font-size: 0.7rem; vertical-align: middle; }
.howto-skip {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.82rem;
    color: var(--muted);
    margin: 4px 0 16px;
    cursor: pointer;
    user-select: none;
}
.howto-skip input { accent-color: var(--accent); width: 16px; height: 16px; }
.howto-card .btn-primary { width: 100%; padding: 12px 0; font-size: 1.02rem; }

/* ---- Bottom controls ---------------------------------------------------- */
.bottom-panel {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 16px 0 10px;
    flex-wrap: wrap;
}

.btn {
    font: inherit;
    font-weight: 600;
    color: var(--ink);
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 10px 18px;
    cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease, transform 0.05s ease;
}
.btn:hover:not(:disabled) { border-color: var(--muted); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.btn-primary {
    background: var(--accent);
    color: #1a1d10;
    border-color: var(--accent);
}
.btn-primary:hover:not(:disabled) { filter: brightness(1.05); }

.debug-toggle {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--muted);
    font-size: 0.85rem;
    cursor: pointer;
    user-select: none;
}
.debug-toggle input { accent-color: var(--accent); width: 16px; height: 16px; }
.debug-toggle input:disabled { opacity: 0.4; }
/* Group wrapper: transparent to layout so each toggle is still a flex item,
   but hideable as one unit while a game is in progress. */
.debug-toggles { display: contents; }
.debug-toggles[hidden] { display: none; }

/* Floating "Exit Fullscreen" — sits above every overlay so it's reachable even
   from the Start menu while fullscreen. Shown only in fullscreen (JS-toggled). */
.fs-exit {
    position: fixed;
    top: 10px; right: 10px;
    z-index: 9999;
    font: inherit; font-size: 0.76rem; font-weight: 600;
    color: var(--ink);
    background: rgba(20, 24, 30, 0.88);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 7px 12px;
    cursor: pointer;
    backdrop-filter: blur(2px);
}
.fs-exit:hover { border-color: var(--muted); }
.fs-exit[hidden] { display: none; }

/* ---- Legend ------------------------------------------------------------- */
.legend {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin: 6px 0 0;
}
.chip {
    font-family: "Consolas", monospace;
    font-size: 0.72rem;
    font-weight: 700;
    color: #10130a;
    padding: 3px 9px;
    border-radius: 20px;
}
.chip.lvl-1 { background: var(--lvl-1); }
.chip.lvl-2 { background: var(--lvl-2); }
.chip.lvl-3 { background: var(--lvl-3); }
.chip.lvl-4 { background: var(--lvl-4); color: #fff; }
.chip.lvl-5 { background: var(--lvl-5); color: #fff; }

/* ---- Settings grid (used by the Start modal) ---------------------------- */
.settings-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 14px;
    padding: 8px 0 4px;
}
.setting { display: flex; flex-direction: column; gap: 5px; }
.setting label {
    font-size: 0.72rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
    display: flex;
    justify-content: space-between;
}
.setting output { color: var(--accent); font-family: "Consolas", monospace; }
.setting select,
.setting input[type="range"] {
    font: inherit;
    width: 100%;
    accent-color: var(--accent);
}
.setting select {
    background: var(--panel-2);
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 6px 8px;
}
@media (max-width: 720px) { .settings-grid { grid-template-columns: 1fr 1fr; } }

/* ---- Results overlay ---------------------------------------------------- */
.results-outcome {
    margin: -6px 0 16px;
    font-size: 0.95rem;
    color: var(--muted);
}
/* Defeat styling — the results dialog turns hostile red on death. */
.results.defeat h2 { color: var(--lvl-5); }

.results-actions {
    display: flex;
    gap: 10px;
    justify-content: center;
}

/* Floating button to reopen results after reviewing the revealed field. */
.reopen-results {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 60;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
.reopen-results[hidden] { display: none; }

.results-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(8, 10, 14, 0.78);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 50;
}
/* The `hidden` attribute must win over `display:flex` above, otherwise the
   dialog can never be dismissed. */
.results-backdrop[hidden] { display: none; }
.results {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 28px 32px;
    width: min(520px, 92vw);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
}
.results h2 {
    margin: 0 0 18px;
    font-size: 1.6rem;
    letter-spacing: 0.03em;
    color: var(--accent);
}
.results-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    margin-bottom: 16px;
}
.result-item {
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.result-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--muted);
}
.result-value {
    font-family: "Consolas", monospace;
    font-size: 1.4rem;
    font-weight: 700;
}
.results-caption {
    font-size: 0.85rem;
    color: var(--muted);
    margin: 0 0 18px;
}

/* ---- Daily Challenge ---------------------------------------------------- */
.daily-panel { text-align: left; margin: 4px 0 8px; }
.daily-panel[hidden] { display: none; }
#manualSettings[hidden], #previewWrap[hidden], #advancedWrap[hidden] { display: none; }

.daily-datebar { display: flex; align-items: flex-end; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.daily-datebar .setting { flex: 1; min-width: 0; }   /* let the date input shrink, don't overflow */
.daily-datebar input[type="date"] {
    background: var(--panel-2); color: var(--ink);
    border: 1px solid var(--line); border-radius: 6px;
    padding: 6px 8px; font: inherit; width: 100%;
}

.daily-levels { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 10px; }
.daily-level {
    display: flex; flex-direction: column; gap: 3px; align-items: flex-start;
    background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
    padding: 8px 10px; cursor: pointer; color: var(--ink); font: inherit; text-align: left;
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.daily-level:hover { border-color: var(--muted); }
.daily-level.is-active { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.dl-name { font-weight: 700; letter-spacing: 0.03em; }
.dl-meta { font-size: 0.68rem; color: var(--muted); font-family: "Consolas", monospace; }
.daily-level.is-active .dl-name { color: var(--accent); }

.daily-attempts { margin: 0 0 12px; font-size: 0.85rem; color: var(--ink); font-weight: 600; }

/* "Clear all three" framing + per-day progress. */
.daily-goal { margin: 0 0 10px; font-size: 0.86rem; color: var(--ink); }
.daily-goal strong { color: var(--accent); }
.daily-progress { margin: 0 0 8px; font-size: 0.8rem; color: var(--muted); font-family: "Consolas", monospace; }
.daily-progress.is-complete { color: var(--accent); font-weight: 700; }
.daily-progress:empty { display: none; }

/* Quick-play row (random / random past). */
.daily-quick {
    display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
    background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
    padding: 8px 10px; margin: 0 0 12px;
}
.daily-quick .dq-label {
    font-size: 0.66rem; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--muted); margin-right: auto;
}

/* Completed-level badge on the level picker. */
.daily-level.is-done { border-color: var(--lvl-1); }
.daily-level.is-done .dl-name::after {
    content: " ✓"; color: var(--lvl-1); font-weight: 700;
}

/* "Challenge a friend" — shares a deep link to this exact date/level. */
.daily-share {
    display: inline-block;
    margin: 0 0 12px;
    background: transparent;
    border-color: var(--accent);
    color: var(--accent);
}
.daily-share:hover { background: rgba(196, 240, 0, 0.10); }
.daily-share[hidden] { display: none; }
#drShareBtn { margin: 0 0 14px; }

.daily-board { background: #0e1116; border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; }
.daily-board-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; }
.daily-board-title { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); font-weight: 700; }
.daily-board-sub { font-size: 0.72rem; color: var(--muted); font-family: "Consolas", monospace; }
.daily-board-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; max-height: 140px; overflow-y: auto; }
.daily-board-list li {
    display: grid; grid-template-columns: 30px 1fr auto auto; gap: 8px; align-items: center;
    font-size: 0.82rem; padding: 3px 4px; border-radius: 4px;
}
.daily-board-list .db-rank  { color: var(--muted); font-family: "Consolas", monospace; text-align: right; }
.daily-board-list .db-name  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.daily-board-list .db-score { font-family: "Consolas", monospace; font-weight: 700; color: var(--accent); }
.daily-board-list .db-time  { font-family: "Consolas", monospace; color: var(--muted); min-width: 48px; text-align: right; }
.daily-board-list .db-you   { background: var(--panel-2); border: 1px solid var(--line); }
.daily-board-list .db-you .db-name { color: var(--accent); font-weight: 700; }
.daily-board-empty { color: var(--muted); font-size: 0.8rem; padding: 6px 4px !important; display: block !important; }

.daily-editor-link { display: inline-block; margin-top: 10px; font-size: 0.78rem; color: var(--muted); text-decoration: none; }
.daily-editor-link:hover { color: var(--accent); }
.daily-editor-link[hidden] { display: none; }
.daily-season-link { display: block; margin-top: 12px; font-size: 0.8rem; color: var(--accent); text-decoration: none; }
.daily-season-link:hover { text-decoration: underline; }

/* Daily result block inside the results dialog */
.daily-result { margin: 4px 0 16px; border-top: 1px solid var(--line); padding-top: 14px; }
.daily-result[hidden] { display: none; }
.dr-headline { display: flex; align-items: center; gap: 18px; margin-bottom: 8px; }
.dr-score { display: flex; flex-direction: column; align-items: center; line-height: 1; }
.dr-score-num { font-family: "Consolas", monospace; font-size: 2.4rem; font-weight: 700; color: var(--accent); }
.dr-score-label { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted); margin-top: 3px; }
.dr-stats { display: flex; flex-direction: column; gap: 3px; font-size: 0.88rem; }
.dr-stats span { font-family: "Consolas", monospace; }
.dr-breakdown { font-family: "Consolas", monospace; font-size: 0.74rem; color: var(--muted); margin-bottom: 10px; }

@media (max-width: 560px) { .daily-levels { grid-template-columns: 1fr; } }

/* Touch-friendly + non-overflowing on phones. */
.stat { min-width: 0; }   /* let grid cells shrink instead of forcing overflow */
@media (max-width: 640px) {
    /* Trim the page chrome so the board isn't pushed off-screen. */
    .app { padding: 12px 12px 16px; }
    .app-header { margin-bottom: 8px; }
    .app-header h1 { font-size: 1.15rem; }
    .tagline { display: none; }                       /* fluff on a phone */
    .top-panel { grid-template-columns: 1fr 1fr; margin-bottom: 10px; }   /* 4-up telemetry -> 2x2 */
    .stat { padding: 7px 11px; }            /* reclaim vertical room for the board */
    .stat-value { font-size: 1.25rem; }
    .bottom-panel { gap: 10px; justify-content: center; }
    .bottom-panel .btn { padding: 13px 18px; min-height: 46px; }
    .btn-sm { min-height: 40px; padding: 8px 14px; }   /* Shuffle / Today reachable by thumb */
    .debug-toggle { font-size: 0.9rem; }
    .debug-toggle input { width: 20px; height: 20px; }
}

/* ---- Fullscreen ---------------------------------------------------------- */
/* In fullscreen it's a game, not a web page: drop the page header + legend and
   tighten spacing. The whole game is laid out as a viewport-tall flex column
   that is CENTERED vertically (so it isn't pinned to the top) and never scrolls.
   `is-fullscreen` is toggled from JS on fullscreenchange. */
body.is-fullscreen { overflow: hidden; }
body.is-fullscreen .app {
    display: flex;
    flex-direction: column;
    justify-content: center;     /* centre the stack — no more "pushed to the top" */
    height: 100vh;
    height: 100dvh;
    max-width: 100%;             /* use the full width the centred board may need */
    overflow: hidden;            /* hard requirement: fullscreen must not scroll */
    padding: 6px 12px;
    gap: 6px;
}
body.is-fullscreen .app-header,
body.is-fullscreen .legend { display: none; }
body.is-fullscreen .top-panel,
body.is-fullscreen .health-row,
body.is-fullscreen .bottom-panel,
body.is-fullscreen .scoreboard { margin: 0; flex: 0 0 auto; }
/* Compact telemetry so the field gets the reclaimed vertical room. */
body.is-fullscreen .stat { padding: 6px 10px; }
body.is-fullscreen .stat-value { font-size: 1.15rem; }
/* The board takes the leftover middle and centres itself there. */
body.is-fullscreen .field-wrap { flex: 1 1 auto; min-height: 0; align-items: center; }
/* Size the board by whichever axis is limiting so it always fits the leftover
   space without distorting the 5:3 mines or overflowing (which would scroll):
   height is capped at ~70dvh (room for telemetry + controls) AND at the height
   whose derived width (height*5/3) still fits 96vw. width follows from aspect. */
body.is-fullscreen:not(.is-portrait) .field {
    width: auto;
    height: min(70dvh, 96vw * 3 / 5);
    max-width: 96vw;
    max-height: 100%;
}
/* Portrait fullscreen: stand the board up and fit the leftover height the same
   way (width = height*3/5, kept within 96vw). */
body.is-fullscreen.is-portrait .field {
    width: auto;
    height: min(88dvh, 96vw * 5 / 3);
    max-width: 96vw;
    max-height: 100%;
}

/* ---- Portrait fit-to-viewport (phones) ----------------------------------
   Belt-and-suspenders for the standing board: lay the page out as a
   viewport-tall flex column so the board can be clamped to the space the page
   chrome leaves, rather than relying on the min(52vh, 150vw) guess alone. The
   board keeps that height but max-height:100% trims it to the flex wrap when
   the chrome is tall — and because width is auto, aspect-ratio recomputes the
   width from the clamped height, so the 3:5 box never distorts (unlike a
   max-WIDTH clamp, which would leave the height untouched and squish it). */
@media (max-width: 640px) {
    body.is-portrait .app {
        display: flex;
        flex-direction: column;
        min-height: 100vh;
        min-height: 100dvh;
    }
    body.is-portrait .field-wrap {
        flex: 1 1 auto;
        min-height: 0;           /* allow the board to shrink to the space available */
        align-items: center;     /* centre the standing board in the leftover height */
    }
    body.is-portrait .field {
        max-height: 100%;        /* never taller than the leftover; width follows */
    }
}
