﻿/* ============================================================
   LE TRE TAGLIE DELLE ICONE

   `slIco()`, `ctIco()` e compagni chiedono un'icona piccola scrivendo
   `class="xs"`, ma la regola che la rimpicciolisce non e' mai esistita:
   dove nessun antenato dava una misura, lucide disegnava alla sua —
   ventiquattro pixel, il doppio del testo che le sta accanto.

   Stanno in cima apposta. Hanno la stessa specificita' delle regole per
   componente (`.tag svg`, `.kpi-icon svg`, `.empty-state>svg`), quindi a
   parita' vince l'ultima scritta: mettendole qui, ogni misura decisa piu'
   sotto continua a valere e queste fanno solo da rete.

   Sono scritte su `svg` e non su `.xs` per non incrociare `.btn.xs`, che
   e' un bottone e non un'icona.
   ============================================================ */
svg.lucide{width:16px;height:16px;flex-shrink:0;}
svg.l{width:20px;height:20px;}
svg.s{width:14px;height:14px;}
svg.xs{width:12px;height:12px;}

/* Header timer chip */
.header-timer{display:flex;align-items:center;gap:9px;background:var(--primary-soft);border:1px solid var(--primary-mid);border-radius:11px;padding:6px 8px 6px 12px;font-size:12.5px;}
.header-timer .dot{width:7px;height:7px;border-radius:50%;background:var(--primary);flex-shrink:0;animation:pulseDot 1.4s infinite;}
@keyframes pulseDot{0%,100%{opacity:1;}50%{opacity:.35;}}
.header-timer .ht-info{display:flex;flex-direction:column;line-height:1.25;}
.header-timer .ht-client{font-weight:700;color:var(--primary-dark);}
.header-timer .ht-task{color:var(--muted);font-size:11px;max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.header-timer .ht-clock{font-variant-numeric:tabular-nums;font-weight:700;margin-left:4px;}
.header-timer .ht-actions{display:flex;gap:3px;}
.header-timer .ht-actions button{width:26px;height:26px;border-radius:8px;border:none;background:var(--card);display:flex;align-items:center;justify-content:center;color:var(--primary-dark);}
.header-timer .ht-actions button:hover{background:var(--primary-soft);}
.header-timer .ht-actions button svg{width:13px;height:13px;}
.header-start-btn{background:var(--card);border:1px solid var(--border);}

/* KPI */
.kpis{display:grid;gap:14px;margin-bottom:18px;}
.kpis.n4{grid-template-columns:repeat(4,1fr);}
.kpis.n5{grid-template-columns:repeat(5,1fr);}
.kpis.n3{grid-template-columns:repeat(3,1fr);}
.kpi-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 18px;box-shadow:var(--shadow);}
.kpi-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;}
.kpi-icon{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;}
.kpi-icon svg{width:15px;height:15px;}
.kpi-label{font-size:12.5px;color:var(--muted);font-weight:600;}
.kpi-value{font-size:22px;font-weight:700;letter-spacing:-.3px;margin-bottom:3px;}
.kpi-sub{font-size:12px;color:var(--muted);margin-bottom:9px;}
.kpi-sub.up{color:var(--green);font-weight:600;}
.progress{height:5px;border-radius:5px;background:var(--track);overflow:hidden;}
.progress>div{height:100%;border-radius:5px;}
/* Il pieno di partenza. Alcune barre non ne dichiaravano nessuno (i
   progetti nella scheda di un cliente) e restavano un binario vuoto a
   qualunque percentuale. `:where` lo tiene al peso di un elemento: una
   barra che ha il suo colore (`.tt-seg-over`, `.mnav-week-bar > div`) vince
   senza doverlo chiedere. */
:where(.progress) > div{background:var(--primary);}

.layout2{display:grid;grid-template-columns:1.5fr 1fr;gap:16px;align-items:start;}
.layout3{display:grid;grid-template-columns:2fr 1fr;gap:16px;align-items:start;}
.card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);padding:var(--card-y);margin-bottom:16px;}
.card-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;flex-wrap:wrap;gap:10px;}
.card-title{font-size:14px;font-weight:700;}
.card-title .count{color:var(--muted);font-weight:500;font-size:12.5px;}
/* La variante con l'icona nel quadratino. Stava in `admin.css`, cioe' nel
   foglio di una pagina, e vestiva il titolo di scheda di tutte. */
.card-title.with-icon{display:flex;align-items:center;gap:10px;}
.card-title.with-icon>svg{width:15px;height:15px;padding:5px;box-sizing:content-box;border-radius:8px;background:var(--primary-soft);color:var(--primary-dark);flex-shrink:0;stroke-width:2;}
.tabbtns{display:flex;gap:6px;background:var(--track);border-radius:9px;padding:3px;flex-wrap:wrap;}
.tabbtns button,.tabbtns a{display:inline-flex;align-items:center;gap:6px;background:transparent;border:none;padding:6px 12px;font-size:12.5px;font-weight:600;border-radius:7px;color:var(--muted);}
.tabbtns button svg,.tabbtns a svg{width:14px;height:14px;flex-shrink:0;}
.tabbtns a{cursor:pointer;text-decoration:none;}
.tabbtns button.active,.tabbtns a.active{background:var(--card);color:var(--text);box-shadow:0 1px 2px rgba(0,0,0,.06);}

/* ---- Pillole di navigazione tra pagine di un modal (es. editor servizio) ---- */
.pager-pills{display:flex;gap:2px;flex-wrap:wrap;}
.pager-pills button{display:flex;align-items:center;gap:5px;background:transparent;border:none;padding:5px 10px;font-size:11.5px;font-weight:600;border-radius:8px;color:var(--muted);}
.pager-pills button:hover{color:var(--text);}
.pager-pills button.active{background:var(--primary-soft);color:var(--primary-dark);}
/* Il selettore deve prendere l'svg, non l'<i>: lucide sostituisce l'elemento
   e la classe si perde per strada. L'<i> resta elencato per quando le icone
   non si caricano e il segnaposto rimane al suo posto. */
.pager-pills button svg,.pager-pills button i{width:12px;height:12px;flex-shrink:0;}

/* ---- il campo ----
   La stessa grammatica stava scritta quattro volte, una per pagina
   (`.pf-wrap .field`, `.set-wrap .field`, `.tm-db .field`, `.sl-input`):
   quattro copie che si sarebbero allontanate al primo ritocco. Qui sta una
   volta; le pagine aggiungono solo quello che hanno di diverso.

   `.form-row input` in `tasks.css` resta a se': li' i campi non portano
   una classe, e dargliela vorrebbe dire toccare il markup di ogni modale
   dell'app. E' l'ultima copia rimasta. */
.field{width:100%;min-width:0;border:1px solid var(--border);background:var(--card);border-radius:9px;
  padding:8px 10px;font-size:13px;font-family:inherit;color:inherit;outline:none;}
.field:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft);}
.field.bad{border-color:var(--red);}
.field[readonly]{background:var(--field);color:var(--neutral-ink);}
.field:disabled{color:var(--neutral-ink);cursor:not-allowed;}
textarea.field{resize:vertical;line-height:1.45;}

.badge{display:inline-flex;align-items:center;gap:4px;font-size:10.5px;font-weight:700;padding:3px 8px;border-radius:6px;white-space:nowrap;}
/* Pastiglia di stato generica, sorella di `.badge` ma per gli stati di una
   funzione (attiva, da collegare, spenta) invece che di un record. */
.tag{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;white-space:nowrap;background:var(--track);color:var(--neutral-ink);}
.tag svg{width:12px;height:12px;flex:0 0 auto;}
.tag.t-ok{background:var(--primary-soft);color:var(--primary-dark);}
.tag.t-warn{background:var(--amber-soft);color:var(--amber-dark);}
.tag.t-neutral{background:var(--track);color:var(--neutral-ink);}
/* min-height di .aselect va annullato: qui il controllo è un badge, non un campo */
.badge.aselect.badge-toggle{cursor:pointer;padding:5px 9px 5px 11px;font-size:12px;position:relative;min-height:0;gap:5px;}
.badge.aselect.badge-toggle:hover{filter:brightness(.96);}
.badge.aselect.badge-toggle.open{filter:brightness(.94);}
.badge.aselect.badge-toggle .aselect-chevron{width:11px;height:11px;opacity:.65;}
.badge-alta{background:var(--red-soft);color:var(--red-dark);}
.badge-media{background:var(--amber-soft);color:var(--amber-dark);}
.badge-bassa{background:var(--green-soft);color:var(--green-dark);}
.badge-billable{background:var(--green-soft);color:var(--green-dark);}
/* "Fatto / arrivato / a posto" e' arancione, non verde: il verde in questa
   palette resta solo il fondo della pastiglia di stato "Completato". */
.badge-ok{background:var(--primary-soft);color:var(--primary-dark);}
.badge-nonbillable{background:var(--track);color:var(--neutral-ink);}
.badge-forfait{background:var(--violet-soft);color:var(--violet);}
.badge-status-attivo{background:var(--blue-soft);color:var(--blue);}
.badge-status-completato{background:var(--green-soft);color:var(--green-dark);}
.badge-status-inrevisione{background:var(--violet-soft);color:var(--violet);}
.badge-status-incorso{background:var(--blue-soft);color:var(--blue);}
.badge-status-dafare{background:var(--track);color:var(--neutral-ink);}
.badge-status-backlog{background:var(--track);color:var(--neutral-ink);}
.badge-status-pausa{background:var(--amber-soft);color:var(--amber-dark);}
.badge-status-attesa{background:var(--violet-soft);color:var(--violet);}
.badge-status-dainiziare{background:var(--track);color:var(--neutral-ink);}
.badge-status-archiviato{background:var(--track);color:var(--neutral-ink);}
.badge-status-lead{background:var(--blue-soft);color:var(--blue);}
.badge-status-prospect{background:var(--violet-soft);color:var(--violet);}
.badge-status-concluso{background:var(--track);color:var(--neutral-ink);}
.badge-tag{background:var(--track);color:var(--neutral-ink);font-weight:700;font-size:9.5px;text-transform:uppercase;letter-spacing:.3px;}
.badge-blocked{background:var(--red-soft);color:var(--red-dark);}
.badge-label{background:var(--track);color:var(--neutral-ink);font-weight:700;text-transform:uppercase;letter-spacing:.3px;font-size:9.5px;}
.badge-overdue{background:var(--red-soft);color:var(--red-dark);}
.badge-today{background:var(--amber-soft);color:var(--amber-dark);}
.badge-upcoming{background:var(--track);color:var(--neutral-ink);}
.client-dot{width:7px;height:7px;border-radius:50%;display:inline-block;flex-shrink:0;}
/* Testo per chi legge con lo schermo, invisibile a chi guarda: serve dove
   una colonna ha solo icone e l'intestazione resterebbe muta. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;}
/* ---- l'etichetta di un cliente (design B) ----
   Una pillola — il raggio pieno, la forma che nessun badge di stato ha —
   con un tondo pieno nella tinta del cliente e la sua icona di settore in
   bianco (`core/client-icons.js`), e il nome nella tinta scura su un fondo
   appena tinto. Tre mescole, e ognuna ha un mestiere:
   - il **fondo** e' la tinta al 13% sulla scheda: di notte la scheda e'
     scura, e il fondo si scurisce con lei;
   - il **nome** e' la tinta a meta' con l'inchiostro del testo: sulle otto
     tinte della tavolozza non scende sotto 4,7:1, in tutti e due i temi;
   - il **tondo** e' la tinta con un quarto di `--inverse`, perche' il
     bianco dell'icona regga anche sul lime e sul ciano: 3:1, la soglia di
     un segno grafico. La tinta pura, li', la farebbe sparire.
   `--tint` viene dal record e lo scrive `dsTint()`, che accetta solo un
   esadecimale o un token. L'icona e' della libreria dei clienti
   (`.cg`), forme piene pensate per queste misure. */
.cg{display:block;flex:none;fill:currentColor;}
.client-chip{--cl-tint:var(--tint,var(--primary));display:inline-flex;align-items:center;gap:8px;max-width:100%;min-width:0;
  padding:2px 12px 2px 2px;border-radius:999px;
  background:color-mix(in srgb, var(--cl-tint) 13%, var(--card));
  color:color-mix(in srgb, var(--cl-tint) 50%, var(--text));
  font-size:12px;font-weight:700;line-height:1.3;white-space:nowrap;vertical-align:middle;}
.client-chip .chip-icon,.client-mark{flex:none;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;
  background:color-mix(in srgb, var(--tint,var(--primary)) 75%, var(--inverse));color:var(--on-accent);}
.client-chip .chip-icon{width:21px;height:21px;}
.client-chip .chip-icon svg{width:12px;height:12px;}
.client-chip .chip-label{min-width:0;overflow:hidden;text-overflow:ellipsis;}
.client-chip.sm{padding:2px 10px 2px 2px;gap:6px;font-size:11px;}
.client-chip.sm .chip-icon{width:18px;height:18px;}
.client-chip.sm .chip-icon svg{width:10px;height:10px;}
/* Senza un cliente: la stessa forma, spenta. */
.client-chip.none{--cl-tint:var(--muted);}
.client-chip.none .chip-icon,.client-mark.empty{background:var(--track);color:var(--muted);}
/* Il segno da solo: lo stesso tondo, piu' piccolo. */
.client-mark{width:16px;height:16px;}
.client-mark svg{width:9px;height:9px;}
/* L'avatar: lo stesso tondo in grande, con l'icona nella stessa
   proporzione (dodici su ventuno). */
.client-ava{flex:none;display:inline-flex;align-items:center;justify-content:center;width:29px;height:29px;border-radius:50%;
  background:color-mix(in srgb, var(--tint,var(--primary)) 75%, var(--inverse));color:var(--on-accent);}
.client-ava svg{width:57%;height:57%;}
.client-ava.sm{width:21px;height:21px;}
.client-ava.lg{width:52px;height:52px;}
.client-ava.none{background:var(--track);color:var(--muted);}
/* Dentro a una tendina l'etichetta perde la pillola: la cornice ce l'ha
   gia' la tendina, e una pillola dentro a una cornice e' un riquadro dentro
   a un riquadro. Il nome torna del colore di chi la contiene. */
.aselect .client-chip{background:transparent;padding:0;color:inherit;}
.aselect .client-chip .chip-icon{width:18px;height:18px;}
.aselect .client-chip .chip-icon svg{width:10px;height:10px;}
/* ---- colore e icona di un cliente (`clientLookPickerHtml`) ----
   La scelta della procedura «Nuovo cliente» e della finestra della scheda:
   l'anteprima vera in cima, poi le otto tinte, poi le ventiquattro icone. */
.ci-look{display:flex;flex-direction:column;gap:14px;}
.ci-look-prev{display:flex;align-items:center;gap:14px;min-width:0;padding:12px 14px;border:1px solid var(--border);
  border-radius:12px;background:var(--field);}
.ci-look-txt{display:flex;flex-direction:column;align-items:flex-start;gap:6px;min-width:0;}
.ci-look-txt > span:last-child{font-size:12px;color:var(--muted);}
.ci-look-sec{display:flex;flex-direction:column;gap:7px;}
.ci-look-lab{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.3px;color:var(--muted);}
/* Le tinte sono gia' il tondo che il cliente avra', con l'icona dentro.
   Quella scelta ha un anello — lo spazio della scheda e poi l'inchiostro
   — e non solo un colore diverso. */
.ci-colors{display:flex;flex-wrap:wrap;gap:8px;}
.ci-color{display:flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;border:0;border-radius:50%;cursor:pointer;
  background:color-mix(in srgb, var(--tint,var(--primary)) 75%, var(--inverse));color:var(--on-accent);}
.ci-color svg{width:18px;height:18px;}
.ci-color.on{box-shadow:0 0 0 2px var(--card),0 0 0 4px var(--text);}
.ci-color:focus-visible{outline:2px solid var(--primary);outline-offset:4px;}
/* L'icona scelta si riconosce da tre cose e non da una — il fondo tinto,
   il bordo doppio, l'icona nella tinta — perche' uno stato detto solo dal
   colore non e' detto a tutti. */
.ci-grid{--cl-tint:var(--tint,var(--primary));display:grid;grid-template-columns:repeat(auto-fill,minmax(40px,1fr));gap:6px;}
.ci-opt{display:flex;align-items:center;justify-content:center;aspect-ratio:1;min-height:40px;padding:0;
  border:1px solid var(--border);border-radius:10px;background:var(--card);color:var(--neutral-ink);cursor:pointer;font:inherit;}
.ci-opt svg{width:17px;height:17px;}
.ci-opt:hover{background:var(--hover);color:var(--text);}
.ci-opt:focus-visible{outline:2px solid var(--primary);outline-offset:2px;}
.ci-opt.on{background:color-mix(in srgb, var(--cl-tint) 13%, var(--card));color:color-mix(in srgb, var(--cl-tint) 50%, var(--text));
  border-color:color-mix(in srgb, var(--cl-tint) 60%, var(--card));box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--cl-tint) 60%, var(--card));}
.ticket-key{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;font-weight:700;color:var(--muted);}
.type-icon{width:16px;height:16px;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;}
.type-icon svg{width:11px;height:11px;}
.type-icon.lg{width:26px;height:26px;border-radius:8px;}
.type-icon.lg svg{width:13px;height:13px;}

table{width:100%;border-collapse:collapse;font-size:13px;}
/* Le frecciette su e giu' dei campi numerici: rubano spazio al numero, si
   premono per sbaglio e cambiano un importo di un'unita' senza che te ne
   accorga. Si scrive la cifra, non la si incrementa. */
input[type=number]{-moz-appearance:textfield;appearance:textfield;}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}
/* L'aria intorno alle righe la decide la densita' scelta nel profilo:
   `--row-y` vale 10px di norma e 6px in compatta (base.css). */
th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.3px;color:var(--muted);font-weight:700;padding:var(--head-y) 10px;border-bottom:1px solid var(--border);}
td{padding:var(--row-y) 10px;border-bottom:1px solid var(--border);}
tr.clickable{cursor:pointer;}
tr.clickable:hover{background:var(--field);}
tr:last-child td{border-bottom:none;}
.table-wrap{overflow-x:auto;}

.filters{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:16px;align-items:center;}
.quick-filters{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:14px;}
.qf-chip{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--border);background:var(--card);border-radius:20px;padding:6px 13px;font-size:12px;font-weight:600;color:var(--muted);cursor:pointer;}
.qf-chip svg{width:13px;height:13px;flex-shrink:0;}
.qf-chip.active{background:var(--primary);color:var(--on-accent);border-color:var(--primary);}
.task-toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:16px;}
.task-toolbar .quick-filters,.task-toolbar .filters{margin-bottom:0;}
.filters-divider{width:1px;height:20px;background:var(--border);margin:0 2px;flex-shrink:0;}
.filter-rail{display:flex;align-items:center;gap:4px;}
/* In fondo alla corsia dei filtri non c'e' solo un selettore: c'e' anche un
   interruttore, ed e' un `<button>` vero, non un `.aselect`. Senza queste
   righe restava l'unico senza cornice e piu' piccolo degli altri — in fila
   con sette riquadri sembrava un'icona decorativa invece che un comando.
   Prende la stessa misura, la stessa cornice e lo stesso acceso degli altri:
   `aria-pressed` dice quando e' premuto, ed e' anche quello che lo colora. */
/* 33x37 e non 33x33: gli `.aselect.icon-only` accanto dichiarano 33px di
   altezza ma ne prendono 37 dal `min-height` della classe base, ed e' su
   quella misura che si allineano le pastiglie dei filtri. */
.filter-rail .icon-btn{width:33px;height:37px;border:1px solid var(--border);background:var(--field);border-radius:9px;cursor:pointer;}
.filter-rail .icon-btn:hover{background:var(--field);border-color:var(--primary-mid);color:var(--muted);}
.filter-rail .icon-btn svg{width:15px;height:15px;}
.filter-rail .icon-btn[aria-pressed="true"]{background:var(--primary-soft);border-color:var(--primary-soft);color:var(--primary-dark);}
.filter-rail .icon-btn[aria-pressed="true"]:hover{background:var(--primary-soft);color:var(--primary-dark);}
.filter-rail .icon-btn:disabled{opacity:.45;cursor:not-allowed;}
.filter-rail .icon-btn:disabled:hover{border-color:var(--border);}

.icon-btn{width:28px;height:28px;border-radius:8px;border:none;background:transparent;display:flex;align-items:center;justify-content:center;color:var(--muted);flex-shrink:0;}
.icon-btn:hover{background:var(--hover);color:var(--text);}
.icon-btn svg{width:14.5px;height:14.5px;}

/* Timer card (sidebar widget on dashboard) */
.timer-card{background:linear-gradient(160deg,var(--primary),var(--seg-3));color:var(--on-accent);border-radius:var(--radius);padding:20px;box-shadow:0 8px 24px rgba(255,122,69,.32);}
.timer-card .status{font-size:11.5px;opacity:.8;font-weight:600;text-transform:uppercase;letter-spacing:.4px;margin-bottom:9px;}
.timer-card .task-name{font-size:16px;font-weight:700;margin-bottom:3px;}
.timer-card .client-name{font-size:12.5px;opacity:.85;margin-bottom:16px;}
.timer-display{font-size:38px;font-weight:800;letter-spacing:1px;font-variant-numeric:tabular-nums;margin-bottom:14px;}
.timer-actions{display:flex;gap:8px;margin-bottom:12px;}
.timer-actions .btn{background:rgba(255,255,255,.16);color:var(--on-accent);flex:1;justify-content:center;}
.timer-actions .btn.stop{background:var(--card);color:var(--primary-dark);}
.timer-actions .btn:hover{background:rgba(255,255,255,.26);}
.timer-actions .btn.stop:hover{background:var(--primary-soft);}
.timer-foot{display:flex;justify-content:space-between;align-items:center;font-size:12px;opacity:.9;}
.toggle{width:34px;height:19px;background:rgba(255,255,255,.3);border-radius:20px;position:relative;cursor:pointer;flex-shrink:0;}
.toggle.on{background:var(--card);}
.toggle::after{content:'';position:absolute;width:15px;height:15px;background:var(--card);border-radius:50%;top:2px;left:2px;transition:.15s;}
.toggle.on::after{left:17px;background:var(--primary);}
.toggle.dark{background:var(--track);}
.toggle.dark::after{background:var(--card);box-shadow:0 1px 2px rgba(46,33,25,.18);}
.toggle.dark.on::after{background:var(--primary);}
.toggle.dark.on{background:var(--primary-soft);}
/* Riga "Fatturabile" della modale ore: l'interruttore a destra, sotto
   l'etichetta una riga che dice cosa comporta dirgli di sì. */
.bill-switch{margin:4px 0 16px;padding:11px 13px;border:1px solid var(--border);border-radius:11px;background:var(--field);}
.bill-switch>span{display:flex;flex-direction:column;gap:2px;}
.bill-switch>span small{font-size:11.5px;font-weight:500;color:var(--muted);}
.no-timer{text-align:center;padding:22px 10px;}
.no-timer p{color:rgba(255,255,255,.85);font-size:13px;margin:0 0 14px 0;}


.evsa-row{display:flex;justify-content:space-between;align-items:center;padding:11px 0;border-top:1px solid var(--border);}
.evsa-row:first-child{border-top:none;}
.evsa-name{font-size:13px;font-weight:600;margin-bottom:3px;}
.evsa-bar-bg{width:100%;height:6px;background:var(--track);border-radius:6px;}
.evsa-bar{height:100%;border-radius:6px;background:var(--primary);}
.evsa-over{background:var(--red);}
.evsa-diff{font-size:11.5px;font-weight:700;margin-left:10px;white-space:nowrap;}

/* Ticket summary mini stats (dashboard) */
.mini-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;}

/* **Alla prima soglia le griglie larghe perdono colonne.** Queste regole
   stavano in `tasks.css`, cioe' nel foglio di una pagina, e vestivano
   tutte le pagine che usano questi componenti: la lista dei ticket e' il
   posto dove si vedeva il problema, non il posto a cui la regola
   appartiene. Qui accanto alla definizione, dove chi cambia il
   componente la trova. */
@media (max-width:1100px){
  .layout2,.layout3{grid-template-columns:1fr;}
  .kpis.n3,.kpis.n4,.kpis.n5{grid-template-columns:1fr 1fr;}
  .mini-stats{grid-template-columns:1fr 1fr;}
}
/* Sotto ai 640 le schede KPI sono un carosello (`.kpis.kpis` in
   `mobile-kit.css`, come vuole il disegno): la griglia a due colonne che
   stava qui non si vedeva mai. Restano le mini-statistiche. */
@media (max-width:640px){
  .mini-stats{grid-template-columns:repeat(2,minmax(0,1fr));}
}
.mini-stat{text-align:center;padding:10px 6px;border-radius:10px;background:var(--bg);border:1px solid var(--border);}
.mini-stat .n{font-size:18px;font-weight:700;}
.mini-stat .l{font-size:11px;color:var(--muted);margin-top:2px;}

/* Sales mini card */
.sales-mini-row{display:flex;justify-content:space-between;align-items:center;padding:9px 0;border-top:1px solid var(--border);font-size:13px;}
.sales-mini-row:first-child{border-top:none;}

/* Project cards v2 */
.proj-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px;}
.proj-card{background:var(--card);border:1px solid var(--border);border-radius:13px;padding:16px;box-shadow:var(--shadow);cursor:pointer;}
.proj-card:hover{border-color:var(--primary-mid);}
.proj-card .top{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px;}
.proj-card .name{font-weight:700;font-size:14px;margin-bottom:2px;}
.proj-card .client{font-size:12px;color:var(--muted);display:flex;align-items:center;gap:6px;}
.proj-card .svc-row{font-size:11.5px;color:var(--muted);margin:8px 0;}
.proj-card .metrics{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:10px 0;}
.proj-card .metric{background:var(--bg);border-radius:9px;padding:8px 10px;}
.proj-card .metric .l{font-size:10.5px;color:var(--muted);}
.proj-card .metric .v{font-size:13.5px;font-weight:700;margin-top:2px;}
.proj-card .meta-row{display:flex;justify-content:space-between;font-size:11.5px;color:var(--muted);margin:8px 0 5px 0;}
.proj-card .period{font-size:11.5px;color:var(--muted);margin-top:8px;padding-top:8px;border-top:1px solid var(--border);}

/* Services */
.service-card{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;border:1px solid var(--border);border-radius:11px;margin-bottom:8px;background:var(--card);}
.service-card .sname{font-weight:700;font-size:13.5px;margin-bottom:3px;}
.service-card .smeta{font-size:11.5px;color:var(--muted);}
.service-card .sprice{font-weight:700;font-size:14px;color:var(--primary-dark);white-space:nowrap;margin-left:12px;}

.empty-state{text-align:center;padding:40px 20px;color:var(--muted);}
.empty-state>svg{width:32px;height:32px;margin-bottom:12px;color:var(--dim);}
.empty-state h3{color:var(--text);font-size:14.5px;margin:0 0 6px 0;}
.empty-state p{font-size:13px;margin:0 0 16px 0;}
/* Il pulsante e' inline: un <button> in display:flex resta di livello
   blocco e il text-align del contenitore non lo centra.

   **E due pulsanti non si toccano.** Due `inline-flex` uno accanto
   all'altro, senza spazi nel markup, restano attaccati — si vedeva sotto
   «Nessuna cartella di Drive per questo cliente». Lo stacco sta qui e non
   nel markup per la stessa ragione dell'avviso delle Impostazioni: una
   regola che chi scrive la riga si deve ricordare non e' una regola, e
   basta dimenticarla una volta. Il margine sta su tutti e due i lati
   perche' a schermo stretto vanno a capo, e uno stacco da un lato solo
   li porterebbe fuori centro; quello verticale e' per la riga che nasce
   andando a capo. */
.empty-state .btn{display:inline-flex;justify-content:center;margin:4px 5px;}

/* Livelli espliciti: il drawer è il contesto, la modale è il focus e sta
   sopra, la conferma sopra a tutto. Senza questo vincevano per ordine nel DOM. */
.modal-overlay{position:fixed;inset:0;background:var(--scrim);display:none;align-items:flex-start;justify-content:flex-end;z-index:200;}
#drawerOverlay{z-index:200;}
#modalOverlay{z-index:300;}
#confirmOverlay{z-index:360;}
.modal-overlay.centered{align-items:center;justify-content:center;padding:20px;}
.modal-overlay.open{display:flex;}
.modal{background:var(--card);padding:24px;width:100%;max-width:480px;max-height:100vh;overflow-y:auto;border-radius:16px;}
.modal-overlay:not(.centered) .modal{border-radius:0;height:100vh;max-height:100vh;box-shadow:-12px 0 40px rgba(20,20,43,.15);}
.modal.wide{max-width:720px;}
.modal.xwide{max-width:860px;}
.modal.drawer{max-width:760px;}
.modal.drawer.wide{max-width:1040px;}
.modal h2{margin:0 0 18px 0;font-size:17px;}
.modal-sub{font-size:12.5px;color:var(--muted);margin:-12px 0 18px 0;}
/* Nota dentro un modulo: dice la conseguenza di cio' che si e' appena
   scelto, li' dove si e' scelto. */
.form-note{display:flex;align-items:flex-start;gap:7px;font-size:11.5px;line-height:1.45;color:var(--primary-dark);background:var(--primary-soft);border-radius:9px;padding:8px 11px;margin:-6px 0 14px;}
.form-note svg{width:13px;height:13px;flex-shrink:0;margin-top:2px;}
.modal-foot{display:flex;justify-content:flex-end;gap:9px;margin-top:16px;}

/* La freccetta del menu azioni (`components/action-menu.js`). Lo
   `!important` batte la misura generica delle icone dentro a un
   pulsante, ed e' il motivo per cui c'e'. */
.am-chev{width:13px!important;height:13px!important;opacity:.8;}

/* ---- il modulo dentro a una finestra ----
   Stava in `tasks.css`, cioe' nel foglio di una pagina, e lo usano tre
   file di `core/` — promemoria, timer, fatturazione — che con i ticket
   non c'entrano. */
.form-row{display:flex;flex-direction:column;gap:4px;margin-bottom:11px;}
.form-row label{font-size:11.5px;font-weight:600;color:var(--muted);display:flex;align-items:center;gap:5px;}
.form-row input,.form-row textarea{border:1px solid var(--border);border-radius:9px;padding:8px 10px;font-size:13px;font-family:inherit;outline:none;background-color:var(--field);}
.form-row input:focus,.form-row textarea:focus{border-color:var(--primary);background-color:var(--card);}
/* `minmax(0,...)` e non `1fr`: una colonna `1fr` non scende sotto il
   min-content di quello che ci sta dentro, e il min-content di un `<input>`
   e' la larghezza di venti caratteri. Bastava un campo in una colonna per
   allargare la griglia oltre la modale che la contiene. */
.form-grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;}
.form-grid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;}
.checkline{display:flex;align-items:center;justify-content:space-between;padding:2px 0;}
.checkline span{font-size:13px;font-weight:600;}

/* ---- una tabella larga su un telefono: `.table-cards` ----
   **Non scorre, cambia forma.** Dieci colonne in trecentosettantacinque
   pixel non sono dieci colonne: o si trascinano di lato — e la prima
   cosa utile, il nome, esce dallo schermo al primo dito — o si
   strizzano, e i nomi vanno a capo tre volte. Sotto ai 640 ogni riga
   diventa una **scheda**: il nome in cima e sotto le altre colonne come
   «etichetta: valore».

   Il nome della colonna lo scrive il foglio da `content:attr(data-lab)`,
   cosi' non sta due volte nel markup e nessuna colonna diventa un numero
   senza nome. Chi disegna la tabella mette la classe sulla `<table>` e
   `data-lab` su ogni cella che non sia la prima; il resto e' qui, una
   volta per tutte le pagine che ne hanno una.

   **Niente si nasconde.** Le colonne le sceglie chi usa l'app, e
   sceglierne di meno al posto suo perche' lo schermo e' piccolo non
   tocca al programma. Quello che si toglie e' solo la cella **vuota**:
   un'etichetta con il nulla accanto, su una scheda, e' una riga in meno
   di quelle che si contano. */
/* **La specificita' e' scritta piu' alta del necessario, apposta.** Ogni
   pagina veste le sue celle con `.xx-table td` — un peso identico a
   `.table-cards td` — e il suo foglio il browser lo legge **dopo**
   questo: a parita' vincerebbe lei, e la scheda si ritroverebbe i bordi
   e le spaziature della tabella. `tbody` in mezzo costa un elemento e
   chiude la questione senza un solo `!important`. */
@media (max-width:640px){
  .table-cards,.table-cards tbody,.table-cards tbody tr,.table-cards tbody td{display:block;width:auto;}
  .table-cards thead{display:none;}
  .table-cards tbody tr{position:relative;background:var(--card);border:1px solid var(--border);
    border-radius:12px;padding:11px 12px;margin-bottom:8px;}
  .table-cards tbody td{border-bottom:none;padding:2px 0;text-align:left;}
  .table-cards tbody tr:hover td{background:transparent;}
  /* La prima cella e' il titolo della scheda. */
  .table-cards tbody td:first-child{padding-bottom:5px;}
  /* `flex-start` e non `baseline`: un'etichetta che va a capo, con
     l'allineamento alla linea di base, tira giu' il valore accanto e la
     riga si legge storta. */
  /* `text-align` anche qui: una colonna di numeri la pagina la allinea a
     destra con `.xx-table td.xx-num`, che pesa due classi — piu' di
     `.table-cards tbody td`. Dentro a una scheda pero' etichetta e valore
     sono **una riga sola**, non due colonne, e il numero spinto a destra
     si stacca dal suo nome. */
  .table-cards tbody td[data-lab]{display:flex;align-items:flex-start;gap:10px;min-height:22px;text-align:left;}
  .table-cards tbody td[data-lab]::before{content:attr(data-lab);flex:0 0 33%;padding-top:1px;
    font-size:10.5px;font-weight:700;line-height:1.35;text-transform:uppercase;letter-spacing:.3px;color:var(--muted);}
  .table-cards tbody td[data-lab]:empty{display:none;}
  /* Niente piu' niente di largo: il contenitore smette di scorrere. */
  .table-cards-wrap{overflow-x:visible;}
}

/* ---- i componenti condivisi, sotto ai 640 ----
   Stanno qui e non in un foglio di pagina perche' li usano Attivita',
   Progetti, Clienti, Servizi e Sales: la stessa pastiglia deve essere
   alta uguale dappertutto, e cinque copie divergono al primo ritocco.

   Le misure vengono dal disegno mobile, non da una stima: pastiglia alta
   34, striscia alta 36 piu' tre di cornice, testo 12,5 e 13. Sul
   desktop la stessa pastiglia e' alta 31 perche' li' la si clicca con un
   mouse; qui ci va un dito, e sotto ai 44 di area toccabile non si
   scende senza pagarlo in errori. */
@media (max-width:640px){
  /* La striscia delle viste: piu' alta, e **senza icone**. Due parole
     corte si leggono da sole, e l'icona accanto mangia i pixel che
     servono al testo — con tre viste (Giorno/Settimana/Mese) la terza
     andava a capo. */
  /* **Due viste sono un segmento, otto sono delle sezioni.** Con
     `flex:1` e una riga sola le due di Attivita' si dividevano la
     larghezza — giusto — ma le otto di Impostazioni finivano fuori
     dallo schermo, tagliate a meta' su «Timer e o…». Con `flex:1 0
     auto` e le righe che vanno a capo funzionano tutte e due: poche si
     allargano, tante si dispongono su piu' righe. Non scorrono, perche'
     una sezione nascosta dietro a uno scorrimento e' una pagina che non
     si raggiunge. */
  /* **Una riga sola, che scorre quando le voci sono tante.** Per un giro
     le voci andavano a capo — le nove sezioni delle Impostazioni su tre
     righe — per non nascondere niente dietro a uno scorrimento; il
     disegno mobile invece tiene ogni striscia su una riga
     (`.seg.scroll`): tre righe di schede si riprendevano l'altezza che la
     testata del telefono esiste per liberare. Poche voci si allargano a
     riempirla, tante scorrono, e quella tagliata sul bordo dice da sola
     che ce n'e' ancora. */
  .tabbtns{border-radius:11px;padding:3px;gap:2px;flex-wrap:nowrap;overflow-x:auto;
    scrollbar-width:none;-ms-overflow-style:none;}
  .tabbtns::-webkit-scrollbar{display:none;}
  .tabbtns button,.tabbtns a{
    flex:1 0 auto;justify-content:center;min-height:36px;padding:0 13px;
    font-size:13px;border-radius:9px;white-space:nowrap;color:var(--neutral-ink);
  }
  .tabbtns button.active,.tabbtns a.active{color:var(--text);}
  /* **Le icone restano.** Per un giro qui c'era `display:none`, perche'
     nel disegno la striscia delle viste e' di solo testo e con tre voci
     l'icona faceva andare a capo la terza. Ma la stessa classe la usano
     i selettori a **sola icona** di Clienti e di Progetti: li' quella
     riga lasciava due pulsanti **vuoti**, e nessuna regola CSS sa
     distinguere un pulsante con del testo accanto all'icona da uno senza
     (`:only-child` guarda gli elementi, e il testo non e' un elemento).
     Meglio un'icona di troppo che due pulsanti che non dicono niente —
     e da quando le righe vanno a capo, la terza voce non si perde. */

  /* La pastiglia di un filtro rapido: piu' alta, e **accesa non si
     riempie**. Il pieno primario con il bianco sopra e' il linguaggio
     dell'azione principale — qui accanto c'e' il tondo che crea un
     ticket — e due pieni della stessa tinta nella stessa schermata si
     leggono come lo stesso gesto. Acceso e' la coppia tenue: fondo
     `--primary-soft`, inchiostro `--primary-dark`. */
  .qf-chip{
    min-height:34px;padding:0 13px;border-radius:999px;
    font-size:12.5px;font-family:inherit;background:var(--card);
  }
  .qf-chip.active{
    background:var(--primary-soft);color:var(--primary-dark);border-color:transparent;
  }
  .qf-chip svg{width:15px;height:15px;}
  /* Quanti ne accende: il pieno che non si schiarisce di notte, cosi' il
     bianco sopra si legge in tutti e due i temi (`--primary-deep`, §2). */
  .qf-chip .qf-n{padding:1px 5px;border-radius:6px;font-size:10.5px;font-weight:700;line-height:1.4;
    background:var(--primary-deep);color:var(--on-accent);font-variant-numeric:tabular-nums;}

  /* **Una colonna sola e' `minmax(0,1fr)`, non `1fr`.** `1fr` vuol dire
     «almeno quanto il contenuto piu' largo», e una riga di avviso che non
     va a capo allargava la colonna a quattrocentosettanta pixel dentro a
     trecentosessantasei: la panoramica di un cliente usciva dallo schermo
     di un terzo, e la pagina scorreva di lato. Sopra ai 640 la regola
     resta com'era. */
  .layout2,.layout3{grid-template-columns:minmax(0,1fr);}
  /* **Una tabella che scorre deve contenere anche quello che e'
     posizionato.** Il testo per chi legge con la voce (`.sr-only`) e'
     assoluto, e il suo riferimento era la pagina: dentro alle
     intestazioni di una tabella larga finiva a novecento pixel, fuori dal
     riquadro che scorre, e la pagina intera si trascinava di lato. Con il
     riquadro come riferimento resta dentro, e il riquadro lo taglia. */
  .table-wrap{position:relative;}

  /* L'etichetta di un ticket: piu' piccola, perche' su una scheda ce ne
     sono due o tre in fila accanto alla chiave. */
  .badge-label{font-size:9px;padding:2px 6px;border-radius:5px;letter-spacing:.05em;}
}

/* ---- una finestra su un telefono ----
   La finestra e' **lo schermo**: i 24px di aria per lato piu' i 20 del
   velo sono 88 dei 375 pixel spesi in margine, e quello che resta al
   contenuto non basta a un campo con la sua etichetta. I pulsanti in
   fondo si impilano invece di stringersi, nell'ordine in cui stanno nel
   markup — quello che annulla sopra, quello che fa sotto, dove arriva il
   pollice. E le griglie a due e a tre colonne diventano una: due campi
   affiancati in 300 pixel non sono due campi. */
@media (max-width:640px){
  .modal-overlay.centered{padding:12px;}
  .modal{padding:18px;border-radius:14px;}
  .modal.wide,.modal.xwide,.modal.drawer,.modal.drawer.wide{max-width:none;}
  .modal h2{font-size:16px;margin-bottom:14px;}
  .modal-foot{flex-direction:column;align-items:stretch;gap:8px;}
  .modal-foot .btn{justify-content:center;}
  .form-grid2,.form-grid3{grid-template-columns:minmax(0,1fr);}
}

/* ===== SCHEDA CLIENTE — header, alert, timeline, note, mini-progetti ===== */
.section-title{font-size:11.5px;text-transform:uppercase;letter-spacing:.3px;color:var(--muted);font-weight:700;margin:18px 0 10px 0;padding-top:14px;border-top:1px solid var(--border);}
.section-title:first-child{margin-top:0;padding-top:0;border-top:none;}

.client-header{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:20px;flex-wrap:wrap;}
.client-header-left{display:flex;gap:14px;align-items:flex-start;}
.client-header .cname{font-size:20px;font-weight:700;letter-spacing:-.2px;}
.client-header .clegal{font-size:12.5px;color:var(--muted);margin-bottom:6px;}
.client-header .cmeta{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:6px;}

.alert-row{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:10px;background:var(--amber-soft);color:var(--amber-dark);font-size:12.8px;font-weight:600;margin-bottom:8px;cursor:pointer;}
.alert-row:last-child{margin-bottom:0;}
.alert-row.danger{background:var(--red-soft);color:var(--red-dark);}
/* Non un allarme: un'informazione. Stesso impianto, tono primario. */
.alert-row.info{background:var(--primary-soft);color:var(--primary-dark);}
a.alert-row{text-decoration:none;}
.alert-row:hover{filter:brightness(.98);}
.alert-row b{font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:46%;}
.alert-row span{font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.alert-row .go{margin-left:auto;opacity:.6;}
.alert-row svg{width:15px;height:15px;flex-shrink:0;}
/* "ce ne sono altri": non e' un avviso, e' il modo di vederli tutti */
.alert-more{display:block;width:100%;text-align:left;padding:8px 12px;border:none;background:none;font:inherit;
  font-size:12px;font-weight:600;color:var(--muted);cursor:pointer;border-radius:10px;}
.alert-more:hover{background:var(--hover);color:var(--text);}
/* avviso che si può mettere a tacere: la x resta discreta finché non ci si passa sopra */
.alert-x{margin-left:auto;background:none;border:none;padding:2px;display:flex;align-items:center;color:inherit;opacity:.55;border-radius:6px;}
.alert-x:hover{opacity:1;background:rgba(0,0,0,.06);}
.alert-x svg{width:14px;height:14px;}

.timeline-item{display:flex;gap:10px;padding:11px 0;border-top:1px solid var(--border);font-size:12.8px;}
.timeline-item:first-child{border-top:none;}
.timeline-item .dot{width:7px;height:7px;border-radius:50%;background:var(--primary);margin-top:5px;flex-shrink:0;}
.timeline-item .when{color:var(--muted);font-size:11px;margin-bottom:2px;}

/* ---- Note e storico (scheda cliente) ---- */
.jr-head{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:14px;}
.jr-section{margin-top:30px;padding-top:24px;border-top:1px solid var(--border);}
.sec-actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.sec-stat{font-size:11.5px;font-weight:600;color:var(--muted);}

/* Riepilogo compatto: sostituisce una fila di kpi-card dove i numeri sono
   di contorno alla tabella e non meritano un quarto di schermata. */
.tsum{display:flex;flex-wrap:wrap;align-items:center;background:var(--card);border:1px solid var(--border);border-radius:12px;padding:10px 4px;margin-bottom:12px;}
.tsum-item{display:flex;align-items:baseline;gap:7px;padding:2px 16px;border-left:1px solid var(--border);}
.tsum-item:first-child{border-left:none;}
.tsum-item span{font-size:11px;color:var(--muted);font-weight:600;white-space:nowrap;}
.tsum-item b{font-size:14px;font-weight:700;white-space:nowrap;}
td.nowrap,th.nowrap{white-space:nowrap;}

/* ---- la robustezza di una password ----
   La barra e la riga del suggerimento. Stanno qui e non nel foglio delle
   Impostazioni perche' le mostrano **due** posti: la scheda Sicurezza e
   la schermata del primo accesso di chi e' entrato con una provvisoria.
   Il disegno lo compone `pwAiutoHtml()` in `core/password-rules.js`, una
   volta per tutti e due.

   I tre gradini sono **rosso, giallo, verde**, che e' la scala che tutti
   leggono senza spiegazioni. E' l'unico posto dell'app dove il verde
   vuol dire «a posto» — altrove quel mestiere ce l'ha il primario —
   perche' qui la scala vale piu' della tinta di casa: una barra
   arancione in fondo a una scala che comincia in rosso non dice niente a
   nessuno.

   I nomi arrivano da `pwForza()`, e sono **nomi di classe**: per un
   pezzo di li' tornava un `var(--red)` scritto dentro all'attributo
   `class`, che non veste niente — la barra restava vuota mentre accanto
   c'era scritto «Forte». Il colore sta qui, con i token, che di notte si
   rovesciano da soli. */
.pw-strength{height:4px;border-radius:3px;background:var(--track);overflow:hidden;margin-top:6px;}
.pw-strength i{display:block;height:100%;transition:width .2s,background .2s;}
.pw-strength i.st-weak{background:var(--red);}
.pw-strength i.st-mid{background:var(--amber);}
.pw-strength i.st-ok{background:var(--green);}

/* La riga del suggerimento: **uno alla volta**, e cambia a ogni tasto.
   Il disegno dice di che tipo e' prima del colore — un guaio, una
   lampadina, una spunta — perche' di una riga di dodici pixel il colore
   e' la parte che meta' delle persone non vede. */
.pw-hint{display:flex;align-items:center;gap:6px;font-size:11.5px;margin-top:6px;min-height:16px;color:var(--muted);}
.pw-hint svg{width:13px;height:13px;flex:none;}
.pw-hint.is-req{color:var(--amber-dark);}
.pw-hint.is-ok{color:var(--green-dark);}
.pw-level{font-weight:700;color:var(--text);}
.pw-level::after{content:"·";margin-left:6px;color:var(--dim);font-weight:500;}

/* ---- il paginatore ----
   Un elenco lungo mostra una pagina e dice quale di quante. Era della
   pagina Team; il tempo registrato di un cliente e' il secondo posto che
   ne ha bisogno, e alla seconda volta un componente si estrae. Il markup
   lo fa `renderPager()` in `components/pager.js`, e siccome quel file sta
   in `components/` le sue classi non possono piu' abitare nel foglio di
   una pagina — `ui-tests/componenti-stretti.cjs` lo pretende. */
.pager{display:flex;align-items:center;gap:12px;padding:10px 20px;border-top:1px solid var(--border);
  background:var(--field);border-radius:0 0 var(--radius) var(--radius);flex-wrap:wrap;font-size:12px;color:var(--muted);}
.pager>span{font-variant-numeric:tabular-nums;}
.pager .size{display:inline-flex;align-items:center;gap:6px;}
.pager .size .aselect{min-height:26px;padding:3px 8px;font-size:12px;}
.pager .pages{margin-left:auto;display:flex;gap:2px;align-items:center;}
.pager .pages button{min-width:28px;height:28px;border:none;background:transparent;border-radius:7px;font-size:12px;
  font-weight:600;color:var(--neutral-ink);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;
  padding:0 6px;font-family:inherit;}
.pager .pages button:hover:not(:disabled){background:var(--card);box-shadow:0 0 0 1px var(--border);}
.pager .pages button.on{background:var(--primary-soft);color:var(--primary-dark);}
.pager .pages button:disabled{opacity:.35;cursor:default;}
.pager .pages svg{width:14px;height:14px;}
.pager .gap{padding:0 4px;}
