/*
 * MendAi Design System — token e componenti.
 *
 * FONTE UNICA dei valori: il preset Tailwind (tailwind.mend-ds.preset.js) li legge
 * da qui tramite var(), non li ricopia. Si cambia un valore qui, e basta.
 * Documentazione e regole d'uso: brain/wiki/11-design-system/design-system.md
 *
 * Stile ricostruito misurando i valori calcolati del template B2base (Webflow),
 * senza copiarne i file né gli asset: le texture sono rifatte in CSS.
 *
 * Tutto è opt-in: le classi .ds-* e lo scope .ds non toccano le pagine esistenti.
 */

:root {
    /* ── Colori ─────────────────────────────────────────────── */
    --ds-ink: #061b31;            /* testo e titoli: blu-notte, mai nero puro */
    --ds-white: #ffffff;
    /* ▶ IL COLORE DEL MARCHIO SI CAMBIA QUI, E SOLO QUI. Le tre sfumature sotto
       ne derivano (blocco @supports più in basso); i valori scritti qui accanto sono
       solo il ripiego per i browser senza colori relativi (pre-2024) e vanno
       riallineati a mano se il colore cambia. */
    --ds-accent: #216351;         /* verde bosco: CTA, stati attivi, link-freccia */
    --ds-accent-light: #74c0ab;   /* alone del pallino badge, inizio gradienti */
    --ds-accent-mist: #a8c9c0;    /* tappa intermedia dei gradienti chiari */
    --ds-accent-deep: #0d3026;    /* fondo dei gradienti scuri */

    --ds-50: #fafafa;             /* superficie delle card */
    --ds-100: #f7f7f7;            /* LINEE della griglia, bordi sottili, hover card */
    --ds-200: #f2f2f2;            /* bordo navbar, input, divider tratteggiato, hover bottone secondario */
    --ds-300: #ededed;
    --ds-400: #e6e6e6;
    --ds-500: #dedede;
    --ds-600: #d9d9d9;            /* bordo input in focus */
    --ds-700: #d1d1d1;
    --ds-800: #c2c2c2;
    --ds-900: #a6a6a6;            /* testo secondario */

    --ds-danger-ink: #3b0b0b;
    --ds-danger-bg: #f8e4e4;
    --ds-danger: #d92d20;         /* rosso acceso: azioni distruttive (Marco, 2026-10-22) */
    --ds-success-bg: #ededed;
    --ds-success-ink: #000000;
    --ds-warn-ink: #5c4200;       /* avvisi (derivato: il template non ne ha) */
    --ds-warn-bg: #fbf3dc;
    --ds-check: #000d14;          /* checkbox spuntata */

    /* ── Font ───────────────────────────────────────────────── */
    --ds-font-body: "Google Sans", ui-sans-serif, system-ui, sans-serif;
    --ds-font-heading: "Google Sans Flex", "Google Sans", ui-sans-serif, system-ui, sans-serif;
    --ds-font-mono: "Google Sans Code", ui-monospace, SFMono-Regular, Menlo, monospace;

    /* ── Scala tipografica (desktop; sotto 768px vedi media query) ─ */
    --ds-h1: 3.5rem;      --ds-h1-lh: 110%;
    --ds-h2: 2.5rem;      --ds-h2-lh: 115%;
    --ds-h3: 2rem;        --ds-h3-lh: 120%;
    --ds-h4: 1.75rem;     --ds-h4-lh: 120%;
    --ds-h5: 1.5rem;      --ds-h5-lh: 130%;
    --ds-h6: 1.125rem;    --ds-h6-lh: 130%;
    --ds-text-lg: 1.25rem;
    --ds-text-md: 1.1rem;
    --ds-text-base: 1rem;
    --ds-text-sm: 0.9rem;       /* bottoni, label (gli input sono a 16px) */
    --ds-text-nav: 0.875rem;
    --ds-text-badge: 0.875rem;  /* 14px: nessun testo sotto (Marco, 2026-10-12) */
    --ds-lh-body: 150%;

    /* ── Raggi ──────────────────────────────────────────────── */
    --ds-radius: 6px;           /* bottoni, card, input, immagini, pannelli */
    --ds-radius-icon: 4px;      /* riquadri icona, pulsante +/− delle FAQ */
    --ds-radius-chip: 2px;      /* chip di metadati, checkbox */
    --ds-radius-dot: 50px;

    /* ── Layout ─────────────────────────────────────────────── */
    --ds-container: 1232px;
    --ds-width-xl: 1138px;
    --ds-width-lg: 896px;
    --ds-width-md: 654px;
    --ds-width-sm: 480px;
    --ds-gutter: 16px;          /* padding del container e delle card */
    --ds-grid-gap: 6px;         /* spazio fra card affiancate: stretto, voluto */
    --ds-section-sm: 48px;
    --ds-section-md: 96px;
    --ds-section-lg: 144px;
    --ds-nav-h: 76px;

    /* ── Linee ──────────────────────────────────────────────── */
    --ds-line: 1px solid var(--ds-100);
    --ds-line-strong: 1px solid var(--ds-200);

    /* ── Ombre (quasi tutto è piatto: solo due livelli) ───────── */
    --ds-shadow-lift: 0 16px 36px rgba(0, 0, 0, 0.12), 0 40px 40px rgba(0, 0, 0, 0.06);
    --ds-shadow-pop: 0 6px 20px rgba(0, 0, 0, 0.03);

    /* ── Movimento ──────────────────────────────────────────── */
    --ds-fast: 0.2s;
    --ds-slow: 0.3s;

    /* ── Gradienti ──────────────────────────────────────────── */
    --ds-grad-hero: linear-gradient(180deg, #fff 25%, var(--ds-accent-mist) 59%, var(--ds-accent) 102%);
    --ds-grad-dark: linear-gradient(180deg, var(--ds-accent), var(--ds-accent-deep));
    --ds-grad-banner: linear-gradient(180deg, var(--ds-accent-light), var(--ds-accent) 50%, var(--ds-accent));
    --ds-grad-footer: linear-gradient(180deg, #fff 30%, var(--ds-accent));
}

/* Le sfumature dell'accento, ricavate in OKLCH (chiarezza + saturazione, stessa tinta).
   Scarti misurati sul verde del template, così col #216351 tornano i valori originali:
   light = +0.30 chiarezza, ×1.13 saturazione · mist = +0.357, ×0.51 · deep = −0.172, ×0.61.
   In @supports perché una variabile con un colore che il browser non capisce non
   ricade sul valore di prima: diventa invalida, e il gradiente sparirebbe. */
@supports (color: oklch(from red l c h)) {
    :root {
        --ds-accent-light: oklch(from var(--ds-accent) calc(l + 0.3) calc(c * 1.13) h);
        --ds-accent-mist: oklch(from var(--ds-accent) calc(l + 0.357) calc(c * 0.51) h);
        --ds-accent-deep: oklch(from var(--ds-accent) calc(l - 0.172) calc(c * 0.61) h);
    }
}

@media (max-width: 991px) {
    :root {
        --ds-section-sm: 44px;
        --ds-section-md: 84px;
        --ds-section-lg: 128px;
        --ds-nav-h: 3.9rem;
    }
}

@media (max-width: 767px) {
    :root {
        --ds-h1: 2.625rem;
        --ds-h2: 1.875rem;
        --ds-h3: 1.5rem;
        --ds-h4: 1.3125rem;
        --ds-h5: 1.125rem;
        --ds-h6: 1rem;
        --ds-text-lg: 1.125rem;
        --ds-section-sm: 40px;
        --ds-section-md: 72px;
        --ds-section-lg: 112px;
    }
}

/* ═════════════════════════════════════════════════════════════
 * Scope: metti .ds sul <body> (o su un wrapper) per le basi.
 * ═════════════════════════════════════════════════════════════ */
.ds {
    margin: 0;
    background: var(--ds-white);
    color: var(--ds-ink);
    font-family: var(--ds-font-body);
    font-size: var(--ds-text-base);
    line-height: var(--ds-lh-body);
    font-weight: 400;
    font-feature-settings: "dlig";
    -webkit-font-smoothing: antialiased;
    /* Una parola più larga della riga (email, URL, percorso, token) va a capo
       invece di spingere la pagina di lato. `break-word` e non `anywhere`: non
       cambia la larghezza minima, quindi le tabelle restano larghe e scorrono
       nel loro contenitore invece di spezzare ogni parola. */
    overflow-wrap: break-word;
}
.ds *, .ds *::before, .ds *::after { box-sizing: border-box; }
:where(.ds) :where(button, input, select, textarea) { font: inherit; color: inherit; }   /* specificità zero: le classi .ds-* vincono */

/* ── Titoli: peso 400, mai bold. È metà del carattere dello stile. ── */
.ds-h1, .ds-h2, .ds-h3, .ds-h4, .ds-h5, .ds-h6 {
    font-family: var(--ds-font-heading);
    font-weight: 400;
    letter-spacing: normal;
    margin: 0;
}
.ds-h1 { font-size: var(--ds-h1); line-height: var(--ds-h1-lh); }
.ds-h2 { font-size: var(--ds-h2); line-height: var(--ds-h2-lh); }
.ds-h3 { font-size: var(--ds-h3); line-height: var(--ds-h3-lh); }
.ds-h4 { font-size: var(--ds-h4); line-height: var(--ds-h4-lh); }
.ds-h5 { font-size: var(--ds-h5); line-height: var(--ds-h5-lh); font-weight: 500; }
.ds-h6 { font-size: var(--ds-h6); line-height: var(--ds-h6-lh); font-weight: 500; }

.ds-text-lg { font-size: var(--ds-text-lg); line-height: var(--ds-lh-body); }
.ds-text-md { font-size: var(--ds-text-md); line-height: var(--ds-lh-body); }
.ds-text-sm { font-size: var(--ds-text-sm); line-height: var(--ds-lh-body); }
.ds-muted { opacity: 0.8; }
.ds-muted-60 { opacity: 0.6; }
.ds-secondary { color: var(--ds-900); }

/* ── Badge / eyebrow: mono leggero, maiuscolo, pallino con alone ── */
.ds-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--ds-font-mono);
    font-size: var(--ds-text-badge);
    line-height: var(--ds-text-badge);
    font-weight: 300;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: inherit;
}
.ds-badge-dot {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 12px;
    height: 12px;
    flex: 0 0 auto;
}
.ds-badge-dot::before {             /* alone */
    content: "";
    position: absolute;
    width: 10px;
    height: 10px;
    border-radius: var(--ds-radius-dot);
    background: var(--ds-accent-light);
}
.ds-badge-dot::after {              /* pallino */
    content: "";
    position: relative;
    width: 6px;
    height: 6px;
    border-radius: var(--ds-radius-dot);
    background: var(--ds-accent);
}

/* ═════════════════════════════════════════════════════════════
 * LA GRIGLIA A LINEE — il dettaglio che fa lo stile.
 *
 *   .ds-band  = fascia a tutta larghezza, linea sopra e sotto
 *   .ds-rails = container 1232px con linea a sinistra e a destra
 *   .ds-section-gap = aria FRA due fasce: lì le rotaie si interrompono
 *
 * Risultato: rotaie verticali che corrono lungo la pagina, tagliate da
 * linee orizzontali a ogni sezione, e un vuoto bianco senza linee fra
 * una sezione e l'altra.
 * ═════════════════════════════════════════════════════════════ */
.ds-band {
    border-top: var(--ds-line);
    border-bottom: var(--ds-line);
    padding-left: 16px;
    padding-right: 16px;
}
.ds-band.no-bottom { border-bottom: 0; }
/* Fascia attaccata alla navbar: la linea sopra la dà già la navbar */
.ds-band.no-top { border-top: 0; }
/* Sul telefono le rotaie stanno a 8px dal bordo, non a 20: restano visibili (lo
   stile è quello) ma non mangiano la pagina. Fascia 20 + rotaia 16 + card.lg 24
   lasciavano ~253px di contenuto su 375 (Marco, 2026-10-12). La navbar si
   stringe dello stesso tanto, così le sue linee restano allineate alle rotaie. */
@media (max-width: 767px) { .ds-band { padding-left: 0.5rem; padding-right: 0.5rem; } }

.ds-rails {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: var(--ds-container);
    margin-left: auto;
    margin-right: auto;
    padding: var(--ds-gutter);
    border-left: var(--ds-line);
    border-right: var(--ds-line);
}
.ds-rails.flush { padding: 0; }

.ds-section-gap { padding-top: var(--ds-section-md); }
.ds-section-gap.sm { padding-top: var(--ds-section-sm); }
.ds-section-gap.lg { padding-top: var(--ds-section-lg); }

/* Linea piena che separa due .ds-rails impilate nella stessa fascia */
.ds-divider {
    width: 100%;
    max-width: var(--ds-container);
    height: 1px;
    margin-left: auto;
    margin-right: auto;
    background: var(--ds-100);
}

/* Intestazione di sezione: «• NOME» a sinistra, «01» a destra */
.ds-section-title {
    display: flex;
    justify-content: space-between;
    align-items: stretch;
    padding-top: 8px;
    padding-bottom: 8px;
}

/* Divider tratteggiato fra voci di un elenco: 6px pieno, 6px vuoto */
.ds-dash {
    width: 100%;
    height: 1px;
    background-image: repeating-linear-gradient(90deg, var(--ds-200) 0 6px, transparent 6px 12px);
}

/* ═════════════════════════════════════════════════════════════
 * Texture (rifatte in CSS, nessun asset del template)
 * ═════════════════════════════════════════════════════════════ */
.ds-textured { position: relative; isolation: isolate; overflow: hidden; }

/* Vetro scanalato: colonne verticali da 44px */
.ds-tile::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image: repeating-linear-gradient(90deg,
        rgba(204, 204, 255, 0.04) 0,
        rgba(255, 255, 255, 0.07) 44px);
}
/* Grana: rumore al 5% */
.ds-noise::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    opacity: 0.05;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.ds-bg-hero   { background-image: var(--ds-grad-hero); }
.ds-bg-dark   { background-image: var(--ds-grad-dark); color: var(--ds-white); }
.ds-bg-banner { background-image: radial-gradient(ellipse 60% 50% at 50% 0, rgba(255, 255, 255, 0.25), transparent 70%), var(--ds-grad-banner); color: var(--ds-white); }
.ds-bg-footer { background-image: var(--ds-grad-footer); }

/* ═════════════════════════════════════════════════════════════
 * Navbar
 * ═════════════════════════════════════════════════════════════ */
.ds-navbar {
    position: sticky;
    top: 0;
    z-index: 50;
    height: var(--ds-nav-h);
    border-bottom: var(--ds-line-strong);
    background: transparent;
}
.ds-navbar-inner {                 /* allineata alle rotaie */
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1.25rem;
    max-width: var(--ds-container);
    height: 100%;
    margin: 0 auto;
    padding: 0 16px;
    background: var(--ds-white);
    border-left: var(--ds-line);
    border-right: var(--ds-line);
    border-bottom: var(--ds-line);
}
.ds-navbar-inner > :last-child { justify-self: end; display: flex; gap: 0.5rem; white-space: nowrap; }
.ds-navbar-menu { display: flex; align-items: center; }
/* Sotto 992px il menu centrale sparisce: la schermata mette il suo hamburger */
@media (max-width: 991px) {
    .ds-navbar-inner { display: flex; justify-content: space-between; }
    .ds-navbar-menu { display: none; }
}
/* Allineata alle rotaie del telefono (vedi .ds-band): fondo bianco sui due
   margini, se no sotto la navbar sticky si vedrebbe scorrere la pagina. */
@media (max-width: 767px) {
    .ds-navbar { padding: 0 0.5rem; background: var(--ds-white); }
    /* la tendina sta dentro la navbar ma ha già la sua .ds-band: niente doppio rientro */
    .ds-navbar-drawer { margin: 0 -0.5rem; }
}
/* Tendina mobile dei pannelli: sta dentro la navbar sticky, quindi la pagina
   scorre sotto ma lei no. Con più voci dello schermo scorre da sé, fino al
   bordo inferiore, senza trascinare la pagina (overscroll).
   Il padding in fondo: alcuni browser (barra in basso di Safari iOS, Samsung
   Internet, browser dentro le app) la disegnano sopra la pagina e `dvh` la
   conta come spazio visibile, quindi l'ultima voce finiva sotto la barra. */
.ds-navbar-drawer {
    max-height: calc(100vh - var(--ds-nav-h));
    max-height: calc(100dvh - var(--ds-nav-h));
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-bottom: calc(5rem + env(safe-area-inset-bottom, 0px));
    background: var(--ds-white);
}
.ds-nav-link {
    padding: 1.75rem 1rem;
    font-size: var(--ds-text-nav);
    line-height: 1.4;
    color: var(--ds-ink);
    text-decoration: none;
    transition: opacity var(--ds-fast);
}
.ds-nav-link:hover { opacity: 0.5; }
button.ds-nav-link { background: none; border: 0; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; }
/* L'hamburger dei pannelli sotto i 992px. Aveva `.ds-nav-link`, il padding dei link
   del menu desktop (1.75rem × 1rem): alto 80px in una navbar da 62 e rientrato di
   16px rispetto al contenuto (Marco, 2026-10-12). Ora 40px, e i margini negativi
   portano le tre linee (che nel disegno da 24 partono a 4px) a filo del contenuto
   della pagina, a 16px dal logo. */
.ds-nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 40px;
    height: 40px;
    margin: 0 -8px 0 -12px;
    padding: 0;
    border: 0;
    border-radius: var(--ds-radius);
    background: none;
    color: var(--ds-ink);
    cursor: pointer;
}
.ds-nav-toggle svg { width: 24px; height: 24px; }

/* Voce di un menu a tendina (DERIVATO: il pannello ha gruppi di voci, il template
   no). Sta dentro un .ds-panel; attiva = verde, come la tab a celle. */
.ds-menu { display: flex; flex-direction: column; gap: 2px; padding: 0.375rem; min-width: 13rem; }
.ds-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;               /* comoda col dito (Marco, 2026-10-22) */
    padding: 0.5rem 0.75rem;
    border-radius: var(--ds-radius);
    font-size: var(--ds-text-nav);
    line-height: 1.4;
    color: var(--ds-ink);
    text-decoration: none;
    transition: background-color var(--ds-fast);
}
.ds-menu-item:hover { background: var(--ds-200); }
.ds-menu-item.is-current { color: var(--ds-accent); font-weight: 500; }
.ds-menu-item svg { width: 16px; height: 16px; flex: 0 0 auto; }
button.ds-menu-item { width: 100%; border: 0; background: none; cursor: pointer; text-align: left; font-family: inherit; }
.ds-menu-sep { height: 1px; margin: 4px 0; background: var(--ds-400); }
/* Voce distruttiva (elimina, revoca): come `.ds-btn.danger`, testo rosso e hover rosso pieno. */
.ds-menu-item.danger { color: var(--ds-danger); }
.ds-menu-item.danger:hover { background: var(--ds-danger); color: var(--ds-white); }

/* Menu dell'account nella navbar (DERIVATO, Marco 2026-10-12): le iniziali in un
   pallino al posto di nome + «Il mio account» + «Esci», che sul telefono non ci
   stavano e sul desktop toglievano posto al menu. Nome, email, account ed
   «Esci» stanno nella tendina (.ds-panel.ds-menu.ds-account-menu). */
.ds-account {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px;
    border: 0;
    border-radius: var(--ds-radius);
    background: none;
    color: var(--ds-ink);
    cursor: pointer;
}
.ds-account-initials {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: var(--ds-line-strong);
    border-radius: var(--ds-radius-dot);
    background: var(--ds-50);
    font-size: var(--ds-text-sm);
    font-weight: 500;
    letter-spacing: 0.02em;
    transition: background-color var(--ds-fast);
}
.ds-account:hover .ds-account-initials { background: var(--ds-100); }
.ds-account.is-current .ds-account-initials { border-color: var(--ds-accent); color: var(--ds-accent); }
.ds-account svg { width: 14px; height: 14px; transition: transform var(--ds-fast); }
/* La navbar ha il gruppo di destra `nowrap`: la tendina va a capo per conto suo */
.ds-account-menu { width: 16rem; max-width: calc(100vw - 1rem); white-space: normal; }
.ds-nav-link.is-current { display: inline-flex; align-items: center; gap: 6px; font-weight: 500; }
.ds-nav-link.is-current::before {
    content: "";
    width: 6px; height: 6px;
    border-radius: var(--ds-radius-dot);
    background: var(--ds-accent);
}

/* Logo (componente <x-ds.logo />): SVG in fill="currentColor", quindi il colore
   è quello del testo che lo contiene. Si dimensiona in altezza, mai in larghezza. */
.ds-logo { display: block; height: 28px; width: auto; flex: 0 0 auto; }
.ds-logo.sm { height: 20px; }
.ds-logo.lg { height: 40px; }
.ds-brand { display: inline-flex; align-items: center; color: var(--ds-ink); text-decoration: none; }
.ds-brand.on-dark { color: var(--ds-white); }

/* Footer: linea sopra, gradiente verso il verde, rotaie fino in fondo */
.ds-footer { margin-top: var(--ds-section-md); border-top: var(--ds-line); }
.ds-footer > .ds-rails { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; min-height: 220px; color: var(--ds-white); }

/* ═════════════════════════════════════════════════════════════
 * Bottoni
 * ═════════════════════════════════════════════════════════════ */
.ds-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    /* Ogni bottone ha un bordo di 1px, trasparente sul primario: senza, il primario
       era 2px più basso del secondario accanto (Marco, 2026-10-22). */
    padding: 11px 19px;
    border: 1px solid transparent;
    border-radius: var(--ds-radius);
    background: var(--ds-accent);
    color: var(--ds-white);
    font-family: var(--ds-font-body);
    font-size: var(--ds-text-sm);
    line-height: var(--ds-lh-body);
    font-weight: 500;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--ds-fast), color var(--ds-fast), border-color var(--ds-fast);
}
/* Hover solo di colore (Marco, 2026-10-22): il bottone non cambia misura. Fino ad allora
   l'opacità calava e lo spazio verso la freccia cresceva, allargando il bottone. */
.ds-btn:hover:not(:disabled) { background: color-mix(in srgb, var(--ds-accent) 82%, var(--ds-ink)); }
.ds-btn svg { width: 16px; height: 16px; flex: 0 0 auto; }

.ds-btn.secondary {
    background: var(--ds-white);
    color: var(--ds-ink);
    border: var(--ds-line);
}
.ds-btn.secondary:hover { background: var(--ds-200); border-color: var(--ds-600); }

/* `outline` è anche un'utility Tailwind (`outline-style: solid`, 3px di default),
 * generata appena una vista usa la classe: senza `outline: 0` si somma al bordo. */
.ds-btn.outline {                                 /* su fondo scuro */
    background: transparent;
    color: var(--ds-white);
    border: 1px solid var(--ds-white);
    outline: 0;
}
.ds-btn.outline:hover { background: var(--ds-200); color: var(--ds-ink); }
.ds-btn.outline:focus-visible { outline: 1px solid var(--ds-white); outline-offset: 2px; }

/* Azione distruttiva (DERIVATO, 2026-09-29; rivista da Marco il 2026-10-22): testo rosso
   acceso su bianco, filo dello stesso rosso; all'hover rosso pieno col testo bianco.
   Il rosso pieno solo all'hover: a riposo il verde resta l'unico accento.
   Una classe sua e non `text-ds-danger-ink`, che perde contro .ds-btn.secondary. */
.ds-btn.secondary.danger, .ds-btn.danger {
    background: var(--ds-white);
    color: var(--ds-danger);
    border: 1px solid color-mix(in srgb, var(--ds-danger) 35%, transparent);
}
.ds-btn.danger:hover:not(:disabled) { background: var(--ds-danger); border-color: var(--ds-danger); color: var(--ds-white); }

/* «Vedi come» (Marco, 2026-10-22): uscire dal pannello verso ciò che vede il cliente è
   un'azione, non un allarme. Bianco col filo e il testo verdi: si distingue dal primario
   (pieno) e dal secondario (filo grigio). Prima era `.warn`, e si confondeva col banner
   giallo «Da fare». */
.ds-btn.esce { background: var(--ds-white); color: var(--ds-accent); border-color: var(--ds-accent); }
.ds-btn.esce:hover { background: color-mix(in srgb, var(--ds-accent) 8%, var(--ds-white)); }

/* Uscita dal pannello (DERIVATO, Marco 2026-10-14): «Vedi come» apre il portale del
   cliente in un'altra scheda. Nei colori dell'avviso, così non si confonde con le
   azioni che restano qui. Bordo e hover ricavati dagli stessi due token. */
.ds-btn.warn {
    background: var(--ds-warn-bg);
    color: var(--ds-warn-ink);
    border: 1px solid color-mix(in srgb, var(--ds-warn-ink) 25%, transparent);
}
.ds-btn.warn:hover { background: color-mix(in srgb, var(--ds-warn-ink) 10%, var(--ds-warn-bg)); }

/* Due altezze sole: ~46px (testata, form) e ~34px (`.sm`, dentro card e righe).
   Il bottone solo icona è un quadrato della stessa altezza (1.35rem = riga di testo). */
.ds-btn.sm { padding: 5px 15px; }
.ds-btn.icon { padding: 0; width: calc(1.35rem + 24px); height: calc(1.35rem + 24px); }
.ds-btn.icon.sm { width: calc(1.35rem + 12px); height: calc(1.35rem + 12px); }
/* `block` è anche un'utility Tailwind (`display: block`), come `outline` sopra: senza
 * ridire `display` il bottone smette di essere flex e la freccia va a capo da sola. */
.ds-btn.block { display: flex; width: 100%; }
.ds-btn:disabled, .ds-btn[aria-disabled="true"] { opacity: 0.4; cursor: default; }

/* Link con freccia: verde; all'hover cambia solo il colore (Marco, 2026-10-22: niente
   cose che si allargano), prima lo spazio verso la freccia cresceva. */
.ds-link-arrow {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    color: var(--ds-accent);
    font-weight: 400;
    text-decoration: none;
    transition: color var(--ds-fast);
}
.ds-link-arrow:hover { color: color-mix(in srgb, var(--ds-accent) 75%, var(--ds-ink)); }

/* ═════════════════════════════════════════════════════════════
 * Superfici
 * ═════════════════════════════════════════════════════════════ */
.ds-card {                         /* nessun bordo, nessuna ombra: solo un grigio appena */
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1rem;
    border-radius: var(--ds-radius);
    background: var(--ds-50);
}
.ds-card.hoverable { transition: background-color var(--ds-slow); }
.ds-card.hoverable:hover { background: var(--ds-100); }
.ds-card.lg { padding: 1.5rem; }
/* Sul telefono una card grande ha il padding di una normale, e una card dentro
   una card ne ha un po' meno: ogni scatola annidata toglieva 48px di larghezza. */
@media (max-width: 767px) {
    .ds-card.lg { padding: 1rem; }
    .ds-card .ds-card, .ds-panel .ds-card { padding: 0.75rem; }
}
.ds-card.outlined { border: var(--ds-line); }
.ds-card.featured {                /* card in evidenza: gradiente scuro + texture + ombra */
    position: relative;
    isolation: isolate;
    overflow: hidden;
    color: var(--ds-white);
    background-image: var(--ds-grad-dark);
    box-shadow: var(--ds-shadow-lift);
}

.ds-grid { display: grid; gap: var(--ds-grid-gap); }
.ds-grid.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ds-grid.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ds-grid.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 991px) { .ds-grid.cols-3, .ds-grid.cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* `minmax(0, 1fr)` anche qui, non `1fr`: un `1fr` nudo non scende sotto il contenuto, e
   un testo `truncate` dentro una card allargava la colonna fino a 800px (2026-10-12). */
@media (max-width: 767px) { .ds-grid.cols-2, .ds-grid.cols-3, .ds-grid.cols-4 { grid-template-columns: minmax(0, 1fr); } }

.ds-icon-box {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border: var(--ds-line);
    border-radius: var(--ds-radius-icon);
    background: var(--ds-white);
}
.ds-icon-box.lg { width: 80px; height: 80px; }
.ds-icon-box svg { width: 24px; height: 24px; }

.ds-chip {                          /* metadati: data, categoria, stato */
    display: inline-block;
    padding: 6px 8px;
    border-radius: var(--ds-radius-chip);
    background: var(--ds-50);
    font-family: var(--ds-font-mono);
    font-size: var(--ds-text-badge);
    line-height: 1;
    font-weight: 300;
    letter-spacing: 0.6px;
    text-transform: uppercase;
}
.ds-chip.on-card { background: var(--ds-white); }

.ds-panel {                         /* dropdown, popover, menu */
    padding: 1.5rem;
    border: var(--ds-line);
    border-radius: var(--ds-radius);
    background: var(--ds-white);
    box-shadow: var(--ds-shadow-pop);
}

@media (max-width: 767px) { .ds-panel { padding: 1rem; } }
/* Una tendina è un .ds-panel con .ds-menu: `.ds-panel` è scritto dopo e, a parità di peso,
   le dava 24px di bordo interno («bordi sproporzionati», Marco 2026-10-22). */
.ds-panel.ds-menu { padding: 0.375rem; max-width: calc(100vw - 2rem); }

/* Involucro di un modale: `<div class="ds-modal">` > velo `fixed inset-0 bg-ds-ink
   opacity-40` + `.ds-panel`. Il pannello è centrato con `margin: auto`, non con
   `items-center`: se è più alto dello schermo (un telefono, un form lungo) l'involucro
   scorre e la cima resta raggiungibile, mentre un flex centrato la taglia fuori dallo
   schermo senza modo di arrivarci (2026-10-12). */
.ds-modal {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: flex;
    padding: 1rem;
    overflow-y: auto;
    overscroll-behavior: contain;
}
.ds-modal > .ds-panel { margin: auto; }
@media (max-width: 767px) { .ds-modal { padding: 0.5rem; } }
/* Sopra la navbar (50), sotto gli avvisi fluttuanti (60). Ma le rotaie hanno
   `z-index: 1`, cioè un contesto di impilamento: un modale lì dentro restava
   sotto la navbar sticky qualunque fosse il suo z-index, e sul telefono il
   pannello finiva dietro l'header (Marco, 2026-10-12). Finché il modale è
   aperto le rotaie che lo contengono rinunciano al loro. */
.ds-modal { z-index: 55; }
.ds-rails:has(.ds-modal) { z-index: auto; }
/* Modale aperto = la pagina sotto non scorre (sul telefono il dito la
   trascinava quando il pannello non aveva niente da scorrere). */
html:has(.ds-modal) { overflow: hidden; }

.ds-lift { box-shadow: var(--ds-shadow-lift); }

/* ═════════════════════════════════════════════════════════════
 * Form
 * ═════════════════════════════════════════════════════════════ */
.ds-label {
    display: block;
    margin-bottom: 0.375rem;
    font-size: var(--ds-text-sm);
    line-height: var(--ds-lh-body);
    font-weight: 400;
}
.ds-input {
    display: block;
    width: 100%;
    max-width: 100%;                  /* anche con `w-auto`: una select con un'opzione lunga non esce dalla card */
    min-height: 3rem;
    padding: 0.875rem 1rem;
    border: var(--ds-line-strong);
    border-radius: var(--ds-radius);
    background: var(--ds-white);
    color: var(--ds-ink);
    font-family: var(--ds-font-body);
    font-size: var(--ds-text-base);   /* 16px: sotto, iOS ingrandisce la pagina al tocco */
    line-height: 1.25rem;
    font-weight: 500;
    outline: none;
    transition: border-color var(--ds-fast);
}
.ds-input::placeholder { color: rgba(0, 0, 0, 0.6); font-weight: 400; }
.ds-input:focus { border-color: var(--ds-600); }
textarea.ds-input { min-height: 14rem; padding-top: 1rem; line-height: var(--ds-lh-body); }
.ds-input[aria-invalid="true"] { border-color: var(--ds-danger-ink); }

/* Zona di caricamento — `label.ds-drop` > `input.ds-drop-input` + `.ds-icon-box`
   + testo (derivato, Marco 2026-10-15: il campo file del browser «è retrò»).
   Si trascina il file dentro o si clicca; l'input resta vero (required, form
   normale), solo nascosto alla vista. Col file scelto il bordo diventa pieno. */
.ds-drop {
    position: relative;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1.25rem 1rem;
    border: 1px dashed var(--ds-800);
    border-radius: var(--ds-radius);
    background: var(--ds-50);
    color: var(--ds-ink);
    cursor: pointer;
    transition: border-color var(--ds-fast), background var(--ds-fast);
}
.ds-drop:hover, .ds-drop.is-over { border-color: var(--ds-accent); background: var(--ds-white); }
.ds-drop.has-file { border-style: solid; border-color: var(--ds-accent); background: var(--ds-white); }
.ds-drop:focus-within { border-color: var(--ds-accent); }
.ds-drop .ds-icon-box { flex-shrink: 0; color: var(--ds-accent); }
.ds-drop-testo { display: flex; flex-direction: column; gap: 0.125rem; min-width: 0; overflow-wrap: anywhere; }
.ds-drop-testo strong { font-weight: 500; }
.ds-drop-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

/* Campo password con l'occhiello — componente <x-ds.password> */
.ds-password { position: relative; }
.ds-password > .ds-input { padding-right: 3rem; }
.ds-password > .ds-input::-ms-reveal { display: none; } /* Edge ha il suo occhiello: ne basta uno */
.ds-password-toggle {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 3rem;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: var(--ds-radius);
    background: none;
    color: var(--ds-900);
    cursor: pointer;
    transition: color var(--ds-fast);
}
.ds-password-toggle:hover { color: var(--ds-ink); }
.ds-password-toggle:focus-visible { outline: 1px solid var(--ds-ink); outline-offset: -6px; }
.ds-password-toggle svg { width: 1.125rem; height: 1.125rem; }

.ds-check {
    width: 0.875rem;
    height: 0.875rem;
    margin: 0 0.5rem 0 0;
    border-radius: var(--ds-radius-chip);
    accent-color: var(--ds-check);
}

.ds-alert-error { padding: 0.75rem; background: var(--ds-danger-bg); color: var(--ds-danger-ink); border-radius: var(--ds-radius); }
.ds-alert-success { padding: 1.25rem; background: var(--ds-success-bg); color: var(--ds-success-ink); border-radius: var(--ds-radius); }
.ds-alert-warn { padding: 0.75rem; background: var(--ds-warn-bg); color: var(--ds-warn-ink); border-radius: var(--ds-radius); }

/* Sezione che porta la pagina su di sé quando compare (x-ds-scorri, app.js):
   si ferma sotto la navbar sticky, non dietro. */
[x-ds-scorri] { scroll-margin-top: calc(var(--ds-nav-h) + 1rem); }

/* Avvisi fluttuanti — componente <x-ds.avviso>. Il contenitore #ds-avvisi sta
   in ogni layout Livewire: in alto a destra, sotto la navbar, sopra le modali. */
.ds-avvisi {
    position: fixed;
    top: calc(var(--ds-nav-h) + 1rem);
    right: 1rem;
    z-index: 60;
    width: min(26rem, calc(100vw - 2rem));
    display: flex;
    flex-direction: column;
    gap: var(--ds-grid-gap);
    pointer-events: none;
}
.ds-avviso {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.875rem 0.75rem 0.875rem 1rem;
    box-shadow: var(--ds-shadow-lift);
    pointer-events: auto;
}
.ds-avviso-testo { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.ds-avviso-chiudi {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    border: 0;
    border-radius: var(--ds-radius-icon);
    background: none;
    color: inherit;
    opacity: 0.6;
    cursor: pointer;
    transition: opacity var(--ds-fast);
}
.ds-avviso-chiudi:hover { opacity: 1; }
.ds-avviso-chiudi:focus-visible { outline: 1px solid currentColor; outline-offset: 1px; }
.ds-avviso-chiudi svg { width: 0.875rem; height: 0.875rem; }
.ds-warn { color: var(--ds-warn-ink); }

/* ═════════════════════════════════════════════════════════════
 * Tab
 * ═════════════════════════════════════════════════════════════ */
/* Tab a pillola (filtri, categorie) */
.ds-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.ds-tab {
    padding: 0.5rem 1rem;
    border: var(--ds-line);
    border-radius: var(--ds-radius);
    background: transparent;
    color: var(--ds-ink);
    font-size: var(--ds-text-base);
    font-weight: 400;
    letter-spacing: 0.02em;
    cursor: pointer;
    text-decoration: none;
    transition: all var(--ds-fast);
}
.ds-tab.is-active, .ds-tab[aria-selected="true"] {
    border-color: var(--ds-accent);
    background: var(--ds-accent);
    color: var(--ds-white);
}

/* Tab a celle (navigazione principale di una sezione) */
.ds-tabs-cells {
    display: flex;
    margin-left: calc(-1 * var(--ds-gutter));
    margin-right: calc(-1 * var(--ds-gutter));
    border-top: var(--ds-line);
}
.ds-tab-cell {
    flex: 1 1 0%;
    padding: 1rem;
    border-right: var(--ds-line);
    border-bottom: 1px solid var(--ds-100);
    background: transparent;
    color: var(--ds-ink);
    text-align: center;
    text-decoration: none;
    cursor: pointer;
}
.ds-tab-cell:last-child { border-right: 0; }
.ds-tab-cell.is-active, .ds-tab-cell[aria-selected="true"] {
    border-bottom-color: var(--ds-accent);
    color: var(--ds-accent);
}

/* Tab con la linea sotto (DERIVATE, Marco 2026-10-22): le tab di una scheda nei pannelli.
   `.ds-tab-cell` resta per le fasce della vetrina: coi margini negativi e la linea da 1px,
   dentro un pannello «sembrava un errore di CSS».
   Ogni voce: icona + `<span class="ds-tab-testo">` + facoltativo `.ds-tab-num` (contatore).
   `.celle` = celle larghe uguali divise da linee. Scelta: testo verde e linea da 3px. */
.ds-tabs-linea { display: flex; gap: 0.25rem; overflow-x: auto; scrollbar-width: none; border-bottom: var(--ds-line-strong); }
.ds-tab-linea {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.875rem 1rem;
    margin-bottom: -1px;
    border: 0;
    border-bottom: 3px solid transparent;
    background: none;
    color: var(--ds-ink);
    opacity: 0.6;
    font-family: var(--ds-font-body);
    font-size: var(--ds-text-sm);
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--ds-fast), border-color var(--ds-fast), opacity var(--ds-fast);
}
.ds-tab-linea:hover { opacity: 1; border-bottom-color: var(--ds-600); }
.ds-tab-linea.is-active, .ds-tab-linea[aria-selected="true"] { opacity: 1; color: var(--ds-accent); border-bottom-color: var(--ds-accent); }
.ds-tab-linea svg { width: 16px; height: 16px; flex: 0 0 auto; }
.ds-tab-num {
    padding: 3px 6px;
    border-radius: var(--ds-radius-chip);
    background: var(--ds-200);
    color: var(--ds-ink);
    font-family: var(--ds-font-mono);
    font-size: var(--ds-text-badge);
    line-height: 1;
}
.ds-tab-linea.is-active .ds-tab-num { background: var(--ds-accent); color: var(--ds-white); }
.ds-tabs-linea.celle { gap: 0; }
.ds-tabs-linea.celle .ds-tab-linea { flex: 1 0 auto; justify-content: center; border-right: var(--ds-line); }
.ds-tabs-linea.celle .ds-tab-linea:last-child { border-right: 0; }

/* Sul telefono (Marco, 2026-10-22): le spente mostrano solo l'icona (48px), la scelta icona,
   nome e contatore e prende lo spazio che resta. UN solo movimento al cambio: la cella
   cresce con flex-grow, il testo è già a misura piena e la cella lo scopre, poi compare in
   dissolvenza. Animare anche la larghezza del testo dava due ritmi diversi («lagga»).
   Il velo bianco a destra sfuma un nome che non ci sta senza toccare il bordo (una maschera
   sfumava anche la linea fra le tab). Griglia due per riga e riga che scorre: scartate. */
@media (max-width: 767px) {
    .ds-tabs-linea.celle { overflow: hidden; }
    .ds-tabs-linea.celle .ds-tab-linea {
        position: relative;
        flex: 0 0 48px;
        min-width: 0;
        overflow: hidden;
        justify-content: flex-start;
        padding: 0.75rem 15px;
        transition: flex-grow 0.3s cubic-bezier(0.4, 0, 0.2, 1), color var(--ds-fast), border-color var(--ds-fast);
    }
    .ds-tabs-linea.celle .ds-tab-linea.is-active { flex-grow: 1; }
    .ds-tabs-linea.celle .ds-tab-linea::after {
        content: "";
        position: absolute;
        top: 0; right: 0; bottom: 0;
        width: 15px;
        background: linear-gradient(to right, transparent, var(--ds-white));
        pointer-events: none;
    }
    .ds-tabs-linea.celle .ds-tab-testo,
    .ds-tabs-linea.celle .ds-tab-num { flex: 0 0 auto; opacity: 0; transition: opacity 0.12s ease; }
    .ds-tabs-linea.celle .is-active .ds-tab-testo,
    .ds-tabs-linea.celle .is-active .ds-tab-num { opacity: 1; transition: opacity 0.2s ease 0.1s; }
}
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
    .ds-tabs-linea.celle .ds-tab-linea, .ds-tabs-linea.celle .ds-tab-linea * { transition: none; }
}

/* ═════════════════════════════════════════════════════════════
 * Accordion (FAQ)
 * ═════════════════════════════════════════════════════════════ */
.ds-accordion-list { display: flex; flex-direction: column; gap: 6px; }
.ds-accordion {
    padding: 1.5rem;
    border-radius: var(--ds-radius);
    background: var(--ds-50);
    cursor: pointer;
}
.ds-accordion > summary {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    list-style: none;
    font-size: var(--ds-text-md);
    line-height: var(--ds-lh-body);
}
.ds-accordion > summary::-webkit-details-marker { display: none; }
.ds-accordion > summary::after {        /* il + in un riquadro da 32px */
    content: "";
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border: var(--ds-line-strong);
    border-radius: var(--ds-radius-icon);
    background:
        linear-gradient(var(--ds-ink), var(--ds-ink)) center / 10px 2px no-repeat,
        linear-gradient(var(--ds-ink), var(--ds-ink)) center / 2px 10px no-repeat;
}
.ds-accordion[open] > summary::after {
    background: linear-gradient(var(--ds-ink), var(--ds-ink)) center / 10px 2px no-repeat;
}
.ds-accordion > :not(summary) { padding-top: 0.5rem; opacity: 0.8; }
@media (max-width: 767px) { .ds-accordion { padding: 1rem; } }

/* Schermata in una guida: mai più larga della sua misura vera né del contenitore. */
.ds-shot {
    display: block;
    max-width: 100%;
    height: auto;
    border: var(--ds-line-strong);
    border-radius: var(--ds-radius);
}

/* ═════════════════════════════════════════════════════════════
 * Elenchi e tabelle (DERIVATI: il template non ha tabelle,
 * questi applicano le sue regole alle schermate del pannello)
 * ═════════════════════════════════════════════════════════════ */
.ds-list-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1rem 0;
    border-bottom: var(--ds-line);
    transition: background-color var(--ds-slow), padding-left var(--ds-slow);
}
.ds-list-row:hover { background: var(--ds-50); }
.ds-list-row:not(.still):hover { padding-left: 1rem; }   /* .still = righe con controlli: non si spostano */
.ds-list-row:last-child { border-bottom: 0; }

.ds-table { width: 100%; border-collapse: collapse; font-size: var(--ds-text-sm); }
.ds-table th {
    padding: 0.75rem 1rem;
    border-bottom: var(--ds-line-strong);
    text-align: left;
    font-family: var(--ds-font-mono);
    font-size: var(--ds-text-badge);
    font-weight: 300;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--ds-ink);
}
.ds-table td { padding: 0.875rem 1rem; border-bottom: var(--ds-line); }
.ds-table tbody tr { transition: background-color var(--ds-slow); }
/* Sul telefono le celle si stringono: più colonne in vista prima di dover scorrere. */
@media (max-width: 767px) {
    .ds-table th, .ds-table td { padding-left: 0.625rem; padding-right: 0.625rem; }
}
.ds-table tbody tr:hover { background: var(--ds-50); }

/* Tabella che sul telefono diventa un elenco (DERIVATA, Marco 2026-10-22): scorrere di lato
   una tabella col dito non è comodo. `<table class="ds-table impila">`: sotto i 768px niente
   intestazioni, ogni riga è un blocco; la prima cella è il titolo, `td.ds-cella-azione` sta
   alla sua destra, le altre celle vanno sotto, una dopo l'altra, con l'etichetta presa da
   `data-label`; `td.ds-cella-larga` prende una riga intera. */
@media (max-width: 767px) {
    .ds-table.impila thead { display: none; }
    .ds-table.impila, .ds-table.impila tbody { display: block; }
    .ds-table.impila tr { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem 0.75rem; padding: 0.75rem 0; border-bottom: var(--ds-line); }
    .ds-table.impila tr:last-child { border-bottom: 0; }
    .ds-table.impila tbody tr:hover { background: none; }
    .ds-table.impila td { display: block; order: 2; padding: 0; border: 0; text-align: left; white-space: normal; }
    .ds-table.impila td:first-child { order: 0; }
    .ds-table.impila tr:has(.ds-cella-azione) td:first-child { flex: 1 1 0; min-width: 0; }
    .ds-table.impila td.ds-cella-azione { order: 1; }
    .ds-table.impila tr:has(.ds-cella-azione)::after { content: ""; order: 1; flex-basis: 100%; height: 0; }
    .ds-table.impila td.ds-cella-larga { flex-basis: 100%; }
    .ds-table.impila td[data-label]::before {
        content: attr(data-label) " ";
        margin-right: 0.25rem;
        font-family: var(--ds-font-mono);
        font-size: var(--ds-text-badge);
        letter-spacing: 0.6px;
        text-transform: uppercase;
        opacity: 0.6;
    }
}

/* Stato con pallino (derivato dal badge) */
.ds-status { display: inline-flex; align-items: center; gap: 6px; font-size: var(--ds-text-sm); }
.ds-status::before { content: ""; width: 6px; height: 6px; border-radius: var(--ds-radius-dot); background: currentColor; }
.ds-status.ok { color: var(--ds-accent); }
.ds-status.off { color: var(--ds-900); }
.ds-status.err { color: var(--ds-danger-ink); }
.ds-status.warn { color: var(--ds-warn-ink); }   /* in attesa, da guardare (derivato) */

/* Barra di consumo (derivato, #193): una risorsa contro il suo limite.
 * <div class="ds-meter warn"><span style="--ds-meter: 82%"></span></div>
 * La larghezza è l'unico valore inline: è un dato, non uno stile. */
.ds-meter { height: 6px; border-radius: var(--ds-radius-dot); background: var(--ds-200); overflow: hidden; }
.ds-meter > span { display: block; height: 100%; width: var(--ds-meter, 0%); background: var(--ds-accent); }
.ds-meter.warn > span { background: var(--ds-warn-ink); }
.ds-meter.err > span { background: var(--ds-danger-ink); }

/* Scheletro (derivato, Marco 2026-10-15): la forma di un dato che sta arrivando
 * da un fornitore. <span class="ds-skeleton h-4 w-40"></span> — altezza e
 * larghezza con le utility, il resto qui. Solo DENTRO una card: sul grigio
 * della pagina dei pannelli (`--ds-200`) sparirebbe.
 * Fondo `--ds-400` e riflesso bianco (Marco: «fai notare meglio le sfumature»):
 * con `--ds-200`/`--ds-100` la differenza era dell'1% e il movimento non si vedeva. */
.ds-skeleton {
    display: block; border-radius: var(--ds-radius-icon);
    background: linear-gradient(90deg, var(--ds-400) 30%, var(--ds-white) 50%, var(--ds-400) 70%);
    background-size: 250% 100%;
    animation: ds-skeleton 1.2s ease-in-out infinite;
}
@keyframes ds-skeleton { from { background-position: 100% 0; } to { background-position: -100% 0; } }
/* L'arrivo di ciò che lo scheletro aspettava: una dissolvenza breve invece di un
 * cambio secco (Marco: «scattini subito dopo il click su Vedi come»). Sulla radice
 * della parte vera; Livewire la mette al posto dello scheletro e l'animazione parte. */
.ds-arriva { animation: ds-arriva var(--ds-slow) ease-out; }
@keyframes ds-arriva { from { opacity: 0; } }

/* Link nel testo: verde, sottolineato solo all'hover */
.ds-link { color: var(--ds-accent); text-decoration: none; }
.ds-link:hover { text-decoration: underline; }

/* ═════════════════════════════════════════════════════════════
 * Variante «pannello» (DERIVATA, Marco 2026-10-14): `<body class="ds pannello">`
 * nei soli layout app, tenant e portal. Il sito di vendita resta com'è.
 * La card a `--ds-50` su bianco (il 2%) spariva in un pannello pieno di
 * blocchi: qui la pagina è grigia e la card bianca, a tutta larghezza.
 * ═════════════════════════════════════════════════════════════ */
.ds.pannello {
    --ds-container: 100%;
    --ds-line: 1px solid var(--ds-400);
    --ds-line-strong: 1px solid var(--ds-500);
    background: var(--ds-200);
}
/* Lo spazio della barra di scorrimento sempre riservato (2026-10-15): quando una
   pagina si allunga dopo il caricamento (la home del portale, che si riempie)
   la barra compariva a pagina già disegnata e spostava tutto di 15px. */
html:has(> body.ds.pannello) { scrollbar-gutter: stable; }
.ds.pannello .ds-card { background: var(--ds-white); box-shadow: 0 0 0 1px var(--ds-300); }
.ds.pannello .ds-card.hoverable:hover { background: var(--ds-50); }
/* Dentro una card bianca, ciò che prima era bianco su grigio diventa grigio su bianco. */
.ds.pannello .ds-card .ds-card,
.ds.pannello .ds-card .ds-accordion,
.ds.pannello .ds-card .ds-chip.on-card,
.ds.pannello .ds-card .bg-ds-white { background: var(--ds-200); box-shadow: none; }

/* ═════════════════════════════════════════════════════════════
 * Dashboard (DERIVATI, Marco 2026-10-14): la home del portale.
 * ═════════════════════════════════════════════════════════════ */
/* Due colonne (contenuto · lato) da 992px, a ogni larghezza: «Da fare» resta
   SOPRA i servizi (Marco: le tre colonne da 1440px lo mettevano accanto). */
.ds-dash-layout { display: grid; gap: var(--ds-grid-gap); grid-template-columns: minmax(0, 1fr); align-items: start; }
.ds-dash-main, .ds-dash-side { display: flex; flex-direction: column; gap: var(--ds-grid-gap); min-width: 0; }
@media (min-width: 992px) { .ds-dash-layout { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); } }

/* «Da fare»: righe numerate, il bottone a destra (sotto il testo sul telefono). */
.ds-todo { display: flex; gap: 1rem; align-items: flex-start; padding: 1rem 0; border-bottom: var(--ds-line); }
.ds-todo:first-child { padding-top: 0; }
.ds-todo:last-child { border-bottom: 0; padding-bottom: 0; }
.ds-todo > div { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.ds-todo > :last-child:not(div) { flex: 0 0 auto; }
.ds-todo > .ds-icon-box { color: var(--ds-warn-ink); background: var(--ds-warn-bg); border: 0; }   /* l'icona della voce, nei colori dell'avviso */
@media (max-width: 767px) {
    .ds-todo { flex-wrap: wrap; }
    .ds-todo > div { flex-basis: calc(100% - 56px); }
    .ds-todo > :last-child:not(div) { margin-left: 56px; }
}

/* ═════════════════════════════════════════════════════════════
 * Icone e menu laterale (DERIVATI, Marco 2026-10-14)
 * ═════════════════════════════════════════════════════════════ */
/* <x-ds.icona nome="…" />: Lucide, 18px di base, colore del testo. */
.ds-icona { width: 18px; height: 18px; flex: 0 0 auto; }
.ds-icon-box .ds-icona { width: 20px; height: 20px; }

/* Il guscio dei pannelli: menu a sinistra (256px), pagina a destra. Sotto i
   992px il menu esce da sinistra col ☰ della barra in alto (`.ds-shell-top`).
   Lo stato aperto/chiuso è `menu` di Alpine sul <body>. */
.ds.pannello { --ds-nav-h: 0px; }
.ds-shell { display: grid; grid-template-columns: 256px minmax(0, 1fr); min-height: 100vh; }
.ds-shell-main { min-width: 0; display: flex; flex-direction: column; }
.ds-shell-top { display: none; }
.ds-sidebar {
    position: sticky; top: 0; height: 100vh; height: 100dvh; z-index: 30;
    display: flex; flex-direction: column; background: var(--ds-white); border-right: var(--ds-line);
}
.ds-sidebar-head { display: flex; align-items: center; gap: 10px; min-height: 64px; padding: 0 16px; border-bottom: var(--ds-line); }
.ds-sidebar-head .ds-brand { min-width: 0; }
.ds-sidebar-nav { flex: 1 1 auto; overflow-y: auto; padding: 12px 8px; display: flex; flex-direction: column; gap: 2px; }
.ds-sidebar-link {
    display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--ds-radius);
    color: var(--ds-ink); text-decoration: none; font-size: var(--ds-text-sm); line-height: 1.3;
    transition: background-color var(--ds-fast);
}
.ds-sidebar-link .ds-icona { opacity: 0.7; }
.ds-sidebar-link:hover { background: var(--ds-200); }
.ds-sidebar-link.is-current { background: var(--ds-200); font-weight: 500; }
.ds-sidebar-link.is-current .ds-icona { color: var(--ds-accent); opacity: 1; }
.ds-sidebar-group { margin-top: 10px; }
.ds-sidebar-group > summary {
    list-style: none; display: flex; align-items: center; justify-content: space-between; padding: 6px 10px; cursor: pointer;
    font-family: var(--ds-font-mono); font-size: var(--ds-text-badge); font-weight: 300; letter-spacing: 0.6px;
    text-transform: uppercase; opacity: 0.7;
}
.ds-sidebar-group > summary::-webkit-details-marker { display: none; }
.ds-sidebar-group > summary .ds-icona { width: 14px; height: 14px; transition: transform var(--ds-fast); }
.ds-sidebar-group[open] > summary .ds-icona { transform: rotate(180deg); }
.ds-sidebar-foot { border-top: var(--ds-line); padding: 8px; }
.ds-sidebar-velo { display: none; }
@media (max-width: 991px) {
    .ds.pannello { --ds-nav-h: 56px; }
    .ds-shell { grid-template-columns: minmax(0, 1fr); }
    .ds-sidebar {
        position: fixed; left: 0; top: 0; z-index: 70; width: min(280px, 85vw);
        transform: translateX(-100%); transition: transform var(--ds-slow); box-shadow: var(--ds-shadow-lift);
    }
    .ds-sidebar.is-open { transform: none; }
    .ds-sidebar-velo { display: block; position: fixed; inset: 0; z-index: 69; background: var(--ds-ink); opacity: 0.3; }
    .ds-shell-top {
        display: flex; align-items: center; gap: 12px; height: var(--ds-nav-h); padding: 0 8px;
        position: sticky; top: 0; z-index: 50; background: var(--ds-white); border-bottom: var(--ds-line);
    }
}

/* Tessere di azione rapida e riquadri numero (KPI). `auto-fit` e non
   `auto-fill`: le tessere si allargano a riempire la riga invece di lasciare un
   vuoto a destra (Marco: «gli elementi non hanno un layout»). */
.ds-azioni { display: grid; gap: var(--ds-grid-gap); grid-template-columns: minmax(0, 1fr); }
/* Le colonne le decide la larghezza del RIQUADRO, non dello schermo: una, poi
   2×2, poi 4 in riga — mai 3+1, e mai un'etichetta spezzata parola per parola. */
.ds-azioni-box { container-type: inline-size; }
@container (min-width: 420px) { .ds-azioni { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@container (min-width: 860px) { .ds-azioni { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.ds-azione {
    display: flex; align-items: center; gap: 0.75rem; width: 100%; height: 100%; padding: 0.75rem;
    border: var(--ds-line-strong); border-radius: var(--ds-radius); background: var(--ds-white); color: var(--ds-ink);
    font: inherit; font-size: var(--ds-text-sm); font-weight: 500; line-height: 1.3; text-align: left; text-decoration: none; cursor: pointer;
    transition: border-color var(--ds-fast), color var(--ds-fast);
}
/* Un pulsante, non un riquadro (Marco: «non si capisce che ci posso interagire»):
   fondo bianco col filo invece del grigio dei numeri, e una freccia in fondo —
   in su a destra se si apre in un'altra scheda (cPanel), a destra se resta qui. */
.ds-azione:hover { border-color: var(--ds-accent); color: var(--ds-accent); }
.ds-azione .ds-icon-box { background: var(--ds-200); border: 0; color: var(--ds-ink); }
.ds-azione-freccia { margin-left: auto; color: var(--ds-accent); transition: transform var(--ds-fast); }
.ds-azione:hover .ds-azione-freccia { transform: translateX(2px); }
.ds-azioni > form { display: flex; }       /* la tessera dentro un form prende tutta la cella */
.ds-kpi { display: grid; gap: var(--ds-grid-gap); grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.ds-kpi > div { display: flex; flex-direction: column; gap: 0.5rem; min-width: 0; padding: 0.75rem 1rem; border-radius: var(--ds-radius); background: var(--ds-200); }
.ds-kpi .ds-meter { background: var(--ds-white); }   /* sul fondo della tessera la barra vuota spariva */
@media (max-width: 767px) {
    .ds-kpi { grid-template-columns: minmax(0, 1fr); }
}

/* ═════════════════════════════════════════════════════════════
 * Scheda di un oggetto (DERIVATI, Marco 2026-10-22): cliente, spazio…
 * Testata con le azioni, banner «Da fare», tab e sezioni in un'unica
 * card («cartella»). brain/output/redesign-layout-pannelli-2026-10-22.md
 * ═════════════════════════════════════════════════════════════ */
/* Azioni della testata: sul telefono sempre in una riga, il `⋯` a filo destro, così la
   sua tendina (allineata a destra) resta nello schermo. */
@media (max-width: 767px) {
    .ds-testata-azioni { flex-wrap: nowrap; }
    .ds-testata-azioni > .ds-btn, .ds-testata-azioni > :not(:last-child) { flex: 1 1 auto; min-width: 0; }
    .ds-testata-azioni > :not(:last-child) > .ds-btn { width: 100%; }
    .ds-testata-azioni .ds-btn:not(.icon) { padding-left: 11px; padding-right: 11px; }
}
@media (max-width: 479px) { .ds-btn.esce > .ds-icona:first-child { display: none; } }

/* «Da fare»: banner richiudibile, chiuso all'apertura. Gialla solo la riga in alto
   (icona, numero, freccia); l'elenco su bianco, una riga per voce col suo bottone.
   `<details class="ds-dafare">` > `<summary>` + `.ds-dafare-elenco` > `.ds-dafare-riga`. */
.ds-dafare {
    border: 1px solid color-mix(in srgb, var(--ds-warn-ink) 25%, transparent);
    border-radius: var(--ds-radius);
    background: var(--ds-white);
    overflow: hidden;
}
.ds-dafare > summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 46px;
    padding: 0.75rem 1rem;
    background: var(--ds-warn-bg);
    color: var(--ds-warn-ink);
    cursor: pointer;
    list-style: none;
}
.ds-dafare > summary::-webkit-details-marker { display: none; }
.ds-dafare > summary:hover { background: color-mix(in srgb, var(--ds-warn-ink) 8%, var(--ds-warn-bg)); }
.ds-dafare-freccia { margin-left: auto; transition: transform var(--ds-fast); }
.ds-dafare[open] .ds-dafare-freccia { transform: rotate(180deg); }
.ds-dafare[open] > summary { border-bottom: 1px solid color-mix(in srgb, var(--ds-warn-ink) 25%, transparent); }
.ds-dafare-elenco { padding: 0.25rem 1rem; }
.ds-dafare-riga { display: flex; align-items: center; gap: 0.25rem 0.75rem; padding: 0.375rem 0; border-bottom: var(--ds-line); }
.ds-dafare-riga:last-child { border-bottom: 0; }
.ds-dafare-riga > .ds-icona { flex: 0 0 auto; align-self: flex-start; margin-top: 3px; color: var(--ds-warn-ink); }
.ds-dafare-riga > p { flex: 1 1 auto; min-width: 0; }
.ds-dafare-riga > :last-child:not(p) { flex: 0 0 auto; }
@media (max-width: 767px) {
    .ds-dafare-dettaglio { display: block; }
    .ds-dafare-sep { display: none; }
}

/* Cartella: le tab sono la testa di un'unica card bianca, le sezioni stanno dentro senza
   card proprie e le dividono linee («sembravano staccate», Marco). Le card della vista
   restano `.ds-card`: qui perdono fondo e bordo. */
.ds-cartella { background: var(--ds-white); border: var(--ds-line); border-radius: var(--ds-radius); overflow: hidden; }
.ds-cartella > .ds-tabs-linea { border: 0; border-bottom: var(--ds-line); }
.ds.pannello .ds-cartella-corpo .ds-card { background: transparent; box-shadow: none; border-radius: 0; }
.ds-cartella-corpo .ds-dash-layout, .ds-cartella-corpo .ds-dash-main, .ds-cartella-corpo .ds-dash-side,
.ds-cartella-corpo .ds-sezioni { gap: 0; }
.ds-cartella-corpo .ds-sezioni { display: flex; flex-direction: column; }
.ds-cartella-corpo .ds-dash-main > * + *, .ds-cartella-corpo .ds-dash-side > * + *,
.ds-cartella-corpo .ds-sezioni > * + * { border-top: var(--ds-line); }
.ds-cartella-corpo .ds-dash-side { border-top: var(--ds-line); }
@media (min-width: 992px) {
    .ds-cartella-corpo .ds-dash-side { border-top: 0; border-left: var(--ds-line); align-self: stretch; }
}
/* Una griglia di card direttamente nella cartella: niente spazio fra le celle, ognuna
   disegna la linea a destra e sotto; quelle sul bordo le taglia l'`overflow` della cartella. */
.ds-cartella-corpo > .ds-grid { gap: 0; }
.ds.pannello .ds-cartella-corpo > .ds-grid > .ds-card { box-shadow: 1px 0 0 var(--ds-400), 0 1px 0 var(--ds-400); }

/* ═════════════════════════════════════════════════════════════
 * Archetipo «elenco» (Marco, 2026-10-22) — brain/output/redesign-layout-pannelli-2026-10-22.md
 * L'elenco sta in una `.ds-cartella`: in testa `.ds-cartella-barra` coi filtri, sotto
 * `.ds-cartella-tabella` con la tabella `.impila` e la paginazione.
 * ═════════════════════════════════════════════════════════════ */
.ds-cartella-barra { padding: 0.875rem 1.25rem; border-bottom: var(--ds-line); }
.ds-cartella-tabella { padding: 0 1.25rem 0.75rem; }
.ds-cartella-tabella .ds-table th:first-child, .ds-cartella-tabella .ds-table td:first-child { padding-left: 0; }
.ds-cartella-tabella .ds-table th:last-child, .ds-cartella-tabella .ds-table td:last-child { padding-right: 0; }
@media (max-width: 767px) {
    .ds-cartella-barra { padding: 0.75rem; }
    .ds-cartella-tabella { padding: 0 0.75rem 0.5rem; }
}

/* La riga dei filtri: ricerca, tendine `<x-ds.filtro>`, conteggio. Tutto alto 46px come un
   bottone, comodo col dito. Sul telefono la ricerca prende la riga e le tendine si dividono
   quella sotto; il conteggio sparisce. */
.ds-barra-filtri { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.ds-cerca { position: relative; flex: 1 1 16rem; min-width: 0; }
.ds-cerca > .ds-icona { position: absolute; left: 0.75rem; top: 50%; width: 16px; height: 16px; transform: translateY(-50%); opacity: 0.6; pointer-events: none; }
.ds-cerca > .ds-input { min-height: 46px; height: 46px; padding-top: 0; padding-bottom: 0; padding-left: 2.25rem; }
.ds-filtri { display: flex; gap: 0.5rem; }
.ds-conta { margin-left: auto; white-space: nowrap; }
@media (max-width: 767px) {
    .ds-filtri { flex: 1 1 100%; }
    .ds-filtri > * { flex: 1 1 0; min-width: 0; }
    .ds-conta { display: none; }
}

/* `<x-ds.filtro>`: «Tipo: Tutti ▾», un bottone che apre il menu con la spunta sulla scelta.
   Acceso (filo e valore verdi) quando il filtro non è sul «tutti». */
.ds-btn.ds-filtro { font-weight: 400; gap: 0.5rem; }
.ds-filtro-nome { opacity: 0.6; }
.ds-filtro-valore { font-weight: 500; }
.ds-btn.ds-filtro.is-attivo { border-color: var(--ds-accent); }
.ds-filtro.is-attivo .ds-filtro-valore { color: var(--ds-accent); }
.ds-menu-spunta { margin-left: auto; }
/* Il menu sotto il bottone, sopra ciò che segue (come `.ds-scelta-pannello`, sotto i modali);
   `.a-destra` per l'ultimo filtro della riga, perché sul telefono non esca dallo schermo. */
.ds-filtro-menu { position: absolute; top: 100%; left: 0; z-index: 40; margin-top: 0.5rem; }
.ds-filtro-menu.a-destra { left: auto; right: 0; }
@media (max-width: 767px) {
    .ds-btn.ds-filtro { width: 100%; justify-content: flex-start; padding-left: 0.75rem; padding-right: 0.75rem; }
    .ds-btn.ds-filtro > .ds-icona { margin-left: auto; }
    .ds-filtro-valore { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* La riga che si apre sul posto: un `<tbody>` per riga, la seconda `tr.ds-riga-dettaglio`
   compare al clic. La freccia punta in basso da chiusa, in alto da aperta (Marco). */
.ds-riga-apribile { cursor: pointer; }
.ds-freccia { transition: transform var(--ds-fast); }
[aria-expanded="true"] > .ds-freccia { transform: rotate(180deg); }
.ds-table tr.ds-riga-dettaglio > td { background: var(--ds-100); padding: 1rem 1.25rem; }
.ds-dettaglio-griglia { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1rem; align-items: start; }
.ds-dettaglio-azioni { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.ds-elenco-servizi { display: flex; flex-direction: column; gap: 0.375rem; }
.ds-elenco-servizi > li { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.5rem; }
.ds-elenco-servizi .ds-icona { width: 16px; height: 16px; opacity: 0.7; flex: 0 0 auto; }
@media (max-width: 767px) {
    .ds-dettaglio-griglia { grid-template-columns: minmax(0, 1fr); }
    .ds-table.impila tr.ds-riga-dettaglio { padding: 0.75rem; background: var(--ds-100); }
    .ds-table.impila tr.ds-riga-dettaglio > td { flex-basis: 100%; padding: 0; background: none; }
}

/* I servizi in breve: icona e numero (dominio, hosting, spazio). Il nome per intero sta nel
   `title` e per i lettori di schermo. */
.ds-servizi { display: inline-flex; flex-wrap: wrap; gap: 0.25rem 0.75rem; }
.ds-servizi > span { display: inline-flex; align-items: center; gap: 0.25rem; white-space: nowrap; }
.ds-servizi .ds-icona { width: 15px; height: 15px; opacity: 0.7; }

/* Una riga di testo che non va a capo: finisce coi puntini (le email lunghe). */
.ds-taglia { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* `.ds-table.impila.compatta`: sul telefono niente etichette, le celle in fila su una riga
   sotto il titolo (~100px per riga invece di ~165). Il `data-label` resta per i lettori. */
@media (max-width: 767px) {
    .ds-table.impila.compatta td[data-label]::before { display: none; }
    .ds-table.impila.compatta tr { row-gap: 0.125rem; }
    .ds-table.impila.compatta td[data-label] { font-size: var(--ds-text-sm); }
    .ds-table.impila.compatta td.ds-segue-punto::after { content: " ·"; }
    .ds-table.impila.compatta td.ds-a-destra { margin-left: auto; }
}

/* ═════════════════════════════════════════════════════════════
 * Utility
 * ═════════════════════════════════════════════════════════════ */
.ds-container-xl { max-width: var(--ds-width-xl); margin-inline: auto; width: 100%; }
.ds-container-lg { max-width: var(--ds-width-lg); margin-inline: auto; width: 100%; }
.ds-container-md { max-width: var(--ds-width-md); margin-inline: auto; width: 100%; }
.ds-container-sm { max-width: var(--ds-width-sm); margin-inline: auto; width: 100%; }

@media (prefers-reduced-motion: reduce) {
    .ds-btn, .ds-link-arrow, .ds-card, .ds-list-row, .ds-nav-link, .ds-tab { transition: none; }
    .ds-skeleton, .ds-arriva { animation: none; }
}

/* La tendina con la ricerca (`<x-ds.scelta>`, #285): il pannello si apre SOPRA
   ciò che viene dopo nella pagina. Senza z-index i bottoni e le card che seguono
   (posizionati) gli passavano sopra — visto da Nico in prova. Sotto il modale (55). */
.ds-scelta-pannello { position: absolute; left: 0; right: 0; top: 100%; z-index: 40; margin-top: 0.25rem; padding: 0.375rem; }
