/* css/responsive.css — RESPONSIVE / TOUCH layer (added in the mobile-interface pass).
 *
 * Loaded LAST (linked after the inline <style> in index.html) so equal-specificity rules win by
 * source order. NOTHING here touches the desktop layout: every layout rule is gated by `@media (max-width:
 * 1024px)` and/or a `body.touch` / `body.coarse` class that js/ui/mobile.js only sets on coarse-pointer /
 * touch devices. A 1025px+ pointer:fine desktop matches none of these → its render is byte-identical.
 *
 * The hard problem (the ~800px #stats pill + 9 buttons in one top-right row colliding with the top-left
 * #hud on a phone) is solved STRUCTURALLY: on touch we hide #hud + #toolbar, and js/ui/mobile.js relocates
 * #stats into a fixed TOP STRIP (#mStrip, horizontally scrollable so an over-long pill scrolls instead of
 * colliding/cutting off) and the action buttons into a fixed BOTTOM band (#mDock thumb-bar + #mDrawer
 * overflow on phones; an inline scrollable #mBtnRow on tablets). Top band and bottom band are disjoint, so
 * overlap is impossible by construction.
 *
 * Runtime-injected modals (#luCard / #mpCard / #goalsCard, whose <style> main.js appends to <head> AFTER
 * this file) are LATER in source order, so their small-screen overrides here MUST use !important to win.
 * (The Jukebox's runtime .mpTrk:hover is in the same boat — see the hover:none block.)
 */

/* ============================ design tokens ============================ */
:root {
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --tap: 36px;                 /* desktop default; body.coarse bumps to 44px (touch-target floor) */
  --strip-h: 46px;             /* top status-strip content height (excl. safe-area) */
  --dock-h: 56px;              /* bottom dock content height (excl. safe-area) */
  --chrome-pad: 10px;
  --toast-top: 64px;           /* toasts sit below the top band; default == desktop #rushBanner top */
  --stat-font: clamp(12px, 1.5vw, 13px);   /* Phase F1: 12px type floor everywhere */
  --coin-font: clamp(14px, 1.8vw, 16px);
  --bar-w: clamp(40px, 7vw, 64px);
}
body.coarse { --tap: 44px; }
@media (max-width: 900px) and (orientation: landscape) { :root { --strip-h: 40px; --dock-h: 48px; } }
@media (max-width: 360px) { :root { --strip-h: 42px; } }
/* on touch the top strip exists, so push toasts below it (side-notch landscape has safe-t ~0) */
body.touch { --toast-top: calc(var(--safe-t) + var(--strip-h) + 8px); }
@media (min-width: 561px) and (max-width: 1024px) { body.touch { --toast-top: calc(var(--safe-t) + 96px + 8px); } } /* tablet two-row bar */

/* ======================= global gesture / scroll hygiene ======================= */
html, body { overscroll-behavior: none; -webkit-text-size-adjust: 100%; }
/* the canvas owns ALL gestures (pan/pinch/double-tap); the browser must not scroll or page-zoom over it */
#stage, #stage canvas { touch-action: none; }
/* the scrollable chrome regions still scroll by touch, but only vertically, and don't rubber-band the page */
#palGrid, #palTabs, #menuGrid, #hireGrid, #menuTabs, #goalsBody, #journalBody,
#mStrip, #mDrawer, #mBtnRow {
  touch-action: pan-y; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
}
/* horizontally-scrolling strips need pan-x instead */
body.touch #mStrip #stats, body.touch #mBtnRow, body.touch #palTabs,
#menuTabs, #marketTabs, #journalTabs { touch-action: pan-x; }
button, .palItem { -webkit-tap-highlight-color: transparent; }
@media (prefers-reduced-motion: reduce) { * { transition-duration: .01ms !important; animation-duration: .01ms !important; } }

/* mobile hosts are created up-front by mobile.js but stay hidden until a touch layout activates them */
#mStrip, #mDock, #mDrawer, #mScrim, #mBtnRow { display: none; }

/* ====================== cosmetic #stats compaction (any small viewport) ====================== */
/* Priority order: the high-value metrics sit leftmost (always visible); the rest scroll-defer. Pure CSS —
   the spans already carry ids. Harmless on a narrow MOUSE window too (just smaller + reordered). */
@media (max-width: 1024px) {
  #stats { align-items: center; }
  #stats #coins   { order: 1; font-size: var(--coin-font); }
  #stats #prof    { order: 2; }
  #stats #pop     { order: 3; }
  #stats #lvl     { order: 4; }
  #stats #clock   { order: 5; }
  #stats #inc     { order: 6; }
  #stats #exp     { order: 7; }
  #stats #rating  { order: 8; }
  #stats #venue   { order: 9; }  /* REMASTER Phase B: identity chip (created in main.js) scroll-defers last */
  #stats span { font-size: var(--stat-font); }
  #stats #popBar, #stats #gpBar { width: var(--bar-w); }
}
@media (max-width: 360px) { #stats #inc, #stats #exp { display: none; } } /* NARROW: drop per-hour income/expense */

/* Narrow NON-touch windows need no fallback since the header rework: #topbar's bands are in normal
   flow (theme.css §3/§4) — the stats pill wraps within band A and the button row wraps below it,
   so a small DESKTOP browser window shows everything with zero overlap by construction. */

/* ============================ TOUCH structural layout ============================ */
@media (max-width: 1024px) {
  body.touch #hud,
  body.touch #toolbar { display: none; }                 /* relocated into the strip/dock/drawer/btn-row */

  /* shared top strip */
  body.touch #mStrip {
    display: flex; position: fixed; top: 0; left: 0; right: 0; z-index: 30;
    background: rgba(14, 11, 24, .86); backdrop-filter: blur(6px);
    padding-left: max(var(--chrome-pad), var(--safe-l));
    padding-right: max(var(--chrome-pad), var(--safe-r));
  }
  body.touch #mStrip #stats {
    display: flex; flex-wrap: nowrap; overflow-x: auto; max-width: 100%; gap: 9px;
    background: transparent; border: 0; box-shadow: none; padding: 0; scrollbar-width: none;
  }
  body.touch #mStrip #stats::-webkit-scrollbar { display: none; }

  /* the relocated buttons lose the `#toolbar button` rule — restyle them inside the mobile hosts */
  body.touch #mStrip button, body.touch #mDock button,
  body.touch #mDrawer button, body.touch #mBtnRow button {
    font-family: Verdana; color: #e9e2f5; border: 0; cursor: pointer; box-shadow: none;
  }
  /* ...but the host restyle (two type selectors) outranks the ID-based `.on` active states, so a toggled
     button (Rushes default-ON, the open screen) would lose its highlight on the tablet row + phone drawer.
     Restore each at two-ID specificity, preserving the per-button hue (the dock keeps its own .on below). */
  body.touch #mBtnRow #btnBuild.on, body.touch #mDrawer #btnBuild.on { background: #66ff88; color: #1b1726; }
  body.touch #mBtnRow #btnMenu.on,  body.touch #mDrawer #btnMenu.on  { background: #ffd27a; color: #1b1726; }
  body.touch #mBtnRow #btnGoals.on, body.touch #mDrawer #btnGoals.on { background: #7dffa0; color: #1b1726; }
  body.touch #mBtnRow #btnJournal.on, body.touch #mDrawer #btnJournal.on { background: #cdb3ff; color: #1b1726; }
  body.touch #mBtnRow #btnHire.on,  body.touch #mDrawer #btnHire.on  { background: #9b8bff; color: #1b1726; }
  /* REMASTER Phase D (§10 mobile parity): the Phase C/D buttons relocate too (ui/mobile.js) */
  body.touch #mBtnRow #btnMarket.on, body.touch #mDrawer #btnMarket.on { background: #ffb37a; color: #1b1726; }
  body.touch #mBtnRow #btnOrders.on, body.touch #mDrawer #btnOrders.on { background: #7ab8ff; color: #1b1726; }
  body.touch #mBtnRow #btnBlueprints.on, body.touch #mDrawer #btnBlueprints.on { background: #8fd0ff; color: #1b1726; }
}

/* TABLET (561–1024): full-width two-row bar — #stats strip + an inline horizontally-scrollable button row.
   Every one of the 9 actions stays one tap away (no drawer needed on a roomy tablet). */
@media (min-width: 561px) and (max-width: 1024px) {
  body.touch #mStrip { flex-direction: column; gap: 4px; padding-top: var(--safe-t); padding-bottom: 6px; }
  body.touch #mStrip #stats { order: 1; padding: 2px 0; }
  body.touch #mBtnRow {
    display: flex; order: 2; gap: 6px; overflow-x: auto; padding-bottom: 2px; scrollbar-width: none;
  }
  body.touch #mBtnRow::-webkit-scrollbar { display: none; }
  body.touch #mBtnRow button {
    min-height: var(--tap); white-space: nowrap; font: 600 13px Verdana; padding: 8px 12px;
    background: #3a3350; border-radius: 9px; flex: 0 0 auto;
  }
}

/* PHONE (≤560): single compact strip + a 4-up bottom dock (Build/Menu/Staff/More) + off-canvas drawer. */
@media (max-width: 560px) {
  body.touch #mStrip { align-items: center; height: calc(var(--safe-t) + var(--strip-h)); padding-top: var(--safe-t); }
  body.touch #mStrip #stats { font-size: var(--stat-font); }

  body.touch #mDock {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    height: calc(var(--dock-h) + var(--safe-b)); padding-bottom: var(--safe-b);
    background: rgba(14, 11, 24, .92); backdrop-filter: blur(6px); border-top: 1px solid #4a4366;
  }
  body.touch #mDock button {
    flex: 1 1 0; min-height: var(--tap); display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 2px; font: 700 12px Verdana;
    background: transparent; color: #e9e2f5; overflow: visible; white-space: nowrap; border-radius: 0;
  }
  body.touch #mDock button.on { color: #ffd86b; }          /* active screen highlight (two-ID rule beats the restyle) */
  body.touch #mMoreBtn { position: relative; }
  body.touch #mMoreBtn .mDot {
    position: absolute; top: 5px; right: calc(50% - 22px); width: 9px; height: 9px; border-radius: 50%;
    background: #ff5d6c; display: none; box-shadow: 0 1px 3px rgba(0, 0, 0, .5);
  }
  body.touch #mMoreBtn.hasNew .mDot { display: block; }

  body.touch #mDrawer {
    display: flex; position: fixed; top: 0; bottom: 0; right: 0; width: min(280px, 80vw); z-index: 80;
    transform: translateX(100%); transition: transform .22s ease; background: #1c1730;
    padding: calc(var(--safe-t) + 12px) 12px calc(var(--safe-b) + 12px);
    flex-direction: column; gap: 8px; overflow-y: auto; box-shadow: -8px 0 30px rgba(0, 0, 0, .5);
  }
  body.touch.drawer-open #mDrawer { transform: none; }
  body.touch #mDrawer .mDrawerTitle { font: 800 12px Verdana; letter-spacing: .6px; color: #9b8bff;
    text-transform: uppercase; padding: 2px 4px 4px; }
  body.touch #mDrawer button {
    min-height: var(--tap); width: 100%; text-align: left; font: 600 14px Verdana; padding: 11px 14px;
    border-radius: 10px; background: #3a3350; overflow: visible; position: relative;
  }
  body.touch #mScrim {
    display: block; position: fixed; inset: 0; z-index: 79; background: rgba(0, 0, 0, .45);
    opacity: 0; pointer-events: none; transition: opacity .22s ease;
  }
  body.touch.drawer-open #mScrim { opacity: 1; pointer-events: auto; }
}

/* LANDSCAPE-SHORT (≤900 landscape, ≤520 tall): reclaim vertical space — hide the dock WHILE building so the
   open palette + strip don't sandwich the playfield. */
@media (max-width: 900px) and (orientation: landscape) and (max-height: 520px) {
  body.touch.build-on #mDock { display: none; }
}

/* ============================ build palette as a touch bottom-sheet ============================ */
@media (max-width: 1024px) {
  body.touch #palette {
    display: none; flex-direction: column;                /* the GRID owns the scroll, not the sheet */
    left: 0; right: 0; bottom: 0; width: auto;
    max-height: 58vh; max-height: 58dvh;
    border-radius: 16px 16px 0 0; padding-bottom: var(--safe-b);
  }
  body.touch.build-on #palette { display: flex; }
  body.touch.build-on #inspect { display: none; }         /* the inspector card must never overlap the open sheet (any touch width) */
  body.touch #palHead { position: sticky; top: 0; flex-wrap: wrap; gap: 6px; padding: 8px 12px 0;
    background: rgba(20, 16, 32, .98); z-index: 2; }
  body.touch #palTabs { flex-wrap: nowrap; overflow-x: auto; max-width: 100%; scrollbar-width: none; }
  body.touch #palTabs::-webkit-scrollbar { display: none; }
  body.touch #palTabs button { min-height: 40px; padding: 9px 16px; font: 600 13px Verdana; flex: 0 0 auto; }
  body.touch #btnExpand { min-height: 40px; margin-left: 0; }
  body.touch #palHint { display: none; }                  /* R/Del/Esc are keyboard-only; mobile.js injects a touch hint */
  body.touch #palGrid {
    grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: 10px; max-height: none; flex: 1;
    /* rows must track tile content from the FIRST layout — stretched auto rows briefly resolved to
       leftover/N and the tiles overlapped (fixed min-height must never cap them either) */
    grid-auto-rows: max-content; align-content: start; align-items: start;
    overflow-y: auto; padding: 10px 12px calc(12px + var(--safe-b)); overscroll-behavior: contain; touch-action: pan-y;
  }
  /* injected sheet affordances (mobile.js) */
  body.touch .mGrab { width: 36px; height: 5px; border-radius: 3px; background: #5a5276; margin: 4px auto 2px; flex: 0 0 auto; }
  body.touch .mPalHint { font: 12px Verdana; color: #b6abd6; padding: 4px 4px 0; }
  body.touch #mPalDone { min-height: 40px; margin-left: auto; padding: 7px 16px; border: 0; border-radius: 9px;
    background: #5a4fb0; color: #fff; font: 700 13px Verdana; cursor: pointer; }
}
body.coarse .palItem { width: auto; min-height: 44px; padding: 8px; }  /* 44px tap floor; content sets the height */
body.coarse .palItem img { width: 56px; height: 56px; }
/* press feedback + hover-kill — coarse/touch only, so a pointer:fine desktop press is byte-identical */
@media (hover: none) { .palItem:active { transform: scale(.96); } .palItem:hover { transform: none; } }
/* mobile.js injects .mGrab/.mPalHint/#mPalDone on EVERY device (it runs unconditionally); they light up only
   under body.touch above, so explicitly hide them on a pointer:fine desktop to keep its render byte-identical. */
body:not(.touch) .mGrab, body:not(.touch) .mPalHint, body:not(.touch) #mPalDone { display: none; }

/* sit the sheet ABOVE the phone dock (no overlap); on tablet there is no dock so it goes full-bottom */
@media (max-width: 560px) {
  body.touch #palette { bottom: calc(var(--dock-h) + var(--safe-b)); padding-bottom: 0; }
}
@media (max-width: 900px) and (orientation: landscape) and (max-height: 520px) {
  body.touch #palette { max-height: 45vh; max-height: 45dvh; bottom: 0; padding-bottom: var(--safe-b); }
}

/* ============================ modals (static) ============================ */
/* REMASTER Phase C wave 2: the catering order board (#ordersModal, game/orders.js) joins the same
   modal family, so it rides every rule the market/hire modals already have (mobile parity, §10). */
@media (max-width: 1024px) {
  #menuModal, #hireModal, #marketModal, #ordersModal { padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom); box-sizing: border-box; }
  #menuCard, #hireCard, #marketCard, #ordersCard {
    width: min(96vw, 860px);
    max-height: calc(100vh - var(--safe-t) - var(--safe-b) - 16px);
    max-height: calc(100dvh - var(--safe-t) - var(--safe-b) - 16px);
  }
  #menuTabs, #marketTabs, #journalTabs { overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; }
  #menuTabs::-webkit-scrollbar, #marketTabs::-webkit-scrollbar, #journalTabs::-webkit-scrollbar { display: none; }
  #menuTabs button, #marketTabs button, #journalTabs button { flex: 0 0 auto; }
  #menuHead, #hireHead, #marketHead, #ordersHead { flex-wrap: wrap; }
}
@media (max-width: 560px) {
  #menuCard, #hireCard, #marketCard, #ordersCard {
    width: 100vw; max-width: 100vw; border-radius: 14px 14px 0 0;
    max-height: calc(100vh - var(--safe-t)); max-height: calc(100dvh - var(--safe-t)); margin-top: var(--safe-t);
  }
  #menuGrid { grid-template-columns: 1fr; padding-bottom: calc(20px + var(--safe-b)); }
  #hireGrid, #marketGrid, #ordersGrid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); padding-bottom: calc(20px + var(--safe-b)); }
  /* Phase F1: the header may wrap (coins/sub drop a row) but the ✕ stays pinned top-right */
  .rcHead { position: relative; padding-right: 62px; }
  .rcHead .rcClose { position: absolute; top: 10px; right: 12px; margin-left: 0; }
}
/* coarse-pointer tap-target floor for in-modal controls */
body.coarse #menuClose, body.coarse #hireClose, body.coarse #marketClose, body.coarse #ordersClose, body.coarse #inspClose { width: 44px; height: 44px; }
body.coarse .mkBuy, body.coarse .odBtn { min-height: 44px; }
body.coarse .staff .meal, body.coarse .staff .train { min-height: 44px; }
body.coarse .staff .countRow button { width: 44px; height: 44px; }
body.coarse .dishBtn { min-height: 44px; }
body.coarse #inspBody .fireBtn { min-height: 44px; }

/* actor inspector → bottom sheet on a phone (the hide-while-building rule lives in the touch block above) */
@media (max-width: 560px) {
  #inspect { left: 0; right: 0; bottom: calc(var(--dock-h) + var(--safe-b)); width: auto; }
  #inspCard { border-radius: 14px 14px 0 0; margin: 0 8px; }
}

/* ============================ modals (runtime-injected → need !important) ============================ */
/* These cards' <style> is injected to <head> AFTER this file. Short-landscape (≤1024 wide, ~360 tall) must
   SCROLL them, not clip — the injected styles + the ≤560 block below set no height bound or overflow, so the
   close button gets pushed off-screen on a multi-row level-up / the 7-track jukebox. Clamp + scroll here. */
@media (max-width: 1024px) {
  #luCard, #mpCard {
    max-height: calc(100dvh - var(--safe-t) - var(--safe-b) - 16px) !important; overflow-y: auto !important;
  }
}
@media (max-width: 560px) {
  #luCard, #mpCard {
    width: min(94vw, 420px) !important;
    margin: var(--safe-t) 0 var(--safe-b) !important;
  }
  /* Phase D (§10): the blueprints modal (#bpCard, game/blueprints.js) joins the injected family */
  #goalsCard, #journalCard, #bpCard {
    width: 100vw !important; max-width: 100vw !important; border-radius: 14px 14px 0 0 !important;
    max-height: calc(100dvh - var(--safe-t)) !important; margin-top: var(--safe-t) !important;
  }
  #goalsBody, #journalBody, #bpBody { padding-bottom: calc(20px + var(--safe-b)) !important; }
  body.coarse #goalsHead .gClose, body.coarse #journalHead .jClose, body.coarse #mpCard .mpClose,
  body.coarse #luCard .luClose, body.coarse #bpHead .bpClose {
    min-width: 44px; min-height: 44px;
  }
  body.coarse .bpBtns button { min-height: 44px; }
}

/* ============================ toasts / banners ============================ */
/* #rushBanner + #buildToast have stable ids → retarget them in CSS (re-evaluates on every resize, immune to
   the runtime observer's first-append timing). The two JS toasts (welcome top:56 / achievement top:108) get
   retargeted at runtime by mobile.js's body-childList observer to var(--toast-top). */
@media (max-width: 1024px) {
  #rushBanner { top: var(--toast-top); max-width: 92vw; }
  body.touch #buildToast { top: var(--toast-top) !important; max-width: min(92vw, 480px); }
}

/* ============================ tooltips / hover affordances on coarse pointers ============================ */
.itemTip { max-width: min(240px, 80vw); }
@media (hover: none) {
  .dish:hover, .staff:hover, .gAch:hover, #toolbar button:hover { transform: none; }
  .mpTrk:hover { transform: none !important; }   /* the Jukebox CSS is injected AFTER this file → needs !important to win */
}
