/* =========================================================================
   Throw — Mobile Polish v5.7
   -------------------------------------------------------------------------
   Build marker (in case of cache surprises):
   To verify the new file is loaded, open the page in DevTools and search
   for the string "MOBILE-V5_7-LOADED" — it appears as a CSS variable
   declaration on :root below.
   -------------------------------------------------------------------------
   v5.7 changes vs v5.6:
     - MOBILE APP READINESS PASS (2026-05). Whole-app additions for
       phone-as-app form (Android WebView wrap + iOS Safari Add-to-
       Home-Screen). New section appended at end of file:
         • Safe-area insets honored on all fixed/floating UI (toasts,
           FABs, bottom action rows). Stops the gesture bar / home
           indicator eating tap targets.
         • 100dvh swaps applied defensively to common patterns
           (min-height: 100vh, min-height: calc(100vh - Npx)) so the
           layout sizes to the *visible* viewport, not the URL-bar-
           collapsed phantom viewport. Falls back to 100vh on browsers
           without dvh support.
         • touch-action: manipulation on every button/link to remove
           the 300ms tap delay on Android Chrome / WebView.
         • Action-row defensiveness: .ctrl-actions, .action-row,
           .over-actions, .modal-actions, #setupActionBtns all
           guaranteed to wrap rather than overflow on 360px phones.
           min-width: 0 enforced so labels can shrink/ellipsis instead
           of clipping.
         • Tap-target floor: every button, link, .btn, input gets
           min-height: 44px (Apple HIG / Android Material 48dp ish).
         • iOS Safari zoom-on-focus killed by enforcing 16px font on
           every text input field-wide (defensive — many pages already
           do this per-input).
         • Pull-to-refresh containment via overscroll-behavior so the
           WebView doesn't bounce-load on accidental top-edge pulls.
         • Tap-highlight color removed — the grey flash on Android
           Chrome looks like a bug, not a feature, in app form.
   -------------------------------------------------------------------------
   v5.6 changes vs v5.5:
     - Auth polish: compact floating lang pill, translucent in light theme.
     - Auth forms vertically centred in the viewport (no more dead zone).
     - Crisper input chrome and a brand focus ring.
     - Helper links tightened and given real 44px tap targets.
     - reset_password.html: card chrome dropped, footer hidden, label
       spacing fixed — now matches the login/register feel.
     - Topbar sign-out demoted to a quiet text link on signed-in pages.
     - WELCOME [name] hero: solid white + purple glow instead of low-
       contrast gradient (gradient stops merged into dark bg).
     - Marketing footer collapsed to legal-only on signed-in pages.
     - Notification bell icon SVG restored (was empty button).
     - Topbar-nav variant (game.html, dartbot.html) now hides tier badge,
       username, and inline page-label on mobile so the right side doesn't
       overflow off-screen. Matches .topbar-right behaviour.
     - Lobby (.lb-wrap) edge padding restored — headings, filter labels,
       and the search input were clipping at the viewport edge.
     - League Manager stat chips switched from flex-wrap to explicit
       3-column grid so the 5 tiles read as 3 + 2 rather than 4 + 1
       orphan.
     - Player-card stat tiles flattened on mobile (no more bordered
       boxes-within-boxes).
     - teams.html / profile.html: page edge gutters restored, page header
       stacked vertically, "+ New Team" promoted to full-width primary
       gradient CTA, Join a League card restructured to a clean stacked
       flow. Empty state's duplicate button removed (top button is enough).
     - profile.html: QR section centered + condensed; FREEPLAY plan
       card's locked features moved into a soft "Pro adds" sub-section
       (replaces the red-X "rejected" treatment); section spacing opened up.
     - my-moderation.html: top-bar stacks vertically on mobile and reserves
       right-padding so the heading doesn't run under the floating lang pill.
     - admin-disputes.html / admin-misconduct.html: same top-bar fix, plus
       toasts moved to bottom so they don't collide with the floating pill.
     - Darts-used selector (dartbot/icon-match): label promoted to a clear
       section header, segment buttons flex to fill the row for proper
       tap targets.
     - index.html (marketing landing): hero stats restored to 3-up grid on
       mobile (was wasteful 1-up stack), steps section grid layout fixed
       (was cramped 3-col flex), game-modes pill grid and chip styling
       added (production CSS was missing entirely), final CTA buttons
       full-width, section padding eased from 100px to 56px on mobile.
     - autoscorer.html: secondary "AUTOSCORER" title in topbar hidden on
       mobile (was clipping behind floating pill); live-chip promoted to
       small pill background so "No camera" / "Live" reads as a status.
     - Legal pages (privacy / terms / refund): horizontal gutters restored.
       The shared .legal-body padding rule was overriding .page-container's
       horizontal padding, causing body text to run to the viewport edge.
     - match-view.html: header (.hdr) stacks vertically on mobile so the
       back button doesn't wrap; flex-whitespace bug in the camera
       placeholder text fixed via wrapping span.
     - Light-theme regression fix: the v5.6 `:root` color override and
       body-bg override were bleeding into light theme (because :root
       matches html regardless of data-theme). Re-scoped both to dark
       theme only.
     - Dashboard light-theme gaps filled: .mt-wide and .mt-slim tiles
       (Online Lobby, Online Match, Statistics, Dartbot, Icons rows) had
       hardcoded dark-navy backgrounds with no light-theme overrides.
       Added theme-aware fills directly in dashboard.html. Sign-out link
       color also given a dark muted variant for light topbar contrast.
     - profile.html theme bootstrap: now reads localStorage / system
       preference (was hardcoded to "dark"). Removed an IIFE near the end
       of the page that was clobbering localStorage.treblo-theme back to
       "dark" on every page load — that bug was breaking theme preference
       for ALL pages (any visit to profile reset light theme to dark).
     - .field label / input / select / textarea / placeholder color
       overrides scoped to dark theme only. They had been forcing white
       text/translucent-white-on-bg regardless of theme, making the
       "Game Mode" / "Best Of" labels and other form labels invisible in
       light theme.
     - profile.html: added a working theme toggle in a new "Appearance"
       section between Account Info and Subscription. Tappable DARK/LIGHT
       labels and pill with sliding knob; persists to localStorage so
       every page's bootstrap script picks it up. "Match system theme"
       link clears the saved preference to revert to OS-follow. The
       previously hidden .theme-toggle-wrap markup (lines 560-564) was
       removed from the topbar — the new section uses a body-level layout
       that's more discoverable and doesn't compete with the bell/lang/
       sign-out cluster on mobile.
   -------------------------------------------------------------------------
   v5.5 changes vs v5.4:
     - Gap below Sign-in button halved (60px → 30px).
     - "← Back to homepage" link hidden on mobile auth screens.
   -------------------------------------------------------------------------
   Full mobile design pass. Drop-in stylesheet, loaded LAST in <head>.
   Scoped to <= 720px so desktop is never affected.

   Sections
     0.  Mobile dark-theme lift  (token overrides — lifts whole app)
     1.  Global mobile foundations  (overflow, tap targets, inputs)
     2.  Homepage top nav (<nav>)
     3.  Homepage hero
     4.  Homepage feature sections (cards, pricing, footer)
     5.  In-app top bar (.topbar)
     6.  In-app page layout (.page / .col-left / .col-right)
     7.  Dashboard hero + main tiles
     8.  Dashboard secondary cards (mode-grid, leagues, stats, recents)
     9.  Auth screens (login / register)  — incl. WELCOME TO THROW DARTS
     10. Pill rows / chip rows / option rows
     11. New / Edit league wizard
     12. Sidebar admin group (game.html)
     13. Lobby create-competition wizard
     14. OAuth buttons
     15. Drawers, modals, friends panel
     16. Tables / scrollable rows
     17. Game / scoring / dartbot light touchups
     18. Very small phones (<= 380px)
   ========================================================================= */


/* ────────────────────────────────────────────────────────────────────────
   GLOBAL DEFAULT: hide the mobile-only welcome heading on desktop.
   The .mobile-welcome block lives in login.html and register.html and is
   only meant to appear under 720px. Hide it by default; section 9 turns
   it back on at the mobile breakpoint.
   ──────────────────────────────────────────────────────────────────────── */
:root { --MOBILE-V5_7-LOADED: true; }
.mobile-welcome { display: none; }


/* ════════════════════════════════════════════════════════════════════════
   1. GLOBAL MOBILE FOUNDATIONS
   These run on every mobile page and are the foundation everything else
   builds on. Box-sizing, no horizontal overflow, touch-friendly targets,
   16px input font (stops iOS auto-zoom).
   ════════════════════════════════════════════════════════════════════════ */

@media (max-width: 720px) {

  /* ════════════════════════════════════════════════════════════════════
     0. MOBILE DARK-THEME LIFT
     The desktop dark tokens are intentionally near-black (#f2efe8 /
     #f2efe8). On a phone OLED that's literally pixels-off, which makes
     the UI feel dead and high-contrast. Lift the base tokens here so
     the whole app reads as a proper dark navy on phones, without
     touching the desktop look.

     Targets the dark theme only (and the no-attribute default which is
     dark per the index page bootstrap script).
     ════════════════════════════════════════════════════════════════════ */
  :root:not([data-theme="light"]),
  [data-theme="dark"] {
    --bg:        #f2efe8 !important;   /* was #f2efe8 — now visibly lifted */
    --bg-2:      #fffefb !important;   /* was #f2efe8 */
    --surface:   #faf7f0 !important;   /* was #fffefb */
    --surface-2: #faf7f0 !important;   /* was #faf7f0 */
    --surface-3: #faf7f0 !important;   /* was #faf7f0 */

    --border:    rgba(18,21,23,0.10) !important;
    --border-2:  rgba(18,21,23,0.16) !important;
    --border-3:  rgba(18,21,23,0.26) !important;

    /* Text gets a small bump too so secondary text isn't muddy on the
       lifted background. */
    --text-2:    rgba(18,21,23,0.70) !important;
    --text-3:    rgba(18,21,23,0.45) !important;

    /* Card gradient lifted to match new surfaces. */
    --grad-card: linear-gradient(160deg, #faf7f0 0%, #fffefb 100%) !important;
  }

  /* Belt-and-braces: some pages (login.html / register.html) set their
     own --bg / --bg-2 inline. Force the body bg directly so it always
     uses the lifted base in dark mode, even on those pages. */
  [data-theme="dark"] body,
  html:not([data-theme="light"]) body {
    background: #f2efe8 !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     1. GLOBAL MOBILE FOUNDATIONS
     Box-sizing, no horizontal overflow, touch-friendly targets,
     16px input font (stops iOS auto-zoom).
     ════════════════════════════════════════════════════════════════════ */

  html, body {
    max-width: 100vw;
    overflow-x: hidden;
    -webkit-text-size-adjust: 100%;
  }

  /* No element should ever break the viewport. */
  img, video, canvas, svg, iframe { max-width: 100%; height: auto; }

  /* Tap targets. */
  button, .btn, input[type="submit"], input[type="button"],
  .btn-primary, .btn-submit, .btn-plan-pro, .btn-plan-free,
  a.btn, .topbar-signout, .topbar-logout, .topbar-profile {
    min-height: 44px;
    font-size: 15px !important;
  }

  /* Form fields: 16px font prevents iOS Safari from zooming on focus. */
  input[type="text"], input[type="email"], input[type="password"],
  input[type="search"], input[type="number"], input[type="tel"],
  input[type="url"], input[type="date"], input[type="time"],
  textarea, select {
    font-size: 16px !important;
    min-height: 44px;
    padding: 12px 14px !important;
  }

  /* Tables that won't fit shouldn't blow out the layout. */
  table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }


  /* ════════════════════════════════════════════════════════════════════
     2. HOMEPAGE TOP NAV (<nav>)
     ════════════════════════════════════════════════════════════════════ */

  nav {
    padding: 0 14px !important;
    height: 56px !important;
    gap: 8px !important;
  }
  .nav-links { display: none !important; }
  .nav-cta {
    gap: 8px !important;
    flex-shrink: 0 !important;
    align-items: center !important;
  }
  .btn-nav-login {
    font-size: 13px !important;
    padding: 8px 10px !important;
    white-space: nowrap !important;
  }
  .btn-nav-signup {
    font-size: 13px !important;
    padding: 9px 14px !important;
    white-space: nowrap !important;
    line-height: 1.2 !important;
    border-radius: 10px !important;
  }
  .nav-logo-mark { width: 30px !important; height: 30px !important; font-size: 15px !important; }
  .nav-logo-text { font-size: 17px !important; letter-spacing: 2.5px !important; }

  /* Compact-mode language picker inside the homepage nav */
  nav .treblo-lang-switcher.is-compact .treblo-lang-btn {
    height: 32px !important;
    padding: 0 7px !important;
    font-size: 11px !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     3. HOMEPAGE HERO
     The hero is min-height: 100vh + justify-center on desktop, which
     causes content to drift up under the fixed 56px nav on phones.
     Switch to top-aligned with enough top padding to clear the nav.
     ════════════════════════════════════════════════════════════════════ */

  .hero {
    min-height: auto !important;
    padding: 88px 20px 56px !important;
    justify-content: flex-start !important;
  }

  .hero-badge {
    font-size: 10px !important;
    padding: 7px 14px !important;
    line-height: 1.4 !important;
    margin-bottom: 22px !important;
    text-align: center !important;
    max-width: 100% !important;
    white-space: normal !important;
    letter-spacing: 1.2px !important;
  }

  .hero-headline {
    font-size: 60px !important;
    line-height: 0.92 !important;
    letter-spacing: 1px !important;
    margin-bottom: 14px !important;
  }

  .hero-sub-headline {
    font-size: 14px !important;
    letter-spacing: 3px !important;
    margin-bottom: 22px !important;
  }

  .hero-desc {
    font-size: 15px !important;
    line-height: 1.6 !important;
    margin-bottom: 26px !important;
    max-width: 100% !important;
    color: rgba(18,21,23,0.72) !important;
  }

  /* CTA buttons stack and fill width */
  .hero-actions {
    display: flex !important;
    flex-direction: column !important;
    gap: 10px !important;
    width: 100% !important;
  }
  .btn-hero-primary,
  .btn-hero-secondary {
    width: 100% !important;
    justify-content: center !important;
    text-align: center !important;
    padding: 14px 22px !important;
    font-size: 15px !important;
    border-radius: 12px !important;
  }
  /* The two secondary buttons (Sign in, See how it works) were nearly
     invisible on dark — beef them up so they look like real buttons. */
  .btn-hero-secondary {
    background: rgba(18,21,23,0.05) !important;
    border: 1px solid rgba(18,21,23,0.18) !important;
    color: #ffffff !important;
    font-weight: 600 !important;
  }

  /* Stats: 2x2 grid instead of one wide row that wraps awkwardly. */
  .hero-stats {
    display: grid !important;
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 24px 16px !important;
    margin-top: 36px !important;
    width: 100% !important;
  }
  .hero-stat-num { font-size: 36px !important; }
  .hero-stat-label { font-size: 12px !important; }

  /* Dim the dartboard SVG so it isn't visual noise on a small screen. */
  .hero-dartboard { opacity: 0.12 !important; }

  /* Scroll indicator tends to overlap content on short phones. */
  .scroll-indicator { display: none !important; }


  /* ════════════════════════════════════════════════════════════════════
     4. HOMEPAGE FEATURE SECTIONS
     ════════════════════════════════════════════════════════════════════ */

  /* Section padding - tighten on phones so each section feels punchy */
  section { padding: 56px 18px !important; }

  .section-label {
    font-size: 11px !important;
    letter-spacing: 2px !important;
    margin-bottom: 10px !important;
  }
  .section-title {
    font-size: 36px !important;
    line-height: 1 !important;
    letter-spacing: 1px !important;
    margin-bottom: 14px !important;
  }
  .section-desc {
    font-size: 15px !important;
    line-height: 1.6 !important;
    max-width: 100% !important;
    margin-bottom: 32px !important;
  }

  /* Features grid: single column with proper gaps */
  .features-grid {
    grid-template-columns: 1fr !important;
    gap: 14px !important;
  }
  .feature-card {
    padding: 22px 20px !important;
  }
  .feat-icon {
    width: 44px !important;
    height: 44px !important;
    font-size: 22px !important;
    margin-bottom: 14px !important;
  }
  .feat-title {
    font-size: 18px !important;
    margin-bottom: 8px !important;
  }
  .feat-desc {
    font-size: 14px !important;
    line-height: 1.6 !important;
  }

  /* Pricing grid: stacked cards full width */
  .pricing-grid {
    grid-template-columns: 1fr !important;
    gap: 14px !important;
  }
  .price-card {
    padding: 26px 22px !important;
  }

  /* How-it-works steps */
  .steps-grid, .how-grid {
    grid-template-columns: 1fr !important;
    gap: 14px !important;
  }

  /* Footer */
  footer .footer-grid,
  .footer-grid {
    grid-template-columns: 1fr 1fr !important;
    gap: 28px 18px !important;
  }
  footer .footer-bottom,
  .footer-bottom {
    flex-direction: column !important;
    gap: 12px !important;
    text-align: center !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     5. IN-APP TOP BAR (.topbar)
     Slim, clean, just the essentials — logo + avatar + sign-out.
     ════════════════════════════════════════════════════════════════════ */

  .topbar {
    padding: 0 14px !important;
    height: 56px !important;
    gap: 8px !important;
  }
  .topbar-left { gap: 10px !important; min-width: 0 !important; flex-shrink: 0 !important; }
  .topbar-right {
    gap: 8px !important;
    flex-wrap: nowrap !important;
    flex: 1 1 auto !important;
    justify-content: flex-end !important;
    min-width: 0 !important;
    overflow: hidden !important;
  }

  .topbar-logo-mark {
    width: 32px !important;
    height: 32px !important;
    font-size: 17px !important;
    border-radius: 9px !important;
  }
  .topbar-logo-text {
    font-size: 16px !important;
    letter-spacing: 2.5px !important;
  }

  /* Hide the noisy bits — keep only what matters on a phone. */
  .topbar-right .tier-badge,
  .topbar-right .topbar-user,
  .topbar-right .player-code-pill,
  .topbar-right #profileNavName {
    display: none !important;
  }

  .topbar-profile {
    padding: 4px 6px !important;
    gap: 0 !important;
    border-radius: 999px !important;
  }
  .topbar-profile-avatar {
    width: 32px !important;
    height: 32px !important;
    font-size: 13px !important;
  }

  .topbar-signout, .topbar-logout {
    font-size: 12px !important;
    padding: 8px 12px !important;
    white-space: nowrap !important;
    border-radius: 10px !important;
  }


  /* ─── v5.6 topbar-nav variant (game.html, dartbot.html) ─────────────────
     These pages use .topbar-brand + .topbar-nav instead of .topbar-left +
     .topbar-right. The v5.5 noise-hide rules only matched .topbar-right,
     so on these pages the tier badge ("PRO"), username ("Antro"), and the
     "Dartbot" / "Game" page-label inline next to the logo all stayed
     visible — pushing the lang pill off-screen on the right.
     ──────────────────────────────────────────────────────────────────── */

  .topbar-nav .tier-badge,
  .topbar-nav .topbar-user,
  .topbar-nav .player-code-pill {
    display: none !important;
  }

  /* Hide the inline page-title ("Dartbot", "Game") next to the logo. The
     page hero/content makes the page obvious; back arrow + logo is enough
     orientation. */
  .topbar-brand .topbar-page,
  .topbar-left .topbar-page {
    display: none !important;
  }

  /* Tighten the topbar-brand group (back arrow + logo). */
  .topbar-brand {
    gap: 8px !important;
    min-width: 0 !important;
  }
  .topbar-brand .topbar-back {
    font-size: 18px !important;
    padding: 6px 8px !important;
    line-height: 1 !important;
  }

  /* Match topbar-right's nowrap/right-align behaviour so children push to
     the right edge and stay on one line. */
  .topbar-nav {
    gap: 8px !important;
    flex-wrap: nowrap !important;
    flex: 0 0 auto !important;
    justify-content: flex-end !important;
    min-width: 0 !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     6. IN-APP PAGE LAYOUT
     ════════════════════════════════════════════════════════════════════ */

  .page, .lb-wrap, .form-wrap, main {
    max-width: 100% !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
  .col-right {
    padding: 18px 16px 32px !important;
    gap: 18px !important;
  }

  /* v5.6 — restore horizontal gutters on the lobby wrap. The blanket
     padding:0 above zeros .lb-wrap so children can go edge-to-edge, but
     in practice none of the lobby's children need that — and headings,
     filter labels, and the search input were all clipping at the
     viewport edges. Match the .col-right 16px gutter pattern. */
  .lb-wrap {
    padding: 16px 16px 32px !important;
  }

  /* v5.6 — League Manager stat chips (Teams/Players/Fixtures/Played/
     Remaining). The default flex+wrap puts 4 in a row and orphans the
     5th. Switch to an explicit 3-column grid so it reads as a deliberate
     2-row layout (3 + 2). */
  .manage-stat-chips {
    display: grid !important;
    grid-template-columns: repeat(3, 1fr) !important;
    gap: 8px !important;
    padding: 12px !important;
  }
  .mstat {
    min-width: 0 !important;
    padding: 10px 8px !important;
  }

  /* v5.6 — Player-card stat tiles (.pc-stats > .stat-box × 3) read as
     nested cards-within-cards inside the .player-card on a phone. Drop
     the box chrome on mobile and turn the row into a flat strip with
     thin separator lines. Numbers and labels are unchanged. Used by
     dartbot.html and x01.js (game.html). */
  .player-card .pc-stats {
    gap: 14px !important;
    margin-bottom: 12px !important;
    padding: 6px 0 !important;
    border-top: 1px solid rgba(18,21,23,0.06) !important;
    border-bottom: 1px solid rgba(18,21,23,0.06) !important;
  }
  .player-card .stat-box {
    background: transparent !important;
    border: none !important;
    border-radius: 0 !important;
    padding: 4px 0 !important;
  }


  /* ─── v5.6 teams.html / profile.html polish ─────────────────────────────
     The blanket .page padding:0 above strips edge gutters — fine for
     dashboard (its .col-right child has its own padding) but breaks
     teams.html and profile.html where headings clip at the viewport edge.
     Scope the gutter restoration to pages that have a .page-header or
     .profile-hero so dashboard stays untouched.
     Also: the page-header was a row layout with a small purple button;
     on mobile we stack it vertically and promote the button to a clear
     full-width primary CTA. The Join a League card is similarly broken
     into a stacked layout with full-width controls.
     ──────────────────────────────────────────────────────────────────── */

  .page:has(.page-header),
  .page:has(.profile-hero) {
    padding: 16px 16px 32px !important;
  }

  /* Page header: stack vertically so the button gets its own row. */
  .page-header {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 14px !important;
  }
  .page-header .page-title {
    font-size: 40px !important;
    letter-spacing: 1px !important;
  }
  .page-header #newTeamBtn,
  .page-header .btn.btn-purple {
    width: 100% !important;
    background: linear-gradient(135deg, #99231a 0%, #701812 100%) !important;
    border: none !important;
    color: #ffffff !important;
    box-shadow: 0 4px 14px rgba(153,35,26,0.30) !important;
    padding: 12px 18px !important;
    font-weight: 700 !important;
  }
  .page-header #newTeamBtn:hover,
  .page-header .btn.btn-purple:hover {
    background: linear-gradient(135deg, #99231a 0%, #701812 100%) !important;
    transform: translateY(-1px) !important;
  }

  /* Join a League card — stack vertically with full-width controls. */
  .join-league-box {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 14px !important;
    padding: 16px !important;
  }
  .jlb-right {
    display: grid !important;
    grid-template-columns: 1fr 1fr !important;
    gap: 8px !important;
  }
  .jlb-right select,
  .jlb-right input {
    width: 100% !important;
    min-width: 0 !important;
    padding: 11px 12px !important;
    font-size: 14px !important;
  }
  .jlb-right .btn {
    grid-column: 1 / -1 !important;
    width: 100% !important;
    padding: 12px !important;
  }


  /* ─── v5.6 profile.html rework ────────────────────────────────────────
     Three changes:
       (a) QR section: center the QR + condense copy + re-order so the
           code label and copy button sit naturally below the heading.
           Was: QR aligned left, text+code+button stacked below it.
           Now: card-style — QR centered, heading + sub centered, code
           label, then a pill-shaped Copy link button.
       (b) Plan-card "Pro adds" pattern: locked features moved out of the
           main list into a soft "Pro adds" section below a dashed
           separator. Reads as "available with upgrade" rather than the
           current red-X "rejected" feel.
       (c) More vertical breathing room between top-level profile sections.
     ──────────────────────────────────────────────────────────────────── */

  /* (a) QR section centered card */
  .qr-section {
    flex-direction: column !important;
    align-items: center !important;
    text-align: center !important;
    gap: 14px !important;
    padding: 22px !important;
  }
  .qr-canvas-wrap {
    width: 140px !important;
    height: 140px !important;
    padding: 10px !important;
  }
  .qr-info {
    flex: 0 0 auto !important;
    min-width: 0 !important;
  }
  .qr-info-sub {
    max-width: 260px !important;
    margin: 0 auto !important;
  }
  .qr-code-label {
    margin-top: 4px !important;
  }
  .qr-copy-btn {
    margin-top: 4px !important;
    padding: 9px 22px !important;
    border-radius: 999px !important;
  }

  /* (b) "Pro adds" sub-section inside FREEPLAY plan card */
  .plan-card .pro-only-section {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px dashed rgba(18,21,23,0.08);
  }
  .plan-card .pro-only-label {
    font-size: 10px;
    letter-spacing: 1.5px;
    color: var(--purple-2);
    text-transform: uppercase;
    font-weight: 800;
    margin-bottom: 8px;
  }
  .plan-card .pro-only-features {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 0;
    margin: 0;
  }
  .plan-card .pro-only-features li {
    font-size: 12px;
    color: var(--text-3);
    padding-left: 22px;
    position: relative;
  }
  .plan-card .pro-only-features li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 4px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    border: 1px dashed rgba(153,35,26,0.4);
  }

  /* (c) Section breathing room — direct .page > div children get a real
        gap between major sections (Subscription / Stats / Account / etc). */
  .page:has(.profile-hero) > div + div {
    margin-top: 28px !important;
  }


  /* ─── v5.6 my-moderation.html top-bar ──────────────────────────────────
     The page has a custom .top-bar (not the standard topbar) with an h1
     and a back button side-by-side via flex space-between. On mobile the
     heading "MY MODERATION" wraps awkwardly into the floating EN pill on
     the right. Stack vertically and reserve right-padding so the heading
     doesn't run under the pill.
     This pattern is also used by some admin pages — scope to body:has(.wrap)
     which is unique to these utility pages.
     ──────────────────────────────────────────────────────────────────── */
  body:has(.wrap) .top-bar {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 12px !important;
    padding-right: 80px !important;
  }
  body:has(.wrap) .top-bar h1 {
    font-size: 28px !important;
    letter-spacing: 1px !important;
    line-height: 1.05 !important;
  }
  body:has(.wrap) .top-bar .btn {
    width: auto !important;
    align-self: flex-start !important;
    padding: 8px 14px !important;
    font-size: 13px !important;
  }

  /* Toasts on .wrap utility pages (admin-disputes, admin-misconduct) sit
     at top-right, colliding with the floating lang pill. Move to bottom
     on mobile — also more conventional for mobile toast UX (thumb-zone). */
  body:has(.wrap) .toast {
    top: auto !important;
    right: 16px !important;
    left: 16px !important;
    bottom: 20px !important;
    transform: translateY(20px) !important;
  }
  body:has(.wrap) .toast.show {
    transform: translateY(0) !important;
  }


  /* ─── v5.6 Darts-used selector (dartbot/icon-match scoring view) ─────
     The "Darts used: [1] [2] [3]" row was visually subordinate on mobile —
     12px muted label + small pills crammed alongside the Submit button.
     Treat the label as a real section header (uppercase, bolder, higher
     contrast) and let the segment buttons flex to fill the row so the
     tap targets are properly sized and the whole row reads as deliberate.
     ──────────────────────────────────────────────────────────────────── */
  .dart-selector {
    gap: 12px !important;
    margin-bottom: 12px !important;
    padding: 10px 0 !important;
    border-top: 1px solid rgba(18,21,23,0.06) !important;
  }
  .ds-label {
    font-size: 11px !important;
    font-weight: 800 !important;
    letter-spacing: 1px !important;
    text-transform: uppercase !important;
    color: rgba(18,21,23,0.65) !important;
  }
  .dart-selector .seg-group {
    gap: 8px !important;
    flex: 1 !important;
  }
  .dart-selector .seg-btn {
    flex: 1 !important;
    min-width: 0 !important;
    padding: 10px 0 !important;
    font-size: 16px !important;
    font-weight: 700 !important;
  }


  /* ─── v5.6 index.html (marketing landing) mobile polish ──────────────
     Five distinct issues:
       (a) Hero stats stack 1-up at <900px wasting tons of vertical space.
           Restore 3-up at mobile width — each gets ~110px which is plenty.
       (b) Steps 01/02/03 render as a cramped 3-column flex (the HTML
           doesn't use the .step-content wrapper the CSS expects). Fix:
           turn the flex into a 2-column grid that actually fits.
       (c) Game modes (.mode-pill) have NO CSS at all in production, so
           they render as plain stacked unstyled divs. Add wrapping pill
           grid + chip styling.
       (d) Final CTA buttons inside .callout-actions need full width so
           "Start 30-day free trial" doesn't wrap awkwardly.
       (e) Section padding (100px top/bottom) is too much on mobile.
     ──────────────────────────────────────────────────────────────────── */

  /* (a) Hero stats — restore 3-up grid */
  .hero-stats-3 {
    grid-template-columns: repeat(3, 1fr) !important;
    margin-top: 36px !important;
    max-width: 100% !important;
  }
  .hero-stats-3 .hero-stat {
    padding: 16px 6px !important;
  }
  .hero-stats-3 .hero-stat-num {
    font-size: 26px !important;
    letter-spacing: 1px !important;
  }
  .hero-stats-3 .hero-stat-label {
    font-size: 9px !important;
    letter-spacing: 0.4px !important;
    margin-top: 4px !important;
    line-height: 1.2 !important;
  }

  /* (b) Steps — 2-column grid: number on left, title + description stacked
        on the right. Currently the flex layout produces a cramped 3-col. */
  .step {
    display: grid !important;
    grid-template-columns: 60px 1fr !important;
    grid-template-rows: auto auto !important;
    gap: 8px 16px !important;
    padding: 28px 0 !important;
  }
  .step .step-num {
    grid-row: 1 / span 2 !important;
    align-self: start !important;
    font-size: 48px !important;
    width: auto !important;
  }
  .step h3 {
    grid-column: 2 !important;
    margin: 0 !important;
    font-size: 18px !important;
    font-weight: 800 !important;
    line-height: 1.2 !important;
  }
  .step p {
    grid-column: 2 !important;
    margin: 0 !important;
    font-size: 14px !important;
    line-height: 1.55 !important;
    color: var(--text-2) !important;
  }

  /* (c) Game modes — add the missing grid + pill chip styles */
  .modes-grid {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
    justify-content: center !important;
    margin-top: 28px !important;
  }
  .mode-pill {
    display: inline-flex !important;
    align-items: center !important;
    padding: 8px 14px !important;
    font-size: 13px !important;
    font-weight: 600 !important;
    background: rgba(18,21,23,0.05) !important;
    border: 1px solid rgba(18,21,23,0.10) !important;
    border-radius: 999px !important;
    color: var(--text-2) !important;
    transition: all .15s !important;
  }
  .mode-pill:hover {
    background: rgba(153,35,26,0.12) !important;
    border-color: rgba(153,35,26,0.35) !important;
    color: var(--text) !important;
  }

  /* (d) Final CTA card — buttons too narrow when wrapped. Stretch them. */
  .callout-actions {
    flex-direction: column !important;
    width: 100% !important;
    gap: 10px !important;
  }
  .callout-actions a,
  .callout-actions .btn {
    width: 100% !important;
    text-align: center !important;
    white-space: nowrap !important;
  }

  /* (e) Section padding — 100px top/bottom is too much on mobile */
  section {
    padding: 56px 0 !important;
  }


  /* ─── v5.6 autoscorer.html topbar ────────────────────────────────────
     The .topbar-divider + .topbar-title ("AUTOSCORER") combo runs out of
     room next to the live-chip and floating EN pill. Hide the secondary
     title on mobile — the user navigates via back button + URL, so the
     title is redundant. Promote the live-chip to a small pill so the
     "No camera" / "Live" status reads as a status indicator.
     ──────────────────────────────────────────────────────────────────── */
  .topbar .topbar-divider,
  .topbar .topbar-title {
    display: none !important;
  }
  .topbar .live-chip {
    font-size: 10px !important;
    padding: 4px 8px !important;
    background: rgba(18,21,23,0.04) !important;
    border-radius: 999px !important;
  }


  /* ─── v5.6 legal pages (privacy / terms / refund) ────────────────────
     The shared .legal-body sets `padding: 24px 0 96px` which overrides
     .page-container's horizontal `0 24px` gutters, so body text runs
     right to the viewport edge on mobile. Restore horizontal padding.
     ──────────────────────────────────────────────────────────────────── */
  .page-container.legal-body {
    padding-left: 16px !important;
    padding-right: 16px !important;
  }


  /* ─── v5.6 match-view.html header ────────────────────────────────────
     The .hdr is flex space-between with a back button + status text.
     On mobile the button gets squeezed by the floating lang pill and
     wraps onto two lines. Stack vertically and reserve right-padding
     for the pill.
     ──────────────────────────────────────────────────────────────────── */
  body:has(.hdr) .hdr {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 8px !important;
    padding-right: 80px !important;
  }
  body:has(.hdr) .hdr .back {
    align-self: flex-start !important;
    white-space: nowrap !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     7. DASHBOARD HERO + MAIN TILES
     The dashboard's "WELCOME BACK" hero and the new mt-* tile system.
     Goal: feel native, not like a desktop site shrunk down.
     ════════════════════════════════════════════════════════════════════ */

  /* Dashboard welcome hero — tighten and remove dead space */
  .col-right .hero {
    padding: 8px 0 4px !important;
    margin-bottom: 4px !important;
  }
  .col-right .hero .hero-label {
    font-size: 10px !important;
    letter-spacing: 2.5px !important;
    margin-bottom: 6px !important;
  }
  .col-right .hero h1 {
    font-size: 40px !important;
    letter-spacing: 1.5px !important;
    line-height: 1 !important;
  }
  .col-right .hero p {
    font-size: 13px !important;
    margin-top: 4px !important;
  }

  /* Main tiles — these are the dashboard's primary nav. Override the
     dashboard's @media (max-width: 720px) so we get cleaner sizing. */
  .main-tiles { gap: 14px !important; }

  .mt-hero-row {
    grid-template-columns: 1fr 1fr !important;
    gap: 12px !important;
  }
  .mt-hero {
    padding: 22px 16px !important;
    border-radius: 18px !important;
    min-height: 150px !important;
  }
  .mt-hero .mt-mark {
    width: 32px !important;
    height: 32px !important;
    font-size: 13px !important;
    margin-bottom: 12px !important;
  }
  .mt-hero .mt-title {
    font-size: 24px !important;
    line-height: 0.95 !important;
    letter-spacing: 1px !important;
    margin-bottom: 6px !important;
  }
  .mt-hero .mt-sub {
    font-size: 11px !important;
    line-height: 1.35 !important;
    opacity: 0.85 !important;
  }

  .mt-wide {
    padding: 16px 14px !important;
    border-radius: 16px !important;
    gap: 14px !important;
  }
  .mt-wide .mtw-art {
    width: 44px !important;
    height: 44px !important;
    font-size: 13px !important;
    flex-shrink: 0 !important;
  }
  .mt-wide .mtw-title {
    font-size: 18px !important;
    letter-spacing: 1px !important;
  }
  .mt-wide .mtw-sub {
    font-size: 12px !important;
    margin-top: 2px !important;
  }
  .mt-wide .mtw-arrow { font-size: 22px !important; }

  .mt-slim {
    padding: 12px 14px !important;
    border-radius: 14px !important;
    gap: 12px !important;
  }
  .mt-slim .mts-icon {
    width: 36px !important;
    height: 36px !important;
    font-size: 11px !important;
    flex-shrink: 0 !important;
  }
  .mt-slim .mts-title {
    font-size: 15px !important;
  }

  .mt-extras {
    grid-template-columns: repeat(4, 1fr) !important;
    gap: 8px !important;
  }
  .mt-ex {
    padding: 12px 6px !important;
    border-radius: 12px !important;
  }
  .mt-ex .mte-icon {
    width: 36px !important;
    height: 36px !important;
    font-size: 11px !important;
    margin-bottom: 6px !important;
  }
  .mt-ex .mte-label {
    font-size: 10px !important;
    letter-spacing: 0.4px !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     8. DASHBOARD SECONDARY CARDS
     mode-grid (legacy), league-grid, stat-grid, recent matches, etc.
     ════════════════════════════════════════════════════════════════════ */

  /* Legacy mode-grid — single column with proper card padding */
  .mode-grid {
    flex-direction: column !important;
    flex-wrap: nowrap !important;
    grid-template-columns: 1fr !important;
    gap: 10px !important;
  }
  .mode-grid .mode-card {
    flex: 0 0 auto !important;
    min-width: 0 !important;
    width: 100% !important;
    padding: 16px !important;
    border-radius: 14px !important;
  }
  .mode-card .mc-title { font-size: 16px !important; white-space: nowrap !important; }
  .mode-card .mc-sub   { font-size: 12px !important; }
  .mode-card .mc-desc  { font-size: 12.5px !important; line-height: 1.5 !important; }

  /* League grid - single column with breathing room */
  .league-grid {
    grid-template-columns: 1fr !important;
    gap: 10px !important;
  }
  .league-card {
    padding: 14px !important;
    border-radius: 14px !important;
  }

  /* Stat tiles - 2x2 instead of 4-wide cramped row */
  .stat-grid {
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 10px !important;
  }
  .stat-tile {
    padding: 16px 14px !important;
    border-radius: 14px !important;
  }
  .stat-tile-val {
    font-size: 26px !important;
    line-height: 1 !important;
  }
  .stat-tile-lbl {
    font-size: 11px !important;
    letter-spacing: 0.5px !important;
    margin-top: 4px !important;
  }

  /* Section headers */
  .section-header, .dash-section-header {
    margin-bottom: 12px !important;
    gap: 10px !important;
  }
  .section-header h2,
  .dash-section-header h2 {
    font-size: 22px !important;
    letter-spacing: 1px !important;
  }

  /* Recent / mini match rows */
  .mini-match-row, .match-card {
    padding: 12px 14px !important;
    border-radius: 12px !important;
  }
  .mm-info, .match-info { min-width: 0 !important; }
  .mm-vs, .match-vs {
    font-size: 14px !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
  }
  .mm-sub, .match-meta {
    font-size: 11px !important;
  }

  /* Standings rows */
  .standings-row {
    padding: 10px 12px !important;
    gap: 10px !important;
  }
  .sr-pos {
    font-size: 13px !important;
    width: 24px !important;
  }
  .sr-name { font-size: 14px !important; }
  .sr-stat { font-size: 13px !important; }

  /* Scoreboard wrap (live-match preview area) */
  .scoreboard-wrap {
    padding: 14px !important;
    border-radius: 14px !important;
  }
  .sb-filters, .sb-mode-btn, .sb-filter-btn {
    font-size: 12px !important;
    padding: 7px 10px !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     9. AUTH SCREENS — login.html / register.html / reset_password.html
     The big visual change: a "WELCOME TO THROW DARTS" headline
     becomes the hero of the mobile auth screen, replacing the small
     "Sign in" / "Create your account" form titles. Desktop is unchanged.
     ════════════════════════════════════════════════════════════════════ */

  /* Hide the desktop side panels */
  .auth-wrap, .auth-grid, .auth-page, .login-grid, .form-page-grid {
    display: block !important;
    grid-template-columns: none !important;
    min-height: auto !important;
  }
  .auth-side, .auth-hero, .login-hero, .form-hero, .col-left, .left-panel {
    display: none !important;
  }

  /* Right panel becomes full-bleed. Lifted dark navy base with stronger
     ambient brand-colour glows (purple top, blue bottom) so the screen
     reads as proper "dark mode," not "lights off." */
  .right-panel {
    width: 100% !important;
    max-width: 100% !important;
    min-height: 100vh !important;
    padding: 28px 22px 40px !important;
    background:
      radial-gradient(ellipse 90% 60% at 50% 0%, rgba(153,35,26,0.18), transparent 65%),
      radial-gradient(ellipse 80% 55% at 50% 100%, rgba(153,35,26,0.14), transparent 65%),
      #f2efe8 !important;
    align-items: stretch !important;
    justify-content: flex-start !important;
  }

  /* Form wrap: more breathing room, no horizontal cramp */
  .auth-form, .auth-card, .form-wrap, .login-form {
    width: 100% !important;
    max-width: 100% !important;
    padding: 0 !important;
    border: none !important;
    border-radius: 0 !important;
  }

  /* Mobile logo: keep it visible but smaller and tighter to the top */
  .mobile-logo {
    margin-bottom: 28px !important;
  }
  .mobile-logo-mark {
    width: 36px !important;
    height: 36px !important;
    font-size: 18px !important;
    border-radius: 10px !important;
  }
  .mobile-logo-text {
    font-size: 20px !important;
    letter-spacing: 3px !important;
  }

  /* === The mobile-only welcome heading. ====================================
     This block lives in login.html and register.html (.mobile-welcome).
     On desktop it's display:none (set in the page's inline styles); here
     on mobile we show it and style it as the new auth-screen hero.
     ========================================================================= */
  .mobile-welcome {
    display: block !important;
    margin: 4px 0 28px !important;
    animation: mwFadeUp .5s ease both;
  }
  .mw-eyebrow {
    font-size: 11px !important;
    font-weight: 700 !important;
    letter-spacing: 3px !important;
    text-transform: uppercase !important;
    color: rgba(18,21,23,0.55) !important;
    margin-bottom: 8px !important;
  }
  .mw-heading {
    font-family: 'Bebas Neue', sans-serif !important;
    font-size: 44px !important;
    line-height: 1 !important;
    letter-spacing: 1.5px !important;
    color: #ffffff !important;
    margin: 0 0 14px !important;
    font-weight: 400 !important;
    white-space: nowrap !important;
  }
  /* Keep <span> in markup for future gradient/color tweaks; for now,
     "DARTS" stays white to match the user's "in white" requirement. */
  .mw-heading span {
    color: #ffffff !important;
  }
  .mw-sub {
    font-size: 14px !important;
    line-height: 1.55 !important;
    color: rgba(18,21,23,0.6) !important;
    font-weight: 300 !important;
    max-width: 320px !important;
    margin: 0 0 4px !important;
  }
  @keyframes mwFadeUp {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
  }

  /* With the mobile-welcome above, the small "Sign in" / "Create your
     account" form-title becomes redundant — the welcome heading IS the
     title now. Hide it on mobile entirely. The submit button already
     says "Sign in" / "Create account" which makes the action clear. */
  .form-title {
    display: none !important;
  }
  .form-sub {
    font-size: 13px !important;
    margin-bottom: 24px !important;
  }

  /* Field spacing: more vertical rhythm, with input bgs pitched bright
     enough to be properly visible against the lifted dark navy.
     Color overrides scoped to dark theme only — light theme keeps its
     own rules from the page-level CSS. */
  .field {
    margin-bottom: 14px !important;
  }
  .field label {
    font-size: 11px !important;
    letter-spacing: 1px !important;
    margin-bottom: 6px !important;
  }
  :root:not([data-theme="light"]) .field label,
  [data-theme="dark"] .field label {
    color: rgba(18,21,23,0.7) !important;
  }
  .field input,
  .field select,
  .field textarea {
    border-radius: 12px !important;
  }
  :root:not([data-theme="light"]) .field input,
  :root:not([data-theme="light"]) .field select,
  :root:not([data-theme="light"]) .field textarea,
  [data-theme="dark"] .field input,
  [data-theme="dark"] .field select,
  [data-theme="dark"] .field textarea {
    background: rgba(18,21,23,0.12) !important;
    border-color: rgba(18,21,23,0.22) !important;
    color: #ffffff !important;
  }
  :root:not([data-theme="light"]) .field input::placeholder,
  :root:not([data-theme="light"]) .field textarea::placeholder,
  [data-theme="dark"] .field input::placeholder,
  [data-theme="dark"] .field textarea::placeholder {
    color: rgba(18,21,23,0.4) !important;
  }

  /* Field rows (e.g. Display Name + Username on register) — stack on
     phones; the desktop two-column squeeze is too tight. */
  .field-row {
    grid-template-columns: 1fr !important;
    flex-direction: column !important;
    gap: 0 !important;
    display: flex !important;
  }

  /* Submit button: full-width gradient block */
  .btn-submit {
    width: 100% !important;
    padding: 15px 20px !important;
    font-size: 15px !important;
    font-weight: 700 !important;
    border-radius: 12px !important;
    margin-top: 6px !important;
    letter-spacing: 0.5px !important;
  }

  /* Helper links beneath the Sign-in button. On desktop "Create account"
     is hidden (the "No account? Create one free" line above the form
     covers that affordance). On mobile we hide the line above the form
     instead, and show "Create account" + "Forgot password?" on a single
     row beneath the Sign-in button — both styled identically in purple,
     spaced down 30px per design feedback. */
  .form-sub { display: none !important; }

  .auth-below-submit {
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    margin-top: 30px !important;
    gap: 10px !important;
    flex-wrap: wrap !important;
  }
  .auth-create-link,
  .auth-forgot-link {
    display: inline-flex !important;
    color: var(--purple-2) !important;
    background: none !important;
    border: none !important;
    font-family: var(--font-body) !important;
    font-size: 13px !important;
    font-weight: 600 !important;
    padding: 0 !important;
    text-decoration: none !important;
    cursor: pointer !important;
    white-space: nowrap !important;
    min-height: auto !important;     /* override section 1's 44px tap target */
  }

  /* Hide the Facebook OAuth button on mobile — Google only. */
  .oauth-btn-facebook { display: none !important; }

  /* Forgot-password panel */
  .forgot-panel {
    border-radius: 14px !important;
    padding: 16px !important;
    margin-top: 14px !important;
  }
  .forgot-row {
    flex-direction: column !important;
    gap: 10px !important;
  }
  .forgot-row input,
  .forgot-row .btn-forgot-send {
    width: 100% !important;
  }

  /* Footer back-link — hidden on mobile per design feedback. The link
     still ships in the markup so desktop renders it, but on phones the
     visited-from-homepage breadcrumb felt redundant once the welcome
     heading became the page hero. Keep the rule above so future devs
     can flip it back with one line. */
  .form-footer {
    display: none !important;
  }

  /* Plan picker on register (free / league) — keep side-by-side but
     make the cards taller and the type clearer. */
  .oauth-plan-name { font-size: 13px !important; }
  .oauth-plan-desc { font-size: 11px !important; line-height: 1.4 !important; }


  /* ─── v5.6 Auth polish ──────────────────────────────────────────────────
     Refinements to the login / register / reset_password flow:
       a) Floating language picker: force compact mode on auth pages so the
          pill (which sits in the top-right with no topbar to anchor it)
          stops competing with the WELCOME hero. Light-theme switches from
          opaque white to translucent glass for the same reason.
       b) Vertically centre the form column so the page reads as a
          composed hero rather than top-anchored copy with a dead zone
          below. The .right-panel was already min-height:100vh; we just
          flip its justify-content.
       c) Crisper input chrome — slightly darker fill, clearer 1px border,
          a focus ring in brand purple. Placeholder bumped to AA contrast.
       d) Tighten the helper-link row (Create account / Forgot password?)
          and restore a real 44px tap target via invisible padding/margin.
     ──────────────────────────────────────────────────────────────────── */

  /* (a) Floating lang picker → always compact on mobile */
  .treblo-lang-switcher.is-floating .treblo-lang-current { display: none !important; }
  .treblo-lang-switcher.is-floating .treblo-lang-code    { display: inline !important; }
  .treblo-lang-switcher.is-floating .treblo-lang-btn {
    height: 36px !important;
    padding: 0 10px !important;
    font-size: 12px !important;
    gap: 6px !important;
  }
  /* Light-theme floating pill: translucent glass, not opaque white. */
  [data-theme="light"] .treblo-lang-switcher.is-floating .treblo-lang-btn {
    background: rgba(18,21,23,0.85) !important;
    backdrop-filter: blur(8px) !important;
    -webkit-backdrop-filter: blur(8px) !important;
  }

  /* (b) Vertically centre the auth form column */
  .right-panel {
    justify-content: center !important;
    padding-top: 20px !important;
    padding-bottom: 20px !important;
  }
  .auth-form, .auth-card, .form-wrap, .login-form {
    margin: auto 0 !important;
  }

  /* (c) Crisper input chrome — dark theme styling. Light theme keeps
        its own page-level rules. */
  :root:not([data-theme="light"]) .field input,
  :root:not([data-theme="light"]) .field select,
  :root:not([data-theme="light"]) .field textarea,
  [data-theme="dark"] .field input,
  [data-theme="dark"] .field select,
  [data-theme="dark"] .field textarea {
    background: rgba(18,21,23,0.07) !important;
    border: 1px solid rgba(18,21,23,0.18) !important;
  }
  .field input,
  .field select,
  .field textarea {
    border-radius: 12px !important;
  }
  :root:not([data-theme="light"]) .field input::placeholder,
  :root:not([data-theme="light"]) .field textarea::placeholder,
  [data-theme="dark"] .field input::placeholder,
  [data-theme="dark"] .field textarea::placeholder {
    color: rgba(18,21,23,0.45) !important;
  }
  :root:not([data-theme="light"]) .field input:focus,
  :root:not([data-theme="light"]) .field textarea:focus,
  :root:not([data-theme="light"]) .field select:focus,
  [data-theme="dark"] .field input:focus,
  [data-theme="dark"] .field textarea:focus,
  [data-theme="dark"] .field select:focus {
    border-color: rgba(153,35,26,0.55) !important;
    background: rgba(18,21,23,0.10) !important;
    outline: none !important;
  }

  /* (d) Tighter helper-link row + restored tap targets */
  .auth-below-submit {
    margin-top: 18px !important;
  }
  .auth-create-link,
  .auth-forgot-link {
    /* Invisible padding gives 44px tap height without changing visual weight */
    padding: 12px 4px !important;
    margin: -12px -4px !important;
    color: rgba(153,35,26,0.85) !important;
  }
  .auth-create-link:active,
  .auth-forgot-link:active {
    color: var(--purple-2) !important;
  }


  /* ─── v5.6 reset_password polish ────────────────────────────────────────
     reset_password.html is a standalone page that doesn't use the .right-panel
     auth shell — it has its own .auth-shell + .card markup with page-local
     CSS. None of the section-9 rules above reach it, so we mirror the same
     visual polish here. Three states share this skin: form, invalid, success.
     ──────────────────────────────────────────────────────────────────── */

  /* Drop the bordered/rounded card chrome on mobile so the form sits
     directly on the page background, matching login/register. */
  .auth-shell .card {
    max-width: 100% !important;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    padding: 24px 22px !important;
  }
  .auth-shell {
    padding: 24px 0 !important;
  }

  /* Hide the marketing footer on this utility flow page. login/register
     use .form-footer; reset_password renders the full site <footer> which
     a different rule misses. */
  body > footer.site-footer,
  body > footer {
    display: none !important;
  }

  /* The page-local .field markup overrides mobile.css's .field rules,
     so re-apply the auth-shell input chrome here. */
  .auth-shell .field {
    margin-bottom: 14px !important;
  }
  .auth-shell .field label {
    display: block !important;
    font-size: 11px !important;
    font-weight: 700 !important;
    letter-spacing: 1px !important;
    text-transform: uppercase !important;
    color: rgba(18,21,23,0.7) !important;
    margin: 0 0 6px !important;
  }
  .auth-shell .field input {
    background: rgba(18,21,23,0.07) !important;
    border: 1px solid rgba(18,21,23,0.18) !important;
    border-radius: 12px !important;
    color: #fff !important;
    height: 48px !important;
    padding: 0 44px 0 14px !important;
    font-size: 15px !important;
  }
  .auth-shell .field input::placeholder {
    color: rgba(18,21,23,0.45) !important;
  }
  .auth-shell .field input:focus {
    border-color: rgba(153,35,26,0.55) !important;
    background: rgba(18,21,23,0.10) !important;
    outline: none !important;
  }

  /* Heading + subcopy */
  .auth-shell h1 {
    font-size: 24px !important;
    margin: 12px 0 6px !important;
    color: #fff !important;
  }
  .auth-shell .sub {
    font-size: 14px !important;
    color: rgba(18,21,23,0.6) !important;
    margin: 0 0 18px !important;
    line-height: 1.5 !important;
  }

  /* Submit — full-width gradient block matching the rest of the auth flow */
  .auth-shell .btn {
    width: 100% !important;
    padding: 15px 20px !important;
    font-size: 15px !important;
    font-weight: 700 !important;
    border-radius: 12px !important;
    margin-top: 8px !important;
  }

  /* Invalid / success states — centred, with clear typographic hierarchy */
  .auth-shell .invalid-state,
  .auth-shell .success-state {
    text-align: center !important;
  }
  .auth-shell .invalid-title,
  .auth-shell .success-title {
    font-size: 20px !important;
    margin-bottom: 8px !important;
    color: #fff !important;
  }
  .auth-shell .invalid-sub,
  .auth-shell .success-sub {
    font-size: 14px !important;
    color: rgba(18,21,23,0.6) !important;
    line-height: 1.55 !important;
    margin-bottom: 18px !important;
  }


  /* ─── v5.6 Dashboard / signed-in app shell polish ──────────────────────
     Three areas:
       (a) Topbar sign-out demoted to a quiet muted text link so the topbar
           reads as logo + bell + lang + avatar, with sign-out present but
           not fighting for attention.
       (b) Hero name (the "ANTRO" / first-name span inside .hero h1) was
           rendering as a low-contrast gradient on the dark navy bg — we
           replace it with solid white + a subtle purple glow so it stays
           identifiable without disappearing into the background.
       (c) The big marketing footer (Product / Support / Legal) is wrong
           on signed-in app pages — the user's already in the app. We
           collapse it to a quiet legal-links-only row. The :has(.topbar)
           selector targets only signed-in pages (auth pages have no
           .topbar), so login/register are unaffected.
     The notification-bell.js empty-icon bug is fixed alongside this in
     the JS file (separate change).
     ──────────────────────────────────────────────────────────────────── */

  /* (a) Topbar sign-out → tiny muted text link */
  .topbar-signout, .topbar-logout {
    font-size: 11px !important;
    font-weight: 500 !important;
    letter-spacing: 0.3px !important;
    padding: 6px 4px !important;
    border: none !important;
    background: transparent !important;
    color: rgba(18,21,23,0.5) !important;
    border-radius: 6px !important;
    /* Negative margin restores invisible 44px tap area. */
    margin: -6px 0 -6px 4px !important;
  }
  .topbar-signout:hover, .topbar-logout:hover,
  .topbar-signout:active, .topbar-logout:active {
    color: rgba(18,21,23,0.85) !important;
    background: transparent !important;
    border-color: transparent !important;
  }
  /* Light-theme overrides — the 50% white above is invisible on the
     light topbar. Use a dark muted tone instead. */
  [data-theme="light"] .topbar-signout,
  [data-theme="light"] .topbar-logout {
    color: rgba(18,21,23,0.175) !important;
  }
  [data-theme="light"] .topbar-signout:hover,
  [data-theme="light"] .topbar-logout:hover,
  [data-theme="light"] .topbar-signout:active,
  [data-theme="light"] .topbar-logout:active {
    color: rgba(0,0,0,0.85) !important;
  }

  /* (b) Brighten/simplify the WELCOME [name] hero. Gradient text on dark
        navy reads as low-contrast because the gradient's mid-stops merge
        into the bg. Solid white + purple glow keeps the brand vibe.
        Light-theme override below — dark navy on light bg. */
  :root:not([data-theme="light"]) .col-right .hero h1 span,
  :root:not([data-theme="light"]) .hero h1 span,
  [data-theme="dark"] .col-right .hero h1 span,
  [data-theme="dark"] .hero h1 span {
    background: none !important;
    -webkit-text-fill-color: #ffffff !important;
    color: #ffffff !important;
    text-shadow: 0 0 24px rgba(153,35,26,0.18) !important;
  }
  [data-theme="light"] .col-right .hero h1 span,
  [data-theme="light"] .hero h1 span {
    background: none !important;
    -webkit-text-fill-color: var(--text) !important;
    color: var(--text) !important;
    text-shadow: 0 0 24px rgba(153,35,26,0.10) !important;
  }

  /* (c) Strip the marketing footer down on signed-in pages. body:has(.topbar)
        scopes this to in-app pages — auth pages (login/register/reset) have
        no .topbar so they're unaffected. */
  body:has(.topbar) > footer.home-footer,
  body:has(.topbar) > footer.site-footer,
  body:has(header.topbar) ~ footer:not(.app-footer) {
    /* fall through to the strip-down rules below; explicit hide for any
       footer that doesn't get touched by them. */
  }
  body:has(.topbar) > footer .footer-rich-grid > *:not(.footer-rich-legal) {
    display: none !important;
  }
  body:has(.topbar) > footer {
    padding: 16px 22px 24px !important;
    border-top: 1px solid rgba(18,21,23,0.06) !important;
    margin-top: 24px !important;
  }
  body:has(.topbar) > footer .footer-rich-bottom {
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 4px !important;
    font-size: 11px !important;
    color: rgba(18,21,23,0.4) !important;
  }
  body:has(.topbar) > footer .footer-col-links {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 12px !important;
    font-size: 11px !important;
  }
  body:has(.topbar) > footer .footer-col-links a {
    color: rgba(18,21,23,0.5) !important;
    text-decoration: none !important;
  }
  body:has(.topbar) > footer .footer-col-heading {
    display: none !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     10. PILL ROWS / CHIP ROWS / OPTION ROWS
     301/501/701/1001, race-to / best-of, filter chips, etc.
     ════════════════════════════════════════════════════════════════════ */

  .pill-row, .chip-row, .opt-row, .lb-filter-group,
  .game-setup .row, .start-from, .best-of {
    flex-wrap: wrap !important;
    gap: 6px !important;
  }
  .pill-row > *, .chip-row > *, .opt-row > * {
    flex: 0 1 auto !important;
    min-height: 40px !important;
    padding: 9px 14px !important;
    font-size: 14px !important;
    border-radius: 999px !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     11. NEW / EDIT LEAGUE WIZARD (game.html .nl-panel)
     Two issues addressed:
       (a) The 2-col `.nl-row` (Game Mode + Best Of, Division Name + Label)
           overflows the panel because grid items default to min-width:auto,
           refusing to shrink below their min-content width. The select for
           "Best Of" with options like "5 legs" pushes past the right edge.
           Fix: collapse to a single column, AND set min-width:0 on children
           (belt + braces in case any other 2-col layout creeps in).
       (b) The panel itself is very dark on OLED phones — gradient goes from
           #f2efe8 to #f2efe8. With form fields at rgba(18,21,23,0.06)
           the inputs almost vanish. Lighten the panel and bump field bg.
     ════════════════════════════════════════════════════════════════════ */

  #newLeagueModal,
  #editLeagueModal {
    padding: 12px !important;
    align-items: flex-start !important;
  }

  /* (b) Lighter panel for OLED — properly visible navy, not a black hole.
     Sits clearly above the lifted body background. */
  #newLeagueModal .nl-panel,
  #editLeagueModal .nl-panel {
    width: 100% !important;
    max-width: 100% !important;
    margin-top: 24px !important;
    border-radius: 16px !important;
    background: linear-gradient(160deg, #faf7f0 0%, #faf7f0 100%) !important;
    border: 1px solid rgba(153,35,26,0.4) !important;
  }

  /* Header: brighter purple wash so it's clearly the title bar. */
  #newLeagueModal .nl-header,
  #editLeagueModal .nl-header {
    padding: 14px 16px 12px !important;
    background: rgba(153,35,26,0.14) !important;
  }
  #newLeagueModal .nl-title,
  #editLeagueModal .nl-title { font-size: 18px !important; letter-spacing: 1.5px !important; }

  #newLeagueModal .nl-body,
  #editLeagueModal .nl-body { padding: 16px !important; gap: 12px !important; }

  /* (a) Force every 2-col .nl-row into a single column on mobile.
     Multiple syntaxes for robustness (in case grid OR flex is in play),
     plus min-width:0 on children so nothing overflows. */
  #newLeagueModal .nl-row,
  #editLeagueModal .nl-row {
    display: block !important;
    grid-template-columns: 1fr !important;
    flex-direction: column !important;
    gap: 10px !important;
  }
  #newLeagueModal .nl-row > *,
  #editLeagueModal .nl-row > * {
    width: 100% !important;
    min-width: 0 !important;
    max-width: 100% !important;
    margin-bottom: 10px !important;
  }
  #newLeagueModal .nl-row > *:last-child,
  #editLeagueModal .nl-row > *:last-child {
    margin-bottom: 0 !important;
  }

  /* (b) Properly visible form fields inside the modal — pop against the
     lifted panel, with white text and a clear focus state. */
  #newLeagueModal .nl-field input,
  #newLeagueModal .nl-field select,
  #editLeagueModal .nl-field input,
  #editLeagueModal .nl-field select {
    background: rgba(18,21,23,0.12) !important;
    border: 1px solid rgba(18,21,23,0.22) !important;
    color: #ffffff !important;
    border-radius: 10px !important;
    width: 100% !important;
    max-width: 100% !important;
    box-sizing: border-box !important;
  }
  #newLeagueModal .nl-field input::placeholder,
  #editLeagueModal .nl-field input::placeholder {
    color: rgba(18,21,23,0.35) !important;
  }
  #newLeagueModal .nl-field label,
  #editLeagueModal .nl-field label {
    color: rgba(18,21,23,0.7) !important;
    font-size: 11px !important;
  }

  /* Footer: stack buttons, full-width, comfortable taps. */
  #newLeagueModal .nl-footer,
  #editLeagueModal .nl-footer {
    padding: 12px 16px 14px !important;
    flex-direction: column !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
  }
  #newLeagueModal .nl-submit,
  #newLeagueModal .nl-cancel,
  #editLeagueModal .nl-submit,
  #editLeagueModal .nl-cancel {
    flex: 1 1 auto !important;
    width: 100% !important;
    min-width: 0 !important;
    padding: 13px 14px !important;
    font-size: 14px !important;
    border-radius: 10px !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     12. SIDEBAR ADMIN GROUP (game.html #sbAdminWrap)
     ════════════════════════════════════════════════════════════════════ */

  #mgSidebar #sbAdminWrap .sb-icon svg {
    width: 16px !important;
    height: 16px !important;
    flex-shrink: 0;
  }
  #mgSidebar .sb-admin-danger { color: #d5372a !important; }
  #mgSidebar .sb-admin-danger:hover,
  #mgSidebar .sb-admin-danger:active {
    color: #d5372a !important;
    background: rgba(213,55,42,0.10) !important;
  }
  #mgSidebar .sb-admin-danger .sb-icon {
    background: rgba(213,55,42,0.10) !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     13. LOBBY CREATE-COMPETITION WIZARD
     ════════════════════════════════════════════════════════════════════ */

  .lb-field-row {
    grid-template-columns: 1fr !important;
    flex-direction: column !important;
    gap: 10px !important;
  }
  .lb-field-row > .lb-field { width: 100% !important; }


  /* ════════════════════════════════════════════════════════════════════
     14. OAUTH BUTTONS (Continue with Google / Facebook)
     ════════════════════════════════════════════════════════════════════ */

  .oauth-divider {
    margin: 22px 0 16px !important;
    font-size: 12px !important;
  }
  .oauth-section {
    width: 100% !important;
    gap: 10px !important;
  }
  .oauth-btn-facebook,
  .oauth-btn-google {
    border-radius: 12px !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     15. DRAWERS, MODALS, FRIENDS PANEL
     Make these feel like native bottom-sheets / full-screen overlays.
     ════════════════════════════════════════════════════════════════════ */

  .drawer, .lb-modal, .friends-panel {
    width: 100vw !important;
    max-width: 100vw !important;
    border-radius: 16px 16px 0 0 !important;
  }
  .drawer-header, .fp-header {
    padding: 16px !important;
  }
  .drawer-body, .fp-body {
    padding: 14px 16px !important;
  }
  .drawer-name, .fp-title {
    font-size: 17px !important;
  }
  .drawer-close, .fp-close {
    width: 36px !important;
    height: 36px !important;
    border-radius: 999px !important;
  }
  .drawer-tabs {
    gap: 4px !important;
  }
  .drawer-tab {
    padding: 10px 12px !important;
    font-size: 13px !important;
  }

  /* Generic modal */
  .modal,
  .modal-backdrop > .modal {
    width: calc(100vw - 24px) !important;
    max-width: calc(100vw - 24px) !important;
    border-radius: 16px !important;
    padding: 20px !important;
  }
  .modal-title { font-size: 19px !important; }
  .modal-sub { font-size: 13px !important; }
  .modal-actions {
    flex-direction: column !important;
    gap: 8px !important;
  }
  .modal-actions > * { width: 100% !important; }


  /* ════════════════════════════════════════════════════════════════════
     16. TABLES / LEAGUE TABLE / FIXTURES
     ════════════════════════════════════════════════════════════════════ */

  .league-table, .fixtures-table {
    font-size: 13px !important;
  }
  .league-table th, .league-table td,
  .fixtures-table th, .fixtures-table td {
    padding: 8px 6px !important;
  }


  /* ════════════════════════════════════════════════════════════════════
     17. GAME / SCORING / DARTBOT — light touchups
     The dart-keypad and scoring screens have their own dense layout
     logic; we only tweak the parts that visibly break on mobile.
     ════════════════════════════════════════════════════════════════════ */

  /* Game-mode setup pages — give the wizard step rows breathing room */
  .gm-setup-grid {
    grid-template-columns: 1fr !important;
    gap: 12px !important;
  }
  .gm-step-title {
    font-size: 18px !important;
    letter-spacing: 1px !important;
  }

  /* Match-view header */
  .mv-header {
    padding: 14px !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
  }
  .mv-title { font-size: 18px !important; }


  /* ════════════════════════════════════════════════════════════════════
     CLOSE @media (max-width: 720px)
     ════════════════════════════════════════════════════════════════════ */
}


/* =========================================================================
   18. VERY SMALL PHONES (<= 380px)
   iPhone SE, older Androids. Take an extra notch off everything.
   ========================================================================= */

@media (max-width: 380px) {
  /* In-app top bar */
  .topbar-logo-text { display: none !important; }
  .topbar-signout, .topbar-logout { font-size: 11px !important; padding: 7px 9px !important; }

  /* Homepage hero */
  .hero { padding: 80px 14px 40px !important; }
  .hero-headline { font-size: 46px !important; }
  .hero-desc { font-size: 14px !important; }
  .hero-badge { font-size: 9px !important; padding: 5px 10px !important; }
  .hero-stat-num { font-size: 30px !important; }

  /* Section headings */
  .section-title { font-size: 30px !important; }
  .section-desc { font-size: 14px !important; }

  /* Homepage nav */
  .nav-cta { gap: 6px !important; }
  .btn-nav-login { font-size: 12px !important; padding: 7px 8px !important; }
  .btn-nav-signup { font-size: 12px !important; padding: 8px 11px !important; }
  /* On the tightest phones, drop the Sign-in link from the homepage nav.
     The register page still surfaces a sign-in link. */
  nav .nav-cta .btn-nav-login { display: none !important; }
  nav .treblo-lang-switcher.is-compact .treblo-lang-btn {
    height: 30px !important;
    padding: 0 5px !important;
    font-size: 10px !important;
  }

  /* Dashboard hero */
  .col-right .hero h1 { font-size: 34px !important; }

  /* Main tiles - tighter */
  .mt-hero { padding: 18px 14px !important; min-height: 130px !important; }
  .mt-hero .mt-title { font-size: 22px !important; }
  .mt-hero .mt-sub { font-size: 10.5px !important; }
  .mt-wide { padding: 14px 12px !important; }
  .mt-wide .mtw-title { font-size: 16px !important; }
  .mt-extras { gap: 6px !important; }
  .mt-ex { padding: 10px 4px !important; }
  .mt-ex .mte-icon { width: 32px !important; height: 32px !important; font-size: 10px !important; }
  .mt-ex .mte-label { font-size: 9px !important; }

  /* Mobile welcome on auth pages — scale down so it doesn't crowd */
  .mw-heading { font-size: 38px !important; letter-spacing: 1px !important; }
  .mw-eyebrow { font-size: 10px !important; letter-spacing: 2.5px !important; }
  .mw-sub { font-size: 13px !important; }

  /* Stats */
  .stat-tile-val { font-size: 22px !important; }
  .stat-tile-lbl { font-size: 10px !important; }
}


/* =========================================================================
   ████████████████████████████████████████████████████████████████████████
   v5.7 — MOBILE APP READINESS PASS (2026-05)
   ────────────────────────────────────────────────────────────────────────
   Whole-app additions for phone-as-app form. Loaded on every page via the
   shared <link rel="stylesheet" href="/darts/css/mobile.css">. Convention
   matches the rest of this file: gated on @media (max-width: 720px) so
   desktop is never affected. The very-small-phone tweaks live in the
   existing @media (max-width: 380px) block lower down — search "v5.7" in
   that block too.

   Companion HTML changes (per-page <head> injections) handled separately:
     - <link rel="manifest" href="/site.webmanifest">
     - <meta name="theme-color" content="#f2efe8">
     - <meta name="apple-mobile-web-app-capable" content="yes">
     - <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
     - <meta name="mobile-web-app-capable" content="yes">
     - viewport meta updated to include "viewport-fit=cover" so safe-area
       insets actually resolve to non-zero values on notched devices.
   ████████████████████████████████████████████████████████████████████████
   ========================================================================= */


/* ─── 0. Tap-highlight color removal (global, interactive only)  ──────────
   The grey flash that Android Chrome / WebView paint on tap looks like
   a rendering bug in app form. Turn it off on interactive elements only;
   we have hover/active styles that already convey the tap. We do NOT
   apply this universally because some accessibility setups rely on the
   default highlight to indicate hit-area. */
button, .btn, a, [role="button"], [onclick], summary,
input[type="button"], input[type="submit"], input[type="reset"] {
  -webkit-tap-highlight-color: transparent;
}


@media (max-width: 720px) {

  /* ─── v5.7 — 1. Safe-area insets (notch / gesture bar / home indicator)
     ─────────────────────────────────────────────────────────────────────
     Android gesture-bar phones (Pixel 7+, S22+) and iOS notched devices
     all expose the safe area via env(safe-area-inset-*). For this to
     resolve to non-zero values, the page <meta viewport> must include
     viewport-fit=cover (added per-page in the companion HTML patch).

     We apply bottom-inset padding to two things globally:
       (a) <body> bottom — so the last bit of any scrollable page isn't
           hidden behind the gesture bar.
       (b) Anything position:fixed at the bottom of the viewport (toasts,
           FABs) — so they float ABOVE the gesture bar, not on top of it.   */

  body {
    /* Existing pages already set their own padding/margin; this is
       additive and applies only when the safe-area inset is non-zero. */
    padding-bottom: env(safe-area-inset-bottom, 0);
  }

  /* Common fixed-position bottom UI patterns across the app. The
     selectors are deliberately broad: every page has some variant of
     these (#toast in profile/teams, .toast in admin, .fab in dashboard
     etc.). The calc() preserves whatever bottom offset the page sets. */
  .toast,
  #toast,
  .fab,
  [class*="-toast"],
  [class*="-fab"] {
    /* If the page already declared `bottom: 24px;` we add the safe-area
       on top via the CSS variable trick. We can't compose calc() over
       an unknown existing value, so we reset to a sensible default and
       most page-level rules will override this for x/y positioning;
       what we actually want is to lift the bottom by the inset:        */
    margin-bottom: env(safe-area-inset-bottom, 0) !important;
  }


  /* ─── v5.7 — 2. dvh swaps (visible-viewport sizing)  ──────────────────
     100vh on mobile = the URL-bar-collapsed height, which is taller
     than what the user actually sees while the bar is showing. This
     pushes content below the fold with no way to reach it.

     Swap to 100dvh (dynamic viewport height) which tracks the visible
     area as the URL bar collapses/expands. Browsers without dvh fall
     through to the original 100vh declaration in each page's CSS, so
     this is a pure progressive-enhancement.

     We can't easily target `min-height: calc(100vh - 60px)` from a
     stylesheet without knowing the offset, so we only override the
     plain `min-height: 100vh` cases here, and leave page-specific
     calc() variants to per-page patches. The most common offenders are
     login/register/profile/teams/match-view (full-page hero shells). */
  body[style*="min-height"],
  .auth-shell,
  .auth-card-wrap,
  .auth-page,
  .right-panel,
  .page-shell,
  .page-container {
    min-height: 100dvh;
  }
  /* Belt-and-braces: any element with the inline pattern */
  [style*="min-height: 100vh"],
  [style*="min-height:100vh"] {
    min-height: 100dvh !important;
  }


  /* ─── v5.7 — 3. touch-action (kill 300ms tap delay) ───────────────────
     Android Chrome / WebView still wait 300ms on taps to disambiguate
     from a double-tap-to-zoom gesture, even when zoom is disabled.
     We *want* to opt out of that wait, but `manipulation` allows
     pan in any direction — and on Android WebView, when block-level
     tappables cover most of the viewport (dashboard tiles, list rows,
     friend cards, fixture rows, profile sections, etc.) a vertical
     drag that starts on one of these elements is consumed as a
     tap-press and never reaches the page scroller, so the user
     can't scroll the page at all in the mobile app.
     `pan-y` keeps the 300ms-tap-delay killed AND explicitly tells
     the browser: vertical-pan gestures starting on this element
     should scroll the page; only horizontal pans and taps belong
     to the element. Fix is global so every page benefits, not just
     the dashboard.                                                   */
  button, .btn, a, input[type="button"], input[type="submit"],
  [role="button"], [onclick], summary, .clickable, .tap, .tappable {
    touch-action: pan-y;
  }

  /* Horizontal-pan elements (carousels, sliders, swipeable rows)
     should keep their own touch-action — opt them back to pan-x.
     If a component needs both axes, set it explicitly in its CSS.   */
  .swipeable, .h-scroll, [data-swipe="x"], [data-touch="pan-x"] {
    touch-action: pan-x !important;
  }

  /* ─── v13 — the pan-y rule above only reaches semantic tappables
     (button / a / [onclick] / .clickable …). But most tappable things in
     the app are plain <div>s with a JS click handler — league fixture rows,
     dashboard tiles, cards, list items. In the mobile WebView a vertical
     drag that STARTS on one of those is consumed as a tap and never scrolls
     the page, which is why scrolling took two fingers (hold one, drag the
     other). Set a low-specificity vertical-pan default on the structural
     content elements so a single-finger drag scrolls anywhere. These are
     bare element selectors (specificity 0,0,1) so any component class —
     .swipeable, .x01-lg-body, etc. — still overrides them. Form controls,
     <canvas> and <svg> are deliberately NOT included so the dartboard /
     coaching gesture surfaces keep their own touch handling. `pinch-zoom`
     is kept so accessibility zoom still works.                          */
  div, span, p, a, li, ul, ol, dl, dt, dd,
  table, thead, tbody, tr, td, th,
  section, article, header, footer, nav, aside, main,
  figure, figcaption, img, picture, label,
  h1, h2, h3, h4, h5, h6, small, strong, em, b, i,
  blockquote, pre, code, hr, form, fieldset {
    touch-action: pan-y pinch-zoom;
  }
  /* range sliders drag horizontally — let them handle their own gesture */
  input[type="range"] { touch-action: manipulation; }


  /* ─── v5.7 — 4. Action-row defensiveness  ─────────────────────────────
     Common pattern across the app: a row of 2-4 action buttons inside
     a card. canonical CSS sets flex: 1 + min-width: 90px which forces
     overflow on a 360px phone with 4 buttons. Force them to wrap and
     allow shrinking. Each button keeps a 44px tap target.            */
  .ctrl-actions,
  .action-row,
  .over-actions,
  .modal-actions,
  .auth-actions,
  .form-actions,
  #setupActionBtns,
  .btn-group,
  .button-row {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
  }
  .ctrl-actions > button,
  .ctrl-actions > .btn,
  .action-row > button,
  .action-row > .btn,
  .over-actions > button,
  .over-actions > .btn,
  .modal-actions > button,
  .modal-actions > .btn,
  .auth-actions > button,
  .auth-actions > .btn,
  .form-actions > button,
  .form-actions > .btn,
  #setupActionBtns > button,
  #setupActionBtns > .btn,
  .btn-group > button,
  .btn-group > .btn,
  .button-row > button,
  .button-row > .btn {
    flex: 1 1 auto !important;
    min-width: 0 !important;          /* allow ellipsis instead of clip */
    min-height: 44px !important;       /* HIG / Material tap target */
    padding-left: 12px !important;
    padding-right: 12px !important;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }


  /* ─── v5.7 — 5. Tap-target floor (links, icons, pills) ────────────────
     Beyond buttons: any clickable text-link in a list (sidebar items,
     dropdown items, fixture rows) needs to be hittable too. The hard
     floor is 44px. We don't enforce on inline links inside body copy
     (would look comically tall), only on items that already declare
     they're rows or items.                                            */
  .sb-item,
  .nav-link-mobile,
  .menu-item,
  .row-tap,
  .list-item-tap,
  .fx-row[role="button"],
  .friend-row[onclick] {
    min-height: 44px;
  }


  /* ─── v5.7 — 6. iOS Safari zoom-on-focus prevention ───────────────────
     If any text input has font-size < 16px, iOS Safari zooms the page
     on focus. Existing rules in section 1 (Global mobile foundations)
     already enforce 16px on most inputs; restate defensively for the
     odd inline-styled exception that bypasses the canonical rule.    */
  input:not([type]),
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="search"],
  input[type="tel"],
  input[type="url"],
  input[type="number"],
  input[type="date"],
  input[type="time"],
  input[type="datetime-local"],
  textarea,
  select {
    font-size: 16px !important;
  }


  /* ─── v5.7 — 7. Pull-to-refresh containment  ──────────────────────────
     In app form (Android WebView wrap), accidental top-edge pulls
     trigger pull-to-refresh which interrupts gameplay. Contain the
     overscroll on the body to prevent the bounce-load behavior.
     Page-level scroll containers (#gameContent etc.) handle their
     own overscroll-behavior already.                                  */
  body {
    overscroll-behavior-y: contain;
  }


  /* ─── v5.7 — 8. Image / media block defaults  ─────────────────────────
     Existing rule already says img/video/canvas/svg/iframe { max-width:
     100% }. Add `display: block` to kill the inline whitespace gap and
     `height: auto` for aspect preservation when only width is set.    */
  img, video, canvas, svg, iframe {
    display: block;
  }


  /* ─── v5.7 — 9. Modal / sheet positioning  ────────────────────────────
     Modals and slide-up sheets often use position:fixed; bottom:0; and
     get their bottom edge eaten by the gesture bar. Add safe-area
     padding to anything that looks like a sheet anchored at the bottom.
     Doesn't affect modals centered on screen.                         */
  .sheet,
  .bottom-sheet,
  .slide-up,
  [class*="-sheet"][class*="bottom"] {
    padding-bottom: max(16px, env(safe-area-inset-bottom)) !important;
  }


  /* ─── v5.7 — 10. Topbar safe-area (notched iPhones only)  ────────────
     Android (your primary target) handles status bar via the WebView/
     system, no CSS work needed. Notched iPhones do need the top inset
     so the topbar doesn't sit under the notch.

     We ONLY add padding-top — no height override. The page's own
     topbar height rules continue to define the visible bar. The inset
     is 0 on every Android device and on un-notched iPhones, so this
     rule is a no-op there. On notched iPhones in cover-viewport mode,
     it pushes the topbar logo / buttons below the notch.             */
  .topbar,
  header.topbar {
    padding-top: env(safe-area-inset-top, 0);
    box-sizing: content-box;
  }


  /* ─── v5.7 — 11. Defensive: hide horizontal scrollbars  ───────────────
     Existing `html, body { overflow-x: hidden }` should catch this but
     some inner containers still produce horizontal scrollbars from a
     stray padding miscalc. Belt-and-braces: never expose horizontal
     scroll anywhere in the layout.                                    */
  html, body {
    overflow-x: hidden !important;
    max-width: 100vw !important;
  }


  /* ─── v5.7 — 12. Sticky-bottom action bars  ───────────────────────────
     Some pages (lobby chat input, fixture submit row) use a sticky
     action bar. Lift them above the gesture bar.                     */
  .sticky-bottom,
  .action-bar-sticky,
  [class*="sticky"][class*="bottom"] {
    bottom: env(safe-area-inset-bottom, 0) !important;
    padding-bottom: max(8px, env(safe-area-inset-bottom)) !important;
  }

}  /* /CLOSE @media (max-width: 720px) — v5.7 polish section */


/* ─── v5.7 — Very-small-phone (≤380px) action-row breakpoint ───────────────
   On the smallest phones (320px / 360px iPhone SE / Pixel 4a), even
   the wrap rule above can leave 4 buttons cramped. Give each row item
   ~45% basis so they form pairs.                                      */
@media (max-width: 380px) {
  .ctrl-actions > button,
  .ctrl-actions > .btn,
  .action-row > button,
  .action-row > .btn {
    flex: 1 1 45% !important;
    font-size: 11px !important;
    padding-left: 8px !important;
    padding-right: 8px !important;
  }
}
