/* ============================================================================
   PALETTE D'ACCENTO
   ============================================================================
   Il tema (chiaro / bilanciato / scuro) decide gli sfondi e i grigi.
   L'accento (viola / verde / arancione) decide UN SOLO colore, quello delle
   azioni e delle evidenziazioni.

   Sono due assi indipendenti: 3 temi × 3 accenti, gestiti da due attributi
   distinti su <html> (data-theme e data-accent), non da nove varianti scritte
   a mano. Aggiungere un quarto accento significa aggiungere un blocco qui,
   senza toccare nient'altro.

   Regola: il colore serve per l'azione primaria, la selezione e lo stato.
   Prima di questa versione gli hover erano ciano mentre il primario era viola:
   due famiglie di colore che si contendevano l'attenzione nella stessa schermata.
   Ora l'hover è una velatura dell'accento corrente, qualunque esso sia.
   ============================================================================ */

/* Ogni accento dichiara i propri toni in modo esplicito, invece di ricavarli tutti dalla
   stessa formula: a parità di valore HSL colori diversi hanno luminosità percepite molto
   diverse. L'arancione a saturazione piena "brucia" molto prima del verde, e il verde
   scurisce prima del viola. Una formula unica dava un arancione cupo sul tema chiaro e
   sbiadito su quello scuro, e un verde troppo pallido sullo scuro. */

:root,
[data-accent="violet"] {
    --accent-h: 249;
    --accent-s: 45%;

    /* toni per i temi chiaro e bilanciato */
    --accent-strong: hsl(249 45% 47%);
    --accent-deep:   hsl(249 45% 38%);
    --accent-soft:   hsl(249 60% 95%);
    --accent-softer: hsl(249 60% 91%);
    --accent-ink:    hsl(249 46% 36%);

    /* toni per il tema scuro: devono staccare dal fondo senza abbagliare */
    --accent-lit:       hsl(249 62% 70%);
    --accent-lit-hover: hsl(249 66% 77%);
    --accent-lit-ink:   hsl(249 70% 82%);
}

[data-accent="green"] {
    --accent-h: 158;
    --accent-s: 52%;

    --accent-strong: hsl(158 52% 33%);
    --accent-deep:   hsl(158 54% 26%);
    --accent-soft:   hsl(158 48% 94%);
    --accent-softer: hsl(158 46% 88%);
    --accent-ink:    hsl(158 58% 25%);

    /* Schiarito come il viola il verde diventa pastello e perde corpo: qui resta
       più basso e più saturo. */
    --accent-lit:       hsl(158 50% 50%);
    --accent-lit-hover: hsl(158 52% 57%);
    --accent-lit-ink:   hsl(158 48% 64%);
}

[data-accent="orange"] {
    --accent-h: 22;
    --accent-s: 90%;

    /* Sul chiaro serve un tono più alto: sotto il 50% l'arancione internazionale vira
       al marrone e smette di essere riconoscibile. */
    --accent-strong: hsl(22 90% 53%);
    --accent-deep:   hsl(22 88% 45%);
    --accent-soft:   hsl(22 88% 95%);
    --accent-softer: hsl(22 85% 90%);
    /* Il testo su fondo tenue resta scuro: con una tinta così satura è l'unico modo
       per avere contrasto sufficiente. */
    --accent-ink:    hsl(22 80% 34%);

    /* Sullo scuro va tenuto BASSO, non alto: schiarito diventa pesca. */
    --accent-lit:       hsl(24 85% 58%);
    --accent-lit-hover: hsl(24 88% 64%);
    --accent-lit-ink:   hsl(26 85% 70%);
}

/* --- Sui temi chiari l'accento entra nei token già usati dal resto del CSS --- */
:root,
[data-theme="light"],
[data-theme="balanced"] {
    --primary: var(--accent-strong);
    --primary-hover: var(--accent-deep);
    --primary-focus: hsl(var(--accent-h) var(--accent-s) 45% / 0.18);
    --accent: var(--accent-strong);

    --btn-primary-bg: var(--accent-soft);
    --btn-primary-bg-hover: var(--accent-softer);
    --btn-primary-text: var(--accent-ink);

    /* Un tempo ciano: ora è l'accento appena accennato. */
    --hover-tint: hsl(var(--accent-h) var(--accent-s) 45% / 0.07);
    --sidebar-hover-bg: hsl(var(--accent-h) var(--accent-s) 45% / 0.09);
    --sidebar-hover-text: var(--accent-ink);
}

/* --- Sul tema scuro si usano i toni "lit" dichiarati da ciascun accento --- */
[data-theme="dark"] {
    --primary: var(--accent-lit);
    --primary-hover: var(--accent-lit-hover);
    --primary-focus: hsl(var(--accent-h) 60% 60% / 0.30);
    --accent: var(--accent-lit);

    --btn-primary-bg: hsl(var(--accent-h) 55% 55% / 0.20);
    --btn-primary-bg-hover: hsl(var(--accent-h) 55% 55% / 0.30);
    --btn-primary-text: var(--accent-lit-ink);

    --hover-tint: hsl(var(--accent-h) 55% 62% / 0.11);
    --sidebar-hover-bg: hsl(var(--accent-h) 55% 62% / 0.15);
    --sidebar-hover-text: #ffffff;
}

/* ============================================================================
   TIPOGRAFIA — tre taglie, non undici
   ============================================================================
   Prima c'erano dimensioni scritte a mano un po' ovunque (0.78, 0.8, 0.82,
   0.85, 0.9, 1.1 rem...). Tre livelli bastano e rendono le pagine coerenti
   senza doverci pensare ogni volta.

   Lexend è disegnata per la leggibilità: nasce da studi sulla fluenza di
   lettura ed è una scelta utile per un software usato anche da studenti con
   difficoltà di lettura. È servita da locale: nessuna chiamata a un CDN, così
   il programma funziona identico anche senza rete.
   ============================================================================ */
:root {
    --font-ui: "Lexend", "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;

    /* Tre taglie, ciascuna con un compito preciso. La regola che le tiene insieme è che
       la taglia dipende dal RUOLO dell'elemento, mai dal contenitore in cui si trova: due
       campi compilabili hanno lo stesso corpo che stiano in un modale, in una griglia o in
       una colonna. Prima non era così — il campo della domanda risultava più piccolo delle
       opzioni solo perché stava dentro un contenitore diverso. */
    --text-sm: 0.8125rem;   /* 13px — etichette, note, metadati, testo di aiuto */
    --text-md: 0.9375rem;   /* 15px — testo corrente e TUTTI i controlli: campi, pulsanti, tabelle */
    --text-lg: 1.25rem;     /* 20px — titoli di sezione */

    /* Il testo che lo studente LEGGE non è interfaccia: è contenuto. Una domanda e le sue
       risposte si leggono per minuti, non si scorrono con l'occhio come un'etichetta, e
       meritano un corpo un po' più generoso — come già faceva la v1.6 con i suoi 1,05 rem.
       Tenerlo fuori dalle tre taglie dell'interfaccia è una distinzione di ruolo, non
       un'eccezione: cresce insieme alle preferenze di lettura, come le altre. */
    --text-reading: 1.0625rem;   /* 17px — testo di domande e risposte nella prova */

    /* Aspetto dei campi compilabili, in un posto solo. */
    --field-bg: var(--surface-muted);
    --field-border: var(--border);

    --line-tight: 1.35;
    --line-normal: 1.6;

    /* --- Spaziatura: meno bordi, più aria ---
       Le schede erano riquadri con bordo su fondo colorato. Qui il bordo
       diventa l'eccezione e la separazione la fa lo spazio. */
    --space-1: 0.375rem;
    --space-2: 0.75rem;
    --space-3: 1.25rem;
    --space-4: 2rem;
    --space-5: 3rem;

    --radius: 10px;
    --radius-sm: 7px;

    /* Distanza fra l'etichetta di un campo e il campo stesso. Serve anche a calcolare
       gli allineamenti fra colonne che hanno l'etichetta e colonne che non ce l'hanno. */
    --label-gap: 0.4rem;

    /* Una sola elevazione, riservata a ciò che galleggia davvero (modali, menu). */
    --shadow-float: 0 12px 32px rgba(20, 24, 38, 0.14);
}

[data-theme="dark"] {
    --shadow-float: 0 12px 32px rgba(0, 0, 0, 0.45);
}

/* ============================================================================
   ACCESSIBILITÀ
   ============================================================================
   Attivabili dal pannello Accessibilità (lato docente) e dal controllo discreto
   nella barra della prova (lato studente, indipendente dal tempo aggiuntivo). */

[data-text-size="large"]  { --text-sm: 0.9375rem; --text-md: 1.0625rem; --text-lg: 1.4375rem; --text-reading: 1.25rem; }
[data-text-size="xlarge"] { --text-sm: 1.0625rem; --text-md: 1.25rem;   --text-lg: 1.75rem;   --text-reading: 1.5rem; }

[data-reading-font="atkinson"] {
    --font-ui: "Atkinson Hyperlegible", "Lexend", system-ui, sans-serif;
}

/* Interlinea e spaziatura fra lettere più generose: è l'accorgimento con
   l'effetto maggiore sulla leggibilità per chi ha dislessia, più del font. */
[data-reading-spacing="loose"] {
    --line-normal: 1.9;
    --line-tight: 1.6;
    letter-spacing: 0.02em;
    word-spacing: 0.08em;
}

[data-contrast="high"] {
    --text-muted: var(--text-main);
    --border: currentColor;
}

/* Chi ha impostato nel sistema la riduzione delle animazioni non deve vederle. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Il focus da tastiera deve essere sempre visibile: prima spariva su diversi
   controlli, rendendo l'applicazione inutilizzabile senza mouse. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* ============================================================================
   LIVELLO DI RIFINITURA
   ============================================================================
   Caricato DOPO admin.css: agisce per sovrascrittura, senza dover riscrivere le
   2.700 righe esistenti. Fa tre cose:
   1. applica il font unico e le tre taglie tipografiche;
   2. toglie bordi e ombre dove non servono e rimette lo spazio al loro posto;
   3. definisce i pochi componenti nuovi (scelta del colore, controllo studente).
   ============================================================================ */

body,
button, input, select, textarea {
    font-family: var(--font-ui);
}

body {
    font-size: var(--text-md);
    line-height: var(--line-normal);
    -webkit-font-smoothing: antialiased;
}

/* --- Tre taglie, non undici --------------------------------------------------- */
h1 { font-size: var(--text-lg); font-weight: 600; line-height: var(--line-tight); letter-spacing: -0.01em; }
h2 { font-size: var(--text-lg); font-weight: 600; line-height: var(--line-tight); }
h3 { font-size: var(--text-md); font-weight: 600; line-height: var(--line-tight); }
label, .hint-text, .upload-hint, small { font-size: var(--text-sm); }
button, input, select, textarea, td, th { font-size: var(--text-md); }

/* --- Meno bordi, più aria ------------------------------------------------------
   Le schede erano riquadri con bordo su fondo colorato: molte cornici ravvicinate
   creano un reticolo che affatica. Ora la scheda è una superficie, e a separare
   è lo spazio. Il bordo resta solo dove distingue davvero (campi compilabili). */
.card,
.stat-card,
.panel,
.settings-list,
.quiz-picker-list {
    border: none;
    box-shadow: none;
    border-radius: var(--radius);
    padding: var(--space-3);
}

.card + .card,
.panel + .panel { margin-top: var(--space-3); }

.main-content { padding: var(--space-4); }

h1 + *, h2 + * { margin-top: var(--space-2); }
h1, h2 { margin-bottom: var(--space-2); }

/* Le righe di impostazione si separano con una linea sottile, non con una scatola. */
.settings-row {
    border: none;
    border-bottom: 1px solid var(--border);
    padding: var(--space-2) 0;
}
.settings-row:last-child { border-bottom: none; }

/* Tabelle: righe leggibili senza griglia completa. */
table { border-collapse: collapse; }
th, td { border-left: none; border-right: none; padding: var(--space-2) var(--space-2); }
thead th {
    border-bottom: 1px solid var(--border);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--text-muted);
    text-transform: none;
    letter-spacing: 0;
}
tbody tr { border-bottom: 1px solid var(--border); }
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: var(--hover-tint); }

/* Una sola elevazione, e solo per ciò che galleggia davvero. */
.modal-content, .user-menu-dropdown, .rich-symbol-panel { box-shadow: var(--shadow-float); }

/* --- Progressive disclosure a un solo livello ---------------------------------
   Prima le opzioni avanzate erano un <details> dentro un modale dentro un wizard.
   Il blocco resta, ma smette di sembrare una terza scatola annidata. */
.launch-advanced-details {
    border: none;
    border-top: 1px solid var(--border);
    margin-top: var(--space-2);
    padding-top: var(--space-1);
    background: none;
}
.launch-advanced-details > summary {
    cursor: pointer;
    padding: var(--space-2) 0;
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--text-muted);
    list-style: none;
}
.launch-advanced-details > summary::-webkit-details-marker { display: none; }
.launch-advanced-details > summary::before {
    content: "›";
    display: inline-block;
    margin-right: 0.5em;
    transition: transform 0.15s ease;
}
.launch-advanced-details[open] > summary::before { transform: rotate(90deg); }
.launch-advanced-details > summary:hover { color: var(--primary); }

/* --- Scelta del colore nel menu utente ----------------------------------------- */
.accent-swatch {
    width: 20px;
    height: 20px;
    padding: 0;
    margin-left: 5px;
    border-radius: 50%;
    border: 2px solid transparent;
    background: var(--swatch);
    cursor: pointer;
    vertical-align: middle;
}
.accent-swatch.selected {
    border-color: var(--text-main);
    box-shadow: 0 0 0 2px var(--bg-card) inset;
}

/* --- Timer della prova ---------------------------------------------------------
   Neutro per quasi tutta la durata. Giallo negli ultimi cinque minuti (avviso),
   rosso nell'ultimo (urgenza). Un timer allarmante dall'inizio è solo rumore. */
#exam-timer.mid-time {
    color: var(--cell-pending-text, #8a5b12);
    background: var(--cell-pending-bg, #fdf1d8);
}
#exam-timer.low-time {
    color: var(--cell-wrong-text, #b23b34);
    background: var(--cell-wrong-bg, #fbe7e6);
}
#exam-timer.mid-time, #exam-timer.low-time {
    border-radius: var(--radius-sm);
    padding: 0.15em 0.5em;
}

/* --- Controllo accessibilità nella barra della prova ----------------------------
   Discreto per scelta: uno studente non deve dover segnalare a tutta la classe che
   sta ingrandendo il testo. */
.a11y-mini {
    position: relative;
}
.a11y-mini-panel {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    min-width: 210px;
    padding: var(--space-2);
    background: var(--bg-card, #fff);
    border-radius: var(--radius);
    box-shadow: var(--shadow-float);
    display: none;
    z-index: 60;
    text-align: left;
}
.a11y-mini-panel.open { display: block; }
.a11y-mini-panel label {
    display: block;
    font-size: var(--text-sm);
    color: var(--text-muted);
    margin: var(--space-1) 0 2px;
}
.a11y-mini-panel select { width: 100%; }

/* ============================================================================
   BARRA LATERALE E ACCENTO
   ============================================================================
   Il tema "bilanciato" ha una barra laterale piena, in gradiente. Prima quel
   gradiente era viola scritto a mano: cambiando accento restava viola mentre
   tutto il resto diventava verde o arancione. Ora deriva anch'esso dall'accento,
   così i tre colori valgono su tutti e tre i temi.

   Le due tappe del gradiente sono la stessa tinta a due luminosità diverse:
   cambiando accento cambia solo la tonalità, non il carattere della barra.
   ============================================================================ */

[data-theme="balanced"] {
    --sidebar-bg: linear-gradient(180deg,
        hsl(var(--accent-h) var(--accent-s) 53%) 0%,
        hsl(var(--accent-h) var(--accent-s) 38%) 100%);
    --sidebar-text: #ffffff;
    --sidebar-text-muted: hsl(var(--accent-h) 55% 88%);
    --sidebar-border: hsl(var(--accent-h) var(--accent-s) 60%);
    /* Su fondo pieno l'evidenziazione è una velatura chiara, non una seconda tinta:
       colorare sopra un colore saturo produce sempre un accostamento sgradevole. */
    --sidebar-hover-bg: rgba(255, 255, 255, 0.16);
    --sidebar-hover-text: #ffffff;
    --sidebar-shadow: none;
}

/* L'arancione internazionale è molto luminoso: alla stessa luminosità degli altri
   la barra risulterebbe abbagliante e il testo bianco poco leggibile. */
[data-theme="balanced"][data-accent="orange"] {
    --sidebar-bg: linear-gradient(180deg,
        hsl(var(--accent-h) var(--accent-s) 46%) 0%,
        hsl(var(--accent-h) var(--accent-s) 33%) 100%);
    --sidebar-text-muted: hsl(var(--accent-h) 60% 90%);
}

/* Sul tema scuro la barra resta scura: l'accento la attraversa appena, quel
   tanto che basta a farla appartenere alla stessa famiglia del resto. */
[data-theme="dark"] {
    --sidebar-bg: linear-gradient(180deg,
        hsl(var(--accent-h) 32% 20%) 0%,
        hsl(var(--accent-h) 22% 13%) 100%);
    --sidebar-border: hsl(var(--accent-h) 22% 26%);
}

/* Sul tema chiaro la barra è bianca: l'accento compare solo su ciò che è
   selezionato o sotto il puntatore. */
[data-theme="light"] {
    --sidebar-bg: var(--bg-card);
    --sidebar-text: var(--text-main);
    --sidebar-text-muted: var(--text-muted);
    --sidebar-border: var(--border);
}

/* --- Voce di menu attiva -------------------------------------------------------
   Definita qui una volta sola, con la stessa specificità delle regole per tema che
   stavano in admin.css. Il criterio è sempre lo stesso: riempimento tenue e testo
   scuro sui fondi chiari, riempimento chiaro e testo colorato sui fondi pieni. */
[data-theme] .sidebar .tab-btn.active,
.sidebar .tab-btn.active {
    font-weight: 600;
    opacity: 1;
    box-shadow: none;
}

/* Sidebar bianca: riempimento tenue dell'accento, testo scuro dello stesso accento. */
[data-theme="light"] .sidebar .tab-btn.active {
    background: var(--accent-soft);
    color: var(--accent-ink);
}

/* Sidebar piena (gradiente dell'accento): il riempimento bianco è l'unico che regge
   su tutte e tre le tinte, e il testo riprende l'accento. */
[data-theme="balanced"] .sidebar .tab-btn.active {
    background: #ffffff;
    color: var(--accent-deep);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.14);
}

/* Sidebar scura: velatura chiara dell'accento e testo nel tono "lit". */
[data-theme="dark"] .sidebar .tab-btn.active {
    background: hsl(var(--accent-h) 50% 60% / 0.20);
    color: var(--accent-lit-ink);
}

/* ============================================================================
   LATO STUDENTE — palette propria
   ============================================================================
   Il colore d'accento scelto dal docente vale per il pannello di gestione, non
   per la pagina della prova. Lo studente non ha scelto nulla e non deve trovarsi
   un'interfaccia arancione o verde solo perché il docente preferisce quel colore:
   sulla schermata di una verifica serve un colore neutro, calmo e costante.
   Resta quindi il blu originale, uguale per tutti.
   ============================================================================ */

.join-body,
.exam-body,
.live-player-body {
    --primary: #3b6fe0;
    --primary-hover: #2f5cc4;
    --primary-focus: rgba(59, 111, 224, 0.18);
    --accent: #3b6fe0;
    --hover-tint: rgba(59, 111, 224, 0.07);
    --btn-primary-bg: #e8eefc;
    --btn-primary-bg-hover: #d8e3fa;
    --btn-primary-text: #23459b;
}

/* --- Form di accesso: etichetta SOPRA il campo, campo a tutta larghezza ------
   Il livello di rifinitura, applicandosi anche a queste pagine, aveva stretto i
   campi e portato l'etichetta di fianco. Qui la disposizione è dichiarata in
   modo esplicito, così non dipende più da cosa viene ereditato. */
.join-card .field,
.exam-body .field {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.4rem;
    margin-bottom: 1rem;
}

.join-card .field > label,
.exam-body .field > label {
    display: block;
    width: 100%;
    margin: 0;
    font-size: var(--text-sm);
    color: var(--text-muted);
}

.join-card .field > input,
.join-card .field > select,
.join-card .field > textarea,
.exam-body .field > input,
.exam-body .field > select,
.exam-body .field > textarea {
    width: 100%;
    box-sizing: border-box;
    font-size: var(--text-md);
}

/* ============================================================================
   CORREZIONI PUNTUALI
   ============================================================================ */

/* Il pallino di scelta della risposta corretta era schiacciato in ovale: dentro
   una riga flex l'input si lascia comprimere se non gli si vieta esplicitamente.
   flex non basta da solo, serve anche fissare le due dimensioni. */
.option-radio,
.option-radio-wrap input[type="checkbox"],
.option-radio-wrap input[type="radio"] {
    flex: 0 0 auto;
    width: 1.15rem;
    height: 1.15rem;
    min-width: 1.15rem;
    min-height: 1.15rem;
    aspect-ratio: 1 / 1;
    border-radius: 50%;
    padding: 0;
    margin: 0;
}
.option-radio-wrap {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
}

/* Le voci del menu Account devono avere tutte la stessa forma: icona, testo,
   eventuale valore a destra. Prima la riga del colore era un blocco a sé, con
   allineamento e spaziatura diversi da tutte le altre. */
.user-menu-item,
.user-menu-row {
    display: flex;
    font-family: var(--font-ui);
    font-weight: 500;
    line-height: var(--line-tight);
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.55rem 0.9rem;
    text-align: left;
    background: none;
    border: none;
    color: inherit;
    font-size: var(--text-md);
}
.user-menu-row { cursor: default; }
.user-menu-item:hover { background: var(--hover-tint); }
.user-menu-row .nav-icon,
.user-menu-item .nav-icon {
    flex: 0 0 auto;
    width: 1.25rem;
    display: inline-flex;
    justify-content: center;
}
.user-menu-row .user-menu-row-value {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

/* --- Pulsanti con la sola icona ------------------------------------------------
   Nella barra della prova convivono pulsanti con testo ("Calcolatrice") e pulsanti
   con la sola icona (preferenze di lettura). Senza una larghezza propria questi
   ultimi ereditano il padding pensato per il testo e l'icona resta spostata a
   sinistra invece che al centro. */
.btn-icon-only {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.35rem;
    min-width: 2.35rem;
    padding: 0;
    gap: 0;
}

/* Le icone hanno un margine destro per staccarsi dall'etichetta ("🖩 Calcolatrice").
   In un pulsante senza etichetta quel margine sposta l'icona a sinistra del centro:
   il contenuto è centrato, ma il contenuto comprende anche lo spazio vuoto a destra. */
.btn-icon-only > i,
.btn-icon-only .ti {
    margin: 0;
    line-height: 1;
}
.btn-tool > i { line-height: 1; }

/* L'icona dentro le voci di menu deve occupare una colonna fissa, altrimenti le
   etichette non si allineano fra una riga e l'altra. */
.user-menu-item .nav-icon,
.user-menu-row .nav-icon,
.tab-btn .nav-icon {
    flex: 0 0 1.25rem;
    width: 1.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* --- Stati vuoti ----------------------------------------------------------------
   "Nessuna prova svolta per questo filtro" e simili: sono messaggi, non celle di
   tabella, e vanno al centro dello spazio che occupano. */
.empty-state,
.no-results,
td.empty-state,
tbody tr.empty-row td {
    text-align: center;
    color: var(--text-muted);
    padding: var(--space-4) var(--space-2);
}

/* ============================================================================
   SOVRAPPOSIZIONE DEI POPUP
   ============================================================================
   Tutti i modali avevano lo stesso z-index, quindi a decidere chi sta sopra era
   l'ordine nel file HTML: la conferma di eliminazione compariva SOTTO la finestra
   da cui era stata aperta, semplicemente perché scritta prima nel template.

   Qui viene fissata una scala esplicita, e in admin.js un osservatore alza
   automaticamente l'ultimo modale aperto: così vale per qualunque combinazione,
   comprese quelle che verranno aggiunte in futuro.
   ============================================================================ */
:root {
    --z-modal: 1000;      /* finestre normali */
    --z-modal-top: 1100;  /* conferme: nascono sempre sopra a un'altra finestra */
    --z-toast: 1200;      /* avvisi: devono restare visibili sopra a tutto */
}

.modal { z-index: var(--z-modal); }
#confirm-modal, .modal-confirm { z-index: var(--z-modal-top); }
#toast, .toast { z-index: var(--z-toast); }


/* ============================================================================
   TEMA SCURO — fondi neutri, non violacei
   ============================================================================
   I fondi del tema scuro erano indaco fissi (#12121f, #1c1c30, #22224a): scelti
   quando l'unico accento era il viola. Con l'accento verde o arancione l'intera
   interfaccia restava violacea e i due colori si contendevano lo sguardo.

   Ora i fondi prendono la tonalità dell'accento corrente a saturazione bassissima:
   restano sostanzialmente grigi, ma "appartengono" alla stessa famiglia del colore
   scelto invece di litigarci. Con il viola il risultato è quasi identico a prima;
   con verde e arancione l'insieme torna coerente.
   ============================================================================ */
[data-theme="dark"] {
    --bg-dark:       hsl(var(--accent-h) 12% 9%);
    --bg-card:       hsl(var(--accent-h) 11% 13%);
    --bg-darker:     hsl(var(--accent-h) 13% 7%);
    --surface-muted: hsl(var(--accent-h) 11% 13%);
    --border:        hsl(var(--accent-h) 10% 24%);
    --text-main:     hsl(var(--accent-h) 15% 96%);
    --text-muted:    hsl(var(--accent-h) 8% 66%);

    --sidebar-bg: linear-gradient(180deg,
        hsl(var(--accent-h) 16% 16%) 0%,
        hsl(var(--accent-h) 13% 11%) 100%);
    --sidebar-text: hsl(var(--accent-h) 15% 96%);
    --sidebar-text-muted: hsl(var(--accent-h) 8% 66%);
    --sidebar-border: hsl(var(--accent-h) 10% 22%);
}

/* --- Gradiente della barra sul tema bilanciato ---------------------------------
   L'arancione partiva da un tono così basso da leggersi come marrone, e arrivava a
   uno così acceso da risultare aggressivo: troppa distanza fra le due tappe. Qui
   l'escursione è ridotta e la partenza alzata, per tutti e tre gli accenti. */
[data-theme="balanced"] {
    --sidebar-bg: linear-gradient(180deg,
        hsl(var(--accent-h) var(--accent-s) 52%) 0%,
        hsl(var(--accent-h) var(--accent-s) 42%) 100%);
}

[data-theme="balanced"][data-accent="orange"] {
    /* Saturazione un po' più bassa e tappe ravvicinate: resta arancione dall'alto
       in basso, senza virare al marrone e senza abbagliare. */
    --sidebar-bg: linear-gradient(180deg,
        hsl(24 76% 56%) 0%,
        hsl(21 72% 47%) 100%);
    --sidebar-text-muted: hsl(24 60% 93%);
}

[data-theme="balanced"][data-accent="green"] {
    --sidebar-bg: linear-gradient(180deg,
        hsl(160 44% 38%) 0%,
        hsl(158 48% 29%) 100%);
    --sidebar-text-muted: hsl(158 40% 90%);
}

/* --- Quale logo su quale fondo -------------------------------------------------
   Il logo ha colori propri: ciano e giallo nella versione per fondi scuri, viola e
   giallo in quella per fondi chiari. Sul tema bilanciato la barra è di un colore
   pieno che cambia con l'accento, e il ciano su arancione è un accostamento che non
   regge. Lì si usa la versione monocromatica bianca, che funziona con tutti e tre. */
.logo-img.logo-for-color-bg { display: none; }

[data-theme="balanced"] .sidebar .logo-img.logo-for-dark-bg,
[data-theme="balanced"] .sidebar .logo-img.logo-for-light-bg { display: none; }
[data-theme="balanced"] .sidebar .logo-img.logo-for-color-bg { display: block; }

/* Sul tema scuro il fondo è ormai un grigio neutro: il logo a colori ci sta bene e
   resta preferibile, perché è quello che identifica il prodotto. */
[data-theme="dark"] .sidebar .logo-img.logo-for-color-bg { display: none; }

/* ============================================================================
   TESTO FORMATTATO
   ============================================================================ */

/* Barra a comparsa: una sola per pagina, si posiziona sopra il campo attivo. */
.rich-bar {
    position: absolute;
    display: none;
    align-items: center;
    gap: 2px;
    padding: 4px;
    background: var(--bg-card);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-float);
    z-index: 1150;   /* sopra i modali: i campi da formattare stanno quasi sempre lì dentro */
}
.rich-bar.visible { display: flex; }

.rich-bar-btn {
    min-width: 30px;
    height: 30px;
    padding: 0 6px;
    border: none;
    border-radius: 6px;
    background: none;
    color: var(--text-main);
    font-size: var(--text-sm);
    line-height: 1;
    cursor: pointer;
}
.rich-bar-btn:hover { background: var(--hover-tint); color: var(--primary); }
.rich-bar-sep { width: 1px; height: 18px; margin: 0 4px; background: var(--border); }

.rich-bar-symbols {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    display: grid;
    grid-template-columns: repeat(8, 28px);
    gap: 2px;
    padding: 6px;
    background: var(--bg-card);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-float);
}
.rich-bar-symbols[hidden] { display: none; }
.rich-symbol {
    width: 28px; height: 28px; padding: 0;
    border: none; border-radius: 5px;
    background: none; color: var(--text-main);
    font-size: var(--text-md); cursor: pointer;
}
.rich-symbol:hover { background: var(--hover-tint); }

/* Formula non disegnata (KaTeX assente o sintassi errata): resta leggibile come
   sorgente, perché uno studente deve poter comunque capire la domanda anche quando
   il docente ha sbagliato a scriverla. */
.math-fallback {
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 0.95em;
    padding: 0 0.2em;
    background: var(--surface-muted);
    border-radius: 4px;
}

/* Nel testo delle domande apice e pedice non devono alterare l'interlinea. */
.question-text sub, .question-text sup,
.opt-text sub, .opt-text sup { line-height: 0; font-size: 0.75em; }

/* --- Arancione: stesso schema degli altri accenti -------------------------------
   Il pulsante primario resta "fondo tenue + testo dello stesso colore", come per viola
   e verde: la coerenza fra i tre accenti conta più del contrasto massimo.

   Il testo è però un arancione vero, non un marrone: hsl(21 88% 42%) è tre gradini
   sotto al colore primario, quindi si distingue dal fondo restando riconoscibilmente
   arancione. Il contrasto è 4,05:1 sul fondo tenue — sotto la soglia AA di 4,5:1 per il
   testo normale, ma sopra quella di 3:1 valida per il testo in grassetto, che è come i
   pulsanti sono resi. Scendere sotto il 39% porterebbe il contrasto in regola e il
   colore nel marrone: chi ha bisogno di più contrasto lo ottiene dal pannello
   Accessibilità, che alza il contrasto su tutta l'interfaccia. */
[data-accent="orange"] {
    --accent-ink: hsl(21 88% 42%);
}

/* ============================================================================
   EDITOR CON RESA IMMEDIATA
   ============================================================================
   Il campo originale resta nel DOM e conserva i marcatori: tutto il codice che
   legge .value continua a funzionare. A schermo si vede solo l'editor.

   L'ASPETTO dell'editor (bordo, sfondo, spaziature, altezza) NON è dichiarato qui:
   viene copiato dal campo che sostituisce, al momento della creazione. Ogni contesto
   stilizza i propri campi in modo diverso — il modale del pool, il creatore di prove,
   le opzioni di risposta — e spesso lo fa con selettori discendenti che su un <div>
   non si applicherebbero. Imporre un aspetto unico scardinava l'impaginazione di
   ciascun contesto. Qui restano solo i comportamenti che il campo non poteva avere.
   ============================================================================ */

.rich-source {
    /* `fixed` e non `absolute`, e larghezza con !important: la tecnica precedente
       («absolute, width:1px») veniva sconfitta da regole più specifiche come
       `.field select { width:100% }` — l'elemento nascosto restava largo 960px,
       assolutamente posizionato OLTRE il bordo destro del modale, e regalava a ogni
       finestra una barra di scorrimento orizzontale che nessun ritocco alle parti
       visibili poteva togliere. Un elemento `fixed` in alto a sinistra, qualunque
       larghezza gli venga imposta, non entra nel calcolo dello scroll di nessun
       antenato: il bug non può ripresentarsi per specificità. */
    position: fixed !important;
    top: 0 !important; left: 0 !important;
    width: 1px !important; height: 1px !important;
    padding: 0 !important; margin: 0 !important;
    overflow: hidden !important; clip: rect(0 0 0 0);
    white-space: nowrap; border: 0 !important;
    opacity: 0; pointer-events: none;
}

.rich-editor {
    outline: none;
    overflow-wrap: anywhere;
    white-space: pre-wrap;
    cursor: text;
}
.rich-editor:focus {
    border-color: var(--primary) !important;
    box-shadow: 0 0 0 3px var(--primary-focus) !important;
}
.rich-editor:empty::before {
    content: attr(data-placeholder);
    color: var(--text-muted);
    pointer-events: none;
}
.rich-editor sub, .rich-editor sup { line-height: 0; font-size: 0.75em; }

/* Le formule sono elementi atomici: si selezionano e si cancellano come un carattere. */
.rich-editor .math-inline {
    display: inline-block;
    padding: 0 3px;
    border-radius: 4px;
    background: var(--hover-tint);
    cursor: pointer;
    user-select: all;
}
.rich-editor .math-inline:hover { outline: 1px solid var(--primary); }

/* Pulsante formula nella barra: è l'azione meno ovvia, quindi la sola evidenziata. */
.rich-bar-btn--accent { color: var(--primary); font-weight: 600; }
.rich-bar-btn.attivo { background: var(--hover-tint); color: var(--primary); }

/* --- Popup della formula ------------------------------------------------------- */
.formula-modal-content { max-width: 620px; width: 100%; }

.formula-preview {
    min-height: 74px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-2);
    margin-bottom: var(--space-2);
    background: var(--surface-muted);
    border-radius: var(--radius-sm);
    font-size: 1.15rem;
    overflow-x: auto;
}
.formula-preview-empty { color: var(--text-muted); font-size: var(--text-sm); }
.formula-preview--error { color: var(--danger); font-size: var(--text-sm); }

.formula-source {
    width: 100%;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
}

.formula-palette {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--space-2);
    margin-top: var(--space-2);
    max-height: 230px;
    overflow-y: auto;
}
.formula-group-title {
    font-size: var(--text-sm);
    color: var(--text-muted);
    margin-bottom: 4px;
}
.formula-group-items { display: flex; flex-wrap: wrap; gap: 4px; }
.formula-chip {
    min-width: 34px;
    height: 32px;
    padding: 0 8px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-card);
    color: var(--text-main);
    font-size: var(--text-md);
    cursor: pointer;
}
.formula-chip:hover { border-color: var(--primary); color: var(--primary); }

/* ============================================================================
   CONTROLLI: UN SOLO CORPO, UN SOLO ASPETTO
   ============================================================================
   Il corpo del testo di un campo deve dipendere dal suo RUOLO, non da dove si
   trova. Prima il campo della domanda risultava più piccolo delle opzioni solo
   perché stava dentro un contenitore diverso, e l'editor restava senza bordo
   perché le regole erano scritte con selettori di elemento (`input, textarea`)
   che su un `<div>` non fanno presa.

   Qui `.rich-editor` compare accanto ai campi veri, così l'aspetto è definito
   una volta sola e vale per entrambi. La spaziatura interna resta invece
   specifica del contesto: nei campi a crescita automatica deve combaciare al
   pixel con quella del gemello invisibile che ne detta l'altezza.
   ============================================================================ */

input,
select,
textarea,
button,
.rich-editor {
    font-family: var(--font-ui);
    font-size: var(--text-md);
}

/* L'ASPETTO dei campi (bordo, sfondo, angoli) NON si dichiara qui. Una regola generale
   avrebbe specificità più alta delle regole di contesto e rimetterebbe il bordo anche ai
   campi che lo tolgono apposta perché annidati dentro un contenitore già bordato — è così
   che il campo dei punti si era ritrovato con due bordi. L'editor eredita invece lo stesso
   trattamento del campo che sostituisce, perché è nominato accanto a `textarea` in ognuna
   delle regole che li riguardano (vedi admin.css ed exam.css). */

/* Le etichette e i testi di aiuto restano alla taglia piccola ovunque. */
label,
.hint-text,
.upload-hint,
.upload-label,
small {
    font-size: var(--text-sm);
}


/* ============================================================================
   TESTO SEGNAPOSTO
   ============================================================================
   Il segnaposto non è contenuto: è un suggerimento su cosa scrivere. Se ha lo
   stesso peso visivo del testo vero, un campo vuoto sembra pieno. Qui è ricavato
   dal colore del testo con una trasparenza, così si adatta da solo al tema
   chiaro e a quello scuro senza doverne dichiarare due. */
:root {
    --text-placeholder: color-mix(in srgb, var(--text-muted) 62%, transparent);
}

/* Ripiego per i browser senza color-mix: un grigio dichiarato per tema. */
@supports not (color: color-mix(in srgb, red 50%, transparent)) {
    :root, [data-theme="light"], [data-theme="balanced"] { --text-placeholder: #a8aebd; }
    [data-theme="dark"] { --text-placeholder: #6b7186; }
}

::placeholder { color: var(--text-placeholder); opacity: 1; }
:-ms-input-placeholder { color: var(--text-placeholder); }
.rich-editor:empty::before { color: var(--text-placeholder); }

/* Con il contrasto elevato il segnaposto torna pienamente leggibile: chi ha attivato
   quell'impostazione ha bisogno di leggerlo, non di distinguerlo dal contenuto. */
[data-contrast="high"] { --text-placeholder: var(--text-muted); }

/* ============================================================================
   CAMPO NUMERICO
   ============================================================================
   Il bordo sta sull'involucro, non sul campo: così valore, unità di misura e
   frecce appaiono dentro un'unica cornice invece di essere tre elementi
   accostati. Vedi static/numberfield.js per il comportamento. */

.number-field {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex: 0 0 auto;
    height: var(--control-height, 38px);
    padding: 0 0.3rem 0 0.6rem;
    background: var(--field-bg, var(--surface-muted));
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}
.number-field:focus-within {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-focus);
}
.number-field > input {
    border: none;
    background: transparent;
    padding: 0;
    height: auto;
    width: 3.2rem;
    text-align: right;
    font-size: var(--text-md);
    color: var(--text-main);
}
.number-field > input:focus { box-shadow: none; outline: none; }
.number-field-suffix {
    color: var(--text-muted);
    font-size: var(--text-sm);
    white-space: nowrap;
}
.number-field-spinner {
    display: flex;
    flex-direction: column;
    width: 1.1rem;
    height: 1.9rem;
    flex: 0 0 auto;
}
.number-field-btn {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    height: auto;
    min-height: 0;
    border: none;
    background: none;
    color: var(--text-muted);
    font-size: var(--text-sm);
    line-height: 1;
    cursor: pointer;
}
.number-field-btn:hover { color: var(--primary); background: none; }
.number-field-btn > i { margin: 0; }

/* ============================================================================
   IMPOSTAZIONI: INTERRUTTORI E RIGHE COMPATTE
   ============================================================================
   Un interruttore ha un'etichetta breve e, sotto, una spiegazione in piccolo.
   Prima la spiegazione stava fra parentesi nell'etichetta stessa — che la
   allungava — oppure occupava tre righe a corpo pieno sotto il controllo. */

/* L'interruttore sta a DESTRA, l'etichetta a sinistra: è la disposizione di tutti gli
   elenchi di impostazioni del programma (vedi `.settings-row`), e averne due diverse nella
   stessa applicazione costringe a cercare il controllo invece di trovarlo dov'è sempre. */
.setting-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin: 0.9rem 0;
    cursor: pointer;
}
.setting-toggle > input {
    flex: 0 0 auto;
    order: 2;              /* l'interruttore va a destra qualunque sia l'ordine nel markup */
}
.setting-toggle-text {
    display: block;
    order: 1;
    font-size: var(--text-md);
    color: var(--text-main);
    line-height: var(--line-tight);
}
.setting-toggle-hint {
    display: block;
    margin-top: 0.25rem;
    font-size: var(--text-sm);
    font-weight: 400;
    color: var(--text-muted);
    max-width: 46ch;   /* righe corte: una spiegazione larga quanto lo schermo non si legge */
}

/* Due impostazioni brevi affiancate invece che impilate con spazio vuoto in mezzo. */
.settings-inline-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: var(--space-3);
    align-items: start;
    padding: var(--space-3);
    margin-bottom: var(--space-3);
    background: var(--surface-muted);
    border-radius: var(--radius);
}
/* Solo le etichette vere prendono l'aspetto da etichetta: se la regola colpisse anche
   il <label> che avvolge un interruttore, il testo della funzione ("Lode oltre il
   punteggio pieno") assumerebbe il corpo e il colore di un commento. */
.settings-inline-item > label:not(.setting-toggle) {
    display: block;
    margin-bottom: 0.4rem;
    font-size: var(--text-md);
    color: var(--text-main);
}
/* Ogni voce ha la stessa forma: etichetta, controllo, spiegazione sotto. La spiegazione va
   SOTTO e non accanto, perché accanto costringe a leggerla prima di capire che cosa fa il
   controllo — e con due voci affiancate produce due allineamenti diversi nella stessa riga. */
.settings-inline-controls {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    min-height: var(--control-height);
}
.settings-inline-controls-label { font-size: var(--text-md); color: var(--text-main); }
.settings-inline-hint {
    margin: 0.45rem 0 0;
    font-size: var(--text-sm);
    color: var(--text-muted);
    line-height: var(--line-tight);
    max-width: 46ch;
}
.settings-inline-hint code {
    padding: 0.05rem 0.3rem;
    background: var(--bg-card);
    border-radius: 4px;
}

/* ============================================================================
   PARAMETRI DELLA PROVA
   ============================================================================
   Due colonne affiancate al posto di tre riquadri annidati: descrizione a
   sinistra, tempi a destra, e sotto il testo della consegna senza altre
   cornici. I campi dei tempi sono brevi e stanno su una riga sola — dargli
   tutta la larghezza disponibile produceva solo spazio vuoto. */

.quiz-config-form {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.quiz-config-cols {
    display: grid;
    /* La colonna dei tempi si stringe sul proprio contenuto: le etichette restano
       accanto ai campi invece di essere separate da uno spazio vuoto largo mezza pagina.
       Tutto ciò che avanza va alla descrizione. */
    grid-template-columns: 1fr auto;
    gap: var(--space-4);
    align-items: start;
}

/* Sotto i 900px le due colonne si impilano: affiancate diventerebbero illeggibili. */
@media (max-width: 900px) {
    .quiz-config-cols { grid-template-columns: 1fr; gap: var(--space-3); }
}

.quiz-config-cols .field { margin: 0; }
.quiz-config-cols textarea { width: 100%; resize: vertical; }

/* I due campi di testo si compilano di seguito, quindi stanno nella stessa colonna. */
.quiz-config-texts {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    min-width: 0;
}

/* "Descrizione" e "Consegna" sono titoli di campo, non note: stesso trattamento delle
   etichette dei tempi, con cui stanno affiancati. */
.quiz-config-texts .field > label {
    display: block;
    margin: 0 0 var(--label-gap) 0;
    font-size: var(--text-md);
    color: var(--text-main);
    line-height: var(--line-tight);
}

/* La colonna dei tempi comincia all'altezza del CAMPO descrizione, non della sua etichetta:
   sono i campi a doversi allineare fra loro, non un campo con un titolo. Lo scarto è
   calcolato dall'altezza dell'etichetta invece che scritto a mano, così resta giusto anche
   se cambia la scala tipografica. */
.quiz-config-times {
    padding-top: calc(var(--text-md) * var(--line-tight) + var(--label-gap));
}

@media (max-width: 900px) {
    /* Impilate, lo scarto non serve più: la colonna dei tempi non ha nulla accanto. */
    .quiz-config-times { padding-top: 0; }
}

/* Etichette a sinistra, campi a destra: l'occhio scorre una colonna sola di valori
   invece di cercarli fra le intestazioni. */
.quiz-config-times {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}
.quiz-config-times-row {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: var(--space-2);
}
.quiz-config-times-row > label {
    margin: 0;
    font-size: var(--text-md);
    color: var(--text-main);
    white-space: nowrap;
}

/* La nota spiega la riga che ha sopra: le sta attaccata e allineata a sinistra, come
   il testo che commenta. */
.quiz-config-times .hint-text-tiny {
    margin: 0.15rem 0 0;
    max-width: 30ch;
    text-align: left;
}

/* 4) I tre campi hanno la stessa larghezza: con l'unità dentro la cornice, "%" e "min"
   darebbero altrimenti riquadri di misura diversa, e una colonna di valori disallineati
   è più difficile da leggere di quanto sembri. */
.quiz-config-times .number-field { width: 9.5rem; justify-content: flex-end; }
.quiz-config-times .number-field > input { flex: 1 1 auto; width: auto; }
.quiz-config-times .number-field-suffix { min-width: 2.2rem; text-align: left; }

/* Una riga sola per la descrizione: è un promemoria, non un testo. L'altezza viene dal
   numero di righe, non dai valori di default dei textarea. */
.quiz-config-texts #conf-desc { height: auto; min-height: 0; }

/* ============================================================================
   IMPORTAZIONE DALLE SEZIONI DEL POOL
   ============================================================================
   Stessa impaginazione del creatore di domande: etichetta sopra, campi affiancati
   su una riga, unità di misura dentro la cornice. Prima era una riga di controlli
   nudi (una tendina, un campo "Qty", un pulsante) senza etichette. */

.pool-add-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}
.pool-add-row .field { margin: 0; min-width: 0; }
.pool-add-row .field > label {
    display: block;
    margin-bottom: var(--label-gap);
    font-size: var(--text-md);
    color: var(--text-main);
    line-height: var(--line-tight);
}
.pool-add-row select { min-width: 12rem; }
.pool-add-row > button { flex: 0 0 auto; }

/* Le due misure hanno la stessa larghezza, come nei tempi della prova. */
.pool-add-row .number-field { width: 8.5rem; justify-content: flex-end; }
.pool-add-row .number-field > input { flex: 1 1 auto; width: auto; }
.pool-add-row .number-field-suffix { min-width: 2.6rem; text-align: left; }

.pool-warn { color: var(--danger); font-size: var(--text-sm); white-space: nowrap; }
.pool-avail { color: var(--text-muted); font-size: var(--text-sm); white-space: nowrap; }

/* Sovrapposizione fra una sezione e le domande obbligatorie: è un'informazione, non un
   errore — la prova funziona, semplicemente quella sezione contribuirà con meno domande. */
.pool-overlap {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    margin-top: 0.45rem;
    font-size: var(--text-sm);
    color: var(--text-muted);
}
.pool-overlap > i { margin-top: 0.1rem; }

/* ============================================================================
   BLOCCHI DELLE SEZIONI NEL CREATORE DI PROVE
   ============================================================================
   Un blocco per sezione, e dentro tutto quello che riguarda quella sezione:
   quali domande devono esserci per tutti, e quante altre prenderne a caso.
   Prima erano due passi separati e distanti nella pagina, e la relazione fra
   loro andava ricostruita a mente. */

.pool-block {
    padding: var(--space-3);
    margin-bottom: var(--space-2);
    background: var(--surface-muted);
    border-radius: var(--radius);
}

.pool-block-head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-bottom: var(--space-2);
}

/* I due passi hanno la stessa forma: che cosa si decide, com'è ora, come cambiarlo. */
.pool-block-step + .pool-block-step {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--border);
}
.pool-block-step-head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}
.pool-step-label {
    min-width: 10.5rem;
    font-size: var(--text-md);
    color: var(--text-main);
}
.pool-step-value { font-size: var(--text-sm); color: var(--text-muted); }
.pool-step-criterion { min-width: 12rem; }
.pool-block-step .number-field { width: 9.5rem; justify-content: flex-end; }
.pool-block-step .number-field > input { flex: 1 1 auto; width: auto; }
.pool-block-step .number-field-suffix { min-width: 3.2rem; text-align: left; }

/* Elenco per scegliere le domande obbligatorie: compare solo quando serve, così il
   blocco resta breve anche con sezioni da cento domande. */
.pool-picker {
    margin-top: 0.6rem;
    padding: var(--space-2);
    background: var(--bg-card);
    border-radius: var(--radius-sm);
}
.pool-picker-actions { display: flex; gap: var(--space-2); margin-bottom: 0.4rem; }
.pool-picker-list { max-height: 260px; overflow-y: auto; }

.pool-pick-item {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--space-2);
    padding: 0.35rem 0.4rem;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--text-md);
}
.pool-pick-item:hover { background: var(--hover-tint); }
.pool-pick-item.selected { background: var(--btn-primary-bg); color: var(--btn-primary-text); }
.pool-pick-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pool-pick-points { font-size: var(--text-sm); color: var(--text-muted); white-space: nowrap; }
.pool-pick-item.selected .pool-pick-points { color: inherit; }

.btn-link {
    padding: 0;
    height: auto;
    border: none;
    background: none;
    color: var(--primary);
    font-size: var(--text-sm);
    cursor: pointer;
}
.btn-link:hover { text-decoration: underline; background: none; }
.btn-small { height: auto; padding: 0.3rem 0.7rem; font-size: var(--text-sm); }

.pool-block .pool-warn { display: flex; align-items: center; gap: 0.35rem; margin-top: 0.5rem; }

/* Il modale della domanda del pool segue la stessa impaginazione del creatore rapido:
   due colonne, campi con etichetta sopra, punteggio nel componente numerico. */
.question-modal-columns .field > label,
#question-form > .field > label {
    display: block;
    margin-bottom: var(--label-gap);
    font-size: var(--text-md);
    color: var(--text-main);
    line-height: var(--line-tight);
}
#question-form .number-field { width: 9.5rem; justify-content: flex-end; }
#question-form .number-field > input { flex: 1 1 auto; width: auto; }
#question-form .number-field-suffix { min-width: 2.6rem; text-align: left; }

/* Azione neutra: importazioni ed esportazioni non sono l'azione principale di una
   schermata e non devono prendere il colore d'accento, che va riservato a ciò che
   l'utente è lì per fare. Restano grigie qualunque accento sia attivo. */
.btn-neutral {
    background: var(--surface-muted);
    border: 1px solid var(--border);
    color: var(--text-main);
}
.btn-neutral:hover {
    background: var(--bg-darker);
    border-color: var(--text-muted);
    color: var(--text-main);
}

/* I passaggi del creatore di prove non sono più riquadri: i blocchi delle sezioni lo sono
   già, e una scatola dentro una scatola confonde invece di raggruppare. Restano separati
   dallo spazio e da un titolo. */
.builder-flow {
    margin-bottom: var(--space-5);
}
.builder-flow-title {
    margin: 0 0 0.35rem;
    font-size: var(--text-lg);
    font-weight: 600;
}
.builder-flow > .hint-text { margin: 0 0 var(--space-3); }

/* Avviso nelle pagine di stampa: sostituisce alert() del browser, che non segue il tema,
   blocca la pagina e su alcuni browser si può disattivare del tutto. */
.print-error {
    margin: 0 0 0.6rem;
    padding: 0.5rem 0.8rem;
    background: var(--cell-wrong-bg, #fbe7e6);
    color: var(--cell-wrong-text, #b23b34);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
}

/* Il punteggio totale è un'informazione sulla prova, non un'azione: sta nella barra
   delle azioni ma spinto a sinistra, separato dai pulsanti. */
.quiz-total-points { margin-right: auto; font-size: var(--text-md); color: var(--text-main); }
.quiz-total-points .hint-text-tiny { display: inline; }

/* Il suggerimento è un promemoria breve: una riga, anche qui. Senza questa regola
   l'editor eredita l'altezza del campo del testo della domanda. */
#question-hint,
#question-form .rich-editor[data-placeholder^="Es."] {
    min-height: var(--control-height);
    height: var(--control-height);
    overflow-x: auto;
    white-space: nowrap;
}

/* Il testo delle risposte si legge insieme a quello della domanda: stessa taglia.
   Nella v1.6 ereditava dal corpo pagina, che era più grande di quello attuale. */
.exam-body .answer-option,
.exam-body .open-answer-textarea,
.exam-body .open-answer-textarea.rich-editor {
    font-size: var(--text-reading);
}


/* L'attributo `hidden` vale `display: none`, ma una classe che dichiara `display: flex`
   ha la stessa specificità e viene dopo: l'elemento resta visibile. Succedeva alla casella
   opzionale della finestra di conferma, che compariva vuota in ogni conferma — per esempio
   in "termina sessione", dove non serve. */
[hidden] { display: none !important; }

/* ============================================================================
   SELETTORE DEL TIPO DI DOMANDA
   ============================================================================
   Un campo che mostra la scelta corrente e apre un pannello al clic. Sei
   riquadri sempre visibili occupavano più spazio del resto del modulo e
   spostavano l'attenzione sul tipo invece che sulla domanda che si sta
   scrivendo — che è la cosa a cui il docente deve pensare.

   Il <select> originale resta nel DOM, nascosto: tutto il codice che legge
   `.value` o ascolta `change` continua a funzionare. */

.type-picker-source {
    /* `fixed` e non `absolute`, e larghezza con !important: la tecnica precedente
       («absolute, width:1px») veniva sconfitta da regole più specifiche come
       `.field select { width:100% }` — l'elemento nascosto restava largo 960px,
       assolutamente posizionato OLTRE il bordo destro del modale, e regalava a ogni
       finestra una barra di scorrimento orizzontale che nessun ritocco alle parti
       visibili poteva togliere. Un elemento `fixed` in alto a sinistra, qualunque
       larghezza gli venga imposta, non entra nel calcolo dello scroll di nessun
       antenato: il bug non può ripresentarsi per specificità. */
    position: fixed !important;
    top: 0 !important; left: 0 !important;
    width: 1px !important; height: 1px !important;
    padding: 0 !important; margin: 0 !important;
    overflow: hidden !important; clip: rect(0 0 0 0);
    white-space: nowrap; border: 0 !important;
    opacity: 0; pointer-events: none;
}

.type-picker { position: relative; display: inline-block; }

.type-picker-trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    height: var(--control-height);
    padding: 0 0.7rem;
    background: var(--field-bg, var(--surface-muted));
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-main);
    font-size: var(--text-md);
    font-weight: 400;
    cursor: pointer;
    white-space: nowrap;
}
.type-picker-trigger:hover { border-color: var(--text-muted); background: var(--field-bg, var(--surface-muted)); }
.type-picker-trigger[aria-expanded="true"] {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-focus);
}
.type-picker-caret { margin-left: 0.2rem; color: var(--text-muted); font-size: var(--text-sm); }

/* Il pannello galleggia sopra il modulo: inserirlo nel flusso sposterebbe tutto ciò che
   sta sotto ogni volta che si apre. */
.type-picker-panel {
    position: absolute;
    z-index: 1150;
    top: calc(100% + 4px);
    left: 0;
    min-width: 22rem;
    max-width: 26rem;
    padding: 0.35rem;
    background: var(--bg-card);
    border-radius: var(--radius);
    box-shadow: var(--shadow-float);
}
.type-picker-panel[hidden] { display: none; }

.type-picker-item {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas: "icona etichetta" "icona descrizione";
    align-items: center;
    gap: 0 0.65rem;
    width: 100%;
    height: auto;
    padding: 0.5rem 0.6rem;
    text-align: left;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--text-main);
    cursor: pointer;
}
.type-picker-item:hover { background: var(--hover-tint); }
.type-picker-item.selected { background: var(--btn-primary-bg); }
.type-picker-item.selected .type-picker-icon { color: var(--primary); }

.type-picker-icon {
    grid-area: icona;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.6rem;
    font-size: 1.1rem;
    color: var(--text-muted);
}
.type-picker-icon > i { margin: 0; }

.type-picker-label {
    grid-area: etichetta;
    font-size: var(--text-md);
    font-weight: 600;
    line-height: var(--line-tight);
}
.type-picker-desc {
    grid-area: descrizione;
    font-size: var(--text-sm);
    color: var(--text-muted);
    line-height: var(--line-tight);
}

/* ============================================================================
   CAMPI DEI TIPI COMPLETAMENTO, ABBINAMENTO E SEQUENZA
   ============================================================================
   Ogni tipo chiede informazioni diverse e ha quindi un modulo proprio. Le tre
   forme condividono però l'impaginazione — riga con indicatore, campi, azioni —
   così passare da un tipo all'altro non è un salto visivo. */

.type-fields-hint { margin: 0 0 0.6rem; }
.type-fields-hint code {
    padding: 0.05rem 0.3rem;
    background: var(--surface-muted);
    border-radius: 4px;
    font-size: 0.95em;
}

.type-fields-head {
    display: grid;
    grid-template-columns: 1fr 1.6rem 1fr 2.2rem;
    gap: 0.5rem;
    margin-bottom: 0.35rem;
    font-size: var(--text-sm);
    color: var(--text-muted);
}

.type-field-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.45rem;
}
.type-field-row input[type="text"] { flex: 1 1 auto; min-width: 0; }

/* Numero dello spazio o posizione nella sequenza: lo stesso indicatore delle lettere
   nelle opzioni, perché svolge la stessa funzione. */
.type-field-badge {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    background: var(--surface-muted);
    border-radius: 50%;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--text-muted);
}

.match-row { display: grid; grid-template-columns: 1fr 1.6rem 1fr 2.2rem; }
.type-field-arrow { color: var(--text-muted); text-align: center; }

/* Selettore a due posizioni con descrizione variabile: due nomi da soli non dicono in che
   cosa differiscono, e provarli entrambi per scoprirlo non è ragionevole. */
.mode-switch {
    display: inline-flex;
    padding: 0.2rem;
    background: var(--surface-muted);
    border-radius: var(--radius);
}
.mode-switch-option {
    height: auto;
    padding: 0.4rem 1.1rem;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: var(--text-md);
    font-weight: 500;
    cursor: pointer;
}
.mode-switch-option:hover { background: var(--hover-tint); color: var(--text-main); }
.mode-switch-option.active {
    background: var(--bg-card);
    color: var(--primary);
    font-weight: 600;
    box-shadow: 0 1px 3px rgba(30, 36, 51, 0.12);
}

/* --- TENDINA DEL PROGRAMMA (dropdown.js) --------------------------------------------------
   La regola d'oro, imparata a spese di tre schermate rotte: il CAMPO tiene l'ingombro che
   il <select> nativo avrebbe avuto lì (una toolbar lo vuole stretto quanto il contenuto,
   un modulo lo vuole a tutta riga); solo il PANNELLO che si apre è disegnato da noi.
   Dare al campo width:100% ovunque mandava a capo le etichette accanto («Anno
   Scolastico:», «Ordina per:») e creava scorrimenti orizzontali. */
.app-dropdown, .app-dropdown * { box-sizing: border-box; }
.app-dropdown { position: relative; display: inline-block; max-width: 100%; vertical-align: middle; }
.app-dropdown-source {
    /* `fixed` e non `absolute`, e larghezza con !important: la tecnica precedente
       («absolute, width:1px») veniva sconfitta da regole più specifiche come
       `.field select { width:100% }` — l'elemento nascosto restava largo 960px,
       assolutamente posizionato OLTRE il bordo destro del modale, e regalava a ogni
       finestra una barra di scorrimento orizzontale che nessun ritocco alle parti
       visibili poteva togliere. Un elemento `fixed` in alto a sinistra, qualunque
       larghezza gli venga imposta, non entra nel calcolo dello scroll di nessun
       antenato: il bug non può ripresentarsi per specificità. */
    position: fixed !important;
    top: 0 !important; left: 0 !important;
    width: 1px !important; height: 1px !important;
    padding: 0 !important; margin: 0 !important;
    overflow: hidden !important; clip: rect(0 0 0 0);
    white-space: nowrap; border: 0 !important;
    opacity: 0; pointer-events: none;
}
.app-dropdown-trigger {
    display: inline-flex; align-items: center; gap: 0.5rem;
    max-width: 100%; padding: 0.6rem 0.75rem;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-page); color: var(--text-main);
    font: inherit; cursor: pointer; text-align: left;
}
/* La voce scelta sta su UNA riga: se non ci sta, si tronca con i puntini — mai a capo.
   `min-width: 0` è la riga che conta: un elemento flex per difetto NON scende sotto la
   larghezza del proprio contenuto (min-width:auto), quindi un testo lungo su una riga
   spingeva il campo oltre il modale e faceva comparire la barra di scorrimento
   orizzontale. Con min-width:0 il testo si restringe e i puntini fanno il loro lavoro. */
.app-dropdown-current { white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
                        min-width: 0; flex: 0 1 auto; }
.app-dropdown-trigger { overflow: hidden; }
/* Dentro un .field (i moduli) il campo occupa la riga, come faceva il select nativo. */
.field .app-dropdown, .field .app-dropdown-trigger { width: 100%; }
.field .app-dropdown-trigger { justify-content: space-between; }
.app-dropdown-trigger:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.app-dropdown-caret { color: var(--text-muted); flex-shrink: 0; transition: transform 0.15s ease; }
.app-dropdown-trigger[aria-expanded="true"] .app-dropdown-caret { transform: rotate(180deg); }
.app-dropdown-panel {
    position: absolute; z-index: 60; top: calc(100% + 4px); left: 0;
    /* Largo almeno quanto il campo, di più se le voci lo chiedono — ma mai oltre lo
       schermo: è il pannello a doversi adattare, non la pagina a scorrere in orizzontale. */
    min-width: 100%; width: max-content; max-width: min(92vw, 440px);
    max-height: 280px; overflow-y: auto;
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14); padding: 0.3rem;
}
.app-dropdown-panel.apre-a-destra { left: auto; right: 0; }
.app-dropdown-item {
    display: flex; align-items: center; gap: 0.4rem; width: 100%;
    padding: 0.5rem 0.6rem; border: 0; border-radius: 7px;
    background: none; color: var(--text-main); font: inherit; text-align: left; cursor: pointer;
}
.app-dropdown-item:hover, .app-dropdown-item:focus-visible { background: var(--bg-darker); outline: none; }
.app-dropdown-item[aria-selected="true"] { color: var(--primary); font-weight: 600; }
.app-dropdown-locked { opacity: 0.5; cursor: not-allowed; }
.app-dropdown-pro {
    /* Accanto al testo, non spinto al bordo del pannello: il pannello è largo
       `max-content` e un `margin-left: auto` apriva un vuoto che spezzava la voce in
       due — testo tutto a sinistra, lucchetto tutto a destra. Il badge è parte della
       voce e le sta attaccato. */
    display: inline-flex; align-items: center; gap: 0.2rem; margin-left: 0.35rem;
    font-size: var(--text-xs, 0.72rem); font-weight: 700; color: var(--primary);
}

/* Interruttore «vede il mio materiale» nelle righe dei membri */
.share-toggle { display: inline-flex; align-items: center; gap: 0.35rem;
                font-size: var(--text-xs, 0.75rem); color: var(--text-muted); cursor: pointer;
                white-space: nowrap; }
.share-toggle input { accent-color: var(--primary); }
