/* ──────────────────────────────────────────────────────────────────────────
   Mobile layout (portrait phones, ≤1400px wide).

   Disables the #root zoom ladder (which squashed the 3-col desktop layout to
   28% on phones) and replaces it with a true mobile layout:
   - left-col fills the viewport (below the banner) with NO scrolling — the
     game-area is zoomed by --ga-mobile-zoom so every piece fits
   - mid-col and right-col become position:fixed slide-in overlays, invoked
     via two vertical tab buttons pinned on top on the right edge
   - the wallet (Gold/Gems/Eggplants/Cash/Buy/Convert) collapses into a
     slide-down drawer behind one 💰 Wallet button on the banner
   - upgrade Squeeze/Passive split collapses to a single column
   - modals become full-screen with a sticky, 30% larger close button
   - pinch zoom / pull-to-refresh are suppressed
   ────────────────────────────────────────────────────────────────────────── */

/* Disable pull-to-refresh + browser bounce on mobile */
html,body{overscroll-behavior:none;}
body{touch-action:manipulation;}

/* Disable Android Chrome's automatic text inflation ("font boosting").
   Without this, Chrome on phones scales text up for readability — which
   does NOT happen in DevTools emulation, so a layout that fits in the
   emulator can overflow on a real phone once labels get boosted. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;}

/* Kill horizontal + vertical overflow on mobile. The fixed slide-in columns
   (#mid-col/#right-col at transform:translateX(110%)) and the banner's
   overflow-x:auto can leak horizontal scroll space on Android Chrome even
   though the content is visually off-screen. Locking html/body to the
   viewport dimensions prevents the right/bottom edges from being cropped
   by Chrome's own scroll-past-edge behavior. */
@media (max-width: 1400px){
  html,body{overflow:hidden;max-width:100vw;width:100%;height:100dvh;}
}

/* Column-toggle tabs are mobile-only — hidden entirely on desktop. */
#mobile-col-tabs{display:none;}

/* Scratch + Lootbox grouping: a layout-transparent wrapper on desktop (so
   the buttons flow as normal inline banner-right children) and a non-
   wrapping flex pair on mobile (so they stay on the same row when the
   banner wraps). */
.b-pair{display:contents;}

/* Wallet drawer: mobile-only. On desktop the toggle button is hidden and the
   #wallet-group span is transparent to layout (display:contents) so its
   children flow inline in #banner-left exactly as before. */
#wallet-toggle-btn{display:none;}
#wallet-group{display:contents;}

/* Radio-mode toggle button: mobile-only. Hidden on desktop where the radio
   controls flow inline in the banner. */
#radio-toggle-btn{display:none;}

@media (max-width: 1400px){

  /* ── Kill the #root zoom ladder. Force --w-zoom / --h-zoom back to 1 so the
        whole-UI zoom disappears and we lay things out at natural size with a
        vertical stack instead. */
  :root{--w-zoom:1 !important;--h-zoom:1 !important;}
  #root{zoom:1 !important;width:100% !important;height:100dvh !important;overflow:hidden;}

  /* ── Main container: no scroll. Left-col is the only in-flow child; mid
     and right cols become fixed-position overlays that slide in from the
     right, so they don't need to fit in the flex flow. */
  /* Desktop uses grid (see core.css) — revert to flex-column on mobile so
     the existing single-column stack still works. */
  #main{display:flex;flex-direction:column;overflow:hidden;padding:6px;gap:0;height:calc(100dvh - var(--banner-h,49px));}

  /* ── Left column: fills the entire visible area below the banner. No
     scrolling — the inner game-area is zoomed (--ga-mobile-zoom, set by
     _updateMobileGameZoom in main.js) to fit whatever height remains after
     the non-scaled chrome (prestige bar, cosmetics/stroke buttons). */
  #left-col{
    flex:1 1 auto !important;
    width:100%;
    height:100%;
    padding-bottom:8px;
    overflow:hidden;
    position:relative;
    border-right:1px solid #2e1220;
    border-radius:14px;
    min-height:0;
  }

  /* ── Mid / Right columns: slide-in overlays from the right edge ─────
     The Upgrades/Shop tab buttons (42px wide) are pinned to right:0 and
     own that strip outright — the columns stop 48px short of the right
     edge so the tabs and column have dedicated, non-overlapping space.
     Width is capped so that on wider tablets the overlay doesn't stretch
     absurdly. Transform drives show/hide — display:flex stays on so the
     transition animates in/out. */
  #mid-col,#right-col{
    position:fixed !important;
    top:var(--banner-h,49px);
    right:48px;            /* leave 48px strip for the tab buttons */
    width:calc(91vw - 48px);
    max-width:534px;       /* 582 - 48 so total footprint matches the old cap */
    height:calc(100dvh - var(--banner-h,49px));
    max-height:none !important;
    padding-right:0;
    border-radius:14px;
    /* Softened shadow — the old -6px/26px/0.7 felt like a heavy desktop modal
       on a phone; -4px/18px/0.45 + a subtle inner hairline reads as a clean
       sheet floating over the game. */
    box-shadow:-4px 0 18px rgba(0,0,0,0.45),inset 1px 0 0 rgba(255,180,220,0.05);
    /* Frosted-glass look — the column sits over the running game so a bit
       of blur lets the motion behind it feel present without distracting. */
    -webkit-backdrop-filter:blur(10px) saturate(1.2);
    backdrop-filter:blur(10px) saturate(1.2);
    z-index:85;
    transform:translateX(calc(110% + 48px));
    transition:transform 0.32s cubic-bezier(0.5,0,0.25,1);
    overflow:hidden;
  }
  body.mcol-mid #mid-col,
  body.mcol-right #right-col{transform:translateX(0);}
  /* Disable the desktop unlock slide-in animation — it fights our
     transform-based transition and causes a visible snap-back when the
     column is hidden. */
  #mid-col.col-slide-entering,
  #right-col.col-slide-entering{animation:none !important;}

  /* Restore internal scrolling inside the slide-in columns (the earlier
     mobile rule disabled it to allow page-level scroll, but with overlays
     we want each overlay to scroll its own content). The column now ends
     48px short of the right edge, so no per-child padding-right reserve
     is needed — tab buttons own their own strip. */
  #upgrades-list{overflow:hidden;flex:1 1 auto;}
  #upgrades-scroll{
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
    /* Fade mask at top/bottom hints "there's more to scroll" — dual-layer
       so the header/footer don't dissolve into the blur behind the column. */
    -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%);
    mask-image:linear-gradient(to bottom,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%);
  }
  #bookshelf{
    overflow-y:auto;
    min-height:0;
    flex:1;
    -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 12px,#000 calc(100% - 12px),transparent 100%);
    mask-image:linear-gradient(to bottom,transparent 0,#000 12px,#000 calc(100% - 12px),transparent 100%);
  }

  /* ── Game area: scale #left-game-wrap so the 220px cylinder fills ~90vw.
        --ga-mobile-zoom is set by JS on resize. Zoom (vs transform) preserves
        layout so absolutely-positioned kiwis/hit-zone stay correctly placed.
        padding-top is 2px (was 8px) — part of the vertical-tightening pass
        for phones & short screens; see the block below. */
  #left-game-wrap{zoom:var(--ga-mobile-zoom,1);display:flex;flex-direction:column;align-items:center;padding:2px 0 4px;}

  /* Banner: single-line layout. 💦 | Currencies | radio | VIP | Shop |
     Daily | Scratch | Lootbox — all on one row, in that DOM order. Nothing
     wraps; if the combined min widths exceed the viewport the banner
     scrolls horizontally rather than breaking onto multiple rows. */
  #banner{
    display:flex !important;
    flex-wrap:nowrap !important;
    align-items:center;
    gap:4px;
    height:auto;
    min-height:49px;
    padding:6px 6px;
    overflow-x:auto;
    overflow-y:hidden;
    /* Frosted banner feels more modern and keeps the background visible
       during UI-pulse animations behind it. The linear-gradient stays
       underneath as the "base color" through the blur. */
    -webkit-backdrop-filter:blur(8px) saturate(1.15);
    backdrop-filter:blur(8px) saturate(1.15);
  }
  #banner-left{flex:0 0 auto;flex-wrap:nowrap !important;gap:4px;min-width:0;}
  #banner-center{flex:0 0 auto;min-width:0;position:static;transform:none;}
  #banner-right{flex:0 0 auto;flex-wrap:nowrap !important;gap:4px;min-width:0;justify-content:flex-start;}

  /* .b-pair (Scratch + Lootbox) stays glued together in the row; inline-
     flex with nowrap keeps them side-by-side with no chance of breaking. */
  .b-pair{display:inline-flex;flex-wrap:nowrap;gap:4px;}

  /* The radio now lives in the #minigame-bar top banner (block below), so the
     legacy in-banner radio toggle is unused — and the #banner is hidden anyway.
     #radio-controls is left under radio.js's own inline display control so it
     can show, centered, in the minigame bar once the radio is revealed. */
  #radio-toggle-btn{display:inline-flex !important;align-items:center;}

  /* Compress banner items to fit on one line. Buttons shrink to a minimal
     but still-tappable size; radio controls drop the track name + slim the
     volume slider since those aren't critical here. */
  #banner .b-btn{font-size:11px;padding:4px 7px;}
  #wallet-toggle-btn,#radio-toggle-btn{font-size:11px !important;padding:4px 7px !important;}
  #banner .radio-btn{width:22px;height:22px;font-size:9px;}
  #radio-track-name{display:none;}
  #radio-vol-slider{width:46px;margin-left:2px;}
  #radio-wave{width:18px;height:12px;margin-left:2px;}

  /* ── Top banner: VIP / Daily / Casino / Minigames / Lootbox ────────────────
     On desktop these live in #minigame-bar across the top. On mobile the bar
     becomes a top button banner inside #main. The radio is relocated out of
     this bar (into the top of #left-col — see _applyMobileRadioPlacement in
     main.js + the #left-col rules below). The bar stays hidden until the first
     of these buttons unlocks (the :has() rule in addons.css still applies). */
  #minigame-bar{
    display:flex !important;
    flex-direction:row;
    flex-wrap:wrap;
    align-items:center;
    justify-content:center;
    width:100%;
    height:auto !important;
    min-height:0 !important;
    flex-shrink:0;
    padding:5px 6px;
    gap:5px;
    overflow:visible;
    background:rgba(26,8,15,0.72);
    -webkit-backdrop-filter:blur(8px) saturate(1.15);
    backdrop-filter:blur(8px) saturate(1.15);
    border-bottom:1px solid #2e1220;
  }
  /* Radio's old slot in the bar is now empty (it lives in #left-col) — hide it. */
  #minigame-bar #minigame-bar-left{display:none !important;}
  /* Button row — centered, wrapping as needed. The many hidden minigame wraps
     stay display:none via the global rule in addons.css. */
  #minigame-buttons-wrap{
    width:100%;
    flex:0 0 auto;
    justify-content:center;
    flex-wrap:wrap;
    align-content:center;
    height:auto;
    min-height:0;
    transform:none !important;
    opacity:1 !important;
    pointer-events:auto !important;
    gap:5px;
  }
  /* Buttons stay at their full desktop size on roomy windows; font + horizontal
     padding scale down with the viewport once it gets too narrow to fit. */
  #vip-btn,#daily-btn,#casino-btn,#minigames-btn,#lootbox-btn{
    font-size:clamp(10px, 4.32vw, 17px) !important;
    padding-left:clamp(6px, 2.85vw, 11px) !important;
    padding-right:clamp(6px, 2.85vw, 11px) !important;
  }
  /* Desktop chevron stays hidden; mobile uses its own pair below. */
  #minigame-toggle{display:none !important;}

  /* ── Mobile collapse chevron for the VIP/Casino/Minigames bar ──────────────
     #mm-mobile-collapse pins to the right edge of the bar and collapses the
     whole section. When collapsed (body.mm-bar-collapsed) the bar is hidden and
     #mm-bar-expand — sitting just right of the Themes button — appears pointing
     up to bring it back. */
  #minigame-bar{position:relative;}
  /* Reserve room at the right so centered buttons never slide under the chevron. */
  #minigame-buttons-wrap{padding-right:50px;}
  #mm-mobile-collapse{
    display:flex !important;
    align-items:center;justify-content:center;
    position:absolute;right:7px;top:50%;
    transform:translateY(-50%);
    width:39px;height:34px;padding:0;
    background:linear-gradient(135deg,#4a1a30,#250c18);
    border:1.5px solid #8a3060;border-radius:7px;
    color:#f0c0d0;font-size:15px;font-weight:700;line-height:1;
    cursor:pointer;z-index:6;
    box-shadow:0 0 8px 2px rgba(160,60,100,0.28);
  }
  #mm-bar-expand{
    display:none;
    align-items:center;justify-content:center;
    width:39px;height:37px;padding:0;margin-left:4px;
    background:linear-gradient(135deg,#4a1a30,#250c18);
    border:1.5px solid #8a3060;border-radius:7px;
    color:#f0c0d0;font-size:15px;font-weight:700;line-height:1;
    cursor:pointer;flex-shrink:0;
    box-shadow:0 0 8px 2px rgba(160,60,100,0.28);
  }
  /* Collapsed state: drop the whole top bar, reveal the Themes-side chevron. */
  body.mm-bar-collapsed #minigame-bar{display:none !important;}
  body.mm-bar-collapsed #mm-bar-expand{display:inline-flex;}

  /* ── Radio: relocated to the top of the left column, above the cylinder ─────
     main.js moves #mid-radio-wrap into #left-col (before #left-game-wrap) on
     mobile. radio.js still controls its display (hidden until revealed). */
  #left-col > #mid-radio-wrap{
    justify-content:center;
    width:100%;
    flex-shrink:0;
    margin:-44px 0 0; /* nudged up 46px from the original 2px top margin */
    /* Pulled up far enough to overlap #prestige-info (position:relative;
       z-index:51), which would otherwise paint over the radio and eat its
       clicks. Position + higher z-index puts the controls back on top. */
    position:relative;
    z-index:52;
  }
  #left-col #radio-controls{justify-content:center;gap:5px;}
  #left-col #radio-track-name{display:none;}
  #left-col .radio-btn{width:24px;height:24px;font-size:10px;}
  #left-col #radio-vol-slider{width:64px;margin-left:4px;}
  #left-col #radio-wave{width:18px;height:12px;margin-left:3px;}

  /* Tactile press feedback: desktop has hover states but mobile had zero
     visual confirmation on tap. Scale + brightness together sell the press
     without shifting layout (no margin/padding change = no jitter). */
  .b-btn:active,
  #wallet-toggle-btn:active,
  #radio-toggle-btn:active,
  #drug-market-btn:active,
  #harem-training-btn:active,
  #hired-cyl-btn:active,
  #exped-btn:active{
    transform:scale(0.94) !important;
    filter:brightness(1.18);
    transition:transform 0.07s ease,filter 0.07s ease;
  }

  /* Prestige XP bar was a 13px hairline — easy to miss on mobile and hard
     to tap for the details tooltip. Grow the whole strip to 22px so the
     gradient reads clearly and the tap target matches Material guidance.
     The inner #prestige-bar-fill already uses height:100% so it follows. */
  #prestige-bar-wrap{
    height:25px !important;
    min-height:25px !important;
  }

  /* Cosmetics/Themes buttons keep their desktop positioning (absolute, top-
     right of #left-col) — #left-col is position:relative on mobile so the
     absolute coords anchor correctly. Stroke-style sits in-flow (flex),
     centered for a cleaner narrow layout. */
  #stroke-style-btn-wrap{align-self:center !important;margin-top:4px;}

  /* Drippy Skill Tree button — on desktop it sits at right:8px,bottom:8px of
     #left-col. On mobile that lands inside the 48px tab-strip (vw-48→vw) and
     pokes out past the right edge of the sliding column overlay (right:48),
     so the "D+" remained visible on top of / next to the Upgrades/Shop panel.
     Shifting right to 56px puts it inside the column's x-coverage so the
     overlay (z:85) properly covers it when slid in; drippy stays at z:50 so
     it's beneath the overlay but above the game canvas. */
  #drippy-tree-btn{
    right:56px !important;
    bottom:12px !important;
  }
  /* When the Tamaglitchi is open, the "+" button is relocated into the egg
     shell (bottom-center, above the Select button) via inline styles in
     tamagotchi.js. The mobile rule above uses !important, which would drag it
     back down to bottom:12px / right:56px. This higher-specificity override
     restores the desktop in-shell position so it sits up where it belongs. */
  #tama-shell #drippy-tree-btn{
    bottom:142px !important;
    right:auto !important;
  }

  /* ── Upgrade 2-col split collapses to a single column ───────────────── */
  #upgrades-split{flex-direction:column;gap:4px;}
  .upgrades-col-wrap{width:100%;}
  .upgrades-col{padding:5px 2px 20px;}

  /* Ability Shop cards — shrink text 30% and compress card padding so more
     upgrades are visible at once on a phone. Desktop: name 13px / desc 11px
     / padding 7px 8px; mobile: name 9px / desc 8px / padding 5px 7px.
     Icon stays readable at 18px (was 22px). */
  .upgrades-col .upg-card-top{padding:5px 7px !important;gap:6px !important;}
  .upgrades-col .upg-name{font-size:9px !important;line-height:1.15 !important;}
  .upgrades-col .upg-desc{font-size:8px !important;line-height:1.2 !important;margin-top:1px !important;}
  .upgrades-col .upg-icon{font-size:18px !important;width:22px !important;}

  /* Stats / Graph / Achievements / Options buttons in #mid-top-bar: emoji-
     only on mobile. Hide the inline text via font-size:0 and prepend the
     emoji as a pseudo-element so the labels stay in the DOM for tooltips /
     screen readers on desktop while the rendered button becomes compact. */
  #mid-top-bar #stats-btn,
  #mid-top-bar #graph-btn,
  #mid-top-bar #achievements-btn,
  #mid-top-bar #options-btn{
    font-size:0 !important;
    padding:6px 8px !important;
    min-width:36px;
  }
  #mid-top-bar #stats-btn::before       { content:"📊"; font-size:17px; display:inline-block; line-height:1; }
  #mid-top-bar #graph-btn::before       { content:"📈"; font-size:17px; display:inline-block; line-height:1; }
  #mid-top-bar #achievements-btn::before{ content:"🏆"; font-size:17px; display:inline-block; line-height:1; }
  #mid-top-bar #options-btn::before     { content:"⚙️"; font-size:17px; display:inline-block; line-height:1; }

  /* ── Modals: full-screen, padded for notch/safe areas ──────────────── */
  .overlay{padding:0;}
  .overlay .modal-box,
  .overlay .vip-modal,
  .overlay .daily-modal,
  .overlay .ad-box,
  .overlay .scratch-box,
  .overlay .cosm-modal,
  .overlay .prestige-modal,
  .overlay .vir-wheel-modal,
  .overlay .premium-shop-modal,
  .overlay .fake-pay-modal,
  .overlay .lootbox-modal{
    width:100vw !important;
    height:100dvh !important;
    max-width:none !important;
    max-height:none !important;
    min-width:0 !important;
    min-height:0 !important;
    border-radius:0 !important;
    padding:56px 14px 20px !important;  /* top pad leaves room for sticky close */
    overflow-y:auto !important;
    box-sizing:border-box;
    transform:none !important;
  }
  /* fake-pay-modal uses transform:scale(1.3) by default — undo on mobile */
  .overlay .fake-pay-modal{transform:none !important;}

  /* ── Sticky close button: pinned top-right, 30% bigger than desktop ───
     Covers every modal-style close button in .overlay. */
  .overlay .modal-close,
  .overlay .daily-modal-close,
  .overlay .scratch-close,
  .overlay .scratch-x-btn,
  .overlay .ad-close-btn,
  .overlay .lootbox-close-btn,
  .overlay .cosm-x-btn,
  .overlay .cv-close-x,
  .overlay .cylarmy-x-btn,
  .overlay .ui-unlock-x{
    position:fixed !important;
    top:8px;
    right:8px;
    z-index:1000;
    transform:scale(1.3);
    transform-origin:top right;
    box-shadow:0 2px 12px rgba(0,0,0,0.6);
  }

  /* In-panel close buttons (stats/ach/graph/options are in mid-col panels,
     not inside .overlay). Kept in-flow but scaled up 30%. */
  .stats-close-btn,
  .ach-close-btn,
  .graph-close-btn,
  .opt-close-btn{
    transform:scale(1.3);
    transform-origin:top right;
  }

  /* Achievement-popup close button — same red-X affordance as the in-panel
     closes above, 30% bigger on mobile. */
  .ach-popup-close{
    transform:scale(1.3);
    transform-origin:top right;
  }

  /* Version-info widget (bottom-right corner of main menu): widen and lift
     it slightly on mobile so the scrollable notes are readable on small
     screens. */
  #vp-widget{
    width:min(86vw,460px) !important;
    max-height:55vh !important;
    right:12px !important;
    bottom:12px !important;
  }

  /* Ad close button and harem-training modal close button — 20% bigger
     (not 30%) per direct request. The harem modal reuses the generic
     .ui-unlock-x class, so we scope the 1.2× scale to the harem modal
     specifically so other .ui-unlock-x close buttons (UI-unlock popups)
     keep the 1.3× scale set above. */
  .shop-ad-close{
    transform:scale(1.2);
    transform-origin:top right;
  }
  .overlay .harem-training-modal .ui-unlock-x{
    transform:scale(1.2) !important;
  }

  /* ── Column-toggle tabs ───────────────────────────────────────────────────
     Two vertical buttons fixed to the right edge of the viewport. They open
     the mid-col (Upgrades) and right-col (Shop) respectively. On mobile those
     columns are hidden by default and only shown when their tab is active;
     only one column can be visible at a time. The buttons themselves stay
     .ui-locked until their column has unlocked via the normal gating rules
     (see display.js _UI_UNLOCK_GROUPS). */
  #mobile-col-tabs{
    display:flex;
    flex-direction:column;
    gap:9px;
    position:fixed;
    top:50%;
    right:0;
    transform:translateY(-50%);
    /* z-index sits ABOVE the column overlays (85) so the tabs remain visible
       and tappable when a column is slid in — they double as the close/switch
       control. Still below .overlay (200) so modals cover them. */
    z-index:95;
    pointer-events:auto;
  }
  .mobile-col-tab-btn{
    /* Vertical text — reads top-to-bottom on the narrow tab */
    writing-mode:vertical-rl;
    text-orientation:mixed;
    /* Size & shape — 10% larger than the previous mobile sizing */
    width:42px;
    min-height:132px;
    padding:15px 7px;
    /* Curved on the LEFT side only — tab feels attached to the right edge */
    border-radius:15px 0 0 15px;
    border:1.5px solid #8a3060;
    border-right:none;
    background:linear-gradient(to left,#3a1525,#4a1a30);
    color:#f0c0d0;
    font-family:'Exo 2',Calibri,sans-serif;
    font-size:16px;
    font-weight:800;
    letter-spacing:0.10em;
    text-transform:uppercase;
    cursor:pointer;
    box-shadow:-3px 2px 14px rgba(0,0,0,0.55),inset 1px 0 0 rgba(255,160,200,0.08);
    transition:background 0.15s,box-shadow 0.15s,color 0.15s,border-color 0.15s;
    text-shadow:0 1px 2px rgba(0,0,0,0.45);
    /* Anchor for ::before (ribbon) and ::after (chevron) pseudos below. */
    position:relative;
  }
  .mobile-col-tab-btn:hover{
    background:linear-gradient(to left,#4a1a30,#6a2545);
    color:#ffd5e8;
  }
  .mobile-col-tab-btn.active{
    background:linear-gradient(to left,#6a2545,#8a3060);
    border-color:#c060a0;
    color:#fff;
    box-shadow:-3px 2px 18px rgba(200,80,160,0.55),inset 1px 0 0 rgba(255,200,230,0.2);
  }
  /* Active-column ribbon: a small vertical glow bar protrudes off the
     tab's left edge and visually "points into" the open column. Extends
     into the 48px gap between the tab and the column edge, so the two
     surfaces feel connected as a single unit while open. */
  .mobile-col-tab-btn.active::before{
    content:"";
    position:absolute;
    left:-6px;
    top:16px;
    bottom:16px;
    width:4px;
    border-radius:3px;
    background:linear-gradient(to bottom,#ff90c8,#c060a0,#ff90c8);
    box-shadow:0 0 10px rgba(220,100,180,0.7),0 0 18px rgba(220,100,180,0.35);
    pointer-events:none;
  }

  /* ── Currency header mode ─────────────────────────────────────────────────
     Default mobile state: the toggle button is visible; everything inside
     #wallet-group (currency pills + Buy + Convert) is hidden. Tapping the
     button enters "currency mode" — body.currency-mode — which hides the
     radio and most right-side buttons (VIP / Daily / Scratch / Lootbox) and
     reveals the currency pills inline in the banner. Shop stays visible
     throughout. Exit via the "← Back" label that replaces the button text. */
  #wallet-toggle-btn{display:inline-flex !important;align-items:center;}
  /* Default: hide the currency pills + Buy/Convert on mobile. They live
     inside a display:contents span so we have to hide each direct child to
     avoid leaving a layout-transparent shell that still flows its kids. */
  #wallet-group > *{display:none !important;}

  /* Currency mode: show the pills inline and hide the non-shop chrome.
     :not(.ui-locked) preserves the per-pill unlock gating — a currency that
     hasn't been unlocked yet stays hidden even when the panel is open. */
  body.currency-mode #wallet-group > *:not(.ui-locked){display:inline-flex !important;}
  /* .b-sep isn't a flex pill — it's a thin divider. Let it collapse on
     mobile since the banner already wraps when space is tight. */
  body.currency-mode #wallet-group .b-sep{display:none !important;}
  body.currency-mode #banner-center{display:none !important;}
  body.currency-mode #vip-btn,
  body.currency-mode #shop-btn,
  body.currency-mode #daily-btn,
  body.currency-mode #scratch-btn,
  body.currency-mode #lootbox-btn{display:none !important;}

  /* In currency mode nothing visible lives in banner-right anymore — hide
     it and let banner-left wrap its pills across the full banner width
     instead of staying on the single-line flex row used in default mode. */
  body.currency-mode #banner{flex-wrap:wrap !important;overflow-x:visible !important;}
  body.currency-mode #banner-left{flex:1 1 100% !important;flex-wrap:wrap !important;width:100%;justify-content:flex-start;gap:6px;}
  body.currency-mode #banner-right{display:none !important;}

  /* Active-state styling for the toggle while currency mode is on. */
  body.currency-mode #wallet-toggle-btn{
    background:#6a2545;
    box-shadow:0 0 10px rgba(200,80,140,0.55);
  }

  /* ── Radio-mode ──────────────────────────────────────────────────────────
     Mirror of currency-mode for the radio. Tapping 📻 Radio enters
     body.radio-mode: hides every other banner item except the toggle (now
     labeled "← Back") and reveals the radio controls inline. Exiting
     restores the normal banner layout. */
  body.radio-mode #radio-controls{display:flex !important;align-items:center;gap:4px;}
  body.radio-mode #radio-track-name{display:inline !important;max-width:40vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:700;}
  body.radio-mode #wallet-toggle-btn{display:none !important;}
  body.radio-mode #wallet-group > *{display:none !important;}
  body.radio-mode #banner-center{display:flex !important;flex:1 1 auto;justify-content:center;}
  body.radio-mode #vip-btn,
  body.radio-mode #shop-btn,
  body.radio-mode #daily-btn,
  body.radio-mode #scratch-btn,
  body.radio-mode #lootbox-btn{display:none !important;}
  body.radio-mode #banner-right{display:none !important;}
  body.radio-mode #radio-toggle-btn{
    background:#6a2545;
    box-shadow:0 0 10px rgba(200,80,140,0.55);
  }

  /* Shop-overlay top button row: force Drug Market / Training / Manage /
     Expedition to stay on a single line by shrinking font/padding. Also
     keeps 20px breathing room below the row. */
  #right-top-btn-row{
    padding-bottom:20px;
    flex-wrap:nowrap !important;
    gap:4px;
  }
  #drug-market-btn,
  #harem-training-btn,
  #hired-cyl-btn,
  #exped-btn{
    font-size:11px !important;
    padding:5px 6px !important;
    letter-spacing:0 !important;
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
    min-width:0;
  }

  /* Milestone toasts ("1000 squeeze!", "💦 1M total droplets!") float over
     the cylinder at 41px on desktop — too big on phones, where they
     wrap and overflow the narrow game-area. Shrink 30% so they fit.
     .milestone-moment-text is the big full-screen "⭐ 1st squeeze!" pop
     from showMilestoneToast (60px on desktop → 42px here).
     Also cap width + allow wrapping — long labels like "💦 1M total
     droplets!" still overflow the 90vw zone in portrait at 28px. */
  .milestone-toast{
    font-size:28px !important;
    max-width:86vw;
    white-space:normal !important;
    word-break:break-word;
    line-height:1.15;
    text-align:center;
    transform:translateX(-50%);
  }
  .milestone-moment-text{
    font-size:42px !important;
    max-width:92vw;
    word-break:break-word;
    line-height:1.1;
  }

  /* UI-unlock popups — core.css sets width:520px on body.mobile-touch-ui and
     relies on max-width:calc(100vw - 32px) to clamp, which makes the panel
     stretch flush to the edges on a phone and read as "too wide". Cap it to
     ~75% of the viewport (with a sensible minimum/maximum) so the popup feels
     like a card instead of a full-screen banner.
     Also drop the scaleY(0.7) squish from core.css — it only applied while
     the panel was idle (the close animation's transform overrides it, so the
     popup visually "grew" when the X was tapped). Keeping the natural aspect
     ratio throughout means no size jump on close. Note: no !important on
     transform — that lets the entrance/closing slide animations still run. */
  body.mobile-touch-ui .ui-unlock-panel,
  .ui-unlock-panel{
    width:min(60vw,256px) !important;
    max-width:min(60vw,256px) !important;
    transform:none;
  }

  /* Harem modal layout shuffle: on mobile the desktop puts the Fuse button
     floating absolutely in the middle-top, "📥 Import NPC" inline next to
     the title, and the counter beside it. That wastes horizontal space on a
     phone. Rearrange so:
       - Fuse button sits inline at the top-right (where Import used to be)
       - Import button moves to a stacked group BELOW the "X / 2 imports
         today" counter (via flex-direction:column-reverse)
       - DPS counter drops to its natural spot below the title block */
  .cylarmy-modal .cylarmy-top-actions{
    position:absolute !important;
    top:12px !important;
    right:54px !important;     /* leave the ✕ close button undisturbed */
    left:auto !important;
    transform:none !important;
    display:flex !important;
    gap:6px !important;
    z-index:9 !important;
  }
  .cylarmy-modal .cylarmy-fuse-btn-top,
  .cylarmy-modal .cylarmy-breed-btn-top{
    padding:6px 12px !important;
    font-size:13px !important;
    border-radius:8px !important;
  }
  .cylarmy-modal .cylarmy-import-wrap{
    display:flex !important;
    flex-direction:column-reverse !important;  /* counter ABOVE button */
    align-items:flex-start !important;
    gap:6px !important;
    margin-left:0 !important;
    margin-top:8px !important;
  }
  .cylarmy-modal .cylarmy-import-header-btn{
    width:100%;
    justify-content:center;
  }
  .cylarmy-modal .cylarmy-import-counter{
    font-size:11px !important;
    padding:3px 8px !important;
  }
  /* DPS counter — drop the absolute positioning (JS also skips its coord
     math on mobile) so the counter sits statically below the title line. */
  .cylarmy-modal .cylarmy-dps-bottom{
    position:static !important;
    top:auto !important;
    left:auto !important;
    margin:6px 0 10px !important;
    display:inline-flex;
  }
  /* Title wraps so the title + help button + (now empty-ish) import wrap
     line flows vertically on narrow phones. */
  .cylarmy-modal .cylarmy-modal-title{
    display:flex !important;
    flex-wrap:wrap !important;
    align-items:center;
    gap:6px;
  }

  /* NPC card grid — force 3 columns on mobile so at least 3 cards fit per
     row at any phone width. Desktop uses auto-fill with minmax(132px) which
     only fits 2 at 375px. Cards stay tall enough for the existing content
     to lay out; padding slightly reduced to free interior width. */
  .cylarmy-modal .cylarmy-npc-grid{
    grid-template-columns:repeat(3, 1fr) !important;
    gap:8px !important;
    grid-auto-rows:236px !important;
    padding:10px 6px !important;
  }
  .cylarmy-modal .cylarmy-npc-card{
    padding:9px 5px 7px !important;
    gap:3px !important;
    font-size:11px;
  }

  /* Harem — "Cylinder Upgrades" inventory section (.cylarmy-upgrade-counter):
     scale everything inside down 20% so the 5-rarity row doesn't dominate
     the modal on a phone. font-size shrinks the text; gap/padding scale
     proportionally so the pill spacing matches. */
  .cylarmy-modal .cylarmy-upgrade-counter{
    font-size:11px !important;      /* 14 × 0.8 */
    gap:6px 10px !important;      /* 8 × 0.8 / 13 × 0.8 */
    padding:7px 13px !important;  /* 9 × 0.8 / 16 × 0.8 */
    border-radius:8px !important;
  }
  .cylarmy-modal .cylarmy-upgrade-counter-label{
    font-size:11px !important;
  }
  .cylarmy-modal .cylarmy-upgrade-cell{
    font-size:10px !important;      /* 13 × 0.8 */
    padding:2.4px 8px !important;     /* 3 × 0.8 / 10 × 0.8 */
    gap:4px !important;               /* 5 × 0.8 */
    border-radius:10px !important;  /* 13 × 0.8 */
  }

  /* Harem toolbar — collapse sort/filter to the active button only on
     mobile. Tapping the active button toggles the `.dropdown-open` class on
     the group (see _caSortBy / _caFilterBy in cylinder_army.js), which
     reveals the full option list; tapping any option commits the choice
     and re-collapses. The view toggle (▦/☰) isn't inside these groups so
     it stays fully visible. */
  .cylarmy-modal .cylarmy-sort-group:not(.dropdown-open) .cylarmy-sort-btn:not(.active),
  .cylarmy-modal .cylarmy-filter-group:not(.dropdown-open) .cylarmy-filter-btn:not(.active){
    display:none !important;
  }
  /* Chevron hint on the collapsed-state active button so the player knows it
     opens a dropdown. Removed when the group is expanded. */
  .cylarmy-modal .cylarmy-sort-group:not(.dropdown-open) .cylarmy-sort-btn.active::after,
  .cylarmy-modal .cylarmy-filter-group:not(.dropdown-open) .cylarmy-filter-btn.active::after{
    content:" ▾";
    font-size:10px;
    opacity:0.8;
    margin-left:3px;
  }
  /* Expanded state: reveal all options in a flex row; the active one stays
     highlighted via its existing .active styling so the current choice is
     still visually marked. */
  .cylarmy-modal .cylarmy-sort-group.dropdown-open,
  .cylarmy-modal .cylarmy-filter-group.dropdown-open{
    flex-wrap:wrap;
    background:#1a0a28;
    border:1px solid #4a2080;
    border-radius:8px;
    padding:4px 6px;
  }

  /* Cosmetics modal: the desktop grids use repeat(6,1fr) which stays wider
     than ~330px even after max-width:96vw kicks in (each card wants ≥76px
     for the 60px preview + padding → 6 × 76 + 5 × 10 gap = 506px min). On
     phones that forces horizontal scrolling across the skins/themes grids.
     Drop to 3 columns and shrink the preview so every card fits the
     viewport width. Same treatment for the sized-card (size/style) grids,
     which use flex-wrap but have a hardcoded 120px card width — cap it to
     fill the row in 3s without going too small to read. */
  .cosm-modal .cosm-grid,
  .cosm-modal .theme-grid{
    grid-template-columns:repeat(3,1fr) !important;
    gap:8px !important;
  }
  .cosm-modal .cosm-preview,
  .cosm-modal .theme-preview{
    width:48px !important;
    height:48px !important;
    border-radius:24px !important;
    margin-bottom:6px !important;
  }
  .cosm-modal .cosm-card,
  .cosm-modal .theme-card{
    padding:10px 6px !important;
  }
  .cosm-modal .size-card{
    width:calc((100% - 20px) / 3) !important;
    min-width:0 !important;
    padding:10px 6px !important;
  }
  .cosm-modal .size-grid,
  .cosm-modal .style-grid{
    gap:8px !important;
  }

  /* Touch-down ring: spawned by squeeze.js/startDrag on mobile touch, placed
     at the cursor position inside #game-area. Confirms "your tap landed" a
     full frame before the first droplet appears — on touch there's no
     hover state, so the glow+cursor-emoji was the only prior feedback and
     both can be missed on a fast tap. Auto-removes after the animation. */
  .touch-ripple{
    position:absolute;
    width:110px;
    height:110px;
    border-radius:50%;
    border:3px solid rgba(255,220,150,0.85);
    box-shadow:0 0 14px rgba(255,210,130,0.55),inset 0 0 10px rgba(255,230,180,0.35);
    transform:translate(-50%,-50%) scale(0.3);
    pointer-events:none;
    z-index:40;
    animation:touchRipplePulse 0.5s cubic-bezier(0.2,0.6,0.3,1) forwards;
    will-change:transform,opacity;
  }
  @keyframes touchRipplePulse{
    0%  { transform:translate(-50%,-50%) scale(0.3); opacity:0.95; border-width:4px; }
    60% { opacity:0.7; }
    100%{ transform:translate(-50%,-50%) scale(1.55); opacity:0; border-width:1px; }
  }
}

/* ── Vertical-space tightening: phones AND short landscape screens ─────────
   #cylinder-wrap sits at top:330px inside a 780px-tall #game-area, which
   leaves a lot of empty room above the cylinder. On phones and on long-but-
   short (landscape-short) viewports, vertical space is scarce — pull the
   whole game-area up ~20% of that offset with a negative margin-top so the
   cylinder reads higher under the banner. Trimming #left-game-wrap's top
   padding reclaims a few more pixels. Margin (vs shifting individual
   absolute-positioned children) keeps hit-zone / kiwis / tutorial arrows
   aligned, since they all offset from the same game-area origin. */
@media (max-width: 1400px),
       (max-height: 640px) and (orientation: landscape){
  #left-game-wrap{padding-top:2px !important;}
  /* Responsive lift: scale with viewport height instead of a hard -66px.
     On tall phones (~800dvh) ≈ -64px, close to the old constant. On very
     short screens (≤400dvh, keyboard open / short landscape) it softens
     to ~-32px so the cylinder's top doesn't get cropped under the banner.
     On unusually tall viewports the MIN (-88px) gives a little more lift
     so the kiwis/stats don't drift far from the banner. */
  #game-area{margin-top:clamp(-88px, -8dvh, -32px);}
}

/* ── Sit the cylinder/kiwis lower on roomy phones ─────────────────────────
   The lift above is tuned for the tightest cases. On phones that aren't very
   narrow (>360px) AND have real vertical room (≥700px tall), soften the lift
   a lot so the (now slightly larger) cylinder reads lower under the banner
   instead of crowding the top. Very narrow phones and short/landscape screens
   keep the stronger lift from the rule above, since they have no room to spare.
   This rule comes later in source with equal specificity, so it wins where it
   matches. */
@media (min-width: 361px) and (max-width: 1400px) and (min-height: 700px){
  #game-area{margin-top:clamp(-8px, 1.5dvh, 24px);}
}

/* ── Ultra-narrow phones (<320px wide): shop top-button row collapses to
   icons only. The labels truncated to "Drug Mar…" / "Train…" at this width
   because the row forces single-line + nowrap; emoji-only is clearer than
   a three-letter ellipsis. Full label still visible on 320px+ phones. */
@media (max-width: 319px){
  #right-top-btn-row #drug-market-btn,
  #right-top-btn-row #harem-training-btn,
  #right-top-btn-row #exped-btn{
    font-size:0 !important;
    min-width:38px;
    padding:6px 8px !important;
  }
  #drug-market-btn::before{content:"💊";font-size:17px;display:inline-block;line-height:1;}
  #harem-training-btn::before{content:"🏋️";font-size:17px;display:inline-block;line-height:1;}
  #exped-btn #exped-btn-text{font-size:0 !important;}
  #exped-btn #exped-btn-text::before{content:"🗺️";font-size:17px;display:inline-block;line-height:1;}
}
