/* =========================================================
   ALC_TimeKeeping (Lewke) — app.css
   Design system for the UI rebuild.

   Load order:  bootstrap 4.6.2 -> site.css -> app.css  [ -> crm.css on CRM pages ]

   RULES FOR THIS FILE
   1. Every class defined here is namespaced `app-` or `cx-`.
      Legacy names owned by site.css / crm.css (.chip, .pill, .tile, .kpi-*,
      .status-badge, .fb-*, .table-shell, .btn-soft, ...) are NEVER defined here.
   2. Colour lives ONLY in the two theme blocks below. Component rules must
      reference tokens, never a literal colour. A component that hardcodes a
      colour is broken in one of the two themes.
   3. Structural tokens (radii, spacing, sizes, timings) are declared once and
      are theme independent.
   4. Bootstrap stays at 4.6.2. Do not rely on BS5 utilities or data-bs-* here.
   ========================================================= */


/* =========================================================
   1. ROOT SCALE
   Chronexa's whole rem scale assumes 13px / 14px. Ported components
   render ~8-20% too large without this.

   Deliberately OPT-IN per page, not global. site.css uses a 14/16/17px
   root, so forcing 13/14px app-wide would shrink every not-yet-converted
   page by 12.5% on desktop and 23.5% on phones -- pages that already
   contain .55rem type. A converted page opts in with
       @{ ViewData["AppTypo"] = "on"; }
   which puts .app-typo on <html>. Shell geometry (sidebar width, topbar
   height, tap targets) is px, so the shell stays put either way.
   Remove the scoping and make this plain `html` once every page is converted.
   ========================================================= */

html.app-typo {
    font-size: 13px;
}

@media (min-width: 768px) {
    html.app-typo {
        font-size: 14px;
    }
}


/* =========================================================
   2. STRUCTURAL TOKENS  (theme independent)
   ========================================================= */

:root {
    /* Radii */
    /* Fonty Lewke (decyzja właściciela 2026-10-01) — ładowane w _Layout dla wszystkich. */
    --cx-font-display: "Jost Variable", "Jost", system-ui, -apple-system, "Segoe UI", sans-serif;
    --cx-font-text: "Figtree Variable", "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;

    --cx-radius-xl: 28px;
    --cx-radius-lg: 22px;
    --cx-radius-md: 16px;
    --cx-radius-sm: 12px;
    --cx-radius-pill: 999px;

    /* Shell geometry */
    --cx-sidebar-width: 260px;
    --cx-shell-gap: 0;
    --app-topbar-h: 64px;
    --app-drawer-width: min(88vw, 350px);

    /* Spacing rhythm */
    --app-gutter: 1.35rem;
    --app-gutter-sm: .6rem;
    --app-gap: 1rem;
    --app-gap-sm: .6rem;
    --app-gap-xs: .35rem;

    /* Controls / touch targets.
       Mobile clarity is a priority: nothing interactive should go under 44px. */
    --app-tap: 44px;
    --app-control-h: 44px;
    --app-control-h-lg: 52px;
    --app-icon-box: 34px;

    /* Type scale. Use these instead of inventing sizes like .55rem. */
    --app-fs-xs: .76rem;
    --app-fs-sm: .86rem;
    --app-fs-md: .95rem;
    --app-fs-lg: 1.08rem;
    --app-fs-xl: 1.45rem;
    --app-fs-2xl: clamp(1.7rem, 2.4vw, 2.4rem);
    --app-fs-display: clamp(2.1rem, 3vw, 3.2rem);

    /* Motion */
    --app-dur: .18s;
    --app-dur-slow: .24s;
    --app-ease: ease;

    /* Effects */
    --app-blur: 18px;

    /* Content canvas width */
    --app-content-max: 1180px;
    --app-content-max-wide: 1540px;

    /* Brand plate: deliberately identical in both themes so the white
       Lewke logo always sits on a dark ground and stays readable. */
    --cx-brand-plate: linear-gradient(180deg, #0b2038 0%, #061425 100%);
    --cx-brand-plate-border: rgba(125, 184, 255, .22);
    /* Tło okrągłego avatara klienta w bocznym menu. Stała marki, identyczna w obu
       motywach: logo Lewke to JPG z nieprzezroczystym BIAŁYM tłem, więc koło musi
       być białe także w motywie ciemnym, inaczej zostaje biały kwadrat w kole. */
    --cx-client-plate: #ffffff;
}

/* Tablet: a 260px rail eats too much of a 800-1100px viewport. */
@media (min-width: 768px) and (max-width: 1199.98px) {
    :root {
        --cx-sidebar-width: 216px;
        --app-gutter: 1rem;
    }
}


/* =========================================================
   3a. LIGHT THEME  (default)
   ========================================================= */

:root,
:root[data-theme="light"] {
    --cx-bg: #eef3fb;
    --cx-bg-2: #f6f9ff;
    --cx-bg-3: #ffffff;
    --cx-body-bg: radial-gradient(1200px 520px at 12% -6%, rgba(72, 124, 230, .14), transparent 60%), linear-gradient(180deg, #f6f9ff 0%, #eef3fb 46%, #e9eff8 100%);

    --cx-panel: rgba(255, 255, 255, .94);
    --cx-panel-2: #ffffff;
    --cx-panel-soft: rgba(19, 44, 86, .04);

    --cx-surface: linear-gradient(180deg, rgba(255, 255, 255, .97) 0%, rgba(250, 252, 255, .93) 100%);
    --cx-surface-raised: linear-gradient(180deg, rgba(255, 255, 255, .97) 0%, rgba(246, 250, 255, .92) 100%);
    --cx-sidebar-bg: linear-gradient(180deg, #ffffff 0%, #f5f8fe 100%);

    --cx-border: rgba(19, 44, 86, .11);
    --cx-border-strong: rgba(19, 44, 86, .18);
    --cx-border-dashed: rgba(19, 44, 86, .18);

    --cx-text: #0f1c2e;
    --cx-text-strong: #08101c;
    --cx-text-soft: rgba(15, 28, 46, .68);
    --cx-text-dim: rgba(15, 28, 46, .50);
    --cx-on-accent: #ffffff;

    --cx-blue: #2f6fe0;
    --cx-blue-2: #1c53bd;
    --cx-blue-soft: rgba(47, 111, 224, .10);
    --cx-blue-border: rgba(47, 111, 224, .24);
    --cx-accent-grad: linear-gradient(180deg, #3d7ded 0%, #2059c9 100%);

    --cx-hover: rgba(20, 44, 86, .05);
    --cx-hover-strong: rgba(20, 44, 86, .09);
    --cx-active-bg: linear-gradient(180deg, rgba(47, 111, 224, .13) 0%, rgba(47, 111, 224, .07) 100%);
    --cx-active-border: rgba(47, 111, 224, .24);

    --cx-inset: rgba(19, 44, 86, .035);
    --cx-inset-border: rgba(19, 44, 86, .09);

    --cx-shadow: 0 16px 40px rgba(18, 38, 74, .10);
    --cx-shadow-soft: 0 8px 22px rgba(18, 38, 74, .07);
    --cx-shadow-strong: 0 28px 70px rgba(18, 38, 74, .20);
    --cx-sidebar-shadow: 10px 0 30px rgba(18, 38, 74, .06);

    --cx-ring: rgba(47, 111, 224, .25);
    --cx-scrim: rgba(16, 28, 48, .42);
    --cx-danger-soft: rgba(173, 35, 56, .09);

    --cx-ring-hole: #ffffff;
    --app-track: rgba(19, 44, 86, .11);

    /* Zegar sesji + panel główny (sekcja 27) — light */
    --cx-clock-track: rgba(19, 44, 86, .08);
    --cx-clock-from: #2f6fe0;
    --cx-clock-to: #12b3c4;
    --cx-clock-core: radial-gradient(circle at 50% 0%, rgba(47, 111, 224, .10), transparent 46%), #ffffff;
    --cx-clock-core-border: rgba(19, 44, 86, .08);
    --cx-clock-shadow: 0 22px 56px rgba(18, 38, 74, .14), 0 0 0 1px rgba(47, 111, 224, .10);
    --cx-clock-halo: rgba(47, 111, 224, .22);
    --cx-clock-text-glow: 0 10px 26px rgba(47, 111, 224, .16);
    --cx-clock-hand: #ffffff;
    --cx-dot-work: #2f6fe0;
    --cx-dot-start: #0f9f9f;
    --cx-dot-project: #7c5ce0;
    --cx-dot-type: #c98a1e;
    --cx-dot-status: #6d4ad8;
    --cx-dot-note: #4b87d6;
    --cx-home-hero-bg: radial-gradient(circle at 80% 18%, rgba(47, 111, 224, .14), transparent 26%), linear-gradient(135deg, #ffffff 0%, #f3f7ff 58%, #e9f0fd 100%);
    --cx-home-hero-stripe: linear-gradient(130deg, transparent 0%, transparent 42%, rgba(47, 111, 224, .08) 42%, rgba(47, 111, 224, .02) 66%, transparent 66%);
    --cx-home-meta-bg: rgba(255, 255, 255, .72);
    --cx-home-portrait-bg: radial-gradient(circle at 50% 0%, rgba(255, 255, 255, .7), transparent 42%), linear-gradient(180deg, rgba(47, 111, 224, .22), rgba(47, 111, 224, .10));
    --cx-neon: rgba(214, 28, 186, .78);
    --cx-neon-glow: rgba(214, 28, 186, .22);

    /* Semantic — light */
    --app-success-fg: #15784a;
    --app-success-bd: rgba(21, 120, 74, .24);
    --app-success-bg: rgba(21, 120, 74, .08);
    --app-success-solid: #1f9d62;

    --app-warning-fg: #8a5406;
    --app-warning-bd: rgba(138, 84, 6, .24);
    --app-warning-bg: rgba(138, 84, 6, .08);
    --app-warning-solid: #c98a1e;

    --app-danger-fg: #ad2338;
    --app-danger-bd: rgba(173, 35, 56, .22);
    --app-danger-bg: rgba(173, 35, 56, .07);
    --app-danger-solid: #d34a5f;

    --app-info-fg: #15568f;
    --app-info-bd: rgba(21, 86, 143, .22);
    --app-info-bg: rgba(21, 86, 143, .07);
    --app-info-solid: #2f7cc4;

    /* Lewke — ekrany logowania (gość) + ekran startowy — light */
    --cx-gold: #c2a26a;
    --cx-gold-hover: #d3b67f;
    --cx-gold-ink: #0b1220;
    --cx-gold-text: #8a6a33;
    --cx-gold-soft: #f5efe3;
    --cx-gold-line: #e3d3b3;
    --cx-gold-ring: rgba(194, 162, 106, .28);
    --cx-auth-bg: #f2f3f5;
    --cx-auth-surface: #ffffff;
    --cx-auth-surface-2: #f6f7f9;
    --cx-auth-line: #e3e6eb;
    --cx-auth-line-2: #d5d9e0;
    --cx-auth-text: #0e1726;
    --cx-auth-soft: #4a5465;
    --cx-auth-dim: #677285;
    --cx-auth-ok: #1e8a5a;
    --cx-auth-ok-ink: #ffffff;

    /* Stałe marki — TAKIE SAME w obu motywach (blok ciemny ich nie nadpisuje):
       ciemny panel marki gościa i ekran startowy. */
    --cx-brand-ink: #070d18;
    --cx-brand-ink-2: #1a2436;
    --cx-brand-text: #f2f4f7;
    --cx-brand-soft: #a7b0be;
    --cx-brand-dim: #7d889a;
    --cx-brand-hover: #121c2e;
    --cx-brand-gold-line: rgba(194, 162, 106, .35);

    /* Lewke — Panel Główny + Przegląd Ewidencji Czasu (sekcja 33) — light */
    --cx-auth-surface-3: #edeff2;
    --cx-auth-ink: #0b1220;
    --cx-auth-ink-text: #f2f4f7;
    --cx-lw-clock-a: #8a6a33;
    --cx-lw-clock-b: #d9bf8c;
    --cx-lw-clock-track: #edeff2;
    --cx-lw-clock-halo: rgba(194, 162, 106, .30);
    --cx-lw-clock-shadow: 0 18px 44px rgba(14, 23, 38, .10);
    --cx-lw-hand: #ffffff;
    --cx-lw-dot-1: #c2a26a;
    --cx-lw-dot-2: #16706a;
    --cx-lw-dot-3: #5b4a9a;
    --cx-lw-dot-4: #2a5da8;
    --cx-lw-dot-5: #b9771c;
    --cx-lw-dot-6: #1e7a4f;
    --cx-lw-vio: #5b4a9a;
    --cx-lw-vio-soft: #eeeaf7;
    --cx-lw-teal: #16706a;
    --cx-lw-teal-soft: #e3f4f1;
    --cx-lw-rose: #9a3e6e;
    --cx-lw-rose-soft: #f8e8f0;
    --cx-lw-warn: #8a5a0b;
    --cx-lw-warn-soft: #fbf0dc;
    --cx-lw-warn-line: #ebd3a6;
    --cx-lw-ok: #1e7a4f;
    --cx-lw-ok-soft: #e5f4ec;
    --cx-lw-ok-solid: #1e7a4f;
    --cx-lw-ok-ink: #ffffff;
    --cx-lw-bad: #b03a2e;
    --cx-lw-bad-soft: #fce9e1;
    --cx-lw-bad-line: #f1c4bd;
    --cx-lw-bad-solid: #c0392b;
    --cx-lw-bad-ink: #ffffff;
    --cx-lw-info: #2a5da8;
    --cx-lw-info-soft: #e8f1fb;
    --cx-lw-shadow-pop: 0 2px 8px rgba(14, 23, 38, .10);
    --cx-chart-1: #c2a26a;
    --cx-chart-2: #2a5da8;
    --cx-chart-3: #16706a;
    --cx-chart-4: #5b4a9a;
    --cx-chart-5: #b9771c;
    --cx-chart-6: #9a3e6e;
}


/* =========================================================
   3b. DARK THEME  (Chronexa palette, real values)
   ========================================================= */

:root[data-theme="dark"] {
    --cx-bg: #020916;
    --cx-bg-2: #041325;
    --cx-bg-3: #061d36;
    --cx-body-bg: radial-gradient(1200px 520px at 14% -6%, rgba(43, 126, 245, .20), transparent 60%), linear-gradient(180deg, #041a31 0%, #020b16 46%, #020812 100%);

    --cx-panel: rgba(12, 27, 45, .88);
    --cx-panel-2: rgba(17, 36, 58, .96);
    --cx-panel-soft: rgba(255, 255, 255, .05);

    --cx-surface: linear-gradient(180deg, rgba(13, 33, 53, .84) 0%, rgba(8, 22, 37, .92) 100%);
    --cx-surface-raised: radial-gradient(circle at 0% 0%, rgba(43, 126, 245, .20), transparent 36%), linear-gradient(180deg, rgba(4, 15, 28, .96) 0%, rgba(6, 24, 43, .90) 100%);
    --cx-sidebar-bg: radial-gradient(circle at 0% 0%, rgba(38, 111, 219, .22), transparent 28%), linear-gradient(180deg, rgba(4, 18, 34, .96) 0%, rgba(3, 14, 27, .98) 100%);

    --cx-border: rgba(255, 255, 255, .08);
    --cx-border-strong: rgba(125, 184, 255, .16);
    --cx-border-dashed: rgba(255, 255, 255, .14);

    --cx-text: #f4f7fb;
    --cx-text-strong: #ffffff;
    --cx-text-soft: rgba(244, 247, 251, .72);
    --cx-text-dim: rgba(244, 247, 251, .55);
    --cx-on-accent: #ffffff;

    --cx-blue: #62aaff;
    --cx-blue-2: #2f7df5;
    --cx-blue-soft: rgba(98, 170, 255, .14);
    --cx-blue-border: rgba(125, 184, 255, .22);
    --cx-accent-grad: linear-gradient(180deg, #5da7ff 0%, #2c7cf4 100%);

    --cx-hover: rgba(255, 255, 255, .06);
    --cx-hover-strong: rgba(255, 255, 255, .10);
    --cx-active-bg: linear-gradient(180deg, rgba(63, 133, 228, .22) 0%, rgba(33, 82, 148, .22) 100%);
    --cx-active-border: rgba(125, 184, 255, .20);

    --cx-inset: rgba(255, 255, 255, .04);
    --cx-inset-border: rgba(255, 255, 255, .07);

    --cx-shadow: 0 16px 44px rgba(0, 0, 0, .26);
    --cx-shadow-soft: 0 8px 24px rgba(0, 0, 0, .20);
    --cx-shadow-strong: 0 28px 80px rgba(0, 0, 0, .48);
    --cx-sidebar-shadow: 18px 0 44px rgba(0, 0, 0, .20);

    --cx-ring: rgba(98, 170, 255, .28);
    --cx-scrim: rgba(2, 7, 18, .64);
    --cx-danger-soft: rgba(255, 137, 137, .12);

    --cx-ring-hole: #071627;
    --app-track: rgba(255, 255, 255, .08);

    /* Zegar sesji + panel główny (sekcja 27) — dark (wartości Chronexy) */
    --cx-clock-track: rgba(255, 255, 255, .08);
    --cx-clock-from: #2f7df5;
    --cx-clock-to: #38e8db;
    --cx-clock-core: radial-gradient(circle at 50% 0%, rgba(98, 170, 255, .13), transparent 45%), rgba(4, 16, 31, .96);
    --cx-clock-core-border: rgba(255, 255, 255, .08);
    --cx-clock-shadow: 0 26px 70px rgba(0, 0, 0, .32), 0 0 0 1px rgba(125, 184, 255, .16);
    --cx-clock-halo: rgba(56, 232, 219, .20);
    --cx-clock-text-glow: 0 14px 38px rgba(63, 134, 255, .26);
    --cx-clock-hand: #ffffff;
    --cx-dot-work: #54a7ff;
    --cx-dot-start: #38e8db;
    --cx-dot-project: #a78bfa;
    --cx-dot-type: #ffd14f;
    --cx-dot-status: #8b5cf6;
    --cx-dot-note: #7db8ff;
    --cx-home-hero-bg: radial-gradient(circle at 80% 20%, rgba(71, 140, 255, .22), transparent 24%), linear-gradient(135deg, rgba(11, 41, 77, .95) 0%, rgba(7, 28, 55, .98) 55%, rgba(5, 18, 34, .98) 100%);
    --cx-home-hero-stripe: linear-gradient(130deg, transparent 0%, transparent 42%, rgba(48, 111, 214, .17) 42%, rgba(48, 111, 214, .04) 66%, transparent 66%);
    --cx-home-meta-bg: rgba(2, 12, 26, .28);
    --cx-home-portrait-bg: radial-gradient(circle at 50% 0%, rgba(255, 255, 255, .20), transparent 40%), linear-gradient(180deg, rgba(65, 154, 255, .38), rgba(15, 67, 131, .35));
    --cx-neon: rgba(227, 21, 197, .92);
    --cx-neon-glow: rgba(227, 21, 197, .28);

    /* Semantic — dark (values Chronexa repeats literally) */
    --app-success-fg: #97e6b4;
    --app-success-bd: rgba(98, 196, 132, .22);
    --app-success-bg: rgba(98, 196, 132, .08);
    --app-success-solid: #3fbf78;

    --app-warning-fg: #ffd48b;
    --app-warning-bd: rgba(231, 178, 92, .22);
    --app-warning-bg: rgba(231, 178, 92, .08);
    --app-warning-solid: #e7b25c;

    --app-danger-fg: #ffb8c3;
    --app-danger-bd: rgba(227, 103, 120, .22);
    --app-danger-bg: rgba(227, 103, 120, .08);
    --app-danger-solid: #e36778;

    --app-info-fg: #9fd4ff;
    --app-info-bd: rgba(92, 166, 231, .22);
    --app-info-bg: rgba(92, 166, 231, .08);
    --app-info-solid: #5ca6e7;

    /* Lewke — ekrany logowania (gość) — dark. --cx-brand-* są wspólne (blok light). */
    --cx-gold-text: #d9bf8c;
    --cx-gold-soft: #2a2418;
    --cx-gold-line: #4a3d24;
    --cx-gold-ring: rgba(194, 162, 106, .30);
    --cx-auth-bg: #070d18;
    --cx-auth-surface: #0e1726;
    --cx-auth-surface-2: #121c2e;
    --cx-auth-line: #1e2a3e;
    --cx-auth-line-2: #2a3850;
    --cx-auth-text: #f2f4f7;
    --cx-auth-soft: #b3bcc9;
    --cx-auth-dim: #8c98ab;
    --cx-auth-ok: #3dd68c;
    --cx-auth-ok-ink: #0b1220;

    /* Lewke — Panel Główny + Przegląd Ewidencji Czasu (sekcja 33) — dark */
    --cx-auth-surface-3: #18233a;
    --cx-auth-ink: #111c2e;
    --cx-auth-ink-text: #f2f4f7;
    --cx-lw-clock-a: #a8854a;
    --cx-lw-clock-b: #ead6a9;
    --cx-lw-clock-track: #18233a;
    --cx-lw-clock-halo: rgba(194, 162, 106, .32);
    --cx-lw-clock-shadow: 0 18px 44px rgba(0, 0, 0, .42);
    --cx-lw-hand: #ffffff;
    --cx-lw-dot-1: #c2a26a;
    --cx-lw-dot-2: #5ccfc2;
    --cx-lw-dot-3: #b3a4ee;
    --cx-lw-dot-4: #7fb0f5;
    --cx-lw-dot-5: #e6b45a;
    --cx-lw-dot-6: #4cc38a;
    --cx-lw-vio: #b3a4ee;
    --cx-lw-vio-soft: #1d1830;
    --cx-lw-teal: #5ccfc2;
    --cx-lw-teal-soft: #0c2322;
    --cx-lw-rose: #f0a3c8;
    --cx-lw-rose-soft: #2a1424;
    --cx-lw-warn: #e6b45a;
    --cx-lw-warn-soft: #2a2112;
    --cx-lw-warn-line: #5a4318;
    --cx-lw-ok: #4cc38a;
    --cx-lw-ok-soft: #0d2019;
    --cx-lw-ok-solid: #3dd68c;
    --cx-lw-ok-ink: #0b1220;
    --cx-lw-bad: #f07a6e;
    --cx-lw-bad-soft: #2a1414;
    --cx-lw-bad-line: #5a2620;
    --cx-lw-bad-solid: #f07a6e;
    --cx-lw-bad-ink: #0b1220;
    --cx-lw-info: #7fb0f5;
    --cx-lw-info-soft: #0f1e36;
    --cx-lw-shadow-pop: 0 2px 8px rgba(0, 0, 0, .40);
    --cx-chart-1: #c2a26a;
    --cx-chart-2: #7fb0f5;
    --cx-chart-3: #5ccfc2;
    --cx-chart-4: #b3a4ee;
    --cx-chart-5: #e6b45a;
    --cx-chart-6: #f0a3c8;
}


/* =========================================================
   4. BASE
   Krój: od 2026-10-01 (decyzja właściciela) Figtree dla tekstu i Jost dla nagłówków,
   tokeny --cx-font-* w sekcji 2, pliki ładuje _Layout (Fontsource przez jsDelivr, SRI).
   Ustawienie font-family na body jest w sekcji 32.
   ========================================================= */

body {
    min-height: 100vh;
    margin: 0;
    color: var(--cx-text);
    background: var(--cx-body-bg);
    background-attachment: fixed;
    -webkit-tap-highlight-color: transparent;
}

/* BEZ z-index na <main> i .app-shell. Z-index tworzy tu osobny kontekst warstw,
   a okna modalne Bootstrapa są w środku <main>, podczas gdy jego szare tło
   (.modal-backdrop, z-index 1040) jest doklejane na końcu <body>. Tło lądowało
   wtedy NAD modalem: wszystko szare i nic nie dało się kliknąć. */
main {
    position: relative;
}

a {
    color: var(--cx-blue);
}

a:hover,
a:focus {
    color: var(--cx-blue-2);
}

hr {
    border-top-color: var(--cx-border);
}

.app-muted {
    color: var(--cx-text-soft);
}

.app-dim {
    color: var(--cx-text-dim);
}

.app-eyebrow {
    display: block;
    color: var(--cx-text-dim);
    font-size: var(--app-fs-xs);
    font-weight: 800;
    letter-spacing: .05em;
    text-transform: uppercase;
    line-height: 1.1;
}

/* Screen-reader-only text (Polish labels for icon-only controls). */
.app-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}


/* =========================================================
   5. GLOBAL CONTROLS  (layered on Bootstrap 4.6.2)
   ========================================================= */

.btn {
    border-radius: var(--cx-radius-md);
    font-weight: 700;
    transition: transform var(--app-dur) var(--app-ease), box-shadow var(--app-dur) var(--app-ease), background var(--app-dur) var(--app-ease), border-color var(--app-dur) var(--app-ease), color var(--app-dur) var(--app-ease);
}

    .btn:hover {
        transform: translateY(-1px);
    }

    .btn:focus,
    .btn.focus,
    .btn:active:focus,
    .btn-link.nav-link:focus,
    .form-control:focus,
    .form-check-input:focus {
        box-shadow: 0 0 0 .2rem var(--cx-ring);
    }

.btn-primary,
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active,
.btn-primary:not(:disabled):not(.disabled):active,
.btn-primary:not(:disabled):not(.disabled).active {
    color: var(--cx-on-accent);
    border-color: var(--cx-blue-border);
    background: var(--cx-accent-grad);
}

    .btn-primary:focus,
    .btn-primary.focus {
        box-shadow: 0 0 0 .2rem var(--cx-ring);
    }

.btn-outline-primary {
    color: var(--cx-blue);
    border-color: var(--cx-blue-border);
    background: var(--cx-blue-soft);
}

    .btn-outline-primary:hover,
    .btn-outline-primary:not(:disabled):not(.disabled):active {
        color: var(--cx-on-accent);
        border-color: var(--cx-blue-border);
        background: var(--cx-accent-grad);
    }

/* Button modifiers for converted pages. */
.app-btn-pill {
    border-radius: var(--cx-radius-pill);
    padding-left: 1.1rem;
    padding-right: 1.1rem;
}

.app-btn-lg {
    min-height: var(--app-control-h-lg);
    border-radius: var(--cx-radius-md);
    font-weight: 800;
}

.app-btn-ghost {
    color: var(--cx-text);
    border: 1px solid var(--cx-border);
    background: var(--cx-hover);
}

    .app-btn-ghost:hover,
    .app-btn-ghost:focus {
        color: var(--cx-text-strong);
        border-color: var(--cx-border-strong);
        background: var(--cx-hover-strong);
    }

/* Square icon-only button that always clears the 44px tap target. */
.app-btn-icon {
    width: var(--app-tap);
    height: var(--app-tap);
    min-width: var(--app-tap);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-sm);
    background: var(--cx-hover);
    color: var(--cx-text);
    text-decoration: none !important;
    cursor: pointer;
}

    .app-btn-icon:hover,
    .app-btn-icon:focus {
        color: var(--cx-text-strong);
        border-color: var(--cx-border-strong);
        background: var(--cx-hover-strong);
    }

    .app-btn-icon i {
        font-size: 1rem;
        line-height: 1;
        color: currentColor;
    }

/* Semantic tones for a destructive / confirming icon action. Deliberately
   no :hover pairing — .app-btn-icon:hover is more specific and takes the
   button back to the neutral hover, which is the behaviour these pages
   already have. A page that wants the tone held on hover declares its own
   .app-btn-icon--danger:hover (see Users/Index). */
.app-btn-icon--danger {
    border-color: var(--app-danger-bd);
    background: var(--app-danger-bg);
    color: var(--app-danger-fg);
}

.app-btn-icon--success {
    border-color: var(--app-success-bd);
    background: var(--app-success-bg);
    color: var(--app-success-fg);
}

/* Button row that stacks full-width on phones. */
.app-btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--app-gap-sm);
    align-items: center;
}

@media (max-width: 575.98px) {
    .app-btn-row {
        flex-direction: column;
        align-items: stretch;
    }

        .app-btn-row > .btn,
        .app-btn-row > .app-btn-icon {
            width: 100%;
        }
}


/* =========================================================
   6. FORM VOCABULARY
   ========================================================= */

.app-field {
    display: block;
    min-width: 0;
}

    .app-field + .app-field {
        margin-top: var(--app-gap-sm);
    }

.app-label {
    display: block;
    margin-bottom: .45rem;
    color: var(--cx-text);
    font-size: var(--app-fs-sm);
    font-weight: 700;
}

.app-input,
.app-field .form-control {
    min-height: var(--app-control-h);
    border-radius: var(--cx-radius-md);
    border: 1px solid var(--cx-inset-border);
    background: var(--cx-inset);
    color: var(--cx-text);
    box-shadow: none;
}

    .app-input:focus,
    .app-field .form-control:focus {
        border-color: var(--cx-blue-border);
        background: var(--cx-panel-soft);
        box-shadow: 0 0 0 4px var(--cx-ring);
        color: var(--cx-text);
    }

    .app-input::placeholder,
    .app-field .form-control::placeholder {
        color: var(--cx-text-dim);
    }

.app-input--lg {
    min-height: var(--app-control-h-lg);
}

textarea.app-input {
    min-height: 120px;
    resize: vertical;
}

.app-help {
    display: block;
    margin-top: .38rem;
    color: var(--cx-text-soft);
    font-size: var(--app-fs-sm);
    line-height: 1.45;
}

.app-error {
    display: block;
    margin-top: .35rem;
    color: var(--app-danger-fg);
    font-size: var(--app-fs-sm);
    font-weight: 700;
}

.app-check {
    display: flex;
    align-items: center;
    gap: .65rem;
    min-height: var(--app-tap);
    color: var(--cx-text-soft);
    font-size: var(--app-fs-md);
}

    .app-check input[type="checkbox"],
    .app-check input[type="radio"] {
        width: 1.05rem;
        height: 1.05rem;
        accent-color: var(--cx-blue);
    }

.app-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--app-gap);
}

.app-actions {
    display: grid;
    gap: var(--app-gap-sm);
    margin-top: 1.2rem;
}

    .app-actions .btn {
        min-height: var(--app-control-h-lg);
        font-weight: 800;
    }


/* =========================================================
   7. APP SHELL — sidebar / topbar / content
   ========================================================= */

.app-shell {
    display: grid;
    grid-template-columns: var(--cx-sidebar-width) minmax(0, 1fr);
    column-gap: var(--cx-shell-gap);
    min-height: 100vh;
    width: 100%;
    position: relative;
    /* Bez z-index — patrz komentarz przy regule main (okna modalne). */
}

.app-sidebar {
    position: sticky;
    top: 0;
    height: 100vh;
    min-width: 0;
}

.app-sidebar__inner {
    height: 100%;
    display: flex;
    flex-direction: column;
    padding: 1.15rem 1rem;
    border-right: 1px solid var(--cx-border);
    background: var(--cx-sidebar-bg);
    box-shadow: var(--cx-sidebar-shadow);
    backdrop-filter: blur(var(--app-blur));
    overflow-y: auto;
    overscroll-behavior: contain;
}

.app-sidebar__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding-bottom: .7rem;
    margin-bottom: .25rem;
    border-bottom: 1px solid var(--cx-border);
}

/* The Lewke logo asset is a wide wordmark (1007x221), so the brand block is a
   landscape plate, not a square avatar. The plate stays dark in both themes so
   the white wordmark always reads. */
.app-brand {
    display: grid;
    gap: .4rem;
    flex: 1 1 auto;
    min-width: 0;
    color: var(--cx-text) !important;
    text-decoration: none !important;
}

    .app-brand:hover {
        color: var(--cx-text-strong) !important;
    }

.app-brand__mark {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 46px;
    padding: 9px 14px;
    border-radius: 14px;
    border: 1px solid var(--cx-brand-plate-border);
    background: var(--cx-brand-plate);
}

    .app-brand__mark img {
        display: block;
        width: auto;
        height: auto;
        max-width: 100%;
        max-height: 100%;
    }

.app-brand__text {
    min-width: 0;
    display: grid;
    gap: .05rem;
    text-align: center;
}

    .app-brand__text strong {
        display: block;
        font-size: var(--app-fs-md);
        line-height: 1.15;
        font-weight: 800;
        letter-spacing: -.02em;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .app-brand__text small {
        display: block;
        color: var(--cx-text-dim);
        font-size: var(--app-fs-xs);
        font-weight: 700;
        letter-spacing: .06em;
        text-transform: uppercase;
    }

/* Drawer close button — mobile only. */
.app-sidebar__close {
    display: none;
}

.app-sidebar__section {
    margin-top: 1.05rem;
    padding: 0 .2rem .35rem;
    color: var(--cx-text-dim);
    font-size: var(--app-fs-xs);
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.app-sidebar__actions {
    display: grid;
    gap: var(--app-gap-sm);
    margin-top: auto;
    padding-top: .9rem;
    border-top: 1px solid var(--cx-border);
}

    .app-sidebar__actions .btn,
    .app-sidebar__actions .app-sidebar__action {
        width: 100%;
        justify-content: center;
    }

.app-sidebar__action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-height: var(--app-tap);
    padding: .55rem .9rem;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-sm);
    background: var(--cx-hover);
    color: var(--cx-text) !important;
    text-decoration: none !important;
    font-weight: 700;
    font-size: var(--app-fs-sm);
    cursor: pointer;
    transition: background var(--app-dur) var(--app-ease), border-color var(--app-dur) var(--app-ease), transform var(--app-dur) var(--app-ease);
}

    .app-sidebar__action:hover,
    .app-sidebar__action:focus {
        background: var(--cx-hover-strong);
        border-color: var(--cx-border-strong);
        color: var(--cx-text-strong) !important;
    }

    .app-sidebar__action i {
        line-height: 1;
        color: currentColor;
    }

.app-sidebar__action--accent {
    color: var(--cx-on-accent) !important;
    border-color: var(--cx-blue-border);
    background: var(--cx-accent-grad);
}

    .app-sidebar__action--accent:hover,
    .app-sidebar__action--accent:focus {
        color: var(--cx-on-accent) !important;
        background: var(--cx-accent-grad);
        filter: brightness(1.06);
    }


/* --- Navigation ------------------------------------------------ */

.app-nav {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    margin-top: .75rem;
}

.app-nav__link {
    display: flex;
    align-items: center;
    gap: .7rem;
    min-height: var(--app-tap);
    padding: .55rem .7rem;
    border: 1px solid transparent;
    border-radius: var(--cx-radius-md);
    color: var(--cx-text-soft);
    text-decoration: none !important;
    transition: background var(--app-dur) var(--app-ease), border-color var(--app-dur) var(--app-ease), color var(--app-dur) var(--app-ease);
}

    .app-nav__link:hover,
    .app-nav__link:focus {
        color: var(--cx-text-strong);
        background: var(--cx-hover);
        border-color: var(--cx-border);
    }

    .app-nav__link.active {
        color: var(--cx-text-strong);
        background: var(--cx-active-bg);
        border-color: var(--cx-active-border);
        box-shadow: var(--cx-shadow-soft);
    }

.app-nav__icon {
    width: var(--app-icon-box);
    height: var(--app-icon-box);
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 11px;
    border: 1px solid var(--cx-border);
    background: var(--cx-hover);
}

    .app-nav__icon i {
        font-size: .92rem;
        line-height: 1;
        color: currentColor;
    }

.app-nav__link.active .app-nav__icon {
    border-color: var(--cx-active-border);
    background: var(--cx-blue-soft);
    color: var(--cx-blue);
}

.app-nav__label {
    min-width: 0;
    flex: 1 1 auto;
    font-weight: 700;
    line-height: 1.15;
    font-size: var(--app-fs-md);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-nav__badge {
    flex-shrink: 0;
    min-width: 1.4rem;
    height: 1.4rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 .35rem;
    border-radius: var(--cx-radius-pill);
    background: var(--app-danger-solid);
    color: #fff;
    font-size: var(--app-fs-xs);
    font-weight: 800;
}


/* --- Main column / topbar --------------------------------------- */

.app-main {
    min-width: 0;
    display: flex;
    flex-direction: column;
    padding: 1.05rem var(--app-gutter) 1.15rem;
}

.app-topbar {
    display: flex;
    align-items: center;
    gap: .75rem;
    min-height: var(--app-topbar-h);
    padding: .15rem 0 1rem;
}

.app-topbar__menu {
    display: none;
}

.app-topbar__left {
    min-width: 0;
    flex: 1 1 auto;
}

.app-topbar__title {
    margin: .2rem 0 0;
    color: var(--cx-text-strong);
    font-size: var(--app-fs-xl);
    line-height: 1.1;
    letter-spacing: -.03em;
    font-weight: 800;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-topbar__right {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: .42rem;
    flex: 0 0 auto;
}

/* Icon action in the topbar. Same box as .app-btn-icon so the row is even. */
.app-topbar__icon {
    width: var(--app-tap);
    height: var(--app-tap);
    min-width: var(--app-tap);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-sm);
    background: var(--cx-hover);
    color: var(--cx-text) !important;
    text-decoration: none !important;
    cursor: pointer;
    transition: background var(--app-dur) var(--app-ease), border-color var(--app-dur) var(--app-ease);
}

    .app-topbar__icon:hover,
    .app-topbar__icon:focus {
        color: var(--cx-text-strong) !important;
        background: var(--cx-hover-strong);
        border-color: var(--cx-border-strong);
    }

    .app-topbar__icon i {
        font-size: 1.02rem;
        line-height: 1;
        color: currentColor;
    }

/* site.css adds a mobile-only padding to #messageIcon for the old navbar. */
.app-topbar #messageIcon {
    padding-right: 0;
}

/* Hamburger. */
.app-topbar__menu span {
    width: 17px;
    height: 2px;
    display: block;
    border-radius: var(--cx-radius-pill);
    background: currentColor;
}

/* Theme toggle: show the icon of the theme you would switch TO. */
.app-theme-toggle .app-theme-toggle__to-dark {
    display: inline-block;
}

.app-theme-toggle .app-theme-toggle__to-light {
    display: none;
}

:root[data-theme="dark"] .app-theme-toggle .app-theme-toggle__to-dark {
    display: none;
}

:root[data-theme="dark"] .app-theme-toggle .app-theme-toggle__to-light {
    display: inline-block;
}


/* --- Content canvas --------------------------------------------- */

.app-content {
    min-width: 0;
    flex: 1 0 auto;
    padding-top: 0;
    padding-bottom: 1rem;
}

/* Bootstrap's .container max-widths are viewport-based and overflow once a
   260px rail is subtracted. Cap to the available width. crm.css still wins
   with its own `main.container { max-width:100% !important }`. */
.app-content.container {
    width: 100%;
    max-width: min(100%, var(--app-content-max));
}

.app-content--wide {
    width: 100%;
    max-width: min(100%, var(--app-content-max-wide));
    margin-left: auto;
    margin-right: auto;
}


/* --- Footer ------------------------------------------------------ */

.app-footer {
    flex-shrink: 0;
    margin-top: var(--app-gap);
    padding: .9rem 0 .2rem;
    border-top: 1px solid var(--cx-border);
    color: var(--cx-text-dim);
    font-size: var(--app-fs-xs);
    line-height: 1.6;
    text-align: center;
}

    .app-footer a {
        color: inherit;
        text-decoration: underline;
        text-underline-offset: 3px;
    }

        .app-footer a:hover {
            color: var(--cx-text);
            text-decoration: none;
        }

.app-footer__sep {
    margin: 0 .35rem;
    opacity: .7;
}


/* =========================================================
   8. MOBILE SHELL + OFF-CANVAS DRAWER  (< 768px)
   ========================================================= */

.app-backdrop {
    display: none;
}

@media (max-width: 767.98px) {
    html,
    body {
        overflow-x: hidden;
    }

    body.app-menu-open {
        overflow: hidden;
    }

    .app-shell {
        display: block;
        min-height: 100vh;
        padding: max(.55rem, env(safe-area-inset-top)) var(--app-gutter-sm) calc(1rem + env(safe-area-inset-bottom));
    }

    /* Sidebar becomes a right-side drawer. */
    .app-sidebar {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: auto;
        z-index: 1060;
        width: var(--app-drawer-width);
        height: 100dvh;
        padding: max(.75rem, env(safe-area-inset-top)) .75rem calc(.75rem + env(safe-area-inset-bottom));
        transform: translateX(112%);
        /* visibility keeps the closed drawer out of the tab order and out of
           the accessibility tree, while still letting it animate out. */
        visibility: hidden;
        transition: transform var(--app-dur-slow) var(--app-ease), visibility 0s linear var(--app-dur-slow);
    }

    body.app-menu-open .app-sidebar {
        transform: translateX(0);
        visibility: visible;
        transition: transform var(--app-dur-slow) var(--app-ease), visibility 0s;
    }

    .app-sidebar__inner {
        border: 1px solid var(--cx-border-strong);
        border-radius: var(--cx-radius-xl) 0 0 var(--cx-radius-xl);
        box-shadow: var(--cx-shadow-strong);
        -webkit-overflow-scrolling: touch;
    }

    .app-sidebar__close {
        display: inline-flex;
    }

    .app-backdrop {
        position: fixed;
        inset: 0;
        z-index: 1050;
        display: block;
        pointer-events: none;
        opacity: 0;
        background: var(--cx-scrim);
        backdrop-filter: blur(10px);
        transition: opacity .2s var(--app-ease);
    }

    body.app-menu-open .app-backdrop {
        pointer-events: auto;
        opacity: 1;
    }

    /* Topbar becomes the sticky mobile header card. */
    .app-topbar {
        position: sticky;
        top: max(.35rem, env(safe-area-inset-top));
        z-index: 1040;
        min-height: var(--app-topbar-h);
        gap: .45rem;
        padding: .5rem;
        border: 1px solid var(--cx-border);
        border-radius: var(--cx-radius-lg);
        background: var(--cx-surface-raised);
        box-shadow: var(--cx-shadow-soft);
        backdrop-filter: blur(var(--app-blur));
    }

    .app-topbar__menu {
        display: inline-flex;
        flex-direction: column;
        gap: 4px;
        order: 3;
    }

    .app-topbar__left {
        order: 1;
    }

    .app-topbar__title {
        font-size: var(--app-fs-lg);
        font-weight: 900;
        letter-spacing: -.035em;
    }

    .app-topbar__right {
        order: 2;
        gap: .32rem;
    }

    .app-main {
        padding: .7rem 0 0;
    }

    .app-content.container,
    .app-content.container-fluid {
        padding-left: .5rem;
        padding-right: .5rem;
    }

    .app-nav {
        gap: .4rem;
        margin-top: .8rem;
    }

    .app-nav__link {
        min-height: 52px;
        border-radius: var(--cx-radius-md);
        padding: .6rem .7rem;
    }

    .app-nav__icon {
        width: 38px;
        height: 38px;
        border-radius: 13px;
    }

    .app-nav__label {
        font-size: 1rem;
    }
}

@media (max-width: 390px) {
    :root {
        --app-drawer-width: min(91vw, 340px);
        --app-tap: 42px;
    }

    .app-shell {
        padding-left: .5rem;
        padding-right: .5rem;
    }

    .app-topbar {
        padding: .45rem;
    }
}

/* Desktop: drawer-only affordances stay hidden.
   This must live here, after .app-topbar__icon, because the hamburger also
   carries that class and would otherwise win on display. */
@media (min-width: 768px) {
    .app-topbar__menu {
        display: none;
    }
}


/* =========================================================
   9. CARDS / PANELS / HERO
   ========================================================= */

.app-card {
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-lg);
    background: var(--cx-surface);
    box-shadow: var(--cx-shadow);
    backdrop-filter: blur(var(--app-blur));
    overflow: hidden;
}

.app-card--pad {
    padding: 1.15rem;
}

.app-card--flat {
    box-shadow: none;
    background: var(--cx-panel-soft);
}

.app-card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: 1.05rem 1.15rem;
    border-bottom: 1px solid var(--cx-border);
}

.app-card--pad > .app-card__header {
    padding: 0 0 .85rem;
}

.app-card__title {
    margin: 0;
    color: var(--cx-text-strong);
    font-size: var(--app-fs-lg);
    font-weight: 800;
    letter-spacing: -.03em;
}

.app-card__text {
    margin: 0;
    color: var(--cx-text-soft);
    font-size: var(--app-fs-md);
    line-height: 1.55;
}

.app-card__body {
    padding: 1.15rem;
}

.app-card__footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--app-gap-sm);
    padding: .9rem 1.15rem 1.1rem;
    border-top: 1px solid var(--cx-border);
}

/* Hero panel — the big page-opening block. */
.app-hero {
    position: relative;
    padding: 1.3rem;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-lg);
    background: var(--cx-surface);
    box-shadow: var(--cx-shadow);
    overflow: hidden;
}

    .app-hero::after {
        content: "";
        position: absolute;
        inset: 0;
        pointer-events: none;
        background: radial-gradient(circle at 88% 6%, var(--cx-blue-soft), transparent 26%);
    }

.app-hero > * {
    position: relative;
    z-index: 1;
}

.app-hero__title {
    margin: .7rem 0 .35rem;
    color: var(--cx-text-strong);
    font-size: var(--app-fs-2xl);
    line-height: 1.02;
    letter-spacing: -.05em;
    font-weight: 800;
}

.app-hero__subtitle {
    margin: 0;
    color: var(--cx-text-soft);
    font-size: var(--app-fs-md);
    line-height: 1.5;
}

.app-hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--app-gap-sm);
    margin-top: var(--app-gap);
}

/* Generic section + toolbar rhythm. */
.app-section {
    display: grid;
    gap: var(--app-gap);
}

.app-section + .app-section {
    margin-top: var(--app-gap);
}

.app-section__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--app-gap-sm);
}

.app-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--app-gap-sm);
}

/* Layout helpers. */
.app-stack {
    display: grid;
    gap: var(--app-gap);
}

.app-stack--sm {
    gap: var(--app-gap-sm);
}

.app-grid-auto {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--app-gap);
}

.app-grid-2 {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--app-gap);
}

.app-grid-3 {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--app-gap);
}

@media (max-width: 991.98px) {
    .app-grid-3 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 575.98px) {
    .app-grid-2,
    .app-grid-3 {
        grid-template-columns: 1fr;
    }
}


/* =========================================================
   10. KPI TILES
   ========================================================= */

.app-kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
    gap: var(--app-gap);
}

.app-kpi {
    position: relative;
    display: grid;
    gap: .2rem;
    align-content: center;
    min-height: 118px;
    padding: 1rem 1.1rem;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-lg);
    background: var(--cx-surface);
    box-shadow: var(--cx-shadow-soft);
    overflow: hidden;
}

.app-kpi__label {
    color: var(--cx-text-soft);
    font-size: var(--app-fs-sm);
    font-weight: 700;
}

.app-kpi__value {
    color: var(--cx-text-strong);
    font-size: clamp(1.7rem, 2.6vw, 2.6rem);
    line-height: .98;
    letter-spacing: -.05em;
    font-weight: 900;
}

.app-kpi__meta {
    color: var(--cx-text-dim);
    font-size: var(--app-fs-xs);
    font-weight: 700;
}

.app-kpi__icon {
    position: absolute;
    top: .85rem;
    right: .95rem;
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 11px;
    border: 1px solid var(--cx-border);
    background: var(--cx-hover);
    color: var(--cx-text-soft);
}

    .app-kpi__icon i {
        font-size: .9rem;
        line-height: 1;
        color: currentColor;
    }

.app-kpi--success {
    border-color: var(--app-success-bd);
    background: var(--app-success-bg);
}

.app-kpi--warning {
    border-color: var(--app-warning-bd);
    background: var(--app-warning-bg);
}

.app-kpi--danger {
    border-color: var(--app-danger-bd);
    background: var(--app-danger-bg);
}

.app-kpi--info {
    border-color: var(--app-info-bd);
    background: var(--app-info-bg);
}


/* =========================================================
   11. CHIPS / BADGES / STATUS
   ========================================================= */

.app-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.app-chip {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-height: 34px;
    padding: .4rem .8rem;
    border-radius: var(--cx-radius-pill);
    border: 1px solid var(--cx-border);
    background: var(--cx-hover);
    color: var(--cx-text);
    font-weight: 700;
    font-size: var(--app-fs-sm);
    line-height: 1.2;
    white-space: nowrap;
}

.app-chip--accent {
    color: var(--cx-blue);
    border-color: var(--cx-blue-border);
    background: var(--cx-blue-soft);
}

/* Status chip with the coloured leading dot (Chronexa's signature). */
.cx-status-chip {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    min-height: 34px;
    padding: .35rem .8rem;
    border-radius: var(--cx-radius-pill);
    border: 1px solid var(--cx-border);
    background: var(--cx-hover);
    color: var(--cx-text);
    font-size: var(--app-fs-sm);
    font-weight: 700;
    white-space: nowrap;
}

    .cx-status-chip::before {
        content: "";
        flex-shrink: 0;
        width: .5rem;
        height: .5rem;
        border-radius: var(--cx-radius-pill);
        background: currentColor;
        opacity: .9;
        box-shadow: 0 0 0 4px var(--cx-panel-soft);
    }

.cx-status-chip--success {
    color: var(--app-success-fg);
    border-color: var(--app-success-bd);
    background: var(--app-success-bg);
}

.cx-status-chip--warning {
    color: var(--app-warning-fg);
    border-color: var(--app-warning-bd);
    background: var(--app-warning-bg);
}

.cx-status-chip--danger {
    color: var(--app-danger-fg);
    border-color: var(--app-danger-bd);
    background: var(--app-danger-bg);
}

.cx-status-chip--info {
    color: var(--app-info-fg);
    border-color: var(--app-info-bd);
    background: var(--app-info-bg);
}

/* Compact badge — for inline table/row tagging. */
.app-badge {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-height: 26px;
    padding: .18rem .6rem;
    border-radius: var(--cx-radius-pill);
    border: 1px solid var(--cx-border);
    background: var(--cx-hover);
    color: var(--cx-text-soft);
    font-size: var(--app-fs-xs);
    font-weight: 800;
    white-space: nowrap;
}

.app-badge--success {
    color: var(--app-success-fg);
    border-color: var(--app-success-bd);
    background: var(--app-success-bg);
}

.app-badge--warning {
    color: var(--app-warning-fg);
    border-color: var(--app-warning-bd);
    background: var(--app-warning-bg);
}

.app-badge--danger {
    color: var(--app-danger-fg);
    border-color: var(--app-danger-bd);
    background: var(--app-danger-bg);
}

.app-badge--info {
    color: var(--app-info-fg);
    border-color: var(--app-info-bd);
    background: var(--app-info-bg);
}

/* Standalone status dot. */
.app-dot {
    display: inline-block;
    width: .55rem;
    height: .55rem;
    border-radius: var(--cx-radius-pill);
    background: var(--cx-text-dim);
}

.app-dot--success {
    background: var(--app-success-solid);
    box-shadow: 0 0 0 4px var(--app-success-bg);
}

.app-dot--warning {
    background: var(--app-warning-solid);
    box-shadow: 0 0 0 4px var(--app-warning-bg);
}

.app-dot--danger {
    background: var(--app-danger-solid);
    box-shadow: 0 0 0 4px var(--app-danger-bg);
}

.app-dot--info {
    background: var(--app-info-solid);
    box-shadow: 0 0 0 4px var(--app-info-bg);
}


/* =========================================================
   12. KEY/VALUE ROWS
   ========================================================= */

.app-kv-list {
    display: grid;
    gap: .5rem;
}

.app-kv-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .9rem;
    min-height: 44px;
    padding: .6rem .8rem;
    border: 1px solid var(--cx-inset-border);
    border-radius: 14px;
    background: var(--cx-inset);
}

    .app-kv-row > span {
        min-width: 0;
        color: var(--cx-text-soft);
        font-size: var(--app-fs-sm);
    }

    .app-kv-row > strong {
        text-align: right;
        color: var(--cx-text-strong);
        font-weight: 800;
    }


/* =========================================================
   13. TABS  (pill capsule)
   ========================================================= */

.app-tabs {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    width: fit-content;
    max-width: 100%;
    margin: 0;
    padding: .3rem;
    list-style: none;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-pill);
    background: var(--cx-hover);
    overflow-x: auto;
}

    .app-tabs.nav {
        border-bottom: 0;
        flex-wrap: nowrap;
    }

.app-tab-item {
    margin: 0;
}

.app-tab-link,
.app-tabs.nav .app-tab-link.nav-link {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-height: 40px;
    margin: 0;
    padding: .55rem 1rem;
    border: 0 !important;
    border-radius: var(--cx-radius-pill);
    color: var(--cx-text-soft) !important;
    background: transparent !important;
    text-decoration: none !important;
    font-weight: 800;
    font-size: var(--app-fs-sm);
    white-space: nowrap;
    transition: background var(--app-dur) var(--app-ease), color var(--app-dur) var(--app-ease);
}

    .app-tab-link:hover,
    .app-tab-link:focus,
    .app-tabs.nav .app-tab-link.nav-link:hover,
    .app-tabs.nav .app-tab-link.nav-link:focus {
        color: var(--cx-text-strong) !important;
        background: var(--cx-hover-strong) !important;
    }

    .app-tab-link.active,
    .app-tabs.nav .app-tab-link.nav-link.active {
        color: var(--cx-on-accent) !important;
        background: var(--cx-accent-grad) !important;
        border: 0 !important;
    }


/* =========================================================
   14. TABLES
   Desktop: spaced, rounded rows.
   Mobile (< 768px): card mode driven by td[data-label].
   Use `<div class="app-table-wrap"><table class="app-table">` — do NOT also
   add Bootstrap's `.table`, the legacy runtime wrapper script targets that.
   ========================================================= */

.app-table-wrap {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.app-table {
    width: 100%;
    margin: 0;
    border-collapse: separate;
    border-spacing: 0 .5rem;
    color: var(--cx-text);
    font-size: var(--app-fs-sm);
}

    .app-table thead th {
        padding: .4rem .8rem;
        border: 0;
        color: var(--cx-text-soft);
        font-size: var(--app-fs-xs);
        font-weight: 800;
        text-transform: uppercase;
        letter-spacing: .04em;
        white-space: nowrap;
    }

    .app-table tbody tr {
        background: var(--cx-inset);
    }

        .app-table tbody tr:hover {
            background: var(--cx-hover-strong);
        }

    .app-table tbody td {
        padding: .8rem;
        border-top: 1px solid var(--cx-inset-border);
        border-bottom: 1px solid var(--cx-inset-border);
        color: var(--cx-text);
        vertical-align: middle;
    }

        .app-table tbody td:first-child {
            border-left: 1px solid var(--cx-inset-border);
            border-radius: var(--cx-radius-md) 0 0 var(--cx-radius-md);
        }

        .app-table tbody td:last-child {
            border-right: 1px solid var(--cx-inset-border);
            border-radius: 0 var(--cx-radius-md) var(--cx-radius-md) 0;
        }

.app-table__num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 767.98px) {
    .app-table-wrap {
        overflow-x: visible;
    }

    .app-table thead {
        display: none;
    }

    .app-table,
    .app-table tbody,
    .app-table tr,
    .app-table td {
        display: block;
        width: 100%;
    }

    .app-table {
        border-spacing: 0;
    }

        .app-table tbody tr {
            display: grid;
            gap: .4rem;
            padding: .85rem;
            margin-bottom: .75rem;
            border: 1px solid var(--cx-inset-border);
            border-radius: var(--cx-radius-md);
            background: var(--cx-inset);
        }

        .app-table tbody td {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 1rem;
            padding: .2rem 0;
            border: 0;
            font-size: var(--app-fs-md);
        }

            .app-table tbody td::before {
                content: attr(data-label);
                flex-shrink: 0;
                color: var(--cx-text-soft);
                font-size: var(--app-fs-sm);
                font-weight: 700;
            }

            .app-table tbody td:first-child,
            .app-table tbody td:last-child {
                border: 0;
                border-radius: 0;
            }

    .app-table__num {
        text-align: left;
    }
}


/* =========================================================
   15. FLASH MESSAGES / NOTICES / EMPTY STATE
   ========================================================= */

.cx-flash-stack {
    display: grid;
    gap: .8rem;
    margin-bottom: var(--app-gap);
}

.cx-flash {
    display: flex;
    align-items: flex-start;
    gap: .85rem;
    padding: .9rem 1rem;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-md);
    background: var(--cx-surface);
    box-shadow: var(--cx-shadow-soft);
}

.cx-flash-icon {
    width: 2rem;
    height: 2rem;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-top: .05rem;
    border-radius: var(--cx-radius-pill);
    border: 1px solid currentColor;
    color: var(--cx-text-soft);
    font-weight: 900;
    font-size: .92rem;
}

.cx-flash-content strong {
    display: block;
    margin: 0 0 .15rem;
    color: var(--cx-text-strong);
    font-size: var(--app-fs-md);
    font-weight: 800;
}

.cx-flash-content p {
    margin: 0;
    color: var(--cx-text-soft);
    font-size: var(--app-fs-md);
    line-height: 1.55;
}

.cx-flash--success {
    border-color: var(--app-success-bd);
    background: var(--app-success-bg);
}

    .cx-flash--success .cx-flash-icon {
        color: var(--app-success-fg);
    }

.cx-flash--warning {
    border-color: var(--app-warning-bd);
    background: var(--app-warning-bg);
}

    .cx-flash--warning .cx-flash-icon {
        color: var(--app-warning-fg);
    }

.cx-flash--error,
.cx-flash--danger {
    border-color: var(--app-danger-bd);
    background: var(--app-danger-bg);
}

    .cx-flash--error .cx-flash-icon,
    .cx-flash--danger .cx-flash-icon {
        color: var(--app-danger-fg);
    }

.cx-flash--info {
    border-color: var(--app-info-bd);
    background: var(--app-info-bg);
}

    .cx-flash--info .cx-flash-icon {
        color: var(--app-info-fg);
    }

/* Quieter inline note. */
.app-note {
    padding: .8rem 1rem;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-md);
    background: var(--cx-panel-soft);
    color: var(--cx-text-soft);
    font-size: var(--app-fs-md);
    line-height: 1.5;
}

.app-note--danger {
    border-color: var(--app-danger-bd);
    background: var(--app-danger-bg);
    color: var(--app-danger-fg);
}

.app-note--warning {
    border-color: var(--app-warning-bd);
    background: var(--app-warning-bg);
    color: var(--app-warning-fg);
}

.app-note--info {
    border-color: var(--app-info-bd);
    background: var(--app-info-bg);
    color: var(--app-info-fg);
}

/* Bootstrap alerts inside the new shell. */
.alert {
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-md);
    box-shadow: var(--cx-shadow-soft);
}

.app-empty {
    display: grid;
    justify-items: center;
    align-content: center;
    min-height: 220px;
    padding: 1.25rem;
    border: 1px dashed var(--cx-border-dashed);
    border-radius: var(--cx-radius-lg);
    background: var(--cx-panel-soft);
    text-align: center;
}

.app-empty__icon {
    width: 52px;
    height: 52px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: .8rem;
    border: 1px solid var(--cx-blue-border);
    border-radius: 18px;
    background: var(--cx-blue-soft);
    color: var(--cx-blue);
    font-size: 1.2rem;
}

    .app-empty__icon i {
        line-height: 1;
        color: currentColor;
    }

.app-empty strong {
    color: var(--cx-text-strong);
    font-size: var(--app-fs-lg);
    font-weight: 800;
}

.app-empty p {
    max-width: 40ch;
    margin: .35rem 0 0;
    color: var(--cx-text-soft);
    line-height: 1.55;
}


/* =========================================================
   16. MODAL RESKIN  (Bootstrap 4.6.2 markup — data-toggle/data-dismiss)
   Put .app-modal on .modal and .app-modal-content on .modal-content.
   ========================================================= */

.app-modal-content {
    border: 1px solid var(--cx-border-strong);
    border-radius: var(--cx-radius-lg);
    background: var(--cx-surface);
    color: var(--cx-text);
    box-shadow: var(--cx-shadow-strong);
    overflow: hidden;
}

.app-modal-header,
.app-modal-footer {
    border-color: var(--cx-border);
}

.app-modal-header {
    align-items: flex-start;
    padding: 1.05rem 1.15rem;
}

    .app-modal-header h5,
    .app-modal-header .modal-title {
        margin: 0;
        color: var(--cx-text-strong);
        font-size: var(--app-fs-lg);
        font-weight: 800;
        letter-spacing: -.03em;
    }

    .app-modal-header p {
        margin: .25rem 0 0;
        color: var(--cx-text-soft);
        font-size: var(--app-fs-sm);
    }

.app-modal-body {
    padding: 1.15rem;
}

.app-modal-footer {
    gap: var(--app-gap-sm);
    padding: .9rem 1.15rem 1.15rem;
}

.app-modal-close,
.app-modal-close:hover {
    color: var(--cx-text);
    opacity: .85;
    text-shadow: none;
}

@media (max-width: 575.98px) {
    .app-modal-footer {
        flex-direction: column-reverse;
        align-items: stretch;
    }

        .app-modal-footer .btn {
            width: 100%;
            margin: 0;
        }
}


/* =========================================================
   17. TOGGLE SWITCH
   Uses `~` (not `+`): hidden inputs can sit between the checkbox and the UI.
   ========================================================= */

.cx-switch-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: .65rem;
    min-height: var(--app-tap);
    padding: .55rem .7rem;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-md);
    background: var(--cx-inset);
    cursor: pointer;
    user-select: none;
    transition: border-color var(--app-dur) var(--app-ease), background var(--app-dur) var(--app-ease);
}

    .cx-switch-card:hover {
        border-color: var(--cx-border-strong);
        background: var(--cx-hover-strong);
    }

.cx-switch-input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.cx-switch-ui {
    position: relative;
    width: 48px;
    height: 26px;
    flex-shrink: 0;
    border-radius: var(--cx-radius-pill);
    border: 1px solid var(--cx-border-strong);
    background: var(--app-track);
    transition: background var(--app-dur) var(--app-ease), box-shadow var(--app-dur) var(--app-ease);
}

    .cx-switch-ui::before {
        content: "";
        position: absolute;
        top: 2px;
        left: 2px;
        width: 20px;
        height: 20px;
        border-radius: var(--cx-radius-pill);
        background: var(--cx-panel-2);
        box-shadow: var(--cx-shadow-soft);
        transition: transform .22s var(--app-ease);
    }

.cx-switch-input:checked ~ .cx-switch-ui {
    border-color: var(--cx-blue-border);
    background: var(--cx-accent-grad);
}

    .cx-switch-input:checked ~ .cx-switch-ui::before {
        transform: translateX(22px);
    }

.cx-switch-input:focus ~ .cx-switch-ui {
    box-shadow: 0 0 0 4px var(--cx-ring);
}

.cx-switch-copy {
    min-width: 0;
    display: grid;
    gap: .1rem;
}

    .cx-switch-copy strong {
        display: block;
        color: var(--cx-text-strong);
        font-size: var(--app-fs-sm);
        line-height: 1.25;
        font-weight: 800;
    }

    .cx-switch-copy span {
        color: var(--cx-text-soft);
        font-size: var(--app-fs-sm);
        line-height: 1.4;
    }


/* =========================================================
   18. PROGRESS RING  (pure CSS conic-gradient, no chart library)
   Usage: <div class="app-ring" style="--cx-ring-fill:62%"><div>…</div></div>
   ========================================================= */

.app-ring {
    --cx-ring-fill: 0%;
    --app-ring-size: 132px;
    width: var(--app-ring-size);
    height: var(--app-ring-size);
    display: grid;
    place-items: center;
    border-radius: var(--cx-radius-pill);
    background: radial-gradient(circle, var(--cx-ring-hole) 0 53%, transparent 54%), conic-gradient(var(--cx-blue) var(--cx-ring-fill), var(--cx-blue-2) var(--cx-ring-fill) calc(var(--cx-ring-fill) + 12%), var(--app-track) 0);
}

.app-ring--lg {
    --app-ring-size: min(320px, 78vw);
}

.app-ring__inner {
    width: 66%;
    height: 66%;
    display: grid;
    place-items: center;
    align-content: center;
    text-align: center;
    border-radius: var(--cx-radius-pill);
    border: 1px solid var(--cx-border);
    background: var(--cx-ring-hole);
}

    .app-ring__inner span {
        display: block;
        color: var(--cx-text-soft);
        font-size: var(--app-fs-xs);
        font-weight: 800;
        text-transform: uppercase;
        letter-spacing: .06em;
    }

    .app-ring__inner strong {
        display: block;
        margin-top: .3rem;
        color: var(--cx-text-strong);
        font-size: clamp(1.4rem, 5vw, 2.6rem);
        line-height: .95;
        letter-spacing: -.05em;
        font-weight: 900;
        font-variant-numeric: tabular-nums;
    }

.app-ring-layout {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: var(--app-gap);
}

@media (max-width: 575.98px) {
    .app-ring-layout {
        grid-template-columns: 1fr;
        justify-items: center;
        text-align: center;
    }
}


/* =========================================================
   19. FONT AWESOME 6.5.0 INTEGRATION
   Icons stay Font Awesome (client decision). These rules only make FA
   glyphs size and align predictably inside the new components.
   ========================================================= */

.app-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.25em;
    height: 1.25em;
    line-height: 1;
    color: currentColor;
    vertical-align: -.12em;
}

.app-card__title i,
.app-chip i,
.app-badge i,
.cx-status-chip i,
.app-tab-link i,
.app-sidebar__action i,
.app-nav__icon i,
.app-topbar__icon i {
    color: currentColor;
    line-height: 1;
}


/* =========================================================
   19b. PAGINATION
   Bootstrap 4's .pagination / .page-link has no dark-theme pairing of its
   own, so every paged list page used to carry its own copy of these rules.
   Two shared skins live here; both are applied ON TOP of Bootstrap's
   markup (ul.pagination > li.page-item > a.page-link), which is left alone.

   .app-pager          — the full skin: 44px tap targets, bold labels and a
                         token-driven idle/hover/active/disabled palette.
   .app-pager--wrap    — let the bar wrap instead of overflowing at 375px.
   .app-pager--flush   — no gap between wrapped rows.
   .app-pager-compact  — colour only, for pages that keep Bootstrap's own
                         .pagination-sm metrics and hover behaviour.
   .app-pagesize       — the "entries per page" btn-group next to a pager.
   ========================================================= */

.app-pager {
    --app-pager-row-gap: .35rem;
}

.app-pager--wrap {
    flex-wrap: wrap;
    row-gap: var(--app-pager-row-gap);
}

.app-pager--flush {
    --app-pager-row-gap: 0;
}

.app-pager .page-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--app-tap);
    min-height: var(--app-tap);
    border-color: var(--cx-border);
    background: var(--cx-panel-soft);
    color: var(--cx-text);
    font-weight: 700;
}

    .app-pager .page-link:hover,
    .app-pager .page-link:focus {
        border-color: var(--cx-border-strong);
        background: var(--cx-hover-strong);
        color: var(--cx-text-strong);
    }

.app-pager .page-item.active .page-link {
    border-color: var(--cx-blue-border);
    background: var(--cx-accent-grad);
    color: var(--cx-on-accent);
}

.app-pager .page-item.disabled .page-link {
    border-color: var(--cx-border);
    background: var(--cx-inset);
    color: var(--cx-text-dim);
}

/* Colour-only variant. Deliberately does NOT set metrics, font weight or a
   hover pairing, so Bootstrap's own .pagination-sm sizing and hover stay
   exactly as they are on the pages that use it. */
.app-pager-compact .page-link {
    border-color: var(--cx-border);
    background: var(--cx-surface);
    color: var(--cx-text);
}

.app-pager-compact .page-item.disabled .page-link {
    background: var(--cx-panel-soft);
    color: var(--cx-text-dim);
}

.app-pager-compact .page-item.active .page-link {
    border-color: var(--cx-blue-border);
    background: var(--cx-accent-grad);
    color: var(--cx-on-accent);
}

.app-pagesize .btn {
    min-height: var(--app-tap);
}


/* =========================================================
   19c. CHAT / MESSAGE LOG
   Shared by Messages/Chat, Messages/Department and Messages/Monitor.
   NOTE: Chat and Department also build this markup client-side (their
   appendMessage()/append() helpers), so these class names appear in the JS
   of those two pages as well — rename here and you must rename there.

   The scroll box only carries the look; each page sets its own height via
   the three custom properties, because the 1:1 chat, the department channel
   and the read-only monitor pane are deliberately different heights.
   ========================================================= */

.app-chatlog {
    display: grid;
    align-content: start;
    gap: var(--app-chatlog-gap, .5rem);
    height: var(--app-chatlog-h, auto);
    min-height: var(--app-chatlog-min, 240px);
    max-height: var(--app-chatlog-max, 60vh);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 1rem;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-lg);
    background: var(--cx-surface);
    box-shadow: var(--cx-shadow);
}

/* Centred day divider (department channel). */
.app-chat-day {
    justify-self: center;
    padding: .3rem .9rem;
    border-radius: var(--cx-radius-pill);
    background: var(--cx-panel-soft);
    color: var(--cx-text-dim);
    font-size: var(--app-fs-xs);
    font-weight: 700;
    text-transform: capitalize;
}

.app-chat-row {
    display: flex;
}

.app-chat-row--in {
    justify-content: flex-start;
}

.app-chat-row--out {
    justify-content: flex-end;
}

.app-chat-bubble {
    max-width: 78%;
    padding: .65rem .9rem;
    border: 1px solid var(--cx-inset-border);
    border-radius: var(--cx-radius-md);
    background: var(--cx-inset);
}

.app-chat-row--out .app-chat-bubble {
    border-color: var(--cx-blue-border);
    background: var(--cx-blue-soft);
}

.app-chat-name {
    margin-bottom: .15rem;
    color: var(--cx-text-strong);
    font-size: var(--app-fs-sm);
    font-weight: 800;
}

.app-chat-text {
    color: var(--cx-text);
    font-size: var(--app-fs-md);
    line-height: 1.45;
    white-space: pre-wrap;
    word-break: break-word;
}

.app-chat-meta {
    margin-top: .3rem;
    color: var(--cx-text-dim);
    font-size: var(--app-fs-xs);
    font-weight: 700;
    text-align: right;
}


/* =========================================================
   19d. PAGE HEAD
   The identity row that opens a page inside .app-hero: a framed square
   logo, a copy column (eyebrow + title + chips) and, underneath, a
   horizontally scrollable tab strip.

   Its title is deliberately smaller and tighter than .app-hero__title —
   these pages put a section title under a logo, not a display headline.
   ========================================================= */

.app-pagehead {
    display: flex;
    align-items: center;
    gap: var(--app-gap);
    flex-wrap: wrap;
}

.app-pagehead__logo {
    width: 76px;
    height: 76px;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 7px;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-md);
    background: var(--cx-panel-soft);
    overflow: hidden;
}

    .app-pagehead__logo img {
        max-width: 100%;
        max-height: 100%;
        object-fit: contain;
    }

.app-pagehead__copy {
    min-width: 0;
    flex: 1 1 240px;
}

.app-pagehead__title {
    margin: .15rem 0 .5rem;
    color: var(--cx-text-strong);
    font-size: var(--app-fs-xl);
    line-height: 1.1;
    letter-spacing: -.03em;
    font-weight: 800;
}

/* Scroll container for .app-tabs so a long strip never widens the page. */
.app-tabs-wrap {
    margin-top: var(--app-gap);
    max-width: 100%;
    overflow-x: auto;
}


/* =========================================================
   19e. SPLIT LAYOUT  (narrow rail + wide main column)
   One grid, two stacked-card columns, collapsing to a single column
   below 992px. The rail sticks on desktop.

   Column ORDER is a property of the page, not of the component: the list
   pages put the filter rail first, the detail/creation pages put the main
   column first. Use --main-first for the latter and keep the DOM order the
   same as the visual order (no grid reordering, so tab order stays right).
   ========================================================= */

.app-split {
    display: grid;
    grid-template-columns: var(--app-split-cols, minmax(0, 300px) minmax(0, 1fr));
    gap: var(--app-gap);
    align-items: start;
}

.app-split--main-first {
    --app-split-cols: minmax(0, 1fr) minmax(0, 300px);
}

.app-split__rail,
.app-split__main {
    display: grid;
    gap: var(--app-gap);
    min-width: 0;
    align-content: var(--app-split-align, normal);
}

/* Pack the columns to the top instead of letting auto rows stretch. */
.app-split--align-start {
    --app-split-align: start;
}

@media (min-width: 992px) {
    .app-split__rail {
        position: sticky;
        top: 1rem;
    }
}

@media (max-width: 991.98px) {
    .app-split {
        grid-template-columns: 1fr;
    }
}


/* =========================================================
   19f. SEMANTIC TEXT COLOUR
   One-property utilities for inline marks (arrows, warning glyphs, a
   destructive icon button). Single-class specificity on purpose, so they
   override inherited colour but never fight a component's own rule — a
   cell that must be recoloured needs the component to say so, not these.
   ========================================================= */

.app-text-success {
    color: var(--app-success-fg);
}

.app-text-warning {
    color: var(--app-warning-fg);
}

.app-text-danger {
    color: var(--app-danger-fg);
}

.app-text-info {
    color: var(--app-info-fg);
}


/* =========================================================
   19g. INPUT GROUP SKIN
   Token skin for Bootstrap's input-group addon, so an icon prefix or a
   unit suffix reads as one control with the .app-input next to it.
   Put .app-input-group on the .input-group itself and add the side
   modifier that matches the markup.

   In the dark theme the addon's colour comes from the legacy-compat block
   in section 20, which is more specific — that is existing behaviour and
   is left alone here.
   ========================================================= */

.app-input-group .input-group-text {
    min-height: var(--app-control-h);
    border: 1px solid var(--cx-inset-border);
    background: var(--cx-inset);
    color: var(--cx-text-soft);
}

/* Addon before the field (.input-group-prepend). */
.app-input-group--prepend .input-group-text {
    border-right: 0;
    border-radius: var(--cx-radius-md) 0 0 var(--cx-radius-md);
}

.input-group.app-input-group--prepend > .app-input {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

/* Addon after the field (.input-group-append). */
.app-input-group--append .input-group-text {
    border-left: 0;
    border-radius: 0 var(--cx-radius-md) var(--cx-radius-md) 0;
}

.input-group.app-input-group--append > .app-input {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}


/* =========================================================
   19h. COMPACT METRIC TILE
   A dense label-over-figure tile for cost breakdowns. Much smaller than
   .app-kpi (no icon, no 118px floor), so a dozen of them fit in a card
   without turning into a wall of dashboard widgets. Pair the label with
   .app-eyebrow.
   ========================================================= */

.app-tile-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(138px, 1fr));
    gap: var(--app-gap-sm);
}

.app-tile {
    min-width: 0;
    padding: .55rem .7rem;
    border: 1px solid var(--cx-inset-border);
    border-radius: var(--cx-radius-md);
    background: var(--cx-inset);
}

.app-tile__value {
    color: var(--cx-text-strong);
    font-size: var(--app-fs-md);
    font-weight: 800;
}

/* The totals tile that closes a breakdown. */
.app-tile--sum {
    border-color: var(--app-warning-bd);
    background: var(--app-warning-bg);
}


/* =========================================================
   19i. STACKED LABEL-OVER-VALUE LAYOUTS
   Two of them, deliberately distinct — do not merge:

   .app-kv-grid   plain, unboxed, wide gap. The record summary at the top
                  of a detail page. (Not .app-kv-list/.app-kv-row, which
                  are the label-left / value-right variant.)
   .app-readout-grid  boxed, tighter gap. The per-entry facts inside a
                  time-entry card.
   Pair either label with .app-eyebrow / .app-label.
   ========================================================= */

.app-kv-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: var(--app-gap);
}

.app-kv-cell {
    min-width: 0;
}

    .app-kv-cell--wide {
        grid-column: 1 / -1;
    }

.app-kv-value {
    color: var(--cx-text-strong);
    font-size: var(--app-fs-md);
    font-weight: 800;
    line-height: 1.3;
    overflow-wrap: anywhere;
}

/* Secondary line under a value (address, VAT id, remarks). */
.app-kv-note {
    margin-top: .25rem;
    color: var(--cx-text-soft);
    font-size: var(--app-fs-sm);
    line-height: 1.5;
    overflow-wrap: anywhere;
}

.app-readout-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(185px, 1fr));
    gap: var(--app-gap-sm);
    margin-top: .85rem;
}

.app-readout {
    min-width: 0;
    padding: .5rem .7rem;
    border: 1px solid var(--cx-inset-border);
    /* 14px sits between --cx-radius-sm and --cx-radius-md on purpose: these
       boxes nest inside an already-rounded card and a 16px corner reads as
       a second card. */
    border-radius: 14px;
    background: var(--cx-inset);
}

    .app-readout p {
        margin: .15rem 0 0;
        color: var(--cx-text);
        font-size: var(--app-fs-md);
        line-height: 1.35;
        word-break: break-word;
    }


/* =========================================================
   20. LEGACY COMPATIBILITY — DARK THEME ONLY
   The 49 not-yet-converted pages are light-styled Bootstrap. In dark theme
   they would render as white-on-white. These rules give Bootstrap's own
   primitives a dark surface so the transition is survivable. They do NOTHING
   in light theme, so today's appearance is untouched.
   Remove a block here once the pages that needed it are converted.
   ========================================================= */

:root[data-theme="dark"] .card,
:root[data-theme="dark"] .list-group-item,
:root[data-theme="dark"] .modal-content,
:root[data-theme="dark"] .dropdown-menu,
:root[data-theme="dark"] .popover,
:root[data-theme="dark"] .toast {
    border-color: var(--cx-border);
    background-color: var(--cx-bg-2);
    color: var(--cx-text);
}

:root[data-theme="dark"] .card-header,
:root[data-theme="dark"] .card-footer,
:root[data-theme="dark"] .modal-header,
:root[data-theme="dark"] .modal-footer {
    border-color: var(--cx-border);
    background-color: var(--cx-panel-soft);
    color: var(--cx-text);
}

:root[data-theme="dark"] .bg-light,
:root[data-theme="dark"] .bg-white {
    background-color: var(--cx-bg-2) !important;
    color: var(--cx-text);
}

:root[data-theme="dark"] .text-dark,
:root[data-theme="dark"] .text-body {
    color: var(--cx-text) !important;
}

:root[data-theme="dark"] .text-muted {
    color: var(--cx-text-dim) !important;
}

:root[data-theme="dark"] .table {
    color: var(--cx-text);
}

    :root[data-theme="dark"] .table th,
    :root[data-theme="dark"] .table td,
    :root[data-theme="dark"] .table thead th {
        border-color: var(--cx-border);
    }

    :root[data-theme="dark"] .table-striped tbody tr:nth-of-type(odd),
    :root[data-theme="dark"] .table-hover tbody tr:hover {
        background-color: var(--cx-hover);
        color: var(--cx-text);
    }

:root[data-theme="dark"] .form-control,
:root[data-theme="dark"] .custom-select,
:root[data-theme="dark"] .input-group-text {
    border-color: var(--cx-inset-border);
    background-color: var(--cx-inset);
    color: var(--cx-text);
}

    :root[data-theme="dark"] .form-control::placeholder {
        color: var(--cx-text-dim);
    }

    :root[data-theme="dark"] .form-control:focus {
        border-color: var(--cx-blue-border);
        background-color: var(--cx-panel-soft);
        color: var(--cx-text);
    }

    /* Native select/option popups are OS-drawn; force a readable pair. */
    :root[data-theme="dark"] select.form-control option,
    :root[data-theme="dark"] .custom-select option {
        background: var(--cx-bg-2);
        color: var(--cx-text);
    }

:root[data-theme="dark"] .dropdown-item {
    color: var(--cx-text);
}

    :root[data-theme="dark"] .dropdown-item:hover,
    :root[data-theme="dark"] .dropdown-item:focus {
        background-color: var(--cx-hover);
        color: var(--cx-text-strong);
    }

:root[data-theme="dark"] .dropdown-divider,
:root[data-theme="dark"] .border-top,
:root[data-theme="dark"] .border-bottom,
:root[data-theme="dark"] .border {
    border-color: var(--cx-border) !important;
}

:root[data-theme="dark"] .close {
    color: var(--cx-text);
    text-shadow: none;
    opacity: .8;
}

:root[data-theme="dark"] .btn-outline-secondary,
:root[data-theme="dark"] .btn-outline-dark {
    color: var(--cx-text);
    border-color: var(--cx-border-strong);
}

    :root[data-theme="dark"] .btn-outline-secondary:hover,
    :root[data-theme="dark"] .btn-outline-dark:hover {
        background-color: var(--cx-hover-strong);
        color: var(--cx-text-strong);
    }


/* =========================================================
   21. REDUCED MOTION
   ========================================================= */

@media (prefers-reduced-motion: reduce) {
    .app-sidebar,
    .app-backdrop,
    .app-nav__link,
    .app-topbar__icon,
    .app-sidebar__action,
    .app-btn-icon,
    .app-tab-link,
    .cx-switch-card,
    .cx-switch-ui,
    .cx-switch-ui::before,
    .btn {
        transition: none !important;
    }

        .btn:hover {
            transform: none;
        }
}


/* =========================================================
   22. PRINT
   ========================================================= */

@media print {
    .app-sidebar,
    .app-topbar,
    .app-backdrop,
    .app-footer {
        display: none !important;
    }

    .app-shell {
        display: block;
    }

    .app-main {
        padding: 0;
    }

    body {
        background: #fff;
        color: #000;
    }
}


/* =========================================================
   APP SHELL — WARIANT DLA GOŚCIA (niezalogowanego)
   Ekran logowania nie ma szyny bocznej ani nawigacji, więc siatka
   dwukolumnowa .app-shell zostawiłaby po lewej pustą kolumnę
   o szerokości --cx-sidebar-width. Tu układ jest jednokolumnowy.

   Wygląd Lewke (2026-10-01): płaskie tło --cx-auth-*, złoty akcent
   --cx-gold-*, na ekranach >= 900px po lewej ciemny panel marki
   (.app-guest-brand, tylko dla gościa — _Layout). Fonty Jost/Figtree
   ładuje _Layout WYŁĄCZNIE dla gościa, więc reszta aplikacji zostaje
   przy systemowym kroju (zasada z sekcji 4).
   ========================================================= */

.app-shell--bare {
    grid-template-columns: minmax(0, 1fr);
    column-gap: 0;
    background: var(--cx-auth-bg);
    color: var(--cx-auth-text);
    font-family: var(--cx-font-text);
}

/* Panel marki — tylko szeroki ekran. Rodzeństwo .app-main (nie przodek modali),
   więc animacja transform w środku nie dotyka warstw okien modalnych. */
.app-guest-brand {
    display: none;
}

.app-guest-brand__ghost {
    position: absolute;
    right: -150px;
    top: 120px;
    width: 560px;
    height: 560px;
    color: var(--cx-gold);
    opacity: .10;
    pointer-events: none;
    animation: guest-drift 26s ease-in-out infinite alternate;
}

.app-guest-brand__head {
    position: relative;
    display: flex;
    align-items: center;
    gap: 14px;
}

.app-guest-brand__mark {
    width: 64px;
    height: 64px;
    flex-shrink: 0;
}

.app-guest-brand__eyebrow {
    color: var(--cx-brand-soft);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .22em;
    text-transform: uppercase;
}

.app-guest-brand__body {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.app-guest-brand__title {
    max-width: 340px;
    margin: 0;
    color: var(--cx-brand-text);
    font-family: var(--cx-font-display);
    font-size: 40px;
    font-weight: 400;
    line-height: 1.12;
    letter-spacing: -.01em;
}

.app-guest-brand__client {
    color: var(--cx-brand-soft);
    font-size: 16px;
}

.app-guest-brand__by {
    position: relative;
    display: block;
    width: 170px;
    height: auto;
    opacity: .6;
}

/* Logo Lewke w kreskach (ramki + litery + trzy pionowe kreski) — wspólne
   dla panelu marki, mini-logo w pasku gościa i ekranu startowego. */
.app-lw {
    fill: none;
    stroke: var(--cx-gold);
    stroke-linecap: square;
    stroke-linejoin: miter;
}

.app-lw__frame,
.app-lw__tick {
    stroke-width: var(--lw-frame, 2.2);
}

.app-lw__letter {
    stroke-width: var(--lw-letter, 3.4);
}

/* Pasek tytułu gościa: bez karty, z mini-logo na telefonie. */
.app-shell--bare .app-main {
    padding: 18px 18px 0;
}

.app-shell--bare .app-topbar {
    position: static;
    min-height: 0;
    gap: 12px;
    padding: 0 0 4px;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    backdrop-filter: none;
}

.app-topbar__lw {
    display: block;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    --lw-frame: 7;
    --lw-letter: 8;
}

.app-shell--bare .app-eyebrow {
    color: var(--cx-auth-dim);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .18em;
    text-transform: uppercase;
}

.app-shell--bare .app-topbar__title {
    margin-top: 2px;
    color: var(--cx-auth-text);
    font-family: var(--cx-font-display);
    font-size: 19px;
    font-weight: 500;
    letter-spacing: 0;
}

.app-shell--bare .app-topbar__icon {
    width: 44px;
    height: 44px;
    min-width: 44px;
    border-radius: 22px;
    border-color: var(--cx-auth-line);
    background: var(--cx-auth-surface);
    color: var(--cx-auth-text) !important;
}

    .app-shell--bare .app-topbar__icon:hover,
    .app-shell--bare .app-topbar__icon:focus {
        border-color: var(--cx-auth-line-2);
        background: var(--cx-auth-surface-2);
    }

.app-shell--bare .app-content {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.app-shell--bare .app-content.container,
.app-shell--bare .app-content.container-fluid {
    padding-left: 0;
    padding-right: 0;
}

.app-shell--bare .app-footer {
    margin-top: 8px;
    padding: 14px 0 22px;
    border-top: 0;
    color: var(--cx-auth-dim);
    font-size: 12px;
}

    .app-shell--bare .app-footer a {
        font-weight: 700;
    }

@media (min-width: 900px) {
    .app-shell--bare {
        grid-template-columns: clamp(360px, 36vw, 540px) minmax(0, 1fr);
    }

    .app-guest-brand {
        position: sticky;
        top: 0;
        height: 100vh;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        padding: 44px 48px;
        overflow: hidden;
        background: var(--cx-brand-ink);
        color: var(--cx-brand-text);
    }

    .app-shell--bare .app-main {
        padding: 22px 40px 0;
    }

    .app-topbar__lw {
        display: none;
    }
}

/* --- Ekrany logowania: SignIn + VerifyCode ----------------------- */

.app-auth {
    width: 100%;
    max-width: 440px;
    margin: 0 auto;
    padding: 18px 0 8px;
    display: flex;
    flex-direction: column;
    gap: 16px;
    color: var(--cx-auth-text);
}

    /* Atrybut hidden (karta instalacji, wskazówki) musi wygrywać z display:flex niżej. */
    .app-auth [hidden] {
        display: none !important;
    }

.app-auth__card {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.app-auth__mark {
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--cx-auth-line);
    border-radius: 28px;
    background: var(--cx-auth-surface-2);
    color: var(--cx-auth-text);
    font-size: 22px;
    animation: auth-in .55s var(--splash-ease) both;
}

.app-auth__mark--gold {
    color: var(--cx-gold-text);
}

.app-auth__head {
    display: flex;
    flex-direction: column;
    gap: 10px;
    animation: auth-in .55s var(--splash-ease) .06s both;
}

.app-auth__title {
    margin: 0;
    color: var(--cx-auth-text);
    font-family: var(--cx-font-display);
    font-size: 34px;
    font-weight: 500;
    line-height: 1.08;
    letter-spacing: -.01em;
}

.app-auth__lead {
    margin: 0;
    color: var(--cx-auth-soft);
    font-size: 16px;
    line-height: 1.55;
}

.app-auth__addr {
    display: block;
    margin-top: 4px;
    color: var(--cx-auth-text);
    font-weight: 700;
    word-break: break-all;
}

.app-auth__form {
    display: flex;
    flex-direction: column;
    gap: 16px;
    animation: auth-in .55s var(--splash-ease) .12s both;
}

/* Podsumowanie walidacji (asp-validation-summary + jquery.validate przełącza klasy). */
.app-auth__errors.validation-summary-valid {
    display: none;
}

.app-auth__errors.validation-summary-errors {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--app-danger-bd);
    border-radius: 14px;
    background: var(--app-danger-bg);
    color: var(--app-danger-fg);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.45;
    animation: auth-shake .4s cubic-bezier(.36, .07, .19, .97);
}

    .app-auth__errors.validation-summary-errors::before {
        content: "\f06a";
        flex-shrink: 0;
        font-family: "Font Awesome 6 Free";
        font-weight: 900;
        font-size: 17px;
        line-height: 1.2;
    }

    .app-auth__errors ul {
        margin: 0;
        padding: 0;
        list-style: none;
    }

.app-auth .cx-flash {
    margin: 0;
    padding: 12px 14px;
    border-radius: 14px;
    box-shadow: none;
}

.app-auth__field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.app-auth__label {
    margin: 0;
    color: var(--cx-auth-soft);
    font-size: 13px;
    font-weight: 700;
}

.app-auth__control {
    position: relative;
    display: flex;
    align-items: center;
}

.app-auth__control-icon {
    position: absolute;
    left: 18px;
    color: var(--cx-auth-dim);
    font-size: 17px;
    pointer-events: none;
}

.app-auth .app-auth__input.form-control,
.app-auth .app-auth__code.form-control {
    height: 56px;
    min-height: 56px;
    border: 1.5px solid var(--cx-auth-line-2);
    border-radius: 16px;
    background: var(--cx-auth-surface);
    color: var(--cx-auth-text);
    font-size: 17px;
    box-shadow: none;
    transition: border-color .2s, box-shadow .2s;
}

.app-auth .app-auth__input.form-control {
    padding: 0 50px 0 48px;
}

    .app-auth .app-auth__input.form-control:focus,
    .app-auth .app-auth__code.form-control:focus {
        border-color: var(--cx-gold);
        background: var(--cx-auth-surface);
        box-shadow: 0 0 0 4px var(--cx-gold-ring);
        color: var(--cx-auth-text);
    }

    .app-auth .app-auth__input.form-control::placeholder,
    .app-auth .app-auth__code.form-control::placeholder {
        color: var(--cx-auth-dim);
    }

    .app-auth .app-auth__input.input-validation-error,
    .app-auth .app-auth__code.input-validation-error {
        border-color: var(--app-danger-solid);
    }

/* Zielony znacznik przy poprawnym formacie adresu — czyste CSS (:valid). */
.app-auth__ok {
    position: absolute;
    right: 16px;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    background: var(--cx-auth-ok);
    color: var(--cx-auth-ok-ink);
    font-size: 12px;
    opacity: 0;
    transform: scale(0);
    pointer-events: none;
    transition: opacity .2s ease, transform .3s cubic-bezier(.3, 1.6, .5, 1);
}

.app-auth__input:valid:not(:placeholder-shown) ~ .app-auth__ok {
    opacity: 1;
    transform: scale(1);
}

.app-auth__remember {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin: 0;
    padding: 14px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 16px;
    background: var(--cx-auth-surface-2);
    cursor: pointer;
    transition: border-color .2s ease;
}

    .app-auth__remember:hover {
        border-color: var(--cx-auth-line-2);
    }

    .app-auth__remember input {
        flex-shrink: 0;
        width: 22px;
        height: 22px;
        margin: 1px 0 0;
        accent-color: var(--cx-gold);
        cursor: pointer;
    }

.app-auth__remember-title {
    display: block;
    color: var(--cx-auth-text);
    font-size: 15px;
    font-weight: 700;
    line-height: 1.35;
}

.app-auth__remember-hint {
    display: block;
    margin-top: 3px;
    color: var(--cx-auth-soft);
    font-size: 13px;
    line-height: 1.5;
}

.app-auth .app-auth__submit.btn {
    width: 100%;
    min-height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    border: 0;
    border-radius: 16px;
    background: var(--cx-gold);
    color: var(--cx-gold-ink);
    font-size: 17px;
    font-weight: 800;
}

    .app-auth .app-auth__submit.btn:hover,
    .app-auth .app-auth__submit.btn:focus {
        background: var(--cx-gold-hover);
        color: var(--cx-gold-ink);
    }

    .app-auth .app-auth__submit.btn:focus {
        box-shadow: 0 0 0 4px var(--cx-gold-ring);
    }

    .app-auth .app-auth__submit.btn:active {
        transform: scale(.98);
    }

.app-auth__help {
    text-align: center;
    color: var(--cx-auth-dim);
    font-size: 14px;
    line-height: 1.5;
}

.app-auth__links {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.app-auth__link {
    width: 100%;
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 12px;
    border: 0;
    border-radius: 12px;
    background: transparent;
    color: var(--cx-auth-soft);
    font-size: 14px;
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}

    .app-auth__link:hover,
    .app-auth__link:focus {
        background: var(--cx-auth-surface-2);
        color: var(--cx-auth-text);
    }

/* Karta „Zainstaluj aplikację” (logika: wwwroot/js/pwa-install.js). */
.app-auth__install {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 16px;
    border: 1px solid var(--cx-gold-line);
    border-radius: 20px;
    background: var(--cx-auth-surface);
    box-shadow: inset 0 3px 0 var(--cx-gold);
    animation: auth-in .55s var(--splash-ease) .18s both;
}

.app-auth__install-head {
    display: flex;
    align-items: center;
    gap: 14px;
}

.app-auth__install-icon {
    flex-shrink: 0;
    width: 52px;
    height: 52px;
    overflow: hidden;
    border: 1px solid var(--cx-auth-line-2);
    border-radius: 14px;
}

    .app-auth__install-icon img {
        display: block;
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .app-auth__install-icon .is-dark {
        display: none;
    }

:root[data-theme="dark"] .app-auth__install-icon .is-light {
    display: none;
}

:root[data-theme="dark"] .app-auth__install-icon .is-dark {
    display: block;
}

.app-auth__install-title {
    margin: 0 0 3px;
    color: var(--cx-auth-text);
    font-size: 17px;
    font-weight: 800;
}

.app-auth__install-lead {
    margin: 0;
    color: var(--cx-auth-soft);
    font-size: 14px;
    line-height: 1.5;
}

.app-auth__platforms {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.app-auth .app-auth__install-btn.btn {
    width: 100%;
    min-height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: 1px solid var(--app-success-bd);
    border-radius: 16px;
    background: var(--app-success-bg);
    color: var(--app-success-fg);
    font-size: 16px;
    font-weight: 800;
}

.app-auth__hint {
    margin: 0;
    padding: 11px 13px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 12px;
    background: var(--cx-auth-surface-2);
    color: var(--cx-auth-text);
    font-size: 14px;
    line-height: 1.5;
    animation: auth-in .35s ease both;
}

.app-auth__steps {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: step;
}

    .app-auth__steps li {
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 11px 12px;
        border: 1px solid var(--cx-auth-line);
        border-radius: 12px;
        background: var(--cx-auth-surface-2);
        color: var(--cx-auth-text);
        font-size: 15px;
        line-height: 1.4;
        counter-increment: step;
    }

        .app-auth__steps li::before {
            content: counter(step);
            flex-shrink: 0;
            width: 28px;
            height: 28px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 14px;
            background: var(--cx-gold);
            color: var(--cx-gold-ink);
            font-size: 13px;
            font-weight: 800;
        }

        .app-auth__steps li i {
            color: var(--cx-gold-text);
        }

/* Pole kodu: jedno prawdziwe <input> (autouzupełnianie „one-time-code”, wklejanie).
   Bez JS wygląda jak duże pole z rozstrzelonymi cyframi; skrypt strony dodaje
   .is-boxed — wtedy to samo pole leży przezroczyste nad 6 kratkami. */
.app-auth__otp {
    position: relative;
}

.app-auth .app-auth__code.form-control {
    height: 62px;
    min-height: 62px;
    padding: 0 12px;
    text-align: center;
    font-family: var(--cx-font-display);
    font-size: 30px;
    font-weight: 500;
    letter-spacing: .5rem;
    text-indent: .5rem;
}

.app-auth__otp-cells {
    display: none;
}

.app-auth__otp.is-boxed .app-auth__otp-cells {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 8px;
}

.app-auth__otp.is-boxed .app-auth__code {
    position: absolute;
    inset: 0;
    z-index: 1;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: text;
}

.app-auth__otp-cell {
    height: 62px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1.5px solid var(--cx-auth-line-2);
    border-radius: 14px;
    background: var(--cx-auth-surface);
    color: var(--cx-auth-text);
    font-family: var(--cx-font-display);
    font-size: 30px;
    font-weight: 500;
    transition: border-color .2s ease, box-shadow .2s ease;
}

    .app-auth__otp-cell.is-empty::after {
        content: "0";
        color: var(--cx-auth-line-2);
    }

    .app-auth__otp-cell.is-filled {
        animation: auth-pop .22s cubic-bezier(.3, 1.6, .5, 1);
    }

    .app-auth__otp-cell.is-active {
        border-color: var(--cx-gold);
        box-shadow: 0 0 0 4px var(--cx-gold-ring);
    }

        .app-auth__otp-cell.is-active.is-empty::after {
            content: "";
            width: 2px;
            height: 30px;
            background: var(--cx-gold);
            animation: auth-blink 1s steps(1) infinite;
        }

.app-auth__otp.has-error .app-auth__otp-cell,
.app-auth__code.input-validation-error + .app-auth__otp-cells .app-auth__otp-cell {
    border-color: var(--app-danger-solid);
}

.app-auth__otp.has-error .app-auth__otp-cells {
    animation: auth-shake .4s cubic-bezier(.36, .07, .19, .97);
}

.app-auth__code-help {
    color: var(--cx-auth-dim);
    font-size: 13px;
    line-height: 1.45;
}

@keyframes auth-in {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }
}

@keyframes auth-pop {
    from { transform: scale(.86); }
    to   { transform: scale(1); }
}

@keyframes auth-blink {
    50% { opacity: 0; }
}

@keyframes auth-shake {
    20%, 60% { transform: translateX(-6px); }
    40%, 80% { transform: translateX(6px); }
}

@keyframes guest-drift {
    from { transform: translate(0, 0); }
    to   { transform: translate(-24px, 18px); }
}

@media (prefers-reduced-motion: reduce) {
    .app-auth *,
    .app-auth__errors,
    .app-guest-brand__ghost {
        animation: none !important;
    }
}


/* =========================================================
   22. SPLASH / EKRAN STARTOWY
   Sekwencja marki odtwarzana raz na sesję przeglądarki (patrz app-ui.js).
   Wersja Lewke (2026-10-01, zatwierdzona przez właściciela):
     0.15 - 1.55  trzy ramki logo Lewke rysują się linią
     0.90 - 1.70  litery LEWKE rysują się kreską
     1.45 - 2.05  trzy pionowe kreski pod ramkami
     1.80 - 2.40  podpis „Czas pracy · Projekty · Zespół”
     2.30 - 3.10  na dole „Dostarcza” + logotyp Alcaeus
     0.20 - 4.30  złoty pasek ładowania
     4.40 - 5.00  warstwa unosi się i znika (splash-lift; JS sprząta po animationend)

   Tło CELOWO ciemne w obu motywach (decyzja właściciela: ekran startowy
   tylko w ciemnym). Logo Lewke jest inline SVG z samych kresek — bez pliku
   i bez fontu, więc niczego nie doładowuje. Animacja wyłącznie stroke /
   opacity / transform. Przy wyłączonym JS warstwa i tak znika
   (animacja kończy się visibility:hidden).
   ========================================================= */
:root {
    --splash-total: 5s;
    --splash-ease: cubic-bezier(.22, 1, .36, 1);
}

.app-splash {
    position: fixed;
    inset: 0;
    z-index: 2147483000;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: var(--cx-brand-ink);
    animation: splash-lift .6s var(--splash-ease) calc(var(--splash-total) - .6s) both;
    will-change: opacity, transform;
}

/* Pominięcie: użytkownik już widział sekwencję w tej sesji (flaga ustawiana
   przed pierwszym malowaniem), więc warstwa nie może nawet mrugnąć. */
:root[data-splash="done"] .app-splash {
    display: none !important;
}

.app-splash__stage {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 28px;
}

.app-splash__logo {
    display: block;
    width: min(48vw, 188px);
    height: auto;
    overflow: visible;
}

    .app-splash__logo .app-lw__frame,
    .app-splash__logo .app-lw__letter,
    .app-splash__logo .app-lw__tick {
        stroke-dasharray: 1;
        stroke-dashoffset: 1;
        animation: splash-draw 1.1s cubic-bezier(.65, 0, .35, 1) both;
    }

    .app-splash__logo .app-lw__letter {
        animation-duration: .5s;
    }

    .app-splash__logo .app-lw__tick {
        animation-duration: .4s;
    }

.app-splash__tagline {
    color: var(--cx-brand-soft);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .24em;
    text-align: center;
    text-transform: uppercase;
    animation: splash-rise .6s var(--splash-ease) 1.8s both;
}

.app-splash__bar {
    width: 132px;
    height: 2px;
    overflow: hidden;
    border-radius: 999px;
    background: var(--cx-brand-ink-2);
}

    .app-splash__bar::after {
        content: "";
        display: block;
        height: 100%;
        background: var(--cx-gold);
        transform-origin: left center;
        animation: splash-bar 4.1s cubic-bezier(.3, .7, .2, 1) .2s both;
    }

.app-splash__by {
    position: absolute;
    left: 0;
    right: 0;
    bottom: clamp(2.2rem, 7vh, 3.5rem);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    animation: splash-by .8s var(--splash-ease) 2.3s both;
}

    .app-splash__by span {
        color: var(--cx-brand-dim);
        font-size: 11px;
        letter-spacing: .2em;
        text-transform: uppercase;
    }

    .app-splash__by img {
        display: block;
        width: 172px;
        height: auto;
    }

@media (min-width: 900px) {
    .app-splash__stage {
        gap: 32px;
    }

    .app-splash__logo {
        width: 240px;
    }

    .app-splash__tagline {
        font-size: 13px;
    }

    .app-splash__bar {
        width: 168px;
    }

    .app-splash__by img {
        width: 200px;
    }
}

@keyframes splash-draw {
    to { stroke-dashoffset: 0; }
}

@keyframes splash-rise {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

@keyframes splash-by {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: .8; transform: none; }
}

@keyframes splash-bar {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}

@keyframes splash-lift {
    from { opacity: 1; transform: scale(1);     filter: blur(0); visibility: visible; }
    99%  { opacity: 0; transform: scale(1.045); filter: blur(5px); visibility: visible; }
    to   { opacity: 0; transform: scale(1.045); filter: blur(5px); visibility: hidden; }
}

/* Redukcja ruchu: logo od razu narysowane, bez wjazdów — tylko krótkie
   wygaszenie całej warstwy. */
@media (prefers-reduced-motion: reduce) {
    .app-splash {
        animation: splash-lift-reduced .4s linear 1.1s both;
    }

        .app-splash__logo .app-lw__frame,
        .app-splash__logo .app-lw__letter,
        .app-splash__logo .app-lw__tick {
            animation: none;
            stroke-dashoffset: 0;
        }

    .app-splash__tagline {
        animation: none;
    }

    .app-splash__by {
        animation: none;
        opacity: .8;
    }

    .app-splash__bar::after {
        animation: splash-bar 1.1s linear both;
    }

    @keyframes splash-lift-reduced {
        from { opacity: 1; visibility: visible; }
        99%  { opacity: 0; visibility: visible; }
        to   { opacity: 0; visibility: hidden; }
    }
}



/* =========================================================
   23. CRM: NAGŁÓWEK W TOPBARZE, PASEK POLECEŃ, TABELA „FIT”
   Wspólne klocki dla stron CRM (i każdej przyszłej listy):
     .app-brand__client  okrągły avatar klienta w bocznym menu
     .app-topbar__meta   chipy strony obok tytułu w topbarze
     .app-commandbar     jedna karta: zakładki + akcje + filtry nad tabelą
     .app-filterbar      filtry w poziomie; na telefonie zwinięte pod przyciskiem
     .app-toggle-chip    checkbox w formie przełączanej pigułki
     .app-table--fit     tabela, która NIGDY nie przewija się w poziomie
     .app-cellstack      komórka: wartość główna + druga linia
     .app-rowhead        numer rekordu + przyciski akcji
   ========================================================= */

/* --- Boczne menu: klient jako okrągły avatar zamiast napisu „Lewke” ------ */
.app-brand__client {
    display: flex;
    align-items: center;
    gap: .75rem;
    min-width: 0;
    padding: .55rem .65rem;
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-md);
    background: var(--cx-hover);
    transition: background var(--app-dur) var(--app-ease), border-color var(--app-dur) var(--app-ease);
}

    .app-brand:hover .app-brand__client {
        border-color: var(--cx-border-strong);
        background: var(--cx-hover-strong);
    }

.app-brand__avatar {
    flex: 0 0 auto;
    width: 52px;
    height: 52px;
    display: grid;
    place-items: center;
    padding: 6px;
    border-radius: 50%;
    background: var(--cx-client-plate);
    box-shadow: 0 0 0 2px var(--cx-border-strong), var(--cx-shadow-soft);
    overflow: hidden;
}

    .app-brand__avatar img {
        display: block;
        width: 100%;
        height: 100%;
        object-fit: contain;
    }

.app-brand__name {
    min-width: 0;
    color: var(--cx-text-strong);
    font-size: var(--app-fs-md);
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -.02em;
    text-align: left;
}

/* --- Topbar: tytuł strony + jej chipy (data, tydzień, uprawnienia) ------- */
.app-topbar__headline {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .35rem .8rem;
    min-width: 0;
}

    .app-topbar__headline .app-topbar__title {
        flex: 0 1 auto;
        min-width: 0;
    }

.app-topbar__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem;
    min-width: 0;
    margin-top: .2rem;
}

    .app-topbar__meta .app-chip {
        min-height: 28px;
        padding: .2rem .62rem;
        font-size: var(--app-fs-xs);
    }

/* --- Pasek poleceń: zakładki + akcje + filtry w JEDNEJ karcie ------------ */
.app-commandbar {
    display: grid;
    gap: .9rem;
    padding: .9rem;
}

.app-commandbar__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .75rem;
}

.app-commandbar__actions {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

    .app-commandbar__actions form {
        margin: 0;
    }

    .app-commandbar__actions .btn {
        display: inline-flex;
        align-items: center;
        gap: .45rem;
        min-height: var(--app-tap);
        white-space: nowrap;
    }

.app-commandbar__rule {
    height: 1px;
    margin: 0;
    border: 0;
    background: var(--cx-border);
}

/* Zakładki w pasku poleceń zawijają się zamiast przewijać w poziomie. */
.app-commandbar .app-tabs {
    flex-wrap: wrap;
    overflow: visible;
}

/* --- Filtry w poziomie ----------------------------------------------------- */
.app-filterbar {
    display: grid;
    gap: .8rem;
}

/* Przycisk zwijania: tylko na telefonie (patrz media query niżej). */
.app-filterbar__toggle {
    display: none;
}

.app-filterbar__panel {
    display: grid;
    gap: .9rem;
}

.app-filterbar__depts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
}

    .app-filterbar__depts > .app-label {
        margin: 0 .25rem 0 0;
    }

.app-filterbar__chips {
    display: flex;
    flex-wrap: wrap;
    gap: .45rem;
}

.app-filterbar__body {
    display: grid;
    grid-template-columns:
        minmax(0, .8fr)
        minmax(0, 1.1fr)
        minmax(0, 1.6fr)
        minmax(0, 1.3fr)
        auto;
    gap: .75rem 1rem;
    align-items: end;
}

.app-filterbar__field {
    display: grid;
    gap: .35rem;
    min-width: 0;
}

    .app-filterbar__field > .app-label {
        margin: 0;
    }

.app-filterbar__submit .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    width: 100%;
    min-height: var(--app-control-h);
    white-space: nowrap;
}

/* Licznik aktywnych filtrów na przycisku zwijania. */
.app-filterbar__count {
    display: inline-grid;
    place-items: center;
    min-width: 1.5rem;
    height: 1.5rem;
    padding: 0 .4rem;
    border-radius: var(--cx-radius-pill);
    background: var(--cx-blue);
    color: var(--cx-on-accent);
    font-size: var(--app-fs-xs);
    font-weight: 800;
}

@media (max-width: 1199.98px) {
    .app-filterbar__body {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 767.98px) {
    .app-filterbar__toggle {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: .6rem;
        width: 100%;
        min-height: var(--app-tap);
        padding: .55rem .9rem;
        border: 1px solid var(--cx-inset-border);
        border-radius: var(--cx-radius-md);
        background: var(--cx-inset);
        color: var(--cx-text-strong);
        font-weight: 800;
        text-align: left;
        cursor: pointer;
    }

        .app-filterbar__toggle .app-filterbar__chev {
            transition: transform var(--app-dur) var(--app-ease);
        }

    .app-filterbar.is-open .app-filterbar__chev {
        transform: rotate(180deg);
    }

    .app-filterbar__panel {
        display: none;
    }

    .app-filterbar.is-open .app-filterbar__panel {
        display: grid;
    }

    .app-filterbar__body {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* --- Przełączana pigułka (checkbox) ---------------------------------------- */
.app-toggle-chip {
    position: relative;
    display: inline-flex;
    margin: 0;
    cursor: pointer;
}

    /* Pole pozostaje prawdziwym checkboxem formularza (name/value/checked bez zmian):
       jest tylko wizualnie ukryte, nie wyłączone ani usunięte z tabulacji. */
    .app-toggle-chip input {
        position: absolute;
        width: 1px;
        height: 1px;
        opacity: 0;
        pointer-events: none;
    }

    .app-toggle-chip span {
        display: inline-flex;
        align-items: center;
        gap: .45rem;
        min-height: 38px;
        padding: .4rem .95rem;
        border: 1px solid var(--cx-border);
        border-radius: var(--cx-radius-pill);
        background: var(--cx-hover);
        color: var(--cx-text-soft);
        font-size: var(--app-fs-sm);
        font-weight: 800;
        letter-spacing: .02em;
        user-select: none;
        transition: background var(--app-dur) var(--app-ease), border-color var(--app-dur) var(--app-ease), color var(--app-dur) var(--app-ease);
    }

        .app-toggle-chip span::before {
            content: "";
            width: .6rem;
            height: .6rem;
            border: 1.5px solid currentColor;
            border-radius: 50%;
            opacity: .65;
            transition: background var(--app-dur) var(--app-ease), box-shadow var(--app-dur) var(--app-ease);
        }

    .app-toggle-chip:hover span {
        border-color: var(--cx-border-strong);
        color: var(--cx-text-strong);
    }

    .app-toggle-chip input:checked + span {
        border-color: var(--cx-active-border);
        background: var(--cx-active-bg);
        color: var(--cx-text-strong);
    }

        .app-toggle-chip input:checked + span::before {
            border-color: var(--cx-blue);
            background: var(--cx-blue);
            box-shadow: 0 0 0 3px var(--cx-blue-soft);
            opacity: 1;
        }

    .app-toggle-chip input:focus-visible + span {
        outline: 2px solid var(--cx-blue);
        outline-offset: 2px;
    }

@media (pointer: coarse) {
    .app-toggle-chip span {
        min-height: var(--app-tap);
    }
}

/* --- Tabela „fit”: nigdy nie przewija się w poziomie ------------------------
   table-layout: fixed + szerokości z colgroup sprawiają, że tabela nie może
   być szersza od kontenera: treść się ZAWIJA, zamiast rozpychać kolumny.

   O trybie (tabela / karty) decyduje szerokość SAMEJ tabeli — container query,
   a nie szerokość okna. Szerokość okna to zły miernik: boczne menu zabiera 216
   albo 260 px zależnie od ekranu, więc to samo okno daje różną szerokość tabeli.
     >= 920px  tabela
     < 920px   karty w 2 kolumnach
     < 560px   karty w 1 kolumnie
   Próg 920px wynika z pomiaru: przy 8 kolumnach węższa tabela ścina etykiety
   statusu do pojedynczych liter. */
.app-table-wrap--fit {
    overflow-x: visible;
    container-type: inline-size;
    container-name: fittable;
}

.app-table--fit {
    table-layout: fixed;
}

    .app-table--fit thead th {
        white-space: normal;
        overflow-wrap: anywhere;
        vertical-align: bottom;
        padding: .4rem .75rem;
    }

    .app-table--fit tbody td {
        padding: .7rem .75rem;
        vertical-align: top;
        overflow-wrap: anywhere;
    }

    /* Liczby i kwoty nie mogą pękać w środku. */
    .app-table--fit .app-table__num {
        overflow-wrap: normal;
    }

    /* Zwarty chip statusu w gęstej tabeli. Łamie się WYŁĄCZNIE między słowami
       (overflow-wrap: normal) — bez tego „Zlecenie otwarte” rozsypywało się na
       „Zlec/enie/otwa/rte”. Kropka tonu jest tu ukryta: ikona i zabarwienie chipa
       niosą tę samą informację, a kropka zabierała miejsce na tekst. */
    .app-table--fit .cx-status-chip {
        max-width: 100%;
        min-height: 28px;
        gap: .35rem;
        padding: .25rem .6rem;
        font-size: var(--app-fs-xs);
        white-space: normal;
        overflow-wrap: normal;
        line-height: 1.25;
        text-align: left;
    }

        .app-table--fit .cx-status-chip::before {
            display: none;
        }

.app-cellstack {
    display: grid;
    gap: .2rem;
    min-width: 0;
}

.app-cellstack__main {
    color: var(--cx-text-strong);
    font-weight: 700;
    line-height: 1.3;
}

.app-cellstack__sub {
    color: var(--cx-text-soft);
    font-size: var(--app-fs-xs);
    line-height: 1.45;
}

.app-rowhead {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .45rem;
}

.app-rowhead__id {
    color: var(--cx-text-strong);
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.app-rowhead__actions {
    display: flex;
    gap: .3rem;
}

/* Na myszy (i tylko w trybie tabeli) przyciski w wierszu mogą być mniejsze;
   na dotyku oraz w kartach zostają 44px. */
@media (pointer: fine) {
    @container fittable (min-width: 920px) {
        .app-table--fit .app-btn-icon {
            width: 32px;
            height: 32px;
            min-width: 32px;
            border-radius: 10px;
        }
    }
}

@container fittable (max-width: 919.98px) {
    .app-table--fit {
        table-layout: auto;
        border-spacing: 0;
    }

        .app-table--fit colgroup,
        .app-table--fit thead {
            display: none;
        }

        .app-table--fit,
        .app-table--fit tbody,
        .app-table--fit tr,
        .app-table--fit td {
            display: block;
            width: 100%;
        }

            .app-table--fit tbody {
                display: grid;
                grid-template-columns: repeat(2, minmax(0, 1fr));
                gap: .75rem;
            }

                .app-table--fit tbody tr {
                    display: grid;
                    align-content: start;
                    gap: .5rem;
                    margin: 0;
                    padding: .9rem;
                    border: 1px solid var(--cx-inset-border);
                    border-radius: var(--cx-radius-md);
                    background: var(--cx-inset);
                }

                .app-table--fit tbody td {
                    display: flex;
                    align-items: flex-start;
                    justify-content: space-between;
                    gap: 1rem;
                    padding: .1rem 0;
                    border: 0;
                    font-size: var(--app-fs-md);
                    text-align: right;
                }

                    .app-table--fit tbody td::before {
                        content: attr(data-label);
                        flex: 0 0 auto;
                        max-width: 45%;
                        color: var(--cx-text-soft);
                        font-size: var(--app-fs-sm);
                        font-weight: 700;
                        text-align: left;
                    }

                    .app-table--fit tbody td:first-child,
                    .app-table--fit tbody td:last-child {
                        border: 0;
                        border-radius: 0;
                    }

                    /* Pierwsza komórka = nagłówek karty (numer + akcje), bez etykiety. */
                    .app-table--fit tbody td.app-table__head {
                        align-items: center;
                        padding-bottom: .6rem;
                        border-bottom: 1px solid var(--cx-inset-border);
                    }

                        .app-table--fit tbody td.app-table__head::before {
                            content: none;
                        }

        .app-table--fit .app-rowhead {
            width: 100%;
            justify-content: space-between;
        }

        .app-table--fit .app-rowhead__id {
            font-size: var(--app-fs-lg);
        }

        .app-table--fit .app-cellstack {
            justify-items: end;
            text-align: right;
        }
}

@container fittable (max-width: 559.98px) {
    .app-table--fit tbody {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Zakładki na telefonie: siatka kafelków (ikona nad podpisem) zamiast paska,
   który trzeba by przewijać w bok. */
@media (max-width: 575.98px) {
    /* <nav> jest elementem flex i kurczy się do treści — bez tego siatka zakładek
       miałaby 100% szerokości zbyt wąskiego rodzica, a nie całej karty. */
    .app-commandbar__top > nav {
        flex: 1 1 100%;
        min-width: 0;
    }

    .app-commandbar .app-tabs {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        width: 100%;
        border-radius: var(--cx-radius-md);
    }

        .app-commandbar .app-tab-link {
            flex-direction: column;
            justify-content: center;
            gap: .25rem;
            width: 100%;
            min-height: 56px;
            padding: .45rem .3rem;
            border-radius: var(--cx-radius-sm);
            font-size: var(--app-fs-xs);
            text-align: center;
            white-space: normal;
        }

    .app-commandbar__actions,
    .app-commandbar__actions form,
    .app-commandbar__actions .btn {
        width: 100%;
    }

    .app-commandbar__actions .btn {
        justify-content: center;
    }
}

/* Podpowiedzi pod polami filtrów: na komputerze to samo jest w podpowiedzi (title)
   pola, więc linijki pomocy nie rozpychają poziomego paska. Na telefonie, gdzie nie
   ma najechania kursorem, a pola stoją jedno pod drugim, podpowiedź jest widoczna. */
.app-filterbar__help {
    display: none;
}

@media (max-width: 767.98px) {
    .app-filterbar__help {
        display: block;
    }
}


/* =========================================================
   24. POPRAWKI PO WDROŻENIU UKŁADU CRM
   Luki zgłoszone przy przenoszeniu 11 stron CRM na komponenty z sekcji 23.
   Poprawione tu centralnie, żeby nie żyły jako łatki w poszczególnych stronach.
   ========================================================= */

/* (a) Długi chip w topbarze (np. nazwa klienta na stronie projektu) nie może
       poszerzać strony. .app-chip ma nowrap, więc przy 768px chip z długą nazwą
       wystawał o ~69px i dawał poziomy pasek przewijania. */
.app-topbar__meta .app-chip {
    max-width: 100%;
    white-space: normal;
    overflow-wrap: anywhere;
}

/* (b) Pola w .app-form-grid stoją obok siebie w siatce — regułą .app-field + .app-field
       dostawałyby górny margines i rozjeżdżały się w pionie. */
.app-form-grid > .app-field + .app-field {
    margin-top: 0;
}

/* (c) Kilka przycisków w polu „submit” filtrów (np. Szukaj + Wyczyść). */
.app-filterbar__submit {
    display: flex;
    gap: .5rem;
}

    .app-filterbar__submit .btn {
        flex: 1 1 auto;
    }

/* (d) Pojedyncza zakładka (np. „Powrót” na stronach szczegółów) nie może na telefonie
       stać się kafelkiem 1/3 szerokości w pustej siatce 3-kolumnowej. */
@media (max-width: 575.98px) {
    .app-commandbar .app-tabs:has(> .app-tab-item:only-child) {
        display: inline-flex;
        width: auto;
    }

        .app-commandbar .app-tabs:has(> .app-tab-item:only-child) .app-tab-link {
            flex-direction: row;
            min-height: 40px;
            font-size: var(--app-fs-sm);
        }
}

/* (e) KOMPAKTOWA TABELA „FIT” — dla małych tabel (3–5 kolumn, mało stałych szerokości).
       Próg 920px z sekcji 23 dobrano dla tabel 8-kolumnowych; mała tabela (np. lista
       klientów) zamieniała się przez to w karty nawet na laptopie 1280px. Tutaj karty
       pojawiają się dopiero poniżej 600px szerokości tabeli, zawsze w 1 kolumnie.
       Użycie: <div class="app-table-wrap app-table-wrap--fit app-table-wrap--compact">.
       Inna nazwa kontenera sprawia, że reguły „fittable” z sekcji 23 w ogóle jej nie
       dotyczą — dlatego reguły kart są tu powtórzone (CSS nie pozwala sparametryzować
       progu container query zmienną).
       Warunek: suma stałych szerokości kolumn musi być wyraźnie poniżej 600px. */
.app-table-wrap--compact {
    container-name: fittable-sm;
}

@media (pointer: fine) {
    @container fittable-sm (min-width: 600px) {
        .app-table--fit .app-btn-icon {
            width: 32px;
            height: 32px;
            min-width: 32px;
            border-radius: 10px;
        }
    }
}

@container fittable-sm (max-width: 599.98px) {
    .app-table--fit {
        table-layout: auto;
        border-spacing: 0;
    }

        .app-table--fit colgroup,
        .app-table--fit thead {
            display: none;
        }

        .app-table--fit,
        .app-table--fit tbody,
        .app-table--fit tr,
        .app-table--fit td {
            display: block;
            width: 100%;
        }

            .app-table--fit tbody {
                display: grid;
                grid-template-columns: minmax(0, 1fr);
                gap: .75rem;
            }

                .app-table--fit tbody tr {
                    display: grid;
                    align-content: start;
                    gap: .5rem;
                    margin: 0;
                    padding: .9rem;
                    border: 1px solid var(--cx-inset-border);
                    border-radius: var(--cx-radius-md);
                    background: var(--cx-inset);
                }

                .app-table--fit tbody td {
                    display: flex;
                    align-items: flex-start;
                    justify-content: space-between;
                    gap: 1rem;
                    padding: .1rem 0;
                    border: 0;
                    font-size: var(--app-fs-md);
                    text-align: right;
                }

                    .app-table--fit tbody td::before {
                        content: attr(data-label);
                        flex: 0 0 auto;
                        max-width: 45%;
                        color: var(--cx-text-soft);
                        font-size: var(--app-fs-sm);
                        font-weight: 700;
                        text-align: left;
                    }

                    .app-table--fit tbody td:first-child,
                    .app-table--fit tbody td:last-child {
                        border: 0;
                        border-radius: 0;
                    }

                    .app-table--fit tbody td.app-table__head {
                        align-items: center;
                        padding-bottom: .6rem;
                        border-bottom: 1px solid var(--cx-inset-border);
                    }

                        .app-table--fit tbody td.app-table__head::before {
                            content: none;
                        }

        .app-table--fit .app-rowhead {
            width: 100%;
            justify-content: space-between;
        }

        .app-table--fit .app-cellstack {
            justify-items: end;
            text-align: right;
        }
}


/* =========================================================
   25. POPRAWKI: LISTY ROZWIJANE W PASKU POLECEŃ, IKONA CZATU, TOPBAR
   (Okna modalne naprawia brak z-index na main / .app-shell — sekcje 4 i 7.)
   ========================================================= */

/* (a) Lista rozwijana w pasku poleceń (np. „Status projektu (Autofiltr)” na CRM/Index)
       wystaje poniżej karty. .app-card ma overflow: hidden (przycina treść do zaokrągleń),
       więc lista była ucięta na dolnej krawędzi paska, a karty KPI pod spodem ją zasłaniały.
       Pasek nie ma treści dochodzącej do krawędzi, więc overflow: visible nic nie psuje;
       z-index podnosi go nad następne karty (każda z backdrop-filter to osobna warstwa). */
.app-commandbar {
    position: relative;
    z-index: 3;
    overflow: visible;
}

/* (b) Ikona czatu. Znacznik z dawnego paska (.icon-wrap z site.css: stałe pole 1.6em,
       display: inline-block) stawiał kopertę w lewym górnym rogu tego pola — ok. 4px
       w lewo i w górę względem środka przycisku, podczas gdy ikona motywu obok jest
       na środku. Pole obejmuje teraz samą ikonę, więc licznik nieprzeczytanych
       (.badge-counter, position: absolute) siedzi na jej rogu. */
.app-topbar .icon-wrap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: auto;
    height: auto;
    line-height: 1;
}

/* (c) Topbar w jednej linii z treścią strony. Treść ma maksymalną szerokość i jest
       wyśrodkowana (.app-content, sekcja 7), a topbar szedł przez całą szerokość —
       na szerokim ekranie tytuł stał daleko z lewej, a ikony czatu i motywu daleko
       z prawej, ok. 125px poza krawędzią kart. Ta sama szerokość, wyśrodkowanie
       i 15px wcięcia co kontener Bootstrapa w <main>. Tylko od 768px — na telefonie
       topbar jest osobną przyklejoną kartą (sekcja 8). */
@media (min-width: 768px) {
    .app-topbar {
        width: 100%;
        max-width: min(100%, var(--app-content-max));
        margin-left: auto;
        margin-right: auto;
        padding-left: 15px;
        padding-right: 15px;
    }

    .app-topbar--wide {
        max-width: min(100%, var(--app-content-max-wide));
    }
}


/* =========================================================
   26. PASEK STRONICOWANIA — jeden wygląd na wszystkich stronach
   Wzór: strona Użytkownicy (zatwierdzony przez klienta 2026-09-24). Używają go:
   Users/Index, Payroll/Index, TimeEntry/Review, Pages/Index (pulpit), CRM/Invoices.
   Znacznik (linki zostają po stronie każdej strony, tu tylko wygląd):
     <div class="app-pagebar">
       <div class="app-pagebar__sizes">
         <span class="small app-muted">Liczba wpisów na stronę:</span>
         <a class="btn btn-sm btn-secondary|btn-outline-secondary">20</a> …
       </div>
       <div class="app-pagebar__nav">
         <nav><ul class="pagination pagination-sm app-pager-compact mb-0">…</ul></nav>
         <div class="small app-muted">Łączna liczba wpisów: <strong>N</strong></div>
       </div>
     </div>
   Płaski pasek z linią u góry, bez karty. Poniżej 768px elementy układają się
   w kolumnę, a numery stron zawijają się zamiast wystawać poza ekran.
   ========================================================= */
.app-pagebar {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    margin-top: 1rem;
    padding-top: .75rem;
    border-top: 1px solid var(--cx-border);
}

@media (min-width: 768px) {
    .app-pagebar {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }
}

.app-pagebar__sizes {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem;
}

.app-pagebar__nav {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: .75rem;
}

    .app-pagebar__nav .pagination {
        flex-wrap: wrap;
        row-gap: .35rem;
    }

@media (max-width: 767.98px) {
    .app-pagebar__nav {
        justify-content: flex-start;
    }
}

/* W .app-stack odstęp daje już gap stosu — bez dodatkowego marginesu. */
.app-stack > .app-pagebar {
    margin-top: 0;
}

/* Stała wielkość strony (CRM/Invoices: zawsze 20) — pigułka wygląda jak aktywny wybór,
   ale nie jest przyciskiem. */
.app-pagebar__fixed {
    cursor: default;
    pointer-events: none;
}


/* =========================================================
   27. ZEGAR SESJI, REJESTRATOR CZASU I PANEL GŁÓWNY (wzór: Chronexa)
   Używają: TimeEntry/Tracker (karta sesji + ostatnie sesje) i Pages/Index
   (nagłówek panelu: powitanie z awatarem albo aktywna sesja + szybkie akcje).
   Kolory tylko z tokenów --cx-clock-* / --cx-dot-* / --cx-home-* (sekcje 3a i 3b).

   Zegar:
     <div class="cx-clock" data-clock-ring>            (+ --idle | --sm | --live)
       <span class="cx-clock__hand" aria-hidden="true"></span>
       <div class="cx-clock__core">
         <span class="cx-clock__label">W trakcie</span>
         <strong class="cx-clock__time" data-clock-elapsed>00:00:00</strong>
       </div>
     </div>
   Pierścień wypełnia się raz na minutę (jak w Chronexie); kąt ustawia app-ui.js
   (window.AppSessionClock) przez zmienną --cx-clock-deg. Dzięki @property kąt
   przechodzi płynnie z sekundy na sekundę; przeglądarka bez @property po prostu
   przeskakuje co sekundę.
   ========================================================= */

@property --cx-clock-deg {
    syntax: "<angle>";
    inherits: true;
    initial-value: 0deg;
}

.cx-clock {
    --cx-clock-size: min(300px, 76vw);
    --cx-clock-deg: 0deg;
    position: relative;
    width: var(--cx-clock-size);
    aspect-ratio: 1;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    margin-inline: auto;
    border-radius: 999px;
    background:
        conic-gradient(from 0deg, var(--cx-clock-from) 0deg, var(--cx-clock-to) var(--cx-clock-deg), var(--cx-clock-track) var(--cx-clock-deg) 360deg);
    box-shadow: var(--cx-clock-shadow);
    transition: --cx-clock-deg 1s linear;
}

    /* Otwór pierścienia — ten sam kolor co rdzeń, więc pierścień ma ok. 12% grubości. */
    .cx-clock::before {
        content: "";
        position: absolute;
        inset: 12%;
        border-radius: inherit;
        background: var(--cx-clock-core);
    }

    /* Delikatna, „oddychająca” poświata, gdy licznik działa. */
    .cx-clock--live::after {
        content: "";
        position: absolute;
        inset: -6px;
        border-radius: inherit;
        box-shadow: 0 0 0 0 var(--cx-clock-halo);
        animation: cx-clock-breathe 2.4s ease-in-out infinite;
        pointer-events: none;
    }

    /* Przeskok 59 s -> 0 s bez cofania się pierścienia (app-ui.js dodaje klasę na jedną klatkę). */
    .cx-clock.is-wrapping,
    .cx-clock.is-wrapping .cx-clock__hand {
        transition: none;
    }

/* Wskazówka to wąski pionowy pasek przez środek tarczy (a nie pełny kwadrat): obrócony
   kwadrat ma ramkę do 41% większą i przy niektórych sekundach wystawałby poza ekran
   telefonu, dając poziomy pasek przewijania. Pasek mieści się w tarczy pod każdym kątem. */
.cx-clock__hand {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 47%;
    width: 6%;
    z-index: 2;
    /* Bez własnego transition: kąt dziedziczy już płynnie animowaną --cx-clock-deg. */
    transform: rotate(var(--cx-clock-deg));
    pointer-events: none;
}

    /* Kropka na czele postępu, na środku grubości pierścienia. */
    .cx-clock__hand::before {
        content: "";
        position: absolute;
        top: 6%;
        left: 50%;
        width: 84%;
        aspect-ratio: 1;
        border-radius: 999px;
        background: var(--cx-clock-hand);
        box-shadow: 0 0 0 4px var(--cx-clock-halo), 0 0 14px var(--cx-clock-to);
        transform: translate(-50%, -50%);
    }

.cx-clock__core {
    position: relative;
    z-index: 1;
    width: 66%;
    aspect-ratio: 1;
    display: grid;
    place-items: center;
    align-content: center;
    gap: .35rem;
    border: 1px solid var(--cx-clock-core-border);
    border-radius: 999px;
    background: var(--cx-clock-core);
    text-align: center;
}

.cx-clock__label {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    color: var(--cx-text-soft);
    font-size: .82rem;
    font-weight: 850;
    letter-spacing: .07em;
    text-transform: uppercase;
}

.cx-clock--live .cx-clock__label::before {
    content: "";
    width: .5rem;
    height: .5rem;
    border-radius: 999px;
    background: var(--app-success-solid);
    animation: cx-live-dot 1.6s ease-in-out infinite;
}

.cx-clock__time {
    color: var(--cx-text-strong);
    font-size: clamp(2.2rem, 5.2vw, 3.5rem);
    font-weight: 950;
    line-height: .95;
    letter-spacing: -.055em;
    font-variant-numeric: tabular-nums;
    text-shadow: var(--cx-clock-text-glow);
}

/* Bezczynny: pełny pierścień, bez wskazówki i animacji. */
.cx-clock--idle {
    --cx-clock-deg: 360deg;
    transition: none;
}

    .cx-clock--idle .cx-clock__hand {
        display: none;
    }

/* Mniejszy wariant (panel główny). */
.cx-clock--sm {
    --cx-clock-size: min(210px, 64vw);
}

    .cx-clock--sm .cx-clock__label {
        font-size: .7rem;
    }

    .cx-clock--sm .cx-clock__time {
        font-size: clamp(1.7rem, 4vw, 2.15rem);
    }

@keyframes cx-clock-breathe {
    0%, 100% { box-shadow: 0 0 0 0 var(--cx-clock-halo); }
    50%      { box-shadow: 0 0 0 10px transparent, 0 0 36px 4px var(--cx-clock-halo); }
}

@keyframes cx-live-dot {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: .35; transform: scale(.7); }
}


/* --- Karta sesji: nagłówek, zegar + statystyki/formularz, akcje -------- */

.cx-session {
    container-type: inline-size;
    container-name: cxsession;
    display: grid;
    gap: 1.1rem;
    padding: 1.15rem;
}

.cx-session__head h3 {
    margin: 0;
    color: var(--cx-text-strong);
    font-size: var(--app-fs-xl);
    font-weight: 900;
    letter-spacing: -.035em;
}

.cx-session__head p {
    margin: .3rem 0 0;
    color: var(--cx-text-soft);
    line-height: 1.5;
}

.cx-session__body {
    display: grid;
    gap: 1.1rem;
    align-items: center;
}

@container cxsession (min-width: 640px) {
    .cx-session__body {
        grid-template-columns: auto minmax(0, 1fr);
        gap: 1.4rem;
    }

    .cx-session__body > .cx-clock {
        --cx-clock-size: clamp(230px, 42cqi, 300px);
    }

    .cx-session__body > .cx-clock--sm {
        --cx-clock-size: clamp(180px, 34cqi, 220px);
    }
}

/* Lista statystyk sesji z kolorowymi kropkami (Chronexa: tracker-running-stats). */
.cx-session-stats {
    display: grid;
    margin: 0;
    padding: .35rem 1rem;
    border: 1px solid var(--cx-border-strong);
    border-radius: 20px;
    background: var(--cx-inset);
    list-style: none;
}

.cx-session-stat {
    --cx-dot: var(--cx-dot-work);
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    align-items: center;
    gap: .85rem;
    min-height: 46px;
    padding: .6rem 0 .6rem 1.35rem;
    border-bottom: 1px solid var(--cx-border);
}

    .cx-session-stat:last-child {
        border-bottom: 0;
    }

    .cx-session-stat::before {
        content: "";
        position: absolute;
        left: 0;
        top: 50%;
        width: .55rem;
        height: .55rem;
        border-radius: 999px;
        background: var(--cx-dot);
        box-shadow: 0 0 0 5px color-mix(in srgb, var(--cx-dot) 14%, transparent);
        transform: translateY(-50%);
    }

    .cx-session-stat > span {
        color: var(--cx-text-soft);
        font-size: .92rem;
        font-weight: 750;
        white-space: nowrap;
    }

    .cx-session-stat > strong {
        min-width: 0;
        color: var(--cx-text-strong);
        font-weight: 900;
        text-align: right;
        overflow-wrap: anywhere;
    }

.cx-session-stat--start { --cx-dot: var(--cx-dot-start); }
.cx-session-stat--project { --cx-dot: var(--cx-dot-project); }
.cx-session-stat--note { --cx-dot: var(--cx-dot-note); }
.cx-session-stat--type { --cx-dot: var(--cx-dot-type); }
.cx-session-stat--status { --cx-dot: var(--cx-dot-status); }

.cx-session-stat [data-clock-elapsed] {
    font-variant-numeric: tabular-nums;
}

@container cxsession (max-width: 419.98px) {
    .cx-session-stat {
        grid-template-columns: minmax(0, 1fr);
        gap: .15rem;
    }

        .cx-session-stat > strong {
            text-align: left;
        }
}

/* Akcje: „Zakończ i zapisz” (główna) + „Anuluj sesję” pod spodem, pełna szerokość. */
.cx-session-actions {
    display: grid;
    gap: .6rem;
}

    .cx-session-actions > form {
        margin: 0;
    }

    .cx-session-actions .btn {
        width: 100%;
        min-height: 52px;
        border-radius: 16px;
        font-weight: 850;
    }

.cx-session-actions--row {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
}

@container cxsession (max-width: 479.98px) {
    .cx-session-actions--row {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Formularz startu obok bezczynnego zegara. */
.cx-session-form {
    display: grid;
    gap: .9rem;
    min-width: 0;
}

    .cx-session-form .app-field + .app-field {
        margin-top: 0;
    }

    .cx-session-form .cx-session-start {
        width: 100%;
        min-height: 54px;
        border-radius: 16px;
        font-weight: 850;
    }


/* --- Rejestrator: siatka (sesja | ostatnie sesje) + lista ostatnich sesji --- */

.cx-tracker-grid {
    display: grid;
    gap: var(--app-gap);
    align-items: start;
}

/* Dwie kolumny dopiero od 1500px: węższa karta sesji nie mieści zegara obok statystyk. */
@media (min-width: 1500px) {
    .cx-tracker-grid {
        grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
    }
}

.cx-recent {
    display: grid;
    gap: .55rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.cx-recent__item {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: .8rem;
    padding: .75rem .85rem;
    border: 1px solid var(--cx-inset-border);
    border-radius: 16px;
    background: var(--cx-inset);
}

.cx-recent__icon {
    width: 38px;
    height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    background: var(--cx-blue-soft);
    color: var(--cx-blue);
}

.cx-recent__item--commute .cx-recent__icon {
    background: var(--app-warning-bg);
    color: var(--app-warning-fg);
}

.cx-recent__main {
    display: grid;
    gap: .15rem;
    min-width: 0;
}

    .cx-recent__main strong {
        color: var(--cx-text-strong);
        font-weight: 850;
        font-variant-numeric: tabular-nums;
    }

    .cx-recent__main small {
        color: var(--cx-text-soft);
        font-size: var(--app-fs-sm);
        overflow-wrap: anywhere;
    }

/* Czas trwania jako dwa kafelki: godziny i minuty (Chronexa: tracker-duration-breakdown). */
.cx-recent__dur {
    display: inline-flex;
    gap: .3rem;
}

    .cx-recent__dur > span {
        min-width: 44px;
        display: grid;
        justify-items: center;
        gap: .1rem;
        padding: .4rem .45rem;
        border: 1px solid var(--cx-border-strong);
        border-radius: 12px;
        background: var(--cx-panel-soft);
    }

    .cx-recent__dur strong {
        color: var(--cx-text-strong);
        font-weight: 950;
        line-height: 1;
        font-variant-numeric: tabular-nums;
    }

    .cx-recent__dur small {
        color: var(--cx-text-soft);
        font-size: .7rem;
        font-weight: 850;
        line-height: 1;
    }

@media (max-width: 419.98px) {
    .cx-recent__item {
        grid-template-columns: auto minmax(0, 1fr);
    }

    .cx-recent__dur {
        grid-column: 2;
    }
}


/* --- Panel główny: nagłówek (powitanie / aktywna sesja) + szybkie akcje --- */

.cx-home-top {
    container-type: inline-size;
    container-name: cxhome;
    display: grid;
    gap: var(--app-gap);
}

@container cxhome (min-width: 1000px) {
    .cx-home-top__grid {
        grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
    }
}

.cx-home-top__grid {
    display: grid;
    gap: var(--app-gap);
}

.cx-home-hero {
    position: relative;
    overflow: hidden;
    display: grid;
    gap: 1rem;
    min-height: 250px;
    padding: 1.45rem;
    border: 1px solid var(--cx-border-strong);
    border-radius: 22px;
    background: var(--cx-home-hero-bg);
    box-shadow: var(--cx-shadow);
    animation: cx-rise 420ms var(--app-ease) both;
}

    .cx-home-hero::before {
        content: "";
        position: absolute;
        inset: 0;
        background: var(--cx-home-hero-stripe);
        pointer-events: none;
    }

    .cx-home-hero > * {
        position: relative;
        z-index: 1;
    }

@media (min-width: 768px) {
    .cx-home-hero--welcome {
        grid-template-columns: minmax(0, 1fr) 250px;
    }
}

.cx-home-hero__date {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-height: 32px;
    padding: .4rem .8rem;
    border: 1px solid var(--cx-border-strong);
    border-radius: 999px;
    background: var(--cx-home-meta-bg);
    color: var(--cx-text-soft);
    font-size: .84rem;
    font-weight: 800;
}

.cx-home-hero__title {
    margin: .8rem 0 .45rem;
    color: var(--cx-text-strong);
    font-size: clamp(2rem, 4vw, 3.1rem);
    font-weight: 950;
    line-height: .98;
    letter-spacing: -.06em;
    overflow-wrap: anywhere;
}

.cx-home-hero__lead {
    max-width: 58ch;
    margin: 0;
    color: var(--cx-text-soft);
    line-height: 1.55;
}

.cx-home-meta {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    max-width: 640px;
    margin-top: 1.25rem;
    overflow: hidden;
    border: 1px solid var(--cx-border);
    border-radius: 16px;
    background: var(--cx-home-meta-bg);
}

    .cx-home-meta > div {
        display: grid;
        gap: .2rem;
        min-width: 0;
        padding: .8rem .9rem;
        border-right: 1px solid var(--cx-border);
    }

        .cx-home-meta > div:last-child {
            border-right: 0;
        }

    .cx-home-meta span {
        color: var(--cx-text-dim);
        font-size: .76rem;
        font-weight: 750;
    }

    .cx-home-meta strong {
        color: var(--cx-text-strong);
        font-size: .9rem;
        font-weight: 850;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

@media (max-width: 479.98px) {
    .cx-home-meta {
        grid-template-columns: minmax(0, 1fr);
    }

        .cx-home-meta > div {
            border-right: 0;
            border-bottom: 1px solid var(--cx-border);
        }

            .cx-home-meta > div:last-child {
                border-bottom: 0;
            }
}

/* Awatar w kwadracie z zaokrągleniem + dwa neonowe pierścienie (Chronexa: cx-dashboard-portrait). */
.cx-home-visual {
    position: relative;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    min-height: 200px;
}

.cx-home-portrait {
    position: relative;
    z-index: 2;
    width: 168px;
    height: 168px;
}

.cx-home-portrait__frame {
    width: 100%;
    height: 100%;
    overflow: hidden;
    border: 1px solid var(--cx-border-strong);
    border-radius: 44px;
    background: var(--cx-home-portrait-bg);
    box-shadow: var(--cx-shadow-strong);
}

    .cx-home-portrait__frame img {
        display: block;
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

.cx-home-portrait__edit {
    position: absolute;
    right: -8px;
    bottom: -8px;
    border-radius: 999px !important;
    background: var(--cx-panel-2);
    box-shadow: var(--cx-shadow-soft);
}

.cx-home-neon {
    position: absolute;
    right: -.4rem;
    bottom: -2.6rem;
    width: 150px;
    height: 150px;
    border: 16px solid var(--cx-neon);
    border-radius: 999px;
    box-shadow: 0 0 34px var(--cx-neon-glow);
    pointer-events: none;
    animation: cx-float-ring 7s ease-in-out infinite;
}

.cx-home-neon--small {
    right: auto;
    left: -.6rem;
    bottom: -3.8rem;
    width: 104px;
    height: 104px;
    border-width: 13px;
    animation-duration: 9s;
    animation-direction: reverse;
}

@media (max-width: 767.98px) {
    .cx-home-visual {
        order: -1;
        min-height: 0;
        justify-content: flex-start;
    }

    .cx-home-portrait {
        width: 112px;
        height: 112px;
    }

    .cx-home-portrait__frame {
        border-radius: 32px;
    }

    .cx-home-neon {
        display: none;
    }
}

/* Aktywna sesja w nagłówku panelu: mały awatar obok tytułu. */
.cx-home-session__head {
    display: flex;
    align-items: center;
    gap: .85rem;
}

    .cx-home-session__head .cx-home-portrait {
        width: 58px;
        height: 58px;
        flex: 0 0 auto;
    }

    .cx-home-session__head .cx-home-portrait__frame {
        border-radius: 18px;
    }

    .cx-home-session__head .cx-home-portrait__edit {
        right: -10px;
        bottom: -10px;
        transform: scale(.82);
    }

.cx-home-session .cx-session {
    padding: 0;
}

/* Szybkie akcje (Chronexa: cx-dashboard-quick). */
.cx-quick {
    display: grid;
    align-content: start;
    gap: .85rem;
    padding: 1.1rem;
    animation: cx-rise 420ms 80ms var(--app-ease) both;
}

    .cx-quick h3 {
        margin: 0;
        color: var(--cx-text-strong);
        font-size: 1.05rem;
        font-weight: 900;
        letter-spacing: -.035em;
    }

.cx-quick__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: .65rem;
}

.cx-quick__tile {
    --cx-dot: var(--cx-dot-work);
    display: grid;
    justify-items: center;
    align-content: center;
    gap: .3rem;
    min-height: 104px;
    padding: .85rem .6rem;
    border: 1px solid var(--cx-border);
    border-radius: 14px;
    background: var(--cx-inset);
    color: var(--cx-text) !important;
    text-align: center;
    text-decoration: none !important;
    transition: transform var(--app-dur) var(--app-ease), background var(--app-dur) var(--app-ease), border-color var(--app-dur) var(--app-ease);
}

    .cx-quick__tile:hover,
    .cx-quick__tile:focus {
        transform: translateY(-2px);
        border-color: var(--cx-blue-border);
        background: var(--cx-blue-soft);
    }

    .cx-quick__tile i {
        width: 38px;
        height: 38px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border-radius: 14px;
        background: color-mix(in srgb, var(--cx-dot) 15%, transparent);
        color: var(--cx-dot);
    }

    .cx-quick__tile strong {
        margin-top: .15rem;
        color: var(--cx-text-strong);
        font-size: .86rem;
        font-weight: 900;
    }

    .cx-quick__tile small {
        color: var(--cx-text-dim);
        font-size: .74rem;
        font-weight: 700;
    }

.cx-quick__tile--cyan { --cx-dot: var(--cx-dot-start); }
.cx-quick__tile--purple { --cx-dot: var(--cx-dot-project); }
.cx-quick__tile--yellow { --cx-dot: var(--cx-dot-type); }
.cx-quick__tile--violet { --cx-dot: var(--cx-dot-status); }

@keyframes cx-rise {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

@keyframes cx-float-ring {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-8px); }
}

@media (prefers-reduced-motion: reduce) {
    .cx-clock,
    .cx-clock__hand {
        transition: none;
    }

    .cx-clock--live::after,
    .cx-clock--live .cx-clock__label::before,
    .cx-home-neon,
    .cx-home-hero,
    .cx-quick {
        animation: none;
    }

    .cx-quick__tile:hover,
    .cx-quick__tile:focus {
        transform: none;
    }
}

/* Tytuł w nagłówku z aktywną sesją (panel główny). */
.cx-home-session__title {
    margin: 0 0 .3rem;
    color: var(--cx-text-strong);
    font-size: clamp(1.6rem, 2.6vw, 2.3rem);
    font-weight: 950;
    line-height: 1;
    letter-spacing: -.05em;
}

.cx-home-session__copy {
    display: grid;
    gap: .45rem;
    min-width: 0;
}

    .cx-home-session__copy .cx-home-hero__lead {
        margin: 0;
    }


/* =========================================================
   28. TELEFON: ODSTĘP POD PRZYKLEJONYM NAGŁÓWKIEM
   Na telefonie topbar jest osobną kartą (sekcja 8), ale bez marginesu — pierwsza karta
   strony stykała się z nim na każdej stronie. Na komputerze odstęp daje dolny padding
   płaskiego topbaru, więc reguła dotyczy tylko układu mobilnego.
   ========================================================= */
@media (max-width: 767.98px) {
    .app-topbar {
        margin-bottom: .75rem;
    }
}


/* =========================================================
   29. BOCZNE MENU BEZ PASKA PRZEWIJANIA + DUŻE PRZYCISKI-LINKI
   ========================================================= */

/* (a) Duży przycisk zbudowany z linku (<a class="btn app-btn-lg">): min-height bez
       wyśrodkowania stawiał napis przy górnej krawędzi (10px od góry, 28px od dołu),
       a .app-btn-lg nadpisywał kształt pigułki z .app-btn-pill. Przycisk <button>
       wyśrodkowuje treść sam, link — nie; teraz oba wyglądają tak samo. */
.btn.app-btn-lg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.btn.app-btn-pill.app-btn-lg {
    border-radius: var(--cx-radius-pill);
}

/* (b) Boczne menu. Przy 11 pozycjach (widok CEO) treść miała ok. 974px wysokości, więc
       na laptopie zawsze pojawiał się pionowy pasek. Na komputerze z myszą pozycje są
       niższe (36px zamiast 44px dotykowych), a w niskim oknie jeszcze niższe. Pasek jest
       ukryty zawsze — w skrajnie niskim oknie menu nadal przewija się kółkiem myszy.
       Szuflada na telefonie (< 768px, sekcja 8) zostaje bez zmian: tam liczy się duży cel dotyku. */
.app-sidebar__inner {
    scrollbar-width: none;
}

    .app-sidebar__inner::-webkit-scrollbar {
        display: none;
    }

@media (min-width: 768px) {
    .app-sidebar__inner {
        padding: .8rem .75rem;
    }

    .app-sidebar__head {
        padding-bottom: .5rem;
    }

    .app-brand {
        gap: .3rem;
    }

    .app-brand__mark {
        height: 38px;
        padding: 7px 12px;
    }

    .app-brand__client {
        gap: .6rem;
        padding: .35rem .5rem;
    }

    .app-brand__avatar {
        width: 40px;
        height: 40px;
        padding: 4px;
    }

    .app-nav {
        gap: .15rem;
        margin-top: .5rem;
    }

    .app-sidebar__section {
        margin-top: .6rem;
        padding-bottom: .2rem;
    }

    .app-sidebar__actions {
        gap: .4rem;
        padding-top: .6rem;
    }
}

/* Komputer z myszą: rozmiar pozycji zależy od WYSOKOŚCI okna — w wysokim oknie menu jest
   wygodnie duże, w niskim ściśnięte, ale zawsze mieści się bez paska. Kroki zmierzone dla pełnego
   menu CEO (11 pozycji, 2 nagłówki sekcji): naturalna wysokość treści ≤ dolna granica kroku.
   Wysokość wiersza = ikona + 2 × padding + 2px ramki. */
@media (min-width: 768px) and (pointer: fine) {
    .app-sidebar {
        --app-nav-icon: 32px;
        --app-nav-pad: .35rem;
        --app-nav-gap: .25rem;
        --app-nav-fs: 1.03rem;
        --app-nav-glyph: .95rem;
        --app-side-action: 40px;
        --app-side-mark: 44px;
        --app-side-avatar: 46px;
        --app-side-section: .8rem;
    }

    .app-nav {
        gap: var(--app-nav-gap);
    }

    .app-nav__link {
        min-height: 0;
        gap: .65rem;
        padding: var(--app-nav-pad) .6rem;
    }

    .app-nav__icon {
        width: var(--app-nav-icon);
        height: var(--app-nav-icon);
        border-radius: 10px;
    }

        .app-nav__icon i {
            font-size: var(--app-nav-glyph);
        }

    .app-nav__label {
        font-size: var(--app-nav-fs);
    }

    .app-sidebar__section {
        margin-top: var(--app-side-section);
    }

    .app-sidebar__action {
        min-height: var(--app-side-action);
        padding: .35rem .8rem;
    }

    .app-brand__mark {
        height: var(--app-side-mark);
    }

    .app-brand__avatar {
        width: var(--app-side-avatar);
        height: var(--app-side-avatar);
    }
}

@media (min-width: 768px) and (pointer: fine) and (max-height: 899.98px) {
    .app-sidebar {
        --app-nav-icon: 30px;
        --app-nav-pad: .28rem;
        --app-nav-gap: .2rem;
        --app-nav-fs: 1rem;
        --app-nav-glyph: .88rem;
        --app-side-action: 38px;
        --app-side-mark: 40px;
        --app-side-avatar: 42px;
        --app-side-section: .7rem;
    }
}

/* Progi zmierzone 2026-09-29 przy 12 pozycjach (widok CEO, z „Aktywność”): naturalna wysokość
   873 / 801 / 724 / 643px przy wierszach 44 / 40 / 36 / 31px — każdy próg zaczyna się tam, gdzie
   menu mieści się bez paska (810, 730), więc wiersze są możliwie duże. Nowa pozycja = zmierzyć ponownie. */
@media (min-width: 768px) and (pointer: fine) and (max-height: 809.98px) {
    .app-sidebar {
        --app-nav-icon: 28px;
        --app-nav-pad: .22rem;
        --app-nav-gap: .15rem;
        --app-nav-fs: .96rem;
        --app-nav-glyph: .82rem;
        --app-side-action: 35px;
        --app-side-mark: 34px;
        --app-side-avatar: 36px;
        --app-side-section: .5rem;
    }
}

@media (min-width: 768px) and (pointer: fine) and (max-height: 729.98px) {
    .app-sidebar {
        --app-nav-icon: 25px;
        --app-nav-pad: .15rem;
        --app-nav-gap: .1rem;
        --app-nav-fs: .93rem;
        --app-nav-glyph: .78rem;
        --app-side-action: 32px;
        --app-side-mark: 32px;
        --app-side-avatar: 34px;
        --app-side-section: .4rem;
    }
}

/* =========================================================
   30. PRZYCISK W TRAKCIE WYSYŁANIA (.app-btn--pending)
   Ustawiany przez app-ui.js dla <form data-submit-once> (logowanie: „Wyślij kod”,
   „Zaloguj się”, „Wyślij kod ponownie”). Kręciołek rysowany kolorem tekstu przycisku
   (currentColor), więc działa w obu motywach bez nowych kolorów.
   ========================================================= */
@keyframes app-pending-spin {
    to {
        transform: rotate(360deg);
    }
}

button.app-btn--pending,
button.app-btn--pending:disabled {
    cursor: progress;
    opacity: .92;
}

    button.app-btn--pending::before {
        content: "";
        display: inline-block;
        flex: 0 0 auto;
        width: .85em;
        height: .85em;
        margin-right: .45em;
        border: 2px solid currentColor;
        border-top-color: transparent;
        border-radius: 50%;
        vertical-align: -.1em;
        animation: app-pending-spin .7s linear infinite;
    }

form[data-submit-locked] button:disabled {
    cursor: progress;
}

@media (prefers-reduced-motion: reduce) {
    button.app-btn--pending::before {
        animation: none;
    }
}


/* =========================================================
   31. ZMIANY „BYŁO → JEST” (.app-changes)
   Historia projektu i Aktywność firmy: każda zmieniona wartość w osobnej linii.
   ========================================================= */
.app-changes {
    list-style: none;
    margin: .2rem 0 0;
    padding: 0;
    font-size: var(--app-fs-sm);
}

    .app-changes li + li {
        margin-top: .15rem;
    }

.app-changes__field {
    color: var(--cx-text-soft);
    font-weight: 600;
}


/* =========================================================
   32. POWŁOKA PO ZALOGOWANIU — WYGLĄD LEWKE (2026-10-01)
   Zatwierdzony projekt (canvas „Lewke Portal Redesign”, strona „Czas pracy”):
   płaskie tło --cx-auth-*, ciemne menu boczne w obu motywach (--cx-brand-*),
   złoty akcent --cx-gold-*, nagłówki Jost, tekst Figtree (sekcja 4).
   Tylko wygląd — znaczniki, warunki widoczności i skrypty menu bez zmian.
   ========================================================= */

body {
    background: var(--cx-auth-bg);
    font-family: var(--cx-font-text);
}

/* --- Menu boczne (laptop) i szuflada (telefon) ------------------- */
.app-sidebar__inner {
    border-right: 0;
    background: var(--cx-brand-ink);
    box-shadow: none;
    backdrop-filter: none;
    color: var(--cx-brand-text);
}

.app-sidebar__head {
    border-bottom-color: var(--cx-brand-ink-2);
}

.app-brand.app-brand--lw {
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--cx-brand-text) !important;
}

.app-brand__lw {
    flex-shrink: 0;
    width: 46px;
    height: 46px;
    --lw-frame: 6;
    --lw-letter: 7;
}

.app-brand__lwtext {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

    .app-brand__lwtext strong {
        color: var(--cx-brand-text);
        font-family: var(--cx-font-display);
        font-size: 16px;
        font-weight: 500;
        line-height: 1.1;
    }


.app-sidebar__close {
    border-color: var(--cx-brand-ink-2);
    background: transparent;
    color: var(--cx-brand-soft) !important;
}

.app-sidebar__section {
    color: var(--cx-brand-dim);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .16em;
}

.app-nav__link {
    border-color: transparent;
    border-radius: 12px;
    color: var(--cx-brand-soft) !important;
}

    .app-nav__link:hover,
    .app-nav__link:focus {
        border-color: transparent;
        background: var(--cx-brand-hover);
        color: var(--cx-brand-text) !important;
    }

    .app-nav__link.active {
        border-color: transparent;
        background: var(--cx-brand-ink-2);
        box-shadow: inset 3px 0 0 var(--cx-gold);
        color: var(--cx-brand-text) !important;
    }

.app-nav__icon {
    width: 28px;
    height: 28px;
    border: 0;
    background: transparent;
    color: inherit;
}

.app-nav__link.active .app-nav__icon {
    background: transparent;
    color: var(--cx-gold);
}

.app-nav__label {
    font-size: 14px;
    font-weight: 600;
}

.app-sidebar__actions {
    border-top-color: var(--cx-brand-ink-2);
}

.app-sidebar__action {
    border-color: var(--cx-brand-ink-2);
    background: transparent;
    color: var(--cx-brand-soft) !important;
}

    .app-sidebar__action:hover,
    .app-sidebar__action:focus {
        border-color: var(--cx-brand-ink-2);
        background: var(--cx-brand-hover);
        color: var(--cx-brand-text) !important;
    }

.app-sidebar__action--accent,
.app-sidebar__action--accent:hover,
.app-sidebar__action--accent:focus {
    border-color: var(--cx-brand-gold-line);
    background: transparent;
    color: var(--cx-gold) !important;
    filter: none;
}

    .app-sidebar__action--accent:hover,
    .app-sidebar__action--accent:focus {
        background: var(--cx-brand-hover);
    }

/* Podpis dostawcy na samym dole menu: „Dostarcza” + logotyp Alcaeus, jak na ekranie
   startowym — krótka złota kreska nad nim, przygaszony, jaśnieje po najechaniu. */
.app-sidebar__by {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 9px;
    margin-top: 14px;
    padding-top: 14px;
    background: linear-gradient(var(--cx-brand-gold-line), var(--cx-brand-gold-line)) top center / 32px 1px no-repeat;
}

    .app-sidebar__by span {
        color: var(--cx-brand-dim);
        font-size: 10px;
        font-weight: 600;
        letter-spacing: .24em;
        text-transform: uppercase;
    }

    .app-sidebar__by img {
        display: block;
        width: 132px;
        height: auto;
        opacity: .55;
        transition: opacity var(--app-dur) var(--app-ease);
    }

    .app-sidebar__by:hover img {
        opacity: .9;
    }

/* Niskie okno komputera: podpis ściśnięty, żeby menu nadal mieściło się bez paska. */
@media (min-width: 768px) and (pointer: fine) and (max-height: 809.98px) {
    .app-sidebar__by {
        gap: 6px;
        margin-top: 8px;
        padding-top: 9px;
    }

        .app-sidebar__by img {
            width: 112px;
        }
}

@media (min-width: 768px) and (pointer: fine) and (max-height: 729.98px) {
    .app-sidebar__by span {
        display: none;
    }
}

/* --- Pasek tytułu --------------------------------------------------- */
.app-shell:not(.app-shell--bare) .app-topbar__title {
    color: var(--cx-auth-text);
    font-family: var(--cx-font-display);
    font-size: 26px;
    font-weight: 500;
    letter-spacing: 0;
}

.app-topbar .app-eyebrow {
    color: var(--cx-auth-dim);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .18em;
    text-transform: uppercase;
}

.app-topbar .app-topbar__icon {
    width: 44px;
    height: 44px;
    min-width: 44px;
    border-color: var(--cx-auth-line);
    border-radius: 22px;
    background: var(--cx-auth-surface);
    color: var(--cx-auth-text) !important;
}

    .app-topbar .app-topbar__icon:hover,
    .app-topbar .app-topbar__icon:focus {
        border-color: var(--cx-auth-line-2);
        background: var(--cx-auth-surface-2);
    }

.app-footer {
    border-top-color: var(--cx-auth-line);
    color: var(--cx-auth-dim);
}

@media (max-width: 767.98px) {
    .app-sidebar__inner {
        border-color: var(--cx-brand-ink-2);
    }

    .app-shell:not(.app-shell--bare) .app-topbar {
        border-color: var(--cx-auth-line);
        border-radius: 18px;
        background: var(--cx-auth-surface);
        box-shadow: none;
        backdrop-filter: none;
    }

    .app-shell:not(.app-shell--bare) .app-topbar__title {
        font-size: 20px;
        font-weight: 500;
        letter-spacing: 0;
    }
}


/* =========================================================
   33. PANEL GŁÓWNY + PRZEGLĄD EWIDENCJI CZASU — WYGLĄD LEWKE (2026-10-01)
   Pages/Index.cshtml i Pages/TimeEntry/Review.cshtml. Klasy .cx-lw-*.
   Zegar sesji to nadal .cx-clock z sekcji 27 (ten sam mechanizm w app-ui.js:
   pełny obrót = 1 minuta, kropka na czele, „oddychająca” poświata) —
   .cx-clock--lw podmienia tylko kolory, .cx-clock--mini to mała wersja
   przy trwającej sesji na liście wpisów.
   ========================================================= */

.cx-lw-card {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 18px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 22px;
    background: var(--cx-auth-surface);
    color: var(--cx-auth-text);
}

.cx-lw-h2 {
    margin: 0;
    color: var(--cx-auth-text);
    font-family: var(--cx-font-display);
    font-size: 25px;
    font-weight: 500;
    line-height: 1.15;
}

.cx-lw-h2--lg {
    font-size: 30px;
}

.cx-lw-h3 {
    margin: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--cx-auth-text);
    font-size: 16px;
    font-weight: 800;
}

.cx-lw-lead {
    margin: 0;
    color: var(--cx-auth-soft);
    font-size: 15px;
    line-height: 1.5;
}

.cx-lw-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.cx-lw-chip {
    min-height: 30px;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 0 12px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 15px;
    background: var(--cx-auth-surface-2);
    color: var(--cx-auth-soft);
    font-size: 13px;
    font-weight: 700;
}

.cx-lw-chip--gold {
    align-self: flex-start;
    border-color: var(--cx-gold-line);
    background: var(--cx-gold-soft);
    color: var(--cx-gold-text);
}

.cx-lw-badges {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

.cx-lw-badge {
    min-height: 28px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0 10px;
    border-radius: 9px;
    background: var(--cx-auth-surface-3);
    color: var(--cx-auth-soft);
    font-size: 13px;
    font-weight: 700;
    white-space: nowrap;
}

.cx-lw-badge--ok {
    background: var(--cx-lw-ok-soft);
    color: var(--cx-lw-ok);
}

.cx-lw-badge--bad {
    background: var(--cx-lw-bad-soft);
    color: var(--cx-lw-bad);
}

.cx-lw-badge--info {
    background: var(--cx-lw-info-soft);
    color: var(--cx-lw-info);
}

.cx-lw-dim {
    color: var(--cx-auth-dim);
    font-weight: 600;
}

/* --- Przyciski (tylko na tych stronach; .btn z Bootstrapa zostaje bazą) --- */
.btn.cx-lw-btn {
    min-height: 46px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 0 18px;
    border: 1px solid transparent;
    border-radius: 14px;
    font-size: 15px;
    font-weight: 700;
}

.btn.cx-lw-btn--lg {
    min-height: 54px;
    border-radius: 16px;
}

.btn.cx-lw-btn--block {
    width: 100%;
}

.btn.cx-lw-btn--gold,
.btn.cx-lw-btn--gold:hover,
.btn.cx-lw-btn--gold:focus {
    background: var(--cx-gold);
    color: var(--cx-gold-ink);
}

    .btn.cx-lw-btn--gold:hover {
        background: var(--cx-gold-hover);
    }

.btn.cx-lw-btn--ghost,
.btn.cx-lw-btn--ghost:hover,
.btn.cx-lw-btn--ghost:focus {
    border-color: var(--cx-auth-line-2);
    background: var(--cx-auth-surface);
    color: var(--cx-auth-text);
}

    .btn.cx-lw-btn--ghost:hover {
        background: var(--cx-auth-surface-2);
    }

.btn.cx-lw-btn--warn,
.btn.cx-lw-btn--warn:hover,
.btn.cx-lw-btn--warn:focus {
    border-color: var(--cx-lw-warn-line);
    background: var(--cx-lw-warn-soft);
    color: var(--cx-lw-warn);
}

.btn.cx-lw-btn--danger,
.btn.cx-lw-btn--danger:hover,
.btn.cx-lw-btn--danger:focus {
    background: var(--cx-lw-bad-solid);
    color: var(--cx-lw-bad-ink);
}

.btn.cx-lw-btn--success,
.btn.cx-lw-btn--success:hover,
.btn.cx-lw-btn--success:focus {
    background: var(--cx-lw-ok-solid);
    color: var(--cx-lw-ok-ink);
}

.btn.cx-lw-btn:focus {
    box-shadow: 0 0 0 4px var(--cx-gold-ring);
}

.btn.cx-lw-btn:active {
    transform: scale(.98);
}

/* --- Nagłówek panelu ---------------------------------------------- */
.cx-lw-top {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
}

.cx-lw-hero {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: 20px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 24px;
    background: var(--cx-auth-surface);
    box-shadow: inset 0 3px 0 var(--cx-gold);
    color: var(--cx-auth-text);
    animation: lw-in .55s var(--splash-ease) both;
}

    .cx-lw-hero > * {
        position: relative;
    }

    .cx-lw-hero > .cx-lw-hero__ghost {
        position: absolute;
        top: -60px;
        right: -70px;
        width: 260px;
        height: 260px;
        opacity: .08;
        pointer-events: none;
        --lw-frame: 1;
    }

.cx-lw-hero__head {
    display: flex;
    align-items: center;
    gap: 18px;
}

.cx-lw-hero__copy {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.cx-lw-portrait {
    position: relative;
    flex-shrink: 0;
    width: 76px;
    height: 76px;
}

.cx-lw-portrait__frame {
    width: 100%;
    height: 100%;
    overflow: hidden;
    border: 2px solid var(--cx-gold-line);
    border-radius: 22px;
    background: var(--cx-auth-surface-2);
}

    .cx-lw-portrait__frame img {
        display: block;
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

.cx-lw-portrait__edit {
    position: absolute;
    right: -8px;
    bottom: -8px;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 2px solid var(--cx-auth-surface);
    border-radius: 17px;
    background: var(--cx-auth-ink);
    color: var(--cx-gold-text);
    font-size: 13px;
    cursor: pointer;
}

:root[data-theme="dark"] .cx-lw-portrait__edit {
    color: var(--cx-gold);
}

.cx-lw-portrait--big {
    width: 116px;
    height: 116px;
    justify-self: center;
}

    .cx-lw-portrait--big .cx-lw-portrait__frame {
        border-radius: 30px;
    }

.cx-lw-sess {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: center;
    gap: 18px;
}

.cx-lw-welcome {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: center;
    gap: 18px;
}

.cx-lw-welcome__copy {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.cx-lw-meta {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
}

    .cx-lw-meta > div {
        min-width: 0;
        padding: 10px 12px;
        border: 1px solid var(--cx-auth-line);
        border-radius: 14px;
        background: var(--cx-auth-surface-2);
    }

    .cx-lw-meta span {
        display: block;
        color: var(--cx-auth-dim);
        font-size: 12px;
        font-weight: 600;
    }

    .cx-lw-meta strong {
        display: block;
        margin-top: 3px;
        overflow: hidden;
        color: var(--cx-auth-text);
        font-size: 14px;
        font-weight: 800;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

.cx-lw-stats {
    min-width: 0;
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 4px 14px;
    list-style: none;
    border: 1px solid var(--cx-auth-line);
    border-radius: 18px;
    background: var(--cx-auth-surface-2);
}

    .cx-lw-stats li {
        min-height: 46px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        padding: 6px 0;
        border-top: 1px solid var(--cx-auth-line);
        font-size: 14px;
    }

        .cx-lw-stats li:first-child {
            border-top: 0;
        }

        .cx-lw-stats li > span {
            flex-shrink: 0;
            display: flex;
            align-items: center;
            gap: 10px;
            color: var(--cx-auth-soft);
            font-weight: 600;
        }

            .cx-lw-stats li > span::before {
                content: "";
                width: 8px;
                height: 8px;
                border-radius: 4px;
                background: var(--cx-lw-dot, var(--cx-gold));
            }

        .cx-lw-stats li > strong {
            min-width: 0;
            color: var(--cx-auth-text);
            font-weight: 800;
            font-variant-numeric: tabular-nums;
            overflow-wrap: anywhere;
            text-align: right;
        }

    .cx-lw-stats .is-1 { --cx-lw-dot: var(--cx-lw-dot-1); }
    .cx-lw-stats .is-2 { --cx-lw-dot: var(--cx-lw-dot-2); }
    .cx-lw-stats .is-3 { --cx-lw-dot: var(--cx-lw-dot-3); }
    .cx-lw-stats .is-4 { --cx-lw-dot: var(--cx-lw-dot-4); }
    .cx-lw-stats .is-5 { --cx-lw-dot: var(--cx-lw-dot-5); }
    .cx-lw-stats .is-6 { --cx-lw-dot: var(--cx-lw-dot-6); }

.cx-lw-2btn {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}

    .cx-lw-2btn form {
        margin: 0;
    }

/* Zegar sesji w kolorach Lewke (mechanika: sekcja 27 + app-ui.js). */
.cx-clock.cx-clock--lw {
    --cx-clock-from: var(--cx-lw-clock-a);
    --cx-clock-to: var(--cx-lw-clock-b);
    --cx-clock-track: var(--cx-lw-clock-track);
    --cx-clock-core: var(--cx-auth-surface-2);
    --cx-clock-core-border: var(--cx-auth-line);
    --cx-clock-shadow: var(--cx-lw-clock-shadow);
    --cx-clock-halo: var(--cx-lw-clock-halo);
    --cx-clock-hand: var(--cx-lw-hand);
    --cx-clock-text-glow: none;
}

    .cx-clock.cx-clock--lw::before {
        inset: 11%;
        background: var(--cx-auth-surface);
    }

    .cx-clock.cx-clock--lw .cx-clock__core {
        width: 68%;
    }

    .cx-clock.cx-clock--lw .cx-clock__label {
        color: var(--cx-auth-soft);
        letter-spacing: .14em;
    }

    /* Rozmiar cyfr liczony od średnicy zegara — „00:00:00” zawsze mieści się w środku tarczy
       (stały clamp(…3.5rem) był szerszy niż rdzeń zegara 260px w Rejestratorze). */
    .cx-clock.cx-clock--lw .cx-clock__time {
        color: var(--cx-auth-text);
        font-family: var(--cx-font-display);
        font-size: calc(var(--cx-clock-size) * .148);
        font-weight: 500;
        letter-spacing: -.01em;
        white-space: nowrap;
    }

.cx-clock.cx-clock--mini {
    --cx-clock-size: 44px;
    box-shadow: none;
}

    .cx-clock.cx-clock--mini::before {
        inset: 17%;
    }

    .cx-clock.cx-clock--mini .cx-clock__hand {
        left: 42%;
        width: 16%;
    }

        .cx-clock.cx-clock--mini .cx-clock__hand::before {
            top: 8.5%;
            width: 90%;
            box-shadow: 0 0 0 2px var(--cx-clock-halo);
        }

    .cx-clock.cx-clock--mini.cx-clock--live::after {
        inset: -3px;
    }

/* --- Szybkie akcje ------------------------------------------------- */
.cx-lw-quick {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
}

.cx-lw-tile {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 14px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 18px;
    background: var(--cx-auth-surface-2);
    color: var(--cx-auth-text) !important;
    text-decoration: none !important;
    transition: transform .15s ease, border-color .2s ease;
}

    .cx-lw-tile:hover,
    .cx-lw-tile:focus {
        border-color: var(--cx-auth-line-2);
        transform: translateY(-2px);
    }

    .cx-lw-tile strong {
        font-size: 15px;
        font-weight: 800;
        line-height: 1.2;
    }

    .cx-lw-tile small {
        color: var(--cx-auth-dim);
        font-size: 12px;
    }

.cx-lw-tile__icon {
    width: 38px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    background: var(--cx-lw-tile-bg);
    color: var(--cx-lw-tile-fg);
    font-size: 17px;
}

.cx-lw-tile--gold { --cx-lw-tile-bg: var(--cx-gold-soft); --cx-lw-tile-fg: var(--cx-gold-text); }
.cx-lw-tile--yellow { --cx-lw-tile-bg: var(--cx-lw-warn-soft); --cx-lw-tile-fg: var(--cx-lw-warn); }
.cx-lw-tile--violet { --cx-lw-tile-bg: var(--cx-lw-vio-soft); --cx-lw-tile-fg: var(--cx-lw-vio); }
.cx-lw-tile--cyan { --cx-lw-tile-bg: var(--cx-lw-teal-soft); --cx-lw-tile-fg: var(--cx-lw-teal); }
.cx-lw-tile--purple { --cx-lw-tile-bg: var(--cx-lw-rose-soft); --cx-lw-tile-fg: var(--cx-lw-rose); }

/* --- Filtry ---------------------------------------------------------- */
.cx-lw-form {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
    gap: 12px;
}

.cx-lw-field {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.cx-lw-field--full {
    grid-column: 1 / -1;
}

.cx-lw-field--end {
    align-self: end;
}

.cx-lw-label {
    margin: 0;
    color: var(--cx-auth-soft);
    font-size: 13px;
    font-weight: 700;
}

.cx-lw-help {
    color: var(--cx-auth-dim);
    font-size: 12px;
    line-height: 1.4;
}

.cx-lw-card .form-control.cx-lw-input,
.cx-lw-hero .form-control.cx-lw-input,
.cx-lw-modal .form-control.cx-lw-input {
    height: 48px;
    min-height: 48px;
    padding: 0 14px;
    border: 1.5px solid var(--cx-auth-line-2);
    border-radius: 12px;
    background: var(--cx-auth-surface);
    color: var(--cx-auth-text);
    font-size: 16px;
    box-shadow: none;
    transition: border-color .2s, box-shadow .2s;
}

    .cx-lw-card .form-control.cx-lw-input:focus,
    .cx-lw-hero .form-control.cx-lw-input:focus,
    .cx-lw-modal .form-control.cx-lw-input:focus {
        border-color: var(--cx-gold);
        background: var(--cx-auth-surface);
        box-shadow: 0 0 0 4px var(--cx-gold-ring);
        color: var(--cx-auth-text);
    }

    .cx-lw-card .form-control.cx-lw-input::placeholder,
    .cx-lw-hero .form-control.cx-lw-input::placeholder,
    .cx-lw-modal .form-control.cx-lw-input::placeholder {
        color: var(--cx-auth-dim);
    }

    .cx-lw-card .form-control.cx-lw-input.is-invalid,
    .cx-lw-hero .form-control.cx-lw-input.is-invalid {
        border-color: var(--app-danger-solid);
    }

/* Strzałka listy rozwijanej jako obramowanie w kolorze tokenu (bez obrazka). */
.cx-lw-select {
    position: relative;
}

    .cx-lw-select select.form-control {
        padding-right: 40px;
        appearance: none;
        -webkit-appearance: none;
        cursor: pointer;
    }

    .cx-lw-select::after {
        content: "";
        position: absolute;
        top: 50%;
        right: 17px;
        width: 8px;
        height: 8px;
        margin-top: -6px;
        border-right: 2px solid var(--cx-auth-dim);
        border-bottom: 2px solid var(--cx-auth-dim);
        transform: rotate(45deg);
        pointer-events: none;
    }

.cx-lw-check {
    min-height: 48px;
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    color: var(--cx-auth-soft);
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
}

    .cx-lw-check input {
        width: 20px;
        height: 20px;
        margin: 0;
        accent-color: var(--cx-gold);
    }

/* --- Liczniki -------------------------------------------------------- */
.cx-lw-kpis {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
}

.cx-lw-kpi {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 16px 18px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 20px;
    background: var(--cx-auth-surface);
}

.cx-lw-kpi__label {
    padding-right: 52px;
    color: var(--cx-auth-soft);
    font-size: 13px;
    font-weight: 700;
}

.cx-lw-kpi__value {
    color: var(--cx-auth-text);
    font-family: var(--cx-font-display);
    font-size: 30px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.cx-lw-kpi__meta {
    color: var(--cx-auth-dim);
    font-size: 12px;
}

.cx-lw-kpi__icon {
    position: absolute;
    top: 16px;
    right: 16px;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    background: var(--cx-lw-tile-bg);
    color: var(--cx-lw-tile-fg);
    font-size: 17px;
}

.cx-lw-kpi--ok { --cx-lw-tile-bg: var(--cx-lw-ok-soft); --cx-lw-tile-fg: var(--cx-lw-ok); }
.cx-lw-kpi--info { --cx-lw-tile-bg: var(--cx-lw-info-soft); --cx-lw-tile-fg: var(--cx-lw-info); }
.cx-lw-kpi--warn { --cx-lw-tile-bg: var(--cx-lw-warn-soft); --cx-lw-tile-fg: var(--cx-lw-warn); }

/* --- Wpisy ----------------------------------------------------------- */
.cx-lw-feed {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.cx-lw-entry {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 16px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 20px;
    background: var(--cx-auth-surface);
    color: var(--cx-auth-text);
}

.cx-lw-entry--live {
    border-color: var(--cx-gold-line);
    box-shadow: inset 0 3px 0 var(--cx-gold);
}

.cx-lw-entry--alert {
    border-color: var(--cx-lw-bad-line);
    background: var(--cx-lw-bad-soft);
}

.cx-lw-entry__head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

.cx-lw-entry__title {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 12px;
}

    .cx-lw-entry__title p {
        margin: 0;
    }

.cx-lw-entry__name {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--cx-auth-text);
    font-size: 16px;
    font-weight: 800;
}

.cx-lw-entry__sub {
    margin-top: 3px !important;
    color: var(--cx-auth-soft);
    font-size: 13px;
}

    .cx-lw-entry__sub strong {
        color: var(--cx-auth-text);
        font-weight: 700;
    }

.cx-lw-live-dot {
    flex-shrink: 0;
    width: 9px;
    height: 9px;
    border-radius: 5px;
    background: var(--cx-auth-ok);
    animation: lw-dot 1.6s ease-in-out infinite;
}

.cx-lw-readouts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px 16px;
}

.cx-lw-readout--wide {
    grid-column: 1 / -1;
}

.cx-lw-readout__k {
    display: block;
    color: var(--cx-auth-dim);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.cx-lw-readout__v {
    margin: 4px 0 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    color: var(--cx-auth-text);
    font-size: 14px;
    font-weight: 600;
    overflow-wrap: anywhere;
}

    .cx-lw-readout__v a {
        color: var(--cx-gold-text);
        font-weight: 700;
    }

.cx-lw-warn {
    color: var(--cx-lw-bad);
    font-weight: 800;
    cursor: help;
}

.cx-lw-entry__actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}

    .cx-lw-entry__actions--one {
        grid-template-columns: minmax(0, 1fr);
    }

    .cx-lw-entry__actions .delete-form {
        display: flex;
        margin: 0;
    }

        .cx-lw-entry__actions .delete-form > .btn {
            width: 100%;
        }

/* --- Stronicowanie (te same linki Bootstrapa, inne kolory) ------------- */
.app-pagebar.cx-lw-pagebar {
    margin-top: 0;
    padding: 14px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 18px;
    background: var(--cx-auth-surface);
    color: var(--cx-auth-soft);
}

    .app-pagebar.cx-lw-pagebar .btn-sm,
    .app-pagebar.cx-lw-pagebar .page-link {
        min-width: 36px;
        height: 36px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding: 0 10px;
        border: 1px solid var(--cx-auth-line);
        border-radius: 10px !important;
        background: var(--cx-auth-surface-2);
        color: var(--cx-auth-text);
        font-weight: 700;
        box-shadow: none;
    }

    .app-pagebar.cx-lw-pagebar .pagination {
        gap: 6px;
    }

    .app-pagebar.cx-lw-pagebar .btn-secondary,
    .app-pagebar.cx-lw-pagebar .page-item.active .page-link {
        border-color: var(--cx-auth-ink);
        background: var(--cx-auth-ink);
        color: var(--cx-auth-ink-text);
    }

:root[data-theme="dark"] .app-pagebar.cx-lw-pagebar .btn-secondary,
:root[data-theme="dark"] .app-pagebar.cx-lw-pagebar .page-item.active .page-link {
    border-color: var(--cx-gold);
    background: var(--cx-gold);
    color: var(--cx-gold-ink);
}

.app-pagebar.cx-lw-pagebar .page-item.disabled .page-link {
    opacity: .45;
}

.app-pagebar.cx-lw-pagebar strong {
    color: var(--cx-auth-text);
}

/* --- Pusty stan --------------------------------------------------------- */
.cx-lw-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 44px 16px;
    border: 1.5px dashed var(--cx-auth-line-2);
    border-radius: 22px;
    color: var(--cx-auth-soft);
    font-size: 15px;
    text-align: center;
}

    .cx-lw-empty p {
        margin: 0;
    }

.cx-lw-empty__icon {
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 28px;
    background: var(--cx-auth-surface-2);
    color: var(--cx-auth-dim);
    font-size: 22px;
}

/* --- Wykres (Przegląd) ---------------------------------------------- */
.cx-lw-chart-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.cx-lw-chart-head__left {
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

.nav.cx-lw-tabs {
    display: inline-flex;
    flex-wrap: nowrap;
    gap: 4px;
    margin: 0;
    padding: 4px;
    border: 0;
    border-radius: 12px;
    background: var(--cx-auth-surface-3);
}

    .nav.cx-lw-tabs .nav-link {
        height: 34px;
        display: inline-flex;
        align-items: center;
        gap: 6px;
        padding: 0 12px;
        border: 0;
        border-radius: 9px;
        background: transparent;
        color: var(--cx-auth-soft);
        font-size: 13px;
        font-weight: 700;
    }

        .nav.cx-lw-tabs .nav-link.active {
            background: var(--cx-auth-surface);
            color: var(--cx-auth-text);
            box-shadow: var(--cx-lw-shadow-pop);
        }

    /* Sekcja 13 ustawia zakładki z !important — tu wygrywa ta sama waga i wyższa szczegółowość. */
    .cx-lw-tabs.app-tabs.nav .app-tab-link.nav-link {
        border: 0 !important;
        background: transparent !important;
        color: var(--cx-auth-soft) !important;
    }

        .cx-lw-tabs.app-tabs.nav .app-tab-link.nav-link:hover,
        .cx-lw-tabs.app-tabs.nav .app-tab-link.nav-link:focus {
            background: var(--cx-auth-surface-2) !important;
            color: var(--cx-auth-text) !important;
        }

        .cx-lw-tabs.app-tabs.nav .app-tab-link.nav-link.active {
            background: var(--cx-auth-surface) !important;
            color: var(--cx-auth-text) !important;
        }

/* --- Okna (Bootstrap 4: te same data-toggle / data-dismiss) ----------- */
.modal-content.cx-lw-modal {
    overflow: hidden;
    border: 1px solid var(--cx-auth-line);
    border-radius: 24px;
    background: var(--cx-auth-surface);
    color: var(--cx-auth-text);
}

    .modal-content.cx-lw-modal .modal-header {
        align-items: center;
        padding: 18px 20px 10px;
        border-bottom: 0;
        background: transparent;
    }

    .modal-content.cx-lw-modal .modal-title {
        color: var(--cx-auth-text);
        font-family: var(--cx-font-display);
        font-size: 21px;
        font-weight: 500;
    }

    .modal-content.cx-lw-modal .close {
        width: 40px;
        height: 40px;
        margin: 0 0 0 auto;
        padding: 0;
        border: 1px solid var(--cx-auth-line);
        border-radius: 20px;
        background: var(--cx-auth-surface);
        color: var(--cx-auth-text);
        opacity: 1;
        text-shadow: none;
    }

    .modal-content.cx-lw-modal .modal-body {
        display: flex;
        flex-direction: column;
        gap: 12px;
        padding: 6px 20px 16px;
        color: var(--cx-auth-text);
        font-size: 15px;
        line-height: 1.55;
    }

    .modal-content.cx-lw-modal .modal-footer {
        gap: 10px;
        padding: 14px 20px 20px;
        border-top: 1px solid var(--cx-auth-line);
        background: transparent;
    }

        .modal-content.cx-lw-modal .modal-footer > * {
            margin: 0;
        }

.cx-lw-avatars {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
}

.cx-lw-avatar {
    min-height: 44px;
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0;
    padding: 8px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 14px;
    background: var(--cx-auth-surface-2);
    cursor: pointer;
}

    .cx-lw-avatar:hover {
        border-color: var(--cx-auth-line-2);
    }

    .cx-lw-avatar:has(input:checked) {
        border-color: var(--cx-gold);
        box-shadow: 0 0 0 3px var(--cx-gold-ring);
    }

    .cx-lw-avatar input[type="radio"] {
        flex-shrink: 0;
        width: 18px;
        height: 18px;
        margin: 0 2px 0 4px;
        accent-color: var(--cx-gold);
    }

    .cx-lw-avatar img {
        flex-shrink: 0;
        width: 52px;
        height: 52px;
        border-radius: 12px;
        object-fit: cover;
    }

    .cx-lw-avatar strong {
        display: block;
        color: var(--cx-auth-text);
        font-size: 14px;
        font-weight: 800;
    }

    .cx-lw-avatar small {
        color: var(--cx-auth-dim);
        font-size: 12px;
    }

.cx-lw-in-2 { animation: lw-in .55s var(--splash-ease) .06s both; }
.cx-lw-in-3 { animation: lw-in .55s var(--splash-ease) .12s both; }

@keyframes lw-in {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }
}

@keyframes lw-dot {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: .45; transform: scale(.8); }
}

@media (max-width: 479.98px) {
    .cx-lw-2btn {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (min-width: 576px) {
    .cx-lw-avatars {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1200px) {
    .cx-lw-form {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

@media (min-width: 768px) {
    .cx-lw-field--full {
        grid-column: auto;
    }

    .cx-lw-field--lastcol {
        grid-column: -2 / -1;
    }

    .cx-lw-kpis {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 14px;
    }

    .cx-lw-readouts {
        grid-template-columns: 2fr 1.2fr 1fr 1fr;
    }

    .cx-lw-readouts--six {
        grid-template-columns: 2fr 1.3fr 1.2fr;
    }

    .cx-lw-readout--wide {
        grid-column: auto;
    }

    .cx-lw-entry__actions,
    .cx-lw-entry__actions--one {
        display: flex;
        justify-content: flex-end;
    }
}

@media (min-width: 992px) {
    .cx-lw-sess {
        grid-template-columns: auto minmax(0, 1fr);
        gap: 24px;
    }

    .cx-lw-welcome {
        grid-template-columns: minmax(0, 1fr) auto;
    }
}

@media (min-width: 1200px) {
    .cx-lw-top {
        grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr);
    }

    .cx-lw-readouts--six {
        grid-template-columns: 2fr 1.3fr 1.2fr 1.2fr 1fr 1.1fr;
    }
}

@media (prefers-reduced-motion: reduce) {
    .cx-lw-hero,
    .cx-lw-in-2,
    .cx-lw-in-3,
    .cx-lw-live-dot {
        animation: none;
    }

    .cx-lw-tile {
        transition: none;
    }
}


/* =========================================================
   34. REJESTRATOR CZASU — WYGLĄD LEWKE (2026-10-01)
   Pages/TimeEntry/Tracker.cshtml. Korzysta z klas sekcji 33 (karta, zegar --lw,
   lista szczegółów, przyciski); tutaj tylko elementy tej strony.
   ========================================================= */

.cx-lw-tracker {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: 14px;
}

.cx-lw-card__head {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.cx-lw-session-form {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* Wybór projektu (działy inne niż Biuro): ten sam btn-group-toggle Bootstrapa
   (radio w etykiecie .btn), inny wygląd. */
.cx-lw-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

    .cx-lw-picker .btn.cx-lw-pick {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        margin: 0;
        padding: 8px 14px;
        border: 1.5px solid var(--cx-auth-line-2);
        border-radius: 12px;
        background: var(--cx-auth-surface);
        color: var(--cx-auth-text);
        font-size: 14px;
        font-weight: 600;
        text-align: left;
        white-space: normal;
    }

        .cx-lw-picker .btn.cx-lw-pick:hover {
            border-color: var(--cx-gold-line);
            background: var(--cx-auth-surface-2);
        }

        .cx-lw-picker .btn.cx-lw-pick.focus,
        .cx-lw-picker .btn.cx-lw-pick:focus-within {
            box-shadow: 0 0 0 4px var(--cx-gold-ring);
        }

        .cx-lw-picker .btn.cx-lw-pick.active {
            border-color: var(--cx-gold);
            background: var(--cx-gold);
            color: var(--cx-gold-ink);
            font-weight: 700;
        }

.cx-lw-note {
    padding: 11px 13px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 12px;
    background: var(--cx-auth-surface-2);
    color: var(--cx-auth-text);
    font-size: 14px;
    line-height: 1.5;
}

/* Przełącznik „Dojazd do pracy” (sekcja 27) w kolorach Lewke. */
.cx-lw-card .cx-switch-card {
    min-height: 56px;
    padding: 12px 14px;
    border-color: var(--cx-auth-line);
    border-radius: 16px;
    background: var(--cx-auth-surface-2);
}

    .cx-lw-card .cx-switch-card:hover {
        border-color: var(--cx-auth-line-2);
        background: var(--cx-auth-surface-2);
    }

.cx-lw-card .cx-switch-ui {
    border-color: var(--cx-auth-line-2);
    background: var(--cx-auth-surface-3);
}

    .cx-lw-card .cx-switch-ui::before {
        background: var(--cx-lw-hand);
    }

.cx-lw-card .cx-switch-input:checked ~ .cx-switch-ui {
    border-color: var(--cx-gold);
    background: var(--cx-gold);
}

.cx-lw-card .cx-switch-input:focus ~ .cx-switch-ui {
    box-shadow: 0 0 0 4px var(--cx-gold-ring);
}

.cx-lw-card .cx-switch-copy strong {
    color: var(--cx-auth-text);
    font-size: 15px;
}

.cx-lw-card .cx-switch-copy span {
    color: var(--cx-auth-soft);
}

/* Ostatnie sesje. */
.cx-lw-recent {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
}

.cx-lw-recent__item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 0;
    border-top: 1px solid var(--cx-auth-line);
}

    .cx-lw-recent__item:first-child {
        border-top: 0;
    }

.cx-lw-recent__icon {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    background: var(--cx-lw-ok-soft);
    color: var(--cx-lw-ok);
}

.cx-lw-recent__item--commute .cx-lw-recent__icon {
    background: var(--cx-lw-bad-soft);
    color: var(--cx-lw-bad);
}

.cx-lw-recent__main {
    flex-grow: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

    .cx-lw-recent__main strong {
        color: var(--cx-auth-text);
        font-size: 14px;
        font-weight: 700;
        font-variant-numeric: tabular-nums;
    }

    .cx-lw-recent__main small {
        overflow: hidden;
        color: var(--cx-auth-soft);
        font-size: 13px;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

.cx-lw-recent__dur {
    flex-shrink: 0;
    display: flex;
    align-items: baseline;
    gap: 8px;
}

    .cx-lw-recent__dur > span {
        display: flex;
        align-items: baseline;
        gap: 2px;
    }

    .cx-lw-recent__dur strong {
        color: var(--cx-auth-text);
        font-family: var(--cx-font-display);
        font-size: 20px;
        font-weight: 500;
        font-variant-numeric: tabular-nums;
    }

    .cx-lw-recent__dur small {
        color: var(--cx-auth-dim);
        font-size: 11px;
    }

.cx-lw-tracker .cx-clock:not(.cx-clock--mini) {
    --cx-clock-size: min(260px, 72vw);
}

/* Lista ostatnich sesji obok karty dopiero od 1400px — węższa kolumna ściskała szczegóły sesji. */
@media (min-width: 1400px) {
    .cx-lw-tracker {
        grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    }
}


/* =========================================================
   35. SKÓRKA LEWKE DLA STRON NA WSPÓLNYCH KOMPONENTACH (2026-10-01)
   Strona włącza ją przez @{ ViewData["AppSkin"] = "lw"; } — _Layout dodaje
   wtedy klasę .app-skin-lw do <html>. Wspólne komponenty (app-card, app-table,
   app-kpi, app-tile, app-tabs, app-filterbar, app-commandbar, przyciski,
   pola, okna, stronicowanie) biorą kolory z tokenów, więc tutaj tylko
   przepinamy te tokeny na paletę Lewke (oba motywy) i poprawiamy kształt.
   Znaczniki, warunki i skrypty stron zostają bez zmian.
   --cx-on-accent celowo NIE jest przepinany: biały tekst na nasyconych
   kolorach (np. chipy prognoz w CRM) musi zostać biały. Tam, gdzie tekst leży
   na złotym akcencie, kolor ustawiają reguły niżej.
   ========================================================= */

:root.app-skin-lw,
:root.app-skin-lw[data-theme] {
    --cx-panel: var(--cx-auth-surface);
    --cx-panel-2: var(--cx-auth-surface);
    --cx-panel-soft: var(--cx-auth-surface-2);
    --cx-surface: var(--cx-auth-surface);
    --cx-surface-raised: var(--cx-auth-surface);
    --cx-border: var(--cx-auth-line);
    --cx-border-strong: var(--cx-auth-line-2);
    --cx-border-dashed: var(--cx-auth-line-2);
    --cx-text: var(--cx-auth-text);
    --cx-text-strong: var(--cx-auth-text);
    --cx-text-soft: var(--cx-auth-soft);
    --cx-text-dim: var(--cx-auth-dim);
    --cx-blue: var(--cx-gold-text);
    --cx-blue-2: var(--cx-gold-text);
    --cx-blue-soft: var(--cx-gold-soft);
    --cx-blue-border: var(--cx-gold-line);
    --cx-accent-grad: linear-gradient(180deg, var(--cx-gold) 0%, var(--cx-gold) 100%);
    --cx-hover: var(--cx-auth-surface-2);
    --cx-hover-strong: var(--cx-auth-surface-3);
    --cx-active-bg: var(--cx-gold-soft);
    --cx-active-border: var(--cx-gold-line);
    --cx-inset: var(--cx-auth-surface-2);
    --cx-inset-border: var(--cx-auth-line);
    --cx-shadow: none;
    --cx-shadow-soft: none;
    --cx-ring: var(--cx-gold-ring);
    --cx-ring-hole: var(--cx-auth-surface);
    --app-track: var(--cx-auth-surface-3);
}

/* Tekst na złotym akcencie — ciemny, czytelny w obu motywach. */
.app-skin-lw .btn-primary,
.app-skin-lw .btn-primary:hover,
.app-skin-lw .btn-primary:focus,
.app-skin-lw .btn-primary:active,
.app-skin-lw .btn-primary:not(:disabled):not(.disabled):active,
.app-skin-lw .btn-primary:not(:disabled):not(.disabled).active,
.app-skin-lw .btn-outline-primary:hover,
.app-skin-lw .btn-outline-primary:not(:disabled):not(.disabled):active,
.app-skin-lw .app-pager .page-item.active .page-link,
.app-skin-lw .app-pager-compact .page-item.active .page-link,
.app-skin-lw .app-filterbar__count {
    border-color: var(--cx-gold);
    color: var(--cx-gold-ink);
}

    .app-skin-lw .btn-primary:hover {
        background: var(--cx-gold-hover);
    }

.app-skin-lw .app-tabs .app-tab-link.active,
.app-skin-lw .app-tabs.nav .app-tab-link.nav-link.active {
    color: var(--cx-gold-ink) !important;
}

/* --- Kształt -------------------------------------------------------- */
.app-skin-lw .app-card,
.app-skin-lw .app-kpi {
    border-radius: 22px;
    backdrop-filter: none;
}

.app-skin-lw .app-kpi {
    min-height: 0;
    padding: 16px 18px;
}

/* :where() = niska szczegółowość, żeby własny rozmiar strony (np. .crm-kpi-text dla wartości tekstowych) nadal wygrywał. */
:where(.app-skin-lw) .app-kpi__value {
    font-family: var(--cx-font-display);
    font-size: clamp(24px, 2.4vw, 30px);
    font-weight: 500;
    letter-spacing: -.01em;
    line-height: 1.1;
}

.app-skin-lw .app-kpi__label {
    padding-right: 48px;
}

.app-skin-lw .app-tile__value {
    font-family: var(--cx-font-display);
    font-size: 17px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.app-skin-lw .app-tile {
    border-radius: 14px;
}

.app-skin-lw .btn {
    border-radius: 14px;
}

.app-skin-lw .btn-sm {
    border-radius: 10px;
}

.app-skin-lw .app-input,
.app-skin-lw .app-field .form-control,
.app-skin-lw .form-control.app-input {
    border-width: 1.5px;
    border-color: var(--cx-auth-line-2);
    border-radius: 12px;
    background: var(--cx-auth-surface);
}

    .app-skin-lw .app-input:focus,
    .app-skin-lw .app-field .form-control:focus {
        border-color: var(--cx-gold);
        background: var(--cx-auth-surface);
        box-shadow: 0 0 0 4px var(--cx-gold-ring);
    }

.app-skin-lw .app-check input[type="checkbox"],
.app-skin-lw .app-check input[type="radio"],
.app-skin-lw .app-toggle-chip input {
    accent-color: var(--cx-gold);
}

.app-skin-lw .app-modal-content {
    border-color: var(--cx-auth-line);
    border-radius: 24px;
}

.app-skin-lw .modal-title {
    font-family: var(--cx-font-display);
    font-weight: 500;
}

/* Stronicowanie — jak na Panelu Głównym (sekcja 33). */
.app-skin-lw .app-pagebar {
    padding: 14px;
    border: 1px solid var(--cx-auth-line);
    border-radius: 18px;
    background: var(--cx-auth-surface);
    color: var(--cx-auth-soft);
}

    .app-skin-lw .app-pagebar .btn-sm,
    .app-skin-lw .app-pagebar .page-link {
        min-width: 36px;
        height: 36px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding: 0 10px;
        border: 1px solid var(--cx-auth-line);
        border-radius: 10px !important;
        background: var(--cx-auth-surface-2);
        color: var(--cx-auth-text);
        font-weight: 700;
        box-shadow: none;
    }

    .app-skin-lw .app-pagebar .pagination {
        gap: 6px;
    }

    .app-skin-lw .app-pagebar .btn-secondary,
    .app-skin-lw .app-pagebar .page-item.active .page-link {
        border-color: var(--cx-auth-ink);
        background: var(--cx-auth-ink);
        color: var(--cx-auth-ink-text);
    }

:root[data-theme="dark"].app-skin-lw .app-pagebar .btn-secondary,
:root[data-theme="dark"].app-skin-lw .app-pagebar .page-item.active .page-link {
    border-color: var(--cx-gold);
    background: var(--cx-gold);
    color: var(--cx-gold-ink);
}

.app-skin-lw .app-pagebar .page-item.disabled .page-link {
    opacity: .45;
}

/* KPI jak na Panelu Głównym: neutralna karta, kolor tylko na ikonie. */
.app-skin-lw .app-kpi.app-kpi--success,
.app-skin-lw .app-kpi.app-kpi--warning,
.app-skin-lw .app-kpi.app-kpi--danger,
.app-skin-lw .app-kpi.app-kpi--info {
    border-color: var(--cx-auth-line);
    background: var(--cx-auth-surface);
}

.app-skin-lw .app-kpi__icon {
    width: 40px;
    height: 40px;
    border: 0;
    border-radius: 12px;
    background: var(--cx-gold-soft);
    color: var(--cx-gold-text);
}

.app-skin-lw .app-kpi--success .app-kpi__icon { background: var(--cx-lw-ok-soft); color: var(--cx-lw-ok); }
.app-skin-lw .app-kpi--warning .app-kpi__icon { background: var(--cx-lw-warn-soft); color: var(--cx-lw-warn); }
.app-skin-lw .app-kpi--danger .app-kpi__icon { background: var(--cx-lw-bad-soft); color: var(--cx-lw-bad); }
.app-skin-lw .app-kpi--info .app-kpi__icon { background: var(--cx-lw-info-soft); color: var(--cx-lw-info); }

/* Przycisk usuwania (Bootstrap .btn-danger) w tym samym czerwonym co „Usuń” w Przeglądzie (sekcja 33). */
.app-skin-lw .btn-danger,
.app-skin-lw .btn-danger:hover,
.app-skin-lw .btn-danger:focus,
.app-skin-lw .btn-danger:not(:disabled):not(.disabled):active {
    border-color: var(--cx-lw-bad-solid);
    background: var(--cx-lw-bad-solid);
    color: var(--cx-lw-bad-ink);
}

/* Kalendarze flatpickr (Urlopy, Użytkownicy): wybrany dzień/miesiąc na złocie — ciemny tekst. */
.app-skin-lw .flatpickr-day.selected,
.app-skin-lw .flatpickr-day.selected:hover {
    border-color: var(--cx-gold);
    background: var(--cx-gold);
    color: var(--cx-gold-ink);
}

:root.app-skin-lw[data-theme] .flatpickr-monthSelect-months .flatpickr-monthSelect-month.selected {
    color: var(--cx-gold-ink);
}

/* Czat: dymki jak w projekcie (zaokrąglone, „ogonek” po stronie nadawcy). */
.app-skin-lw .app-chatlog {
    border-radius: 22px;
}

.app-skin-lw .app-chat-bubble {
    border-radius: 18px 18px 18px 6px;
}

.app-skin-lw .app-chat-row--out .app-chat-bubble {
    border-radius: 18px 18px 6px 18px;
}


/* =========================================================
   36. SKÓRKA LEWKE — SZCZEGÓŁY WSPÓLNYCH KOMPONENTÓW (2026-10-01)
   Te same proporcje i typografia co strony budowane ręcznie (sekcje 33–34):
   tytuły kart Jost, pola 48px ze strzałką listy w kolorze tokenu, plakietki,
   pusty stan, notatki, komunikaty, nagłówki tabel. Tylko wygląd.
   ========================================================= */

.app-skin-lw .app-card__title {
    font-family: var(--cx-font-display);
    font-size: 22px;
    font-weight: 500;
    letter-spacing: 0;
    line-height: 1.2;
}

.app-skin-lw .app-label {
    color: var(--cx-auth-soft);
    font-size: 13px;
    font-weight: 700;
}

.app-skin-lw .app-eyebrow {
    color: var(--cx-auth-dim);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .1em;
}

.app-skin-lw .app-help {
    color: var(--cx-auth-dim);
    font-size: 12px;
}

.app-skin-lw .app-input,
.app-skin-lw .app-field .form-control,
.app-skin-lw .form-control.app-input {
    min-height: 48px;
    font-size: 16px;
}

/* Strzałka listy rozwijanej z dwóch gradientów w kolorze tokenu (bez obrazka i bez literału). */
.app-skin-lw select.form-control:not([multiple]):not([size]),
.app-skin-lw select.form-control.app-input:not([multiple]):not([size]),
.app-skin-lw .app-field select.form-control:not([multiple]):not([size]) {
    padding-right: 40px;
    appearance: none;
    -webkit-appearance: none;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--cx-auth-dim) 50%),
        linear-gradient(135deg, var(--cx-auth-dim) 50%, transparent 50%);
    background-position: calc(100% - 21px) 52%, calc(100% - 15px) 52%;
    background-size: 6px 6px, 6px 6px;
    background-repeat: no-repeat;
    cursor: pointer;
}

.app-skin-lw .app-badge {
    min-height: 28px;
    padding: 0 10px;
    border-radius: 9px;
    font-size: 13px;
    font-weight: 700;
}

.app-skin-lw .app-chip,
.app-skin-lw .cx-status-chip {
    min-height: 30px;
    font-size: 13px;
}

.app-skin-lw .app-empty {
    min-height: 0;
    padding: 44px 16px;
    border: 1.5px dashed var(--cx-auth-line-2);
    border-radius: 22px;
    background: transparent;
    color: var(--cx-auth-soft);
}

.app-skin-lw .app-empty__icon {
    border: 0;
    border-radius: 28px;
    background: var(--cx-auth-surface-2);
    color: var(--cx-auth-dim);
}

.app-skin-lw .app-note {
    border-radius: 12px;
    font-size: 14px;
}

.app-skin-lw .app-note:not([class*="app-note--"]) {
    background: var(--cx-auth-surface-2);
    color: var(--cx-auth-text);
}

.app-skin-lw .cx-flash {
    padding: 12px 14px;
    border-radius: 14px;
    box-shadow: none;
}

.app-skin-lw .app-readout {
    border-radius: 14px;
}

.app-skin-lw .app-kv-value {
    font-size: 15px;
    font-weight: 700;
}

.app-skin-lw .app-table thead th {
    color: var(--cx-auth-dim);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .1em;
}

.app-skin-lw .app-commandbar {
    box-shadow: inset 0 3px 0 var(--cx-gold);
}

.app-skin-lw .app-btn-icon {
    border-radius: 12px;
}

.app-skin-lw .btn {
    font-weight: 700;
}

/* Na stronach ze skórką strzałkę listy rysuje już sekcja 36 (gradient na select) — bez drugiej strzałki z .cx-lw-select. */
.app-skin-lw .cx-lw-select::after {
    display: none;
}

/* Jedna złota linia na stronę: gdy strona ma własną główną kartę z akcentem
   (.cx-lw-hero i karty główne CRM), pasek poleceń nie dokłada drugiej. */
.app-skin-lw .app-content:has(.cx-lw-hero, .ci-card--main, .mat-card--main, .cx-lwd-summary) .app-commandbar {
    box-shadow: none;
}

/* Elementy stosu strony (.app-stack = grid) mogą się zwężać poniżej szerokości treści —
   bez tego długi przycisk / lista rozwijana rozpychała kartę poza ekran telefonu. */
.app-skin-lw .app-stack > *,
.app-skin-lw .app-content > * {
    min-width: 0;
}

/* Stos/sekcja strony to grid bez szablonu kolumn — kolumna rosła do najszerszej treści.
   Jedna kurcząca się kolumna trzyma karty w szerokości ekranu. */
.app-skin-lw .app-stack,
.app-skin-lw .app-section {
    grid-template-columns: minmax(0, 1fr);
}

/* =========================================================
   37. INFORMACJA O PLIKACH COOKIE (2026-10-01)
   Mała karta przy dolnej krawędzi, raz na urządzenie (_Layout.cshtml + app-ui.js).
   z-index 1035: pod tłem szuflady menu (1040) i modali Bootstrapa (1050),
   więc niczego nie zasłania, gdy użytkownik otwiera menu lub okno.
   Karta leży poza .app-shell — żaden przodek modala nie dostaje z-index/transform.
   Telefon: pełna szerokość z marginesami, nad paskiem gestów (safe-area),
   a strona dostaje dolny odstęp (--app-cookie-space), żeby karta nie zakryła
   ostatniego przycisku (np. „Wyślij kod” na ekranie logowania).
   ========================================================= */
.app-cookie {
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(14px + env(safe-area-inset-bottom));
    z-index: 1035;
    display: flex;
    align-items: center;
    gap: 12px;
    width: min(600px, calc(100% - 28px));
    margin: 0 auto;
    padding: 10px 10px 10px 16px;
    border: 1px solid var(--cx-border-strong);
    border-radius: var(--cx-radius-md);
    background-color: var(--cx-bg-3);
    background-image: var(--cx-surface-raised);
    box-shadow: var(--cx-shadow-strong);
    color: var(--cx-text-soft);
    animation: app-cookie-in .45s var(--splash-ease) both;
}

    .app-cookie[hidden] {
        display: none;
    }

.app-cookie__icon {
    flex: none;
    color: var(--cx-gold-text);
    font-size: 18px;
}

.app-cookie__text {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    font-size: 13px;
    line-height: 1.45;
}

    .app-cookie__text a {
        color: var(--cx-gold-text);
        font-weight: 700;
        text-decoration: underline;
        text-underline-offset: 3px;
        white-space: nowrap;
    }

        .app-cookie__text a:hover,
        .app-cookie__text a:focus {
            color: var(--cx-text);
        }

.app-cookie__ok {
    flex: none;
    min-height: 38px;
    padding: 8px 18px;
    border: 0;
    border-radius: var(--cx-radius-pill);
    background: var(--cx-gold);
    color: var(--cx-gold-ink);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}

    .app-cookie__ok:hover {
        background: var(--cx-gold-hover);
    }

    .app-cookie__ok:focus-visible {
        outline: 3px solid var(--cx-gold-ring);
        outline-offset: 2px;
    }

body.app-cookie-open {
    padding-bottom: var(--app-cookie-space, 0px);
}

@keyframes app-cookie-in {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
}

@media (max-width: 575.98px) {
    .app-cookie {
        bottom: calc(10px + env(safe-area-inset-bottom));
        width: calc(100% - 20px);
        gap: 10px;
        padding: 8px 8px 8px 12px;
    }

    .app-cookie__icon {
        display: none;
    }

    .app-cookie__text {
        font-size: 12px;
    }

    .app-cookie__ok {
        min-height: 36px;
        padding: 8px 14px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .app-cookie {
        animation: none;
    }
}

@media print {
    .app-cookie {
        display: none !important;
    }
}


/* =========================================================
   38. OKNO POTWIERDZENIA / KOMUNIKATU (.app-dialog) — 2026-10-18
   Zastępuje natywne window.confirm / window.alert (app-ui.js:
   AppUi.confirm, AppUi.alert, atrybut data-confirm). Natywny <dialog>
   otwierany przez showModal() leży w warstwie górnej (top layer): bez
   z-indexu, także nad otwartym oknem Bootstrapa i jego tłem.
   Przyciemnienie rysuje sam <dialog> (pełny ekran), nie ::backdrop —
   starsze przeglądarki nie przekazują tokenów do ::backdrop. Karta
   wygląda jak .cx-lw-modal (zaokrąglona karta, okrągłe ×, stopka
   z „Anuluj” i przyciskiem głównym .cx-lw-btn). Kolory tylko z tokenów.
   ========================================================= */
.app-dialog {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    margin: 0;
    padding: 16px;
    border: 0;
    background: var(--cx-scrim);
    color: var(--cx-auth-text);
    overflow-y: auto;
    overscroll-behavior: contain;
}

    .app-dialog[open] {
        display: flex;
    }

    .app-dialog::backdrop {
        background: transparent;
    }

.app-dialog__card {
    width: 100%;
    max-width: 440px;
    margin: auto;
    overflow: hidden;
    border: 1px solid var(--cx-auth-line);
    border-radius: 24px;
    background: var(--cx-auth-surface);
    color: var(--cx-auth-text);
    box-shadow: var(--cx-shadow-strong);
    animation: app-dialog-in .16s ease-out;
}

.app-dialog__head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 18px 20px 10px;
}

.app-dialog__title {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    color: var(--cx-auth-text);
    font-family: var(--cx-font-display);
    font-size: 21px;
    font-weight: 500;
    line-height: 1.3;
    overflow-wrap: anywhere;
}

.app-dialog__close {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid var(--cx-auth-line);
    border-radius: 20px;
    background: var(--cx-auth-surface);
    color: var(--cx-auth-text);
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
}

    .app-dialog__close:hover {
        background: var(--cx-auth-surface-2);
    }

    .app-dialog__close:focus {
        outline: 0;
    }

    .app-dialog__close:focus-visible {
        outline: 3px solid var(--cx-gold-ring);
        outline-offset: 2px;
    }

.app-dialog__message {
    margin: 0;
    padding: 6px 20px 18px;
    color: var(--cx-auth-text);
    font-size: 15px;
    line-height: 1.55;
    white-space: pre-line;
    overflow-wrap: anywhere;
}

.app-dialog__foot {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 14px 20px 20px;
    border-top: 1px solid var(--cx-auth-line);
}

    .app-dialog__foot .btn {
        margin: 0;
    }

    /* .btn.cx-lw-btn ustawia display — bez tego ukryte „Anuluj” (komunikat) by zostało. */
    .app-dialog__foot .btn[hidden] {
        display: none;
    }

@keyframes app-dialog-in {
    from {
        opacity: 0;
        transform: translateY(8px) scale(.98);
    }
}

@media (max-width: 575.98px) {
    .app-dialog__title {
        font-size: 19px;
    }

    .app-dialog__foot {
        flex-direction: column-reverse;
        align-items: stretch;
    }

        .app-dialog__foot .btn {
            width: 100%;
        }
}

@media (prefers-reduced-motion: reduce) {
    .app-dialog__card {
        animation: none;
    }
}

@media print {
    .app-dialog {
        display: none !important;
    }
}
