﻿/* ===========================================================
   Stay by Overcore — Admin Web Client
   Dark tokens ispirati a Linear Buildr (Crypto Exchange Dribbble shot
   #27323200): deep navy quasi-nero + accent indigo/periwinkle.
   Light theme: palette semantica (blu primario #2563EB + neutri slate)
   =========================================================== */

/* Inter self-hostato (variable font, pesi 100–900, Inter v20 da fonts.gstatic.com):
   niente fetch da Google Fonts al primo caricamento, quindi il flash col font di
   sistema sparisce (il file è same-origin e precaricato da App.razor) e l'app non
   dipende da un host esterno. Per il cinese si resta sul fallback di sistema. */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('fonts/inter-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('fonts/inter-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Utility: hide an element (Bootstrap-compatible name). */
.d-none { display: none !important; }

/* ====== Token condivisi + tema CHIARO (default) ======
   Il chiaro è il tema di default del prodotto e vive su :root: senza attributo, senza JS o con una
   preferenza sconosciuta l'app è chiara. Geometria (raggi, larghezze) e font mono sono comuni a
   tutti i temi. I temi scuri (dark / indigo / hc) sono override, vedi sotto.
   Light: palette semantica (blu primario #2563EB + neutri slate) — raw palette + mappatura dei
   design token su di essa: ogni pagina che usa le variabili (--accent, --danger, --text-primary,
   --border, …) eredita la palette. */
/* .tb-theme-scope[data-theme]: i token di un tema applicati a un solo riquadro (anteprima Impostazioni → Tableau). */
:root,
.tb-theme-scope[data-theme="light"] {
    --radius-sm: 6px;
    --radius: 10px;
    --radius-md: 8px;   /* controlli e card compatte (fra --radius-sm 6 e --radius 10) */
    --radius-lg: 14px;
    /* Curvatura dei badge/pill/stato/chip in tutta la web app: rettangolo poco arrotondato,
       NON più capsula. Cambiare qui per regolare globalmente. */
    --badge-radius: 6px;
    --sidebar-w: 270px;
    --sidebar-collapsed-w: 64px;
    --topbar-h: 58px;
    /* Modalità telefono (/hk/*): testata compatta e barra in basso (HousekeepingLayout). */
    --hk-header-h: 56px;
    --hk-bar-h: 64px;
    --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    /* Testata scura dei modali (ricetta "bkm"): per scelta resta scura in ogni tema, ma i suoi
       colori vivono qui, non copiati in ogni componente. Un tema (es. hc) puo' ridefinirli. */
    --mhead-bg: linear-gradient(160deg, #26262b 0%, #191a1d 100%);
    --mhead-fg: #ffffff;
    --mhead-muted: #a3a3aa;   /* occhielli, sottotitoli */
    --mhead-meta: #adadb4;    /* riepiloghi, codici */
    --mhead-icon: #d0d0d6;    /* icone dei pulsanti (X) */
    --mhead-dot: #6f6f77;     /* separatori */
    --mhead-border: rgba(255, 255, 255, 0.08);

    /* ── Raw palette ── */
    --p-600: #2563EB;   /* blu primario */
    --p-500: #3B82F6;
    --p-50:  #EFF6FF;
    --ok: #047857;      --ok-bg: #ECFDF5;   /* successo / pagato (5,5:1 su bianco) */
    --warn: #B45309;    --warn-bg: #FFF7ED; /* attenzione / saldo (5,0:1 su bianco, 4,7:1 su warn-bg) */
    --danger: #B91C1C;  --danger-bg: #FEF2F2; /* errore / scaduto (6,5:1 su bianco) */
    --teal: #0E7490;    --teal-bg: #ECFEFF; /* accento info (5,4:1 su bianco) */
    --ink: #1E293B;     /* testo forte */
    --ink-soft: #475569;/* testo secondario */
    --muted: #5F6E85;   /* testo tenue: 4,8:1 su --bg-app (il vecchio #94A3B8 faceva 2,6:1) */
    --line: #E2E8F0;    /* bordi */
    --field: #F8FAFC;   /* sfondo campi / superfici tenui */

    /* ── Token → palette ── */
    --bg-app: #f4f5fb;
    --bg-panel: #ffffff;
    --bg-sidebar: #ffffff;
    --bg-sidebar-2: #f7f8fd;
    --bg-card: #ffffff;
    --bg-card-2: var(--field);
    --bg-subtle: var(--field);
    --bg-hover: rgba(37, 99, 235, 0.05);
    --bg-active: rgba(37, 99, 235, 0.12);

    --text-primary: var(--ink);
    --text-secondary: var(--ink-soft);
    --text-muted: var(--muted);

    --accent: var(--p-600);
    --accent-2: var(--p-500);
    --accent-deep: #1D4ED8;
    --accent-soft: rgba(37, 99, 235, 0.14);
    --accent-glow: rgba(37, 99, 235, 0.40);
    --on-accent: #ffffff;

    --success: var(--ok);
    --warning: var(--warn);
    --info: var(--teal);

    --danger-soft: var(--danger-bg);
    --warning-soft: var(--warn-bg);
    --success-soft: var(--ok-bg);
    --info-soft: var(--teal-bg);
    /* Cambio camera (vista giornaliera, planner): viola, 4,6:1 su bianco. */
    --move: #6D28D9;
    --move-soft: rgba(109, 40, 217, 0.12);

    --border: var(--line);
    --border-strong: #CBD5E1;
    --border-control: #7F8CA3; /* 3,3:1 su --field */

    /* Ambra "obbligatorio" ricalibrata per il chiaro: #E0932A faceva 2,5:1 su bianco. */
    --req: #B45309;
    --req-soft: rgba(180, 83, 9, 0.08);

    /* Nastro segnaletico della MANUTENZIONE (blocco camera, rif. nastro 3M 766i): strisce diagonali
       giallo/nero. Unico segno visivo dei blocchi ovunque (Tableau, selettori camera, pagine pulizie,
       Blocchi camera). Mai testo sulle strisce: l'etichetta va nella pastiglia nera (--maint-tape-ink
       su --maint-tape-black = 17,4:1). Le camere non vendibili NON usano il nastro. */
    --maint-tape-yellow: #F5C400;
    --maint-tape-black: #1A1A1A;
    --maint-tape-ink: #FFFFFF;
    --maint-tape-edge: transparent;   /* sul chiaro il nero delle strisce basta a staccarlo dal fondo */
    --maint-tape: repeating-linear-gradient(-45deg, var(--maint-tape-yellow) 0 10px, var(--maint-tape-black) 10px 20px);

    --sidebar-gradient-end: #eef2fb;
    --scrollbar-thumb: #cbd0e2;
    --scrollbar-thumb-hover: #aeb6d0;
    --scrollbar-track: transparent;
    --topbar-bg: rgba(255, 255, 255, 0.82);

    --shadow-sm: 0 1px 2px rgba(30,41,59,.06);
    --shadow: 0 8px 24px rgba(30,41,59,.08);
    --shadow-lg: 0 20px 50px rgba(30,41,59,.12);
}

/* ====== Famiglia SCURA: base comune a dark / indigo / hc ======
   Dark tokens ispirati a Linear Buildr (deep navy quasi-nero + accent indigo). Indigo e hc
   ridefiniscono solo colore/superficie/bordo/accento e ereditano da qui ombre scure, --req ambra
   scuro e le altre tinte non ridefinite. */
:root[data-theme="dark"],
:root[data-theme="indigo"],
:root[data-theme="hc"],
.tb-theme-scope[data-theme="dark"],
.tb-theme-scope[data-theme="hc"] {
    /* Alias della raw palette chiara usati fuori dai token (.sub-*, planner .sri-*): nei temi scuri
       puntano ai token semantici scuri, cosi' non ereditano il verde/ambra tarati sul bianco. */
    --ok: var(--success);
    --warn: var(--warning);

    --bg-app: #0d0d0f;
    --bg-panel: #18181b;
    --bg-sidebar: #0a0a0c;
    --bg-sidebar-2: #1a1a1e;
    --bg-card: #18181b;
    --bg-card-2: #111113;
    --bg-subtle: #111113;
    --bg-hover: rgba(255, 255, 255, 0.05);
    --bg-active: rgba(255, 255, 255, 0.10);

    --text-primary: #ffffff;
    --text-secondary: #b3b3b9;
    --text-muted: #8b8b93; /* 5,2:1 su --bg-card: era #7c7c83 (4,3:1) */

    --accent: #2563EB;
    --accent-2: #3B82F6;
    --accent-deep: #1D4ED8;
    --accent-soft: rgba(37, 99, 235, 0.16);
    --accent-glow: rgba(37, 99, 235, 0.55);
    --on-accent: #ffffff;

    --success: #16c784;
    --warning: #f0b90b;
    --danger: #f0555e; /* 5,2:1 su --bg-card come testo: era #ea3943 (4,4:1) */
    /* Era #2563EB, identico a --accent: come TESTO su una superficie scura faceva 3,2:1
       (badge .cx-badge.info, alert .cx-alert.info, saldo a credito) e non si distingueva
       dall'interattivo. Blu chiaro: 6,5:1 sulle superfici soft, e "info" torna diverso da
       "cliccabile". Indaco e alto contrasto hanno il proprio valore più sotto. */
    --info: #60A5FA;

    /* Superfici "soft": sfondo traslucido da accoppiare SEMPRE col token pieno
       come foreground (--danger su --danger-soft, --warning su --warning-soft). */
    --danger-soft: rgba(234, 57, 67, 0.12);
    --warning-soft: rgba(240, 185, 11, 0.12);
    --success-soft: rgba(22, 199, 132, 0.12);
    --info-soft: rgba(96, 165, 250, 0.14);
    --move: #A78BFA;
    --move-soft: rgba(167, 139, 250, 0.16);

    --border: rgba(255,255,255,0.06);
    --border-strong: rgba(255,255,255,0.12);
    /* Bordo dei CONTROLLI (input/select/textarea/ricerche): >= 3:1 sul loro sfondo (WCAG 1.4.11).
       --border resta per card e separatori, dove il contrasto non e' richiesto. */
    --border-control: #66666e;

    /* Campo obbligatorio ancora vuoto: ambra sottile (informativa, non allarmante).
       Il rosso (--danger) resta riservato all'ERRORE dopo un salvataggio fallito.
       Ereditata da tutti i temi (light/hc non la ridefiniscono). */
    --req: #E0932A;
    --req-soft: rgba(224, 147, 42, 0.08);

    /* Nastro segnaletico della manutenzione sullo scuro: giallo appena smorzato (meno abbagliante),
       nero più profondo delle superfici e bordo giallo, perché il nero delle strisce e della
       pastiglia si confonderebbe con --bg-card. Ridichiarato qui (non solo ereditato da :root) per
       gli scope .tb-theme-scope, che altrimenti erediterebbero il gradiente calcolato col chiaro. */
    --maint-tape-yellow: #EBBC00;
    --maint-tape-black: #0B0B0C;
    --maint-tape-ink: #FFFFFF;
    --maint-tape-edge: color-mix(in srgb, var(--maint-tape-yellow) 70%, transparent);
    --maint-tape: repeating-linear-gradient(-45deg, var(--maint-tape-yellow) 0 10px, var(--maint-tape-black) 10px 20px);

    --sidebar-gradient-end: #070708;
    --scrollbar-thumb: #45454d;
    --scrollbar-thumb-hover: #5a5a63;
    --scrollbar-track: #141417;
    --topbar-bg: rgba(13, 13, 15, 0.78);

    --shadow-sm: 0 1px 2px rgba(0,0,0,.30);
    --shadow: 0 8px 24px rgba(0,0,0,.45);
    --shadow-lg: 0 20px 50px rgba(0,0,0,.60);
}

/* ====== Indigo — dark desaturato navy + periwinkle (stile Mercury) ======
   Solo i token colore/superficie/bordo/accento: raggi, ombre, geometria e
   --req/--req-soft/--mono ereditano dal blocco :root dark (ombre scure corrette). */
:root[data-theme="indigo"] {
    --bg-app: #0e1116;
    --bg-panel: #151a23;
    --bg-sidebar: #0b0e14;
    --bg-sidebar-2: #171c26;
    --bg-card: #161b25;
    --bg-card-2: #10141b;
    --bg-subtle: #10141b;
    --bg-hover: rgba(255, 255, 255, 0.045);
    --bg-active: rgba(112, 115, 240, 0.14);

    --text-primary: #f2f3f7;
    --text-secondary: #a8adbd;
    --text-muted: #8a90a2; /* 5,4:1 su --bg-card: era #6b7180 (3,5:1) */

    --accent: #7073F0;
    --accent-2: #8B8DF5;
    --accent-deep: #575AE8;
    --accent-soft: rgba(112, 115, 240, 0.16);
    --accent-glow: rgba(112, 115, 240, 0.50);
    --on-accent: #ffffff;

    --success: #2fbf8f;
    --warning: #e5a83b;
    --danger: #e5484d;
    --info: #8B8DF5;

    --danger-soft: rgba(229, 72, 77, 0.14);
    --warning-soft: rgba(229, 168, 59, 0.12);
    --success-soft: rgba(47, 191, 143, 0.14);
    --info-soft: rgba(139, 141, 245, 0.16);
    --move: #C4B5FD;
    --move-soft: rgba(196, 181, 253, 0.16);

    --border: rgba(255, 255, 255, 0.07);
    --border-strong: rgba(255, 255, 255, 0.13);
    --border-control: #5d6678;

    --sidebar-gradient-end: #080a0f;
    --scrollbar-thumb: #3a4152;
    --scrollbar-thumb-hover: #4a5266;
    --scrollbar-track: #12161e;
    --topbar-bg: rgba(14, 17, 22, 0.78);
}

/* ====== High contrast ====== */
:root[data-theme="hc"],
.tb-theme-scope[data-theme="hc"] {
    --bg-app: #000000;
    --bg-panel: #000000;
    --bg-sidebar: #000000;
    --bg-sidebar-2: #0a0a0a;
    --bg-card: #000000;
    --bg-card-2: #0a0a0a;
    --bg-subtle: #0a0a0a;
    --bg-hover: rgba(255, 255, 0, 0.12);
    --bg-active: rgba(255, 204, 0, 0.22);

    --text-primary: #ffffff;
    --text-secondary: #ffffff;
    --text-muted: #e8e8e8;

    --accent: #ffcc00;
    --accent-2: #ffdd33;
    --accent-deep: #e6b800; /* prima ereditava il blu scuro: gradiente giallo->blu sui primari */
    --accent-soft: rgba(255, 204, 0, 0.22);
    --accent-glow: rgba(255, 204, 0, 0.6);
    --on-accent: #000000;

    --success: #00ff66;
    --warning: #ffcc00;
    --danger: #ff3355;
    --info: #00ddff;

    --danger-soft: rgba(255, 51, 85, 0.22);
    --warning-soft: rgba(255, 204, 0, 0.22);
    --success-soft: rgba(0, 255, 102, 0.22);
    --info-soft: rgba(0, 221, 255, 0.22);
    --move: #D8B4FE;
    --move-soft: rgba(216, 180, 254, 0.25);

    --border: #ffffff;
    --border-strong: #ffffff;
    --border-control: #ffffff;

    --sidebar-gradient-end: #000000;
    --scrollbar-thumb: #ffffff;
    --scrollbar-thumb-hover: #ffffff;
    --scrollbar-track: #000000;
    --topbar-bg: #000000;
}

/* ====== Dimensione testo ======
   Asse indipendente dal tema (data-size, non data-theme): "Caratteri grandi" si combina con
   qualunque palette. Prima era un valore di data-theme e scegliendolo si perdeva il tema chiaro. */
:root[data-size="xl"] { font-size: 17px; }

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
    margin: 0;
    font-family: 'Inter', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
    background: var(--bg-app);
    color: var(--text-primary);
    -webkit-font-smoothing: antialiased;
    overflow: hidden;
}
:root[data-theme="dark"] body {
    background:
        radial-gradient(ellipse 900px 600px at 50% 60%, rgba(255, 255, 255, 0.03) 0%, transparent 55%),
        linear-gradient(180deg, #0a0a0c 0%, #0d0d0f 50%, #111113 100%);
}
:root[data-theme="indigo"] body {
    background:
        radial-gradient(ellipse 900px 600px at 50% 60%, rgba(112, 115, 240, 0.05) 0%, transparent 55%),
        linear-gradient(180deg, #0b0e14 0%, #0e1116 50%, #12161e 100%);
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* =================== Scrollbar globali ===================
   scrollbar-color è ereditata: impostata su :root vale per ogni contenitore
   scrollabile dell'app (Firefox, Chromium 121+) e segue il tema attivo.
   Le regole ::-webkit-* coprono i Chromium più vecchi con la stessa palette;
   gli stili locali (es. .bkm-tabs che la nasconde via scrollbar-width: none)
   restano prioritari. */
:root { scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--scrollbar-track); }
::-webkit-scrollbar-thumb {
    background: var(--scrollbar-thumb);
    border-radius: 8px;
    border: 3px solid transparent;
    background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover {
    background: var(--scrollbar-thumb-hover);
    background-clip: padding-box;
}
::-webkit-scrollbar-corner { background: transparent; }

/* =================== App layout =================== */
.app {
    display: grid;
    grid-template-columns: var(--sidebar-w) 1fr;
    grid-template-rows: var(--topbar-h) 1fr;
    grid-template-areas:
        "sidebar topbar"
        "sidebar main";
    height: 100vh;
    /* Niente transition su grid-template-columns: animare il layout rilayouta tutto il main
       (planner SVG incluso) per 250 ms. Il collasso e' istantaneo; le etichette svaniscono via CSS. */
}
.app.collapsed { grid-template-columns: var(--sidebar-collapsed-w) 1fr; }

/* Focus mode (primo avvio della configurazione guidata): la sidebar non e' renderizzata,
   la griglia resta a una colonna sola. La doppia selezione con .collapsed alza la
   specificita' sopra .app.collapsed, cosi' l'ordine delle regole non conta. */
.app.no-sidebar,
.app.no-sidebar.collapsed {
    grid-template-columns: 1fr;
    grid-template-areas:
        "topbar"
        "main";
}
/* Senza sidebar non c'e' niente da aprire: via l'hamburger (<=900px) e lo scrim del drawer,
   che altrimenti resterebbe un velo cliccabile sopra la pagina. */
.app.no-sidebar .topbar-hamburger,
.app.no-sidebar .sidebar-scrim { display: none; }
/* Cintura: MainLayout non renderizza la sidebar in focus mode, ma se un domani lo facesse
   senza l'area di griglia finirebbe auto-posizionata in una riga implicita in fondo. */
.app.no-sidebar .sidebar { display: none; }

/* =================== SIDEBAR =================== */
/* Pannello unico: righe icona+etichetta con sottomenu inline (accordion). Collassata (solo
   desktop, toggle utente) resta la sola colonna icone con flyout al hover. */
.sidebar {
    grid-area: sidebar;
    display: flex;
    flex-direction: column;
    min-width: 0;
    position: relative;
    z-index: 20;
    border-right: 1px solid var(--border);
    background: linear-gradient(180deg, var(--bg-sidebar) 0%, var(--sidebar-gradient-end) 100%);
}

/* ---- Testata: logo + brand + toggle compressione ---- */
.side-head {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 12px 8px;
}
.side-logo {
    width: 38px; height: 38px; flex: 0 0 38px;
    display: grid; place-items: center;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 4px 10px var(--accent-glow);
}
.side-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
.side-brand {
    flex: 1 1 auto; min-width: 0;
    display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
    white-space: nowrap; overflow: hidden;
}
/* Logo e wordmark sono bottoni (aprono il popup versioni): reset del bottone nativo. */
.side-logo, .side-brand {
    appearance: none; border: 0; padding: 0; margin: 0; background: transparent;
    color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.side-brand { padding: 2px 4px; margin-left: -4px; border-radius: 8px; }
.side-brand:hover, .side-logo:hover { opacity: .85; }
.side-brand:focus-visible, .side-logo:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.side-brand-stay { height: 17px; width: auto; display: block; }
.side-brand-by {
    font-size: .6875rem; font-weight: 600; line-height: 1;
    color: var(--text-secondary); letter-spacing: .05em;
}
.side-collapse {
    width: 28px; height: 28px; flex: 0 0 28px;
    border: 1px solid var(--border-strong); background: var(--bg-panel);
    color: var(--text-secondary); cursor: pointer;
    border-radius: 50%;
    display: grid; place-items: center;
    transition: background .15s ease, color .15s ease;
}
.side-collapse:hover { background: var(--accent-soft); color: var(--accent); }
/* Base chevron points right (">"); expanded = collapse action → point left ("<") */
.side-collapse svg { width: 13px; height: 13px; transform: rotate(180deg); transition: transform .2s ease; }
.app.collapsed .side-collapse svg { transform: none; }

.rail-avatar {
    width: 36px; height: 36px; border-radius: 50%;
    background: linear-gradient(135deg, var(--accent), var(--accent-deep));
    display: grid; place-items: center;
    color: #fff; font-weight: 700; font-size: .8125rem;
    flex: 0 0 36px;
}

.side-search {
    padding: 4px 10px 10px;
    border-bottom: 1px solid var(--border);
    position: relative; /* àncora del dropdown risultati */
}
.panel-search {
    display: flex; align-items: center; gap: 8px;
    width: 100%; padding: 7px 9px;
    border: 1px solid var(--border-control); border-radius: var(--radius);
    background: var(--bg-app); cursor: text;
    color: var(--text-muted); font-size: .7812rem;
    transition: border-color .15s ease;
}
.panel-search:hover { border-color: var(--border-strong); }
.panel-search:focus-within { border-color: var(--accent); }
.panel-search input {
    flex: 1 1 auto; min-width: 0;
    border: 0; outline: none; background: transparent; padding: 0;
    color: var(--text-primary); font-size: .7812rem; font-family: inherit;
}
.panel-search input::placeholder { color: var(--text-muted); }
.ps-icon { display: grid; place-items: center; color: var(--text-muted); }
.ps-icon svg { width: 15px; height: 15px; }
.ps-text { flex: 1 1 auto; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Risultati della ricerca voci di menu — dropdown ancorato sotto la casella */
.side-search-results {
    position: absolute; left: 10px; right: 10px; top: calc(100% - 4px);
    background: var(--bg-panel); border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
    padding: 6px; z-index: 80;
    max-height: 55vh; overflow-y: auto;
}
.ssr-item {
    display: flex; flex-direction: column; align-items: stretch; gap: 2px;
    width: 100%; padding: 7px 9px;
    border: 0; border-radius: var(--radius);
    background: transparent; cursor: pointer; text-align: left;
}
.ssr-item:hover, .ssr-item.sel { background: var(--bg-hover); }
.ssr-label { color: var(--text-primary); font-size: .8125rem; font-weight: 600; }
.ssr-context { color: var(--text-muted); font-size: .6875rem; }
.ssr-empty { color: var(--text-muted); font-size: .7812rem; padding: 8px 9px; }

/* ---- Corpo: righe area + sottomenu inline ---- */
.side-body {
    flex: 1 1 auto; overflow-y: auto; overflow-x: hidden;
    padding: 10px 10px 14px;
    scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) transparent;
}
.side-body::-webkit-scrollbar { width: 6px; }
.side-body::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 6px; }
.side-divider { height: 1px; background: var(--border-strong); margin: 8px 6px; }

.nav-area-wrap { position: relative; }
.nav-row {
    display: flex; align-items: center; gap: 10px;
    width: 100%; padding: 9px 10px; margin-bottom: 2px;
    border: 0; background: transparent; cursor: pointer;
    border-radius: 10px;
    color: var(--text-secondary); font-size: .8438rem; font-weight: 600;
    text-align: left; position: relative;
    transition: background .12s ease, color .12s ease;
}
.nav-row:hover { background: var(--bg-hover); color: var(--accent); }
.nav-row.on { background: var(--accent-soft); color: var(--accent); }
.nav-row.on::before {
    content: ""; position: absolute; left: -10px; top: 8px;
    width: 3px; height: 22px; border-radius: 0 3px 3px 0; background: var(--accent);
}
.nav-row-icon { display: grid; place-items: center; flex: 0 0 auto; }
.nav-row-icon svg { width: 20px; height: 20px; }
.nav-row-label { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav-row-chev { display: grid; place-items: center; opacity: .7; transition: transform .2s ease; }
.nav-row-chev svg { width: 13px; height: 13px; }
.nav-area-wrap.open > .nav-row .nav-row-chev { transform: rotate(90deg); }

/* Sottomenu inline (accordion) con guida verticale */
.nav-area-items {
    padding: 2px 0 6px 28px;
    position: relative;
}
.nav-area-items::before {
    content: ""; position: absolute;
    left: 19px; top: 4px; bottom: 8px;
    width: 1px; background: var(--border);
}

/* Home (Dashboard) quick-launch cards (flyout della Dashboard da collassata) */
.panel-home-label {
    font-size: .6875rem; text-transform: uppercase; letter-spacing: .12em;
    color: var(--text-muted); padding: 6px 8px;
}
.panel-home-card {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px; margin-bottom: 4px;
    border: 1px solid var(--border); border-radius: var(--radius);
    color: var(--text-secondary); font-size: .8125rem;
    text-decoration: none;
    transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.panel-home-card:hover { background: var(--bg-hover); border-color: var(--border-strong); color: var(--text-primary); text-decoration: none; }
.phc-icon { display: grid; place-items: center; color: var(--accent); flex: 0 0 auto; }
.phc-icon svg { width: 18px; height: 18px; }
.phc-label { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Gruppo = sottomenu di 1° livello (riga cliccabile, chiuso di default) */
.panel-group {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 8px 10px; margin-top: 2px;
    background: transparent; border: 0; cursor: pointer;
    border-radius: var(--radius);
    color: var(--text-secondary); font-size: .8125rem; font-weight: 600;
    text-align: left;
    transition: background .15s ease, color .15s ease;
}
.panel-group:hover { background: var(--bg-hover); color: var(--text-primary); }
.panel-group-title { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.panel-group-chev { display: grid; place-items: center; transition: transform .2s ease; transform: rotate(90deg); opacity: .7; }
.panel-group-chev svg { width: 13px; height: 13px; }
.panel-group.closed .panel-group-chev { transform: rotate(0deg); }
/* Voci del gruppo = sottomenu di 2° livello, indentate con guida verticale */
.panel-group-items {
    display: flex; flex-direction: column;
    padding-left: 14px; margin: 0 0 4px;
    position: relative;
}
.panel-group-items::before {
    content: ""; position: absolute;
    left: 7px; top: 4px; bottom: 4px;
    width: 1px; background: var(--border);
}

/* Panel leaf */
.panel-item {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 10px; border-radius: var(--radius);
    color: var(--text-secondary); font-size: .8125rem;
    text-decoration: none; cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.panel-item:hover { background: var(--bg-hover); color: var(--text-primary); text-decoration: none; }
.panel-item.active { background: var(--bg-active); color: var(--accent); font-weight: 600; }
.panel-item.muted { opacity: .55; }
.panel-item.muted:hover { opacity: .8; }
.panel-item-label { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.panel-item-tag {
    font-size: .6875rem; text-transform: uppercase; letter-spacing: .04em;
    background: var(--accent-soft); color: var(--accent);
    padding: 2px 6px; border-radius: var(--badge-radius); font-weight: 700;
}

/* Rail flyout — shown on hover only when collapsed */
.rail-flyout {
    display: none;
    position: absolute; left: calc(100% + 8px); top: -6px;
    width: 226px; max-height: 70vh; overflow-y: auto;
    background: var(--bg-panel); border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 10px; z-index: 60;
}
.flyout-title { font-size: .8125rem; font-weight: 700; color: var(--text-primary); padding: 2px 6px 8px; }

/* ---- Piè (utente + logout) ---- */
.side-foot {
    border-top: 1px solid var(--border);
    padding: 10px 12px;
    display: flex; align-items: center; gap: 10px;
    background: var(--bg-card-2);
}

/* ---- Collassata (solo desktop): sola colonna icone, flyout al hover ---- */
@media (min-width: 901px) {
    .app.collapsed .side-brand,
    .app.collapsed .ps-text,
    .app.collapsed .nav-row-label,
    .app.collapsed .nav-row-chev,
    .app.collapsed .nav-area-items,
    .app.collapsed .user-info { display: none; }

    .app.collapsed .side-head { flex-direction: column; gap: 8px; padding: 12px 0 6px; }
    .app.collapsed .side-search { padding: 4px 10px 10px; display: flex; justify-content: center; }
    .app.collapsed .panel-search { width: auto; padding: 8px; border-radius: 10px; }
    .app.collapsed .nav-row { justify-content: center; padding: 10px 0; }
    .app.collapsed .side-foot { flex-direction: column; gap: 8px; padding: 10px 0; }
    /* Da collassata il corpo non scrolla (come il vecchio rail): overflow visibile, altrimenti
       i flyout assoluti verrebbero clippati dal contenitore scrollabile. */
    .app.collapsed .side-body { overflow: visible; }

    /* Invisible bridge over the 8px gap so hover survives the icon→flyout crossing
       (on the wrap, not the flyout: the flyout's overflow-y would clip it) */
    .app.collapsed .nav-area-wrap:hover::after {
        content: ""; position: absolute;
        left: 100%; top: -6px; bottom: -6px; width: 8px;
    }
    .app.collapsed .nav-area-wrap:hover > .rail-flyout,
    .app.collapsed .rail-flyout:hover { display: block; }
}
.submenu {
    display: none;
    padding: 4px 0 6px 38px;
    margin: 2px 0 4px;
    position: relative;
}
.submenu::before {
    content: "";
    position: absolute;
    left: 22px; top: 4px; bottom: 4px;
    width: 1px;
    background: var(--border);
}
.nav-item.open + .submenu { display: block; }
/* Maintenance section: folder buttons (Auth, Diagnostics, ...) are .submenu-item, not
   .nav-item, so expanding them must reveal their nested .submenu of endpoints too. */
.submenu-item.open + .submenu { display: block; }
.submenu-item {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 10px;
    color: var(--text-secondary);
    font-size: .8125rem;
    border-radius: 8px;
    cursor: pointer;
    position: relative;
    text-decoration: none;
    transition: background .15s ease, color .15s ease;
}
/* Sub-folder toggles (Utenti, Tasse & Pagamenti, Maintenance folders) reuse .submenu-item but are
   <button>s — without these resets they'd show the browser's default border/background box. Reset
   so they render identically to the <a> leaf links. */
button.submenu-item {
    width: 100%;
    background: transparent;
    border: 0;
    font: inherit;
    font-size: .8125rem;
    text-align: left;
}
/* Toggle sub-folders keep focus after a click; suppress the mouse-focus box while keeping a
   keyboard focus ring. (The open/active state is the selected indicator.) */
button.submenu-item:focus:not(:focus-visible) { outline: none; }
button.submenu-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.submenu-item::before {
    content: "";
    position: absolute;
    left: -16px; top: 50%;
    width: 10px; height: 1px;
    background: var(--border);
}
.submenu-item:hover { background: var(--bg-hover); color: var(--text-primary); text-decoration: none; }
.submenu-item.active {
    background: var(--bg-active);
    color: var(--accent);
    font-weight: 600;
}
.submenu-item.active::after {
    content: ""; position: absolute; right: 10px; top: 50%;
    width: 5px; height: 5px; border-radius: 50%;
    background: var(--accent); transform: translateY(-50%);
    box-shadow: 0 0 10px var(--accent-glow);
}
.sub-code {
    font-family: var(--mono);
    font-size: .6875rem;
    color: var(--text-muted);
    margin-left: auto;
}
.submenu-item.active .sub-code { color: var(--accent-2); }

/* HTTP method pills (Postman-style) */
.method-pill {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 40px; padding: 2px 6px;
    font: 700 .6875rem/1 var(--mono);
    border-radius: 4px;
    text-transform: uppercase; letter-spacing: .06em;
    color: #fff;
    flex: 0 0 auto;
}
.method-pill.get     { background: #22c55e; }
.method-pill.post    { background: #f59e0b; }
.method-pill.put     { background: #38bdf8; color: #0b2337; }
.method-pill.patch   { background: #8b5cf6; }
.method-pill.delete  { background: #ef4444; }
.method-pill.head    { background: #64748b; }
.method-pill.options { background: #64748b; }

.submenu-item .method-pill { margin-right: 2px; }
.submenu-item .label-text { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.submenu-item.impl { color: var(--text-primary); }
.submenu-item.impl::before { background: var(--accent); }

/* ---- Maintenance page: in-page catalog sidebar ---- */
.mnt-nav { padding: 10px; overflow: hidden; }
.mnt-nav-head { padding: 4px 6px 10px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.mnt-nav-head b { font-size: .875rem; color: var(--text-primary); }
.mnt-tree { flex: 1 1 auto; overflow-y: auto; overflow-x: hidden; padding-right: 2px; scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) transparent; }
.mnt-tree::-webkit-scrollbar { width: 6px; }
.mnt-tree::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 6px; }
.mnt-cat { font-size: .6875rem; text-transform: uppercase; letter-spacing: .12em; color: var(--text-muted); padding: 12px 6px 4px; }
.mnt-tree > .submenu-item::before { display: none; }
.mnt-detail-empty { color: var(--text-muted); padding: 40px 24px; text-align: center; font-size: .8125rem; }

/* Folder emojis in the maintenance catalog tree (inside .submenu-item buttons). Rendered
   monochrome to match the muted UI: white in dark themes, black in light. */
.folder-emoji {
    font-size: 1rem; line-height: 1;
    width: 20px; text-align: center;
    filter: grayscale(1) brightness(0);
    opacity: .78;
    transition: opacity .15s ease;
}
:root[data-theme="dark"] .folder-emoji, :root[data-theme="indigo"] .folder-emoji { filter: grayscale(1) brightness(0) invert(1); opacity: .92; }
:root[data-theme="hc"] .folder-emoji { filter: grayscale(1) brightness(0) invert(1); opacity: 1; }
.submenu-item:hover .folder-emoji,
.submenu-item.open .folder-emoji,
.submenu-item.active .folder-emoji { opacity: 1; }

.avatar {
    width: 34px; height: 34px; border-radius: 50%;
    background: linear-gradient(135deg, var(--accent), var(--accent-deep));
    display: grid; place-items: center;
    font-weight: 700; font-size: .8125rem; flex: 0 0 34px; color: #fff;
}
.user-info { flex: 1 1 auto; min-width: 0; }
.user-info b { display: block; font-size: .8125rem; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-info span { font-size: .6875rem; color: var(--text-muted); }
.user-info .user-org { display: block; font-size: .6875rem; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.logout-btn {
    background: transparent; border: 0; color: var(--text-muted); cursor: pointer;
    padding: 6px; border-radius: 6px; display: grid; place-items: center;
}
.logout-btn:hover { background: var(--bg-hover); color: var(--danger); }
.logout-btn svg { width: 16px; height: 16px; }

/* ---- Mobile hamburger + off-canvas drawer ---- */
.topbar-hamburger { display: none; background: transparent; border: 0; color: var(--text-secondary); cursor: pointer; padding: 6px; border-radius: 8px; margin-right: 2px; }
.topbar-hamburger:hover { background: var(--bg-hover); color: var(--text-primary); }
.sidebar-scrim { display: none; }

@media (max-width: 900px) {
    /* Sidebar becomes an off-canvas drawer toggled by the topbar hamburger */
    /* minmax(0,...): senza, la traccia 1fr ha minimo = min-content e il contenuto largo allarga
       la pagina oltre il viewport (e la riga main cresce oltre 100vh, tagliando lo scroll). */
    .app, .app.collapsed {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: var(--topbar-h) minmax(0, 1fr);
        grid-template-areas: "topbar" "main";
    }
    .topbar, .main { min-width: 0; }
    .sidebar {
        position: fixed; top: 0; left: 0; bottom: 0;
        width: 288px; z-index: 80;
        transform: translateX(-100%);
        transition: transform .22s ease;
        box-shadow: var(--shadow-lg);
    }
    .app.drawer-open .sidebar { transform: translateX(0); }
    /* In the drawer the sidebar is always fully expanded: the desktop collapse rules live in a
       min-width media query and don't apply here — only the toggle button is hidden. */
    .side-collapse { display: none; }
    .sidebar-scrim {
        display: block; position: fixed; inset: 0; z-index: 70;
        background: rgba(0,0,0,.45); opacity: 0; pointer-events: none;
        transition: opacity .2s ease;
    }
    .app.drawer-open .sidebar-scrim { opacity: 1; pointer-events: auto; }
    .topbar-hamburger { display: grid; place-items: center; }
}

/* =================== TOPBAR =================== */
/* Niente backdrop-filter (ne' transform, filter, opacity, isolation, contain, will-change, z-index):
   creerebbe uno stacking context e un containing block per i discendenti fixed, intrappolando il
   pannello notifiche (z-index 901) e il suo sfondo cliccabile (fixed, inset 0) dentro la fascia
   della topbar, sotto le intestazioni di pagina posizionate (es. Tableau, z-index 20). Il blur non
   aveva comunque nulla da sfocare: sotto la topbar c'e' solo il colore piatto di --bg-app. */
.topbar {
    grid-area: topbar;
    display: flex; align-items: center; gap: 16px;
    padding: 0 22px;
    background: var(--topbar-bg);
    border-bottom: 1px solid var(--border);
}
.breadcrumbs { display: flex; align-items: center; gap: 8px; color: var(--text-muted); font-size: .8125rem; }
.breadcrumbs b, .breadcrumbs .topbar-title { color: var(--text-primary); font-weight: 600; }
/* Il titolo pagina e' l'unico h1 dell'app: stessa resa del vecchio <b>, semantica corretta. */
.breadcrumbs .topbar-title { margin: 0; font-size: inherit; line-height: inherit; }
.breadcrumbs .sep { opacity: .5; }
.topbar-spacer { flex: 1; }
.search {
    display: flex; align-items: center; gap: 8px;
    background: var(--bg-card-2);
    border: 1px solid var(--border-control);
    padding: 7px 12px; border-radius: 10px;
    min-width: 300px;
    color: var(--text-muted);
    font-size: .8125rem;
}
.search input {
    flex: 1; background: transparent; border: 0; outline: none; color: var(--text-primary);
    font: inherit;
}
.kbd {
    font-family: var(--mono); font-size: .6875rem;
    border: 1px solid var(--border-strong); padding: 1px 6px; border-radius: 5px;
    color: var(--text-muted);
}
/* Badge ambiente accanto alla search: compaiono solo su staging (mai in produzione),
   quindi il warning può essere vistoso senza disturbare l'uso quotidiano. */
.env-badges { display: flex; gap: 6px; }
.env-badge {
    font-family: var(--mono); font-size: .6875rem; font-weight: 700; letter-spacing: .08em;
    color: var(--warning);
    background: var(--warning-soft);
    border: 1px solid var(--warning);
    padding: 3px 8px; border-radius: 6px;
    white-space: nowrap; text-transform: uppercase;
}
.icon-btn {
    width: 36px; height: 36px; border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--bg-card-2);
    color: var(--text-secondary);
    cursor: pointer; display: grid; place-items: center;
    position: relative;
    transition: background .15s, color .15s, border-color .15s;
}
.icon-btn:hover { color: var(--accent); border-color: var(--accent-soft); background: var(--accent-soft); }
.icon-btn .dot {
    position: absolute; top: 8px; right: 9px;
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--accent); box-shadow: 0 0 6px var(--accent-glow);
}
/* Subscription health indicator on the subscription button. */
.icon-btn .dot.sub-ok     { background: var(--ok, #1f9d55);     box-shadow: 0 0 6px rgba(5,150,105,.6); }
.icon-btn .dot.sub-warn   { background: var(--warn, #d99a00);   box-shadow: 0 0 6px rgba(217,119,6,.6); }
.icon-btn .dot.sub-danger { background: var(--danger, #e3342f); box-shadow: 0 0 6px rgba(220,38,38,.6); }

/* ---- Launcher assistente AI (accanto alla ricerca) ----
   Bordo a gradiente cangiante (trucco padding-box/border-box su border trasparente) e
   scritta "AI" con gli STESSI colori via background-clip:text. L'animazione di scorrimento
   colori è sempre definita ma in pausa: all'hover parte, all'uscita si congela dov'è
   (niente scatto di ritorno). Bordo e testo condividono durata/keyframes → restano in fase. */
.ai-launch {
    --ai-grad: linear-gradient(100deg, #7c3aed, #2563eb, #06b6d4, #ec4899, #7c3aed);
    width: 36px; height: 36px; padding: 0;
    border: 2px solid transparent; border-radius: 10px;
    background:
        linear-gradient(var(--bg-card-2), var(--bg-card-2)) padding-box,
        var(--ai-grad) border-box;
    background-size: 100% 100%, 300% 300%;
    cursor: pointer;
    display: grid; place-items: center;
    animation: ai-grad-flow 2.2s ease-in-out infinite paused;
    transition: box-shadow .2s ease;
}
.ai-launch-label {
    font-size: .75rem; font-weight: 800; letter-spacing: .06em; line-height: 1;
    background: var(--ai-grad);
    background-size: 300% 300%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    animation: ai-grad-flow 2.2s ease-in-out infinite paused;
}
.ai-launch:hover,
.ai-launch:hover .ai-launch-label { animation-play-state: running; }
.ai-launch:hover { box-shadow: 0 0 14px rgba(124, 58, 237, .35); }
@keyframes ai-grad-flow {
    0%   { background-position: 0% 50%; }
    50%  { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}

/* Subscription popup — kept global (not component-scoped) so the fixed overlay is
   always styled; otherwise the modal would fall back into the layout grid. */
.sub-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1400;
    background: color-mix(in srgb, var(--bg-app, #0b0f17) 60%, transparent);
    backdrop-filter: blur(3px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    animation: sub-fade .15s ease;
}
@keyframes sub-fade { from { opacity: 0; } to { opacity: 1; } }
.sub-modal {
    position: relative;
    width: 100%;
    max-width: 420px;
    max-height: 92vh;
    overflow-y: auto;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: 0 24px 70px rgba(0, 0, 0, 0.45);
    display: flex;
    flex-direction: column;
    animation: sub-pop .18s cubic-bezier(.2,.8,.3,1.1);
}
@keyframes sub-pop { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
.sub-modal-pay { max-width: 480px; }

/* Floating close button (over the hero) */
.sub-x {
    position: absolute; top: 12px; right: 12px; z-index: 2;
    appearance: none; border: 0; cursor: pointer;
    width: 30px; height: 30px; border-radius: 8px;
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; background: rgba(255,255,255,.16);
    transition: background .12s ease;
}
.sub-x:hover { background: rgba(255,255,255,.3); }

/* Hero — colored by health */
.sub-hero {
    position: relative;
    padding: 22px 20px 18px;
    color: #fff;
    text-align: center;
    background: linear-gradient(135deg, #2563EB, #1D4ED8);
}
.sub-hero-ok     { background: linear-gradient(135deg, var(--ok, #1f9d55), #0e8a6b); }
.sub-hero-warn   { background: linear-gradient(135deg, var(--warn, #e0922b), #b45309); }
.sub-hero-danger { background: linear-gradient(135deg, var(--danger, #e0492f), #b91c1c); }
.sub-hero-icon {
    width: 46px; height: 46px; margin: 0 auto 10px;
    border-radius: 14px; display: grid; place-items: center;
    background: rgba(255,255,255,.18); color: #fff;
}
.sub-hero-title {
    font-size: .6875rem; font-weight: 700; letter-spacing: .14em;
    text-transform: uppercase; opacity: .9;
}
.sub-hero .sub-badge { margin: 10px 0 8px; }
.sub-hero-sub { font-size: .8125rem; line-height: 1.45; opacity: .95; max-width: 32ch; margin: 0 auto; }

.sub-badge {
    display: inline-flex; align-items: center; padding: 4px 12px;
    border-radius: var(--badge-radius); font-size: .6875rem; font-weight: 800;
    letter-spacing: .06em; text-transform: uppercase;
    background: rgba(255,255,255,.22); color: #fff;
}
.sub-badge-ok, .sub-badge-warn, .sub-badge-danger, .sub-badge-neutral {
    background: rgba(255,255,255,.22); color: #fff;
}

.sub-body { padding: 18px 20px; display: flex; flex-direction: column; gap: 16px; }
.sub-state { padding: 28px 8px; text-align: center; color: var(--text-secondary); font-size: .8125rem; }
.sub-state-error { color: var(--danger, #e3342f); }
.sub-renew-error { font-size: .75rem; }

/* ===== Popup versioni (logo/wordmark Stay) ===== */
.ver-modal { max-width: 560px; }
.ver-x { color: var(--text-secondary); background: var(--bg-panel); }
.ver-x:hover { background: var(--bg-hover, var(--bg-panel)); color: var(--text-primary); }
.ver-head {
    display: flex; align-items: center; gap: 14px;
    padding: 20px 56px 14px 20px;
    border-bottom: 1px solid var(--border);
}
.ver-wordmark { height: 22px; width: auto; flex: 0 0 auto; }
.ver-head-text { flex: 1 1 auto; min-width: 0; }
.ver-title { font-size: 1rem; font-weight: 700; color: var(--text-primary); line-height: 1.2; }
.ver-sub { font-size: .75rem; color: var(--text-secondary); margin-top: 2px; }
.ver-env {
    flex: 0 0 auto; font-size: .6875rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    padding: 3px 9px; border-radius: 999px; border: 1px solid var(--border-strong);
    color: var(--text-secondary); background: var(--bg-panel);
}
.ver-env.staging { color: var(--warning, #b45309); background: var(--warning-soft, rgba(245,158,11,.15)); border-color: transparent; }
.ver-body { padding: 14px 20px 20px; display: flex; flex-direction: column; gap: 18px; }
.ver-section-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
    margin-bottom: 6px;
}
.ver-section-head h3 {
    margin: 0; font-size: .75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--text-secondary);
}
.ver-release {
    font-variant-numeric: tabular-nums; font-size: .8125rem; font-weight: 700; color: var(--text-primary);
    padding: 1px 8px; border-radius: 6px; background: var(--bg-panel); border: 1px solid var(--border);
}
.ver-table { width: 100%; border-collapse: collapse; font-size: .8125rem; }
.ver-table th, .ver-table td { padding: 5px 6px; border-bottom: 1px solid var(--border); text-align: left; }
.ver-table th { font-size: .6875rem; font-weight: 600; color: var(--text-secondary); }
.ver-table .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ver-table tr:last-child td { border-bottom: 0; }
.ver-name { color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 0; width: 100%; }
.ver-ver { font-weight: 600; color: var(--text-primary); }
.ver-build { color: var(--text-secondary); font-size: .75rem; }

/* Price card */
.sub-pricecard {
    text-align: center;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-card-2, var(--bg-hover));
}
.sub-plan { font-size: .8125rem; font-weight: 600; color: var(--text-secondary); }
.sub-price { font-size: 1.875rem; font-weight: 800; color: var(--text-primary); line-height: 1.2; margin-top: 4px; }
.sub-price-note { font-size: .6875rem; color: var(--text-muted); margin-top: 2px; }

/* Detail grid */
.sub-grid { display: grid; grid-template-columns: auto 1fr; gap: 9px 16px; margin: 0; }
.sub-grid dt { color: var(--text-muted); font-size: .75rem; align-self: center; }
.sub-grid dd { margin: 0; text-align: right; color: var(--text-primary); font-size: .8125rem; font-weight: 600; }
.sub-grid dd.sub-warn   { color: var(--warn, #9a6700); }
.sub-grid dd.sub-danger { color: var(--danger, #b3251f); }

/* Embedded Stripe checkout */
.sub-checkout { min-height: 260px; }
.sub-secure {
    display: flex; align-items: center; justify-content: center; gap: 6px;
    margin-top: 12px; color: var(--text-muted); font-size: .6875rem;
}

/* Success state */
.sub-success { text-align: center; padding: 14px 8px 6px; }
.sub-success-check {
    width: 60px; height: 60px; margin: 0 auto 14px;
    border-radius: 50%; display: grid; place-items: center;
    color: #fff; background: linear-gradient(135deg, var(--ok, #1f9d55), #0e8a6b);
    animation: sub-pop .28s cubic-bezier(.16, 1, .3, 1); /* arrivo deciso, senza rimbalzo */
}
.sub-success-title { font-size: 1.0625rem; font-weight: 800; color: var(--text-primary); }
.sub-success-msg { font-size: .8125rem; color: var(--text-secondary); margin-top: 6px; line-height: 1.45; }
.sub-success-pending { font-size: .75rem; color: var(--warn, #9a6700); margin-top: 10px; }

/* Footer + buttons */
.sub-footer {
    flex: 0 0 auto; display: flex; justify-content: flex-end; gap: 8px;
    padding: 14px 20px 18px;
}
.sub-btn {
    appearance: none; border: 1px solid var(--border); border-radius: var(--radius);
    padding: 11px 18px; font-size: .875rem; font-weight: 700; cursor: pointer;
    transition: filter .12s ease, background .12s ease, color .12s ease, border-color .12s ease, opacity .12s ease;
}
.sub-btn:disabled { opacity: .6; cursor: default; }
.sub-btn-ghost { background: transparent; color: var(--text-secondary); }
.sub-btn-ghost:hover { background: var(--bg-hover); color: var(--text-primary); }
.sub-btn-primary {
    flex: 1 1 auto;
    background: linear-gradient(135deg, var(--accent, #2563EB), var(--accent-2, #3B82F6));
    border-color: transparent; color: var(--on-accent, #fff);
    box-shadow: 0 6px 18px var(--accent-glow, rgba(92,95,233,.35));
}
.sub-btn-primary:not(:disabled):hover { filter: brightness(1.07); }

/* Theme menu */
.theme-menu {
    position: absolute;
    top: calc(var(--topbar-h) - 8px);
    right: 22px;
    min-width: 240px;
    background: var(--bg-panel);
    border: 1px solid var(--border-strong);
    border-radius: 12px;
    box-shadow: var(--shadow-lg);
    padding: 6px;
    z-index: 30;
    display: none;
}
.theme-menu.open { display: block; animation: fadeIn .14s ease; }
@keyframes fadeIn { from{opacity:0;transform:translateY(-4px)} to{opacity:1;transform:translateY(0)} }
.theme-menu-title {
    font-size: .6875rem; text-transform: uppercase; letter-spacing: .12em;
    color: var(--text-muted); padding: 8px 12px 6px;
}
.theme-option {
    display: flex; align-items: center; gap: 12px;
    padding: 9px 10px; border-radius: 8px; cursor: pointer;
    color: var(--text-secondary); font-size: .8125rem; font-weight: 500;
    background: transparent; border: 0; width: 100%;
    transition: background .12s ease, color .12s ease;
}
.theme-option:hover { background: var(--bg-hover); color: var(--text-primary); }
.theme-option.active { color: var(--accent); background: var(--bg-active); }
.theme-option .swatch {
    width: 22px; height: 22px; border-radius: 6px;
    border: 1px solid var(--border-strong); flex: 0 0 22px;
}
.theme-option .swatch.dark { background: linear-gradient(135deg, #0d0d0f 40%, #2563EB 40% 55%, #1D4ED8 55%); }
.theme-option .swatch.indigo { background: linear-gradient(135deg, #0e1116 40%, #7073F0 40% 55%, #575AE8 55%); }
.theme-option .swatch.light { background: linear-gradient(135deg, #ffffff 40%, #2563EB 40% 55%, #f4f5fb 55%); }
.theme-option .swatch.hc { background: linear-gradient(135deg, #000000 40%, #ffcc00 40% 55%, #000000 55%); border-color: #fff; }
.theme-option .swatch.auto { background: linear-gradient(135deg, #ffffff 50%, #0d0d0f 50%); }
/* Dimensione testo: glifo "Aa" al posto dello swatch (il secondo gruppo del menu Aspetto). */
.theme-option .size-glyph {
    width: 22px; height: 22px; border-radius: 6px; flex: 0 0 22px;
    border: 1px solid var(--border-strong);
    display: grid; place-items: center;
    font-size: .625rem; font-weight: 700; letter-spacing: -.02em; color: var(--text-secondary);
}
.theme-option .size-glyph.xl { font-size: .8125rem; }
.theme-menu-title.sub { margin-top: 6px; padding-top: 10px; border-top: 1px solid var(--border); }

/* Language menu — same shell as the theme menu, with a small monospaced 2-letter
   chip in place of the colored swatch so each option reads as a recognised locale code. */
.theme-option .lang-code {
    width: 22px; height: 22px;
    border-radius: 6px;
    border: 1px solid var(--border-strong);
    flex: 0 0 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font: 700 .6875rem var(--mono);
    letter-spacing: 0.04em;
    background: var(--bg-card-2);
    color: var(--text-secondary);
}
.theme-option.active .lang-code {
    background: var(--accent-soft);
    color: var(--accent);
    border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}

/* =================== MAIN =================== */
.main {
    grid-area: main;
    overflow: hidden;
    display: flex;
    padding: 18px;
    gap: 16px;
}
.master {
    flex: 1 1 58%;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    display: flex; flex-direction: column;
    min-width: 0;
    box-shadow: var(--shadow);
}
.detail {
    flex: 0 0 42%;
    max-width: 520px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    display: flex; flex-direction: column;
    box-shadow: var(--shadow);
    overflow: hidden;
}
.panel-full {
    flex: 1 1 auto;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    display: flex; flex-direction: column;
    box-shadow: var(--shadow);
    overflow: hidden;
}

/* Generic master/detail layout (cx-* family).
   Scoped overrides in CustomersList.razor.css win on specificity thanks to the
   [b-xxx] attribute that Blazor appends. Any page outside CustomersList that
   uses these class names picks up the global rules below. */
.cx-master, .cx-detail {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    display: flex;
    flex-direction: column;
    box-shadow: var(--shadow);
    overflow: hidden;
    min-height: 0;
}
.cx-master { flex: 1 1 60%; min-width: 0; }
.cx-detail { flex: 0 0 620px; max-width: 720px; min-width: 520px; }

.cx-toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 18px;
    border-bottom: 1px solid var(--border);
    flex: 0 0 auto;
}
.cx-toolbar-title { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.cx-toolbar-title b { font-size: .875rem; font-weight: 700; color: var(--text-primary); }
.cx-toolbar-title span { font-size: .6875rem; color: var(--text-muted); letter-spacing: 0.08em; text-transform: uppercase; }
.cx-toolbar-actions { display: flex; gap: 8px; align-items: center; }

.cx-search-group {
    display: flex;
    align-items: stretch;
    border: 1px solid var(--border-control);
    border-radius: 10px;
    background: var(--bg-card-2);
    overflow: hidden;
}
.cx-search-group:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 4px var(--accent-soft);
    background: var(--bg-card);
}
.cx-search {
    width: 220px;
    min-width: 0;
    padding: 0 12px 0 34px;
    height: 36px;
    border: 0;
    background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E") no-repeat 12px center / 14px 14px;
    color: var(--text-primary);
    font: 500 .8125rem 'Inter', sans-serif;
    outline: none;
}
:root[data-theme="hc"] .cx-search {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23e2e8f0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
}
.cx-search::placeholder { color: var(--text-muted); opacity: .75; font-weight: 400; }

/* Badge outline monocromatici: un solo colore per bordo, icona e testo, fondo trasparente.
   L'icona SVG inline eredita il colore via stroke="currentColor". */
.cx-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: var(--badge-radius);
    border: 1px solid currentColor;
    background: transparent;
    font-size: .6875rem;
    font-weight: 600;
    white-space: nowrap;
}
.cx-badge svg { width: 13px; height: 13px; flex: 0 0 auto; }
.cx-badge b { font-weight: 700; }
.cx-badge--amber { color: #b45309; }
.cx-badge--sky { color: #0369a1; }
.cx-badge--neutral { color: var(--text-muted); }
:root[data-theme="dark"] .cx-badge--amber, :root[data-theme="indigo"] .cx-badge--amber { color: #fbbf24; }
:root[data-theme="dark"] .cx-badge--sky, :root[data-theme="indigo"] .cx-badge--sky { color: #38bdf8; }
:root[data-theme="hc"] .cx-badge--amber { color: #fcd34d; }
:root[data-theme="hc"] .cx-badge--sky { color: #7dd3fc; }

/* ── Nastro segnaletico della manutenzione (blocco camera) ──────────────────────────────────
   .maint-tape: superficie a strisce diagonali -45° giallo/nero (token --maint-tape-* sopra). Lo
   spessore si scala con --maint-tape-stripe sull'elemento o su un antenato (default 10px; es. 4px
   per una striscia stretta, metà altezza per una barra). MAI testo sopra le strisce.
   .maint-tape-chip: badge "Fuori uso fino al 14/11" = spezzone di nastro + pastiglia nera piena con
   testo bianco (contrasto AA). Stesso nastro per Fuori uso e Fuori servizio: il tipo sta nel testo. */
.maint-tape {
    /* --maint-tape-alpha (default 100%) rende il nastro semitrasparente, es. 30% nella legenda del Tableau. */
    background-color: color-mix(in srgb, var(--maint-tape-black) var(--maint-tape-alpha, 100%), transparent);
    background-image: repeating-linear-gradient(-45deg,
        color-mix(in srgb, var(--maint-tape-yellow) var(--maint-tape-alpha, 100%), transparent) 0 var(--maint-tape-stripe, 10px),
        color-mix(in srgb, var(--maint-tape-black) var(--maint-tape-alpha, 100%), transparent) var(--maint-tape-stripe, 10px) calc(2 * var(--maint-tape-stripe, 10px)));
}
.maint-tape-chip {
    display: inline-flex;
    align-items: stretch;
    max-width: 100%;
    min-height: 22px;
    border: 1px solid var(--maint-tape-edge);
    border-radius: var(--badge-radius);
    overflow: hidden;
    background: var(--maint-tape-black);
    color: var(--maint-tape-ink);
    font-size: .6875rem;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    vertical-align: middle;
}
.maint-tape-chip > .maint-tape {
    --maint-tape-stripe: 4px;
    flex: 0 0 auto;
    width: 16px;
}
.maint-tape-chip-label {
    align-self: center;
    padding: 3px 8px 3px 7px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cx-primary-btn {
    appearance: none;
    border: 0;
    border-radius: 10px;
    padding: 0 14px;
    height: 36px;
    display: inline-flex; align-items: center; gap: 6px;
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-deep) 100%);
    color: var(--on-accent);
    font: 600 .7812rem 'Inter', sans-serif;
    cursor: pointer;
    box-shadow: 0 6px 14px var(--accent-glow);
    transition: filter 0.12s ease, transform 0.12s ease;
}
.cx-primary-btn:hover { filter: brightness(1.1); }
.cx-primary-btn:active { transform: translateY(1px); }
.cx-primary-btn svg { display: block; }
.cx-primary-btn:disabled { opacity: .55; cursor: not-allowed; filter: grayscale(.3); }

/* Pulsanti dell'hero delle schede (Clienti/Aziende): neutro + variante primaria. Prima duplicati
   nei css scoped di CompaniesList e CustomerCard. */
.cx-hero-btn {
    appearance: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    height: 32px;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--bg-card-2);
    color: var(--text-secondary);
    font: 600 .75rem 'Inter', sans-serif;
    text-decoration: none;
    transition: background .12s ease, color .12s ease, border-color .12s ease, transform .08s ease;
}
.cx-hero-btn:hover {
    background: var(--bg-card);
    border-color: var(--border-strong);
    color: var(--text-primary);
}
.cx-hero-btn:active { transform: translateY(1px); }
.cx-hero-btn svg { width: 13px; height: 13px; flex-shrink: 0; }
.cx-hero-btn.disabled,
.cx-hero-btn[href=""] {
    pointer-events: none;
    opacity: 0.4;
}
.cx-hero-btn-primary {
    background: linear-gradient(135deg, var(--accent), var(--accent-deep));
    color: var(--on-accent);
    border-color: transparent;
    box-shadow: 0 4px 12px var(--accent-glow);
}
.cx-hero-btn-primary:hover {
    color: var(--on-accent);
    border-color: transparent;
    filter: brightness(1.08);
    background: linear-gradient(135deg, var(--accent), var(--accent-deep));
}


/* Indicatore di attesa dentro un pulsante (BusyButton). Prende il posto dell'icona mentre
   l'azione è in corso: dice all'utente che il click è stato preso, che è il motivo per cui
   normalmente ne farebbe un secondo. Le dimensioni seguono l'icona standard dei .btn (14px).
   Variante dedicata e non riuso di .spinner: quella è tarata sui pannelli in caricamento
   (18px, --accent su --border-strong) e dentro un .btn-primary sarebbe accent su accent,
   quindi invisibile. Qui il colore è currentColor, così eredita il testo del pulsante e resta
   leggibile sul primario colorato come sul neutro, in tutti i temi. */
.cx-btn-spinner {
    width: 14px;
    height: 14px;
    flex: 0 0 auto;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    opacity: .85;
    animation: cx-btn-spin .6s linear infinite;
}
@keyframes cx-btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    /* Nessuna rotazione: resta un cerchio statico, il pulsante disabilitato segnala già l'attesa. */
    .cx-btn-spinner { animation: none; border-top-color: currentColor; opacity: .5; }
    /* Drawer e scrim compaiono senza scorrere; il cambio di stato resta leggibile (opacita' immediata). */
    .sidebar, .sidebar-scrim, .theme-menu, .nav-row-chev, .panel-group-chev, .side-collapse svg { transition: none !important; animation: none !important; }
}

.panel-header {
    display: flex; align-items: center; gap: 12px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border);
}
.panel-title { display: flex; flex-direction: column; gap: 2px; }
.panel-title b { font-size: .9375rem; font-weight: 700; }
.panel-title span { font-size: .6875rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: .1em; }
.panel-actions { margin-left: auto; display: flex; gap: 8px; }

.btn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 7px 12px; border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--bg-card-2);
    color: var(--text-secondary);
    font: 500 .7812rem 'Inter', sans-serif;
    cursor: pointer;
    transition: all .15s ease;
}
.btn:hover:not(:disabled) { border-color: var(--border-strong); color: var(--text-primary); }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-primary {
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-deep) 100%);
    color: var(--on-accent); border-color: transparent; font-weight: 700;
    box-shadow: 0 6px 16px var(--accent-glow);
}
.btn-primary:hover:not(:disabled) { filter: brightness(1.08); color: var(--on-accent); }
.btn-ghost { background: transparent; }
.btn-danger {
    background: var(--danger);
    color: var(--on-accent); border-color: transparent; font-weight: 700;
}
.btn-danger:hover:not(:disabled) { filter: brightness(1.1); color: var(--on-accent); }
/* Taglia compatta per azioni di riga/card (era ridefinita in 4 css scoped con due altezze diverse). */
.btn-xs { padding: 3px 9px; height: 26px; font-size: .7188rem; border-radius: 7px; }
/* Footer "Elimina" delle schede (shared DeleteButton): chrome neutro come Annulla,
   solo l'icona cestino è rossa; al hover il rosso si estende a testo e bordo.
   Il rosso pieno (.btn-danger) resta al bottone di conferma nei popup. */
.btn-delete svg { color: var(--danger); }
.btn-delete:hover:not(:disabled) { border-color: var(--danger); color: var(--danger); }

.toolbar {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border);
    background: rgba(255,255,255,0.015);
}
.chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 10px; font-size: .75rem;
    background: var(--bg-card-2); border: 1px solid var(--border);
    border-radius: var(--badge-radius); color: var(--text-secondary);
    cursor: pointer; white-space: nowrap;
}
.chip.active { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.chip:hover { color: var(--text-primary); }
/* Pallino colore data-driven dentro una chip (es. colore del tipo camera nei filtri
   matrice listino): il colore arbitrario resta confinato al dot, mai sulla chip intera
   (nessuna garanzia di contrasto col testo, romperebbe il tema HC). */
.chip-dot {
    width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto;
    border: 1px solid var(--border-strong);
}

/* Grid/Table */
.grid-wrap { flex: 1 1 auto; overflow: auto; }
table.grid {
    width: 100%; border-collapse: separate; border-spacing: 0;
    font-size: .8125rem;
}
table.grid thead th {
    position: sticky; top: 0; z-index: 1;
    text-align: left; font-weight: 600; font-size: .6875rem;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--text-muted);
    padding: 10px 14px;
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
table.grid tbody td {
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    color: var(--text-secondary);
    vertical-align: middle;
}
table.grid tbody tr { cursor: pointer; transition: background .12s ease; }
table.grid tbody tr:hover { background: var(--bg-hover); }
table.grid tbody tr.selected { background: var(--bg-active); }
table.grid tbody tr.selected td { color: var(--text-primary); }
table.grid tbody tr.selected td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

.cell-id { font-family: var(--mono); color: var(--text-muted); font-size: .75rem; }
.cell-name { color: var(--text-primary); font-weight: 600; }
.cell-sub { font-size: .6875rem; color: var(--text-muted); margin-top: 2px; }

/* ── Righe raggruppate (griglie risorse: intestazione per gruppo, poi le risorse) ──
 * La riga di sezione non è selezionabile: stesso registro tipografico dell'intestazione
 * tabella, pallino col colore del gruppo, conteggio a destra del nome.
 */
table.grid tbody tr.grid-group-row { cursor: default; }
table.grid tbody tr.grid-group-row:hover { background: transparent; }
table.grid tbody tr.grid-group-row td {
    padding: 8px 14px 6px;
    background: var(--bg-subtle, var(--bg-card));
    font-size: .6875rem; font-weight: 600;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--text-muted);
    white-space: nowrap;
}
.grid-group-dot {
    display: inline-block; width: 10px; height: 10px; border-radius: 50%;
    background: var(--border-strong); border: 1px solid var(--border-strong);
    margin-right: 8px; vertical-align: -1px;
}
.grid-group-type { color: var(--text-muted); font-weight: 500; margin-right: 4px; }
.grid-group-name { color: var(--text-primary); }
.grid-group-count {
    display: inline-block; min-width: 18px; margin-left: 8px; padding: 0 6px;
    border-radius: 999px; background: var(--bg-hover); color: var(--text-muted);
    font-family: var(--mono); font-size: .6875rem; letter-spacing: 0; text-align: center;
}

/* ── Drag-and-drop reorder (opt-in via .grid-reorder on the table) ──
 * Adds a drag-handle column with a six-dot grip, a "lift" effect on the row
 * being dragged and a top-edge indicator on the row about to receive the drop.
 */
table.grid.grid-reorder tbody tr { cursor: pointer; }
table.grid.grid-reorder tbody tr.dragging {
    opacity: .45;
    background: var(--bg-card-2);
}
table.grid.grid-reorder tbody tr.drag-over td {
    box-shadow: inset 0 2px 0 var(--accent);
}

.cell-grip {
    width: 36px;
    text-align: center;
    color: var(--text-muted);
    cursor: grab;
    user-select: none;
}
.cell-grip:active { cursor: grabbing; }
.cell-grip svg {
    display: inline-block;
    vertical-align: middle;
    transition: color 0.12s ease, transform 0.12s ease;
}
table.grid.grid-reorder tbody tr:hover .cell-grip { color: var(--accent); }
table.grid.grid-reorder tbody tr:hover .cell-grip svg { transform: scale(1.1); }
.cell-flag { width: 24px; height: 16px; border-radius: 2px; object-fit: cover; vertical-align: middle; margin-right: 8px; background: var(--bg-card-2); }

/* Badge di stato: UNA primitiva per tutta l'app. Il colore arriva da --st-color: le varianti
   semantiche (.ok/.warn/.err/.info/.muted) lo impostano dai token, la griglia prenotazioni e il
   tableau lo passano inline dalla lookup. Sfondo e bordo derivano dal colore (color-mix), cosi'
   il badge regge in ogni tema senza rgba fissi. */
.status {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 3px 9px; border-radius: var(--badge-radius);
    font-size: .6875rem; font-weight: 600; white-space: nowrap;
    color: var(--st-color, var(--text-secondary));
    background: color-mix(in srgb, var(--st-color, var(--border)) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--st-color, var(--border)) 34%, transparent);
}
.status::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.status.ok { --st-color: var(--success); }
.status.warn { --st-color: var(--warning); }
.status.err { --st-color: var(--danger); }
.status.info { --st-color: var(--info); }
.status.muted { --st-color: var(--text-muted); }

/* Segmented control: UNA primitiva (era .seg pill in Dashboard + .bkm-seg nei due modali booking).
   Contenitore a rettangolo arrotondato, segmento attivo pieno accent. I figli possono essere
   <button> diretti oppure .seg-btn. */
.seg {
    display: inline-flex; gap: 3px; padding: 3px;
    border-radius: 10px;
    background: var(--bg-card-2);
    border: 1px solid var(--border);
}
.seg > button, .seg-btn {
    flex: 1 1 0; min-width: 0;
    padding: 6px 10px; border: 0; border-radius: 7px;
    background: transparent; color: var(--text-muted);
    font: inherit; font-size: .6875rem; font-weight: 600; white-space: nowrap;
    cursor: pointer;
    transition: color .12s ease, background .12s ease;
}
.seg > button:hover:not(.active), .seg-btn:hover:not(.active) { color: var(--text-primary); }
.seg > button.active, .seg-btn.active { background: var(--accent); color: var(--on-accent); }

/* Testi di supporto (al posto degli style inline "font-size:13px; color:var(--text-muted)"). */
.dlg-text { font-size: .8125rem; color: var(--text-muted); }
.hint-sm { font-size: .75rem; color: var(--text-muted); }
.hint-xs { font-size: .6875rem; color: var(--text-muted); }

/* Detail */
.detail-hero {
    padding: 18px;
    background: linear-gradient(160deg, var(--accent-soft), transparent 60%), var(--bg-card);
    border-bottom: 1px solid var(--border);
}
.detail-hero .title-row { display: flex; align-items: flex-start; gap: 14px; }
.detail-avatar {
    width: 48px; height: 48px; border-radius: 12px;
    background: linear-gradient(135deg, var(--accent), var(--accent-deep));
    color: #fff; display: grid; place-items: center;
    font-weight: 800; font-size: 1.125rem;
    box-shadow: 0 8px 18px var(--accent-glow);
}
.detail-hero h3 { margin: 0; font-size: 1.125rem; font-weight: 700; }
.detail-hero .meta { color: var(--text-muted); font-size: .75rem; margin-top: 2px; font-family: var(--mono); }

.detail-body { flex: 1 1 auto; overflow-y: auto; padding: 18px; }

.field-group {
    display: grid; grid-template-columns: 140px 1fr;
    gap: 10px 14px;
    padding: 12px 0;
    border-bottom: 1px dashed var(--border);
    font-size: .8125rem;
}
.field-group:last-child { border-bottom: 0; }
.field-label { color: var(--text-muted); font-size: .75rem; }
.field-value { color: var(--text-primary); font-weight: 500; word-break: break-word; }
.field-value.mono { font-family: var(--mono); font-size: .75rem; }

/* Anagrafica con logo a destra: il riquadro del logo prende l'altezza del blocco dati (non la determina);
   l'immagine è assoluta, quindi si ridimensiona dentro l'altezza esistente senza allargarla. */
.detail-with-logo { display: flex; gap: 24px; align-items: stretch; border-bottom: 1px dashed var(--border); }
.detail-with-logo > .field-group { flex: 1 1 auto; min-width: 0; border-bottom: 0; }
.org-logo { flex: 0 0 clamp(140px, 22%, 260px); position: relative; margin: 12px 0; }
.org-logo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; object-position: right center; }
@media (max-width: 720px) {
    .detail-with-logo { flex-direction: column-reverse; gap: 0; }
    .org-logo { flex-basis: auto; height: 80px; }
}

.detail-section-title {
    font-size: .6875rem; text-transform: uppercase; letter-spacing: .12em;
    color: var(--text-muted); margin: 18px 0 8px;
    display: flex; align-items: center; gap: 8px;
}
.detail-section-title::after { content: ""; flex: 1; height: 1px; background: var(--border); }

.empty-state {
    flex: 1 1 auto; display: grid; place-items: center;
    padding: 24px; text-align: center;
    color: var(--text-muted);
}
.empty-state .eicon {
    width: 56px; height: 56px; border-radius: 14px;
    background: var(--bg-card-2); border: 1px solid var(--border);
    display: grid; place-items: center; margin: 0 auto 14px;
    color: var(--accent);
}
.empty-state h4 { margin: 0 0 6px; color: var(--text-primary); font-size: .9375rem; }

/* ── Shared form controls (global so programmatically-rendered selects hit them too) ── */

.cx-input,
.cx-select,
.cx-textarea {
    width: 100%;
    height: 40px;
    padding: 0 14px;
    border-radius: 10px;
    border: 1px solid var(--border-control);
    background: var(--bg-card-2);
    color: var(--text-primary);
    font: 500 .8125rem 'Inter', 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', sans-serif;
    line-height: 1.3;
    outline: none;
    box-shadow: 0 1px 2px rgba(0,0,0,0.04);
    transition: border-color 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;
}
.cx-input::placeholder,
.cx-textarea::placeholder { color: var(--text-muted); opacity: .75; font-weight: 400; }

.cx-input:hover,
.cx-select:hover,
.cx-textarea:hover {
    border-color: var(--border-strong);
    background-color: var(--bg-card);
}
.cx-input:focus,
.cx-select:focus,
.cx-textarea:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 4px var(--accent-soft), 0 1px 2px rgba(0,0,0,0.04);
    background-color: var(--bg-card);
}
.cx-input:disabled,
.cx-select:disabled,
.cx-textarea:disabled {
    opacity: .55;
    cursor: not-allowed;
}
.cx-input.mono { font-family: var(--mono); font-size: .7812rem; letter-spacing: 0.02em; }

/* ── Freccine native dei type="number": MAI. Rete di sicurezza per qualunque <input type="number">
 * sfugga a StayNumberField (o venga aggiunto in futuro): bersagli da 8 px, rotella che cambia il
 * valore per sbaglio. Le frecce tastiera continuano a funzionare. */
.cx-input[type="number"],
.price-cell-input { appearance: textfield; -moz-appearance: textfield; }
.cx-input[type="number"]::-webkit-outer-spin-button,
.cx-input[type="number"]::-webkit-inner-spin-button,
.price-cell-input::-webkit-outer-spin-button,
.price-cell-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ── StayNumberField (.snf) — campo numerico condiviso ───────────────────────────────────────
 * Due modi: .snf-amount (testo + unita', niente bottoni) e .snf-stepper (− + da 40 px).
 * L'input e' un .cx-input normale: eredita bordo/focus/req/invalid dalle regole sopra.
 * Il tieni-premuto sui .snf-btn, la selezione al focus e il blocco dei default di ↑↓/PgUp/PgDn
 * sono delegati in app.js (nessun interop). */
.snf { position: relative; display: block; width: 100%; min-width: 0; }
.snf-input {
    text-align: right;
    font-variant-numeric: tabular-nums;
    letter-spacing: .01em;
}
.snf-amount .snf-input { padding-right: calc(14px + var(--unit-w, 0px)); }
.snf-unit {
    position: absolute; right: 13px; top: 50%; transform: translateY(-50%);
    font-size: .75rem; font-weight: 500; color: var(--text-muted);
    pointer-events: none; user-select: none;
}
.snf-disabled .snf-unit { opacity: .55; }

.snf-hint {
    position: absolute; left: 0; right: 0; top: calc(100% + 5px);
    font-family: var(--mono); font-size: .625rem; color: var(--text-muted); white-space: nowrap;
    opacity: 0; transform: translateY(-3px); pointer-events: none;
    transition: opacity .16s ease, transform .16s ease;
}
.snf:focus-within .snf-hint { opacity: 1; transform: none; }

/* Sola lettura: valore formattato con unita', allineato a destra come la casella che sostituisce. */
.snf-ro {
    display: flex; align-items: center; justify-content: flex-end; gap: 5px;
    min-height: 40px; padding: 0 14px;
    font: 600 .8125rem 'Inter', sans-serif; font-variant-numeric: tabular-nums; color: var(--text-primary);
}
.snf-ro-unit { color: var(--text-muted); font-weight: 500; }

/* Stepper: contenitore con l'aspetto del .cx-input, input trasparente in mezzo. */
.snf-step {
    display: grid; grid-template-columns: 40px minmax(0, 1fr) 40px; height: 40px; overflow: hidden;
    border: 1px solid var(--border-control); border-radius: 10px; background: var(--bg-card-2);
    box-shadow: 0 1px 2px rgba(0,0,0,.04);
    transition: border-color .18s ease, box-shadow .18s ease, background-color .18s ease;
}
.snf-step:hover { border-color: var(--border-strong); background: var(--bg-card); }
.snf-step:focus-within { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft), 0 1px 2px rgba(0,0,0,.04); background: var(--bg-card); }
.snf.cx-req .snf-step { border-color: var(--req); background: var(--req-soft); }
.snf.cx-req .snf-step:focus-within { box-shadow: 0 0 0 4px rgba(224,147,42,.16); }
.snf-invalid .snf-step { border-color: var(--danger); box-shadow: 0 0 0 3px rgba(220,38,38,.18); background: rgba(220,38,38,.04); }
.snf-step .cx-input,
.cx-invalid .snf-step .cx-input,
.cx-req .snf-step .cx-input {
    height: 100%; border: 0; border-radius: 0; background: transparent; box-shadow: none;
    text-align: center; padding: 0 4px;
}
.snf-step .cx-input:disabled { opacity: 1; }
.snf-disabled .snf-step { opacity: .55; }
.snf-btn {
    border: 0; background: transparent; color: var(--text-secondary); cursor: pointer; padding: 0;
    display: grid; place-items: center; user-select: none; -webkit-user-select: none; touch-action: manipulation;
    transition: background-color .12s ease, color .12s ease;
}
.snf-btn:first-child { border-right: 1px solid var(--border); }
.snf-btn:last-child { border-left: 1px solid var(--border); }
.snf-btn:hover:not(:disabled) { background: var(--accent-soft); color: var(--accent); }
.snf-btn:active:not(:disabled) { background: var(--bg-active); }
.snf-btn:disabled { color: var(--text-muted); opacity: .4; cursor: not-allowed; }
.snf-btn svg { width: 14px; height: 14px; }

/* "Sei arrivato al bordo": scossone di 2 px e bordo ambra 220 ms. Non e' un errore. */
@keyframes snf-nudge { 0%, 100% { transform: translateX(0); } 30% { transform: translateX(-2px); } 70% { transform: translateX(2px); } }
.snf-nudge .snf-input, .snf-nudge .snf-step { animation: snf-nudge .18s ease; }
.snf-nudge.snf-amount .snf-input, .snf-nudge .snf-step { border-color: var(--warning); }
.snf-nudge .snf-step .snf-btn:disabled { color: var(--warning); opacity: 1; }
@media (prefers-reduced-motion: reduce) { .snf-nudge .snf-input, .snf-nudge .snf-step { animation: none; } }
@media (pointer: coarse) {
    .snf-step { height: 44px; grid-template-columns: 44px minmax(0, 1fr) 44px; }
    .snf-ro { min-height: 44px; }
}
.cx-textarea {
    height: auto;
    min-height: 88px;
    padding: 10px 14px;
    resize: vertical;
    font-family: 'Inter', sans-serif;
    line-height: 1.5;
}
/* Compact variant — roughly half the default height (UsersList "Note"). */
.cx-textarea-compact { min-height: 44px; }

/* ── Inline field validation ──────────────────────────────────────────────
 * Missing required inputs are flagged on the control itself (red outline) with
 * a short message rendered right below it. The generic .alert banner stays for
 * server/generic failures only. */
.cx-input.input-error,
.cx-select.input-error,
.cx-textarea.input-error {
    border-color: var(--danger);
    box-shadow: inset 0 0 0 1px var(--danger);
}
.cx-input.input-error:focus,
.cx-select.input-error:focus,
.cx-textarea.input-error:focus {
    border-color: var(--danger);
    box-shadow: 0 0 0 4px rgba(234, 57, 67, .18), inset 0 0 0 1px var(--danger);
}
.field-error {
    display: flex; align-items: center; gap: 5px;
    margin-top: 5px;
    font-size: .7188rem; font-weight: 500;
    color: var(--danger);
}
.field-error svg { flex: 0 0 auto; }

.cx-select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding-right: 40px;
    cursor: pointer;
    background-image:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2300ADEF' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 16px;
}
.cx-select:hover {
    background-image:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2300ADEF' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
}
:root[data-theme="dark"] .cx-select, :root[data-theme="indigo"] .cx-select {
    background-image:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235C5FE9' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
}
:root[data-theme="dark"] .cx-select:hover, :root[data-theme="indigo"] .cx-select:hover {
    background-image:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%237B7DFF' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
}
:root[data-theme="hc"] .cx-select {
    background-image:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffcc00' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
}
:root[data-theme="hc"] .cx-select:hover {
    background-image:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffdd33' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
}
.cx-select option {
    background: var(--bg-card);
    color: var(--text-primary);
    padding: 10px 14px;
    font-size: .8125rem;
    line-height: 1.6;
}
.cx-select::-ms-expand { display: none; }

/* ── Required-field marker + invalid outline (customer card validation) ──
 * Global (not scoped) so they also reach the <select>s built via RenderTreeBuilder
 * and the municipality autocomplete rendered inside its own child component.
 * .cx-required: asterisk next to a mandatory label, shown only in edit mode.
 * .cx-invalid:  red outline on the control once validation is revealed (first save). */
.cx-required {
    color: var(--danger, #d64545);
    font-weight: 700;
    margin-left: 3px;
}
/* .req-mark: asterisco AMBRA per "obbligatorio ancora da compilare" (stato informativo).
 * Il rosso di .cx-required/.cx-invalid resta riservato all'errore dopo il salvataggio. */
.req-mark {
    color: var(--req);
    font-weight: 700;
    margin-left: 3px;
}
/* .cx-req: bordo ambra sottile sul controllo obbligatorio ancora vuoto. Funziona sia diretto
 * (.cx-input.cx-req) sia via wrapper (.cx-req .cx-input), come .cx-invalid. Dichiarato PRIMA del
 * blocco .cx-invalid così, a parità di specificità, il rosso dell'errore vince sull'ambra. */
.cx-input.cx-req,
.cx-select.cx-req,
.cx-textarea.cx-req,
.cx-req .cx-input,
.cx-req .cx-select,
.cx-req .cx-textarea,
.cx-req .psm-input {
    border-color: var(--req);
    background-color: var(--req-soft);
}
.cx-input.cx-req:focus,
.cx-select.cx-req:focus,
.cx-textarea.cx-req:focus,
.cx-req .cx-input:focus,
.cx-req .cx-select:focus,
.cx-req .cx-textarea:focus {
    border-color: var(--req);
    box-shadow: 0 0 0 4px rgba(224, 147, 42, 0.16);
}
.cx-field-value.cx-invalid .cx-input,
.cx-field-value.cx-invalid .cx-select,
.cx-field-value.cx-invalid .cx-textarea,
.cx-field-value.cx-invalid .psm-input {
    border-color: var(--danger, #d64545);
    box-shadow: 0 0 0 3px rgba(220, 38, 38, .18);
    background-color: rgba(220, 38, 38, .04);
}
.cx-field-value.cx-invalid .cx-input:focus,
.cx-field-value.cx-invalid .cx-select:focus,
.cx-field-value.cx-invalid .cx-textarea:focus,
.cx-field-value.cx-invalid .psm-input:focus {
    border-color: var(--danger, #d64545);
    box-shadow: 0 0 0 4px rgba(220, 38, 38, .22);
}
/* .cx-color-picker: <input type="color"> nativo con bordo/raggio del tema. Il bordo del
 * swatch interno e il padding dello user-agent si neutralizzano via pseudo-elementi vendor
 * (non impostabili inline). Globale: usato da ProductsList, BookingGroupModal, BookingGroupPage. */
.cx-color-picker {
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: transparent;
    cursor: pointer;
}
.cx-color-picker::-webkit-color-swatch-wrapper { padding: 0; }
.cx-color-picker::-webkit-color-swatch { border: none; border-radius: 7px; }
.cx-color-picker::-moz-color-swatch { border: none; border-radius: 7px; }

/* Generic invalid-field outline: any wrapper tagged .cx-invalid outlines the controls
 * inside it, regardless of the field-layout class the page uses (.cx-field-value,
 * .field-value, …). Complements the customer-card rule above so every data-entry form
 * shares one red-outline treatment. */
.cx-invalid .cx-input,
.cx-invalid .cx-select,
.cx-invalid .cx-textarea,
.cx-invalid .psm-input,
.cx-invalid .cx-color-picker {
    border-color: var(--danger, #d64545);
    box-shadow: 0 0 0 3px rgba(220, 38, 38, .18);
    background-color: rgba(220, 38, 38, .04);
}

/* .cx-field-error: the "campo obbligatorio" message rendered directly under an invalid
 * field (see the shared FieldError component). Global so it is available to every form. */
.cx-field-error {
    display: block;
    margin-top: 4px;
    padding: 5px 9px;
    border-radius: 6px;
    font-size: .6875rem;
    line-height: 1.35;
    color: var(--danger, #d64545);
    background: rgba(220, 38, 38, .10);
    border: 1px solid rgba(220, 38, 38, .30);
}

/*
 * Modern date picker — restyle the native <input type="date"> so it matches
 * the cx-input/cx-select look: themed calendar glyph, accent hover and a
 * dark-aware native popup (color-scheme). Lives in app.css because the
 * ::-webkit-calendar-picker-indicator pseudo-element can't be reached from
 * scoped CSS.
 */
input[type="date"] {
    cursor: pointer;
    font-variant-numeric: tabular-nums;
    color-scheme: light;
}
:root[data-theme="dark"] input[type="date"], :root[data-theme="indigo"] input[type="date"], :root[data-theme="hc"] input[type="date"] { color-scheme: dark; }

input[type="date"]::-webkit-calendar-picker-indicator {
    width: 16px;
    height: 16px;
    margin-left: 4px;
    cursor: pointer;
    border-radius: 4px;
    opacity: .8;
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2300ADEF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='18' rx='2' ry='2'/><line x1='16' y1='2' x2='16' y2='6'/><line x1='8' y1='2' x2='8' y2='6'/><line x1='3' y1='10' x2='21' y2='10'/></svg>") center / 16px 16px no-repeat;
    transition: opacity .15s ease;
}
input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="date"]:focus::-webkit-calendar-picker-indicator { opacity: 1; }
:root[data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator,
:root[data-theme="indigo"] input[type="date"]::-webkit-calendar-picker-indicator {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235C5FE9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='18' rx='2' ry='2'/><line x1='16' y1='2' x2='16' y2='6'/><line x1='8' y1='2' x2='8' y2='6'/><line x1='3' y1='10' x2='21' y2='10'/></svg>");
}
:root[data-theme="hc"] input[type="date"]::-webkit-calendar-picker-indicator {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffcc00' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='18' rx='2' ry='2'/><line x1='16' y1='2' x2='16' y2='6'/><line x1='8' y1='2' x2='8' y2='6'/><line x1='3' y1='10' x2='21' y2='10'/></svg>");
}

/* Scadenza superata (BookingDetailModal): bordo rosso + icona calendario rossa.
   Vive qui — e non nello scoped CSS del componente — perché ::-webkit-calendar-picker-indicator
   non è raggiungibile dagli stili scoped. La classe è applicata via IsExpired. */
input[type="date"].bkm-exp-expired {
    border-color: var(--danger);
    box-shadow: inset 0 0 0 1px var(--danger);
}
input[type="date"].bkm-exp-expired::-webkit-calendar-picker-indicator {
    opacity: 1;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ea3943' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='18' rx='2' ry='2'/><line x1='16' y1='2' x2='16' y2='6'/><line x1='8' y1='2' x2='8' y2='6'/><line x1='3' y1='10' x2='21' y2='10'/></svg>");
}

/* Filter bars: label + compact date field aligned with the .btn height */
.panel-actions label,
.toolbar label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--text-secondary);
    font: 500 .7812rem 'Inter', sans-serif;
    white-space: nowrap;
}
.panel-actions input[type="date"].cx-input,
.toolbar input[type="date"].cx-input {
    width: 148px;
    height: 34px;
    padding: 0 10px;
    border-radius: 8px;
    font-size: .7812rem;
}

/*
 * Modern file input — restyle the native <input type="file"> so it matches the
 * cx-input/cx-select look. Lives in app.css (not scoped CSS) because the styles
 * target Blazor's <InputFile> component, whose rendered <input> is *not* tagged
 * with the parent component's scope attribute.
 */
.cx-file {
    display: inline-flex;
    align-items: center;
    height: 40px;
    padding: 0 14px 0 4px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-card-2);
    color: var(--text-primary);
    font: 500 .8125rem 'Inter', 'Segoe UI', sans-serif;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(0,0,0,0.04);
    transition: border-color 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;
    max-width: 100%;
}
.cx-file:hover {
    border-color: var(--border-strong);
    background-color: var(--bg-card);
}
.cx-file:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 4px var(--accent-soft), 0 1px 2px rgba(0,0,0,0.04);
    background-color: var(--bg-card);
}
.cx-file:disabled,
.cx-file[disabled] {
    opacity: .55;
    cursor: not-allowed;
}
.cx-file::file-selector-button {
    appearance: none;
    -webkit-appearance: none;
    border: 0;
    height: 32px;
    padding: 0 14px;
    margin-right: 12px;
    border-radius: 8px;
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-deep) 100%);
    color: #fff;
    font: 600 .75rem 'Inter', 'Segoe UI', sans-serif;
    letter-spacing: 0.02em;
    cursor: pointer;
    box-shadow: 0 4px 10px var(--accent-glow);
    transition: filter 0.12s ease, transform 0.12s ease;
}
.cx-file:hover::file-selector-button { filter: brightness(1.06); }
.cx-file:active::file-selector-button { transform: translateY(1px); }
.cx-file::-webkit-file-upload-button {
    appearance: none;
    -webkit-appearance: none;
    border: 0;
    height: 32px;
    padding: 0 14px;
    margin-right: 12px;
    border-radius: 8px;
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-deep) 100%);
    color: #fff;
    font: 600 .75rem 'Inter', 'Segoe UI', sans-serif;
    letter-spacing: 0.02em;
    cursor: pointer;
    box-shadow: 0 4px 10px var(--accent-glow);
    transition: filter 0.12s ease, transform 0.12s ease;
}
.cx-file:hover::-webkit-file-upload-button { filter: brightness(1.06); }
.cx-file:active::-webkit-file-upload-button { transform: translateY(1px); }

/* Inline country flag — 22×16 px, used by CountryRender() in view mode */
.cx-flag {
    display: inline-block;
    width: 22px;
    height: 16px;
    border-radius: 2px;
    border: 1px solid var(--border);
    object-fit: cover;
    vertical-align: -3px;
    margin-right: 8px;
    background: var(--bg-card-2);
    box-shadow: 0 1px 2px rgba(0,0,0,0.08);
    flex-shrink: 0;
}


/* Detail tabs — horizontal nav shown inside a detail panel */
.detail-tabs {
    display: flex; gap: 2px;
    padding: 0 18px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-card);
    overflow-x: auto;
    scrollbar-width: thin;
}
.detail-tab {
    appearance: none; border: 0; background: transparent;
    padding: 12px 14px;
    font: 600 .8125rem 'Inter', sans-serif;
    color: var(--text-muted);
    cursor: pointer; white-space: nowrap;
    border-bottom: 2px solid transparent;
    transition: color .12s ease, border-color .12s ease;
}
.detail-tab:hover { color: var(--text-primary); }
.detail-tab.active { color: var(--accent); border-bottom-color: var(--accent); }

.detail-footer {
    display: flex; align-items: center; justify-content: flex-end;
    gap: 8px;
    padding: 12px 18px;
    border-top: 1px solid var(--border);
    background: var(--bg-card);
}

/* Virtualized grid (used by lazy-loaded lists like Customers) */
.vgrid { flex: 1 1 auto; display: flex; flex-direction: column; overflow: hidden; }
.vgrid-head { background: var(--bg-card); border-bottom: 1px solid var(--border); }
.vgrid-row {
    display: grid; align-items: center;
    padding: 0 14px; height: 48px;
    border-bottom: 1px solid var(--border);
    cursor: pointer;
    transition: background .12s ease;
}
.vgrid-head-row {
    height: 36px; cursor: default;
    font-weight: 600; font-size: .6875rem; letter-spacing: .08em;
    text-transform: uppercase; color: var(--text-muted);
    background: transparent;
}
.vgrid-row:not(.vgrid-head-row):hover { background: var(--bg-hover); }
.vgrid-row.selected { background: var(--bg-active); box-shadow: inset 3px 0 0 var(--accent); }
.vgrid-row.selected .vgrid-cell { color: var(--text-primary); }
.vgrid-cell { padding: 4px 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vgrid-placeholder { opacity: .6; }
.vgrid-body { flex: 1 1 auto; overflow-y: auto; }
.skeleton {
    display: inline-block; width: 70%; height: 10px; border-radius: 4px;
    background: linear-gradient(90deg, var(--bg-card) 0%, var(--border) 50%, var(--bg-card) 100%);
    background-size: 200% 100%;
    animation: shimmer 1.2s infinite;
}
@keyframes shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* Alerts
   Inline feedback usato dai form e dai toast. Colori scelti per essere leggibili
   in entrambi i temi (chiaro di default, scuro via [data-theme="dark"]).
   - .err: rosso medio saturo (#ef4444) → contrasto sufficiente su sfondo scuro
     (saturazione 15%) e su sfondo bianco.
   - .ok: verde scuro (#16a34a) → idem, l'icona check rende chiaro l'esito positivo.
   - .info: azzurro (#0ea5e9).
   `font-weight: 500` migliora la leggibilità dei caratteri sottili dei temi. */
.alert {
    padding: 10px 14px; border-radius: 10px;
    border: 1px solid var(--border);
    font-size: .8125rem; font-weight: 500; line-height: 1.4;
    margin-bottom: 12px;
    display: flex; align-items: center; gap: 10px;
}
.alert svg { flex: 0 0 auto; }
.alert.err {
    background: rgba(220,38,38,.15);
    border-color: rgba(220,38,38,.45);
    color: #ef4444;
}
.alert.ok {
    background: rgba(34,197,94,.15);
    border-color: rgba(34,197,94,.45);
    color: #16a34a;
}
.alert.info {
    background: rgba(14,165,233,.15);
    border-color: rgba(14,165,233,.45);
    color: #0ea5e9;
}

/* Form */
.form-grid { display: grid; grid-template-columns: 1fr; gap: 14px; max-width: 420px; }
.form-field { display: flex; flex-direction: column; gap: 6px; }
.form-field label {
    font-size: .75rem; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .08em; font-weight: 600;
}
.form-field input {
    padding: 10px 12px; border-radius: 8px;
    background: var(--bg-card-2);
    border: 1px solid var(--border);
    color: var(--text-primary); font: inherit; font-size: .875rem;
    outline: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.form-field input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.form-field .hint { font-size: .6875rem; color: var(--text-muted); }
.form-field .validation { font-size: .6875rem; color: var(--danger); }

/* Login hero — animated background + glass card */
.login-wrap {
    position: fixed;
    inset: 0;
    display: grid;
    place-items: center;
    padding: 24px;
    background: #05060d;
    overflow: hidden;
}

.login-anim-geom {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.login-anim-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    cursor: crosshair;
}

.login-anim-brand {
    position: absolute;
    top: 26px;
    left: 28px;
    font-size: .8125rem;
    letter-spacing: 0.5em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.55);
    z-index: 10;
    user-select: none;
    pointer-events: none;
}
.login-anim-brand b { color: #00ADEF; font-weight: 600; }

.login-anim-release {
    position: absolute;
    bottom: 24px;
    left: 28px;
    font-size: .6875rem;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.35);
    z-index: 10;
    pointer-events: none;
    user-select: none;
    font-variant-numeric: tabular-nums;
}

.login-card {
    position: absolute;
    right: 28px;
    bottom: 28px;
    z-index: 5;
    width: calc(100% - 56px);
    max-width: 400px;
    background: rgba(15, 18, 30, 0.65);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid rgba(0, 173, 239, 0.18);
    border-radius: 14px;
    box-shadow: 0 20px 60px rgba(0,0,0,0.55);
    padding: 24px;
    color: rgba(255,255,255,0.92);
}
.login-card h2 { margin: 0 0 4px; font-size: 1.25rem; font-weight: 800; color: rgba(255,255,255,0.95); }
.login-card .sub { color: rgba(255,255,255,0.55); font-size: .75rem; margin-bottom: 18px; }

/* Inputs harmonized with the dark login glass background */
.login-card .form-field label {
    color: rgba(255,255,255,0.6);
}
.login-card .form-field input {
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.12);
    color: rgba(255,255,255,0.95);
}
.login-card .form-field input::placeholder {
    color: rgba(255,255,255,0.3);
}
.login-card .form-field input:focus {
    border-color: rgba(0, 173, 239, 0.6);
    box-shadow: 0 0 0 3px rgba(0, 173, 239, 0.18);
    background: rgba(255,255,255,0.08);
}
.login-card .form-field .hint {
    color: rgba(255,255,255,0.45);
}
.login-card .form-field .hint code {
    background: rgba(255,255,255,0.08);
    color: rgba(255,255,255,0.85);
    padding: 1px 5px;
    border-radius: 4px;
}

/* Tenant chooser (email login): one button per candidate property */
.login-card .tenant-choice {
    width: 100%;
    justify-content: flex-start;
    text-align: left;
    gap: 12px;
    padding: 10px 14px;
}
.login-card .tenant-choice .tc-icon {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    color: var(--text-primary);
    opacity: .85;
}
.login-card .tenant-choice .tc-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
}
.login-card .tenant-choice .tc-name {
    font-size: .9375rem;
    font-weight: 800;
    color: var(--text-primary);
    line-height: 1.2;
}
.login-card .tenant-choice .tc-slug {
    font-size: .75rem;
    font-weight: 500;
    color: var(--text-muted);
}
.login-card .tenant-choice .tc-note {
    font-size: .6875rem;
    color: var(--text-muted);
}

/* Active-session panel. Vertical stack — identity row, then a full-width CTA —
   purpose-built instead of the generic .alert banner. Stacking (rather than a
   single row) guarantees the label and the button never overlap or wrap in the
   narrow card, across every language and theme. The username ellipsizes if long. */
.login-card .session-active {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 14px;
    margin-bottom: 12px;
    border-radius: 12px;
    background: rgba(34,197,94,.10);
    border: 1px solid rgba(34,197,94,.35);
}
.login-card .session-active-id {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;            /* enables ellipsis on the username */
}
.login-card .session-active-avatar {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: rgba(34,197,94,.18);
    color: #16a34a;
}
.login-card .session-active-avatar svg { width: 18px; height: 18px; }
.login-card .session-active-text {
    display: flex;
    flex-direction: column;
    min-width: 0;            /* enables ellipsis on the username */
    line-height: 1.25;
}
.login-card .session-active-label {
    font-size: .6875rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: rgba(255,255,255,0.5);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.login-card .session-active-user {
    font-size: .875rem;
    font-weight: 700;
    color: rgba(255,255,255,0.95);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.login-card .session-active-go {
    width: 100%;
    justify-content: center;
    white-space: nowrap;
}

/* Layout root when unauthenticated (no app-shell grid) */
.main-unauth {
    min-height: 100vh;
}

/* Dashboard tiles */
.dash-grid {
    display: grid; gap: 14px;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.dash-tile {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 18px;
    box-shadow: var(--shadow);
}
.dash-tile .t-label { font-size: .6875rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: .12em; }
.dash-tile .t-value { font-size: 1.625rem; font-weight: 800; color: var(--text-primary); margin-top: 6px; }
.dash-tile .t-sub { font-size: .75rem; color: var(--text-muted); margin-top: 4px; }

/* Loading */
.spinner {
    width: 18px; height: 18px; border-radius: 50%;
    border: 2px solid var(--border-strong);
    border-top-color: var(--accent);
    animation: spin .8s linear infinite;
    display: inline-block; vertical-align: middle;
}
@keyframes spin { to { transform: rotate(360deg); } }

.pagination {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 14px;
    border-top: 1px solid var(--border);
    font-size: .75rem; color: var(--text-muted);
}

/* Blazor error UI override */
#blazor-error-ui {
    background: var(--danger);
    color: #fff;
    bottom: 0; box-shadow: var(--shadow-lg);
    display: none; left: 0; padding: 0.8rem 1.4rem; position: fixed;
    width: 100%; z-index: 1000;
}
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 1rem; top: 0.5rem; }

/* ===========================================================
   Modern toggle switch — replaces native checkboxes.
   Add class="cx-toggle" to any <input type="checkbox"> to convert
   it into a pill switch with smooth thumb animation. Honours the
   accent palette and works under both dark and light themes.
   =========================================================== */
.cx-toggle {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    position: relative;
    display: inline-block;
    vertical-align: middle;
    width: 38px;
    height: 22px;
    margin: 0;
    padding: 0;
    /* Off-state: grigio tenue che legge "spento" sui pannelli bianchi (chiaro = default). */
    background: #d8dbe6;
    border: 1px solid #d8dbe6;
    border-radius: 999px;
    cursor: pointer;
    outline: none;
    transition: background-color 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
    flex: 0 0 auto;
}
:root[data-theme="dark"] .cx-toggle, :root[data-theme="indigo"] .cx-toggle, :root[data-theme="hc"] .cx-toggle {
    background: var(--border-strong, rgba(255, 255, 255, 0.18));
    border-color: var(--border-strong, rgba(255, 255, 255, 0.18));
}

.cx-toggle::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 2px;
    width: 16px;
    height: 16px;
    background: #ffffff;
    border-radius: 50%;
    transform: translateY(-50%);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18), 0 0 0 1px rgba(0, 0, 0, 0.04);
    transition: left 0.18s cubic-bezier(0.4, 0.0, 0.2, 1), background-color 0.18s ease;
}
:root[data-theme="dark"] .cx-toggle::before, :root[data-theme="indigo"] .cx-toggle::before, :root[data-theme="hc"] .cx-toggle::before {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(0, 0, 0, 0.04);
}

.cx-toggle:hover:not(:disabled) {
    border-color: var(--accent-2, #3B82F6);
}

.cx-toggle:focus-visible {
    box-shadow: 0 0 0 3px var(--accent-soft, rgba(37, 99, 235, 0.16));
}

.cx-toggle:checked {
    background: var(--accent, #2563EB);
    border-color: var(--accent, #2563EB);
}

.cx-toggle:checked::before {
    left: calc(100% - 18px);
    background: #ffffff;
}

.cx-toggle:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.cx-toggle:disabled::before {
    background: #e0e0e0;
}

/* ===========================================================
   Color picker field (preview button + popover: RGB + alpha)
   =========================================================== */
.cpk { position: relative; display: inline-block; }
.cpk-swatch {
    width: 48px; height: 28px; padding: 3px; cursor: pointer;
    border: 1px solid var(--border-strong); border-radius: 7px;
    /* checkerboard so transparency is visible behind the fill */
    background-image:
        linear-gradient(45deg, rgba(255,255,255,.12) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(255,255,255,.12) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(255,255,255,.12) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(255,255,255,.12) 75%);
    background-size: 10px 10px;
    background-position: 0 0, 0 5px, 5px -5px, -5px 0;
    background-color: var(--bg-card-2);
}
.cpk-swatch:hover { border-color: var(--accent); }
.cpk-swatch-fill { display: block; width: 100%; height: 100%; border-radius: 4px; }
.cpk-pop {
    position: absolute; z-index: 60; top: calc(100% + 6px); left: 0;
    width: 236px; padding: 12px;
    background: var(--bg-card); border: 1px solid var(--border-strong);
    border-radius: var(--radius); box-shadow: var(--shadow);
    display: flex; flex-direction: column; gap: 10px;
}
.cpk-row { display: flex; align-items: center; gap: 10px; }
.cpk-rgb { width: 48px; height: 34px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: transparent; cursor: pointer; }
.cpk-hex { font-family: var(--mono); font-size: .75rem; color: var(--text-secondary); }
.cpk-lbl { font-size: .75rem; color: var(--text-secondary); }
.cpk-alpha { flex: 1; accent-color: var(--accent); }
.cpk-pct { font-size: .75rem; color: var(--text-primary); min-width: 38px; text-align: right; }
.cpk-foot { display: flex; justify-content: flex-end; gap: 8px; }
.cpk-foot .btn { padding: 4px 12px; font-size: .75rem; }

/* ===========================================================
   Tableau settings: two-column layout with sticky live preview
   =========================================================== */
/* The row fills the panel's remaining height; the left column (.detail-body) keeps its own
   vertical scroll, while the preview is pinned beside it. Without flex:1 + min-height:0 the
   row collapses to content height and .panel-full (overflow:hidden) clips the overflow. */
.tableau-settings-layout {
    display: flex; gap: 18px; align-items: stretch;
    flex: 1 1 auto; min-height: 0; overflow: hidden;
}
/* Il fieldset (disabled = sola lettura) è la cella flex sinistra: deve poter
   restringersi (min-height:0, min-inline-size:0 per i fieldset) e distribuire
   l'altezza in colonna, altrimenti cresce col contenuto e .detail-body non scorre. */
.tableau-settings-fields {
    /* Larghezza fissa che contiene tutti i campi (niente scorrimento orizzontale); l'anteprima prende il resto. */
    flex: 0 0 560px; min-width: 0; min-height: 0; min-inline-size: 0;
    display: flex; flex-direction: column;
    border: 0; padding: 0; margin: 0;
}
.tableau-settings-fields > .detail-body { flex: 1 1 auto; min-width: 0; min-height: 0; }
.field-group.tcolors { grid-template-columns: 140px 96px 96px 1fr; align-items: center; }
.tcolors-head { font-size: .6875rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: .04em; }
.tcolors-hint { grid-column: 1 / -1; font-size: .6875rem; color: var(--text-muted); }
.tableau-preview-theme { display: flex; gap: 6px; align-items: center; margin: 0 0 10px; font-size: .75rem; color: var(--text-muted); }
.tableau-preview { flex: 1 1 0; min-width: 0; min-height: 0; overflow-y: auto; }  /* anteprima + festività: scorre da sola */
.tableau-preview-hint { font-size: .75rem; color: var(--text-muted); margin: -4px 0 10px; }
.tableau-preview-card {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: var(--radius); padding: 12px; box-shadow: var(--shadow-sm);
}
.tableau-preview-card h4 { margin: 0 0 10px; font-size: .8125rem; font-weight: 600; color: var(--text-secondary); }
@media (max-width: 1400px) {
    /* Stacked: let the whole layout scroll as one column. */
    .tableau-settings-layout { flex-direction: column; overflow-y: auto; }
    /* flex-shrink 0: altrimenti il fieldset (min-height 0) si schiaccia a 0 px e i campi finiscono sotto l'anteprima. */
    .tableau-settings-fields { display: block; flex: 0 0 auto; }
    .tableau-settings-fields > .detail-body { overflow: visible; }
    /* flex 0 0 auto: in colonna l'anteprima non deve restringersi (con flex 1 1 0 finirebbe alta zero). */
    .tableau-preview { flex: 0 0 auto; width: 100%; position: static; overflow: visible; }
}

/* ── Listino camera: matrice "per stagione" (scroll verticale) ─────────────
   Un blocco per periodo; dentro, una riga per fascia d'età (Per persona) o per
   occupazione (Per camera) e una colonna per trattamento. Tutte le righe sono
   editabili insieme: niente filtro a pill da cambiare di continuo. */
.pl-matrix-toolbar {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 18px; border-bottom: 1px solid var(--border); flex-wrap: wrap;
    background: var(--bg-subtle);
}
.pl-seasons { display: flex; flex-direction: column; gap: 14px; padding: 14px 18px; }
.pl-season-card {
    border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--bg-card); overflow: hidden;
}
.pl-season-head {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 18px; border-bottom: 1px solid var(--border);
    background: var(--bg-card-2);
}
.pl-season-cal { font-size: .875rem; line-height: 1; }
.pl-season-head .pl-season-name { font-weight: 700; font-size: .875rem; color: var(--text-primary); }
.pl-season-head .pl-season-dates { font-size: .75rem; color: var(--text-secondary); }
.pl-season-table-wrap { overflow-x: auto; }
.pl-season-table { width: 100%; border-collapse: collapse; font-size: .8125rem; }
.pl-season-table thead th {
    text-align: right; font-weight: 600; font-size: .6875rem; color: var(--text-muted);
    padding: 7px 8px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.pl-season-table thead th.pl-row-head { text-align: left; padding-left: 14px; }
.pl-season-table thead th.pl-unit-head { text-align: center; }
.pl-season-table tbody td {
    padding: 4px 8px; border-bottom: 1px solid var(--border); text-align: right;
}
.pl-season-table tbody tr:last-child td { border-bottom: 0; }
.pl-season-table tbody td.pl-row-label { text-align: left; padding-left: 14px; white-space: nowrap; }
/* Rendi discoverable il campo editabile anche quando è vuoto (PriceCell di base è trasparente). */
.pl-season-table tbody td .price-cell-input {
    border-color: var(--border);
    background: var(--bg-card-2);
}
.pl-season-table tbody td .price-cell-input:hover,
.pl-season-table tbody td .price-cell-input:focus {
    border-color: var(--accent);
    background: var(--bg-card);
}
.pl-row-name { font-weight: 500; }
.pl-row-tag {
    font-size: .6875rem; padding: 1px 7px; border-radius: 10px;
    background: var(--accent-soft); color: var(--accent); margin-left: 6px;
}
.pl-row-sub { font-size: .6875rem; color: var(--text-muted); margin-left: 6px; }
.pl-unit-cell { text-align: center !important; color: var(--text-muted); }
.pl-unit-toggle {
    display: inline-flex; border: 1px solid var(--border-strong);
    border-radius: 7px; overflow: hidden;
}
.pl-unit-toggle button {
    border: 0; background: transparent; padding: 3px 9px;
    font-size: .75rem; cursor: pointer; color: var(--text-muted); white-space: nowrap;
}
.pl-unit-toggle button.active { background: var(--accent); color: var(--on-accent); }
/* Cella sconto: input + toggle unità per-cella (override della cella su fascia × trattamento) */
.pl-disc-cell { display: inline-flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.pl-cell-unit {
    display: inline-flex; border: 1px solid var(--border); border-radius: 5px; overflow: hidden;
}
.pl-cell-unit button {
    border: 0; background: transparent; padding: 0 6px; line-height: 18px;
    font-size: .6875rem; cursor: pointer; color: var(--text-muted);
}
.pl-cell-unit button.active { background: var(--accent); color: var(--on-accent); }
/* Colonna "Tutti i trattamenti": valore unico per fascia, sfondo tenue per distinguerla dai trattamenti */
.pl-alltreatments-head, .pl-alltreatments-cell { background: color-mix(in srgb, var(--accent) 7%, transparent); }
.pl-alltreatments-head { font-style: italic; }
/* Sezione "Aggiustamenti fasce" a livello di listino (fuori dalle stagioni) */
/* niente overflow:hidden: il popover di preview (assoluto) deve poter uscire dalla card */
.pl-band-adjust { margin: 12px 18px 18px; border: 1px solid var(--border); border-radius: var(--radius); }
.pl-band-adjust-head {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 14px; font-weight: 600; font-size: .8125rem; color: var(--text-primary);
    background: var(--bg-subtle);
}
.pl-band-adjust-hint { padding: 4px 14px 8px; font-size: .75rem; color: var(--text-muted); }
/* Aggiustamenti fasce in orizzontale (sotto le stagioni, sempre visibili) */
.pl-band-row { display: flex; flex-wrap: wrap; gap: 14px; padding: 4px 14px 12px; }
.pl-band-item { position: relative; display: flex; flex-direction: column; gap: 4px; min-width: 120px; }
.pl-band-item-label { font-size: .75rem; white-space: nowrap; }
.pl-band-item-input { display: flex; align-items: center; gap: 6px; }
/* Box temporaneo al focus: prezzo finale per stagione × trattamento attivo */
.pl-band-focusbox {
    display: none; position: absolute; bottom: 100%; left: 0; z-index: 30; margin-bottom: 6px;
    background: var(--bg-card); border: 1px solid var(--border-strong); border-radius: var(--radius);
    box-shadow: var(--shadow); padding: 8px; max-width: 90vw; overflow: auto;
}
.pl-band-item:focus-within .pl-band-focusbox { display: block; }
.pl-band-focusbox-cap { font-size: .6875rem; color: var(--text-muted); margin-bottom: 4px; }
.pl-band-focusbox-table { border-collapse: collapse; font-size: .75rem; white-space: nowrap; }
.pl-band-focusbox-table th, .pl-band-focusbox-table td { padding: 2px 8px; text-align: right; }
.pl-band-focusbox-table thead th { color: var(--text-muted); font-weight: 600; font-size: .6875rem; border-bottom: 1px solid var(--border); }
.pl-band-focusbox-table .pl-band-focusbox-season { text-align: left; font-weight: 500; }
/* Pannello coerenza periodi (buchi + sovrapposizioni) */
.pl-coherence {
    margin: 8px 18px 0; padding: 8px 12px; border-radius: var(--radius-sm);
    background: var(--danger-soft); border: 1px solid color-mix(in srgb, var(--danger) 40%, transparent);
    color: var(--danger); font-size: .75rem; font-weight: 500; display: flex; flex-direction: column; gap: 2px;
}
/* Popup duplicazione stagione (stesse convenzioni di DuplicatePriceListModal.razor.css) */
.pl-modal-backdrop {
    position: fixed; inset: 0; background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(3px);
    display: flex; align-items: center; justify-content: center; z-index: 1000;
}
.pl-modal {
    background: var(--bg-card); border: 1px solid var(--border-strong); border-radius: var(--radius-lg);
    padding: 18px 20px; width: 440px; max-width: 92vw; box-shadow: var(--shadow-lg);
    font-size: .8125rem; color: var(--text-secondary);
}
.pl-modal-title { font-weight: 700; font-size: .9375rem; margin-bottom: 12px; color: var(--text-primary); }
.pl-modal-label { display: block; font-size: .75rem; color: var(--text-muted); margin: 8px 0 3px; }
.pl-modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
/* Popup eliminazione listino: elenchi di derivati / risorse / prodotti che lo referenziano */
.pl-usage-title { font-size: .75rem; font-weight: 600; margin-top: 10px; color: var(--text-muted); }
.pl-usage-list { margin: 4px 0 0; padding-left: 18px; max-height: 160px; overflow-y: auto; font-size: .8125rem; }
/* Matrice camere: header trattamenti unico (sticky) + stagioni scorrevoli, colonne allineate, compatto */
.pl-matrix-scroll { overflow: auto; max-height: 55vh; padding: 0 18px 8px; }
.pl-matrix-table { width: auto; border-collapse: collapse; font-size: .8125rem; }
.pl-matrix-table thead th {
    position: sticky; top: 0; z-index: 3;
    text-align: right; font-weight: 600; font-size: .6875rem; color: var(--text-muted);
    padding: 6px 8px; background: var(--bg-card-2); border-bottom: 1px solid var(--border); white-space: nowrap;
}
.pl-matrix-table thead th.pl-row-head { text-align: left; }
.pl-matrix-table td { padding: 2px 8px; }
.pl-matrix-table .pl-row-label { text-align: left; white-space: nowrap; }
.pl-matrix-table .pl-season-row td { padding: 0; }
.pl-matrix-table .pl-gap-row td {
    background: var(--danger-soft); color: var(--danger); text-align: left;
    font-size: .75rem; padding: 6px 12px; border-top: 1px dashed var(--danger); border-bottom: 1px dashed var(--danger);
}
/* Nome trattamento sotto il codice nell'header (tooltip = descrizione completa) */
.pl-matrix-table thead th .pl-plan-name { display: block; font-weight: 400; font-size: .6875rem; color: var(--text-muted); text-transform: none; }

/* ── Vista periodi compatta (una riga per periodo): azioni · periodo · fascia · dal · al · trattamenti ── */
.pl-seasons-table { width: 100%; }
.pl-seasons-table thead th.pl-seasons-actions,
.pl-seasons-table thead th.pl-seasons-date { text-align: left; }
.pl-seasons-table thead th.pl-seasons-actions { width: 1%; }
.pl-seasons-table tbody tr.pl-season-line td { padding: 6px 8px; border-bottom: 1px solid var(--border); }
.pl-seasons-table tbody tr.pl-season-line:hover td { background: var(--bg-hover); }
.pl-seasons-table tbody tr.pl-season-line:last-child td { border-bottom: 0; }
.pl-seasons-table td.pl-seasons-actions { white-space: nowrap; text-align: left; }
.pl-seasons-table td.pl-seasons-actions .btn { padding: 3px 7px; margin-right: 2px; }
.pl-seasons-table td.pl-seasons-desc { min-width: 150px; }
.pl-seasons-table td.pl-seasons-desc .pl-row-name { font-weight: 700; color: var(--text-primary); }
.pl-seasons-table .pl-seasons-date { text-align: left; color: var(--text-secondary); white-space: nowrap; }
/* Rendi discoverable il campo editabile vuoto (PriceCell di base è trasparente). */
.pl-matrix-table td .price-cell-input,
.pl-band-item .price-cell-input {
    border-color: var(--border);
    background: var(--bg-card-2);
}
.pl-matrix-table td .price-cell-input:hover,
.pl-matrix-table td .price-cell-input:focus,
.pl-band-item .price-cell-input:hover,
.pl-band-item .price-cell-input:focus {
    border-color: var(--accent);
    background: var(--bg-card);
}
/* Barra gestione periodi nella scheda matrice (aggiunta/modifica periodo inline) */
.pl-period-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 8px 18px; }
.pl-period-arrow { color: var(--text-muted); }
/* Sotto-sezione "Letti aggiunti" dentro la card stagione */
.pl-extrabeds { border-top: 1px solid var(--border); }
.pl-extrabeds-head {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 14px; font-weight: 500; font-size: .8125rem; color: var(--text-primary);
}
/* Cluster azioni nell'header dettaglio (Modifica/Elimina/Duplica/Salva) */
.pl-hero-actions { display: flex; gap: 8px; margin-left: auto; align-items: center; }
/* Utility: contenuto allineato al gutter orizzontale 18px della pagina */
.pl-inset { padding: 8px 18px; }
/* Quadrato colore della tabella master: contiene l'icona del TargetType.
   Il background arriva inline (colore scelto dall'utente); senza colore il
   fallback è accent-soft/accent (vedi BadgeStyle in PriceListsConfig.razor.cs). */
.pl-color-badge {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: var(--radius-sm);
    border: 1px solid var(--border);
}
/* Barra azioni bulk della matrice prezzi (N selezionati → imposta prezzo) */
.pl-bulkbar {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 8px 18px; border-bottom: 1px solid var(--border);
    background: var(--warning-soft); font-size: .75rem;
}
.pl-bulkbar b { color: var(--warning); }
/* Riga di intestazione categoria nella matrice prezzi prodotti (click = collapse) */
.pl-cat-row { cursor: pointer; }
.pl-cat-row td {
    font-weight: 600; font-size: .75rem; color: var(--text-primary);
    background: var(--bg-card-2); padding: 6px 12px;
    border-bottom: 1px solid var(--border);
}

/* ── PriceCell: cella prezzo editabile (input nudo, usata in matrici e band-adjust).
      Base trasparente: i contesti (.pl-matrix-table, .pl-season-table, .pl-band-item)
      la rendono discoverable con bordo+sfondo. Stati:
      hover → bordo forte; focus → ring accent; dirty → ambra "in attesa di salvataggio"
      (coerente con la semantica ambra-required; il rosso resta per gli errori). ── */
.price-cell-input {
    width: 76px; text-align: right;
    font: inherit; color: inherit;
    background: transparent;
    border: 1px solid transparent; border-radius: var(--radius-sm);
    padding: 3px 6px; outline: none;
    /* freccine native: gia' spente dalla regola globale accanto a .cx-input */
}
.price-cell-input:hover { border-color: var(--border-strong); background: var(--bg-hover); }
.price-cell-input:focus {
    border-color: var(--accent); background: var(--bg-card);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.price-cell-input.dirty { background: var(--req-soft); border-color: var(--req); }
.price-cell-input.placeholder-empty { color: var(--text-muted); }

/* ── Popup "effettua il login" (LoginRedirectPopup): mostrato 3s su pagina protetta
      senza sessione, poi redirect automatico al login. Layout critico inline nel
      componente; qui solo l'estetica. ── */
.lr-modal { box-shadow: var(--shadow-lg); text-align: center; }
.lr-body {
    padding: 26px 24px 20px;
    display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.lr-icon {
    width: 46px; height: 46px; border-radius: 12px;
    display: flex; align-items: center; justify-content: center;
    background: var(--accent-soft); color: var(--accent); margin-bottom: 4px;
}
.lr-title { font-weight: 700; font-size: .9375rem; color: var(--text-primary); }
.lr-sub { font-size: .75rem; color: var(--text-muted); }
.lr-progress { height: 4px; background: var(--border); }
/* Durata = RedirectDelayMs in LoginRedirectPopup.razor.cs */
.lr-progress-fill {
    height: 100%; width: 100%; background: var(--accent);
    animation: lr-countdown 3s linear forwards;
}
@keyframes lr-countdown {
    from { width: 100%; }
    to { width: 0; }
}

/* ── Dotazioni camera nella scheda tipologia (ServiceTypesConfig) ─────────── */
/* Selezione per-organizzazione sul catalogo globale: raggruppata per categoria,
   a colonne su schermi larghi per non allungare la scheda. */

.srt-amenities {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
}

@media (min-width: 900px) {
    .srt-amenities { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.srt-amenity-cat {
    font-size: .6875rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-secondary);
    margin-bottom: 4px;
}

.srt-amenity {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 2px 0;
    font-size: .8125rem;
    cursor: pointer;
}

.field-hint {
    color: var(--text-secondary);
    font-size: .75rem;
    margin: 6px 0 0;
}

/* ===========================================================================
   Accessibilita' e adattivita' trasversali (audit set 2026)
   Scala breakpoint dell'app, da usare ovunque al posto di valori ad hoc:
     640px  telefono            (una colonna, controlli a tutta larghezza)
     900px  shell -> drawer      (gia' usato dalla sidebar)
    1200px  due pannelli -> uno  (master/detail impilati o pannello a tutta larghezza)
   =========================================================================== */

/* Focus visibile su TUTTI i controlli, con il colore del tema. Gli input hanno gia' il
   proprio stato :focus (bordo + alone), qui coprono bottoni, link e righe attivabili. */
:where(button, [role="button"], a[href], summary, [tabindex]:not([tabindex="-1"])):focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
/* Righe/chip attivabili da tastiera (data-kb-click: Invio/Spazio => click, vedi app.js). */
[data-kb-click]:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
:root[data-theme="hc"] :focus-visible { outline-color: var(--accent); outline-width: 3px; }

/* Superfici del browser: selezione e cursore seguono la palette. */
::selection { background: var(--accent-soft); color: inherit; }
input, textarea, [contenteditable] { caret-color: var(--accent); }

/* Link "vai al contenuto": invisibile finche' non riceve il focus da tastiera. */
.skip-link {
    position: fixed; top: 8px; left: 8px; z-index: 5000;
    padding: 8px 12px; border-radius: 8px;
    background: var(--accent); color: var(--on-accent);
    font-weight: 600; text-decoration: none;
    transform: translateY(-200%);
    opacity: 0;
}
.skip-link:focus-visible { transform: none; opacity: 1; outline-offset: 2px; }

/* Indigo: il gradiente accent -> accent-deep porta il bianco a 3,9:1 sul lato chiaro.
   Il pulsante primario usa la meta' scura del gradiente (>= 4,8:1). */
:root[data-theme="indigo"] .btn-primary {
    background: linear-gradient(135deg, var(--accent-deep) 0%, #4B4EDA 100%);
}

/* Puntatore grossolano (touch): bersagli >= 44px sui controlli dello shell e condivisi. */
@media (pointer: coarse) {
    .icon-btn { width: 44px; height: 44px; }
    .btn { min-height: 44px; padding-top: 10px; padding-bottom: 10px; }
    .topbar-hamburger, .logout-btn, .side-collapse { min-width: 44px; min-height: 44px; }
    .nav-row, .panel-item, .panel-group, .theme-option, .submenu-item { min-height: 44px; }
    .cx-input, .cx-select { height: 44px; }
    .search { padding-top: 10px; padding-bottom: 10px; }
}

/* Sotto 900px l'area principale scorre da sola (le pagine non gestiscono tutte il proprio
   scroll) e i pannelli master/detail si impilano a tutta larghezza. */
@media (max-width: 900px) {
    .main { overflow: auto; padding: 12px; gap: 12px; flex-direction: column; }
    .main > .master, .main > .detail, .main > .panel-full { flex: 0 0 auto; max-width: none; min-width: 0; }
    /* Stesso impilamento per le pagine master/detail "cx-*". Il master ha altezza propria (le liste
       virtualizzate dentro hanno bisogno di un contenitore con altezza, altrimenti Virtualize
       renderizza tutte le righe); il dettaglio segue sotto a tutta larghezza. */
    .main > .cx-master { flex: 0 0 auto; height: max(420px, 75dvh); max-width: none; }
    .main > .cx-detail { flex: 0 0 auto; max-width: none; min-width: 0; width: 100%; }
    .search { min-width: 0; flex: 1 1 auto; }
}

/* Telefono: la topbar non puo' ospitare breadcrumb + ricerca + 6 pulsanti. Via sezione, scorciatoia
   da tastiera e schermo intero (inutili col touch); titolo che si accorcia; ricerca elastica; i
   pulsanti restano tutti raggiungibili e, se ancora non bastano, la barra scorre in orizzontale. */
@media (max-width: 720px) {
    .topbar { gap: 8px; padding: 0 10px; overflow-x: auto; scrollbar-width: none; }
    .topbar::-webkit-scrollbar { display: none; }
    .topbar > * { flex-shrink: 0; }
    .crumb-section, .breadcrumbs .sep, .topbar-fs, .search .kbd, .topbar-spacer { display: none; }
    .breadcrumbs { flex: 0 1 auto; min-width: 0; }
    .breadcrumbs .topbar-title { max-width: 30vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .topbar > .search { flex: 1 0 120px; }
}

/* =================== GRIGLIE DATI -> CARD (telefono) ===================
   Pattern condiviso per le liste a righe (prenotazioni, clienti, ...). Sopra 720px non fa nulla:
   la tabella resta com'e'. Sotto, ogni riga diventa una card a blocchi:
     .dg-title  riga 1 sinistra  (identificativo: cliente / nome)
     .dg-meta   riga 2 sinistra  (riepilogo in una riga: valori che si leggono insieme)
     .dg-side   colonna destra, righe 1-2  (valore chiave: importo, totale, badge)
     .dg-foot   riga 3 a tutta larghezza  (stato, azioni secondarie)
     .dg-hide   celle che stanno solo nel dettaglio (nascoste)
   Markup: <div class="dg-head">...</div> + righe <div class="dg-row ..."> con quelle classi sulle
   celle; .dg-meta e' un blocco in piu' dedicato alle card (sul desktop display:none, aria-hidden).
   Selettori con :root:root: devono battere le regole scoped della pagina (.bk-row[b-xxx] ecc.).
   Virtualize: l'altezza della card e' FISSA (--dg-row-h) e la pagina passa la stessa cifra a
   ItemSize (MediaQueryWatcher.CardRowHeightPx) quando MediaQueryWatcher.Phone e' attiva. Senza
   Virtualize l'altezza e' libera: non usare .dg-fixed. */
.dg-meta { display: none; }
@media (max-width: 720px) {
    :root { --dg-row-h: 92px; }
    :root:root .dg-head { display: none; }
    :root:root .dg-row {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-areas:
            "title side"
            "meta  side"
            "foot  foot";
        align-content: center;
        row-gap: 4px;
        column-gap: 12px;
        padding: 8px 14px;
    }
    :root:root .dg-row.dg-fixed { height: var(--dg-row-h); }
    :root:root .dg-row > .dg-hide { display: none; }
    :root:root .dg-row > .dg-title { grid-area: title; }
    :root:root .dg-row > .dg-side  { grid-area: side; align-self: start; }
    :root:root .dg-row > .dg-foot  { grid-area: foot; }
    :root:root .dg-row > .dg-meta {
        grid-area: meta;
        display: flex; align-items: center; gap: 8px;
        min-width: 0; overflow: hidden; white-space: nowrap;
        font-size: .75rem; color: var(--text-secondary);
    }
    .dg-meta > * { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
    .dg-meta > .mono { flex: 0 1 auto; color: var(--text-muted); }
    .dg-meta > :last-child { color: var(--text-muted); }
    /* Scheletro del Virtualize: solo il primo blocco */
    :root:root .dg-row.dg-skel > :not(:first-child) { display: none; }
}

/* Toolbar delle liste cx-* (clienti, configurazioni...) sul telefono: titolo a tutta riga, poi
   ricerca a tutta larghezza, poi i pulsanti che vanno a capo invece di uscire dal pannello. */
@media (max-width: 720px) {
    :root:root .cx-toolbar { flex-wrap: wrap; gap: 8px; }
    :root:root .cx-toolbar-title { flex: 1 1 100%; }
    :root:root .cx-toolbar-actions { flex-wrap: wrap; width: 100%; }
    :root:root .cx-search-group { flex: 1 1 100%; }
    :root:root .cx-search { width: 100%; min-width: 0; }
}

/* Tabelle -> card (telefono): una <table> con .dg-tbl / .dg-table perde il layout a colonne e le
   sue righe .dg-row seguono il pattern .dg-* sopra. Le pagine possono aggiungere i propri ritocchi. */
@media (max-width: 720px) {
    :root:root table.dg-tbl, :root:root table.dg-tbl > tbody,
    :root:root table.dg-table, :root:root table.dg-table > tbody { display: block; }
}

/* =================== MODALITÀ TELEFONO (/hk/*) ===================
   Stili condivisi dalle pagine della cornice HousekeepingLayout:
   bottoni d'azione grandi (>= 56 px) e bottom sheet. Globali perché ogni pagina HK li usa; testata e
   barra vivono nel CSS isolato dei componenti del layout. Il banner di riconnessione è qui sotto. */
.hk-btn {
    flex: 1 1 auto;
    min-height: 56px;
    min-width: 96px;
    border: 0;
    border-radius: 12px;
    font-size: .9375rem;
    font-weight: 600;
    /* Testo = fondo pagina del tema: scuro sui riempimenti chiari (temi scuri), chiaro su
       quelli scuri (light). Cosi' il contrasto regge in tutti e quattro i temi. */
    color: var(--bg-app);
    cursor: pointer;
}

.hk-btn:disabled { opacity: 0.6; }
.hk-btn.start { background: var(--accent); color: var(--on-accent); }
.hk-btn.done { background: var(--success); }
.hk-btn.skip { background: var(--text-muted); }
.hk-btn.report { background: var(--warning); }

/* Bottom sheet */
.hk-sheet-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

.hk-sheet {
    width: 100%;
    max-width: 560px;
    background: var(--bg-card);
    border-radius: 18px 18px 0 0;
    padding: 18px;
    /* viewport-fit=cover: i bottoni in fondo restano sopra la home bar di iPhone. */
    padding-bottom: calc(18px + env(safe-area-inset-bottom));
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-height: 88vh;
    overflow-y: auto;
}

.hk-sheet-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    font-size: 1.0625rem;
}

.hk-sheet-room {
    color: var(--text-muted);
    font-size: .875rem;
}

.hk-sheet-types {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.hk-type-chip {
    padding: 10px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-card);
    font-size: .875rem;
    cursor: pointer;
    color: inherit;
}

.hk-type-chip.sel {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 14%, transparent);
    font-weight: 600;
}

.hk-photo-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 14px;
    border: 1px dashed var(--border);
    border-radius: 12px;
    cursor: pointer;
    font-size: .9375rem;
    justify-content: center;
}

.hk-photo-ok {
    color: var(--success);
    font-size: .8125rem;
}

/* Foto ancora in lettura (C-025): Invia e Risolvi restano disabilitati finché non compare ✓. */
.hk-photo-reading {
    color: var(--text-muted);
    font-size: .8125rem;
}

.hk-sheet-foot {
    display: flex;
    gap: 10px;
    margin-top: 4px;
}

.hk-sheet-foot .btn {
    flex: 1;
    min-height: 50px;
}

/* ---- Banner di riconnessione (#components-reconnect-modal.hk-reconnect) ----
   Creato da js/hk-shell.js in fondo a <body>, fuori dall'albero Blazor, una volta per vita della pagina:
   dopo il primo ingresso in modalità telefono Blazor lo usa per ogni caduta di connessione, anche sulle
   pagine desktop. Per questo è globale e usa solo i token del tema. Nascosto finché Blazor non mette una
   classe di stato; la pausa voluta (app in secondo piano) resta invisibile. Il testo segue data-state
   (impostato da hk-shell.js); le classi "failed"/"rejected" bastano da sole. */
.hk-reconnect {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1150;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 8px 12px;
    padding: calc(8px + env(safe-area-inset-top)) 16px 8px;
    background: color-mix(in srgb, var(--warning) 16%, var(--bg-card));
    border-bottom: 1px solid var(--warning);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    color: var(--text-primary);
    font-size: .875rem;
    font-weight: 600;
    text-align: center;
}

.hk-reconnect.components-reconnect-show,
.hk-reconnect.components-reconnect-retrying,
.hk-reconnect.components-reconnect-failed,
.hk-reconnect.components-reconnect-rejected {
    display: flex;
}

.hk-reconnect.components-reconnect-paused,
.hk-reconnect[data-state="paused"] {
    display: none;
}

.hk-reconnect.components-reconnect-failed,
.hk-reconnect.components-reconnect-rejected {
    background: color-mix(in srgb, var(--danger) 16%, var(--bg-card));
    border-bottom-color: var(--danger);
}

.hk-reconnect-msg { display: none; }
.hk-reconnect-lost { display: inline; }

.hk-reconnect[data-state="retrying"] .hk-reconnect-lost,
.hk-reconnect.components-reconnect-failed .hk-reconnect-lost,
.hk-reconnect.components-reconnect-rejected .hk-reconnect-lost {
    display: none;
}

.hk-reconnect[data-state="retrying"] .hk-reconnect-retrying {
    display: inline;
}

.hk-reconnect.components-reconnect-failed .hk-reconnect-failed,
.hk-reconnect.components-reconnect-rejected .hk-reconnect-failed {
    display: inline;
}

.hk-reconnect-reload {
    display: none;
    min-height: 56px;
    padding: 0 20px;
    border: 0;
    border-radius: 12px;
    background: var(--accent);
    color: var(--on-accent);
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}

.hk-reconnect.components-reconnect-failed .hk-reconnect-reload,
.hk-reconnect.components-reconnect-rejected .hk-reconnect-reload {
    display: inline-flex;
    align-items: center;
}

.hk-reconnect-reload:focus-visible {
    outline: 2px solid var(--text-primary);
    outline-offset: 2px;
}

/* =================== STAMPA =================== */
/* Stampa di una pagina: via lo shell (sidebar, topbar, scrim del drawer, skip-link, assistente AI,
   toast, banner d'errore Blazor) e via i vincoli di altezza/overflow della griglia a tutta
   finestra, altrimenti si stampa solo la porzione visibile del pannello. Selettori reali di
   MainLayout.razor / Sidebar.razor / Topbar.razor / StayAiChat.razor / NotificationCenter.razor. */
@media print {
    .sidebar, .topbar, .sidebar-scrim, .skip-link, .ai-drawer, .notif-toasts, #blazor-error-ui { display: none !important; }
    html, body { height: auto !important; overflow: visible !important; }
    /* Carta bianca con qualunque tema (dark/indigo ridefiniscono i token su :root[data-theme]). */
    :root, :root[data-theme] { --bg-app: #fff; --bg-card: #fff; --text-primary: #000; --text-secondary: #333; }
    body { background: #fff; color: #000; }
    .app { display: block !important; height: auto !important; }
    .main { display: block !important; overflow: visible !important; padding: 0 !important; }
    .panel-full { overflow: visible !important; height: auto !important; border: 0; box-shadow: none; border-radius: 0; }
    /* Registro corrispettivi: rotolo 80 mm (pagina con nome: le altre pagine restano A4/Letter). */
    .panel-full.cor { page: cor-roll-80mm; }
}
/* "80mm auto" non è un valore valido di size (verrebbe ignorato): 80 x 297 mm è la carta
   "Roll Paper" dei driver delle stampanti termiche (Epson TM, Star); il margine resta 4 mm. */
@page cor-roll-80mm { size: 80mm 297mm; margin: 4mm; }
