/* Atletieklab — design tokens uit het VS Running Lab ontwerp */

/* Merk-fonts (self-hosted, latin-subset). Zie wwwroot/fonts/README.md.
   font-display: swap → valt terug op de stack-fallback tot het bestand er is. */
@font-face { font-family: 'Space Grotesk'; font-style: normal; font-weight: 500; font-display: swap; src: url('../fonts/spacegrotesk-500.woff2') format('woff2'); }
@font-face { font-family: 'Space Grotesk'; font-style: normal; font-weight: 700; font-display: swap; src: url('../fonts/spacegrotesk-700.woff2') format('woff2'); }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 400; font-display: swap; src: url('../fonts/archivo-400.woff2') format('woff2'); }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 600; font-display: swap; src: url('../fonts/archivo-600.woff2') format('woff2'); }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 700; font-display: swap; src: url('../fonts/archivo-700.woff2') format('woff2'); }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 800; font-display: swap; src: url('../fonts/archivo-800.woff2') format('woff2'); }
@font-face { font-family: 'JetBrains Mono'; font-style: normal; font-weight: 500; font-display: swap; src: url('../fonts/jetbrainsmono-500.woff2') format('woff2'); }
@font-face { font-family: 'JetBrains Mono'; font-style: normal; font-weight: 700; font-display: swap; src: url('../fonts/jetbrainsmono-700.woff2') format('woff2'); }

:root {
  --primary: #e0342a;
  --primary-dark: #c02a22;
  --primary-soft: #fdecea;
  --navy: #16324e;
  --navy-2: #1e405f;
  /* Groen en rood zoals ze op donkerblauw leesbaar blijven. De gewone --green en --red zijn
     gekozen voor witte kaarten en zakken op de navy-balk weg in de achtergrond. */
  --ok-on-navy: #5ec99b;
  --danger-on-navy: #ff8b82;
  /* Dieper dan de zijbalk, voor de landingspagina: die vult het hele scherm, en op die
     oppervlakte leest #16324e als een blauw vlak in plaats van als achtergrond. */
  --navy-deep: #0b1724;
  --paper: #f4f1ea;
  --app-bg: #f4f1ea;
  --card-bg: #ffffff;
  --sidebar-bg: #16324e;
  --text-main: #1a2230;
  --text-sub: #625c52;
  --border: #e2dcd0;
  --green: #2f9e6b;
  --red: #e0342a;
  --amber: #c8811f;
  --purple: #7c3aed;
  /* Sidebar (navy paneel) tinten */
  --side-text: #eef2f6;
  --side-sub: #a9b9c8;
  --side-active: rgba(255, 255, 255, 0.08);
  --radius: 14px;
  --font: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-display: 'Space Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Consolas, monospace;

  /* ── Typografische schaal ──
     Zeven rollen, elk met een taak. De views schreven tweeëntwintig verschillende groottes door
     elkaar (van 9 tot 40 px, met 11,5 en 12,5 ertussen); dat is geen schaal maar een reeks losse
     beslissingen, en het is de reden dat twee secties naast elkaar nooit helemaal hetzelfde ogen.
     Wie hier een maat mist, hoort een rol te missen — niet een getal toe te voegen. */
  --fs-label: 11px;      /* kapitalen boven een kolom of kaart */
  --fs-meta: 12.5px;     /* datum, herkomst, toelichting bij een waarde */
  --fs-dense: 13px;      /* tabellen die veel kolommen moeten dragen */
  --fs-body: 14px;       /* alles wat gewoon tekst is */
  --fs-section: 17px;    /* kop boven een blok */
  --fs-page: 26px;       /* paginatitel */
  --fs-stat: 32px;       /* het ene cijfer waar een statkaart om draait */

  /* Ondergrens. Onder 11px wordt tekst op een laptopscherm gokwerk; 11 blijft voorbehouden aan
     korte labels in kapitalen, lopende tekst begint bij --fs-meta. */

  /* ── Ritme ──
     Alles een veelvoud van vier. Marges stonden in de views op 4, 6, 8, 10, 12, 14, 16 en 18 door
     elkaar, waardoor blokken op dezelfde pagina net niet uitlijnen. */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;

  /* ── Rondingen ──
     Drie maten: de kaart, wat erin zit, en wat klein is. */
  --radius-lg: 20px;     /* het logoblok op de landingspagina, dat op 84px groter moet ronden */
  --radius-sm: 10px;
  --radius-xs: 8px;

  /* Het wit waarop een QR-code moet staan. Geen thema-kleur maar een eis van de scanner: een
     omgekeerde code wordt niet gelezen, ook niet in donkere modus. */
  --qr-paper: #ffffff;

  /* ── Betekenis in plaats van kleur ──
     "Groen" zegt niets over waarom iets groen is. Deze namen wel, en ze laten toe de tint ooit te
     wijzigen zonder overal te moeten nagaan of dat groen "goed" of "gelopen" betekende. */
  --ok: var(--green);
  --warn: var(--amber);
  --danger: var(--red);
  --info: var(--navy);
  --accent-neutral: #5b7185;

  /* Een badge of een gemarkeerde regel heeft er drie nodig: een vlak, een rand en inkt die op dat
     vlak leesbaar blijft. Met alleen --ok belanden die twee andere alsnog als kale waarde in de
     component, en dan is de kleur niet meer centraal te wijzigen. */
  --ok-soft: #dcfce7;
  --ok-ink: #15803d;
  --ok-border: #86ce9f;
  --warn-soft: #fef3c7;
  --warn-ink: #b45309;
  --danger-soft: #fee2e2;
  --danger-ink: #b91c1c;
  /* Het bruin-amber dat gebruikt wordt voor "verouderd" op een lichte achtergrond; stond op drie
     plaatsen als #b07d1a. */
  --stale-ink: #b07d1a;

  /* ── Reekskleuren voor grafieken ──
     Acht tinten in een vaste volgorde, nooit doorlopend hergebruikt: krijgt een grafiek een
     negende reeks, dan is dat een teken dat er te veel op één beeld staat.
     De volgorde is niet zelf gekozen maar overgenomen uit een gevalideerde set die de gangbare
     controles doorstaat — voldoende verschil tussen buurkleuren, ook voor wie kleuren anders ziet.
     Elke grafiek in de app haalt haar kleuren hier; tot nu toe koos elke grafiek ze zelf, met als
     gevolg dat dezelfde reeks op twee schermen een andere kleur had. */
  --series-1: #2a78d6;
  --series-2: #eb6834;
  --series-3: #1baf7a;
  --series-4: #eda100;
  --series-5: #e87ba4;
  --series-6: #008300;
  --series-7: #4a3aa7;
  --series-8: #e34948;
}

* { box-sizing: border-box; }

/* Het hidden-attribuut moet altijd winnen: een eigen display (flex/grid) van een
   component overschrijft anders de standaardregel van de browser en dan blijft
   een 'verborgen' paneel gewoon staan. */
[hidden] { display: none !important; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font);
  background: var(--app-bg);
  color: var(--text-main);
  font-size: var(--fs-body);
  line-height: 1.5;
}
a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }
/* Naam-links (atleten, testen) zijn donker; rood blijft voor echte navigatie-accenten. */
strong a { color: var(--text-main); }
strong a:hover { color: var(--primary); }
:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.sr-only {
  position: absolute !important;
  width: 1px !important; height: 1px !important;
  padding: 0 !important; margin: -1px !important;
  overflow: hidden !important; clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important; border: 0 !important;
}
.skip-link {
  position: fixed; top: 8px; left: 8px; z-index: 2000;
  padding: 9px 14px; border-radius: 8px;
  background: #fff; color: var(--navy); font-weight: 700;
  transform: translateY(-160%);
}
.skip-link:focus { transform: translateY(0); }

/* ===== App shell ===== */
.app { display: flex; min-height: 100vh; }

.sidebar {
  width: 232px;
  flex-shrink: 0;
  background: var(--sidebar-bg);
  color: var(--side-text);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}

/* Merk-kop met embleem */
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 20px 18px 16px;
}
.sidebar-brand .emblem {
  width: 36px; height: 36px;
  border-radius: 8px;
  background: #fff;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; overflow: hidden;
}
.sidebar-brand .emblem img { width: 28px; height: 28px; object-fit: contain; }
.sidebar-brand .title {
  font-family: var(--font-display);
  font-weight: 700; font-size: 15px; color: #fff;
  letter-spacing: .01em; line-height: 1;
}
.sidebar-brand .sub {
  font-size: 9.5px; font-weight: 600; color: var(--side-sub);
  letter-spacing: .14em; text-transform: uppercase; margin-top: 3px;
}

/* Primaire actie */
.sidebar-cta { padding: 4px 14px 10px; }
.btn-newtest {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%;
  padding: 10px 12px;
  border-radius: 10px;
  border: none;
  background: var(--primary);
  color: #fff;
  font: inherit; font-weight: 700; font-size: 13px;
  cursor: pointer;
  transition: background .15s;
}
.btn-newtest:hover { background: var(--primary-dark); color: #fff; text-decoration: none; }
.btn-newtest svg { width: 15px; height: 15px; }

.sidebar-nav { flex: 1 1 auto; min-height: 80px; padding: 4px 0; overflow-y: auto; }
.nav-section { margin-bottom: 6px; }
.nav-heading {
  font-size: 9.5px; font-weight: 700; color: var(--side-sub);
  letter-spacing: .14em; text-transform: uppercase;
  padding: 8px 22px 4px;
}
.nav-link {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 22px;
  border-left: 2px solid transparent;
  color: var(--side-text);
  font-weight: 500; font-size: 13.5px;
  opacity: .82;
  transition: background .15s, color .15s, opacity .15s;
}
.nav-link:hover { background: var(--side-active); text-decoration: none; opacity: 1; }
.nav-link.active {
  background: var(--side-active);
  border-left-color: var(--primary);
  color: #fff;
  font-weight: 700;
  opacity: 1;
}
.nav-link svg { width: 17px; height: 17px; flex-shrink: 0; }

/* Uitklapmenu in de zijbalk (Nieuw-knop en accountmenu) */
.sidebar-cta, .sidebar-user { position: relative; }
.side-menu {
  position: absolute; left: 12px; right: 12px; z-index: 40;
  background: #1e3f60; border: 1px solid rgba(255,255,255,0.14);
  border-radius: 11px; padding: 5px; box-shadow: 0 12px 28px rgba(0,0,0,.35);
  display: flex; flex-direction: column;
}
.side-menu.up { bottom: calc(100% - 6px); }
.side-menu a, .side-menu button {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 11px; border-radius: 7px; border: none; background: none;
  font: inherit; font-size: 13px; text-align: left; cursor: pointer;
  color: var(--side-text); width: 100%;
}
.side-menu a:hover, .side-menu button:hover { background: rgba(255,255,255,0.1); color: #fff; text-decoration: none; }
.side-menu .sep { height: 1px; background: rgba(255,255,255,0.12); margin: 5px 4px; }
.dot-badge {
  margin-left: auto; background: var(--primary); color: #fff;
  font-size: 10px; font-weight: 800; border-radius: 100px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
}

.sidebar-user {
  border-top: 1px solid rgba(255,255,255,0.08);
  padding: 10px 12px;
  font-size: 13px;
  flex-shrink: 0;
}
.sidebar-user .who {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 6px; border: none; border-radius: 10px; background: none;
  font: inherit; text-align: left; color: var(--side-text); cursor: pointer;
}
.sidebar-user .who:hover { background: rgba(255,255,255,0.07); }
.sidebar-user .who .whotext { display: flex; flex-direction: column; min-width: 0; }
.sidebar-user .who strong { color: #fff; font-size: 13px; }
.sidebar-user .who .role { color: var(--side-sub); font-size: 11px; }
.quick-caret { font-size: 11px; letter-spacing: 0; transition: transform .15s; margin-left: auto; }
.sidebar-user .who[aria-expanded="true"] .quick-caret { transform: rotate(180deg); }
.sidebar-user .who .dot-badge + .quick-caret { margin-left: 6px; }
@media (prefers-reduced-motion: reduce) { .quick-caret { transition: none; } }

.avatar {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  flex-shrink: 0;
}
.avatar.alt { background: var(--purple); }

.main { flex: 1; padding: 32px 36px; max-width: 1180px; width: 100%; margin: 0 auto; }

/* ===== Headings & cards ===== */
/* ===== Hulpklassen =====
   Bewust een korte lijst. Duizend inline stijlen vervangen door honderd utilities is technisch
   netter en conceptueel even stuurloos; wat een eigen betekenis heeft, hoort een component te
   worden (zie .comp-card). Dit zijn de zes gevallen die overal terugkomen zonder ergens bij te
   horen. Komt er een zevende bij, dan is dat een aanwijzing dat er een component ontbreekt. */
.muted { color: var(--text-sub); }
.t-label { font-size: var(--fs-label); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-sub); }
.t-meta { font-size: var(--fs-meta); color: var(--text-sub); }
.t-dense { font-size: var(--fs-dense); }
.t-num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }

/* Leestekst — release notes, uitleg, hulpteksten van enige lengte. De enige plaats waar de
   bodymaat omhoog gaat: dit is tekst die je léést, niet aftast. Een tweede bodymaat overal
   toelaten zou een nieuwe bron van drift zijn, dus ze staat hier en nergens anders. */
.prose { font-size: 15px; line-height: 1.6; max-width: 68ch; }
.prose p { margin: 0 0 var(--sp-3); }
.prose ul { margin: 0 0 var(--sp-3); padding-left: 20px; }
.prose li + li { margin-top: var(--sp-1); }

.page-head { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: var(--sp-3); margin-bottom: var(--sp-2); }
h1 { font-family: var(--font-display); font-size: var(--fs-page); font-weight: 700; margin: 0; letter-spacing: -.01em; }
.page-sub { color: var(--text-sub); margin: 2px 0 22px; }
h2.section { font-family: var(--font-display); font-size: var(--fs-section); font-weight: 700; margin: var(--sp-5) 0 var(--sp-3); }

.card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-4) var(--sp-5);
}
/* Twee kaarten onder elkaar in een gewone stroom houden afstand. In een grid niet: daar zorgt de
   gap al voor de ruimte, en telde deze marge er bovenop — de tweede kolom zakte dan zichtbaar weg
   ten opzichte van de eerste. */
.card + .card { margin-top: 16px; }
.grid > .card + .card, .grid > .card { margin-top: 0; }

/* Varianten met een spatie en niet met "--": dit huis schrijft modifiers als .btn.primary,
   .badge.green en .grid.cols-4. Een tweede naamgeving ernaast zetten is dezelfde drift die we
   bestrijden, één laag hoger. Een variant verandert de maatvoering of de betekenis van een kaart,
   nooit haar bouw — vandaar dat ze allemaal op dezelfde basis staan. */
.card.compact { padding: var(--sp-3) var(--sp-4); }
.card.flush { padding: 0; }                       /* kaart die volledig door een tabel gevuld wordt */
.card.quiet { background: transparent; border-style: dashed; }
.card.attention { border-left: 3px solid var(--warn); }
.card.problem { border-left: 3px solid var(--danger); }

.grid { display: grid; gap: 16px; }
.grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1000px) { .grid.cols-4, .grid.cols-3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .grid.cols-4, .grid.cols-3, .grid.cols-2 { grid-template-columns: 1fr; } }

/* Statkaarten met gekleurde topborder (zoals het ontwerp) */
.stat-card { position: relative; overflow: hidden; }
.stat-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px; background: var(--accent, var(--primary));
}
.stat-card .label {
  font-size: var(--fs-label); font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-sub);
  display: flex; justify-content: space-between; align-items: center;
}
.stat-card .value { font-size: var(--fs-stat); font-weight: 800; margin: 6px 0 2px; }
.stat-card .hint { color: var(--text-sub); font-size: var(--fs-meta); }

/* Navy KPI-balk (het herkenbare instrumentenpaneel uit het ontwerp) */
.stat-hero {
  background: var(--navy); border-radius: var(--radius);
  display: grid; grid-template-columns: repeat(4, 1fr);
  padding: 20px 4px; margin-bottom: 22px;
}
.stat-hero .col { padding: 2px 22px; border-left: 1px solid rgba(255,255,255,0.1); min-width: 0; }
.stat-hero .col:first-child { border-left: none; }
.stat-hero .label {
  font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--side-sub); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.stat-hero .value {
  font-family: var(--mono); font-size: 30px; font-weight: 700; color: #fff;
  margin: 10px 0 8px; line-height: 1; letter-spacing: -.5px;
}
.stat-hero .value.alert { color: var(--danger-on-navy); }
.stat-hero .value.ok { color: var(--ok-on-navy); }
/* Een link in de balk moet leesbaar blijven op donkerblauw en toch als link lezen. */
.stat-hero .hint a { color: var(--side-text); text-decoration: underline; text-underline-offset: 2px; }
.stat-hero .hint a:hover { color: var(--card-bg); }
/* De balk mag ook drie kolommen breed zijn; vier is enkel de standaard. */
.stat-hero.three-cols { grid-template-columns: repeat(3, 1fr); }
.stat-hero .hint { font-size: 11px; color: #8ea3b8; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stat-hero .hint.alert { color: #ff8a7d; }
@media (max-width: 900px) { .stat-hero { grid-template-columns: repeat(2, 1fr); row-gap: 16px; } }
@media (max-width: 480px) { .stat-hero { grid-template-columns: 1fr; } }

/* Richting-trend onder een KPI-waarde (↑ groen / ↓ rood / → neutraal) */
.stat-hero .trend { font-size: 11px; font-weight: 700; margin: 0 0 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stat-hero .trend.up { color: #5fd39a; }
.stat-hero .trend.down { color: #ff7a70; }
.stat-hero .trend.flat { color: #8ea3b8; }

/* ===== Status-chips (FIT / MOE / RUST) — lab-readout uit het ontwerp ===== */
.chip {
  display: inline-block;
  font-size: 9.5px; font-weight: 700; letter-spacing: .04em;
  padding: 3px 8px; border-radius: 5px; white-space: nowrap;
}
.chip.green   { background: #e7f4ee; color: #2f9e6b; }
.chip.amber   { background: #fbf1e2; color: #c8811f; }
.chip.navy    { background: #eceef1; color: #16324e; }
.chip.neutral { background: var(--app-bg); color: var(--text-sub); }

/* Klinische atletentabel: dunne kleur-tick vóór de naam */
.tick { display: inline-block; width: 4px; height: 30px; border-radius: 2px; flex-shrink: 0; vertical-align: middle; }
.atable .anm { display: flex; align-items: center; gap: 11px; min-width: 0; }
.atable td.mono, .atable th.mono { font-family: var(--mono); }

/* Officiële atletiekcategorie (cadet, scholier, …) */
.badge.cat { background: #eef2f7; color: #2c4a68; border: 1px solid #d6dfe9; font-family: var(--mono); }

/* ===== Subpagina's van het atleetdossier ===== */
.athlete-tabs {
  display: flex; gap: 4px; margin: -4px 0 18px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.athlete-tabs a {
  padding: 9px 14px; white-space: nowrap;
  font-size: 13.5px; font-weight: 600; color: var(--text-sub); text-decoration: none;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.athlete-tabs a:hover { color: var(--text-main); text-decoration: none; }
.athlete-tabs a.on { color: var(--primary); border-bottom-color: var(--primary); }

/* ===== Dashboard: werklijst en teamstatus ===== */
.worklist { display: flex; flex-direction: column; }
.workitem {
  display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 12px;
  padding: 10px 12px; border-left: 3px solid var(--amber);
  background: #fdfaf3; border-radius: 8px; margin-bottom: 6px;
}
.workitem.high { border-left-color: var(--red); background: #fdf4f3; }
.workitem .wname a { font-weight: 700; font-size: 14px; color: var(--text-main); }
.workitem .wreason { display: block; font-size: 12px; color: #8a6114; font-weight: 600; }
.workitem.high .wreason { color: #a3261b; }
.workitem .wfact { font-size: 12px; color: var(--text-sub); font-family: var(--mono); white-space: nowrap; }
@media (max-width: 620px) {
  .workitem { grid-template-columns: 1fr; }
  .workitem .wfact { white-space: normal; }
}

.backlog { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.backlogitem {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 0; font-size: 13.5px;
}

.teamstat { display: flex; flex-direction: column; gap: 8px; }
.teamstat a {
  display: block; padding: 9px 11px; border-radius: 8px; background: var(--app-bg);
  text-decoration: none; color: var(--text-main);
}
.teamstat a:hover { background: #eef2f7; text-decoration: none; }
.teamstat .tsvalue { font-family: var(--mono); font-size: 19px; font-weight: 700; }
.teamstat .tsvalue.warn { color: var(--amber); }
.teamstat .tslabel { font-size: 12.5px; font-weight: 600; margin-left: 7px; }
.teamstat .tscov { display: block; font-size: 11px; color: var(--text-sub); margin-top: 1px; }

/* ===== Herstelkaart op de atleetpagina ===== */
.recovery { display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 10px; }
.rmetric { border: 1px solid var(--border); border-left: 3px solid var(--border); border-radius: 10px; padding: 9px 11px; }
.rmetric .rlabel { font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-sub); }
.rmetric .rlabel .rsub { display: block; font-size: 9px; font-weight: 600; letter-spacing: 0; text-transform: none; color: #9aa7b4; }
.rmetric .rvalue { font-family: var(--mono); font-size: 20px; font-weight: 700; line-height: 1.25; }
.rmetric .runit { font-size: 11px; font-weight: 600; color: var(--text-sub); margin-left: 2px; }
.rmetric .rnote { font-size: 11px; color: var(--text-sub); margin-top: 2px; }
.rmetric .rnote.stale { color: var(--stale-ink); }
.rmetric .rdate { font-size: 10px; color: #9aa7b4; margin-top: 4px; font-family: var(--mono); }
.rmetric.ok { border-left-color: #cfd8e3; }
.rmetric.bad { border-left-color: var(--red); background: #fef5f4; }
.rmetric.flag { border-left-color: var(--amber); background: #fdf8ee; }
.rmetric.stale { border-left-color: #e2c68a; background: #fbf7ef; }
.rmetric.stale .rvalue { color: var(--text-sub); }

/* ===== Atletenlijst: filterchips en groepskoppen ===== */
.catfilter { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.chipbtn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: 100px; border: 1px solid var(--border);
  background: #fff; color: var(--text-main);
  font-size: 12.5px; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.chipbtn:hover { border-color: var(--navy); text-decoration: none; }
.chipbtn .n { font-family: var(--mono); font-size: 11px; color: var(--text-sub); }
.chipbtn.on { background: var(--navy); border-color: var(--navy); color: #fff; }
.chipbtn.on .n { color: #b9c8d6; }

.data tr.grouphead th {
  background: var(--app-bg); color: var(--text-sub);
  font-size: 10.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  padding: 7px 14px; border-bottom: 1px solid var(--border); text-align: left;
}
.data tr.grouphead.fav th { background: #fdf6e7; color: #9a6b12; }
.data tr.grouphead th .n { font-family: var(--mono); letter-spacing: 0; margin-left: 4px; }
.alist .rowsub { display: block; font-size: 11.5px; color: var(--text-sub); }
.alist .nowrap { white-space: nowrap; }
.alist .mono { font-family: var(--mono); font-size: 13px; }
.alist .mono.stale, .alist .rowsub.stale { color: var(--stale-ink); }
.alist td { vertical-align: middle; }

/* Mobiele kaartweergave van de atletenlijst: de tabel leest niet meer op een smal scherm,
   dus daaronder wisselt Atleten/Index naar een stapel volledige kaarten, elk met dezelfde
   snelkoppeling terug naar het dossier en naar een nieuwe test. */
.athlete-cards { display: none; }
@media (max-width: 640px) {
  .athlete-table { display: none; }
  .athlete-cards { display: block; }
  .athlete-list-card { padding: 14px !important; border: none; background: none; }
  .athlete-cards .section { margin: 4px 0 10px; }
}
.acard {
  background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 16px; margin-bottom: 12px;
}
.acard.fav { border-color: #f0d089; background: #fffdf7; }
.acard-head { display: flex; align-items: flex-start; gap: 10px; }
.acard-head .who { flex: 1; min-width: 0; }
.acard-head strong { display: block; font-family: var(--font-display); text-transform: uppercase; letter-spacing: .01em; }
.acard-head .rowsub { display: block; font-size: 12.5px; color: var(--text-sub); margin-top: 1px; }
.acard-fav { background: none; border: none; padding: 2px; color: #d5dbe3; cursor: pointer; }
.acard-fav.on { color: #d6960f; }
.acard-fav svg { width: 20px; height: 20px; }
.acard-stats { display: flex; gap: 24px; margin: 14px 0; }
.acard-stats .lbl { display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-sub); }
.acard-stats .val { display: block; font-family: var(--mono); font-size: 15px; font-weight: 700; margin-top: 2px; }
.acard-lasttest { border-top: 1px solid var(--border); padding-top: 12px; margin-bottom: 14px; }
.acard-lasttest .lbl { display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-sub); }
.acard-lasttest .val { font-size: 15px; font-weight: 700; margin-top: 3px; }
.acard-lasttest .sub { font-size: 12.5px; color: var(--text-sub); }
.acard .btn.block { display: block; width: 100%; text-align: center; }

/* Aandacht: één reden per rij, feitelijk geformuleerd */
.attn {
  display: inline-block; font-size: 11.5px; font-weight: 600;
  padding: 3px 9px; border-radius: 100px;
  background: #fdf3dc; color: #8a6114; border: 1px solid #f0d089;
}
.attn.high { background: #fdecea; color: #a3261b; border-color: #f3bdb6; }

/* Syncindicator: een stip in plaats van een kolom */
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; vertical-align: middle; }
.dot.ok { background: #74c69d; }
.dot.bad { background: var(--red); }
.dot.off { background: #d5dbe3; }

/* Syncindicator per bron: letterbadge zodat "welke bron" zonder hoveren te zien is */
.srcdot {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border-radius: 4px; vertical-align: middle;
  font-size: 9px; font-weight: 800; line-height: 1;
}
/* Donkerder groen dan .dot.ok: wit op #74c69d haalt geen leesbaar contrast op 9px tekst. */
.srcdot.ok { background: #1f7a4d; color: #fff; }
.srcdot.bad { background: var(--red); color: #fff; }
.srcdot.off { background: #d5dbe3; color: #57616c; }

/* Secundaire acties achter ⋯ */
.rowmenu { position: relative; display: inline-block; margin-left: 8px; }
.rowmenu-btn {
  background: none; border: 1px solid transparent; border-radius: 7px;
  font: inherit; font-size: 16px; line-height: 1; color: var(--text-sub);
  padding: 2px 7px; cursor: pointer;
}
.rowmenu-btn:hover { background: var(--app-bg); border-color: var(--border); color: var(--text-main); }
.rowmenu-panel {
  display: none; position: absolute; right: 0; top: calc(100% + 4px); z-index: 30;
  min-width: 168px; background: #fff; border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 10px 24px rgba(16,36,58,.14); padding: 5px;
  text-align: left;
}
.rowmenu.open .rowmenu-panel { display: block; }
.rowmenu-panel a {
  display: block; padding: 7px 11px; border-radius: 7px;
  font-size: 13px; font-weight: 500; color: var(--text-main); text-decoration: none;
}
.rowmenu-panel a:hover { background: var(--app-bg); text-decoration: none; }

/* ===== Favorieten in de atletenlijst ===== */
.favcell { width: 34px; padding-right: 0 !important; }
.favcell form { display: flex; }
.fav-btn {
  background: none; border: none; cursor: pointer; padding: 3px;
  line-height: 0; border-radius: 6px; color: #c7ced8;
}
.fav-btn svg { width: 17px; height: 17px; }
.fav-btn:hover { color: var(--amber); background: var(--app-bg); }
.fav-btn.on { color: var(--amber); }
.data tr.fav-row > td { background: #fffaf0; }
/* Scheidingslijn onder de laatste favoriet: de knip tussen vastgezet en de rest. */
.data tr.fav-last > td { border-bottom: 2px solid var(--amber); }

/* ===== Release-notes / roadmap ===== */
.roadmap { display: grid; grid-template-columns: 190px 1fr; gap: 26px; align-items: start; }
.roadmap-nav {
  position: sticky; top: 18px; background: #fff; border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px 12px; display: flex; flex-direction: column; gap: 2px;
}
.roadmap-nav .track {
  font-size: 11px; font-weight: 700; color: var(--text-sub);
  text-transform: uppercase; letter-spacing: .5px; margin: 10px 0 4px;
}
.roadmap-nav a {
  padding: 5px 10px; border-radius: 7px; font-size: 13.5px; font-weight: 600;
  color: var(--text-main); text-decoration: none; font-family: var(--mono);
}
.roadmap-nav a:hover, .roadmap-nav a:focus-visible { background: var(--app-bg); }
.release { margin-bottom: 18px; scroll-margin-top: 18px; }
.rn-head { margin: 14px 0 6px; font-size: 13px; font-weight: 700; }
.rn-list { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 7px; font-size: 14px; }
.rn-list.fix { color: var(--text-sub); }
.planned { border: 2px dashed var(--border); background: transparent; margin-bottom: 18px; scroll-margin-top: 18px; }
.parked { background: #fdf3dc; border-color: #f0d089; scroll-margin-top: 18px; }
.parked .idea + .idea { margin-top: 16px; border-top: 1px solid #f0d089; padding-top: 16px; }
@media (max-width: 780px) {
  .roadmap { grid-template-columns: 1fr; }
  .roadmap-nav { position: static; flex-direction: row; flex-wrap: wrap; align-items: center; }
  .roadmap-nav .track { margin: 0 2px 0 8px; }
}

/* ===== Badges & pills ===== */
.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  background: var(--app-bg);
  color: var(--text-sub);
}
/* Prestatiebadges. Eigen klassen in plaats van een inline kleur, en met een vorm- of
   tekstverschil erbij: een deel van de trainers ziet rood en groen niet uit elkaar, en dan is
   "groen = record" geen informatie. PR draagt daarom ook een rand en meer gewicht dan SB. */
.badge.pr { background: var(--ok-soft); color: var(--ok-ink); font-weight: 700; border: 1px solid var(--ok-border); }
.badge.sb { background: var(--app-bg); color: var(--text-sub); border: 1px solid var(--border); }
.badge.wind { background: var(--warn-soft); color: var(--warn-ink); }
/* Voorlopig: een gestreepte rand, want dit is geen waarschuwing maar een "nog niet vast". Het
   verschil met wind moet ook zonder kleur te zien zijn. */
.badge.provisional { background: transparent; color: var(--warn-ink); border: 1px dashed var(--warn-ink); }
/* De kolom met het ijkpunt: de tijd waartegen deze prestatie gelezen hoort.
   Rechts uitgelijnd en met vaste breedte, zodat de ijkpunten onder elkaar staan naast de tijden
   waar ze bij horen. Stonden ze achter de badge, dan zweefde het getal in elke rij op een andere
   plek en viel er tussen atleten onderling niets te vergelijken.
   Gedempt: dit is de achtergrond bij de uitslag, niet de uitslag zelf. */
td.vs {
  font-family: var(--mono); font-size: var(--fs-meta); font-weight: 500;
  color: var(--text-sub); white-space: nowrap; text-align: right;
  min-width: 78px; font-variant-numeric: tabular-nums; cursor: help;
}
td.vs.first { font-weight: 400; font-style: italic; }

.badge.blue   { background: #dbeafe; color: #1d4ed8; }
.badge.purple { background: #ede9fe; color: #6d28d9; }
.badge.green  { background: #dcfce7; color: #15803d; }
.badge.red    { background: #fee2e2; color: #b91c1c; }
.badge.amber  { background: #fef3c7; color: #b45309; }

.threshold-box {
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .05em;
}
.threshold-box .big { font-size: 22px; font-weight: 800; letter-spacing: 0; }
.threshold-box .sub { font-weight: 500; color: var(--text-sub); font-size: 12px; }
.threshold-box.lt1 { background: #f0fdf4; color: #15803d; }
.threshold-box.lt2 { background: #fef2f2; color: #b91c1c; }

/* Zone-strip: 8 gekleurde blokjes Z0–Z7 */
.zone-strip { display: flex; gap: 3px; }
.zone-strip span { height: 8px; flex: 1; border-radius: 2px; }

/* ===== Tabellen ===== */
table.data { width: 100%; border-collapse: collapse; }
table.data th {
  text-align: left;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-sub);
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
table.data td { padding: 10px 12px; border-bottom: 1px solid var(--border); }
table.data tr:last-child td { border-bottom: none; }
table.data tr:hover td { background: #faf8f3; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
/* Numerieke kopcellen boven hun rechts-uitgelijnde waarden: anders staat de kop links
   (table.data th wint qua specificiteit van .num) en lijnt niets meer uit. */
table.data th.num { text-align: right; }
/* De zones-tabel toont tempo-/hartslagbereiken (bv. "05:18 – 04:45"); die ogen mooier
   gecentreerd dan rechts uitgelijnd. Kop én waarde centreren zodat ze op één lijn staan. */
table.data.zones th.num,
table.data.zones td.num { text-align: center; }
.table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Zone-tabel met gekleurde rijen */
.zone-row td:first-child { font-weight: 600; }
.zone-anchor { font-weight: 700; }

/* ===== Formulieren & knoppen ===== */
label { display: block; font-size: 12px; font-weight: 600; color: var(--text-sub); margin-bottom: 4px; }
input[type=text], input[type=date], input[type=number], input[type=password], input[type=search], select, textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font: inherit;
  background: #fff;
  color: var(--text-main);
}
input:focus, select:focus, textarea:focus {
  border-color: var(--primary);
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}
.field { margin-bottom: 14px; }
.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 18px; }
.form-grid.compact { gap: 0 14px; }
@media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--text-main);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.btn:hover { background: var(--app-bg); text-decoration: none; }
.btn.primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn.primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); }
.btn.danger { color: var(--red); border-color: #fecaca; }
.btn.danger:hover { background: #fef2f2; }
.btn.sm { padding: 6px 11px; font-size: 13px; }
/* Lijnicoon in een knop, in dezelfde maat als de sidebar-CTA. Zonder deze regel rekt een
   inline <svg> uit tot zijn intrinsieke maat en breekt de knop. */
.btn svg { width: 15px; height: 15px; flex-shrink: 0; }
/* Uitgeschakeld: overal herkenbaar inactief, niet enkel op de testdag. Een primaire knop
   verliest bovendien zijn rood, zodat een uitgeschakelde hoofdactie niet als een klaarstaande
   knop leest — de stijlgids vraagt dit al, alleen ontbrak de visuele afdwinging. */
.btn:disabled, .btn[disabled] { opacity: .55; cursor: not-allowed; }
.btn.primary:disabled, .btn.primary[disabled],
.btn.primary:disabled:hover, .btn.primary[disabled]:hover {
  background: var(--accent-neutral); border-color: var(--accent-neutral);
}

.validation-summary-errors, .field-validation-error { color: var(--red); font-size: 13px; }
.input-validation-error { border-color: var(--red); }

/* ===== Toast ===== */
.toast {
  position: fixed;
  right: 24px;
  bottom: 24px;
  background: var(--text-main);
  color: #fff;
  padding: 12px 18px;
  border-radius: 12px;
  font-weight: 500;
  box-shadow: 0 8px 24px rgba(15, 23, 42, .25);
  animation: toast-in .25s ease-out;
  z-index: 950;
}
body:has(.feedback-btn) .toast { bottom: 78px; }

/* Toegankelijk tekstalternatief voor interactieve canvasgrafieken. */
.chart-data { margin-top: 10px; }
.chart-data summary { color: var(--text-sub); cursor: pointer; font-size: 12px; font-weight: 700; }
.chart-data[open] summary { margin-bottom: 10px; }
.chart-data .table-scroll { overflow-x: auto; }
.chart-data table.data { font-size: 12px; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
@keyframes toast-in { from { transform: translateY(10px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }

/* ===== Login ===== */
/* ===== Openbare pagina's =====
   Landing, aanmelden, privacy en de foutpagina delen één wereld: donker navy met rood, net als
   offline.html. Dat zijn de schermen die iemand ziet vóór hij binnen is, en ze horen bij elkaar te
   passen. Binnen de app blijft alles gewoon licht — deze regels hangen aan .public, dat enkel in de
   niet-aangemelde tak van de layout staat.

   De landings- en aanmeldpagina brengen hun eigen verloop mee en schilderen hier gewoon overheen;
   voor de rest is dit de ondergrond. */
.public {
  min-height: 100vh;
  color: var(--side-text);
  background:
    radial-gradient(ellipse at 15% 10%, var(--navy-2), transparent 55%),
    radial-gradient(ellipse at 95% 90%, var(--navy), transparent 55%),
    var(--navy-deep);
}

/* Een leesbaar document op die ondergrond: de kaart uit de app is wit en zou hier een gat slaan. */
.public .card {
  background: rgba(255, 255, 255, .05);
  border-color: rgba(255, 255, 255, .12);
  box-shadow: none;
}
.public .page-head { padding: var(--sp-6) var(--sp-5) 0; max-width: 860px; margin: 0 auto; }
.public .page-head h1 { color: var(--side-text); }
.public .page-sub, .public .muted { color: var(--side-sub); }
.public .section { color: var(--side-text); }
.public a { color: var(--side-text); }
.public a:hover { color: var(--primary); }

/* De inhoud zelf krijgt dezelfde marge als de kop, zodat een document niet tegen de rand plakt. */
.public > .card,
.public > .doc { max-width: 860px; margin: var(--sp-5) auto var(--sp-6); }
@media (max-width: 900px) {
  .public > .card,
  .public > .doc { margin-left: var(--sp-4); margin-right: var(--sp-4); }
  .public .page-head { padding: var(--sp-5) var(--sp-4) 0; }
}

/* ===== Aanmelden =====
   Dezelfde donkere wereld als de landingspagina en offline.html. Dat zijn de drie schermen die
   iemand ziet vóór hij binnen is; stond dit er als lichte kaart tussen, dan leest het aanmelden als
   een ander product dan de pagina waar je net vandaan kwam. */
.login-wrap {
  min-height: 100vh; display: grid; place-items: center;
  padding: var(--sp-5) var(--sp-4);
  color: var(--side-text);
  background:
    radial-gradient(ellipse at 15% 10%, var(--navy-2), transparent 55%),
    radial-gradient(ellipse at 95% 90%, var(--navy), transparent 55%),
    var(--navy-deep);
}
.login-card { width: min(380px, calc(100vw - 32px)); }

/* Het paneel deelt zijn opmaak met dat op de landingspagina. */
.login-card .card {
  padding: var(--sp-5);
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: var(--radius-sm);
  box-shadow: none;
}
.login-card .card h1 { font-size: var(--fs-page); }
.login-card .page-sub, .login-card .login-help { color: var(--side-sub); }
.login-card .login-help a { color: var(--side-text); }

/* Invulvelden op een donkere ondergrond: het lichte veld uit de app valt hier als een gat. */
.login-card label { color: var(--side-text); }
.login-card input[type="text"], .login-card input[type="password"] {
  background: rgba(255, 255, 255, .07);
  border-color: rgba(255, 255, 255, .16);
  color: var(--side-text);
}
.login-card input:focus {
  border-color: var(--primary);
  background: rgba(255, 255, 255, .1);
}

/* ===== Empty state ===== */
/* Lege toestand: icoon, wat er ontbreekt, wat je eraan kunt doen. Die drie delen stonden in negen
   varianten door de app (iconen van 26 tot 50 px, titels van 15 of 16, soms geen titel), telkens
   met inline stijlen. Hier één keer, zodat een nieuwe lege toestand niets hoeft te bedenken. */
.empty { color: var(--text-sub); text-align: center; padding: 32px 0; }
/* Het icoon is beeld en geen tekst, maar het deelt de maat van het cijfer in een statkaart: dat
   houdt de pagina rustig en scheelt een achtste getal in de schaal. De titel is gewone tekst met
   gewicht — 15px was een strooiwaarde die nergens anders voorkwam. */
.empty .icon { font-size: var(--fs-stat); margin-bottom: var(--sp-2); }
/* Lijnicoon i.p.v. emoji: emoji renderen per toestel anders en botsen met de nav-iconen.
   Zelfde maat als het cijfer in een statkaart, in de gedempte bijschriftkleur. */
.empty .icon svg, .state-icon svg { width: var(--fs-stat); height: var(--fs-stat); }
.state-icon { display: block; color: var(--accent-neutral); margin-bottom: var(--sp-2); line-height: 0; }
.empty .icon svg { color: var(--accent-neutral); }
.empty strong { display: block; color: var(--text-main); font-size: var(--fs-body); font-weight: 700; margin-bottom: var(--sp-1); }

@media (max-width: 860px) {
  .app { flex-direction: column; }
  .sidebar { width: 100%; height: auto; position: static; }
  .sidebar-toggle { display: inline-flex; align-items: center; justify-content: center; }
  .sidebar-nav { display: flex; flex-wrap: wrap; gap: 2px 4px; padding: 4px 8px; }
  .sidebar.sidebar-collapsible:not(.nav-open) .sidebar-nav,
  .sidebar.sidebar-collapsible:not(.nav-open) .sidebar-cta,
  .sidebar.sidebar-collapsible:not(.nav-open) .sidebar-user { display: none; }
  .nav-heading { width: 100%; padding: 8px 14px 2px; }
  .nav-link { border-left: none; border-radius: 8px; padding: 8px 12px; }
  .side-menu { position: static; margin-top: 6px; }
  .side-menu.up { bottom: auto; }
  .main { padding: 18px; }
}
@media (max-width: 700px) {
  .card:has(> table.data) { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .card > table.data { min-width: 620px; }
}

/* ===== Testdag ===== */
.testday-setup-wrap { max-width:680px; }
.testday-setup-card { padding:22px; }
.testday-date-field { max-width:180px; }
.testday-group-filters { display:flex; flex-wrap:wrap; gap:8px; margin:16px 0 10px; }
.testday-filter { padding:5px 12px; border:1px solid var(--border); border-radius:99px; background:#fff; color:var(--text); font:inherit; font-size:12px; font-weight:600; cursor:pointer; }
.testday-filter:hover,.testday-filter.active { border-color:var(--primary); color:var(--primary); background:var(--primary-soft); }
.testday-queue { border:0; padding:0; margin:8px 0 0; }
.testday-queue-row { display:grid; grid-template-columns:20px max-content 1fr; align-items:center; gap:8px; min-height:42px; padding:6px 10px; border-radius:8px; cursor:pointer; }
.testday-queue-row:hover { background:var(--primary-soft); }
.testday-queue-row input { width:16px; height:16px; margin:0; }
.testday-queue-row strong { font-size:13px; }
.testday-queue-row span { color:var(--text-sub); font-size:12px; }
.testday-start-actions { display:flex; align-items:center; gap:12px; margin-top:18px; }
.testday-start-actions span { color:var(--text-sub); font-size:12px; }
.testday-start-actions .btn:disabled { opacity:.48; cursor:not-allowed; }
.testday-previous { margin-top:16px; color:var(--text-sub); font-size:13px; }
.testday-previous summary { cursor:pointer; font-weight:600; }
.testday-previous .card { margin-top:9px; padding:10px; }
.testday-start-grid { display:grid; grid-template-columns:minmax(0,1.35fr) minmax(280px,.65fr); gap:20px; align-items:start; }
.testday-athlete-picker { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; max-height:380px; overflow:auto; }
.testday-athlete-picker label { display:flex; align-items:center; gap:9px; padding:10px; border:1px solid var(--border); border-radius:9px; cursor:pointer; }
.testday-athlete-picker label:has(input:checked) { border-color:var(--primary); background:var(--primary-soft); }
.testday-athlete-picker small,.testday-session-list small { display:block; color:var(--text-sub); margin-top:2px; }
.testday-session-list { display:grid; gap:8px; }
.testday-session-list a { display:flex; justify-content:space-between; align-items:center; gap:10px; padding:12px; border:1px solid var(--border); border-radius:9px; color:inherit; text-decoration:none; }
.testday-session-list a:hover { border-color:var(--primary); }
.testday-session-wrap { max-width:1180px; }
.testday-session-title { margin-bottom:14px; }
.testday-session-overview { display:grid; grid-template-columns:auto minmax(180px,1fr) auto; align-items:center; gap:14px; padding:16px 20px; margin-bottom:18px; }
.testday-session-overview > span { color:var(--text-sub); font-size:12px; }
.testday-total-progress { width:100%; height:9px; border-radius:99px; overflow:hidden; background:var(--border); }
.testday-total-progress span { display:block; height:100%; background:var(--green); }
.testday-board { display:grid; grid-template-columns:1fr; gap:16px; align-items:start; }
.testday-card { padding:20px; }
.testday-athlete-header { display:grid; grid-template-columns:auto minmax(180px,1fr) auto auto; align-items:center; gap:12px; margin-bottom:14px; }
.testday-athlete-name h2 { font-size:17px; margin:0 0 2px; }
.testday-athlete-name span,.testday-athlete-count { color:var(--text-sub); font-size:12px; }
.testday-card.done { border-color:#86c99a; background:#fbfffc; }
.testday-step-dots { display:flex; gap:6px; margin-bottom:16px; }
.testday-step-dots span { height:7px; flex:1; border-radius:9px; background:var(--border); }
.testday-step-dots .complete { background:var(--green); }
.testday-step-dots .current { background:var(--primary); }
.testday-current-form { padding-top:2px; }
.testday-current-form h3 { margin:12px 0 8px; font-size:14px; }
.testday-pretest { max-width:260px; margin-bottom:16px; }
.testday-pretest small { color:var(--text-sub); font-size:11px; }
.testday-step-grid { display:grid; grid-template-columns:34px 95px 90px 110px 82px 82px 120px minmax(130px,1fr) auto; align-items:end; gap:8px; }
.testday-step-grid .field { min-width:0; }
.testday-step-grid .field label { font-size:10.5px; white-space:nowrap; }
.testday-step-grid input { width:100%; min-width:0; height:36px; padding:7px 9px; }
.testday-step-grid .step-number span { display:flex; height:36px; align-items:center; justify-content:center; color:var(--text-sub); font-weight:700; }
.testday-step-grid .step-save { height:36px; white-space:nowrap; }
.testday-measured-steps { margin-top:14px; border-top:1px solid var(--border); padding-top:12px; }
.testday-measured-steps summary { color:var(--primary); cursor:pointer; font-size:12px; font-weight:700; }
.testday-history-scroll { overflow-x:auto; margin-top:9px; }
.testday-history-scroll table { width:100%; border-collapse:collapse; font-size:12px; }
.testday-history-scroll th,.testday-history-scroll td { padding:7px 9px; border-bottom:1px solid var(--border); text-align:left; white-space:nowrap; }
.testday-history-scroll th { color:var(--text-sub); font-size:10px; text-transform:uppercase; }
.testday-card-actions { display:flex; justify-content:flex-end; margin-top:12px; }
@media (max-width:1000px) { .testday-step-grid { grid-template-columns:34px repeat(3,minmax(90px,1fr)); } .testday-step-grid .step-note { grid-column:2/-1; } .testday-step-grid .step-save { grid-column:1/-1; } }
@media (max-width:800px) { .testday-start-grid { grid-template-columns:1fr; } .testday-athlete-picker { grid-template-columns:1fr; } .testday-session-overview { grid-template-columns:1fr; } .testday-athlete-header { grid-template-columns:auto 1fr auto; } .testday-athlete-count { grid-column:2; } .testday-start-actions { align-items:flex-start; flex-direction:column; } }
@media (max-width:560px) { .testday-step-grid { grid-template-columns:34px 1fr 1fr; } .testday-step-grid .step-note { grid-column:2/-1; } }

/* Wachtrij van de testdag */
.testday-progress-card { padding:16px 20px; margin-bottom:18px; }
.testday-progress-row { display:grid; grid-template-columns:auto minmax(120px,1fr) auto; align-items:center; gap:16px; }
.testday-progress-row > strong { white-space:nowrap; }
.testday-progress-actions { display:flex; align-items:center; gap:8px; }
.testday-progress-card small { display:block; margin-top:10px; color:var(--text-sub); font-size:12px; }
.testday-queue-list { list-style:none; margin:0; padding:0; display:grid; gap:10px; }
.testday-queue-item { display:grid; grid-template-columns:auto minmax(0,1fr) auto auto auto; align-items:center; gap:12px; padding:14px 16px; }
.testday-queue-item.in-group { border-left:3px solid var(--primary); }
.testday-queue-item.done { grid-template-columns:auto minmax(0,1fr) auto auto; border-color:#86c99a; background:#fbfffc; }
.testday-done-hint { margin-top:10px; color:var(--text-sub); font-size:12px; }
.testday-queue-number { display:flex; width:26px; height:26px; align-items:center; justify-content:center; border-radius:99px; background:var(--primary-soft); color:var(--primary); font-size:12px; font-weight:800; }
.testday-queue-check { color:var(--green); font-weight:800; }
.testday-queue-who strong { display:block; font-size:14px; }
.testday-queue-who span { color:var(--text-sub); font-size:12px; }
.testday-queue-remove { border:0; background:none; color:var(--text-sub); font-size:20px; line-height:1; cursor:pointer; padding:0 4px; }
.testday-queue-remove:hover { color:var(--primary); }
.testday-queue-empty { padding:20px; color:var(--text-sub); text-align:center; }
.testday-done-heading { margin:24px 0 10px; font-size:13px; text-transform:uppercase; letter-spacing:.06em; color:var(--text-sub); }

/* ===== Groepstest: één invoertabel voor de hele groep ===== */
.grouptest-wrap { max-width:1240px; }
.grouptest-meta { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto; align-items:end; gap:16px; padding:18px 20px; margin-bottom:14px; }
.grouptest-meta .field { max-width:260px; }
.grouptest-count { color:var(--text-sub); font-size:12px; }
.grouptest-chips { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:14px; }
.grouptest-chip { padding:5px 13px; border-radius:99px; background:var(--primary); color:#fff; font-size:12px; font-weight:700; }
.grouptest-table-card { padding:16px 18px; }
.grouptest-scroll { overflow-x:auto; }
.grouptest-table { width:100%; border-collapse:collapse; }
.grouptest-table th { padding:8px 10px; color:var(--text-sub); font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; text-align:left; white-space:nowrap; }
.grouptest-table .grouptest-athlete-head { color:var(--text); font-size:13px; text-transform:none; letter-spacing:0; border-left:1px solid var(--border); text-align:center; }
.grouptest-table tbody td { padding:5px 6px; }
.grouptest-table .col-step { width:52px; color:var(--text-sub); font-weight:700; }
.grouptest-table .col-distance { width:110px; }
.grouptest-table input { width:100%; min-width:78px; height:36px; padding:7px 9px; text-align:center; }
.grouptest-table .col-distance input { min-width:92px; }
.grouptest-notes-row td { padding-top:12px; }
.grouptest-notes-label { color:var(--text-sub); font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; }
.grouptest-notes-row input { text-align:left; min-width:180px; }
.grouptest-step-actions { display:flex; gap:8px; margin-top:12px; }
.grouptest-actions { display:flex; align-items:center; gap:12px; margin-top:16px; }
.grouptest-actions small { color:var(--text-sub); font-size:12px; }
.grouptest-save { background:var(--green); border-color:var(--green); color:#fff; font-weight:700; }
.grouptest-save:hover { background:#28855b; border-color:#28855b; color:#fff; }
@media (max-width:800px) { .grouptest-meta { grid-template-columns:1fr; } .grouptest-actions { align-items:flex-start; flex-direction:column; } .testday-progress-row { grid-template-columns:1fr; } .testday-queue-item { grid-template-columns:auto minmax(0,1fr) auto; } }

/* ===== Wizard ===== */
.wizard-wrap { max-width: 860px; margin: 0 auto; }
.wizard-wrap > h1 { margin-bottom: 8px; }
.wizard-back { display: inline-flex; align-items: center; gap: 6px; color: var(--primary); font-weight: 600; font-size: 13px; margin-bottom: 20px; background: none; border: none; cursor: pointer; padding: 0; }
.wizard-back:hover { text-decoration: underline; }

.wizard-nav { display: flex; align-items: center; margin-bottom: 28px; }
.wz-step { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.wz-step .circle {
  width: 36px; height: 36px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 14px;
  background: var(--border); color: var(--text-sub);
  border: 2px solid var(--border); transition: background .2s, border-color .2s;
}
.wz-step.active .circle { background: var(--primary); border-color: var(--primary); color: #fff; }
.wz-step.done .circle   { background: var(--green);   border-color: var(--green);   color: #fff; }
.wz-step .label { font-size: 11px; font-weight: 600; color: var(--text-sub); text-transform: uppercase; letter-spacing: .05em; white-space: nowrap; }
.wz-step.active .label { color: var(--primary); }
.wz-step.done   .label { color: var(--green); }
.wz-line { flex: 1; height: 2px; background: var(--border); margin-bottom: 22px; transition: background .2s; }
.wz-line.done { background: var(--primary); }

.wizard-panel { display: block; margin-top: 16px; }
.wizard-wrap.is-enhanced .wizard-panel { display: none; margin-top: 0; }
.wizard-wrap.is-enhanced .wizard-panel.active { display: block; }

/* Radio selection cards */
.rc-group { display: grid; gap: 10px; }
.rc-card {
  display: flex; align-items: center; gap: 16px;
  padding: 14px 18px;
  border: 1.5px solid var(--border); border-radius: 12px;
  cursor: pointer; transition: border-color .15s, background .15s;
  user-select: none;
}
.rc-card:hover { border-color: var(--primary); }
.rc-card.sel { border-color: var(--primary); background: var(--primary-soft); }
.rc-fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
.rc-card input[type=radio] {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap;
}
.rc-card:has(input[type=radio]:focus-visible) {
  outline: 2px solid var(--primary); outline-offset: 2px;
}
.rc-icon { font-size: 20px; width: 32px; text-align: center; flex-shrink: 0; }
.rc-body { flex: 1; }
.rc-body strong { display: block; font-size: 14px; font-weight: 700; }
.rc-body span { font-size: 12px; color: var(--text-sub); }
.rc-dot {
  width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--border); flex-shrink: 0; transition: border-color .15s, box-shadow .15s;
}
.rc-card.sel .rc-dot { border-color: var(--primary); box-shadow: inset 0 0 0 4px #fff, inset 0 0 0 9px var(--primary); }

/* Athlete radio cards with avatar */
.rc-card .avatar { flex-shrink: 0; }

/* Tab row for athlete step */
.tab-row { display: flex; gap: 6px; margin-bottom: 16px; }
.tab-btn { padding: 8px 18px; border-radius: 8px; border: 1px solid var(--border); background: #fff; font: inherit; font-size: 13px; font-weight: 600; color: var(--text-sub); cursor: pointer; }
.tab-btn.active { background: var(--primary); border-color: var(--primary); color: #fff; }
.tab-pane { display: none; }
.tab-pane.active { display: block; }

/* Steps entry table */
.steps-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.steps-tbl th {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-sub); padding: 8px 5px 8px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.steps-tbl td { padding: 3px 3px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.steps-tbl tr:last-child td { border-bottom: none; }
.steps-tbl input { padding: 6px 7px; font-size: 12px; border-radius: 7px; }
.steps-tbl .sn { width: 28px; text-align: center; font-weight: 700; color: var(--text-sub); font-size: 13px; }
.steps-tbl .del-btn { background: none; border: none; color: var(--text-sub); cursor: pointer; font-size: 16px; padding: 0 4px; line-height: 1; }
.steps-tbl .del-btn:hover { color: var(--red); }

/* ===== Beta-feedback (zwevende knop + teken-overlay) ===== */
.feedback-btn {
  position: fixed; bottom: 20px; right: 20px; z-index: 900;
  background: var(--navy); color: #fff; border: none; border-radius: 999px;
  padding: 11px 18px; font-family: var(--font); font-size: 13.5px; font-weight: 700;
  cursor: pointer; box-shadow: 0 4px 14px rgba(22,50,78,.35);
  display: inline-flex; align-items: center; gap: 7px;
}
.sidebar-toggle {
  display: none; margin-left: auto; width: 40px; height: 40px;
  border: 1px solid rgba(255,255,255,.25); border-radius: 8px;
  background: transparent; color: #fff; font: inherit; font-size: 20px; cursor: pointer;
}
.feedback-btn:hover { background: var(--navy-2); }
.feedback-btn svg { width: 16px; height: 16px; flex-shrink: 0; }

.fb-overlay {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(15,23,42,.55); backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center; padding: 18px;
}
.fb-panel {
  background: #fff; border-radius: 16px; box-shadow: 0 20px 60px rgba(0,0,0,.3);
  width: min(960px, 96vw); max-height: 94vh; display: flex; flex-direction: column;
  padding: 16px 18px; gap: 10px;
}
.fb-overlay[aria-hidden="true"] { display: none; }
.fb-head { display: flex; align-items: baseline; gap: 10px; }
.fb-head strong { font-size: 16px; }
.fb-hint { font-size: 12px; color: var(--text-sub); }
.fb-close {
  margin-left: auto; background: #f1f5f9; border: none; border-radius: 8px;
  width: 30px; height: 30px; font-size: 16px; cursor: pointer; color: #64748b;
}
.fb-tools { display: flex; gap: 6px; flex-wrap: wrap; }
.fb-tools button {
  background: #f1f5f9; border: 1px solid var(--border); border-radius: 8px;
  padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer; color: var(--text-main);
}
.fb-tools .fb-tool.active { background: var(--navy); border-color: var(--navy); color: #fff; }
.fb-canvas-wrap { overflow: auto; border: 1px solid var(--border); border-radius: 10px; background: #f8fafc; }
.fb-canvas-wrap canvas { display: block; width: 100%; height: auto; cursor: crosshair; touch-action: none; }
.fb-comment {
  width: 100%; box-sizing: border-box; border: 1.5px solid var(--border); border-radius: 8px;
  padding: 9px 12px; font-family: var(--font); font-size: 14px; resize: vertical;
}
.fb-consent { display: flex; align-items: flex-start; gap: 8px; color: var(--text-main); }
.fb-consent input { margin-top: 3px; flex: 0 0 auto; }
.fb-consent small { display: block; color: var(--text-sub); font-weight: 400; }
.fb-actions { display: flex; justify-content: flex-end; gap: 8px; }
.fb-actions button {
  border-radius: 8px; padding: 9px 18px; font-size: 14px; font-weight: 600; cursor: pointer;
  font-family: var(--font);
}
.fb-cancel { background: #f1f5f9; border: 1px solid var(--border); color: var(--text-main); }
.fb-send { background: var(--primary); border: 1px solid var(--primary); color: #fff; }
.fb-send:disabled { opacity: .6; cursor: default; }

.stat-hero.five-cols { grid-template-columns: repeat(5, 1fr); }
.grid.cols-5 { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 1000px) {
  .stat-hero.five-cols, .grid.cols-5 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .stat-hero.five-cols, .grid.cols-5 { grid-template-columns: 1fr; }
  .wizard-nav { overflow-x: auto; padding-bottom: 4px; }
  .wizard-panel { padding: 16px; }
}

/* ── Meldingen-dropdown (dashboard-topbar) ────────────────────────── */
.notif-wrap { position: relative; }
.notif-btn {
  position: relative; background: #fff; border: 1px solid var(--border);
  border-radius: 9px; width: 40px; height: 40px; display: flex;
  align-items: center; justify-content: center; color: var(--navy); cursor: pointer;
}
.notif-btn:hover { background: #faf8f3; }
.notif-badge {
  position: absolute; top: -5px; right: -5px; background: var(--red); color: #fff;
  font-size: 10px; font-weight: 800; border-radius: 100px; min-width: 16px; height: 16px;
  display: flex; align-items: center; justify-content: center; padding: 0 3px;
}
.notif-panel {
  position: absolute; right: 0; top: 46px; width: 300px; max-width: 84vw;
  max-height: 70vh; overflow-y: auto; background: #fff; border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 12px 32px rgba(15, 23, 42, .16); padding: 8px; z-index: 60;
}
.notif-panel[hidden] { display: none; }
.notif-head {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-sub); padding: 8px 10px 6px;
}
.notif-empty { padding: 10px; color: var(--text-sub); font-size: 13px; }
.notif-item {
  display: flex; align-items: flex-start; gap: 10px; padding: 9px 10px;
  border-radius: 8px; text-decoration: none; color: var(--text-main);
}
.notif-item:hover { background: #faf8f3; }
.notif-ic { font-size: 15px; line-height: 1.3; flex-shrink: 0; }
.notif-txt { display: flex; flex-direction: column; font-size: 13px; line-height: 1.35; }
.notif-txt strong { font-weight: 700; }
.notif-sub { color: var(--text-sub); font-size: 12px; }

/* ===== Wedstrijdkalender (Uitslagen) =====
   Wat eraan komt en wat gelopen is, staan onder elkaar op één pagina. Ze horen dus ook één vorm
   te hebben: dezelfde sectiekop, dezelfde wedstrijdkaart, dezelfde eerste kolom met de atleet.
   Stonden eerst als losse inline-stijlen in de view, elk net iets anders — met een datumkolom in
   de ene die de wedstrijdnaam over drie regels brak, en een kaartkop in de andere die dat niet
   deed. */
.cal-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--sp-3); flex-wrap: wrap; margin: var(--sp-5) 0 var(--sp-3);
}
.cal-head:first-of-type { margin-top: var(--sp-1); }
.cal-head h2 {
  font-family: var(--font-display); font-size: var(--fs-section); font-weight: 700; margin: 0;
}
.cal-head .range { font-family: inherit; font-size: var(--fs-meta); font-weight: 400; color: var(--text-sub); }
.cal-head .meta { color: var(--text-sub); font-size: var(--fs-meta); }

/* De ouderdom van de gegevens hoort bij de kop, niet bij de eerste wedstrijd eronder. */
.cal-note { margin: -4px 0 var(--sp-3); font-size: var(--fs-meta); color: var(--text-sub); }
.cal-note.stale { color: var(--stale-ink); }

.comp-card + .comp-card { margin-top: var(--sp-3); }
.comp-card .chead {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--sp-3); flex-wrap: wrap;
}
/* De naam mag de breedte nemen die ze nodig heeft; de datum schuift erachteraan in plaats van
   haar in een kolom te persen. */
.comp-card .chead .cname { font-weight: 700; }
.comp-card .chead .cwhen { color: var(--text-sub); font-size: var(--fs-meta); }
.comp-card .chead .ccount { color: var(--text-sub); font-size: var(--fs-meta); white-space: nowrap; }
.comp-card table.data { margin-top: var(--sp-2); }
/* Eén breedtebeleid voor beide tabellen: de atleet vooraan zo smal als zijn naam, het onderdeel
   ernaast, en wat daarna komt tegen de rechterrand. Zo staan uitslagen en inschrijvingen onder
   elkaar in dezelfde kolommen. */
/* Vaste ondergrens voor de naamkolom: elke wedstrijd is een eigen tabel, dus zonder deze breedte
   begint het onderdeel in elke kaart op een andere plek en oogt de pagina rafelig. Een langere
   naam duwt zijn eigen kaart gerust breder — dat is beter dan afkappen. */
.comp-card table.data td.who { white-space: nowrap; min-width: 190px; }
.comp-card table.data td.what { white-space: nowrap; min-width: 130px; }
.comp-card table.data td.val { font-family: var(--mono); font-weight: 700; white-space: nowrap; }
.comp-card table.data td.flags { white-space: nowrap; width: 1px; }
.comp-card table.data td.place { font-size: var(--fs-meta); color: var(--text-sub); }
/* De kolom die de rest opeet, zodat alles ervóór tegen elkaar staat en niet uitgesmeerd wordt. */
.comp-card table.data td.fill { width: 100%; }
.comp-card table.data td.unknown { color: var(--text-sub); font-style: italic; }

/* ===== Papier =====
   Het testrapport regelt zijn eigen printopmaak (het staat los van deze layout). Elk ánder scherm
   erft wat hier staat, en dat was tot nu toe niets: wie op Uitslagen of een groepslijst Ctrl+P
   drukte, kreeg de navy zijbalk, de navigatie en de feedbackknop mee op papier.
   Geen printontwerp per scherm — enkel het chroom weg, de inkt zwart en tabellen niet over een
   paginagrens laten breken. */
@media print {
  :root { --app-bg: #fff; --card-bg: #fff; }
  body { background: #fff; }
  .sidebar, .feedback-btn, .fb-panel, .toast, .skip-link, .sidebar-toggle,
  .rowmenu, .quick-caret, .notif-panel { display: none !important; }
  .app { display: block; }
  .main { max-width: none; padding: 0; }
  .card { border: 1px solid #d5d5d5; box-shadow: none; break-inside: avoid; }
  /* Een tabel die over twee bladen valt verliest haar kop; die herhalen we. */
  table.data thead { display: table-header-group; }
  table.data tr { break-inside: avoid; }
  h1, h2 { break-after: avoid; }
  /* Een link naar een scherm heeft op papier geen nut, maar de tekst moet leesbaar blijven. */
  a { color: inherit; text-decoration: none; }
  /* Badges dragen betekenis; zonder kleurbehoud vallen PR en SB samen. */
  .badge { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ===== Planner: subtabs (Week / Lijst / Rooster) ===== */
.subtabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 18px; flex-wrap: wrap; }
.subtab {
  padding: 8px 14px; font-size: var(--fs-dense); text-decoration: none; font-weight: 500;
  color: var(--text-sub); border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.subtab.active { font-weight: 700; color: var(--primary); border-bottom-color: var(--primary); }
.subtab:hover { color: var(--text-main); text-decoration: none; }

/* ===== Planner: rooster-weekbord (atleten × dagen) ===== */
.roster-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: 12px; background: var(--card-bg); }
.roster { border-collapse: separate; border-spacing: 0; width: 100%; min-width: 780px; }
.roster th, .roster td { border-bottom: 1px solid var(--border); vertical-align: top; padding: 8px; }
.roster tr:last-child td { border-bottom: none; }
.roster thead th {
  position: sticky; top: 0; z-index: 2; background: var(--app-bg);
  font-size: var(--fs-label); text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-sub); font-weight: 700; text-align: center; padding: 10px 8px; white-space: nowrap;
}
.roster thead th .rr-day { display: block; font-family: var(--mono); font-size: var(--fs-meta); color: var(--text-main); }
.roster .rr-name { position: sticky; left: 0; z-index: 1; background: var(--card-bg);
  text-align: left; min-width: 148px; box-shadow: 1px 0 0 var(--border); }
.roster thead th.rr-name { z-index: 3; }
.roster td.rr-today { background: var(--primary-soft); }
.roster tr.rr-grouphead th {
  background: var(--app-bg); text-align: left; font-weight: 700; padding: 7px 10px;
  font-size: var(--fs-label); text-transform: uppercase; letter-spacing: .06em; color: var(--text-sub);
}
.rr-athlete { font-weight: 600; font-size: var(--fs-dense); color: var(--text-main); text-decoration: none; }
.rr-athlete:hover { color: var(--primary); text-decoration: none; }
.rr-athlete .rr-sub { display: block; font-size: var(--fs-label); color: var(--text-sub); font-weight: 500; }
.rr-cell { display: flex; flex-direction: column; gap: 4px; min-height: 34px; }
.rr-chip { display: block; text-decoration: none; border-radius: 8px; padding: 4px 7px; border: 1px solid transparent; line-height: 1.3; }
.rr-chip .rr-t { font-size: var(--fs-label); font-weight: 700; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rr-chip .rr-meta { display: block; font-weight: 500; font-size: var(--fs-label); color: var(--text-sub); }
.rr-chip.rr-group { border-style: dashed; }
.rr-add {
  display: block; text-align: center; text-decoration: none; color: var(--text-sub);
  border: 1px dashed var(--border); border-radius: 7px; padding: 2px 0; font-size: var(--fs-dense);
}
.rr-add:hover { color: var(--primary); border-color: var(--primary); text-decoration: none; }
.rr-att { font-size: var(--fs-label); color: var(--text-sub); margin-top: 2px; }
/* "Geen plan" — subtiele markering voor een atleet zonder training deze week. Bewust geen felle
   rand of achtergrondkleur: het is een geheugensteun, geen fout. */
.roster tr.rr-blank td.rr-name { border-left: 3px solid var(--warn); }
.rr-badge {
  display: inline-block; margin-left: var(--sp-1);
  padding: 1px 6px; border-radius: 4px;
  background: var(--warn-soft); color: var(--warn-ink);
  font-size: var(--fs-label); font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase;
}
/* Afwijkers-teller op de clubbrede rij: kleine chip "3 ≠" onder de groepschip. Coach ziet meteen
   waar er individuele uitzonderingen bestaan zonder de rijen te moeten scannen. */
.rr-deviant {
  display: inline-block; padding: 1px 6px; border-radius: 4px;
  background: var(--card-bg); border: 1px dashed var(--border);
  color: var(--text-sub); font-size: var(--fs-label); font-weight: 600;
  align-self: flex-start;
}
/* "Wijk af"-knop: bewust een andere presentatie dan de gewone "+" om het onderscheid tussen
   "een clubbrede sessie toevoegen" en "een individuele uitzondering maken" niet aan intuïtie
   over te laten. */
.rr-deviate {
  color: var(--warn-ink); border-color: var(--warn-ink); border-style: dashed;
  font-weight: 600;
}
.rr-deviate:hover { color: var(--warn-ink); border-color: var(--warn-ink); background: var(--warn-soft); }

/* Wedstrijden — automatisch uit Athletics.app-inschrijvingen. Bewust rood/paars als aparte
   visuele klasse: een wedstrijd is geen training, en de coach mag ze op geen enkel moment door
   elkaar halen op het rooster. */
.rr-chip.rr-competition {
  background: var(--danger-soft); border-color: var(--primary);
  border-style: solid; cursor: default;
}
.rr-chip.rr-competition .rr-t { color: var(--danger-ink); }

/* Km-meter — "gelopen / gepland km" per atleet per week. Kleur zegt zonder rekenen hoe dicht
   het volume bij het plan zit. Neutraal (geen tint) wanneer er niets gepland is: dan is er ook
   geen norm om aan af te meten. */
.rr-km {
  display: inline-block; margin-left: var(--sp-2);
  padding: 1px 6px; border-radius: 4px;
  font-family: var(--mono); font-size: var(--fs-label); font-weight: 600;
  background: var(--card-bg); border: 1px solid var(--border);
  color: var(--text-sub); white-space: nowrap;
}
.rr-km .rr-km-sep { color: var(--text-sub); margin: 0 2px; opacity: 0.5; }
.rr-km .rr-km-planned { color: var(--text-sub); }
.rr-km.rr-km-ok { background: var(--ok-soft); border-color: var(--ok-border); color: var(--ok-ink); }
.rr-km.rr-km-ok .rr-km-planned { color: var(--ok-ink); opacity: 0.8; }
.rr-km.rr-km-warn { background: var(--warn-soft); border-color: var(--warn-ink); color: var(--warn-ink); }
.rr-km.rr-km-warn .rr-km-planned { color: var(--warn-ink); opacity: 0.8; }
.rr-km.rr-km-low { background: var(--danger-soft); border-color: var(--danger-ink); color: var(--danger-ink); }
.rr-km.rr-km-low .rr-km-planned { color: var(--danger-ink); opacity: 0.8; }

/* ── Portaal weekplanning ── */
.portal-link-icon { font-size: var(--fs-section); }
.portal-week {
  display: grid; gap: var(--sp-3);
}
.portal-day {
  background: var(--card-bg); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--sp-4);
}
.portal-day--today { border-color: var(--primary); border-width: 2px; }
.portal-day--empty { opacity: 0.7; }
.portal-day-head {
  display: flex; align-items: baseline; gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--border);
}
.portal-day-name {
  font-weight: 700; font-size: var(--fs-dense);
  text-transform: capitalize;
}
.portal-day-date { color: var(--text-sub); font-size: var(--fs-dense); }
.portal-day-badge {
  font-size: var(--fs-label); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--primary); margin-left: auto;
}
.portal-day-empty {
  color: var(--text-sub); font-size: var(--fs-dense);
  font-style: italic; padding: var(--sp-2) 0;
}
.portal-training {
  border: 1px solid; border-radius: var(--radius-sm);
  padding: var(--sp-3); margin-bottom: var(--sp-2);
}
.portal-training-type { font-weight: 800; font-size: var(--fs-dense); }
.portal-training-level {
  display: inline-block; font-size: var(--fs-label); font-weight: 600;
  color: var(--text-sub); text-transform: uppercase; letter-spacing: 0.06em;
  margin-top: 2px;
}
.portal-training-meta {
  display: flex; gap: var(--sp-3); flex-wrap: wrap;
  color: var(--text-sub); font-size: var(--fs-dense);
  margin-top: var(--sp-1);
}
.portal-training-desc {
  color: var(--text-sub); font-size: var(--fs-dense);
  margin-top: var(--sp-1); white-space: pre-line;
}
.portal-activities { margin-top: var(--sp-2); }
.portal-activity {
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--sp-2); flex-wrap: wrap;
  padding: var(--sp-2) var(--sp-3);
  background: var(--ok-soft); border: 1px solid var(--ok-border);
  border-radius: var(--radius-sm); margin-bottom: var(--sp-1);
  font-size: var(--fs-dense);
}
.portal-activity-name { font-weight: 600; color: var(--ok-ink); }
.portal-activity-stats {
  display: flex; gap: var(--sp-3);
  font-variant-numeric: tabular-nums;
  color: var(--text-sub);
}

/* Plan vs werkelijk — voortgangsbalk in weeksamenvatting */
.plan-actual { font-size: var(--fs-dense); font-weight: 700; margin-top: var(--sp-2); }
.plan-bar { height: 6px; border-radius: 3px; background: var(--border); margin-top: var(--sp-2); overflow: hidden; }
.plan-bar-fill { height: 100%; border-radius: 3px; transition: width .3s ease; }

/* ── Opvolgingstabel (compliance) ── */
.cp-table { width: 100%; border-collapse: collapse; font-size: var(--fs-dense); font-variant-numeric: tabular-nums; }
.cp-table th, .cp-table td { padding: var(--sp-2) var(--sp-3); text-align: center; border-bottom: 1px solid var(--border); }
.cp-table thead th { font-size: var(--fs-label); text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-sub); white-space: nowrap; }
.cp-name { text-align: left !important; white-space: nowrap; min-width: 140px; position: sticky; left: 0; background: var(--bg); z-index: 1; }
.cp-cell { display: flex; flex-direction: column; align-items: center; gap: 1px; padding: var(--sp-1); border-radius: 6px; }
.cp-pct { font-weight: 700; font-size: var(--fs-dense); }
.cp-km { font-size: var(--fs-label); color: var(--text-sub); white-space: nowrap; }
.cp-bar { width: 100%; height: 4px; border-radius: 2px; background: var(--border); margin-top: 2px; overflow: hidden; }
.cp-bar-fill { height: 100%; border-radius: 2px; }
.cp-ok { background: var(--ok-soft); }
.cp-ok .cp-pct { color: var(--ok-ink); }
.cp-ok .cp-bar-fill { background: var(--ok-ink); }
.cp-warn { background: var(--warn-soft); }
.cp-warn .cp-pct { color: var(--warn-ink); }
.cp-warn .cp-bar-fill { background: var(--warn-ink); }
.cp-low { background: var(--danger-soft); }
.cp-low .cp-pct { color: var(--danger-ink); }
.cp-low .cp-bar-fill { background: var(--danger-ink); }
.cp-avg { border: 1px solid var(--border); }
.cp-nodata, .cp-empty { color: var(--text-sub); opacity: 0.5; }
.cp-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 3px; vertical-align: middle; }
.cp-ok-dot { background: var(--ok-ink); }
.cp-warn-dot { background: var(--warn-ink); }
.cp-low-dot { background: var(--danger-ink); }

/* ── Seizoensperiode-balk ── */
.phase-bar { display: inline-flex; align-items: center; padding: 1px var(--sp-2); border-radius: 4px; font-size: var(--fs-label); font-weight: 600; letter-spacing: 0.03em; white-space: nowrap; }
.phase-basis { background: var(--info-soft); color: var(--info-ink); }
.phase-specifiek { background: var(--warn-soft); color: var(--warn-ink); }
.phase-wedstrijd { background: var(--danger-soft); color: var(--danger-ink); }
.phase-overgang { background: var(--ok-soft); color: var(--ok-ink); }

/* ── Doelwedstrijd-countdown ── */
.goal-pill { display: inline-flex; align-items: center; gap: var(--sp-1); padding: 2px var(--sp-2); border-radius: 12px; font-size: var(--fs-label); font-weight: 600; white-space: nowrap; }
.goal-pill-soon { background: var(--danger-soft); color: var(--danger-ink); }
.goal-pill-mid { background: var(--warn-soft); color: var(--warn-ink); }
.goal-pill-far { background: var(--info-soft); color: var(--info-ink); }

/* ── Weekrapport ── */
.wr-section { margin-bottom: var(--sp-6); }
.wr-section-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.wr-level { display: inline-flex; align-items: center; gap: var(--sp-1); padding: 2px var(--sp-2); border-radius: 4px; font-size: var(--fs-label); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }
.wr-intensief { background: var(--danger-soft); color: var(--danger-ink); }
.wr-standaard { background: var(--warn-soft); color: var(--warn-ink); }
.wr-licht { background: var(--ok-soft); color: var(--ok-ink); }
.wr-row { display: grid; grid-template-columns: 160px 1fr; gap: var(--sp-3); padding: var(--sp-2) 0; border-bottom: 1px solid var(--border); align-items: start; }
.wr-row:last-child { border-bottom: none; }
.wr-metrics { display: flex; gap: var(--sp-4); flex-wrap: wrap; font-size: var(--fs-dense); font-variant-numeric: tabular-nums; }
.wr-metric { display: flex; flex-direction: column; }
.wr-metric-value { font-weight: 700; }

/* ── Groepsprofiel beheer ── */
.gp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--sp-4); }
.gp-card { padding: var(--sp-4); }
.gp-field { margin-bottom: var(--sp-3); }
.gp-field label { display: block; font-size: var(--fs-label); text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-sub); margin-bottom: var(--sp-1); }

/* ── Doorstroomoverzicht ── */
.transfer-timeline { position: relative; padding-left: 24px; }
.transfer-timeline::before { content: ''; position: absolute; left: 8px; top: 0; bottom: 0; width: 2px; background: var(--border); }
.transfer-dot { position: absolute; left: 3px; width: 12px; height: 12px; border-radius: 50%; background: var(--primary); border: 2px solid var(--card-bg); }
.transfer-entry { position: relative; padding-bottom: var(--sp-4); }
.transfer-entry:last-child { padding-bottom: 0; }
.transfer-date { font-size: var(--fs-label); color: var(--text-sub); }
.transfer-label { font-size: var(--fs-dense); font-weight: 600; }

/* ── Blessure-registratie ── */
.injury-page-head h1 { margin: 0; }
.injury-page-head .page-sub { margin: var(--sp-1) 0 0; }
.injury-form { max-width: 1120px; }
.injury-form-layout {
  display: grid; grid-template-columns: minmax(360px, 1.15fr) minmax(360px, .85fr);
  gap: var(--sp-5); align-items: stretch;
}
.injury-map-panel {
  min-height: 760px; padding: var(--sp-4) var(--sp-5) var(--sp-5);
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--paper);
  display: flex; flex-direction: column;
}
.injury-map-toolbar { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.injury-segment {
  display: inline-flex; gap: 2px; margin: 0; padding: 3px;
  border: 0; border-radius: var(--radius-sm); background: var(--border);
}
.injury-segment button {
  min-width: 82px; padding: 8px 14px; border: 0; border-radius: var(--radius-xs);
  background: transparent; color: var(--text-sub); font: inherit; cursor: pointer;
}
.injury-segment button.is-active { color: var(--card-bg); background: var(--ok); box-shadow: 0 2px 5px rgba(22, 50, 78, .15); }
.injury-map-stage {
  flex: 1; display: grid; grid-template-columns: 46px minmax(220px, 300px) 46px;
  justify-content: center; align-items: center; gap: var(--sp-2); padding: var(--sp-5) 0 var(--sp-3);
}
.body-map-svg-wrap {
  width: 100%; padding: 8px; border-radius: 48%;
  background: radial-gradient(ellipse at center, color-mix(in srgb, var(--card-bg) 58%, transparent), transparent 68%);
}
.body-map { display: block; width: 100%; height: auto; overflow: visible; }
.body-map-view[hidden] { display: none; }
.body-map-view-mark {
  fill: color-mix(in srgb, var(--text-sub) 72%, transparent);
  font-size: var(--fs-meta); font-weight: 800; letter-spacing: 1.5px;
}
/* De omtrek van de hele figuur, één keer onder alle zones gelegd.
   Klinische pijnkaarten tekenen een silhouet met zones erbinnen; wij bouwden de figuur ópuit
   zones, elk met een eigen rand rondom. Daardoor las ze als losse blokjes tegen elkaar in plaats
   van als één lichaam. Deze <use> herhaalt dezelfde zones met een dikke rand eronder: buiten de
   figuur blijft daarvan een strakke contour over, binnenin wordt ze door de zones zelf afgedekt.
   Meteen ook de reden dat kleine naden tussen twee zones niet meer opvallen. */
.body-map-silhouette {
  fill: color-mix(in srgb, var(--side-sub) 88%, var(--card-bg));
  stroke: color-mix(in srgb, var(--text-sub) 55%, var(--side-sub)); stroke-width: 3.5;
  stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.body-map-part {
  fill: color-mix(in srgb, var(--side-sub) 88%, var(--card-bg));
  /* Haarlijn: de scheiding tussen twee zones mag zichtbaar zijn, maar hoort niet te wedijveren
     met de buitenrand. Anders valt de figuur visueel weer uiteen. */
  stroke: color-mix(in srgb, var(--text-sub) 22%, transparent); stroke-width: .75;
  stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke;
  cursor: pointer; transition: fill .15s, stroke .15s, filter .15s;
}
[data-body-view="back"] .body-map-part,
[data-body-view="back"] .body-map-silhouette {
  fill: color-mix(in srgb, var(--side-sub) 78%, var(--text-sub));
}
/* Man en vrouw verschillen in getekende omtrek — zie _BodyMap.cshtml. Hier stond eerst een scaleX
   per lichaamsdeel rond één gedeeld transform-origin: de schouder werd met .86 samengedrukt en de
   bovenarm met .92, allebei naar het midden toe, waardoor delen die tegen elkaar horen te liggen
   verschillend ver opschoven en er naden ontstonden. */
.body-map-part:hover, .body-map-part:focus { fill: var(--accent-neutral); stroke: var(--card-bg); outline: none; }
.body-map-part.body-part--active {
  fill: var(--primary); stroke: var(--card-bg); stroke-width: 3;
  filter: drop-shadow(0 0 7px rgba(224, 52, 42, .55));
}
.body-map-anatomy {
  fill: none; stroke: color-mix(in srgb, var(--text-sub) 60%, transparent);
  stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round;
  pointer-events: none;
}
.body-map-anatomy circle { fill: color-mix(in srgb, var(--text-sub) 60%, transparent); stroke: none; }
.body-map-anatomy--back { stroke: color-mix(in srgb, var(--paper) 68%, var(--text-sub)); stroke-width: 1.6; }
.body-map-anatomy--back .body-map-spine { stroke-dasharray: 2 3; stroke-width: 1.1; }
[data-gender="Man"] .body-map-detail--female,
[data-gender="Vrouw"] .body-map-detail--male { display: none; }
.injury-side-label {
  color: var(--text-sub); font-size: var(--fs-label); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; writing-mode: vertical-rl;
}
.injury-side-label--right { transform: rotate(180deg); justify-self: end; }
.injury-side-label--left { justify-self: start; }
.injury-map-help { margin: 0; color: var(--text-sub); text-align: center; font-size: var(--fs-meta); }
.injury-form-fields { display: flex; flex-direction: column; gap: var(--sp-3); }
.injury-field-card { padding: var(--sp-4); border: 1px solid var(--border); border-radius: var(--radius); background: var(--card-bg); }
.injury-card-label {
  display: block; margin-bottom: var(--sp-2); color: var(--text-sub);
  font-size: var(--fs-label); font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}
.injury-athlete-name { display: block; padding: 7px 0; font-size: var(--fs-section); }
.injury-location-card { text-align: center; }
.injury-location-card strong { display: block; font-family: var(--font-display); font-size: var(--fs-section); }
.injury-location-card .t-meta { display: block; margin-top: 2px; }
.injury-location-controls { display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--sp-2); margin-top: var(--sp-3); text-align: left; }
.injury-choice-row { display: flex; gap: 6px; }
.injury-choice-row--wrap { flex-wrap: wrap; }
.injury-choice-row--three > * { flex: 1 1 0; }
.injury-choice { position: relative; }
.injury-choice input { position: absolute; opacity: 0; pointer-events: none; }
.injury-choice span {
  display: flex; min-height: 38px; padding: 8px 12px; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius-xs); color: var(--text-sub);
  font-size: var(--fs-dense); text-align: center; cursor: pointer; transition: .15s ease;
}
.injury-choice input:focus-visible + span { outline: 2px solid var(--primary); outline-offset: 2px; }
.injury-choice input:checked + span { color: var(--ok-ink); border-color: var(--ok); background: var(--ok-soft); font-weight: 600; }
.injury-choice--trend span { min-height: 56px; flex-direction: column; line-height: 1.2; }
.injury-choice--trend b { font-size: var(--fs-section); font-weight: 500; }
.injury-choice--trend input[value="Stijgend"]:checked + span { color: var(--danger-ink); border-color: var(--danger); background: var(--danger-soft); }
.injury-choice--trend input[value="Dalend"]:checked + span { color: var(--ok-ink); border-color: var(--ok); background: var(--ok-soft); }
.injury-choice--status input[value="Actief"]:checked + span { color: var(--danger-ink); border-color: var(--danger); background: var(--danger-soft); }
.injury-choice--status input[value="Herstellend"]:checked + span { color: var(--warn-ink); border-color: var(--warn); background: var(--warn-soft); }
.injury-choice--status input[value="Hersteld"]:checked + span { color: var(--ok-ink); border-color: var(--ok); background: var(--ok-soft); }
.injury-severity-card { text-align: center; }
.injury-severity-value { display: block; color: var(--ok); font-family: var(--font-display); font-size: var(--fs-stat); font-weight: 700; line-height: 1; margin-bottom: var(--sp-2); }
.injury-severity { font-weight: 700; font-variant-numeric: tabular-nums; }
.severity-slider { width: 100%; height: 6px; border-radius: 4px; appearance: none; background: linear-gradient(90deg, var(--ok) 0%, var(--warn) 55%, var(--danger) 100%); }
.severity-slider::-webkit-slider-thumb { width: 21px; height: 21px; appearance: none; border: 3px solid var(--card-bg); border-radius: 50%; background: var(--card-bg); box-shadow: 0 1px 5px rgba(0,0,0,.28); cursor: pointer; }
.severity-slider::-moz-range-thumb { width: 17px; height: 17px; border: 3px solid var(--card-bg); border-radius: 50%; background: var(--card-bg); box-shadow: 0 1px 5px rgba(0,0,0,.28); cursor: pointer; }
.injury-scale-labels { display: flex; justify-content: space-between; margin-top: 6px; color: var(--text-sub); font-size: var(--fs-label); }
.injury-date-grid { margin-bottom: var(--sp-3); }
.injury-status-row { margin-top: var(--sp-2); }
.injury-form textarea { resize: vertical; min-height: 78px; }
.injury-form-actions { display: flex; justify-content: flex-end; gap: var(--sp-2); margin-top: var(--sp-4); }
.injury-delete-form { max-width: 1120px; margin-top: var(--sp-3); text-align: right; }
.injury-trend--up { color: var(--red); font-weight: 600; }
.injury-trend--up::before { content: '\2191 '; }
.injury-trend--down { color: var(--green); font-weight: 600; }
.injury-trend--down::before { content: '\2193 '; }
.injury-trend--stable { color: var(--text-sub); font-weight: 600; }
.injury-trend--stable::before { content: '\2194 '; }

@media (max-width: 900px) {
  .injury-form-layout { grid-template-columns: 1fr; }
  .injury-map-panel { min-height: 660px; }
  .injury-map-stage { grid-template-columns: 38px minmax(210px, 280px) 38px; }
}
@media (max-width: 520px) {
  .injury-map-panel { min-height: 570px; padding: var(--sp-3); }
  .injury-map-toolbar { justify-content: center; }
  .injury-segment { flex: 1; }
  .injury-segment button { min-width: 0; flex: 1; padding-inline: 8px; }
  .injury-map-stage { grid-template-columns: 24px minmax(180px, 240px) 24px; padding-top: var(--sp-3); }
  .injury-location-controls, .injury-date-grid { grid-template-columns: 1fr; }
  .injury-choice-row--three { flex-direction: column; }
  .injury-choice--trend span { min-height: 44px; flex-direction: row; gap: var(--sp-2); }
  .injury-form-actions { flex-direction: column-reverse; }
  .injury-form-actions .btn { width: 100%; justify-content: center; }
}

/* ── RPE-schaal (feedback) ── */
.rpe-scale { display: flex; gap: 4px; flex-wrap: wrap; }
.rpe-option { position: relative; }
.rpe-option input { position: absolute; opacity: 0; width: 0; height: 0; }
.rpe-label {
  display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 8px;
  font-weight: 700; font-size: var(--fs-body); cursor: pointer;
  border: 2px solid var(--border); background: var(--card-bg); transition: all 0.15s;
}
.rpe-option input:checked + .rpe-label { color: #fff; border-color: transparent; }
.rpe--easy .rpe-label { color: var(--green); }
.rpe--easy input:checked + .rpe-label { background: var(--green); }
.rpe--moderate .rpe-label { color: var(--amber); }
.rpe--moderate input:checked + .rpe-label { background: var(--amber); }
.rpe--hard .rpe-label { color: var(--red); }
.rpe--hard input:checked + .rpe-label { background: var(--red); }
.rpe--max .rpe-label { color: var(--red); }
.rpe--max input:checked + .rpe-label { background: var(--red); }

/* ── Coachlogboek ── */
.coachlog-list { display: flex; flex-direction: column; gap: var(--sp-3); }
.coachlog-item p { font-size: var(--fs-body); line-height: 1.5; }

/* ── Formulier helpers ── */
.form-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
@media (max-width: 600px) { .form-grid-2 { grid-template-columns: 1fr; } }



/* ── Landingspagina ──
   Dezelfde donkere wereld als offline.html, en om dezelfde reden: dat zijn de twee schermen die
   iemand ziet vóór hij binnen is. Bewust niet themagevoelig — dit is de eerste indruk van het merk
   en die hoort er voor iedereen hetzelfde uit te zien.

   Staat los van .app-shell: de layout rendert deze pagina zonder zijbalk, dus alle maatvoering
   hoort hier. */
.landing {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-6) var(--sp-5);
  color: var(--side-text);
  background:
    radial-gradient(ellipse at 15% 10%, var(--navy-2), transparent 55%),
    radial-gradient(ellipse at 95% 90%, var(--navy), transparent 55%),
    var(--navy-deep);
}
.landing-inner { width: 100%; max-width: 940px; display: flex; flex-direction: column; gap: var(--sp-6); }

/* Links de identiteit, rechts het aanmelden. Dat laatste is waarvoor de pagina bestaat, dus het
   krijgt een eigen kader in plaats van los onder de tekst te hangen. */
.landing-top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
  gap: var(--sp-6);
  align-items: center;
}

.landing-mark {
  width: 84px; height: 84px; border-radius: var(--radius-lg);
  margin-bottom: var(--sp-5);
  background: var(--card-bg); padding: 9px; object-fit: contain;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .4);
  display: block;
}
.landing-name {
  margin: 0; font-size: var(--fs-landing); line-height: 1.05;
  letter-spacing: -.025em; font-weight: 700;
}
.landing-club {
  margin: var(--sp-2) 0 0; font-size: var(--fs-label); font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: var(--side-sub);
}
.landing-rule {
  width: 84px; height: 4px; margin: var(--sp-5) 0 var(--sp-4);
  border: 0; border-radius: 2px; background: var(--primary);
}
.landing-tagline {
  margin: 0 0 var(--sp-3); font-size: var(--fs-section); font-weight: 600;
  max-width: 22ch; line-height: 1.3;
}
.landing-lede { margin: 0; color: var(--side-sub); max-width: 46ch; }

/* Het aanmeldpaneel. */
.landing-signin {
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: var(--radius-sm);
  padding: var(--sp-5) var(--sp-4);
}
.landing-signin-title { margin: 0 0 2px; font-size: var(--fs-section); font-weight: 600; }
.landing-signin-hint { margin: 0 0 var(--sp-4); font-size: var(--fs-meta); color: var(--side-sub); }
.landing-signin-note {
  margin: var(--sp-4) 0 0; font-size: var(--fs-meta);
  color: var(--side-sub); line-height: 1.55;
}
.landing-signin form { margin: 0; }

.landing-btn {
  display: flex; align-items: center; justify-content: center;
  width: 100%; margin-bottom: var(--sp-2);
  text-decoration: none;
}
.landing-btn-ghost {
  background: rgba(255, 255, 255, .07);
  color: var(--side-text);
  border-color: rgba(255, 255, 255, .12);
}
.landing-btn-ghost:hover { background: rgba(255, 255, 255, .12); color: var(--side-text); }

.landing-sep {
  display: flex; align-items: center; gap: var(--sp-3);
  margin: var(--sp-4) 0; color: var(--side-sub); font-size: var(--fs-meta);
}
.landing-sep::before, .landing-sep::after {
  content: ""; flex: 1; height: 1px; background: rgba(255, 255, 255, .12);
}

.landing-error {
  background: color-mix(in srgb, var(--danger) 20%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 45%, transparent);
  border-radius: var(--radius-sm);
  padding: var(--sp-3);
  margin-bottom: var(--sp-4);
  font-size: var(--fs-meta);
  line-height: 1.5;
}

/* Onderbouwing, geen boodschap: rustig zodat ze de knop niet beconcurreren. */
.landing-features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1px;
  background: rgba(255, 255, 255, .12);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.landing-feature { background: rgba(11, 23, 36, .55); padding: var(--sp-4); }
.landing-feature .t { display: block; font-weight: 600; font-size: var(--fs-body); margin-bottom: 3px; }
.landing-feature .d { font-size: var(--fs-meta); color: var(--side-sub); line-height: 1.45; }

.landing-footer {
  border-top: 1px solid rgba(255, 255, 255, .12);
  padding-top: var(--sp-4);
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5);
  justify-content: space-between;
  font-size: var(--fs-meta); color: var(--side-sub);
}
.landing-footer a { color: var(--side-text); }

@media (max-width: 820px) {
  .landing-top { grid-template-columns: 1fr; gap: var(--sp-5); }
  .landing { padding: var(--sp-5) var(--sp-4); align-items: flex-start; }
}

/* ── Beta-label ──
   Zolang de app onder versie 1.0.0 zit. Klein en rustig: het hoort naast de naam te staan zonder
   ze te overstemmen — een bezoeker moet weten dat er nog aan gewerkt wordt, niet erdoor afgeschrikt.
   Verdwijnt vanzelf bij de eerste echte uitrol, want het volgt uit het versienummer. */
.beta-tag {
  display: inline-block; vertical-align: middle; margin-left: 6px;
  padding: 1px 6px; border-radius: var(--radius-xs);
  font-size: var(--fs-meta); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  line-height: 1.5; cursor: help;
  background: color-mix(in srgb, var(--primary) 18%, transparent);
  color: var(--side-text);
  border: 1px solid color-mix(in srgb, var(--primary) 45%, transparent);
}
/* Op de landingspagina staat hij naast een veel grotere naam en mag hij mee schalen. */
.beta-tag-lg {
  margin-left: 12px; padding: 3px 10px; border-radius: var(--radius-sm);
  font-size: var(--fs-label); letter-spacing: .1em;
  background: color-mix(in srgb, var(--primary) 22%, transparent);
  border-color: color-mix(in srgb, var(--primary) 55%, transparent);
}

/* ── Normen per atleet ──
   De eerste versie zette elke norm op een eigen tabelrij. Een atleet met drie normen stond er dan
   drie keer, en wie wilde weten "wat draagt Riete" moest de rijen zelf bij elkaar zoeken. De vraag
   op dit scherm is nooit "welke normen bestaan er" maar "wie draagt er wat", dus de atleet is de
   eenheid en zijn normen staan eronder.

   Twee ploegen naast elkaar waar het scherm breed genoeg is; daaronder onder elkaar. */
.normteams {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: var(--sp-4);
  align-items: start;
  margin-bottom: var(--sp-4);
}

.normteam { border: 1px solid var(--border); background: var(--card-bg); border-radius: var(--radius-sm); }
.normteam > header {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 2px solid var(--primary);
}

/* Eén atleet met zijn normen. */
.normathlete { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--border); }
.normteam .normathlete:last-child { border-bottom: 0; }
.normathlete > .nm { font-weight: 700; }

/* Eén norm: onderdeel, prestatie, niveau, geldigheid. Vaste kolombreedtes zodat de tijden onder
   elkaar uitlijnen — daar leest een trainer een reeks aan af. */
/* Eén regel per prestatie: onderdeel — waarde — behaalde niveaus — geldigheid.

   De onderdeelkolom was 5,5em en brak "3000 m steeple" over twee regels, waarna de hele rij uit
   het lood liep. Ze is nu ruim genoeg voor de langste naam die er is, en de waardekolom staat
   vast in monospace zodat de tijden onder elkaar uitlijnen — daar leest een trainer een reeks aan
   af. De laatste kolom vangt de rest op en mag wél afbreken. */
.normline {
  display: grid;
  grid-template-columns: 8.5em 6.5em auto 1fr;
  gap: var(--sp-1) var(--sp-2);
  align-items: baseline;
  padding: 3px 0;
  font-size: var(--fs-dense);
}
.normline .dist { color: var(--text-sub); }
/* De parcourslengte hoort bij het onderdeel, niet bij de prestatie: ze verklaart de tijd. */
.normline .len { font-family: var(--mono); font-size: var(--fs-meta); opacity: .75; }

.normline .val { font-family: var(--mono); text-align: right; white-space: nowrap; }

/* Meerdere niveaus uit één race staan naast elkaar; ze horen bij dezelfde prestatie. */
.normline .lvl { display: flex; flex-wrap: wrap; gap: var(--sp-1); align-items: baseline; }

.normline .until {
  display: flex; flex-wrap: wrap; gap: var(--sp-1); align-items: baseline;
  font-family: var(--mono); font-size: var(--fs-meta); color: var(--text-sub);
}
.normline .until .as { font-family: inherit; font-style: italic; }

@media (max-width: 560px) {
  .normline { grid-template-columns: 1fr auto; }
  .normline .lvl,
  .normline .until { grid-column: 1 / -1; }
}

/* Norm van het Talenten- of Topteam, naast de PR- en SB-badge bij een uitslag.
   Navy in plaats van groen: PR en SB gaan over de atleet tegenover zichzelf, een norm over een
   grens die de club stelt. Dat onderscheid hoort zichtbaar te zijn zonder de rij te overstemmen. */
.badge.norm {
  background: color-mix(in srgb, var(--navy) 12%, transparent);
  color: var(--navy);
  border: 1px solid color-mix(in srgb, var(--navy) 30%, transparent);
  font-weight: 700;
}

/* ── Tweestapsverificatie ─────────────────────────────────────────────────────
   De QR staat op wit, ook los van het thema: een scanner leest een omgekeerde
   code niet. De cijfervelden krijgen de mono-familie met ruime letterafstand,
   want zes cijfers overtikken van een telefoon gaat sneller als ze niet aan
   elkaar plakken. */
.qr-box {
  display: flex;
  justify-content: center;
  margin-top: var(--sp-4);
  padding: var(--sp-4);
  background: var(--qr-paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.qr-box svg { width: 200px; height: 200px; }

.totp-input {
  font-family: var(--mono);
  font-size: var(--fs-stat);
  letter-spacing: .25em;
  text-align: center;
}

.totp-secret {
  font-family: var(--mono);
  font-size: var(--fs-section);
  letter-spacing: .08em;
  margin: var(--sp-2) 0 0;
  word-break: break-all;
}

.recovery-codes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--sp-2);
  list-style: none;
  margin: var(--sp-4) 0 0;
  padding: 0;
}
.recovery-codes li {
  font-family: var(--mono);
  font-size: var(--fs-section);
  letter-spacing: .06em;
  padding: var(--sp-2) var(--sp-3);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  text-align: center;
}
