/* ===================================================================
   Mobile UX overlay — shared by every user-facing page in waifumaster.
   Strategy: mobile-first patches that activate at <=720px viewport.
   Below 720px we hide the standard top nav, tighten paddings, enlarge
   touch targets, and pin a bottom nav bar with the gacha-game pattern.
   =================================================================== */

/* iOS prevents zoom on focus only when input font-size is >=16px.
   Smaller fonts on small screens are fine, but inputs/textareas/selects
   must stay at 16px to keep keyboards from triggering layout zoom. */
input, textarea, select{
  font-size: 16px;
}

/* login.html / signup.html zero out outline on input:focus to use a
   border highlight instead. That breaks keyboard navigation on the rest
   of the controls. Restore a visible focus ring for keyboard users via
   :focus-visible on every interactive element — does not affect mouse. */
button:focus-visible,
a:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible{
  outline: 2px solid #73d1ff !important;
  outline-offset: 2px;
}

/* Buttons get at least 44x44 pt of tap area (Apple HIG / Material guideline). */
button, .btn, a.btn{
  min-height: 40px;
  touch-action: manipulation;       /* removes 300ms tap delay */
  -webkit-tap-highlight-color: rgba(115, 209, 255, .25);
}
/* The `.small` modifier shouldn't shrink below the touch-target floor */
button.small, .btn.small{
  min-height: 36px;
}

/* Body padding to keep content from sitting under the bottom nav.
   ONLY applies at <=720px where the nav is actually visible — otherwise
   desktop layouts get a phantom 64px dead band at the bottom. */
@media (max-width: 720px){
  body.has-mobile-bottom-nav{
    padding-bottom: 64px;            /* fallback for non-iOS */
  }
  @supports (padding: env(safe-area-inset-bottom)){
    body.has-mobile-bottom-nav{
      padding-bottom: calc(64px + env(safe-area-inset-bottom));
    }
  }
}

/* ----- Bottom nav (mobile only) -------------------------------------
   Markup contract — pages render this once, near </body>:

   <nav class="mobile-bottom-nav" data-active="pulls">
     <a href="/dashboard"   data-key="dashboard"><span>🏠</span><label>Home</label></a>
     <a href="/pulls"       data-key="pulls">    <span>🎴</span><label>Pulls</label></a>
     <a href="/roster"      data-key="roster">   <span>👥</span><label>Roster</label></a>
     <a href="/achievements" data-key="achievements"><span>🏆</span><label>Achievements</label></a>
     <a href="/app"         data-key="app">      <span>✨</span><label>Generate</label></a>
   </nav>

   On desktop (>720px) it's hidden, so the existing top nav stays.
*/
.mobile-bottom-nav{ display: none; }

@media (max-width: 720px){
  /* Hide every top-nav block; it costs us 60+ vertical px. Cover both
     `<header><nav>…</nav></header>` (dashboard/roster/achievements) and
     `<div class="topbar"><nav>…</nav></div>` (pulls). */
  body.has-mobile-bottom-nav .topbar nav,
  body.has-mobile-bottom-nav header nav{
    display: none !important;
  }
  /* Compact the topbar so the title stays but it's tight. */
  body.has-mobile-bottom-nav .topbar{
    padding: 8px 12px;
  }
  body.has-mobile-bottom-nav .topbar h1{
    font-size: 18px;
  }

  .mobile-bottom-nav{
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 150;   /* below .modal-bg (200) so dialogs cover the nav */
    background: rgba(15, 17, 32, .95);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-top: 1px solid var(--line, #2b2f4a);
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .mobile-bottom-nav a{
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 8px 4px 6px;
    color: var(--muted, #8d92b3);
    text-decoration: none;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .3px;
    transition: color .15s, background .15s;
    -webkit-tap-highlight-color: transparent;
  }
  .mobile-bottom-nav a span{
    font-size: 22px;
    line-height: 1;
    filter: grayscale(.4);
    transition: filter .15s, transform .15s;
  }
  .mobile-bottom-nav a label{
    font-size: 10px;
    line-height: 1;
  }
  .mobile-bottom-nav a.active{
    color: var(--accent, #73d1ff);
  }
  .mobile-bottom-nav a.active span{
    filter: none;
    transform: scale(1.08);
  }
  .mobile-bottom-nav a:active{
    background: rgba(115, 209, 255, .08);
  }

  /* Universal mobile niceties: keep page content from getting eaten by
     the bottom nav (the body padding above already does this for
     opted-in pages, but adding overscroll containment helps the
     scrolling feel native). */
  body.has-mobile-bottom-nav{
    overscroll-behavior-y: contain;
  }

  /* Modals get more breathing room on mobile and respect safe areas.
     Includes the dashboard's .login-modal which auto-pops on day-roll
     and would otherwise overflow vertically with no scroll path. */
  dialog, .modal-card, .age-gate, .style-modal-card,
  .login-modal, .detail-modal{
    width: calc(100vw - 24px) !important;
    max-width: calc(100vw - 24px) !important;
    max-height: calc(100vh - 32px - env(safe-area-inset-bottom, 0px)) !important;
    overflow-y: auto !important;
    margin: max(12px, env(safe-area-inset-top, 0)) auto
            max(12px, env(safe-area-inset-bottom, 0)) auto;
  }

  /* Push the toast above the bottom nav so it's not hidden. */
  .toast{
    bottom: calc(78px + env(safe-area-inset-bottom, 0)) !important;
  }
}

/* ----- Even tighter rules below 380px (older / small phones) -------- */
@media (max-width: 380px){
  body.has-mobile-bottom-nav .topbar h1{ font-size: 16px; }
  .mobile-bottom-nav a label{ font-size: 9px; }
  .mobile-bottom-nav a span{ font-size: 20px; }
  .mobile-bottom-nav a{ padding: 6px 2px 4px; }
}

/* ----- Pull cards: tighten typography in narrow grid cells ---------- */
@media (max-width: 720px){
  .pull-card .name,
  .pull-card .label{
    font-size: 12px;
    line-height: 1.25;
  }
  .pull-card{
    padding: 6px;
  }
}

/* ----- Forms: stack stacked fields cleanly -------------------------- */
@media (max-width: 480px){
  .row{ flex-wrap: wrap; }
  .row .btn, .row button{ flex: 1 1 auto; }
}

/* ====================================================================
   MOBILE ROUND 2 — fix topbar wrap, pull-card carousel, roster layout
   ==================================================================== */

/* ----- Topbar layout: keep header content from overflowing on phones.
   Both `<header><div class="wrap">…</div></header>` and `.topbar` markups
   are covered. Stats pills (hearts, level) pulled inside also wrap.    */
@media (max-width: 720px){
  body.has-mobile-bottom-nav header,
  body.has-mobile-bottom-nav .topbar{
    padding: 8px 12px !important;
  }
  body.has-mobile-bottom-nav header > .wrap,
  body.has-mobile-bottom-nav .topbar{
    display: flex !important;
    flex-wrap: wrap !important;
    align-items: center !important;
    gap: 6px !important;
    row-gap: 6px !important;
  }
  /* Logo / title takes priority */
  body.has-mobile-bottom-nav .topbar h1,
  body.has-mobile-bottom-nav header .logo{
    flex: 0 0 auto !important;
    margin: 0 !important;
  }
  /* Email turns into a single-line ellipsis so it never pushes signout
     off-screen; only relevant on dashboard which has #hdr-email. */
  body.has-mobile-bottom-nav header #hdr-email,
  body.has-mobile-bottom-nav .topbar #hdr-email{
    flex: 1 1 0 !important;
    min-width: 0 !important;
    overflow: hidden !important;
    white-space: nowrap !important;
    text-overflow: ellipsis !important;
    text-align: right !important;
    font-size: 11px !important;
  }
  /* Signout / sound-toggle stay compact */
  body.has-mobile-bottom-nav header .signout,
  body.has-mobile-bottom-nav header #signout,
  body.has-mobile-bottom-nav header #sound-toggle,
  body.has-mobile-bottom-nav .topbar #sound-toggle{
    flex: 0 0 auto !important;
  }
  /* pulls.html stats row (hearts + level pills) — let it wrap to a new
     line under the title rather than spill horizontally. */
  body.has-mobile-bottom-nav .topbar .stats{
    flex: 1 1 100% !important;
    display: flex !important;
    gap: 6px !important;
    justify-content: flex-end !important;
    flex-wrap: wrap !important;
  }
  body.has-mobile-bottom-nav .topbar .stats .pill{
    font-size: 11px !important;
    padding: 3px 8px !important;
  }
}
/* On really small phones drop the email entirely — the avatar/signout
   button is enough for orientation. */
@media (max-width: 380px){
  body.has-mobile-bottom-nav #hdr-email{ display: none !important; }
}

/* ----- Pull cards: deal-a-hand carousel on mobile -------------------
   When .pull-cards has >2 children on a phone, switch to a single-card
   horizontal scroller with snap. Each card occupies ~80vw so the next
   one peeks in from the right (signaling "swipe me"). The existing
   in-page JS still runs flipNext() so reveals stay sequential.        */
@media (max-width: 720px){
  .pull-cards{
    display: flex !important;
    flex-direction: row !important;
    grid-template-columns: none !important;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scroll-padding: 16px;
    gap: 14px;
    padding: 14px 16px 18px;
    margin: 0 -16px;            /* let scroll bleed to viewport edges */
    scrollbar-width: none;       /* Firefox */
  }
  .pull-cards::-webkit-scrollbar{ display: none; }   /* WebKit */
  .pull-cards.single{
    /* For 1× pulls, the existing centered layout still works; just
       remove the carousel-only padding to recenter the lone card. */
    padding: 14px;
    margin: 0;
    overflow: visible;
  }
  .pull-cards .pull-card-slot,
  .pull-cards .pull-card{
    flex: 0 0 80%;               /* ~one card per view, 20% peek of next */
    max-width: 320px;
    scroll-snap-align: center;
    scroll-snap-stop: always;
  }
  /* Counter strip — pages render this once below the carousel; hidden
     on desktop, visible only when there's actually a multi-card hand. */
  .pull-counter{
    display: flex;
    justify-content: center;
    gap: 6px;
    padding: 4px 0 8px;
  }
  .pull-counter .dot{
    width: 7px; height: 7px; border-radius: 50%;
    background: rgba(255,255,255,.2);
    transition: background .15s, transform .15s;
  }
  .pull-counter .dot.active{
    background: var(--accent, #73d1ff);
    transform: scale(1.3);
  }
  .pull-counter .dot.flipped{
    background: rgba(255,255,255,.55);
  }
}
/* Hidden on desktop (the page may render the markup unconditionally) */
.pull-counter{ display: none; }

/* ----- Roster page: filter row stacks, character cards larger ------- */
@media (max-width: 720px){
  /* The existing .wrap has 24px padding which steals visible width; let's
     tighten it so cards have room. */
  body.has-mobile-bottom-nav .wrap{
    padding: 0 14px;
  }
  /* Search/filter bar: stack into a column so each control gets full width.
     Roster page uses .filter-bar; cover both naming conventions. */
  .roster-filters,
  body.has-mobile-bottom-nav header .row,
  .filter-row,
  .filter-bar{
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 8px !important;
  }
  .roster-filters input,
  .roster-filters select,
  .filter-row input,
  .filter-row select,
  .filter-bar input,
  .filter-bar select{
    width: 100% !important;
    box-sizing: border-box;
    min-width: 0 !important;
  }
  /* Stat pills row stays horizontal but wraps */
  .filter-bar > div:has(.stat-pill),
  .filter-bar .stat-pill{
    display: inline-flex;
  }
  /* Anime headers in roster — stack the title above the progress bar */
  .anime-head{
    flex-wrap: wrap;
    gap: 6px;
  }
  .anime-head .pct-bar{
    flex: 1 1 100%;
    max-width: none;
  }
  /* Bigger character cards on phones — 3 per row on a typical 380px viewport */
  .char-grid{
    grid-template-columns: repeat(auto-fill, minmax(108px, 1fr)) !important;
    gap: 8px;
  }
  .char-card{
    padding: 6px;
  }
  .char-card .name{
    font-size: 11px;
    line-height: 1.2;
  }
  /* Roster detail modal — give it real breathing room and let action
     buttons stack 2-up since there are now 6 of them. */
  .detail-modal{
    width: calc(100vw - 24px) !important;
    max-width: calc(100vw - 24px) !important;
    max-height: calc(100vh - 80px - env(safe-area-inset-bottom, 0px)) !important;
    overflow-y: auto !important;
  }
  .detail-modal .quick-actions{
    grid-template-columns: 1fr 1fr !important;
  }
}

/* ----- Lightbox / video preview: full viewport on mobile ------------ */
@media (max-width: 720px){
  .lightbox img,
  .style-result img{
    max-width: calc(100vw - 24px) !important;
    max-height: calc(100vh - 120px) !important;
  }
}
