/* =========================================================================
   ADMIS — responzivita a přetékající obsah

   Načítá se za material-dashboard.css pro všechny tenanty. Doplňuje šablonu
   Material Dashboard o chování, které potřebují husté datové přehledy
   AdmisHUBu. Neřeší vzhled, jen rozvržení a dostupnost obsahu.
   ========================================================================= */


/* -------------------------------------------------------------------------
   1. Stránka scrolluje dokumentem, ne vnitřním kontejnerem

   Šablona dává <main> `max-height: 100vh` a na Windows ho navíc předává
   perfect-scrollbaru, který na něj pověsí `.ps { overflow: hidden }`.
   Dokument pak má vždy přesně výšku okna a scrolluje se <main>. Důsledky:
   na mobilu se nikdy neschová adresní řádek prohlížeče, nefunguje obnovení
   pozice po návratu zpět a vodorovné přetečení posouvá celou stránku včetně
   fixní hlavičky místo jen té tabulky, která přetéká.

   Na jiných systémech než Windows se perfect-scrollbar vůbec nespouští
   (kontroluje `navigator.platform`), takže tohle pravidlo hlavně srovnává
   chování napříč operačními systémy.

   Vyšší specificita (`main.main-content`) přebíjí `.ps` i s `!important`.
   ------------------------------------------------------------------------- */
main.main-content {
    max-height: none !important;
    overflow: visible !important;

    /* Kontejnerový kontext pro `@container` dotazy níže. Sidebar si z okna
       bere 120 nebo 274 px, takže mediální dotazy podle okna měří něco jiného,
       než co je pro obsah k dispozici. Tohle měří přímo plochu obsahu.

       Pozor: `container-type` zapíná layout containment, čímž se z <main>
       stává containing block pro `position: fixed`. Řádkové nabídky s tím
       počítají — souřadnice si dopočítávají z naměřeného počátku
       (viz admis-tables.js). */
    container-type: inline-size;
    container-name: admis-obsah;
}

/* Lišty, které perfect-scrollbar stihne vyrobit dřív, než se uplatní
   pravidlo výše. Bez skrytí by zůstaly viset přes obsah. */
main.main-content > .ps__rail-x,
main.main-content > .ps__rail-y {
    display: none !important;
}


/* -------------------------------------------------------------------------
   2. Vodorovné přetečení musí být poznat

   `.table-responsive` umí obsah posouvat, ale nedává o tom nijak vědět —
   uživatel netuší, že vpravo pokračují další sloupce. Přidáváme dvě věci:

   a) stále viditelnou, ale nenápadnou posuvnou lištu,
   b) stínový náznak na okraji, který sám zmizí po dosunutí na konec.

   Náznak je čistě v CSS: bílé krycí vrstvy mají `background-attachment: local`
   (posouvají se s obsahem), stíny `scroll` (drží se u okraje rámu). Když je
   obsah dosunutý k okraji, krycí vrstva stín překryje. Žádný JavaScript, takže
   to přežije i překreslení Livewirem.
   ------------------------------------------------------------------------- */
.table-responsive {
    scrollbar-width: thin;
    scrollbar-color: #b9c0ce transparent;

    background-image:
        linear-gradient(to right, #fff 35%, rgba(255, 255, 255, 0)),
        linear-gradient(to left, #fff 35%, rgba(255, 255, 255, 0)),
        linear-gradient(to right, rgba(52, 71, 103, 0.22), rgba(52, 71, 103, 0)),
        linear-gradient(to left, rgba(52, 71, 103, 0.22), rgba(52, 71, 103, 0));
    background-position: 0 0, 100% 0, 0 0, 100% 0;
    background-repeat: no-repeat;
    background-size: 34px 100%, 34px 100%, 14px 100%, 14px 100%;
    background-attachment: local, local, scroll, scroll;
}

.table-responsive::-webkit-scrollbar {
    height: 10px;
}

.table-responsive::-webkit-scrollbar-track {
    background: transparent;
}

.table-responsive::-webkit-scrollbar-thumb {
    background-color: #c7cddb;
    border-radius: 10px;
    border: 3px solid transparent;
    background-clip: content-box;
}

.table-responsive:hover::-webkit-scrollbar-thumb {
    background-color: #a3abbe;
}


/* -------------------------------------------------------------------------
   3. Nabídky v řádcích tabulky

   Rozbalovací nabídka uvnitř posuvného rámu by se ořízla. Řádkové nabídky
   proto přepínáme na `position: fixed` a souřadnice jim počítá Alpine při
   otevření (viz komponenta x-table-scroll a šablony, které ji používají).
   Tahle třída jen zajistí, že se nabídka vykreslí nad zbytkem stránky.
   ------------------------------------------------------------------------- */
.admis-row-menu {
    position: fixed;
    z-index: 1060;
    /* Šířka musí být tady, ne v inline `style` — Alpine při vazbě `:style`
       přepisuje celý atribut a inline hodnotu by smazal. */
    min-width: 180px;
}


/* -------------------------------------------------------------------------
   4. Šířka obsahu na velkých obrazovkách

   Nad 1200 px se sidebar zafixuje a natrvalo si ukrojí 274 px. Rozšíření okna
   z 1199 na 1200 px tak pracovní plochu zmenší z 1199 na 926 px — širší okno
   ukáže méně dat než užší. Nejvíc to bolí na 1200–1400 px, tedy na běžných
   firemních noteboocích.

   Řešíme to tím, že pod 1400 px je výchozí zúžený rail (`g-sidenav-hidden`,
   120 px místo 274 px). Navigace zůstane vidět jako ikony a obsah dostane
   o 154 px víc. Třídu nasazuje skript v layoutu ještě před vykreslením a
   uživatelova volba se pamatuje v cookie — viz admis-sidenav.js.
   ------------------------------------------------------------------------- */

@media (min-width: 1200px) {
    /* Šablona při najetí myší na zúžený rail odsune obsah o dalších 154 px.
       Stránka se tím přelije pokaždé, když myš jen přejede přes sidebar.
       Rozbalený rail se má přes obsah překrýt, ne ho odstrkovat. */
    .g-sidenav-hidden .navbar-vertical:hover.fixed-start + .main-content {
        margin-left: 7.5rem;
    }

    /* Aby překryv byl čitelný jako překryv. */
    .g-sidenav-hidden .navbar-vertical:hover {
        box-shadow: 0 0 2rem 0 rgba(52, 71, 103, 0.28);
    }
}

/* Tam, kde je místa málo, nemá smysl dávat 24 px na každou stranu. */
@container admis-obsah (max-width: 1120px) {
    main.main-content .container-fluid.py-4 {
        padding-left: 1rem;
        padding-right: 1rem;
    }
}

/* Na ultrawide se obsah nemá roztahovat donekonečna — bez stropu naroste
   textová buňka na 2560 px klidně na 900 px, což je trojnásobek pohodlné
   délky řádku. */
@media (min-width: 2000px) {
    main.main-content .container-fluid {
        max-width: 1800px;
        margin-inline: auto;
    }
}


/* -------------------------------------------------------------------------
   5. Nároky datových tabulek

   Přehled úkolů si o osmi sloupcích říká o 1 395 px. Dvě textové buňky —
   název úkolu a název projektu — z toho tvoří přes polovinu, protože je nic
   neomezuje: jeden dlouhý název roztáhne celou tabulku.

   Stropy jsou dvoustupňové. Úzké obrazovky potřebují, aby se tabulka vešla;
   nad 1600 px je místa dost a zbytečně krátký ořez by jen otravoval. Plný
   text zůstává v `title`, takže se nic neztrácí.
   ------------------------------------------------------------------------- */

.admis-col-title {
    max-width: 17rem;
    min-width: 0;
}

.admis-col-project {
    max-width: 11rem;
}

@container admis-obsah (max-width: 1080px) {
    .admis-col-title {
        max-width: 14rem;
    }

    .admis-col-project {
        max-width: 9rem;
    }
}

@container admis-obsah (min-width: 1500px) {
    .admis-col-title {
        max-width: 26rem;
    }

    .admis-col-project {
        max-width: 18rem;
    }
}

/* Priorita sloupců.

   Ne každý sloupec musí být vidět vždycky. Tyhle dvě třídy říkají, jak moc je
   sloupec postradatelný, a zapínají ho podle toho, kolik místa má obsah — ne
   kolik ho má okno, protože sidebar si z okna bere 120 nebo 274 px.

   `low`  — technická data: ID, časová razítka, IP adresy, interní kódy.
   `mid`  — druhotné atributy, které se hodí, ale výpis se bez nich obejde.

   V šablonách se to zadává přes `<x-table.heading priority="low">` a stejnou
   hodnotou na odpovídající `<x-table.cell>`. Hlavička a buňka musí souhlasit,
   jinak se sloupce rozjedou. */
.admis-col-low,
.admis-col-mid,
.admis-col-high {
    display: none;
}

@container admis-obsah (min-width: 820px) {
    .admis-col-high {
        display: table-cell;
    }
}

@container admis-obsah (min-width: 1080px) {
    .admis-col-mid {
        display: table-cell;
    }
}

@container admis-obsah (min-width: 1400px) {
    .admis-col-low {
        display: table-cell;
    }
}

/* Na úzkém displeji je lepší nechat dlouhý e-mail nebo název zalomit než kvůli
   němu roztáhnout celou tabulku. Ve výchozím stavu se nezalomí, protože je to
   jedno dlouhé slovo bez mezery. */
@container admis-obsah (max-width: 820px) {
    .table-responsive .table > :not(caption) > * > * {
        overflow-wrap: anywhere;
    }
}

/* Kartový výpis na mobilu: dlouhý název nesmí odtlačit nabídku mimo kartu. */
.min-width-0 {
    min-width: 0;
}


/* -------------------------------------------------------------------------
   6. Čitelnost a ovladatelnost

   Aplikace je hustá na data a sází drobným písmem: `text-xxs` má 0,65 rem,
   tedy 10,4 px, a v šablonách se vyskytuje 400×. Na telefonu a pro oči, které
   už nejsou nejmladší, je to pod hranicí použitelnosti — a u stavební agendy
   je práce v terénu na mobilu běžný scénář.

   Měníme to na jednom místě, ne ve čtyřech stovkách šablon.
   ------------------------------------------------------------------------- */

.text-xxs {
    font-size: 0.7rem !important;
}

@media (max-width: 767.98px) {
    .text-xxs {
        font-size: 0.75rem !important;
    }

    .text-xs {
        font-size: 0.8rem !important;
    }
}

/* Na dotykových zařízeních musí mít ikonová tlačítka na co sáhnout. Řeší se
   jen aktivní plocha, vzhled zůstává — proto `pointer: coarse`, ať to na myši
   nerozhází rozestupy. */
@media (pointer: coarse) {
    .btn-link,
    .navbar-nav .nav-link,
    .dropdown-item,
    .table-responsive .btn {
        min-height: 40px;
    }

    /* Jen výška. Šířku si vynutit nejde: osm ikon v horní liště po 40 px dá
       přes 368 px a to se do telefonu s okraji nevejde — lišta by přetekla ven.
       Vodorovně jim prostor dává rozestup, ne minimální šířka. */
    .btn-link:not(.btn-sm) {
        min-width: 40px;
    }

    /* Vynucená výška musí obsah i vycentrovat. Bez toho zůstane ikona nahoře
       na prvním řádku čtyřicetipixelového bloku a vypadá to, jako by jedna
       ikona v řadě padala níž než ostatní. */
    .navbar-main .navbar-nav .nav-link {
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    .navbar-nav {
        flex-wrap: wrap;
    }

    .dropdown-item {
        display: flex;
        align-items: center;
    }
}

/* Alpine skrývá prvky do své inicializace přes `x-cloak`, jenže pravidlo
   k tomu si dosud definovala jen čtyři z devatenácti šablon, které atribut
   používají. Jinde nedělal nic a obsah na okamžik probliknul. */
[x-cloak] {
    display: none !important;
}


/* -------------------------------------------------------------------------
   7. Tabulka jako seznam karet

   Osmisloupcová tabulka se do 375 px nedostane skrýváním sloupců — zbyly by
   dva a to už není tabulka. Pod 720 px plochy se proto rozpadne na karty:
   každý řádek je jedna karta, každá buňka řádek "popisek — hodnota".

   Popisek bere z `data-label`, které doplňuje `<x-table.cell>` podle hlavičky
   (záhlaví je v tomhle režimu skryté, takže by jinak nebylo poznat, co je co).

   V kartě se ukážou i sloupce se sníženou prioritou: na výšku je místa dost,
   šetřilo se jen šířkou.
   ------------------------------------------------------------------------- */

@container admis-obsah (max-width: 720px) {
    .admis-table-cards,
    .admis-table-cards > tbody {
        display: block;
    }

    .admis-table-cards > thead {
        display: none;
    }

    .admis-table-cards > tbody > tr {
        display: block;
        margin: 0 0 0.75rem;
        padding: 0.25rem 0.875rem;
        border: 1px solid #e9ecef;
        border-radius: 0.5rem;
        background: #fff;
    }

    /* `flex-wrap` je tu nutný: z obsahu buňky se stanou flex položky, a když
       je jich víc (štítky oprávnění, tlačítka akcí), bez zalomení by se
       vyskládaly do řádku a vylezly z karty ven. */
    .admis-table-cards > tbody > tr > td {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        gap: 0.35rem 0.75rem;
        width: auto;
        min-width: 0;
        padding: 0.35rem 0;
        border: 0;
        box-shadow: none;
    }

    .admis-table-cards > tbody > tr > td > * {
        min-width: 0;
        max-width: 100%;
    }

    /* Šablona dává buňkám `white-space: nowrap` (.table td) — v tabulce to dává
       smysl, v kartě je to ale jediný důvod, proč delší popis vyleze ven. */
    .admis-table-cards > tbody > tr > td,
    .admis-table-cards > tbody > tr > td * {
        white-space: normal;
    }

    /* Priorita omezuje šířku, ne výšku — v kartě proto neplatí. */
    .admis-table-cards > tbody > tr > td.admis-col-low,
    .admis-table-cards > tbody > tr > td.admis-col-mid,
    .admis-table-cards > tbody > tr > td.admis-col-high {
        display: flex;
    }

    .admis-table-cards > tbody > tr > td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 7rem;
        color: #7b809a;
        font-size: 0.7rem;
        font-weight: 700;
        text-transform: uppercase;
        line-height: 1.5;
    }

    /* Prázdný stav přes celou šířku není řádek karty, ale hlášení. */
    .admis-table-cards > tbody > tr > td[colspan] {
        display: block;
        text-align: center;
    }

    .admis-table-cards > tbody > tr:has(> td[colspan]) {
        border: 0;
        background: transparent;
    }
}


/* -------------------------------------------------------------------------
   8. Vysunutý sidebar patří nad lištu

   Pod 1200 px je sidebar vysouvací zásuvka, jenže má `z-index: 999`, zatímco
   horní lišta `z-index: 1020` (třída `z-index-sticky`). Lišta se proto kreslí
   přes vysunutou zásuvku a prosvítá skrz ni.

   Nad 1200 px je sidebar napevno vedle obsahu, nepřekrývají se a pořadí je
   jedno — proto jen pod tou hranicí.

   `!important` je tu kvůli tenant-jmk.css, který `.sidenav` připíchl na 999
   s `!important`, aby zůstal pod modály. Ten záměr platí dál: 1035 je nad
   lištou (1020) a pořád pod Bootstrapím modálem (1055) i jeho zastíněním
   (1050).
   ------------------------------------------------------------------------- */

@media (max-width: 1199.98px) {
    .sidenav.fixed-start,
    .sidenav.fixed-end {
        z-index: 1035 !important;
    }
}


/* -------------------------------------------------------------------------
   9. Zastínění za vysunutou zásuvkou

   Sidebar se pod 1200 px vysune přes obsah, ale za ním nebylo nic ztmaveného
   a zavřít ho šlo jen malým křížkem. Zastínění jednak ukáže, že zbytek
   stránky teď není na řadě, jednak dá čím zavřít — klepnutím vedle.

   Leží mezi lištou (1020) a zásuvkou (1035).
   ------------------------------------------------------------------------- */

.admis-sidenav-scrim {
    position: fixed;
    inset: 0;
    z-index: 1030;
    background: rgba(0, 0, 0, 0.45);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, visibility 0.2s ease;
}

@media (max-width: 1199.98px) {
    .g-sidenav-pinned .admis-sidenav-scrim {
        opacity: 1;
        visibility: visible;
    }
}

@media (prefers-reduced-motion: reduce) {
    .admis-sidenav-scrim {
        transition: none;
    }
}


/* -------------------------------------------------------------------------
   10. Rozbalovací nabídky v horní liště na úzkých displejích

   Zvoneček a poznámky mají nabídku širokou 360 px a `dropdown-menu-end`, tedy
   zarovnanou pravou hranou k ikoně. Dokud ikony stály u pravého kraje, vešlo
   se to. Jenže na úzkých displejích se ikony rozprostírají po celé šířce, takže
   spouštěč sedí uprostřed — a nabídka pak vylézala 25 px za levý okraj
   obrazovky. Popperu se to přenastavit nedá, jeho hranicí je lišta.

   Řešíme to ukotvením k liště místo k ikoně: `li` přestane být pozicovacím
   kontextem, takže se nabídka pozicuje vůči liště a zarovná se k jejímu
   pravému okraji. Šířka zůstává 360 px, pokud je na ni místo.
   ------------------------------------------------------------------------- */

@media (max-width: 991.98px) {
    .navbar-main .navbar-nav > li.dropdown {
        position: static;
    }

    .navbar-main .navbar-nav > li.dropdown .dropdown-menu {
        position: absolute !important;
        inset: 100% 0 auto auto !important;
        transform: none !important;
        /* Strop, ne pevná šířka: zvoneček a poznámky si o 360 px říkají samy,
           ale nabídka účtu má zůstat úzká podle svého obsahu. */
        max-width: min(360px, 100%) !important;
        /* přebíjí `me-sm-n4` ze šablony, které nabídku posouvalo o 24 px
           doprava, až dosedla na hranu obrazovky */
        margin-right: 0 !important;
        margin-top: 0.5rem !important;
    }
}
