/*
 * Pannello di gestione Apptec.
 *
 * Sobrio di proposito: lo usano due o tre redattori, tutti i giorni, per
 * caricare documenti. Quello che conta è leggere l'elenco senza fatica e
 * capire a colpo d'occhio che cosa è pubblicato e che cosa no.
 *
 * LE FORME SONO QUELLE DI `info.cucineturi.com`, come per la vista pubblica:
 * stesso fondo velato, stessi angoli larghi, stesse pastiglie, stesse
 * micro-transizioni. Chi passa dal pannello al sito e viceversa resta nella
 * stessa casa.
 *
 * MA I COLORI QUI SONO FISSI, e non è una dimenticanza: il pannello serve
 * TUTTI i marchi insieme — Turi, EVO, e quelli che verranno — e vestirlo di
 * uno di essi direbbe una cosa falsa a chi ci lavora. Navy e oro sono del
 * Gruppo, non di un marchio. Nelle viste, invece, gli stessi ruoli li riempie
 * il marchio: là il colore arriva dal database.
 *
 * Nessun carattere tipografico esterno: sull'hosting condiviso una richiesta
 * in più costa più di quanto renda, e i caratteri di sistema si vedono subito.
 */

:root {
    --inchiostro:      #0f172a;
    /* Fisso e non derivato: alla stessa opacità del navy scendeva a 3,7:1.
       E MISURATO SUL VELO, non sul bianco: conteggi, note d'aiuto e piede
       stanno FUORI dalle card, sul fondo velato, dove #5b6b76 scendeva a
       4,07:1 — di nuovo sotto la soglia, per aver misurato sullo sfondo
       sbagliato. Questo dà 5,38:1 sul velo e 7,29:1 sul bianco, ed è lo stesso
       valore della vista pubblica: un colore in meno da tenere allineato. */
    --inchiostro-lieve: #4a5866;

    /* L'oro pieno come TESTO su bianco vale 2,74:1: va bene come pieno dietro
       un testo scuro, non per scriverci sopra. Questo è l'oro scurito fino a
       4,90:1, e serve dove l'oro deve essere leggibile o fare da confine
       (WCAG 1.4.11 chiede 3:1 per un indicatore non testuale). */
    --oro-testo: #8a6d1f;
    --carta:           #f4f6f7;
    --superficie:      #ffffff;

    /* Il bordo è il navy diluito, non un grigio neutro: tiene insieme la
       pagina anche dove non c'è colore.
       DUE BORDI, E LA DIFFERENZA NON È ESTETICA. Questo, a 1,26:1 sul bianco,
       è un separatore: divide due zone che si vedono già da sole, e più
       marcato farebbe da griglia a una pagina che griglia non è. */
    --bordo:           rgb(40 72 88 / .14);

    /* Questo è il confine di ciò che si TOCCA — campi, tendine, aree di testo,
       caselle. WCAG 1.4.11 chiede 3:1 per un elemento di interfaccia il cui
       confine è l'unica cosa che lo delimita, ed è esattamente questo il caso:
       un campo di testo vuoto è bianco su bianco, e il bordo è tutto ciò che
       dice dove comincia. A .14 valeva 1,26:1, cioè un fattore 2,4 sotto la
       soglia — ed è il motivo per cui i moduli sembravano fogli bianchi.
       Misurato appiattendo su #ffffff: (126,145,155) → 3,23:1. */
    --bordo-campo:     rgb(40 72 88 / .60);
    --bordo-acceso:    rgb(184 152 88 / .55);

    --primario:        #284858;
    --primario-scuro:  #1b333f;
    --rgb-primario:    40 72 88;
    --oro:             #b89858;
    --rgb-oro:         184 152 88;
    --su-oro:          #1d3744;

    --buono:           #2f6b46;
    --buono-carta:     #e8f3ec;
    --attento:         #8a5b12;
    --attento-carta:   #fdf3e2;
    --grave:           #9b2c2c;
    --grave-carta:     #fbeaea;

    --raggio:          14px;
    --raggio-piccolo:  10px;
    --raggio-pillola:  999px;

    --ombra-alzata:    0 12px 24px rgb(0 0 0 / .10);
    --ombra-premuta:   0 8px 16px rgb(0 0 0 / .10);
    --ombra-bottone:   0 10px 20px rgb(0 0 0 / .12);

    /* LA SCALA DELLE MISURE. Prima erano ventitré valori letterali diversi fra
       .1 e 3 rem, scelti uno alla volta: nessuno sbagliato, nessuno in
       relazione con gli altri. Un ritmo si riconosce anche senza saperlo
       nominare, e la sua assenza pure. Le regole vecchie non sono state
       riscritte in blocco — si migrano toccandole — ma tutto ciò che si
       aggiunge da qui in poi usa questi passi. */
    --s1: .25rem;
    --s2: .5rem;
    --s3: .75rem;
    --s4: 1rem;
    --s5: 1.5rem;
    --s6: 2rem;
    --s7: 3rem;

    --transizione:     .18s ease;
    --tempo-svelto:    120ms;
    /* Parte decisa e si posa: la curva del movimento che sembra fisico. */
    --curva:           cubic-bezier(.2, .8, .25, 1);

    /* Il pannello si usa col mouse, ma un bersaglio grande non ha mai fatto
       male a nessuno: 44px è la soglia sotto la quale si sbaglia bottone. */
    --bersaglio:       2.75rem;

    /* Il rientro di un livello dell'albero. Uno solo, cosi' il passo non puo'
       diventare irregolare a forza di ritocchi. */
    --rientro-albero:  1.6rem;

    /* L'IMBOTTITURA DELLE CARD, dichiarata una volta. La barra dei comandi si
       riporta ai bordi con un margine NEGATIVO pari a questa misura: finche'
       erano due numeri scritti a mano, una card con imbottitura diversa —
       `.modulo--sposta` e `.modulo--marchi`, che ne avevano 1,2rem — faceva
       sbordare la barra di 8,8px per lato oltre il bordo arrotondato. Legarle
       alla stessa variabile rende impossibile lo scarto. */
    --card-x:          1.75rem;
    --card-y:          1.5rem;
}

* { box-sizing: border-box; }

/* `hidden` DEVE VINCERE, e non e' una precauzione teorica.
   L'attributo vale `display: none` come regola dello user agent, cioe' la
   piu' debole che esista: qualunque `display` dichiarato in questo foglio la
   batte. L'anteprima del file e il pulsante «Annulla» nascono nascosti e li
   mostra il JavaScript togliendo l'attributo — con `display: flex` scritto
   sulla loro classe sarebbero rimasti visibili SEMPRE, anche prima di aver
   scelto un file. Lo stesso inciampo era gia' costato l'albero della vista
   pubblica, che si presentava tutto aperto con il pulsante di apertura
   inerte.
   Se un giorno servisse un elemento che resta visibile pur avendo `hidden`
   — succede: nella vista pubblica il pannello dell'albero, su schermo largo,
   e' comandato da un bottone che li' non c'e' — quella regola va scritta piu'
   avanti nel foglio, con maggiore specificita' e il proprio `!important`. */
[hidden] { display: none !important; }

/* L'ANELLO DI FUOCO, UNA VOLTA PER TUTTE.
   Prima di questa regola `:focus-visible` compariva UNA volta in 1.772 righe —
   su un solo collegamento di tabella, e aggiungeva una sottolineatura. Otto
   famiglie di comandi (pulsanti, azioni di riga, paginazione, menu,
   intestazioni ordinabili, `summary`, frecce di riordino, piega dell'albero)
   non dichiaravano nessuno stato di fuoco: il pannello si poteva usare col
   mouse, e da tastiera non si sapeva mai dove si era.
   Si dichiara qui, in alto, e non in fondo: chi aggiunge un comando domani lo
   riceve senza doverselo ricordare. `:focus-visible` e non `:focus` perché
   l'anello serve a chi naviga da tastiera, non a chi ha appena cliccato.
   `outline` e non `box-shadow`: l'ombra viene tagliata da qualunque antenato
   con `overflow: hidden` — e le card di questo pannello ce l'hanno tutte, per
   via degli angoli. */
/* IL SALTO AL CONTENUTO. Fuori schermo finche' non prende il fuoco, e allora
   torna al suo posto: non si ritaglia con `display: none`, che lo toglierebbe
   anche alla tastiera — cioe' proprio a chi serve. */
.salta {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;

    padding: var(--s2) var(--s4);
    background: var(--superficie);
    color: var(--primario);
    font-weight: 700;
    border-radius: 0 0 var(--raggio-piccolo) 0;
    box-shadow: var(--ombra-alzata);
}

.salta:focus {
    left: 0;
}

/* IL CONTENUTO TIENE IL SUO ANELLO, e ci ho ripensato una volta.
   L'istinto e' toglierlo: un anello attorno a mezza pagina sembra un errore.
   Ma e' l'unica conferma che il salto e' andato a segno — senza, si preme il
   collegamento e non succede visibilmente niente, e la volta dopo non lo si
   preme piu'. Resta, spostato di qualche pixel per non incollarsi al bordo. */
.contenuto:focus-visible {
    outline: 2px dashed var(--primario);
    outline-offset: -4px;
}

a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--primario);
    outline-offset: 2px;
    border-radius: var(--raggio-piccolo);
}

/* Sul fondo scuro dell'intestazione il navy sparisce: là l'anello è chiaro. */
.intestazione a:focus-visible,
.intestazione button:focus-visible {
    outline-color: #fff;
}

body {
    margin: 0;
    min-height: 100vh;
    font: 16px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    color: var(--inchiostro);

    /* I due veli del sito, con i colori del Gruppo. Fissi rispetto alla
       finestra: su una pagina lunga non «scorrono via». */
    background:
        radial-gradient(900px 500px at 20% 20%, rgb(var(--rgb-oro) / .10), transparent 60%),
        radial-gradient(900px 500px at 80% 30%, rgb(var(--rgb-primario) / .09), transparent 55%),
        var(--carta);
    background-attachment: fixed;
}

a { color: var(--primario); }

/* --- Intestazione ------------------------------------------------------ */

/* La barra è una fascia che galleggia sul fondo velato invece di essere
   incollata al bordo: le dà lo stesso stacco che hanno le card, e sotto si
   vede il velo. */
.intestazione {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem 1.5rem;
    margin: clamp(.5rem, 2vw, 1rem) clamp(.5rem, 2vw, 1.5rem) 0;
    padding: .9rem 1.5rem;
    background: var(--primario);
    color: #fff;
    border-radius: var(--raggio);
    box-shadow: var(--ombra-bottone);
}

/* Il menu della barra: pastiglie chiare su fondo scuro, come tutto il resto. */
.intestazione .menu a,
.intestazione .uscita button {
    border-radius: var(--raggio-pillola);
    transition: background var(--transizione), border-color var(--transizione);
}

.marchio {
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: .02em;
    color: #fff;
    text-decoration: none;
}

.marchio span {
    font-weight: 400;
    opacity: .75;
    margin-left: .4rem;
}

/* `flex-wrap` non è pignoleria: senza, su un telefono da 390px il comando
   «Nuovo documento» finiva 104 pixel FUORI dallo schermo e la pagina scrollava
   di lato. L'intestazione lo faceva già; il menu dentro no, e bastava lui.
   Misurato, non dedotto. */
.menu {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem 1rem;
    margin-left: auto;
}

.menu a {
    color: #fff;
    text-decoration: none;
    padding: .3rem 0;
    border-bottom: 2px solid transparent;
}

.menu a:hover { border-bottom-color: var(--oro); }

/* La pagina in cui ci si trova si riconosce dal PIENO oro: la sottolineatura
   da due pixel era l'unico segno, e su una barra con cinque voci non bastava
   a dire dove si è. `aria-current` lo dichiara già per i lettori di schermo —
   qui si limita a renderlo visibile anche a chi guarda. */
.menu a[aria-current="true"] {
    background: var(--oro);
    color: var(--su-oro);
    font-weight: 700;
    padding-inline: .8rem;
    border-bottom-color: transparent;
}

.menu a.azione {
    border: 1px solid rgba(255, 255, 255, .45);
    border-radius: var(--raggio);
    padding: .3rem .8rem;
}

.uscita {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin: 0;
}

.uscita .chi { opacity: .85; font-size: .9rem; }

.uscita button {
    background: transparent;
    color: #fff;
    border: 1px solid rgba(255, 255, 255, .45);
    /* Il raggio lo dà `.intestazione .uscita button` (specificità maggiore):
       dichiararlo anche qui era una riga senza effetto. */
    padding: .3rem .8rem;
    cursor: pointer;
    font: inherit;
    font-size: .9rem;
}

.uscita button:hover { background: rgba(255, 255, 255, .12); }

/* Le voci di menu portano l'icona a sinistra della parola: due elementi in
   riga hanno bisogno di essere dichiarati tali, altrimenti l'icona si siede
   sulla linea di base e il testo le scivola sotto. */
.menu a,
.uscita button {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
}

/* --- Le pagine pubbliche, dall'intestazione ---------------------------- */

/* Una tendina accanto al nome del pannello: da qualunque schermata, due clic
   per vedere la pagina pubblica di un brand così come la vede chi la apre.
   Il pulsante è vestito come «Esci», l'altro comando della barra che non è
   una sezione del pannello. */
.pubbliche {
    position: relative;
}

.pubbliche > summary {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-height: var(--bersaglio);
    padding: 0 .8rem;
    color: #fff;
    font-size: .9rem;
    border: 1px solid rgba(255, 255, 255, .45);
    border-radius: var(--raggio-pillola);
    cursor: pointer;
    list-style: none;
    transition: background var(--transizione);
}

/* Safari disegna un suo triangolo che non si toglie con `list-style`. */
.pubbliche > summary::-webkit-details-marker { display: none; }

.pubbliche > summary:hover,
.pubbliche[open] > summary { background: rgba(255, 255, 255, .12); }

/* Sul fondo scuro l'anello navy sparirebbe, come per gli altri comandi della
   barra: la regola dell'intestazione copre `a` e `button`, non `summary`. */
.intestazione .pubbliche > summary:focus-visible { outline-color: #fff; }

.pubbliche__freccia { transition: transform var(--transizione); }
.pubbliche[open] .pubbliche__freccia { transform: rotate(180deg); }

.pubbliche__elenco {
    position: absolute;
    top: calc(100% + var(--s2));
    left: 0;
    /* Sopra la barra dei comandi appiccicata in fondo ai moduli, che ha 5. */
    z-index: 20;
    width: max-content;
    min-width: 16rem;
    max-width: min(26rem, calc(100vw - 2rem));
    padding: var(--s2);
    background: var(--superficie);
    color: var(--inchiostro);
    border: 1px solid var(--bordo);
    border-radius: var(--raggio);
    box-shadow: var(--ombra-alzata);
}

.pubbliche__nota {
    margin: var(--s1) var(--s3) var(--s2);
    color: var(--inchiostro-lieve);
    font-size: .85rem;
}

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

.pubbliche__elenco a,
.pubbliche__spenta {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: var(--bersaglio);
    padding: var(--s2) var(--s3);
    border-radius: var(--raggio-piccolo);
    text-decoration: none;
}

.pubbliche__elenco a { color: var(--primario); }
.pubbliche__elenco a:hover { background: rgb(var(--rgb-primario) / .07); }

/* DENTRO LA TENDINA IL FONDO È BIANCO. La regola dell'intestazione schiarisce
   l'anello di ogni collegamento della barra, e queste voci sono collegamenti
   della barra: senza questa riga il fuoco da tastiera sarebbe bianco su
   bianco, cioè invisibile proprio a chi lo usa. */
.intestazione .pubbliche__elenco a:focus-visible { outline-color: var(--primario); }

.pubbliche__nome {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-weight: 700;
}

.pubbliche__indirizzo {
    color: var(--inchiostro-lieve);
    font-size: .85rem;
    overflow-wrap: anywhere;
}

.pubbliche__spenta .pubbliche__nome { color: var(--inchiostro-lieve); }

/* Il testo che solo un lettore di schermo legge: «si apre in una nuova
   scheda». Ritagliato e non tolto — con `display: none` sparirebbe anche per
   chi deve sentirlo. È la stessa forma di `.sr-solo` nella pagina pubblica. */
.sr-solo {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* I comandi della testata di una scheda: il collegamento alla pagina pubblica
   e il ritorno all'elenco, in riga e allineati al centro — sulla linea di base
   la pastiglia e il testo semplice non si incontrano. */
.testata__azioni {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s2) var(--s4);
}

/* --- Struttura della pagina -------------------------------------------- */

/* SESSANTOTTO REM ERANO STRETTI PER QUESTE TABELLE. L'elenco documenti ha
   otto colonne — titolo, categoria, tipo, marchi, stato, file, ordine,
   azioni — e la somma delle loro larghezze minime sforava il contenitore di
   diciotto pixel: la tabella usciva dal bordo della propria card. Le
   alternative erano spezzare le parole (e «Istruzioni di montaggio» usciva
   sillabato) o togliere informazione. Dare spazio costa una riga. */
/* DUE LARGHEZZE, NON UNA. Una tabella e un modulo hanno bisogni opposti: la
   prima vuole tutto lo schermo — misurato, otto colonne di prosa italiana ne
   chiedono 1.697px e ne avevano 1.168, cioe' il 45% in meno, ed e' da li' che
   nascevano le righe alte 126px con «Kit pilastrino per base angolo» su
   quattro righe; il secondo non lo vuole, perche' un campo di testo largo
   seicento pixel si legge male e si compila peggio.
   La distinzione la fa la pagina stessa: se contiene un modulo, si stringe.
   Dove `:has()` non c'e' resta la larghezza ampia, che e' il male minore. */
.contenuto {
    max-width: 82rem;
    margin: 0 auto;
    padding: 1.75rem 1.5rem 3rem;
}

.contenuto:has(.modulo) { max-width: 76rem; }

.testata {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem 1rem;
    margin-bottom: 1.25rem;
}

.testata h1 { margin: 0; font-size: 1.5rem; }

.conteggio, .minuta, .aiuto {
    color: var(--inchiostro-lieve);
    font-size: .85rem;
}

.piede {
    /* La stessa misura del contenuto, e non una qualunque: l'allargamento
       precedente si era fermato a `.contenuto` e il piede era rimasto 8rem
       più stretto, cioè 64px di rientro per lato rispetto a tutto ciò che gli
       sta sopra. Si vedeva, e sembrava un errore di allineamento perché lo era. */
    max-width: 82rem;
    margin: 0 auto;
    padding: 0 1.5rem 2rem;
    color: var(--inchiostro-lieve);
    font-size: .8rem;
}

/* --- Avvisi ------------------------------------------------------------ */

.avviso {
    margin: 0 0 1rem;
    padding: .8rem 1rem;
    border-radius: var(--raggio);
    border-left: 4px solid;
}

.avviso ul { margin: .5rem 0 0; padding-left: 1.2rem; }
.avviso p:first-child { margin-top: 0; }

.avviso--successo   { background: var(--buono-carta);  border-color: var(--buono);   color: var(--buono); }
.avviso--attenzione { background: var(--attento-carta); border-color: var(--attento); color: var(--attento); }
.avviso--errore     { background: var(--grave-carta);  border-color: var(--grave);   color: var(--grave); }

/* --- Moduli ------------------------------------------------------------ */

.modulo {
    background: var(--superficie);
    border: 1px solid var(--bordo);
    border-radius: var(--raggio);
    box-shadow: var(--ombra-alzata);
    padding: var(--card-y) var(--card-x);
}

/* IL MODULO DEL DOCUMENTO ERA ALTO 2172 PIXEL su uno schermo da 1000, in
   colonna singola, con campi larghi novecento pixel per contenere un titolo.
   Due schermate e mezza di scorrimento per creare un documento, e il pulsante
   «Crea» invisibile finché non si arrivava in fondo.
   Da qui in giù: i campi si affiancano a due a due dove ha senso, quelli che
   hanno bisogno di larghezza se la prendono tutta, e i comandi restano
   attaccati al bordo inferiore invece di aspettare in fondo alla pagina. */
.modulo fieldset {
    border: 0;
    border-top: 1px solid var(--bordo);
    margin: 0 0 var(--s5);
    padding: var(--s4) 0 0;

    /* DUE COLONNE, NON «QUANTE CE NE STANNO». Con `auto-fit` ne entravano tre
       e i campi corti finivano sparsi con due celle vuote accanto: una
       griglia che si riempie da sola non sa quali campi vanno letti insieme.
       Due colonne accostano il campo alla sua coppia naturale — categoria e
       tipo, lingua e ordine — e lasciano il resto prevedibile. */
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--s5);
    align-items: start;
}

/* Le caselle dei marchi non sono campi affiancabili: sono un elenco di scelte
   che si legge in fila. Dentro la griglia finivano una per colonna, con la
   spiegazione in una terza cella lontana da entrambe. */
.modulo fieldset.marchi {
    display: block;
}

.modulo fieldset:first-of-type { border-top: 0; padding-top: 0; }

/* La legenda occupa la riga intera: dentro una griglia, lasciata a se stessa,
   finirebbe nella prima cella accanto al primo campo. */
.modulo legend {
    grid-column: 1 / -1;
    float: left;
    width: 100%;
    margin-bottom: var(--s3);
    font-weight: 700;
    font-size: .8rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--inchiostro-lieve);
    padding: 0;
}

/* `float` sulla legenda la fa uscire dal suo posto speciale e la rende un
   elemento normale — è l'unico modo di farla stare in una griglia — ma
   lascia il flottante attivo per ciò che segue: questa riga lo chiude. */
.modulo legend + * { clear: both; }

/* CHI HA BISOGNO DI RESPIRO SE LO PRENDE, e il criterio è il contenuto, non
   il capriccio: un'area di testo stretta a metà colonna si riempie in tre
   righe; un indirizzo web spezzato a metà non si rilegge; un percorso di
   archivio è `ab/cd/<sessantaquattro caratteri>.pdf` e in mezza colonna non
   ci sta mai.
   I selettori che nominano un campo — `name="titolo"`, `name="file_path"` —
   sono un accoppiamento che si paga: rinominare quel campo toglie la regola
   senza rompere niente di visibile. È il prezzo per non toccare i modelli
   mentre ci lavora qualcun altro, e va sciolto aggiungendo `campo--largo`
   nell'HTML alla prima occasione in cui quei file sono liberi. */
/* L'ACCOPPIAMENTO SUI NOMI DEI CAMPI E' SCIOLTO. Il commento qui sopra lo
   chiedeva «alla prima occasione in cui quei file sono liberi»: e' questa. Un
   selettore che nomina `name="file_path"` smette di valere se qualcuno
   rinomina il campo, e non rompe niente di visibile — il modulo diventa
   semplicemente sbilenco e nessuno sa perche'. Ora la larghezza la dichiara
   l'HTML accanto al campo che la chiede.
   `:has(textarea)` resta perche' non nomina niente: un'area di testo vuole
   tutta la riga per definizione, qualunque nome abbia. */
.campo:has(textarea),
.campo--largo,
.campo--caricamento,
.spiega,
.avviso,
/* IL RIQUADRO DEL DOMINIO E' ALTO, E STAVA IN MEZZA COLONNA. Trecento pixel
   di colonna sinistra vuota accanto a un pannello di quattro sezioni: la
   pagina sembrava sbilanciata perche' lo era. A riga intera il buco sparisce
   e il pannello si legge su una misura giusta. Spostarlo nel markup avrebbe
   rotto `PannelloDominiTest`, che ritaglia la sezione fra `modulo--dominio` e
   il primo `<p class="campo">` successivo: qui non si sposta niente, cambia
   solo quante colonne occupa. */
.modulo--dominio {
    grid-column: 1 / -1;
}

/* E IL CONTRARIO. Un intero e un codice di due lettere non chiedono mezza
   pagina: alla larghezza della colonna sembravano campi importanti e vuoti.
   La colonna resta della sua misura — la griglia non si sfalsa — e a
   stringersi e' il comando dentro l'etichetta. */
.campo--breve input,
.campo--breve select {
    max-width: 11rem;
}

.campo { margin: 0 0 var(--s4); }

.campo label {
    display: block;
    font-weight: 600;
    font-size: .9rem;
    margin-bottom: .3rem;
}

/* `:not([type=file])` NON è pedanteria. La zona di caricamento contiene un
   `input[type=file]`, e questo selettore discendente gli metteva addosso la
   pelle di un campo di testo: fondo bianco, bordo, angoli e larghezza piena
   DENTRO la cornice tratteggiata della zona. Due cornici concentriche, che è
   precisamente ciò che la zona di rilascio era stata scritta per togliere. */
/* `[type=color]` E' ESCLUSO PER LA STESSA RAGIONE DI `[type=file]`: non e' un
   campo di testo, e `width: 100%` lo stirava per tutta la colonna — un
   campione di colore largo quattrocento pixel accanto a un campo di testo
   ridotto a un francobollo. La regola generale vestiva un elemento che ha
   bisogno di una misura sua. */
.campo input:not([type=file]):not([type=color]),
.campo select,
.campo textarea {
    width: 100%;
    font: inherit;
    padding: var(--s3) var(--s4);
    /* Il confine di un campo vuoto è l'unica cosa che dice dove comincia: a
       1,26:1 non c'era, e i moduli si leggevano come fogli bianchi. */
    border: 1px solid var(--bordo-campo);
    border-radius: var(--raggio-piccolo);
    background: var(--superficie);
    color: inherit;
    transition: border-color var(--transizione), box-shadow var(--transizione);
}

.campo input:not([type=file]):not([type=color]):hover,
.campo select:hover,
.campo textarea:hover {
    border-color: var(--primario);
}

/* `:focus-visible` E NON `:focus`: con `:focus` l'anello compare anche a chi
   ha appena cliccato dentro il campo, che sa benissimo dove si trova. E niente
   ombra portata: sollevare il campo dice «questo si può premere», non «sei
   qui». Un anello dice la seconda cosa, ed è quella che serve. */
.campo input:not([type=file]):not([type=color]):focus-visible,
.campo select:focus-visible,
.campo textarea:focus-visible {
    outline: 2px solid var(--primario);
    outline-offset: 2px;
    border-color: var(--primario);
}

/* Il ripiego per i motori che non distinguono i due stati sui campi di testo:
   meglio un anello di troppo che nessuno. */
.campo input:not([type=file]):not([type=color]):focus,
.campo select:focus,
.campo textarea:focus {
    border-color: var(--primario);
}

/* Un campo spento deve dire di esserlo: senza, si prova a scriverci dentro e
   non succede niente. */
.campo input:disabled,
.campo select:disabled,
.campo textarea:disabled,
.campo input[readonly] {
    background: var(--carta);
    color: var(--inchiostro-lieve);
    border-color: var(--bordo);
    cursor: not-allowed;
}

.campo .aiuto { display: block; margin-top: .3rem; }

.marchi { border-top: 1px solid var(--bordo); }

/* LA CASELLA ERA NATIVA E NUDA: nessun colore, nessuna misura, nessun fuoco.
   Sta su due schermate in cui una spunta sbagliata nasconde un ramo intero
   dalle viste pubbliche — cioe' il posto dove serve di piu' vedere bene che
   cosa e' spuntato e che cosa no.
   IL BERSAGLIO E' L'ETICHETTA INTERA, non il quadratino: la casella misura
   18px, ma il `<label>` la contiene e vale come bersaglio per costruzione.
   Portandolo a 44px di altezza si preme la parola, che e' quello che si fa
   davvero. E l'anello di fuoco va sull'ETICHETTA e non sulla casella: sulla
   sola casella si vedrebbe la meta' del segno. */
.spunta {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);

    min-height: var(--bersaglio);
    padding: var(--s1) var(--s3);
    margin: 0 var(--s2) var(--s1) 0;

    font-weight: 400;
    border: 1px solid transparent;
    border-radius: var(--raggio-piccolo);
    cursor: pointer;

    transition: background var(--transizione), border-color var(--transizione);
}

.spunta:hover {
    background: rgb(var(--rgb-primario) / .07);
    border-color: var(--bordo-campo);
}

.spunta:has(input:checked) {
    background: rgb(var(--rgb-primario) / .10);
    border-color: var(--primario);
    font-weight: 600;
}

.spunta:has(input:focus-visible) {
    outline: 2px solid var(--primario);
    outline-offset: 2px;
}

.spunta input {
    width: 1.15em;
    height: 1.15em;
    flex: 0 0 auto;
    /* Il colore della spunta lo decide il browser se non glielo si dice: sui
       sistemi in tema scuro esce blu di sistema in mezzo al navy del Gruppo. */
    accent-color: var(--primario);
    cursor: pointer;
}

/* I COMANDI RESTANO ATTACCATI AL BORDO INFERIORE. Su un modulo lungo il
   pulsante «Crea documento» stava in fondo alla pagina: per salvare bisognava
   scorrere fino alla fine, e chi si fermava a metà non aveva modo di sapere
   che il salvataggio esisteva più giù. Restando in vista, il modulo si può
   chiudere da qualunque punto lo si stia guardando.
   Il margine negativo e il riempimento riportano la barra ai bordi della card,
   così la striscia opaca copre tutta la larghezza invece di lasciare due
   fessure da cui si vede passare il testo. */
/* SOLO DENTRO UN MODULO. `.comandi` la porta anche la barra dei filtri
   dell'elenco documenti, che non e' in fondo a niente: resa appiccicata,
   quel «Filtra» si staccava dalla riga dei campi e scendeva da solo con una
   striscia opaca sotto. Visto aprendo la pagina — leggendo il foglio la
   regola sembrava riguardare una cosa sola. */
.modulo .comandi {
    position: sticky;
    bottom: 0;
    z-index: 5;

    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s3);

    margin: var(--s5) calc(-1 * var(--card-x)) calc(-1 * var(--card-y));
    padding: var(--s4) var(--card-x);

    background: rgb(255 255 255 / .92);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-top: 1px solid var(--bordo);
    border-radius: 0 0 var(--raggio) var(--raggio);
}

/* I comandi sono pastiglie, come la CTA del sito: si sollevano di un pixel
   al passaggio e tornano giù quando si premono. Il bersaglio non scende mai
   sotto i 44px, che è la soglia sotto la quale si sbaglia bottone. */
button, .principale, .secondaria, .pericolo {
    font: inherit;
    font-weight: 700;
    border-radius: var(--raggio-pillola);
    /* `var(--bersaglio)` e non «2.75rem»: il numero sparso fra le regole si
       erode senza che nessuno se ne accorga — è già successo in questo
       progetto, sulla vista pubblica, dove la misura era scesa da 48 a 44
       durante un restyling e nessun test lo aveva visto. Prima di questa riga
       la variabile era dichiarata, documentata con tre righe di commento, e
       referenziata ZERO volte in 1.772 righe. */
    min-height: var(--bersaglio);
    padding: .6rem 1.35rem;
    cursor: pointer;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    transition: transform var(--transizione), box-shadow var(--transizione),
        background var(--transizione), border-color var(--transizione), color var(--transizione);
}

button:active, .principale:active, .secondaria:active, .pericolo:active {
    transform: translateY(1px);
    box-shadow: var(--ombra-premuta);
}

.principale {
    background: var(--primario);
    color: #fff;
    border: 1px solid var(--primario);
    box-shadow: var(--ombra-bottone);
}

.principale:hover {
    background: var(--primario-scuro);
    transform: translateY(-1px);
    box-shadow: 0 14px 28px rgb(0 0 0 / .18);
}

.secondaria {
    background: var(--superficie);
    color: var(--primario);
    border: 1px solid var(--bordo);
}

.secondaria:hover {
    border-color: var(--bordo-acceso);
    box-shadow: var(--ombra-alzata);
    transform: translateY(-1px);
}

.pericolo {
    background: var(--superficie);
    color: var(--grave);
    border: 1px solid rgb(155 44 44 / .35);
}

/* L'eliminazione NON si solleva al passaggio: l'invito a premere lo si dà ai
   comandi che si possono disfare, non a quello che toglie una vista dalla
   rete. */
.pericolo:hover { background: var(--grave); color: #fff; border-color: var(--grave); }

button[disabled] { opacity: .6; cursor: progress; }

/* --- Accesso ----------------------------------------------------------- */

.accesso {
    max-width: 24rem;
    margin: 3rem auto;
}

.accesso h1 { font-size: 1.3rem; margin-bottom: 1rem; }

/* --- Filtri ------------------------------------------------------------ */

.filtri {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: .75rem 1rem;
    background: var(--superficie);
    border: 1px solid var(--bordo);
    border-radius: var(--raggio);
    padding: 1rem 1.25rem;
    box-shadow: var(--ombra-alzata);
    margin-bottom: 1.25rem;
}

.filtri .campo { margin: 0; flex: 1 1 9rem; }
.filtri .campo--ricerca { flex: 2 1 16rem; }

/* TUTTI I COMANDI DELLA BARRA ALLA STESSA ALTEZZA. Il campo di ricerca ne
   misurava 44 e le tendine 40: allineati in basso, le loro etichette
   finivano a quote diverse e la barra sembrava storta senza che si capisse
   perche'. Non e' un dettaglio da poco: e' la prima cosa che si guarda in
   ogni elenco del pannello. */
.filtri .campo input,
.filtri .campo select,
.filtri button {
    min-height: var(--bersaglio);
}
.filtri .comandi { margin: 0; }

/* --- Tabella ----------------------------------------------------------- */

/* `width: 100%` su una tabella e' un desiderio, non un ordine: se la somma
   delle larghezze MINIME delle colonne supera il contenitore, la tabella si
   allarga lo stesso e sfora. Qui il minimo era dettato dagli slug —
   «pilastrino-per-moduli-angolo» non ha spazi in cui andare a capo, quindi la
   colonna del titolo non poteva scendere sotto la sua lunghezza. Permettendo
   di spezzare le parole senza spazi, la tabella torna dentro il suo bordo. */
/* `table-layout: fixed` E NON `auto`, ed e' la correzione che cambia di piu'
   in tutto il pannello.
   Con `auto` le larghezze scritte sulle celle sono SUGGERIMENTI: qui c'era
   `width: 28%; min-width: 12rem` sulla prima colonna e il browser le ignorava
   entrambe — misurato, il titolo restava a 278px cioe' il 23,8%, mentre la
   colonna «Azioni», che non ha bisogno di niente, se ne prendeva 182.
   Il conto vero: le otto colonne dell'elenco documenti chiedevano 1.697px per
   stare su una riga sola e ne avevano 1.168. Il 45% in meno. Da li' «Kit
   pilastrino per base angolo» su quattro righe e le righe alte 126px accanto
   a righe alte 80: un ritmo che non c'e'.
   Con `fixed` le larghezze comandano davvero — al punto che il contenuto che
   non ci sta ESCE invece di allargare la colonna. Quindi vanno misurate sul
   contenuto reale, ed e' quello che e' stato fatto: sotto, tabella per
   tabella, i numeri vengono dalla misura della stringa piu' lunga. */
.tabella {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
    background: var(--superficie);
    border: 1px solid var(--bordo);
    border-radius: var(--raggio);
    box-shadow: var(--ombra-alzata);
    overflow: hidden;
}

.tabella th,
.tabella td {
    text-align: left;
    padding: var(--s3) var(--s4);
    border-bottom: 1px solid var(--bordo);
    vertical-align: middle;
}

/* LE LARGHEZZE, misurate. La prima colonna non ne dichiara nessuna: con
   `fixed` prende quello che avanza, ed e' giusto che sia lei — e' l'unica che
   si legge davvero. Le altre dichiarano il minimo che serve alla loro stringa
   piu' lunga piu' il respiro delle celle.
   In `rem` e non in percentuale: una percentuale di un contenitore che cambia
   non ha alcun rapporto con la lunghezza di «Istruzioni di montaggio». */

/* Documenti — 7 colonne. Titolo · Classificazione · Marchi · Stato · File ·
   Ordine · Azioni. Fissi 63rem su 79rem di tabella: al titolo ne restano 16,
   cioe' 256px. Quando «Ordine» e' passata da un numero a maniglia e frecce,
   il centimetro in piu' l'ha dato «File», dove il nome era gia' troncato:
   toglierlo al titolo lo mandava a capo. */
/* 16rem e non 15: «Kit pilastrino per base angolo» ne chiede 212 al netto
   dell'imbottitura, e a 15rem ne aveva 208. Quattro pixel che costavano
   venticinque di altezza su due righe su sette. */
.tabella--documenti th:nth-child(2) { width: 16rem; }
.tabella--documenti th:nth-child(3) { width: 8rem; }
.tabella--documenti th:nth-child(4) { width: 7.5rem; }
.tabella--documenti th:nth-child(5) { width: 11.25rem; }
/* L'ORDINE: maniglia e due frecce, 20 + 32 + 32 pixel con due di stacco, e
   un'imbottitura piu' stretta di quella delle altre celle — con la solita la
   seconda freccia usciva. A 5,5rem, quando la colonna diceva solo un numero,
   non ci stavano. */
.tabella--documenti th:nth-child(6) { width: 6.75rem; }

.tabella--documenti th:nth-child(6),
.tabella--documenti td.posizione { padding-left: .625rem; padding-right: .625rem; }
/* 11,5rem e non 9,5: da quando le due azioni sono testo e non pastiglie
   chiedono 170px per stare in fila, e a layout fisso cio' che non ci sta ESCE
   — «Elimina» usciva come «Elimin». Misurato, non stimato. */
.tabella--documenti th:nth-child(7) { width: 13.5rem; }

/* Categorie: le larghezze stanno piu' in basso, con il resto dell'albero. */

/* Marchi — 5 colonne. «Azioni» ne ha 17 e non 10 perche' quella cella, quando
   il marchio non si puo' eliminare, contiene anche il MOTIVO: una frase, non
   un pulsante. Finche' la colonna si dimensionava da sola quella frase usciva
   dal bordo e veniva tagliata a meta' parola — «designarne un al» — dal
   ritaglio della card. */
.tabella--marchi th:nth-child(2) { width: 19rem; }
.tabella--marchi th:nth-child(3) { width: 8rem; }
.tabella--marchi th:nth-child(4) { width: 9rem; }
.tabella--marchi th:nth-child(5) { width: 20rem; }

/* Redattori — 6 colonne. */
.tabella--utenti th:nth-child(2) { width: 17rem; }
.tabella--utenti th:nth-child(3) { width: 7rem; }
.tabella--utenti th:nth-child(4) { width: 11rem; }
.tabella--utenti th:nth-child(5) { width: 7rem; }
.tabella--utenti th:nth-child(6) { width: 15rem; }

.tabella th {
    font-size: .78rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--inchiostro-lieve);
    background: rgb(var(--rgb-primario) / .04);
    vertical-align: bottom;
}

.tabella tr:last-child td { border-bottom: 0; }

.tabella tbody tr {
    transition: background var(--transizione);
}

.tabella tbody tr:hover { background: rgb(var(--rgb-oro) / .07); }

.tabella .minuta { display: block; }

/* I DUE ASSI, UNO SOPRA L'ALTRO. Lasciati inline si leggevano come una frase
   sola — «Base forno Istruzioni di montaggio» — che non e' ne' la categoria
   ne' il tipo. Il ramo porta il peso perche' e' quello che si cerca; il tipo
   sta sotto, in grigio di servizio, perche' e' l'asse trasversale. */
.classificazione__ramo {
    display: block;
    font-weight: 600;
}

.classificazione__tipo {
    display: block;
    color: var(--inchiostro-lieve);
    font-size: .85rem;
}

.segno {
    display: inline-block;
    font-size: .78rem;
    font-weight: 700;
    padding: .2rem .6rem;
    margin: 0 .2rem .2rem 0;
    border: 1px solid var(--bordo);
    border-radius: var(--raggio-pillola);
    color: var(--inchiostro-lieve);
    /* Il nome di un marchio non si spezza: «Cucine / Turi» su due righe in una
       pastiglia alta il doppio è il modo più veloce per far sembrare rotta una
       tabella che funziona.
       MA non tutte le pastiglie sono nomi: la scheda del marchio ne usa una
       per l'avviso di contrasto insufficiente, che è una frase di novanta
       caratteri. Con `nowrap` su tutte, quella usciva dallo schermo e faceva
       scorrere la pagina di lato — proprio quando c'è da leggerla. Il divieto
       di andare a capo vale dove il contenuto è una parola sola. */
    white-space: nowrap;
}

/* Le pastiglie che contengono una frase vanno a capo come qualunque testo. */
.segno--attenzione,
.segno--tutti {
    white-space: normal;
}

.segno--attenzione { border-color: var(--attento); color: var(--attento); }

.stato {
    display: inline-block;
    font-size: .78rem;
    padding: .1rem .5rem;
    border-radius: 999px;
}

/* IL CONFINE, non solo il fondo. `--buono-carta` sul bianco vale 1,14:1 e
   `#eceff1` 1,15:1: il testo dentro era a norma, la PASTIGLIA no — cioe' non
   si leggeva come un oggetto, solo come testo colorato. Il bordo prende il
   colore del testo, che a norma ci sta gia'. */
.stato {
    border: 1px solid currentColor;
}

.stato--pubblicato { background: var(--buono-carta); color: var(--buono); }
.stato--bozza      { background: #eceff1;            color: var(--inchiostro-lieve); }

.vuoto {
    background: var(--superficie);
    border: 1px dashed var(--bordo);
    border-radius: var(--raggio);
    padding: 2rem;
    text-align: center;
    color: var(--inchiostro-lieve);
}

/* SOLO LE PAROLE CHE NON HANNO SPAZI, e non tutte le celle. `anywhere`
   spezza dove capita E riduce la larghezza minima della colonna: applicato a
   ogni cella, il browser ne approfitta per stringere tutto, e «Istruzioni di
   montaggio» usciva incolonnato sillaba per sillaba — «Istru / zioni / di /
   mon / tagg / io» — mentre «pubblicato» diventava tre righe dentro la sua
   pastiglia. Serviva a slug, nomi di file e impronte, che sono le uniche
   stringhe senza spazi in cui andare a capo: sono loro a dettare la
   larghezza minima che faceva sforare la tabella. */
.tabella .minuta { overflow-wrap: anywhere; }

/* Il nome del file non va a capo: si accorcia. Vedi il commento nel modello —
   il nome intero resta nel `title` e nell'albero di accessibilita'. */
.nome-file {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Le pastiglie non si spezzano MAI: una pastiglia su tre righe non e' piu'
   una pastiglia. */
.tabella .segno,
.tabella .stato { white-space: nowrap; }

/* --- Paginazione ------------------------------------------------------- */

.pagine {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-top: 1.25rem;
}

/* La paginazione misurava 35×36px e non aveva ne' hover, ne' fuoco, ne'
   pressione: tre numeri in fila che non sembravano premibili. Qui il bersaglio
   pieno si puo' dare davvero, perche' non sta dentro una riga di tabella. */
.pagina {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--bersaglio);
    min-height: var(--bersaglio);
    padding: 0 var(--s2);
    border: 1px solid var(--bordo-campo);
    border-radius: var(--raggio-piccolo);
    background: var(--superficie);
    color: var(--primario);
    font-weight: 600;
    text-decoration: none;
    transition: background var(--transizione), border-color var(--transizione);
}

.pagina:hover {
    background: rgb(var(--rgb-primario) / .08);
    border-color: var(--primario);
    text-decoration: none;
}

.pagina:active { background: rgb(var(--rgb-primario) / .14); }

.pagina--corrente {
    background: var(--primario);
    border-color: var(--primario);
    color: #fff;
}

/* IL BERSAGLIO SI ESTENDE, LA RIGA NO.
   Il pannello dichiara 44px (`--bersaglio`) e i comandi di riga ne misuravano
   28 (la piega dell'albero), 32 (azioni e frecce di riordino), 35×36 (la
   paginazione). Alzarli con l'imbottitura funziona e costa: ogni riga della
   tabella cresce di dodici pixel per un pulsante che deve restare discreto.
   Si estende invece l'AREA SENSIBILE con uno strato assoluto, che non entra
   nel flusso e quindi non alza niente. `inset` negativo su un elemento
   `position: relative`: il disegno resta di 32px, il dito ne trova 44.
   Va messo su elementi che non hanno gia' un ::after usato per altro. */
.bersaglio-esteso { position: relative; }

.bersaglio-esteso::after {
    content: "";
    position: absolute;
    inset: -6px;
    /* Nessun colore: e' area, non decorazione. */
}

/* IL SELETTORE DI COLORE ACCANTO AL SUO CODICE.
   I due sono lo stesso dato in due forme, quindi si toccano: separati da un
   `gap` sembrerebbero due campi diversi. Il selettore ha la stessa altezza del
   campo — il navigatore gliene darebbe una sua — cosi' la coppia legge come un
   solo comando. */
.colore {
    display: flex;
    align-items: stretch;
    gap: 0;
}

.colore__scelta {
    flex: 0 0 auto;
    align-self: stretch;
    width: var(--bersaglio);
    /* `height: auto` perche' un `input` porta un'altezza intrinseca che
       `align-self: stretch` da sola non batte: senza, il campione restava 44px
       accanto a un campo di 51 e la coppia aveva un gradino. */
    height: auto;
    min-height: var(--bersaglio);
    padding: .2rem;

    background: var(--superficie);
    border: 1px solid var(--bordo-campo);
    border-right: 0;
    border-radius: var(--raggio-piccolo) 0 0 var(--raggio-piccolo);
    cursor: pointer;
}

/* Il riquadro interno del campione: senza, i navigatori lasciano una cornice
   grigia di sistema attorno al colore e la coppia sembra scollata. */
.colore__scelta::-webkit-color-swatch-wrapper { padding: 0; }
.colore__scelta::-webkit-color-swatch { border: 0; border-radius: 6px; }
.colore__scelta::-moz-color-swatch { border: 0; border-radius: 6px; }

.colore__scelta:focus-visible {
    outline: 2px solid var(--primario);
    outline-offset: 2px;
    position: relative;
    z-index: 1;
}

.campo .colore__codice {
    flex: 1 1 auto;
    min-width: 0;
    border-radius: 0 var(--raggio-piccolo) var(--raggio-piccolo) 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* LA PAGINA D'ERRORE NON AVEVA UNA SOLA REGOLA. `class="errore"` era scritta
   nel modello e non corrispondeva a niente nel foglio: un titolo di sistema e
   due paragrafi nudi in mezzo a una pagina che altrove e' fatta di card. E' la
   schermata che si vede nel momento peggiore — quando qualcosa e' gia' andato
   storto — ed era l'unica lasciata all'aspetto predefinito del navigatore.
   Il numero non e' un titolo: e' un dato. Il titolo e' la frase che dice che
   cosa e' successo, e sotto sta la via d'uscita — perche' una pagina d'errore
   senza una via d'uscita e' un vicolo cieco. */
.errore {
    max-width: 34rem;
    margin: var(--s7) 0;
    padding: var(--s6) var(--s6) var(--s5);

    background: var(--superficie);
    border: 1px solid var(--bordo);
    border-radius: var(--raggio);
    box-shadow: var(--ombra-alzata);
}

.errore h1 {
    margin: 0 0 var(--s3);
    font-size: 1.4rem;
    line-height: 1.25;
}

.errore h1 .errore__codice {
    display: block;
    font-size: .8rem;
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--inchiostro-lieve);
    margin-bottom: var(--s1);
}

.errore p { margin: 0 0 var(--s4); color: var(--inchiostro-lieve); }

.errore p:last-child { margin-bottom: 0; }

/* `.secondaria` e' gia' vestita globalmente: qui basta lo stacco. */
.errore .secondaria { margin-top: var(--s2); }

/* --- Eliminazione ------------------------------------------------------ */

/* LA ZONA PERICOLOSA E' UNA ZONA, non una riga di roba in fondo.
   Con `align-items: center` e un solo `gap` il pulsante finiva schiacciato fra
   due paragrafi e usciva su due righe — «Elimina / marchio» — cioe' l'unico
   comando irreversibile della pagina aveva l'aria di un errore di
   impaginazione. Ora e' un riquadro suo, con il comando in fondo e alla sua
   misura piena: si vede che e' un'altra cosa rispetto al modulo sopra, ed e'
   esattamente il messaggio che deve dare. */
.eliminazione {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s3) var(--s5);

    margin-top: var(--s5);
    padding: var(--s4) var(--s5);

    background: var(--grave-carta);
    border: 1px solid rgb(155 44 44 / .25);
    border-radius: var(--raggio);
}

/* Il testo prende quello che resta, il pulsante non si stringe mai. */
.eliminazione .aiuto,
.eliminazione .minuta,
.eliminazione p { flex: 1 1 16rem; margin: 0; }

.eliminazione .pericolo {
    flex: 0 0 auto;
    white-space: nowrap;
    background: var(--superficie);
}

/* --- Schermi stretti --------------------------------------------------- */

@media (max-width: 40rem) {
    /* LA CARD RESTITUISCE VENTIQUATTRO PIXEL PER LATO.
       Su 390 la scheda del marchio lasciava 44px di margine per lato — 16 del
       contenuto e 28 della card — e i campi restavano larghi 300. Ma soprattutto
       la barra dei comandi ne aveva 300 di spazio utile contro 336 di pulsanti:
       «Salva modifiche» e «Annulla» andavano a capo, e la barra — che e'
       sempre in vista — diventava alta 137px su uno schermo da 844.
       Il margine di una card serve a staccarla dal fondo, e su un telefono un
       centimetro per lato non stacca niente: toglie leggibilita' e basta. */
    :root {
        --card-x: 1rem;
        --card-y: 1.25rem;
    }

    /* E i comandi si stringono quel tanto che basta a stare in riga: sono due
       pulsanti, non un modulo. Misurato: 308px di pulsanti e 8 di distacco
       dentro 324 di spazio utile — il margine e' voluto, perche' su un altro
       sistema lo stesso testo puo' misurare qualche pixel in piu'. Se un
       giorno non bastasse, `flex-wrap` li rimanda a capo: il peggio che
       succede e' tornare com'era. */
    .modulo .comandi { gap: var(--s2); }

    .modulo .comandi > .principale,
    .modulo .comandi > .secondaria { padding-left: 1rem; padding-right: 1rem; }

    /* DUE COLONNE SU UN TELEFONO SONO DUE CAMPI DA CENTOTRENTOTTO PIXEL.
       Misurato a 390px, prima di questa regola: le tendine «Categoria» e
       «Tipo di documento» stavano affiancate a 138px l'una — dentro ci
       entrava «· · Base forn» — e il codice del colore del marchio si
       leggeva «#28485», tagliato dal campo. La griglia a due colonne serve
       ad accostare i campi che si leggono insieme, e su una colonna da
       centocinquanta pixel non accosta niente: impila due campi illeggibili
       invece di uno leggibile.

       Vale per OGNI modulo del pannello — documento, categoria, marchio,
       redattore — perche' la griglia e' una sola. */
    .modulo fieldset,
    .gruppo-formato { grid-template-columns: minmax(0, 1fr); }

    .intestazione { padding: .75rem 1rem; }
    .menu { margin-left: 0; width: 100%; }
    .uscita { margin-left: auto; }

    /* LA TENDINA PRENDE TUTTA LA RIGA DEL SUO PULSANTE. Ancorata al solo
       pulsante, su un telefono largo abbastanza da tenerlo accanto al nome del
       pannello partirebbe da metà schermo e ne uscirebbe con metà degli
       indirizzi. Ancorata all'intestazione intera — il primo tentativo — si
       apriva sotto le quattro righe del menu, a 180px dal pulsante premuto:
       sembrava un'altra cosa. Così parte subito sotto il pulsante e occupa la
       larghezza della barra. A 390px il pulsante andava già a capo da solo. */
    .pubbliche { flex-basis: 100%; }

    .pubbliche__elenco {
        left: 0;
        right: 0;
        width: auto;
        min-width: 0;
        max-width: none;
    }
    .contenuto { padding: 1.25rem 1rem 2rem; }

    /* La tabella diventa un elenco di schede: sei colonne su un telefono
       si leggono solo inclinando la testa.
       MA NASCONDERE `thead` SENZA SOSTITUIRLO PERDE L'INFORMAZIONE: restava una
       colonna di valori senza nome — «0», «tutti i marchi», «10» — e nessun
       modo di sapere che cosa fossero. Ogni cella porta ora l'etichetta della
       propria colonna in `data-etichetta`, scritta dal template leggendo il
       `<thead>`: non è un nome inventato qui, è la stessa parola che si legge
       sullo schermo largo. */
    .tabella, .tabella tbody { display: block; width: 100%; }
    .tabella thead { display: none; }

    /* LA RIGA DIVENTA UNA SCHEDA, E LA SCHEDA SCORRE IN ORIZZONTALE.
       Prima ogni cella prendeva una riga intera con la sua etichetta a
       sinistra: sette righe per documento, e l'elenco di sette documenti era
       alto 3.313px — nove schermate di telefono per sette voci. La scheda ora
       e' un titolo, una fila di dati che va a capo da sola, e i comandi. */
    .tabella tr {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        gap: var(--s1) var(--s3);

        border-bottom: 1px solid var(--bordo);
        padding: var(--s3) var(--s4);
    }

    .tabella td {
        display: block;
        width: auto;
        flex: 0 0 auto;
        border: 0;
        padding: 0;
    }

    .tabella td[data-etichetta]::before {
        content: attr(data-etichetta) ": ";
        font-size: .72rem;
        font-weight: 800;
        text-transform: uppercase;
        letter-spacing: .06em;
        color: var(--inchiostro-lieve);
    }

    /* L'ETICHETTA SERVE SOLO DOVE IL VALORE NON SI SPIEGA.
       Il principio di prima era giusto — «0», «tutti i marchi», «10» senza un
       nome accanto non vogliono dire niente — ma vale per quei valori, non per
       tutti. Una pastiglia verde che dice «pubblicato» non ha bisogno di
       sentirsi chiamare STATO, e «Cucine Turi» dentro una pastiglia non ha
       bisogno di MARCHI: l'etichetta li' e' rumore che raddoppia l'altezza.
       Resta dove il valore e' un numero nudo o una parola sola ambigua. */
    .tabella td[data-etichetta="Stato"]::before,
    .tabella td[data-etichetta="Marchi"]::before,
    .tabella td[data-etichetta="File"]::before,
    .tabella td[data-etichetta="Classificazione"]::before,
    .tabella td[data-etichetta="Indirizzo pubblico"]::before,
    .tabella td[data-etichetta="Accesso"]::before,
    .tabella td[data-etichetta="Azioni"]::before { content: none; }

    /* Il titolo prende la riga intera: e' quello che si cerca scorrendo. */
    .tabella td:first-child {
        flex: 1 0 100%;
        font-size: 1.05rem;
        margin-bottom: var(--s1);
    }

    .tabella td:first-child::before { display: none; }

    /* Anche la classificazione: due fatti su due righe, non due parole in
       mezzo agli altri dati. */
    .tabella td[data-etichetta="Classificazione"] { flex: 1 0 100%; }

    /* L'ordine e' un dato di servizio: in fondo alla fila e in piccolo, non
       incastrato fra il nome del file e il suo peso, dove sembrava una parte
       del file. `order` e non un cambio di markup: la sequenza del documento
       resta quella della tabella, che e' anche quella che si ascolta. */
    .tabella td[data-etichetta="Ordine"] {
        order: 5;
        margin-left: auto;
        font-size: .8rem;
        color: var(--inchiostro-lieve);
    }

    /* I comandi chiudono la scheda, su una riga loro, distanziati dai dati:
       premuti per sbaglio scorrendo sarebbero il difetto peggiore di tutti. */
    .tabella td[data-etichetta="Azioni"] {
        order: 9;
        flex: 1 0 100%;
        margin-top: var(--s2);
        padding-top: var(--s2);
        border-top: 1px solid var(--bordo);
    }

    .tabella .azioni { display: flex; gap: var(--s2); }

    /* La larghezza fissa delle colonne vale solo sullo schermo largo: qui la
       tabella non e' piu' una tabella. */
    .tabella th { width: auto; }
}

/* --- Caricamento a blocchi -------------------------------------------- */

/*
 * La barra e lo stato restano nel flusso anche da fermi: comparendo solo a
 * caricamento avviato sposterebbero il resto del modulo proprio mentre il
 * redattore ci sta lavorando.
 */
/* IL TRATTEGGIO SE L'E' PRESO LA ZONA. Questo riquadro era la sola cosa che
   somigliasse a un'area di rilascio, e non lo era: adesso che il rilascio
   esiste davvero e ha il suo contorno, tenere il tratteggio anche qui
   disegnava due riquadri concentrici, uno dentro l'altro, per una cosa sola.
   Resta il contenitore del campo, senza aspetto proprio. */
.campo--caricamento {
    display: grid;
    gap: var(--s2);
    padding: 0;
    border: 0;
    margin-bottom: 1rem;
}

/* DUE REGOLE PER LA STESSA BARRA, e vinceva questa — non perche' venisse
   dopo, ma perche' `.campo--caricamento progress` (0,1,1) batte
   `.caricamento__barra` (0,1,0), che sta 900 righe piu' in basso e dichiara
   `.5rem`. Chi leggeva quella la credeva in vigore. Ora la misura sta qui e
   li' non c'e' piu': una regola sola, sulla classe.
   Anche `.caricamento__stato` era dichiarata due volte, con `min-height`
   diversi: vinceva la seconda per il `min-height` e la prima per il colore,
   cioe' cancellare una delle due rompeva qualcosa in modo diverso a seconda
   di quale. Unite. */
.campo--caricamento progress {
    width: 100%;
    height: .5rem;
    border-radius: var(--raggio-pillola);
    overflow: hidden;
}

/* ======================================================================
   Le tre schermate di gestione — categorie, marchi, redattori.
   Scritte separatamente e unite qui: il pannello carica un foglio solo,
   e tre file in più peggiorerebbero la pagina per non far litigare chi
   li ha scritti.
   ====================================================================== */

/* --- Albero delle categorie -------------------------------------------
 *
 * Da unire in coda a public/assets/css/pannello.css: usa le variabili già
 * dichiarate là (--bordo, --inchiostro-lieve, --buono, --carta) e nessun
 * carattere tipografico esterno, come il resto del pannello.
 *
 * IL RIENTRO È L'UNICA COSA CHE CONTA DAVVERO in questa pagina: un albero
 * disegnato piatto non è un albero, e con 29 voci non si capisce più se
 * «Dekton» sia una sezione o una voce dentro «Piani di lavoro». Il livello
 * arriva dal server come classe (albero__riga--liv0, --liv1, ...) perché la
 * profondità si perde appiattendo l'albero, e va calcolata dove l'albero
 * esiste ancora.
 */

.tabella--albero td { vertical-align: baseline; }

/* Niente `min-width` qui: a `table-layout: fixed` non vincola niente — la
   colonna la decide l'intestazione — e leggerlo fa credere il contrario. */

/* IL RIENTRO DEVE VALERE PER TUTTA LA CELLA, non per la sola prima riga.
 *
 * Lo slug sta in una «.minuta», e `.tabella .minuta { display: block }` la
 * manda a capo: senza questo, va a filo di cella sotto un nome rientrato.
 * L'occhio segue la colonna degli slug — perfettamente allineata a sinistra —
 * e la gerarchia sparisce: 29 voci si leggono piatte, con i «└» sospesi nel
 * vuoto. Il rientro si dà quindi alla cella, e i «&nbsp;» del modello
 * spaziano solo il segno del ramo. */
/* IL PASSO DEV'ESSERE COSTANTE, E NON LO ERA.
   Il primo livello non aveva una regola sua: ereditava l'imbottitura normale
   della cella, `var(--s4)` cioe' 16px, mentre il secondo ne dichiarava 25,6.
   Il primo scalino misurava quindi 9,6px e tutti gli altri 25,6 — misurato nel
   DOM, non dedotto. E il primo scalino e' quello che conta di piu': separa le
   due sezioni radice dai loro figli, cioe' l'unica distinzione che rende
   leggibile un albero di ventinove voci. A 9,6px non si vedeva, e ventinove
   righe si leggevano piatte.
   Ora il passo e' dichiarato una volta e i livelli lo moltiplicano: non si
   puo' sbagliarne uno senza sbagliarli tutti. */
.albero__riga--liv0 > .albero__nome { padding-left: var(--s4); }
.albero__riga--liv1 > .albero__nome { padding-left: calc(var(--s4) + var(--rientro-albero)); }
.albero__riga--liv2 > .albero__nome { padding-left: calc(var(--s4) + 2 * var(--rientro-albero)); }
.albero__riga--liv3 > .albero__nome { padding-left: calc(var(--s4) + 3 * var(--rientro-albero)); }
.albero__riga--liv4 > .albero__nome { padding-left: calc(var(--s4) + 4 * var(--rientro-albero)); }

/* `PROFONDITA_MASSIMA` vale 50, i livelli disegnati erano cinque: al sesto il
   rientro tornava a zero e una voce annidata sembrava una sezione di primo
   livello. Cinque non bastano a coprirlo, ma nove si': oltre, la colonna
   sarebbe comunque finita. L'ultimo livello disegnato non torna indietro. */
.albero__riga--liv5 > .albero__nome { padding-left: calc(var(--s4) + 5 * var(--rientro-albero)); }
.albero__riga--liv6 > .albero__nome { padding-left: calc(var(--s4) + 6 * var(--rientro-albero)); }
.albero__riga--liv7 > .albero__nome { padding-left: calc(var(--s4) + 7 * var(--rientro-albero)); }
.albero__riga--liv8 > .albero__nome { padding-left: calc(var(--s4) + 8 * var(--rientro-albero)); }
.albero__riga--liv9 > .albero__nome { padding-left: calc(var(--s4) + 9 * var(--rientro-albero)); }

/* IL SEGNO DEL RAMO NON DEVE STACCARSI DAL NOME. Con la cella lasciata al
   flusso normale, il «└» e il nome sono due elementi in riga: quando il nome
   e' lungo — «Vasistas Blum Aventos HKi per vetrine Slim» — va a capo e il
   segno resta solo sulla riga sopra, sospeso nel vuoto, con il nome
   incolonnato sotto. Succedeva su quattro righe su ventinove, cioe' proprio
   sulle categorie dal nome piu' lungo, che sono anche le piu' profonde.
   Con la cella a colonne il segno ha la sua e il nome ha la sua: il nome puo'
   andare a capo quanto vuole e resta allineato con se stesso. */
/* Le colonne interne alla cella: il posto del pulsante, il nome, il numero.
   `auto` e non `minmax(0, auto)` sulla seconda — con il minimo a zero la
   colonna si stringeva sotto la misura del testo e il nome traboccava SOTTO
   la pastiglia del conteggio: si leggeva «Compl 2 enti». Il traboccamento di
   una griglia non si vede finche' non ci sono due elementi sulla stessa riga,
   ed e' per questo che era passato. */
.albero__blocco {
    display: grid;
    grid-template-columns: 1.75rem auto auto;
    column-gap: .35rem;
    align-items: baseline;
    justify-content: start;
}

.albero__blocco > a { grid-column: 2; grid-row: 1; }

/* Lo slug sotto, allineato al nome e non al segno del ramo: allineato a
   sinistra l'occhio seguirebbe la colonna degli slug e la gerarchia
   sparirebbe. */
.albero__blocco > .minuta { grid-column: 2 / -1; grid-row: 2; }

/* IL SEGNO DEL RAMO E IL PULSANTE OCCUPANO LO STESSO POSTO, e non e' un
   accidente: dicono la stessa cosa. Dove c'e' qualcosa da aprire comanda il
   pulsante, che e' informativo E premibile; dove non c'e' niente resta il
   segno, che dice soltanto «sto sotto». Tenerli entrambi metteva due simboli
   a tre pixel di distanza per un'informazione sola. */
.albero__blocco:has(.albero__piega) > .albero__rientro { display: none; }

/* Lo slug resta sotto il nome — accanto veniva troncato a «b…», che non
   identifica niente — ma sotto AL NOME, non a filo di cella: allineato al
   segno del ramo l'occhio seguirebbe la colonna degli slug e la gerarchia
   sparirebbe. Costa una riga per categoria, e la si ripaga chiudendo i rami:
   con l'albero collassato le righe visibili sono tre, non ventinove. */
.albero__blocco > .minuta { display: block; }

/* LA COLONNA DEI NOMI SE LA DEVE PRENDERE, LA LARGHEZZA, E QUI SI VEDE
   PERCHE' NON BASTA CHIEDERLA. Con tre azioni per riga, «Ordine» e «Visibile
   a», l'algoritmo automatico lasciava alla prima colonna centonovantadue
   pixel e «Istruzioni di montaggio e regolazioni» usciva su cinque righe.
   Ne' `min-width` ne' `width` su una cella lo impediscono: a layout
   automatico sono suggerimenti che l'algoritmo usa come vuole, e infatti
   sono stati ignorati entrambi — misurato, non dedotto.
   A layout fisso comandano le intestazioni, e comandano davvero. Le colonne
   di servizio prendono il minimo che serve al loro contenuto, che e' noto:
   un numero, due frecce, tre azioni. */
.tabella--albero { table-layout: fixed; }

/* Le percentuali sono misurate sul contenuto reale, non scelte a occhio: a
   layout fisso cio' che non sta nella cella non la allarga, ESCE — e si
   sovrappone alla colonna accanto senza che niente lo segnali. Con «Azioni»
   al 25% le tre voci uscivano sotto la freccia dell'ordine. */
.tabella--albero th:nth-child(1) { width: 43%; }
.tabella--albero th:nth-child(2) { width: 9%; }
.tabella--albero th:nth-child(3) { width: 10.5%; }
.tabella--albero th:nth-child(4) { width: 12.5%; }
.tabella--albero th:nth-child(5) { width: 25%; }

.tabella--albero .albero__ordine,
.tabella--albero .albero__azioni,
.tabella--albero .albero__documenti { white-space: nowrap; }

/* A layout fisso una parola piu' larga della sua colonna esce dal bordo
   invece di allargarla: gli slug lunghi vanno spezzati. */
.tabella--albero .minuta { overflow-wrap: anywhere; }

/* --- L'albero si chiude ------------------------------------------------
   Ventinove righe tutte aperte non sono un albero: sono un elenco lungo con
   dei trattini. Il pulsante compare solo dove c'e' qualcosa da aprire, e
   senza JavaScript non compare affatto — l'albero resta tutto visibile, che
   e' il comportamento di prima e va bene. */

.albero__piega {
    grid-column: 1;
    grid-row: 1;
    justify-self: start;

    width: 1.75rem;
    height: 1.75rem;
    /* `min-height` E NON SOLO `height`: la regola generale dei pulsanti impone
       44px di altezza minima, e `min-height` batte `height`. Senza questa riga
       la piega tornava a 44 e portava con se' l'altezza di ogni riga
       dell'albero — da 57 a 69px per ventinove righe, cioe' trecentocinquanta
       pixel di scorrimento in piu' per un pulsante che deve restare discreto.
       Il bersaglio pieno c'e' lo stesso, ed e' lo strato qui sotto. */
    min-height: 1.75rem;
    padding: 0;

    display: grid;
    place-items: center;

    /* 28px disegnati, 44 sensibili: era il bersaglio piu' piccolo del pannello
       e apre l'unica cosa che rende leggibile un albero di ventinove voci. */
    position: relative;

    color: var(--inchiostro-lieve);
    background: none;
    border: 1px solid transparent;
    border-radius: var(--raggio-piccolo);
    cursor: pointer;

    transition: background var(--tempo-svelto) var(--curva), color var(--tempo-svelto) var(--curva);
}

.albero__piega::after {
    content: "";
    position: absolute;
    inset: -8px;
}

.albero__piega:hover {
    background: rgb(var(--rgb-primario) / .16);
    color: var(--primario);
}

.albero__piega .icona {
    width: 1em;
    height: 1em;
    transition: transform var(--tempo-svelto) var(--curva);
}

.albero__piega[aria-expanded="true"] .icona { transform: rotate(90deg); }

/* Quante voci nasconde un ramo chiuso: senza il numero, chiudere un ramo lo
   fa sembrare vuoto invece che chiuso. */
.albero__nascoste {
    grid-column: 3;
    grid-row: 1;
    justify-self: start;
    margin-left: .4rem;
    font-size: .78rem;
    font-weight: 700;
    color: var(--inchiostro-lieve);
    background: var(--carta);
    border-radius: var(--raggio-pillola);
    padding: 0 .5rem;
}

.albero__rientro {
    grid-column: 1;
    grid-row: 1;
    /* Era `--bordo`, cioe' 1,26:1 sul bianco: il segno del ramo c'era e non si
       vedeva, e la gerarchia restava affidata al solo rientro. Questo e' il
       grigio del testo di servizio portato a meta': si vede, e non compete
       con il nome che accompagna. */
    color: var(--inchiostro-lieve);
    opacity: .5;
    letter-spacing: .1em;
    user-select: none;
}

/* Le sezioni di primo livello reggono la lettura dell'intero elenco: sono
   poche e servono da appiglio per l'occhio. */
.albero__riga--liv0 .albero__nome > a {
    font-weight: 600;
}

.albero__riga--liv0 > td {
    border-top: 1px solid var(--bordo);
}

.albero__riga--liv1 .albero__nome > a { font-weight: 500; }

.albero__riga--liv2 .albero__nome > a,
.albero__riga--liv3 .albero__nome > a,
.albero__riga--liv4 .albero__nome > a { font-weight: 400; }

.albero__documenti {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Zero documenti non è un allarme: è la norma per una sezione, che raccoglie
   e non contiene. Resta leggibile ma non chiama l'attenzione. */
.albero__documenti[data-documenti="0"] { color: var(--inchiostro-lieve); }

.albero__azioni {
    white-space: nowrap;
    font-size: .9rem;
}

.albero__azioni a + a { margin-left: .6rem; }

/* «Vale per tutti i marchi» è un'informazione, non una mancanza: se avesse
   l'aspetto di un campo vuoto il redattore proverebbe a riempirlo, e una
   categoria comune diventerebbe riservata. */
.segno--tutti {
    border-style: dashed;
    color: var(--inchiostro-lieve);
    background: transparent;
}

/* --- Briciole di navigazione ------------------------------------------ */

.briciole {
    margin: -.5rem 0 1rem;
    color: var(--inchiostro-lieve);
    font-size: .9rem;
}

.briciole a { color: inherit; }

.briciole a:hover { color: var(--primario); }

/* --- Pagine collegate e stato corrente -------------------------------- */

.collegate {
    margin: 1rem 0;
    padding: .6rem .9rem;
    background: var(--superficie);
    border: 1px solid var(--bordo);
    border-radius: var(--raggio);
    font-size: .95rem;
}

.stato-attuale {
    margin: .8rem 0;
    padding: .5rem .8rem;
    border-left: 3px solid var(--buono);
    background: var(--buono-carta);
    color: var(--buono);
    border-radius: 0 var(--raggio) var(--raggio) 0;
}

/* --- Dove risponde davvero la vista di un marchio ---------------------- */

/* Il campo «dominio» e il dominio a cui la vista risponde sono due cose
   separate, e il riquadro esiste per tenerle insieme sotto lo stesso titolo:
   sparpagliate fra i campi, si leggerebbero come tre note scollegate. */
.modulo--dominio {
    margin: .4rem 0 1.4rem;
    padding: 1rem 1.2rem;
    background: var(--superficie);
    border: 1px solid var(--bordo);
    border-radius: var(--raggio);
}

.modulo--dominio h3 {
    margin: 0 0 .8rem;
    font-size: 1rem;
}

.modulo--dominio h4 {
    margin: 1.2rem 0 .4rem;
    font-size: .9rem;
    color: var(--inchiostro-lieve);
}

/* L'ultimo avviso non porta con sé il margine inferiore: dentro il riquadro
   diventerebbe uno spazio vuoto prima del bordo. */
.modulo--dominio > :last-child { margin-bottom: 0; }

/* QUANDO NON C'E' NIENTE DA MOSTRARE, IL RIQUADRO SPARISCE E RESTA LA RIGA.
   Su un marchio senza dominio dedicato la sezione si ripiega — il perche' sta
   nel modello — e il ripiegamento ha gia' il suo vestito: fondo, bordo,
   angoli. Lasciandogli intorno anche quello del riquadro si vedevano due
   cornici concentriche, che e' proprio il difetto che il ripiegamento doveva
   togliere. Il contenitore resta nel documento con i suoi attributi `data-`,
   che sono il modo in cui i test leggono lo stato del dominio. */
.modulo--dominio--quieto {
    margin: .4rem 0 1rem;
    padding: 0;
    border: 0;
    background: none;
}

/* --- Moduli delle categorie ------------------------------------------- */

/* Ridichiarano l'imbottitura invece del valore: la barra dei comandi la
   segue senza doverlo sapere. */
.modulo--sposta,
.modulo--marchi {
    --card-x: 1.2rem;
    --card-y: 1.2rem;
    padding: var(--card-y) var(--card-x);
    background: var(--superficie);
    border: 1px solid var(--bordo);
    border-radius: var(--raggio);
}

.modulo--sposta select { max-width: 34rem; }

/* Su schermo stretto la tabella dell'albero non si comprime: si scorre.
   Comprimerla accorpa le colonne e il rientro smette di significare. */
@media (max-width: 720px) {
    .tabella--albero { display: block; overflow-x: auto; }
    .albero__nome { min-width: 14rem; }
}

/* --- Marchi ------------------------------------------------------------
 *
 * Da unire in coda a public/assets/css/pannello.css. Usa le variabili già
 * definite là (--bordo, --carta, --attento, ...) e non ridefinisce nulla.
 *
 * Tre sole classi nuove, e tutte e tre servono a una cosa che nel pannello
 * dei marchi conta più che altrove: rendere leggibile ciò che il redattore
 * deve sapere PRIMA di salvare.
 */

/* Una spiegazione che resta sulla pagina: non è un avviso della richiesta
 * precedente e non deve somigliarci, altrimenti si impara a scartarla con lo
 * sguardo come si scartano i messaggi già letti. */
.nota {
    margin: 0 0 1.25rem;
    padding: .7rem .9rem;
    border-left: 3px solid var(--oro);
    background: var(--superficie);
    border-radius: 0 var(--raggio) var(--raggio) 0;
    font-size: .92rem;
    color: var(--inchiostro-lieve);
}

.nota strong { color: var(--inchiostro); }

.nota code,
.aiuto code,
.tabella code {
    font-size: .92em;
    padding: .05em .3em;
    background: var(--carta);
    border: 1px solid var(--bordo);
    border-radius: 3px;
}

/* L'anteprima del colore. Sta sotto al campo perché si guarda dopo aver
 * scritto, non prima. */
.anteprima {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin-top: .4rem;
}

.campione {
    display: inline-block;
    padding: .35rem .8rem;
    border-radius: var(--raggio);
    border: 1px solid var(--bordo);
    font-weight: 600;
}

/* Il comando principale dell'elenco: la testata non è il menu, e senza
 * questa regola «Nuovo marchio» resta un collegamento in mezzo al testo. */
.testata .azione {
    /* LE STESSE MISURE DEGLI ALTRI COMANDI. Questo era alto 39,2px contro i 44
       di ogni altro pulsante e aveva un raggio di 14px contro i 999 delle
       pastiglie: e' il comando primario di tre pagine su quattro, ed era
       l'unico vestito in un modo suo. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s2);
    min-height: var(--bersaglio);
    padding: var(--s2) var(--s5);
    border-radius: var(--raggio-pillola);
    font-weight: 700;
    text-decoration: none;
    background: var(--primario);
    color: #fff;
    border: 1px solid var(--primario);
    box-shadow: var(--ombra-bottone);
    transition: transform var(--transizione), box-shadow var(--transizione), background var(--transizione);
}

.testata .azione:hover {
    background: var(--primario-scuro);
    transform: translateY(-1px);
    box-shadow: 0 14px 28px rgb(0 0 0 / .18);
    text-decoration: none;
}

.testata .azione:active { transform: translateY(1px); box-shadow: var(--ombra-premuta); }

.testata .azione:hover { background: var(--primario-scuro); }

/* Un comando spento deve SEMBRARE spento: se resta identico a quello attivo,
 * il redattore lo preme e non capisce perché non succede niente. */
.pericolo[disabled] {
    opacity: .5;
    cursor: not-allowed;
}

.pericolo[disabled]:hover {
    background: transparent;
    color: var(--grave);
}

/* --- Redattori ---------------------------------------------------------
 *
 * Da unire in coda a public/assets/css/pannello.css, PRIMA del blocco
 * @media (max-width: 40rem): le regole per gli schermi stretti che stanno in
 * fondo a questo file vanno invece dentro quel blocco.
 *
 * Nessuna variabile nuova: si usano quelle già dichiarate in :root.
 *
 * L'UNICA REGOLA CHE FA UN LAVORO E NON UN ORNAMENTO è `.riga--tu`. Da questa
 * pagina si tolgono gli accessi, e chi confonde la propria riga con quella di
 * un altro si chiude fuori dal pannello: la riga di chi sta guardando deve
 * distinguersi prima che si legga il nome. Il segno «sei tu» dice la stessa
 * cosa a parole, perché il colore da solo non arriva a chi non lo distingue.
 */

.riga--tu {
    /* Filo d'oro a sinistra invece di uno sfondo pieno: si vede scorrendo
       l'elenco e non compete con lo stato «attivo/disattivato». */
    box-shadow: inset 3px 0 0 var(--oro-testo);
}

.tabella tbody tr.riga--tu:hover { background: #fdfaf3; }

.segno--tu {
    border-color: var(--oro-testo);
    color: var(--oro-testo);
    font-weight: 600;
    white-space: nowrap;
}

/* Conteggi allineati a destra: incolonnati si confrontano a colpo d'occhio,
   che è l'unica cosa che si fa con questa colonna. */
.tabella .numero {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/*
 * Le azioni di riga: un collegamento e un modulo con un solo pulsante.
 * Il modulo è `block` per natura e andrebbe a capo da solo, lasciando la
 * colonna alta il doppio delle altre — ed è per questo che qui c'era
 * `display: flex`.
 *
 * MA QUESTA CLASSE STA SUL <td>, E UN <td> RESO FLEX ESCE DAL MODELLO
 * TABELLARE: smette di stirarsi fino all'altezza della riga e si dimensiona
 * sul proprio contenuto. Misurato: 71 pixel contro i 126 delle sorelle, con
 * il bordo inferiore della colonna sfalsato rispetto a tutti gli altri.
 * Nessuno se n'era accorto perché la pagina dove esisteva — i redattori — ha
 * righe basse, dove lo scarto è di pochi pixel; è saltato fuori portando le
 * azioni su documenti e marchi, che hanno righe alte.
 * Il modulo si mette in riga rendendolo `inline-flex`: il <td> resta una
 * cella e fa quello che le celle fanno.
 */
.tabella .azioni {
    white-space: nowrap;
}

.tabella .azioni > * {
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
}

.tabella .azioni form { margin: 0; }

/* IL MOTIVO NON E' UN PULSANTE, e non deve stare sulla sua riga.
   `white-space: nowrap` sulla cella serve a tenere in fila i comandi; su una
   frase di quaranta caratteri produceva un traboccamento che la card ritagliava
   — misurato: scrollWidth 338 contro clientWidth 283, cioe' cinquantacinque
   pixel di testo perduti, «designarne un al» e basta. Va a capo come qualunque
   testo, e prende la riga sotto i comandi. */
.tabella .azioni > .minuta,
.tabella .azioni .azioni__pericolo > .minuta {
    display: block;
    white-space: normal;
    margin-top: var(--s1);
    font-size: .78rem;
    line-height: 1.35;
}

/* IL MOTIVO VA A CAPO DENTRO LA COLONNA, non oltre. Reso `inline-flex` il
   contenitore prendeva la larghezza del suo contenuto piu' lungo — cioe' la
   frase intera — e la cella lo ritagliava lo stesso: il testo andava a capo
   nel punto sbagliato e la prima riga usciva. `max-width: 100%` piu'
   `min-width: 0` sul figlio e' quello che permette a un elemento flex di
   stringersi davvero: senza il secondo, la base `auto` lo tiene largo quanto
   il contenuto e il primo non morde. */
.tabella .azioni .azioni__pericolo {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    max-width: 100%;
    vertical-align: top;
}

.tabella .azioni .azioni__pericolo > .minuta { min-width: 0; }

/* UN SOLO LINGUAGGIO PER LE AZIONI DI RIGA, E SI FA QUI.
   Il pannello ne aveva due: `.azioni`+`.pericolo` su documenti, marchi e
   redattori — pastiglie piene alte 44px — e `.azioni-riga`+`.azione-riga`
   sulle categorie — testo con icona, alto 32. Chi passava da un elenco
   all'altro cambiava interfaccia senza cambiare applicazione. E la pastiglia
   rossa piena era l'elemento piu' appariscente di ogni riga: l'eliminazione,
   cioe' l'unica azione che non si disfa, era anche l'unica che si vedeva.
   L'unificazione si fa in CSS e non nel markup perche' `class="pericolo"` e
   `azioni__pericolo` sono cercate ALLA LETTERA da tre test di integrazione:
   aggiungere una classe a quell'attributo li fa fallire. Quindi le classi
   restano quelle e a cambiare e' come si vestono. */
.tabella .azioni a,
.tabella .azioni button {
    min-height: 2rem;
    padding: var(--s1) var(--s2);

    font-size: .85rem;
    font-weight: 600;
    color: var(--primario);
    background: none;
    border: 1px solid transparent;
    border-radius: var(--raggio-piccolo);
    box-shadow: none;
    text-decoration: none;

    /* 32px disegnati, 44 sensibili: vedi «bersaglio esteso». */
    position: relative;
}

.tabella .azioni a::after,
.tabella .azioni button::after {
    content: "";
    position: absolute;
    inset: -6px -2px;
}

.tabella .azioni a:hover,
.tabella .azioni button:hover:not([disabled]) {
    background: rgb(var(--rgb-primario) / .10);
    border-color: var(--bordo-campo);
    text-decoration: none;
    transform: none;
}

/* Il rosso resta, e resta solo sull'eliminazione: e' il segno, e un segno che
   compare ovunque non e' un segno. Ma e' il colore del TESTO, non un pieno:
   cosi' l'azione che distrugge si riconosce senza essere la piu' evidente
   della riga. */
.tabella .azioni .pericolo {
    color: var(--grave);
    border-color: transparent;
}

.tabella .azioni .pericolo:hover:not([disabled]) {
    background: var(--grave-carta);
    border-color: rgb(155 44 44 / .55);
    color: var(--grave);
}

.tabella .azioni .pericolo[disabled] {
    opacity: .5;
    cursor: not-allowed;
}

/* IL CAMPO FILE NATIVO NON SI STILA: SI SOSTITUISCE.
   «Scegli file — Nessun file selezionato» e' testo scritto dal sistema
   operativo, cambia da macchina a macchina e non si puo' tradurre. Dentro una
   zona di rilascio disegnata era anche la seconda cornice di due concentriche.
   Il rimedio non e' nasconderlo con `display: none` — cosi' sparisce anche
   dalla tastiera e dai lettori di schermo, e il caricamento diventa
   irraggiungibile per chi non usa il mouse. Si ritaglia come `.sr-solo`: resta
   nell'albero di accessibilita', resta raggiungibile con TAB, e ad avere
   l'aspetto e' l'etichetta che gli e' gia' associata con `for`.
   IL FUOCO VA MOSTRATO SULL'ETICHETTA, perche' l'anello sul campo ritagliato
   non lo vedrebbe nessuno: `:focus-within` sulla zona fa il lavoro. */
.caricamento__scelta {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.caricamento__etichetta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s2);

    min-height: var(--bersaglio);
    padding: var(--s2) var(--s5);

    font-weight: 700;
    color: var(--primario);
    background: var(--superficie);
    border: 1px solid var(--bordo-campo);
    border-radius: var(--raggio-pillola);
    cursor: pointer;

    transition: background var(--transizione), border-color var(--transizione),
        box-shadow var(--transizione), transform var(--transizione);
}

.caricamento__etichetta:hover {
    border-color: var(--primario);
    box-shadow: var(--ombra-alzata);
    transform: translateY(-1px);
}

.caricamento__zona:focus-within .caricamento__etichetta {
    outline: 2px solid var(--primario);
    outline-offset: 2px;
}

/* --- Scheda del redattore --------------------------------------------- */

.utente__altro {
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--bordo);
}

/* `.eliminazione` porta già bordo e stacco: dentro questo blocco sarebbero
   due righe di separazione una sull'altra. */
.utente__altro .eliminazione {
    margin-top: .75rem;
    padding-top: 0;
    border-top: 0;
}

.utente__altro .aiuto { max-width: 46rem; }

.modulo--password { max-width: 34rem; }

/* --- Schermi stretti ---------------------------------------------------
 * Da spostare DENTRO il @media (max-width: 40rem) già presente in fondo al
 * foglio: là la tabella diventa un elenco di schede e le righe perdono il
 * bordo laterale su cui si appoggia `.riga--tu`.
 */
@media (max-width: 40rem) {
    .riga--tu {
        box-shadow: none;
        border-left: 3px solid var(--oro-testo);
        padding-left: .5rem;
    }

    /* `text-align` qui non allineerebbe niente: in modalità scheda la cella è
       un `flex`, e il valore è largo quanto il suo contenuto. Ad accostarlo
       all'etichetta è la scatola flessibile, non l'allineamento del testo. */
    .tabella td.numero { justify-content: flex-start; gap: 1rem; }
}

/* --- Leggibilità degli elenchi ----------------------------------------- */

/* Il link di una riga è alto 18px come il suo testo, e WCAG 2.2 (2.5.8, che è
   livello AA) chiede 24. Si allarga con il padding invece che con una misura
   fissa: la riga resta compatta, il bersaglio arriva a 26px.
   NON si usa qui `--bersaglio-minimo` (48px): quella è la misura della vista
   pubblica, che si preme con un dito guantato in cantiere. Il pannello si usa
   con un mouse, e righe alte 48px ne farebbero stare la metà sullo schermo. */
.tabella td a {
    display: inline-block;
    padding-block: .25rem;
    font-weight: 700;
    text-decoration: none;
}

.tabella td a:hover,
.tabella td a:focus-visible {
    text-decoration: underline;
}

/* Le colonne di servizio non si prendono lo spazio del titolo. */
.tabella .stato,
.tabella .segno {
    vertical-align: middle;
}

/* --- Le spiegazioni lunghe, a richiesta --------------------------------
   PERCHÉ ESISTE QUESTO PATTERN — le pagine di questo pannello spiegano molto,
   e fanno bene: le regole del repository sono severe e il rifiuto arriva a
   modulo compilato. Ma tutte le spiegazioni tutte insieme, sempre aperte,
   producono l'effetto opposto di quello voluto: il redattore impara a saltare
   i grigi, e con loro salta anche l'unico avviso che quel giorno contava.

   La riga breve resta sempre; il resto si apre a chi lo cerca. Il testo è
   comunque nel documento — quindi una ricerca nella pagina lo trova, e un
   lettore di schermo può raggiungerlo — non è nascosto, è ripiegato. */

.spiega {
    margin-top: .35rem;
}

.spiega > summary {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    width: fit-content;
    padding: .1rem .55rem;
    font-size: .8rem;
    font-weight: 700;
    color: var(--primario);
    background: rgb(var(--rgb-primario) / .06);
    border-radius: var(--raggio-pillola);
    cursor: pointer;
    list-style: none;
}

/* Safari disegna un suo triangolo che non si toglie con `list-style`. */
.spiega > summary::-webkit-details-marker { display: none; }

.spiega > summary::after {
    content: "\203A";
    display: inline-block;
    font-weight: 900;
    transition: transform var(--transizione);
}

.spiega[open] > summary::after { transform: rotate(90deg); }

.spiega > summary:hover {
    background: rgb(var(--rgb-oro) / .18);
}

.spiega > div {
    margin-top: .4rem;
    padding-left: .8rem;
    border-left: 2px solid var(--bordo);
}

/* ======================================================================
   COMPONENTI — la parte moderna del pannello.
   ======================================================================

   Qui sotto stanno i pezzi che prima non c'erano e i cui difetti si
   vedevano solo aprendo le pagine: le azioni di riga che mancavano su due
   elenchi su quattro, le intestazioni che si possono ordinare (la capacita'
   c'era gia' nel server e non aveva interfaccia), la zona che accetta un
   file rilasciato, il riordino dell'albero.

   Tutto quello che si aggiunge da qui in giu' usa i passi `--s1..--s7`. */

/* --- Icone -------------------------------------------------------------
   Disegnate in `src/Pannello/Icone.php`, tinte con `currentColor`: seguono
   il testo che accompagnano senza che nessuno debba ricordarsi di
   aggiornarle quando cambia un colore. Sempre accanto a una parola, mai al
   posto di una parola: un bersaglio con la sola icona non si capisce, e chi
   usa un lettore di schermo non lo sente proprio. */

.icona {
    width: 1.15em;
    height: 1.15em;
    flex: 0 0 auto;
    /* Le maiuscole di un carattere di sistema non arrivano al bordo alto
       della riga: senza questo ritocco l'icona galleggia sopra il testo. */
    vertical-align: -.18em;
}

/* Dichiarata e mai emessa: qui aveva senso, ma nessun modello la chiedeva.
   Ora la porta il quadrato del formato nell'elenco documenti. */
.icona--grande { width: 1.5em; height: 1.5em; }

/* IL QUADRATO DEL FORMATO, come nella vista pubblica. Non e' l'icona di un
   comando: e' l'insegna del documento, e sta su una piastra che la stacca dal
   nome del file. Il colore e' quello del testo di servizio, non del marchio:
   nel pannello convivono tutti i marchi e un colore solo direbbe una cosa
   falsa. */
/* L'insegna e i dati stanno in riga, e il contenitore e' DENTRO la cella. */
.file {
    display: flex;
    align-items: flex-start;
    gap: var(--s2);
    min-width: 0;
}

.file__dati { min-width: 0; }

.icona--formato {
    width: 1rem;
    height: 1rem;
    padding: .375rem;
    box-sizing: content-box;
    flex: 0 0 auto;

    color: var(--primario);
    background: rgb(var(--rgb-primario) / .08);
    border-radius: var(--raggio-piccolo);
}

/* Sul collegamento esterno il quadrato prende l'oro, come nella vista: un
   video non si stampa e non si consulta con le mani sporche, e la differenza
   si deve vedere prima di leggere. */
.file:has(.segno) .icona--formato {
    color: var(--su-oro);
    background: rgb(var(--rgb-oro) / .30);
}

/* --- Azioni di riga ----------------------------------------------------
   Su documenti e marchi non c'erano: per eliminare un documento bisognava
   aprirlo, e che il titolo fosse un collegamento si scopriva provando.
   Compaiono al passaggio sulle righe larghe ma restano SEMPRE presenti per
   chi arriva da tastiera e per chi tocca lo schermo — un comando che esiste
   solo sotto il mouse non esiste per meta' delle persone. */

.azioni-riga {
    display: flex;
    align-items: center;
    gap: var(--s1);
    justify-content: flex-end;

    /* MAI A CAPO DENTRO UNA RIGA DI TABELLA. Con la colonna dichiarata non
       allargabile — «width: 1%», che e' il modo di dire a una tabella «dai a
       questa colonna il minimo» — il flex interpretava il minimo come
       permesso di impilare, e tre azioni diventavano tre righe alte
       centosessanta pixel. `white-space: nowrap` sulla cella non c'entra
       niente: governa il testo, non gli elementi di un contenitore flex. */
    flex-wrap: nowrap;
}

.azioni-riga form { display: contents; }

.azione-riga {
    display: inline-flex;
    align-items: center;
    gap: var(--s1);

    min-height: 2rem;
    padding: var(--s1) var(--s2);

    font: inherit;
    font-size: .85rem;
    font-weight: 600;
    color: var(--primario);
    background: none;
    border: 1px solid transparent;
    border-radius: var(--raggio-piccolo);
    text-decoration: none;
    cursor: pointer;

    transition: background var(--tempo-svelto) var(--curva),
        border-color var(--tempo-svelto) var(--curva), color var(--tempo-svelto) var(--curva);
}

.azione-riga { position: relative; }

.azione-riga::after {
    content: "";
    position: absolute;
    inset: -6px -2px;
}

.azione-riga:hover {
    background: rgb(var(--rgb-primario) / .10);
    border-color: var(--bordo-campo);
    text-decoration: none;
}

/* RIMOSSO: `.azione-riga--pericolo`, mai applicata da nessun modello. Le tre
   pagine con un'azione distruttiva di riga usano l'ALTRO componente
   (`.azioni` + `.pericolo`), che ora ha lo stesso aspetto: il rosso sul testo
   e non un pieno. Il ruolo che questa classe descriveva esiste, ma lo assolve
   quella. */

.azione-riga[disabled] {
    opacity: .45;
    cursor: not-allowed;
}

/* --- Intestazioni che ordinano ------------------------------------------
   `CriteriDiRicerca` sapeva gia' ordinare e costruire i collegamenti
   conservando i filtri: mancava soltanto il modo di premerli, e l'ordinamento
   si poteva cambiare solo scrivendo la query string a mano.
   La freccia dice in che verso si sta guardando; `aria-sort` lo dice a chi
   non la vede. Sono due canali per la stessa informazione, e servono
   entrambi. */

.ordinabile { cursor: pointer; }

.ordinabile > a {
    display: flex;
    align-items: center;
    gap: var(--s1);

    color: inherit;
    text-decoration: none;
    /* Il bersaglio e' tutta la cella, non le sole lettere: un'intestazione da
       premere larga quanto la parola si manca. */
    margin: calc(var(--s2) * -1) calc(var(--s3) * -1);
    padding: var(--s2) var(--s3);
    border-radius: var(--raggio-piccolo);

    transition: background var(--tempo-svelto) var(--curva), color var(--tempo-svelto) var(--curva);
}

.ordinabile > a:hover {
    color: var(--primario);
    background: rgb(var(--rgb-primario) / .06);
}

/* La colonna su cui si sta ordinando: piena, non sfumata. */
.ordinabile--attiva > a { color: var(--primario); }

.ordinabile__verso {
    /* Lo spazio resta riservato anche per la doppia freccia dello stato
       neutro: senza, la tabella intera si sposta di qualche pixel al primo
       clic, e lo spostamento si nota piu' dell'ordinamento. */
    min-width: 1em;
    text-align: center;
    font-size: .85em;
    /* La doppia freccia compare su OGNI colonna ordinabile: se pesasse quanto
       quella attiva, cinque colonne griderebbero insieme e nessuna direbbe
       piu' dove si sta guardando. */
    /* Era .45, cioe' 2,06:1 sul fondo dell'intestazione: sotto i 3:1 che WCAG
       1.4.11 chiede a un indicatore non testuale, ed e' l'UNICO invito a
       premere l'intestazione. A .7 vale ~3,4:1 e le colonne inattive
       continuano a non gridare. */
    opacity: .7;
}

.ordinabile--attiva .ordinabile__verso { opacity: 1; }

/* --- L'azione che distrugge sta per conto suo --------------------------
   Non basta il colore: chi non distingue i rossi ha comunque bisogno che
   «Elimina» non sia il vicino di casa di «Modifica». La distanza e il
   confine fanno il lavoro che il colore da solo non fa. */
/* Lo spazio fra le azioni: `gap` non vale piu' — il <td> non e' un
   contenitore flex, e non deve esserlo. */
.tabella .azioni > * + * { margin-left: var(--s1); }

.azioni__pericolo {
    padding-left: var(--s2);
    margin-left: var(--s1);
    border-left: 1px solid var(--bordo);
}

/* Quando l'eliminazione e' impedita, accanto al pulsante spento c'e' il
   motivo — «e' il predefinito: designarne un altro». Un pulsante disattivato
   senza motivo e' una porta chiusa senza cartello, e chi la trova prova a
   forzarla. Il motivo va a capo invece di spingere la colonna fino al bordo
   della tabella: `nowrap` vale per le azioni, non per una frase. */
.azioni__pericolo .minuta {
    white-space: normal;
    max-width: 11rem;
    margin-left: var(--s2);
    line-height: 1.3;
}

/* --- La zona che accetta un file rilasciato -----------------------------
   Il riquadro tratteggiato SEMBRAVA una zona di rilascio da sempre e non lo
   era: si poteva solo premere «Scegli file». Ora lo e' davvero, e il pulsante
   resta — chi usa la tastiera non trascina niente, e una zona di rilascio
   senza alternativa e' una funzione che esiste per meta' delle persone.

   ATTENZIONE A `hidden`: l'anteprima e il pulsante di annullamento nascono
   nascosti e li mostra il JavaScript togliendo l'attributo. Un `display`
   dichiarato senza condizioni su quelle classi lo batterebbe — `hidden` vale
   `display: none` come regola dello user agent, e qualunque riga del foglio
   la vince. E' lo stesso inciampo gia' incontrato sull'albero della vista
   pubblica, dove i rami chiusi si riaprivano da soli. */

.caricamento__zona {
    display: grid;
    gap: var(--s2);

    padding: var(--s5);
    text-align: center;

    background: var(--carta);
    border: 2px dashed var(--bordo);
    border-radius: var(--raggio);

    transition: background var(--transizione), border-color var(--transizione);
}

/* Le due dichiarazioni residue del vecchio campo nativo. `justify-self`
   perche' la zona e' una griglia e senza si stira per tutta la larghezza:
   un pulsante largo mille pixel non e' un pulsante, e' una barra. */
.caricamento__etichetta { justify-self: center; }

.caricamento__invito {
    margin: 0;
    font-size: .9rem;
    color: var(--inchiostro-lieve);
}

/* Il segno del rilascio, in cima alla zona. Il tracciato «rilascia» era
   scritto in `Icone.php` e non veniva disegnato da nessuna parte. E' puramente
   decorativo — sotto ci sono un pulsante e una frase che dicono tutto — quindi
   esce `aria-hidden` come tutte le altre. */
.caricamento__segno {
    justify-self: center;
    width: 2rem;
    height: 2rem;
    color: var(--primario);
    opacity: .55;
}

.caricamento__zona--sopra .caricamento__segno {
    color: var(--attento);
    opacity: 1;
}

/* Mentre il file e' sospeso sopra: e' l'unico istante in cui l'interfaccia
   deve dire «lascia pure qui», e deve dirlo forte. */
.caricamento__zona--sopra {
    background: var(--attento-carta);
    border-color: var(--oro);
    border-style: solid;
}

/* Durante il caricamento la zona non accetta piu' niente, e si vede: il
   tratteggio sparisce perche' il tratteggio e' l'invito. */
.caricamento__zona--in-corso {
    border-style: solid;
    border-color: var(--bordo);
    background: var(--superficie);
}

/* Il file scelto, prima e durante l'invio. */
.caricamento__anteprima {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--s2) var(--s3);

    padding: var(--s2) var(--s3);
    background: var(--superficie);
    border: 1px solid var(--bordo);
    border-radius: var(--raggio-piccolo);
}

.caricamento__nome {
    font-weight: 600;
    min-width: 0;
    /* Un nome di file non ha spazi in cui andare a capo: senza questo esce
       dal riquadro e allarga la pagina. */
    overflow-wrap: anywhere;
}

.caricamento__peso {
    font-size: .85rem;
    color: var(--inchiostro-lieve);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.caricamento__annulla {
    justify-self: center;
    min-height: 2.25rem;
    padding-inline: var(--s4);
    font-size: .9rem;
}

.caricamento__stato {
    margin: 0;
    font-size: .9rem;
    color: var(--inchiostro-lieve);
    /* Riservato anche quando e' vuoto: senza, la zona cresce di una riga al
       primo messaggio e tutto il modulo scatta verso il basso. */
    min-height: 1.4em;
}

/* RIMOSSO: «Avanzamento», 22 righe per due classi che nessuno emetteva.
   `avanzamento` in `caricamento.js` e' il nome di una FUNZIONE, non di una
   classe — la percentuale la scrive `.caricamento__stato`. Il costo di un
   blocco cosi' non e' il peso del file: e' che chi legge il foglio crede che
   quella funzione esista, e la cerca. */

/* --- Riordino dell'albero ----------------------------------------------
   L'ordine delle categorie si cambiava scrivendo un numero — 10, 20, 30 —
   in un campo di un altro modulo. Ora si sposta la riga da dove la si sta
   guardando. Le frecce funzionano anche senza JavaScript, perche' sono
   moduli veri: il trascinamento e' un di piu' per chi ha il mouse, non il
   solo modo di farlo. */

.ordina-riga {
    display: inline-flex;
    gap: 2px;
}

.ordina-riga button {
    min-height: 2rem;
    min-width: 2rem;
    padding: 0;

    /* Vedi «bersaglio esteso»: 32px disegnati, 44 sensibili. Due frecce
       adiacenti da 32px con 2px di distanza sono l'invito a premere quella
       sbagliata. */
    position: relative;

    color: var(--inchiostro-lieve);
    background: none;
    border: 1px solid transparent;
    border-radius: var(--raggio-piccolo);

    transition: background var(--tempo-svelto) var(--curva), color var(--tempo-svelto) var(--curva);
}

.ordina-riga button::after {
    content: "";
    position: absolute;
    inset: -6px -4px;
}

.ordina-riga button:hover:not([disabled]) {
    background: rgb(var(--rgb-primario) / .16);
    color: var(--primario);
}

.ordina-riga button[disabled] { opacity: .3; cursor: default; }

/* RIMOSSO: il trascinamento delle righe dell'albero. Diciotto righe di stile
   per un gesto che non e' mai stato scritto — `pannello.js` non contiene un
   solo `dragstart`, `draggable` o `drop`, e nessun modello emette
   `si-trascina`, `bersaglio-sopra`, `bersaglio-sotto` o `impugnatura`.
   Il riordino c'e' e sono le frecce, che funzionano anche senza JavaScript.
   Se un giorno si vorra' il trascinamento, queste righe si riscrivono in dieci
   minuti; finche' non c'e', dicono il falso a chi legge. */

/* --- L'ordine dei documenti --------------------------------------------
   Si decide nell'elenco, non nel modulo: trascinando la riga dalla maniglia,
   o con le frecce — le stesse dell'albero delle categorie, e per la stessa
   ragione. La maniglia la mostra `pannello.js`: senza JavaScript restano le
   frecce, che sono moduli veri. */

.tabella--documenti .posizione { white-space: nowrap; }

.maniglia {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    min-height: 2rem;
    color: var(--inchiostro-lieve);
    cursor: grab;
}

.maniglia:hover { color: var(--primario); }

/* SU UNO SCHERMO A TOCCO LA MANIGLIA SAREBBE UNA PROMESSA FALSA: il
   trascinamento nativo dei navigatori, quasi ovunque, col dito non parte. Si
   toglie, e restano le frecce, che col dito funzionano. */
@media (hover: none) and (pointer: coarse) {
    .maniglia { display: none; }
}

/* La riga in viaggio si vede ancora, ma sbiadita: dice dove finirà senza
   coprire le righe accanto, che sono il riferimento. */
.riga--trascinata > td {
    opacity: .5;
    background: rgb(var(--rgb-primario) / .06);
}

.riga--trascinata .maniglia { cursor: grabbing; }

/* FIN DOVE SI PUO' TRASCINARE. Una riga si sposta solo fra quelle della sua
   categoria — la pagina pubblica, dentro una categoria, non guarda altro — e
   la linea fra un gruppo e il successivo dice dove finisce la corsa. */
/* Solo sulla tabella: sotto i 40rem ogni riga e' una scheda, le schede sono
   gia' separate, e la linea finirebbe sopra ogni campo del primo documento. */
@media (min-width: 40.01rem) {
    .tabella--documenti tr.riga--gruppo > td { border-top: 2px solid rgb(var(--rgb-primario) / .22); }
}

.riordino__aiuto { margin: 0 0 var(--s2); }

/* Riservata anche da vuota, come quella del caricamento: al primo messaggio
   la tabella non deve scattare in basso di una riga. */
.riordino__stato {
    min-height: 1.4em;
    margin: 0 0 var(--s2);
    font-size: .9rem;
    color: var(--inchiostro-lieve);
}

.riordino__stato--successo { color: var(--buono); }
.riordino__stato--attenzione { color: var(--attento); }
.riordino__stato--errore { color: var(--grave); font-weight: 600; }

/* La cella dell'ordine: il numero resta perche' il campo nel modulo continua
   a esistere, ma non e' piu' lui il comando — e' un dato di servizio, e si
   legge come tale. */
.albero__ordine {
    white-space: nowrap;
}

.albero__numero {
    display: inline-block;
    min-width: 2em;
    font-size: .85rem;
    font-variant-numeric: tabular-nums;
    color: var(--inchiostro-lieve);
}

/* «tutti i marchi» compariva ventinove volte su ventinove righe: e' il valore
   predefinito, cioe' l'informazione meno interessante della colonna, e
   ripetuta a quel modo copriva le tre righe che dicevano qualcosa. Resta
   scritto — toglierlo farebbe credere che manchi un'assegnazione, che e'
   l'equivoco che questa pagina esiste per evitare — ma smette di gridare. */
.tabella .segno--tutti {
    background: none;
    border-color: transparent;
    color: var(--inchiostro-lieve);
    font-weight: 400;
    padding-inline: 0;
}

/* --- Chi ha chiesto meno movimento ------------------------------------
   Il sistema operativo lo dichiara, e qui si ubbidisce in un posto solo.
   Le transizioni di questo foglio sono brevi e tutte su `transform` e
   `box-shadow` — nessuna gira da sola, tutte rispondono a un gesto — ma
   «breve» non è una scusa: chi soffre di disturbi vestibolari ha chiesto di
   non vedere le cose muoversi, e il sollevamento di un pixel su ogni card di
   un elenco lungo È movimento.
   Non si azzera la durata a zero con `animation: none`: alcune animazioni
   portano stati (un `open` che si apre) e toglierle del tutto le romperebbe.
   Si riduce a un tempo impercettibile, che conserva il passaggio di stato. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    /* E soprattutto: niente spostamenti. La transizione ridotta a zero
       lascerebbe comunque il salto di posizione, che è proprio la cosa da
       togliere. */
    .principale:hover,
    .principale:active,
    .secondaria:hover,
    .secondaria:active,
    .pericolo:hover,
    button:hover,
    button:active,
    .tabella tbody tr:hover {
        transform: none;
    }
}

/* --- Ripiegamento di ciò che quasi nessuno cambia -----------------------

   NON E' LO STESSO OGGETTO DI `.spiega`. Quello ripiega un TESTO — la
   spiegazione lunga di un campo che resta visibile —, questo ripiega dei
   CAMPI: il modulo del documento chiedeva dodici valori insieme su due
   schermate e mezza, e di quei dodici tre sono predisposizioni che restano
   al loro posto per anni (lingua, ordine, indirizzo pubblico).

   Da chiuso mostra il valore che contiene, e questo e' il punto: un
   ripiegamento che dice solo «Altre opzioni» costringe ad aprirlo per
   sapere se dentro c'e' qualcosa da guardare, e a quel punto tanto valeva
   lasciarlo aperto. Il server lo apre da se' quando un valore non e' quello
   solito (`open` nel modello), perche' nascondere l'unica cosa che val la
   pena vedere e' peggio che non ripiegare affatto. */

.ripiego {
    /* Il fieldset del modulo e' una griglia a due colonne: senza questa riga
       il ripiegamento occuperebbe mezza riga e il campo accanto gli
       resterebbe appiccicato, con il riepilogo tagliato a meta'. */
    grid-column: 1 / -1;
    margin: 0 0 var(--s4);
    border: 1px solid var(--bordo);
    border-radius: var(--raggio-piccolo);
    background: var(--carta);
}

.ripiego > summary {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s1) var(--s3);
    /* `min-height` e non `height`: sono due proprieta' diverse e la regola
       generale sui bersagli vincerebbe comunque. */
    min-height: var(--bersaglio);
    padding: var(--s2) var(--s3);
    cursor: pointer;
    list-style: none;
    border-radius: inherit;
}

.ripiego > summary::-webkit-details-marker { display: none; }

.ripiego > summary::after {
    content: "\203A";
    margin-left: auto;
    font-weight: 900;
    color: var(--inchiostro-lieve);
    transition: transform var(--transizione);
}

.ripiego[open] > summary::after { transform: rotate(90deg); }

.ripiego > summary:hover { background: rgb(var(--rgb-primario) / .05); }

.ripiego > summary:focus-visible {
    outline: 2px solid var(--primario);
    outline-offset: -2px;
}

.ripiego__titolo {
    font-weight: 700;
    font-size: .9rem;
}

/* Il valore corrente e' un dato, non un titolo: monospaziato dove e' un
   indirizzo, sempre piu' tenue del titolo che lo precede. */
.ripiego__valore {
    color: var(--inchiostro-lieve);
    font-size: .85rem;
}

.ripiego[open] > summary {
    border-bottom: 1px solid var(--bordo);
    border-radius: var(--raggio-piccolo) var(--raggio-piccolo) 0 0;
}

/* I campi che stanno dentro non sono piu' figli del fieldset e hanno perso
   la sua griglia: qui se la rifanno, ma in riga — dentro un ripiegamento ci
   vanno i campi brevi, e due campi brevi su due colonne intere sarebbero due
   francobolli in mezzo al vuoto. */
.ripiego > .campo,
.ripiego > .campi-in-riga {
    margin: var(--s3) var(--s4) var(--s4);
}

.ripiego > .campi-in-riga {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s4);
}

.ripiego > .campi-in-riga > .campo { margin: 0; }

/* --- Il gruppo di campi che il formato richiede -------------------------

   Il riquadro non si vede: esiste per poter sparire tutto insieme. Il suo
   margine e' quello che avrebbe avuto l'ultimo campo dentro di lui, cosi'
   togliendolo di mezzo non resta un buco. */

.gruppo-formato > .campo:last-child { margin-bottom: 0; }

/* La nota vive dove viveva il campo di troppo: sopra i due riquadri, cosi'
   si legge prima di arrivare al campo che riguarda. Vuota e' `hidden`, ma il
   nodo resta nel documento — un `aria-live` creato quando ha qualcosa da
   dire non annuncia niente. */
.nota-formato {
    grid-column: 1 / -1;
    margin-bottom: var(--s4);
}

/* I TESTI DI UNA SEZIONE NON SONO CAMPI, e nella griglia a due colonne del
   modulo finivano in celle alterne: sulla scheda del marchio la spunta
   «Marchio acceso» stava a sinistra, la frase che la riguarda a destra, la
   pastiglia della spiegazione sotto a sinistra e la nota del predefinito
   ancora piu' giu' — quattro pezzi dello stesso discorso disposti a
   scacchiera. Un aiuto, una nota o una spiegazione appesi direttamente al
   `fieldset` riguardano la sezione intera: vanno a riga piena, sotto il
   controllo di cui parlano. */
.modulo fieldset > .aiuto,
.modulo fieldset > .nota,
.modulo fieldset > .spiega,
.modulo fieldset > .spunta {
    grid-column: 1 / -1;
}

/* LA RIGA E' PIENA, LA PASTIGLIA NO.
   `grid-column: 1 / -1` qui sopra da' alla spunta la riga intera — ed e'
   giusto, perche' la frase che la riguarda le sta sotto — ma una cella di
   griglia stira anche la SCATOLA: «Marchio acceso» diventava una pastiglia
   azzurra larga 1102px per due parole, che si legge come un campo di testo e
   non come una scelta. Misurato sulla scheda del marchio.
   `justify-self: start` tiene la riga e restituisce la misura: la pastiglia
   torna larga quanto la sua frase, come le spunte dei marchi nella scheda del
   documento — che stanno in un contenitore flessibile e non hanno mai avuto
   il problema. */
.modulo fieldset > .spunta { justify-self: start; }

/* LE PASTIGLIE DELLE SPIEGAZIONI SONO BERSAGLI, e misuravano 23px.
   Sotto i 24 del criterio WCAG 2.5.8, e su una pagina che ora ne porta dieci
   invece di quattro: il difetto c'era già, ripiegare gli aiuti l'ha
   moltiplicato.

   NON si allarga l'area sensibile con lo strato assoluto usato per le azioni
   di riga: sotto il campo «Dominio dedicato» due pastiglie distano SEI pixel,
   e due aree estese si sovrapporrebbero — chi mira alla seconda aprirebbe la
   prima. Qui il bersaglio si alza davvero e le pastiglie si distanziano, che
   e' anche la lettura giusta dell'eccezione di spaziatura del criterio. */
.spiega > summary {
    min-height: 24px;
    padding: .25rem .55rem;
}

/* Due spiegazioni di fila sotto lo stesso campo: 5,6px non bastano a
   separare due bersagli. */
.spiega + .spiega { margin-top: .5rem; }

/* --- Il gruppo governato dal formato ------------------------------------

   UN CONTENITORE CIECO TOGLIE I SUOI FIGLI DALLA GRIGLIA. Avvolgendo la zona
   di caricamento e il percorso in `.gruppo-formato` — per poterli far sparire
   tutti insieme — quei campi hanno smesso di essere figli del `fieldset`, e
   con essi le regole che li mandavano a riga intera: `.campo--caricamento`
   continuava a DICHIARARE `grid-column: 1 / -1`, ma dentro un blocco che
   griglia non e'. Misurato: la zona di rilascio occupava 543px su 1110,
   affiancata al menu del formato come se fossero due campi paritari.
   E' la forma «dichiarazione invece di uso» gia' vista in questo progetto.

   Il rimedio non e' allargare il gruppo e basta: il gruppo deve ESSERE una
   griglia con le stesse colonne del `fieldset`, cosi' ogni campo che ci
   finisce dentro si comporta come si comporterebbe fuori. Un contenitore che
   raccoglie campi senza portarsi dietro il sistema che li dispone e' un
   sistema che vale solo finche' nessuno raggruppa niente. */
.gruppo-formato {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--s5);
    align-items: start;
}

/* IL FORMATO E' LA DOMANDA, NON UN CAMPO FRA GLI ALTRI. Da mezza colonna
   sembrava paritario al gruppo che gli stava accanto, mentre e' quello che
   decide se quel gruppo esiste: una dipendenza si legge dall'alto in basso,
   non da sinistra a destra. Cambiando il menu, poi, cio' che cambiava stava
   nella meta' opposta della riga — fuori dal punto in cui l'occhio guarda.

   Sta su una riga sua, ma il comando non si stira per 1110px: si ferma alla
   sua opzione piu' lunga. Un menu a tendina largo quanto la pagina per
   scegliere fra cinque voci brevi e' un campo di testo mancato. */
.campo--misurato { grid-column: 1 / -1; }

.modulo .campo--misurato select {
    width: fit-content;
    max-width: 100%;
}

/* ======================================================================
   LA LIBRERIA DEI FILE
   ======================================================================

   IL PROBLEMA CHE RISOLVE. Il file del documento si sceglieva da un
   `<select>` con dentro tutti i file dell'archivio: con duecento schede
   caricate — e ne arrivano da ogni marchio — quella tendina e' una colonna
   di duecento righe, senza ricerca, senza il peso a colpo d'occhio, senza il
   tipo. Su Windows si naviga battendo la prima lettera del nome, che e'
   l'unica cosa che di un file non si ricorda mai.

   Il pannello elenca gli stessi file con una riga ciascuno e un campo che
   filtra mentre si scrive. Le voci restano pulsanti di scelta nativi: il
   modulo continua a funzionare senza JavaScript, e chi usa un lettore di
   schermo sente «3 di 205» senza che nessuno abbia dovuto scriverlo.
   ---------------------------------------------------------------------- */

/* Lo stacco che il componente non eredita più da `.campo`: il contenitore ha
   smesso di portarne la classe, perché le regole dei campi vincevano su
   queste — il perché sta scritto nel modello, accanto al `<div>`. */
.libreria {
    position: relative;
    margin: 0 0 var(--s4);
}

.libreria .aiuto { display: block; margin-top: .3rem; }

/* Il posto dell'etichetta di un campo, su un gruppo che un campo unico non
   ce l'ha piu': il testo che dice «Il file» non puo' essere una `<label>` se
   i controlli sono duecentosei. */
.libreria__etichetta {
    display: block;
    font-weight: 600;
    font-size: .9rem;
    margin-bottom: .3rem;
}

/* --- La scheda del file scelto ---------------------------------------- */

/* CHE COSA C'E' ADESSO, senza aprire niente. E' la sola riga che il redattore
   guarda nel novanta per cento dei casi: il pannello si apre per cambiare. */
.libreria__scelto {
    display: flex;
    align-items: center;
    gap: var(--s3);
    padding: var(--s3) var(--s4);
    border: 1px solid var(--bordo-campo);
    border-radius: var(--raggio-piccolo);
    background: var(--superficie);
}

.libreria__insegna {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--raggio-piccolo);
    background: rgb(var(--rgb-primario) / .08);
    color: var(--primario);
}

/* `min-width: 0` o il nome lungo sfonda la riga invece di accorciarsi: dentro
   un contenitore flessibile la misura minima non e' zero, e' il contenuto. */
.libreria__testo {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .1rem;
    flex: 1 1 auto;
}

/* IL NOME NON VA A CAPO: SI ACCORCIA. Un nome di file e' una parola sola di
   sessanta caratteri, e a capo occuperebbe tre righe dicendo la stessa cosa.
   Il nome intero resta nell'elenco, dove c'e' spazio. */
.libreria__nome {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.libreria__nome--vuoto { font-weight: 500; color: var(--inchiostro-lieve); }

.libreria__dati {
    font-size: .85rem;
    color: var(--inchiostro-lieve);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Il comando non si stringe mai: e' l'unica via per aprire il pannello, e a
   restringere la finestra sparirebbe prima il pulsante del nome del file. */
.libreria__apri { flex: 0 0 auto; white-space: nowrap; }

/* --- Il pannello ------------------------------------------------------- */

/* UN `<dialog>` E NON UN RIQUADRO QUALUNQUE, per quello che porta con se':
   strato superiore, velo, `Esc` che chiude, fuoco trattenuto dentro e resto
   della pagina reso inerte. Riscritte a mano, sono quattro cose che si
   sbagliano, e la quarta la sbagliano tutti. */
.libreria__pannello {
    width: min(46rem, calc(100vw - 2rem));
    max-height: min(42rem, calc(100vh - 4rem));
    padding: 0;
    border: 0;
    border-radius: var(--raggio);
    background: var(--superficie);
    color: var(--inchiostro);
    box-shadow: var(--ombra-alzata);
    overflow: hidden;
}

/* La colonna del pannello: testa e piede fermi, elenco che scorre. Senza
   questa griglia il piede finisce in fondo a duecento righe, cioe' dove
   nessuno lo trova. */
.libreria__pannello[open] {
    display: grid;
    grid-template-rows: auto auto auto minmax(0, 1fr) auto;
}

.libreria__pannello::backdrop {
    background: rgb(15 23 42 / .45);
    backdrop-filter: blur(2px);
}

.libreria__testa {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s4);
    padding: var(--s4) var(--s5);
    border-bottom: 1px solid var(--bordo);
}

.libreria__intestazione {
    margin: 0;
    font-size: 1.05rem;
}

/* Un bersaglio con la sola icona: 44px, ed e' etichettato con `aria-label`
   nel modello — un pulsante muto non lo annuncia nessuno. */
.libreria__chiudi {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--bersaglio);
    height: var(--bersaglio);
    border: 1px solid transparent;
    border-radius: var(--raggio-pillola);
    background: transparent;
    color: var(--inchiostro-lieve);
    cursor: pointer;
    transition: background var(--transizione), color var(--transizione);
}

.libreria__chiudi:hover {
    background: rgb(var(--rgb-primario) / .08);
    color: var(--primario);
}

/* --- La ricerca -------------------------------------------------------- */

.libreria__ricerca {
    position: relative;
    padding: var(--s4) var(--s5) var(--s2);
}

/* L'etichetta c'e' e non si vede: il campo ha gia' il suo invito scritto
   dentro, ma un segnaposto non e' un'etichetta — sparisce appena si scrive,
   e chi torna sul campo dopo dieci secondi non sa piu' che cosa ci stava
   cercando. Fuori schermo, non `display: none`, o non la legge nessuno. */
.libreria__etichetta-ricerca {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.libreria__lente {
    position: absolute;
    left: calc(var(--s5) + var(--s3));
    top: 50%;
    transform: translateY(-40%);
    color: var(--inchiostro-lieve);
    pointer-events: none;
}

/* L'imbottitura a sinistra fa posto alla lente: senza, il testo ci passa
   sopra alla terza lettera. */
.libreria__campo {
    width: 100%;
    font: inherit;
    padding: var(--s3) var(--s4) var(--s3) calc(var(--s4) + 1.6rem);
    border: 1px solid var(--bordo-campo);
    border-radius: var(--raggio-piccolo);
    background: var(--superficie);
    color: inherit;
    transition: border-color var(--transizione), box-shadow var(--transizione);
}

.libreria__campo:focus-visible,
.libreria__campo:focus {
    outline: none;
    border-color: var(--primario);
    box-shadow: 0 0 0 3px rgb(var(--rgb-primario) / .18);
}

.libreria__conteggio {
    margin: 0;
    padding: 0 var(--s5) var(--s2);
    font-size: .85rem;
    color: var(--inchiostro-lieve);
}

/* --- L'elenco ---------------------------------------------------------- */

/* `overscroll-behavior: contain` o la rotellina, arrivata in fondo
   all'elenco, si porta dietro la pagina sotto al velo. */
.libreria__elenco {
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0 var(--s4) var(--s2);
}

.libreria__voce {
    display: flex;
    align-items: center;
    gap: var(--s3);
    min-height: var(--bersaglio);
    padding: var(--s2) var(--s3);
    border-radius: var(--raggio-piccolo);
    cursor: pointer;
    transition: background var(--transizione);
}

.libreria__voce:hover { background: rgb(var(--rgb-oro) / .10); }

/* IL PULSANTE DI SCELTA NON SI VEDE, MA C'E'. Tolto con `display: none`
   sparirebbe anche dalla tastiera e dai lettori di schermo, e con lui la
   navigazione a frecce dentro il gruppo — che e' l'unica ragione per cui
   queste righe sono pulsanti di scelta e non pulsanti. Qui e' trasparente e
   sovrapposto alla riga: resta focalizzabile, e il segno della selezione lo
   danno il fondo e la spunta. */
.libreria__radio {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.libreria__voce:has(.libreria__radio:checked) {
    background: rgb(var(--rgb-primario) / .10);
}

/* L'ANELLO DI FUOCO STA SULLA RIGA, non sul controllo invisibile: chi
   tabula dentro l'elenco deve vedere dove si trova, e il controllo e' un
   pixel trasparente. */
.libreria__voce:has(.libreria__radio:focus-visible) {
    outline: 3px solid var(--primario);
    outline-offset: 2px;
}

.libreria__voce .libreria__insegna {
    width: 2rem;
    height: 2rem;
}

/* Nell'elenco il nome puo' andare a capo: la riga e' larga, e troncare
   `base-forno-standard-h72-maggiorata.pdf` a meta' toglie proprio la parte
   che distingue un file dal suo vicino. */
.libreria__voce .libreria__nome,
.libreria__voce .libreria__dati {
    white-space: normal;
    overflow: visible;
    overflow-wrap: anywhere;
}

/* La crocetta della voce vuota è grigia, e resta grigia anche quando la
   scheda fuori dal pannello la clona: la classe viaggia con l'insegna. */
.libreria__voce--nessuno .libreria__insegna,
.libreria__insegna--vuota {
    background: #eceff1;
    color: var(--inchiostro-lieve);
}

/* Il file che sta in elenco solo perche' e' quello del documento: un filo
   d'oro a sinistra, e la sua nota lo dice a parole. */
.libreria__voce--fuori { border-left: 3px solid var(--oro); }

/* LA SPUNTA E' IL SEGNO DELLA SCELTA, e il fondo colorato da solo non
   basterebbe: WCAG 1.4.1 non vuole che il colore sia l'unica cosa che
   distingue uno stato. Occupa il suo posto anche da spenta, cosi' la riga
   non si sposta di venti pixel nel momento in cui la si sceglie. */
.libreria__spunta {
    flex: 0 0 auto;
    color: var(--primario);
    visibility: hidden;
}

.libreria__voce:has(.libreria__radio:checked) .libreria__spunta { visibility: visible; }

.libreria__niente {
    margin: 0;
    padding: var(--s5);
    color: var(--inchiostro-lieve);
    text-align: center;
}

/* --- Il piede ---------------------------------------------------------- */

/* DICE CHE COSA SI STA PORTANDO VIA. Il pannello si chiude e la scelta
   resta: senza questa riga bisogna chiuderlo per sapere che cosa si e'
   scelto, e riaprirlo se non era quello. */
.libreria__piede {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s4);
    padding: var(--s4) var(--s5);
    border-top: 1px solid var(--bordo);
    background: var(--superficie-tenue, #f7f9fa);
}

.libreria__eco {
    margin: 0;
    min-width: 0;
    font-size: .9rem;
    color: var(--inchiostro-lieve);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.libreria__eco strong { color: var(--inchiostro); }

/* Su un telefono il pannello prende tutto: un riquadro centrato con dodici
   pixel di velo intorno e' un riquadro che non si vede. */
@media (max-width: 40rem) {
    .libreria__pannello {
        width: 100vw;
        max-width: none;
        max-height: 100vh;
        height: 100vh;
        border-radius: 0;
        margin: 0;
    }

    .libreria__testa,
    .libreria__ricerca,
    .libreria__piede { padding-left: var(--s4); padding-right: var(--s4); }

    .libreria__lente { left: calc(var(--s4) + var(--s3)); }

    /* Il nome del file e il pulsante non stanno sulla stessa riga a 390px:
       il pulsante finisce sotto, largo quanto la scheda. */
    .libreria__scelto { flex-wrap: wrap; }
    .libreria__apri { flex: 1 1 100%; justify-content: center; }
}

/* Chi ha chiesto meno movimento non vuole nemmeno il velo che sfuoca. */
@media (prefers-reduced-motion: reduce) {
    .libreria__pannello::backdrop { backdrop-filter: none; }
    .libreria__voce { transition: none; }
}

/* --- La libreria delle categorie ---------------------------------------

   Lo stesso componente dei file, con un elenco che ha una forma in più.

   A RIPOSO È L'ALBERO: ogni voce rientra di un passo per livello, le sezioni
   di primo livello hanno il nome pieno, e il percorso non si scrive — lo dice
   già il rientro. CERCANDO DIVENTA PIATTO: le voci di contorno spariscono, il
   rientro direbbe il falso, e ogni riga mostra invece dove sta.

   Il livello arriva dal server come numero in `--livello`; qui si decide
   quanto vale. */
.libreria--categorie .libreria__voce {
    padding-left: calc(var(--s3) + var(--livello, 0) * 1.5rem);
}

.libreria--categorie .libreria__elenco--cercando .libreria__voce {
    padding-left: var(--s3);
}

/* Le sottocategorie hanno la cartella più piccola e il nome più leggero: su
   trenta righe tutte uguali l'occhio non trova le sezioni. */
.libreria--categorie .libreria__voce .libreria__nome { font-weight: 500; }
.libreria--categorie .libreria__voce--sezione .libreria__nome { font-weight: 700; }

.libreria--categorie .libreria__elenco:not(.libreria__elenco--cercando) .libreria__voce:not(.libreria__voce--sezione):not(.libreria__voce--nessuno) .libreria__insegna {
    width: 1.5rem;
    height: 1.5rem;
}

/* Il percorso si legge solo cercando. La nota — a chi è riservata, in che
   lingua è — si legge sempre: è quella che evita l'errore. */
.libreria--categorie .libreria__elenco:not(.libreria__elenco--cercando) .libreria__percorso {
    display: none;
}

.libreria--categorie .libreria__elenco--cercando .libreria__percorso + .libreria__nota::before {
    content: " · ";
}

/* --- L'anteprima di logo e favicon -------------------------------------
 *
 * PERCHE' — nel campo si scrive `marchi/cucineturi-logo.png` e non succede
 * niente di visibile: si salva, il pannello dice di si', e se il percorso e'
 * sbagliato la vista pubblica scrive il nome del marchio al posto del logo,
 * senza un errore. E' il terzo divario di questa pagina — dopo il dominio e
 * il predefinito — e l'unico che si chiude mostrando la cosa invece di
 * spiegarla.
 *
 * LO SFONDO E' A SCACCHI perche' i loghi sono PNG con la trasparenza: su
 * fondo bianco un logo bianco non si distingue da un'immagine che non c'e'.
 * -------------------------------------------------------------------- */

.immagine {
    /* IL RIQUADRO SI FERMA AL CONTENUTO. Steso per tutta la larghezza del
       campo erano 543 pixel di scacchi intorno a un logo da 48: un fondo
       decorativo che si prende piu' spazio della cosa che deve far vedere. */
    width: fit-content;
    max-width: 100%;

    display: flex;
    align-items: center;
    gap: var(--s3);
    margin-top: var(--s2);
    padding: var(--s2) var(--s3);
    border: 1px solid var(--bordo);
    border-radius: var(--raggio-piccolo);
    background-color: var(--superficie);
    background-image:
        linear-gradient(45deg, rgb(var(--rgb-primario) / .06) 25%, transparent 25%),
        linear-gradient(-45deg, rgb(var(--rgb-primario) / .06) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgb(var(--rgb-primario) / .06) 75%),
        linear-gradient(-45deg, transparent 75%, rgb(var(--rgb-primario) / .06) 75%);
    background-size: 14px 14px;
    background-position: 0 0, 0 7px, 7px -7px, -7px 0;
}

/* L'immagine si adatta al riquadro invece di dettarne l'altezza: un logo da
   duemila pixel di lato, incollato per sbaglio, spingerebbe fuori schermo
   tutto il resto del modulo. */
.immagine__prova {
    flex: 0 0 auto;
    max-width: 12rem;
    max-height: 3rem;
    object-fit: contain;
}

.immagine--minuscola .immagine__prova {
    max-width: 2rem;
    max-height: 2rem;
}

/* La riga di stato prende quel che resta e non spinge: un percorso lungo la
   fa andare a capo dentro il riquadro, non oltre. */
.immagine .minuta {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* CHE COSA NON VA SI DICE COL COLORE DELL'ERRORE, non con un colore qualunque:
   e' la stessa tinta con cui questa pagina dice tutto il resto che non va. */
.immagine--rotta {
    border-color: var(--grave);
    background-color: var(--grave-carta);
}

.immagine--rotta .minuta { color: var(--grave); }

/* Un'immagine che non si apre non lascia il segno del riquadro rotto: lo
   toglie di mezzo del tutto, o resterebbe l'icona di immagine mancante del
   navigatore accanto alla frase che dice la stessa cosa. */
.immagine--rotta .immagine__prova { display: none; }

/* --- Logo e favicon: caricare invece di scrivere ------------------------

   Il titolo del gruppo ha l'aspetto dell'etichetta di un campo ma NON E' UN
   `<label>`: i comandi del gruppo sono due — il pulsante di caricamento e il
   campo del percorso — e ognuno ha gia' la sua. Un'etichetta legata a uno
   solo dei due farebbe aprire la finestra dei file a chi clicca sul titolo
   cercando il percorso. Il gruppo e' `role="group"` con questo titolo come
   nome, che e' cio' che un lettore di schermo annuncia entrando. */
.campo__titolo {
    display: block;
    font-weight: 600;
    font-size: .9rem;
}

/* AFFIANCATI, NON A RIGA INTERA. `.campo--caricamento` va a riga intera
   perche' nel documento la zona e' una sola ed e' il campo principale. Qui
   le zone sono due e paritarie: a riga intera finivano una sotto l'altra, e
   la pagina cresceva di 493px — misurato — per due riquadri larghi 1110px
   con in mezzo un pulsante da 139. Il doppio della classe batte la regola
   della riga intera per peso, non per posizione nel foglio. */
.campo--caricamento.campo--immagine { grid-column: auto; }

/* Dentro il gruppo l'anteprima segue la griglia: il suo margine superiore
   serviva quando stava sotto un campo di testo, qui raddoppierebbe lo
   spazio che il `gap` gia' mette.

   L'ALTEZZA E' LA STESSA PER LOGO E FAVICON perche' stanno affiancati: il
   riquadro del favicon — immagine da 2rem — era 13px piu' basso di quello del
   logo, e le due zone di caricamento sotto partivano sfalsate. Misurato, non
   stimato: 1025 contro 1012 dal bordo alto. La misura e' quella del riquadro
   del logo, immagine da 3rem piu' l'imbottitura. */
.campo--immagine .immagine {
    margin-top: 0;
    min-height: calc(3rem + 2 * var(--s2) + 2px);
}

/* IL PERCORSO E' IL RIPIEGO, e si vede. Stesso disegno dei ripiegamenti
   della pagina — chi ha aperto «Da dove si servono i file» riconosce il
   gesto — ma in un corpo piu' piccolo, perche' qui e' un dettaglio del
   campo, non una sezione. */
.ripiego--percorso { margin: 0; }

.ripiego--percorso > summary {
    font-size: .85rem;
    font-weight: 600;
}

.ripiego--percorso > div {
    padding: var(--s3);
}

.ripiego--percorso .aiuto { margin-bottom: 0; }
