/* Cut the Fuse — retro off-white note-paper aesthetic (from prototype) */

/* Self-hosted 1930s poster fonts (local so the game works offline on portals). */
@font-face {
    font-family: 'Luckiest Guy';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('assets/fonts/luckiest-guy-latin.woff2') format('woff2');
}
@font-face {
    font-family: 'Baloo 2';
    font-style: normal;
    font-weight: 400 800; /* variable font */
    font-display: swap;
    src: url('assets/fonts/baloo-2-latin.woff2') format('woff2');
}

body, html {
    margin: 0; padding: 0; width: 100%; height: 100%;
    /* iOS PWA/landscape safe sizing: JS publishes --app-h = the VISIBLE
       viewport height (visualViewport), which excludes Safari's bottom toolbar
       and the PWA home-indicator/status-bar chrome. 100vh→100dvh are the
       no-JS fallbacks. */
    height: 100vh;
    height: var(--app-h, 100dvh);
    background-color: #F2E8D0; /* Aged off-white paper fallback */
    background-image: url('assets/ui/ui-bg-paper.jpg');
    background-repeat: repeat;
    background-size: 1024px 1024px; /* tileable vintage paper */
    overflow: hidden;
    font-family: 'Baloo 2', 'Luckiest Guy', 'Courier New', Courier, monospace;
    touch-action: none; /* Prevents mobile scrolling so we can swipe! */
    -webkit-user-select: none; user-select: none;
}
#game-container { position: relative; width: 100%; height: 100%; }
canvas { display: block; position: absolute; z-index: 10; }

/* ---- Loading / splash screen -------------------------------------------
   Purely static HTML+CSS so it is painted on the browser's FIRST frame, with
   no JS, no font download and no image fetch on the critical path (the mark is
   a plain <img> that degrades to empty if it hasn't arrived yet — the title,
   bar and hint below it are always visible). YouTube Playables requires
   firstFrameReady() to be called while this is up. */
#loading-overlay {
    /* Above the modals (100) so the splash cross-fades over the menu card that
       openMenu() has already put up, and below .host-shield (200) so a host
       pause during loading still blocks input on top of everything. */
    position: fixed; inset: 0; z-index: 150;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 18px;
    background-color: #F2E8D0;
    background-image: url('assets/ui/ui-bg-paper.jpg');
    background-repeat: repeat;
    background-size: 1024px 1024px;
    transition: opacity 260ms ease;
}
/* Fade-out state, then main.js removes it. */
#loading-overlay.is-hidden { opacity: 0; pointer-events: none; }
#loading-mark {
    width: 84px; height: 84px; object-fit: contain;
    animation: splash-spin 2.4s ease-in-out infinite;
}
#loading-title {
    font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', monospace;
    font-size: clamp(28px, 9vw, 64px);
    letter-spacing: 2px;
    color: #3A2A1A;
    text-shadow: 2px 2px 0 rgba(255, 255, 255, 0.6);
    text-align: center; padding: 0 16px;
}
/* Burning-fuse progress bar: a warm fill crawling across a soot track. */
#loading-bar {
    width: min(240px, 60vw); height: 10px;
    background: rgba(58, 42, 26, 0.18);
    border: 2px solid #3A2A1A; border-radius: 6px;
    overflow: hidden;
}
#loading-bar span {
    display: block; width: 40%; height: 100%;
    background: linear-gradient(90deg, #C8452F, #E8892F, #F2C14E);
    animation: splash-burn 1.15s ease-in-out infinite;
}
#loading-hint {
    font-size: 13px; letter-spacing: 3px;
    color: rgba(58, 42, 26, 0.72);
    animation: splash-pulse 1.6s ease-in-out infinite;
}
@keyframes splash-spin {
    0%, 100% { transform: rotate(-8deg); }
    50%      { transform: rotate(8deg); }
}
@keyframes splash-burn {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(250%); }
}
@keyframes splash-pulse {
    0%, 100% { opacity: 0.5; }
    50%      { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    #loading-mark, #loading-bar span, #loading-hint { animation: none; }
    #loading-bar span { width: 100%; }
}

/* Vintage film grain + scratches over the whole game, under the UI chrome.
   soft-light keeps the texture without darkening the paper. */
#film-overlay {
    position: absolute; inset: 0; z-index: 15;
    pointer-events: none;
    background-image:
        url('assets/ui/ui-bg-scratches.png'),
        url('assets/ui/ui-bg-grain.png');
    background-repeat: repeat;
    background-size: 1024px 1024px, 512px 512px;
    mix-blend-mode: soft-light;
    opacity: 0.65;
}

#ui-layer {
    position: absolute; top: 0; left: 0; width: 100%; height: 100%;
    pointer-events: none; z-index: 20;
    /* Respect the device chrome (notch/status bar/home indicator) so the
       header and controls never sit under it on iOS PWA landscape. */
    padding:
        calc(20px + env(safe-area-inset-top, 0px))
        calc(20px + env(safe-area-inset-right, 0px))
        calc(20px + env(safe-area-inset-bottom, 0px))
        calc(20px + env(safe-area-inset-left, 0px));
    box-sizing: border-box;
}
.header {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    color: #1c1917; font-size: 1.5rem; font-weight: bold;
    font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace;
}
#level-label { text-transform: uppercase; justify-self: start; }
#star-display {
    color: #d97706;
    display: inline-flex; align-items: center; gap: 6px;
    line-height: 1;
    justify-self: center;
    pointer-events: auto; /* opens the armory */
}
#star-display::before {
    content: ""; display: inline-block;
    width: 22px; height: 22px;
    margin-top: -6px; /* Luckiest Guy numerals sit high; lift the icon to match */
    background: url('assets/ui/ui-icon-star.png') no-repeat center / contain;
}
#snips-counter {
    display: inline-flex; align-items: center; gap: 5px;
    line-height: 1;
    padding: 2px 6px;
    border-radius: 10px;
    justify-self: end;
    transition: color 0.2s ease;
}
#snips-counter .snips-label { font-size: 0.9em; }
#snips-counter .snip-icon {
    width: 18px; height: 18px; object-fit: contain;
    margin-top: -5px; /* Luckiest Guy numerals sit high; lift the icons to match */
    transition: opacity 0.25s ease, filter 0.25s ease;
}
#snips-counter .snip-icon.spent { opacity: 0.22; filter: grayscale(1); }
#snips-counter.last-snip { color: #d97706; animation: snip-pulse 1s ease-in-out infinite; }
#snips-counter.depleted { color: #dc2626; }
#snips-counter.shake { animation: snip-shake 0.45s ease; }
#snips-counter.bonus { animation: snip-bonus 0.7s ease; }
#star-display.new-unlock { animation: snip-pulse 0.9s ease-in-out 3; }
#star-display.shake { animation: snip-shake 0.45s ease; }
@keyframes snip-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.55; }
}
@keyframes snip-bonus {
    0% { transform: scale(1); background: rgba(34, 197, 94, 0); box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
    30% { transform: scale(1.18); background: rgba(34, 197, 94, 0.35); box-shadow: 0 0 20px 5px rgba(34, 197, 94, 0.6); }
    100% { transform: scale(1); background: rgba(34, 197, 94, 0); box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
}
@keyframes snip-shake {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-5px) rotate(-3deg); }
    50% { transform: translateX(5px) rotate(3deg); }
    75% { transform: translateX(-3px); }
}

.controls {
    position: absolute;
    /* Clear the home indicator / notch before the corner offset applies. */
    bottom: calc(20px + env(safe-area-inset-bottom, 0px));
    right: calc(20px + env(safe-area-inset-right, 0px));
    display: flex; gap: 10px; pointer-events: auto;
}
.controls button {
    position: relative;
    background: #f5f5f4; border: 3px solid #1c1917; color: #1c1917;
    width: 56px; height: 56px; border-radius: 10px; font-size: 1.2rem;
    cursor: pointer; font-weight: bold;
    box-shadow: 4px 4px 0px rgba(0,0,0,0.2);
    display: flex; justify-content: center; align-items: center;
    padding: 0;
}
.controls button img {
    width: 30px; height: 30px; object-fit: contain;
    pointer-events: none;
}
.controls button#btn-menu {
    width: auto; padding: 0 16px;
    font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace;
    font-size: 1.4rem; line-height: 1; color: #1c1917;
}
.controls button:hover { background: #e7e5e4; transform: translateY(-2px); }
.controls button.active { background: #fef08a; }

/* X-ray hint credit badge (rewarded builds only — Playables). Shows the
   remaining free/rewarded hint count on the corner of the hint button. */
.hint-count {
    display: none; /* hidden unless updateUi arms the rewarded economy */
    position: absolute; top: -6px; right: -6px;
    min-width: 22px; height: 22px; padding: 0 5px;
    border-radius: 11px;
    background: #2563eb; color: #fff;
    border: 2px solid #1c1917;
    font-size: 0.8rem; font-weight: bold; line-height: 18px;
    text-align: center; pointer-events: none;
}
.controls button.out { background: #fecaca; animation: hint-empty-pulse 1.2s ease-in-out infinite; }
@keyframes hint-empty-pulse {
    0%, 100% { box-shadow: 4px 4px 0px rgba(0,0,0,0.2); }
    50% { box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.35), 4px 4px 0px rgba(0,0,0,0.2); }
}
/* Muted speaker: dimmed + red slash badge */
#btn-mute.muted img { filter: grayscale(0.85) brightness(0.55); }
#btn-mute.muted::after {
    content: "✕";
    position: absolute; top: 6px; right: 8px;
    font-size: 1rem; line-height: 1; color: #ef4444; font-weight: bold;
}

/* Host-pause / ad shield: covers EVERYTHING (canvas, controls, modals) with a
   transparent layer so no pointer event reaches the game while the platform
   pauses (console pause) or an ad plays. Paired with body.inert for keyboard
   activation. z-index sits above .message-box (100). */
.host-shield {
    position: fixed; inset: 0; z-index: 200;
    background: transparent;
    display: none;
    cursor: default;
}

/* Modals at bottom, high z-index to prevent canvas blocking clicks */
.message-box {
    position: absolute;
    bottom: calc(40px + env(safe-area-inset-bottom, 0px));
    top: auto; left: 50%;
    transform: translateX(-50%);
    background-image: url('assets/ui/ui-card-modal.png');
    background-repeat: no-repeat;
    background-size: 100% 100%;
    padding: 40px 52px;
    border-radius: 0;
    border: 0;
    box-sizing: border-box; /* width/max-width include padding so modals never overflow small screens */
    text-align: center; color: #2B1F14;
    pointer-events: auto; display: none;
    box-shadow: none;
    z-index: 100;
    max-width: 92vw;
}
.message-box h1 { margin: 0 0 10px 0; font-size: 2.2rem; text-transform: uppercase; font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace; letter-spacing: 0.03em; }
.message-box p { font-size: 1.1rem; }
/* Direct-child buttons get the frame art. Scoped with > so inner buttons
   (e.g. the 60 level-select cells, which are <button> too) keep their own look.
   Frame is drawn in CSS (cream card + ink border + hard offset shadow) so it
   matches the mute/hint/zoom buttons exactly — no PNG corners to show through. */
.message-box > button {
    position: relative;
    background: #F6ECD1;              /* cream card fill */
    border: 4px solid #2B1F14;        /* ink outline */
    border-radius: 14px;
    box-shadow: 5px 5px 0 rgba(43, 31, 20, 0.85); /* hard offset shadow */
    outline: none;
    min-width: 220px; height: 96px;
    padding: 0 34px;
    font-size: 1.25rem;
    cursor: pointer; font-weight: bold; color: #2B1F14;
    font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace;
    letter-spacing: 0.04em;
    margin: 8px 6px;
    display: inline-flex; align-items: center; justify-content: center;
    text-shadow: 1px 1px 0 rgba(255, 244, 214, 0.35);
    transition: transform 0.08s ease, box-shadow 0.08s ease;
}
.message-box > button img {
    width: 30px; height: 30px; object-fit: contain;
    margin-right: 10px; pointer-events: none;
}
/* One frame for all states — hover lifts, press pushes down. Transform only:
   applying a filter here makes Chromium rasterize transparent PNG corners
   as a white box. */
.message-box > button:hover {
    transform: translateY(-2px) scale(1.03);
    box-shadow: 7px 7px 0 rgba(43, 31, 20, 0.85);
}
.message-box > button:active {
    transform: translateY(4px) scale(0.99);
    box-shadow: 2px 2px 0 rgba(43, 31, 20, 0.85);
}

/* Bottom action modals (lose/win): the button IS the modal — no card-in-card. */
#modal-lose,
#modal-win {
    background-image: none;
    background: none;
    border: 0;
    box-shadow: none;
    padding: 20px 24px;
}

.win-stars { display: flex; justify-content: center; gap: 12px; margin: 4px 0 10px; }
.win-stars img { width: 46px; height: 46px; object-fit: contain; }
.win-stars img.dim { filter: grayscale(1) brightness(0.7); opacity: 0.4; }
/* Earned stars pop into the case with a scale bounce + gold glow flash, then
   settle — the level-clear beat, kept short so it never drags. */
.win-stars img.pop {
    filter: none; opacity: 1;
    animation: star-pop 0.5s cubic-bezier(0.2, 1.4, 0.4, 1);
}
@keyframes star-pop {
    0% { transform: scale(0) rotate(-28deg); opacity: 0; filter: drop-shadow(0 0 0 rgba(253,224,71,0)); }
    45% { transform: scale(1.3) rotate(5deg); opacity: 1; filter: drop-shadow(0 0 12px rgba(253,224,71,.9)); }
    100% { transform: scale(1) rotate(0deg); opacity: 1; filter: drop-shadow(0 0 3px rgba(253,224,71,.35)); }
}
#win-stats {
    display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 14px;
    margin: 0 0 16px; font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace;
}
#win-stats .stat {
    display: inline-flex; align-items: center; justify-content: center;
    background: #1c1917; color: #f5f5f4;
    border-radius: 999px; padding: 6px 13px 3px; /* Luckiest Guy rises high in the em box; top-heavy padding centers it */
    font-size: 0.9rem; letter-spacing: 0.05em; line-height: 1;
    text-transform: uppercase;
}
#win-stats .stat.record { background: #d97706; color: #fff7ed; padding: 8px 13px 2px; animation: win-record-pulse 0.9s ease-in-out infinite alternate; } /* pure-caps pills: Luckiest Guy's tall "!" sits high, needs extra top padding */
#win-stats .stat.coverage { background: #dc2626; color: #fef2f2; } /* flame-red: how much of the maze actually burned */
#win-stats .stat.perfect { background: #16a34a; color: #f0fdf4; padding: 8px 13px 1px; } /* larger-glyph pills need more top-heavy padding */
#win-stats .stat.streak { background: #b45309; color: #fffbeb; padding: 8px 13px 2px; animation: win-record-pulse 0.9s ease-in-out infinite alternate; }
#win-stats .stat.score { background: #f59e0b; color: #451a03; font-size: 1.1rem; padding: 9px 13px 0; }
#win-stats .stat.best { background: #15803d; color: #f0fdf4; padding: 8px 13px 2px; animation: win-record-pulse 0.9s ease-in-out infinite alternate; }
@keyframes win-record-pulse { from { transform: scale(1); } to { transform: scale(1.08); } }

/* Tutorial overlay */
#tutorial-overlay {
    position: absolute; inset: 0; z-index: 90;
    display: none; justify-content: center; align-items: flex-start;
    pointer-events: none;
    padding-top: calc(var(--app-h, 100dvh) * 0.15);
}
#tutorial-box {
    background-image: url('assets/ui/ui-card-modal.png');
    background-repeat: no-repeat;
    background-size: 100% 100%;
    border: 0; border-radius: 0; box-shadow: none;
    padding: 30px 42px; text-align: center; color: #2B1F14;
    pointer-events: auto; max-width: 360px;
}
#tutorial-text { margin: 0 0 12px; font-size: 1.05rem; line-height: 1.35; }
#tutorial-next {
    background: #F6ECD1;
    border: 4px solid #2B1F14;
    border-radius: 12px;
    box-shadow: 4px 4px 0 rgba(43, 31, 20, 0.85);
    color: #2B1F14; font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace;
    font-size: 1.1rem; font-weight: bold; padding: 0 26px;
    min-width: 150px; height: 62px; cursor: pointer;
    transition: transform 0.08s ease, box-shadow 0.08s ease;
}
#tutorial-next:hover { transform: translateY(-2px) scale(1.03); box-shadow: 6px 6px 0 rgba(43, 31, 20, 0.85); }
#tutorial-next:active { transform: translateY(3px) scale(0.99); box-shadow: 1px 1px 0 rgba(43, 31, 20, 0.85); }

/* Skin select / level select / DDA: tall or multi-row dialogs keep a plain
   cream card so the frame art isn't stretched. */
.message-box.skins,
.message-box.level-select,
#modal-dda {
    box-sizing: border-box;
    background-image: none;
    background-color: #f6ecd1;
    border: 6px solid #1c1917;
    border-radius: 20px;
    box-shadow: 10px 10px 0px rgba(0,0,0,0.3);
}
.message-box.skins { width: min(94vw, 760px); }
.message-box.skins {
    /* Vertically centered (unlike the bottom-anchored win/lose cards) so the
       modal stays put when switching BOMBS ↔ IGNITERS and the grid height
       changes — bottom anchoring would make the top edge jump. */
    max-height: calc(var(--app-h, 100dvh) * 0.9);
    overflow-y: auto;
    top: 50%; bottom: auto;
    transform: translate(-50%, -50%);
}
#skin-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 14px;
    justify-content: center;
    margin: 12px 0;
    /* Fixed height (not max-height) so the armory modal keeps the SAME size
       when switching BOMBS ↔ IGNITERS — a 10-card grid vs a 3-card grid would
       otherwise collapse the modal and shift it around the screen. Taller
       content scrolls inside; shorter content leaves the box stable. */
    height: min(520px, calc(var(--app-h, 100dvh) * 0.60));
    overflow-y: auto;
    padding: 2px;
}
.skin-card {
    border: 3px solid #1c1917; border-radius: 12px;
    background: #f5f5f4; padding: 12px 10px 10px; cursor: pointer; text-align: center;
    box-sizing: border-box; min-width: 0;
    display: flex; flex-direction: column; align-items: center;
}
.skin-card img { width: 100%; height: 150px; object-fit: contain; }
.skin-card .skin-name { font-weight: bold; font-size: 0.95rem; line-height: 1.15; min-height: 2.2em; display: flex; align-items: center; }
.skin-card.locked { opacity: 0.35; cursor: not-allowed; }
.skin-card.selected { background: #fef08a; box-shadow: 0 0 0 3px #d97706; }
.skin-card .cost { font-size: 0.8rem; color: #d97706; font-weight: bold; }
.skin-card .blurb { font-size: 0.75rem; color: #57534e; min-height: 2.2em; }
.skin-card .skin-footer { margin-top: auto; }
.skin-card .unlock {
    font-size: 0.7rem; color: #b91c1c; font-weight: bold;
    text-transform: uppercase; letter-spacing: 0.02em;
}
.skin-card .watch-ad {
    display: inline-block; margin-top: 6px; padding: 4px 10px;
    background: #fef08a; border: 3px solid #2B1F14; border-radius: 8px;
    box-shadow: 3px 3px 0 rgba(43, 31, 20, 0.85);
    font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace;
    font-size: 0.75rem; color: #2B1F14; cursor: pointer; text-transform: uppercase;
    transition: transform 0.08s ease;
}
.skin-card .watch-ad:hover { transform: translateY(-1px); }
.skin-card .watch-ad:active { transform: translateY(2px); box-shadow: 1px 1px 0 rgba(43, 31, 20, 0.85); }
.skin-card .buy-stars {
    display: inline-block; margin-top: 6px; padding: 4px 10px;
    background: #fef08a; border: 3px solid #b45309; border-radius: 8px;
    box-shadow: 3px 3px 0 rgba(43, 31, 20, 0.85);
    font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace;
    font-size: 0.75rem; color: #b45309; cursor: pointer; text-transform: uppercase;
    transition: transform 0.08s ease, filter 0.12s ease;
}
.skin-card .buy-stars:hover:not(.unaffordable) { transform: translateY(-1px); }
.skin-card .buy-stars:active:not(.unaffordable) { transform: translateY(2px); box-shadow: 1px 1px 0 rgba(43, 31, 20, 0.85); }
.skin-card .buy-stars.unaffordable { background: #e7e5e4; border-color: #78716c; color: #78716c; cursor: not-allowed; box-shadow: none; }
.skin-card .selected-tag { font-size: 0.8rem; color: #b45309; font-weight: bold; text-transform: uppercase; }

#skin-tabs {
    display: flex; gap: 8px; justify-content: center; margin: 10px 0 4px;
}
#skin-tabs button {
    background: #F6ECD1; border: 3px solid #2B1F14; border-radius: 10px;
    box-shadow: 3px 3px 0 rgba(43, 31, 20, 0.85);
    padding: 6px 18px; font-size: 1rem; cursor: pointer;
    font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace;
    letter-spacing: 0.04em; color: #2B1F14; text-transform: uppercase;
    transition: transform 0.08s ease, background 0.15s ease;
}
#skin-tabs button:hover { transform: translateY(-1px); }
#skin-tabs button.active { background: #fef08a; box-shadow: 0 0 0 3px #d97706, 3px 3px 0 rgba(43, 31, 20, 0.85); }

/* Level selector */
#level-label {
    cursor: pointer;
    pointer-events: auto;
    padding: 4px 8px;
    margin: -4px -8px;
}
#level-label:hover { text-decoration: underline; }
#star-display { pointer-events: auto; }
.message-box.level-select {
    top: 50%; left: 50%; bottom: auto;
    transform: translate(-50%, -50%);
    width: min(94vw, 760px);
    max-height: calc(var(--app-h, 100dvh) * 0.86);
    padding: 20px 24px;
    display: none; flex-direction: column; align-items: center;
}
.message-box.level-select h1 { font-size: 1.8rem; }
#level-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
    gap: 10px;
    width: 100%;
    max-height: calc(var(--app-h, 100dvh) * 0.56);
    overflow-y: auto;
    padding: 4px;
    margin: 12px 0;
    box-sizing: border-box;
}
.level-cell {
    border: 3px solid #1c1917; border-radius: 10px;
    background: #f5f5f4; color: #1c1917;
    font-family: inherit; cursor: pointer;
    padding: 10px 4px; text-align: center;
    display: flex; flex-direction: column; gap: 4px;
    align-items: center;
    box-sizing: border-box;
}
.level-cell:hover:not(.locked) { background: #e7e5e4; transform: translateY(-1px); }
.level-cell .num { font-size: 1.35rem; font-weight: bold; line-height: 1; font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace; }
.level-cell .stars { display: inline-flex; gap: 2px; line-height: 1; }
.level-cell .stars img { width: 15px; height: 15px; object-fit: contain; }
.level-cell .stars img.dim { filter: grayscale(1) brightness(0.55); opacity: 0.35; }
.level-cell .time { font-size: 0.72rem; color: #78716c; line-height: 1; min-height: 0.75rem; }
.level-cell.current { background: #fef08a; box-shadow: 0 0 0 3px #d97706; }
.level-cell.locked { opacity: 0.45; cursor: not-allowed; }
.level-cell.locked .stars { visibility: hidden; }

/* Daily challenge banner — sits above the level grid, same cream-card frame. */
#daily-row {
    display: flex; align-items: center; justify-content: center; gap: 12px;
    width: 100%; margin: 10px 0 2px; flex-wrap: wrap;
}
#btn-daily {
    background: #F6ECD1;
    border: 4px solid #2B1F14;
    border-radius: 14px;
    box-shadow: 4px 4px 0 rgba(43, 31, 20, 0.85);
    color: #2B1F14; font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace;
    font-size: 1.05rem; font-weight: bold; letter-spacing: 0.04em;
    padding: 8px 22px; cursor: pointer;
    transition: transform 0.08s ease, box-shadow 0.08s ease;
}
#btn-daily:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 6px 6px 0 rgba(43, 31, 20, 0.85); }
#btn-daily:active:not(:disabled) { transform: translateY(3px); box-shadow: 1px 1px 0 rgba(43, 31, 20, 0.85); }
#btn-daily:disabled {
    background: #e7e5e4; color: #57534e; cursor: default;
    box-shadow: 2px 2px 0 rgba(43, 31, 20, 0.5);
}
.daily-streak-pill {
    display: inline-flex; align-items: center;
    background: #b45309; color: #fffbeb;
    border: 3px solid #2B1F14; border-radius: 999px;
    padding: 5px 14px 3px; font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace;
    font-size: 0.95rem; letter-spacing: 0.05em; line-height: 1;
    text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.35);
}

/* Main menu hub — centered title card with the star bank and stacked buttons.
   Shared cream-card frame with the other tall dialogs. */
.message-box.main-menu {
    top: 50%; left: 50%; bottom: auto;
    transform: translate(-50%, -50%);
    box-sizing: border-box;
    background-image: none;
    background-color: #f6ecd1;
    border: 6px solid #1c1917;
    border-radius: 20px;
    box-shadow: 10px 10px 0px rgba(0, 0, 0, 0.3);
    width: min(92vw, 440px);
    max-height: calc(var(--app-h, 100dvh) * 0.92);
    padding: 30px 30px 24px;
    display: none; flex-direction: column; align-items: center;
    overflow-y: auto;
}
.message-box.main-menu h1 {
    margin: 0; font-size: 2.8rem; color: #b45309;
    text-shadow: 3px 3px 0 rgba(43, 31, 20, 0.22);
}
.message-box.main-menu .menu-tagline {
    margin: 2px 0 6px; font-size: 1.05rem; letter-spacing: 0.28em;
    color: #57534e; text-transform: uppercase; font-weight: bold;
}
.menu-stars {
    display: inline-flex; align-items: center; gap: 8px;
    font-family: 'Luckiest Guy', 'Baloo 2', 'Courier New', Courier, monospace;
    font-size: 1.5rem; color: #d97706; line-height: 1;
    background: #1c1917; color: #fbbf24;
    border-radius: 999px; padding: 7px 18px 3px;
    margin-bottom: 6px;
}
.menu-stars::before {
    content: ""; display: inline-block;
    width: 22px; height: 22px;
    margin-top: -5px;
    background: url('assets/ui/ui-icon-star.png') no-repeat center / contain;
}
.message-box.main-menu > button {
    width: min(80vw, 340px);
    min-width: 0;
    height: 84px;
    font-size: 1.3rem;
    margin: 6px 0;
    box-sizing: border-box;
}
.message-box.main-menu > button img {
    margin-right: 10px; pointer-events: none;
}

/* ---------------------------------------------------------------------------
   Mobile / short-screen responsive passes.
   Small phones (<= 480px wide) and landscape phones (short height) get more
   compact chrome so every button, modal, and the puzzle stay on screen.
--------------------------------------------------------------------------- */
@media (max-width: 480px) {
    .message-box {
        padding: 24px 20px;
        max-width: 94vw;
    }
    .message-box > button {
        min-width: 0;
        width: min(78vw, 300px);
        height: 76px;
        padding: 0 22px;
        font-size: 1.05rem;
    }
    #modal-lose,
    #modal-win {
        padding: 14px 18px;
    }
    #win-stats .stat { font-size: 0.72rem; padding: 5px 9px 2px; }
    .message-box.skins { width: min(92vw, 520px); }
    .header { font-size: 1.15rem; }
    .controls {
        bottom: calc(14px + env(safe-area-inset-bottom, 0px));
        right: calc(14px + env(safe-area-inset-right, 0px));
        gap: 8px;
    }
    .controls button { width: 48px; height: 48px; }
    .controls button img { width: 26px; height: 26px; }
    .win-stars img { width: 38px; height: 38px; }
    .message-box.level-select h1 { font-size: 1.4rem; }
    #level-grid {
        grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
        gap: 8px;
        max-height: calc(var(--app-h, 100dvh) * 0.52);
    }
    .level-cell .num { font-size: 1.2rem; }
    .level-cell .stars img { width: 13px; height: 13px; }
    .level-cell .time { font-size: 0.66rem; }
    .message-box.main-menu { padding: 24px 20px 18px; }
    .message-box.main-menu h1 { font-size: 2.2rem; }
    .message-box.main-menu > button { height: 72px; font-size: 1.15rem; }
    .skin-card { padding: 8px 6px 6px; }
    .skin-card img { width: 100%; height: 110px; }
    #skin-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
    #tutorial-box { max-width: 92vw; padding: 22px 26px; }
}

/* Landscape phones: height is the scarce dimension. Compact the tall dialogs
   so DDA/level-select never push off the top or bottom. */
@media (max-height: 480px) and (orientation: landscape) {    .message-box > button {
        height: 64px;
        font-size: 1rem;
    }
    #modal-dda {
        max-height: calc(var(--app-h, 100dvh) * 0.92);
        overflow-y: auto;
        padding: 16px 22px;
    }
    #modal-dda h1 { font-size: 1.5rem; margin: 0 0 6px; }
    #modal-dda p { font-size: 0.95rem; margin: 0 0 8px; }
    .message-box.level-select { max-height: calc(var(--app-h, 100dvh) * 0.94); }
    #level-grid { max-height: calc(var(--app-h, 100dvh) * 0.62); }
    .message-box.main-menu { max-height: calc(var(--app-h, 100dvh) * 0.94); padding: 16px 22px 12px; }
    .message-box.main-menu > button { height: 62px; margin: 4px 0; }
    .message-box.main-menu h1 { font-size: 1.9rem; }
    .win-stars { gap: 8px; margin: 2px 0 10px; }
    #win-stats { margin: 0 0 12px; }
    #win-stats .stat { font-size: 0.72rem; padding: 5px 9px 2px; }
    #modal-lose, #modal-win { padding: 10px 16px; }
    /* Center the armory vertically so its tabs stay on screen. */
    .message-box.skins {
        max-height: calc(var(--app-h, 100dvh) * 0.94);
        overflow-y: auto;
        top: 50%; bottom: auto;
        transform: translate(-50%, -50%);
    }
    .message-box.skins #skin-grid { height: calc(var(--app-h, 100dvh) * 0.36); }
}

/* Hide the corner control buttons while any modal / tutorial is open, so they
   never peek out from under a modal on small screens. */
#game-container:has(.message-box:not([style*="display: none"])) .controls,
#game-container:has(#tutorial-overlay[style*="flex"]) .controls {
    display: none;
}
