/* =====================================================================
   SEC StatCat — MOBILE LAYER                       built 2026-08-20
   ---------------------------------------------------------------------
   ONE stylesheet, loaded LAST, on top of everything else.
   PURELY ADDITIVE. No existing CSS file was edited to make this work.

   To revert the entire mobile treatment: delete this file.
   (The hamburger button in sec/sectemplate.blade.php carries an inline
    style="display:none" — it is only ever revealed by a rule in THIS
    file, so removing this file hides it again permanently.)

   Everything here is inside a @media max-width query, so desktop above
   1100px is byte-for-byte untouched. !important is used throughout
   because the page-level <style> blocks in the Blade views render into
   the <body>, i.e. AFTER this file in document order.

   TIERS
     <=1100px  stop the PAGE scrolling sideways; tables/charts scroll
     <=900px   shell collapses: hamburger + drawer, topbar reflow
     <=700px   filter panels stack, padding tightens
     <=480px   phone tier
   ===================================================================== */


/* =====================================================================
   TIER 1 — <=1100px
   THE ROOT FIX. .main-content is a flex child; flex children default to
   min-width:auto, so a 50-column table shoves the whole layout wider
   than the screen and the PAGE scrolls instead of the TABLE. Setting
   min-width:0 is what makes every existing overflow-x:auto wrapper on
   the site finally do its job.
   ===================================================================== */
@media (max-width: 1100px) {

  html { -webkit-text-size-adjust: 100%; }

  .app-layout   { min-width: 0 !important; max-width: 100% !important; }
  /* NOTE: deliberately NOT setting overflow-x here. A clipping context on
     .main-content would cut off the absolutely-positioned filter dropdowns
     and multi-select trees. min-width:0 is the actual fix. */
  .main-content { min-width: 0 !important; max-width: 100% !important; }
  .page         { min-width: 0 !important; max-width: 100% !important; }

  /* page-level containers that are themselves flex/grid children */
  .pg-body, .pg-hdr, .pg-hdr-inner,
  .matrix-card, .stat-card, .ryoa-card, .cpg, .cpg .card,
  .headline-wrap, .cdef-wrap, .sc-wrap, .kr-wrap, .art-wrap,
  .def-panel, .dv-sec, .sch-wrap {
    min-width: 0 !important;
    max-width: 100% !important;
  }

  /* ---------------------------------------------------------------
     EVERY horizontal scroll box on the site. Hold the screen width,
     scroll inside, with momentum on iOS.
     --------------------------------------------------------------- */
  .tbl-scroll,
  .stat-wrap,
  .matrix-stats-wrap,
  .def-tablewrap,
  .dv-wrap,
  .cpg .twrap,
  .cpg .pietbl,
  .kr-scroll,
  .tscroll,
  .sscroll,
  .cdef-wrap,
  .rusher-tabs,
  .secnav,
  .scores-ticker {
    max-width: 100% !important;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch !important;
    overscroll-behavior-x: contain;
  }

  /* A visible scrollbar is a strong affordance on a phone — it is the
     only cue that a table can be swiped. Thin, not ugly. */
  .tbl-scroll::-webkit-scrollbar,
  .stat-wrap::-webkit-scrollbar,
  .matrix-stats-wrap::-webkit-scrollbar,
  .def-tablewrap::-webkit-scrollbar,
  .dv-wrap::-webkit-scrollbar,
  .cpg .twrap::-webkit-scrollbar,
  .kr-scroll::-webkit-scrollbar,
  .tscroll::-webkit-scrollbar,
  .sscroll::-webkit-scrollbar { height: 6px; }
  .tbl-scroll::-webkit-scrollbar-thumb,
  .stat-wrap::-webkit-scrollbar-thumb,
  .matrix-stats-wrap::-webkit-scrollbar-thumb,
  .def-tablewrap::-webkit-scrollbar-thumb,
  .dv-wrap::-webkit-scrollbar-thumb,
  .cpg .twrap::-webkit-scrollbar-thumb,
  .kr-scroll::-webkit-scrollbar-thumb,
  .tscroll::-webkit-scrollbar-thumb,
  .sscroll::-webkit-scrollbar-thumb { background: rgba(26,39,68,.32); border-radius: 3px; }

  /* ---------------------------------------------------------------
     FROZEN NAME COLUMN — the shadow that makes it read as pinned.
     table.psr / table.st / .stat-tbl / .matrix-stats-tbl / .kr-table
     already carry position:sticky;left:0 in their own stylesheets;
     this only adds the depth cue so it is obvious while swiping.
     --------------------------------------------------------------- */
  table.psr thead th:first-child,
  table.psr tbody td:first-child,
  table.psr tfoot td:first-child,
  table.st  thead th:first-child,
  table.st  tbody td:first-child,
  .stat-tbl thead th:first-child,
  .stat-tbl tbody td:first-child,
  .matrix-stats-tbl thead th:first-child,
  .matrix-stats-tbl tbody td:first-child,
  .kr-table thead th:first-child,
  .kr-table tbody td:first-child {
    box-shadow: 6px 0 8px -6px rgba(16,24,40,.35) !important;
  }

  /* ---------------------------------------------------------------
     FROZEN NAME COLUMN — the three tables that never had one.
     Defenders (.def-table), EDGE (.dv-table), Concepts (.cpg tables).
     Both already carry min-width on the table, so the wrapper scrolls.
     Zebra striping is re-applied to the frozen cell so the stripe does
     not break at column 1.
     --------------------------------------------------------------- */

  /* ── Defenders (/sec/defender-stats) and EDGE (/sec/dvoa) ──
     REWORKED 2026-08-28. These originally pinned only :first-child,
     which on BOTH pages is the RANK column — so you swiped an 841px
     (Defenders) / 864px (EDGE) table and kept a column of row numbers
     while the player/team name scrolled away. Useless.

     Pin BOTH columns: rank + name. Clark's ruling, and it matches the
     home rankings table (# + TEAM). Pinning only column 2 would leave
     a dead strip at the left edge where the rank scrolls out and
     unrelated stat columns slide underneath.

     DO NOT hardcode the `left` offset for column 2. Both tables are
     table-layout:auto, so the rank column is content-sized: measured
     27px on Defenders but 44px on EDGE, and it grows again at a
     three-digit rank. Instead FIX column 1's width and derive the
     offset from that number — same pattern as the home rankings table.
     Widths chosen from the real data: Defenders ranks reach 84 (2
     digits, 20px padding → 34px); EDGE ranks render as "#10"/"#64"
     (3 chars, 22px padding → 46px). Verified unclipped.

     The `thead th { z-index }` line fixes a separate latent bug: the
     page's own CSS makes every header cell sticky-top with z-index
     auto, so a pinned BODY cell (z 2) painted OVER the sticky header
     when you scrolled down. Header now sits above the body. */

  /* Defenders — /sec/defender-stats · rank column 34px */
  .def-table thead th { z-index: 6 !important; }
  .def-table thead th:first-child,
  .def-table tbody td:first-child {
    position: sticky !important; left: 0 !important;
    width: 34px !important; min-width: 34px !important; max-width: 34px !important;
  }
  .def-table thead th:first-child { z-index: 8 !important; background: var(--navy, #1a2744) !important; }
  .def-table tbody td:first-child { z-index: 3 !important; background: #ffffff !important; }
  .def-table thead th:nth-child(2),
  .def-table tbody td:nth-child(2) { position: sticky !important; left: 34px !important; }
  .def-table thead th:nth-child(2) {
    z-index: 7 !important; background: var(--navy, #1a2744) !important;
    box-shadow: 6px 0 8px -6px rgba(16,24,40,.45) !important;
  }
  .def-table tbody td:nth-child(2) {
    z-index: 2 !important; background: #ffffff !important;
    box-shadow: 6px 0 8px -6px rgba(16,24,40,.28) !important;
  }
  /* zebra + hover must cover BOTH pinned columns or the stripe breaks at column 2 */
  .def-table tbody tr:nth-child(even) td:first-child,
  .def-table tbody tr:nth-child(even) td:nth-child(2) { background: #f7f9fc !important; }
  .def-table tbody tr:hover td:first-child,
  .def-table tbody tr:hover td:nth-child(2)           { background: #fff8e6 !important; }

  /* EDGE — /sec/dvoa · rank column 46px ("#10" is wider than "10") */
  .dv-table thead th { z-index: 6 !important; }
  .dv-table thead th:first-child,
  .dv-table tbody td:first-child {
    position: sticky !important; left: 0 !important;
    width: 46px !important; min-width: 46px !important; max-width: 46px !important;
  }
  .dv-table thead th:first-child { z-index: 8 !important; background: var(--navy, #1a2744) !important; }
  .dv-table tbody td:first-child { z-index: 3 !important; background: #ffffff !important; }
  .dv-table thead th:nth-child(2),
  .dv-table tbody td:nth-child(2) { position: sticky !important; left: 46px !important; }
  .dv-table thead th:nth-child(2) {
    z-index: 7 !important; background: var(--navy, #1a2744) !important;
    box-shadow: 6px 0 8px -6px rgba(16,24,40,.45) !important;
  }
  .dv-table tbody td:nth-child(2) {
    z-index: 2 !important; background: #ffffff !important;
    box-shadow: 6px 0 8px -6px rgba(16,24,40,.28) !important;
  }
  .dv-table tbody tr:nth-child(even) td:first-child,
  .dv-table tbody tr:nth-child(even) td:nth-child(2) { background: #f7f9fc !important; }
  .dv-table tbody tr:hover td:first-child,
  .dv-table tbody tr:hover td:nth-child(2)           { background: #fff8e6 !important; }

  /* Concepts — /sec/concepts and /team/{slug}/concepts */
  .cpg .stbl   thead th:first-child,
  .cpg .sittbl thead th:first-child,
  .cpg .ptbl   thead th:first-child,
  .cpg .main-t thead th:first-child {
    position: sticky !important; left: 0 !important; z-index: 4 !important;
    background: #f4f6fb !important;
    box-shadow: 6px 0 8px -6px rgba(16,24,40,.35) !important;
  }
  .cpg .stbl   tbody td:first-child,
  .cpg .sittbl tbody td:first-child,
  .cpg .ptbl   tbody td:first-child,
  .cpg .main-t tbody td:first-child {
    position: sticky !important; left: 0 !important; z-index: 2 !important;
    background: #ffffff !important;
    box-shadow: 6px 0 8px -6px rgba(16,24,40,.28) !important;
  }

  /* ---------------------------------------------------------------
     CHARTS — floor width, then scroll. Never squash.
     --------------------------------------------------------------- */

  /* DIRECTIONAL RUN CHART (per-team rusher page).
     Its formation pieces are absolutely positioned by percentage
     inside .dir-chart-wrap, so shrinking the box collapses the
     formation. Give the whole card a floor and scroll it as one unit
     so the field keeps its exact proportions. */
  #matrixCard { overflow-x: auto !important; -webkit-overflow-scrolling: touch !important; }
  #matrixCard > div { min-width: 700px !important; }
  .dir-chart-wrap { min-width: 700px !important; }

  /* RYOA chart (per-team rusher page) */
  .ryoa-card { overflow-x: auto !important; -webkit-overflow-scrolling: touch !important; }
  .ryoa-body { min-width: 640px !important; }

  /* Rose / spider charts (Team Offense + Team Defense) */
  .spider-wrap { min-width: 620px !important; }
  .spider-svg-wrap { min-width: 0 !important; }
}


/* =====================================================================
   TIER 2 — <=900px : THE SHELL COLLAPSES
   Sidebar becomes an off-canvas drawer behind a hamburger.
   Topbar reflows: brand row on top, live-score ticker on its own full
   width row underneath it. The topbar scrolls away with the page and
   the SEC nav strip pins to the top instead, so only 40px of chrome is
   permanently on screen. The hamburger rides in the pinned nav strip
   so it is always reachable.
   ===================================================================== */
@media (max-width: 900px) {

  /* --- hamburger: revealed here and ONLY here --------------------- */
  .mob-menu-btn {
    display: flex !important;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 46px;
    min-width: 46px;
    height: 40px;
    padding: 0;
    border: 0;
    border-right: 1px solid rgba(255,255,255,.14);
    background: var(--navy, #1a2744);
    color: #fff;
    cursor: pointer;
    position: sticky;
    left: 0;
    z-index: 5;
  }
  .mob-menu-btn span {
    display: block;
    width: 18px; height: 2px;
    background: #fff; border-radius: 2px;
    position: relative;
  }
  .mob-menu-btn span::before,
  .mob-menu-btn span::after {
    content: ''; position: absolute; left: 0;
    width: 18px; height: 2px; background: #fff; border-radius: 2px;
  }
  .mob-menu-btn span::before { top: -6px; }
  .mob-menu-btn span::after  { top:  6px; }
  body.mob-nav-open .mob-menu-btn span { background: transparent; }
  body.mob-nav-open .mob-menu-btn span::before { top: 0; transform: rotate(45deg); }
  body.mob-nav-open .mob-menu-btn span::after  { top: 0; transform: rotate(-45deg); }

  /* --- topbar: two rows, brand + actions on top, ticker below ----- */
  .topbar {
    position: static !important;   /* let the brand row scroll away */
    height: auto !important;
    flex-wrap: wrap !important;
    overflow: visible !important;
    align-items: stretch !important;
  }
  .topbar-logo {
    order: 1;
    min-width: 0 !important;
    flex: 0 0 auto;
    padding: 0 12px !important;
    height: 44px !important;
  }
  .topbar-actions {
    order: 2;
    margin-left: auto;
    height: 44px !important;
    padding: 0 8px !important;
    gap: 6px !important;
    flex: 0 0 auto;
  }

  /* THE TICKER — compressed, not hidden. Full screen width on its own
     row so 3 games are visible at 390px, swipeable left/right.
     It is above the fold on load and scrolls away with the topbar, so
     it never competes with a table swipe further down the page. */
  .scores-ticker {
    order: 3;
    flex: 0 0 100% !important;
    width: 100% !important;
    height: 40px !important;
    border-top: 1px solid rgba(255,255,255,.10);
    background: var(--navy-light, #243154);
    scroll-snap-type: x proximity;
  }
  .score-item {
    min-width: 118px !important;
    padding: 0 11px !important;
    scroll-snap-align: start;
  }
  .score-label { font-size: 8.5px !important; letter-spacing: .5px; }
  .score-team  { font-size: 11px !important; gap: 10px !important; }

  /* --- SEC nav strip becomes the pinned nav ---------------------- */
  .secnav {
    position: sticky !important;
    top: 0 !important;
    z-index: 120 !important;
    padding-left: 0 !important;
  }
  .secnav-link { padding: 0 13px !important; font-size: 12.5px !important; min-height: 40px; }

  /* --- SIDEBAR -> off-canvas drawer ------------------------------ */
  .app-layout { display: block !important; min-height: 0 !important; }

  .sidebar {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    width: 272px !important;
    max-width: 84vw !important;
    height: 100vh !important;          /* fallback for iOS < 15.4 */
    height: 100dvh !important;
    max-height: 100vh !important;
    max-height: 100dvh !important;
    /* 10500 clears .fdd-menu (the filter dropdowns) at z-index 9999. Those
       dropdowns are closed by document-level click-away handlers in 10 files,
       but the hamburger handler calls stopPropagation, so a dropdown that is
       already open stays open when the drawer opens — at 9500 it painted
       straight through the drawer. Must stay above 9999. */
    z-index: 10500 !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important;
    border-right: 1px solid rgba(0,0,0,.12) !important;
    box-shadow: 4px 0 24px rgba(16,24,40,.28);
    transform: translateX(-102%);
    transition: transform .22s cubic-bezier(.4,0,.2,1);
    padding-bottom: 40px;
  }
  body.mob-nav-open .sidebar { transform: translateX(0); }

  /* dark scrim behind the open drawer (the toggle script closes on tap) */
  .mob-nav-scrim {
    display: block !important;
    position: fixed;
    inset: 0;
    background: rgba(12,18,32,.5);
    z-index: 10400;   /* directly under the drawer, still above .fdd-menu 9999 */
    opacity: 0;
    pointer-events: none;
    transition: opacity .22s ease;
  }
  body.mob-nav-open .mob-nav-scrim { opacity: 1; pointer-events: auto; }
  body.mob-nav-open { overflow: hidden; }

  .main-content { width: 100% !important; }

  /* drawer tap targets */
  .team-accordion-header { min-height: 46px !important; font-size: 14px !important; }
  .team-sub-item         { min-height: 42px !important; font-size: 13.5px !important; }
  .sidebar-item          { min-height: 44px !important; }
  .sidebar-section-label { padding-top: 14px !important; }

  /* --- generic tap targets -------------------------------------- */
  select.dropdown-btn,
  .btn-outline, .btn-gold,
  .fdd-btn, .fdd-item,
  .ms-item, .ms-concept-row, .ms-sub-item,
  .cpg .mc > button, .cpg .btn-apply, .cpg .btn-clear,
  .fc, .fc-sl, .wk-btn {
    min-height: 40px !important;
  }
  .fdd-item, .ms-item, .ms-sub-item { padding-top: 10px !important; padding-bottom: 10px !important; }

  /* dropdown / multi-select trees must never run off screen */
  .fdd-menu, .ms-menu, .mpanel, .cpg .mpanel, .cpg .mpanel.wide {
    max-width: 92vw !important;
    width: auto !important;
    min-width: 190px !important;
    max-height: 62vh !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important;
  }

  /* --- stack everything else into one column --------------------- */
  .two-col-grid,
  .scatter-body,
  .tc-headlines,
  .cpg .two, .cpg .sit3, .cpg .pieblk, .cpg .rpovenn {
    grid-template-columns: 1fr !important;
  }
  .rank-bars-grid { grid-template-columns: repeat(2, 1fr) !important; }
  .scatter-wrap   { overflow-x: hidden !important; }

  /* filter panels */
  .fp-row  { flex-direction: column !important; }
  .fp-tag  { min-width: 0 !important; padding: 10px 14px 6px !important; }
  .fp-g, .matrix-filters .fp-g { grid-template-columns: repeat(3, 1fr) !important; }
  .filter-panel, .tbl-fp { padding: 8px 12px !important; }
  .cpg .matrix   { flex-direction: column !important; }
  .cpg .mx-label { flex: 0 0 auto !important; padding: 9px 14px !important; }
  .cpg .mx-act   { padding: 10px 14px !important; }

  /* page-card slide-out (Team Offense/Defense) must fit the screen */
  .team-card { width: min(300px, 88vw) !important; max-height: 82vh !important; }

  /* ═══════════════════════════════════════════════════════════════
     HOME — "SEC Offense Rankings" (.home-off8)
     ---------------------------------------------------------------
     This table renders as TWO side-by-side halves (teams 1-8 | 1px
     divider | teams 9-16). At 390px each half got ~190px for seven
     columns, and because home.blade.php sets `table-layout: fixed;
     width: 100%` the columns could not overflow — they could only
     CRUSH, printing headers and values on top of each other.

     >>> READ THIS FIRST IF THE TABLE EVER LOOKS CRUSHED AGAIN <<<
     The two-up container is:
         <div style="display:grid;grid-template-columns:1fr 1px 1fr;">
     It has NO CLASS, so rule (1) below matches it on its inline style
     STRING. If anyone edits that style in home.blade.php — reorders
     it, adds a space, switches to a class — the selector silently
     stops matching and the table reverts to the crushed two-up with
     no error anywhere. That is the FIRST thing to check.
     Verify with:  grep -n 'grid-template-columns:1fr 1px 1fr' \
                     resources/views/home.blade.php
     ═══════════════════════════════════════════════════════════════ */

  /* (1) stack the two halves into one column + become the scroll box */
  .card > div[style*="1fr 1px 1fr"] {
    display: block !important;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch !important;
    overscroll-behavior-x: contain;
  }
  /* the 1px divider is a grid child; give it height now that it is a block */
  .card > div[style*="1fr 1px 1fr"] > div {
    height: 1px !important;
    min-width: 100% !important;
  }

  /* (2) undo the crush — size to content so it can overflow and scroll */
  .home-off8 {
    table-layout: auto !important;
    width: max-content !important;
    min-width: 100% !important;
  }
  .home-off8 th,
  .home-off8 td { white-space: nowrap !important; }
  .home-off8 th { font-size: 10px !important; padding: 8px 9px 7px !important; }
  .home-off8 td { font-size: 12px !important; padding: 8px 9px !important; }
  /* TEAM gets a FIXED width, not auto. The two halves are separate <table>
     elements, so with auto sizing each one sizes to its own longest name —
     measured 92px in the 1-8 half vs 116px in the 9-16 half, which left the
     two halves visibly out of line. 124px is the widest name (MISSISSIPPI
     STATE, measured at 116px) plus slack, so both halves match exactly. */
  .home-off8 th:nth-child(2),
  .home-off8 td:nth-child(2) {
    width: 124px !important;
    min-width: 124px !important;
    max-width: 124px !important;
  }

  /* (3) full team names — the column no longer has to fit 190px */
  .home-off8 .team-name-cell {
    overflow: visible !important;
    text-overflow: clip !important;
    white-space: nowrap !important;
    max-width: none !important;
  }

  /* (4) pin # and TEAM. Column 1 is pinned to an exact width so the
         38px offset for column 2 is a known quantity, not a guess. */
  .home-off8 th:first-child,
  .home-off8 td:first-child {
    position: sticky !important;
    left: 0 !important;
    z-index: 3 !important;
    background: #fff !important;
    width: 38px !important;
    min-width: 38px !important;
    max-width: 38px !important;
    padding-left: 7px !important;
    padding-right: 7px !important;
  }
  .home-off8 th:nth-child(2),
  .home-off8 td:nth-child(2) {
    position: sticky !important;
    left: 38px !important;
    z-index: 3 !important;
    background: #fff !important;
    box-shadow: 6px 0 8px -6px rgba(16,24,40,.35) !important;
  }
  /* keep the hover stripe on the pinned cells */
  .home-off8 tr:hover td:first-child,
  .home-off8 tr:hover td:nth-child(2) {
    background: var(--gray-50, #f8f9fa) !important;
  }

  /* ═══════════════════════════════════════════════════════════════
     CLIPPED CONTENT — three places where content was WIDER than an
     overflow:hidden ancestor, so it was silently amputated with no
     scrollbar and no error. Every string/HTTP check called these
     pages clean. Found only by eye + getBoundingClientRect.

     RULE THIS TAUGHT: never set a min-width without confirming an
     ancestor will actually scroll. Illegible-but-complete beats
     amputated. (.spider-wrap below is exactly how I broke it.)
     ═══════════════════════════════════════════════════════════════ */

  /* (a) The rose/spider panel — /sec/team-stats AND /sec/defense.
         .spider-wrap is 620px (my min-width) inside .stat-section,
         which is overflow-x:hidden. 292px was cut off, and it was not
         just half a rose — the whole LEGEND + "PERCENTILE VS SEC
         HISTORY" panel (12 stats with percentile + SEC rank) was
         unreachable on a phone.
         Scoped with :has() so ONLY the rose section changes. The other
         four .stat-sections report a 41-87px overflow, but that is the
         sticky first column inflating scrollWidth, not hidden content —
         a blanket rule would add two useless scrollbars.
         .stat-section already computes overflow-y:hidden, so switching
         x from hidden to auto adds no new clipping context. */
  .stat-section:has(> .spider-wrap) {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }
  /* pre-2022 browsers with no :has(): take the two spare scrollbars
     rather than leave content amputated. */
  @supports not (selector(:has(*))) {
    .stat-section { overflow-x: auto !important; }
  }

  /* (b) Concepts cards — /sec/concepts and /team/{slug}/concepts.
         Three cards clipped: two .ptbl.types at 322px each and one
         .stbl at 102px, all cut off by .card{overflow:hidden}.
         Scroll .cbody rather than .card so the card HEADER stays put
         and only the content moves.

     REWORKED 2026-08-28 (was: .cpg .cbody with overflow-x auto).
     Scrolling the whole CARD BODY was too blunt: it dragged the
     "Plot on chart" control row and the scatter chart sideways along
     with the table, so swiping the table pushed the row off the left
     edge ("...ON CHART" with the gold Y/A chip amputated). Scroll only
     the wide TABLE's own wrapper instead, so controls stay put.
     Pinning the row with position:sticky does NOT work here —
     .cpg .cbody sets container-type:inline-size and the containment
     defeats sticky. Do not retry that. */
  @supports (selector(:has(*))) {
    .cpg .cbody { overflow-x: visible !important; }
    .cpg .cbody > div:has(> table) {
      overflow-x: auto !important;
      -webkit-overflow-scrolling: touch;
    }
  }
  /* pre-2022 fallback: the blunt version — controls drift, but no
     content is amputated, which is the worse failure. */
  @supports not (selector(:has(*))) {
    .cpg .cbody { overflow-x: auto !important; -webkit-overflow-scrolling: touch; }
  }

  /* .cpg .two is a 2-col grid forced to 1fr by concepts.css at <=900px,
     but `1fr` floors at MIN-CONTENT, which held the comparative chart
     column at 411px inside a 294px card. The scatter <svg width="100%">
     then inherited 411 and overflowed. Same minmax(0,...) fix as the
     drive panels — the chart drops to 294 and fits. */
  .cpg .two { grid-template-columns: minmax(0, 1fr) !important; }
  .cpg .two > * { min-width: 0 !important; }

  /* (c) Team Defense headline block — /sec/defense.
         .headline-wrap clipped 356px of "SEC DEFENSIVE RANK — HEADLINE
         STATS"; the offender is .headline-hl-row, the team highlight
         chip row. */
  .headline-wrap {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }

  /* (e) SCHEDULE ROWS — /team/georgia/schedule and /sec/schedule.
         WORST instance found: 14 x .game-row hid 69-191px and what was
         cut was the RESULT — .result-badge (W/L), .result-score
         ("24-20"), and the .matchup-btn + .expand-arrow that open the
         per-game detail. About half the games showed no score at all.
         A schedule page where you cannot see who won.

         NOTE THE TREATMENT: `flex-wrap`, NOT `overflow-x:auto`.
         Both were built and screenshotted side by side. Scrolling is
         WRONG here — it produced 14 (and 15) independently-scrolling
         one-line cards, a scrollbar under every game, with the score
         STILL hidden until you swipe each row individually. Wrapping
         drops the result onto a second line: 0 of 14 and 0 of 15 rows
         clipped, every score and Matchup button visible, row height
         54px -> 81px. Clark reviewed both and chose wrap.

         The overflowing element is the inner flex row, not the card:
         .game-header on the team page, .sched-row on the SEC page. */
  .game-header { flex-wrap: wrap !important; }
  .sched-row   { flex-wrap: wrap !important; }

  /* (g) DRIVE BOTTOM PANELS — /team/{slug}/scripts.
         .drive .bottom is a hardcoded 3-column desktop grid:
             grid-template-columns: 300px 186px 458px  (+18px gaps) = 995px
         inside a 328px container, clipped by .drive{overflow-x:hidden}.
         TWO whole analysis panels per drive were unreachable — "Play mix
         / Success rate" and "Concepts · drive share" (the second one
         started at x=568, entirely off-screen). Times 12 drives.

         minmax(0,1fr) not 1fr: plain `1fr` floors at min-content, which
         for the Concepts panel is 458px, so the panels stack but the
         card still overflows. minmax(0,...) lets them shrink to the
         column. The children then need their own scroller because the
         Concepts table inside is 458px wide at min-content. */
  .drive .bottom { grid-template-columns: minmax(0, 1fr) !important; }
  .drive .bottom > * {
    min-width: 0 !important;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }

  /* (h) SCRIPT PLAY TABLE — /team/{slug}/scripts.
         The table already scrolled, but cells WRAPPED, so rows reached
         122px and six plays filled a whole phone screen.
             tallest row  122px -> 32px
             table height 520px -> 220px  (58% shorter)
             table width 1020px -> 1446px (longer swipe, already swiped)
         Down & Distance is pinned so you keep the situation while the
         concept columns swipe past — it was position:static, the only
         major table on the site without a frozen column.

         NO background override on the pinned cells: each td already
         carries its own opaque play-type colour (blue = pass, olive =
         scramble), so sticky preserves the colour-coding for free.
         Setting background:inherit would break it — the <tr> is
         transparent and only the cells are coloured.

         The border matters. Without it the partially-scrolled Concept
         column runs straight up against the pinned column in the same
         row colour and reads as if its text is inside the Down cell
         ("3 & 10 on/Texas"). The white rule matches the table's own
         gridlines; the shadow alone was invisible on saturated blue. */
  .plays th, .plays td { white-space: nowrap !important; }
  .plays thead th:first-child { position: sticky !important; left: 0 !important; z-index: 4 !important; }
  .plays tbody td:first-child { position: sticky !important; left: 0 !important; z-index: 3 !important; }
  .plays thead th:first-child,
  .plays tbody td:first-child {
    border-right: 2px solid rgba(255,255,255,.85) !important;
    box-shadow: 5px 0 6px -4px rgba(0,0,0,.45) !important;
  }

  /* (i) DRIVE FIELD CHART — /team/{slug}/scripts.
         .drive-chart is 300px on a phone (desktop ~700px) but its marks
         are FIXED px — .sc-snap 22x22 numbered circles, .sc-ic 66x28
         icon groups — so they were ~2.3x oversized relative to the
         shrunken field and collided into an unreadable blob.
         Option B, the Directional Run Chart precedent: floor the chart
         and scroll it, so the marks keep their real size and the
         spacing returns to desktop proportions. Scaling the marks down
         instead would take the 22px circles to ~9px, where the digit
         inside (11px tall) is unreadable and untappable.
         The field <img> scales with it: 300x134 -> 640x286, same
         aspect ratio, so the pitch is not distorted. */
  .fieldbody { overflow-x: auto !important; -webkit-overflow-scrolling: touch; }
  .drive-chart { min-width: 640px !important; }

  /* (f) Passer rose — /team/{slug}/passer-stats.
         .rose-card hid 85px of .rose-info-col (the legend + percentile
         table: "Gunner Stockton (Raw) / (EDGE — schedule-adjusted) /
         Team avg / STAT PERC..."). Same shape as (a). */
  .rose-card {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }

  /* (d) Team Offense rank-bars block — /sec/team-stats.
         .rank-bars-wrap clipped 35px; the offender is
         .rank-bars-highlight-row ("EPA: Raw / Opp-Adjusted / Highlight:
         All Teams / ALABAMA / ARKANSAS / ...") at 347px vs 328px, so
         the rightmost team chips were cut. Same shape as (c). */
  .rank-bars-wrap {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }

  /* ═══════════════════════════════════════════════════════════════
     SHIELD CREST vs the hamburger.
     Another session set .shield-logo{position:fixed} so the crest is
     not clipped on desktop. DO NOT UNDO THAT — it is correct above
     900px and this rule is deliberately inside the mobile breakpoint
     only. On a phone the topbar scrolls away but a FIXED crest does
     not, so it floated over the pinned .secnav and covered 62% of the
     hamburger (hit-test: 15 of 18 probe points landed on the image,
     leaving a ~12px live strip). It also clipped the first nav tab to
     "eam Offense" and covered the first ticker game.
     position:static puts it back in the flow of its own brand row, so
     it scrolls away with that row and overlaps nothing. It stays
     inside <a class="topbar-logo"> — it IS the Home link on mobile, so
     it must remain visible and tappable. Verified 0px overlap with
     both the hamburger and the ticker. */
  img.shield-logo {
    position: static !important;
    height: 34px !important;
    width: auto !important;
    z-index: auto !important;
  }
  .topbar-logo { min-width: 0 !important; padding: 0 10px !important; }
}


/* =====================================================================
   TIER 3 — <=700px
   ===================================================================== */
@media (max-width: 700px) {

  .page { padding: 12px !important; }
  .pg-body { padding: 12px !important; gap: 12px !important; }
  .pg-hdr-inner { padding: 14px 14px 12px !important; flex-direction: column !important;
                  align-items: flex-start !important; gap: 10px !important; }
  .page-title { font-size: 21px !important; }
  .page-hdr-row { flex-direction: column !important; align-items: flex-start !important; gap: 8px !important; }

  /* filters go 2 across */
  .fp-g, .matrix-filters .fp-g { grid-template-columns: repeat(2, 1fr) !important; }
  .fc-sl { grid-column: span 2 !important; }
  .rank-bars-grid { grid-template-columns: 1fr !important; }

  /* tighter table type so more columns fit before you have to swipe */
  table.psr { font-size: 11px !important; }
  table.psr thead th:first-child { min-width: 150px !important; }
  table.psr td:first-child { min-width: 150px !important; }
  .stat-tbl, .matrix-stats-tbl { font-size: 11.5px !important; }
  .def-table, .dv-table { font-size: 11.5px !important; }

  /* week nav: keep the dropdown, drop the arrows */
  .week-nav-arrow { display: none !important; }

  .legend { padding: 9px 12px !important; gap: 10px !important; }
  .cur-f  { padding: 8px 11px !important; }
}


/* =====================================================================
   TIER 4 — <=480px : PHONE
   ===================================================================== */
@media (max-width: 480px) {

  .page { padding: 10px 8px !important; }
  .pg-body { padding: 10px 8px !important; }

  /* brand shrinks to make room for the ticker + actions */
  .topbar-logo { padding: 0 9px !important; gap: 5px !important; }
  .logo-icon { width: 24px !important; height: 24px !important; font-size: 10px !important; }
  .logo-text { font-size: 14px !important; }

  /* Login hides; Subscribe stays (it is the conversion button) */
  .btn-outline { display: none !important; }
  .btn-gold { padding: 5px 11px !important; font-size: 11.5px !important; }
  select.dropdown-btn { font-size: 11.5px !important; padding: 5px 20px 5px 8px !important; max-width: 118px; }

  /* ticker: 3 games across a 390px screen */
  .score-item { min-width: 112px !important; padding: 0 9px !important; }

  /* filters single column */
  .fp-g, .matrix-filters .fp-g { grid-template-columns: 1fr !important; }
  .fc-sl { grid-column: span 1 !important; }

  table.psr { font-size: 10.5px !important; }
  table.psr thead th:first-child,
  table.psr td:first-child { min-width: 132px !important; }
  .stat-tbl, .matrix-stats-tbl, .def-table, .dv-table { font-size: 11px !important; }

  .page-title { font-size: 19px !important; }
  .secnav-link { padding: 0 11px !important; }
}
