/* ══════════════════════════════════════════════════════════════════════
   PIXEL UP! · UX LANE 5 · MOBILE LAYOUT
   Polish only — same ink / pop / halftone language as desktop, no redesign.
   Load LAST in <head> (after l8-arcade.css and layout.css) so equal-
   specificity rules here win without !important.
   Every rule below answers a measured defect; the numbers are in
   test/ux-lanes/mobile.md (before → after, 320–430 px, 740×360, 768×1024).
   New classes, if ever needed, use the `mb-` prefix. None are needed yet.
   ══════════════════════════════════════════════════════════════════ */

/* ── 1 · SAFE AREAS ─────────────────────────────────────────────────────
   index.html + games pages declare viewport-fit=cover, so on a notched
   phone in landscape the page runs under the notch. env() is 0 on every
   other device, so these max()es are no-ops there. */
/* on the BODY, not .wrap: several .wrap rows set their own padding (the chip
   rail is 0 on purpose) and must not change on desktop. env() is 0 there. */
body{
  padding-left:env(safe-area-inset-left, 0px);
  padding-right:env(safe-area-inset-right, 0px);
}
.top{padding-top:env(safe-area-inset-top, 0px)}
.foot{padding-bottom:calc(40px + env(safe-area-inset-bottom, 0px))}
.toast{bottom:calc(26px + env(safe-area-inset-bottom, 0px))}
/* the wooden frame grows into the notch instead of the notch eating the page */
body::before{
  border-left-width:max(var(--frame, 0px), env(safe-area-inset-left, 0px));
  border-right-width:max(var(--frame, 0px), env(safe-area-inset-right, 0px));
  border-bottom-width:max(var(--frame, 0px), env(safe-area-inset-bottom, 0px));
}

/* ── 2 · PHONES & SMALL TABLETS (≤ 860 px · the burger breakpoint) ───── */
@media (max-width:860px){
  /* The skin's fixed wooden frame (9 px here) sits ON TOP of the page.
     The header's end controls were starting at x=10 and ending at W-10,
     i.e. touching / under the frame. Clear it by the frame + 6 px. */
  .top-in{
    padding-left:calc(var(--frame, 0px) + 6px);
    padding-right:calc(var(--frame, 0px) + 6px);
  }

  /* tap targets ≥ 40 px — min-height only, so padding/shape stay the skin's */
  .catrail .chip,
  main .chip:is(a,button),          /* in-page filter chips measured 28 px */
  .sec-head .more,
  main .cab-btn,
  .so-btn,
  button.play, button.ghost{min-height:40px}
  .sec-head .more{display:inline-flex;align-items:center}
  .top .xp-pill,.top .so-me,.top .brand{min-height:40px}

  /* card corner buttons are 32 px by design. Keep the look, grow the HIT
     area with an invisible pseudo: 32 + 4 + 4 = 40. The social button
     moves 2 px down so the two hit areas meet instead of overlapping. */
  /* (the pseudo is placed from the PADDING box, so −4 px − the 2.5 px border) */
  .card .fav::after,.card .so-card::after{content:'';position:absolute;inset:-6.5px}
  .card .so-card{top:48px}

  /* static game pages (games/*) have no burger and no search: arcade.css
     hides .nav at ≤860, which left phones with NO navigation at all.
     Bring it back as a swipeable strip beside the brand. */
  .top-in:not(:has(.burger)) .nav{
    display:flex;margin-left:auto;min-width:0;overflow-x:auto;scrollbar-width:none;
    -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
  .top-in:not(:has(.burger)) .nav::-webkit-scrollbar{display:none}
  .top-in:not(:has(.burger)) .nav a{flex:none;min-height:40px;display:inline-flex;align-items:center;padding:7px 11px}
}

/* ── 3 · PHONES (≤ 640 px) ──────────────────────────────────────────────
   iOS Safari zooms the whole page when a field under 16 px gets focus,
   and the wager forms' inputs measured 22 px tall (selects 18 px). */
@media (max-width:640px), (orientation:landscape) and (max-height:500px), (pointer:coarse){
  .top .search input{font-size:16px}
  main input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]),
  main select,main textarea{font-size:16px;min-height:40px}
}

/* ── 4 · NARROW PHONES (≤ 520 px) ───────────────────────────────────────
   wager.html does not load layout.css, so its header kept the 16 px gaps
   and the full wordmark: 87–139 px of sideways scroll at 320–390 px. Give
   every header with a search the same compact treatment index already has. */
@media (max-width:520px){
  .top-in{gap:8px}
  .top-in:has(.search) .brand .wm{display:none}
  .top .search{min-width:0;flex:1 1 auto}
  .top .search input{padding-left:12px;padding-right:30px}
  .top .search .mag{right:11px}

  /* a live board inside the wager stage: 8 × minmax(30px,11vw) was wider than
     the stage at 320 px and the stage clips. Let the squares share the width. */
  #gameRoot{padding:10px}
  #gameRoot .board{grid-template-columns:repeat(8,minmax(0,1fr));width:100%;max-width:432px}
}

/* ── 5 · SMALL PHONES (≤ 430 px) ────────────────────────────────────────
   The signed-out "👤 Sign in" pill (88 px) was what pushed the header past
   the frame. Icon-only here; the text stays in the DOM, so the accessible
   name is still "Sign in", and the title tooltip still explains it. */
@media (max-width:430px){
  .top .so-me.out{font-size:0;width:42px;min-width:42px;height:40px;padding:0;justify-content:center;gap:0}
  .top .so-me.out::before{content:'👤';font-size:18px;line-height:1}
  .top .so-me{min-width:40px;justify-content:center}

  /* the frame is decoration: 9 → 6 px gives the page back 6 px per row */
  :root{--frame:6px}
  body::before{border-width:6px}
  body::before{
    border-left-width:max(6px, env(safe-area-inset-left, 0px));
    border-right-width:max(6px, env(safe-area-inset-right, 0px));
    border-bottom-width:max(6px, env(safe-area-inset-bottom, 0px));
  }

  /* static pages: the swipe nav needs the room more than the wordmark does */
  .top-in:not(:has(.burger)) .brand .wm{display:none}
}

/* ── 6 · PHONES < 390 px (SE, 360-class Androids, iPhone mini/8) ───────
   After everything above, the index search's TYPING area was 36 px at 320,
   31 px at 360 and 46 px at 375 — "Se…". Collapse it to a 42 px magnifier
   button (the usual mobile-portal pattern); on focus it opens across the
   whole header bar. Pure CSS, no script, input + id + handlers untouched. */
@media (max-width:389px){
  /* margin-right:auto keeps the trailing controls docked right, as before */
  .top .search{flex:0 0 42px;width:42px;margin:0 auto 0 0}
  /* the skin paints every input's text with !important, so this has to too */
  .top .search:not(:focus-within) input{padding:0;color:transparent!important;cursor:pointer}
  .top .search:not(:focus-within) input::placeholder{color:transparent}
  .top .search:not(:focus-within) input::-webkit-search-cancel-button{display:none}
  /* a query is still applied while collapsed: say so with the cool fill */
  .top .search:not(:focus-within):has(input:not(:placeholder-shown)) input{background:var(--cool)!important}
  .top .search .mag{right:13px}
  .top .search:focus-within{
    position:absolute;z-index:70;
    left:calc(var(--frame, 0px) + 6px);right:calc(var(--frame, 0px) + 6px);
    top:calc(env(safe-area-inset-top, 0px) + 12px);width:auto;flex:none}
  .top .search:focus-within input{padding:0 30px 0 14px;cursor:text}
}

/* ── 7 · LANDSCAPE PHONES (short screens) ───────────────────────────────
   The 66 px sticky header was 18.3 % of a 360 px-tall landscape screen.
   52 px keeps every control at 40 px and drops it to ~14 %. */
@media (orientation:landscape) and (max-height:500px){
  :root{--toph:52px}
  .top-in{height:50px;
    padding-left:calc(var(--frame, 0px) + 6px);
    padding-right:calc(var(--frame, 0px) + 6px)}
  .catrail-in{padding:7px 0}
  :root{--frame:6px}
  body::before{border-top-width:6px}
}
