/*
 * Komponenty webadminu. Tokeny su v tokens.css.
 *
 * Podpisovy prvok znacky je asymetricky radius so stvorcovym LAVYM DOLNYM
 * rohom. Drzi sa na kartach, tlacidlach a stitkoch. Na vstupnych polach
 * ZAMERNE nie - v mriezke formulara s dvadsiatimi polami sa asymetria cita
 * ako chyba zarovnania, nie ako styl.
 */

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

/*
 * `[hidden]` musi prebit layoutove `display` z tried.
 *
 * Prehliadac ma v user-agent styloch `[hidden] { display: none }`, ale to je
 * selektor s nizsou specificitou nez `.app { display: grid }` alebo
 * `.login { display: grid }`. Bez tohto pravidla zostava prihlasovaci formular
 * vykresleny POD aplikaciou - `hidden` sa nastavi, ale nic nespravi.
 */
[hidden] {
  display: none !important;
}

html,
body {
  margin: 0;
  height: 100%;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--fs-body);
  font-weight: var(--fw-normal);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  /* Hierarchia je velkostou a farbou, nie tuckou. Marketingovy web nema
     ziadny bold rez a webadmin ho preto tiez nepouziva. */
  font-weight: var(--fw-medium);
  letter-spacing: var(--tracking-tight);
}

h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h4); }

a {
  color: inherit;
  text-decoration: none;
}

code,
pre,
.mono {
  font-family: var(--font-mono);
  font-size: 0.92em;
  font-variant-ligatures: none;
}

.muted { color: var(--muted); }
.small { font-size: var(--fs-small); }
.micro { font-size: var(--fs-micro); }
.right { text-align: right; }
.nowrap { white-space: nowrap; }

.boot {
  display: grid;
  place-items: center;
  height: 100%;
  color: var(--muted);
}

/* ---------------------------------------------------------------------------
   Rozlozenie
   --------------------------------------------------------------------------- */

.app {
  display: grid;
  grid-template-columns: var(--nav-w) 1fr;
  min-height: 100%;
}

.nav {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  padding: var(--sp-4);
  border-right: 1px solid var(--line);
  background: var(--surface);
  /* Panel zostava na obrazovke pri scrollovani dlhej tabulky zariadeni. */
  position: sticky;
  top: 0;
  /* `dvh`, nie `vh`: na mobile `vh` pocita s vysuvacou listou prehliadaca,
     takze spodok panela skonci pod okrajom obrazovky. */
  height: 100dvh;
  /* Menu ma sestnast poloziek a pod nimi este paticku s uctom. Na nizsom okne
     (alebo pri vacsom pisme) sa to do `100dvh` nezmesti a BEZ TOHTO RIADKU sa
     spodok NEDA dosiahnut - prvky su za okrajom a nic sa neposuva. Prejavilo
     sa to tym, ze "na velkej obrazovke je to cele vidiet" a inde nie. */
  overflow-y: auto;
  /* Vodorovne nie - dlhy nazov polozky sa ma skratit, nie vyrobit druhy
     posuvnik vedla zvisleho. */
  overflow-x: hidden;
}

.nav__brand {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-2) 0;
  font-size: var(--fs-h4);
  letter-spacing: var(--tracking-tight);
}

.nav__name strong { font-weight: var(--fw-medium); }

/* Znacka: ten isty asymetricky tvar ako karty, v plnom inku. */
.nav__mark {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  background: var(--ink);
  border-radius: var(--radius-sm);
}

.nav__links {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.nav__links a {
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius-sm);
  color: var(--muted);
  transition: background var(--transition), color var(--transition);
}

.nav__links a:hover {
  background: var(--surface-sunken);
  color: var(--ink);
}

.nav__links a[aria-current='page'] {
  background: var(--ink);
  color: var(--bg);
}

/* Paticka bocneho pruhu: prepinac rezimu a ucet.
   Oddeluje sa od polozek menu JEDNOU linkou hore - nie este raz medzi
   prepinacom a uctom. Dve linky nad sebou v rozostupe 40 px vyzerali ako
   rozsypany spodok, nie ako struktura. */
.nav__foot {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}

/* Ucet je JEDNO tlacidlo cez celu sirku, nie dva prvky vedla seba.
   Povodne tu bol popisok a tlacidlo Odhlasit s `space-between`; po presune
   odhlasenia do menu zostal jediny prvok, ktory sa tym roztiahol na kraje a
   spodok menu vyzeral rozsypane. */
.nav__user {
  position: relative;
}

.nav__who {
  font-size: var(--fs-small);
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.main {
  min-width: 0; /* bez toho rozsiri siroka tabulka cely grid */
  display: flex;
  flex-direction: column;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  height: var(--header-h);
  padding: 0 var(--sp-5);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  position: sticky;
  top: 0;
  z-index: 5;
}

.topbar__title {
  font-size: var(--fs-h3);
}

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

.view {
  padding: var(--sp-5);
  min-width: 0;
}

/* ---------------------------------------------------------------------------
   Karty a mriezky
   --------------------------------------------------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: var(--sp-5);
}

.card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}

/* Nadpis sekcie priamo vo `view` (nie v karte) potrebuje odstup aj zhora,
   inak sa lepi na mriezku dlazdic nad sebou. V karte ho mat nesmie - tam uz
   odstup robi padding karty. */
.view > h2.card__head,
.view > h3.card__head {
  margin-top: var(--sp-6);
}

.view > :is(h2, h3).card__head:first-child {
  margin-top: 0;
}

.grid {
  display: grid;
  gap: var(--sp-4);
}

/* `auto-fill` a nie `auto-fit`: pri jednej karte by `auto-fit` roztiahol
   dlazdicu na celu sirku obrazovky a cislo v nej by plavalo v prazdne. */
.grid--tiles {
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}

.grid--2 { grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); }

/* Dlazdica s jednym cislom. */
.tile {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.tile__value {
  font-size: 30px;
  font-weight: var(--fw-light);
  letter-spacing: var(--tracking-tight);
  line-height: 1.1;
  /* Tabularne cislice: pri obnovovani kazdych par sekund by sa inak cisla
     rozskakali do stran, lebo `1` je v proporcionalnom reze uzsia. */
  font-variant-numeric: tabular-nums;
}

.tile__label {
  font-size: var(--fs-small);
  color: var(--muted);
}

.tile--ok    .tile__value { color: var(--ok); }
.tile--warn  .tile__value { color: var(--warn); }
.tile--bad   .tile__value { color: var(--bad); }
.tile--muted .tile__value { color: var(--muted); }

/* Dlazdica, ktora je odkazom na filtrovany zoznam. */
a.tile {
  transition: border-color var(--transition), box-shadow var(--transition);
}

a.tile:hover {
  border-color: var(--ink);
  box-shadow: var(--shadow-sm);
}

/* ---------------------------------------------------------------------------
   Tlacidla
   --------------------------------------------------------------------------- */

.btn {
  font: inherit;
  font-size: var(--fs-small);
  cursor: pointer;
  border: 0;
  border-radius: var(--radius-sm);
  padding: 10px 18px;
  background: var(--ink);
  color: var(--bg);
  transition: opacity var(--transition), transform var(--transition);
}

.btn:hover { opacity: 0.86; }
.btn:active { transform: translateY(1px); }

.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
}

.btn--ghost:hover {
  border-color: var(--ink);
  opacity: 1;
}

.btn--sm {
  padding: 5px 11px;
  font-size: var(--fs-micro);
}

/* Nebezpecna akcia: reboot, factory_reset, OTA downgrade. Nie plna cervena -
   v teplej palete by trcala; obrys a farba textu staci a zostava citatelna. */
.btn--danger {
  background: transparent;
  color: var(--bad);
  border: 1px solid var(--bad-line);
}

.btn--danger:hover {
  background: var(--bad-bg);
  opacity: 1;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

:where(button, a, input, select, textarea):focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  box-shadow: var(--focus-ring);
}

/* ---------------------------------------------------------------------------
   Stitky
   --------------------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: var(--surface-sunken);
  color: var(--muted);
  font-size: var(--fs-micro);
  white-space: nowrap;
}

.badge--ok   { background: var(--ok-bg);   border-color: var(--ok-line);   color: var(--ok); }
.badge--warn { background: var(--warn-bg); border-color: var(--warn-line); color: var(--warn); }
.badge--bad  { background: var(--bad-bg);  border-color: var(--bad-line);  color: var(--bad); }
.badge--info { background: var(--info-bg); border-color: var(--info-line); color: var(--info); }

/* Bodka pred textom stitku. Stav sa tak da precitat aj periferne, bez
   citania textu - a nespoliehame sa pritom len na farbu. */
.badge::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: currentColor;
  flex: 0 0 auto;
}

.badge--plain::before { display: none; }

/* ---------------------------------------------------------------------------
   Tabulky
   --------------------------------------------------------------------------- */

.table-wrap {
  /* Siroka tabulka scrolluje v sebe VODOROVNE. Bez toho scrolluje cela stranka
     vodorovne a bocny panel odide z obrazovky. */
  overflow-x: auto;
  /*
   * ZVISLE sa tu uz neposuva nic - posuva sa cela podstranka.
   *
   * Povodne tu bolo `max-height: calc(100vh - ...)`, takze dlha tabulka
   * dostala vlastny posuvnik vnutri stranky. Vysledkom boli dva posuvniky nad
   * sebou: jeden pre okno, jeden pre tabulku. Clovek scrolloval kolieskom,
   * hybala sa tabulka, zvysok stranky stal - a na nizsom okne sa k patickam
   * pod tabulkou nedalo dostat vobec.
   *
   * Cenou je sticky hlavicka tabulky, ktora takto nema voci comu drzat (viz
   * `thead th` nizsie). Je to zamena vedoma: hlavicka, ktora stoji, je prijemna,
   * ale posuvnik v posuvniku je prekazka.
   */
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--surface);
}

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

thead th {
  text-align: left;
  font-weight: var(--fw-medium);
  color: var(--muted);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  /*
   * ZIADNE `position: sticky`.
   *
   * `.table-wrap` ma `overflow-x: auto` a podla specifikacie sa tym stava
   * scroll kontajnerom AJ ZVISLE (`visible` sa v druhej osi pocita ako
   * `auto`). Sticky prvok vnutri sa potom pozicuje voci tomuto kontajneru, nie
   * voci stranke. Odkedy wrapper nema `max-height`, zvisle sa v nom uz nic
   * neposuva, takze sticky by bolo len mrtve pravidlo - hlavicka by nedrzala
   * voci niecomu, ani voci stranke.
   */
}

tbody td {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}

tbody tr:last-child td { border-bottom: 0; }

tbody tr.clickable {
  cursor: pointer;
  transition: background var(--transition);
}

tbody tr.clickable:hover { background: var(--surface-sunken); }

td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
   Formulare
   --------------------------------------------------------------------------- */

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

.field__label {
  font-size: var(--fs-small);
  color: var(--muted);
}

.field__hint {
  font-size: var(--fs-micro);
  color: var(--muted);
}

input,
select,
textarea {
  font: inherit;
  font-size: var(--fs-small);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-input);
  padding: 8px 11px;
  width: 100%;
  transition: border-color var(--transition);
}

input:hover,
select:hover,
textarea:hover { border-color: var(--muted); }

textarea {
  font-family: var(--font-mono);
  min-height: 160px;
  resize: vertical;
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}

.toolbar .field { min-width: 180px; }
.toolbar .field--grow { flex: 1 1 260px; }

/* ---------------------------------------------------------------------------
   Oznamenia
   --------------------------------------------------------------------------- */

.alert {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-small);
  background: var(--surface-sunken);
}

.alert--ok   { background: var(--ok-bg);   border-color: var(--ok-line);   color: var(--ok); }
.alert--warn { background: var(--warn-bg); border-color: var(--warn-line); color: var(--warn); }
.alert--bad  { background: var(--bad-bg);  border-color: var(--bad-line);  color: var(--bad); }

/* `code` v oznameni je ZVYCAJ sucastou vety a musi zostat inline - inak sa
   veta roztrhne na tri riadky okolo neho. Samostatny prikaz na skopirovanie
   dostane `.alert__cmd`. */
.alert code {
  background: var(--surface-sunken);
  border-radius: 3px;
  padding: 1px 5px;
}

.alert__cmd,
.alert code.block {
  display: block;
  margin-top: var(--sp-2);
  word-break: break-all;
}

.empty {
  padding: var(--sp-7) var(--sp-5);
  text-align: center;
  color: var(--muted);
  font-size: var(--fs-small);
}

/* ---------------------------------------------------------------------------
   Prihlasenie
   --------------------------------------------------------------------------- */

.login {
  display: grid;
  place-items: center;
  min-height: 100%;
  padding: var(--sp-5);
}

.login__card {
  width: 100%;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: var(--sp-6);
  box-shadow: var(--shadow-lg);
}

.login__brand {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-h3);
  letter-spacing: var(--tracking-tight);
}

.login__brand strong { font-weight: var(--fw-medium); }

/* ---------------------------------------------------------------------------
   Tok paketov
   --------------------------------------------------------------------------- */

.stream {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  /* Bez `max-height`: posuva sa cela podstranka, nie zoznam v nej. Ten isty
     dovod ako pri `.table-wrap` - dva posuvniky nad sebou su prekazka.
     Pocet riadkov obmedzuje `app.js`, nie CSS. */
}

.stream__row {
  display: grid;
  grid-template-columns: 78px 96px 1fr auto;
  gap: var(--sp-3);
  padding: 6px var(--sp-4);
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}

.stream__row:last-child { border-bottom: 0; }

/* Problemova sprava je zvyraznena pozadim, nie len farbou textu - v rychlo
   beziacom toku sa odtien textu neprecita. */
.stream__row--bad { background: var(--bad-bg); }

.stream__payload {
  white-space: pre-wrap;
  word-break: break-all;
  color: var(--muted);
}

/* ---------------------------------------------------------------------------
   Uzsie obrazovky
   --------------------------------------------------------------------------- */

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

  .nav {
    position: static;
    height: auto;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  .nav__links { flex-direction: row; flex-wrap: wrap; }
  .nav__foot { margin-top: 0; }
  .view { padding: var(--sp-4); }

  /* Panel je tu vodorovna lista, nie stlpec cez celu vysku - vlastny posuvnik
     by prekazal. */
  .nav { overflow-y: visible; }
}

/* ---------------------------------------------------------------------------
   Mriezka formulara - generovane nastavenia zo capability schemy
   --------------------------------------------------------------------------- */

/*
 * `auto-fit` a nie pevny pocet stlpcov.
 *
 * Pocet poli nie je znamy dopredu - prichadza zo schemy a lisi sa od typu k
 * typu (SEN66 ma pat, hub tri). Pevne dva stlpce by pri troch poliach nechali
 * polovicu riadku prazdnu a pri dvadsiatich by boli stlpce uzke.
 */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--sp-4);
  margin: var(--sp-4) 0;
}

/* Pole, ktore sa do jedneho stlpca nezmesti: URL, SHA-256, podpisovy blok. */
.form-grid .field--wide { grid-column: 1 / -1; }

.field--inline {
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

.field--inline input { width: 120px; }
.field--inline .field__hint { flex: 1 1 100%; margin: 0; }

/* Kluc protokolu pri nazve pola. Obsluha hlada podla neho v logoch, takze
   musi byt vidno - ale nesmie prekryt citatelny nazov. */
.field__key {
  margin-left: var(--sp-2);
  color: var(--muted);
  font-weight: var(--fw-normal);
}

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

/* Checkbox nesmie dedit `width: 100%` z pravidla pre vsetky inputy - inak sa
   roztiahne na celu sirku stlpca a vyzera ako rozbity prvok. */
input[type='checkbox'] {
  width: auto;
  margin: 0;
  accent-color: var(--ink);
}

.form__status:not(:empty) { margin: var(--sp-3) 0; }

/* OTA podpisovy blok je dlhy, ale nie je to kod na citanie - staci nizke pole.
   Schemu v inom formulari necham vysoku (pravidlo pre `textarea` vyssie). */
.card textarea[rows='3'] { min-height: 72px; }

/* ---------------------------------------------------------------------------
   Grafy
   --------------------------------------------------------------------------- */

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

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

.chart__title {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
}

.chart__now { margin-left: auto; font-size: var(--fs-body); }
.chart__range { color: var(--muted); }

/*
 * `height: auto` so zachovanym pomerom cez `aspect-ratio`.
 *
 * SVG ma `preserveAspectRatio: none`, takze sa natahuje na sirku karty. Bez
 * pevneho pomeru by pri uzkej karte vysla ciara stlacena na niekolko pixelov.
 */
.chart {
  width: 100%;
  aspect-ratio: 720 / 160;
  overflow: visible;
}

.chart__grid {
  stroke: var(--line);
  stroke-width: 1;
}

.chart__tick {
  fill: var(--muted);
  font-size: 9px;
  font-family: var(--font-mono);
  text-anchor: end;
}

/* Pasmo min-max. Priehladnost, nie svetlejsia farba - pod nim je mriezka a tu
   ma byt vidno, inak sa strati predstava o hodnotach. */
.chart__band {
  fill: var(--ink);
  opacity: 0.12;
  stroke: none;
}

.chart__line {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.6;
  stroke-linejoin: round;
  stroke-linecap: round;
}

/*
 * Prazdna karta nema zaberat vysku plnej karty.
 *
 * `.empty` ma velke odsadenie, aby v tabulke posobilo ako plnohodnotny obsah.
 * V karte, ktora NIC neobsahuje (typ bez vystupov, graf bez dat), z toho vznikne
 * velky prazdny blok, ktory na obrazovke vyzera ako chyba vykreslenia.
 */
.card > .empty:only-child,
.chart-wrap + .empty,
.card > .empty:first-child:last-child {
  padding: var(--sp-4);
  font-size: var(--fs-small);
}

/* ---------------------------------------------------------------------------
   Pomocne triedy namiesto inline stylov
   ---------------------------------------------------------------------------

   Webadmin posiela `Content-Security-Policy: style-src 'self'`, takze
   prehliadac kazdy inline `style=""` TICHO ZAHODI. Prvok potom zostane bez
   pravidla a vyzera to ako chyba rozlozenia - nie ako zablokovane pravidlo.
   V konzole to svieti ako "Applying inline style violates ...", ale len tam.

   Konkretne na obrazovke Triggery to znamenalo, ze ciselne polia a vyber
   sondy dostali `width: 100%` z obecneho pravidla pre `input` a vyber
   "všetky sondy" sa orezal. Preto su sirky TU, nie v JS. */

.input--num { width: 76px; }
.input--num-sm { width: 64px; }

/* Sirky v tabulke typov senzorov. Prvy stlpec je nazov, zvysok su meradla -
   uzke polia by nazov orezali, siroke by z tabulky urobili vodorovny scroll. */
.input--lg { width: 150px; }
.input--sm { width: 80px; }

.btn-row--spaced { margin-top: var(--sp-4); }
.field--spaced { margin-top: var(--sp-4); }
.text-bad { color: var(--bad); }
.badge--clickable { cursor: pointer; }

/* Vyber sondy v triggeroch.
   `auto` namiesto `100%`: polozka "všetky sondy" je najdlhsia a pri 100 %
   sirke rodica sa orezala. `min-width` drzi vyber citatelny aj ked ma
   zariadenie jedinu sondu s kratkym popisom - ale len tolko, kolko
   najdlhsia polozka naozaj potrebuje. Prva verzia mala 150 px a tabulka
   triggerov preto pretekala o 66 px, takze stlpec s tlacidlom "Uložiť"
   koncil mimo viditelnej casti. */
.select--probe {
  width: auto;
  min-width: 118px;
  max-width: 100%;
}

/* ---------------------------------------------------------------------------
   Husta tabulka - riadky s formularovymi polami
   ---------------------------------------------------------------------------

   Riadok triggera ma vysku 83 px: odsadenie bunky plus odsadenie vstupneho
   pola plus jeho ramik. Pri 49 triggeroch je z toho strana, ktora sa posuva
   dlhsie, nez trva precitat jeden riadok - a pritom tam nie je nic naviac.

   Obycajnych tabuliek sa to netyka: tam je vysoky riadok citatelnejsi. */
.table--dense tbody td { padding: var(--sp-2) var(--sp-3); }
.table--dense input,
.table--dense select { padding: 5px 8px; }

/* ---------------------------------------------------------------------------
   Simulator zariadeni
   --------------------------------------------------------------------------- */

/*
 * Kompaktny zoznam udajov v karte.
 *
 * `grid--tiles` je stavany na siroku kartu (`minmax(190px, 1fr)` s auto-fill).
 * V dvojstlpcovom rozlozeni simulatora sa zlomi na jeden stlpec a z osmich
 * udajov vznikne karta vysoka na cely ekran. Tu je popis a hodnota na jednom
 * riadku.
 */
.facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px var(--sp-3);
  margin: var(--sp-3) 0;
  align-items: baseline;
}

.facts dt {
  font-size: var(--fs-micro);
  color: var(--muted);
}

.facts dd {
  margin: 0;
  font-size: var(--fs-small);
  /* Dlhy `boot_id` nesmie roztiahnut kartu - radsej sa skrati. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * Zaznam simulovaneho zariadenia.
 *
 * Jeden riadok = jedna udalost. Dlhy riadok sa SCROLLUJE, nelame: zalomenie
 * mono textu po znakoch z neho robi stlpec pismen, v ktorom sa nic neprecita.
 */
.simlog {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-2);
  max-height: 180px;
  overflow: auto;
}

.simlog > div {
  white-space: pre;
  padding: 1px 0;
}

/* ---------------------------------------------------------------------------
   Ikony v menu
   ---------------------------------------------------------------------------

   Inline SVG, nie ikonova kniznica. Webadmin ma byt dostupny prave vtedy, ked
   je vsetko ostatne rozbite, takze externy zdroj neprichadza do uvahy - a
   lokalna kopia celej sady je pre dvanast ikon nepomer.
   `currentColor` znamena, ze ikona dedi farbu polozky vratane aktivneho stavu. */

.nav__links a {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

.nav__icon {
  width: 17px;
  height: 17px;
  flex: 0 0 auto;
  /* Opticke zarovnanie na uciaru textu - ikona v riadku posadena presne na
     stred posobi o kusok vyssie, než kde text lezi. */
  margin-top: -1px;
  opacity: 0.75;
}

.nav__links a:hover .nav__icon,
.nav__links a.active .nav__icon { opacity: 1; }

/* ---------------------------------------------------------------------------
   Prepinac rezimu zobrazenia
   --------------------------------------------------------------------------- */

.theme {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  padding: 2px;
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  /* ZIADNY `margin-bottom`. Odstup medzi prvkami paticky drzi `gap` na
     `.nav__foot`; vlastny okraj sa k nemu pripocital a medzi prepinacom
     rezimu a uctom vznikla diera na dva prsty. */
}

.theme__btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 6px 2px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 9.5px;
  cursor: pointer;
  border-radius: calc(var(--radius-input) - 1px);
  transition: background var(--transition), color var(--transition);
}

.theme__btn svg { width: 15px; height: 15px; }

.theme__btn:hover { color: var(--ink); }

/* Aktivna volba ma PLNE pozadie, nie len inu farbu textu.
   Pri troch rovnako velkych tlacidlach je rozdiel v odtieni textu prislabo
   citatelny - clovek nevidi, ktory rezim prave plati. */
.theme__btn--active {
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}

/* ---------------------------------------------------------------------------
   Modal
   ---------------------------------------------------------------------------

   Nativny `<dialog>`, nie vlastny prekryv. Prehliadac za nas riesi zachytenie
   fokusu vnutri dialogu, zatvorenie klavesou Escape a vrstvenie nad vsetkym
   ostatnym bez `z-index` vojny. */

.modal {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: min(880px, calc(100vw - 2 * var(--sp-5)));
  width: 100%;
  /* `max-height` + scroll vnutri tela: dlhy formular (typ s dvadsiatimi
     velicinami) sa inak nezmesti a patickou s tlacidlami sa vysunie mimo
     obrazovku - clovek vyplni formular a nema co stlacit. */
  max-height: calc(100vh - 2 * var(--sp-5));
}

.modal::backdrop {
  background: #29282499;
  backdrop-filter: blur(2px);
}

/* Posuva sa LEN telo dialogu.
   `<dialog>` je sam o sebe posuvatelny, takze pri dlhom formulari boli na
   pravej strane DVA posuvniky vedla seba - jeden dialogu a jeden jeho tela.
   Vyzeralo to ako chyba vykreslenia a klikalo sa do toho nespravneho. */
.modal { overflow: hidden; }

.modal__box {
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 2 * var(--sp-5));
  background: var(--bg);
  /* Farba textu sa MUSI uviest.
     `<dialog>` ma v prehliadaci vlastne `color: CanvasText`, takze NEDEDI
     farbu zo stranky. V tmavom rezime z toho bol cierny nadpis na ciernom
     pozadi - vsetko ostatne v dialogu farbu nastavenu malo (popisky, napovedy),
     takze chybal presne a len nadpis. */
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.modal__head {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-4);
  padding: var(--sp-5) var(--sp-5) var(--sp-4);
  border-bottom: 1px solid var(--line);
}

.modal__title {
  font-size: var(--fs-h3);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tracking-tight);
}

.modal__subtitle {
  margin-top: 2px;
  font-size: var(--fs-small);
  color: var(--muted);
}

.modal__close {
  margin-left: auto;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}

.modal__close:hover { color: var(--ink); }

.modal__body {
  padding: var(--sp-5);
  overflow-y: auto;
}

.modal__foot {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--line);
  background: var(--surface);
}

/* Hlaska je v PATICKE, pri tlacidle - nie nad obsahom.
   Chyba ulozenia patri k akcii, ktora ju sposobila; nad formularom by ju
   clovek pri dlhsom obsahu vobec nevidel. */
.modal__status { flex: 1 1 auto; min-width: 0; }

.modal__msg {
  font-size: var(--fs-small);
  display: block;
}

.modal__msg--bad { color: var(--bad); }
.modal__msg--ok { color: var(--ok); }

.modal__foot .btn-row { flex: 0 0 auto; }

/* ---------------------------------------------------------------------------
   Lista nastrojov nad zoznamom
   --------------------------------------------------------------------------- */

.toolbar__actions {
  margin-left: auto;
  display: flex;
  gap: var(--sp-2);
}

.filter {
  display: flex;
  align-items: flex-end;
  gap: var(--sp-3);
  flex-wrap: wrap;
  flex: 1 1 320px;
}

.filter__main { flex: 1 1 240px; min-width: 180px; }

.filter__input {
  /* `type=search` ma vo WebKite vlastny vzhlad vratane kruzku na zrusenie;
     zjednoteny so zvyskom formularov. */
  appearance: none;
}

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

.filter__label {
  font-size: var(--fs-micro);
  color: var(--muted);
}

.filter__select { width: auto; min-width: 110px; }

/* ---------------------------------------------------------------------------
   Nahlad obrazka a prepinacie znacky
   --------------------------------------------------------------------------- */

.thumb {
  width: 34px;
  height: 34px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: var(--radius-input);
  background: var(--surface);
  display: block;
}

.thumb--empty {
  display: grid;
  place-items: center;
  color: var(--muted);
  font-size: var(--fs-micro);
}

/* Vyber velicin - husta mriezka prepinacov.
   `btn-row` sa na to nehodi: pri dvadsiatich velicinach z neho vznikne osem
   riadkov roznej dlzky a neda sa v nich nic najst. */
.chips {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}

.chip {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 5px 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-input);
  font-size: var(--fs-small);
  cursor: pointer;
  background: var(--surface);
}

.chip:hover { border-color: var(--muted); }
.chip:has(input:checked) { border-color: var(--ink); background: var(--surface-sunken); }

/* ---------------------------------------------------------------------------
   Karty nad obrazovkou
   ---------------------------------------------------------------------------
   Lista je VODOROVNE POSUVATELNA, nie zalamovana. Sest kariet sa na uzkej
   obrazovke do jedneho riadku nezmesti a zalomenie by posunulo obsah o riadok
   nizsie - teda presne to posuvanie, ktoremu sa karty vyhybaju. */
.tabs {
  display: flex;
  gap: var(--sp-1);
  overflow-x: auto;
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--sp-4);
  /* Posuvatelna lista bez viditelneho pruhu - pruh by na desktope zabral
     riadok, ktory tam nie je potrebny. */
  scrollbar-width: none;
}

.tabs::-webkit-scrollbar { display: none; }

.tabs__btn {
  flex: 0 0 auto;
  padding: var(--sp-2) var(--sp-4);
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--muted);
  font: inherit;
  font-weight: var(--fw-medium);
  cursor: pointer;
  /* Posun o sirku spodneho okraja lista, aby aktivna karta prekryla linku. */
  margin-bottom: -1px;
}

.tabs__btn:hover { color: var(--ink); }

.tabs__btn--on {
  color: var(--ink);
  border-bottom-color: var(--ink);
}

/* ---------------------------------------------------------------------------
   Vysvetlujuci text POD obsahom
   ---------------------------------------------------------------------------
   Nie `.alert`: vysvetlenie, ktore clovek potrebuje raz, nema mat ramec ani
   pozadie - prituhlo by sa k zoznamu a vyzeralo by ako hlaska, ktoru treba
   riesit. Odstup zhora je zamerne velky, aby bolo jasne, ze to k poslednemu
   riadku tabulky nepatri. */
.note {
  color: var(--muted);
  font-size: var(--fs-small);
  max-width: 78ch;
}

.note--after { margin-top: var(--sp-6); }

/* Odstup medzi dvoma samostatnymi zoznamami na jednej obrazovke (firmvery a
   davky). Bez neho nadpis druhej sekcie sedi na poslednom riadku prvej. */
.section--gap { margin-top: 30px; }

/* Vypis celeho JSON dokumentu v dialogu (capability schema).
   `pre` sa NEZALAMUJE, posuva sa - zalomeny JSON straca odsadenie, ktore je
   jediny sposob, ako sa v nom da citat struktura. Vyska je obmedzena, inak by
   dialog pri 20 kB dokumente prerastol obrazovku a tlacidla by boli mimo. */
.code-block {
  margin-top: var(--sp-3);
  padding: var(--sp-3);
  max-height: 45vh;
  overflow: auto;
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  line-height: 1.5;
  white-space: pre;
  tab-size: 2;
}

/* ---------------------------------------------------------------------------
   Kalendar dostupnosti
   ---------------------------------------------------------------------------
   Pevna sirka dlazdice, nie `1fr`: pri 14 dnoch by sa sirka menila podla
   sirky okna a dva kusy vedla seba by sa nedali porovnat pohladom. */
.cal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}

.cal__day {
  width: 64px;
  padding: var(--sp-2);
  border-radius: var(--radius-sm);
  text-align: center;
  border: 1px solid transparent;
}

.cal__date { font-size: var(--fs-micro); opacity: 0.85; }
.cal__pct { font-size: var(--fs-small); font-weight: var(--fw-medium); }

.cal__day--ok   { background: var(--ok-bg);   border-color: var(--ok-line);   color: var(--ok); }
.cal__day--warn { background: var(--warn-bg); border-color: var(--warn-line); color: var(--warn); }
.cal__day--bad  { background: var(--bad-bg);  border-color: var(--bad-line);  color: var(--bad); }

/* Nezname je INE nez nula percent - vtedy sme kus este nesledovali. Preto
   neutralna plocha, nie cervena. */
.cal__day--unknown {
  background: var(--surface-sunken);
  border-color: var(--line);
  color: var(--muted);
}

/* Nahlad obrazka typu zariadenia v dialogu. Pevna vyska, `contain` - ikony
   prichadzaju v roznych pomeroch stran a `cover` by im orezal okraje. */
.img-preview {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 72px;
  padding: var(--sp-2);
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}

.img-preview img {
  width: 56px;
  height: 56px;
  object-fit: contain;
}


/* Karta vlozena do dialogu nekresli vlastny ramec - dialog uz jeden ma a dva
   ramce okolo toho isteho vyzeraju ako chyba. */
.modal__body .card {
  border: 0;
  padding: 0;
  background: none;
  box-shadow: none;
}


/* ---------------------------------------------------------------------------
   Nadpis sekcie sa NELEPI na to, co je nad nim
   ---------------------------------------------------------------------------
   `card__head` je zaroven hlavicka karty aj nadpis sekcie vo `view`. V karte
   ma sedet hore, ale ako nadpis sekcie potreboval odstup - a kedze ho nemal,
   kazdy druhy nadpis (Priebehy, Kadencia, Pakety, Historia dostupnosti,
   Bezia ce) sa dotykal tabulky nad sebou.

   Riesi sa to SUSEDSKYM selektorom namiesto triedy na kazdom mieste: nadpis,
   pred ktorym nieco je, dostane odstup; prvy prvok na obrazovke nie. Tym sa
   to tyka aj vsetkych buducich sekcii bez toho, aby si na to niekto musel
   spomenut. */
/* Plati v KAZDOM kontajneri okrem karty - nadpis sekcie casto nie je priamy
   potomok `.view`, ale sedi vnutri obalu, ktory sa prekresluje (zoznam
   bezia cich zariadeni, telo dialogu). Vnutri `.card` je hlavicka prvy prvok a
   odstup by ju odtrhol od vlastnej karty. */
:not(.card) > * + .card__head,
:not(.card) > * + h2,
:not(.card) > * + h3,
:not(.card) > * + h4 {
  margin-top: var(--sp-6);
}

/* Filter a tabulka nie su to iste - medzi nimi musi byt vidno hranicu. */
.view > .filter + .table-wrap,
.view > .toolbar + .table-wrap,
.view > .filter + div,
.view > .toolbar + div {
  margin-top: var(--sp-4);
}

/* Hlaska nad zoznamom tiez nema sediet na jeho prvom riadku. */
.alert + .table-wrap,
.alert + .card,
.alert + .toolbar,
.alert + .filter,
.note + .table-wrap,
.table-wrap + .toolbar,
.table-wrap + .alert,
.toolbar + .table-wrap,
.filter + .table-wrap {
  margin-top: var(--sp-4);
}

/* ---------------------------------------------------------------------------
   Posuvniky
   ---------------------------------------------------------------------------
   Systemovy posuvnik je v tmavom rezime svetly pruh cez pol obrazovky a v
   dialogoch bil do oci viac nez obsah. Vlastny je uzsi, v farbach rozhrania a
   zvyrazni sa az pod kurzorom.

   `scrollbar-color` je standard (Firefox aj novy Chrome), `::-webkit-*` je
   pre starsie webkit prehliadace - preto obe. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

*::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

*::-webkit-scrollbar-track {
  background: transparent;
}

*::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: var(--radius-pill);
  /* Priehladny ramcek zuzi viditelnu cast - posuvnik tak nelipne na obsahu. */
  border: 2px solid transparent;
  background-clip: content-box;
}

*::-webkit-scrollbar-thumb:hover {
  background: var(--muted);
  background-clip: content-box;
}

*::-webkit-scrollbar-corner {
  background: transparent;
}


/* Veta, ktora hovori, co prah urobi. Je to ZHRNUTIE formulara nad nou, preto
   ma vlastnu plochu a nie je to `field__hint` - tie su pod jednotlivymi
   polami a tato veta patri k vsetkym naraz. */
.sentence {
  margin-top: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-sunken);
  border-left: 3px solid var(--ink);
  border-radius: var(--radius-sm);
  font-size: var(--fs-small);
  line-height: 1.5;
}

/* Dvojica od-do na jednom riadku. */
.range-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

/* ---------------------------------------------------------------------------
   Oddelovac v menu a ucet pouzivatela
   --------------------------------------------------------------------------- */
.nav__sep {
  height: 1px;
  margin: var(--sp-3) var(--sp-3);
  border: 0;
  background: var(--line);
}

.nav__account {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  padding: var(--sp-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.nav__account:hover { background: var(--surface-sunken); }

.nav__avatar {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: var(--bg);
  font-size: var(--fs-micro);
  font-weight: var(--fw-medium);
}

/* Menu sa otvara NAHOR - ucet sedi na spodku bocneho pruhu a nadol by sa
   nezmestilo. */
.nav__menu {
  position: absolute;
  bottom: 100%;
  left: var(--sp-3);
  right: var(--sp-3);
  margin-bottom: var(--sp-2);
  padding: var(--sp-2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  z-index: 20;
}

.nav__menu a,
.nav__menu button {
  display: block;
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.nav__menu a:hover,
.nav__menu button:hover { background: var(--surface-sunken); }


/* ---------------------------------------------------------------------------
   Tlacidlo sa nelepi na to, co je nad nim
   ---------------------------------------------------------------------------
   Tlacidlo, ktore nasleduje po inom bloku (hlaske, tabulke, formulari), je
   SAMOSTATNY krok - a ako taky potrebuje odstup. Bez neho sedelo "Ulozit"
   priamo na spodnom okraji hlasky nad nim.

   Vynimky su miesta, kde su tlacidla ZAMERNE v rade vedla seba alebo v jednom
   riadku s inym obsahom: hlavicka karty, panel nastrojov, filter, paticka
   dialogu, bunka tabulky a skupina tlacidiel. Tam by odstup rozhodil riadok. */
:not(.card__head):not(.toolbar):not(.filter):not(.modal__foot):not(.btn-row):not(td):not(.range-row)
  > * + .btn,
:not(.card__head):not(.toolbar):not(.filter):not(.modal__foot):not(td)
  > * + .btn-row {
  margin-top: var(--sp-4);
}

/* To iste pre bezne tlacidla vo formulari, ktore nasleduju po poli. */
.form-grid + .btn,
.form-grid + .btn-row,
.field + .btn,
.sentence + .btn,
.sentence + .btn-row {
  margin-top: var(--sp-4);
}

/* Tlacidla zarovnane doprava - akcia patri na koniec riadku, nie na zaciatok. */
.btn-row--right {
  justify-content: flex-end;
}

/* Obrazok produktu vedla identity. Vacsi nez ikona v zozname - tu je to
   jedina vizualna kotva, podla ktorej clovek spozna, o aky kus ide. */
.identity {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-bottom: var(--sp-4);
}

.identity__img {
  width: 96px;
  height: 96px;
  flex: 0 0 96px;
  object-fit: contain;
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: var(--sp-2);
}

.identity__name .h4 {
  font-size: var(--fs-h4);
  font-weight: var(--fw-medium);
}

/* Stlpcovy prehlad notifikacii po dnoch. Pevna vyska, aby dva dni vedla seba
   boli porovnatelne pohladom; stlpec bez hodnoty necha prazdne miesto, nie
   dieru v rade. */
.bars {
  display: flex;
  align-items: flex-end;
  gap: var(--sp-2);
  height: 90px;
  margin-top: var(--sp-3);
  padding: var(--sp-3);
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}

.bars__col {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  height: 100%;
  gap: 4px;
}

.bars__fill {
  width: 100%;
  min-height: 2px;
  background: var(--ink);
  border-radius: 3px 3px 0 0;
  opacity: 0.75;
}

.bars__label {
  font-size: var(--fs-micro);
  color: var(--muted);
}

/* ===========================================================================
   DIZAJNOVY PRECHOD
   ===========================================================================

   Co bolo zle, ked sa na to clovek pozrel ako na celok:

   1. FORMULARE NEMALI HIERARCHIU. Vsetky polia boli vizualne rovnake, takze
      "Nazov" a "SHA-256 podpisoveho bloku" vyzerali rovnako dolezito, a nic
      nehovorilo, ktore polia spolu suvisia.

   2. TABULKY MALI VSETKY STLPCE ROVNAKEJ VAHY. Oko nemalo kde zacat; pritom
      v kazdej tabulke je jeden stlpec, podla ktoreho sa riadok hlada
      (seriove cislo, nazov veliciny, verzia).

   3. PRVKY MALI ROZNE VYSKY. Vstup, vyberatko a tlacidlo v jednom riadku
      nesedeli na spolocnej linke.

   Nize je to, co to napravuje. Je to v CSS, nie v kazdej obrazovke zvlast -
   inak by sa to rozislo pri prvej novej obrazovke.
   =========================================================================== */

/* --- 1. Skupiny poli vo formulari ----------------------------------------
   Nadpis skupiny je mensi nez nadpis sekcie a oddeleny linkou. Hovori "toto
   patri k sebe" bez toho, aby sutazil s nazvom dialogu. */
.modal__body h4,
.form-section__title {
  margin-top: var(--sp-5);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

/* Prva skupina v dialogu uz odstup zhora ma od tela dialogu. */
.modal__body > h4:first-child { margin-top: 0; }

/* --- 2. Tabulky: jeden stlpec vedie, zvysok je potichu -------------------
   Prvy stlpec je ten, podla ktoreho sa riadok hlada, takze ma plnu farbu a
   vacsiu vahu. Ostatne su o ton tichsie - rozdiel je maly, ale oko podla neho
   skenuje stlpec, nie cely riadok. */
tbody td:first-child {
  color: var(--ink);
  font-weight: var(--fw-medium);
}

tbody td { color: var(--muted); }

/* Cisla v stlpci pod sebou musia mat rovnako siroke cislice, inak sa
   nedaju porovnat pohladom. */
td.num,
.num,
.mono {
  font-variant-numeric: tabular-nums;
}

tbody tr { transition: background var(--transition); }
tbody tr:hover { background: var(--surface-sunken); }

/* --- 3. Spolocna vyska ovladacich prvkov ---------------------------------
   Vstup, vyberatko a tlacidlo v jednom riadku sedia na spolocnej linke. Bez
   toho bol kazdy panel nastrojov o pol pixela inde. */
input,
select,
.btn {
  min-height: 34px;
}

.btn--sm { min-height: 28px; }

/* Zaskrtavatko sa nema natiahnut na sirku riadku - `width: 100%` z obecneho
   pravidla pre `input` mu dava sirku cez pol obrazovky. */
input[type='checkbox'],
input[type='radio'] {
  width: auto;
  min-height: 0;
  accent-color: var(--ink);
}

/* Subor: predvoleny vzhlad je v kazdom prehliadaci iny a ziadny z nich
   nesedi so zvyskom. */
input[type='file'] {
  padding: 6px 8px;
  background: var(--surface-sunken);
  cursor: pointer;
}

/* --- 4. Dialog: sirka patri DIALOGU, nie jeho vnutru ---------------------
   Formular s dvoma polami nema byt siroky ako obrazovka a formular s
   dvadsiatimi nema byt v uzkom stlpci - preto 880px (hore, na `.modal`).

   Tu stalo `width: min(880px, ...)` na `.modal__box`, teda na OBSAHU dialogu,
   kym sam `<dialog>` zostal na 760px a ma `overflow: hidden`. Vysledok: kazdy
   modal bol vpravo orezany o 120px a hlavne tlacidlo ("Ulozit", "Pridat do
   zoznamu") lezalo ZA hranou - nebolo ho vidiet a nedalo sa k nemu ani
   doscrollovat. Sirka teda musi byt na dialogu a obsah ju len vyplna. */
.modal__box { width: 100%; }

/* --- 5. Dve karty pod sebou potrebuju medzeru ----------------------------
   Vnutorny priestor karty uz je nastaveny vyssie; chybal len odstup medzi
   nimi, takze sa dotykali ramcami. */
.card + .card { margin-top: var(--sp-4); }

/* --- 6. Odznaky: jedna velkost, nie tri ---------------------------------- */
.badge {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Detail auditu sa skracuje - niektore zaznamy nesu cely objekt zmeny
   (import nastaveni, davka OTA) a bez skratenia by roztiahli tabulku tak, ze
   ostatne stlpce sa stlacia na nulu. Cely text je v `title`. */
.audit__detail {
  max-width: 340px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
