/* ════════════════════════════════════════════════════════════════════════
   BETEB Intel — MOBILE APP LAYER
   Everything here is wrapped in @media (max-width:767px) so the DESKTOP build
   is never affected — two independent versions. Loaded last on all 5 intel
   pages, so it wins the cascade; !important only where existing inline/JS
   styles force it.
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 767px) {

  /* ── kill raw native scrollbars on every horizontal scroller ─────────── */
  .i4-tabs, .sport-tab-bar, #rc-coursefilter, .i4-ticker,
  .bz-ribbon, .bz-picksbar, [data-hscroll], .mb-hscroll {
    scrollbar-width: none !important;
    -ms-overflow-style: none !important;
  }
  .i4-tabs::-webkit-scrollbar, .sport-tab-bar::-webkit-scrollbar,
  #rc-coursefilter::-webkit-scrollbar, .i4-ticker::-webkit-scrollbar,
  .bz-ribbon::-webkit-scrollbar, .bz-picksbar::-webkit-scrollbar,
  [data-hscroll]::-webkit-scrollbar, .mb-hscroll::-webkit-scrollbar {
    display: none !important; width: 0 !important; height: 0 !important;
  }

  /* ── app frame: full-bleed, no side gutters/rounding on a phone ───────── */
  .i4-frame {
    border-radius: 0 !important;
    border-left: 0 !important; border-right: 0 !important;
    margin-left: 0 !important; margin-right: 0 !important;
    box-shadow: none !important;
  }

  /* ── sticky app header (race band + sport rail + tab bar) ─────────────────
     Sits BELOW the fixed 56px site nav so the FULL header — sport colour bar, race band,
     rail and tabs — stays visible when scrolling (not clipped behind the nav). The sport
     colour bar (var --i4) moves off the frame onto the header so it sticks WITH it. ── */
  /* full-bleed the header: drop the 18px side gutter so the colour bar spans edge-to-edge
     (a clean app bar) instead of a bar that overhangs/mismatches an inset box */
  .live-pane, #intelPane, #statsPane { padding-left: 0 !important; padding-right: 0 !important; }
  .i4-frame { border-top: 0 !important; }
  .i4-mhead {
    position: sticky !important; top: 56px !important; z-index: 60 !important;
    margin: 0 !important; padding: 0 !important;
    border-top: 3px solid var(--i4, #22c55e) !important;   /* the sport colour bar, edge-to-edge, capping the sticky header */
    background: linear-gradient(180deg, #0c1811, #0a140e) !important;
    border-bottom: 1px solid #1e3327 !important;
    backdrop-filter: saturate(1.2) blur(4px);
  }
  .i4-top { padding: 8px 12px 8px !important; }

  /* race band (RACING pill + live NAP + clock) — one tidy row */
  .i4-top {
    padding: 0 12px 8px !important;
    gap: 8px !important;
    min-height: 0 !important;
  }
  .i4-top > * { min-width: 0 !important; }

  /* ── sport rail: centred, well-spaced pills that are easy to tap ─────────
     The rail is #sport-tab-bar (an ID), styled by `.i4-mhead #sport-tab-bar` in intel4.css —
     a bare .class can't beat that ID specificity, so match it. ── */
  .i4-mhead #sport-tab-bar {
    display: flex !important; flex-wrap: nowrap !important;
    justify-content: center !important;             /* centre the 5 sports */
    overflow-x: auto !important; -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    gap: 20px !important; padding: 4px 12px 10px !important;   /* more room between them */
  }
  .i4-mhead #sport-tab-bar > * { flex: 0 0 auto !important; scroll-snap-align: center; }
  .i4-frame .i4-mhead #sport-tab-bar .sport-tab-btn { padding: 5px 8px !important; }  /* bigger tap target */

  /* ── tab bar: clean scroll-snap segmented control, big touch targets ──── */
  .i4-tabs {
    display: flex !important; flex-wrap: nowrap !important;
    overflow-x: auto !important; -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    gap: 7px !important; padding: 4px 14px 10px !important;
    /* fade the edges so a cut-off tab reads as "scroll for more", not broken */
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
  }
  .i4-tab {
    flex: 0 0 auto !important; scroll-snap-align: start;
    min-height: 40px !important; padding: 0 16px !important;
    display: inline-flex !important; align-items: center !important; gap: 6px;
    font-size: 13px !important; letter-spacing: .02em !important;
    border-radius: 999px !important; white-space: nowrap !important;
  }
  .i4-tab.active { box-shadow: 0 2px 10px rgba(34,197,94,.28) !important; }

  /* ── content stage: full-bleed, comfortable spacing, bottom-safe ─────── */
  .i4-stage {
    padding: 14px 12px calc(96px + env(safe-area-inset-bottom, 0px)) !important;
  }
  .i4-view { padding: 0 !important; }

  /* Form tab: the course filter flows in AFTER the jockey-form table — pull it to the TOP.
     Scoped to the ACTIVE view (.on) only — forcing display on the inactive Form view made its
     boxes bleed onto Profiles/Market Tape/etc. Inactive views keep their display:none. */
  .i4-stage .i4-view.on:has(#rc-coursefilter) { display: flex !important; flex-direction: column !important; }
  .i4-stage #rc-coursefilter { order: -1 !important; margin: 0 0 12px !important; }

  /* generic content boxes go full width with mobile padding */
  .i4-stage .bz-card,
  .i4-stage .bz-fxbox,
  .i4-stage .bz-zone,
  .i4-stage [class*="-box"] {
    width: 100% !important; max-width: 100% !important; min-width: 0 !important;
    margin-left: 0 !important; margin-right: 0 !important;
  }

  /* multi-column grids collapse to a single column on a phone */
  .i4-stage #rc-deeprow,
  .i4-stage #rc-angrow,
  .i4-stage .bz-grid,
  .i4-stage [style*="grid-template-columns"] {
    grid-template-columns: 1fr !important;
  }

  /* ── PICKS grid: simple singles can sit 2-up, but MULTIPLES (Trixie / Lucky 15 /
     Emerald) carry 3-4 legs each and crush in a 194px column — give them the full
     row so leg text never crams or overlaps ── */
  .i4-stage .bzp-multi { grid-column: 1 / -1 !important; }
  .i4-stage .bzp-card { padding: 13px 14px !important; line-height: 1.4 !important; }
  .i4-stage .bzp-card * { min-width: 0 !important; }        /* let long labels shrink, not overflow */
  .i4-stage .bzp-leg { padding: 7px 0 !important; }         /* space each acca leg */

  /* section headers: stack the title and its <small> subtitle so they never collide */
  .i4-stage [class*="secttl"], .i4-stage .bz-secttl, .i4-stage .bz4-secttl {
    display: block !important; height: auto !important;
  }
  .i4-stage [class*="secttl"] small, .i4-stage .bz-secttl small, .i4-stage .bz4-secttl small,
  .i4-stage .t > small {   /* board headers "📈 BETEB <b>MARKET TAPE</b><small>subtitle</small>" */
    display: block !important; float: none !important; margin: 4px 0 0 !important;
    white-space: normal !important; line-height: 1.35 !important;
  }

  /* long clickable names truncate inside their cell instead of overlapping the next column */
  .i4-stage .cxn-lnk, .i4-stage .pdg-lnk, .i4-stage .rc-person, .i4-stage .rc-ped {
    max-width: 100% !important; overflow: hidden !important; text-overflow: ellipsis !important;
    white-space: nowrap !important; display: inline-block !important; vertical-align: bottom !important;
  }

  /* filter chip rows: horizontal scroll, touch-height chips */
  #rc-coursefilter { flex-wrap: nowrap !important; overflow-x: auto !important; }
  #rc-coursefilter .cf-chip, .cf-chip {
    min-height: 34px !important; display: inline-flex !important; align-items: center !important;
    flex: 0 0 auto !important;
  }

  /* wide tables scroll inside their OWN container — never the page body */
  .i4-stage table { display: block !important; overflow-x: auto !important; -webkit-overflow-scrolling: touch; }

  /* 🚨 …but NOT the BETEB sheet. It is a fixed 1080px card scaled by a transform, so it must keep
     its desktop layout exactly and only get smaller. Caught by the rule above, its stat tables
     became blocks, `table-layout: fixed` stopped applying, and every column collapsed to content
     width — the columns bunched together with dead space beside them instead of spreading across
     the card the way they do on desktop. */
  .i4-stage .beteb-v7 table { display: table !important; width: 100% !important; overflow-x: visible !important; }
  .i4-stage .beteb-v7 thead { display: table-header-group !important; }
  .i4-stage .beteb-v7 tbody { display: table-row-group !important; }
  .i4-stage .beteb-v7 tr { display: table-row !important; }
  .i4-stage .beteb-v7 th, .i4-stage .beteb-v7 td { display: table-cell !important; }

  /* The jockey/trainer Form 14d win%/plc% columns get hidden on mobile by a JS column-hider
     (inline display:none from the header's .hide-mob). The user wants recent-form on the mobile
     Form card, so force those two cells visible — CSS !important beats the JS inline style, and
     intel-rendering.js gives them explicit data-th so the card shows "14D WIN% : value". */
  .i4-stage table[data-i4mob] td[data-th="14d Win%"],
  .i4-stage table[data-i4mob] td[data-th="14d Plc%"] { display: flex !important; }


  /* ── BETEB Sheet (fixed 680px export card): let it scroll within its box ─
     (it's a fixed-width shareable image; a scroll box is robust — proper
     scale-to-fit is a follow-up) ── */
  #bz4-wrap, #bz4-section { overflow-x: auto !important; -webkit-overflow-scrolling: touch; }

  /* hide EVERY inner scrollbar in the content stage (horizontal chip rows, the
     sheet card, tables) — users swipe; raw native scrollbars look unfinished */
  .i4-stage *::-webkit-scrollbar { width: 0 !important; height: 0 !important; display: none !important; }
  .i4-stage * { scrollbar-width: none !important; -ms-overflow-style: none !important; }

  /* ── ticker stays but contained ───────────────────────────────────────── */
  .i4-ticker { overflow: hidden !important; }

  /* the chat FAB shouldn't sit ON the last card */
  #cw-fab { bottom: calc(16px + env(safe-area-inset-bottom, 0px)) !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   MOBILE v2 — 2026-08-21 · density, reclaimed width, and a tab bar that actually sticks
   Measured on a 390x844 phone against /intel/racing/ before any change:
     · the race row got 298px of 390 (76%) — three nested frames each charged padding + border
     · every multi-column grid was forced to ONE column, so the page became an endless stack
     · the header was declared position:sticky and DID NOT STICK, so changing tab meant
       scrolling all the way back to the top of a 3,000px page
   ═══════════════════════════════════════════════════════════════════════════════════════════ */
@media (max-width: 767px) {

  /* ── 1. THE BIG ONE: restore position:sticky ──────────────────────────────────────────────
     html/body carried `overflow-x: hidden`, the usual defence against sideways scroll. But a
     non-visible overflow makes that element a SCROLL CONTAINER, and a sticky descendant then
     sticks relative to it instead of the viewport — so .i4-mhead never stuck anywhere.
     `overflow-x: clip` blocks the same sideways scroll WITHOUT creating a scrollport.
     (Note: the `overflow: clip` on .i4-frame in intel4.css is correct and must stay — clip is
     precisely the value that does NOT trap a sticky child.) */
  html, body { overflow-x: clip !important; overflow-y: visible !important; }

  /* ── 2. the header is charged to every screen now that it genuinely sticks ────────────────
     Drop the ticker row — it repeats the NAP and the clock already shown in the Tips tab —
     and set the sport buttons on one line instead of emoji-stacked-over-label. 147px → 97px. */
  .i4-mhead .i4-top { display: none !important; }
  .i4-mhead #sport-tab-bar .sport-tab-btn {
    flex-direction: row !important; align-items: center !important; gap: 5px !important;
    padding: 8px 10px !important;
    min-height: 44px !important;          /* keep the WCAG/Material tap target */
  }

  /* ── 3. one frame, not three ──────────────────────────────────────────────────────────────
     A card inside a card must not pay for padding AND a border twice. 76% → 90% of the screen. */
  .i4-stage { padding-left: 8px !important; padding-right: 8px !important; }
  .i4-stage .bz-card { padding-left: 10px !important; padding-right: 10px !important; }
  .i4-stage .bz-card .rc-wrap,
  .i4-stage .bz-card [class$="-wrap"] {
    padding-left: 0 !important; padding-right: 0 !important;
    border-left: 0 !important; border-right: 0 !important;
    background: transparent !important;
  }

  /* ── 4. stop forcing every grid to a single column ────────────────────────────────────────
     The old rule was `grid-template-columns: 1fr`, which is what turned every board into a
     long vertical ribbon. auto-fit with a 150px floor still gives wide content a full row
     (the floor forces one column when it cannot fit two) but lets compact stat boxes pair up. */
  .i4-stage [style*="grid-template-columns"],
  .i4-stage .bz-grid, .i4-stage #rc-deeprow, .i4-stage #rc-angrow {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)) !important;
    gap: 8px !important;
  }
  .i4-stage .bzp-multi { grid-column: 1 / -1 !important; }   /* multiples still need a full row */

  /* ── 5. anchored jumps must clear the (now working) sticky header ─────────────────────── */
  .i4-stage [id] { scroll-margin-top: 150px !important; }
}

/* ── 6. WIDE TABLES: frozen column + horizontal scroll, not a 16-deep card stack ───────────
   intel4.css:449 deliberately converts data-i4mob tables into label/value cards ("no more
   horizontal panning"): thead is clipped away, tr/td go block/flex, and td::before prints
   attr(data-th). That is the right call for a narrow table. On a WIDE one it is not — the
   trainer form table (16 cols) rendered at 458px PER ROW, 4,249px for 16 rows, and the
   horizontal scroll it was given never engaged because the table had no natural width, so it
   crushed columns to 23px and wrapped every cell instead.

   Measured after: 458px -> 24px per row, and the columns are legible.

   Card transformation suits small sets where you read ONE record; these are comparison tables
   where you read DOWN a column, so the frozen-identifier + scroll pattern is correct. Narrow
   tables are unaffected in practice: min-width:100% means a 4-column table still fills the
   container and simply never scrolls. */
@media (max-width: 767px) {
  .i4-stage div:has(> table[data-i4mob]) {
    overflow-x: auto !important; -webkit-overflow-scrolling: touch !important;
  }
  .i4-stage table[data-i4mob] {
    display: table !important;
    width: max-content !important; min-width: 100% !important;
    border-collapse: separate !important; border-spacing: 0 !important;
  }
  /* bring the real header row back — it replaces the per-cell data-th labels */
  .i4-stage table[data-i4mob] thead {
    position: static !important; width: auto !important; height: auto !important;
    overflow: visible !important; clip: auto !important; clip-path: none !important;
    display: table-header-group !important;
  }
  .i4-stage table[data-i4mob] tbody { display: table-row-group !important; }
  .i4-stage table[data-i4mob] tr { display: table-row !important; }
  .i4-stage table[data-i4mob] th,
  .i4-stage table[data-i4mob] td {
    display: table-cell !important; white-space: nowrap !important;
    padding: 7px 9px !important; vertical-align: middle !important;
    flex-basis: auto !important;
  }
  /* the data-th label is redundant once the real thead is visible */
  .i4-stage table[data-i4mob] td::before { content: none !important; display: none !important; }

  /* frozen identifier column: keeps the name in view while the numbers scroll */
  .i4-stage table[data-i4mob] th:first-child,
  .i4-stage table[data-i4mob] td:first-child {
    position: sticky !important; left: 0 !important; z-index: 3 !important;
    background: #12161f !important;
    box-shadow: 6px 0 8px -6px rgba(0,0,0,.9) !important;
  }
  /* numbers right-aligned so place value lines up and magnitudes compare at a glance */
  .i4-stage table[data-i4mob] td:not(:first-child),
  .i4-stage table[data-i4mob] th:not(:first-child) { text-align: right !important; }

  /* a table must never be dropped into a narrow auto-fit column */
  .i4-stage [style*="grid-template-columns"] > *:has(table),
  .i4-stage .bz-grid > *:has(table),
  .i4-stage #rc-deeprow > *:has(table),
  .i4-stage #rc-angrow > *:has(table),
  .i4-stage [style*="grid-template-columns"] > *:has([data-hscroll]) {
    grid-column: 1 / -1 !important;
  }
}

/* ── 6b. EXPANDED PANELS: scroll the overflow instead of clipping it ───────────────────────
   See the note above §7. `.bz-fxbody` panels hold tables wider than the phone (552px in a 437px
   box on the racing Form tab), `.bz-fxbox` above them is `overflow: hidden`, and the runtime
   styles injected by intel-rendering.js force `overflow: visible` on the body — so the surplus
   was cut off mid-value and unreachable. These selectors out-specify the injected ones on
   purpose; they restore the HORIZONTAL axis only, and `max-height: none` keeps the panel free to
   grow downwards the way those rules intended. */
@media (max-width: 767px) {
  .i4-stage .fb-brow .bz-fxbody,
  .i4-stage #rc-angrow .bz-fxbody,
  .i4-stage .bz-fxbox .bz-fxbody,
  .i4-stage .bz-fxbody {
    overflow-x: auto !important;
    max-height: none !important;
    -webkit-overflow-scrolling: touch !important;
    scrollbar-width: thin !important;
  }
  /* a visible rail is the affordance: without it a clipped edge just looks like a bug */
  .i4-stage .bz-fxbody::-webkit-scrollbar { height: 5px !important; }
  .i4-stage .bz-fxbody::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, .22) !important; border-radius: 3px !important;
  }
  /* the clipping ancestor must stop cutting once the child scrolls itself */
  .i4-stage .bz-fxbox { overflow-x: visible !important; }
}

/* ── 6c. FORM CONTROLS must not out-size the phone ─────────────────────────────────────────
   A <select> sizes to its longest OPTION, so one long label ("Main games · all 30 competitions")
   pushed the by-game stat board 106px past the screen edge, where `.bz-card`'s `overflow: hidden`
   cut it off. `min-width: 0` is the other half of the fix: a replaced element in a flex row will
   not shrink below its intrinsic width without it. */
@media (max-width: 767px) {
  .i4-stage select,
  .i4-stage input,
  .i4-stage button { max-width: 100% !important; min-width: 0 !important; }
  .i4-stage .dd-metric,
  .i4-stage .dd-metric > div { min-width: 0 !important; }
  .i4-stage .dd-metric select { flex: 1 1 auto !important; }
}

/* ── 7. sticky column headers ──────────────────────────────────────────────────────────────
   These tables run to hundreds of rows. Once the header row scrolls off, a column of bare
   numbers means nothing — you cannot tell 14d Win% from season Win%. Pin the header beneath
   the site nav (56px) + the intel header (97px after §2 above).
   The first cell is sticky on BOTH axes, so it needs the higher z-index of the two. */
@media (max-width: 767px) {
  /* 🚨 SCOPED to data-i4mob deliberately. Applied to every table it broke the FPL cards, which
     use a TWO-ROW thead (a colspan group row above the column row): both rows pinned to the same
     153px offset, collided, and the header ended up floating in the middle of the tbody with a
     blank gap where it should have been. Sticky headers are for the wide comparison tables that
     run to hundreds of rows — a six-row card does not need one and is actively harmed by it. */
  /* `tr:only-child` is the guard, and it is doing real work. Scoping by data-i4mob was
     useless — intel4.js stamps that attribute on EVERY table in the stage. The tables this
     breaks are the ones with a TWO-ROW thead (a colspan group row above the column row):
     both rows pin to the same 153px offset, collide, and the header ends up floating in the
     middle of the tbody with a gap where it belongs. A single-row thead cannot collide with
     itself, so pin only those. */
  .i4-stage table[data-i4mob] thead tr:only-child th {
    position: sticky !important; top: 153px !important;
    z-index: 4 !important;
    background: #0f131b !important;
    box-shadow: 0 4px 8px -5px rgba(0,0,0,.9) !important;
  }
  .i4-stage table[data-i4mob] thead tr:only-child th:first-child {
    left: 0 !important; z-index: 6 !important;   /* the corner cell sits above both rails */
  }
}

/* ── SPORT RAIL: reachable, and football full-bleed like the rest ───────────────────────────
   Two faults, reported together and both real.

   1. `justify-content: center` on #sport-tab-bar. When flex content OVERFLOWS a centred
      container the surplus is pushed into NEGATIVE scroll space — space `scrollLeft: 0` cannot
      reach. Measured on a 390px phone: the rail needs 412px in a 354px scrollport, and FOOTBALL
      sat at left:-28 with scrollLeft already 0. So it was not merely clipped, it was genuinely
      unswipeable; no amount of dragging could reveal it. flex-start makes every pixel reachable.
      (Mobile only — on desktop the rail fits and centring is right.)

   2. The football page nests its frame in a .content-wrap carrying an 18px side gutter, which
      the other sports do not have — racing's frame measures the full viewport width. That is why
      football alone looked narrower. Scoped with :has(.i4-frame) so only the intel shell
      full-bleeds and any other .content-wrap on the page keeps its gutter. */
@media (max-width: 767px) {
  .i4-mhead #sport-tab-bar {
    justify-content: flex-start !important;
    scroll-padding-inline-start: 12px;
  }
  .content-wrap:has(.i4-frame) {
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
}

/* ── 8. WIDE TABLES BECOME CARDS ON A PHONE (2026-09-09) ───────────────────────────────────
   §6 gave every wide table a frozen first column and sideways scroll. That beat the crushed
   columns it replaced, but on a 390px screen it is still a spreadsheet: 10-16 columns with the
   header scrolled away from the values it names, and on the racing FORM tab an expanded trainer
   sat under a nested runners table whose header row belonged to a different table entirely.

   scripts/intel-tables.js marks a wide table `.i4c-cards` and tags each row's identifier
   (.i4c-head), its expander (.i4c-exp), its secondary cells (.i4c-more) and its detail payload
   (.i4c-detail). Here that becomes ONE CARD PER ROW, labelled from the data-th attributes the
   renderers already emit.

   🔑 Not a repeat of the 2026-08-21 card attempt, which showed every column — 458px per row and
   4,249px for 16 rows — and was rightly reverted. Only the headline cells show here, so a card
   measures ~122px. The rest fold behind the row's own expander: present, one tap away, never
   dropped. Hiding data outright would break the "a redesign keeps ALL the data" rule, which is
   why .hide-mob is read as a FOLD here and never as a delete.

   🚨 These selectors carry `tbody tr :is(td, th)` deliberately. §6 above sets `position: sticky` and
   friends with !important on the same cells, so anything shorter loses and the rules silently
   do nothing — the frozen-column geometry stays and the card never forms.


   🚨 The identifier and expander cells are <th>, not <td> — the renderers mark the row header as
   a header cell. Selectors written for `td` alone matched nothing and the card silently kept its
   frozen-column geometry, which is why every rule here says :is(td, th).

   🚨 DESKTOP IS UNTOUCHED: the whole section is inside the media query, only .i4c-cards tables
   are affected, and the marking script does not run above 767px. */
@media (max-width: 767px) {
  .i4-stage div:has(> table.i4c-cards) { overflow-x: visible !important; }
  .i4-stage table.i4c-cards,
  .i4-stage table.i4c-cards tbody { display: block !important; width: 100% !important; min-width: 0 !important; }
  .i4-stage table.i4c-cards thead { display: none !important; }   /* replaced by per-cell labels */

  .i4-stage table.i4c-cards tbody tr:not(.i4c-detail) {
    position: relative !important;
    display: grid !important;
    grid-template-columns: 1fr 1fr !important;
    column-gap: 14px !important; row-gap: 2px !important;
    margin: 0 0 10px !important;
    padding: 9px 12px 10px !important;
    border: 1px solid rgba(255, 255, 255, .09) !important;
    border-radius: 12px !important;
    background: rgba(255, 255, 255, .022) !important;
  }
  .i4-stage table.i4c-cards tbody tr :is(td, th) {
    display: flex !important; justify-content: space-between !important; align-items: baseline !important;
    gap: 8px !important; position: static !important;      /* beats §6's sticky frozen column */
    width: auto !important; max-width: 100% !important;
    padding: 3px 0 !important; border: 0 !important;
    text-align: right !important; font-size: 13px !important;
    /* 🚨 Values WRAP, they do not truncate. nowrap+ellipsis looked tidier but silently ate 101px of
       "Match of the Day · Longshot" in the tracker and needed a new per-class exception for every
       table that had a long value. A card has vertical room; it does not have horizontal room. */
    white-space: normal !important; overflow: visible !important; text-overflow: clip !important;
  }
  /* attr() prints only what the renderer emitted, so a cell with no data-th shows its value
     full width rather than an empty label box */
  .i4-stage table.i4c-cards tbody tr :is(td, th)[data-th]::before {
    content: attr(data-th) !important;
    flex: 0 1 auto; margin-right: auto; text-align: left;
    display: inline !important; position: static !important;
    color: var(--bz-dim, #9aa0ad) !important;
    font: 600 9.5px/1.5 var(--mono, ui-monospace, monospace) !important;
    letter-spacing: .4px; text-transform: uppercase; opacity: .9;
  }

  /* the identifier line — the card's heading, left of everything, clearing the expander */
  .i4-stage table.i4c-cards tbody tr :is(td, th).i4c-head {
    grid-column: 1 / -1 !important;
    justify-content: flex-start !important; align-items: center !important;
    text-align: left !important; overflow: visible !important; white-space: normal !important;
    min-height: 32px !important;
    padding: 0 0 7px 42px !important; margin: 0 0 5px !important;
    border-bottom: 1px solid rgba(255, 255, 255, .10) !important;
    font-weight: 700 !important; font-size: 14.5px !important; line-height: 1.25 !important;
  }
  .i4-stage table.i4c-cards tbody tr :is(td, th).i4c-head::before { content: none !important; }

  /* the expander is lifted OUT of the grid — as a grid item it took a half-width column and
     pushed the name into the middle of the card */
  .i4-stage table.i4c-cards tbody tr :is(td, th).i4c-exp {
    position: absolute !important; left: 10px !important; top: 7px !important;
    width: 32px !important; min-width: 32px !important; max-width: 32px !important; height: 32px !important;
    margin: 0 !important; padding: 0 !important; border: 0 !important; border-radius: 8px !important;
    background: rgba(255, 255, 255, .05) !important;
    display: flex !important; align-items: center !important; justify-content: center !important;
    text-align: center !important; font-size: 16px !important;
  }
  .i4-stage table.i4c-cards tbody tr :is(td, th).i4c-exp::before { content: none !important; }

  /* folded, never dropped — opened by the table's own expander or the injected toggle */
  .i4-stage table.i4c-cards tbody tr :is(td, th).i4c-more { display: none !important; }
  .i4-stage table.i4c-cards tbody tr.bz-expanded :is(td, th).i4c-more,
  .i4-stage table.i4c-cards tbody tr.i4c-open :is(td, th).i4c-more,
  /* the expanded row carries NO class of its own — measured — so the open state is read from the
     detail row that follows it */
  .i4-stage table.i4c-cards tbody tr:has(+ tr.i4c-detail:not([style*="none"])) :is(td, th).i4c-more {
    display: flex !important;
  }

  /* THE DETAIL BELONGS TO THE CARD. The runners/rides panel is its own row in the DOM; on a phone
     it is welded to the card above — same border, no gap, no second top edge — so tapping + moves
     the horses INTO the card exactly as the desktop table does. */
  /* 🚨 THE EXPANDER IS THE SITE'S, NOT OURS. It shows and hides this row with an INLINE
     style="display:none" / "display:table-row". A stylesheet !important beats an inline
     declaration, so the blanket `display:grid !important` above was overriding the toggle: every
     card showed its runners permanently and + only changed its own glyph. Keying off the inline
     value hands control back, so + and − behave exactly as they do on desktop. */
  .i4-stage table.i4c-cards tbody tr.i4c-detail { display: block !important; }
  .i4-stage table.i4c-cards tbody tr.i4c-detail[style*="none"] { display: none !important; }
  .i4-stage table.i4c-cards tbody tr.i4c-detail {
    margin: -11px 0 10px !important; padding: 2px 10px 10px !important;
    border: 1px solid rgba(255, 255, 255, .09) !important; border-top: 0 !important;
    border-radius: 0 0 12px 12px !important;
    background: rgba(255, 255, 255, .022) !important;
  }
  .i4-stage table.i4c-cards tbody tr.i4c-detail > :is(td, th) {
    grid-column: 1 / -1 !important; display: block !important;
    white-space: normal !important; text-align: left !important;
    padding: 0 !important; overflow: visible !important;
  }
  .i4-stage table.i4c-cards tbody tr.i4c-detail > :is(td, th)::before { content: none !important; }
  .i4-stage table.i4c-cards tbody tr:has(+ tr.i4c-detail:not([style*="none"])) {
    margin-bottom: 0 !important; border-bottom: 0 !important;
    border-bottom-left-radius: 0 !important; border-bottom-right-radius: 0 !important;
  }

  /* 🚨 The heading needs a left inset to clear the absolutely-placed expander, and PADDING cannot
     do it: something loaded after this file pins padding-left on these header cells at 2px, and it
     survives both !important and a doubled-class selector (0,4,4) — measured, not assumed. MARGIN
     is not contested, so the inset is a margin. Without it the trainer's name renders on top of
     the + button. If you ever move this back to padding, check the computed value in a phone
     viewport rather than trusting the rule. */
  .i4-stage table.i4c-cards tbody tr :is(td, th).i4c-head.i4c-head {
    margin-left: 42px !important;
  }
  .i4-stage table.i4c-cards tbody tr.i4c-detail :is(td, th).i4c-head.i4c-head {
    margin-left: 0 !important;
  }

  /* toggle injected for tables that have no expander of their own */
  .i4-stage table.i4c-cards .i4c-tog {
    margin-left: auto; min-width: 32px; min-height: 32px; padding: 0;
    border: 1px solid rgba(255, 255, 255, .18); border-radius: 9px;
    background: rgba(255, 255, 255, .04); color: var(--color-silver, #e8eaed);
    font: 700 15px/1 var(--mono, ui-monospace, monospace);
  }
}

/* ── 9. CLIPPED CONTENT FOUND BY THE 390px SWEEP (2026-09-09) ──────────────────────────────
   Both of these are the failure this file already documents: content wider than its box with no
   way to reach it. Measured with the scrollWidth > clientWidth walk, not guessed. */
@media (max-width: 767px) {
  /* RESULTS: race titles are sponsor-length ("Quooker Tap 100 Degrees Ebf Fillies' Novice…") and
     were truncated to about 100px with 643px of the name unreachable. On a phone the title gets
     to wrap — the row is already card-shaped, so height is cheap and a half-name is not. */
  .i4-stage .rc-rname {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
  }

  /* MARKET TAPE: the price ladder sets its own overflow-x:auto, but it sits in a grid and a grid
     item's automatic minimum size is its CONTENT — so it refused to shrink, overflowed the card by
     328px and never scrolled. min-width:0 is what lets the child shrink and its scroller engage.
     Same root cause as the <select> that pushed a card 106px off-screen. */
  /* the ladder is a GRANDCHILD of .bz8-body, so `> *` never reached it — the automatic minimum
     size propagates down every nested grid/flex level, not just the first. The ladder is one
     unbroken slash-separated string, so it also needs permission to break. */
  .i4-stage .bz8-body div { min-width: 0 !important; }
  .i4-stage .bz8-body { overflow-wrap: anywhere !important; }
  /* The market-tape chart is an SVG pinned to 640px inside a 312px card — 328px of it was simply
     off the edge. It carries viewBox="0 0 900 380", so forcing it to the container scales it
     correctly instead of cropping; without min-width:0 it keeps its intrinsic size and ignores
     the 100% width it already declares. */
  .i4-stage .bz8-body svg {
    width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important;
  }
}

/* ── 10. NAMES WRAP, THEY NEVER TRUNCATE (2026-09-09) ──────────────────────────────────────
   From the 390px sweep of all 31 intel tabs. A stat can be ellipsed without losing meaning; a
   NAME cannot — "Quooker Tap 100 Degrees Ebf Fi…" tells a reader nothing, and the tracker was
   cutting selections by up to 287px. Section 8 keeps value cells on one line deliberately; this
   exempts the cells that carry names.

   The doubled class on .i4c-head is not a typo — see §8: a runtime-injected <style> pins these
   header cells and beats a single-class selector even with !important. */
@media (max-width: 767px) {
  .i4-stage .i4c-cards .i4c-head.i4c-head,
  .i4-stage .i4c-cards .i4c-head.i4c-head > *,
  .i4-stage .i4-trk-tbl .nm,      /* tracker selections — 287px cut on tennis, 219px on F1 */
  .i4-stage .i4-trk-tbl .nm *,    /* the name is wrapped in a span that clips independently */
  .i4-stage .tm,                  /* football results team names — the clip is on the CELL as well
                                     as the link inside it, so both need releasing */
  .i4-stage .tm a,
  .i4-stage .tm span,
  .i4-stage .md,                  /* football tracker match column — 101px cut */
  .i4-stage .md *,
  .i4-stage .wim-mu,              /* tennis form match-up line */
  .i4-stage .tr-pick-sub,         /* tennis results pick sub-line — last 25px in the whole sweep */
  .i4-stage .dd-split {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    min-width: 0 !important;
    overflow-wrap: anywhere !important;   /* long unbroken names must break rather than spill */
  }
}

/* ── 11. ONE BAR, NOT TWO (2026-09-09) ─────────────────────────────────────────────────────
   Measured at 390px: the nav ends at 56, a 2px GOLD .top-bar sits at 56-58, then 19px of dead
   space (.content-wrap's 8px bottom padding + .i4-frame's 8px top margin) before the frame's 3px
   SPORT-COLOURED top border at 77. Two rules and a gap where one rule would do.

   The sport bar takes the gold bar's place and the gap closes — about 21px of a 844px screen
   handed back to actual content, which is most of a card row.

   Mobile only. The gold bar is the brand line on desktop and stays exactly as it is there. */
@media (max-width: 767px) {
  .top-bar { display: none !important; }
  .content-wrap { padding-bottom: 0 !important; }
  main > .i4-frame,
  .i4-frame { margin-top: 0 !important; }
}

/* ── 12. EVERY TAB VISIBLE WITHOUT SCROLLING (2026-09-10) ──────────────────────────────────
   Measured at 390px: .i4-tabs is a nowrap flex row 672px wide inside a 390px window, so BETEB
   SHEET and MARKET TAPE sit off the right edge. They were not loading late — they were never on
   screen. A right-edge fade was added in the 08-21 mobile pass to hint at the scroll, but a hint
   that a tab exists is not the same as being able to see it.

   Wrapping costs one extra row of height and shows all seven. The strip renders in one go about
   1.2s after load (it is built from the tips payload, badge counts and all), so nothing appears
   before then either way — this makes sure that when it does appear, the whole thing is there. */
@media (max-width: 767px) {
  /* ONE ROW, SWIPEABLE — restored 2026-09-11 (see the note above for what was tried before).
     The wrap was not wrong about the problem, only about the remedy: the tabs were undiscoverable
     because the fade never ran outside F1. intel4.js now toggles .i4-more-l / .i4-more-r from the
     real scroll position on every sport, and scrolls the selected tab into view — so the row can
     be a row again. */
  .i4-stage ~ * .i4-tabs,
  .i4-mhead .i4-tabs,
  .i4-tabs {
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    overflow-y: hidden !important;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    justify-content: flex-start !important;
    scrollbar-width: none;                      /* the fade is the scrollbar */
  }
  .i4-tabs::-webkit-scrollbar { display: none !important; }
  .i4-tabs > .i4-tab { flex: 0 0 auto !important; scroll-snap-align: start; }

  /* The fade only appears when there is genuinely more in that direction, because the classes
     are toggled from scrollWidth/scrollLeft rather than assumed. */
  .i4-tabs.i4-more-r { -webkit-mask-image: linear-gradient(90deg, #000 86%, transparent);
                               mask-image: linear-gradient(90deg, #000 86%, transparent); }
  .i4-tabs.i4-more-l { -webkit-mask-image: linear-gradient(270deg, #000 86%, transparent);
                               mask-image: linear-gradient(270deg, #000 86%, transparent); }
  .i4-tabs.i4-more-l.i4-more-r {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
            mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent); }
  /* The fades advertise a horizontal scroll that no longer happens. Suppress them on the BASE
     class: f1-more-r / f1-more-l are toggled by script and were absent when measured, so a rule
     written for those variants left the 28px gradient sitting next to the last tab. */
  .i4-tabs::after,
  .i4-tabs::before,
  .i4-tabs.f1-more-r::after,
  .i4-tabs.f1-more-l::before { display: none !important; content: none !important; }

  /* a little tighter so four fit on the first row rather than three */
  .i4-mhead .i4-tabs .i4-tab,
  .i4-tabs .i4-tab { padding: 9px 12px !important; }
}

/* ── 13. THE TWO SWITCHES ON ONE ROW (2026-09-11) ──────────────────────────────────────────
   .fb-mode-bar wrapped: "Viewing [Club][International]" on one line, "[Men][Women] Club & league
   fixtures" on the next. Its children are already in the right order (lead, scope, gender, hint),
   so this only hides the two labels and stops the wrap — no element moves.

   Both labels were decoration. "Viewing" restates what a pair of switches plainly is, and
   "Club & league fixtures" restates the Club pill sitting right beside it. */
@media (max-width: 767px) {
  .fb-mode-bar {
    flex-wrap: nowrap !important;
    align-items: center !important;
    gap: 8px !important;
    overflow-x: auto !important;
    scrollbar-width: none;
  }
  .fb-mode-bar::-webkit-scrollbar { display: none !important; }
  .fb-mode-bar > * { flex: 0 0 auto !important; }
  .fb-mode-bar .fb-mode-lead,
  .fb-mode-bar .fb-mode-hint { display: none !important; }
}
