/* ── Article/prose content (About page) ───────────────────────────────── */
.content-article { max-width: var(--content-article); margin: 0 auto; }
.content-article h2 { margin-top: 2rem; }
.content-article p, .content-article li { color: var(--ink-2); }
/* Prose links (About page) use the site's win-green instead of the global
   $link-color lavender (theme/tng.scss) — every other link on the site
   already overrides that default with color:inherit or its own token, so
   this is the one place the raw Bootstrap link color was actually visible. */
.content-article a { color: var(--win); }
.content-article a:hover { color: var(--win); text-decoration: underline; }

/* ── Teams landing grid ────────────────────────────────────────────────── */
.teams-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  margin-bottom: 2rem;
}
@media (max-width: 768px) { .teams-grid { grid-template-columns: repeat(2, 1fr); } }

.team-card-wrap { display: contents; }
.team-card {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 0.85rem 1rem;
  color: inherit;
  text-decoration: none;
  transition: border-color 100ms var(--ease-out);
}
.team-card:hover { border-color: var(--line-strong); color: inherit; }
.team-card img { border-radius: 4px; flex-shrink: 0; }
.team-card .tc-text { display: flex; flex-direction: column; min-width: 0; }
.team-card .tc-name { font-family: var(--font-display); font-size: 12px; font-weight: 400; }
.team-card .tc-sub { font-family: var(--font-mono); font-size: 11px; color: var(--ink-muted); margin-top: 0.2rem; }

/* ── Back link (district/team detail pages) ───────────────────────────── */
.back-link {
  display: inline-block;
  font-size: 13px;
  color: var(--ink-muted);
  margin-bottom: 0.75rem;
}

/* ── District prev/next breadcrumb (district detail pages) ──────────────── */
.district-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.75rem;
}
.district-nav-link {
  font-size: 13px;
  color: var(--ink-muted);
  text-decoration: none;
  white-space: nowrap;
}
.district-nav-link:hover { color: var(--ink); text-decoration: underline; }
.district-nav-link.next { margin-left: auto; }

/* ── Week pill nav (Scheds/Scores) ────────────────────────────────────── */
/* Standalone page-to-page links (not a real Bootstrap tabset — each week is
   its own static .qmd page), styled to match the spec's pill tab bar. */
.week-pill-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1.25rem;
}
.week-pill {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 40px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  color: var(--ink-muted);
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  transition: background-color 100ms var(--ease-out), color 100ms var(--ease-out);
}
.week-pill span { font-size: 13px; }
.week-pill:hover { border-color: var(--line-strong); background: var(--bg-paper); color: var(--ink); }
.week-pill.active { background: var(--win); border-color: var(--win); color: #fff; }

/* ── Region pill nav (Standings) ──────────────────────────────────────── */
/* Auto-width single-line pill, not week-pill's fixed 46px circle (sized for
   2-line "Wk/N" content) — "Region I"/"Region III" need to fit on one
   line. Plain HTML/JS toggle rather than a real Quarto `.panel-tabset` —
   see [[gt_asis_style_corruption]]: that Lua filter loses track of tab
   boundaries whenever a chunk inside it uses `output: asis` + cat(), which
   render_region_standings() needs for its per-district empty-state
   handling; the whole tabset collapsed into one long stacked column
   instead of switchable tabs. */
.region-pill-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}
.region-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem 1.1rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  color: var(--ink-muted);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  transition: background-color 100ms var(--ease-out), color 100ms var(--ease-out);
}
.region-pill:hover { border-color: var(--line-strong); background: var(--bg-paper); color: var(--ink); }
.region-pill.active { background: var(--win); border-color: var(--win); color: #fff; }
/* Mobile: shrink padding/font/gap enough that all 4 region pills ("Region
   I".."Region IV") stay on one row instead of "Region IV" wrapping to its
   own second line. */
@media (max-width: 640px) {
  .region-pill-nav { gap: 0.3rem; flex-wrap: nowrap; }
  .region-pill { padding: 0.35rem 0.55rem; font-size: 11px; }
}

/* ── Sched/Scores search + district filter ────────────────────────────── */
.sched-filters {
  display: flex;
  gap: 0.6rem;
  margin-bottom: 1.25rem;
  flex-wrap: wrap;
}
.sched-filters input[type="text"] {
  flex: 1 1 240px;
  padding: 0.45rem 0.75rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 13px;
}
.sched-filters select {
  padding: 0.45rem 0.75rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 13px;
}
.empty-state {
  padding: 2rem 1rem;
  text-align: center;
  color: var(--ink-muted);
  font-size: 0.9rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-md);
}

/* ── Matchup cell (Home GOTW + Sched/Scores build_schedule_table()) ──────── */
/* Away/home render as two stacked flex rows (matchup_side_html(), one call
   per side) instead of one flowing "A @ B" line — team-name length varies
   game to game, so a single line meant "@"/Team B never lined up from row
   to row. Fixed flex slots (at/rank/name/score) give every row the same
   alignment regardless of name length, and reflow/truncate together at
   whatever width the cell gets — no separate mobile-only wrap rule needed. */
/* padding-right opens up breathing room before the TNG Pick column — with
   no score yet (pre-season/pre-kickoff) the row's content falls well short
   of the column's 318px, but once a final score is entered
   margin-left:auto on .matchup-score pushes it flush to the column edge,
   which then sits right up against the adjacent column with no gap at all. */
.matchup-line { display: flex; flex-direction: column; gap: 2px; padding-right: 14px; }
.matchup-side { display: flex; align-items: baseline; gap: 4px; }
.matchup-at {
  flex: 0 0 10px;
  color: var(--ink-subtle);
  font-size: 12px;
}
.matchup-rank {
  flex: 0 0 26px;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 11px;
  color: #E5B467;
}
/* Name + inline Record/Elo share one unit that hugs its own content
   (flex-grow:0) instead of stretching to fill the row — matchup-name alone
   at flex:1 always grew to fill the row's full remaining width regardless
   of how short the actual name was, which stranded Record/Elo flush against
   the score on the far right instead of sitting right next to a short name
   like "Allen". flex-shrink+ellipsis still apply so a very long team name's
   truncation eats into its own Record/Elo first, never the other team's —
   the team name stays the priority content. The score's own margin-left:
   auto (not this unit's flex-grow) is what pushes it to a consistent right
   edge, so the two teams' scores still line up in a column despite name
   length varying. */
.matchup-nameline {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.matchup-name {
  font-size: 13px;
}
/* Record + Elo, inline right after the team name (a leading space is baked
   into matchup_side_html()'s record_html/elo_html) — smaller/gray like the
   rest of the row's secondary info, Elo italic to match combine_rtg()'s
   OVR/Elo badge convention used everywhere else on the site. Absent
   entirely (not "0-0"/na) pre-season or for non-6A opponents, which have
   neither a tracked record nor an Elo. */
.matchup-recelo {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-muted);
}
/* Reserved-width score slot: present (blank) pre-game so the row doesn't
   reflow once a final score is entered. margin-left:auto pushes it flush to
   the row's right edge on its own — regardless of how much (or little) room
   the name/record/elo actually use — so both teams' scores stay aligned in
   a column, prominent and easy to scan down. */
/* font-size bumped from 12px to 14px — once a game is final, the real score
   should read as the headline over GameScore (now shrunk to 11px for final
   games in build_schedule_table()'s text_transform), not the other way
   around. This span is only ever populated with text for final games to
   begin with (blank pregame), so the bump has no effect until a score is
   actually entered. */
.matchup-score {
  flex: 0 0 auto;
  margin-left: auto;
  min-width: 20px;
  text-align: right;
  font-family: var(--font-mono);
  font-size: 14px;
}

/* Mobile: restack the Sched/Scores matchup row into a 2-line card.
   The table's real content (~840px: Date+Matchup+Pick+GameScore laid out
   side by side) is far wider than a phone's usable content width (~325px)
   — the horizontal-scroll shadow cue (see .cell-output-display rules
   above) told users there was more, but Pick/GameScore stayed fully
   off-screen by default (memory: launch_readiness_assessment #2 — "hiding"
   never actually got fixed, only "discoverability" did). Fix: CSS Grid
   reflow of the SAME four <td> cells — gt's `headers="<ColName>"`
   attribute is a stable per-column hook, so no R/template change is
   needed — into a stacked card: Date on its own line, Matchup unchanged
   (full team names/record/Elo, nothing trimmed), then Pick + GameScore
   side by side in a compact strip below. Scoped via
   `:has(td[headers="MatchupHtml"])` so only this exact table (Home GOTW +
   Sched/Scores week pages) is affected — no other gt table on the site
   uses that column name. */
@media (max-width: 640px) {
  table.gt_table:has(td[headers="MatchupHtml"]) thead { display: none; }
  /* <col> width hints only apply under table layout — since tr/td below
     switch to grid, the table itself must fully leave table layout too
     (display:block on table/tbody, colgroup/col suppressed entirely),
     otherwise Chromium still constrains the row to the original column
     tracks and the whole card collapses to the first column's width. */
  /* gt also sets an inline width:0px on the table itself (relies on
     table-layout sizing to expand it) — that becomes literally 0 width
     once display:block applies, so it needs an explicit override too. */
  table.gt_table:has(td[headers="MatchupHtml"]) { display: block !important; width: 100% !important; }
  table.gt_table:has(td[headers="MatchupHtml"]) tbody { display: block !important; }
  table.gt_table:has(td[headers="MatchupHtml"]) colgroup,
  table.gt_table:has(td[headers="MatchupHtml"]) col { display: none; }
  table.gt_table:has(td[headers="MatchupHtml"]) tbody tr {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "date  date"
      "match match"
      "pick  gs";
    column-gap: 8px;
    row-gap: 2px;
    padding: 10px;
    margin-bottom: 8px;
    box-sizing: border-box;
    /* One clean border per game card, nothing internal — no striping,
       no row dividers, no dashed strip separator (all of those read as
       hard rectangular blocks once a "row" is this tall). */
    border: 1px solid var(--line-strong) !important;
    border-radius: var(--radius-md) !important;
    background-color: transparent !important;
  }
  table.gt_table:has(td[headers="MatchupHtml"]) tbody tr:last-child { margin-bottom: 0; }
  table.gt_table:has(td[headers="MatchupHtml"]) td {
    /* gt's table_body.hlines styling puts its own border-top on every
       cell (independent of the card border above) — since DateFmt is the
       first cell in each card, that hline reads as a stray line directly
       above the date, and the next cell's hline reads as one directly
       below it. Neutralize both edges on every cell so the card border
       is the only line anywhere. */
    border-top: none !important;
    border-bottom: none !important;
    background-color: transparent !important;
    padding: 0 !important;
    margin: 0 !important;
  }
  table.gt_table:has(td[headers="MatchupHtml"]) td[headers="DateFmt"] {
    grid-area: date;
    font-size: 10px !important;
  }
  table.gt_table:has(td[headers="MatchupHtml"]) td[headers="MatchupHtml"] { grid-area: match; }
  table.gt_table:has(td[headers="MatchupHtml"]) td[headers="PickHtml"] {
    grid-area: pick;
    font-size: 11px;
    padding-top: 6px !important;
  }
  table.gt_table:has(td[headers="MatchupHtml"]) td[headers="GameScore"] {
    grid-area: gs;
    font-size: 11px;
    text-align: right;
    white-space: nowrap;
    padding-top: 6px !important;
  }
  /* Drop the pick's small logo chip — team name + inline label already
     identify it; targets logo_badge()'s fixed #3A4150 chip background
     rather than DOM position, so it still works if PickHtml's markup
     order ever changes. */
  table.gt_table:has(td[headers="MatchupHtml"]) td[headers="PickHtml"] span[style*="background:#3A4150"] {
    display: none !important;
  }
  /* Pick's team name (font-size:13px) and win%/edge (font-size:12px) both
     carry their own inline font-size from build_schedule_table() — the
     td-level font-size above doesn't cascade over an explicit inline
     value, so both need a direct !important override to actually shrink
     (this is what stops "89% (+20)" from wrapping to its own line).
     team_name_html() renders an <a> for 6A teams but a plain <span> for
     non-6A opponents with no team page to link to (e.g. Iowa Colony,
     Pflugerville Weiss) — target the shared inline style substring
     ("font-weight:600") instead of the tag, so both cases get caught. */
  table.gt_table:has(td[headers="MatchupHtml"]) td[headers="PickHtml"] [style*="font-weight:600"] {
    font-size: 11px !important;
  }
  table.gt_table:has(td[headers="MatchupHtml"]) td[headers="PickHtml"] > span:last-child {
    font-size: 10px !important;
  }
  /* Inline mini-labels since the shared column header ("TNG Pick"/"Game
     Score") no longer sits above these cells once stacked into a card. */
  table.gt_table:has(td[headers="MatchupHtml"]) td[headers="PickHtml"]::before {
    content: "PICK ";
    font-size: 9px; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-subtle);
  }
  table.gt_table:has(td[headers="MatchupHtml"]) td[headers="GameScore"]::before {
    content: "GAMESCORE ";
    font-size: 9px; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-subtle);
  }
}

/* ── Team page: Historical Performance Elo chart, desktop/mobile swap ──────
   Two separate images (site/teams/_template.qmd, elo-history-chart-desktop/
   -mobile chunks) rather than one image scaled responsively — a naive scale-
   down of the wide 9.3x3.2in desktop chart to ~340px mobile width shrank
   axis/tier text below legibility (memory: team_history_chart_flagged).
   The mobile chunk renders its own near-square canvas with larger relative
   font sizes instead, tagged via knitr's `out-extra` chunk option. */
.elo-chart-mobile { display: none; }
@media (max-width: 640px) {
  .elo-chart-desktop { display: none; }
  .elo-chart-mobile { display: block; width: 100%; height: auto; }
}

/* ── Rankings table (build_rankings_table()), mobile column-hiding ─────────
   rankings.qmd + Home Top 10 + standings.qmd's per-Region "Top 10" table —
   up to ~100 rows, meant to be scanned quickly by rank order, so it keeps
   the real single-line row shape and just hides the secondary stat columns
   below 640px (Dist/Proj, Record, SOS, PPG, PAPG, Last/This Wk), leaving
   Rank + logo + Team + OVR/Elo always visible. A multi-line card per row
   (like the tables below get) would turn a 100-row list into thousands of
   px of scroll — column-hiding is the right tradeoff here specifically
   because of the row count, not a general rule. Every hidden column is
   still reachable via the existing horizontal-scroll affordance. Scoped
   via combortg, this builder's unique OVR/Elo column name. */
@media (max-width: 640px) {
  table.gt_table:has(td[headers="combortg"]) td[headers="combodist"],
  table.gt_table:has(td[headers="combortg"]) th[id="Dist / Proj"],
  table.gt_table:has(td[headers="combortg"]) td[headers="Record"],
  table.gt_table:has(td[headers="combortg"]) th[id="Record"],
  table.gt_table:has(td[headers="combortg"]) td[headers="comboSOS"],
  table.gt_table:has(td[headers="combortg"]) th[id="SOS"],
  table.gt_table:has(td[headers="combortg"]) td[headers="TotalPPG"],
  table.gt_table:has(td[headers="combortg"]) th[id="PPG"],
  table.gt_table:has(td[headers="combortg"]) td[headers="TotalPAPG"],
  table.gt_table:has(td[headers="combortg"]) th[id="PAPG"],
  table.gt_table:has(td[headers="combortg"]) td[headers="LastWk"],
  table.gt_table:has(td[headers="combortg"]) th[id="Last Wk"],
  table.gt_table:has(td[headers="combortg"]) td[headers="ThisWk"],
  table.gt_table:has(td[headers="combortg"]) th[id="This Wk"] {
    display: none !important;
  }
  /* Hiding the <td>/<th> cells alone doesn't shrink the table — <colgroup>
     <col> sizing hints still reserve each hidden column's width regardless
     of cell visibility (same mechanism encountered on the matchup table).
     The 7 hidden columns are one contiguous run, the 6th column onward. */
  table.gt_table:has(td[headers="combortg"]) colgroup col:nth-child(n+6) {
    display: none !important;
  }
  /* Even with the trailing 7 columns gone, the 5 kept columns' desktop
     widths (tuned to fit a ~880px page, not a ~324px phone) still add up
     to more than the viewport. Trim Team-name/OVR-Elo (the two with real
     slack — combortg is just a 2-line stacked number, doesn't need 65px)
     down to fit the ~26+28+34=88px of fixed-width columns into the ~324px
     budget. Team names wrap to a 2nd line more often as a result —
     acceptable on mobile, matches [[feedback_wrap_not_truncate]]. */
  table.gt_table:has(td[headers="combortg"]) colgroup col:nth-child(4) { width: 165px !important; }
  table.gt_table:has(td[headers="combortg"]) colgroup col:nth-child(5) { width: 56px !important; }
}

/* ── EloRk column: 3-digit ranks (100+) clipping at the right edge ──────────
   Every EloRk column (build_standings_table's small italic global rank AND
   build_rankings_table's primary "Rk" column) is budgeted at a tight 26-32px
   column width against gt's shared 6px data_row.padding — fine for 1-2
   digits but a 3-digit rank has no room left after 12px of padding eats
   into it. Applies at every viewport, not just mobile: the desktop
   Rankings/Top 100 table is right at its ~880px column-width budget, so
   widening the column itself risks a horizontal-scroll regression instead;
   tightening this one column's padding is the lower-risk fix. */
table.gt_table td[headers="EloRk"],
table.gt_table th#EloRk {
  padding-left: 2px !important;
  padding-right: 2px !important;
}

/* ── District Standings table (build_standings_table()), mobile card ───────
   standings.qmd, districts pages, Home District Standings, Team page
   widget — unlike the Rankings table above, a district never has more than
   ~8 qualifying teams, so a per-team card (same reasoning as the Team
   Schedule & Results / Team Performance History tables) fits comfortably
   instead of needing lean column-hiding. Card: Rank + Team on their own
   line (logo and the small italic global EloRk dropped — Team name/
   district rank alone already carries the "at a glance" identity), then
   OVR/Elo + Rec(Overall) + Dist(District) on one 3-up stat line, then
   ProjRec/PO%/Bracket on a second 3-up line. Labels are injected via CSS
   ::before (not a cols_label() change) so the desktop header text and the
   Substack PNG export stay untouched — only this mobile card gets the
   shortened "REC"/"DIST" wording. Scoped via combo_rtg, this builder's
   unique OVR/Elo column name. */
@media (max-width: 640px) {
  table.gt_table:has(td[headers="combo_rtg"]) thead { display: none; }
  table.gt_table:has(td[headers="combo_rtg"]) { display: block !important; width: 100% !important; }
  table.gt_table:has(td[headers="combo_rtg"]) tbody { display: block !important; }
  table.gt_table:has(td[headers="combo_rtg"]) colgroup,
  table.gt_table:has(td[headers="combo_rtg"]) col { display: none; }
  table.gt_table:has(td[headers="combo_rtg"]) tbody tr {
    display: grid !important;
    /* 12 columns (not 6) so rank/logo can each take a narrow 1/12 share —
       at 6 columns they got a full 1/6 (~57px) despite the content ("#1",
       a 20px logo) needing barely half that, leaving a visible dead gap
       before the team name. Stat rows still split evenly (4 columns = 1/3
       each), unchanged from before. */
    grid-template-columns: repeat(12, 1fr);
    grid-template-areas:
      "rk    logo  team  team  team  team  team  team  team  team  team  team"
      "ovr   ovr   ovr   ovr   rec   rec   rec   rec   dist  dist  dist  dist"
      "proj  proj  proj  proj  po    po    po    po    brk   brk   brk   brk";
    column-gap: 4px;
    align-items: center;
    row-gap: 4px;
    padding: 10px;
    margin-bottom: 8px;
    box-sizing: border-box;
    border: 1px solid var(--line-strong) !important;
    border-radius: var(--radius-md) !important;
    background-color: transparent !important;
  }
  table.gt_table:has(td[headers="combo_rtg"]) tbody tr:last-child { margin-bottom: 0; }
  table.gt_table:has(td[headers="combo_rtg"]) td {
    border-top: none !important;
    border-bottom: none !important;
    background-color: transparent !important;
    padding: 0 !important;
    margin: 0 !important;
    font-size: 11px;
    text-align: center !important;
  }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="EloRk"],
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="TotalPPG"],
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="TotalPAPG"] {
    display: none !important;
  }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="DistRank"] {
    grid-area: rk;
    text-align: left !important;
    font-size: 13px;
    font-weight: 600;
  }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="DistRank"]::before { content: "#"; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="Local_Logo"] {
    grid-area: logo;
    display: block !important;
    text-align: left !important;
  }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="combo_team_enr"] {
    grid-area: team;
    text-align: left !important;
    font-size: 13px;
  }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="combo_rtg"] { grid-area: ovr; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ovrrec"]   { grid-area: rec; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="distrec"]  { grid-area: dist; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ProjRec"]  { grid-area: proj; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="POOddsHtml"] { grid-area: po; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ProjBracket"] { grid-area: brk; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ovrrec"],
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="distrec"],
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="combo_rtg"] {
    padding-top: 6px !important;
    border-top: 1px solid var(--line-hairline) !important;
  }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ProjRec"],
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="POOddsHtml"],
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ProjBracket"] {
    padding-top: 6px !important;
  }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="combo_rtg"]::before { content: "OVR/ELO"; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ovrrec"]::before    { content: "REC"; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="distrec"]::before   { content: "DIST"; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ProjRec"]::before   { content: "PROJ REC"; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="POOddsHtml"]::before { content: "PO%"; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ProjBracket"]::before { content: "BRACKET"; }
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="combo_rtg"]::before,
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ovrrec"]::before,
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="distrec"]::before,
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ProjRec"]::before,
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="POOddsHtml"]::before,
  table.gt_table:has(td[headers="combo_rtg"]) td[headers="ProjBracket"]::before {
    display: block;
    font-size: 8px; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-subtle);
  }
}

/* ── Team page: Schedule & Results table, mobile card reflow ───────────────
   build_team_schedule_table() (7 cols, ~765px: Wk/Opponent/Proj WP%/Result/
   Perf/WQ/LQ). Unlike the Rankings/Standings family above, this is a
   per-GAME list (max ~17 rows incl. playoffs, not a 100-row ranked list) —
   same reasoning as the original Sched/Scores matchup table, so it gets the
   same card-reflow treatment rather than column-hiding: Week on its own
   line, Opponent unchanged (full name/record/Elo, matchup_side_html — same
   markup this table already shares with the matchup table), then a 5-up
   stats strip (WP% / Result / Perf / WQ / LQ) below. Scoped via the
   Opponent column's real name (OppHtml, unique to this builder). */
@media (max-width: 640px) {
  table.gt_table:has(td[headers="OppHtml"]) thead { display: none; }
  table.gt_table:has(td[headers="OppHtml"]) { display: block !important; width: 100% !important; }
  table.gt_table:has(td[headers="OppHtml"]) tbody { display: block !important; }
  table.gt_table:has(td[headers="OppHtml"]) colgroup,
  table.gt_table:has(td[headers="OppHtml"]) col { display: none; }
  table.gt_table:has(td[headers="OppHtml"]) tbody tr {
    display: grid !important;
    grid-template-columns: repeat(5, 1fr);
    grid-template-areas:
      "wk     wk     wk     wk     wk"
      "opp    opp    opp    opp    opp"
      "wp     result perf   wq     lq";
    row-gap: 4px;
    padding: 10px;
    margin-bottom: 8px;
    box-sizing: border-box;
    border: 1px solid var(--line-strong) !important;
    border-radius: var(--radius-md) !important;
    background-color: transparent !important;
  }
  table.gt_table:has(td[headers="OppHtml"]) tbody tr:last-child { margin-bottom: 0; }
  table.gt_table:has(td[headers="OppHtml"]) td {
    border-top: none !important;
    border-bottom: none !important;
    background-color: transparent !important;
    padding: 0 !important;
    margin: 0 !important;
    font-size: 12px;
  }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="Week"] {
    grid-area: wk;
    font-size: 10px;
    color: var(--ink-subtle);
  }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="Week"]::before { content: "WK "; }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="OppHtml"] { grid-area: opp; }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="WPHtml"],
  table.gt_table:has(td[headers="OppHtml"]) td[headers="ResultHtml"],
  table.gt_table:has(td[headers="OppHtml"]) td[headers="PerfFmt"],
  table.gt_table:has(td[headers="OppHtml"]) td[headers="WQFmt"],
  table.gt_table:has(td[headers="OppHtml"]) td[headers="LQFmt"] {
    text-align: center;
    padding-top: 6px !important;
    border-top: 1px solid var(--line-hairline) !important;
  }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="WPHtml"] { grid-area: wp; }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="ResultHtml"] { grid-area: result; }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="PerfFmt"] { grid-area: perf; }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="WQFmt"] { grid-area: wq; }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="LQFmt"] { grid-area: lq; }
  /* Every stat cell's inline style (mono font-size:12px on WPHtml/
     ResultHtml, plain text on PerfFmt/WQFmt/LQFmt) still needs its own
     shrink so "69% (+8)" / "W 42-10" don't wrap inside their ~65px share
     of the 5-column stats strip — matching the matchup table's PickHtml
     fix, td-level font-size doesn't cascade over an inline value. */
  table.gt_table:has(td[headers="OppHtml"]) td[headers="WPHtml"] span,
  table.gt_table:has(td[headers="OppHtml"]) td[headers="ResultHtml"] span {
    font-size: 10px !important;
  }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="WPHtml"]::before { content: "WP%"; }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="ResultHtml"]::before { content: "RESULT"; }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="PerfFmt"]::before { content: "PERF"; }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="WQFmt"]::before { content: "WQ"; }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="LQFmt"]::before { content: "LQ"; }
  table.gt_table:has(td[headers="OppHtml"]) td[headers="WPHtml"]::before,
  table.gt_table:has(td[headers="OppHtml"]) td[headers="ResultHtml"]::before,
  table.gt_table:has(td[headers="OppHtml"]) td[headers="PerfFmt"]::before,
  table.gt_table:has(td[headers="OppHtml"]) td[headers="WQFmt"]::before,
  table.gt_table:has(td[headers="OppHtml"]) td[headers="LQFmt"]::before {
    display: block;
    font-size: 9px; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-subtle);
  }
}

/* ── Team page: Team Performance History table, mobile card reflow ────────
   build_season_log_table() (15 cols, ~878px: Year/Record/FinalElo/PPG/PAPG/
   Margin/EloSOS/AOS/ADS/DOM/Perf/RQ/WQ/LQ/All-Time Rating). Per-YEAR list
   (max ~22 rows, 2004-present), same reasoning as the matchup and Schedule
   & Results tables — card reflow, not column-hiding. Year becomes the card
   header, then two 6-up stat rows (Record/Elo/PPG/PAPG/Margin/EloSOS, then
   AOS/ADS/DOM/Perf/RQ/All-Time Rating); WQ/LQ are dropped from this compact
   view entirely (still in the full desktop table). Scoped via the AOS
   column (unique to this builder — matchup/schedule tables have no AOS
   column). */
@media (max-width: 640px) {
  table.gt_table:has(td[headers="AOS"]) thead { display: none; }
  table.gt_table:has(td[headers="AOS"]) { display: block !important; width: 100% !important; }
  table.gt_table:has(td[headers="AOS"]) tbody { display: block !important; }
  table.gt_table:has(td[headers="AOS"]) colgroup,
  table.gt_table:has(td[headers="AOS"]) col { display: none; }
  table.gt_table:has(td[headers="AOS"]) tbody tr {
    display: grid !important;
    grid-template-columns: repeat(6, 1fr);
    grid-template-areas:
      "yr     yr     yr     yr     yr     yr"
      "rec    elo    ppg    papg   margin sos"
      "aos    ads    dom    perf   rq     rtg";
    row-gap: 4px;
    padding: 10px;
    margin-bottom: 8px;
    box-sizing: border-box;
    border: 1px solid var(--line-strong) !important;
    border-radius: var(--radius-md) !important;
    background-color: transparent !important;
  }
  table.gt_table:has(td[headers="AOS"]) tbody tr:last-child { margin-bottom: 0; }
  table.gt_table:has(td[headers="AOS"]) td {
    border-top: none !important;
    border-bottom: none !important;
    background-color: transparent !important;
    padding: 0 !important;
    margin: 0 !important;
    font-size: 11px;
    text-align: center !important;
  }
  table.gt_table:has(td[headers="AOS"]) td[headers="Year"] {
    grid-area: yr;
    text-align: left !important;
    font-size: 13px;
    font-weight: 600;
  }
  table.gt_table:has(td[headers="AOS"]) td[headers="Record"]   { grid-area: rec; }
  table.gt_table:has(td[headers="AOS"]) td[headers="FinalElo"] { grid-area: elo; }
  table.gt_table:has(td[headers="AOS"]) td[headers="PPG"]      { grid-area: ppg; }
  table.gt_table:has(td[headers="AOS"]) td[headers="PAPG"]     { grid-area: papg; }
  table.gt_table:has(td[headers="AOS"]) td[headers="Margin"]   { grid-area: margin; }
  table.gt_table:has(td[headers="AOS"]) td[headers="EloSOS"]   { grid-area: sos; }
  table.gt_table:has(td[headers="AOS"]) td[headers="AOS"]      { grid-area: aos; }
  table.gt_table:has(td[headers="AOS"]) td[headers="ADS"]      { grid-area: ads; }
  table.gt_table:has(td[headers="AOS"]) td[headers="DOM"]      { grid-area: dom; }
  table.gt_table:has(td[headers="AOS"]) td[headers="Perf"]     { grid-area: perf; }
  table.gt_table:has(td[headers="AOS"]) td[headers="RQ"]       { grid-area: rq; }
  table.gt_table:has(td[headers="AOS"]) td[headers="AllTimeHtml"] { grid-area: rtg; }
  table.gt_table:has(td[headers="AOS"]) td[headers="WQ"],
  table.gt_table:has(td[headers="AOS"]) td[headers="LQ"] {
    display: none !important;
  }
  table.gt_table:has(td[headers="AOS"]) td[headers="Record"]::before   { content: "REC"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="FinalElo"]::before { content: "ELO"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="PPG"]::before      { content: "PPG"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="PAPG"]::before     { content: "PAPG"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="Margin"]::before   { content: "MARGIN"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="EloSOS"]::before   { content: "SOS"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="AOS"]::before      { content: "AOS"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="ADS"]::before      { content: "ADS"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="DOM"]::before      { content: "DOM"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="Perf"]::before     { content: "PERF"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="RQ"]::before       { content: "RQ"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="AllTimeHtml"]::before { content: "RATING"; }
  table.gt_table:has(td[headers="AOS"]) td[headers="Record"]::before,
  table.gt_table:has(td[headers="AOS"]) td[headers="FinalElo"]::before,
  table.gt_table:has(td[headers="AOS"]) td[headers="PPG"]::before,
  table.gt_table:has(td[headers="AOS"]) td[headers="PAPG"]::before,
  table.gt_table:has(td[headers="AOS"]) td[headers="Margin"]::before,
  table.gt_table:has(td[headers="AOS"]) td[headers="EloSOS"]::before,
  table.gt_table:has(td[headers="AOS"]) td[headers="AOS"]::before,
  table.gt_table:has(td[headers="AOS"]) td[headers="ADS"]::before,
  table.gt_table:has(td[headers="AOS"]) td[headers="DOM"]::before,
  table.gt_table:has(td[headers="AOS"]) td[headers="Perf"]::before,
  table.gt_table:has(td[headers="AOS"]) td[headers="RQ"]::before,
  table.gt_table:has(td[headers="AOS"]) td[headers="AllTimeHtml"]::before {
    display: block;
    font-size: 8px; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-subtle);
  }
  /* AllTimeHtml's percentile span carries its own inline font-size/margin
     — small enough already, just drop the left-margin so "855"/"(99th)"
     can wrap onto their own centered lines instead of pushing past this
     cell's ~54px share of the 6-column grid. */
  table.gt_table:has(td[headers="AOS"]) td[headers="AllTimeHtml"] span {
    margin-left: 0 !important;
  }
}

/* ── Jump nav (standings page) ────────────────────────────────────────── */
.jump-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-bottom: 2rem;
  font-size: 0.8rem;
}

.jump-nav a {
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--line-strong);
  border-radius: 0.25rem;
  color: var(--ink-2);
  text-decoration: none;
}

.jump-nav a:hover { background: var(--bg-paper); }

/* ── District directory ───────────────────────────────────────────────── */
.district-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  margin-bottom: 2rem;
}

@media (max-width: 992px) { .district-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 576px) { .district-grid { grid-template-columns: 1fr; } }

/* Wrapper exists only so pandoc treats the card as a raw HTML block (see
   build_district_card() comment) — remove it from the box tree so
   .district-card is still the direct, sized grid item. */
.district-card-wrap { display: contents; }

/* Whole card is the link (spec: team names inside are NOT individually
   clickable — that was tried and reverted). */
.district-card {
  display: block;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 0.9rem 1rem;
  font-size: 0.85rem;
  color: inherit;
  text-decoration: none;
  transition: border-color 100ms var(--ease-out);
}
.district-card:hover { border-color: var(--line-strong); color: inherit; }

.district-card h4 {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  margin: 0 0 0.6rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--line);
}
.district-card ul { list-style: none; padding: 0; margin: 0; }
.district-card li { display: flex; align-items: center; gap: 0.4rem; padding: 0.2rem 0; font-size: 12px; }
.district-card li img { border-radius: 3px; flex-shrink: 0; }
.district-card .dc-empty { color: var(--ink-subtle); font-style: italic; font-size: 12px; margin: 0; }

/* ── Team page: header band ───────────────────────────────────────────── */
.team-header-row {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  margin: 0.5rem 0 1.5rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--line);
}
@media (max-width: 640px) {
  .team-header-row { flex-direction: column; align-items: flex-start; gap: 1rem; }
}

.team-logo-lg-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 88px; height: 88px; border-radius: var(--radius-md);
  background: #3A4150; flex-shrink: 0;
}
.team-logo-lg { width: 74px; height: 74px; object-fit: contain; }
@media (max-width: 640px) {
  .team-logo-lg-badge { width: 64px; height: 64px; }
  .team-logo-lg { width: 54px; height: 54px; }
}

.team-header-text { flex: 1 1 auto; min-width: 0; }
.team-class-line {
  font-family: var(--font-ui);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
}
.team-name-h1 {
  font-size: 52px;
  line-height: 1.05;
  margin: 6px 0 4px;
}
@media (max-width: 640px) { .team-name-h1 { font-size: 32px; } }
.team-name-h1 .mascot { font-style: italic; font-weight: 400; }
.team-enroll-line { font-family: var(--font-mono); font-size: 11px; color: var(--ink-muted); }

.team-stat-trio { display: flex; gap: 2rem; flex-shrink: 0; }
.team-stat-trio .tst-item { text-align: right; }
@media (max-width: 640px) {
  .team-stat-trio { width: 100%; justify-content: space-between; gap: 0.5rem; }
  .team-stat-trio .tst-item { text-align: left; }
}
.team-stat-trio .tst-label {
  font-family: var(--font-ui);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
}
.team-stat-trio .tst-value { font-family: var(--font-display); font-size: 28px; font-weight: 700; line-height: 1.2; }
.team-stat-trio .tst-sub { font-family: var(--font-mono); font-size: 11px; color: var(--ink-muted); }

/* ── Team page: grade cards ───────────────────────────────────────────── */
.grade-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.75rem;
  margin-bottom: 2rem;
}
@media (max-width: 640px) { .grade-cards { grid-template-columns: repeat(2, 1fr); } }
.grade-card {
  background: var(--bg-paper);
  border-radius: var(--radius-md);
  padding: 1rem 0.75rem;
  text-align: center;
}
.grade-card .gc-label {
  font-family: var(--font-ui);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  margin-bottom: 0.3rem;
}
.grade-card .gc-value { font-size: 1.6rem; }
.grade-card .gc-rank { font-family: var(--font-mono); font-size: 11px; color: var(--ink-muted); margin-top: 0.2rem; }

/* ── Team page: historical performance ────────────────────────────────── */
.history-section-head { border-top: 1px solid var(--line); padding-top: 1.5rem; margin-top: 2.5rem; }
.history-section-head h2 { margin-top: 0.3rem; }
.history-section-head h3 { font-size: 1rem; margin: 2rem 0 0.75rem; }

.chart-note {
  font-family: var(--font-ui);
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--ink-muted);
  text-align: center;
  margin: 0.25rem auto 1.5rem;
  max-width: 720px;
}

.col-glossary {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem 1.5rem;
  margin: 0.75rem 0 2rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
}
@media (max-width: 768px) { .col-glossary { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .col-glossary { grid-template-columns: 1fr; } }
.col-glossary .cg-item {
  font-family: var(--font-ui);
  font-size: 11px;
  line-height: 1.45;
  color: var(--ink-muted);
}
.col-glossary .cg-item strong { color: var(--ink-subtle); font-weight: 700; }

.season-cards {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.75rem;
  margin: 1.5rem 0 2rem;
}
@media (max-width: 768px) { .season-cards { grid-template-columns: 1fr; } }
.season-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 0.9rem 0.75rem;
  text-align: center;
}
.season-card .sc-rank { font-family: var(--font-ui); font-size: 11px; color: var(--ink-muted); margin-bottom: 0.35rem; }
.season-card .sc-record { font-family: var(--font-mono); font-size: 1.3rem; font-weight: 700; }
.season-card .sc-elo { font-family: var(--font-mono); font-size: 11px; color: var(--win); margin-top: 0.3rem; }

/* ── H2H matrix ───────────────────────────────────────────────────────── */
.h2h-table { font-size: 0.82rem; overflow-x: auto; margin-bottom: 2rem; }
.h2h-table table { min-width: 400px; }

/* ── Playoff round odds ───────────────────────────────────────────────── */
.round-bars {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0.5rem;
  margin-bottom: 2rem;
  font-size: 0.8rem;
  text-align: center;
}

@media (max-width: 576px) { .round-bars { grid-template-columns: repeat(3, 1fr); } }

.round-bar-cell .round-label {
  color: var(--ink-muted);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.round-bar-cell .round-pct { font-size: 1.2rem; font-weight: 700; }

/* ── Nav pills (Week / Region / District tabs) ────────────────────────── */
/* Quarto's .panel-tabset renders Bootstrap underline nav-tabs by default;   */
/* spec wants pill buttons — active = filled --win, inactive = outlined     */
/* muted, 100ms background transition only, no purple/violet accent.        */
.nav-tabs {
  border-bottom: none;
  gap: 0.4rem;
  flex-wrap: wrap;
}
.nav-tabs .nav-link {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-muted);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  padding: 0.3rem 0.85rem;
  margin: 0;
  transition: background-color 100ms var(--ease-out), color 100ms var(--ease-out);
}
.nav-tabs .nav-link:hover,
.nav-tabs .nav-link:focus {
  color: var(--ink);
  border-color: var(--line-strong);
  background-color: var(--bg-paper);
  isolation: isolate;
}
.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link {
  color: #fff;
  background-color: var(--win);
  border-color: var(--win);
}
/* Bootstrap's compiled CSS puts a left/right/bottom border on .tab-content
   by default (using this theme's own border-color Sass variable, which is
   why it was easy to miss — it reads as "our" hairline, not an obvious
   Bootstrap default) — that's the box that was outlining the whole
   Region/District nav pane section, distinct from the pill buttons'
   individual borders (kept — see .nav-tabs .nav-link above). */
.tab-content { background-color: transparent; padding-top: 1.25rem; border: none; }

/* ── Section head (Home + other section-based pages) ─────────────────── */
/* Section titles render as serif h2s per spec; the "head" wrapper just  */
/* provides the sub-label + right-aligned "Full X →" link row above it.  */
.home-section { margin-bottom: var(--space-8); }
@media (max-width: 640px) { .home-section { margin-bottom: var(--space-7); } }

.home-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-2);
}

.home-section-head h2 {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 700;
  margin: 0;
}

.home-section-head a { font-size: 13px; color: var(--ink-muted); white-space: nowrap; }
.home-section-sub { font-size: 13px; color: var(--ink-muted); margin: 0 0 var(--space-4); }
@media (max-width: 576px) {
  .home-section-head { flex-direction: column; align-items: flex-start; gap: 0.25rem; }
}

/* ── Top nav: align width to page content, tighten link size ─────────── */
.navbar-container.container-fluid {
  max-width: 880px;
  margin-inline: auto;
  padding-inline: 0;
}
.navbar-nav .nav-link { font-size: 14px; }

/* Empty title-block (every page sets title: "" and uses pagetitle instead)
   still reserves its default margin-bottom — kills that dead strip between
   the fixed navbar and each page's first real content row. */
#title-block-header:empty { display: none; margin: 0; }

/* ── Identity strip (Home) ────────────────────────────────────────────── */
/* Quarto's own main.content ships a ~17px top margin site-wide — scoped via
   :has() to just the page carrying .identity-strip (Home) rather than
   overriding it globally, so every other page's top spacing is untouched. */
main.content:has(.identity-strip) { margin-top: 6px !important; }
.identity-strip {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-5);
  margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--line-hairline);
}
.identity-strip .id-left { font-family: var(--font-ui); font-size: 13px; color: var(--ink-muted); }
.identity-strip .id-right { font-family: var(--font-mono); font-size: 12px; color: var(--ink-subtle); white-space: nowrap; }
@media (max-width: 576px) {
  .identity-strip { flex-direction: column; align-items: flex-start; gap: 0.35rem; }
}

/* ── Efficiency Leaders two-column grid ───────────────────────────────── */
.aos-ads-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-6); }
@media (max-width: 768px) { .aos-ads-grid { grid-template-columns: 1fr; gap: var(--space-5); } }
.aos-ads-grid h3 { font-family: var(--font-ui); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-muted); margin: 0 0 var(--space-3); }
