/* ═══════════════════════════════════════════════════════════
   Základ stránky — rám, mřížka modulů, karta, hodnota, chování
   při najetí myší.

   Žádná barva ani rozměr se tu nepíše natvrdo — všechno jde
   z tokens.css, který dodal designér. Hlídá to test.

   Používají se ANGLICKÉ názvy tokenů. České aliasy v sekci 4
   souboru tokens.css jsou přechodné a jednou zmizí; kdo sem
   napíše var(--barva-…), připraví si práci navíc.

   Rozvržení podle HANDOFF.md, oddíl 3:
     • vlevo panel 260 px, vpravo obsah
     • mřížka auto-fit s minimem 686 px — modul, jehož soused je
       vypnutý, se roztáhne na celou šířku
     • obsah modulu se přeskládá podle šířky MODULU, ne okna
       (container queries), protože týž modul může být úzký
       ve dvousloupcovém i v jednosloupcovém rozvržení
   ═══════════════════════════════════════════════════════════ */

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

/* ── Skrytý prvek je opravdu skrytý ───────────────────────
   Prohlížeč skrývá `hidden` pravidlem [hidden] { display: none },
   jenže to je v jeho vlastní tabulce a JAKÁKOLI naše třída s
   `display` ho přebije. Prvek pak zůstane na obrazovce.

   Nejde jen o vzhled. 9. 9. takhle prázdná hláška o chybě ležela
   přes celý graf, byla neviditelná, a přitom chytala všechny
   pohyby myši — grafy se tvářily, že nereagují, a přitom se
   události ani nedostaly k plátnu.

   Tohle jediné pravidlo to uzavírá pro celou aplikaci, včetně
   modulů, které teprve vzniknou. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg-canvas);
  color: var(--text-primary);
  font-family: var(--font-family-base);
  font-size: var(--font-size-16);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; line-height: 1.2; text-wrap: balance; }
p { margin: 0; }

/* ── Rám stránky ──────────────────────────────────────────
   Panel je připnutý vlevo, obsah se o jeho šířku odsadí.
   Odsazení jde z téhož tokenu jako šířka panelu, takže se
   nemůžou rozejít. */
.obsah {
  margin-left: var(--layout-sidebar-width);
  min-height: 100vh;
  transition: margin-left var(--motion-base) ease;
}

.je-sbaleny .obsah { margin-left: var(--layout-sidebar-width-collapsed); }

/* Na tabletu a telefonu se panel schovává za hamburger — odsazení
   obsahu řeší panel.css, aby to bylo na jednom místě. */

/* ── Mřížka modulů ────────────────────────────────────────
   DVA SLOUPCE, VŽDY PŮL NA PŮL (designér, 10. 9.).

   Do té doby to byla mřížka auto-fit, která prázdné dráhy sbalila —
   modul, jehož soused byl vypnutý, se roztáhl přes celou šířku.
   Designér to výslovně nechce: osamělý modul v řadě má zůstat
   poloviční. Proto pevné dva sloupce a jediný media dotaz na jejich
   počet, což je odchylka od HANDOFF.md 3 („no media query needed").

   Práh 1340 px: dva sloupce po 500 px plus mezera potřebují 1016 px
   obsahu, k tomu panel 260, odsazení 48 a svislý posuvník 15.
   Pod ním se skládá do jednoho sloupce. */
.module-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* `dense` zaplní díru, která vznikne po vypnutém modulu.
     Petr 15. 9. u instalace bez baterie (#44): „na místo, kde bylo SOC
     baterie, ať se přesune např. Domácnost a síť, ať se zaplní to
     prázdné místo."

     Proč díra vůbec vzniká: Flow je vysoké přes dvě řady, takže vedle
     něj stojí dva poloviční moduly. Když jeden z nich zmizí, další
     v pořadí je široký přes obě dráhy a do zbylé půlky se nevejde —
     přeskočí ji a místo zůstane prázdné. `dense` dovolí pozdějšímu
     polovičnímu modulu vrátit se a díru vyplnit.

     Když se nic nevypíná, nemá to co dělat — bez díry se `dense`
     neprojeví, takže výchozí rozložení od designéra zůstává. */
  grid-auto-flow: row dense;
  gap: var(--space-16);
  padding: var(--space-24);
  align-items: start;
}

@media (max-width: 1339px) {
  .module-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Modul přes obě šířky */
.module-grid > .module--wide { grid-column: 1 / -1; }

/* Detailní stránka má jedinou kartu přes celou šířku — dva sloupce
   by tu jen dělily prázdno. */
.module-grid--jeden { grid-template-columns: minmax(0, 1fr); }

/* ── Drobečková navigace ──────────────────────────────────
   Na detailní stránce místo prostého nadpisu:

       FVE James Cole  >  Stav baterie (SOC)

   Obě části jsou stejně velké (20 px, změřeno z návrhu — nadpis
   stránky i nadpis modulu tam mají stejnou výšku verzálek). Liší se
   jen tloušťkou a barvou: název instalace tučně a plnou barvou, konec
   lehčeji a druhou barvou.

   Název instalace je ODKAZ zpátky na dashboard. V návrhu není žádné
   tlačítko „zpět" ani šipka v rohu — tohle je jediná cesta zpátky,
   takže musí být opravdu klikací. */
.drobecek {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  flex-wrap: wrap;
  min-width: 0;
}

.drobecek__zpet {
  color: inherit;
  font: inherit;
  text-decoration: none;
  border-radius: var(--radius-8);
  transition: color var(--motion-fast) ease;
}

.drobecek__zpet:hover { color: var(--text-secondary); }
.drobecek__zpet:focus-visible { outline: var(--border-2) solid var(--state-focus-ring); }

.drobecek__sipka,
.drobecek__konec {
  color: var(--text-secondary);
  font-weight: var(--font-weight-medium);
}

/* ── Karta modulu ─────────────────────────────────────────
   Společný obal. Modul si řeší jen svůj obsah, ne rám. */
.module {
  /* Plocha je přechod, ne plná barva — plná slouží jako záloha */
  background: var(--bg-surface);
  background: var(--gradient-surface);
  border-radius: var(--radius-32);

  /* ── Proč tu je stín ──────────────────────────────────
     Ve světlém motivu je plocha stránky #F5F5F5 a karta
     #FAFAFA → #FFFFFF. To je rozdíl dvou procent jasu, takže se
     karta v podstatě ztrácí — Petr 15. 9.: „nejsou vidět moduly
     a pozadí je bílé".

     Není to regrese: karta stín nikdy neměla. Designér ale světlý
     dashboard nenakreslil (všechna jeho PDF jsou tmavá), takže se
     na to nepřišlo — v tmavém motivu se karta od plochy odliší
     jasem sama.

     Bereme jeho vlastní token. HANDOFF.md: „Shadows — identical in
     both themes" a --shadow-default je popsaný jako „anything
     raised off the surface", což karta modulu je. V tmavém motivu
     je prakticky neviditelný, ve světlém kartu oddělí. */
  box-shadow: var(--shadow-default);
  padding: var(--module-padding);
  padding-bottom: var(--module-padding-bottom);
  display: flex;
  flex-direction: column;
  gap: var(--space-40);
  height: 100%;

  /* Obsah se přeskládá podle šířky modulu, ne okna */
  container-type: inline-size;
}

/* Nadpis modulu — velikost a váhu určuje .type-heading-module z tokens.css */
.module__title { color: var(--text-primary); }

/* Hlavička modulu: nadpis vlevo, ovládání vpravo. V návrhu stojí
   výběr období v pravém horním rohu čtyř modulů. */
.module__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-16);
  flex-wrap: wrap;
}

/* Řádek uvnitř modulu. Zlomí se, až se zúží MODUL — prahy podle
   HANDOFF.md: 1000 px široké moduly, 686 px poloviční, 660 px
   Domácnost a síť. */
.module__row {
  display: flex;
  gap: var(--space-24);
}

@container (max-width: 470px) {
  .module__row { flex-direction: column; }
}

/* Dvě poloviny oddělené svislou linkou — Data Baterie i Analytika
   dne to mají v návrhu stejně. */
.dve-poloviny {
  display: flex;
  gap: var(--space-32);
  align-items: stretch;
}

.dve-poloviny > * {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;   /* obsah začíná nahoře, ne na střed */
  gap: var(--space-24);
}

.dve-poloviny > * + * {
  border-left: var(--border-1) solid var(--border-divider);
  padding-left: var(--space-32);
}

@container (max-width: 470px) {
  .dve-poloviny { flex-direction: column; }
  .dve-poloviny > * + * {
    border-left: 0;
    padding-left: 0;
    border-top: var(--border-1) solid var(--border-divider);
    padding-top: var(--space-24);
  }
}

/* Podnadpis nad polovinou — v návrhu vystředěný a v druhé barvě */
.podnadpis {
  color: var(--text-secondary);
  text-align: center;
}

/* ── Hodnota ──────────────────────────────────────────────
   Číslo a jednotka odděleně, aby jednotka nerostla s číslem.
   Velikost číslu dává třída .type-* z tokens.css. */
.value {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-4);
}
.value__unit  { color: var(--text-secondary); }
.value__label { color: var(--text-secondary); }

/* Číslo a jednotka mají tabulkové číslice (tokens.css), takže se
   při aktualizaci nehýbe šířka. Podbarvení při změně tu bylo
   a bylo zrušeno — viz poznámka v jadro/prvky.js. */

/* Velké číslo s přechodem — Analytika dne má výrobu i spotřebu
   vykreslenou přechodem, ne plnou barvou. Text se obarví pozadím
   proříznutým do písma.

   Tohle pravidlo jsem 10. 9. omylem smazal spolu s probliknutím,
   protože stálo mezi ním a odkazy. Čísla pak zůstala průhledná
   a vypadala jako by zmizel gradient — což taky zmizel. */
.cislo--prechod {
  background-image: var(--prechod);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ── Odkazy „Zobrazit detail" a „Více" ────────────────────
   V návrhu podtržené, v druhé barvě, při najetí zesvětlí. */
.odkaz {
  color: var(--action-link);
  text-decoration: underline;
  background: none;
  border: 0;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
  transition: color var(--motion-fast) ease;
}

.odkaz:hover { color: var(--action-link-hover); }
.odkaz:focus-visible { outline: var(--border-2) solid var(--state-focus-ring); }

/* ── Hlavní tlačítka (CTA) ────────────────────────────────
   Popsal designér v patchi 10. 9. Zatím je nikde nepoužíváme —
   na dashboardu žádné takové tlačítko není. Připravené jsou proto,
   že přijdou s obrazovkami, které se teprve navrhnou (uložit
   nastavení, potvrdit alarm), a mají být hotové ze systému, ne
   vymýšlené narychlo.

   Odsazení 12 px nahoře a dole, 24 px po stranách. Písmo
   .type-cta-primary (18 px Inter Semibold). */
.tlacitko {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  padding: var(--space-12) var(--space-24);
  border-radius: var(--radius-8);
  border: var(--border-1) solid transparent;
  font-family: inherit;
  cursor: pointer;
  transition: background var(--motion-fast) ease,
              border-color var(--motion-fast) ease,
              color var(--motion-fast) ease;
}

.tlacitko--hlavni {
  background: var(--action-primary-bg);
  color: var(--action-primary-text);
}

.tlacitko--hlavni:hover { background: var(--action-primary-bg-hover); }

/* Vedlejší: jen obrys. Po najetí obrys zmizí a plocha se vyplní
   do bílé (--action-link-hover). */
.tlacitko--vedlejsi {
  background: transparent;
  border-color: var(--border-default);
  color: var(--text-primary);
}

.tlacitko--vedlejsi:hover {
  border-color: transparent;
  background: var(--action-link-hover);
  color: var(--text-inverse);
}

.tlacitko:focus-visible { outline: var(--border-2) solid var(--state-focus-ring); }

/* ── Stavy ────────────────────────────────────────────────*/
/* Stavy. POZOR: alarm se NIKDY nekreslí jako holý barevný text —
   podle HANDOFF.md 1.2 musí být vždy vyplněný odznak s ikonou,
   jinak splyne s hodnotou spotřeby, která je také červená. */
.status-ok      { color: var(--status-ok); }
.status-warning { color: var(--status-warning); }
.status-offline { color: var(--status-offline); }

.alarm-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-8);
  border-radius: var(--radius-4);
  background: var(--status-danger);
  color: var(--text-on-accent);
}

/* ── Hlášky ───────────────────────────────────────────────*/
.banner {
  padding: var(--space-12) var(--space-16);
  border-radius: var(--radius-8);
  background: var(--bg-banner);
  color: var(--text-primary);
  box-shadow: var(--shadow-default);
}


/* Mřížka se na telefonu stáhne. Vnitřní odsazení modulu řeší
   --module-padding v tokens.css, tady se mění jen mezery mřížky. */
@media (max-width: 768px) {
  .module-grid {
    gap: var(--space-12);
    padding: var(--space-16);
  }
}

/* ── Popisek a vstup ──────────────────────────────────────
   Dvojice „popisek nad polem" je základní stavební kámen formulářů
   a používá ji správa i přihlašovací stránka. Do 17. 9. ležela
   v sprava.css — přihlášení ho ale nenačítá, takže tam pole zůstala
   v syrové podobě od prohlížeče. */
.pole {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.pole__popis { color: var(--text-secondary); padding: 0; }
.pole__napoveda { color: var(--text-secondary); }

.pole__vstup {
  padding: var(--space-12) var(--space-16);
  border: var(--border-1) solid var(--border-default);
  border-radius: var(--radius-8);
  background: var(--bg-control);
  color: var(--text-primary);
  font-family: inherit;
  width: 100%;
  min-width: 0;
  transition: border-color var(--motion-fast) ease;
}

.pole__vstup::placeholder { color: var(--text-secondary); }

/* ⚠️ ZAŠKRTÁVÁTKA A PŘEPÍNAČE MAJÍ NAŠI BARVU, NE SYSTÉMOVOU.
   Designér vlastní součástku nedodal (HANDOFF mluví o přepínačích
   jen jako o funkci), takže zůstávají nativní — ale nesmí svítit
   modrou od operačního systému uprostřed oranžovo-zelené aplikace.

   Do 20. 9. to bylo nastavené jen u dvou ze sedmi míst, každé
   zvlášť; zbytek byl systémový. Zjištěno při auditu odchylek. */
input[type="checkbox"],
input[type="radio"] { accent-color: var(--energy-battery); }
.pole__vstup:focus { outline: none; border-color: var(--state-focus-ring); }

/* Rozbalovačka ve formuláři se roztáhne přes celé pole. Ve sdílené
   podobě je to úzký ovladač do rohu modulu; ve formuláři stojí pod
   popiskem jako ostatní vstupy a šipka by jinak zůstala viset
   u pravého okraje sama pro sebe. */
.pole > .vyber-obal { align-self: stretch; }
.pole > .vyber-obal .vyber { width: 100%; }

/* ── Hlavička stránky ─────────────────────────────────────
   Název instalace nad mřížkou, jak to má návrh. */
/* Nadpis vlevo, hamburger vpravo. Na počítači je hamburger skrytý
   a řádek vypadá stejně jako dřív. */
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-16);
  padding: var(--space-24) var(--space-24) 0;
  color: var(--text-primary);
}

/* Flow energie je v návrhu vysoké přes dva moduly — vedle něj stojí
   Data Baterie a Analytika dne nad sebou. Mřížka to sama neudělá,
   musí se to říct. Platí jen tam, kde jsou dva sloupce. */
@media (min-width: 1340px) {
  .module-grid > .module--tall { grid-row: span 2; }
}

/* ═══════════════════════════════════════════════════════════
   OVLÁDACÍ PRVKY SEZNAMŮ

   Hledání a filtrovací pilulky. Používá je přehled instalací i
   alarmy, a používat je bude každý další seznam — proto jsou tady
   a ne u jedné z těch obrazovek. Kdyby si je každá kreslila sama,
   rozešly by se při první úpravě od designéra.
   ═══════════════════════════════════════════════════════════ */

/* ── Hledání ──────────────────────────────────────────────
   Tvar obrysové pilulky jako listování obdobím, aby to na stránce
   nebyl cizí prvek. */
.hledani {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-16);
  border: var(--border-1) solid var(--border-default);
  border-radius: var(--radius-8);
  background: var(--bg-control);
  color: var(--text-secondary);
  min-width: 240px;
  flex: 1 1 240px;
  max-width: 360px;
  transition: border-color var(--motion-fast) ease;
}

.hledani:focus-within { border-color: var(--state-focus-ring); }
.hledani__ikona { display: inline-flex; flex: none; }
.hledani__ikona .ikona { width: 16px; height: 16px; }

.hledani__pole {
  border: 0;
  background: none;
  color: var(--text-primary);
  font-family: inherit;
  width: 100%;
  min-width: 0;
  outline: none;
}

.hledani__pole::placeholder { color: var(--text-secondary); }

/* Křížek, kterým prohlížeč nabízí vymazání hledání, má v každém
   prohlížeči jinou barvu a v tmavém motivu mizí. Kreslíme si ho
   po svém přes ikonu, kterou už máme. */
.hledani__pole::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

/* ── Filtry stavu ─────────────────────────────────────────
   Týž tvar jako položky legendy v grafu — 12px odsazení, radius 16,
   vybraná má podbarvení. */
.filtry {
  display: flex;
  gap: var(--space-8);
  flex-wrap: wrap;
}

.filtr {
  padding: var(--space-8) var(--space-12);
  border: 0;
  border-radius: var(--radius-16);
  background: transparent;
  color: var(--text-secondary);
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--motion-fast) ease, color var(--motion-fast) ease;
}

.filtr:hover { background: var(--bg-hover); color: var(--text-primary); }
.filtr:focus-visible { outline: var(--border-2) solid var(--state-focus-ring); }

.filtr.is-selected {
  background: var(--state-selected);
  color: var(--text-primary);
}

/* ── Modální okno ─────────────────────────────────────────
   Návrh designéra, patch 4.0. Staví se na <dialog>, takže se tu
   neřeší ani pozicování na střed, ani vrstvení — prohlížeč kreslí
   dialog v „top layer", nad vším ostatním včetně panelu. */
.modal {
  width: min(720px, calc(100vw - var(--space-32)));
  padding: var(--space-32);
  border: 0;
  border-radius: var(--radius-24);
  /* Stejná plocha jako modul — v návrhu okno vypadá jako karta
     vytažená nad stránku. Plná barva je záloha pro přechod. */
  background: var(--bg-surface);
  background: var(--gradient-surface);
  color: var(--text-primary);
}

.modal::backdrop { background: var(--zavoj-modal); }

.modal__hlava {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-24);
}

.modal__nadpis { margin: 0; }

.modal__zavrit {
  flex: none;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-primary);
  cursor: pointer;
  transition: color var(--motion-fast) ease;
}
.modal__zavrit:hover { color: var(--text-secondary); }
.modal__zavrit:focus-visible {
  outline: var(--border-2) solid var(--state-focus-ring);
  border-radius: var(--radius-8);
}
.modal__zavrit .ikona { width: 19px; height: 19px; display: block; }

.modal__text {
  margin: var(--space-24) 0 0;
  color: var(--text-primary);
}

/* Tlačítka vpravo, hlavní jako poslední — v návrhu je „Zrušit"
   vlevo od „Požádat o změnu hesla". */
.modal__tlacitka {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-12);
  margin-top: var(--space-32);
}

/* Na úzké obrazovce tlačítka pod sebe — vedle sebe by se text
   „Požádat o změnu hesla" zalomil doprostřed slova. */
@media (max-width: 480px) {
  .modal { padding: var(--space-24); }
  .modal__tlacitka { flex-direction: column-reverse; }
  .modal__tlacitka .tlacitko { width: 100%; }
}


/* ── Jen pro čtečky ───────────────────────────────────────
   Popisek, který musí existovat pro odečítač obrazovky, ale
   vidět nemá být. Bydlí v base.css, protože ho potřebuje každá
   stránka — do 11. 9. ležel v sprava.css a na klientském
   Nastavení proto nefungoval. */
.sr-jen {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* ── Kostra: obrys toho, co se načítá ─────────────────────
   Petr 26. 9.: „načítat stránku a data do ní aktualizovat, až se
   data opravdu načtou… aplikace alespoň nemusí působit mrtvě."

   Do té doby uměly stránky prázdno nebo větu „Načítám…" uprostřed.
   Obojí vypadá stejně jako porucha — a u grafu dne se na to prázdno
   kouká 2,5 s (#88).

   Bydlí to v base.css, protože kostru potřebují i stránky, které
   nejsou moduly dashboardu (Přehled, Alarmy, Dohled). Podrobnosti
   a pravidla v jadro/kostra.js.

   Pulzování řeší `prefers-reduced-motion` v tokens.css globálně. */
.kostra {
  display: block;
  border-radius: var(--radius-8);
  /* `--bg-hover` je nejsvětlejší povrch, který má smysl v OBOU
     motivech: v tmavém se od karty odliší, ve světlém není bílá na
     bílé. Barvy z palety (neutral-…) se tu nepoužívají schválně —
     ty se mezi motivy nepřevracejí a kostra by v jednom zmizela. */
  background: var(--bg-hover);
  animation: kostra-puls 1.4s ease-in-out infinite;
}

/* ⚠️ Průhlednost, ne jiná barva. Kostra se kreslí uvnitř karet
   i na holé stránce a dvě různá pozadí by musela mít každé svůj
   odstín — jeden z nich by se pak ve světlém motivu ztratil. */
@keyframes kostra-puls {
  0%, 100% { opacity: 1; }
  50%      { opacity: .45; }
}

.kostra-skupina {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
}

/* Karty Přehledu. Šířka sloupce je táž jako u skutečných karet,
   aby se po načtení nic neposunulo. */
.kostra-mrizka {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: var(--space-24);
}

/* Plocha grafu — sloupce různé výšky stojící na společné základně.
   Výšku bere od rodiče (.graf), takže plátno po načtení nastoupí
   přesně na místo kostry a nic se neposune. */
.kostra-graf {
  position: absolute;
  inset: 0;
  /* ⚠️ Leží přes plátno, takže by jinak polykala kliknutí — chytil to
     hlídač v moduly.test.js. Je to jen obrázek, ne ovládání. */
  pointer-events: none;
  display: flex;
  align-items: flex-end;
  gap: var(--space-8);
  padding: var(--space-24) 0;
}

.kostra-graf .kostra {
  flex: 1 1 0;
  min-width: 0;
}
