/* ============================================================
   MoveGym — design systém  ·  LUXURY EDITORIAL
   Teplá ivory paleta · bronz/šampaň akcent · serif Fraunces
   Filmové zrno · vlasové linky · pomalý pohyb · espresso bloky
   Tmavé sekce: třída .invert (přemapuje barevné proměnné).
   ============================================================ */

:root {
  /* ---------- Světlá paleta ---------- */
  --bg:         #F4F0E7;   /* teplá ivory */
  --bg-2:       #EDE7D9;   /* alternující sekce */
  --surface:    #FBF8F1;   /* karty / povrchy */
  --surface-2:  #F2ECDF;   /* hover / zvýšené */
  --surface-3:  #EAE2D2;   /* inputy / nejvyšší */
  --line:       #DDD4C3;   /* vlasové linky */
  --line-2:     #CCC1A9;   /* výraznější linky */

  --text:       #1B1A16;   /* teplý inkoust */
  --muted:      #6C6557;   /* taupe / sekundární (≈5:1 na ivory) */
  --muted-2:    #6B6256;   /* drobné labely — ztmaveno na ≈5:1 (WCAG AA) */

  --accent:     #7E5E2F;   /* bronz pro TEXT/linky — ztmaveno na ≈4.8:1 na ivory (WCAG AA) */
  --accent-2:   #C2A878;   /* šampaň — hover/záře */
  --accent-soft: rgba(154,122,74,.10);
  --accent-line: rgba(154,122,74,.34);
  --accent-ink: #FBF8F1;   /* text na bronzové ploše */
  --accent-rgb: 154,122,74;

  --deep:       #201C14;   /* espresso (reference) */

  --ok:    #5C7C52;
  --warn:  #B08534;
  --error: #B0473B;
  --error-soft: rgba(176,71,59,.10);

  /* Rozvrh — rámeček slotu podle toho, jestli se dá lekce ještě stihnout.
     Schválně tlumené odstíny z palety, ne semaforová zelená/červená. */
  --ring-ok:   #5C7C52;
  --ring-past: rgba(176,71,59,.5);

  /* ---------- Typografie ---------- */
  --f-display: "Fraunces", Georgia, "Times New Roman", serif;
  --f-body:    "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Drobné prostrkané labely (eyebrow, tagy, drobečky, hlavičky tabulek).
     Dřív to byl systémový monospace — ten se ale na každém zařízení kreslil jinak
     a vedle Interu a Fraunces působil jako cizí třetí písmo. Teď jede vše v Interu. */
  --f-label:   "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Skutečný monospace zbyl jen na <code> v právních textech. */
  --f-mono:    ui-monospace, "SF Mono", "SFMono-Regular", Menlo, Consolas, monospace;

  /* ---------- Rádiusy (luxus = jemné) ---------- */
  --r-sm: 6px;
  --r:    10px;
  --r-md: 12px;   /* používá `.dpick__pop`; dřív token chyběl a kalendář měl ostré rohy */
  --r-lg: 14px;
  --r-xl: 20px;
  --r-pill: 999px;

  /* ---------- Stíny / záře (světlé, jemné) ---------- */
  --sh-sm: 0 1px 2px rgba(27,26,22,.05), 0 2px 8px rgba(27,26,22,.04);
  --sh:    0 12px 30px -14px rgba(27,26,22,.14), 0 4px 12px rgba(27,26,22,.05);
  /* šipka rozbalovacích seznamů — kreslí se přes mask, takže barvu bere z currentColor */
  --chev:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --sh-lg: 0 34px 70px -28px rgba(27,26,22,.24), 0 12px 26px -16px rgba(27,26,22,.12);
  --glow:  0 16px 44px -16px rgba(var(--accent-rgb),.45);

  /* ---------- Rozměry ---------- */
  --maxw: 1180px;
  --maxw-narrow: 760px;
  --gutter: clamp(20px, 5vw, 72px);
  /* 🔴 `--nav-h` NENÍ VÝŠKA LIŠTY, ALE KOLIK ZABÍRÁ SHORA (28. 8. 2026).
     Na telefonu s výřezem musí lišta sahat až k hornímu okraji, aby výřez
     seděl V NÍ a nad ní se neveze proužek stránky. Safe area je proto
     součástí téhle hodnoty a `.nav` si ji odsadí paddingem, takže obsah
     lišty zůstane vycentrovaný ve svých 80 (na telefonu 68) px.
     Díky tomu se srovná i všechno, co se pod lištu odsazuje
     (`scroll-padding-top`, `.mobile-menu`, `.auth`, `.dash`, `.legal`, hero)
     — je to jediné místo, kde se ta výška počítá.
     Na displeji bez výřezu je `--nav-safe` nula a nemění se nic. */
  --nav-safe: env(safe-area-inset-top, 0px);
  --nav-h: calc(80px + var(--nav-safe));

  /* 🔴 ❌ PŘETÉKÁNÍ LIŠTY NAD HRANU BYLO ŠPATNĚ — VYZKOUŠENO A ZRUŠENO.
     Safari 26 obarvuje plochu u status baru podle fixed/sticky prvků
     **do ~4 px od hrany**. Lišta odsunutá na `top: -120px` do toho okna
     nespadá, takže ji Safari přestane brát v úvahu úplně. Přetečení, které
     u hero fotky funguje, tady vadu prohlubuje. `top` MUSÍ zůstat 0. */

  --ease:     cubic-bezier(.22,.61,.36,1);
  --ease-out: cubic-bezier(.16,1,.3,1);  /* pomalé „drahé" doběhnutí */
}

/* ---------- Invertované (espresso) sekce: přemapování proměnných ---------- */
.invert {
  --bg:        #1A1710;
  --bg-2:      #15120C;
  --surface:   #241F16;
  --surface-2: #2C2719;
  --surface-3: #352F20;
  --line:      rgba(239,231,214,.12);
  --line-2:    rgba(239,231,214,.22);
  --text:      #EFE7D6;
  --muted:     #A39A87;
  --muted-2:   #948B79;   /* zesvětleno na ≈5:1 na espressu (WCAG AA) */
  --accent:    #C7A56A;
  --accent-2:  #DCC08A;
  --accent-soft: rgba(199,165,106,.12);
  --accent-line: rgba(199,165,106,.32);
  --accent-ink: #201C14;
  --accent-rgb: 199,165,106;
  /* na espressu by tmavé varianty zmizely → světlejší odstíny */
  --ring-ok:   #86A87A;
  --ring-past: rgba(214,124,110,.45);
  background: var(--bg);
  color: var(--text);
}

/* ============================================================
   RESET
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
/* ⚠️ `html` MUSÍ mít výslovnou `background-color`. Safari 26 ji použije jako
   náhradu, když u hrany nenajde žádný fixed prvek — a průhledný kořen spadne
   na BÍLOU, ne na barvu `body`. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--nav-h) + 14px);
  background-color: var(--bg); }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* Plynulé přechody mezi stránkami (View Transitions API) — progresivní vylepšení */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .45s; animation-timing-function: cubic-bezier(.16,1,.3,1); }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

/* Lenis smooth scroll (init v script.js, jen když uživatel nechce omezit pohyb) */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: clip; }

body {
  font-family: var(--f-body);
  background: var(--bg);
  color: var(--text);
  line-height: 1.65;
  font-size: clamp(16px, 1.05vw, 18px);
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  position: relative;
}

img, svg, video { max-width: 100%; display: block; }
picture { display: contents; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, textarea, select { font: inherit; color: inherit; }
ul { list-style: none; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }
::selection { background: var(--accent); color: var(--accent-ink); }

/* jemná bronzová aura nahoře */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(60% 50% at 50% -8%, rgba(var(--accent-rgb),.10), transparent 70%),
    radial-gradient(50% 40% at 100% 0%, rgba(194,168,120,.08), transparent 65%);
}
/* filmové zrno přes celou stránku — největší „luxusní" efekt */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 9998; pointer-events: none;
  opacity: .045; mix-blend-mode: multiply;
  /* ⚠️ `background-size` je povinné: bez něj se dlaždice šumu škáluje s hustotou
     displeje a na iPhonu s DPR 3 je zrno třikrát jemnější, tedy prakticky
     neviditelné přesně na zařízení, kde web většina lidí uvidí. */
  background-size: 160px 160px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion: reduce) { body::after { opacity: .03; } }

/* ============================================================
   APPKA — ESPRESSO (13. 8. 2026)
   Jakub: „na aplikaci do gymu se mi to zdá moc světlé." Marketingový web
   zůstává ivory (Aman #F3EEE7, Bamford #F4EFEC i konkurenční Reformer studio
   Heartcore #F7F8F6 jsou světlé — ivory je tam správně), tmavne jen appka,
   kterou lidi otevírají večer v šatně.

   Řídí to atribut `data-app` na <body>, ne výčet stránek: přidat další
   obrazovku je tím pádem jedno slovo v HTML a nikdo nemusí hledat, kde se
   selektor rozšiřuje. Dnes ho mají členská sekce, přihlášení, registrace a
   obě stránky obnovy hesla — tedy všechno za přihlašovací zdí i před ní.
   ⚠️ Kdo přidá `data-app`, musí přepsat i `theme-color` v hlavičce té stránky
   na #1A1710, jinak zůstane lišta prohlížeče a PWA světlá.

   Hodnoty vycházejí z třídy .invert, kterou má web odladěnou od začátku, s
   opravami, které vyplynuly z průzkumu:
   · --muted-2 #948B79 dával na --surface-2 jen 4,41:1 a na --surface-3 3,94:1
     (pod AA). Tady jsou oba tlumené odstíny světlejší: 7,9:1 a 7,1:1.
   · --error #B0473B má na espressu 3,25:1 → #D67C6E (5,9:1).
   · .invert nikdy nepřemapovával STÍNY — rgba(27,26,22,…) je na espressu
     neviditelná a karty by plavaly bez oddělení. Na tmavém odděluje plochy
     linka, ne stín, takže stíny jdou do černé a tlumeně.
   Prémiová tma je vždy tónovaná (Remedy Place #1A1817, Aman #281E09), ne
   achromatická — achromatická tma s jedním sytým akcentem je přesně brand
   sportovních řetězců (Barry's #111111 + #D6001A, Psycle #212121 + #CCFF00).
   ============================================================ */
body[data-app] {
  --bg:        #1A1710;
  --bg-2:      #15120C;
  --surface:   #241F16;
  --surface-2: #2C2719;
  --surface-3: #352F20;
  --line:      rgba(239,231,214,.13);
  --line-2:    rgba(239,231,214,.24);
  --text:      #EDE7DA;
  --muted:     #B5B1A6;
  --muted-2:   #C1BDB4;
  --accent:    #C7A56A;
  --accent-2:  #DCC08A;
  --accent-soft: rgba(199,165,106,.14);
  --accent-line: rgba(199,165,106,.34);
  --accent-ink: #201C14;
  --accent-rgb: 199,165,106;
  --deep:      #100E08;
  --ok:        #86A87A;
  --warn:      #D8A94E;
  --error:     #DD8878;
  --error-soft: rgba(214,124,110,.14);
  --ring-ok:   #86A87A;
  --ring-past: rgba(214,124,110,.45);
  --sh-sm: 0 1px 2px rgba(0,0,0,.42);
  --sh:    0 14px 34px -16px rgba(0,0,0,.62), 0 4px 12px rgba(0,0,0,.28);
  --sh-lg: 0 34px 70px -28px rgba(0,0,0,.72), 0 12px 26px -16px rgba(0,0,0,.36);
  --glow:  0 16px 44px -18px rgba(199,165,106,.38);
}
/* Zrno jede na `multiply`, což na espressu nedělá vůbec nic — na tmavém musí
   svítit, ne tmavit. Vzor je v repu na .hero-fb__grain. */
body[data-app]::after { mix-blend-mode: overlay; opacity: .07; }
/* Lišta má barvu ivory zapsanou natvrdo (nejde přes token), takže by nad tmavou
   stránkou zůstal světlý pruh. */
body[data-app] .nav.scrolled { background: rgba(26,23,16,.86); }
/* Patička je .invert, tedy taky tmavá — bez linky by s obsahem splynula. */
body[data-app] .footer { border-top: 1px solid var(--line); }

/* ============================================================
   TYPOGRAFIE
   ============================================================ */
h1, h2, h3, h4 {
  font-family: var(--f-display);
  /* 500, ne 600 — na 600 byly nadpisy příliš těžké a nesedělo to
     s claimem v heru, který má 500. */
  font-weight: 500;
  line-height: 1.06;
  letter-spacing: -.015em;
  font-optical-sizing: auto;
  text-wrap: balance;
}
.display {
  font-family: var(--f-display); font-weight: 500;
  font-size: clamp(2.7rem, 7vw, 6rem);
  line-height: 1.0; letter-spacing: -.025em;
}
.h-xl { font-size: clamp(2.1rem, 4.8vw, 3.8rem); line-height: 1.02; letter-spacing: -.02em; }
.h-lg { font-size: clamp(1.6rem, 3.2vw, 2.6rem); }
.h-md { font-size: clamp(1.2rem, 2vw, 1.55rem); font-weight: 600; }
p { text-wrap: pretty; }
.lead { font-size: clamp(1.08rem, 1.4vw, 1.28rem); color: var(--muted); line-height: 1.7; }
strong, b { font-weight: 600; color: var(--text); }
.accent { color: var(--accent); }
.muted { color: var(--muted); }
em { font-style: italic; }

/* eyebrow / kicker — drobný prostrkaný monospace label */
.eyebrow {
  display: inline-flex; align-items: center; gap: .7em;
  font-family: var(--f-label); font-size: .76rem; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase; color: var(--accent);
}
.eyebrow::before { content: ""; width: 30px; height: 1px; background: var(--accent-line); display: inline-block; }
.eyebrow--center { justify-content: center; }

/* ============================================================
   LAYOUT
   ============================================================ */
/* ⚠️ `viewport-fit=cover` v meta tagu (kvůli plovoucí liště Safari 26) pustí
   obsah i pod výřez displeje. Na výšku jsou obě `env()` nulové a nic se nemění,
   na šířku drží text mimo výřez. */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto;
  padding-inline: max(var(--gutter), env(safe-area-inset-left), env(safe-area-inset-right)); }
.wrap--narrow { max-width: var(--maxw-narrow); }
.section { padding-block: clamp(72px, 11vw, 150px); position: relative; }
.section--tight { padding-block: clamp(48px, 7vw, 90px); }
/* Dvě sekce po sobě se STEJNÝM podkladem: odsazení se sečtou (150 + 90 až
   150 + 150) a vznikne pás 240–300 px, kde není vůbec nic. U střídavé sekce
   to smysl dává — hranici je vidět a prostor ji odděluje. Kde se podklad
   nemění, je to jen díra; přesně na ni ukázal Jakub 14. 8. 2026 („projdi celý
   web a vymaž zbytečné mezery"). Druhá sekce si proto horní odsazení odpustí
   a mezeru drží spodek té první.
   ⚠️ `--alt` se schválně NEVYJÍMÁ jen podle jména: podmínka je vždy „stejný
   podklad na obou stranách", takže se sem nesmí přidat dvojice, kde se barva
   mění (tam by se bloky slily). */
:where(.section, .section--tight):not(.section--alt, .invert, .section--photo)
  + :where(.section, .section--tight):not(.section--alt, .invert, .section--photo) { padding-top: 0; }
.section--alt:not(.invert) + .section--alt:not(.invert) { padding-top: 0; }
/* A ta jedna zbylá mezera se ještě zkrátí, když pod ní stojí blok `.callout`
   (závěrečné CTA „Přijď na lekci"). Callout si nese vlastních 80 px odsazení,
   takže s plnými 150 px nad ním vycházel prázdný pás 234 px. */
.section:not(.section--alt, .invert, .section--photo):has(+ .section--tight .callout) {
  padding-bottom: clamp(48px, 7vw, 90px); }
/* Střídavá sekce nekončí řezem, ale dohasne. Rozdíl mezi --bg-2 a --bg je jen
   pár bodů na kanál, takže ostrá linka nevypadá jako záměr, ale jako chyba
   napojení — nejvíc je to vidět tam, kde pod ní začíná prázdné místo (CTA na
   /o-nas/). Přechodový pruh 90 px si kreslí sekce sama pod sebou; `bottom: -1px`
   kvůli tomu, aby mezi barvou a pruhem nezůstala vlasová mezera ze zaokrouhlení. */
.section--alt { background: var(--bg-2); position: relative; }
/* ⚠️ Pruh je UVNITŘ sekce a přechází do barvy TÉ DALŠÍ (`transparent` → `--bg`),
   ne naopak. Kdyby visel pod sekcí, překryl by prvních 90 px obsahu té další;
   a kdyby uvnitř přecházel z `--bg-2` do průhledna, ležel by nad stejnou barvou
   a nebyl by vidět vůbec. Takhle je na spodní hraně sekce už barva pozadí, a
   žádný skok tedy nevznikne. */
.section--alt::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 90px;
  background: linear-gradient(transparent, var(--bg));
  pointer-events: none; z-index: 0;
}
.section--alt > * { position: relative; z-index: 1; }
/* Sekce s vlastním obsahem na pozadí (fotka, tmavý blok) si přechod nekreslí. */
.section--alt.invert::after, .section--alt.section--photo::after { display: none; }
.section__head { max-width: 720px; margin-bottom: clamp(40px, 5vw, 64px); }
.section__head--center { margin-inline: auto; text-align: center; }
.section__title { font-size: clamp(2rem, 4.6vw, 3.6rem); margin: 18px 0 0; letter-spacing: -.02em; }
.section__lead { margin-top: 20px; }
.grid { display: grid; gap: clamp(16px, 2.4vw, 26px); }
/* Trojice karet (Proč MoveGym, Na čem stojíme, Dobré vědět). Sloupce byly natvrdo
   inline `repeat(3,1fr)` → na telefonu zůstaly tři a text lezl z karet ven.
   min(100%, 260px) drží kartu čitelnou i na 320px displeji. */
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }

.skip {
  position: fixed; left: 14px; top: -60px; z-index: 1000;
  background: var(--text); color: var(--bg); padding: 10px 16px;
  border-radius: var(--r-sm); font-weight: 600; transition: top .2s var(--ease);
}
.skip:focus { top: 14px; }

/* tenké linky */
.divider { height: 1px; background: var(--line); margin-block: clamp(48px, 7vw, 90px); border: none; }

/* ============================================================
   TLAČÍTKA
   ============================================================ */
.btn {
  --bbg: var(--surface-2); --bfg: var(--text);
  display: inline-flex; align-items: center; justify-content: center; gap: .6em;
  background: var(--bbg); color: var(--bfg);
  font-family: var(--f-body); font-weight: 600; font-size: .95rem; letter-spacing: .01em;
  padding: .95em 1.6em; border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--line-2);
  transition: transform .35s var(--ease-out), box-shadow .4s var(--ease), background .35s, color .35s;
  position: relative; white-space: nowrap;
}
.btn svg { width: 1.1em; height: 1.1em; flex: none; }
.btn:hover { transform: translateY(-2px); box-shadow: var(--sh), inset 0 0 0 1px var(--line-2); }

/* ---------- PROKLIK ----------
   Tlačítko musí pod prstem viditelně klesnout, ne se jen vrátit do výchozí
   polohy. Na telefonu není hover, takže tohle je jediná zpětná vazba, že se
   ťuknutí povedlo — bez ní lidi mačkají podruhé. Platí pro všechno, co se dá
   zmáčknout, ne jen pro `.btn`. */
.btn:active,
.pill:active, .sched__arrow:active, .fsel__btn:active, .modal__close:active,
.pwd__toggle:active, .avail__go:active, .cookiebar__btn:active, .faq__q:active {
  transform: translateY(1px) scale(.985);
  transition-duration: .06s;
  filter: brightness(.94);
}
/* Slot v rozvrhu se při najetí zvedá o 3 px — stisk ho musí posadit zpátky. */
.slot:active { transform: translateY(0) scale(.99); transition-duration: .06s; filter: brightness(.97); }
/* Plocha tlačítka je vlastní, prohlížeč přes ni nemá kreslit svůj šedý blik. */
.btn, .pill, .sched__arrow, .fsel__btn, .modal__close, .pwd__toggle, .avail__go, .cookiebar__btn, .slot {
  -webkit-tap-highlight-color: transparent;
}
@media (prefers-reduced-motion: reduce) {
  /* Beze skoku, ale zpětná vazba zůstat musí — ztmavením. */
  .btn:active, .pill:active, .sched__arrow:active, .fsel__btn:active, .modal__close:active,
  .pwd__toggle:active, .avail__go:active, .cookiebar__btn:active, .faq__q:active, .slot:active {
    transform: none; filter: brightness(.92);
  }
}

/* primární = inkoust na ivory (na invert sekci = ivory na espressu) */
.btn--primary { --bbg: var(--text); --bfg: var(--bg); box-shadow: var(--sh); font-weight: 600; }
.btn--primary:hover { --bbg: var(--accent); --bfg: var(--accent-ink); box-shadow: var(--glow); }

.btn--ghost { --bbg: transparent; --bfg: var(--text); box-shadow: inset 0 0 0 1px var(--line-2); }
.btn--ghost:hover { box-shadow: inset 0 0 0 1px var(--text); }
.btn--danger { --bbg: #A85A43; --bfg: #F7F2E7; }
.btn--danger:hover { --bbg: #944C37; }

.btn--dark { --bbg: transparent; --bfg: var(--text); box-shadow: inset 0 0 0 1px var(--line-2); }
.btn--dark:hover { --bbg: var(--text); --bfg: var(--bg); }

.btn--lg { padding: 1.1em 2.1em; font-size: 1.02rem; }
.btn--block { width: 100%; }
.btn--sm { padding: .6em 1.1em; font-size: .85rem; }
.btn[disabled] { opacity: .5; pointer-events: none; }

.btn--primary.btn--lg { overflow: hidden; isolation: isolate; }
.btn__spot {
  position: absolute; top: 0; left: 0; width: 200px; height: 200px; border-radius: 50%;
  pointer-events: none; z-index: -1; opacity: 0; transition: opacity .5s var(--ease); will-change: transform;
  background: radial-gradient(circle, rgba(255,255,255,.3), rgba(255,255,255,.08) 42%, transparent 70%);
}
@media (prefers-reduced-motion: reduce) { .btn__spot { display: none; } }

/* odkaz s rostoucím podtržením */
.arrow-link {
  display: inline-flex; align-items: center; gap: .5em; font-weight: 600; color: var(--text);
  background: linear-gradient(var(--accent), var(--accent)) 0 100% / 0 1px no-repeat; padding-bottom: 4px;
  transition: gap .4s var(--ease-out), background-size .5s var(--ease-out), color .3s;
}
.arrow-link:hover { gap: .85em; color: var(--accent); background-size: 100% 1px; }
.arrow-link svg { width: 1.05em; height: 1.05em; }

/* ============================================================
   NAVIGACE
   ============================================================ */
.nav {
  /* ⚠️ `top: 0` je podmínka, ne detail: Safari 26 vzorkuje jen fixed prvky
     do ~4 px od hrany. Plocha u výřezu se přidává výškou a paddingem. */
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  height: var(--nav-h);
  padding-top: var(--nav-safe);
  /* 🔴 BARVA LIŠTY PRO `theme-color` (28. 8. 2026). Safari plochu nad lištou
     nemaluje z `background`, ale z `<meta name="theme-color">` — tak to má
     i Klideq, na který se Jakub odkázal (`#1a1a2e`, celý web tmavý, plocha
     jim splyne sama). My máme lištu ivory nad tmavou fotkou, takže se ta
     hodnota musí měnit se stavem lišty; přepíná ji `script.js`.
     ⚠️ Musí to být VLASTNÍ VLASTNOST, ne čtení `background-color`: `.nav`
     má `transition: background .4s` a computed barva by se během přechodu
     četla rozmazaná. Custom property se bez `@property` netransituje,
     takže se přepne skokem a je čitelná hned. */
  --nav-barva: var(--bg);
  display: flex; align-items: center;
  transition: background .4s var(--ease), border-color .4s, backdrop-filter .4s;
  border-bottom: 1px solid transparent;
}
.nav.scrolled {
  background: rgba(244,240,231,.82);
  backdrop-filter: saturate(140%) blur(14px); -webkit-backdrop-filter: saturate(140%) blur(14px);
  border-bottom-color: var(--line);
}
.nav__inner { width: 100%; max-width: var(--maxw); margin-inline: auto;
  padding-inline: max(var(--gutter), env(safe-area-inset-left), env(safe-area-inset-right));
  display: flex; align-items: center; justify-content: space-between; gap: 18px; }

/* Wordmark MOVEGYM + plaketa HEALTH · STRONG (dle reálného loga na gymu) */
.brand { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 5px;
  font-family: var(--f-body); color: var(--text); line-height: 1; font-size: 1.3rem; }
.brand__word { display: inline-flex; align-items: baseline; line-height: .82; font-size: 1em;
  letter-spacing: .01em; }
.brand__lite { font-weight: 400; }
.brand__bold { font-weight: 700; letter-spacing: -.012em; }
.brand__tag { align-self: stretch; box-sizing: border-box; background: var(--text); color: var(--bg);
  font-size: .38em; font-weight: 700; letter-spacing: .22em; text-transform: uppercase; text-align: center;
  text-indent: .22em; padding: 3px 4px 2px; border-radius: 2px;
  transition: background .35s var(--ease), color .35s var(--ease); }
.brand__tag i { font-style: normal; padding: 0 .32em; opacity: .8; }
.brand:hover .brand__tag { background: var(--accent); color: var(--accent-ink); }
.brand .accent { color: var(--accent); }

.nav__links { display: flex; align-items: center; gap: 2px; }
.nav__links a {
  padding: 9px 15px; border-radius: var(--r-pill); font-weight: 500; font-size: .94rem; color: var(--muted);
  transition: color .3s, background .3s;
}
.nav__links a:hover, .nav__links a[aria-current="page"] { color: var(--text); }
.nav__links a[aria-current="page"] { color: var(--accent); }

.nav__cta { display: flex; align-items: center; gap: 14px; }
.nav__login { font-weight: 600; font-size: .92rem; color: var(--text); padding: 9px 6px; }
.nav__login:hover { color: var(--accent); }

.nav__burger { display: none; width: 44px; height: 44px; border-radius: 10px; position: relative;
  box-shadow: inset 0 0 0 1px var(--line-2); }
.nav__burger span { position: absolute; left: 12px; right: 12px; height: 1.5px; background: var(--text);
  border-radius: 2px; transition: transform .35s var(--ease), opacity .2s; }
.nav__burger span:nth-child(1) { top: 16px; }
.nav__burger span:nth-child(2) { top: 21px; }
.nav__burger span:nth-child(3) { top: 26px; }
body.menu-open .nav__burger span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
body.menu-open .nav__burger span:nth-child(2) { opacity: 0; }
body.menu-open .nav__burger span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

.mobile-menu {
  position: fixed; inset: var(--nav-h) 0 0 0; z-index: 90; background: var(--bg);
  display: flex; flex-direction: column; gap: 2px; padding: 30px var(--gutter) 40px;
  transform: translateY(-10px); opacity: 0; visibility: hidden;
  transition: transform .4s var(--ease), opacity .35s, visibility .35s; overflow-y: auto;
}
body.menu-open .mobile-menu { transform: none; opacity: 1; visibility: visible; }
body.menu-open { overflow: hidden; }
.mobile-menu a { padding: 16px 4px; font-family: var(--f-display); font-weight: 500; font-size: 1.7rem;
  border-bottom: 1px solid var(--line); }
.mobile-menu a.btn { border: none; margin-top: 18px; font-size: 1rem; font-family: var(--f-body); }
.mobile-menu .mm-sub { font-family: var(--f-label); font-size: .76rem; color: var(--muted-2); text-transform: uppercase;
  letter-spacing: .18em; border: none; padding-bottom: 4px; margin-top: 12px; }

/* Starý editorial hero (split + typewriter + plovoucí karta) odstraněn — homepage používá .hero-fb. */

/* statistický pruh */
/* ⚠️ Sloupce se NEPÍŠOU natvrdo. Když se z pruhu vyhodí položka (25. 8. šla
   pryč „4 max lidí na Reformeru"), `repeat(4, 1fr)` nechá čtvrtý sloupec prázdný
   a pruh se zlomí na tři čtvrtiny šířky. `grid-auto-flow: column` se počtu
   přizpůsobí sám, ať jich je tři nebo pět. */
.statbar { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 0; margin-top: clamp(48px, 7vw, 80px);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
/* Odsazení nahoře má oddělovat pruh od textu NAD ním. Na úvodu i na /o-nas/ je
   ale statbar první věc ve své sekci, takže se jen přičetlo k odsazení sekce
   a nad pruhem zůstalo 230 px prázdna. */
.wrap > .statbar:first-child { margin-top: 0; }
.statbar__i { padding: clamp(22px, 3vw, 34px) clamp(8px, 2vw, 28px); text-align: left; position: relative; }
.statbar__i + .statbar__i::before { content: ""; position: absolute; left: 0; top: 22%; bottom: 22%; width: 1px; background: var(--line); }
.statbar__n { font-family: var(--f-display); font-weight: 500; font-size: clamp(2rem, 3.6vw, 3rem); line-height: 1;
  font-feature-settings: 'tnum' 1; font-variant-numeric: tabular-nums; }
.statbar__n .accent { color: var(--accent); }
.statbar__l { margin-top: 10px; font-size: .82rem; color: var(--muted); }

/* Jak to funguje — 3 kroky (rozvrh) */
.howto { list-style: none; display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 0 0 26px; padding: 0; }
.howto li { display: flex; gap: 14px; align-items: flex-start; padding: 18px 20px; background: var(--bg-2); border-radius: var(--r-lg); box-shadow: inset 0 0 0 1px var(--line); }
.howto__n { flex: none; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; background: var(--accent-soft); color: var(--accent); font-family: var(--f-display); font-weight: 600; box-shadow: inset 0 0 0 1px var(--accent-line); }
.howto strong { font-family: var(--f-display); font-weight: 600; font-size: 1.02rem; }
.howto p { margin-top: 4px; font-size: .88rem; color: var(--muted); line-height: 1.5; }
@media (max-width: 720px) { .howto { grid-template-columns: 1fr; } }

/* ============================================================
   MARQUEE (jemné, nízký kontrast)
   ============================================================ */
.marquee { position: relative; overflow: hidden; border-block: 1px solid var(--line); padding-block: 22px; background: var(--bg-2); }
/* Kraje ztmívá překryv, ne mask-image. Maska totiž seděla na .marquee a ukrajovala
   i pozadí pruhu a obě vlasové linky — pás se na krajích rozplýval do ztracena.
   Překryv leží mezi linkami (top/bottom 1px), takže rám drží až k okraji obrazovky. */
.marquee::before, .marquee::after { content: ""; position: absolute; top: 1px; bottom: 1px;
  width: clamp(40px, 7%, 150px); pointer-events: none; z-index: 1; }
.marquee::before { left: 0; background: linear-gradient(90deg, var(--bg-2) 12%, transparent); }
.marquee::after { right: 0; background: linear-gradient(270deg, var(--bg-2) 12%, transparent); }
/* Jede ZLEVA DOPRAVA (Jakub 16. 8. 2026). Stačí obrátit směr přehrávání —
   klíčové snímky zůstávají, takže se nemusí přepočítávat posun. Smyčka je
   plynulá i pozpátku, protože obsah je v pásu dvakrát. */
.marquee__track { display: flex; width: max-content;
  animation: marquee 48s linear infinite; animation-direction: reverse; }
.marquee__item { display: inline-flex; align-items: center; gap: 28px; padding-inline: 28px;
  font-family: var(--f-display); font-weight: 500; font-size: clamp(1.3rem, 2.4vw, 2rem);
  letter-spacing: -.01em; color: var(--muted); }
.marquee__item::after { content: "·"; color: var(--accent); font-style: normal; }
.marquee__item.is-ghost { color: var(--muted-2); }
@keyframes marquee { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .marquee__track { animation: none; } }

/* ============================================================
   REVEAL (pomalý, drahý doběh)
   ============================================================ */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity 1s var(--ease-out), transform 1s var(--ease-out); }
.reveal.in { opacity: 1; transform: none; }
.reveal[data-d="1"] { transition-delay: .1s; }
.reveal[data-d="2"] { transition-delay: .2s; }
.reveal[data-d="3"] { transition-delay: .3s; }
.reveal[data-d="4"] { transition-delay: .4s; }
.reveal[style*="--i"] { transition-delay: calc(var(--i, 0) * .09s); }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .float, .ring--spin { animation: none !important; }
}

/* ============================================================
   KARTY + kurzorové interakce
   ============================================================ */
.card { position: relative; background: var(--surface); border-radius: var(--r-lg);
  box-shadow: inset 0 0 0 1px var(--line); padding: clamp(24px, 3vw, 36px); overflow: hidden;
  transition: transform .45s var(--ease), box-shadow .45s var(--ease); }
.card > * { position: relative; z-index: 1; }
.card--hover:hover { transform: translateY(-3px); box-shadow: inset 0 0 0 1px var(--line-2), var(--sh-lg); }

/* ⚠️ KURZOROVÁ ZÁŘE NA KARTÁCH JE PRYČ (28. 8. 2026). `.glow-spot` (kruhová záře
   sledující myš) a `.cbord` (svítící okraj) tu byly od začátku; Jakub je nechal
   z celého webu odstranit. Zmizel s nimi i atribut `data-glow` ze 73 míst v HTML
   a obsluha ve `script.js`. NEVRACET bez jeho pokynu.
   Světlo na velkém CTA (`.btn__spot`, výš v souboru) zůstává — je to jiný prvek
   a Jakub na něj neukazoval.
   Původní poznámka, proč záře nejela v appce (platila do dnešního smazání): na
   ivory to byl jemný detail, na espressu se prala s barvami, které něco znamenají
   (zelená „dá se rezervovat", červená „zrušeno", bronzová permanentka). */

/* ============================================================
   SLUŽBY / LEKCE — mřížka karet
   ============================================================ */
.svc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2vw, 24px); }
.svc {
  position: relative; background: var(--surface); border-radius: var(--r-lg); overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line); padding: clamp(24px, 2.6vw, 32px);
  display: flex; flex-direction: column; min-height: 230px;
  transition: transform .45s var(--ease), box-shadow .45s var(--ease);
}
.svc > * { position: relative; z-index: 1; }
.svc:hover { transform: translateY(-3px); box-shadow: inset 0 0 0 1px var(--line-2), var(--sh); }
/* Karta začíná vlasovou linkou, ne ikonou. Dřív tu byl zaoblený tónovaný čtvereček
   s čárovým piktogramem uvnitř — komponenta „feature list“ z UI kitů, která na webu
   z vlasových linek, Fraunces a ivory ploch trčela jako z jiné stavebnice
   („moc cartoon na gym“, Jakub 31. 7. 2026). Linka je prvek, kterým mluví zbytek webu. */
.svc__rule { width: 46px; height: 1px; background: var(--accent-line); margin-bottom: 24px; }
.svc__name { font-family: var(--f-display); font-weight: 600; font-size: 1.4rem; }
.svc__txt { margin-top: 10px; color: var(--muted); font-size: .96rem; flex: 1; }
.svc__meta { margin-top: 18px; display: flex; flex-wrap: wrap; gap: 8px; }

.tag { display: inline-flex; align-items: center; gap: 6px; font-family: var(--f-label); font-size: .7rem;
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted); padding: 5px 11px;
  border-radius: var(--r-pill); box-shadow: inset 0 0 0 1px var(--line-2); }
.tag--accent { color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent-line); }
/* typ lekce: kurz (pravidelná docházka) vs jednotlivá rezervace */
.tag--kurz { color: var(--surface); background: var(--text); box-shadow: none; }
.tag--book { color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-line); }
.lesson__note { margin-top: 14px; font-size: .88rem; line-height: 1.55; color: var(--muted);
  padding: 11px 14px; border-radius: var(--r); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); }
.lesson__note strong { color: var(--text); font-weight: 600; }
.lesson__note a { color: var(--accent); }
.lekce-legend { margin-top: 26px; display: grid; gap: 12px; max-width: 780px; }
.lekce-legend__row { display: flex; align-items: center; gap: 12px; font-size: .92rem; color: var(--muted); }
.lekce-legend__row .tag { flex: 0 0 auto; }
@media (max-width: 560px) { .lekce-legend__row { align-items: flex-start; } }
/* Tabulka obsazenosti kurzů */
.avail { margin-top: 22px; border-radius: var(--r-lg); box-shadow: inset 0 0 0 1px var(--line); background: var(--surface); overflow: hidden; }
.avail__scroll { overflow-x: auto; }
.avail table { width: 100%; border-collapse: collapse; min-width: 560px; }
.avail th, .avail td { text-align: left; padding: 13px 18px; font-size: .92rem; border-bottom: 1px solid var(--line); white-space: nowrap; }
.avail thead th { font-family: var(--f-body); font-weight: 600; font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); background: var(--bg-2); }
.avail tbody tr:last-child td { border-bottom: none; }
.avail tbody tr:hover td { background: var(--bg-2); }

.avail__course { font-weight: 600; color: var(--text); }
/* Bez tečky před textem — barva pilulky říká totéž a puntík vypadal genericky. */
.avail__pill { display: inline-flex; align-items: center; font-family: var(--f-body); font-weight: 600; font-size: .8rem; padding: 5px 12px; border-radius: 999px; }
.avail__pill--ok { color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-line); }
.avail__pill--full { color: #8A3327; background: rgba(138,51,39,.08); box-shadow: inset 0 0 0 1px rgba(138,51,39,.25); }
/* „Ptej se" = o termínu nic nevíme. Bronzová (--ok) by u něj slibovala volno,
   což u tabulky, kde je většina termínů bez čísla, mate. */
.avail__pill--ask { color: var(--muted); background: transparent; box-shadow: inset 0 0 0 1px var(--line-2); }
/* poslední místo — ať je vidět, že se to chýlí ke konci */
.avail__pill--low { color: #8A5A16; background: rgba(138,90,22,.10); box-shadow: inset 0 0 0 1px rgba(138,90,22,.28); }
.avail__cta { margin-top: 16px; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.avail__note { margin-top: 12px; font-size: .85rem; color: var(--muted-2); max-width: 70ch; }
.avail__note a { color: var(--accent); }
.avail-group { margin-top: 30px; }
.avail-group__head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-bottom: 12px; }
.avail-group__head h3 { font-size: 1.25rem; }
.avail-group__head .arrow-link { margin-left: auto; font-size: .88rem; }
/* Detail lekce/kurzu (/lekce/<slug>/) */
.ldx { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 5vw, 64px); align-items: center; }
.ldx__media img { width: 100%; height: auto; aspect-ratio: 4/3; object-fit: cover; border-radius: var(--r-xl); box-shadow: var(--sh-lg); display: block; }
/* Sólo snímek u baletní tyče potřebuje 6/5 – ve 4/3 mu chybí 2,5 % výšky a uřízne
   se přesně oporná noha (změřeno, rozpětí postavy je 0,432 výšky zdroje, tedy
   nejvýš poměr 1,30). Zatím jediná lekce, která výjimku potřebuje. */
.ldx__media--vysoky img { aspect-ratio: 6/5; }
/* ⚠️ NA PROFILU LEKTORA JE RÁM NA VÝŠKU, PROTOŽE PORTRÉTY JSOU NA VÝŠKU.
   Ve 4/3 ukáže `cover` z portrétu 900×1200 jen prostředních 56 % výšky, takže
   Maxovi uřízlo hlavu. Posunout `object-position` nestačí: Tomáš dělá stojku
   a hlavu má DOLE, ostatní nahoře, takže jedna hodnota nesedí na všechny.
   🔴 A 5/6 TAKY NESTAČILO (27. 8. 2026). Jakub poslal snímek profilu Maxe:
   „oprav Maxe, ať tam má celej obličej a tělo." Rám 5/6 (0,833) je pořád širší
   než soubor 3/4 (0,75), takže `cover` ubíral 10 % VÝŠKY, půlku shora, a to
   je přesně Maxova hlava. Změřeno ve zdroji: vlasy mu začínají na 28 % výšky
   a chodidla končí na 97 %, tedy pod nohama jsou jen 3 % rezervy. Přegenerovat
   soubor s větším okrajem proto NEJDE, ve zdroji to místo není.
   ✅ Řešení je rám 3/4, tedy PŘESNĚ poměr souborů (900×1200): neořízne se nic.
   Ověřeno na všech čtyřech profilech (`scratchpad/lektor-ram.mjs`) — Max má
   celou postavu i chodidla, Tomášovi se vrátily ruce a Kubovi (640×696) se
   uberou jen boky, kde má prázdné pozadí.
   Omezeno na `data-page="lektor"` — stránky lekcí mají fotky na šířku a tam
   4/3 sedí. */
body[data-page="lektor"] .ldx__media img { aspect-ratio: 3/4; }
.ldx__points { margin-top: 26px; display: grid; gap: 18px; }
.ldx__point strong { display: block; font-family: var(--f-body); font-weight: 600; font-size: .78rem; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); margin-bottom: 5px; }
.ldx__point p { color: var(--muted); }
.ldx__price { margin-top: 18px; border-radius: var(--r-lg); box-shadow: inset 0 0 0 1px var(--line); overflow: hidden; }
.ldx__price-row { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 14px 18px; border-bottom: 1px solid var(--line); background: var(--surface); }
.ldx__price-row:last-child { border-bottom: none; }
.ldx__price-row strong { font-family: var(--f-display); font-weight: 600; font-size: 1.3rem; color: var(--accent); white-space: nowrap; }
[data-page="lekce-detail"] .lesson__figure { max-width: 300px; margin-inline: auto; }
[data-page="lekce-detail"] .bodyfig { max-width: 320px; }
.chipcloud { display: flex; flex-wrap: wrap; gap: 10px; }
.chipcloud .tag--accent { font-size: .78rem; padding: 7px 14px; }
/* Čísla se dřív vznášela v prázdnu: neměla žádnou strukturu a pod nimi zůstávala
   díra, protože textový sloupec vedle je vyšší. Vlasové linky je zasadí do mřížky
   (stejný princip jako pás .statbar na homepage) a dotažení na výšku textu tu díru
   zavře — blok tak začíná i končí spolu s textem. */
.minigrid { display: grid; grid-template-columns: 1fr 1fr; gap: 0;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.minigrid > * { position: relative; padding: clamp(20px, 2.6vw, 28px) clamp(14px, 2vw, 24px); }
.minigrid > *:nth-child(2n+1) { padding-left: 0; }   /* levý sloupec lícuje s okrajem */
/* svislá linka mezi sloupci */
.minigrid > *:nth-child(2n)::before { content: ""; position: absolute; left: 0; top: 18%; bottom: 18%;
  width: 1px; background: var(--line); }
/* vodorovná linka mezi řádky */
.minigrid > *:nth-child(n+3)::after { content: ""; position: absolute; top: 0; left: 0; right: 0;
  height: 1px; background: var(--line); }
.minigrid .statbar__n { font-family: var(--f-display); font-weight: 500; font-size: clamp(2rem, 3.6vw, 3rem); line-height: 1; }
.minigrid .statbar__n .accent { color: var(--accent); }
.minigrid .statbar__l { margin-top: 8px; font-size: .82rem; color: var(--muted); }

/* Jen sekce s čísly se protahuje na výšku sousedního textu. Sahat na .ldx globálně
   nejde — stejný layout nese i bloky s fotkou, ty by se roztáhly taky. */
.ldx--stats { align-items: stretch; }
.ldx--stats > *:last-child { display: flex; }
.ldx--stats .minigrid { flex: 1; grid-template-rows: 1fr 1fr; }
.ldx--stats .minigrid > * { display: flex; flex-direction: column; justify-content: center; }
@media (max-width: 860px) { .ldx { grid-template-columns: 1fr; } }
/* Grid položky mají min-width: auto — dlouhý řádek ceníku (popis + cena, která se
   nesmí zalomit) roztáhl sloupec nad šířku displeje. */
.ldx > * { min-width: 0; }
@media (max-width: 420px) { .ldx__price-row { flex-wrap: wrap; gap: 4px 16px; } }

/* `.cat-dot` a odstíny kategorií (.cat-pilates …) tu byly do 13. 8. 2026 —
   barevný puntík u času v rozvrhu. Puntíky před textem šly z webu pryč, a jinde
   se ty barvy nepoužívaly, takže odsud zmizely taky. */

/* ============================================================
   ROZVRH
   ============================================================ */
.sched { position: relative; }
/* ⚠️ ROZVRH SE UŽ Z KONTEJNERU NEVYLÉVÁ (13. 8. 2026). Dřív si bral o 130 px na
   každou stranu navíc, aby se sedm sloupců nemačkalo — jenže tím byl jediný
   blok na stránce, který nelícoval s nadpisem, drobečky ani se sekcí pod ním.
   Sloupce ale opravdu potřebuje: v 1180px kontejneru vyjde 136 px a láme se
   v nich jak jméno lektora, tak datum v hlavičce dne (a hlavičky pak končí
   každá jinde). Řešení je proto opačné — ne vylít rozvrh z mřížky, ale
   ROZŠÍŘIT CELOU STRÁNKU ROZVRHU, aby s ním lícoval i zbytek. */
.sched { margin-inline: 0; }
body[data-page="rozvrh"] { --maxw: 1400px; }
/* Pod 1200 px by sedm sloupců kleslo pod čitelnou šířku → kalendář se posouvá
   vodorovně a sloupce drží pevné minimum. Týden zůstane týdnem, jen se v něm roluje. */
@media (max-width: 1199px) {
  .sched__days:not(.is-seznam) { grid-template-columns: repeat(var(--sched-cols, 7), 172px); overflow-x: auto;
    padding-bottom: 10px; scroll-snap-type: x proximity; overscroll-behavior-x: contain; }
  .sched__days:not(.is-seznam) > .day { scroll-snap-align: start; }
}
.sched__bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 24px; }
.sched__filters { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 24px; }
.sched__bar .sched__filters { margin-bottom: 0; }
/* Filtr = vlastní rozbalovací seznam. Nativní <select> tu byl dřív, ale popup si
   kreslí operační systém — na macOS se rozbalí PŘES tlačítko, překryje vybranou
   hodnotu a CSS s tím nic nesvede. Tohle je tlačítko + seznam pod ním. */
.fsel { position: relative; display: inline-flex; align-items: center; gap: 8px; padding: 6px 8px 6px 14px;
  border-radius: var(--r-pill); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-2); transition: box-shadow .3s; }
.fsel:focus-within, .fsel.is-open { box-shadow: inset 0 0 0 1px var(--accent); }
.fsel__l { font-family: var(--f-label); font-size: .66rem; letter-spacing: .13em; text-transform: uppercase; color: var(--muted-2); }
.fsel__btn { display: inline-flex; align-items: center; gap: 8px; background: none; border: 0; cursor: pointer;
  font: inherit; font-size: .88rem; font-weight: 500; color: var(--text); padding: 4px 2px 4px 0; text-align: left; }
.fsel__val { max-width: min(210px, 44vw); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fsel__chev { flex: none; width: 14px; height: 14px; background: currentColor; color: var(--accent);
  -webkit-mask: var(--chev) center / 14px no-repeat; mask: var(--chev) center / 14px no-repeat;
  transition: transform .25s var(--ease); }
.fsel.is-open .fsel__chev { transform: rotate(180deg); }
.fsel__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

/* Seznam se otevírá VŽDY vedle tlačítka, nikdy přes něj. Pozici (top/left) dopočítává
   app.js — fixed proto, aby ho neuřízl panel s `overflow: hidden` v členské sekci. */
/* z-index nad lištou cookies (250) i navigací (100) — seznam je krátkodobý překryv,
   který si klient sám otevřel, a nesmí ho nic zakrýt. */
.fsel__menu { position: fixed; z-index: 260; max-width: min(280px, 86vw);
  overflow-y: auto; margin: 0; padding: 6px; list-style: none;
  background: var(--surface); border-radius: var(--r); box-shadow: inset 0 0 0 1px var(--line-2), var(--sh);
  animation: fselIn .16s var(--ease) both; }
.fsel.fsel--up .fsel__menu, .fsel__menu.is-up { animation-name: fselInUp; }
@keyframes fselIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@keyframes fselInUp { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.fsel__opt { padding: 9px 12px; border-radius: calc(var(--r) - 6px); cursor: pointer; white-space: nowrap;
  font-size: .88rem; color: var(--text); transition: background .18s, color .18s; }
.fsel__opt:hover, .fsel__opt:focus-visible { background: var(--accent-soft); color: var(--accent); outline: none; }
.fsel__opt.is-sel { font-weight: 600; color: var(--accent); }
/* Odsazení na fajfku má i nevybraná položka, jinak text při výběru poskočí. */
.fsel__opt::before { content: ""; display: inline-block; width: 15px; }
.fsel__opt.is-sel::before { content: "✓"; font-weight: 700; }
@media (prefers-reduced-motion: reduce) { .fsel__menu { animation: none; } .fsel__chev { transition: none; } }
.sched__count { font-size: .85rem; color: var(--muted); margin-left: 4px; font-variant-numeric: tabular-nums; }
.sched__clear { font-size: .85rem; font-weight: 600; color: var(--accent); padding: 6px 10px; border-radius: var(--r-pill);
  cursor: pointer; transition: background .3s; }
.sched__clear:hover { background: var(--accent-soft); }
.sched__week { display: inline-flex; align-items: center; gap: 6px; }
.sched__wlabel { font-family: var(--f-display); font-weight: 600; font-size: 1.05rem; min-width: 132px; text-align: center; font-variant-numeric: tabular-nums; }
.sched__arrow { width: 40px; height: 40px; border-radius: 50%; flex: none; display: grid; place-items: center; color: var(--text);
  box-shadow: inset 0 0 0 1px var(--line-2); transition: color .3s, box-shadow .3s, background .3s; }
.sched__arrow:hover:not([disabled]) { background: var(--text); color: var(--bg); }
.sched__arrow[disabled] { opacity: .35; cursor: default; }
.sched__arrow svg { width: 19px; height: 19px; }
/* Kalendář: dny vedle sebe na jednom řádku. Dřív tu bylo auto-fill minmax(168px),
   které i na 1920 px vyrobilo 5 sloupců a týden zalomilo na dva řádky — nešlo to
   číst jako týden. Počet sloupců nastavuje app.js do --sched-cols: dny, kdy se
   vůbec necvičí (sobota), se do rozvrhu nekreslí. */
/* `align-items: start` (19. 8. 2026): dřív se všech sedm sloupců natáhlo na
   výšku toho nejdelšího, takže pátek, sobota a neděle byly ze tří čtvrtin
   prázdné rámečky. Den je teď vysoký přesně podle toho, co v něm je. */
.sched__days { display: grid; grid-template-columns: repeat(var(--sched-cols, 7), minmax(0, 1fr));
  gap: 14px; align-items: start; }
/* Přepínač „pod sebou" — den po dni, užitečné hlavně na telefonu. */
.sched__days.is-seznam { grid-template-columns: 1fr; overflow: visible; }
.day { background: var(--surface); border-radius: var(--r-lg); box-shadow: inset 0 0 0 1px var(--line);
  padding: 14px 12px 6px; min-height: 0; }
.day__h { font-family: var(--f-body); font-weight: 600; font-size: 1rem;
  padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid var(--line); display: flex; justify-content: space-between; align-items: baseline; }
.day__h .d { color: var(--muted-2); font-family: var(--f-body); font-size: .72rem; font-weight: 500; white-space: nowrap; }
.day__wd { display: inline-flex; align-items: center; gap: 8px; }
/* V kalendáři je sloupec úzký — hlavička se do něj musí vejít na jeden řádek.
   Bez tohohle se „20. 7." lámalo za tečkou a odznak „Proběhlo" ukrojil půl sloupce. */
.sched__days:not(.is-seznam) .day__h { gap: 6px; flex-wrap: wrap; }
.sched__days:not(.is-seznam) .day__wd { gap: 6px; min-width: 0; }
.sched__days:not(.is-seznam) .day__past,
.sched__days:not(.is-seznam) .day__today { font-size: .52rem; padding: 3px 6px; letter-spacing: .06em; }
/* dnešek — zvýrazněný jako aktivní den */
.day.is-today { box-shadow: inset 0 0 0 1.5px var(--accent-line); }
.day.is-today .day__h { color: var(--accent); border-bottom-color: var(--accent-line); }
.day__today { font-family: var(--f-body); font-size: .58rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--surface); background: var(--accent); padding: 3px 8px; border-radius: 999px; line-height: 1; }
/* proběhlý den — odlišený štítkem „Proběhlo" + tlumeným záhlavím + tlumenými sloty (is-past).
   Bez opacity fade: ten by srážel kontrast drobného textu pod WCAG AA. */
.day.is-pastday .day__h { color: var(--muted-2); }
.day.is-pastday .day__h .d { color: var(--muted-2); }
.day__past { font-family: var(--f-body); font-size: .58rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted-2); background: var(--bg-2); padding: 3px 8px; border-radius: 999px; line-height: 1;
  box-shadow: inset 0 0 0 1px var(--line); }
.day__empty { color: var(--muted-2); font-size: .82rem; padding: 6px 2px 12px; }

.slot {
  /* Barva rámečku jde přes proměnnou schválně: kdyby se přepisoval rovnou
     box-shadow, přebily by stavové selektory níž hover a ten by přestal fungovat. */
  --slot-ring: var(--line); --slot-ring-w: 1px;
  display: block; width: 100%; text-align: left; background: var(--surface-2); border-radius: var(--r); padding: 12px 13px;
  margin-bottom: 9px; box-shadow: inset 0 0 0 var(--slot-ring-w) var(--slot-ring); transition: transform .3s var(--ease), box-shadow .3s; cursor: pointer;
}
.slot:hover, .slot:focus-visible { transform: translateY(-3px); background: var(--accent-soft); box-shadow: inset 0 0 0 1.5px var(--accent-line), var(--sh); }
.slot:hover .slot__n, .slot:focus-visible .slot__n { color: var(--accent); }
/* Čas vlevo, stav vpravo. `gap` je minimum, o zbytek se stará space-between —
   u dlouhého štítku („Kurz · zápis předem") se tak čas nikam neposune. */
/* `flex-wrap` je pojistka, ne dekorace: u admina má štítek podobu „0/12 obsazeno"
   a v nejužším sloupci by se vedle času nevešel. Radši spadne na vlastní řádek,
   než aby přetekl z karty. */
.slot__top { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  flex-wrap: wrap; margin-bottom: 6px; }
.slot__t { font-family: var(--f-body); font-weight: 600; font-size: .8rem; color: var(--accent); }
.slot__n { font-family: var(--f-body); font-weight: 600; font-size: .97rem; line-height: 1.2; }
.slot__m { font-family: var(--f-body); font-size: .75rem; color: var(--muted); margin-top: 2px; line-height: 1.3; }
/* Stav je ŠTÍTEK, ne věta pod kartou: v úzkém sloupci se text lámal a karta
   kvůli němu narostla o dva řádky. Barvu nese pozadí, ne jen písmo, takže se
   stav pozná i koutkem oka při rolování. */
/* Velikost je vyladěná tak, aby se „PROBĚHLO" i „VOLNO" vešly vedle času do
   nejužšího sloupce kalendáře (~144 px). Při .66rem a rozpalu .04em to o čtyři
   pixely nevycházelo a štítek padal na druhý řádek jen u některých karet —
   rozvrh pak vypadal rozhozeně. */
.slot__cap { font-family: var(--f-body); font-size: .63rem; font-weight: 600; letter-spacing: .02em;
  text-transform: uppercase; color: var(--muted-2); background: var(--bg-2); border-radius: 999px;
  padding: 3px 7px; line-height: 1.25; white-space: nowrap; flex: 0 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; }
.slot:not(.is-past):not(.is-cancelled):not(.is-full):not(.is-kurz) .slot__cap {
  color: #40602F; background: rgba(92,124,82,.14); }
.slot__cap.is-mine { color: var(--surface); background: var(--accent); }
.slot.is-full { opacity: .6; }
.slot.is-full .slot__cap { color: #8A3327; background: rgba(176,71,59,.12); }
.slot.is-kurz .slot__cap { color: var(--accent); background: var(--accent-soft); }
/* Zelený rámeček = na lekci se ještě dá jít. Vyřazeny plné, zrušené i proběhlé —
   u těch by zelená slibovala něco, co neplatí. */
.slot:not(.is-past):not(.is-cancelled):not(.is-full):not(.is-kurz) { --slot-ring: var(--ring-ok); --slot-ring-w: 1.5px; }
/* Kurz má bronzový rámeček, ne zelený (19. 8. 2026). Zelená na webu znamená
   „dá se rezervovat" — u kurzu to neplatí, ten se zapisuje předem. Rámeček tak
   drží stejnou barvu jako jeho štítek a rozvrh se dá číst i bez čtení štítků:
   zelená = klikni a rezervuj, bronzová = kurz. */
.slot.is-kurz:not(.is-past):not(.is-cancelled) { --slot-ring: rgba(154,122,74,.55); --slot-ring-w: 1.5px; }
body[data-app] .slot.is-kurz:not(.is-past):not(.is-cancelled) { --slot-ring: rgba(199,165,106,.5); }
/* proběhlé lekce: tlumené barvou (ne opacity) → zůstává čitelný kontrast (WCAG) */
/* Proběhlá lekce má NEUTRÁLNÍ rámeček (19. 8. 2026). Červenavý `--ring-past`
   dělal z každého uplynulého dne varování — Jakub na to ukázal na screenshotu
   rozvrhu, kde pondělí a úterý svítily do růžova. Že je po lekci, řekne štítek. */
.slot.is-past { cursor: default; background: var(--bg-2); --slot-ring: var(--line); --slot-ring-w: 1px; }
.slot.is-past .slot__t, .slot.is-past .slot__n, .slot.is-past .slot__m { color: var(--muted-2); }
.slot.is-past:hover { transform: none; background: var(--bg-2); box-shadow: inset 0 0 0 var(--slot-ring-w) var(--slot-ring); }
/* zrušený výskyt lekce (malá účast) — rámeček schválně neutrální, ne červený:
   jinak by splynul s proběhlými. Odliší ho přeškrtnutí a červené „Zrušeno“. */
.slot.is-cancelled { cursor: default; background: var(--bg-2); --slot-ring: var(--line-2); }
/* Přeškrtnutí si NEkreslí prohlížeč: `line-through` sedí na metrice fontu, která
   je nastavená pro malá písmena, takže přes číslice („18:00–18:55") a velká
   písmena jede vysoko. Čáru proto maluje pozadí spanu přesně na 50 % výšky
   řádku. `box-decoration-break: clone` ji udrží i u názvu, který se zalomí. */
.slot.is-cancelled .slot__t, .slot.is-cancelled .slot__n, .slot.is-cancelled .slot__m { color: var(--muted-2); text-decoration: none; }
.slot.is-cancelled .slot__t > span,
.slot.is-cancelled .slot__n > span,
.slot.is-cancelled .slot__m > span {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 100% 1.5px; background-position: 0 50%; background-repeat: no-repeat;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
.slot.is-cancelled .slot__cap { color: #8A3327; font-weight: 700; }
.slot.is-cancelled:hover { transform: none; background: var(--bg-2); box-shadow: inset 0 0 0 var(--slot-ring-w) var(--slot-ring); }
.slot.is-hidden { display: none; }

/* ---------- ROZVRH PO DNECH (výchozí na telefonu) ----------
   Sedm sloupců se na 390 px přečíst nedá a týden pod sebou znamená rolovat
   přes všechny dny, i když člověk hledá jedno odpoledne. Pruh nahoře proto
   ukazuje celý týden (kdy se cvičí a kolik toho je) a pod ním je JEDEN den. */
.sched__days.is-den { display: block; }
/* Sedm dní se vejde vedle sebe, dokud má každý aspoň 44 px (dotykové minimum).
   Na 320px displeji se nevejdou, proto se pruh raději roluje, než aby se dny
   zmáčkly na 36 px a člověk ťukal vedle. */
.dstrip { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(44px, 1fr); gap: 6px;
  margin-bottom: 16px; overflow-x: auto; scroll-snap-type: x proximity;
  overscroll-behavior-x: contain; scrollbar-width: none; padding-bottom: 2px; }
.dstrip::-webkit-scrollbar { display: none; }
.dstrip__b { scroll-snap-align: center; }
.dstrip__b {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 9px 2px 8px; min-height: 62px; border-radius: var(--r);
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--line);
  font-family: var(--f-body); cursor: pointer;
  transition: background .2s, box-shadow .2s, color .2s;
}
.dstrip__wd { font-size: .68rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.dstrip__d { font-size: 1.02rem; font-weight: 600; line-height: 1.1; }
/* Počet lekcí v daném dni. Bez něj člověk ťuká naslepo a v půlce dnů najde prázdno. */
.dstrip__n { font-size: .64rem; font-weight: 600; color: var(--muted-2); line-height: 1; }
.dstrip__b.is-empty .dstrip__wd, .dstrip__b.is-empty .dstrip__d, .dstrip__b.is-empty .dstrip__n { color: var(--muted-2); }
.dstrip__b.is-past { background: var(--bg-2); }
.dstrip__b.is-past .dstrip__wd, .dstrip__b.is-past .dstrip__d { color: var(--muted-2); }
.dstrip__b.is-today { box-shadow: inset 0 0 0 1.5px var(--accent-line); }
.dstrip__b.is-today .dstrip__wd { color: var(--accent); }
/* Vybraný den je plný, ne jen orámovaný: na telefonu se orámování ztratí. */
.dstrip__b.is-active { background: var(--accent); box-shadow: none; }
.dstrip__b.is-active .dstrip__wd,
.dstrip__b.is-active .dstrip__d,
.dstrip__b.is-active .dstrip__n { color: var(--surface); }
.dstrip__b:hover:not(.is-active) { background: var(--surface-2); box-shadow: inset 0 0 0 1.5px var(--accent-line); }

/* Karta dne, když je na stránce sama */
.day--solo { padding: 16px 14px 8px; }
.day--solo .day__h { font-size: 1.15rem; }
.day--solo .slot { padding: 14px; }
.day--solo .slot__n { font-size: 1.05rem; }
.day--solo .slot__m { font-size: .82rem; }
/* Delší půlka štítku kurzu se ukazuje jen tam, kde je na ni místo — tedy
   v jednom dni a v seznamu, ne v sedmi sloupcích kalendáře. Ze stejného důvodu
   je v kalendáři štítek o kousek menší: na 1280px displeji vyjde sloupec na
   129 px a při .63rem se „PROBĚHLO" vedle času nevešlo. */
.sched__days:not(.is-den):not(.is-seznam) .slot__cap-l { display: none; }
.sched__days:not(.is-den):not(.is-seznam) .slot__cap { font-size: .58rem; padding: 3px 6px; }
/* Prázdný štítek (proběhlý den, kde stav nese hlavička) drží čas na svém místě
   a nic nekreslí. */
.slot__cap--zadny { padding: 0; background: none; }
.day--solo .day__empty { padding: 14px 2px 18px; }

/* Kurzy pod rozvrhem — zapisuje se předem, nerezervuje online (Reformer, funkční, MOVEKIDS) */
.courses { margin-top: 44px; padding-top: 34px; border-top: 1px solid var(--line); }
.courses[hidden] { display: none; }
.courses__head { max-width: 62ch; margin-bottom: 24px; }
.courses__title { font-size: clamp(1.35rem, 2.6vw, 1.85rem); letter-spacing: -.015em; }
.courses__lead { margin-top: 10px; color: var(--muted); line-height: 1.7; }
.courses__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; }
.course { display: flex; flex-direction: column; gap: 12px; padding: 22px 22px 20px; background: var(--bg-2);
  border-radius: var(--r-lg); box-shadow: inset 0 0 0 1px var(--line); }
.course__n { display: flex; align-items: center; gap: 9px; font-size: 1.06rem; letter-spacing: -.01em; }
/* Krátký štítek, ne odstavec — proto prostrkané drobné písmo jako u ostatních
   popisků, ne blok textu. */
.course__how { color: var(--muted-2); font-family: var(--f-label); font-size: .74rem;
  letter-spacing: .06em; text-transform: uppercase; }
.course__times { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.course__times li { display: flex; flex-direction: column; gap: 2px; padding-top: 9px; border-top: 1px dashed var(--line); }
.course__times li:first-child { padding-top: 0; border-top: 0; }
.course__times strong { font-size: .82rem; font-weight: 600; color: var(--text); }
.course__times span { font-size: .86rem; color: var(--muted); line-height: 1.5; font-variant-numeric: tabular-nums; }
/* Jeden řádek na den — zkratka dne ve vlastním sloupci, aby časy začínaly pod sebou. */
.course__day { display: grid; grid-template-columns: 2.1em 1fr; gap: 8px; align-items: baseline; margin-top: 3px; }
.course__day:first-of-type { margin-top: 0; }
.course__times .course__d { font-size: .78rem; font-weight: 600; color: var(--muted-2); }
.course .btn { margin-top: auto; align-self: flex-start; }
/* celá karta kurzu je odkaz — bez hledání tlačítka */
.course--link { position: relative; cursor: pointer; }
.course--link .btn { pointer-events: none; }
.course__link { position: absolute; inset: 0; border-radius: inherit; }
.course__link:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
.course--link:hover .btn, .course--link:focus-within .btn { background: var(--text); color: var(--bg); box-shadow: none; }

/* ============================================================
   NOVINKY — výpis, detail, pruh na homepage
   ============================================================ */
.news { display: grid; gap: 2px; margin-top: 8px; }
.news__item { border-top: 1px solid var(--line); }
.news__item:last-child { border-bottom: 1px solid var(--line); }
.news__link { display: block; padding: 26px 4px; text-decoration: none; color: inherit;
  transition: background .25s var(--ease), padding-left .25s var(--ease); border-radius: var(--r-lg); }
.news__link:hover { background: var(--bg-2); padding-left: 16px; }
.news__date { display: block; font-size: .8rem; letter-spacing: .04em; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; }
.news__title { font-size: clamp(1.25rem, 2.4vw, 1.7rem); letter-spacing: -.015em; }
.news__perex { margin-top: 8px; color: var(--muted); line-height: 1.6; max-width: 68ch; }
.news__more { display: inline-block; margin-top: 12px; font-size: .88rem; font-weight: 600; color: var(--accent); }

/* margin-top drží stejný odstup od drobečkové navigace jako mají detaily lekcí (18 px) —
   bez něj se datum novinky lepilo přímo na drobečkovou navigaci */
/* ⚠️ Sekce musí klipovat, kroužek jinak roztáhne rolovací plochu do strany. */
.post-sekce { position: relative; overflow: hidden; }
.post-koncept { background: var(--accent-soft); color: var(--accent); border-radius: 10px;
  padding: 10px 14px; margin: 0 0 18px; font-size: .9rem;
  box-shadow: inset 0 0 0 1px var(--accent-line); }
.post { max-width: 68ch; margin-top: 18px; }
/* Hlavička článku: nadpisek s linkou, velký serif, perex jako lead a datum až
   pod tím. Datum nahoře bralo pozornost dřív než titulek, přitom u novinky
   z gymu je to ta nejméně důležitá informace. */
.post__head { margin-bottom: 30px; padding-bottom: 24px; border-bottom: 1px solid var(--line); }
.post__perex { font-size: clamp(1.02rem, 1.5vw, 1.22rem); line-height: 1.6; color: var(--muted);
  margin: 12px 0 0; }
.post__meta { margin: 18px 0 0; font-family: var(--f-label); font-size: .76rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted-2); }
/* Fotka v těle novinky dostane rám i rádius, ať nevypadá jako vložený soubor. */
.post__body img { max-width: 100%; height: auto; display: block; margin: 26px 0;
  border-radius: var(--r-lg); box-shadow: inset 0 0 0 1px var(--line); }
.post__body > p:first-of-type { font-size: 1.06em; }
.post__pata { margin-top: 38px; padding-top: 26px; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.post__title { font-size: clamp(1.8rem, 4vw, 2.8rem); letter-spacing: -.02em; margin: 8px 0 4px; }
.post__body { line-height: 1.8; color: var(--text); }
.post__body p { margin-bottom: 1.1em; }
.post__body ul { margin: 0 0 1.1em; padding-left: 1.3em; list-style: disc; }
.post__body ul::marker, .post__body li::marker { color: var(--accent); }
.post__body li { margin-bottom: .4em; }
.post__body a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
/* Novinky se od 17. 8. 2026 píšou ve WYSIWYG editoru, takže sem přiteče i to,
   co dřív nešlo: číslovaný seznam, mezinadpis, odsazení, obrázek a velikosti
   písma. Server pouští jen tyhle značky (`functions/_lib/sanitize.js`), takže
   je tenhle seznam úplný — co není níž, na stránce nevznikne. */
.post__body ol { margin: 0 0 1.1em; padding-left: 1.45em; list-style: decimal; }
.post__body h2 { font-size: clamp(1.3rem, 2.4vw, 1.7rem); margin: 1.6em 0 .5em; }
.post__body h3 { font-size: 1.15rem; margin: 1.4em 0 .4em; }
.post__body h2:first-child, .post__body h3:first-child { margin-top: 0; }
.post__body blockquote { margin: 0 0 1.1em; padding-left: 18px; border-left: 2px solid var(--line-2); }
.post__body img { max-width: 100%; height: auto; border-radius: var(--r); margin: .4em 0 1.2em; display: block; }
.post__body hr { border: 0; border-top: 1px solid var(--line); margin: 2em 0; }
/* Editor ukládá velikost jako klíčové slovo (`font-size: large`), což je proti
   okolnímu textu skok. Přepočet na em drží velikosti v rozumném rozsahu. */
.post__body [style*="font-size: x-small"] { font-size: .8em; }
.post__body [style*="font-size: small"] { font-size: .9em; }
.post__body [style*="font-size: large"] { font-size: 1.15em; }
.post__body [style*="font-size: x-large"] { font-size: 1.35em; }
.post__body [style*="font-size: xx-large"] { font-size: 1.6em; }

/* ============================================================
   AKTUALITY — rám s posledními novinkami na homepage
   Dřív tu byl tmavý pruh přes celou šířku. Tvarem (zaoblený blok se stínem
   plovoucí na ivory) se ale hlásil ke cookie liště, takže ho čtenář četl jako
   systémové hlášení, ne jako obsah od gymu. Teď je to obyčejný rám ve stejné
   řeči jako zbytek webu; čerstvost nese datum, ne tmavé pozadí.
   ============================================================ */
/* Řádky v jednom rámu nahradily čtvercové karty (přání majitele, 16. 8. 2026).
   Čtverec drží `aspect-ratio: 1` a mřížka má pevný počet sloupců — s `auto-fill`
   by jedna novinka roztáhla kartu přes celou šířku a čtverec by z ní byl
   plakát. Server posílá nejvýš tři novinky, takže se na desktopu vejdou vedle
   sebe v jedné řadě. Hlavička zůstala nad mřížkou jako řádek s linkou. */
/* ⚠️ 10 px odshora i zdola bylo málo. Pod aktualitami začíná pás se službami
   (`.marquee`) a nad nimi statbar, takže karta byla vmáčknutá mezi dva pruhy
   a působila jako jejich součást. Oddělení musí být větší než mezera uvnitř
   karty, jinak se sekce opticky slije s okolím. */
.akt { margin: clamp(30px, 4vw, 54px) 0 clamp(38px, 5vw, 66px); }
.akt__head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.akt__title { font-family: var(--f-label); font-size: .72rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--muted-2); margin: 0; }
.akt__all { font-size: .84rem; font-weight: 600; color: var(--accent); text-decoration: none; white-space: nowrap; }
.akt__all:hover { text-decoration: underline; }

/* Karty se drží uprostřed, ať jich je kolik chce. Mřížka to neumí — `grid` má
   sloupce napevno, takže jedna novinka zůstane viset vlevo a dvě třetiny řady
   jsou prázdné. Proto flex: šířku karty počítá `flex-basis` ze stejného vzorce
   jako by měl sloupec v mřížce (100 % minus mezery, děleno počtem sloupců),
   takže jedna, dvě i tři novinky jsou pořád stejně velké čtverce – ale ta řada
   se vycentruje. Počet sloupců mění jen proměnná `--akt-sloupce` v media query. */
.akt__grid { --akt-mezera: clamp(12px, 1.6vw, 18px); --akt-sloupce: 3;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: var(--akt-mezera); margin-top: clamp(14px, 2vw, 20px); }

/* Celá karta je odkaz, uvnitř žádné tlačítko „číst“ (stejně jako karty lekcí). */
.akt__card { flex: 0 0 calc((100% - (var(--akt-sloupce) - 1) * var(--akt-mezera)) / var(--akt-sloupce));
  display: flex; flex-direction: column; aspect-ratio: 1; overflow: hidden;
  padding: clamp(18px, 2vw, 26px); border-radius: var(--r); background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line-2); text-decoration: none; color: inherit;
  transition: transform .45s var(--ease), box-shadow .45s var(--ease); }
.akt__card:hover, .akt__card:focus-visible { transform: translateY(-3px); outline: none;
  box-shadow: inset 0 0 0 1px var(--accent), var(--sh-lg); }
.akt__card:hover .akt__name, .akt__card:focus-visible .akt__name { color: var(--accent); }
.akt__date { display: block; font-family: var(--f-label); font-size: .74rem; font-weight: 500;
  letter-spacing: .04em; color: var(--muted-2); font-variant-numeric: tabular-nums; }
/* Text sedí u dolní hrany, ne nahoře. Krátká novinka („Nové činky / 10 kg 2×")
   by jinak visela v horním rohu a zbytek čtverce vypadal jako nedodělaný. */
.akt__body { display: block; min-width: 0; margin-top: auto; padding-top: 14px; }
/* Text se nesmí rozrůst přes hranu čtverce, proto se láme na daný počet řádků. */
.akt__name { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  font-family: var(--f-display); font-size: clamp(1.08rem, 1.5vw, 1.28rem); font-weight: 500;
  line-height: 1.25; transition: color .25s var(--ease); }
.akt__perex { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
  font-size: .9rem; color: var(--muted); line-height: 1.5; margin-top: 8px; }
.akt__arrow { align-self: flex-start; margin-top: 14px;
  color: var(--accent); font-size: 1.05rem; transition: transform .25s var(--ease); }

/* Náhled fotky z novinky. Karta zůstává čtvercem a fotka si bere prostor, který
   po datu a textu zbyde — krátká novinka („mobil / ss") tak nemá v kartě prázdno
   a dlouhá fotku jen zúží. `min-height` je pojistka, aby z náhledu nikdy nebyl
   proužek; radši se karta o pár pixelů natáhne pod čtverec, než aby v ní byla
   fotka vysoká 20 px. Text se u karty s fotkou láme dřív, ať na ni zbyde místo. */
.akt__photo { display: block; flex: 1; min-height: 84px; margin-top: 12px; overflow: hidden;
  border-radius: calc(var(--r) - 4px); background: var(--surface-2);
  box-shadow: inset 0 0 0 1px var(--line); }
.akt__photo img { display: block; width: 100%; height: 100%; object-fit: cover;
  transition: transform .9s var(--ease); }
.akt__card--foto:hover .akt__photo img,
.akt__card--foto:focus-visible .akt__photo img { transform: scale(1.04); }
/* `margin-top: auto` na textu tlačí obsah k dolní hraně. S fotkou, která volné
   místo vyplní sama, by se o ně obojí přetahovalo. */
.akt__card--foto .akt__body { margin-top: 0; }
.akt__card--foto .akt__name { -webkit-line-clamp: 2; }
.akt__card--foto .akt__perex { -webkit-line-clamp: 2; }

/* Pod 900 px se tři čtverce vedle sebe zúží tak, že se do nich nevejde titulek,
   proto dva sloupce a na telefonu jeden. */
@media (max-width: 900px) { .akt__grid { --akt-sloupce: 2; } }
/* Karta novinky zůstává čtverec i když je novinka jedna — Jakubovo rozhodnutí
   z 25. 8. Aby v ní nezůstala díra, nemá obsah tlačený k dolní hraně napevno:
   datum je nahoře, text u dolního okraje a mezi nimi je pružné místo, které
   vyplní fotka, když novinka nějakou má. Šipka je v kroužku, na prázdné ploše
   je samotný znak ztracený. */
.akt__arrow { width: 42px; height: 42px; display: grid; place-items: center;
  border-radius: 50%; box-shadow: inset 0 0 0 1px var(--accent-line); color: var(--accent);
  transition: background .35s var(--ease), transform .35s var(--ease); }
.akt__card:hover .akt__arrow { background: var(--accent-soft); transform: translateX(3px); }

@media (max-width: 560px) {
  .akt__grid { --akt-sloupce: 1; }
  .akt__name { -webkit-line-clamp: 2; }
  /* Na telefonu je karta přes celou šířku, takže čtverec je vysoký přes 350 px.
     Novinka bez fotky ho nemá čím zaplnit a v kartě zůstane díra mezi datem
     a textem. S fotkou čtverec smysl dává, ta prostor vyplní. */
  .akt__card:not(.akt__card--foto) { aspect-ratio: auto; }
}
@media (prefers-reduced-motion: reduce) { .akt__arrow, .akt__name, .akt__card, .akt__photo img { transition: none; } }

/* ============================================================
   CENÍK / PLÁNY
   ============================================================ */
.plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2vw, 24px); align-items: stretch; }
.plan {
  position: relative; background: var(--surface); border-radius: var(--r-lg); overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line); padding: clamp(26px, 3vw, 38px);
  display: flex; flex-direction: column; transition: transform .45s var(--ease), box-shadow .45s var(--ease); }
.plan > * { position: relative; z-index: 1; }
.plan:hover { transform: translateY(-3px); box-shadow: inset 0 0 0 1px var(--line-2), var(--sh); }
.plan--featured { box-shadow: inset 0 0 0 1px var(--accent-line), var(--sh); }
.plan__badge { align-self: flex-start; font-family: var(--f-label); font-size: .66rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--accent); padding: .4em 0; margin-bottom: 16px; position: relative; }
.plan__badge::after { content: ""; display: block; width: 28px; height: 1px; background: var(--accent); margin-top: 8px; }
.plan__name { font-family: var(--f-display); font-weight: 600; font-size: 1.55rem; }
.plan__for { color: var(--muted); font-size: .92rem; margin-top: 8px; }
.plan__price { margin: 24px 0 4px; display: flex; align-items: baseline; gap: .35em; font-variant-numeric: tabular-nums; }
.plan__price b { font-family: var(--f-display); font-weight: 500; font-size: clamp(2.2rem, 3.6vw, 3rem); letter-spacing: -.02em; }
.plan__price .unit { color: var(--muted); font-size: .9rem; font-weight: 500; }
.plan__note { color: var(--muted); font-size: .86rem; margin-top: 6px; }
.plan__feats { margin: 24px 0; display: grid; gap: 13px; }
.plan__feats li { display: flex; gap: 11px; align-items: flex-start; font-size: .94rem; color: var(--muted); }
.plan__feats svg { width: 17px; height: 17px; color: var(--accent); flex: none; margin-top: 3px; }
.plan__cta { margin-top: auto; }

.ptable { width: 100%; border-collapse: collapse; }
.ptable th, .ptable td { text-align: left; padding: 17px 8px; border-bottom: 1px solid var(--line); }
.ptable th { font-family: var(--f-label); font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--muted-2); font-weight: 500; }
.ptable td:last-child, .ptable th:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.ptable .price { font-family: var(--f-display); font-weight: 600; white-space: nowrap; }
.ptable tr:hover td { background: rgba(var(--accent-rgb),.04); }

/* ============================================================
   TRENÉŘI
   ============================================================ */
.trainers { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(18px, 2.4vw, 28px); }
/* Karty jsou stejně vysoké a štítky lícují na společné lince, i když má někdo
   dvouřádkové jméno nebo o dva štítky víc — `margin-top: auto` je odsune na
   spodek karty. Bez toho každá karta končila jinde a řada vypadala rozsypaně. */
.trainer { position: relative; display: flex; flex-direction: column; border-radius: var(--r-lg);
  overflow: hidden; background: var(--surface); box-shadow: inset 0 0 0 1px var(--line);
  transition: transform .45s var(--ease), box-shadow .45s var(--ease); }
/* Fotka je vsazená do karty jako do rámu, nesahá na hrany. Když se dotýkala
   okrajů, splynula s nimi a rámeček karty nebylo poznat — tenhle proužek podkladu
   kolem dokola je celý rozdíl. Odsazení je nahoře i po stranách stejné, dole
   navazuje text; radius fotky je o šířku proužku menší než radius karty, jinak
   se oblouky nekryjí a roh vypadá odseknutě.
   ⚠️ Odsazení je `margin` na fotce, ne `padding` na kartě: překryvný odkaz
   (`.trainer__link`) se opírá o `inset: 0` a to je padding box — s paddingem na
   kartě by proužek kolem fotky přestal být klikatelný a focus by vylezl ven.
   ⚠️ Fotka NEMÁ vlastní linku po obvodu. Tmavý hairline po ní na odbarvených
   portrétech vypadal jako černý okraj — snímky jsou v šedé a nízkém kontrastu,
   takže se linka čte jako součást fotky, ne jako rám. Rám dělá proužek podkladu. */
.trainer__photo { aspect-ratio: 3/4; position: relative; overflow: hidden;
  margin: 9px 9px 0; border-radius: calc(var(--r-lg) - 4px);
  background: linear-gradient(160deg, #2A2417, #17140D); }
/* 🔴 PORTRÉTY JSOU BAREVNÉ (27. 8. 2026, Jakub: „udělej je barevné, ty instruktory,
   ne ten šedej layout"). Dřív tu bylo `filter: grayscale(1) contrast(1.05)`
   a barva naskakovala až na hover.
   ⚠️ `position: relative; z-index: 1` NENÍ dekorace, drží fotku nad iniciálami.
   `.trainer__initials` je `position: absolute` (záložní monogram, když se fotka
   nenačte) a POZICOVANÝ prvek se maluje NAD nepozicovaným bez ohledu na pořadí
   v HTML. Dosud to nevadilo jen proto, že `filter` na obrázku dělá vlastní
   vrstvu a tím ho zvedl do stejné roviny. Jakmile filtr zmizel, propsaly se
   přes fotky bronzové „TČ / VČ / MV". Vidět to bylo až v renderu, v kódu ne. */
.trainer__photo img { width: 100%; height: 100%; object-fit: cover;
  position: relative; z-index: 1;
  transition: transform .8s var(--ease); }
.trainer:hover .trainer__photo img { transform: scale(1.04); }
.trainer__initials { position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--f-display); font-weight: 500; font-size: 3.6rem; color: rgba(199,165,106,.5); }
.trainer__body { padding: 20px 22px 22px; display: flex; flex-direction: column; flex: 1; }
.trainer__name { font-family: var(--f-display); font-weight: 600; font-size: 1.35rem; }
.trainer__role { color: var(--accent); font-family: var(--f-label); font-size: .72rem; letter-spacing: .1em;
  text-transform: uppercase; margin-top: 6px; }
.trainer__bio { color: var(--muted); font-size: .92rem; margin-top: 14px; }
/* Celá karta je odkaz na profil lektora — stejně jako karty lekcí.
   Překryv nad obsahem, jméno se při najetí zbarví bronzově. */
.trainer--link { cursor: pointer; }
/* Karta se při najetí nadzvedne a rámeček zbronzoví — stejná odpověď jako u karet
   lekcí a novinek, aby se web choval všude stejně. */
.trainer--link:hover, .trainer--link:focus-within { transform: translateY(-3px);
  box-shadow: inset 0 0 0 1px var(--accent-line), var(--sh-lg); }
.trainer > .trainer__link { position: absolute; inset: 0; z-index: 2; border-radius: inherit; }
.trainer > .trainer__link:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
.trainer--link:hover .trainer__name, .trainer--link:focus-within .trainer__name { color: var(--accent); }
.trainer__name { transition: color .25s var(--ease); }
.trainer__tags { margin-top: auto; padding-top: 16px; display: flex; flex-wrap: wrap; gap: 7px; }
@media (prefers-reduced-motion: reduce) { .trainer, .trainer__photo img { transition: none; }
  .trainer--link:hover, .trainer--link:focus-within { transform: none; } }

/* ============================================================
   RECENZE
   ============================================================ */
.quotes { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2vw, 24px); }
.quote { position: relative; background: var(--surface); border-radius: var(--r-lg); padding: 32px;
  box-shadow: inset 0 0 0 1px var(--line); display: flex; flex-direction: column; }
.quote > * { position: relative; z-index: 1; }
.quote__stars { color: var(--accent); letter-spacing: 3px; font-size: .85rem; }
.quote__txt { margin: 16px 0 20px; font-family: var(--f-display); font-weight: 400; font-size: 1.15rem; line-height: 1.5; flex: 1; }
.quote__who { display: flex; align-items: center; gap: 12px; }
.quote__av { width: 42px; height: 42px; border-radius: 50%; background: var(--accent-soft); color: var(--accent);
  display: grid; place-items: center; font-family: var(--f-display); font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--accent-line); }
/* ⚠️ Obojí bylo `inline` v jednom <span>u, takže se podpis slil do
   „Jaroslav Buršíkrodič". Jméno je proto blok a role si sedne pod něj. */
.quote__name { display: block; font-weight: 600; font-size: .92rem; line-height: 1.25; }
.quote__role { display: block; margin-top: 2px; color: var(--muted); font-size: .82rem; }

/* Recenze — plynulý auto-scroll marquee (posun doprava, nekonečná smyčka) */
.rmq { position: relative; overflow: hidden; margin-top: clamp(30px, 4vw, 48px);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); }
.rmq__track { display: flex; width: max-content; animation: rmq 60s linear infinite;
  animation-direction: reverse; will-change: transform; }
.rmq__card { flex: 0 0 auto; width: clamp(282px, 80vw, 384px); margin: 0 clamp(16px, 2vw, 24px) 0 0; }
@keyframes rmq { from { transform: translateX(0); } to { transform: translateX(-33.3333%); } }
@media (prefers-reduced-motion: reduce) {
  .rmq { overflow-x: auto; -webkit-overflow-scrolling: touch; scroll-snap-type: x mandatory;
    -webkit-mask-image: none; mask-image: none; padding-inline: var(--gutter); }
  .rmq__track { animation: none; }
  .rmq__card { scroll-snap-align: start; }
  .rmq__card[aria-hidden="true"] { display: none; }  /* bez animace stačí každá recenze jednou */
}

/* ============================================================
   FAQ
   ============================================================ */
.faq { max-width: 800px; }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__q { width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 16px;
  text-align: left; padding: 24px 4px; font-family: var(--f-display); font-weight: 500; font-size: clamp(1.1rem, 1.8vw, 1.35rem); }
.faq__q .ic { width: 28px; height: 28px; flex: none; border-radius: 50%; display: grid; place-items: center;
  box-shadow: inset 0 0 0 1px var(--line-2); position: relative; transition: background .3s, box-shadow .3s; }
.faq__q .ic::before, .faq__q .ic::after { content: ""; position: absolute; background: var(--text); border-radius: 2px; transition: transform .4s var(--ease), background .3s; }
.faq__q .ic::before { width: 11px; height: 1.5px; }
.faq__q .ic::after { width: 1.5px; height: 11px; }
.faq__item.open .faq__q .ic { background: var(--accent); box-shadow: none; }
.faq__item.open .faq__q .ic::before, .faq__item.open .faq__q .ic::after { background: var(--accent-ink); }
.faq__item.open .faq__q .ic::after { transform: scaleY(0); }
.faq__a { max-height: 0; overflow: hidden; transition: max-height .45s var(--ease); }
.faq__a p { padding: 0 4px 26px; color: var(--muted); }

/* ---------- DOTYKOVÉ CÍLE (13. 8. 2026) ----------
   Mobilní audit našel ovladače pod 40 px: filtry rozvrhu měly 31 px, „Rozumím"
   na cookie liště 39, odkazy se šipkou 30 a „Otevřít v Mapách" 35. Plochu
   roztahuje pseudo-prvek, ne vyšší tlačítko — jinak by se rozjelo rozložení
   (pilulky filtrů stojí v řadě, šipkový odkaz sedí uvnitř textu).
   ⚠️ JEN NA VÝŠKU: se zápornými left/right začne prvek hlásit
   scrollWidth > clientWidth, tedy přesně to, co si v auditu hlídáme. */
@media (max-width: 860px) {
  .fsel__btn, .btn--sm, .arrow-link, .mapwrap__open, .hero-fb__rating, .akt__all,
  .sched__arrow, .booking__ics, .booking__cancel, .info__v a { position: relative; }
  /* Oko u hesla sedí uvnitř pole (52 px), takže se smí zvětšit rovnou.
     ⚠️ `.pwd .pwd__toggle` schválně — základní pravidlo je v souboru AŽ ZA
     tímhle blokem a se stejnou specifičností by ho přebilo zpátky na 38 px. */
  .pwd .pwd__toggle { width: 44px; height: 44px; }
  .fsel__btn::after, .btn--sm::after, .arrow-link::after, .mapwrap__open::after,
  .hero-fb__rating::after, .akt__all::after, .booking__ics::after, .booking__cancel::after,
  .sched__arrow::after, .info__v a::after {
    content: ""; position: absolute; left: 0; right: 0; top: 50%;
    height: 44px; transform: translateY(-50%);
  }
  /* ⚠️ `.expand > summary` má `::after` OBSAZENÝ — kreslí se jím šipka
     rozbalování. Dotyková plocha proto jede na `::before`. Absolutní pozice
     je nutná i proto, že summary je `inline-flex` s `gap: 7px`: prvek v toku
     by se stal položkou mřížky a odsunul text. `position: relative` už
     summary má ze svého základního pravidla níž v souboru. */
  .expand > summary::before {
    content: ""; position: absolute; left: 0; right: 0; top: 50%;
    height: 44px; transform: translateY(-50%);
  }
}

/* ============================================================
   DATUMOVÉ POLE S KALENDÁŘEM (16. 8. 2026)
   Nativní `<input type="date">` si vzhled i pořadí polí řídí operační
   systém — Jakubovi vykreslil americké „08/14/2026" a k roku narození se
   šlo doklikat jen rok po roce. Vlastní pole je v `assets/datum.js`.
   ⚠️ Barvy jdou přes tokeny, takže v adminu (espresso) se přebarví samy.
   Admin načítá tenhle soubor, proto tu ten styl je a ne v admin.css.
   ============================================================ */
.dpick { position: relative; display: block; }
.dpick > input { padding-right: 46px; }        /* místo pro ikonu, ať ji text nepodleze */
.dpick__btn {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; display: grid; place-items: center;
  background: none; border: 0; border-radius: 10px; cursor: pointer;
  color: var(--muted); padding: 0;
}
.dpick__btn svg { width: 20px; height: 20px; }
.dpick__btn:hover { color: var(--accent); }
.dpick__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Visí na <body> a pozicuje se skriptem — viz komentář v datum.js.
   z-index pod lištou cookies (250) i modalem (200) být nesmí, protože se
   kalendář otevírá i v modalech administrace. */
.dpick__pop {
  position: fixed; z-index: 300;
  background: var(--surface); border-radius: var(--r-md);
  box-shadow: inset 0 0 0 1px var(--line), var(--sh-lg);
  padding: 12px; font-family: var(--f-body);
}
.dpick__pop { overflow-y: auto; overscroll-behavior: contain; }
.dpick__pop[hidden] { display: none; }

.dpick__head {
  display: grid; grid-template-columns: auto 1fr auto auto auto auto; align-items: center;
  gap: 2px; margin-bottom: 10px;
}
.dpick__lbl { text-align: center; font-size: .86rem; font-weight: 600; color: var(--text); padding: 0 4px; }
.dpick__lbl:last-of-type { min-width: 46px; }
.dpick__sip {
  width: 30px; height: 30px; border: 0; background: none; cursor: pointer;
  color: var(--muted); border-radius: 8px; font-size: 1rem; line-height: 1; padding: 0;
}
.dpick__sip:hover { background: var(--surface-2); color: var(--accent); }
.dpick__sip:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.dpick__dny, .dpick__mrizka { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.dpick__dny { margin-bottom: 4px; }
.dpick__dny span {
  text-align: center; font-size: .66rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted-2);
}
.dpick__den {
  aspect-ratio: 1; border: 0; background: none; cursor: pointer; border-radius: 8px;
  font: inherit; font-size: .84rem; color: var(--text); padding: 0;
}
.dpick__den:hover:not([disabled]) { background: var(--surface-2); }
.dpick__den[disabled] { color: var(--muted-2); opacity: .35; cursor: default; }
/* Dnešek jen obtažený, vybraný plný — ať se ty dva stavy nepletou. */
.dpick__den.je-dnes { box-shadow: inset 0 0 0 1px var(--accent-line); }
.dpick__den.je-vybrano { background: var(--accent); color: var(--accent-ink); font-weight: 600; }
.dpick__den:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.dpick__dnes {
  width: 100%; margin-top: 10px; padding: 8px; border: 0; cursor: pointer;
  background: var(--surface-2); border-radius: 8px; font: inherit; font-size: .8rem;
  color: var(--accent); font-weight: 600;
}
.dpick__dnes:hover { background: var(--surface-3); }

/* Na telefonu se čtyři 30px šipky vedle sebe prstem míjejí, ale ve 44 px se
   do jednoho řádku nevejdou. Hlavička se proto zalomí na dva řádky: měsíc
   nahoře, rok pod ním. Šest dětí napadá do tří sloupců samo, DOM se nemění.
   Kalendář je za přihlášením a vzniká až za běhu, takže ho mobilní průchod
   po sitemapě nikdy neviděl — hlídá ho `npm run mobil:admin`. */
@media (max-width: 620px) {
  .dpick__head { grid-template-columns: 44px 1fr 44px; gap: 4px; }
  .dpick__sip { width: 44px; height: 44px; font-size: 1.15rem; }
  .dpick__btn { width: 44px; height: 44px; }
  .dpick > input { padding-right: 52px; }
  .dpick__dnes { padding: 12px; font-size: .85rem; }
}

/* ============================================================
   FORMULÁŘE
   ============================================================ */
.field { margin-bottom: 20px; }
/* Popisek mluví řečí značky, ne UI kitu: verzálky s prostrkáním jako `.fsel__l`
   nebo `.tag`. Tučný tmavý popisek se pral s nadpisem karty. */
.field label { display: block; font-family: var(--f-label); font-weight: 600; font-size: .68rem;
  letter-spacing: .13em; text-transform: uppercase; color: var(--muted-2); margin-bottom: 9px; }
.field .req { color: var(--accent); }
/* ⚠️ `border: 0` MUSÍ zůstat. Reset výš dědí jen písmo a barvu, takže prohlížeč
   kreslil vlastní nativní rámeček — tmavý, v každém prohlížeči jinak silný — a
   jemná inset linka z designu ležela pod ním. Odtud ten „ohraničený" vzhled. */
/* ⚠️ VÝPLŇ MUSÍ BÝT JINÁ NEŽ KARTA (28. 8. 2026). Pole měla `var(--surface)`,
   což je #FBF8F1 — PŘESNĚ barva `.card`. Kontrast pole vůči kartě byl tedy 1,00
   a držel je jen rámeček (1,39:1). Systém přitom má na inputy vlastní token
   `--surface-3` (komentář u něj to říká doslova) a nikdo ho nepoužíval.
   Naměřeno po opravě: výplň vůči kartě 1,21:1 a rámeček vůči kartě 1,68:1.
   ⚠️ `background-color`, NE zkratka — zkratka by u `<select>`u smazala vlastní
   šipku (ověřeno samotestem: se zkratkou opravdu zmizí). */
.field input, .field textarea, .field select {
  width: 100%; min-height: 54px; background-color: var(--surface-3);
  border: 1px solid var(--line-2); border-radius: var(--r); padding: 15px 18px;
  box-shadow: none; transition: border-color .25s var(--ease), box-shadow .25s var(--ease), background-color .25s;
}
.field input:hover, .field textarea:hover, .field select:hover { border-color: var(--accent-line); }
.field input::placeholder, .field textarea::placeholder { color: var(--muted-2); }
/* Safari na <select> IGNORUJE padding, dokud se nevypne nativní vzhled — pole pak
   mělo na telefonu 25 px místo 58 a vedle ostatních vypadalo jako omylem. Šipku si
   proto kreslíme sami (data: URI, CSP img-src ji povoluje). `appearance: none`
   vypíná jen vzhled, rozbalování zůstává nativní — na mobilu je to správně, iOS
   ukáže svůj válec, který se ovládá palcem líp než cokoli vlastního. */
.field select {
  -webkit-appearance: none; appearance: none;
  padding-right: 44px; line-height: 1.4; color: var(--text);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%236B6256' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 16px center;
}
/* Zaostřené pole nemění výplň ani rozměr — jen se kolem něj rozsvítí prstenec.
   Přebarvování pozadí působilo, jako by pole poskočilo. */
.field input:focus, .field textarea:focus, .field select:focus { outline: none;
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
/* `background-color`, ne zkratka — u <select>u by zkratka smazala vlastní šipku. */
.field input.err, .field textarea.err, .field select.err { border-color: var(--error); background-color: var(--error-soft); }
.field input.err:focus, .field textarea.err:focus, .field select.err:focus { box-shadow: 0 0 0 3px rgba(176,71,59,.14); }
/* Zpráva byla 128 px a na kartě z ní byl velký prázdný blok. */
.field textarea { resize: vertical; min-height: 112px; line-height: 1.6; }
/* Nápověda i chyba lícují s levou hranou pole a mají stejný odstup. */
.field__err { color: var(--error); font-size: .82rem; line-height: 1.45; margin-top: 7px; }
.field__hint { color: var(--muted-2); font-size: .82rem; line-height: 1.45; margin-top: 7px; }
/* Pod 620 px se řádek skládá pod sebe (níž v souboru) — svislou mezeru tam
   dělá `.field` sám, gap by ji zdvojil. */
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; align-items: start; }
/* Vlasovka odděluje prodejní větu od formuláře. Jen na kontaktu — je to jediná
   karta, kde nad formulářem stojí dva odstavce textu, a `.card` tam má jediný form. */
body[data-page="kontakt"] .card form { border-top: 1px solid var(--line); padding-top: 26px; }

.pwd { position: relative; }
.pwd input { padding-right: 48px; }
.pwd__toggle { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 38px; height: 38px;
  border-radius: 8px; display: grid; place-items: center; color: var(--muted); }
.pwd__toggle:hover { color: var(--text); }
.pwd__toggle svg { width: 20px; height: 20px; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.auth { min-height: calc(100vh - var(--nav-h)); display: grid; place-items: center; padding: calc(var(--nav-h) + 30px) var(--gutter) 60px; }
.auth__card { width: 100%; max-width: 440px; background: var(--surface); border-radius: var(--r-xl);
  box-shadow: inset 0 0 0 1px var(--line), var(--sh-lg); padding: clamp(30px, 4vw, 46px); position: relative; overflow: hidden; }
.auth__card > * { position: relative; z-index: 1; }
.auth__title { font-size: clamp(1.7rem, 3vw, 2.2rem); }
.auth__sub { color: var(--muted); margin-top: 10px; margin-bottom: 28px; }
.auth__alt { margin-top: 24px; text-align: center; color: var(--muted); font-size: .92rem; }

/* ============================================================
   REGISTRACE NA ŠÍŘKU (.auth__card--split)
   ============================================================
   Na počítači měla registrace všechno v jednom sloupci 440 px a člověk kvůli
   ní zbytečně roloval. Na širokém displeji jde text vlevo a formulář vpravo,
   pole se párují do řádků. Na telefonu zůstává všechno pod sebou.
   ⚠️ `.auth` má `place-items: center`, takže karta se šířkou pořád centruje.
   ⚠️ Pole s nápovědou jsou spárovaná spolu (telefon + heslo), aby řádek nebyl
   jednou nohou dole. `.field-row` má `align-items: start`, takže nestejně
   dlouhé nápovědy řádek nerozhodí. */
/* ⚠️ Zlom je 960 px, ne 900. Na 900 px zbývalo v poli hesla jen 3 px rezervy
   na placeholder a stačilo by jiné vykreslení písma, aby se usekl. */
@media (min-width: 960px) {
  /* ⚠️ Karta byla 940 px a do pole se vešlo 146 px textu. Běžný e-mail
     „jana.novakova@seznam.cz" má 205 px, takže se nevešel ani ten obyčejný
     a člověk si při psaní neviděl na začátek. Karta je proto širší a formulář
     má z ní větší díl než text vlevo. */
  .auth__card--split { max-width: 1140px; display: grid;
    grid-template-columns: minmax(0, .8fr) minmax(0, 1.15fr);
    column-gap: clamp(36px, 4vw, 60px); align-items: stretch; }
  /* ⚠️ `align-items: stretch`, ne `start`. Levý sloupec byl vysoký 306 px proti
     559 px formuláře, takže pod ním zůstávalo 252 px prázdna. Teď se natáhne
     na výšku karty a obsah se v něm rozprostře. */
  .auth__card--split .auth__uvod { display: flex; flex-direction: column; }
  /* Hvězdičky a věta o gymu se odsadí dolů a vyplní to místo něčím, co dává
     smysl. Hodnocení je skutečné z Google profilu, nevymýšlí se. */
  .auth__uvod .auth__proof { margin-top: auto; padding-top: 26px;
    border-top: 1px solid var(--line); display: flex; align-items: center; gap: 10px;
    color: var(--muted); font-size: .92rem; }
  .auth__uvod .auth__proof .st { color: var(--accent); letter-spacing: 2px; }
  .auth__uvod .auth__proof strong { color: var(--text); }
  .auth__uvod .auth__proof-sub { margin: 10px 0 0; color: var(--muted-2); font-size: .86rem; line-height: 1.6; }
  /* Telefon dostane širší půlku, číslo v něm sedělo natěsno. */
  .auth__vypln .field-row { grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr); }
  /* ⚠️ Do páru jdou JEN krátká pole. Dlouhé jméno potřebuje 253 px a e-mail
     289 px, což se do půlky řádku nevejde při žádné rozumné šířce karty.
     Jméno a e-mail proto berou celou šířku formuláře, spárovaný zůstal jen
     telefon (138 px) s heslem (97 px). Formulář je tím o řádek vyšší, pořád
     ale o dost nižší než původních 555 px. */
  /* Dělicí vlasovka mezi sloupci, stejný vzor jako u hlaviček sekcí. */
  .auth__card--split .auth__vypln { padding-left: clamp(36px, 4vw, 60px);
    border-left: 1px solid var(--line); }
  .auth__card--split .auth__sub { margin-bottom: 20px; }
  .auth__card--split .auth__legal { margin-top: 18px; }
  .auth__card--split .auth__alt { text-align: left; }
}
/* Pod 900 px se dvojice polí rozpadnou zpátky pod sebe. */
@media (max-width: 959px) {
  .auth__card--split .field-row { grid-template-columns: 1fr; }
}
.auth__alt a { color: var(--accent); font-weight: 600; }
.auth__legal { margin-top: 18px; font-size: .78rem; color: var(--muted-2); text-align: center; line-height: 1.5; }
.auth__legal a { color: var(--muted); text-decoration: underline; }

.formmsg { padding: 13px 16px; border-radius: var(--r); font-size: .9rem; margin-bottom: 18px; display: none; }
.formmsg.show { display: block; }
/* ⚠️ Barva textu jde přes token, ne natvrdo: #8a3327 dával na espressu 2,70:1,
   takže „Odkaz pro obnovu hesla je neplatný" nebyl na tmavé stránce k přečtení.
   Na ivory je --error #B0473B (4,8:1), v appce #D67C6E (5,9:1). */
.formmsg--err { background: var(--error-soft); color: var(--error); box-shadow: inset 0 0 0 1px rgba(176,71,59,.3); }
.formmsg--ok { background: var(--accent-soft); color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent-line); }

/* ============================================================
   ČLENSKÁ SEKCE
   ============================================================ */
.dash { padding-top: calc(var(--nav-h) + clamp(34px, 5vw, 60px)); padding-bottom: clamp(64px, 8vw, 104px); }
.dash__head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: end; gap: 18px; margin-bottom: 40px; }
.dash__grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: clamp(18px, 2.4vw, 28px); align-items: start; }
/* Položka mřížky má ve výchozím stavu `min-width: auto`, takže se nesmrskne pod
   šířku svého nejširšího obsahu — na 390 px kvůli tomu panel držel 380 px v
   350px sloupci a celá členská sekce rolovala do strany. */
.dash__grid > * { min-width: 0; }
/* Panely jsou přímo v mřížce, ne ve dvou sloupcových obalech — pořadí v HTML je
   tím pádem to, co člověk vidí na telefonu (lekce → permanentka → historie →
   účet), a na počítači si permanentka vezme celý pravý sloupec a srovná výšku
   obou stran. Dřív byl levý sloupec o třetinu kratší než pravý. */
@media (min-width: 921px) {
  /* Řádky: lekce si nechají svou výšku, HISTORIE dorovná zbytek. Permanentka
     v pravém sloupci je skoro vždycky vyšší než ty dva panely dohromady a bez
     tohohle se přebytek rozlil do mezery mezi nimi — mezera pak byla 70 px
     místo 28 a sloupce končily každý jinde. */
  .dash__grid { grid-template-rows: auto 1fr auto; }
  .dash__panel--pass { grid-column: 2; grid-row: 1 / span 2; }
  .dash__panel--hist { align-self: stretch; }
  .dash__panel--acc { grid-column: 1 / -1; }
}
.dash__panel { background: var(--surface); border-radius: var(--r-lg); box-shadow: inset 0 0 0 1px var(--line);
  padding: clamp(24px, 2.6vw, 32px); position: relative; overflow: hidden; }
.dash__panel > * { position: relative; z-index: 1; }
.dash__panel h2 { font-size: 1.2rem; margin-bottom: 20px; display: flex; align-items: center; gap: 10px; }
.dash__settings { display: grid; grid-template-columns: repeat(auto-fit, minmax(248px, 1fr)); gap: clamp(22px, 3vw, 40px); align-items: start; }
.dash__sub { font-family: var(--f-body); font-weight: 600; font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 14px; }
.dash__settings .field:last-of-type { margin-bottom: 18px; }
.pass { border-radius: var(--r); box-shadow: inset 0 0 0 1px var(--line-2); padding: 20px; margin-bottom: 14px; background: var(--surface-2); }
.pass--accent { background: linear-gradient(135deg, rgba(var(--accent-rgb),.12), rgba(var(--accent-rgb),.03)); box-shadow: inset 0 0 0 1px var(--accent-line); }
.pass__name { font-family: var(--f-display); font-weight: 600; }
.pass__big { font-family: var(--f-display); font-weight: 500; font-size: 2rem; line-height: 1; margin: 8px 0; }
/* Permanentka bez evidence vstupů — místo velkého čísla jen stav a datum.
   Drží stejnou výšku bloku jako .pass__big, ať karty vedle sebe neposkakují. */
.pass__since { font-family: var(--f-display); font-weight: 500; font-size: 1.15rem; line-height: 1.7; margin: 8px 0; }
.pass__meta { color: var(--muted); font-size: .84rem; }
.pass__bar { margin-top: 14px; height: 5px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.pass__bar i { display: block; height: 100%; background: var(--accent); border-radius: 99px; }
/* Koupě permanentky převodem — vizuálně oddělené od karet už koupených permanentek,
   ať si klient nesplete nabídku s tím, co má. */
.buypass { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--line); }
.buypass h3 { margin-bottom: 4px; }

/* Rozbalovací vysvětlení. Text, který je zajímavý jen napoprvé, nemá zabírat
   místo pořád — kdo ho chce, klikne na šipku. Značka `<details>` funguje i bez
   skriptu a čtečka stav sama oznámí; kreslí se jen vlastní šipka místo
   nativního trojúhelníku, který vypadá v každém prohlížeči jinak. */
.expand { margin-top: 4px; }
.expand > summary {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  list-style: none; font-size: .84rem; font-weight: 600; color: var(--muted);
  padding: 6px 0; position: relative;
}
.expand > summary::-webkit-details-marker { display: none; }
.expand > summary::after {
  content: ""; width: 8px; height: 8px; flex: none;
  border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .3s var(--ease);
}
.expand[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.expand > summary:hover { color: var(--accent); }
.expand > p { margin-top: 2px; }
/* Varianta, ve které je uvnitř víc než odstavec (kroky rezervace v rozvrhu). */
.expand--wide { margin: 0 0 26px; }
.expand--wide > summary { margin-bottom: 4px; }
.buypass__row { display: flex; flex-wrap: wrap; gap: 10px; margin: 12px 0 10px; }
.buypass__row .fsel { flex: 1 1 160px; min-width: 0; padding: 8px 12px; }
.buypass__row .fsel__l { display: none; }   /* popisek nese samotná volba, štítek by řádek zbytečně tříštil */
.buypass__row .fsel__btn { width: 100%; justify-content: space-between; }
.buypass__row .fsel__val { max-width: none; }


/* Výběr termínu v tabulce volných míst → přihláška. Klikací je CELÝ ŘÁDEK.
   ⚠️ NE přes odkaz roztažený na `inset: 0` — ten stojí na `position: relative`
   u `<tr>`, což některé prohlížeče ignorují: odkazy se pak všechny odvodí od
   společného předka, leží přes sebe a „vybraný" je pořád ten poslední.
   Řádek proto kliká přes JS (app.js) a odkaz v poslední buňce zůstává normální
   šipkou — funguje bez JS, jde otevřít v novém panelu a čtečka ho přečte. */
.uk { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0; }
.avail tbody tr.is-pick { cursor: pointer; }
.avail__goc { width: 1%; text-align: right; }
.avail__go { display: inline-block; padding: 4px 6px; color: var(--muted-2); font-weight: 700;
  transition: transform .25s var(--ease), color .25s; }
.avail tbody tr.is-pick:hover .avail__go,
.avail tbody tr:focus-within .avail__go,
.avail__go:hover { color: var(--accent); transform: translateX(4px); }
.avail__go:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-sm); }
/* Obsazený termín odkaz nemá — zůstane jen text, ať je vidět, proč nejde kliknout. */
.avail__off { font-size: .85rem; color: var(--muted-2); white-space: nowrap; }

/* Vybraný termín nad formulářem přihlášky — ať člověk vidí, k čemu údaje vyplňuje. */
.pr-term { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; padding: 16px 20px; }
.pr-term__k { font-family: var(--f-label); font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; color: var(--muted-2); }
.pr-term__v { font-size: 1.05rem; }
.pr-term__volno { font-size: .85rem; color: var(--accent); font-weight: 600; }
/* Dotykový cíl roztahuje pseudo-prvek, ne padding — „Změnit" sedí na účaří
   vedle termínu (.pr-term je flex s align-items: baseline) a skutečné zvětšení
   tlačítka by ten řádek rozhodilo. Stejný vzor jako křížek v modalu (6e0fd26).
   Bez toho měl na telefonu 46×22 px. */
.pr-term__zmena { position: relative; margin-left: auto; font-size: .85rem; font-weight: 600; color: var(--accent); }
.pr-term__zmena::after { content: ""; position: absolute; left: 0; right: 0; top: 50%;
  transform: translateY(-50%); height: 44px; }

/* Platební stránka. Na telefonu sloupec (tam je to správně), na počítači QR
   VEDLE údajů — nastojato se karta táhla přes celou výšku obrazovky a všechno
   v ní bylo natlačené na sebe. */
.pay-wrap { max-width: 920px; }
.pay { text-align: center; padding: clamp(24px, 4vw, 44px); }
.pay__title { margin: 10px 0 2px; }
.pay__demo { color: var(--warn); font-size: .9rem; }
.pay__grid { display: grid; gap: clamp(18px, 3vw, 40px); margin-top: 22px; }
.pay__qr { display: flex; justify-content: center; align-items: flex-start; }
.pay__qr canvas { width: min(240px, 100%); height: auto; background: #fff; border-radius: 12px; padding: 8px; }
.pay__info { text-align: left; }
.pay__info .hours { margin-top: 12px; }
.pay__hint { margin-top: 12px; color: var(--muted-2); }
.pay__foot { margin-top: 18px; color: var(--muted); }
@media (min-width: 760px) {
  .pay { padding: clamp(32px, 3.5vw, 52px); }
  /* `auto 1fr`, ne `1fr 1fr`: QR má pevnou velikost, druhý sloupec si bere zbytek. */
  .pay__grid { grid-template-columns: auto 1fr; align-items: center; text-align: left; }
  .pay__qr canvas { width: 260px; }
  .pay__lead { margin-top: 0; }
}
/* Na telefonu zůstává všechno na střed jako dřív — vlevo zarovnaný text patří
   až k rozdělení na dva sloupce. Tabulka údajů je zarovnaná vždycky. */
@media (max-width: 759px) {
  .pay__info { text-align: center; }
  .pay__info .hours { max-width: 360px; margin-inline: auto; text-align: left; }
}

/* Tytéž pilulky v modalu ceníku musí být pod sebou — vedle sebe zbylo na každou
   ~180 px a „10 vstupů — 1 900 Kč" se ořízlo na „1 9…", takže cena nebyla vidět. */
/* ⚠️ `flex: 1 1 160px` z řádkové varianty míří v sloupci na VÝŠKU — pilulky
   vyrostly na 130 px. Proto se tu základ ruší, ne jen otáčí směr. */
.modal .buypass__row { flex-direction: column; gap: 8px; }
.modal .buypass__row .fsel { flex: 0 0 auto; }

/* Výběr lekce v ceníku („Na jakou lekci chceš jít?"). Roluje seznam, ne modal —
   dva týdny provozu je přes třicet termínů a modal by přerostl obrazovku. */
.pick { max-height: min(46vh, 340px); overflow-y: auto; overscroll-behavior: contain;
  margin-bottom: 16px; border: 1px solid var(--line-2); border-radius: var(--r); }
.pick__i { display: grid; grid-template-columns: 1fr auto; gap: 2px 12px; width: 100%; text-align: left;
  padding: 10px 12px; background: none; border: 0; border-bottom: 1px solid var(--line); cursor: pointer;
  font: inherit; color: var(--text); transition: background .2s; }
.pick__i:last-child { border-bottom: 0; }
.pick__i:hover { background: var(--accent-soft); }
.pick__i.is-on { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.pick__i:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Sloupce se přiřazují ručně — samospádem si cena vzala první buňku a text
   lekce skončil vpravo od ní, řádek od řádku jinak. */
.pick__when { grid-column: 1; grid-row: 1; font-family: var(--f-label); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); }
.pick__what { grid-column: 1; grid-row: 2; font-size: .92rem; color: var(--muted); }
.pick__price { grid-column: 2; grid-row: 1 / span 2; align-self: center; text-align: right;
  font-weight: 700; font-variant-numeric: tabular-nums; }

/* Rezervace jsou řádky, ne karty jako sloty v rozvrhu — stejné rozlišení proto
   nese svislý proužek vlevo, ne rámeček dokola. Barvy sdílené s rozvrhem. */
.booking { position: relative; display: flex; align-items: center; gap: 14px; padding: 16px 0 16px 13px; border-bottom: 1px solid var(--line); }
.booking:last-child { border-bottom: none; }
.booking::before {
  content: ""; position: absolute; left: 0; top: 14px; bottom: 14px; width: 3px;
  border-radius: 3px; background: var(--booking-ring, var(--ring-ok));
}
/* proběhlé (Historie) — červený, stejně jako v rozvrhu */
.booking.is-past { --booking-ring: var(--ring-past); }
/* čekačka — místo ještě není jisté, tak ani zelená, ani červená */
.booking.is-wait { --booking-ring: var(--warn); }
.booking__date { text-align: center; flex: none; width: 54px; }
.booking__day { font-family: var(--f-display); font-weight: 500; font-size: 1.6rem; line-height: 1; }
.booking__mon { font-family: var(--f-label); font-size: .68rem; text-transform: uppercase; color: var(--muted); }
.booking__info { flex: 1; min-width: 0; }
.booking__name { font-family: var(--f-display); font-weight: 600; }
.booking__meta { color: var(--muted); font-size: .84rem; }
.booking__cancel { color: var(--muted); font-size: .82rem; font-weight: 500; padding: 7px 13px; border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--line-2); transition: color .3s, box-shadow .3s; }
.booking__cancel:hover { color: var(--error); box-shadow: inset 0 0 0 1px var(--error); }
/* Na telefonu zbyde vedle data a tlačítka na jméno lektorky ~60 px a „Černohousová"
   se nemá kde zalomit — text pak z řádku leze ven. Tlačítko proto ustoupí na
   vlastní řádek a zaroví se pod text (54 px datum + 14 px mezera). */
@media (max-width: 620px) {
  .booking { flex-wrap: wrap; }
  .booking__info { flex: 1 1 140px; }
  .booking__cancel { margin-left: 68px; }
}

.empty { text-align: center; padding: 32px 10px; color: var(--muted); }

/* ============================================================
   TOAST
   ============================================================ */
.toast-wrap { position: fixed; left: 50%; bottom: max(26px, env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 9999;
  display: flex; flex-direction: column; gap: 10px; width: min(420px, calc(100vw - 32px)); }
.toast { background: var(--surface); border-radius: var(--r); padding: 14px 16px; box-shadow: var(--sh-lg), inset 0 0 0 1px var(--line-2);
  display: flex; gap: 12px; align-items: center; font-size: .92rem; transform: translateY(14px); opacity: 0;
  transition: transform .4s var(--ease), opacity .4s; }
.toast.show { transform: none; opacity: 1; }
.toast__ic { width: 26px; height: 26px; flex: none; border-radius: 50%; display: grid; place-items: center; }
.toast--ok .toast__ic { background: var(--accent); color: var(--accent-ink); }
.toast--err .toast__ic { background: var(--error); color: #fff; }
.toast__ic svg { width: 16px; height: 16px; }

/* ============================================================
   CALLOUT / CTA
   ============================================================ */
/* ⚠️ Bronzová záře se kreslila UVNITŘ oříznutého boxu (`overflow: hidden` +
   `inset: 0`), takže na jeho hraně končila řezem — ve světlé ploše byl vidět
   obdélník s viditelnými rohy. Teď přesahuje ven a dohasíná dřív, než by na
   nějakou hranu narazila. Ořez zůstává jen variantě s fotkou, kde ho potřebuje
   samotný obrázek. */
.callout { position: relative; border-radius: var(--r-xl); padding: clamp(40px, 6vw, 80px);
  text-align: center; }
.callout > * { position: relative; z-index: 1; }
/* ⚠️ ZÁŘE MUSÍ DOHASNOUT UVNITŘ SVÉHO BOXU, jinak se řez jen posune.
   Napoprvé jsem box zvětšil a myslel si, že je hotovo — jenže gradient byl na
   jeho horní hraně pořád na ~60 % síly, takže hrana zůstala, jen o 60 px výš
   (a v místě, kde nad blokem začíná jinak podbarvená sekce, byla ještě líp
   vidět). Spočítat se to dá: průhledná je až na 70 % poloměru, tedy
   0,70 × 58 % = 40,6 % od středu. Se středem v 42 % výšky sahá záře od 1,4 %
   do 82,6 % a do stran od 9,4 % do 90,6 % — na žádnou hranu boxu nedosáhne.
   ⚠️ Do stran box nepřesahuje schválně: absolutní prvek nehýbe rozložením, ale
   počítá se do rolovací plochy a na 390 px kvůli tomu stránka rolovala. */
.callout::before { content: ""; position: absolute; inset: -18% 0; z-index: 0; pointer-events: none;
  background: radial-gradient(58% 58% at 50% 42%, rgba(var(--accent-rgb),.14), transparent 70%); }
.callout__cta { margin-top: 30px; display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; }
/* ⚠️ `.hero__cta` je ve 13 HTML souborech a v CSS k němu NEBYLO jediné pravidlo.
   Na šesti stránkách lekcí jsou v něm dvě tlačítka a bez `gap` se dotýkala:
   naměřená mezera 0 px na 1440 px, na 390 px se zalomila taky bez mezery. */
.hero__cta { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

/* ============================================================
   VÝRAZNÁ VÝZVA BEZ FOTKY (.callout--vyrazna)
   ============================================================
   Fotka na pozadí šla pryč na Jakubovo přání. Aby blok neztratil sílu, nese ji
   teď kresba: espresso plocha, bronzová záře ze středu, čtyři rohové značky,
   vsazený rám a filmové zrno. Všechno je CSS, žádný soubor navíc, takže to
   nezestárne s výměnou fotek a nestojí to ani bajt přenosu.
   ⚠️ `::before` na `.callout` kreslí záři, proto rám a rohy jedou přes
   `::after` a přes vnitřní vrstvu. */
.callout--vyrazna { background:
    radial-gradient(120% 90% at 50% 0%, rgba(194,168,120,.16), transparent 62%),
    linear-gradient(165deg, #2A2417 0%, #1B1A16 45%, #12100B 100%) !important;
  box-shadow: inset 0 0 0 1px rgba(194,168,120,.26) !important;
  overflow: hidden; }
/* zrno, ať plocha nepůsobí jako plochý obdélník */
.callout--vyrazna::before { content: ""; position: absolute; inset: 0; z-index: 0;
  pointer-events: none; opacity: .07; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
/* vsazený rám + čtyři rohové značky */
.callout--vyrazna::after { content: ""; position: absolute; z-index: 1; pointer-events: none;
  inset: clamp(10px, 1.4vw, 18px); border-radius: calc(var(--r-xl) - 10px);
  box-shadow: inset 0 0 0 1px rgba(194,168,120,.22);
  background:
    linear-gradient(var(--accent-2), var(--accent-2)) left top / 34px 2px no-repeat,
    linear-gradient(var(--accent-2), var(--accent-2)) left top / 2px 34px no-repeat,
    linear-gradient(var(--accent-2), var(--accent-2)) right top / 34px 2px no-repeat,
    linear-gradient(var(--accent-2), var(--accent-2)) right top / 2px 34px no-repeat,
    linear-gradient(var(--accent-2), var(--accent-2)) left bottom / 34px 2px no-repeat,
    linear-gradient(var(--accent-2), var(--accent-2)) left bottom / 2px 34px no-repeat,
    linear-gradient(var(--accent-2), var(--accent-2)) right bottom / 34px 2px no-repeat,
    linear-gradient(var(--accent-2), var(--accent-2)) right bottom / 2px 34px no-repeat; }
@media (max-width: 560px) {
  .callout--vyrazna::after { background-size: 22px 2px, 2px 22px, 22px 2px, 2px 22px,
    22px 2px, 2px 22px, 22px 2px, 2px 22px; }
}

/* ⚠️ `display: flex` na třídě PŘEBÍJÍ atribut `hidden` (výchozí pravidlo
   prohlížeče `[hidden]{display:none}` má nižší specifičnost než třída).
   Bez řádku níž zůstala záložní výzva na úvodní stránce viditelná i poté,
   co ji `script.js` skryl, takže se pod živým pruhem „Nejbližší lekce"
   vykreslila druhá výzva na rozvrh. Doloženo 29. 8. 2026 měřením i snímkem.
   Týž vzor už má `.dnes[hidden]` o kus níž. */
.callout-mini[hidden] { display: none; }
.callout-mini { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px;
  background: var(--surface); border-radius: var(--r-lg); padding: clamp(26px, 3vw, 38px); box-shadow: inset 0 0 0 1px var(--line); }

.info-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
/* Lichý počet karet nechal poslední („Provozovatel") viset vlevo a vedle ní díru.
   Roztáhne se proto přes obě kolony — a protože má ze všech nejdelší text
   (IČO, sídlo, neplátce DPH), přestane se zároveň lámat na dva řádky.
   Selektor drží i při sudém počtu karet: `:nth-child(odd)` na poslední kartě
   je pravda jen tehdy, když opravdu zůstala v řadě sama. */
.info-grid > .info:last-child:nth-child(odd) { grid-column: 1 / -1; }
.info { display: flex; gap: 14px; align-items: flex-start; background: var(--surface); border-radius: var(--r-lg);
  padding: 22px 24px; box-shadow: inset 0 0 0 1px var(--line); transition: transform .35s var(--ease), box-shadow .35s; }
.info:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--line-2), var(--sh); }
.info__ic { width: 44px; height: 44px; border-radius: 10px; flex: none; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent-line); }
.info__ic svg { width: 21px; height: 21px; }
.info__k { display: block; font-family: var(--f-label); font-size: .7rem; letter-spacing: .14em; text-transform: uppercase; color: var(--muted-2); line-height: 1.3; }
.info__v { display: block; font-family: var(--f-display); font-weight: 600; margin-top: 6px; line-height: 1.35; }
.info__v small { display: block; margin-top: 4px; font-family: var(--f-body); font-weight: 400; color: var(--muted); font-size: .85rem; line-height: 1.45; }

.mapframe { width: 100%; height: clamp(360px, 44vw, 520px); border: none; border-radius: var(--r-lg);
  box-shadow: inset 0 0 0 1px var(--line); filter: grayscale(.3) sepia(.12) contrast(.96); }

.hours { display: grid; gap: 0; }
.hours__row { display: flex; justify-content: space-between; padding: 13px 4px; border-bottom: 1px solid var(--line); font-size: .94rem; }
.hours__row span:last-child { font-variant-numeric: tabular-nums; color: var(--muted); }
.hours__row.is-today { color: var(--accent); }
.hours__row.is-today span:last-child { color: var(--accent); }

/* ============================================================
   FOOTER (espresso = .invert)
   ============================================================ */
.footer { position: relative; padding-top: clamp(60px, 8vw, 100px); overflow: hidden; }
/* Pět sloupců od 17. 8. 2026: značka, Gym, Účet, Kontakt, Firma. Provozovatelé
   s IČO a právní odkazy měly dřív spodní lištu, kde se z nich stal řádek o 134
   znacích — `space-between` neměl co rozestoupit a zbytek spadl vlevo pod něj.
   Šířky nejsou stejné schválně: odkazové sloupce jsou krátké, adresa a firma
   potřebují víc, jinak se láme „621 00 Brno-" a „Ochrana osobních údajů". */
.footer__grid { display: grid; grid-template-columns: 1.35fr .8fr .95fr 1.05fr 1.15fr;
  gap: clamp(22px, 2.6vw, 40px); }
.footer__brand .brand { font-size: 1.5rem; }
.footer__about { color: var(--muted); font-size: .92rem; margin-top: 18px; max-width: min(32ch, 100%); }
/* Bez zalomení řádka ikon roztáhla patičku nad šířku displeje (320 px → 325 px). */
.footer__soc { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }
.footer__soc a { width: 40px; height: 40px; border-radius: 10px; display: grid; place-items: center; color: var(--muted);
  box-shadow: inset 0 0 0 1px var(--line-2); transition: color .3s, background .3s, transform .3s; }
.footer__soc a:hover { color: var(--accent-ink); background: var(--accent); transform: translateY(-2px); }
.footer__soc svg { width: 19px; height: 19px; }
.footer__col h3 { font-family: var(--f-label); font-size: .72rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted-2); font-weight: 500; margin-bottom: 18px; }
.footer__col a { display: block; padding: 7px 0; color: var(--muted); font-size: .94rem; transition: color .3s; }
.footer__col a:hover { color: var(--accent); }
/* Firma: jména s IČO nejsou odkazy, tak si nesou vlastní rytmus. */
.footer__osoba { color: var(--muted); font-size: .88rem; line-height: 1.6; margin-bottom: 14px; }
.footer__osoba span { display: block; color: var(--muted-2); font-size: .8rem; }

.footer__bottom { margin-top: clamp(44px, 5vw, 70px); padding-block: 28px; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between; align-items: center; color: var(--muted-2); font-size: .85rem; }
.footer__bottom a { color: var(--muted); }
.footer__bottom a:hover { color: var(--accent); }
/* Zkrácená patička (19 stránek bez mřížky) nemá kam identitu a právní odkazy
   uklidit, takže zůstávají tady — ale ve DVOU řádcích, každý zvlášť zarovnaný
   doleva a doprava. Jeden dlouhý řádek se sám zalomil a vypadal jako omyl. */
.footer__bottom--rows { display: block; }
.footer__bottom--rows .fb__row { display: flex; flex-wrap: wrap; gap: 8px 26px; justify-content: space-between; align-items: baseline; }
.footer__bottom--rows .fb__row + .fb__row { margin-top: 12px; }
/* Odkazy zůstávají v běžném textovém toku s oddělovačem „·". Flexbox z toho
   oddělovače udělá vlastní položku a puntík pak visí sám mezi mezerami. */
.footer__bottom--rows .fb__links { white-space: nowrap; }
.footer__wordmark { position: relative; margin-top: 30px; width: 100vw; margin-left: calc(50% - 50vw);
  font-family: var(--f-body); font-weight: 400;
  /* Váha 400, ne 700: u obrysového písma se vnitřní plocha V, M a Y sbíhá do špičky
     nad spodní hranou a obtáhne se jako malý trojúhelník. U vyplněného písma ho není
     vidět, u obrysu ano. Odstranit ho nejde (je to tvar písma, ne artefakt obrysu —
     ověřeno tím, že roste s velikostí písma), ale při tenčích tazích je vnitřní
     plocha širší a trojúhelník se scvrkne na tečku.
     Kladné prostrkání: stlačení do sebe (dřív -.03em) bylo vidět jako protínající se
     linky. Velikost je menší, aby se prostrkaný nápis vešel do šířky okna
     (nowrap + overflow: hidden by jinak uřízl M). */
  font-size: clamp(2.8rem, 17vw, 15rem); line-height: .8; letter-spacing: .02em;
  color: transparent; -webkit-text-stroke: 1px var(--line-2); text-align: center; white-space: nowrap;
  user-select: none; pointer-events: none; overflow: hidden; }
/* Vnitřní obal vkládá script.js — jen on se posouvá, ořezává ho rodič s overflow: hidden.
   Bez JS (i při prefers-reduced-motion) zůstane text na místě a je vidět celý. */
.footer__wordmark-i { display: block; will-change: transform, opacity; }

/* ============================================================
   DEKORATIVNÍ TVARY
   ============================================================ */
.ring { position: absolute; border-radius: 50%; border: 1px solid var(--line-2); pointer-events: none; z-index: 0; }
.ring--accent { border-color: var(--accent-line); }
.ring--spin { animation: spin 80s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.bignum { font-family: var(--f-display); font-weight: 500;
  font-size: clamp(3.5rem, 9vw, 8rem); line-height: .8; color: transparent;
  -webkit-text-stroke: 1px var(--accent-line); user-select: none; pointer-events: none; }
.vlabel { writing-mode: vertical-rl; font-family: var(--f-label); font-size: .72rem; letter-spacing: .3em;
  text-transform: uppercase; color: var(--muted-2); }
.arc { position: absolute; pointer-events: none; z-index: 0; opacity: .5; }

/* ============================================================
   RŮZNÉ / utility
   ============================================================ */
.center { text-align: center; }
.mt-s { margin-top: 14px; } .mt-m { margin-top: 28px; } .mt-l { margin-top: 48px; }
.hide { display: none !important; }
.badge-soft { display: inline-flex; align-items: center; gap: 8px; padding: 8px 15px; border-radius: var(--r-pill);
  background: var(--surface); color: var(--accent); font-family: var(--f-label); font-size: .74rem;
  letter-spacing: .1em; text-transform: uppercase; box-shadow: inset 0 0 0 1px var(--accent-line); }
.float { animation: float 8s ease-in-out infinite; }
@keyframes float { 0%,100%{ transform: translateY(0) } 50%{ transform: translateY(-10px) } }

/* ---------- Profil lektora: vzdělání a certifikace ---------- */
.creds { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: clamp(22px, 3vw, 38px); }
.creds__g h3 { font-family: var(--f-body); font-weight: 600; font-size: .76rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 12px; }
.creds__g ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 8px; }
.creds__g li { position: relative; padding-left: 16px; color: var(--muted); font-size: .93rem; line-height: 1.5; }
.creds__g li::before { content: "—"; position: absolute; left: 0; color: var(--line-2); }
.creds__g li b { color: var(--text); font-weight: 500; }

.prose { max-width: 68ch; }
.prose p { margin-bottom: 20px; color: var(--muted); font-size: 1.05rem; }
.prose h2 { font-size: clamp(1.5rem, 2.6vw, 2.1rem); margin: 40px 0 18px; }
.prose h3 { font-size: 1.25rem; margin: 30px 0 12px; }
.prose ul { margin: 0 0 20px; display: grid; gap: 11px; }
/* Odrážka je pomlčka, ne puntík — stejná jako v certifikacích lektorů (.creds__g).
   Kulaté tečky před textem působily genericky a na webu už nikde nejsou. */
.prose ul li { display: flex; gap: 12px; color: var(--muted); }
.prose ul li::before { content: "—"; color: var(--line-2); flex: none; }
.breadcrumb { font-family: var(--f-label); font-size: .76rem; color: var(--muted-2); letter-spacing: .06em; }
.breadcrumb a:hover { color: var(--accent); }

/* ============================================================
   MODAL
   ============================================================ */
.modal-back { position: fixed; inset: 0; z-index: 200; background: rgba(27,26,22,.5);
  backdrop-filter: blur(5px); display: grid; place-items: center; padding: 20px;
  opacity: 0; visibility: hidden; transition: opacity .3s var(--ease), visibility .3s; }
.modal-back.show { opacity: 1; visibility: visible; }
.modal { width: 100%; max-width: 420px; background: var(--surface); border-radius: var(--r-xl);
  box-shadow: var(--sh-lg), inset 0 0 0 1px var(--line-2); padding: clamp(26px, 4vw, 36px);
  transform: translateY(16px) scale(.98); transition: transform .4s var(--ease); position: relative;
  /* Na telefonu se delší obsah (např. lekce mimo permanentku) nevešel a spodní
     tlačítko zůstalo pod okrajem — modal se proto uvnitř scrolluje. */
  max-height: calc(100dvh - 32px); overflow-y: auto; overscroll-behavior: contain; }
.modal-back.show .modal { transform: none; }
.modal__close { position: absolute; top: 14px; right: 14px; width: 38px; height: 38px; border-radius: 50%;
  display: grid; place-items: center; color: var(--muted); box-shadow: inset 0 0 0 1px var(--line-2); }
.modal__close:hover { color: var(--text); }
.modal__k { font-family: var(--f-label); font-size: .7rem; letter-spacing: .16em; text-transform: uppercase; color: var(--accent); }
.modal__title { font-family: var(--f-display); font-weight: 600; font-size: 1.6rem; margin: 8px 0 16px; }
.modal__rows { display: grid; gap: 1px; background: var(--line); border-radius: var(--r); overflow: hidden; margin-bottom: 20px; }
.modal__row { display: flex; justify-content: space-between; gap: 12px; background: var(--surface-2); padding: 12px 14px; font-size: .92rem; }
.modal__row span:first-child { color: var(--muted); }
.modal__row span:last-child { font-weight: 600; text-align: right; }
.modal__actions { display: grid; gap: 10px; }
.modal__note { margin: 0 0 18px; font-size: .86rem; line-height: 1.55; color: var(--muted);
  background: var(--bg-2); border-radius: var(--r-sm); padding: 11px 13px; box-shadow: inset 0 0 0 1px var(--line); }
/* lekce mimo permanentku — cena musí padnout do oka dřív, než člověk klikne */
.modal__note--pay { background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-line); color: var(--text); }
.modal__note--pay strong { color: var(--accent); }

/* ============================================================
   LEKCE — detail + figura svalů
   ============================================================ */
.lesson { position: relative; background: var(--surface); border-radius: var(--r-lg); overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line); padding: clamp(24px, 2.6vw, 34px); }
.lesson > * { position: relative; z-index: 1; }
.lesson__head { display: flex; gap: 18px; align-items: flex-start; }
.lesson__ic { width: 50px; height: 50px; flex: none; border-radius: 11px; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent-line); }
.lesson__ic svg { width: 25px; height: 25px; }
.lesson__name { font-family: var(--f-display); font-weight: 600; font-size: 1.5rem; line-height: 1.1; }
.lesson__sub { color: var(--accent); font-family: var(--f-label); font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; margin-top: 6px; }
.lesson__txt { color: var(--muted); margin-top: 16px; font-size: 1.02rem; }
.lesson__tags { margin-top: 16px; display: flex; flex-wrap: wrap; gap: 8px; }

.lesson details { margin-top: 20px; border-top: 1px solid var(--line); }
.lesson summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 8px;
  padding-top: 18px; font-weight: 600; color: var(--accent); font-size: .92rem; }
.lesson summary::-webkit-details-marker { display: none; }
.lesson summary .chev { width: 18px; height: 18px; transition: transform .4s var(--ease); }
.lesson details[open] summary .chev { transform: rotate(180deg); }
.lesson__detail { display: grid; grid-template-columns: 150px 1fr; gap: clamp(20px, 3vw, 36px); padding: 22px 0 6px; align-items: start; }
.lesson__figure { display: grid; place-items: center; gap: 10px; padding: 16px; background: var(--bg-2);
  border-radius: var(--r); box-shadow: inset 0 0 0 1px var(--line); }
.lesson__figcap { font-family: var(--f-label); font-size: .64rem; letter-spacing: .14em; text-transform: uppercase; color: var(--muted-2); text-align: center; }
.lesson__info h3 { font-family: var(--f-label); font-size: .7rem; letter-spacing: .14em; text-transform: uppercase; color: var(--accent); margin: 0 0 8px; }
.lesson__info h3:not(:first-child) { margin-top: 20px; }
.lesson__info p { color: var(--muted); font-size: .96rem; }
.lesson__muscles { display: flex; flex-wrap: wrap; gap: 7px; }

/* Anatomická postava (přední + zadní pohled). Data: HichamELBSI/react-native-body-highlighter (MIT). */
.bodyfig { width: 100%; max-width: 300px; height: auto; display: block; margin: 0 auto;
  stroke-linejoin: round; stroke-linecap: round; }
.bodyfig .fig-base { fill: #D4C9B1; stroke: none; }
.bodyfig .fig-outline { fill: none; stroke: #8C8068; stroke-width: 3.2; }
.bodyfig .b { fill: #DBD2BC; stroke: #B6AA8E; stroke-width: 1.5; }
.bodyfig .m { fill: #E1D8C3; stroke: #B6AA8E; stroke-width: 1.5; transition: fill .5s var(--ease); }
.bodyfig[data-on~="shoulders"] .m-shoulders,
.bodyfig[data-on~="chest"]     .m-chest,
.bodyfig[data-on~="core"]      .m-core,
.bodyfig[data-on~="arms"]      .m-arms,
.bodyfig[data-on~="back"]      .m-back,
.bodyfig[data-on~="glutes"]    .m-glutes,
.bodyfig[data-on~="legs"]      .m-legs,
.bodyfig[data-on~="calves"]    .m-calves { fill: var(--accent); stroke: #5E471F; }

/* KDE NÁS NAJDEŠ */
.findus { display: grid; grid-template-columns: 1fr 1.2fr; gap: clamp(24px, 3vw, 48px); align-items: center; }
.findus__map { position: relative; }

/* Kontakt: pravý sloupec (otevírací doba + mapa) končil o 200 px níž než
   formulář vedle něj a mezi nimi zůstávala díra. Mapa proto dorovná zbytek
   výšky — obě strany končí na stejné lince a mapa vyjde menší, což je i tak
   dost velké okno na to, aby se v něm dala najít adresa. Pod 921 px se sloupce
   skládají pod sebe, tam si mapa nechá svou vlastní výšku. */
@media (min-width: 921px) {
  .kontakt__grid { align-items: stretch; }
  .kontakt__grid > * { display: flex; flex-direction: column; }
  .kontakt__grid .findus__map { flex: 1; min-height: 260px; }
  .kontakt__grid .findus__map .mapframe { height: 100%; }
}
/* Mapa — klik pro interakci: vrstva přes iframe, takže scroll posouvá stránku (mapa „neuteče") */
.mapwrap { position: relative; border-radius: var(--r-lg); overflow: hidden; }
.mapwrap .mapframe { pointer-events: none; display: block; }
.mapwrap.is-live .mapframe { pointer-events: auto; }
.mapwrap__veil { position: absolute; inset: 0; z-index: 1; border: 0; padding: 0; cursor: pointer;
  background: transparent; display: grid; place-items: center; transition: background .25s var(--ease); }
.mapwrap__veil:hover, .mapwrap__veil:focus-visible { background: rgba(27,26,22,.05); outline: none; }
.mapwrap__veil span { background: var(--text); color: var(--surface); font-size: .82rem; font-weight: 600;
  padding: 9px 16px; border-radius: 999px; box-shadow: var(--sh); opacity: 0; transform: translateY(8px);
  transition: opacity .25s, transform .25s; }
.mapwrap__veil:hover span, .mapwrap__veil:focus-visible span { opacity: 1; transform: none; }
.mapwrap.is-live .mapwrap__veil { display: none; }
.mapwrap__open { position: absolute; top: 12px; right: 12px; z-index: 2; background: var(--surface); color: var(--text);
  font-size: .78rem; font-weight: 600; padding: 7px 12px; border-radius: 999px;
  box-shadow: var(--sh), inset 0 0 0 1px var(--line); text-decoration: none; }
.mapwrap__open:hover, .mapwrap__open:focus-visible { color: var(--accent); }
@media (prefers-reduced-motion: reduce) { .mapwrap__veil span { transition: none; } }

/* GALERIE (reálné fotky studia) */
.gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(10px, 1.4vw, 16px); }
.gallery__item { position: relative; overflow: hidden; border-radius: var(--r-lg); aspect-ratio: 4/3;
  box-shadow: inset 0 0 0 1px var(--line); background: var(--surface-2); }
.gallery__item img { width: 100%; height: 100%; object-fit: cover; transition: transform .9s var(--ease); }
.gallery__item:hover img { transform: scale(1.05); }
.gallery__item--tall { grid-row: span 2; aspect-ratio: 3/4; }

/* Foto nahoře v kartě lekce.
   Býval to pruh 21/8. Karta je jednosloupcová a široká 1036 px, takže se do pruhu
   vešlo jen 57 % výšky snímku a lidem to uřezávalo hlavy a chodidla — přesně to
   majitel reklamoval. Žádná hodnota `object-position` to nespraví, postava zabírá
   80–100 % výšky souboru; musí se změnit poměr. 3/2 je nejširší poměr, ve kterém
   mají všechny vybrané snímky ještě rezervu (16/9 už neunese funkční trénink ani
   skupinovou BARRE) a zároveň je to poměr, ve kterém soubory rovnou vznikají —
   fotka se tím nezmenší ani neořízne, je vidět celá. */
.lesson__media { margin: calc(-1 * clamp(24px, 2.6vw, 34px)) calc(-1 * clamp(24px, 2.6vw, 34px)) clamp(16px, 2vw, 22px);
  aspect-ratio: 3/2; overflow: hidden; background: var(--surface-2); }
.lesson__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .9s var(--ease); }
/* Box je jediná výjimka. Boxer stojí a celý se vejde nejvýš do 1,13:1 — ve 3/2 končí
   v půli stehna, v 5/4 pod kolenem. Dotažení plátna zrcadlením tu nejde, vlevo by
   zduplikovalo jeho nohu. Než bude fotka z větší dálky, má karta boxu čtverec. */
.lesson__media--ctverec { aspect-ratio: 1/1; }
.lesson:hover .lesson__media img { transform: scale(1.04); }

/* celá karta lekce je odkaz na detail — bez tlačítka „Zjistit více" */
.lesson--link { cursor: pointer; }
.lesson > .lesson__link { position: absolute; inset: 0; z-index: 2; border-radius: inherit; }
.lesson > .lesson__link:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
/* odkazy uvnitř poznámky (e-mail) musí zůstat klikatelné nad překryvem,
   zbytek poznámky klik propouští na kartu */
.lesson--link > .lesson__note { z-index: 3; pointer-events: none; }
.lesson--link > .lesson__note a { pointer-events: auto; }
.lesson--link:hover .lesson__name, .lesson--link:focus-within .lesson__name { color: var(--accent); }
.lesson__name { transition: color .25s var(--ease); }

/* COOKIE LIŠTA */
/* Přes otevřené mobilní menu se lišta nezobrazuje — zakrývala tlačítko „Rezervovat lekci". */
body.menu-open .cookiebar { display: none; }
/* Na malém telefonu (iPhone SE) lišta překryla tlačítko „Závazně rezervovat" v modalu
   — ťuknutí doprostřed tlačítka pak trefilo lištu a rezervace nešla dokončit. */
body:has(.modal-back.show) .cookiebar { display: none; }
.cookiebar { position: fixed; left: 12px; right: 12px; bottom: max(12px, env(safe-area-inset-bottom)); z-index: 250; max-width: 560px; margin-inline: auto;
  background: var(--surface); border-radius: var(--r-lg); box-shadow: var(--sh-lg), inset 0 0 0 1px var(--line-2);
  padding: 16px 18px; display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
  transform: translateY(160%); transition: transform .6s var(--ease); }
.cookiebar.show { transform: none; }
.cookiebar__txt { flex: 1; min-width: 200px; font-size: .88rem; color: var(--muted); }
.cookiebar__txt a { color: var(--accent); text-decoration: underline; }
.cookiebar__btn { flex: none; }

/* ============================================================
   RESPONZIVITA
   ============================================================ */
@media (max-width: 1040px) {
  .hero { min-height: auto; display: block; }
  .hero__grid { grid-template-columns: 1fr; }
  .hero__visual { max-width: 440px; margin-inline: auto; order: -1; }
  .hero__lead { max-width: 54ch; }
  /* Čtyři odkazové sloupce na dvě řady po dvou. Tři a jeden osamocený pod nimi
     vypadalo jako zbytek, který se nevešel. */
  .footer__grid { grid-template-columns: repeat(2, 1fr); }
  .footer__brand { grid-column: 1 / -1; }
}
@media (max-width: 920px) {
  .nav__links { display: none; }
  .nav__login { display: none; }
  .nav__cta .btn--primary { display: none; }
  .nav__burger { display: block; }
  .svc-grid, .plans, .trainers, .quotes, .gallery { grid-template-columns: repeat(2, 1fr); }
  .gallery__item--tall { grid-row: auto; aspect-ratio: 4/3; }
  .day { min-height: auto; }
  .dash__grid { grid-template-columns: 1fr; }
  .findus { grid-template-columns: 1fr; }
}
@media (max-width: 620px) {
  :root { --nav-h: calc(68px + var(--nav-safe)); }
  /* Na telefonu je výchozí „po dnech" (nastavuje app.js): pruh s celým týdnem
     a pod ním jeden den. „Celý týden pod sebou" zůstává v přepínači. */
  .sched__days.is-seznam { grid-template-columns: 1fr; }
  .sched__days.is-den { margin-inline: 0; }
  /* Čtyři filtry pod sebou zabraly půl displeje dřív, než člověk viděl první
     lekci. Vejdou se po dvou, když popisek („LEKCE") sdílí řádek s hodnotou
     a nezalamuje se. */
  .sched__filters { gap: 8px; margin-bottom: 18px; }
  /* Na telefonu se `.sched__bar` zalomí a týdenní navigace zůstane sama na řádku.
     `justify-content: space-between` pak jediný prvek přisaje doleva a vpravo
     zbyde díra: naměřeno 390 px, navigace široká 224 px se středem na 132,
     kdežto pruh dnů pod ní má střed 195. Na počítači zůstává vpravo naproti
     filtrům, tam je to záměr. */
  .sched__bar .sched__week { width: 100%; justify-content: center; }
  /* Popisek nad hodnotu, ne vedle ní: vedle sebe se do půlky displeje nevešly
     a hodnota se ořezávala na „Všechny l…". Takhle je vidět celá. */
  .sched__filters .fsel { flex: 1 1 calc(50% - 4px); min-width: 0; flex-direction: column;
    align-items: stretch; gap: 1px; padding: 7px 10px 8px 12px; }
  .sched__filters .fsel__l { font-size: .55rem; letter-spacing: .1em; }
  .sched__filters .fsel__btn { font-size: .92rem; min-width: 0; justify-content: space-between; }
  .sched__filters .fsel__val { max-width: none; }
  .sched__count { flex: 1 1 100%; margin-left: 2px; }
  .dstrip { gap: 5px; }
  .day--solo { padding: 14px 12px 6px; }
  .day--solo .day__h { font-size: 1.05rem; }
  .svc-grid, .plans, .trainers, .quotes, .info-grid, .statbar, .field-row { grid-template-columns: 1fr; }
  /* ⚠️ Statbar jede na `grid-auto-flow: column`, aby se přizpůsobil počtu
     položek. Samotné `grid-template-columns: 1fr` ho tady neskládá pod sebe —
     implicitní sloupce by se tvořily dál. Tok se musí přepnout zpátky na řádky. */
  .statbar { grid-auto-flow: row; }
  /* V ceníku drží prázdný odznak (`aria-hidden`) místo v kartách bez štítku,
     aby tři názvy plánů lícovaly na jedné lince. Jakmile se karty seřadí pod
     sebe, není co lícovat a z rezervy je jen 51 px prázdna na kartu — přesně
     to, na co Jakub 14. 8. 2026 ukázal. */
  .plan__badge[aria-hidden] { display: none; }
  .statbar__i + .statbar__i::before { display: none; }
  .statbar__i { border-top: 1px solid var(--line); }
  .statbar__i:first-child { border-top: none; }
  .hero__card { position: static; width: 100%; margin-top: 16px; }
  .hero__visual { max-width: 100%; }
  .callout-mini { flex-direction: column; align-items: stretch; text-align: center; }
  .callout-mini .btn { width: 100%; }
  /* Tlačítka mají white-space: nowrap — vedle sebe se na telefon nevešla
     a delší popisek („Založit účet zdarma") přetékal z tlačítka ven. */
  .callout__cta { flex-direction: column; align-items: stretch; }
  .callout__cta .btn { width: 100%; white-space: normal; }
  .footer__grid { grid-template-columns: 1fr 1fr; }
  /* Tlačítko přes celou šířku už nemá kam růst — dlouhý popisek („Napsat na
     info@movegym.cz") se musí zalomit, jinak leze z tlačítka ven. */
  .btn--block { white-space: normal; padding-inline: 1.2em; }
  .lesson__detail { grid-template-columns: 1fr; justify-items: center; }
  .lesson__figure { max-width: 200px; }
}

/* Nejužší telefony (320 px). Hodnota filtru („Všichni lektoři") tu přetéká
   o pár pixelů a ořízla by se na „Všichni l…"; menší písmo je pořád čitelné
   a filtr zůstane celý. Blok MUSÍ být až za celým 620px blokem — když jsem ho
   omylem vrazil doprostřed, zbytek mobilních pravidel se přestal používat
   a jednosloupcové mřížky na telefonu zmizely. */
@media (max-width: 370px) {
  .sched__filters .fsel { padding: 6px 8px 7px 10px; }
  .sched__filters .fsel__btn { font-size: .84rem; }
  .sched__filters .fsel__l { font-size: .52rem; }
}

/* ---------- Právní stránky (GDPR, obchodní podmínky) ---------- */
.legal { padding: calc(var(--nav-h) + 44px) 0 76px; }
.legal__wrap { max-width: var(--maxw-narrow); margin: 0 auto; padding-inline: var(--gutter); }
.legal__title { font-family: var(--f-display); font-weight: 500; font-size: clamp(1.9rem, 4vw, 2.8rem);
  line-height: 1.08; margin: 10px 0 14px; }
.legal__lead { font-size: 1.08rem; color: var(--muted); max-width: 62ch; margin-bottom: 6px; }
.legal h2 { font-family: var(--f-display); font-weight: 500; font-size: 1.32rem; margin: 34px 0 10px; }
.legal h3 { font-family: var(--f-body); font-weight: 600; font-size: 1.02rem; letter-spacing: -.005em;
  margin: 22px 0 8px; color: var(--text); }
.legal p { margin: 0 0 12px; line-height: 1.72; color: var(--text); }
.legal ul { margin: 0 0 16px; padding-left: 1.2em; }
.legal li { margin: 6px 0; line-height: 1.6; color: var(--text); }
.legal a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.legal code { font-family: var(--f-mono); font-size: .85em; background: var(--surface-2);
  padding: 1px 6px; border-radius: 5px; }
/* Přehledová tabulka v právních textech (účel → údaje → právní základ → doba).
   Na úzkých displejích se posouvá vodorovně uvnitř svého rámu, stránka nepřetéká. */
.legal__table { overflow-x: auto; margin: 0 0 18px; -webkit-overflow-scrolling: touch; }
.legal__table table { border-collapse: collapse; width: 100%; min-width: 560px; font-size: .93rem; }
.legal__table th, .legal__table td { text-align: left; vertical-align: top; padding: 10px 14px 10px 0;
  border-bottom: 1px solid var(--line); line-height: 1.55; }
.legal__table th { font-weight: 600; color: var(--text); border-bottom-color: var(--line-2); }
.legal__table td { color: var(--muted); }
.legal__table td:first-child { color: var(--text); font-weight: 500; }
.legal__note { background: var(--surface-2); border-left: 3px solid var(--accent-2);
  border-radius: 0 8px 8px 0; padding: 12px 16px; margin: 0 0 16px; }
.legal__note p:last-child { margin-bottom: 0; }
.legal__meta { color: var(--muted); font-size: .92rem; }
.legal__back { margin-top: 34px; }

/* ---------- Hero: hodnocení (social proof u CTA) ---------- */
.hero__rating { display: inline-flex; align-items: center; gap: 10px; margin-top: 18px;
  color: var(--muted); font-size: .92rem; text-decoration: none; transition: color .3s; }
.hero__rating:hover { color: var(--text); }
.hero__rating strong { color: var(--text); font-weight: 700; }
.hero__stars { color: var(--accent); letter-spacing: 2px; font-size: .95rem; white-space: nowrap; }

/* ============================================================
   HERO — FULL-BLEED (homepage): dramatická fotka + velký serif claim
   ============================================================ */
.hero-fb { position: relative; min-height: 100svh; display: flex; align-items: center; overflow: hidden; }
/* overflow kvůli pomalému odzoomování fotky: obal si přesah klipuje sám a
   nepropisuje ho do sekce. */
.hero-fb__bg { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
/* 62% 38% patřilo portrétní box-1; skupinová fotka na šířku potřebuje střed. */
.hero-fb__bg img { width: 100%; height: 100%; object-fit: cover; object-position: center 45%; }
.hero-fb__bg::after { content: ""; position: absolute; inset: 0;
  /* 🔴 ZTMAVENO 26. 8. 2026 SPOLU S VÝMĚNOU HERO FOTKY. Nové snímky mají
     světle šedou betonovou zeď a světlé parkety, kdežto předchozí fotka byla
     tmavě hnědá. Se starým závojem (.58/.44/.52/.42/.86) spadl kontrast na
     2,8–3,3:1 v nejhorším místě, tedy pod čitelnost, a to na obou šířkách.
     Hodnoty nejsou odhad: `scratchpad/zavoj.mjs` proměřil čtyři varianty na
     390 i 1440 px a tahle je nejsvětlejší, která projde všude (nejhorší místo
     4,5–5,2:1). ⚠️ Po každé výměně hero fotky pustit `npm run kontrast`,
     závoj sedí na konkrétní snímek. */
  background: linear-gradient(180deg, rgba(18,15,10,.66) 0%, rgba(18,15,10,.60) 22%, rgba(18,15,10,.66) 50%, rgba(18,15,10,.58) 74%, rgba(18,15,10,.90) 100%); }
/* ⚠️ `background-size` je povinné. Bez něj se dlaždice šumu škáluje s hustotou
   displeje, takže na iPhonu s DPR 3 je zrno třikrát jemnější a prakticky zmizí
   přesně na zařízení, na kterém web většina lidí uvidí. */
.hero-fb__grain { position: absolute; inset: 0; z-index: 1; opacity: .06; pointer-events: none; mix-blend-mode: overlay;
  background-size: 180px 180px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.hero-fb > .wrap { position: relative; z-index: 2; width: 100%; text-align: center;
  padding-top: calc(var(--nav-h) + 32px); padding-bottom: clamp(40px, 6vh, 80px); }
/* ⚠️ DROBNÝ TEXT NA FOTCE NESMÍ BÝT BRONZOVÝ. Bronz má střední jas, takže se
   proti fotce nevytáhne, ať je závoj jakkoli silný: při ztmavení z .34 na .76
   se kontrast hnul z 1,40 na 1,58 a pořád byl nečitelný. Světlá krémová to
   řeší jedním krokem. Linka u nadpisku zůstává bronzová (`::before` má barvu
   napsanou zvlášť), takže se akcent neztrácí. */
.hero-fb__eyebrow { color: #EFE7D6; font-family: var(--f-label); font-size: .72rem; letter-spacing: .2em;
  text-transform: uppercase; display: inline-flex; align-items: center; gap: 12px; }
.hero-fb__eyebrow::before { content: ""; width: 40px; height: 1px; background: var(--accent-2); display: inline-block; }
.hero-fb__title { font-family: var(--f-display); color: #F7F2E7; font-weight: 500; line-height: .95;
  letter-spacing: -.015em; font-size: clamp(3.4rem, 10.5vw, 8.6rem); margin: 20px 0 0;
  text-shadow: 0 2px 60px rgba(0,0,0,.4); max-width: 15ch; margin-inline: auto; }
.hero-fb__title em { font-style: italic; color: var(--accent-2); }
.hero-fb__lead { color: #E9E1D1; max-width: 48ch; margin: 24px auto 0; font-size: clamp(1rem, 1.35vw, 1.2rem); line-height: 1.6; }
.hero-fb__cta { margin-top: 32px; display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; }
.hero-fb__rating { margin-top: 26px; color: #E9E1D1; display: inline-flex; align-items: center; gap: 10px;
  font-size: .92rem; text-decoration: none; transition: opacity .3s; }
.hero-fb__rating:hover { opacity: .82; }
.hero-fb__rating .st { color: var(--accent-2); letter-spacing: 2px; white-space: nowrap; }

/* ---------- nástup hera při otevření stránky ----------
   Čistě CSS (žádný JS): kdyby se skript nenačetl, obsah je stejně vidět.
   Fotka se zlehka odzoomuje, text nastupuje odspodu po řadě. */
@keyframes heroIn { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }
@keyframes heroZoom { from { transform: scale(1.07); } to { transform: none; } }
@keyframes heroVeil { from { opacity: .55; } to { opacity: 1; } }

/* Nadpis vyjíždí po slovech zpod masky. Animuje se jen transform a opacity —
   filter: blur() na písmu téhle velikosti trhá na slabších telefonech. */
@keyframes heroSlovo { from { opacity: 0; transform: translateY(112%); } to { opacity: 1; transform: none; } }

.hero-fb__title .rvl { display: inline-block; overflow: hidden; vertical-align: bottom;
  /* ⚠️ Maska MUSÍ být vyšší než řádek, jinak uřízne háček nad „ě" a čárku nad „á".
     Padding ji zvětší, záporný margin vrátí sazbu přesně tam, kde byla. */
  /* Jen svisle. Boční odsazení rozšiřovalo krajní slovo o 0,08em za okraj
     nadpisu a hero na 390 px přetékal o 2 px (našel audit). */
  padding: .22em 0 .12em; margin: -.22em 0 -.12em; }
.hero-fb__title .rvl__i { display: inline-block; }

/* 🔴 CHOREOGRAFIE SE 26. 8. 2026 ZKRÁTILA NA POLOVINU. Jakub poslal snímek
   z telefonu, na kterém je v heru VIDĚT JEN NADPISEK A PŮLKA PRVNÍHO SLOVA:
   odstavec, tlačítka i hvězdičky mají `both`, takže do svého zpoždění drží
   `opacity: 0`. Poslední z nich naskakoval až v 3,45 s a `heroZoom` držel
   fotku přiblženou celých 9 s, takže postavě uřízl hlavu i dlaně.
   Teď je všechno na místě v 1,9 s. ⚠️ Nová čísla se musí vejít pod pojistku
   `hero.js` (2,4 s), jinak pojistka uřízne doběh animace. */
.hero-fb__bg img { animation: heroZoom 6s var(--ease-out) both; }
.hero-fb__bg::after { animation: heroVeil 1.8s var(--ease) both; }
.hero-fb__eyebrow { animation: heroIn .9s var(--ease-out) .1s both; }
/* Linka u nadpisku se vykresluje zleva. Přes scaleX, ne přes width — šířka je
   layout a pruh by při každém snímku posouval text vedle sebe. */
@keyframes heroLinka { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.hero-fb__eyebrow::before { transform-origin: left center;
  animation: heroLinka 1s var(--ease-out) .3s both; }
/* Nadpis sám už nenajíždí — nastupují jeho slova, jinak by se pohyby sčítaly. */
.hero-fb__title .rvl__i { animation: heroSlovo 1s var(--ease-out) both; }
.hero-fb__title .rvl:nth-child(1) .rvl__i { animation-delay: .15s; }
.hero-fb__title .rvl:nth-child(2) .rvl__i { animation-delay: .28s; }
/* Bronzové „tělo." je pointa věty, tak dorazí znatelně později. */
.hero-fb__title .rvl:nth-child(3) .rvl__i { animation-delay: .42s; }
.hero-fb__lead    { animation: heroIn 1s var(--ease-out) .6s both; }
.hero-fb__cta     { animation: heroIn 1s var(--ease-out) .75s both; }
.hero-fb__rating  { animation: heroIn 1s var(--ease-out) .9s both; }

/* ⚠️ POJISTKA. Když se animace zaseknou (iOS v úsporném režimu, karta otevřená
   na pozadí, návrat přes bfcache), zůstal by hero prakticky prázdný a fotka
   přiblížená. `script.js` proto po 2,4 s a při návratu na kartu přidá tuhle
   třídu, která dorovná koncový stav. Text v heru se nesmí schovávat za animaci. */
.hero-fb.je-hotovo .hero-fb__bg img,
.hero-fb.je-hotovo .hero-fb__bg::after,
.hero-fb.je-hotovo .hero-fb__eyebrow,
.hero-fb.je-hotovo .hero-fb__eyebrow::before,
.hero-fb.je-hotovo .hero-fb__title .rvl__i,
.hero-fb.je-hotovo .hero-fb__lead,
.hero-fb.je-hotovo .hero-fb__cta,
.hero-fb.je-hotovo .hero-fb__rating { animation: none; opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .hero-fb__bg img, .hero-fb__bg::after, .hero-fb__eyebrow, .hero-fb__title,
  .hero-fb__lead, .hero-fb__cta, .hero-fb__rating, .hero-fb__title .rvl__i,
  .hero-fb__eyebrow::before { animation: none; }
  /* Maska bez animace nemá co skrývat a mohla by ořezávat při jiné velikosti písma. */
  .hero-fb__title .rvl { overflow: visible; }
}
.hero-fb__rating strong { color: #F7F2E7; font-weight: 700; }
.hero-fb .btn--ghost { color: #F7F2E7; box-shadow: inset 0 0 0 1px rgba(247,242,231,.42); }
.hero-fb .btn--ghost:hover { box-shadow: inset 0 0 0 1px rgba(247,242,231,.9); background: rgba(247,242,231,.08); }

/* světlý nav nad tmavým herem (jen homepage, dokud není odscrollováno) */
body[data-page="home"] .nav:not(.scrolled) .brand__word,
body[data-page="home"] .nav:not(.scrolled) .nav__links a,
body[data-page="home"] .nav:not(.scrolled) .nav__login { color: #F7F2E7; }
body[data-page="home"] .nav:not(.scrolled) .nav__links a:hover,
body[data-page="home"] .nav:not(.scrolled) .nav__links a[aria-current="page"] { color: #fff; }
body[data-page="home"] .nav:not(.scrolled) .brand__tag { background: #F7F2E7; color: #17130C; }
body[data-page="home"] .nav:not(.scrolled) .nav__burger span { background: #F7F2E7; }

/* 🔴 BÍLÝ PRUH NAD FOTKOU: SAFARI 26 UŽ NEČTE `theme-color` (27. 8. 2026).
   Jakub otevřel web na iPhonu 16 Pro a nad herem svítil ivory pruh přesně
   62 px vysoký, tedy `env(safe-area-inset-top)`. Nebylo to odsazení stránky
   — v CSS žádné není. Safari 26 („Liquid Glass") si plochu pod status barem
   obarvuje SAMO a barvu si vzorkuje z CSS: bere `background-color` prvku
   s `position: fixed/sticky` u okraje, a když ten je průhledný, spadne na
   `body`. Naše `body` je ivory, `.nav` byl bez pozadí, takže vyšla ivory.
   `<meta name="theme-color">` na to od Safari 26 nemá vliv, i když v HTML je.

   Fotku pod status bar dostat NEJDE: při scrollu 0 Safari skutečné pixely pod
   svou lištou nekompozituje a použije tuhle náhradní barvu. Jde ale obarvit
   ji tónem fotky, což je přesně ten trik, co je dole s parketami.

   ⚠️ Odstín je vzorkovaný ze SNÍMKU stránky (fotka + závoj + zrno), ne ze
   souboru — `scratchpad/hero-horni-pruh2.mjs` měří po řádcích a vynechá
   logo. Naměřeno na 402×874: horních 140 px jde od #46423a do #49453d, tedy
   rozptyl 3, a šev mezi pruhem a fotkou vychází na rozdíl 1/1/1. Plná barva
   je tam proto neviditelná.
   ⚠️ Musí to být `background-color` PŘÍMO na `.nav`. Safari nevzorkuje
   pseudo-prvky ani absolutně pozicované potomky, a `background-image`
   (gradient) taky ne. Po výměně hero fotky odstín přeměřit. */
body[data-page="home"] .nav:not(.scrolled) { background-color: #47433B; --nav-barva: #47433B; }
/* Kdyby Safari sáhlo na kořen místo na `.nav`: na úvodní stránce je nahoře
   tmavý hero a dole tmavá patička, takže tmavý kořen sedí obojímu. Body si
   svoje ivory maluje dál přes celou výšku dokumentu, na stránce se tím nic
   nemění — projeví se to jen v přetažení (rubber band), kde dřív blikalo
   bílé pozadí. Prohlížeč bez `:has()` pravidlo přeskočí a nic se nerozbije. */
html:has(body[data-page="home"]) { background-color: #47433B; }
/* 🔴 TÁŽ VADA NA TMAVÝCH STRÁNKÁCH APPKY (28. 8. 2026, Jakubovy dva snímky).
   `body[data-app]` přepisuje `--bg` na espresso, ale JEN NA BODY — `html` si
   token bere z `:root`, takže kořen zůstal IVORY. Kdekoli kořen prosvitne
   (přetažení stránky, sešívaný snímek celé stránky, mezikrok přechodu mezi
   stránkami) je pod tmavou appkou světlý pruh. Změřeno na produkci: html
   #F4F0E7 vs body #1A1710 na všech šesti stránkách s `data-app`.
   ⚠️ Selektor je na ATRIBUT, ne na výčet stránek — kdo přidá `data-app`,
   dostane správný kořen bez dalšího zásahu. Hlídá `scratchpad/pozadi.mjs`. */
html:has(body[data-app]) { background-color: #1A1710; }

@media (max-width: 720px) {
  /* 🔴 `dvh`, NE `svh` (26. 8. 2026). `svh` je výška okna s ROZBALENÝMI lištami.
     Jakmile se v Safari lišta smrskne na pilulku, je viditelná plocha vyšší
     a pod herem vykoukne pruh ivory pozadí další sekce — přesně to Jakub
     vyfotil potřetí. `dvh` drží hero na aktuální viditelné ploše vždycky.
     ⚠️ Dřív tu stálo, že `dvh` poskakuje. Platilo to, dokud byl text heru
     svisle vycentrovaný: se změnou výšky se přepočítával jeho střed. Od
     přesunu textu nahoru (`align-items: flex-start`) na výšce heru nezávisí,
     a fotka je ukotvená k dolnímu okraji, takže se plocha jen dorolovává. */
  /* 🔴 LIŠTA SAFARI 26 JE PLOVOUCÍ PŘEKRYV. Zjištěno z rešerše (Safari 26
     „Liquid Glass") i z Jakubových snímků: stránka pod lištou pokračuje,
     `dvh` ani `visualViewport` tu plochu nepopisují a KAŽDÝ pokus fotku na
     hranu lišty napasovat nechal nad ní pruh — nejdřív ivory (pozadí další
     sekce), pak tmavý (podklad heru). Doporučený postup je opačný: nechat
     fotku PŘETÉCT pod lištu, ať prohlížeč pod sklem vidí skutečný obsah.
     Proto `inset: 0`, tedy fotka přes celý hero, a hero přes celou plochu
     stránky. K tomu patří `viewport-fit=cover` v meta tagu (bez něj se
     stránka za lištu vůbec nedostane) a tmavý podklad heru pro případ, že
     by fotka nedojela.
     ⚠️ Postava se kvůli tomu posunula v souboru výš: pod dlaněmi je 15 %
     podlahy, takže i s lištou, která bere ~11 % výšky, zůstane celá nad ní.
     Dělá to `scripts/hero-mobil-stojka.mjs`. */
  .hero-fb { min-height: 100svh; min-height: 100dvh; min-height: var(--vh-cela, 100lvh);
    /* Podklad heru je BARVA PARKET, ne tmavá. Ukáže se jen v pruhu pod fotkou
       (mezi hranou lišty a koncem plochy) a odstín je vzorkovaný z dolních
       řádků samotné fotky pod závojem, takže pruh čte jako pokračování
       podlahy. Tmavý podklad tam dělal viditelný blok.
       ⚠️ Odstín NENÍ z fotky, ale ze SNÍMKU stránky: parkety pod závojem
       vycházejí na #af8354, kdežto samotný soubor má #e7ac6e. Kdo vzorkuje
       soubor, netrefí se o dva tóny. */
    background: #ad8254; }
  /* Fotka jde přes CELÝ hero, tedy až pod lištu. Jakub 27. 8.: „jenom natáhni
     tu fotku dolů, ať je na full screenu." Tím je jedno, kde přesně lišta
     začíná, a žádný pruh nevzniká. Postava se kvůli tomu posunula v souboru
     výš (dlaně na 93 %), viz scripts/hero-mobil-stojka.mjs. */
  .hero-fb__bg { inset: 0; }
  /* 🔴 TEXT NAHORU, SPODEK PATŘÍ FOTCE (26. 8. 2026). Změřeno na živém webu:
     text heru zabírá na 390×844 celkem 492 px z 844 (58 %). Vycentrovaný svisle
     začínal na 204 px a končil na 696 px, takže na postavu zbývalo 148 px a
     tlačítka jí ležela přes trup. Odsazený pod lištu končí na 590 px a dole
     zbývá 254 px, do kterých se celá figura vejde (viz scripts/hero-mobil-stojka.mjs). */
  .hero-fb { align-items: flex-start; }
  .hero-fb > .wrap { padding-top: calc(var(--nav-h) + 24px); padding-bottom: 0; }
  /* Závoj má proto na telefonu vlastní průběh: nad 71 % tmavý, ať text drží
     4,5:1 (nejníž leží hvězdičky, změřeno 5,49:1 v nejhorším pixelu), pod 71 %
     rychle světlá, jinak by byla postava skoro černá. */
  .hero-fb__bg::after { background: linear-gradient(180deg, rgba(18,15,10,.72) 0%, rgba(18,15,10,.68) 30%, rgba(18,15,10,.66) 68%, rgba(18,15,10,.62) 71%, rgba(18,15,10,.34) 80%, rgba(18,15,10,.28) 100%); }
  /* 🔴 `center bottom`, NE PROCENTA. Soubor má poměr 0,4615, ale rám heru ho
     nemá vždycky: Safari si nechává lišty, takže `100svh` vyjde třeba 390×760
     (poměr 0,51) a `cover` musí fotku oříznout SVISLE. S hodnotou `38 %` se
     62 % přebytku ubíralo ZDOLA, tedy přesně z postavy: změřeno, že na rámu
     390×760 je vidět jen 3,8–93,8 % výšky souboru a dlaně (96 %) jsou pryč.
     Přesně tohle Jakub vyfotil na svém iPhonu. `bottom` posadí ořez nahoru,
     kde je jen prázdná zeď: na všech šesti zkoušených rámech (SE, mini, 12,
     11, Pro Max, nízký rám) je pak spodek souboru vidět celý. */
  .hero-fb__bg img { object-position: center bottom; }
  /* 🔴 ŽÁDNÉ PŘIBLIŽOVÁNÍ NA TELEFONU. `heroZoom` startuje na scale(1.07) a ubírá
     3,5 % z každé strany, tedy přesně dlaně a hlavu postavy, která sedí u spodního
     okraje. Na snímku z Jakubova iPhonu z ní byl vidět trup a nic víc. Na počítači
     zůstává, tam má figura po stranách rezervu. */
  .hero-fb__bg img { animation: none; }
  .hero-fb__title { font-size: clamp(2.9rem, 14vw, 4.6rem); }
  .hero-fb__lead { font-size: 1rem; }
  /* Popisek se láme na dva řádky a vodorovná linka pak zůstávala sama vlevo. */
  .hero-fb__eyebrow { font-size: .66rem; letter-spacing: .16em; }
  .hero-fb__eyebrow::before { display: none; }
  /* 🔴 TLAČÍTKA VEDLE SEBE, JINAK SE POSTAVA DO HERU NEVEJDE. Blok textu měřil
     492 z 844 px a mezi jeho spodkem a lištou Safari zbývalo ~120 px, kdežto
     figura má 226 px: buď ji zakryla tlačítka, nebo lišta. Vedle sebe měří
     blok tlačítek 52 px místo 140, takže se uvolnilo 88 px.
     ⚠️ Odsazení a písmo jsou zmenšené jen tak, aby se dvojice vešla s rezervou:
     naměřeno 151 + 163 + 10 = 324 px z 350 px, tedy 26 px k dobru. Dotykový cíl
     zůstává 52 px, nad hranicí 44 px. */
  .hero-fb__cta { flex-wrap: nowrap; gap: 10px; margin-top: 26px; }
  .hero-fb__cta .btn { padding: 14px 16px; font-size: .92rem; white-space: nowrap; }
}


/* ============================================================
   GALERIE: ZVĚTŠENÍ FOTKY (lightbox)
   ============================================================
   Dlaždice se dá rozkliknout a šipkami se přepíná. Tlačítko dovnitř vkládá
   `script.js`, tady je jen vzhled.
   ⚠️ Překryv musí být `position: fixed` s `inset: 0` a vlastním `z-index`
   nad hlavičkou — ta je sticky a jinak by přes tmavé pozadí prosvítala. */
.gallery__item--zoom { cursor: zoom-in; }
.gallery__open { position: absolute; inset: 0; z-index: 2; border: 0; padding: 0;
  background: transparent; cursor: zoom-in; border-radius: inherit; }
.gallery__open:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }
/* Lupa se objeví až na najetí. Na dotykovém displeji hover neexistuje, proto
   je na dlaždici i tak `cursor: zoom-in` a celá plocha je klikací. */
.gallery__item--zoom::after { content: ""; position: absolute; z-index: 1;
  right: 12px; bottom: 12px; width: 34px; height: 34px; border-radius: 50%;
  background: rgba(20,17,11,.55) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' fill='none' stroke='%23F4F0E7' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='8' cy='8' r='6'/%3E%3Cpath d='M12.5 12.5 16.5 16.5M8 5.5v5M5.5 8h5'/%3E%3C/svg%3E") center/18px no-repeat;
  opacity: 0; transform: scale(.85); pointer-events: none;
  transition: opacity .3s var(--ease), transform .3s var(--ease); }
.gallery__item--zoom:hover::after,
.gallery__item--zoom:focus-within::after { opacity: 1; transform: none; }

.lb { position: fixed; inset: 0; z-index: 120; display: none;
  align-items: center; justify-content: center; padding: clamp(14px, 3vw, 48px);
  background: rgba(12,10,7,.92); backdrop-filter: blur(6px); }
.lb.is-on { display: flex; }
html.lb-open { overflow: hidden; }
.lb__ram { position: relative; max-width: min(1100px, 100%); max-height: 100%;
  display: flex; flex-direction: column; gap: 12px; }
.lb__img { max-width: 100%; max-height: calc(100vh - 150px); object-fit: contain;
  border-radius: var(--r-lg); box-shadow: 0 30px 80px rgba(0,0,0,.5); }
.lb__lista { display: flex; align-items: baseline; justify-content: space-between;
  gap: 18px; color: #E9E1D1; }
.lb__popis { font-size: .92rem; margin: 0; }
.lb__pocet { font-family: var(--f-label); font-size: .78rem; letter-spacing: .12em;
  color: var(--accent-2); white-space: nowrap; }
/* Dotykové cíle 44 px, jinak se na telefonu do šipek nedá trefit. */
.lb__zavri, .lb__sipka { position: absolute; z-index: 2; width: 46px; height: 46px;
  display: grid; place-items: center; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(244,240,231,.12); color: #F4F0E7; font-size: 1.5rem; line-height: 1;
  transition: background .25s var(--ease), transform .25s var(--ease); }
.lb__zavri:hover, .lb__sipka:hover { background: rgba(244,240,231,.24); }
.lb__zavri:focus-visible, .lb__sipka:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 3px; }
.lb__zavri { top: clamp(12px, 2vw, 26px); right: clamp(12px, 2vw, 26px); font-size: 1.9rem; }
.lb__sipka { top: 50%; transform: translateY(-50%); }
.lb__sipka--prev { left: clamp(8px, 2vw, 26px); }
.lb__sipka--next { right: clamp(8px, 2vw, 26px); }
.lb__sipka:hover { transform: translateY(-50%) scale(1.06); }
@media (max-width: 620px) {
  /* Na telefonu by šipky ležely přes fotku, tak jdou pod ni vedle počtu. */
  .lb__sipka { top: auto; bottom: 14px; transform: none; }
  .lb__sipka:hover { transform: none; }
  .lb__img { max-height: calc(100vh - 190px); }
}
@media (prefers-reduced-motion: reduce) {
  .gallery__item--zoom::after, .lb__zavri, .lb__sipka { transition: none; }
}

/* ============================================================
   FAKTA V RÁMEČKU (ceník, „Podmínky bez háčků")
   ============================================================
   Šest tvrzení jen v nadpisu, bez popisků. Prázdný rámeček s jedním řádkem
   působí nedodělaně, proto číslo bronzem: zaplní plochu a udělá z dlaždic
   výčet, který se čte odshora dolů.
   ⚠️ Mřížka je natvrdo 3 sloupce. `.grid--3` má jinak `auto-fit` s minmax,
   který na 1440 px nasadí čtyři sloupce a šest dlaždic se rozpadne na 4+2. */
.fakta { counter-reset: fakta; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.fakta .card { counter-increment: fakta; display: flex; flex-direction: column;
  justify-content: center; min-height: 124px; padding: 26px 24px; }
.fakta .card::after { content: "0" counter(fakta); order: -1; margin-bottom: 10px;
  font-family: var(--f-display); font-size: 1.5rem; line-height: 1; color: var(--accent-2); }
.fakta .card h3 { font-size: 1.16rem; line-height: 1.3; }
@media (max-width: 900px) { .fakta { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .fakta { grid-template-columns: 1fr; }
  .fakta .card { min-height: 0; padding: 20px 22px; }
  .fakta .card::after { margin-bottom: 6px; font-size: 1.3rem; } }

/* ============================================================
   RÁM KOLEM VÝZVY (.callout bez fotky)
   ============================================================
   Blok „Vyber si vstup a přijď" plaval na stránce bez ohraničení, protože rám
   měla jen fotková varianta. Dvojitá linka je editorial vzor: vnější neutrální
   drží tvar, vnitřní bronzová odsazená o 10 px dělá ten „rámeček".
   ⚠️ `::before` je obsazený bronzovou září, proto rám kreslí `::after`.
   ⚠️ Musí to být `inset` stín, ne `border` — border by přidal 2 px k šířce
   a na 390 px by blok vyčníval.
   Platí na ceníku, „O nás" a čtyřech profilech lektorů, ať vypadají stejně. */
.callout:not(.callout--vyrazna) { background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line); }
.callout:not(.callout--vyrazna)::after { content: ""; position: absolute; inset: 10px;
  z-index: 0; pointer-events: none; border-radius: calc(var(--r-xl) - 8px);
  box-shadow: inset 0 0 0 1px var(--accent-line); }
/* Na espressu je neutrální linka neviditelná, tak ji nese bronz. */
.callout.invert:not(.callout--vyrazna) { background: var(--text);
  box-shadow: inset 0 0 0 1px rgba(194,168,120,.22); }
@media (max-width: 560px) {
  .callout:not(.callout--vyrazna)::after { inset: 7px; border-radius: calc(var(--r-xl) - 6px); }
}

/* ============================================================
   RYTMUS HLAVIČEK SEKCÍ
   ============================================================
   Změřeno 25. 8. 2026: úvodní stránka má PĚT sekcí za sebou s identickým
   schématem nadpisek → titulek → lead → mřížka karet, dohromady 5 749 px,
   tedy víc než polovinu všeho pod herem. Odtud pochází „je to všechno stejné".
   Řeší se to v hlavičce, ne v kartách, takže vrácení je smazání tohohle bloku.

   ⚠️ ČÍSLOVÁNÍ JEN NA ÚVODNÍ STRÁNCE. `.section__head` je i na podstránkách,
   kde má jedna stránka dvě sekce a „01 / 02" by nedávalo smysl. Rytmus se
   navíc řeší tam, kde byl změřený problém.
   ⚠️ Dva sloupce jen tam, kde je co dát do druhého. `:has(.section__lead)`
   ošetří sekce bez leadu, jinak by zůstal poloviční sloupec prázdný. */
body[data-page="home"] main { counter-reset: sek; }
body[data-page="home"] .section__head { counter-increment: sek; }
body[data-page="home"] .section__head .eyebrow::after {
  content: counter(sek, decimal-leading-zero);
  font-family: var(--f-display); font-size: 1.05rem; letter-spacing: 0;
  color: var(--accent-2); margin-left: .55em; }

/* Bronzová linka pod titulkem sekce. Drží hlavičku pohromadě a dělá z ní
   předěl, ne jen tři odstavce pod sebou. */
.section__head .section__title { padding-bottom: 16px;
  border-bottom: 1px solid var(--accent-line); }

@media (min-width: 1000px) {
  /* 🔴 STROP 720 px SE MUSEL ZRUŠIT. Základ `.section__head` má `max-width: 720px`
     a do něj se ve dvou sloupcích mačkal titulek i lead: na `/rozvrh/` zbylo na
     lead 309 px, tedy 17 řádků po třech slovech, a vypadalo to rozbitě.
     Bez stropu má hlavička celý `.wrap` (1180 px) a lead 585 px, tedy 8 řádků. */
  .section__head:has(.section__lead) { max-width: none; display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: clamp(40px, 6vw, 90px); align-items: end; }
  .section__head:has(.section__lead) .eyebrow { grid-column: 1 / -1; }
  .section__head:has(.section__lead) .section__title { margin: 14px 0 0; }
  /* Přes ~46 znaků na řádek se souvislý text čte hůř, i když je místa dost. */
  .section__head:has(.section__lead) .section__lead { margin: 0 0 6px; max-width: 46ch;
    padding-left: clamp(30px, 4vw, 60px); border-left: 1px solid var(--line);
    align-self: end; }
  /* ⚠️ UVNITŘ `.ldx` ZŮSTÁVÁ HLAVIČKA JEDNOSLOUPCOVÁ. `.ldx` je samo dvousloupcové
     (text 486 px + fotka), takže dělit ten sloupec ještě jednou znamená lead
     o 195 px: na `/o-nas/` z toho bylo 26 řádků po třech slovech. Týká se
     `/o-nas/`, `/lekce/funkcni-trenink/` a `/lekce/movekids/`. */
  .ldx > .section__head:has(.section__lead) { display: block; }
  .ldx > .section__head:has(.section__lead) .section__lead { max-width: none;
    margin-top: 20px; padding-left: 0; border-left: 0; }
  /* Vycentrovaná hlavička (ceník) na dva sloupce nejde, tam by se rozpadla. */
  .section__head:has(.eyebrow--center) { display: block; }
  .section__head:has(.eyebrow--center) .section__title { border-bottom: 0; padding-bottom: 0; }
  /* 🔴 `display: block` NESTAČÍ. Pravidlo pro dvousloupcovou hlavičku o pár řádků
     výš dává leadu `max-width: 46ch`, `padding-left` a `border-left`, a ty se
     resetem rozložení neruší. Vycentrovaná hlavička tím dostala titulek na ose
     stránky a odstavec o 225 px vlevo, k tomu svislou čárku, která tam patřila
     jen jako dělítko dvou sloupců. Naměřeno 29. 8. 2026 na 1440 px: titulek
     střed 720, lead střed 495, obal střed 720. Šířku odstavce si necháváme
     (souvislý text se přes ~46 znaků čte hůř), jen se vycentruje.
     ⚠️ A horní mezeru taky. Dvousloupcové pravidlo dává leadu `margin: 0 0 6px`,
     protože tam stojí VEDLE titulku a zarovnává se k jeho patce. Pod titulkem
     z toho byla mezera 0 px a odstavec se lepil na dotažnice. Zpátky na
     základních 20 px. */
  .section__head:has(.eyebrow--center) .section__lead { margin: 20px auto 0;
    padding-left: 0; border-left: 0; }
}

/* ============================================================
   TABULKA VOLNÝCH MÍST NA TELEFONU — MUSÍ ZŮSTAT NA KONCI SOUBORU
   ============================================================
   ⚠️ Přepisuje `.avail thead th`, `.avail__pill` a `.avail__go`, jejichž
   základní pravidla jsou rozeseta po celém souboru (poslední až u klikacího
   řádku o osm set řádků níž). Se stejnou specifičností vyhrává to pozdější,
   takže když tenhle blok neleží úplně na konci, tiše přestane platit —
   tabulka se pak měří jako v pořádku a přitom vypadá rozbitě. */
/* Na telefonu se tabulka MUSÍ vejít bez posunu do strany. Dřív tu stálo, že se
   vejde, a nevešla se: `min-width: 0` nepomůže, dokud mají buňky `nowrap` —
   vnitřní šířka textu je pak stejně větší než okno. Naměřeno 94 px přetoku na
   MOVEKIDS a 93 px na funkčním (390 px) a poslední sloupec byl vidět 0 px.
   `table-layout: fixed` je jediné řešení, u kterého přetok ze šířky textu
   VZNIKNOUT NEMŮŽE: sloupce dostanou procenta a obsah se láme.
   ⚠️ Čas musí zůstat nezalomený, jinak se „15:30–16:25" rozpadne na dva řádky.
   ⚠️ Štítek obsazenosti i šipka se musí zúžit s tím — `inline-flex` s vlastním
   odsazením se do procentního sloupce jinak nevejde a přeteče přes jeho okraj.
   🔴 A NEPOUŽÍVAT `overflow-wrap: anywhere`. Přetok tím zmizí, ale slova se
   lámou uprostřed: v hlavičce „OBSAZEN/OST" a v buňce „MOVEKI/DS 7–12 let".
   Měření pak hlásí čistotu a tabulka vypadá rozbitě. Procenta níž jsou
   doměřená tak, aby se nejdelší SLOVO vešlo celé (`scratchpad/ladeni-tabulky.mjs`):
   0 px přetoku a 0 přetečených buněk na všech třech kurzech ve 320 i 390 px. */
@media (max-width: 620px) {
  .avail table { min-width: 0; table-layout: fixed; width: 100%; }
  .avail th, .avail td { padding: 10px 5px; font-size: .78rem;
    white-space: normal; overflow-wrap: normal; word-break: normal; }
  .avail thead th { font-size: .64rem; letter-spacing: .04em; }
  .avail__pill { padding: 4px 7px; font-size: .70rem; }
  .avail__go { padding: 4px 2px; }
  /* U obsazeného termínu píše app.js „Obsazeno" i do posledního sloupce, kde je
     jinak jen šipka. Na šířku telefonu je to duplikát vedlejšího sloupce a
     stálo přesně těch 39 px, o které tabulka přetékala. */
  .avail__goc .avail__off { display: none; }
  .avail th:nth-child(1), .avail td:nth-child(1) { width: 18%; }
  .avail th:nth-child(2), .avail td:nth-child(2) { width: 28%; white-space: nowrap; }
  .avail th:nth-child(3), .avail td:nth-child(3) { width: 21%; }
  .avail th:nth-child(4), .avail td:nth-child(4) { width: 23%; }
  .avail th:nth-child(5), .avail td:nth-child(5) { width: 10%; }
}
/* Pod 375 px (iPhone SE a spol.) chybí posledním sloupcům pár pixelů, tak jde
   celá tabulka o stupeň dolů. Na 390 px se to zapínat NESMÍ, tam je písmo .78rem
   čitelné a měřením se vejde.
   Hlavička ztrácí i prostrkání — „OBSAZENOST" je nejdelší slovo v tabulce a
   .04em na deseti znacích dělá skoro 3 px, přesně ty, co chyběly. */
@media (max-width: 375px) {
  .avail th, .avail td { padding: 9px 2px; font-size: .68rem; }
  .avail thead th { font-size: .52rem; letter-spacing: 0; }
  .avail__pill { padding: 3px 5px; font-size: .64rem; }
}

/* ============================================================
   NEJBLIŽŠÍ LEKCE — živý pruh z rozvrhu (27. 8. 2026)
   ============================================================
   Jediné místo na úvodní stránce se skutečnými daty z rezervačního
   systému. Vykresluje `script.js` z `/api/schedule`.

   🔴 PROČ TMAVÝ PODKLAD: z dvanácti sekcí úvodní stránky byla tmavá
   jediná (recenze, dole) a pět mřížek karet za sebou zabíralo 47,6 %
   výšky. Změřeno, ne odhadnuto — `scratchpad/rytmus.mjs`. Espresso
   uprostřed stránky je proto hlavní důvod, proč tenhle pruh vůbec
   rozbije rytmus. `.invert` jen překlopí tokeny, žádná barva se nepíše
   natvrdo.

   ⚠️ Řádek je `<a>`, ne buňka tabulky. Roztažený překryv přes `<tr>` je
   v tomhle projektu zapsaná past (přeloží se přes sebe a klikací zůstane
   poslední řádek). Tady je odkazem celý řádek sám, takže past nevzniká. */
.dnes { background: var(--bg); color: var(--text);
  border-radius: var(--r-xl); padding: clamp(26px, 3.2vw, 42px) clamp(20px, 3vw, 44px); }
.dnes[hidden] { display: none; }
.dnes__head { display: flex; align-items: baseline; justify-content: space-between;
  gap: 14px 24px; flex-wrap: wrap; padding-bottom: 16px; border-bottom: 1px solid var(--line-2); }
.dnes__title { font-family: var(--f-display); font-weight: 500;
  font-size: clamp(1.4rem, 2.3vw, 1.95rem); line-height: 1.15; }
.dnes__all { position: relative; font-family: var(--f-label); font-size: .78rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent-2); text-decoration: none;
  display: inline-flex; align-items: center; gap: .5em; transition: gap .3s var(--ease); }
.dnes__all:hover { gap: .85em; }
/* Dotykový cíl 44 px. Samotný text měří 21 px a mobilní audit to našel.
   ⚠️ Pseudo-prvek se roztahuje JEN NA VÝŠKU. Kdyby dostal `left/right: -10px`,
   začne prvek hlásit `scrollWidth > clientWidth`, tedy přesně tu vadu, kterou
   si u sebe hlídáme. A musí být `absolute`: rodič je `inline-flex` s `gap`,
   takže jinak by se z pseudo-prvku stala položka mřížky a odsunula by šipku. */
.dnes__all::after { content: ""; position: absolute; left: 0; right: 0;
  top: 50%; transform: translateY(-50%); height: 44px; }

.dnes__list { display: flex; flex-direction: column; }
.dnes__row { display: grid; grid-template-columns: 5.6rem 1fr auto; align-items: center;
  gap: 4px 22px; padding: 15px 2px; border-bottom: 1px solid var(--line);
  color: inherit; text-decoration: none; }
.dnes__row:last-child { border-bottom: none; }
.dnes__kdy { display: flex; flex-direction: column; gap: 2px; }
.dnes__den { font-family: var(--f-label); font-size: .64rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted-2); }
.dnes__cas { font-family: var(--f-display); font-size: 1.35rem; line-height: 1;
  color: var(--accent-2); font-variant-numeric: tabular-nums; }
.dnes__co { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.dnes__nazev { font-family: var(--f-display); font-weight: 600; font-size: 1.08rem;
  transition: color .3s var(--ease); }
.dnes__kdo { color: var(--muted); font-size: .88rem; }
.dnes__row:hover .dnes__nazev, .dnes__row:focus-visible .dnes__nazev { color: var(--accent-2); }
.dnes__row:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 3px; border-radius: 6px; }

.dnes__stav { font-family: var(--f-label); font-size: .64rem; letter-spacing: .1em;
  text-transform: uppercase; padding: 6px 11px; border-radius: 999px; white-space: nowrap; }
.dnes__stav--volno { background: var(--accent-soft); color: var(--accent-2);
  box-shadow: inset 0 0 0 1px var(--accent-line); }
.dnes__stav--plno  { color: var(--muted-2); box-shadow: inset 0 0 0 1px var(--line-2); }
.dnes__stav--kurz  { color: var(--muted); box-shadow: inset 0 0 0 1px var(--line-2); }

/* Na telefonu se štítek přesune pod název, jinak by se na 320 px
   ukrojila delší jména lekcí („Pilates Reformer"). */
@media (max-width: 560px) {
  .dnes { padding: 22px 18px; }
  .dnes__row { grid-template-columns: 4.6rem 1fr; padding: 13px 0; }
  .dnes__stav { grid-column: 2; justify-self: start; margin-top: 2px; }
  .dnes__cas { font-size: 1.2rem; }
}

/* ============================================================
   PRVNÍ NÁVŠTĚVA — tři kroky
   ============================================================
   🔴 ZÁMĚRNĚ TO NENÍ MŘÍŽKA KARET. Na úvodní stránce jich jde pět za
   sebou (Proč, Lekce, Ceník, Lektoři, Galerie) a dohromady zabírají
   47,6 % její výšky, takže šestá by ji zhoršila, i kdyby byla hezká.
   Krok proto nemá rám ani podklad, nese ho velká serifová číslice
   a vlasová linka nad ní. */
.kroky { list-style: none; display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(26px, 3.6vw, 48px); margin-top: clamp(30px, 3.6vw, 46px); }
.kroky__k { position: relative; padding-top: 22px; }
.kroky__k::before { content: ""; position: absolute; top: 0; left: 0; right: 0;
  height: 1px; background: var(--line-2); }
.kroky__c { display: block; font-family: var(--f-display); font-weight: 500;
  font-size: clamp(2.4rem, 4.2vw, 3.4rem); line-height: 1; color: var(--accent-2); }
.kroky__t { font-family: var(--f-display); font-weight: 600; font-size: 1.2rem;
  margin-top: 12px; text-wrap: balance; }
.kroky__p { color: var(--muted); margin-top: 8px; max-width: 36ch; }

@media (max-width: 860px) { .kroky { grid-template-columns: 1fr; gap: 28px; } }

/* ============================================================
   SJEDNOCENÍ FOTEK ZÁVOJEM — VYZKOUŠENO A VRÁCENO (27. 8. 2026)
   ============================================================
   Byl tu `--foto-zavoj: saturate(.85) sepia(.14) contrast(1.03)
   brightness(1.02)` přes galerii, karty lekcí, detaily a portréty.
   Jakub ho po nasazení vrátil: „vrať to do původních barev."
   NEVRACET bez jeho pokynu.

   Co z toho měření zůstává v platnosti (`scratchpad/fotky-barvy.mjs`):
   fotky nejsou špatným směrem, průměr b* je +12,5, tedy teplé, což
   k ivory a bronzu sedí. Rozcházejí se v ROZPTYLU: teplota má rozpětí
   27 bodů, jas 43 bodů. Závoj stáhl rozptyl teploty z ±6,9 na ±5,4,
   ale **na jas neplatil vůbec** a sjednocení se stejně dělá jinde:
   srovnáním jednotlivých souborů, ne stylem.
   ============================================================ */

/* ============================================================
   PLOCHA POD STATUS BAREM: LIŠTA MUSÍ BÝT NEPRŮHLEDNÁ (28. 8. 2026)
   ============================================================
   Jakub poslal snímek z iPhonu s odrolovanou úvodní stránkou: nad ivory
   lištou seděl šedý pruh, který s ní vůbec neladil, a při scrollu se měnil.

   Změřeno přímo z jeho snímku (1206×2622, tedy 402×874 při 3×,
   `scratchpad/pruh.mjs`):
     • y 0–184 px  = 62 px CSS, přesně `env(safe-area-inset-top)`:
       gradient od #d4d0c7 po #656057
     • y 186–384 px = 66 px, tedy `--nav-h` na telefonu: stabilní #d7d2c8
     • šev mezi nimi: rozdíl 117 stupňů v každém kanálu, přes celou šířku

   Navazuje to na nález z 27. 8. výš v souboru: Safari 26 nečte `theme-color`
   a plochu pod status barem si obarvuje samo z `background-color` prvku
   s `position: fixed` u okraje. Tehdy byla `.nav` bez pozadí a vyšel ivory
   pruh nad tmavým herem; opravilo se to plnou barvou na `.nav:not(.scrolled)`.
   `.nav.scrolled` ale zůstala POLOPRŮHLEDNÁ (`rgba(244,240,231,.82)`
   + `backdrop-filter`), takže na ni Safari nesáhne a místo barvy si vykreslí
   rozostřený obraz obsahu, který pod lištou projíždí — tedy hero fotku.
   Proto ten gradient a proto se mění se scrollem.

   ➡️ Na telefonu je lišta plná. Nad ivory sekcemi (což je většina webu) je to
   vizuálně shodné: 0,82 ivory přes ivory dává zpátky ivory. Rozdíl je vidět
   jen tam, kde pod lištou leží fotka — a přesně tam ten šev vznikal.
   Na počítači se nemění nic, tam žádná plocha pod status barem není.

   ⚠️ Musí to být `background-color` PŘÍMO na `.nav` a NEPRŮHLEDNÁ. Safari
   nevzorkuje pseudo-prvky, absolutně pozicované potomky ani `background-image`,
   a přes alfu propadne níž.
   ⚠️ `var(--bg)` tu funguje pro obojí: na veřejném webu je z `:root` ivory,
   v členské sekci z `body[data-app]` espresso #1A1710 — tedy přesně ta barva,
   kterou tam měl `rgba(26,23,16,.86)`, jen bez průhlednosti. Členská sekce
   měla tutéž vadu, jen ji nikdo nevyfotil.
   ============================================================ */
@media (max-width: 720px) {
  .nav.scrolled,
  body[data-app] .nav.scrolled {
    background-color: var(--bg);
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
}
