td[class~=py-3],th[class~=py-3]{padding-top:.4rem;padding-bottom:.4rem}td[class~=py-4],th[class~=py-4]{padding-top:.5rem;padding-bottom:.5rem}td[class~=py-2],th[class~=py-2]{padding-top:.3rem;padding-bottom:.3rem}[class~=py-3][class~=border-b]{padding-top:.45rem;padding-bottom:.45rem}[class~=py-4][class~=border-b]{padding-top:.55rem;padding-bottom:.55rem}.mt-18{margin-top:2.5rem}body{overflow-wrap:break-word}.flex>*,[class*=inline-flex]>*{min-width:0}table{max-width:100%}code,pre{overflow-x:auto;max-width:100%}@media (max-width:640px){.px-6,.px-8{padding-left:.8rem;padding-right:.8rem}.px-5{padding-left:.7rem;padding-right:.7rem}.px-4{padding-left:.65rem;padding-right:.65rem}.p-6{padding:.85rem}.p-5{padding:.75rem}.p-4{padding:.65rem}.gap-6{gap:.6rem}.gap-4{gap:.5rem}.gap-3{gap:.45rem}.py-10{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:1.2rem;padding-bottom:1.2rem}.py-6{padding-top:1rem;padding-bottom:1rem}.text-5xl{font-size:2.1rem;line-height:1.05}.text-4xl{font-size:1.7rem;line-height:1.12}}.p-8{padding:1.25rem}.p-7{padding:1.05rem}.p-6{padding:1rem}.p-5{padding:.85rem}.px-8{padding-left:1.25rem;padding-right:1.25rem}.px-7{padding-left:1.05rem;padding-right:1.05rem}.py-8{padding-top:1.1rem;padding-bottom:1.1rem}.py-7{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:.85rem;padding-bottom:.85rem}.py-24{padding-top:2.25rem;padding-bottom:2.25rem}.py-20{padding-top:2rem;padding-bottom:2rem}.py-16{padding-top:1.75rem;padding-bottom:1.75rem}.py-14{padding-top:1.5rem;padding-bottom:1.5rem}.py-12{padding-top:1.4rem;padding-bottom:1.4rem}.py-10{padding-top:1.2rem;padding-bottom:1.2rem}.py-9{padding-top:1.1rem;padding-bottom:1.1rem}.bg-hero,section[class*=bg-hero]{padding-top:1.4rem;padding-bottom:1.4rem}.mb-12{margin-bottom:1.25rem}.mb-10{margin-bottom:1rem}.mb-8{margin-bottom:.85rem}.mt-12{margin-top:1.25rem}.mt-10{margin-top:1rem}.mt-8{margin-top:.85rem}table td,table th{padding-top:.35rem;padding-bottom:.35rem}[class*="text-[10px]"],[class*="text-[11px]"],[class*="text-[9px]"],[class*=rounded-full]{white-space:nowrap}[class*="text-[10px]"]:not([class*=rounded]):not([class*=bg-]):not([class*=border]),[class*="text-[11px]"]:not([class*=rounded]):not([class*=bg-]):not([class*=border]),[class*="text-[9px]"]:not([class*=rounded]):not([class*=bg-]):not([class*=border]){white-space:normal}.px-4.py-1\.5,.px-4.py-2,.px-4.py-2\.5{padding-left:.65rem;padding-right:.65rem}@media (max-width:640px){#div-tabs{flex-wrap:nowrap!important;overflow-x:auto;-webkit-overflow-scrolling:touch;justify-content:flex-start!important;scrollbar-width:none}#div-tabs::-webkit-scrollbar{display:none}#div-tabs>*{flex:0 0 auto}#division-tabs{flex-wrap:nowrap!important;overflow-x:auto;-webkit-overflow-scrolling:touch;justify-content:flex-start!important;scrollbar-width:none}#division-tabs::-webkit-scrollbar{display:none}#division-tabs>*{flex:0 0 auto}}
/* DENSITY-MOBILE-V2 (2026-08-31, operator: too much whitespace/gaps on mobile) — tighten oversized
   titles + vertical rhythm on phones, family-wide. */
@media (max-width:640px){
  h1[class*=text-3xl],.text-3xl{font-size:1.5rem;line-height:1.18}
  h1[class*=text-2xl],.text-2xl{font-size:1.3rem;line-height:1.2}
  .text-xl{font-size:1.12rem;line-height:1.25}
  .mb-10{margin-bottom:.9rem}.mb-8{margin-bottom:.8rem}.mb-6{margin-bottom:.65rem}.mb-5{margin-bottom:.55rem}.mb-4{margin-bottom:.55rem}.mb-3{margin-bottom:.4rem}
  .mt-10{margin-top:.9rem}.mt-8{margin-top:.8rem}.mt-6{margin-top:.65rem}
  .space-y-6>*+*{margin-top:.65rem}.space-y-5>*+*{margin-top:.55rem}.space-y-4>*+*{margin-top:.5rem}
  section[class*=bg-hero],.hero,.page-hero{padding-top:1.1rem!important;padding-bottom:1.1rem!important}
}
/* DENSITY-HERO-V3 (2026-08-31): the shared .bg-hero banner ate ~40% of the mobile fold (huge title +
   multi-line description) before any data. Compact it on phones, family-wide (standings/schedule/results/etc). */
@media (max-width:640px){
  section.bg-hero,.bg-hero{padding-top:.9rem!important;padding-bottom:1rem!important}
  .bg-hero h1{font-size:1.45rem!important;line-height:1.12!important;margin-top:.35rem!important}
  .bg-hero p{font-size:.82rem!important;line-height:1.38!important;margin-top:.4rem!important}
  .bg-hero .hero-rule{margin-top:.4rem!important;margin-bottom:.15rem!important}
  .bg-hero .hero-pill{font-size:11px!important}
}
/* DENSITY-GLOBAL-V4 (2026-08-31, operator: finish the whole mobile density pass) — broaden the phone
   density: shrink the largest display text, compact ANY hero inner container + big section padding, tighten
   section-to-section rhythm. Applies to every page that loads density.css. */
@media (max-width:640px){
  .text-6xl{font-size:2rem!important;line-height:1.05!important}
  .text-5xl{font-size:1.75rem!important;line-height:1.08!important}
  .text-4xl{font-size:1.5rem!important;line-height:1.12!important}
  section.bg-hero>div,section.bg-hero .max-w-7xl,.hero>div,.page-hero>div{padding-top:1rem!important;padding-bottom:1.05rem!important}
  .py-16,.py-14,.py-12{padding-top:1rem!important;padding-bottom:1rem!important}
  .py-10,.py-9{padding-top:.9rem!important;padding-bottom:.9rem!important}
  section+section{margin-top:0}
}
/* TABLE-SCROLL-V1 (2026-09-04, operator: data tables unreachable on mobile) — bare data tables
   (admin-club-managers Manage action, and any .w-full/.arch-table not already in an overflow-x-auto
   wrapper) render wider than the phone viewport inside overflow:visible wrappers with NO horizontal
   scroll, pushing the right-most columns (actions / WIN% / PTS) off-screen and out of reach. On phones
   only, turn each data table into its own horizontal scroll container (GitHub-markdown pattern) so every
   column/action is reachable by swipe, with a visible scroll cue. Desktop (>640px) is byte-identical
   (proven: SHA256-identical before/after screenshots at 1280x800). Already-wrapped tables are unharmed. */
@media (max-width:640px){
  table.w-full,table.arch-table{
    display:block;
    width:max-content;
    max-width:100%;
    overflow-x:auto;
    -webkit-overflow-scrolling:touch;
  }
  table.w-full::-webkit-scrollbar,table.arch-table::-webkit-scrollbar{height:6px}
  table.w-full::-webkit-scrollbar-thumb,table.arch-table::-webkit-scrollbar-thumb{background:rgba(0,0,0,.28);border-radius:3px}
}

/* ===================================================================
   MOBILE-PHASE1 (2026-09-04): shared-component mobile polish, family-wide.
   EVERY rule below is inside @media (max-width:640px) — desktop (>640px) is
   byte-unchanged by construction. Central fix in the site-wide density.css so
   the whole fleet (standings/results/schedule/players/staff) benefits at once.
   Families: 5 compact hero · 6 drop duplicate .lnav · 7 44px tap targets ·
   8 staff-header stack + floating back-button size.
   =================================================================== */
@media (max-width:640px){
  /* --- FAMILY 5: compact hero -> ~56px title bar ---------------------
     The shared hero (.bg-hero / .page-hero / .site-hero) ate ~200px of the
     mobile fold before any data. Collapse to a compact title bar: drop the
     badge pill, the accent rule and the multi-line description, shrink the
     title, tighten padding, and flatten the heavy cover photo to a light
     brand wash (perf + clean strip). */
  section.bg-hero,.bg-hero,section.site-hero,.site-hero,.page-hero{
    min-height:0!important;padding-top:.5rem!important;padding-bottom:.55rem!important;
    background-image:none!important;background:var(--brand-700,#006c2c)!important;}
  section.bg-hero h1,.bg-hero h1,.site-hero h1,.page-hero h1,.site-hero-title{
    font-size:1.2rem!important;line-height:1.15!important;margin:0!important;}
  section.bg-hero p,.bg-hero p,.site-hero p,.page-hero p{display:-webkit-box!important;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:.8rem!important;line-height:1.3!important;margin:.15rem 0 0!important;opacity:.9}
  .bg-hero .hero-pill,.page-hero .hero-pill,.site-hero .hero-pill,
  .bg-hero .hero-rule,.page-hero .hero-rule,.site-hero .hero-rule{display:none!important;}

  /* --- FAMILY 6: drop .lnav entries that duplicate the bottom tab-bar ----
     #hkpl-tabbar (fixed bottom nav) already carries Home/Schedule/Results/
     Standings/History persistently on phones (verified rendered at 390px), so
     the section nav's Schedule/Standings/Results are redundant here. Hide
     ONLY those three; keep the uniques (Club rankings, Top players, Playoffs,
     League Stats, Team Stats). */
  #league-nav .lnav a[href="/schedule.html"],
  #league-nav .lnav a[href="/standings.html"],
  #league-nav .lnav a[href="/results.html"]{display:none!important;}

  /* --- FAMILY 7: 44px minimum tap targets (Apple/Google standard) --------
     Applied to the shared section-nav pills, footer links, the back button and
     the header mode pills. Header lang/font/simple-mode controls are already
     >=44px. */
  #league-nav .lnav a{min-height:44px!important;display:inline-flex!important;align-items:center!important;}
  #hkpl-sf a{min-height:44px;display:inline-flex;align-items:center;}
  #hkpl-back{min-height:44px!important;min-width:44px!important;justify-content:center;}
  #hkpl-sh a.sh-mode{min-width:44px!important;}

  /* --- FAMILY 8: staff header stack + floating back-button ---------------
     Let the shared header row wrap instead of cramming when a staff/admin page
     adds extra controls (public header has few items -> no wrap, unchanged).
     Floating back-button: keep it clear of content and reliably on top on
     phones (position/size/z-index only; back-button.js scroll logic untouched). */
  #hkpl-sh .inner{flex-wrap:wrap!important;height:auto!important;min-height:64px;row-gap:6px;}
  #hkpl-back.floating{z-index:41;top:calc(8px + var(--uat-bar-h,0px));left:8px;}
}
@media (max-width:640px){
  /* MOBILE-PHASE1 hero inner-container: trim the inner padding V4 left at 1rem so the compact title bar lands near ~56px (family 5). */
  section.bg-hero>div,section.bg-hero .max-w-7xl,.page-hero>div,.page-hero-inner,.site-hero>div{padding-top:.35rem!important;padding-bottom:.35rem!important}
}

/* ===================================================================
   MOBILE-PHASE3 (2026-09-04): density & layout, SAFE CSS subset, family-wide.
   EVERY rule below is inside @media (max-width:640px) -> desktop (>640px) is
   byte-unchanged by construction. Central fix in site-wide density.css so the
   whole density family (148 pages) benefits at once. Items 22/21/23/24.
   =================================================================== */
@media (max-width:640px){
  /* --- ITEM 22: 16px text-input floor -> stop iOS Safari focus auto-zoom ---
     iOS zooms when a focused text control has font-size < 16px. Audit (headless
     Chrome @390px) found every text control at 15px or less (text/email/tel=15,
     textarea=14) and NONE above 16 -> a flat 16px only RAISES sub-16 controls,
     never shrinks. Scoped to text-entry controls; checkbox/radio/range/color/
     file excluded so their box sizing is untouched. */
  input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not([type=file]),
  textarea,select,[contenteditable=true]{font-size:16px!important}

  /* --- ITEM 21: tidy 2-col KPI/stat grid + tighter card padding -------------
     KPI/stat grid containers render inconsistently on phones: .kpi-row collapses
     to 1 wasteful column, others go 3-cramped or auto-fit. Converge the family to
     a clean 2-col grid and tighten the card inner padding. */
  .kpis,.kpi-row,.kpi-grid,.stats-grid,.stat-grid,.stats-ribbon,.kpi-cards,.stat-cards{
    display:grid!important;
    grid-template-columns:repeat(2,minmax(0,1fr))!important;
    gap:.5rem!important;
  }
  .kpi-card,.stat-card,.stat-cell,.stat-block{padding:.6rem .7rem!important}

  /* --- ITEM 23: scroll affordance on clipped tab/segment strips -------------
     Horizontal strips that clip on phones: guarantee momentum scroll, hide the
     scrollbar, keep children from shrinking (so overflow can scroll), and add a
     subtle right-edge fade so users see there is more. Applied to the scrolling
     strip family only (wrapping strips .hub-tabs/.elig-tabs are left to wrap). */
  .tabs,.seg-tabs,.role-tabs,.tabs-wrap,.role-tabs-wrap,#div-tabs,#division-tabs,[role=tablist]{
    overflow-x:auto!important;-webkit-overflow-scrolling:touch;
    flex-wrap:nowrap!important;scrollbar-width:none;
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 18px),transparent);
    mask-image:linear-gradient(to right,#000 calc(100% - 18px),transparent);
  }
  .tabs::-webkit-scrollbar,.seg-tabs::-webkit-scrollbar,.role-tabs::-webkit-scrollbar,
  #div-tabs::-webkit-scrollbar,#division-tabs::-webkit-scrollbar,[role=tablist]::-webkit-scrollbar{display:none}
  .tabs>*,.seg-tabs>*,.role-tabs>*,#div-tabs>*,#division-tabs>*,[role=tablist]>*{flex:0 0 auto}

  /* --- ITEM 24: consistent empty-state alignment ---------------------------
     Ad-hoc empty states vary from 22px to 60px padding (some via inline style).
     Converge the family to centered text + one consistent padding matching the
     shared .ds-empty rhythm (24px/20px). !important overrides inline padding. */
  .hkpl-empty,.empty-state,.onb-empty,.ov-empty,.hns-empty,.ro-empty,.hit-empty,.empty-premium{
    text-align:center!important;padding:1.5rem 1.25rem!important;
  }
}

/* ===================================================================
   MOBILE-CEILING (2026-09-04): the professional native-feel pass — the
   final "web page -> app" polish. Families below:
     A  zero horizontal scroll  (admin control-row reflow + off-canvas clip)
     B  tactile :active feedback on every tappable (native tap response)
     C  crisp :focus-visible rings (keyboard a11y)
     D  momentum scroll on every scroll container
     E  consistent motion, all honouring prefers-reduced-motion
   THE LAW: every layout-affecting rule is inside @media(max-width:640px), so
   desktop (>640px) renders byte-identical (proven: 1280px before/after PNGs).
   The two globals (focus-visible ring, reduced-motion guard) are additive-
   desktop-neutral — a focus ring only paints on keyboard focus and the motion
   guard only fires when the OS asks for it, so a static desktop render is
   unchanged. Both were operator-requested a11y for this pass.
   =================================================================== */

/* --- A1  ADMIN "Stand in a real user's shoes" filter row -> reflow --------
   Root cause of admin.html's 390px sideways scroll (scrollWidth 746 vs the
   390 client width): #impersonate-real-card's control row (a search input +
   4 selects) is a NON-wrapping flex row whose min-content is ~700px. Let it
   wrap so every control stays reachable AND the page fits the phone. */
@media (max-width:640px){
  #impersonate-real-card > div > div{flex-wrap:wrap!important}
  #impersonate-real-card #imp-search{flex:1 1 100%!important}
  #impersonate-real-card #imp-club,
  #impersonate-real-card #imp-team,
  #impersonate-real-card #imp-role{max-width:none!important;flex:1 1 46%!important;min-width:0}
}

/* --- A2  OFF-CANVAS CONTAINMENT -------------------------------------------
   A position:fixed drawer parked off the right edge (.dupr-pm-panel, which
   hides via transform:translateX(100%), and any future off-canvas panel)
   extends the document's horizontal scroll box -> a phantom sideways scroll
   even though nothing is visible. Clip horizontal overflow at the root on
   phones. overflow-x:CLIP (not hidden) does NOT establish a scroll container,
   so position:sticky / position:fixed and vertical momentum scrolling keep
   working; per spec clip also does not coerce overflow-y, so page scroll is
   untouched. Self-contained scrollers (wide tables via TABLE-SCROLL-V1, the
   tab strips) keep their own overflow-x:auto and are unaffected. */
@media (max-width:640px){
  html{overflow-x:clip}
}

/* --- B  TACTILE FEEDBACK --------------------------------------------------
   Every tappable gets a crisp ~110ms press state so a tap feels native, and
   loses the 300ms double-tap delay + the grey tap-flash. Phones only. */
@media (max-width:640px){
  a,button,[role="button"],summary,label[for],[data-act],
  .hkpl-card[onclick],.div-tab,.lnav a,#hkpl-tabbar a,#hkpl-sf a,
  .home-acc-h,[role="tab"],.seg-tabs>*,.role-tabs>*{
    -webkit-tap-highlight-color:transparent;
    touch-action:manipulation;
  }
  button:active,[role="button"]:active,[data-act]:active,
  .div-tab:active,.lnav a:active,#hkpl-tabbar a:active,
  .home-acc-h:active,[role="tab"]:active,summary:active,
  .ds-tile:active,.hkpl-btn:active,.btn:active{
    transform:scale(.97);
    transition:transform .11s ease;
  }
  .hkpl-card[onclick]:active,a.card:active,.press-dim:active{opacity:.9}
}

/* --- C  FOCUS-VISIBLE (keyboard a11y; additive-desktop-neutral) -----------
   Paints ONLY on keyboard focus (never mouse/touch), so static renders are
   unchanged. outline (not box-shadow/border) => no layout shift. Modest
   specificity + :focus-visible so it never fights a deliberate ds- ring. */
a:focus-visible,button:focus-visible,[role="button"]:focus-visible,
input:focus-visible,select:focus-visible,textarea:focus-visible,
summary:focus-visible,[tabindex]:focus-visible,[role="tab"]:focus-visible,
.div-tab:focus-visible,.lnav a:focus-visible,#hkpl-tabbar a:focus-visible,
.home-acc-h:focus-visible{
  outline:2px solid var(--focus,var(--brand,#008034));
  outline-offset:2px;
  border-radius:6px;
}

/* --- D  MOMENTUM SCROLL on every scroll container (phones) ----------------- */
@media (max-width:640px){
  .overflow-auto,.overflow-x-auto,.overflow-y-auto,.overflow-scroll,
  [data-h-scroll],[style*="overflow:auto"],[style*="overflow: auto"],
  [style*="overflow-x:auto"],[style*="overflow-y:auto"],[style*="overflow:scroll"]{
    -webkit-overflow-scrolling:touch;
  }
}

/* --- E  REDUCED MOTION (a11y; additive-desktop-neutral — only when the OS
   asks). Neutralises the press transitions above and any page transition/
   animation for users who requested less motion. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important;
    animation-iteration-count:1!important;
    transition-duration:.001ms!important;
    scroll-behavior:auto!important;
  }
  a:active,button:active,[role="button"]:active,.div-tab:active,
  .lnav a:active,#hkpl-tabbar a:active,.home-acc-h:active,[role="tab"]:active,
  summary:active,[data-act]:active{transform:none!important}
}

/* ===================================================================
   QA-WAVE2 (2026-09-05): consumer-grade visual polish, family-wide.
   EVERY layout rule below is inside @media (max-width:640px) OR is a
   :has()/pseudo hit-area expander that only paints on mobile -> desktop
   (>640px) renders byte-identical by construction. Central fix in the
   site-wide density.css so the whole fleet benefits at once.
   Families: A 44px tap targets · B floating-back header overlap ·
   D3 roster name column.
   =================================================================== */
@media (max-width:640px){
  /* --- FAMILY A: >=44px tap targets (Apple/Google), extends the earlier
     44px pass which missed these shared controls. Grow the HIT AREA with
     min-height/padding (and a centered ::before expander for icon buttons)
     so the visible chrome does not balloon. --------------------------- */
  /* topten gender/division filter tabs (were ~33-34px tall) */
  #gender-tabs .g-tab,#division-tabs .d-tab{min-height:44px!important;display:inline-flex!important;align-items:center!important;}
  /* topten per-card Share icon (was 37x37) */
  .topten-share-btn{min-width:44px!important;min-height:44px!important;}
  /* standings grouped-division sub-tabs (were ~33px tall) */
  #group-tabs .group-tab{min-height:44px!important;display:inline-flex!important;align-items:center!important;}
  /* footer utility (nav) links: height was 44 but some were only ~35px wide */
  #hkpl-sf li a{min-width:44px!important;}

  /* --- FAMILY B: the shared floating back-button (#hkpl-back.floating,
     appended to <body> on pages with no inline back control) sat on top of
     the page's own top header content (settings' "HKPL" logo, my-lineup's
     CAPTAIN pill). Reserve left space on that top header so its leading
     content clears the 44px button parked at left:8px. Only applies when a
     floating back is actually present (so headers with an inline back or no
     back are untouched), and only on phones. --------------------------- */
  body:has(#hkpl-back.floating) > header,
  body:has(#hkpl-back.floating) > .topbar{padding-left:56px!important;}

  /* --- FAMILY D3: team-roster Name column was so tight that names wrapped
     to 3 lines while Rating/Eligible/Remove kept full padding. Reclaim
     horizontal room on phones by trimming per-cell padding on the roster
     table (5 visible columns) so the Name column widens. Table markup and
     desktop padding are untouched. ------------------------------------ */
  .roster-table td,.roster-table th{padding-left:5px!important;padding-right:5px!important;}
  .roster-table .col-remove{white-space:nowrap;}
}

/* --- FAMILY A (copy-DUPR-ID icon) lives in dupr.css (the component's own
   stylesheet); the notification-sheet header fix lives in notif-sheet.js. --- */

/* ===================================================================
   ADMIN-TABLE-PHONE-V1 (2026-09-17, old-pages sweep #9: on an iPhone 8 admin tabs rendered tables 1.1-3.8x the
   viewport with 10-12px text and no anchor column; embedded tabs sat 448-529px below the fold).
   ONE rule for every admin data table under 1024px (the breakpoint where the admin sidebar becomes a drawer):
     - the table scrolls inside its OWN box, never the page (bare tables become their own scroller; wrapped ones keep
       their .overflow-x-auto wrapper);
     - the first column of a list of records (a table with a header row of 4+ columns) is sticky at the left edge so the
       row identity stays in view while the rest scrolls under it. Registrations is excluded on purpose: Richard asked for
       its columns unfrozen on 2026-09-14 (REG-TABLE-UNPIN-V1, scripts/admin-reg-table-unpinned.test.cjs) and its first
       column is a date, not the record;
     - no text under 14px inside the admin content (Tailwind text-xs / text-[10px] / text-[11px] and inline font-size
       bumped; badges and pills scale with it).
   Scope: the admin console content (#content on admin.html) and every page that runs embedded inside it
   (html.hkpl-embedded-tab, set synchronously by /js/hkpl-overlays.js from ?embedded=1). Desktop (>=1024px) is untouched.
   Standing check: scripts/admin-table-phone.test.cjs. */
@media (max-width:1023px){
  #content table,html.hkpl-embedded-tab table{font-size:14px}
  #content table:not(.hkpl-inline-table),html.hkpl-embedded-tab table:not(.hkpl-inline-table){max-width:100%}
  /* a bare table (no scrolling wrapper) scrolls itself */
  #content :not(.overflow-x-auto):not(.overflow-auto):not([style*="overflow"])>table,
  html.hkpl-embedded-tab :not(.overflow-x-auto):not(.overflow-auto):not([style*="overflow"])>table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;width:max-content;max-width:100%}
  #content .overflow-x-auto,#content .overflow-auto,html.hkpl-embedded-tab .overflow-x-auto,html.hkpl-embedded-tab .overflow-auto{-webkit-overflow-scrolling:touch}
  /* the sticky first column (thead with 4+ columns) lives in css/admin-table-phone.css, loaded only where #content or an
     embedded tab exists: as a :has() rule here it restyled every page on every DOM change (HAS-RULES-SCOPED-0927) */
  /* 14px floor: the Tailwind small-text utilities and inline 10-13px sizes inside the admin content */
  #content .text-xs,#content .text-\[9px\],#content .text-\[10px\],#content .text-\[11px\],#content .text-\[12px\],#content .text-\[13px\],#content small,
  #content [style*="font-size:11px"],#content [style*="font-size:11px"],#content [style*="font-size:11px"],#content [style*="font-size:12px"],#content [style*="font-size:13px"],
  #content [style*="font-size: 11px"],#content [style*="font-size: 11px"],#content [style*="font-size: 11px"],#content [style*="font-size: 12px"],#content [style*="font-size: 13px"],
  #content [style*="font-size:.7"],#content [style*="font-size:.8"],#content [style*="font-size:0.7"],#content [style*="font-size:0.8"],
  #content [style*="font-size:11px"],#content [style*="font-size:11.5px"],#content [style*="font-size:12.5px"],#content [style*="font-size:13.5px"],#content [style*="font-size: 11px"],#content [style*="font-size: 11.5px"],#content [style*="font-size: 12.5px"],#content [style*="font-size: 13.5px"],
  html.hkpl-embedded-tab .text-xs,html.hkpl-embedded-tab .text-\[9px\],html.hkpl-embedded-tab .text-\[10px\],html.hkpl-embedded-tab .text-\[11px\],html.hkpl-embedded-tab .text-\[12px\],html.hkpl-embedded-tab .text-\[13px\],html.hkpl-embedded-tab small,
  html.hkpl-embedded-tab [style*="font-size:11px"],html.hkpl-embedded-tab [style*="font-size:11px"],html.hkpl-embedded-tab [style*="font-size:11px"],html.hkpl-embedded-tab [style*="font-size:12px"],html.hkpl-embedded-tab [style*="font-size:13px"],
  html.hkpl-embedded-tab [style*="font-size: 11px"],html.hkpl-embedded-tab [style*="font-size: 11px"],html.hkpl-embedded-tab [style*="font-size: 11px"],html.hkpl-embedded-tab [style*="font-size: 12px"],html.hkpl-embedded-tab [style*="font-size: 13px"],
  html.hkpl-embedded-tab [style*="font-size:.7"],html.hkpl-embedded-tab [style*="font-size:.8"],html.hkpl-embedded-tab [style*="font-size:0.7"],html.hkpl-embedded-tab [style*="font-size:0.8"],
  html.hkpl-embedded-tab [style*="font-size:11px"],html.hkpl-embedded-tab [style*="font-size:11.5px"],html.hkpl-embedded-tab [style*="font-size:12.5px"],html.hkpl-embedded-tab [style*="font-size:13.5px"],html.hkpl-embedded-tab [style*="font-size: 11px"],html.hkpl-embedded-tab [style*="font-size: 11.5px"],html.hkpl-embedded-tab [style*="font-size: 12.5px"],html.hkpl-embedded-tab [style*="font-size: 13.5px"]{font-size:14px!important;line-height:1.35}
}

/* ============================================================================================================
   PHONE-COLUMN-PRIORITY-V1 + PHONE-TAP-TARGETS-V1 (2026-09-19, CLOSE-EVERYTHING O1; old-pages sweep on an iPhone 390:
   registrations 12 columns / 1505px wide with 2,701 sub-24px targets, teams 10 columns / 1495px with 1,827).
   Under 640px, inside the admin console content (#content) and every page embedded as a tab (html.hkpl-embedded-tab):
     - /js/admin-phone-tables.js hides a wide table's secondary columns (.hkpl-col-hidden) and appends a "More" cell per
       row that opens a details row (.hkpl-row-details) listing the hidden columns as label: value. The primary columns
       are the table's own choice (<th data-phone-keep>), else its first two;
     - every control inside a table cell is a 44px target (inline-flex box, min 44x44); every button in the content is at
       least 44px tall and wide; a plain text link keeps its layout and grows its HIT AREA with symmetric padding + negative
       margin (the standard touch-target technique: the pixels do not move, the tap box does).
   Desktop (>=640px) is untouched. Standing check: scripts/admin-office-family.test.cjs rules E + F. */
@media (max-width:639px){
  #content .hkpl-phone-table .hkpl-col-hidden,html.hkpl-embedded-tab .hkpl-phone-table .hkpl-col-hidden{display:none!important}
  #content .hkpl-phone-table,html.hkpl-embedded-tab .hkpl-phone-table{width:100%!important;max-width:100%}
  /* a long email / timestamp in a kept column wraps instead of pushing the table past the viewport (invitations 395px, audit 514px) */
  .hkpl-phone-table td,.hkpl-phone-table th{overflow-wrap:break-word;white-space:normal!important}
  /* STAFF-PHONE-0910b: overflow-wrap:anywhere lets a cell shrink below its longest word ("click" drawn clic/k, "Views", "Reject" - 400+ cut words in the admin tabs) and it is inherited by every button / chip inside; break-word only breaks a word that cannot fit a line on its own */
  .hkpl-phone-table button,.hkpl-phone-table a.btn,.hkpl-phone-table select,.hkpl-phone-table input{overflow-wrap:normal}
  /* STAFF-PHONE-0910: a status chip / pill / badge inside a phone table keeps its word whole ("SCHEDULED" was drawn SCHEDULE / D in a 60 px cell), and the first cell takes the room (a 7-line paragraph in a 130 px column made 157 rows 330 px tall) */
  .hkpl-phone-table td span.inline-block,.hkpl-phone-table td span[class*="rounded"],.hkpl-phone-table td .badge,.hkpl-phone-table td .pill{white-space:nowrap!important;overflow-wrap:normal}
  .hkpl-phone-table tr:not(.hkpl-row-details)>td:first-child{width:56%}
  .hkpl-more-cell{width:1%;white-space:nowrap;padding:4px 6px!important;text-align:right;vertical-align:middle;position:static!important}
  .hkpl-more{white-space:nowrap;min-height:44px;min-width:60px;padding:0 12px;border:1px solid var(--line,#d1d5db);border-radius:10px;background:var(--surface,#fff);color:var(--ink,#111827);font-family:inherit;font-size:14px;font-weight:700;line-height:1;cursor:pointer;-webkit-tap-highlight-color:transparent}
  .hkpl-row-open>td{border-bottom:0!important}
  .hkpl-row-details>td{padding:6px 12px 12px!important;background:var(--surface-2,#f9fafb);position:static!important;box-shadow:none!important;white-space:normal}
  .hkpl-row-dl{margin:0;display:grid;gap:8px}
  .hkpl-row-kv{display:grid;grid-template-columns:minmax(88px,34%) minmax(0,1fr);gap:8px;align-items:start;font-size:14px;line-height:1.4}
  .hkpl-row-kv dt{margin:0;font-weight:700;color:var(--muted,#6b7280);font-size:14px;text-transform:uppercase;letter-spacing:.03em;overflow-wrap:break-word}
  .hkpl-row-kv dd{margin:0;min-width:0;overflow-wrap:break-word;display:flex;flex-wrap:wrap;gap:4px 6px;align-items:center}
  .hkpl-row-kv dd select,.hkpl-row-kv dd input{max-width:100%;box-sizing:border-box}
  /* 44px targets */
  #content td a,#content td button,#content td label[onclick],#content td [role=button],
  html.hkpl-embedded-tab td a,html.hkpl-embedded-tab td button,html.hkpl-embedded-tab td label[onclick],html.hkpl-embedded-tab td [role=button]{display:inline-flex;align-items:center;justify-content:center;min-height:44px;min-width:44px;padding:0 8px;box-sizing:border-box;vertical-align:middle;line-height:1.2}
  #content td select,#content td input:not([type=checkbox]):not([type=radio]):not([type=file]),
  html.hkpl-embedded-tab td select,html.hkpl-embedded-tab td input:not([type=checkbox]):not([type=radio]):not([type=file]){min-height:44px}
  #content th[onclick],#content th.cursor-pointer,html.hkpl-embedded-tab th[onclick]{height:44px;vertical-align:middle}
  /* the three controls the sweep still found under 24px: the sandbox code link and the header Portal / Sign Out links */
  #sbx-code-link,#admin-head a.inline-flex,#admin-head button.inline-flex{min-height:44px;display:inline-flex;align-items:center}
  /* a 12-column record grid (translations rows, studio cards) stacks its cells: 12 tracks in 356px are 20px each */
  #content .grid.grid-cols-12>[class*="col-span-"]{grid-column:1 / -1}
  #content .grid.grid-cols-12>.flex.gap-1{flex-wrap:wrap}
  #content button:not(.hkpl-more),html.hkpl-embedded-tab button:not(.hkpl-more){min-height:44px;min-width:44px;box-sizing:border-box}
  /* plain text links only: no class at all, or a Tailwind text/underline link; never a card, button, block or flex box */
  #content :not(td)>a:not([class]),#content :not(td)>a[class*="text-"]:not([class^="hkpl-"]):not([class*=" hkpl-"]):not([class*="btn"]):not([class*="card"]):not([class*="rounded"]):not([class*="block"]):not([class*="flex"]),
  html.hkpl-embedded-tab :not(td)>a:not([class]),html.hkpl-embedded-tab :not(td)>a[class*="text-"]:not([class^="hkpl-"]):not([class*=" hkpl-"]):not([class*="btn"]):not([class*="card"]):not([class*="rounded"]):not([class*="block"]):not([class*="flex"]){padding-top:14px;padding-bottom:14px;margin-top:-14px;margin-bottom:-14px;padding-left:6px;padding-right:6px;margin-left:-6px;margin-right:-6px}
}

/* ============================================================================================================
   CONTACT-LINKS-44-0924-V1 (2026-09-24, journeys walk as captain Danny: the Team Contacts phone and email links were
   14px tall on a phone). PHONE-TAP-TARGETS-V1 above made table controls 44px only inside the admin console and embedded
   tabs; a call / email / text link anywhere else on a member page stayed a line of text. Every tel:, mailto: and sms:
   link is a 44px target on a phone AND on a touch tablet (the 640px-only trap in FRONTEND_UAT_STANDARD section 5).
   Links that already lay themselves out as a block, flex box or button keep their display and only gain the minimum.
   Standing check: scripts/journeys-0924.test.cjs rule J9 (this rule present; every page with such a link loads this sheet). */
@media (max-width:640px),(hover:none) and (pointer:coarse){
  a[href^="tel:"],a[href^="mailto:"],a[href^="sms:"]{min-height:44px;min-width:44px;box-sizing:border-box}
  a[href^="tel:"]:not([class*="flex"]):not([class*="block"]):not([class*="btn"]),
  a[href^="mailto:"]:not([class*="flex"]):not([class*="block"]):not([class*="btn"]),
  a[href^="sms:"]:not([class*="flex"]):not([class*="block"]):not([class*="btn"]){display:inline-flex;align-items:center;vertical-align:middle}
}

/* --- PHONE-AUDIT1-0910 (operator 9 Oct: the roster was the tip of the iceberg; website audit on uat as guest/player/captain/co-captain/club manager) ---
   Families measured with scripts/mobile-audit-probe.cjs:
   (1) the marketing nav of demo/tutorial/features pages is a one-row flex wider than the phone (demo.html scrollWidth 790 at 390: Features / Demo / Full
       tutorial / Test plan / Live Sandbox unreachable behind html{overflow-x:clip}) and its language switch broke letter by letter ("E/N");
   (2) tap targets under 36 px on shared chrome: the masthead logo link (30 px, 43 pages), the Search pill (28 px, 38 pages), footer links (34 px, 28 pages). */
@media (max-width:640px){
  nav.nav > .in{flex-wrap:wrap;padding:10px 16px;gap:8px}
  nav.nav .sp{flex:none;flex-basis:100%;height:0}
  nav.nav .brand{white-space:nowrap}
  nav.nav a.lnk{padding:10px 10px;min-height:40px;box-sizing:border-box;font-size:13px;white-space:nowrap}
  .langbar button,.langtog button{white-space:nowrap;flex:0 0 auto;word-break:normal;overflow-wrap:normal}
  #hkpl-sh a.logo,#sh-logo-link{min-height:44px;display:inline-flex;align-items:center}
  button.cmdk-hint{min-height:44px;min-width:44px}
  #hkpl-sf a,footer a[href^="mailto:"],footer li a{min-height:44px;display:inline-flex;align-items:center}
}

/* --- TAP-FLOOR-0910 (phone audit 1: 211 controls under 36 px high; the rule, once) ---
   Two shapes, two treatments, phones only:
   (a) a LINK inside a table cell, a list item or a table header (team names in standings, results, schedule rows: 20 px high) gets a 36 px hit
       area from vertical padding on its inline box. An inline box's padding does not change the line height, so the look and the row height
       stay exactly as they were (for an inline-block / flex link the negative margin cancels the padding); the tap area grows into the empty space between the lines.
   (b) a BUTTON-LOOKING control (button, .btn, tab, segmented pill) gets min-height 36 px: it is a visible shape, so it simply grows by a few px.
   Floating controls and the tab bar keep their own sizes (hkpl-overlays.js, mobile-tabbar.js). */
@media (max-width:640px){
  /* round 2 (10 Oct): page utility classes (py-1, p-0, h-6) out-rank a zero-specificity rule, so the families that still measured under 36 px get html-prefixed twins */
  html a[class*="hover:underline"],html a.truncate,html td a,html th a,html #hkpl-cookie-banner a{padding-block:10px;margin-block:-10px}
  html a.inline-flex:not([class*="btn"]):not(.tb),html body select:not([data-no-tapfloor]){min-height:36px}
  /* inline style="min-height:30..35px" (JS-built controls) out-ranks every stylesheet rule: the floor needs !important there */
  html button[style*="min-height:3"]:not([style*="min-height:36"]):not([style*="min-height:38"]):not([style*="min-height:4"]),html a[style*="min-height:3"]:not([style*="min-height:36"]):not([style*="min-height:38"]){min-height:36px!important}
  html a.skew,html a[class*="text-xs"]:not(.tb):not([class*="btn"]),html a[class*="text-[1"]:not(.tb),html a[href="/sponsors.html"],html a[href="/social-games.html"]{padding-block:10px;margin-block:-10px}
  html summary{min-height:36px;box-sizing:border-box;padding-block:7px}
  html .pill:is(button,a),html .range-btn,html .div-tab{min-height:36px}
  :where(td a:not([class*="btn"]):not(.tb),th a,li > a:not([class*="btn"]):not(.tb),.stand-tbl a,a[class*="hover:underline"],a.truncate,a.inline-flex:not([class*="btn"]):not(.tb)){padding-block:10px;margin-block:-10px}
  /* :where() = zero specificity: a page or component that sets its own larger min-height (roster pill 40, tab bar 48) always wins */
  html body :where(button:not([class*="fab"]):not(.cmdk-hint):not(.tb):not([data-no-tapfloor]),a.btn,a[class*="btn-"],[role="tab"],.hub-tab,.div-tab,.copy-btn){min-height:36px}
}
