/**
 * Base styles — reset + typography + globální chování.
 * Načítá tokens.css.
 */
@import url("tokens.f0cf381de02f.css");

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

/* CZ: SKRYTÍ PŘES `hidden` MUSÍ PŘEBÍT LAYOUT (9. 9. 2026).
       Prohlížeč má ve výchozím stylu `[hidden] { display: none }`, jenže to je pravidlo
       s nulovou specificitou — jakákoli třída, která nastaví `display`, ho porazí. Prvek pak
       má `hidden=true`, ale je VIDĚT.

       Nebyla to teorie: `.widget-error { display: flex }` takhle svítil chybový pruh
       „Kartu se teď nepodařilo načíst" na KAŽDÉ kartě dashboardu, přestože si žádná
       nestěžovala. Komentář u té třídy se přitom odvolával na „globální reset v hlavičce
       stránky", který nikdy neexistoval. `sales_board.css` si na totéž musel udělat vlastní
       výjimku (`.modal-overlay[hidden]`) — což je přesně ta záplata, kterou tenhle řádek
       nahrazuje.

       `!important` je tu na místě: `hidden` není styl, ale stav. Kdo ho nastaví, myslí tím
       „pryč", ne „pryč, pokud se nenajde silnější selektor".
   EN: `hidden` MUST BEAT LAYOUT (9 Sep 2026).
       Browsers ship `[hidden] { display: none }` in the UA stylesheet, but that rule has zero
       specificity — any class setting `display` defeats it. The element then carries
       `hidden=true` and is still VISIBLE.

       Not theoretical: `.widget-error { display: flex }` kept the "this card failed to load"
       strip lit on EVERY dashboard card although none had failed. The comment on that class
       even claimed a "global reset in the page head" that never existed. `sales_board.css` had
       to write its own workaround (`.modal-overlay[hidden]`) for the same reason — exactly the
       patch this line replaces.

       `!important` belongs here: `hidden` is a state, not a style. Setting it means "gone", not
       "gone unless a stronger selector turns up". */
[hidden] { display: none !important; }

/* CZ: Základ stránky podle vzoru (F2, 6. 9. 2026): tělo 17 px / leading 1.6, plocha je BÍLÁ,
       ne šedá. Vzor staví bílou stránku a šedou používá jen na zapuštěné panely — dřív to
       bylo naopak (`--gray-pale`), takže by karty na šedé ztratily obrys jako
       hranici a splynuly.
   EN: The page base per the sample (F2, 6 Sep 2026): body 17 px / 1.6 leading, and the page is
       WHITE, not grey. The sample builds a white page and uses grey only for inset panels — it
       used to be the other way round (`--gray-pale`), which would make the cards'
       outline stop reading as a boundary against the grey. */
html, body {
  margin: 0;
  padding: 0;
  font-family: var(--font-core);
  font-size: var(--body-size);
  font-weight: var(--weight-body);
  line-height: var(--body-leading);
  color: var(--text-primary);
  background-color: var(--surface-page);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "cv11", "ss01";
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-core);
  margin: 0;
  color: var(--text-primary);
  /* CZ: Dlouhý nelomitelný název/URL v nadpisu se musí zalomit, ne přetéct viewport na mobilu.
     EN: A long unbreakable title/URL in a heading must wrap, not overflow the viewport on mobile. */
  overflow-wrap: break-word;
}

/* CZ: Typografická stupnice vzoru. `clamp()` propojuje dvojici `size-min` / `size` — vzor sám
       udává obě čísla („H1 44–54 px"), jen je neuměl přepnout, protože nemá jedinou media
       query. Tady se to řeší bez breakpointu: velikost plyne se šířkou okna.
       Nadpisy mají VLASTNÍ váhy a tracking (H1 800/−1.5, H2 600/−0.5, H3 500/−0.25) — vzor je
       odstupňoval schválně, jedna společná váha by hierarchii setřela.
   EN: The sample's type scale. `clamp()` ties each `size-min` / `size` pair together — the sample
       states both numbers ("H1 44–54 px") but could not switch between them, having not a single
       media query. Here it needs no breakpoint: the size follows the viewport width.
       The headings carry their OWN weights and tracking (H1 800/−1.5, H2 600/−0.5, H3 500/−0.25)
       — the sample graded them deliberately; one shared weight would flatten the hierarchy. */
h1 {
  font-size: clamp(var(--h1-size-min), 4.5vw, var(--h1-size));
  font-weight: var(--h1-weight);
  letter-spacing: var(--h1-tracking);
  line-height: var(--h1-leading);
}
h2 {
  font-size: clamp(var(--h2-size-min), 3vw, var(--h2-size));
  font-weight: var(--h2-weight);
  letter-spacing: var(--h2-tracking);
  line-height: var(--h2-leading);
}
h3 {
  font-size: clamp(var(--h3-size-min), 2vw, var(--h3-size));
  font-weight: var(--h3-weight);
  letter-spacing: var(--h3-tracking);
  line-height: var(--h3-leading);
}
h4 { font-size: var(--text-xl); font-weight: var(--weight-subhead); line-height: var(--leading-snug); }
h5, h6 { font-weight: var(--weight-subhead); line-height: var(--leading-snug); }

/* =====================================================================================
 * CZ: APLIKAČNÍ ŠKÁLA (R2) — přebíjí značkovou uvnitř `.app`.
 *
 *     Pravidla NAD tímhle blokem jsou věrný přepis značkového listu vzoru a platí pro
 *     marketingový web: h1 44-54px, h2 30-36px, body 17px. Obrazovky téhož vzoru ale mají
 *     h1 32px, h2 20px a běžný text 14px — vzor si odporuje sám se sebou a brand manuál
 *     v §4 neuvádí jediné číslo v px (jeho TO-DO zní „potvrdit přesnou px type scale").
 *
 *     Majitel rozhodl (R2): **pro přihlášenou aplikaci platí škála obrazovek.** Značková
 *     zůstává beze změny pro web, e-maily a PDF exporty, které `.app` nemají.
 *
 *     ⚠️ Bez tohohle bloku by `tokens-app.css` byl jen další slovník bez konzumenta — přesně
 *        ta chyba, kvůli které se aplikace se vzorem rozcházela: hodnoty byly zapsané
 *        a nikdy se neuplatnily.
 * EN: THE APPLICATION SCALE (R2) — overrides the brand one inside `.app`.
 *
 *     The rules above are a faithful transcription of the sample's brand sheet and govern the
 *     marketing site: h1 44-54px, h2 30-36px, body 17px. But that same sample's screens use
 *     h1 32px, h2 20px and 14px body text — the sample contradicts itself, and the brand manual
 *     gives no pixel value at all in §4 (its own TO-DO reads "confirm the exact px type scale").
 *
 *     Owner's decision (R2): the logged-in application follows the screens. The brand scale is
 *     untouched for the web, e-mails and PDF exports, which carry no `.app`.
 *
 *     ⚠️ Without this block `tokens-app.css` would be one more dictionary with no consumer —
 *        exactly the failure that let the app drift from the sample: values written down and
 *        never applied.
 * ===================================================================================== */
body.app {
  font-size: var(--app-body-size);
  font-weight: var(--app-body-weight);
  line-height: var(--app-body-leading);
}
/* CZ: Nadpis stránky nese `page-header`; holý `<h1>` má stejnou velikost, aby se plocha
       nerozešla podle toho, do čeho ho kdo zabalil. Přesně tak vznikl rozchod: `.page-header h1`
       dával 30px, holý `<h1>` 44-54px, a záleželo na šabloně.
   EN: The page title is carried by `page-header`; a bare `<h1>` gets the same size so a screen
       cannot diverge based on what someone wrapped it in. That is precisely how the divergence
       arose: `.page-header h1` gave 30px, a bare `<h1>` 44-54px, depending on the template. */
.app h1 {
  font-size: var(--app-h1-size);
  font-weight: var(--app-h1-weight);
  letter-spacing: var(--app-h1-tracking);
  line-height: var(--app-h1-leading);
}
.app h2 {
  font-size: var(--app-h2-size);
  font-weight: var(--app-h2-weight);
  letter-spacing: var(--app-h2-tracking);
  line-height: var(--app-h2-leading);
}
.app h3 {
  font-size: var(--app-h3-size);
  font-weight: var(--app-h3-weight);
  letter-spacing: var(--tracking-normal);
  line-height: var(--app-h3-leading);
}
.app h4 { font-size: var(--app-body-size); font-weight: var(--weight-subhead); }

p { margin: 0; overflow-wrap: break-word; }

/* CZ: Média se nikdy nesmí roztáhnout přes svůj kontejner (typicky obrázky vložené do těla
       článků/videí přes Wagtail StreamField, které nemají vlastní inline width). height:auto
       drží poměr stran; inline height (např. logo) tuto hodnotu přebije, takže loga zůstanou.
   EN: Media must never exceed its container (typically images embedded in article/video bodies
       via Wagtail StreamField with no inline width). height:auto preserves aspect ratio; an
       inline height (e.g. the logo) overrides it, so fixed-size logos stay intact. */
img, video, iframe { max-width: 100%; }
img { height: auto; }

/* CZ: Dlouhé řetězce v buňkách/položkách seznamů také lámat (názvy, e-maily, URL).
   EN: Break long strings in table cells / list items too (titles, emails, URLs). */
td, th, li, dd, dt { overflow-wrap: break-word; }

a {
  /* CZ: Odkaz je MODRÝ — ve vzoru `a{color:#0092FF}`. Sytý odstín ale na bílé dává jen 3.20:1,
         takže se bere `-text` krok rampy (`--text-link` = #005E9E, 6.79:1). Barva je táž rodina,
         jen v odstínu, který smí nést text.
     EN: A link is BLUE — the sample has `a{color:#0092FF}`. That saturated shade gives only
         3.20:1 on white, so the ramp's `-text` step is used (`--text-link` = #005E9E, 6.79:1).
         Same family, in the shade that may carry text. */
  color: var(--text-link);
  text-decoration: none;
  transition: color var(--transition-normal);
}
a:hover { color: var(--action-primary-hover); text-decoration: underline; text-underline-offset: 4px; }

button { font-family: inherit; cursor: pointer; }

input, select, textarea { font-family: inherit; font-size: inherit; }

:focus-visible {
  /* CZ: Průhledný outline vedle box-shadow — ve Windows „forced colors / high contrast"
         se box-shadow zahazuje a outline se naopak zviditelní, takže focus zůstane vidět.
     EN: Transparent outline alongside box-shadow — in Windows forced-colors / high-contrast
         mode box-shadow is dropped while the outline becomes visible, so focus stays visible. */
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-chip);
}

/* CZ: Označený text — modrá plocha s bílým textem. `--white` se tu použít NESMÍ:
       v tmavém režimu se překlápí na tmavou a označený text by na modré zmizel (stejná past
       jako u `.btn-primary`, viz F1).
   EN: Selected text — a blue surface with white text. `--white` must NOT be used
       here: it flips dark in dark mode and the selection would vanish on the blue (the same trap
       as `.btn-primary`, see F1). */
::selection { background-color: var(--action-primary); color: var(--text-on-primary); }

/* CZ: Respektuj systémové omezení pohybu — zkrať animace/přechody (globálně, nejen chat.css).
       Chrání uživatele s vestibulárními potížemi (nekonečné voice-pulse/voice-spin apod.).
   EN: Respect the OS "reduce motion" setting — shorten animations/transitions globally
       (not just chat.css). Protects users with vestibular disorders (infinite voice-pulse etc.). */
@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;
  }
}

/* HTMX indicators */
.htmx-indicator { opacity: 0; transition: opacity var(--transition-normal); }
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator { opacity: 1; }

/* Disable transitions during theme switch (prevents flash) */
.no-transitions, .no-transitions * { transition: none !important; }
