/* FinVize component library - docs/design.md, section 4.
 *
 * The @font-face declarations live in fonts.css, generated by
 * tools/fetch_fonts.py, and are linked before this file. Fonts are self-hosted
 * (CLAUDE.md bod 9): a Google Fonts link would hand the visitor's IP address
 * to a processor we do not list, and the CSP forbids any other origin anyway.
 */

/* ---------------------------------------------------------------- base --- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--tx);
  font-family: var(--font-body);
  font-size: var(--fs-16);
  line-height: var(--lh-body);
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
  line-height: var(--lh-heading);
  margin: 0 0 var(--sp-3);
}

/* Nadpis stránky o krok dolů (varianta B, zvolil zadavatel 17. 8. 2026).
 * „Přehled“ v 38 px zabíral pruh přes celou šířku a nic neříkal — čtenář ví,
 * kde je, z levého menu, které tu položku má zvýrazněnou. Nadpis je popisek,
 * ne obsah.
 *
 * **Posouvá se komponenta po škále, nepřepisuje se token.** design.md §2
 * škálu vyjmenovává a říká „nic mezi těmi kroky"; změnit hodnotu `--fs-38` by
 * znamenalo, že 38 px v dokumentu a v kódu jsou dvě různá čísla. Krok dolů
 * dělá −21 %, ne −30 %, jak varianta B slibovala — mezi 24 a 30 žádný krok
 * není a vyrábět ho kvůli jednomu nadpisu se nevyplatí.
 *
 * `h2` a `h3` zůstávají: 30 / 24 / 19 je pořád čitelná hierarchie, kdežto
 * posunout celou řadu by srazilo `h3` na velikost běžného textu. */
h1 {
  /* Tokeny stylu se záložní hodnotou škály: Výchozí drží 30 / 24. */
  font-size: var(--h1-size, var(--fs-30));
}
h2 {
  font-size: var(--h2-size, var(--fs-24));
}
h3 {
  font-size: var(--fs-19);
}

p {
  margin: 0 0 var(--sp-3);
}

a {
  color: var(--acc);
}

/* Focus is always visible. design.md 3 forbids `outline: none` outright. */
:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

/* Screen-reader-only, but still in the accessibility tree. Never
 * `display: none` - the data table under every chart depends on this
 * (design.md 4.4 bod 7). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* All numbers line up in a column. */
.num,
td.num,
.fv-metric__value,
.fv-result__value {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------- environment banner --- */
/* 12.6b bod 6: permanent, and impossible to mistake for the product. */

.fv-envbar {
  background: var(--acc2);
  color: var(--on-gold);
  font-size: var(--fs-13);
  font-weight: 600;
  padding: var(--sp-1) var(--sp-4);
  text-align: center;
}

/* Host (§3.3, 10. 9. 2026): trvalý pruh sdíleného plánu, táž mechanika jako
 * pruh testovacího prostředí, jen v barvě linky, ne zlaté. Nejde sbalit. */
.fv-guestbar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--sp-1) var(--sp-4);
  background: var(--surf2);
  color: var(--tx);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-13);
  font-weight: 600;
  padding: var(--sp-1) var(--sp-4);
}

.fv-guestbar__form {
  display: inline;
}

.fv-guestbar__link {
  font: inherit;
  font-weight: 500;
  color: var(--acc);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
}

/* Co host nemění, to nevidí: každý formulář s POST bez `data-guest-ok`.
 * Není to kontrola, ta je na serveru (`app.auth.guest`); je to pořádek na
 * stránce, aby host nemačkal tlačítka, která ho odmítnou. */
body.is-guest form[method="post"]:not([data-guest-ok]):not([action^="/scenare"]) {
  display: none;
}

/* Varianty a simulace host zkouší (11. 9. 2026): formuláře blueprintu
 * `scenare` (založení, úprava, přepnutí, páky v pruhu) vidí, jen smazání
 * varianty ne, to mu server odmítne. */
body.is-guest form[action^="/scenare"][action$="/smazat"] {
  display: none;
}

/* --------------------------------------------------------- app shell --- */

.fv-shell {
  display: grid;
  grid-template-columns: var(--w-menu) minmax(0, 1fr);
  min-height: 100vh;
}

.fv-shell[data-menu="collapsed"] {
  grid-template-columns: var(--w-menu-collapsed) minmax(0, 1fr);
}

.fv-main {
  max-width: var(--w-content);
  padding: var(--sp-6);
  min-width: 0;
}

/* ------------------------------------------------ 4.1 left navigation --- */

/* The menu is its own scroll region, not part of the page's.
 *
 * It used to travel with the content: on a long plan page the seven entries,
 * the nineteen parts and the way out of the application all scrolled off the
 * top, so navigating meant scrolling back up first. Sticky and one viewport
 * tall, it stays where it is put; `fv-nav__scroll` below takes the overflow
 * when nineteen parts do not fit.
 *
 * `position: sticky` rather than `fixed` so the column keeps its place in the
 * grid - a fixed menu would need the content to be indented by hand, and the
 * two would drift apart at the first change to the width. */
.fv-nav {
  /* Podání menu podle grafického stylu (15. 9. 2026 večer): výplň, linka,
   * stín a rozostření jsou tokeny `--panel-*`, Výchozí dává dnešní podobu. */
  background: var(--panel-bg);
  border-right: var(--panel-bw) solid var(--panel-line);
  box-shadow: var(--panel-shadow);
  backdrop-filter: var(--panel-blur);
  -webkit-backdrop-filter: var(--panel-blur);
  padding: var(--sp-4) var(--sp-3);
  /* The handle lives on the right edge, so the entries stop before it. Not a
   * negative margin over the top of them: the handle is on top and would
   * swallow the last few pixels of every link - which is where the tick and
   * the count sit. */
  padding-right: var(--w-grip);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  position: sticky;
  top: 0;
  height: 100vh;
  z-index: 20;
}

/* The brand and the view settings: the header of the menu. They stay while
 * the entries move, which is what makes them read as a header rather than as
 * the first two things in a list. */
.fv-nav__head {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  flex: 0 0 auto;
}

/* Everything that scrolls. `min-height: 0` because a flex item will not
 * shrink below its content otherwise, and without it the overflow lands on
 * the page instead of here - which is the bug this whole block replaces. */
.fv-nav__scroll {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* Thin and in the menu's own colours: a default Windows scrollbar is a
   * 15 px grey slab between the entries and the handle, and the menu is the
   * one place on the page where a scrollbar is now permanent. */
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

/* 7: centred, not sitting on a shared baseline. The mark is a shape and the
 * wordmark is type; aligning their baselines pushed the mark down against the
 * descender line and it read as having slipped. */
.fv-nav__brand {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-display);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
  font-size: var(--fs-19);
  color: inherit;
  text-decoration: none;
}

/* design.md 7.3: only the wordmark reacts to the theme, never the mark. */
.fv-nav__brand .fin {
  color: var(--tx);
}
.fv-nav__brand .vize {
  color: var(--acc);
}

/* 9, 10: the view settings on one quiet row under the brand.
 *
 * They were a toggle in the strip above the plan and nothing at all: the strip
 * is about one plan while the theme is a property of the whole application. So:
 * icons, together, where a person looks for settings about the view they are
 * in. Collapsing the menu **left** this row (12. 8. 2026) - it is not a
 * setting about how the application looks but about how wide it is, and it now
 * sits on the edge it moves. */
.fv-nav__tools {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  margin-top: calc(-1 * var(--sp-3));
}

/* --- the handle that collapses the menu ------------------------------- */
/* On the border, the full height of the menu, and quiet until it is wanted.
 * The 22 px chevron it replaces was correct and invisible: it sat among the
 * view settings, where nothing suggests that one of the three changes the
 * layout. Here the target is the whole edge - twelve pixels wide and a
 * viewport tall - so it is hard to miss and hard to hit by accident. */
.fv-nav__grip {
  position: absolute;
  top: 0;
  right: -1px;
  bottom: 0;
  width: var(--w-grip);
  padding: 0;
  border: 0;
  background: none;
  color: var(--tx2);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
}

/* The grip itself: a short rounded rule on the border, the shape every
 * draggable divider has. It is the only thing visible at rest. */
.fv-nav__grip-bar {
  position: absolute;
  top: 50%;
  right: 5px;
  transform: translateY(-50%);
  width: 3px;
  height: 44px;
  border-radius: 999px;
  background: var(--line);
  transition: background var(--transition), height var(--transition);
}

.fv-nav__grip:hover .fv-nav__grip-bar,
.fv-nav__grip:focus-visible .fv-nav__grip-bar {
  background: var(--acc);
  height: 72px;
}

/* The caret appears on the grip only when it is reached for; at rest the rule
 * alone says "this edge moves" without adding a glyph to every screen. */
.fv-nav__grip .fv-nav__chevron {
  position: relative;
  font-size: var(--fs-15);
  line-height: 1;
  opacity: 0;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: 999px;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity var(--transition), transform var(--transition);
}

.fv-nav__grip:hover .fv-nav__chevron,
.fv-nav__grip:focus-visible .fv-nav__chevron {
  opacity: 1;
  color: var(--tx);
  border-color: var(--acc);
}

.fv-nav__grip:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: -2px;
}

@media (prefers-reduced-motion: reduce) {
  .fv-nav__grip-bar,
  .fv-nav__grip .fv-nav__chevron {
    transition: none;
  }
}

.fv-nav__icon-button {
  background: none;
  border: 1px solid transparent;
  border-radius: var(--r-field);
  color: var(--tx2);
  cursor: pointer;
  font-size: var(--fs-15);
  line-height: 1;
  padding: var(--sp-2);
  transition: background var(--transition), color var(--transition);
}

.fv-nav__icon-button:hover {
  background: var(--surf2);
  color: var(--tx);
}

/* Přepínač vzhledu se třemi stavy (zadavatel 9. 9. 2026): světlý, podle
 * zařízení, tmavý. Malý ovál, aby se vešel na řádek nastavení vedle skrytí
 * částek; ve svinutém menu se stavy řadí pod sebe jako zbytek řádku. */
.fv-theme {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--line);
  border-radius: var(--r-chip);
  background: var(--surf2);
}

.fv-theme__option {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--tx2);
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}

.fv-theme__option:hover {
  color: var(--tx);
}

.fv-theme__option:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 1px;
}

/* Vybraný stav má výplň kolečka, ne jen jiný odstín (WCAG 1.4.1). */
.fv-theme__option[aria-pressed="true"] {
  background: var(--acc);
  color: var(--bg);
}

.fv-theme__icon {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

[data-menu="collapsed"] .fv-theme {
  flex-direction: column;
  align-self: center;
  border-radius: 14px;
}

/* Přepínač Admin / Uživatel vedle značky. Tichý jako sousední ikony — je to
 * cesta jinam, ne akce, a ve svinutém menu se schová s popiskami. */
.fv-nav__switch {
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  color: var(--tx2);
  font-size: var(--fs-12);
  letter-spacing: 0.02em;
  padding: var(--sp-1) var(--sp-2);
  text-decoration: none;
  text-transform: uppercase;
  transition: background var(--transition), color var(--transition);
  white-space: nowrap;
}

.fv-nav__switch:hover {
  background: var(--surf2);
  color: var(--tx);
}

/* Ve svinutém menu se schová jako ostatní popisky — dvě písmena v rámečku
 * na osmdesáti pixelech vypadají jako chyba, ne jako přepínač. */
[data-menu="collapsed"] .fv-nav__switch {
  display: none;
}

/* On, and saying so without colour alone (WCAG 1.4.1). */
.fv-nav__icon-button[aria-pressed="true"] {
  background: var(--surf2);
  border-color: var(--acc);
  color: var(--tx);
}

/* Points the way the menu will go. Not animated for anybody who asked for
 * less motion - it is a rotation of a glyph, not information. */
.fv-nav__chevron {
  display: inline-block;
  transition: transform var(--transition);
}

[data-menu="collapsed"] .fv-nav__chevron {
  transform: rotate(180deg);
}

/* Collapsed, the row is as narrow as the menu and the three stack. */
[data-menu="collapsed"] .fv-nav__tools {
  flex-direction: column;
  align-items: stretch;
}

@media (prefers-reduced-motion: reduce) {
  .fv-nav__chevron {
    transition: none;
  }
}

/* 2: sign-out is a form, so its control is a button that has to pass for the
 * links above it. Everything a <button> brings of its own is undone here. */
.fv-nav__link--button {
  background: none;
  border: 0;
  border-left: 3px solid transparent;
  font: inherit;
  text-align: left;
  width: 100%;
  cursor: pointer;
}

.fv-nav__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.fv-nav__link {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-field);
  color: var(--tx);
  text-decoration: none;
  border-left: 3px solid transparent;
  transition: background var(--transition), color var(--transition);
}

.fv-nav__link:hover {
  background: var(--surf2);
}

/* The active item is recognisable when collapsed too - a green bar, not just
 * a tinted icon (design.md 4.1). */
.fv-nav__link[aria-current="page"] {
  background: var(--surf2);
  border-left-color: var(--acc);
}

.fv-nav__icon {
  flex: 0 0 18px;
  width: 18px;
  height: 18px;
}

.fv-nav__count {
  margin-left: auto;
  background: var(--acc2);
  color: var(--on-gold);
  border-radius: var(--r-chip);
  font-size: var(--fs-12);
  padding: 0 var(--sp-2);
}

[data-menu="collapsed"] .fv-nav__label,
[data-menu="collapsed"] .fv-nav__group,
[data-menu="collapsed"] .fv-nav__brand .name {
  display: none;
}

[data-menu="collapsed"] .fv-nav__count {
  margin-left: 0;
}

/* 1: the short list. `display:none` rather than a shorter list from the
 * server, so the toggle costs no request and a reader without scripting keeps
 * all nineteen. */
[data-parts="collapsed"] .fv-nav__part[data-extra] {
  display: none;
}

.fv-nav__group-title {
  font-family: var(--font-label);
  font-size: var(--fs-12);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--tx2);
  margin: 0 0 var(--sp-2);
}

/* Rozbalit / Sbalit části plánu - a control, not a twentieth destination.
 *
 * It used to be a `fv-nav__link` in the list, indistinguishable from the parts
 * above it, with a second link ("Přehled částí") under it pointing at `/plan`
 * - which is already the second entry of the main menu. The link is gone and
 * this is what a control looks like: a rule across the group with a caret and
 * a small label on it, quieter than anything it can reveal. */
.fv-nav__parts-toggle {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  margin-top: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  background: none;
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
  color: var(--tx2);
  font: inherit;
  font-size: var(--fs-12);
  letter-spacing: 0.04em;
  text-align: left;
  cursor: pointer;
  transition: color var(--transition);
}

.fv-nav__parts-toggle:hover {
  color: var(--tx);
}

.fv-nav__parts-caret {
  display: inline-block;
  line-height: 1;
  transition: transform var(--transition);
}

/* Points at what pressing it will do: closed, it opens downwards. */
[data-parts="collapsed"] .fv-nav__parts-caret {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .fv-nav__parts-caret {
    transition: none;
  }
}

/* ---------------------------------------------------- 4.1b top strip --- */

/* The strip stays at the top of the page it belongs to.
 *
 * It carries the scenario, the basis, the view and the three numbers - the
 * things a reader checks *while* reading further down, which is exactly when
 * it used to be gone. Sticky rather than fixed for the same reason as the
 * menu: it keeps its place in the flow, so nothing below it needs a hand-set
 * offset.
 *
 * `z-index` below the menu's: where they meet, the menu is in front. */
.fv-topbar {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  flex-wrap: wrap;
  background: var(--panel-bg);
  border-bottom: var(--strip-bw) solid var(--panel-line);
  box-shadow: var(--panel-shadow);
  backdrop-filter: var(--panel-blur);
  -webkit-backdrop-filter: var(--panel-blur);
  padding: var(--sp-3) var(--sp-5);
  position: sticky;
  top: 0;
  z-index: 15;
}

/* Kotvy počítají s přilepeným pruhem (zadavatel 1. 9. 2026, tlačítko
 * Aktualizovat: „hodí mě to na konec toho malého formuláře"). Prohlížeč
 * sroluje cíl kotvy na horní hranu okna, kterou ale zakrývá dvouřadý pruh,
 * takže byl vidět konec karty místo začátku. Odsazení platí pro všechna
 * kotvená id (#aktualizovat, #pridat, odkazy na pole z výčtu vad); rezerva
 * nad výšku pruhu jen posadí cíl o kus níž, což nevadí. */
[id] {
  scroll-margin-top: 150px;
}

/* 4.13 turned the **whole strip** gold when the view was not "average", and
 * on the deployed site that read as a fault rather than as a state: seven
 * controls, three result numbers and a chart rail all sitting on a gold field,
 * every one of them coloured for a dark surface. Rejected by the owner
 * 12. 8. 2026.
 *
 * What §5.12 actually requires is that the pessimistic view can never be
 * mistaken for the plan, and that is kept - and made louder - by two things
 * that are still gold: the chosen option in the switch, and the full-width
 * notice under it (A11, §12.6), which says the same thing in words. Both are
 * small surfaces designed for `--on-gold`. The strip itself stays as it is on
 * every other page, so the controls on it stay readable.
 *
 * Recorded in STAV.md: `zadani.md` §5.12 and `design.md` §4.13 still describe
 * the old treatment. */
.fv-viewswitch .fv-basis__option[aria-pressed="true"] {
  background: var(--acc2);
  color: var(--on-gold);
  font-weight: 600;
}

.fv-topbar__spacer {
  margin-left: auto;
}

/* A (zadavatel 20. 8. 2026, nahrazuje ranní P5): pruh má dvě řady. Nahoře
 * teče ovládání od „Počítá se přes…" doleva, čtyři čísla výsledku stojí
 * v druhé řadě vlevo. Plná šířka toku znamená, že se ovládání láme ve
 * vlastních řadách a čísla nikdy nic neodsune — to byla vada obou
 * předchozích rozložení. */
/* Řada čísel s tlačítky (zadavatel 7. 9. 2026 večer: „vybrat číslo, z čeho
 * se skládá, kde najdu a průvodce aplikací zrovnej do stejné výšky jako ty
 * 4 velké hodnoty k jejich spodnímu okraji“). Obal `fv-topbar__row` je
 * druhá řada pruhu: čísla vlevo berou zbytek řádku (šířka přesně po obsahu
 * se zalomením uvnitř narážela na zaokrouhlení), dvojice Kde najdu?
 * a Průvodce vpravo, a všechno, co v řadě je, sedí na **posledním účaří**
 * čísel, tedy na účaří velké hodnoty, ne popisku nad ní. `flex-end` je
 * záloha pro prohlížeč bez `last baseline`. */
.fv-topbar__row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  align-items: last baseline;
  gap: var(--sp-4);
  flex: 1 1 100%;
  min-width: 0;
}

.fv-topbar__row > .fv-result {
  flex: 1 1 auto;
  min-width: 0;
  align-items: flex-end;
  align-items: last baseline;
}

.fv-topbar__row > .fv-topbar__help {
  margin-left: auto;
}

.fv-topbar__flow {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  flex-wrap: wrap;
  flex: 1 1 100%;
  min-width: 0;
}

/* B (zadavatel 20. 8. 2026): jedna velikost pro všechno ovládání pruhu.
 * „Rychlé změny" a „Přepnout" byla plná tlačítka (základní písmo, padding
 * sp-2/sp-4) mezi přepínači o fs-13 — a `.fv-basis` si z formulářů nesl
 * `margin-top`, takže seděl níž než zbytek řady. */
.fv-topbar__flow .fv-button {
  font-size: var(--fs-13);
  padding: var(--sp-1) var(--sp-3);
  min-height: 2rem;
}

.fv-topbar__flow select {
  font-size: var(--fs-13);
  padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  min-height: 2rem;
}

.fv-topbar__flow .fv-basis {
  margin-top: 0;
}

/* Průvodce aplikací vpravo nahoře (zadavatel 30. 8. 2026). V řadě ovládání
 * plánového pruhu ho k pravému okraji odsouvá vlastní auto margin; ve
 * scénářovém stojí za `fv-topbar__spacer`, který dělá totéž — dvě auto
 * marginy v jedné řadě by si volné místo rozdělily a tlačítko by stálo
 * uprostřed. Ikona jde s výškou textu, aby řadu nezvyšovala. */
.fv-topbar__guide {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-13);
  padding: var(--sp-1) var(--sp-3);
  min-height: 2rem;
  white-space: nowrap;
}

/* Kde najdu? a Průvodce aplikací jako dvojice (zadavatel 7. 9. 2026: „Kde
 * najdu a Průvodce aplikací se nevejde na horní řádek ani na monitoru
 * počítače“). Do té doby držel pravý okraj řady sám Kde najdu? a Průvodce,
 * když se nevešel, spadl na začátek další řady vlevo. Obal se láme jako
 * celek. **V plánovém pruhu stojí na řadě čísel vpravo** (7. 9. 2026
 * odpoledne: řada ovládání potřebovala i se stropem roletky 1586 px, na
 * monitoru s Windows zvětšením 125 % má 1240 px, kdežto řada čísel má
 * vpravo přes 800 px volných); k pravému okraji ji odsouvá auto margin za
 * čísly. Ve scénářovém pruhu, kde čísla nejsou, to dělá `fv-topbar__spacer`
 * před ní (dvě auto marginy v jedné řadě by si volné místo rozdělily). */
.fv-topbar__help {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-4);
}


.fv-topbar__guide-icon {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
}

/* Malé tlačítko pruhu (zadavatel 7. 9. 2026 večer: „zvýraznil při najetí
 * myší a zmenšil font i jejich velikost … ty dva odkazy bych také změnil na
 * tlačítka“). Jedna podoba pro Vybrat číslo, Z čeho se skládají, Kde najdu?
 * a Průvodce aplikací: menší písmo i výška než ovládání pruhu, rám v barvě
 * linky, při najetí myší zelený rám, text i podklad. Obsah sedí na účaří,
 * takže tlačítko drží účaří velkých hodnot; ikona jde o dva body dolů, aby
 * na něm stála jako písmeno. Stojí po `.fv-topbar__guide`, které přebíjí. */
.fv-topbar__action {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-1);
  font: inherit;
  font-size: var(--fs-12);
  font-weight: 500;
  line-height: 1.2;
  color: var(--tx2);
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  padding: 3px var(--sp-2);
  min-height: 0;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition),
    background var(--transition);
}

.fv-topbar__action:hover {
  color: var(--acc);
  border-color: var(--acc);
  background: var(--surf2);
}

.fv-topbar__action:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

.fv-topbar__action .fv-topbar__guide-icon {
  width: 14px;
  height: 14px;
  /* Vystředěná, ne na účaří: na účaří ikona zvedala řádek o tři body
   * a dvojice byla vyšší než Vybrat číslo vedle ní. */
  align-self: center;
}

@media (prefers-reduced-motion: reduce) {
  .fv-topbar__action {
    transition: none;
  }
}

/* Trojúhelník seznamu u `summary` přidával šířku navíc; šipka za textem
 * říká totéž a drží tlačítko v řadě. */
.fv-levers > summary {
  list-style: none;
}

.fv-levers > summary::-webkit-details-marker {
  display: none;
}

.fv-levers > summary::after {
  content: " ▾";
}

/* §5.4 bod 6: the thin axis under the strip, clickable, leading to the
 * timeline. It is the last item of a wrapping flex row and nothing gave it a
 * width, so it was laid out **0 px wide** - present in the markup, invisible
 * on every page, and a link nobody could hit. Found 12. 8. 2026 measuring the
 * strip; `flex-basis: 100%` is what the row needed to be told. */
.fv-timeline-strip {
  height: 4px;
  background: linear-gradient(90deg, var(--acc), var(--acc2));
  border: 0;
  margin: 0;
  cursor: pointer;
}

.fv-timeline-link {
  flex: 1 0 100%;
}

/* --- sbalený horní pruh (zadavatel 13. 9. 2026) -------------------------- */
/* „Dejme možnost sbalit horní lištu, nějak rozumně, aby bylo jasné, jaké
 * volby právě platí a zmenšeniny těch hlavních čísel a ovládacích prvků.“
 * Stav nese `<html data-topbar="collapsed">` (theme.js před prvním
 * vykreslením, app.js při přepnutí). Sbalený pruh je jedna nízká řada:
 * vlevo roletka variant se zlatým bodem a z každého přepínače jen volba,
 * která platí, jako štítek (u pohledu zůstává zlatá jako rozbalená),
 * odznak dokončenosti, pak čtyři čísla v malém (popisek nad hodnotou)
 * a vpravo tlačítko k rozbalení. Zlatý pruh pohledu (§12.6, A11) a tenká
 * osa (§5.4 bod 6) zůstávají vždycky. Jen od 1025 px: pod tím skládá
 * ovládání za tlačítko Zobrazení `data-narrow-collapse`, a dvě mechaniky
 * na jednom pruhu by se praly. */
.fv-topbar__fold {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: none;
  color: var(--tx2);
  cursor: pointer;
  flex: 0 0 auto;
  transition: color var(--transition), border-color var(--transition),
    background var(--transition);
}

/* Na řadě čísel plánového pruhu drží spodní hranu s malými tlačítky (ikona
 * účaří nemá); ve scénářovém pruhu, kde je přímé dítě řady ovládání, sedí
 * na střed jako ostatní. */
.fv-topbar__row > .fv-topbar__fold {
  align-self: flex-end;
}

.fv-topbar > .fv-topbar__fold {
  align-self: center;
}

.fv-topbar__fold:hover {
  color: var(--acc);
  border-color: var(--acc);
  background: var(--surf2);
}

.fv-topbar__fold:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

.fv-topbar__fold-icon {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Šipka ukazuje, kam se pruh pohne: nahoru sbalit, dolů rozbalit. */
.fv-topbar__fold[aria-expanded="false"] .fv-topbar__fold-icon {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .fv-topbar__fold {
    transition: none;
  }
}

@media (max-width: 1024px) {
  .fv-topbar__fold {
    display: none;
  }
}

@media (min-width: 1025px) {
  /* Míry jsou spočítané na 1280 px s rozbaleným menu (pruh má 1029 px,
   * změřeno 13. 9. 2026): ovládání 450 px, čtyři čísla 455 px, tlačítko
   * vpravo mimo tok. S běžnými mezerami pruhu chybělo třicet bodů a řada
   * čísel spadla pod ovládání, což je přesně to, co sbalení nemá dělat. */
  html[data-topbar="collapsed"] .fv-topbar {
    padding: var(--sp-2) calc(28px + 2 * var(--sp-3)) var(--sp-2) var(--sp-4);
    gap: var(--sp-2) var(--sp-4);
  }

  /* Tok ovládání přestane brát celou šířku, takže řada čísel stojí vedle
   * něj; když se vedle nevejde, zalomí se pod něj celá (`flex-shrink: 0`,
   * jinak by se smrskla a čísla přetekla z pruhu ven). */
  html[data-topbar="collapsed"] .fv-topbar__flow {
    flex: 0 1 auto;
    gap: var(--sp-2);
  }

  html[data-topbar="collapsed"] .fv-topbar__row {
    flex: 1 0 auto;
    min-width: auto;
    align-items: center;
    gap: var(--sp-3);
  }

  html[data-topbar="collapsed"] .fv-topbar__row > .fv-result {
    flex: 0 1 auto;
    align-items: center;
  }

  /* Tlačítko stojí ve sbaleném pruhu mimo tok, na středu pravého okraje:
   * v toku by jeho šířka a mezera scházely řadě čísel, a když se řada přece
   * zalomí pod ovládání, zůstává tlačítko na místě, kde ho oko čeká. */
  html[data-topbar="collapsed"] .fv-topbar__fold {
    position: absolute;
    top: 50%;
    right: var(--sp-3);
    transform: translateY(-50%);
    margin: 0;
  }

  /* Co ve sbaleném pruhu není. */
  html[data-topbar="collapsed"] .fv-levers,
  html[data-topbar="collapsed"] .fv-topbar__flow .fv-tip,
  html[data-topbar="collapsed"] .fv-viewswitch__label,
  html[data-topbar="collapsed"] .fv-topbar .fv-basis__option[aria-pressed="false"],
  html[data-topbar="collapsed"] .fv-topbar__help,
  html[data-topbar="collapsed"] .fv-result__pick,
  html[data-topbar="collapsed"] .fv-topbar__spacer {
    display: none;
  }

  /* Popisek roletky zůstává čtečce (`label for`), z obrazovky jde pryč. */
  html[data-topbar="collapsed"] .fv-topbar__scenario-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  /* Zmenšeniny ovládání: roletka o řád níž, z přepínačů štítek s platnou
   * volbou. Zlatou barvu vybraného pohledu nese dál pravidlo
   * `.fv-viewswitch .fv-basis__option[aria-pressed="true"]`. */
  html[data-topbar="collapsed"] .fv-topbar__flow select {
    font-size: var(--fs-12);
    min-height: 26px;
    padding: 2px var(--sp-2);
    max-width: 11rem;
  }

  html[data-topbar="collapsed"] .fv-topbar .fv-basis {
    padding: 0;
    border: 0;
  }

  html[data-topbar="collapsed"] .fv-topbar .fv-basis__option[aria-pressed="true"] {
    font-size: var(--fs-12);
    line-height: 1.2;
    padding: 4px 6px;
    border: 1px solid var(--line);
    border-radius: var(--r-chip);
  }

  html[data-topbar="collapsed"] .fv-viewswitch {
    gap: 0;
  }

  html[data-topbar="collapsed"] .fv-topbar__flow .fv-badge {
    font-size: var(--fs-12);
  }

  /* Zmenšeniny čísel: popisek nad hodnotou v jedné nízké řadě, nic se
   * neláme; když se čtveřice vedle ovládání nevejde, jde pod něj celá. */
  html[data-topbar="collapsed"] .fv-result {
    gap: var(--sp-3);
    flex-wrap: nowrap;
  }

  html[data-topbar="collapsed"] .fv-result__item {
    min-width: 0;
  }

  html[data-topbar="collapsed"] .fv-result__label {
    font-size: 10px;
    letter-spacing: 0.02em;
    line-height: 1.2;
    white-space: nowrap;
  }

  html[data-topbar="collapsed"] .fv-result__value {
    font-size: var(--fs-13);
    line-height: 1.3;
    white-space: nowrap;
  }

  html[data-topbar="collapsed"] .fv-result__delta {
    font-size: 10px;
  }
}

/* --------------------------------------------- 4.11 the three numbers --- */

/* Zalomení i nad 900 px (7. 9. 2026, změřeno při hledání místa pro dvojici
 * Kde najdu? a Průvodce): mezi 900 a zhruba 1100 px s rozbaleným menu měla
 * řada čtyř čísel a dvou odkazů 850 px a přetékala z pruhu ven, protože
 * nesměla zalomit. Na širokém okně se nic nemění, řada se vejde. */
.fv-result {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
}

.fv-result__item {
  min-width: 96px;
}

.fv-result__label {
  display: block;
  font-family: var(--font-label);
  font-size: var(--fs-12);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tx2);
}

.fv-result__value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-24);
}

/* "Calculating": a neutral rectangle. Never the old value, which would lie,
 * and never zero, which would frighten (design.md 4.11). */
.fv-result__value[data-state="pending"] {
  display: inline-block;
  min-width: 4ch;
  color: transparent;
  background: var(--surf2);
  border-radius: var(--r-field);
  animation: fv-pulse 1.4s ease-in-out infinite;
}

@keyframes fv-pulse {
  50% {
    opacity: 0.55;
  }
}

.fv-result__delta {
  display: block;
  font-family: var(--font-data);
  font-size: var(--fs-12);
}
.fv-result__delta[data-dir="up"] {
  color: var(--acc);
}
.fv-result__delta[data-dir="down"] {
  color: var(--warn);
}

@media (max-width: 900px) {
  /* design.md 4.11: below 900 px the strip moves under the header as a
   * horizontal band of three cards. Everything else in the strip stacks with
   * it - a row of seven controls has nowhere to go on a phone, and letting it
   * overflow sideways puts the result numbers off the screen entirely. */
  .fv-topbar {
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
  }

  .fv-topbar__spacer {
    display: none;
  }

  .fv-topbar > * {
    max-width: 100%;
  }

  .fv-result {
    width: 100%;
    justify-content: space-between;
    gap: var(--sp-3);
    flex-wrap: wrap;
  }

  .fv-result__item {
    min-width: 0;
    flex: 1;
  }

  .fv-result__value {
    font-size: var(--fs-19);
  }

  /* The pairs and triples of switches wrap instead of pushing the row wide. */
  .fv-basis {
    flex-wrap: wrap;
  }
}

/* Čtyři čísla na telefonu po dvou (zadavatel 11. 9. 2026: „ty čtyři hlavní
 * čísla text je svisle, nečitelné“). Čtyři položky v jedné řadě měly na
 * 375 px každá kolem 70 px: popisek se lámal po slovech a hodnota
 * (`overflow-wrap: anywhere`) po písmenech. Dvě na řádek dají každé půl
 * šířky; odkazy Vybrat číslo a Z čeho se skládají zůstávají na vlastním
 * řádku vpravo. */
@media (max-width: 640px) {
  .fv-result__item {
    flex: 1 1 40%;
  }
}

/* ------------------------------------------------------- 4.8 / cards --- */

.fv-card {
  /* Okraj, výplň, stín a odsazení podle grafického stylu (15. 9. 2026);
   * Výchozí dává 1 px linku, plochu karty, bez stínu a odsazení 20 px. */
  background: var(--surf-c);
  border: var(--bw) solid var(--line-c);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: var(--card-pad);
}

/* 5b: a card that is a link is not painted like one.
 *
 * `u-plain-link` dropped the underline and nothing else, so every word inside
 * inherited `a { color: var(--acc) }`. On the analysis cards that is a
 * paragraph of body text in accent green - **4.05:1 against the light theme's
 * surface**, below the 4.5:1 of WCAG 2.2 AA, and why they read as
 * half-erased. Dark measures 6.71:1 and still looks washed out beside its own
 * headings.
 *
 * Here rather than in `u-plain-link`, which also sits on the badges: those
 * carry `--on-gold` on gold and `inherit` would break them the other way. */
a.fv-card {
  display: block;
  color: var(--tx);
  transition: border-color var(--transition), background var(--transition),
    transform var(--transition);
}

/* What says it is clickable now that the colour does not. The keyboard gets
 * the same lift, on top of the outline `:focus-visible` already draws. */
a.fv-card:hover,
a.fv-card:focus-visible {
  border-color: var(--acc);
  background: var(--surf2);
  transform: translateY(var(--lift));
}

.fv-card__title {
  font-size: var(--fs-19);
  margin-bottom: var(--sp-2);
}

.fv-metric {
  display: block;
  color: inherit;
  text-decoration: none;
  /* Dlaždice je kontejner pro své číslo (7. 9. 2026), viz níž. */
  container-type: inline-size;
}

.fv-metric__label {
  font-family: var(--font-label);
  font-size: var(--fs-12);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tx2);
}

/* Číslo na dlaždici o krok dolů (varianta B). Klesá **míň než nadpis** a je to
 * záměr: nadpis je popisek, kdežto tohle je odpověď, kvůli které se na
 * stránku kouká. Padesát procent na obojí by z dlaždic udělalo seznam. */
/* Číslo jde s šířkou dlaždice (zadavatel 7. 9. 2026, snímek z tabletu:
 * „−345 897 Kč“ přeteklo mimo dlaždici). Na široké dlaždici 24 px jako
 * dřív; na úzké tolik, aby se nejdelší podoba částky („−99,9 mil. Kč“,
 * třináct znaků tabulkových číslic) vešla mezi okraje, nejméně 19 px,
 * tedy pořád víc než běžný text pod ním (`tests/test_branding.py`).
 * Kontejnerová jednotka, ne šířka okna: dlaždice je na tabletu úzká
 * kvůli dvěma sloupcům, ne kvůli obrazovce. */
.fv-metric__value {
  font-family: var(--font-display);
  font-weight: var(--fw-heading);
  /* Násobek podle stylu; Výchozí má 1, takže clamp platí beze změny. */
  font-size: calc(clamp(var(--fs-19), 10cqi, var(--fs-24)) * var(--tile-scale));
  display: block;
  margin: var(--sp-1) 0;
}

/* Věta pod číslem o krok dolů. Není to „běžný text“, který se zmenšovat
 * neměl — je to popisek k číslu, a v 15 px zabíral na dlaždici víc místa než
 * číslo samo. */
.fv-metric__context {
  color: var(--tx2);
  font-size: var(--fs-13);
  margin: 0;
}

/* Dlaždice, jejíž věta je varování (zadavatel 9. 9. 2026: když se simulace
 * nespustí, „by tam ta informace měla být dostatečně výrazně uvedena"). */
.fv-metric--pozor {
  border-color: var(--warn);
}

.fv-metric--pozor .fv-metric__context {
  color: var(--warn);
  font-weight: 600;
}

/* ------------------------------------------------------ 4.5 tooltip ---- */

.fv-tip {
  display: inline-block;
  position: relative;
}

.fv-tip__button {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: none;
  color: var(--tx2);
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}

/* Opens on click and on focus, not only on hover - touch devices and keyboards
 * have no hover (design.md 4.5). */
.fv-tip__body {
  /* Zalomení dlouhé věty: bublina drží šířku a text teče do řádků. Bez toho
   * dělal dlouhý obsah jeden řádek přes celou kartu (zadavatel 19. 8. 2026). */
  overflow-wrap: break-word;
  position: absolute;
  z-index: 20;
  top: calc(100% + var(--sp-1));
  left: 0;
  width: 260px;
  background: var(--surf2);
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  padding: var(--sp-3);
  font-size: var(--fs-13);
  color: var(--tx);
}

.fv-tip__body[hidden] {
  display: none;
}

/* Najetí myší bublinu ukáže hned (zadavatel 19. 8. 2026: „měly by se
 * objevovat hned při přejetí myší“). Klik a fokus zůstávají — dotyk a
 * klávesnice hover nemají, takže tohle je přídavek, ne náhrada. Čistě CSS:
 * `hidden` platí dál a po odjetí myši se bublina zase schová, pokud ji klik
 * neotevřel doopravdy. */
/* Jen tam, kde myš opravdu je (11. 9. 2026): dotyk najetí nemá, ale prohlížeč
 * na telefonu ho po klepnutí předstírá a bublina pak stála „najetá“ i po
 * klepnutí jinam. Na telefonu ji řídí jen klik a skript. */
@media (hover: hover) {
  .fv-tip:hover .fv-tip__body[hidden] {
    display: block;
  }
}

/* Můstek přes mezeru mezi tlačítkem a bublinou (zadavatel 10. 9. 2026:
 * „v tooltipu se objeví odkaz na slovník, ale nelze na to kliknout, tooltip
 * mizí“). Bublina stojí o `--sp-1` níž než tlačítko a myš cestou k odkazu
 * tu mezeru přejížděla: `.fv-tip` přestal být pod kurzorem, bublina se
 * schovala a odkaz s ní. Průhledný pruh nad bublinou drží najetí
 * nepřerušené; klik a fokus se nemění. */
.fv-tip__body::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(-1 * var(--sp-1) - 2px);
  height: calc(var(--sp-1) + 2px);
}

/* Pojem s výkladem (`term` v components.html): slovo samo je tlačítko,
 * tečkované podtržení říká, že se dá otevřít. Písmo i barva dědí z věty,
 * takže slovo nevypadá jako odkaz ani jako ovládací prvek. */
.fv-term {
  display: inline;
}

.fv-term__word {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: help;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}

.fv-term__word:hover,
.fv-term__word[aria-expanded="true"] {
  color: var(--acc);
}

/* ------------------------------------------------- 4.2 form controls --- */

.fv-field {
  display: block;
  margin-bottom: var(--sp-4);
}

.fv-field__label {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-15);
  font-weight: var(--fw-label);
  margin-bottom: var(--sp-2);
}

.fv-field__control {
  display: flex;
  align-items: center;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  padding: 0 var(--sp-3);
}

.fv-field__control:focus-within {
  border-color: var(--acc);
}

/* Schovaný obal pole (druhý faktor, nález zadavatele 4. 9. 2026): skript
 * šesti políček schová původní pole atributem `hidden`, jenže `display: flex`
 * výš má větší váhu než pravidlo prohlížeče pro `[hidden]`, takže pod
 * políčky zůstával prázdný široký pruh pro celý kód. Táž pojistka, jakou
 * má `.fv-otp[hidden]`. */
.fv-field__control[hidden] {
  display: none;
}


/* Oko u pole s heslem. Staví ho `app.js`, takže bez skriptu tenhle styl nemá
 * co obarvit — a to je záměr, ne opomenutí.
 *
 * Terč 40 px na výšku i na šířku: prst na dotyku potřebuje aspoň tolik, a
 * pole samo je vyšší, takže se to nikam nevejde jen tak tak. Vlastní obrys
 * při zaostření, protože pole kolem něj kreslí svůj vlastní na `focus-within`
 * a bez toho by nešlo poznat, jestli je uvnitř kurzor, nebo tlačítko. */
.fv-field__reveal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  margin-right: calc(var(--sp-3) * -1);
  padding: 0;
  border: 0;
  border-radius: var(--r-field);
  background: none;
  color: var(--tx2);
  cursor: pointer;
}

.fv-field__reveal:hover {
  color: var(--tx1);
}

.fv-field__reveal:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: -2px;
  color: var(--tx1);
}

.fv-field__reveal-icon {
  width: 1.25rem;
  height: 1.25rem;
}

/* Pole samo o sobě má **odlišné pozadí** (zadavatel 21. 8. 2026): v tabulce
 * benchmarků, v řádcích pozic, u bodů trajektorie nebo v pruhu pák stojí
 * bez obalu `.fv-field__control`, a bez pozadí nebylo poznat, že se tam dá
 * psát. Uvnitř obalu se pozadí vrací na nic — rámeček kreslí obal. */
.fv-field__input {
  flex: 1;
  min-width: 0;
  background: var(--field);
  border: 0;
  border-radius: var(--r-field);
  color: var(--tx);
  font: inherit;
  padding: var(--sp-2);
}

.fv-field__control .fv-field__input {
  background: none;
  border-radius: 0;
  padding: var(--sp-2) 0;
}

/* Pole bez obalu potřebuje vlastní kroužek zaostření — obal tu není, aby ho
 * nakreslil (klávesnice a viditelný fokus jsou součást hotové práce). */
.fv-field__input:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: -2px;
}

.fv-field__control .fv-field__input:focus {
  outline: none; /* the ring is drawn on .fv-field__control instead */
}

/* Rozbalovací seznam kreslí operační systém, ne stránka, a barvu popupu bere
 * z **vlastního `background-color`** prvku `select`. `background: none` výš
 * znamená průhledné, takže popup spadl na bílou, zatímco text zůstal světlý —
 * v tmavém tématu tedy šedivé na bílém. Bylo to na celém webu, protože to bylo
 * v základu pole, ne na jedné stránce. `color-scheme: dark` na kořeni nestačí:
 * platí pro ovládací prvky, které si barvu neurčily samy. */
select.fv-field__input,
select.fv-button,
select {
  background-color: var(--surf);
  color: var(--tx);
}

/* Roletka bez obalu sdílí pozadí pole; uvnitř obalu zůstává na barvě karty,
 * ze které popup bere barvu. */
select.fv-field__input {
  background-color: var(--field);
}

.fv-field__control select.fv-field__input {
  background-color: var(--surf);
}

option {
  background-color: var(--surf);
  color: var(--tx);
}

/* Roletka příjemců u šablony v Napsat zprávu (2. 9. 2026): seznam s více
 * položkami je vysoký podle `size`, ne jednořádkový jako obyčejná roletka,
 * a označené řádky drží barvu značky, ať je poznat i bez zaostření. */
select[multiple].fv-field__input {
  height: auto;
  min-height: 6rem;
  padding: var(--sp-1) 0;
}

select[multiple].fv-field__input option {
  padding: var(--sp-1) var(--sp-2);
}

select[multiple].fv-field__input option:checked {
  background-color: var(--acc-soft, var(--surf));
  color: var(--tx);
}

.fv-recipients {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.fv-recipients__all {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: var(--sp-2) 0;
}

/* Tlačítka pod seznamem na vlastní řadě: v nápovědě se lámala mezi věty. */
.fv-recipients__tools {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}

/* Značky v textu e-mailu (6. 9. 2026): řada tlačítek nad textovým polem
 * a rám s náhledem zprávy, jak přijde do schránky. Rám má světlé pozadí
 * zprávy napevno: e-mail tmavé téma nemá a náhled má vypadat jako schránka,
 * ne jako stránka administrace. */
.fv-markup-tools {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-2);
}

.fv-mail-preview {
  display: block;
  width: 100%;
  min-height: 36rem;
  height: 72vh;
  margin-top: var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: #eff3f1;
  color: #0d2129;
}

/* Živý náhled vedle pole (6. 9. 2026): na širokém displeji dvě stejné
 * poloviny, náhled zůstává na očích při posouvání formuláře; na užším
 * pod sebou, jako do té doby. */
.fv-mail-editor {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4, 1.5rem);
  align-items: start;
}

@media (min-width: 1200px) {
  .fv-mail-editor--split {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }

  .fv-mail-editor__preview {
    position: sticky;
    top: var(--sp-3, 1rem);
  }
}

.fv-field__input[inputmode="numeric"] {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.fv-field__unit {
  color: var(--tx2);
  font-family: var(--font-data);
  padding-left: var(--sp-2);
}

.fv-field__hint {
  display: block;
  color: var(--tx2);
  font-size: var(--fs-13);
  margin-top: var(--sp-1);
}

/* Chyba u pole (veřejné kalkulačky, třetí audit Astra 21. 9. 2026). Barva
 * textu zůstává běžná a chybu nese proužek vlevo a hlavně znění: barva nikdy
 * není jediný signál (16, WCAG) a varovná červená na malém písmu by navíc
 * neprošla kontrastem v tmavém stylu. */
.fv-field__error {
  display: block;
  border-left: 3px solid var(--warn);
  padding-left: var(--sp-2);
  font-size: var(--fs-13);
  margin-top: var(--sp-1);
}

/* Pole, které pro zvolenou odpověď nedává smysl (nález 24.8, rozhodnutí R1).
 *
 * Zašedit, ne skrýt: formulář, který se pod rukou přeskládá, mate víc než
 * jedno pole, o kterém je vidět, že teď není na řadě. Proto tu není
 * `display: none` a proto věta s důvodem není `aria-hidden` — je to jediné
 * místo, kde se čtenář dozví, na čem pole visí.
 *
 * Krytí, ne barva textu: kontrast 4,5 : 1 platí i tady, takže se ztlumí celý
 * blok najednou a popisek si drží poměr k pozadí. */
.fv-field.is-dead {
  opacity: 0.55;
}

.fv-field.is-dead .fv-field__input {
  cursor: not-allowed;
  background: var(--surf2);
}

/* Zašedlá otázka se nedá ani odložit na později (zadavatel 25. 8. 2026):
 * kolečka, zaškrtávátka i „Nevím, chci doplnit později" pod ní jsou mimo hru
 * a kurzor to říká dřív, než na ně někdo klikne. Klik zaráží `app.js`. */
.fv-field.is-dead .fv-choice,
.fv-field.is-dead .fv-choice input {
  cursor: not-allowed;
}

.fv-field__dead {
  display: none;
  color: var(--tx2);
  font-size: var(--fs-13);
  margin-top: var(--sp-1);
}

.fv-field.is-dead .fv-field__dead {
  display: block;
}

/* Nápověda a důvod se nezobrazují oba — jinak by pod polem stály dvě věty,
 * z nichž jedna právě neplatí. */
.fv-field.is-dead .fv-field__hint {
  display: none;
}

/* 2.1 - today's money or a future amount, on every monetary item. */
.fv-basis {
  display: inline-flex;
  gap: var(--sp-1);
  margin-top: var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-chip);
  padding: 2px;
}

/* 5: the view switch says what it switches. Three adjectives in a box, with a
 * header that changes colour and nothing else to go on, was a control people
 * pressed and then could not describe. */
.fv-viewswitch {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

/* The label is the button that opens the explanation, so it has to look like
 * something to press: dotted underline, a question mark riding on it, the
 * whole word as the target. It was a plain span with a separate 20 px `?`
 * beside it - a dead word and a mark small enough to be missed. */
.fv-viewswitch__label {
  font: inherit;
  font-size: var(--fs-13);
  color: var(--tx2);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}

.fv-viewswitch__label:hover {
  color: var(--tx);
}

.fv-viewswitch__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: var(--fs-12);
  line-height: 1;
}

.fv-basis__option {
  border: 0;
  background: none;
  color: var(--tx2);
  font: inherit;
  font-size: var(--fs-13);
  border-radius: var(--r-chip);
  padding: var(--sp-1) var(--sp-3);
  cursor: pointer;
}

.fv-basis__option[aria-pressed="true"],
/* G3: přepínač druhu grafu je dvojice **odkazů**, ne tlačítek — je to pohled
 * na tatáž data, takže se dá poslat odkazem a funguje bez skriptu. Vybranou
 * volbu proto značí třída, ne `aria-pressed`. */
.fv-basis__option.is-on {
  background: var(--surf2);
  color: var(--tx);
}

a.fv-basis__option {
  text-decoration: none;
}

a.fv-basis__option:hover {
  color: var(--tx);
}

/* ------------------------------------------------- 4.3 item table ------ */

.fv-table-wrap {
  overflow-x: auto;
}

/* Upravit is a link and Smazat is a form, so without this they stack: a
 * `<form>` is a block and would push the button onto its own line. */
.fv-row-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  white-space: nowrap;
}

.fv-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-15);
}

.fv-table th,
.fv-table td {
  text-align: left;
  padding: var(--cell-py) var(--sp-3);
  border-bottom: var(--row-line) solid var(--line-c);
}

.fv-table thead th {
  background: var(--th-bg);
  font-family: var(--font-label);
  font-size: var(--label-size);
  color: var(--th-c);
  font-weight: var(--fw-strong);
  text-transform: var(--tt-label);
  letter-spacing: var(--ls-label);
}

/* Pruhování řádků je token stylu; Výchozí má průhledné, tedy žádné. */
.fv-table tbody tr:nth-child(even) > td,
.fv-table tbody tr:nth-child(even) > th {
  background: var(--zebra);
}

.fv-table td.num,
.fv-table th.num {
  text-align: right;
}

/* The total always sits in the last row (design.md 4.3). */
.fv-table tfoot td {
  font-weight: 600;
  border-bottom: 0;
}

@media (max-width: 640px) {
  .fv-table thead {
    display: none;
  }
  .fv-table tr {
    display: block;
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    margin-bottom: var(--sp-3);
    padding: var(--sp-2);
  }
  .fv-table td {
    display: flex;
    justify-content: space-between;
    border: 0;
  }
  .fv-table td::before {
    content: attr(data-label);
    color: var(--tx2);
    font-size: var(--fs-13);
  }
}

/* ------------------------------------------------- 4.7 empty state ----- */

.fv-empty {
  text-align: center;
  padding: var(--sp-7) var(--sp-5);
  border: 1px dashed var(--line);
  border-radius: var(--r-card);
}

.fv-empty__title {
  font-family: var(--font-display);
  font-size: var(--fs-19);
  margin-bottom: var(--sp-2);
}

/* Věta prázdného stavu má pod sebou vzduch, než přijde tlačítko. */
.fv-empty .fv-metric__context {
  margin-bottom: var(--sp-4);
}

/* ------------------------------------------------- 4.6 notice block ---- */
/* Never red: this is not an error (design.md 4.6). */

.fv-notice {
  background: var(--surf2);
  border-left: 3px solid var(--acc2);
  color: var(--tx2);
  font-size: var(--fs-14, 0.875rem);
  padding: var(--sp-3) var(--sp-4);
  border-radius: 0 var(--r-field) var(--r-field) 0;
}

/* ------------------------------------------------------- 4.4 chart ----- */

.fv-chart {
  background: var(--surf-c);
  border: var(--bw) solid var(--line-c);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: var(--card-pad);
}

.fv-chart__head {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
}

/* The title is a sentence with the result, not a description of the data. */
.fv-chart__title {
  font-family: var(--font-display);
  font-size: var(--fs-19);
  margin: 0;
}

/* Nabídka ⋮ jako plovoucí panel, ne odstavec v hlavičce (zadavatel
 * 31. 8. 2026: „vylepšit zobrazení voleb a automaticky zavřít"). Rozbalený
 * seznam do té doby vjel do toku hlavičky a odsunul kresbu; teď se ukotví
 * pod tlačítko jako karta. Zavírání klikem vedle, únikem a po volbě
 * obsluhuje `app.js`. */
.fv-chart__menu {
  margin-left: auto;
  position: relative;
}

.fv-chart__menu-list {
  position: absolute;
  right: 0;
  top: calc(100% + var(--sp-1));
  z-index: 12;
  min-width: 15rem;
  max-width: 22rem;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  box-shadow: var(--shadow-pop);
  padding: var(--sp-1);
  list-style: none;
}

.fv-chart__menu-list .fv-button {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: none;
}

.fv-chart__menu-list .fv-button:hover,
.fv-chart__menu-list .fv-button:focus-visible {
  background: var(--surf2);
  opacity: 1;
}

/* Maximalizace grafu (zadavatel 20. 8. 2026): dialog v top-layer leží nad
 * vším včetně horního pruhu a levého menu. SVG má viewBox, takže mu stačí
 * víc místa.
 *
 * Nález 21. 8. 2026: kresba přes celou šířku vytlačila panel s čísly pod
 * obrazovku a zvětšení tak vyměnilo menu za rolování. Dialog je proto
 * sloupec přes celou výšku a pružná je jen kresba: hlava, panel, legenda
 * i popisek si nechají svou výšku a SVG dostane zbytek — díky viewBox se
 * do něj vepíše (letterbox), takže je na obrazovce všechno najednou. */
.fv-chart__max {
  margin-left: auto;
  white-space: nowrap;
}

.fv-chart__head .fv-chart__max + .fv-chart__menu {
  margin-left: 0;
}

dialog.fv-chart-max {
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  max-width: none;
  max-height: none;
  border: 0;
  margin: 0;
  padding: var(--sp-4) var(--sp-5);
  background: var(--bg);
  color: var(--tx);
  overflow: auto;
  overscroll-behavior: contain;
}

/* Jen [open]: bez atributu platí display: none z prohlížeče a holé
 * `display: flex` by zavřený dialog ukázalo. */
dialog.fv-chart-max[open] {
  display: flex;
  flex-direction: column;
}

.fv-chart-max__bar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: var(--sp-3);
}

.fv-chart-max__slot {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.fv-chart-max__slot > .fv-chart {
  max-width: none;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

/* Kresba je jediné pružné dítě figury. `minmax(0, 1fr)` dává řádku mřížky
 * určitou výšku, proti které se SVG se `height: 100%` umí spočítat. */
.fv-chart-max__slot .fv-chart__body {
  flex: 1 1 auto;
  min-height: 6rem;
  grid-template-rows: minmax(0, 1fr);
}

.fv-chart-max__slot .fv-chart__plot {
  width: 100%;
  height: 100%;
}

/* Sankey, skládaná plocha, histogram a donut mají SVG rovnou ve figuře,
 * bez obalu — pružným dítětem je tedy SVG samo. */
.fv-chart-max__slot > .fv-chart > .fv-chart__plot,
.fv-chart-max__slot > .fv-chart > .fv-chart__donut {
  flex: 1 1 auto;
  min-height: 6rem;
  height: auto;
  /* Donut má v běžném pohledu strop 220 px; ve zvětšení kreslí do celé
   * zbylé výšky a průměr si vezme z menšího rozměru sám (viewBox). */
  max-width: none;
}

/* Rozbalená datová tabulka roluje sama v sobě, místo aby vytlačila kresbu
 * a poslala celý dialog do rolování. Skrytého stavu (`sr-only`) se pravidlo
 * nedotýká. */
.fv-chart-max__slot .fv-chart__datatable:not(.sr-only) {
  overflow: auto;
  max-height: 35dvh;
}

/* Popisky v SVG se zvětšením kresby neškálují (nález 21. 8. 2026): číslo na
 * ose nepotřebuje být trojnásobné, aby graf byl větší. Skript při otevření
 * změří skutečné měřítko kresby (--fv-max-scale) a písmo se jím vydělí,
 * takže na obrazovce zůstane stejně velké jako v běžném pohledu. Selektor
 * po atributu, protože velikost nese atribut `font-size` skupiny. */
.fv-chart-max svg [font-size="9"] {
  font-size: calc(9px / var(--fv-max-scale, 1));
}

.fv-chart-max svg [font-size="10"] {
  font-size: calc(10px / var(--fv-max-scale, 1));
}

.fv-chart-max svg [font-size="11"] {
  font-size: calc(11px / var(--fv-max-scale, 1));
}

/* **Ve zvětšení jen graf, jeho čísla a jeho ovládání** (zadavatel 23. 8.
 * 2026: „díky všem těm textům okolo je samotný graf ještě menší než bez
 * zvětšení; komentáře úplně dole bych neukazoval, nechal bych jen hodnoty
 * a případné přepínače a zaškrtávátka"). Vysvětlivka pod grafem, věta
 * o cíli i poznámka o dluhu z plánu jsou k přečtení ve stránce pod
 * dialogem — ve zvětšení berou výšku kresbě, kvůli které se otevřelo.
 *
 * Povinné upozornění „projekce, ne předpověď" **zůstává** (§9, design A2);
 * jen se zmenší na jeden řádek. Skrýt ho by znamenalo ukázat čísla bez věty,
 * která říká, co znamenají. */
.fv-chart-max .fv-chart__caption,
.fv-chart-max .fv-chart__goal,
.fv-chart-max .fv-chart__debt {
  display: none;
}

.fv-chart-max .fv-chart__forecast {
  font-size: var(--fs-12);
  margin: 0 0 var(--sp-1);
}

/* Mezery: v běžném pohledu dělí graf od zbytku stránky, v dialogu ho jen
 * zmenšují — kolem dokola je prázdno. */
dialog.fv-chart-max {
  padding: var(--sp-2) var(--sp-4) var(--sp-3);
}

.fv-chart-max__bar {
  margin-bottom: var(--sp-1);
}

.fv-chart-max__slot > .fv-chart > * {
  margin-top: 0;
  margin-bottom: 0;
}

/* Figura je na stránce karta s vnitřním okrajem 20 px nahoře i dole. V
 * dialogu je kolem ní prázdno, takže těch čtyřicet pixelů jen ubírá kresbě. */
.fv-chart-max__slot > .fv-chart {
  padding-top: var(--sp-2);
  padding-bottom: var(--sp-2);
}

.fv-chart-max .fv-chart__panel {
  padding-top: var(--sp-2);
}

.fv-chart-max .fv-chart__head {
  margin-bottom: var(--sp-1);
}

.fv-chart-max .fv-chart__title {
  font-size: var(--fs-19);
}

.fv-chart-max .fv-chart__panel,
.fv-chart-max .fv-chart__legend {
  margin: var(--sp-2) 0 0;
}

.fv-chart-max .fv-chart__curves,
.fv-chart-max .fv-chart__marks {
  margin: var(--sp-2) 0 0;
}

/* Uvnitř dialogu tlačítko zvětšení nic nedělá — zavírá se vlastním. */
.fv-chart-max .fv-chart__max {
  display: none;
}

/* **Hodnoty a legenda doprava vedle kresby** (zadavatel 29. 8. 2026):
 * „zvětší to prostor pro graf na výšku a měl by být větší, hlavně na
 * menších monitorech či tabletu". Mřížka jen tam, kde figura obal
 * `fv-chart__side` má — Sankey a donut ho nemají a zůstávají sloupcem —
 * a jen od šířky, kde sloupec vedle kresby něco ubere; telefon zůstává
 * pod sebou. Prohlížeč bez `:has()` zůstane u sloupce, což je dosavadní
 * stav, ne rozbitá stránka. */
@media (min-width: 760px) {
  .fv-chart-max__slot > .fv-chart:has(> .fv-chart__side) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(15rem, 19rem);
    grid-template-rows: auto auto minmax(0, 1fr) auto;
    column-gap: var(--sp-5);
    align-items: start;
  }

  .fv-chart-max__slot > .fv-chart:has(> .fv-chart__side) > .fv-chart__forecast {
    grid-column: 1 / -1;
    grid-row: 1;
  }

  .fv-chart-max__slot > .fv-chart:has(> .fv-chart__side) > .fv-chart__head {
    grid-column: 1;
    grid-row: 2;
  }

  .fv-chart-max__slot > .fv-chart:has(> .fv-chart__side) > .fv-chart__body {
    grid-column: 1;
    grid-row: 3;
    min-height: 0;
    align-self: stretch;
  }

  .fv-chart-max__slot > .fv-chart:has(> .fv-chart__side) > .fv-chart__side {
    grid-column: 2;
    grid-row: 2 / span 2;
    min-height: 0;
    max-height: 100%;
    overflow-y: auto;
  }

  /* Rozbalená tabulka pod oběma sloupci, aby nerozstřelila mřížku. */
  .fv-chart-max__slot > .fv-chart:has(> .fv-chart__side) > .fv-chart__datatable {
    grid-column: 1 / -1;
    grid-row: 4;
  }

  /* Čísla panelu si šířka sloupce srovná pod sebe sama (auto-fit
   * s minimem 11 rem); legenda se přepíná na svislý seznam, protože
   * sloupec vedle kresby se čte shora dolů. */
  .fv-chart-max .fv-chart__side .fv-chart__legend {
    display: block;
  }

  .fv-chart-max .fv-chart__side .fv-chart__legend li {
    margin-bottom: var(--sp-1);
  }
}

html.has-chart-max {
  overflow: hidden;
}

.fv-chart__plot {
  width: 100%;
  height: auto;
}

.fv-chart__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  list-style: none;
  margin: var(--sp-3) 0 0;
  padding: 0;
  font-size: var(--fs-13);
}

.fv-chart__legend button {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  background: none;
  border: 0;
  color: var(--tx2);
  font: inherit;
  cursor: pointer;
}

.fv-chart__swatch {
  width: 14px;
  height: 3px;
  border-radius: 2px;
  display: inline-block;
}

/* Světlá vrstva „vklady a základ" na Výnosech z majetku (1. 9. 2026):
 * vzorek legendy nese touž průhlednost jako vrstva v kresbě. Třída, ne
 * inline style - ten CSP blokuje. */
.fv-chart__swatch--soft {
  opacity: 0.4;
}

/* The caption is mandatory - no chart ships without one (design.md 4.4). */
.fv-chart__caption {
  border-left: 2px solid var(--acc);
  color: var(--tx2);
  font-size: var(--fs-13);
  margin-top: var(--sp-4);
  padding-left: var(--sp-3);
}

.fv-chart__datatable {
  margin-top: var(--sp-4);
}

.fv-chart__datatable[hidden] {
  display: none;
}

/* ------------------------------------------- 7.7 stáří parametrů v adminu --- */

/* Prošlá hodnota vypadá úplně stejně jako platná — to je celý problém, který
 * tohle řeší. Barva sama nestačí (WCAG 1.4.1), takže stav nese i slovo. */
.fv-stale {
  color: var(--warn);
}

.fv-due {
  color: var(--acc2);
}

/* Řádek po termínu se pozná i letmým pohledem na tabulku o 250 řádcích. */
tr[data-freshness="po_termine"] > th {
  border-left: 3px solid var(--warn);
}

tr[data-freshness="blizi_se"] > th {
  border-left: 3px solid var(--acc2);
}

.fv-field__input--narrow {
  width: 5rem;
}

/* Cíl rezervy (zadavatel 1. 9. 2026): počítadlo 1 až 24 nepotřebuje pole
 * přes celý řádek. Obal se stáhne na obsah a vstup drží pevnou šířku;
 * šipky počítadla kreslí prohlížeč (type="number"). */
.fv-field__control--kratke {
  display: inline-flex;
  width: auto;
}

.fv-field__control--kratke .fv-field__input {
  flex: 0 0 auto;
  width: 4.5rem;
  text-align: center;
}

/* Dvě cesty, jak zadat investici, vedle sebe (zadavatel 21. 8. 2026):
 * položka podle třídy a jednotlivá pozice. Formuláře jsou úzké (520 px),
 * tak se na široké obrazovce vejdou oba; na úzké jdou pod sebe. */
.fv-add-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  gap: var(--sp-4);
  align-items: start;
}

.fv-add-pair__item {
  min-width: 0;
}

.fv-add-pair__when {
  color: var(--tx2);
  font-size: var(--fs-13);
  margin: var(--sp-2) 0 var(--sp-3);
}

/* Přepínač jednoduchého a pokročilého zadání: dvojice pilulek nahoře
 * v části, zapnutá plná, druhá je odkaz na mezistránku. */
.fv-mode-switch {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: var(--sp-3) 0 var(--sp-2);
}

.fv-mode-switch__label {
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-mode-switch__pills {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: var(--r-chip);
  padding: 2px;
  background: var(--surf);
}

.fv-mode-switch__pill {
  display: inline-block;
  padding: var(--sp-1) var(--sp-4);
  border-radius: var(--r-chip);
  color: var(--tx2);
  font-size: var(--fs-13);
  text-decoration: none;
}

.fv-mode-switch__pill.is-on {
  background: var(--acc);
  color: var(--bg);
  font-weight: 600;
}

a.fv-mode-switch__pill:hover,
a.fv-mode-switch__pill:focus-visible {
  color: var(--tx);
  background: var(--surf2);
  outline: none;
}

/* Pravidlo vývoje portfolia je sbalené; v nadpisu stojí, co platí. */
.fv-vyvoj > summary .u-muted {
  font-weight: 400;
}

/* Historie hodnot a audit (zadavatel 21. 8. 2026). Podrobnosti zápisu jsou
 * dlouhý řádek JSON přepsaný do vět; bez limitu by roztáhl tabulku o deseti
 * sloupcích přes celou obrazovku, bez lámání by ji rozbil. */
.fv-audit__details {
  max-width: 28rem;
  overflow-wrap: anywhere;
  font-size: var(--fs-13);
  color: var(--tx2);
}

.fv-plain-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.fv-plain-list > li + li {
  margin-top: var(--sp-1);
}

/* Výrok je věta, ne slovo — pole na něj musí být široké, jinak se v seznamu
 * o 365 položkách needituje, jen hádá. */
.fv-field__input--wide {
  width: min(48rem, 70%);
}

/* Hromadná revize: formulář stojí nad tabulkou, ale jeho zaškrtávátka jsou
 * v řádcích (přes `form=`), takže je tenhle blok jen věta a tlačítko. */
.fv-review {
  border: var(--bw) solid var(--line-c);
  border-radius: var(--r-card);
  background: var(--surf-c);
  box-shadow: var(--shadow-card);
  padding: var(--sp-4);
  margin-bottom: var(--sp-4);
}

/* ======================================================================
 * Veřejný web (§5.1, §5.2) a kalkulačky — fáze 8b
 *
 * Stojí na týchž komponentách jako aplikace (design.md 20, pravidlo 2): karta
 * je `.fv-card`, graf `.fv-chart__plot`, upozornění `.fv-notice`. Co je tady
 * navíc, je rozvržení stránky, ne druhý vzhled téhož.
 * ==================================================================== */

.fv-hero {
  padding: var(--sp-6) 0 var(--sp-5);
}

.fv-hero__lead {
  font-size: var(--fs-19);
  color: var(--tx2);
}

.fv-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
}

/* 10. 8. 2026: hero bez grafu. Tři otázky, které si člověk klade sám — je to
 * to, s čím na web přichází, a zároveň to říká, co web umí, aniž by to musel
 * tvrdit o sobě. */
.fv-asks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--sp-4);
  list-style: none;
  margin: var(--sp-5) 0;
  padding: 0;
}

.fv-ask {
  border-left: 3px solid var(--acc);
  padding-left: var(--sp-4);
}

.fv-ask__q {
  font-size: var(--fs-19);
  margin-bottom: var(--sp-2);
}

/* Postup, ne odrážky: čtyři řádky pod sebou nikdo nečte. Číslo je velké a
 * tiché, karty jdou vedle sebe a na úzké obrazovce pod sebe. Zůstává to
 * `<ol>` — pořadí je obsah, ne výzdoba. */
.fv-flow {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--sp-4);
  list-style: none;
  margin: var(--sp-4) 0 var(--sp-5);
  padding: 0;
  counter-reset: none;
}

.fv-flow__step {
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--sp-4);
  position: relative;
}

.fv-flow__number {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-30);
  line-height: 1;
  color: var(--acc);
}

.fv-flow__title {
  font-size: var(--fs-19);
  margin: var(--sp-2) 0;
}

/* Můj plán zabírá celou šířku mřížky: je to jádro produktu, ne jedna
 * z pěti rovnocenných dlaždic. */
.fv-card--wide {
  grid-column: 1 / -1;
}

/* Jediný graf na stránce, a proto se s ním zachází jako s grafem podle
 * design.md 4.4: nadpis je věta, osy mají popisky, pod ním vysvětlivka
 * a datová tabulka. Předchozí verze měla dva grafy, oba bez čehokoli z toho. */
.fv-figure {
  margin: var(--sp-5) 0;
}

.fv-figure__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-19);
  margin-bottom: var(--sp-3);
}

.fv-figure__chart {
  display: block;
  width: 100%;
  height: auto;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.fv-figure__grid {
  stroke: var(--grid);
  stroke-width: 1;
}

/* Barva křivky. **Tohle chybělo** — pravidla se jmenovala `.fv-hero__line` a
 * odešla spolu s blokem starého hero, ve kterém shodou okolností stála. Čára
 * bez `stroke` je v SVG neviditelná, ve všech tématech a na všech
 * obrazovkách; graf tam byl a nebylo v něm nic. */
.fv-figure__line[data-colour="s1"] {
  stroke: var(--s1);
}
.fv-figure__line[data-colour="s2"] {
  stroke: var(--s2);
}
.fv-figure__line[data-colour="s3"] {
  stroke: var(--s3);
}

.fv-figure__tick,
.fv-figure__axis {
  fill: var(--tx2);
  font-size: 12px;
}

.fv-figure__axis {
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Svislá značka v roce, kdy ten člověk přestane pracovat. Bez ní vypadal zlom
 * na křivce jako chyba vykreslení. */
.fv-figure__mark {
  stroke-dasharray: 3 4;
  stroke-width: 1;
}

.fv-figure__mark[data-colour="s1"] {
  stroke: var(--s1);
}
.fv-figure__mark[data-colour="s2"] {
  stroke: var(--s2);
}
.fv-figure__mark[data-colour="s3"] {
  stroke: var(--s3);
}

.fv-figure__result {
  border-left: 2px solid var(--acc);
  color: var(--tx2);
  font-size: var(--fs-15);
  margin-top: var(--sp-3);
  padding-left: var(--sp-3);
}

/* §5.2 bod 5: „Co FinVize není" je plnohodnotná sekce, ne malé písmo dole.
 * Odsazená a orámovaná, aby to nešlo přehlédnout ani přeskočit. */
.fv-not {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: var(--sp-5) 0;
  margin: var(--sp-6) 0;
}

.fv-cta {
  margin: var(--sp-6) 0 var(--sp-5);
}

.fv-grid-parts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--sp-3);
  list-style: none;
  margin: var(--sp-4) 0;
  padding: 0;
}

.fv-grid-parts .fv-card {
  padding: var(--sp-3) var(--sp-4);
}

/* Skupiny na /funkce: tři, do kterých plán opravdu spadá, plus rámec. Odsazení
 * mezi nimi je to jediné, co z dvaceti dlaždic dělá tři odpovědi. */
.fv-group + .fv-group {
  margin-top: var(--sp-6);
}

/* Výrok nad zápatím. Tiše, kurzívou, na střed — je to poznámka na okraj, ne
 * sdělení. Kdyby křičel, čte se jako reklamní slogan. */
.fv-saying {
  border-top: 1px solid var(--line);
  color: var(--tx2);
  font-size: var(--fs-15);
  font-style: italic;
  margin: var(--sp-6) auto 0;
  max-width: 46rem;
  padding-top: var(--sp-4);
  text-align: center;
}

/* CLAUDE.md bod 11: zdroj a datum u každého předvyplněného čísla. Drobným
 * písmem, ale ne schované — je to podmínka, za které tu to číslo smí být. */
.fv-sources {
  list-style: none;
  margin: var(--sp-3) 0;
  padding: 0;
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-sources > li + li {
  margin-top: var(--sp-2);
}

.fv-links {
  list-style: none;
  margin: var(--sp-3) 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
}

.fv-faq {
  border-bottom: 1px solid var(--line);
  padding: var(--sp-3) 0;
}

.fv-faq:last-child {
  border-bottom: 0;
}

.fv-faq > summary {
  cursor: pointer;
  font-weight: 600;
}

.fv-calc__form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--sp-4);
  align-items: start;
  margin-bottom: var(--sp-5);
}

.fv-calc__form > p {
  grid-column: 1 / -1;
  margin: 0;
}

.fv-calc__note {
  color: var(--tx2);
  font-size: var(--fs-15);
}

.fv-chart__tick {
  fill: var(--tx2);
  font-size: 11px;
}

/* ---------------------------------------------- 5.4 graf v dlaždici --- */

/* Small enough that the tile still reads as one number and one sentence, and
 * last in the tile so nothing above it moves when a chart cannot be drawn. */
.fv-microchart {
  display: block;
  width: 100%;
  height: 32px;
  margin-top: var(--sp-3);
}

.fv-microchart--gauge,
.fv-microchart--donut {
  width: auto;
  height: 44px;
  margin-left: auto;
  margin-right: auto;
}

.fv-microchart__line {
  stroke: var(--acc);
}

.fv-microchart__track {
  stroke: var(--line);
}

.fv-microchart__arc {
  stroke: var(--acc);
}

/* Colour by class, never by attribute: the CSP forbids inline styles (12.4)
 * and these are the same six series colours the charts use (design.md 3.4). */
.fv-microchart__bar[data-colour="acc"],
.fv-microchart__slice[data-colour="s1"] {
  fill: var(--acc);
  stroke: var(--acc);
}
.fv-microchart__bar[data-colour="acc2"],
.fv-microchart__slice[data-colour="s2"] {
  fill: var(--acc2);
  stroke: var(--acc2);
}
.fv-microchart__slice[data-colour="s3"] {
  stroke: var(--s3);
}
.fv-microchart__slice[data-colour="s4"] {
  stroke: var(--s4);
}
.fv-microchart__slice[data-colour="s5"] {
  stroke: var(--s5);
}
.fv-microchart__slice[data-colour="s6"] {
  stroke: var(--s6);
}

/* --------------------------------------- 20/3 miniatura osy na přehledu --- */

/* The shared visual motif on the one page that never carried it. Not the axis
 * of 4.10 - no dragging, no tracks, no table - a strip that says what is
 * coming and leads to the page where it can be changed. */
.fv-strip {
  display: block;
  /* Kotva pro bublinu po najetí (5. 9. 2026), jako u osy a karty grafu. */
  position: relative;
  border: var(--bw) solid var(--line-c);
  border-radius: var(--r-card);
  background: var(--surf-c);
  box-shadow: var(--shadow-card);
  padding: var(--sp-4) var(--sp-5);
  color: var(--tx);
  transition: border-color var(--transition);
}

.fv-strip:hover,
.fv-strip:focus-visible {
  border-color: var(--acc);
}

/* `height: auto`, jako u velké osy. Pevných 34 px tu zbylo z doby, kdy obrázek
 * nesl jen čáru a puntíky a popisky tekly v seznamu pod ním. Jenže obrázek se
 * od té doby škáluje rovnoměrně, a rovnoměrné škálování se vejde do **obou**
 * rozměrů: z 935 px na šířku a 34 px na výšku vyhrála výška, obrázek se srazil
 * na 217 px a text na tři pixely. Výška se teď řídí poměrem stran, takže pruh
 * je tak široký jako karta, ve které leží. */
.fv-strip__rail {
  display: block;
  width: 100%;
  height: auto;
}

.fv-strip__line {
  stroke: var(--line);
  stroke-width: 2;
}

/* Prstenec s ikonkou — táž značka jako na časové ose (zadavatel 19. 8. 2026),
 * jen menší. Podklad je barva stránky, aby značka nesplynula s čárou. */
.fv-strip__ring {
  fill: var(--bg);
  stroke: var(--acc);
  stroke-width: 1.5;
}

/* 4.10: what the plan worked out for itself is drawn differently from what
 * the user put on the axis, and the legend says so in words. */
.fv-strip__ring.is-derived {
  stroke: var(--acc2);
  stroke-dasharray: 3 2;
}

.fv-strip__icon {
  color: var(--acc);
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

.fv-strip__icon.is-derived {
  color: var(--acc2);
}

/* Popisky uvnitř pruhu. Barvu a písmo řídí CSS, polohu atributy v SVG —
 * `style-src 'self'` bez `unsafe-inline` (§12.4) by atribut ze serveru
 * zahodilo. */
.fv-strip__text {
  font-size: 9px;
  fill: var(--tx2);
  /* Hover řídí terč, ne text: neviditelný popisek by jinak bral najetí
   * puntíku, který pod ním leží. */
  pointer-events: none;
  transition: opacity var(--transition);
}

/* Terč pro myš. Puntík má na obrazovce šest pixelů, terč osmnáct. */
.fv-strip__hit {
  fill: transparent;
  pointer-events: all;
}

/* Bublina (zadavatel 18. 8. 2026). Popisek, který se do hustého místa nevešel,
 * je vidět po najetí na puntík; podklad je proto tmavší než karta, aby se
 * nečetl přes to, co pod ním leží. Bez skriptu — je to `:hover` nad skupinou,
 * takže to platí i tam, kde skript neběží.
 *
 * Bublina není jediná cesta k údaji: bez myši ho nese seznam pod pruhem
 * a stránka /casova-osa, kam karta vede. */
.fv-strip__plate {
  fill: var(--bg);
  stroke: var(--line);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition);
}

.fv-strip__point.is-tip .fv-strip__text {
  opacity: 0;
}

.fv-strip__point:hover .fv-strip__plate,
.fv-strip__point:hover .fv-strip__text {
  opacity: 1;
}

/* Značka, na které myš stojí, ztuční — jinak není poznat, ke kterému
 * z natěsnaných bodů ta bublina patří. */
.fv-strip__point:hover .fv-strip__ring {
  stroke-width: 3;
}

.fv-strip__year {
  font-family: var(--font-data);
  font-weight: 700;
  fill: var(--tx);
}

/* Seznam pod pruhem zůstává **jen pro odečítač**. Obrázek je `aria-hidden`,
 * takže bez něj by body v něm nikdo nepřečetl; na obrazovce by ale teď
 * zdvojoval to, co je čitelné přímo u puntíků. */
.fv-strip__list {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Na telefonu je pruh 280 px široký a písmo v něm vyjde na tři a půl pixelu —
 * pruh, ze kterého se nic nepřečte. Velká osa na tutéž potíž odpovídá
 * vodorovným posuvem (`min-width: 34rem`), jenže tady by se muselo posouvat
 * přes tři obrazovky, aby popisky vyšly čitelně, a to na rozcestníku nedává
 * smysl. Nastoupí tedy seznam, který jinak čte jen odečítač: nese tytéž body
 * slovy, vejde se a nikam se posouvat nemusí. Obrázek je `aria-hidden`, takže
 * se tím nic nezdvojuje. */
@media (max-width: 40rem) {
  .fv-strip__rail {
    display: none;
  }

  .fv-strip__list {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
    white-space: normal;
    list-style: none;
    margin: 0;
    padding: 0;
    color: var(--tx2);
    font-size: var(--fs-13);
  }

  .fv-strip__list > li + li {
    margin-top: var(--sp-2);
  }

  .fv-strip__list strong {
    font-family: var(--font-data);
    color: var(--tx);
    margin-right: var(--sp-2);
  }
}

/* „z plánu vychází" u bodu, který si nikdo nezadal. V obrázku to říká strana
 * čáry, tady slovo — a tiše, protože je to původ bodu, ne jeho obsah. */
.fv-strip__from {
  color: var(--tx2);
  font-size: var(--fs-12);
  font-style: italic;
}


/* ------------------------------------------------------- 10 soukromí --- */

/* A masked amount keeps the space the number had, so nothing on the page
 * moves when it is switched on and off. Tabular figures make `••••` about as
 * wide as the four digits most amounts have. */
.fv-masked {
  color: var(--tx2);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
}

/* The shape of a curve is as readable over a shoulder as the number under it,
 * so the plot goes too. Blur rather than hide: the page keeps its layout and
 * its purpose is still legible, which is the difference between working with
 * somebody beside you and closing the tab.
 *
 * The data table under the chart is masked by the same macro that masks the
 * amounts, so it is not a way round this. */
.fv-chart__plot.is-private,
.fv-microchart.is-private {
  filter: blur(8px);
}

/* A microchart is 32 px tall, so 8 px of blur would erase it rather than
 * obscure it - and an empty box in a tile reads as a bug. */
.fv-microchart.is-private {
  filter: blur(3px);
}

/* ------------------------------------------------- 4.12 section row ---- */

.fv-section-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--line);
  color: inherit;
  text-decoration: none;
}

.fv-section-row__summary {
  color: var(--tx2);
  font-size: var(--fs-13);
}

/* Poslední řádek v kartě linku nekreslí: karta má vlastní okraj a dvě čáry
 * kousek od sebe se čtou jako chyba. */
.fv-card > .fv-section-row:last-child {
  border-bottom: 0;
}

/* Jméno nad větou, ne za ní (zadavatel 26. 8. 2026, rozcestí účtu). Popisky
 * jako „heslo, druhý faktor, přihlášená zařízení" jsou na jeden řádek dlouhé
 * a za tučným jménem by se lámaly doprostřed. */
.fv-section-row__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.fv-section-row__state {
  margin-left: auto;
  font-size: var(--fs-13);
}

/* Řádek části s přepínačem menu vedle odkazu (zadavatel 19. 8. 2026).
 * Přepínač je mimo odkaz — ovládání v odkazu není markup, který má
 * prohlížeč luštit — a schovaná část ztlumí jen svůj řádek: dál existuje
 * a jde rozkliknout, jen v levém menu není. */
.fv-part-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

.fv-part-row .fv-section-row {
  flex: 1;
  min-width: 0;
}

.fv-part-row__menu {
  flex: none;
  border-bottom: 1px solid var(--line);
  align-self: stretch;
  display: flex;
  align-items: center;
  font-size: var(--fs-13);
  white-space: nowrap;
}

.fv-part-row.is-hidden .fv-section-row {
  opacity: 0.6;
}

.fv-badge {
  background: var(--acc2);
  color: var(--on-gold);
  border-radius: var(--r-chip);
  font-family: var(--font-label);
  font-size: var(--fs-12);
  text-transform: var(--tt-label);
  letter-spacing: var(--ls-label);
  padding: 0 var(--sp-2);
}

/* ----------------------------------------------------------- buttons --- */

.fv-button {
  font: inherit;
  font-weight: var(--fw-label);
  border-radius: var(--r-field);
  border: 1px solid var(--acc);
  background: var(--acc);
  color: var(--bg);
  padding: var(--sp-2) var(--sp-4);
  cursor: pointer;
  transition: opacity var(--transition), transform var(--transition);
}

/* Odkaz jako tlačítko je `inline-block`, aby jeho svislé odsazení počítal
 * řádek. Jako holý inline prvek mu horní padding vyjel přes větu nad ním —
 * u prázdného stavu Státního důchodu tlačítko *Zadat kariéru* lehce
 * překrývalo text (zadavatel 22. 8. 2026). */
a.fv-button {
  display: inline-block;
}

.fv-button--quiet {
  background: none;
  color: var(--tx);
  border-color: var(--line);
}

/* Potvrzení nevratného kroku (zadavatel 26. 8. 2026). Barva `--warn` je
 * v tokenech „co odchází a co dlužím", tedy přesně to, co se tímhle
 * tlačítkem stane. §1 designu žádá, aby rozdíl nestál jen na barvě: tlačítko
 * je v dialogu první a nese sloveso („Smazat"), kdežto druhé má tvar
 * `--quiet` a jméno „Zrušit". Fokus dostává to druhé. */
.fv-button--danger {
  background: var(--warn);
  border-color: var(--warn);
  color: var(--bg);
}

.fv-button:hover {
  opacity: 0.9;
  transform: translateY(var(--lift));
}


/* Řádek akcí u karty (varianta S3, zvolil zadavatel 17. 8. 2026).
 *
 * Karta varianty plánu je hlavně tabulka čísel a čtyři obdélníky pod ní
 * o pozornost soupeří — čtyřikrát `--quiet` vedle sebe mělo stejnou váhu, ať
 * šlo o „Simulaci" nebo o „Smazat". Svislý proužek dá tlačítku začátek, aniž
 * by z něj dělal plochu.
 *
 * Menší písmo než `--quiet` a bez rámu, takže řádek nese čísla nad sebou.
 * Barva **není** jediný nositel rozdílu u mazání: proužek u něj mění barvu
 * i tloušťku, a text sám je pořád „Smazat". */
.fv-action {
  font: inherit;
  font-size: var(--fs-13);
  color: var(--tx);
  background: none;
  border: 0;
  border-left: 2px solid var(--line);
  border-radius: 0;
  padding: var(--sp-1) var(--sp-3);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  transition: color var(--transition), border-color var(--transition);
}

.fv-action:hover {
  color: var(--acc);
  border-left-color: var(--acc);
}

.fv-action--danger:hover {
  color: var(--warn);
  border-left-color: var(--warn);
  border-left-width: 3px;
}

.fv-action:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .fv-action {
    transition: none;
  }
}

/* ------------------------------------------ narrow layout (Průvodce) --- */
/* design.md 5: one thing on the screen, no left menu. Used for sign-in and,
 * from phase 1 onwards, for the questionnaire. */

.fv-narrow {
  min-height: 100vh;
  display: grid;
  place-items: center;
  align-content: center;
  gap: var(--sp-5);
  padding: var(--sp-5);
}

.fv-narrow__box {
  width: min(420px, 100%);
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--sp-6);
}

.fv-narrow__brand {
  margin-bottom: var(--sp-5);
}

.fv-narrow__title {
  font-size: var(--fs-24);
  margin-bottom: var(--sp-4);
}

.fv-narrow__aside {
  margin-top: var(--sp-4);
  font-size: var(--fs-13);
}

/* Dotazník jako pevné okno **nad viditelnou aplikací** (zadavatel
 * 29. 8. 2026, druhé kolo: „aplikace pod dotazníkem není vidět, ztmavení
 * by mělo být jen symbolické"). Stránky dotazníku dědí z hlavního
 * rozvržení (`dotaznik/okno.html`), takže za závojem stojí skutečné menu
 * a patička; závoj je lehký a okno od nich dělí rámeček a stín dialogů.
 * `safe center`: krátký krok je uprostřed, dlouhý se ukotví nahoře a roluje
 * — obyčejný `center` by mu uřízl začátek. */
.fv-narrow--okno {
  position: fixed;
  inset: 0;
  /* Nad horním pruhem (15) i levým menu (20), ale **pod lištou cookies**
   * (30): souhlas musí zůstat k odkliknutí, i když je dotazník otevřený. */
  z-index: 25;
  overflow: auto;
  overscroll-behavior: contain;
  min-height: 0;
  align-content: start;
  align-content: safe center;
  background: rgba(10, 15, 24, 0.3);
  /* Lehké zamlžení aplikace za oknem (zadavatel 29. 8. 2026): rozmazání
   * dá oknu hloubku líp než tmavší závoj a čísla za ním přestanou svádět
   * ke čtení. Prohlížeč bez podpory nechá jen závoj, což je dosavadní
   * stav, ne rozbitá stránka. */
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}

.fv-narrow--okno .fv-narrow__box {
  position: relative;
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.35);
}

/* Výplň pozadí, když za oknem ještě není Přehled (první průchod): zatlačí
 * patičku pod ohyb, aby pozadí nevypadalo jako konec neznámé stránky. */
.fv-okno-vypln {
  min-height: 100vh;
  min-height: 100dvh;
}

/* Cesta ven z okna. Odkaz v rohu, ne skript — rozepsaný krok zachytí
 * hlídač neuložených změn jako každý jiný odchod. */
/* Hlavička okna (zadavatel 8. 9. 2026): značka a Zavřít na jedné řadě nad
 * obsahem, ne odkaz obtékaný zprávou pod značkou. */
.fv-okno-hlava {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
}

.fv-okno-hlava .fv-narrow__brand {
  margin-bottom: 0;
}

.fv-okno-zavrit {
  font-size: var(--fs-13);
  color: var(--tx2);
}

/* Jedna věta o tom, co se v dotazníku děje (zadavatel 29. 8. 2026):
 * nahradila odznak plné verze, který se opakoval na každém kroku. */
.fv-wizard__outline {
  font-size: var(--fs-13);
  margin: 0 0 var(--sp-4);
}

/* Kategorie výdajů jako sbalitelný blok (zadavatel 29. 8. 2026). Vyplněná
 * celková částka je sbalí — skript v app.js hned při psaní, server při
 * načtení. Souhrn vypadá jako popisek pole, aby blok nepůsobil jako cizí
 * prvek uprostřed formuláře. */
.fv-krok-kategorie {
  margin: var(--sp-4) 0;
  border-top: 1px solid var(--line);
  padding-top: var(--sp-3);
}

.fv-krok-kategorie > summary {
  cursor: pointer;
  font-size: var(--fs-14);
  font-weight: 600;
  color: var(--tx2);
  margin-bottom: var(--sp-3);
}

/* Co se doplnilo za vás — sbalené, jen pro zvídavé (zadavatel 29. 8. 2026). */
.fv-hotovo-doplneno > summary {
  cursor: pointer;
}

.fv-hotovo-doplneno > summary .fv-subhead {
  display: inline;
}

.fv-narrow__footer {
  width: min(420px, 100%);
  color: var(--tx2);
  font-size: var(--fs-12);
  text-align: center;
  margin: 0;
}

/* Flash messages. Never red for anything that is not an error, and the colour
 * is never the only signal - the wording carries it (16, WCAG). */
.fv-flash {
  border-left: 3px solid var(--acc);
  background: var(--surf2);
  border-radius: 0 var(--r-field) var(--r-field) 0;
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-15);
  margin-bottom: var(--sp-4);
}

.fv-flash[data-kind="error"] {
  border-left-color: var(--warn);
}

.fv-flash[data-kind="info"] {
  border-left-color: var(--acc2);
}

/* ------------------------------------------------ questionnaire (4) --- */

.fv-progress {
  font-size: var(--fs-13);
  color: var(--tx2);
  margin-bottom: var(--sp-4);
}

.fv-progress__bar {
  display: block;
  width: 100%;
  height: 4px;
  margin-top: var(--sp-2);
  border: 0;
  border-radius: var(--r-chip);
  background: var(--surf2);
  /* The browser draws the fill, which is why nothing here needs an inline
   * width the CSP would refuse. */
  accent-color: var(--acc);
}

.fv-progress__bar::-webkit-progress-bar {
  background: var(--surf2);
  border-radius: var(--r-chip);
}

.fv-progress__bar::-webkit-progress-value {
  background: var(--acc);
  border-radius: var(--r-chip);
}

.fv-progress__bar::-moz-progress-bar {
  background: var(--acc);
  border-radius: var(--r-chip);
}

/* A fieldset carries the browser's own border and padding; the design has
 * neither (design.md 3 builds depth from surface and line, not boxes). */
fieldset.fv-field {
  border: 0;
  margin: 0 0 var(--sp-4);
  padding: 0;
  min-width: 0;
}

fieldset.fv-field > legend {
  padding: 0;
}

.fv-choice {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) 0;
  font-size: var(--fs-15);
}

/* The skip option sits apart from the answers: it is a different kind of
 * choice, not one more option among them. */
.fv-choice--skip {
  margin-top: var(--sp-2);
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-wizard__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
}

.fv-subhead {
  font-size: var(--fs-19);
}

.fv-result__sentence {
  font-family: var(--font-display);
  font-size: var(--fs-24);
  line-height: var(--lh-heading);
  margin-bottom: var(--sp-5);
}

.fv-missing {
  margin: 0 0 var(--sp-3);
  padding-left: var(--sp-5);
  color: var(--tx2);
}

/* ------------------------------------------- account security (12.1) --- */

.fv-codes {
  list-style: none;
  margin: var(--sp-3) 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--sp-2);
  font-family: var(--font-data);
  font-size: var(--fs-15);
}

.fv-steps {
  color: var(--tx2);
  padding-left: var(--sp-5);
  margin-bottom: var(--sp-4);
}

.fv-qr {
  background: #fff; /* a QR needs light quiet zones in both themes */
  padding: var(--sp-3);
  border-radius: var(--r-field);
  width: fit-content;
  margin-bottom: var(--sp-4);
}

.fv-secret {
  font-family: var(--font-data);
  background: var(--surf2);
  border-radius: var(--r-field);
  padding: 0 var(--sp-2);
  word-break: break-all;
}

/* -------------------------------------------------------- utilities --- */
/* These exist because the CSP forbids inline styles (12.4) and a `style="..."`
 * attribute cannot be allowed by a hash - only by 'unsafe-hashes', which is
 * the thing we are avoiding. So every one-off rule gets a class. */

.u-muted {
  color: var(--tx2);
}

/* Šířka čtecího sloupce (design.md §65: 66 ch).
 *
 * **Vyjádřená v rem, ne v ch, aby se dala sdílet s nadpisem.** `ch` se počítá
 * z písma toho prvku, na kterém stojí, takže `66ch` na nadpisu je skoro
 * dvakrát širší sloupec než `66ch` na odstavci pod ním. Nadpis se pak táhne
 * přes celou stránku, text končí v 57 % šířky a blok vypadá nedodělaně —
 * přesně to zadavatel našel u sekce „Kolik to stojí“ (11. 8. 2026). Hodnota
 * odpovídá dosavadním 66 ch základního písma.
 */
:root {
  --w-prose: 38rem;
}

.u-measure {
  max-width: var(--w-prose);
}

/* Výčet vad importu revize jde po řádcích (30. 8. 2026). */
.u-pre-line {
  white-space: pre-line;
}

/* Velký skok u návrhu hodnoty (revize s AI, 30. 8. 2026): --warn je
 * „co odchází a co dlužím" a tady „na tohle číslo se podívejte dvakrát". */
.fv-badge[data-kind="warn"] {
  border-color: var(--warn);
  color: var(--warn);
}

.u-section {
  margin-top: var(--sp-7);
  /* Linka nad nadpisem oddílu je token stylu (Novinový: dvojlinka). */
  border-top: var(--rule-top);
  border-bottom: var(--rule-bottom);
  padding-top: var(--rule-pad);
}

/* Nadpis sekce s akcí vpravo (zadavatel 21. 8. 2026: „Zpět do dotazníku"
 * u Částí plánu). Odkaz sedí na účaří nadpisu; na úzké obrazovce se zalomí
 * pod něj, ne přes něj. */
.fv-heading-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
}

.fv-heading-row > .u-section {
  margin-bottom: 0;
}

.fv-heading-row__action {
  margin-top: var(--sp-7);
  font-size: var(--fs-13);
  white-space: nowrap;
}

.u-footnote {
  color: var(--tx2);
  font-size: var(--fs-13);
  margin-top: var(--sp-8);
}

.u-plain-link {
  text-decoration: none;
}

.u-push-bottom {
  margin-top: auto;
}

.u-minw0 {
  min-width: 0;
}

.u-sprite {
  position: absolute;
  width: 0;
  height: 0;
}

/* The margin is the fix to a paragraph sitting straight on the cards: `p` has
 * no top margin (the flow expects each block to bring its own bottom one) and
 * this grid brought none, so `.fv-tiles` followed by text touched it. The two
 * sibling grids - `.fv-asks` and `.fv-flow` - have carried their own vertical
 * margin from the start; this one was the exception. It collapses against a
 * heading's margin rather than adding to it. */
/* Přehled ve dvou sloupcích (varianta A, zvolil zadavatel 17. 8. 2026).
 *
 * Do té chvíle bylo všechno pod sebou a stránka měřila skoro osm tisíc bodů:
 * graf i „Co vás čeká“ ležely hluboko pod ohybem. Zmenšení písma ubralo
 * procento a půl — délku stránky nedělá písmo, dělá ji rozvržení.
 *
 * Práh 62rem, ne breakpoint z tabulky: pod ním by na dva sloupce nezbylo
 * místo, protože dlaždice mají vlastní minimum 240 px a graf potřebuje aspoň
 * tolik, aby se na ose daly rozeznat roky.
 *
 * **Jedna mřížka, šest buněk** (18. 8. 2026). Do té doby to byly dva vnořené
 * sloupce a to, co v nich stálo na téže lince, drželo **čtvero ručně
 * naměřených čísel**: 8 px nad pruhem úkolů, 2 px pod ním, 2 px nad
 * dlaždicemi a 66 px pro případ, že pruh není. Jedno z nich bylo odvozené
 * z **výšky řádku záložek v druhém sloupci**, kterou CSS nepřečte — takže jiné
 * písmo v pruhu nebo čtvrtá záložka by zarovnání tiše rozešly a test na to
 * není. Teď leží nadpisy, ovládání a obsah po dvojicích ve třech řadách; výšku
 * řady určuje vyšší z dvojice a lícování obstará prohlížeč.
 *
 * Rozestupy dělá `gap`, ne marže bloků: v mřížce by se s mezerou řady sčítaly
 * a u dlaždic a karty grafu by navíc rozhodovaly o tom, kde buňka začne —
 * tedy přesně o tom lícování, kvůli kterému mřížka vznikla.
 *
 * Pořadí v DOM je to původní (nadpis · úkol · dlaždice · Podrobněji · záložky ·
 * graf), takže odečítač i tabulátor čtou sloupec po sloupci; do řad je rozdělí
 * `grid-area`. Pod 62rem je jeden sloupec a oblasti jdou v témž pořadí, takže
 * se vidoucímu i odečítači skládá stejně. */
/* Společná výška sbaleného pruhu úkolů a řádku záložek — viz `.fv-todo__summary-bar`. */
.fv-overview {
  --fv-control-row: 2.75rem;
  display: grid;
  /* Kontejner pro dlaždice (7. 9. 2026): jestli se vejdou dvě vedle sebe,
   * rozhoduje šířka Přehledu, ne okna — dělá ji i rozbalené menu. */
  container-type: inline-size;
  container-name: prehled;
  /* Mezera mezi řadami je užší než mezi sloupci: svisle jde o odstup dvou
   * bloků pod sebou, vodorovně o dělicí pruh mezi dvěma sloupci stránky. */
  gap: var(--sp-4) var(--sp-5);
  grid-template-areas:
    "nazev"
    "ukol"
    "dlazdice"
    "pohledy"
    "zalozky"
    "graf";
}

.fv-overview > h1 {
  grid-area: nazev;
}

/* Marže se ruší **tady**, ne hromadně u `.fv-overview > *`: `.fv-todo--strip`
 * má vlastní `margin-bottom` a při shodné váze vyhrává to, co stojí v souboru
 * níž. Selektor se dvěma třídami je silnější, takže na pořadí nezáleží. */
.fv-overview > .fv-todo {
  grid-area: ukol;
  margin-bottom: 0;
}

.fv-overview > .fv-tiles {
  grid-area: dlazdice;
  margin: 0;
}

/* Pravý sloupec má obal (zadavatel 21. 8. 2026, viz `prehled.html`). Na úzké
 * obrazovce je obal `display: contents`, takže tři bloky jsou položkami
 * mřížky jako dřív — proto selektory potomka, ne přímého dítěte. */
.fv-overview__right {
  display: contents;
}

.fv-overview .fv-overview__views {
  grid-area: pohledy;
}

.fv-overview .fv-views__tabs {
  grid-area: zalozky;
}

.fv-overview .fv-views__body {
  grid-area: graf;
  padding-top: 0;
}

/* `min-width: 0` na každé buňce: bez něj mřížka roste podle nejširšího obsahu
 * (dlouhé číslo v dlaždici, široká tabulka pod grafem) místo podle sloupce
 * a druhý sloupec se vytlačí ze stránky. Klasická past mřížky.
 *
 * Spodní marže bloků se ruší tamtéž — mezeru mezi řadami má na starosti `gap`
 * a dvojí odstup by se sečetl. */
.fv-overview > *,
.fv-overview__right > * {
  min-width: 0;
  margin-bottom: 0;
}

@media (min-width: 62rem) {
  .fv-overview {
    /* **Grafy dostaly víc než polovinu** (zadavatel 17. 8. 2026: „sekce s grafy
     * nevyužívá plnou šířku stránky"). Bylo 1 : 1,05, tedy 51 % pro graf —
     * dlaždice nesou šest krátkých čísel a graf čtyřicet let, takže stejný díl
     * pro obojí byl dělení podle počtu karet, ne podle toho, co potřebují. */
    grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.28fr);
    grid-template-areas:
      "nazev    pravy"
      "ukol     pravy"
      "dlazdice pravy";
    /* Buňka sedí na horní lince své řady, ne roztažená přes celou její výšku:
     * když se pruh úkolů rozbalí, zůstanou záložky nahoře u svého podtržení,
     * místo aby se jim linka odsunula pod prázdné místo. */
    align-items: start;
  }

  /* Pravý sloupec: tři řady přes `subgrid`, dokud je pruh úkolů sbalený —
   * nadpis, záložky a graf lícují s nadpisem, pruhem a dlaždicemi vlevo,
   * řada si výšku bere z vyššího z dvojice. Jakmile se pruh rozbalí, obal se
   * přepne na obyčejný sloupec a graf přestane čekat na výšku druhé řady
   * (zadavatel 21. 8. 2026: „graf odjede dolů, oprav to; zarovnání
   * s dlaždicemi se v tomto případě výjimečně poruší"). */
  .fv-overview__right {
    display: grid;
    grid-area: pravy;
    grid-template-rows: subgrid;
    align-items: start;
  }

  .fv-overview__right > .fv-overview__views {
    grid-area: auto;
    grid-row: 1;
  }

  .fv-overview__right > .fv-views__tabs {
    grid-area: auto;
    grid-row: 2;
  }

  .fv-overview__right > .fv-views__body {
    grid-area: auto;
    grid-row: 3;
  }

  /* Při rozbaleném pruhu se obal přepne na obyčejný sloupec: graf přestane
   * čekat na výšku druhé řady a dlaždice sjedou pod pruh. Aby přitom graf ani
   * záložky neuhnuly ani o pixel, měří obě strany první a druhou řadu z týchž
   * tokenů — nadpis bloku má výšku řádku `h1` a sbalený pruh výšku řádku
   * záložek (`--fv-control-row`). Bez toho řady v sevřeném stavu určoval levý
   * sloupec a pravý po odpojení poskočil nahoru o rozdíl (změřeno 21. 8.
   * 2026: 6 px u nadpisu, 8 px u pruhu). */
  .fv-overview:has(> .fv-todo--strip[open]) > .fv-overview__right {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
  }

  .fv-overview .fv-overview__views {
    min-height: calc(var(--fs-30) * var(--lh-heading));
  }

  /* Oba nadpisy v jedné řadě začínají na téže lince. `u-section` dává nadpisu
   * sekce `margin-top: --sp-7`, což je správně tam, kde sekce navazuje na to
   * nad sebou; v první řadě mřížky nad ním není nic a odstup by ho shodil
   * o třicet bodů níž než `h1` vedle. */
  .fv-overview .fv-overview__views {
    margin-top: 0;
  }
}

/* Pobídka k druhému faktoru nad dlaždicemi (zadavatel 30. 8. 2026): jeden
 * tichý řádek přes celou šířku mřížky, věta vlevo, Skrýt vpravo. */
.fv-tiles__mfa {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin: 0;
}

.fv-tiles__mfa form {
  margin: 0;
}

.fv-tiles {
  display: grid;
  /* 240 px drželo dlaždice široké i poté, co už nesly jen číslo a větu.
   * S užším levým sloupcem se při 240 slily do jednoho pruhu. */
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-3);
  /* Vlastní odstup pro stránky, kde dlaždice stojí v běžném toku. Na Přehledu
   * ho mřížka shazuje na nulu — tam odstup dělá `gap`. */
  margin: var(--sp-4) 0 var(--sp-5);
}

/* Dlaždice na Přehledu jsou užší než karty jinde (zadavatel 17. 8. 2026).
 *
 * `--sp-5` je odsazení karty, která nese odstavce; dlaždice nese řádek,
 * číslo a větu, a šest takových s dvaceťšesti body kolem dokola dělalo
 * z rozcestníku svitek. Spolu s vypuštěnou mikrografikou a menším číslem
 * (varianta B) je to třetí úspora na témže místě. */
.fv-tiles .fv-card {
  padding: var(--sp-4);
}

/* Ve dvou sloupcích má levá strana pevně dva sloupce dlaždic, ne `auto-fit`:
 * ten by při 240 px minimu spadl na jeden a šest dlaždic pod sebou je zase
 * ta dlouhá stránka, které se vyhýbáme. */
@media (min-width: 62rem) {
  .fv-overview > .fv-tiles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Jeden sloupec dlaždic, dokud je Přehled užší než 64 rem (zadavatel
   * 7. 9. 2026, snímek z tabletu: „−345 897 Kč“ přeteklo mimo dlaždici).
   * Levý sloupec má 0,72 dílu, takže na tabletu na šířku (1024 px)
   * měla každá ze dvou dlaždic 120 px a číslo o 24 px bylo o polovinu
   * širší než dlaždice. Od 64 rem má dlaždice aspoň 175 px a číslo se
   * do ní vejde i s písmem podle kontejneru (viz `.fv-metric__value`). */
  @container prehled (max-width: 64rem) {
    .fv-overview > .fv-tiles {
      grid-template-columns: minmax(0, 1fr);
    }
  }

  /* Co plán říká (23. 8. 2026): dlaždice přes celou šířku stránky ve třech
   * sloupcích. Šest a pět dlaždic dává 3+3 a 3+2; `auto-fit` na 977 px dělal
   * čtyři sloupce, tedy 4+2 a 4+1, a poslední řada vypadala jako zbytek. */
  .fv-tiles--three {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.fv-form-card {
  max-width: 520px;
}

.fv-chart {
  margin: 0;
}

.fv-chart__menu summary {
  list-style: none;
}

.fv-chart__menu summary::-webkit-details-marker {
  display: none;
}

.fv-chart__menu-list {
  margin: 0;
  font-size: var(--fs-13);
}

/* Series colour set by attribute rather than by an inline style, for the same
 * CSP reason. Keep in step with the tokens in tokens.css. */
.fv-chart__swatch[data-color="acc"] {
  background: var(--acc);
}
.fv-chart__swatch[data-color="acc2"] {
  background: var(--acc2);
}
.fv-chart__swatch[data-color="warn"] {
  background: var(--warn);
}
.fv-chart__swatch[data-color="s1"] {
  background: var(--s1);
}
.fv-chart__swatch[data-color="s2"] {
  background: var(--s2);
}
.fv-chart__swatch[data-color="s3"] {
  background: var(--s3);
}
.fv-chart__swatch[data-color="s4"] {
  background: var(--s4);
}
.fv-chart__swatch[data-color="s5"] {
  background: var(--s5);
}
.fv-chart__swatch[data-color="s6"] {
  background: var(--s6);
}
/* The "you are here" marker of chart 7, which is drawn in the text colour
 * rather than in a series colour. */
.fv-chart__swatch[data-color="mark"] {
  background: var(--tx);
}

/* --- plan pages (5.5) ------------------------------------------------- */
/* The shared anatomy of all nineteen parts. Nothing here is per-part: a part
 * differs in its text and its fields, never in its look (design.md 20). */

.fv-crumb {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-13);
}

.fv-crumb a {
  color: var(--tx2);
}

/* Anything longer than the page has room for goes into a disclosure, which is
 * how a plan part stays inside two screens (5.5). */
.fv-disclosure {
  margin: var(--sp-4) 0;
  border: var(--bw) solid var(--line-c);
  /* Rozbalovací blok bez rámečku má aspoň linku nahoře (návrh, oddíl 2b). */
  border-top-width: max(var(--bw), 1px);
  border-radius: var(--r-card);
  background: var(--surf-c);
  box-shadow: var(--shadow-card);
  padding: var(--sp-3) var(--sp-4);
}

.fv-disclosure > summary {
  cursor: pointer;
  font-weight: 600;
}

.fv-disclosure > summary:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

.fv-disclosure > * + * {
  margin-top: var(--sp-3);
}

/* Položky plánu na Přehledu (13. 9. 2026): řádek části se jménem vlevo
 * a souhrnem vpravo, tabulka až po rozbalení. Sbalené řádky jsou těsné,
 * aby devatenáct částí nedělalo z Přehledu svitek; táž soupiska jako na
 * Celém plánu. Trojúhelník `summary` se u řádku ve flexu nekreslí, takže
 * šipku za jménem dělá `::after` jako u panelu rychlých změn. */
.fv-items__part {
  margin: var(--sp-2) 0;
  padding: var(--sp-2) var(--sp-4);
}

/* Dva sloupce, ne jméno vlevo a souhrn u pravého okraje (nález zadavatele
 * 16. 9. 2026: „na širokém monitoru jsem se ztrácel a nevěděl kde jsem“).
 * Řádky jsou dál stejně široké, ale souhrn začíná hned za nejdelším jménem,
 * ne o tisíc pixelů dál: na 1400 px stránce končilo jméno na 40 až 120 px
 * a souhrn začínal na 1200 až 1300 px, takže oko přejíždělo prázdno.
 *
 * Sloupec je pevný, protože každý řádek je vlastní `details` a mřížka se
 * mezi nimi nedomluví (`display: contents` na `details` prohlížeč neprovede).
 * 13 rem je nejdelší dnešní jméno (*Dary, které chcete dát*, 177 px) a ještě
 * kus navíc; delší jméno se v sloupci zalomí, sloupce zůstanou srovnané. */
.fv-items__part > summary {
  display: grid;
  grid-template-columns: 13rem max-content;
  align-items: baseline;
  gap: var(--sp-1) var(--sp-4);
  list-style: none;
}

/* Na úzké obrazovce se souhrn vrací pod jméno: dva sloupce by se nevešly. */
@media (max-width: 640px) {
  .fv-items__part > summary {
    grid-template-columns: minmax(0, 1fr);
  }
}

.fv-items__part > summary::-webkit-details-marker {
  display: none;
}

.fv-items__label::after {
  content: " ▾";
  color: var(--tx2);
}

.fv-items__part[open] > summary .fv-items__label::after {
  content: " ▴";
}

/* Bez `margin-left: auto` (16. 9. 2026): souhrn stojí ve druhém sloupci hned
 * za jménem, ne u pravého okraje řádku. */
.fv-items__summary {
  font-weight: 400;
  font-size: var(--fs-13);
  color: var(--tx2);
}

.fv-items__open {
  font-size: var(--fs-13);
}

/* The linear route of 5.5a: Previous on the left, Next on the right, always
 * both present so "click Next" is advice that always works. */
.fv-route {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
}

/* 5.12 - a view other than average is visible permanently and in gold, so it
 * is never mistaken for the plan itself. */
/* §12.6 asks for a full-width band whenever a view other than the average is
 * on, and since the strip around it is no longer gold this is the band. It
 * therefore has to claim the whole row rather than shrink to its sentence -
 * `flex-basis: 100%` inside the wrapping strip - and it sits below the
 * controls because it is about them. */
.fv-viewbar {
  margin: 0;
  flex: 1 0 100%;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-field);
  background: var(--acc2);
  color: var(--on-gold);
  font-size: var(--fs-13);
  font-weight: 600;
}

.fv-viewbar a,
.fv-viewbar .fv-notice {
  color: var(--on-gold);
}

/* The notice inside it is the band's own sentence, not a card of its own. */
.fv-viewbar .fv-notice {
  margin: 0;
  border: 0;
  background: none;
  padding: 0;
  font-size: inherit;
}

.fv-nav__state {
  margin-left: auto;
  color: var(--acc);
  font-size: var(--fs-13);
}

/* design.md 4.4, body 2, 4, 9, 10 a 11 — interaktivní vrstva grafu.
 * Do 14. 8. 2026 z ní nebylo nic: legenda byla tlačítko bez obsluhy, osa Y
 * nebyla vůbec a rok se nedal ukázat ani myší, ani klávesnicí. */
/* Graf už nesdílí řádek s panelem (zadavatel 17. 8. 2026): panel sešel pod
 * něj, takže plocha dostala zpátky těch 220 bodů — na Přehledu, kde od
 * varianty A sdílí stránku s dlaždicemi, je to skoro třetina.
 *
 * Zůstává to `grid` s jedním sloupcem, ne `block`: `minmax(0, 1fr)` je to,
 * co drží SVG uvnitř rodiče místo aby ho roztlačilo do šířky. */
.fv-chart__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.fv-chart__marker {
  opacity: 0;
}

.fv-chart__marker.is-on {
  opacity: 1;
}

/* 2.1: aktivní scénář v pruhu je odkaz, ne vypnutá roletka. Zlatý bod nese
 * §4.1b — aktivní scénář je vždycky zlatý. */
.fv-topbar__scenario {
  text-decoration: none;
  white-space: nowrap;
}

/* Strop šířky roletky variant (zadavatel 7. 9. 2026). Roletka bere šířku
 * po nejdelším jménu varianty („Kolik potřebuji, abych nemusel(a)
 * pracovat“) a ta jediná volba odsunula Průvodce aplikací na další řadu
 * i na monitoru. Strop je na šířku jména „Vyšší inflace (ze 2 % na 5 %)“
 * (207 px při 13 px Arial, změřeno 7. 9. 2026; bez stropu měla roletka
 * 284 px); delší jméno v zavřené roletce končí třemi tečkami, celé je po
 * najetí myší (`title`, obnovuje ho `app.js`) a v otevřeném seznamu. */
.fv-topbar__scenario select {
  max-width: 14rem;
  text-overflow: ellipsis;
}

.fv-topbar__scenario span[aria-hidden] {
  color: var(--acc2);
}

/* Popisek roletky variant. Vidět, ne jen pro čtečku: jméno varianty vedle
 * zlatého puntíku samo neřeklo, čí jméno to je (15. 8. 2026). */
.fv-topbar__scenario-label {
  color: var(--tx2);
  font-size: var(--fs-13);
}

/* 11.2: dopočet vedle zadané hodnoty. Je to nabídka, ne oprava — proto
 * tlačítko, ne automatika, a proto to stojí vedle sebe. */
.fv-restated {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-3);
  color: var(--tx2);
  font-size: var(--fs-13);
}

/* 8.4: řazení a filtr nad soupiskou, od osmi řádků výš. */
.fv-table-controls {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  font-size: var(--fs-13);
}

.fv-table-controls select {
  max-width: 22ch;
  padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-field);
}

.fv-table th a {
  color: inherit;
}

/* §14 graf 11: skóre po pilířích jako segmentovaný pruh. Kreslí se z téhož
 * čísla, které stojí vedle — pruh je `aria-hidden`, takže odečítač čte zlomek
 * a ne dvakrát totéž. Šířku nese `data-share`, aby v šabloně nebyl `style`. */
.fv-pillar {
  display: inline-block;
  width: 64px;
  height: 6px;
  margin-right: var(--sp-2);
  border-radius: var(--r-chip);
  background: var(--surf2);
  vertical-align: middle;
  overflow: hidden;
}

.fv-pillar__fill {
  display: block;
  height: 100%;
  border-radius: var(--r-chip);
  background: var(--acc);
}

/* §14 graf 2: sloupce se od čar liší tvarem, ne jen barvou — legenda proto
 * nese čtvereček místo čárky. */
.fv-chart__swatch--bar {
  height: 10px;
  border-radius: 2px;
}

/* 9: najetí ztlumí ostatní na 25 % krytí, kliknutí je skryje. */
.fv-chart__plot [data-series].is-dim {
  opacity: 0.25;
}

.fv-chart__plot [data-series].is-off {
  display: none;
}

/* Plocha s přechodem pod čarou (styl Novinový); jde s čarou. */
.fv-chart__area {
  opacity: var(--chart-area);
  pointer-events: none;
}

.fv-chart__plot [data-area].is-dim {
  opacity: calc(var(--chart-area) * 0.25);
}

.fv-chart__plot [data-area].is-off {
  display: none;
}

/* Pod grafem, na jeho šířku. Oddělení shora čarou místo zleva — panel už
 * není sloupec vedle, je to pás pod. */
.fv-chart__panel {
  border-top: 1px solid var(--line);
  padding-top: var(--sp-3);
  margin-top: var(--sp-3);
  font-size: var(--fs-13);
}

.fv-chart__panel-title {
  margin: 0 0 var(--sp-2);
  color: var(--tx2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: var(--fs-12);
}

/* Čísla vedle sebe, ne pod sebe: v pruhu přes celou šířku by sloupec tří
 * položek nechal dvě třetiny prázdné. `auto-fit` je nechá zalomit samo, až
 * jich bude víc nebo bude úzko. */
.fv-chart__panel-list {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--sp-2) var(--sp-4);
}

.fv-chart__panel-list div {
  margin-bottom: 0;
}

.fv-chart__panel-list dt {
  color: var(--tx2);
}

.fv-chart__panel-list dd {
  margin: 0;
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
}

.fv-chart__slider {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-2) 0 0;
}

.fv-chart__slider input[type="range"] {
  flex: 1;
  min-width: 0;
}

.fv-chart__datatable tr.is-chosen {
  background: var(--surf2);
}

/* 6: pod 640 px zjednodušená verze — panel pod grafem, nejvýš dvě řady,
 * a datová tabulka se ukáže, protože na úzké obrazovce je čitelnější než
 * křivka. Musí být za `.sr-only`, aby ji přebila. */
@media (max-width: 640px) {
  .fv-chart__body {
    grid-template-columns: minmax(0, 1fr);
  }

  .fv-chart__panel {
    border-left: 0;
    border-top: 1px solid var(--line);
    padding: var(--sp-3) 0 0;
  }

  /* Nejvýš dvě řady. Značka je na prvku, ne `:nth-of-type` — ten počítá
   * sourozence téhož druhu, takže u sloupcového grafu (dvě `<g>` mezi jinými
   * `<g>`) schoval výdaje a graf tvrdil, že se jen přijímá. */
  .fv-chart__plot [data-extra] {
    display: none;
  }

  /* Tabulka pod grafem se na úzké obrazovce **taky schovává** (rozhodnuto
   * zadavatelem 15. 8. 2026). Do té chvíle se tu odkrývala sama, protože na
   * telefonu je graf hůř čitelný — jenže „hůř čitelný" není „nečitelný",
   * a rozvinutá tabulka pod každým grafem z Přehledu na mobilu udělala
   * několikametrový svitek. Volba „Zobrazit jako tabulku" v nabídce grafu
   * je na telefonu stejně dostupná jako na počítači, takže ať rozhodne
   * uživatel. */
}

/* 4.3: průvodce prostředím. Číslovaný seznam, ne překryv nad aplikací —
 * stránka jde otevřít znovu a přečte ji i odečítač. */
.fv-tour {
  margin: var(--sp-4) 0;
  padding-left: var(--sp-4);
}

.fv-tour__stop {
  margin-bottom: var(--sp-4);
}

/* 24.1, varianta C: dnešní stav plánu vedle odpovědi z dotazníku. Řádek pod
 * polem, ne druhé pole — jsou to dvě různá čísla a splynout nesmějí. */
.fv-field__plan {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
  color: var(--tx2);
  font-size: var(--fs-13);
}

/* 24.6: co si u položky z dotazníku plán domýšlí. Věta pod názvem, ne štítek
 * navíc — štítků by v jednom řádku byly tři a přestaly by se číst. */
.fv-row-note {
  display: block;
  color: var(--tx2);
  font-size: var(--fs-13);
}

/* Nálezy 3.1 a 4.1: kudy začít. Pruh, ne dlaždice — je to jedna věta a dvě
 * cesty, a dlaždice by v mřížce dlaždic zmizela mezi nimi. */
.fv-start {
  border: 1px solid var(--line);
  border-left: 3px solid var(--acc);
  border-radius: 0 var(--r-field) var(--r-field) 0;
  background: var(--surf);
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-4);
}

.fv-start__text {
  margin: 0 0 var(--sp-3);
}

.fv-start__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
}

/* Příloha 1: co brání uložení. Barva sama nestačí (design.md 4.9), takže je
 * u toho i rámeček a věta — a pole, kterého se to týká, nese `is-wrong`. */
.fv-problems {
  border: 1px solid var(--warn);
  border-radius: var(--r-field);
  padding: var(--sp-3);
  margin-bottom: var(--sp-4);
}

.fv-problems__title {
  font-weight: 600;
  margin: 0 0 var(--sp-2);
}

.fv-problems ul {
  margin: 0;
  padding-left: var(--sp-4);
}

.fv-field.is-wrong .fv-field__control {
  border-color: var(--warn);
}

/* Průřezové téma B: měsíc jede vedle roku v jednom rámečku, protože „od března
 * 2027“ je jedna odpověď. Měsíc je užší a oddělený linkou, aby bylo vidět, že
 * jsou to dvě roletky a ne jedna rozseknutá. */
.fv-field__input--month {
  flex: 0 0 auto;
  max-width: 11ch;
  border-right: 1px solid var(--line);
  padding-right: var(--sp-3);
  margin-right: var(--sp-3);
}

.fv-field__control--plain {
  border: 0;
  background: none;
  padding: 0;
}

/* Scoped by type on purpose. This wrapper was written for a checkbox, and a
   bare `input` selector also caught the file field on the import page - which
   came out as a 1,1rem square with the filename clipped to one letter. */
.fv-field__control--plain input[type="checkbox"],
.fv-field__control--plain input[type="radio"] {
  width: 1.1rem;
  height: 1.1rem;
  accent-color: var(--acc);
}

.fv-field__control--plain input[type="file"] {
  width: 100%;
  min-width: 0;
  font: inherit;
  color: var(--tx);
}

.fv-field__control--plain input[type="file"]::file-selector-button {
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  color: var(--tx);
  cursor: pointer;
  font: inherit;
  margin-right: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
}

.fv-field__control--plain input[type="file"]::file-selector-button:hover {
  border-color: var(--acc);
}

.fv-basis__option input {
  margin-right: var(--sp-1);
  accent-color: var(--acc);
}

/* --- 4.1 the menu on a phone ----------------------------------------- */
/* "Mobil: menu je skryte a otevira se tlacitkem pres obsah (prekryv), nikdy
 * jako horni lista." Without this the 236 px menu keeps its column and the
 * content gets 139 px on a 375 px screen - which is what happened. */

.fv-nav-open {
  display: none;
}

@media (max-width: 900px) {
  .fv-shell {
    grid-template-columns: 1fr;
  }

  .fv-nav-open {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    top: var(--sp-3);
    left: var(--sp-3);
    z-index: 30;
    width: 40px;
    height: 40px;
    border: 1px solid var(--line);
    border-radius: var(--r-field);
    background: var(--surf);
    color: var(--tx);
    font-size: var(--fs-19);
    cursor: pointer;
  }

  .fv-nav {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 40;
    width: 236px;
    height: auto;
    transform: translateX(-100%);
    transition: transform 180ms ease;
    overflow-y: auto;
    border-right: 1px solid var(--line);
  }

  /* No handle on a phone: there is no collapsed state to reach: the menu is
   * an overlay that opens and closes with the button above the strip. */
  .fv-nav__grip {
    display: none;
  }

  /* The overlay scrolls as one, so the inner scroll region is not needed and
   * would give the menu two scrollbars. */
  .fv-nav__scroll {
    overflow-y: visible;
  }

  .fv-shell[data-mobile-menu="open"] .fv-nav {
    transform: none;
  }

  /* The button sits over the strip, so the strip starts to the right of it. */
  .fv-topbar {
    padding-left: calc(40px + var(--sp-5));
    /* And it scrolls away again. Stacked into a column on a phone the strip is
     * some 365 px tall - nearly half an 812 px screen - so pinning it would
     * take the page away rather than keep the controls to hand. 4.11 already
     * treats the narrow strip as a different thing; this is the same line. */
    position: static;
  }

  /* A collapsed desktop menu must not become a 64 px sliver on a phone.
   *
   * **A nesmí udělat sloupek ani z obsahu stránky** (zadavatel 13. 9. 2026,
   * snímek z tabletu na výšku: celý pruh i stránka v proužku 64 px, hodnoty
   * po písmenech). `.fv-shell[data-menu="collapsed"]` má vyšší specificitu
   * než `.fv-shell` nahoře v tomhle bloku, takže dvousloupcová mřížka
   * zasunutého menu tady přebíjela jednosloupcovou; menu je na úzké
   * obrazovce `fixed` a mimo tok, obsah se tím stal prvním prvkem mřížky
   * a spadl do prvního sloupce širokého jako zasunuté menu. Zasunutí si
   * prohlížeč pamatuje, proto to potkalo tablet, na kterém se menu zasunulo
   * naležato, a telefon ne. Pod 900 px zasunutí neplatí v ničem: mřížka,
   * značka, počty, přepínač vzhledu, přepínač role i řádek nastavení
   * vypadají jako u rozbaleného menu. */
  .fv-shell[data-menu="collapsed"] {
    grid-template-columns: 1fr;
  }

  .fv-shell[data-menu="collapsed"] .fv-nav {
    width: 236px;
  }

  .fv-shell[data-menu="collapsed"] .fv-nav__label,
  .fv-shell[data-menu="collapsed"] .fv-nav__group,
  .fv-shell[data-menu="collapsed"] .fv-nav__brand .name,
  .fv-shell[data-menu="collapsed"] .fv-nav__switch {
    display: revert;
  }

  .fv-shell[data-menu="collapsed"] .fv-nav__count {
    margin-left: auto;
  }

  .fv-shell[data-menu="collapsed"] .fv-theme {
    flex-direction: row;
    align-self: auto;
    border-radius: 999px;
  }

  .fv-shell[data-menu="collapsed"] .fv-nav__tools {
    flex-direction: row;
    align-items: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .fv-nav {
    transition: none;
  }
}

/* Long result values wrap rather than pushing the strip off the screen. */
.fv-result__value {
  overflow-wrap: anywhere;
}

/* Jednorázový registrační odkaz na /admin/pozvanky je delší než mobilní
 * displej — láme se, místo aby stránku roztáhl do vodorovného posuvníku. */
.fv-invite-link {
  overflow-wrap: anywhere;
}

/* --- 4.9 / 5 the Sloupce layout for scenarios ------------------------- */
/* design.md 3: deliberately without rounded corners, so the columns read as a
 * comparison table rather than as a row of cards. */

/* --------------------------------- jedna varianta plánu (18. 8. 2026) --- */

/* Sloupce vedle sebe znamenají u tří variant třicet šest údajů naráz. Tohle
 * ukazuje **jednu** variantu: vlevo odpověď, vpravo z čeho je. Sloupce vrací
 * přepínač *Porovnat* — nezmizely, jen přestaly být to první, co je vidět.
 *
 * Levý sloupec je širší, protože nese rozcestí obou křivek; oko padne první
 * na obrázek a na větu vedle něj, a to je záměr. */
.fv-variant {
  display: grid;
  gap: var(--sp-4);
  margin: var(--sp-4) 0 var(--sp-5);
}

@media (min-width: 62rem) {
  .fv-variant {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    align-items: start;
  }
}

.fv-variant__answer,
.fv-variant__working {
  display: grid;
  gap: var(--sp-4);
  min-width: 0;
}

/* Pruh s roletkou a přepínačem. Ovládání jedné stránky, ne hlavička: drží se
 * na jednom řádku, dokud se vejde. */
.fv-variant__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-4) 0;
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--line);
}

.fv-variant__pick {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.fv-variant__pick .fv-field__input {
  max-width: 22rem;
}

/* Uložit a Zrušit nahoře i dole na stránce varianty (zadavatel 22. 8. 2026):
 * vedle sebe, tlačítko i formulář „Zahodit" na jednom řádku. */
.fv-variant__save {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-3) 0 var(--sp-4);
}

.fv-variant__save .fv-inline-form {
  margin: 0;
}

/* Řádky rychlých variant s políčky (události §21.2, cesty výnosů). Název
 * má základ 16rem a roste, políčko má základ 8rem a strop 14rem, takže se
 * buď vejde celé, nebo jde na další řádek. Se základem 0 dostávalo políčko
 * jen zbytek řádku — a když název nesl celou větu popisu, zbyl mu na šířku
 * 16 px a na telefonu řádek přetekl z karty (zadavatel 22. 8. 2026).
 * Na telefonu je všechno pod sebou: název, popisek, políčko, tlačítko. */
form.fv-section-row--form {
  flex-wrap: wrap;
}

form.fv-section-row--form > span:first-of-type {
  flex: 1 1 16rem;
  min-width: 0;
}

form.fv-section-row--form > .fv-field__input {
  flex: 1 1 8rem;
  max-width: 14rem;
}

@media (max-width: 640px) {
  form.fv-section-row--form > span:first-of-type,
  form.fv-section-row--form > .fv-field__label,
  form.fv-section-row--form > .fv-field__input,
  form.fv-section-row--form > .fv-field__hint {
    flex: 1 1 100%;
  }

  form.fv-section-row--form > .fv-field__input {
    max-width: none;
  }

  form.fv-section-row--form > .fv-field__label {
    margin-bottom: 0;
  }
}

/* Vlastní průběh výnosů (22. 8. 2026): řádky rok → posun v p. b., dva prvky
 * vedle sebe, řádky pod sebou. Úzké, protože čísel je málo. Úvod zabere
 * celou šířku řádku, řádky a tlačítko jdou pod něj — v jednom řádku by
 * vedle úvodu zbylo políčkům pár desítek pixelů. */
.fv-own-course {
  flex-wrap: wrap;
  align-items: flex-end;
}

.fv-own-course > span {
  flex: 1 1 100%;
}

.fv-own-course__rows {
  display: grid;
  gap: var(--sp-2);
  margin: var(--sp-2) 0;
  flex: 0 0 auto;
}

.fv-own-course__row {
  display: grid;
  grid-template-columns: minmax(0, 8rem) minmax(0, 8rem);
  gap: var(--sp-2);
}

/* Jak se k hodnotě přepisu došlo — drobným písmem pod řádkem změny. */
.fv-variant__note {
  font-size: var(--fs-13);
}

/* Nadpisy pravých dlaždic jsou nadpisy, ne popisky (zadavatel 22. 8. 2026). */
.fv-variant__working .fv-subhead {
  margin: 0 0 var(--sp-3);
}

/* Akce vpravo, aby pruh nečetl jako řada stejně důležitých tlačítek. */
.fv-variant__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-left: auto;
}

.fv-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0;
  margin: var(--sp-4) 0;
  border: 1px solid var(--line);
  background: var(--surf);
}

.fv-column {
  padding: var(--sp-4);
  border-left: 1px solid var(--line);
}

.fv-column:first-child {
  border-left: 0;
}

/* 4.9: the active scenario carries a coloured bar, and gold is reserved for
 * "the one that drives the overview" (design.md 1). */
.fv-column--active {
  border-top: 3px solid var(--acc2);
}

.fv-column__title {
  font-family: var(--font-display);
  font-weight: 700;
  margin: 0 0 var(--sp-2);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}

.fv-column__note {
  font-size: var(--fs-13);
  color: var(--tx2);
  margin: 0 0 var(--sp-3);
}

.fv-column__changes {
  margin: 0 0 var(--sp-3);
  padding-left: var(--sp-5);
  font-size: var(--fs-13);
  color: var(--tx2);
}

/* Rozcestí dvou plánů (§14 graf 13, přestavba scénářů 15. 8. 2026). Základní
 * plán šedě a přerušovaně, scénář plnou čarou v akcentní barvě, svislá značka
 * tam, kde se rozešly. Výška 64 px je dvojnásobek microchartu u dlaždice:
 * tenhle obrázek nese dvě křivky a rozdíl mezi nimi je celé sdělení. */
.fv-fork {
  display: block;
  width: 100%;
  height: 64px;
  margin: 0 0 var(--sp-3);
}

.fv-fork__base {
  stroke: var(--tx2);
  opacity: 0.55;
}

.fv-fork__line {
  stroke: var(--acc);
}

.fv-fork__mark {
  stroke: var(--line);
}

.fv-fork.is-private {
  filter: blur(4px);
}

/* Rozdíl proti základnímu plánu — to, kvůli čemu scénář vznikl, tedy největší
 * písmo ve sloupci. Barva jde po znaménku stejně jako u `fv-result__delta`
 * v porovnání; „flat“ je záměrně bez barvy, protože nula není směr. */
.fv-column__lead {
  margin: 0 0 var(--sp-3);
}

.fv-column__delta {
  margin: 0 0 var(--sp-1);
  font-family: var(--font-display);
  /* Krok ze škály §2 designu, ne mezistupeň — mezi 16 a 19 nic není. */
  font-size: var(--fs-19);
  line-height: var(--lh-heading);
}

.fv-column__delta[data-dir="up"] {
  color: var(--acc);
}

.fv-column__delta[data-dir="down"] {
  color: var(--warn);
}

.fv-column__human {
  margin: var(--sp-2) 0 0;
  font-size: var(--fs-15);
  color: var(--tx2);
}

/* Pět čísel §5.8 zůstává vedle sebe, jen přestala být to první, co je vidět. */
.fv-column__kpi-head {
  margin: var(--sp-4) 0 var(--sp-2);
  font-size: var(--fs-13);
  color: var(--tx2);
  text-transform: none;
}

.fv-column__kpi {
  margin: 0;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-1) var(--sp-3);
  font-size: var(--fs-13);
}

.fv-column__kpi dt {
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-column__kpi dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* Pod sebou, ne vedle sebe (17. 8. 2026, spolu s variantou S3).
 *
 * Sloupec karty má v mřížce minimum 220 px a „Nastavit jako aktivní" je samo
 * 136 px, takže se čtyři akce stejně lámaly — jen roztřepeně, na tři nestejně
 * dlouhé řádky. Záměrný sloupec vypadá líp než náhodné zalomení a svislé
 * proužky se v něm srovnají pod sebe, což je přesně ta „značka v knize",
 * kvůli které se S3 vybíralo.
 *
 * `align-items: flex-start`, aby proužek končil u textu a netáhl se přes
 * celou šířku karty. */
.fv-column__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-1);
  margin: var(--sp-4) 0 0;
}

.fv-column__actions form {
  display: inline;
}

.fv-section-row form {
  display: inline;
}

/* --- 4.14 finding card, and the priority task ------------------------- */
/* 9.5: the priority task is the same card with a gold frame. There is only
 * ever one - two priorities are none. */

.fv-priority {
  border: 2px solid var(--acc2);
}

.fv-finding + .fv-finding {
  margin-top: var(--sp-3);
}

.fv-finding .fv-column__title,
.fv-priority .fv-column__title {
  font-size: var(--fs-19);
}

/* Nadpis nad názvem podnětu („Prioritní úkol“ v kartě Co udělat teď). Uvnitř
 * karty, ne nad ní: karta „Co udělat teď“ má vlastní `h2` a druhý nadpis
 * v jedné kartě by z ní udělal dvě. */
.fv-card__kicker {
  display: block;
  color: var(--tx2);
  font-size: var(--fs-12);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --- F11-8 rychlé páky u přepínače scénáře ----------------------------- */
/* Obsah prvního prvku pruhu, ne sedmý prvek: §5.4 má závazný výčet šesti.
 * `details`, aby to bez skriptu fungovalo stejně. */

.fv-levers {
  position: relative;
}

.fv-levers__hint {
  font-size: var(--fs-13);
  margin: calc(-1 * var(--sp-2)) 0 var(--sp-2);
}

.fv-levers__form {
  position: absolute;
  z-index: 20;
  top: calc(100% + var(--sp-2));
  left: 0;
  display: grid;
  /* 12ch, ne 8ch: od 22. 8. 2026 je tu i cíl „chci zanechat" v korunách
   * s oddělovačem tisíců a osm znaků na „2 000 000" nestačilo. */
  grid-template-columns: auto 12ch;
  align-items: center;
  gap: var(--sp-2);
  width: max-content;
  max-width: min(92vw, 30rem);
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surf);
}

/* Vysvětlivka a tlačítka jdou přes obě sloupce mřížky. */
.fv-levers__form > p {
  grid-column: 1 / -1;
  margin: 0;
}

.fv-levers__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}

/* --- F11-2 změna proti minulému snímku --------------------------------- */
/* Směr a datum, ne známka. Barva říká, kam se to pohnulo; slovo k ní patří
 * v textu, protože rozdíl nesmí stát jen na barvě (design.md §1). */
.fv-metric__change {
  font-size: var(--fs-12);
  font-family: var(--font-data);
}

.fv-metric__change[data-dir="up"] {
  color: var(--acc);
}

.fv-metric__change[data-dir="down"] {
  color: var(--warn);
}

.fv-metric__change[data-dir="same"],
.fv-metric__change[data-dir="drift"] {
  color: var(--tx2);
}

/* Věta o změně pod rukama je delší než štítek a nesmí se lepit na číslo. */
.fv-metric__change[data-dir="drift"] {
  display: block;
  margin-top: var(--sp-1);
  font-family: inherit;
}

/* §4.11: pod třetím číslem cesta k volbě. Tiché a malé — je to nabídka, ne
 * ovládání pruhu. */
.fv-result__pick {
  /* Vpravo vedle čtvrtého čísla, ne pod ním (zadavatel 23. 8. 2026); od
   * 7. 9. 2026 malé tlačítko `fv-topbar__action` na účaří hodnot. */
  flex: 0 0 auto;
}

/* Na telefonu se vedle čtyř čísel odkaz nevejde: čísla by zbyla na 48 px
 * a lámala se po slabikách. Jeden řádek pod nimi, vpravo, bez mezer. Tady,
 * ne v bloku 900 px výš: pravidlo nad tímhle by ho přebilo pořadím. */
@media (max-width: 900px) {
  .fv-result__pick {
    flex: 0 0 auto;
  }

  /* První z dvojice odsune obě k pravému okraji řádku pod čísly. */
  a.fv-result__pick:first-of-type {
    margin-left: auto;
  }
}

/* --- F11-5 police čísel ------------------------------------------------ */
/* Vedle šesti dlaždic širší police. Bez známek: karta má dva stavy a rozdíl
 * mezi nimi nestojí na barvě (design.md §1) — nespočítaný ukazatel nese
 * šrafování, jediná věc, kterou Boldin dělá s pásmy dobře. */

.fv-shelf {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
}

.fv-shelf__count {
  margin-bottom: var(--sp-4);
  color: var(--tx2);
}

.fv-shelf__card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

/* Odkud se počítá (13. 9. 2026): jeden odkaz na každou část, ze které číslo
 * vzniká, podle váhy; do té doby jedno tlačítko na první z nich. Řádek
 * drobným písmem nad tlačítky, přilepený ke spodku karty s nimi. */
.fv-shelf__sources {
  margin: auto 0 0;
  color: var(--tx2);
  font-size: var(--fs-13);
  line-height: 1.5;
}

.fv-shelf__sources-label {
  margin-right: var(--sp-1);
}

.fv-shelf__sources a {
  white-space: nowrap;
}

.fv-shelf__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
}

.fv-shelf__pinned {
  margin: 0;
  color: var(--acc);
  font-size: var(--fs-13);
}

.fv-shelf__nodata {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  color: var(--tx2);
  font-size: var(--fs-13);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Šrafování, ne šedá plocha: rozdíl „nemáme data“ proti „spočítáno“ musí být
 * poznat i bez barvy. */
.fv-shelf__hatch {
  width: 2.2em;
  height: 0.9em;
  border: 1px solid var(--line);
  border-radius: 2px;
  background-image: repeating-linear-gradient(
    45deg,
    var(--line) 0,
    var(--line) 1px,
    transparent 1px,
    transparent 5px
  );
}

/* --- F11-3 blok se záložkami pod dlaždicemi ---------------------------- */
/* Změna §5.4 rozhodnutá zadavatelem 14. 8. 2026. Záložky s názvy, ne karusel:
 * Boldin má na témž místě tři grafy za třemi tečkami a kdo neklikne, dva
 * z nich nikdy neuvidí. */

.fv-views__tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: var(--sp-1);
  box-sizing: border-box;
  min-height: var(--fv-control-row);
  border-bottom: 1px solid var(--line);
}

.fv-views__tab {
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 2px solid transparent;
  color: var(--tx2);
  text-decoration: none;
}

.fv-views__tab:hover {
  color: var(--tx);
}

/* Vybraná záložka se nepozná jen barvou (design.md §1): nese i linku pod
 * sebou a `aria-current`, takže ji odečítač jmenuje. */
.fv-views__tab.is-on {
  border-bottom-color: var(--acc);
  color: var(--tx);
  font-weight: 600;
}

.fv-views__body {
  padding-top: var(--sp-4);
}

.fv-views__summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--sp-4);
  margin: 0;
}

.fv-views__summary dt {
  color: var(--tx2);
  font-size: var(--fs-12);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.fv-views__summary dd {
  margin: var(--sp-1) 0 var(--sp-2);
}

/* Posuvník roku pod Sankey. Popisek, rozsah, vybraný rok a tlačítko v řadě —
 * a `output` nese rok i s věkem, protože „2029“ samo o sobě nic neříká. */
.fv-sankey .fv-chart__slider {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}

.fv-sankey .fv-chart__slider output {
  min-width: 9ch;
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
}

/* Rok nad jezdcem (zadavatel 19. 8. 2026). Třídu přidává skript, který
 * `output` zároveň vodí za palcem — bez skriptu zůstane rok v řadě vedle
 * posuvníku, kde ho vykreslil server. Horní odsazení drží místo, aby
 * bublina nelezla do obrázku nad sebou. */
.fv-chart__slider--live {
  position: relative;
  padding-top: 30px;
}

/* Dvě třídy kvůli specificitě: pravidlo `.fv-sankey .fv-chart__slider output`
 * výš by jinak vyhrálo min-width a bublina by byla zbytečně široká. */
.fv-chart__slider.fv-chart__slider--live output {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  min-width: 0;
  padding: 1px var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  background: var(--surf2);
  font-size: var(--fs-13);
  white-space: nowrap;
}

.fv-sankey__legend {
  margin-top: var(--sp-3);
}

/* Legenda pohybu úspor nese totéž šrafování jako uzel v grafu — jinak by
 * rozdíl proti utracené koruně stál jen na barvě (§1 designu). */
.fv-chart__swatch.is-moved {
  border: 1px solid var(--acc2);
  background-color: transparent;
  background-image: repeating-linear-gradient(
    45deg,
    var(--acc2) 0,
    var(--acc2) 2px,
    transparent 2px,
    transparent 6px
  );
}

/* Uzly a stuhy mají vlastní barvu z řady, takže popisky u nich musí zůstat
 * čitelné i tam, kde se stuhy překrývají. Krytí drží graf; tohle je pojistka
 * pro text nad nejsytější stuhou. */
.fv-sankey .fv-chart__plot text {
  paint-order: stroke;
  stroke: var(--surf);
  stroke-width: 2.5px;
  stroke-linejoin: round;
}

/* Uzel nese bublinu s částkou (zadavatel 25. 8. 2026), takže kurzor musí
 * říct, že se nad ním něco dozvím. Bublina je nativní SVG `<title>`, tedy
 * bez skriptu a s tím, co ohlásí i odečítač. */
.fv-sankey__node {
  cursor: help;
}

/* --- F11-6 číslo uvnitř věty ------------------------------------------ */
/* Věta „máte míru úspor 20,0 %“ se čte líp než popisek a hodnota pod sebou —
 * pod podmínkou, že v ní číslo jde najít okem. Podklad a mono, žádný rámeček:
 * je to zvýraznění uvnitř textu, ne štítek.
 *
 * Nepatří na tabulková čísla; tam dělá totéž zarovnaný sloupec. */
.fv-num {
  padding: 0 0.28em;
  border-radius: var(--r-field);
  background: var(--surf2);
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  /* Mono je opticky větší než tělo, takže by věta o číslo poskakovala. */
  font-size: 0.94em;
  /* Řádkování zůstává na větě: `line-height` na zvýraznění by rozestrčilo
     odstavec, ve kterém je čísel víc. */
  line-height: inherit;
  white-space: nowrap;
}

/* --- 5.4 karta „Co udělat teď“ (F11-1) -------------------------------- */
/* Trvalá karta nad dlaždicemi. Do 15. 8. 2026 tu byl pruh „Kudy začít“, který
 * uměl říct, kolik částí je vyplněných, ne kudy dál a za jak dlouho. */

.fv-todo {
  margin-bottom: var(--sp-5);
}

.fv-todo__title {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-19);
}

/* Karta podnětu uvnitř karty úkolu nemá mít druhý rám — rám nese ta vnější,
 * a zlatý rámeček prioritního úkolu (§4.14) se drží u něj. */
.fv-todo .fv-card {
  margin: 0;
}

.fv-todo__steps {
  margin: 0 0 var(--sp-3);
  padding: 0;
  list-style: none;
}

.fv-todo__step {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2);
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--line);
}

.fv-todo__step:last-child {
  border-bottom: 0;
}

/* Fajfka má pevné místo, aby názvy kroků stály pod sebou i tehdy, když je
 * jeden hotový a druhý ne. Rozdíl nesmí stát jen na barvě (design.md §1),
 * takže hotový krok nese značku a čtečka k němu slyší slovo „hotovo“. */
.fv-todo__mark {
  flex: 0 0 1.2em;
  color: var(--acc);
}

.fv-todo__step.is-done > a {
  color: var(--tx2);
}

.fv-todo__summary {
  color: var(--tx2);
  font-size: var(--fs-13);
}

/* Poslední řádek není úkol, ale cíl, ke kterému čtyři nad ním vedou. */
.fv-todo__step--goal > a {
  font-weight: 600;
}

.fv-todo__budget {
  margin-bottom: 0;
}

/* The category filter of 5.9. The selected one is filled, never coloured red:
 * 5.9 says the counter "nikdy nesviti cervene". */
.fv-badge--on {
  background: var(--acc);
  color: var(--on-gold);
}

/* Zašedlý přepínač výběru do porovnání (zadavatel 19. 8. 2026): plný výběr
 * volbu jen znepřístupní a `title` řekne proč — zmizet nesmí, jinak by
 * nebylo kde se to dozvědět. */
.fv-badge.is-dead {
  color: var(--tx2);
  border-style: dashed;
  cursor: not-allowed;
}

/* Oddělená sekce uvnitř tabulky porovnání: nadpis přes celou šířku na
 * podkladu — nahoře čísla výsledků, pod nadpisem změny zadání a předpokladů
 * (zadavatel 19. 8. 2026). */
.fv-table__section th {
  background: var(--surf2);
  font-weight: 600;
  border-top: 1px solid var(--line);
}

.fv-table__section-row td:first-child {
  color: var(--tx2);
}

/* ------------------------------------------------ 4.10 the timeline (5.7) --- */

/* The geometry is in SVG attributes, not in styles: `style-src 'self'` (12.4)
 * blocks style attributes outright, and unlike a script a style attribute
 * cannot be rescued with a nonce. So this file only ever says what things look
 * like, never where they are. */

.fv-timeline {
  margin: var(--sp-5) 0 var(--sp-4);
  /* Kotva pro bublinu po najetí — táž úloha jako u karty grafu. */
  position: relative;
}

/* Bublina u kurzoru nad bodem osy (zadavatel 19. 8. 2026). Táž řeč jako
 * bublina grafu: hned po najetí, omezená šířka, text zalomený do řádků.
 * `pointer-events: none`, aby si nepřebírala vlastní najetí. */
.fv-timeline__tip {
  position: absolute;
  z-index: 2;
  pointer-events: none;
  max-width: 18rem;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  background: var(--surf2);
  color: var(--tx);
  font-size: var(--fs-13);
  line-height: var(--lh-body);
}

.fv-timeline__tip strong {
  display: block;
  margin-bottom: 2px;
  font-family: var(--font-data);
}

.fv-timeline__track + .fv-timeline__track {
  margin-top: var(--sp-5);
}

.fv-timeline__name {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-13);
  color: var(--tx2);
}

/* Dva pásy jedné osy (varianta A, zadavatel 18. 8. 2026): nahoře přání, dole
 * následky, roky mezi nimi. Jméno pásu nese víc váhy než jméno dráhy uvnitř —
 * dráha říká, koho se milník týká, pás říká, odkud ten bod vůbec je. */
.fv-timeline__band-name {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-13);
  font-weight: 600;
  color: var(--tx);
}

.fv-timeline__band--derived {
  margin-top: var(--sp-3);
}

.fv-timeline__band--derived .fv-timeline__band-name {
  color: var(--tx2);
}

.fv-timeline__rail,
.fv-timeline__ticks {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* `stop-color` has to come from the stylesheet. As a presentation attribute a
 * `var()` is just text and never resolves, so the gradient came out empty and
 * the rail was invisible. */
.fv-timeline__stop1 {
  stop-color: var(--acc);
}

.fv-timeline__stop2 {
  stop-color: var(--acc2);
}

.fv-timeline__line {
  stroke: url(#osa-prechod);
  stroke-width: 4;
  stroke-linecap: round;
}

.fv-timeline__line--derived {
  stroke: var(--acc2);
  stroke-dasharray: 6 6;
}

/* **Značka je prstenec s ikonkou** (varianta B, zvolil zadavatel 18. 8. 2026).
 * Prostředek je podklad, ne barva: čára osy jím prosvítá a značka je o třetinu
 * lehčí než plné kolečko, takže se jich na jednu linku vejde víc — a od
 * 18. 8. 2026 je linka jedna pro všechny milníky. */
.fv-timeline__dot {
  fill: var(--bg);
  stroke: var(--acc);
  stroke-width: 2;
}

/* Ikonka nese `currentColor`, takže stačí obarvit skupinu. Bez `pointer-events`
 * by kresba brala tažení, které patří celé značce. */
.fv-timeline__icon {
  color: var(--acc);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

.fv-timeline__point--derived .fv-timeline__icon {
  color: var(--acc2);
}

/* Značka milníku v grafu (zadavatel 18. 8. 2026): týž prstenec s ikonkou jako
 * na časové ose, jen menší, protože v ploše grafu jich stojí vedle sebe víc.
 * Podklad je plný, aby značka nesplynula s křivkou pod sebou. */
.fv-chart__mark-ring {
  fill: var(--bg);
  stroke: var(--acc);
  stroke-width: 1.5;
}

.fv-chart__mark--derived .fv-chart__mark-ring {
  stroke: var(--acc2);
  stroke-dasharray: 3 2;
}

.fv-chart__mark-icon {
  color: var(--acc);
  fill: none;
  stroke: currentColor;
  /* Značka se 19. 8. 2026 zmenšila na 70 % a tah se zmenšil s ní — tady se
   * mu kousek vrací, aby ikonka v deseti bodech nezešedla do vlasu. */
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

.fv-chart__mark--derived .fv-chart__mark-icon {
  color: var(--acc2);
}

/* Jméno milníku vedle značky (zadavatel 25. 8. 2026). Obrys v barvě podkladu,
 * jako u popisků Sankey: text leží přes křivky a bez něj by se v místě, kde
 * se dvě čáry kříží, nedal přečíst. */
.fv-chart__mark-text {
  font-family: var(--font-data);
  font-size: 9px;
  fill: var(--tx2);
  paint-order: stroke;
  stroke: var(--surf);
  stroke-width: 2.5px;
  stroke-linejoin: round;
}

/* Nožička druhé řady. Tenká a v barvě linky: je to spojnice, ne značka. */
.fv-timeline__stem {
  stroke: var(--line);
  stroke-width: 1.5;
}

/* Komu milník patří. Iniciála, ne jméno: na osu s dvaceti body se jméno
 * nevejde a dvě jména na stejné písmeno rozliší `_initials` samo. */
.fv-timeline__owner {
  font-family: var(--font-data);
  font-size: 11px;
  fill: var(--tx2);
}

/* Název milníku pod iniciálou (zadavatel 5. 9. 2026), jen kde se vejde:
 * totéž písmo a barva jako popisky pruhu na Přehledu, o dva body větší,
 * protože osa má na šířku víc místa. */
.fv-timeline__label {
  font-size: 11px;
  fill: var(--tx2);
  pointer-events: none;
}

/* 4.10: derived points are dashed and in the second accent - a point nobody
 * can move has to look different from one they can. */
.fv-timeline__dot--derived {
  stroke: var(--acc2);
  stroke-dasharray: 3 3;
}

.fv-timeline__point {
  cursor: grab;
  touch-action: none; /* the drag is ours, not the browser's scroll */
}

.fv-timeline__point--derived {
  cursor: default;
}

.fv-timeline__point:focus-visible {
  outline: none; /* replaced by a ring that follows the SVG shape */
}

.fv-timeline__point:focus-visible .fv-timeline__dot {
  stroke: var(--acc);
  stroke-width: 3;
  r: 11;
}

.fv-timeline__point.is-dragging {
  cursor: grabbing;
}

/* Moved but not saved: the table below is where it is committed, so the axis
 * has to admit that what it shows is not yet what is stored. */
.fv-timeline__point.is-moved .fv-timeline__dot {
  fill: var(--acc);
}

/* Ikonka na plném podkladu se překreslí do barvy pozadí — jinak splyne
 * s výplní a značka vypadá jako prázdné kolečko (zadavatel 19. 8. 2026:
 * „posunu milník a zmizí ikonka"). */
.fv-timeline__point.is-moved .fv-timeline__icon {
  color: var(--bg);
}

.fv-timeline__year,
.fv-timeline__tick {
  font-family: var(--font-data);
  font-size: 13px;
  fill: var(--tx2);
}

.fv-timeline__year {
  fill: var(--tx);
}

/* Roky leží **mezi pásy**, takže jsou hranicí obou: linka nad nimi zavírá
 * horní pás a linka pod nimi otevírá spodní. Bez té spodní by roky vypadaly
 * jako popiska horního pásu, a přitom patří stejně oběma. */
.fv-timeline__ticks {
  margin-top: var(--sp-2);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.fv-timeline__yearfield {
  max-width: 8ch;
}

/* Narrow screens: an axis 320 px wide is not a timeline, it is a smudge. The
 * table below says the same thing and stays usable, so the axis scrolls. */
@media (max-width: 40rem) {
  .fv-timeline {
    overflow-x: auto;
  }

  .fv-timeline__rail,
  .fv-timeline__ticks {
    min-width: 34rem;
  }
}

/* --------------------------------------------- 5.9c the whole plan on paper --- */

/* On screen the page is an ordinary page; `fv-print__only` is the wording that
 * only makes sense once the sheet has left the application. */
.fv-print__only {
  display: none;
}

/* Značka na dokumentu, který odešel z aplikace (zadavatel 17. 9. 2026:
 * „barevné logo"). Na obrazovce ji nese levé menu, jenže `.fv-nav` se
 * netiskne, takže doklad i celý plán vycházely bez čehokoli, co by řeklo,
 * čí dokument to je.
 *
 * Značka si nese vlastní přechod přímo v SVG, takže zůstává barevná
 * i v paletě, která všechno ostatní srazila na černou. Slovo „Vize" bere
 * barvu ze značkového tokenu `--logo2`, ne z `--acc`: `--acc` je na papíře
 * černá a je to tak správně, jenže značka není zvýraznění, nýbrž značka. */
.fv-doc-brand {
  display: none;
}

@media print {
  .fv-doc-brand {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    margin: 0 0 var(--sp-5);
    font-family: var(--font-display);
    font-weight: var(--fw-heading);
    font-size: var(--fs-19);
    color: #000000;
  }

  .fv-doc-brand .vize {
    color: var(--logo2);
  }
}

/* --- doklad ve tvaru běžné české faktury (zadavatel 17. 9. 2026) ------- *
 * „Faktura by mohla mít nějakou standardní podobu, na netu jich českých
 * najdeš dost, ať to má nějakou štábní kulturu." Česká faktura staví
 * dodavatele a odběratele proti sobě, platební údaje píše jako dvojice
 * popisek a hodnota a rozpis uzavírá součtem oddělenou linkou. Web to měl
 * jako čtyři karty pod sebou. */
.fv-doc__parties {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-4);
  align-items: start;
}

/* Na telefonu se sloupce složí pod sebe. Dvě adresy vedle sebe na 360 bodech
 * jsou dva sloupce po jednom slově. */
@media (max-width: 640px) {
  .fv-doc__parties {
    grid-template-columns: 1fr;
  }
}

.fv-doc__meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-1) var(--sp-4);
  margin: var(--sp-5) 0;
}

.fv-doc__meta dt {
  color: var(--tx2);
}

.fv-doc__meta dd {
  margin: 0;
}

/* Popis plnění je řádek bez částky: co se účtuje, stojí vlevo, a čísla pod
 * ním jsou jeho rozpis. Období a odkaz na opravovaný doklad jdou pod popis,
 * ne za něj, aby se dlouhá věta nelámala uprostřed data. */
.fv-doc__item {
  font-weight: var(--fw-strong);
}

.fv-doc__item .u-muted {
  display: block;
  font-weight: 400;
  font-size: var(--fs-13);
}

/* Součet je konec dokladu, ne další řádek tabulky. */
.fv-doc__lines tfoot th,
.fv-doc__lines tfoot td {
  border-top: 2px solid var(--line);
  font-weight: var(--fw-heading);
  font-size: var(--fs-19);
}

.fv-print__meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-1) var(--sp-4);
  margin: var(--sp-4) 0;
  font-size: var(--fs-13);
}

.fv-print__meta dt {
  color: var(--tx2);
}

.fv-print__meta dd {
  margin: 0;
}

.fv-print__part + .fv-print__part {
  margin-top: var(--sp-5);
}

/* --- fonts for the printed document (17. 9. 2026) ---------------------- *
 * WeasyPrint merges every `@font-face` of the same family and weight into
 * one embedded subset **by glyph index**, and `fonts.css` gives each family
 * two files: `latin` and `latin-ext`, generated separately and therefore in
 * different glyph orders. The result is a swap: in the whole plan the
 * heading "Příjmy" came out as "P7íjmy" and "Kč" as "Km" - not a mangled
 * text layer but the wrong glyph on the page, which the advance widths in
 * the PDF confirm. A browser is unaffected: it honours `unicode-range`.
 *
 * The cure is that the two files must not share a family. These faces exist
 * only for paged media and only for that reason; the screen keeps the
 * families from `fonts.css` untouched. The files are the same ones, so the
 * browser serves them from its cache when a reader presses Print.
 *
 * Measured in the deployed image, not assumed: with one family the word
 * came out "Úmty Km péme", with two families "Účty Kč péče".
 */
@font-face {
  font-family: "FinVize Display";
  src: url("/static/fonts/bricolage-grotesque-700-latin.woff2") format("woff2");
  font-weight: 700;
}
@font-face {
  font-family: "FinVize Display Ext";
  src: url("/static/fonts/bricolage-grotesque-700-latin-ext.woff2") format("woff2");
  font-weight: 700;
}
@font-face {
  font-family: "FinVize Body";
  src: url("/static/fonts/inter-tight-400-latin.woff2") format("woff2");
  font-weight: 400;
}
@font-face {
  font-family: "FinVize Body Ext";
  src: url("/static/fonts/inter-tight-400-latin-ext.woff2") format("woff2");
  font-weight: 400;
}
@font-face {
  font-family: "FinVize Body";
  src: url("/static/fonts/inter-tight-500-latin.woff2") format("woff2");
  font-weight: 500;
}
@font-face {
  font-family: "FinVize Body Ext";
  src: url("/static/fonts/inter-tight-500-latin-ext.woff2") format("woff2");
  font-weight: 500;
}
@font-face {
  font-family: "FinVize Body";
  src: url("/static/fonts/inter-tight-600-latin.woff2") format("woff2");
  font-weight: 600;
}
@font-face {
  font-family: "FinVize Body Ext";
  src: url("/static/fonts/inter-tight-600-latin-ext.woff2") format("woff2");
  font-weight: 600;
}
@font-face {
  font-family: "FinVize Data";
  src: url("/static/fonts/ibm-plex-mono-400-latin.woff2") format("woff2");
  font-weight: 400;
}
@font-face {
  font-family: "FinVize Data Ext";
  src: url("/static/fonts/ibm-plex-mono-400-latin-ext.woff2") format("woff2");
  font-weight: 400;
}
@font-face {
  font-family: "FinVize Data";
  src: url("/static/fonts/ibm-plex-mono-500-latin.woff2") format("woff2");
  font-weight: 500;
}
@font-face {
  font-family: "FinVize Data Ext";
  src: url("/static/fonts/ibm-plex-mono-500-latin-ext.woff2") format("woff2");
  font-weight: 500;
}

/* The sheet is meant to be carried to an accountant, so it has to be a
 * document: margins that survive a stapler and pages that can be put back in
 * order. Margin boxes are paged media, so a browser ignores this block and
 * prints by its own settings; WeasyPrint (the server-side PDF, 17. 9. 2026)
 * honours it. Only the numbers live here - wording belongs in the content
 * registry, never in a stylesheet. */
@page {
  size: A4;
  margin: 18mm 16mm 20mm;

  @bottom-center {
    content: counter(page) " / " counter(pages);
    font-size: 9pt;
  }
}

@media print {
  /* Háčky a čárky na papíře: viz poznámka u `@font-face` výš. */
  :root {
    --font-display: "FinVize Display", "FinVize Display Ext", system-ui, sans-serif;
    --font-body: "FinVize Body", "FinVize Body Ext", system-ui, sans-serif;
    --font-data: "FinVize Data", "FinVize Data Ext", ui-monospace, monospace;
  }

  /* --- paper palette (zadavatel 17. 9. 2026) -------------------------- */
  /* Papír není obrazovka. Výchozí motiv produktu je **tmavý**: `tokens.css`
   * dává tmavé hodnoty rovnou do `:root` a světlé až pod `[data-theme="light"]`
   * nebo `@media (prefers-color-scheme: light)`. Prohlížeč při tisku motiv
   * nemění a WeasyPrint uživatelské předvolby nevyhodnocuje vůbec, takže se
   * faktura i celý plán sázely na tmavém podkladu. Doklad, který spolkne
   * tiskárně celou kazetu, se účetní nedává.
   *
   * Zadání zadavatele zní: „barevné logo, zbytek černá, pozadí bílé nebo
   * žádné". Barvu si proto nechávají jen dvě věci, a obě proto, že u nich
   * barva nese význam, ne ozdobu:
   *   **značka**, která říká, čí ten dokument je,
   *   **řady grafu**, kde je barva jediné, co odliší čáru od čáry.
   * Všechno ostatní je na papíře černé, včetně `--acc`, `--acc2` a `--warn`.
   *
   * Selektor je zdvojený schválně. `:root` má váhu (0,1,0) a prohrál by
   * s `@media (prefers-color-scheme: light) { :root:not([data-theme]) }`
   * i s `[data-style="vlastni"][data-custom~="hlavicka-barevna"]`, které
   * obarvuje hlavičku tabulky barvou pozadí. `:root:root` má (0,2,0), takže
   * s nimi je na stejné váze a rozhoduje pořadí: `app.css` se načítá jako
   * poslední. Bez toho by tahle paleta platila jen někdy a nikdo by nevěděl
   * kdy. */
  :root:root {
    color-scheme: light;

    /* Podklad bílý, karta bez výplně: na papíře není karta vyvýšenina,
     * ale odstavec. */
    --bg: #ffffff;
    --surf: #ffffff;
    --surf2: #ffffff;
    --field: #ffffff;
    --surf-c: transparent;
    --surf-c2: transparent;
    --panel-bg: #ffffff;
    --zebra: transparent;
    --th-bg: transparent;

    /* Písmo černé. `--tx2` je tmavě šedá, ne černá: vedlejší údaj se od
     * hlavního odlišit musí a samotná velikost písma to na papíře nesvede. */
    --tx: #000000;
    --tx2: #444444;
    --th-c: #000000;

    /* Význam se na papíře slévá do černé. Na jednobarevné tiskárně by
     * z odstínu zelené a odstínu červené vyšly dvě šedé, které od sebe
     * nikdo nepozná, takže rozdíl musí nést slovo, ne barva. */
    --acc: #000000;
    --acc2: #000000;
    --on-gold: #ffffff;
    --warn: #000000;

    /* Linky vlasové a černé; mřížka grafu světlá, ať nepřekrývá čáry. */
    --line: #000000;
    --line-c: #000000;
    --panel-line: #000000;
    --grid: rgba(0, 0, 0, 0.16);

    /* Řady grafu si barvu nechávají, ale v hodnotách světlého motivu:
     * tmavší odstíny jsou laděné na bílý podklad (design.md 1). */
    --s1: #0e8f72;
    --s2: #be883e;
    --s3: #5b93b2;
    --s4: #a272ab;
    --s5: #b54a38;
    --s6: #5a7379;

    /* Nic, co se na papír nepropíše: stín, záře, rozostření, zdvih
     * a plocha s přechodem pod čarou grafu. */
    --shadow-card: none;
    --shadow-pop: none;
    --shadow-ink: 0, 0, 0;
    --panel-shadow: none;
    --chart-glow: none;
    --chart-area: 0;
    --blur: none;
    --panel-blur: none;
    --lift: 0px;

    /* Ostré rohy. Zaoblení je řeč obrazovky; na dokladu, který jde do šanonu,
     * působí rámeček s poloměrem 14 bodů jako kartička, ne jako rubrika. */
    --r-card: 0;
    --r-field: 0;
  }

  /* Podklad se dědí z `--bg`, ale stránka a obal si ho drží zvlášť, takže
   * by z nich tmavá zůstala i s přepsanými tokeny. */
  html,
  body,
  .fv-shell {
    background: #ffffff;
    color: #000000;
  }

  /* **Graf je jediná výjimka z černé, a není to ozdoba.** Zadavatel barvu
   * grafu připustil („možná ten graf barevný") a ukázalo se, že bez ní to
   * nejde: v grafu celého plánu kreslí `--acc` čáru majetku a `--acc2` čáru
   * cíle. Sražené obě do černé by z dvou čar udělaly jednu a list by tvrdil
   * něco jiného než obrazovka. Význam tokenů zůstává týž jako všude jinde
   * (design.md 1), jen v hodnotách světlého motivu, laděných na bílý podklad.
   *
   * Platí to uvnitř grafu, ne na stránce: popisky, čísla a text okolo jsou
   * dál černé, protože tam barva nic nerozlišuje. */
  .fv-chart {
    --acc: #0e8f72;
    --acc2: #8a6a16;
    --warn: #b54a38;
  }

  /* Nothing that cannot be pressed on paper. The cookie bar and the enlarge
   * button joined the list on 17. 9. 2026: both are fixed to the viewport,
   * so in the PDF of the whole plan „Odmítnout / Přijmout vše" came out at
   * the foot of every one of the seven pages.
   *
   * The footer keeps two of its three parts. The notice of §12.6 stays,
   * because a mandatory warning is not decoration, and so does the company
   * identification, which is exactly what a document carried out of the
   * building should say. The row of legal links is navigation: relative
   * hrefs, so the rule further down cannot even print an address next to
   * them, and on paper they are a line of words that lead nowhere. The
   * saying above the footer goes with them - an invoice is not the place
   * for an aphorism about money. */
  .fv-nav,
  /* Tlačítko, které menu otevírá, se schovávalo samo tím, že na širší
   * obrazovce není. Na papíře šířka obrazovky nic neznamená, takže se
   * vytisklo, a protože je v toku nad obsahem, přistálo přes značku
   * (nalezeno 17. 9. 2026 na vytištěném dokladu). */
  .fv-nav-open,
  .fv-topbar,
  .fv-viewbar,
  .fv-envbar,
  .fv-result,
  .fv-cookies,
  .fv-chart__max,
  .fv-saying,
  .fv-footer__links,
  .fv-chart__menu,
  .fv-chart__legend,
  .fv-print__hide {
    display: none !important;
  }

  /* Text for screen readers is not text for paper: the 1px box with `clip`
   * hides it in a browser, but WeasyPrint drew it, so the sheet opened with
   * „Přejít na obsah". The data table under a chart keeps its exception -
   * the rule below promotes it from a reader aid to the record. */
  .sr-only:not(.fv-chart__datatable) {
    display: none !important;
  }

  .fv-print__only {
    display: block;
  }

  .fv-shell,
  .fv-main {
    display: block;
    max-width: none;
    margin: 0;
    padding: 0;
  }

  /* A source the reader cannot click has to be a source they can type
   * (CLAUDE.md bod 11 - the address is the "clickable" part on paper). */
  .fv-print a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    word-break: break-all;
  }

  /* The chart's data table is the part worth archiving, so on paper it stops
   * being screen-reader-only and becomes the record. */
  .fv-chart__datatable {
    position: static;
    width: auto;
    height: auto;
    clip: auto;
    clip-path: none;
    overflow: visible;
    white-space: normal;
  }

  .fv-print__part,
  .fv-chart,
  table {
    break-inside: avoid;
  }

  h2,
  h3 {
    break-after: avoid;
  }
}

/* An entry whose page does not exist yet (design.md 4.1 fixes the seven, but
 * Importy výpisů is phase 6). Muted and not interactive - it says "not yet",
 * never "broken". */
.fv-nav__link.is-unavailable {
  opacity: 0.45;
  cursor: default;
}

/* --- investments: weights and the donut (5.6) ------------------------- */
/* Stroke colour by attribute, never by an inline style: the CSP of 12.4 is
 * `style-src 'self'` and a style attribute cannot be rescued by a nonce.
 * Geometry stays in the SVG attributes; this file only says what things look
 * like, never where they are. */
.fv-donut__segment[data-color="s1"] {
  stroke: var(--s1);
}
.fv-donut__segment[data-color="s2"] {
  stroke: var(--s2);
}
.fv-donut__segment[data-color="s3"] {
  stroke: var(--s3);
}
.fv-donut__segment[data-color="s4"] {
  stroke: var(--s4);
}
.fv-donut__segment[data-color="s5"] {
  stroke: var(--s5);
}
.fv-donut__segment[data-color="s6"] {
  stroke: var(--s6);
}

.fv-chart--donut .fv-chart__donut {
  width: 100%;
  max-width: 220px;
  height: auto;
}

/* The swatch is a line in a line chart and a block next to a donut - same
 * token, shape that matches what it stands for. */
.fv-chart--donut .fv-chart__swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
}

.fv-weights {
  margin-block: var(--sp-4);
}

.fv-weights__headline {
  font-weight: 600;
  margin: 0 0 var(--sp-2);
}

/* The state is carried by a left border as well as by the sentence: a card
 * that says "sedí" only in colour says nothing to a colour-blind reader. */
.fv-weights--balanced {
  border-left: 3px solid var(--s1);
}

.fv-weights--off,
.fv-weights--missing {
  border-left: 3px solid var(--acc2);
}

/* The mode a user is already in says so as a sentence, not only as a missing
 * button - a card with nothing in it reads as broken (3.1). */
.fv-mode__current {
  color: var(--tx2);
  font-weight: 600;
  margin-bottom: 0;
}

/* --- allocation over time (chart 7 of section 14) --------------------- */
/* A 100 % stacked area, drawn as two polygons. Fill in a class, geometry in
 * the points attribute - style-src 'self' again. */
.fv-band--equity {
  fill: var(--s1);
  fill-opacity: 0.75;
}

.fv-band--bonds {
  fill: var(--s2);
  fill-opacity: 0.55;
}

/* The user's own allocation, for comparison. Dashed as well as differently
 * coloured, so it survives colour blindness (design.md 1). */
.fv-band__own {
  stroke: var(--acc2);
  stroke-width: 2;
}

/* "You are here" on the trajectory. Deliberately NOT --acc: that token and
 * --s1 are the same colour in both themes, so an accent-coloured marker was
 * invisible wherever it crossed the equity band - which is most of the chart.
 * Dashed as well, so it is not confused with the comparison line. */
.fv-band__marker {
  stroke: var(--tx);
  stroke-width: 1.5;
  stroke-dasharray: 2 3;
}

/* A list of choices where each one is a card: the label, then what it means
 * in one sentence. Radios rather than a select, because the sentences are the
 * point and a select hides them. */
.fv-choices {
  border: 0;
  margin: var(--sp-5) 0;
  padding: 0;
}

.fv-choice {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  margin-bottom: var(--sp-2);
  cursor: pointer;
}

.fv-choice:focus-within {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

.fv-choice__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.fv-choice__note {
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-weights__link {
  margin-bottom: 0;
  font-size: var(--fs-13);
}

.fv-weights--glidepath {
  border-left: 3px solid var(--s1);
}

/* --- own assumptions (5.6, advanced mode) ----------------------------- */
/* The value and the benchmark it replaced, one above the other. Showing both
 * is the point: a field that displays only what is in force cannot answer
 * "is this ours or mine?". */
.fv-assume {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-1);
}

.fv-assume__input {
  max-width: 7rem;
}

.fv-assume__benchmark {
  display: block;
  color: var(--tx2);
  font-size: var(--fs-13);
  margin-top: var(--sp-1);
}

/* --- positions (5.6, advanced mode) ----------------------------------- */
/* The valuation date sits under every price. It is not a footnote: a price
 * that looks current and is eight months old is worse than no price. */
.fv-holding__age {
  display: block;
  color: var(--tx2);
  font-size: var(--fs-13);
  font-weight: 400;
  margin-top: var(--sp-1);
}

/* How old the valuation is, said in colour as well as in words. The words
 * carry it on their own - colour never has to be seen to understand the row. */
.fv-holding__age[data-freshness="starsi"] {
  color: var(--acc2);
}

.fv-holding__age[data-freshness="stare"],
.fv-holding__age[data-freshness="nedatovane"] {
  color: var(--warn);
}

.fv-holding__derived {
  display: block;
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-holding__detail {
  padding-top: 0;
}

.fv-form-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  align-items: center;
  margin-top: var(--sp-3);
}

.fv-form-row .fv-field__input {
  max-width: 11rem;
}

/* --- cash flows (5.6c) ------------------------------------------------ */
/* The rank box is one or two characters wide; a full-width field beside it
 * would suggest a sentence goes in. */
.fv-rank {
  max-width: 3.5rem;
  text-align: center;
}

/* A cheaper alternative is marked by more than colour - the number carries a
 * minus sign of its own, and the column heading says what it is a difference
 * against (design.md 1, WCAG). */
[data-cheaper="ano"] {
  color: var(--s1);
}

/* --- imports (5.10) --------------------------------------------------- */
/* A line that could not be read stays in the preview with its reason. It is
 * marked by more than colour: the row below it says in words what was not
 * understood, and repeats the raw text of the line. */
.fv-import__problem {
  color: var(--tx2);
  font-size: var(--fs-13);
  padding-top: 0;
}

.fv-import__raw {
  display: block;
  font-family: var(--font-data);
  color: var(--tx2);
  margin-top: var(--sp-1);
  word-break: break-word;
}

tr[data-problem="ano"] {
  background: color-mix(in srgb, var(--warn) 8%, transparent);
}

.fv-remember {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-13);
  color: var(--tx2);
  white-space: nowrap;
}

/* --- free-account limits (11.1) --------------------------------------- */
/* A limit is information, not an error, so it gets the calm surface of a card
 * rather than the warning colour. The `Plus` badge is the same one that sits
 * next to a locked button, so the page and the button that led to it look
 * like the same thing. */
.fv-limit {
  max-width: 44rem;
}

.fv-limit__title {
  margin: var(--sp-2) 0 var(--sp-4);
}

.fv-limit__line {
  color: var(--tx2);
  margin-bottom: var(--sp-3);
}

/* The first sentence says what the limit is; it carries the page. */
.fv-limit__line:first-of-type {
  color: var(--tx);
  font-size: var(--fs-17, 1.0625rem);
}

.fv-limit__actions {
  margin-top: var(--sp-5);
}

/* A locked feature stays visible with a badge and one line saying what it does
 * (11.1). Never hidden: the user is meant to know what exists before deciding
 * whether to pay, not discover it afterwards. */
.fv-locked {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2);
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-locked__what {
  color: var(--tx2);
}

/* Dlaždice, kterou nejde otevřít (§11.1 od 26. 8. 2026): odznak Plus u jména
 * a kurzor, který neslibuje odkaz. Co je za ní, říká věta nad trojicí. */
.fv-card.is-locked {
  cursor: default;
}

/* Odznak v nabídce grafu stojí místo tlačítek, ne vedle nich. */
.fv-chart__menu-locked {
  padding: var(--sp-2) var(--sp-3);
  max-width: 42ch;
}

.fv-chart__menu-locked .fv-locked {
  margin: 0;
}

/* Nabídka zkoušky pod odznakem (§11.2, na stránce od 25. 8. 2026). Tichá
 * a odsazená pod první větu, aby pravidlo §11.1 „odznak a jedna věta" drželo:
 * co ta věc dělá, říká pořád ten řádek nad ní. */
.fv-locked__trial {
  margin-top: calc(var(--sp-1) * -1);
  font-size: var(--fs-13);
  max-width: 62ch;
}

/* Where the account stands (11.1b). Three levels of attention, because a
 * subscription running normally and one about to lapse are not the same news
 * - and neither of them is an error, so none of the three is the warning red
 * used for a failed form. */
.fv-standing {
  border-left: 3px solid var(--line);
}

.fv-standing--notice {
  border-left-color: var(--acc2);
}

.fv-standing--warning {
  border-left-color: var(--warn);
}


/* Nadpis stránky v hlavním rozvržení. Účet a jeho podstránky se z úzkého
 * rozvržení přesunuly sem: design.md 5 ho má pro **veřejné** stránky, které
 * „nemají do čeho navigovat", a účet za přihlášením má. */
.fv-page__title {
  margin-bottom: var(--sp-4);
}


/* =========================================================== fáze 8 ===
 * Obsah: veřejné stránky, patička, lišta o cookies.
 *
 * Everything here is a class, never a style attribute: `style-src 'self'`
 * (12.4) blocks an inline style and a style *attribute* cannot be rescued by
 * a hash. Same rule the timeline learned the hard way.
 */

/* ------------------------------------------------ veřejné rozvržení --- */

.fv-public__header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  width: min(var(--w-public), 100%);
  margin: 0 auto;
  padding: var(--sp-4) var(--sp-5);
  border-bottom: var(--strip-bw) solid var(--panel-line);
}

.fv-public__brand {
  text-decoration: none;
}

.fv-public__nav {
  display: flex;
  flex-wrap: wrap;
  /* Na střed kvůli oválu přepínače vzhledu (13. 9. 2026): je vyšší než
   * řádek odkazů a bez zarovnání by odkazy seděly u jeho horní hrany. */
  align-items: center;
  gap: var(--sp-4);
  font-size: var(--fs-15);
}

.fv-public {
  width: min(var(--w-public), 100%);
  margin: 0 auto;
  padding: var(--sp-6) var(--sp-5);
}

.fv-public > * + * {
  margin-top: var(--sp-5);
}

/* Nadpis sekce drží tentýž sloupec jako text pod ním (11. 8. 2026, rozhodnutí
 * zadavatele). Do té doby šel nadpis přes celých 1080 px, kdežto odstavec
 * skončil na 611 — a nedopsaný pravý okraj se četl jako chyba rozvržení, ne
 * jako čtecí sloupec. Nadpisy jsou krátké, takže je strop nezalomí; jen
 * srovná levý blok do jedné šířky.
 *
 * Mřížky karet strop **nedostávají**: karta je vlastní sloupec a §5.2 je
 * staví vedle sebe přes celou šířku. */
.fv-public h2,
.fv-public h3 {
  max-width: var(--w-prose);
}

/* ------------------------------------------------------------ patička --- */

/* 12.6: A1 on every page. Quiet, but never hidden - a warning in a colour
 * nobody reads is the same as no warning. */
.fv-footer {
  border-top: 1px solid var(--line);
  margin-top: var(--sp-8);
  padding: var(--sp-5);
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-footer > * + * {
  margin-top: var(--sp-3);
}

.fv-footer__notice {
  max-width: 80ch;
}

.fv-footer__links ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  list-style: none;
  padding: 0;
  margin: 0;
}

.fv-footer__company {
  font-size: var(--fs-12);
}

.fv-footer__placeholder {
  display: block;
  color: var(--warn);
}

.fv-narrow__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2) var(--sp-3);
  width: min(420px, 100%);
  margin-top: var(--sp-2);
  font-size: var(--fs-12);
}

/* ---------------------------------------------------- lišta o cookies --- */

/* 12.5: refusal is an equal choice. It is the same button class, the same
 * size and it comes first - in the markup, so also first in the tab order.
 * Not a modal and no focus trap: the page stays readable underneath. */
.fv-cookies {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 30;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3) var(--sp-5);
  padding: var(--sp-4) var(--sp-5);
  background: var(--surf);
  border-top: 1px solid var(--line);
}

/* Odstavec, ne nadpis (docs/seo.md, A8): podobu nadpisu si nese sám, aby
 * lišta vypadala stejně a přitom nevstupovala do osnovy stránky. */
.fv-cookies__title {
  font-family: var(--font-display);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
  line-height: var(--lh-heading);
  font-size: var(--fs-15);
  margin: 0;
}

.fv-cookies__text {
  flex: 1 1 32ch;
  margin: 0;
  color: var(--tx2);
  font-size: var(--fs-13);
  max-width: 80ch;
}

.fv-cookies__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin: 0;
}

/* --------------------------------------------------- slovník a otázky --- */

.fv-search {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-3);
}

.fv-search .fv-field__label {
  flex: 0 0 100%;
}

.fv-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

.fv-chip {
  border: 1px solid var(--line);
  border-radius: var(--r-chip);
  padding: var(--sp-1) var(--sp-3);
  font-size: var(--fs-13);
  text-decoration: none;
}

.fv-chip:hover,
.fv-chip:focus-visible {
  border-color: var(--acc);
}

.fv-glossary {
  margin: 0;
}

.fv-glossary dt {
  margin-top: var(--sp-3);
  font-weight: 600;
}

.fv-glossary dd {
  margin: 0;
  color: var(--tx2);
}

.fv-list {
  padding-left: var(--sp-5);
}

.fv-list > li + li {
  margin-top: var(--sp-2);
}

.fv-breadcrumb {
  font-size: var(--fs-13);
}

.fv-tagline {
  color: var(--tx2);
  font-size: var(--fs-15);
}

.fv-example {
  border-left: 3px solid var(--acc2);
  padding-left: var(--sp-4);
}

.fv-meta {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--sp-2) var(--sp-4);
  margin: var(--sp-3) 0 0;
}

.fv-meta dt {
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-meta dd {
  margin: 0;
}

.fv-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--sp-4);
}

/* ------------------------------------------------- právní dokumenty --- */

.fv-doc-version {
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-document > * + * {
  margin-top: var(--sp-4);
}

.fv-document h3 {
  margin-top: var(--sp-6);
  font-size: var(--fs-19);
}

/* Průvodce a stránka Jak píšeme (zadání §22 fáze D): text je celý článek,
 * takže jeho oddíly jsou nadpisy druhé úrovně. Odstup jako u oddílu stránky. */
.fv-document h2 {
  margin-top: var(--sp-7);
}

.fv-document ul,
.fv-document ol {
  padding-left: var(--sp-5);
}

.fv-document li + li {
  margin-top: var(--sp-2);
}

.fv-doc-others {
  margin-top: var(--sp-7);
}


/* 12.6: souhlas při registraci je samostatné pole, ne věta pod tlačítkem.
 * Big enough to hit on a phone, and the label is clickable - a 13 px square
 * next to three lines of text is a checkbox that gets ticked by accident. */
.fv-consent {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-2) var(--sp-3);
  margin: var(--sp-5) 0;
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surf2);
}

.fv-consent__box {
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.15rem;
}

.fv-consent__label {
  font-size: var(--fs-15);
}

.fv-consent__links {
  grid-column: 2;
  margin: 0;
  font-size: var(--fs-13);
}

/* 12.6: A2 nad každým grafem budoucnosti. Above the plot, not folded into the
 * caption underneath it - the notice is about what the picture is, and it has
 * to arrive before the picture does. */
.fv-chart__forecast {
  margin: 0 0 var(--sp-3);
  color: var(--tx2);
  font-size: var(--fs-13);
  max-width: 80ch;
}


/* §6.6 — plán, kterému došel finanční majetek. Vypadá jinak než popisek nad
 * ním schválně: `fv-chart__forecast` je poznámka o metodě („tohle je
 * projekce"), tahle věta je nález o plánu, a splynout s metodickou poznámkou
 * je přesně to, co §6.6 vytýká dosavadnímu stavu — schodek byl v číslech
 * a nikdo ho nepojmenoval. Proužek vlevo, ne barevné pozadí přes celou šířku:
 * upozornění, které křičí, se přeskakuje. */
.fv-chart__debt {
  margin: var(--sp-3) 0 0;
  padding: var(--sp-2) 0 var(--sp-2) var(--sp-3);
  border-left: 3px solid var(--warn, var(--tx2));
  color: var(--tx1);
  font-size: var(--fs-13);
  max-width: 80ch;
}


/* Cíl „chci zanechat" pod grafem (zadavatel 22. 8. 2026). Týž tvar jako
 * nález o dluhu nad ním, v barvě čáry cíle: je to věta o plánu, ne o metodě
 * — a u nuly je to jediné místo, které čtenáři řekne, že cíl nemá. */
.fv-chart__goal {
  margin: var(--sp-3) 0 0;
  padding: var(--sp-2) 0 var(--sp-2) var(--sp-3);
  border-left: 3px solid var(--acc2);
  color: var(--tx1);
  font-size: var(--fs-13);
  max-width: 80ch;
}

/* Nabídka experimentů v kartě Kolik po mně zůstane: tlačítka v řadě. */
.fv-analysis__experiments {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  list-style: none;
  margin: var(--sp-3) 0 0;
  padding: 0;
}

/* Karta cíle v Pozůstalosti: jedno pole, jedna věta, jedno tlačítko.
 * Stojí nad čísly části, protože cíl je to, co část ostatním stránkám dává. */
.fv-goal__form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-3);
  margin-top: var(--sp-3);
}

.fv-goal__form .fv-field {
  flex: 1 1 14rem;
  max-width: 20rem;
  margin: 0;
}

.fv-goal__state {
  margin: var(--sp-2) 0 0;
}

/* Víceřádkové pole v editoru obsahu (§10). The one place in the product where
 * somebody types a paragraph rather than a number. */
.fv-field__input--area {
  min-height: 12rem;
  font-family: var(--font-body);
  line-height: var(--lh-body);
  resize: vertical;
}


/* -------------------------------------------- §10 - texty stránek (§5.2) --- */
/* A whole public page edited in one form. Grows with its content rather than
 * to a fixed height: sixty-eight fields at 12rem each is a page nobody
 * scrolls to the bottom of, and a heading is one line. */
.fv-field__input--text {
  font-family: var(--font-body);
  line-height: var(--lh-body);
  resize: vertical;
}

/* Sections of the page being edited, separated so the form reads like the
 * page it edits rather than like a list of fields. */
.fv-textgroup {
  margin-bottom: var(--sp-6);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--line);
}

.fv-textgroup:last-of-type {
  border-bottom: 0;
}

.fv-textrow {
  margin-bottom: var(--sp-4);
}

/* A refused text keeps its place in the page and says why, rather than the
 * whole form failing with one message at the top. The border is never the
 * only signal - the sentence underneath carries it (WCAG, §16). */
.fv-textrow--refused .fv-field__input {
  border-color: var(--warn);
}

.fv-field__refused {
  display: block;
  margin-top: var(--sp-1);
  color: var(--warn);
  font-size: var(--fs-13);
}

/* What a page is, beside its name in the list. */
.fv-page__note {
  display: block;
  color: var(--tx2);
  font-size: var(--fs-13);
}

/* 23.1: řádek příjemce v hromadném formuláři pozůstalosti. Na úzké obrazovce
   pole pod sebe, na široké vedle sebe - jméno má nejvíc místa, podíl je vždy
   nanejvýš tři znaky. */
.fv-recipient {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--fv-space-2);
  margin-bottom: var(--fv-space-2);
}
.fv-recipient > .fv-field__input:first-of-type { flex: 1 1 14rem; }
.fv-recipient > [data-podil] { flex: 0 0 5rem; }

/* Volba křivek a značek v grafu Vývoj v čase (§5.4, 16. 8. 2026). Odkazy,
 * ne zaškrtávátka: s výběrem se přepočítá měřítko na serveru, takže je to
 * navigace, ne nastavení formuláře. */
.fv-chart__curves,
.fv-chart__marks {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-3);
}

.fv-chart__curves .fv-badge {
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

.fv-chart__marks fieldset {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  border: 0;
  padding: 0;
  margin: 0;
}


/* Rozcestník smí být širší než míra pro čtení (17. 8. 2026).
 *
 * `--w-content` je 1180 px a je to **míra pro čtení** — řádek přes celou
 * širokou obrazovku se čte špatně. Na Přehledu ale žádný dlouhý řádek není:
 * jsou to dlaždice a grafy ve dvou sloupcích, a s tím stropem zůstávalo na
 * 1920 px pět set bodů prázdných, zatímco graf měl na čtyřicet let jedenáct
 * bodů na rok. Zvednout `--w-content` globálně by rozšířilo i stránky s texty,
 * kde ta míra dává smysl; tohle je proto výjimka pro jednu stránku, ne změna
 * pravidla.
 *
 * Odstavce uvnitř si měřítko drží samy třídou `u-measure`, takže se text
 * nerozjede ani tady. */
.fv-main--wide {
  max-width: var(--w-wide);
}

/* Bublina s hodnotami u kurzoru (zadavatel 17. 8. 2026: „při najetí myši
 * budeme ukazovat hodnoty tooltipem, ale i pod tím“). Panel pod grafem
 * zůstává — bublina zmizí s myší, panel ne, a odečítač bublinu nevidí.
 *
 * `pointer-events: none` je tu nutnost, ne kosmetika: bublina leží nad
 * plochou grafu, a kdyby brala myš, přebrala by si `mousemove` sama sobě
 * a vybraný rok by pod kurzorem poskakoval. */
.fv-chart__tip {
  position: absolute;
  z-index: 2;
  pointer-events: none;
  max-width: 16rem;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  background: var(--surf2);
  color: var(--tx);
  font-size: var(--fs-13);
  line-height: var(--lh-body);
}

.fv-chart__tip strong {
  display: block;
  margin-bottom: var(--sp-1);
  font-family: var(--font-data);
}

.fv-chart__tip div {
  display: flex;
  gap: var(--sp-2);
  justify-content: space-between;
}

.fv-chart__tip dt {
  color: var(--tx2);
}

.fv-chart__tip dd {
  margin: 0;
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
}

/* Karta je kotva pro absolutní polohu bubliny. */
.fv-chart {
  position: relative;
}

/* Pruh „Co udělat teď“ (zadavatel 18. 8. 2026).
 *
 * Byla to karta přes půl sloupce; teď je to řádek, který se rozbalí. Důvod
 * není jen místo: odkliknutý úkol se po přepnutí pohledu vracel a karta
 * skočila čtenáři do cesty. Řádek, který si drží sbalení, nemá čemu vyskočit.
 *
 * Sbalený zabírá jednu výšku řádku, takže se vejde mezi nadpis a dlaždice,
 * aniž by posunul jejich zarovnání s kartou grafu. */
.fv-todo--strip {
  margin: 0 0 var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surf);
}

/* Sbalený pruh je stejně vysoký jako řádek záložek Přehledu (`--fv-control-row`,
 * 21. 8. 2026): oba stojí v téže řadě mřížky a při rozbaleném pruhu měří řadu
 * už jen záložky — kdyby byl pruh vyšší, graf by při rozbalení poskočil. */
.fv-todo__summary-bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  box-sizing: border-box;
  /* Bez dvou bodů rámečku `details`, aby celý sbalený pruh měřil přesně
   * tolik, co řádek záložek. */
  min-height: calc(var(--fv-control-row) - 2px);
  padding: var(--sp-2) var(--sp-4);
  cursor: pointer;
  list-style: none;
}

/* Vlastní ukazatel místo trojúhelníčku prohlížeče: ten je v každém jiný
 * a v tmavém tématu leckde skoro neviditelný. */
.fv-todo__summary-bar::-webkit-details-marker {
  display: none;
}

.fv-todo__summary-bar::after {
  content: "▾";
  color: var(--tx2);
  transition: transform var(--transition);
}

.fv-todo--strip[open] .fv-todo__summary-bar::after {
  transform: rotate(180deg);
}

.fv-todo--strip .fv-todo__title {
  margin: 0;
  font-size: var(--fs-15);
}

.fv-todo__count {
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-todo__body {
  padding: 0 var(--sp-4) var(--sp-4);
}

.fv-todo__collapse {
  margin-top: var(--sp-3);
}

/* Focus musí být vidět i na shrnutí — je to ovládací prvek. */
.fv-todo__summary-bar:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

/* Tělo přijaté zprávy v administraci (20. 8. 2026). <pre>, aby zůstaly
 * odstavce, jak přišly — ale se zalamováním, jinak dlouhý řádek e-mailu
 * roztáhne tabulku přes celou obrazovku. */
.fv-mail-body {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-family: inherit;
  font-size: var(--fs-13);
  margin: var(--sp-3) 0 0;
}

/* Formulář vedle odkazu v buňce tabulky (Přečteno u přijaté zprávy).
 * Inline style by zablokovalo CSP — proto třída. */
.fv-inline-form {
  display: inline;
}

/* Pruh oznámení provozovatele (F2, 20. 8. 2026). Decentní jako fv-envbar,
 * ale vlastní: envbar říká „tohle není skutečné", tenhle říká „stalo se".
 * Odstávka dostane výraznější okraj — je to jediné oznámení, které čtenáři
 * bere něco, s čím počítal. */
.fv-announce {
  padding: var(--sp-2) var(--sp-4);
  background: var(--surf);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-13);
}

.fv-announce[data-kind="odstavka"] {
  border-left: 3px solid var(--acc);
}

.fv-announce a {
  margin-left: var(--sp-2);
}

/* Návrat do rozdělaného dotazníku (zadavatel 21. 8. 2026): stálý pruh na
 * každé stránce aplikace, dokud dotazník není dokončený. Tvarem sedí
 * k oznámením provozovatele; akcentní hrana říká, že tohle je krok
 * čtenáře, ne zpráva provozu. */
.fv-resume {
  padding: var(--sp-2) var(--sp-4);
  background: var(--surf);
  border-bottom: 1px solid var(--line);
  border-left: 3px solid var(--acc2);
  font-size: var(--fs-13);
}

.fv-resume__link {
  margin-left: var(--sp-2);
  font-weight: 600;
}

/* Nadpis skupiny polí ve formuláři části (26. 8. 2026): menší než nadpis
 * bloku, s linkou, aby oddělil skupiny otázek tam, kde jich je hodně. */
.fv-form-group {
  margin: var(--sp-5) 0 var(--sp-2);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
  font-size: var(--fs-13);
  font-weight: 600;
  color: var(--tx2);
  text-transform: none;
}

/* Podrobná nastavení — druhé patro formuláře položky (zadavatel 30. 8.
 * 2026, varianta 2 návrhu „Rozhodněte za mě"): základ nahoře, předpoklady
 * a volby složené pod linkou. Sbalení pole neodstraňuje z odeslání.
 * Spodní okraj drží sbalený řádek dál od tlačítka Uložit/Přidat — dva
 * klikací prvky nalepené na sebe (nález zadavatele 31. 8. 2026). */
.fv-form-details {
  margin-top: var(--sp-5);
  margin-bottom: var(--sp-5);
  border-top: 1px solid var(--line);
  padding-top: var(--sp-3);
}

.fv-form-details > summary {
  cursor: pointer;
  list-style: none;
  font-size: var(--fs-13);
  font-weight: 600;
  color: var(--tx2);
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  flex-wrap: wrap;
}

.fv-form-details > summary::-webkit-details-marker {
  display: none;
}

.fv-form-details__caret {
  transition: transform var(--transition);
}

.fv-form-details[open] > .fv-form-details__caret,
.fv-form-details[open] > summary > .fv-form-details__caret {
  transform: rotate(180deg);
}

/* Počítadlo „z Předpokladů se doplní: N" — zlatá je „číslo, které jsme
 * spočítali my" (§1 designu), a přesně to tohle je. */
.fv-form-details__count {
  font-weight: 400;
  color: var(--acc2);
}

/* Formulář volby k Podrobným nastavením nese od 9. 9. 2026 jen skrytá pole
 * (token a návrat); jeho tlačítko stojí v hlavičce dlaždice formuláře
 * a je s ním svázané atributem `form`. Na stránce nemá co ukazovat. */
.fv-details-pref {
  display: none;
}

/* Hlavička dlaždice formuláře položky s volbou k Podrobným nastavením
 * vpravo (zadavatel 9. 9. 2026: „dát doprava, do té dlaždice nad tím,
 * zmenšit a přidat tooltip"). Řádek je flex, aby volba stála u pravého
 * okraje a na úzké obrazovce se zalomila pod jméno. Klik na tlačítko ani na
 * otazník dlaždici nesbalí: aktivace patří jim, ne `summary`.
 *
 * **Flex je na `summary`, ne na obalu uvnitř** (nález zadavatele 16. 9. 2026:
 * „odskočil řádek na tlačítku“). Do té doby zůstával `summary` jako
 * `list-item` kvůli značce rozbalení a flex nesl `span` uvnitř: blokový flex
 * uvnitř položky seznamu ale nesmí na řádek se značkou, takže značka zabrala
 * první řádek sama a text spadl pod ni (`summary` 51,8 px místo 25,9 px,
 * změřeno v prohlížeči). Flex na `summary` značku zruší, a tak si ji stránka
 * kreslí sama jako u pruhu úkolů a u položek Přehledu.
 *
 * `justify-content` zůstává na začátku řádku: doprava odsouvá volbu až
 * `margin-left: auto` na `.fv-disclosure__aside`. Se `space-between` by se
 * v části bez podrobných nastavení, kde je v řádku jen šipka a jméno,
 * odsunulo jméno k pravému okraji. */
summary.fv-disclosure__row {
  display: flex;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  flex-wrap: wrap;
  list-style: none;
}

summary.fv-disclosure__row::-webkit-details-marker {
  display: none;
}

summary.fv-disclosure__row::before {
  content: "▸";
  flex: none;
  color: var(--tx2);
}

.fv-disclosure[open] > summary.fv-disclosure__row::before {
  content: "▾";
}

.fv-disclosure__aside {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  margin-left: auto;
  font-weight: 400;
}

/* Malé tlačítko (zadavatel 9. 9. 2026: „zmenšit"): táž podoba jako malá
 * tlačítka horního pruhu (design §4.1b), písmo 12 px, rám v barvě linky,
 * po najetí myší zelený rám, text i podklad. */
.fv-button--mini {
  font-size: var(--fs-12);
  font-weight: 500;
  line-height: 1.2;
  padding: 3px var(--sp-2);
  min-height: 0;
  color: var(--tx2);
  background: none;
  border-color: var(--line);
  white-space: nowrap;
}

.fv-button--mini:hover {
  color: var(--acc);
  border-color: var(--acc);
  background: var(--surf2);
}

/* Výběr souboru (26. 8. 2026): vlastní tlačítko, protože nápis nativního
 * jde za jazykem prohlížeče, ne stránky. Vstup je skrytý zrakově, ne z DOM:
 * fokus na něm zůstává a rámeček se kreslí na tlačítko vedle. Jméno
 * vybraného souboru vypisuje `app.js` do řádku vedle tlačítka. */
.fv-file {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

.fv-file__input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.fv-file__input:focus-visible + .fv-file__button {
  outline: 2px solid var(--acc2);
  outline-offset: 2px;
}

.fv-file__button {
  cursor: pointer;
}

.fv-file__name {
  font-size: var(--fs-13);
  color: var(--tx2);
  overflow-wrap: anywhere;
}

/* Rozcestník Státního důchodu (zadavatel 21. 8. 2026): tři cesty pod sebou,
 * ta platná má akcentní hranu. Formuláře uvnitř jsou řádkové, aby tlačítko
 * stálo u věty, ke které patří. */
.fv-cesty {
  margin-bottom: var(--sp-4);
}

.fv-cesty__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.fv-cesty__item {
  padding: var(--sp-3) var(--sp-4);
  border-left: 3px solid var(--line);
  margin-bottom: var(--sp-3);
}

.fv-cesty__item.is-on {
  border-left-color: var(--acc2);
  background: color-mix(in srgb, var(--acc2) 8%, transparent);
}

.fv-cesty__title {
  margin: 0 0 var(--sp-1);
  font-weight: 600;
}

.fv-cesty__form {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: var(--sp-2) 0 0;
}

/* Vstupy cest mají jednu šířku (zadavatel 9. 9. 2026): částka byla užší než
 * základ, protože pole bralo šířku podle obsahu. */
.fv-cesty__form .fv-field__input {
  flex: 0 1 220px;
  min-width: 0;
}

/* Formulář osob užší než stránka (zadavatel 9. 9. 2026: „pole pro zadání jsou
 * zbytečně široké přes celou obrazovku"): táž šířka jako formulář položky. */
.fv-osoby-form {
  max-width: 520px;
}

/* Neuložené změny (zadavatel 22. 8. 2026): dialog v top-layer nad vším,
 * tři volby vedle sebe. Nativní `<dialog>`, takže fokus i Esc řeší
 * prohlížeč; `::backdrop` ztmaví stránku stejně jako zvětšený graf. */
dialog.fv-unsaved {
  width: min(26rem, calc(100vw - 2rem));
  padding: var(--sp-5);
  background: var(--surf);
  color: var(--tx);
  border: 1px solid var(--line);
  border-left: 3px solid var(--acc2);
  border-radius: var(--r-card);
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.35);
}

dialog.fv-unsaved::backdrop {
  background: rgba(10, 15, 24, 0.55);
}

/* Potvrzení smazání je týž dialog, jen s hranou v barvě toho, co se stane. */
dialog.fv-confirm {
  border-left-color: var(--warn);
}

.fv-unsaved__text {
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-15);
}

.fv-unsaved__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

/* Varování před odhlášením pro nečinnost (zadavatel 21. 8. 2026): karta
 * v rohu obrazovky, ne překryv — člověk má číst dál, jen ví, že má dvě
 * minuty. Nad vším ostatním kromě dialogů v top-layer. */
.fv-idle {
  position: fixed;
  right: var(--sp-4);
  bottom: var(--sp-4);
  z-index: 65;
  width: min(24rem, calc(100vw - 2rem));
  padding: var(--sp-4);
  background: var(--surf);
  color: var(--tx);
  border: 1px solid var(--line);
  border-left: 3px solid var(--acc2);
  border-radius: var(--r-card);
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.35);
}

.fv-idle__text {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-15);
}

/* Průvodce aplikací (zadavatel 21. 8. 2026): ztmavení dělá stín vysvíceného
 * rámu, takže výřez je jediný prvek a nic se neskládá z panelů; u závěru
 * bez cíle ztmavuje překryv sám (is-veil). Karta je dialog vedle
 * vysvíceného prvku, na telefonu list u spodní hrany. Pohyb rámu a karty
 * jen mimo prefers-reduced-motion. */
.fv-guide {
  position: fixed;
  inset: 0;
  z-index: 60;
}

.fv-guide.is-veil {
  background: rgba(10, 15, 24, 0.55);
}

.fv-guide__spot {
  position: fixed;
  border: 2px solid var(--acc2);
  border-radius: var(--r-card);
  box-shadow: 0 0 0 200vmax rgba(10, 15, 24, 0.55);
  pointer-events: none;
}

.fv-guide__card {
  position: fixed;
  width: min(24rem, calc(100vw - 2rem));
  padding: var(--sp-4);
  background: var(--surf);
  color: var(--tx);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.35);
}

.fv-guide__card.is-centered {
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.fv-guide__card.is-sheet {
  left: var(--sp-3);
  right: var(--sp-3);
  bottom: var(--sp-3);
  top: auto;
  width: auto;
  transform: none;
}

.fv-guide__count {
  margin: 0;
  font-size: var(--fs-13);
  color: var(--tx2);
}

.fv-guide__heading {
  margin: var(--sp-1) 0 var(--sp-2);
  font-size: var(--fs-19);
}

.fv-guide__text {
  margin: 0;
  font-size: var(--fs-15);
}

.fv-guide__actions {
  display: flex;
  gap: var(--sp-2);
  margin: var(--sp-3) 0 0;
}

@media (prefers-reduced-motion: no-preference) {
  .fv-guide__spot,
  .fv-guide__card {
    transition: top 0.25s ease, left 0.25s ease, width 0.25s ease,
      height 0.25s ease;
  }
}

/* Jedna zpráva na stránce Co je nového. */
.fv-news {
  margin-bottom: var(--sp-4);
  padding: var(--sp-4);
}

.fv-news__body {
  white-space: pre-wrap;
}

/* ------------------------------ revize 2. 9. 2026 (U3): telefon ----------- */
/* The strip's controls fold behind one button below 640 px; the four numbers
 * stay. On a desktop the wrapper is `display: contents`, so the controls are
 * flex items of the flow row exactly as before, and the summary is not there.
 * `details` keeps working without a script: it is marked `open` in the
 * markup, and only app.js closes it on a narrow screen. */
/* `display: contents` na `details` prohlížeč neprovede (CSS Display 3,
 * příloha B: details zůstává blokem), a tak od rána 2. 9. 2026 stálo na
 * počítači každé ovládání pruhu na vlastním řádku přes celou šířku (nález
 * zadavatele téhož večera: „pole rychlé změny se neúměrně roztáhlo“). Ani
 * `display: flex` na `details` nestačí: Chrome obsah `details` obaluje
 * vlastním blokem `::details-content`. Obal je proto blok přes celou řadu
 * a řadou s vlastnostmi `.fv-topbar__flow` je až jeho tělo, obyčejný `div`;
 * `display: contents` tu není nikde. */
/* `flex: 1 1 0`, ne `1 1 100%` (zadavatel 2. 9. 2026 v noci, z tabletu:
 * „lišta vykreslí název části úplně nahoru"): s celou šířkou řady zůstal
 * název stránky, který se do pruhu vysouvá po posunu, sám na vlastní řadě.
 * Takhle stojí vlevo a ovládání dostane zbytek řady. */
.fv-topbar__controls {
  display: block;
  flex: 1 1 0;
  min-width: 0;
}

.fv-topbar__controls-body {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  flex-wrap: wrap;
}

.fv-topbar__controls > summary {
  display: none;
}

/* **I na tabletu za jedním tlačítkem** (zadavatel 2. 9. 2026 v noci: „horní
 * lišta zabírá spoustu místa", snímek z tabletu): dvě řady ovládání nad
 * čísly se skládají všude, kde se do jedné řady nevejdou, tedy zhruba do
 * 1024 px. Pod 640 px to platilo od rána (U3); hranici hlídá i `app.js`,
 * který obal na úzké obrazovce jednou zavře. */
@media (max-width: 1024px) {
  .fv-topbar__controls {
    display: block;
  }

  .fv-topbar__controls > summary {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    list-style: none;
    cursor: pointer;
  }

  .fv-topbar__controls > summary::-webkit-details-marker {
    display: none;
  }

  .fv-topbar__controls > summary::after {
    content: "\25BE";
  }

  .fv-topbar__controls[open] > summary::after {
    content: "\25B4";
  }

  .fv-topbar__controls-body {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    margin-top: var(--sp-3);
  }
}

@media (max-width: 640px) {
  /* Charts: the SVG scales with the screen, so 11-unit labels came out at
   * some 6 px on a 360 px phone. Bigger units, and every other year on the
   * X axis so the bigger labels do not collide. Presentation attributes lose
   * to any stylesheet rule, which is what lets this override `font-size="11"`. */
  .fv-chart svg text {
    font-size: 15px;
  }

  .fv-chart .fv-chart__x:nth-child(even) {
    display: none;
  }
}

/* ------------------------- vysvětlovací vrstva: roletka roku pod grafem --- */
/* One line under the caption: label, the years, one quiet button. */
.fv-chart__year-ask {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: var(--sp-2) 0 0;
  font-size: var(--fs-13);
  color: var(--tx2);
}

.fv-chart__year-ask select {
  font-size: var(--fs-13);
  padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  min-height: 2rem;
}

/* Poznámka verze zdarma za roletkou roků (§11.1, 9. 9. 2026): odkaz na
 * srovnání verzí místo vypnuté volby v roletce, na stránce nesmí být nic
 * `disabled` (R1). */
.fv-chart__year-note {
  font-size: var(--fs-12);
}

/* Záložky Vývoj v čase a Z čeho se skládá na Mém plánu (5. 9. 2026): týž
 * pás záložek jako na Přehledu, jen s odstupem od odstavce nad sebou. */
.fv-plan-views {
  margin-top: var(--sp-4);
}

/* Roletka roku v nadpisu stránky roku (zadavatel 5. 9. 2026): hned za slovy
 * „Co vychází v roce“, ne u pravého okraje, a písmem nadpisu. */
.fv-heading-row--rok {
  justify-content: flex-start;
  align-items: center;
  margin-bottom: var(--sp-3);
}

.fv-heading-row--rok h1 {
  margin: 0;
}

.fv-heading-row--rok .fv-chart__year-ask {
  margin: 0;
}

.fv-heading-row--rok .fv-chart__year-ask select {
  font-size: var(--fs-19);
  font-weight: 600;
  min-height: 2.5rem;
}

/* ------------------------------ Co plán říká: tlačítka k vysvětlení ------- */
.fv-ask {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: var(--sp-4) 0 var(--sp-2);
}

/* --- druhý faktor: šest políček (zadavatel 2. 9. 2026) ------------------- */
/* Bez skriptu zůstává jedno pole; skript ho schová a číslice sbírá tady.
 * Políčka jsou velká a s mezerou po třetí číslici, jak se kód čte
 * z telefonu. Obal `.fv-field__control` tu není, kroužek zaostření si kreslí
 * každé políčko samo (klávesnice a viditelný fokus jsou součást hotové
 * práce). */
.fv-otp {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: var(--sp-1) 0 var(--sp-2);
}

.fv-otp[hidden] {
  display: none;
}

.fv-otp__digit {
  width: 2.75rem;
  height: 3.25rem;
  padding: 0;
  text-align: center;
  font: inherit;
  font-size: var(--fs-24);
  font-variant-numeric: tabular-nums;
  background: var(--field);
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  color: var(--tx);
}

.fv-otp__digit:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 0;
}

.fv-otp__gap {
  width: var(--sp-2);
}

.fv-otp__backup {
  margin-top: var(--sp-2);
}

/* Tlačítko, které kód přečte ze schránky (11. 9. 2026); kreslí ho skript
 * před tlačítkem záložního kódu, na telefonu se zalomí pod něj. */
.fv-otp__paste {
  margin: var(--sp-2) var(--sp-2) 0 0;
}

@media (max-width: 360px) {
  .fv-otp__digit {
    width: 2.25rem;
    height: 2.75rem;
    font-size: var(--fs-19);
  }
}

/* --- Zeptat se plánu: připravené odpovědi (zadavatel 2. 9. 2026 večer) --- */
/* Otázka je `summary`, odpověď pod ní; první je rozbalená, ostatní sbalené,
 * aby pět odpovědí nenatáhlo stránku. Odkazy jsou v jedné řádce. */
.fv-answer {
  margin: 0 0 var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: var(--bw) solid var(--line-c);
  border-radius: var(--r-card);
  background: var(--surf-c);
  box-shadow: var(--shadow-card);
}

.fv-answer__question {
  cursor: pointer;
  font-weight: 600;
}

.fv-answer > p {
  margin: var(--sp-2) 0 0;
}

.fv-answer__where {
  font-size: var(--fs-13);
}

/* --- ikony přepínačů v hlavičce: oko a vysvětlivky (2. 9. 2026 v noci) ---- */
/* Ikona ze sady místo textového znaku; velikost drží krok s písmem tlačítka
 * a čára se kreslí barvou textu, takže se stavy hover a stisknuto propíšou. */
.fv-nav__icon-button .fv-nav__icon-svg {
  display: block;
  width: 1.2em;
  height: 1.2em;
}

/* --- Rok po měsících (15. 9. 2026): tabulka dvanácti měsíců --------------- */
/* Třináct sloupců se na telefonu neskládá pod sebe (dvanáct řádků na položku
 * by byl svitek); tabulka zůstává tabulkou a obal ji posouvá do strany. */
.fv-table--mesice {
  font-size: var(--fs-13);
  white-space: nowrap;
}

.fv-table--mesice th,
.fv-table--mesice td {
  padding: var(--sp-1) var(--sp-2);
}

.fv-table--mesice th[scope="row"] {
  white-space: normal;
  min-width: 12rem;
}

.fv-table--mesice .fv-badge {
  font-size: var(--fs-12);
  vertical-align: middle;
}

@media (max-width: 640px) {
  .fv-table--mesice thead {
    display: table-header-group;
  }
  .fv-table--mesice tr {
    display: table-row;
    border: 0;
    margin: 0;
    padding: 0;
  }
  .fv-table--mesice td {
    display: table-cell;
    border-bottom: 1px solid var(--line);
  }
  .fv-table--mesice td::before {
    content: none;
  }
}

/* ===== Grafické styly (zadavatel 15. 9. 2026) ==============================
 * Návrh `navrhy/NAVRH-GRAFICKE-STYLY.md`: hodnoty tokenů jsou v tokens.css,
 * tady je jen to, co token sám neudělá: roletka, mřížka a čáry grafu,
 * pozadí a rozostření Skleněného a pohyb Živého. */

/* Roletka stylu: pevná malá šířka, ne podle nejdelší volby; v zasunutém
 * menu se schová, ovál vzhledu tam stojí svisle a roletka by se nevešla. */
.fv-style {
  display: inline-flex;
  align-items: center;
  margin: 0;
}

/* V levém menu na vlastním řádku pod oválem (zadavatel 15. 9. 2026 večer:
 * do řady nástrojů se nevešla ani bez tlačítka Admin). */
.fv-nav__head .fv-style {
  margin-top: calc(-1 * var(--sp-1));
}

.fv-style__select {
  width: 6.75rem;
  max-width: 6.75rem;
  height: 26px;
  padding: 0 var(--sp-2);
  font: inherit;
  font-size: var(--fs-12);
  color: var(--tx2);
  background-color: var(--surf2);
  border: 1px solid var(--line);
  border-radius: var(--r-chip);
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
  cursor: pointer;
}

.fv-style__select:hover {
  color: var(--tx);
}

.fv-style__select:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 1px;
}

[data-menu="collapsed"] .fv-style {
  display: none;
}

/* Odkaz na stránku vlastního stylu vedle roletky (16. 9. 2026): vidět jen
 * s vlastním stylem, bez skriptu, atribut nese <html>. */
.fv-style__edit {
  display: none;
  margin-left: var(--sp-2);
  font-size: var(--fs-12);
  color: var(--tx2);
  white-space: nowrap;
}

[data-style="vlastni"] .fv-style__edit {
  display: inline;
}

.fv-style__edit:hover {
  color: var(--tx);
}

/* Mřížka a čáry grafu: atributy SVG prohrávají s každým pravidlem CSS,
 * takže tloušťka jde násobkem hodnoty ze šablony (aktivní 2,5, ostatní 1,8). */
.fv-chart__plot line[stroke="var(--grid)"] {
  opacity: var(--grid-o);
  stroke-dasharray: var(--chart-grid);
}

.fv-chart__plot polyline[data-series][stroke-width="2.5"] {
  stroke-width: calc(2.5 * var(--chart-scale));
}

.fv-chart__plot polyline[data-series][stroke-width="1.8"] {
  stroke-width: calc(1.8 * var(--chart-scale));
}

.fv-chart__plot polyline[data-series] {
  filter: var(--chart-glow);
}

.fv-chart__plot text {
  font-style: var(--chart-italic);
}

/* Skleněný: barevné skvrny pod poloprůhlednými kartami, aby sklo mělo co
 * rozostřovat; z palety, ne nová barva. Rozostření jen nad 900 px, na
 * slabším telefonu by při posunu cukalo (návrh, oddíl 4). */
:is([data-style="skleneny"], [data-style="vlastni"][data-custom~="sklo"]) body {
  background-image:
    radial-gradient(60% 40% at 15% 10%, color-mix(in srgb, var(--acc) 28%, transparent), transparent 70%),
    radial-gradient(50% 35% at 85% 30%, color-mix(in srgb, var(--acc2) 22%, transparent), transparent 70%),
    radial-gradient(45% 30% at 50% 90%, color-mix(in srgb, var(--warn) 16%, transparent), transparent 70%);
  background-attachment: fixed;
}

:is([data-style="skleneny"], [data-style="vlastni"][data-custom~="sklo"]) :is(.fv-card, .fv-chart, .fv-disclosure, .fv-review, .fv-answer) {
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
}

@media (max-width: 900px) {
  :is([data-style="skleneny"], [data-style="vlastni"][data-custom~="sklo"]) {
    --blur: none;
    --panel-blur: none;
    /* Bez rozostření by přilepený pruh propouštěl rolující obsah. */
    --panel-bg: var(--surf);
  }
}

/* Novinový: svislé linky mezi většími bloky jako mezi sloupci novin
 * (zadavatel 15. 9. 2026 večer: „ne na okrajích, ale mezi nimi“). Blok se
 * rozšíří do půlky mezery (odsazení a záporný okraj se vyruší, obsah se
 * nehne) a linka stojí uprostřed mezery; karty Novinového nemají výplň ani
 * okraj, takže rozšíření není vidět. Jen tam, kde je počet sloupců pevný:
 * dva sloupce Přehledu, dvě dlaždice vlevo (od 64 rem šířky Přehledu), tři
 * dlaždice Co plán říká, dva sloupce jedné varianty. */
@media (min-width: 62rem) {
  :is([data-style="novinovy"], [data-style="vlastni"][data-custom~="svisle-linky"]) .fv-overview > .fv-overview__right {
    border-left: var(--column-rule);
    padding-left: calc(var(--sp-5) / 2);
    margin-left: calc(-1 * var(--sp-5) / 2);
  }

  @container prehled (min-width: 64rem) {
    :is([data-style="novinovy"], [data-style="vlastni"][data-custom~="svisle-linky"]) .fv-overview > .fv-tiles > :nth-child(2n) {
      border-left: var(--column-rule);
      padding-left: calc(var(--sp-3) / 2 + var(--sp-4));
      margin-left: calc(-1 * var(--sp-3) / 2);
    }
  }

  :is([data-style="novinovy"], [data-style="vlastni"][data-custom~="svisle-linky"]) .fv-tiles--three > :not(:nth-child(3n + 1)) {
    border-left: var(--column-rule);
    padding-left: calc(var(--sp-3) / 2 + var(--sp-4));
    margin-left: calc(-1 * var(--sp-3) / 2);
  }

  :is([data-style="novinovy"], [data-style="vlastni"][data-custom~="svisle-linky"]) .fv-variant > :nth-child(2) {
    border-left: var(--column-rule);
    padding-left: calc(var(--sp-4) / 2);
    margin-left: calc(-1 * var(--sp-4) / 2);
  }
}

/* Živý: dlaždice a karty se objeví postupně, čára grafu se vykreslí; jen bez
 * omezení pohybu (design.md §3), s ním je Živý totéž co Výchozí se zdvihem. */
@keyframes fv-style-up {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes fv-style-draw {
  to {
    stroke-dashoffset: 0;
  }
}

/* Zachvění tlačítka po najetí (zadavatel 15. 9. 2026 večer: „položky
 * s odkazy, v podstatě tlačítka, po najetí myší trochu zachvět“): zdvih se
 * dvěma kmity do stran, konec ve zdvihu jako u ostatních stylů. */
@keyframes fv-style-wiggle {
  0% {
    transform: translateY(0) rotate(0);
  }
  30% {
    transform: translateY(-2px) rotate(-1.5deg);
  }
  60% {
    transform: translateY(-2px) rotate(1.2deg);
  }
  100% {
    transform: translateY(-2px) rotate(0);
  }
}

/* Položka menu po najetí popojede doprava a vrátí se o kus zpět. */
@keyframes fv-style-nudge {
  0% {
    transform: translateX(0);
  }
  45% {
    transform: translateX(5px);
  }
  100% {
    transform: translateX(2px);
  }
}

@media (prefers-reduced-motion: no-preference) {
  /* Totéž zapíná slovo `oziveni` vlastního stylu (16. 9. 2026). */
  :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) .fv-card,
  :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) .fv-chart {
    animation: fv-style-up 420ms ease both;
  }
  :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) .fv-card:nth-child(2) { animation-delay: 60ms; }
  :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) .fv-card:nth-child(3) { animation-delay: 120ms; }
  :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) .fv-card:nth-child(4) { animation-delay: 180ms; }
  :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) .fv-card:nth-child(5) { animation-delay: 240ms; }
  :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) .fv-card:nth-child(6) { animation-delay: 300ms; }
  :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) .fv-card:nth-child(n + 7) { animation-delay: 360ms; }
  :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) .fv-chart {
    animation-delay: 240ms;
  }
  /* Jen plné čáry: čárkovaná řada by po vykreslení zůstala plná. */
  :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) .fv-chart__plot polyline[data-series][stroke-dasharray="0"] {
    stroke-dasharray: 1400;
    stroke-dashoffset: 1400;
    animation: fv-style-draw 900ms ease-out 350ms forwards;
  }

  /* Zachvění jen s myší (`hover: hover`): na dotyku by se prvek chvěl až po
   * klepnutí, tedy pozdě a bez užitku. Klávesnice má zdvih a fokus. */
  @media (hover: hover) {
    :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) :is(.fv-button, .fv-topbar__action, .fv-topbar__fold, .fv-nav__icon-button, .fv-basis__option, .fv-chip, .fv-views__tab):hover {
      animation: fv-style-wiggle 360ms ease-out both;
    }

    :is([data-style="zivy"], [data-style="vlastni"][data-custom~="oziveni"]) .fv-nav__link:hover {
      animation: fv-style-nudge 280ms ease-out both;
    }
  }
}

/* ===== Vlastní styl: stránka /vzhled/vlastni (16. 9. 2026) =================
 * Skupiny voleb po řádcích: jméno, přepínač nebo zaškrtávací pole, věta,
 * co se změní. Ukázka nahoře jsou tytéž třídy jako živá dlaždice, graf
 * a tabulka, aby volba grafu nebo tabulky byla vidět hned. */
.fv-custom__sample {
  display: grid;
  grid-template-columns: minmax(190px, 1fr) minmax(240px, 2fr) minmax(220px, 1.4fr);
  gap: var(--sp-3);
  margin: var(--sp-4) 0 var(--sp-5);
}

.fv-custom__tile {
  container-type: inline-size;
}

.fv-custom__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: var(--sp-3) 0 0;
}

.fv-custom__chart .fv-chart__title {
  margin-bottom: var(--sp-2);
}

.fv-custom__table {
  overflow-x: auto;
}

.fv-custom__preset {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  margin: 0 0 var(--sp-5);
}

.fv-custom__preset-select {
  width: auto;
  max-width: none;
  height: auto;
  padding: var(--sp-1) var(--sp-3);
  font-size: var(--fs-13);
}

.fv-custom__preset-note,
.fv-custom__actions-note {
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-custom__section {
  margin: 0 0 var(--sp-4);
  min-width: 0;
}

.fv-custom__legend {
  font-family: var(--font-display);
  font-size: var(--h2-size);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
  line-height: var(--lh-heading);
  padding: 0;
  margin-bottom: var(--sp-2);
}

.fv-custom__row {
  display: grid;
  grid-template-columns: minmax(9rem, 12rem) 1fr;
  gap: var(--sp-1) var(--sp-4);
  align-items: start;
  border: 0;
  margin: 0;
  padding: var(--sp-3) 0;
  border-top: max(var(--row-line), 1px) solid var(--line-c);
  min-width: 0;
}

.fv-custom__row:first-of-type {
  border-top: 0;
}

.fv-custom__name {
  padding: 0;
  font-weight: var(--fw-label);
  font-size: var(--fs-15);
}

/* Legend je v mřížce jako běžný prvek jen s `float`, jinak ho prohlížeč
 * vyjme z mřížky a řádek se rozpadne. */
.fv-custom__row > legend {
  float: left;
  width: 100%;
}

.fv-custom__note {
  grid-column: 2;
  color: var(--tx2);
  font-size: var(--fs-13);
}

.fv-custom__options {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

.fv-custom__option {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-chip);
  background: var(--field);
  font-size: var(--fs-13);
  cursor: pointer;
}

.fv-custom__option input {
  margin: 0;
  accent-color: var(--acc);
}

.fv-custom__option:has(input:checked) {
  border-color: var(--acc);
}

.fv-custom__option:has(input:focus-visible) {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

.fv-custom__row--toggle .fv-custom__option--toggle {
  grid-column: 1 / -1;
  justify-self: start;
  background: none;
  border: 0;
  padding: 0;
  border-radius: 0;
  font-size: var(--fs-15);
}

.fv-custom__row--toggle .fv-custom__note {
  grid-column: 1 / -1;
  padding-left: calc(13px + var(--sp-2));
}

.fv-custom__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-5) 0;
}

/* Ukázka zůstává nahoře a volby pod ní rolují (zadavatel 16. 9. 2026:
 * „aby uživatel viděl efekty toho, co zaklikává“). Přilepená k hornímu
 * okraji okna: stránka nemá horní pruh plánu, a hlavička veřejných stránek
 * ani pruh testovacího prostředí přilepené nejsou, takže nula sedí v obou
 * rozvrženích. Podklad stránky pod ní, aby rolující text neprosvítal mezi
 * kartami; vlasová linka dole odděluje, co stojí, od toho, co jede. Jen
 * tam, kde na to je místo: na telefonu by tři karty nad sebou vzaly celou
 * obrazovku a na nízkém okně by na volby nezbylo. */
@media (min-width: 901px) and (min-height: 640px) {
  .fv-custom__sample {
    position: sticky;
    top: 0;
    z-index: 10;
    margin: 0;
    padding: var(--sp-3) 0;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
  }

  .fv-custom__preset {
    margin-top: var(--sp-5);
  }
}

@media (max-width: 900px) {
  .fv-custom__sample {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 640px) {
  .fv-custom__row {
    grid-template-columns: 1fr;
  }

  .fv-custom__note {
    grid-column: 1;
  }
}

/* Autor na stránce O nás (20. 9. 2026). Fotka vedle textu na širokém
 * displeji, pod sebou na telefonu. Šířka fotky je pevná, aby se logo
 * v pozadí dalo přečíst; `flex` s `wrap` stačí a nepotřebuje dotaz na
 * šířku obrazovky. */
.fv-autor {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
  align-items: flex-start;
  margin-top: var(--sp-4);
}

.fv-autor__foto {
  display: block;
  width: 240px;
  height: auto;
  border-radius: var(--r-card);
  border: var(--bw) solid var(--line-c);
}

/* Text si bere zbytek řádku a pod 520 px se fotka i text roztáhnou přes
 * celou šířku, takže odstavce nezůstanou v úzkém sloupci. */
.fv-autor__text {
  flex: 1 1 20rem;
}

.fv-autor__jmeno {
  margin-top: 0;
}
