/* ==========================================================================
   Boost Růst — administrace
   ==========================================================================
   Nástroj, ne prezentace: systémové písmo, husté řádky, žádné animace, které
   by zdržovaly. Barvy se drží webu, aby bylo poznat, čí administrace to je,
   ale rozvržení je vlastní — sloupec s rozcestníkem vlevo, obsah vpravo.  */

:root {
  --ink:      #2a2320;
  --ink-soft: #4a3f39;
  --muted:    #857468;
  --line:     #e6dbd1;
  --line-soft:#f0e8e1;
  --bg:       #fbf6f1;
  --card:     #fff;
  /* Nativní ovladače (zaškrtávátko, výběr dne v kalendáři) se tím obarví
     samy — jedna vlastnost místo překreslování prohlížečových widgetů. */
  accent-color: #ee8c46;
  --accent:   #ee8c46;
  --accent-d: #d9722c;
  --ok:       #2e7d52;
  --ok-bg:    #dff0e6;
  --warn:     #9a6b16;
  --warn-bg:  #fbeed3;
  --danger:   #c0392b;
  --danger-bg:#f9e2df;
  --r:        14px;
  --shadow:   0 1px 2px rgba(42, 35, 32, .05), 0 8px 24px rgba(42, 35, 32, .06);
  /* Účes accentu na plochy: štítek kategorie, aktivní filtr, počet u něj. */
  --accent-sk:#fce6d3;
  --accent-ln:#f3c79c;
  /* Výška horní lišty je daná, ne dopočítaná — lepí se pod ni filtry
     a o pixel vedle by byla vidět škvíra. */
  --topbar-h: 64px;
  /* Výška políčka: řádek textu (.92rem × 1.55) plus odsazení a rámeček z
     `.field input` níž. Tlačítka, která mají stát vedle políčka v jedné
     řadě, si ji berou odsud — psát jim podobná čísla podruhé znamená, že
     se při první změně odsazení rozejdou. */
  --field-h: calc(.92rem * 1.55 + 18px);
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 15px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -.01em; }
a { color: inherit; }
[hidden] { display: none !important; }

/* ---------- přihlášení ---------------------------------------------------- */
#gate { display: grid; place-items: center; min-height: 100%; padding: 24px; }
.gate-card {
  width: 100%; max-width: 380px; background: var(--card); padding: 32px;
  border: 1px solid var(--line); border-radius: 20px; box-shadow: var(--shadow);
}
.gate-brand { display: block; height: 56px; width: auto; margin: 0 0 22px; }
.gate-card h1 { font-size: 1.4rem; }
.gate-sub { color: var(--muted); font-size: .9rem; margin: 6px 0 22px; }
.gate-alt { margin-top: 22px; border-top: 1px solid var(--line-soft); padding-top: 16px; }
.gate-alt summary { cursor: pointer; font-size: .85rem; color: var(--muted); }
.gate-note { text-align: center; margin: 18px 0 0; }

/* ---------- kostra -------------------------------------------------------- */
#app { display: grid; grid-template-columns: 232px 1fr; min-height: 100%; }

.sidebar {
  background: var(--card); border-right: 1px solid var(--line);
  padding: 22px 16px; display: flex; flex-direction: column; gap: 26px;
  position: sticky; top: 0; height: 100vh;
}
.sidebar-brand { display: block; height: 42px; width: auto; margin: 0 10px; }
#tabs { display: flex; flex-direction: column; gap: 2px; }
#tabs button {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  font: inherit; font-size: .92rem; color: var(--ink-soft); cursor: pointer;
  background: transparent; border: 0; border-radius: 10px; padding: 9px 11px;
}
#tabs button i { font-style: normal; width: 16px; text-align: center; opacity: .55; font-size: .8rem; }
#tabs button:hover { background: var(--bg); }
#tabs button.active { background: var(--ink); color: #fff; font-weight: 600; }
#tabs button.active i { opacity: .8; }
.sidebar-foot { margin-top: auto; display: flex; flex-direction: column; gap: 8px; padding: 0 11px; font-size: .85rem; }
.sidebar-foot a, .linky {
  color: var(--muted); text-decoration: none; font: inherit; background: 0;
  border: 0; padding: 0; text-align: left; cursor: pointer;
}
.sidebar-foot a:hover, .linky:hover { color: var(--ink); }

main { min-width: 0; display: flex; flex-direction: column; }
.topbar {
  position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 14px;
  height: var(--topbar-h); padding: 0 28px; background: rgba(251, 246, 241, .92);
  backdrop-filter: blur(8px); border-bottom: 1px solid var(--line);
}
.topbar h1 { font-size: 1.15rem; flex: 1; }
.topbar-right { display: flex; align-items: center; gap: 12px; }
.whoami { font-size: .82rem; color: var(--muted); }
.menu-btn { display: none; font: inherit; font-size: 1.2rem; background: 0; border: 0; cursor: pointer; }
/* Na šířku obsahu, ne na šířku odstavce. Administrace je nástroj: seznam
   akcí, tabulka objednávek ani dva sloupce na obrazovce akce nemají důvod
   končit v půlce monitoru a nechat vedle sebe pruh prázdna. Strop je až tam,
   kde by řádek přestal být čitelný. */
.view { padding: 24px 28px 80px; max-width: 1720px; width: 100%; flex: 1 1 auto; min-width: 0; }
/* Plocha = obsah a vedle něj náhled (viz „náhled vedle obsahu" níž). Strop
   šířky drží obsah; s otevřeným náhledem padá, protože pruh prázdna vedle
   něj by byl zrovna to místo, které má náhled zabrat. */
.workspace { display: flex; align-items: flex-start; flex: 1 1 auto; min-width: 0; }
.workspace.has-preview .view { max-width: none; }

/* ---------- prvky --------------------------------------------------------- */
.card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  padding: 18px 20px; margin-bottom: 14px;
}
.card.off { opacity: .6; }
.card > h3 { font-size: 1rem; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.card .sub { color: var(--muted); font-size: .84rem; margin: 3px 0 0; }
.card-head { display: flex; align-items: flex-start; gap: 14px; }
.card-head .grow { flex: 1; min-width: 0; }
.card-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.btn {
  font: inherit; font-size: .88rem; font-weight: 600; cursor: pointer; white-space: nowrap;
  padding: 8px 14px; border-radius: 9px; border: 1px solid var(--line);
  background: var(--card); color: var(--ink-soft);
}
.btn:hover { border-color: var(--muted); }
.btn.primary { background: var(--ink); border-color: var(--ink); color: #fff; }
.btn.primary:hover { background: #1b1613; }
.btn.accent { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.accent:hover { background: var(--accent-d); border-color: var(--accent-d); }
.btn.danger { color: var(--danger); border-color: #e8c8c3; }
.btn.danger:hover { background: var(--danger-bg); border-color: var(--danger); }
.btn.small { padding: 6px 11px; font-size: .82rem; }
.btn.block { display: block; width: 100%; margin-top: 6px; }
.btn:disabled { opacity: .45; cursor: default; }

.field { display: flex; flex-direction: column; gap: 5px; font-size: .78rem; font-weight: 600; color: var(--muted); margin-bottom: 12px; }
.field input, .field textarea, .field select {
  font: inherit; font-size: .92rem; font-weight: 400; color: var(--ink);
  padding: 8px 11px; border: 1px solid var(--line); border-radius: 9px; width: 100%;
  /* `background-color`, ne zkratka `background`: ta maže i obrázek na pozadí,
     kterým je kreslená šipka výběru (níž). */
  background-color: #fff;
}
.field textarea { min-height: 84px; resize: vertical; line-height: 1.5; }
.field input:focus, .field textarea:focus, .field select:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent; }
.field input:hover, .field select:hover, .mini-field input:hover, .mini-field select:hover {
  border-color: var(--accent-ln);
}
.field .hint { font-weight: 400; font-size: .76rem; color: var(--muted); }

/* Kalendářová ikonka v poli s datem. Nativní je drobná a šedivá; tohle jí dá
   velikost, na kterou se dá trefit, a barvu, která patří k webu. */
.field input[type=date]::-webkit-calendar-picker-indicator,
.mini-field input[type=date]::-webkit-calendar-picker-indicator,
.lesson input[type=date]::-webkit-calendar-picker-indicator {
  width: 17px; height: 17px; padding: 2px; margin-left: 4px;
  border-radius: 5px; cursor: pointer; opacity: .55;
}
.field input[type=date]::-webkit-calendar-picker-indicator:hover,
.mini-field input[type=date]::-webkit-calendar-picker-indicator:hover,
.lesson input[type=date]::-webkit-calendar-picker-indicator:hover {
  opacity: 1; background: var(--accent-sk);
}
.field input[type=date], .mini-field input[type=date], .lesson input[type=date] {
  font-variant-numeric: tabular-nums;
}

/* Číselník u čísla je past: šipka o jedno nahoru u ceny nikomu nepomůže
   a kolečkem myši se přes něj dá cena přepsat omylem. */
.field input[type=number], .mini-field input[type=number] { -moz-appearance: textfield; }
.field input[type=number]::-webkit-outer-spin-button,
.field input[type=number]::-webkit-inner-spin-button,
.mini-field input[type=number]::-webkit-outer-spin-button,
.mini-field input[type=number]::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}

/* Jednotka uvnitř pole („690 Kč"). */
.input-wrap { position: relative; display: block; }
.input-wrap input { padding-right: 42px; }
.input-suffix {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  font-style: normal; font-size: .88rem; font-weight: 600; color: var(--muted);
  pointer-events: none;
}

/* Zaškrtávátko: čtvereček, popisek na řádek a vysvětlivka pod něj. Dřív
   stálo všechno v jedné řadě, takže se popisek lámal uprostřed slova
   a vedle něj běžela věta, která k němu patří. */
.field.check {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start;
  gap: 4px 10px; font-size: .88rem; color: var(--ink-soft); cursor: pointer;
  padding: 9px 11px; border: 1px solid var(--line-soft); border-radius: 10px;
  background: var(--bg);
}
.field.check:hover { border-color: var(--accent-ln); }
.check-body { display: grid; gap: 2px; }
.check-label { font-weight: 700; }
.field.check .hint { font-size: .78rem; }
/* Výběr barvy na celou šířku vypadá jako prázdný řádek — vzorek má být
   velký tak, aby se v něm ta barva dala poznat, a ne o nic víc. */
.field input[type=color] { width: 64px; height: 34px; padding: 3px; cursor: pointer; }
/* Seznam po řádcích místo textového pole se syntaxí — viz fieldHtml().
   Popisek a hodnota mají různou šířku schválně: popisek je „Forma“ nebo
   „Kapacita“, hodnota bývá delší věta. */
.rowset-list { display: flex; flex-direction: column; gap: 6px; }
/* Řádek seznamu se smí zalomit: ve dvou sloupcích je na tři pole vedle sebe
   (typ + vlastní název + hodnota) málo místa a stlačená by z nich byla
   políčka po pěti znacích.

   Zarovnává se k hornímu okraji, ne na střed: buňka s typem údaje je při
   volbě „vlastní…“ o řádek vyšší a hodnota s křížkem se pak odsunuly
   doprostřed té výšky — vedle prázdna, ke kterému nepatří. */
.rowset-row { display: flex; gap: 6px; align-items: flex-start; flex-wrap: wrap; }
/* Základ 0, ne `auto`. Políčka mají `width: 100 %`, takže z `auto` vycházel
   základ přes celou šířku řádku — křížek se do zbytku nevešel a spadl pod
   ně na vlastní řádek. Dvojice (popisek + hodnota) si svůj poměr nastavují
   níž a tenhle zápis přebíjejí. */
.rowset-row input, .rowset-row textarea { flex: 1 1 0; min-width: 0; }
.rowset-row textarea { min-height: 0; }
.rowset[data-pairs] .rowset-row input[data-row-a] { flex: 1 1 34%; min-width: 130px; }
/* Křížek je přesně tak vysoký jako políčko vedle něj. Výšku si bere ze
   sdílené proměnné, ne z odsazení opsaného podle inputu: znak se do ní
   vystředí sám, takže jde zvětšit, aniž by se tím výšky rozešly. */
.rowset-row [data-row-del] {
  flex: none; width: 34px; height: var(--field-h); padding: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.05rem; line-height: 1; border-radius: 9px;
}
/* Odstavec je textarea — vysoká dvě řady a navíc roztažitelná za roh, takže
   žádná pevná výška vedle ní nesedí. Křížek se proto protáhne přes celou
   její výšku a stane se z něj úzký proužek na kraji odstavce: patří k němu
   celému, ne k jeho prvnímu řádku.

   Znak přesto drží nahoře, v ose s prvním řádkem textu — uprostřed
   roztaženého pole by se vznášel bez vztahu k čemukoliv. A dokud na něj
   nikdo nemíří, je proužek jen tichá linka; červený je až pod myší, aby
   vedle rozepsaného textu nesvítilo tlačítko na mazání. */
.rowset-row.tall [data-row-del] {
  height: auto; align-self: stretch;
  align-items: flex-start; padding-top: 11px;
  background: transparent; border-color: var(--line-soft); color: var(--muted);
}
.rowset-row.tall [data-row-del]:hover {
  background: var(--danger-bg); border-color: var(--danger); color: var(--danger);
}
.rowset > [data-row-add] { align-self: flex-start; margin-top: 7px; }

/* Několik možností z pevného seznamu. Dvě řady zaškrtávátek se přehlédnou
   hůř než seznam řádků, do kterých se psalo volným textem — a hlavně se
   z nich nedá vyrobit hodnota, kterou web nezná. */
.checks-list { display: grid; grid-template-columns: 1fr 1fr; gap: 7px 14px; margin-top: 2px; }
.check-item {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  font-weight: 400; font-size: .86rem; color: var(--ink-soft);
}
.check-item input { width: auto; flex: none; }

/* Zaškrtávátko kreslené, ne systémové — jedno pro obě místa, kde je
   (`.field.check` u samostatné volby, `.check-item` v mřížce kategorií).
   Systémové je v každém prohlížeči jiné a v poli s ručně kreslenými rámečky
   vypadalo jako kus cizí aplikace. */
.field.check input, .check-item input {
  appearance: none; -webkit-appearance: none;
  width: 19px; height: 19px; margin: 1px 0 0; padding: 0; flex: none;
  border: 1.5px solid var(--line); border-radius: 6px;
  background-color: #fff; cursor: pointer;
}
.field.check input:checked, .check-item input:checked {
  background-color: var(--accent); border-color: var(--accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; background-size: 12px;
}
.field.check input:hover, .check-item input:hover { border-color: var(--accent-ln); }
.field.check input:focus-visible, .check-item input:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.check-item input { margin-top: 0; }

/* Mezititulek ve formuláři. Odděluje skupiny polí, aby okno nebylo stěna. */
.form-legend {
  font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin: 22px 0 10px; padding-bottom: 7px;
  border-bottom: 1px solid var(--line-soft);
}
.form-legend:first-child { margin-top: 0; }

/* Výběr s možností napsat vlastní hodnotu. */
.field.choice select + [data-choice-custom] { margin-top: 6px; }

/* Přepínač místo čísla s vysvětlivkou. */
.seg { display: inline-flex; padding: 3px; gap: 3px; background: var(--bg); border: 1px solid var(--line); border-radius: 10px; }
.seg button {
  font: inherit; font-size: .86rem; font-weight: 600; cursor: pointer;
  padding: 6px 14px; border: 0; border-radius: 7px; background: transparent; color: var(--muted);
}
.seg button:hover { color: var(--ink); }
.seg button.on { background: var(--card); color: var(--ink); box-shadow: 0 1px 2px rgba(42,35,32,.12); }

/* Popisek faktu je select, hodnota input — select nesmí zabrat celou šířku. */
/* Typ údaje a jeho hodnota jsou dvě buňky řádku, ne tři. Políčko na vlastní
   název proto leží **v té první** — pod výběrem —, jinak by řádek při volbě
   „vlastní…" přetekl do druhé řady a hodnota by se octla pod popiskem.

   Slepené na sebe schválně: dvě volně stojící políčka pod sebou vypadají
   jako dva různé údaje, i když se obě ptají na jednu věc — jak se ten údaj
   jmenuje. Spojený rámeček z nich udělá jeden ovladač. */
.rowset-key { flex: 1 1 34%; min-width: 130px; display: grid; }
.rowset-key select, .rowset-key input { width: 100%; }
.rowset-key.is-custom select { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.rowset-key.is-custom input {
  border-top-left-radius: 0; border-top-right-radius: 0; margin-top: -1px;
}
.rowset-key.is-custom select:focus, .rowset-key.is-custom input:focus { position: relative; z-index: 1; }
.rowset-row [data-row-b] { flex: 1 1 40%; min-width: 150px; }
/* Ve středně úzkém poli se obě hodnoty ještě vejdou vedle sebe, ale křížek
   už ne. První hodnota se proto přesune nad druhou; křížek zůstane u ní. */
.rowset[data-pairs] { container-type: inline-size; }
@container (max-width: 325px) {
  .rowset[data-pairs] .rowset-row > input[data-row-a],
  .rowset[data-pairs] .rowset-row > .rowset-key { flex-basis: 100%; }
}

/* ---------- seznam akcí -----------------------------------------------------
   Jeden řádek na akci. Nese to, co se hledá očima — název, čím ta akce je,
   kategorii, cenu a kdy běží. Všechno ostatní je o klik dál, na vlastní
   obrazovce akce; dřív se tu rozbalovaly tabulky termínů a seznam se v tom
   ztrácel. */
.item {
  display: flex; align-items: center; gap: 10px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r); margin-bottom: 8px; padding: 4px 14px 4px 6px;
}
.item.off { opacity: .62; }
.item-open {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 11px;
  text-align: left; font: inherit; color: inherit; cursor: pointer;
  background: transparent; border: 0; border-radius: 10px; padding: 9px 8px;
}
.item-open:hover { background: var(--bg); }
.item-open:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.item-dot { flex: none; width: 10px; height: 10px; border-radius: 50%; }
.item-text { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.item-name {
  font-size: .95rem; font-weight: 700; display: flex; align-items: center;
  gap: 7px; flex-wrap: wrap;
}
/* Popis se nezalamuje: řádek musí mít pořád stejnou výšku, jinak seznam
   při každém filtru nadskakuje. Co se nevejde, si člověk otevře. */
.item-meta {
  font-size: .82rem; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Čím ta akce je. Není to volba v žádném formuláři — plyne to z počtu
   vypsaných termínů —, tak to nevypadá jako přepínač, ale jako údaj. */
.tag {
  font-size: .68rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 999px; white-space: nowrap;
  background: var(--line-soft); color: var(--muted);
}
.tag-one { background: #e4eefb; color: #2f5f9e; }
.tag-many { background: #e6f2e9; color: #2e7d52; }
.tag-none { background: var(--warn-bg); color: var(--warn); }
/* Kurz o víc lekcích — vlastní barva, protože je to jiný druh věci než
   „jednorázová" a „opakovaná": ty se liší počtem termínů, tenhle tím, že se
   prodává vcelku. */
.tag-course { background: #f1e7fb; color: #6b3fa0; }
.pill.course { background: #f1e7fb; color: #6b3fa0; }

/* ---------- obrazovka akce --------------------------------------------------
   Celá úprava jedné akce na jedné obrazovce, na celou šířku a ve dvou
   sloupcích: vlevo termíny (to, co se mění nejčastěji), vpravo text a nastavení.
   Náhled webu se sem nevejde a hlavně tu nemá být pořád — je za tlačítkem
   v liště, protože se do něj kouká jednou za čas, ne při každém psaní.

   Každý blok je `<details>`: na širokém okně jsou všechny otevřené a dají se
   zavřít, na úzkém začínají zavřené a projde se to jako seznam kapitol. */
.editor-bar {
  position: sticky; top: var(--topbar-h); z-index: 15;
  display: flex; align-items: center; gap: 12px;
  margin: -24px -28px 18px; padding: 12px 28px;
  background: rgba(251, 246, 241, .92); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
/* Cedulka „na tohle mezitím sáhl někdo jiný". Sedí nad lištou, aby se nedala
   přehlédnout, a drží se `--warn` paletou zbytku administrace: je to varování,
   ne chyba — rozepsané se nikam neztratilo. */
.stale {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: -18px -28px 18px; padding: 11px 28px;
  background: var(--warn-bg); color: var(--warn); font-size: .86rem;
}
.stale span { flex: 1; min-width: 220px; }

/* Tečka na tlačítku, když je na obrazovce něco neuloženého — ať už ve
   formuláři, nebo v rozepsaném termínu. Jedno tlačítko ukládá obojí, takže
   je to jediné místo, kde se to má ohlásit. */
.editor-bar.has-unsaved [data-save-event]::after {
  content: ""; display: inline-block; width: 7px; height: 7px; margin-left: 8px;
  border-radius: 50%; background: currentColor; vertical-align: middle;
}
.editor-bar.has-unsaved [data-save-event] { animation: nudge .5s ease; }
@keyframes nudge {
  0%, 100% { transform: none; }
  35% { transform: translateY(-1px); }
}
.editor-title { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; }
/* Dlouhý název se zkrátí tečkami. Zalomit ho nejde: v úzké liště by se
   rozpadl na jednotlivá písmena pod sebou. */
.editor-title b {
  font-size: 1.02rem; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Půl na půl to nebylo: formulář je sloupec políček, který se nad 460 px
   hůř čte, kdežto termíny jsou tabulka — a u běhu kurzu tabulka o pěti
   sloupcích a dvanácti řádcích, které se do poloviny obrazovky nevejdou
   a přetékaly ven. Formulář má proto pevnou příjemnou šířku a zbytek
   dostanou termíny. */
/* Stav akce jednou větou pod hlavičkou. Odpověď na „proč to na webu nevidím?"
   má být na očích, ne poskládaná ze tří bloků. */
.editor-state {
  display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline;
  margin: 0 0 14px; padding: 9px 14px; border-radius: 10px;
  font-size: .86rem; border: 1px solid transparent;
}
.editor-state b { font-weight: 700; }
.editor-state span { color: var(--muted); }
.editor-state.ok { background: #eef6f0; border-color: #cfe5d7; color: #2e7d52; }
.editor-state.warn { background: var(--warn-bg); border-color: #f0dcc0; color: var(--warn); }
.editor-state.warn span { color: #8a6a3c; }

/* Doplněk popisku pole („prodáno 3 z 15"). */
.mini-note { font-weight: 400; color: var(--muted); }

.editor-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px; align-items: start;
}
@media (min-width: 1101px) {
  .editor-grid { grid-template-columns: minmax(0, 440px) minmax(0, 1fr); }
}
.editor-col { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

/* Kde jsou sloupce dva, patří termíny doprava a všechny údaje akce doleva.
   V DOM je pořadí opačné (termíny první) kvůli jednomu sloupci na úzkém
   okně — proto se to řeší `order`, ne pořadím v šabloně. */
@media (min-width: 1101px) {
  .editor-col-terms { order: 2; }
}
/* Jeden sloupec čte bloky v pořadí, v jakém stojí v šabloně: termíny,
   základ, cena, text, zobrazení. Dřív tu `order` vytahoval „Text na stránce"
   nad „Základ", protože v šabloně stál až úplně poslední kvůli rozvržení
   dvou sloupců. Od chvíle, kdy se „Kdy a kde" přestěhovalo k termínům, stojí
   text tam, kde se čte, a to přeskládání by ho jen zase rozhodilo. */

/* Blok. Hlavička je zároveň přepínač, tak vypadá jako tlačítko na kliknutí —
   ale ne jako tlačítko akce: je to nadpis, který jde sbalit. */
.panel {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r); overflow: hidden;
}
/* Hlavička je pruh, ne řádek. Když měla stejný podklad jako obsah pod ní,
   splynula s formulářem a nadpisy sekcí se ztrácely mezi popisky polí.

   Odstín je vlastní, ne `--bg`: tím je i podklad stránky, takže hlavička
   v něm zmizela podruhé — jednou v obsahu, jednou v pozadí. Takhle se liší
   od obojího. */
.panel > summary {
  display: flex; align-items: baseline; gap: 10px; cursor: pointer;
  padding: 13px 18px; list-style: none; user-select: none;
  background: #f1e8de;
}
.panel > summary::-webkit-details-marker { display: none; }
.panel > summary:hover { background: #ece1d5; }
.panel > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Svislý proužek u nadpisu. Jedna čárka navíc, ale je to ta, podle které oko
   najde začátek sekce dřív, než začne číst. */
.panel-name {
  display: flex; align-items: center; gap: 9px;
  font-size: 1rem; font-weight: 700; color: var(--ink); white-space: nowrap;
}
.panel-name::before {
  content: ""; width: 3px; height: 16px; border-radius: 2px;
  background: var(--accent); flex: none;
}
.panel[open] > .panel-body { border-top: 1px solid var(--line); }

.panel-note { font-size: .82rem; color: var(--muted); flex: 1; min-width: 0; }
/* Rozbalovací šipka. Tenký úhelník ze dvou okrajů, ne plný trojúhelník:
   stejný tvar jako u výběrů a u rozvrhu lekcí, takže se všechno, co jde
   rozbalit, ohlašuje stejně. */
.panel > summary::after {
  content: ""; flex: none; margin-left: auto;
  width: 8px; height: 8px; margin-bottom: 3px;
  border-right: 1.8px solid var(--muted); border-bottom: 1.8px solid var(--muted);
  transform: rotate(45deg); transition: transform .15s;
}
.panel[open] > summary::after { transform: rotate(225deg); margin-bottom: 0; margin-top: 3px; }
.panel-body { padding: 16px 18px 18px; }
.panel-body > .field:last-child, .panel-body > .grid2:last-child { margin-bottom: 0; }
/* Uvnitř bloku je mezititulek navíc — nadpis má blok sám. */
.panel-body .form-legend:first-child { display: none; }

/* ---------- termíny ---------------------------------------------------------
   Karta na termín, ne řádek tabulky. V tabulce se pozná, co který sloupec
   znamená, jen podle záhlaví o pět řádků výš; při šesti termínech je z toho
   mřížka čtyřiadvaceti políček bez popisků. Tady má každé pole svůj popisek
   a datum je nadpis, protože podle data se termín hledá.

   Odehrané termíny se schovají do rozbalovátka: u kurzu, který běží rok, jsou
   tři čtvrtiny seznamu minulost, ve které se nic nemění. */
/* Malé popsané pole. Popisek nad polem, výška daná číslem: nativní pole na
   datum si jinak počítá vlastní a v řádku pak stojí o kus jinde než pole
   vedle a tlačítko. */
.mini-field {
  display: flex; flex-direction: column; gap: 4px;
  font-size: .74rem; font-weight: 600; color: var(--muted);
}
.mini-field input, .mini-field select {
  font: inherit; font-size: .9rem; font-weight: 400; color: var(--ink);
  height: 36px; padding: 0 11px; line-height: normal;
  border: 1px solid var(--line); border-radius: 9px; background-color: #fff;
}
.mini-field input:focus, .mini-field select:focus {
  outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent;
}
.mini-field input[type=date] { min-width: 152px; }

/* Šipka výběru kreslená, ne systémová: ta se v každém prohlížeči liší a
   v jednom sloupci s ručně kreslenými poli vypadala jako kus cizí aplikace.
   `appearance: none` ji vypne, obrázek na pozadí nakreslí vlastní — a musí
   k tomu přibýt místo vpravo, aby text nelezl pod ni. */
.field select, .mini-field select, .term-new select, .lesson-new select, .lesson-bulk select {
  appearance: none; -webkit-appearance: none;
  padding-right: 32px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%236b5f55' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 11px;
}


/* Mezititulek uvnitř bloku. Dvě patra („co platí pro všechny" a „jednotlivé
   termíny") potřebují hranici, ale ne druhý nadpis ve váze toho hlavního. */
.sub-head {
  margin: 0 0 10px; font-size: .74rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .07em; color: var(--muted);
}

/* Výchozí nastavení termínů. Sedí nad seznamem, kterého se týkají, a je
   odsazené linkou — ne rámečkem: rámeček v rámečku dělá z bloku matrjošku. */
.term-defaults { padding-bottom: 16px; margin-bottom: 16px; border-bottom: 1px solid var(--line); }
.term-defaults .field { margin-bottom: 12px; }
.term-defaults .field:last-child { margin-bottom: 0; }

/* Prázdný stav. Věta ve varovné barvě uprostřed bloku vypadala jako chyba,
   kterou někdo udělal — přitom je to jen další krok. */
.term-empty {
  border: 1px dashed var(--line); border-radius: var(--r);
  padding: 18px 20px; background: var(--bg); text-align: center;
}
.term-empty p { margin: 0; font-size: .88rem; color: var(--muted); line-height: 1.6; }
.term-empty p b { color: var(--ink); font-size: .95rem; }
.term-empty p + p { margin-top: 5px; }

.terms { display: flex; flex-direction: column; gap: 8px; }
.term {
  position: relative; background: var(--bg); border: 1px solid var(--line-soft);
  border-radius: 11px; padding: 12px 14px;
}
/* Rozepsaný řádek se pozná i bez tlačítka „Uložit" — ukládá se celá obrazovka
   jedním tlačítkem nahoře a tohle je stopa, kde se co změnilo. */
.term.is-dirty, .lesson.is-dirty {
  background: #fff8f0; border-color: var(--accent-ln);
  box-shadow: inset 3px 0 0 var(--accent);
}
.term.off { opacity: .6; }
.term-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.term-head b {
  font-size: 1.02rem; font-weight: 700; font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}
.term-dow { font-size: .78rem; color: var(--muted); }
.term-act { margin-left: auto; display: flex; gap: 6px; }
/* `align-items: end` sráží políčka na jednu linku i tam, kde je popisek
   o řádek delší („Volných míst · prodáno 3 z 15"). Bez toho se sloupce
   rozjely o výšku jednoho řádku textu. */
.term-fields {
  display: grid; grid-template-columns: 132px 1fr 1fr; gap: 8px; margin-top: 8px;
  align-items: end;
}
.term-fields .mini-field input { width: 100%; height: 34px; }
.terms-past { margin-top: 10px; }
.terms-past > summary {
  cursor: pointer; font-size: .82rem; color: var(--muted); padding: 6px 0;
  list-style: none;
}
.terms-past > summary::-webkit-details-marker { display: none; }
.terms-past > summary { display: flex; align-items: center; gap: 8px; }
.terms-past > summary::before {
  content: ""; flex: none; width: 7px; height: 7px;
  border-right: 1.6px solid var(--muted); border-bottom: 1.6px solid var(--muted);
  transform: rotate(-45deg); transition: transform .15s;
}
.terms-past[open] > summary::before { transform: rotate(45deg); }
.terms-past > summary:hover { color: var(--ink); }
.terms-past .terms { margin-top: 8px; }
/* Řádek na nový termín je součást bloku, ne další karta — má stejný podklad
   a odděluje se linkou. */
/* Vypsání termínu je vlastní krok, ne dovětek seznamu — a od dubna i jediné
   místo, kde se zakládá kurz, takže musí unést dva řádky polí. */
.term-new {
  margin-top: 16px; padding: 14px 16px;
  border: 1px solid var(--line-soft); border-radius: var(--r); background: var(--bg);
}
.term-new-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px; align-items: end;
}
.term-new-row + .term-new-row { margin-top: 10px; }
.term-new-course { padding-top: 10px; border-top: 1px dashed var(--line); }
.term-new-course .hint { grid-column: 1 / -1; margin: 0; }
.term-new > .btn { margin-top: 12px; }

/* ---------- lekce běhu ------------------------------------------------------
   Rozvrh uvnitř karty termínu: vypsané lekce z termínu dělají běh kurzu. */

/* Rozbalovátko je pruh, ne šedivá řádka. Dřív to byl drobný popisek v barvě
   nápovědy a nešlo poznat, že se na něj dá kliknout — přitom je to jediná
   cesta k tomu, jak z termínu udělat kurz. */
.lessons { margin-top: 12px; }
.lessons > summary {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 9px 12px; border: 1px solid var(--line-soft); border-radius: 9px;
  background: var(--bg); list-style: none; user-select: none;
}
.lessons > summary::-webkit-details-marker { display: none; }
.lessons > summary::before {
  content: ""; width: 7px; height: 7px; flex: none;
  border-right: 1.8px solid var(--muted); border-bottom: 1.8px solid var(--muted);
  transform: rotate(-45deg); margin-left: 2px;
  transition: transform .15s ease;
}
.lessons[open] > summary::before { transform: rotate(45deg); }
.lessons > summary:hover { border-color: var(--accent-ln); }
.lessons-title { font-weight: 700; font-size: .88rem; }
.lessons-count {
  font-size: .78rem; color: var(--muted); background: var(--card);
  border: 1px solid var(--line-soft); border-radius: 999px; padding: 2px 9px;
}
.lessons-body { padding-top: 12px; }
/* Pravidlo nad seznamem: co platí pro lekci, která čas ani místo nemá. */
.lessons-rule { margin: 0 0 10px; }

/* Popisky sloupců jednou nahoře, ne u každého z dvanácti řádků — mřížka se
   proto musí shodovat s `.lesson` do posledního sloupce. */
/* Vodorovné rolování je záchranná brzda, ne plán: sloupce se umí stlačit
   (`minmax(0, …)`), takže se seznam do panelu skoro vždycky vejde. Když ne —
   úzké okno, dlouhý název místa — je lepší, aby se dal odrolovat, než aby
   tlačítka na konci řádku zmizela za okrajem. */
.lesson-list { overflow-x: auto; }
/* Rozvrh zůstává tabulkou i na úzkém okně. Přeskládat řádek na dva by
   znamenalo, že sloupce přestanou souhlasit se záhlavím — a záhlaví je
   jediné, co v něm popisuje, co které políčko je. */
.lesson-head, .lesson {
  display: grid;
  grid-template-columns:
    20px 126px minmax(0, .8fr) minmax(0, 1.1fr) minmax(0, 1fr) auto;
  align-items: center; gap: 6px; min-width: 430px;
}
.lesson + .lesson, .lesson-head + .lesson { margin-top: 5px; }
.lesson-head {
  padding: 0 10px 2px;
  font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted);
}
.lesson {
  background: var(--card); border: 1px solid var(--line-soft);
  border-radius: 9px; padding: 6px 10px;
}
.lesson.off { opacity: .55; }
.lesson.is-dirty { background: #fff8f0; border-color: var(--accent-ln); }
.lesson-n {
  font-size: .78rem; color: var(--muted);
  font-variant-numeric: tabular-nums; text-align: right;
}
.lesson > input, .lesson .choice select, .lesson .choice input {
  width: 100%; min-width: 0; height: 32px;
}
/* Datum a název lekce jsou jediná pole v administraci, která stála bez rámu:
   `.choice` vedle nich si styl nese z `.field`, ale prosté `<input>` v mřížce
   nepatří nikam, takže ho prohlížeč nakreslil po svém — hranatý rámeček
   systémovým písmem vedle zaoblených polí. Tady dostávají týž rám, rádius
   i chování při najetí a zaostření jako `.mini-field` o kus výš. */
.lesson > input {
  font: inherit; font-size: .86rem; font-weight: 400; color: var(--ink);
  padding: 0 9px; line-height: normal;
  border: 1px solid var(--line); border-radius: 9px; background-color: #fff;
}
.lesson > input:hover { border-color: var(--accent-ln); }
.lesson > input:focus {
  outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent;
}
/* Datum je v řádku nejužší sloupec a tabulkové číslice ho ještě roztahují —
   o chlup menší písmo a užší okraje ho udrží ve 126 px i s ikonkou kalendáře. */
.lesson > input[type=date] { font-size: .82rem; padding: 0 4px 0 7px; }
.lesson-act { display: flex; gap: 4px; align-items: center; }

/* Tlačítko, které je jen ikona. Co dělá, řekne `title`. */
.icon-btn {
  display: grid; place-items: center; width: 30px; height: 30px; padding: 0;
  border: 1px solid var(--line-soft); border-radius: 8px;
  background: var(--card); color: var(--muted); cursor: pointer;
}
.icon-btn svg { width: 16px; height: 16px; }
.icon-btn:hover { color: var(--ink); border-color: var(--accent-ln); }
.icon-btn.danger:hover { color: var(--danger); border-color: #e8c8c3; }

/* Volba uvnitř karty termínu a řádku lekce. `.field.choice` je jinak pole
   formuláře (blok s popiskem a mezerou pod sebou); tady je to jeden ovladač
   v mřížce, takže se z něj sundá všechno, co dělá odstavec. */
.term .field.choice, .lesson .field.choice { margin: 0; display: block; min-width: 0; }
.term .field.choice select { width: 100%; height: 36px; }
.lesson .field.choice select { width: 100%; }
.term .field.choice [data-choice-custom],
.lesson .field.choice [data-choice-custom] { width: 100%; margin-top: 4px; }
/* Osmipixelové odsazení z `.field` se do 32px řádku lekce nevejde: text se
   v něm posadí tak nízko, že mu prohlížeč ukousne dolní dotažnice („p", „ý"
   v „nevyplněno"). Ve 32 px se řádka vystředí sama, odsazení se proto nuluje
   — vpravo zůstává místo na kreslenou šipku. */
.lesson .field.choice select {
  height: 32px; font-size: .86rem; padding: 0 30px 0 10px;
}

/* Rozepsání termínu na lekce — jediné místo v běhu, kde se zadává datum
   (rozvrh ještě žádný není, na co by navazoval). */
.lesson-new {
  display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap;
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line-soft);
}
.lesson-new select { height: 36px; }

/* Přidání lekce do existujícího běhu. Tlačítko s předpovězeným datem, ne
   formulář: pod tabulkou dvanácti vyplněných dat je další sada políček to
   poslední, co člověk čeká — a hlavně vypadala k nerozeznání od formuláře
   na nový termín o kus níž. */
.lesson-more {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin-top: 8px; padding-top: 10px; border-top: 1px dashed var(--line);
}
.lesson-more > .btn span {
  color: var(--muted); font-weight: 400; margin-left: 6px;
  font-variant-numeric: tabular-nums;
}
/* Odkaz, ne tlačítko: prodloužení o víc lekcí je řídká potřeba a nemá si
   brát váhu toho, co se dělá běžně. */
.btn.link {
  border: 0; background: none; padding: 4px 2px; height: auto;
  color: var(--muted); text-decoration: underline; text-underline-offset: 3px;
}
.btn.link:hover { color: var(--ink); background: none; }
.lesson-bulk {
  flex: 1 0 100%; display: flex; align-items: flex-end; flex-wrap: wrap; gap: 10px;
  margin-top: 4px; padding: 12px 14px;
  border: 1px solid var(--line-soft); border-radius: var(--r); background: var(--bg);
}
.lesson-bulk select { height: 36px; }
.lesson-bulk .hint { flex: 1 0 100%; margin: 0; }
/* Křížek na konci řádku, ne u pole: zavírá celý panel, ne jednu hodnotu. */
.lesson-bulk .bulk-x { margin-left: auto; align-self: center; }

/* ---------- náhled v okně ---------------------------------------------------
   Skutečná stránka, ne překreslená napodobenina — ta musela znát pravidla webu
   a při každé jeho změně se s ním rozcházela. V okně se vejde v šířce, ve
   které ji uvidí většina lidí; ve sloupci vedle formuláře by z ní byl mobil
   zmenšený na dlaň. */
.modal-card.preview { width: min(1180px, 100%); }
.modal-card.preview #modal-body { padding: 0; }
.pv-frame { position: relative; background: #fff7f0; }
.pv-frame iframe { display: block; width: 100%; height: 74vh; border: 0; }
.pv-frame::before {
  content: "Načítám náhled…"; position: absolute; inset: 0;
  display: grid; place-items: center; font-size: .85rem; color: var(--muted);
}
.pv-frame.is-loaded::before { display: none; }
.pv-bar {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 22px; border-bottom: 1px solid var(--line); background: var(--bg);
  font-size: .82rem; color: var(--muted);
}
.pv-bar a { margin-left: auto; }

.move { display: flex; gap: 3px; }
.move .btn { padding: 6px 9px; line-height: 1; }

/* Zaoblený čtverec: fotka ho vyplní bez deformace, iniciála sedí přesně
   uprostřed — svisle i vodorovně. */
.team-thumb {
  flex: 0 0 auto; align-self: flex-start;
  width: 52px; height: 52px; aspect-ratio: 1 / 1;
  border-radius: 14px; overflow: hidden;
  border: 1px solid var(--line); background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  line-height: 1; text-align: center;
}
.team-thumb img {
  width: 100%; height: 100%; object-fit: cover; object-position: center;
  display: block; border-radius: inherit;
}
/* Ne `.empty`: tak se jmenuje hláška „zatím tu nic není" a její 44px
   odsazení rám roztáhlo na obdélník. */
.team-thumb.no-photo span {
  display: block; font-weight: 700; font-size: 1.15rem; line-height: 1;
  color: var(--muted); user-select: none;
}

.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 14px; }
.hint { font-size: .8rem; color: var(--muted); }

.toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 16px; }
.toolbar .search { flex: 1; min-width: 180px; }
.toolbar .search input {
  font: inherit; width: 100%; padding: 9px 13px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--card);
}
.toolbar .search input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

/* ---------- filtry -------------------------------------------------------- */
/* Hledání a filtr drží pohromadě a zůstávají na očích i po odscrollování —
   u dlouhých seznamů je jinak člověk musí jít nahoru hledat. */
.filters {
  position: sticky; top: var(--topbar-h); z-index: 15;
  margin: -24px -28px 20px; padding: 18px 28px 14px;
  background: rgba(251, 246, 241, .92); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.filters .toolbar { margin: 0; }
.filters .toolbar + .chiprail { margin-top: 12px; }

/* Vodorovný pás štítků. Na úzké obrazovce se posouvá do strany a okraj
   se stmívá, aby bylo poznat, že seznam pokračuje. */
.chiprail { display: flex; gap: 7px; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
  font: inherit; font-size: .84rem; font-weight: 600; cursor: pointer;
  padding: 6px 8px 6px 13px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card); color: var(--ink-soft);
  transition: background .15s, border-color .15s, color .15s;
}
.chip:hover { border-color: var(--muted); }
/* Zapnutý filtr vypadá jako štítek, který nese karta pod ním — kliknutím
   na „Logopedie" se pás obarví do stejné barvy jako odznak na výsledcích. */
.chip.is-on { background: var(--accent-sk); border-color: var(--accent-ln); color: var(--accent-d); }
.chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.chip-n {
  font-size: .72rem; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--muted); background: var(--line-soft); border-radius: 999px;
  padding: 1px 7px; min-width: 23px; text-align: center;
}
.chip.is-on .chip-n { background: rgba(217, 114, 44, .16); color: var(--accent-d); }
/* Prázdnou kategorii nezakazujeme — jen ustoupí, ať je vidět, kde co je. */
.chip.is-empty { opacity: .42; }

table { width: 100%; border-collapse: collapse; font-size: .88rem; }
th, td { text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
th { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 700; }
td.num, th.num { text-align: right; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr.clickable { cursor: pointer; }
tbody tr.clickable:hover { background: var(--bg); }
tr.off td { opacity: .5; }
table input { font: inherit; font-size: .88rem; padding: 5px 8px; border: 1px solid var(--line); border-radius: 7px; width: 100%; }
table input[type=number] { max-width: 88px; }
.table-wrap { overflow-x: auto; }

.legend { margin: 10px 0 0; }

.pill {
  display: inline-block; font-size: .72rem; font-weight: 700; padding: 2px 9px;
  border-radius: 999px; background: var(--line-soft); color: var(--muted); white-space: nowrap;
}
.pill.paid, .pill.ok { background: var(--ok-bg); color: var(--ok); }
.pill.pending, .pill.warn { background: var(--warn-bg); color: var(--warn); }
.pill.failed, .pill.cancelled, .pill.bad { background: var(--danger-bg); color: var(--danger); }
.pill.accent { background: #fce6d3; color: var(--accent-d); }

/* ---------- plocha přehledu ------------------------------------------------
   Karty ve mřížce o čtyřech sloupcích: číslo zabere jeden, tabulka nebo graf
   dva, cokoli si kdo roztáhne až na čtyři. Šířka je **třída**, ne proměnná —
   `grid-column: span` chce celé číslo, takže se `min()` v ní použít nedá
   a užší okna přepisují celé pravidlo.  */

.dash-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.dash-note { flex: 1 1 auto; }
.dash-tools { display: flex; gap: 8px; margin-left: auto; }

.wgrid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; align-items: start; }
.wgrid > .w1 { grid-column: span 1; }
.wgrid > .w2 { grid-column: span 2; }
.wgrid > .w3 { grid-column: span 3; }
.wgrid > .w4 { grid-column: span 4; }

.wg {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  padding: 16px 18px; min-width: 0;
}
.wg-head { margin-bottom: 12px; }
.wg-head h3 { font-size: 1rem; }
.wg-head .sub { color: var(--muted); font-size: .82rem; margin: 3px 0 0; }
.wg .table-wrap { margin: 0 -4px; }

/* Jedno velké číslo. Nadpis nemá — popisek pod číslem říká totéž a dvakrát
   napsaná táž věc z dlaždice dělá formulář. */
.wg.is-kpi { padding: 0; }
.wg .kpi {
  display: block; width: 100%; text-align: left; font: inherit; color: inherit;
  background: transparent; border: 0; padding: 16px 18px; border-radius: var(--r);
}
.wg button.kpi { cursor: pointer; }
.wg button.kpi:hover { background: var(--bg); }
.wg button.kpi:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.wg .kpi b { display: block; font-size: 1.65rem; font-weight: 800; letter-spacing: -.02em; }
.wg .kpi span { display: block; font-size: .8rem; color: var(--muted); }
.wg .kpi .wg-hint { display: block; font-style: normal; font-size: .74rem; color: var(--muted); opacity: .85; margin-top: 7px; }
.wg.is-kpi .fill { width: calc(100% - 36px); margin: 0 18px 16px; }

/* Sloupcový graf. Z divů, ne z SVG: v SVG se s obrázkem zmenšují i popisky
   měsíců a v šířce widgetu z nich byly nečitelné drobky. */
.chart-top {
  display: flex; justify-content: flex-end; font-size: .72rem; color: var(--muted);
  border-bottom: 1px dashed var(--line); padding-bottom: 4px; margin-bottom: 10px;
}
.chart-cols { display: flex; align-items: flex-end; gap: 4px; height: 148px; }
.chart-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; height: 100%; }
.chart-track { flex: 1; display: flex; align-items: flex-end; }
/* Sloupec nemá být širší než dlaň — u tří měsíců by z grafu jinak byly tři
   plochy vedle sebe a čte se z nich hůř než ze tří čísel. */
.chart-track i {
  display: block; width: 100%; max-width: 72px; margin: 0 auto; min-height: 2px;
  border-radius: 5px 5px 2px 2px; background: linear-gradient(var(--accent), #f6bf94);
}
.chart-track:hover i { background: linear-gradient(var(--accent-d), var(--accent)); }
.chart-col em {
  font-style: normal; font-size: .66rem; color: var(--muted); text-align: center;
  margin-top: 7px; white-space: nowrap; overflow: hidden;
}

.donut-wrap { display: flex; gap: 18px; align-items: center; flex-wrap: wrap; }
.donut { width: 118px; height: 118px; flex: none; }
.legend {
  list-style: none; margin: 0; padding: 0; flex: 1 1 200px; min-width: 0;
  display: flex; flex-direction: column; gap: 7px; font-size: .84rem;
}
.legend li { display: flex; align-items: center; gap: 9px; }
.legend-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.legend b { font-variant-numeric: tabular-nums; font-size: .82rem; }
.legend-share { color: var(--muted); font-size: .74rem; min-width: 36px; text-align: right; }

.barlist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.barlist li {
  display: grid; grid-template-columns: minmax(80px, 1.3fr) minmax(50px, 1fr) auto;
  gap: 10px; align-items: center; font-size: .85rem;
}
.barlist-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.barlist-track { height: 8px; border-radius: 999px; background: var(--line-soft); overflow: hidden; }
.barlist-track i { display: block; height: 100%; border-radius: 999px; }
.barlist b { font-size: .82rem; font-variant-numeric: tabular-nums; }

.wg-list { list-style: none; margin: 0; padding: 0; }
.wg-list li {
  display: flex; align-items: center; gap: 10px; padding: 8px 0;
  border-bottom: 1px solid var(--line-soft);
}
.wg-list li:last-child { border-bottom: 0; padding-bottom: 0; }
.wg-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.wg-list-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.wg-list-main b { font-size: .88rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wg-list-side { flex: none; width: 96px; display: flex; flex-direction: column; align-items: flex-end; gap: 5px; }

/* Kolik míst je prodaných. Nezadaná kapacita má vlastní tvar — plný pruh by
   o termínu, u kterého se kapacita nehlídá, lhal. */
.fill { display: block; width: 100%; height: 6px; border-radius: 999px; background: var(--line-soft); overflow: hidden; }
.fill i { display: block; height: 100%; border-radius: 999px; background: var(--accent); }
.fill.is-none { background: repeating-linear-gradient(90deg, var(--line-soft) 0 4px, transparent 4px 8px); }

/* Úpravy plochy. Lišta a rámeček se ukazují jen v nich; jinak by z každé
   karty byl ovládací panel a plocha by přestala být tím, kvůli čemu se
   otevírá. Obsah karty je v úpravách nekliknutelný — táhne se s ní. */
.wgrid.is-edit .wg { border-style: dashed; border-color: var(--accent-ln); }
.wgrid.is-edit .wg-body { pointer-events: none; }
.wgrid.is-edit .wg.is-kpi { padding: 14px 16px 0; }
.wgrid.is-edit .wg.is-kpi .kpi { padding: 0 0 14px; }
.wgrid.is-edit .wg.is-kpi .fill { margin: 0 0 14px; }
.wg-bar {
  display: flex; align-items: center; gap: 6px;
  padding-bottom: 9px; margin-bottom: 11px; border-bottom: 1px solid var(--line-soft);
}
.wg-bar b { flex: 1; min-width: 0; font-size: .82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Na kartu o šířce jednoho sloupce se název a šest tlačítek vedle sebe
   nevejdou — název jde na vlastní řádek, ať z něj nezbudou tři písmena. */
.wgrid.is-edit .w1 .wg-bar { flex-wrap: wrap; }
.wgrid.is-edit .w1 .wg-bar b { flex: 1 0 100%; order: -1; margin-bottom: 2px; }
.wg-grab { cursor: grab; color: var(--muted); font-size: .9rem; }
.wg-size { font-size: .7rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.wg-btn {
  font: inherit; font-size: .8rem; line-height: 1; width: 25px; height: 25px; flex: none;
  border: 1px solid var(--line); background: var(--card); border-radius: 7px;
  color: var(--ink-soft); cursor: pointer;
}
.wg-btn:hover:not(:disabled) { border-color: var(--muted); }
.wg-btn:disabled { opacity: .32; cursor: default; }
.wg.is-dragging { opacity: .45; }

.dash-picker { margin-top: 14px; }
.picker-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px; margin-top: 14px; }
.picker-item {
  display: flex; flex-direction: column; gap: 3px; text-align: left; font: inherit;
  background: var(--bg); border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 12px; cursor: pointer;
}
.picker-item b { font-size: .86rem; }
.picker-item span { font-size: .76rem; color: var(--muted); }
.picker-item:hover { border-color: var(--accent-ln); background: var(--accent-sk); }

/* Užší okno = míň sloupců. Roztažení, které si někdo uložil na monitoru,
   se tím neztrácí — jen se tady nemá kam vejít. */
@media (max-width: 1400px) {
  .wgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wgrid > .w2, .wgrid > .w3, .wgrid > .w4 { grid-column: span 2; }
}
@media (max-width: 760px) {
  .wgrid { grid-template-columns: 1fr; }
  .wgrid > .w1, .wgrid > .w2, .wgrid > .w3, .wgrid > .w4 { grid-column: span 1; }
  /* Na mobilu by vysvětlivka k období zabrala vlastní řádek nad plochou.
     Totéž stojí pod nadpisem každého widgetu, kterého se to týká. */
  .dash-note { display: none; }
  .dash-tools { width: 100%; margin-left: 0; }
  .wg-list-side { width: 74px; }
}

.empty { text-align: center; color: var(--muted); padding: 44px 20px; }
.empty b { display: block; color: var(--ink); margin-bottom: 4px; }

.section-title { display: flex; align-items: center; gap: 10px; margin: 26px 0 12px; font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 700; }
.section-title::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* Důvod storna v detailu objednávky. Je to jediná věta okna, kterou napsal
   člověk — a hlavně přesné znění toho, co dostal zákazník do schránky. */
.cancel-reason {
  margin: 0; padding: 11px 14px; border-left: 3px solid var(--accent);
  background: var(--bg); border-radius: 0 10px 10px 0;
  font-size: .92rem; line-height: 1.55; color: var(--ink);
}

/* ---------- rozcestník vedle obsahu --------------------------------------- */
/* Devatenáct stránek textů, sedm kategorií akcí. Svislý rozcestník je proti
   rozbalovacímu seznamu i vodorovnému pásu ve dvou věcech lepší: je vidět
   celý najednou a nese čísla — kde co je, se pozná bez klikání. Sdílí ho
   „Texty na webu" i „Akce a termíny", proto ty obecné názvy. */
.split { display: grid; grid-template-columns: 268px minmax(0, 1fr); gap: 20px; align-items: start; }
.rail {
  position: sticky; top: calc(var(--topbar-h) + 20px);
  display: flex; flex-direction: column; gap: 1px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  padding: 8px; max-height: calc(100vh - var(--topbar-h) - 40px); overflow-y: auto;
}
.rail-label {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); font-weight: 700; padding: 10px 10px 5px;
}
.rail-item {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  font: inherit; font-size: .87rem; color: var(--ink-soft); cursor: pointer;
  background: transparent; border: 0; border-radius: 9px; padding: 7px 10px;
  transition: background .15s, color .15s;
}
.rail-item:hover { background: var(--bg); }
.rail-item.is-on { background: var(--accent-sk); color: var(--accent-d); font-weight: 700; }
.rail-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.rail-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail-n { font-size: .74rem; font-weight: 700; color: var(--muted); font-variant-numeric: tabular-nums; }
.rail-item.is-on .rail-n { color: var(--accent-d); }
.rail-item.is-empty { opacity: .42; }
/* Tečka = tady něco stojí za pozornost. U textů přepsané znění, u akcí
   akce, která nemá termín, a tudíž se nedá koupit. */
.rail-dot { flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.rail-sep { height: 1px; background: var(--line-soft); margin: 7px 8px; }

/* Rozcestník schovaný pod tlačítko. Nasazuje ho `railAsMenu()` v admin.js na
   dvě situace, které vypadají různě, ale jsou totéž: na sloupec vedle obsahu
   není místo. Buď je úzké celé okno, nebo je vedle otevřený náhled a 268 px
   sloupce by chybělo přesně tam, kde se píše.

   Rozbalí se **přes obsah**, ne nad ním: jinak by kliknutí do seznamu
   posunulo karty pod ním a text by uhnul pod rukou. A pořád je to týž svislý
   seznam s čísly — pás štítků vedle sebe by u dvaceti stránek znamenal hledat
   je vodorovným rolováním. */
.rail-box > summary { display: none; }
.rail-box > summary::-webkit-details-marker { display: none; }

.split.menu { grid-template-columns: minmax(0, 1fr); gap: 12px; }
.split.menu .rail-box { position: relative; z-index: 15; }
.split.menu .rail-box > summary {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  font-size: .87rem; color: var(--muted);
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  padding: 9px 13px; list-style: none;
}
.split.menu .rail-box > summary b { color: var(--ink); }
.split.menu .rail-box > summary::after {
  content: "▾"; margin-left: auto; font-size: .8rem; opacity: .6;
}
.split.menu .rail-box[open] > summary { border-color: var(--accent-ln); }
.split.menu .rail-box[open] > summary::after { content: "▴"; }
.split.menu .rail-box > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.split.menu .rail {
  position: absolute; top: calc(100% + 6px); left: 0;
  width: min(340px, 100%); max-height: min(60vh, 420px);
  box-shadow: var(--shadow);
}

/* ---------- texty --------------------------------------------------------- */
/* Texty vedle sebe, ne pod sebou. Jsou to většinou nadpisy a věty na jeden
   řádek: přes celou šířku monitoru by z každého byla stopadesátiznaková
   linka, ve které oko ztrácí začátek dalšího řádku, a pod sebou by z jedné
   stránky bylo pár metrů rolování. Sloupec má šířku čitelné věty a kolik se
   jich vedle sebe vejde, rozhodne okno — s otevřeným náhledem klidně jeden. */
/* `min(320px, 100%)` a ne rovnou 320: v užším sloupci (vedle otevřeného
   náhledu) by pevných 320 znamenalo dráhu širší než místo, do kterého se
   kreslí — mřížka by z karty vylezla ven místo aby se srovnala do jedné. */
.text-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); gap: 12px; align-items: start; }
/* S otevřeným náhledem je karta stránky úzká. Název se v ní nemá mačkat na
   dvě slabiky kvůli tlačítkům vedle — ta radši spadnou pod něj. */
[data-page-card] > .card-head { flex-wrap: wrap; }
[data-page-card] > .card-head .grow { min-width: 180px; }
.text-row { border: 1px solid var(--line-soft); border-radius: 11px; padding: 10px 12px; background: var(--bg); }
.text-row.is-on { border-color: var(--accent-ln); background: var(--card); }
.text-row.is-dirty { border-color: var(--accent-ln); }
/* Celý dokument stránky (`kind: block`) — právní texty a doprava a platba.
   Nestojí ve sloupci vedle vět: je to celá stránka a čte se jako stránka,
   tak si bere celou šířku karty a výšku, ve které je vidět souvislost. */
.text-row.is-block { grid-column: 1 / -1; }
.text-row.is-block .rt-area { min-height: 460px; resize: vertical; overflow: auto; }
.text-row.is-block .text-row-head .hint { margin-left: auto; font-size: .76rem; }

/* ---------- dokument tak, jak vypadá na webu --------------------------------
   Editor celé stránky je jediné místo v administraci, kde se **nepíše do
   formuláře, ale sází stránka**. Systémové písmo a holé `dt`/`dd` v něm proto
   nestačí: kdo psal do editoru, kde je seznam údajů odsazeným řádkem, a pak
   se podíval na web, kde je z toho dvousloupcový blok v rámečku, nemá jak si
   ty dva obrazy spojit.

   Pravidla jsou proto opsaná z webu (`.legal*` v assets/css/style.css) —
   jenom ta, která ty dokumenty opravdu používají. Kdyby se na webu změnila,
   musí se srovnat i tady; je to cena za náhled, který nelže. Písmo se kvůli
   tomu do administrace natahuje z Google Fonts, ale platí **jen uvnitř
   editoru** — zbytek administrace zůstává nástroj v systémovém písmu. */
/* Písmo, rytmus a struktura se opisují z webu, **podklad ne**: do bílého
   políčka se píše a barevná plocha přes půl obrazovky z editoru dělá obrázek
   stránky. Vedle je na to náhled. */
.rt-doc .rt-area {
  font-family: "Source Serif 4", "Iowan Old Style", Georgia, serif;
  color: #2a2320; background: var(--card);
  font-size: 1rem; line-height: 1.72;
  max-width: 760px; margin-inline: auto; padding: 22px 26px;
}
.rt-doc .rt-area h2, .rt-doc .rt-area h3 {
  font-family: "Playfair Display", "Iowan Old Style", Georgia, serif;
  color: #2a2320; font-weight: 800; line-height: 1.08;
}
.rt-doc .rt-area h2 { font-size: 1.6rem; margin: 3rem 0 1rem; }
.rt-doc .rt-area h2:first-child { margin-top: 0; }
.rt-doc .rt-area h3 { font-size: 1.12rem; font-weight: 700; margin: 2rem 0 .6rem; }
.rt-doc .rt-area p { margin: 0 0 1rem; }
.rt-doc .rt-area ul, .rt-doc .rt-area ol { margin: 0 0 1.2rem 1.3rem; padding: 0; }
.rt-doc .rt-area li { margin-bottom: .5rem; line-height: 1.7; }
.rt-doc .rt-area a { color: #e07a34; text-decoration: underline; text-underline-offset: 3px; }
.rt-doc .rt-area .legal-note { font-size: .92rem; color: #2a2320; font-style: italic; }
/* Bez vlastního podkladu, stejně jako na webu: tam má seznam údajů tutéž
   barvu jako stránka, takže se proti okolí neodliší. Podbarvit ho tady by
   znamenalo ukazovat rámeček, který na stránce není — z bloku zůstává to, co
   je na něm vidět doopravdy: dva sloupce a odsazení. */
.rt-doc .rt-area .legal-block { padding: 18px 22px; }

/* Mřížka údajů a tabulka se v editoru nevykreslují jako na stránce, ale jako
   řádky s políčky — dělá to `doc-editor.js` a vzhled si veze s sebou, protože
   tentýž widget je i na webu. Zbývá tu jen to, co je zdejší: kolem sebe má
   dýchat stejně jako odstavec. */
.rt-doc .rt-area .ge { margin-bottom: 1.4rem; }

/* Úzký sloupec dokumentu by se v úzkém panelu nevešel i s odsazením. */
@media (max-width: 1400px) {
  .rt-doc .rt-area { padding: 18px; }
}

/* Vlastní sekce stránky — text, který v šabloně nebyl. Stojí pod texty ze
   šablony a odděleně: nahoře se přepisuje, co na stránce je, tady se přidává,
   co na ní není. */
.own-sections { margin-top: 20px; }
.own-sections .section-title { margin-top: 0; }
.own-sections .text-row { margin-bottom: 12px; }
.own-sections .text-row .rt-area { min-height: 220px; }
.own-sections .row-tools { display: flex; gap: 6px; margin-left: auto; }
.own-sections .row-tools .btn { padding: 4px 9px; line-height: 1.2; }
.own-sections .hint { margin: 0 0 12px; }
.own-sections .own-note { margin: -4px 0 14px; }
/* Skrytá sekce je pořád k dispozici, jen se zlehka ztiší — stejně jako
   skryté akce a novinky. */
.own-sections .text-row.off { opacity: .62; }
.text-row-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.text-row-head .where { font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Políčko textu je zmenšený editor článku (`.rt`), takže tučné slovo i odkaz
   jsou vidět tak, jak budou na webu. Lišta se proto smršťuje na čtyři ikony
   a plocha na pár řádků: v jednom sloupci jich vedle sebe stojí desítky. */
.text-row .rt { border-radius: 9px; background: var(--card); }
.text-row .rt-bar { padding: 4px 5px; gap: 1px; background: transparent; }
.text-row .rt-btn { width: 26px; height: 26px; border-radius: 6px; }
.text-row .rt-btn svg { width: 15px; height: 15px; }
.text-row .rt-btn:hover { background: var(--bg); }
.text-row .rt-area {
  min-height: 54px; max-height: 220px; padding: 8px 11px;
  font-size: .9rem; line-height: 1.5;
}
.text-row .rt-area.rt-empty::before { top: 8px; left: 11px; font-style: italic; }
.text-row .orig { font-size: .8rem; color: var(--muted); margin: 6px 0 0; }
.text-row .row-actions { display: flex; gap: 8px; margin-top: 8px; }

/* ---------- náhled vedle obsahu ---------------------------------------------
   Upravit text a nevidět, kde na stránce sedí, znamená přepínat se do druhé
   karty a zpátky. Náhled je tedy vedle políček — v místě, kde do téhle chvíle
   bylo prázdno — a ukazuje **rozepsané** znění, ne jen uložené: to je celý
   smysl toho, že stojí u editace.

   Stránka se v něm vykresluje v šířce, ve které ji uvidí návštěvník, a teprve
   pak se celá zmenší (`transform: scale` v `fitPreview`). Bez toho by náhled
   ukazoval mobilní rozvržení jen proto, že je panel užší než monitor — což je
   přesně ta chyba, kvůli které je náhled akce v okně, a ne ve sloupci. */
.pv-panel {
  position: sticky; top: var(--topbar-h); z-index: 10;
  flex: 0 0 var(--pv-w, min(620px, 42vw)); height: calc(100vh - var(--topbar-h));
  display: flex; flex-direction: column;
  background: var(--card); border-left: 1px solid var(--line);
}
.pv-grab { position: absolute; inset: 0 auto 0 -3px; width: 7px; cursor: col-resize; z-index: 2; }
.pv-grab::after {
  content: ""; position: absolute; inset: 0 auto 0 2px; width: 3px;
  background: var(--accent); opacity: 0; transition: opacity .15s;
}
.pv-grab:hover::after, .pv-grab:focus-visible::after, body.pv-resizing .pv-grab::after { opacity: .6; }
.pv-grab:focus-visible { outline: none; }
/* Při tažení nesmí rám polykat pohyby myši — jinak se panel „utrhne", jakmile
   kurzor přejede přes stránku v náhledu. */
body.pv-resizing { cursor: col-resize; user-select: none; }
body.pv-resizing .pv-stage { pointer-events: none; }

.pv-panel-head { display: flex; align-items: center; gap: 8px; padding: 9px 12px; border-bottom: 1px solid var(--line); }
.pv-panel-head b { flex: 1; min-width: 0; font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-modes { display: flex; gap: 2px; padding: 2px; background: var(--bg); border: 1px solid var(--line); border-radius: 9px; }
.pv-modes button {
  font: inherit; font-size: .78rem; cursor: pointer; color: var(--muted);
  background: transparent; border: 0; border-radius: 7px; padding: 3px 9px;
}
.pv-modes button.is-on { background: var(--card); color: var(--ink); font-weight: 700; box-shadow: 0 1px 2px rgba(42, 35, 32, .1); }

.pv-stage { position: relative; flex: 1; min-height: 0; overflow: hidden; background: #fff7f0; }
.pv-stage iframe { position: absolute; top: 0; left: 0; display: block; border: 0; transform-origin: top left; }
.pv-stage::before {
  content: "Načítám náhled…"; position: absolute; inset: 0;
  display: grid; place-items: center; font-size: .85rem; color: var(--muted);
}
.pv-stage.is-loaded::before { display: none; }
.pv-panel-foot {
  margin: 0; padding: 8px 12px; border-top: 1px solid var(--line);
  background: var(--bg); font-size: .76rem; color: var(--muted);
}

/* ---------- modál --------------------------------------------------------- */
#modal { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 20px; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(42, 35, 32, .4); }
.modal-card {
  position: relative; background: var(--card); border-radius: 18px; width: min(640px, 100%);
  max-height: 88vh; display: flex; flex-direction: column; box-shadow: 0 24px 60px rgba(42, 35, 32, .3);
}
/* Okno s editorem článku. Psaní je jiná práce než vyplnění pěti políček:
   text potřebuje šířku, aby se dal číst po odstavcích, a lišta se do užšího
   okna vejde jen zalomená do dvou řad. */
.modal-card.wide { width: min(920px, 100%); }
/* Okno s náhledem vedle formuláře. Užší už by znamenalo buď formulář na
   dva sloupce v jednom, nebo náhled tak malý, že by se v něm nedalo číst. */
.modal-card.has-preview { width: min(980px, 100%); }
.modal-card > header { display: flex; align-items: center; gap: 12px; padding: 18px 22px; border-bottom: 1px solid var(--line); }
.modal-card > header h2 { font-size: 1.05rem; flex: 1; }
.modal-x { font: inherit; background: 0; border: 0; cursor: pointer; color: var(--muted); font-size: 1rem; }
.modal-x:hover { color: var(--ink); }
#modal-form { display: contents; }
#modal-body { padding: 20px 22px; overflow-y: auto; }
.modal-card footer { display: flex; justify-content: flex-end; gap: 10px; padding: 14px 22px; border-top: 1px solid var(--line); background: var(--bg); border-radius: 0 0 18px 18px; }
.modal-note { background: var(--bg); border-radius: 10px; padding: 11px 13px; font-size: .84rem; color: var(--muted); margin: 0 0 16px; }
.modal-note.warn { background: var(--warn-bg); color: var(--warn); }

/* ---------- hlášky -------------------------------------------------------- */
#toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%) translateY(8px);
  background: var(--ink); color: #fff; padding: 11px 20px; border-radius: 10px;
  font-size: .9rem; opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s;
  max-width: min(520px, calc(100% - 32px)); z-index: 90; box-shadow: var(--shadow);
}
#toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
#toast.err { background: var(--danger); }

/* ---------- úzká obrazovka ------------------------------------------------ */
/* Rozcestník se vejde vedle obsahu jen na širokém okně; pod tím se z něj
   stane vodorovný pás, ať nebere půlku šířky. */
/* Náhled se vedle úpravy vejde jen na širokém okně; pod tím jde pod ni.
   Zmenšovat ho dál nemá smysl — přestal by být čitelný dřív, než by se
   vešel. */
/* Dva sloupce se vejdou jen na širokém okně; pod tím jde všechno pod sebe
   a bloky se zavřou (viz `viewEvent`), ať je z toho seznam kapitol a ne
   nekonečné rolování. */
/* Náhled vedle textů má smysl, jen když vedle něj zbude na políčka. Pod tím
   se schová celý — zúžený na dlaň by z něj byl obrázek, na kterém není vidět,
   co se upravuje, a přitom by bral polovinu okna. Odkaz „Otevřít ↗" v kartě
   stránky vede na tutéž stránku ve vlastní kartě. */
@media (max-width: 1200px) {
  .pv-panel, .pv-only { display: none; }
}

@media (max-width: 1100px) {
  .editor-grid { grid-template-columns: 1fr; }
}

@media (max-width: 820px) {
  .checks-list { grid-template-columns: 1fr; }
  .term-fields { grid-template-columns: 1fr 1fr; }
}

/* Popisek u nadpisu bloku je vysvětlivka, ne obsah — na úzkém okně by ze
   dvouřádkové hlavičky udělal čtyřřádkovou. */
@media (max-width: 620px) {
  .panel-note { display: none; }
}

/* Pás štítků místo sloupce nasazuje `flatRail()` v admin.js — je to totiž
   otázka místa vedle obsahu, ne jen šířky okna (viz `.split.flat` výš). */

@media (max-width: 860px) {
  #app { grid-template-columns: 1fr; }
  /* Na úzkém okně je název na vlastním řádku a tlačítka pod ním — čtyři věci
     vedle sebe se do 430 px nevejdou a název by se rozpadl na písmena. */
  .editor-bar { margin: -18px -18px 14px; padding: 10px 18px; flex-wrap: wrap; }
  .editor-title { order: -1; flex: 1 0 100%; }
  .editor-title b { font-size: .95rem; }
  .editor-bar .btn { flex: 1 1 auto; }
  .hide-sm { display: none; }
  .term-fields { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed; inset: 0 auto 0 0; width: 236px; height: 100%; z-index: 40;
    transform: translateX(-100%); transition: transform .2s; box-shadow: var(--shadow);
  }
  body.nav-open .sidebar { transform: none; }
  body.nav-open::after { content: ""; position: fixed; inset: 0; background: rgba(42, 35, 32, .35); z-index: 30; }
  .menu-btn { display: block; }
  .topbar { padding: 0 18px; }
  .view { padding: 18px 18px 70px; }
  .filters { margin: -18px -18px 16px; padding: 14px 18px 12px; }
  .chiprail { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 2px; scrollbar-width: thin; }
  .grid2, .grid3 { grid-template-columns: 1fr; }
  .whoami { display: none; }
}

/* ---- editor článku -------------------------------------------------------
   Psaní je tu delší práce než vyplnění pole, tak dostane víc místa a klid:
   servisní písmo lišty, ale text článku v proporcionálním, aby bylo poznat,
   co se píše, a ne v čem se to píše. */

.rt {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  overflow: hidden;
}
.rt:focus-within { outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent; }

/* Lišta: rozbalovátko s typem odstavce a za ním skupiny ikon oddělené
   svislou linkou. Skupiny drží pohromadě to, co spolu souvisí — bez nich je
   to řada čtrnácti stejných čtverečků, ve které se hledá po jedné. */
.rt-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px;
  padding: 7px 8px;
  background: var(--bg);
  border-bottom: 1px solid var(--line-soft);
  position: sticky;
  top: 0;
  z-index: 1;
}
.rt-group {
  display: flex;
  align-items: center;
  gap: 2px;
}
.rt-group + .rt-group::before,
.rt-block + .rt-group::before {
  content: "";
  width: 1px;
  height: 18px;
  margin: 0 7px;
  background: var(--line);
}
/* Selektor je dvojitý schválně: `.field select { width: 100% }` o kus výš je
   specifičtější než samotná třída a bez toho by rozbalovátko zabralo celý
   řádek lišty — editor totiž stojí uvnitř pole formuláře. */
.rt-bar .rt-block {
  width: auto;
  flex: none;
  height: 30px;
  padding: 0 26px 0 9px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #fff
    /* Šipka jako obrázek: vlastní vzhled `select`u znamená zrušit ten
       systémový i s ní, a bez šipky by nebylo poznat, že se to rozbaluje. */
    url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234a3f39' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")
    no-repeat right 7px center / 13px;
  -webkit-appearance: none;
  appearance: none;
  font: inherit;
  font-size: .82rem;
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
}
.rt-bar .rt-block:hover { border-color: var(--muted); }

.rt-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: 1px solid transparent;
  background: transparent;
  border-radius: 7px;
  padding: 0;
  color: var(--ink-soft);
  cursor: pointer;
}
.rt-btn svg { width: 17px; height: 17px; display: block; }
.rt-btn:hover { background: #fff; border-color: var(--line); }
/* Zapnuté formátování pod kurzorem. Barvou, ne jen rámečkem — vedle
   najetí myší by se dvě skoro stejná zvýraznění pletla. */
.rt-btn.on {
  background: var(--accent-sk);
  border-color: var(--accent-ln);
  color: var(--accent-d);
}

.rt-area {
  position: relative;
  min-height: 260px;
  max-height: 52vh;
  overflow-y: auto;
  padding: 16px 18px;
  font-weight: 400;
  font-size: .95rem;
  line-height: 1.65;
  color: var(--ink);
}
/* Nápověda v prázdném editoru. Leží přes první odstavec, ne nad ním — jinak
   by text při prvním napsaném písmenu poskočil o řádek dolů. Souřadnice
   kopírují odsazení plochy: bez nich by se box odvozoval od statické pozice
   a skončil zarovnaný na opačné straně. */
.rt-area.rt-empty::before {
  content: attr(data-placeholder);
  position: absolute;
  top: 16px;
  left: 18px;
  color: var(--muted);
  pointer-events: none;
}
/* Nadpisy uvnitř editoru vypadají jako nadpisy, ne jako tučný odstavec —
   jinak se při psaní nepozná, co se do stránky opravdu uloží. */
.rt-area h2 { font-size: 1.25rem; margin: 1.1em 0 .4em; line-height: 1.3; }
.rt-area h3 { font-size: 1.05rem; margin: 1em 0 .35em; line-height: 1.35; }
.rt-area h2:first-child, .rt-area h3:first-child, .rt-area p:first-child { margin-top: 0; }
.rt-area p { margin: 0 0 .85em; }
.rt-area ul, .rt-area ol { margin: 0 0 .85em; padding-left: 1.4em; }
.rt-area li { margin-bottom: .3em; }
.rt-area blockquote {
  margin: 0 0 .85em;
  padding: .2em 0 .2em 1em;
  border-left: 3px solid var(--accent-ln);
  color: var(--muted);
  font-style: italic;
}
.rt-area a { color: var(--accent-d); }
/* Co umí lišta, musí být v editoru vidět tak, jak to nakonec vyjde na
   stránce — jinak se píše naslepo. Protějšek je v assets/css/style.css
   u `.article-body`. */
.rt-area pre {
  margin: 0 0 .85em;
  padding: .7em .9em;
  border-radius: 8px;
  background: var(--bg);
  border: 1px solid var(--line-soft);
  font: .85rem/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.rt-area code { font: .88em ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.rt-area img { max-width: 100%; height: auto; border-radius: 8px; }
.rt-area s, .rt-area strike { color: var(--muted); }

/* Přetažení obrázku rovnou do textu — ať je poznat, že se pustit smí. */
.rt-area.over { outline: 2px dashed var(--accent); outline-offset: -3px; }

/* ---- obrázek ve formuláři -------------------------------------------------
   Náhled vlevo, tlačítka vpravo. Náhled má pevný poměr stran a ořezává
   stejně jako karta na webu, takže je hned vidět, co z obrázku zbude —
   po nahrání to nemá být překvapení. */
.img-pick {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 12px; border: 1px solid var(--line); border-radius: 11px;
  background: var(--bg); font-weight: 400;
}
.img-pick.over { outline: 2px dashed var(--accent); outline-offset: -3px; }
.img-pick.busy { opacity: .55; pointer-events: none; }
.img-shot {
  flex: 0 0 132px; aspect-ratio: 5 / 4; overflow: hidden;
  border-radius: 9px; border: 1px solid var(--line);
  background: #fff; display: flex; align-items: center; justify-content: center;
  text-align: center; font-size: .76rem; color: var(--muted); padding: 6px;
}
.img-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.img-side { display: flex; flex-direction: column; align-items: flex-start; gap: 7px; }
.img-note { font-size: .76rem; color: var(--muted); line-height: 1.45; }

/* ---- obrázek akce ---------------------------------------------------------
   Totéž co `.img-pick` o kus výš, jen s jedním rozdílem: do náhledu patří
   fotka i kreslená ilustrace, takže se v něm musí vejít `<svg>` stejně jako
   `<img>`. Tlačítka jsou tři, protože cesty k obrázku jsou tři — banka,
   fotka, vlastní soubor —, a čtvrté odebírá. */
.art-pick {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 12px; border: 1px solid var(--line); border-radius: 11px;
  background: var(--bg); font-weight: 400;
}
.art-pick.busy { opacity: .55; pointer-events: none; }
.art-shot {
  flex: 0 0 148px; aspect-ratio: 4 / 3; overflow: hidden;
  border-radius: 9px; border: 1px solid var(--line);
  background: #fff; display: flex; align-items: center; justify-content: center;
  text-align: center; font-size: .76rem; color: var(--muted); padding: 6px;
}
.art-shot img, .art-shot svg { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Banka ilustrací v okně. Dlaždice drží poměr stran obrázku na webu — kdo
   vybírá, má vidět tvar, ve kterém to nakonec bude. */
.illu-bank h4 {
  margin: 16px 0 8px; font-size: .78rem; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted);
}
.illu-bank h4:first-child { margin-top: 0; }
.illu-bank-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.illu-choice {
  padding: 0; overflow: hidden; cursor: pointer; aspect-ratio: 4 / 3;
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
}
.illu-choice svg { display: block; width: 100%; height: 100%; }
.illu-choice:hover { border-color: var(--accent); }

@media (max-width: 700px) {
  .illu-bank-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ---- ikony a obrázky na obrazovce Úprava webu -----------------------------
   Dlaždice s kresbou a popiskem: podle čeho jiného by měl člověk poznat,
   kterou ikonu mění, než podle toho, jak vypadá a co u ní na stránce stojí.
   Vyměněná má tečku — je to táž značka jako u přepsaného textu. */
.art-block { margin-top: 22px; border-top: 1px solid var(--line); padding-top: 16px; }
.art-block h4 {
  margin: 14px 0 10px; font-size: .82rem; letter-spacing: .02em;
  display: flex; align-items: baseline; gap: 8px;
}
.art-block h4 .hint { font-weight: 400; }
.art-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(122px, 1fr)); gap: 10px; }

.art-tile {
  display: flex; flex-direction: column; gap: 7px; align-items: stretch;
  padding: 9px; cursor: pointer; text-align: left;
  background: #fff; border: 1px solid var(--line); border-radius: 11px;
}
.art-tile:hover { border-color: var(--accent); }
.art-tile.is-changed { border-color: var(--accent-ln); background: var(--accent-sk); }
.art-tile-art {
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  aspect-ratio: 4 / 3; border-radius: 8px; background: var(--bg);
}
.art-tile-art svg { width: 46%; height: 46%; }
.art-tile.wide .art-tile-art svg, .art-tile-art img { width: 100%; height: 100%; object-fit: cover; }
.art-tile-name {
  font-size: .74rem; line-height: 1.3; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Okno výměny: nahoře to, co na stránce je teď, pod tím banka. */
.swap-now {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px; margin-bottom: 6px;
  border: 1px solid var(--line); border-radius: 11px; background: var(--bg);
}
.swap-now .art-tile-art { flex: 0 0 110px; background: #fff; border: 1px solid var(--line); }
.swap-now p { margin: 0; flex: 1; min-width: 120px; font-size: .82rem; color: var(--muted); }
.swap-now .btn { cursor: pointer; }

/* Hledání v bance — sto třicet ikon se v okně neprolistuje. */
.picker-find { margin: 4px 0 12px; }
.picker-find input {
  width: 100%; font: inherit; padding: .5em .8em;
  border: 1px solid var(--line); border-radius: 999px; background: #fff;
}
.picker-find input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.icon-bank-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 8px; }
.icon-choice {
  display: grid; place-items: center; aspect-ratio: 1; padding: 0; cursor: pointer;
  background: #fff; border: 1px solid var(--line); border-radius: 10px; color: var(--ink);
}
.icon-choice svg { width: 58%; height: 58%; }
.icon-choice:hover { border-color: var(--accent); }

@media (max-width: 700px) {
  .icon-bank-grid { grid-template-columns: repeat(5, 1fr); }
}

/* ---- přepínač „doporučeno" ------------------------------------------------
   Drží stav, a tak vypadá jinak než akce vedle: zapnutý je tónovaný, ne
   plný. Ikona i text se mění spolu — samotná barva by přepnutí neřekla
   tomu, kdo barvy nerozlišuje. */
.btn.star { display: inline-flex; align-items: center; gap: 6px; }
.btn.star svg { width: 15px; height: 15px; flex: none; }
.btn.star[aria-pressed="true"] {
  background: var(--accent-sk); border-color: var(--accent-ln); color: var(--accent-d);
}
.btn.star[aria-pressed="true"]:hover { border-color: var(--accent); }

/* ==========================================================================
   Newsletter
   ==========================================================================
   Obrazovka čísla je táž `.editor` jako u akce, jen o jednom sloupci: číslo
   nemá nic, co by stálo vedle textu, a formulář roztažený přes celou šířku
   monitoru se špatně čte. */
.editor-grid.one { grid-template-columns: minmax(0, 1fr); }
.editor-grid.one .editor-col { max-width: 760px; }

/* Náhled zprávy. Rám, ne vykreslení do stránky: e-mail má vlastní styly na
   `body` a v administraci by se s ní popral. */
.nl-preview {
  width: 100%; height: 68vh; border: 1px solid var(--line);
  border-radius: 12px; background: #fff;
}

/* ---- náhled vedle formuláře ------------------------------------------------
   Číslo je jeden úzký sloupec políček, takže vpravo zbývalo prázdno — a přesně
   tam náhled patří, stejně jako u úprav webu. Zpráva se kreslí na 600 px, což
   se do sloupce vejde v pravé velikosti; nezmenšuje se, na rozdíl od náhledu
   stránky.

   **Hranice musí sedět s `PV_MIN_WIN` v admin.js.** Pod ní panel mizí a zbývá
   tlačítko „Náhled" s oknem — v užším sloupci by z e-mailu byl proužek. */
@media (min-width: 1201px) {
  .editor-grid.one.nl-grid { grid-template-columns: minmax(0, 760px) minmax(400px, 1fr); }
  .editor-bar .nl-narrow { display: none; }
}
.nl-side {
  position: sticky; top: calc(var(--topbar-h) + 20px);
  display: flex; flex-direction: column;
  height: calc(100vh - var(--topbar-h) - 40px);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  overflow: hidden;
}
.nl-side-head {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; border-bottom: 1px solid var(--line);
}
.nl-side-head b { flex: 1; min-width: 0; font-size: .9rem; }
.nl-side-stage { position: relative; flex: 1; min-height: 0; background: #fff; }
.nl-side-stage .nl-preview {
  width: 100%; height: 100%; border: 0; border-radius: 0; display: block;
}
.nl-side-stage::before {
  content: "Načítám náhled…"; position: absolute; inset: 0;
  display: grid; place-items: center; font-size: .85rem; color: var(--muted);
  background: var(--card);
}
.nl-side-stage.is-loaded::before { display: none; }
/* Nové číslo ještě nikde není, tak není co vykreslit — a „Načítám" by lhalo. */
.nl-side-stage.is-blank::before { content: "Náhled se ukáže po uložení."; }
.nl-side-foot {
  margin: 0; padding: 8px 12px; border-top: 1px solid var(--line);
  background: var(--bg); font-size: .76rem; color: var(--muted);
}
@media (max-width: 1200px) {
  .nl-side { display: none; }
}

/* Rozeslané číslo k přečtení. Text v něm je HTML z editoru, takže potřebuje
   vlastní sazbu — jinak by odstavce splynuly do jednoho bloku. */
.rt-read { font-size: .95rem; line-height: 1.65; color: var(--ink); }
.rt-read h2 { font-size: 1.15rem; margin: 18px 0 8px; }
.rt-read h3 { font-size: 1rem; margin: 16px 0 6px; }
.rt-read p, .rt-read ul, .rt-read ol { margin: 0 0 10px; }
.rt-read img { max-width: 100%; height: auto; border-radius: 10px; }
.rt-read blockquote {
  margin: 12px 0; padding-left: 14px; border-left: 3px solid var(--line);
  color: var(--muted);
}

/* Dvě čísla vedle sebe ve widgetu plochy. */
.wg-split { display: flex; gap: 26px; flex-wrap: wrap; }
.wg-split > div { display: flex; flex-direction: column; }
.wg-big { font-size: 1.6rem; line-height: 1.1; color: var(--ink); }

/* Odhlášená adresa v seznamu — zůstává čitelná, jen ustoupí. */
tr.off td { opacity: .58; }

/* Nepotvrzené adresy u přepínače „Odběratelé". Vedle počtu odebírajících,
   ne místo něj — jsou to dvě různá čísla a splynout nesmějí. */
.chip-n.warn { background: var(--warn-bg); color: var(--warn); margin-left: 4px; }
