/* ==========================================================================
   Base — il reset, la tipografia, il telaio della pagina.
   Legge i token e non ne dichiara nessuno.

   Il telaio e' una griglia a due colonne: la barra laterale e il contenuto.
   LA BARRA LATERALE E' VERDE PROFONDA (--g-700), e questo e' l'unico posto
   dell'applicazione in cui il verde del sito di riferimento compare come
   superficie grande. E' la ragione per cui l'app si riconosce da un metro di
   distanza, e il motivo per cui il verde del sito non e' sparso altrove: un
   accento usato in dieci posti non e' piu' un accento.

   Tre debiti del sistema precedente, pagati qui:
   1. una sola larghezza di contenuto (1280px) tagliava la nona colonna
      dell'elenco delle Uscite a 1440px di finestra. Ora sono due, --w-data e
      --w-read, e la pagina dichiara quale vuole;
   2. il nome di un gruppo della barra laterale stava a 2,76:1 sul proprio
      fondo. Ora --on-dark-2 sta a 6,16:1;
   3. il breakpoint del cassetto (860) era scritto in due file e nessun test lo
      verificava. Ora e' un token, e il JavaScript lo legge da
      getComputedStyle.
   ========================================================================== */

/* ── Reset ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-base);
  color: var(--n-800);
  background: var(--bg-page);
  /* Le cifre si dichiarano tabellari qui, una volta, per tutto il documento.
     E' una RICHIESTA che il font puo' ignorare, e lo si e' misurato: la pila di
     sistema risolve in Noto Sans, le cui cifre sono gia' a larghezza fissa
     (dieci «1» e dieci «0» a 15px: 85,81px entrambi, scarto 0,00px), mentre su
     un font senza tabella `tnum` la proprieta' e' INERTE (scarto 5,00px prima
     e dopo). Costa zero e vince sui font che hanno `tnum` senza attivarlo di
     default, ma la garanzia dell'incolonnamento NON viene da qui: viene
     dall'allineamento a destra e dalla larghezza fissa delle colonne di
     importi. Vedi .c-table__num in components.css. */
  font-variant-numeric: tabular-nums;
}

img, svg, video { max-width: 100%; height: auto; }
svg { display: block; }

form { margin: 0; }

button, input, select, textarea { font: inherit; color: inherit; }

/* L'ANELLO DI FUOCO, uno per tutta l'applicazione, senza eccezioni.
   Il token e' stato risolto per passare su tutti e sette i fondi su cui puo'
   comparire, bottone verde pieno compreso: li' --g-400 avrebbe fatto 2,26:1.
   2px di spessore e 2px di scostamento, cosi' l'anello non mangia il bordo del
   controllo che segna. Da nessuna parte, in nessun foglio, esiste un
   `outline: none`: lo verifica un test. */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--radius-inner);
}

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

/* I CONTROLLI NATIVI. Una riga che governa ogni casella e ogni radio
   dell'applicazione: i dodici file con una casella di filtro, i tre radio del
   pagatore, ogni selezione multipla.

   Il verde del sito (--g-200) qui NON va, e la ragione non e' quella che
   sembra. Il primo sospetto era che il segno di spunta bianco diventasse
   invisibile dentro il verde chiaro: misurato rendendo con Chromium e leggendo
   i pixel, e' FALSO — il browser adatta il segno da se', #3B3B3B dentro
   #8DF868 (8,41:1) e bianco dentro i verdi scuri.
   L'argomento vero e' piu' stringente: cio' che deve distinguersi non e' il
   segno dal suo fondo, e' LA CASELLA SPUNTATA DALLA PAGINA BIANCA. WCAG 1.4.11
   chiede 3:1 allo stato di un controllo, e --g-200 sul bianco fa 1,33:1: una
   casella spuntata si leggerebbe solo dal segno.
   --g-600 fa 7,06:1, ed e' anche il verde che tutti i motori riempiono con un
   segno bianco senza dover calcolare niente. */
input[type="checkbox"], input[type="radio"] { accent-color: var(--g-600); }

::selection { background: var(--g-100); color: var(--n-900); }

/* ── Tipografia ────────────────────────────────────────────────────────── */
h1, h2, h3, h4 {
  margin: 0;
  font-weight: var(--fw-semi);
  line-height: var(--lh-tight);
  color: var(--n-900);
  /* Un titolo lungo non deve spezzare una parola a meta' quando la colonna si
     stringe: preferisce andare a capo prima. */
  text-wrap: balance;
}

/* h1 di pagina e h2 di scheda condividono il gradino, e non e' una svista.
   In una pagina di dati la gerarchia la fanno la POSIZIONE e lo SPAZIO BIANCO:
   due corpi diversi creerebbero un terzo gradino che non porta informazione. Il
   sistema precedente li separava a 17 e 13, e il risultato era un titolo di
   scheda indistinguibile dal testo della tabella che conteneva. */
h1, h2 { font-size: var(--fs-title); }
h3     { font-size: var(--fs-body); }
h4     { font-size: var(--fs-small); }

p { margin: 0 0 var(--sp-3); }
p:last-child { margin-bottom: 0; }

a { color: var(--g-600); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--g-700); }

code, kbd, samp { font-family: var(--font-mono); font-size: 0.9em; }
code, kbd {
  padding: 0 var(--sp-1);
  background: var(--n-100);
  border-radius: var(--radius-inner);
}

hr {
  height: 1px;
  margin: var(--sp-5) 0;
  border: 0;
  background: var(--n-200);
}

fieldset { margin: 0; padding: 0; border: 0; }
legend {
  padding: 0;
  font-size: var(--fs-micro);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--n-500);
}

/* ── Il salto al contenuto ─────────────────────────────────────────────── */
.c-skiplink {
  position: absolute;
  left: var(--sp-3);
  top: calc(-1 * var(--h-control) - var(--sp-3));
  z-index: 100;
  display: inline-grid;
  place-items: center;
  height: var(--h-control);
  padding: 0 var(--sp-4);
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  color: var(--n-900);
  background: var(--g-200);
  border-radius: var(--radius-control);
  transition: top var(--t-state) var(--ease);
}
.c-skiplink:focus-visible { top: var(--sp-3); }

/* ── Struttura di pagina ───────────────────────────────────────────────── */
.l-app {
  display: grid;
  grid-template-columns: var(--w-sidebar) minmax(0, 1fr);
  min-height: 100vh;
  /* `100dvh` non si usa: su iOS cambia all'apparire della barra degli
     indirizzi, e una griglia che si ridimensiona mentre si scorre fa saltare
     ogni elemento appiccicato. */
}

/* La preferenza arriva da un COOKIE, cioe' dal server: con localStorage la
   prima pittura sarebbe sempre quella aperta e chi ha chiuso la barra la
   vedrebbe saltare a ogni navigazione. */
.l-app.is-collapsed { grid-template-columns: var(--w-sidebar-rail) minmax(0, 1fr); }

.l-app__side {
  grid-row: 1;
  background: var(--g-700);
  /* Il filo non e' un grigio: e' un verde della stessa famiglia, perche' su un
     fondo cosi' scuro un grigio neutro si legge come una riga sporca. */
  border-inline-end: 1px solid var(--on-dark-3);
  /* La barra non scorre con la pagina: ha il suo porto. */
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* La barra di scorrimento della colonna scura va dichiarata, altrimenti il
     browser la dipinge chiara su fondo scuro. */
  scrollbar-color: var(--on-dark-3) transparent;
  scrollbar-width: thin;
}

.l-app__main {
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  min-width: 0;   /* senza questo una tabella larga sfonda la griglia */
}

/* ── La barra in alto ──────────────────────────────────────────────────── */
.l-topbar {
  display: grid;
  /* QUATTRO colonne: comando del menu + sezione · i due bottoni di
     registrazione · la ricerca, che prende tutto quel che resta · le azioni.
     I due bottoni stanno PRIMA della ricerca e non dopo: si leggono da sinistra
     insieme al nome della sezione, e il campo di ricerca resta l'elemento
     elastico — spostandoli a destra, ogni parola in piu' nel nome della sezione
     li farebbe ballare. */
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-4);
  height: var(--h-topbar);
  padding-inline: var(--sp-4);
  background: var(--n-000);
  border-block-end: 1px solid var(--n-200);
  position: sticky;
  top: 0;
  z-index: 20;
}

.l-topbar__lead { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.l-topbar__toggleform { display: contents; }

/* I due gesti piu' frequenti. `white-space: nowrap` sul bottone: «+ Uscita» che
   va a capo in «+» e «Uscita» su due righe alte sedici pixel e' il modo in cui
   una barra alta 56 px si rompe. */
.l-topbar__new { display: flex; gap: var(--sp-2); }
.l-topbar__new .c-btn { white-space: nowrap; }

/* Il nome della sezione, NON un <h1>: l'h1 della pagina sta in <main>, dentro
   .l-pagehead. Qui sarebbe dentro il landmark `banner`, cioe' chi salta al
   contenuto principale si lascerebbe indietro il titolo. */
.l-topbar__section {
  margin: 0;
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  color: var(--n-500);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Tre oggetti a destra e non quattro: il selettore del tema e' stato soppresso
   (un tema solo), quindi il passo del gruppo e' rimisurato su tre. */
.l-topbar__actions { display: flex; align-items: center; gap: var(--sp-2); }

.l-topbar__avatar { display: inline-grid; place-items: center; border-radius: var(--radius-pill); }

/* ── Il marchio ────────────────────────────────────────────────────────── */
.l-brand {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--h-topbar);
  padding-inline: var(--sp-4);
  color: var(--on-dark-1);
  text-decoration: none;
  border-block-end: 1px solid var(--on-dark-3);
}

.l-brand__mark {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: none;
  font-size: var(--fs-small);
  font-weight: var(--fw-semi);
  /* Il marchio e' l'unico posto in cui il verde del sito tocca il verde
     profondo: 8,36:1 di stacco, e il simbolo sopra e' --n-900 a 12,84:1.
     Qui c'era 15,76:1, che e' il rapporto del NERO PURO su --g-200: giusto come
     numero, sbagliato come affermazione su questo inchiostro, che nero non e'. */
  color: var(--n-900);
  background: var(--g-200);
  border-radius: var(--radius-control);
}

/* Il marchio si distingue con la SPAZIATURA, non col peso: il 700 non esiste
   piu' nel sistema, e a questo corpo avrebbe impastato. */
.l-brand__name {
  font-size: var(--fs-body);
  font-weight: var(--fw-semi);
  letter-spacing: var(--ls-label);
  white-space: nowrap;
  overflow: hidden;
}

.l-brand:hover { color: var(--on-dark-pill); }

.is-collapsed .l-brand { padding-inline: 0; justify-content: center; }
.is-collapsed .l-brand__name { display: none; }

/* ── Il piede della barra laterale: l'account ──────────────────────────── */
.l-account {
  margin-top: auto;
  padding: var(--sp-3) var(--sp-4);
  border-block-start: 1px solid var(--on-dark-3);
}

.l-account__user {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2);
  color: var(--on-dark-1);
  text-decoration: none;
  border-radius: var(--radius-control);
}
.l-account__user:hover { background: var(--g-800); }

.l-account__text { min-width: 0; display: grid; }
.l-account__name {
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 6,16:1 sul fondo della barra. Il sistema precedente metteva questo testo a
   2,76:1, cioe' sotto ogni soglia, e lo dichiarava come debito nel proprio
   commento. */
.l-account__role { font-size: var(--fs-micro); color: var(--on-dark-2); }

/* IL BOTTONE «ESCI» E' L'UNICO CONTROLLO DELL'APPLICAZIONE SU FONDO SCURO, e
   senza queste tre righe prendeva --n-600 — l'inchiostro del bottone quieto, che
   e' pensato per una scheda bianca. Misurato sulla pagina resa: 1,58:1 sul verde
   della barra, cioe' invisibile. Un comando che nessuno vede non e' un comando
   discreto: e' un comando rotto, e questo e' quello con cui si esce.
   --on-dark-2 porta 6,16:1, e il bordo --on-dark-3 gli ridà i confini. */
.l-account .c-btn--quiet {
  color: var(--on-dark-2);
  /* Senza bordo, come ogni bottone quieto. Un filetto in --on-dark-3 misurerebbe
     1,58:1 sul fondo della barra: sotto il 3:1 che il sistema chiede a un
     confine, cioe' un contorno che si intuisce invece di vedersi. Qui a dire che
     e' un comando basta l'etichetta, che sta a 6,16:1. */
  border-color: transparent;
}
.l-account .c-btn--quiet:hover {
  color: var(--on-dark-1);
  background: var(--g-800);
  border-color: transparent;
}

.is-collapsed .l-account { padding-inline: var(--sp-2); }
.is-collapsed .l-account__text { display: none; }
.is-collapsed .l-account__user { justify-content: center; }

/* ── Il contenuto ──────────────────────────────────────────────────────── */
.l-content {
  width: 100%;
  max-width: var(--w-read);
  margin-inline: auto;
  padding: var(--sp-5) var(--sp-4) var(--sp-6);
  min-width: 0;
}

/* Un REGISTRO e' piu' largo di un DOCUMENTO, e la pagina lo dichiara mettendo
   `is-wide` su <main>. I numeri, misurati rendendo e fotografando — il conto
   scritto qui prima («1440px con padding --sp-3») era sbagliato due volte:
   `--sp-3` su `.l-content` vale solo sotto gli 860px, dove `is-wide` non puo'
   applicarsi, e il 1440 non arriva mai intero al contenuto.

   Il padding in forza e' `--sp-4`, 16px per lato. La barra laterale prende
   `--w-sidebar`, 248px. Quindi:
     finestra 1920 -> <main> 1440 (il tetto), cassa utile 1408
     finestra 1688 -> <main> 1393, e da qui in giu' comanda la finestra
     finestra 1440 -> <main> 1192, cassa utile 1160
   A 1440 le otto colonne di /uscite ne chiedono 1164 e il porto ne offre 1128:
   scorrono di 36px, ed e' esattamente il lavoro del porto. Da 1536 in su
   nessuna tabella scorre piu'. */
.l-content.is-wide { max-width: var(--w-data); }


/* Il passo verticale fra i blocchi di una pagina. Scritto come «fratello che
   segue» invece che come margine di ciascuno: cosi' il primo blocco non porta
   mai un margine superiore da annullare. */
.l-content > * + * { margin-block-start: var(--sp-5); }

.l-footer {
  padding: var(--sp-5) var(--sp-4);
  font-size: var(--fs-micro);
  color: var(--n-500);
  text-align: center;
}
.l-footer p { margin: 0; }

/* ── L'intestazione di pagina: due righe, e la seconda e' un dato ───────── */
.l-pagehead {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-block-end: var(--sp-5);
}

/* `flex: 1 1 24rem` e non la base automatica. In un contenitore che va a capo il
   browser dispone gli elementi PRIMA di restringerli: con la base sul contenuto,
   un sottotitolo lungo riempiva da solo la riga e l'azione finiva sotto, a
   sinistra. Fotografate a 1440 px: su /conti e /scadenze il bottone stava in
   alto a destra, su /ricorrenze e /regole sotto il sottotitolo — stessa
   struttura, due posti diversi in cui cercarlo, e a deciderlo era la lunghezza
   di una frase. Con una base di 24rem il testo si restringe e l'azione resta in
   riga; sotto quella soglia va a capo come deve. */
.l-pagehead__text { display: grid; gap: var(--sp-1); min-width: 0; flex: 1 1 24rem; }

/* L'AMBITO E' UN VALORE, NON UNA FRASE. «Anno 2026», «al 07/10/2026», «dal
   01/09 al 30/09», «Tutto il libro · nessuna data». Mai «Si aggiorna da solo:
   basta registrare uscite ed entrate».
   E' meta' dell'identita' di un documento contabile — un Riepilogo che non dice
   a quando si riferisce non si porta da nessuna parte — e resta in TESTO oltre
   che nel selettore, perche' in stampa i controlli non ci sono.
   Nessuna riga di prosa sta fra il titolo e il primo numero: le spiegazioni
   vanno sotto la grandezza che spiegano, o nello stato vuoto. */
/* La stessa regola serve all'ambito di una REGIONE: una regione dichiara il
   proprio ambito esattamente come lo dichiara una pagina, e due dichiarazioni
   separate divergerebbero al primo ritocco. */
.l-pagehead__scope,
.l-region__scope {
  margin: 0;
  font-size: var(--fs-small);
  color: var(--n-500);
  font-variant-numeric: tabular-nums;
}

.l-pagehead__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }

/* «Stampato il …»: si stampa e non si vede a schermo. E' informazione del
   foglio, non della pagina. La regola di stampa sta in print.css. */
.l-pagehead__printed { display: none; }

/* ── Le griglie ────────────────────────────────────────────────────────── */
.l-grid { display: grid; gap: var(--sp-4); }

/* Le tessere: tante quante stanno, mai piu' strette di quanto un numero a 22px
   con la sua etichetta richieda. */
.l-grid--tiles { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

/* Due colonne che diventano una sotto la soglia stretta. Il minmax(0,1fr) e'
   obbligatorio: con `1fr` una tabella larga dentro una colonna la sfonda. */
.l-grid--halves { grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); }

.l-grid > * { min-width: 0; }

/* ── Le sezioni ────────────────────────────────────────────────────────── */
/* Il distacco fra due SEZIONI e' --sp-6: una sezione non ha bordi propri, il
   bordo e' della scheda che contiene. */
.l-section { display: grid; gap: var(--sp-4); }
.l-content > .l-section + .l-section { margin-block-start: var(--sp-6); }

.l-section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
}

.l-section__note {
  margin: 0;
  max-width: var(--measure-prose);
  font-size: var(--fs-small);
  color: var(--n-500);
}

/* ── Le regioni ──────────────────────────────────────────────── */
/* Un gruppo di sezioni che leggono la STESSA data, con l'ambito dichiarato nella
   propria testata. Nasce dal Riepilogo, dove sette blocchi su undici non
   filtrano per data e quattro leggono l'anno del selettore: finche' stavano in un
   elenco solo, il selettore in cima alla pagina sembrava governarli tutti.

   Il passo verticale lo porta la REGIONE e non le sezioni: la regola qui sopra e'
   un selettore di figlio diretto di `.l-content`, e dentro un contenitore le
   sezioni perderebbero il distacco di --sp-6 e si toccherebbero. */
.l-region { display: grid; gap: var(--sp-6); }

/* Le sezioni di una regione sono BERSAGLI D'ANCORA, e sopra di loro ci sono due
   barre appiccicate: senza margine di scorrimento l'indice porterebbe il titolo
   della sezione dietro l'indice stesso. --h-topbar per la barra in alto, --sp-7
   per l'indice piu' un filo d'aria. */
.l-region .l-section { scroll-margin-block-start: calc(var(--h-topbar) + var(--sp-7)); }

/* La testata: la stessa forma di `.l-pagehead` — titolo e ambito a sinistra, il
   controllo che cambia l'ambito a destra — chiusa da un filetto a tutta
   larghezza. E' IL FILETTO CHE DIVIDE: il titolo resta al gradino degli altri
   <h2>, perche' in questo sistema la gerarchia la fanno la posizione e lo spazio
   bianco, e un terzo corpo di carattere non porterebbe informazione. */
.l-region__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-block-end: var(--sp-2);
  border-block-end: 2px solid var(--n-300);
}

/* Titolo e ambito incolonnati, e il gruppo e' l'elemento elastico della testata:
   senza, col selettore dell'anno accanto, l'ambito finirebbe su una riga sua. */
.l-region__text { display: grid; gap: var(--sp-1); min-width: 0; }

/* Il titolo di una regione interpola un ANNO: le cifre sono tabulari come in ogni
   altro posto in cui questa applicazione stampa un numero. */
.l-region__title { font-variant-numeric: tabular-nums; }

/* ── L'accesso ─────────────────────────────────────────────────────────── */
.l-auth {
  display: grid;
  place-items: center;
  gap: var(--sp-5);
  min-height: 100vh;
  padding: var(--sp-5);
  background: var(--bg-page);
}

.l-auth__brand {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-title);
  font-weight: var(--fw-semi);
  letter-spacing: var(--ls-label);
  color: var(--n-900);
  text-decoration: none;
}

.l-auth__card {
  width: 100%;
  max-width: 400px;
  padding: var(--sp-5);
  background: var(--n-000);
  border: 1px solid var(--n-200);
  border-radius: var(--radius-card);
}

.l-auth__title { margin-block-end: var(--sp-4); }

/* Lo stato vuoto nasce per stare SOLO in mezzo a una pagina, quindi porta un
   fondo e un bordo. Dentro la scheda dell'accesso la scheda c'e' gia': qui si
   spoglia e tiene solo il testo centrato. */
.l-auth__card .c-empty {
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
}

/* ── Sotto la soglia stretta ───────────────────────────────────────────── */
/* 860px, e il numero e' il token --bp-narrow. Una media query non puo' leggere
   una custom property, quindi il valore e' scritto qui una volta e il token
   esiste perche' il JavaScript lo legga da getComputedStyle invece di
   ripeterlo: era scritto in due file e nessun test lo verificava. */
@media (max-width: 860px) {
  .l-app, .l-app.is-collapsed { grid-template-columns: minmax(0, 1fr); }

  /* La barra diventa una FASCIA in testa alla pagina: resta solo il <summary>,
     alto come la barra in alto, e il menu esce da sotto.

     Non e' un cassetto che scorre da sinistra, e la differenza non e' estetica:
     un cassetto traslato porta via con se' il proprio comando, quindi senza
     JavaScript non si potrebbe piu' chiudere. Qui il comando resta in testa,
     appiccicato, e si tocca due volte: apri e chiudi. */
  .l-app__side {
    position: sticky;
    top: 0;
    z-index: 40;
    width: auto;
    height: auto;
    overflow: visible;
    border-inline-end: 0;
    border-block-end: 1px solid var(--on-dark-3);
  }
  /* Il resto della tendina sta in components.css, con la sua soglia: base.css
     viene PRIMA nell'ordine dei fogli e una media query non aggiunge
     specificita', quindi una regola di componente scritta qui verrebbe annullata
     dalla regola senza soglia che la segue. */

  /* Il dito e' un puntatore piu' grosso del mouse: 44px e' la raccomandazione,
     e sotto questa soglia si applica a ogni controllo. */
  :root { --h-control: 44px; }

  .l-content { padding-inline: var(--sp-3); }
  .l-topbar {
    grid-template-columns: auto minmax(0, 1fr) auto;
    padding-inline: var(--sp-3);
  }
  /* I due bottoni di registrazione escono dalla barra: su uno schermo stretto
     non c'e' larghezza per due etichette, la ricerca e le azioni insieme, e il
     primo a cedere sarebbe il campo di ricerca. Il gesto non si perde — in
     testa a ogni elenco c'e' il suo «Aggiungi», che su questa larghezza e'
     l'unico posto in cui serve. */
  .l-topbar__new { display: none; }
}

/* ── Utility ───────────────────────────────────────────────────────────────
   Si contano su una mano e mezza, e ognuna fa UNA cosa. Una utility non puo'
   avere un modificatore: se serve, e' un componente.
   Spariscono `u-right` e `u-center`, che nessuna view usava: l'allineamento di
   una colonna di importi e' una proprieta' della tabella, non una decisione da
   prendere riga per riga. */
.u-nowrap  { white-space: nowrap; }
.u-muted   { color: var(--n-500); }
.u-small   { font-size: var(--fs-small); }
.u-mono    { font-family: var(--font-mono); }
.u-stack   { display: grid; gap: var(--sp-3); }
.u-row     { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.u-prose   { max-width: var(--measure-prose); }

/* Testo per chi usa uno screen reader: presente nel DOM, invisibile a schermo.
   `clip-path` e non `display: none`, che lo toglierebbe anche a loro. */
.u-visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
