/* ---- Karan OS mobile-apps.css ---- */
/* 375px mobile fix sweep for individual app windows. Loads AFTER css/mobile.css,
   so equal-specificity rules here win by source order — but several apps inject
   their OWN <style> tag at runtime (when the app is first launched), which lands
   in <head> even later than this file. Where that matters, selectors below are
   written with extra specificity (body.mobile + app class + element) so they
   win on specificity alone, not just source order. See per-section notes.
   Every rule is scoped under body.mobile unless explicitly marked "global". */

/* =====================================================================
   GLOBAL FIX (not body.mobile-scoped — applies on every viewport)
   js/replay.js's #rec-pill and js/focus.js's #focus-pill both default to
   top:38-40px; right:14px, so they overlap when both are visible. Bump the
   rec pill down so it stacks under the focus pill. #rec-pill is a bare-ID
   rule (specificity 100) injected by replay.js at recording-start time,
   i.e. *after* this stylesheet in the DOM — a same-specificity override
   here would lose on source order, so this uses "body #rec-pill" (specificity
   101) to win outright regardless of injection timing.
   ===================================================================== */
body #rec-pill { top: 84px; }


/* =====================================================================
   Mail — js/apps/mail.js
   Compose modal is a fixed 500px box; clips at 375px. Compose buttons use
   their own classes (not .tool-btn), so the generic mobile.css touch-target
   rule doesn't reach them.
   ===================================================================== */
body.mobile .mail-compose-box {
  width: auto;
  max-width: min(94vw, 500px);
}
body.mobile .mail-compose-header,
body.mobile .mail-compose-body,
body.mobile .mail-compose-footer {
  padding: 12px;
}
body.mobile .mail-compose-footer button {
  min-height: 34px;
}

/* Mail baseline (item 9): three fixed-width panes (sidebar 180 + list + reading×2)
   never fit 375px — stack them instead of squeezing. */
body.mobile .mail-container {
  flex-direction: column;
}
body.mobile .mail-sidebar {
  width: 100%;
  flex: 0 0 auto;
  display: flex;
  flex-direction: row;
  overflow-x: auto;
  border-right: none;
  border-bottom: 1px solid var(--border);
  padding: 4px;
}
body.mobile .mail-sidebar-item {
  flex: 0 0 auto;
  white-space: nowrap;
}
body.mobile .mail-list {
  flex: 0 0 38%;
  border-right: none;
  border-bottom: 1px solid var(--border);
}
body.mobile .mail-reading {
  flex: 1;
}


/* =====================================================================
   Replay scrub bar — js/replay.js #replay-bar
   ~420px of fixed-width content overflows 375px; compact + wrap + clear the dock.
   ===================================================================== */
body.mobile #replay-bar {
  left: 8px;
  right: 8px;
  transform: none;
  width: auto;
  max-width: none;
  bottom: calc(var(--chrome-b) + 14px);
  gap: 6px;
  padding: 6px 10px;
  flex-wrap: wrap;
  justify-content: center;
}
body.mobile #replay-bar input[type="range"] {
  flex: 1;
  min-width: 80px;
  width: auto;
}
body.mobile #replay-bar .rb-time {
  font-size: 11px;
  min-width: auto;
}


/* =====================================================================
   Calendar — js/apps/calendar.js
   .calendar-side is a fixed 220px column; on mobile put it below the grid,
   full width. Day cells get a real touch target; header wraps if cramped.
   ===================================================================== */
body.mobile .calendar-app {
  flex-direction: column;
  overflow-y: auto;
}
body.mobile .calendar-side {
  width: 100%;
  border-left: none;
  border-top: 1px solid var(--border);
}
body.mobile .calendar-header {
  flex-wrap: wrap;
  gap: 8px;
}
body.mobile .calendar-day {
  min-height: 44px;
}

/* hover -> active (item 8) */
body.mobile .calendar-day:active {
  background: var(--glass);
}
body.mobile .calendar-navbtn:active,
body.mobile .calendar-todaybtn:active {
  background: var(--accent);
  color: #fff;
  border-color: transparent;
}


/* =====================================================================
   Numbers — js/apps/numbers.js
   .nb-fbar input is a plain class selector (specificity 0,1,0-ish once nested:
   .numbers .nb-fbar input), which OUTRANKS the generic "body.mobile input"
   16px rule in mobile.css (2 classes beats 1 class+2 elements once tied on
   the class count... concretely: .numbers .nb-fbar input = (0,2,1) beats
   body.mobile input = (0,1,2) because class-count is compared first) — so
   the formula bar needs its own explicit iOS zoom-guard override here.
   Cell-edit inputs (.numbers td input) have the SAME problem (font:inherit,
   tied specificity with body.mobile input, and the app's own <style> is
   injected after this file) — also fixed below as a bonus, since tapping a
   cell to edit would otherwise trigger iOS zoom too.
   ===================================================================== */
body.mobile .numbers .nb-fbar {
  flex-wrap: wrap;
}
body.mobile .numbers .nb-fbar input {
  font-size: 16px;
}
body.mobile .numbers td input {
  font-size: 16px;
}
body.mobile .numbers .nb-tools button {
  min-height: 34px;
  padding: 6px 10px;
}


/* =====================================================================
   Diyas over dock — js/seasonal.js runDiyas()
   The diya row is positioned with an inline style ("bottom:76px"), which
   external CSS cannot win against without !important. SKIPPED here per
   instructions — the main model should adjust the JS-side inline value
   (or read a mobile-aware offset) directly in seasonal.js.
   ===================================================================== */


/* =====================================================================
   Toolbar wraps (item 7)
   ===================================================================== */
body.mobile .finder .fbar {
  flex-wrap: wrap;
}
body.mobile .finder .fpath {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}
body.mobile .fstatus {
  flex-wrap: wrap;
}
body.mobile .photos-toolbar {
  flex-wrap: wrap;
}
body.mobile .notes .ntools {
  flex-wrap: wrap;
}
body.mobile .preview-bar {
  flex-wrap: wrap;
}


/* =====================================================================
   Hover-only -> :active (item 8)
   ===================================================================== */
body.mobile .radio-station:active {
  background: var(--glass-strong);
}

body.mobile .trophy-card.unlocked:active {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, .15);
}

/* photos thumbnail: neutralize the sticky hover scale (mobile has no true
   "hover", so :hover can get stuck after a tap) and use :active instead */
body.mobile .photos-thumb:hover {
  transform: none;
}
body.mobile .photos-thumb:active {
  transform: scale(1.03);
}

/* account (Karan ID) */
body.mobile .acct-signin:active,
body.mobile .acct-syncnow:active,
body.mobile .acct-create:active,
body.mobile .acct-signout:active {
  filter: brightness(1.08);
}

/* shareddesk (Shared Space) */
body.mobile .sd-create:active,
body.mobile .sd-join:active,
body.mobile .sd-copy:active,
body.mobile .sd-leave:active {
  filter: brightness(1.08);
}

/* sdk (Developer) */
body.mobile .sdk-tab:active {
  background: rgba(128, 128, 128, .15);
}
body.mobile .sdk-btn:active {
  background: rgba(128, 128, 128, .2);
}

/* admin — .adm .btn has NO :hover rule in admin.js at all (nothing to
   "duplicate"), so this adds a baseline tap-feedback state instead */
body.mobile .adm .btn:active {
  filter: brightness(.9);
}
body.mobile .adm-tabs {
  flex-wrap: wrap;
}


/* =====================================================================
   Baseline usability at 375px (item 9) — apps with ~zero mobile rules
   ===================================================================== */

/* terminal — NOT duplicated here on purpose: js/apps/terminal.js's
   ".term input" is (0,1,1) specificity, which loses to mobile.css's
   "body.mobile input" (0,1,2) regardless of load order, so the 16px iOS
   zoom guard already applies. Verified, no rule needed. */

/* paint — toolbar already has flex-wrap:wrap in its own stylesheet;
   only the fixed 640x480 canvas needs to scale down. Paint's own pointer
   math (getPos) reads canvas.width/getBoundingClientRect ratio, so a
   CSS-scaled canvas keeps correct drawing coordinates. */
body.mobile .paint-canvas-wrap canvas {
  max-width: 100%;
  height: auto;
}

/* code — the editor overlays a transparent <textarea> exactly on top of a
   visible <pre> (character-for-character), so both MUST share a font-size.
   ".code-ta" is a bare class (0,1,0), which loses to "body.mobile textarea"
   (0,1,2) — so on mobile the invisible textarea alone would jump to 16px
   while the visible .code-pre stayed at 13px, wrecking the overlay
   alignment. Both are pinned to 16px together here. */
body.mobile .code-pre,
body.mobile .code-ta {
  font-size: 16px;
}

/* camera — controls/filters already wrap and the stage uses object-fit;
   reviewed at 375px, nothing broken, no rule needed. */

/* video — .video-sidebar is a fixed 200px column next to a flex player;
   at 375px that leaves ~175px for the player. Stack instead. */
body.mobile .video-container {
  flex-direction: column;
}
body.mobile .video-sidebar {
  width: 100%;
  flex: 0 0 auto;
  max-height: 160px;
  border-left: none;
  border-top: 1px solid var(--border);
}

/* timemachine — fixed 220px sidebar narrowed so the card stage keeps room */
body.mobile .timemachine-sidebar {
  width: 140px;
  flex: 0 0 140px;
}

/* battle — canvas is forced to width:100%;height:100% of a flex arena,
   stretching the fixed 600x360 coordinate space unevenly on a tall mobile
   viewport. Let it scale down keeping aspect ratio instead. */
body.mobile .battle-arena canvas {
  max-width: 100%;
  height: auto;
}

/* widgets — 180px cards default to safe on-screen positions already;
   this is just a safety cap so a dragged card can't be shoved off-canvas. */
body.mobile .widgets-card {
  max-width: calc(100vw - 24px);
}

/* music — already a centered flex column with a 110px disc; reviewed at
   375px, nothing broken, no rule needed. */


/* =====================================================================
   Wave 21/22 sweep — apps and arcana panels never audited at 375px.
   Read in full (not edited) for their real class names: js/apps/potions.js,
   js/apps/reckonings.js, js/apps/diary.js, js/arcana/warder-gallery.js,
   js/arcana/familiar-gallery.js, js/arcana/sump.js,
   js/arcana/registry-of-names.js, js/arcana/door.js, js/apps/almanac.js.
   Most of these already carry their own body.mobile rules (each app's own
   injected <style> was inspected end to end) — only the gaps below were
   actually missing: a couple of touch targets under 44px, hover-only
   feedback with no :active twin (mobile has no true hover, so a tapped
   element can visibly "stick" hovered), and one 12px input that would
   still trigger iOS zoom-on-focus despite being readonly.
   ===================================================================== */

/* ---- Potions (js/apps/potions.js) — already ships thorough body.mobile
   rules of its own: shelf becomes a wrapping row, ingredients/buttons hit
   44px, the cauldron is capped at 230x230 and centered. That 230px cap
   holds on anything wider than ~250px, so the stir surface (72%/44% of
   the pot) is not actually being squeezed today — but nothing currently
   guarantees a floor, and item 5 of the brief asks for one explicitly, so
   one is added here defensively. */
body.mobile .potions-app .pt-pot { min-width: 200px; min-height: 200px; }
body.mobile .potions-app .pt-stir { min-width: 120px; min-height: 70px; }

/* ---- Reckonings (js/apps/reckonings.js) — .rk-opt's selected-preview
   highlight is :hover-only (both the light rule and its body.dark
   variant); give it a tap-friendly twin so choosing an answer shows
   feedback on mobile. */
body.mobile .rk-opt:active { background: rgba(255, 255, 255, .55); }
body.mobile.dark .rk-opt:active { background: rgba(0, 0, 0, .22); }

/* ---- Diary (js/apps/diary.js) — same gap: the page-strip row highlight
   (.dy-item) is hover-only. */
body.mobile .diary-app .dy-item:active { background: var(--glass-strong, var(--border)); }

/* ---- Warder Gallery (js/arcana/warder-gallery.js) — its own mobile
   block already shrinks .wgal-close/.wgal-revert, but only to 38px,
   under the 44px floor. Both are (0,2,1)-specificity rules injected by
   the app's own <style> AFTER this file loads, so an equal-specificity
   override here would still lose on source order — qualified with the
   .wgal-panel ancestor for (0,3,1) to win outright, same trick the Mail/
   Numbers sections above use. Hover-only feedback on the close button,
   the revert button and the statue tiles also gets an :active twin. */
body.mobile .wgal-panel .wgal-close { width: 44px; height: 44px; min-width: 44px; min-height: 44px; }
body.mobile .wgal-panel .wgal-revert { min-height: 44px; }
body.mobile .wgal-close:active { background: var(--border); }
body.mobile .wgal-revert:active { background: var(--border); }
body.mobile .wgal-tile:active { border-color: var(--accent); }

/* ---- Familiar Gallery (js/arcana/familiar-gallery.js) — already 44px+
   throughout and already a single grid column on mobile; only its
   .fg-x/.fg-card hover states have no :active twin. */
body.mobile .fg-x:active { background: rgba(255, 235, 190, .12); }
body.mobile .fg-card:active { background: rgba(255, 235, 190, .12); }

/* ---- Sump (js/arcana/sump.js) — its close button (.arc-sump-close) was
   never given a mobile override at all (still the desktop 28px), and its
   existing mobile .arc-sump-btn rule stops at 42px. The btn override
   needs the .arc-sump-panel ancestor for the same (0,3,1)-beats-(0,2,1)
   reason as the gallery above (its own <style> also lands after this
   file). Hover-only feedback on both buttons gets an :active twin. */
body.mobile .arc-sump-close { width: 44px; height: 44px; }
body.mobile .arc-sump-panel .arc-sump-btn { min-height: 44px; }
body.mobile .arc-sump-close:active { background: rgba(24, 60, 76, .9); }
body.mobile .arc-sump-btn:active { background: rgba(32, 92, 116, .95); }

/* ---- The Duelling Ladder / duel-link popup (js/arcana/registry-of-names.js)
   — had no body.mobile rules at all. The copy-link box (.regn-pop-input)
   is a real <input> at 12px; readonly does not stop iOS from zooming on
   focus, so it needs the same 16px guard as every other input. Everything
   else here (92vw popup, .regn-list's own overflow-y:auto, ellipsised
   .regn-name) was already safe at 375px on inspection. */
body.mobile .regn-pop-input { font-size: 16px; }

/* ---- The Door (js/arcana/door.js) — the Places grid is already a fixed
   2-column grid and its rows (.arc-door-place, .arc-door-tog) already
   carry a 44px mobile floor; only .arc-door-place's hover highlight has
   no :active twin. */
body.mobile .arc-door-place:active { background: rgba(232, 220, 196, .15); }

/* ---- Almanac (js/apps/almanac.js) — the card list already collapses to
   one column and "Show me" is already bumped to 44px on mobile; the
   category tab strip (.al-tab) was left at its desktop 32px. */
body.mobile .almanac-app .al-tab { min-height: 44px; }
