/* =================================================================
 * portal/css/portal.css
 * Styly portálu (index.php) + sdílené login styly + sjednocený horní pruh
 * (.app-topbar) + Delta launcher.
 *
 * Téma: tmavé (default) / světlé (přepínač v topbaru = data-theme="light"
 * na <html>). Barvy se řídí CSS proměnnými v :root, světlá varianta je
 * override v [data-theme="light"]. Žádné hardcoded barvy v selektorech -
 * vše přes var(--*).
 *
 * Pozn.: DevExtreme používá vlastní stylesheet (dx.material.blue.dark.css).
 * Ten zůstává tmavý i ve světlém tématu (přepnutí na light variantu by
 * vyžadovalo úpravu importu v každém modulu - V2 vylepšení).
 * ================================================================= */

/* ----- CSS proměnné: tmavé téma (default) -------------------------- */
:root {
    /* Pozadí */
    --bg:                  #303030;   /* hlavní body bg */
    --bg-elevated:         #262626;   /* topbar, header */
    --bg-card:             #3a3a3a;   /* portal cards, login card */
    --bg-card-hover:       #444;
    --bg-popover:          #2b2b2b;   /* launcher popover */
    --bg-input:            #2a2a2a;   /* form inputs (login) */
    --bg-tag:              rgba(255,255,255,0.06);

    /* Text */
    --text:                #fff;      /* hlavní text */
    --text-strong:         #fff;      /* titulky */
    --text-muted:          #b8b8b8;   /* sekundární */
    --text-faint:          #999;
    --text-subtle:         #888;
    --text-light:          #ddd;

    /* Hranice */
    --border:              #444;
    --border-soft:         #3c3c3c;
    --border-input:        #555;
    --border-strong:       #4a4a4a;

    /* Akcent (modrá Hanák/portal) */
    --accent:              #6cb2f0;
    --accent-hover:        #99cfff;
    --accent-soft:         rgba(108, 182, 255, 0.08);
    --accent-soft-hover:   rgba(108, 182, 255, 0.14);
    --accent-focus-ring:   rgba(108, 178, 240, 0.25);

    /* Hover overlay */
    --hover-overlay:       rgba(255,255,255,0.06);
    --hover-overlay-strong:rgba(255,255,255,0.14);

    /* Stíny */
    --shadow-card:         0 4px 20px rgba(0, 0, 0, 0.3);
    --shadow-card-hover:   0 6px 18px rgba(0, 0, 0, 0.35);
    --shadow-popover:      0 8px 24px rgba(0, 0, 0, 0.5);
    --logo-shadow:         rgba(0, 0, 0, 0.4);

    /* Accent řádků v gridech (poznámka / status / pozor / demont / special).
       V tmavém tématu = tlumené tóny na tmavém podkladu. V light tématu se
       převádí na pastelové bg s tmavým textem (definováno v [data-theme="light"]).
       Tyhle vars se používají v zakazky/css/style.css (a kdekoli jinde,
       kde chceš stejné semantické zvýraznění). */
    --row-yellow-bg:        #5a4d1a;
    --row-yellow-text:      #fff8d8;
    --row-yellow-bg-hover:  #6a5a1f;

    --row-green-bg:         #1e4d2b;
    --row-green-text:       #d6f0d8;
    --row-green-bg-hover:   #265a36;

    --row-red-bg:           #5a2828;
    --row-red-text:         #ffd6d6;
    --row-red-bg-hover:     #6a3030;

    --row-orange-bg:        #5a3a1a;
    --row-orange-text:      #ffe0c0;
    --row-orange-bg-hover:  #6a4520;

    --row-blue-bg:          #1a3a5a;
    --row-blue-text:        #d6e4ff;
    --row-blue-bg-hover:    #224a6a;
}

/* ----- Světlé téma (override) ------------------------------------- */
/* Pozadí má jemný modrý nádech (ne čistá šedá) - ladí s brand modrou
   (--accent: #0d6efd) a bílé karty (--bg-card: #ffffff) hezky "vyplývají"
   z plochy. Pokud bys chtěl víc/míň modré, mění se tu --bg + --bg-card-hover.
   Card a topbar zůstávají čistě bílé záměrně - kontrast s modravou plochou
   dělá hierarchii zřejmou. */
[data-theme="light"] {
    --bg:                  #e9f0fa;
    --bg-elevated:         #ffffff;
    --bg-card:             #ffffff;
    --bg-card-hover:       #dde7f4;
    --bg-popover:          #ffffff;
    --bg-input:            #ffffff;
    --bg-tag:              rgba(13, 110, 253, 0.06);

    --text:                #1c1f24;
    --text-strong:         #000;
    --text-muted:          #4a5159;
    --text-faint:          #6c757d;
    --text-subtle:         #8a9097;
    --text-light:          #495057;

    --border:              #d8dce0;
    --border-soft:         #e6e8eb;
    --border-input:        #c4c9cf;
    --border-strong:       #c0c5ca;

    --accent:              #0d6efd;
    --accent-hover:        #0a58ca;
    --accent-soft:         rgba(13, 110, 253, 0.08);
    --accent-soft-hover:   rgba(13, 110, 253, 0.14);
    --accent-focus-ring:   rgba(13, 110, 253, 0.25);

    --hover-overlay:       rgba(0,0,0,0.04);
    --hover-overlay-strong:rgba(0,0,0,0.08);

    --shadow-card:         0 2px 12px rgba(0, 0, 0, 0.06);
    --shadow-card-hover:   0 4px 16px rgba(0, 0, 0, 0.10);
    --shadow-popover:      0 6px 20px rgba(0, 0, 0, 0.12);
    --logo-shadow:         rgba(0, 0, 0, 0.15);

    /* Accent řádků - light varianty (Bootstrap-like pastelové tóny).
       Pozadí mají dost saturace na to, aby se odlišily od bílého řádku,
       text je tmavý pro plnou čitelnost. */
    --row-yellow-bg:        #fff3cd;
    --row-yellow-text:      #664d03;
    --row-yellow-bg-hover:  #ffe89c;

    --row-green-bg:         #d1e7dd;
    --row-green-text:       #0f5132;
    --row-green-bg-hover:   #b8dac6;

    --row-red-bg:           #f8d7da;
    --row-red-text:         #842029;
    --row-red-bg-hover:     #f1b9bf;

    --row-orange-bg:        #ffe5d0;
    --row-orange-text:      #8b3d00;
    --row-orange-bg-hover:  #fdd5b3;

    --row-blue-bg:          #cfe2ff;
    --row-blue-text:        #084298;
    --row-blue-bg-hover:    #b6d4fe;
}

/* ----- Module body - sjednocené pozadí podle tématu --------------- */
/* Každý modul má svou class na <body> (nastavená v jeho index.php).
   Aplikujeme přes ni base bg+text, které pak modul-specifická CSS
   může přebít. V tmavém tématu zůstávají hardcoded barvy v modulech
   (zpětná kompatibilita), ve světlém je přebíjíme tady. */
[data-theme="light"] body.portal-body,
[data-theme="light"] body.zakazky-body,
[data-theme="light"] body.expedice-body,
[data-theme="light"] body.ctecka-body,
[data-theme="light"] body.agent-body,
[data-theme="light"] body.dilny-body,
[data-theme="light"] body.katalog-body,
[data-theme="light"] body.napoveda-body,
[data-theme="light"] body.nv-body,
[data-theme="light"] body.login-body,
[data-theme="light"] body.exp-body {
    background: var(--bg);
    color: var(--text);
}

/* ----- Sjednocený horní pruh modulů (partials/topbar.php) ---------
   Title vlevo (me-auto), modul-specifické extras, user, Portál, Odhlásit
   vpravo. Nízká, kompaktní, matchuje motiv tmavé DevExtreme.
   ------------------------------------------------------------------ */
.app-topbar {
    background: var(--bg-elevated);
    /* Modul-specifický spodní border - 3px v barvě modulu (z $APPS registru,
       propisováno přes inline --app-color v partials/topbar.php). Fallback
       na neutrální border pokud --app-color není nastavená (např. hlavní
       portál index.php nebo modul bez topbarApp). */
    border-bottom: 3px solid var(--app-color, var(--border));
    padding: 6px 0;
    margin-bottom: 6px;
    transition: background-color 0.15s, border-color 0.15s;
}
/* Opt-in sticky topbar (partials/topbar.php přidá tuto třídu když volající
   nastaví $topbarSticky=true). Používá se v dlouhých čtecích modulech
   (Nápověda, Novinky), kde má smysl mít jméno + menu pořád na očích.
   z-index drží topbar nad DX widgety a sticky sidebars (np-sidebar má top
   posunutý, ať pod topbar nezalézá). */
.app-topbar--sticky {
    position: sticky;
    top: 0;
    z-index: 1030;  /* Bootstrap fixed-top range, nad DX overlay (~1000). */
}
.app-topbar-title {
    font-size: 15px;
    font-weight: 500;
    letter-spacing: 0.3px;
    color: var(--text);
}
/* User blok v modul-topbaru. Bez ikonky, 2 řádky: jméno (nahoře) +
   role (dole). Column flex se zarovnáním vpravo (align-items:flex-end),
   ať se text v topbaru ráhuje k pravé hraně mezi sebou (= klidnější
   "lego" v řadě s tlačítky). */
.app-topbar-user {
    color: var(--text-light);
    display: inline-flex;
    flex-direction: column;
    align-items: flex-end;
    line-height: 1.2;
    margin-right: 6px;
    user-select: none;
}
.app-topbar-user-name {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-strong);
}
.app-topbar-user-role {
    font-size: 10.5px;
    color: var(--text-faint);
    letter-spacing: 0.3px;
    text-transform: uppercase;
    margin-top: 1px;
}
/* Legacy class - emoji ikonka už nerendrujeme, ale CSS ponecháno pro
   případ, že by ji starý kód někde jinde používal. */
.app-topbar-user-icon {
    font-size: 14px;
}
.app-topbar-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    font-size: 12px;
}
.app-topbar-btn-ico {
    font-size: 13px;
    line-height: 1;
}

/* Icon-only varianta - kulatý badge s SVG ikonou uprostřed.
   Ve světlém tématu přidáváme okraj - bootstrap btn-outline-light
   v light-mode není vidět (bílý rámeček na bílém pozadí). */
.app-topbar-btn-icon {
    width: 32px;
    height: 32px;
    padding: 0;
    border-radius: 50%;
    justify-content: center;
    display: inline-flex;
    align-items: center;
}
.app-topbar-btn-icon:hover {
    transform: scale(1.05);
    transition: transform 0.12s ease;
}
[data-theme="light"] .app-topbar-btn-icon {
    color: var(--text);
    border-color: var(--border-input);
}
[data-theme="light"] .app-topbar-btn-icon:hover {
    background: var(--hover-overlay);
    color: var(--text-strong);
    border-color: var(--text-muted);
}
.app-topbar-svg {
    width: 16px;
    height: 16px;
    display: block;
}

/* ====== Sjednocený link-strip mezi admin sekcemi ======
   Renderuje partials/admin_nav.php a vkládá ho admin_users.php,
   ctecka/admin_mista.php a dilny/admin_stroje.php do svého header
   bloku. Vizuálně stejný pattern napříč všemi 3 admin stránkami,
   ať admin neztrácí kontext při přepínání.
   Aktivní stav = modré pozadí (#2b5fa1), ať uživatel hned vidí
   na které admin obrazovce právě je. */
.admin-nav {
    display: flex;
    gap: 6px;
    margin-left: 12px;
    flex-wrap: wrap;
}
.admin-nav-link {
    font-size: 12.5px;
    padding: 4px 10px;
    border-radius: 4px;
    color: #cdd;
    text-decoration: none;
    background: #1c1c1c;
    border: 1px solid #444;
    line-height: 1.4;
    white-space: nowrap;
}
.admin-nav-link:hover {
    background: #333;
    color: #fff;
    text-decoration: none;
}
.admin-nav-link.is-active {
    background: #2b5fa1;
    color: #fff;
    border-color: #2b5fa1;
}
.admin-nav-link.is-active:hover {
    background: #316bb3;  /* slightly lighter shade than is-active */
}

/* Admin cross-nav - světlá varianta (data-theme=light). Doteď byla nav
   jen tmavá; admin stránky se světlým režimem (admin_users, admin_pracoviste)
   ji potřebují čitelnou i na světlém podkladu. */
[data-theme="light"] .admin-nav-link {
    color: var(--text-light);
    background: var(--bg-elevated);
    border-color: var(--border-input);
}
[data-theme="light"] .admin-nav-link:hover {
    background: #e9ecef;
    color: var(--text-strong);
}
[data-theme="light"] .admin-nav-link.is-active,
[data-theme="light"] .admin-nav-link.is-active:hover {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}

/* ====== Admin gear menu (ozubené kolo) ======
   Tlačítko v topbaru + dropdown menu vedle. Identický wrapper na obou
   variantách (portál module topbar + admin pages inline topbars). */
.app-topbar-admin-wrap {
    position: relative;
    display: inline-flex;
}
.app-topbar-admin-btn.is-active,
.app-topbar-admin-btn[aria-expanded="true"] {
    background: var(--hover-overlay, rgba(255,255,255,0.12));
    border-color: var(--text-muted, #888);
}
.app-topbar-admin-menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    min-width: 180px;
    background: #1d1d1d;
    border: 1px solid #444;
    border-radius: 6px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
    padding: 4px;
    opacity: 0;
    transform: translateY(-4px);
    pointer-events: none;
    visibility: hidden;
    transition: opacity 0.12s ease, transform 0.12s ease, visibility 0s linear 0.12s;
    z-index: 1100;
}
.app-topbar-admin-menu.open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
    visibility: visible;
    transition: opacity 0.12s ease, transform 0.12s ease, visibility 0s;
}
.app-topbar-admin-menu a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    color: #cdd;
    text-decoration: none;
    border-radius: 4px;
    font-size: 13px;
}
.app-topbar-admin-menu a:hover {
    background: #2b5fa1;
    color: #fff;
}
.app-topbar-admin-menu .adm-menu-ico {
    font-size: 14px;
    width: 18px;
    text-align: center;
    flex: 0 0 auto;
}
.app-topbar-extra {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* ----- Theme toggle ikony (sun / moon) ---------------------------- */
/* Společné styly pro SVG ikony v theme toggleru. Přepínač samotný je
   v launcher popoveru (footer .app-launcher-footer níž), ne v topbaru.
   .app-theme-btn = společná class buttonu, dvě SVG vrstvy, CSS vždy
   zobrazí jen jednu podle data-theme. */
.app-theme-btn .app-theme-svg {
    width: 18px;
    height: 18px;
    display: block;
    flex-shrink: 0;
}
/* Default (dark theme): zobrazí se moon (akce = přepnout na light) */
.app-theme-btn .app-theme-sun  { display: none; }
.app-theme-btn .app-theme-moon { display: block; }
/* Light theme: zobrazí se sun (akce = přepnout na dark) */
[data-theme="light"] .app-theme-btn .app-theme-sun  { display: block; }
[data-theme="light"] .app-theme-btn .app-theme-moon { display: none; }
/* Stejně pro textový label - "Světlé téma" v dark, "Tmavé téma" v light */
.app-launcher-theme-text-dark  { display: inline; }
.app-launcher-theme-text-light { display: none; }
[data-theme="light"] .app-launcher-theme-text-dark  { display: none; }
[data-theme="light"] .app-launcher-theme-text-light { display: inline; }

/* ----- Delta launcher (vlevo v topbaru) ---------------------------- */
/* Logo = SVG trojúhelník v gradientové modré. Klik otevře popover
   s aplikacemi (níž). Hover má jemné světlé pozadí + scale. */
.app-topbar-logo {
    width: 38px;
    height: 38px;
    padding: 4px;
    margin-right: 4px;
    background: transparent;
    border: 0;
    border-radius: 8px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.12s, transform 0.12s;
    flex-shrink: 0;
    color: inherit;
}
.app-topbar-logo:hover {
    background: var(--hover-overlay);
}
.app-topbar-logo:active,
.app-topbar-logo[aria-expanded="true"] {
    background: var(--hover-overlay-strong);
    transform: scale(0.96);
}
.app-topbar-logo:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.app-topbar-logo-svg {
    width: 26px;
    height: 26px;
    display: block;
    filter: drop-shadow(0 1px 2px var(--logo-shadow));
}

/* ----- App launcher popover --------------------------------------- */
.app-launcher-popover {
    position: fixed;
    top: 50px;
    left: 12px;
    /* Sirsi, aby se vesly 2 sloupce aplikaci (nizsi menu na tabletu). */
    width: 520px;
    max-width: calc(100vw - 24px);
    max-height: calc(100vh - 70px);
    background: var(--bg-popover);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: var(--shadow-popover);
    z-index: 1080;
    display: none;
    flex-direction: column;
    overflow: hidden;
}
.app-launcher-popover.open {
    display: flex;
    animation: app-launcher-fadein 0.14s ease-out;
}
@keyframes app-launcher-fadein {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}

.app-launcher-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border-soft);
    /* Mírné modré podbarvení prvního řádku ("Přepnout modul") - tmavé
       téma ztlumená modrá, světlé téma jemně modrá (viz override níž). */
    background: rgba(96, 150, 230, 0.14);
}
[data-theme="light"] .app-launcher-header {
    background: #e9f0fb;
}
.app-launcher-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-strong);
    letter-spacing: 0.3px;
}
.app-launcher-portal-link {
    font-size: 11px;
    color: var(--accent);
    text-decoration: none;
    white-space: nowrap;
}
.app-launcher-portal-link:hover {
    color: var(--accent-hover);
    text-decoration: underline;
}

.app-launcher-empty {
    padding: 24px 14px;
    text-align: center;
    color: var(--text-subtle);
    font-size: 13px;
}

.app-launcher-list {
    overflow-y: auto;
    padding: 8px;
    flex: 1;
    /* Matice ikon - 3-4 sloupce dle sirky popoveru (auto-fill). */
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
    gap: 6px;
}

/* Karta jedné aplikace v launcheru = ctverec s oblymi rohy ve stylu
   dlazdic na uvodni strane (ikona nahore, nazev pod ni). --app-color
   zděděno z inline stylu na <a>; ikona ma neutralni pozadi + barevny
   spodni okraj v teto barve. */
.app-launcher-app {
    position: relative;             /* kotva pro .current badge */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    padding: 12px 8px;
    border-radius: 12px;
    text-decoration: none;
    color: var(--text);
    transition: background-color 0.12s, transform 0.12s;
    text-align: center;
    border: 1px solid transparent;
}
.app-launcher-app:hover {
    background: var(--hover-overlay);
    color: var(--text);
}
.app-launcher-app.current {
    background: var(--accent-soft);
    border-color: var(--app-color, var(--accent));
}
.app-launcher-app.current:hover {
    background: var(--accent-soft-hover);
}
.app-launcher-icon {
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    /* Office-styl (jako ikony na uvodu): neutralni pozadi dle motivu +
       jemny barevny spodni okraj, barevnost drzi jen SVG. */
    background: var(--bg-elevated);
    border: 1px solid var(--border-soft);
    border-bottom: 2px solid var(--app-color, #555);
    color: var(--app-color, #555);
    padding: 6px;
    transition: border-bottom-width 0.15s ease;
}
.app-launcher-app:hover .app-launcher-icon {
    border-bottom-width: 3px;
}
.app-launcher-icon svg {
    width: 100%;
    height: 100%;
    display: block;
}
/* Zjednoduseni: v menu staci nazev modulu (jako dlazdice na uvodu),
   popisek skryjeme - polozky jsou kompaktni a menu nizsi. */
.app-launcher-desc {
    display: none;
}
.app-launcher-info {
    width: 100%;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}
.app-launcher-name {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-strong);
    line-height: 1.2;
    text-align: center;
    /* Delsi nazvy se zalomi pod ikonu (max 2 radky). */
    white-space: normal;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.app-launcher-desc {
    font-size: 11px;
    color: var(--text-faint);
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.app-launcher-current-badge {
    position: absolute;
    top: 6px;
    right: 8px;
    color: var(--app-color, var(--accent));
    font-size: 10px;
    line-height: 1;
    flex-shrink: 0;
    text-shadow: 0 0 6px var(--app-color, var(--accent));
}

/* ----- Launcher footer s theme toggle ----------------------------- */
.app-launcher-footer {
    border-top: 1px solid var(--border-soft);
    background: var(--bg-elevated);
    padding: 6px;
}
.app-launcher-theme-btn {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    background: transparent;
    border: 0;
    border-radius: 6px;
    color: var(--text);
    font-size: 13px;
    cursor: pointer;
    text-align: left;
    transition: background-color 0.12s, color 0.12s;
}
.app-launcher-theme-btn:hover {
    background: var(--hover-overlay);
    color: var(--text-strong);
}
.app-launcher-theme-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.app-launcher-theme-label {
    flex: 1;
    font-weight: 500;
}

/* Mobil: launcher přes celou šířku, pod topbarem */
@media (max-width: 480px) {
    .app-launcher-popover {
        left: 6px;
        right: 6px;
        width: auto;
        max-width: none;
    }
}
/* Uzky telefon: zpet na 1 sloupec (2 sloupce by byly stesnane). */
@media (max-width: 440px) {
    .app-launcher-list {
        grid-template-columns: 1fr;
    }
}

/* ----- Portál (index.php) ----------------------------------------- */
.portal-body {
    background: var(--bg);
    color: var(--text);
    margin: 0;
    min-height: 100vh;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    /* Stack context pro tečkovanou animaci - obsah portálu (header/main)
       musí být nad ::before vrstvou (z-index: 0 -> 1). */
    position: relative;
    overflow-x: hidden;
}

/* ====== Tečkované pozadí reagující na myš ======
   Dvouvrstvý radial-gradient dot pattern v různých roztečích a alfa
   hodnotách (vrstvený dojem hloubky). Pozadí se posouvá podle pozice
   myši - dvě vrstvy jedou různou rychlostí, takže vzniká parallax efekt
   (přední vrstva běží rychleji než pozadí).

   Pohyb se ovládá CSS proměnnými --dot-mx, --dot-my (-1..+1) nastavovanými
   JS handlerem v portal/index.php a portal/login.php. Mezi pohyby
   dotahuje pozici cubic-bezier transition, takže když uživatel přestane
   pohybovat myší, dotečky doplujou tam kde právě stál kurzor.

   pointer-events: none = kliky/výběr procházejí na obsah pod ním. */
.portal-body::before,
.login-body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    --dot-size: 20px;
    /* Conic gradient v jediném hue (slate blue ~210°) - same hue, varying
       lightness. Když to promaskujeme do mřížky bodů, každá tečka má jen
       jinou jasovou variantu téže barvy = monochromatické pozadí bez
       duhových přechodů. Subtle depth bez vizuálního rušení (předchozí
       5-barevný rainbow byl barevně bohatý, ale s 11 různě barevnými
       modul ikonkami nahoře to vytvářelo barevný šum).
       Pokud chceš ladit jiný odstín, stačí změnit první číslo (hue, 0-360):
         210 = slate blue (current), 180 = teal, 0 = warm white, 50 = warm amber. */
    background: conic-gradient(
        from 180deg at 50% 70%,
        rgba(78, 96, 112, 0.322) 0deg,
        rgba(120, 130, 139, 0.363) 90deg,
        hsla(210, 38%, 52%, 1) 180deg,
        rgba(52, 75, 99, 0.521) 270deg,
        rgba(70, 88, 104, 0.349) 360deg
    );
    /* Dvojitá maska:
       1) Radial gradient = mřížka teček (2 px průměr) po --dot-size pixelech.
          Viditelné jen body, nikoli plocha mezi nimi.
       2) Noise PNG = nepravidelný šum 256x256 px. Posouvá se v X,
          takže každou chvíli osvětluje jiné tečky = blikání jako hvězdy.
       mask-composite: intersect = tečka svítí JEN když ji v dané chvíli
       povolí oba masky najednou (existence v mřížce ∧ šum nad ní). */
    mask:
        radial-gradient(circle at 50% 50%, white 2px, transparent 2.5px)
            50% 50% / var(--dot-size) var(--dot-size),
        url("noise-mask.png") 256px 50% / 256px 256px;
    -webkit-mask:
        radial-gradient(circle at 50% 50%, white 2px, transparent 2.5px)
            50% 50% / var(--dot-size) var(--dot-size),
        url("noise-mask.png") 256px 50% / 256px 256px;
    mask-composite: intersect;
    -webkit-mask-composite: source-in;  /* WebKit ekvivalent intersect pro 2 vrstvy */
    animation: portal-dot-flicker 40s infinite linear;
}
/* Posuv noise masky o 256 px za 20 s = nepřetržitý blikací efekt.
   První maska (mřížka teček) zůstává staticky uprostřed (50% 50%),
   posouvá se jen druhá (noise) z 256 px na 0 px na ose X. */
@keyframes portal-dot-flicker {
    to {
        mask-position: 50% 50%, 0 50%;
        -webkit-mask-position: 50% 50%, 0 50%;
    }
}
/* Reduced-motion uživatelé - bez blikání, tečky zůstávají statické,
   ale viditelné. */
@media (prefers-reduced-motion: reduce) {
    .portal-body::before,
    .login-body::before {
        animation: none;
    }
}

/* Header a main musí být nad pozadím (z-index 0 z ::before), jinak by
   tečky překreslily karty. Stejné pro login content. */
.portal-main,
.login-body .container {
    position: relative;
    z-index: 1;
}
/* Header zvlášť s vyšším z-index než main - jinak by absolutně-pozicované
   dropdown menu uvnitř headeru (.portal-actions-menu) bylo prebito
   stejnopozicovaným .portal-main (dva stacking contexts s z-index: 1,
   pozdějši v DOM vyhrává). Hodinová sekce je v main, takže byla nad
   menu. Header s z-index 10 ji odsune pod. */
.portal-header {
    position: relative;
    z-index: 10;
}

.portal-header {
    background: var(--bg-elevated);
    border-bottom: 1px solid var(--border);
    padding: 18px 0;
    margin-bottom: 32px;
}
.portal-title {
    font-size: 22px;
    font-weight: 500;
    letter-spacing: 0.3px;
    color: var(--text-strong);
    /* Inline-flex aby se SVG logo, text a verze srovnaly podle baselinu
       (resp. vertical-center). */
    display: inline-flex;
    align-items: center;
    gap: 12px;
}

/* Velký Delta logo v hlavičce portál home - většinou ~48 px. SVG má
   vlastní gradient + outline. drop-shadow zlehka odsadí logo od bg
   (subtle 3D pocit, žádný harsh efekt).

   Periodický světelný puls (každých 8 s krátký záblesk modré záře).
   Pomáhá vizuálně "ožít" stránce, ale dost vzácně, aby to nerozptylovalo.
   Drop-shadow filter sleduje tvar trojúhelníku (na rozdíl od box-shadow,
   která by byla obdélníková). */
.portal-home-logo {
    /* Sjednoceno s velikostí avataru (.portal-avatar = 56 px), ať logo
       a profilový blok na hlavní straně mají vizuální rovnováhu. */
    width: 56px;
    height: 56px;
    flex: 0 0 auto;
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.35));
    animation: portal-logo-pulse 8s ease-in-out infinite;
}
@keyframes portal-logo-pulse {
    /* 0-70 %: klid - jen baseline drop-shadow.
       70-90 %: záře nabíhá a vrcholí (~85 %) - modrá v tónu loga.
       90-100 %: zpět do klidu. */
    0%, 70% {
        filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.35));
    }
    78% {
        filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.35))
                drop-shadow(0 0  6px rgba(126, 200, 255, 0.55))
                drop-shadow(0 0 14px rgba(126, 200, 255, 0.30));
    }
    85% {
        filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.35))
                drop-shadow(0 0 10px rgba(126, 200, 255, 0.75))
                drop-shadow(0 0 22px rgba(126, 200, 255, 0.45));
    }
    100% {
        filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.35));
    }
}
/* Respekt k uživatelské volbě "omezit pohyb" (Win / macOS / iOS settings).
   Animace se vypne, baseline drop-shadow zůstane. */
@media (prefers-reduced-motion: reduce) {
    .portal-home-logo {
        animation: none;
    }
}

/* Stacked title-text - "Delta" velký, verze pod ním v jednom sloupci.
   Logo vedle zůstává vertikálně vycentrované na celý blok (parent
   .portal-title je inline-flex align-items: center). */
.portal-title-text {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    line-height: 1.1;
    gap: 1px;
}
.portal-title-name {
    font-size: 24px;
    font-weight: 500;
    color: var(--text-strong);
}

/* Verze portálu - drobný subtilní text pod hlavním nadpisem na
   portal/index.php a vedle nadpisu na login.php. Žádný jiný modul
   tuto třídu nepoužívá (vědomě - topbar modulů zůstává kompaktní). */
.portal-version {
    color: var(--text-faint);
    font-size: 12px;
    font-weight: 400;
    letter-spacing: 0;
    cursor: help;
}
/* Na portal/index.php = pod nadpisem ve sloupcové struktuře - není
   potřeba margin-left ani vertical-align. */
.portal-title-text .portal-version {
    margin-left: 0;
}
/* Na login obrazovce vedle "Delta portál" - menší a zarovnaný baseline,
   ať nevyčuhuje z nadpisu h2. */
.login-version {
    font-size: 11px;
}
.portal-user {
    font-size: 14px;
    color: var(--text-light);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.portal-user-icon {
    font-size: 18px;
}
/* Role na samostatném řádku pod jménem (3-řádkový stack jméno/role/firmy).
   Bez závorek - layout sám říká, že je to upřesnění jména. Drobnější
   font + uppercase letter-spacing, ať vypadá jako "tag" než další jméno. */
.portal-user-role {
    color: var(--text-faint);
    font-size: 11px;
    margin-top: 1px;
    letter-spacing: 0.3px;
    font-weight: 500;
    text-transform: uppercase;
}

/* ====== Profil uživatele v hlavičce portálu ======
   Avatar (kruh s iniciálami) vlevo, dva řádky info vpravo (jméno+role
   a seznam firem). Layout: horizontal flex, vertikální zarovnání na střed.
   Avatar má deterministickou barvu (CSS proměnná --avatar-color z PHP),
   ať se shoduje napříč sessions stejného uživatele. */
.portal-user-block {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-size: 14px;
    color: var(--text-light);
    /* Max-width pro firmy řádek - dlouhé seznamy se zalomí, ne aby
       narostl header do šířky. ellipsis fallback pro extrémně dlouhé. */
    max-width: 360px;
}
/* Avatar - kruh 56px, buď uploadnutý obrázek (img dovnitř, object-fit:cover)
   nebo iniciály fallback. Renderovaný jako <button>, ne <span>, ať se na
   něj dá kliknout a otevřít file picker. Hover overlay s kamera ikonkou
   naznačuje "klikni pro změnu". */
.portal-avatar {
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--avatar-color, #6c757d);
    color: #fff;
    /* button reset - bez native rámečku */
    border: 0;
    padding: 0;
    cursor: pointer;
    /* layout pro iniciály/img a overlay */
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    /* Subtle inner shadow pro dojem hloubky, žádný šedý look */
    box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.18),
                0 0 0 1px rgba(255, 255, 255, 0.06);
    user-select: none;
    transition: box-shadow 0.15s, transform 0.12s;
}
.portal-avatar:hover {
    box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.18),
                0 0 0 2px rgba(255, 255, 255, 0.18);
}
.portal-avatar:active {
    transform: scale(0.97);
}
.portal-avatar.is-uploading {
    pointer-events: none;
    opacity: 0.6;
}
/* Iniciály - text uvnitř kruhu (fallback bez nahrané fotky) */
.portal-avatar-initials {
    font-weight: 600;
    font-size: 20px;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}
/* Uploadnutý obrázek - vyplní celý kruh, ořízne se přesah */
.portal-avatar-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
/* Hover overlay - poloprůhledná tmavá vrstva s kamera ikonou na hover.
   Slouží jako visual hint, že se na avatar dá kliknout. Default skryto. */
.portal-avatar-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    opacity: 0;
    transition: opacity 0.15s;
    pointer-events: none;  /* klik propadne na .portal-avatar button */
}
.portal-avatar:hover .portal-avatar-overlay,
.portal-avatar:focus-visible .portal-avatar-overlay {
    opacity: 1;
}
/* Delete button - malá křížek pravým horním rohem avataru, viditelný
   jen když má user fotku. Stop propagation v JS, ať klik na něj
   neotevře file picker. */
.portal-avatar-delete {
    position: absolute;
    /* Posunutý k pravému hornímu rohu, ale neopustí .portal-user-block */
    margin-left: -16px;
    margin-top: -6px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #dc3545;
    color: #fff;
    border: 2px solid var(--bg-elevated, #1e1e1e);
    font-size: 14px;
    font-weight: bold;
    line-height: 1;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 2;
    transition: transform 0.12s, background 0.12s;
}
.portal-avatar-delete:hover {
    background: #b02a37;
    transform: scale(1.1);
}
.portal-user-info {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    line-height: 1.2;
    min-width: 0;  /* dovolí text-overflow ellipsis */
}
.portal-user-name {
    font-weight: 500;
    color: var(--text-strong);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}
.portal-user-firmy {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 2px;
    /* Dlouhé seznamy firem se zalomí na další řádek pomocí
       overflow:hidden + line-clamp (2 řádky max). Není-li clamp
       podporován, fallback na ellipsis na 1. řádku. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.3;
    max-width: 100%;
}
/* Profilový blok záměrně neutrální - žádné zvýraznění barvou. Všechny
   stavy ("Všechny firmy" / seznam / "Bez přiřazené firmy") dědí
   --text-muted z .portal-user-firmy. Topbar má držet jen logo modrou +
   neutrální text, ať drobnosti jako pole firem neodvádějí pozornost
   od hlavního obsahu portálu. */
.portal-user-firmy-all {
    /* Bez zvláštní barvy - dědí --text-muted. */
}
.portal-user-firmy-none {
    /* Bez zvláštní barvy - italic jako jediný jemný hint, že stav je
       atypický (uživatel bez přiřazené firmy). */
    font-style: italic;
}

.portal-main {
    padding-bottom: 60px;
}

/* ====== Sekce "Oblíbené zakázky" ======
   Renderuje se pod hlavním apps-gridem, jen pokud má uživatel app
   'zakazky' A aspoň jeden uložený set v portal_users.skupiny_zk
   (gating v PHP). Tile = složka se srdcem + název + počet + datum,
   klik = navigace na zakazky/?favorite_set=ID.

   Layout je užší a kompaktnější než hlavní apps grid (oblíbené
   jsou doplněk, ne hlavní akce - nepřebíjet vizuálně modul-karty
   nad nimi). */
.portal-favorites {
    margin-top: 36px;
    padding-top: 24px;
    border-top: 1px solid var(--border-soft);
}
/* Když .portal-favorites následuje po .portal-tips (`~` = general sibling,
   adjacent `+` by selhal kvůli <script> bloku mezi).
   Override:
     - margin-top: 0  — tipy.margin-bottom (30 px) už zajišťuje gap nad favorites
     - padding-top: small — separace mezi border-top a title
     - border-top: ZACHOVÁN (user: "tu carku nad oblibenymi zakakami nech")
   Bez tipsů (= když .portal-favorites stojí samostatně bez tipů nad sebou)
   zůstává default margin-top: 36 + padding-top: 24 — větší vzdušná separace. */
.portal-tips ~ .portal-favorites {
    margin-top: 0;
    padding-top: 26px;       /* match s tipy.margin-top → symetrický gap 45 px kolem ticker */
    /* border-top inherited = 1px solid var(--border-soft); "tu carku nech" */
}
.portal-favorites-title {
    font-size: 15px;
    font-weight: 500;
    color: var(--text-muted);
    margin: 0 0 14px;
    letter-spacing: 0.3px;
}
.portal-favorites-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
}
/* Tile = container s position:relative, uvnitř <a> link (clickable area)
   a <div class="portal-favorite-actions"> (hover-only edit/delete buttons).
   Barva skupiny propagována přes CSS proměnnou --fav-color (inline style
   z PHP) - aplikuje se na border-left + ikonu složky.
   Tile NENÍ samo <a>, protože ne všechno uvnitř má vést na navigaci -
   tlačítka edit/delete jsou osamostatněná. */
.portal-favorite-tile {
    position: relative;
    /* Tile bez vlastniho pozadi/ramecku - jediny barevny prvek je ikona
       (folder/hodiny). Pod nazvem a meta textem zadne pozadi. Hover dela
       jen lift (+ zvyrazneni ikony nize), bez tintu cele dlazdice. */
    background: transparent;
    border: 0;
    border-radius: 12px;
    transition: transform 0.12s ease, opacity 0.18s;
}
.portal-favorite-tile:hover {
    /* Office-styl: bez "liftu", jen jemne zvyrazneni pozadi dlazdice. */
    background: var(--bg-card-hover);
}
.portal-favorite-tile.is-removing {
    opacity: 0;
    transform: translateY(4px);
    pointer-events: none;
}
/* Klikací oblast - hlavní část tile (ikona + jméno + meta) */
.portal-favorite-tile-link {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    text-decoration: none;
    color: var(--text);
}
.portal-favorite-tile-link:hover {
    text-decoration: none;
    color: var(--text);
}
.portal-favorite-tile-link:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 6px;
}
.portal-favorite-icon {
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Stejny Office-styl jako ikony na uvodni strane (.portal-card-icon):
       neutralni pozadi dle motivu + jemny barevny spodni okraj (border),
       barevnost drzi jen SVG. */
    background: var(--bg-elevated);
    border: 1px solid var(--border-soft);
    border-bottom: 3px solid var(--fav-color, #6c757d);
    border-radius: 12px;
    color: var(--fav-color, #6c757d);
    transition: box-shadow 0.15s ease, border-bottom-width 0.15s ease;
}
.portal-favorite-icon svg {
    width: 24px;
    height: 24px;
}
.portal-favorite-tile:hover .portal-favorite-icon {
    border-bottom-width: 4px;
}
.portal-favorite-body {
    flex: 1;
    min-width: 0;
    /* padding-right rezervuje misto na edit + delete ikony v rohu (skryte
       dokud neni hover, ale dlouhe nazvy musi byt ellipsovany predtim,
       jinak text se prekryl s ikonami pri hoveru). 2 ikony x 24 + gap 4 +
       right 8 = ~60 px. */
    padding-right: 60px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.portal-favorite-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.portal-favorite-meta {
    font-size: 11px;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Hover akce - edit + delete buttony v pravém horním rohu tile.
   Default skryté (opacity:0), zviditelní se při hover na .portal-favorite-tile.
   pointer-events:none když skryté = klik prochází na klikatelný link pod nimi. */
.portal-favorite-actions {
    position: absolute;
    top: 8px;
    right: 8px;
    display: flex;
    gap: 4px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s;
}
.portal-favorite-tile:hover .portal-favorite-actions,
.portal-favorite-tile:focus-within .portal-favorite-actions {
    opacity: 1;
    pointer-events: auto;
}
.portal-favorite-action {
    width: 24px;
    height: 24px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 4px;
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.portal-favorite-action:hover {
    background: rgba(255, 255, 255, 0.14);
    color: var(--text);
    border-color: rgba(255, 255, 255, 0.22);
}
.portal-favorite-delete:hover {
    background: rgba(220, 53, 69, 0.18);
    color: #ff8a96;
    border-color: rgba(220, 53, 69, 0.35);
}

/* Sdílení badge - levý dolní roh dlaždice. Dva stavy:
   - portal-favorite-badge--own (vlastní sdílený set, "Sdíleno")
       = uživatel ho sdílí s firmou, reminder badge
   - portal-favorite-badge--received (přijato od kolegy, "Sdílené")
       = read-only, žádné edit/delete tlačítka
   Decentní pozadí + ikonka lidi vlevo. NEZASAHUJE do hover akcí
   (vlastní sdílené sety mají edit/delete vpravo nahoře jako vždy). */
.portal-favorite-badge {
    position: absolute;
    left: 10px;
    bottom: 8px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 7px 2px 6px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    line-height: 1.4;
    border-radius: 10px;
    color: #cbd3da;
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid rgba(255, 255, 255, 0.12);
    /* Klikání nesabotuje - klik prochází na tile-link pod ním. */
    pointer-events: none;
}
.portal-favorite-badge svg {
    flex: 0 0 auto;
    opacity: 0.85;
}
/* Received - subtilní teal odstín, ať user okamžitě vidí, že je to
   "cizí" skupina (read-only). Stejný odstín, jaký používá novinky modul. */
.portal-favorite-badge--received {
    color: #74d3b8;
    background: rgba(32, 201, 151, 0.12);
    border-color: rgba(32, 201, 151, 0.32);
}
/* Own-shared - neutrálnější "ok, sdílím to" reminder, modrý odstín. */
.portal-favorite-badge--own {
    color: #9ec5fe;
    background: rgba(13, 110, 253, 0.14);
    border-color: rgba(13, 110, 253, 0.32);
}
/* Received tile - žádný hover lift (== "není to úplně tvoje, nelez tam
   moc". Zachová klikací odkaz, ale less aggressive treatment). */
.portal-favorite-tile.is-received:hover {
    /* Nepřebij hover state úplně - jen ho lehce ztlumí. */
    filter: brightness(1.02);
    transform: none;
}
/* Owner label uvnitř meta line - mírně přitlumený, ale viditelný. */
.portal-favorite-owner {
    color: #74d3b8;
    font-weight: 500;
}

/* Edit modal - sdílení checkbox + krátká poznámka. Žádný box / border /
   background - drží se ploché linie ostatních polí modalu (Název / Barva).
   První řádek = hlavní label (medium váha jako .fav-edit-label),
   druhý řádek = drobný hint (muted, menší písmo). */
.fav-edit-share {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 14px 0 6px;
    cursor: pointer;
    user-select: none;
}
.fav-edit-share input[type="checkbox"] {
    width: 16px;
    height: 16px;
    margin-top: 1px;
    flex: 0 0 auto;
    accent-color: #0d6efd;
    cursor: pointer;
}
.fav-edit-share-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    line-height: 1.35;
    font-size: 13px;
    color: var(--text);
}
.fav-edit-share-text small {
    color: var(--text-muted);
    font-size: 11px;
}

/* ====== Edit modal pro oblíbenou skupinu ======
   Vanilla HTML overlay (z portal-favorites.js), open/close řízeno
   .is-open class na #favEditOverlay. */
.fav-edit-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 1050;
    padding: 20px;
}
.fav-edit-overlay.is-open {
    display: flex;
}
.fav-edit-modal {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: var(--shadow-popover);
    padding: 20px 24px 18px;
    width: 100%;
    max-width: 420px;
    max-height: 90vh;
    overflow: auto;
}
.fav-edit-title {
    font-size: 16px;
    font-weight: 600;
    margin: 0 0 14px;
    color: var(--text);
}
.fav-edit-label {
    display: block;
    font-size: 12px;
    color: var(--text-muted);
    margin: 10px 0 4px;
    font-weight: 500;
}
.fav-edit-input {
    width: 100%;
    padding: 8px 10px;
    background: var(--bg-input);
    color: var(--text);
    border: 1px solid var(--border-input);
    border-radius: 4px;
    font-size: 14px;
    box-sizing: border-box;
}
.fav-edit-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--accent-focus-ring);
}
.fav-edit-colors {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 4px;
}
.fav-color-chip {
    width: 28px;
    height: 28px;
    padding: 0;
    border: 2px solid transparent;
    border-radius: 50%;
    cursor: pointer;
    transition: transform 0.12s, border-color 0.12s, box-shadow 0.12s;
}
.fav-color-chip:hover {
    transform: scale(1.08);
}
.fav-color-chip.is-selected {
    border-color: var(--text);
    box-shadow: 0 0 0 2px var(--bg-card), 0 0 0 4px var(--accent);
}
.fav-edit-err {
    font-size: 12px;
    color: #ff8a96;
    margin-top: 10px;
    min-height: 0;
    overflow: hidden;
    transition: min-height 0.15s;
}
.fav-edit-err.is-visible {
    min-height: 18px;
}
.fav-edit-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 18px;
}

/* ====== Success varianta error blocku ====== Stejný element jako
   .fav-edit-err, jen jiná barva textu - používá ho portal-password.js
   pro krátké "Heslo bylo změněno" hláška před auto-close modalu. */
.fav-edit-err.is-success {
    color: #6fdc8c;
}

/* ====== Modal pro změnu hesla ======
   Sdílí .fav-edit-overlay / .fav-edit-modal / .fav-edit-input s edit
   modalem oblíbených skupin, ale přidává navíc:
   - .pwd-input-wrap = relativně pozicovaný wrapper, aby se eye-toggle
     dal absolutně přilepit do pravé strany inputu
   - .pwd-toggle     = ikonové tlačítko s dvěma SVG (eye / eye-off),
     které se přepíná třídou .is-visible
   - .pwd-strength   = 4-segmentový bar pod novým heslem, segmenty se
     postupně rozsvěcují podle skóre (třídy .is-1 .. .is-4)
*/
.pwd-input-wrap {
    position: relative;
}
.pwd-input-wrap .fav-edit-input {
    padding-right: 38px;  /* místo pro eye-toggle */
}
.pwd-toggle {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    background: transparent;
    border: 0;
    padding: 4px;
    color: var(--text-muted);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    transition: color 0.12s, background 0.12s;
}
.pwd-toggle:hover {
    color: var(--text);
    background: rgba(255, 255, 255, 0.05);
}
.pwd-toggle .pwd-eye-off { display: none; }
.pwd-toggle.is-visible .pwd-eye     { display: none; }
.pwd-toggle.is-visible .pwd-eye-off { display: block; }

/* Strength meter - 4 stejně široké segmenty s gap. Rozsvícení řízeno
   třídami .is-1 .. .is-4 na rodiči (.pwd-strength). Barevný gradient
   slabé→silné = červená → oranžová → žlutá → zelená. */
.pwd-strength {
    margin-top: 8px;
    margin-bottom: 4px;
}
.pwd-strength-bar {
    display: flex;
    gap: 4px;
    height: 6px;
}
.pwd-strength-seg {
    flex: 1;
    background: var(--border);
    border-radius: 2px;
    transition: background 0.18s;
}
.pwd-strength.is-1 .pwd-strength-seg:nth-child(-n+1) { background: #dc3545; }
.pwd-strength.is-2 .pwd-strength-seg:nth-child(-n+2) { background: #fd7e14; }
.pwd-strength.is-3 .pwd-strength-seg:nth-child(-n+3) { background: #ffc107; }
.pwd-strength.is-4 .pwd-strength-seg:nth-child(-n+4) { background: #198754; }
.pwd-strength-text {
    margin-top: 5px;
    font-size: 11px;
    color: var(--text-muted);
    min-height: 14px;
}
.pwd-strength.is-1 .pwd-strength-text { color: #ff8a96; }
.pwd-strength.is-2 .pwd-strength-text { color: #ffac6b; }
.pwd-strength.is-3 .pwd-strength-text { color: #ffd966; }
.pwd-strength.is-4 .pwd-strength-text { color: #6fdc8c; }

/* ====== System-style hodiny nad mřížkou dlaždic ======
   Veliký čas (HH:MM:SS) a pod ním česky den + datum. Renderuje JS
   v portal-home.js každou sekundu. Tabular-nums zabrání skoku layoutu
   při změně sekund. Subtle text-shadow zlepšuje čitelnost nad barevným
   blikajícím pozadím (conic gradient + noise mask v portal-body::before). */
.portal-clock {
    text-align: center;
    margin: 8px 0 32px;
    user-select: none;
    /* Fixni vyska bloku (pozdrav + cas + datum + svatek), aby stranka
       neposkakovala behem intro pozdravu - tehdy je cas/datum/svatek
       docasne display:none a vyska by jinak kolabovala. Drzime steady-state
       vysku po celou dobu. */
    min-height: 156px;
}
/* Vlídný pozdrav podle denní doby nad hodinami. Jemnější váha, menší
   než čas, ale větší než datum - signál "vítej", než uživatel sklouzne
   na čas a info pod ním. */
.portal-clock-greeting {
    font-size: 20px;
    font-weight: 300;
    color: var(--text);
    letter-spacing: 0.4px;
    margin-bottom: 6px;
    text-shadow: 0 0 12px rgba(0, 0, 0, 0.5);
    /* Plynule zmenseni z intro velikosti (64px) zpet na 20px. */
    transition: font-size 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
/* === Intro pozdravu (psani velkym pismem, viz portal-clock.js) === */
/* Behem psani je v bloku jen pozdrav - cas/datum/svatek skryty. Pozdrav
   navic vystredime svisle do oblasti hodin (min-height bloku), aby se psal
   priblizne uprostred mista, kde pak bude pozdrav+cas+datum. */
.portal-clock.is-greeting-intro {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
.portal-clock.is-greeting-intro .portal-clock-time,
.portal-clock.is-greeting-intro .portal-clock-date,
.portal-clock.is-greeting-intro .portal-clock-nameday {
    display: none;
}
/* Faze "usazeni": pozdrav se zmensuje a zaroven sklouzava z vystredene
   pozice na svoje bezne staticke misto (nahore). Layout uz je top-aligned
   (bezny tok), ale cas/datum/svatek jsou jeste skryte, dokud pozdrav nedojede
   na misto - jinak by blok behem prechodu poskocil. JS ridi translateY. */
.portal-clock.is-greeting-settling .portal-clock-time,
.portal-clock.is-greeting-settling .portal-clock-date,
.portal-clock.is-greeting-settling .portal-clock-nameday {
    display: none;
}
/* Psany pozdrav se pise VELKYM pismem ve vysce casu (64px), v normalnim
   psani (bez verzalek - "Dobrý den"), s blikajicim kurzorem. Po dopsani se
   chvili podrzi a pak se s font-size transition zmensi do bezne podoby. */
.portal-clock-greeting.is-typing {
    /* inline-block, aby se sirka stahla na text a kurzor (border-right)
       sedel hned za poslednim napsanym znakem (ne u praveho okraje bloku).
       Parent .portal-clock ma text-align:center, takze zustava vystredeny. */
    display: inline-block;
    font-size: 64px;            /* stejna vyska jako .portal-clock-time */
    font-weight: 200;
    line-height: 1;
    letter-spacing: 1px;
    color: var(--text-strong);
    text-shadow: 0 0 16px rgba(0, 0, 0, 0.55);
    margin-bottom: 0;
    min-height: 1em;
    white-space: nowrap;
    border-right: 0.06em solid currentColor;
    padding-right: 0.06em;
    animation: portalGreetCaret 0.85s steps(1, end) infinite;
}
@keyframes portalGreetCaret {
    0%, 50%   { border-right-color: currentColor; }
    51%, 100% { border-right-color: transparent; }
}
/* Po dopsani: cas/datum/svatek se doplni s jemnym fade-in zdola. */
.portal-clock.is-greeting-reveal .portal-clock-time,
.portal-clock.is-greeting-reveal .portal-clock-date,
.portal-clock.is-greeting-reveal .portal-clock-nameday {
    animation: portalClockReveal 0.45s ease both;
}
@keyframes portalClockReveal {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}
@media (max-width: 640px) {
    .portal-clock-greeting.is-typing { font-size: 44px; }
}
@media (prefers-reduced-motion: reduce) {
    .portal-clock-greeting.is-typing {
        animation: none;
        border-right-color: transparent;
    }
}
.portal-clock-time {
    font-size: 64px;
    font-weight: 200;
    color: var(--text-strong);
    line-height: 1;
    letter-spacing: 1px;
    font-variant-numeric: tabular-nums;
    text-shadow: 0 0 16px rgba(0, 0, 0, 0.55);
}
/* Roll animace cislic: kazda cislice je vlastni klipovaci okenko vysoke
   1 radek. Pri zmene casu prijede nova cislice seshora dolu a stara
   zaroven odjede dolu a schova se za spodni hranou okenka (overflow:hidden).
   JS (portal-clock.js) stavi bunky a track. Dvojtecka (.is-sep) je staticka.
   .portal-clock-time--roll trida se pridava az z JS, aby pri vypnutem JS
   zustal cisty textovy fallback. */
.portal-clock-time--roll {
    display: inline-flex;
    align-items: flex-start;
    justify-content: center;
}
.portal-clock-digit {
    position: relative;
    display: inline-block;
    /* Trochu vyssi nez 1em, aby se glow cislic neorezaval u horni/dolni
       hrany okenka. Track se posouva o tuto vysku. */
    height: 1.12em;
    line-height: 1.12;
    overflow: hidden;
    vertical-align: top;
}
.portal-clock-digit.is-sep {
    /* Separator neklipujeme - at glow dvojtecky neni orezany. */
    overflow: visible;
}
.portal-clock-digit-track {
    display: flex;
    flex-direction: column;
    will-change: transform;
}
.portal-clock-digit-cell {
    display: block;
    height: 1.12em;
    line-height: 1.12;
}
/* Vychozi (pred-animacni) stav: track posunut nahoru o jednu bunku, takze
   v okenku je videt STARA cislice (spodni bunka). */
.portal-clock-digit-track.is-pre {
    transform: translateY(-50%);
}
/* Cilovy stav: track na 0 -> v okenku NOVA cislice (horni bunka), stara
   sjela pod spodni hranu a schovala se. */
.portal-clock-digit-track.is-rolling {
    transform: translateY(0);
    transition: transform 0.42s cubic-bezier(0.16, 1, 0.3, 1);
}
@media (prefers-reduced-motion: reduce) {
    .portal-clock-digit-track.is-rolling {
        transition: none;
    }
}
.portal-clock-date {
    margin-top: 6px;
    font-size: 16px;
    color: var(--text-muted);
    font-weight: 400;
    letter-spacing: 0.5px;
    text-shadow: 0 0 10px rgba(0, 0, 0, 0.45);
}
/* Řádek se svátkem (jmeniny / státní svátek) - jemnější, ještě menší
   font než datum, aby tvořil jasnou hierarchii čas > datum > svátek. */
.portal-clock-nameday {
    margin-top: 4px;
    font-size: 13px;
    color: var(--text-faint);
    font-weight: 400;
    letter-spacing: 0.3px;
    text-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
    /* Inline-block aby slide animace fungovala (transform na inline el ne). */
    display: inline-block;
    min-height: 1.4em;
}
/* Rotace polozek pod hodinami (svatek/tyden/serie) - slide-out doleva
   + slide-in zprava. Stejny pattern jako splash modul. */
@keyframes portalClockNdSlideOut {
    0%   { transform: translateX(0);    opacity: 1; }
    100% { transform: translateX(-30px); opacity: 0; }
}
@keyframes portalClockNdSlideIn {
    0%   { transform: translateX(30px); opacity: 0; }
    100% { transform: translateX(0);    opacity: 1; }
}
.portal-clock-nameday.is-rotating-out {
    animation: portalClockNdSlideOut 0.28s cubic-bezier(0.4, 0, 0.85, 0.1) forwards;
}
.portal-clock-nameday.is-rotating-in {
    animation: portalClockNdSlideIn 0.38s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@media (max-width: 640px) {
    .portal-clock          { min-height: 120px; }
    .portal-clock-greeting { font-size: 16px; }
    .portal-clock-time     { font-size: 44px; }
    .portal-clock-date     { font-size: 14px; }
    .portal-clock-nameday  { font-size: 12px; }
}

/* karta aplikace - klikací <a> vyplňující celý sloupec */
.portal-card {
    --app-color: #6cb2f0;
    position: relative;             /* kotva pro .portal-card-grip a další overlay */
    display: flex;
    flex-direction: column;         /* krychle: ikona nahoře, název pod ní */
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 18px 12px;
    text-align: center;
    background: transparent;
    border: none;
    border-radius: 12px;
    color: var(--text);
    text-decoration: none;
    transition: transform 0.12s ease, background 0.12s ease;
    height: 100%;
    min-height: 116px;
}
.portal-card:hover {
    /* Bez velke plochy pozadi - hover feedback drzi jen stin pod ikonou
       (viz .portal-card:hover .portal-card-icon). */
    background: transparent;
    color: var(--text);
    text-decoration: none;
}
.portal-card:focus-visible {
    outline: 2px solid var(--app-color);
    outline-offset: 2px;
}

.portal-card-icon {
    position: relative;             /* kotva pro barevny spodni okraj (::after) */
    flex: 0 0 auto;
    width: 60px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Pozadi ikony = neutralni plocha dle motivu (svetly = bila, tmavy =
       tmava), barevnost drzi jen SVG (color: var(--app-color)). */
    background: var(--bg-elevated);
    /* Jemny obrys + barevny spodni okraj (border) v barve ikony. */
    border: 1px solid var(--border-soft);
    border-bottom: 3px solid var(--app-color);
    border-radius: 16px;
    color: var(--app-color);
    transition: transform 0.15s ease, box-shadow 0.15s ease, border-bottom-width 0.15s ease;
}
.portal-card-icon svg {
    width: 34px;
    height: 34px;
}
.portal-card:hover .portal-card-icon {
    /* Hover feedback: stin pod ctvercem pozadi ikony + silnejsi barevny okraj. */
    border-bottom-width: 4px;
    box-shadow: var(--shadow-card-hover);
}

.portal-card-body {
    flex: 1;
    min-width: 0;
}
.portal-card-name {
    margin: 0;
    font-size: 15px;
    font-weight: 500;
    line-height: 1.25;
    color: var(--text-strong);
}
.portal-card-desc {
    margin: 0;
    font-size: 13px;
    color: var(--text-muted);
    line-height: 1.4;
}
.portal-card-arrow {
    color: var(--app-color);
    font-size: 22px;
    opacity: 0.6;
    transition: transform 0.12s ease, opacity 0.12s ease;
}
.portal-card:hover .portal-card-arrow {
    opacity: 1;
    transform: translateX(3px);
}

/* ----- Drag & drop dlaždic na portál home (portal/index.php) -----
   .portal-card-grip = subtilní handle v rohu karty. Skrytý dokud
   uživatel nepřejede myší přes kartu (na touch zařízeních vidět vždy).
   SortableJS poslouchá MOUSEDOWN jen na tomto elementu (option `handle`),
   takže klik kdekoli jinde = navigace, klik+tah za grip = přesun. */
.portal-card-grip {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-faint);
    cursor: grab;
    opacity: 0;
    transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
    border-radius: 4px;
    /* Aby SortableJS dostal mousedown a ne <a>:
       1) pointer-events: auto (default);
       2) z-index nad ostatní obsah karty (rgba na ikoně apod.).
       <a> má zachycený click, ale tah-handle ho přebije přes preventDefault. */
    z-index: 2;
}
.portal-card:hover .portal-card-grip,
.portal-card-grip:focus-visible {
    opacity: 1;
}
.portal-card-grip:hover {
    color: var(--text-strong);
    background: rgba(255, 255, 255, 0.08);
}
.portal-card-grip:active {
    cursor: grabbing;
}
@media (hover: none) {
    /* Touch zařízení nemají hover - grip ukážeme vždy s mírnou
       průhledností, ať je vidět, že karta jde přesouvat. */
    .portal-card-grip { opacity: 0.45; }
}

/* Sortable stavy - vizuální feedback při tahání. */
.portal-grid-item--ghost .portal-card {
    /* Místo, kam karta spadne - polosvitné, zvýrazněný rámeček. */
    opacity: 0.4;
    border-style: dashed;
}
.portal-grid-item--chosen .portal-card {
    /* Karta právě uchopená myší - krátce před začátkem tahu. */
    box-shadow: var(--shadow-card-hover);
}
.portal-grid-item--drag .portal-card {
    /* "Letící" kopie karty pod kurzorem během tahu. */
    cursor: grabbing;
    transform: rotate(1deg);
}

/* Reset tlačítko a Odhlásit na portál home používají sdílené třídy
   .app-topbar-btn-icon + .app-topbar-svg z topbar sekce výš (round 32×32
   ikonová tlačítka). Žádné lokální styly tu už netřeba. */

/* ----- Login (login.php) ----------------------------------------- */
.login-body {
    background: var(--bg);
    color: var(--text);
    margin: 0;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Stack context pro tečkované pozadí (::before) - login.php sdílí
       totéž jako .portal-body. */
    position: relative;
    overflow-x: hidden;
}
.login-body .container {
    max-width: 420px;
    padding: 0 1rem;
}
.login-card {
    background: var(--bg-card);
    padding: 2rem;
    border-radius: 8px;
    box-shadow: var(--shadow-card);
    /* relative pro absolutně pozicovaný help button a popover v rohu */
    position: relative;
}
.login-card .form-label  { color: var(--text-light); }
.login-card .form-control {
    background: var(--bg-input);
    color: var(--text);
    border: 1px solid var(--border-input);
}
.login-card .form-control:focus {
    background: var(--bg-input);
    color: var(--text);
    border-color: var(--accent);
    box-shadow: 0 0 0 0.2rem var(--accent-focus-ring);
}
.login-card .form-control::placeholder { color: var(--text-subtle); }
.login-card h2              { color: var(--text-strong) !important; }
/* DELTA PORTAL brand mark - Poppins 700 uppercase s lehkým letter-spacing.
   Gradient text efekt (modrá → světlá modrá) zopakovává tón favicon.svg. */
.login-card .login-brand {
    font-family: 'Poppins', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-weight: 700;
    font-size: 28px;
    letter-spacing: 2.5px;
    margin-bottom: 28px !important;
    display: flex;
    align-items: baseline;
    gap: 10px;
    line-height: 1.1;
}
.login-card .login-brand-text {
    background: linear-gradient(180deg, #7ec8ff 0%, #0d6efd 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: #0d6efd;   /* fallback pokud background-clip:text nepodporuje (legacy) */
}
.login-card .login-brand .login-version {
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-weight: 400;
    letter-spacing: 0;
}
.login-card .login-subtitle { color: var(--text-light) !important; }
.login-card .login-hint     { color: var(--text-muted) !important; }
.login-card .text-muted     { color: var(--text-muted) !important; }

/* Help button (?) v pravém horním rohu login karty a popover s informací
   "kam se obrátit pro přístup nebo zapomenuté heslo". Slučuje předchozí
   dva texty (login-access-info pod formulářem + login-forgot-hint v error
   alertu) do jediného nenápadného prvku, který user otevře jen když ho
   skutečně potřebuje. */
.login-help-btn {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-light);
    border: 1px solid var(--border);
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
    z-index: 5;
}
.login-help-btn:hover,
.login-help-btn[aria-expanded="true"] {
    background: rgba(108, 182, 255, 0.18);
    color: #6cb6ff;
    border-color: #6cb6ff;
}
.login-help-popover {
    position: absolute;
    top: 46px;
    right: 12px;
    width: 320px;
    background: var(--bg-elevated, #1e1e1e);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 14px 16px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
    z-index: 10;
    font-size: 13px;
    color: var(--text-light);
    line-height: 1.5;
}
.login-help-section + .login-help-section {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}
.login-help-popover strong {
    color: var(--text-strong);
    display: block;
    margin-bottom: 4px;
    font-size: 13px;
}
.login-help-popover .login-help-desc {
    margin: 0 0 8px;
    font-size: 12.5px;
    color: var(--text-light);
}
.login-help-popover a {
    color: #6cb6ff;
    text-decoration: none;
}
.login-help-popover a:hover {
    text-decoration: underline;
}

/* Inline reset offer v alert-danger - tlačítko se objeví, když user
   zadal špatné heslo k existujícímu loginu s emailem. Šetří mu klik
   do help popoveru a překlepávání loginu znovu. */
.login-error-reset {
    margin-top: 10px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}
.login-error-reset .btn {
    font-size: 12px;
}
.login-error-reset-msg {
    font-size: 12px;
    line-height: 1.4;
    flex: 1 1 100%;
}
.login-error-reset-msg.is-pending { color: #ddd; opacity: 0.9; }
.login-error-reset-msg.is-ok      { color: #6fdc8c; }
.login-error-reset-msg.is-error   { color: #ffb3b3; }

/* Forgot-password inline form - login input + submit button */
.login-forgot-form {
    display: flex;
    gap: 6px;
    margin-top: 6px;
}
.login-forgot-form input.form-control {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 12.5px;
}
.login-forgot-form .btn {
    flex: 0 0 auto;
    white-space: nowrap;
    font-size: 12px;
}
.login-forgot-msg {
    margin-top: 8px;
    padding: 8px 10px;
    border-radius: 4px;
    font-size: 12px;
    line-height: 1.4;
}
.login-forgot-msg.is-pending {
    background: rgba(108, 182, 255, 0.10);
    color: #6cb6ff;
}
.login-forgot-msg.is-ok {
    background: rgba(46, 204, 113, 0.10);
    color: #6fdc8c;
}
.login-forgot-msg.is-error {
    background: rgba(220, 53, 69, 0.15);
    color: #ff8a96;
}
/* Drobná šipka směrem k tlačítku (vizuální propojení) */
.login-help-popover::before {
    content: '';
    position: absolute;
    top: -6px;
    right: 13px;
    width: 10px;
    height: 10px;
    background: var(--bg-elevated, #1e1e1e);
    border-top: 1px solid var(--border);
    border-left: 1px solid var(--border);
    transform: rotate(45deg);
}

/* Hodiny na login stránce - menší verze. Login viewport je úzký
   a hlavní karta sedí ve středu, takže 64px čas z hlavního portálu
   by působil ohromně. Stáhneme to do ~44/16/13/12 px hierarchie. */
.login-clock {
    margin: 24px 0 16px;
    /* Mensi font hierarchie nez hlavni portal -> nizsi steady-state vyska. */
    min-height: 120px;
}
.login-clock .portal-clock-greeting { font-size: 16px;  margin-bottom: 4px; }
.login-clock .portal-clock-time     { font-size: 44px;  }
.login-clock .portal-clock-date     { font-size: 13px;  margin-top: 4px; }
.login-clock .portal-clock-nameday  { font-size: 11px;  margin-top: 2px; }

/* Webkit autofill - drží sjednocené pozadí + barvu, ať to nepřebije
   prohlížeč. Ve světlém tématu by autofill žluté pozadí bylo přijatelné,
   ale chceme konzistenci -> override v obou tématech. */
.login-card .form-control:-webkit-autofill,
.login-card .form-control:-webkit-autofill:hover,
.login-card .form-control:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--text);
    -webkit-box-shadow: 0 0 0px 1000px var(--bg-input) inset;
    caret-color: var(--text);
    transition: background-color 9999s ease-out;
}

/* toggle "zobrazit heslo" */
.login-card .password-group .form-control { border-right: 0; }
.login-card .password-toggle {
    background: var(--bg-input);
    color: var(--text-muted);
    border: 1px solid var(--border-input);
    border-left: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 12px;
}
.login-card .password-toggle:hover { color: var(--text-strong); background: var(--bg-card-hover); }
.login-card .password-toggle:focus {
    box-shadow: 0 0 0 0.2rem var(--accent-focus-ring);
    outline: none;
    color: var(--text-strong);
}
.login-card .password-group .form-control:focus + .password-toggle {
    border-color: var(--accent);
}
.login-card .password-toggle .icon-eye-off       { display: none; }
.login-card .password-toggle.show .icon-eye      { display: none; }
.login-card .password-toggle.show .icon-eye-off  { display: inline-block; }

/* ====== Tipy pod modulovou mřížkou ======
   Minimalistický centred ticker s auto-rotací každých 10 s (viz
   js/portal-tips.js). Žádné kartičky, jen jeden řádek vystředěný
   horizontálně. Fade-in/out animace mezi tipy.
   Tipy se filtrují per userHasApp() v PHP - vidíš jen tipy modulů,
   ke kterým máš přístup. Zdroj: _config/tips.php.

   Layout: mezi modulovým gridem a sekcí "Oblíbené zakázky".
   Cíl - ticker vizuálně centrovaný, gap nad i pod ticker (do
   sousedního obsahu) STEJNÝ. Hodnoty (= 45 px gap na obě strany,
   border ~7 px od ticker):
     - margin-top:   26  ← gap modules → border tipy
     - padding-top:  18  ← border → ticker
     - padding-bot:  18  ← ticker → bottom of tipy box
     - margin-bot:    0  ← nestackovat s favorites override níž
     - favorites override: margin-top: 0, padding-top: 26 (border inherited)
       → 18 (tipy pad-bot) + 0 + 1 (favorites border) + 26 (favorites pad-top) = 45 ✓
   Vychází stejných 45 px nad i pod ticker. Border je v každém směru
   blíž k ticker (18 nahoru, 19 dolů) - vizuálně se ticker drží
   "uvnitř" sekce.
   Selektor `~` (general sibling) ne `+` (adjacent), protože mezi
   tipy a favorites v DOMu sedí <script> blok pro window.__tips. */
.portal-tips {
    margin-top: 26px;
    margin-bottom: 0;
    padding: 18px 0;
    border-top: 1px solid var(--border-soft);
    display: flex;
    justify-content: center;
}
/* Když je tipy POSLEDNÍ sekce (žádné favorites), doplň symetrický
   spodní margin - jinak by ticker visel těsně nad koncem mainu. */
.portal-tips:last-child {
    margin-bottom: 26px;
}
.portal-tip-ticker {
    display: flex;
    align-items: baseline;
    gap: 10px;
    max-width: 800px;
    text-align: center;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--text-muted);
    padding: 0 16px;
}
.portal-tip-label {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    font-size: 11px;
    opacity: 0.8;
}
.portal-tip-content {
    flex: 1 1 auto;
    color: var(--text);
    opacity: 0;
    transition: opacity 0.5s ease-in-out;  /* match s FADE_MS v portal-tips.js */
    /* Fixni vyska na 2 radky (line-height 1.5 -> 2 radky = 3em), aby pri
       rotaci jedno- vs dvouradkovych tipu stranka neposkakovala. Kratsi tip
       se zarovna k horni hrane, dvouradkovy box prave zaplni. */
    min-height: 3em;
}
.portal-tip-content.is-visible {
    opacity: 1;
}
.portal-tip-content strong {
    color: var(--text-strong);
    margin-right: 4px;
}
/* Chip se jménem modulu na začátku tipu - jasně sděluje, ke kterému
   modulu se tip váže. Drobně barevně oddělené pozadí, malý border.
   Záměrně decentní, ať to nepřebíjí samotný text tipu. */
.portal-tip-module {
    display: inline-block;
    padding: 1px 8px;
    margin-right: 8px;
    border-radius: 10px;
    background: rgba(13, 110, 253, 0.10);
    color: var(--accent, #4ea3ff);
    border: 1px solid rgba(13, 110, 253, 0.25);
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    line-height: 1.5;
    vertical-align: baseline;
    white-space: nowrap;
}
.portal-tip-link {
    font-size: 12px;
    color: var(--accent, #4ea3ff);
    text-decoration: none;
    margin-left: 6px;
    white-space: nowrap;
}
.portal-tip-link:hover {
    text-decoration: underline;
}

/* ===== Portal actions menu (cog dropdown na uvodni strane) =====
   3 sekce: Administrace / Informace / Nastaveni. Polozky = ikona vlevo +
   label vpravo. Pop position: pravy okraj zarovnan s tlacitkem (right: 0).
   Click handler je inline IIFE pod </main> v index.php. */
.portal-actions-wrap {
    position: relative;
    display: inline-flex;
    /* Vlastni stacking context, jinak by absolute popover sice byl nad
       svym sourozencem (logout), ale jine prvky stranky s vyssim z-index
       (napr. card hover, hodiny) by ho prebily. */
    z-index: 2000;
}
/* Chevron - rotace o 180° kdyz je menu otevrene, jako vizualni signal
   "expanded". Tlacitko dostane class .is-open z JS toggle handleru. */
.portal-actions-chevron {
    transition: transform 0.18s ease;
}
#portalActionsBtn.is-open .portal-actions-chevron {
    transform: rotate(180deg);
}
.portal-actions-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 240px;
    background: var(--bg-popover);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: var(--shadow-popover);
    padding: 6px;
    opacity: 0;
    transform: translateY(-4px);
    pointer-events: none;
    visibility: hidden;
    transition: opacity 0.14s ease, transform 0.14s ease, visibility 0s linear 0.14s;
    /* Vyssi nez vsechno na hlavni strance - hodiny (z-index neset = 0),
       grid cards (no z-index), tipy/favorites. 2000 = nad vsemi. */
    z-index: 2100;
}
.portal-actions-menu.open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
    visibility: visible;
    transition: opacity 0.14s ease, transform 0.14s ease, visibility 0s;
}
.portal-actions-section-label {
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-subtle);
    padding: 6px 10px 4px;
}
.portal-actions-section-label:not(:first-child) {
    margin-top: 4px;
}
.portal-actions-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    color: var(--text);
    background: transparent;
    border: none;
    border-radius: 5px;
    font-size: 13px;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    line-height: 1.3;
}
.portal-actions-item:hover,
.portal-actions-item:focus-visible {
    background: var(--hover-overlay);
    color: var(--text-strong);
    text-decoration: none;
    outline: none;
}
.portal-actions-item svg {
    flex-shrink: 0;
    opacity: 0.85;
}
.portal-actions-item:hover svg,
.portal-actions-item:focus-visible svg {
    opacity: 1;
}
.portal-actions-separator {
    height: 1px;
    background: var(--border-soft);
    margin: 6px 4px;
}
/* Theme btn v menu - sun/moon prepinani prebira existujici CSS
   (.app-theme-btn .app-theme-sun/moon v ~r.380), zobrazi se ta spravna
   podle data-theme. Sirka 16px je in-place primo v <svg width=...>. */

/* ----- Hodiny v light: odstranit tmavy text-shadow ----- */
/* Tmavy glow (rgba(0,0,0,0.55)) je delany pro tmave pozadi - tam vypada
   jako jemne halo. Na svetlem podkladu vytvari "neostry" efekt kolem
   cerneho textu. V light prepneme na zadny stin = ciste cerne pismo. */
[data-theme="light"] .portal-clock-greeting,
[data-theme="light"] .portal-clock-time,
[data-theme="light"] .portal-clock-date,
[data-theme="light"] .portal-clock-nameday {
    text-shadow: none;
}

/* ----- Animace teček na pozadí: světlejší v light režimu -----
   Default tecky pouzivaji slate-blue tony (rgba 70-130 lightness) navrhle
   pro tmave pozadi. Na bilem podkladu vypadaji jako tmave skvrny.
   Pro light prepneme conic-gradient na svetlejsi pastel modre + snizena
   alpha = jemna nenarocna texture pozadi. */
[data-theme="light"] body.portal-body::before,
[data-theme="light"] body.login-body::before {
    background: conic-gradient(
        from 180deg at 50% 70%,
        rgba(180, 195, 215, 0.55) 0deg,
        rgba(195, 210, 225, 0.62) 90deg,
        hsla(210, 38%, 78%, 0.85) 180deg,
        rgba(170, 188, 210, 0.58) 270deg,
        rgba(186, 200, 220, 0.55) 360deg
    );
}

/* ----- Hover karta modulu: jemny prechod bila -> modra ----- */
/* Gradient pres ::before pseudo-element, ne primo na .portal-card.
   Duvod: CSS neumi plynule transitionovat z background-color (plain)
   na background-image (gradient) - menily by se naraz a behem 0.12s
   transition by problikalo nic. Trik: pseudo s gradient + opacity 0
   default → opacity 1 hover. Opacity transition je smooth.
   Plati jen v light - dark zustava plain --bg-card-hover. */
[data-theme="light"] .portal-card {
    overflow: hidden;     /* pseudo s rounded corners */
}
[data-theme="light"] .portal-card::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, #ffffff 0%, #dbe7f8 100%);
    opacity: 0;
    transition: opacity 0.18s ease;
    pointer-events: none;
    z-index: 0;
    border-radius: inherit;
}
[data-theme="light"] .portal-card:hover::before {
    opacity: 0;   /* sjednocený app-tint hover místo modrého gradientu */
}
/* Detske elementy musi byt nad ::before vrstvou. */
[data-theme="light"] .portal-card > * {
    position: relative;
    z-index: 1;
}
/* Svetly motiv: zadna barevna plocha na hover, jen stin pod ikonou
   (sjednoceno s dark motivem). */
[data-theme="light"] .portal-card:hover {
    background: transparent;
}

/* =================================================================
 * Login HN ID / OIDC SSO - 'Prihlasit pres HN ID' tlacitko pod
 * standardnim login formem. Divider (vodorovna cara s 'nebo' v
 * stredu) ho oddeluje, ne aby splynul s primary submit buttonem.
 * Dle dvoufaktor.docx specifikace od X9 (2026-06-01).
 * ================================================================= */
.login-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 16px 0;
    color: var(--text-muted, #888);
    font-size: 13px;
}
.login-divider::before,
.login-divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--border-color, #444);
}
/* Light theme - vyssi kontrast cary */
[data-theme="light"] .login-divider {
    color: var(--text-faint, #888);
}
[data-theme="light"] .login-divider::before,
[data-theme="light"] .login-divider::after {
    background: var(--border, #ddd);
}
