    :root{
      /* Jednotka výšky okna kompenzovaná hustotou zobrazenia (density.css) —
         predvolene obyčajné vh/svh. */
      --vh:1vh; --svh:1svh;
      --bg:#eef1f8; --surface:rgba(255,255,255,.62); --surface-strong:rgba(255,255,255,.82);
      --stroke:rgba(255,255,255,.85); --ink:#1c2337; --ink-2:#5b6478; --ink-3:#636d85;
      /* `--ink-3` (tlmený text: menovky stĺpcov, čas pod dátumom, pätička) bol
         #8b93a8 — voči `--bg` 2,7:1 a voči panelu 2,9:1, teda pod normou 4,5:1
         pre bežný text. Ten istý odtieň (224°, sýtosť 14 %), len tmavší:
         4,6:1 voči `--bg`, 5,0:1 voči panelu, 5,2:1 voči bielej. */
      --teal:#0d9488; --indigo:#4f46e5; --amber:#b45309; --amber-soft:rgba(217,119,6,.14);
      --rose:#be123c; --rose-soft:rgba(225,29,72,.11); --green:#047857; --green-soft:rgba(16,185,129,.14);
      /* Svietiaca LED (živé hodnoty I/O): jasná zelená, NIE `--green` — tá je
         vo svetle tmavá a s jasom sivej sa zapnutý bod nedal rozoznať. Rovnaká
         v oboch témach (svieti aj na tmavom podklade). */
      --led-on:#22c55e; --led-on-line:#16a34a; --led-glow:rgba(34,197,94,.75);
      --led-halo:rgba(34,197,94,.22); --led-soft:rgba(34,197,94,.16);
      /* Výplň odznaku „prebieha" a zvýraznenej dropzone. V rodine `*-soft`
         chýbal jediný — a vtedajšia `rs_docs.css` ho používala BEZ náhradnej
         hodnoty (obrazovka dokumentov medzitým zanikla),
         takže odznak nemal vôbec žiadne pozadie (nedefinovaný token zahodí
         celú deklaráciu, nie len farbu). Hodnota je tá, ktorú už nesú
         náhradné hodnoty na ostatných miestach (alarms, shift_report),
         nech nevzniknú dva odtiene tej istej výplne. */
      --indigo-soft:rgba(99,102,241,.12);
      /* Doplnkové farby stĺpcov nástenky. Odstupy v odtieni sú zámerné —
         teal(175) a green(160) sú si už blízke, tak nové sedia do medzier:
         lime(85), sky(200), purple(272), fuchsia(292). Hnedá sa neujala — v odtieni
         splýva s amber a ako 16px bodka sa od nej nedá odlíšiť. */
      --lime:#4d7c0f; --sky:#0369a1; --purple:#7e22ce; --fuchsia:#a21caf;
      /* Dva medzistupne medzi `--amber` a `--rose`. Boli natvrdo (#c2410c
         v kvalite PLC tagov, #a16207 v horizonte objednávky) a tmavá téma
         ich nemala ako otočiť — text mal na tmavom podklade 2,1 a 2,9:1. */
      --orange:#c2410c; --yellow:#a16207;
      /* Safety (F) — žltá Siemens F-modulov: pruh na module v racku a značka
         F-modulu v prieskumníkovi TIA. Zlatšia než `--amber` (výstupy), aby sa
         pruh vpravo (safety) nepliesť s pruhom vľavo (druh modulu). */
      --safety:#ca8a04; --safety-soft:rgba(202,138,4,.16);
      --r:20px; --shadow:0 1px 2px rgba(28,35,55,.05),0 12px 32px -10px rgba(49,66,128,.16);
      --shadow-lift:0 2px 4px rgba(28,35,55,.06),0 20px 44px -12px rgba(49,66,128,.24);
      /* Veľkosti tlačidiel. Boli namerané pätnásť a nikto nevedel, ktorú si
         vybrať — najmenšia (4px/10px/.66rem) sedela na hlavnej akcii okna
         zdieľania. Tri stupne stačia; nové tlačidlo si vyberá z nich a NEMÁ
         mať vlastný `padding` ani `font-size`.
         Výšku drží `min-height`, nie zvislý padding: rovnaký padding dá pri
         inej veľkosti písma iné vysoké tlačidlo a vedľa seba v lište to
         potom „skáče". */
      --btn-h-lg:38px; --btn-px-lg:16px; --btn-fs-lg:.82rem;   /* hlavná akcia */
      --btn-h:32px;    --btn-px:13px;    --btn-fs:.76rem;      /* PREDVOLENÁ */
      --btn-h-sm:26px; --btn-px-sm:10px; --btn-fs-sm:.7rem;    /* husté lišty */
      --btn-r:10px;    --btn-r-sm:8px;
      /* Neutrálne podklady (chipy, jemné panely, .seg). Boli zapísané 156×
         natvrdo ako rgba(28,35,55,.0X) — na tmavom podklade z nich neostalo
         nič, takže dark.css ich musel prepisovať kus po kuse. Token to rieši
         na jednom mieste (dark variant je v dark.css). */
      --fill-1:rgba(28,35,55,.05); --fill-2:rgba(28,35,55,.07); --fill-3:rgba(28,35,55,.10);
      /* Vlasová čiara (mriežka tabuliek, orámovanie panelov, oddeľovače) a
         druhá, zapustená plocha pod vnorený panel. Oba tokeny sa v /v2
         používali od začiatku — ale definované NEBOLI. Nedefinovaný token vo
         `var()` bez náhrady nedá bledšiu čiaru, ale zahodí CELÚ deklaráciu:
         preto v tabuľkách DB/UDT/tagov nebola ani jedna čiara a panely
         simulácie a Watch nemali podklad. Váha vlasu sedí medzi podklad
         (`--fill-3` .10) a okraj ovládacieho prvku (`--btn-line` .16), takže
         mriežka je čitateľná a neprekričí tlačidlá; druhá plocha je o stupeň
         tichšia (.06 = domáci stupeň hoveru riadku). V tmavej téme sa oba
         otáčajú na biely prekryv, viď dark.css.
         Stráži to tests/test_v2_css_tokeny.py. */
      --line:rgba(28,35,55,.14); --surface-2:rgba(28,35,55,.06);
      /* Okraj `.ghost` tlačidiel. Hodnota tu bola len ako NÁHRADA vo
         `var(--btn-line,rgba(28,35,55,.16))` na štyroch miestach — token
         existoval iba v `dark.css`, takže svetlá téma ho nemala ako doladiť
         a tmavá ho nemala čo prepísať (prepisovala náhradu). */
      --btn-line:rgba(28,35,55,.16);
      /* Jemný tyrkysový podklad — v rodine `*-soft` chýbal ako jediný, hoci
         ho `tia_explorer` (zvýraznený riadok, zvýraznená sieť) používal
         BEZ definície, teda so zapísanou náhradou. */
      --teal-soft:rgba(20,184,166,.14);
      /* Plocha vstupného poľa. Vo svetlom je to `--surface-strong` (pole
         VYSTUPUJE), v tmavom `--d-field` (pole je ZAPUSTENÉ) — kto potrebuje
         nakresliť „takto vyzerá pole" (legenda výkazu hodín), siahne sem
         a nepíše si na to vlastné tmavé pravidlo. */
      --field-bg:rgba(255,255,255,.82);
      /* Trvalé varovanie `V2.warn` sa kreslí inline štýlom z `core.js`, takže
         token je jediný spôsob, ako doňho siahnuť. Tmavé hodnoty boli
         v `dark.css` od začiatku, svetlé ostali zapísané ako náhrada v JS. */
      --warn-bg:#fff5f5; --warn-ink:#9f1239; --warn-line:#fecdd3;
      /* Farba štítka nástenky. NIE je to farba témy: šablóna ju dosadzuje
         inline cez `:style` z `labelColor(l)`, tu je len predvolená hodnota
         pre štítok bez farby. POZOR: v komentároch vnútri `:root` nesmie
         byť zložená zátvorka — guard testy čítajú blok po prvú z nich. */
      --lbl:var(--ink-3);
      /* Okraje sfarbených plôch (bannery, karty pending/on) — doteraz 8×
         hardcoded rgba(...,.35/.4). Výplň má token (`*-soft`), okraj nie. */
      --green-line:rgba(16,185,129,.35); --rose-line:rgba(225,29,72,.4); --amber-line:rgba(217,119,6,.4);
      /* Doplnené k tej istej rodine kvôli chipom pripnutého kontextu Copilota
         (projekt indigo, PLC tyrkys) — okraj sfarbenej plochy musí byť token,
         inak sa v tmavej téme nedá prebiť. */
      --indigo-line:rgba(79,70,229,.35); --teal-line:rgba(13,148,136,.35);
      /* Radius kariet a panelov — bol 16px v 12 súboroch. */
      --card-r:16px;
      /* Ovládacie prvky: polia, rozbaľovacie zoznamy, zaškrtávacie polia
         a prepínače zap/vyp. Rovnaká úvaha ako pri tlačidlách — namerané
         bolo PÄŤ nezávislých definícií toho istého poľa (.us-f, .sc-f,
         .wf-f, .mv-f, .md-f), zakaždým s vlastným paddingom a zaoblením.

         `--fld-h` je ZÁMERNE tá istá hodnota ako `--btn-h-lg`: pole a
         tlačidlo stoja v lište vedľa seba a pri rozdiele dvoch pixelov
         riadok viditeľne „skáče".

         `--fld-fs` je 16px a NESMIE klesnúť. Pod 16 px iOS Safari pri
         zaostrení poľa priblíži celú stránku — a späť ju už nevráti.
         Preto tu NIE JE menší stupeň písma, len menší stupeň výšky. */
      --fld-h:38px;    --fld-px:12px;    --fld-r:12px;    /* PREDVOLENÉ pole */
      --fld-h-sm:32px; --fld-px-sm:10px; --fld-r-sm:10px; /* bunky, ponuky */
      --fld-fs:16px;
      /* Vyhľadávacie pole má vľavo lupu a vpravo krížik na zmazanie. Odsadenie
         musí byť na oboch stranách rovnaké, inak text pri písaní „ujde". */
      --fld-px-ico:34px;
      --chk:17px;                   /* zaškrtávacie pole */
      --sw-w:38px; --sw-h:22px;     /* prepínač zap/vyp */
      /* Škála rádiusov (2026-08-23, plátno „Dizajnový systém CMS"): 190+ zápisov
         mimo škály v 40 súboroch — 11, 13, 15, 17, 18, 28 px podľa nálady. Odteraz
         má každý rádius meno a hodnotu zo škály 10 · 12 · 14 · 16 · 20 · 24 · 26 · 999:
           --btn-r 10 tlačidlo/ikonové · --r-sm 12 box, pole, dlaždica v zásuvke ·
           --r-menu 14 prepínač .seg, ponuka .dd-panel, toast · --card-r 16 karta,
           lišta · --r 20 panel, dlaždica KPI · --r-modal 24 modál · 26 rail · 999 pilulka.
         Stráži to tests/test_v2_design_scale.py. */
      --r-sm:12px; --r-menu:14px; --r-modal:24px;
      /* Neutrálny prekryv pod hover riadku/ikony (.04) a vlas (.08) — dva stupne,
         ktoré v rodine --fill-*/--line chýbali, takže sa písali natvrdo (300+ zápisov
         rgba(28,35,55,.0X)). Tmavá téma ich otáča na biely prekryv v dark.css. */
      --hover:rgba(28,35,55,.04); --line-soft:rgba(28,35,55,.08);
      /* Hover riadku v tabuľke — tyrkysový nádych, nie neutrálny: riadok
         pod myšou má vyzerať ako vybraný, nie ako zašednutý. Bol trikrát
         natvrdo (analytics, stock, users) a v tme sa nemal na čo otočiť. */
      --hover-row:rgba(13,148,136,.04);
      /* Krycia plocha modálu, zásuvky, lišty — takmer nepriehľadná, aby pod ňou
         nepresvital obsah; v tme rgba(24,31,46,.97) (dark.css). */
      --cover:rgba(247,249,253,.98);
      /* Písmo NA vyplnenej akcentovej ploche (odznak, plná pilulka, vybraná
         záložka, nebezpečné tlačidlo). V svetlej téme je akcent sýty (rose 700,
         amber 700…) a biely text na ňom má kontrast nad 5:1. V tmavej sa akcenty
         posúvajú na 400-ky — biele písmo na `--amber` má potom 1,5:1 a číslo
         v odznaku sa NEDÁ prečítať. Preto sa v tme otáča na tmavý atrament.
         Nepatrí sem text na GRADIENTE značky: ten je v oboch témach rovnaký,
         a teda aj jeho písmo ostáva biele. */
      --on-accent:#fff;
      /* Gradient značky — logo, hlavná akcia, zapnutý chip. ZÁMERNE rovnaký v oboch
         témach (dark.css ho neprepisuje): je to identita, nie farba povrchu. Preto
         token a nie var(--teal)/var(--indigo), ktoré sa v tme posúvajú. */
      --grad:linear-gradient(135deg,#0d9488,#4f46e5);
      --grad-soft:linear-gradient(135deg,rgba(20,184,166,.18),rgba(79,70,229,.18));
      --font:'Plus Jakarta Sans',ui-sans-serif,system-ui,'Segoe UI',Helvetica,Arial,sans-serif;
    }
    *{box-sizing:border-box;margin:0;padding:0}
    html{font-size:16px;-webkit-text-size-adjust:100%;text-size-adjust:100%}
    /* `text-size-adjust` vypína „text autosizing" Mobile Safari: v širokom
       obsahu (tabuľka v posuvnom ráme) Safari sám zväčšil písmo dlhého
       textu — v Prehliadači projektov bola veta skupiny verzií dvakrát
       väčšia než zvyšok a odrezaná (iOS Simulator, iPhone 17, 2026-10-01).
       Playwright WebKit to nerobí, preto to videl až simulátor. Priblíženie
       prstami ostáva — to rieši viewport, nie toto. */
    /* Pozadie patrí aj html, nie len body: pri pružnom dorolovaní na iOS sa
       pod stránkou inak ukáže holý biely/šedý pás. */
    html{background:var(--bg)}
    body{font-family:var(--font);background:var(--bg);color:var(--ink);
      /* 100vh je na iOS VEĽKÝ viewport (ako keby lišty neboli), takže stránka
         vyjde vyššia než viditeľná plocha a dá sa odrolovať do prázdna.
         100svh = malý viewport, ktorý je stabilný a nikdy nie je väčší. */
      min-height:100vh;min-height:100svh;
      overscroll-behavior-y:none;
      -webkit-font-smoothing:antialiased;font-variant-numeric:tabular-nums}
    body::before{content:"";position:fixed;inset:0;z-index:-2;background:
      radial-gradient(900px 620px at 12% -8%, rgba(45,212,191,.20), transparent 60%),
      radial-gradient(1000px 700px at 88% 4%, rgba(99,102,241,.16), transparent 62%),
      radial-gradient(820px 640px at 78% 96%, rgba(251,113,133,.13), transparent 58%),
      radial-gradient(700px 520px at 6% 88%, rgba(45,212,191,.10), transparent 60%), var(--bg)}
    body::after{content:"";position:fixed;inset:0;z-index:-1;opacity:.5;pointer-events:none;
      background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 0.4 0 0 0 0 0.42 0 0 0 0 0.5 0 0 0 .05 0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E")}
    a{color:inherit;text-decoration:none}
    button{font-family:inherit}
    input,select{font-family:inherit}
    :focus-visible{outline:2px solid var(--teal);outline-offset:2px;border-radius:10px}
    /* v-cloak MUSÍ poraziť #app{display:flex} nižšie: ID selektor (1,0,0)
       prebíjal atribútový (0,1,0), takže cloak NIKDY nefungoval a pred
       mountom Vue preblikla surová šablóna — vrátane modal-back overlayov
       („modal na sekundu, potom stránka", hlásené 2026-08-10). ID+atribút
       + !important, nech ho neprebije ani žiadne budúce stránkové pravidlo. */
    [v-cloak], #app[v-cloak]{display:none!important}

    .rail{position:fixed;top:16px;left:16px;bottom:16px;width:72px;z-index:50;
      background:var(--surface-strong);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
      border:1px solid var(--stroke);border-radius:26px;box-shadow:var(--shadow);
      display:flex;flex-direction:column;align-items:center;padding:14px 0;gap:4px}
    .rail .logo{width:44px;height:44px;border-radius:var(--card-r);display:grid;place-items:center;color:#fff;
      background:var(--grad);box-shadow:0 8px 18px -6px rgba(79,70,229,.45);margin-bottom:10px;flex:none}
    .rail .logo svg{width:24px;height:24px}
    /* Zoznam ROLUJE. Bez toho položky nad 900 px šírky len prerástli svoj box:
       zmrštili sa pod svojich 46 px a ikony si sadli na seba. `margin-bottom`
       drží slot pre zvonček alarmov, ktorý visí napevno v `body` (do railu ho
       dať nemožno — na mobile sa rail posúva `transform`om a odsunul by sa
       s ním). Päta (Profil) je mimo `nav`, takže dno nezávisí od dĺžky zoznamu. */
    .rail nav{display:flex;flex-direction:column;gap:4px;align-items:center;flex:1;width:100%;
      min-height:0;overflow-y:auto;overscroll-behavior:contain;margin-bottom:52px;
      scrollbar-width:none}
    .rail nav::-webkit-scrollbar{width:0;height:0}
    .rail-item{flex:none}
    /* Profil drží dno railu — patrí k účtu, nie k obsahu. Je to `.rail-foot`
       MIMO rolovacieho zoznamu, takže dno nezávisí od toho, koľko je položiek.
       Zvonček alarmov sedí tesne nad ním (slot mu drží `margin-bottom` na nav). */
    .rail-foot{flex:none;margin-top:0}
    .rail-item{position:relative;width:46px;height:46px;border-radius:var(--card-r);display:grid;place-items:center;
      color:var(--ink-2);transition:background .15s,color .15s,transform .15s}
    .rail-item:hover{background:var(--fill-2);color:var(--ink);transform:translateY(-1px)}
    .rail-item[aria-current="page"]{background:var(--grad-soft);
      color:var(--indigo);box-shadow:inset 0 0 0 1px rgba(79,70,229,.25)}
    .rail-item[aria-current="page"]::before{content:"";position:absolute;left:-14px;width:4px;height:22px;
      border-radius:4px;background:linear-gradient(180deg,#14b8a6,#4f46e5)}
    .rail-item svg{width:22px;height:22px}
    .tip{position:absolute;left:58px;top:50%;transform:translateY(-50%) translateX(-6px);
      background:rgba(23,29,48,.94);color:#fff;border-radius:12px;padding:8px 12px;
      opacity:0;pointer-events:none;transition:opacity .15s,transform .15s;white-space:nowrap;
      font-size:.76rem;font-weight:700;box-shadow:0 12px 28px -8px rgba(23,29,48,.5);z-index:60}
    .tip::before{content:"";position:absolute;left:-4px;top:50%;transform:translateY(-50%) rotate(45deg);
      width:9px;height:9px;background:rgba(23,29,48,.94);border-radius:2px}
    .rail-item:hover .tip,.rail-item:focus-visible .tip{opacity:1;transform:translateY(-50%) translateX(0)}
    /* Zvonček alarmov je mimo Vue (core.js), ale popisok má mať rovnaký. */
    .ab-btn:hover .tip,.ab-btn:focus-visible .tip{opacity:1;transform:translateY(-50%) translateX(0)}

    /* ── Sekcia s podmenu (napr. PLC) ── */
    .rail-group{position:relative;width:100%;display:grid;place-items:center}
    .rail-group>.rail-item{border:0;background:transparent;cursor:pointer;font-family:inherit;padding:0}
    /* bodka = „táto položka sa rozbaľuje" */
    .rail-dot{position:absolute;right:6px;bottom:6px;width:4px;height:4px;border-radius:50%;
      background:var(--ink-3);opacity:.55}
    .rail-group.open .rail-dot,.rail-group>.rail-item[aria-current="page"] .rail-dot{background:var(--indigo);opacity:1}
    /* Panel vysunutý vedľa railu. Otvára sa klikom (dotykové zariadenia v hale),
       preto nie :hover. Tooltip pri otvorenom paneli prekáža → skryť. */
    /* Panel je vysunutý NAD obsah stránky, nie vedľa neho — pri priehľadnosti
       railu (.82) sa cezeň dali čítať nadpisy a čísla pod ním a položky menu
       sa v tom strácali. Popover musí byť krycí; priehľadnosť patrí plochám,
       ktoré nič neprekrývajú. */
    .rail-sub{display:none;position:absolute;left:56px;top:-6px;z-index:70;min-width:196px;
      padding:8px;border-radius:16px;background:rgba(255,255,255,.97);
      backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
      border:1px solid var(--stroke);box-shadow:0 18px 38px -12px rgba(28,35,55,.35)}
    .rail-group.open .rail-sub{display:block}
    .rail-group.open .tip{display:none}
    .rail-sub-cap{font-size:.6rem;font-weight:800;letter-spacing:.07em;text-transform:uppercase;
      color:var(--ink-3);padding:2px 9px 6px}
    .rail-sub-item{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:10px;
      font-size:.79rem;font-weight:600;color:var(--ink-2);white-space:nowrap;transition:background .12s}
    /* Nie každá podpoložka je odkaz — voľby vzhľadu sú `<button>`, lebo prepínajú
       stav, nikam nevedú. Prehliadač im dá vlastný rámik, pozadie aj zarovnanie,
       takže reset potrebujú; ROZMERY si ale brať NESMÚ (docs/v2-controls.md).
       Práve tie prišli s inline `style="font:inherit"`, ktorý core.js písal
       priamo do tlačidla: inline prebije triedu, a skratka `font` zhodí naraz
       veľkosť, hrúbku aj riadkovanie — Vzhľad tak stál väčším písmom než „Môj
       profil" o riadok vyššie. Preto len tie vlastnosti, ktoré sú naozaj reset,
       a riadkovanie sa berie z dokumentu ako pri odkazoch. */
    button.rail-sub-item{width:100%;border:0;background:transparent;cursor:pointer;
      text-align:left;line-height:inherit}
    .rail-sub-item:hover{background:var(--fill-2);color:var(--ink)}
    /* Vnorená položka (PLC › Prehľad › Projekty) — odsadená a s čiarou
       vľavo, aby sa čítala ako časť položky nad ňou, nie ako ďalšia sekcia. */
    .rail-sub-item.rail-sub-nest{margin-left:18px;padding-left:10px;position:relative}
    .rail-sub-item.rail-sub-nest::before{content:"";position:absolute;left:-8px;top:6px;bottom:6px;
      width:2px;border-radius:2px;background:var(--line)}
    .rail-sub-item[aria-current="page"]{background:linear-gradient(135deg,rgba(20,184,166,.16),rgba(79,70,229,.16));
      color:var(--indigo);font-weight:800}
    /* Ikona podpoložky je menšia a tlmenejšia než v hlavnej úrovni — má riadok
       pomôcť nájsť periférnym videním, nie súperiť so sekciou o pozornosť.
       `flex:none` + pevná šírka drží texty zarovnané pod sebou aj vtedy, keď
       niektorá položka ikonu nemá. */
    .rail-sub-ic{flex:none;width:16px;height:16px;display:grid;place-items:center;opacity:.55}
    .rail-sub-ic svg{width:16px;height:16px}
    .rail-sub-item:hover .rail-sub-ic{opacity:.8}
    .rail-sub-item[aria-current="page"] .rail-sub-ic{opacity:1}
    /* Odznak „klasika" — položka railu, ktorá otvára klasické rozhranie
       (nezmigrovaná stránka). Zámerne tlmený obrys z currentColor: funguje
       vo svetlej aj tmavej téme bez vlastného override a nesúperí s textom —
       má len ticho povedať „toto ťa vezme mimo /v2". `margin-left:auto` ho
       sadí k pravému okraju panela, nech texty položiek ostanú zarovnané. */
    .rail-classic{flex:none;margin-left:auto;padding:2px 5px;border-radius:6px;
      border:1px solid currentColor;font-size:.5rem;font-weight:800;
      letter-spacing:.08em;text-transform:uppercase;line-height:1;opacity:.45}
    .rail-sub-item:hover .rail-classic{opacity:.7}
    /* Odhlásenie — posledná položka podmenu Profilu. Jemná čiara ju oddelí od
       Vzhľadu/Inštalácie nad ňou (bežná konvencia profilových menu: účet vs.
       nastavenia appky), nie vlastná farba — je to bežná akcia, nie varovanie.
       `--btn-line`, nie `--stroke`: `--stroke` je vo svetlom režime takmer
       biela (glass okraj kariet) a na rovnako bielom podmenu by splynula,
       presne ako pri `.ghost` vyššie. */
    .rail-sub-logout{margin-top:6px;padding-top:9px;
      border-top:1px solid var(--btn-line)}
    /* ── Podmenu v podmenu: Profil › Vzhľad (téma) a Profil › Jazyk ──
       Dve súrodenecké skupiny, pravidlá nižšie platia pre obe rovnako.
       Panel volieb je tiež `.rail-sub` (vzhľad aj tmavú variantu dedí), takže
       ho pravidlo „otvorená sekcia ukáže svoj panel" ukáže hneď s Profilom.
       Toto ho drží zavretý, kým sa neotvorí jeho vlastná skupina. Polohu
       vysunutého panela počíta core.js (`_umiestniPodpodmenu`) — preto ani
       tu nie je `:hover`. */
    .rail-group.open .rail-subgroup:not(.open)>.rail-sub{display:none}
    .rail-sub-chev{flex:none;margin-left:auto;display:grid;place-items:center;
      opacity:.45;transition:transform .15s}
    .rail-subgroup.open>.rail-sub-more{background:var(--fill-2);color:var(--ink)}
    .rail-subgroup.open>.rail-sub-more .rail-sub-chev{opacity:.8}
    .rail-sub-2{min-width:200px}
    /* Rozbalené V TOKU (zásuvka na telefóne, alebo Profil vyšší než
       obrazovka, ktorý roluje a vysunutý panel by orezal): voľby sú odsadené
       pod rozbaľovačom s čiarou vľavo ako vnorené položky PLC, šípka sa
       otočí nadol. Popisok nad voľbami netreba — Vzhľad a Jazyk sú dve
       skupiny, každú pomenúva jej rozbaľovač priamo nad ňou, a otvorená je
       vždy len jedna (core.js `_otvorPodpodmenu`). */
    .rail-subgroup.inline>.rail-sub{position:static;min-width:0;width:auto;box-shadow:none;
      background:transparent;border:0;border-radius:0;backdrop-filter:none;
      -webkit-backdrop-filter:none;margin:2px 0 4px 17px;padding:0 0 0 7px;
      border-left:2px solid var(--line)}
    .rail-subgroup.inline.open>.rail-sub-more .rail-sub-chev{transform:rotate(90deg)}
    /* Značka jazyka v slote ikony: dve písmená (SK, EN) namiesto vlajky —
       vlajka je štát, nie jazyk. Krúžok témy (.theme-sw, 12 px) dostane
       okraj na šírku slotu ikony (16 px), aby texty volieb začínali pod
       textom rozbaľovača a ostatných položiek Profilu. */
    .lang-sw{font-size:.56rem;font-weight:800;letter-spacing:.02em;line-height:1}
    .rail-sub-2 .theme-sw{margin:0 2px}
    /* Hustota zobrazenia v paneli Vzhľadu: popisok skupiny a číslo v slote
       ikony (90, 80) — rovnaký princíp ako SK/EN pri jazyku. */
    .rail-sub-dcap{margin:8px 10px 2px;padding-top:8px;border-top:1px solid var(--line);
      font-size:.62rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
    .density-sw{font-size:.56rem;font-weight:800;line-height:1}

    /* rail right edge = 16+72 = 88px; content starts at margin+padding-left
       (79+24) = 103px → gap k widgetom = 15px = bento gap. */
    /* Pätka má sadnúť na spodok obrazovky aj vtedy, keď je obsahu málo
       (napr. nástenka s jedným stĺpcom) — preto stĺpcový layout a `margin-top:auto`
       na pätke. Pri dlhej stránke normálne odscrolluje na koniec obsahu. */
    #app{display:flex;flex-direction:column;min-height:100vh;min-height:100svh}
    .main{margin-left:79px;max-width:2400px;padding:22px 24px 0;
      flex:1;display:flex;flex-direction:column}
    .topbar{display:flex;align-items:center;gap:12px;margin-bottom:24px;flex-wrap:wrap}
    .topbar h1{font-size:1.85rem;font-weight:800;letter-spacing:-.02em;display:flex;align-items:center;gap:12px}
    .topbar .sub{color:var(--ink-2);font-size:.9rem;margin-top:5px;font-weight:500}
    .topbar .spacer{flex:1}
    /* Odznak stavu — malá pilulka so slovom („hotové", „chyba", „ERROR",
       „čaká na aktiváciu"). Vzor bol napísaný 31× (70 pravidiel s
       `border-radius:999px`) a samotná dvojica farieb
       `background:var(--X-soft);color:var(--X)` stála v 19 súboroch 81×.
       Odteraz `.badge` + tón: ok · warn · bad/err · info · mute.

       `.badge` tu BOL — ale ako biely nápis na gradiente značky a bez
       jediného tónu, hoci `tia_analysis`, `tia_explorer` a `plc_tia` mu
       `ok`/`err` v šablóne dávali (`anaBadge()`). Tie triedy nemali kde
       zabrať, takže „hotové" aj „chyba" svietili rovnako. */
    .badge{display:inline-block;padding:2px 8px;border-radius:999px;
      font-size:.63rem;font-weight:800;letter-spacing:.02em;line-height:1.5;
      white-space:nowrap;background:var(--fill-2);color:var(--ink-2)}
    .badge.ok{background:var(--green-soft);color:var(--green)}
    .badge.warn{background:var(--amber-soft);color:var(--amber)}
    .badge.bad,.badge.err{background:var(--rose-soft);color:var(--rose)}
    .badge.info{background:var(--indigo-soft);color:var(--indigo)}
    .badge.mute{background:var(--fill-2);color:var(--ink-3)}
    /* Kľúčové slovo z počítača (úroveň záznamu, stav agenta) — VEĽKÝMI. */
    .badge.caps{text-transform:uppercase;letter-spacing:.04em}
    /* ODHAD („odhad · 88" pri väzbe, ktorú vypočítal stroj a nikto ju
       nepotvrdil) — šrafovaný a s prerušovaným rámom, aby nikdy nevyzeral
       ako fakt (docs/research/jeden-strom-prepojeni.md, kap. 5). Tóny zo
       stavu by klamali: odhad nie je ani „ok", ani „chyba". */
    .badge.est{color:var(--ink-2);border:1px dashed var(--line);
      background:repeating-linear-gradient(135deg,var(--fill-2) 0 3px,transparent 3px 6px)}
    .seg{display:flex;flex-wrap:wrap;gap:2px;background:var(--fill-2);border:1px solid rgba(255,255,255,.7);
      border-radius:14px;padding:3px;backdrop-filter:blur(12px)}
    /* 3 px obal + tlačidlo veľkosti md = presne --btn-h-lg, takže je prepínač
       rovnako vysoký ako .ghost, ktorý stojí v lište vedľa neho. */
    /* `a` v prepínači = prepnutie na INÚ STRÁNKU (Výroba ↔ Cykly): vzhľad
       ako tlačidlo pohľadu, ale ide o navigáciu (2026-09-14). */
    .seg button,.seg a{border:0;background:transparent;cursor:pointer;
      display:inline-flex;align-items:center;justify-content:center;
      min-height:var(--btn-h);padding:0 var(--btn-px);border-radius:var(--btn-r);
      font-size:var(--btn-fs);font-weight:600;color:var(--ink-2);transition:.15s;
      text-decoration:none}
    .seg button:hover,.seg a:hover{color:var(--ink)}
    .seg button.active,.seg a.active{background:#fff;color:var(--ink);box-shadow:0 2px 8px rgba(28,35,55,.12)}
    /* ── Obnovovanie stránky ──────────────────────────────────────────────
       Ovládač `<refresh-every>` z core.js: popisok REFRESH EVERY a prepínač
       Off · 15 s · 30 s · 60 s. Je to `.seg` ako všade inde — `.rf-seg` mu
       len dáva hustú veľkosť, lebo stojí v lište vedľa chipov a filtrov,
       nie sám. Pred zjednotením mala každá PLC stránka vlastnú podobu
       (prepínač / `.ghost-sel` / `select` v ponuke „Viac"). */
    .rf{display:inline-flex;align-items:center;gap:8px;flex:none}
    /* Menovka ovládača, nie veta: tlmená a malými kapitálkami ako `.lbl`. */
    .rf-lbl{font-size:.66rem;font-weight:800;letter-spacing:.05em;text-transform:uppercase;
      color:var(--ink-3);white-space:nowrap}
    .rf-seg{padding:2px}
    /* `min-width`: štyri možnosti majú rôzne dlhé popisky („Off" vs. „60 s")
       a v inom jazyku sa dĺžky posunú znova. Rovnako široké tlačidlá držia
       šírku celého ovládača NEMENNÚ, takže sa ním nikdy nepohne to, čo stojí
       vedľa (Roman 2026-09-07: „keď sa načítava, tlačidlá skáču"). */
    .rf-seg button{min-height:var(--btn-h-sm);min-width:40px;
      padding:0 var(--btn-px-sm);font-size:var(--btn-fs-sm)}

    /* ── Nová hlavička stránky (vlna 1, docs/v2-design-system.md) ──────────
       `templates/v2/_page_head.html` + `<global-search>`/`<refresh-chip>`/
       `<source-switch>`/`<hdr-menu>` (static/js/v2/core.js). Riadok 1 je
       TROJSTĹPCOVÁ mriežka — bočné stĺpce sú ROVNAKO ŠIRŠOKÉ, takže hľadanie
       v strede je vždy presne v strede, nech je nadpis akokoľvek dlhý alebo
       akcií akokoľvek málo. Pravý stĺpec sa pri nedostatku miesta skráti
       (`min-width:0`), NIKDY nevytlačí hľadanie zo stredu. */
    .ph{display:grid;grid-template-columns:minmax(0,1fr) clamp(240px,34%,480px) minmax(0,1fr);
      align-items:center;gap:14px}
    .ph-title{display:flex;align-items:center;gap:10px;min-width:0}
    .ph-title>div{min-width:0}
    .ph-title h3{margin:0;font-size:1.55rem;font-weight:800;letter-spacing:-.02em;
      line-height:1.2;display:flex;align-items:center;gap:10px;min-width:0}
    /* Nadpis sa ZALAMUJE na dva riadky, až potom „…". V jednom riadku sa na PC
       skracovala samotná identita stránky — číslo kusu na karte RS
       („AC-AngleDrive-BCV-BL-…"), meno zálohy robota (audit pretekania
       2026-10-12). Celé znenie je aj v `title`. */
    .ph-title h3 .t{white-space:normal;display:-webkit-box;-webkit-box-orient:vertical;
      -webkit-line-clamp:2;line-clamp:2;overflow:hidden;overflow-wrap:anywhere}
    /* Podnadpis sa ZALAMUJE, najviac na dva riadky (na telefóne tri) —
       jednoriadkový s „…" sa na telefóne nedal dočítať (Pracovný čas, Výroba).
       Čo sa nezmestí ani tak, je celé v `title` (šablóna `_page_head.html`). */
    .ph-title .sub{color:var(--ink-2);font-size:.86rem;font-weight:500;margin-top:3px;
      display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;
      overflow:hidden;overflow-wrap:anywhere}
    .ph-act{grid-column:3;display:flex;justify-content:flex-end;align-items:center;
      gap:8px;flex-wrap:wrap;min-width:0}
    .ph-act .btn-add{flex:none}
    .ph-row2{display:flex;align-items:center;gap:10px;margin-top:14px;flex-wrap:wrap}
    /* Odstup hlavičky od obsahu — ten istý, aký mala stará `.topbar`
       (margin-bottom:24px). Nesie ho POSLEDNÝ riadok hlavičky: bez druhého
       riadku `.ph`, s ním `.ph-row2` (inak by sa filtre a karty lepili
       priamo na prepínač — Nástenka 2026-09-27). */
    .ph{margin-bottom:24px}
    .ph:has(+ .ph-row2){margin-bottom:0}
    .ph-row2{margin-bottom:24px}
    .ph-row2 .rf-chip-wrap{margin-left:auto}
    .ph-row2-end{margin-left:auto;display:flex;align-items:center;gap:8px}
    /* Ovládač pre CELÚ stránku vľavo v 2. riadku (`row2_start`) — môže sa
       zalomiť, čip obnovy ostáva vpravo (`margin-left:auto` vyššie). */
    .ph-row2-start{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
    .ph-row2-end+.rf-chip-wrap,.ph-row2-end+refresh-chip{margin-left:0}
    /* Pás pohľadov a zdroja (`.ph-strip`, _page_head.html) na PC nie je — jeho
       deti sú položkami riadku ako predtým. Ponuka „Viac pohľadov" je
       v šablóne až za pásom (na telefóne by jej panel posuvný pás orezal),
       `order` jej vracia miesto medzi pohľadmi a zdrojom. Rovnaký vzor ako
       `.pd-tabstrip` (plc.css). */
    .ph-strip{display:contents}
    .ph-strip>.src-seg{order:1}
    .ph-row2>.ph-row2-end,.ph-row2>.rf-chip-wrap{order:2}
    /* Ponuka „Viac" s vedľajšou akciou (`.ph-mob`) je len pre telefón — tam
       sú samostatné tlačidlá `.ph-pc` skryté (`_page_head.html`). */
    .dd-btn.ph-mob,.ph-act>.ph-mob{display:none}

    /* ── Globálne hľadanie (`<global-search>`) — VŽDY v strede, VŽDY jedno.
       `.srch .srch-ic` prichádza AŽ ZA `.iconbtn` (breakdowns.css, načíta sa
       za dashboard.css) — vyššia špecifickosť (dve triedy) drží poradie
       zobraz./skry aj keby sa súbory zoradili inak. */
    .srch{grid-column:2;position:relative;justify-self:stretch}
    /* Lupa má VLASTNÝ vzhľad — `.iconbtn` je v breakdowns.css a ten nenačítava
       každá stránka (Nástenka: holý biely štvorec, iPhone 2026-09-27). */
    .srch .srch-ic{display:none;place-items:center;width:var(--btn-h-lg);height:var(--btn-h-lg);
      padding:0;border-radius:var(--btn-r);border:1px solid var(--line);background:var(--surface);
      color:var(--ink-2);cursor:pointer}
    .srch .srch-ic:hover{color:var(--ink);background:var(--hover)}
    .srch .srch-ic:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
    .srch .srch-ic .icn{display:inline-grid;place-items:center}
    .srch .srch-ic .icn svg{width:17px;height:17px}
    .srch-box{display:flex;align-items:center;gap:9px;height:var(--btn-h-lg);
      padding:0 10px 0 13px;border-radius:var(--btn-r);border:1px solid var(--stroke);
      background:var(--surface-strong);box-shadow:var(--shadow);color:var(--ink-3);
      cursor:text;transition:border-color .15s,box-shadow .15s}
    .srch-box .icn{color:var(--ink-3)}
    .srch-box .icn svg{width:16px;height:16px}
    .srch-box input{flex:1;min-width:0;border:0;background:transparent;color:var(--ink);
      font:600 .86rem var(--font);outline:none}
    .srch-box input::placeholder{color:var(--ink-3);font-weight:500}
    .srch-box:focus-within{border-color:color-mix(in srgb,var(--teal) 55%,transparent);
      box-shadow:0 0 0 4px var(--teal-soft)}
    .srch-box kbd{font:600 .68rem/1 var(--font);color:var(--ink-2);border:1px solid var(--line-soft);
      border-radius:6px;padding:3px 6px;background:var(--fill-2);white-space:nowrap}
    /* Paleta výsledkov. */
    .pal{position:absolute;left:0;right:0;top:calc(100% + 8px);z-index:60;
      background:var(--surface-strong);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
      border:1px solid var(--stroke);border-radius:var(--r-menu);box-shadow:var(--shadow-lift);
      padding:8px;text-align:left;max-height:min(70vh,520px);overflow-y:auto}
    .pal-scope{display:flex;gap:6px;padding:2px 6px 8px;flex-wrap:wrap;
      border-bottom:1px solid var(--line-soft);margin-bottom:6px}
    .chip{font:600 .74rem var(--font);border:1px solid var(--line-soft);color:var(--ink-2);
      border-radius:999px;padding:4px 10px;background:transparent;cursor:pointer}
    .chip:hover{background:var(--fill-2);color:var(--ink)}
    .chip[aria-pressed="true"]{background:var(--teal-soft);border-color:transparent;color:var(--teal)}
    .pal .grp{font:700 .66rem/1 var(--font);letter-spacing:.08em;text-transform:uppercase;
      color:var(--ink-3);padding:10px 8px 6px}
    .pal .res{display:grid;grid-template-columns:26px minmax(0,1fr) auto;gap:10px;
      align-items:center;padding:8px 8px;border-radius:10px;cursor:pointer}
    .pal .res:hover,.pal .res.on{background:var(--fill-2)}
    .pal .res .ic{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;
      background:var(--fill-2);color:var(--ink-2);font-size:.72rem;font-weight:800;flex:none}
    .pal .res.here .ic{background:var(--teal-soft);color:var(--teal)}
    .pal .res .nm{font-weight:600;font-size:.86rem;color:var(--ink);white-space:nowrap;
      overflow:hidden;text-overflow:ellipsis}
    .pal .res .ds{color:var(--ink-3);font-size:.74rem;white-space:nowrap;overflow:hidden;
      text-overflow:ellipsis}
    .pal .res .meta{font-size:.68rem;font-weight:700;color:var(--ink-3);white-space:nowrap;
      text-transform:uppercase;letter-spacing:.03em}
    .pal-msg{padding:18px 10px;text-align:center;color:var(--ink-3);font-size:.82rem}
    /* Skupiny výsledkov jemne odlíšené farbou (Roman 2026-09-29) — odtieň
       len podkladu, text ostáva v bežných farbách, aby kontrast nezávisel od
       skupiny. `color-mix` s priehľadnou → funguje v svetlej aj tmavej téme. */
    .pal-g{border-radius:12px;padding:0 4px 4px;margin-top:6px;
      background:color-mix(in srgb,var(--pal-g,transparent) 7%,transparent)}
    .pal-g[data-g="part"]{--pal-g:var(--teal)}
    .pal-g[data-g="workorder"]{--pal-g:#3b82f6}
    .pal-g[data-g="breakdown"]{--pal-g:#ef4444}
    .pal-g[data-g="repairable_spare"]{--pal-g:#a855f7}
    .pal-g[data-g="plc_device"]{--pal-g:#f59e0b}
    .pal-g[data-g="station"]{--pal-g:#10b981}
    .pal .res.ask{grid-template-columns:26px minmax(0,1fr) auto 28px}
    .pal-ask{width:28px;height:28px;border-radius:8px;border:0;background:transparent;
      color:var(--ink-3);display:grid;place-items:center;cursor:pointer}
    .pal-ask:hover,.pal-ask:focus-visible{background:var(--teal-soft);color:var(--teal)}
    .pal-ask .icn svg{width:15px;height:15px}

    /* ── Obnovovací čip (`<refresh-chip>`) — nahrádza <refresh-every>,
       .pl-stamp, .al-stamp na migrovaných stránkach. Pevná šírka: text sa
       mení každú sekundu (odpočítavanie) a nič vedľa čipu sa nesmie hýbať. */
    .rf-chip-wrap{position:relative;flex:none}
    .rf-chip{display:inline-flex;align-items:center;gap:8px;height:32px;min-width:15.5rem;
      padding:0 10px 0 11px;border-radius:999px;border:1px solid var(--stroke);
      background:var(--surface-strong);color:var(--ink-2);font:500 .76rem/1 var(--font);
      cursor:pointer;white-space:nowrap;justify-content:space-between;
      font-variant-numeric:tabular-nums}
    .rf-chip:hover{border-color:color-mix(in srgb,var(--teal) 45%,transparent);color:var(--ink)}
    .rf-chip .dot{width:7px;height:7px;border-radius:50%;flex:none;background:var(--green);
      box-shadow:0 0 0 3px var(--green-soft)}
    .rf-chip .dot.off{background:var(--ink-3);box-shadow:none}
    .rf-chip .dot.stale{background:var(--amber);box-shadow:0 0 0 3px var(--amber-soft)}
    .rf-chip .full{flex:1;text-align:left;overflow:hidden;text-overflow:ellipsis}
    .rf-chip .short{display:none}
    .rf-chip .care{flex:none;opacity:.6}
    .rf-pop{position:absolute;right:0;top:calc(100% + 8px);z-index:61;width:min(280px,86vw);
      background:var(--surface-strong);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
      border:1px solid var(--stroke);border-radius:var(--r-menu);box-shadow:var(--shadow-lift);padding:10px}
    .rf-pop .seg{display:flex;width:100%}
    .rf-pop .seg button{flex:1;padding:6px 4px}
    .rf-pop .rf-now{width:100%;justify-content:center;margin-top:8px}

    /* ── Prepínač zdroja zariadení (`<source-switch>`) — počty vedľa
       popisku, tlmené. */
    .src-seg .n{font:700 .66rem var(--font);color:var(--ink-3);margin-left:5px}
    .src-seg button.active .n{color:var(--ink-2)}
    .ghost,.ghost-sel{display:inline-flex;align-items:center;gap:7px;
      min-height:var(--btn-h-lg);padding:0 var(--btn-px-lg);border-radius:var(--btn-r);cursor:pointer;
      font-size:var(--btn-fs-lg);font-weight:700;color:var(--ink-2);background:var(--surface-strong);
      /* --btn-line, nie --stroke: --stroke je vo svetle BIELA (glass okraj
         kariet) a biele tlačidlo na bielom pozadí držal len tieň — splývalo.
         Tmavý režim si token prepíše na svoju bielu linku (dark.css). */
      border:1px solid var(--btn-line);box-shadow:var(--shadow);transition:.15s}
    .ghost:hover,.ghost-sel:hover{color:var(--ink);transform:translateY(-1px)}
    .ghost svg{width:15px;height:15px}
    /* Šípku `.ghost-sel` kreslí spoločné pravidlo pre rozbaľovacie zoznamy
       nižšie — nie je to zvláštnosť lišty, je to ten istý ovládač. */
    /* Zoznam je široký ako jeho NAJDLHŠIA voľba — PLC s dlhým menom na
       /plc/raw ho roztiahlo za okraj a stránka sa posúvala do strany. Strop
       je šírka riadku; vybraná voľba sa skráti „…" (celá je v zozname). */
    .ghost-sel{max-width:100%;text-overflow:ellipsis}
    /* Výber súboru ako tlačidlo (`<file-button>`, core.js). Skutočné pole je
       vizuálne skryté, ale fokusovateľné — fokus sa kreslí na tlačidle. */
    .file-btn{display:inline-flex;align-items:center;flex-wrap:wrap;gap:6px 10px;max-width:100%;cursor:pointer}
    .file-btn-in{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden;
      clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
    .file-btn-b{flex:none}
    /* Rámik len pri klávesnici (`:focus-visible`) — okno dáva fokus prvému
       poľu aj po kliknutí myšou a rámik by vtedy svietil bez dôvodu. */
    .file-btn:has(.file-btn-in:focus-visible) .file-btn-b{outline:2px solid var(--indigo);outline-offset:2px}
    .file-btn-n{min-width:0;font-size:.8rem;font-weight:600;color:var(--ink);overflow-wrap:anywhere}
    .file-btn-n.none{color:var(--ink-3);font-weight:500}
    .file-btn.dis{cursor:default;opacity:.6}
    .file-btn.dis .file-btn-b{transform:none}

    /* ── Ovládacie prvky ─────────────────────────────────────────────────
       Jeden vzhľad pre vstupné pole, rozbaľovací zoznam aj viacriadkový text.
       Namerané pred zjednotením: PÄŤ nezávislých definícií toho istého poľa
       (`.us-f`, `.sc-f`, `.wf-f`, `.mv-f`, `.md-f`) a k nim ďalšie v modáloch,
       prihlásení a príkazoch — zakaždým vlastný padding, zaoblenie a písmo.

       `.field` je pre nový kód. Menované obaly stoja v tom istom pravidle,
       aby sa nemuseli prepisovať šablóny — vzhľad má ale JEDEN zdroj.

       Prečo `:is(...)`: drží špecifickosť na (0,1,1), presne ako pôvodné
       `.us-f input`. Stránkové súbory sa načítavajú ZA týmto, takže prebíjajú
       ďalej rovnako ako doteraz (šírka poľa, iné zalomenie a pod.).

       Prečo `:not(:where(...))`: `:where()` je nulovej špecifickosti, takže
       výnimka nič neposúva. A je nutná — v ⚙ ponuke obrazoviek sedí `.sc-chk`
       VNÚTRI `.sc-f`, takže `.sc-f input` doteraz kreslilo aj zaškrtávacie
       pole, s 9px paddingom a 11px zaoblením.

       Prečo `min-height` a nie zvislý padding: to isté, čo pri tlačidlách —
       rovnaký padding dá pri inej veľkosti písma inak vysoké pole a dve vedľa
       seba v jednom riadku potom nesedia. Text v `input`/`select` si prehliadač
       zvisle vycentruje sám, v `textarea` má správne začať hore. */
    .field,.field-sm,.fin,.dd-search,.md-in,.md-sel,
    :is(.us-f,.sc-f,.wf-f,.wf-col,.mv-f,.md-f,.mo-f,.wo-w,.wo-range,
        .lg-input,.cp-form,.cp-compose,.uw-ai,.md-tree-bar,
        .fsearch,.us-search,.rl-search,.ad-search,.al-trfind)
      :is(input:not(:where([type=checkbox],[type=radio],[type=color],[type=file],[type=range])),
          select,textarea){
      width:100%;min-height:var(--fld-h);padding:0 var(--fld-px);
      border-radius:var(--fld-r);font-family:inherit;font-size:var(--fld-fs);
      font-weight:600;color:var(--ink);background:var(--surface-strong);
      border:1px solid var(--stroke);box-shadow:var(--shadow);
      transition:border-color .15s,box-shadow .15s}
    /* Viacriadkový text potrebuje zvislý padding — inak sa prvý riadok lepí
       na hornú hranu. Výšku mu drží `rows`/`min-height` stránky, nie token. */
    textarea.field,.mo-f textarea,.wo-w textarea,.uw-ai textarea,.cp-compose textarea{
      padding-top:8px;padding-bottom:8px;line-height:1.45;resize:vertical}
    :is(.field,.fin,.dd-search,.us-f,.sc-f,.wf-f,.mv-f,.md-f,.mo-f,.wo-w,
        .lg-input,.md-tree-bar,.cp-compose,.uw-ai,
        .fsearch,.us-search,.rl-search,.ad-search,.al-trfind) ::placeholder,
    :is(.field,.fin,.dd-search)::placeholder{color:var(--ink-3);font-weight:500}
    /* Hustý stupeň: úprava na mieste v tabuľke a polia v ⚙ ponuke widgetu.
       Menšia je len VÝŠKA, nie písmo — pod 16 px iOS pri ťuknutí zoomuje. */
    .field-sm,.md-in,.md-sel,.md-cell,
    :is(.wmenu) :is(.sc-f)
      :is(input:not(:where([type=checkbox],[type=radio])),select){
      min-height:var(--fld-h-sm);padding:0 var(--fld-px-sm);
      border-radius:var(--fld-r-sm)}

    /* Rozbaľovací zoznam. Natívna šípka vyzerá na každom systéme inak (a na
       Windows je to sivý štvorec cez pol výšky poľa), preto vlastná — jedna
       pre všetky zoznamy v /v2. `appearance:none` je nutné, inak ostane
       natívna vedľa našej. */
    select.field,select.field-sm,.ghost-sel,.md-sel,
    :is(.us-f,.sc-f,.wf-f,.mv-f,.md-f,.mo-f) select{
      appearance:none;-webkit-appearance:none;cursor:pointer;
      padding-right:30px;
      background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%235b6478' stroke-width='3'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
      background-repeat:no-repeat;background-position:right 11px center}
    /* Šípka je kresba v `background-image`, takže sa nefarbí tokenom. V tmavom
       režime by ostala tmavosivá na tmavom poli — preto svetlá varianta. */
    :root[data-theme="dark"] select.field,:root[data-theme="dark"] select.field-sm,
    :root[data-theme="dark"] .ghost-sel,:root[data-theme="dark"] .md-sel,
    :root[data-theme="dark"] :is(.us-f,.sc-f,.wf-f,.mv-f,.md-f,.mo-f) select{
      background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23a8b2c8' stroke-width='3'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")}

    /* Zameranie. Doteraz malo každé pole vlastné: `outline:none` + zelený
       rámik na `.us-f`, dvojpixelový obrys na `.wf-f`, nič na `.mv-f`.
       Najhoršie bolo `outline:none` na `:focus` — prebilo globálne
       `:focus-visible` z tohto súboru, takže klávesnicou sa po formulári dalo
       chodiť bez toho, aby bolo vidieť kde človek je. */
    .field:focus-visible,.field-sm:focus-visible,.fin:focus-visible,
    .dd-search:focus-visible,.md-in:focus-visible,.md-sel:focus-visible,
    :is(.us-f,.sc-f,.wf-f,.wf-col,.mv-f,.md-f,.mo-f,.wo-w,.wo-range,
        .lg-input,.cp-form,.md-tree-bar,.fsearch,.us-search,.rl-search,.ad-search,.al-trfind)
      :is(input,select,textarea):focus-visible{
      outline:2px solid var(--teal);outline-offset:1px;border-color:var(--teal)}

    /* Výber s hľadaním `<search-select>` (core.js) — výber z veľmi dlhého
       zoznamu (výrobcovia: ~1900). Pole je obyčajné `.field`, takže výšku,
       písmo 16 px aj zameranie má zo spoločných pravidiel vyššie; tu je len
       zoznam. Ten je V TOKU, nie plávajúci: v modáli s vlastným rolovaním by
       `position:absolute` orezal okraj okna. `max-height` s `vh` drží zoznam
       na telefóne s otvorenou klávesnicou menší než polovicu obrazovky
       a `overscroll-behavior` zabráni tomu, aby dorolovanie zoznamu rolovalo
       celý modál. */
    .ss{display:flex;flex-direction:column;gap:4px;min-width:0}
    .ss-list{list-style:none;margin:0;padding:5px;max-height:min(260px,40vh);
      overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
      background:var(--cover);border:1px solid var(--btn-line);border-radius:var(--r-menu);
      box-shadow:var(--shadow-lift)}
    /* Riadok aspoň 32 px — prstom sa musí dať trafiť (docs/v2-controls.md). */
    .ss-opt{display:flex;flex-direction:column;justify-content:center;gap:1px;min-height:32px;
      padding:6px 10px;border-radius:9px;cursor:pointer;min-width:0}
    .ss-opt b{font-size:.8rem;font-weight:800;color:var(--ink);overflow-wrap:anywhere}
    .ss-opt span{font-size:.7rem;font-weight:600;color:var(--ink-3);line-height:1.35;overflow-wrap:anywhere}
    .ss-opt:hover,.ss-opt.act{background:var(--fill-2)}
    /* Zvýraznená (klávesnicou) položka má navyše pásik — samotný odtieň
       pozadia je pri rýchlom prechádzaní šípkami ťažko vidieť. */
    .ss-opt.act{box-shadow:inset 3px 0 0 var(--teal)}
    /* Nápovedné riadky zoznamu („nič nezodpovedá", „ďalších N — píšte ďalej"):
       sú to RIADKY rozbaleného výberu, nie prázdny stav stránky — ten má
       vlastný primitív (.empty-full) a vlastnú stráž v test_v2_alarm_bell. */
    .ss-hint{padding:8px 10px;font-size:.72rem;font-weight:600;color:var(--ink-3)}
    .ss-hint.ss-more{border-top:1px solid var(--line-soft);margin-top:3px}
    .ss-bad{font-size:.72rem;font-weight:700;color:var(--rose)}
    .ss-in[aria-invalid="true"]{border-color:var(--rose)}
    .field:hover,.fin:hover{border-color:rgba(13,148,136,.45)}
    /* Natívna ikona kalendára je v tomto podklade priveľmi kontrastná. */
    .fin[type=date]::-webkit-calendar-picker-indicator,
    .field[type=date]::-webkit-calendar-picker-indicator{opacity:.5;cursor:pointer}
    .fin[type=date]:hover::-webkit-calendar-picker-indicator,
    .field[type=date]:hover::-webkit-calendar-picker-indicator{opacity:1}

    /* Zaškrtávacie pole. Namerané štyri veľkosti (15/16/17 px) a dve farby
       (tyrkysová aj indigová) podľa toho, kto stránku písal. Odteraz jeden
       token a jedna farba; výber riadkov v tabuľke si necháva indigovú, lebo
       zvýraznenie označeného riadku je indigové a musia si sedieť. */
    .chk input,.dd-row input,.rl-perm input,.pf-kind input,
    .fchk input[type=checkbox],.lg-remember input,.wtl-t1 input,
    .md-ck input,.md-f-row input[type=checkbox],
    .btab td.sel input,.btab th.sel input{
      width:var(--chk);height:var(--chk);flex:none;cursor:pointer;
      accent-color:var(--teal);margin:0}
    .md-ck input,.md-f-row input[type=checkbox],
    .btab td.sel input,.btab th.sel input{accent-color:var(--indigo)}
    /* Riadok „zaškrtávacie pole + popis". Popis je SÚČASŤ ovládača, takže sa
       má dať kliknúť celý — preto `<label>` a `user-select:none` (dvojklik na
       popis inak označí text namiesto prepnutia). */
    .chk{display:flex;align-items:center;gap:9px;min-height:var(--fld-h-sm);
      padding:0 4px;border-radius:var(--fld-r-sm);cursor:pointer;user-select:none;
      font-size:.82rem;font-weight:600;color:var(--ink-2)}
    .chk:hover{background:var(--fill-1);color:var(--ink)}

    /* Prepínač zap/vyp. Spoločný v /v2 NEEXISTOVAL: „posielať poruchy do MVP
       One", notifikácie v profile aj áno/nie argument widgetu boli holé
       zaškrtávacie polia — teda ten istý prvok, ktorým sa OZNAČUJE riadok
       tabuľky. Pritom je rozdiel medzi „vyberám" a „zapínam". Jediný posuvník
       v aplikácii bol `.us-sw` na používateľoch a nemal s ničím spoločné nič.

       Dva tvary, obidva ovládateľné klávesnicou:
         <label class="switch"><input type="checkbox"><i></i><span>…</span></label>
             — hodnota vo formulári, uloží sa až tlačidlom
         <button class="switch" role="switch" :aria-checked="…"><i></i>…</button>
             — okamžitá akcia (volanie servera), preto tlačidlo a nie pole

       Pri prvom tvare je `<input>` len PRIEHĽADNÝ, nie `display:none`: skryté
       pole vypadne z poradia tabulátora a čítačka obrazovky oň príde. */
    .switch{position:relative;display:inline-flex;align-items:center;gap:10px;
      cursor:pointer;min-height:var(--fld-h-sm);user-select:none;
      font:inherit;font-size:.84rem;font-weight:700;color:var(--ink-2);
      background:transparent;border:0;padding:0;text-align:left}
    .switch>input{position:absolute;left:0;width:var(--sw-w);height:var(--sw-h);
      margin:0;opacity:0;cursor:pointer}
    .switch>i{flex:none;position:relative;width:var(--sw-w);height:var(--sw-h);
      border-radius:999px;background:rgba(28,35,55,.18);
      border:1px solid var(--stroke);transition:background .18s}
    .switch>i::after{content:"";position:absolute;top:2px;left:2px;
      width:calc(var(--sw-h) - 6px);height:calc(var(--sw-h) - 6px);border-radius:50%;
      background:#fff;box-shadow:0 1px 3px rgba(28,35,55,.4);transition:transform .18s}
    .switch>input:checked+i,
    .switch[aria-checked="true"]>i{background:var(--grad)}
    .switch>input:checked+i::after,
    .switch[aria-checked="true"]>i::after{
      transform:translateX(calc(var(--sw-w) - var(--sw-h)))}
    .switch>input:focus-visible+i,
    .switch:focus-visible>i{outline:2px solid var(--teal);outline-offset:2px}
    .switch:focus-visible{outline:none}
    .switch>input:disabled~*,.switch:disabled{opacity:.55}
    .switch>input:disabled,.switch:disabled,
    .switch:has(>input:disabled){cursor:not-allowed}
    .switch.on,.switch[aria-checked="true"]{color:var(--ink)}
    @media(prefers-reduced-motion:reduce){.switch>i,.switch>i::after{transition:none}}

    .btn-add{display:inline-flex;align-items:center;gap:7px;
      min-height:var(--btn-h-lg);padding:0 var(--btn-px-lg);border-radius:var(--btn-r);cursor:pointer;border:0;
      font-size:var(--btn-fs-lg);font-weight:700;color:#fff;background:var(--grad);
      box-shadow:0 10px 24px -8px rgba(79,70,229,.5);transition:.15s}
    .btn-add:hover{transform:translateY(-1px);box-shadow:0 14px 30px -8px rgba(79,70,229,.6)}
    /* Zablokované primárne tlačidlo MUSÍ vyzerať zablokované. Bez tohto si
       drží plnú indigo farbu aj tieň a vyzerá aktívne — človek klikne a nič
       sa nedeje (2026-08-12: „Zmazať natrvalo" pri TIA agentovi). Platí pre
       všetkých 57 výskytov `btn-add` s :disabled naprieč /v2. */
    .btn-add:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}
    .btn-add:disabled:hover{transform:none;box-shadow:none}
    .btn-add svg{width:16px;height:16px}
    .scope-chip{flex:none;font-size:var(--btn-fs-sm);font-weight:700;letter-spacing:.04em;
      padding:3px var(--btn-px-sm);border-radius:999px;
      color:var(--ink-3);background:var(--fill-2);cursor:help;text-transform:none}
    /* mobile off-canvas nav toggle */
    .nav-btn{display:none;position:fixed;top:14px;left:14px;z-index:51;width:44px;height:44px;border-radius:14px;
      background:var(--surface-strong);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
      border:1px solid var(--stroke);box-shadow:var(--shadow);color:var(--ink);cursor:pointer;place-items:center}
    .nav-btn svg{width:22px;height:22px}
    .nav-backdrop{position:fixed;inset:0;z-index:49;background:rgba(28,35,55,.28);backdrop-filter:blur(3px)}

    .bento{display:grid;grid-template-columns:repeat(12,1fr);gap:15px;align-items:stretch;grid-auto-flow:row dense;grid-auto-rows:152px}
    .bento.is-loading{opacity:.55;pointer-events:none;transition:opacity .2s}
    .tile{display:flex;flex-direction:column}
    .tile>.tile-head{flex:none}
    .h1{grid-row:span 1}.h2{grid-row:span 2}.h3{grid-row:span 3}
    .tile-body{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}
    .wcol{flex:1;min-height:0;display:flex;flex-direction:column}
    /* department checkbox dropdown */
    .dd{position:relative}
    .dd-panel{position:absolute;top:44px;right:0;z-index:45;min-width:210px;max-height:320px;overflow-y:auto;padding:6px;
      background:var(--surface-strong);backdrop-filter:blur(20px);border:1px solid var(--stroke);border-radius:14px;box-shadow:var(--shadow-lift)}
    .dd-row{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:9px;font-size:.82rem;font-weight:600;color:var(--ink-2);cursor:pointer}
    .dd-row:hover{background:var(--fill-2);color:var(--ink)}
    .dd-sep{height:1px;background:var(--line-soft);margin:4px 6px}
    .tile{background:var(--surface);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
      border:1px solid var(--stroke);border-radius:var(--r);box-shadow:var(--shadow);
      padding:16px 18px;position:relative;overflow:visible;transition:transform .18s,box-shadow .18s,opacity .18s}
    .tile:hover{box-shadow:var(--shadow-lift)}
    .c3{grid-column:span 3}.c4{grid-column:span 4}.c5{grid-column:span 5}
    .c6{grid-column:span 6}.c7{grid-column:span 7}.c8{grid-column:span 8}.c12{grid-column:span 12}
    .r2{grid-row:span 2}
    .tile.dragging{opacity:.4;transform:scale(.98)}
    .tile.dragover{outline:2px dashed var(--teal);outline-offset:3px}
    .tile.menu-open{z-index:50}   /* raise the whole tile so its ⚙ menu is above the tile below */

    .tile-head{display:flex;align-items:center;gap:8px;margin-bottom:11px;cursor:grab;position:relative;z-index:4}
    .tile-head:active{cursor:grabbing}
    .grip{color:var(--ink-3);opacity:.55;flex:none;display:grid}
    .grip svg{width:14px;height:14px}
    .tile-label{display:flex;align-items:center;gap:8px;font-size:.68rem;font-weight:700;
      letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);flex:1;min-width:0}
    .tile-label span.t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
    .dot{width:8px;height:8px;border-radius:3px;flex:none}
    .dot.teal{background:#14b8a6}.dot.indigo{background:#6366f1}.dot.amber{background:#f59e0b}
    .dot.rose{background:#fb7185}.dot.emerald{background:#10b981}
    .gear{border:0;background:transparent;cursor:pointer;color:var(--ink-3);padding:3px;border-radius:9px;
      flex:none;transition:color .15s,background .15s,transform .3s}
    .gear:hover{color:var(--ink);background:var(--fill-2);transform:rotate(45deg)}
    .gear svg{width:16px;height:16px;display:block}
    .wmenu{position:absolute;top:38px;right:0;z-index:60;min-width:180px;padding:12px;
      background:var(--surface-strong);backdrop-filter:blur(20px);border:1px solid var(--stroke);
      border-radius:16px;box-shadow:var(--shadow-lift)}
    .wmenu-cap{font-size:.64rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);margin-bottom:8px}
    .wmenu-sizes{display:flex;gap:6px;margin-bottom:12px}
    /* `nowrap`: tlačidlá majú `flex:1`, takže by sa v úzkej ponuke zmrštili
       pod svoj text a „↑ Vyššie" by sa zalomilo do dvoch riadkov. Takto radšej
       o pár pixelov narastie ponuka, ktorá je aj tak `position:absolute`. */
    .wmenu-sizes button{flex:1;border:1px solid var(--line);background:#fff;cursor:pointer;
      display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;
      min-height:var(--btn-h);padding:0 var(--btn-px);border-radius:var(--btn-r);
      font-size:var(--btn-fs);font-weight:700;color:var(--ink-2);transition:.12s}
    .wmenu-sizes button:hover{border-color:var(--teal);color:var(--ink)}
    .wmenu-sizes button.on{background:var(--grad);color:#fff;border-color:transparent}
    .wmenu-sizes button:disabled{opacity:.4;cursor:not-allowed;border-color:var(--line);color:var(--ink-3)}
    /* Zaškrtávací filter (viac hodnôt naraz). Roluje sa: typov príkazu je
       dvadsaťsedem a celý zoznam by ⚙ ponuku natiahol cez pol obrazovky. */
    .wmenu-multi{max-height:170px;overflow-y:auto;margin-bottom:12px}
    .wmenu-multi-all{width:100%;padding:4px 8px;margin-bottom:2px;border:0;background:none;
      cursor:pointer;text-align:left;border-radius:9px;
      font-size:.72rem;font-weight:800;color:var(--ink-3)}
    .wmenu-multi-all:hover{background:var(--fill-2);color:var(--ink-2)}
    /* Zapnuté „Všetky" = prázdny výber; nie je to voľba navyše, len zmazanie,
       preto sa nefarbí prechodom ako prepínacie tlačidlá. */
    .wmenu-multi-all.on{color:var(--ink)}
    .wmenu-hide{width:100%;border:0;cursor:pointer;background:var(--rose-soft);color:var(--rose);
      min-height:var(--btn-h);padding:0 var(--btn-px);border-radius:var(--btn-r);
      font-size:var(--btn-fs);font-weight:700;display:flex;align-items:center;justify-content:center;gap:6px}
    .wmenu-hide svg{width:14px;height:14px}

    /* Odznak, nie tlačidlo: berie z tokenu písmo a vodorovné odsadenie, ale
       NIE `min-height` — nikto naň neklikne, a vynútená výška tlačidla by
       natiahla riadky v dlaždici aj v tabuľke. */
    .chip{display:inline-flex;align-items:center;gap:6px;padding:3px var(--btn-px);
      border-radius:999px;font-size:var(--btn-fs);font-weight:700}
    .chip.ok{background:var(--green-soft);color:var(--green)}
    .chip.warn{background:var(--amber-soft);color:var(--amber)}
    .chip.na{background:var(--fill-2);color:var(--ink-3)}
    .hero .big{font-size:2.9rem;font-weight:800;letter-spacing:-.04em;line-height:1.02;margin:2px 0}
    .hero .big small{font-size:1rem;font-weight:700;color:var(--ink-3);margin-left:6px}
    .hero .meta{display:flex;align-items:center;gap:10px;margin-top:9px;flex-wrap:wrap}
    .hero .spark{margin-top:13px;flex:1;min-height:0;display:flex;flex-direction:column}
    /* h1 (nízka dlaždica): .meta je skrytá + menší margin, aby spark-box (36px)
       dostal miesto a graf sa zmestil do body ako pri MTTR (inak pretečie von). */
    .hero.h1 .spark{margin-top:4px}
    .cap{font-size:.7rem;color:var(--ink-3);font-weight:600;margin-bottom:6px}
    .val{font-size:1.7rem;font-weight:800;letter-spacing:-.03em;margin:2px 0 7px}
    .val small{font-size:.85rem;font-weight:700;color:var(--ink-3);margin-left:4px}

    .gauge-wrap{display:flex;align-items:center;justify-content:center;gap:16px;flex-wrap:wrap;flex:1;min-height:0}
    .gauge{position:relative;flex:none;height:min(360px,100%);aspect-ratio:1;max-width:100%}
    .gauge .num{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
    .gauge .num b{font-size:1.35rem;font-weight:800;letter-spacing:-.02em}
    .gauge-side{min-width:120px;flex:1}
    .gauge-side p{font-size:.78rem;color:var(--ink-2);font-weight:500;line-height:1.6;margin-top:6px}

    .chart-top{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:7px;flex:none}
    .chart-top .n{font-size:.78rem;color:var(--ink-2);font-weight:600}
    .bars{display:flex;align-items:flex-end;gap:5px;flex:1;min-height:80px}
    /* activity chart: y-axis + gridlines + max highlight (per user mockup) */
    .act-plot{flex:1;min-height:96px;position:relative;margin-top:14px}
    .act-grid{position:absolute;left:30px;right:0;height:0;border-top:1.5px dashed var(--line);pointer-events:none}
    .act-grid>span{position:absolute;right:calc(100% + 3px);top:-.55em;text-align:right;white-space:nowrap;
      font-size:.6rem;font-weight:600;color:var(--ink-3);font-variant-numeric:tabular-nums}
    .bars.in-plot{position:absolute;left:30px;right:0;top:0;bottom:0;flex:none;min-height:0;height:auto}
    .bars .col{position:relative}
    /* (0,4,0) so it beats .bars .bar base AND .bars .bar.now/.fut — the max bar
       matches Top poruchové miesta (amber bottom → rose top). */
    .bars .col .bar.maxbar{background:linear-gradient(180deg,#fb7185,#f59e0b)}
    .bars .col:hover .bar.maxbar{filter:brightness(1.05)}
    .bar-badge{position:absolute;left:50%;top:0;transform:translate(-50%,-70%);z-index:3;
      background:rgba(23,29,48,.95);color:#fff;font-size:.66rem;font-weight:800;
      padding:2px 8px;border-radius:999px;white-space:nowrap;pointer-events:none;
      box-shadow:0 6px 16px -6px rgba(23,29,48,.5)}
    .axis-full.with-y{margin-left:30px}
    .ax-col.maxd{color:var(--rose);font-weight:800}
    .leg{display:inline-flex;align-items:center;gap:5px;font-size:.7rem;font-weight:600;color:var(--ink-2)}
    .leg i{width:8px;height:8px;border-radius:50%;display:inline-block;flex:none}
    .tstack{display:flex;height:11px;border-radius:6px;overflow:hidden;margin:12px 0 12px;background:var(--surface-2)}
    .tstack>div{transition:flex .3s}
    .tlegend{display:flex;flex-wrap:wrap;gap:12px;font-size:.76rem;font-weight:600;color:var(--ink-2)}
    .tlegend span{display:inline-flex;align-items:center;gap:6px}
    .tlegend i.d{width:9px;height:9px;border-radius:3px;display:inline-block}
    .bars .col{flex:1;min-width:0;height:100%;display:flex;flex-direction:column;justify-content:flex-end}
    .bars .bar{width:100%;border-radius:6px 6px 3px 3px;min-height:3px;
      background:linear-gradient(180deg,#2dd4bf,#4f46e5);transition:.2s;opacity:.9}
    .bars .col:hover .bar{opacity:1}
    .axis{display:flex;justify-content:space-between;font-size:.66rem;color:var(--ink-3);font-weight:600;margin-top:8px;flex:none}
    .axis-full{display:flex;gap:5px;margin-top:8px;flex:none}
    .ax-col{flex:1;min-width:0;text-align:center;font-size:.62rem;color:var(--ink-3);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
    /* Riedka os (aktivita): popisok je len na každom N-tom dni, ostatné stĺpce sú
       prázdne — nesmie ho teda orezávať šírka jedného dňa (z „10" robila „1."). */
    .axis-full.sparse .ax-col{overflow:visible;text-overflow:clip}
    /* Krajné popisky sa pri centrovaní vysunú mimo dlaždice a orežú sa o jej
       okraj — prvý ukotvíme vľavo, posledný vpravo. */
    .axis-full.sparse .ax-col:first-child{text-align:left}
    .axis-full.sparse .ax-col:last-child{text-align:right}
    .ax-col.now{color:var(--indigo);font-weight:800}
    /* Dvojica stĺpcov na záznam: počet + minúty prestoja (každý s vlastnou
       škálou — os vľavo patrí počtom, minúty majú max v legende). */
    .bars .col.pair{position:relative}
    .bars .col.pair .pairwrap{display:flex;align-items:flex-end;gap:2px;height:100%;width:100%}
    .bars .col.pair .bar{flex:1;min-width:0}
    .bars .bar.mins{background:linear-gradient(180deg,#5eead4,#0d9488);opacity:.85}
    .bars .col:hover .bar.mins{opacity:1}
    .bars .bar.fut{background:var(--fill-3)}
    .bars .bar.now{background:linear-gradient(180deg,#6366f1,#4f46e5);box-shadow:0 0 0 2px rgba(99,102,241,.25)}
    .bars .col:hover .bar{filter:brightness(1.08)}
    /* Prázdny stav typu „všetko v poriadku" — ikona namiesto emoji 👍,
       aby to sedelo so zvyškom dizajnu (rovnaký zelený akcent ako KPI chipy). */
    .empty.ok{display:flex;align-items:center;justify-content:center;gap:7px;color:var(--ink-2)}
    .empty.ok::before{content:"";width:17px;height:17px;flex:none;
      background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='10' fill='%23047857'/%3E%3Cpath d='m5.5 10.5 3 3 6-6.5' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat}
    /* Emoji, ktoré do odpovede vloží model (🔴🟡🟢) — jednotná veľkosť a
       zarovnanie, nech nerozhadzujú riadkovanie textu. */
    .cp-ans img.emoji,.cp-ans .emo{width:1em;height:1em;vertical-align:-.12em}
    .cp-ans{font-variant-emoji:text}

    /* Inventúra — súhrnné karty (počet/presnosť/manká/prebytky/dopad) */
    .inv-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(112px,1fr));gap:9px;margin:10px 0 4px}
    .inv-card{background:rgba(255,255,255,.62);border:1px solid var(--stroke);border-radius:var(--r-sm);
      padding:9px 11px;display:flex;flex-direction:column;gap:1px;min-width:0}
    .inv-card .ic-cap{font-size:.62rem;font-weight:700;color:var(--ink-3);text-transform:uppercase;letter-spacing:.05em}
    .inv-card .ic-val{font-size:1.18rem;font-weight:800;letter-spacing:-.02em;line-height:1.15;
      white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
    .inv-card .ic-sub{font-size:.64rem;color:var(--ink-3);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
    .inv-top{flex:1;min-height:0;display:flex;flex-direction:column;margin-top:6px}

    /* interactive sparkline */
    .spark-box{position:relative;width:100%;cursor:crosshair}
    .spark-box.fill{flex:1;min-height:36px}
    /* Draw-on reveal: clip the whole chart left→right (line + gradient area
       together). Re-keyed on data change so it replays like the bars grow.
       Uses clip-path (NOT stroke-dash, which under non-scaling-stroke +
       non-uniform scale mis-renders and hides the line). If the animation never
       runs, clip-path defaults to none → the chart is simply fully visible. */
    .spark-anim{animation:sparkreveal .8s cubic-bezier(.33,0,.2,1)}
    @keyframes sparkreveal{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
    .spark-guide{position:absolute;top:0;bottom:0;width:1px;background:rgba(28,35,55,.2);transform:translateX(-.5px);pointer-events:none}
    .spark-dot{position:absolute;width:8px;height:8px;border-radius:50%;border:1.5px solid #fff;
      transform:translate(-50%,-50%);pointer-events:none;box-shadow:0 1px 3px rgba(0,0,0,.25);z-index:2}
    .spark-dot.today{width:10px;height:10px;box-shadow:0 0 0 3px rgba(13,148,136,.18),0 1px 3px rgba(0,0,0,.25)}
    .spark-tip{position:absolute;top:-4px;transform:translate(-50%,-100%);background:rgba(23,29,48,.95);color:#fff;
      font-size:.66rem;font-weight:700;padding:4px 8px;border-radius:8px;white-space:nowrap;pointer-events:none;z-index:5;
      box-shadow:0 8px 20px -6px rgba(23,29,48,.5)}

    .top-list{display:flex;flex-direction:column;gap:9px}
    .top-line{display:flex;align-items:baseline;gap:10px;font-size:.78rem;margin-bottom:3px}
    .top-label{font-weight:600;color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}
    .top-line b{font-weight:800;color:var(--ink)}
    .top-track{height:9px;border-radius:6px;background:var(--fill-2);overflow:hidden}
    .top-fill{height:100%;border-radius:6px;min-width:3px;background:linear-gradient(90deg,#2dd4bf,#4f46e5)}
    .top-fill.maxf{background:linear-gradient(90deg,#f59e0b,#fb7185)}
    .maxr .top-line b{color:var(--rose)}

    .list-row{display:flex;align-items:center;gap:10px;padding:6px 0;border-top:1px solid var(--line-soft)}
    .list-row:first-child{border-top:0}
    /* Fixed min-width + centred tabular figures → the text column (t1/t2) lines
       up across every list row regardless of the badge's digit count. */
    .pill{padding:2px 7px;border-radius:999px;font-size:.66rem;font-weight:800;flex:none;
      min-width:3.4rem;text-align:center;font-variant-numeric:tabular-nums;background:var(--rose-soft);color:var(--rose)}
    .list-row .txt{min-width:0;flex:1}
    .list-row .t1{font-size:.78rem;font-weight:600;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}
    .list-row .t2{font-size:.66rem;color:var(--ink-3);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}
    a.list-row{cursor:pointer;text-decoration:none;border-radius:10px;margin:0 -8px;padding-left:8px;padding-right:8px}
    a.list-row:hover{background:var(--hover)}
    a.tl-row{display:block;cursor:pointer;text-decoration:none;border-radius:9px;margin:0 -6px;padding:2px 6px}
    a.tl-row:hover{background:var(--hover)}
    /* riadok bez cieľa (napr. bez práva na detail) nie je odkaz */
    a.tl-row:not([href]){cursor:default}
    a.tl-row:not([href]):hover{background:none}
    .spark-stats{font-size:.68rem;color:var(--ink-3);font-weight:600;margin-top:6px;flex:none;letter-spacing:.01em}

    .tile.copilot{background:linear-gradient(140deg,rgba(255,255,255,.74),rgba(255,255,255,.5)),
      linear-gradient(140deg,rgba(45,212,191,.22),rgba(99,102,241,.20) 55%,rgba(251,113,133,.18));border:1px solid rgba(255,255,255,.9)}
    .cp-badge{width:38px;height:38px;border-radius:12px;display:grid;place-items:center;color:#fff;flex:none;
      background:linear-gradient(135deg,#2dd4bf,#6366f1 60%,#fb7185);box-shadow:0 8px 18px -6px rgba(99,102,241,.55)}
    .cp-badge svg{width:20px;height:20px}
    /* Odpoveď vypĺňa dlaždicu (flex:1 v .wcol) namiesto fixných 150px — pri
       veľkej dlaždici sa už neoreže do mini-okna s prázdnom pod ním. */
    .cp-ans{font-size:.82rem;color:var(--ink);line-height:1.5;white-space:normal;flex:1 1 auto;min-height:56px;overflow:auto;
      background:rgba(255,255,255,.6);border:1px solid rgba(255,255,255,.9);border-radius:14px;padding:12px 14px;margin-bottom:10px}
    .cp-ans .md-h{font-weight:800;font-size:.88rem;margin:9px 0 4px;letter-spacing:-.01em}
    .cp-ans .md-h:first-child{margin-top:0}
    .cp-ans ul,.cp-ans ol{margin:4px 0 6px 18px}
    .cp-ans li{margin:2px 0}
    .cp-ans p{margin:4px 0}
    .cp-ans code{background:var(--fill-2);border-radius:5px;padding:1px 5px;font-size:.78rem}
    /* Prvok rozhrania spomenutý v odpovedi (`[[ikona|Názov]]`). Vyzerá ako
       tlačidlo v aplikácii, aby ho človek na obrazovke našiel očami — návod
       „klikni na Nový diel" inak znamená hľadať text v riadku po riadku.
       Nie je to tlačidlo: nedá sa naň kliknúť a nesmie tak ani vyzerať pri
       kurzore (žiadny pointer, žiadny hover). */
    .md-ui{display:inline-flex;align-items:center;gap:5px;vertical-align:baseline;
      padding:2px 8px 2px 6px;margin:0 1px;border-radius:9px;
      background:var(--surface-strong);border:1px solid var(--stroke);
      box-shadow:0 1px 2px rgba(28,35,55,.06);white-space:nowrap}
    .md-ui svg{width:13px;height:13px;flex:none;opacity:.7}
    .md-ui b{font-weight:700;font-size:.95em}

    /* ── Odkaz na zdieľanú stránku ── */
    /* Adresa je vidieť CELÁ a v poli, ktoré sa dá označiť — človek má vedieť,
       čo posiela ďalej, nie kopírovať naslepo. */
    .share-box{width:min(520px,92vw);background:#fff;border-radius:20px;padding:20px 22px;
      box-shadow:0 30px 70px -20px rgba(23,29,48,.55);display:flex;flex-direction:column;gap:10px}
    .share-h{font-size:1rem;font-weight:800;letter-spacing:-.01em;color:var(--ink)}
    .share-sub{font-size:.82rem;font-weight:700;color:var(--ink-2)}
    .share-url{width:100%;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
      font-size:.78rem;padding:10px 12px;border-radius:12px;border:1px solid rgba(28,35,55,.16);
      background:var(--hover);color:var(--ink)}
    .share-note{font-size:.72rem;color:var(--ink-3);font-weight:600;line-height:1.5}
    .share-err{font-size:.82rem;color:var(--rose);font-weight:700}
    .share-foot{display:flex;justify-content:flex-end;gap:8px;margin-top:2px}
    /* ZÁKLADNÝ vzhľad tlačidla musí byť NEZANORENÝ. Okno so zdieľaným odkazom
       sa pripája na `document.body`, teda MIMO `.cp-ans` — a keď bol tvar
       definovaný len pod `.cp-ans .md-code-b`, dostalo iba farbu pozadia
       a zvyšok ostal systémový (čierny rámik, iné písmo). Farby si nižšie
       zanorené pravidlá aj tak prebijú, tie sú v každom kontexte iné. */
    .md-code-b{border:0;cursor:pointer;font-family:inherit;
      display:inline-flex;align-items:center;justify-content:center;
      min-height:var(--btn-h-sm);padding:0 var(--btn-px-sm);border-radius:var(--btn-r-sm);
      font-size:var(--btn-fs-sm);font-weight:700;transition:.12s}
    /* Kopírovať/Zavrieť sú HLAVNÉ akcie svojho okna, nie lišta nad blokom
       kódu — preto veľkosť lg. Práve tu boli najmenšie tlačidlá v aplikácii. */
    .share-foot .md-code-b{min-height:var(--btn-h-lg);padding:0 var(--btn-px-lg);
      border-radius:var(--btn-r);font-size:var(--btn-fs-lg);
      background:var(--fill-2);color:var(--ink-2)}
    .share-foot .md-code-b:hover{background:rgba(28,35,55,.13);color:var(--ink)}
    .share-foot .md-code-b.prim{background:var(--grad);color:#fff}
    /* ── Blok kódu: hlavička s jazykom + akcie, zvýraznená syntax ── */
    /* Obrázok v odpovedi Copilota (mdLite ho kreslí z markdown/holej URL) —
       ohraničený, s odkazom na originál pod ním. */
    .cp-ans .md-img{display:block;max-width:min(340px,100%);max-height:260px;
      object-fit:contain;margin:8px 0 2px;border-radius:12px;
      border:1px solid var(--stroke);background:#fff}
    .cp-ans .md-img-src{display:block;font-size:.68rem;margin-bottom:6px}
    .cp-ans .md-code{margin:9px 0;border-radius:var(--r-sm);overflow:hidden;
      border:1px solid rgba(28,35,55,.22);background:#1e2536}
    .cp-ans .md-code-h{display:flex;align-items:center;gap:7px;padding:6px 8px 6px 12px;
      background:rgba(255,255,255,.06);border-bottom:1px solid rgba(255,255,255,.08)}
    .cp-ans .md-code-l{flex:1;font-size:.6rem;font-weight:800;letter-spacing:.08em;
      text-transform:uppercase;color:rgba(230,233,242,.5);
      min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
    /* Názov bloku za jazykom (```scl FB12 Robot_Com · Network 3). */
    .cp-ans .md-code-t{margin-left:9px;font-size:.68rem;font-weight:600;letter-spacing:0;
      text-transform:none;color:rgba(230,233,242,.82)}
    /* Rozmery si berie zo základného `.md-code-b` (veľkosť sm) — tu je len to,
       čo je v tmavej hlavičke bloku kódu iné: farby. */
    .cp-ans .md-code-b{color:rgba(230,233,242,.8);background:rgba(255,255,255,.08)}
    .cp-ans .md-code-b:hover{background:rgba(255,255,255,.16);color:#fff}
    .cp-ans .md-code-b.prim{background:var(--grad);color:#fff}
    .cp-ans .md-code-b.prim:hover{filter:brightness(1.1)}
    /* Dlhý výpis (napr. celý HTML report) by odtlačil odpoveď mimo obrazovku —
       zbalíme ho a necháme rozbaliť; na pozeranie výsledku je tlačidlo Otvoriť. */
    .cp-ans .md-code .md-pre{margin:0;border:0;border-radius:0;max-height:340px}
    .cp-ans .md-code.full .md-pre{max-height:none}
    .cp-ans .md-code:not(.full) .md-pre{overflow-y:hidden}
    .cp-ans .md-code:not(.full){position:relative}
    .cp-ans .md-code:not(.full)::after{content:"";position:absolute;left:0;right:0;bottom:0;height:56px;
      pointer-events:none;background:linear-gradient(180deg,rgba(30,37,54,0),#1e2536)}

    .cp-ans .md-pre{position:relative;margin:8px 0;padding:11px 13px;border-radius:12px;
      overflow-x:auto;background:#1e2536;border:1px solid rgba(28,35,55,.25)}
    .cp-ans .md-pre code{display:block;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
      font-size:.72rem;line-height:1.55;color:#e6e9f2;background:none;padding:0;white-space:pre;
      font-variant-numeric:normal}
    /* Farby tokenov — ladené na tmavé pozadie bloku, kontrast ≥ 4.5:1. */
    .cp-ans .tk-com{color:#7f8ba6;font-style:italic}
    .cp-ans .tk-str{color:#7ee0c0}
    .cp-ans .tk-num{color:#f5b478}
    .cp-ans .tk-kw{color:#93b4ff;font-weight:700}
    .cp-ans .tk-tag{color:#ff9ab0}
    .cp-ans .tk-atr{color:#e5c07b}

    /* ── Náhľad HTML v samostatnom okne ── */
    .code-prev-back{position:fixed;inset:0;z-index:120;background:rgba(28,35,55,.5);
      backdrop-filter:blur(4px);display:grid;place-items:center;padding:22px}
    .code-prev{width:min(1100px,100%);height:min(86vh,100%);display:flex;flex-direction:column;
      background:#fff;border-radius:var(--r);overflow:hidden;
      box-shadow:0 30px 70px -20px rgba(28,35,55,.5)}
    .code-prev-h{display:flex;align-items:center;gap:8px;padding:10px 14px;
      background:var(--surface-strong);border-bottom:1px solid var(--stroke)}
    .code-prev-t{flex:1;font-size:.72rem;font-weight:800;letter-spacing:.05em;
      text-transform:uppercase;color:var(--ink-3)}
    .code-prev-b{border:1px solid var(--stroke);cursor:pointer;font-family:inherit;
      display:inline-flex;align-items:center;justify-content:center;
      min-height:var(--btn-h-lg);padding:0 var(--btn-px-lg);border-radius:var(--btn-r);
      font-size:var(--btn-fs-lg);font-weight:700;
      color:var(--ink-2);background:#fff;box-shadow:var(--shadow);transition:.12s}
    .code-prev-b:hover{color:var(--ink);transform:translateY(-1px)}
    .code-prev-f{flex:1;width:100%;border:0;background:#fff}
    /* Hláška, ktorá ostane po zbúranom ráme (uviaznutý beh Pythonu). Rám sa
       búra celý — jeho vlákno je zablokované, takže povedať to musí rodič. */
    /* Pozadie si NEDEFINUJE — dedí ho z `.code-prev`, ktoré má v tmavom režime
       vlastnú farbu (dark.css). Vlastné biele pozadie by v tmavom svietilo. */
    .py-run-note{flex:1;display:flex;align-items:center;justify-content:center;
      text-align:center;padding:26px;font-size:.84rem;font-weight:600;
      color:var(--ink-2);line-height:1.6}
    .py-run-note[hidden]{display:none}

    .cp-ans .md-tw{overflow-x:auto;margin:7px 0;border-radius:10px;border:1px solid var(--line)}
    .cp-ans .md-t{border-collapse:collapse;width:100%;font-size:.7rem}
    .cp-ans .md-t th,.cp-ans .md-t td{padding:5px 9px;text-align:left;white-space:nowrap;border-bottom:1px solid var(--line-soft)}
    .cp-ans .md-t th{background:var(--fill-1);font-weight:800;color:var(--ink);position:sticky;top:0}
    .cp-ans .md-t tbody tr:last-child td{border-bottom:0}
    .cp-ans .md-t tbody tr:nth-child(even) td{background:var(--hover)}
    .cp-ans.err{color:var(--rose);background:rgba(255,241,242,.7);border-color:rgba(225,29,72,.25)}
    .cp-hint{font-size:.8rem;color:var(--ink-2);font-weight:500;line-height:1.5;margin-bottom:10px}
    .cp-form{display:flex;gap:8px}
    /* Rozmery a farby berie zo spoločného pravidla pre polia — tu ostáva len
       to, že pole má v riadku s tlačidlom zabrať zvyšok šírky. */
    .cp-form input{flex:1;width:auto}
    .cp-form button{border:0;cursor:pointer;width:42px;border-radius:var(--r-sm);color:#fff;font-weight:800;font-size:1rem;
      background:var(--grad);box-shadow:0 8px 18px -6px rgba(79,70,229,.5)}
    .cp-form button:disabled{opacity:.5;cursor:not-allowed}
    .cp-full{display:inline-block;margin-top:10px;font-size:.74rem;font-weight:700;color:var(--indigo)}
    .spin{display:inline-block;width:14px;height:14px;border:2px solid rgba(79,70,229,.25);border-top-color:var(--indigo);
      border-radius:50%;animation:spin .8s linear infinite;vertical-align:-2px;margin-right:6px}
    @keyframes spin{to{transform:rotate(360deg)}}

    /* Copilot quick-question chips */
    .cp-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px}
    .cp-chip{display:inline-flex;align-items:center;font-size:var(--btn-fs);font-weight:600;
      color:var(--ink-2);background:var(--surface-strong);
      border:1px solid var(--stroke);border-radius:999px;
      min-height:var(--btn-h);padding:0 var(--btn-px);cursor:pointer;line-height:1.2;
      text-align:left;box-shadow:var(--shadow);transition:transform .14s,box-shadow .14s,color .14s}
    .cp-chip:hover{transform:translateY(-1px);color:var(--ink);box-shadow:var(--shadow-lift)}
    /* Copilot footer: full-page link + "Nová téma" reset */
    .cp-foot{display:flex;align-items:center;gap:12px;margin-top:10px}
    .cp-foot .cp-full{margin-top:0;flex:1}
    .cp-newtopic{border:1px solid var(--stroke);background:var(--surface-strong);cursor:pointer;
      display:inline-flex;align-items:center;justify-content:center;
      min-height:var(--btn-h);padding:0 var(--btn-px);border-radius:var(--btn-r);
      font-size:var(--btn-fs);font-weight:700;color:var(--ink-2);
      box-shadow:var(--shadow);transition:transform .14s,color .14s;flex:none}
    .cp-newtopic:hover{transform:translateY(-1px);color:var(--ink)}
    /* mdLite rendered markdown inside answer bubbles */
    .cp-ans p+p{margin-top:.5em}
    .cp-ans ul,.cp-ans ol{margin:.3em 0;padding-left:1.25em}
    .cp-ans li{margin:.12em 0}
    .cp-ans code{background:var(--fill-3);border-radius:5px;padding:1px 5px;font-size:.9em;
      font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
    /* per-widget active-filter chip in the tile header */
    .f-chip{flex:none;font-size:var(--btn-fs-sm);font-weight:800;letter-spacing:.02em;
      padding:3px var(--btn-px-sm);border-radius:999px;
      color:var(--indigo);background:rgba(79,70,229,.12);text-transform:none;max-width:90px;
      overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:help}
    /* Pareto: cumulative % curve + 80 % threshold overlaid on the bars plot */
        /* SVG s viewBox sa pri width/height:auto riadi vlastným pomerom strán (tu
       1:1), NIE okrajmi — kreslilo sa preto štvorcové a krivka vytŕčala pod
       graf. Rozmer preto zadávame explicitne (30px = miesto pre os vľavo). */
    .pareto-curve{position:absolute;left:30px;top:0;width:calc(100% - 30px);height:100%;
      pointer-events:none;overflow:visible}
    .pareto-line{fill:none;stroke:#fb7185;stroke-width:2;vector-effect:non-scaling-stroke;stroke-linejoin:round;stroke-linecap:round}
    .pareto-dot{fill:#fb7185}
    .pareto-80{stroke:rgba(28,35,55,.4);stroke-width:1;stroke-dasharray:3 3;vector-effect:non-scaling-stroke}
    /* Pie/donut (bar↔koláč prepínač) — responsive: legenda vpravo, pod pri úzkom */
    .pie-wrap{display:flex;align-items:center;gap:16px;flex-wrap:wrap;flex:1;min-height:0;margin-top:6px}
    .pie-svg{flex:none;width:clamp(96px,42%,148px);aspect-ratio:1;max-width:100%}
    .pie-legend{flex:1;min-width:130px;display:flex;flex-direction:column;gap:5px;min-width:0}
    .pie-leg-row{display:flex;align-items:center;gap:8px;font-size:.74rem;font-weight:600;color:var(--ink-2);min-width:0}
    .pie-sw{width:10px;height:10px;border-radius:3px;flex:none}
    .pie-leg-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
    .pie-leg-val{font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums;flex:none}
    .pie-leg-pct{color:var(--ink-3);font-weight:600;font-variant-numeric:tabular-nums;min-width:34px;text-align:right;flex:none}
    /* AI summary widget */
    .ai-gen{display:inline-flex;align-items:center;gap:7px;
      min-height:var(--btn-h-lg);padding:0 var(--btn-px-lg);border-radius:var(--btn-r);cursor:pointer;border:0;
      font-size:var(--btn-fs-lg);font-weight:700;color:#fff;background:var(--grad);
      box-shadow:0 10px 24px -8px rgba(79,70,229,.5);transition:.15s}
    .ai-gen:hover{transform:translateY(-1px);box-shadow:0 14px 30px -8px rgba(79,70,229,.6)}
    .ai-gen svg{width:15px;height:15px}
    .ai-foot{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
    .ai-time{font-size:.72rem;color:var(--ink-3);font-weight:600;flex:1;min-width:0}
    .ai-refresh{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--stroke);cursor:pointer;
      background:var(--surface-strong);border-radius:var(--btn-r);
      min-height:var(--btn-h);padding:0 var(--btn-px);font-size:var(--btn-fs);font-weight:700;
      color:var(--ink-2);box-shadow:var(--shadow);transition:transform .14s,color .14s}
    .ai-refresh:hover{transform:translateY(-1px);color:var(--ink)}
    .ai-refresh:disabled{opacity:.5;cursor:not-allowed}
    .ai-refresh svg{width:13px;height:13px}

    .empty{font-size:.82rem;color:var(--ink-3);font-weight:500;text-align:center;padding:22px 0}
    /* Dva a DOSŤ. Prázdny stav sa líšil paddingom stránku od stránky (10, 14,
       18, 26, 30, 48…), pritom sú to len tri situácie: riadok v tabuľke
       (základ), tichý riadok v karte (`sm`) a prázdna plocha panelu (`lg`). */
    .empty.lg{padding:48px 0}
    .empty.sm{padding:10px 0}
    /* Chybový box: tučný nadpis a drobný vysvetľujúci riadok. Stránky si to
       písali inline štýlom v šablóne (`style="font-size:.82rem;opacity:.85"`),
       takže rovnaká chyba vyzerala na každej obrazovke inak. */
    .errbox b{font-weight:800}
    .errbox p,.errbox small{font-size:.82rem;opacity:.85;margin:0}
    .skl{background:linear-gradient(90deg,var(--fill-1) 25%,var(--fill-3) 37%,var(--fill-1) 63%);
      background-size:400% 100%;animation:skl 1.4s ease infinite;border-radius:10px}
    @keyframes skl{0%{background-position:100% 0}100%{background-position:0 0}}
    .errbox{grid-column:span 12;background:linear-gradient(160deg,rgba(255,241,242,.82),rgba(255,255,255,.6));
      border:1px solid rgba(225,29,72,.3);border-radius:var(--r);box-shadow:var(--shadow);padding:20px;
      display:flex;align-items:flex-start;gap:12px;color:var(--rose)}
    /* ── Akcie v obsahu majú tvar tlačidla ────────────────────────────────
       Roman 8/2026: akcia sa nesmie tváriť ako holý text. Bývalá rodina
       „textových odkazov v tvare tlačidla" (.al-more, .bl-old button,
       .errbox button, .rl-all, .ro-mfr-more, …) dostala tvar tlačidla
       z tokenov. Vzhľad je TU (spoločný základ, viď v2-controls.md o poliach),
       stránkové súbory si nechávajú len rozloženie (margin, align-self).
       Zoznam a stupne stráži tests/test_v2_buttons.py. */
    .al-more,.bl-old button,.errbox button,.ro-mfr-more,.rs-f-more,.rd-rawtog,.cl-link,
    .rl-all,.md-link,.rv-conf,.wt-jump,.lb-link,.kpi-retry,.wol-fix{
      display:inline-flex;align-items:center;justify-content:center;gap:6px;
      min-height:var(--btn-h);padding:0 var(--btn-px);border-radius:var(--btn-r);
      font-family:inherit;font-size:var(--btn-fs);font-weight:700;line-height:1.2;
      color:var(--ink-2);background:var(--surface-strong);border:1px solid var(--stroke);
      cursor:pointer;text-decoration:none;transition:.15s}
    .al-more:hover,.bl-old button:hover,.errbox button:hover,.ro-mfr-more:hover,
    .rs-f-more:hover,.rd-rawtog:hover,.cl-link:hover,.rl-all:hover,.md-link:hover,
    .rv-conf:hover,.wt-jump:hover,.lb-link:hover,.kpi-retry:hover,
    .wol-fix:hover{color:var(--ink);transform:translateY(-1px)}
    /* husté miesta — bunka tabuľky, riadok súčtu, hlavička kategórie: sm */
    .rl-all,.md-link,.rv-conf,.wt-jump,.lb-link,.kpi-retry,.wol-fix{
      min-height:var(--btn-h-sm);padding:0 var(--btn-px-sm);
      border-radius:var(--btn-r-sm);font-size:var(--btn-fs-sm)}
    /* chybový kontext ostáva ružový, ale už s tvarom tlačidla */
    .errbox button{margin-top:8px;color:var(--rose);border-color:rgba(225,29,72,.35);background:transparent}
    .errbox button:hover{color:var(--rose)}
    .kpi-retry{margin-left:6px;color:var(--rose);border-color:var(--rose-line);background:transparent}
    .kpi-retry:hover{color:var(--rose)}

    /* ── Mikro-text: `.hint` pod poľom, `.note` k sekcii ───────────────────
       Dva rôzne texty, ktoré si každá stránka písala nanovo (`.ph-hint`,
       `.md-hint`, `.wo-note`, `.pm-note`…): popisok POD ovládačom („formát
       DBn.DBX0.0") je drobný a tlmený, poznámka k sekcii je o stupeň väčšia,
       čitateľná ako veta a stojí v toku obsahu. Rozdiel je v role, nie
       v nálade — preto majú meno a nie vlastné číslo na každej stránke. */
    /* `.mo-note` a `.dr-note` sú staré mená tých istých dvoch vecí
       (poruchy, zásuvka detailu) — ostávajú ako ALIAS tu, nie ako
       vlastná kópia hodnôt v breakdowns.css. */
    .hint,.mo-note{font-size:.72rem;color:var(--ink-3)}
    .note,.dr-note{font-size:.76rem;font-weight:500;line-height:1.5;color:var(--ink-2);margin:0}
    /* Obal ikony z registra `ic` (`<span class="icn" v-html="ic['sync']">`).
       Bez neho je SVG v `v-html` obyčajný riadkový prvok: v `.iconbtn`
       (inline-grid) sa nezarovná na stred a vo flexovom riadku sa zmršťuje.
       Písali si ho plc.css aj runtime.css — teraz je JEDEN. */
    .icn{display:inline-flex;flex:none;align-items:center}

    /* Ikona v položke ponuky je značka, nie obrázok — 14 px v každom paneli.
       Bez rozmeru si SVG bez `width` vezme celú šírku panelu (stalo sa to
       odznaku výstrahy v PLC mapovaniach 2026-09-04). */
    .dd-panel .dd-btn svg{width:14px;height:14px}

    /* ── Nebezpečná akcia: JEDEN modifikátor `.danger` ─────────────────────
       Zmazať, zamietnuť, zverejniť natrvalo. Bolo to ŠESTNÁSŤ definícií toho
       istého v dvanástich súboroch (`.pl-danger`, `.md-btn-danger`,
       `.ph-btn-danger`, `.cl-danger`, `.le-danger`, `.aa-danger`,
       `.bc-danger`, `.danger-solid`, `.btn-del`, `.us-ic.danger`, `.rc-rej`
       a štyri kópie `.ghost.danger`) — a rozišli sa: jedna farbila rám, druhá
       nie, tretia mala vlastnú červenú mimo palety.

       Mení LEN farbu. Rozmer si tlačidlo ďalej berie zo svojej rodiny
       (`.ghost` 38 · `.iconbtn` 32 · `.btn-add` 38), takže sa stupnica
       38/32/26 nerozíde — presne ako to hovorí docs/v2-buttons.md.

       Ružová je z tokenov (`--rose`, `--rose-soft`, `--rose-line`) a písmo na
       plnej ploche z `--on-accent`: v tmavej téme je `--rose` svetlá 400-ka
       a biely nápis na nej má 2,0:1. */
    .ghost.danger{color:var(--rose);border-color:var(--rose-line)}
    .ghost.danger:hover:not(:disabled){color:var(--rose);background:var(--rose-soft);border-color:var(--rose)}
    /* Ikona v riadku je červená AŽ pod myšou — červený kôš v každom riadku by
       z tabuľky spravil výstrahu. */
    .iconbtn.danger:hover:not(:disabled){background:var(--rose-soft);color:var(--rose)}
    /* Nevratná položka ponuky sa musí líšiť FARBOU, nie len textom — v zozname
       rovnako vyzerajúcich riadkov sa klikne omylom. */
    .dd-btn.danger{color:var(--rose)}
    .dd-btn.danger:hover{background:var(--rose-soft);color:var(--rose)}
    /* Plná podoba: potvrdzujúce tlačidlo nesie farbu NÁSLEDKU, nie farbu
       „ďalej" (zverejniť odkaz, zmazať nástenku). */
    .btn-add.danger{background:var(--rose);border-color:var(--rose);color:var(--on-accent);
      box-shadow:0 8px 18px -8px rgba(190,18,60,.6)}
    .btn-add.danger:hover{filter:brightness(1.06);box-shadow:0 8px 18px -8px rgba(190,18,60,.6)}

    /* Staré stránkové meno tej istej veci. Z pôvodných dvanástich prežilo
       B6 jediné — `.rc-rej` v `repairable_spare_card.html`; ostatné (`.pl-danger`,
       `.md-danger`, `.md-btn-danger`, `.md-bulk-danger`, `.cl-danger`,
       `.le-danger`, `.bc-danger`, `.aa-danger`, `.danger-solid`, `.btn-del`,
       `.us-ic.danger`, `.ph-btn-danger`) už žiadna šablóna ani JS nepoužíva,
       tak sú preč. Alias smie iba ubúdať: každý selektor medzi značkami musí
       byť naozaj použitý — stráži `tests/test_v2_consistency.py`
       (`test_danger_aliasy_su_len_pre_zive_triedy`). Keď aj `.rc-rej` prejde
       na `.danger`, zmizne celý blok. */
    /* @danger-alias-start */
    .rc-rej:hover:not(:disabled){color:var(--rose);border-color:var(--rose)}
    /* @danger-alias-end */

    /* Šípka poradia v ponuke widgetu (`ic.up` / `ic.down`) — značka pri
       slove, nie obrázok. */
    .wm-arr{display:inline-flex;vertical-align:-2px;margin-right:2px}
    .wm-arr svg{width:14px;height:14px}

    /* add-widget modal */
    /* ── Modál, prázdny stav, chybový box — JEDNA definícia (vlna 2, 2026-08-23)
       Predtým: dve kópie `.modal-back/.modal` (tu a v breakdowns.css — iný
       z-index, šírka aj rádius; poradie súborov rozhodovalo, ktorá vyhrá) a 15
       stránkových dvojíc `.xx-modal/.xx-modal-a`, žiadna s role="dialog".
       Markup: .modal-back > .modal[role=dialog][aria-modal=true] > .mo-head
       (h2 + .mo-x) / .mo-body / .mo-foot. Šírku mení len .modal-sm/.modal-lg.
       `.modal-head` ostáva ako alias pre V2 dialógy bez vlastnej šablóny.
       Stráži tests/test_v2_primitives.py. */
    .modal-back{position:fixed;inset:0;z-index:100;background:rgba(28,35,55,.34);backdrop-filter:blur(4px);
      display:grid;place-items:center;padding:20px}
    .modal{width:min(620px,100%);max-height:90vh;display:flex;flex-direction:column;
      background:var(--cover,rgba(247,249,253,.98));backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
      border:1px solid var(--stroke);border-radius:var(--r-modal);box-shadow:0 30px 70px -20px rgba(28,35,55,.4);
      animation:modalin .2s cubic-bezier(.33,0,.2,1)}
    .modal-sm{width:min(440px,100%)}
    .modal-lg{width:min(880px,100%)}
    @keyframes modalin{from{transform:translateY(10px) scale(.99);opacity:.5}to{transform:none;opacity:1}}
    .mo-head,.modal-head{display:flex;align-items:center;gap:12px;padding:18px 20px 12px;border-bottom:1px solid var(--line-soft)}
    .mo-head h2,.modal-head h2,.modal-head h3{flex:1;font-size:1.05rem;font-weight:800;letter-spacing:-.02em;margin:0}
    .mo-body{padding:16px 20px;overflow-y:auto;display:flex;flex-direction:column;gap:11px}
    /* Deti flex stĺpca majú `min-width:auto` — široká tabuľka v `.tscroll` by
       telo modálu roztiahla nad šírku telefónu (modál vyhľadávania zariadení,
       snímka 2026-09-13). S `min-width:0` sa posúva tabuľka, nie stránka. */
    .mo-body>*{min-width:0;max-width:100%}
    .mo-foot{display:flex;justify-content:flex-end;gap:9px;padding:12px 20px 18px;border-top:1px solid var(--line-soft)}
    .mo-foot button[disabled]{opacity:.6;cursor:not-allowed}
    /* Chyba servera v PÄTE modálu (`<p class="… mo-err">` ako prvé dieťa
       `.mo-foot`): v tele bola pod okrajom okna (~700 px) a tlačidlo akoby nič
       neurobilo (preklik 2026-10-11). Vlastný riadok nad tlačidlami, vzhľad
       nesie trieda stránky (`.cp-ans.err`, `.md-err`…), tu je len rozloženie. */
    .mo-foot:has(>.mo-err){flex-wrap:wrap}
    .mo-foot>.mo-err{flex:1 1 100%;min-width:0;min-height:0;margin:0;max-height:30vh;overflow:auto;
      overflow-wrap:anywhere}
    .mo-x,.modal-head button{border:0;background:var(--fill-2);cursor:pointer;width:34px;height:34px;border-radius:var(--r-sm);
      color:var(--ink-2);font-size:1rem;display:grid;place-items:center;flex:none}
    .mo-x:hover,.modal-head button:hover{background:var(--fill-3);color:var(--ink)}
    /* Krížik sa KRESLÍ, nepíše. Znak „×" sedí v Plus Jakarta Sans medzi
       účiarím a x-výškou, takže jeho tuš je o 3 px pod stredom riadku a v
       každom modáli vyzeral posunutý dole (2026-09-03). Dve čiary cez
       currentColor: farba ide z tlačidla (aj dark.css), text ostáva pre
       čítačky (aria-label + font-size:0). */
    .mo-x{font-size:0;line-height:0}
    .mo-x::before{content:'';width:12px;height:12px;transform:rotate(45deg);
      background:linear-gradient(currentColor,currentColor) center/100% 2px no-repeat,
                 linear-gradient(currentColor,currentColor) center/2px 100% no-repeat}
    /* Klávesnica v primitívoch (B4): kým bol obrys len globálny tyrkysový
       `:focus-visible`, na krížiku modálu a v riadkoch ponuky sa strácal —
       obrys sedel presne na hrane tlmenej plochy. Ponuka a modál majú preto
       vlastný, indigový a zatiahnutý dovnútra (`outline-offset:-2px`), aby ho
       neorezal `overflow:auto` v `.dd-tall`. Farba VŽDY tokenom: v tme má
       `--indigo` inú hodnotu a hex by na tmavom podklade zhasol. */
    .mo-x:focus-visible,.modal:focus-visible{outline:2px solid var(--indigo);outline-offset:2px}
    .dd-panel .dd-btn:focus-visible,.dd-panel .dd-row:focus-visible,
    .dd-panel button:focus-visible,.dd-panel a:focus-visible,
    .dd-row input:focus-visible{outline:2px solid var(--indigo);outline-offset:-2px;
      border-radius:var(--btn-r-sm)}
    .dd>button:focus-visible{outline:2px solid var(--indigo);outline-offset:2px}
    /* Prázdny stav: `.empty` = jeden riadok tlmeného textu; `.empty-full` = blok
       (ikona v dlaždici, nadpis, veta, akcia) — vzor z Násteniek, predtým 15 mien
       (.kb-empty, .nb-empty, .ab-empty, .lb-empty, .tx-empty, .shr-empty…) — posledný
       stránkový názov (.ab-empty zo zvončeka) padol v nightrun B3. */
    .empty-full{display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px;padding:40px 16px}
    .empty-ic{width:56px;height:56px;border-radius:var(--card-r);background:var(--fill-2);display:grid;place-items:center;color:var(--teal);flex:none}
    .empty-ic svg{width:26px;height:26px}
    .empty-full h2{font-size:1.05rem;font-weight:800;letter-spacing:-.02em;color:var(--ink);margin:0}
    .empty-full p{max-width:420px;font-size:.84rem;font-weight:600;line-height:1.6;color:var(--ink-2);margin:0}
    .empty-full .btn-add,.empty-full .ghost{margin-top:6px}

    /* ── Komponenty (vlna 5 zjednotenia, docs/v2-design-system.md) ────────────
       Vzory, ktoré si každá stránka prepísala nanovo. Merané 2026-08-26 nad
       `static/css/v2/*.css` (4 136 pravidiel v 49 stránkových súboroch):
       nadpis sekcie 12×, KPI dlaždica 6×, tabuľka 13×, odznak-pilulka 31×,
       mikro-popisok 42×. Stránka ich odteraz VOLÁ; vlastnú kópiu nepíše —
       stráži `tests/test_v2_components.py`.

       Nadpis sekcie: riadok „h2 + doplnky vpravo" nad panelom alebo v ňom.
       Bol 12× (.aa-sec-h, .aic-sec-h, .bc-sec-h, .mvo-sec-h, .pa-sec-h,
       .kw-sec-h, .mo-sec-h, .cr-sec-h, .ti-sec-h DVAKRÁT — v plc_tia.css aj
       tia_explorer.css, .ta-sec-h, .shr-sec-h, .pd-diag-h) a líšili sa len
       spodnou medzerou (8/10/12) a tým, či h2 vôbec dostal veľkosť. */
    .sec-h{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px}
    .sec-h h2{font-size:.95rem;font-weight:800;margin:0;display:flex;align-items:center;gap:8px}
    .sec-h .spacer{flex:1;min-width:8px}

    /* Mikro-popisok — VEĽKÝMI, tlmene, nad hodnotou alebo pred ňou („STANICA",
       „POSLEDNÝ BEH", „ZMENA"). Merané: 143 pravidiel v 42 súboroch malo
       `text-transform:uppercase` + `letter-spacing`, z toho vyše dvadsať bolo
       presne toto — a každé s vlastným písmom (.6 / .62 / .63 / .64 / .66 /
       .68 / .7 / .72 rem) a vlastným rozpalom (.04 / .05 / .06 em). Vedľa
       seba to nikto neuvidí, ale dve stránky vedľa seba vyzerali inak.
       `.blk` = popisok NAD prvkom (vlastný riadok), `.inl` = pred hodnotou
       v riadku. `small` vnútri je doplnok bežným písmom. */
    .lbl{font-size:.66rem;font-weight:800;letter-spacing:.05em;text-transform:uppercase;
      color:var(--ink-3);overflow-wrap:anywhere}
    .lbl.blk{display:block;margin-bottom:5px}
    .lbl.inl{margin-right:6px}
    /* Popisok stojaci V RIADKU s ovládačom („Obnovovať každých [30 s]") — sám
       si drží zvislé zarovnanie, aby sa nemusel obaľovať ďalším flexom. */
    .lbl.row{display:inline-flex;align-items:center;gap:6px;flex:none}
    .lbl small{font-size:.62rem;font-weight:600;text-transform:none;letter-spacing:0;
      margin-left:7px;opacity:.8}
    /* Popisok ako POLOŽKA flex riadku — v pruhu rýchlych filtrov (`.qbar`,
       na telefóne posuvný riadok) a pred ovládačom vnútri `.lbl.row` — sa
       nesmie stlačiť: `overflow-wrap:anywhere` mu dovolí zúžiť sa na jedno
       písmeno a na iPhone sa vysádzal zvislo po písmenách („PROJEKTY" na
       Pracovnom čase, „OBLA/SŤ" na MCP serveri — sweep 2026-10-01). Ten istý
       prípad bol `.qseg-cap` (2026-09-15) — toto je jeho všeobecná podoba. */
    .qbar > .lbl, .lbl.row > span:first-child{flex-shrink:0;white-space:nowrap}
    /* Nadpis skupiny v ponuke `.dd-panel` — patrí k primitívu ponuky, a predsa
       stál dvakrát (boards.css 7/10/5, breakdowns.css 6/9/4). */
    .dd-cap{font-size:.6rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
      color:var(--ink-3);padding:7px 10px 5px}

    /* KPI dlaždica: pruh čísel nad obsahom stránky (`.kpis` mriežka,
       `.kpi` = panel s popiskom `<span>`, číslom `<b>` a doplnkom `<i>`/
       `<small>`). Bola šesťkrát (.aa-kpi, .aic-kpi, .bc-kpi, .pa-kpi,
       .mo-kpi, .shr-kpi = 47 pravidiel) a rozchádzala sa v maličkostiach:
       číslo malo 1,05 / 1,25 / 1,35 / 1,4 rem, medzera 2 alebo 4 px,
       `letter-spacing` .04 alebo .06 em — vedľa seba to nikto neuvidí, ale
       stránky vyzerali každá inak.
       Počet stĺpcov je JEDINÉ, čo si stránka nastavuje: `style="--kpi-n:5"`
       (mimo škály nič nie je, je to počet dlaždíc). Zúžený pruh deviatich
       čísel (hlásenie zo zmeny) je `.kpis.dense`. */
    .kpis{display:grid;grid-template-columns:repeat(var(--kpi-n,4),1fr);gap:12px;margin-bottom:14px}
    .kpi{display:flex;flex-direction:column;gap:2px;padding:13px 15px}
    .kpi span{font-size:.68rem;font-weight:700;text-transform:uppercase;
      letter-spacing:.04em;color:var(--ink-3)}
    .kpi b{font-size:1.3rem;font-weight:800;color:var(--ink);
      display:flex;align-items:baseline;gap:6px}
    .kpi i,.kpi small{font-style:normal;font-size:.7rem;font-weight:600;color:var(--ink-3)}
    /* Tón sa dá povedať na čísle (`<b class="bad">`) aj na dlaždici
       (`<div class="kpi bad">`) — obe zápisy sa v stránkach vyskytovali. */
    .kpi b.ok,.kpi.ok b{color:var(--green)}
    .kpi b.warn,.kpi.warn b{color:var(--amber)}
    .kpi b.bad,.kpi.bad b{color:var(--rose)}
    .kpi i.up{color:var(--amber)}
    .kpi i.down{color:var(--green)}
    .kpis.dense{gap:8px;margin-bottom:8px;--kpi-n-sm:3}
    .kpis.dense .kpi{padding:10px 12px}
    .kpis.dense .kpi span{font-size:.6rem}
    .kpis.dense .kpi b{font-size:1.05rem}
    .kpis.dense .kpi i{font-size:.66rem;font-weight:700}
    /* Užšia obrazovka mení POČET STĹPCOV, nie triedu — mediálne pravidlá sú
       v spoločných blokoch na konci súboru (vlastný mediálny blok tu by testom
       mobilnej lišty podstrčil nesprávny: hľadajú PRVÝ výskyt otváracieho
       riadku pre 900 px a krájajú od neho — preto ho tento komentár ani
       nesmie vypísať doslova). Prepisuje sa
       `grid-template-columns`, nie `--kpi-n`: keby premennú, `style="--kpi-n:5"`
       na prvku by ho prebilo (inline vyhráva nad hárkom) a pruh by na telefóne
       ostal päťstĺpcový. */

    /* Tabuľka mimo zoznamovej stránky (`.btab` zo zoznamov je vlastný, hustejší
       vzor s výberom riadkov a triedením — ten ostáva). Merané: 13 samostatných
       `border-collapse` definícií a 169 pravidiel `th`/`td`. Boli to DVE rodiny,
       každá napísaná 3–4×:
       - holá mriežka v paneli — `.aic-tbl`, `.mvo-tbl`, `.mo-tbl` boli znak po
         znaku tá istá (7 pravidiel × 3), `.shr-table` o vlások iná,
       - tabuľka ako karta — `.an-t`, `.st-t`, `.us-t`: rovnaký povrch, rám,
         rádius a tieň, len padding 10/13 vs. 11/14 a písmo .8 vs. .82 rem.
       Preto `.tbl` (mriežka) a `.tbl.boxed` (karta). Zarovnanie čísel
       (`td.num`), manko/prebytok (`td.mi`/`td.pl`) a stlmený riadok (`tr.off`)
       boli tiež v každom súbore zvlášť — sú tu raz. */
    .tbl{width:100%;border-collapse:collapse;font-size:.76rem}
    .tbl th{font-size:.64rem;font-weight:800;text-transform:uppercase;letter-spacing:.05em;
      color:var(--ink-3);text-align:left;padding:7px 9px;border-bottom:1px solid var(--stroke)}
    .tbl td{padding:8px 9px;border-bottom:1px solid var(--stroke);vertical-align:top}
    .tbl tr:last-child td{border-bottom:0}
    .tbl th.num,.tbl td.num,.tbl .r{text-align:right;font-variant-numeric:tabular-nums}
    .tbl .c{text-align:center}
    .tbl td.mi{color:var(--rose);font-weight:700}
    .tbl td.pl{color:var(--green);font-weight:700}
    .tbl tr.off td{opacity:.55}     /* vypnutý agent / účet — riadok stlmený */
    /* Karta: rám a tieň nesie sama tabuľka, preto `overflow:hidden` — inak
       podklad hlavičky prečnieva cez zaoblený roh. */
    .tbl.boxed{background:var(--surface);border:1px solid var(--stroke);
      border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow)}
    .tbl.boxed th{font-size:.62rem;letter-spacing:.06em;padding:10px 13px;
      background:var(--hover);white-space:nowrap}
    .tbl.boxed td{padding:9px 13px;border-bottom:1px solid var(--line-soft);
      font-size:.8rem;color:var(--ink-2);vertical-align:middle}
    .tbl.boxed tbody tr:hover td{background:var(--hover-row)}
    /* Triediteľná hlavička: kurzor a stmavnutie textu. Bolo trikrát to isté. */
    .tbl th.sortable{cursor:pointer;user-select:none}
    .tbl th.sortable:hover{color:var(--ink-2)}
    /* Toast — GLOBÁLNE (predtým žil v breakdowns.css, no `<div class="toast">`
       a V2.toast ho tvoria na 25 stránkach). Dark override je v dark.css. */
    .toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%);z-index:100;
      background:rgba(23,29,48,.95);color:#fff;font-size:.82rem;font-weight:700;
      padding:11px 20px;border-radius:14px;box-shadow:0 16px 36px -10px rgba(23,29,48,.55);
      animation:toastin .2s ease;display:flex;align-items:center;gap:14px}
    @keyframes toastin{from{transform:translate(-50%,8px);opacity:0}to{transform:translate(-50%,0);opacity:1}}
    @media(prefers-reduced-motion:reduce){.toast{animation:none}.modal{animation:none}}
    /* Akcia v toaste (napr. „Vrátiť" po zmazaní, plc_rules.js). `.toast` má
       vlastné pevné farby (nie tokeny — je to vrstva nad celou stránkou,
       rovnaká v oboch témach), takže hranica aj hover vychádzajú z
       `currentColor` (farba textu toastu), nie z nového natvrdo zapísaného
       odtieňa. */
    .toast-action{background:transparent;border:1px solid color-mix(in srgb,currentColor 35%,transparent);
      color:inherit;font-family:inherit;border-radius:999px;padding:4px 12px;
      font-size:.78rem;font-weight:800;cursor:pointer;white-space:nowrap;flex:0 0 auto}
    .toast-action:hover{background:color-mix(in srgb,currentColor 15%,transparent)}
    .toast-action:focus-visible{outline:2px solid currentColor;outline-offset:2px}
    /* Druh oznamu (`V2.toast(msg, {kind})`, core.js): plocha toastu ostáva,
       druh nesie odznak so ZNAKOM (✓ / !) vo farbe akcentu — farba nie je
       jediný nosič. Akcent + `--on-accent` je overená dvojica v oboch témach
       (tests/test_v2_dark.py), takže tmavá vrstva tu nič prepisovať nemusí. */
    .toast-kind{flex:0 0 auto;width:20px;height:20px;border-radius:50%;display:grid;
      place-items:center;font-size:.74rem;font-weight:900;line-height:1;
      background:var(--teal);color:var(--on-accent)}
    .toast-ok .toast-kind{background:var(--green)}
    .toast-bad .toast-kind{background:var(--rose)}
    .toast-warn .toast-kind{background:var(--amber)}
    .cat-group{margin-bottom:16px}
    .cat-group-title{font-size:.68rem;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-bottom:9px;padding-left:2px}
    .cat-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px}
    .cat-item{display:flex;flex-direction:column;align-items:stretch;gap:4px;text-align:left;
      background:rgba(255,255,255,.7);border:1px solid var(--stroke);border-radius:16px;padding:14px 16px;transition:.14s}
    .cat-item:hover{transform:translateY(-2px);box-shadow:var(--shadow);border-color:var(--teal)}
    /* Karta je div (nesie ešte tlačidlá upraviť/zmazať), samotný výber je
       tlačidlo cez celú jej plochu. */
    .cat-pick{display:flex;flex-direction:column;align-items:flex-start;gap:4px;text-align:left;
      cursor:pointer;background:transparent;border:0;padding:0;width:100%;color:inherit;font:inherit}
    .cat-ic{width:34px;height:34px;border-radius:var(--r-sm);display:grid;place-items:center;color:var(--indigo);
      background:linear-gradient(135deg,rgba(20,184,166,.16),rgba(79,70,229,.16));margin-bottom:4px}
    .cat-ic svg{width:18px;height:18px}
    .cat-t{font-size:.9rem;font-weight:800;color:var(--ink)}
    .cat-d{font-size:.74rem;color:var(--ink-2);font-weight:500}
    /* .cat-grid na telefóne: v hlavnom mobilnom bloku nižšie (jeden blok pre
       640 px — test mobilnej lišty kráji CSS od PRVÉHO takého bloku). */
    .cat-item.mine{border-color:rgba(79,70,229,.35);background:linear-gradient(180deg,rgba(79,70,229,.07),rgba(255,255,255,.72))}
    .cat-item.mine .cat-ic{color:var(--teal)}
    .cat-item.mine .cat-t::after{content:"moje";margin-left:7px;font-size:.6rem;font-weight:800;
      letter-spacing:.08em;text-transform:uppercase;color:var(--indigo);
      background:rgba(79,70,229,.13);border-radius:999px;padding:2px 7px;vertical-align:middle}
    .cat-own{display:flex;gap:6px;margin-top:10px}
    .cat-own button{flex:1;border:1px solid var(--line);background:#fff;cursor:pointer;
      display:inline-flex;align-items:center;justify-content:center;
      min-height:var(--btn-h);padding:0 var(--btn-px);border-radius:var(--btn-r);
      font:inherit;font-size:var(--btn-fs);font-weight:700;color:var(--ink-2)}
    .cat-own button:hover{border-color:var(--teal);color:var(--ink)}
    .cat-own button.del:hover{border-color:var(--rose);color:var(--rose)}

    /* zoznam vlastných definícií (aj tých, čo už na ploche sú) */
    .uw-defs{display:flex;flex-direction:column;gap:8px}
    .uw-def{display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:var(--r-sm);
      background:rgba(255,255,255,.66);border:1px solid var(--stroke)}
    .uw-def-ic{width:28px;height:28px;flex:none;border-radius:9px;display:grid;place-items:center;color:var(--indigo);
      background:linear-gradient(135deg,rgba(20,184,166,.16),rgba(79,70,229,.16))}
    .uw-def-ic svg{width:15px;height:15px}
    .uw-def-t{flex:1;min-width:0}
    .uw-def-t b{display:block;font-size:.84rem;font-weight:800;color:var(--ink);
      overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
    .uw-def-t span{font-size:.68rem;font-weight:600;color:var(--ink-3);font-family:ui-monospace,monospace}
    .uw-def button{border:1px solid var(--line);background:#fff;cursor:pointer;
      display:inline-flex;align-items:center;justify-content:center;
      min-height:var(--btn-h);padding:0 var(--btn-px);border-radius:var(--btn-r);
      font:inherit;font-size:var(--btn-fs);font-weight:700;color:var(--ink-2);flex:none}
    .uw-def button:hover{border-color:var(--teal);color:var(--ink)}
    .uw-def button.del:hover{border-color:var(--rose);color:var(--rose)}
    /* Hlavné tlačidlo definície (Pridať) a veta „už na dashboarde". Pri piatich tlačidlách sa akcie zalomia pod názov —
       preto `flex-basis` názvu (s `flex:1 1 0` by ho tlačidlá stlačili na nulu). */
    .uw-def{flex-wrap:wrap}
    .uw-def-t{flex-basis:160px}
    .uw-def-acts{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:6px;margin-left:auto}
    .uw-def button.go{border-color:var(--teal);color:var(--teal)}
    .uw-def-on{font-size:var(--btn-fs);font-weight:700;color:var(--ink-3);padding:0 4px}
    /* štítok „verejný" (definícia, karta ponuky) — tokeny, takže tmavá téma
       netreba zvlášť */
    .uw-pub{font-size:.6rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
      border-radius:999px;padding:2px 7px;flex:none;white-space:nowrap;
      color:var(--teal);background:var(--teal-soft)}
    .cat-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}
    .uw-chip.pub{color:var(--teal);background:var(--teal-soft)}
    .uw-new{width:100%;display:flex;align-items:center;justify-content:center;gap:8px;cursor:pointer;
      border:1px dashed rgba(79,70,229,.45);background:rgba(79,70,229,.06);color:var(--indigo);
      border-radius:var(--btn-r);min-height:var(--btn-h-lg);padding:0 var(--btn-px-lg);
      font:inherit;font-size:var(--btn-fs-lg);font-weight:800}
    .uw-new:hover{background:rgba(79,70,229,.12)}
    .uw-new svg{width:16px;height:16px}

    /* ── widget z opisu (v ponuke „Pridať widget") ──────────────────────── */
    .uw-ai{margin-top:12px;border:1px solid rgba(79,70,229,.28);border-radius:16px;padding:14px 15px;
      background:linear-gradient(180deg,rgba(79,70,229,.07),rgba(20,184,166,.05))}
    .uw-ai-h{display:flex;align-items:center;gap:8px;color:var(--indigo);font-size:.84rem;font-weight:800}
    .uw-ai-h svg{width:16px;height:16px;flex:none}
    /* Vzhľad (vrátane 16px písma, ktoré bráni priblíženiu na iPhone) je zo
       spoločného pravidla pre polia. Tu ostáva len výška hlavného vstupu
       tejto funkcie a odstup od nadpisu. */
    .uw-ai textarea{margin-top:9px;min-height:56px}
    .uw-ai textarea:disabled{opacity:.6}
    .uw-ai-ex{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:8px;
      font-size:.7rem;font-weight:700;color:var(--ink-3)}
    .uw-ai-ex button{cursor:pointer;border:1px solid rgba(79,70,229,.28);background:rgba(255,255,255,.72);
      display:inline-flex;align-items:center;color:var(--ink-2);border-radius:999px;
      min-height:var(--btn-h-sm);padding:0 var(--btn-px-sm);
      font:inherit;font-size:var(--btn-fs-sm);font-weight:600}
    .uw-ai-ex button:hover{border-color:var(--indigo);color:var(--ink)}
    .uw-ai-ex button:disabled{opacity:.5;cursor:default}
    .uw-ai-row{display:flex;align-items:center;gap:10px;margin-top:10px}
    .uw-ai-cnt{flex:1;font-size:.68rem;font-weight:700;color:var(--ink-3)}
    .uw-ai-go{display:flex;align-items:center;gap:8px;cursor:pointer;border:0;border-radius:var(--btn-r);
      min-height:var(--btn-h-lg);padding:0 var(--btn-px-lg);
      font:inherit;font-size:var(--btn-fs-lg);font-weight:800;color:#fff;
      background:linear-gradient(135deg,var(--indigo),var(--teal))}
    .uw-ai-go:disabled{opacity:.55;cursor:default}
    .uw-ai-go .spin{border-color:rgba(255,255,255,.4);border-top-color:#fff}
    .uw-ai-note{margin:9px 0 0;font-size:.72rem;font-weight:500;line-height:1.5;color:var(--ink-2)}
    .uw-ai-err{margin-top:10px;border-radius:12px;padding:10px 12px;font-size:.76rem;font-weight:700;
      color:var(--rose);background:rgba(244,63,94,.08);border:1px solid rgba(244,63,94,.24)}
    .uw-ai-err .h{margin-top:5px;font-weight:600;color:var(--ink-2)}
    .uw-ai-acts{display:flex;gap:7px;margin-top:9px}
    .uw-ai-acts button{cursor:pointer;border:1px solid rgba(28,35,55,.14);background:#fff;
      display:inline-flex;align-items:center;justify-content:center;
      min-height:var(--btn-h);padding:0 var(--btn-px);border-radius:var(--btn-r);
      font:inherit;font-size:var(--btn-fs);font-weight:700;color:var(--ink-2)}
    .uw-ai-acts button:hover{border-color:var(--teal);color:var(--ink)}
    .uw-ai-acts button:disabled{opacity:.5;cursor:default}

    /* ── vygenerovaný widget na ploche ────────────────────────────────────
     * Vykresľuje ho zdieľaný widget_render.js. Jeho štýly BÝVALI TU, ako jedna
     * zo ŠTYROCH kópií toho istého (kiosk × 2, builder, tu) — každá s inými
     * číslami, takže ten istý widget vyzeral na štyroch miestach inak.
     * Odteraz sú v static/css/widget_render.css pod triedami s prefixom `wr-`;
     * dlaždica k `.uw` len pridá `wr` (viď šablónu). Scopovať netreba: prefix
     * je práve to, čo bránilo kolízii s /v2 `.bars` (zvislý stĺpcový graf)
     * a `.val` (nadpisová hodnota). Tu ostáva len rozmer miesta na ploche. */
    .uw{flex:1;min-height:0;overflow:hidden;display:flex;flex-direction:column}
    .uw-chip{font-size:var(--btn-fs-sm);font-weight:800;letter-spacing:.07em;text-transform:uppercase;
      color:var(--indigo);background:rgba(79,70,229,.13);border-radius:999px;
      padding:3px var(--btn-px-sm);flex:none}
    .uw-gone{flex:1;min-height:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
      gap:4px;text-align:center}
    .uw-gone-t{font-size:.84rem;font-weight:800;color:var(--ink)}
    .uw-gone p{font-size:.74rem;color:var(--ink-3);font-weight:500}
    .uw-gone button{margin-top:9px;border:0;cursor:pointer;background:var(--rose-soft);color:var(--rose);
      display:inline-flex;align-items:center;justify-content:center;
      min-height:var(--btn-h);padding:0 var(--btn-px);border-radius:var(--btn-r);
      font:inherit;font-size:var(--btn-fs);font-weight:800}
    /* Hláška po vyrobení/zmazaní widgetu (dlaždica pribudne na koniec plochy,
       často mimo obrazovky — bez nej to vyzerá, že sa nič nestalo). */
    .uw-note{display:flex;align-items:center;gap:10px;margin:0 0 14px;padding:11px 15px;border-radius:14px;
      background:rgba(13,148,136,.12);color:var(--ink);font-size:.8rem;font-weight:700}
    .uw-note span{flex:1;min-width:0}
    .uw-note button{border:0;background:transparent;cursor:pointer;color:var(--ink-3);font-size:.85rem;
      line-height:1;padding:4px}

    /* ── tvorca widgetu ───────────────────────────────────────────────────
     * Modal má pevnú hlavu aj pätku a roluje sa len telo — na telefóne je
     * formulár dlhý a tlačidlo „Vytvoriť" musí byť stále na dosah. Kostru
     * (šírku, hlavu, rolujúce telo, pätku) drží kanonický `.modal-lg` +
     * `.mo-head/.mo-body/.mo-foot`; tu ostáva len to, čím sa pätka tvorcu
     * líši — hláška vľavo a zalomenie na úzkej obrazovke. */
    .mo-foot.wfm-foot{align-items:center;flex-wrap:wrap;gap:8px}
    .wf-missing{flex:1;min-width:130px;font-size:.72rem;font-weight:600;color:var(--amber)}
    /* Tlačidlá pätky sú spoločné `.ghost` a `.btn-add` (oboje stupeň lg) —
       `.wf-ghost`/`.wf-save` boli ich kópia s bielym `#fff` natvrdo, ktorý
       v tmavej téme musel prepisovať `dark.css` (B5, 2026-09-07). */
    .wf-step{font-size:.66rem;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3);
      margin:18px 0 9px;padding-bottom:6px;border-bottom:1px solid var(--line-soft)}
    .wf-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:11px}
    .wf-f{display:flex;flex-direction:column;gap:5px;min-width:0}
    .wf-f>span{font-size:.7rem;font-weight:800;color:var(--ink-2);display:flex;align-items:center;gap:7px}
    /* Prepínač zap/vyp stojí v slote poľa, takže je priamym potomkom `.wf-f` —
       ale nie je to popisok a nesmie zdediť jeho drobné písmo. */
    .wf-f>span.switch{font-size:.84rem;color:var(--ink-2);gap:10px}
    .wf-f .req{font-style:normal;font-size:.56rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
      color:var(--rose);background:var(--rose-soft);border-radius:999px;padding:2px 6px}
    /* Rozmery, farby aj zameranie sú v spoločnom pravidle pre polia vyššie —
       vrátane 16px písma, ktoré bráni priblíženiu stránky na iPhone. */
    /* Technický názov argumentu vedľa slovenského popisku — v chybových
       hláškach servera vystupuje pod ním, takže musí byť vidieť. */
    .wf-f .tech{font-style:normal;font-size:.6rem;font-weight:700;color:var(--ink-3);opacity:.75;
      font-family:ui-monospace,monospace}
    .wf-desc{font-style:normal;font-size:.68rem;color:var(--ink-3);font-weight:500}
    .wf-intro{font-size:.78rem;color:var(--ink-2);font-weight:500;line-height:1.5;margin:0 0 14px}
    /* Prúžok „toto je návrh". Jantárová, nie zelená: predvyplnené polia sa
       majú prejsť, nie odklepnúť. */
    .wf-ai-note{margin:0 0 14px;border:1px solid rgba(245,158,11,.35);background:var(--amber-soft);
      border-radius:var(--r-sm);padding:11px 13px}
    .wf-ai-note .t{display:flex;align-items:center;gap:8px}
    .wf-ai-note .t b{flex:1;font-size:.8rem;font-weight:800;color:var(--amber)}
    .wf-ai-note .t button{flex:none;border:0;background:transparent;cursor:pointer;color:var(--ink-3);
      font:inherit;font-size:.8rem;line-height:1;padding:2px 4px}
    .wf-ai-note p{margin:6px 0 0;font-size:.75rem;font-weight:500;line-height:1.5;color:var(--ink-2)}
    .wf-ai-note p.w{font-style:italic;color:var(--ink-3)}
    .wf-ai-note ul{margin:7px 0 0;padding-left:18px;font-size:.73rem;font-weight:600;color:var(--ink-2)}
    .wf-ai-note li{margin-top:3px}
    /* Dátumové čipy: token namiesto pevného dátumu je jediná vec, ktorá
       odlišuje živý widget od widgetu zamrznutého v deň vzniku. */
    .wf-chips{display:flex;flex-wrap:wrap;align-items:center;gap:5px}
    .wf-chips button{border:1px solid var(--line);background:#fff;cursor:pointer;border-radius:999px;
      display:inline-flex;align-items:center;min-height:var(--btn-h-sm);padding:0 var(--btn-px-sm);
      font:inherit;font-size:var(--btn-fs-sm);font-weight:700;color:var(--ink-2)}
    .wf-chips button.on{background:var(--teal);border-color:transparent;color:var(--on-accent)}
    .wf-chips b{font-size:.66rem;font-weight:700;color:var(--ink-3)}
    .wf-chips b.warn{color:var(--amber)}
    .wf-hint{font-size:.74rem;color:var(--ink-3);font-weight:500;margin:4px 0 2px}
    /* Technický názov nástroja vedľa popisu — drobný a odlíšený, aby sa dal
       spárovať s chybovou hláškou zo servera, ale nesúperil s popisom. */
    .wf-tname{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.68rem;
      background:var(--fill-2);border-radius:5px;padding:1px 5px;margin-right:6px}
    .wf-types{display:flex;gap:7px;flex-wrap:wrap}
    .wf-types.sub{margin:11px 0}
    .wf-types button{border:1px solid var(--line);background:#fff;cursor:pointer;
      display:inline-flex;align-items:center;justify-content:center;
      min-height:var(--btn-h);padding:0 var(--btn-px);border-radius:var(--btn-r);
      font:inherit;font-size:var(--btn-fs);font-weight:700;color:var(--ink-2)}
    .wf-types button.on{background:var(--grad);color:#fff;border-color:transparent}
    .wf-keys{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:10px 0;font-size:.7rem}
    .wf-keys b{font-weight:800;color:var(--ink-2)}
    .wf-key{background:var(--fill-2);border-radius:8px;padding:3px 8px;font-weight:700;color:var(--ink-2);
      font-family:ui-monospace,monospace}
    .wf-key i{font-style:normal;font-weight:600;color:var(--ink-3);opacity:.8}
    .wf-cols{display:flex;flex-direction:column;gap:8px;margin-top:11px}
    .wf-col{display:flex;gap:7px;align-items:center}
    .wf-col button{flex:none;width:38px;height:38px;border-radius:var(--r-sm);border:1px solid var(--line);
      background:#fff;cursor:pointer;color:var(--ink-3);font-size:.85rem}
    .wf-col button:hover{border-color:var(--rose);color:var(--rose)}
    .wf-addcol{align-self:flex-start;border:1px dashed rgba(28,35,55,.2);background:transparent;cursor:pointer;
      display:inline-flex;align-items:center;justify-content:center;
      border-radius:var(--btn-r);min-height:var(--btn-h);padding:0 var(--btn-px);
      font:inherit;font-size:var(--btn-fs);font-weight:700;color:var(--ink-2)}
    .wf-prevbox{position:relative;min-height:130px;display:flex;flex-direction:column;
      border:1px solid var(--stroke);border-radius:16px;padding:14px 16px;background:rgba(255,255,255,.66)}
    .wf-prevhint{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;gap:8px;
      font-size:.78rem;font-weight:600;color:var(--ink-3);pointer-events:none}
    .wf-warn{margin-top:9px;font-size:.74rem;font-weight:700;color:var(--amber);
      background:var(--amber-soft);border-radius:var(--r-sm);padding:9px 12px}
    .wf-err{margin-top:12px;font-size:.78rem;font-weight:700;color:var(--rose);
      background:var(--rose-soft);border-radius:var(--r-sm);padding:10px 13px}

    /* Pätka s firmou (nahradila technický popis stacku). */
    .v2-foot{display:flex;align-items:center;justify-content:center;gap:9px;
      margin-top:auto;padding:20px 0 18px}
    /* Na Copilote je pätka mimo .main (chat má pevnú výšku), tak si musí
       odsadenie od railu vziať sama — inak by podliezla pod rail. */
    #app>.v2-foot{margin-left:79px;margin-top:0;padding:2px 24px 10px}
    .v2-foot img{height:20px;width:auto;opacity:.9}
    .v2-foot span{font-size:.72rem;font-weight:600;color:var(--ink-3);letter-spacing:.01em}

    @media(max-width:1080px){.c3,.c4{grid-column:span 6}.c5,.c6,.c7,.c8{grid-column:span 12}
      .bento{grid-auto-rows:auto}.h1,.h2,.h3,.r2{grid-row:auto}
      /* Tu už výšku neurčuje mriežka, ale obsah — a skeleton žiadny obsah nemá,
         takže by mal ~80 px namiesto 150–480 px a plocha by po príchode dát
         narástla o tisíce pixelov. Rovnaké čísla, aké drží grid-auto-rows. */
      .tile-skl.h1{min-height:152px}
      .tile-skl.h2,.tile-skl.r2{min-height:319px}
      .tile-skl.h3{min-height:486px}}
    /* ── Široký rail (voľba „Popisky ikon" v podmenu Vzhľad) ──
       Triedu `rail-wide` na <html> nastavuje _head_theme.html pred prvým
       vykreslením. LEN desktop — mobilná zásuvka nižšie je široká vždy
       a tieto pravidlá by sa s ňou bili. Vzor je práve ona: popisok .tip
       prestáva byť bublinou a stáva sa názvom položky. */
    /* Tlačidlo zbaliť/rozbaliť menu na hrane railu. Mimo desktopu sa nekreslí
       (mobilná zásuvka je široká vždy). Šípka ukazuje, čo klik urobí. */
    .rail-collapse{display:none}
    @media(min-width:901px){
      .rail-collapse{position:absolute;top:22px;right:-13px;width:26px;height:26px;border-radius:50%;
        display:grid;place-items:center;padding:0;cursor:pointer;z-index:3;
        background:var(--surface-strong,var(--surface));border:1px solid var(--stroke);color:var(--ink-2);
        box-shadow:0 2px 8px rgba(20,24,40,.18)}
      .rail-collapse svg{width:14px;height:14px;transition:transform .15s}
      .rail-collapse:hover{color:var(--ink);border-color:var(--ink-3)}
      .rail-collapse:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
      html:not(.rail-wide) .rail-collapse svg{transform:rotate(180deg)}
      html.rail-wide .rail{width:216px;align-items:stretch;padding-left:10px;padding-right:10px}
      html.rail-wide .rail .logo{margin-left:2px}
      html.rail-wide .rail nav{align-items:stretch}
      html.rail-wide .rail-item{width:100%;height:auto;min-height:46px;display:flex;
        align-items:center;justify-content:flex-start;gap:11px;padding:0 12px}
      html.rail-wide .rail-item svg{flex:none}
      html.rail-wide .rail-item .tip{position:static;opacity:1;transform:none;background:none;
        color:inherit;box-shadow:none;padding:0;font-size:.84rem;font-weight:700;z-index:auto}
      html.rail-wide .rail-item .tip::before{display:none}
      html.rail-wide .rail-group.open .tip{display:block}
      html.rail-wide .rail-item[aria-current="page"]::before{left:-10px;height:26px}
      html.rail-wide .rail-group{width:100%;place-items:stretch}
      html.rail-wide .rail-group>.rail-item{width:100%;padding:0 12px}
      html.rail-wide .rail-dot{right:12px;bottom:auto;top:50%;transform:translateY(-50%)}
      /* Popisok Profilu je meno človeka (core.js `userLabel`), nie krátke
         slovo „Profil" — mená sú rôzne dlhé a rail má pevnú šírku. `flex:1`
         + `min-width:0` dovolí .tip zmrštiť sa POD obsah (bez min-width:0 by
         flex položka nikdy neklesla pod šírku textu a preteklo by mimo panel
         namiesto orezania). */
      html.rail-wide .rail-group.rail-foot>.rail-item .tip{flex:1;min-width:0;
        overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
      /* Podmenu sa vysúva vedľa ŠIRŠIEHO panela. */
      html.rail-wide .rail-sub{left:200px}
      html.rail-wide .rail-foot{width:100%;height:auto;min-height:46px;display:flex;
        align-items:center;justify-content:flex-start;gap:11px;padding:0 12px}
      /* rail right edge = 16+216 = 232px; rovnaká vôľa ako pri úzkom (79/88). */
      html.rail-wide .main{margin-left:223px}
      html.rail-wide #app>.v2-foot{margin-left:223px}
    }

    @media(max-width:900px){
      .kpis{grid-template-columns:repeat(var(--kpi-n-sm,2),1fr)}
      .main{margin-left:0;padding-top:70px;padding-bottom:0}
      #app>.v2-foot{margin-left:0;padding:0 14px 12px}
      .nav-btn{display:grid}
      /* Na telefóne to nie je úzka lišta, ale ZÁSUVKA.
       *
       * Kým bola široká 72 px, mala tri chyby naraz: názvy sekcií sa ukazovali
       * len po prejdení myšou (na dotyk teda nikdy), rozbalené podmenu sa
       * textom vylialo mimo panela, a keď bol obsah vyšší než obrazovka, spodné
       * položky sa nedali dosiahnuť — rail nerolovaal. */
      .rail{transform:translateX(-120%);transition:transform .25s ease;
        width:min(272px,82vw);align-items:stretch;padding:14px 10px;gap:2px;
        /* Hamburger aj zvonček sú `fixed` v ľavom hornom rohu a inak by
           prekryli logo. */
        padding-top:64px}
      .rail .logo{margin-left:2px}
      /* Rolovanie patrí ZOZNAMU, nie celej zásuvke — logo aj Profil majú ostať
         na mieste. `contain` drží ťah prsta vnútri, nech neroluje stránku pod ňou. */
      /* Zvonček je tu hore pri tlačidle navigácie, takže slot dole netreba. */
      .rail nav{align-items:stretch;-webkit-overflow-scrolling:touch;
        padding-bottom:10px;margin-bottom:0}
      .rail-foot{width:100%;height:auto;min-height:46px;display:flex;
        align-items:center;justify-content:flex-start;gap:11px;padding:0 12px}
      /* Profil je SKUPINA (.rail-group.rail-foot): pravidlo vyššie z nej robilo
         flex riadok, takže rozbalené podmenu sedelo VEDĽA karty ako druhý
         stĺpec — karta natiahnutá na výšku, menu úzke a mimo zásuvky (Roman,
         iPhone 2026-09-15). V zásuvke ide podmenu POD položku ako pri sekciách. */
      .rail-group.rail-foot{display:block;padding:0;gap:0}
      .rail-item{width:100%;height:auto;min-height:46px;display:flex;
        align-items:center;justify-content:flex-start;gap:11px;padding:0 12px}
      .rail-item svg{flex:none}
      /* Popisok prestáva byť bublinou a stáva sa názvom položky. */
      .rail-item .tip{position:static;opacity:1;transform:none;background:none;
        color:inherit;box-shadow:none;padding:0;font-size:.84rem;font-weight:700;
        z-index:auto}
      .rail-item .tip::before{display:none}
      /* Na desktope sa popisok pri otvorenom podmenu skrýva, lebo je to bublina
         a prekážala by vysunutému panelu. Tu je to NÁZOV SEKCIE — po rozbalení
         Administrácie by inak ostal pri ikone prázdny riadok. */
      .rail-group.open .tip{display:block}
      .rail-item[aria-current="page"]::before{left:-10px;height:26px}
      .rail-group{width:100%;place-items:stretch}
      /* Odsadenie sa musí zopakovať aj tu: `.rail-group>.rail-item{padding:0}`
         mimo médií má dve triedy a prebilo by `.rail-item{padding:0 12px}`
         s jednou (mediálne pravidlo špecifickosť nezvyšuje) — ikony PLC
         a Administrácie boli preto o 12 px vľavo oproti ostatným položkám.
         Musí sedieť s paddingom `.rail-item` vyššie. */
      .rail-group>.rail-item{width:100%;padding:0 12px}
      /* Bodka „rozbaľuje sa" ide na koniec riadku, nie do rohu ikony. */
      .rail-dot{right:12px;bottom:auto;top:50%;transform:translateY(-50%)}
      /* V zásuvke nie je vedľa railu miesto — podmenu sa rozbalí pod položkou. */
      .rail-sub{position:static;min-width:0;width:100%;margin-top:4px;box-shadow:none;
        background:var(--fill-1);border:0;padding:5px}
      .rail-sub-cap{display:none}
      .rail-sub-item{white-space:normal}
      .rail.open{transform:translateX(0)}
    }
    /* Užšie okno: hľadanie ostáva presne v strede, len sa zúži na ikonu —
       nikdy nevytlačí zo stredu (pravý stĺpec sa skráti prvý, `.ph-act`
       má `overflow:hidden`). Rovnaké pravidlo platí aj v galérii (`.gc .ph`,
       docs len — nepoužité v appke, ale nech sedí, keby pribudlo). */
    @media(max-width:900px){
      .ph{grid-template-columns:minmax(0,1fr) 40px minmax(0,1fr);position:relative}
      .srch .srch-box{display:none}
      .srch .srch-ic{display:inline-grid}
      /* Otvorené hľadanie v úzkom okne: pole prekryje celý 1. riadok hlavičky
         (absolútne voči `.ph`, NIE fixed — predok s transform/filtrom by
         fixed prvok odniesol inam, Nástenka na mobile 2026-09-27), paleta
         pod ním na celú šírku. */
      .srch.open{position:static}
      .srch.open .srch-ic{visibility:hidden}
      /* Pole aj paleta sú tu NAD obsahom stránky (nadpis, karty), nie vedľa
         neho ako na širokom okne — priesvitná `--surface-strong` (.82/.9)
         nechala nadpis presvitať cez výsledky. `--cover` je krycia plocha
         zásuviek a modálov, takmer nepriehľadná v oboch témach. */
      .srch.open .srch-box{display:flex;position:absolute;left:0;right:0;top:0;z-index:70;
        background:var(--cover)}
      .srch.open .pal{left:0;right:0;width:auto;top:calc(var(--btn-h-lg) + 8px);z-index:70;
        background:var(--cover)}
    }
    @media(max-width:640px){.main{padding:14px 14px 0}.bento{gap:14px}
      .kpis.dense{grid-template-columns:repeat(2,1fr)}
      .cat-grid{grid-template-columns:1fr}
      .c3,.c4,.c5,.c6,.c7,.c8{grid-column:span 12}.hero .big{font-size:2.8rem}
      /* Telefón: nadpis ide VEDĽA fixného hamburgera (odsadenie namiesto
         horného paddingu) a ovládanie sa nenaťahuje na celú šírku — inak
         lišta zožerie štyri riadky skôr, než začnú widgety. */
      .topbar{gap:8px;margin-bottom:14px}
      .ph{margin-bottom:14px}.ph:has(+ .ph-row2){margin-bottom:0}.ph-row2{margin-bottom:14px}
      /* Miesto pre hamburger (14–58) aj zvonček alarmov (66–112). Nadpis musí
         zabrať celý riadok: pri 390 px ostáva vedľa neho ~75 px, čo na tlačidlo
         nestačí a nadpis by sa zalomil do dvoch riadkov — to je horšie než
         tlačidlo v druhom riadku. */
      .topbar>div:first-child{flex:1 1 100%;padding-left:118px;min-height:44px}
      .topbar h1{font-size:1.28rem}
      .topbar .sub{margin-top:2px;font-size:.8rem}
      .topbar .spacer{display:none}
      /* Tlačidlá v lište sa na telefón zmenšujú TOKENOM na konci súboru, nie
         pravidlom pre túto lištu. Predtým tu bola skratka `padding`, ktorá
         zmazala `padding-right:30px` z .ghost-sel a šípka výberu si sadla na
         text — token sa vodorovného odsadenia zvlášť netýka, takže tá pasca
         zanikla. */
      /* ⚙ malo dotykový cieľ 22 px — na palec málo, a je to jediná cesta
         k nastaveniu widgetu. Ikona ostáva rovnaká, rastie len plocha. */
      .gear{padding:9px;margin:-9px -6px -9px 0}
      /* Nová hlavička (`.ph`) na telefóne: rovnaké pravidlo ako `.topbar` —
         nadpis na celý riadok vedľa fixného hamburgera, akcie pod ním.
         Hľadanie (stále len ikona od 980px) sa presúva k zvončeku — v mriežke
         by pri jednom stĺpci nemalo kam sadnúť. */
      .ph{display:flex;flex-wrap:wrap;gap:8px}
      .ph-title{flex:1 1 100%;padding-left:118px;min-height:44px}
      .ph-title h3{font-size:1.28rem}
      /* Nadpis (názov nástenky, stanice, číslo kusu RS…) má na telefóne vedľa
         hamburgera a lupy ~240 px — tri riadky, inak z čísla kusu ostalo
         „AC-AngleDrive-…"; celé znenie nesie aj `title`. */
      .ph-title h3 .t{-webkit-line-clamp:3;line-clamp:3}
      /* Vedľa hamburgera a lupy ostáva podnadpisu ~200 px — dva riadky
         nestačili ani Pracovnému času, tak na telefóne tri. */
      .ph-title .sub{margin-top:2px;font-size:.8rem;-webkit-line-clamp:3;line-clamp:3}
      .ph-act{flex:1 1 100%;justify-content:flex-start}
      /* Lupa na konci riadku s nadpisom (vpravo), nie fixed — v mriežke by
         pri jednom stĺpci nemala kam sadnúť a fixed ju pod predkom
         s transformom odnášalo do stredu stránky. */
      .ph-title{flex:1 1 0;order:1}
      .srch{order:2;flex:0 0 auto;grid-column:auto}
      .srch .srch-ic{width:44px;height:44px}
      .ph-act{order:3}
      .srch.open .srch-box{height:44px}
      .srch.open .pal{top:52px}
      /* ── Hlavička S AKCIAMI (vlna 2 mobilu, 2026-10-15) ───────────────────
         Akcie („Viac", „Nový…", export) boli samostatný riadok POD nadpisom
         a nadpisu ostávalo vedľa hamburgera a lupy ~190 px — „Mapovanie PLC
         tagov" na dva riadky, akcie Opraviteľných kusov na ďalšie dva.
         Teraz najviac dva riadky, vzor hlavičky stroja (tia_explorer.css):
           1. riadok NÁSTROJOV vedľa hamburgera a zvončeka: šípka späť vľavo,
              vedľajšie akcie (ponuka „Viac", tlačidlá slotu) a lupa vpravo
              (lupa pri nedostatku miesta k nadpisu — nižšie),
           2. nadpis s podnadpisom a VEDĽA NEHO hlavná akcia (`.btn-add`,
              split „+ Pridať ▾" = `.hm-prim`) — ako na PC.
         Nadpis do JEDNÉHO riadku s akciami sa nezmestí: na 375 px mu vedľa
         hamburgera, zvončeka, lupy, „Viac" a „Pridať poruchu" ostávalo ~20 px.
         Obaly `.ph-title` a `.ph-act` sú `display:contents`, ich deti sú
         položkami riadku hlavičky a poradie určuje `order`. `::before` drží
         miesto fixného hamburgera a zvončeka (14–112 px, ako `padding-left`
         nadpisu vyššie) aj výšku 1. riadku; `::after` na celú šírku riadky
         oddelí. Hlavička BEZ akcií ostáva po starom — nadpis vedľa
         hamburgera, žiadny riadok navyše. */
      /* Režim nástrojov zapne AKCIA v `.ph-act` (odkaz, tlačidlo, výber,
         ponuka). Vedľajšia akcia = akcia, ktorá nie je hlavná; čokoľvek iné
         v slote (stav pripojenia PLC, pečiatka, odznak) je STAV a ide na
         vlastný riadok pod nadpis — tam, kde bol doteraz. */
      .ph:has(> .ph-act > :is(a,button,select,.dd)){row-gap:4px}
      .ph:has(> .ph-act > :is(a,button,select,.dd))::before{content:'';order:1;flex:0 0 110px;height:44px}
      .ph:has(> .ph-act > :is(a,button,select,.dd))>.ph-title,.ph:has(> .ph-act > :is(a,button,select,.dd))>.ph-act{display:contents}
      .ph:has(> .ph-act > :is(a,button,select,.dd))>.ph-title>.iconbtn{order:2;flex:none}
      .ph:has(> .ph-act > :is(a,button,select,.dd))>.ph-act>*{order:3;flex:none}
      .ph:has(> .ph-act > :is(a,button,select,.dd))>.ph-act>:nth-child(1 of :is(a,button,select,.dd):not(.btn-add,.hm-prim,.ph-pc)){margin-left:auto}
      .ph:has(> .ph-act > :is(a,button,select,.dd))>.srch{order:4}
      .ph:has(> .ph-act > :is(a,button,select,.dd)):not(:has(> .ph-act > :is(a,button,select,.dd):not(.btn-add,.hm-prim,.ph-pc)))>.srch{margin-left:auto}
      .ph:has(> .ph-act > :is(a,button,select,.dd))::after{content:'';order:5;flex:0 0 100%;height:0}
      .ph:has(> .ph-act > :is(a,button,select,.dd))>.ph-title>div{order:6;flex:1 1 0;min-width:0}
      .ph:has(> .ph-act > :is(a,button,select,.dd))>.ph-act>:is(.btn-add,.hm-prim){order:7}
      .ph:has(> .ph-act > :is(a,button,select,.dd))>.ph-act>:not(a,button,select,.dd){order:9;flex:1 1 100%;min-width:0}
      /* Lupa ide na koniec riadku s nadpisom, keď by riadok nástrojov
         nestačil: pri troch a viac vedľajších akciách (Opraviteľné kusy:
         Cenník, Fronta rozhodnutí, Ďalšie akcie — aj ako ikony 190 px) a na
         detaile so šípkou späť a textovým tlačidlom `secondary` (`.ph-sec`;
         PLC: ‹ + „Opýtať sa Copilota"). Šípka + „Viac" alebo ikona sa
         s lupou zmestia (stroj, Mapovanie tagov, Objednávky). Dve pravidlá,
         nie zoznam: `:has()` sa nedá vnoriť a neplatný člen zoznamu by
         zhodil celé pravidlo. */
      .ph:has(> .ph-act > :nth-child(3 of :is(a,button,select,.dd):not(.btn-add,.hm-prim,.ph-pc)))>.srch{order:8}
      .ph:has(> .ph-title > .iconbtn):has(> .ph-act > .ph-sec:not(.ph-pc))>.srch{order:8}
      /* Textové tlačidlo v riadku nástrojov sa pri nedostatku miesta skráti
         „…" (celý text ostáva v DOM, čítačka ho prečíta), nezalomí riadok —
         `flex-basis:0` + `max-width:max-content`: rastie len do svojej
         šírky. Tlačidlá s ikonou sú ikony (nižšie). */
      .ph:has(> .ph-act > :is(a,button,select,.dd))>.ph-act>:is(a,button).ghost:not(.ph-pc):not(:has(> svg:first-child)){
        display:block;flex:1 1 0;max-width:max-content;min-width:0;overflow:hidden;
        white-space:nowrap;text-overflow:ellipsis;line-height:calc(var(--btn-h-lg) - 2px)}
      /* Vedľajšia akcia je pri ponuke „Viac" V ponuke (`_page_head.html`). */
      .ph-act>.ph-pc{display:none}
      .dd-btn.ph-mob,.ph-act>.ph-mob{display:block}
      /* Tlačidlá s ikonou v riadku nástrojov sú na telefóne LEN ikona (s
         odznakom počtu, ak ho majú) — Opraviteľné kusy majú v hlavičke
         Cenník, Frontu rozhodnutí a Ďalšie akcie, s textom 430 px na 230.
         Text ostáva v DOM (`font-size:0`, ako krížik okna `.mo-x`), takže ho
         čítačka aj test nájde podľa mena. Ponuka `<hdr-menu>` (`.hm-btn`,
         šípka ZA textom) sa nemení — „Viac ▾" ostáva slovom. */
      .ph-act>.ghost:has(> svg:first-child),
      .ph-act>.dd>.ghost:not(.hm-btn):has(> svg:first-child){
        font-size:0;gap:0;justify-content:center;min-width:var(--btn-h-lg)}
      /* Čip sa skracuje na bodku + čas — plná veta by na 360 px nezmestila
         ani seba, ani akcie vedľa. */
      /* 2. riadok na telefóne: prepínač sa nezalamuje do dvoch riadkov, ale
         posúva do strany; keď je v riadku JEDINÝ (PLC prehľad), zúži sa, aby
         čip obnovy ostal vedľa neho a nezaberal celý riadok sám. */
      .ph-row2 .seg{flex-wrap:nowrap;overflow-x:auto;max-width:100%;scrollbar-width:none}
      .ph-row2 .seg::-webkit-scrollbar{display:none}
      .ph-row2 .seg>*{flex:none}
      /* To isté pre KAŽDÝ prepínač na telefóne, nielen v hlavičke: v karte sa
         zalamoval do dvoch riadkov (Report „Obdobie", Podmienková údržba
         „Udalosti", Failure kódy „Kontrola návrhov" — posledná voľba sama
         na druhom riadku pilulky). Posúva sa do strany ako v hlavičke. */
      .seg{flex-wrap:nowrap;overflow-x:auto;max-width:100%;scrollbar-width:none}
      .seg::-webkit-scrollbar{display:none}
      .seg>*{flex:none}
      .ph-row2 > .seg:first-child:nth-last-child(2){flex:0 1 auto;min-width:0}
      .ph-row2:has(> .seg:first-child:nth-last-child(2)){flex-wrap:nowrap}
      .ph-row2{flex-wrap:wrap;row-gap:8px}
      /* Pás pohľadov a zdroja (`.ph-strip`): JEDEN vodorovne posuvný pás
         namiesto troch riadkov (Alarmy 2026-10-15: pohľady, „Viac pohľadov"
         a zdroj zariadení každé na vlastnom riadku, 156 px). Rovnaký vzor
         ako pás záložiek stroja (`.pd-tabstrip`, plc.css): prepínače vnútri
         sa NEposúvajú samy (inak dva posuvníky v jednom riadku), posúva sa
         celý pás; ponuka „Viac pohľadov" a čip obnovy stoja pevne vedľa neho.
         `flex-basis:0` — pás si vezme zvyšok riadku, nevytlačí ponuku ani
         čip na ďalší riadok. Na otvorený pohľad ho posunie `v-scroll-active`. */
      .ph-strip{display:flex;align-items:center;gap:8px;flex:1 1 0;min-width:0;
        overflow-x:auto;scrollbar-width:none;overscroll-behavior-x:contain}
      .ph-strip::-webkit-scrollbar{display:none}
      .ph-strip>*{flex:none}
      .ph-strip>.seg{overflow:visible;max-width:none}
      .ph-row2>.dd{flex:none}
      .rf-chip{min-width:0}
      .rf-chip .full{display:none}
      .rf-chip .short{display:inline}
    }
    @media(prefers-reduced-motion:reduce){.tile,.bars .bar,.ghost,.gear{transition:none}.skl,.spin{animation:none}
      .spark-anim{animation:none}}

    /* Náklady na diely podľa zariadenia + neaktívne zásoby */
    .top-label .at{font-size:.58rem;font-weight:800;letter-spacing:.05em;margin-left:6px;
      padding:1px 5px;border-radius:5px;background:var(--fill-3);color:var(--ink-3)}
    /* Popis RS za jeho ID — bez neho je „RS-04812" nečitateľné. */
    .top-label .rsd{font-size:.62rem;font-weight:600;color:var(--ink-3);margin-left:7px}
    .plan-bar{position:relative;height:22px;flex:none;border-radius:8px;overflow:hidden;margin:8px 0 10px;
      background:var(--rose-soft);display:flex;align-items:center}
    .plan-fill{position:absolute;left:0;top:0;bottom:0;background:var(--green-soft)}
    .plan-bar span{position:relative;font-size:.62rem;font-weight:800;color:var(--ink-2);
      padding-left:9px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
    .idle-sum{font-size:.78rem;color:var(--ink-2);font-weight:600;margin:6px 0 8px;display:flex;
      align-items:baseline;gap:6px;flex-wrap:wrap;flex:none}
    .idle-sum b{font-size:1.1rem;font-weight:800;color:var(--ink)}
    .idle-sum span{font-size:.62rem;color:var(--ink-3);font-weight:700}

    /* Spodná os pod sparklinou (M/L výška) — mimo .spark-box, aby graf ostal flex. */
    .spark-axis{margin-top:5px}

    /* ── Zvonček aktívnych PLC alarmov (core.js, mimo Vue) ──────────────
       Sedí v päte railu; na mobile je rail zasunutý, tak ho posunieme
       k tlačidlu navigácie, aby ostal dosiahnuteľný. */
    .ab-wrap{position:fixed;left:16px;bottom:82px;width:72px;z-index:60;
      display:flex;justify-content:center}
    .ab-btn{position:relative;width:46px;height:46px;border-radius:var(--card-r);border:0;cursor:pointer;
      display:grid;place-items:center;color:var(--ink-2);background:var(--fill-2);
      transition:background .15s,color .15s,transform .15s}
    .ab-btn:hover{background:var(--fill-3);color:var(--ink);transform:translateY(-1px)}
    .ab-btn svg{width:21px;height:21px}
    .ab-badge{position:absolute;top:-3px;right:-3px;min-width:19px;height:19px;padding:0 5px;
      border-radius:999px;background:var(--rose);color:var(--on-accent);font-size:.6rem;font-weight:800;
      display:grid;place-items:center;box-shadow:0 2px 6px rgba(190,18,60,.4)}
    /* `display:grid` vyššie prebíja [hidden]{display:none} z prehliadača
       (0,1,0 vs 0,0,1), takže odznak svietil ako prázdny červený bod aj vtedy,
       keď žiadny alarm nehorel. */
    .ab-badge[hidden]{display:none}
    .ab-badge.warn{background:var(--amber)}
    .ab-panel{position:absolute;left:64px;bottom:0;width:min(360px,calc(100vw - 96px));
      background:rgba(247,249,253,.98);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
      border:1px solid var(--stroke);border-radius:var(--r);box-shadow:var(--shadow-lift);
      overflow:hidden;text-align:left}
    .ab-head{display:flex;align-items:center;gap:10px;padding:12px 14px;
      background:var(--rose-soft);border-bottom:1px solid var(--line-soft)}
    .ab-head b{flex:1;font-size:.82rem;font-weight:800;color:var(--rose)}
    .ab-head a{font-size:.72rem;font-weight:800;color:var(--rose)}
    .ab-filters{display:flex;gap:6px;padding:9px 14px;border-bottom:1px solid var(--line-soft)}
    .ab-chip{border:1px solid var(--stroke);background:var(--fill-1);color:var(--ink-3);
      display:inline-flex;align-items:center;
      font:inherit;font-size:var(--btn-fs-sm);font-weight:800;text-transform:uppercase;letter-spacing:.04em;
      min-height:var(--btn-h-sm);padding:0 var(--btn-px-sm);border-radius:999px;cursor:pointer;transition:.14s}
    .ab-chip.on.critical{background:var(--rose-soft);color:var(--rose)}
    .ab-chip.on.warning{background:var(--amber-soft);color:var(--amber)}
    .ab-chip.on.info{background:var(--fill-3);color:var(--ink-2)}
    .ab-off{padding:7px 14px;font-size:.66rem;font-weight:800;color:var(--amber);
      background:var(--amber-soft)}
    .ab-list{max-height:min(60vh,420px);overflow-y:auto}
    .ab-row{padding:9px 14px;border-bottom:1px solid var(--line-soft)}
    .ab-row:last-child{border-bottom:0}
    .ab-r1{display:flex;align-items:center;gap:7px}
    .ab-sev{font-size:.56rem;font-weight:800;text-transform:uppercase;letter-spacing:.05em;
      padding:2px 6px;border-radius:5px;background:var(--fill-3);color:var(--ink-3)}
    .ab-sev.critical{background:var(--rose-soft);color:var(--rose)}
    .ab-sev.warning{background:var(--amber-soft);color:var(--amber)}
    .ab-tag{font-size:.66rem;color:var(--ink-3);font-weight:600;overflow:hidden;
      text-overflow:ellipsis;white-space:nowrap;flex:1}
    .ab-dur{font-size:.62rem;font-weight:800;color:var(--ink-3);white-space:nowrap}
    .ab-txt{font-size:.78rem;font-weight:600;color:var(--ink);margin-top:2px;
      overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
    .ab-st{font-size:.62rem;color:var(--ink-3);font-weight:600;margin-top:2px}
    /* Prázdny stav panela je zdieľaný `.empty-full` — `.ab-empty` už nekreslí
       vlastný vzhľad, len zmenší mieru do 360 px širokého panela. Preto je
       každý override viazaný na OBE triedy: `.empty-full` má rovnakú
       špecifickosť (0,1,0) a rozhodovalo by poradie súborov. */
    .ab-empty.empty-full{padding:22px 14px;gap:7px}
    .ab-empty .empty-ic{width:42px;height:42px;border-radius:var(--r-sm)}
    .ab-empty .empty-ic svg{width:21px;height:21px}
    .ab-empty h2{font-size:.86rem}
    .ab-empty p{font-size:.76rem;line-height:1.5}
    .ab-empty.ok .empty-ic{background:var(--green-soft);color:var(--green)}
    .ab-empty.ok h2{color:var(--green)}
    /* „Načítavam…" nie je prázdny stav, ale dočasný oznam — jeden tlmený
       riadok, aby panel počas obnovy neposkakoval na výšku bloku. */
    .ab-loading{display:flex;align-items:center;justify-content:center;gap:7px;
      padding:26px 14px;font-size:.78rem;font-weight:600;color:var(--ink-3)}
    /* Na mobile je rail zasunutý, tak zvonček sadne vedľa tlačidla navigácie.
       Plávajúce rohy sa neosvedčili: vpravo hore sedí ovládanie lišty (na
       tablete), vpravo dole ⚙ widgetov a na Copilote pole pre správu. Tu je
       vždy nad obsahom a nikdy nič neprekrýva. */
    @media(max-width:900px){
      .ab-wrap{left:66px;top:14px;right:auto;bottom:auto;width:auto}
      .ab-btn{background:var(--surface-strong);border:1px solid var(--stroke);
        box-shadow:var(--shadow)}
      .ab-panel{left:0;right:auto;top:56px;bottom:auto;width:min(340px,calc(100vw - 80px))}
      .ab-list{max-height:min(50vh,320px)}
    }


    /* Zoznam sa nikdy neoreže v polovici riadku — počet riadkov dopočíta
       WList podľa nameranej výšky; overflow je tu len poistka. */
    .wlist-rows{overflow:hidden}

    /* h1 (najnižšia dlaždica): telo má ~85 px. Číslo + cieľový chip + popisok
       ho zjedia celé a graf sa oreže. Pri h1 preto ustúpi chip aj popisok
       a číslo sa zmenší — ostane hodnota a trend, teda to podstatné. */
    .tile.h1 .kpi-goal,.tile.h1 .kpi-sub{display:none}
    .tile.h1 .val{font-size:1.45rem;margin:0 0 4px}
    .tile.h1 .cap{display:none}

    /* Tvorca widgetu na telefóne. Blok je ZÁMERNE až tu, na konci súboru:
       test mobilnej lišty krája CSS od PRVÉHO `@media(max-width:640px)`
       a skorší blok by mu podstrčil cudzie pravidlá. */
    @media(max-width:640px){
      .wf-grid{grid-template-columns:1fr}
      .wfm-foot .ghost,.wfm-foot .btn-add{flex:1}
      .wf-missing{flex:1 0 100%}
      .uw-def-t span{display:none}
    }

    /* ── Tlačidlá na telefóne ──────────────────────────────────────────────
       Dvíha sa TOKEN, nie jednotlivé triedy. Mediálny blok nezvyšuje
       špecifickosť, takže pravidlo `@media{.qchip{min-height:32px}}` prehrá
       vždy, keď je v súbore vyššie než to, čo prebíja — a pri troch stupňoch
       naprieč dvanástimi súbormi by sa to muselo strážiť na dvanástich
       miestach. Premenná sa vyhodnocuje pri použití, takže na poradí
       nezáleží.
       26 px sa prstom netrafí (namerané: chipy 27 px, malý prepínač 23 px);
       32 px je spodná hranica. Hlavná akcia ostáva vysoká — len užšia
       a s menším písmom, aby sa lišta zmestila do 390 px. */
    @media(max-width:640px){:root{
      --btn-h-sm:32px;
      --btn-px-lg:12px; --btn-fs-lg:.78rem;
    }}

    /* ── Dotyk: ciele pre prst ─────────────────────────────────────────────
       Rozhoduje UKAZOVADLO, nie šírka okna: tablet na šírku je „desktop"
       podľa šírky, ale ovláda sa prstom; úzke okno na počítači sa ovláda
       myšou a meniť sa nemá. `pointer:coarse` je presne „primárne ukazovadlo
       je prst", takže počítač s myšou (aj s dotykovým displejom navyše)
       ostáva bez zmeny.
       Namerané pri 390 px (preklik 2026-10-11): chipy 24–32 px, podmenu 32,
       zaškrtávacie polia 17×17. Spodná hranica je 40 px; hlavná akcia
       a pole 44 (držia spolu, viď `--fld-h`). Dvíha sa TOKEN — rovnaký
       dôvod ako v bloku nad týmto; blok musí ostať ZA ním, na telefóne
       platia oba a pri rovnakej špecifickosti vyhráva neskorší.
       Prvky s vlastnou výškou mimo tokenu sú dorovnané pri sebe
       (breakdowns, alarms, boards, repairable_spares.css). */
    @media(pointer:coarse){
      :root{
        --btn-h-sm:40px; --btn-h:40px; --btn-h-lg:44px;
        --fld-h:44px; --fld-h-sm:40px;
        --chk:22px;
      }
      .rail-sub-item{min-height:40px}
      /* Prepínač s číslom („25 · 50 · 100" riadkov) mal tlačidlá 34 px úzke. */
      .seg button,.seg a{min-width:40px}
      .gear{padding:12px;margin:-12px -9px -12px 0}
      /* „Otvoriť plný Copilot" v dlaždici bol riadok textu 15 px vysoký. */
      .cp-full{display:inline-flex;align-items:center;min-height:40px}
      .pal-scope .chip{display:inline-flex;align-items:center;min-height:40px}
      .rf-chip{height:40px}
      /* Výber riadku v tabuľke: `<label class="ck-hit">` okolo políčka.
         Samotné políčko sa nedá zväčšiť bez toho, aby narástla aj jeho
         kresba (padding ani rámik plochu kliknutia nezväčšia), label áno —
         klik naň prepne políčko natívne. Záporný okraj vráti rozmer, takže
         riadok nenarastie o 18 px. */
      .ck-hit{display:inline-grid;place-items:center;min-width:40px;min-height:40px;
        margin:-9px;cursor:pointer}
    }

/* Drobná poznámka pod panelom — „toto číslo je spodný odhad", „extrahované diely
   sú inde". Býva to jediné miesto, kde stránka prizná, čo NEVIE, takže musí byť
   čitateľná a nesmie splynúť s obsahom.

   Je TU, a nie pri stránke, ktorá ju zaviedla: používajú ju štyri /v2 stránky
   (zoznam, dokumentácia, skupiny, revízie) a tri z nich štýly zoznamu
   nenačítavajú. Kým bola tam, poznámka na stránke dokumentov vypadla bez štýlu
   a pretiekla z panela — prvé písmeno odrezal jeho okraj. */
.rs-note{margin:11px 15px 14px;font-size:.72rem;line-height:1.45;color:var(--ink-3)}
.rs-note b{color:var(--ink-2)}
@media (max-width:640px){ .rs-note{margin:9px 12px 12px} }

/* ── Flash správy servera vo /v2 ──────────────────────────────────────────
 * „Nemáte oprávnenie" a spol. sa strácali — /v2 flash nevykresľovalo.
 * Server-rendered toasty vpravo hore; zmiznú samy (core.js v2FlashInit)
 * alebo krížikom. Farby z tokenov, fungujú v svetlej aj tmavej téme. */
.v2-flash{position:fixed;top:14px;right:14px;z-index:400;display:flex;
  flex-direction:column;gap:8px;max-width:min(420px,calc(100vw - 28px))}
.v2-flash-i{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;
  border-radius:10px;font-size:.82rem;line-height:1.35;color:var(--ink);
  background:var(--surface-strong);border:1px solid var(--line);
  box-shadow:0 8px 24px rgba(15,23,42,.18)}
/* Chybová hláška bola napísaná cez `var(--red)` — token, ktorý v palete
   nikdy neexistoval, takže sa nenakreslila. Nová 25. farba sa nezavádza:
   červená tejto palety sa volá `--rose` a v tmavej téme sa posúva na #fb7185
   (sýta 500-ka má na tmavom podklade kontrast pod 3:1). */
.v2-flash-i.bad{border-color:var(--rose);}
.v2-flash-i.warn{border-color:var(--amber)}
.v2-flash-i.ok{border-color:var(--line)}
.v2-flash-x{flex:none;margin-left:auto;border:0;background:none;cursor:pointer;
  color:var(--ink-3);font-size:1rem;line-height:1;padding:0 2px}
.v2-flash-x:hover{color:var(--ink)}

/* ══ B2 — zdieľané primitívy (balík B2 dizajnového auditu) ═════════════════
   Blok je zámerne na KONCI súboru a v jednom kuse: vznikal súbežne s inými
   úpravami dashboard.css a takto sa zlučuje bez konfliktu. */

/* ── Varovný pás (`v2Warn` v core.js) ────────────────────────────────────
   Predtým osem riadkov `style.cssText` v JavaScripte: rádius 14 px opísaný
   namiesto tokenu, tieň opísaný namiesto `--shadow` a nič z toho sa nedalo
   prebiť témou ani médiom. JS odteraz nastavuje LEN triedu.
   Farby cez `--warn-*` s náhradou: premenné definuje tmavá vrstva (dark.css),
   bez nej platia pôvodné svetlé hodnoty — na tmavom podklade by inak bola
   svetloružová ploška jediné svietiace miesto na obrazovke. */
.v2-warnband{position:fixed;left:50%;bottom:18px;transform:translateX(-50%);
  z-index:9999;max-width:min(560px,92vw);display:flex;align-items:flex-start;gap:10px;
  padding:12px 14px;border-radius:var(--r-menu);
  background:var(--warn-bg);color:var(--warn-ink);
  border:1px solid var(--warn-line);box-shadow:var(--shadow);
  font-size:.82rem;font-weight:600;line-height:1.45}
.v2-warnband-t{flex:1;min-width:0}
.v2-warnband-x{flex:none;border:0;background:none;color:inherit;cursor:pointer;
  font:inherit;padding:0 2px;opacity:.65}
.v2-warnband-x:hover{opacity:1}

/* `.errbox b` / `.errbox p` definuje kanonicky blok B1 vyššie. */
/* Ikona výstrahy (`ic['alert']`) sa nesmie zmenšiť, keď je hláška dlhá. */
.errbox .errbox-ic{flex:none;display:inline-flex}
.errbox .errbox-ic svg{width:20px;height:20px}

/* ── Farba prvku HMI a atribúty nového prvku (karty zmeny obrazovky) ──────
   Karta návrhu v chate (copilot.html) aj karta „Zmeny z Copilota" pri makete
   (_tia_hmi_change.html) — obe kreslí `window.HmiFarba` (hmi_color.js), preto
   jeden štýl tu, nie dve kópie. Vzorka je obrázok farby (`aria-hidden`),
   prístupný text je hex hneď za ňou. Rám tokenom `--ink-3` (stredná sivá
   v oboch témach): biela vzorka na bielom aj čierna na tmavom je vidieť.
   Pod farbou šachovnica — farba s alfou (#RRGGBBAA) a priehľadná ju ukážu. */
.hmi-farba{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.hmi-sw{--hmi-sw:transparent;flex:none;width:12px;height:12px;border-radius:3px;
  border:1px solid var(--ink-3);
  background:linear-gradient(var(--hmi-sw),var(--hmi-sw)),
    repeating-conic-gradient(#c9ced8 0 25%,#fff 0 50%) 0 0/6px 6px}
/* Nový prvok: atribút po atribúte ako zalomené čipy, nie jeden orezaný riadok. */
.hmi-attrs{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:4px 6px}
.hmi-attrs > li{display:inline-flex;align-items:center;gap:6px;padding:1px 8px;
  border-radius:999px;background:var(--fill-2);color:var(--ink);overflow-wrap:anywhere}
.hmi-attr-k{color:var(--ink-3);font-weight:600}

/* ── Náhľad obrázka pod myšou (`<img data-zoom>`, core.js @img-zoom) ──────
   Plávajúci rámik mimo toku stránky: `position:fixed` nič neposunie,
   `pointer-events:none` nezachytí klik ani ďalší hover. Podklad je biely
   v OBOCH témach ako pri miniatúrach dielov (fotky s odstráneným pozadím,
   kresba z rozkresu) — poistka je v dark.css. Rozmer obrázka a polohu
   dosadzuje core.js; padding 6 + okraj 1 sú tam ako `RAM` (14 px). Nad
   zásuvkou (80) aj modálom (100), pod pásom chýb (400). */
.v2-zoom{position:fixed;left:0;top:0;z-index:300;display:none;padding:6px;pointer-events:none;
  background:#fff;border:1px solid var(--line);border-radius:var(--r-sm);box-shadow:var(--shadow-lift)}
.v2-zoom.on{display:block;animation:v2zoomin .12s ease-out}
.v2-zoom img{display:block;object-fit:contain;border-radius:var(--btn-r-sm)}
@keyframes v2zoomin{from{opacity:0}to{opacity:1}}
@media(prefers-reduced-motion:reduce){.v2-zoom.on{animation:none}}

/* `desk-only` — ovládač, ktorý má zmysel len pri počítači (CSV pre tlačiareň
   štítkov P-touch, Roman 2026-10-27: „na mobile je zbytočné"). Na telefóne
   sa skryje; `!important`, lebo tlačidlá majú display z vlastných pravidiel
   s vyššou špecifickosťou (`.qr-acts .ghost`, `.dd-btn`). */
@media(max-width:640px){.desk-only{display:none !important}}
