/* DO NOT EDIT — copied from packages/shared/src/design/css/tournament.css
   by `npm run tokens`. Edit the source there, regenerate, commit both.
   A vitest in packages/shared fails if this file drifts from the source. */
/* Tournament formats, bans, prizes and organizer UI — shared presentation
   (2026-09-28 batch, task C1). This is how the desktop app, `/app` (via the
   shared `console.js` renderer, task C2) and `/m` (its own ES6 phone pages,
   D1-D5) stay visually one product for tournament screens, per CLAUDE.md's
   "Shared design system" section.

   Hand-written, NOT generated. `npm run tokens` COPIES this file to
   apps/server/public/shared/tournament.css so the no-build web surfaces can
   link it; the desktop app imports it directly through the `@tdtt/shared`
   exports map (`apps/desktop/src/index.css`). Edit this file, never the copy.

   Every value here comes from tokens.css custom properties, or is derived
   from one with `color-mix()`/`rgb(from …)` — no new raw colours. Mobile rule
   (CLAUDE_WEB_MOBILE.md): a SURFACE background (a panel/card fill) is always
   a solid token (`--surface`, `--surface-2`, `--input`, `--bg`), never an
   alpha mix — alpha is reserved for glows, washes and borders layered OVER a
   solid fill, never for the fill itself.

   ── Accent system ──────────────────────────────────────────────────────────
   `--tn-accent` is the one colour every component in this file reads (with a
   `var(--tn-accent, var(--cyan))` fallback so a component still renders sanely
   if used outside any `[data-accent]` ancestor, e.g. in `_preview.html`).
   `[data-accent="cyan|magenta|orange|gold"]` sets it on whatever element
   carries the attribute (typically `.tdtt-tn-console`/`.tdtt-tn-builder`/
   `.tdtt-tv-board`, the per-tournament brand accent from the Brand tab) and it
   cascades to every descendant through ordinary custom-property inheritance.
   There is no separate `--tn-accent-glow`/`--tn-accent-wash` custom property —
   every glow/wash below computes its own `color-mix()`/`rgb(from …)` straight
   off `--tn-accent` inline, to keep the token surface small.

   ── The chamfered panel (`.tdtt-tn-panel`) ─────────────────────────────────
   The angled-corner neon frame from the mockups (Console Run/View/Format/
   Players/Brand, the builder, the register page) is ONE mixin class,
   `.tdtt-tn-panel`, combined in markup with whatever semantic class a
   component needs, e.g. `<div class="tdtt-tn-panel tdtt-tn-table">`. It chops
   the top-left and bottom-right corners with `clip-path` (a `::before`
   pseudo-element, inset 1.5px and re-clipped, paints the solid surface fill
   inside a same-hue accent "border"), and throws a soft `drop-shadow` glow
   (NOT `box-shadow` — `clip-path` clips box-shadow away with the corners, so
   the glow must be a filter). `--tn-cut` (default 16px) sizes the chamfer;
   `.tdtt-tn-panel--sm` shrinks it for compact cards (tables, place cards).
   `.tdtt-tn-panel__head` / `__icon` / `__title` / `__actions` are its optional
   header row.

   ── Component list (brief C1, each documented at its own rule below) ──────
   Console / phone (`.tdtt-tn-*`):
     .tdtt-tn-panel        chamfered card mixin (+ __head/__icon/__title/__actions)
     .tdtt-tn-hero         banner (create builder / register page header)
     .tdtt-tn-tabs         role tab bar (Run/View/Format/Players/Brand) (+ __tab, .on)
     .tdtt-tn-stat-row     grid of .tdtt-tn-stat tiles
     .tdtt-tn-stat         one stat tile (+ __i/__v/__l)
     .tdtt-tn-table        a Tables-grid match card (+ __head/__label/__badge/
                            __body/__player/__avatar/__name/__vs, --reported,
                            --live)
     .tdtt-tn-place        a prize/standings place card, `data-rank="1|2|3"`
                            (+ __medal/__avatar/__name/__record/__history/__row)
     .tdtt-tn-chip-ban     a banned-hero chip (+ __portrait/__label)
     .tdtt-tn-livebar      the bottom live action bar (+ __btn, --cyan/--magenta/
                            --gold, .on)
     .tdtt-tn-steps        pre-game step indicator, one dot per step
                            (+ __step, .done, .on)
     .tdtt-tn-bracket      elimination bracket (+ __round/__match/__slot/
                            __connector/__label)
     .tdtt-tn-group        a group-stage / swiss standings pod (+ __head/__row/__cell)
     .tdtt-tn-preview      builder/brand live preview frame (+ __frame/__chip)
     .tdtt-tn-toggle-row   a labelled toggle switch row (+ __label/__hint/
                            __switch, .on)
     .tdtt-tn-stepper      a +/- number input (+ __btn, __value)
     .tdtt-tn-field        a labeled form field wrapper (+ .tdtt-tn-label,
                            .tdtt-tn-input/.tdtt-tn-select/.tdtt-tn-textarea)
     .tdtt-tn-console      the organizer console shell (phone-stacked below
                            700px; two-column with a left sub-rail and sticky
                            .tdtt-tn-console__aside at >=1024px)
     .tdtt-tn-builder      the create-tournament builder shell (sticky
                            .tdtt-tn-preview column at >=1024px)

   Projector boards (`.tdtt-tv-*`), one shared shell + eight states:
     .tdtt-tv-board        full-bleed dark stage (hex texture, corner glow
                            brackets) — wraps every state below
     .tdtt-tv-header       title + POWERED BY + center announcement pill +
                            right round/format/timer meta (+ __title/__announce/
                            __meta/__timer)
     .tdtt-tv-panel        a centered message/content frame reused by several
                            states (chamfered, same mixin idea as .tdtt-tn-panel)
     .tdtt-tv-table        a pairings/round match card (+ __label/__live/__vs/
                            __player)
     .tdtt-tv-standings    a ranked table (+ __head/__row)
     .tdtt-tv-prizes       a numbered prize list (+ __row/__rank)
     .tdtt-tv-gate         4-digit view-code entry screen
     .tdtt-tv-signin       QR + room-code "waiting for players" screen
     .tdtt-tv-pairings     "Round N Pairings" grid of .tdtt-tv-table cards
     .tdtt-tv-round        round-in-progress board (+ __match/__player/__hp)
     .tdtt-tv-intermission "INTERMISSION" title + standings/prizes panels
     .tdtt-tv-podium       Final Results (+ __place[data-rank], --first)
     .tdtt-tv-disabled     "organizer has not enabled the view screen" empty state
     .tdtt-tv-sponsor      sponsor/break slide

   Breakpoints (spec §8.0):
     - Below 700px: the phone layout from the mockups (stacked, full width).
     - >=1024px: `.tdtt-tn-console` becomes two columns (tabs as a left
       sub-rail, a sticky `.tdtt-tn-console__aside` preview column);
       `.tdtt-tn-builder` gets a sticky `.tdtt-tn-preview` right column. */

/* ── accent system ─────────────────────────────────────────────────────── */
[data-accent='cyan'] { --tn-accent: var(--cyan); }
[data-accent='magenta'] { --tn-accent: var(--magenta); }
[data-accent='orange'] { --tn-accent: var(--orange); }
[data-accent='gold'] { --tn-accent: var(--gold); }

/* ── chamfered panel mixin ─────────────────────────────────────────────── */
.tdtt-tn-panel {
  position: relative; isolation: isolate;
  --tn-cut: 16px;
  padding: 18px 20px;
  color: var(--text);
  background: var(--tn-accent, var(--cyan));
  clip-path: polygon(
    var(--tn-cut) 0, 100% 0,
    100% calc(100% - var(--tn-cut)), calc(100% - var(--tn-cut)) 100%,
    0 100%, 0 var(--tn-cut)
  );
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--tn-accent, var(--cyan)) 30%, transparent));
}
.tdtt-tn-panel::before {
  content: ''; position: absolute; inset: 1.5px; z-index: -1;
  background: var(--surface);
  clip-path: polygon(
    var(--tn-cut) 0, 100% 0,
    100% calc(100% - var(--tn-cut)), calc(100% - var(--tn-cut)) 100%,
    0 100%, 0 var(--tn-cut)
  );
}
.tdtt-tn-panel--sm { --tn-cut: 10px; padding: 12px 14px; }
.tdtt-tn-panel__head {
  display: flex; align-items: center; gap: 9px; margin-bottom: 12px;
  font-family: var(--head); font-size: 12px; font-weight: 700;
  letter-spacing: 0.11em; text-transform: uppercase; color: var(--tn-accent, var(--cyan));
}
.tdtt-tn-panel__icon { display: flex; color: var(--tn-accent, var(--cyan)); }
.tdtt-tn-panel__title { color: var(--tn-accent, var(--cyan)); }
.tdtt-tn-panel__actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }

/* ── hero banner ──────────────────────────────────────────────────────────
   The builder's "THE ARENA / CUSTOM FORMAT" header and the /m register
   page's event header. A magenta/orange wash over a dark plate, a dotted
   texture tinted by the accent, and an oversized ghosted glyph — same layered
   language as chrome.css's `.tdtt-banner`, kept as a SEPARATE class because
   this stylesheet is a standalone import (tournament screens only) and must
   not require chrome.css to be loaded first. */
.tdtt-tn-hero {
  position: relative; isolation: isolate; overflow: hidden;
  padding: 20px 24px; border-radius: 4px;
  background: linear-gradient(160deg, var(--surface) 0%, var(--bg) 78%);
}
.tdtt-tn-hero::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(120% 140% at 85% 15%, color-mix(in srgb, var(--magenta) 26%, transparent) 0%, transparent 60%),
    radial-gradient(90% 120% at 0% 100%, color-mix(in srgb, var(--tn-accent, var(--cyan)) 20%, transparent) 0%, transparent 55%);
}
.tdtt-tn-hero::after {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: radial-gradient(color-mix(in srgb, var(--tn-accent, var(--cyan)) 30%, transparent) 1px, transparent 1px);
  background-size: 8px 8px; opacity: 0.4;
}
.tdtt-tn-hero__eyebrow {
  font-family: var(--head); font-size: 11px; font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--tn-accent, var(--cyan));
}
.tdtt-tn-hero__title {
  margin: 4px 0 0;
  font-family: var(--display); font-weight: 800; font-size: clamp(19px, 2.6vw, 29px);
  line-height: 1; letter-spacing: -0.01em; text-transform: uppercase; color: var(--text);
}
.tdtt-tn-hero__title em { font-style: normal; color: inherit; }
.tdtt-tn-hero__sub { margin: 6px 0 0; max-width: 56ch; font-family: var(--body); font-size: 13.5px; color: var(--text-dim); }
.tdtt-tn-hero__meta { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 10px; font-size: 12px; color: var(--text-dim); }
.tdtt-tn-hero__badges { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

/* ── role tab bar ─────────────────────────────────────────────────────────
   Run / View / Format / Players / Brand / Share. Each tab is its own bordered
   pill (distinct from `.seg-slab`'s single inset track) with the active tab a
   solid magenta fill, matching the mockups exactly. */
.tdtt-tn-tabs { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 2px; scrollbar-width: none; }
.tdtt-tn-tabs::-webkit-scrollbar { display: none; }
.tdtt-tn-tabs__tab {
  flex: 0 0 auto;
  padding: 10px 16px;
  font-family: var(--head); font-size: 11.5px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-dim); background: var(--surface);
  border: 1px solid var(--border); border-radius: 10px;
  cursor: pointer; white-space: nowrap;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
@media (hover: hover) {
  .tdtt-tn-tabs__tab:not(.on):hover { border-color: var(--border-hi); color: var(--text); }
}
.tdtt-tn-tabs__tab:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.tdtt-tn-tabs__tab.on {
  color: var(--text); background: var(--magenta); border-color: transparent;
  box-shadow: 0 0 16px color-mix(in srgb, var(--magenta) 45%, transparent);
}

/* ── stat tiles ───────────────────────────────────────────────────────────
   Players tab's Registered/Checked-in/Pending/Dropped tiles, and the Run
   tab's "R2 OF 3 ROUNDS" headline figure. */
.tdtt-tn-stat-row { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
.tdtt-tn-stat {
  display: flex; flex-direction: column; gap: 2px;
  padding: 12px 14px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 12px;
}
.tdtt-tn-stat .tdtt-tn-stat__i { display: flex; color: var(--tn-accent, var(--cyan)); margin-bottom: 4px; }
.tdtt-tn-stat .tdtt-tn-stat__v { font-family: var(--head); font-size: 1.6rem; font-weight: 900; color: var(--text); line-height: 1; }
.tdtt-tn-stat .tdtt-tn-stat__l { font-size: 0.6rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-dim); }
/* The big "R2 OF 3 ROUNDS" headline variant inside .tdtt-tn-panel. */
.tdtt-tn-stat--headline .tdtt-tn-stat__v {
  font-size: clamp(2.2rem, 6vw, 3rem); color: var(--gold);
  text-shadow: 0 0 20px color-mix(in srgb, var(--gold) 55%, transparent);
}

/* ── table card (Tables grid) ─────────────────────────────────────────────
   `<div class="tdtt-tn-panel tdtt-tn-panel--sm tdtt-tn-table">`. The colored
   corner ribbon is `__label` ("TABLE 1"), chamfered to match the card's own
   top-left cut; `__badge` is the Reported/Live pill. */
.tdtt-tn-table { padding-top: 34px; }
.tdtt-tn-table__label {
  position: absolute; left: 0; top: 0;
  padding: 5px 14px 5px 10px;
  font-family: var(--head); font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em;
  color: var(--bg); background: var(--tn-accent, var(--cyan));
  clip-path: polygon(0 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
}
.tdtt-tn-table__badge {
  position: absolute; right: 12px; top: 10px;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px;
  font-family: var(--head); font-size: 10px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--green); background: color-mix(in srgb, var(--green) 16%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--green) 45%, transparent);
}
/* ── "now running" headline (C2-polish): the big italic round indicator plus
   its two dim sublines, "OF N ROUNDS" and "N PLAYERS • M TABLES" -- the
   mockups' left-number-plus-stacked-meta layout, distinct from the plain
   .tdtt-tn-stat tile grid used elsewhere. */
.tdtt-tn-now-running { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.tdtt-tn-now-running__round {
  font-family: var(--display); font-style: italic; font-weight: 800;
  font-size: clamp(1.9rem, 6vw, 2.8rem); line-height: 0.95; color: var(--gold);
  text-shadow: 0 0 20px color-mix(in srgb, var(--gold) 55%, transparent);
}
.tdtt-tn-now-running__meta { display: flex; flex-direction: column; gap: 3px; }
.tdtt-tn-now-running__meta-line {
  font-family: var(--head); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-dim);
}
/* ── round status banner (C2-polish): all-reported (green) vs N-still-out
   (orange), shown inside the "Now Running" panel whenever the current round
   has at least one table. */
.tdtt-tn-round-banner {
  display: flex; align-items: center; gap: 10px; margin-top: 12px;
  padding: 11px 16px; border-radius: 10px;
  font-family: var(--head); font-size: 12.5px; font-weight: 700; letter-spacing: 0.02em;
}
.tdtt-tn-round-banner--ok {
  color: var(--green); background: color-mix(in srgb, var(--green) 14%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--green) 45%, transparent);
}
.tdtt-tn-round-banner--warn {
  color: var(--orange); background: color-mix(in srgb, var(--orange) 14%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--orange) 45%, transparent);
}
.tdtt-tn-round-banner__icon { flex: none; }
/* ── per-player avatar circle (C2-polish): a ring + filled dot in a colour
   deterministic from the player id (tables grid), replaced by the player's
   own photo when one is set. `data-c` cycles 1-7 through the bf palette
   tokens -- two (slot 4 "purple-ish", slot 6 "blue-ish") have no direct
   token, so they're derived with color-mix() off tokens that do exist,
   never a raw hex. */
.tdtt-tn-avatar {
  --tn-avatar-c: var(--cyan);
  position: relative; flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--tn-avatar-c); background: var(--surface);
}
.tdtt-tn-avatar::before {
  content: ''; width: 12px; height: 12px; border-radius: 50%; background: var(--tn-avatar-c);
}
.tdtt-tn-avatar__img {
  position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 50%; object-fit: cover;
}
.tdtt-tn-avatar[data-c='1'] { --tn-avatar-c: var(--cyan); }
.tdtt-tn-avatar[data-c='2'] { --tn-avatar-c: var(--magenta); }
.tdtt-tn-avatar[data-c='3'] { --tn-avatar-c: var(--gold); }
.tdtt-tn-avatar[data-c='4'] { --tn-avatar-c: color-mix(in srgb, var(--magenta) 55%, var(--cyan) 45%); }
.tdtt-tn-avatar[data-c='5'] { --tn-avatar-c: var(--green); }
.tdtt-tn-avatar[data-c='6'] { --tn-avatar-c: color-mix(in srgb, var(--cyan) 60%, var(--chrome) 40%); }
.tdtt-tn-avatar[data-c='7'] { --tn-avatar-c: var(--orange); }
.tdtt-tn-table--live .tdtt-tn-table__badge {
  color: var(--magenta); background: color-mix(in srgb, var(--magenta) 16%, var(--surface));
  border-color: color-mix(in srgb, var(--magenta) 45%, transparent);
}
.tdtt-tn-table__body { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tdtt-tn-table__player { display: flex; align-items: center; gap: 8px; min-width: 0; }
.tdtt-tn-table__avatar {
  flex: none; width: 30px; height: 30px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--head); font-weight: 900; font-size: 0.75rem; color: var(--bg);
  background: var(--tn-accent, var(--cyan));
}
.tdtt-tn-table__name { font-family: var(--body); font-weight: 600; font-size: 13.5px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tdtt-tn-table__vs { flex: none; font-family: var(--head); font-size: 11px; font-weight: 700; color: var(--muted); }

/* ── place card (prize / final standings) ─────────────────────────────────
   `<div class="tdtt-tn-panel tdtt-tn-place" data-rank="1|2|3">`. No new raw
   colours: rank 1 uses --gold, rank 2 derives a "silver" from --chrome, rank
   3 derives a "bronze" from --orange (owner ruling, per the C1 brief). */
.tdtt-tn-place {
  --place-c: var(--gold);
  text-align: center;
  --tn-accent: var(--place-c);
}
.tdtt-tn-place[data-rank='2'] { --place-c: var(--chrome); }
.tdtt-tn-place[data-rank='3'] { --place-c: var(--orange); }
.tdtt-tn-place__medal {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; margin: 0 auto 8px; border-radius: 50%;
  font-family: var(--head); font-weight: 900; font-size: 0.9rem;
  color: var(--bg); background: var(--place-c);
  box-shadow: 0 0 12px color-mix(in srgb, var(--place-c) 55%, transparent);
}
.tdtt-tn-place__avatar {
  width: 64px; height: 64px; margin: 0 auto 8px; border-radius: 16px; overflow: hidden;
  background: var(--surface-2); border: 2px solid var(--place-c);
}
.tdtt-tn-place__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tdtt-tn-place__name { font-family: var(--head); font-weight: 700; font-size: 1rem; color: var(--text); }
.tdtt-tn-place__record { font-family: var(--mono); font-size: 12px; color: var(--place-c); margin-top: 2px; }
.tdtt-tn-place__history { margin-top: 10px; text-align: left; border-top: 1px solid var(--border); padding-top: 8px; }
.tdtt-tn-place__row { display: flex; align-items: center; gap: 8px; padding: 3px 0; font-size: 12px; color: var(--text-dim); }
.tdtt-tn-place__row .w { color: var(--green); font-weight: 700; }
.tdtt-tn-place__row .l { color: var(--red); font-weight: 700; }
/* First place gets the emphasized, larger treatment from the podium mockup. */
.tdtt-tn-place--first { transform: scale(1.04); }
.tdtt-tn-place--first .tdtt-tn-place__avatar { width: 80px; height: 80px; }

/* ── banned-hero chip ─────────────────────────────────────────────────────
   A greyed-out portrait with a diagonal strike, used in the bans editor and
   on the register page to show which heroes a player cannot pick. */
.tdtt-tn-chip-ban { display: flex; flex-direction: column; align-items: center; gap: 4px; width: 64px; }
.tdtt-tn-chip-ban__portrait {
  position: relative; width: 64px; height: 88px; border-radius: 10px; overflow: hidden;
  background: var(--surface-2); border: 1px solid var(--border);
  filter: grayscale(0.85) brightness(0.6);
}
.tdtt-tn-chip-ban__portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tdtt-tn-chip-ban__portrait::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 46%, var(--red) 48%, var(--red) 52%, transparent 54%);
  opacity: 0.85;
}
.tdtt-tn-chip-ban__label { font-size: 10.5px; color: var(--text-dim); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }

/* ── live action bar ──────────────────────────────────────────────────────
   The bottom bar: Pair Next (solid), Announce / Timer / Break (outline hue
   variants), matching `.tdtt-btn--cyan/--gold`'s "fixed hue" family. */
.tdtt-tn-livebar {
  display: flex; gap: 10px; margin-top: 12px; padding: 10px;
  position: sticky; bottom: 0; z-index: 5;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(8px);
  border: 1px solid var(--border); border-radius: 14px;
}
.tdtt-tn-livebar__btn {
  flex: 1 1 0; display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 46px; padding: 0 10px;
  font-family: var(--head); font-size: 11.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--cyan); background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--cyan) 45%, transparent); border-radius: 11px;
  cursor: pointer; transition: filter 0.15s, background 0.15s;
}
@media (hover: hover) {
  .tdtt-tn-livebar__btn:hover { filter: brightness(1.15); }
}
.tdtt-tn-livebar__btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.tdtt-tn-livebar__btn[disabled] { opacity: 0.45; cursor: not-allowed; filter: none; }
.tdtt-tn-livebar__btn--magenta { color: var(--magenta); border-color: color-mix(in srgb, var(--magenta) 45%, transparent); }
.tdtt-tn-livebar__btn--gold { color: var(--gold); border-color: color-mix(in srgb, var(--gold) 45%, transparent); }
/* The one filled/primary slot (Pair Next / Start Top Cut). */
.tdtt-tn-livebar__btn.on {
  color: var(--bg); background: var(--cyan); border-color: transparent;
  box-shadow: 0 0 18px color-mix(in srgb, var(--cyan) 45%, transparent);
}
/* A hue-modified button's own "on" state (C2-polish: the Break toggle)
   overrides the cyan default above -- same specificity, later in source. */
.tdtt-tn-livebar__btn--magenta.on {
  color: var(--bg); background: var(--magenta);
  box-shadow: 0 0 18px color-mix(in srgb, var(--magenta) 45%, transparent);
}
.tdtt-tn-livebar__btn--gold.on {
  color: var(--bg); background: var(--gold);
  box-shadow: 0 0 18px color-mix(in srgb, var(--gold) 45%, transparent);
}

/* ── pre-game step indicator ──────────────────────────────────────────────
   One dot per step (roll / ban / report) shown on a table card, so the
   organizer can see and act on a table's current step at a glance. */
.tdtt-tn-steps { display: flex; align-items: center; gap: 6px; }
.tdtt-tn-steps__step {
  flex: none; width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--head); font-size: 10px; font-weight: 700;
  color: var(--muted); background: var(--input); border: 1px solid var(--border);
}
.tdtt-tn-steps__step.on {
  color: var(--bg); background: var(--tn-accent, var(--cyan)); border-color: transparent;
  box-shadow: 0 0 8px color-mix(in srgb, var(--tn-accent, var(--cyan)) 55%, transparent);
}
.tdtt-tn-steps__step.done { color: var(--green); background: var(--input); border-color: color-mix(in srgb, var(--green) 55%, transparent); }
.tdtt-tn-steps__sep { flex: 1 1 12px; height: 1px; background: var(--border); }

/* ── bracket ───────────────────────────────────────────────────────────────
   Elimination-stage bracket: columns of rounds, each with match slots joined
   by connector lines (the projector "TO ROUND 2" arrows use the same idea —
   see .tdtt-tv-pairings — but the console bracket is its own vertical/
   horizontal scroller since a phone screen can't show a full bracket at once). */
.tdtt-tn-bracket { display: flex; gap: 28px; overflow-x: auto; padding: 6px 2px 14px; }
.tdtt-tn-bracket__round { display: flex; flex-direction: column; justify-content: space-around; gap: 18px; flex: none; min-width: 190px; }
.tdtt-tn-bracket__label { font-family: var(--head); font-size: 10px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-dim); text-align: center; }
.tdtt-tn-bracket__match { position: relative; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.tdtt-tn-bracket__slot { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px; font-size: 12.5px; color: var(--text); }
.tdtt-tn-bracket__slot:first-child { border-bottom: 1px solid var(--border); }
.tdtt-tn-bracket__slot.win { color: var(--tn-accent, var(--cyan)); font-weight: 700; }
.tdtt-tn-bracket__score { font-family: var(--mono); color: var(--text-dim); }
/* A connector is a simple two-sided bracket rendered as a border, positioned
   by the caller between two match slots feeding into the next round. */
.tdtt-tn-bracket__connector { flex: none; width: 20px; align-self: center; height: 40%; border: 1px solid var(--border); border-left: none; border-radius: 0 4px 4px 0; }

/* ── group / swiss pod ────────────────────────────────────────────────────
   A small standings table for one group (group-stage) or the whole field
   (swiss). Distinct from `.tdtt-tv-standings` (projector, bigger type). */
.tdtt-tn-group__head, .tdtt-tn-group__row {
  display: flex; align-items: center; gap: 10px; padding: 7px 10px;
}
.tdtt-tn-group__head {
  font-family: var(--head); font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); background: var(--surface-2); border-radius: 8px 8px 0 0;
}
.tdtt-tn-group__row { border-bottom: 1px solid var(--border); font-size: 12.5px; color: var(--text); }
.tdtt-tn-group__row:last-child { border-bottom: none; }
.tdtt-tn-group__cell { flex: 1 1 auto; min-width: 0; }
.tdtt-tn-group__cell--num { flex: 0 0 auto; width: 44px; text-align: right; font-family: var(--mono); color: var(--text-dim); }
.tdtt-tn-group__cell--pl { flex: 0 0 auto; width: 24px; text-align: center; font-family: var(--head); font-weight: 900; color: var(--text-dim); }

/* ── live/brand preview frame ─────────────────────────────────────────────
   The builder's Preview Summary and the Brand tab's view-screen preview: a
   small chamfered frame with a chip row underneath. */
.tdtt-tn-preview__frame {
  aspect-ratio: 16 / 9; border-radius: 10px; overflow: hidden;
  background: var(--bg); border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  color: var(--muted); font-family: var(--head); font-weight: 700; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
}
.tdtt-tn-preview__chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.tdtt-tn-preview__chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px; border-radius: 9px;
  font-family: var(--body); font-size: 11.5px; color: var(--text);
  background: var(--surface-2); border: 1px solid var(--border);
}
.tdtt-tn-preview__chip .tdtt-tn-preview__chip-i { color: var(--tn-accent, var(--cyan)); display: flex; }
.tdtt-tn-preview__chip .tdtt-tn-preview__chip-l { display: block; font-size: 9.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; }

/* ── toggle row ────────────────────────────────────────────────────────────
   A labelled row ending in a pill switch — "Require approval to join",
   "Win-lock after a win", "Allow late registration". */
.tdtt-tn-toggle-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; }
.tdtt-tn-toggle-row__body { flex: 1 1 auto; min-width: 0; }
.tdtt-tn-toggle-row__label { font-family: var(--body); font-size: 13.5px; font-weight: 600; color: var(--text); }
.tdtt-tn-toggle-row__hint { display: block; font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.tdtt-tn-toggle-row__switch {
  flex: none; position: relative; width: 44px; height: 24px; border-radius: 999px;
  background: var(--input); border: 1px solid var(--border);
  cursor: pointer; padding: 0; transition: background 0.15s, border-color 0.15s;
}
.tdtt-tn-toggle-row__switch::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: var(--muted); transition: transform 0.15s, background 0.15s;
}
.tdtt-tn-toggle-row__switch:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.tdtt-tn-toggle-row__switch.on { background: color-mix(in srgb, var(--cyan) 40%, var(--input)); border-color: transparent; }
.tdtt-tn-toggle-row__switch.on::after { transform: translateX(20px); background: var(--text); }

/* ── stepper (+/- number input) ───────────────────────────────────────────
   Bring count, Ban count, Number of Rounds, Player Cap. */
.tdtt-tn-stepper { display: inline-flex; align-items: center; gap: 8px; }
.tdtt-tn-stepper__value {
  min-width: 42px; padding: 8px 10px; text-align: center;
  font-family: var(--mono); font-size: 14px; color: var(--text);
  background: var(--input); border: 1px solid var(--border); border-radius: 8px;
}
.tdtt-tn-stepper__btn {
  flex: none; width: 32px; height: 32px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--head); font-weight: 900; font-size: 15px; line-height: 1;
  color: var(--tn-accent, var(--cyan)); background: var(--surface-2);
  border: 1px solid var(--border); cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
@media (hover: hover) {
  .tdtt-tn-stepper__btn:hover { border-color: var(--border-hi); }
}
.tdtt-tn-stepper__btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.tdtt-tn-stepper__btn[disabled] { opacity: 0.4; cursor: not-allowed; }

/* ── form field (label + input/select/textarea) ───────────────────────────
   console.js's builder and console tabs repeat the same "small dim label
   over a bordered input" shape at dozens of call sites (name, date, time,
   search boxes, prize labels, the Run/Players tab forms) — this is that
   shape as classes instead of an inline `style="..."` block per call site. */
.tdtt-tn-field { margin-bottom: 12px; }
.tdtt-tn-label { display: block; font-size: 11px; color: var(--text-dim); margin-bottom: 4px; }
.tdtt-tn-input, .tdtt-tn-select, .tdtt-tn-textarea {
  padding: 8px 10px; background: var(--input); border: 1px solid var(--border);
  border-radius: 8px; color: var(--text); font: inherit;
}
.tdtt-tn-input { width: 100%; }
.tdtt-tn-textarea { width: 100%; resize: vertical; }

/* ── console / builder shells ──────────────────────────────────────────────
   Below 700px both are a single stacked phone column (the mockups' native
   layout — no rule needed, that's the unqualified base). At >=1024px the
   console gains a left sub-rail (the tab bar turns vertical) and a sticky
   preview column; the builder gains a sticky Preview Summary column. */
.tdtt-tn-console { display: flex; flex-direction: column; gap: 16px; }
.tdtt-tn-console__body { display: flex; flex-direction: column; gap: 16px; }
.tdtt-tn-builder { display: flex; flex-direction: column; gap: 16px; }

@media (min-width: 1024px) {
  .tdtt-tn-console { flex-direction: row; align-items: flex-start; gap: 20px; }
  .tdtt-tn-console__body { flex: 1 1 auto; min-width: 0; }
  /* The tab bar becomes a left sub-rail: a vertical stack, sticky so it stays
     visible while the body column scrolls. */
  .tdtt-tn-console .tdtt-tn-tabs {
    flex: 0 0 180px; flex-direction: column; overflow-x: visible;
    position: sticky; top: 0; align-self: flex-start;
  }
  .tdtt-tn-console .tdtt-tn-tabs__tab { text-align: left; }
  .tdtt-tn-console__aside { flex: 0 0 320px; position: sticky; top: 0; align-self: flex-start; }

  .tdtt-tn-builder { flex-direction: row; align-items: flex-start; gap: 20px; }
  .tdtt-tn-builder__body { flex: 1 1 auto; min-width: 0; }
  .tdtt-tn-preview { flex: 0 0 320px; position: sticky; top: 16px; align-self: flex-start; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Projector boards (`.tdtt-tv-*`) — sign-in, pairings, round, intermission,
   podium, gate, disabled, sponsor slide. These render on a TV/monitor, not a
   phone or desktop window, so type is larger and there is no <700px rule —
   the board always fills the viewport it's given.
   ═══════════════════════════════════════════════════════════════════════ */

.tdtt-tv-board {
  position: relative; isolation: isolate; overflow: hidden;
  min-height: 100vh; padding: 24px 32px;
  color: var(--text); background: var(--bg);
}
/* Fallback ONLY when no [data-accent] is set on this element — `:not()`
   keeps this at the same (0,2,0) specificity family as the `[data-accent]`
   rules above it in a way that never wins over them for an element that
   actually HAS the attribute. Fix round 2: this used to be a bare class
   rule, same specificity as those `[data-accent=X]` rules but LATER in
   source order, so it always won and every accent rendered cyan regardless
   of `branding.accent` — any `.tdtt-tn-*`/`.tdtt-tv-*` component in this
   file that sets its own `--tn-accent` fallback must stay guarded the same
   way; `packages/shared/src/__tests__/tournament-accent-specificity.test.ts`
   guards this. */
.tdtt-tv-board:not([data-accent]) {
  --tn-accent: var(--cyan);
}
/* Hex/grid texture + faint diagonal seams, same procedural-not-photographic
   language as chrome.css's `.tdtt-banner::before`. */
.tdtt-tv-board::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    linear-gradient(30deg, color-mix(in srgb, var(--tn-accent, var(--cyan)) 6%, transparent) 12%, transparent 12.5%, transparent 87%, color-mix(in srgb, var(--tn-accent, var(--cyan)) 6%, transparent) 87.5%),
    linear-gradient(150deg, color-mix(in srgb, var(--tn-accent, var(--cyan)) 6%, transparent) 12%, transparent 12.5%, transparent 87%, color-mix(in srgb, var(--tn-accent, var(--cyan)) 6%, transparent) 87.5%);
  background-size: 46px 80px;
}
/* Corner glow brackets, the recurring motif in every projector mockup. */
.tdtt-tv-board::after {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--cyan) 22%, transparent), transparent 22%),
    linear-gradient(-135deg, color-mix(in srgb, var(--magenta) 22%, transparent), transparent 22%);
  background-position: top left, top right;
  background-repeat: no-repeat;
  background-size: 45% 45%, 45% 45%;
  opacity: 0.5;
}

.tdtt-tv-header { display: flex; align-items: center; gap: 16px; margin-bottom: 20px; }
.tdtt-tv-header__title { font-family: var(--display); font-weight: 800; font-size: clamp(16px, 1.8vw, 24px); letter-spacing: -0.01em; text-transform: uppercase; color: var(--text); line-height: 1; }
.tdtt-tv-header__by { display: block; margin-top: 2px; font-family: var(--body); font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.tdtt-tv-header__announce {
  flex: 1 1 auto; text-align: center; padding: 10px 18px;
  font-family: var(--head); font-size: 12px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--tn-accent, var(--cyan)); background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--tn-accent, var(--cyan)) 55%, transparent); border-radius: 10px;
}
.tdtt-tv-header__meta { text-align: right; font-family: var(--body); font-size: 13px; color: var(--text-dim); }
.tdtt-tv-header__meta strong { color: var(--text); }
.tdtt-tv-header__timer { font-family: var(--mono); font-size: 22px; font-weight: 700; color: var(--gold); }

/* A centered content frame reused by gate / disabled / sponsor / intermission
   title. Uses the same chamfer idea as .tdtt-tn-panel, sized bigger. */
.tdtt-tv-panel {
  position: relative; isolation: isolate;
  --tn-cut: 22px;
  padding: 36px 48px;
  background: var(--tn-accent, var(--cyan));
  clip-path: polygon(
    var(--tn-cut) 0, 100% 0,
    100% calc(100% - var(--tn-cut)), calc(100% - var(--tn-cut)) 100%,
    0 100%, 0 var(--tn-cut)
  );
  filter: drop-shadow(0 0 24px color-mix(in srgb, var(--tn-accent, var(--cyan)) 35%, transparent));
}
.tdtt-tv-panel::before {
  content: ''; position: absolute; inset: 2px; z-index: -1;
  background: var(--surface);
  clip-path: polygon(
    var(--tn-cut) 0, 100% 0,
    100% calc(100% - var(--tn-cut)), calc(100% - var(--tn-cut)) 100%,
    0 100%, 0 var(--tn-cut)
  );
}
.tdtt-tv-panel__title { font-family: var(--display); font-weight: 800; font-size: clamp(26px, 4vw, 45px); letter-spacing: -0.01em; text-transform: uppercase; color: var(--text); text-align: center; }
.tdtt-tv-panel__sub { margin-top: 8px; font-family: var(--body); font-size: 15px; color: var(--text-dim); text-align: center; }
.tdtt-tv-panel__icon { display: flex; justify-content: center; margin-bottom: 14px; color: var(--muted); }

/* Match card, shared by .tdtt-tv-pairings and .tdtt-tv-round. */
.tdtt-tv-table {
  position: relative; padding: 16px 18px;
  background: var(--surface); border: 1px solid color-mix(in srgb, var(--tn-accent, var(--cyan)) 45%, var(--border));
  border-radius: 12px;
  clip-path: polygon(14px 0, 100% 0, 100% 100%, 0 100%, 0 14px);
}
.tdtt-tv-table__label {
  position: absolute; left: 0; top: 0; padding: 4px 12px 4px 8px;
  font-family: var(--head); font-size: 11px; font-weight: 700; color: var(--bg);
  background: var(--magenta); clip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 0 100%);
}
.tdtt-tv-table__live {
  position: absolute; right: 14px; top: 12px; display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--head); font-size: 11px; font-weight: 700; text-transform: uppercase; color: var(--green);
}
.tdtt-tv-table__live::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--green); box-shadow: 0 0 8px var(--green); }
.tdtt-tv-table__body { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; }
.tdtt-tv-table__player { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.tdtt-tv-table__avatar {
  width: 56px; height: 56px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--head); font-weight: 900; font-size: 1.1rem; color: var(--bg);
  background: linear-gradient(135deg, var(--cyan), var(--magenta));
}
.tdtt-tv-table__name { font-family: var(--body); font-weight: 700; font-size: 13.5px; color: var(--text); }
.tdtt-tv-table__vs { flex: none; font-family: var(--head); font-weight: 700; font-style: italic; font-size: 13px; color: var(--magenta); }

/* Ranked standings, bigger type than the console's .tdtt-tn-group. */
.tdtt-tv-standings { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.tdtt-tv-standings__head, .tdtt-tv-standings__row { display: flex; align-items: center; gap: 14px; padding: 10px 16px; }
.tdtt-tv-standings__head { font-family: var(--head); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); background: var(--surface-2); }
.tdtt-tv-standings__row { border-top: 1px solid var(--border); font-size: 15px; color: var(--text); }
.tdtt-tv-standings__row .pl { flex: 0 0 28px; font-family: var(--head); font-weight: 900; color: var(--tn-accent, var(--cyan)); }
.tdtt-tv-standings__row .nm { flex: 1 1 auto; min-width: 0; }
.tdtt-tv-standings__row .rec { flex: 0 0 90px; font-family: var(--mono); color: var(--magenta); text-align: right; }
.tdtt-tv-standings__row .pts { flex: 0 0 60px; font-family: var(--head); font-weight: 900; color: var(--gold); text-align: right; }

/* Numbered prize list. */
.tdtt-tv-prizes { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; display: flex; flex-direction: column; gap: 4px; }
.tdtt-tv-prizes__row { display: flex; align-items: center; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 14px; color: var(--text); }
.tdtt-tv-prizes__row:last-child { border-bottom: none; }
.tdtt-tv-prizes__rank {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--head); font-weight: 900; font-size: 13px; color: var(--bg); background: var(--gold);
}
.tdtt-tv-prizes__row:nth-child(2) .tdtt-tv-prizes__rank { background: var(--chrome); }
.tdtt-tv-prizes__row:nth-child(3) .tdtt-tv-prizes__rank { background: var(--orange); }

/* Gate — 4-digit view-code entry. */
.tdtt-tv-gate { display: flex; align-items: center; justify-content: center; min-height: 70vh; }
.tdtt-tv-gate__code { display: flex; gap: 10px; justify-content: center; margin-top: 18px; }
.tdtt-tv-gate__digit {
  width: 52px; height: 64px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 28px; font-weight: 700; color: var(--text);
  background: var(--input); border: 1px solid var(--border);
}

/* Sign-in — QR + room code, "waiting for players". */
.tdtt-tv-signin { display: flex; align-items: center; justify-content: center; gap: 48px; min-height: 70vh; }
.tdtt-tv-signin__qr { width: 220px; height: 220px; border-radius: 12px; background: var(--text); padding: 12px; }
.tdtt-tv-signin__code {
  font-family: var(--mono); font-size: clamp(36px, 5vw, 56px); font-weight: 700; letter-spacing: 0.08em;
  color: var(--tn-accent, var(--cyan));
}

/* Pairings — "Round N Pairings" title over a grid of .tdtt-tv-table cards,
   plus format + prizes panels below. */
.tdtt-tv-pairings__title { text-align: center; margin-bottom: 20px; }
.tdtt-tv-pairings__title .k { display: block; font-family: var(--head); font-weight: 700; font-size: 12px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--text-dim); }
.tdtt-tv-pairings__title .v { font-family: var(--display); font-weight: 800; font-size: clamp(26px, 4vw, 42px); letter-spacing: -0.01em; color: var(--green); text-transform: uppercase; text-shadow: 0 0 24px color-mix(in srgb, var(--green) 55%, transparent); }
.tdtt-tv-pairings__grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); margin-bottom: 20px; }
.tdtt-tv-pairings__foot { display: grid; gap: 16px; grid-template-columns: 1fr 1fr; }

/* Round in progress — bigger match cards with HP bars, standings alongside. */
.tdtt-tv-round { display: grid; gap: 20px; grid-template-columns: 1fr 320px; }
.tdtt-tv-round__matches { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); align-content: start; }
.tdtt-tv-round__hp { margin-top: 6px; width: 100%; height: 6px; border-radius: 999px; background: var(--input); overflow: hidden; }
.tdtt-tv-round__hp-fill { display: block; height: 100%; background: var(--green); border-radius: 999px; }
.tdtt-tv-round__hp-fill.low { background: var(--red); }
.tdtt-tv-round__crown { color: var(--gold); }

/* Intermission — big title + standings/prizes panels, same layout as pairings foot. */
.tdtt-tv-intermission__title { text-align: center; margin: 20px 0; }
.tdtt-tv-intermission__title .v {
  font-family: var(--display); font-weight: 800; font-size: clamp(32px, 5.6vw, 58px); letter-spacing: -0.01em; color: var(--magenta); text-transform: uppercase;
  text-shadow: 0 0 30px color-mix(in srgb, var(--magenta) 60%, transparent);
}
.tdtt-tv-intermission__title .sub { display: block; margin-top: 6px; font-family: var(--body); font-size: 15px; color: var(--text-dim); }
.tdtt-tv-intermission__foot { display: grid; gap: 16px; grid-template-columns: 1fr 1fr; }

/* Podium — Final Results: three place cards (middle = 1st, emphasized) plus
   the ranks-4-and-below standings table underneath. */
.tdtt-tv-podium__title { text-align: center; margin-bottom: 20px; }
.tdtt-tv-podium__title .v {
  font-family: var(--display); font-weight: 800; font-size: clamp(29px, 4.8vw, 51px); letter-spacing: -0.01em; color: var(--gold); text-transform: uppercase;
  text-shadow: 0 0 30px color-mix(in srgb, var(--gold) 60%, transparent);
}
.tdtt-tv-podium__places { display: grid; gap: 16px; grid-template-columns: 1fr 1.15fr 1fr; align-items: end; margin-bottom: 20px; }
.tdtt-tv-podium__place {
  --place-c: var(--gold);
  padding: 18px; text-align: center; border-radius: 12px;
  background: var(--surface); border: 2px solid var(--place-c);
  box-shadow: 0 0 22px color-mix(in srgb, var(--place-c) 40%, transparent);
}
.tdtt-tv-podium__place[data-rank='2'] { --place-c: var(--chrome); }
.tdtt-tv-podium__place[data-rank='3'] { --place-c: var(--orange); }
.tdtt-tv-podium__place--first { padding: 26px 18px; }
.tdtt-tv-podium__place .avatar {
  width: 72px; height: 72px; margin: 0 auto 10px; border-radius: 14px; overflow: hidden;
  background: var(--surface-2); border: 2px solid var(--place-c);
}
.tdtt-tv-podium__place .avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tdtt-tv-podium__place--first .avatar { width: 96px; height: 96px; }
.tdtt-tv-podium__place .name { font-family: var(--head); font-weight: 700; font-size: 17px; color: var(--text); }
.tdtt-tv-podium__place .record { font-family: var(--mono); font-size: 12px; color: var(--place-c); margin-top: 2px; }

/* Disabled — "the organizer has not enabled the view screen" empty state.
   The one board with no accent: neutral, muted, deliberately quiet. */
.tdtt-tv-disabled { --tn-accent: var(--muted); }
.tdtt-tv-disabled .tdtt-tv-panel__title { color: var(--text-dim); font-family: var(--body); font-size: 17px; text-transform: none; }
.tdtt-tv-disabled .tdtt-tv-panel__icon { color: var(--muted); }

/* Sponsor / break slide. */
.tdtt-tv-sponsor { display: flex; align-items: center; justify-content: center; min-height: 70vh; }
.tdtt-tv-sponsor__logo { max-width: 60%; max-height: 40vh; object-fit: contain; }
.tdtt-tv-sponsor__caption { margin-top: 16px; text-align: center; font-family: var(--head); font-weight: 700; font-size: 14px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-dim); }

@media (max-width: 900px) {
  .tdtt-tv-round { grid-template-columns: 1fr; }
  .tdtt-tv-pairings__foot, .tdtt-tv-intermission__foot { grid-template-columns: 1fr; }
  .tdtt-tv-podium__places { grid-template-columns: 1fr; }
}
