/*
 * Mobilní opravy rozvržení technikovy aplikace (audit J.14).
 *
 * Všechno je pod breakpointem — nad ním se nemění vůbec nic, takže desktop
 * i tablet zůstávají, jak byly.
 *
 * PODMÍNKA JE HUSTOTA, NE ŠÍŘKA (UI2, etapa 1).
 *
 * Do 3. 9. 2026 tu stálo `max-width: 767.98px` plus výjimka na telefon na
 * šířku. Tablet tím propadl: mobilní pravidla končila na 767,98 px a Metronic
 * začíná na 992, takže na 768–991 px NECÍLILO ANI JEDNO PRAVIDLO — ověřeno.
 * Na iPadu na výšku to znamenalo dvanáctisloupcovou tabulku s vodorovným
 * scrollem, materiál bez stackování a žádnou připnutou patku: tlačítko
 * „Pokračovat" až na konci třímetrové stránky. Změřeno 86 % ovládacích prvků
 * pod 44 px, tedy hůř než na mobilu i na desktopu.
 *
 * Rozhoduje proto `pointer: coarse` — čím se to ovládá — a šířka je jen
 * doplněk pro úzké okno na myši (vývoj, rozdělená obrazovka). Tablet už není
 * třetí layout, ale dotyková hustota.
 *
 * Tenhle soubor NENÍ za PWA flagem. Přetečení hlavičky se týká každého telefonu
 * bez ohledu na to, jestli je aplikace nainstalovaná.
 *
 * Soubor leží v public/assets/, což je zmrazený výstup zrušeného buildu —
 * edituje se přímo, nikdy se negeneruje. Viz CLAUDE.md.
 */

/* Podminka je zamerne dvojita.
 *
 * Sama sirka nestaci: telefon otoceny na sirku ma 844-932 px, tedy vic nez
 * breakpoint, a vsechna pravidla nize by se vyply — pripnuta patka, zmensena
 * hlavicka i odsazeni. Aplikace se pak na sirku chovala jako desktop.
 *
 * Druha vetev proto miri na "nizky displej v ruce": vyska do 500 px pokryje
 * kazdy telefon na sirku (iPhone SE 320, Pixel 7 412, iPhone 14 Pro Max 430),
 * zatimco tablet na sirku ma 810 px a zustane nedotceny. pointer: coarse
 * vylucuje uzke nebo nizke okno na desktopu, kde jsou tahle pravidla na skodu.
 */
@media (pointer: coarse),
       (max-width: 767.98px) {

    /* ------------------------------------------------------------------
     * Hlavička
     *
     * Změřeno na iPhone SE (320 px): logo 124 px + topbar 323 px = 477 px.
     * Topbar má flex-shrink-0, takže se odmítal zmenšit, obsah přetekl na
     * 484 px a prohlížeč kvůli tomu odzoomoval celou stránku — vodorovný
     * scroll se tak objevil na KAŽDÉ obrazovce aplikace, ne jen v hlavičce.
     *
     * min-width: 0 je nutné: flex položka se bez něj nezmenší pod velikost
     * svého obsahu, i když flex-shrink povolíme.
     * ------------------------------------------------------------------ */

    #kt_header .topbar {
        flex-shrink: 1 !important;
        min-width: 0;
    }

    /* Kontejner hlavicky ma 15 px odsazeni z kazde strany, tedy 30 z 320 px.
       Po opravach zbyvalo presne 22 px pretečeni a tohle je nejlevnejsi misto,
       kde se daji ziskat. */
    #kt_header .container-fluid {
        padding-left: .5rem;
        padding-right: .5rem;
    }

    #kt_header .topbar > * {
        min-width: 0;
    }

    /* Logo je široký logotyp; na 320 px si bralo 124 px, tedy 39 % šířky.
       30vw nestačilo — po prvním měření zbývalo v hlavičce pořád 99 px přetečení,
       protože topbar potřeboval 286 px a zbývalo pro něj jen 194. */
    #kt_header .header-logo img {
        max-width: 22vw;
        width: auto;
        height: auto;
    }

    /* ------------------------------------------------------------------
     * Chip s běžícími stopkami
     *
     * Ukazuje číslo zakázky a název fáze. Na šířku displeje se to nevejde,
     * takže se text zkracuje — ne aby tlačil hlavičku do šířky.
     * ------------------------------------------------------------------ */

    #kt_timer_worker {
        min-width: 0;
    }

    /* Přebíjí inline max-width: 160px v _timer_header.latte. */
    #kt_timer_worker #header-timer-info > span {
        max-width: 16vw !important;
        min-width: 0;
    }

    /* Odsazení mezi položkami topbaru je na 320 px luxus. */
    #kt_header .topbar > * {
        margin-left: .25rem !important;
        margin-right: .25rem !important;
    }

    #kt_header .topbar .ms-3,
    #kt_header .topbar .ms-4,
    #kt_header .topbar .ms-lg-3 {
        margin-left: .25rem !important;
    }

    #kt_timer_worker .header-timer-text {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* ------------------------------------------------------------------
     * Podpisové plátno
     *
     * Plátno má max-width 380 px a všichni jeho flex předci mají implicitní
     * min-width: auto, takže se pod šířku obsahu nezmenší. Změřeno na 320px
     * displeji: 380 → 386 → 398 → 443 px, čili plátno diktovalo šířku celé
     * stránce a dělalo +165 px vodorovného scrollu.
     *
     * Řeší se to na obou koncích: plátno smí být užší a předci se smí zmenšit.
     * ------------------------------------------------------------------ */

    #signature-pad {
        max-width: 100% !important;
    }

    /* Přímý obal plátna.

       width: 100% je tu podstatné. Plátno má HTML atribut width="380", což mu dává
       vnitřní velikost, a obal se bez definitivní šířky zmenšuje podle obsahu —
       drželi se tedy navzájem na 380 px a max-width: 100% nemělo čeho se chytit. */
    .signature-pad {
        width: 100%;
        min-width: 0;
        max-width: 100%;
    }

    /* Flex předci výš v řetězu. Cílit na ně přes :has() nestačilo — řetěz je
       hlubší, než kolik úrovní se dá rozumně vyjmenovat (380 → 386 → 398 → 443).

       min-width: 0 je bezpečné: nic nezmenšuje násilím, jen ruší implicitní
       min-width: auto, kvůli kterému se flex položka odmítá zmenšit pod velikost
       svého obsahu. Omezeno na stepper, tedy na krokovaný formulář zakázky. */
    .stepper,
    .stepper * {
        min-width: 0;
    }

    /* ------------------------------------------------------------------
     * Bootstrap sloupce
     *
     * .col a .col-* jsou flex polozky s implicitnim min-width: auto, takze se
     * nezmensi pod sirku obsahu. Zmereno na kroku podpisu (320px displej):
     * .col mel 443 px uvnitr .col-xl-7 sirokeho 254 px.
     *
     * Omezeno na obsahovou cast technikovy aplikace; hlavicku ani admin se to
     * netyka. min-width: 0 nic nezmensuje nasilim, jen rusi tu spodni mez.
     * ------------------------------------------------------------------ */

    #kt_content .col,
    #kt_content [class*="col-"] {
        min-width: 0;
        /* max-width je tu druha polovina opravy. Samotne min-width: 0 jen dovoli
           zmensit se — nezabrani tomu, aby si prvek drzel vlastni sirku. Zmereno:
           .col mela 443 px uvnitr rodice sirokeho 254 a jako jedina na strance
           snizovala scrollWidth, kdyz se skryla. */
        max-width: 100%;
    }

    /* ------------------------------------------------------------------
     * Odsazení obsahu
     *
     * Změřeno na 320px displeji od podpisového plátna nahoru: z 320 px se na
     * vnořeném odsazení ztratí 114 px, takže na plátno zbylo 176 px, tedy 55 %
     * displeje. Největší díl bere .card-body s 54 px vodorovně (py-8 → px-9).
     *
     * Odsazení navržené pro desktop je na telefonu luxus. Svislé zůstává —
     * krátí se jen vodorovné, kde je místa nedostatek.
     * ------------------------------------------------------------------ */

    #kt_content_container {
        padding-left: .5rem;
        padding-right: .5rem;
    }

    /* Metronic cili na .card-body specifictejsim selektorem, takze holy
       .card-body prohraval. Zmereno: pravidlo se neuplatnilo, padding zustal 54 px. */
    #kt_content .card-body,
    .card > .card-body {
        padding-left: .75rem;
        padding-right: .75rem;
    }

    #kt_content .card-header,
    #kt_content .card-footer,
    .card > .card-header,
    .card > .card-footer {
        padding-left: .75rem;
        padding-right: .75rem;
    }

    /* Obaly nad podpisovym platnem se smrstuji podle obsahu, takze i kdyz se
       misto uvolni, platno ho nedostane — merilo by se pri nulove sirce platna
       jen to, co je v nich jeste za text. width: 100% je donuti misto vyplnit. */
    #kt_content .stepper,
    #kt_content .stepper > *,
    #kt_content .stepper > * > *,
    #kt_content .fv-row {
        width: 100%;
    }

    /* ------------------------------------------------------------------
     * Editor TinyMCE
     *
     * Změřeno na kroku Protokol: ze 67 prvků pod 44 px jich 46 patří toolbaru
     * editoru (34×28, split tlačítka 30×28 a šipky 20×28). Nejsou to naše
     * ovládací prvky, ale technik je používá stejně.
     *
     * Zvětšeno na 40 px, ne na doporučených 44 — toolbar má přes třicet tlačítek
     * a na 320px displeji by při 44 px zabral podstatnou část obrazovky. 40 px je
     * kompromis mezi trefitelností a tím, aby zbylo místo na samotný protokol.
     * ------------------------------------------------------------------ */

    .tox .tox-tbtn {
        min-height: 40px !important;
        min-width: 40px !important;
    }

    .tox .tox-tbtn.tox-split-button__chevron {
        min-width: 28px !important;
    }

    .tox .tox-toolbar__group {
        padding: 0 2px !important;
    }

    /* ------------------------------------------------------------------
     * Prihlasovaci obrazovka (J.16)
     *
     * Zmereno na iPhone SE (320 px) pred opravou: logo 379 px (uriznute z obou
     * stran, +29 px vodorovneho scrollu), karta zacinala az na 242 px, formular
     * mel 151 px, tedy necelou polovinu displeje.
     *
     * Rozvrzeni resi sablona (karta pres celou stranku, logo dovnitr karty);
     * tady zbyva velikost loga, citelnost poli a instalacni karta.
     * ------------------------------------------------------------------ */

    /* Logo je siroky logotyp — na uzkem displeji ho drzi sirka, ne vyska. */
    .login-logo img {
        max-width: min(240px, 70vw);
        height: auto;
    }

    /* Karta vyplnuje stranku, takze nesmi mit vlastni stin ani zaobleni. */
    .login-card {
        min-height: 100vh;
        min-height: 100dvh;
        box-shadow: none;
    }

    /* Pole a odesilaci tlacitko: 44 px je minimum pro ovladani v rukavicich,
       vychozich 40 px na to nestaci. Vetsi pismo zaroven vypina automaticke
       priblizeni pri fokusu, ktere iOS spousti pod 16 px. */
    .login-card .form-control,
    .login-card .form-select,
    .login-card .btn {
        min-height: 46px;
        font-size: 16px;
    }

    /* Nadpis "Prihlaseni" mel spodni mezeru 11 (2.75rem) a spolu s podtitulkem
       tlacil formular pod ohyb. */
    .login-card .mb-11 {
        margin-bottom: 1.5rem !important;
    }

    /* Instalacni karta je position: fixed dole a prekryvala konec formulare —
       zmereno 20 px uriznutych z prihlasovaciho tlacitka i po odscrollovani.
       Vysku hlasi sama do --pwa-hint (lisi se platformou: navod pro iOS je o tri
       radky delsi nez android varianta), takze se rezervuje presne tolik, kolik
       zabira. Fallback plati, nez se skript spusti; kdyz karta neni, je nula. */
    .login-card {
        padding-bottom: var(--pwa-hint, 0px) !important;
    }

    /* ------------------------------------------------------------------
     * Patka aplikace
     *
     * Copyright, odkaz na CRM, web klienta a verze. Na uzkem displeji se to
     * zalamovalo pres tri radky pod kazdou obrazovkou a technik z toho pri praci
     * nema nic. Obsah se presunul na "O aplikaci ALUNOVA" v uzivatelskem menu,
     * kde je na nej misto — nikam se neztratil.
     *
     * Na strance "O aplikaci" se patka skryva taky — udaje z ni jsou tam
     * primo v obsahu, takze by se jen zdvojily.
     * ------------------------------------------------------------------ */

    #kt_footer {
        /* !important je nutne: patka ma tridu d-flex a bootstrapovske utility
           maji display: flex !important, coz prebije i ID selektor. Zmereno —
           bez toho zustal computed display "flex". */
        display: none !important;
    }


    /* ------------------------------------------------------------------
     * Akční patka detailu připnutá dole
     *
     * Tlačítka kroku (Pokračovat, Dokončit, Zpět) jsou napříč osmnácti
     * šablonami detailu shodně v .card-footer, takže staci jedno pravidlo.
     * Na telefonu se připnou ke spodní hraně a nescrollují — aplikace se tím
     * chová jako systémová, ne jako webová stránka.
     *
     * env(safe-area-inset-bottom) je nutné: ve standalone režimu na iPhonu je
     * pod tím domovský indikátor a tlačítko by pod ním končilo.
     *
     * Spodní odsazení obsahu musí být větší než patka, jinak by pod ní zůstal
     * schovaný konec formuláře.
     * ------------------------------------------------------------------ */

    #kt_content .card-footer {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 100;
        background: #fff;
        /* Jedno oddeleni, ne dve. Driv tu byl vlastni RAMECEK I STIN naraz.
           Nestaci vlastni ramecek zrusit — Metronic ma na .card-footer svuj
           (zmereno: prosvitl jako 1px #F4F4F4), takze se musi vypnout. */
        border-top: 0;
        box-shadow: 0 -2px 12px rgba(0, 0, 0, .07);
        /* V PIXELECH zamerne. Korenova velikost je pod 768 px 12 px, takze
           .625rem = 7,5 px a .75rem = 9 px — tlacitko pak sedi skoro na hrane
           displeje. Merene hodnoty, ne odhad. */
        padding: 12px 16px;
        padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    }

    /* Tmavý motiv aplikace. */
    [data-bs-theme="dark"] #kt_content .card-footer,
    .dark-mode #kt_content .card-footer {
        background: #1e1e2d;
        border-top-color: rgba(255, 255, 255, .1);
    }

    /* Aby patka nezakryla konec obsahu.

       Vyska patky se lisi krok od kroku (zmereno 60 az 140 px podle poctu
       tlacitek), takze pevna hodnota by byla bud malo, nebo plytvani. Promennou
       nastavuje skript v layoutu podle skutecne vysky; fallback plati, nez se
       stihne spustit, a kdyby skript selhal. */
    /* .container je tu kvuli @detail_custom_fields.latte — jediny krok, ktery
       nema .card-body (ma <div class="container py-4">). Patka se mu pripnula,
       ale odsazeni se nedoplnilo, takze konec formulare koncil POD ni.
       Zavedeno tim, ze pravidlo puvodne cililo jen na .card-body. */
    #kt_content .card > .card-body,
    #kt_content .card-body,
    #kt_content > .card > .container {
        /* !important je tu vedome: Metronic cili na .card-body specifictejsim
           selektorem a bez toho pravidlo neprojde — zmereno, odsazeni zustavalo
           24 px misto potrebnych ~156 a konec formulare koncil pod patkou. */
        padding-bottom: calc(var(--sapp-footer, 9rem) + 1rem) !important;
    }

    /* Tlačítka v patce. Bez tohohle se mačkala do úzkých sloupců a text v nich
       lámal na výšku — změřeno 181 px vysoké tlačítko a patka přes 200 px, tedy
       přes třetinu displeje. Zalamuje se tedy řádek tlačítek, ne text v nich. */
    #kt_content .card-footer {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        justify-content: flex-end;
    }

    /* Tlacitka nejsou primymi detmi patky — jsou zanorena ve dvou d-flex obalech
       (zmereno), takze flex pravidlo na .btn na ne nedosahlo. Zalamuji se proto
       i ty obaly a plnou sirku dostavaji jejich deti. */
    #kt_content .card-footer .d-flex {
        flex-wrap: wrap;
        gap: 8px;
        width: 100%;
    }

    #kt_content .card-footer > *,
    #kt_content .card-footer .d-flex > * {
        margin: 0 !important;
        flex: 1 1 100%;
        min-width: 0;
    }

    #kt_content .card-footer .btn {
        min-height: 44px;
        /* Plna sirka pod sebou. Tri tlacitka vedle sebe se na 320 px nevejdou —
           text v nich lamal uprostred slova ("Doko / ncit"), coz je horsi nez
           o radek vyssi patka. Odsazeni obsahu se dopocitava, takze vyssi patka
           nic nezakryje. */
        flex: 1 1 100%;
        min-width: 0;
        white-space: normal;
        word-break: normal;
        overflow-wrap: normal;
        hyphens: none;
    }
}

/* ----------------------------------------------------------------------
 * Telefon na sirku
 *
 * Pravidla vyse uz tady plati (viz dvojita podminka nahore). Meni se ale
 * pomer: sirky je najednou dost a vysky kriticky malo. Patka s tlacitky
 * pod sebou by na 400px vysokem displeji sebrala tretinu obrazovky.
 * ---------------------------------------------------------------------- */

@media (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {

    /* Tlacitka vedle sebe — duvod pro skladani pod sebe byl, ze se na 320 px
       lamal text uprostred slova. Na sirku ten problem neni. */
    #kt_content .card-footer .btn {
        flex: 0 1 auto;
        min-width: 8rem;
    }

    #kt_content .card-footer .d-flex > * {
        flex: 0 1 auto;
    }

    /* Hlavicka na vysku, ktere je nedostatek. */
    #kt_header {
        min-height: 44px;
    }

    #kt_header .header-logo img {
        max-height: 28px;
    }

    /* Login se na vysku nevejde, takze musi jit odscrollovat — 100dvh by ho
       zamknul na vysku displeje a spodek formulare by zustal nedosazitelny. */
    .login-card {
        min-height: 0;
    }
}

/* ----------------------------------------------------------------------
 * Seznam zakázek jako karty
 *
 * Tabulka má sedm viditelných sloupců a na desktopu měří 1292 px — zúžit
 * se nedá. `cardView` z bootstrap-table by ale nepomohl: vykreslí každý
 * sloupec jako řádek „popisek: hodnota" a změřeno z toho vyšla karta
 * 313 px o osmi řádcích, tedy necelé tři zakázky na displej.
 *
 * Místo toho má tabulka sloupec navíc (`data-field="_mobil"`), který celý
 * řádek vykreslí jako tři řádky. Přepíná se TÍMHLE CSS, ne JavaScriptem:
 * tabulky mají data-cookie="true" a viditelnost sloupců si cookie pamatuje,
 * takže sahat na sloupce z JS by prosakovalo na desktop.
 *
 * ⚠️ Pravidla jsou OPT-IN přes třídu `sapp-cards` na `<table>`. Původně cílila
 * na `table.table` obecně a vyprázdnila tím KAŽDOU tabulku v technikově cestě —
 * dvanáct šablon včetně materiálu a souhrnu mělo 0 viditelných buněk ze 7
 * a řádky vysoké 1 px, protože buňku `.sapp-mobile` má jen ta jedna tabulka,
 * která pro ni má formatter. Tabulka bez toho sloupce se proto nesmí dotknout.
 * ---------------------------------------------------------------------- */

/* Nad breakpointem mobilní sloupec neexistuje. */
.sapp-mobile {
    display: none !important;
}

@media (pointer: coarse),
       (max-width: 767.98px) {

    /* Bez prefixu #kt_content ZÁMĚRNĚ: změřeno, že tabulky pod tím ID nejsou
       a pravidlo se neuplatnilo — tabulka zůstala 924 px, takže pravý sloupec
       karty (fáze, stav) ležel mimo obrazovku a vypadal jako nevykreslený.
       mobile.css načítá jen technikův layout, takže je to dost úzké samo o sobě. */

    /* Popisky nese karta sama, hlavička tabulky je zbytečná — a je to ona,
       kdo tabulce tu šířku diktoval (THEAD.sticky-header měl 924 px). */
    table.sapp-cards > thead,
    .fixed-table-header,
    .fixed-table-header-columns,
    .sticky-header-container {
        display: none !important;
    }

    /* Tabulka se nesmí roztáhnout podle skrytých sloupců. */
    .fixed-table-container,
    .fixed-table-body,
    table.sapp-cards {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
        table-layout: fixed;
    }

    .fixed-table-body {
        overflow-x: hidden;
    }

    /* Jeden řádek = jedna karta. */
    table.sapp-cards > tbody > tr {
        display: block;
        width: 100%;
        border-bottom: 1px solid rgba(0, 0, 0, .08);
    }

    [data-bs-theme="dark"] table.sapp-cards > tbody > tr {
        border-bottom-color: rgba(255, 255, 255, .1);
    }

    /* Ostatní buňky zmizí, mobilní zabere celou šířku. */
    table.sapp-cards > tbody > tr > td {
        display: none;
    }

    table.sapp-cards > tbody > tr > td.sapp-mobile {
        display: block !important;
        width: 100%;
        max-width: 100%;
        padding: 0;
        border: 0;
    }

    /* Řádek „nenalezeny žádné výsledky" nemá mobilní buňku — musí zůstat.
       Třídu dává bootstrap-table na <tr>, ne na <td>; dokud selektor mířil na
       buňku, nesedl nikdy a hlášku spolklo obecné pravidlo `td { display: none }`
       o pár řádků výš. Technik pak při prázdném seznamu viděl jen prázdno. */
    table.sapp-cards > tbody > tr.no-records-found > td {
        display: block !important;
        width: 100%;
        text-align: center;
        padding: 1.5rem .5rem;
        font-size: 14px;
        color: var(--bs-gray-600, #7e8299);
    }

    .sapp-card {
        /* position kvůli stretched-link na názvu — ten pokrývá celou kartu. */
        position: relative;
        display: flex;
        gap: 10px;
        /* Vlevo i vpravo 6 px: s odsazením .card-body (3 px) to dělá 9 px od
           hrany karty, takže proužek stavu začíná na stejné svislici jako
           dlaždice, záložky i lišta filtrace. Dřív bylo vlevo 3 a vpravo 6
           a karta stála o 3 px jinde než všechno nad ní. */
        padding: 9px 6px;
        color: inherit;
    }

    .sapp-card:active {
        background: rgba(0, 0, 0, .03);
    }

    /* Barevný proužek stavu vlevo — stejná role jako kolečko v Raynet appce:
       stav se pozná periferně, bez čtení. Sytá barva, ne light-* varianta. */
    .sapp-card__state {
        flex: 0 0 3px;
        width: 3px;
        border-radius: 2px;
        align-self: stretch;
        opacity: .85;
    }

    /* min-width: 0 je nutné, aby se text uvnitř mohl zkrátit výpustkou —
       flex položka se jinak nezmenší pod šířku svého obsahu. */
    .sapp-card__body {
        flex: 1 1 auto;
        min-width: 0;
        display: flex;
        flex-direction: column;
        gap: .2rem;
        justify-content: center;
    }

    /* Název a odznak stavu na jednom řádku: odznak si vezme, co potřebuje,
       název zbytek. Bez toho odznak název odtlačil a ten se zkrátil zbytečně. */
    .sapp-card__head {
        display: flex;
        align-items: flex-start;
        justify-content: space-between;
        gap: .5rem;
    }

    .sapp-card__name {
        /* flex: 1 1 auto je nutné. display: -webkit-box se ve flexu chová jako
           shrink-to-fit, takže se název bez tohohle smrskl na 158 px z 360 a
           lámal se na druhý řádek dřív, než bylo potřeba. */
        flex: 1 1 auto;
        min-width: 0;
        font-weight: 600;
        /* Pixely, ne rem: Metronic ma na mobilu kořenovou velikost 12 px, takze
           .95rem bylo 11,4 px a text byl v terenu necitelny. rem tady lze. */
        font-size: 16px;
        line-height: 1.3;
        color: var(--bs-gray-900);
        text-decoration: none;
        /* Dlouhé názvy zakázek jsou pravidlo, ne výjimka — dva řádky a dost. */
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

    .sapp-card__name:hover {
        color: var(--bs-primary);
    }

    .sapp-card__badge {
        flex: 0 0 auto;
        font-size: 12px;
        font-weight: 600;
        padding: .25rem .5rem;
        white-space: nowrap;
    }

    /* Velikosti v PIXELECH, ne v rem.
       Metronic nastavuje kořenovou velikost na 12 px (na desktopu 13), takze
       zmerene .8rem nebylo 12,8 px, ale 9,6 px — odtud ta necitelnost. rem by
       tady tise skaloval podle cizi hodnoty, kterou nemame pod kontrolou.

       Stupnice seznamu na mobilu má pět stupňů a jiné se v něm nepoužívají:
         18  nadpis karty a čísla v dlaždicích
         16  název zakázky
         14  řádky karty, záložky, štítky filtrů, prázdný stav
         13  ztlumený řádek (klient, termín)
         12  stavový odznak a stránkování
       Před sjednocením jich tu bylo osm (18/17/17/15/14/14/12/12) a štítky
       filtrů padaly přes knihovní fs-8/fs-9 až na 8,25 px. */
    .sapp-card__row {
        display: flex;
        justify-content: space-between;
        gap: .5rem;
        font-size: 14px;
        line-height: 1.4;
        color: var(--bs-gray-700);
    }

    .sapp-card__row--muted {
        font-size: 13px;
        color: var(--bs-gray-600);
    }

    .sapp-card__left {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* Pravý sloupec se nezkracuje: fáze a termín jsou krátké a jsou to právě
       ty údaje, kvůli kterým technik do seznamu kouká. */
    .sapp-card__right {
        flex: 0 0 auto;
        text-align: right;
        max-width: 45%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .sapp-card__date {
        color: var(--bs-gray-500);
    }

    /* Akce ze sloupce, který je na mobilu skrytý. z-index je nutný: jinak by
       je překryl stretched-link názvu a nešly by zmáčknout.

       Pravý sloupec, ne vlastní řádek pod textem: ten bral 40 px výšky navíc
       a kvůli němu by zvětšené písmo kartu neúnosně natáhlo. Takhle se výška
       karty řídí textem a tlačítka se do ní vejdou vedle. */
    .sapp-card__actions {
        position: relative;
        z-index: 2;
        flex: 0 0 auto;
        align-self: center;
        display: flex;
        flex-direction: column;
        gap: .375rem;
    }

    /* Tlačítka v kartě jsou menší než v tabulce. Změřeno: bez tohohle se
       vykreslila 78 px vysoká a karta kvůli nim narostla na dvojnásobek.
       !important je vědomé — Metronic cílí na .btn.btn-icon stejnou
       specificitou a bez něj vyhrálo jeho pravidlo.
       40 px je pořád trefitelné prstem (J4.3). */
    .sapp-card__actions .btn,
    .sapp-card__actions .btn.btn-icon {
        margin: 0 !important;
        width: 40px !important;
        height: 40px !important;
        min-width: 40px !important;
        min-height: 40px !important;
        padding: 0 !important;
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
    }

    /* Ikony uvnitř jsou svg-icon-2x, tedy 2rem — v 40px tlačítku by přetekly. */
    .sapp-card__actions .btn .svg-icon,
    .sapp-card__actions .btn .svg-icon svg,
    .sapp-card__actions .btn i {
        width: 20px !important;
        height: 20px !important;
        font-size: 20px !important;
        line-height: 1 !important;
        margin: 0 !important;
    }

    /* Stránkování se na 320 px nevejde vedle sebe. */
    .fixed-table-pagination > .pull-left,
    .fixed-table-pagination > .pull-right,
    .fixed-table-pagination > .float-left,
    .fixed-table-pagination > .float-right {
        float: none !important;
        width: 100%;
        text-align: center;
    }
}

/* ----------------------------------------------------------------------
 * Hlavička seznamu zakázek (app/@index.latte)
 *
 * Změřeno na iPhone SE (320 × 568): k první zakázce bylo 1006 px, tedy
 * 1,77 obrazovky. Rozpad: dlaždice stavů 456 px, záložky 154 px,
 * filtrovací lišta 153 px.
 *
 * Dlaždice NEJSOU dekorace — statsCardsFilters() (@index.latte:799) na nich
 * visí jako zkratka "vyfiltruj tenhle stav a přepni záložku". Proto se neruší,
 * jen se z nich stane jednořádkový pás čipů. Vodorovný pás je zvolený
 * záměrně: počet dlaždic je daný daty (service_states má 20 řádků), takže
 * mřížka by rostla do výšky, kdežto pás má výšku konstantní.
 *
 * Celé CSS-only. Markup po AJAXu skládá refreshAllTables() ze stejných tříd,
 * takže pravidla platí i po obnovení dat.
 * ---------------------------------------------------------------------- */

@media (pointer: coarse),
       (max-width: 767.98px) {

    /* Pás má overflow-x: auto. Bez min-width: 0 na řetězci rodičů by se flexový
       obal roztáhl podle obsahu pásu a vrátil vodorovný scroll celé stránce —
       přesně ten problém, který řeší komentář na začátku souboru. */
    #kt_dashboard .flex-grow-1,
    #kt_dashboard .d-flex.flex-wrap.justify-content-start {
        min-width: 0;
        width: 100%;
    }

    /* --- Svislé odsazení karty, navržené pro desktop --- */

    #kt_dashboard {
        margin-bottom: .75rem !important;
    }

    #kt_dashboard > .card-body {
        padding-top: 1rem !important;
    }

    #kt_dashboard > .card-body > .d-flex.mb-6 {
        margin-bottom: .5rem !important;
    }

    #kt_dashboard .fs-2.fw-bolder {
        font-size: 18px !important;
    }

    /* "Nástěnka pro správu servisních činností" — dekorace za 42 px i s mb-4. */
    #kt_dashboard .d-flex.flex-column > .fs-5.text-gray-400 {
        display: none !important;
    }

    /* --- Akční tlačítka --- */

    /* „Logování času" se přesunulo do uživatelského menu (@layout.latte).
       Nad seznamem zakázek bralo 56 px a rušilo — technik loguje čas z detailu
       zakázky, ne odsud. Ostatní tlačítka v té liště zůstávají. */
    #kt_dashboard a[href*="action=timeLogger"] {
        display: none !important;
    }


    #kt_dashboard .justify-content-between > .d-flex.mb-4 {
        margin-bottom: .5rem !important;
        gap: .5rem;
        width: 100%;
    }

    #kt_dashboard .justify-content-between > .d-flex.mb-4 > .btn {
        flex: 1 1 0;
        min-width: 0;
        min-height: 44px;
        margin-right: 0 !important;
        padding: .5rem !important;
        font-size: 15px !important;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* --- Dlaždice stavů → pás čipů --- */

    /* Dlaždice "Ke dni": jediný <div> v kontejneru, ostatní děti jsou <a>.
       Je statická, neklikací a vypisuje dnešní datum, které má technik ve
       stavovém řádku telefonu. AJAX vkládá jen <a>, selektor je tím stabilní. */
    #statsCards > div {
        display: none !important;
    }

    #statsCards {
        flex-wrap: nowrap !important;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scroll-snap-type: x proximity;
        scrollbar-width: none;
        gap: .375rem;
        width: 100%;
        min-width: 0;
        padding-bottom: .25rem;
        margin-bottom: .25rem;
    }

    #statsCards::-webkit-scrollbar {
        display: none;
    }

    #statsCards > a {
        display: flex !important;
        flex: 0 0 auto;
        flex-direction: column;
        justify-content: center;
        scroll-snap-align: start;
        min-height: 48px;
        margin: 0 !important;
        padding: .25rem .5rem !important;
        border-radius: 1.5rem !important;
    }

    /* V pixelech ze stejneho duvodu jako pismo: rem je tu 12 px, takze 7rem
       bylo 84 px a "Nenaplanovano" se pri 12px pismu lamalo na dva radky. */
    #statsCards > a.summary-services-counter {
        min-width: 72px !important;
        max-width: 118px;
    }

    /* Ikona je redundantní — barvu nese bg-* samotného čipu — a brala by 28 px
       ze ~100px čipu. Cíleno přes :not(), aby to nezáviselo na konkrétním
       markupu ikony ze sloupce service_states.icon. */
    #statsCards > a.summary-services-counter > .d-flex > *:not([data-kt-countup]) {
        display: none !important;
    }

    #statsCards > a.summary-services-counter [data-kt-countup] {
        font-size: 18px !important;
        line-height: 1.1 !important;
    }

    /* Popisek na dva řádky, ať "Čeká na synchronizaci" zůstane celé. */
    #statsCards > a.summary-services-counter > .text-gray-400 {
        font-size: 12px !important;
        line-height: 1.15 !important;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

    /* Obnovení dat je po výpadku signálu první věc, kterou technik hledá —
       proto pevně na začátek pásu. order, ne position: sticky: sticky uvnitř
       vodorovného scrolleru je na starším WebKitu nespolehlivé. */
    #statsCards > a.summary-services-refresh {
        order: -1;
        width: 44px;
        min-width: 44px !important;
        padding: 0 !important;
        align-items: center;
    }

    #statsCards > a.summary-services-refresh .text-light {
        display: none !important;
    }

    #statsCards > a.summary-services-refresh svg {
        width: 18px;
        height: 18px;
    }

    /* --- Záložky ze tří řádků na jeden, jako přepínač --- */

    /* Podtržítko (nav-line-tabs-2x) drží aktivní záložku dvěma pixely na
       spodní hraně — na mobilu je to při třech položkách vedle sebe málo
       čitelné. Návrh (navrh/Main.dc.html) má segmentovaný přepínač: šedý
       podklad, aktivní dlaždice bílá. */
    #kt_dashboard .nav-line-tabs {
        flex-wrap: nowrap !important;
        align-items: center;
        gap: 1px;
        background-color: #F0F0F0;
        border-radius: 5px;
        border-bottom: 0 !important;
        /* Svislý padding musí být !important — .nav ho nuluje. */
        padding: 2px !important;
        /* Vodorovně nic: přepínač má držet stejný okraj jako dlaždice stavů
           nad ním, a ten dává už vnitřní odsazení karty. */
        margin: 0 0 8px !important;
    }

    #kt_dashboard .nav-line-tabs > .nav-item {
        flex: 1 1 0;
        min-width: 0;
    }

    #kt_dashboard .nav-line-tabs > .nav-item > .nav-link {
        display: flex !important;
        /* .nav-item je u nav-stretch sám flexový, takže odkaz uvnitř se scvrkne
           na text (změřeno 66 px ve 114px položce) a bílá dlaždice by nesedla
           na třetinu. */
        flex: 1 1 auto;
        align-items: center;
        justify-content: center;
        /* 44px je dotykový cíl z ADR-J; návrh počítá s myší. */
        min-height: 44px;
        padding: .5rem .25rem !important;
        margin: 0 !important;
        border: 0 !important;
        border-radius: 4px;
        font-size: 14px !important;
        font-weight: 500;
        line-height: 1.3;
        text-align: center;
        color: var(--sapp-ink-secondary, #6B6B8D);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* text-active-gray-800 je na odkazu natvrdo v šabloně, proto !important. */
    #kt_dashboard .nav-line-tabs > .nav-item > .nav-link.active {
        background-color: #fff;
        color: var(--sapp-indigo, #1E1B4B) !important;
        font-weight: 600;
    }

    /* Oddělovač nad přepínačem byl hranice mezi dlaždicemi a záložkami;
       přepínač si ji nese sám svým podkladem. */
    #kt_dashboard > .card-body > .separator,
    #kt_dashboard .separator + .nav-line-tabs {
        margin-top: 0 !important;
    }

    /* --- Filtrovací lišta (platí pro všechny tři panely) --- */

    /* Lišta stojí mimo karty, na podkladu stránky, takže si vnitřní okraj
       musí dát sama: 9 px od hrany karty = 15 px od hrany obrazovky, stejně
       jako dlaždice stavů a přepínač záložek.

       Hodnoty jsou v px, ne v rem: kořenové písmo je v téhle aplikaci 12 px,
       takže .5rem není 8 px, ale 6 px — a mezery se pak rozcházejí s okraji. */
    .tab-pane > .d-flex.flex-stack {
        padding: 0 9px 8px !important;
        gap: 8px;
        /* .flex-stack je space-between — na desktopu drží nadpis vlevo
           a ovládání vpravo. Na mobilu nadpis mizí, takže by zbylá dvě
           tlačítka odletěla na opačné konce řádku (změřeno 270 px mezi nimi). */
        justify-content: flex-start !important;
    }

    /* Nadpis panelu duplikuje text aktivní záložky o 46 px výš. Celkový počet
       zůstává v pageInfo pod tabulkou (data-pagination-parts). */
    .tab-pane > .d-flex.flex-stack h3 {
        display: none !important;
    }

    .tab-pane > .d-flex.flex-stack .ms-9 {
        margin-left: 0 !important;
    }

    /* Řádek 1: hledání přes celou šířku. */
    .tab-pane > .d-flex.flex-stack > .d-flex:first-child {
        width: 100%;
        margin-bottom: 0 !important;
    }

    .tab-pane > .d-flex.flex-stack > .d-flex:first-child > .position-relative {
        flex: 1 1 auto;
        width: 100%;
    }

    .tab-pane > .d-flex.flex-stack input[id^="tableSearch"] {
        width: 100% !important;
        min-height: 44px;
    }

    /* Řádek 2: reset, rozsah a filtry. Vnitřní .d-flex.my-0 nemá flex-wrap
       a [data-reset-button] má min-width: 125px !important, takže se to dnes
       na 320 px nevejde. */
    .tab-pane > .d-flex.flex-stack > .d-flex:last-child {
        width: 100%;
    }

    .tab-pane .d-flex.flex-stack .d-flex.my-0 {
        width: 100%;
        min-width: 0;
        gap: 8px;
    }

    .tab-pane .d-flex.flex-stack .d-flex.my-0 > * {
        margin: 0 !important;
    }

    .tab-pane [data-reset-button] {
        min-width: 0 !important;
        font-size: 14px !important;
        white-space: nowrap;
    }

    /* Select2 si kopíruje šířku do inline stylu; !important ho přebije. */
    .tab-pane .d-flex.flex-stack .d-flex.my-0 > .select2-container,
    .tab-pane .d-flex.flex-stack .d-flex.my-0 > select {
        flex: 1 1 auto;
        width: auto !important;
        min-width: 0;
    }

    /* --- Obal tabulky --- */

    .tab-pane > .card.mb-5 {
        margin-bottom: .5rem !important;
    }

    .tab-pane > .card > .card-body.py-3 {
        padding: .25rem .25rem 0 .25rem !important;
    }

    /* Výběr sloupců nemá v kartách funkci — sloupce jsou schované všechny
       a zobrazuje se jediný, který kartu vykresluje. Schovává se tedy ON,
       ne celá lišta: od přesunu ovládání doprava v ní sedí i tlačítko
       Filtry, které na mobilu zmizelo s ní (změřeno 0 × 0 px na 390 px). */
    .fixed-table-toolbar {
        display: none !important;
    }

    [class^="sapp-toolbar-"] .columns,
    [class*=" sapp-toolbar-"] .columns {
        display: none !important;
    }

    /* Hledání a Filtry stojí vedle sebe u levého okraje, ne na opačných
       koncích řádku — mezi dvěma osamělými čtverci bylo 270 px prázdna.

       `width: auto` musí být !important: cíl pro výběr sloupců je v DOM první
       dítě lišty, takže na něj sedne pravidlo „řádek 1 přes celou šířku"
       o pár řádků výš a odsunulo by ho pod hledání. Stejně tak ms-auto
       z šablony, které patří desktopu. */
    .tab-pane > .d-flex.flex-stack > [class^="sapp-toolbar-"],
    .tab-pane > .d-flex.flex-stack > [class*=" sapp-toolbar-"] {
        width: auto !important;
        flex: 0 0 auto;
        margin-left: 0 !important;
    }

    /* basis 0, ne auto: s auto si blok drží šířku pole (w-200px) a na 320 px
       tlačítko Filtry propadlo pod něj (změřeno). Takhle si vezme jen to,
       co po tlačítku zbude. */
    .tab-pane > .d-flex.flex-stack > .d-flex:last-child {
        flex: 1 1 0;
        min-width: 0;
        width: auto;
    }

    /* Obal nadpisu zůstává v DOM i s ukrytým h3 a bral by si mezeru mezi
       položkami řádku (změřeno 8 px navíc před lupou). Trojice tříd cílí
       právě na něj: lišta ovládání nemá flex-wrap, blok s hledáním nemá
       align-items-center. */
    .tab-pane > .d-flex.flex-stack > .d-flex.flex-wrap.align-items-center {
        display: none !important;
    }

    /* Obě tlačítka jsou 44 × 44 se stejným rádiusem — lupa měla 6 px a Filtry
       knihovní rádius i šířku podle textu (změřeno 56 px). */
    [class^="sapp-toolbar-"] > .btn,
    [class*=" sapp-toolbar-"] > .btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 44px;
        min-height: 44px;
        padding: 0 10px !important;
        /* .btn-sm nese 0.475rem a je v pořadí za tímhle souborem. */
        border-radius: 10px !important;
    }

    /* Štítky zapnutých filtrů drží stejný okraj jako lišta nad nimi. */
    .tab-pane > .sapp-filter-chips {
        padding-left: 9px !important;
        padding-right: 9px !important;
    }

    /* ------------------------------------------------------------------
     * Panel filtrů
     *
     * w-250px ze šablony je desktopová míra: na telefonu z toho byl úzký
     * sloupek přes seznam a písma v něm 12–13,8 px (knihovní rem při kořeni
     * 12 px). Panel dostává celou šířku mezi okraji a vlastní velikosti v px.
     * ------------------------------------------------------------------ */

    #kt_content .menu-sub-dropdown[id^="menuFilters"] {
        width: calc(100vw - 30px) !important;
        max-width: 360px !important;
    }

    #kt_content [id^="menuFilters"] {
        font-size: 14px;
    }

    #kt_content [id^="menuFilters"] .fs-5 {
        font-size: 16px !important;
    }

    #kt_content [id^="menuFilters"] .form-label {
        font-size: 13px !important;
        margin-bottom: 6px;
    }

    #kt_content [id^="menuFilters"] .form-check-label {
        font-size: 14px;
    }

    /* Zaškrtávátko musí jít trefit prstem — knihovní 1,35rem je 16 px. */
    #kt_content [id^="menuFilters"] .form-check {
        min-height: 40px;
        display: flex;
        align-items: center;
    }

    #kt_content [id^="menuFilters"] .btn {
        min-height: 44px;
        font-size: 14px;
    }
}

/* ----------------------------------------------------------------------
 * Nejužší displeje (320 px)
 *
 * Samostatný stupeň, ne součást hlavního bloku: na 390 px se všechno vejde
 * a zmenšovat tam písmo by bylo zbytečné. Změřeno, že na 320 px se ořezává
 * jen záložka „Rozpracované" — 12 znaků v ~100px sloupci.
 * ---------------------------------------------------------------------- */

@media (max-width: 360px) {

    #kt_dashboard .nav-line-tabs > .nav-item > .nav-link {
        font-size: 13px !important;
        padding-left: .125rem !important;
        padding-right: .125rem !important;
    }
}

/* ----------------------------------------------------------------------
 * Prosté HTML tabulky jako karty (audit J.14, návrh B)
 *
 * Tady bootstrap-table není, takže formatter jako u seznamu zakázek použít
 * nejde. Standardní řešení je stackování: řádek se stane blokem a každá buňka
 * si nese popisek v `data-label`.
 *
 * Dvě varianty, protože tabulky jsou dvojího druhu:
 *
 *   .sapp-stack         formulářová (materiál) — popisek NAD polem, protože
 *                       input potřebuje celou šířku
 *   .sapp-stack-inline  jen ke čtení (souhrn) — popisek vlevo, hodnota vpravo,
 *                       což je u krátkých hodnot podstatně úspornější
 *
 * Opt-in přes třídu, stejně jako .sapp-cards — tabulka bez ní se nedotkne.
 * Viz regrese z 2026-09-03, kdy plošné pravidlo vyprázdnilo dvanáct šablon.
 * ---------------------------------------------------------------------- */

@media (pointer: coarse),
       (max-width: 767.98px) {

    table.sapp-stack > thead,
    table.sapp-stack-inline > thead {
        display: none;
    }

    table.sapp-stack,
    table.sapp-stack-inline {
        display: block;
        width: 100% !important;
        min-width: 0 !important;
    }

    table.sapp-stack > tbody,
    table.sapp-stack-inline > tbody {
        display: block;
        width: 100%;
    }

    /* Řádek = karta. Rámeček je to jediné, co odděluje jednu položku od druhé,
       když zmizí mřížka tabulky. */
    table.sapp-stack > tbody > tr,
    table.sapp-stack-inline > tbody > tr {
        display: block;
        width: 100%;
        margin-bottom: .625rem;
        padding: .5rem .625rem;
        border: 1px solid rgba(0, 0, 0, .1);
        border-radius: .475rem;
    }

    [data-bs-theme="dark"] table.sapp-stack > tbody > tr,
    [data-bs-theme="dark"] table.sapp-stack-inline > tbody > tr {
        border-color: rgba(255, 255, 255, .12);
    }

    /* Řádek je flex, aby krátká pole mohla vedle sebe. Bez toho měla položka
       materiálu 452 px, tedy celou obrazovku na jeden řádek tabulky. */
    table.sapp-stack > tbody > tr {
        display: flex;
        flex-wrap: wrap;
        gap: 0 .5rem;
    }

    table.sapp-stack > tbody > tr > td,
    table.sapp-stack-inline > tbody > tr > td {
        display: block;
        width: 100%;
        max-width: 100%;
        border: 0 !important;
        padding: .25rem 0;
    }

    /* Kód a Položka přes celou šířku — kód i název jsou dlouhé. */
    table.sapp-stack > tbody > tr > td[data-label="Kód"],
    table.sapp-stack > tbody > tr > td[data-label="Položka"] {
        flex: 1 1 100%;
    }

    /* Množství, cena a jednotka jsou krátké údaje — všechny tři na jeden řádek.
       Změřeno: samostatně měla položka 452 px, po dvojici 364 px, takhle 264. */
    table.sapp-stack > tbody > tr > td[data-label="Množství"],
    table.sapp-stack > tbody > tr > td[data-label="Cena za jednotku"],
    table.sapp-stack > tbody > tr > td[data-label="Cena za kus"],
    table.sapp-stack > tbody > tr > td[data-label="Jednotka"] {
        flex: 1 1 0;
        width: auto;
        min-width: 0;
    }

    /* Popisek „Cena za jednotku" se v úzkém sloupci láme na dva řádky a rozhodil
       by výšku sousedům — proto pevná výška popisku pro celou trojici. */
    table.sapp-stack > tbody > tr > td[data-label="Množství"]::before,
    table.sapp-stack > tbody > tr > td[data-label="Cena za jednotku"]::before,
    table.sapp-stack > tbody > tr > td[data-label="Cena za kus"]::before,
    table.sapp-stack > tbody > tr > td[data-label="Jednotka"]::before {
        min-height: 2.4em;
        line-height: 1.2;
    }

    /* Popisek z data-label. Buňka bez atributu ho nedostane — tak se řeší
       sloupec Akce, kde by popisek byl jen šum. */
    table.sapp-stack > tbody > tr > td[data-label]::before {
        content: attr(data-label);
        display: block;
        margin-bottom: .125rem;
        font-size: 12px;
        font-weight: 600;
        color: var(--bs-gray-600);
    }

    /* ------------------------------------------------------------------
     * Hledání v seznamu — přes celou šířku
     *
     * Dřív se pole sbalovalo do lupy: form-control-solid má #F9F9F9 a leží na
     * podkladu #F9F9F9, změřený kontrast 1,00, takže pole nebylo vidět a přesto
     * zabíralo 45 px výšky. Řeší to bílá plocha s rámečkem — stejná jako na
     * desktopu (actions.css) — takže důvod sbalovat zmizel a lišta filtrace
     * může držet celou šířku řádku, jak má.
     *
     * mobile-search.js zůstává: klepnutí na lupu teď jen zaostří pole.
     * ------------------------------------------------------------------ */

    .sapp-search {
        flex: 1 1 auto;
        min-width: 0;
        margin-bottom: 0 !important;
    }

    /* Vzhled pole (bílá, rámeček, rádius) drží actions.css pro všechny šířky.
       Tady je jen rozměr: přes celou šířku a místo pro lupu vlevo. */
    .sapp-search .form-control,
    .sapp-search .form-control-solid {
        width: 100% !important;
        min-width: 0;
        /* Vlevo místo pro lupu (ms-3 = 9 px + ikona 18 px). */
        padding: 0 12px 0 34px !important;
    }

    .sapp-search .svg-icon {
        color: var(--sapp-ink-secondary, #6B6B8D);
    }

    #kt_content .card-header,
    #kt_content .card-toolbar {
        row-gap: 8px;
    }

    /*
     * Pole obecně: 44px dotykový cíl a 16px písmo.
     *
     * Tohle pravidlo tu bylo, ale jen pro .login-card a pro tabulky materiálu —
     * zbytek formulářů zůstal na 13,2 px (rem při kořeni 12 px) a pod dotykovým
     * cílem: změřeno na @new_service 3 ze 4 polí. Když má etapa 3b pole
     * sjednocená na jednu podobu, patří sem i jednotný rozměr.
     *
     * 16 px není estetika: pod touto hodnotou iOS při fokusu sám přiblíží
     * stránku a technik se pak musí vracet gestem.
     */
    #kt_content .form-control,
    #kt_content .form-select,
    #kt_content textarea.form-control {
        min-height: 44px;
        font-size: 16px;
    }

    /* Vícerádkový text si výšku určuje sám, jen nesmí klesnout pod cíl. */
    #kt_content textarea.form-control {
        min-height: 88px;
    }

    /* Formulářová pole přes celou šířku, 44px dotykový cíl (J4.3), 16px písmo
       kvůli tomu, aby iOS při fokusu nepřibližoval stránku. */
    table.sapp-stack .form-control,
    table.sapp-stack .form-select,
    table.sapp-stack .input-group {
        width: 100% !important;
        min-width: 0 !important;
    }

    table.sapp-stack .form-control,
    table.sapp-stack .form-select {
        min-height: 44px;
        font-size: 16px;
    }

    /* Select2 si šířku kopíruje do inline stylu. */
    table.sapp-stack .select2-container {
        width: 100% !important;
    }

    /* Šířkové utility z desktopu (w-200px, min-w-325px) by kartu roztáhly. */
    table.sapp-stack > tbody > tr > td[class*="w-"],
    table.sapp-stack > tbody > tr > td[class*="min-w-"] {
        min-width: 0 !important;
    }

    /* Akce doprava, ať nekoukají doprostřed karty. */
    table.sapp-stack > tbody > tr > td:not([data-label]) {
        display: flex;
        justify-content: flex-end;
        gap: .375rem;
    }

    /* Prázdná buňka (v šablonách se vyskytuje) by dělala zbytečnou mezeru. */
    table.sapp-stack > tbody > tr > td:not([data-label]):empty {
        display: none;
    }

    /* --- Varianta jen ke čtení: popisek vlevo, hodnota vpravo --- */

    table.sapp-stack-inline > tbody > tr > td[data-label] {
        display: flex;
        justify-content: space-between;
        gap: .5rem;
        font-size: 15px;
    }

    table.sapp-stack-inline > tbody > tr > td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-weight: 600;
        color: var(--bs-gray-600);
        font-size: 15px;
    }

    table.sapp-stack-inline > tbody > tr > td[data-label] {
        text-align: right;
    }
}

/* ----------------------------------------------------------------------
 * Sbalená položka formulářové tabulky
 *
 * Vykresluje public/assets/js/mobile-stack.js. Rozbalená položka materiálu
 * měří 287 px, což je při osmi položkách přes dvě obrazovky jen na to, aby
 * si technik přečetl, co v zakázce je. Sbalená má 56 px.
 * ---------------------------------------------------------------------- */

@media (pointer: coarse),
       (max-width: 767.98px) {

    /* Souhrn je <td>, ne <div>: přímým dítětem <tr> smí být jen buňka,
       cokoli jiného prohlížeč při parsování vystrčí mimo tabulku. */
    td.sapp-summary {
        display: flex !important;
        align-items: center;
        gap: .5rem;
        width: 100%;
        flex: 1 1 100%;
        padding: .5rem 0 !important;
        border: 0 !important;
        cursor: pointer;
        min-height: 48px;
    }

    .sapp-summary__text {
        flex: 1 1 auto;
        min-width: 0;
        display: flex;
        flex-direction: column;
        gap: .1rem;
    }

    .sapp-summary__name {
        font-weight: 600;
        font-size: 15px;
        line-height: 1.3;
        color: var(--bs-gray-900);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .sapp-summary__desc {
        font-size: 13px;
        line-height: 1.3;
        color: var(--bs-gray-600);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* Šipka je jediné, co napovídá, že se položka dá rozbalit — malý šedý
       znak vpravo to nesdělil. Kroužek ji odliší od textu. */
    .sapp-summary__arrow {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 28px;
        height: 28px;
        border-radius: 50%;
        background: rgba(0, 0, 0, .04);
        color: var(--bs-gray-600);
        font-size: 14px;
        line-height: 1;
        transition: transform .15s ease;
    }

    [data-bs-theme="dark"] .sapp-summary__arrow {
        background: rgba(255, 255, 255, .06);
    }

    /* Sbalený stav je výchozí: pole jsou schovaná, vidět je jen souhrn. */
    table.sapp-stack > tbody > tr:not(.sapp-open) > td[data-label] {
        display: none !important;
    }

    /* Odsazení a oddělovač s !important: Metronic má na tabulce třídu gs-0,
       která prvnímu sloupci ruší vodorovné odsazení — změřeno, že první
       položka začínala o 8 px vlevo než ostatní. Rámeček řádku ruší taky. */
    table.sapp-stack > tbody > tr {
        padding: .5rem .75rem !important;
        border: 0 !important;
        border-radius: .475rem;
    }

    /* Oddělovač místo rámečku dokola: u seznamu pod sebou je čitelnější
       a nedělá z každé položky krabičku. */
    table.sapp-stack > tbody > tr:not(:last-child) {
        border-bottom: 1px solid rgba(0, 0, 0, .07) !important;
    }

    [data-bs-theme="dark"] table.sapp-stack > tbody > tr:not(:last-child) {
        border-bottom-color: rgba(255, 255, 255, .1) !important;
    }

    table.sapp-stack > tbody > tr:not(.sapp-open) {
        margin-bottom: 0;
    }

    /* Rozbalená položka dostane podklad, ať je zřetelné, která je otevřená,
       a odsadí se od sousedů. */
    table.sapp-stack > tbody > tr.sapp-open {
        background: rgba(0, 0, 0, .02);
        margin: .375rem 0;
        padding-bottom: .75rem !important;
    }

    [data-bs-theme="dark"] table.sapp-stack > tbody > tr.sapp-open {
        background: rgba(255, 255, 255, .03);
    }

    table.sapp-stack > tbody > tr.sapp-open .sapp-summary__arrow {
        transform: rotate(180deg);
    }

    /* V rozbalené položce souhrn zůstává jako hlavička — je to zároveň
       tlačítko na sbalení a technik neztratí, o kterou položku jde. */
    table.sapp-stack > tbody > tr.sapp-open > td.sapp-summary {
        border-bottom: 1px solid rgba(0, 0, 0, .1) !important;
        margin-bottom: .375rem;
        padding-bottom: .5rem !important;
    }
}

/* ----------------------------------------------------------------------
 * Hlavičky detailu zakázky (J.14, etapa 1)
 *
 * Změřeno na iPhone 13 (390 × 844), krok Materiál: k první buňce tabulky
 * bylo 395 px, tedy 47 % obrazovky. U podpisu začíná plátno až na 727 px.
 *
 * Rozpad těch 395 px — stojí za zapamatování, protože 48 px z toho nedrží
 * vůbec nic:
 *
 *     65  hlavička aplikace          (zůstává)
 *     33  pt-11 na #kt_content_container   PRÁZDNO
 *     15  padding na .content              PRÁZDNO
 *     83  modrý blok Událost + klient
 *     24  vzduch card-body py-8
 *     41  nadpis kroku + podtitulek
 *     20  datum vytvoření
 *     88  nadpis sekce + tlačítka Přidat
 *
 * Tahle etapa jen zhušťuje. Nadpis kroku ani modrý blok NEMIZÍ, jen se
 * zdrobní — technik neztratí, kde je, takže to nevyžaduje náhradní navigaci.
 * Celé je to CSS a celé pod media query, takže desktop se nemůže hnout.
 * ---------------------------------------------------------------------- */

@media (pointer: coarse),
       (max-width: 767.98px) {

    /* --- 1. Prázdné odsazení: 48 → 12 px --- */

    /* pt-11 je v celé technikově cestě jen na @layout_detail.latte:195,
       takže je to bezpečný háček. */
    #kt_content_container.pt-11 {
        padding-top: .5rem !important;
    }

    /* Vodorovné odsazení obsahu. 6 px od okraje displeje bylo příliš těsné —
       text karet začínal prakticky na hraně. 12 px je kompromis mezi vzduchem
       a šířkou, které je na 320 px nedostatek. */
    #kt_content.content {
        padding: 6px 0 !important;
    }

    #kt_content_container.pt-11 {
        padding-left: 12px !important;
        padding-right: 12px !important;
    }

    /* --- 2. Modrý blok Událost: 83 → ~52 px --- */

    /* Přesný selektor cílí jen na _detail_header.latte (je to první dítě
       karty v #kt_content), ne na karty uvnitř obsahu kroku. */
    /* Změřeno: samotné zmenšení odsazení nestačilo — blok měl pořád 91 px,
       přestože jeho odsazení bylo 4,8 px a obsah 34 px. Zbytek dělalo zalomení
       flexu (Metronic má na .card-header flex-wrap: wrap, takže se toolbar
       s tlačítkem Zpět zalomil pod nadpis) a marginy na h3.card-title. */
    #kt_content > .card > .card-header {
        display: flex !important;
        flex-wrap: nowrap !important;
        align-items: center !important;
        gap: .5rem;
        row-gap: 0 !important;
        min-height: 0 !important;
        padding-top: .4rem !important;
        padding-bottom: .4rem !important;
        /* dekorativní pattern-2.png — na 390 px se z něj stejně nic nepozná */
        background-image: none !important;
    }

    #kt_content > .card > .card-header .card-title {
        margin: 0 !important;
        padding: 0 !important;
    }

    #kt_content > .card > .card-header .card-toolbar {
        flex: 0 0 auto;
        margin: 0 !important;
        padding: 0 !important;
    }

    #kt_content > .card > .card-header .card-title.w-75 {
        width: auto !important;
        flex: 1 1 auto;
        min-width: 0;
    }

    #kt_content > .card > .card-header .card-label.fs-3 {
        font-size: 15px !important;
        line-height: 1.2;
        margin-bottom: 0 !important;
    }

    #kt_content > .card > .card-header .badge {
        font-size: 11px !important;
        padding: 2px 6px !important;
        margin: 0 0 0 .4rem !important;
    }

    #kt_content > .card > .card-header .card-title > span:last-child {
        font-size: 12px !important;
        line-height: 1.3;
        margin-top: 0 !important;
    }

    #kt_content > .card > .card-header .card-toolbar .nav-link {
        padding: .25rem .5rem !important;
        font-size: 12px !important;
    }

    /* --- 3. Vzduch karty: horní 24 → 8 px --- */

    /* Spodní se NESMÍ sáhnout — dopočítává se proti připnuté patce
       přes --sapp-footer (mobile-footer.js). */
    #kt_content .card-body.py-8 {
        padding-top: .5rem !important;
    }

    /* --- 4. Nadpis kroku: 41 → ~30 px --- */

    #kt_content .step-title {
        margin-bottom: 6px !important;
    }

    #kt_content .step-title h1 {
        font-size: 16px !important;
        line-height: 1.2;
        margin: 0 !important;
    }

    #kt_content .step-title span {
        font-size: 12px !important;
        line-height: 1.3;
        display: block;
    }

    /* --- 5. Datum vytvoření: zdrobnit, NE skrýt --- */

    /* Skrýt ho podle tříd .col-sm-4.d-sm-flex.justify-content-end nejde:
       z 32 výskytů té trojice jich část nese něco jiného (@detail_photos_main,
       @detail_material_pickup), takže by zmizely i ony. Než se dá bezpečně
       schovat, musí dostat vlastní třídu — to je etapa 2. */
    #kt_content .col-sm-4.d-sm-flex.justify-content-end {
        font-size: 12px !important;
        line-height: 1.3;
    }

    /* --- 6. Nadpis sekce a tlačítka Přidat: 88 → ~56 px --- */

    #kt_content h4.text-primary.fw-lighter {
        font-size: 14px !important;
        margin: 0 0 .25rem !important;
    }

    #kt_content .card-body .row > .col-md-6.mt-3.mb-3,
    #kt_content .card-body .row > .col-md-6.mb-3.d-flex {
        margin-top: 0 !important;
        margin-bottom: .25rem !important;
    }

    /* --- 7. Hygiena scrollování --- */

    /* Když prohlížeč sám odscrolluje na pole (fokus, validace), nesmí ho
       schovat pod připnutou patku ani pod hlavičku. */
    html {
        scroll-padding-top: 70px;
        scroll-padding-bottom: calc(var(--sapp-footer, 9rem) + 8px);
    }
}

/* ----------------------------------------------------------------------
 * Hlavičky detailu, etapa 2: kompaktní lišta
 *
 * Po etapě 1 bylo k první buňce 265 px. Zbytek drží modrý blok (61 px)
 * a nadpis kroku (35 px), které říkají skoro totéž — obojí nahradí jeden
 * řádek s kódem zakázky a názvem kroku.
 *
 * Lišta i původní blok jsou v _detail_header.latte, který se vkládá z layoutu
 * na jediném místě, takže tahle změna platí pro všech 18 kroků.
 *
 * Přepíná se TÍMHLE CSS, ne bootstrapovským d-md-none: to má breakpoint
 * 768 px a schovalo by lištu i telefonu otočenému na šířku (844 px), kde ji
 * naopak chceme.
 * ---------------------------------------------------------------------- */

@media (pointer: coarse),
       (max-width: 767.98px) {

    /* Původní blok na mobilu nahrazuje lišta. */
    #kt_content > .card > .card-header.sapp-block {
        display: none !important;
    }

    /* Přebíjí inline display:none ze šablony — to je tam kvůli tomu, aby při
       zastaralém CSS ze service workeru zůstalo dnešní chování. */
    #kt_content > .card > .card-header.sapp-bar {
        display: flex !important;
        align-items: center;
        gap: .625rem;
        min-height: 0 !important;
        /* Svisle víc vzduchu — s .5rem působila lišta nahňácaně. */
        padding: .625rem .75rem !important;
        background: var(--bs-gray-900, #1e1e2d);
        border: 0 !important;
        /* Rohy podle karty, ne natvrdo: karta má 7,5 px, .475rem dávalo 5,7
           a nesedělo to. Proměnná drží obojí v souladu, i kdyby Metronic
           hodnotu změnil. */
        border-radius: var(--bs-card-border-radius, .625rem) var(--bs-card-border-radius, .625rem) 0 0 !important;
    }

    .sapp-bar__back {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 34px;
        height: 34px;
        margin-left: -.25rem;
        border-radius: 50%;
        background: rgba(255, 255, 255, .12);
        color: #fff;
        font-size: 22px;
        line-height: 1;
        text-decoration: none;
    }

    .sapp-bar__back:hover,
    .sapp-bar__back:focus-visible {
        background: rgba(255, 255, 255, .22);
        color: #fff;
    }

    /* min-width: 0 je nutné, aby se text uvnitř mohl zkrátit výpustkou. */
    .sapp-bar__text {
        flex: 1 1 auto;
        min-width: 0;
        display: flex;
        flex-direction: column;
        gap: 1px;
    }

    .sapp-bar__main {
        display: flex;
        align-items: baseline;
        gap: .4rem;
        min-width: 0;
    }

    .sapp-bar__code {
        flex: 0 0 auto;
        font-weight: 700;
        font-size: 15px;
        line-height: 1.2;
        color: #fff;
    }

    /* Název kroku se smí zkrátit — kód zakázky ne, ten technik čte klientovi. */
    .sapp-bar__step {
        min-width: 0;
        font-size: 13px;
        line-height: 1.25;
        color: rgba(255, 255, 255, .72);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .sapp-bar__client {
        font-size: 12px;
        line-height: 1.25;
        color: rgba(255, 255, 255, .6);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .sapp-bar__state {
        flex: 0 0 auto;
        font-size: 11px !important;
        padding: 2px 6px !important;
    }

    /* Kroky vpravo v liště. Otevírá tutéž zásuvku jako tlačítko v hlavičce
       aplikace — spouštěč je proto na třídě, ne na ID (@layout_detail.latte). */
    .sapp-bar__steps {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        gap: .35rem;
        min-height: 36px;
        padding: 0 .5rem;
        border: 0;
        border-radius: 18px;
        background: rgba(255, 255, 255, .12);
        color: #fff;
        font-family: inherit;
        cursor: pointer;
    }

    .sapp-bar__steps:hover,
    .sapp-bar__steps:focus-visible {
        background: rgba(255, 255, 255, .22);
    }

    .sapp-bar__stepsNumber {
        font-size: 13px;
        font-weight: 600;
        line-height: 1;
        font-variant-numeric: tabular-nums;
    }

    .sapp-bar__stepsIcon {
        display: inline-flex;
        opacity: .8;
    }

    /* Původní spouštěč v hlavičce aplikace je na mobilu zbytečný — kroky se
       otevírají z lišty, která je u obsahu, kterého se týkají. */
    .sapp-steps-toggle--header {
        display: none !important;
    }

    /* Číslo kroku je teď na tlačítku vpravo, v textu by se opakovalo. */
    .sapp-bar__step .sapp-bar__stepCount {
        display: none;
    }

    /* Nadpis kroku je teď v liště — druhý výskyt o 40 px níž je duplicita. */
    #kt_content .step-title {
        display: none !important;
    }

    /* Datum vytvoření: services.created_at, tedy kdy řádek založila
       synchronizace — ne termín práce. Vlastní třída je tu proto, že hledat
       ho podle .col-sm-4.d-sm-flex.justify-content-end nešlo: ta trojice má
       32 výskytů a část z nich nese něco jiného. */
    #kt_content .sapp-date {
        display: none !important;
    }
}

/* ----------------------------------------------------------------------
 * Kroky v zásuvce (_progress.latte)
 *
 * Značení je dobré — Metronic stepper-pills s ikonou, názvem a podtitulkem.
 * Na mobilu je ale navržené pro postranní panel na desktopu: svislé marginy
 * my-10, odsazení ps-8 a stav „hotovo" se skoro nepozná.
 * ---------------------------------------------------------------------- */

@media (pointer: coarse),
       (max-width: 767.98px) {

    /* my-10 je 2.5rem nahoře i dole — v zásuvce zbytečné. */
    #kt_stepper_aside .d-flex.flex-row-auto {
        margin: .5rem auto !important;
        width: 100% !important;
    }

    #kt_stepper_aside.stepper {
        padding-left: 1rem !important;
        padding-right: 1rem !important;
    }

    #kt_stepper_aside .stepper-nav {
        width: 100%;
        align-items: stretch !important;
    }

    /* Celý krok je dotykový cíl, ne jen odkaz v popisku. */
    #kt_stepper_aside .stepper-item {
        margin: 0 !important;
        width: 100%;
    }

    #kt_stepper_aside .stepper-wrapper {
        gap: .75rem;
        padding: .5rem .5rem;
        border-radius: .475rem;
        min-height: 56px;
    }

    /* Aktuální krok podbarvený — dosud se poznal jen barvou ikony. */
    #kt_stepper_aside .stepper-item.current .stepper-wrapper {
        background: rgba(var(--bs-primary-rgb, 0, 158, 247), .08);
    }

    #kt_stepper_aside .stepper-icon {
        flex: 0 0 auto;
        width: 40px !important;
        height: 40px !important;
    }

    #kt_stepper_aside .stepper-label {
        min-width: 0;
        flex: 1 1 auto;
    }

    #kt_stepper_aside .stepper-label a {
        display: block;
        color: inherit;
        text-decoration: none;
    }

    #kt_stepper_aside .stepper-title {
        font-size: 15px !important;
        line-height: 1.25;
        margin: 0 !important;
    }

    #kt_stepper_aside .stepper-desc {
        font-size: 12px !important;
        line-height: 1.3;
        color: var(--bs-gray-600);
    }

    /* Spojnice mezi kroky: 40 px je na mobilu zbytečně dlouhá. */
    #kt_stepper_aside .stepper-line.h-40px {
        height: 14px !important;
        margin-left: 20px;
    }

    /* Hotový krok. Třída je v šabloně `baf`, ne `completed` — nepřejmenovávat,
       visí na ní i desktopové styly. */
    #kt_stepper_aside .stepper-item.baf .stepper-title {
        color: var(--bs-gray-700);
    }

    #kt_stepper_aside .stepper-item.baf .stepper-desc {
        color: var(--bs-gray-500);
    }

    /* Budoucí krok není klikací (šablona kolem něj nedá <a>) — ať to je vidět. */
    #kt_stepper_aside .stepper-item:not(.baf):not(.current) .stepper-wrapper {
        opacity: .55;
    }
}

/* ----------------------------------------------------------------------
 * Podpis: plátno první (J.14, etapa 3)
 *
 * Krok je na desktopu dvousloupec 5/7 — kontaktní údaje klienta vlevo,
 * podpisové plátno vpravo. Na mobilu se sloupce naskládají pod sebe v pořadí
 * z markupu, takže plátno skončí až za vším ostatním: změřeno 727 px, po
 * etapách 1 a 2 pořád 569 px, tedy dvě třetiny obrazovky.
 *
 * Bootstrapovský .row je flex, takže stačí prohodit pořadí. Žádná změna
 * šablony, žádný JavaScript — a desktop se nehne, protože je to pod
 * media query.
 * ---------------------------------------------------------------------- */

@media (pointer: coarse),
       (max-width: 767.98px) {

    /* Ukotveno na ten konkrétní řádek (@detail_sign.latte:392), ne na
       .col-xl-7 obecně — ta třída je v šabloně i jinde. */
    #kt_content .row.align-items-stretch > .col-xl-7 {
        order: -1;
    }

    #kt_content .row.align-items-stretch > .col-xl-5 {
        order: 0;
    }

    /* Vnitřní obaly plátna mají inline width: 443px, což je víc než displej.
       min-width: 0 ruší implicitní min-width: auto flex položky, jinak by se
       pod svůj obsah nezmenšily a vrátil by se vodorovný scroll. */
    #kt_content .row.align-items-stretch > .col-xl-7 [style*="width: 443px"],
    #kt_content .row.align-items-stretch > .col-xl-7 [style*="width:443px"] {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
    }

    /* Zarovnání doprava je pro desktopový sloupec; na plnou šířku působí divně. */
    #kt_content .row.align-items-stretch > .col-xl-7.align-items-end,
    #kt_content .row.align-items-stretch > .col-xl-7 .align-items-end {
        align-items: stretch !important;
    }

    /* Nadpis kontaktních údajů je až pod podpisem — ať je zřejmé, že tam
       něco pokračuje, a ne že stránka končí. */
    #kt_content h4.text-primary.fw-lighter {
        margin-top: .75rem !important;
    }
}
