/* ===== Theme palette (Wave: light/dark toggle) =====
   Neutrály jako proměnné: dark = default (beze změny), light = override.
   Akcenty zůstávají literály (fungují na obou motivech). ===== */
:root{
  --c-facc15: #facc15;
  --c-fde047: #fde047;
  --c-0a0a0a: #0a0a0a;
  --c-0c1a2e: #0c1a2e;
  --c-0f172a: #0f172a;
  --c-1e293b: #1e293b;
  --c-243245: #243245;
  --c-273449: #273449;
  --c-334155: #334155;
  --c-475569: #475569;
  --c-94a3b8: #94a3b8;
  --c-cbd5e1: #cbd5e1;
  --c-e2e8f0: #e2e8f0;
  --c-f1f5f9: #f1f5f9;
}
:root[data-theme="light"]{
  --c-facc15: #ea580c;
  --c-fde047: #c2410c;
  --c-0a0a0a: #ffffff;
  --c-0c1a2e: #e8eef5;
  --c-0f172a: #f1f5f9;
  --c-1e293b: #ffffff;
  --c-243245: #e6eaf0;
  --c-273449: #e2e8f0;
  --c-334155: #cbd5e1;
  --c-475569: #94a3b8;
  --c-94a3b8: #64748b;
  --c-cbd5e1: #334155;
  --c-e2e8f0: #1e293b;
  --c-f1f5f9: #0f172a;
}
/* ── Design tokens (Wave 2.13.0 landing-sections) ── */
:root {
  --card-bg: var(--c-1e293b);
  --card-border: var(--c-334155);
  --accent: #38bdf8;
  --muted: var(--c-94a3b8);
  --live: #22c55e;
  --live-soft: rgba(34, 197, 94, 0.15);
}

/* ── Reset ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 16px; -webkit-text-size-adjust: 100%; }

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--c-0f172a);
  color: var(--c-e2e8f0);
  line-height: 1.5;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

a { color: #60a5fa; text-decoration: none; }
a:hover { text-decoration: underline; }

/* ── Layout ── */
.site-header {
  background: var(--c-1e293b);
  padding: 0 0.75rem;
  min-height: 55px;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  border-bottom: 1px solid var(--c-334155);
}
.site-header-event {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.6rem;
  min-width: 0;
}
.site-header-event-name {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--c-f1f5f9);
  line-height: 1.1;
}
.site-header-event-meta {
  font-size: 0.78rem;
  color: var(--c-94a3b8);
}

.site-main {
  flex: 1;
  padding: 1rem;
  max-width: 900px;
  width: 100%;
  margin: 0 auto;
}

.breadcrumb {
  font-size: 0.85rem;
  color: var(--c-94a3b8);
  margin-bottom: 1rem;
}
.breadcrumb a { color: var(--c-94a3b8); }
.breadcrumb span { color: var(--c-e2e8f0); }

h1 { font-size: 1.5rem; font-weight: 700; margin-bottom: 1rem; color: var(--c-f1f5f9); }
h2 { font-size: 1.15rem; font-weight: 600; margin: 1.5rem 0 0.75rem; color: var(--c-f1f5f9); }
h3 { font-size: 1rem; font-weight: 600; margin: 1rem 0 0.5rem; color: var(--c-cbd5e1); }

h1 small { font-size: 0.8em; color: var(--c-94a3b8); font-weight: 400; }

/* ── Event detail ── */
.event-meta { display: grid; grid-template-columns: max-content 1fr; gap: 0.25rem 0.75rem; font-size: 0.9rem; margin-bottom: 1.5rem; }
.event-meta dt { color: var(--c-94a3b8); }
.event-meta dd { color: var(--c-e2e8f0); }

.category-list { list-style: none; display: flex; flex-direction: column; gap: 0.5rem; }
.category-card { background: var(--c-1e293b); border: 1px solid var(--c-334155); border-radius: 8px; }
.category-card a { display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem; color: inherit; text-decoration: none; }
.category-card a:hover { background: var(--c-273449); text-decoration: none; }
.category-card-code { font-weight: 700; color: #60a5fa; min-width: 3.5rem; font-family: monospace; }
.category-card-name { flex: 1; color: var(--c-f1f5f9); }
.category-card-meta { display: flex; gap: 0.5rem; align-items: center; }

/* ── Badges ── */
.status-badge, .phase-badge, .race-status, .junior-badge {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.status-upcoming { background: #1e3a8a; color: #bfdbfe; }
.status-live     { background: #14532d; color: #86efac; }
.status-finished { background: var(--c-334155); color: var(--c-94a3b8); }

.phase-tt            { background: #3730a3; color: #c7d2fe; }
.phase-heats         { background: #1e40af; color: #bfdbfe; }
.phase-quarterfinals { background: #7c2d12; color: #fed7aa; }
.phase-semifinals    { background: #9a3412; color: #fed7aa; }
.phase-finals        { background: #166534; color: #86efac; }
.phase-done          { background: var(--c-334155); color: var(--c-94a3b8); }

.junior-badge { background: #6b21a8; color: #e9d5ff; }

/* Live karta: status u done (✓) a pending (čas) je čistý text — bez podbarvení
   a bez rámečku. Active si žlutozelený badge ponechává (zvýraznění běžící jízdy). */
.race-status-pending { color: var(--c-cbd5e1); }
.race-status-active  { background: #15803d; color: #bbf7d0; }
.race-status-done    { color: var(--c-94a3b8); }

.race-time { font-size: 0.8rem; color: var(--c-94a3b8); font-weight: 400; margin-left: 0.5rem; }

/* ── Category dump ── */
.category-header { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; margin-bottom: 1rem; font-size: 0.9rem; color: var(--c-94a3b8); }

.dump-section { margin-bottom: 2rem; }
.dump-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}
.dump-table th, .dump-table td {
  text-align: left;
  padding: 0.4rem 0.5rem;
  border-bottom: 1px solid var(--c-1e293b);
}
.dump-table th {
  background: var(--c-1e293b);
  color: var(--c-94a3b8);
  font-weight: 600;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.race-block { margin-bottom: 1.25rem; }

.race-athlete-empty td { color: var(--c-475569); font-style: italic; }

/* ── Bib colors ── */
.bib-color {
  display: inline-block;
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--c-0f172a);
}
.bib-red    { background: #ef4444; color: #fff; }
.bib-green  { background: #22c55e; color: var(--c-0f172a); }
.bib-blue   { background: #3b82f6; color: #fff; }
.bib-yellow { background: #eab308; color: var(--c-0f172a); }

/* ── Empty state ── */
.empty-state { color: #64748b; font-style: italic; text-align: center; padding: 2rem 1rem; }

/* ── Technical meta (collapsed details) ── */
.technical-meta {
  margin-top: 2rem;
  border-top: 1px solid var(--c-1e293b);
  padding-top: 1rem;
  font-size: 0.8rem;
  color: #64748b;
}
.technical-meta summary { cursor: pointer; color: var(--c-94a3b8); }
.technical-meta dl { display: grid; grid-template-columns: max-content 1fr; gap: 0.25rem 0.75rem; margin-top: 0.5rem; }
.technical-meta dt { color: #64748b; }

/* ── 404 ── */
.error-page { text-align: center; padding: 3rem 1rem; }
.error-page h1 { font-size: 4rem; color: var(--c-334155); margin-bottom: 0.5rem; }

/* ── TT Live View ── */
.live-indicator {
  color: #ef4444;
  font-weight: bold;
  margin-right: 1rem;
}
.tt-refresh-info {
  color: var(--c-94a3b8);
  font-size: 0.9em;
}
.tt-live-header {
  margin-bottom: 1rem;
}
.tt-live-link {
  margin: 0.5rem 0 1rem 0;
}
.tt-live-link a {
  font-weight: bold;
}
.race-athlete-dnf {
  opacity: 0.65;
}

/* Wave 2.4.11: latest finisher highlight — green persistence (15s server-driven)
   plus a one-shot 2s pulse triggered by JS on 0→1 transition.
   box-shadow inset gives a 4px left accent bar without affecting layout. */
.dump-table tbody tr[data-latest-finisher="1"] {
  background-color: rgba(34, 197, 94, 0.22);
  box-shadow: inset 4px 0 0 #22c55e;
  transition: background-color 0.5s ease-out;
}
.dump-table tbody tr[data-latest-finisher="1"] td {
  color: var(--c-f1f5f9);
  font-weight: 600;
}
@keyframes latest-finisher-pulse {
  0%   { background-color: rgba(34, 197, 94, 0.70); }
  50%  { background-color: rgba(34, 197, 94, 0.45); }
  100% { background-color: rgba(34, 197, 94, 0.22); }
}
.dump-table tbody tr.latest-finisher-pulse {
  animation: latest-finisher-pulse 2s ease-out;
}
/* Defensive: latest finisher cannot have a finish_time AND be disqualified
   (server only flags rows with finish_time), but if data shape ever changes
   keep the DNF coloring visually dominant. */
.dump-table tbody tr.race-athlete-dnf[data-latest-finisher="1"] {
  background-color: rgba(239, 68, 68, 0.15);
  box-shadow: inset 4px 0 0 #ef4444;
}
.scroll-x {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.on-track-running {
  font-variant-numeric: tabular-nums;
  color: #60a5fa;
  font-weight: 600;
}
.on-track-running.finished-pending {
  color: #22c55e;
}

/* Vlna 2.4.9: hlavička brán v "Na trati" — barevné odlišení dle typu */
.gate-th {
  text-align: center;
  font-weight: 700;
  font-size: 0.78rem;
  padding: 0.35rem 0.2rem;
  min-width: 1.8rem;
}
/* Bumpne specificitu (0,2,1) přes .dump-table th/td (0,1,1), aby text-align:
   center skutečně vyhrál → digit v hlavičce a badge v body cellu jsou
   centrované ve sloupci (vizuální center-to-center alignment). */
.dump-table thead th.gate-th { text-align: center; }
.dump-table td.gate-cell     { text-align: center; }
/* Vlna 2.4.9.2: decentní styl podle hlavního KXRS — pozadí dědí z .dump-table
   thead th (var(--c-1e293b)), žádný spodní border, jen barevný text. Specificita
   .dump-table thead th.gate-th-* (0,3,1) přebíjí .dump-table th (0,1,1) color. */
.dump-table thead th.gate-th-downstream { color: #4ade80; }   /* zelená — povodná */
.dump-table thead th.gate-th-upstream   { color: #f87171; }   /* červená — protivoda */
.dump-table thead th.gate-th-eskimo     { color: var(--c-fde047); }   /* žlutá — eskymák */

/* Vlna 2.4.9: penalty buňky jako badge, ne plnobarevné pozadí */
.gate-cell {
  text-align: center;
  background: transparent;
  padding: 0.2rem 0.15rem;
}
.gate-cell .penalty-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.4rem;
  height: 1.05rem;
  padding: 0 0.3rem;
  border-radius: 4px;
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.02em;
}
/* CLEAN en-dash: bez letter-spacing, ať pomlčka nevypadá zbytečně tažená */
.cell-clean .penalty-badge { letter-spacing: 0; }
.cell-flt .penalty-badge {
  background: #7f1d1d;
  color: #fecaca;
  border: 1px solid #ef4444;
}
.cell-clean .penalty-badge {
  background: #14532d;
  color: #86efac;
  border: 1px solid #22c55e;
}
.cell-pending .penalty-badge {
  background: transparent;
  color: var(--c-475569);
  border: none;
}
.flt-badge {
  background: rgba(239, 68, 68, 0.2);
  color: #ef4444;
  font-weight: bold;
  padding: 0.1em 0.4em;
  border-radius: 3px;
  font-size: 0.85em;
}
.empty-note {
  color: var(--c-94a3b8);
  font-style: italic;
}


/* ─── Wave 2.4.12: Denser "Pořadí" table ─── */
/* Tighter padding + slightly smaller font for the ranking table.
   Scoped to #tt-section-ranking so the scoreboard "Na trati" keeps its
   own sizing. Specificity (1,1,1) wins over .dump-table th/td (0,1,1). */
#tt-section-ranking .dump-table th,
#tt-section-ranking .dump-table td {
  padding: 0.25rem 0.45rem;
  font-size: 0.78rem;
  line-height: 1.25;
}
#tt-section-ranking .dump-table th {
  font-size: 0.68rem;
}

/* Wave 2.7.16: scoreboard look v2 — refactor of Wave 2.4.12.
   Unified yellow palette (FLT no longer red), modern monospace
   stack, dashed dividers, ID-scoped to prevent global bleed.
   Stadium LED feel for projector / event-center display.
   Gate header color rules (.gate-th-downstream/upstream/eskimo)
   are intentionally NOT overridden — those colors are part of
   the gate-type semantics, not the scoreboard chrome. */

#tt-section-on-course {
  background: var(--c-0a0a0a);
  border: 2px solid var(--c-facc15);
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: 1.25rem;
}

#tt-section-on-course .dump-table,
#tt-section-on-course .dump-table th,
#tt-section-on-course .dump-table td {
  background: transparent;
  color: var(--c-facc15);
  font-family: ui-monospace, "SF Mono", Monaco, "Cascadia Code",
               "Roboto Mono", Consolas, "Liberation Mono",
               "Courier New", monospace;
  font-weight: 700;
}

#tt-section-on-course .dump-table thead {
  background: transparent;
  border-bottom: 1px solid var(--c-facc15);
}

#tt-section-on-course .dump-table thead th {
  color: var(--c-fde047);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-size: 0.85rem;
  padding: 0.4rem 0.75rem;
}

#tt-section-on-course .dump-table tbody tr {
  background: transparent;
}

#tt-section-on-course .dump-table tbody tr:hover {
  background: rgba(250, 204, 21, 0.08);
}

#tt-section-on-course .dump-table td {
  padding: 0.55rem 0.75rem;
  border: none;
  border-bottom: 1px dashed rgba(250, 204, 21, 0.2);
}

#tt-section-on-course .dump-table tbody tr:last-child td {
  border-bottom: none;
}

/* Running clock — focal point: larger, bolder, glow, tabular-nums. */
#tt-section-on-course .on-track-running {
  font-size: 1.15rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.05em;
  text-shadow: 0 0 6px rgba(250, 204, 21, 0.4);
  white-space: nowrap;
}

/* Athlete finished but waiting for sync — dimmed, no glow. */
#tt-section-on-course .on-track-running.finished-pending {
  color: #ca8a04;
  text-shadow: none;
}

#tt-section-on-course .gate-cell {
  text-align: center;
  font-variant-numeric: tabular-nums;
}

#tt-section-on-course .gate-cell.cell-pending {
  color: #78716c;
}

#tt-section-on-course .gate-cell.cell-pending .penalty-badge {
  color: #78716c;
  background: transparent;
  border: none;
}

/* CLEAN cell — override the global green palette (background #14532d /
   color #86efac / border #22c55e) to fit the unified yellow scoreboard. */
#tt-section-on-course .gate-cell.cell-clean {
  color: var(--c-facc15);
  background: transparent;
}

#tt-section-on-course .gate-cell.cell-clean .penalty-badge {
  color: var(--c-facc15);
  background: transparent;
  border: 1px solid rgba(250, 204, 21, 0.4);
  font-weight: 600;
}

/* FLT cell — override the global red palette (background #7f1d1d /
   color #fecaca / border #ef4444). Yellow text + yellow border keeps
   FLT visually distinct without breaking the unified palette. */
#tt-section-on-course .gate-cell.cell-flt {
  background: transparent;
  color: var(--c-facc15);
}

#tt-section-on-course .gate-cell.cell-flt .penalty-badge {
  color: var(--c-facc15);
  background: transparent;
  border: 1px solid var(--c-facc15);
  font-weight: 800;
  padding: 0.05rem 0.3rem;
  border-radius: 3px;
}

#tt-section-on-course .gate-th {
  color: var(--c-fde047);
}

#tt-section-on-course .scroll-x {
  background: transparent;
}

/* ─── Wave 2.6.0: Bracket live (mobile-first) ─── */

/* Sticky chip navigation. Base header is not sticky/fixed, so top: 0
   pins to the viewport once the header scrolls out. */
.bracket-nav-sticky {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--c-0f172a);
  border-bottom: 1px solid var(--c-1e293b);
  padding: 0.5rem 0;
  margin: -0.5rem -0.25rem 1rem;
}

.phase-tabs {
  display: flex;
  gap: 0.4rem;
  margin-bottom: 0.4rem;
  padding: 0 0.25rem;
}
.phase-tab {
  padding: 0.4rem 0.8rem;
  background: var(--c-1e293b);
  color: var(--c-cbd5e1);
  border: 1px solid var(--c-334155);
  border-radius: 6px;
  font-weight: 700;
  font-size: 0.85rem;
  cursor: pointer;
}
.phase-tab:hover { background: var(--c-273449); }

.race-chips {
  display: flex;
  gap: 0.3rem;
  overflow-x: auto;
  scrollbar-width: thin;
  padding: 0 0.25rem 0.2rem;
  -webkit-overflow-scrolling: touch;
}
.race-chip {
  flex: 0 0 auto;
  padding: 0.3rem 0.6rem;
  background: var(--c-1e293b);
  color: var(--c-cbd5e1);
  border: 1px solid var(--c-334155);
  border-radius: 6px;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
}
.race-chip:hover { background: var(--c-273449); }
.race-chip-done {
  background: var(--c-0f172a);
  color: #64748b;
  border-color: var(--c-1e293b);
}
.race-chip-done::before { content: '✓ '; color: #22c55e; }
.race-chip-active {
  background: #064e3b;
  color: #6ee7b7;
  border-color: #10b981;
  animation: bracket-chip-pulse 1.5s ease-in-out infinite;
}
@keyframes bracket-chip-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.45); }
  50%      { box-shadow: 0 0 0 4px rgba(16, 185, 129, 0); }
}

/* Race blocks — extends existing .race-block (which only sets margin) with
   a card look + active-status border. */
.bracket-race-block {
  background: var(--c-1e293b);
  border: 1px solid var(--c-334155);
  border-radius: 8px;
  padding: 0.6rem 0.75rem;
  margin-bottom: 0.8rem;
  scroll-margin-top: 6.5rem;   /* sticky-nav height clearance for chip-jump */
}
.bracket-race-block.race-status-active {
  border-color: #10b981;
  box-shadow: 0 0 0 1px rgba(16, 185, 129, 0.35);
}
.bracket-race-block.race-status-done {
  border-color: #1e3a2e;
  opacity: 0.85;
}

.bracket-race-block .race-block-header {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  font-size: 0.95rem;
}
.bracket-race-block .race-name {
  font-weight: 700;
  color: var(--c-e2e8f0);
}
.bracket-race-block .race-time {
  font-family: monospace;
  margin-left: 0;
}
.bracket-race-block .race-status-icon {
  margin-left: auto;
  font-size: 1rem;
}
.bracket-race-block.race-status-done .race-status-icon { color: #22c55e; }
.bracket-race-block.race-status-active .race-status-icon { color: #6ee7b7; }
.bracket-race-block.race-status-pending .race-status-icon { color: #64748b; }

/* Wave 2.6.6: compact bracket race table — no thead, fixed-layout columns
   so the BIB swatch sits next to its name regardless of how many cols
   the row has (4 for pending/active, 5 for done). */
.race-results-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
  table-layout: fixed;
}
.race-results-table td {
  padding: 0.18rem 0.35rem;
  border-top: 1px solid var(--c-1e293b);
  color: var(--c-e2e8f0);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.race-results-table .race-pos {
  width: 2rem;
  font-weight: 700;
  color: #38bdf8;
}
.race-results-table .race-stc {
  width: 2.2rem;
  color: var(--c-94a3b8);
}
.race-results-table .race-bib {
  width: 1.6rem;
  text-align: center;
  padding-left: 0.2rem;
  padding-right: 0.2rem;
}
/* Bib swatch — colored square only, no text. Reuses existing .bib-{color}
   classes from the .bib-color block (the per-color background rules apply
   to any element bearing the class). */
.bib-square {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 3px;
  vertical-align: middle;
}
.race-results-table .race-name-cell { color: var(--c-e2e8f0); }
.race-results-table .race-flt {
  width: 3.4rem;
  text-align: right;
  font-family: monospace;
  color: #fca5a5;
}
.race-athlete-row.race-athlete-dnf .race-status-text {
  color: #fca5a5;
  font-size: 0.7rem;
  font-weight: 700;
}

.phase-heading {
  font-size: 0.95rem;
  color: var(--c-94a3b8);
  margin: 1rem 0 0.5rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.race-phase-section {
  scroll-margin-top: 6.5rem;
}

/* Wave 2.6.1: primary Live link in category.html — bolder green to signal
   it's the recommended single-URL entry point. */
.live-primary {
  font-weight: 700;
  color: #6ee7b7 !important;
}
.live-primary:hover { color: #a7f3d0 !important; }
.live-link-sep { color: var(--c-475569); }

/* ─── Wave 2.6.2b: live current_heat block ─── */
.live-current-heat {
  background: var(--c-1e293b);
  border: 1px solid var(--c-334155);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin: 0 0 1rem 0;
}
.live-current-heat[data-status="active"] {
  border-color: #ef4444;
  box-shadow: 0 0 0 1px rgba(239, 68, 68, 0.2);
}
.live-current-heat[data-status="done"] {
  border-color: #10b981;
  opacity: 0.85;
}
/* Wave 2.6.14: live-current-heat header redesign — pulsing status dot
   in the top-right corner replaces the textual AKTIVNÍ/DOKONČENO badge. */
.live-current-heat .live-header {
  position: relative;       /* anchor for the absolutely positioned dot */
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
  padding-right: 1.25rem;   /* leave room for the corner dot */
}
.live-current-heat .live-heat-label {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--c-e2e8f0);
}
.live-current-heat .live-status-dot {
  position: absolute;
  top: 0;
  right: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--c-94a3b8);       /* fallback grey */
}
.live-current-heat .live-status-dot-active {
  background: #ef4444;       /* red */
  animation: live-status-pulse 1.5s ease-in-out infinite;
}
.live-current-heat .live-status-dot-done {
  background: #10b981;       /* green, no animation */
}
@keyframes live-status-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.8); }
}

/* Wave 2.6.14.2: gate progress bar lives inline inside .live-header
   (between label and the absolute status dot). Cells are bare 10×6
   rectangles — grey border when pending, green fill when visited. */
.live-gates {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 3px;
  margin: 0;
}
/* Wave 2.6.14: visited progress instead of penalty-status colors.
   Gate cells turn green once the operator's focus has moved at or
   past that gate. Pending = neutral grey frame. Old gate-all_clean /
   gate-all_flt / gate-partial classes deprecated — kept in CSS as
   fallback so legacy snapshots don't render unstyled. */
.live-gates .gate-cell {
  display: inline-block;
  width: 10px;
  height: 6px;
  border-radius: 2px;
  background: transparent;
  border: 1px solid var(--c-475569);
  transition: background 0.25s ease, border-color 0.25s ease;
}
.live-gates .gate-cell.gate-pending {
  background: transparent;
  border-color: var(--c-475569);
}
.live-gates .gate-cell.gate-visited {
  background: #10b981;
  border-color: #10b981;
}
/* Legacy fallback — keep light styling so old snapshots without
   `visited` field render readable. */
.live-gates .gate-cell.gate-all_clean,
.live-gates .gate-cell.gate-all_flt,
.live-gates .gate-cell.gate-partial {
  background: #10b981;
  border-color: #10b981;
}

.live-current-heat .live-athletes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.live-current-heat .live-athlete {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0;
  font-size: 0.85rem;
  color: var(--c-e2e8f0);
}
.live-current-heat .athlete-final-pos {
  display: inline-block;
  min-width: 1.4rem;
  font-family: ui-monospace, "Courier New", monospace;
  font-size: 0.85rem;
  font-weight: 700;
  color: #fbbf24;
  text-align: right;
}
.live-current-heat .lane-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.live-current-heat .lane-red    .lane-dot { background: #ef4444; }
.live-current-heat .lane-green  .lane-dot { background: #22c55e; }
.live-current-heat .lane-blue   .lane-dot { background: #3b82f6; }
.live-current-heat .lane-yellow .lane-dot { background: #eab308; }
.live-current-heat .athlete-stc {
  font-family: ui-monospace, "Courier New", monospace;
  font-size: 0.8rem;
  color: #64748b;
  min-width: 2rem;
}
.live-current-heat .athlete-name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.live-current-heat .athlete-status {
  font-family: ui-monospace, "Courier New", monospace;
  font-size: 0.75rem;
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
  transition: background-color 0.3s ease;
}
.live-current-heat .status-ok {
  background: rgba(16, 185, 129, 0.15);
  color: #10b981;
}
/* Match any FLT-N (FLT-1, FLT-2, FLT-start, ...) — class is status-flt_N.
   Bílý text v červeném rámečku — parita s Pavouk (.athlete-flt) a TT (.tt-rank-flt). */
.live-current-heat .athlete-status[class*="status-flt"] {
  background: #b91c1c;
  color: #fff;
  font-weight: 700;
}
.live-current-heat .status-dns,
.live-current-heat .status-dnf,
.live-current-heat .status-ral,
.live-current-heat .status-dsq,
.live-current-heat .status-dqb {
  background: rgba(100, 116, 139, 0.2);
  color: var(--c-94a3b8);
}

/* Brief flash on per-cell update (driven by JS toggling .flash class). */
.live-gates .gate-cell.flash,
.live-current-heat .athlete-status.flash {
  animation: live-current-flash 0.6s ease-out;
}
@keyframes live-current-flash {
  0%   { background-color: rgba(56, 189, 248, 0.4); }
  100% { background-color: transparent; }
}

/* ─────────────────────────────────────────────────────────────────────
   Wave 2.7.5: a11y utilities
   ───────────────────────────────────────────────────────────────────── */

/* Screen-reader-only — visually hidden but in the accessibility tree. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Focus-visible: outline only on keyboard nav, suppressed on click/touch. */
*:focus-visible {
  outline: 2px solid #38bdf8;
  outline-offset: 2px;
  border-radius: 3px;
}
*:focus:not(:focus-visible) {
  outline: none;
}

/* ─────────────────────────────────────────────────────────────────────
   Vlna 1 fáze A: sjednocené TT live styly (sdílené desktop + mobile).
   DOM model = ol/li (převzato z mobilu). Layout řídí breakpoint v
   desktop.css / mobile.css. Per-branka detail (.gate-*/.cell-*) zůstává
   v base.css výše a aktivuje se ve fázi B (responzivní akordeon).
   ───────────────────────────────────────────────────────────────────── */

/* Sub-header s titulkem kategorie + cat-switcher dropdownem. */
.tt-subheader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.6rem 0.75rem 0.4rem;
  background: var(--c-0f172a);
  border-bottom: 1px solid var(--c-1e293b);
}
.tt-cat-title {
  margin: 0;
  font-size: 1rem;
  color: var(--c-f1f5f9);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tt-cat-switcher { position: relative; flex-shrink: 0; }

.cat-switch-btn {
  background: var(--c-1e293b);
  color: var(--c-f1f5f9);
  border: 1px solid var(--c-334155);
  padding: 0.35rem 0.7rem;
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.cat-switch-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  background: var(--c-1e293b);
  border: 1px solid var(--c-334155);
  border-radius: 8px;
  list-style: none;
  margin: 0;
  padding: 0.25rem 0;
  min-width: 200px;
  max-width: calc(100vw - 1.5rem);
  z-index: 50;
  box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.cat-switch-menu li { margin: 0; padding: 0; }
.cat-switch-item {
  display: block;
  padding: 0.7rem 1rem;
  color: var(--c-f1f5f9);
  text-decoration: none;
  font-size: 0.9rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: 44px;
  line-height: 1.6;
}
.cat-switch-item.active { color: #38bdf8; font-weight: 600; }
.cat-switch-item:active { background: var(--c-334155); }

/* TT live tělo — sdílený základ. */
.tt-live { padding: 0; }

/* Vlna 2.7.29 → 3-stavový přepínač „Živý čas v pořadí" vpravo v řádku
   kategorií (.tt-cat-tabs-strip.has-live-toggle). Klik cykluje režimy;
   stav řídí JS přes data-mode na <button>. Ikona má 3 podoby, všechny žluté
   (jen obrys): off = scoreboard (tabulka), light = dělící čára, full = hodiny.
   Klikací plocha ≥ 44px. */
.tt-live-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  margin-left: 0.5rem;
  min-width: 44px;
  min-height: 38px;
  padding: 0 0.4rem;
  color: var(--c-facc15);
  cursor: pointer;
  user-select: none;
  border: 0;
  /* pozadí pásu, aby pod ikonou „mizely" odscrollované kategorie */
  background: var(--c-0f172a);
}
.tt-live-toggle:hover { color: var(--c-fde047); }
.tt-live-toggle-icon {
  width: 22px;
  height: 22px;
  display: block;
  transition: color 0.15s;
}
/* Ikona má 3 podoby dle data-mode (vždy je vidět jen jedna):
     off   = scoreboard (.ic-board) — šedý
     light = žlutá dělící čára (.ic-divider)
     full  = hodiny (.ic-clock + .ic-clock-hands) — žluté
   Výchozí: hodiny i čára skryté, board zobrazen (off). */
.tt-live-toggle .ic-clock,
.tt-live-toggle .ic-clock-hands { display: none; }
.tt-live-toggle .ic-divider { opacity: 0; transition: opacity 0.15s; }
/* light — jen žlutá čára */
.tt-live-toggle[data-mode="light"] .ic-board { display: none; }
.tt-live-toggle[data-mode="light"] .ic-divider {
  opacity: 1;
  stroke: var(--c-facc15);
  stroke-width: 2.5;
}
/* full — jen žluté hodiny */
.tt-live-toggle[data-mode="full"] .ic-board { display: none; }
.tt-live-toggle[data-mode="full"] .ic-clock,
.tt-live-toggle[data-mode="full"] .ic-clock-hands { display: inline; }
.tt-live-toggle[data-mode="full"] { color: var(--c-facc15); }
.tt-live-toggle[data-mode="full"]:hover { color: var(--c-fde047); }
.tt-live-toggle:focus-visible {
  outline: 2px solid #38bdf8;
  outline-offset: 2px;
  border-radius: 4px;
}

/* LIVE (kros TT i časové disciplíny): tentýž přepínač sedí v nástrojích
   hlavičky (.header-tools) před ikonou řádkování — pás pod hlavičkou se
   štítkem kategorie zmizel a obsah začíná rovnou pod dělící linkou záhlaví.
   Geometrii proto srovnáváme s ostatními ikonami hlavičky (28×38, bez
   vlastního pozadí a levého okraje); barvu (žlutá) i 3-stavovou ikonu
   necháváme — je to stavový přepínač, ne jen nástroj. */
.header-tools .tt-live-toggle {
  width: 28px;
  min-width: 28px;
  height: 38px;
  padding: 0;
  margin-left: 0;
  background: transparent;
}
.header-tools .tt-live-toggle-icon { width: 19px; height: 19px; }

/* Light varianta: zvýrazněná dělící čára v Pořadí (mezi řádky), na pozici
   dle živého času. Žlutá scoreboard paleta. Marker sdílí grid .tt-row-ranking
   (stejné sloupce), takže STČ a jméno korespondují se sloupci v Pořadí.
   Dělící čára = žlutá svítící horní hrana (přes celou šířku). Chip vlevo.
   Marker je <li> bez data-stc → neúčastní se serverové rekonciliace. */
.tt-rank-marker {
  position: relative;
  display: block;
  margin: 0;
  /* svislý prostor, aby pilulka seděla a čára prošla středem */
  padding: 0.45rem 0.75rem;
  list-style: none;
}
/* dělící čára — přes celou šířku, ve svislém středu markeru */
.tt-rank-marker::before {
  content: "";
  position: absolute;
  left: 0.75rem;
  right: 0.75rem;
  top: 50%;
  height: 2px;
  transform: translateY(-50%);
  background: var(--c-facc15);
  box-shadow: 0 0 6px rgba(250, 204, 21, 0.55);
}
/* pilulka „STČ + jméno" sedí NA čáře (z-index nad ní), zleva zarovnaná
   na sloupec STČ (≈ šířka sloupce pořadí + gap). Tmavý lem ji odděluje
   od čáry. */
.tt-rank-marker-chip {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-left: 2.35rem;        /* rank col 2rem + gap 0.35rem */
  padding: 0.06rem 0.5rem;
  background: var(--c-facc15);
  color: var(--c-0a0a0a);
  border-radius: 999px;
  font-size: 0.74rem;
  font-weight: 700;
  box-shadow: 0 0 0 2px var(--c-0f172a);   /* tmavý lem proti čáře */
}
@media (min-width: 720px) {
  .tt-rank-marker-chip { margin-left: 2.5rem; }   /* desktop gap 0.5rem */
}
.tt-rank-marker-stc {
  font-variant-numeric: tabular-nums;
  padding-right: 0.35rem;
  border-right: 1px solid rgba(10, 10, 10, 0.35);
}
.tt-rank-marker-name { font-weight: 700; }

.tt-on-course {
  background: var(--c-0c1a2e);
  border-bottom: 2px solid #38bdf8;
}
.tt-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Vlna 1 fáze A: 4 sloty on-course (stc | name | time | flt), 6 slotů
   ranking (rank | stc | name | time | diff | flt). Rozdíl přidán
   v této vlně. */
.tt-row {
  display: grid;
  grid-template-columns: 2.5rem 1fr auto 2.5rem;
  gap: 0.5rem;
  /* Vertikální zarovnání: center, NE baseline. Řádek míchá různé velikosti
     písma (běžící hodiny 1.05rem vs STČ 0.85rem) a badge s vlastním
     paddingem (FLT) — baseline pak sráží text k horní hraně řádku a posun
     kolísá řádek od řádku (nejvíc u live řádku v Pořadí, kde FLT badge má
     border). center drží text opticky uprostřed nezávisle na obsahu. */
  align-items: center;
  padding: 0.3rem 0.75rem;
  border-bottom: 1px solid var(--c-1e293b);
  font-size: 0.92rem;
}
/* `display: grid` výše přebíjí UA [hidden]{display:none} (autorské pravidlo
   vyhrává nad UA), takže `li.hidden` by řádek neskryl. Tohle pravidlo (vyšší
   specificita) hidden zase obnoví — full mód jím skrývá promovaného
   závodníka z „Na trati". */
.tt-row[hidden] { display: none; }
/* Delici cara postupu do vyrazovacich jizd (pavouka) v Poradi (TT). */
.tt-advance-cut {
  display: block;
  padding: 0;
  height: 0;
  line-height: 0;
  font-size: 0;
  border-top: 2px solid #22c55e;
}
.tt-row-on-course .tt-row-stc,
.tt-row-ranking .tt-row-rank,
.tt-row-ranking .tt-row-stc {
  color: var(--c-94a3b8);
  font-weight: 600;
  font-size: 0.85rem;
}
/* Pořadí zarovnat zprava (na úrovni jednotek) — tabular-nums drží číslice
   pod sebou, takže „1." a „10." lícují tečkou i jednotkami. padding-right
   zvětšuje mezeru mezi pořadím a startovním číslem. */
.tt-row-ranking .tt-row-rank {
  text-align: right;
  font-variant-numeric: tabular-nums;
  padding-right: 0.25rem;   /* STČ blízko k pořadí */
}
/* Startovní číslo vycentrovat (v pořadí (TT) i startovce, vč. hlaviček). */
.tt-row-ranking .tt-row-stc,
.tt-row-startlist .tt-row-stc,
.sl-head > span:first-child {
  text-align: center;
  font-variant-numeric: tabular-nums;
}
/* Detail buňky v ranking řádku (NAR/VK/VT/Oddíl) — na mobilu skryté
   (rozbalí se přes .sl-summary po tapu), na desktopu sloupce (viz @media). */
.tt-row-ranking .sl-cell { display: none; }
/* TT ranking hlavička — reuse .tt-row .tt-row-ranking gridu, přebarvená na
   muted header styl. */
.tt-rank-head {
  border-bottom: 1px solid var(--c-334155);
  /* zafixovat hlavičku pořadí pod sticky .site-header; z-index pod on-course
     scoreboardem (50), aby při aktivní NA TRATI sekci nepřekrývala. */
  position: sticky;
  top: var(--mobile-header-h, 100px);
  z-index: 40;
  background: var(--c-0f172a);
}
.tt-rank-head > span {
  color: #64748b !important;
  font-weight: 600 !important;
  font-size: 0.7rem !important;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
/* FLT v rankingu — červené pole „FLT-X" (parita s pavoukem,
   .bracket-race-athlete .athlete-flt). Žlutý badge .tt-row-flt zůstává
   on-course/scoreboardu. */
.tt-rank-flt {
  justify-self: start;
  align-self: center;
  background: #b91c1c;
  color: #fff;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  font-size: 0.7rem;
  font-weight: 600;
  white-space: nowrap;
}
.tt-row-ranking {
  /* Vlna 1 fáze A: pevné šířky Čas (4.5rem) + Rozdíl (3.5rem) — auto
     šířky by hodnotu cell po cellu měnily a desetinné tečky by neseděly
     pod sebou. tabular-nums + right-align v .tt-row-(time|diff) drží
     desetinné tečky zarovnané sloupcově. */
  grid-template-columns: 2.5rem 2.5rem 1fr 4.5rem 3.5rem 2.5rem;
}
.tt-row-ranking .tt-row-time {
  text-align: right;
}

/* Vlna 2.7.29: live-inline-ranking — scoreboard chrome na řádku v Pořadí.
   Paleta navazuje na Wave 2.7.16 scoreboard look (žlutá var(--c-facc15) na černém
   var(--c-0a0a0a), ui-monospace, dashed dividers). Žádný red FLT badge — uvnitř
   live řádku zůstává scoreboard yellow palette. Animace přesunu = Krok 4. */
.tt-row.tt-row--live {
  background: var(--c-0a0a0a);
  color: var(--c-facc15);
  font-family: ui-monospace, "SF Mono", Monaco, "Cascadia Code",
               "Roboto Mono", Consolas, "Liberation Mono",
               "Courier New", monospace;
  font-weight: 700;
  /* Jemný žlutý rámeček kolem celého řádku — tenká poloprůhledná čára přes
     inset box-shadow (nemění layout, na rozdíl od borderu), místo tlustých
     4px bočních pruhů. border-color: transparent zruší šedý spodní separátor.
     Horní hrana je 2px (druhý inset shadow): sticky neprůhledná hlavička
     Pořadí (.tt-rank-head, z-index 40) občas na hraně přilepení sub-pixel
     ukousne horní 1px → s 2px vždy aspoň 1px zůstane vidět. */
  border-color: transparent;
  box-shadow: inset 0 0 0 1px rgba(250, 204, 21, 0.5),
              inset 0 2px 0 0 rgba(250, 204, 21, 0.5);
}
.tt-row.tt-row--live .tt-row-rank,
.tt-row.tt-row--live .tt-row-stc,
.tt-row.tt-row--live .tt-row-name,
.tt-row.tt-row--live .tt-row-time,
.tt-row.tt-row--live .tt-row-diff {
  color: var(--c-facc15);
  font-weight: 700;
}
/* Tikající elapsed — glow stejně jako scoreboard running clock. */
.tt-row.tt-row--live .tt-row-time {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
  text-shadow: 0 0 6px rgba(250, 204, 21, 0.4);
}
/* FLT badge na live řádku: yellow ghost (rámeček + transparentní pozadí),
   ne červené pole z normálního .tt-rank-flt. Drží scoreboard estetiku. */
.tt-row.tt-row--live .tt-rank-flt {
  background: transparent;
  color: var(--c-facc15);
  border: 1px solid var(--c-facc15);
}

/* Vlna 2.7.29: animace přesunů.
   Entry: "vyletí z Na trati a vlétne do Pořadí" — slide-down + fade-in.
   Reposition: FLIP-style (JS změří delta, CSS dotáhne transform → 0).
   Respektuje prefers-reduced-motion: animace se nahradí instantním cut. */
@keyframes tt-live-row-enter {
  from {
    opacity: 0;
    transform: translateY(-12px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
.tt-row--live-entering {
  animation: tt-live-row-enter 280ms ease-out both;
}
.tt-row--live-flipping {
  /* Used by JS FLIP — JS sets initial transform inline, this class drives
     the easing back to identity. */
  transition: transform 250ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .tt-row--live-entering { animation: none; }
  .tt-row--live-flipping { transition: none; }
}
/* Startovní listina.
   Mobil (base): 3 sloty — stč | jméno | nasazený čas + chevron. Detailní
   buňky (ročník/VK/VT/oddíl) jsou skryté, rozbalí se po tapu (.is-expanded).
   Desktop (≥720px, viz @media níže): buňky jako plnohodnotné sloupce,
   řádek se nerozbaluje a hlavička .sl-head nese popisky. */
.tt-row-startlist {
  grid-template-columns: 2.5rem 1fr auto;
}
.tt-row-startlist .tt-row-stc {
  color: var(--c-94a3b8);
  font-weight: 600;
  font-size: 0.85rem;
}
.tt-row-startlist .tt-row-time {
  text-align: right;
}
/* Rezervované místo pro dosud neznámého postupujícího (repasáž Finále B →
   Finále A): čas platí, jméno ještě ne. Ztlumené + kurzíva, ať je na první
   pohled jasné, že řádek není závodník. */
.tt-row-sl-pending { color: #64748b; }
.tt-row-sl-pending .tt-row-name {
  font-style: italic;
  font-weight: 400;
  color: #64748b;
}
.tt-row-sl-pending .tt-row-stc { color: #475569; }
.tt-row-sl-pending .tt-row-time { color: #64748b; }
/* Průběžně postupující ze zdrojové fáze (Finále B ještě nedojelo): jméno už
   známé, ale ne konečné. Kreslí se stejně jako rezervované místo výše —
   ztlumeně a kurzívou, ať je jedním pohledem vidět, které řádky Finále A ještě
   nejsou jisté; teprve po dojetí zdrojové fáze zesílí do normálu. */
.tt-row-sl-provisional { color: #64748b; }
.tt-row-sl-provisional .tt-row-name {
  font-weight: 400;
  color: #64748b;
}
.tt-row-sl-provisional .tt-row-stc { color: #475569; }
.tt-row-sl-provisional .tt-row-time,
.tt-row-sl-provisional .sl-cell,
.tt-row-sl-provisional .sl-summary { color: #64748b; }
.tt-row-sl-provisional .tt-row-name,
.tt-row-sl-provisional .tt-row-stc,
.tt-row-sl-provisional .tt-row-time,
.tt-row-sl-provisional .sl-cell,
.tt-row-sl-provisional .sl-summary { font-style: italic; }
/* Hláška „listina ještě není úplná" nad startovkou fáze. */
.sl-pending-note {
  margin: 0;
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--c-1e293b);
  font-size: 0.78rem;
  line-height: 1.35;
  color: #94a3b8;
}
/* detailní buňky (desktop sloupce) a mobilní souhrn — skryté ve výchozím stavu */
.tt-row-startlist .sl-cell { display: none; }
.sl-summary { display: none; }
/* Hlavička sloupců startovky. Mobil (base): 3 nadpisy (St.č | Jméno | Start)
   zarovnané s řádky; detailní nadpisy (Roč./VK/VT/Oddíl) skryté. Desktop
   (≥720px) přepne grid na 7 sloupců a detailní nadpisy zobrazí. */
.sl-head {
  display: grid;
  grid-template-columns: 2.5rem 1fr auto;
  gap: 0.5rem;
  padding: 0.4rem 0.75rem;
  border-bottom: 1px solid var(--c-1e293b);
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #64748b;
  /* zafixovat hlavičku tabulky pod sticky .site-header (banner + cat-tabs).
     --mobile-header-h publikuje tt_sticky.js; var(--c-0f172a) pozadí kryje rolující
     řádky, z-index nad řádky a pod hlavičkou (100). */
  position: sticky;
  top: var(--mobile-header-h, 100px);
  z-index: 40;
  background: var(--c-0f172a);
}
.sl-head-detail { display: none; }
.sl-head-time { text-align: right; }

/* Mobil: sbalený řádek = jeden řádek (stč | jméno | čas); tap rozbalí druhý
   řádek se souhrnem (Oddíl, Ročník, VK, VT) bez popisků, oddělený čárkami. */
@media (max-width: 719.98px) {
  .tt-row-startlist { cursor: pointer; }
  /* souhrn těsně pod prvním řádkem (potlačit row-gap mřížky) */
  .tt-row-startlist.is-expanded { row-gap: 0; }
  .tt-row-startlist.is-expanded .sl-summary {
    display: block;
    grid-column: 1 / -1;
    padding: 0 0 0.15rem 3rem;
    font-size: 0.8rem;
    color: var(--c-94a3b8);
  }
  .tt-row-startlist.is-expanded .sl-summary:empty { display: none; }
}

/* Desktop: detailní buňky jako sloupce, žádné rozbalování.
   `.startlist` prefix zvyšuje specificitu nad duplicitní `.tt-row-startlist`
   pravidlo (grid 3 sloty) níže v souboru — bez něj by 7 buněk spadlo do
   3 sloupců a každý závodník by zabral 3 řádky. */
@media (min-width: 720px) {
  .startlist .sl-head,
  .startlist .tt-row-startlist {
    grid-template-columns: 2.5rem minmax(7rem, 1.4fr) 3.5rem 3rem 2.75rem minmax(5rem, 1fr) 5rem;
  }
  /* desktop: zobrazit i detailní nadpisy (Roč./VK/VT/Oddíl) */
  .sl-head-detail { display: block; }
  /* čas patří do posledního sloupce (vpravo), ač je v DOM hned za jménem */
  .tt-row-startlist .tt-row-time { order: 1; }
  .tt-row-startlist .sl-cell {
    display: block;
    font-size: 0.85rem;
    color: var(--c-cbd5e1);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .tt-row-startlist .sl-cell-year { font-variant-numeric: tabular-nums; }
  .tt-row-startlist .sl-cell::before { content: none; } /* popisek nese hlavička */
}

/* TT ranking — stejný princip jako startovka.
   Mobil: tap rozbalí souhrn (Oddíl, Ročník/VK, VT) pod řádkem. */
@media (max-width: 719.98px) {
  .tt-row-ranking { cursor: pointer; }
  /* Víc místa pro jméno — užší fixní sloupce + menší mezera, menší písmo
     jména a času. `.tt-ranking` prefix přebíjí duplicitní base grid.
     (platí i pro hlavičku .tt-rank-head, takže zarovnání drží.) */
  .tt-ranking .tt-row-ranking {
    grid-template-columns: 2rem 2rem 1fr 3.5rem 2.75rem 3rem;
    gap: 0.35rem;
  }
  .tt-row-ranking .tt-row-name,
  .tt-row-ranking .tt-row-time { font-size: 0.85rem; }
  .tt-row-ranking.is-expanded { row-gap: 0; }
  .tt-row-ranking.is-expanded .sl-summary {
    display: block;
    grid-column: 1 / -1;
    padding: 0 0 0.15rem 2.75rem;
    font-size: 0.8rem;
    color: var(--c-94a3b8);
  }
  .tt-row-ranking.is-expanded .sl-summary:empty { display: none; }
  /* hlavička se na mobilu nerozbaluje */
  .tt-rank-head { cursor: default; }
}

/* Desktop: NAR/VK/VT/Oddíl jako sloupce mezi jménem a časem → 10 sloupců.
   `.tt-ranking` prefix zvyšuje specificitu nad duplicitní `.tt-row-ranking`
   (6-sloupcové) pravidlo níže v souboru. */
@media (min-width: 720px) {
  .tt-ranking .tt-row-ranking {
    grid-template-columns: 2rem 2rem minmax(6rem, 1fr) 3.5rem 2rem 3rem 2.75rem minmax(4.5rem, 1fr) 4.5rem 3.5rem 3.25rem;
  }
  .tt-row-ranking .sl-cell {
    display: block;
    font-size: 0.85rem;
    color: var(--c-cbd5e1);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .tt-row-ranking .sl-cell-year { font-variant-numeric: tabular-nums; }
  .tt-row-ranking .sl-cell-vkrank { font-variant-numeric: tabular-nums; text-align: right; }
  .tt-row-ranking .sl-cell-vk { text-align: center; }
}
.tt-row-name {
  font-weight: 500;
  color: var(--c-f1f5f9);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tt-row-time {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--c-cbd5e1);
}
.tt-row-on-course .tt-row-time { color: #38bdf8; }
.tt-row-diff {
  font-variant-numeric: tabular-nums;
  color: var(--c-94a3b8);
  font-size: 0.85rem;
  text-align: right;
  white-space: nowrap;
}
/* Vlna 3 (C.1): FLT badge — žluté plné pozadí, černá číslice. Statický
   `G` prefix (G4) odstraněn z renderů — badge sám značí FLT, číslo
   uvnitř značí bránu.
   Vlna 3 (K3): vertikální centrování — inline-flex + align-items:center
   + line-height:1 + symetric padding. Bez line-height:1 sedí číslice
   v upper-half line-boxu (default 1.4, font bez descenderu) → opticky
   prázdné místo pod číslicí. */
.tt-row-flt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  background: var(--c-facc15);
  color: var(--c-0a0a0a);
  padding: 0.2rem 0.4rem;
  border-radius: 4px;
  font-size: 0.72rem;
  font-weight: 700;
  white-space: nowrap;
}
.tt-row-flt-empty {
  color: var(--c-475569);
  text-align: center;
  font-size: 0.85rem;
}
.tt-row.status-dnf,
.tt-row.status-dns,
.tt-row.status-ral,
.tt-row.status-dsq,
.tt-row.status-dqb { opacity: 0.55; }
.tt-row.status-dnf .tt-row-time,
.tt-row.status-dns .tt-row-time,
.tt-row.status-ral .tt-row-time,
.tt-row.status-dsq .tt-row-time,
.tt-row.status-dqb .tt-row-time { color: #f87171; }
.tt-empty {
  padding: 1.5rem 1rem;
  text-align: center;
  color: #64748b;
}

/* Latest finisher highlight (sjednoceno s desktop wave 2.4.11 / mobile 2.7.19). */
.tt-row-ranking[data-latest-finisher="1"] {
  background-color: rgba(34, 197, 94, 0.18);
  box-shadow: inset 3px 0 0 #22c55e;
  transition: background-color 0.5s ease-out;
}
@keyframes tt-latest-finisher-pulse {
  0%   { background-color: rgba(34, 197, 94, 0.55); }
  50%  { background-color: rgba(34, 197, 94, 0.35); }
  100% { background-color: rgba(34, 197, 94, 0.18); }
}
.tt-row-ranking.latest-finisher-pulse {
  animation: tt-latest-finisher-pulse 2s ease-out;
}
.tt-row-ranking.status-dnf[data-latest-finisher="1"],
.tt-row-ranking.status-ral[data-latest-finisher="1"],
.tt-row-ranking.status-dns[data-latest-finisher="1"],
.tt-row-ranking.status-dsq[data-latest-finisher="1"],
.tt-row-ranking.status-dqb[data-latest-finisher="1"] {
  background-color: rgba(239, 68, 68, 0.12);
  box-shadow: inset 3px 0 0 #ef4444;
}

/* Na trati scoreboard look — sdílená yellow paleta (převzato z mobile 2.7.17). */
#tt-on-course {
  background: var(--c-0a0a0a);
  border: 2px solid var(--c-facc15);
  border-radius: 8px;
  padding: 0.5rem;
  margin-bottom: 1rem;
}
/* Optická korekce: obsah o ~1px níž. align-items: center vystředí BOXY,
   jenže ink písma sedí v line-boxu výš — pod účařím je vyhrazené místo pro
   dolní dotažnice, které STČ/jméno/hodiny nemají. Text pak opticky visí
   u horní hrany černého panelu (měřeno po pixelech: 5,3 px nad inkem vs
   7,4 px pod ním). Padding 0.36rem nahoře / 0.24rem dole — součet zůstává
   0.6rem, výška řádku se nemění. */
#tt-on-course .tt-row {
  background: transparent;
  color: var(--c-facc15);
  font-family: ui-monospace, "SF Mono", Monaco, "Cascadia Code",
               "Roboto Mono", Consolas, "Liberation Mono",
               "Courier New", monospace;
  font-weight: 700;
  border-bottom: 1px dashed rgba(250, 204, 21, 0.2);
  padding: 0.36rem 0.25rem 0.24rem;
}
#tt-on-course .tt-row:last-child {
  border-bottom: none;
}
#tt-on-course .tt-row-stc {
  color: var(--c-fde047);
  font-weight: 700;
  font-size: 0.85rem;
}
#tt-on-course .tt-row-name {
  color: var(--c-facc15);
  font-weight: 700;
}
#tt-on-course .tt-row-on-course .tt-row-time {
  color: var(--c-facc15);
  font-size: 1.05rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
  text-shadow: 0 0 5px rgba(250, 204, 21, 0.4);
  white-space: nowrap;
}
/* Vlna 3 (C.1): scoreboard FLT badge sjednocený s globálním .tt-row-flt
   — plné žluté pozadí, černá číslice. Dřív transparentní s žlutým
   borderem; teď konzistentní look v on-course i ranking sekci.
   Vlna 3 (K3): vertikální centrování — inline-flex + line-height:1 dědí
   z globálního .tt-row-flt; padding přepisujeme jen pro scoreboard
   font-size (0.78rem) a větší font-weight. */
#tt-on-course .tt-row-flt {
  background: var(--c-facc15);
  color: var(--c-0a0a0a);
  padding: 0.2rem 0.4rem;
  border-radius: 3px;
  font-size: 0.78rem;
  font-weight: 800;
}
#tt-on-course .tt-row-flt-empty {
  color: #78716c;
  font-size: 0.78rem;
}

/* ─────────────────────────────────────────────────────────────────────
   Vlna 2 fáze A: TT live header rámec (banner + pás kategorií + status
   puntík). Sdílený _tt_frame.html partial v site-header bloku `header`.
   Mírné breakpoint úpravy v desktop.css / mobile.css drží šířky a tap
   targets (CSS unify → Commit 3b).
   ───────────────────────────────────────────────────────────────────── */

.tt-frame {
  display: flex;
  flex-direction: column;
  gap: 0;             /* divider na .event-banner sedí flush proti .tt-cat-tabs */
  flex: 1;            /* zabírá flex middle slot v site-header / site-header */
  min-width: 0;       /* prevent overflow z dlouhého názvu závodu */
}

/* Banner kontejner — robustní layout. Pozdější vlna vymění textový
   obsah za <img> / background-image bez změny okolního layoutu.
   Vlna 2 fáze B: dva řádky — název závodu (větší) + meta (venue + datum,
   menší, oba jsou volitelné).
   Vlna 3 (A, K1): KXRS top-stripe barva #1e3a5f — explicitní background
   na .event-banner, jen banner (NE celý header — outer .site-header /
   .site-header zůstává na var(--c-1e293b) a .tt-cat-tabs ji dědí). Spodní
   border var(--c-475569) odděluje banner od pásu kategorií.
   Vlna 3 (K2): redukované vertikální padding (0.35rem) + tightening
   line-heights (1.1) + meta margin (0.1rem) → výška banneru cca 47-48px
   (vs původních ~64px), opticky srovnatelné s KXRS header (~45px). */
.event-banner {
  background: #1e3a5f;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0.35rem 1rem;
  overflow: hidden;
  text-align: center;
  border-bottom: 1px solid var(--c-475569);
}
.event-banner-text {
  font-weight: 700;
  font-size: 1.15rem;
  line-height: 1.1;
  color: var(--c-f1f5f9);
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.event-banner-meta {
  font-size: 0.78rem;
  line-height: 1.1;
  color: var(--c-cbd5e1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  margin-top: 0.1rem;
}

/* Vlna 3 (K4): banner edge-to-edge — zrušit padding na .site-header /
   .site-header když je uvnitř .event-banner (TT view). Bez padding
   rodiče modrý banner lícuje s okrajem okna. Logo je v TT view skryté
   přes block site_logo override v tt_live.html (jinak by blokovalo
   left edge na desktopu). Kompenzaci poskytuje padding přímo na
   .tt-cat-tabs (níže) — vrátíme horizontální/vertikální offset, jen
   pro pás kategorií, ne pro banner. */
.site-header:has(.event-banner),
.site-header:has(.event-banner) {
  padding: 0;
}

/* Pás kategorií — anchor tlačítka místo popup. Status puntík na konci.
   Vlna 3 (K4): kompenzační padding (header v TT view má padding: 0
   kvůli edge-to-edge banneru) — vrací horizontální + vertikální offset,
   který měl předtím rodič. Banner ho NEMÁ (zůstává edge-to-edge). */
/* Segment control kategorií (varianta D): vnější pruh (full-width separátor
   pod hlavičkou + horizontální scroll) obaluje orámovaný blok segmentů bez
   mezer. Sdílí TT / pavouk / startovka. */
.tt-cat-tabs-strip {
  /* Flex řádek: vlevo scrollovatelný pás kategorií (.tt-cat-tabs), volitelně
     vpravo ikona „Živý čas v pořadí" (.tt-live-toggle, jen TT). Scroll se
     odehrává uvnitř .tt-cat-tabs, takže ikona zůstává trvale vpravo. */
  display: flex;
  align-items: center;
  /* .site-header má horizontální padding 0.75rem — prolomíme ho negativním
     okrajem, aby band sahal až k okrajům obrazovky, a kompenzujeme vnitřním
     paddingem 1.5rem (0.75 header + 0.75), aby tlačítka zůstala zarovnaná
     s titulem v hlavičce. */
  margin: 0 -0.75rem;
  padding: 0.3rem 1.5rem;
  /* Pozadí sjednoceno s obsahem pod ním (tabulka s pořadím = var(--c-0f172a), body),
     ne s hlavičkou (var(--c-1e293b)). */
  background: var(--c-0f172a);
  /* Header-unify: pás sedí pod hlavním řádkem záhlaví (TT + pavouk),
     tenká linka ho odděluje. */
  border-top: 1px solid var(--c-334155);
}
/* Live ve fázi TT: místo přepínače kategorií jen štítek aktivní kategorie
   (live_tt.html). Sdílí band (.tt-cat-tabs-strip), label je needitovatelný. */
.live-focus-strip {
  min-height: 38px;          /* parita výšky s pásem kategorií */
}
.live-focus-label {
  display: inline-flex;
  align-items: center;
  flex: 1 1 auto;            /* roztáhne se → přepínač vzhledu / PDF chipy vpravo */
  min-width: 0;
  min-height: 38px;
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--c-e2e8f0);
}
/* Konečné výsledky: nadpis na velikost nadpisu sekce v Rozpisu (1.05rem). */
.live-focus-label--lg { font-size: 1.05rem; font-weight: 700; }
/* Label aktivní fáze (KVAL/FA/FB) PŘED názvem kategorie v záhlaví LIVE —
   přesunutý z nadpisu nad výsledky. Akcentní, oddělený svislítkem
   (.live-focus-sep) mezi fází a názvem kategorie. */
.live-focus-phase {
  flex: 0 0 auto;
  font-weight: 700;
  color: #38bdf8;
}
/* Svislítko oddělující text fáze (KVALIFIKACE) od názvu kategorie. */
.live-focus-sep {
  flex: 0 0 auto;
  margin: 0 0.5rem;
  font-weight: 400;
  color: var(--c-94a3b8);
}
/* Celkové (event-level) PDF chipy v řádku s nadpisem. */
.live-focus-docs { display: flex; align-items: center; gap: 0.4rem; flex: 0 0 auto; }
/* Live „konečné výsledky" — responzivní grid karet (1 na kategorii), uvnitř
   top-4 finále A. Athlete řádky reusují .race-card-athlete (vč. desktop
   sloupce oddíl/stát + FLT pruhu). */
.results-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
  gap: 0.6rem;
  padding: 0.5rem;
}
.results-card {
  background: var(--c-1e293b);
  border: 1px solid var(--c-475569);
  border-radius: 8px;
  padding: 0.6rem 0.75rem;
}
.results-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  font-weight: 700;
  color: var(--c-f1f5f9);
  font-size: 1.05rem;          /* parita s .rozpis-section-title */
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 0.4rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--c-334155);
}
.results-card-title { min-width: 0; }
.results-card-docs { display: flex; gap: 0.35rem; flex: 0 0 auto; }
/* Podsekce Finále A / Finále B v rámci karty kategorie. */
.results-final + .results-final { margin-top: 0.5rem; }
.results-card-sublabel {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-94a3b8);
  margin: 0.25rem 0 0.1rem;
}
.results-card-athletes { list-style: none; margin: 0; padding: 0; }
/* o malinko čitelnější než kompaktní prev/next karty + řádkové rozestupy */
.results-card-athletes .race-card-athlete {
  font-size: 0.85rem;
  padding: 0.18rem 0;
}
/* medaile pro top 3 (zlato/stříbro/bronz) — jen číslo pořadí */
.results-card-athletes .race-card-athlete[data-pos="1"] .athlete-pos { color: #facc15; }
.results-card-athletes .race-card-athlete[data-pos="2"] .athlete-pos { color: #cbd5e1; }
.results-card-athletes .race-card-athlete[data-pos="3"] .athlete-pos { color: #d97706; }

.tt-cat-tabs {
  display: flex;              /* řada tlačítek kategorií */
  align-items: center;
  gap: 0;                     /* segmenty bez mezer */
  flex-wrap: nowrap;
  flex: 1 1 auto;            /* zabere zbytek řádku, ikona vpravo si nechá své */
  min-width: 0;             /* dovolí scroll uvnitř flex itemu */
  overflow-x: auto;          /* scroll přesunut sem ze stripu (kvůli ikoně vpravo) */
  -webkit-overflow-scrolling: touch;
  /* 7+ kategorií → blok přeteče → plynulý scroll se scroll-snapem.
     proximity (ne mandatory) snapne jen blízko hranice, jinak volný scroll. */
  scroll-snap-type: x proximity;
  scrollbar-width: none;      /* Firefox: skrýt scrollbar */
  /* bez orámování — jednotlivá tlačítka si nesou vlastní styl (aktivní pilulka) */
}
.tt-cat-tabs::-webkit-scrollbar { display: none; }  /* WebKit: skrýt scrollbar */
/* Segment: štíhlejší (~38px tap-target, kompromis vs 44px a11y floor
   z Wave 2.7.5), jen jemně zaoblený (4px). Aktivní = modrá + bílá;
   neaktivní = transparentní + světle šedá + hover. */
.tt-cat-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;             /* nezmenšovat → 7+ položek korektně scrolluje */
  scroll-snap-align: start;
  min-height: 38px;
  min-width: 3rem;
  padding: 0.4rem 1.05rem;    /* ~6px svisle, ~17px vodorovně */
  border-radius: 4px;
  background: transparent;
  color: var(--c-cbd5e1);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
  transition: background 0.15s, color 0.15s;
}
.tt-cat-tab:hover {
  background: rgba(255, 255, 255, 0.08);
  color: var(--c-f1f5f9);
  text-decoration: none;
}
.tt-cat-tab.active {
  background: #38bdf8;
  color: #ffffff;             /* aktivní text bílý (dříve tmavý var(--c-0f172a)) */
}
.tt-cat-tab:active { transform: scale(0.97); }

/* Desktop: zarovnat obsah hlavičky (titul) i tlačítka kategorií s levým
   okrajem tabulky (startovka / TT / pořadí). Obsah .site-main je max-width
   900px centrovaný (+1rem padding); bandy hlavičky (var(--c-1e293b)) a pruhu
   kategorií (var(--c-0f172a)) zůstávají full-width, ale jejich OBSAH dostane stejný
   kontejner (max-width 900 + margin:auto + 1rem padding). margin:auto drží
   shodný střed jako .site-main → levé okraje lícují, bez 100vw/scrollbar
   nesouladu. */
@media (min-width: 720px) {
  .site-header-main {
    width: 100%;
    max-width: 900px;
    margin: 0 auto;
    padding-left: 1rem;
    padding-right: 1rem;
  }
  /* Landing: tabulka závodů (.home) je max-width 1280px — titul v hlavičce
     zarovnáme na stejnou šířku, ať lícuje s jejím levým okrajem. */
  body.home-no-dock .site-header-main {
    max-width: 1280px;
  }
  /* Band zůstává full-width (var(--c-0f172a)), ale jeho OBSAH (nav + ikona) se
     centruje do 900px sloupce přes symetrický padding. Levý okraj navu tak
     lícuje s tabulkou pod ním, ikona „Živý čas" sedí na pravém okraji
     stejného sloupce. max() drží min. 1rem padding na užších desktopech. */
  .tt-cat-tabs-strip {
    padding-left: max(1rem, (100% - 900px) / 2);
    padding-right: max(1rem, (100% - 900px) / 2);
  }
  /* Desktop: pravá hrana PDF skupiny (a tím i fázového přepínače — je to tentýž
     element) lícuje svisle s přepínačem jazyka CZ|EN, tj. s posledním prvkem
     hlavičky. Cílový odstup od pravé hrany pásu je `centrovací offset hlavičky
     + 1.5rem` (0.75rem breakout margin pásu + 0.75rem padding .site-header).

     Proč to není jedna konstanta ani jedna formule:
     a) pás i hlavička se centrují na 900px sloupec, ale KLAMPUJÍ jinde —
        hlavička `max-width` + `margin:auto` (offset nikdy < 0), pás
        `padding: max(1rem, …)` (podlaha 1rem). Dřívější konstanta 1.75rem tak
        seděla jen nad 956px; pod ní ujížděla doleva až o 20px.
     b) PAST: % v `margin` téhle flex položky se počítá z CONTENT boxu pásu
        (tj. už BEZ jeho paddingu), ne z hlavičky jako padding výše — proto
        v (100% - 892px) figuruje 892 = 924 - 2*1rem, ne 900. Nad breakpointem
        je navíc ten content box konstantních 924px, takže tam % nic neřeší
        a musí nastoupit konstanta.
     Zlom 956px = šířka, při které padding pásu opouští podlahu 1rem
     ((956 - 24 - 900) / 2 = 16px). Ověřeno měřením na 22 šířkách 360–1920px
     (Výsledky bez přepínače i Startovka s přepínačem), odchylka 0px. */
  .tt-doc-switch {
    margin-right: calc(clamp(0px, (100% - 892px) / 2, 1rem) + 0.5rem);
  }
  @media (min-width: 956px) {
    .tt-doc-switch { margin-right: 1.5rem; }
  }
  .tt-cat-tabs {
    flex: 1 1 auto;
    margin: 0;
    padding: 0;
    justify-content: flex-start;
  }
}

/* Mobil (< 720px): zhusti taby kategorií i PDF přepínač, ať se vejdou vedle
   sebe do jednoho řádku bez zbytečného scrollování. Zmenšujeme hlavně
   vodorovné rozměry (padding/min-width/font) — výšku tap-targetu držíme na
   38px (a11y). PDF skupina (.tt-doc-switch) se přitiskne blíž k tabům. */
@media (max-width: 719px) {
  .tt-cat-tab {
    min-width: 2.1rem;
    padding: 0.4rem 0.55rem;
    font-size: 0.82rem;
    letter-spacing: 0.01em;
  }
  .tt-doc-switch { margin-left: 0.4rem; }
  .tt-doc-switch .doc-chip--tabs { padding: 3px 6px; }
  .doc-chip--phase .doc-chip-lbl { min-width: 12px; font-size: 11px; }
}

/* Status puntík — bez textu, barva podle stavu. Žije na konci pásu
   kategorií (margin-left: auto). Class řídí connection_status.js přes
   classList add/remove (ne přes celý className přepis — jinak by se
   .tt-conn-dot ztratil). Specificita .tt-conn-dot.connection-status-*
   (0,2,0) > .connection-status-* (0,1,0) → puntík background vyhrává
   nad původním badge backgroundem. */
.tt-conn-dot {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #4ade80;       /* default online */
  margin-left: auto;
  flex-shrink: 0;
  transition: background 0.2s, box-shadow 0.2s;
}
.tt-conn-dot.connection-status-online   { background: #4ade80; }
.tt-conn-dot.connection-status-stale    {
  background: #fb923c;
  animation: live-pulse 1.5s ease-in-out infinite;
}
.tt-conn-dot.connection-status-offline  { background: #ef4444; }
.tt-conn-dot.connection-status-recovered {
  background: #4ade80;
  box-shadow: 0 0 8px rgba(74, 222, 128, 0.8);
}

/* ── Home page (Wave 2.13.0 landing-sections) ── */
.home {
  max-width: 1280px;
  margin: 0 auto;
  padding: 1.5rem 1rem;
}

.home-section {
  margin-bottom: 2.5rem;
}

.event-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 1rem;
}

.event-grid--compact {
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.6rem;
}

.event-card {
  display: block;
  padding: 1rem;
  border-radius: 8px;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s, transform 0.15s;
}
.event-card:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
  text-decoration: none;
}

.event-card--live {
  border-color: rgba(34, 197, 94, 0.5);
  background:
    linear-gradient(135deg, rgba(34,197,94,0.08), transparent 60%),
    var(--card-bg);
}
.event-card--finished {
  opacity: 0.75;
}

.event-card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.event-card-name {
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0;
  line-height: 1.3;
  color: var(--c-f1f5f9);
}

.event-card-live-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: var(--live-soft);
  color: #4ade80;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  white-space: nowrap;
  flex-shrink: 0;
}

.event-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  font-size: 0.85rem;
  color: var(--muted);
}
.event-card-meta > span + span::before {
  content: "·  ";
  margin-right: 0.2rem;
  opacity: 0.6;
}

.event-card-updated {
  margin-top: 0.6rem;
  font-size: 0.75rem;
  color: #4ade80;
}

/* Wave 2.13.3: .live-pulse + @keyframes live-pulse-anim removed —
   landing status indicator is a static colored dot (.event-dot), no
   animation. The unrelated .live-dot pulse in TT live banner uses
   @keyframes live-pulse (no -anim suffix) in mobile.css/desktop.css. */

/* Mobile úpravy: na úzkém viewportu jen menší padding, sekce jdou
   přirozeně do 1 sloupce díky auto-fill 320px minimum. */
@media (max-width: 480px) {
  .home {
    /* L/R padding 1rem = stejně jako hlavička (.site-header-main) → levý okraj
       tabulky lícuje s názvem a pravý s ikonou režim. */
    padding: 1rem;
  }
  .home-section {
    margin-bottom: 1.6rem;
  }
  .event-card {
    padding: 0.8rem;
  }
}

/* ── Wave 2.13.4: unified landing layout ──
   Desktop: single <table> with 3 <tbody> sections (live/upcoming/archive),
   one <thead> for column alignment, visible separator between sections.
   Mobile: dedicated <div>-based cards (separate partial). Markup is split
   per layout — CSS toggles which one is visible. No table-reset gymnastics.
*/

/* Status dot — shared between desktop table cell and mobile card header. */
.event-dot {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  flex-shrink: 0;
  vertical-align: middle;
}
.event-dot--live      { background: #22c55e; }
.event-dot--upcoming  { background: var(--accent); }
.event-dot--finished  { background: var(--muted); }
/* live_now: běží živé výsledky → červená pulzující tečka (radar ping),
   stejná červená jako Live puntík v docku. Odlišuje „běží výsledky" od
   pouhého „probíhá" (zelená). */
.event-dot--livenow {
  background: #ef4444;
  animation: event-dot-pulse 1.8s ease-out infinite;
}
@keyframes event-dot-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.55); }
  70%  { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
  100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .event-dot--livenow { animation: none; }
}

/* ── Mobile default (<720px): show cards, hide table ── */

.event-table {
  display: none;
}
.event-cards {
  display: block;
}

.event-cards-section {
  margin-bottom: 1.2rem;
}
.event-cards-section:last-child {
  margin-bottom: 0;
}

.event-mobile-card {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.6rem;
  row-gap: 0.25rem;
  align-items: center;
  padding: 0.8rem 1rem;
  margin-bottom: 0.6rem;
  border-radius: 8px;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s;
}
.event-mobile-card:hover {
  border-color: var(--accent);
  text-decoration: none;
}
.event-mobile-card--live {
  border-color: rgba(34, 197, 94, 0.5);
  background:
    linear-gradient(135deg, rgba(34,197,94,0.08), transparent 60%),
    var(--card-bg);
}
.event-mobile-card--finished {
  opacity: 0.75;
}

.event-mobile-card-header {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.event-mobile-card-name {
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--c-f1f5f9);
}

.event-mobile-card-meta {
  grid-column: 2;   /* aligned with name (offset right of dot column) */
  font-size: 0.85rem;
  color: var(--muted);
  line-height: 1.5;
}
.event-mobile-card-sep {
  margin: 0 0.2rem;
  opacity: 0.5;
}
.event-mobile-card-number {
  font-variant-numeric: tabular-nums;
}


/* ── Desktop (>=720px): show table, hide cards ── */

@media (min-width: 720px) {
  .event-cards {
    display: none;
  }
  .event-table {
    display: table;
    width: 100%;
    border-collapse: collapse;
  }

  .event-table thead {
    display: table-header-group;
  }
  .event-table th {
    padding: 0.65rem 0.8rem;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-bottom: 1px solid var(--card-border);
    text-align: left;
  }

  .event-table .event-tbody {
    display: table-row-group;
  }
  /* Visible separator between sections: thicker top border on the first
     row of any non-first <tbody>. Pseudo-elements on <tbody> are spotty
     across browsers, so we put the border on the first <tr>'s cells. */
  .event-table .event-tbody + .event-tbody .event-row:first-child > td {
    border-top: 2px solid var(--card-border);
    padding-top: 1.05rem;  /* visual breathing room above the separator */
  }

  .event-row {
    display: table-row;
    cursor: pointer;
    transition: background-color 0.12s;
  }
  .event-row > td {
    display: table-cell;
    padding: 0.65rem 0.8rem;
    vertical-align: middle;
    border-bottom: 1px solid rgba(51, 65, 85, 0.5);
  }
  .event-row:hover {
    background: rgba(56, 189, 248, 0.06);
  }
  .event-row--live {
    background: rgba(34, 197, 94, 0.04);
  }
  .event-row--live:hover {
    background: rgba(34, 197, 94, 0.10);
  }
  .event-row--finished {
    opacity: 0.85;
  }

  .event-row > td.col-name {
    font-size: 1rem;
    font-weight: 700;
  }
  .event-row > td.col-name a {
    color: var(--c-f1f5f9);
    text-decoration: none;
  }
  .event-row > td.col-name a:hover {
    color: var(--accent);
  }

  /* Číslo závodu, datum a místo menším písmem (méně výrazné než název). */
  .event-row > td.col-number,
  .event-row > td.col-date,
  .event-row > td.col-venue {
    font-size: 0.82rem;
  }

  /* Column widths — fixed so all sections align identically. */
  .event-table .col-status { width: 4rem; text-align: center; }
  .event-table .col-number { width: 4rem; text-align: center; font-variant-numeric: tabular-nums; color: var(--muted); }
  .event-table .col-date   { width: 8rem; white-space: nowrap; }
  .event-table .col-name   { width: auto; }
  .event-table .col-venue  { width: 10rem; }
}


/* ═══════════════════════════════════════════════════════════════════
   Wave 2.14.0 Commit 3b: merged from mobile.css (mobile-first ground state).
   Linked after the base rules above — same cascade order as the previous
   base.css + mobile.css <link> pair, so rendering is unchanged.
   ═══════════════════════════════════════════════════════════════════ */

/* Wave 2.7.1 + 2.7.2: mobile-specific styles. Loaded only when shell == "mobile". */

/* From base style.css (Wave 2.6.2b live chip polish): tighter padding */
@media (max-width: 480px) {
  .live-current-heat { padding: 0.5rem 0.75rem; }
  .live-current-heat .athlete-name { font-size: 0.8rem; }
}

/* Wave 2.14.0: dead blocks removed (shell-toggle, mobile-placeholder,
   shell-mobile) — shell mechanism + placeholder page jsou pryč; dark theme
   žije na `body` v base.css. */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  background: var(--c-1e293b);
  border-bottom: 1px solid var(--c-334155);
}
/* Header-unify: hlavní řádek záhlaví — event-info (vlevo) + connection-status. */
.site-header-main {
  display: flex;
  align-items: center;
  /* menší mezera než dřív (0.75rem): ovládací prvky vpravo žijí ve vlastním
     sevřeném shluku (.header-tools), takže tenhle gap odděluje už jen titul
     od shluku — víc místa na název závodu. */
  gap: 0.5rem;
  /* mobil: levý padding 0 → logo flush k okraji; pravý 0.75rem drží přepínač
     režimu uvnitř obrazovky. Desktop padding přepíše @media (min-width:720px). */
  padding: 0.5rem 0.75rem 0.5rem 0;
  min-height: 53px;
}
/* Logo „kros.results.cz" je v hlavičce jen na landing (jako titul stránky);
   na stránkách závodu hlavičku nese blok .site-event-info. */
.site-brand {
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--c-f1f5f9);
  text-decoration: none;
}
.site-brand:hover { text-decoration: none; }
/* Detail závodu v hlavičce: dvouřádkový blok — název (větší) + pod ním
   místo · datum · #číslo (menší, tlumené). flex:1 + min-width:0 + ellipsis
   na obou řádcích nechá dlouhý text useknout, aby neodtlačil connection-status. */
.site-event-line {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.1rem;
  color: var(--c-f1f5f9);
}
.site-event-name {
  font-size: 1.1rem;   /* mobil; desktop zvětší v @media (min-width:720px) */
  font-weight: 700;
  line-height: 1.15;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.site-event-meta {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--c-94a3b8);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Hlavička je odkaz na landing — potlač defaultní podtržení/barvu odkazu,
   jemný hover jako náznak klikatelnosti (parita s domečkem v docku). */
a.site-event-line {
  text-decoration: none;
  cursor: pointer;
  transition: opacity 0.15s ease;
}
a.site-event-line:hover {
  opacity: 0.8;
}

.live-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: #0c4a6e;
  color: var(--c-f1f5f9);
  border-radius: 999px;
  padding: 0.3rem 0.7rem;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
  border: none;
}
.live-badge[data-state="paused"] {
  background: var(--c-475569);
  opacity: 0.85;
}
.live-badge.live-badge-error {
  background: #7f1d1d;
}
.live-badge .live-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #38bdf8;
  animation: live-pulse 1.5s ease-in-out infinite;
}
.live-badge[data-state="paused"] .live-dot {
  animation: none;
  background: var(--c-94a3b8);
}
@keyframes live-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.5; transform: scale(1.3); }
}
.live-badge .live-scope {
  font-size: 0.78rem;
  opacity: 0.85;
  text-transform: lowercase;
}

.site-main {
  padding-bottom: 56px;
  min-height: calc(100vh - 48px - 56px);
}
/* Wave 2.13.4: landing page nemá dock — uvolnit rezervovaný spodní prostor. */
body.home-no-dock .site-main {
  padding-bottom: 1rem;
  min-height: calc(100vh - 48px);
  /* Landing: nech šířku řídit .home (max-width 1280), ať tabulka lícuje
     s hlavičkou (taky 1280). Bez tohoto by .site-main (900) tabulku seřízl. */
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

/* ─────────────────────────────────────────────────────────────────────
   Race strip
   ───────────────────────────────────────────────────────────────────── */

.race-strip {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.5rem;
}

/* Compact cards (prev/next).
   Wave 2.7.12: status-driven border — done (prev) gets a soft green,
   pending (next) gets the hero pending blue. Default fallback is a
   light gray visible against the var(--c-1e293b) background. The same color
   protocol as the hero card but subtler since compacts are secondary. */
.race-card-compact {
  background: var(--c-1e293b);
  border: 1px solid var(--c-475569);
  border-radius: 8px;
  padding: 0.6rem 0.75rem;
  cursor: pointer;
  transition: background 0.15s, border-color 0.3s;
  min-height: 80px;
}
.race-card-compact[data-race-status="done"] {
  border-color: rgba(74, 222, 128, 0.4); /* mírná zelená */
}
.race-card-compact[data-race-status="pending"] {
  border-color: #38bdf8; /* hero pending blue */
}
.race-card-compact:active { background: var(--c-334155); }
.race-card-compact-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 0.4rem;
  font-size: 0.85rem;
}
.race-card-label { font-weight: 600; color: var(--c-f1f5f9); }
.race-card-status { font-size: 0.78rem; color: var(--c-94a3b8); }
.race-card-status.race-status-active { color: #38bdf8; }
.race-card-status.race-status-done { color: #4ade80; }

.race-card-athletes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.2rem 0.5rem;
}
.race-card-athlete {
  font-size: 0.78rem;
  color: var(--c-cbd5e1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  align-items: baseline;
  gap: 0.25rem;
}
.race-card-athlete .athlete-pos {
  display: inline-block;
  width: 1.2em;
  font-weight: 600;
  color: var(--c-f1f5f9);
  flex-shrink: 0;
}
.race-card-athlete .athlete-name {
  overflow: hidden;
  text-overflow: ellipsis;
}
.race-card-athlete .athlete-flt {
  font-size: 0.7rem;
  background: #b91c1c;
  color: #fff;
  padding: 0.1rem 0.45rem;
  border-radius: 4px;
  margin-left: 0.2em;
}
.race-card-athlete.athlete-status-dns,
.race-card-athlete.athlete-status-dnf,
.race-card-athlete.athlete-status-ral,
.race-card-athlete.athlete-status-dsq,
.race-card-athlete.athlete-status-dqb { opacity: 0.55; }
/* Wave 2.7.11: junior italic dropped — was a desktop bracket-table legacy
   that mobile inherited; Wave 2.6.6 already removed it from the desktop
   side. Class .athlete-junior is still emitted by templates for any
   future hook but no longer carries a font-style. */

/* Hero card.
   Wave 2.7.8: auto-height (drop min-height: 280px) — card sizes to actual
   content, no empty space below 4 athletes. Asymmetric padding: 0.5rem
   right (was 0.75rem) so the right column (pulsing dot in header, status
   pills in athlete rows) sits closer to content rather than glued to the
   card edge. Left padding unchanged to preserve label position. */
.race-card-hero {
  background: var(--c-1e293b);
  border-radius: 12px;
  padding: 0.75rem 0.5rem 0.75rem 0.75rem;
  border: 2px solid #38bdf8; /* default = pending / unknown */
  transition: border-color 0.3s;
}
/* Wave 2.7.7: status-driven border colors. Mirror the .live-current-heat
   convention (red=active, green=done) so the outer hero ring agrees with
   the inner live chip. Pending falls back to the default blue. */
.race-card-hero[data-race-status="active"] {
  border-color: #ef4444;
}
.race-card-hero[data-race-status="done"] {
  border-color: #4ade80;
}
/* Wave 2.7.13: strip ALL chrome from the inner .live-current-heat
   section when nested in the mobile hero. base.css gives that section
   padding, margin, and border for standalone use (desktop bracket_live
   and category overview), but inside the hero card the outer
   .race-card-hero already carries border / background / padding —
   the inner section should be a transparent passthrough. Without this,
   active hero was visibly taller than done hero (margin-bottom: 1rem
   from base.css plus residual padding leaked ~32px of extra height).
   This rule supersedes the partial Wave 2.7.7 (border-color transparent
   only) and Wave 2.7.10 (margin-top + partial padding only) overrides. */
.race-card-hero .live-current-heat {
  padding: 0;
  margin: 0;
  border: none;
  background: transparent;
  box-shadow: none;
}
/* Wave 2.7.9: pulsing red dot in the hero header right side, replacing
   the "Live" text we dropped in 2.7.8. The inner .live-current-heat dot
   is hidden when this is shown (suppress duplicate). */
.race-hero-live-dot {
  display: inline-block;   /* funguje i mimo flex (bracket status span) */
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #ef4444;
  flex-shrink: 0;
  animation: live-pulse 1.5s ease-in-out infinite;
}
.race-card-hero[data-race-status="active"] .live-current-heat .live-status-dot {
  display: none;
}
/* Wave 2.7.10: hero header lays out as label + (gate bar) + (dot or status)
   on a single row. Wave 2.7.11: gates sit immediately to the right of the
   label (not pushed to the right edge). The pulsing dot is then pushed to
   the right edge via margin-left: auto on .race-hero-live-dot, and the
   non-active status text uses justify-content: space-between as a fallback. */
.race-hero-header {
  display: flex;
  justify-content: space-between;
  align-items: center;       /* was baseline — center fits dot + gate cells */
  gap: 0.5rem;
  margin-bottom: 0.6rem;
}
.race-hero-header .live-gates {
  flex: 0 0 auto;            /* sit right after label, no growing */
}
.race-hero-live-dot {
  margin-left: auto;         /* push to the far right of the row */
}
/* Wave 2.7.10/12 padding + margin override removed: superseded by the
   Wave 2.7.13 comprehensive .race-card-hero .live-current-heat reset
   above (padding: 0; margin: 0; border: none; background: transparent).
   The .live-status-pill column alignment that 2.7.10 cared about is
   now achieved by the inner section having zero horizontal padding. */
.race-hero-label {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--c-f1f5f9);
}
.race-hero-status { font-size: 0.85rem; font-weight: 600; }
.race-hero-status.race-status-active { color: #38bdf8; }
.race-hero-status.race-status-done { color: #4ade80; }
.race-hero-status.race-status-pending { color: var(--c-94a3b8); }

.race-hero-athletes {
  list-style: none;
  margin: 0; padding: 0;
}
/* Wave 2.7.12: unified hero athlete row layout. Active state renders
   via _live_current_heat.html partial as <li class="live-athlete">;
   done state renders directly as <li class="race-hero-athlete">. Both
   share the same padding, border-bottom, and font-size so the hero
   card visuals are consistent regardless of state. The 3-class
   .race-card-hero .live-current-heat .live-athlete selector outranks
   the 2-class .live-current-heat .live-athlete rule in base.css, so
   this override is mobile-only — desktop bracket_live keeps its
   original layout. Last child has no border for a clean visual end. */
.race-hero-athlete,
.race-card-hero .live-current-heat .live-athlete {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--c-334155);
  font-size: 0.95rem;
}
.race-hero-athlete:last-child,
.race-card-hero .live-current-heat .live-athlete:last-child {
  border-bottom: none;
}
/* Suppress the inter-row gap from base.css when inside the hero —
   row dividers are now the visual separator, gap is redundant. */
.race-card-hero .live-current-heat .live-athletes {
  gap: 0;
  padding: 0;
}
.race-hero-athlete .athlete-pos {
  display: inline-block;
  width: 1.5rem;
  font-weight: 700;
  color: #38bdf8;
}
.race-hero-athlete .athlete-name { flex: 1; min-width: 0; }
.race-hero-athlete .athlete-flt {
  background: #b91c1c;
  color: white;
  padding: 0.1rem 0.45rem;
  border-radius: 4px;
  font-size: 0.75rem;
}
.race-hero-athlete .athlete-tt {
  font-size: 0.75rem;
  color: var(--c-94a3b8);
}
.race-hero-athlete.athlete-status-dns,
.race-hero-athlete.athlete-status-dnf,
.race-hero-athlete.athlete-status-ral,
.race-hero-athlete.athlete-status-dsq,
.race-hero-athlete.athlete-status-dqb { opacity: 0.55; }
/* Wave 2.7.11: junior italic dropped (see .race-card-athlete note above). */

.race-hero-empty,
.race-hero-empty-row {
  text-align: center;
  padding: 2rem 1rem;
  color: var(--c-94a3b8);
}
.race-hero-empty-row { padding: 1rem; font-size: 0.9rem; }
.race-hero-empty .race-hero-next-hint {
  margin-top: 1rem;
  font-size: 0.9rem;
}

.race-card-empty {
  text-align: center;
  padding: 1.25rem 1rem;
  color: #64748b;
  font-size: 0.85rem;
  background: var(--c-1e293b);
  border-radius: 8px;
}

/* ─────────────────────────────────────────────────────────────────────
   Bottom dock
   ───────────────────────────────────────────────────────────────────── */

.site-dock {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: var(--c-1e293b);
  border-top: 1px solid var(--c-334155);
  display: flex;
  z-index: 99;
  padding-bottom: env(safe-area-inset-bottom, 0);
}
/* Tlačítka přizpůsobená šířce tabulky: max-width 900px (jako .site-main),
   centrovaná; band .site-dock zůstává full-width. Na užším viewportu (< 900)
   width:100% → tlačítka přes celou šířku jako dřív. */
.dock-inner {
  display: flex;
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
}
.dock-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0.85rem 0;
  background: transparent;
  color: var(--c-94a3b8);
  text-decoration: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
  min-height: 56px;
}
.dock-btn-active { color: #38bdf8; }
/* Live = živý přenos: ikona zčervená a halo prstenec pulzuje jako „radar
   ping" JEN když právě běží výsledky — třídu .dock-live-on nastavuje
   dock_live.js podle event.json.live_now. Bez ní Live drží normální barvu
   docku (šedá / aktivní modrá), prstenec je statický (opacity z SVG). */
.dock-btn[data-target="live"].dock-live-on { color: #ef4444; }
.dock-btn[data-target="live"].dock-live-on.dock-btn-active { color: #f87171; }
.dock-btn[data-target="live"].dock-live-on .dock-live-halo {
  transform-box: fill-box;
  transform-origin: center;
  animation: dock-live-ping 1.8s ease-out infinite;
}
@keyframes dock-live-ping {
  0%   { transform: scale(0.55); opacity: 0.7; }
  70%  { transform: scale(1.7);  opacity: 0; }
  100% { transform: scale(1.7);  opacity: 0; }
}
/* Respekt k uživatelům s omezeným pohybem — bez pingu, jen statický prstenec. */
@media (prefers-reduced-motion: reduce) {
  .dock-btn[data-target="live"].dock-live-on .dock-live-halo { animation: none; opacity: 0.5; }
}
.dock-btn[aria-disabled="true"] { opacity: 0.4; pointer-events: none; }
.dock-btn:active { background: var(--c-334155); }
/* Vlna 2 fáze B (B.2): inline SVG ikony, text popisky dropnuty. Velikost
   24×24 sedí na 56px dock-btn s vertikálním paddingem 0.85rem. */
.dock-icon-svg {
  width: 24px;
  height: 24px;
  display: block;
  stroke: currentColor;
}

/* ─────────────────────────────────────────────────────────────────────
   More menu (bottom sheet)
   ───────────────────────────────────────────────────────────────────── */

.more-menu-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 200;
  opacity: 0;
  transition: opacity 0.2s;
}
body.more-menu-open .more-menu-overlay {
  opacity: 1;
}

.more-menu {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: var(--c-1e293b);
  border-radius: 16px 16px 0 0;
  z-index: 201;
  transform: translateY(100%);
  transition: transform 0.25s ease-out;
  padding-bottom: env(safe-area-inset-bottom, 0);
}
body.more-menu-open .more-menu {
  transform: translateY(0);
}
.more-menu-handle {
  width: 32px;
  height: 4px;
  background: var(--c-475569);
  border-radius: 2px;
  margin: 0.6rem auto;
}
.more-menu-content { padding: 0.5rem 0; }
.more-menu-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.85rem 1.25rem;
  color: var(--c-f1f5f9);
  text-decoration: none;
  font-size: 1rem;
}
.more-menu-item:active { background: var(--c-334155); }
.more-menu-icon {
  font-size: 1.25rem;
  width: 1.5em;
  text-align: center;
}
.more-menu-sep {
  margin: 0.5rem 1.25rem;
  border: none;
  border-top: 1px solid var(--c-334155);
}

/* ─────────────────────────────────────────────────────────────────────
   Athlete detail modal (long press)
   ───────────────────────────────────────────────────────────────────── */

.athlete-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.6);
  z-index: 300;
  animation: fade-in 0.2s ease-out;
}
.athlete-modal {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: var(--c-1e293b);
  border-radius: 16px 16px 0 0;
  padding: 0.5rem 1.25rem 2rem;
  z-index: 301;
  animation: slide-up 0.25s ease-out;
  padding-bottom: calc(2rem + env(safe-area-inset-bottom, 0));
}
.athlete-modal-handle {
  width: 32px;
  height: 4px;
  background: var(--c-475569);
  border-radius: 2px;
  margin: 0.5rem auto 1rem;
}
.athlete-modal h3 {
  margin: 0 0 0.85rem;
  font-size: 1.15rem;
  color: var(--c-f1f5f9);
}
.athlete-modal-meta {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.5rem 1rem;
  font-size: 0.95rem;
  margin: 0;
}
.athlete-modal-meta dt { color: var(--c-94a3b8); font-weight: 500; }
.athlete-modal-meta dd { margin: 0; color: var(--c-f1f5f9); }
.athlete-modal-note {
  color: var(--c-94a3b8);
  font-size: 0.9rem;
  font-style: italic;
}
@keyframes slide-up {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ─────────────────────────────────────────────────────────────────────
   Wave 2.7.3: bracket mobile + TT mobile
   ───────────────────────────────────────────────────────────────────── */

/* Sub-header (kategorie + dropdown) — sdíleno bracket + TT */
.bracket-subheader, .tt-subheader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.6rem 0.75rem 0.4rem;
  background: var(--c-0f172a);
  border-bottom: 1px solid var(--c-1e293b);
}
.bracket-cat-title, .tt-cat-title {
  margin: 0;
  font-size: 1rem;
  color: var(--c-f1f5f9);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bracket-cat-switcher, .tt-cat-switcher { position: relative; flex-shrink: 0; }
.cat-switch-btn {
  background: var(--c-1e293b);
  color: var(--c-f1f5f9);
  border: 1px solid var(--c-334155);
  padding: 0.35rem 0.7rem;
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}
.cat-switch-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  background: var(--c-1e293b);
  border: 1px solid var(--c-334155);
  border-radius: 8px;
  list-style: none;
  margin: 0;
  padding: 0.25rem 0;
  min-width: 200px;
  max-width: calc(100vw - 1.5rem);
  z-index: 50;
  box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.cat-switch-menu li { margin: 0; padding: 0; }
.cat-switch-item {
  display: block;
  padding: 0.6rem 1rem;
  color: var(--c-f1f5f9);
  text-decoration: none;
  font-size: 0.9rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cat-switch-item.active { color: #38bdf8; font-weight: 600; }
.cat-switch-item:active { background: var(--c-334155); }

/* Phase strip (sticky tab bar) */
.phase-strip {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  position: sticky;
  top: 48px;
  z-index: 90;
  background: var(--c-1e293b);
  border-bottom: 1px solid var(--c-334155);
  /* celý strip (pozadí + spodní linka) na šířku karet rozjížděk — margin
     (ne padding), aby barevný pruh nebyl širší než karty. .bracket-races má
     padding 0.5rem, takže margin 0.5rem srovná okraje. */
  margin: 0 0.5rem;
}
.phase-tab {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  padding: 0.6rem 0.25rem;
  color: var(--c-94a3b8);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.85rem;
  border-bottom: 2px solid transparent;
}
/* Globální a:hover podtrhává — u tlačítek fáze ho potlačíme i v hover/focus
   (text-decoration:none v base stavu sám hover/focus nepokryje). */
.phase-tab:hover,
.phase-tab:focus { text-decoration: none; }
.phase-tab-current {
  color: #38bdf8;
  border-bottom-color: #38bdf8;
}
.phase-tab-done { color: #4ade80; }
.phase-tab-current.phase-tab-done {
  color: #4ade80;
  border-bottom-color: #4ade80;
}
.phase-tab-dot {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #38bdf8;
  animation: live-pulse 1.5s ease-in-out infinite;
}
.phase-tab-short { line-height: 1; }

/* Bracket race cards */
.bracket-races {
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.bracket-race-card {
  background: var(--c-1e293b);
  border-radius: 8px;
  /* Barevné orámování podle stavu — stejná konvence jako karty Live
     (active=červená, done=zelená, pending=modrá). box-sizing: border-box,
     padding kompenzuje 1px border, aby obsah nedrkal. */
  border: 1px solid #38bdf8; /* default = pending (modrá), tenká čára */
  padding: calc(0.65rem - 1px) calc(0.75rem - 1px);
}
/* Běžící jízda zvýrazněna červeně — tenký rámeček + pulzující červený glow,
   aby okamžitě upoutala (auto-refresh ji překreslí po dojetí). */
.bracket-race-card.status-active {
  border-color: #ef4444;
  animation: bracket-active-pulse 1.6s ease-in-out infinite;
}
@keyframes bracket-active-pulse {
  0%, 100% { box-shadow: 0 0 0 1px #ef4444, 0 0 5px rgba(239, 68, 68, 0.30); }
  50%      { box-shadow: 0 0 0 1px #ef4444, 0 0 12px rgba(239, 68, 68, 0.60); }
}
.bracket-race-card.status-done   { border-color: #4ade80; } /* zelená */
/* Živý blok běžící jízdy nemá mít vlastní (vnitřní) rámeček — barevný rámeček
   nese jen vnější karta podle stavu. Strhneme chrome jako u Live hero. */
.bracket-race-card .live-current-heat {
  border: none;
  background: transparent;
  padding: 0;
  margin: 0;
  box-shadow: none;
}
.bracket-race-header {
  display: flex;
  justify-content: space-between;
  align-items: center;          /* vycentruje název + gate bar + status/puntík */
  gap: 0.5rem;
  margin-bottom: 0.4rem;
  font-size: 0.9rem;
}
.bracket-race-name { font-weight: 600; color: var(--c-f1f5f9); flex-shrink: 0; }
/* Běžící jízda: gate bar sedí hned za názvem, status/puntík vpravo (jako hero). */
.bracket-race-header .live-gates { margin-right: auto; }
.bracket-race-status { font-size: 0.78rem; color: var(--c-94a3b8); }
.bracket-race-card.status-active .bracket-race-status {
  color: #38bdf8;
  font-weight: 600;
}
.bracket-race-card.status-done .bracket-race-status { color: #4ade80; }
.bracket-race-athletes {
  list-style: none;
  margin: 0;
  padding: 0;
}
.bracket-race-athlete {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.32rem 0;
  font-size: 0.88rem;
  border-bottom: 1px solid var(--c-334155);
}
.bracket-race-athlete:last-child { border-bottom: none; }
.bracket-race-athlete .athlete-pos {
  display: inline-block;
  width: 1.5rem;
  font-weight: 700;
  color: #38bdf8;
  flex-shrink: 0;
}
.bracket-race-athlete .athlete-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--c-cbd5e1);
}
.bracket-race-athlete .athlete-flt {
  background: #b91c1c;
  color: white;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  font-size: 0.7rem;
  flex-shrink: 0;
}
.bracket-race-athlete.status-dns,
.bracket-race-athlete.status-dnf,
.bracket-race-athlete.status-ral,
.bracket-race-athlete.status-dsq,
.bracket-race-athlete.status-dqb { opacity: 0.55; }
/* Wave 2.7.11: junior italic dropped from the bracket card too. */

.bracket-empty {
  padding: 2.5rem 1rem;
  text-align: center;
  color: var(--c-94a3b8);
}

/* TT mobile rows */
.tt-mobile { padding: 0; }
.tt-section-title {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--c-94a3b8);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.6rem 0.75rem 0.3rem;
  margin: 0;
  background: var(--c-0f172a);
  position: sticky;
  top: 48px;
  z-index: 50;
}
.tt-on-course {
  background: var(--c-0c1a2e);
  border-bottom: 2px solid #38bdf8;
}
.tt-on-course .tt-section-title {
  color: #38bdf8;
  background: var(--c-0c1a2e);
}
.tt-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}
.tt-row {
  display: grid;
  grid-template-columns: 2.5rem 1fr auto 2.5rem;
  gap: 0.5rem;
  /* Vertikální zarovnání: center, NE baseline. Řádek míchá různé velikosti
     písma (běžící hodiny 1.05rem vs STČ 0.85rem) a badge s vlastním
     paddingem (FLT) — baseline pak sráží text k horní hraně řádku a posun
     kolísá řádek od řádku (nejvíc u live řádku v Pořadí, kde FLT badge má
     border). center drží text opticky uprostřed nezávisle na obsahu. */
  align-items: center;
  padding: 0.3rem 0.75rem;
  border-bottom: 1px solid var(--c-1e293b);
  font-size: 0.92rem;
}
.tt-row-on-course .tt-row-stc,
.tt-row-ranking .tt-row-rank,
.tt-row-ranking .tt-row-stc {
  color: var(--c-94a3b8);
  font-weight: 600;
  font-size: 0.85rem;
}
.tt-row-ranking {
  /* Vlna 1 fáze A: 6 slotů — rank | stc | name | time | diff | flt.
     Pevné šířky Čas/Rozdíl (sjednoceno s base.css) — auto by zlomilo
     sloupcové zarovnání desetinných teček mezi řádky. */
  grid-template-columns: 2.5rem 2.5rem 1fr 4.5rem 3.5rem 2.5rem;
}
.tt-row-startlist {
  grid-template-columns: 2.5rem 1fr auto;
}
.tt-row-startlist .tt-row-time {
  text-align: right;
}
.tt-row-name {
  font-weight: 500;
  color: var(--c-f1f5f9);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tt-row-time {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--c-cbd5e1);
}
.tt-row-on-course .tt-row-time { color: #38bdf8; }
/* Vlna 3 (C.1, K3): viz base.css — žluté plné pozadí, černá číslice,
   inline-flex centering + line-height:1 + symetric padding (fix
   asymetrického místa kolem číslice v default line-boxu 1.4). */
.tt-row-flt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  background: var(--c-facc15);
  color: var(--c-0a0a0a);
  padding: 0.2rem 0.4rem;
  border-radius: 4px;
  font-size: 0.72rem;
  font-weight: 700;
  white-space: nowrap;
}
.tt-row-flt-empty {
  color: var(--c-475569);
  text-align: center;
  font-size: 0.85rem;
}
.tt-row.status-dnf, .tt-row.status-dns, .tt-row.status-ral,
.tt-row.status-dsq, .tt-row.status-dqb { opacity: 0.55; }
.tt-row.status-dnf .tt-row-time,
.tt-row.status-dns .tt-row-time,
.tt-row.status-ral .tt-row-time,
.tt-row.status-dsq .tt-row-time,
.tt-row.status-dqb .tt-row-time { color: #f87171; }
.tt-empty {
  padding: 1.5rem 1rem;
  text-align: center;
  color: #64748b;
}

/* ─────────────────────────────────────────────────────────────────────
   Wave 2.7.19: latest finisher highlight in mobile ranking — mirrors
   desktop Wave 2.4.11 (.dump-table tbody tr[data-latest-finisher='1']).
   Persistent green tint + 4px-equivalent left accent (3px on mobile,
   proportional to narrower viewport) + 2s pulse on 0→1 transition.
   ───────────────────────────────────────────────────────────────────── */

.tt-row-ranking[data-latest-finisher="1"] {
  background-color: rgba(34, 197, 94, 0.18);
  box-shadow: inset 3px 0 0 #22c55e;
  transition: background-color 0.5s ease-out;
}

@keyframes latest-finisher-pulse-mobile {
  0%   { background-color: rgba(34, 197, 94, 0.55); }
  50%  { background-color: rgba(34, 197, 94, 0.35); }
  100% { background-color: rgba(34, 197, 94, 0.18); }
}

.tt-row-ranking.latest-finisher-pulse {
  animation: latest-finisher-pulse-mobile 2s ease-out;
}

/* Defensive: latest-finisher cannot be DNF/DNS/RAL by server logic
   (server only flags rows with finish_time), but if data shape ever
   changes keep the disqualified red coloring visually dominant. */
.tt-row-ranking.status-dnf[data-latest-finisher="1"],
.tt-row-ranking.status-ral[data-latest-finisher="1"],
.tt-row-ranking.status-dns[data-latest-finisher="1"],
.tt-row-ranking.status-dsq[data-latest-finisher="1"],
.tt-row-ranking.status-dqb[data-latest-finisher="1"] {
  background-color: rgba(239, 68, 68, 0.12);
  box-shadow: inset 3px 0 0 #ef4444;
}

/* ─────────────────────────────────────────────────────────────────────
   Wave 2.7.17: mobile NA TRATI scoreboard look — sjednoceno s desktop
   Wave 2.7.16. Stejná paleta (var(--c-facc15) na var(--c-0a0a0a)), modern monospace
   stack, glow effect na running clocku. Scaled-down padding/font pro
   mobile viewport. ID-scoped (1,0,0) — beats existing .tt-on-course
   class rules (0,1,0) bez !important. Pre-Wave-2.7.17 tu byla sky-blue
   paleta (var(--c-0c1a2e) bg + #38bdf8 border + #38bdf8 clock); FLT badges
   byly red (#b91c1c) — všechno teď unified yellow.
   Scope: jen #tt-on-course (mobile POŘADÍ + race-strip beze změny;
   .tt-row grid layout zachován — overridujeme jen colors/font/border).
   ───────────────────────────────────────────────────────────────────── */

#tt-on-course {
  background: var(--c-0a0a0a);
  border: 2px solid var(--c-facc15);
  border-radius: 8px;
  padding: 0.5rem;
  margin-bottom: 1rem;
  /* Vlna 2 fáze B (B.1): scoreboard zafixován pod sticky .site-header.
     Header drží banner + pás kategorií nahoře (site-header je sticky
     top:0 z Wave 2.7.x — neměníme ho), scoreboard sticky-uje s offsetem
     = reálná výška headeru. CSS proměnnou --mobile-header-h publikuje
     tt_sticky.js (ResizeObserver na .site-header). Fallback 132px
     kryje obvyklou výšku TT live headeru (banner 64 + cat-tabs ~44 +
     padding ~16 + gap ~6 + border 1).
     z-index: 50 — pod header (z-index 100), nad běžný obsah; při
     teoretickém vizuálním překryvu header vyhrává a yellow border
     scoreboardu neprosvítá.
     Stuck-state stín jen směrem dolů (negative spread + offset),
     dekorativně odděluje sticky chrome od scrollujícího pořadí. */
  position: sticky;
  top: var(--mobile-header-h, 132px);
  z-index: 50;
  box-shadow: 0 6px 12px -4px rgba(0, 0, 0, 0.65);
}

/* #tt-on-course[hidden] (= on_course prázdné) zruší display:block →
   display:none. Sticky se nemá kde projevit, žádná kolize. Pojistka
   pro jistotu, kdyby budoucí CSS reset hidden override: */
#tt-on-course[hidden] { display: none; }

/* Wave 2.7.18: #tt-on-course .tt-section-title rule removed — the
   <h3> element itself is gone (dropped in tt_mobile.html). */

/* Optická korekce: obsah o ~1px níž. align-items: center vystředí BOXY,
   jenže ink písma sedí v line-boxu výš — pod účařím je vyhrazené místo pro
   dolní dotažnice, které STČ/jméno/hodiny nemají. Text pak opticky visí
   u horní hrany černého panelu (měřeno po pixelech: 5,3 px nad inkem vs
   7,4 px pod ním). Padding 0.36rem nahoře / 0.24rem dole — součet zůstává
   0.6rem, výška řádku se nemění. */
#tt-on-course .tt-row {
  background: transparent;
  color: var(--c-facc15);
  font-family: ui-monospace, "SF Mono", Monaco, "Cascadia Code",
               "Roboto Mono", Consolas, "Liberation Mono",
               "Courier New", monospace;
  font-weight: 700;
  border-bottom: 1px dashed rgba(250, 204, 21, 0.2);
  padding: 0.36rem 0.25rem 0.24rem;
}

#tt-on-course .tt-row:last-child {
  border-bottom: none;
}

#tt-on-course .tt-row-stc {
  color: var(--c-fde047);
  font-weight: 700;
  font-size: 0.85rem;
}

#tt-on-course .tt-row-name {
  color: var(--c-facc15);
  font-weight: 700;
}

/* Running clock — focal point: bigger, glow, tabular-nums. */
#tt-on-course .tt-row-on-course .tt-row-time {
  color: var(--c-facc15);
  font-size: 1.05rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
  text-shadow: 0 0 5px rgba(250, 204, 21, 0.4);
  white-space: nowrap;
}

/* Vlna 3 (C.1, K3): scoreboard FLT badge — sjednocený s globálním
   .tt-row-flt (žluté plné pozadí, černá číslice, inline-flex centering
   dědí). Dřív transparentní s žlutým borderem. Padding přepisujeme
   pro scoreboard font-size (0.78rem) a větší font-weight. */
#tt-on-course .tt-row-flt {
  background: var(--c-facc15);
  color: var(--c-0a0a0a);
  padding: 0.2rem 0.4rem;
  border-radius: 3px;
  font-size: 0.78rem;
  font-weight: 800;
}

#tt-on-course .tt-row-flt-empty {
  color: #78716c;
  font-size: 0.78rem;
}

/* ─────────────────────────────────────────────────────────────────────
   Wave 2.7.5: tap target floor (Apple HIG ≥44×44px)
   Visual size unchanged where possible — padding/min-height expands the
   tap zone without changing layout flow.
   ───────────────────────────────────────────────────────────────────── */

.cat-switch-btn {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

.cat-switch-item {
  /* Wave 2.7.20: revert display from flex back to block. Wave 2.7.5
     set flex+align-items:center for the 44×44px tap target, but the
     <a class="cat-switch-item"> contains multi-line whitespace from
     Jinja loop indentation — flex layout treats whitespace text
     nodes as flex items, and the first item's real text rendered
     invisibly. Block + min-height + padding + line-height satisfies
     the 44px tap target without the flex whitespace quirk. The
     base rule at line ~597 already sets display: block; this
     override now keeps it block while bumping the tap zone.
     Tap math: padding 0.7rem (×2 ≈ 22px) + 0.9rem text × line-height
     1.6 ≈ 22px → ≈ 66px ≥ 44px ✓ */
  display: block;
  min-height: 44px;
  padding: 0.7rem 1rem;
  line-height: 1.6;
}

.phase-tab {
  min-height: 44px;
  /* phase-tab is already display:flex with align-items:center — just floor it */
}

/* dock-btn already ~56px (icon + label rows). live-badge stays 36px (informational). */

/* ─────────────────────────────────────────────────────────────────────
   Wave 2.7.5: athlete modal close button
   ───────────────────────────────────────────────────────────────────── */

.athlete-modal { position: fixed; }  /* re-affirm; existing rule already sets this */
.athlete-modal-close {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  background: transparent;
  border: none;
  color: var(--c-94a3b8);
  font-size: 1.6rem;
  line-height: 1;
  width: 44px;
  height: 44px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  border-radius: 50%;
}
.athlete-modal-close:hover { color: var(--c-f1f5f9); }
.athlete-modal-close:active { background: rgba(255, 255, 255, 0.08); }

/* ─────────────────────────────────────────────────────────────────────
   Wave 2.7.5: connection status badge (mobile — slot in site-header)
   ───────────────────────────────────────────────────────────────────── */

.connection-status {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: auto;
  margin-right: 0.5rem;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  background: var(--c-1e293b);
  color: var(--c-f1f5f9);
  white-space: nowrap;
  transition: opacity 0.3s, background 0.2s;
}
.connection-status[hidden] { display: none; }
.connection-status .connection-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #4ade80;
}
.connection-status-stale {
  background: #78350f;
  color: #fed7aa;
}
.connection-status-stale .connection-dot {
  background: #fb923c;
  animation: live-pulse 1.5s ease-in-out infinite;
}
.connection-status-offline {
  background: #7f1d1d;
  color: #fee2e2;
}
.connection-status-offline .connection-dot {
  background: #ef4444;
}
.connection-status-recovered {
  background: #14532d;
  color: #d1fae5;
}
.connection-status-recovered .connection-dot {
  background: #4ade80;
}

/* ─────────────────────────────────────────────────────────────────────
   Wave 2.7.11: lane-dot + BIB shared between hero (done state) and
   compact race cards. Selectors target the dot directly via
   .lane-dot.lane-{color} so they do not collide with the existing
   .live-current-heat .lane-{color} .lane-dot rules in base.css (those
   put the lane class on the parent <li>, this puts it on the dot).
   ───────────────────────────────────────────────────────────────────── */

.race-hero-athletes .lane-dot,
.race-card-athletes .lane-dot,
.bracket-race-athletes .lane-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.lane-dot.lane-red    { background: #ef4444; }
.lane-dot.lane-green  { background: #22c55e; }
.lane-dot.lane-blue   { background: #3b82f6; }
.lane-dot.lane-yellow { background: #eab308; }
.lane-dot.lane-gray   { background: #6b7280; } /* fallback when bib_color missing */

.race-hero-athlete .athlete-bib,
.race-card-athlete .athlete-bib,
.bracket-race-athlete .athlete-bib {
  font-family: ui-monospace, "Courier New", monospace;
  font-size: 0.78rem;
  color: var(--c-94a3b8);
  font-variant-numeric: tabular-nums;
  min-width: 1.4rem;
  text-align: right;
}

/* ─────────────────────────────────────────────────────────────────────
   Site footer — jen landing page (© results.cz <rok> | ver. X.YY)
   ───────────────────────────────────────────────────────────────────── */
.site-footer {
  padding: 1.5rem 1rem 1rem;
  text-align: center;
  font-size: 0.78rem;
  color: var(--c-94a3b8);
}


/* ── Publikované PDF dokumenty (SL/VL/TT) — Wave PDF docs ── */
/* Ikony dokumentů zarovnané zleva (řádky začínají na stejném místě a plní se
   doprava); první chip flush s hlavičkou „Dokumenty". */
.col-docs { width: 1%; white-space: nowrap; text-align: left; }
.col-docs .doc-chip:first-child { margin-left: 0; }
.doc-chip {
  display: inline-block; padding: 2px 9px; margin-left: 4px;
  border: 1px solid var(--card-border); border-radius: 99px;
  font-size: 11px; font-weight: 700; letter-spacing: .4px;
  color: var(--muted); line-height: 1.5;
  background: var(--card-bg);
}
.doc-chip:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }
/* chip v pásu kategorií (startovka/tt/pavouk) — drží se vpravo za taby.
   margin-right 0: poslední chip na pravém okraji obsahu pásu = svisle pod
   ikonou režim (theme-toggle) v hlavičce. */
.doc-chip--tabs { flex: 0 0 auto; margin-left: 8px; margin-right: 0; }

.doc-chip--mid { margin-right: 0; }

.doc-chip { display: inline-flex; align-items: center; justify-content: center; padding: 3px 7px; }
.doc-chip-ico { width: 15px; height: 15px; display: block; }
/* Fázový odznak (Σ/A/B/K/1/2) na tlačítkách přepínače POHLEDU — drží stejnou
   výšku jako ikonové chipy (15px box). Odkazy na PDF nesou vždy jen ikonu. */
.doc-chip--phase { min-width: 15px; }
.doc-chip-lbl {
  display: block; min-width: 13px; height: 15px; line-height: 15px;
  text-align: center; font-size: 12px; font-weight: 700; letter-spacing: .2px;
}

/* Segmentovaná skupina PDF odkazů (SL/VL fáze) v pásu kategorií — kompaktní
   „přepínač" ve stejném vizuálním jazyce jako segment-control kategorií
   (.tt-cat-tabs) a přepínač jízd v KXRS. Jednotlivé chipy (.doc-chip--tabs, jen
   v tomto pásu) splývají do jedné pilulky oddělené svislítkem; skupina nese
   rámeček i zaoblení. Šetří šířku → vejde se vedle tabů kategorií i na mobilu. */
.tt-doc-switch {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: stretch;
  margin-left: 8px;
  border: 1px solid var(--c-334155);
  border-radius: 6px;
  overflow: hidden;
}
.tt-doc-switch .doc-chip--tabs {
  margin: 0;
  min-height: 30px;
  border: none;
  border-radius: 0;
  background: transparent;
  color: var(--c-cbd5e1);
}
.tt-doc-switch .doc-chip--tabs + .doc-chip--tabs {
  border-left: 1px solid var(--c-334155);
}
.tt-doc-switch .doc-chip--tabs:hover {
  background: rgba(255, 255, 255, 0.08);
  color: var(--c-f1f5f9);
  border-color: var(--c-334155);   /* neztrácej svislítko při hoveru */
}
.tt-doc-switch .doc-chip-ico { color: var(--c-cbd5e1); }

/* Fázový přepínač POHLEDU (Σ/A/B/K) — stejná pilulka jako PDF chipy, ale
   tlačítka místo odkazů: přepínají renderovanou listinu/tabulku na stránce.
   Vybraná fáze je zvýrazněná jako aktivní segment (obdoba .tt-cat-tab.active).
   PDF právě zobrazené fáze je vedle jako samostatná ikona (.tt-phase-pdf). */
.tt-phase-switch .phase-view-btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 3px 8px; cursor: pointer; font: inherit;
}
.tt-phase-switch .phase-view-btn.is-active {
  background: var(--c-334155);
  color: var(--c-f1f5f9);
}
.tt-phase-switch .phase-view-btn.is-active:hover { background: var(--c-334155); }
/* Tisk PDF je poslední segment téže pilulky (jedna řada s výběrem fáze) —
   oddělený svislítkem jako ostatní segmenty. Obal <span> nese [hidden], když
   zobrazená fáze nemá publikované PDF. */
.tt-phase-switch .tt-phase-pdf {
  display: inline-flex;
  align-items: stretch;
  border-left: 1px solid var(--c-334155);
}
.tt-phase-switch .tt-phase-pdf[hidden] { display: none; }
/* Fázový přepínač drží pravý okraj pásu (co nejdál vpravo) — na mobilu se tím
   odlepí od tabů kategorií, na desktopu lícuje s pravým okrajem hlavičky. */
.tt-phase-switch { margin-left: auto; }
/* [hidden] samo nestačí — .tt-doc-switch má explicitní display (inline-flex),
   který by ho přebil. Fáze bez publikovaného PDF tak ikonu opravdu skryje. */
.tt-doc-switch[hidden] { display: none; }

/* odkaz na propozice závodu v hlavičce — ikona */
.site-propositions {
  display: inline-flex; align-items: center; justify-content: center;
  margin-left: 0.5rem; flex-shrink: 0; text-decoration: none;
  width: 30px; height: 30px; border-radius: 50%;
  color: var(--accent, #0a9fb4); border: 1px solid currentColor;
}
.site-propositions svg { width: 17px; height: 17px; }
.site-propositions:hover { background: var(--accent, #0a9fb4); color: #fff; }
/* mobilní karta — řádek s doc ikonami */
.event-mobile-card-docs { grid-column: 1 / -1; display: flex; gap: 0.45rem; margin-top: 0.4rem; }
a.event-mobile-card-name { color: inherit; text-decoration: none; }

/* ===== Shluk ovládacích prvků hlavičky (hustota / motiv / jazyk) =====
   Tři přepínače drží pohromadě u pravého okraje s minimální mezerou — vodorovně
   zabírají co nejmíň, aby zbylo místo na název závodu. Zužujeme jen ŠÍŘKY
   (ikony 28px místo 38px, užší pilulka jazyka, gap 2px); výšku tap-targetu
   držíme na 38px (a11y) — svisle stejně nic nekrade. */
.header-tools {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  /* landing (bez event-line s flex:1) — odtlač shluk k pravému okraji */
  margin-left: auto;
}

/* ===== Přepínač světlý/tmavý motiv ===== */
.theme-toggle {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 38px; padding: 0;
  background: transparent; border: none; cursor: pointer;
  color: var(--c-94a3b8);
}
.theme-toggle:hover { color: var(--c-f1f5f9); }
.theme-toggle svg { width: 19px; height: 19px; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="light"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="light"] .theme-toggle .icon-moon { display: inline; }

/* Přepínač hustoty řádkování — vícestavová ikona jako v KXRS (tři vodorovné
   čáry, jejichž hustotu JS mění dle režimu). Ikonový button vedle přepínače
   motivu. Klik cykluje Kompaktní → Normální → Vzdušné. */
.density-toggle {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 38px; padding: 0;
  background: transparent; border: none; cursor: pointer;
  color: var(--c-94a3b8);
}
.density-toggle:hover { color: var(--c-f1f5f9); }
.density-toggle svg { width: 19px; height: 19px; }

/* Hustota řádkování — tři úrovně jako v KXRS. „Normální" = základní pravidla
   bez atributu; „compact" zhustí a „airy" rozvolní svislé rozestupy. Cílí
   startovku/TT/pořadí (.tt-row), výsledkové tabulky časových disciplín
   (.time-table) i karty konečných výsledků (.race-card-athlete) na Live.
   Vyšší specificita (:root[...] .selektor) přebíjí i mobilní @media varianty.

   Kromě svislých rozestupů mění režim i velikost písma: kořenové `font-size`
   (base `html { font-size: 16px }`) škáluje všechny rem hodnoty naráz —
   fonty i rem-based šířky gridů/sloupců, takže nic nepřeteče ani neuřízne.
   Vzdušné = větší písmo (čitelné z dálky na plátně/tabuli), kompaktní = menší
   (víc řádků na obrazovku). Media queries se neposouvají — `px`/`em` v MQ se
   počítají z výchozí velikosti dokumentu, ne z této.

   Na mobilu je vzdušný krok menší (17px): výsledková tabulka se tam vejde na
   šířku jen tak tak, plných 18px by ji poslalo do vodorovného scrollu. Zmenšení
   (kompaktní) nic nepřetéká, takže platí na všech šířkách stejně. */
:root[data-density="compact"] { font-size: 13.5px; }
:root[data-density="airy"] { font-size: 17px; }
@media (min-width: 720px) {
  :root[data-density="airy"] { font-size: 18px; }
}

:root[data-density="compact"] .tt-row { padding-top: 0.02rem; padding-bottom: 0.02rem; line-height: 1.25; }
:root[data-density="compact"] .time-table th,
:root[data-density="compact"] .time-table td { padding-top: 0.08rem; padding-bottom: 0.08rem; line-height: 1.25; }
:root[data-density="compact"] .results-card-athletes .race-card-athlete { padding-top: 0; padding-bottom: 0; line-height: 1.3; }
:root[data-density="compact"] .race-card-athletes { row-gap: 0.02rem; }

/* Vzdušné: rem paddingy níž než dřív — větší kořenový font je sám o sobě
   zvedá (0.45rem × 18px ≈ původních 0.55rem × 16px), jinak by řádky narostly
   dvakrát. */
:root[data-density="airy"] .tt-row { padding-top: 0.45rem; padding-bottom: 0.45rem; }
:root[data-density="airy"] .time-table th,
:root[data-density="airy"] .time-table td { padding-top: 0.5rem; padding-bottom: 0.5rem; }
:root[data-density="airy"] .results-card-athletes .race-card-athlete { padding-top: 0.28rem; padding-bottom: 0.28rem; }
:root[data-density="airy"] .race-card-athletes { row-gap: 0.34rem; }

/* Landing (seznam závodů) — hustota platí i tady, jinak by ikona v hlavičce
   měnila jen velikost písma. Desktop tabulka i mobilní karty; pravidla jsou
   mimo @media, ale skrytá varianta se stejně nevykresluje (display:none).
   Specifičnost (0,2,1) přebíjí základ (0,1,1) bez ohledu na pořadí. */
:root[data-density="compact"] .event-table th,
:root[data-density="compact"] .event-row > td { padding-top: 0.3rem; padding-bottom: 0.3rem; }
:root[data-density="compact"] .event-table .event-tbody + .event-tbody .event-row:first-child > td { padding-top: 0.55rem; }
:root[data-density="compact"] .event-mobile-card { padding: 0.45rem 0.7rem; margin-bottom: 0.35rem; row-gap: 0.1rem; }
:root[data-density="compact"] .event-mobile-card-name { line-height: 1.2; }

:root[data-density="airy"] .event-table th,
:root[data-density="airy"] .event-row > td { padding-top: 0.85rem; padding-bottom: 0.85rem; }
:root[data-density="airy"] .event-table .event-tbody + .event-tbody .event-row:first-child > td { padding-top: 1.3rem; }
:root[data-density="airy"] .event-mobile-card { padding: 1.05rem 1.1rem; margin-bottom: 0.85rem; row-gap: 0.4rem; }

/* Přepínač jazyka CZ | EN — segmentovaná pilulka vedle přepínače motivu.
   Aktivní strana zvýrazněná; klik nastaví cookie a reloadne (kxrsSetLang). */
.lang-toggle {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: stretch;
  /* mezeru od sousedů řeší gap shluku .header-tools */
  margin-left: 0;
  border: 1px solid var(--c-334155);
  border-radius: 6px;
  overflow: hidden;
}
.lang-opt {
  appearance: none;
  border: none;
  background: transparent;
  color: var(--c-94a3b8);
  font-family: inherit;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 0 0.3rem;
  min-height: 38px;          /* zarovnání výšky s .theme-toggle + a11y tap floor */
  cursor: pointer;
  line-height: 1;
}
.lang-opt + .lang-opt { border-left: 1px solid var(--c-334155); }
.lang-opt:hover { color: var(--c-f1f5f9); }
.lang-opt.is-active {
  background: var(--c-334155);
  color: var(--c-f1f5f9);
  cursor: default;
}

/* ===== Světlý režim: scoreboard jedoucího závodníka (TT) =====
   Žlutá výplň + černý text — analogie reálné světelné tabule, vysoká
   viditelnost na světlé stránce. (V tmavém režimu zůstává žlutá na černé.) */
:root[data-theme="light"] #tt-on-course {
  background: #facc15;
  border-color: #ca8a04;
}
:root[data-theme="light"] #tt-on-course .tt-row,
:root[data-theme="light"] #tt-on-course .tt-row-name,
:root[data-theme="light"] #tt-on-course .tt-row-stc,
:root[data-theme="light"] #tt-on-course .tt-row-on-course .tt-row-time {
  color: #0a0a0a;
}
:root[data-theme="light"] #tt-on-course .tt-row {
  border-bottom-color: rgba(10, 10, 10, 0.15);
}
/* FLT odznak na žlutém pozadí: invertovaný (černé pozadí + žlutý text). */
:root[data-theme="light"] #tt-on-course .tt-row-flt {
  background: #0a0a0a;
  color: #facc15;
}
:root[data-theme="light"] #tt-on-course .tt-row-flt-empty {
  color: rgba(10, 10, 10, 0.4);
}

/* Světlý režim: LED scoreboard „na trati" časových disc. — invert jako
   #tt-on-course (žlutý panel + černý text, glow hodin zhasnut). Prázdný
   panel (.is-empty) chrome nemá, takže se ho invert netýká. */
:root[data-theme="light"] .time-live-board:not(.is-empty) {
  background: #facc15;
  border-color: #ca8a04;
}
:root[data-theme="light"] .time-live-board .gm-head,
:root[data-theme="light"] .time-live-board .gm-stc,
:root[data-theme="light"] .time-live-board .gm-name,
:root[data-theme="light"] .time-live-board .gm-clock {
  color: #0a0a0a;
  text-shadow: none;
}
:root[data-theme="light"] .time-live-board .gm-card {
  border-bottom-color: rgba(10, 10, 10, 0.15);
}
/* Světlý režim: projekce jako kros (.tt-row--live light) — žlutý řádek +
   černý text; čára/pilulka zůstávají žluté (chip má černý text). */
:root[data-theme="light"] .time-proj-row > td {
  background: #facc15; color: #0a0a0a;
  border-top-color: #ca8a04; border-bottom-color: #ca8a04;
}
:root[data-theme="light"] .time-proj-row .time-rank,
:root[data-theme="light"] .time-proj-row .time-name,
:root[data-theme="light"] .time-proj-clock { color: #0a0a0a; text-shadow: none; }

/* ===== Světlý režim: propadávající závodník v Pořadí (.tt-row--live) =====
   Stejně jako scoreboard #tt-on-course: žluté pozadí + černý text. */
:root[data-theme="light"] .tt-row.tt-row--live {
  background: #facc15;
  color: #0a0a0a;
  /* Horní hrana 2px — viz tmavý režim (sticky hlavička Pořadí jinak občas
     sežere horní 1px žluté čáry prvního/nejhornějšího živého řádku). */
  box-shadow: inset 0 0 0 1px #ca8a04,
              inset 0 2px 0 0 #ca8a04;
}
:root[data-theme="light"] .tt-row.tt-row--live .tt-row-rank,
:root[data-theme="light"] .tt-row.tt-row--live .tt-row-stc,
:root[data-theme="light"] .tt-row.tt-row--live .tt-row-name,
:root[data-theme="light"] .tt-row.tt-row--live .tt-row-time,
:root[data-theme="light"] .tt-row.tt-row--live .tt-row-diff {
  color: #0a0a0a;
}
:root[data-theme="light"] .tt-row.tt-row--live .tt-row-time {
  text-shadow: none;
}
:root[data-theme="light"] .tt-row.tt-row--live .tt-rank-flt {
  background: #0a0a0a;
  color: #facc15;
  border-color: #0a0a0a;
}

/* ===== Logo ČSK v hlavičce (vlevo před názvem) =====
   Dvě průhledné varianty: barevné (RGB) pro světlý režim, bílé pro tmavý.
   Žádná podložka — každá varianta sedí na svém pozadí. */
.site-logo {
  flex: 0 0 auto;
  display: inline-flex; align-items: center;
  text-decoration: none;
}
/* Výška jen tady (žádný display — ten řídí .site-logo-rgb/.white, jinak by
   .site-logo img display:block přebíjelo skrytí špatné varianty). ~25 % větší. */
.site-logo img { height: 44px; width: auto; }
/* default = tmavý režim → bílé logo; světlý režim → barevné */
.site-logo-rgb { display: none; }
.site-logo-white { display: block; }
:root[data-theme="light"] .site-logo-rgb { display: block; }
:root[data-theme="light"] .site-logo-white { display: none; }

/* ===== Desktop (≥720px): větší logo, větší název, logo zpět z flush ===== */
@media (min-width: 720px) {
  .site-logo img { height: 56px; }
  .site-event-name { font-size: 1.3rem; }
}

/* ===== Světlý režim: scoreboard toggle žlutý (stejně jako v tmavém) =====
   Bez tohoto by zdědil oranžovou z var(--c-facc15). Uživatel chce žlutou v obou. */
:root[data-theme="light"] .tt-live-toggle,
:root[data-theme="light"] .tt-live-toggle[data-mode="full"] { color: #facc15; }
:root[data-theme="light"] .tt-live-toggle:hover,
:root[data-theme="light"] .tt-live-toggle[data-mode="full"]:hover { color: #fde047; }
:root[data-theme="light"] .tt-live-toggle[data-mode="light"] .ic-divider { stroke: #facc15; }


/* ───────────────────────────────────────────────────────────────────
   Landing (home) — fixní výška okna + sbalitelný archiv
   Cíl: hlavička i patička (ver./©) jsou vždy vidět; scrolluje jen
   prostřední oblast se seznamem závodů. Archiv je defaultně sbalený,
   takže Aktivní + Nadcházející padnou na obrazovku i přes dlouhou sezónu.
   ─────────────────────────────────────────────────────────────────── */
body.home-no-dock {
  height: 100vh;
  height: 100dvh;        /* mobil: respektuje pohyblivou lištu prohlížeče */
  overflow: hidden;      /* stránka sama nescrolluje; scrolluje .site-main */
}
body.home-no-dock .site-main {
  flex: 1 1 auto;
  min-height: 0;         /* nutné, aby šel obsah ve flex-column scrollovat */
  overflow-y: auto;      /* scrolluje jen seznam závodů */
  /* přebíjí dřívější min-height: calc(100vh - 48px), které drželo plnou výšku */
}
body.home-no-dock .site-footer {
  flex: 0 0 auto;        /* patička drží výšku, nezmizí pod přehyb */
}

/* ── Sbalitelný archiv (dojeté závody) ── */
.archive-details {
  margin-top: 0.25rem;
}
.archive-summary {
  list-style: none;                 /* skryje výchozí trojúhelník (standard/FF) */
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 1rem;
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  user-select: none;
}
.archive-summary::-webkit-details-marker { display: none; }  /* Safari/Chrome */
.archive-summary:hover { color: var(--c-e2e8f0); }
.archive-caret svg {
  width: 16px; height: 16px; display: block;
  transition: transform 0.15s ease;
}
.archive-details[open] .archive-caret svg { transform: rotate(90deg); }
.archive-count {
  font-variant-numeric: tabular-nums;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 99px;
  padding: 1px 8px;
  font-size: 0.72rem;
  color: var(--muted);
}
/* oddělovač nese summary → archivní tabulka/karty bez vlastního horního okraje */
.archive-details .event-table,
.archive-details .event-cards { margin-top: 0; }

/* Odkaz results.cz v patičce landingu — dědí barvu patičky, ne globální modrou. */
.site-footer-link { color: inherit; text-decoration: none; }
.site-footer-link:hover { color: var(--accent); }
/* „x" v KXRS jako křížek — stejná typografie jako .st-logo-mark .x v hlavní
   aplikaci (znak × obarvený akcentem). */
.site-footer-x { color: var(--accent); }

/* ─────────────────────────────────────────────────────────────────────
   Oddíl (domácí závod) / národnost (mezinárodní) na kartách Live + pavouk.
   Jen desktop (≥720px). Sloupce: jméno (roztáhne se) | oddíl/stát |
   rezervovaný sloupec FLT vpravo. FLT (karty) i stav (live heat) jsou
   absolutně ukotvené k pravému okraji, takže oddíl/stát končí VŽDY na
   stejné pozici bez ohledu na to, jestli řádek FLT má — sloupce jsou tak
   zarovnané napříč řádky. Na mobilu skryto.
   ───────────────────────────────────────────────────────────────────── */
.athlete-org { display: none; }
@media (min-width: 720px) {
  /* Rezervovaný pruh vpravo pro FLT / stav. */
  .race-card-athlete,
  .race-hero-athlete,
  .bracket-race-athlete,
  .live-current-heat .live-athlete {
    position: relative;
    padding-right: 3.4rem;
  }
  /* Hero živý (červeně orámovaný) heat: 3-class pravidlo
     `.race-card-hero .live-current-heat .live-athlete` (Wave 2.7.12,
     padding: 0.55rem 0) má vyšší specificitu než 2-class rezervace výše →
     padding-right spadne na 0 a oddíl (margin-left:auto) i stav/FLT
     (position:absolute; right:0) skončí oba vpravo (kolize). Obnovíme pruh
     stejně specifickým selektorem. */
  .race-card-hero .live-current-heat .live-athlete {
    padding-right: 3.4rem;
  }
  .race-card-athlete .athlete-org,
  .race-hero-athlete .athlete-org,
  .bracket-race-athlete .athlete-org,
  .live-current-heat .athlete-org {
    display: inline-block;
    margin-left: auto;
    padding-left: 0.6rem;
    text-align: right;
    flex-shrink: 0;
    max-width: 45%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--c-94a3b8);
    font-size: 0.82em;
    font-variant-numeric: tabular-nums;
  }
  /* FLT (karty) i stav (live heat) ukotvené do rezervovaného sloupce vpravo. */
  .race-card-athlete .athlete-flt,
  .race-hero-athlete .athlete-flt,
  .bracket-race-athlete .athlete-flt,
  .live-current-heat .athlete-status {
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
  }
}

/* ─────────────────────────────────────────────────────────────────────
   Watermark s názvem stránky (STARTOVNÍ LISTINA / KVALIFIKACE / LIVE /
   VYŘAZOVACÍ JÍZDY / ROZPIS) — svisle podél levého okraje, písmo otočené
   o 180° (čte se zdola nahoru). Neinteraktivní (pointer-events:none),
   klipuje přetečení (žádný horizontální scroll), pod dockem i záhlavím.
   ───────────────────────────────────────────────────────────────────── */
.page-watermark {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 40;            /* pod sticky záhlavím i dockem (99) */
}
.page-watermark-text {
  position: absolute;
  left: 0.1rem;
  top: 50%;
  transform: translateY(-50%) rotate(180deg);
  writing-mode: vertical-rl;
  text-orientation: mixed;
  font-weight: 800;
  /* Zhruba 2× větší než původní 1rem. `min(…, 3.2vh)` drží nápis na JEDNOM
     sloupci a celý ve výřezu: bez stropu by se delší popisky („STARTOVNÍ
     LISTINA · FINÁLE A") na nižších oknech buď zalomily do několika sloupců
     (a zalezly pod tabulku), nebo se oříznuly uprostřed slova. */
  font-size: min(1.9rem, 3.2vh);
  white-space: nowrap;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--c-e2e8f0);
  opacity: 0.11;
  user-select: none;
}
@media (min-width: 1200px) {
  /* Na širokém okně je vedle obsahu (max-width ~900px) volný pruh — odsadíme
     nápis od hrany, ať „nevisí" na okraji. */
  .page-watermark-text { left: 0.5rem; }
}

/* Live (kros TT i časové disciplíny): obsah je hustý a začíná hned u levé
   hrany, takže pořadí/StČ leží přímo na písmu watermarku. Prostor v řádku je
   (za jménem zbývá volno), proto celý obsah posuneme doprava za watermark.
   Šířka nápisu = font-size (svislé písmo) ≤ 1.9rem + left 0.1rem → 2.5rem
   nechá i mezeru. Nad ~980px je obsah (max-width 900) vycentrovaný a volný
   pruh vznikne sám → beze změny. */
@media (max-width: 980px) {
  body.live-page .site-main { padding-left: 2.5rem; }
}

/* ============================================================
   Časové disciplíny (slalom / sjezd / sprint) — vlna B
   Výsledkové tabulky + branková matice. Tabulky scrollují uvnitř
   .time-table-wrap (overflow-x), stránka nikdy horizontálně.
   ============================================================ */
.time-page { max-width: 900px; margin: 0 auto; padding: 0 0.5rem 1rem; }

.time-banner {
  display: flex; align-items: center; gap: 0.5rem;
  margin: 0.6rem 0; padding: 0.45rem 0.75rem;
  border-radius: 8px; font-size: 0.9rem; font-weight: 600;
  background: var(--c-1e293b); color: var(--c-e2e8f0);
  border: 1px solid var(--c-334155);
}
.time-banner-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.time-banner-running .time-banner-dot {
  background: #ef4444; animation: time-banner-pulse 1.4s ease-in-out infinite;
}
.time-banner-done .time-banner-dot { background: #22c55e; }
@keyframes time-banner-pulse { 50% { opacity: 0.35; } }

.time-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.time-table {
  width: 100%; border-collapse: collapse; font-size: 0.88rem;
  color: var(--c-e2e8f0);
}
.time-table th, .time-table td {
  padding: 0.4rem 0.5rem; text-align: left; white-space: nowrap;
  border-bottom: 1px solid var(--c-273449);
}
.time-table thead th {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--c-94a3b8); border-bottom: 1px solid var(--c-334155);
  position: sticky; top: 0; background: var(--c-0f172a);
}
.time-table .tt-num { text-align: right; font-variant-numeric: tabular-nums; }
.time-table .time-name { white-space: normal; min-width: 10rem; }
/* Dvojice VK sloupců (pořadí ve VK „2." + samotná VK) pod jedním společným
   nadpisem „VK" (colspan=2). Sloupce těsně u sebe — pořadí zarovnané doprava
   s malým pravým paddingem, VK doleva s malým levým → „2. DS" čte se jako
   jeden celek. Viditelné i na mobilu (nemají .time-col-detail). */
.time-table th.time-vk-head { text-align: center; }
.time-table td.time-vkrank { text-align: right; font-variant-numeric: tabular-nums; padding-right: 0.15rem; }
.time-table td.time-vkcat  { text-align: left;  padding-left: 0.15rem; }
.time-rank { font-weight: 700; }
.time-total { font-weight: 700; }
.time-best { font-weight: 700; color: var(--c-fde047); }
/* Penalizace za časem (bez oddělovače, jen barvou), zarovnaná na 3 místa
   mezerami místo úvodních nul (white-space: pre je zachová). */
.time-pen { color: #f87171; font-size: 0.78rem; white-space: pre; }
.time-flt { color: #f87171; font-size: 0.78rem; font-weight: 700; }
.time-behind { color: var(--c-94a3b8); }
.time-pending { color: var(--c-94a3b8); font-style: italic; }
.time-badge { font-size: 0.8rem; letter-spacing: 0.03em; }
/* Posádka (C2/raft): jeden pádler = jeden řádek, stejně jako v KXRS. Obě jména
   mají stejnou váhu — dřív se tu vypisoval slepený titulek a pod ním ještě
   jednou šedá sedadla, tedy dvakrát totéž. */
.time-crew-member { display: block; }
.sl-crew-member { display: block; }

/* Dělící čáry: skupiny FA/FB + čára postupu (zelená, jako TT). */
.time-group-divider td {
  padding: 0.35rem 0.5rem; font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--c-94a3b8); background: var(--c-1e293b);
  border-top: 2px solid var(--c-475569);
}
tr.time-advance-cut td { border-bottom: 2px solid #22c55e; }
/* Postupový sloupec „Q" (poslední sloupec) — zelené Q u postupujících do
   Finále A (rank ≤ advance_count). Zůstává viditelný i na mobilu (není
   .time-col-detail), aby byl postup vždy vidět. */
.time-table th.time-col-q { text-align: center; width: 1.5rem; }
.time-table td.time-col-q { text-align: center; }
.time-q { color: #22c55e; font-weight: 700; }

/* Popisek aktuálního stavu nad výsledkovou tabulkou (Kvalifikace / Celkové
   výsledky) — NE sbalovací sekce, jen štítek fáze podle průběhu závodu. */
.time-stage-label {
  font-size: 0.78rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--c-94a3b8); margin: 0.1rem 0 0.5rem;
}

/* Poslední dojetý v LIVE výsledcích časové disciplíny — sjednoceno s kros
   latest-finisher (viz .tt-row-ranking výše). Trvalé zelené podbarvení + levý
   akcentový pruh drží server (data-latest-finisher, do dalšího dojezdu / max
   5 min); JEDNORÁZOVÝ pulz řídí JS (třída .latest-finisher-pulse) jen při
   změně dojetého (time_live.js), NE na každý swap — proto ne animace na
   atributovém selektoru. */
.time-table tbody tr.time-row[data-latest-finisher="1"] {
  background-color: rgba(34, 197, 94, 0.18);
  box-shadow: inset 3px 0 0 #22c55e;
  transition: background-color 0.5s ease-out;
}
.time-table tbody tr.time-row[data-latest-finisher="1"] > td {
  font-weight: 600;
}
@keyframes time-latest-finisher-pulse {
  0%   { background-color: rgba(34, 197, 94, 0.55); }
  50%  { background-color: rgba(34, 197, 94, 0.35); }
  100% { background-color: rgba(34, 197, 94, 0.18); }
}
.time-table tbody tr.time-row.latest-finisher-pulse {
  animation: time-latest-finisher-pulse 2s ease-out;
}
/* DNF/DSQ dominuje barvou i kdyby se sem řádek s terminálním stavem dostal
   (server značí jen řádně dojeté, tohle je jen obrana). */
.time-table tbody tr.time-row.race-athlete-dnf[data-latest-finisher="1"] {
  background-color: rgba(239, 68, 68, 0.12);
  box-shadow: inset 3px 0 0 #ef4444;
  animation: none;
}

/* Sbalitelné sekce (mezivýsledky, matice). */
.time-section { margin: 0.9rem 0; }
.time-section > summary {
  cursor: pointer; font-weight: 700; font-size: 0.92rem;
  padding: 0.45rem 0.2rem; color: var(--c-cbd5e1); user-select: none;
}
.time-section > summary::marker { color: var(--c-94a3b8); }
.time-matrix-label {
  font-size: 0.78rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--c-94a3b8); margin: 0.6rem 0 0.2rem;
}

/* Branková matice — živý pohled „na trati": karta per závodník, branky
   ve DVOU řádcích (grid ceil(n/2) sloupců), číslo branky v buňce.
   Protivodné branky = červené číslo (barvou, ne šipkou). */
/* Živý scoreboard „na trati" — jednotná LED tabule s kros TT (#tt-on-course):
   černý panel + žlutý rámeček, monospace žluté řádky, svítící běžící hodiny.
   Karta = plochý řádek (STČ · jméno · běžící čas), oddělený čárkovanou žlutou
   linkou. Branky (slalom/raft) se ukážou pod hlavičkou jako matice. */
.time-live-board {
  background: var(--c-0a0a0a);
  border: 2px solid var(--c-facc15);
  border-radius: 8px;
  padding: 0.5rem;
  margin-bottom: 1rem;
}
/* Prázdno (nikdo na trati) → žádná panelová chrome, jen prázdný stav uvnitř. */
.time-live-board.is-empty {
  background: transparent; border: 0; padding: 0; margin-bottom: 0.5rem;
}
.gm-card {
  margin: 0; padding: 0.3rem 0.25rem;
  background: transparent; border: 0; border-radius: 0;
  border-bottom: 1px dashed rgba(250, 204, 21, 0.2);
}
.gm-card:last-child { border-bottom: none; }
.gm-head {
  /* center (ne baseline) — hodiny jsou větší než STČ/jméno, viz .tt-row. */
  display: flex; align-items: center; gap: 0.5rem;
  font-family: ui-monospace, "SF Mono", Monaco, "Cascadia Code",
               "Roboto Mono", Consolas, "Liberation Mono",
               "Courier New", monospace;
  font-weight: 700; color: var(--c-facc15);
  font-size: 0.95rem; min-width: 0; margin-bottom: 0;
}
.gm-stc { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--c-fde047); font-size: 0.85rem; }
.gm-name { font-weight: 700; color: var(--c-facc15); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gm-pen { color: #f87171; font-weight: 700; font-size: 0.82rem; white-space: nowrap; }
/* Běžící hodiny — ohnisko: větší, svítí (glow), tabular-nums (jako #tt-on-course). */
.gm-clock {
  font-variant-numeric: tabular-nums; font-weight: 800;
  color: var(--c-facc15); font-size: 1.05rem; letter-spacing: 0.03em;
  text-shadow: 0 0 5px rgba(250, 204, 21, 0.4);
  white-space: nowrap; min-width: 4.2rem; text-align: right;
}
/* Když jsou branky (slalom/raft), oddělit matici od LED hlavičky. */
.gm-card .gm-gates { margin-top: 0.25rem; }
.gm-gates {
  display: grid; grid-template-columns: repeat(var(--gm-cols, 25), minmax(0, 1fr));
  gap: 1px;
}
.gm-gate {
  display: flex; flex-direction: column; align-items: center;
  padding: 0.15rem 0; border-radius: 5px;
  background: var(--c-0f172a); min-width: 0;
}
.gm-num { font-size: 0.62rem; line-height: 1.1; color: var(--c-94a3b8); font-variant-numeric: tabular-nums; }
.gm-num-up { color: #f87171; font-weight: 700; }
.gm-val {
  font-size: 0.78rem; font-weight: 700; line-height: 1.2; min-height: 1.05rem;
  display: flex; align-items: center; justify-content: center;
  font-variant-numeric: tabular-nums;
}
.gm-gate-touch .gm-val { color: var(--c-fde047); }
.gm-gate-miss .gm-val { color: #f87171; }
.gm-gate-touch { background: rgba(250, 204, 21, 0.12); }
.gm-gate-miss { background: rgba(239, 68, 68, 0.14); }
.time-gate-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: #22c55e;
}

/* ── Rozbalovací kompaktní detail závodníka (klik na výsledkový řádek) ─────
   Barevně odlišené okno pod řádkem na 2–3 řádcích, BEZ popisků kolonek:
   1) nacionále (STČ · jméno · oddíl · roč · VK · VT · pořadí ve VK),
   2) výsledky 1. jízdy (pořadí · čas · pen · celkem + čipy branek),
   3) 2. jízda (je-li). Čipy: žlutá „2" dotek / červená „50" neprůjezd,
   protivodná = červené číslo. */
.time-row-clickable { cursor: pointer; }
.time-row-clickable:hover { background: var(--c-1e293b); }
.time-row-clickable:focus-visible { outline: 2px solid #38bdf8; outline-offset: -2px; }
.time-table tbody tr.time-row.is-open { background: var(--c-1e293b); }
.time-table tbody tr.time-row.is-open > td { font-weight: 600; border-bottom-color: transparent; }

/* Buňka detailu — bez tabulkového paddingu, panel si řídí vlastní odsazení. */
.time-detail-row > td { padding: 0 0.35rem 0.6rem; border-bottom: 1px solid var(--c-273449); }

/* Barevně odlišené okno (accent proužek vlevo, tmavší podklad než řádek). */
.td-panel {
  background: var(--c-0f172a);
  border: 1px solid var(--c-334155);
  border-left: 3px solid #38bdf8;
  border-radius: 8px;
  padding: 0.5rem 0.7rem 0.55rem;
  display: flex; flex-direction: column; gap: 0.3rem;
}

/* 1. řádek — nacionále, tečkami oddělené doplňky. */
.td-nat {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.5rem;
  font-size: 0.84rem; color: var(--c-cbd5e1);
}
.td-stc { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--c-94a3b8); }
.td-name { font-weight: 700; color: var(--c-e2e8f0); }
/* Posádka v detailu — pádleři pod sebou (stejně jako ve výsledkové buňce),
   ročník za jménem ztlumeně. */
.td-crew-member { display: block; }
.td-crew-year { font-weight: 400; color: var(--c-94a3b8); }
.td-nat-x { display: inline; color: var(--c-94a3b8); }
.td-nat-x .nx { white-space: nowrap; }
.td-nat-x .nx + .nx::before { content: "·"; margin: 0 0.35rem; color: var(--c-475569); }

/* 2./3. řádek — jedna jízda na řádku, hodnoty bez popisků (rozliší barva). */
.td-runline {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.5rem;
  font-size: 0.85rem; font-variant-numeric: tabular-nums;
}
.td-run-rank {
  font-weight: 700; color: var(--c-e2e8f0);
  min-width: 1.6rem;
}
.td-run-rank::after { content: none; }
.td-net { color: var(--c-cbd5e1); }
.td-pen { color: #f87171; font-weight: 700; }
.td-total { color: var(--c-fde047); font-weight: 700; }
.td-flt { color: #f87171; font-size: 0.74rem; font-weight: 700; }
.td-run-badge {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.03em;
  padding: 0.02rem 0.35rem; border-radius: 4px;
  background: rgba(239, 68, 68, 0.16); color: #f87171;
}
.td-badge-dns { background: rgba(148, 163, 184, 0.18); color: var(--c-94a3b8); }

/* Čipy penalizace (MOBIL) = JEN číslo branky v barevném poli: žluté = dotek
   (2 s), červené = neprůjezd (50 s). Hodnota se neuvádí, nese ji barva pole.
   Protivodná branka = podtržené číslo. */
.td-gates { display: inline-flex; flex-wrap: wrap; gap: 0.25rem; margin-left: 0.25rem; }
.td-gate {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.15rem; padding: 0.04rem 0.34rem; border-radius: 4px;
  font-size: 0.78rem; font-weight: 700; line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.td-gate-up { text-decoration: underline; text-underline-offset: 2px; }
.td-gate-touch { background: rgba(250, 204, 21, 0.22); color: var(--c-fde047); }
.td-gate-miss { background: rgba(239, 68, 68, 0.26); color: #fca5a5; }

/* Kompletní stav VŠECH branek (desktop): buňka číslo/hodnota, všechny branky
   1..N; penalizace vybarvené (žlutá 2 / červená 50), čistě = tlumená „0",
   nerozhodnutá = přerušovaná „–". Skryto na mobilu (tam jen čipy výše). */
.td-gates-full { display: none; }
.td-gf {
  display: inline-flex; flex-direction: column; align-items: center;
  min-width: 1.55rem; padding: 0.04rem 0.28rem; border-radius: 4px;
  line-height: 1.15; font-variant-numeric: tabular-nums;
}
.td-gf-n { font-size: 0.6rem; font-weight: 600; color: var(--c-94a3b8); }
.td-gf-up .td-gf-n { color: #f87171; font-weight: 700; }
.td-gf-v { font-size: 0.74rem; font-weight: 700; }
.td-gf-clean .td-gf-v { color: var(--c-64748b, #64748b); }
.td-gf-empty { border: 1px dashed var(--c-334155); }
.td-gf-empty .td-gf-v { color: var(--c-475569); }
.td-gf-touch { background: rgba(250, 204, 21, 0.14); }
.td-gf-touch .td-gf-v { color: var(--c-fde047); }
.td-gf-miss { background: rgba(239, 68, 68, 0.16); }
.td-gf-miss .td-gf-v { color: #f87171; }

/* Desktop (≥720px): nacionále i časy jsou už ve sloupcích tabulky → v okně
   ukazuj JEN kompletní branky. Skryj nacionále řádek, časy/pořadí/čipy;
   ponech štítek jízdy (kontext) + status a mřížku všech branek. */
@media (min-width: 720px) {
  .td-nat { display: none; }
  .td-runline .td-run-rank,
  .td-runline .td-net,
  .td-runline .td-pen,
  .td-runline .td-total,
  .td-runline .td-flt,
  .td-runline .td-gates { display: none; }
  .td-gates-full { display: inline-flex; flex-wrap: wrap; gap: 0.22rem; }
  .td-panel { gap: 0.25rem; }
}

/* Mobil (<720px): detailové sloupce pryč, tabulka je kompaktní. */
@media (max-width: 719.98px) {
  .time-col-detail { display: none; }
}

/* Mobil (<720px) — výsledky časových disciplín (LIVE panel i statická stránka
   Výsledky; .time-table je výhradně výsledková tabulka): vejít se na šířku
   obrazovky. Pořadí zarovnané doleva a bez levého odsazení (posun vlevo), jméno
   jen příjmení (.time-given skryto), a jen výsledek bez penalizací (sloupec ČAS
   .time-col-net + .time-pen pryč). */
@media (max-width: 719.98px) {
  .time-table .time-col-net,
  .time-table .time-pen,
  .time-table .time-given { display: none; }
  .time-table { font-size: 0.85rem; }
  .time-table th,
  .time-table td { padding: 0.35rem 0.3rem; }
  .time-table th:first-child,
  .time-table td:first-child {
    padding-left: 0.1rem; text-align: center;
  }
  .time-table .time-name {
    min-width: 0; white-space: nowrap;
  }
}

/* Startovka časových dvoukolových formátů (.sl-two-runs): oba startovní
   časy vedle sebe jako samostatné sloupce — mobil 4 sloty, desktop 8. */
.startlist.sl-two-runs .sl-head,
.startlist.sl-two-runs .tt-row-startlist {
  grid-template-columns: 2.5rem 1fr auto auto;
}
@media (min-width: 720px) {
  .startlist.sl-two-runs .sl-head,
  .startlist.sl-two-runs .tt-row-startlist {
    grid-template-columns: 2.5rem minmax(7rem, 1.4fr) 3.5rem 3rem 2.75rem minmax(5rem, 1fr) 5rem 5rem;
  }
}
.tt-row-startlist .tt-row-time2 { text-align: right; color: var(--c-cbd5e1); }

/* Startovka finále s výsledky předchozích fází (.sl-prior / .sl-prior-fb):
   Kvalifikace u obou finále, u Finále A navíc Finále B. Sloupce jsou
   běžné .sl-cell, takže na mobilu zůstávají skryté (jdou do souhrnu pod
   jménem) a přibývají jen na desktopu — mobilní mřížka se nemění. */
@media (min-width: 720px) {
  .startlist.sl-prior .sl-head,
  .startlist.sl-prior .tt-row-startlist {
    grid-template-columns: 2.5rem minmax(7rem, 1.4fr) 3.5rem 3rem 2.75rem minmax(5rem, 1fr) 4.5rem 5rem;
  }
  .startlist.sl-prior.sl-prior-fb .sl-head,
  .startlist.sl-prior.sl-prior-fb .tt-row-startlist {
    grid-template-columns: 2.5rem minmax(7rem, 1.4fr) 3.5rem 3rem 2.75rem minmax(5rem, 1fr) 4.5rem 4.5rem 5rem;
  }
  .sl-head-prior { text-align: right; }
  .tt-row-startlist .sl-cell-prior {
    text-align: right;
    font-variant-numeric: tabular-nums;
  }
  /* Započítaná jízda (lepší z obou) — zvýrazněná ve svém zdrojovém sloupci;
     samostatný sloupec „Lepší" se nevypisuje. */
  .tt-row-startlist .sl-cell-counted { color: var(--c-e2e8f0); font-weight: 600; }
}

/* ═══════════════════════════════════════════════════════════════════════
   LIVE pohled časové disciplíny (time_live.html) — event-level scoreboard
   „na trati" + přepínač typu scoreboardu + spodní přepínač fází.
   Používá paletové proměnné (--c-*), které se ve světlém motivu přemapují,
   takže je celý blok theme-aware bez extra overridů.
   ═══════════════════════════════════════════════════════════════════════ */

/* Přepínač „Živý čas v pořadí" na časových disciplínách sdílí komponent
   .tt-live-toggle s kros TT (styl viz ~ř. 965). Dřívější přepínač TYPU
   scoreboardu (.time-sb-toggle, matrix/compact/clock) byl odstraněn —
   scoreboard „na trati" je teď jednotná LED tabule (viz .time-live-board). */

/* Živá kategorie v horní liště — červená pulzující tečka */
.tt-cat-live-dot {
  display: inline-block; width: 7px; height: 7px; margin-left: 0.4rem;
  border-radius: 50%; background: #ef4444;
  animation: time-live-ping 1.6s ease-out infinite;
}
@keyframes time-live-ping {
  0%   { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.55); }
  70%  { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
  100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
}

/* Kontejner — rezervuj místo pod fázovou lištou (nad app dockem) */
.time-live { padding-bottom: 60px; }

/* Prázdný stav scoreboardu „na trati" */
.time-live-empty {
  text-align: center; color: var(--c-94a3b8); font-weight: 600;
  padding: 1.6rem 1rem; background: var(--c-1e293b);
  border: 1px dashed var(--c-334155); border-radius: 10px; margin: 0.5rem 0;
}

/* Výsledky aktivní fáze (bez ručního přepínače — auto-follow live fáze) */
.time-phase-panel.is-hidden { display: none; }

/* „Živý čas v pořadí" — projekce běžícího závodníka ze scoreboardu do
   výsledkové tabulky aktivní fáze (time_live.js, off/light/full). Vizuálně
   SHODNÉ s kros TT: full = LED řádek (.tt-row--live), light = svítící žlutá
   dělící čára + pilulka „STČ · jméno" (.tt-rank-marker). Default off. */
/* full = LED řádek: černý podklad, žlutý monospace, svítící hodiny, žlutý rám. */
.time-proj-row > td {
  /* Optická korekce svislé polohy (stejný princip jako #tt-on-course .tt-row):
     řádek má barevný podklad (LED černý / ve světlém režimu žlutý), takže je
     vidět, že ink písma sedí v line-boxu výš — pod účařím zůstává nevyužité
     místo pro dolní dotažnice, které STČ/jméno/hodiny nemají. Měřeno po
     pixelech: 8,0 px nad textem vs 12,25 px pod ním. Padding buňky (jinak
     0.4rem) proto rozdělen 0.53 / 0.27rem — součet 0.8rem i výška řádku
     zůstávají stejné. */
  padding-top: 0.53rem;
  padding-bottom: 0.27rem;
  background: var(--c-0a0a0a);
  color: var(--c-facc15);
  font-family: ui-monospace, "SF Mono", Monaco, "Cascadia Code",
               "Roboto Mono", Consolas, "Liberation Mono",
               "Courier New", monospace;
  font-weight: 700;
  border-top: 1px solid rgba(250, 204, 21, 0.5);
  border-bottom: 1px solid rgba(250, 204, 21, 0.5);
}
.time-proj-row .time-rank,
.time-proj-row .time-name { color: var(--c-facc15); }
.time-proj-clock {
  color: var(--c-facc15); font-weight: 700; font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em; text-shadow: 0 0 6px rgba(250, 204, 21, 0.4);
}
/* light = svítící žlutá dělící čára (::before přes celou šířku) + pilulka
   „STČ · jméno" na ní (mirror .tt-rank-marker / .tt-rank-marker-chip). */
.time-proj-cut > td { position: relative; padding: 0.4rem 0.5rem; }
.time-proj-cut > td::before {
  content: ""; position: absolute; left: 0.5rem; right: 0.5rem; top: 50%;
  height: 2px; transform: translateY(-50%);
  background: var(--c-facc15); box-shadow: 0 0 6px rgba(250, 204, 21, 0.55);
}
.time-proj-chip {
  position: relative; z-index: 1; display: inline-flex; align-items: center;
  gap: 0.35rem; margin-left: 2.5rem; padding: 0.06rem 0.5rem;
  background: var(--c-facc15); color: var(--c-0a0a0a); border-radius: 999px;
  font-size: 0.74rem; font-weight: 700; box-shadow: 0 0 0 2px var(--c-0f172a);
}
.time-proj-chip-stc {
  font-variant-numeric: tabular-nums; padding-right: 0.35rem;
  border-right: 1px solid rgba(10, 10, 10, 0.35);
}
.time-proj-chip-name { font-weight: 700; }

/* Závodník PRÁVĚ NA TRATI ve formátu „na lepší jízdu" (Finále B best(KVAL, FB),
   2. jízda dvouběhu): dokud si nepolepšil, drží svůj dosavadní čas i pořadí —
   projekční duplikát by mu stál na vlastním řádku, tak se místo něj zvýrazní
   rovnou ten řádek (time_live.js: markRunningRow) a do buňky probíhající jízdy
   se vloží běžící hodiny. Tlumené LED ladění (žlutá), aby řádek zůstal čitelný
   jako součást listiny — na rozdíl od .time-proj-row, který je celý LED. */
.time-row--running > td {
  background: rgba(250, 204, 21, 0.1);
}
.time-row--running > td:first-child {
  box-shadow: inset 3px 0 0 var(--c-facc15);
}
:root[data-theme="light"] .time-row--running > td {
  background: rgba(250, 204, 21, 0.28);
}
.time-live-panels { margin-top: 0.9rem; }
/* Nadpis fáze nad výsledky (jen finále A/B — říká, která fáze se ukazuje) */
.time-phase-heading {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0.2rem 0 0.5rem;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--c-e2e8f0);
}

/* Spodní přepínač fází — sticky pruh NAD app dockem (.site-dock = 56px). */
.time-phase-dock {
  position: fixed; left: 0; right: 0;
  bottom: calc(56px + env(safe-area-inset-bottom, 0));
  background: var(--c-0f172a);
  border-top: 1px solid var(--c-273449);
  z-index: 98;
}
.time-phase-dock-inner {
  display: flex; width: 100%; max-width: 900px; margin: 0 auto; gap: 2px;
  padding: 0.25rem 0.4rem;
}
.time-phase-btn {
  flex: 1; display: inline-flex; align-items: center; justify-content: center;
  gap: 0.4rem; position: relative; min-height: 44px; padding: 0.35rem 0.5rem;
  background: transparent; color: var(--c-94a3b8);
  border: 1px solid transparent; border-radius: 8px;
  font-family: inherit; font-weight: 700; font-size: 0.9rem; cursor: pointer;
}
.time-phase-btn:hover { background: rgba(255, 255, 255, 0.06); color: var(--c-e2e8f0); }
.time-phase-btn.active { background: #38bdf8; color: #fff; }
.time-phase-btn.is-empty { opacity: 0.5; }
.time-phase-ico { width: 20px; height: 20px; flex: 0 0 auto; }
.time-phase-letter { font-size: 1.1rem; font-weight: 800; line-height: 1; }
.time-phase-label { white-space: nowrap; }
.time-phase-live-dot {
  width: 7px; height: 7px; border-radius: 50%; background: #ef4444; flex: 0 0 auto;
  animation: time-live-ping 1.6s ease-out infinite;
}
.time-phase-btn.active .time-phase-live-dot { background: #fff; }

/* Úzký mobil: schovej textový popisek (nech ikonu/písmeno) */
@media (max-width: 519.98px) {
  .time-phase-label { display: none; }
}
