/* === 01-tokens.css === */
/* ==========================================================================
   01 · Tokeny
   Odvozené z Zff-brand-manual.html v1.0. Názvy proměnných jsou závazné
   (zadání, část 3) — nepřejmenovávat, jinou barvu nedopisovat.
   ========================================================================== */

:root {
  /* --- paleta manuálu, oddíl 09 --------------------------------------- */
  --zff-blue:  #2D2E94;  /* nosná barva, plochy, hlavní text */
  --zff-cream: #E9DBBC;  /* sekundární plocha */
  --zff-gold:  #CFAE6A;  /* akcent: linky, detaily, deskriptor */
  --zff-paper: #F8F7F6;  /* základní podklad — NE #FFFFFF */
  --zff-mint:  #13CFB4;  /* data, pozitivní hodnoty */
  --zff-sun:   #FFE04E;  /* signály, highlighty, CTA na modré */
  --zff-ink:   #14153F;  /* text na světlém, kde modrá vibruje */

  /* --- odvozené, ale nutné -------------------------------------------- */

  /* Zlatá jako text na světlém neprojde (1,98 : 1). Náhrada ze zadání,
     část 3: #7C6840 — na papíru 5,02 : 1, tedy AA.
     Na KRÉMOVÉ ale stejná barva dává jen 3,92 : 1 a na drobný text
     nestačí, proto druhý, tmavší odstín. Ověřuje tests/test_design.py. */
     Řeší se přepsáním samotného tokenu na krémové ploše (viz 03-type.css),
     takže každé var(--zff-gold-text) je správné automaticky a nikdo to
     nemusí hlídat u jednotlivých komponent. */
  --zff-gold-text: #7C6840;         /* na papíru — 5,02 : 1, AA */
  --zff-gold-text-on-cream: #745A25; /* na krémové — 4,74 : 1, AA */

  /* Fokusový obrys. Není v paletě manuálu záměrně: musí být rozlišitelný
     od každé barvy identity, aby ho nešlo přehlédnout na modré ani na
     krémové ploše (zadání, část 3). */
  --zff-focus: #8865FF;

  /* Fialová sama projde 3 : 1 (WCAG 1.4.11) jen na papíru (3,67 : 1) a na
     inkoustu (4,43 : 1). Na krémové 2,86, na modré 2,77, na zlaté 1,85.
     Fokus proto nese DVA soustředné prstence: fialový obrys a vedle něj
     prstenec v barvě, která proti dané ploše kontrast má. Každá plocha si
     --zff-focus-ring přepíše na svou. Není to stín — nulové rozostření,
     plná barva, tedy obrys, který manuál povoluje. */
  --zff-focus-ring: var(--zff-ink);

  /* Linky a jemné hranice. Nikdy stín — manuál stíny zakazuje. */
  --zff-rule:        rgba(45, 46, 148, .14);
  --zff-rule-strong: rgba(45, 46, 148, .28);
  --zff-rule-on-blue:  rgba(233, 219, 188, .22);
  --zff-rule-on-cream: rgba(20, 21, 63, .16);

  /* Text v nižší hierarchii. Držíme se inkoustu s alfou, ne šedé —
     šedá není v paletě. */
  --zff-ink-80: rgba(20, 21, 63, .80);
  --zff-ink-64: rgba(20, 21, 63, .64);
  /* Pozor: 48 % inkoustu na papíře je 3,14 : 1. --zff-c-faint z něj
     smí barvit jen dekoraci (linky, neaktivní značky), nikdy text —
     na tak světlé ploše žádná čtvrtá úroveň sytosti AA neprojde. */
  --zff-ink-48: rgba(20, 21, 63, .48);
  --zff-cream-80: rgba(233, 219, 188, .80);
  /* 64 % krémové na modré je 4,13 : 1, pod AA. Na tmavých plochách
     proto muted začíná na 75 % (5,09 : 1) — popisky formuláře v oddílu 10
     a text patičky nesou obsah, ne dekoraci. */
  --zff-cream-64: rgba(233, 219, 188, .64);
  --zff-cream-75: rgba(233, 219, 188, .75);

  /* --- mřížka, oddíl „Mřížka" v zadání -------------------------------- */
  --zff-maxw: 1180px;      /* max. šířka obsahu */
  --zff-gutter: 40px;      /* okraj na desktopu */
  --zff-unit: 8px;         /* základní jednotka */

  /* Editoriální rozvržení: levý sloupec s číslem oddílu + obsah */
  --zff-rail: 200px;
  /* Výška lepivé lišty na mobilu. Drží ji dvě položky vysoké 44 px
     kvůli cílové ploše plus odsazení — a stejnou hodnotu si bere
     <main> jako rezervu odspodu. */
  --zff-mobilnav-h: 64px;
  --zff-rail-gap: 56px;

  /* Krok o osmi. Používat tyto, ne libovolná px. */
  --zff-s1:  8px;
  --zff-s2:  16px;
  --zff-s3:  24px;
  --zff-s4:  32px;
  --zff-s5:  40px;
  --zff-s6:  56px;
  --zff-s7:  72px;
  --zff-s8:  96px;
  --zff-s9:  128px;

  /* Řádek 60–72 znaků (manuál, Pravidla sazby) */
  --zff-measure: 68ch;
  --zff-measure-narrow: 56ch;

  /* --- typografie ------------------------------------------------------ */
  --zff-font: "Golos Text", Inter, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  /* Calibri ani Times New Roman se ve fallbacku neobjeví — manuál je
     výslovně zakazuje. */

  --zff-wght-body:    400;
  --zff-wght-medium:  500;
  --zff-wght-semi:    600;
  --zff-wght-num:     700;
  --zff-wght-display: 800;

  /* Škála. Weight a prostrkání jsou z manuálu, velikosti dopočítané na
     mřížku 8 px s fluidním rozsahem. */
  --zff-fs-display: clamp(40px, 6.0vw, 76px);
  --zff-fs-h1:      clamp(32px, 4.4vw, 54px);
  --zff-fs-h2:      clamp(26px, 3.2vw, 40px);
  --zff-fs-h3:      clamp(19px, 1.6vw, 22px);
  --zff-fs-h4:      17px;
  --zff-fs-lead:    clamp(18px, 1.5vw, 21px);
  --zff-fs-body:    17px;
  --zff-fs-small:   14px;
  --zff-fs-label:   12.5px;

  --zff-fs-num-xl: clamp(40px, 5.2vw, 64px);
  --zff-fs-num-l:  clamp(28px, 3.0vw, 36px);
  --zff-fs-num-m:  21px;

  --zff-ls-display: -.03em;   /* −3 % */
  --zff-ls-h1:      -.025em;  /* −2,5 % */
  --zff-ls-h2:      -.02em;   /* −2 % */
  --zff-ls-h3:      -.01em;
  --zff-ls-num:     -.02em;   /* −2 % */
  --zff-ls-label:    .09em;   /* +9 % */

  --zff-lh-heading: 1.1;      /* nadpisy 1,1 */
  --zff-lh-display: 1.04;
  --zff-lh-body:    1.6;      /* běžný text 1,6 */

  /* --- pohyb ----------------------------------------------------------- */
  /* Jen opacity a posun, do 200 ms (zadání, část 3) */
  --zff-motion: 160ms;
  --zff-ease: cubic-bezier(.2, .6, .3, 1);

  /* --- klikací plocha --------------------------------------------------- */
  --zff-touch: 44px;   /* nikdy méně */
}

@media (max-width: 640px) {
  :root {
    --zff-gutter: 20px;   /* okraj na mobilu */
  }
}

/* === 02-base.css === */
/* ==========================================================================
   02 · Základ — font, reset, fokus, pohyb
   ========================================================================== */

/* Golos Text, variabilní, self-hostovaný. Žádné Google Fonts CDN —
   u webu FKI je zbytečné posílat IP návštěvníků třetí straně
   (kostra, část 8). Licence SIL OFL 1.1.

   BC Novatica se nenasazuje vůbec: žije jen v logu, a tam je v obrysech. */
@font-face {
  font-family: "Golos Text";
  src: url("fonts/zff-golos-var.woff2") format("woff2") tech(variations),
       url("fonts/zff-golos-var.woff2") format("woff2-variations");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

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

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

body {
  margin: 0;
  background: var(--zff-paper);
  color: var(--zff-ink);
  font-family: var(--zff-font);
  font-size: var(--zff-fs-body);
  font-weight: var(--zff-wght-body);
  line-height: var(--zff-lh-body);
  font-synthesis-weight: none;   /* radši chybějící řez než falešný bold */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: left;              /* nikdy nic vycentrovaného */
}

img, svg, picture, video { max-width: 100%; height: auto; display: block; }

/* --- fokus ---------------------------------------------------------------
   `outline: none` je zakázané (zadání, část 3). Obrys 2 px, odsazení 2 px,
   na každém interaktivním prvku včetně <summary> a vlastních přepínačů. */
:where(a, button, input, select, textarea, summary, label, [tabindex]):focus-visible {
  outline: 2px solid var(--zff-focus);
  outline-offset: 2px;
  /* Druhý prstenec, aby indikátor splnil 3 : 1 i tam, kde na to fialová
     sama nemá (krémová, modrá, zlatá, slunečná, mentolová).
     Nulové rozostření = obrys, ne stín. */
  box-shadow: 0 0 0 2px var(--zff-focus-ring);
}

/* Prohlížeče, které :focus-visible neznají, dostanou obrys na :focus.
   Nikde se nesmí objevit outline:0 bez náhrady. */
@supports not selector(:focus-visible) {
  :where(a, button, input, select, textarea, summary, [tabindex]):focus {
    outline: 2px solid var(--zff-focus);
    outline-offset: 2px;
  }
}

/* Druhý prstenec si každá plocha nastavuje tokenem --zff-focus-ring
   v 03-type.css, kde jsou všechny barvy ploch pohromadě. Poměry ověřuje
   tests/test_design.py, ne odhad. */

/* --- klikací plochy ------------------------------------------------------
   Nikdy pod 44 × 44 px (zadání, část 3 a část 9). */
a, button, summary, input[type="checkbox"], input[type="radio"], label.zff-choice {
  min-height: var(--zff-touch);
}

button, a.zff-btn, .zff-btn {
  min-width: var(--zff-touch);
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
}

/* Odkaz uprostřed věty nemůže být 44 px vysoký, aniž by rozhodil
   řádkování. Dřív tu byl pseudoprvek, který klikací plochu roztahoval —
   nefungoval (hit test vracel sousední prvek) a hlavně vytvářel neviditelné
   překryvy, které kradly kliknutí obsahu nad a pod sebou. Odstraněno.

   WCAG 2.5.5 i 2.5.8 mají pro odkazy ve větě výslovnou výjimku: hitem je
   řádek textu. Pravidlo 44 × 44 px se drží u všeho, co je samostatný
   ovládací prvek — a to jsou selektory níže. */
p a, li a, td a, dd a { min-height: 0; }

/* Odkazy, které stojí samy a nejsou součástí věty: zdroj pod grafem,
   poznámka pod tabulkou, odkazy v patičce. Ty 44 px mít mají a dostanou
   je odsazením, ne trikem. */
.zff-source a,
.zff-table a,
.zff-footer a,
.zff-card a {
  display: inline-block;
  padding-block: 12px;
  min-height: 0;
}

/* Jenže v patičce už odkaz na metodiku nestojí sám — je uprostřed věty.
   Odsazení 12 px z něj udělá 45px blok, který nadzvedne svůj řádek
   a rozhodí prokládání celého odstavce. Odkaz uvnitř věty je navíc
   z pravidla 24 × 24 výslovně vyjmutý (WCAG 2.5.8, výjimka „inline":
   velikost cíle je dána prokládáním okolního textu). */
.zff-footer small a {
  display: inline;
  padding-block: 0;
}

/* --- pohyb ---------------------------------------------------------------
   Jen opacity a posun, do 200 ms. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* --- co manuál zakazuje --------------------------------------------------
   Stíny, gradienty a plastické efekty. Necháváme tu jako dokumentaci
   toho, co se do webu nesmí dopsat; kontroluje to tests/test_design.py. */

/* === 03-type.css === */
/* ==========================================================================
   03 · Typografická škála a plochy
   Manuál, oddíl 10. Weight a prostrkání jsou závazné, velikosti dopočítané.
   ========================================================================== */

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-weight: var(--zff-wght-semi);
  line-height: var(--zff-lh-heading);
  color: var(--zff-c-heading);
  /* Nadpisy zalamovat po smyslu (zadání, část 5). balance dělá zbytek
     práce, ochranu proti jednoslovné poslední řádce doplňuje build. */
  text-wrap: balance;
  max-width: 34ch;
}

/* Display · 800 · −3 % */
.zff-display {
  font-size: var(--zff-fs-display);
  font-weight: var(--zff-wght-display);
  letter-spacing: var(--zff-ls-display);
  line-height: var(--zff-lh-display);
  max-width: 22ch;
}

/* H1 · 600 · −2,5 % */
h1, .zff-h1 {
  font-size: var(--zff-fs-h1);
  letter-spacing: var(--zff-ls-h1);
}

/* H2 · 600 · −2 % */
h2, .zff-h2 {
  font-size: var(--zff-fs-h2);
  letter-spacing: var(--zff-ls-h2);
}

/* H3 · 600 */
h3, .zff-h3 {
  font-size: var(--zff-fs-h3);
  letter-spacing: var(--zff-ls-h3);
  max-width: 40ch;
}

/* H4 · 600 */
h4, .zff-h4 {
  font-size: var(--zff-fs-h4);
  letter-spacing: 0;
  max-width: 46ch;
}

/* Body · 400 · 1,6 */
p, li, dd, .zff-body {
  font-size: var(--zff-fs-body);
  line-height: var(--zff-lh-body);
  max-width: var(--zff-measure);
}

p { margin: 0 0 var(--zff-s3); }
p:last-child { margin-bottom: 0; }

/* Seznamy. Odrážka zlatá jako orientační prvek, text vlevo na praporek. */
ul, ol {
  margin: 0;
  padding-left: 1.3em;
  max-width: var(--zff-measure);
}
li + li { margin-top: var(--zff-s1); }
li::marker {
  color: var(--zff-c-label);
  font-weight: var(--zff-wght-num);
}
li > ul, li > ol { margin-top: var(--zff-s1); }

/* Perex */
.zff-lead {
  font-size: var(--zff-fs-lead);
  line-height: 1.5;
  max-width: var(--zff-measure-narrow);
  color: var(--zff-c-lead);
}

/* Small · 400 — poznámky pod grafy, disclaimery */
small, .zff-small {
  font-size: var(--zff-fs-small);
  line-height: 1.5;
  color: var(--zff-c-muted);
  display: block;
  max-width: var(--zff-measure);
}

/* Label · 600 · +9 % */
.zff-label {
  font-size: var(--zff-fs-label);
  font-weight: var(--zff-wght-semi);
  letter-spacing: var(--zff-ls-label);
  text-transform: uppercase;
  line-height: 1.3;
  margin: 0;
  max-width: none;
  color: var(--zff-c-label);
}

/* Číslo · 700 · −2 · tabular-nums
   Bez tabular-nums by čísla ve sloupci tabulky neseděla pod sebou. */
.zff-num,
.zff-num-xl,
.zff-num-l,
.zff-num-m {
  font-weight: var(--zff-wght-num);
  letter-spacing: var(--zff-ls-num);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  line-height: 1.05;
  display: block;
  color: var(--zff-c-num);
}

.zff-num-xl { font-size: var(--zff-fs-num-xl); }
.zff-num-l  { font-size: var(--zff-fs-num-l); }
.zff-num-m  { font-size: var(--zff-fs-num-m); }

/* ==========================================================================
   Plochy

   POZOR na architekturu: barvy se NESMÍ řešit potomkovými selektory jako
   `.zff-on-blue .zff-num`. Plochy se na webu vnořují (modrá karta v krémové
   sekci) a tam by dvě takové pravidla měla stejnou specificitu — vyhrálo by
   to poslední v souboru, ne to nejbližší. Modrá karta v krémové sekci by tak
   dostala modré číslo na modré ploše, tedy nic.

   Každá plocha proto přepisuje TOKENY. Ty se dědí, takže vždy platí
   nejbližší plocha, a komponenty čtou var(--zff-c-*) bez ohledu na to,
   kde jsou vnořené. Hlídá to tests/test_design.py.
   ========================================================================== */

/* Výchozí hodnoty — pro obsah, který není v žádné ploše */
:root {
  --zff-c-text:    var(--zff-ink);
  --zff-c-heading: var(--zff-blue);
  --zff-c-num:     var(--zff-blue);
  --zff-c-label:   var(--zff-gold-text);
  --zff-c-lead:    var(--zff-ink-80);
  --zff-c-muted:   var(--zff-ink-64);
  --zff-c-faint:   var(--zff-ink-48);
  --zff-c-link:    var(--zff-blue);
  --zff-c-rule:    var(--zff-rule);
  --zff-c-rule-strong: var(--zff-rule-strong);
  --zff-c-pos:     var(--zff-blue);
  --zff-c-neg:     var(--zff-ink);
  --zff-c-cta-bg:  var(--zff-blue);
  --zff-c-cta-fg:  var(--zff-cream);
}

.zff-on-paper {
  /* CTA — modrá na papíru 10,17 : 1 */
  --zff-c-cta-bg: var(--zff-blue);
  --zff-c-cta-fg: var(--zff-cream);
  --zff-c-text:    var(--zff-ink);
  --zff-c-heading: var(--zff-blue);
  --zff-c-num:     var(--zff-blue);
  --zff-c-label:   var(--zff-gold-text);
  --zff-c-lead:    var(--zff-ink-80);
  --zff-c-muted:   var(--zff-ink-64);
  --zff-c-faint:   var(--zff-ink-48);
  --zff-c-link:    var(--zff-blue);
  --zff-c-rule:    var(--zff-rule);
  --zff-c-rule-strong: var(--zff-rule-strong);
  /* Mentolová na světlém je 1,85 : 1 — jako text neprojde. Pozitivní
     hodnota se tu proto nese modrou a mentolová zůstane jen v grafu. */
  --zff-c-pos:     var(--zff-blue);
  --zff-c-neg:     var(--zff-ink);
  --zff-focus-ring: var(--zff-ink);
  background: var(--zff-paper);
  color: var(--zff-c-text);
}

.zff-on-cream {
  /* CTA — modrá na krémové 7,94 : 1 */
  --zff-c-cta-bg: var(--zff-blue);
  --zff-c-cta-fg: var(--zff-cream);
  --zff-c-text:    var(--zff-ink);
  --zff-c-heading: var(--zff-blue);
  --zff-c-num:     var(--zff-blue);
  /* Krémová je světlejší než papír — zlatý text na ní potřebuje tmavší
     odstín (3,92 : 1 by neprošlo). */
  --zff-gold-text: var(--zff-gold-text-on-cream);
  --zff-c-label:   var(--zff-gold-text-on-cream);
  --zff-c-lead:    rgba(20, 21, 63, .80);
  --zff-c-muted:   rgba(20, 21, 63, .66);
  --zff-c-faint:   rgba(20, 21, 63, .55);
  --zff-c-link:    var(--zff-blue);
  --zff-c-rule:    var(--zff-rule-on-cream);
  --zff-c-rule-strong: rgba(20, 21, 63, .30);
  --zff-c-pos:     var(--zff-blue);
  --zff-c-neg:     var(--zff-ink);
  --zff-focus-ring: var(--zff-ink);
  background: var(--zff-cream);
  color: var(--zff-c-text);
}

.zff-on-blue {
  /* CTA — slunečná s modrým textem 8,30 : 1 */
  --zff-c-cta-bg: var(--zff-sun);
  --zff-c-cta-fg: var(--zff-blue);
  --zff-c-text:    var(--zff-cream);
  --zff-c-heading: var(--zff-cream);
  --zff-c-num:     var(--zff-cream);
  --zff-c-label:   var(--zff-gold);      /* 5,14 : 1 — na modré projde */
  --zff-c-lead:    var(--zff-cream-80);
  --zff-c-muted:   var(--zff-cream-75);
  --zff-c-faint:   var(--zff-cream-64);
  --zff-c-link:    var(--zff-cream);
  --zff-c-rule:    var(--zff-rule-on-blue);
  --zff-c-rule-strong: rgba(233, 219, 188, .38);
  --zff-c-pos:     var(--zff-mint);      /* 5,50 : 1 — na modré projde */
  --zff-c-neg:     var(--zff-cream);
  --zff-focus-ring: var(--zff-paper);
  background: var(--zff-blue);
  color: var(--zff-c-text);
}

.zff-on-ink {
  /* CTA — slunečná s modrým textem 8,30 : 1 */
  --zff-c-cta-bg: var(--zff-sun);
  --zff-c-cta-fg: var(--zff-blue);
  --zff-c-text:    var(--zff-cream);
  --zff-c-heading: var(--zff-cream);
  --zff-c-num:     var(--zff-cream);
  --zff-c-label:   var(--zff-gold);      /* 8,20 : 1 */
  --zff-c-lead:    var(--zff-cream-80);
  --zff-c-muted:   var(--zff-cream-75);
  --zff-c-faint:   var(--zff-cream-64);
  --zff-c-link:    var(--zff-cream);
  --zff-c-rule:    var(--zff-rule-on-blue);
  --zff-c-rule-strong: rgba(233, 219, 188, .38);
  --zff-c-pos:     var(--zff-mint);      /* 8,78 : 1 */
  --zff-c-neg:     var(--zff-cream);
  --zff-focus-ring: var(--zff-paper);
  background: var(--zff-ink);
  color: var(--zff-c-text);
}

/* Hodnoty se znaménkem. Záporné jdou inkoustem nebo krémovou, nikdy
   červenou — manuál červenou nemá (kostra, oddíl 05). */
.zff-val-pos { color: var(--zff-c-pos); }
.zff-val-neg { color: var(--zff-c-neg); }

/* --- odkazy --------------------------------------------------------------- */

a {
  color: var(--zff-c-link);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  text-decoration-color: var(--zff-gold);
  transition: opacity var(--zff-motion) var(--zff-ease);
}
a:hover { text-decoration-color: currentColor; }

/* --- doplňky -------------------------------------------------------------- */

strong, b { font-weight: var(--zff-wght-semi); }

abbr[title] { text-decoration: underline dotted var(--zff-gold); cursor: help; }

/* Zlatá displejově nad 32 px — jediná výjimka pro zlatý text na světlém
   (manuál: „nebo v displejové velikosti nad 32 px"), a i tak nikdy pro
   sdělení, které musí být přečteno. */
.zff-gold-display {
  color: var(--zff-gold);
  font-size: clamp(34px, 4vw, 56px);
  font-weight: var(--zff-wght-display);
  letter-spacing: var(--zff-ls-display);
}

/* === 04-layout.css === */
/* ==========================================================================
   04 · Mřížka a rytmus sekcí
   Max. šířka 1180, okraje 40 / 20, jednotka 8. Editoriální rozvržení
   200 px rail + obsah, mezera 56 px, pod 900 px se skládá.
   ========================================================================== */

.zff-wrap {
  max-width: var(--zff-maxw);
  margin-inline: auto;
  padding-inline: var(--zff-gutter);
}

/* --- sekce ---------------------------------------------------------------
   Rytmus ploch: modrá → papír → krémová → papír → modrá → krémová → modrá
   (zadání, část 3). Poměr cílí na 45 % modrá, 45 % papír a krémová,
   7 % zlatá, 3 % mentolová se slunečnou. */
.zff-section {
  padding-block: var(--zff-s8);
  position: relative;
}

@media (max-width: 640px) {
  .zff-section { padding-block: var(--zff-s6); }
}

/* Sekce na modré, která nese pás vzoru u dolní hrany, potřebuje odspodu
   místo na jeho výšku — jinak vzor poleze pod text, což manuál zakazuje. */
.zff-section--pattern-bottom { padding-bottom: calc(var(--zff-s8) + 120px); }

/* --- editoriální rozvržení ------------------------------------------------ */

.zff-editorial {
  display: grid;
  grid-template-columns: var(--zff-rail) minmax(0, 1fr);
  gap: var(--zff-rail-gap);
  align-items: start;
}

/* min-width: 0 na položkách mřížky.

   Bez toho má položka `min-width: auto`, což je min-content jejího obsahu.
   Široká tabulka uvnitř .zff-table-scroll pak roztáhne celý obsahový
   sloupec nad šířku stopy — a to i když tabulka sama má overflow-x: auto,
   protože k výpočtu min-content se scroll container nepřihlíží.
   Projevilo se to jako vodorovné přetečení stránky o pár pixelů. */
.zff-editorial__rail,
.zff-editorial__body {
  min-width: 0;
}

.zff-editorial__rail {
  display: flex;
  flex-direction: column;
  gap: var(--zff-s1);
  position: sticky;
  top: var(--zff-s5);
}

/* Číslo oddílu. Zlatá, ale ne jako sdělení — je to orientační prvek. */
.zff-editorial__num {
  font-size: var(--zff-fs-num-m);
  font-weight: var(--zff-wght-num);
  letter-spacing: var(--zff-ls-num);
  font-variant-numeric: tabular-nums;
  color: var(--zff-c-label);
  line-height: 1;
}

/* Rytmus uvnitř obsahového sloupce: mezera mezi bloky, větší PŘED
   podnadpisem. Nadpisy samy margin nemají — jinak by se mezery sčítaly. */
.zff-editorial__body > * + * { margin-top: var(--zff-s3); }
.zff-editorial__body > * + h3,
.zff-editorial__body > * + h4 { margin-top: var(--zff-s5); }

/* Pod 900 px se skládá pod sebe (zadání, část 3). */
@media (max-width: 900px) {
  .zff-editorial {
    grid-template-columns: 1fr;
    gap: var(--zff-s3);
  }
  .zff-editorial__rail {
    position: static;
    flex-direction: row;
    align-items: baseline;
    gap: var(--zff-s2);
  }
}

/* --- pomocné rozvržení ---------------------------------------------------- */

/* Kontejnery, které drží mezery vlastním `gap`, musí potomkům vynulovat
   svislé marginy. Ve flexu ani v gridu se marginy neslučují, takže
   `gap: 24px` plus `p { margin-bottom: 24px }` dá 48 px — a rytmus se
   rozjede právě tam, kde je textu nejvíc. */
.zff-stack > *,
.zff-row > *,
.zff-grid > *,
.zff-statrow > *,
.zff-databar > *,
.zff-goldblock > *,
.zff-controls > *,
.zff-results > *,
.zff-diff > *,
.zff-contact > *,
.zff-form > *,
.zff-chartrow > *,
.zff-logoband > *,
.zff-figure > * {
  margin-block: 0;
}

.zff-stack        { display: flex; flex-direction: column; }
.zff-stack--1     { gap: var(--zff-s1); }
.zff-stack--2     { gap: var(--zff-s2); }
.zff-stack--3     { gap: var(--zff-s3); }
.zff-stack--4     { gap: var(--zff-s4); }
.zff-stack--6     { gap: var(--zff-s6); }

.zff-row { display: flex; flex-wrap: wrap; gap: var(--zff-s3); align-items: baseline; }

.zff-grid { display: grid; gap: var(--zff-s3); }
.zff-grid--2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.zff-grid--3 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.zff-grid--4 { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }

/* Čtyři čísla v řadě — hlavička oddílu 05. Na mobilu 2 × 2, ne 1 × 4:
   dvojice „propad / kladných měsíců" má být vidět pohromadě.

   minmax(0, 1fr), ne 1fr: `1fr` znamená `minmax(auto, 1fr)` a auto
   nedovolí položce zmenšit se pod min-content. Dlouhá hodnota jako
   „200–250 mil. Kč" pak rozšíří celou mřížku a stránka začne přetékat
   vodorovně. S minmax(0, …) se místo toho zalomí. */
/* Počet sloupců se řídí šířkou, kterou číslo potřebuje — ne pevnou
   čtyřkou. Pevné `repeat(4, minmax(0, 1fr))` bylo v oddílu 05 rozbité:
   --zff-fs-num-xl je clamp(40px, 5.2vw, 64px), tedy roste s OBRAZOVKOU,
   zatímco sloupec sazby se zastaví na 844 px. Na 1920 px pak „+36,7 %"
   potřebovalo 240 px ve 187px buňce a první dvě čísla se překryla.

   auto-fit s dolní mezí drží čísla oddělená na jakékoli šířce: kde se
   čtyři nevejdou, vysází se dvě řady. */
.zff-statrow {
  display: grid;
  /* 180px drží čtyři sloupce v plné šířce sazby (844 px); delší hodnota
     jako „200–250m Kč" se v takové buňce zalomí na dva řádky, což je
     v pořádku — zalomení nevadí, překryv ano. */
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--zff-s4);
}
/* Řada s 64px čísly potřebuje širší buňku než řada s 36px. */
.zff-statrow--xl {
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
@media (max-width: 760px) {
  .zff-statrow { gap: var(--zff-s3); }
}

/* Čísla a popisky se v úzkém sloupci musí umět zalomit. */
.zff-statrow .zff-num-xl,
.zff-statrow .zff-num-l,
.zff-goldblock .zff-num-xl,
.zff-goldblock .zff-num-l {
  overflow-wrap: break-word;
  text-wrap: balance;
}

/* --- pás vzoru -----------------------------------------------------------
   Vzor jen jako pás u hrany modré plochy. Nikdy pod logem, textem ani
   čísly, nikdy rotovaný, nikdy dvoubarevný (manuál, oddíl 11). */
.zff-pattern {
  position: absolute;
  left: 0;
  right: 0;
  height: 120px;
  pointer-events: none;
  overflow: hidden;
  opacity: .5;
}
.zff-pattern--bottom { bottom: 0; }
.zff-pattern--top    { top: 0; }
.zff-pattern svg { width: 100%; height: 100%; display: block; }

/* --- oddělovače ----------------------------------------------------------- */

.zff-rule {
  border: 0;
  border-top: 1px solid var(--zff-c-rule);
  margin: 0;
}

/* Zlatá linka — akcent, ne nosič. Grafický prvek, takže na světlém smí. */
.zff-rule--gold { border-top: 2px solid var(--zff-gold); }

/* --- přeskočit na obsah --------------------------------------------------- */

.zff-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--zff-blue);
  color: var(--zff-cream);
  padding: var(--zff-s2) var(--zff-s3);
  z-index: 100;
  text-decoration: none;
}
.zff-skip:focus { left: var(--zff-s2); top: var(--zff-s2); }

/* --- jen pro čtečky ------------------------------------------------------- */

.zff-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- barevný pás uvnitř oddílu -------------------------------------------
   Oddíly na /prilezitost mají i patnáct odstavců a šest tabulek. Jedna
   plocha na celý oddíl je pro takovou délku málo — čtenář nepozná, kde
   jedna věc končí. Pás vezme část oddílu na jinou plochu a rozdělí ho
   opticky, aniž by se musel dělit na dva oddíly.

   Vodorovně přetéká o mezeru mřížky, aby to byl pás, ne karta: uvnitř
   textového sloupce by se to čtlo jako poznámka. Odspodu i odshora
   dýchá víc než odstavec, jinak se slepí s okolním textem. */
.zff-band {
  margin: var(--zff-s5) calc(-1 * var(--zff-s4));
  padding: var(--zff-s5) var(--zff-s4);
}
.zff-band > :first-child { margin-top: 0; }
.zff-band > :last-child { margin-bottom: 0; }

/* Na úzkém displeji stojí oddíl v obalu s vlastním odsazením — pás se
   proto roztáhne na celou jeho šířku a přesah zruší, jinak by vylezl
   z obrazovky. */
@media (max-width: 900px) {
  .zff-band {
    margin-inline: calc(-1 * var(--zff-gutter));
    padding-inline: var(--zff-gutter);
  }
}

/* --- navigace po oddílech ------------------------------------------------
   Stránka /prilezitost má deset oddílů a přes dvanáct tisíc pixelů. Bez
   navigace se v ní nedá orientovat a krok dál je až v desátém oddílu.

   Nikde na to není potřeba JavaScript: rejstřík jsou obyčejné odkazy
   a lepivý index v railu je vypsaný v každém oddílu zvlášť, takže
   o aktivní položce rozhoduje build, ne skript. */

/* Pás „Na této stránce" mezi herem a oddílem 01. */
.zff-obsah {
  padding-block: var(--zff-s4);
}
.zff-obsah__list {
  list-style: none;
  padding: 0;
  margin: var(--zff-s2) 0 0;
  max-width: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--zff-s1) var(--zff-s4);
}
.zff-obsah__item { margin: 0; max-width: none; }
.zff-obsah__link {
  display: flex;
  align-items: baseline;
  gap: var(--zff-s2);
  padding-block: 6px;
  min-height: var(--zff-touch);
  align-content: center;
  flex-wrap: wrap;
  text-decoration: none;
  color: var(--zff-c-text);
  border-bottom: 1px solid var(--zff-c-rule);
}
.zff-obsah__link:hover { border-bottom-color: var(--zff-c-rule-strong); }
.zff-obsah__link:hover .zff-obsah__nazev { text-decoration: underline; }
.zff-obsah__num {
  font-weight: var(--zff-wght-num);
  letter-spacing: var(--zff-ls-num);
  font-variant-numeric: tabular-nums;
  color: var(--zff-c-label);
  flex: none;
}

/* Lepivý index v railu. Rail je sticky už kvůli číslu oddílu, takže
   index jen dosedne pod něj. Na úzkých displejích se rail překlápí do
   řádku a index by ho roztrhal — proto se skrývá a nahradí ho lišta dole. */
.zff-railnav {
  margin-top: var(--zff-s4);
  padding-top: var(--zff-s3);
  border-top: 1px solid var(--zff-c-rule);
  display: flex;
  flex-direction: column;
  gap: var(--zff-s3);
}
.zff-railnav__list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: none;
  display: flex;
  flex-direction: column;
}
.zff-railnav__item { margin: 0; max-width: none; }
.zff-railnav__link {
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding-block: 5px;
  font-size: var(--zff-fs-small);
  line-height: 1.25;
  text-decoration: none;
  /* Neaktivní položky drží zpátky, aby index nekonkuroval textu. */
  color: var(--zff-c-muted);
}
.zff-railnav__link:hover { color: var(--zff-c-text); }
.zff-railnav__num {
  font-weight: var(--zff-wght-num);
  letter-spacing: var(--zff-ls-num);
  font-variant-numeric: tabular-nums;
  flex: none;
}
/* Aktivní oddíl. Zlatá linka vlevo — stejný prostředek, jakým se
   zvýrazňuje řádek portfolia v tabulkách. */
.zff-railnav__item--nyni .zff-railnav__link {
  color: var(--zff-c-heading);
  font-weight: var(--zff-wght-semi);
  box-shadow: inset 2px 0 0 var(--zff-gold);
  padding-left: var(--zff-s2);
  margin-left: calc(-1 * var(--zff-s2));
}

/* Trvalé CTA. Schválně ne pilulka: v heru už jedna je a druhá by na sebe
   strhla pozornost od čtení. Tady stačí, že je pořád na dosah. */
.zff-railnav__cta {
  font-size: var(--zff-fs-small);
  font-weight: var(--zff-wght-semi);
  color: var(--zff-c-link);
  text-decoration-color: var(--zff-gold);
  text-underline-offset: 4px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--zff-touch);
}
.zff-railnav__cta::after { content: "→"; }

/* Lišta u dolní hrany pro úzké displeje. */
.zff-mobilnav { display: none; }

@media (max-width: 900px) {
  .zff-railnav { display: none; }

  /* `position: fixed`, ne sticky. Sticky s `bottom: 0` pinuje prvek jen
     dokud je jeho místo v toku POD dolní hranou okna; lišta je ale první
     dítě <main>, tedy nad ním, takže by se odrolovala nahoru a nikdy
     nepřilepila. Fixed za to platí tím, že si musíme na konci stránky
     rezervovat místo — jinak by lišta zakryla patičku. */
  .zff-mobilnav {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    align-items: center;
    gap: var(--zff-s2);
    padding: var(--zff-s1) var(--zff-gutter);
    /* Lišta je jediné místo, kde se plocha drží u hrany okna — proto
       linka nahoře, aby se neslila s obsahem, který pod ní projíždí. */
    border-top: 1px solid var(--zff-c-rule-strong);
  }
  /* Rezerva patří na <body>, ne na <main>: patička je mainu sourozenec,
     takže odsazení uvnitř mainu by ji pod lištou nezachránilo. */
  body { padding-bottom: calc(var(--zff-mobilnav-h) + var(--zff-s2)); }

  /* Dokud je na obrazovce rejstřík oddílů, je lišta zbytečná a jen by ho
     překrývala. Skryje ji ale jen prohlížeč, ve kterém běží skript —
     bez JavaScriptu zůstane vidět od začátku. Lišta, která se sama
     neukáže, je horší než lišta, která je vidět pořád. */
  .zff-hasjs .zff-mobilnav {
    transform: translateY(100%);
    opacity: 0;
    pointer-events: none;
    transition: transform var(--zff-motion) var(--zff-ease),
                opacity var(--zff-motion) var(--zff-ease);
  }
  .zff-hasjs .zff-mobilnav.zff-mobilnav--vidi {
    transform: none;
    opacity: 1;
    pointer-events: auto;
  }
  .zff-mobilnav__details { flex: 1 1 auto; min-width: 0; }
  .zff-mobilnav__summary {
    display: flex;
    align-items: center;
    gap: var(--zff-s1);
    min-height: var(--zff-touch);
    cursor: pointer;
    font-size: var(--zff-fs-label);
    font-weight: var(--zff-wght-semi);
    letter-spacing: var(--zff-ls-label);
    text-transform: uppercase;
    color: var(--zff-c-muted);
    list-style: none;
  }
  .zff-mobilnav__summary::-webkit-details-marker { display: none; }
  .zff-mobilnav__summary::after { content: "▾"; }
  .zff-mobilnav__details[open] .zff-mobilnav__summary::after { content: "▴"; }

  /* Seznam se rozbaluje nahoru, ne dolů — dole je hrana okna. */
  .zff-mobilnav__details[open] .zff-mobilnav__list {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    max-height: 62vh;
    overflow-y: auto;
    background: var(--zff-ink);
    border-top: 1px solid var(--zff-c-rule-strong);
    border-bottom: 1px solid var(--zff-c-rule-strong);
    padding: var(--zff-s2) var(--zff-gutter);
    margin: 0;
    list-style: none;
    max-width: none;
  }
  .zff-mobilnav__item { margin: 0; max-width: none; }
  .zff-mobilnav__link {
    display: flex;
    gap: var(--zff-s2);
    align-items: baseline;
    min-height: var(--zff-touch);
    padding-block: 8px;
    text-decoration: none;
    color: var(--zff-c-text);
  }
  .zff-mobilnav__num {
    font-weight: var(--zff-wght-num);
    letter-spacing: var(--zff-ls-num);
    font-variant-numeric: tabular-nums;
    color: var(--zff-c-label);
    flex: none;
  }
  /* Pilulka má ve výchozím stavu svislé odsazení 16 px, takže by lištu
     vytáhla na 79 px. Tady stačí cílová plocha 44 px. */
  /* Dvě třídy schválně: `.zff-btn` nastavuje `padding` zkratkou v
     05-components.css, který se nahrává po tomhle souboru, takže samotné
     `.zff-mobilnav__cta` by prohrálo na pořadí i při stejné specificitě. */
  .zff-mobilnav .zff-mobilnav__cta {
    flex: none;
    padding-block: var(--zff-s1);
    padding-inline: var(--zff-s3);
  }

  /* Ukazatel postupu bez skriptu. Podporují ho jen novější prohlížeče,
     proto je za @supports — jinde lišta prostě žádnou linku nemá. */
  .zff-mobilnav__pruh { display: none; }
}

@supports (animation-timeline: scroll()) {
  @media (max-width: 900px) {
    .zff-mobilnav__pruh {
      display: block;
      position: absolute;
      left: 0;
      top: -1px;
      height: 2px;
      background: var(--zff-gold);
      transform-origin: 0 50%;
      width: 100%;
      animation: zff-postup linear;
      animation-timeline: scroll(root block);
    }
  }
  @keyframes zff-postup {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
  }
}

/* === 05-components.css === */
/* ==========================================================================
   05 · Komponenty
   Zaoblení jen u pilulkových tlačítek a štítků. Nikde stín ani gradient.

   Komponenty NEZNAJÍ plochu, na které stojí — čtou jen tokeny --zff-c-*,
   které si nastavuje nejbližší .zff-on-*. Díky tomu fungují i vnořené
   (modrá karta v krémové sekci). Viz komentář v 03-type.css.
   ========================================================================== */

/* --- tabulky -------------------------------------------------------------
   Čísla vpravo a v tabular-nums, text vlevo. Žádné zebra pruhy — linka
   stačí a drží klid. */

.zff-table-scroll { overflow-x: auto; }

.zff-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--zff-fs-body);
  font-variant-numeric: tabular-nums;
}

.zff-table caption {
  text-align: left;
  font-size: var(--zff-fs-label);
  font-weight: var(--zff-wght-semi);
  letter-spacing: var(--zff-ls-label);
  text-transform: uppercase;
  color: var(--zff-c-label);
  padding-bottom: var(--zff-s2);
}

.zff-table th,
.zff-table td {
  text-align: left;
  padding: var(--zff-s2) var(--zff-s3) var(--zff-s2) 0;
  border-bottom: 1px solid var(--zff-c-rule);
  vertical-align: baseline;
}
.zff-table th:last-child, .zff-table td:last-child { padding-right: 0; }

.zff-table thead th {
  font-size: var(--zff-fs-label);
  font-weight: var(--zff-wght-semi);
  letter-spacing: var(--zff-ls-label);
  text-transform: uppercase;
  color: var(--zff-c-muted);
  border-bottom: 1px solid var(--zff-c-rule-strong);
  white-space: nowrap;
}

.zff-table tbody th {
  font-weight: var(--zff-wght-semi);
  color: var(--zff-c-heading);
  /* Řádkový nadpis se nezalamuje — „S&P 500" na dvou řádcích rozhodí
     zarovnání celého řádku. Tabulka se místo toho posouvá vodorovně. */
  white-space: nowrap;
}

/* Číselné sloupce. Doprava, ať desetinné čárky sedí pod sebou. */
.zff-table .zff-n {
  text-align: right;
  font-weight: var(--zff-wght-num);
  letter-spacing: var(--zff-ls-num);
  white-space: nowrap;
}
.zff-table thead .zff-n { font-weight: var(--zff-wght-semi); }

/* Zvýrazněný řádek — portfolio nebo koš proti benchmarkům. Zlatá linka
   vlevo, ne podbarvení: podbarvení by rozhodilo poměr ploch. */
.zff-table tbody tr.zff-row-hl th,
.zff-table tbody tr.zff-row-hl td {
  border-bottom-color: var(--zff-c-rule-strong);
  font-weight: var(--zff-wght-num);
}
.zff-table tbody tr.zff-row-hl th:first-child {
  box-shadow: inset 3px 0 0 var(--zff-gold);   /* obrys, ne rozostřený stín */
  padding-left: var(--zff-s2);
}

.zff-table tfoot td {
  border-bottom: 0;
  font-size: var(--zff-fs-small);
  color: var(--zff-c-muted);
  padding-top: var(--zff-s2);
}

/* --- statistika ----------------------------------------------------------- */

.zff-stat { display: flex; flex-direction: column; gap: var(--zff-s1); }
.zff-stat__label {
  font-size: var(--zff-fs-label);
  font-weight: var(--zff-wght-semi);
  letter-spacing: var(--zff-ls-label);
  text-transform: uppercase;
  color: var(--zff-c-muted);
}
/* Poznámka pod číslem nese měřenou hodnotu („efektivně 13,5 % p. a."),
   takže to není dekorace a platí pro ni AA. Faint je 48 % inkoustu =
   3,14 : 1; muted dá 5,18 : 1. */
.zff-stat__note { font-size: var(--zff-fs-small); color: var(--zff-c-muted); }

/* --- zlatý blok ----------------------------------------------------------
   Tři čísla v heru. Zlatá jako plocha, text inkoustem (8,20 : 1).
   Přepisuje tokeny, protože je to plocha jako každá jiná. */
.zff-goldblock {
  --zff-c-text:   var(--zff-ink);
  --zff-c-num:    var(--zff-ink);
  /* 70 % inkoustu na zlaté je 4,45 : 1 — o vlásek pod AA. 80 % dá
     5,63 : 1 a hierarchii proti číslu si drží dál. */
  --zff-c-label:  rgba(20, 21, 63, .80);
  --zff-c-muted:  rgba(20, 21, 63, .80);
  --zff-c-faint:  rgba(20, 21, 63, .72);
  --zff-c-heading: var(--zff-ink);
  --zff-c-link:   var(--zff-ink);
  --zff-focus-ring: var(--zff-ink);
  background: var(--zff-gold);
  color: var(--zff-c-text);
  padding: var(--zff-s5);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--zff-s4);
}

/* --- datový pás ----------------------------------------------------------- */

.zff-databar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--zff-s2) var(--zff-s3);
  align-items: baseline;
  font-size: var(--zff-fs-small);
  padding-block: var(--zff-s2);
  border-top: 1px solid var(--zff-c-rule);
  border-bottom: 1px solid var(--zff-c-rule);
  font-variant-numeric: tabular-nums;
}
.zff-databar > * { display: inline-flex; gap: .4em; align-items: baseline; }
.zff-databar b { font-weight: var(--zff-wght-num); letter-spacing: var(--zff-ls-num); }

/* --- tlačítka ------------------------------------------------------------
   Pilulka je jediné místo, kde je zaoblení povolené (spolu se štítky). */

.zff-btn {
  font: inherit;
  font-weight: var(--zff-wght-semi);
  font-size: var(--zff-fs-body);
  letter-spacing: -.01em;
  padding: var(--zff-s2) var(--zff-s4);
  min-height: var(--zff-touch);
  border-radius: 999px;
  border: 2px solid transparent;
  cursor: pointer;
  text-decoration: none;
  background: var(--zff-c-cta-bg);
  color: var(--zff-c-cta-fg);
  transition: opacity var(--zff-motion) var(--zff-ease);
  justify-content: center;   /* výjimka: text v tlačítku, ne v sazbě */
}
.zff-btn:hover { opacity: .88; }

/* Na tmavé ploše je CTA slunečné s modrým textem (8,30 : 1), na světlé
   modré s krémovým (10,17 : 1). Rozhoduje token --zff-c-cta-*, který si
   nastavuje plocha — ne potomkový selektor, aby to fungovalo i vnořené. */
.zff-btn--primary {
  background: var(--zff-c-cta-bg);
  color: var(--zff-c-cta-fg);
}

.zff-btn--ghost {
  background: transparent;
  color: var(--zff-c-link);
  border-color: var(--zff-c-rule-strong);
}

/* --- štítek --------------------------------------------------------------- */

.zff-tag {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  border-radius: 999px;
  border: 1px solid var(--zff-gold);
  padding: 4px 12px;
  font-size: var(--zff-fs-label);
  font-weight: var(--zff-wght-semi);
  letter-spacing: var(--zff-ls-label);
  text-transform: uppercase;
  color: var(--zff-c-label);
  min-height: 0;
}

/* --- karta --------------------------------------------------------------- */

.zff-card {
  border: 1px solid var(--zff-c-rule);
  padding: var(--zff-s4);
  display: flex;
  flex-direction: column;
  gap: var(--zff-s2);
}
/* Karta na vlastní ploše si barvu pozadí nastaví sama přes .zff-on-*;
   bez toho je průhledná a dědí plochu, na které stojí. */

/* Poznámkový box — např. shortlist dalších osmi fondů. */
.zff-note {
  border-left: 2px solid var(--zff-gold);
  padding: var(--zff-s2) 0 var(--zff-s2) var(--zff-s3);
}
.zff-note p { max-width: var(--zff-measure); }

/* --- rozbalovací obsah ---------------------------------------------------
   Kostra, část 2: vysvětlivka (i) nesmí být <span> s odstavci uvnitř <p> —
   parser ho vysune a tooltip zůstane trvale vidět. Proto <details>. */

.zff-details {
  border-top: 1px solid var(--zff-c-rule);
  border-bottom: 1px solid var(--zff-c-rule);
}
.zff-details > summary {
  display: flex;
  align-items: center;
  gap: var(--zff-s2);
  cursor: pointer;
  padding-block: var(--zff-s2);
  min-height: var(--zff-touch);
  font-weight: var(--zff-wght-semi);
  font-size: var(--zff-fs-body);
  list-style: none;
}
.zff-details > summary::-webkit-details-marker { display: none; }
.zff-details > summary::after {
  content: "+";
  margin-left: auto;
  font-weight: var(--zff-wght-num);
  color: var(--zff-c-label);
}
.zff-details[open] > summary::after { content: "–"; }
.zff-details__body { padding-bottom: var(--zff-s3); }

/* --- graf ---------------------------------------------------------------- */

.zff-figure { margin: 0; display: flex; flex-direction: column; gap: var(--zff-s2); }
.zff-figure svg { width: 100%; height: auto; }
.zff-figure figcaption { font-size: var(--zff-fs-small); color: var(--zff-c-muted); }

/* Legenda vlevo, ne pod grafem (kostra, oddíl 05, bod 3). */
.zff-legend {
  display: flex;
  flex-direction: column;
  gap: var(--zff-s1);
  font-size: var(--zff-fs-small);
  list-style: none;
  padding: 0;
  margin: 0;
  /* Legenda není sazba, ale ovládací prvek grafu — míra řádku 68ch pro ni
     neplatí. Na vodorovné legendě ji 68ch (≈ 590 px při 14 px) zalomilo
     do tří řádků, i když měla k dispozici celou šířku pásu. */
  max-width: none;
}
.zff-legend li { display: flex; align-items: center; gap: var(--zff-s1); max-width: none; }
.zff-legend .zff-swatch { width: 14px; height: 3px; flex: none; }

/* Rozptylový graf kreslí tečky, ne úsečky — legenda to má říkat taky.
   Obrys je stejný jako u zvýrazněných teček v grafu: světlé výplně samy
   nemají na papíře dost kontrastu. */
.zff-legend--tecky .zff-swatch {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px var(--zff-ink);
}

/* Legenda na jednom řádku — pro graf, který potřebuje celou šířku sazby. */
.zff-legend--radek {
  flex-direction: row;
  flex-wrap: wrap;
  /* Bez align-items sedí položky po zalomení každá jinde: pružný
     kontejner je ve výchozím stavu roztahuje a účaří se rozejde. */
  align-items: baseline;
  gap: var(--zff-s1) var(--zff-s3);
}

/* --- formulářové prvky --------------------------------------------------- */

input[type="text"], input[type="email"], input[type="tel"],
input[type="number"], select, textarea {
  font: inherit;
  color: var(--zff-c-text);
  background: var(--zff-paper);
  border: 1px solid var(--zff-c-rule-strong);
  border-radius: 0;              /* zaoblení jen u pilulek a štítků */
  padding: var(--zff-s1) var(--zff-s2);
  min-height: var(--zff-touch);
  font-variant-numeric: tabular-nums;
}

/* --- hlavička a patička --------------------------------------------------- */

.zff-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--zff-s3);
  padding-block: var(--zff-s3);
  /* Žádná sticky lišta — u této cílovky škodí (zadání, část 10). */
}
.zff-header__logo { display: block; }
.zff-header__logo img, .zff-header__logo svg { height: 26px; width: auto; }

.zff-footer { padding-block: var(--zff-s6); font-size: var(--zff-fs-small); }
.zff-footer__logo img { height: 34px; width: auto; }

/* --- ochranná zóna loga -------------------------------------------------
   ½ výšky verzálek na všech stranách (manuál, oddíl 07). U slovního loga
   je V = 71,4 % velikosti fontu; u obrázku ji držíme paddingem. */
.zff-logo-zone { padding: .36em; }   /* ≈ ½ V pro logo vysoké 26 px */

/* === 06-charts.css === */
/* ==========================================================================
   06 · Grafy a vstupní prohlášení
   Grafy jsou SVG generované při buildu — bez JS, bez donačítání.
   ========================================================================== */

.zff-chart {
  display: block;
  width: 100%;
  height: auto;
  /* Ne `overflow: visible`: text u hran grafu by se kreslil za viewBox
     a roztahoval scrollWidth celé stránky (vodorovné přetečení o pár
     pixelů, které se v layoutu projeví, ale nikdo ho nevidí). Popisky
     u krajů jsou proto zarovnané dovnitř už v generátoru. */
  overflow: hidden;
}

/* Popisky os. tabular-nums, aby čísla na ose seděla pod sebou.

   Velikost je v uživatelských jednotkách SVG, takže se zmenšuje spolu
   s grafem. Na šířce 720 px odpovídá 12 px na obrazovce; na mobilu, kde
   je graf zmenšený na ~335 px, by z toho bylo 5,6 px a popisky by byly
   nečitelné. Proto se na úzkých displejích zvětšují — poměr zmenšení
   tím vyrovnáváme. */
.zff-chart__label,
.zff-chart__value {
  font-family: var(--zff-font);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
}

@media (max-width: 900px) {
  .zff-chart__label { font-size: 17px; }
  .zff-chart__value { font-size: 18px; }
}
@media (max-width: 620px) {
  .zff-chart__label { font-size: 23px; }
  .zff-chart__value { font-size: 25px; }
}
.zff-chart__label { font-weight: var(--zff-wght-medium); }
.zff-chart__value {
  font-weight: var(--zff-wght-num);
  letter-spacing: var(--zff-ls-num);
  font-size: 13px;
}

/* Graf s legendou vlevo — kostra, oddíl 05, bod 3: legenda vlevo,
   ne pod grafem. */
.zff-chartrow {
  display: grid;
  grid-template-columns: 168px minmax(0, 1fr);
  gap: var(--zff-s4);
  align-items: start;
}
.zff-chartrow > * { min-width: 0; }
@media (max-width: 760px) {
  .zff-chartrow { grid-template-columns: 1fr; gap: var(--zff-s2); }
}

/* --- pruh nad grafem: legenda vlevo, přepínač osy vpravo ----------------
   Předtím stály obě věci pod sebou v 168px sloupci vedle grafu. Legenda se
   tím lámala do tří řádků, fieldset s přepínačem vypadal jako další vstup
   kalkulačky a na graf zbyla dvě třetiny šířky. */
.zff-chartbar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--zff-s2) var(--zff-s4);
  margin-top: var(--zff-s4);
  padding-bottom: var(--zff-s2);
  border-bottom: 1px solid var(--zff-c-rule);
}
.zff-chartbar > * { margin: 0; }

/* Tři popisky legendy zaberou 552 px, přepínač osy 380 — na 844 px sazby
   se vedle sebe nevejdou nikdy. Místo aby se to lámalo náhodně, dostane
   legenda celý první řádek a přepínač druhý, zarovnaný vpravo. */
.zff-chartbar > .zff-legend--radek { flex: 1 1 100%; }
.zff-chartbar > .zff-osa { margin-left: auto; }

/* Odkaz na metodiku pod každým grafem (kostra, oddíl 04). */
.zff-source {
  font-size: var(--zff-fs-small);
  color: var(--zff-c-muted);
  display: flex;
  flex-wrap: wrap;
  gap: var(--zff-s1) var(--zff-s2);
  align-items: baseline;
}
.zff-source > * { margin: 0; }

/* Odhad se označuje u čísla, ne v patičce (kostra, oddíl 04). */
.zff-estimate {
  font-size: var(--zff-fs-small);
  color: var(--zff-c-muted);
  font-weight: var(--zff-wght-body);
  letter-spacing: 0;
}

/* --- vstupní prohlášení --------------------------------------------------
   Ohraničení je jen formální: klik → sessionStorage → stránka fondu.
   Bez JS zůstane viditelná varianta s přímým odkazem, aby se nikdo
   nezasekl (zadání, část 9). */

/* Rytmus uvnitř bloku. Bez toho se nadpis lepí na odstavec — mezery
   z .zff-editorial__body platí jen pro jeho přímé potomky a tady je
   přímým potomkem celý .zff-gate. */
.zff-gate { max-width: 62ch; }
.zff-gate > * + * { margin-top: var(--zff-s3); }
.zff-gate__no > * + * { margin-top: var(--zff-s2); }

.zff-gate__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--zff-s2);
  margin-top: var(--zff-s4);
}

/* Odpověď „ne" — zdvořilé vysvětlení, ne varování. Skrytá do kliknutí. */
.zff-gate__no {
  margin-top: var(--zff-s4);
  padding-top: var(--zff-s3);
  border-top: 1px solid var(--zff-c-rule);
}
.zff-gate__no[hidden] { display: none; }

/* Bez JS by tlačítka neměla co dělat, proto se ve výchozím stavu skrývají
   a je vidět prostý odkaz. Skript přidá na <html> třídu zff-hasjs a role
   se vymění. Obsah webu je čitelný v obou případech. */
.zff-gate__actions { display: none; }
.zff-hasjs .zff-gate__actions { display: flex; }
.zff-hasjs .zff-nojs { display: none; }

/* === 07-kalkulacka.css === */
/* ==========================================================================
   07 · Kalkulačka oddílu 06
   Posuvníky, číselníky, výsledky. Bez JS zůstane vidět statická tabulka.
   ========================================================================== */

.zff-kalk {
  border: 1px solid var(--zff-c-rule);
  padding: var(--zff-s4);
  display: flex;
  flex-direction: column;
  gap: var(--zff-s4);
}

/* Než se skript rozběhne, jsou výsledky prázdné — schováme je, aby
   nebliknuly nuly. Bez JS atribut nikdo neodstraní, proto se místo nich
   ukáže poznámka .zff-nojs. */
.zff-kalk[data-zff-kalkulacka-cekam] .zff-results,
.zff-kalk[data-zff-kalkulacka-cekam] .zff-diff,
.zff-kalk[data-zff-kalkulacka-cekam] .zff-controls,
.zff-kalk[data-zff-kalkulacka-cekam] .zff-chartrow,
.zff-kalk[data-zff-kalkulacka-cekam] > .zff-details { display: none; }

.zff-hasjs .zff-kalk .zff-nojs { display: none; }

/* --- vstupy --------------------------------------------------------------- */

.zff-controls {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--zff-s4);
}

.zff-field {
  display: flex;
  flex-direction: column;
  gap: var(--zff-s1);
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}
/* Uvnitř .zff-controls je pole mřížka se čtyřmi slotovými řádky (viz
   08-form.css). Mezery mezi slotami dělá row-gap, ne flexový gap. */
.zff-controls > .zff-field { row-gap: var(--zff-s1); }

.zff-field--inline { flex-direction: row; flex-wrap: wrap; align-items: center; }

.zff-field__label {
  font-size: var(--zff-fs-label);
  font-weight: var(--zff-wght-semi);
  letter-spacing: var(--zff-ls-label);
  text-transform: uppercase;
  color: var(--zff-c-muted);
  display: block;
  padding: 0;
}

.zff-field__value {
  font-size: var(--zff-fs-body);
  font-weight: var(--zff-wght-num);
  letter-spacing: var(--zff-ls-num);
  font-variant-numeric: tabular-nums;
  text-transform: none;
  color: var(--zff-c-num);
}

.zff-field__row { display: flex; align-items: center; gap: var(--zff-s1); }
/* Číselník nepotřebuje celou šířku sloupce — nejdelší hodnota je
   „100 000 000", tedy jedenáct znaků. Na plnou šířku se na něj zprava
   lepil obsah dalšího sloupce. */
.zff-field__row input { flex: 0 1 auto; width: 100%; max-width: 14ch; min-width: 0; }
/* Slot bez obsahu (přepínače nemají číselnou hodnotu) nesmí zabírat výšku
   sám za sebe — řádek subgridu si ji vezme z ostatních sloupců. */
.zff-field__row:empty, .zff-field__note:empty { display: block; min-height: 0; }
.zff-field__control { display: block; }
.zff-field__note { display: block; font-size: var(--zff-fs-small); }

/* Přepínače pod sebou, aby dlouhý „Přes zprostředkovatele" nezalomil pás. */
.zff-choices { display: flex; flex-direction: column; gap: var(--zff-s1); }

/* Volba kanálu nemá číselnou hodnotu, takže jí slot 2 zůstával prázdný
   a obě volby začínaly až na řádku posuvníku. Ovládání proto sahá přes
   slot hodnoty i ovládání: první volba padne na řádek hodnoty, druhá
   přesně na linii posuvníků vedle. */
@supports (grid-template-rows: subgrid) {
  /* grid-column: 1 je nutné. Dvě položky ve stejném řádku by si jinak
     automatické umísťování rozhodilo do dvou sloupců a volby by odskočily
     o šířku prázdného slotu doprava. */
  .zff-controls > .zff-field--volba > .zff-field__row { grid-row: 2; grid-column: 1; }
  .zff-controls > .zff-field--volba > .zff-field__note { grid-row: 4; grid-column: 1; }
  /* Volby jsou samy položkami subgridu, každá ve svém řádku. Dorovnávat
     to výškami a mezerami nešlo: řádek hodnoty je 35 px, ale volba má
     kvůli cílové ploše 47 px, takže druhá vždycky o pár pixelů odskočila.
     Takhle padne první na řádek hodnoty a druhá přesně na linii
     posuvníků vedle, ať mají řádky jakoukoli výšku. */
  .zff-controls > .zff-field--volba > .zff-field__control {
    grid-row: 2 / 4;
    grid-column: 1;
    display: grid;
    grid-template-rows: subgrid;
    /* Vlastní `gap` tu být nesmí: u subgridu přepíše mezeru zděděnou
       z nadřazené mřížky a řádky se pak rozejdou o polovinu té mezery. */
  }
}
.zff-field__unit {
  font-size: var(--zff-fs-small);
  color: var(--zff-c-muted);
  flex: none;
}

/* Vysvětlivka pod posuvníkem je obsah, ne dekorace — platí AA.
   Faint (48 % inkoustu) dává na papíře 3,14 : 1, muted 5,18 : 1. */
.zff-field small { color: var(--zff-c-muted); }

/* --- posuvník ------------------------------------------------------------
   Vlastní vzhled, ale bez stínů a bez gradientů. Úchop je 24 px, což je
   pod 44 px — u posuvníku to WCAG 2.5.8 výslovně připouští, protože
   ovládat se dá i z klávesnice a kliknutím do celé dráhy. */

input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  /* display: block, jinak posuvník stojí na účaří řádkového boxu a blok
     mu pod ním nechá 4 px na dolní dotah. Sousední sloupec s přepínači
     pak nesedí v jedné linii, i když mřížka je zarovnaná správně. */
  display: block;
  width: 100%;
  min-width: 0;
  height: var(--zff-touch);
  background: transparent;
  cursor: pointer;
  margin: 0;
}

input[type="range"]::-webkit-slider-runnable-track {
  height: 4px;
  background: var(--zff-c-rule-strong);
}
input[type="range"]::-moz-range-track {
  height: 4px;
  background: var(--zff-c-rule-strong);
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 24px;
  height: 24px;
  border-radius: 999px;      /* pilulkový úchop — povolené zaoblení */
  background: var(--zff-blue);
  border: 2px solid var(--zff-paper);
  margin-top: -10px;
}
input[type="range"]::-moz-range-thumb {
  width: 24px;
  height: 24px;
  border-radius: 999px;
  background: var(--zff-blue);
  border: 2px solid var(--zff-paper);
}

/* --- přepínače ------------------------------------------------------------ */

.zff-choice {
  display: inline-flex;
  align-items: center;
  gap: var(--zff-s1);
  min-height: var(--zff-touch);
  font-size: var(--zff-fs-body);
  cursor: pointer;
  padding-right: var(--zff-s3);
}
.zff-choice input { width: 20px; height: 20px; accent-color: var(--zff-blue); }

/* --- výsledky ------------------------------------------------------------- */

.zff-results {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--zff-s4);
  padding-top: var(--zff-s3);
  border-top: 1px solid var(--zff-c-rule);
}

.zff-diff {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--zff-s3);
  padding: var(--zff-s3);
  background: var(--zff-cream);
  /* Krémová plocha uvnitř papírové sekce — přebírá tokeny krémové. */
  --zff-c-num: var(--zff-blue);
  --zff-c-muted: rgba(20, 21, 63, .66);
  --zff-c-faint: rgba(20, 21, 63, .55);
  --zff-gold-text: var(--zff-gold-text-on-cream);
  --zff-focus-ring: var(--zff-ink);
}

/* Čísla se při přepočtu mění jen opacitou, do 200 ms. */
.zff-results .zff-num-xl,
.zff-diff .zff-num-l {
  transition: opacity var(--zff-motion) var(--zff-ease);
}

@media (max-width: 620px) {
  .zff-kalk { padding: var(--zff-s3); }
}

/* Přepínač osy není vstup kalkulačky, ale nastavení zobrazení — proto
   drobný popisek na řádku, ne label nad polem. */
/* Přepínač osy stojí na jedné vodorovné linii a zarovnaný doprava.
   `align-items: baseline` ho vychýlilo: popisek má 22 px, ale volby jsou
   vysoké 47 px kvůli cílové ploše, takže se účaří rozešla. */
.zff-osa {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--zff-s1) var(--zff-s2);
  border: 0;
  padding: 0;
  margin: 0;
}
.zff-osa__label {
  padding: 0;
  font-size: var(--zff-fs-small);
  color: var(--zff-c-muted);
}
.zff-osa .zff-choice { font-size: var(--zff-fs-small); }

/* Přepínač osy se na mobil vejde na jeden řádek, jen se z něj musí
   vyhodit odsazení, které tam k ničemu není:

     · .zff-choice má vpravo 24 px, aby se volby oddělily, když stojí
       vedle sebe bez mezery — tady je od sebe drží `gap`, takže 2 × 24 px
       jen ubírá místo,
     · přepínač si nese vlastní vodorovné marginy 8 px, i když odstup od
       textu řeší `gap` uvnitř volby.

   Dohromady je to 64 px, tedy víc než celý popisek. Po jejich odebrání
   zabere celá trojice 295 px z 301 dostupných. */
.zff-osa .zff-choice { padding-right: 0; }
.zff-osa .zff-choice input { margin-inline: 0; }

@media (max-width: 520px) {
  .zff-osa {
    justify-content: flex-start;
    gap: var(--zff-s1);
  }
  .zff-osa__label { font-size: var(--zff-fs-label); }
}

/* Graf dostane celou šířku sazby. Na 720 px viewBoxu to znamená plnou
   výšku 360 px místo 240 px, které vycházely z 1fr vedle legendy. */
.zff-kalk__graf { margin-top: var(--zff-s2); }
.zff-kalk__graf .zff-chart { width: 100%; }

/* === 08-form.css === */
/* ==========================================================================
   08 · Formulář, karty metrik, kontakt
   ========================================================================== */

/* --- metriky na kartě strategie ------------------------------------------
   Definiční seznam, ne tabulka: je to pár hodnot k jedné věci, ne matice. */

.zff-metrics {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px var(--zff-s2);
  margin: 0;
  padding-top: var(--zff-s2);
  border-top: 1px solid var(--zff-c-rule);
  font-size: var(--zff-fs-small);
}
.zff-metrics dt { color: var(--zff-c-muted); }
.zff-metrics dd {
  margin: 0;
  text-align: right;
  font-weight: var(--zff-wght-num);
  letter-spacing: var(--zff-ls-num);
  font-variant-numeric: tabular-nums;
  color: var(--zff-c-num);
  font-size: var(--zff-fs-small);
}

/* --- kontakt -------------------------------------------------------------- */

.zff-contact {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: var(--zff-s5);
  align-items: start;
}
@media (max-width: 820px) {
  .zff-contact { grid-template-columns: minmax(0, 1fr); gap: var(--zff-s4); }
}

.zff-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--zff-s3);
}
.zff-form .zff-field--full { grid-column: 1 / -1; }

/* width: 100 % patří textovým polím, NE zaškrtávátkům a přepínačům —
   ty by se roztáhly na celý řádek a na text vedle nich by nezbylo místo
   (souhlas se zpracováním pak vytekl mimo formulář). */
.zff-form input:not([type="checkbox"]):not([type="radio"]),
.zff-form select,
.zff-form textarea {
  width: 100%;
  min-width: 0;
  font: inherit;
  color: var(--zff-ink);
  background: var(--zff-paper);
  border: 1px solid var(--zff-c-rule-strong);
  border-radius: 0;
  padding: var(--zff-s1) var(--zff-s2);
  min-height: var(--zff-touch);
}
.zff-form textarea { min-height: calc(var(--zff-touch) * 2.5); resize: vertical; }

/* Souhlas je delší text vedle zaškrtávátka — nesmí se zalomit pod něj
   tak, aby se ztratil vztah k políčku.

   display: flex (ne inline-flex) a min-width: 0 na textu: jako flex položka
   má <span> min-width: auto, takže by se nezmenšil pod min-content a dlouhý
   text souhlasu by roztáhl celý formulář i stránku. */
.zff-form .zff-choice {
  display: flex;
  align-items: flex-start;
  gap: var(--zff-s2);
  padding-right: 0;
  min-width: 0;
}
.zff-form .zff-choice input {
  width: 20px;
  height: 20px;
  margin-top: 12px;
  flex: none;
}
.zff-form .zff-choice span {
  font-size: var(--zff-fs-small);
  line-height: 1.5;
  /* flex: 1 1 auto společně s min-width: 0 — samotné min-width: 0 nechá
     span spadnout na nulovou šířku a text vyteče vedle. */
  flex: 1 1 auto;
  min-width: 0;
}

/* Honeypot — člověk ho nevidí, robot ho vyplní. Ne display:none, to
   některé roboty poznají; a ne tabbable, aby nepletl klávesnici. */
.zff-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- prohlášení pod formulářem ------------------------------------------- */

.zff-form + .zff-card { min-width: 0; }

/* --- pás logotypů --------------------------------------------------------
   Zvažované subjekty, monochrom v inkoustu, sjednocená OPTICKÁ výška.
   Zarovnání na střed pásu, ne na účaří: logotypy mají různé přesahy
   a účaří by je rozhodilo. */

.zff-logoband {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--zff-s5) var(--zff-s6);
  padding-block: var(--zff-s4);
}

.zff-logocell {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--zff-s1);
  min-width: 0;
}
.zff-logocell svg { display: block; }
.zff-logocell__name {
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--zff-c-faint);
}

/* Mřížka 3 × 2 pro pás v oddílu 07 (manuál: nad každou skupinou label
   ve zlaté). */
.zff-logogrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--zff-s4) var(--zff-s5);
  align-items: center;
}
.zff-logogrid svg { display: block; height: 34px; width: auto; max-width: 100%; }

/* --- portréty a karty osob -----------------------------------------------
   Zadání: 4 : 5, srcset 400/800/1200, AVIF + WebP + JPEG. */

.zff-portret {
  display: block;
  aspect-ratio: 4 / 5;
  width: 100%;
  overflow: hidden;
  background: var(--zff-c-rule);
}
.zff-portret img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Kdo fotku nemá, dostane plochu s monogramem. Prázdné místo v mřížce
   by vypadalo jako chybějící obrázek, ne jako záměr. */
.zff-portret--bez {
  display: grid;
  place-items: center;
  background: var(--zff-cream);
}
.zff-portret--bez span {
  font-size: clamp(32px, 4vw, 48px);
  font-weight: var(--zff-wght-display);
  letter-spacing: var(--zff-ls-display);
  /* 28 % inkoustu na krémové je 1,80 : 1. Monogram je sice
     aria-hidden, ale 55 % dá 3,63 : 1 a hlavně je to vidět. */
  color: rgba(20, 21, 63, .55);
}

.zff-card--osoba { padding: 0; overflow: hidden; }
.zff-card--osoba > :not(.zff-portret) {
  padding-inline: var(--zff-s3);
}
.zff-card--osoba > .zff-label { padding-top: var(--zff-s3); }
.zff-card--osoba > p:last-child { padding-bottom: var(--zff-s3); }

/* Logotyp v kartě „Co za námi stojí". Vlastní produkty a veřejnoprávní
   médium zůstávají ve svých barvách — monochrom platí pro zvažované
   subjekty, ne pro doklad vlastní práce. */
.zff-stopa__logo {
  display: flex;
  align-items: center;
  min-height: 56px;
}
.zff-stopa__logo img {
  max-height: 44px;
  max-width: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* --- zarovnání sloupců ---------------------------------------------------
   Když má popisek v jednom sloupci jeden řádek a ve druhém dva, posune se
   zbytek sloupce a velká čísla i posuvníky spolu nesedí.

   Řeší to subgrid: každá dlaždice sdílí řádky s pásem, ve kterém stojí,
   takže popisek, hodnota, ovládání a poznámka leží ve všech sloupcích
   v jedné linii — bez ohledu na to, kolik řádků text zabere.

   `min-height` na popisek by to jen zamaskoval do dvou řádků; „Poměr
   výnosu k maximálnímu propadu" se láme na tři a skákání by se vrátilo. */

.zff-statrow .zff-stat,
.zff-results .zff-stat,
.zff-diff .zff-stat,
.zff-controls .zff-field {
  display: grid;
  align-content: start;
}

@supports (grid-template-rows: subgrid) {
  /* popisek · hodnota · poznámka */
  .zff-statrow, .zff-results, .zff-diff { grid-template-rows: repeat(3, auto); }
  .zff-statrow > .zff-stat,
  .zff-results > .zff-stat,
  .zff-diff > .zff-stat {
    grid-row: span 3;
    grid-template-rows: subgrid;
  }

  /* popisek · hodnota · ovládání · poznámka */
  .zff-controls { grid-template-rows: repeat(4, auto); }
  .zff-controls > .zff-field {
    grid-row: span 4;
    grid-template-rows: subgrid;
  }
  /* Posuvník i skupina přepínačů začínají v horní hraně svého řádku.
     Řádek je vysoký podle nejvyšší dlaždice v pásu (přepínače jsou
     vyšší než posuvník), bez tohoto by se posuvník vycentroval. */
  .zff-controls > .zff-field > * { align-self: start; }
}

/* Bez subgridu (staré prohlížeče) zůstane aspoň jeden řádek popisku
   navíc — sloupce nesedí na pixel, ale nerozjedou se o celý řádek. */
@supports not (grid-template-rows: subgrid) {
  .zff-statrow .zff-stat__label,
  .zff-results .zff-stat__label,
  .zff-diff .zff-stat__label,
  .zff-controls .zff-field__label { min-height: calc(2 * 1.3em); }
}
