/* Design neutro: una colonna, gerarchia netta, un solo colore d'accento.
   Nessuna imitazione di brand.

   Un colore d'accento solo, il verde: tutto cio' che e' interattivo o che porta il numero
   principale lo indossa. Rosso e giallo non sono accenti, sono stati — errore e avviso — e
   compaiono solo quando quello stato esiste. Le misure sono in rem perche' la pagina segua
   la dimensione di carattere scelta nel browser: chi ingrandisce lo fa per leggere. */

:root {
  --accento: #1f5f4f;
  --accento-tenue: #e8f1ee;
  --inchiostro: #1a1c1a;
  --inchiostro-tenue: #5c635e;
  --carta: #fbfbfa;
  --bordo: #dcdedb;
  --allarme: #a3241c;
  --attenzione: #b3801a;
  --attenzione-tenue: #fdf4de;
  --raggio: 10px;

  /* Un'altezza sola per ogni cosa che si tocca: campo, segmenti, date, tendine, bottone.
     Lasciati alla loro altezza naturale non coincidono mai — il padding di un input di
     testo, quello di un segmento e i due pixel che l'input[type=date] si porta dietro dal
     controllo nativo danno tre misure diverse — e in colonna non si nota, ma affiancati
     nella barra ogni bordo cade a una quota sua. Il valore vive qui perche' e' la stessa
     misura in tutte e tre le disposizioni. */
  --altezza-controllo: 3rem;

  /* La pagina ha una sola veste. Dichiararlo evita che un browser mobile in tema scuro
     inverta da solo campo e bottone, ottenendo l'unica combinazione che non abbiamo
     verificato. */
  color-scheme: light;
}

* {
  box-sizing: border-box;
}

/* Un solo anello di focus per tutta la pagina, nel colore d'accento: chi naviga da tastiera
   vede sempre dov'e', e lo vede sempre allo stesso modo. `:focus-visible` e non `:focus`
   perche' il click del mouse non deve lasciare l'anello acceso dietro di se'. */
:focus-visible {
  outline: 2px solid var(--accento);
  outline-offset: 2px;
  border-radius: 3px;
}

/* L'unica animazione della pagina e' la rotazione del chevron. Chi ha chiesto al sistema di
   ridurre il movimento la perde e non perde niente: lo stato aperto si vede dal contenuto. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

::selection {
  background: var(--accento-tenue);
}

body {
  margin: 0;
  /* Il respiro cresce con la finestra: 1rem di margine su un telefono e' giusto, su 1600px
     farebbe toccare i bordi al contenuto. */
  padding: clamp(1.75rem, 1rem + 1.4vw, 3rem) clamp(1rem, 0.4rem + 1.6vw, 2.75rem) 4rem;
  background: var(--carta);
  color: var(--inchiostro);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* 17px con le impostazioni di default, ma in rem: chi ha alzato la dimensione di carattere
     nel browser lo ha fatto per leggere, e un valore in px lo ignorerebbe. */
  font-size: 1.0625rem;
  line-height: 1.55;
  -webkit-text-size-adjust: 100%;
}

/* Il tetto e' 100rem, non la misura di lettura: questa pagina non e' un testo, e' un form
   con cinque campi e una tabella di quindici voci — contenuto che dalla larghezza ci
   guadagna. A 48rem su un laptop restava vuoto quasi meta' schermo. Sopra i 1600px la
   pagina smette di crescere: piu' in la' non c'e' disposizione che regga, e le righe
   diventano impercorribili. La misura di lettura non sparisce, si sposta dentro — sui
   testi e sulla cascata, dove serve davvero. */
.pagina {
  max-width: 100rem;
  margin: 0 auto;
}

/* Intestazione */

/* I corpi scalano con la larghezza. Non e' vezzo: se il contenitore raddoppia e il
   carattere no, lo spazio riempito lo sembra a meta' — la stessa pagina su 1600px si
   legge come una pagina stretta stirata. Gli estremi del `clamp` sono i due valori che
   c'erano prima, quello mobile e quello da colonna larga: in mezzo ora c'e' una rampa
   invece di uno scalino. */

h1 {
  margin: 0;
  font-size: clamp(1.9rem, 1.5rem + 1.2vw, 2.9rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

/* Il tetto era 44ch, e su un desktop spezzava questa frase in 438px piu' 239px: una riga
   piena e un moncone, dentro un'intestazione larga 1436px — che non si legge come una
   scelta ma come un taglio. La misura di lettura serve a proteggere il ritorno a capo, e
   qui il ritorno a capo non c'e': sono 85 caratteri, 683px, una riga sola. 52rem e' la
   stessa misura del perimetro qui sotto, cosi' i due blocchi finiscono sullo stesso bordo
   destro invece di fare scaletta. `balance` e non `pretty` per le finestre in cui la riga
   non ci sta comunque: pretty sistema l'ultima riga, balance pareggia tutte. */
.sottotitolo {
  margin: 0.4rem 0 0;
  max-width: 52rem;
  color: var(--inchiostro-tenue);
  font-size: clamp(1rem, 0.95rem + 0.25vw, 1.2rem);
  text-wrap: balance;
}

.perimetro {
  /* Tre righe di testo stese su 1600px diventerebbero un filo: il riquadro tiene la sua
     misura anche quando l'intestazione prende tutta la larghezza. */
  max-width: 52rem;
  margin: 1.1rem 0 0;
  padding: 0.7rem 0.9rem;
  border-left: 3px solid var(--accento);
  background: var(--accento-tenue);
  border-radius: 0 var(--raggio) var(--raggio) 0;
  font-size: 0.9rem;
  color: var(--inchiostro-tenue);
}

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

/* Il registro delle assunzioni sta dentro il perimetro perche' ne e' la continuazione: qui
   sopra c'e' per chi vale questo numero, di la' perche'. Riga propria e non coda della
   frase — attaccato al punto fermo si leggerebbe come l'ultima parola del perimetro invece
   che come la porta per uscirne. */
.perimetro .registro {
  display: block;
  margin-top: 0.35rem;
  font-weight: 600;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

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

/* Form */

/* Il form e' due cose impilate: il cruscotto dei campi e, sotto, l'azione. In colonna
   singola la distinzione non si vede — e' una sequenza verticale come tutto il resto — ma
   e' la stessa struttura che sopra i 64rem diventa barra + bottone a tutta larghezza. */
.calcolatore {
  margin: 2rem 0 0;
  display: grid;
  gap: 1.4rem;
}

.cruscotto {
  display: grid;
  gap: 1.4rem;
}

.campo {
  margin: 0;
  padding: 0;
  border: 0;
  display: grid;
  gap: 0.45rem;
}

.etichetta-campo {
  padding: 0;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--inchiostro-tenue);
}

/* Su una <label> il distacco dal campo lo mette il `gap` della griglia; su una <legend> no,
   perche' dentro un fieldset in `display: grid` la legenda non e' un grid item — sta fuori
   dalla griglia, e il gap non la tocca. Senza questo margine la RAL scende di 0.45rem
   rispetto a mensilita' e periodo, e nella barra la differenza si legge tutta. */
legend.etichetta-campo {
  margin-bottom: 0.45rem;
}

/* I quattro controlli condividono l'altezza, e la impongono al loro contenuto invece di
   riceverla da lui: gli input dentro non hanno padding verticale (sotto) e si stirano fino
   ai bordi, cosi' l'altezza e' un valore dichiarato e non la somma accidentale di tre
   padding diversi. `min-height` e non `height`: chi ingrandisce il carattere nel browser
   deve poter far crescere il controllo invece di veder tagliare il testo. */
.campo-valuta,
.periodo-estremo,
.segmentato,
.campo-luogo select {
  min-height: var(--altezza-controllo);
}

.campo-valuta {
  display: flex;
  align-items: stretch;
  max-width: 20rem;
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  background: #fff;
  overflow: hidden;
}

.campo-valuta:focus-within {
  border-color: var(--accento);
  box-shadow: 0 0 0 3px var(--accento-tenue);
}

/* Il campo si tinge insieme al messaggio: il colore da solo non porta l'informazione
   (il testo dell'errore c'e' sempre), ma lega l'errore al campo che lo ha generato. */
.campo-valuta:has(input[aria-invalid='true']) {
  border-color: var(--allarme);
}

.campo-valuta input {
  flex: 1;
  min-width: 0;
  padding: 0 0.85rem;
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  font-variant-numeric: tabular-nums;
  color: inherit;
}

.unita {
  display: flex;
  align-items: center;
  padding: 0 0.85rem;
  border-left: 1px solid var(--bordo);
  background: #f4f5f3;
  color: var(--inchiostro-tenue);
}

/* I tre menu' del luogo sono un input solo diviso in tre passi, non tre domande
   indipendenti: incolonnati sullo schermo stretto, disposti come la scelta si restringe su
   quello largo — i due che filtrano affiancati, il comune sotto e per intero. La riga tutta
   sua non e' simmetria: e' il menu' che porta i nomi lunghi (Castelnuovo di Val di Cecina),
   ed e' l'unico dei tre la cui risposta entra nel calcolo. */
.campo-luogo {
  grid-template-columns: 1fr;
  gap: 0.7rem 1rem;
}

@media (min-width: 34rem) {
  .campo-luogo {
    grid-template-columns: 1fr 1fr;
  }

  .campo-luogo .sotto-campo:nth-of-type(3) {
    grid-column: 1 / -1;
  }
}

.sotto-campo {
  display: grid;
  gap: 0.45rem;
  min-width: 0;
}

/* Il testo di aiuto vale per tutti e tre i menu' e va a capo sotto di loro. */
.campo-luogo .aiuto {
  grid-column: 1 / -1;
}

.campo-luogo select {
  width: 100%;
  min-width: 0;
  padding: 0 0.85rem;
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  background: #fff;
  font: inherit;
  color: inherit;
  /* Il passo della provincia ha tolto gli elenchi da millecinquecento voci, ma il piu' lungo
     ne ha ancora oltre trecento: il menu' nativo si cerca da tastiera scrivendo le prime
     lettere, cosa che nessun sostituto costruito a mano fa altrettanto bene — e il repo non
     ha dipendenze. */
  cursor: pointer;
}

.campo-luogo select:focus-visible {
  outline: 0;
  border-color: var(--accento);
  box-shadow: 0 0 0 3px var(--accento-tenue);
}

.campo-luogo select:disabled {
  background: #f4f5f3;
  color: var(--inchiostro-tenue);
  cursor: progress;
}

.aiuto {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--inchiostro-tenue);
}

.segmentato {
  display: inline-flex;
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  background: #fff;
  overflow: hidden;
  width: fit-content;
}

/* Flex e non blocco con padding: da flex item il segmento si stira all'altezza del gruppo,
   e il numero resta al centro di qualunque altezza sia. */
.segmento {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 1.15rem;
  border-left: 1px solid var(--bordo);
  cursor: pointer;
  font-variant-numeric: tabular-nums;
  user-select: none;
}

.segmento:first-child {
  border-left: 0;
}

.segmento input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

.segmento:has(input:checked) {
  background: var(--accento);
  color: #fff;
  font-weight: 600;
}

/* Il radio vero e' invisibile (opacity: 0) e con lui il suo anello di focus: l'anello va
   ridisegnato sul segmento che lo contiene, altrimenti chi naviga da tastiera non vede dove
   si trova. Il colore cambia con il fondo — accento sul bianco, bianco sull'accento — perche'
   un anello dello stesso colore di cio' su cui poggia non e' un anello. */
.segmento:has(input:focus-visible) {
  box-shadow: inset 0 0 0 2px var(--accento);
}

.segmento:has(input:checked:focus-visible) {
  box-shadow: inset 0 0 0 2px #fff;
}

/* I due campi data. Affiancati finche' ci stanno, incolonnati quando la colonna si stringe:
   sono un intervallo, e un intervallo si legge da sinistra a destra finche' e' possibile. */
.periodo {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 0.9rem;
}

.periodo-estremo {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  background: #fff;
  overflow: hidden;
}

.periodo-estremo:focus-within {
  border-color: var(--accento);
  box-shadow: 0 0 0 3px var(--accento-tenue);
}

/* Stessa regola del campo valuta: il colore da solo non porta l'informazione — il testo
   dell'errore c'e' sempre — ma lega il messaggio ai campi che lo hanno generato. */
.periodo-estremo:has(input[aria-invalid='true']) {
  border-color: var(--allarme);
}

/* «Dal» e «Al» stanno dentro il controllo, dal lato da cui si legge: fuori sarebbero due
   etichette in piu' in una colonna che ne ha gia' tre. Stesso trattamento del simbolo
   dell'euro accanto alla RAL, dall'altro lato.

   La larghezza e' dichiarata, non intrinseca: «Dal» e «Al» misurano diversi, e la differenza
   usciva due volte — impilati, le due date partivano a otto pixel l'una dall'altra; affiancati,
   le due scatole non erano larghe uguali. Sono un intervallo, cioe' una coppia: qualunque
   disposizione deve dirlo. */
.periodo-preposizione {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 2.9rem;
  padding: 0 0.7rem;
  border-right: 1px solid var(--bordo);
  background: #f4f5f3;
  color: var(--inchiostro-tenue);
  font-size: 0.9rem;
}

.periodo-estremo input {
  min-width: 0;
  padding: 0 0.85rem;
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  font-variant-numeric: tabular-nums;
  color: inherit;
}

/* L'unico numero derivato del form: non e' un risultato — quelli stanno sotto il bottone —
   ma la lettura di cio' che si sta per calcolare. Discreto, quindi, e nel colore del testo
   secondario. */
.periodo-giorni {
  margin: 0;
  color: var(--inchiostro-tenue);
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

.periodo-giorni:empty {
  display: none;
}

/* Alto quanto un campo: e' un controllo anche lui, e in colonna singola sta nella stessa
   sequenza verticale degli altri. */
.calcola {
  justify-self: start;
  min-height: var(--altezza-controllo);
  padding: 0 1.9rem;
  border: 0;
  border-radius: var(--raggio);
  background: var(--accento);
  color: #fff;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.calcola:hover {
  filter: brightness(1.12);
}

.calcola:active {
  filter: brightness(0.94);
}

.errore {
  margin: 0;
  color: var(--allarme);
  font-size: 0.9rem;
}

/* I tre livelli di messaggio si distinguono per colore *e* per posizione, mai per colore
   soltanto: l'errore e' rosso e sotto il campo, l'avviso e' giallo e sopra i risultati,
   lo scalino e' nel colore d'accento e dentro i risultati. Chi non distingue i colori
   legge comunque tre messaggi in tre posti diversi. */

.avvisi {
  display: grid;
  gap: 0.6rem;
  margin-top: 1.6rem;
}

/* `display: grid` batte la regola `[hidden] { display: none }` del browser, che ha
   specificita' zero: senza questa riga il contenitore vuoto resterebbe in pagina a
   lasciare il suo margine fra il form e i risultati. */
.avvisi[hidden] {
  display: none;
}

.avviso {
  margin: 0;
  display: flex;
  gap: 0.5rem;
  padding: 0.75rem 0.9rem;
  border-left: 3px solid var(--attenzione);
  background: var(--attenzione-tenue);
  border-radius: 0 var(--raggio) var(--raggio) 0;
  font-size: 0.9rem;
}

.segno {
  flex: none;
}

/* L'attesa: la pagina prima del click
   -----------------------------------
   Occupa lo stesso posto dei risultati e ne ha la forma — tre carte, poi l'elenco delle
   voci — ma nessun numero. Due pezzi che si reggono a vicenda: l'invito da solo riempirebbe
   ottanta pixel dove ce ne sono mille, la struttura vuota da sola si leggerebbe come
   «rotto» invece che «non ancora».

   Il tratteggio e' la convenzione che tiene insieme le due letture: linea continua dove c'e'
   un dato, spezzata dove manca. Vale sui bordi delle carte, sul filetto fra le voci e sul
   riquadro dell'elenco. */

.attesa[hidden] {
  display: none;
}

.attesa {
  margin-top: 2.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--bordo);
}

/* Qui il tetto resta: sono cinque righe di prosa, il ritorno a capo c'e' eccome. Cambia
   solo come si spezzano — con `pretty` l'ultima riga restava un moncone di 84px in una
   colonna da 336px, con `balance` le cinque righe si pareggiano e il moncone sparisce. */
.attesa-invito {
  margin: 0 0 1rem;
  max-width: 52ch;
  color: var(--inchiostro-tenue);
  font-size: 0.95rem;
  text-wrap: balance;
}

.attesa-eroi {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(2, 1fr);
  margin-bottom: 1.5rem;
}

.attesa-eroe {
  padding: 1.1rem 1.2rem;
  border: 1px dashed var(--bordo);
  border-radius: var(--raggio);
  background: #fff;
}

/* Il fondo tenue al posto del verde pieno: l'accento pieno appartiene al numero, e qui il
   numero non c'e' ancora. La carta dice gia' che sara' la principale senza promettere
   d'esserlo. */
.attesa-eroe-primario {
  grid-column: 1 / -1;
  border-color: var(--accento);
  background: var(--accento-tenue);
}

.attesa-eroe-etichetta {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--inchiostro-tenue);
}

.attesa-eroe-valore {
  display: block;
  margin: 0.3rem 0 0;
  font-size: 1.85rem;
  font-weight: 700;
  color: var(--bordo);
}

.attesa-eroe-primario .attesa-eroe-valore {
  font-size: 2.6rem;
  color: rgb(31 95 79 / 0.3);
}

.attesa-voci {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px dashed var(--bordo);
  border-radius: var(--raggio);
  background: #fff;
  overflow: hidden;
}

.attesa-voce {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.75rem;
  padding: 0.7rem 0.9rem;
  font-size: 0.95rem;
  color: var(--inchiostro-tenue);
}

.attesa-voce + .attesa-voce {
  border-top: 1px dashed var(--bordo);
}

/* Il trattino tiene la colonna dell'importo e dice «qui, non ancora». */
.attesa-segno {
  color: var(--bordo);
  font-variant-numeric: tabular-nums;
}

/* Risultati */

.risultato {
  margin-top: 2.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--bordo);
}

/* Gerarchia netta: i tre numeri non pesano uguale. Il netto annuo e' la risposta alla
   domanda che ha portato qui — prende la riga intera e l'unico fondo pieno d'accento della
   pagina. Netto mensile e trattenute totali stanno sotto, affiancati: sono la stessa
   risposta vista da un'altra angolazione. Tre card identiche in fila direbbero che le tre
   domande hanno lo stesso peso, e non ce l'hanno. */

.eroi {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(2, 1fr);
}

.eroe {
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  background: #fff;
}

.eroe-primario {
  grid-column: 1 / -1;
  border-color: var(--accento);
  background: var(--accento);
  color: #fff;
}

.eroe-primario .eroe-valore {
  font-size: clamp(2.2rem, 1.7rem + 1.8vw, 3.7rem);
}

.eroe-primario .eroe-etichetta,
.eroe-primario .eroe-glossa {
  /* Bianco velato invece di un grigio: sul fondo d'accento un grigio virerebbe di tinta.
     Il contrasto resta sopra 5:1, ben oltre il minimo per il testo piccolo. */
  color: rgb(255 255 255 / 0.82);
}

.eroe-primario .eroe-nota {
  color: #fff;
  border-left-color: rgb(255 255 255 / 0.55);
}

.eroe-etichetta {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--inchiostro-tenue);
}

.eroe-valore {
  margin: 0.3rem 0 0;
  font-size: clamp(1.6rem, 1.35rem + 0.9vw, 2.3rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.eroe-incidenza {
  margin: 0.35rem 0 0;
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: var(--accento-tenue);
  color: var(--accento);
  font-size: 0.82rem;
  font-weight: 600;
}

.eroe-glossa {
  margin: 0.7rem 0 0;
  font-size: 0.87rem;
  color: var(--inchiostro-tenue);
}

.eroe-nota {
  margin: 0.6rem 0 0;
  font-size: 0.87rem;
  color: var(--inchiostro);
  border-left: 3px solid var(--accento);
  padding-left: 0.6rem;
}

/* Lo scalino: evidenziato, non decorativo. E' il contenuto che nessun calcolatore online
   da' — l'unico posto in cui la pagina spiega perche' il numero appena letto e' piu' basso
   di quello che si otterrebbe guadagnando meno — e sta attaccato ai numeri hero perche'
   commenta quelli. Fondo pieno d'accento: si vede prima di leggerlo. */

/* Il banner sul periodo parziale: stesso pattern e stessa veste di quello sullo scalino —
   dentro l'area risultati, nel colore d'accento, perche' commenta i numeri e non l'input.
   Sta sopra perche' riguarda tutti e tre gli eroi, mentre lo scalino riguarda il solo netto;
   quando compaiono insieme si leggono nell'ordine in cui i due effetti si sommano. */
.periodo-avviso {
  margin: 1rem 0 0;
  padding: 0.9rem 1.05rem;
  border: 1px solid var(--accento);
  border-left-width: 4px;
  border-radius: var(--raggio);
  background: var(--accento-tenue);
  font-size: 0.92rem;
}

.periodo-avviso-testo {
  margin: 0;
}

.scalino {
  margin: 1rem 0 0;
  padding: 0.9rem 1.05rem;
  border: 1px solid var(--accento);
  border-left-width: 4px;
  border-radius: var(--raggio);
  background: var(--accento-tenue);
  font-size: 0.92rem;
}

.scalino-testo {
  margin: 0;
}

/* Il mini-grafico dentro il banner: illustra il testo che l'utente sta gia' leggendo, a
   scala ristretta attorno alla zona in cui la RAL e' caduta. E' l'unica scala a cui il
   salto si vede — su un grafico da zero alla RAL intera sarebbe meno di un pixel — e per
   questo il disegno vive qui dentro e in nessun altro punto della pagina: fuori dal banner
   sarebbe un grafico senza l'avvertenza che gli da' senso.

   Largo quanto la colonna ma non oltre: allargandosi all'infinito il salto diventerebbe
   una scaletta dolce, e il grafico direbbe il contrario di quello che deve dire. */

.scalino-grafico:not(:empty) {
  margin-top: 0.85rem;
}

/* Le scritte dentro l'SVG scalano con il disegno: il tetto e' scelto perche' a colonna
   piena restino appena sotto il corpo del banner — sono annotazioni sul grafico, non testo
   da leggere prima di esso. */
.scalino-grafico svg {
  display: block;
  width: 100%;
  max-width: 24rem;
  height: auto;
}

.grafico-fondo {
  fill: var(--carta);
  stroke: var(--bordo);
}

/* Il buco: quanto netto si perde, e per quanta RAL. Riempimento tenue, non un secondo
   accento — il colore forte resta alla curva, che e' il dato. */
.grafico-perdita {
  fill: var(--accento);
  fill-opacity: 0.13;
}

/* Il livello da cui si scende e a cui si torna: tratteggiato perche' non e' una misura
   letta dal calcolo, e' una riga di riferimento sopra la quale il netto non e' piu' salito. */
.grafico-livello {
  stroke: var(--accento);
  stroke-width: 1;
  stroke-dasharray: 3 3;
  stroke-opacity: 0.55;
}

.grafico-curva {
  fill: none;
  stroke: var(--accento);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.grafico-tacca {
  stroke: var(--bordo);
  stroke-width: 1;
}

.grafico-scala {
  fill: var(--inchiostro-tenue);
  font-size: 12px;
}

.grafico-punto {
  fill: var(--accento);
  stroke: var(--carta);
  stroke-width: 2;
}

/* Con la RAL appena sopra la soglia il punto sta in fondo al salto e l'etichetta finisce
   sopra la risalita della curva: l'alone del colore della carta la stacca dal tratto invece
   di lasciarle addosso una riga verde. `paint-order: stroke` disegna il bordo prima del
   pieno, altrimenti l'alone mangerebbe le lettere dall'interno. */
.grafico-punto-etichetta {
  fill: var(--accento);
  font-size: 12px;
  font-weight: 600;
  paint-order: stroke;
  stroke: var(--carta);
  stroke-width: 3px;
  stroke-linejoin: round;
}

/* Le scritte scalano geometricamente con il disegno: i 12px dichiarati sono 12 veri solo
   quando l'SVG e' largo quanto il suo viewBox (340px). Dove il contenitore lo stringe — il
   pannello dei risultati sul cruscotto, la colonna di un telefono — l'effettivo scendeva
   fino a ~9px, sotto la leggibilita'. Il corpo cresce a gradini dove la scala scende, cosi'
   il testo reso resta fra gli 11 e i 14px a ogni larghezza. */
@media (min-width: 64rem) {
  .grafico-scala,
  .grafico-punto-etichetta {
    font-size: 13.5px;
  }
}

@media (max-width: 24rem) {
  .grafico-scala,
  .grafico-punto-etichetta {
    font-size: 14px;
  }
}

@media (max-width: 22rem) {
  .grafico-scala,
  .grafico-punto-etichetta {
    font-size: 16px;
  }
}

/* La cascata, voce per voce */

.cascata {
  margin-top: 2.5rem;
}

.titolo-sezione {
  margin: 0;
  font-size: clamp(1.15rem, 1.05rem + 0.3vw, 1.4rem);
  letter-spacing: -0.01em;
}

/* Titolo e comando sulla stessa riga, allineati sulla linea di base: il bottone e' un
   attrezzo del titolo, non un elemento dell'elenco. `baseline` e non `center` perche' i due
   corpi sono molto diversi e centrarli lascerebbe la parola piccola a mezz'aria. */
.cascata-intestazione {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}

/* Sobrio per costruzione: nessun fondo, nessun bordo, il grigio del testo secondario. Non
   compete con «Calcola», che resta l'unica cosa piena della pagina, ne' con l'accento, che
   qui marca solo i link alle fonti. Si accende sull'hover — quanto basta a dire che si
   preme. Il padding allarga il bersaglio del dito oltre le due parole; il margine negativo
   lo riassorbe, cosi' il testo resta allineato al bordo dell'elenco qui sotto. */
.tutte {
  flex: none;
  margin: -0.5rem -0.5rem -0.5rem 0;
  padding: 0.5rem;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.85rem;
  color: var(--inchiostro-tenue);
  cursor: pointer;
}

.tutte:hover {
  color: var(--accento);
  text-decoration: underline;
}

.occhiello {
  margin: 0.3rem 0 1rem;
  font-size: 0.9rem;
  color: var(--inchiostro-tenue);
}

.voci {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  background: #fff;
  overflow: hidden;
}

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

.voce-riga {
  display: grid;
  grid-template-columns: 1fr auto 0.75rem;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 0.9rem;
  cursor: pointer;
  list-style: none; /* toglie il triangolo nativo: al suo posto il chevron sotto */
}

.voce-riga::-webkit-details-marker {
  display: none;
}

.voce-riga:hover {
  background: var(--accento-tenue);
}

.voce-riga:focus-visible {
  outline: 2px solid var(--accento);
  outline-offset: -2px;
}

.voce-etichetta {
  font-size: 0.95rem;
}

.voce-importo {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* Le voci a zero restano in cascata: la struttura non cambia con l'input, cambia l'importo. */
.voce-importo-zero {
  color: var(--inchiostro-tenue);
  font-weight: 400;
}

/* Chevron: giu' quando la riga e' chiusa, su quando e' aperta. */
.voce-riga::after {
  content: '';
  width: 0.45rem;
  height: 0.45rem;
  border-right: 2px solid var(--inchiostro-tenue);
  border-bottom: 2px solid var(--inchiostro-tenue);
  transform: translateY(-0.15rem) rotate(45deg);
  transition: transform 0.15s ease;
}

.voce details[open] > .voce-riga::after {
  transform: translateY(0.1rem) rotate(225deg);
}

/* Il tetto era 42rem, e in una riga larga 926px lasciava un quarto di riquadro vuoto a
   destra di ogni glossa: dentro un contenitore che ha un bordo visibile quel vuoto non si
   legge come margine, si legge come testo tagliato. 52rem sono 832px e ne restano 65 di
   respiro prima del bordo — il testo si allarga ma non ci va a sbattere. */
.voce-corpo {
  padding: 0 0.9rem 0.9rem;
  max-width: 52rem;
}

/* Niente `balance` qui: pareggiando le righe le accorcia tutte, e su quindici glosse teneva
   la riga piu' lunga a una media di 482px in un riquadro da 926 — il difetto che il tetto
   piu' alto doveva togliere, rimesso dall'altra parte. Con `pretty` la media sale a 702px e
   le glosse occupano cinque righe in meno in altezza. Il prezzo sono due glosse che
   finiscono con una riga corta, che e' come finisce un paragrafo qualunque. */
.voce-spiegazione {
  margin: 0;
  font-size: 0.9rem;
  color: var(--inchiostro-tenue);
  text-wrap: pretty;
}

.voce-nota {
  margin: 0.6rem 0 0;
  display: flex;
  gap: 0.45rem;
  font-size: 0.9rem;
  border-left: 3px solid var(--accento);
  padding-left: 0.6rem;
}

/* L'offerta di ricalcolo senza massimale (issue #23): sta attaccata alla nota che la
   motiva, senza il filetto d'accento e senza il segno di attenzione. Non e' un avviso —
   non c'e' niente di storto nel risultato — ma una precisione in piu' offerta a chi puo'
   usarla, e si legge come una coda della nota, non come un secondo allarme. */
.voce-deroga {
  margin: 0.45rem 0 0;
  padding-left: 0.6rem;
  font-size: 0.87rem;
  color: var(--inchiostro-tenue);
}

/* Il comando e' un <button> travestito da link: l'azione e' un ricalcolo di questa stessa
   pagina, quindi non puo' essere un <a> — ma resta una parola dentro una frase, e un
   bottone pieno la spezzerebbe come se aprisse chissa' che. La sottolineatura e il colore
   d'accento sono l'unica cosa che promette un click; l'anello di focus e' quello di tutta
   la pagina. `text-align: left` perche' Chrome centra il testo dei bottoni anche quando
   vanno a capo su due righe. */
.deroga-comando {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  color: var(--accento);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

/* La fonte chiude la riga espansa. Piu' piccola e tenue della spiegazione: e' l'apparato
   critico della voce, non il suo contenuto — chi vuole verificare la trova, chi vuole solo
   capire non ci inciampa. La citazione puo' essere lunga (estremi + data + delibera):
   `overflow-wrap` le impedisce di allargare la riga sugli schermi stretti. */
.voce-fonte {
  margin: 0.7rem 0 0;
  font-size: 0.82rem;
  color: var(--inchiostro-tenue);
  overflow-wrap: anywhere;
}

/* Chiusura */

.chiusura {
  margin-top: 3rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--bordo);
  font-size: 0.85rem;
  color: var(--inchiostro-tenue);
}

.chiusura p {
  margin: 0;
}

/* Schermo largo: il cruscotto
   ---------------------------
   Sopra i 1024px la pagina smette di essere una colonna. I campi si stendono in una barra
   sotto l'intestazione, «Calcola» le sta sotto per tutta la sua larghezza, e cio' che ne
   esce si dispone su due colonne: la cascata a sinistra, i tre numeri in un pannello a
   destra. Chi scorre le quindici voci ha sempre a fianco il numero di cui sta leggendo la
   scomposizione.

   La lettura resta una sequenza verticale — inserisci, premi, leggi — quindi il flusso non
   si spezza: quello che cambia e' che l'input smette di occupare un'altezza che non gli
   serve. Il gradino cade a 64rem perche' e' li' che la barra a due righe smette di
   comprimere i suoi quattro controlli; sotto, la colonna singola resta la disposizione
   giusta e non c'e' una larghezza intermedia in cui la pagina sembri strizzata. */

@media (min-width: 64rem) {
  /* La barra. Due righe e non una: i tre menu' del luogo sono larghi quanto tutti gli altri
     campi messi insieme, e in fila unica sarebbero un pettine. Prima riga «quanto e quando»,
     seconda «dove» — la stessa divisione che il form aveva in verticale. */
  .cruscotto {
    grid-template-columns: minmax(11rem, 0.9fr) auto minmax(21rem, 1.1fr);
    /* Allineati in alto, non in basso: sotto il periodo pende «365 giorni su 365», e
       allineando le basi quella riga in piu' spingerebbe su il suo campo lasciando le
       tre etichette a tre altezze diverse. */
    align-items: start;
    gap: 1.1rem 1.5rem;
    padding: 1.35rem 1.5rem;
    border: 1px solid var(--bordo);
    border-radius: var(--raggio);
    background: #fff;
  }

  .cruscotto > :nth-child(1) {
    grid-column: 1;
    grid-row: 1;
  }

  .cruscotto > :nth-child(2) {
    grid-column: 2;
    grid-row: 1;
  }

  .cruscotto > :nth-child(3) {
    grid-column: 3;
    grid-row: 1;
    align-content: start;
  }

  /* Fuori dalla barra, non piu' largo di quanto gli serve. L'importanza gliela da' la
     posizione — sotto il cruscotto, sul bianco della pagina, unica superficie premibile —
     non la stazza: a tutta larghezza diventava una fascia verde da 1300px, che grida invece
     di guidare. Alto quanto i controlli sopra, cosi' la barra e la sua azione stanno sullo
     stesso ritmo verticale. */
  .calcolatore > .calcola {
    min-width: 12rem;
    padding: 0 2.2rem;
  }

  .cruscotto > .campo-luogo {
    grid-column: 1 / -1;
    grid-row: 2;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    padding-top: 1.1rem;
    border-top: 1px solid var(--bordo);
  }

  /* Nella barra i tre menu' hanno una riga tutta loro e larghezze uguali: il comune non ha
     piu' bisogno di prendersi la riga intera per i suoi nomi lunghi. */
  .campo-luogo .sotto-campo:nth-of-type(3) {
    grid-column: auto;
  }

  /* Il campo riempie la sua cella come gli altri tre controlli della barra. Stretto a 14rem
     avvicinava le cifre al loro «€» — a 1512px ci sono 437px di vuoto in mezzo — ma lasciava
     un buco di 302px dentro la cella, e in una barra dove tutto il resto arriva al proprio
     bordo quel buco costa piu' della distanza che risparmia. La coerenza della fila vince
     sulla vicinanza fra numero e unita'. */
  .campo-valuta {
    max-width: none;
  }

  .periodo {
    flex-wrap: nowrap;
  }

  .periodo-estremo {
    flex: 1 1 0;
  }

  .periodo-estremo input {
    flex: 1;
    min-width: 0;
  }

  .periodo-giorni {
    font-size: 0.8rem;
  }

  /* Sotto la barra. Il tetto di lettura sta sulla colonna e non sulla lista: messo sulla
     lista, la colonna resterebbe larga e avanzerebbe un vuoto in mezzo alle due. La terza
     riga elastica serve perche' la cascata attraversa tutta la griglia ed e' molto piu'
     alta del pannello — senza, la griglia spalmerebbe la sua altezza su tutte le righe e
     le carte dei numeri scenderebbero sotto la piega. */
  .risultato:not([hidden]),
  .attesa:not([hidden]) {
    display: grid;
    grid-template-columns: minmax(0, 58rem) minmax(17rem, 21rem);
    grid-template-rows: auto auto 1fr;
    justify-content: space-between;
    column-gap: clamp(2rem, 1rem + 2.4vw, 3.5rem);
    align-items: start;
  }

  .eroi {
    grid-column: 2;
    grid-row: 1;
    grid-template-columns: 1fr;
  }

  .periodo-avviso {
    grid-column: 2;
    grid-row: 2;
  }

  .scalino {
    grid-column: 2;
    grid-row: 3;
  }

  .cascata,
  .attesa-voci {
    grid-column: 1;
    grid-row: 1 / -1;
    margin-top: 0;
  }

  /* L'attesa prende la stessa forma che avra' da calcolata — elenco a sinistra, pannello a
     destra — cosi' il click non sposta niente: riempie. */
  .attesa-invito {
    grid-column: 2;
    grid-row: 1;
    margin: 0 0 1rem;
  }

  .attesa-eroi {
    grid-column: 2;
    grid-row: 2;
    grid-template-columns: 1fr;
    margin: 0;
  }

  .titolo-sezione {
    margin-top: 0;
  }

  /* In un pannello da 21rem il numero grande deve stare in una riga sola: a corpo pieno
     «23.425,48 €» andrebbe a capo in mezzo alle migliaia, che e' il difetto peggiore che
     un numero possa avere. */
  .eroe-primario .eroe-valore,
  .attesa-eroe-primario .attesa-eroe-valore {
    font-size: 2.4rem;
  }

  .eroe-valore,
  .attesa-eroe-valore {
    font-size: 1.7rem;
  }
}

/* Schermo stretto
   ---------------
   La domanda «quanto mi arriva davvero» arriva quasi sempre lontano da una scrivania. Da
   telefono la struttura resta la colonna singola — il cruscotto qui non ci sta — e cambiano
   i bersagli: bottone e segmenti si allargano a tutta riga, perche' un pollice non e' un
   puntatore. I respiri e i corpi non compaiono piu' qui: li porta il `clamp`, che li fa
   crescere con la finestra invece di scattare a una soglia. */

@media (max-width: 34rem) {
  /* Le carte dei numeri si impilano. Affiancate promettevano di risparmiare scorrimento,
     ma erano le glosse a pagare: dieci righe da quindici caratteri in una colonna da 135px,
     due torri piu' alte della carta principale — e l'altezza delle torri si era gia' mangiata
     quasi tutto il risparmio per cui la coppia esisteva. Impilate, ogni carta tiene il corpo
     e il respiro delle altre e la glossa torna a una misura di lettura. */
  .eroi,
  .attesa-eroi {
    grid-template-columns: 1fr;
  }

  /* I due estremi del periodo si impilavano a larghezze diverse (200px e 192px): non e' una
     coppia, sembrava un difetto. Ora o stanno affiancati uguali o impilati uguali. */
  .periodo-estremo {
    flex: 1 1 11rem;
  }

  .periodo-estremo input {
    flex: 1;
    min-width: 0;
  }

  .campo-valuta {
    max-width: none;
  }

  .segmentato {
    display: flex;
    width: 100%;
  }

  .segmento {
    flex: 1;
    text-align: center;
  }

  .calcola {
    justify-self: stretch;
    width: 100%;
  }

  .risultato,
  .attesa {
    margin-top: 2rem;
    padding-top: 1.5rem;
  }

  .cascata {
    margin-top: 2rem;
  }

  /* L'etichetta di una voce puo' essere lunga («Detrazione per lavoro dipendente») e
     l'importo non deve mai spezzarsi per farle posto: e' il dato, il nome puo' andare a capo. */
  .voce-importo {
    white-space: nowrap;
  }
}
