/* =====================================================================
   CodeStack Payments — sistema di stile
   ---------------------------------------------------------------------
   Allineato a codestack.it: stesso marchio, stessa palette (blu #2563EB,
   viola #7C3AED), stesso carattere di testo (Inter), stessi angoli morbidi,
   tema chiaro e scuro. Chi arriva dal pulsante «Paga le tue fatture» non
   deve accorgersi di aver cambiato sito.

   Una cosa NON viene da lì ed è voluta: le cifre restano in IBM Plex Mono
   con tabular-nums. In Inter l'1 è più stretto dell'8, e le colonne di
   importi non si incolonnerebbero più. Qui si maneggiano soldi: gli importi,
   gli ID e i badge stanno in monospaziato, il resto in Inter.

   Il file è diviso in @layer: le utility vincono sempre sui componenti,
   i componenti sulle basi. Così non serve rincorrere le specificità.
   Ordine:  tokens → base → layout → components → utilities
   ===================================================================== */

@layer tokens, base, layout, components, utilities;

/* ---------------------------------------------------------------- font */

/* Inter è auto-ospitato, non preso dal CDN di Google: l'hotlink manderebbe
   l'IP di ogni visitatore ai server di Google, ed è esattamente il caso che
   in UE ha prodotto sanzioni. Per aggiungere un carattere: si mette il woff2
   in /assets/fonts/ e si dichiara qui. */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('/assets/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: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/assets/fonts/plexmono-400-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: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/assets/fonts/plexmono-600-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;
}

@layer tokens {
    :root {
        /* Colore — tema SCURO, che è quello predefinito -----------------
           codestack.it si apre scuro e qui si fa lo stesso: chi arriva dal
           pulsante «Paga le tue fatture» non deve vedere cambiare la luce.
           Lo scuro sta nei valori di partenza, non in una media query,
           così vale anche se il JavaScript non parte.
           I valori vengono dai token di codestack.it (client/src/index.css,
           espressi lì in oklch e qui convertiti in esadecimale). */
        --ink: #dadee5;
        --ink-soft: #babec4;
        --ink-faint: #7b8189;
        --paper: #04070f;
        --surface: #0a1018;
        --surface-2: #11161f;
        --rule: #1c222c;
        --rule-strong: #2b323d;

        /* --accent è l'azzurro usato come TESTO, bordo o icona, e cambia
           fra i due temi: il blu del marchio (#2563eb) su fondo quasi nero
           arriva a 3,7:1, sotto la soglia di 4,5:1 per il testo normale.
           Schiarito a #6692f1 sale a 6,3:1.
           --accent-fill è invece il riempimento dei pulsanti e resta il blu
           del marchio in entrambi i temi: è l'elemento più riconoscibile e
           deve essere identico a quello di codestack.it (bianco su blu =
           5,17:1, che va bene). */
        --accent: #6692f1;
        --accent-hi: #93b4f6;
        --accent-soft: #101c33;
        --accent-fill: #2563eb;
        --accent-fill-hi: #1d4ed8;
        --on-accent: #ffffff;
        /* Il viola del marchio, secondo capo dello sfumato blu→viola del
           logo. Oggi nessuna regola lo usa: sta qui perché la coppia di
           colori del marchio va documentata in un posto solo, e chi domani
           disegnasse uno sfumato deve trovarlo già pronto e giusto. */
        --viola: #7c3aed;

        --danger: #ff6467;
        --danger-soft: #2d1416;
        --warn: #f0b429;
        --warn-soft: #2c2110;

        color-scheme: dark;

        /* Tipografia -------------------------------------------------- */
        /* Inter per tutto il testo, come su codestack.it. Il monospaziato
           resta per cifre, ID, etichette e badge: vedi l'intestazione. */
        --font-display: 'Inter', system-ui, -apple-system, sans-serif;
        --font-body: 'Inter', system-ui, -apple-system, sans-serif;
        --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

        --t-2xs: 0.6875rem;
        --t-xs: 0.75rem;
        --t-sm: 0.8125rem;
        --t-base: 0.9375rem;
        --t-md: 1rem;
        --t-lg: 1.125rem;
        --t-xl: 1.5rem;
        --t-2xl: 2rem;

        /* Spazio ------------------------------------------------------ */
        --s-1: 0.25rem;
        --s-2: 0.5rem;
        --s-3: 0.75rem;
        --s-4: 1rem;
        --s-5: 1.5rem;
        --s-6: 2rem;
        --s-7: 3rem;

        /* Forma ------------------------------------------------------- */
        /* Raggi di codestack.it: --radius vale lì 0.75rem = 12px, con i
           gradini a 8, 10 e 16. Il vecchio sistema si fermava a 8. */
        --r-sm: 8px;
        --r: 10px;
        --r-lg: 12px;
        --r-xl: 16px;
        --shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
        --shadow-lift: 0 4px 16px -6px rgba(0, 0, 0, 0.7);

        /* Larghezze --------------------------------------------------- */
        --w-form: 25rem;
        --w-panel: 34rem;
        --w-wide: 72rem;
    }

    /* Tema chiaro ----------------------------------------------------- */
    /* La variante, applicata solo se l'utente la sceglie: l'interruttore in
       testata scrive data-theme="light" su <html> e lo ricorda nel browser.
       Non si ridefiniscono --accent-fill, --accent-fill-hi e --on-accent:
       il blu dei pulsanti è il marchio e resta identico nei due temi. */
    :root[data-theme='light'] {
        --ink: #060a12;
        --ink-soft: #3a4049;
        --ink-faint: #5e646c;
        --paper: #f9fafb;
        --surface: #ffffff;
        --surface-2: #f0f2f5;
        --rule: #e3e5e8;
        --rule-strong: #cdd1d6;

        --accent: #2563eb;
        --accent-hi: #1d4ed8;
        --accent-soft: #eef3fd;

        --danger: #c60009;
        --danger-soft: #feecec;
        --warn: #96590a;
        --warn-soft: #fdf1dd;

        --shadow: 0 1px 2px rgba(6, 10, 18, 0.06);
        --shadow-lift: 0 4px 16px -6px rgba(6, 10, 18, 0.2);

        color-scheme: light;
    }
}

@layer base {
    *,
    *::before,
    *::after {
        box-sizing: border-box;
    }

    html {
        -webkit-text-size-adjust: 100%;
    }

    body {
        margin: 0;
        min-height: 100vh;
        display: flex;
        flex-direction: column;
        font-family: var(--font-body);
        font-size: var(--t-base);
        line-height: 1.55;
        color: var(--ink);
        background: var(--paper);
        -webkit-font-smoothing: antialiased;
    }

    h1,
    h2,
    h3 {
        font-family: var(--font-display);
        font-weight: 700;
        line-height: 1.15;
        letter-spacing: -0.015em;
        margin: 0;
        text-wrap: balance;
    }

    /* Inter non ha l'asse della larghezza che aveva Archivo: i titoli si
       distinguono per corpo e peso, non per allargamento. */
    h1 {
        font-size: var(--t-xl);
        letter-spacing: -0.025em;
    }

    h2 {
        font-size: var(--t-lg);
        letter-spacing: -0.02em;
    }

    p {
        margin: 0;
    }

    a {
        color: var(--accent);
        text-underline-offset: 2px;
    }

    a:hover {
        color: var(--accent-hi);
    }

    /* Le cifre si incolonnano ovunque: importi, date, contatori. */
    table,
    input,
    select {
        font-variant-numeric: tabular-nums;
    }

    :focus-visible {
        outline: 2px solid var(--accent);
        outline-offset: 2px;
        border-radius: var(--r-sm);
    }

    ::selection {
        background: var(--accent-soft);
    }

    @media (prefers-reduced-motion: reduce) {
        *,
        *::before,
        *::after {
            animation-duration: 0.01ms !important;
            transition-duration: 0.01ms !important;
        }
    }
}

@layer layout {
    /* Barra superiore ------------------------------------------------ */
    .topbar {
        background: var(--surface);
        border-bottom: 1px solid var(--rule);
        position: sticky;
        top: 0;
        z-index: 10;
    }

    .topbar__inner {
        max-width: var(--w-wide);
        margin-inline: auto;
        padding: var(--s-3) var(--s-5);
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--s-4);
    }

    /* Marchio: gli stessi due rombi e lo stesso testo di codestack.it —
       Inter grassetto con crenatura stretta, non maiuscoletto spaziato come
       nel vecchio sistema. Deve leggersi come lo stesso logo, perché è lo
       stesso logo. */
    .wordmark {
        display: inline-flex;
        align-items: center;
        gap: var(--s-2);
        font-family: var(--font-display);
        font-size: var(--t-lg);
        font-weight: 700;
        letter-spacing: -0.02em;
        color: var(--ink);
        text-decoration: none;
    }

    .wordmark__mark {
        width: 1.75rem;
        height: 1.75rem;
        flex: none;
    }

    .wordmark__sub {
        color: var(--ink-faint);
        font-size: var(--t-sm);
        font-weight: 500;
        letter-spacing: 0;
    }

    .nav {
        display: flex;
        align-items: center;
        gap: var(--s-4);
        font-size: var(--t-sm);
    }

    .nav__link {
        color: var(--ink-soft);
        text-decoration: none;
        padding-block: var(--s-1);
        border-bottom: 2px solid transparent;
        white-space: nowrap;
    }

    .nav__link:hover {
        color: var(--ink);
    }

    .nav__link[aria-current='page'] {
        color: var(--ink);
        border-bottom-color: var(--accent);
    }

    .nav__form {
        display: inline-flex;
        margin: 0;
    }

    /* Interruttore chiaro/scuro. È un <button> stampato dal server con
       l'icona di partenza già giusta; il JavaScript scambia icona ed
       etichetta. Senza JavaScript resta nascosto: un interruttore che non
       interruttore niente è peggio di un interruttore che non c'è. */
    .theme-toggle {
        display: none;
        align-items: center;
        justify-content: center;
        width: 2.1rem;
        height: 2.1rem;
        padding: 0;
        color: var(--ink-faint);
        background: transparent;
        border: 1px solid transparent;
        border-radius: var(--r-sm);
        cursor: pointer;
    }

    .js .theme-toggle {
        display: inline-flex;
    }

    .theme-toggle:hover {
        color: var(--ink);
        background: var(--surface-2);
        border-color: var(--rule);
    }

    .theme-toggle svg {
        width: 1.05rem;
        height: 1.05rem;
        fill: none;
        stroke: currentColor;
        stroke-width: 1.6;
        stroke-linecap: round;
        stroke-linejoin: round;
    }

    /* Si mostra un'icona sola: quella che dice dove si va a finire.
       Al buio (predefinito) si vede il sole, perché il clic porta al chiaro. */
    .theme-toggle__luna {
        display: none;
    }

    :root[data-theme='light'] .theme-toggle__sole {
        display: none;
    }

    :root[data-theme='light'] .theme-toggle__luna {
        display: block;
    }

    /* Corpo ----------------------------------------------------------- */
    .main {
        flex: 1 0 auto;
        width: 100%;
        max-width: var(--w-wide);
        margin-inline: auto;
        padding: var(--s-6) var(--s-5) var(--s-7);
    }

    .wrap--form {
        max-width: var(--w-form);
        margin-inline: auto;
    }

    .wrap--panel {
        max-width: var(--w-panel);
        margin-inline: auto;
    }

    .page-head {
        display: flex;
        align-items: flex-end;
        justify-content: space-between;
        gap: var(--s-4);
        flex-wrap: wrap;
        margin-bottom: var(--s-5);
    }

    .stack > * + * {
        margin-top: var(--s-4);
    }

    /* csrf_field() apre ogni form con un input nascosto: senza questa riga
       il primo campo visibile eredita un margine che non gli spetta. */
    .stack > input[type='hidden'] + * {
        margin-top: 0;
    }

    .stack--tight > * + * {
        margin-top: var(--s-3);
    }

    .stack--loose > * + * {
        margin-top: var(--s-6);
    }

    /* Piè di pagina --------------------------------------------------- */
    .footer {
        flex: none;
        border-top: 1px solid var(--rule);
        background: var(--surface);
    }

    /* Quattro colonne che collassano da sole: auto-fit su una larghezza
       minima, così su telefono diventano una colonna sola senza una media
       query dedicata. */
    .footer__inner {
        max-width: var(--w-wide);
        margin-inline: auto;
        /* Lo spazio in basso è generoso di proposito: il pulsante WhatsApp è
           fisso nell'angolo e senza questo margine coprirebbe l'ultima riga
           del piè di pagina. */
        padding: var(--s-6) var(--s-5) var(--s-7);
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
        gap: var(--s-5);
        font-size: var(--t-xs);
        color: var(--ink-faint);
    }

    .footer__col p {
        margin: 0 0 var(--s-1);
    }

    .footer__col a {
        color: var(--ink-soft);
    }

    .footer__col a:hover {
        color: var(--accent);
    }

    .footer__nome {
        font-weight: 700;
        color: var(--ink);
    }

    /* Selettori discendenti e non !important: `.footer__col p` ha
       specificità 0-1-1 e batterebbe una classe sola. */
    .footer__col .footer__titolo {
        font-family: var(--font-mono);
        font-size: var(--t-2xs);
        font-weight: 600;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--ink-faint);
        margin-bottom: var(--s-2);
    }

    .footer__col .footer__nota {
        margin-top: var(--s-2);
        line-height: 1.5;
    }
}

@layer components {
    /* Etichetta di sezione ------------------------------------------- */
    .eyebrow {
        font-family: var(--font-mono);
        font-size: var(--t-2xs);
        font-weight: 600;
        letter-spacing: 0.12em;
        text-transform: uppercase;
        color: var(--ink-faint);
        margin: 0 0 var(--s-1);
    }

    .lede {
        color: var(--ink-soft);
        font-size: var(--t-base);
    }

    /* Sezioni dell'area amministrativa -------------------------------- */
    .tabs {
        display: flex;
        gap: var(--s-5);
        margin-bottom: var(--s-5);
        border-bottom: 1px solid var(--rule);

        /* Scorrimento orizzontale per gli schermi stretti, dove le sezioni
           non ci stanno in fila. Effetto collaterale delle regole CSS: se
           overflow-x non è `visible`, overflow-y diventa `auto` da solo — e
           siccome i link sbordano di 1px sotto (il `margin-bottom: -1px` che
           fa scavalcare al sottolineato la riga della barra), comparivano
           anche le frecce di scorrimento verticale per quel singolo pixel.
           Qui le barre si nascondono senza togliere lo scorrimento: sbarrare
           overflow-y taglierebbe quel pixel e assottiglierebbe il
           sottolineato della sezione attiva. */
        overflow-x: auto;
        scrollbar-width: none;
    }

    .tabs::-webkit-scrollbar {
        display: none;
    }

    .tabs__link {
        padding: var(--s-2) 0 var(--s-3);
        margin-bottom: -1px;
        font-size: var(--t-sm);
        color: var(--ink-soft);
        text-decoration: none;
        white-space: nowrap;
        border-bottom: 2px solid transparent;
    }

    .tabs__link:hover {
        color: var(--ink);
    }

    .tabs__link[aria-current='page'] {
        color: var(--ink);
        font-weight: 600;
        border-bottom-color: var(--accent);
    }

    /* Secondo livello (dentro Impostazioni): pillole, per non confondersi
       con la barra delle sezioni principali che gli sta sopra. */
    .tabs--sub {
        border-bottom: none;
        gap: var(--s-2);
        margin-bottom: var(--s-5);
    }

    .tabs--sub .tabs__link {
        padding: 0.3rem 0.8rem;
        margin-bottom: 0;
        border: 1px solid var(--rule);
        border-radius: 999px;
        background: var(--surface);
    }

    .tabs--sub .tabs__link:hover {
        border-color: var(--rule-strong);
    }

    .tabs--sub .tabs__link[aria-current='page'] {
        background: var(--accent-soft);
        border-color: color-mix(in srgb, var(--accent) 30%, transparent);
        color: var(--accent-hi);
    }

    /* Chat rilevate: una riga per chat, con il pulsante che la sceglie.
       L'ID resta visibile e selezionabile, ma non serve copiarlo a mano. */
    .found {
        padding: var(--s-4);
        border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
        border-radius: var(--r-lg);
        background: var(--accent-soft);
    }

    .found__row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--s-3);
        flex-wrap: wrap;
        padding-top: var(--s-3);
        margin-top: var(--s-3);
        border-top: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
    }

    .found__row code {
        user-select: all;
    }

    /* Istruzioni numerate: la sequenza conta davvero, sono passi da seguire. */
    .passi {
        margin: 0;
        padding-left: 1.2rem;
        display: grid;
        gap: var(--s-2);
        color: var(--ink-soft);
    }

    .passi li::marker {
        font-family: var(--font-mono);
        font-size: var(--t-sm);
        color: var(--ink-faint);
    }

    /* Pannello -------------------------------------------------------- */
    .panel {
        background: var(--surface);
        border: 1px solid var(--rule);
        border-radius: var(--r-lg);
        box-shadow: var(--shadow);
    }

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

    .panel__head {
        padding: var(--s-5) var(--s-5) var(--s-4);
        border-bottom: 1px solid var(--rule);
    }

    .panel__body {
        padding: var(--s-5);
    }

    .panel__foot {
        padding: var(--s-4) var(--s-5);
        border-top: 1px solid var(--rule);
        background: var(--surface-2);
        border-radius: 0 0 var(--r-lg) var(--r-lg);
        font-size: var(--t-sm);
        color: var(--ink-soft);
    }

    /* Campi ----------------------------------------------------------- */
    .field + .field {
        margin-top: var(--s-4);
    }

    /* Campo password con l'occhio per sbirciare quello che si è scritto.
       Il pulsante sta dentro al campo, quindi l'input gli lascia spazio a
       destra: senza quel padding il testo digitato ci finirebbe sotto. */
    .field__occhieggia {
        position: relative;
    }

    .field__occhieggia .input {
        padding-right: 2.5rem;
    }

    /* Selettore composto, non `.field__occhio` da solo: le regole di `.btn`
       stanno più in basso nel file e a parità di specificità vincerebbero
       loro, rimettendo bordo e sfondo. L'occhio tornerebbe a sembrare un
       pulsante appiccicato al campo invece di un'icona dentro al campo. */
    .field__occhieggia .field__occhio,
    .field__occhieggia .field__occhio:hover {
        position: absolute;
        top: 50%;
        right: 0.25rem;
        transform: translateY(-50%);
        border: 0;
        background: none;
        box-shadow: none;
    }

    /* La sbarra sull'occhio compare quando la password è in chiaro: lo stato
       lo dice già il pulsante con aria-pressed, non serve una classe a parte. */
    .field__occhio-sbarra {
        display: none;
    }

    .field__occhio[aria-pressed="true"] .field__occhio-sbarra {
        display: inline;
    }

    .field__label {
        display: block;
        font-size: var(--t-2xs);
        font-weight: 600;
        font-family: var(--font-mono);
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--ink-faint);
        margin-bottom: var(--s-2);
        padding: 0;
    }

    .field__hint {
        margin-top: var(--s-2);
        font-size: var(--t-xs);
        color: var(--ink-faint);
    }

    .input,
    .select {
        width: 100%;
        padding: 0.55rem 0.7rem;
        font: inherit;
        font-size: var(--t-base);
        color: var(--ink);
        background: var(--surface);
        border: 1px solid var(--rule-strong);
        border-radius: var(--r);
        transition: border-color 0.12s ease, box-shadow 0.12s ease;
    }

    .input::placeholder {
        color: var(--ink-faint);
    }

    .input:hover:not(:disabled),
    .select:hover:not(:disabled) {
        border-color: var(--ink-faint);
    }

    .input:focus,
    .select:focus {
        outline: none;
        border-color: var(--accent);
        box-shadow: 0 0 0 3px var(--accent-soft);
    }

    .input:disabled,
    .select:disabled {
        background: var(--surface-2);
        color: var(--ink-faint);
        cursor: not-allowed;
    }

    .select {
        appearance: none;
        padding-right: 2rem;
        background-image: linear-gradient(45deg, transparent 50%, var(--ink-faint) 50%),
            linear-gradient(135deg, var(--ink-faint) 50%, transparent 50%);
        background-position: calc(100% - 1rem) 55%, calc(100% - 0.7rem) 55%;
        background-size: 5px 5px, 5px 5px;
        background-repeat: no-repeat;
    }

    .input--mono {
        font-family: var(--font-mono);
    }

    /* Interruttore ---------------------------------------------------- */
    .switch {
        display: flex;
        align-items: center;
        gap: var(--s-3);
        cursor: pointer;
    }

    .switch__input {
        appearance: none;
        margin: 0;
        flex: none;
        width: 2.5rem;
        height: 1.4rem;
        border-radius: 999px;
        background: var(--rule-strong);
        border: none;
        position: relative;
        cursor: pointer;
        transition: background 0.15s ease;
    }

    .switch__input::after {
        content: '';
        position: absolute;
        top: 3px;
        left: 3px;
        width: 1rem;
        height: 1rem;
        border-radius: 50%;
        background: var(--surface);
        box-shadow: var(--shadow);
        transition: transform 0.15s ease;
    }

    .switch__input:checked {
        background: var(--accent-fill);
    }

    .switch__input:checked::after {
        transform: translateX(1.1rem);
    }

    .switch__text {
        font-weight: 600;
    }

    /* Campo con unità di misura appiccicata (percentuali) -------------- */
    .input-suffix {
        display: flex;
        align-items: stretch;
    }

    .input-suffix .input {
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
        min-width: 0;
    }

    .input-suffix__unit {
        display: flex;
        align-items: center;
        padding: 0 var(--s-3);
        border: 1px solid var(--rule-strong);
        border-left: none;
        border-radius: 0 var(--r-sm) var(--r-sm) 0;
        background: var(--surface-2);
        font-family: var(--font-mono);
        font-size: var(--t-sm);
        color: var(--ink-faint);
    }

    /* Totale da pagare, sopra il pulsante ------------------------------ */
    /* Etichetta sopra e cifra sotto, come .receipt: su due colonne
       l'occhio rimbalza da un bordo all'altro. */
    .totale {
        display: block;
        padding: var(--s-3) var(--s-4);
        border: 1px solid var(--rule);
        border-left: 4px solid var(--accent);
        border-radius: var(--r);
        background: var(--surface-2);
    }

    .totale__label {
        display: block;
        font-family: var(--font-mono);
        font-size: var(--t-2xs);
        font-weight: 600;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--ink-faint);
    }

    .totale__value {
        display: block;
        margin-top: var(--s-1);
        font-family: var(--font-mono);
        font-size: var(--t-xl);
        font-weight: 600;
        font-variant-numeric: tabular-nums;
        letter-spacing: -0.01em;
    }

    .totale__note {
        display: block;
        margin-top: var(--s-1);
        font-size: var(--t-xs);
        color: var(--ink-soft);
    }

    /* Tagli: la griglia delle denominazioni --------------------------- */
    .amounts {
        border: none;
        padding: 0;
        margin: 0;
    }

    .amounts__grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(3.6rem, 1fr));
        gap: var(--s-2);
    }

    .amount {
        position: relative;
        display: block;
    }

    .amount__input {
        position: absolute;
        opacity: 0;
        width: 100%;
        height: 100%;
        margin: 0;
        cursor: pointer;
    }

    .amount__face {
        display: flex;
        align-items: baseline;
        justify-content: center;
        gap: 0.1rem;
        padding: 0.5rem 0.2rem;
        border: 1px solid var(--rule);
        border-radius: var(--r);
        background: var(--surface);
        font-family: var(--font-mono);
        font-size: var(--t-md);
        color: var(--ink-soft);
        transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
    }

    .amount__cur {
        font-size: var(--t-xs);
        color: var(--ink-faint);
    }

    .amount__input:hover + .amount__face {
        border-color: var(--rule-strong);
        background: var(--surface-2);
    }

    .amount__input:checked + .amount__face {
        border-color: var(--accent);
        box-shadow: inset 0 0 0 1px var(--accent);
        background: var(--accent-soft);
        color: var(--accent-hi);
        font-weight: 600;
    }

    .amount__input:checked + .amount__face .amount__cur {
        color: var(--accent);
    }

    .amount__input:focus-visible + .amount__face {
        outline: 2px solid var(--accent);
        outline-offset: 2px;
    }

    /* Pulsanti -------------------------------------------------------- */
    .btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--s-2);
        padding: 0.55rem 1.1rem;
        font-family: var(--font-body);
        font-size: var(--t-base);
        font-weight: 600;
        line-height: 1.3;
        color: var(--ink);
        background: var(--surface);
        border: 1px solid var(--rule-strong);
        border-radius: var(--r);
        cursor: pointer;
        text-decoration: none;
        white-space: nowrap;
        transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
    }

    .btn:hover {
        background: var(--surface-2);
        border-color: var(--ink-faint);
        color: var(--ink);
    }

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

    .btn:disabled {
        opacity: 0.5;
        cursor: not-allowed;
        transform: none;
    }

    /* Il pulsante primario usa --accent-fill, che è il blu del marchio in
       entrambi i temi: è l'elemento che si riconosce a colpo d'occhio e
       deve essere lo stesso di codestack.it. --accent, che si schiarisce al
       buio per restare leggibile come testo, qui non va bene. */
    .btn--primary {
        background: var(--accent-fill);
        border-color: var(--accent-fill);
        color: var(--on-accent);
    }

    .btn--primary:hover {
        background: var(--accent-fill-hi);
        border-color: var(--accent-fill-hi);
        color: var(--on-accent);
    }

    .btn--danger {
        color: var(--danger);
        border-color: color-mix(in srgb, var(--danger) 35%, var(--rule));
    }

    .btn--danger:hover {
        background: var(--danger-soft);
        border-color: var(--danger);
        color: var(--danger);
    }

    .btn--sm {
        padding: 0.3rem 0.7rem;
        font-size: var(--t-sm);
    }

    /* Pulsante di sola icona (l'occhio nella lista transazioni). L'etichetta
       per chi non vede l'icona sta in aria-label, non qui. */
    .btn--icon {
        padding: 0.3rem;
        width: 1.9rem;
        height: 1.9rem;
        color: var(--ink-soft);
    }

    .btn--icon svg {
        width: 1.05rem;
        height: 1.05rem;
        fill: none;
        stroke: currentColor;
        stroke-width: 1.6;
        stroke-linecap: round;
        stroke-linejoin: round;
    }

    .btn--icon:hover {
        color: var(--accent);
    }

    .btn--block {
        display: flex;
        width: 100%;
    }

    .btn--link {
        padding: var(--s-1) 0;
        background: none;
        border: none;
        border-bottom: 2px solid transparent;
        border-radius: 0;
        font-size: var(--t-sm);
        font-weight: 400;
        color: var(--ink-soft);
    }

    .btn--link:hover {
        background: none;
        border-color: transparent;
        color: var(--ink);
    }

    /* Avvisi ---------------------------------------------------------- */
    /* Deve restare un blocco. Con display:flex ogni <strong> o <span> nel
       testo diventerebbe un elemento flex e andrebbe a capo per conto suo:
       la barra colorata si fa con il bordo, non con un figlio in più. */
    .alert {
        padding: var(--s-3) var(--s-4);
        border: 1px solid;
        border-left-width: 4px;
        border-radius: var(--r);
        font-size: var(--t-base);
        background: var(--warn-soft);
        border-color: color-mix(in srgb, var(--warn) 30%, transparent);
        border-left-color: var(--warn);
        color: var(--warn);
    }

    .alert .mono {
        color: inherit;
    }

    /* Il flash sta sopra al contenuto della pagina, non incollato. */
    .alert--flash {
        margin-bottom: var(--s-5);
    }

    .alert--ok {
        background: var(--accent-soft);
        border-color: color-mix(in srgb, var(--accent) 30%, transparent);
        border-left-color: var(--accent);
        color: var(--accent-hi);
    }

    /* Avviso: né conferma né errore — serve alle pagine legali per il
       riquadro «riservato alle partite IVA», che è un'informazione da non
       mancare ma non è un problema. */
    .alert--warn {
        background: var(--warn-soft);
        border-color: color-mix(in srgb, var(--warn) 30%, transparent);
        border-left-color: var(--warn);
        color: var(--warn);
    }

    .alert--error {
        background: var(--danger-soft);
        border-color: color-mix(in srgb, var(--danger) 30%, transparent);
        border-left-color: var(--danger);
        color: var(--danger);
    }

    /* Esito del pagamento --------------------------------------------- */
    .outcome {
        display: flex;
        align-items: center;
        gap: var(--s-4);
    }

    .outcome__sign {
        flex: none;
        display: grid;
        place-items: center;
        width: 2.75rem;
        height: 2.75rem;
        border-radius: 50%;
        font-size: 1.35rem;
        line-height: 1;
        background: var(--accent-soft);
        color: var(--accent);
    }

    .outcome--ko .outcome__sign {
        background: var(--danger-soft);
        color: var(--danger);
    }

    /* Ricevuta: etichetta sopra, valore sotto, tutto allineato a sinistra.
       Con etichetta a sinistra e valore a destra le righe di lunghezza
       diversa facevano rimbalzare lo sguardo da un bordo all'altro. */
    .receipt {
        margin: 0;
        display: grid;
        grid-template-columns: 1fr;
    }

    .receipt dt {
        margin: 0;
        padding-top: var(--s-3);
        border-top: 1px solid var(--rule);
        font-family: var(--font-mono);
        font-size: var(--t-2xs);
        font-weight: 600;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--ink-faint);
    }

    .receipt dt:first-child {
        padding-top: 0;
        border-top: none;
    }

    .receipt dd {
        margin: 0.15rem 0 var(--s-3);
        font-weight: 600;
        overflow-wrap: anywhere;
    }

    .receipt dd:last-child {
        margin-bottom: 0;
    }

    .receipt__total {
        font-family: var(--font-mono);
        font-size: var(--t-xl);
        font-weight: 600;
        letter-spacing: -0.01em;
    }

    /* Tabelle: righe alternate come la carta a bande ------------------ */
    .table-scroll {
        overflow-x: auto;
        border: 1px solid var(--rule);
        border-radius: var(--r-lg);
        background: var(--surface);
        box-shadow: var(--shadow);
    }

    .table {
        width: 100%;
        border-collapse: collapse;
        font-size: var(--t-sm);
    }

    .table th,
    .table td {
        padding: 0.6rem 0.9rem;
        text-align: left;
        vertical-align: middle;
        white-space: nowrap;
    }

    .table thead th {
        font-family: var(--font-mono);
        font-size: var(--t-2xs);
        font-weight: 600;
        letter-spacing: 0.09em;
        text-transform: uppercase;
        color: var(--ink-faint);
        background: var(--surface);
        border-bottom: 1px solid var(--rule-strong);
    }

    .table tbody tr:nth-child(even) {
        background: var(--surface-2);
    }

    /* Tinta più tenue di .badge--ok, altrimenti le etichette di stato
       sparirebbero dentro la riga sotto al puntatore. */
    .table tbody tr:hover {
        background: color-mix(in srgb, var(--accent) 6%, var(--surface));
    }

    .table td.num {
        font-family: var(--font-mono);
        text-align: right;
    }

    .table th.num {
        text-align: right;
    }

    /* Il totale, in una riga di importi scomposti, è la cifra che si cerca. */
    .table td.num--forte {
        font-weight: 600;
    }

    /* Righe che aprono la scheda di dettaglio. La classe la mette il
       JavaScript: senza, la riga non deve sembrare cliccabile perché non lo è
       (resta l'occhio, che è un link vero). */
    .table--cliccabile tbody tr {
        cursor: pointer;
    }

    /* Etichette di stato ---------------------------------------------- */
    .badge {
        display: inline-block;
        padding: 0.1rem 0.5rem;
        border-radius: var(--r-sm);
        font-family: var(--font-mono);
        font-size: var(--t-2xs);
        font-weight: 600;
        letter-spacing: 0.03em;
        white-space: nowrap;
        background: var(--surface-2);
        border: 1px solid var(--rule);
        color: var(--ink-soft);
    }

    .badge--ok {
        background: var(--accent-soft);
        border-color: color-mix(in srgb, var(--accent) 25%, transparent);
        color: var(--accent-hi);
    }

    .badge--ko {
        background: var(--danger-soft);
        border-color: color-mix(in srgb, var(--danger) 25%, transparent);
        color: var(--danger);
    }

    .badge--info {
        background: var(--surface);
        border-color: var(--rule-strong);
        color: var(--ink);
    }

    .badge--warn {
        background: var(--warn-soft);
        border-color: color-mix(in srgb, var(--warn) 25%, transparent);
        color: var(--warn);
    }

    /* Elenco di credenziali: nome, valore mascherato, provenienza — ognuno
       sulla propria riga e tutti allineati a sinistra. Il formato a due
       colonne di .receipt qui faceva zigzagare lo sguardo. */
    .keylist {
        display: grid;
    }

    .keylist__item {
        display: grid;
        gap: 0.15rem;
        padding: var(--s-3) 0;
        border-top: 1px solid var(--rule);
    }

    .keylist__name {
        font-family: var(--font-mono);
        font-size: var(--t-2xs);
        font-weight: 600;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--ink-faint);
    }

    .keylist__value {
        display: flex;
        align-items: center;
        gap: var(--s-2);
        flex-wrap: wrap;
        font-family: var(--font-mono);
        font-size: var(--t-base);
        color: var(--ink);
    }

    .keylist__meta {
        font-size: var(--t-xs);
        color: var(--ink-faint);
    }

    .keyset__title {
        font-size: var(--t-base);
    }

    /* Editor richiudibile: <details> nativo, nessun JavaScript. */
    .editor {
        margin-top: var(--s-3);
    }

    .editor > summary {
        cursor: pointer;
        font-size: var(--t-sm);
        font-weight: 600;
        color: var(--accent);
        padding: var(--s-2) 0;
    }

    .editor > summary:hover {
        color: var(--accent-hi);
    }

    .editor[open] > summary {
        margin-bottom: var(--s-4);
    }

    /* Quando il richiudibile precede altro contenuto (l'elenco utenti sotto
       il modulo di creazione) serve stacco, altrimenti da aperto il pannello
       tocca la tabella. */
    .editor[open] {
        margin-bottom: var(--s-5);
    }

    /* Statistiche ------------------------------------------------------ */
    .stats {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
        gap: var(--s-3);
    }

    .stat {
        padding: var(--s-4);
        background: var(--surface);
        border: 1px solid var(--rule);
        border-radius: var(--r-lg);
        box-shadow: var(--shadow);
    }

    .stat__value {
        display: block;
        font-family: var(--font-mono);
        font-size: var(--t-2xl);
        font-weight: 600;
        line-height: 1.1;
        letter-spacing: -0.02em;
        color: var(--ink);
    }

    .stat__label {
        display: block;
        margin-top: var(--s-1);
        font-size: var(--t-xs);
        color: var(--ink-faint);
    }

    .stat--accent .stat__value {
        color: var(--accent);
    }

    /* Barra filtri ----------------------------------------------------- */
    .toolbar {
        display: flex;
        align-items: flex-end;
        gap: var(--s-3);
        flex-wrap: wrap;
        padding: var(--s-4);
        background: var(--surface);
        border: 1px solid var(--rule);
        border-radius: var(--r-lg);
        box-shadow: var(--shadow);
    }

    .toolbar__field {
        flex: 1 1 11rem;
        min-width: 0;
    }

    .toolbar__field .field__label {
        margin-bottom: var(--s-1);
    }

    /* Paginazione ------------------------------------------------------ */
    .pager {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--s-3);
        margin-top: var(--s-4);
        font-size: var(--t-sm);
        color: var(--ink-faint);
    }

    .pager__spacer {
        flex: 1;
    }

    /* Azioni in riga di tabella ---------------------------------------- */
    .row-actions {
        display: flex;
        align-items: center;
        gap: var(--s-2);
        flex-wrap: wrap;
    }

    .row-actions form {
        display: inline-flex;
        align-items: center;
        gap: var(--s-2);
        margin: 0;
    }

    .row-actions .select {
        width: auto;
        padding-block: 0.25rem;
        font-size: var(--t-sm);
    }

    /* Scheda di dettaglio ---------------------------------------------- */
    .modal {
        padding: 0;
        width: min(30rem, calc(100vw - 2 * var(--s-4)));
        max-height: calc(100vh - 2 * var(--s-5));
        overflow: auto;
        color: var(--ink);
        background: var(--surface);
        border: 1px solid var(--rule);
        border-radius: var(--r-lg);
        box-shadow: var(--shadow-lift);
    }

    .modal::backdrop {
        background: rgba(4, 7, 15, 0.6);
    }

    /* Aperta dal server, senza JavaScript, NON è una modale: dev'essere un
       pannello normale nel flusso della pagina e non il riquadro in posizione
       assoluta che il browser userebbe per un <dialog open>. */
    .modal:not(:modal) {
        position: static;
        width: auto;
        margin: var(--s-4) 0 0;
    }

    .modal__head {
        display: flex;
        align-items: flex-start;
        justify-content: space-between;
        gap: var(--s-4);
        margin: 0;
        padding: var(--s-4) var(--s-5);
        background: var(--surface-2);
        border-bottom: 1px solid var(--rule);
    }

    .modal__titolo {
        display: flex;
        align-items: center;
        gap: var(--s-2);
        margin: 0;
        font-size: var(--t-lg);
    }

    .modal__chiudi {
        flex: none;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 1.9rem;
        height: 1.9rem;
        font-size: var(--t-xl);
        line-height: 1;
        color: var(--ink-faint);
        background: transparent;
        border: 1px solid transparent;
        border-radius: var(--r-sm);
        cursor: pointer;
    }

    .modal__chiudi:hover {
        color: var(--ink);
        background: var(--surface);
        border-color: var(--rule-strong);
    }

    .modal__body {
        padding: var(--s-5);
    }

    .modal__foot {
        display: flex;
        justify-content: flex-end;
        padding: var(--s-3) var(--s-5);
        background: var(--surface-2);
        border-top: 1px solid var(--rule);
    }

    .modal__foot form {
        margin: 0;
    }

    /* Circuiti accettati ----------------------------------------------- */
    .carte {
        margin-bottom: var(--s-3);
    }

    .carte__titolo {
        margin: 0 0 var(--s-2);
        font-family: var(--font-mono);
        font-size: var(--t-2xs);
        font-weight: 600;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--ink-faint);
    }

    .carte__lista {
        display: flex;
        flex-wrap: wrap;
        gap: var(--s-2);
        margin: 0 0 var(--s-2);
        padding: 0;
        list-style: none;
    }

    .carta svg {
        display: block;
        width: 3rem;
        height: 1.875rem;
    }

    /* Il rettangolo della carta segue il tema: al buio un fondo bianco fisso
       sarebbe uno strappo, ma i colori dei circuiti restano quelli loro. */
    .carta__sfondo {
        fill: var(--surface);
        stroke: var(--rule-strong);
        stroke-width: 1;
    }

    .carta__testo {
        font-family: var(--font-display);
        font-size: 11px;
        font-weight: 800;
        letter-spacing: 0.04em;
        text-anchor: middle;
    }

    .carta__testo--sm {
        font-size: 9px;
    }

    .carte__nota {
        margin: 0;
        color: var(--ink-faint);
    }

    /* Contatto WhatsApp fluttuante ------------------------------------- */
    /* Verde del marchio WhatsApp, non un token: è un'icona riconoscibile e
       cambiarle colore la renderebbe irriconoscibile. */
    .whatsapp {
        position: fixed;
        right: var(--s-4);
        bottom: var(--s-4);
        z-index: 20;
        display: inline-flex;
        align-items: center;
        gap: var(--s-2);
        padding: 0.7rem 1rem;
        color: #fff;
        background: #25d366;
        border-radius: 999px;
        box-shadow: var(--shadow-lift);
        text-decoration: none;
        font-size: var(--t-sm);
        font-weight: 600;
        transition: transform 0.12s ease, box-shadow 0.12s ease;
    }

    .whatsapp:hover {
        color: #fff;
        transform: translateY(-1px);
    }

    .whatsapp:active {
        transform: translateY(0);
    }

    .whatsapp svg {
        width: 1.25rem;
        height: 1.25rem;
        flex: none;
        fill: currentColor;
    }

    /* Su schermo stretto resta il solo cerchio con l'icona: una pillola con
       la scritta coprirebbe metà del pulsante «Paga». */
    @media (max-width: 32rem) {
        .whatsapp {
            padding: 0.85rem;
        }

        .whatsapp__testo {
            position: absolute;
            width: 1px;
            height: 1px;
            padding: 0;
            margin: -1px;
            overflow: hidden;
            clip-path: inset(50%);
            white-space: nowrap;
        }
    }

    /* Pagine legali ---------------------------------------------------- */
    /* Testo lungo da leggere davvero: misura di riga più larga dei pannelli
       ma non tutta la pagina, e ritmo verticale marcato fra le sezioni, così
       si trova subito il paragrafo che serve. */
    .legal {
        max-width: 44rem;
        margin-inline: auto;
    }

    .legal h2 {
        margin-top: var(--s-6);
        margin-bottom: var(--s-3);
        padding-top: var(--s-4);
        border-top: 1px solid var(--rule);
    }

    .legal p,
    .legal ul {
        margin-bottom: var(--s-3);
        color: var(--ink-soft);
    }

    .legal ul {
        padding-left: var(--s-5);
    }

    .legal li {
        margin-bottom: var(--s-2);
    }

    .legal li::marker {
        color: var(--ink-faint);
    }

    .legal strong {
        color: var(--ink);
    }

    .legal .alert {
        margin-block: var(--s-4);
    }

    .legal .table-scroll {
        margin-block: var(--s-4);
    }

    /* Scheda utente ----------------------------------------------------- */
    /* Blocco in coda alla scheda, staccato dal modulo che lo precede: la
       disattivazione e la nota sul proprio account non fanno parte del
       «Salva», e devono vedersi come cose separate. */
    .modal__nota {
        display: flex;
        align-items: center;
        gap: var(--s-3);
        flex-wrap: wrap;
        margin-top: var(--s-4);
        padding-top: var(--s-4);
        border-top: 1px solid var(--rule);
    }

    /* La colonna dei comandi non deve allargarsi: tutto lo spazio in più va
       ai dati, che sono la ragione per cui si guarda la tabella. */
    .table__azioni {
        width: 1%;
        white-space: nowrap;
        text-align: right;
    }

    /* Campo modificabile dentro una cella di tabella -------------------- */
    .inline-edit {
        display: flex;
        align-items: center;
        gap: var(--s-2);
        margin: 0;
    }

    .input--sm {
        width: 11rem;
        padding: 0.25rem 0.5rem;
        font-size: var(--t-sm);
    }

    /* Sola lettura: si deve capire a colpo d'occhio che non si tocca, senza
       sembrare disabilitato (il valore va comunque letto e inviato). */
    .input[readonly] {
        background: var(--surface-2);
        color: var(--ink-soft);
        cursor: default;
    }

    .input[readonly]:focus {
        border-color: var(--rule-strong);
        box-shadow: none;
    }

    /* Stato vuoto ------------------------------------------------------ */
    .empty {
        padding: var(--s-6) var(--s-5);
        text-align: center;
        background: var(--surface);
        border: 1px dashed var(--rule-strong);
        border-radius: var(--r-lg);
        color: var(--ink-faint);
    }
}

@layer utilities {
    .mono {
        font-family: var(--font-mono);
        font-size: 0.95em;
    }

    .muted {
        color: var(--ink-faint);
    }

    .small {
        font-size: var(--t-sm);
    }

    .nowrap {
        white-space: nowrap;
    }

    .sr-only {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
    }
}

/* ------------------------------------------------------------ mobile */

@media (max-width: 640px) {
    @layer layout {
        .topbar__inner {
            padding-inline: var(--s-4);
            flex-wrap: wrap;
            gap: var(--s-2);
        }

        .main {
            padding: var(--s-5) var(--s-4) var(--s-6);
        }

        .footer__inner {
            padding-inline: var(--s-4);
        }

        .nav {
            gap: var(--s-3);
        }
    }

    @layer components {
        .panel__head,
        .panel__body {
            padding: var(--s-4);
        }

    }
}
