/* bracket.css — public page: tabs, bracket layout, round view, team view */

/* ── Update notification bar ── */
.update-bar {
  background: var(--blue);
  color: #fff;
  text-align: center;
  padding: 0.35em 1em;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.04em;
  position: sticky;
  top: var(--hdr-h, 0px);
  z-index: 95;
  flex-shrink: 0;
}

/* ── Offline notice banner (fetch failed; last-good data shown) ── */
.offline-notice {
  background: color-mix(in srgb, var(--lose-color) 14%, transparent);
  border-bottom: 0.08em solid color-mix(in srgb, var(--lose-color) 45%, transparent);
  color: var(--lose-color);
  text-align: center;
  padding: 0.55em 1em;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-sm);
  font-weight: 600;
  flex-shrink: 0;
}

/* ── Weather / delay notice banner ── */
.delay-notice {
  background: color-mix(in srgb, var(--gold) 14%, transparent);
  border-bottom: 0.08em solid color-mix(in srgb, var(--gold) 45%, transparent);
  color: var(--gold-lt);
  text-align: center;
  padding: 0.55em 1em;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-sm);
  font-weight: 600;
  flex-shrink: 0;
}

/* ── Tabs ── */
.view-tabs {
  display: flex;
  background: var(--surface);
  border-bottom: 0.07em solid var(--border);
  position: sticky;
  top: calc(var(--hdr-h, 0px) + var(--bar-h, 0px));
  z-index: 90;
}
.view-tab {
  flex: 1;
  text-align: center;
  padding: 0.85em 0.3em;
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-md);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  cursor: pointer;
  border-bottom: 0.18em solid transparent;
  transition: all 0.15s;
  min-height: 3em;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3em;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.tab-icon {
  width: 1.4em; height: 1.4em;
  flex-shrink: 0;
  display: none; /* shown only on mobile via media query */
}
.tab-label { line-height: 1; }
.view-tab.active { color: var(--blue-lt); border-bottom-color: var(--blue-lt); }
.view-tab:active { background: color-mix(in srgb, var(--text) 5%, transparent); }

/* ── Panels ── */
.view-panel { display: none; }
.view-panel.active { display: block; }

/* ── Selectors ── */
.selector-row {
  position: sticky;
  top: calc(var(--hdr-h, 0px) + var(--bar-h, 0px) + var(--tabs-h, 0px));
  z-index: 80;
  background: var(--surface);
  border-bottom: 0.15em solid var(--blue);
  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
}
.selector-inner {
  max-width: 65em;
  margin: 0 auto;
  padding: 0.8em 1em;
  display: flex;
  gap: 0.6em;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
}

/* ── Bucket Challenge leaderboard ── */
.bucket-status-wrap {
  flex-shrink: 0;
  padding: 0.9em 1em 0;
}
.bucket-status-bar {
  background: var(--surface2);
  border: 0.07em solid var(--border);
  border-radius: var(--radius-sm);
  text-align: center;
  padding: 0.55em 1.5em;
  font-family: 'Barlow', sans-serif;
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.03em;
  color: var(--text-dim);
}
.bucket-panel {
  max-width: 42em;
  margin: 0 auto;
  padding: 0.35em 1em 3em;
}
.bucket-leaderboard {
  display: flex;
  flex-direction: column;
  gap: 0.35em;
}
.bucket-row {
  display: flex;
  align-items: center;
  gap: 0.75em;
  background: var(--surface);
  border: 0.07em solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.75em 1em;
}
.bucket-rank {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--text-mute);
  min-width: 1.8em;
  text-align: center;
}
/* Medal backgrounds for top-3 rows */
.bucket-row--1 {
  background: var(--medal-gold-bg);
  border-color: var(--medal-gold-border);
}
.bucket-row--1 .bucket-rank,
.bucket-row--1 .bucket-team-name,
.bucket-row--1 .bucket-count { color: var(--medal-gold-text); }

.bucket-row--2 {
  background: var(--medal-silver-bg);
  border-color: var(--medal-silver-border);
}
.bucket-row--2 .bucket-rank,
.bucket-row--2 .bucket-team-name,
.bucket-row--2 .bucket-count { color: var(--medal-silver-text); }

.bucket-row--3 {
  background: var(--medal-bronze-bg);
  border-color: var(--medal-bronze-border);
}
.bucket-row--3 .bucket-rank,
.bucket-row--3 .bucket-team-name,
.bucket-row--3 .bucket-count { color: var(--medal-bronze-text); }

/* Frozen top-3 block — desktop: sticky below tabs/bar/header */
.bucket-frozen {
  position: sticky;
  top: calc(var(--hdr-h, 0px) + var(--bar-h, 0px) + var(--tabs-h, 0px));
  z-index: 70;
  background: var(--bg);
  max-width: 42em;
  margin: 0 auto;
  padding: 1em 1em 0.35em;
  border-bottom: 0.07em solid var(--border);
}
.bucket-leaderboard--top3 { gap: 0.35em; }
.bucket-team-name {
  flex: 1;
  font-family: 'Oswald', sans-serif;
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.bucket-count {
  font-family: 'Oswald', sans-serif;
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--blue-lt);
  min-width: 2.5em;
  text-align: right;
}
/* ── Standings board ──
   Deliberately built from the Bucket Challenge row card above, not from the
   pool tables: the two share the fourth tab slot, so a visitor switching
   between them should not feel like they changed apps. Same surface, border,
   radius, rhythm and Oswald team name; no medal colouring (owner call — a
   bucket leader is a prize, a standings leader is just today's top of the
   list). The stats live inside the row instead of needing header cells, so
   there is no table chrome to reintroduce. The pool tables embedded in the
   Schedule tab keep .standings-table — a compact grid is right above a list
   of games. */
.std-board {
  max-width: 42em;
  margin: 0 auto;
  padding: 0.75em 0 0.35em;
  display: flex;
  flex-direction: column;
  gap: 0.35em;
}
.std-row {
  display: flex;
  align-items: center;
  gap: 0.75em;
  background: var(--surface);
  border: 0.07em solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.6em 1em;
}
.std-row--unplayed { opacity: 0.55; }
.std-rank {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--text-mute);
  min-width: 1.8em;
  text-align: center;
  flex-shrink: 0;
}
.std-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.15em; }
.std-team {
  font-family: 'Oswald', sans-serif;
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Runs for / against — secondary, so they read as detail under the name
   rather than competing with the record. */
.std-meta {
  display: flex;
  gap: 0.9em;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  color: var(--text-mute);
}
.std-stat b {
  font-weight: 600;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.std-figures {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.05em;
  min-width: 3.4em;
}
/* The row's headline figure, in the same slot and weight as .bucket-count */
.std-record {
  font-family: 'Oswald', sans-serif;
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--blue-lt);
  font-variant-numeric: tabular-nums;
}
.std-record-sep { opacity: 0.5; margin: 0 0.1em; }
.std-diff {
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}
.std-diff--pos { color: var(--win-color); }
.std-diff--neg { color: var(--lose-color); }
/* The tiebreak order is printed under the board: a TD gets asked "why is that
   team above us" and needs the answer on the same screen. */
.std-tiebreaks {
  /* rem, not em: this block sets its own small font-size, so 42em here would
     measure against THAT and the rule would come out narrower than the board
     it sits under. */
  max-width: 42rem;
  box-sizing: border-box;
  margin: 0 auto;
  padding: 0.9em 0 1em;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-xs);
  line-height: 1.45;
  color: var(--text-mute);
  border-top: 0.07em solid var(--border);
}
/* Projection notice — same block, tinted like every other pick affordance. */
.std-tiebreaks--proj { color: var(--blue-lt); border-top-color: var(--blue); }
.bucket-icon-sm {
  width: 1.1em;
  height: 1.1em;
  flex-shrink: 0;
  opacity: 0.5;
  color: var(--text-dim);
}
.bucket-empty {
  text-align: center;
  color: var(--text-mute);
  padding: 3em 1em;
  font-style: italic;
}

/* ── Bucket edit mode (bucket-role users) ── */
.bucket-edit-wrap {
  max-width: 42em;
  margin: 0 auto;
  padding: 0.75em 1em 0.5em;
  display: flex;
  flex-direction: column;
  gap: 0.4em;
}
.bucket-edit-row {
  display: flex;
  align-items: center;
  gap: 0.75em;
  background: var(--surface);
  border: 0.07em solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.6em 0.85em;
}
.bucket-edit-name {
  flex: 1;
  font-family: 'Oswald', sans-serif;
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.bucket-edit-inp {
  width: 4.5em;
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-lg); /* 1rem = 16px, also prevents iOS zoom */
  font-weight: 700;
  text-align: right;
  background: var(--bg);
  border: 0.07em solid var(--border);
  border-radius: 0.25em;
  color: var(--blue-lt);
  padding: 0.2em 0.4em;
}
.bucket-edit-actions {
  max-width: 42em;
  margin: 0 auto;
  padding: 0.75em 1em 3em;
  display: flex;
  align-items: center;
  gap: 0.65em;
}
.bucket-edit-cancel-btn {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 0.55em 1.1em;
  border-radius: var(--radius-xs);
  border: 0.07em solid var(--border);
  cursor: pointer;
  background: transparent;
  color: var(--text-dim);
}
.bucket-edit-cancel-btn:hover,
.bucket-edit-cancel-btn:active { color: var(--text); border-color: var(--text-dim); }
/* bucket-edit-save-btn: base styles from base.css primary-button rule */
.bucket-edit-status {
  font-size: 0.8rem;
  color: var(--text-dim);
  margin-left: 0.25em;
}

/* ── Round sections (By Round all-rounds layout) ── */
.round-section { max-width: 65em; margin: 0 auto; padding: 0 1em; }
.round-section-hdr {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--gold-lt);
  padding: 1.2em 0 0.6em;
  border-bottom: 0.07em solid var(--border);
  margin-bottom: 1em;
}
.selector-row label {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--blue-lt);
  flex-shrink: 0;
  font-weight: 600;
}

/* ── Schedule two-column selector ── */
.sched-selector-inner {
  align-items: stretch;
  justify-content: flex-start;
  flex-wrap: nowrap;
  gap: 0.75em;
}
.sched-select-wrap {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.sched-select-wrap--group { flex: 3; }
.sched-select-wrap--view  { flex: 5; }
.sched-select { width: 100%; }
select.styled {
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-lg);
  font-weight: 600;
  padding: 0.75em 0.9em;
  border-radius: var(--radius-sm);
  border: 0.1em solid var(--blue);
  background: var(--surface2);
  color: var(--text);
  cursor: pointer;
  flex: 1;
  min-height: 3.2em;
}
select.styled:focus { outline: 0.13em solid var(--blue-lt); outline-offset: 0.07em; }

.team-share-btn {
  font-family: 'Oswald', sans-serif;
  font-size: var(--btn-font-size);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: var(--btn-pad-v) var(--btn-pad-h);
  border-radius: var(--radius-xs);
  border: 0.07em solid var(--border);
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  white-space: nowrap;
  touch-action: manipulation;
  min-height: 2.75rem;
}
.team-share-btn:hover,
.team-share-btn:active { color: var(--text); border-color: var(--text-dim); }

/* ════════════════════════════════════════════════════════════
   BRACKET LAYOUT
   ════════════════════════════════════════════════════════════ */

.bracket-outer {
  display: flex;
  align-items: flex-start;
  width: 100%;
  overflow-x: auto;
  padding: calc(var(--col-hdr-h) + 0.5em) 0 1em 0;
}

.bracket-side {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-start;
}
.bracket-side.left-side  { justify-content: flex-end; }
.bracket-side.right-side { justify-content: flex-start; }

.rounds-wrap {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  position: relative;
  max-width: 65em;
  margin: 0 auto;
}

/* ── Open/A/B flight switcher (tiered format) ── */
.bracket-flights {
  display: flex;
  gap: 0.4em;
  justify-content: center;
  /* Top margin (space OUTSIDE the row) rather than padding: this row paints
     its own --bg panel, so padding-top would grow that panel instead of
     moving the pills down off the header rule above them. */
  margin: 1em auto 0.8em;
  max-width: 30em;
  /* The bracket canvas below is absolutely positioned and can extend up over
     this control row; keep the pills on top so they stay clickable. */
  position: relative;
  z-index: 5;
  background: var(--bg);
  padding: 0.15em 0.4em;
  border-radius: var(--radius-sm);
}
.sched-flights { margin: 1em auto 0.4em; }
.flight-pill {
  flex: 1;
  font-family: 'Oswald', sans-serif;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.5em 0.6em;
  border-radius: var(--radius-xs);
  border: 0.07em solid var(--border);
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  white-space: nowrap;
  min-height: 2.4em;
}
.flight-pill.active { background: var(--blue); border-color: var(--blue); color: #fff; }
.flight-pill:hover:not(.active) { color: var(--text); border-color: var(--text-dim); }
@media (pointer: coarse) { .flight-pill { min-height: 44px; } }

/* A/B flights: simple left-to-right round columns (their own single-elim
   brackets, rendered outside the Open tree). Horizontal-scroll on overflow. */
.flight-bracket {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 1.4em;
  overflow-x: auto;
  padding: 0.5em 0.75em 1em;
  max-width: 100%;
  /* Containing block for the measured connector overlay below. */
  position: relative;
}
/* Connector overlay: sized to the flight's full scroll area and drawn in the
   same coordinate space as the cards, so it scrolls with them. Painted under
   the cards (they carry z-index 1) and never intercepts taps. */
.flight-conn-svg {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  overflow: visible;
}
.flight-col {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  gap: 0.9em;
  flex: 0 0 auto;
  min-width: 11em;
}
/* Flight championship column: trophy header above the final's card,
   centered as a group (no space-around spread), gold-tinted like the
   main championship column. */
.flight-col--champ {
  justify-content: center;
  gap: 0.6em;
  padding: 0 1em;
  background: color-mix(in srgb, var(--gold) 4%, transparent);
  border-left: 0.07em solid color-mix(in srgb, var(--gold) 15%, transparent);
  border-right: 0.07em solid color-mix(in srgb, var(--gold) 15%, transparent);
}
.flight-col--champ .champ-winner { text-align: center; }
.flight-col-hdr {
  text-align: center;
  font-family: 'Oswald', sans-serif;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-mute);
  margin-bottom: 0.2em;
}
/* Cards in a flight are statically laid out. The double class out-ranks the
   later `.bc { position: absolute }` rule — with equal specificity the
   cascade would let .bc win and stack every flight card at the same spot. */
.bc.flight-bc {
  position: relative;
  left: auto;
  right: auto;
  min-height: 0;
  z-index: 1;   /* above .flight-conn-svg */
}
.flight-empty {
  text-align: center;
  color: var(--text-mute);
  padding: 2em 1em;
  font-family: 'Barlow', sans-serif;
}
/* "View Schedule" action inside the bracket-tab empty state */
.bracket-empty-goto {
  display: inline-block;
  flex: none;
  margin-top: 1em;
}

.round-col {
  position: relative;
  flex-shrink: 0;
  width: var(--col-w);
  height: calc(var(--slot-h) * 8);
}

.round-col-hdr {
  position: absolute;
  top: calc(var(--col-hdr-h) * -1.1);
  left: 0;
  right: 0;
  text-align: center;
  font-family: 'Oswald', sans-serif;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-mute);
  white-space: nowrap;
}

.round-gap {
  position: relative;
  flex-shrink: 0;
  width: var(--col-gap);
  height: calc(var(--slot-h) * 8);
}
.round-gap svg {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  overflow: visible;
}

/* ── Game card (bracket) ── */
.bc {
  position: absolute;
  left: 0;
  right: 0;
  min-height: var(--card-h);
  border: 0.07em solid var(--border);
  border-radius: var(--radius-sm);
  overflow: visible;
  background: var(--surface);
  display: flex;
  flex-direction: column;
}
.bc-hdr {
  flex: 1;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding: 0 0.45em;
  background: var(--surface2);
  border-bottom: 0.07em solid var(--border);
  min-height: 0;
}
.bc-id {
  font-family: 'Oswald', sans-serif;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  color: var(--blue-lt);
  white-space: nowrap;
  line-height: 1;
}
.bc-time {
  font-size: 0.68rem;
  color: var(--gold-lt);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* No width cap: with show-date on, "7/15 Wed 9:00 PM" overran the old
     60% and ellipsized. Let it use the header's leftover space instead —
     min-width:0 keeps ellipsis as the true last resort, and
     shrinkFieldTags() already frees room by abbreviating field tags. */
  flex: 0 1 auto;
  min-width: 0;
  text-align: right;
  margin-left: auto;
  line-height: 1;
}
/* Desktop bracket team names: single line with ellipsis to prevent crowding */
.bc-team {
  flex: 1;
  padding: 0.2em 0.45em;
  font-size: 0.64rem;
  font-weight: 600;
  color: var(--text);
  border-bottom: 0.07em solid var(--border);
  overflow: hidden;
  line-height: 1.25;
  display: flex;
  align-items: center;
  gap: 0.3em;
  min-height: var(--row-h);
}
.bc-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tt-seed {
  flex: none;
  font-family: 'Barlow', sans-serif;
  font-size: 0.72em;
  font-weight: 400;
  color: var(--text-mute);
  margin-right: 0.25em;
  white-space: nowrap;
}
.game-score {
  font-family: 'Oswald', sans-serif;
  font-weight: 700;
  font-size: 0.9em;
  color: var(--text-dim);
  flex-shrink: 0;
  min-width: 2ch;
  text-align: right;
  letter-spacing: 0.02em;
}
.game-score.live-score { color: var(--blue-lt); }
/* Final game: score matches team name color */
.bc-team.won .game-score,
.mbc-champ-team.won .game-score,
.mbc-game-team.won .game-score { color: var(--win-color); }
.bc-team.lost .game-score,
.mbc-champ-team.lost .game-score,
.mbc-game-team.lost .game-score { color: var(--lose-color); }
.round-team-row:has(.round-team-name.won) .game-score { color: var(--win-color); }
.round-team-row:has(.round-team-name.lost) .game-score { color: var(--lose-color); }
.live-badge {
  display: inline-block;
  font-family: 'Oswald', sans-serif;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--live-color);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.live-period {
  display: inline-block;
  font-family: 'Oswald', sans-serif;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--gold-lt);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.live-updated {
  display: inline-block;
  font-family: 'Barlow', sans-serif;
  font-size: 0.78em;
  font-weight: 400;
  color: var(--text-mute);
  white-space: nowrap;
}
/* Live indicator occupies the date/time slot — keep it on one row. */
.bc-time-live, .round-game-live, .mbc-game-live, .mbc-champ-live {
  display: inline-flex;
  flex-direction: row;
  align-items: baseline;
  gap: 0.65em;
  flex-wrap: nowrap;
}
.bc-time-live { max-width: none; overflow: visible; }
.bc-time-live .live-badge,
.bc-time-live .live-period { font-size: 1em; }
.bc-team:last-child { border-bottom: none; }
.bc-team.tbd  { color: var(--text-mute); font-style: italic; font-weight: 400; font-size: 0.7rem; }
.bc-team.bye  { }
.bc-bye-label {
  display: block;
  width: 100%;
  text-align: center;
  color: color-mix(in srgb, var(--text) 45%, transparent);
  font-style: italic;
  font-weight: 300;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
}
.bc-team.won  { color: var(--win-color); }
.bc-team.lost { color: var(--lose-color); }

/* ── Admin drag-and-drop ── */
.bc-dragging    { opacity: 0.3; pointer-events: none; }
.bc-drop-target { box-shadow: 0 0 0 2px var(--blue), 0 0 12px color-mix(in srgb, var(--blue-lt) 35%, transparent); }
/* Drop rows are thin BARS, not card-sized outlines. The grid is half a
   bracket row apart — fine enough to express a game centred between two games
   that are themselves off-grid — and card-sized ghosts at that pitch would
   overlap each other and bury the cards underneath. `top` addresses the row's
   centre line, hence the translate. */
.bc-drop-row {
  position: absolute;
  left: 6%;
  right: 6%;
  height: 0.5em;
  transform: translateY(-50%);
  border-top: 2px dashed var(--line-color);
  opacity: 0.35;
  pointer-events: all;
  cursor: default;
}
/* Rows the bracket cascade actually lands on — the midpoints of the feeding
   column's cards — read stronger, so the natural shape stays visible while a
   TD is free to ignore it. */
.bc-drop-row--cascade {
  left: 2%;
  right: 2%;
  border-top-style: solid;
  border-top-color: var(--blue);
  opacity: 0.28;
}
/* Level with a winner feeder. The default hang is a quarter-gap, which is off
   the half-step grid, so this is the only way to put a card exactly on its
   feeder's line — worth calling out as its own kind of row. */
.bc-drop-row--align {
  left: 0;
  right: 0;
  border-top-style: solid;
  border-top-color: var(--gold);
  opacity: 0.45;
}
.bc-drop-row.bc-drop-target {
  opacity: 1;
  border-top-color: var(--blue);
  border-top-width: 3px;
  box-shadow: 0 0 10px color-mix(in srgb, var(--blue-lt) 55%, transparent);
}
/* While a card is in the air the rows stop being background furniture — they
   are the thing being aimed at, so bring them up out of their resting wash.
   The class is on <body> so it reaches every column in one toggle. */
body.bc-drag-active .bc-drop-row          { opacity: 0.75; }
body.bc-drag-active .bc-drop-row--cascade { opacity: 0.85; border-top-width: 3px; }
body.bc-drag-active .bc-drop-row--align   { opacity: 0.95; border-top-width: 3px; }
body.bc-drag-active .bc-drop-row.bc-drop-target { opacity: 1; }
/* Rows inside a card's own footprint. Inert and invisible until a drag frees
   them (see freeCoveredRows) — they paint above the cards, so a live one
   would make the card underneath impossible to pick up. These must come AFTER
   the drag-active rules above: same specificity, so order decides. */
.bc-drop-row--covered,
body.bc-drag-active .bc-drop-row--covered { pointer-events: none; opacity: 0; }
body.bc-drag-active .bc-drop-row--covered.bc-drop-row--live { pointer-events: all; opacity: 0.8; }
body.bc-drag-active .bc-drop-row--covered.bc-drop-row--live.bc-drop-target { opacity: 1; }
/* The footprint the dragged card would occupy, centred on the hovered row.
   Sized in px by initBracketDrag from the card being dragged. */
.bc-slot-preview {
  position: absolute;
  left: 0;
  right: 0;
  border: 2px dashed var(--blue);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--blue) 14%, transparent);
  box-shadow: 0 0 14px color-mix(in srgb, var(--blue-lt) 40%, transparent);
  pointer-events: none;
  z-index: 3;
}
/* Placed by hand — this card renders at its slot row instead of wherever the
   automatic layout would put it. The class is only emitted while editing
   (see sideHTML), so the published bracket carries no extra ink. */
.bc-pinned::after {
  content: "";
  position: absolute;
  top: 3px; right: 3px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--blue);
  opacity: 0.75;
  pointer-events: none;
}
.bc-drag-ghost  {
  opacity: 0.88;
  transform: rotate(1.5deg);
  box-shadow: 0 8px 28px rgba(0,0,0,0.55);
  cursor: grabbing !important;
}
/* Active state for the bracket Edit button */
.admin-btn-active { color: var(--blue-lt) !important; border-color: var(--blue) !important; }
/* Hide bracket edit button on mobile — drag-and-drop is desktop only */
@media (max-width: 1279px) {
  #bracketEditBtn { display: none !important; }
}

/* ── Championship center ── */
.champ-center {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 0.5em;
  background: color-mix(in srgb, var(--gold) 4%, transparent);
  border-left: 0.07em solid color-mix(in srgb, var(--gold) 15%, transparent);
  border-right: 0.07em solid color-mix(in srgb, var(--gold) 15%, transparent);
  width: var(--col-w);
  height: calc(var(--slot-h) * 8);
}
.champ-inner { width: 100%; text-align: center; }
.champ-trophy { font-size: 1.8em; margin-bottom: 0.3em; }
/* Trophy renders from the icon file, not the 🏆 emoji — desktop systems
   without a color-emoji font showed an empty box. Sized in em so it
   inherits each wrapper's font-size. */
.trophy-img { width: 1em; height: 1em; vertical-align: -0.12em; }
.champ-title {
  font-family: 'Oswald', sans-serif;
  font-size: 0.68rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 0.3em;
}
.champ-gametime {
  font-size: 0.74rem;
  color: var(--gold-lt);
  font-weight: 600;
  margin-bottom: 0.5em;
}
.champ-bc { position: relative; height: var(--card-h); }
.champ-winner { font-family: 'Oswald', sans-serif; font-size: 0.95rem; color: var(--gold-lt); letter-spacing: 0.07em; margin-top: 0.5em; }

/* ── Desktop championship column ── */
.champ-center--desktop {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  /* stretch (not center): .champ-bc must span the column like the
     original width:100% wrapper, or the card collapses to content width */
  align-items: stretch;
  justify-content: flex-start;
  padding: 0 0.5vw;
  /* Horizontal breathing room between the tinted column and the SF cards.
     The 0.8vw per side is subtracted from the inline width in
     renderDesktopBracket so the total stays champVw. */
  margin: 0 0.8vw;
  background: color-mix(in srgb, var(--gold) 4%, transparent);
  border-left: 0.07em solid color-mix(in srgb, var(--gold) 15%, transparent);
  border-right: 0.07em solid color-mix(in srgb, var(--gold) 15%, transparent);
}
.champ-center--desktop .champ-winner { text-align: center; }
/* Championship card anchored to the feeder row: the wrapper's top is the
   row both feeder games enter at; the trophy/title block floats ABOVE the
   card so the card itself lines up with its feeders. */
.champ-anchor { position: absolute; left: 0.5vw; right: 0.5vw; }
.champ-inner--above {
  position: absolute;
  bottom: 100%;
  left: 0;
  right: 0;
  margin-bottom: 1.2vh;
}
.champ-center--ifnec {
  width: 100%;
  margin-top: 1.5vh;
  text-align: center;
}
.champ-ifnec-label {
  font-family: 'Oswald', sans-serif;
  font-size: 0.55em;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-mute);
  margin-bottom: 0.15em;
}
.champ-center--ifnec.champ-ifnec--pending {
  opacity: 0.5;
}
.champ-ifnec-note {
  font-size: 0.52em;
  color: var(--text-mute);
  font-style: italic;
  margin-bottom: 0.4em;
  line-height: 1.3;
}

/* Bracket side label */
.bracket-side-label {
  display: block;
  width: fit-content;
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 0.15em 0.4em 0.15em 0;
  background: transparent;
  color: var(--text-dim);
  border-bottom: 0.1em solid var(--border);
  position: absolute;
  top: calc(var(--col-hdr-h) * -2);
  cursor: default;
  user-select: none;
}
.left-side  .bracket-side-label { left: 0; }
.right-side .bracket-side-label { right: 0; }

.bracket-side-wrap {
  flex: 1;
  min-width: 0;
  position: relative;
}

/* ── Carousel round column header (tablet + mobile) ── */
.carousel-round-hdr {
  font-family: 'Oswald', sans-serif;
  font-size: 0.70rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-lt);
  text-align: center;
  padding: 0.3em 0 0.5em;
}

/* ── Mobile bracket (legacy classes, kept for compatibility) ── */
.mobile-bracket-wrap {
  width: 85vw;
  margin: 0 auto;
  overflow-x: auto;
  display: flex;
  scroll-snap-type: x mandatory;
  scroll-padding-left: 0;
  scroll-padding-right: 15vw;
  padding-right: 15vw;
}
.mobile-bracket-section { flex: 0 0 85vw; width: 85vw; }
.mobile-bracket-label {
  padding: 0.5em 0 0.25em;
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--text-dim);
  letter-spacing: 0.13em;
  text-transform: uppercase;
}
.mobile-bracket-divider { margin: 0.5em 0; height: 0.07em; background: var(--border); }
.mobile-bracket-svg-wrap { overflow: visible; }

/* ── Round view ── */
.round-panel { padding: 0 0 1.5em; }
/* ── W/L legend ── */

/* ── Round games 2-column grid on desktop ── */
.round-games-grid { display: contents; }
@media (min-width: 1024px) {
  .round-games-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 1.5em;
  }
}

.round-game-card {
  border: 0.07em solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface);
  margin-bottom: 1.4em;
}
.round-game-card.champ2-pending {
  opacity: 0.55;
  border-style: dashed;
}
.round-game-card.champ2-not-needed {
  opacity: 0.35;
  border-style: dashed;
  text-decoration-line: line-through;
}
.champ2-rv-note {
  font-size: var(--text-xs);
  color: var(--text-mute);
  font-style: italic;
  padding: 0.3em 0.8em 0;
}
.champ2-rv-note--nn {
  color: var(--lose-color);
  font-style: normal;
  font-weight: 600;
}
.round-game-card.upcoming {
  opacity: 0.75;
  border-style: dashed;
}
.round-game-header {
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.6em 1em;
  background: var(--surface2);
  border-bottom: 0.07em solid var(--border);
}
.round-game-id {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.07em;
  color: var(--blue-lt);
  flex-shrink: 0;
}
.round-game-day-time { display: flex; align-items: baseline; gap: 0.45em; flex: 1; justify-content: flex-end; }
.round-game-day  { font-family: 'Oswald', sans-serif; font-size: 0.82rem; font-weight: 600; color: var(--text-dim); line-height: 1; flex-shrink: 0; }
.round-game-dow  { font-family: 'Oswald', sans-serif; font-size: 0.95rem; font-weight: 700; color: var(--gold-lt); line-height: 1; }
.round-game-time { font-family: 'Oswald', sans-serif; font-size: 0.95rem; font-weight: 700; color: var(--gold-lt); line-height: 1; }
.round-game-offset { font-family: 'Oswald', sans-serif; font-size: 0.78rem; font-weight: 700; line-height: 1; margin-left: 0.35em; }
.round-game-offset--late  { color: var(--lose-color); }
.round-game-offset--early { color: var(--win-color); }
.round-team-row {
  display: flex;
  align-items: center;
  padding: 0.75em 1em;
  border-bottom: 0.07em solid var(--border);
  min-height: 3.2em;
  gap: 0.6em;
}
.round-team-row:last-child { border-bottom: none; }
.round-team-name { font-size: clamp(1rem, 0.08vw + 0.98rem, 1.15rem); font-weight: 700; flex: 1; }
.round-team-name.tbd  { color: var(--text-mute); font-style: italic; font-weight: 400; }
.round-team-name.bye  { color: var(--text-mute); font-style: italic; font-weight: 400; opacity: 0.55; letter-spacing: 0.08em; }
.round-team-name.won  { color: var(--win-color); }
.round-team-name.lost { color: var(--lose-color); }
/* ── Team view ── */
.team-panel { max-width: 65em; margin: 0 auto; padding: 0 1em 1.5em; }
.team-no-games { padding: 1em; color: var(--text-mute); font-style: italic; }

/* Cards in the team panel show a lose-destination sidebar on the right */
.team-panel .round-game-card { display: flex; flex-direction: row; align-items: stretch; }
.round-game-main { flex: 1; min-width: 0; }
.round-lose-side {
  flex-shrink: 0;
  max-width: 25%;
  border-left: 0.07em solid var(--border);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3em;
  padding: 0.4em 0.25em;
  background: color-mix(in srgb, var(--lose-color) 6%, transparent);
}
.round-lose-tag {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-md);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--lose-color);
}
.round-lose-arrow {
  font-size: var(--text-md);
  color: var(--lose-color);
  line-height: 1;
  opacity: 0.75;
}
.round-lose-dest {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--text-dim);
  letter-spacing: 0.04em;
  text-align: center;
}
.round-lose-dest.out { color: var(--lose-color); }
.round-lose-arrow--cont { color: var(--win-color); opacity: 1; }

/* ── Victory sidebar (shown when team won the game) ── */
.round-win-side {
  flex-shrink: 0;
  max-width: 25%;
  border-left: 0.07em solid var(--win-color);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25em;
  padding: 0.4em 0.2em;
  background: color-mix(in srgb, var(--win-color) 10%, transparent);
}
.round-win-img {
  width: 100%;
  height: auto;
  max-height: 60%;
  object-fit: contain;
  display: block;
}
.round-win-tag {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-md);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--win-color);
  line-height: 1;
}

/* ── Team chip grid (empty state) ── */
.team-chips-prompt {
  max-width: 42em;
  margin: 1.2em auto 0.3em;
  padding: 0 1em;
  color: var(--text-dim);
  font-size: var(--text-md);
}
.team-chips-grid {
  display: flex;
  flex-direction: column;
  gap: 0.35em;
  padding: 1em 1em 2em;
  max-width: 42em;
  margin: 0 auto;
}
.team-chip {
  display: flex;
  align-items: center;
  width: 100%;
  box-sizing: border-box;
  background: var(--surface);
  border: 0.07em solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.75em 1em;
  font-family: 'Oswald', sans-serif;
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text);
  cursor: pointer;
  text-align: left;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  -webkit-tap-highlight-color: transparent;
}
.team-chip:hover, .team-chip:active { background: var(--surface2); border-color: var(--blue-lt); color: var(--blue-lt); }
.team-chip.elim { opacity: 0.45; }
.team-elim-inline {
  max-width: 42em;
  margin: 0.5em auto 0.5em;
  padding: 0 1em;
  text-align: center;
}
.team-elim-inline-img {
  width: 65%;
  height: auto;
  display: block;
  margin: 0 auto;
  border-radius: var(--radius-md);
  object-fit: contain;
}
.team-path-annotation {
  padding: 0.18em 0 0 0.5em;
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-md);
  font-weight: 600;
  letter-spacing: 0.05em;
  display: flex;
  gap: 0.25em;
  align-items: center;
}
.team-path-annotation--terminal { padding-bottom: 0.5em; }
.team-path-connector {
  display: flex;
  align-items: center;
  gap: 0.4em;
  padding: 0 0 0 0.5em;
  margin: 0.1em 0 0.6em;
}
.team-path-connector-track {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 1em;
  padding-left: 0.4em;
}
.team-path-connector-line {
  font-size: var(--text-md);
  line-height: 1;
  color: var(--win-color);
  width: auto;
  height: auto;
  background: none;
}
.team-path-connector-line::before {
  content: '↓';
}
.team-path-connector-line.lose {
  background: none;
  border-left: none;
  color: var(--lose-color);
}
.team-path-win-label {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-md);
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--win-color);
}
.color-win  { color: var(--win-color); }
.color-lose { color: var(--lose-color); }
.color-gold { color: var(--gold-lt); }
.team-path-label {
  padding: 0.6em 0.75em;
  font-size: 1.15rem;
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  background: var(--surface2);
  border-radius: var(--radius-sm);
  border-left: 0.2em solid currentColor;
  margin: 0.5em 0 1.4em;
  text-align: center;
}
.team-path-label.win-label  { color: var(--win-color); }
.team-path-label.lose-label { color: var(--lose-color); }
.team-path-divider { margin: 1.4em 0; height: 0.07em; background: var(--border); }

/* ── Championship banner (team path terminal) ── */
.team-path-champion {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  margin: 0.9em 0 0.5em;
  padding: 0.7em 1.4em;
  background: linear-gradient(135deg, color-mix(in srgb, var(--gold) 16%, transparent), color-mix(in srgb, var(--gold) 4%, transparent));
  border: 0.1em solid var(--gold);
  border-radius: var(--radius-md);
  box-shadow: 0 0 16px color-mix(in srgb, var(--gold) 22%, transparent);
}
.team-path-champion .tpc-pre {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-md);
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--win-color);
}
.team-path-champion .tpc-trophy { font-size: 1.7rem; line-height: 1; }
.team-path-champion .tpc-word {
  font-family: 'Oswald', sans-serif;
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-lt);
}
.team-path-champion.is-crowned {
  box-shadow: 0 0 24px color-mix(in srgb, var(--gold) 40%, transparent);
}
.team-path-champion.is-crowned .tpc-word { font-size: 1.55rem; }

/* ── Clickable loss-destination boxes (team path navigation) ── */
.round-lose-side[data-lose-anchor] { cursor: pointer; }
/* The destination game name reads as a tappable pill (matches .tp-opp-chip)
   so the jump affordance is visible at rest — not just on hover, which
   touch devices never trigger. */
.round-lose-side[data-lose-anchor] .round-lose-dest {
  border: 1px solid var(--border);
  border-radius: 1.2em;
  padding: 0.2em 0.55em;
  color: var(--blue-lt);
  white-space: nowrap;
  max-width: 100%;
  -webkit-tap-highlight-color: transparent;
}
.round-lose-side[data-lose-anchor]:hover .round-lose-dest,
.round-lose-side[data-lose-anchor]:active .round-lose-dest {
  background: var(--surface2);
  border-color: var(--blue-lt);
}
.tp-target-flash { animation: tpTargetFlash 1.4s ease-out; }
@keyframes tpTargetFlash {
  0%   { box-shadow: 0 0 0 0.25em var(--gold); }
  100% { box-shadow: 0 0 0 0.25em transparent; }
}

/* ── Championship bar (mobile/rounds) ── */
.champ-bar { margin: 0.4em 0 0.75em; padding: 0.65em 0.9em; background: var(--surface2); border-radius: var(--radius-sm); border: 0.07em solid var(--border); }
.champ-bar-label { font-family: 'Oswald', sans-serif; font-size: 0.68rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--gold); margin-bottom: 0.5em; }
.champ-bar-teams { display: flex; gap: 0.5em; align-items: center; }
.champ-team-slot { flex: 1; border: 0.07em solid var(--border); border-radius: 0.25em; padding: 0.5em 0.75em; font-size: 0.96rem; font-weight: 600; color: var(--text); background: var(--surface); }
.champ-team-slot.tbd { color: var(--text-mute); font-style: italic; font-weight: 400; }
.champ-winner-display { margin-top: 0.6em; text-align: center; font-family: 'Oswald', sans-serif; font-size: 0.95rem; color: var(--gold-lt); letter-spacing: 0.07em; }

/* ════════════════════════════════════════════════════════════
   MOBILE LAYOUT (phones + tablets under 1280px)
   Snap-scroll carousel: one round visible at a time.
   ════════════════════════════════════════════════════════════ */

/* Breakpoint contract: public bracket goes mobile under 1280px (desktop bracket needs the width); admin/lineup switch at 1023px. Intentional two-tier split. */
@media (max-width: 1279px) {
  .update-bar, .delay-notice { flex-shrink: 0; position: static; }

  .bracket-outer { display: none; }

  .bracket-side {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }
  .bracket-side.left-side,
  .bracket-side.right-side { justify-content: unset; }

  .bracket-side-label { position: static; margin-bottom: 0.5em; display: inline-block; font-size: var(--text-xs); }

  .rounds-wrap {
    width: 100%;
    max-width: 100%;
    margin: 0;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    padding: 0.5em 0.5em 0.5em 0;
  }

  .round-col {
    flex-shrink: 0;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    width: var(--col-w);
    height: auto;
    min-height: auto;
    position: relative;
    padding-right: 0.5em;
  }
  .round-col:last-child { padding-right: 1.5em; }

  .round-col-hdr {
    position: static;
    text-align: center;
    font-size: 0.70rem;
    color: var(--gold-lt);
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 0.4em 0.2em;
    margin-bottom: 0.4em;
  }

  .round-gap { display: none; }

  .bc {
    position: relative;
    margin-bottom: 0.5em;
    border-radius: var(--radius-sm);
    min-height: auto;
  }
  .bc-hdr { padding: 0.33em 0.33em; font-size: 0.62rem; }
  .bc-id  { font-size: 0.65rem; }
  .bc-time { font-size: 0.65rem; }
  .bc-team {
    padding: 0.18em 0.33em;
    font-size: 0.65rem;
    min-height: 1.9em;
    line-height: 1.15;
    white-space: normal;
    word-break: break-word;
  }

  .champ-center {
    position: relative;
    width: auto;
    flex-shrink: 0;
    padding: 0.6em 0.5em;
    border-left: 0.07em solid color-mix(in srgb, var(--gold) 15%, transparent);
    border-right: none;
    border-top: none;
    border-bottom: none;
    margin: 0;
  }
  .champ-inner   { width: 100%; text-align: center; }
  .champ-title   { font-size: 0.62rem; margin-bottom: 0.2em; }
  .champ-gametime { font-size: 0.65rem; margin-bottom: 0.35em; }
  .champ-trophy  { font-size: 1.2em; margin-bottom: 0.15em; }
  .champ-bc      { position: relative; height: auto; margin-bottom: 0; }
  .champ-winner  { font-size: 0.80rem; margin-top: 0.3em; }
  .bracket-side-wrap { position: static; flex: 1; min-width: 0; }
}

/* ════════════════════════════════════════════════════════════
   MOBILE BRACKET — two-column peek layout
   Current round (80vw) fully visible + next round peeks 20vw.
   Cards match By Round card style. Convergence is animated via
   JS-driven translateY blend as the user swipes between rounds.
   ════════════════════════════════════════════════════════════ */

/* Horizontal column container — JS-driven snap via scrollLeft */
.mbc-outer {
  display: flex;
  flex-direction: row;
  overflow-x: scroll;
  overflow-y: hidden;
  overscroll-behavior: none;
  width: 100%;
  scrollbar-width: none;
}
.mbc-outer::-webkit-scrollbar { display: none; }

/* One column per round — no CSS snap (JS handles it) */
.mbc-col {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Full-width vertical scroll overlay — the ONLY scroll container.
   Positioned below .mbc-hdr so the dot-navigation bar stays tappable.
   touch-action:pan-y lets iOS handle vertical with native momentum;
   horizontal swipes are detected in JS and forwarded to .mbc-outer. */
.mbc-scroll-cap {
  overflow-y: scroll;
  overflow-x: hidden;
  overscroll-behavior-y: contain;
  overscroll-behavior-x: none;
  touch-action: pan-y;
  scrollbar-width: none;
}
.mbc-scroll-cap::-webkit-scrollbar { display: none; }

/* Round name + progress dots — above the scroll area */
.mbc-hdr {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5em 1em 0.45em;
  background: var(--surface);
  border-bottom: 0.07em solid var(--border);
}
.mbc-hdr-label {
  font-family: 'Oswald', sans-serif;
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-lt);
}
.mbc-dots { display: flex; gap: 5px; align-items: center; }
.mbc-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--border);
  transition: background 0.2s, transform 0.2s;
  cursor: pointer;
  flex-shrink: 0;
}
.mbc-dot.active { background: var(--blue-lt); transform: scale(1.35); }

/* ── Mobile bracket carousel: prev/next arrow buttons ───────────────────
   Only shown on true pointer-device (mouse) screens via hover:hover +
   pointer:fine. They are position:fixed so they float above all carousel
   columns and above captureEl (which has no explicit z-index). z-index 205
   ensures they sit above the scroll overlay. Top is set by JS to vertically
   centre within the scroll area; transform: translateY(-50%) handles
   the offset. Arrows are hidden by default and overridden to display:flex
   inside the media query, so non-mouse browsers never see them. */
/* Default: arrows hidden on touch/non-hover devices.
   Must precede the media-query override — same specificity, cascade order wins. */
.mbc-arrow { display: none; }

@media (hover: hover) and (pointer: fine) {
  .mbc-arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    width: 2.5rem;
    height: 2.5rem;
    transform: translateY(-50%);
    border-radius: 50%;
    background: color-mix(in srgb, var(--surface) 80%, transparent);
    border: 0.1em solid var(--border);
    color: var(--text-dim);
    font-family: 'Oswald', sans-serif;
    font-size: 1.7rem;
    line-height: 1;
    cursor: pointer;
    z-index: 205;
    opacity: 0.55;
    transition: opacity 0.15s, background 0.15s, color 0.15s;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
  }
  .mbc-arrow:hover {
    opacity: 1;
    background: color-mix(in srgb, var(--surface2) 92%, transparent);
    color: var(--gold-lt);
    border-color: var(--gold);
  }
  .mbc-arrow--prev { left: 0.5rem; }
  .mbc-arrow--next { right: 0.5rem; }
}

/* Column scroll area — overflow:hidden; .mbc-scroll-cap overlay drives scroll */
.mbc-scroll {
  flex: 1;
  overflow: hidden;
}

/* Absolutely-positioned card container — width + height set by JS, centred horizontally */
.mbc-inner {
  position: relative;
  flex-shrink: 0;
  margin: 0 auto;
}

/* ── Championship card ── */
.mbc-champ-card {
  height: 100%;
  display: flex;
  flex-direction: column;
  /* Gold-tinted surface gradient — stays dark-on-dark or light-on-light per
     theme (was a hardcoded dark-green endpoint, illegible with light-mode
     text once the gradient crossed into it). */
  background: linear-gradient(170deg, var(--surface2) 0%, color-mix(in srgb, var(--gold) 12%, var(--bg)) 100%);
  border: 0.15em solid var(--gold);
  border-radius: var(--radius-md);
  box-shadow: 0 0 32px color-mix(in srgb, var(--gold) 30%, transparent), inset 0 1px 0 color-mix(in srgb, var(--gold-lt) 12%, transparent);
  overflow: hidden;
}
/* Top info block */
.mbc-champ-top {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0.9em 1em 0.7em;
  gap: 0.2em;
  flex-shrink: 0;
}
.mbc-champ-trophy {
  font-size: calc(var(--mbc-card-h, 120px) * 0.22);
  line-height: 1;
  filter: drop-shadow(0 2px 8px color-mix(in srgb, var(--gold-lt) 60%, transparent));
}
.mbc-champ-label {
  font-family: 'Oswald', sans-serif;
  font-size: calc(var(--mbc-card-h, 120px) * 0.115);
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
}
.mbc-champ-time {
  font-size: calc(var(--mbc-card-h, 120px) * 0.085);
  color: var(--text-dim);
  letter-spacing: 0.04em;
}
/* Separator */
.mbc-champ-sep {
  height: 0.07em;
  background: var(--gold);
  opacity: 0.35;
  flex-shrink: 0;
  margin: 0 1.2em;
}
/* Teams block fills remaining height */
.mbc-champ-teams {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0.5em 1.2em;
  gap: 0.15em;
  min-height: 0;
}
.mbc-champ-team {
  font-family: 'Barlow', sans-serif;
  font-size: calc(var(--mbc-card-h, 120px) * 0.155);
  font-weight: 700;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 0.4em;
  max-width: 100%;
}
.mbc-champ-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.mbc-champ-team.tbd  { color: var(--text-mute); font-style: italic; font-weight: 400; font-size: calc(var(--mbc-card-h, 120px) * 0.115); }
.mbc-champ-team.won  { color: var(--win-color); }
.mbc-champ-team.lost { color: var(--lose-color); }
.mbc-champ-vs {
  font-size: calc(var(--mbc-card-h, 120px) * 0.075);
  color: var(--text-mute);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.mbc-champ-winner {
  flex-shrink: 0;
  padding: 0.5em 1.2em 0.6em;
  font-family: 'Oswald', sans-serif;
  font-size: calc(var(--mbc-card-h, 120px) * 0.10);
  font-weight: 700;
  color: var(--gold-lt);
  letter-spacing: 0.1em;
  text-align: center;
  border-top: 0.07em solid color-mix(in srgb, var(--gold) 30%, transparent);
}

/* champ2 state classes on .mbc-card */
.mbc-card.mbc-champ2-pending .mbc-champ-card {
  opacity: 0.55;
}
.mbc-card.mbc-champ2-not-needed {
  opacity: 0.35;
}
.mbc-champ2-not-needed {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  border: 0.07em dashed var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-sizing: border-box;
}
.mbc-champ2-nn-label {
  font-family: 'Oswald', sans-serif;
  font-size: 0.7em;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.mbc-champ2-nn-tag {
  font-family: 'Oswald', sans-serif;
  font-size: 0.9em;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--lose-color);
  text-transform: uppercase;
}
/* Suppress champ winner banner when CHAMP2 is pending/needed */
.mbc-card.mbc-champ-winner-pending .mbc-champ-winner {
  display: none;
}

/* Each card: absolute position, translateY driven by JS scroll blend */
.mbc-card {
  position: absolute;
  left: 0;
  right: 0;
}
.mbc-card .round-game-card { margin-bottom: 0; height: 100%; box-sizing: border-box; }

/* ── Bracket-side divider: subtle label between L and R side games ── */
.mbc-playin-divider[data-div-type="side"] .mbc-playin-line {
  opacity: 0.45;
}
.mbc-playin-divider[data-div-type="side"] .mbc-playin-label {
  font-weight: 400;
  letter-spacing: 0.07em;
  opacity: 0.6;
}

/* ── Play-in divider: sits inside .mbc-card, anchored above it ── */
.mbc-playin-divider {
  position: absolute;
  left: 0;
  right: 0;
  /* top is set inline as -(DIV_H + GAP) so it floats above the card */
  display: flex;
  align-items: center;
  gap: 0.6em;
  pointer-events: none;
}
.mbc-playin-line {
  flex: 1;
  height: 1px;
  background: var(--border);
}
.mbc-playin-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-dim, var(--border));
  white-space: nowrap;
}

/* ── Mobile bracket: game card — top 25% header, bottom 75% teams ── */
.mbc-game-card {
  height: 100%;
  display: flex;
  flex-direction: column;
  border: 0.07em solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface);
  box-sizing: border-box;
  transition: opacity 0.15s;
}
.mbc-game-card.upcoming {
  border-style: dashed;
}
/* Each team row gets 3 flex-units = 37.5% of card (×2 = 75%) */
.mbc-game-team {
  flex: 3;
  display: flex;
  align-items: center;
  gap: 0.4em;
  padding: 0 0.7em;
  font-family: 'Barlow', sans-serif;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
  min-height: 0;
  min-width: 0;
}
.mbc-game-team.tbd  {
  color: var(--text-mute);
  font-style: italic;
  font-weight: 400;
  font-size: 0.88rem;
}
.mbc-game-team.bye  { color: var(--text-mute); font-style: italic; font-weight: 400; opacity: 0.55; letter-spacing: 0.08em; }
.mbc-game-team.won  { color: var(--win-color); }
.mbc-game-team.lost { color: var(--lose-color); }
/* Name span: takes all space, truncates with ellipsis */
.mbc-team-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Header row gets 2 flex-units = 25% of card */
.mbc-game-mid {
  flex: 2;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 0 0.9em;
  background: var(--surface2);
  border-bottom: 0.07em solid var(--border);
  min-height: 0;
}
.mbc-game-lbl {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.07em;
  color: var(--blue-lt);
  flex-shrink: 0;
}
.mbc-game-datetime { display: flex; align-items: baseline; gap: 0.3em; margin-left: auto; }
.mbc-game-day {
  font-family: 'Oswald', sans-serif;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text-dim);
  margin-right: 0.2em;
}
.mbc-game-dow {
  font-family: 'Oswald', sans-serif;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--gold-lt);
}
.mbc-game-time {
  font-family: 'Oswald', sans-serif;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--gold-lt);
}

/* ════════════════════════════════════════════════════════════
   MOBILE — flex-body layout: body is a locked column,
   tabs sit naturally at the bottom (no position:fixed needed),
   selector is fixed above tabs with no body-scroll jitter.
   ════════════════════════════════════════════════════════════ */
@media (max-width: 1279px) {
  /* Compact the header to reclaim vertical space */
  .header-timestamp { display: none !important; }
  .site-subtitle { font-size: 0.58em; margin-top: 0.05em; letter-spacing: 0.08em; }

  /* Viewport-locked flex column — body never scrolls, so position:fixed is rock-solid.
     Use height:100% (initial containing block) rather than 100dvh — on iOS, dvh can
     start from behind the notch/address bar and break safe-area layout. --app-h is set
     synchronously from window.innerHeight before first paint as a JS correction. */
  html { height: 100%; height: 100svh; height: var(--app-h, 100svh); }
  body { height: 100%; height: 100svh; height: var(--app-h, 100svh); overflow: hidden; display: flex; flex-direction: column; }
  /* position:sticky inside overflow:hidden body is a no-op and can break WebKit flex
     layout (content starts at y=0 behind the floating header). Use relative instead. */
  .site-header { flex-shrink: 0; position: relative; top: auto; }

  /* Tab bar: last flex item → naturally sits at the bottom, no position:fixed needed */
  .view-tabs {
    order: 10;
    flex-shrink: 0;
    position: relative; top: auto; bottom: auto;
    background: var(--bg);
    border-top: 0.22em solid var(--gold);
    border-bottom: none;
    box-shadow: 0 -6px 24px rgba(0,0,0,0.55);
    padding-bottom: max(1em, env(safe-area-inset-bottom, 0px));
    padding-left: max(env(safe-area-inset-left, 0px), 1.2em);
    padding-right: max(env(safe-area-inset-right, 0px), 1.2em);
    z-index: 90;
  }
  .view-tab {
    min-height: 0;
    padding: 0.75em 0.5em 0.9em;
    border-bottom: none;
    border-top: 0.25em solid transparent;
    font-size: var(--text-sm);
    letter-spacing: 0.08em;
    gap: 0.3em;
  }
  .tab-icon {
    display: block;
    width: 1.8em;
    height: 1.8em;
  }
  .view-tab.active {
    color: var(--gold-lt);
    border-top-color: var(--gold);
  }
  .view-tab.active .tab-icon {
    color: var(--gold-lt);
  }

  /* Active panels fill remaining space between header and tab bar */
  .view-panel.active { flex: 1; min-height: 0; overflow: hidden; }
  /* Schedule and teampath: flex column so selector row can sit naturally above tab bar */
  #view-schedule.active, #view-teampath.active {
    display: flex;
    flex-direction: column;
  }
  /* Content scrolls within the flex column; selector row is a static sibling below */
  #view-schedule.active .round-panel,
  #view-standings.active .team-panel,
  #view-teampath.active .team-panel {
    flex: 1;
    min-height: 0;
    overflow-y: auto;

    overscroll-behavior-y: contain;
    scrollbar-width: none;
  }
  /* Same treatment as .bucket-panel: without box-sizing the 1em side padding
     is ADDED to the full-width panel and every row overflows the screen. */
  #view-standings.active { display: flex; flex-direction: column; overflow: hidden; }
  #view-standings.active .team-panel {
    width: 100%;
    max-width: none;
    margin: 0;
    padding-left: 0.75em;
    padding-right: 0.75em;
    box-sizing: border-box;
  }
  /* A/B flights now use the same mobile column carousel as the tree (its
     own fixed scroll overlay) — the panel just needs the flex column so the
     bracket root fills the space between pills and tab bar. */
  #view-bracket.active { display: flex; flex-direction: column; }
  #view-bracket.active #bracketRoot { flex: 1; min-height: 0; }
  #view-schedule.active .round-panel::-webkit-scrollbar,
  #view-standings.active .team-panel::-webkit-scrollbar,
  #view-teampath.active .team-panel::-webkit-scrollbar { display: none; }

  #view-buckets.active {
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }
  /* On mobile the frozen top-3 is a non-scrolling flex sibling */
  #view-buckets.active .bucket-frozen {
    position: static;
    flex-shrink: 0;
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0.75em 1em 0.35em;
    box-sizing: border-box;
    background: var(--bg);
    border-bottom: 0.07em solid var(--border);
  }
  #view-buckets.active .bucket-panel {
    flex: 1;
    width: 100%;
    max-width: none;
    margin: 0;
    box-sizing: border-box;
    overflow-y: auto;

    overscroll-behavior-y: contain;
    scrollbar-width: none;
  }
  #view-buckets.active .bucket-panel::-webkit-scrollbar { display: none; }

  /* Team Path controls stay on ONE line. The select is the only elastic thing
     here, so it gives up the width: with "What if?" wrapping to a second row
     this bar was 131px tall on a 390px phone, and it sits at the bottom of the
     viewport where every pixel it takes comes straight off the bracket. The
     buttons tighten a little too, but keep the 2.75rem touch target. */
  #view-teampath .selector-inner {
    flex-wrap: nowrap;
    gap: 0.4em;
    padding: 0.6em 0.8em;
  }
  #view-teampath .selector-inner select.styled {
    /* min-width:0 is what actually lets a flex item shrink below its content
       width — without it the select refuses to give ground and the button
       wraps anyway. */
    flex: 1 1 auto;
    min-width: 0;
    font-size: var(--text-md);
    padding: 0.5em 0.6em;
    min-height: 2.75rem;
  }
  #view-teampath .selector-inner .team-share-btn {
    flex: 0 0 auto;
    padding: var(--btn-pad-v) 0.7em;
    min-height: 2.75rem;
  }

  /* Selector row: flex item at the bottom of its view panel — no position:fixed needed.
     Sits naturally above the tab bar via the outer body flex layout.
     Avoids iOS Safari safe-area timing issues that caused gaps with position:fixed. */
  #view-schedule.active .selector-row,
  #view-teampath.active .selector-row {
    position: static;
    top: auto;
    bottom: auto;
    background: var(--surface);
    border-top: 0.3em solid var(--gold);
    border-bottom: none;
    box-shadow: 0 -2px 12px rgba(0,0,0,0.4);
    z-index: 85;
    order: 10;
    flex-shrink: 0;
  }

  /* ── Team view / schedule mobile overrides ── */
  .team-path-label {
    font-size: 1em;
    padding: 0.55em 0.9em;
  }
  .round-game-card {
    margin-bottom: 0.65em;
  }
  .round-game-header {
    padding: 0.4em 0.75em;
  }
  .round-game-dow,
  .round-game-time {
    font-size: 0.85rem;
  }
  .round-team-row {
    padding: 0.55em 0.75em;
    min-height: 2.8em;
  }
  .round-team-name {
    font-size: 0.95rem;
  }
}

/* ── Field badge: which field a game is played on (admin "Field" input) ── */
.game-field-tag {
  font-family: 'Oswald', sans-serif;
  font-size: 0.63rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  /* Soft tint keyed to the field color (currentColor = the color set by the
     numbered palette class or the user-picked inline color). No border, slight
     radius — reads as a highlight, not a tappable button. */
  background: color-mix(in srgb, currentColor 14%, transparent);
  border: none;
  border-radius: 0.3em;
  padding: 0.12em 0.4em;
  margin-left: 0.4em;
  white-space: nowrap;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.mbc-champ-label .game-field-tag { font-size: 0.7rem; }
/* Per-field colors: Teal / Orange / Purple / Pink / Blue (user-overridable in Settings > Fields) */
.game-field-tag--1 { color: var(--field-1); border-color: var(--field-1); }
.game-field-tag--2 { color: var(--field-2); border-color: var(--field-2); }
.game-field-tag--3 { color: var(--field-3); border-color: var(--field-3); }
.game-field-tag--4 { color: var(--field-4); border-color: var(--field-4); }
.game-field-tag--5 { color: var(--field-5); border-color: var(--field-5); }
/* Field tag sits as first item inside the time block — no extra left margin needed */
.round-game-day-time .game-field-tag { margin-left: 0; }

/* Bracket card headers: keep the game label hard-left and push the field tag
   + time block together to the right, so the field reads as part of the
   when/where cluster rather than hugging the game name. */
.bc-hdr .game-field-tag,
.mbc-game-mid .game-field-tag { margin-left: auto; }
/* When a game has no field tag, push the time block right on its own. */
.bc-id + .bc-time,
.mbc-game-lbl + .mbc-game-datetime { margin-left: auto; }

/* ── Team path: tappable opponent chip ("who might I play?") ──────────── */
/* Distinct pill inside the game card; tapping it jumps to the opponent's
   source game, while tapping the rest of the card jumps to this game. */
.tp-opp-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  border: 1px solid var(--border);
  border-radius: 1.2em;
  padding: 0.35em 0.75em;
  margin: -0.2em 0;
  min-height: 2.2em;        /* comfortable thumb target */
  color: var(--blue-lt);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}
.tp-opp-chip:active { background: var(--surface2); }
.tp-opp-chevron {
  font-size: 1.15em;
  line-height: 1;
  color: var(--text-dim);
}

/* Persistent jump highlight: stays until scrolled off screen or tab change */
.tp-target-hold { box-shadow: 0 0 0 0.25em var(--gold); }

/* ── Touch target sizing (coarse pointer = touchscreen) ── */
@media (pointer: coarse) {
  .tp-opp-chip        { min-height: 2.75rem; }
  .team-chip          { min-height: 2.75rem; }
  .bucket-edit-save-btn, .bucket-edit-cancel-btn { min-height: 2.75rem; }
}

/* ── Standings table (round robin / pool play — Schedule tab) ── */
.standings-block {
  max-width: 42em;
  margin: 0 auto;
  padding: 0.9em 1em 0.1em;
}
.standings-group { margin-bottom: 1.2em; }
.standings-hdr {
  font-family: 'Oswald', sans-serif;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--gold-lt);
  margin-bottom: 0.4em;
}
.standings-card {
  background: var(--surface);
  border: 0.07em solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.standings-table {
  width: 100%;
  border-collapse: collapse;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-md);
}
.standings-empty {
  text-align: center;
  color: var(--text-mute);
  padding: 2em 1em;
  font-family: 'Barlow', sans-serif;
}

/* The tiebreak order is printed under every table: a TD gets asked "why is
   that team above us" and needs the answer on the same screen. */
.standings-tiebreaks {
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-xs);
  line-height: 1.45;
  color: var(--text-mute);
  padding: 0.55em 0.8em 0.7em;
  border-top: 0.07em solid var(--border);
}
.standings-table th {
  font-family: 'Oswald', sans-serif;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  text-align: right;
  padding: 0.5em 0.65em;
  border-bottom: 0.12em solid var(--gold);
}
.standings-table th.standings-team-th { text-align: left; }
.standings-table td {
  text-align: right;
  padding: 0.45em 0.65em;
  border-bottom: 0.07em solid var(--border);
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.standings-table tr:last-child td { border-bottom: none; }
.standings-table td.standings-team {
  text-align: left;
  font-weight: 600;
  max-width: 11em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.standings-diff-pos { color: var(--win-color); }
.standings-diff-neg { color: var(--lose-color); }

/* ── Team Path record summary ── */
.team-record-bar {
  font-family: 'Oswald', sans-serif;
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--gold-lt);
  text-align: center;
  padding: 0.2em 0 0.7em;
  letter-spacing: 0.04em;
}
.team-record-detail {
  font-size: 0.72em;
  font-weight: 500;
  color: var(--text-dim);
  letter-spacing: 0.06em;
}

/* ── Print: paper bracket sheet ──────────────────────────────────────────
   TDs tape paper brackets to the fence. Print whichever tab is active with
   the interactive chrome stripped; the palette flips to paper via the token
   override in base.css. Landscape suits the bracket tree. */
@page { size: landscape; margin: 10mm; }
@media print {
  .header-controls,
  .view-tabs,
  .selector-row,
  .update-bar,
  .offline-notice,
  .bracket-flights,
  .toast,
  .mbc-arrow,
  .team-share-btn,
  .admin-quick-bar { display: none !important; }
  .site-header,
  .bucket-frozen { position: static !important; }
  .site-header { border-bottom: 0.15em solid #000; }
  .bracket-outer,
  .bracket-scroller,
  .mbc-scroll { overflow: visible !important; }
  .round-panel,
  .team-panel { overflow: visible !important; max-height: none !important; }
}

/* ── Project-winners mode ── */
/* The on/off toggle is an admin-public-btn in the header (next to Edit);
   this bar only carries the hint + clear button while projecting. */
.project-bar {
  display: flex;
  gap: 0.6em;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  padding: 0.55em 1em 0;
}
.project-clear {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.45em 0.9em;
  border-radius: var(--radius-xs);
  border: 0.07em solid var(--lose-color);
  background: transparent;
  color: var(--lose-color);
  cursor: pointer;
}
.project-clear:hover { color: var(--text); border-color: var(--text-dim); }
/* Save in the Edit bar: the one affirmative action among discards, so it
   borrows the accent rather than the destructive red the base class uses. */
.project-clear--primary {
  border-color: var(--blue);
  color: var(--blue-lt);
}
.project-clear--primary:hover { color: var(--text); border-color: var(--blue-lt); }
.project-hint {
  flex-basis: 100%;
  text-align: center;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-xs);
  color: var(--text-mute);
  padding-bottom: 0.2em;
}
@media (pointer: coarse) { .project-clear { min-height: 44px; } }
@media print { .project-bar { display: none !important; } }

/* ── Share menu (desktop fallback for navigator.share) ── */
.team-share-wrap { position: relative; display: inline-flex; }
.share-menu {
  position: absolute;
  top: calc(100% + 0.4em);
  right: 0;
  z-index: 200;
  min-width: 11em;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 0.07em solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: 0 0.5em 1.6em rgba(0,0,0,0.35);
  overflow: hidden;
}
.share-menu-item {
  padding: 0.7em 1em;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-sm);
  color: var(--text);
  text-align: left;
  text-decoration: none;
  background: none;
  border: 0;
  border-bottom: 0.07em solid var(--border);
  cursor: pointer;
  white-space: nowrap;
}
.share-menu-item:last-child { border-bottom: 0; }
.share-menu-item:hover { background: color-mix(in srgb, var(--blue) 14%, transparent); color: var(--blue-lt); }
@media (pointer: coarse) { .share-menu-item { min-height: 44px; display: flex; align-items: center; } }

/* ── Team Path "What if?" stepper ── */
.pathproj-box { max-width: 30rem; }
.pathproj-step {
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-xs);
  color: var(--text-mute);
  text-align: center;
  margin-bottom: 0.9em;
}
.pathproj-q {
  font-family: 'Oswald', sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: var(--text-xs);
  color: var(--text-mute);
  text-align: center;
  margin-bottom: 0.6em;
}
.pathproj-opts {
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: 0.6em;
  flex-wrap: wrap;
}
.pathproj-opt {
  flex: 1 1 9em;
  min-height: 3.4em;
  padding: 0.7em 0.8em;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--text);
  background: var(--surface);
  border: 0.11em solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.pathproj-opt:hover { border-color: var(--blue); background: color-mix(in srgb, var(--blue) 12%, transparent); }
/* The viewed team reads as the "us" option so a fan can pick their own side
   without reading both labels every round. */
.pathproj-opt--own { border-color: var(--gold); color: var(--gold-lt); }
.pathproj-opt--own:hover { border-color: var(--gold); background: color-mix(in srgb, var(--gold) 14%, transparent); }
/* An opponent that isn't known yet: dashed, because it isn't a pick — it
   opens the games that would decide it. */
.pathproj-opt--unknown {
  border-style: dashed;
  color: var(--text-mute);
  font-weight: 400;
  font-style: italic;
  display: flex;
  flex-direction: column;
  gap: 0.25em;
  align-items: center;
  justify-content: center;
}
.pathproj-opt-sub {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-xs);
  font-style: normal;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue-lt);
}
/* Nothing upstream is settled enough to ask about — not a button. */
.pathproj-opt--dead {
  border-style: dashed;
  color: var(--text-mute);
  font-weight: 400;
  font-style: italic;
  cursor: default;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pathproj-vs {
  align-self: center;
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-mute);
}
.pathproj-note, .pathproj-done-sub {
  margin-top: 0.8em;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-xs);
  color: var(--text-mute);
  text-align: center;
}
.pathproj-done { padding: 0.8em 0 0.2em; text-align: center; }
.pathproj-done-line {
  font-family: 'Oswald', sans-serif;
  font-size: var(--text-md);
  color: var(--gold-lt);
}
.pathproj-actions { justify-content: space-between; }

/* Projected picks: tinted blue + italic, distinct from a real (green) win */
.bc-team.won.projected { color: var(--blue-lt); }
.bc-team.won.projected .bc-name { font-style: italic; }
/* Same convention on the Team Path chain, which renders projections too. */
.round-team-name.won.projected,
.round-team-name.lost.projected { color: var(--blue-lt); font-style: italic; }
.round-team-row:has(.round-team-name.projected) .game-score { color: var(--blue-lt); }
.round-win-side--proj {
  border-left-color: var(--blue-lt);
  background: color-mix(in srgb, var(--blue-lt) 10%, transparent);
}
.round-win-side--proj .round-win-tag { color: var(--blue-lt); }
.bc-proj-chip {
  font-family: 'Oswald', sans-serif;
  font-size: 0.52rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--blue-lt);
  border: 0.09em solid color-mix(in srgb, var(--blue-lt) 55%, transparent);
  border-radius: 0.25em;
  padding: 0.05em 0.35em;
  margin-left: 0.35em;
}

/* ── CSP refactor: classes replacing generated inline styles ── */
.u-invisible { visibility: hidden; }
.u-relative { position: relative; }
.u-dim30 { opacity: 0.3; }
.u-push-right { margin-left: auto; flex-shrink: 0; }
.conn-svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: visible; }
.bcc-outerflex {
  display: flex;
  align-items: flex-start;
  /* min-content keeps the columns at their computed width instead of letting
     flex squeeze them when the bracket is wider than the viewport; the
     wrapper below then scrolls horizontally. */
  justify-content: center;
  width: 97vw;
  min-width: min-content;
  margin: 0 auto;
  box-sizing: border-box;
  padding: calc(var(--col-hdr-h)*1.7) 0 1em;
}
/* Desktop: a large field (22+ team double elim) needs more room than the
   window has once the readability floors in getDims() kick in. Scroll rather
   than shrink — the fit-to-viewport sizing was built for 8-16 team brackets. */
@media (min-width: 1280px) {
  #view-bracket.active { overflow-x: auto; }
}
/* ── Stacked desktop layout (large winners/losers brackets) ──────────────
   Side by side, a functionally-32-team double elim puts 12 round columns plus
   the championship across one screen: every column lands under the
   readability floor and the sheet has to scroll anyway. Stacking winners over
   losers halves the columns across, so the cards stay legible; the cost is
   height, which the page simply scrolls. Both rows read LEFT TO RIGHT (the
   losers side is not mirrored here) and share one column width, so the rounds
   line up vertically. See getDims / stackedDims in bracket.js. */
/* Column wrapper holding the flight pills and the bracket itself. The pills
   are MOVED in here at render time (mountFlightPills) so they sit with the
   bracket instead of in their own page-centred row with dead space beneath —
   and so they travel with it into the exported image. */
.bracket-shell {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: min-content;
}
.bracket-shell > .bracket-flights { margin: 0.9em auto 0.15em; }

.bcc-stack {
  display: flex;
  align-items: center;      /* championship centred across both rows */
  justify-content: center;
  width: 97vw;
  min-width: min-content;   /* scroll instead of squeezing the columns */
  margin: 0 auto;
  box-sizing: border-box;
  /* Top padding only has to clear the absolutely-positioned side label and
     round headers; the pills above supply the visual separation. */
  padding: calc(var(--col-hdr-h)*1.7) 0 1em;
  gap: 0.5vw;
}
.bcc-stack-rows {
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  /* Room for the second row's absolutely-positioned side label + headers. */
  gap: calc(var(--col-hdr-h)*3.2);
}
.bcc-stack-row { display: flex; flex: 0 0 auto; }
/* The championship sits INSIDE the winners row (its natural home — the
   losers row reads as the lower half of the sheet), centred vertically in
   that row and carrying the whole finals story. */
/* Stacked: the championship column behaves like the side-by-side one — the
   card is ANCHORED to the row its two feeders enter at (winners final above,
   losers final below) with the trophy block floating over it, so the
   connector lines land on the card instead of on a floating panel. */
.champ-center--stacked { align-items: stretch; }
/* Flights keep the Open tree's tinted championship COLUMN — same 4% gold, same
   left/right rules, spanning the full bracket height. It used to be a small
   bordered box floating beside the tree, which read as a different kind of
   thing from the main bracket's championship when the two sit a pill-click
   apart. Everything else comes from .champ-center--desktop, including the
   .champ-anchor treatment that sits the title card on its feeders' row.
   justify-content only governs the FALLBACK, used when the final has no
   on-screen winner feeder to be level with — then the block just centres. */
.champ-center--flight { justify-content: center; }
.champ-center--flight .champ-inner,
.champ-center--flight .champ-bc,
.champ-center--flight .champ-winner { width: 100%; }

/* Captions around the losers final, which the stacked layout draws in the
   winners row beside the winners final so both visibly feed the title game.
   It used to be drawn in BOTH rows — a dashed copy here and the real game at
   the end of the losers row — which cost the losers side a whole column to
   say the same thing twice. Now it lives here only, named above and with its
   destination below. */
.bc-final-cap {
  position: absolute;
  left: 0;
  right: 0;
  text-align: center;
  font-family: 'Oswald', sans-serif;
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  /* Gold, matching the "winner to ..." note in the losers row. These captions
     are the thread a reader follows between the two stacked rows, so they
     read as one set rather than as a label and an afterthought. */
  color: var(--gold);
  pointer-events: none;
}
/* Under the card rather than above it: says where the winner goes, since this
   game is drawn in the winners row and no longer sits at the end of the
   losers row. Same colour as the caption above — position is the difference. */
/* Bigger than a round column: this is the thing a visitor looks for first. */
.champ-center--stacked .champ-title { font-size: 0.92rem; letter-spacing: 0.2em; }
.champ-center--stacked .champ-trophy { font-size: 2.6em; }
.champ-center--stacked .champ-gametime { font-size: 0.86rem; }
.champ-center--stacked .champ-winner { font-size: 1.05rem; }

/* Who is playing for it, spelled out — "Winner of G.39" on its own tells a
   visitor nothing. */
.champ-feeders {
  display: flex;
  align-items: stretch;
  gap: 0.5em;
  width: 100%;
  margin-top: 0.9em;
  font-family: 'Barlow', sans-serif;
}
.champ-feed { flex: 1 1 0; min-width: 0; text-align: center; }
.champ-feed-lbl {
  font-family: 'Oswald', sans-serif;
  font-size: 0.56rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.champ-feed-team { font-size: var(--text-sm); color: var(--text-dim); line-height: 1.3; }
.champ-feed-vs {
  align-self: center;
  font-family: 'Oswald', sans-serif;
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-mute);
}

/* The losers-bracket final, repeated here so the championship's second
   feeder is legible without scrolling to the other bracket. */
.champ-lbfinal {
  width: 100%;
  margin-top: 1.1em;
  padding-top: 0.9em;
  border-top: 0.07em solid var(--border);
  text-align: center;
}
.champ-lbfinal-lbl {
  font-family: 'Oswald', sans-serif;
  font-size: 0.6rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-mute);
  margin-bottom: 0.4em;
}
.champ-lbfinal .bc { position: relative; left: auto; right: auto; }
.champ-lbfinal-note {
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-xs);
  color: var(--text-mute);
  margin-top: 0.4em;
  line-height: 1.35;
}

.bcc-sideflex { position: relative; flex: 0 0 auto; display: flex; }
.bcc-rowflex { display: flex; flex-direction: row; }
.bracket-side-label--abs { position: absolute; top: calc(var(--col-hdr-h)*-2.2); }
.bc.bc--static { position: relative; left: auto; right: auto; }
.team-path-win-label--loss { color: var(--lose-color); }

/* ── Share bracket as an image ──────────────────────────────────────── */
.share-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.6);
  padding: 1.5em;
}
.share-box {
  background: var(--surface);
  border: 0.07em solid var(--border);
  border-radius: var(--radius-md);
  padding: 1.2em;
  max-width: min(92vw, 60em);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  gap: 0.8em;
}
.share-title {
  font-family: 'Oswald', sans-serif;
  font-size: 0.95rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text);
}
.share-opts { display: flex; flex-wrap: wrap; gap: 1em; }
.share-opt {
  display: flex;
  align-items: center;
  gap: 0.45em;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-sm);
  color: var(--text-dim);
  cursor: pointer;
}
/* Checkerboard so a transparent-background render is still readable. */
.share-preview-wrap {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  border: 0.07em solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface2);
}
.share-preview { display: block; max-width: 100%; height: auto; }
.share-actions { display: flex; justify-content: flex-end; gap: 0.6em; flex-wrap: wrap; }
.share-dl { background: var(--blue); border-color: var(--blue); color: #fff; }
.share-hint {
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-xs);
  color: var(--text-mute);
  text-align: right;
}

/* Offscreen render frame for the image exporter. It must actually LAY OUT
   (the bracket is sized in vw/vh and measured with getBoundingClientRect),
   so it can't be display:none or zero-sized — it is parked off-canvas
   instead. Fixed size = the virtual desktop viewport the image is rendered
   at, so a phone still exports the full desktop bracket. */
.share-frame {
  position: fixed;
  left: -20000px;
  top: 0;
  width: 1600px;
  height: 1000px;
  border: 0;
  opacity: 0;
  pointer-events: none;
}
.share-themes { gap: 1.1em; }
/* Two of the three scope labels start with "All brackets", so they need room
   to sit on their own lines rather than wrapping mid-label. */
.share-scope { gap: 0.9em 1.1em; flex-wrap: wrap; }
.share-align { gap: 0.9em 1.1em; flex-wrap: wrap; }
.share-opt-note { color: var(--text-mute); }
