/* ==========================================================================
   Quadra — la geometria delle pagine

   Il sistema visivo (caratteri, token, base, guscio, componenti, plancia,
   viste, movimento) sta in `quadra.css`, che la pagina carica prima di
   questo foglio: qui restano solo le regole delle singole pagine e delle loro
   forme, scritte con i nomi storici dei token (`--surface`, `--accent`,
   `--seq-*` …) che `quadra.css` fa puntare ai token del Brand Standards
   3.6. Un valore di colore scritto qui è un errore: si usa un token.

   La direzione che governa entrambi sta in `DESIGN.md`.
   ========================================================================== */

/* ============================== 11 · PAGINE ============================== */

/* ----------------------------- Abbinamenti ------------------------------ */
.score {
  display: inline-block; min-width: 36px; padding: 3px 8px;
  border-radius: var(--r-1);
  font-weight: 700; font-variant-numeric: tabular-nums;
  border: 1px solid transparent;
}
.cmp { font-size: var(--fs-2); margin-top: 0; }
.cmp td { vertical-align: top; }
/* ------------------------------- Sorgenti ------------------------------- */
.upload-card { border-color: var(--border); }
.slot-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-2);
}
.slot-head h2 { margin: 0; }
.card p.slot-desc { margin: 0 0 var(--sp-3); color: var(--muted); }
/* Il ruolo scoperto pesa: bordo rosso e filo a sinistra. Quello facoltativo
   arretra, quello attivo resta neutro perché è la normalità. */
.slot-ok { border-left: 2px solid var(--ok-line); }
.slot-missing { border-color: var(--bad-line); border-left: 2px solid var(--bad); }
.slot-optional { border-style: dashed; opacity: 0.9; }

/* --------------------------- annunci multipli --------------------------- */
.multi {
  border: 1px solid var(--border); border-radius: var(--r-2);
  padding: var(--sp-4); margin-top: var(--sp-4);
  background: var(--surface-2);
  --tbl-bg: var(--surface-2);
}
.multi-head {
  display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap;
  margin-bottom: var(--sp-2);
}

/* ------------------------------- Accesso -------------------------------- */
.gate { display: grid; place-items: start center; padding-top: var(--sp-3); }
.gate-card { max-width: 560px; width: 100%; }

/* ------------------------------ Direzione ------------------------------- */
.fasi { list-style: none; margin: var(--sp-4) 0 0; padding: 0; }
.fase {
  display: flex; gap: var(--sp-4);
  padding: var(--sp-4) 0; border-bottom: 1px solid var(--border);
}
.fase:first-child { padding-top: 0; }
.fase:last-child { border-bottom: none; padding-bottom: 0; }
.fase-n {
  width: 26px; height: 26px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--pri-ink);
  font-size: var(--fs-1); font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.fase > div { min-width: 0; }
.fase strong { font-size: var(--fs-4); font-weight: 650; }
.fase p { margin: var(--sp-2) 0 0; font-size: var(--fs-2); line-height: 1.5; }
/* Ciò che si può misurare e ciò che non si può: il testo lo dice, il segno
   lo conferma. Nessuno dei due dipende dal solo colore. */
.misurabile { color: var(--ok); }
.non-misurabile { color: var(--dim); }
.misurabile::before, .non-misurabile::before {
  display: inline-block; width: 1.1em; font-weight: 700;
}
.misurabile::before { content: "＋"; }
.non-misurabile::before { content: "−"; }

/* --- il caso: cinque anelli di natura diversa ---------------------------
   È il componente che porta il senso della pagina. I cinque passi non sono
   cinque paragrafi colorati: hanno statuti epistemici diversi e la forma lo
   dichiara, senza affidarsi al colore.

     nodo pieno   = accertato (misurato, oppure deciso da una persona)
     nodo vuoto   = non ancora stabilito (ipotesi, proposta, procedura futura)
     guida piena  = il passaggio è dimostrato
     guida tratteggiata = il passaggio è un'inferenza, non una prova
     riquadro     = qui si scrive (decisione) o qui non c'è ancora nulla
   ---------------------------------------------------------------------- */
.caso {
  border: 1px solid var(--border); border-radius: var(--r-3);
  padding: var(--sp-5) var(--sp-6); margin-top: var(--sp-5);
  background: var(--surface-2);
  --tbl-bg: var(--surface-2);
}
/* La priorità è già scritta in lettere nel badge `.pri` dentro l'intestazione
   del caso: il filetto la diceva una seconda volta, in colore, spesso tre
   pixel. Resta un filo di un pixel, che separa i casi senza classificarli. */
.caso-alta  { border-left: 1px solid var(--bad); }
.caso-media { border-left: 1px solid var(--warn); }
.caso-bassa { border-left: 1px solid var(--border-strong); }
.caso-head {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  padding-bottom: var(--sp-3); border-bottom: 1px solid var(--border);
}
.caso-head h3 {
  margin: 0; font-size: var(--fs-5); font-weight: 650;
  flex: 1; min-width: 220px; display: block;
}
.caso-numeri { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin: var(--sp-4) 0; }
.caso-numeri .mini { min-width: 152px; flex: 1 1 152px; background: var(--surface); }

.caso-catena { display: grid; }
.anello {
  position: relative;
  padding: var(--sp-4) 0 var(--sp-4) var(--sp-7);
}
/* la guida verticale, continua da un anello all'altro */
.anello::before {
  content: ""; position: absolute; left: 6px; top: 0; bottom: 0;
  border-left: 1px solid var(--border-strong);
}
.anello:first-child::before { top: 22px; }
.anello:last-child::before { bottom: auto; height: 22px; }
/* il nodo */
.anello::after {
  content: ""; position: absolute; left: 0; top: 16px;
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--surface-2); border: 2px solid var(--border-strong);
}
.anello-tag {
  display: block;
  font-size: var(--fs-0); font-weight: 800;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted);
}
.anello p, .anello ul { margin: var(--sp-2) 0 0; font-size: var(--fs-3); line-height: 1.6; }
.anello ul { padding-left: var(--sp-4); }
.anello li { margin-bottom: var(--sp-1); }

/* 1 · osservato — nodo pieno, guida piena */
.anello-evidenza::after { background: var(--ok); border-color: var(--ok); }
.anello-evidenza .anello-tag { color: var(--ok); }
.anello-evidenza p { color: var(--text); }

/* 2 · ipotesi non dimostrata — nodo vuoto, guida tratteggiata */
.anello-causa::after { border-color: var(--warn); }
.anello-causa::before { border-left-style: dashed; }
.anello-causa .anello-tag { color: var(--warn); }

/* 3 · proposta — nodo vuoto, guida tratteggiata */
.anello-esperimento::after { border-color: var(--data); }
.anello-esperimento::before { border-left-style: dashed; }
.anello-esperimento .anello-tag { color: var(--pri-ink); }
.misura {
  color: var(--muted);
  padding-top: var(--sp-2); border-top: 1px dashed var(--border-strong);
}
.misura strong { color: var(--text); font-weight: 650; }

/* 4 · atto di una persona — nodo pieno, riquadro in cui si scrive */
.anello-decisione::after { background: var(--info); border-color: var(--info); }
.anello-decisione .anello-tag { color: var(--info); }
.dec-form {
  display: grid; gap: var(--sp-2);
  margin-top: var(--sp-3); max-width: 640px;
  padding: var(--sp-4);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-2);
}
.dec-form textarea { resize: vertical; font-family: var(--font-ui); }
.dec-form button { justify-self: start; }
.dec-esito { font-size: var(--fs-2); }
.dec-esito.ok { color: var(--ok); }
.dec-esito.bad { color: var(--bad); }

/* 5 · non ancora esistente — nodo spento, riquadro tratteggiato e vuoto */
.anello-procedura::before { border-left-style: dashed; }
.anello-procedura > p {
  margin-top: var(--sp-3);
  padding: var(--sp-4);
  border: 1px dashed var(--border-strong); border-radius: var(--r-2);
  color: var(--muted);
}
/* Quando il caso è diventato procedura, l'ultimo anello smette di essere
   un'ipotesi: il nodo si riempie, la guida e la cornice si chiudono. */
.caso-stato-procedura .anello-procedura::after { background: var(--ok); border-color: var(--ok); }
.caso-stato-procedura .anello-procedura::before { border-left-style: solid; }
.caso-stato-procedura .anello-procedura .anello-tag { color: var(--ok); }
.caso-stato-procedura .anello-procedura > p {
  border-style: solid; border-color: var(--ok-line);
  background: var(--ok-soft); color: var(--text);
}

/* ============================= 12 · VIEWPORT ============================= */
@media (max-width: 1100px) {
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-2 { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  /* Viewport stretti: la barra laterale diventa una fascia in alto. */
  
  
  
  
  
  
  
  
  
  .pop { grid-template-columns: 1fr; }
  .gen-form, .gate-form { flex-direction: column; align-items: stretch; }
  h1 { font-size: var(--fs-6); }
  .card { padding: var(--sp-4); }
  .caso { padding: var(--sp-4); }
}
@media (max-width: 640px) {
  .grid-2, .grid-4 { grid-template-columns: 1fr; }
  .caso-numeri .mini { min-width: 0; }
}

/* --------------------------- imbuto del portafoglio ---------------------
   Ogni stadio conta gli immobili che ci arrivano. La barra è proporzionale
   al primo stadio, così la perdita si vede prima di leggere i numeri. Lo
   stadio non misurabile non ha barra: un'assenza di dato non deve somigliare
   a uno zero. */
.imbuto { list-style: none; margin: var(--sp-4) 0 0; padding: 0; }

.stadio { padding: var(--sp-3) 0; border-bottom: 1px solid var(--border); }
.stadio:last-child { border-bottom: 0; padding-bottom: 0; }

.stadio-testa {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-4); margin-bottom: var(--sp-2);
}
.stadio-nome { font-size: var(--fs-4); font-weight: 600; }
.stadio-n {
  font-size: var(--fs-6); font-weight: 700; font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.stadio-n em { font-size: var(--fs-2); font-weight: 500; font-style: normal;
               color: var(--dim); letter-spacing: 0; }

.stadio-barra {
  height: 6px; border-radius: var(--r-xs); background: var(--surface-2);
  overflow: hidden; margin-bottom: var(--sp-2);
}
.stadio-barra span {
  display: block; height: 100%; border-radius: var(--r-xs);
  background: var(--data); opacity: 0.55;
}

.stadio-collo .stadio-barra span { opacity: 1; background: var(--warn); }
.stadio-collo .stadio-nome { color: var(--warn); }
.stadio-perdita {
  display: inline-block; margin-left: var(--sp-2); color: var(--warn);
  font-variant-numeric: tabular-nums;
}
.stadio-vuoto .stadio-nome, .stadio-vuoto .stadio-n { color: var(--dim); }

/* ============================ 13 · LUNA (AI) =============================
   Una lettura assistita non è una misura, e non deve mai poter essere
   scambiata per tale. Il foglio lo dice in tre modi contemporaneamente:

     · un COLORE che non appartiene a nessuno stato esistente (--ai). Verde,
       giallo e rosso significano già «va bene / attenzione / male»; il viola
       non significa nulla nel resto dell'interfaccia, ed è esattamente ciò
       che serve: «questo è di un altro genere».
     · un MARCHIO in testa al blocco, che nomina chi parla;
     · un PIÈ DI PAGINA che dichiara sempre modello, costo e che cosa è uscito
       dal computer.

   I numeri restano dove sono sempre stati: nelle tabelle e nelle tessere KPI.
   Qui dentro c'è solo testo, tranne il punteggio di un abbinamento, che viene
   ristampato per mostrare che il modello lo ha copiato e non riscritto.
   ========================================================================= */

:root {
  --ai: var(--ink);
  --ai-line: var(--line);
  --ai-soft: var(--panel);
  --ai-dim: var(--panel);
}

/* --- il comando ------------------------------------------------------- */
/* Sta accanto al dato che commenta, non in una barra a parte: è un'azione
   contestuale, e se non c'è nulla da spiegare non deve esistere. */
.ai-azione {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: 5px var(--sp-3);
  font: 600 var(--fs-1) / 1 var(--font-ui);
  letter-spacing: 0.02em;
  color: var(--ai);
  background: var(--ai-dim);
  border: 1px solid var(--ai-line);
  border-radius: var(--r-pill);
  cursor: pointer;
}
.ai-azione::before {
  content: "◇"; font-size: 11px; opacity: 0.9;
}
.ai-azione:hover { background: var(--ai-soft); }
.ai-azione:disabled { opacity: 0.55; cursor: progress; }
.ai-azione[data-stato="attesa"]::before {
  content: "◈"; animation: ai-pulsa 1.1s ease-in-out infinite;
}
@keyframes ai-pulsa { 50% { opacity: 0.25; } }

/* --- il blocco di risposta -------------------------------------------- */
.ai-blocco {
  margin: var(--sp-4) 0 0;
  background: linear-gradient(var(--ai-dim), var(--ai-dim)) var(--surface-2);
  border: 1px solid var(--ai-line);
  border-radius: var(--r-2);
  /* Nessun ritaglio: l'angolo lo tiene la fascia di testata da sé (sotto).
     Ritagliare tutto il blocco per due angoli costava l'anello di messa a
     fuoco del bottone di chiusura, che sta proprio in quell'angolo. */
}
.ai-head { border-radius: calc(var(--r-2) - 1px) calc(var(--r-2) - 1px) 0 0; }
.ai-blocco-errore { border-color: var(--border-strong);
                    background: var(--surface-2); }

.ai-head {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--ai-line);
  background: var(--ai-soft);
}
.ai-blocco-errore .ai-head { background: transparent; border-bottom-color: var(--border); }
.ai-marchio {
  font: 800 var(--fs-0) / 1 var(--font-ui);
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--paper); background: var(--ai);
  padding: 4px var(--sp-2); border-radius: var(--r-1);
}
.ai-titolo { flex: 1; font-size: var(--fs-2); color: var(--muted); }
.ai-chiudi {
  background: none; border: 0; color: var(--dim); cursor: pointer;
  font-size: 18px; line-height: 1; padding: 0 var(--sp-1);
}
.ai-chiudi:hover { color: var(--text); }

.ai-corpo { padding: var(--sp-4); }
.ai-corpo > *:last-child { margin-bottom: 0; }

.ai-sintesi {
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-4); line-height: var(--lh-body); max-width: 82ch;
}

/* --- campi ------------------------------------------------------------- */
.ai-campo { margin-bottom: var(--sp-4); }
.ai-campo:last-child { margin-bottom: 0; }
.ai-campo > p, .ai-campo > ul, .ai-campo > dl { margin: var(--sp-2) 0 0;
                                                font-size: var(--fs-3);
                                                line-height: var(--lh-cell);
                                                max-width: 86ch; }
.ai-tag {
  display: block;
  font: 800 var(--fs-0) / 1 var(--font-ui);
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--muted);
}
/* Tre famiglie di campo con tre significati diversi: ciò che non si sa, ciò
   che va fatto, ciò che è in conflitto. */
.ai-campo-incerto .ai-tag { color: var(--dim); }
.ai-campo-incerto { border-left: 2px solid var(--border-strong);
                    padding-left: var(--sp-3); }
.ai-campo-azione { border-left: 2px solid var(--ai);
                   padding-left: var(--sp-3); }
.ai-campo-azione .ai-tag { color: var(--ai); }
.ai-campo-conflitto { border-left: 2px solid var(--bad-line);
                      padding-left: var(--sp-3); }
.ai-campo-conflitto .ai-tag { color: var(--bad); }

.ai-lista { margin: var(--sp-2) 0 0; padding-left: var(--sp-4);
            font-size: var(--fs-3); line-height: var(--lh-cell); }
.ai-lista li { margin-bottom: var(--sp-2); }
.ai-lista li:last-child { margin-bottom: 0; }

/* --- microcomponenti --------------------------------------------------- */
.ai-conf {
  display: inline-block; padding: 2px var(--sp-2);
  font: 700 var(--fs-0) / 1.5 var(--font-ui);
  letter-spacing: 0.06em; text-transform: uppercase;
  border: 1px solid var(--border); border-radius: var(--r-pill);
  color: var(--dim); white-space: nowrap;
}
.ai-conf-alta  { color: var(--ok-t);   border-color: var(--ok-line);   background: var(--ok-soft); }
.ai-conf-media { color: var(--warn-t); border-color: var(--warn-line); background: var(--warn-soft); }
.ai-conf-bassa { color: var(--dim);  border-color: var(--border); }

/* La prova è la citazione dalla nota: è la sola cosa in questo blocco che
   NON viene dal modello, ed è per questo che è composta diversamente. */
.ai-prova {
  display: block; margin-top: var(--sp-1);
  font-size: var(--fs-2); font-style: italic; color: var(--muted);
  border-left: 2px solid var(--border-strong); padding-left: var(--sp-3);
}
.ai-conteggio {
  display: inline-flex; flex-direction: column; align-items: center;
  min-width: 44px; padding: var(--sp-1) var(--sp-2);
  font: 700 var(--fs-5) / 1 var(--font-ui); font-variant-numeric: tabular-nums;
  color: var(--ai); background: var(--ai-soft);
  border: 1px solid var(--ai-line); border-radius: var(--r-1);
}
.ai-conteggio em { font: 500 var(--fs-0) / 1.6 var(--font-ui);
                   font-style: normal; color: var(--dim); }
/* --- punteggio ristampato (abbinamenti) -------------------------------- */
.ai-punteggio-v { font: 700 var(--fs-fig) / 1 var(--font-ui);
                  font-variant-numeric: tabular-nums; }
.ai-punteggio-l { font-size: var(--fs-1); color: var(--dim); line-height: 1.4; }

/* --- conferma di una classificazione ------------------------------------ */
.ai-sent-negativo { color: var(--err-t); border-color: var(--bad-line); background: var(--bad-soft); }
.ai-sent-positivo { color: var(--ok-t);  border-color: var(--ok-line);  background: var(--ok-soft); }
.ai-sent-misto    { color: var(--warn-t); border-color: var(--warn-line); background: var(--warn-soft); }

/* --- piè di pagina ------------------------------------------------------ */
.ai-pie {
  display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4);
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-1); color: var(--dim);
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.ai-pie .dim { color: var(--dim); font-style: italic; }
.ai-privacy { margin-left: auto; color: var(--muted); }
.ai-privacy::before { content: "⛉ "; color: var(--ai); }

/* --- pagina Note e segnali ---------------------------------------------- */
.nota-card { margin-bottom: var(--sp-4); }
.nota-head {
  display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap;
  margin-bottom: var(--sp-3);
}
.nota-head .mono { color: var(--muted); }
/* Il testo scritto a mano è la fonte: si compone come una citazione e non
   cambia mai, qualunque cosa dica la classificazione. */
.nota-testo {
  margin: 0 0 var(--sp-3); padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2); border-left: 1px solid var(--border-strong);
  border-radius: 0 var(--r-1) var(--r-1) 0;
  font-size: var(--fs-3); line-height: var(--lh-body); white-space: pre-wrap;
}
.nota-stato {
  display: inline-block; padding: 2px var(--sp-2);
  font: 700 var(--fs-0) / 1.5 var(--font-ui); text-transform: uppercase;
  letter-spacing: 0.06em; border-radius: var(--r-pill); border: 1px solid;
}
.nota-stato-nuova     { color: var(--dim); border-color: var(--border); }
.nota-stato-proposta  { color: var(--ai); border-color: var(--ai-line); background: var(--ai-soft); }
.nota-stato-confermata{ color: var(--ok-t); border-color: var(--ok-line); background: var(--ok-soft); }
.nota-comandi { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
.nuova-nota-riga { display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap; }

/* --- pagina impostazioni AI --------------------------------------------- */
.ai-stato-griglia { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
                    gap: var(--sp-4); margin-bottom: var(--sp-5); }
.ai-funzione {
  display: grid; grid-template-columns: 1fr auto; gap: var(--sp-3);
  align-items: center; padding: var(--sp-3) 0;
  border-top: 1px solid var(--border);
}
.ai-funzione:first-of-type { border-top: 0; }
.ai-funzione-area {
  font: 700 var(--fs-0) / 1 var(--font-ui); text-transform: uppercase;
  letter-spacing: var(--track-label); color: var(--dim);
}
.ai-funzione h3 { margin: var(--sp-1) 0; font-size: var(--fs-4); }
.ai-funzione p { margin: 0; }
.ai-spenta h3, .ai-spenta p { opacity: 0.5; }

@media (max-width: 1100px) {
  .ai-stato-griglia { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  .ai-stato-griglia { grid-template-columns: 1fr; }
  .ai-privacy { margin-left: 0; }
}

/* ======================== 14 · PORTAFOGLIO (ANALISI) =====================
   La pagina che risponde alla domanda «come sta andando il portafoglio».
   Due esigenze visive, entrambe di sostanza:

     · il PERIODO deve essere sempre visibile e sempre cambiabile. Un numero
       senza il suo periodo è un numero che qualcuno prima o poi userà per
       la cosa sbagliata.
     · la differenza fra «tipologia dell'agenzia» e «categoria del portale»
       deve leggersi senza spiegazioni. La prima è testo normale, la seconda
       porta sempre il tag del canale: sono due mondi, non due sinonimi.
   ========================================================================= */

.periodo { padding-bottom: var(--sp-4); }
.periodo-scelta {
  /* `flex-direction: row` è esplicito: la regola generale `nav` del guscio
     impila in colonna, ed è giusto per la barra laterale ma non qui. */
  display: flex; flex-direction: row; flex-wrap: wrap; gap: var(--sp-2);
  margin: var(--sp-3) 0 var(--sp-3);
}
.seg {
  padding: 5px var(--sp-4);
  font: 600 var(--fs-2) / 1 var(--font-ui);
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  text-decoration: none;
}
.seg:hover { color: var(--text); border-color: var(--border-strong); }
.seg.attivo {
  color: var(--on-pri-fill); background: var(--pri-fill);
  border-color: transparent; box-shadow: var(--pri-edge);
}
/* --- le conclusioni: un elenco che si legge, non una parete di testo ---- */
/* Le conclusioni portavano la gravità in un filetto colorato spesso due pixel
   sul bordo sinistro di ogni riga: sette righe, sette bastoni colorati in
   colonna, ed è il gesto più riconoscibile del cruscotto generico. Peggio, la
   gravità era detta DUE volte in colore — il filetto e il titolo — e zero
   volte in una forma, cioè spariva insieme al colore.

   Ora la porta un segno, prima del titolo, e il segno cambia FORMA con la
   gravità: quadrato ciò che è grave, rombo ciò che avverte, tondo ciò che
   informa. È la stessa codifica dei chip in tutta l'applicazione. Il filetto
   resta, un pixel e neutro: separa le righe, non le classifica. */


/* --- di che cosa è fatta una categoria del portale ---------------------- */
.frammento {
  display: inline-block; margin: 0 var(--sp-2) var(--sp-1) 0;
  padding: 2px var(--sp-2);
  font-size: var(--fs-1); color: var(--muted);
  background: var(--surface-3); border-radius: var(--r-1);
}

/* --- tipologie da collocare -------------------------------------------- */
.rivedere {
  margin-top: var(--sp-4); padding: var(--sp-4);
  background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--r-2);
}
.rivedere + .rivedere { margin-top: var(--sp-5); }
.rivedere-testa {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.rivedere-testa code {
  font: var(--fs-mono) / 1 var(--font-mono); color: var(--text);
}
.rivedere-form {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-3);
  margin-top: var(--sp-4);
}
.rivedere-form label {
  display: flex; flex-direction: column; gap: var(--sp-1);
  font-size: var(--fs-1); color: var(--muted);
}
.rivedere-form label.cresci { flex: 1 1 260px; }
.rivedere-form input[type="text"] { width: 100%; }

.limiti { margin: 0; padding-left: var(--sp-5); color: var(--muted); }
.limiti li { margin-bottom: var(--sp-2); font-size: var(--fs-2);
             line-height: var(--lh-body); }

.riga-comandi {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4);
}

/* --- la proposta di famiglia (blocco Luna) ------------------------------ */
.ai-proposta {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-3);
  font-size: var(--fs-4);
}
.ai-famiglia { color: var(--ai); text-transform: capitalize; }
.ai-conf {
  padding: 2px var(--sp-2); border-radius: var(--r-1);
  font: 600 var(--fs-0) / 1.4 var(--font-ui); text-transform: uppercase;
  letter-spacing: .04em;
}
.ai-conf-alta  { color: var(--ok-t);   background: var(--ok-soft); }
.ai-conf-media { color: var(--warn-t); background: var(--warn-soft); }
.ai-conf-bassa { color: var(--err-t);  background: var(--bad-soft); }
.ai-alternativa { color: var(--muted); font-size: var(--fs-2); }

/* Nella testata il selettore è un comando, non una sezione: si stringe e va a
   destra, dove stanno gli altri comandi di pagina. */
.page-head .periodo-scelta { margin: 0 0 0 auto; gap: var(--sp-1); }
.page-head .seg { padding: 4px var(--sp-3); font-size: var(--fs-1); }
/* Il cambio di periodo ridisegna solo il corpo della pagina. Mentre arriva, il
   corpo si spegne appena: dice «sto cambiando» senza far saltare il layout, e
   la testata — che non cambia — resta ferma e leggibile. */
/* La sfocatura, oltre all'opacità, e per un motivo preciso: in una dissolvenza
   fra due stati si vedono DUE oggetti distinti sovrapposti, e l'occhio legge
   uno scambio invece di una trasformazione. Due pixel di sfocatura fondono i
   due stati e l'occhio ne vede uno solo che cambia. È lo stesso trucco con cui
   si salvano i cambi di stato dei pulsanti, ed è l'unico posto in tutta
   l'applicazione dove del movimento tocca il contenuto: qui non sta decorando
   un dato, sta coprendo il momento in cui il dato non c'è ancora.

   Nessuna trasformazione: il corpo non scorre e non scala. Un cambio di
   periodo sostituisce diecimila pixel di tabelle, e farli entrare da qualche
   parte sarebbe uno spettacolo, non un'informazione. */
#periodo-contenuto {
  transition: opacity var(--t-stato) var(--ease-out),
              filter var(--t-stato) var(--ease-out);
}
#periodo-contenuto[data-attesa] { opacity: 0.45; filter: blur(2px); }
@media (prefers-reduced-motion: reduce) {
  #periodo-contenuto[data-attesa] { filter: none; }
}

/* --- la quota, disegnata dentro la sua cella --------------------------- */
/* Una barra e la sua cifra nello stesso posto: la cifra resta leggibile e
   copiabile, la barra rende confrontabili dieci righe con un'occhiata. Non
   serve una libreria di grafici per una percentuale. */
.quota-cella { position: relative; }
.quota-barra {
  position: absolute; left: 0; top: 3px; bottom: 3px;
  background: var(--accent-soft);
  border-left: 1px solid var(--accent-line);
  border-radius: 1px;
  pointer-events: none;
}
.quota-cifra { position: relative; }

/* ========================= 15 · PANORAMICA (COCKPIT) =====================
   Brand Standards 3.6. Quattro movimenti: il quadrante con le quattro cifre
   di apertura, le misure del periodo, le cifre che chiedono una decisione, le
   conclusioni. Le classi restano quelle dei modelli e di `forme-vive.js`
   (`data-anello`, `data-mezzo`, `.ora-b`): cambia solo l'aspetto.
   ========================================================================= */
.ora-scena { display: grid; grid-template-columns: minmax(220px, 300px) minmax(0, 1fr); gap: var(--s-6); align-items: center; }
@container pg (max-width: 760px) { .ora-scena { grid-template-columns: minmax(0, 1fr); justify-items: center; } }
.qdr { position: relative; width: 100%; max-width: 300px; aspect-ratio: 1; margin: 0; }
.qdr-disco { display: block; width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.qdr-pista { fill: none; stroke: var(--soft); stroke-width: 14; }
.qdr-arco { fill: none; stroke-width: 14; stroke-linecap: round; stroke-dasharray: var(--q) 100; }
.qdr-a1 { stroke: var(--ramp-5); }
.qdr-a2 { stroke: var(--ramp-4); }
.qdr-a3 { stroke: var(--ramp-3); }
[data-moto="si"] .qdr-arco { animation: qdr-traccia var(--t-reveal) var(--ease-out) backwards;
  animation-delay: calc(var(--i) * 110ms + 120ms); }
/* L'impulso che ripercorreva gli anelli ogni cinque secondi è uscito il
   2026-09-28: un movimento in ciclo accanto a una cifra è esattamente ciò che
   DESIGN.md vieta («mai in ciclo»). Gli anelli si tracciano una volta. */
.qdr-cifra { position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; gap: 4px;
  text-align: center; pointer-events: none; font-weight: 400; }
.qdr-cifra span { font: 400 clamp(34px, 3.4vw, 46px)/1 var(--display); font-variant-numeric: tabular-nums; color: var(--ink); }
.qdr-cifra i { font: 500 11.5px/1.2 var(--sans); font-style: normal; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); }
/* Al passaggio su una cifra resta acceso il suo anello: cambia la luce, non la geometria. */
.qdr-arco { transition: opacity var(--t-panel) var(--ease-out); }
.ora-scena:has(.ora-b-1:is(:hover, :focus-visible)) .qdr-arco:not(.qdr-a1),
.ora-scena:has(.ora-b-2:is(:hover, :focus-visible)) .qdr-arco:not(.qdr-a2),
.ora-scena:has(.ora-b-3:is(:hover, :focus-visible)) .qdr-arco:not(.qdr-a3) { opacity: .18; }
.ora-fascia { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--grid-gap); width: 100%; }
@container pg (max-width: 560px) { .ora-fascia { grid-template-columns: minmax(0, 1fr); } }
.ora-b { display: grid; gap: 4px; align-content: start; min-width: 0; padding: var(--s-5); border-radius: var(--r-lg);
  background: var(--paper); box-shadow: 0 0 0 1px var(--line); color: var(--ink); text-decoration: none;
  transition: box-shadow var(--t-press); }
.ora-b:hover { box-shadow: 0 0 0 1px var(--ink-2); }
.ora-b:focus-visible { outline: 2px solid var(--pri-ink); outline-offset: 2px; }
.ora-e { display: flex; align-items: center; gap: 8px; font: 500 12px/1.3 var(--sans); letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-2); }
.ora-seg { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.ora-b-1 .ora-seg { background: var(--ramp-5); }
.ora-b-2 .ora-seg { background: var(--ramp-4); }
.ora-b-3 .ora-seg { background: var(--ramp-3); }
.ora-b-fuori .ora-e::before { content: ""; width: 8px; height: 8px; border-radius: 50%; flex: none; box-shadow: inset 0 0 0 1.5px var(--ink-2); }
.ora-v { font: 400 clamp(28px, 2.8vw, 38px)/1.05 var(--display); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.ora-s { font-size: 13px; color: var(--ink-2); line-height: 1.4; }
@container pg (min-width: 761px) { .piano-ora > .chiosa { margin-left: calc(min(300px, 100%) + var(--s-6)); } }

/* le misure del periodo: quattro pannelli, due e due */
.kpi-gruppi { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--grid-gap); }
@container pg (max-width: 860px) { .kpi-gruppi { grid-template-columns: minmax(0, 1fr); } }
.kpi-g { display: grid; gap: var(--s-3); align-content: start; min-width: 0; padding: var(--s-5); border-radius: var(--r-lg);
  background: var(--paper); box-shadow: 0 0 0 1px var(--line); }
.kpi-gt { margin: 0; font: 600 15px/1.35 var(--head); letter-spacing: -.01em; }
.kpi-riga { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3) var(--s-4); }
.kpi-riga > .kpi { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kpi-riga > .kpi-capo { grid-column: 1 / -1; }
.kpi-riga > .kpi > span { order: -1; font: 500 12px/1.3 var(--sans); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-2); }
.kpi-riga > .kpi > b { font: 400 clamp(20px, 1.8vw, 24px)/1.1 var(--display); font-variant-numeric: tabular-nums;
  letter-spacing: -.01em; white-space: nowrap; }
.kpi-riga > .kpi-capo > b { font-size: clamp(28px, 2.8vw, 38px); line-height: 1.05; }

/* le cifre che chiedono una decisione */
.cockpit { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--grid-gap); }
@container pg (max-width: 860px) { .cockpit { grid-template-columns: minmax(0, 1fr); } }
.tessera { display: flex; flex-direction: column; gap: var(--s-2); min-width: 0; padding: var(--s-5); border-radius: var(--r-lg);
  background: var(--paper); box-shadow: 0 0 0 1px var(--line); color: var(--ink); text-decoration: none;
  transition: box-shadow var(--t-press), transform var(--t-press) var(--ease-out); }
.tessera:hover { box-shadow: 0 0 0 1px var(--ink-2); }
.tessera:active { transform: scale(.99); }
.tessera:focus-visible { outline: 2px solid var(--pri-ink); outline-offset: 2px; }
.tessera-l { font: 600 15px/1.35 var(--head); letter-spacing: -.01em; }
.tessera-v { font: 400 clamp(28px, 2.8vw, 38px)/1.05 var(--display); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.tessera-v small { font: 500 14px var(--sans); color: var(--ink-2); letter-spacing: 0; }
.tessera-manca .tessera-v { font: 600 20px/1.25 var(--sans); letter-spacing: -.01em; }
.tessera-s { margin: 0; font-size: 13px; color: var(--ink-2); line-height: 1.45; }
.tessera-n { margin: 0; font-size: 13px; color: var(--ink-2); line-height: 1.45; }
.tessera-go { display: flex; align-items: center; gap: 6px; margin-top: auto; padding-top: var(--s-3); border-top: 1px solid var(--line);
  font-size: 13px; color: var(--ink-2); }
.tessera-go::after { content: "→"; margin-left: auto; }
.tessera-lock { font-size: var(--fs-0); }
/* la quota disegnata accanto alla cifra; rossa solo quando è fuori norma */
.mq { display: block; height: 6px; border-radius: var(--r-full); background: var(--soft); overflow: hidden; }
.mq i { display: block; height: 100%; border-radius: inherit; background: var(--data); }
.mq-male i { background: var(--err); }
.md { display: grid; gap: 3px; }
.md i { display: block; height: 6px; border-radius: var(--r-full); }
.md-su { background: var(--data); }
.md-giu { background: var(--ramp-3); }

/* le conclusioni: una riga per segnale, il quadratino dice la gravità */
.conclusioni { list-style: none; margin: 0; padding: 0; display: grid; border-radius: var(--r-lg); box-shadow: 0 0 0 1px var(--line); overflow: hidden; }
.conclusioni li { display: grid; grid-template-columns: minmax(180px, .34fr) minmax(0, 1fr); gap: var(--s-5); padding: var(--s-4) var(--s-5);
  border-top: 1px solid var(--line); font-size: 14.5px; }
.conclusioni li:first-child { border-top: 0; }
.conclusioni strong { display: flex; gap: 10px; align-items: baseline; font-weight: 600; color: var(--ink); }
.conclusioni strong::before { content: ""; width: 8px; height: 8px; border-radius: 2px; flex: none; transform: translateY(-1px); background: var(--ramp-2); }
.conclusioni .grav-alta strong::before { background: var(--data); }
.conclusioni .grav-media strong::before { background: var(--ramp-3); }
.conclusioni span { color: var(--ink-2); line-height: 1.55; }
@container pg (max-width: 640px) { .conclusioni li { grid-template-columns: minmax(0, 1fr); gap: var(--s-1); } }


/* Cinque tessere, sempre cinque (`app._cockpit` le costruisce tutte, e quella
   senza dato dice cosa manca invece di sparire). Su una griglia da tre
   l'ultima riga resterebbe con un buco; su sei colonne le prime tre occupano
   due colonne e le ultime due ne occupano tre, e le righe si chiudono.

   Non è solo simmetria: le prime tre dicono come sta andando, le ultime due
   cosa richiede una decisione. La riga separa i due gruppi da sé. */


/* La reazione sta sulla pressione, non sul rilascio: aspettare il click per
   dare un segnale fa sembrare morta l'interfaccia. */


/* Una sola metrica di testa per schermo porta l'accento: è quella da cui si
   legge tutto il resto. Le altre sono inchiostro. */


/* Un dato che manca non è uno zero, e non deve somigliargli. */


/* Quando è la riga sotto a portare la notizia cattiva, è la riga a segnalarlo:
   la cifra grande resta com'è. E porta il segno oltre al colore, come ovunque. */
.card.kpi > .kpi-value + p.avviso { color: var(--warn); }
.card.kpi > .kpi-value + p.avviso::before { content: "▲ "; font-weight: 700; }


/* Lo stato dei documenti non è una decisione: è una fascia di servizio, e in
   una fascia sta. Tre schede alte quanto una KPI, per dire dove sta un file,
   toglievano lo schermo alle cifre che contano. */
.strip {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--sp-2) var(--sp-5);
  margin: 0 0 var(--sp-5);
  padding: var(--sp-3) var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-3);
  font-size: var(--fs-2);
}
/* ============================ 16 · LE FORME =============================
   Tre grafici in tutta l'applicazione, e per ognuno la ragione per cui è un
   grafico: mostra una FORMA che la tabella sotto non può mostrare. La tabella
   resta, con le stesse cifre — il grafico non è la fonte, è la lettura.
   ======================================================================== */

.forma { }
.forma-perche {
  margin: 0 0 var(--sp-3);
  padding-left: var(--sp-3);
  border-left: 1px solid var(--accent-line);
  color: var(--muted); font-size: var(--fs-2); line-height: var(--lh-body);
  max-width: 92ch;
}
/* La frase che il grafico dimostra, scritta a parole e con i suoi numeri: chi
   non sa leggere una curva cumulata deve poter leggere la stessa cosa. */
.forma-esito {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-4); line-height: var(--lh-body); max-width: 86ch;
}
.forma-esito strong { font-variant-numeric: tabular-nums; }

.chart-box.grande { height: 340px; }
.chart-box.media { height: 260px; }
/* I contatti sono interi piccoli e sessanta annunci stanno su 0 o 1: il
   quadrante da leggere è una striscia in fondo al riquadro, e più alto è il
   riquadro più quella striscia è alta. */
.chart-box.dispersione { height: 420px; }

.legenda {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5);
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-2); color: var(--muted);
}
.legenda > span { display: inline-flex; align-items: center; gap: var(--sp-2); }
/* Il segno porta il colore, il testo resta inchiostro: un'etichetta colorata
   si legge peggio e non aggiunge niente che il segno non dica già. */
.sw { width: 11px; height: 11px; flex: none; border-radius: 50%; }
.sw-dato { background: var(--chart-dato); }
.sw-segnalato { background: var(--chart-segnalato); clip-path: polygon(50% 0, 100% 100%, 0 100%); border-radius: 0; }
.sw-sfondo { background: var(--chart-sfondo); }
.sw-riferimento {
  width: 18px; height: 0; border-radius: 0;
  border-top: 2px dashed var(--chart-riferimento);
}
/* Un intervallo statistico non è un'anomalia: resta neutro come le altre
   annotazioni, o il rosso finirebbe per non voler più dire niente. */
.sw-intervallo {
  background: color-mix(in srgb, var(--chart-riferimento) 26%, transparent);
  border: 1px solid var(--chart-riferimento); border-radius: 2px;
}

/* Il grafico è la lettura, la tabella è la fonte: si può richiudere, non
   togliere. Aperta di suo quando è corta, richiusa quando sarebbe una parete. */
.fonte-cifre { margin: var(--sp-6) 0; }
.fonte-cifre:last-child { margin-bottom: 0; }

/* Il comando che apre la fonte è un COMANDO, e va detto. Era un filo grigio
   con sopra una riga da dodici pixel del colore delle didascalie: chi non
   sapeva già che si apriva non aveva modo di scoprirlo, e chi lo sapeva
   doveva mirare una riga di testo alta sedici pixel. Ora è un bersaglio con
   un contorno suo, del colore del marchio, scritto nel corpo del testo — e
   largo quanto la sezione, così il clic non si deve puntare.

   Contorno e non riempimento: un bottone pieno qui peserebbe come «genera il
   report», e questo comando apre una tabella. Il segno che ruota dice da solo
   in che stato è. */
.fonte-cifre > summary {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  cursor: pointer;
  list-style: none;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--warn-line);
  border-radius: var(--r-2);
  background: linear-gradient(180deg,
              color-mix(in srgb, var(--warn) 8%, transparent), transparent 78%);
  color: var(--text);
  font-size: var(--fs-3);
  font-weight: 600;
  letter-spacing: -0.006em;
  transition: border-color var(--t-stato) var(--ease-out),
              background-color var(--t-stato) var(--ease-out),
              color var(--t-stato) var(--ease-out);
}
.fonte-cifre > summary::-webkit-details-marker { display: none; }
/* Il segno è disegnato con i bordi, non preso a prestito da un carattere: un
   triangolo unicode cambia forma e larghezza da un sistema all'altro, e in
   questa applicazione nessun altro segno è un glifo. */
.fonte-cifre > summary::before {
  content: "";
  flex: 0 0 auto;
  width: 0; height: 0;
  border-left: 5px solid var(--warn);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform var(--t-stato) var(--ease-out);
}
.fonte-cifre[open] > summary::before { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) {
  .fonte-cifre > summary::before { transition: none; }
}
.fonte-cifre > summary:hover {
  border-color: var(--warn);
  background: linear-gradient(180deg,
              color-mix(in srgb, var(--warn) 8%, transparent), transparent 78%);
}
.fonte-cifre > summary:focus-visible {
  outline: 2px solid var(--warn);
  outline-offset: 2px;
}
/* Aperta, la fonte ha bisogno d'aria fra il comando e la tabella: attaccata,
   la prima intestazione sembrava parte del bottone. */
.fonte-cifre[open] > summary { margin-bottom: var(--sp-4); }

/* Le misure che non guidano una decisione ma servono a leggerne una: stanno
   nella sezione che le riguarda, non nella fascia in cima alla pagina. */
/* Tessere, non schede: la larghezza segue il numero di voci fino a un massimo.
   Due misure stirate a mezza pagina l'una peserebbero come due KPI, ed è
   esattamente il peso che qui si voleva togliere. */
.misure {
  display: flex; flex-wrap: wrap;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-4);
}
.misure .mini { flex: 1 1 155px; max-width: 240px; }

/* ====================== 17 · LE FORME COMPOSTE DAL SERVER ================
   Treemap, matrice di densità, divario, intervalli, banda, movimento.

   Nessuna tela e nessun SVG: la geometria arriva già calcolata da `forme.py`
   e qui restano solo dei rettangoli da collocare in percentuale. Il guadagno
   non è di stile — è che il testo dei grafici resta TESTO: si ingrandisce con
   lo zoom, lo trova la ricerca della pagina, lo legge uno screen reader, esce
   nella stampa e cambia colore con il tema da sé.

   La rampa vive qui in un solo posto (`.g0…g4`) e la usano tutte le forme:
   una cella della matrice e una piastrella del treemap che dicono «tanto»
   devono essere lo stesso colore, o la scala non è una scala.
   ======================================================================== */

.g0 { background: var(--seq-1); --seq-ink: var(--seq-ink-1); }
.g1 { background: var(--seq-2); --seq-ink: var(--seq-ink-2); }
.g2 { background: var(--seq-3); --seq-ink: var(--seq-ink-3); }
.g3 { background: var(--seq-4); --seq-ink: var(--seq-ink-4); }
.g4 { background: var(--seq-5); --seq-ink: var(--seq-ink-5); }
/* -1 = «nessuno». Non è il gradino più basso: è il vuoto, e deve leggersi
   come vuoto. Una cella senza immobili e una con un immobile sono due fatti
   diversi e non devono somigliarsi. */
.g-1 { background: var(--seq-0); --seq-ink: var(--seq-ink-chiaro); }
/* Il testo sopra un passo segue il passo (`--seq-ink`, quadra.css § 3): il
   server dice ancora «chiaro» o «scuro», e vale dove il browser non sa
   leggere la luce di un colore. */
.ink-chiaro { color: var(--seq-ink, var(--seq-ink-chiaro)); }
.ink-scuro { color: var(--seq-ink, var(--seq-ink-scuro)); }

/* --------------------------------------------------------------- TREEMAP */
.tm { margin: 0; }
.tm-piano {
  position: relative;
  width: 100%;
  /* Il rapporto è quello con cui `forme.treemap` ha calcolato i rettangoli:
     cambiarlo qui li deformerebbe, e l'area smetterebbe di essere la
     quantità che dichiara di essere.

     Nessun `min-height`, e non è una dimenticanza: ce n'era uno da 300px, e
     su uno schermo stretto vinceva sul rapporto: la mappa restava alta 300
     pixel su 309 di larghezza, tutte le piastrelle stirate in verticale e
     l'area di ognuna sbagliata. Su schermo largo non serviva — il 62% di
     mille pixel sono già seicento — quindi faceva danno e basta. */
  aspect-ratio: 100 / 62;
  border-radius: var(--r-2);
  overflow: hidden;
  background: var(--bg);
}
.tm-blocco { position: absolute; }
.tm-cella {
  position: absolute;
  display: flex; flex-direction: column; justify-content: flex-end;
  gap: 1px;
  padding: 6px 8px;
  overflow: hidden;
  /* Il filetto è del colore del fondo pagina, non una linea in più: separa
     due piastrelle senza aggiungere un segno da interpretare. */
  box-shadow: inset 0 0 0 1px var(--bg);
  line-height: 1.15;
}
.tm-nome {
  font-size: var(--fs-1); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  opacity: 0.86;
}
.tm-n {
  font-size: var(--fs-4); font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: -0.015em;
}
/* Il nome della famiglia sta SOPRA le sue piastrelle, non accanto: è il modo
   in cui un treemap dichiara i suoi due livelli senza una seconda legenda. La
   striscia in cui sta è riservata dalla geometria (`forme.treemap(testata=…)`),
   non sovrapposta: appoggiarlo sulle piastrelle avrebbe coperto sempre la più
   grande, cioè quella che più merita di essere letta. */
.tm-fam {
  position: absolute; top: 0; left: 0; right: 0;
  display: flex; align-items: center; gap: var(--sp-2);
  padding: 0 2px 4px;
  font-size: var(--fs-0); font-weight: 700;
  text-transform: uppercase; letter-spacing: var(--track-label);
  color: var(--muted);
  white-space: nowrap; overflow: hidden;
  pointer-events: none;
}
.tm-fam b {
  color: var(--text); font-weight: 700; letter-spacing: 0;
  font-size: var(--fs-2); font-variant-numeric: tabular-nums;
}
.tm-sotto {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-4);
  margin-top: var(--sp-3); font-size: var(--fs-2); color: var(--muted);
}
.tm-leg-t {
  font-size: var(--fs-0); font-weight: 700;
  text-transform: uppercase; letter-spacing: var(--track-label);
}
/* La legenda porta gli intervalli, non solo le sfumature: una scala di colore
   senza i suoi numeri è una decorazione. */
.tm-leg { display: flex; border-radius: var(--r-1); overflow: hidden; }
.tm-leg-p {
  padding: 3px 8px; font-size: var(--fs-1); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.tm-leg-p { color: var(--seq-ink, var(--seq-ink-chiaro)); }
.tm-leg-n { color: var(--dim); font-size: var(--fs-1); }

/* --------------------------------------------------------------- DIVARIO */
.dv, .iv, .mv { margin: 0 0 var(--sp-3); }
.dv-testa, .dv-riga, .iv-riga, .mv-riga {
  display: grid;
  grid-template-columns: minmax(96px, 168px) 1fr 64px;
  align-items: center;
  gap: var(--sp-3);
  padding: 3px 0;
}
.dv-testa { padding-bottom: var(--sp-3); }
.dv-h {
  font-size: var(--fs-0); font-weight: 700; text-align: right;
  text-transform: uppercase; letter-spacing: var(--track-label);
  color: var(--muted);
}
.dv-scala, .iv-scala { position: relative; height: 12px; }
.dv-scala i, .iv-scala i {
  position: absolute; top: 0; width: 1px; height: 5px;
  background: var(--border-strong);
}
.dv-scala i em, .iv-scala i em {
  position: absolute; top: 6px; left: 0; transform: translateX(-50%);
  font-size: var(--fs-0); font-style: normal; color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.dv-scala i:first-child em, .iv-scala i:first-child em { transform: none; }
.dv-scala i:last-child em, .iv-scala i:last-child em { transform: translateX(-100%); }
/* La scala dell'asse sta sotto le piste e in colonna con loro: è una riga
   della stessa griglia, con la prima e l'ultima cella vuote. Allinearla a
   occhio con un margine fisso si sarebbe scollata al primo nome più lungo. */
.iv-assi { margin-bottom: var(--sp-4); align-items: start; }
.iv-assi .iv-scala { height: 14px; }

.dv-nome, .iv-nome, .mv-nome, .cl-nome {
  font-size: var(--fs-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.iv-nome em, .mv-nome em {
  margin-left: var(--sp-2); font-style: normal;
  font-size: var(--fs-1); color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.dv-pista, .iv-pista, .mv-pista {
  position: relative; height: 22px;
  border-radius: var(--r-1);
}
/* La riga di fondo è un binario, non una griglia: dice dove finisce la scala
   senza mettere in pagina cinque righe verticali che non servono a nessuno. */
.dv-pista::before, .mv-pista::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: 1px; background: var(--border); transform: translateY(-50%);
}
.dv-seg, .mv-seg {
  position: absolute; top: 50%; height: 3px;
  transform: translateY(-50%);
  border-radius: 2px;
  background: var(--chart-metro);
  min-width: 1px;
}
/* Lo scarto porta l'accento come ogni altro grafico (Brand Standards 12.14):
   il verso si legge dal tono — pieno quando il gruppo rende più di quanto
   pesa, al 45 % verso la carta quando rende meno — e da tre codifiche che
   non dipendono dal colore: il segno nella colonna a destra (+9,7 / −9,1),
   l'ordine delle righe (tutte le positive sopra le negative) e la posizione
   del punto pieno rispetto a quello vuoto. Fino alla 3.8 qui c'erano il verde
   e il rosso degli stati: fra i segni si confondevano con gli accenti Verde,
   Rosso e Rossetto, e uno stato non è una serie. */
.dv-sopra .dv-seg, .mv-su .mv-seg { background: var(--data); }
.dv-sotto .dv-seg, .mv-giu .mv-seg { background: color-mix(in srgb, var(--data) 45%, var(--paper)); }
/* I due punti si distinguono per RIEMPIMENTO, non per tinta: vuoto contro
   pieno è una distinzione che nessuna forma di daltonismo tocca, e con un
   accento solo la tinta non avrebbe comunque niente da distinguere. */
.dv-p, .mv-p {
  position: absolute; top: 50%;
  width: 11px; height: 11px; margin-left: -5.5px;
  transform: translateY(-50%);
  border-radius: 50%;
  /* L'anello del colore del fondo tiene separati i due punti quando lo scarto
     è quasi zero e si sovrappongono. */
  box-shadow: 0 0 0 2px var(--surface);
}
.dv-peso, .mv-prima {
  background: var(--surface);
  border: 2px solid var(--chart-metro);
}
.dv-resa, .mv-dopo { background: var(--data); }
/* Il punto «dopo» è quello che conta e va sopra l'altro quando coincidono. */
.dv-resa, .mv-dopo { z-index: 1; }
.dv-val, .mv-val {
  text-align: right; font-size: var(--fs-3); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.dv-sopra .dv-val, .mv-su .mv-val { color: var(--pri-ink); }
.dv-sotto .dv-val, .mv-giu .mv-val { color: var(--ink); }
.dv-pari .dv-val, .mv-fermo .mv-val { color: var(--dim); }

.dv-legenda {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-5);
  margin-top: var(--sp-4); padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
  font-size: var(--fs-2); color: var(--muted);
}
.dv-legenda > span { display: inline-flex; align-items: center; gap: var(--sp-2); }
.dv-legenda .dv-p, .dv-legenda .mv-p {
  position: static; transform: none; margin: 0; box-shadow: none;
}
.dv-nota { color: var(--dim); font-size: var(--fs-1); flex: 1 1 300px; }

/* ------------------------------------------------------------ INTERVALLI */
.iv-pista { height: 24px; }
.iv-baffo {
  position: absolute; top: 50%; height: 1px;
  transform: translateY(-50%);
  background: var(--chart-riferimento);
}
/* La scatola è neutra e non rossa: un intervallo statistico non è
   un'anomalia, e il rosso qui finirebbe per non voler più dire niente. */
.iv-box {
  position: absolute; top: 50%; height: 15px;
  transform: translateY(-50%);
  background: color-mix(in srgb, var(--chart-dato) 34%, transparent);
  border: 1px solid color-mix(in srgb, var(--chart-dato) 62%, transparent);
  border-radius: var(--r-xs);
  min-width: 2px;
}
.iv-med {
  position: absolute; top: 50%; width: 2px; height: 21px;
  margin-left: -1px; transform: translateY(-50%);
  background: var(--data); border-radius: 1px;
}
.iv-swatch {
  position: static; transform: none; margin: 0;
  width: 16px; height: 10px; flex: none;
}
.iv-med.iv-swatch { width: 2px; height: 14px; }
.iv-baffo.iv-swatch { height: 1px; width: 18px; }
.iv-val {
  text-align: right; font-size: var(--fs-3); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.iv-val em {
  display: block; font-style: normal; font-size: var(--fs-1);
  font-weight: 400; color: var(--dim);
}

/* --------------------------------------------------------------- MATRICE */
.mx-avvolge { overflow-x: auto; }
.mx { width: 100%; border-collapse: separate; border-spacing: 2px; }
.mx th {
  font-size: var(--fs-1); font-weight: 600; color: var(--muted);
  text-align: center; padding: var(--sp-2) var(--sp-1);
  vertical-align: bottom; line-height: 1.2;
}
.mx thead th:first-child, .mx tbody th, .mx tfoot th { text-align: left; }
.mx tbody th {
  white-space: nowrap; padding-right: var(--sp-3);
  font-size: var(--fs-3); color: var(--text); font-weight: 500;
}
.mx td {
  text-align: center; padding: var(--sp-2) var(--sp-1);
  font-size: var(--fs-3); font-weight: 600;
  font-variant-numeric: tabular-nums;
  border-radius: var(--r-1);
  min-width: 38px;
}
/* Nessun fondo dichiarato qui: la campitura arriva da `.g-1…g4`, e una regola
   più specifica in questo punto le vincerebbe tutte lasciando la matrice
   grigia. È successo, e da fuori sembrava che il colore non fosse stato
   scritto affatto. */
.mx-tot {
  background: transparent !important; color: var(--muted) !important;
  font-weight: 700;
}
.mx tfoot td, .mx tfoot th {
  background: transparent; color: var(--muted);
  border-top: 1px solid var(--border); font-weight: 600;
}
.mx-legenda { margin-top: var(--sp-3); }

/* ----------------------------------------------------------------- BANDA */
.bn {
  display: flex; width: 100%; height: 30px;
  border-radius: var(--r-1); overflow: hidden;
}
.bn-s {
  display: flex; align-items: center; justify-content: center;
  min-width: 2px;
  box-shadow: inset 0 0 0 1px var(--bg);
  font-size: var(--fs-1); font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.bn-leg {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  margin-top: var(--sp-3); font-size: var(--fs-2); color: var(--muted);
}
.bn-leg > span { display: inline-flex; align-items: center; gap: var(--sp-2); }
.bn-leg i { width: 10px; height: 10px; border-radius: 2px; flex: none; }
.bn-leg b { color: var(--text); font-variant-numeric: tabular-nums; }
.bn-leg em { font-style: normal; color: var(--dim); font-size: var(--fs-1); }

/* ------------------------------------------------------------ CLASSIFICA */
.cl-riga {
  display: grid; grid-template-columns: minmax(90px, 150px) 1fr 76px;
  align-items: center; gap: var(--sp-3); padding: 2px 0;
}
.cl-pista { position: relative; height: 15px; }
.cl-pista i {
  position: absolute; left: 0; top: 0; height: 100%;
  background: var(--chart-dato);
  border-radius: 0 3px 3px 0;
  min-width: 2px;
}
.cl-val {
  text-align: right; font-size: var(--fs-3); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.cl-val em {
  margin-left: var(--sp-2); font-style: normal; font-weight: 400;
  font-size: var(--fs-1); color: var(--dim);
}

/* ------------------------------------------------------------------ MICRO
   Non sono grafici: sono la cifra che porta con sé la sua proporzione. Una
   percentuale scritta e la stessa percentuale vista arrivano in due momenti
   diversi, e in una tessera servono tutti e due. */


.mb {
  display: flex; height: 6px; width: 100%;
  margin: var(--sp-1) 0 0;
  border-radius: var(--r-xs); overflow: hidden;
}
.mb i { display: block; height: 100%; box-shadow: inset 0 0 0 0.5px var(--surface); }
/* Alta abbastanza da essere una forma. A trentaquattro pixel la curva c'era e
   non si vedeva: una cumulata che sale ripida e una che sale piano diventano
   lo stesso ghirigoro, ed era proprio la differenza fra le due il motivo per
   cui la curva sta in pagina. */
.mc {
  display: block; width: 100%; height: 84px; margin: var(--sp-2) 0 0;
  border-bottom: 1px solid var(--border);
}
.mc-area { fill: color-mix(in srgb, var(--chart-dato) 30%, transparent); }
.mc-linea { fill: none; stroke: var(--chart-dato); stroke-width: 2px; }
.mc-soglia {
  stroke: var(--chart-riferimento); stroke-width: 1px; stroke-dasharray: 2 2;
}
/* Entrate e uscite: due barre sulla stessa scala, una sopra l'altra. Verso
   opposto e colore diverso, ma la cifra sta scritta accanto — il colore da
   solo non dice quale delle due è quale. */


/* --------------------- PANORAMICA · ritratto e forme mini ---------------
   Una riga di composizione sopra le cifre, e due riquadri di forma sotto.
   Sono collegamenti come le tessere: la forma dice che c'è qualcosa da
   guardare, la pagina profonda dice cosa. */
.ritratto {
  display: block;
  margin: 0 0 var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-3);
  color: inherit; text-decoration: none;
  transition: border-color var(--t-stato) var(--ease-out),
              background-color var(--t-stato) var(--ease-out),
              transform var(--t-pressione) var(--ease-out);
}
.ritratto:hover { background: var(--surface-2); border-color: var(--border-strong); }
.ritratto:active { transform: scale(0.996); }
.ritratti { margin-bottom: var(--sp-5); }
.forma-mini-l {
  font-size: var(--fs-4); font-weight: 650; letter-spacing: -0.005em;
  color: var(--text);
}
.forma-mini-d {
  margin: var(--sp-2) 0 var(--sp-4);
  font-size: var(--fs-2); color: var(--dim); line-height: var(--lh-body);
}
.forma-mini-d em { font-style: normal; color: var(--muted); font-weight: 600; }
.forma-mini-e {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-3); color: var(--muted); line-height: var(--lh-body);
}
.forma-mini-e strong { color: var(--text); font-variant-numeric: tabular-nums; }
/* Nel riquadro compatto le piste sono più corte e i nomi più stretti: senza
   questa griglia i sei nomi di zona prenderebbero metà del riquadro. */
.dv-compatto .dv-riga { grid-template-columns: minmax(72px, 104px) 1fr 50px; }
.dv-compatto .dv-pista { height: 18px; }
.dv-compatto .dv-nome, .dv-compatto .dv-val { font-size: var(--fs-2); }

/* Le due sorgenti a confronto, in Qualità dati. Ogni barra è al 100% la sua
   sorgente: sono due proporzioni diverse, non due parti di un totale, e
   metterle sulla stessa scala assoluta avrebbe fatto sembrare l'anagrafica
   grande la metà dell'export. */
.ric {
  display: grid;
  grid-template-columns: minmax(150px, 200px) 1fr minmax(140px, 190px);
  align-items: center; gap: var(--sp-4);
  margin: var(--sp-4) 0;
}
.ric-l { font-size: var(--fs-3); font-weight: 600; }
.ric-l em {
  display: block; font-style: normal; font-weight: 400;
  font-size: var(--fs-1); color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.ric-n { font-size: var(--fs-1); color: var(--dim); }
.ric .bn { height: 26px; }
/* Il segmento vuoto porta comunque la sua cifra: è la parte che NON combacia,
   ed è quella che si va a cercare. */
.ric .bn-s.g-1 { color: var(--muted); }


@media (max-width: 900px) {
  /* Su uno schermo stretto la testata va a capo tre volte e arriva a occupare
     un quinto dell'altezza: a quel punto non è più una testata che resta in
     vista, è una fetta di schermo tolta al contenuto. Torna a scorrere via, e
     con lei sparisce la dissolvenza che serviva solo a chi le passa sotto. */
  .page-head { position: static; margin-left: calc(var(--sp-4) * -1);
               margin-right: calc(var(--sp-4) * -1);
               padding-left: var(--sp-4); padding-right: var(--sp-4);
               backdrop-filter: none; -webkit-backdrop-filter: none;
               background: transparent; border-bottom-color: var(--border); }
  .page-head::after { display: none; }
  .page-head .periodo-scelta { margin-left: 0; }
  [data-sezione] { scroll-margin-top: var(--sp-4); }
  .chart-box.grande { height: 300px; }
  .chart-box.dispersione { height: 340px; }
}


/* ================= 19 · IL METRO A TACCHE — la prima firma ===============
   Una quantità di Quadra è una cosa CONTABILE: immobili, annunci, contatti.
   Una barra continua dichiara un continuo che nel dato non c'è, e per leggerla
   serve un asse che quasi mai le sta accanto. Le tacche si contano.

   L'unità la calcola `forme.tacche()` e la dichiara sempre in legenda: un
   metro con l'unità nascosta è peggio di una barra onesta.
   ========================================================================= */
.metro {
  display: flex; align-items: stretch;
  gap: 2px;
  height: 22px;
  min-width: 0;
}
.metro i {
  flex: 1 1 0; min-width: 1px;
  border-radius: 1px;
  background: var(--surface-3);
}
.metro i.on { background: var(--data); }
/* Il metro dentro una cifra: più basso, e la tacca piena è inchiostro invece
   che accento — l'accento resta a UNA misura per schermata. */
.metro-mini { height: 8px; gap: 1.5px; }
.metro-mini i.on { background: var(--muted); }
.metro-male i.on { background: var(--bad); }
/* La legenda del metro dichiara l'unità e il valore vero. Senza di lei il
   disegno è un'approssimazione non dichiarata, che è la cosa che questo
   strumento non fa. */
.metro-leg {
  display: flex; align-items: baseline; gap: var(--sp-2) var(--sp-4);
  flex-wrap: wrap;
  margin-top: var(--sp-2);
  font-size: var(--fs-1); color: var(--dim);
}
.metro-leg b {
  color: var(--text); font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.metro-leg em { font-style: normal; color: var(--muted); }

/* ================= 20 · IL TERRITORIO — la seconda firma =================
   Le valli come fasce, i comuni come celle. La larghezza di una fascia È la
   quota della zona sul portafoglio intero: tutte le fasce condividono una sola
   scala orizzontale, e questa è la ragione per cui la forma dice qualcosa che
   una classifica non dice. Se ogni fascia si normalizzasse su sé stessa, sei
   valli larghe uguale direbbero che pesano uguale.

   La campitura porta i contatti per annuncio pubblicato: dove STA il
   portafoglio e dove RISPONDE sono due fatti diversi, e qui stanno uno sopra
   l'altro.

   Non è una mappa: nel dato non ci sono coordinate. Le celle sono rettangoli
   in fila, ed è deliberato — una sagoma inventata sarebbe una bugia.
   ========================================================================= */
.territorio { display: flex; flex-direction: column; gap: 3px; }

.terr-fascia {
  display: grid;
  /* TRE colonne, non due: il nome, la pista, e le due cifre in coda. Con due
     colonne dichiarate il terzo figlio finiva in una riga implicita sotto la
     pista e le fasce si accavallavano — una griglia non manda a capo, apre
     una riga nuova. */
  grid-template-columns: minmax(104px, 148px) 1fr auto;
  align-items: center;
  gap: var(--sp-3);
  min-width: 0;
}
.terr-nome {
  display: flex; align-items: baseline; gap: var(--sp-2);
  font-size: var(--fs-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.terr-nome b { font-weight: 600; }
.terr-nome em {
  font-style: normal; font-size: var(--fs-1); color: var(--dim);
  font-variant-numeric: tabular-nums;
}
/* La pista è larga quanto il portafoglio; la fascia dentro è larga quanto la
   zona. Il binario dichiara la scala anche dove la zona è quasi vuota. */
.terr-pista {
  position: relative;
  height: 30px;
  min-width: 0;
  border-radius: var(--r-1);
  /* Il binario è del fondo pagina, non della scheda, e serve a una cosa
     precisa: il gradino più basso della rampa (#7a4216) su `--surface` è un
     bruno scuro su un grigio scuro, e in una fascia alta trenta pixel sparisce.
     Su `--bg` stacca. Nel treemap non succedeva perché lì le piastrelle sono
     grandi: la stessa tinta a due dimensioni diverse è un problema diverso. */
  background: var(--bg);
  box-shadow: inset 0 0 0 1px var(--border);
}
.terr-celle { display: flex; height: 100%; gap: 1px; }

.terr-cella {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  /* Una zona che ha degli immobili deve VEDERSI, anche quando ne ha uno su
     duecentosei: tre pixel non falsano una proporzione, ma la differenza fra
     tre pixel e zero è la differenza fra «quasi niente» e «niente». */
  min-width: 3px;
  padding: 0 3px;
  border: 0;
  font: inherit;
  color: var(--seq-ink, var(--seq-ink-chiaro));
  cursor: pointer;
  overflow: hidden;
  transition: filter var(--t-stato) var(--ease-out),
              box-shadow var(--t-stato) var(--ease-out);
}
.terr-celle > :first-child { border-radius: var(--r-1) 0 0 var(--r-1); }
.terr-celle > :last-child  { border-radius: 0 var(--r-1) var(--r-1) 0; }
.terr-cella span {
  font-size: var(--fs-1); font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: clip;
  pointer-events: none;
}
.terr-cella.ink-scuro { color: var(--seq-ink, var(--seq-ink-scuro)); }
/* La coda e il resto non hanno una resa: sono un conteggio dichiarato, e la
   campitura piatta lo dice. Colorarli fingerebbe una media che non esiste. */
.terr-cella.coda {
  background: var(--surface-3);
  color: var(--muted);
  box-shadow: inset 0 0 0 1px var(--border);
}
@media (hover: hover) and (pointer: fine) {
  .terr-cella:hover { filter: brightness(1.16); }
}
.terr-cella:focus-visible,
.terr-cella[aria-expanded="true"] {
  box-shadow: inset 0 0 0 2px var(--text);
  outline: none;
}
.terr-cella:active { filter: brightness(1.24); }

/* La zona vuota resta in pagina: una valle senza immobili è un'informazione,
   e toglierla dall'elenco la nasconde. */
.terr-fascia.vuota .terr-nome { color: var(--dim); }
/* Su schermo stretto la pista si dimezza e la soglia con cui `forme.territorio`
   ha deciso quali celle reggono la loro cifra — calcolata sulla quota, non sui
   pixel — non vale più: una cella che a 1400 px teneva «21» a 390 px ne mostra
   «2», e «2» è un altro numero. Meglio nessuna cifra che una cifra sbagliata:
   la proporzione resta leggibile, il conteggio della zona sta nell'etichetta a
   sinistra, e ogni cella apre il suo comune con tutte le misure. */
@media (max-width: 720px) {
  .terr-cella span { display: none; }
  .terr-fascia { grid-template-columns: minmax(88px, 128px) 1fr auto; }
}

.terr-scala {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--sp-2) var(--sp-5);
  margin-top: var(--sp-4); padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
  font-size: var(--fs-2); color: var(--muted);
}

/* ============ 22 · I CANALI — ciò che c'è e ciò che non c'è ancora =======
   Il principio, ed è uno solo: **l'interfaccia non dichiara mai una freschezza
   che non ha.** Un file caricato a mano ha un'ETÀ, non una sincronizzazione, e
   chiamarlo «collegato» sarebbe la stessa bugia di un cruscotto che scrive
   «tempo reale» sopra una tabella aggiornata ogni notte.

   Quattro stati e nessun dato finto. Un canale «previsto» occupa il suo posto
   in pagina da subito, dice che cosa manca e non mostra nessun numero: un
   posto vuoto dichiarato è informazione, uno nascosto è una sorpresa il giorno
   del collegamento.
   ========================================================================= */
.canali {
  display: grid;
  gap: var(--grid-gap) !important;
  /* «Housebook — Elenco Agenzia» e «Meta — Facebook e Instagram» sono nomi
     lunghi: sotto i 300 px il titolo va a capo tre volte e il chip di stato ci
     finisce sopra. La colonna si dimensiona sul nome più lungo che deve
     ospitare, non su un numero tondo. */
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--sp-3);
}

.canale {
  display: flex; flex-direction: column; gap: var(--s-3);
  padding: var(--s-5);
  background: var(--paper);
  border: 0;
  box-shadow: 0 0 0 1px var(--line);
  border-radius: var(--r-lg);
  min-width: 0;
}
/* Nome e stato in colonna, non affiancati: affiancati, il chip veniva spinto
   sopra il titolo appena il nome andava a capo — cioè sempre, con questi nomi.
   Il segno occupa la colonna di sinistra su entrambe le righe. */
.canale-testa {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  gap: 2px var(--s-3);
  align-items: center;
}
.canale-segno { grid-row: span 2; align-self: start; }

/* --------------------------- i mestieri di un fornitore --------------------
   Con Meta il consenso non è uno: pubblicare e leggere stanno in due
   configurazioni Login for Business diverse, e quindi in due permessi
   diversi. Il blocco esiste per rendere quella distinzione VISIBILE dove si
   fa la scelta — prima esisteva solo nel codice, e chi voleva il Marketing
   premeva l'unico pulsante e riceveva l'altra configurazione.

   Il filo a sinistra è lo stesso della chiosa: dice «questo sta dentro quello
   di sopra» senza aggiungere una scatola dentro una scatola. */
.scopo {
  border-left: 2px solid var(--border);
  padding-left: var(--sp-3);
  display: flex; flex-direction: column; gap: var(--sp-2);
}
.scopo-collegato { border-left-color: var(--ok-line); }
.scopo-testa {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
}
.scopo-testa strong { font-size: var(--fs-3); font-weight: 600; }
.scopo-nota { margin: -2px 0 0; line-height: 1.45; }
.scopo-comandi {
  display: flex; align-items: center; gap: var(--sp-3);
  flex-wrap: wrap; margin: 0;
}
.scopo-comandi code {
  font-family: var(--font-mono); font-size: var(--fs-1);
  background: var(--surface-2); border: 1px solid var(--border);
  padding: 1px 5px; border-radius: var(--r-1);
}
.canale-nome { min-width: 0; }
.canale-nome strong {
  font: 600 15px/1.3 var(--head); letter-spacing: -.01em;
}
.canale-stato { margin-left: 0; justify-self: start; }
/* Il segno del canale: due lettere, non un'emoji. Un'emoji cambia disegno su
   ogni sistema operativo e non è un sistema di icone. */
.canale-segno {
  flex: none;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 12px;
  background: var(--soft);
  font: 700 12px/1 var(--sans); letter-spacing: .02em;
  color: var(--ink);
}
.canale-stato { justify-self: start; }

/* Una griglia, non un flex che va a capo: con `flex-wrap` le misure si
   incolonnavano ognuna sotto una voce diversa a seconda della lunghezza della
   parola sopra, e sette misure finivano in tre colonne disallineate. Una
   griglia le tiene in colonna, che è l'unico modo di confrontarle a vista. */
.canale-mis {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
  gap: var(--s-2);
  font-size: 13px;
}
.canale-mis > span { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: var(--s-3); border-radius: var(--r-md); background: var(--panel); }
.canale-mis em { overflow: hidden; text-overflow: ellipsis; }
.canale-mis b { font: 600 18px/1.2 var(--sans); font-variant-numeric: tabular-nums; }
.canale-mis em { font-style: normal; font-size: 12px; color: var(--ink-2); line-height: 1.3; }

/* L'età del dato, disegnata. Un canale a file non ha una sincronizzazione: ha
   giorni passati dall'export, e il metro li conta. */
.canale-eta { margin-top: auto; }
.canale-eta .metro-leg { margin-top: var(--sp-1); }

/* Un canale previsto è spento, non nascosto, e non porta nessuna cifra. */
.canale-previsto {
  background: var(--panel);
  box-shadow: inset 0 0 0 1px var(--line);
}
.canale-previsto .canale-nome strong { color: var(--muted); }
.canale-previsto .canale-segno { background: var(--paper); color: var(--ink-2); }
.canale-manca {
  margin: 0; font-size: 13.5px; color: var(--ink-2);
  line-height: 1.5;
}
.canale-manca b { color: var(--ink); font-weight: 600; }


/* IL TERZO STATO DI META, e l'unico posto della pagina in cui il giallo
   significa qualcosa: una delle due superfici risponde e l'altra no. Non e'
   «collegato» — meta' dei canali non pubblicherebbe — e non e' «non
   configurato», perche' l'autorizzazione c'e'. E' un collegamento parziale, e
   la parola esiste per quello. */


.canale-parziale { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 35%, transparent); }
.canale-parziale .canale-segno { color: var(--warn); }


/* Lo stato non è mai solo un colore: la forma del segno cambia con lui. */


/* ================== 23 · LA PRESSIONE — reagire al tocco =================
   Ogni cosa premibile scala sulla PRESSIONE, non sul rilascio. Aspettare il
   click per dare un segnale fa sembrare morta l'interfaccia: il segnale deve
   arrivare nell'istante in cui il dito preme, e 120 ms sono già il massimo che
   si può far aspettare.
   ========================================================================= */
.sez,
.canale-azione,
.terr-cella {
  transition: background-color var(--t-stato) var(--ease-out),
              border-color var(--t-stato) var(--ease-out),
              color var(--t-stato) var(--ease-out),
              transform var(--t-pressione) var(--ease-out),
              filter var(--t-stato) var(--ease-out);
}
.canale-azione:active { transform: scale(.97); }


/* Le superfici del browser che nessuno disegna e che appartengono comunque al
   prodotto: la selezione e il cursore di testo. Lasciarle al browser è il
   modo più economico di sembrare assemblati invece che costruiti. */

:root { caret-color: var(--ink); }
/* Ogni cifra di questo strumento sta in colonna con le altre: le cifre
   proporzionali fanno ballare i totali di una tabella riga per riga. */
table, .metro-leg, .canale-mis, .piano-misure { font-variant-numeric: tabular-nums; }

/* --- le prove: da dove parte una lettura --------------------------------
   Il blocco di Luna dichiarava già di essere un'interpretazione. Non
   dichiarava da DOVE parte, e senza quello «interpretazione» resta una
   parola: chi legge non ha modo di risalire alla cifra e verificarla.

   La striscia sta PRIMA del testo, non dopo. Un'interpretazione si legge
   sapendo su che cosa poggia; scoprirlo alla fine significa averla già
   creduta. Ogni voce porta alla misura deterministica da cui il modello è
   partito, e le voci sono scritte nel compito (`ai/compiti.py`), non
   indovinate dal modello. */
.ai-prove {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  border-bottom: 1px solid var(--ai-line);
  background: var(--ai-dim);
}
.ai-prove-l {
  font-size: var(--fs-1); font-weight: 600; color: var(--muted);
  margin-right: var(--sp-1);
}
/* Le prove NON portano il viola: sono le misure deterministiche, e il viola in
   questa applicazione vuol dire «detto da un modello». Colorarle di viola
   direbbe il contrario esatto di ciò che sono. */
.ai-prova {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px var(--sp-3);
  font-size: var(--fs-1); font-weight: 550;
  color: var(--text); text-decoration: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  transition: border-color var(--t-stato) var(--ease-out),
              background-color var(--t-stato) var(--ease-out),
              transform var(--t-pressione) var(--ease-out);
}
.ai-prova::after { content: "→"; color: var(--dim); }
.ai-prova:hover { background: var(--surface-3); border-color: var(--border-strong); }
.ai-prova:active { transform: scale(.97); }

/* ============ 30 · LA PLANCIA — la superficie di controllo ================
   Portafoglio e Qualità dati non sono più due documenti lunghi: sono due
   PLANCE. Tutto il paesaggio analitico sta in uno schermo, e si decide a
   occhio dove andare invece di scorrere trentamila pixel cercando la sezione
   giusta.

   Tre regole la governano, e sono le stesse del resto dello strumento.

   1 · **La gerarchia è la DIMENSIONE, non il colore.** I moduli non hanno
       ognuno il suo fondo acceso: hanno una terra sola e quieta, e ciò che
       conta è grande. Dodici rettangoli identici non hanno una gerarchia —
       è lo stesso difetto delle nove cifre in fascia, spostato su due assi.

   2 · **Il modulo dichiara il suo stato, non lo riassume.** Ognuno porta la
       cifra da cui si capisce subito come sta: un metro, una curva minima,
       una classifica corta, un conteggio con il suo esito. Chi guarda deve
       poter decidere di NON aprirlo.

   3 · **La profondità sta dietro, non sotto.** L'analisi completa — le stesse
       tabelle, gli stessi grafici, le stesse chiose — vive nella lastra, che
       si apre sopra il contesto che ha fatto scegliere quel modulo. È la
       regola di interazione già scritta in DESIGN.md, applicata a una
       superficie intera invece che a una cella.

   Perché lo scorrimento non può tornare: `main` è alto quanto lo schermo e
   `overflow: hidden`. Non è una precauzione, è il contratto della plancia —
   se un modulo cresce oltre il suo riquadro, si taglia il contenuto del
   modulo, non la promessa della pagina. */


/* Il Portafoglio avvolge il suo corpo in `#periodo-contenuto` — è il blocco
   che il selettore di periodo scambia senza ricaricare la pagina. In una
   colonna flessibile quel contenitore è un anello della catena: se non cresce
   e non si stringe insieme agli altri, la plancia dentro di lui torna alta
   quanto il suo contenuto e sfonda lo schermo dal basso. La catena va tenuta
   intera fino alla griglia. */


/* La testata di una plancia è più bassa di quella di un documento: ogni pixel
   che si prende è un pixel tolto alle forme. Il titolo scende di un gradino e
   il filo sotto sparisce — la plancia comincia da sé. */


/* ------------------------------------------------------------- la griglia --
   Dodici colonne per sei righe, e le righe sono FRAZIONI: la plancia si
   adatta all'altezza della finestra invece di pretenderne una. Un modulo
   occupa da 3×1 a 5×3 — la varietà è il punto, non un effetto. */


/* Il Portafoglio fa eccezione, e solo lui. Là le proporzioni disuguali
   servivano a una plancia la cui fascia bassa ospitava riquadri alti una
   cifra; ora le colonne portano blocchi di tre, due e sei righe, e una riga
   che vale meno delle altre sbilancerebbe proprio la colonna che ne usa sei.
   Qualità dati ha ancora la composizione per cui quelle proporzioni erano
   giuste, e se le tiene. */
/* Ventiquattro colonne e non dodici, e non è un vezzo: con dodici, spostare
   un confine fra due colonne costava una colonna intera — la centrale perdeva
   un quarto della sua larghezza per darne un terzo alla destra. A ventiquattro
   il passo è mezzo, ed è la misura giusta: la colonna della visibilità, che
   porta due grafici, prende quel mezzo passo e la centrale lo cede. */


/* ---------------------------------------------------------------------------
   IL SOMMARIO — i dati principali, in una riga

   Non è un modulo: sta sopra la plancia, non si scambia di posto, non ha un
   riquadro. È la testata dei numeri, e ha un solo compito — dire come sta il
   portafoglio prima che l'occhio arrivi alle forme.

   Niente cornice attorno a ogni cifra: quattro riquadri in fila avrebbero
   ripetuto quattro volte lo stesso bordo per separare cose che si separano già
   da sole. Bastano un filo verticale e lo spazio.
--------------------------------------------------------------------------- */


/* L'unico momento d'accento della riga, sulla cifra da cui discendono tutte
   le altre. Due accenti in una riga di quattro non sono una gerarchia. */


/* Sotto una certa larghezza quattro cifre in riga diventano quattro cifre
   tagliate. Meglio due righe da due che una riga illeggibile. */


/* ---------------------------------------------------------------------------
   LA CIAMBELLA — la composizione come parti di un intero
--------------------------------------------------------------------------- */
.mod-corpo .cia {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin: 0;
}

.cia-disco {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  /* Il buco è una maschera, non un cerchio di fondo sovrapposto: sopra un
     pannello con un gradiente, un cerchio « del colore dello sfondo » è del
     colore sbagliato quasi ovunque. Sta QUI, sul contenitore, e non si muove
     mai: la lancetta che scopre lavora sul disco dentro (§38.4). */
  -webkit-mask: radial-gradient(circle, transparent 53%, #000 53.5%);
  mask: radial-gradient(circle, transparent 53%, #000 53.5%);
  /* Il ridisegno della lancetta non esce da questo rettangolo. */
  contain: paint;
}
/* Il disco vero: porta il `conic-gradient` delle fette e nient'altro. */
.cia-torta { position: absolute; inset: 0; border-radius: 50%; display: block; }
.cia-mezzo {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1.05;
  pointer-events: none;
}
.cia-mezzo b {
  font-size: var(--fs-6);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.cia-mezzo em { font-size: var(--fs-1); color: var(--muted); font-style: normal; }

.cia-anello {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  /* Il lato lo detta la dimensione più stretta fra le due, e resta un CERCHIO.
     Con `height: 100%` più un tetto sulla larghezza il disco si schiaccia in
     un'ellisse, e in un anello la deformazione non è estetica: l'occhio legge
     l'ampiezza delle fette, e su un'ellisse la stessa ampiezza cambia area a
     seconda di dove cade.

     Il tetto serve comunque: in un modulo alto il cerchio crescerebbe fino a
     lasciare alla legenda una colonna di quaranta pixel, i nomi delle famiglie
     sparirebbero e resterebbe una fila di numeri senza soggetto — cioè
     l'anello smetterebbe di dire di che cosa è fatto il portafoglio, che è la
     sua unica domanda. */
  height: min(100%, 52cqw);
  aspect-ratio: 1;
}

.cia-leg {
  flex: 1 1 auto;
  min-width: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
}
.cia-leg li {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-size: var(--fs-2);
  line-height: 1.25;
}
.cia-leg i {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 2px;
  align-self: center;
}
.cia-n {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
}
.cia-n em { font-style: normal; opacity: .7; }
.cia-v { flex: 0 0 auto; font-variant-numeric: tabular-nums; font-weight: 600; }

/* Stretto, l'anello e la legenda non stanno affiancati: si impilano. */
@container (max-width: 300px) {
  .mod-corpo .cia { flex-direction: column; gap: var(--sp-2); }
  .cia-anello { height: auto; width: 58%; }
}

/* ---------------------------------------------------------------------------
   LE SEZIONI DENTRO UN MODULO

   Un modulo che ospita due analisi non le impila e basta: le nomina. Senza il
   titolino, «Concentrazione» e «Visibilità e resa» diventerebbero un elenco di
   cifre senza padrone, che è esattamente il difetto che la fusione doveva
   togliere.
--------------------------------------------------------------------------- */

/* La sezione che porta una forma si prende l'altezza che avanza. Senza questa
   riga la tela nasce alta zero — un contenitore flex non regala altezza a un
   figlio che non la chiede — e il grafico semplicemente non compare, lasciando
   in fondo alla colonna un vuoto che sembra un errore di composizione. */


/* Dentro una sezione la cifra scende di un gradino: due cifre grandi nello
   stesso riquadro si contendono la stessa attenzione e non la vince nessuna. */

/* La didascalia della cifra sta sotto, non di fianco: accanto, nelle colonne
   strette, andava a capo da sola e l'ultima parola sembrava caduta lì. */


/* Le due cifre del movimento nella riga di chiusura. */


/* --------------------------------------------------------------- il modulo -
   Una terra sola, appena sollevata dal fondo, con il filo caldo in cima: è la
   regola della §24 — la luce viene dall'alto — applicata a un riquadro che si
   può premere. I moduli dominanti salgono di UN gradino di superficie, non di
   più: se ogni modulo urla, nessuno guida. */


/* Il modulo che si apre è un comando, e un comando reagisce alla PRESSIONE.
   Il sollevamento è di un pixel: su un riquadro largo mezzo schermo una scala
   percettibile sembrerebbe un difetto di rendering, non una risposta. */


/* La testata del modulo: il nome a sinistra, lo stato a destra. L'etichetta
   maiuscola NON torna qui — è razionata a due posti in tutto lo strumento, e
   dodici occhielli sulla stessa schermata sarebbero il segnale più forte di
   «cruscotto generico» che questa plancia possa dare. */


/* In un modulo stretto lo stato e il nome si contendono la stessa riga, e
   perde sempre il nome — che è la cosa su cui si decide se aprire. Sotto una
   certa larghezza lo stato si toglie: la cifra che porta è comunque nel corpo
   del modulo. Si misura il MODULO, non la finestra: lo stesso modulo può
   essere largo o stretto a seconda di dove il titolare l'ha messo. */


/* Il segno «si apre»: sta fermo e spento finché il puntatore non arriva. Un
   segno sempre acceso su dodici moduli è dodici volte lo stesso rumore. */


/* Il ritmo verticale dentro un modulo lo dà il `gap`, uno solo. I componenti
   che arrivano dalla pagina lunga portano con sé i margini che avevano là —
   sedici pixel sopra e sotto ciascuno — e in un riquadro alto centosessanta
   pixel tre di quei margini valgono più del contenuto. Si azzerano qui, una
   volta, invece di rincorrerli componente per componente. */


/* La cifra guida di un modulo. La scala segue il peso: un modulo compatto con
   la cifra di uno dominante mente sulla propria importanza. */


/* L'accento ha diritto a UN momento per schermata: lo porta il modulo marcato
   `guida`, e nessun altro. */


/* La fascia in fondo alla plancia porta STATI, non prosa: una cifra e una
   riga. Il corpo di quei moduli è alto ottanta pixel su uno schermo da 1280,
   e a corpo pieno la seconda riga finiva tagliata a metà parola — che è il
   modo peggiore di scrivere una frase, perché una frase troncata non dice
   una cosa a metà: ne dice un'altra. Il testo scende di un gradino e ci sta
   intero. La lettura distesa è nella lastra. */


/* Una classifica dentro un modulo: righe corte, cifra a destra, quota
   disegnata dentro la riga. Nessuna tabella — l'intestazione di una tabella
   di tre righe costa più di quanto renda. */
/* La classifica NON si stringe. In una colonna flessibile un elenco con
   `min-height: 0` è la prima cosa che il motore sacrifica quando lo spazio non
   basta: si riduce a dieci pixel e sparisce senza dire niente, lasciando un
   vuoto che sembra un modulo senza dati. Se non ci sta, si mostrano meno
   righe — deciso nel template, dove si sa quante sono. */


/* La quota è disegnata DENTRO la riga che la riporta: la cifra resta esatta e
   dieci righe diventano confrontabili senza spendere una colonna. */


/* La tela dentro un modulo. Prende lo spazio che avanza, mai una misura fissa:
   una tela con un'altezza in pixel dentro una riga in frazioni o sborda o
   lascia un vuoto, e su sei righe l'errore si moltiplica. */


/* Le forme composte dal server dentro un modulo: si stringono, non si
   riscrivono. La geometria resta quella di `forme.py` — una seconda geometria
   per lo schermo piccolo sarebbe un secondo portafoglio.

   Sul territorio la stretta arriva fino a togliere le CIFRE dalle celle, ed è
   la stessa decisione già presa per lo schermo stretto: una cella alta quindici
   pixel non tiene «21» senza tagliarlo a «2», che è un altro numero. Il modulo
   porta la FORMA del territorio — quale valle pesa quanto, e quanto risponde —
   e le cifre stanno nella lastra, dove c'è lo spazio per leggerle intere.
   Meglio nessuna cifra che una cifra sbagliata. */


/* La scala dei contatti per annuncio accompagna le cifre: senza cifre non ha
   nessuno da accompagnare, e in un modulo costerebbe una fascia intera. */

/* `safe center`: una forma più alta del suo riquadro parte dall'alto e scorre
   dentro di lui, invece di perdere la testa e la coda tagliate a metà (il
   Territorio perdeva le prime due zone e la scala in fondo). */
.mod-forma { flex: 1 1 auto; min-height: 0; overflow: auto; scrollbar-width: thin; display: flex; flex-direction: column;
  justify-content: safe center; }
.mod-forma > * { margin: 0; }

/* Le due firme si adattano all'ALTEZZA del modulo, e questo è un requisito di
   onestà prima che di estetica: il titolare può spostare il territorio in una
   casella piccola, e un territorio che perde quattro valli senza dirlo è
   peggio di un territorio piccolo.

   Sul territorio si comprime la FASCIA, mai la geometria: le larghezze e le
   campiture restano quelle che `forme.territorio` ha calcolato, cambia lo
   spessore della banda. Dieci valli restano dieci valli. */


/* Sul treemap si può solo RIMPICCIOLIRE mantenendo il rapporto: quel rapporto
   è quello con cui i rettangoli sono stati calcolati, e deformarlo farebbe
   smettere all'area di essere la quantità che dichiara di essere. Il piano si
   incolonna al centro e lascia margine ai lati, invece di sfondare in basso. */
/* Il divario dentro un modulo perde la legenda e stringe le righe. La legenda
   spiega che cosa sono i due punti — informazione vera, e per questo sta nella
   lastra insieme alla frase che legge lo squilibrio. In un modulo costava
   novantasette pixel su centottantacinque: più della metà dello spazio a
   spiegare la forma invece che a mostrarla. */
.mod-corpo .dv-legenda { display: none; }
/* Anche i riferimenti della scala escono dalla faccia del modulo. A questa
   larghezza cinque etichette in una pista di duecento pixel si sovrappongono
   in un grumo — «0%20%40%» — che non si legge e non si può leggere: è rumore
   messo lì dalla convinzione che un asse serva sempre. Qui non serve: la
   domanda è quale fascia rende meno di quanto pesa, e la risposta è la
   LUNGHEZZA del segmento, che si vede senza asse. La scala con le sue cifre
   resta nel dettaglio, dove la pista è larga il triplo. */
.mod-corpo .dv-scala { display: none; }
.mod-corpo .dv-testa { font-size: var(--fs-0); }
/* Le righe si dividono lo spazio che resta invece di pretendere la loro
   altezza naturale: sei fasce di prezzo restano sei, comunque sia alto il
   modulo in cui il titolare le ha messe. */
.mod-corpo .dv { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.mod-corpo .dv-riga {
  flex: 1 1 0;
  min-height: 0;
  /* Il corpo scende di un gradino: a quindici pixel la riga non poteva
     stringersi sotto i ventidue del suo contenuto, e sei righe sfondavano il
     modulo di cinque pixel su uno schermo da 1280. */
  font-size: var(--fs-2);
  padding: 1px 0;
}
.mod-corpo .dv-testa { padding: 0 0 var(--sp-1); }
/* La pista segue l'altezza della riga invece di imporne ventidue. Dentro un
   modulo le righe si dividono lo spazio che c'è; una pista a misura fissa,
   dentro una riga più bassa di lei, non si stringe — sborda, e il modulo la
   taglia. Sono i punti sull'ultima fascia di prezzo che sparivano sotto il
   bordo, e sparivano in silenzio: la riga c'era, il suo contenuto no. */
.mod-corpo .dv-pista { height: 100%; min-height: 11px; }
.mod-corpo .dv-p { width: 8px; height: 8px; margin-left: -4px; }
/* La riga è una griglia, e una griglia si misura sul figlio più alto: senza
   togliere l'interlinea al nome e al valore, sei fasce chiedono centoventisei
   pixel dove ce ne sono novantatré, e le ultime due escono dal riquadro. */
.mod-corpo .dv-riga { line-height: 1.1; align-items: center; }
.mod-corpo .dv-riga > * { min-height: 0; }

.mod-corpo .tm { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.mod-corpo .tm-piano {
  flex: 1 1 auto;
  min-height: 0;
  /* Con `aspect-ratio: 100/62` già dichiarato, basta liberare la larghezza:
     l'altezza la decide la colonna flessibile e la larghezza la deriva il
     rapporto. `max-width: 100%` fa da tetto quando il modulo è più basso che
     largo, e allora è l'altezza a seguire. In nessuno dei due casi il rapporto
     cambia — cioè in nessuno dei due l'area smette di essere la quantità. */
  width: auto;
  max-width: 100%;
  margin: 0 auto;
}

/* Lo stato di un modulo, quando è uno stato e non una quantità: la parola c'è
   sempre, il colore non è mai da solo. */
.mod-esito {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--fs-1); font-weight: 600;
  padding: 2px 8px; border-radius: var(--r-pill);
  border: 1px solid transparent;
}
.mod-esito::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.mod-esito.ok   { color: var(--ok-t);   background: var(--ok-soft);   border-color: var(--ok-line); }
.mod-esito.warn { color: var(--warn-t); background: var(--warn-soft); border-color: var(--warn-line); }
.mod-esito.bad  { color: var(--err-t);  background: var(--bad-soft);  border-color: var(--bad-line); }
.mod-esito.info { color: var(--info); background: var(--info-soft); border-color: var(--info-line); }

/* Un modulo che porta un allarme si distingue per il BORDO, non per il fondo:
   un fondo rosso dietro una cifra rende la cifra meno leggibile proprio dove
   serve leggerla. */
.mod[data-tono="bad"]  { border-color: var(--bad-line); }
.mod[data-tono="warn"] { border-color: var(--warn-line); }

/* Il modulo vuoto dichiara PERCHÉ è vuoto. Uno zero al posto di un dato
   assente è la bugia più facile di questo strumento. */
.mod-vuoto {
  flex: 1 1 auto;
  display: grid; place-content: center; text-align: center;
  font-size: var(--fs-2); color: var(--dim);
  padding: var(--sp-3); max-width: 34ch; margin: 0 auto;
}

/* -------------------------------------------------- modifica disposizione --
   Un modulo non si trascina per sbaglio: la plancia si usa molte volte al
   giorno e un riquadro che si stacca a ogni pressione lunga sarebbe un
   difetto, non una funzione. Si entra in modifica da un comando, e allora —
   solo allora — i moduli diventano afferrabili. */
.plancia-comandi { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }

body.plancia-modifica .mod {
  cursor: grab;
  border-style: dashed;
  border-color: var(--border-strong);
}
body.plancia-modifica .mod::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  background: color-mix(in srgb, var(--data) 4%, transparent);
  pointer-events: none;
}
body.plancia-modifica .mod-apri { display: none; }
body.plancia-modifica .mod:active { cursor: grabbing; }

/* Il modulo scelto aspetta il suo scambio: da tastiera si preme il primo, poi
   il secondo. È la stessa operazione del trascinamento, senza il puntatore. */
.mod[data-scelto] {
  border-style: solid;
  border-color: var(--data);
  box-shadow: 0 0 0 1px var(--data) inset;
}
.mod[data-scelto]::after { background: var(--accent-dim); }

.mod[data-trascina] { opacity: 0.5; }
.mod[data-bersaglio] {
  border-style: solid;
  border-color: var(--data);
}
.mod[data-bersaglio]::after { background: var(--accent-soft); }

/* La presa compare solo in modifica, e sta in ALTO A DESTRA — nel posto che il
   segno «si apre» lascia libero, visto che in modifica non si apre niente.
   Stava a sinistra, e copriva la prima lettera di ogni titolo: dodici moduli
   che si chiamavano «l portafoglio, ora» e «oerenza e provenienza». Un
   affordance che nasconde il nome della cosa che si sta per spostare è un
   affordance che lavora contro di sé. */
.mod-presa {
  position: absolute; top: var(--sp-3); right: var(--sp-3);
  display: none; align-items: center; justify-content: center;
  padding: 3px 4px; border-radius: var(--r-1);
  background: var(--surface-3); border: 1px solid var(--border-strong);
  color: var(--muted);
  pointer-events: none;
}
.mod-presa svg { width: 9px; height: 13px; display: block; }
body.plancia-modifica .mod-presa { display: inline-flex; }
/* Lo stato del modulo cede il posto alla presa mentre si sposta. */
body.plancia-modifica .mod-testa .mod-stato { visibility: hidden; }
.mod[aria-expanded="true"] { box-shadow: 0 0 0 1.5px var(--ink); }

/* --------------------------------------------------------- la lastra larga -
   La lastra del territorio porta sei righe di una cella: entra in 420 px. Un
   modulo intero porta la sua analisi completa — tabelle a nove colonne, il
   grafico a piena scala, le chiose — e in 420 px quelle tabelle si
   spezzerebbero parola per parola. La lastra si allarga quando è un modulo ad
   aprirla, e resta una lastra: entra di lato, sopra il contesto, e lo lascia
   dov'era. */
.lastra.lastra-larga { width: min(1280px, 84vw); }
.lastra.lastra-larga .lastra-corpo { padding-right: var(--sp-5); }

/* Dentro la lastra le sezioni tornano a essere quello che erano: la pagina
   lunga non è sparita, è passata dietro il modulo che la riguarda. */
.lastra-corpo .card,
.lastra-corpo .piano {
  border: 0; background: none; padding: 0; margin: 0 0 var(--sp-6); box-shadow: none;
  /* E senza superficie non c'è più niente da arrotondare né da ritagliare: il
     raggio qui era invisibile e il ritaglio no — tagliava un arco su ogni
     angolo del contenuto, e con imbottitura zero l'arco cadeva sul testo. */
  border-radius: 0;
  overflow: visible;
}
.lastra-corpo .card:last-child, .lastra-corpo .piano:last-child { margin-bottom: 0; }
.lastra-corpo .chart-box { height: 320px; }
.lastra-corpo .chart-box.grande { height: 380px; }
.lastra-corpo .grid-2 { grid-template-columns: 1fr 1fr; }
/* Dentro la lastra le spiegazioni didattiche TORNANO: là fuori sono rumore su
   una plancia densa, qui sono esattamente ciò che si è venuti a leggere. */
.lastra-corpo .forma-perche,
.lastra-corpo .chiosa,
.lastra-corpo .piano-q,
.lastra-corpo .card > h2 + p.muted.small,
.lastra-corpo section > h2 + p.muted.small { display: block; }
.lastra-corpo h2 { font-size: var(--fs-5); margin: 0 0 var(--sp-2); }
.lastra-corpo h3 { font-size: var(--fs-4); }

/* ------------------------------------------------------------ ripiego ------
   Sotto i 1180 px la plancia non è più una plancia: dodici colonne su sei
   righe darebbero moduli alti quaranta pixel, cioè dodici riquadri illeggibili
   invece di una superficie di controllo. Si torna a una colonna che scorre —
   il contenuto è lo stesso, la promessa del singolo schermo no. Meglio
   dichiararlo che consegnare una griglia che non si legge. */
@media (max-width: 1180px), (max-height: 620px) {
  
  
  
  
  
  .plancia-comandi { display: none; }
}


/* ============ 31 · IL PANNELLO E LE NUOVE FORME ===========================
   Il dettaglio smette di essere un cassetto a destra e diventa un pannello al
   centro. Non è una preferenza di stile: un cassetto laterale sposta la
   lettura su un bordo dello schermo e lascia due terzi di pagina inerti a
   fianco, e quando il contenuto è un'analisi intera — due torte, una tabella
   da dieci righe, un grafico a piena larghezza — quel formato lo strozza.

   Il pannello resta SOPRA la plancia, non al posto suo: si vede ancora che
   cosa c'è sotto, perché il contesto di una analisi è la plancia da cui è
   uscita.
--------------------------------------------------------------------------- */


/* Senza JavaScript, o con il movimento ridotto, resta una comparsa semplice:
   niente scalata, niente origine. Il pannello c'è, e basta. */


/* Il contenuto entra dopo la scalata, non insieme: durante la crescita non
   c'è niente da deformare, e quando il pannello è a misura il contenuto è
   già a fuoco. */


/* --------------------------------------------------------------- LA TORTA */
.torte {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--sp-6);
  margin-bottom: var(--sp-6);
}
.ta { margin: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
.ta-t {
  font-size: var(--fs-2);
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--muted);
}
.ta-disco {
  width: min(300px, 100%);
  aspect-ratio: 1;
  border-radius: 50%;
  align-self: center;
  /* Piena, non ad anello: qui la domanda è quanto pesa una parte, e su una
     superficie intera due parti si confrontano meglio che su due archi. */
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--border-strong) 70%, transparent),
              0 10px 30px -14px rgba(0, 0, 0, .8);
}
.ta-leg { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.ta-leg li {
  display: grid;
  grid-template-columns: 10px 1fr auto auto;
  align-items: baseline;
  gap: 9px;
  font-size: var(--fs-3);
  padding: 3px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
}
.ta-leg li:last-child { border-bottom: 0; }
.ta-leg i { width: 10px; height: 10px; border-radius: 2px; align-self: center; }
.ta-n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ta-n em { font-style: normal; color: var(--muted); }
.ta-v { font-variant-numeric: tabular-nums; font-weight: 600; }
.ta-q { font-variant-numeric: tabular-nums; color: var(--muted); font-size: var(--fs-2); min-width: 42px; text-align: right; }
.ta-nota { margin: 0; font-size: var(--fs-2); color: var(--muted); }

/* ------------------------------------------------------- LA DISTRIBUZIONE */
.ds { display: flex; flex-direction: column; gap: 2px; }
/* Dentro un modulo le bande si dividono l'altezza che c'e', invece di
   pretendere ciascuna la propria: senza questo, su uno schermo basso le
   ultime due uscivano dal riquadro e `overflow:hidden` le tagliava via in
   silenzio — cinque bande ne diventavano tre, e una distribuzione a cui
   mancano le code non e' una distribuzione, e' un errore che sembra un
   grafico. */
.mod-corpo .ds { flex: 1 1 auto; min-height: 0; gap: 1px; }
.mod-corpo .ds-riga { flex: 1 1 0; min-height: 0; align-items: center; }
.mod-corpo .ds-pista { height: 7px; }
/* Le date delle sorgenti non vanno a capo: «2026-07-» e «26» su due righe
   sono due cose, e sono una data. */
.fo-d { white-space: nowrap; }
.fo-n { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ds-riga {
  display: grid;
  grid-template-columns: minmax(66px, auto) 1fr auto auto;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-2);
  line-height: 1.15;
}
.ds-n { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ds-pista {
  position: relative;
  height: 9px;
  min-width: 0;
  border-radius: 2px;
  background: color-mix(in srgb, var(--border) 60%, transparent);
}
.ds-pista i { position: absolute; inset: 0 auto 0 0; border-radius: 2px; background: var(--seq-3); }
.ds-v { font-variant-numeric: tabular-nums; font-weight: 600; }
.ds-q { font-variant-numeric: tabular-nums; color: var(--muted); min-width: 32px; text-align: right; }
/* La banda in cui cade la media: marcata, perché la cifra grande sopra e la
   sua posizione nella distribuzione sono la stessa informazione detta due
   volte, e vederle collegate costa una tinta. */
.ds-qui .ds-n { color: var(--text); font-weight: 600; }
.ds-qui .ds-pista i { background: var(--data); }
.ds-qui .ds-v { color: var(--pri-ink); }

/* --------------------------------------------------------- I RIFERIMENTI */
.rf { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.rf li {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: baseline;
  gap: 7px;
  font-size: var(--fs-2);
  padding: 2px 0;
}
.rf-r { font-family: var(--font-mono); letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rf-v { font-variant-numeric: tabular-nums; font-weight: 600; }
.rf-u { color: var(--muted); font-size: var(--fs-1); }

/* ------------------------------------------------ NOTE E FONTI NEL MODULO */
.nt-e { font-size: var(--fs-1); color: var(--muted); letter-spacing: .04em; text-transform: uppercase; }
.nt-v { font-size: var(--fs-2); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nt-s { font-size: var(--fs-1); color: var(--muted); font-variant-numeric: tabular-nums; }

/* Le due date su una riga sola: incolonnate erano due etichette e due valori
   su quattro righe, per dire una cosa che si dice in una. */
/* Una sorgente per riga, nome a sinistra e data a destra. Affiancate, in un
   riquadro largo un terzo di colonna, ognuna aveva novanta pixel per dire
   «Anagrafica 2026-07-26»: il nome finiva troncato a meta'. In colonna ci
   stanno tutte e due per intero e si leggono come quello che sono — due date
   da confrontare. */
.mod-fonti { display: flex; flex-direction: column; gap: 1px; flex: 0 0 auto; font-size: var(--fs-2); }
.mod-fonti > div { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); min-width: 0; }
.fo-n { font-size: var(--fs-1); color: var(--muted); letter-spacing: .04em; text-transform: uppercase; }
.fo-d { font-size: var(--fs-2); font-variant-numeric: tabular-nums; }

.mod-piede {
  margin: auto 0 0;
  padding-top: var(--sp-2);
  border-top: 1px solid var(--border);
  font-size: var(--fs-2);
  color: var(--muted);
  flex: 0 0 auto;
}
.mod-piede strong { color: var(--text); font-variant-numeric: tabular-nums; }

/* -------------------------------------------- CIFRE AFFIANCATE NEL MODULO */


/* L'ETICHETTA STA ACCANTO ALLA CIFRA, NON SOTTO.
   Sotto, una cifra da quaranta pixel e la sua etichetta occupavano due righe
   e la seconda finiva addosso a quella della cifra accanto. Di fianco costano
   una riga sola, si allineano sulla base della cifra — che e' la linea su cui
   l'occhio le cerca — e restano separate perche' ognuna vive dentro la propria
   meta' della coppia. */


/* La cifra resta bianca, l'etichetta no. Grigia, la mediana sembrava una
   nota accanto alla media invece che la seconda meta' della stessa lettura —
   e le due dicono cose diverse: la distanza fra loro E' un'informazione. Il
   rango lo fa la MISURA, che e' gia' un gradino sotto; non serve anche il
   colore, che invece toglie la cifra dal discorso. */


/* Due classi, e la specificita' conta: `.mod-sez:has(.mod-tela)` vale piu' di
   `.mod-sez-stretta`, quindi la sezione con la curva tornava elastica e si
   lasciava schiacciare sotto l'altezza del suo contenuto — la striscia usciva
   dalla sezione e finiva sopra la classifica sotto. Qui si dichiara che questa
   sezione non si stringe, e lo si dichiara abbastanza forte da vincere. */


/* ------------------------------------------------------ I KPI DI DIREZIONE */
/* DUE E DUE, dichiarate. Erano `auto-fit` su una base di 420 px: l'intenzione
   era «due colonne», ma su uno schermo largo la base ci sta quattro volte e la
   griglia ne faceva quattro — cioe' tre gruppi in alto e il quarto da solo in
   basso, largo un quarto, con mezza riga vuota accanto. Un gruppo spaiato in
   fondo a una riga vuota sembra un avanzo, non una delle quattro domande.
   Due colonne fisse: due sopra, due sotto, e i quattro riempiono la larghezza
   e pesano uguale.

   Sotto gli 880 px la colonna diventa una sola: due gruppi affiancati su un
   telefono non sono due gruppi, sono otto cifre strizzate. */


/* Due colonne, e la capofila se le prende tutte e due. In fila con le altre
   una cifra come «37.853.000 €» non ci sta e va a capo dentro la sua colonna,
   finendo addosso alla vicina: il difetto non era la dimensione del carattere,
   era chiedere a tre cifre di larghezza molto diversa di stare in tre colonne
   uguali. Sopra la capofila, sotto le due che la spiegano: è anche l'ordine in
   cui si leggono. */

.kpi { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.kpi b {
  font-family: var(--font-mono);
  font-size: var(--fs-6);
  font-weight: 640;
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.kpi span { font-size: var(--fs-1); color: var(--muted); line-height: 1.25; }
/* La capofila del gruppo sta più grande: le altre due la spiegano, e una
   gerarchia dentro il gruppo è ciò che rende il gruppo leggibile in un colpo
   invece che in tre. */


/* --------------------------------------------- IL SOMMARIO È UN COMANDO */
.sommario[data-apre] { cursor: pointer; }
@media (hover: hover) and (pointer: fine) {
  .sommario[data-apre]:hover { border-color: var(--border-strong); }
  .sommario[data-apre]:hover .som-apri { color: var(--text); border-color: var(--border-strong); }
}
.sommario[data-apre]:active { transform: scale(0.997); }
.sommario[data-apre]:focus-visible { outline: 2px solid var(--pri-ink); outline-offset: 2px; }

/* --------------------------------------------------------------------------
   SCHERMI BASSI (1280×800 e simili)

   La plancia non scorre: quello che non entra va tolto, e va tolto scegliendo,
   non lasciando che sia il bordo a decidere. Si tolgono le cose che NON portano
   una cifra — la striscia della curva, che dice «è ripida» e nient'altro, e un
   po' di respiro fra le righe delle classifiche. Nessun numero sparisce dalla
   plancia, e la curva resta intera nel dettaglio.
-------------------------------------------------------------------------- */
@media (max-height: 880px) and (min-width: 1181px) and (min-height: 621px) {
  /* La striscia spariva del tutto: era la scelta giusta finché era una striscia
     alta trenta pixel che diceva soltanto «è ripida». Ora le due forme sono la
     cosa per cui il riquadro esiste, e sparire non è più una scelta possibile —
     si stringono, e la stanza gliela si trova togliendo aria, non dati.
     Il minimo scende, ma resta un disegno: le altre regole di questo blocco
     ricavano i pixel dalle didascalie e dai fili fra le sezioni. */
  
  .rf li { padding: 0; }
  .rf { gap: 0; }
  
  .mod-piede { padding-top: var(--sp-1); }
  .mod-fonti { gap: var(--sp-3); }
  
  /* Gli ultimi sei pixel di «Coerenza»: la pastiglia dell'esito ha un respiro
     che a questa altezza non ci sta, e stringerla non toglie niente da leggere. */
  .mod-esito { padding-top: 3px; padding-bottom: 3px; }

  /* ANZIANITÀ — cinque bande hanno bisogno di settanta pixel per restare
     LEGGIBILI, e farle entrare a dieci pixel l'una non e' averle mostrate:
     e' averle rese illeggibili pur di non ammettere che non ci stavano.
     Lo spazio si prende dove non costa una cifra — le due cifre scendono di
     un gradino e la loro didascalia torna in linea, e la frase di chiusura
     (i quartili) resta nel dettaglio, dov'e' scritta per esteso. */
  
  
  

  /* COERENZA — con il movimento tornato dentro, a questa altezza il riquadro
     non tiene tutto. Si sceglie: resta il confronto appaiato (due zone invece
     di tre) e restano le due cifre di entrata e uscita, perche' sono il
     movimento; escono le date delle sorgenti, che sono provenienza e stanno
     per intero nel dettaglio a un clic di distanza. */
  
  

  /* TIPOLOGIA — la colonna a destra (sei voci di legenda piu' le due letture
     di contesto) supera di una decina di pixel l'altezza del disco. Si stringe
     il respiro fra le due parti: nessuna voce sparisce. */
  /* LA COLONNA SI DISTRIBUISCE SULL'ALTEZZA DEL DISCO.
   Con `flex-start` la legenda e le tre letture si impilavano in alto e sotto
   restava un vuoto alto quanto un terzo del cerchio: due blocchi appesi al
   soffitto accanto a una forma centrata. Adesso la legenda sta in cima, le
   letture in fondo, e l'aria sta in mezzo — cioe' i due estremi della colonna
   coincidono con i due estremi del disco, che e' l'allineamento che si cerca
   guardandoli insieme. */
.cia-col { gap: var(--sp-2); justify-content: space-between; }
.cia-col .cia-extra { margin-top: 0; }
  .cia-extra { gap: 4px; padding-top: 4px; }
  .cia-leg li { padding: 1px 0; }
}

/* In un riquadro stretto le due sorgenti si impilano invece di troncarsi:
   «Anagrafi…» non e' un'etichetta piu' corta, e' un'etichetta rotta. */
@container (max-width: 390px) {
  .mod-corpo .mod-fonti { flex-direction: column; gap: 0; }
}

/* ---------------------------------------------------------------------------
   RITOCCHI DI DENSITÀ SUI RIQUADRI
--------------------------------------------------------------------------- */

/* La colonna a destra dell'anello: legenda in ALTO, e sotto le due letture di
   contesto, allineate con essa. Centrata verticalmente la legenda lasciava un
   vuoto sopra e uno sotto, e il contesto finiva a fondo riquadro come una
   didascalia staccata da quello che descrive. */
.cia-col {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: var(--sp-3);
}
.cia-col .cia-leg { flex: 0 0 auto; }
.cia-extra {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding-top: var(--sp-2);
  border-top: 1px solid var(--border);
}
.cia-extra > div { display: flex; flex-direction: column; gap: 0; min-width: 0; }

/* Con la terza lettura — quella che converte meglio — la colonna cresce di una
   sessantina di pixel e supera il disco: la prima voce della legenda finiva
   sotto la testata del riquadro, tagliata da `overflow: hidden` e senza dire
   niente. Si stringe il respiro, non si toglie una lettura: l'occhiello sta
   sulla stessa riga del nome invece che sopra, e le tre voci passano da tre
   righe l'una a due. */
/* Ogni lettura costa esattamente due righe: l'occhiello micro e, sotto, il
   nome con la sua cifra. Le altezze sono dichiarate invece che ereditate,
   perche' con tre letture al posto di due il conto non ha piu' margine —
   sei pixel di troppo per riga e la prima voce della legenda finisce sotto la
   testata del riquadro, tagliata e muta. */
/* LA COLONNA SI DISTRIBUISCE SULL'ALTEZZA DEL DISCO.
   Con `flex-start` la legenda e le tre letture si impilavano in alto e sotto
   restava un vuoto alto quanto un terzo del cerchio: due blocchi appesi al
   soffitto accanto a una forma centrata. Adesso la legenda sta in cima, le
   letture in fondo, e l'aria sta in mezzo — cioe' i due estremi della colonna
   coincidono con i due estremi del disco, che e' l'allineamento che si cerca
   guardandoli insieme. */
.cia-col { gap: var(--sp-2); justify-content: space-between; }
.cia-col .cia-extra { margin-top: 0; }
.cia-col .cia-leg li { padding: 0; line-height: 1.2; }
.cia-extra { gap: 5px; padding-top: 5px; }
.cia-extra > div { display: block; }
.cia-extra .nt-e {
  display: block;
  font-size: var(--fs-0);
  line-height: 1.15;
  letter-spacing: .05em;
  margin: 0;
}
.cia-extra .nt-v { display: inline; font-size: var(--fs-2); line-height: 1.25; }
.cia-extra .nt-s { display: inline; font-size: var(--fs-1); line-height: 1.25; }

/* Il movimento dentro il riquadro: piste sottili, nomi corti, nessuna
   legenda. Le date e la spiegazione del confronto appaiato stanno nel
   dettaglio, dove c'e' lo spazio per dirle per intero. */
.mod-forma-mv { flex: 1 1 auto; min-height: 0; }
.mod-corpo .mv { display: flex; flex-direction: column; gap: 1px; }
.mod-corpo .mv-riga {
  flex: 1 1 0;
  min-height: 0;
  align-items: center;
  font-size: var(--fs-1);
  line-height: 1.1;
}
.mod-corpo .mv-riga > * { min-height: 0; }
.mod-corpo .mv-pista { height: 100%; min-height: 9px; }
.mod-corpo .mv-p { width: 7px; height: 7px; margin-left: -3.5px; }
.mod-corpo .mv-nome em { display: none; }
.mod-corpo .mv .dv-legenda { display: none; }

/* La striscia deve vincere su `.mod-sez:has(.mod-tela) .mod-tela`, che le
   impone sessantaquattro pixel di minimo: e' la regola che serve alla tela
   grande della concentrazione, non a una striscia di supporto alta trenta.
   Stessa specificita' non basta — serve piu' alta, e sta piu' in basso. */


/* Le righe del movimento non scendono sotto la loro altezza leggibile. Con
   `flex: 1 1 0` e basta si dividevano lo spazio che c'era — otto pixel a
   testa — e i nomi delle zone finivano uno sull'altro: tre righe che non si
   possono leggere non sono tre righe. Se lo spazio non basta, deve mancare
   qualcos'altro, non la leggibilita' di questa. */
.mod-corpo .mv-riga { min-height: 13px; }
/* Lo spazio glielo danno le due date, che restano leggibilissime un gradino
   piu' piccole, e la pastiglia dell'esito, che aveva respiro da vendere. */
.mod-corpo .mod-fonti { font-size: var(--fs-1); line-height: 1.25; }


/* Le due sorgenti stanno affiancate finche' ci stanno, e quando non ci stanno
   si incolonnano invece di troncarsi. La misura era al pelo — «Anagrafica»
   piu' la sua data occupavano centocinquantadue pixel su centocinquantadue —
   e la colonna centrale, stretta di trenta pixel per far posto ai grafici
   della visibilita', l'ha superata: il nome finiva «ANAGRA…».
   Due correzioni, e la seconda e' quella che vale: il nome perde la spaziatura
   fra le lettere (in maiuscoletto costa cinque pixel e non aggiunge niente a
   una parola sola), e la riga puo' andare a capo. Un'etichetta troncata non e'
   un'etichetta piu' corta. */
.mod-corpo .mod-fonti { flex-direction: row; flex-wrap: wrap; gap: 2px var(--sp-3); }
.mod-corpo .mod-fonti > div { flex: 1 1 150px; justify-content: flex-start; gap: 5px; }
/* L'etichetta scende al corpo delle etichette micro — lo stesso di `.nt-e`,
   che fa questo mestiere in tutto il resto della plancia: e' una parola in
   maiuscoletto accanto a una data, e a 10,5 px si legge come a 12 e ci sta. */
.mod-corpo .mod-fonti .fo-n { letter-spacing: 0; font-size: var(--fs-0); }

/* Il contesto della tipologia in due righe per voce, non in tre: l'etichetta
   sopra, e sotto il nome con la sua cifra sulla stessa riga. Impilati su tre
   livelli i due blocchi chiedevano centotrenta pixel in una colonna che ne ha
   duecento in tutto, legenda compresa. */
.cia-extra > div { display: block; }
.cia-extra .nt-e { display: block; }
.cia-extra .nt-v { display: inline; }
.cia-extra .nt-s::before { content: " · "; color: var(--muted); }
.cia-extra .nt-s { display: inline; }

/* Queste devono stare DOPO le regole di base, o le perdono per ordine di
   cascata: e' gia' successo una volta in questo foglio. */
@media (max-height: 880px) and (min-width: 1181px) and (min-height: 621px) {
  /* LA COLONNA SI DISTRIBUISCE SULL'ALTEZZA DEL DISCO.
   Con `flex-start` la legenda e le tre letture si impilavano in alto e sotto
   restava un vuoto alto quanto un terzo del cerchio: due blocchi appesi al
   soffitto accanto a una forma centrata. Adesso la legenda sta in cima, le
   letture in fondo, e l'aria sta in mezzo — cioe' i due estremi della colonna
   coincidono con i due estremi del disco, che e' l'allineamento che si cerca
   guardandoli insieme. */
.cia-col { gap: var(--sp-2); justify-content: space-between; }
.cia-col .cia-extra { margin-top: 0; }
  .cia-extra { gap: 3px; padding-top: 4px; }
  .cia-leg li { padding: 1px 0; }
  .cia-leg { gap: 2px; }
}

@media (max-height: 880px) and (min-width: 1181px) and (min-height: 621px) {
  /* Le letture di contesto restano IMPILATE anche qui, e non e' un ritorno
     indietro: affiancate ci stavano finche' erano due: con la terza — quale
     famiglia rende di piu' — ognuna si riduceva a quarantasette pixel di
     colonna e diventavano tre parole spezzate. Impilate ci stanno, a patto di
     trovargli la larghezza: gliela da' il disco, che scende da 52 a 44 punti
     di colonna. Un anello piu' piccolo dice la stessa cosa; tre letture
     spezzate no. */
  .cia-anello { height: min(100%, 44cqw); }
  .cia-extra { flex-direction: column; gap: 2px; padding-top: 2px; }
  .cia-extra > div { flex: 0 0 auto; min-width: 0; }
  .cia-extra .nt-e { font-size: var(--fs-0); line-height: 1; }
  .cia-extra .nt-v, .cia-extra .nt-s { line-height: 1.15; }
  /* E il resto dei pixel dalla legenda: sei righe che cedono l'interlinea che
     avanza, non una riga che sparisce. */
  .cia-col { gap: 2px; }
  .cia-col .cia-leg { gap: 0; }
  .cia-col .cia-leg li { padding: 0; line-height: 1.15; }
}

/* --------------------------------------------------------- L'ISTOGRAMMA */
.ig {
  display: flex;
  align-items: stretch;
  /* Cinque pixel, non otto: a otto l'etichetta «366–730» restava corta di
     due pixel e finiva troncata — la colonna piu' alta della distribuzione
     senza il suo nome. */
  gap: 5px;
  flex: 1 1 auto;
  min-height: 0;
}
.ig-col {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.ig-v {
  flex: 0 0 auto;
  font-size: var(--fs-2);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.ig-pista {
  flex: 1 1 auto;
  min-height: 10px;
  width: 100%;
  display: flex;
  align-items: flex-end;
  border-radius: 2px;
  background: color-mix(in srgb, var(--border) 45%, transparent);
}
.ig-pista i {
  width: 100%;
  border-radius: 2px 2px 0 0;
  background: linear-gradient(180deg, var(--seq-4) 0%, var(--seq-3) 100%);
  min-height: 2px;
}
.ig-q {
  flex: 0 0 auto;
  font-size: var(--fs-1);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.ig-n {
  flex: 0 0 auto;
  font-size: var(--fs-1);
  color: var(--muted);
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
/* La banda in cui cade la media: la cifra e la colonna prendono l'accento,
   perche' la cifra grande sopra e la sua posizione qui sono la stessa cosa. */
.ig-qui .ig-v { color: var(--pri-ink); }
.ig-qui .ig-n { color: var(--text); font-weight: 600; }


/* ---------------------------------------------------------------------------
   L'ENFASI SULLE CIFRE DI DIREZIONE

   Sono le dieci misure piu' importanti dell'applicazione e stavano tutte allo
   stesso peso di grigio: strutturate bene, ma senza un ordine di lettura.
   L'accento arriva qui e solo qui — sulle quattro capofila, una per gruppo —
   perche' un accento che tocca tutto non e' un accento.

   La rampa e' quella del marchio (#F5BE69 → #D58A4C), presa dal chiaro verso
   il caldo: sul fondo scuro il ramo chiaro tiene il contrasto dove il ramo
   scuro lo perderebbe. L'alone e' un solo passaggio a bassa opacita': serve a
   staccare la cifra dal pannello, non ad accendersi.
--------------------------------------------------------------------------- */

/* Il filo d'accento in cima al gruppo: dice «questo e' un blocco» senza
   aggiungere una cornice. Sfuma ai bordi, o sarebbe una riga disegnata. */


/* Se il ritaglio del testo non e' supportato, resta il colore pieno: senza
   questa riga la cifra sarebbe trasparente su trasparente, cioe' invisibile. */


/* Le etichette scendono di tono: la gerarchia la fa anche il silenzio intorno. */


/* ===========================================================================
   §33 · QUALITÀ DATI — le eccezioni e la colonna della tassonomia

   Due componenti, e nascono dalla stessa constatazione: su questa plancia la
   cosa che si viene a controllare non è quasi mai UNA cifra. È un elenco —
   che cosa non torna, e in quanti modi — oppure un confronto riga per riga.

   `.ecc`  tre eccezioni nello stesso riquadro. Non sono tre cifre grandi in
           colonna: tre cifre grandi si contendono la stessa attenzione e non
           la vince nessuna. Il nome guida, la cifra sta a destra sulla stessa
           riga, e sotto una riga sola dice che cosa farne.

   `.tx`   il confronto fra le due tassonomie. È l'unico punto dello strumento
           in cui un'anteprima scorre dentro di sé, e c'è una ragione precisa:
           ventisei accoppiate non si riassumono in un numero senza perdere
           proprio ciò che si viene a verificare qui, e la plancia non scorre.
           La colonna alta quanto lo schermo se le porta tutte.
--------------------------------------------------------------------------- */

/* ---------------------------------------------------------- le eccezioni -- */
.ecc {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}
/* Le tre fasce si dividono l'altezza invece di impilarsi in cima: un blocco
   con due terzi di vuoto in fondo sembra un modulo a cui manca un pezzo.
   Ma partono da quello che chiedono (`auto`), non da zero: a parti uguali la
   fascia che ha due righe di testo ne perdeva mezza — e mezza riga tagliata
   non dice una cosa a metà, ne dice un'altra. L'avanzo si divide, il minimo
   no. */
.ecc-r {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr auto;
  align-content: center;
  column-gap: var(--sp-3);
  row-gap: 2px;
}
/* Il filo fra un'eccezione e l'altra costa nove pixel invece di diciassette:
   tre fasce in un riquadro alto centosettanta, e ogni pixel speso a separare
   è un pixel tolto alla riga che dice che cosa farne. */
.ecc-r + .ecc-r {
  margin-top: var(--sp-1);
  padding-top: var(--sp-1);
  border-top: 1px solid var(--border);
}
.ecc-n {
  font-size: var(--fs-2);
  font-weight: 600;
  color: var(--text);
  align-self: baseline;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ecc-v {
  grid-column: 2;
  grid-row: 1;
  align-self: baseline;
  font-family: var(--font-mono);
  /* Un gradino sotto la cifra di un modulo intero, e per la stessa ragione per
     cui le sezioni scendono: tre cifre della stessa taglia nello stesso
     riquadro si contendono l'attenzione e non la vince nessuna. */
  font-size: var(--fs-5);
  font-weight: 640;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
/* Il colore arriva solo quando l'eccezione esiste davvero: uno zero rosso è
   un allarme per una cosa che va bene. */
.ecc-r.t-bad  .ecc-v { color: var(--bad); }
.ecc-r.t-warn .ecc-v { color: var(--warn); }
.ecc-d {
  grid-column: 1 / -1;
  margin: 0;
  font-size: var(--fs-1);
  line-height: 1.35;
  color: var(--muted);
  /* Due righe, e la terza si taglia: la lettura distesa è nella lastra. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ecc-d strong { color: var(--text); font-weight: 620; }
.ecc-r.t-bad  .ecc-d strong { color: var(--bad); }
.ecc-r.t-warn .ecc-d strong { color: var(--warn); }
.ecc-d .mono { font-family: var(--font-mono); color: var(--text); }

/* ------------------------------------------------------- la tassonomia --- */
.tx-testa {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex: 0 0 auto;
}
.tx-conto {
  margin-left: auto;
  font-size: var(--fs-1);
  color: var(--dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* L'intestazione delle due colonne. Senza, la seconda etichetta di ogni riga
   sembra una precisazione della prima invece che l'altra sorgente. Sta fuori
   dallo scorrimento: un'intestazione che scorre via è un'intestazione che al
   momento del dubbio non c'è. */
.tx-cap,
.tx-r {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-2);
  align-items: baseline;
}
.tx-cap {
  flex: 0 0 auto;
  margin-top: var(--sp-2);
  padding-bottom: 4px;
  font-size: var(--fs-0);
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom: 1px solid var(--border-strong);
}

.tx-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
  /* Il filo in fondo separa l'elenco dalla chiosa senza aggiungere un bordo
     quando l'elenco è corto e non scorre. */
  border-bottom: 1px solid var(--border);
}
.tx { list-style: none; margin: 0; padding: 0; }
.tx-r {
  padding: 5px 0;
  font-size: var(--fs-1);
  line-height: 1.25;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
}
.tx-r:last-child { border-bottom: 0; }
.tx-n {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 620;
  color: var(--muted);
  text-align: right;
}
.tx-hb { color: var(--text); }
/* La classificazione del portale è il termine di paragone, non il canone: sta
   un gradino indietro nel colore, e il segno che la introduce lo dice. */
.tx-pt { color: var(--muted); position: relative; padding-left: 10px; }
.tx-pt::before {
  content: "";
  position: absolute;
  left: 0; top: .5em;
  width: 5px; height: 1px;
  background: var(--border-strong);
}
/* Una discordanza vera non è una generalizzazione: si vede senza leggere. */
.tx-r.tx-disc { background: color-mix(in srgb, var(--warn-soft) 60%, transparent); }
.tx-r.tx-disc .tx-n { color: var(--warn); }
.tx-r.tx-disc .tx-pt { color: var(--warn); }

.tx-piede { flex: 0 0 auto; padding-top: var(--sp-2); }

/* Sotto i 1180 px la plancia diventa una colonna sola: la tassonomia non ha
   più un'altezza da riempire e uno scorrimento dentro uno scorrimento è il
   modo più sicuro di perdere il dito. Si apre e si mostra intera. */
@media (max-width: 1180px) {
  .tx-scroll { max-height: 320px; }
}

/* Cinque esempi invece di tre. La riga dell'elenco cede un pixel sopra e uno
   sotto: la frase di chiusura — quella che dice PERCHÉ l'elenco esiste, e che
   Housebook non distingue il riservato dal dimenticato — non deve essere la
   cosa che si taglia per far posto al quinto esempio. */


/* --------------------------------------------------- schermi bassi -------
   Sotto gli 880 px di finestra la plancia di Qualità dati ha un centinaio di
   pixel in meno da dividere fra sei righe, e la prima cosa che il motore
   sacrifica non è la meno importante: è l'ultima riga di ogni elenco, tolta
   in silenzio. Qui si sceglie che cosa cede, e cede lo SPAZIO prima del
   CONTENUTO — l'aria attorno alle righe, il filo fra le sezioni, la
   precisazione che ha già il suo posto nel dettaglio. Nessuna riga di elenco
   sparisce, nessuna frase resta a metà parola.

   Il blocco sta in fondo al foglio perché deve vincere: una regola di trim
   scritta prima delle regole che corregge è una regola che non fa niente. */
@media (max-height: 880px) and (min-width: 1181px) and (min-height: 621px) {
  /* La precisazione sui pubblicati «solo più recenti» si toglie intera: è una
     nota di lettura, non un'eccezione, e sta nel dettaglio per esteso. */
  .ecc-piu { display: none; }
  .ecc-r + .ecc-r { margin-top: 3px; padding-top: 3px; }

  /* Le righe degli elenchi cedono l'aria, non l'ultima riga. */
  
  
  

  /* La cifra dello stock non pubblicato scende di un gradino: resta la più
     grande della colonna, e i cinque esempi sotto restano cinque. */
  

  /* Le frasi di chiusura scendono al corpo micro, quello che i moduli
     compatti usano già: la frase resta intera, che è l'unica cosa che conta —
     una frase troncata non dice una cosa a metà, ne dice un'altra. */
  
}

/* ===========================================================================
   §34 · LA TESTATA DELLA PANORAMICA — le quattro cifre di apertura

   Quattro riquadri, e sono la prima cosa che si vede aprendo lo strumento. Non
   sono schede come le altre e non devono sembrarlo: chi apre Quadra la mattina
   deve sapere come sta il portafoglio prima di aver deciso di leggere qualcosa.

   La gerarchia sta dentro il singolo riquadro, non fra i quattro. Etichetta
   piccola in alto (che cosa si sta guardando), cifra grande al centro (la
   risposta), riga di servizio sotto (che cosa ci manca o che cosa la limita).
   I quattro pesano uguale perché sono uno stesso imbuto: quanti sono, quanti
   si vedono, quanti rispondono, quanta domanda è arrivata. Dare l'accento a
   uno solo direbbe che gli altri tre sono contorno. Stanno in due e due
   accanto al quadrante — la griglia della fascia è nella §41, dove sta il
   quadrante che le tre quote le disegna.

   Il colore è quello del marchio e arriva sulla cifra, una volta per riquadro:
   la rampa calda con un alone largo e basso, come le cifre capofila del
   Portafoglio. Nessuna staffa agli angoli, nessun segno decorativo: la
   prominenza la fanno la scala della cifra, lo spazio attorno e il colore.
--------------------------------------------------------------------------- */


/* Il filo caldo sul bordo alto: è la stessa luce che hanno tutte le superfici
   portanti, accesa di un gradino perché qui la superficie è la prima. Non è un
   segno che indica: è il bordo del materiale. */


/* LA CIFRA È BIANCA, E L'ACCENTO STA TUTTO NEL QUADRANTE.
   Erano quattro cifre in rampa calda con un alone ciascuna, accanto a un
   quadrante che porta la stessa rampa sui suoi tre anelli: sette oggetti caldi
   in una fascia sola, e l'accento che tocca tutto smette di essere un accento.
   La direzione lo dice da sempre — «l'arancio è la scala, non la decorazione»
   — e qui la scala è il quadrante. Alle cifre resta la gerarchia che avevano
   già senza il colore: il corpo, il peso e lo spazio attorno. */


/* Sotto i 620 px la cifra scende di otto pixel: quarantasei in un riquadro
   largo quanto un telefono e' una cifra che tocca i due bordi. La griglia
   della fascia la decide la §41, dove la fascia e' definita. */


/* ---------------------------------------------- Report · lettura assistita -
   Titolo, comando e una riga che dice che cosa fa questa zona. Niente scheda
   attorno: un riquadro grande quanto la pagina per contenere tre elementi era
   un contenitore che conteneva soltanto se stesso. */
.lettura { margin: 0 0 calc(var(--sp-8) + var(--sp-4)); }
.lettura-testa {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  flex-wrap: wrap;
  padding-bottom: var(--sp-4);
}
/* Lo stesso filo di ogni altra testata: acceso sotto il titolo, spento verso
   destra. Senza scheda attorno è l'unica cosa che dice dove comincia la
   sezione — e senza di lui il titolo galleggia. */
.lettura-testa::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg,
              var(--line), var(--line));
}
.lettura-testa h2 {
  margin: 0;
  font-size: var(--fs-5);
}
.lettura-testa .ai-azione { margin-left: auto; }
.lettura-q {
  margin: var(--sp-4) 0 0;
  max-width: 82ch;
  font-size: var(--fs-3);
  line-height: 1.5;
  color: var(--muted);
}
.lettura #ai-report:not(:empty) { margin-top: var(--sp-5); }

/* ----------------------------------------- Report · i due campi in riga ----
   Il menu della finestra e il campo della nota stanno sulla stessa riga e
   devono avere la stessa altezza. Un `select` nativo si misura da solo — sul
   Mac si tiene due pixel in meno del campo di testo accanto — e due controlli
   affiancati alti diverso si leggono come un difetto di allineamento, non come
   due controlli diversi. L'altezza si dichiara, invece di sperarla. */
.gen-form .field > select,
.gen-form .field > input[type="text"] {
  height: 38px;
  padding-top: 0;
  padding-bottom: 0;
  line-height: 36px;
}
.gen-form .field > select { padding-right: var(--sp-2); }
/* E il bottone con loro: due pixel di scarto su tre elementi affiancati si
   vedono come un difetto di allineamento, non come tre controlli diversi. */
.gen-form > .btn { height: 38px; padding-top: 0; padding-bottom: 0; }
/* Senza la riga di aiuto sotto, il menu non ha più niente che lo tenga largo:
   una finestra di analisi scritta «Anno in corso (dal 1° gennaio)» non deve
   andare a capo dentro il proprio controllo. */
.gen-form .field:has(> select) { flex: 0 1 auto; min-width: 260px; }

/* ===========================================================================
   §35 · VISIBILITÀ — le due forme prendono l'altezza che avanza

   Il riquadro è alto quanto la plancia e le sue due forme erano due strisce da
   trentaquattro pixel. Trentaquattro pixel non sono un grafico: una cumulata
   che sale ripida e una che sale piano diventano lo stesso ghirigoro, e una
   nuvola di duecento punti schiacciata in una fascia alta come una riga di
   testo è una macchia. Erano strisce perché a suo tempo lo spazio non c'era —
   ma lo spazio c'era, raccolto in fondo alla colonna dal `margin-top: auto`
   della sezione di chiusura: quaranta pixel di vuoto che non dicevano niente.

   Qui si dichiara come si divide l'altezza: le classifiche prendono quello che
   chiedono (sono righe di testo, e una riga di testo ha una sola altezza
   giusta), le due sezioni con le forme si dividono tutto il resto. Nessuna
   soglia, nessun asse e nessun dato cambia: cambia quanti pixel ha il disegno
   per dirlo.
--------------------------------------------------------------------------- */
/* `auto` e non `0`: con base zero le due sezioni si dividono l'altezza TOTALE
   in parti uguali, e siccome sotto la seconda forma ci sono due cifre e una
   riga in più, quella forma finiva tredici pixel più bassa dell'altra. Con
   base naturale si divide solo l'AVANZO, e l'avanzo si divide a metà: le due
   forme vengono alte uguali, che è l'unico modo di confrontarle a colpo
   d'occhio. */


/* ------------------------------------------- il percorso in anteprima
   Lo stesso disegno del dettaglio, alto un terzo. Cadono le etichette delle
   tappe — in trecento pixel diventerebbero cinque parole spezzate — e restano
   i nastri, che sono la cosa per cui la forma esiste: si vede DOVE si
   assottiglia. Chi vuole leggere i nomi apre il dettaglio. */
.sk-mini { padding: 0; overflow: hidden; }
.sk-mini .sk { height: 100%; margin: 0; gap: 0; }
/* `min-height: 220px` sopravvive a un `height: 100%`: senza azzerarlo il
   piano restava alto duecentoventi pixel dentro un riquadro da settanta, e i
   nodi — che sono posizionati in percentuale su quel piano — finivano sopra
   le sezioni sotto. */
.sk-mini .sk-piano { height: 100%; min-height: 0; }
/* LE CIFRE NON SI SCRIVONO ADDOSSO: SI CHIEDONO.

   Per un giro le cifre sono state stampate accanto ai nodi, con la ragione che
   un percorso senza numeri mostra che il flusso si assottiglia ma non di
   quanto. La ragione regge, il rimedio no: otto numeri appoggiati sui nastri,
   in trecento pixel, dicono una quantita' senza dire di che cosa — « 118 » non
   e' una lettura, e' un ingombro, e per capirlo bisogna comunque contare le
   tappe da sinistra.

   La risposta e' quella che tutte le altre forme davano gia': il cartellino
   sotto il puntatore, con il nome della tappa, la cifra e la quota. Il
   percorso adesso e' registrato fra le forme che rispondono (`forme-vive`),
   quindi in anteprima non si scrive niente e si chiede tutto — come su una
   banda, su una cella, su una fetta. */
.sk-mini .sk-tappe, .sk-mini .sk-nome, .sk-mini .sk-sotto { display: none; }

/* La sezione di chiusura non raccoglie più l'avanzo in fondo: l'avanzo è già
   stato diviso fra le due forme, e tenerlo qui lo rimetterebbe tutto sotto. */

/* Le classifiche non crescono e non si stringono: tre riferimenti sono tre
   righe, e tre righe hanno un'altezza sola. */

/* E la forma dentro la sezione cresce con lei — fino a un punto. Il minimo è
   la soglia sotto la quale il disegno smette di dire quello per cui esiste; il
   massimo esiste perché senza di lui le due forme si prendevano TUTTO l'avanzo
   e diventavano due terzi del riquadro: un grafico grande quanto mezza colonna
   non è più leggibile di uno alto cento pixel, è solo più grande, e le tre
   classifiche accanto sembravano una nota a piè di pagina. Sopra il tetto
   l'avanzo torna alle righe, che se lo dividono in respiro. */

/* Il vuoto fra la prima forma e le due classifiche.
   La prima sezione prendeva l'avanzo insieme alla terza (`flex: 1 1 auto`), ma
   sotto la sua tela ha una riga sola — «74 a zero contatti» — mentre la terza
   ne ha tre. Con lo stesso fattore di crescita e contenuti diversi, l'avanzo
   si depositava tutto sotto la curva: quaranta pixel di niente in mezzo alla
   colonna, proprio dove la lettura passa da una domanda all'altra.
   La frase si stringe alla sua tela, e l'avanzo torna alle forme, che sono le
   sole che con più pixel dicono di più. */


/* Con il tetto sulle forme l'avanzo va alle classifiche: le righe tornano al
   loro passo invece di stare strette per far posto a un grafico che non ne
   aveva bisogno. */

/* ===========================================================================
   §36 · QUALITÀ DATI — il bordo dice di che genere è il riquadro

   Due generi, e finora si distinguevano solo leggendo il titolo: i record che
   chiedono una mano — un'eccezione da riconciliare, uno stock fermo — e
   l'analisi di classificazione, che non chiede niente a nessuno e serve a
   controllare.

   Lo dice il BORDO e nient'altro, con gli stessi due token che il resto
   dell'applicazione usa già per il tono di un modulo (`data-tono`). Un filo
   spesso a sinistra era un secondo segnale per la stessa cosa, e su tre
   riquadri su cinque leggeva come una plancia semaforo: la distinzione la fa
   il colore del contorno, che si vede di taglio e non ridipinge niente.
--------------------------------------------------------------------------- */

/* L'oro del marchio, lo stesso di `data-tono="warn"`: la tassonomia non è un
   allarme, è l'analisi che si tiene sott'occhio. */


/* --------------------------------------------------- Visibilità, schermi bassi
   In fondo al foglio perché deve vincere: le regole della §35 stanno più sopra
   e hanno la stessa specificità. Una correzione scritta prima di ciò che
   corregge è una correzione che non fa niente — già successo, e questo blocco
   se n'è già andato una volta insieme a una riscrittura più su. Sta qui, e
   qui resta.

   Sotto gli 880 px la colonna ha centoventi pixel in meno. Le due forme non
   spariscono più — sono la cosa per cui il riquadro esiste — ma si stringono,
   e la stanza gliela si trova togliendo aria: le didascalie tornano in linea
   con la loro cifra, i fili fra le sezioni si accorciano. Nessuna cifra e
   nessuna riga di classifica se ne va. */


/* ------------------------------------------ Anzianità in colonna stretta ----
   La colonna centrale ha ceduto mezza colonna alla visibilità, e quaranta
   pixel in meno su cinque bande sono otto pixel per banda: «366–730» non ci
   stava più e finiva «366–7», che non è una banda più corta — è un'altra
   banda. Si misura il MODULO, non la finestra: lo stesso riquadro può essere
   largo o stretto a seconda di dove il titolare l'ha messo, e la regola deve
   seguire lui.

   Cede l'etichetta, non il dato: scende al corpo micro e stringe la
   spaziatura, e il passo fra le colonne si accorcia di due pixel. Le cinque
   bande restano cinque e leggibili. */
@container (max-width: 290px) {
  .ig { gap: 3px; }
  .ig-n { font-size: var(--fs-0); letter-spacing: -0.03em; }
}

/* --------------------------------------------- la riga in cima, a cinque ----
   Con il prezzo medio le voci sono cinque, e sotto i 1400 px cinque etichette
   piu' il suggerimento non ci stanno: «Con annuncio attivo» tornava «Con
   annuncio a…», che non e' un'etichetta piu' corta. Cede il suggerimento, che
   e' l'unica cosa qui dentro che non porta un dato — la riga resta cliccabile
   per intero, e lo dichiara il suo `aria-label`. */


/* ------------------------------------------- le pastiglie della tassonomia --
   Le stesse del dettaglio, ma in una colonna larga centotrenta pixel: la
   pastiglia deve poter andare a capo, o «LOTTO EDIFICABILE RESIDENZIALE» esce
   dalla colonna. Cede la riga unica, non il colore — e il colore è la cosa per
   cui esistono: dicono a colpo d'occhio quale delle due classificazioni
   comanda e quale è il modo in cui il mercato la chiama. */
.tx .tag {
  white-space: normal;
  line-height: 1.25;
  padding: 2px 6px;
  letter-spacing: .03em;
}
.tx-r { align-items: start; }
.tx-hb, .tx-pt { padding-top: 1px; }
/* Il trattino che introduce la classificazione del portale si allinea con la
   prima riga della pastiglia, non con il suo centro. */
.tx-pt::before { top: .75em; }

/* ===========================================================================
   §37 · LA TESTATA DELLA PANORAMICA — l'ingresso

   Le quattro cifre sono la prima cosa che si vede aprendo lo strumento, e
   finora arrivavano già lì, ferme, come qualunque altro riquadro. Qui prendono
   un ingresso: entrano una dopo l'altra da sotto, e mentre entrano una luce
   attraversa la superficie una volta sola.

   Le regole che questo movimento rispetta sono le stesse di tutto il resto:
   dura meno di mezzo secondo, parte da una posizione già vicina a quella
   finale (otto pixel, non mezzo schermo), non si ripete, e sparisce del tutto
   con `prefers-reduced-motion`. Un'animazione in ciclo su una cifra che si
   legge ogni mattina diventa un tic dopo tre giorni.

   Il resto è materia, non movimento: un alone caldo che segue la cifra, un
   velo che schiarisce verso l'alto, e il filo d'accento in cima che si accende
   quando il puntatore passa.
--------------------------------------------------------------------------- */


/* Il velo che passa: un unico riflesso obliquo, fermo, che si sposta solo
   quando il puntatore attraversa il riquadro. Sta SOTTO il testo. */


/* L'ingresso: otto pixel da sotto e un velo di opacità, sfalsati di sessanta
   millisecondi l'uno dall'altro perché si legga l'ordine — quanti sono, quanti
   si vedono, quanti rispondono, quanta domanda è arrivata. */
/* La cifra arriva per ultima: mentre il riquadro sale, il numero compare.
   Non è un secondo movimento — è lo stesso, sfasato. Era una dissolvenza più
   un alone che si accendeva; con la cifra bianca l'alone non c'è più, e resta
   la sola dissolvenza — che è anche l'unica delle due che `prefers-reduced-
   motion` lascerebbe passare. */
/* Chi ha chiesto meno movimento non ne riceve nessuno: le cifre sono già lì,
   accese, alla prima pittura. */


/* Gli ultimi due pixel di «Coerenza e provenienza»: il respiro fra le tre
   parti cede un pixel per giunto. Due pixel su un riquadro alto centoquaranta
   non tolgono niente da leggere; due pixel di traboccamento tagliano l'ultima
   riga del movimento, che invece qualcosa la dice. */


/* Con le pastiglie il trattino che introduceva la classificazione del portale
   non serve piu': erano due righe di testo distinte dal solo colore
   dell'inchiostro, e il trattino diceva «questa e' l'altra». Ora lo dicono la
   forma e il colore, e un segno che ripete quello che si vede gia' e' un segno
   in piu' da scartare. Resta la gola a sinistra, che allinea le due colonne. */
.tx-pt::before { display: none; }

/* ===========================================================================
   §38 · IL MOVIMENTO — la lingua comune

   Fin qui il foglio ha detto che cosa è ogni cosa, di che materiale è fatta e
   dove sta. Questa sezione dice come si MUOVE, e vale come le altre: una
   lingua sola, riusata, non un'animazione diversa per ogni componente.

   ---------------------------------------------------------------- il principio
   Il movimento in Quadra non serve a far sembrare vivo un dato fermo. L'export
   è di ieri e resta di ieri: una barra che cresce da sola al caricamento è la
   stessa bugia raccontata con il tempo invece che con il numero.

   Serve a due cose sole, e si giustifica solo con quelle:

     1. RISPONDERE.  Ogni gesto ha una risposta visiva entro 120 ms. Non è
        cortesia: senza risposta non si sa se il comando è arrivato, e si
        preme di nuovo.
     2. SPIEGARE.    Quando una cosa cambia di posto, di scala o di stato, il
        movimento dice DA DOVE viene. Un pannello che compare al centro
        costringe a ricostruire da soli il legame fra «ho premuto lì» e
        «adesso guardo questo»; lo stesso pannello che cresce dal riquadro che
        l'ha chiesto quel legame lo mostra.

   Da cui sette regole, e nessuna eccezione nel foglio:

     · si risponde alla PRESSIONE, mai al rilascio;
     · ciò che entra o esce usa `--ease-out`; ciò che si sposta `--ease-io`;
       ciò che si posa dopo essersi spostato, una `--molla`;
     · ciò che ESCE va più svelto di ciò che entra (circa 0,6×);
     · non si anima ciò che si vede cento volte al giorno — l'ordinamento di
       una tabella, il cambio di voce nella barra laterale, la scorciatoia da
       tastiera. Là il movimento è ritardo travestito da finitura;
     · una forma si disegna UNA volta per comparsa. Mai in ciclo, mai di nuovo
       al passaggio del puntatore;
     · il movimento non ritarda MAI la lettura: la cifra è già scritta al
       primo fotogramma, si muove solo la forma che le sta intorno;
     · con `prefers-reduced-motion` cade lo spostamento, non la dissolvenza.

   ------------------------------------------------------------- da dove viene
   Le due `--molla` della §1 non sono curve disegnate a occhio: le ha calcolate
   il risolutore di Motion (motion.dev) e sono serializzate in `linear()`, così
   la fisica gira sul compositore e non sul filo principale. È l'unico pezzo
   di quella libreria che entra nel prodotto, ed entra come dato — non come
   codice da eseguire a ogni fotogramma. Il resto — ingressi, sfalsamento,
   risposta al puntatore, continuità fra le pagine — lo fanno il foglio di
   stile e le due API native che il browser ha già: transizioni di vista e
   animazioni sul compositore.

   `--moto` sul documento è il solo interruttore: lo scrive una riga in
   <head>, prima della prima pittura, leggendo `prefers-reduced-motion`.
   Senza JavaScript l'attributo non c'è, nessuna regola di questa sezione si
   applica, e ogni forma è già al suo posto finito. È la stessa promessa della
   plancia: senza JavaScript si compone lo stesso.
--------------------------------------------------------------------------- */

/* ---------------------------------------------------------- 38.1 · LA SCENA
   L'ingresso di base, quello che usano quasi tutte le forme: otto pixel da
   sotto e un velo di opacità. Otto, non cinquanta — deve leggersi come «si sta
   posando», non come «sta arrivando da fuori schermo».

   Lo sfalsamento è calcolato dal foglio con `sibling-index()`, non da uno
   script che scrive un indice su ogni nodo. Dove non è ancora sostenuto la
   dichiarazione cade e resta quella prima, `0ms`: le righe entrano insieme
   invece che a scaglioni, che è una perdita di ritmo, non di informazione. */
@keyframes moto-sale {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@keyframes moto-appare {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* Le forme che si aprono in orizzontale: una tendina che passa da sinistra a
   destra. Non è una scala — il numero dentro la barra resterebbe schiacciato
   fino all'ultimo fotogramma — è un TAGLIO che si ritira. */
@keyframes moto-tenda {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
/* Le barre senza testo dentro: quelle sì, si allungano davvero. */
@keyframes moto-allunga {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
@keyframes moto-cresce {
  from { transform: scaleY(0); }
  to   { transform: scaleY(1); }
}

/* `--ritardo` è REGISTRATA, e senza la registrazione non funzionerebbe.
   Una proprietà personalizzata qualunque si eredita come TESTO: il figlio
   riceve la stringa `calc(… sibling-index() …)` e la valuta a casa propria,
   dove `sibling-index()` vale uno perché quel figlio è figlio unico. Risultato:
   tutte le barre partivano allo stesso istante e lo sfalsamento della riga non
   arrivava mai a destinazione — un difetto che non dà nessun errore e si vede
   soltanto guardando.

   Registrandola con un tipo, il valore si CALCOLA dove è scritto e si eredita
   già fatto. È la differenza fra passare una formula e passare un numero. */
@property --ritardo {
  syntax: "<time>";
  inherits: true;
  initial-value: 0ms;
}

/* Lo sfalsamento condiviso. Il tetto conta: dodici righe a 34 ms sono 400 ms
   di ritmo, quaranta righe sarebbero un secondo e mezzo di attesa per leggere
   l'ultima. Oltre il tetto entrano tutte insieme.

   `--moto-base` è il punto zero del ritmo, e si eredita. Vale 0 in pagina —
   le forme sono già lì e si disegnano subito — e vale 170 ms dentro la lastra,
   dove prima deve arrivare il PANNELLO. Disegnare una torta mentre la scatola
   che la contiene è ancora al 40% della sua scala vuol dire spendere
   l'animazione della torta quando la torta è larga sessanta pixel: si vede il
   movimento e non si vede la forma. Aspettare che la scatola si sia posata
   costa centosettanta millisecondi e restituisce l'intera animazione. */
/* `.ora-b` NON è in questo elenco, e non è una dimenticanza: le quattro
   cifre di apertura della Panoramica hanno già il loro ingresso, scritto e
   tarato nella §37 — sessanta millisecondi di passo, e la cifra che si accende
   sfasata rispetto al riquadro che sale. Rimetterle qui vorrebbe dire
   sovrascrivere quel passo con questo e disallineare le due metà dello stesso
   movimento. Un ingresso su misura vince su un ingresso di serie.

   Anche `.kpi` e `.mini` restano fuori, per una ragione diversa e più
   importante: stanno sotto la piega di una pagina che si apre ogni mattina.
   Un'animazione che quasi nessuno vede è lavoro sprecato; una che si vede
   ogni mattina diventa un tic. La §38.9 elenca tutto ciò che resta fermo, e
   perché. */
[data-moto="si"] :is(
  .ds-riga, .ig-col, .dv-riga, .iv-riga, .cl-riga, .mv-riga,
  .rf li, .cia-leg li, .ta-leg li, .bn-leg > span,
  .ecc-r, .tx-r, .terr-fascia, .tm-blocco
) {
  /* Il ritardo della riga si scrive in una PROPRIETÀ, non solo in
     `animation-delay`, e la ragione è che le proprietà personalizzate si
     ereditano e `animation-delay` no.

     La barra che sta dentro la riga deve partire dopo la riga, ma non è sua
     figlia diretta — fra le due c'è la pista. `animation-delay: inherit` su
     quella barra prende il valore della PISTA, che non ne ha, cioè zero: la
     barra partiva insieme alla riga e lo sfalsamento fra le due non è mai
     esistito. Con una proprietà il valore attraversa la pista e arriva dove
     serve, e ci si può anche sommare.

     Due dichiarazioni: la prima è quella che vale ovunque, la seconda
     aggiunge lo sfalsamento e cade da sola dove `sibling-index()` non c'è
     ancora — là le righe entrano insieme, che è meno ritmo, non meno dato. */
  --ritardo: var(--moto-base, 0ms);
  --ritardo: calc(var(--moto-base, 0ms) +
                  min(sibling-index() - 1, 9) * var(--sfalso));
  /* Il ritmo delle tele (`grafici.js`, 2026-09-28): il passo si divide per il
     numero di elementi, così la forma intera si compone entro `--t-forma`
     qualunque sia il numero delle sue righe. Dove `sibling-count()` non c'è
     vale la riga sopra. */
  --ritardo: calc(var(--moto-base, 0ms) + min(sibling-index() - 1, 9) *
                  min(var(--sfalso), calc(var(--t-forma) * .4 / max(sibling-count() - 1, 1))));
  animation-delay: var(--ritardo);
}
[data-moto="si"] .lastra-corpo { --moto-base: 170ms; }

/* ------------------------------------------------- 38.2 · LE FORME CHE ENTRANO
   Ogni famiglia di forme entra come è fatta: le righe salgono, le barre si
   allungano, le colonne crescono dalla loro base, i dischi si scoprono in
   senso orario, la curva si disegna.

   Tutte con `backwards` e MAI con `both`, ed è una regola non una preferenza.

   `both` lascia in eredità il fotogramma finale: finita l'animazione
   l'elemento resta con un `transform` (che è un contesto di impilamento e un
   blocco contenitore), con un `clip-path: inset(0 0 0 0)` (che è un
   contenitore che ritaglia, invisibile e permanente) e con una maschera. Sono
   esattamente i residui che la §25 ha già dovuto togliere una volta da tutta
   l'interfaccia perché tosavano gli anelli di messa a fuoco e mangiavano un
   arco di quattordici pixel al contenuto.

   Con `backwards` l'animazione tiene il suo primo fotogramma finché non
   parte, lo percorre, e poi SI TOGLIE DI MEZZO: l'elemento torna esattamente
   alla regola che lo descrive, senza trasformazioni, senza ritagli, senza
   maschere. È il motivo per cui il disco dichiara `--rivela: 1turn` come suo
   valore normale e il fotogramma chiave ha solo un `from`: lo stato di riposo
   di quel disco è «intero», e l'animazione è la deviazione. Se un giorno non
   partisse, il disco è comunque tutto lì. */

/* — le righe di una distribuzione, di un divario, di una classifica */
[data-moto="si"] :is(.ds-riga, .dv-riga, .iv-riga, .cl-riga, .mv-riga, .rf li) {
  animation-name: moto-sale;
  animation-duration: var(--t-stato);
  animation-timing-function: var(--ease-out);
  animation-fill-mode: backwards;
}

/* — la barra dentro la riga: parte dal suo bordo sinistro, che è lo zero.
     Si allunga DOPO che la riga si è posata, non insieme: prima si vede che
     riga è, poi quanto vale. */


/* Una forma che sta MORFANDO non entra: `movimento.js` le mette
   `data-morfa` addosso quando le sue bande stanno passando dal valore di un
   periodo a quello di un altro, e in quel caso l'ingresso è di troppo — la
   riga era già lì un attimo fa, e farla ricomparire cancellerebbe proprio il
   confronto che si sta cercando di mostrare. */
[data-moto="si"] [data-morfa] :is(
  .ig-col, .ds-riga, .cl-riga, .dv-riga, .mv-riga, .iv-riga,
  .ig-pista > i, .ds-pista > i, .cl-pista > i
) { animation: none; }

/* — le colonne dell'istogramma crescono dalla base, che è l'asse */
[data-moto="si"] .ig-pista > i {
  transform-origin: center bottom;
  animation: moto-cresce var(--t-forma) var(--ease-out) backwards;
  animation-delay: calc(var(--ritardo, 0ms) + 90ms);
}
[data-moto="si"] .ig-col {
  animation: moto-appare var(--t-stato) var(--ease-out) backwards;
}

/* — le forme che portano una cifra dentro non si scalano: si scoprono.
     `--ease-out` e non `--ease-io`, e la ragione è la regola di sopra: qui
     entra del CONTENUTO, e ciò che entra parte deciso. Una tendina che parte
     lenta lascia il riquadro vuoto proprio nell'istante in cui lo si sta
     guardando. La curva in-out resta ai dischi, che non entrano: ruotano. */
[data-moto="si"] :is(.bn, .mb, .metro, .terr-celle, .an-barra) {
  animation: moto-tenda var(--t-forma) var(--ease-out) backwards;
  animation-delay: var(--moto-base, 0ms);
}
[data-moto="si"] .terr-fascia {
  animation-name: moto-appare;
  animation-duration: var(--t-stato);
  animation-timing-function: var(--ease-out);
  animation-fill-mode: backwards;
}
/* Le celle si scoprono dopo che la fascia si è accesa: prima si vede quale
   valle è, poi quanto pesa. Novanta millisecondi, come per le barre. */
[data-moto="si"] .terr-celle { animation-delay: calc(var(--ritardo, 0ms) + 90ms); }

/* — i dischi si scoprono in senso orario, come si legge una torta.
     La maschera conica È l'animazione: sta qui e solo qui, sotto
     `[data-moto="si"]`, così senza l'interruttore il disco non è mai
     mascherato e quindi non può restare invisibile. */
@property --rivela {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0turn;
}
@keyframes moto-disco { from { --rivela: 0turn; } }
/* LA LANCETTA HA UNA SOLA MASCHERA, E LA CURVA GIUSTA.

   Girava su `--ease-io` — `cubic-bezier(.77, 0, .175, 1)` — cioe' la curva che
   la §38 riserva a cio' che SI SPOSTA. Su una scopertura quella curva sta
   ferma per un sesto della durata, poi attraversa mezzo giro in due
   fotogrammi, poi si posa: l'occhio non legge una lancetta che gira, legge tre
   stacchi. E ogni fotogramma ridisegnava anche il buco, che non cambia mai.

   Una maschera sola per nodo (il buco sta sul contenitore), la curva d'ingresso
   che questo foglio usa per tutto cio' che compare, e sessanta millisecondi in
   piu' perche' la fine del giro sia una posa e non un arresto. */
[data-moto="si"] .ta-disco {
  --rivela: 1turn;
  mask-image: conic-gradient(#000 var(--rivela), transparent 0);
  animation: moto-disco var(--t-disco) var(--ease-out) backwards;
  animation-delay: var(--moto-base, 0ms);
  will-change: mask-image;
}
[data-moto="si"] .cia-torta {
  --rivela: 1turn;
  -webkit-mask-image: conic-gradient(#000 var(--rivela), transparent 0);
  mask-image: conic-gradient(#000 var(--rivela), transparent 0);
  animation: moto-disco var(--t-disco) var(--ease-out) backwards;
  animation-delay: var(--moto-base, 0ms);
  will-change: mask-image;
}
/* Il totale dentro il buco arriva quando la lancetta ha finito il giro. */
[data-moto="si"] .cia-mezzo {
  animation: moto-appare var(--t-stato) var(--ease-out) backwards;
  animation-delay: calc(var(--moto-base, 0ms) + var(--t-disco) * 0.7);
}

/* — la curva si disegna. `pathLength="1"` sul tracciato normalizza la
     lunghezza a uno: la tratteggiatura è esatta senza misurarla in JavaScript,
     e resta esatta se un giorno la curva avrà venti punti invece di dieci. */
@keyframes moto-traccia { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
/* La curva si traccia a velocità COSTANTE: è una penna che percorre un
   tracciato, e una penna che accelera e rallenta disegnerebbe una curva che
   sembra avere due pendenze diverse là dove ne ha una sola. `linear` è
   l'unico posto del foglio in cui la curva di tempo è nessuna curva, ed è
   per questa ragione. */
[data-moto="si"] .mc-linea {
  stroke-dasharray: 1;
  animation: moto-traccia var(--t-forma) linear backwards;
  animation-delay: var(--moto-base, 0ms);
}
[data-moto="si"] .mc-area {
  animation: moto-appare var(--t-forma) var(--ease-out) backwards;
  animation-delay: var(--moto-base, 0ms);
}
[data-moto="si"] .mc-soglia {
  animation: moto-appare var(--t-stato) var(--ease-out) backwards;
  animation-delay: calc(var(--moto-base, 0ms) + var(--t-forma) * 0.6);
}

/* — le piastrelle del treemap e le celle della matrice: non si spostano, si
     accendono. Un rettangolo che scivola in una tassellatura piena sembra
     fuori posto per tutto il tempo in cui è in viaggio. */
[data-moto="si"] .tm-blocco {
  animation: moto-appare var(--t-stato) var(--ease-out) backwards;
}
[data-moto="si"] .mx-c {
  animation: moto-appare 160ms var(--ease-out) backwards;
  animation-delay: var(--moto-base, 0ms);
  animation-delay: calc(var(--moto-base, 0ms) + min(sibling-index() - 1, 8) * 22ms);
}

/* — le righe della tassonomia e delle eccezioni */
[data-moto="si"] :is(.tx-r, .ecc-r) {
  animation-name: moto-sale;
  animation-duration: var(--t-stato);
  animation-timing-function: var(--ease-out);
  animation-fill-mode: backwards;
}

/* --------------------------------------------- 38.3 · LA PLANCIA CHE RISPONDE
   Un modulo è un comando grande. Reagisce a tre cose: il puntatore che passa,
   il dito che preme, e il fatto che il suo pannello sia aperto.

   Il terzo è il meno ovvio e il più utile: mentre il dettaglio è aperto, il
   riquadro da cui è nato resta ACCESO sotto il velo. Chiudendo, l'occhio sa
   già dove tornare senza cercarlo. */

/* Il modulo scelto per lo scambio pulsa una volta sola: dice «tengo questo in
   mano», non «sto caricando». Un pulsare in ciclo su una plancia con dodici
   riquadri diventa un tic in tre giorni. */
@keyframes moto-preso {
  from { box-shadow: 0 0 0 0 color-mix(in srgb, var(--data) 46%, transparent); }
  to   { box-shadow: 0 0 0 9px color-mix(in srgb, var(--data) 0%, transparent); }
}
body.plancia-modifica .mod[data-scelto] {
  animation: moto-preso 620ms var(--ease-out) 1;
}
/* In modifica ogni modulo si stacca di un pixel dalla plancia: è il segnale
   che adesso sono oggetti da prendere, non superfici da leggere. */
body.plancia-modifica .mod {
  transition: transform var(--t-stato) var(--ease-out),
              box-shadow var(--t-stato) var(--ease-out),
              border-color var(--t-stato) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  body.plancia-modifica .mod:hover { transform: translateY(-2px) scale(1.004); }
}
body.plancia-modifica .mod[data-bersaglio] {
  border-color: var(--data);
  transform: scale(0.985);
}
body.plancia-modifica .mod[data-trascina] { opacity: .45; }

/* Le celle del territorio NON prendono niente da questa sezione, e vale la
   pena scriverlo perché il primo istinto è dare loro una scala sulla
   pressione come a ogni altro bersaglio.

   Sarebbe sbagliato: quelle celle sono una TASSELLATURA. Stanno una accanto
   all'altra senza spazio, separate da un filo del colore della pagina, e
   l'area di ognuna è la quantità che dichiara. Una cella che si rimpicciolisce
   del sei per cento sotto il dito apre quattro fessure nel mosaico e per un
   momento mente sulla propria area — cioè sul solo dato che sta portando.
   La risposta giusta per una piastrella è la LUCE, e la §20 gliela dà già:
   più chiara al passaggio, più chiara ancora alla pressione. Un mosaico
   risponde accendendosi, non staccandosi. */

/* -------------------------------------------- 38.4 · IL PANNELLO CHE CRESCE
   L'animazione della lastra la governa `app.js` con l'API di animazione — deve
   conoscere il rettangolo del riquadro d'origine, che è un numero, non una
   regola. Qui restano le due cose che sono davvero di stile: la curva con cui
   cresce, e il velo dietro.

   Il velo entra più lento della lastra e se ne va più svelto: mentre il
   pannello arriva, il fondo deve essere già scuro; mentre se ne va, il fondo
   deve sparire prima, o sembra che la pagina resti coperta. */


/* Qui c'era una sfocatura sul velo, ed è stata tolta: due pixel di sfocatura
   su tutto lo schermo si vedono appena e costano la ricomposizione dell'intera
   finestra a ogni fotogramma, proprio nei quattrocento millisecondi in cui il
   pannello sta crescendo e il compositore ha già da fare. Il velo fa già il
   suo mestiere con l'opacità — dire che la pagina resta lì sotto — e la §24
   dice da tempo che in questa applicazione la profondità la dichiara il bordo,
   non l'alone. Una finitura che si paga in fotogrammi non è una finitura. */
/* Il corpo del pannello scorre: quando ci si arriva da un modulo, le sezioni
   dentro salgono una dopo l'altra. È lo stesso ingresso delle forme, applicato
   a un contenuto che è appena stato inserito nel documento. */
[data-moto="si"] .lastra-corpo > * {
  animation: moto-sale 260ms var(--ease-out) backwards;
  animation-delay: var(--moto-base, 0ms);
  animation-delay: calc(var(--moto-base, 0ms) +
                        min(sibling-index() - 1, 5) * var(--sfalso));
}

/* ------------------------------------------- 38.5 · IL CAMBIO DI PAGINA
   Cinque sezioni, cinque documenti veri: il server compone e il browser
   naviga. Senza niente, ogni passaggio è un lampo bianco-nero e la barra
   laterale — che è identica su tutte e cinque — lampeggia con il resto.

   La transizione di vista fra documenti risolve esattamente questo, ed è
   nativa: nessuna libreria, nessun instradamento in JavaScript, nessuna
   pagina singola da mantenere. Dove non è sostenuta, la navigazione è quella
   di sempre.

   Tre nomi soltanto, e ognuno ha una ragione:
     `guscio`  la barra laterale NON si dissolve: è la stessa, e ciò che è lo
               stesso non deve muoversi;
     `guida`   il pallino della voce attiva SCIVOLA da una voce all'altra —
               è l'unico elemento che davvero cambia posto, e mostrarlo in
               viaggio è il modo più economico di dire «sei passato di lì»;
     `titolo`  il titolo di pagina si sposta invece di sostituirsi.

   180 ms, non di più: una transizione di pagina che si nota è una pagina che
   arriva tardi. */
@view-transition { navigation: auto; }


.page-head h1 { view-transition-name: titolo; }

::view-transition-group(guscio) { animation-duration: 0s; }
::view-transition-old(guscio),
::view-transition-new(guscio) { animation: none; opacity: 1; }

::view-transition-group(guida) {
  animation-duration: var(--t-molla);
  animation-timing-function: var(--molla);
}
::view-transition-old(guida),
::view-transition-new(guida) { animation: none; opacity: 1; }

::view-transition-group(titolo) {
  animation-duration: 220ms;
  animation-timing-function: var(--ease-io);
}

::view-transition-old(root) {
  animation: moto-appare 90ms var(--ease-out) reverse backwards;
}
::view-transition-new(root) {
  animation: moto-pagina 180ms var(--ease-out) backwards;
}
@keyframes moto-pagina {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ------------------------------------------------ 38.6 · I COMANDI
   Bottoni, tendine, segmenti, caricamento. Qui il movimento è tutto sotto i
   200 ms: sono i gesti che si ripetono, e un gesto che si ripete non deve
   costare tempo nemmeno una volta. */

/* — la tendina che apre la fonte delle cifre. `interpolate-size` insegna al
     browser a interpolare `auto`, e `::details-content` è il contenuto che si
     apre: insieme fanno l'apertura in altezza senza misurare niente in
     JavaScript. Dove non c'è, la tendina si apre di scatto come sempre. */
:root { interpolate-size: allow-keywords; }
.fonte-cifre::details-content {
  block-size: 0;
  overflow: clip;
  /* Il ritaglio serve solo a nascondere ciò che non è ancora sceso, e non deve
     diventare l'ennesimo contenitore invisibile che tosa quello che ci sta
     dentro — è il difetto che la §25 ha già dovuto togliere una volta da tutta
     l'interfaccia. Quattro pixel di margine bastano all'anello di messa a
     fuoco (due di contorno più due di scostamento) e non lasciano passare
     niente di visibile mentre la tendina scorre. */
  overflow-clip-margin: 4px;
  opacity: 0;
  transition: block-size var(--t-stato) var(--ease-out),
              opacity var(--t-stato) var(--ease-out),
              content-visibility var(--t-stato) allow-discrete;
}
.fonte-cifre[open]::details-content { block-size: auto; opacity: 1; }
.fonte-cifre > summary:active { transform: scale(.995); }
.fonte-cifre > summary {
  transition: border-color var(--t-stato) var(--ease-out),
              background-color var(--t-stato) var(--ease-out),
              color var(--t-stato) var(--ease-out),
              transform var(--t-pressione) var(--ease-out);
}

/* — il selettore di periodo. Il cursore è un solo elemento che si SPOSTA da un
     segmento all'altro: due pastiglie che si accendono e si spengono sono due
     eventi, una pastiglia che scivola è un movimento, e il movimento dice che
     è la stessa scelta spostata. La posizione la scrive `movimento.js` in due
     variabili; qui c'è solo come ci arriva. */
.periodo-scelta { position: relative; }
.periodo-scelta::before {
  content: "";
  position: absolute;
  left: 0; top: 0;
  width: var(--cursore-w, 0px);
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--pri-fill); box-shadow: var(--pri-edge);
  transform: translateX(var(--cursore-x, 0px));
  opacity: 0;
  pointer-events: none;
  /* `width` è l'unica proprietà di impaginato transitata in tutto il foglio,
     ed è una deroga consapevole: il cursore è un riquadro fuori flusso —
     assoluto dentro un genitore relativo — quindi cambiargli la larghezza non
     rimette in fila nessun altro elemento, e il costo è la ricomposizione di
     una pastiglia di centotrenta pixel per un terzo di secondo, un paio di
     volte a sessione. L'alternativa, `scaleX`, deformerebbe il raggio: un
     pillolo scalato in orizzontale ha le estremità ellittiche, e si vede. */
  transition: transform var(--t-molla) var(--molla),
              width var(--t-molla) var(--molla),
              opacity var(--t-stato) var(--ease-out);
}
.periodo-scelta[data-cursore]::before { opacity: 1; }
/* Con il cursore acceso, il segmento attivo non porta più il suo fondo: il
   fondo è il cursore. Il testo sale sopra. */
.periodo-scelta[data-cursore] .seg { position: relative; z-index: 1; background: none; }
.periodo-scelta[data-cursore] .seg.attivo { background: none; border-color: transparent; }

/* — il caricamento di un export. La zona di rilascio ha già il suo cambio di
     colore (§9); qui prende l'unica cosa che le mancava — il RILIEVO mentre il
     file è sopra di lei. Mezzo punto percentuale: quanto basta a far leggere
     «pronta a prenderlo», non tanto da spostare il testo sotto.

     Il segno cresce insieme alla zona: è il bersaglio vero del rilascio. */
.dropzone {
  transition: border-color var(--t-stato) var(--ease-out),
              background-color var(--t-stato) var(--ease-out),
              transform var(--t-stato) var(--ease-out);
}
.dropzone.over { transform: scale(1.006); }
.dz-mark { transition: border-color var(--t-stato) var(--ease-out),
                       transform var(--t-molla) var(--molla); }
.dropzone.over .dz-mark { transform: scale(1.1); }
/* Il file scelto ARRIVA: comparire e basta lascia il dubbio di averlo già
   letto e non notato. */
.dz-chosen { animation: moto-sale var(--t-stato) var(--ease-out) backwards; }

/* — i canali, su Sorgenti, NON rispondono al puntatore, e anche questo va
     scritto: una scheda che si illumina quando ci passi sopra promette un
     clic, e su quella scheda non c'è nessun clic da fare — il comando è il
     bottone che sta dentro, e quello risponde già. Accendere il contorno
     dell'intera scheda vorrebbe dire chiedere di provare, scoprire che non
     succede niente, e imparare a diffidare del prossimo contorno acceso.
     Il movimento risponde ai gesti che esistono; inventarne uno che non c'è
     è peggio che non rispondere. */

/* ---------------------------------------------------- 38.7 · LE ATTESE
   Un'attesa disegnata dice due cose: che il lavoro è partito, e di che lavoro
   si tratta. La seconda è quella che manca quasi sempre.

   Niente barra che finge di sapere a che punto è: il generatore di report
   dichiara la FASE, e la fase è l'unica cosa vera che si può mostrare. La
   barra resta indeterminata perché il lavoro è indeterminato, e cambia
   soltanto il testo — che però cambia in dissolvenza invece che di scatto,
   perché uno scatto in mezzo a un'attesa si legge come un errore. */
#job-fase {
  transition: opacity 160ms var(--ease-out);
}
#job-fase[data-cambia] { opacity: 0; }
/* La barra: sempre lo stesso passo, senza accelerazioni. Una barra che
   accelera suggerisce un avanzamento che nessuno ha misurato. */
.progress-bar { animation: slide 1.4s linear infinite; }

/* Il bottone che sta lavorando: non sparisce e non cambia larghezza — un
   comando che si restringe mentre lo si guarda sembra rotto. Si spegne, e il
   filo che gli attraversa il fondo dice che qualcosa sta andando. */
/* Solo `.btn`: il comando di Luna ha già il suo segno che pulsa (§13) e
   cambia etichetta in «Luna sta leggendo…». Due indicatori di attesa sullo
   stesso bottone non raddoppiano l'informazione, la dividono. */
.btn[data-stato="attesa"] { position: relative; overflow: hidden; }
.btn[data-stato="attesa"]::after {
  content: "";
  position: absolute; inset: auto 0 0 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--on-pri-fill), transparent);
  animation: slide 1.1s linear infinite;
}
/* Luna che legge: il blocco arriva dal basso quando la risposta è pronta. */
.ai-blocco { animation: moto-sale 300ms var(--ease-out) backwards; }

/* -------------------------------------- 38.8 · CIÒ CHE RESTA FERMO
   Un elenco di animazioni non dice quasi niente su una lingua. Dice qualcosa
   l'elenco di quelle che si è deciso di NON fare, perché è lì che si vede
   dove passa il confine.

   · **L'ordinamento di una tabella.** Cliccare un'intestazione riordina
     duecento righe. Farle scivolare al posto nuovo sarebbe la dimostrazione
     più vistosa di questa sezione e la più dannosa: si ordina per LEGGERE, e
     mezzo secondo di righe in movimento è mezzo secondo in cui non si legge.
     Si muove la freccina dell'intestazione, che è ciò che è cambiato davvero.

   · **La voce attiva della barra laterale, quando ci si clicca sopra.** Il
     pallino scivola solo durante il cambio di PAGINA (§38.5), dove sta
     spiegando un passaggio. Accenderlo con un'animazione anche al clic
     vorrebbe dire animare il gesto più ripetuto dell'applicazione.

   · **Le cifre, al caricamento.** Non salgono da zero, mai. Salgono soltanto
     quando si cambia periodo, dove «da quanto a quanto» è la domanda che si
     sta facendo. Al caricamento non c'è nessun «da quanto»: c'è un export di
     ieri, e farlo salire da zero sarebbe la bugia della freschezza raccontata
     con il tempo. Vedi `DESIGN.md`.

   · **Le due tele, quando si cambia periodo.** La concentrazione e la
     dispersione non scorrono da un periodo all'altro. Là l'ascissa è un rango
     o un annuncio, e il quarantasettesimo del 2025 non è il quarantasettesimo
     del 2026: farli scorrere l'uno nell'altro affermerebbe una continuità che
     non c'è. Si morfano solo le forme a categorie stabili.

   · **Le schede dei canali, e ogni superficie che non si apre.** Un contorno
     che si accende al passaggio promette un clic. Dove il clic non c'è, la
     promessa è falsa e si impara a diffidare della prossima.

   · **La metà bassa della Panoramica.** Le quattro cifre di apertura hanno il
     loro ingresso; il resto della pagina no. Sta sotto la piega di una
     schermata che si apre ogni mattina, e un'animazione che si vede ogni
     mattina è un tic, non una finitura.
--------------------------------------------------------------------------- */

/* -------------------------------------------------- 38.9 · LA CARTA
   Una pagina stampata non ha un tempo: ha un istante solo, e in quell'istante
   ogni animazione vale il suo PRIMO fotogramma — e il primo fotogramma di un
   ingresso è l'elemento invisibile. Senza questa regola, un foglio stampato
   mentre la pagina non è ancora stata guardata uscirebbe con i grafici
   bianchi.

   Vale anche con `backwards`, che è il riempimento che questa sezione usa
   ovunque: prima che l'animazione parta l'elemento sta comunque sul suo primo
   fotogramma. E non è un caso di scuola: il tempo del documento non avanza in
   una scheda in secondo piano, e una scheda aperta e non ancora guardata è
   esattamente lo stato in cui un ingresso non è ancora partito. Che il testo di
   questi grafici finisca sulla carta è una promessa che questa applicazione
   fa da quando le forme sono in HTML invece che su tela (`_forme.html`), e
   una promessa non si rompe per una finitura. */
@media print {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  [data-moto] :is(.ta-disco, .cia-torta, .mc-linea) { mask-image: none; stroke-dasharray: none; }
  [data-moto] :is(.bn, .mb, .metro, .terr-celle, .an-barra) { clip-path: none; }
}

/* ----------------------------------------------- 38.10 · MOVIMENTO RIDOTTO
   La §2 già toglie spostamenti e animazioni a tutto il documento. Qui restano
   le tre cose che quella regola non può raggiungere, perché non sono
   `animation` né `transition`: la maschera dei dischi, la tratteggiatura della
   curva, e le transizioni fra documenti.

   In pratica non serve quasi mai — `--moto` vale «no» già in <head> quando la
   preferenza è attiva, e nessuna regola di questa sezione si applica — ma una
   preferenza cambiata a pagina aperta non ricarica il documento. */
@media (prefers-reduced-motion: reduce) {
  [data-moto] :is(.ta-disco, .cia-torta) { animation: none; mask-image: none; }
  [data-moto] .mc-linea { stroke-dasharray: none; animation: none; }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation-duration: 1ms !important; }
}

/* ==========================================================================
   §39 · LE FORME CHE RISPONDONO — la lente, gli spicchi, i flussi

   La §38 dice come una forma ENTRA. Questa dice che cosa fa mentre la si
   guarda, e aggiunge la sola cosa che a queste forme mancava: la possibilità
   di avvicinarsi.

   ------------------------------------------------------------ perché serve
   Il problema non era estetico. Un treemap con trentadue piastrelle dentro un
   riquadro da trecento pixel SI GUARDA e non si legge: metà delle tessere non
   ha lo spazio per il proprio nome, e quel nome è il dato. Una matrice a
   settantadue celle dentro una lastra larga l'ottantaquattro per cento della
   finestra è già al suo limite su un portatile. Una nuvola di centosessantasei
   punti con una coda a sedicimila visite ha il grosso schiacciato contro
   l'asse — ed è esattamente la forma del portafoglio, quindi non si taglia la
   coda: si dà il modo di avvicinarsi al grosso.

   Fin qui la risposta era «apri il modulo», e finiva lì. Adesso c'è un secondo
   strato, e sta sopra il primo senza sostituirlo.

   ------------------------------------------------------- le quattro regole
     1. UNO STRATO PER GESTO. Un clic fuori chiude ciò che sta in cima e si
        ferma lì; `Escape` toglie un livello per pressione. Se un gesto potesse
        chiudere due strati, aprire il secondo diventerebbe un rischio — e uno
        strumento che si teme non si usa.
     2. LA FORMA È LA STESSA. Quello che si apre non è una seconda versione:
        è lo stesso nodo, clonato, con gli stessi valori negli stessi `data-`.
        Non c'è modo che la copia grande dica una cifra diversa da quella
        piccola.
     3. CI SI AVVICINA SOLO DOVE SERVE. Lo zoom si accende dove i segni sono
        tanti e piccoli. Su una torta con sei spicchi non aggiunge niente e
        toglie: un comando in più da capire, per una forma che si legge già.
     4. IL PUNTATORE È IL PUNTO FERMO. Ingrandendo verso il centro, la cella
        che si sta esaminando scappa via al primo passo.

   ---------------------------------------------------- e la lingua di prima
   Nessuna curva nuova, nessuna durata nuova. La finestra cresce con la
   `--molla-lastra` della §1, come il pannello; gli spicchi rispondono in
   `--t-pressione`, come ogni gesto; le forme che vi entrano dentro si
   compongono con la §38.2 e con lo stesso `--moto-base` della lastra. Le due
   sole misure che nascono qui sono geometria di questa sezione: quanto esce
   uno spicchio, e quanto si smorza ciò che non si sta guardando.
   ========================================================================= */

:root {
  /* Quanto esce lo spicchio sotto il puntatore, in unità del disegno (il
     disco è cento unità di lato): tre su cento. Non è un'esplosione — è il
     minimo che si legga come «questo, non quello». */
  /* Quanto CRESCE la fetta toccata. Sei centesimi: su un disco da trecento
     pixel sono nove pixel di raggio in piu', abbastanza da vedersi e troppo
     pochi perche' la fetta scavalchi il bordo del riquadro. */
  --fetta-cresce: 1.06;
  /* Quanto resta di ciò che NON si sta guardando. Non zero, e non è una
     sfumatura: una parte che sparisce fa sembrare cambiato il totale. */
  --sfondo-smorzato: .34;
  --t-fetta: 160ms;       /* lo spicchio che esce e rientra */
  --t-lente: 240ms;       /* la finestra, e la vista del sunburst che cambia */
}

/* ------------------------------------------------ 39.1 · LA CORNICE APRIBILE
   Una forma dentro una cornice che si può aprire. Il bersaglio è la cornice
   intera — davanti a un grafico si preme il grafico — ma il comando per la
   tastiera e per chi legge con la voce è un BOTTONE vero nell'angolo: la
   figura resta `role="img"` con la sua descrizione, e trasformarla in un
   comando vorrebbe dire far annunciare «pulsante» al posto della composizione
   del portafoglio.

   Il bottone non è nascosto a chi naviga da tastiera: compare al passaggio
   del puntatore E quando prende il fuoco. Un comando che si vede solo col
   mouse è un comando che per metà delle persone non esiste. */
.fo { position: relative; min-width: 0; }
.fo[data-lente] { cursor: zoom-in; }
.fo-apri {
  position: absolute;
  top: 0; right: 0;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  padding: 0;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-1);
  color: var(--muted);
  cursor: zoom-in;
  opacity: 0;
  transition: opacity var(--t-stato) var(--ease-out),
              color var(--t-stato) var(--ease-out),
              background-color var(--t-stato) var(--ease-out),
              transform var(--t-pressione) var(--ease-out);
}
.fo-apri svg { width: 11px; height: 11px; }
.fo:hover > .fo-apri,
.fo:focus-within > .fo-apri { opacity: 1; }
.fo-apri:hover { color: var(--text); background: var(--surface-3); }
.fo-apri:active { transform: scale(.92); }
/* Sul touch non c'è passaggio del puntatore: il comando c'è sempre. */
@media (hover: none) { .fo-apri { opacity: 1; } }

/* ------------------------------------------------------ 39.2 · LA LENTE
   La finestra centrata, sopra tutto il resto.

   Centrata e non laterale, e la differenza non è di gusto: la lastra porta un
   DETTAGLIO accanto al contesto che l'ha fatto scegliere, e quel contesto deve
   restare in vista alla sua sinistra; la lente porta la stessa forma più
   grande, e una forma vuole tutte e due le sue dimensioni.

   Il centraggio è con `inset: 0; margin: auto` e NON con una traslazione,
   perché la traslazione è già occupata: la crescita dal riquadro d'origine la
   anima `lente.js` scrivendo `transform`, e due cose sulla stessa proprietà
   sono una che vince e una che sparisce. Da cui anche le altezze dichiarate
   per misura: `margin: auto` centra in verticale solo su un'altezza definita. */
.lente-velo {
  position: fixed; inset: 0; z-index: var(--z-lente-velo);
  background: rgba(0, 0, 0, .42);
  opacity: 0; visibility: hidden;
  transition: opacity var(--t-uscita) var(--ease-out),
              visibility 0s linear var(--t-uscita);
}
.lente-velo.aperta {
  opacity: 1; visibility: visible;
  transition: opacity var(--t-lastra) var(--ease-out), visibility 0s;
}
.lente {
  position: fixed;
  inset: 0;
  margin: auto;
  z-index: var(--z-lente);
  display: flex;
  flex-direction: column;
  width: min(920px, 92vw);
  height: min(680px, 86vh);
  background: var(--paper);
  border: 0;
  border-radius: var(--r-xl);
  box-shadow: var(--ombra-foglio);
  overflow: hidden;
}
/* La misura la sceglie la forma, non la finestra: una torta con sei spicchi
   in una tela da milleduecento pixel è una torta con sei spicchi e molto
   vuoto intorno, e il vuoto intorno a un grafico si legge come «manca
   qualcosa». */
.lente[data-misura="compatta"] { width: min(620px, 92vw);  height: min(560px, 84vh); }
.lente[data-misura="media"]    { width: min(920px, 92vw);  height: min(680px, 86vh); }
.lente[data-misura="ampia"]    { width: min(1320px, 94vw); height: min(820px, 90vh); }

.lente-testa {
  flex: none;
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--border);
}
.lente-testa h2 { margin: 0; font-size: var(--fs-5); }
.lente-testa p {
  margin: 2px 0 0; font-size: var(--fs-2); color: var(--muted);
  line-height: var(--lh-cell);
}
.lente-testa > div:first-child { min-width: 0; flex: 1 1 auto; }

/* I comandi dello zoom stanno con il titolo e sono SECONDARI: hanno il peso di
   un'etichetta, non di un'azione. Chi apre una forma vuole guardarla; chi ha
   bisogno di avvicinarsi lo sa già e li trova dove se li aspetta. */
.lente-comandi {
  flex: none;
  display: flex; align-items: center; gap: 2px;
  padding: 2px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
}
.lente-comandi button {
  width: 26px; height: 26px;
  display: grid; place-items: center;
  padding: 0;
  background: none; border: 0; border-radius: var(--r-pill);
  color: var(--muted); cursor: pointer;
  transition: background-color var(--t-stato) var(--ease-out),
              color var(--t-stato) var(--ease-out),
              transform var(--t-pressione) var(--ease-out);
}
.lente-comandi button svg { width: 12px; height: 12px; }
.lente-comandi button:hover:not(:disabled) { background: var(--surface-3); color: var(--text); }
.lente-comandi button:active:not(:disabled) { transform: scale(.9); }
.lente-comandi button:disabled { opacity: .34; cursor: default; }
.lente-fattore {
  min-width: 34px; text-align: center;
  font-family: var(--font-mono); font-size: var(--fs-1);
  color: var(--muted); font-variant-numeric: tabular-nums;
}
.lente-reset {
  width: auto !important; padding: 0 10px !important;
  font-size: var(--fs-1); letter-spacing: .02em;
}

/* La tela ritaglia, il corpo si muove. Due nodi e non uno: trasformare il
   riquadro che ritaglia vorrebbe dire trasformare anche il proprio ritaglio,
   e non nasconderebbe più niente. */
.lente-tela {
  flex: 1 1 auto;
  position: relative;
  min-height: 0;
  overflow: hidden;
}
.lente-corpo {
  width: 100%; height: 100%;
  overflow: auto;
  padding: var(--sp-5);
  /* Lo spostamento e la scala non si transizionano: lo zoom è la risposta a un
     gesto continuo, e interpolare fra due inquadrature a ogni scatto di
     rotella trasforma un ingrandimento in un tremolio. */
  will-change: transform;
}
.lente-corpo > * + * { margin-top: var(--sp-5); }
/* Con lo zoom acceso è la tela a ritagliare, e il corpo non scorre più: quello
   che sta fuori si raggiunge trascinando, che è il gesto giusto quando ci si è
   avvicinati a qualcosa. */
.lente-con-zoom .lente-corpo {
  overflow: visible;
  display: grid;
  align-content: center;
}
.lente-tela.lente-zoomata { cursor: grab; }
.lente-tela.lente-presa { cursor: grabbing; }

/* La riga di lettura: dove la forma scrive che cosa sta sotto il puntatore.
   Non è un cartellino che insegue il mouse — quelli coprono proprio la parte
   di grafico che si sta guardando, e su una matrice fitta coprono la cella
   accanto a quella che si vuole confrontare. Sta ferma sotto la forma, ha
   un'altezza propria, e la finestra non si muove quando compare. */
.lente-lettura {
  flex: none;
  margin: 0;
  padding: 0 var(--sp-5);
  height: 34px;
  display: flex; align-items: center;
  border-top: 1px solid var(--border);
  font-size: var(--fs-2);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  opacity: 0;
  transition: opacity var(--t-stato) var(--ease-out),
              color var(--t-stato) var(--ease-out);
}
.lente-lettura.lente-lettura-piena { opacity: 1; color: var(--text); }

/* Dentro la lente le forme prendono lo spazio che c'è, e le spiegazioni
   tornano visibili come nella lastra: è esattamente quello che si è venuti a
   leggere. */
.lente-corpo .card, .lente-corpo .piano {
  border: 0; background: none; padding: 0; margin: 0; box-shadow: none;
  border-radius: 0; overflow: visible;
}
.lente-corpo .chart-box { height: min(58vh, 520px); }
.lente-corpo .chart-box.grande { height: min(64vh, 580px); }
.lente-corpo .forma-perche, .lente-corpo .chiosa, .lente-corpo .dv-nota { display: block; }
.lente-corpo .fo-apri { display: none; }
.lente-corpo .ta-disco { width: min(360px, 76%); }
.lente-corpo .cia-anello { height: min(360px, 42vh); }
.lente-corpo .tm-piano { min-height: min(52vh, 460px); }
/* Il disco è vincolato dall'ALTEZZA disponibile, non solo dalla larghezza: ha
   un lato solo, e in una finestra larga milleduecento e alta seicento un
   `min(100%, 520px)` gli fa chiedere cinquecentoventi pixel di altezza che non
   ci sono — e la forma finisce sotto il bordo. */
.lente-corpo .sb-piano { width: min(100%, 520px, 52vh); }
.lente-corpo .sk-piano { height: min(52vh, 460px); }
.lente-corpo .ig { min-height: min(46vh, 400px); }
/* Una forma aperta nella lente non si riapre dentro se stessa. */
.lente-corpo .fo[data-lente] { cursor: default; }
/* E una cella del territorio, qui dentro, non è più un comando: il dettaglio
   del comune si aprirebbe SOTTO la finestra che si sta guardando. Resta la
   luce al passaggio — un mosaico risponde accendendosi (§38.3) — e le cifre
   finiscono nella riga di lettura, dove non coprono la mappa. */
.lente-corpo .terr-cella { cursor: default; }

/* La testata della lente arriva dopo la scatola, come quella della lastra:
   mentre la scatola cresce il contenuto è ancora trasparente, e la testata si
   posa a finestra quasi ferma. E le forme dentro aspettano il pannello, o si
   spenderebbe l'animazione di una torta mentre la torta è larga sessanta
   pixel. */
[data-moto="si"] .lente.aperta .lente-testa {
  animation: moto-sale var(--t-stato) var(--ease-out) 140ms backwards;
}
[data-moto="si"] .lente-corpo { --moto-base: 170ms; }

/* ------------------------------------------- 39.3 · GLI SPICCHI CHE ESCONO
   Un `conic-gradient` è una pittura: non ha spicchi, ha una tinta che cambia
   a certi angoli. Gli spicchi veri stanno in un SVG sopra il disco,
   trasparenti finché nessuno li tocca — così il disco resta lui a portare la
   forma a riposo, con il suo ingresso a lancetta della §38.2, e questo strato
   è soltanto la risposta al gesto.

   Lo spicchio ESCE lungo la propria bisettrice: una rotazione, un passo, la
   rotazione all'indietro. Tre unità su cento, cioè nove pixel su un disco da
   trecento: si legge come «questo, non quello» e non come un'esplosione. E
   non c'è nessuno spostamento d'impaginato — l'SVG ha `overflow: visible` e
   sta sopra, quindi niente intorno si muove di un pixel. */
.ta-anello {
  position: relative;
  width: min(300px, 100%);
  aspect-ratio: 1;
  align-self: center;
}
.ta-anello > .ta-disco { width: 100%; align-self: auto; }

.fe {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  overflow: visible;
  pointer-events: none;
}
/* Il bersaglio è il GRUPPO — lo spicchio più la sua percentuale — non il solo
   tracciato: quando la fetta esce deve uscire con la cifra addosso, e due
   fratelli con due trasformazioni uguali si disallineano al primo
   arrotondamento. Un gruppo si muove intero. */
.fe-g {
  pointer-events: auto;
  transform-box: view-box;
  transform-origin: 50% 50%;
  cursor: default;
  transition: transform var(--t-fetta) var(--ease-out),
              filter var(--t-fetta) var(--ease-out);
}
.fe-f {
  fill: var(--seq-3);
  fill-opacity: 0;
  transition: fill-opacity var(--t-fetta) var(--ease-out);
}
.fe-f.g0 { fill: var(--seq-1); }
.fe-f.g1 { fill: var(--seq-2); }
.fe-f.g2 { fill: var(--seq-3); }
.fe-f.g3 { fill: var(--seq-4); }
.fe-f.g4 { fill: var(--seq-5); }
.fe-f.g-1 { fill: var(--coda); }
.fe-g:hover .fe-f { fill-opacity: 1; }
.fe-g:hover {
  /* LA FETTA CRESCE, NON ESCE.

     Uscire lungo la bisettrice apriva uno spicchio di vuoto nella torta, e
     quel vuoto ha una larghezza: fra due fette staccate l'occhio misura anche
     l'aria in mezzo, che non e' un dato. Crescendo dal centro del disco la
     fetta resta attaccata alle vicine — gli angoli, che sono l'unica cosa che
     una torta dice, restano confrontabili — e a cambiare e' il RAGGIO, che in
     una torta non porta nessuna informazione ed e' quindi l'unica dimensione
     libera per rispondere a un gesto.

     L'origine e' il centro del disco e non quello dello spicchio: uno spicchio
     che si ingrandisce intorno al proprio baricentro scavalca le vicine. */
  transform: scale(var(--fetta-cresce, 1.06));
  /* Il colore si rinforza appena: è lo stesso pigmento, con più luce. Cambiare
     tinta direbbe che è cambiato il dato. */
  filter: brightness(1.1) saturate(1.06);
}

/* LA PERCENTUALE DENTRO LO SPICCHIO.
   Una torta con la legenda accanto costringe a due letture: si guarda lo
   spicchio, si cerca il colore in legenda, si torna. Dove c'è spazio la cifra
   sta dentro, e la lettura è una sola. Dove non c'è, non si scrive niente —
   due numeri accavallati non si leggono né l'uno né l'altro, ed è il difetto
   classico della torta etichettata. La soglia la decide `forme.ciambella()`. */
.fe-eti {
  font-size: 5.4px;                 /* unità del viewBox: ~16px su un disco da 300 */
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
  fill: var(--seq-ink, var(--seq-ink-chiaro));
  paint-order: stroke;
  transition: opacity var(--t-fetta) var(--ease-out);
}
.fe-eti.ink-scuro { fill: var(--seq-ink, var(--seq-ink-scuro)); }
.fe:has(.fe-g:hover) .fe-g:not(:hover) .fe-eti { opacity: .45; }

/* IL CENTRO NEUTRO, ed è la riga che toglie il difetto peggiore della torta.
   Al centro tutti gli spicchi si toccano: un movimento di due pixel là in
   mezzo passa da una fetta all'altra tre volte, l'animazione riparte a ogni
   passaggio e il grafico sembra rotto. Questo disco intercetta la zona e non
   la assegna a nessuno. `pointer-events: all` perché un riempimento
   trasparente, di suo, il puntatore lo lascia passare. */
.fe-centro {
  fill: transparent;
  pointer-events: all;
  cursor: default;
}
/* Ciò che non si sta guardando si smorza. Il disco dipinto è UNO — non ha
   parti — quindi si smorza tutto e lo spicchio acceso ci sta sopra: il
   risultato a schermo è lo stesso, e costa una proprietà invece di sei nodi. */
.ta-anello:has(.fe-g:hover) > .ta-disco,
.cia-anello:has(.fe-g:hover) > .cia-disco { opacity: var(--sfondo-smorzato); }
.ta-anello > .ta-disco, .cia-anello > .cia-disco {
  transition: opacity var(--t-fetta) var(--ease-out);
}
/* La legenda è la stessa cosa dello spicchio, scritta: si accende con lui. */
.ta-leg li, .cia-leg li {
  transition: color var(--t-stato) var(--ease-out),
              opacity var(--t-stato) var(--ease-out);
}
.ta-leg:has([data-attiva]) li:not([data-attiva]),
.cia-leg:has([data-attiva]) li:not([data-attiva]) { opacity: .45; }
.ta-leg li[data-attiva], .cia-leg li[data-attiva] { color: var(--text); }
.ta-leg li[data-attiva] .ta-v, .cia-leg li[data-attiva] .cia-v { color: var(--pri-ink); }
/* Il totale nel buco diventa il valore della fetta: è il posto in cui l'occhio
   sta già guardando, e non ci vuole nessun cartellino per arrivarci. */
.cia-mezzo { transition: color var(--t-stato) var(--ease-out); }
.cia-mezzo[data-attiva] b { color: var(--pri-ink); }
.cia-mezzo[data-attiva] em { color: var(--text); }

/* ---------------------------------------------------- 39.4 · IL SUNBURST
   Due anelli concentrici: la famiglia canonica dentro, le tipologie
   dell'anagrafica che le appartengono fuori. Il colore è la famiglia — lo
   stesso posto nell'ordine che porta nell'anello e nella torta — e il `--tono`
   distingue due tipologie vicine della stessa famiglia senza cambiare
   famiglia di colore: quattro passi e poi ricomincia, perché oltre il quarto
   la differenza non si vede più e il colore direbbe il falso. */
/* LA TASSONOMIA: LA FORMA A DESTRA, LA LEGENDA IN COLONNA A SINISTRA.

   In colonna unica la legenda finiva SOTTO il disco, larga quanto la pagina e
   spezzata in cinque colonne di due righe: dodici voci sparse su una griglia
   che non aveva niente a che vedere con l'ordine degli spicchi, e per
   ritrovare una voce bisognava rileggerla tutta. Di fianco, in colonna sola,
   la legenda torna un ELENCO — si scorre dall'alto in basso nello stesso
   ordine in cui gli spicchi girano — e il disco si prende l'altezza che ha
   sempre voluto invece di dividerla con lei.

   Le briciole restano sopra la legenda, dove si preme per risalire; la
   didascalia sotto attraversa tutte e due le colonne, perche' parla della
   forma intera. */
/* IL DISCO A SINISTRA, L'ELENCO A DESTRA. Erano al contrario, e al contrario
   si legge male per una ragione che non ha niente a che vedere col gusto: la
   forma e' il soggetto e l'elenco e' la sua didascalia, e in una lingua che si
   legge da sinistra il soggetto viene prima. Le briciole restano attaccate
   all'elenco, sopra, perche' e' li' che si preme per risalire. */
.sb {
  margin: 0;
  display: grid;
  /* Le due colonne SI STRINGONO sul contenuto invece di spartirsi la riga.
     Con `1fr` la colonna della forma prendeva tutto lo spazio avanzato e il
     disco ci galleggiava in mezzo: la legenda finiva all'altro capo della
     pagina, staccata dalla corona che nomina — e la distanza fra i due non
     diceva niente, era solo l'avanzo. */
  grid-template-columns: minmax(0, 420px) minmax(150px, 250px);
  justify-content: start;
  grid-template-areas:
    "titolo titolo"
    "forma  briciole"
    "forma  legenda";
  grid-template-rows: auto auto 1fr;
  align-items: start;
  gap: var(--sp-3) var(--sp-5);
}
.sb-t { grid-area: titolo; }
.sb-briciole { grid-area: briciole; }
.sb-piano { grid-area: forma; }
.sb-leg { grid-area: legenda; }
/* Sotto i mille pixel le due colonne non ci stanno: si torna alla pila, con
   la forma sopra e l'elenco sotto — che e' l'ordine in cui si leggono quando
   non si possono guardare insieme. */
@media (max-width: 1000px) {
  .sb {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "titolo" "briciole" "forma" "legenda";
    grid-template-rows: auto auto auto auto;
  }
}
.sb-t {
  font-size: var(--fs-2); font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted);
}
.sb-briciole { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.sb-briciola {
  padding: 2px 9px;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  color: var(--muted);
  font: inherit; font-size: var(--fs-1);
  cursor: pointer;
  transition: color var(--t-stato) var(--ease-out),
              border-color var(--t-stato) var(--ease-out),
              background-color var(--t-stato) var(--ease-out);
}
.sb-briciola:hover { color: var(--text); border-color: var(--border); }
.sb-briciola[aria-current="true"] {
  color: var(--text); background: var(--surface-2); border-color: var(--border);
}
.sb-briciola + .sb-briciola::before {
  content: "›"; margin-right: 8px; color: var(--muted); opacity: .6;
}
.sb-piano {
  position: relative;
  width: min(100%, 460px);
  aspect-ratio: 1;
  justify-self: center;
  align-self: center;
}
.sb-tela { width: 100%; height: 100%; display: block; overflow: visible; }
/* La vista nascosta si dichiara qui e non si affida al foglio dell'agente
   utente: `[hidden]` è una regola scritta per gli elementi HTML, e questo è un
   gruppo SVG. Dichiararla costa una riga e toglie un dubbio. */
.sb-vista[hidden] { display: none; }
.sb-arco {
  fill: var(--seq-3);
  stroke: var(--surface);
  stroke-width: .5;
  transform-box: view-box;
  transform-origin: 50% 50%;
  cursor: default;
  transition: transform var(--t-fetta) var(--ease-out),
              filter var(--t-fetta) var(--ease-out),
              opacity var(--t-fetta) var(--ease-out);
}
.sb-arco.g0 { fill: var(--seq-1); }
.sb-arco.g1 { fill: var(--seq-2); }
.sb-arco.g2 { fill: var(--seq-3); }
.sb-arco.g3 { fill: var(--seq-4); }
.sb-arco.g4 { fill: var(--seq-5); }
.sb-arco.g-1 { fill: var(--seq-0); }
/* La corona esterna è la stessa famiglia vista da più lontano: stessa tinta,
   un velo in meno a ogni passo. */
.sb-l2 { opacity: calc(1 - var(--tono, 0) * .15); }
.sb-arco[data-sb-apre] { cursor: zoom-in; }
.sb-vista:has([data-attiva]) .sb-arco:not([data-attiva]) { opacity: var(--sfondo-smorzato); }

.sb-mezzo {
  position: absolute;
  inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  line-height: 1.1;
  pointer-events: none;
  padding: 0 22%;
}
.sb-mezzo b {
  font-size: var(--fs-6); font-weight: 600; font-variant-numeric: tabular-nums;
  transition: color var(--t-stato) var(--ease-out);
}
.sb-mezzo em {
  font-style: normal; font-size: var(--fs-1); color: var(--muted);
  line-height: 1.2; margin-top: 2px;
}
.sb-mezzo span {
  font-size: var(--fs-0); color: var(--muted); margin-top: 3px;
  font-variant-numeric: tabular-nums;
}
.sb-mezzo[data-attiva] b { color: var(--pri-ink); }
.sb-mezzo[data-attiva] em { color: var(--text); }
/* La coda nelle legende delle composizioni: stesso neutro del suo spicchio.
   Solo qui — nella matrice e nel treemap `.g-1` continua a voler dire «vuoto»,
   che là è esattamente quello che è. */
.ta-leg .g-1, .cia-leg .g-1, .sb-leg .g-1, .bn-leg .g-1 { background: var(--coda); }

/* La legenda del sunburst. Nel cerchio i nomi non ci stanno — «Rustici e
   poderi» dentro un arco è una scritta curva e minuscola — e un grafico che a
   riposo dice soltanto «206 immobili» non dice niente. Qui i nomi sono testo
   vero: si leggono a qualunque zoom, escono nella stampa, e si accendono
   insieme al loro arco. Ce n'è una per vista, e cambia con la discesa. */
.sb-leg {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  /* Una colonna sola: e' un elenco, e un elenco si scorre. */
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  align-self: stretch;
}
@media (max-width: 1000px) {
  .sb-leg { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 1px 18px; }
}
/* `center` e non `baseline`. Con l'allineamento alla linea di base il testo si
   appoggiava in cima alla riga e il pallino — che una linea di base non ce
   l'ha, ed era quindi centrato — finiva quattro pixel piu' in basso: misurati,
   centro del testo a 6,2 px dall'alto della riga, centro del pallino a 10,4.
   Quattro pixel su una riga da ventuno si vedono, e si vedono dieci volte di
   fila. Centrati tutti e due, i due centri coincidono. */
.sb-leg li {
  display: grid;
  grid-template-columns: 9px 1fr auto auto;
  align-items: center; gap: 8px;
  font-size: var(--fs-2); padding: 2px 0;
  transition: color var(--t-stato) var(--ease-out),
              opacity var(--t-stato) var(--ease-out);
}
.sb-leg i { width: 9px; height: 9px; border-radius: 2px; align-self: center; }
.sb-n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-v { font-variant-numeric: tabular-nums; font-weight: 600; }
.sb-q {
  font-variant-numeric: tabular-nums; color: var(--muted);
  font-size: var(--fs-1); min-width: 40px; text-align: right;
}
.sb-leg:has([data-attiva]) li:not([data-attiva]) { opacity: .45; }
.sb-leg li[data-attiva] { color: var(--text); }
.sb-leg li[data-attiva] .sb-v { color: var(--pri-ink); }
/* La cifra che ha preso il posto della spiegazione: quante tipologie ci sono
   in tutto. La corona ne mostra una famiglia alla volta, quindi il totale e'
   proprio la cosa che la forma non puo' dire. Non usa il componente `.misura`,
   che in questo foglio e' un'altra cosa — la riga con il filo tratteggiato
   dell'anello delle decisioni — e portava qui un bordo che non significava
   niente. */
.sb-conta {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-2);
  color: var(--muted);
}
.sb-conta b {
  color: var(--text);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  margin-right: 5px;
}

/* Il posto delle quattro misure uscite dalla tassonomia. Non e' un vuoto
   dimenticato: e' il respiro che c'era fra la forma e le tabelle, e che senza
   di lui le attaccherebbe l'una alle altre. */
.misure-via { height: var(--sp-5); }

/* La vista che arriva si compone davanti a chi guarda: si scopre in senso
   orario, come si legge un disco, ed è la stessa animazione della torta —
   perché è la stessa cosa che succede. */
@keyframes moto-sb { from { --rivela: 0turn; opacity: .4; } }
[data-moto="si"] .sb-vista.sb-entra {
  --rivela: 1turn;
  mask-image: conic-gradient(#000 var(--rivela), transparent 0);
  animation: moto-sb var(--t-lente) var(--ease-io) backwards;
}

/* ------------------------------------------------------- 39.5 · IL SANKEY
   I nastri sono AREE riempite e non tratti: con un tratto, lo spessore si
   deformerebbe in modo diverso dai nodi quando il riquadro non è quadrato — e
   il riquadro non è mai quadrato. I nodi e le loro etichette restano testo
   vero, collocato in percentuale sopra l'SVG. */
.sk { margin: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.sk-tappe {
  display: flex; justify-content: space-between;
  font-size: var(--fs-0); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--muted);
}
.sk-tappe span:last-child { text-align: right; }
.sk-piano { position: relative; height: 300px; min-height: 220px; }
.sk-nastri { position: absolute; inset: 0; width: 100%; height: 100%; }
.sk-nastro {
  fill: var(--seq-2);
  fill-opacity: .3;
  transition: fill-opacity var(--t-stato) var(--ease-out);
}
/* Il ramo del triage — alta visibilità, conversione debole — è l'unico che
   porta un colore proprio: è il gruppo su cui la pagina chiede di intervenire,
   e la tabella accanto lo elenca uno per uno. */
.sk-nastro.sk-segnalato { fill: var(--chart-segnalato); fill-opacity: .34; }
.sk[data-focus] .sk-nastro { fill-opacity: .1; }
.sk[data-focus] .sk-nastro[data-attiva] { fill-opacity: .62; }
.sk-nodo {
  position: absolute;
  border-radius: 2px;
  cursor: default;
  transition: filter var(--t-stato) var(--ease-out),
              opacity var(--t-stato) var(--ease-out);
}
.sk-nodo.sk-terminale { border-radius: 2px; }
.sk[data-focus] .sk-nodo { opacity: var(--sfondo-smorzato); }
.sk[data-focus] .sk-nodo[data-attiva] { opacity: 1; filter: brightness(1.12); }
.sk-nome {
  position: absolute;
  display: flex; flex-direction: column; justify-content: center;
  transform: translateX(8px);
  max-width: 26%;
  pointer-events: none;
  line-height: 1.15;
  transition: opacity var(--t-stato) var(--ease-out);
}
/* L'ultima colonna tocca il bordo destro: il suo nome sta a sinistra del nodo,
   o uscirebbe dal riquadro. */
.sk-nome-fine { transform: translateX(-100%) translateX(-8px); align-items: flex-end; text-align: right; }
/* L'ultima tappa non finisce sotto il comando che apre la forma. */
.sk-tappe span:last-child { padding-right: 30px; }
.sk-nome b { font-size: var(--fs-3); font-variant-numeric: tabular-nums; }
.sk-nome em { font-style: normal; font-size: var(--fs-1); color: var(--muted); }
.sk[data-focus] .sk-nome { opacity: .4; }
.sk[data-focus] .sk-nome[data-attiva] { opacity: 1; }
.sk[data-focus] .sk-nome[data-attiva] em { color: var(--text); }
.sk-sotto {
  display: flex; flex-direction: column; gap: 4px;
  font-size: var(--fs-1); color: var(--muted); line-height: var(--lh-cell);
}
.sk-letto { color: var(--text); font-size: var(--fs-2); }

/* I nastri si scoprono da sinistra a destra: è il verso in cui il portafoglio
   attraversa il diagramma, e una volta sola per comparsa. */
@keyframes moto-nastri { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
[data-moto="si"] .sk-nastri {
  animation: moto-nastri var(--t-forma) var(--ease-out) backwards;
  animation-delay: var(--moto-base, 0ms);
}
[data-moto="si"] .sk-nodo {
  animation: moto-appare var(--t-stato) var(--ease-out) backwards;
  animation-delay: calc(var(--moto-base, 0ms) + min(sibling-index() - 1, 8) * 26ms);
}
[data-moto="si"] .sk-nome {
  animation: moto-appare var(--t-stato) var(--ease-out) backwards;
  animation-delay: calc(var(--moto-base, 0ms) + var(--t-forma) * .55);
}

/* -------------------------------------- 39.6 · LA MATRICE — l'incrocio letto
   Una cella accesa dice «tanti» e non dice DI CHE COSA: per saperlo bisogna
   risalire con l'occhio alla riga e scendere alla colonna, e su nove righe per
   otto colonne l'occhio si perde a metà strada. La croce lo fa da sé. */
.mx td, .mx th { transition: opacity var(--t-stato) var(--ease-out),
                             filter var(--t-stato) var(--ease-out),
                             color var(--t-stato) var(--ease-out); }
.mx[data-focus] td.mx-c { opacity: .42; }
.mx[data-focus] td.mx-c[data-attiva] { opacity: 1; filter: brightness(1.14); }
.mx[data-focus] th { color: color-mix(in srgb, var(--muted) 60%, transparent); }
.mx[data-focus] th[data-attiva] { color: var(--pri-ink); }
.mx-letto {
  display: block; margin-top: 4px;
  font-size: var(--fs-2); color: var(--text);
  font-variant-numeric: tabular-nums; min-height: 1.3em;
}

/* ---------------------------- 39.7 · LE COLONNE E LE RIGHE CHE RISPONDONO
   L'istogramma, la distribuzione, il divario e il movimento hanno già il loro
   ingresso nella §38.2. Qui manca solo la risposta al puntatore, e vale una
   regola sola: si accende quella sotto il dito, si smorzano le altre, e NIENTE
   SI SPOSTA. Una colonna che cresce sotto il puntatore mentirebbe sulla
   propria altezza, che è il solo dato che porta. */
.ig-col, .ds-riga, .dv-riga, .mv-riga, .iv-riga { transition: opacity var(--t-stato) var(--ease-out); }
.ig:hover .ig-col:not(:hover),
.ds:hover .ds-riga:not(:hover),
.dv:hover .dv-riga:not(:hover),
.mv:hover .mv-riga:not(:hover),
.iv:hover .iv-riga:not(:hover) { opacity: .5; }
.ig-pista i, .ds-pista i, .cl-pista i {
  transition: filter var(--t-stato) var(--ease-out);
}
.ig-col:hover .ig-pista i,
.ds-riga:hover .ds-pista i { filter: brightness(1.16); }
.ig-col:hover .ig-v, .ds-riga:hover .ds-v { color: var(--pri-ink); }

/* Il divario — la domanda lungo il prezzo — e le sue due parenti, il
   movimento fra i due export e i quartili per zona.

   Non avevano un ingresso proprio: la riga saliva e il segno era già lì,
   intero. Adesso il segmento si apre dal suo estremo SINISTRO — che è il
   minore delle due quote, cioè il punto da cui lo scarto si misura — e i due
   pallini si posano dopo, quando la distanza fra loro è già disegnata. È lo
   stesso ordine delle barre della §38.2: prima si vede che riga è, poi quanto
   vale.

   Non è una deroga alla regola sul dato: la lunghezza finale è quella del
   server e la cifra dello scarto è scritta accanto dal primo fotogramma.
   Quello che si muove è il modo di disegnare il segmento, non il suo valore. */
[data-moto="si"] .dv-seg {
  transform-origin: left center;
  animation: moto-allunga var(--t-forma) var(--ease-out) backwards;
  animation-delay: calc(var(--ritardo, 0ms) + 90ms);
}
[data-moto="si"] :is(.dv-p, .mv-p, .iv-med) {
  animation: moto-appare var(--t-stato) var(--ease-out) backwards;
  animation-delay: calc(var(--ritardo, 0ms) + 190ms);
}
[data-moto="si"] .mv-seg {
  transform-origin: left center;
  animation: moto-allunga var(--t-forma) var(--ease-out) backwards;
  animation-delay: calc(var(--ritardo, 0ms) + 90ms);
}
[data-moto="si"] :is(.iv-baffo, .iv-box) {
  transform-origin: left center;
  animation: moto-allunga var(--t-forma) var(--ease-out) backwards;
  animation-delay: calc(var(--ritardo, 0ms) + 90ms);
}
/* Ciò che sta morfando non entra: vale qui come nella §38.2 — la riga era già
   lì un attimo fa, e farla ricomparire cancellerebbe proprio il confronto. */
[data-moto="si"] [data-morfa] :is(.dv-seg, .dv-p, .mv-seg, .mv-p, .iv-baffo, .iv-box, .iv-med) {
  animation: none;
}

/* ------------------------------------------------- 39.8 · CIÒ CHE RESTA FERMO
   · lo zoom NON esiste su una torta, su un anello, su un sunburst e sul
     sankey. Sei spicchi, due anelli e otto nodi si leggono interi: un comando
     in più su una forma che non ne ha bisogno è un comando da capire in
     cambio di niente. Lo zoom sta dove i segni sono tanti e piccoli — il
     treemap, la matrice, il territorio, le tre tele.
   · le colonne e le righe NON si ingrandiscono sotto il puntatore. Una
     colonna che cresce mente sulla propria altezza, che è il dato.
   · i nastri del sankey NON si muovono all'entrata di un nodo: cambiano
     opacità e basta. Un ramo che si sposta farebbe sembrare cambiato il ramo.
   · la lettura sotto la lente NON segue il puntatore. Un cartellino che
     insegue copre proprio la cella accanto a quella che si vuole confrontare.

   ------------------------------------------------- e con il moto ridotto
   Cade lo spostamento, restano lo stato e il colore: lo spicchio non esce ma
   si accende, la vista del sunburst cambia senza scoprirsi, la finestra
   compare senza crescere (`lente.js` lo decide leggendo `data-moto`). Ogni
   informazione che il movimento porta resta raggiungibile: era la promessa
   della §38.10 e vale identica qui. */
[data-moto="no"] .fe-f { transition: fill-opacity var(--t-pressione) linear; }
[data-moto="no"] .fe-g { transition: none; }
[data-moto="no"] .fe-g:hover { transform: none; }
[data-moto="no"] .sb-arco { transition: opacity var(--t-pressione) linear; }
[data-moto="no"] .sb-arco[data-attiva] { transform: none; }
[data-moto="no"] .sb-vista.sb-entra { animation: none; mask-image: none; }

/* In stampa nessuno di questi strati esiste: la lente è una finestra, e una
   finestra non si stampa. Le forme sotto restano quelle di sempre. */
@media print {
  /* La finestra, il comando che la apre e lo strato che risponde al puntatore
     non esistono sulla carta: sono tutti e tre interazione, non disegno. */
  .lente, .lente-velo, .fo-apri, .fe, .sugg { display: none !important; }
  /* E niente resta smorzato per un puntatore che sul foglio non c'è. La messa
     a fuoco è di chi guarda lo schermo, non del documento: un foglio stampato
     mentre il mouse stava su un ramo del sankey uscirebbe con gli altri otto
     al trentaquattro per cento. */
  .sk-nastro, .sk-nodo, .sk-nome, .mx td, .mx th, .sb-arco,
  .ta-leg li, .cia-leg li, .sb-leg li,
  .ig-col, .ds-riga, .dv-riga, .mv-riga, .iv-riga {
    opacity: 1 !important;
    filter: none !important;
  }
}

/* ============================ 40 · PUBLISHER ==============================
   Il banco di composizione di un contenuto social. Tre colonne, e sono i tre
   momenti del lavoro: si guarda il media, si scrive quello che lo accompagna,
   si decide che cosa farne canale per canale.

   QUATTRO REGOLE, e nessuna è di gusto.

   1. NIENTE SCATOLA DENTRO SCATOLA. Le tre colonne non hanno un fondo: sono
      `.piano`, cioè stanno sulla pagina, e il loro confine è il filo sotto la
      testata. Il fondo lo prendono soltanto le cose che si TOCCANO — la tela
      dei media, che è una superficie di lavoro, e il riepilogo.

   2. LE PROPORZIONI SONO UNA GERARCHIA, E SONO CAMBIATE. Erano 36/40/24;
      adesso sono 30/40/30. Il motivo sta in che cosa contengono davvero oggi:
      la colonna dei media non ha più un elenco di righe con nomi di file
      lunghi — ha UNA tela, che sta comoda anche stretta perché il formato
      social è verticale — mentre la colonna delle decisioni ha tre comandi
      affiancati per canale più data, ora, fuso e limitazione, e in 24 parti
      su cento quei comandi andavano a capo uno sotto l'altro.

   3. UNA TELA, NON QUATTRO RIQUADRI. Zona di rilascio, elenco, riquadro del
      video e sezione della copertina erano quattro superfici impilate, e ogni
      superficie diceva a parole quello che la successiva mostrava. Adesso è
      una sola: vuota è l'invito e il bersaglio, piena è l'anteprima vera, e
      la copertina è un telaio in miniatura appoggiato sopra — perché la
      copertina appartiene al video che le sta dietro, e la sua posizione lo
      dichiara senza scriverlo.

   4. NIENTE CHE PROMETTA QUELLO CHE NON C'È. Le pastiglie di stato dei cinque
      canali usano `chip-previsto`, che è la stessa pastiglia spenta dei canali
      non collegati in Sorgenti. Non esiste in questa sezione un verde che
      significhi «pubblicato» finché non lo dice il registro.

   Quello che NON c'è più, e non per distrazione: la carta che imitava un post
   di Instagram. Somigliava alla piattaforma quanto bastava a essere creduta e
   non abbastanza a essere giusta — ritaglio, caratteri e interfaccia cambiano
   quando vogliono — e occupava il terzo centrale della colonna in cui si
   scrive. Lo spazio è tornato alla descrizione e all'automazione.
   ========================================================================== */

/* Le dichiarazioni oneste della pagina d'elenco: prosa, quindi una misura di
   riga da prosa. Larghe quanto la pagina si leggono male, e una limitazione
   che non si legge è una limitazione nascosta con un altro mezzo. */
.pub-dichiarazione { max-width: 96ch; line-height: var(--lh-body); }
.pub-dichiarazione + .pub-dichiarazione { margin-top: var(--sp-3); }

.pub-testa { align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.pub-indietro { font-size: var(--fs-2); color: var(--muted); text-decoration: none; }
.pub-titolo { flex: 1 1 280px; min-width: 220px; }
.pub-titolo input {
  width: 100%;
  font: 650 var(--fs-6) / var(--lh-head) var(--font-ui);
  letter-spacing: -0.02em;
  background: transparent; border-color: transparent;
  padding: var(--sp-1) var(--sp-2);
}
.pub-titolo input:hover { border-color: var(--border); }
.pub-titolo input:focus { background: var(--surface-2); }
.pub-salvato {
  margin-left: auto; font-family: var(--font-mono); font-size: var(--fs-1);
  white-space: nowrap;
}
/* Il salvataggio riuscito si conferma con un tocco di luce sulla parola, non
   con un'icona che compare e sparisce: la parola c'è già, e cambiare colore a
   una parola che si sta leggendo è il modo più breve di dire «fatto». */
.pub-salvato.pub-fatto { color: var(--ok); }
:root[data-moto="si"] .pub-salvato {
  transition: color var(--t-stato) var(--ease-out);
}

/* --- il banco ----------------------------------------------------------- */
.pub-banco {
  display: grid;
  grid-template-columns: minmax(0, 30fr) minmax(0, 40fr) minmax(0, 30fr);
  gap: var(--sp-7);
  align-items: start;
  margin-top: var(--sp-5);
}
.pub-col { min-width: 0; }
/* La colonna delle decisioni NON è appiccicata, e prima lo era per finta: una
   `position: sticky` su un elemento più alto della finestra scorre via come se
   non l'avesse, e «Salva bozza» finiva novecento pixel sotto il bordo. Si
   ferma invece la cosa che deve restare a portata: i due comandi. */
.pub-azioni {
  position: sticky; bottom: 0; z-index: 2;
  margin-top: var(--sp-4);
  padding: var(--sp-4) 0;
  background: var(--bg);
  border-top: 1px solid var(--border);
}

/* La testata di colonna: il titolo e, all'altro capo, la misura corrente.
   Il filo sotto è il confine della colonna — l'unico che ha. */
.pub-col-testa {
  display: flex; align-items: baseline; gap: var(--sp-2) var(--sp-3);
  flex-wrap: wrap;
  padding-bottom: var(--sp-3); margin-bottom: var(--sp-4);
  border-bottom: 1px solid var(--border);
}
.pub-col-testa h2 { margin: 0; font-size: var(--fs-5); }
/* La misura sta a destra del titolo finché ci sta. Quando non ci sta — «1
   subito · 2 programmati · 2 in bozza» in una colonna da trecento pixel — va a
   capo INTERA e si allinea a sinistra, invece di spezzarsi in tre righe che
   schiacciano il titolo contro il bordo. */
.pub-conta {
  margin: 0 0 0 auto; text-align: right;
  font-size: var(--fs-1); color: var(--muted);
  font-family: var(--font-mono);
}
/* Lo stato misto NON è un contatore accanto a un titolo: è una frase, ed è la
   frase che si legge prima di premere «Pubblica». Sta sopra i cinque canali, a
   tutta larghezza, dove non deve spezzarsi in tre righe per entrare. */
.pub-sommario {
  margin: 0 0 var(--sp-3);
  padding-left: var(--sp-3);
  border-left: 1px solid var(--accent-line);
  font-size: var(--fs-2); color: var(--muted); line-height: var(--lh-body);
}
.pub-sommario b { color: var(--text); font-weight: 650; }
.pub-conta b { color: var(--text); font-weight: 650; }

/* ========================== 1 · LA TELA DEI MEDIA ========================
   Il formato del telaio segue le misure VERE del media, dichiarate in
   `--pub-forma` dal JavaScript: 9/16 per un verticale, 4/5 per un quadrato o
   una foto da feed, 16/9 per un orizzontale. Dentro, il file è sempre
   `contain`: non si ritaglia e non si stira niente per far tornare
   un'anteprima. Il solo ritaglio di tutta la pagina è quello della miniatura
   di copertina, e là c'è scritto che c'è. */
.pub-tela {
  position: relative;
  aspect-ratio: var(--pub-forma, 4 / 5);
  border-radius: var(--r-3);
  border: 1px solid var(--border);
  background: var(--surface-2);
  overflow: hidden;
  display: grid;
}
/* Il rilascio: il bordo si fa accento e il fondo si scalda. Non c'è nessuno
   spostamento — la tela è grande, e una superficie che si solleva sotto un
   file trascinato sposta il bersaglio proprio mentre lo si mira. */
.pub-tela.pub-sopra {
  border-color: var(--data);
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--data);
}
:root[data-moto="si"] .pub-tela {
  transition: border-color var(--t-stato) var(--ease-out),
              background var(--t-stato) var(--ease-out),
              box-shadow var(--t-stato) var(--ease-out);
}

/* Lo stato vuoto È il comando: tutta la superficie apre il selettore. */
.pub-tela-vuoto {
  grid-area: 1 / 1;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--sp-3);
  width: 100%; height: 100%;
  padding: var(--sp-5);
  background: none; border: 0; cursor: pointer;
  color: var(--muted); font: inherit; text-align: center;
}
.pub-tela-segno {
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 22px; line-height: 1;
  color: var(--muted);
  border: 1px dashed var(--border-strong);
}
.pub-tela-invito {
  font: 650 var(--fs-4) / var(--lh-head) var(--font-ui);
  color: var(--text);
}
.pub-tela-formati {
  font-size: var(--fs-1); line-height: 1.7; color: var(--dim);
}
.pub-tela-vuoto:hover .pub-tela-segno,
.pub-tela-vuoto:focus-visible .pub-tela-segno {
  color: var(--pri-ink); border-color: var(--data); border-style: solid;
}
.pub-tela-vuoto:focus-visible { outline: 2px solid var(--pri-ink); outline-offset: -4px; }
:root[data-moto="si"] .pub-tela-segno {
  transition: color var(--t-stato) var(--ease-out),
              border-color var(--t-stato) var(--ease-out);
}

/* La scena: il media vero, contenuto e mai stirato. */
.pub-scena {
  grid-area: 1 / 1;
  display: grid; place-items: center;
  width: 100%; height: 100%;
  background: #000;
  min-width: 0; min-height: 0;
}
.pub-scena video, .pub-scena img {
  max-width: 100%; max-height: 100%;
  width: 100%; height: 100%;
  object-fit: contain;
  display: block;
}

/* Il comando che aggiunge, quando la tela è già piena. Sta in alto a destra,
   lontano dai comandi del video e dalla copertina. */
.pub-tela-piu {
  position: absolute; top: var(--sp-3); right: var(--sp-3); z-index: 3;
  width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 17px; line-height: 1;
  color: #fff; background: rgba(0, 0, 0, .55);
  border: 1px solid rgba(255, 255, 255, .28);
  backdrop-filter: blur(6px);
  cursor: pointer;
}
.pub-tela-piu:hover { background: var(--pri-fill-h); border-color: transparent; color: var(--on-pri-fill); }
.pub-tela-piu:focus-visible { outline: 2px solid var(--pri-ink); outline-offset: 2px; }

/* IL FONDO DELLA TELA APPARTIENE AL VIDEO.
   La barra dei comandi di un `<video>` è disegnata dal browser, occupa una
   striscia in basso che non si può spostare e non si può sovrapporre: la
   copertina e il comando del fotogramma le finivano sopra, e per mettere in
   pausa bisognava mirare fra due riquadri. Quando c'è un video, i due strati
   salgono di quanto serve. Quaranta pixel più il respiro: è la misura della
   barra nei browser che questa pagina incontra. */
.pub-tela[data-media="video"] { --pub-fondo: 52px; }

/* Il secondo del video e il comando che ne fa una copertina: stanno sul
   video, in basso a destra, cioè dove si sta già guardando quando si sceglie
   un fotogramma. */
.pub-tela-tempo {
  position: absolute; right: var(--sp-3);
  bottom: calc(var(--sp-3) + var(--pub-fondo, 0px)); z-index: 3;
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2);
  border-radius: var(--r-2);
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(6px);
}
.pub-tela-tempo .btn-ghost {
  color: #fff; border-color: rgba(255, 255, 255, .34); background: transparent;
}
.pub-tela-tempo .btn-ghost:hover { border-color: var(--data); color: var(--pri-ink); }
.pub-tela-tempo .mono { font-size: var(--fs-1); color: rgba(255, 255, 255, .82); }

/* --------------------------- la copertina -------------------------------
   Un telaio in miniatura, appoggiato in basso a sinistra della tela. Il suo
   formato segue quello in cui la copertina verrà usata — 9:16 per un video
   verticale, 4:5 per un contenuto da feed — e la miniatura è ritagliata per
   riempirlo: è l'unico ritaglio della pagina, e la riga di lettura sotto la
   tela lo dichiara. L'originale non viene toccato. */
.pub-cop {
  position: absolute; left: var(--sp-3);
  bottom: calc(var(--sp-3) + var(--pub-fondo, 0px)); z-index: 4;
  width: clamp(58px, 26%, 92px);
}
/* Su una tela vuota una copertina non ha niente da coprire: offrirla lì è un
   comando che chiede di scegliere la miniatura di un video che non esiste. */
.pub-tela[data-stato="vuota"] .pub-cop { display: none; }
.pub-cop-quadro {
  position: relative; display: block;
  width: 100%; aspect-ratio: var(--pub-cop-forma, 9 / 16);
  padding: 0; overflow: hidden;
  border-radius: var(--r-2);
  border: 1px solid rgba(255, 255, 255, .34);
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(6px);
  color: #fff; font: 600 var(--fs-0) / 1.3 var(--font-ui);
  cursor: pointer;
  box-shadow: 0 8px 20px -10px rgba(0, 0, 0, .8);
}
.pub-cop-quadro:hover { border-color: var(--data); }
.pub-cop-quadro:focus-visible { outline: 2px solid var(--pri-ink); outline-offset: 2px; }
.pub-cop-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pub-cop-eti {
  position: absolute; inset: 0;
  display: grid; place-items: center; padding: var(--sp-1);
  text-align: center;
}
/* Con una copertina, l'etichetta resta solo come velo al passaggio: la
   miniatura è l'informazione, la parola è il comando. */
.pub-cop[data-stato="scelta"] .pub-cop-eti {
  opacity: 0; background: rgba(0, 0, 0, .6);
}
.pub-cop[data-stato="scelta"] .pub-cop-quadro:hover .pub-cop-eti,
.pub-cop[data-stato="scelta"] .pub-cop-quadro:focus-visible .pub-cop-eti { opacity: 1; }
:root[data-moto="si"] .pub-cop-eti { transition: opacity var(--t-stato) var(--ease-out); }
.pub-cop-via {
  position: absolute; top: -7px; right: -7px; z-index: 1;
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 11px; line-height: 1;
  color: #fff; background: rgba(0, 0, 0, .78);
  border: 1px solid rgba(255, 255, 255, .4);
  cursor: pointer;
}
.pub-cop-via:hover { background: var(--bad); border-color: var(--bad); }
.pub-cop-via:focus-visible { outline: 2px solid var(--pri-ink); outline-offset: 2px; }

/* Il menu della copertina si apre ancorato al telaio, verso l'alto: sotto non
   c'è spazio, e un menu che esce dal fondo della tela sarebbe tagliato. */
.pub-menu {
  position: absolute; left: 0; bottom: calc(100% + var(--sp-2)); z-index: 6;
  min-width: 210px;
  padding: var(--sp-1);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-2);
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, .55);
}
.pub-menu button {
  display: block; width: 100%; text-align: left;
  padding: 7px var(--sp-3);
  background: none; border: 0; border-radius: var(--r-1);
  font: 600 var(--fs-2) / 1.4 var(--font-ui);
  color: var(--text); cursor: pointer;
}
.pub-menu button:hover, .pub-menu button:focus-visible {
  background: var(--surface-2); color: var(--pri-ink); outline: none;
}
.pub-menu button:disabled { color: var(--dim); cursor: not-allowed; background: none; }
.pub-menu button small { display: block; font-weight: 400; color: var(--dim); }
:root[data-moto="si"] .pub-menu {
  animation: pub-menu-entra var(--t-stato) var(--ease-out) backwards;
}
@keyframes pub-menu-entra {
  from { opacity: 0; transform: translateY(4px); }
}

/* --------------------------- il caricamento ------------------------------
   Sta DENTRO la tela, sopra il media che sta arrivando: un caricamento di
   qualche secondo che non mostra niente si legge come un guasto, ed è
   precisamente ciò che accadeva. La barra è l'unica cosa che si muove in
   continuo in tutta la pagina, e si muove perché sta misurando una cosa che
   sta davvero succedendo. */
.pub-carico {
  position: absolute; inset: auto 0 0 0; z-index: 5;
  display: grid; gap: var(--sp-2);
  padding: var(--sp-3);
  background: linear-gradient(to top, rgba(0, 0, 0, .88), rgba(0, 0, 0, .55) 70%, transparent);
  color: #fff;
}
.pub-carico-testa {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--sp-3); margin: 0; min-width: 0;
}
.pub-carico-testa strong {
  font-size: var(--fs-1); font-weight: 650;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pub-carico-testa .mono { font-size: var(--fs-1); color: rgba(255, 255, 255, .8); }
.pub-barra {
  height: 5px; border-radius: var(--r-full);
  background: rgba(255, 255, 255, .22); overflow: hidden;
}
/* La barra cresce con `transform`, non con `width`: un caricamento manda un
   avanzamento a ogni pacchetto, e animare la larghezza vorrebbe dire rifare
   l'impaginazione decine di volte al secondo mentre il browser sta già
   lavorando per spedire. `scaleX` sta sul compositore e non tocca niente. */
.pub-barra > span {
  display: block; height: 100%; width: 100%; border-radius: var(--r-full);
  background: var(--pri);
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--t-stato) var(--ease-out);
}
/* Sotto «riduci il movimento» la barra continua a dire dove sta il
   caricamento, ma ci arriva senza scivolare: l'informazione resta, il moto no. */
:root[data-moto="no"] .pub-barra > span { transition: none; }
.pub-carico-stato { margin: 0; font-size: var(--fs-1); color: rgba(255, 255, 255, .86); }
.pub-carico .btn-ghost {
  justify-self: start;
  color: #fff; border-color: rgba(255, 255, 255, .34); background: transparent;
}
.pub-carico .btn-ghost:hover { border-color: var(--bad); color: var(--bad); }

/* --------------------------- la riga di lettura --------------------------
   Ferma, sotto la tela, e cambia contenuto. È la regola §39 del foglio:
   quello che c'è sotto il puntatore si scrive in un posto solo, non in un
   cartellino che insegue il mouse e copre proprio quello che si confronta. */
.pub-lettura {
  min-height: 3em; margin: var(--sp-2) 0 0;
  font-size: var(--fs-1); line-height: 1.5; color: var(--dim);
  overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.pub-lettura b { color: var(--muted); font-weight: 650; }

.pub-errore {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3);
  margin-top: var(--sp-3);
}

/* ------------------------------- il nastro -------------------------------
   L'ordine del carosello. Si trascina, e si sposta anche con due comandi: un
   ordine che si può stabilire soltanto con il mouse è un ordine che qualcuno
   non può stabilire. */
.pub-nastro {
  list-style: none; margin: var(--sp-4) 0 0; padding: 0 0 var(--sp-2);
  display: flex; gap: var(--sp-2);
  overflow-x: auto; overflow-y: hidden;
}
.pub-nastro:empty { display: none; }
.pub-tessera {
  position: relative; flex: 0 0 auto;
  /* Settantotto e non sessantaquattro: sotto la tessera ci sono tre comandi
     affiancati, e a 64 px ognuno era largo venti — sotto il minimo di 24×24
     che WCAG 2.2 chiede, con il comando che CANCELLA a fianco di quello che
     sposta. La miniatura non aveva bisogno di crescere; i bersagli sì. */
  width: 78px;
  border-radius: var(--r-2);
  border: 1px solid var(--border);
  background: var(--surface-2);
  overflow: hidden;
  cursor: pointer;
}
.pub-tessera-quadro { display: block; width: 100%; aspect-ratio: 4 / 5; }
.pub-tessera img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pub-tessera-video {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  color: var(--muted); font-size: 15px;
}
.pub-tessera-num {
  position: absolute; top: 3px; left: 3px;
  min-width: 15px; padding: 1px 3px;
  border-radius: var(--r-1);
  background: rgba(0, 0, 0, .62); color: #fff;
  font: 650 var(--fs-0) / 1.4 var(--font-mono); text-align: center;
}
.pub-tessera.pub-scelta { border-color: var(--data); box-shadow: inset 0 0 0 1px var(--data); }
/* Un anello solo, e solo per la tastiera: `:focus-within` lo lasciava acceso
   dopo ogni clic (il fuoco resta sul bottone dentro la tessera), sopra il
   bordo della scelta — due bordi fissi che non dicevano niente. */
.pub-tessera:has(:focus-visible) { outline: 2px solid var(--pri-ink); outline-offset: 2px; }
.pub-tessera.pub-presa { opacity: .45; }
.pub-tessera.pub-bersaglio { border-color: var(--data); }
.pub-tessera-cmd {
  display: flex; justify-content: center; gap: 1px;
  padding: 2px; background: var(--surface-1);
  border-top: 1px solid var(--border);
}
/* Ventiquattro pixel non sono un'estetica: sono il minimo sotto cui un dito
   non centra più il bersaglio, ed è la misura che WCAG 2.2 chiede. Il segno
   dentro resta piccolo; è l'area che deve essere grande. */
.pub-tessera-cmd button {
  flex: 1 1 auto; min-height: 24px; padding: 2px 0;
  display: grid; place-items: center;
  background: none; border: 0; border-radius: var(--r-1);
  color: var(--muted); font-size: 11px; line-height: 1; cursor: pointer;
}
.pub-tessera-cmd button:hover:not(:disabled) { color: var(--pri-ink); background: var(--surface-2); }
.pub-tessera-cmd button:disabled { color: var(--border-strong); cursor: not-allowed; }
:root[data-moto="si"] .pub-tessera {
  transition: border-color var(--t-stato) var(--ease-out),
              box-shadow var(--t-stato) var(--ease-out),
              opacity var(--t-stato) var(--ease-out);
}

/* ================== 2 · DESCRIZIONE E AUTOMAZIONE ======================= */
/* L'importazione è il gesto che si fa una volta per contenuto: si vede, ma
   non comanda la colonna. Il lavoro vero — scrivere e correggere — sta sotto,
   e ha tutto il resto. */
.pub-import {
  display: flex; align-items: center; gap: var(--sp-4);
  flex-wrap: wrap; margin-bottom: var(--sp-3);
}
.pub-import-file { cursor: pointer; }
.pub-import-btn {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  font-size: var(--fs-3);
}
.pub-import-segno {
  width: 21px; height: 21px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--pri-fill); color: var(--on-pri-fill); box-shadow: var(--pri-edge);
  font-size: 13px; line-height: 1;
}
.pub-import-file:hover .pub-import-btn { border-color: var(--data); color: var(--pri-ink); }
.pub-import-file:has(:focus-visible) .pub-import-btn { outline: 2px solid var(--pri-ink); outline-offset: 2px; }
:root[data-moto="si"] .pub-import-btn {
  transition: border-color var(--t-stato) var(--ease-out),
              color var(--t-stato) var(--ease-out);
}

.pub-incolla { margin: var(--sp-4) 0; }
.pub-incolla textarea {
  width: 100%; font-family: var(--font-mono); font-size: var(--fs-mono);
  line-height: 1.5; resize: vertical;
}
.pub-incolla-cmd {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  margin-top: var(--sp-3); flex-wrap: wrap;
}

.pub-esito {
  margin: var(--sp-4) 0;
  padding-left: var(--sp-4);
  border-left: 1px solid var(--accent-line);
}
.pub-esito h3 { margin: 0 0 var(--sp-2); font-size: var(--fs-4); }
.pub-esito .note { margin: var(--sp-2) 0; }
.pub-esito-cmd { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-3); }
/* Che cosa ha letto, non solo quante ne ha lette. Ogni valore è troncato a tre
   righe: serve a riconoscerlo, non a rileggerlo — per rileggerlo c'è il campo,
   subito sotto, dove poi si corregge. */
.pub-letti { margin: var(--sp-3) 0 0; }
.pub-letti dt {
  display: flex; align-items: baseline; gap: var(--sp-2);
  margin-top: var(--sp-3);
  font: 650 var(--fs-0) / 1.4 var(--font-ui);
  letter-spacing: .06em; text-transform: uppercase; color: var(--dim);
}
.pub-letti-scontro {
  padding: 1px 5px; border-radius: var(--r-1);
  background: var(--warn-soft); color: var(--warn-t);
  letter-spacing: .04em;
}
.pub-letti dd {
  margin: 3px 0 0; font-size: var(--fs-2); line-height: var(--lh-body);
  color: var(--muted); white-space: pre-wrap; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
.pub-frammenti summary { cursor: pointer; font-size: var(--fs-2); color: var(--muted); }
.pub-frammenti pre {
  margin: var(--sp-2) 0 0; padding: var(--sp-3);
  background: var(--surface-2); border-radius: var(--r-2);
  font-size: var(--fs-mono); white-space: pre-wrap; color: var(--muted);
  max-height: 220px; overflow: auto;
}
.pub-file-letto {
  margin: 0 0 var(--sp-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Cinque pastiglie che si dividono la riga in parti uguali sembravano
   ordinate e tagliavano i nomi: «Instagr…», «Faceb…», «Linked…». Un nome di
   piattaforma troncato non è una pastiglia più stretta, è un'etichetta che
   smette di dire quale piattaforma sia — e quando la colonna si stringe
   ancora, la griglia usciva addirittura dalla pagina.
   Ognuna prende la larghezza del proprio nome e va a capo quando la riga
   finisce. Due file di pastiglie intere si leggono; una fila di parole
   tagliate no. */
.pub-tabs {
  display: flex; flex-wrap: wrap;
  gap: var(--sp-2); margin: var(--sp-5) 0 var(--sp-4);
}
.pub-tab {
  flex: 0 1 auto; min-width: 0;
  cursor: pointer; text-align: center;
  padding-inline: var(--sp-3); white-space: nowrap;
}
.pub-tab-segno { margin-left: 4px; color: var(--pri-ink); }
.pub-tab.attivo .pub-tab-segno { color: var(--on-pri-fill); }

/* Il cambio di piattaforma è un cambio di CONTENUTO nello stesso posto: una
   dissolvenza brevissima lo dice, e non fa aspettare nessuno. Non c'è
   scorrimento laterale — le cinque piattaforme non stanno l'una accanto
   all'altra da nessuna parte, e fingere che ci stiano è una bugia spaziale. */
:root[data-moto="si"] .pub-pan:not([hidden]) {
  animation: pub-pan-entra 150ms var(--ease-out) backwards;
}
@keyframes pub-pan-entra { from { opacity: 0; } }

.pub-pan-testa {
  display: flex; align-items: center; gap: var(--sp-3);
  flex-wrap: wrap; margin-bottom: var(--sp-4);
}
.pub-attivo {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-2); color: var(--muted); cursor: pointer;
}
.pub-attivo input { accent-color: var(--accent); }
.pub-pan-testa .chip { margin-left: auto; }

.pub-remoto {
  margin: 0 0 var(--sp-4); padding-left: var(--sp-4);
  border-left: 1px solid var(--accent-line);
}
.pub-remoto p { margin: var(--sp-2) 0 0; }

/* Le due attività, alla stessa altezza gerarchica. L'automazione non è più un
   campo avanzato appeso in fondo alla descrizione: è metà del lavoro di
   questo contenuto, e il filo che la separa lo dice. */
.pub-sez { margin: 0 0 var(--sp-6); }
.pub-sez + .pub-sez { padding-top: var(--sp-5); border-top: 1px solid var(--border); }
.pub-sez-testa {
  display: flex; align-items: center; gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.pub-sez-testa h3 { margin: 0; font-size: var(--fs-4); }
/* La cronologia di un canale: che cosa ha provato Quadra, dal diario. */
.pub-storia { margin: var(--sp-2) 0; }
.pub-storia summary { cursor: pointer; color: var(--muted); }
.pub-storia-lista { list-style: none; margin: var(--sp-2) 0 0; padding: 0;
                    display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-2); }
.pub-storia-lista li { display: flex; flex-wrap: wrap; gap: 0 var(--sp-2); min-width: 0;
                       padding-left: var(--sp-2); border-left: 2px solid var(--border); }
.pub-storia-lista li > span { min-width: 0; overflow-wrap: anywhere; }
.pub-storia-ok { border-left-color: var(--ok) !important; }
.pub-storia-errore { border-left-color: var(--bad) !important; }
.pub-storia-incerto { border-left-color: var(--warn) !important; }
.pub-sez-conta {
  margin-left: auto; font-size: var(--fs-1); color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.pub-sez-conta.pub-oltre { color: var(--warn); }
.pub-sez-q {
  margin: 0 0 var(--sp-3); font-size: var(--fs-2);
  color: var(--muted); line-height: var(--lh-body);
}
.pub-sez .field { margin-bottom: var(--sp-3); }
.pub-sez textarea { width: 100%; resize: vertical; line-height: var(--lh-body); }

/* L'interruttore dell'automazione: si vede da lontano se è acceso, che è la
   sola domanda che gli si fa passando. */
.pub-interr {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  cursor: pointer; font-size: var(--fs-2); color: var(--muted);
}
.pub-interr input { position: absolute; opacity: 0; width: 0; height: 0; }
.pub-interr-pista {
  width: 34px; height: 19px; border-radius: var(--r-full); flex: none;
  background: var(--surface-3); border: 1px solid var(--border-strong);
  display: block; position: relative;
}
.pub-interr-pista > span {
  position: absolute; top: 2px; left: 2px;
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--muted); display: block;
}
.pub-interr input:checked + .pub-interr-pista {
  background: var(--accent); border-color: var(--accent);
}
.pub-interr input:checked + .pub-interr-pista > span {
  left: 17px; background: var(--accent-ink);
}
.pub-interr input:focus-visible + .pub-interr-pista {
  outline: 2px solid var(--pri-ink); outline-offset: 2px;
}
.pub-interr input:checked ~ .pub-interr-eti { color: var(--text); }
:root[data-moto="si"] .pub-interr-pista,
:root[data-moto="si"] .pub-interr-pista > span {
  transition: background var(--t-stato) var(--ease-out),
              border-color var(--t-stato) var(--ease-out),
              left var(--t-pressione) var(--ease-out);
}

/* Spenta, l'automazione non sparisce: restano il suo titolo, il suo
   interruttore e la riga che dice che cosa fa. Spariscono i CAMPI, che spenti
   non significano niente e costavano seicento pixel — più del doppio della
   descrizione, cioè del lavoro vero. È la stessa rivelazione contestuale della
   data di programmazione: il comando dichiara sempre di esistere, i suoi
   parametri compaiono quando servono. */
.pub-aut[data-spenta="si"] .pub-aut-corpo { display: none; }
:root[data-moto="si"] .pub-aut[data-spenta="no"] .pub-aut-corpo {
  animation: pub-quando-entra 180ms var(--ease-out) backwards;
}
.pub-aut-riga { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.pub-aut-riga .field { margin-bottom: var(--sp-3); }
.pub-aut-piede { margin: 0 0 var(--sp-3); }
.pub-aut-piede .linkish { font-size: var(--fs-2); font-weight: 600; color: var(--muted); }
.pub-aut-piede .linkish:hover { color: var(--pri-ink); }

/* ========================= 3 · LA PUBBLICAZIONE ========================== */
ul.pub-canali { list-style: none; margin: 0 0 var(--sp-4); padding: 0; }
.pub-canale { padding: var(--sp-3) 0; border-bottom: 1px solid var(--border); }
.pub-canale:first-child { border-top: 1px solid var(--border); }
.pub-canale-testa { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.pub-canale-sigla {
  font: 650 var(--fs-0) / 1 var(--font-mono); color: var(--dim);
  border: 1px solid var(--border); border-radius: var(--r-1);
  padding: 3px 5px; letter-spacing: .06em;
}
.pub-canale-nome { font-size: var(--fs-3); font-weight: 650; }
.pub-canale-testa .chip { margin-left: auto; }
.pub-canale-nota { margin: var(--sp-2) 0 0; }
.pub-canale-spento { opacity: .5; }
/* La provenienza della scelta si legge, non si indovina dal colore: il filo a
   sinistra accompagna la parola scritta nella nota, non la sostituisce. */
.pub-canale[data-origine="manuale"] {
  border-left: 1px solid var(--accent-line); padding-left: var(--sp-3);
}

/* Tre parole affiancate, sempre visibili. Prima erano tre voci dentro una
   tendina, e per leggere uno stato misto — Instagram subito, Facebook
   programmato, TikTok in bozza — bisognava aprire cinque tendine una per
   volta. Adesso lo stato misto si legge in un colpo d'occhio, che è
   esattamente ciò che deve succedere prima di premere «Pubblica». */
.pub-scelte {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  gap: 2px; padding: 2px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
}
.pub-scelta {
  padding: 6px var(--sp-2);
  background: none; border: 0; border-radius: var(--r-1);
  font: 600 var(--fs-1) / 1.35 var(--font-ui);
  color: var(--muted); cursor: pointer; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pub-scelta:hover:not([aria-checked="true"]):not(:disabled) { color: var(--text); background: var(--surface-1); }
/* SCELTO NON VUOL DIRE ARANCIONE.
   La prima versione dava l'accento a qualunque scelta, e siccome il valore
   predefinito è «bozza» la colonna si apriva con cinque pastiglie arancioni in
   fila — che è esattamente ciò che la §1 del foglio vieta: otto numeri
   arancioni non sono una gerarchia. E soprattutto era la codifica sbagliata:
   l'arancione finiva sulla scelta in cui NON succede niente.
   Scelto è un rilievo neutro. L'accento tocca solo le due scelte che fanno
   uscire qualcosa, cioè le sole che meritano di essere viste da lontano. */
.pub-scelta[aria-checked="true"] {
  background: var(--surface); color: var(--text);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .35);
}
.pub-scelta[aria-checked="true"][data-intento="subito"],
.pub-scelta[aria-checked="true"][data-intento="programmato"] {
  background: var(--pri-fill); color: var(--on-pri-fill); box-shadow: var(--pri-edge);
}
.pub-scelta:focus-visible { outline: 2px solid var(--pri-ink); outline-offset: 1px; }
.pub-scelta:disabled { color: var(--border-strong); cursor: not-allowed; }
:root[data-moto="si"] .pub-scelta {
  transition: background var(--t-pressione) var(--ease-out),
              color var(--t-pressione) var(--ease-out);
}

/* La data compare solo quando è stata scelta la programmazione: è una
   rivelazione, non un campo sempre presente e quasi sempre vuoto. */
.pub-quando { margin-top: var(--sp-3); }
/* La riga UTC è mono e lunga: senza questo usciva dalla colonna di ventisette
   pixel, e non si vedeva solo perché a destra c'era il margine di pagina. */
.pub-quando .field-help { overflow-wrap: anywhere; }
.pub-quando .field { margin-bottom: var(--sp-2); }
.pub-quando input[type="datetime-local"] { width: 100%; }
:root[data-moto="si"] .pub-quando:not([hidden]) {
  animation: pub-quando-entra 180ms var(--ease-out) backwards;
}
@keyframes pub-quando-entra {
  from { opacity: 0; transform: translateY(-4px); }
}

.pub-globale { margin-bottom: var(--sp-4); }
.pub-globale > summary {
  cursor: pointer; font-size: var(--fs-2); font-weight: 650; color: var(--muted);
  padding: var(--sp-2) 0;
}
.pub-globale > summary:hover { color: var(--pri-ink); }
.pub-glob-cmd { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-3); }
.pub-glob-prog { display: flex; gap: var(--sp-2); align-items: flex-end; flex-wrap: wrap; }
.pub-glob-prog .field { flex: 1 1 150px; margin-bottom: 0; }
.pub-globale .field-help { margin-top: var(--sp-3); }

.pub-riepilogo { margin-bottom: var(--sp-4); }
.pub-riepilogo h3 { margin: 0 0 var(--sp-3); font-size: var(--fs-4); }
.pub-riepilogo .note { margin: var(--sp-2) 0 0; }

/* «Salva bozza» è neutro e sta a sinistra; «Pubblica» è irreversibile, sta a
   destra e porta il peso. Due comandi con lo stesso aspetto costringono a
   leggerli tutti e due per capire quale sia quello che si stava cercando. */
.pub-azioni-riga { display: flex; gap: var(--sp-3); align-items: stretch; }
.pub-azioni > p, .pub-azioni details, .pub-azioni .pub-niente-invio,
.pub-azioni #pub-esiti { background: var(--bg); }
.pub-azioni-riga .btn { flex: 1 1 auto; text-align: center; }
.pub-azioni .btn-primo {
  flex: 1.25 1 auto;
  padding: var(--sp-3) var(--sp-5); font-weight: 650;
}
.pub-azioni .btn-primo:focus-visible { outline: 2px solid var(--pri-ink); outline-offset: 2px; }
.pub-azioni > p { margin: var(--sp-3) 0 0; }
.pub-azioni details { margin-top: var(--sp-3); }
.pub-azioni summary { cursor: pointer; }
/* Il comando che manderebbe fuori non esiste, e al suo posto c'è la ragione.
   Un bottone spento dice «non ora»; qui la risposta onesta è «non esiste
   ancora il pezzo che lo farebbe», e quella si scrive. */
.pub-niente-invio {
  margin-top: var(--sp-4); padding: var(--sp-3) var(--sp-4);
  border: 1px dashed var(--border-strong); border-radius: var(--r-2);
  background: var(--surface);
}
.pub-niente-invio p { margin: 0 0 var(--sp-2); font-size: var(--fs-2); }
.pub-niente-invio p:last-child { margin-bottom: 0; }

/* --------------------- il riepilogo prima di pubblicare ------------------
   Dentro la lastra del guscio, che è già un dialogo con il suo velo, il suo
   `Escape` e il suo fuoco. «Sei sicuro?» non è una domanda: non dice che cosa
   sta per succedere, e quindi non si può rispondere. Qui si legge riga per
   riga che cosa uscirà, su quale account e con quale testo. */
.pub-conferma-righe { list-style: none; margin: 0 0 var(--sp-5); padding: 0; }
.pub-conferma-riga {
  display: grid; grid-template-columns: 34px minmax(0, 1fr);
  gap: var(--sp-3);
  padding: var(--sp-3) 0; border-top: 1px solid var(--border);
}
.pub-conferma-riga:last-child { border-bottom: 1px solid var(--border); }
.pub-conferma-riga .pub-canale-sigla { align-self: start; }
.pub-conferma-che { margin: 0; font-size: var(--fs-3); font-weight: 650; }
.pub-conferma-come { margin: var(--sp-1) 0 0; font-size: var(--fs-2); color: var(--muted); }
.pub-conferma-riga[data-bloccato="si"] .pub-conferma-che { color: var(--bad); }
.pub-conferma-cmd { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.pub-conferma-cmd .btn { flex: 1 1 auto; text-align: center; }

/* --- adattamenti ---------------------------------------------------------
   Sotto i 1400 px la colonna delle decisioni scende sotto le altre due e si
   stacca dall'alto. La soglia è MISURATA, non scelta: con la barra laterale a
   230 px, tre colonne dentro 1280 px lasciano ai media 300 px scarsi, e sotto
   quella misura la tela verticale diventa più alta della finestra. Sotto i
   900 px si impila tutto nell'ordine in cui si lavora — media, testo,
   decisioni — che è anche l'ordine del documento e quindi quello della
   tastiera. */
@media (max-width: 1400px) {
  .pub-banco { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-6); }
  .pub-pubbl { grid-column: 1 / -1; position: static; }
  /* Solo l'elenco dei canali nella composizione (`ul`): la sezione «I canali»
     dell'elenco porta la stessa classe, e diventava una griglia a due colonne
     con il titolo a sinistra e le schede impilate a destra. */
  ul.pub-canali { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 0 var(--sp-5); }
  .pub-canale:nth-child(2) { border-top: 1px solid var(--border); }
}
@media (max-width: 900px) {
  .pub-banco { grid-template-columns: minmax(0, 1fr); gap: var(--sp-6); }
  /* La tela verticale, a piena larghezza su un telefono, sarebbe più alta
     dello schermo: si dà un tetto in unità di finestra e il media resta
     `contain`, cioè intero e non ritagliato. */
  .pub-tela { max-height: 68vh; }
  .pub-tab { flex: 1 1 auto; }
  .pub-azioni-riga { flex-direction: column; }
}

/* ==========================================================================
   §40 · IL CARTELLINO — la cifra che arriva dove sta l'occhio

   Fin qui una forma diceva il suo numero in una riga ferma sotto di sé, e la
   §39.8 spiegava perché: un cartellino che insegue il mouse copre proprio la
   cella accanto a quella che si vuole confrontare.

   Quella regola vale ancora — per le forme in cui il confronto è fra vicini,
   e sono la matrice e il sankey, che infatti la riga ferma ce l'hanno e se la
   tengono. Non vale per le altre, e il collaudo d'uso l'ha mostrato: su un
   territorio con trenta celle, per leggere «Bobbio» bisognava spostare
   l'occhio in fondo al riquadro, tornare sulla cella, e ricominciare. Là il
   confronto non è fra vicini: è fra la cella e la propria cifra, e in mezzo
   non deve esserci mezzo riquadro.

   Da cui la distinzione, che è la parte che conta:

     · dove si confrontano DUE SEGNI VICINI → riga ferma (matrice, sankey);
     · dove si legge UN SEGNO ALLA VOLTA   → cartellino accanto al puntatore.

   Uno solo per tutta l'applicazione, in fondo al corpo, sopra ogni strato.
   Non intercetta mai il puntatore: un cartellino che si fa cliccare si mette
   fra il mouse e la cella successiva, e la forma sotto smette di rispondere.
--------------------------------------------------------------------------- */
.sugg {
  position: fixed;
  top: 0; left: 0;
  z-index: var(--z-cartellino);   /* sopra ogni strato: vedi la scala in quadra.css */
  min-width: 132px;
  max-width: 280px;
  padding: 8px 10px 9px;
  background: var(--surface-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-2);
  box-shadow: var(--ombra-sollevata);
  color: var(--text);
  font-size: var(--fs-2);
  line-height: var(--lh-cell);
  /* Non intercetta il puntatore. È la riga più importante del blocco. */
  pointer-events: none;
  opacity: 0;
  /* Solo l'opacità si transiziona: la POSIZIONE no, o il cartellino
     rincorrerebbe il mouse con un ritardo elastico invece di stargli
     accanto — e un cartellino che insegue con la molla si legge come
     un'applicazione lenta. */
  transition: opacity 90ms var(--ease-out);
  will-change: transform;
}
/* Entra svelto (90 ms: è una risposta a un gesto, §38) ed esce più adagio, che
   è l'unico posto del foglio in cui l'uscita è più lenta dell'entrata — e c'è
   una ragione: passando da una cella all'altra il cartellino si nasconde e si
   riapre in pochi millisecondi, e con l'uscita rapida quel passaggio
   lampeggia. Rallentandola, il cartellino sembra scivolare da una cella
   all'altra invece di spegnersi e riaccendersi. */
.sugg { transition: opacity 140ms var(--ease-out); }
.sugg.sugg-visibile { opacity: 1; transition: opacity 90ms var(--ease-out); }
.sugg-t {
  display: block;
  font-size: var(--fs-3);
  font-weight: 620;
  line-height: 1.25;
  margin-bottom: 5px;
}
.sugg-t[hidden] { display: none; }
.sugg-c { margin: 0; display: flex; flex-direction: column; gap: 2px; }
.sugg-c > div {
  display: flex; align-items: baseline; gap: 10px;
  justify-content: space-between;
}
.sugg-c dt {
  color: var(--muted);
  font-size: var(--fs-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sugg-c dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  font-weight: 550;
}
.sugg-c dd em { font-style: normal; color: var(--muted); font-weight: 400; font-size: var(--fs-1); }
/* La riga che porta la risposta alla domanda per cui si sta guardando: una
   sola per cartellino, o non è più «quella». */
.sugg-forte dd { color: var(--pri-ink); font-weight: 640; }
.sugg-forte dt { color: var(--text); }

/* Il pallino più vicino al puntatore si accende, ma NON decide più che cosa si
   legge: il cartellino porta comunque tutte e due le quote. È la differenza
   fra evidenziare e scegliere, ed è ciò che toglie lo sfarfallio quando il
   puntatore passa fra i due segni — che è dove passa per forza, perché in
   mezzo c'è il segmento. */
.dv-p, .mv-p { transition: transform var(--t-pressione) var(--ease-out),
                           box-shadow var(--t-pressione) var(--ease-out); }
/* IL PUNTO CRESCE DAL PROPRIO CENTRO, e la traslazione va RIPETUTA.

   `transform` e' una proprieta' sola: scrivendo `scale(1.5)` si cancella il
   `translateY(-50%)` che teneva il punto centrato sul binario, e il punto —
   che e' posizionato con `top: 50%`, cioe' con il suo BORDO ALTO a meta'
   altezza — cade di meta' della propria misura e poi cresce da li'. A vista:
   si ingrandisce verso il basso. Le due trasformazioni si scrivono insieme,
   nell'ordine in cui vanno applicate: prima si mette al suo posto, poi si
   ingrandisce. */
.dv-riga[data-vicino="peso"] .dv-peso,
.dv-riga[data-vicino="resa"] .dv-resa {
  transform: translateY(-50%) scale(1.5);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--data) 26%, transparent);
}

/* Le celle del territorio rispondono con la LUCE, non con la scala (§38.3): un
   mosaico che si stacca apre quattro fessure e mente sulla propria area. */
.terr-cella { transition: filter var(--t-pressione) var(--ease-out); }
.terr-cella:hover { filter: brightness(1.18); }
/* E la fascia sotto il puntatore si stacca dal fondo di un filo: dice «questa
   valle», senza spostare niente. */
.terr-fascia { transition: background-color var(--t-stato) var(--ease-out); }
.terr-fascia:hover { background: color-mix(in srgb, var(--surface-2) 60%, transparent); }

/* Le due cifre in coda alla fascia: la quota della zona e i contatti che
   raccoglie. Sono la ragione per cui l'anteprima del territorio si legge senza
   aprirla — la campitura dice «più acceso», e queste dicono di quanto. */
.terr-cifre {
  display: flex; align-items: baseline; gap: 5px;
  justify-content: flex-end;
  min-width: 62px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  white-space: nowrap;
}
.terr-cifre b { font-size: var(--fs-2); font-weight: 600; }
.terr-cifre em { font-style: normal; font-size: var(--fs-0); color: var(--muted); }

/* La colonna dell'istogramma sotto il puntatore prende l'accento: la §39.7 le
   dava già lo smorzamento delle vicine, mancava il segno positivo su quella
   scelta. Non si ingrandisce — l'altezza è il dato. */
.ig-pista i { transition: filter var(--t-stato) var(--ease-out),
                          background-color var(--t-stato) var(--ease-out); }
.ig-col:hover .ig-pista i {
  background: linear-gradient(180deg, var(--seq-5) 0%, var(--seq-4) 100%);
}
.ig-col:hover .ig-n { color: var(--text); }
/* Le righe della classifica: erano testo fermo, e portano tre `data-` che il
   cartellino sa leggere. Il segno che sono interrogabili è il fondo. */
.rf li { transition: background-color var(--t-stato) var(--ease-out); border-radius: var(--r-1); }
.rf li:hover { background: color-mix(in srgb, var(--surface-2) 70%, transparent); }
.rf li:hover .rf-r { color: var(--text); }

/* ==========================================================================
   §41 · IL RESPIRO — il movimento che dice «questo è vivo», e nient'altro

   Questa sezione cammina sul filo della regola più importante del foglio: **il
   movimento non fa sembrare fresco un dato fermo.** L'export è di ieri e resta
   di ieri, e qualunque cosa pulsi accanto a un numero racconta il contrario.

   Il moto ambientale che c'è qui non tocca nessun numero e nessuna forma di
   dato. Tocca due cose sole, e tutte e due sono VERE:

     1. lo STATO DEL SISTEMA — la pastiglia che dice «report aggiornato» respira
        piano perché il sistema è in ascolto; se l'export mancasse, la stessa
        pastiglia sarebbe ferma e rossa, ed è già così;
     2. la SUPERFICIE — un velo di luce che attraversa la plancia una volta
        ogni molto tempo, così lenta da non essere mai il soggetto di uno
        sguardo. È la stessa cosa che fa un vetro sotto una finestra: non dice
        niente sul contenuto, dice che c'è della luce.

   Le tre misure che tengono la cosa professionale invece che da vetrina:

     · PERIODI LUNGHI. Sotto i sei secondi un ciclo si conta, e ciò che si
       conta diventa un tic in tre giorni. Qui il più rapido è nove secondi.
     · AMPIEZZE MINUSCOLE. Due centesimi di opacità, mezzo pixel di scala.
       Se lo si vede guardandolo di proposito, è troppo.
     · NIENTE ACCANTO A UNA CIFRA. Nessuna di queste regole tocca un `.kpi`,
       una `.mod-cifra`, una barra, una fetta o un asse.

   E la prima cosa che si spegne con `prefers-reduced-motion`: un moto continuo
   è esattamente ciò che quella preferenza chiede di togliere.
--------------------------------------------------------------------------- */

/* 41.1 · Lo stato che ascolta. Il pallino della pastiglia di freschezza
   respira: non «sto caricando», ma «questo è collegato a qualcosa». Solo
   quando lo stato è buono — un pallino d'allarme che pulsa piano sarebbe una
   sirena rilassata, cioè il segnale sbagliato con il tono sbagliato. */
/* Solo la pastiglia BUONA. Quella d'allarme e quella «in lavorazione» hanno il
   loro segno — un quadrato, un rombo — e una che pulsasse piano sarebbe una
   sirena rilassata: il segnale sbagliato con il tono sbagliato. E sono le due
   che portano già una trasformazione propria, che questa cancellerebbe. */


/* 41.2 · Il velo che attraversa. Una luce larghissima e debolissima che
   passa sulla plancia una volta ogni quarantacinque secondi. Non è sopra il
   contenuto — sta sul fondo, dietro i moduli — e non lampeggia: entra ed esce
   con la stessa lentezza con cui il sole gira in una stanza.

   `mask` invece di un elemento in più: nessun nodo aggiunto al documento, e la
   composizione la fa la GPU su un livello che esiste già. */
/* 41.3 · Il modulo che sta rispondendo a una domanda aperta. Mentre la lastra
   è aperta il riquadro da cui è nata resta acceso (§38.3): qui quell'accensione
   respira appena, così l'occhio ritrova il punto di ritorno senza cercarlo.
   Nessun altro modulo si muove. */
/* 41.4 · Ciò che NON respira, e perché.
   · nessuna cifra, nessuna barra, nessuna fetta, nessun asse: sono il dato, e
     il dato è fermo perché l'export è fermo;
   · nessuna riga di tabella e nessuna voce di navigazione: si vedono cento
     volte al giorno, e la §38 le tiene ferme per quello;
   · nessuno scheletro di caricamento pulsante: non c'è niente in arrivo, la
     pagina è già completa quando la si apre.

   E con la preferenza di moto ridotto cade tutta la sezione, per intero: il
   moto ambientale è la prima cosa che `prefers-reduced-motion` chiede di
   togliere, ed è anche la sola che non porta nessuna informazione. */


/* =============================================================================
   39. COLLEGAMENTI — lo stato di una delega
   =============================================================================
   La pagina dei collegamenti aggiunge tre cose che il foglio non aveva ancora:
   una pastiglia per lo stato intermedio, la riga di un account collegato, e
   l'elenco delle capacità con il loro stato reale.

   Il colore fa un lavoro preciso e ristretto: distingue «pronto» da «in
   attesa» da «non arriverà». Non decora — le tre condizioni sono davvero
   diverse e chi guarda deve poterle separare senza leggere.               */

/* Lo stato che mancava: configurato ma non ancora collegato. Non è un
   avvertimento (niente è rotto) e non è spento (basta un clic): sta in mezzo,
   e prende l'accento del prodotto. */


/* La riga di un account. Sta dentro la scheda del canale, sotto la testata. */
.conn-riga {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  padding: .45rem 0;
  border-top: 1px solid var(--border);
}
.conn-nome { flex: 1 1 auto; min-width: 0; }
.conn-nome em { margin-left: .35rem; }
.conn-comandi { display: flex; gap: .35rem; flex: 0 0 auto; }

/* Una connessione revocata o scaduta resta visibile, ma smette di reclamare
   attenzione: sapere che c'è stata è utile, confonderla con una attiva no. */
.conn-spenta { opacity: .62; }

.elenco-manca { margin: 0; padding-left: 1.1rem; }
.elenco-manca li + li { margin-top: .5rem; }

/* Le capacità. Ognuna è una riga a tre parti: nome, stato, e il perché.
   Il perché sta sotto e in piccolo perché si legge una volta sola, quando ci
   si chiede come mai un comando è spento. */
.canale-capacita { margin-top: .6rem; }
.canale-capacita summary { cursor: pointer; }
.elenco-capacita { list-style: none; margin: .5rem 0 0; padding: 0; }
.elenco-capacita .cap {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: .1rem .6rem;
  padding: .35rem 0;
  border-top: 1px solid var(--border);
}
.cap-nome { font-weight: 600; }
.cap-stato { font-size: .82em; white-space: nowrap; }
.cap-nota { grid-column: 1 / -1; }

.cap-disponibile .cap-stato { color: var(--ok); }
.cap-revisione .cap-stato { color: var(--warn); }
.cap-ristretta .cap-stato { color: var(--warn); }
.cap-assente .cap-stato,
.cap-da_verificare .cap-stato { color: var(--dim); }

/* Una tabella per due colonne di fatti: gli indirizzi da registrare, gli
   ultimi eventi. Scorre da sé se la finestra è stretta — un `code` con dentro
   un URL non si spezza, e senza questo la pagina scorrerebbe di lato. */
.tabella-secca { width: 100%; border-collapse: collapse; }
.tabella-secca th,
.tabella-secca td {
  text-align: left;
  padding: .45rem .6rem .45rem 0;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.tabella-secca th { font-weight: 600; color: var(--muted); white-space: nowrap; }
.tabella-secca td code { overflow-wrap: anywhere; }

/* Il canale collegato prende il bordo dello stato buono, come le sorgenti
   attive: è la stessa grammatica, applicata a una cosa nuova. */
.canale-collegato { border-color: var(--ok-line); }
.canale-configurabile { border-color: var(--line); }

/* L'esito buono di un invio. Le note nascono per gli avvisi e i guasti — una
   riga che dice «fatto» non c'era, perché fino a ieri non c'era niente che
   riuscisse. Stesso impianto delle altre due, colore dell'esito buono. */
.note-ok { color: var(--ok); }
.note-ok::before { content: "✓"; }

/* L'esito per canale, nella scheda di composizione. */
.pub-esito {
  display: flex;
  align-items: center;
  gap: .45rem;
  flex-wrap: wrap;
  margin: .5rem 0 .2rem;
}
.pub-esito p, .pub-esito .note { flex: 1 1 100%; margin: .3rem 0 0; }

/* Lo schema da applicare una volta sola, quando il registro non è pronto.
   Scorre da sé: è SQL, non si spezza, e senza questo la pagina scorrerebbe
   di lato. */
.blocco-sql {
  overflow-x: auto;
  max-height: 18rem;
  overflow-y: auto;
  margin: .5rem 0 0;
  padding: .6rem .7rem;
  background: rgba(0, 0, 0, .28);
  border: 1px solid var(--border);
  border-radius: var(--r-xs);
  font-size: .78em;
  line-height: 1.5;
}

/* ===================================== L'AZIONE PRINCIPALE DI UNA TESTATA ==
   `margin-left:auto` la manda all'estremo destro, dove sta l'azione in tutte
   le altre testate del prodotto; il resto della regola le da' il peso che le
   spetta. Una primaria che sembra una secondaria costringe a leggere tre
   bottoni per capire quale sia quello che si stava cercando. */
.page-head .btn-primo {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px var(--sp-5); font-weight: 650;
}
.page-head .btn-primo svg { width: 15px; height: 15px; flex: none; }
.page-head .btn-primo:hover { filter: brightness(1.12); }
.page-head .btn-primo:focus-visible { outline: 2px solid var(--pri-ink); outline-offset: 2px; }
@media (max-width: 640px) {
  /* Su schermo stretto la testata va a capo: l'azione resta l'ultima riga e
     prende tutta la larghezza, che e' il posto in cui il pollice arriva. */
  .page-head .btn-primo { margin-left: 0; width: 100%; justify-content: center; }
}

/* ======================================== IL SELETTORE DEL REPARTO ==========
   Un comando che dice dove si e' e si apre su dove si puo' andare. La sigla
   resta — e' il segno con cui i due reparti si riconoscono da lontano, e stava
   gia' in pagina — e il claim di ciascuno diventa la riga che spiega, cioe' la
   sola cosa che le due piastrelle di prima non riuscivano a dire. */


/* La sigla del reparto in cui si e' porta l'accento: e' l'unico posto della
   barra in cui si dichiara dove si sta lavorando. */


/* LA CORNICE ARANCIONE ERA UN ANELLO DI FUOCO, non uno stato.

   Compariva sulla voce corrente appena si apriva il menu, e sembrava dire
   « sei qui » — cosa che dicono gia' la spunta e il colore del nome. In realta'
   diceva « questa riga ha il fuoco della tastiera », e lo diceva anche a chi
   il menu l'aveva aperto con il mouse, perche' l'apertura spostava il fuoco
   dentro l'elenco in tutti e due i casi.

   L'anello resta — toglierlo lascerebbe chi naviga da tastiera senza sapere
   dov'e' — ma il fuoco entra nell'elenco solo quando il menu si apre DA
   TASTIERA. Aperto con un dito o con il mouse, il fuoco non si sposta e
   l'anello non compare: e' la stessa regola di `:focus-visible`, applicata
   dove il browser da solo non arriva. */


/* Senza JavaScript il menu resta aperto: sono due collegamenti veri, e una
   barra che non porta piu' all'altro reparto sarebbe peggio di una barra
   ingombrante. `[hidden]` va battuto esplicitamente, perche' il browser lo
   traduce in `display:none` e nessuno arriverebbe a toglierlo. */


/* La distribuzione dell'anzianita' si prende l'altezza che la frase sotto le
   toglieva: cinque bande alte cento pixel si confrontano, cinque bande alte
   quaranta sono cinque trattini. `justify-content: stretch` perche' la regola
   di base le centrava, lasciando aria sopra e sotto invece di darla alle
   colonne. */
.mod-forma-alta { justify-content: stretch; }
.mod-forma-alta > * { flex: 1 1 auto; min-height: 0; }

/* ===========================================================================
   §41 — LA PANORAMICA COME STRUMENTO
   ===========================================================================

   La §40 aveva stabilito che il Marketing puo' dichiarare di stare
   sorvegliando, e gli Immobili no: davanti alla scheda di un rustico a Travo
   un ambiente da sala di controllo direbbe una cosa falsa.

   La Panoramica pero' non e' la scheda di un immobile. E' la prima schermata
   della mattina, e la domanda che le si fa e' esattamente quella di un
   quadrante: com'e' messo, adesso, tutto insieme. Qui l'ambiente strumentale
   dice una cosa vera, e si ferma dove la pagina smette di essere un quadrante
   — nel Portafoglio, dove si guardano gli oggetti uno per uno, non entra.

   QUATTRO ELEMENTI CONTINUI, E OGNUNO SIGNIFICA QUALCOSA
     il reticolo    la superficie e' uno strumento, non un documento
     la velatura    passa una volta ogni ventitre secondi. E' lenta apposta:
                    dichiara che la superficie e' viva, non che un numero e'
                    cambiato — e un numero qui non cambia mai da solo
     il quadrante   parti di un intero CONOSCIUTO. Dove l'intero non esiste,
                    l'anello non c'e'
     la lancetta    gira dietro gli anelli, nove secondi al giro. Dice la
                    stessa cosa della velatura, in forma di quadrante: e' lo
                    strumento che e' acceso, non un dato che si aggiorna

   E NIENTE ALTRO SI MUOVE DA SOLO. Nessuna cifra sale da zero, nessuna barra
   scorre in ciclo: le cifre sono scritte al primo fotogramma e restano dove
   sono. Il moto continuo sta soltanto sui due elementi che dichiarano lo
   STATO DELLO STRUMENTO — la velatura e la lancetta, piu' l'alone che le
   accompagna — e mai su un elemento che porta una quantita'. La regola della
   §38 non e' stata allargata, e' stata applicata a una superficie in piu'.
   ------------------------------------------------------------------------ */


/* Il reticolo: verticali larghe, sotto una maschera che le fa nascere e morire
   dentro la fascia invece di tagliarle contro il bordo. */

/* La velatura lenta. Ferma di default: si muove solo se il documento ha
   dichiarato che il movimento e' ammesso. */


/* ----------------------------------------- il quadrante e le quattro cifre --
   A sinistra un quadrante a tre anelli concentrici, a destra le quattro cifre
   in due e due. La divisione del lavoro e' netta e non si sovrappone: il
   quadrante porta la PROPORZIONE, le cifre portano la QUANTITA'.

   Prima ogni riquadro aveva il suo anellino con dentro la sua percentuale.
   Quattro proporzioni piccole, ognuna disegnata sulla propria base, in fila
   larga uno schermo: per confrontarle bisognava leggerle una per una e
   tenerle a mente, che e' esattamente il lavoro che una forma dovrebbe
   togliere. Le tre quote pero' contano LO STESSO intero, e tre parti di uno
   stesso intero conosciuto stanno su un disegno solo.

   Gli anelli vanno dal chiaro allo scuro seguendo la quantita': l'esterno e'
   l'intero ed e' chiuso, i due dentro sono le sue parti. Il pallino accanto
   all'etichetta e' l'unica cosa che lega la cifra al suo anello — la quarta
   cifra non ce l'ha, e non e' una dimenticanza: i contatti sono eventi
   cumulati dalla pubblicazione, non un sottoinsieme dei 206, e un anello per
   loro direbbe «479 su 206», che non vuol dire niente. Dove la proporzione
   non esiste non si disegna.
--------------------------------------------------------------------------- */


/* L'alone che respira: sta dietro tutto, non ha bordi ed e' la sola cosa di
   questa pagina che cambia da sola nel tempo senza dire che un dato e'
   cambiato. Dice che la superficie e' viva — come la velatura del piano. */


/* La lancetta da radar e' uscita (§43). Girava sul giro INTERO, cioe' anche
   sui gradi dove l'arco non arriva: un movimento che attraversa il vuoto dice
   che li' c'e' qualcosa da guardare, e li' non c'e' niente. Al suo posto un
   impulso che percorre soltanto la quota — vedi `.qdr-imp`. */


/* La rampa scende con la quantita': chiaro l'intero, poi due gradini piu'
   caldi. Non e' `--accent` sul secondo anello e `--seq-3` sul terzo, che nel
   tema di questa agenzia sono lo STESSO colore: due anelli identici accanto
   si leggono come un anello solo spesso il doppio. */


/* Gli anelli si compongono in sequenza, dall'esterno verso il centro: e'
   l'ordine in cui si leggono — quanti sono, quanti se ne vedono, quanti
   rispondono. Una volta sola per comparsa, come ogni ingresso della §38. */

@keyframes qdr-traccia {
  from { stroke-dasharray: 0 100; opacity: 0; }
  22%  { opacity: 1; }
}


/* La cifra al centro arriva quando il primo anello ha finito di chiudersi:
   prima l'intero, poi il numero che lo dice. */

/* --------------------------------------------------------- le quattro cifre */

/* Senza l'anellino la colonna non serve piu': il riquadro torna a essere una
   colonna sola — etichetta, cifra, riga di servizio. */

/* L'etichetta e il suo pallino stanno sulla stessa riga, e l'etichetta va a
   capo invece di troncarsi: «Con annuncio at…» costringe a indovinare che
   cosa si sta guardando. */


/* La cifra di apertura passa a Inter come tutte le altre: la monospaziata
   serve dove i numeri si incolonnano, e questi stanno da soli. */


/* ------------------------------- il dito accende la cifra E il suo anello
   La §39, applicata alla fascia: si smorza il resto invece di far sparire
   qualcosa — un riquadro che scompare fa sembrare cambiato il totale. E la
   cifra sotto il dito porta con se' il suo anello, che e' il modo piu' corto
   di dire quale delle tre parti sia. */

/* Da tastiera vale lo stesso: il fuoco accende come il puntatore. */


/* Chi ha chiesto meno movimento trova il quadrante gia' composto: gli anelli
   sono alla loro lunghezza al primo fotogramma, la lancetta e l'alone stanno
   fermi. Nessuna informazione sta nel movimento — solo l'ordine di lettura. */


/* Sotto i 1080 px il quadrante passa sopra le cifre invece di stringersi: un
   quadrante largo centosessanta pixel accanto a quattro riquadri strizzati non
   e' piu' un quadrante, e' un bollino. */


/* ------------------------------------- le misure, sullo stesso strumento ---
   La fascia di sopra e' un quadrante; questa e' il resto del pannello, e deve
   sembrarne la continuazione invece di una tabella che comincia sotto. Stesso
   reticolo, stessa velatura, e la cifra capofila accesa come quelle di sopra:
   dentro ogni gruppo la prima cifra e' quella che le altre spiegano, e adesso
   si vede da lontano quale sia. */


/* Senza il ritaglio del testo la cifra resta a tinta piena: trasparente e
   basta sarebbe una cifra invisibile. */


/* Le cifre di appoggio passano a Inter come tutte le altre. */


/* La squadra in alto a sinistra della testata è stata tolta. Diceva «questo è
   uno strumento» a un pannello che lo dice già col reticolo, la velatura e il
   quadrante: un quarto segno per lo stesso significato non rinforza, ricama.
   Il titolo torna a partire dal margine, in colonna con tutto il resto della
   pagina. */

/* La conclusione e' due colonne — il titolo a sinistra, la frase a destra — e
   la colonna fissa da 210 px non si stringe: su un telefono la frase a destra
   restava larga quanto voleva e usciva dallo schermo di ventun pixel. Sotto i
   720 px le due colonne diventano due righe, e in ogni caso le celle possono
   restringersi: `min-width: 0` e' quello che manca a una cella di griglia per
   accettare di essere piu' stretta del proprio contenuto. */


/* ===========================================================================
   §42 · LE ANTEPRIME DELLA PLANCIA — dove lo spazio è la lettura

   Tre moduli del Portafoglio dicevano la stessa cosa due volte e pagavano la
   ripetizione in altezza — l'unica cosa che su una plancia non si compra. Qui
   si toglie il doppione e si spende quello che libera, con una regola sola:
   il ritmo lo fa il CONTRASTO fra intervalli, non un intervallo ripetuto.

   Le regole di respiro valgono sopra gli 880 px di finestra e solo là. Sotto,
   la §35 ha già tarato la plancia al pixel e un respiro in più non è aria: è
   una riga di legenda tagliata dal bordo del modulo.
   ------------------------------------------------------------------------ */

/* ------------------------------------------- l'anzianità, senza il doppione
   Il conteggio sopra ogni colonna diceva in cifre quello che la colonna dice
   in altezza, e lo diceva cinque volte: cinque numeri in fila sopra un grafico
   che esiste per non farli leggere. Restano la quota e il nome della banda,
   che l'altezza non porta; la banda della media resta marcata dal colore della
   colonna e dal nome in grassetto, come prima.

   Non è `display: none`: la riga della tabella deve restare completa per chi
   la ascolta invece di guardarla, e il conteggio è il suo dato. Sparisce dallo
   schermo, non dalla lettura assistita. Nel dettaglio e nella lente il numero
   torna scritto, perché là lo spazio c'è. */
.mod-corpo .ig-v {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* L'altezza che la cifra lascia va alla pista, che è la parte che porta il
   confronto: la colonna cresce, non il vuoto sopra di lei. */
.mod-corpo .ig-col { gap: 3px; }

@media (min-height: 881px) {
  /* ------------------------------- la concentrazione, distesa in tre letture
     Il piede del modulo Visibilità porta TRE cose diverse — quanti annunci
     fanno l'ottanta per cento, quanto è ripida la curva, quanti sono rimasti a
     zero — e le portava a due pixel l'una dall'altra, cioè come se fossero una
     riga sola andata a capo tre volte. Sotto, le due cifre di chiusura erano
     staccate dal piede quanto le tre liste sopra sono staccate fra loro.

     Lo spazio non si aggiunge, si sposta. Le tre liste in cima sono una pila
     densa e cedono metà dei loro separatori; quello che cedono va dove serve
     un contrasto: sei pixel dentro il piede, e il doppio del respiro prima
     delle due cifre, che non sono la conclusione del piede ma del modulo. */
  
  
  
  

  /* ------------------------------------ la tipologia, e il filo che separa
     Il filo fra la legenda e le tre letture di contesto stava a otto pixel
     dall'una e a cinque dalle altre: abbastanza per essere un bordo, non
     abbastanza per essere una separazione. Un filo che divide due blocchi ha
     bisogno di aria da tutte e due le parti, o divide solo sulla carta.

     L'aria sopra il filo non e' un numero: e' quella che avanza. La colonna
     si allunga fino all'altezza del riquadro (`align-self: stretch`) e la sua
     `space-between` — che c'era gia' e non poteva fare niente su una colonna
     alta quanto il proprio contenuto — appoggia la legenda in cima e le tre
     letture in fondo. Cosi' lo spazio cresce da solo dove il riquadro e' alto
     e si richiude dove non c'e', senza che nessuna riga finisca tagliata dal
     bordo: su una plancia che non scorre, un respiro dichiarato in pixel e' un
     respiro che prima o poi non ci sta.

     `gap` resta come PAVIMENTO, non come misura: dodici pixel sono il minimo
     sotto cui il filo torna a essere un bordo. Sotto il filo i diciotto pixel
     sono dichiarati, perche' li' non c'e' niente che possa distribuirli. */
  /* `align-self: center` e non `stretch`: con `stretch` piu' un tetto la
     colonna si allunga e poi resta appesa in alto, mentre il disco accanto
     e' centrato — due blocchi affiancati che partono da altezze diverse si
     leggono come un errore di impaginazione. Con un'altezza dichiarata e
     `center`, i due estremi della colonna e i due del disco si guardano. */
  .mod-corpo .cia-col { align-self: center; height: min(100%, 263px); gap: 10px; }
  .mod-corpo .cia-extra { padding-top: 22px; gap: var(--sp-1); }
  .mod-corpo .cia-leg { gap: 2px; }
}
/* IL FILO STA IN MEZZO, NON PIU' VICINO A UNO DEI DUE.
   Con `space-between` l'aria finiva tutta sopra il filo (trentuno pixer sopra,
   venti sotto): il filo sembrava appartenere al blocco di sotto invece di
   dividere i due. L'altezza della colonna e' scelta perche' l'avanzo valga
   esattamente quanto il respiro dichiarato sotto — 263 = 219 di contenuto piu'
   due volte 22 — e i due spazi vengono uguali senza doverli misurare a mano.

   Fra 881 e 940 pixel di finestra il riquadro non ha 263 pixel da dare, e la
   colonna prende quelli che ci sono: li' il respiro dichiarato scende a
   quattordici, che e' quanto serve perche' l'avanzo resti dalla sua parte e
   nessuna riga finisca sotto il bordo. */
@media (min-height: 881px) and (max-height: 940px) {
  .mod-corpo .cia-extra { padding-top: 14px; }

  /* ----------------------------------------- l'anzianita', e il suo respiro
     La distribuzione partiva otto pixel sotto la media e la mediana, cioe' si
     leggeva come la loro terza riga invece che come la forma che le spiega.
     Sedici: la cifra e il grafico restano una cosa sola, ma si vede il giunto.
     Li paga il grafico, che perde otto pixel di colonna e nessun confronto. */
  

}

/* ------------------------------- la visibilita', e chi si prende l'avanzo ---
   La §35 divideva l'avanzo del riquadro fra le due forme in parti uguali, e
   fermava tutte e due a 104 px perche' non si prendessero mezza colonna. Sui
   monitor alti quella coppia di regole produceva il difetto opposto: le due
   tele arrivavano al tetto, le sezioni che le contengono continuavano a
   crescere lo stesso — il tetto e' sulla tela, non sulla sezione — e l'altezza
   in piu' si depositava come VUOTO. Misurati a 1512x1250: centoventiquattro
   pixel di niente sotto «arrivano in fondo visti e non convertiti», e altri
   centodiciannove fra «74 a zero contatti» e il filo di chiusura.

   Tre correzioni, e ognuna manda l'avanzo dove dice qualcosa:

   L'avanzo si divide in sette parti: quattro alla CURVA, due al SANKEY, una a
   testa alle DUE CLASSIFICHE. Non e' una proporzione a occhio, e' l'ordine di
   quanto ciascuno guadagna da un pixel in piu':

   1. la CURVA e' la sola forma del riquadro in cui l'altezza E' lettura — piu'
      e' alta, piu' si vede dove smette di salire — e si prende la quota
      maggiore. Tetto a 240 px, perche' la ragione della §35 resta: un grafico
      grande quanto mezza colonna non e' piu' leggibile, e' solo piu' grande.
   2. il SANKEY guadagna meno ma guadagna: e' un percorso a tre colonne, e sotto
      i cento pixel i nastri si sovrappongono al punto che non si vede piu'
      DOVE si assottiglia, che e' l'unica cosa per cui esiste. Tetto a 160.
      La §35 lo faceva crescere quanto la curva per tenerli alti uguali — ma le
      due forme non si confrontano fra loro, rispondono a due domande diverse,
      e tenerle pari costava alla curva senza dare niente al percorso.
   3. quello che resta va alle DUE CLASSIFICHE, che centrano il proprio
      contenuto: l'aria si divide sopra e sotto invece di accumularsi da una
      parte sola. Una quota a testa e non di piu': sono righe di testo, e una
      riga di testo con venti pixel d'aria intorno non si legge meglio di una
      con quindici — mentre venti pixel dati a una curva si vedono. Non si
      stringono comunque: `flex-shrink` resta a zero, che era il punto della
      §35 e vale ancora — tre riferimenti sono tre righe.

   Sui monitor bassi non cambia niente di visibile: dove l'avanzo non c'e', non
   c'e' niente da distribuire. */


/* ===========================================================================
   §43 · IL NEON — la luce come materia del dato

   Il quadrante della Panoramica aveva gia' due cose che le altre forme non
   avevano: una rampa calda che si stacca dal fondo e un alone sotto ciascun
   anello. Non era decorazione riuscita per caso — era la §28 applicata a una
   forma sola: su un fondo profondo un tratto che EMETTE luce si legge prima
   di un tratto che la riflette, e a parita' di spessore stacca di piu'.

   Qui quella lettura esce dal quadrante e va sulle altre tre forme che
   portano una quota: l'anello della tipologia, la corona della tassonomia,
   le fasce del territorio, le colonne dell'anzianita'. Una regola sola:

     LA LUCE STA SUL DATO, MAI SUL CONTORNO.

   E la luce e' CHIARA, non e' del colore del dato. Il primo giro di questa
   sezione accendeva ogni forma con `--accent` — che in questo tema e' un
   bruno rosso (#B5562E) — e su un fondo scuro un alone bruno non e' un alone:
   e' una macchia leggermente meno scura. Il neon del quadrante funzionava
   perche' li' la luce e' l'oro chiaro in cima alla rampa. Quindi l'alone
   prende `--seq-5`, il gradino piu' chiaro, anche quando il dato sotto e' il
   piu' scuro: nel neon la lampada e' sempre piu' chiara del vetro.

   Chiara, non forte. Il secondo giro alzava insieme il colore E la quantita',
   e il risultato era un pannello in cui ogni forma abbagliava: quando tutto
   emette, niente emette piu' degli altri, e l'alone smette di essere una
   gerarchia per diventare una foschia. La luce e' tarata perche' si veda che
   la forma e' accesa e non perche' si veda l'alone — la si nota se la si
   toglie, non mentre la si guarda. La differenza fra le due tarature sta
   quasi tutta nel raggio largo: e' quello che fa alone, e quasi ovunque e'
   uscito.

   Alone sull'arco, sulla fetta, sulla cella, sulla colonna. Mai sul riquadro
   che le contiene, mai su un bordo, mai su un'etichetta: un pannello che
   brilla ai bordi e' un giocattolo, un dato che brilla e' uno strumento.

   ------------------------------------------------------------------------
   E L'IMPULSO

   Il movimento continuo di questo foglio ha sempre detto una cosa sola — la
   superficie e' viva — e non ha mai detto che un dato e' cambiato (§38). La
   lancetta lo diceva male: girava sul cerchio intero, cioe' passava anche
   dove la quota non arriva, e un impulso che attraversa il vuoto sembra un
   dato che non c'e'. L'impulso di qui percorre SOLO la quota — parte
   dall'inizio dell'arco, si ferma dove l'arco si ferma, riposa, ricomincia.

   E' l'unica cosa che una forma piena non riesce a gridare: DOVE FINISCE.
   Nessuna informazione ci sta dentro — chi ha chiesto meno movimento vede la
   stessa forma, ferma, con la stessa lunghezza al primo fotogramma.
   ------------------------------------------------------------------------ */

/* --------------------------------------------- 43.1 · l'impulso sugli anelli
   Un tratto corto su un tratteggio da cento: `stroke-dashoffset` lo fa
   scorrere dall'inizio dell'arco fino alla sua quota, e la quota e' la stessa
   `--q` che disegna l'arco sotto — un numero solo, scritto dal server una
   volta, quindi impulso e arco non possono separarsi. */
/*  `--q` va REGISTRATA, e la ragione e' l'interpolazione. Una proprieta'
    personalizzata non registrata resta una sequenza di token fino all'uso: nei
    fotogrammi chiave `calc(var(--q) * -1)` non ha un tipo, e senza tipo il
    motore non sa interpolare — passava da zero alla fine dell'arco con uno
    scatto solo, a meta' durata. Dichiarata `<number>` diventa una lunghezza
    vera e l'impulso SCORRE. Il valore lo scrive il server sul cerchio. */
@property --q {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;
}

/* La testa dell'impulso e' piu' chiara del suo anello, non di un altro colore:
   e' lo stesso tratto acceso, non un secondo dato. */

/* Gli archi del quadrante: `pathLength=100` e' dichiarato nel markup, la quota
   si scrive in centesimi e non dipende dal raggio. */

/* Lo spicchio scelto del sunburst si accende; gli altri si spengono (la
   geometria non si muove: cambia la luce). */
.sb-arco[data-attiva] { opacity: 1; }
/* La colonna dell'anzianita' in cui cade l'immobile guardato. */
.ig-qui .ig-pista i { background: var(--data); }

/* Lineare, perche' un impulso ha una velocita', non una curva d'ingresso: e'
   la stessa ragione per cui la curva della §38 si traccia a velocita'
   costante. I tre partono sfalsati e nell'ordine in cui si leggono gli
   anelli, cosi' non si sovrappongono mai in un lampo solo. */


/* L'alone degli anelli sale di poco: adesso c'e' un impulso che gli corre
   sopra, e un tratto troppo carico se lo mangerebbe. */


/* ------------------------------------------ 43.2 · l'anello della tipologia
   L'alone non puo' stare sul disco: `.cia-disco` ha `contain: paint` per non
   far uscire il ridisegno della maschera, e la stessa regola taglierebbe la
   luce al bordo. Sta sul contenitore, in due cerchi — uno sul bordo esterno,
   uno sul buco — perche' un anello di neon ha DUE bordi che emettono, e con
   il solo alone esterno il buco resta un ritaglio nero e la forma sembra
   stampata sopra invece che accesa. */


/* Il buco e' al 53% del raggio: il cerchio interno ha lo stesso diametro. */


/* La scia che percorre l'anello. Qui il giro intero E' dato — l'anello e'
   chiuso, le fette coprono tutti i trecentosessanta gradi — quindi un impulso
   che gira non attraversa nessun vuoto: e' la stessa lettura dell'impulso sul
   quadrante, su una forma che non ha una fine. */

/* Parte quando la lancetta d'ingresso ha finito di scoprire le fette: prima
   la composizione, poi la luce che la percorre. */

/* ---------------------------------------- 43.3 · la corona della tassonomia
   Un filtro per VISTA, non per arco: le viste nascoste sono `hidden`, quindi
   il browser ne calcola una sola, e trenta `drop-shadow` su trenta tracciati
   costerebbero trenta volte tanto per la stessa luce. */

/* L'arco sotto il dito si accende davvero, invece di limitarsi a restare
   acceso mentre gli altri si smorzano. */


/* -------------------------------------------- 43.4 · le fasce del territorio
   L'alone sta sulle CELLE, non sulla pista: la pista e' il binario, cioe' il
   contorno, e la regola di questa sezione dice che il contorno non brilla.
   Un `drop-shadow` sul contenitore delle celle disegna la luce sulla sagoma
   di quello che c'e' — una fascia quasi vuota emette quasi niente, ed e'
   esattamente quello che deve dire. */
.terr-celle {
  /* NIENTE alone qui. Su ogni altra forma la luce esce da un tratto isolato
     e si posa sul fondo; qui le celle sono attaccate, e un `drop-shadow` sulla
     sagoma dell'intera fascia non fa un contorno acceso: fa una fascia di
     luce SOTTO i blocchi, che si vede come un'ombra sbagliata e sporca il
     bordo del binario. La stondatura e il passo a due pixel bastano gia' a
     dire che sono segmenti e non un mosaico. */
  /* LE CELLE TORNANO ATTACCATE.

     Stondarle e allargare il passo le faceva sembrare sei oggetti in fila; ma
     la fascia non e' un elenco di comuni, e' UNA quantita' divisa — la sua
     larghezza intera E' la quota della zona, e le celle sono i tagli dentro
     quella larghezza. Separandole, ogni cella si leggeva come una barra a se',
     e la somma — che e' l'unica cosa che questa forma dice meglio di una
     classifica — smetteva di essere una barra sola. Un pixel di stacco basta a
     dire dove finisce un comune; tre di raggio dicevano un'altra cosa. */
}

/* LA CARICA SULLE FASCE E' USCITA.

   Rallentarla l'aveva resa sopportabile e non giusta. Una fascia del
   territorio e' ferma per natura — dice dove STA il portafoglio, non dove sta
   andando — e una luce che la attraversa promette un movimento che nel dato
   non c'e'. Il taglio del binario resta: serve comunque alla stondatura degli
   estremi. */
.terr-pista { overflow: hidden; }

/* ------------------------------------------ 43.5 · le colonne dell'istogramma
   Il tubo al neon ha un tappo acceso in cima: e' il segno che dice dove la
   colonna FINISCE, che in un istogramma e' l'unica cosa che si confronta. */
.ig-pista i {
  position: relative;
  overflow: hidden;
  /* La testa stondata e' la stessa lettura del `linecap` degli archi: una
     colonna che finisce in un angolo vivo e' un rettangolo, una che finisce
     tonda e' un tubo acceso. Sei pixel sopra, tre sotto — la base poggia
     sull'asse e non deve staccarsene. */
  border-radius: var(--r-xs) var(--r-xs) 3px 3px;
}

/* L'IMPULSO SULLE COLONNE E' USCITO.

   Non era il ritmo, era il tipo. Una colonna che si ricarica da sola dice che
   sta salendo, e queste stanno ferme: sono cinque conteggi di un export del
   quattro agosto. Il difetto e' lo stesso che la §38 nomina da sempre —
   « nessuna animazione sul dato » — solo che qui l'avevo scritto io. Resta
   l'alone, che non promette movimento: dice soltanto che il tratto emette.
   Un'animazione al TOCCO, invece, direbbe una cosa vera (« hai chiesto questa
   banda ») e sta ancora da disegnare. */

/* --------------------------------------------------------- 43.6 · le riserve
   Chi ha chiesto meno movimento tiene la luce e perde il viaggio: l'alone e'
   un fatto della forma, l'impulso e' un movimento, e qui si toglie soltanto
   il secondo. Nessuna quota sta nell'impulso — la forma resta identica. */

/* Chi ha chiesto meno trasparenza perde anche l'alone: un `drop-shadow` e'
   una velatura di luce, ed e' esattamente cio' che quella preferenza chiede
   di non avere. Le forme restano piene e leggibili — cambia il fondo, non il
   dato. */
@media (prefers-reduced-transparency: reduce) {
  .terr-celle { filter: none; }
  
}
/* In stampa non esiste luce: resta l'inchiostro. */
@media print {
  
  .terr-celle { filter: none; }
  .ig-pista i { box-shadow: none; }

}

/* --------------------------------------------- 43.7 · le torte della lastra
   Un disco pieno ha un bordo solo, quindi la luce e' un filo interno e non un
   alone esterno: e non e' una scelta di gusto, e' l'unica che regge. La
   lancetta d'ingresso mascherava il disco con un `conic-gradient`, e una
   maschera taglia anche l'ombra ESTERNA — un alone fuori dal bordo sparirebbe
   appena il movimento e' acceso. L'ombra interna sta dentro la maschera e
   resta. */
.ta-disco {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--border-strong) 70%, transparent),
              0 10px 30px -18px rgba(0, 0, 0, .35);
}
@media (prefers-reduced-transparency: reduce), print {
  .ta-disco {
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--border-strong) 70%, transparent);
  }
}

/* ===========================================================================
   §44 · IL QUADRANTE DELLA TIPOLOGIA

   La composizione lascia gli spicchi e prende gli archi. Non e' un cambio di
   gusto: nella ciambella il confronto fra due famiglie e' un confronto fra
   AMPIEZZE di spicchi attaccati, e funziona solo fra vicini — la prima e la
   quarta fetta si confrontano girandoci intorno e tenendo a mente la prima.
   Qui ogni famiglia e' un arco su una pista che vale sempre il portafoglio
   intero: la scala e' una sola, gli archi stanno uno sotto l'altro, e sei
   lunghezze in colonna si guardano invece di leggerle.

   Il prezzo esiste e va nominato: l'anello chiuso DICHIARAVA la somma — «
   quello che vedi e' tutto » — e sei archi concentrici no. Lo dice al posto
   loro la pista, che e' il cento di ciascuno, e la cifra al centro, che e' il
   totale su cui quei cento sono calcolati.

   La forma e' quella della §41, quindi qui non si ridisegna niente: cambiano
   il numero di anelli, che e' dato, e il loro spessore, che ne discende. Il
   raggio e il passo li calcola il modello nel markup — da 92 a 30 su cento,
   qualunque sia il numero di famiglie — cosi' il buco al centro resta lo
   stesso e la cifra dentro non cambia mai misura.
   ------------------------------------------------------------------------ */
.cia-quadrante .cia-anello { display: grid; place-items: center; }
.qt-disco {
  width: 100%; height: 100%; display: block;
  /* Gli archi partono dalle dodici, non dalle tre. */
  transform: rotate(-90deg);
}
.qt-pista {
  fill: none;
  stroke: color-mix(in srgb, var(--border) 85%, transparent);
  stroke-width: var(--sp, 8);
}
.qt-arco {
  fill: none;
  stroke-width: var(--sp, 8);
  /* La testa tonda e' la stessa della §43: un arco che finisce tondo e' un
     tubo acceso, uno che finisce a spigolo e' un settore ritagliato. */
  stroke-linecap: round;
  stroke-dasharray: var(--q) 100;
  filter: drop-shadow(0 0 6px color-mix(in srgb, currentColor 34%, transparent));
  transition: opacity 200ms var(--ease-out), stroke-width 200ms var(--ease-out);
}
/* LA RAMPA SI GIRA, E SOLO QUI.

   Nella ciambella la famiglia piu' grande aveva il gradino piu' SCURO, e
   funzionava: uno spicchio e' un'area, e un'area scura su fondo scuro si vede
   lo stesso perche' e' larga. Un arco no. Un arco e' un tratto da otto pixel,
   e sui due gradini bassi della rampa (#3d2411, #7a4216) su questo fondo
   semplicemente non c'e' — il risultato era un disegno in cui le tre famiglie
   che FANNO il portafoglio sparivano e si vedevano solo le tre piccole.

   Quindi qui la rampa va dal chiaro allo scuro seguendo la quantita', come
   nel quadrante della Panoramica, e resta dentro la meta' alta: sei toni che
   su questo fondo esistono tutti. « L'arancio e' la scala » vale ancora — e'
   la stessa scala, letta dall'altro capo.

   Il pallino della legenda si gira insieme all'anello, e solo dentro questa
   figura: il pallino accanto al nome e il suo arco devono essere lo STESSO
   colore, o la legenda torna a essere un elenco accanto a un disegno. */
.cia-quadrante .qt-arco.g0  { color: var(--ramp-5); }
.cia-quadrante .qt-arco.g1  { color: var(--ramp-4); }
.cia-quadrante .qt-arco.g2  { color: var(--ramp-3); }
.cia-quadrante .qt-arco.g3  { color: var(--ramp-2); }
.cia-quadrante .qt-arco.g4  { color: var(--ramp-1); }
.cia-quadrante .qt-arco.g-1 { color: var(--coda); }
.qt-arco { stroke: currentColor; }

.cia-quadrante .cia-leg .g0 { background: var(--ramp-5); }
.cia-quadrante .cia-leg .g1 { background: var(--ramp-4); }
.cia-quadrante .cia-leg .g2 { background: var(--ramp-3); }
.cia-quadrante .cia-leg .g3 { background: var(--ramp-2); }
.cia-quadrante .cia-leg .g4 { background: var(--ramp-1); }

/* Gli anelli si compongono dal piu' grande al piu' piccolo, cioe' nell'ordine
   della legenda: una volta sola per comparsa, come ogni ingresso della §38. */
[data-moto="si"] .qt-arco {
  animation: qdr-traccia 900ms var(--ease-out) backwards;
  animation-delay: calc(var(--i) * 110ms + 140ms);
}


/* La cifra al centro. Le misure sono in unita' di CONTENITORE e non in pixel:
   il buco e' una frazione fissa del disco e il disco una frazione fissa del
   modulo, quindi l'unica misura che tiene a ogni larghezza e' quella che
   scala con loro. In pixel, a modulo stretto, il totale usciva dal buco. */
.qt-cifra {
  /* `inset: 0` e non la sola `position: absolute`: senza, la cifra resta alla
     sua posizione STATICA — l'angolo del riquadro — invece che al centro del
     disco, e il totale finisce accanto agli anelli anziche' dentro. */
  position: absolute; inset: 0;
  display: grid; place-content: center; justify-items: center; gap: 2px;
  text-align: center;
  pointer-events: none;
}
.qt-cifra span {
  font: 640 clamp(16px, 4.6cqw, 26px)/1 var(--font-ui);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.03em;
  color: var(--text);
}
.qt-cifra i {
  font-style: normal;
  font-size: clamp(10px, 1.7cqw, 11px);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Gli aloni della §43 sull'anello escono: erano tarati sul disco pieno e sul
   suo buco al 53%, e qui non c'e' ne' l'uno ne' l'altro. La luce ce l'ha ogni
   arco per conto suo, che e' anche piu' giusto — emette il dato, non la
   cornice intorno al dato. */


/* ------------------------------------------- il dito accende un anello solo
   La §39 applicata alla legenda: si smorza il resto invece di far sparire
   qualcosa. Sei coppie e non una regola sola perche' il legame fra la riga e
   il suo anello e' posizionale, e in CSS la posizione non si passa. */
@media (hover: hover) and (pointer: fine) {
  .cia-quadrante:has(.cia-leg li:nth-child(1):hover) .qt-arco:not(.qt-r1),
  .cia-quadrante:has(.cia-leg li:nth-child(2):hover) .qt-arco:not(.qt-r2),
  .cia-quadrante:has(.cia-leg li:nth-child(3):hover) .qt-arco:not(.qt-r3),
  .cia-quadrante:has(.cia-leg li:nth-child(4):hover) .qt-arco:not(.qt-r4),
  .cia-quadrante:has(.cia-leg li:nth-child(5):hover) .qt-arco:not(.qt-r5),
  .cia-quadrante:has(.cia-leg li:nth-child(6):hover) .qt-arco:not(.qt-r6) { opacity: .18; }
  .cia-leg li:hover .cia-n { color: var(--text); }
}

@media (prefers-reduced-motion: reduce) {
  [data-moto="si"] .qt-arco { animation: none; }
}
@media (prefers-reduced-transparency: reduce) {
  .qt-arco { filter: none; }
}
@media print {
  .qt-arco { filter: none; }
}

/* ===========================================================================
   §45 · LA TASSONOMIA IN UN RIQUADRO, E TIRATA A SINISTRA

   Il titolo, la corona e la legenda sono una lettura sola: il titolo dice che
   cosa si guarda, la forma lo mostra, la legenda lo nomina. Sciolti sulla
   pagina erano tre blocchi affiancati per caso — e la colonna della forma,
   dichiarata `1fr`, si prendeva tutto l'avanzo della riga, spingendo la
   legenda all'altro capo. Quella distanza non separava niente: era l'avanzo,
   e un avanzo messo fra due cose che si leggono insieme si legge come « queste
   due non c'entrano ».
   ------------------------------------------------------------------------ */
.tassonomia {
  /* Il riquadro si ferma dove finisce la lettura. Largo quanto la pagina, con
     il contenuto tirato a sinistra, rimetterebbe a destra lo stesso vuoto che
     si e' appena tolto fra la corona e la legenda — solo dentro una cornice,
     che lo rende piu' evidente e non meno.

     Un TETTO e non `fit-content`: `fit-content` risolve sul contenuto minimo,
     e il contenuto minimo di questa griglia e' il disco alla sua misura piu'
     piccola — il riquadro si stringeva a duecentonovanta pixel portandosi
     dietro la corona rimpicciolita. Un tetto lascia alle colonne una larghezza
     definita su cui dividersi. */
  max-width: 760px;
  margin-top: var(--sp-5);
  padding: var(--sp-4) var(--sp-5) var(--sp-5);
  border: 1px solid var(--border);
  border-radius: var(--r-3);
  /* La stessa materia dei moduli della plancia: un riquadro nuovo che si
     dipinge da solo sarebbe un secondo linguaggio per la stessa cosa. */
  background: linear-gradient(180deg,
              color-mix(in srgb, var(--surface-2) 70%, transparent) 0%,
              var(--surface) 42%, var(--surface) 100%);
  box-shadow: 0 1px 0 0 color-mix(in srgb, var(--border-strong) 55%, transparent) inset,
              0 2px 10px -6px rgba(0, 0, 0, .7);
}
.tassonomia > .mt { margin-top: 0; }
.tassonomia > .sb-conta { margin-bottom: var(--sp-4); }

/* Il disco si ferma dove finisce, e sta a sinistra: e' il primo elemento
   della lettura, quindi comincia dove comincia il testo sopra. La misura e'
   DEFINITA e non `min(100%, 420px)`: in una colonna dimensionata sul
   contenuto quel cento per cento non ha su che cosa risolversi, e il disco
   restava alla misura minima invece che alla sua. */
.sb-piano { justify-self: start; width: 420px; max-width: 100%; }
/* La briciola apre la colonna della legenda, allineata con le voci sotto:
   centrata sembrava un titolo della legenda, e non lo e' — e' dove sei. */
.sb-briciole { justify-self: start; }

/* ===========================================================================
   §46 · IL GETTO SULLA CURVA — dove sta scritto

   Non sta qui. La prima versione era una banda di luce che attraversava tutta
   la tela: passava sopra il grafico invece che dentro, e una banda
   rettangolare su un riquadro rettangolare non ha niente a che vedere con la
   forma che ci sta dipinta. Adesso il getto e' disegnato sulla TELA insieme
   alla curva — `portafoglio.js`, plugin `getto` — perche' i due segni che
   servono si possono ritagliare solo li': lo sfumato dentro l'area fra la
   curva e la base, la fascia accesa lungo il tracciato. Un `::after` in CSS
   non sa dov'e' la curva.
   ------------------------------------------------------------------------ */

/* ===========================================================================
   §47 · IL SELETTORE DI REPARTO — un filo di colore al posto di un logo

   La sigla in riquadro e' uscita da tutte e tre le posizioni, compresa quella
   chiusa. Due lettere dentro un quadrato sono un logo, e un logo serve a dire
   chi sei a chi non lo sa: qui lo sanno tutti, e in una barra da due voci quel
   quadrato occupava il posto senza aggiungere una lettura.

   Al suo posto un filo verticale di colore, che e' il segno piu' corto
   possibile per « questo e' un ambiente diverso da quello ». E i due colori
   NON sono due tinte scelte per distinguere: sono i due accenti che i due
   reparti gia' usano dentro di se' — il rame degli Immobili e l'oro del
   Marketing — quindi il filo nel menu e' un'anteprima vera dell'ambiente in
   cui si sta per entrare, non un'etichetta appiccicata sopra.

   Scritti a mano e non presi da `--accent`, perche' `--accent` cambia valore
   con il reparto attivo: usarla farebbe due fili dello stesso colore, cioe'
   esattamente il difetto da togliere.
   ------------------------------------------------------------------------ */


/* IL FILO E' USCITO, E CON LUI IL RIQUADRO SULLA VOCE CORRENTE.

   Erano tre segni per una domanda sola. « Quale reparto » lo dice gia' il
   NOME, che porta il colore del suo reparto; « in quale sono » lo dice la
   spunta, che e' un segno con un significato solo e nessuna ambiguita'. Il
   filo colorato ripeteva il primo, la cornice ripeteva la seconda, e due
   ripetizioni in un menu da due voci non rinforzano: riempiono.

   Resta la regola della §47 — i due colori sono i due accenti veri dei
   reparti, non due tinte scelte per distinguere — solo che adesso li porta il
   testo, che e' la cosa che si legge comunque. */


/* Il nome porta il colore del suo reparto anche quando non e' quello attivo:
   e' meta' del segno, e senza, la voce non corrente resta un testo bianco
   accanto a un filo colorato — due cose invece di una. */


/* Una riga sottile fra i due, non uno stacco: sono due voci dello stesso
   elenco, non due blocchi. */


/* La riga che spiega e' una parola sola: « Portafoglio », « Canali web ». Tre
   righe di claim in un menu da due voci erano una scheda prodotto, e una
   scheda prodotto si legge una volta e poi si scavalca per sempre. */


/* ===========================================================================
   §48 · IL DITO SCEGLIE UNA PARTE — e la parte si accende da tutte e due i capi

   La forma e la sua legenda sono due modi di dire la stessa cosa, e finora si
   rispondevano solo in una direzione. Adesso indicare l'arco accende la riga e
   indicare la riga accende l'arco: e' `[data-attiva]`, scritto dal browser sul
   nodo che porta lo stesso `data-voce`.

   Si SMORZA il resto invece di far sparire qualcosa (§39): una parte che
   scompare fa sembrare cambiato il totale.
   ------------------------------------------------------------------------ */
.cia-quadrante .qt-arco[data-attiva] { stroke-width: calc(var(--sp, 8) + 3); }
.cia-quadrante:has([data-attiva]) .qt-arco:not([data-attiva]) { opacity: .2; }
.cia-quadrante .cia-leg li { transition: color var(--t-stato) var(--ease-out),
                                         opacity var(--t-stato) var(--ease-out); }
.cia-quadrante .cia-leg:has([data-attiva]) li:not([data-attiva]) { opacity: .4; }
.cia-quadrante .cia-leg li[data-attiva] .cia-n { color: var(--text); }


/* La cifra al centro cambia di continuo mentre il dito attraversa gli anelli:
   l'etichetta sotto va a capo o tronca a seconda della parola, e un centro che
   cambia ALTEZZA a ogni passaggio fa ballare il disco intorno. Una riga sola,
   larga quanto il buco. */
.qt-cifra i {
  max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Il centro dichiara che sta leggendo una parte e non il totale: l'etichetta
   si schiarisce, la cifra no — la cifra e' gia' la cosa piu' luminosa che c'e',
   e accenderla di piu' non aggiunge un grado, toglie il contrasto. */
.qt-cifra[data-attiva] i { color: var(--text); }

/* ===========================================================================
   §49 · LE BANDE RISPONDONO COME LE TELE

   L'istogramma e' fatto di elementi veri, le tele di pixel: due tecniche, e
   finora due comportamenti. La domanda pero' e' la stessa — « che cosa succede
   QUI » — e qui e' un intervallo, non una coordinata. Quindi lo stesso segno:
   una fascia di fondo larga quanto la banda, chiusa da due fili verticali.

   UNA SOLA fascia per istogramma, e non una per colonna. Due elementi che si
   scambiano l'opacita' sono due lampi vicini; uno che cambia posizione e' una
   cosa che si sposta, ed e' quello che sta facendo la mano. Lo scivolamento lo
   fa la transizione: `left` e `width` sono due proprieta' che costringono a
   rifare l'impaginazione, ma qui la fascia e' l'unico figlio assoluto di un
   riquadro che non ne contiene altri — non c'e' niente da rimpaginare dietro.
   ------------------------------------------------------------------------ */
.ig { position: relative; }
.ig::before {
  content: "";
  position: absolute; top: 0; bottom: 0;
  /* `left` NON si anima: e' una proprieta' che rimpagina, e rimpaginare a
     ogni fotogramma mentre il puntatore attraversa cinque bande e' esattamente
     lo scatto che si vedeva. La fascia sta ferma a sinistra e si SPOSTA con
     una trasformazione, che il compositore muove da solo senza toccare
     l'impaginazione. La larghezza non e' animata affatto: le colonne sono
     `flex: 1 1 0`, quindi larghe uguali, quindi la fascia ha una misura sola
     per tutto l'istogramma e cambia solo di posto. */
  left: 0; width: var(--seg-w, 0);
  transform: translateX(var(--seg-x, 0));
  opacity: var(--seg-o, 0);
  pointer-events: none;
  z-index: 0;
  border-radius: var(--r-1);
  background: color-mix(in srgb, var(--seq-4) 11%, transparent);
  border-left: 1px solid color-mix(in srgb, var(--seq-4) 38%, transparent);
  border-right: 1px solid color-mix(in srgb, var(--seq-4) 38%, transparent);
  will-change: transform;
  transition: transform 170ms var(--ease-out), opacity 140ms var(--ease-out);
}
.ig-col { position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) {
  .ig::before { transition: opacity 100ms linear; }
}

/* ---------------------------------------------------------------------------
   §49.1 · IL RESPIRO — l'unica cosa che si muove da sola su un dato fermo

   Le bande e le fasce sono ferme per natura: contano un export del quattro
   agosto. Ogni animazione che ne muova la GEOMETRIA promette un movimento che
   nel dato non c'e' — e' la ragione per cui la carica e l'impulso sono usciti.

   Ma la LUCE non e' geometria. Un respiro lentissimo sulla luminosita' — cinque
   centesimi di scarto, sette secondi di giro, ogni banda mezzo secondo dopo la
   precedente — non sposta niente, non allunga niente, non fa ripartire nessun
   conteggio. Dice la sola cosa che la §41 ha sempre lasciato dire al movimento
   continuo: la superficie e' viva. Ed e' lo stesso respiro dell'alone sotto il
   quadrante della Panoramica, portato dove serviva.

   Lo scarto e' scelto per non vedersi mentre lo si guarda: si nota se lo si
   toglie, non mentre passa. Sopra il cinque per cento diventa un battito, e un
   battito su una cifra si legge come un allarme. */
/* IL RESPIRO NON SI VEDEVA, E LA RAGIONE E' ARITMETICA.

   Era `brightness(1.05)` sull'elemento. Su un fondo chiaro cinque centesimi si
   notano; su questi bruni no — il gradino piu' basso della rampa e' #7a4216, e
   il cinque per cento di quel colore sono sei livelli su duecentocinquantasei.
   Sei livelli non sono un'animazione discreta: sono un'animazione assente.
   La moltiplicazione non aggiunge luce dove non ce n'e', la scala.

   Quindi la luce si AGGIUNGE, invece di moltiplicarla: una velatura chiara
   sopra il pieno, che porta la sua luminanza per conto suo e si vede uguale su
   qualunque tinta ci sia sotto. E non pulsa tutta insieme — ogni banda parte
   mezzo secondo dopo la precedente, cosi' quello che si vede non e' un
   lampeggio ma UN'ONDA che attraversa la forma nel verso in cui la si legge.
   Un'onda ha una direzione, e una direzione e' una cosa che si guarda; un
   lampeggio non ha niente da guardare, si subisce.

   Resta la regola: si muove la luce, mai la geometria. Nessuna colonna cresce,
   nessuna cella si sposta, nessun conteggio riparte. E sotto il dito l'onda si
   ferma — si sta leggendo QUELLA banda. */
/* La cresta e' larga: l'onda sale, resta un istante e scende. Un picco
   istantaneo su una curva morbida si vede solo se lo si sta fissando — e
   nessuno fissa un istogramma aspettando un lampo. */
/* Le celle del territorio: la stessa velatura, orizzontale come le fasce, e
   l'onda scende per le valli nell'ordine geografico dichiarato. Sta sulla
   CELLA e non sul contenitore perche' cosi' segue la sagoma di quello che c'e':
   una zona quasi vuota emette quasi niente, che e' esattamente cio' che deve
   dire. */


/* La coda e il resto non hanno una resa e non sono campiti: non emettono. */


/* La griglia orizzontale, e solo quella. Le linee verticali direbbero dove
   finisce una banda — che si vede gia', le bande sono staccate — mentre le
   orizzontali portano la scala, che e' l'unica cosa che una colonna da sola
   non dice: quanto e' alta rispetto a che cosa. Stanno DENTRO il binario, e i
   binari sono tutti alti uguale, quindi le righe si allineano da sole. */
.ig-pista {
  background-image: repeating-linear-gradient(
    to top,
    transparent 0, transparent calc(25% - 1px),
    color-mix(in srgb, var(--border) 55%, transparent) calc(25% - 1px),
    color-mix(in srgb, var(--border) 55%, transparent) 25%);
}
@media print { .ig::before { display: none; } }

/* ===========================================================================
   §50 · IL TELEFONO — la stessa plancia, letta col pollice
   ===========================================================================

   Non è una versione per telefono. È lo stesso prodotto — le stesse sezioni,
   gli stessi moduli, le stesse forme, gli stessi comandi — tradotto in uno
   schermo largo quanto una mano. La regola che decide ogni caso è una:

     COMPOSIZIONE DEL COMPUTER → COMPOSIZIONE DEL TELEFONO,
     MAI FUNZIONE DEL COMPUTER → FUNZIONE TOLTA.

   Tre primitive condivise, e ogni pagina le riceve senza saperlo:

     1. il DOCK — la barra laterale scende in fondo allo schermo. Chiusa porta
        le sezioni del reparto in fila sotto il pollice; «Menu» la apre dal
        basso con tutto il resto (marchio, reparto, Direzione, età dei dati).
        È lo stesso elemento: nessuna seconda navigazione da tenere allineata.
     2. i MARGINI SICURI — la pagina arriva sotto la tacca e l'angolo tondo
        (`viewport-fit=cover`), e ogni cosa che si tocca sta dentro
        `env(safe-area-inset-*)`.
     3. gli STRATI — lastra e lente restano finestre sopra la pagina, non
        pagine nuove: occupano quasi tutto lo schermo, ma si vede ancora il
        velo che dice « sotto c'è da dove vengo ».

   Quando vale. Un telefono in verticale è sotto i 760 px di larghezza; un
   telefono in orizzontale è largo come un portatile piccolo ma alto meno di
   500 px, e con un dito — `pointer: coarse` — non con un mouse. Un portatile
   con una finestra bassa NON è un telefono: resta la sua barra laterale.

   Il resto del foglio non viene toccato: sopra i 760 px il computer e il
   tablet sono esattamente quelli di prima.
   =========================================================================== */

/* Il fondo della pagina è del documento, non solo del corpo.

   Il corpo porta sfumature fisse e nessun colore pieno: sul computer non si
   vede la differenza, su un telefono sì — trascinando oltre la fine della
   pagina il browser mostra il fondo del DOCUMENTO, ed era bianco. Un lampo
   bianco sotto uno strumento scuro si legge come un errore di caricamento. */


/* Il pulsante del dock e il suo velo esistono solo sul telefono. */


/* Il ripiego della plancia (sotto i 1180 px) diceva « due colonne, poi una »,
   ma il Portafoglio dichiara le sue ventiquattro colonne con un selettore più
   preciso — `.plancia[data-plancia="portafoglio"]` — e vinceva lui: sotto i
   1180 px i sei moduli restavano in ventiquattro colonne con la casella tolta,
   larghi trentaquattro pixel ciascuno, uno sopra l'altro. Qui la regola del
   ripiego viene detta con la stessa precisione, e l'ORDINE lo decide la
   casella in cui il modulo sta sulla plancia larga (`plancia.js`, 1b). */


@media (max-width: 760px), (pointer: coarse) and (max-height: 500px) {

  /* ------------------------------------------------------------ 50.1 ---
     IL DOCK, chiuso: le sezioni in fila. */
  
  /* Chiuso, il dock porta solo le sezioni e il pulsante. Tutto il resto della
     barra c'è — nel documento, per lettori di schermo e per chi apre — e
     compare nel foglio aperto. */
  

  
  /* La fila si dissolve ai due capi SOLO quando continua oltre il bordo (il
     Marketing, sette sezioni): lì dice « c'è dell'altro » senza una freccia
     che occupi il posto di una sezione. Quando le sezioni stanno tutte in
     vista la dissolvenza mangerebbe la prima lettera di « Panoramica ».
     `dock-sx` e `dock-dx` li mette il dock stesso: la dissolvenza sta
     soltanto dal lato in cui la fila continua. */
  
  
  
  
  

  /* Una sezione è un bersaglio da quarantotto pixel, non una riga di testo:
     il punto sopra il nome è lo stesso segno della barra del computer, qui
     messo dove il pollice lo vede mentre preme. */
  
  
  /* Quando la fila non ci sta (il Marketing), ogni sezione prende la
     larghezza del suo nome più un margine da dito, e la fila scorre. */
  
  
  
  

  
  
  
  /* Il nome resta per chi legge lo schermo; a vista basta il segno, che è
     quello che ogni telefono usa per « tutto il resto ». Lo spazio che libera
     è quello che serve alla quinta sezione degli Immobili per stare in fila. */
  
  

  /* ------------------------------------------------------------ 50.2 ---
     IL DOCK, aperto: la stessa barra, dal basso. */
  
  
  /* Aperto, «Menu» diventa la croce in alto a destra: lo stesso bottone che
     ha aperto chiude, e sta nel punto in cui ogni foglio lo mette. */
  
  
  
  

  
  
  

  .page-head { gap: var(--sp-2) var(--sp-3); }
  .page-head h1 { font-size: var(--fs-6); line-height: 1.15; }

  /* Un bersaglio da dito: nessun comando sotto i 44 px di lato. È la misura
     che le linee guida di iOS e Android danno per un polpastrello, e sotto la
     quale un tocco finisce sul vicino. */
  button.btn,
a.btn,
.btn-small,
select,
input[type="file"]::file-selector-button,
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="hidden"]) {
    min-height: 44px;
  }
  /* Alto quarantaquattro e con il testo al centro: un `<a class="btn">` in
     linea, allungato, teneva il nome in cima e sotto un vuoto. */
  a.btn { display: inline-flex; align-items: center; justify-content: center; }
  select, input, textarea { font-size: 16px; }  /* sotto i 16 px iOS ingrandisce la pagina al tocco */

  /* Un modulo di invio in colonna: il campo « che cresce » aveva una base di
     240 px pensata per la riga del computer, e in colonna diventava 240 px di
     ALTEZZA vuota fra la nota e il bottone. */
  .gen-form .field-grow { flex: 0 0 auto; }
  .card { padding: var(--sp-4); }
}

/* ---------------------------------------------------------------- 50.4 ---
   IL TOCCO, dovunque manchi il puntatore (telefono, tablet, schermo
   tattile). Sul computer con il mouse queste regole non valgono.

   Il segno « si apre » di un modulo stava spento finché il puntatore non
   arrivava: senza puntatore non arrivava mai, e un modulo che si apre senza
   dirlo è un comando nascosto. Qui resta acceso — piccolo, in un angolo, con
   una sua superficie — e dice al dito che il riquadro porta a un dettaglio. */
@media (hover: none) {
  
  .mod[data-apre] .mod-testa { padding-right: 34px; }
  /* Il bottone che apre una forma resta disegnato a ventisei pixel — è un
     segno d'angolo, non un comando da mettere in evidenza — ma il bersaglio
     del dito è di quarantadue: un alone invisibile tutto intorno. */
  .fo-apri::before { content: ""; position: absolute; inset: -8px; }
  /* Il lampo grigio del browser sul tocco non è di Quadra: la pressione la
     dicono già la scala e il colore dei comandi. */
  a,
button,
[role="button"],
.terr-cella,
summary { -webkit-tap-highlight-color: transparent; }
}

/* ---------------------------------------------------------------- 50.5 ---
   LA PLANCIA DEL PORTAFOGLIO, su un telefono.

   Una colonna sola, nell'ordine in cui la plancia larga si legge (colonna
   dopo colonna, `plancia.js` 1b). Nessun modulo perde una riga: le misure
   di altezza erano il bilancio di uno schermo che non scorre, e qui lo
   schermo scorre — quindi le forme riprendono l'altezza che serve a
   leggerle, invece di quella che avanzava. */
@media (max-width: 760px), (pointer: coarse) and (max-height: 500px) {
  
  .plancia[data-plancia] > .mod {
    min-height: 0;
    padding: var(--sp-4);
  }
  
  

  /* Il sommario: cinque cifre in due colonne, e la quinta — il prezzo —
     sulla riga intera. I fili verticali separavano cifre in fila; in una
     griglia le separa lo spazio, e un filo a metà riga sembrerebbe un bordo
     rimasto lì per sbaglio. L'etichetta va a capo invece di troncarsi:
     « CON ANNUNCIO A… » non è un'etichetta più corta, è un'altra etichetta. */
  
  
  .som-voce:nth-child(5) {
    grid-column: 1 / -1;
    padding-top: var(--sp-3);
    border-top: 1px solid var(--border);
  }
  
  

  /* Il territorio: il nome della zona va a capo su due righe invece di
     perdere la fine. « Altre / fuori provinc » non è una zona. */
  
  

  /* La tipologia: il quadrante sopra, la legenda e le tre letture sotto. Il
     disco affiancato a sei voci in una colonna da trecento pixel diventava un
     bollino accanto a un elenco; impilati, il disco torna una forma e la
     legenda una tabella che si legge. */
  .mod-corpo .cia, .mod-corpo .cia.cia-quadrante {
    flex-direction: column;
    align-items: stretch;
    gap: var(--sp-4);
    height: auto;
  }
  .mod-corpo .cia-anello {
    align-self: center;
    width: min(248px, 72%);
    height: auto;
    aspect-ratio: 1;
  }
  .mod-corpo .cia-col { height: auto; width: 100%; align-self: stretch; gap: var(--sp-3); }
  .mod-corpo .cia-leg { gap: 6px; }
  .mod-corpo .cia-leg li { font-size: var(--fs-3); line-height: 1.3; }
  .mod-corpo .cia-extra { padding-top: var(--sp-3); gap: var(--sp-2); }

  /* LE RIGHE TORNANO ALTE QUANTO IL LORO CONTENUTO.
     Sulla plancia larga le righe di un elenco si dividono l'altezza del
     modulo (`flex: 1 1 0`): sei fasce di prezzo restano sei comunque sia alto
     il riquadro. Su una colonna che scorre il riquadro non ha un'altezza da
     dividere — è alto quanto ciò che contiene — e una base zero lascia ogni
     riga alta zero: dieci zone una sopra l'altra nello stesso pixel. Qui ogni
     riga dichiara la sua, e ne dichiara abbastanza per un dito: si toccano
     per leggere il cartellino. */
  
  .mod-corpo .dv-riga,
  .mod-corpo .ds-riga { flex: 0 0 auto; min-height: 34px; }
  .mod-corpo .mv-riga { flex: 0 0 auto; min-height: 30px; font-size: var(--fs-2); }
  .mod-corpo .mv { gap: 2px; }

  /* L'anzianità: le colonne si prendono l'altezza di una forma. */
  .mod-forma-alta { min-height: 168px; }

  /* La visibilità: il percorso e la curva riprendono la loro altezza. La
     curva è la sola forma del riquadro in cui l'altezza È la lettura — più è
     alta, più si vede dove smette di salire. */
  
  
}

/* ---------------------------------------------------------------- 50.6 ---
   GLI STRATI SUL TELEFONO — lastra e lente restano finestre.

   Sul computer la lastra è larga l'84% e la lente ha tre misure scelte dalla
   forma. Su un telefono ogni misura in percentuale diventa la stessa: quasi
   tutto lo schermo, con otto pixel di velo tutto intorno — abbastanza per
   vedere che sotto c'è ancora la pagina da cui si è venuti, e che la finestra
   si chiude toccando fuori. Una finestra a tutto schermo senza bordo sarebbe
   una pagina nuova, e una pagina nuova non ha un « da dove vengo ».

   L'altezza è quella dello schermo UTILE: dentro i margini sicuri, sotto la
   tacca e sopra la barra del gesto, con `dvh` che segue la barra degli
   indirizzi quando compare e scompare. Il corpo scorre dentro la finestra;
   la testata con la croce resta ferma in cima, sempre a portata. */
@media (max-width: 760px), (pointer: coarse) and (max-height: 500px) {
  .lastra.lastra-larga,
.lente,
.lente[data-misura="compatta"],
.lente[data-misura="media"],
.lente[data-misura="ampia"] {
    inset: calc(8px + env(safe-area-inset-top)) max(8px, env(safe-area-inset-right))
           calc(8px + env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left));
    margin: 0;
    width: auto;
    height: auto;
    max-height: none;
    border-radius: var(--r-lg);
  }
  /* La lastra sta SOPRA il dock, e la lente sopra la lastra: il dock è il
     guscio, gli strati sono il lavoro in corso. */
  
  

  .lente-testa {
    padding: var(--sp-4) var(--sp-4) var(--sp-3);
    gap: var(--sp-3);
  }
  .lastra-testa h2, .lente-testa h2 { font-size: var(--fs-5); line-height: 1.2; }
  /* La croce: quarantaquattro pixel, il minimo per un pollice. Sul computer
     è di trenta, e lì va bene: lì c'è un mouse. */
  

  .lastra.lastra-larga .lastra-corpo {
    padding: var(--sp-4) var(--sp-4) calc(var(--sp-6) + env(safe-area-inset-bottom));
    /* Arrivati in fondo al corpo, il dito non trascina la pagina sotto. */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  .lastra-corpo .grid-2,
  .lastra-corpo .grid-4 { grid-template-columns: minmax(0, 1fr); }
  .lastra-corpo .chart-box { height: 260px; }
  .lastra-corpo .chart-box.grande { height: 300px; }
  .torte { grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); }

  .lente-corpo { padding: var(--sp-4); overscroll-behavior: contain; }
  .lente-corpo .chart-box { height: min(52dvh, 420px); }
  .lente-corpo .chart-box.grande { height: min(58dvh, 460px); }
  .lente-corpo .ta-disco { width: min(300px, 86%); }
  .lente-corpo .cia-anello { height: min(300px, 36dvh); }
  .lente-corpo .sb-piano { width: min(100%, 440px, 46dvh); }

  /* I comandi dello zoom vanno a capo sotto il titolo: accanto alla croce,
     in una testata larga trecento pixel, schiacciavano il titolo a una
     parola. Ogni bottone diventa un bersaglio da dito. */
  .lente-testa { flex-wrap: wrap; }
  .lente-testa > div:first-child { flex: 1 1 calc(100% - 60px); }
  .lente-comandi { order: 3; flex: 1 1 100%; justify-content: space-between; padding: 3px; }
  .lente-comandi button { width: 40px; height: 40px; }
  .lente-comandi button svg { width: 14px; height: 14px; }
  .lente-reset { flex: 1; }
  .lente-lettura { height: auto; min-height: 44px; padding: var(--sp-2) var(--sp-4); line-height: 1.35; }

  /* Mentre uno strato è aperto, la pagina sotto non scorre: il dito che
     scorre una tabella nella lastra non deve portarsi dietro la plancia. */
  html:has(.lastra.aperta), html:has(.lastra.aperta) body,
  html:has(.lente.aperta), html:has(.lente.aperta) body { overflow: hidden; }
}

/* Con lo zoom acceso il GRAFICO appartiene alla lente: sopra il disegno un
   dito trascina e due pizzicano, e il browser non interviene. Fuori dal
   disegno — la legenda, le note, la tabella clonata sotto — il dito scorre la
   finestra come sempre: nessuno scorrimento diventa uno zoom per sbaglio, e
   nessuno zoom uno scorrimento. */
.lente-con-zoom .chart-box { touch-action: none; }
@media (max-width: 760px), (pointer: coarse) and (max-height: 500px) {
  .lente-con-zoom .lente-corpo { overflow: auto; display: block; }
}

/* ---------------------------------------------------------------- 50.7 ---
   LA PANORAMICA, sul telefono: il quadrante e le quattro cifre in UNO
   schermo, come sul computer.

   Il ripiego a colonna singola (sotto i 620 px) metteva il quadrante a
   tutta larghezza e sotto quattro riquadri alti uno schermo intero: prima di
   leggere la seconda cifra bisognava scorrere. La domanda della Panoramica è
   « com'è messo, adesso, tutto insieme », e « tutto insieme » vuol dire nella
   stessa vista. Il quadrante scende a una misura che si guarda senza
   scorrere, e le cifre tornano due per riga — la stessa griglia della
   plancia larga, con meno aria dentro ogni riquadro. */
@media (max-width: 760px), (pointer: coarse) and (max-height: 500px) {
  
  
  
  
  
  
  
  

  /* La riga di contesto accanto al titolo di sezione (« 7 famiglie ·
     89,3% pubblicato ») va sotto il titolo, senza il filo verticale che la
     separava da lui: in colonna quel filo non separa niente, resta un
     trattino appeso. */
  .piano-testa { flex-wrap: wrap; row-gap: var(--sp-2); }
  .piano-misure { margin-left: 0; padding-left: 0; width: 100%; gap: var(--sp-1) var(--sp-4); }
  .piano-misure::before { display: none; }

  /* Le misure del periodo: le due cifre sotto la capofila restano affiancate
     (è un confronto), e i quattro gruppi restano quattro. */
  
}

/* ---------------------------------------------------------------- 50.8 ---
   QUALITÀ DATI, sul telefono: la stessa plancia, in un ordine che si legge
   dall'alto in basso — le due sorgenti, le eccezioni, i non pubblicati, le
   sorgenti e la popolazione, la tassonomia. */
@media (max-width: 760px), (pointer: coarse) and (max-height: 500px) {
  /* Le due sorgenti a confronto. Tre colonne — nome, banda, cifre — in
     trecento pixel lasciavano alla banda zero pixel: la forma spariva e
     restavano due righe di testo. Il nome e le cifre stanno sopra, la banda
     sotto a tutta larghezza, dove i due segmenti tornano confrontabili. */
  .ric {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "nome cifre" "banda banda";
    gap: var(--sp-2) var(--sp-3);
    margin: var(--sp-3) 0;
  }
  .ric > .ric-l { grid-area: nome; }
  .ric > .bn { grid-area: banda; }
  .ric > .ric-n { grid-area: cifre; text-align: right; font-size: var(--fs-2); }

  /* La tassonomia si mostra intera. Uno scorrimento dentro uno scorrimento
     è il modo più sicuro di perdere il dito — lo diceva già il commento
     della regola sotto i 1180 px, che però le lasciava un tetto di 320 px:
     nove righe su ventisei e una barra da trovare. Qui la pagina scorre, e
     la tassonomia scorre con lei. */
  .tx-scroll { max-height: none; overflow: visible; }
}

/* ---------------------------------------------------------------- 50.9 ---
   LE TABELLE, sul telefono. Due trattamenti, scelti dalla tabella e non
   dalla pagina:

     · un REGISTRO — una riga è una cosa (un file, un report, un campo) e le
       colonne sono le sue proprietà — diventa una colonna di SCHEDE:
       `table.tbl-schede`. Ogni cella porta il nome della sua colonna
       (`data-etichetta`), nello stesso ordine; nessuna colonna sparisce e
       nessuna ne nasce. Una tabella a sette colonne ristretta a trecento
       pixel non è una tabella: è una colonna di parole spezzate.
     · una MATRICE DI NUMERI — le righe si confrontano fra loro colonna per
       colonna — resta una tabella, perché il confronto verticale È la
       lettura. Scorre di lato dentro la sua cornice (`.tbl-scroll`, con le
       ombre che dicono « c'è dell'altro »), e la prima colonna resta ferma
       mentre scorre: senza, a metà tabella non si sa più di quale riga sia
       la cifra che si sta leggendo. */
@media (max-width: 760px), (pointer: coarse) and (max-height: 500px) {
  table.tbl-schede, table.tbl-schede tbody { display: block; width: 100%; }
  table.tbl-schede thead {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
  table.tbl-schede tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-2);
    padding: var(--sp-4) 0;
    border-bottom: 1px solid var(--border);
  }
  table.tbl-schede tr:first-child { padding-top: var(--sp-2); }
  /* La scheda in uso porta il suo filo d'accento a sinistra, come la riga
     della tabella: qui gli si lascia l'aria per non toccare le etichette. */
  table.tbl-schede tr.row-active { padding-inline: var(--sp-3); border-radius: var(--r-2); }
  /* L'etichetta sta nel margine sinistro della cella, e il contenuto scorre
     come scorreva nella tabella — con i suoi `<br>` e le sue righe di
     servizio. Una griglia avrebbe fatto di ogni riga di testo una cella a
     sé, e la seconda riga del periodo sarebbe finita sotto l'etichetta. */
  table.tbl-schede td {
    /* `flow-root`: la cella contiene la sua etichetta flottante, quindi è
       alta almeno quanto lei — un'etichetta su due righe (« FONTE
       AUTOREVOLE ») accanto a una pastiglia su una riga non scivola più
       sotto, addosso all'etichetta della cella dopo. */
    display: flow-root;
    padding: 0 0 0 108px;
    border: 0;
    text-align: left;
    overflow-wrap: anywhere;
  }
  table.tbl-schede td.num { text-align: left; }
  table.tbl-schede td::before {
    content: attr(data-etichetta);
    float: left;
    width: 96px;
    margin: .2em 0 0 -108px;
    font-size: var(--fs-0);
    font-weight: 600;
    letter-spacing: .06em;
    line-height: 1.3;
    text-transform: uppercase;
    color: var(--muted);
    overflow-wrap: normal;
  }
  /* La prima cella è il nome della riga: sta intera, sopra, senza
     etichetta — « FILE » davanti al nome di un file non aggiunge niente. */
  table.tbl-schede td:first-child { display: block; padding-left: 0; font-size: var(--fs-4); }
  table.tbl-schede td:first-child::before { content: none; }
  /* Le azioni della riga: in fondo alla scheda, a tutta larghezza, bersagli
     da dito. */
  table.tbl-schede td.row-actions {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
    margin-top: var(--sp-1); padding-left: 0;
  }
  table.tbl-schede td.row-actions::before { content: none; }
  table.tbl-schede td.row-actions form { margin: 0; }
  table.tbl-schede td.row-actions .btn { min-height: 44px; padding-inline: var(--sp-4); }
  .tbl-scroll:has(> table.tbl-schede) { overflow: visible; background: none; }

  /* Le matrici di numeri: la prima colonna resta ferma. Solo da quattro
     colonne in su: una tabella chiave–valore a due o tre colonne sta nella
     larghezza del telefono e va letta intera, non scorsa — con la larghezza
     naturale l'etichetta prendeva lo schermo e la cifra finiva fuori, cioè
     restava in vista proprio la metà che non dice niente. */
  .tbl-scroll > table:not(.tbl-schede):not(:has(tr > :nth-child(4))) {
    width: 100%;
  }
  .tbl-scroll > table:not(.tbl-schede):not(:has(tr > :nth-child(4))) td:not(:first-child) {
    max-width: none; overflow-wrap: anywhere;
  }
  .tbl-scroll > table:not(.tbl-schede):has(tr > :nth-child(4)) th:first-child,
  .tbl-scroll > table:not(.tbl-schede):has(tr > :nth-child(4)) td:first-child {
    position: sticky; left: 0; z-index: 1;
    background: var(--tbl-bg, var(--surface));
    box-shadow: 1px 0 0 var(--border);
  }
  .tbl-scroll { overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; }
  /* Una tabella che scorre di lato non deve anche stringersi: stretta a
     trecento pixel, la colonna con il testo più lungo andava a capo a ogni
     parola e una riga diventava alta come mezzo schermo. Qui ogni colonna
     prende la sua larghezza naturale, con un tetto per le colonne di prosa, e
     quello che non entra si raggiunge scorrendo — che è la ragione per cui la
     cornice scorre. */
  .tbl-scroll > table:not(.tbl-schede):has(tr > :nth-child(4)) { width: max-content; min-width: 100%; }
  .tbl-scroll > table:not(.tbl-schede) th,
  .tbl-scroll > table:not(.tbl-schede) td { max-width: 280px; }
}

/* --------------------------------------------------------------- 50.10 ---
   IL MARKETING, sul telefono. Le tre plance restano plance — si cambia vista
   (Forma · Indicatori · Dettaglio), non si scorre — e questo lo decideva già
   il loro foglio sotto i 900 px. Qui si correggono le misure che su trecento
   pixel non tenevano più. */
@media (max-width: 760px), (pointer: coarse) and (max-height: 500px) {
  /* Il campo aveva una sola colonna implicita, cioè larga quanto il suo
     contenuto più largo: la riga dei comandi dell'import (tre schede e un
     bottone, senza andare a capo) lo portava a 472 pixel dentro uno schermo
     da 390, e il grafico usciva dal bordo destro. Una colonna che può
     stringersi fino a zero lascia andare a capo chi deve. */
  .mk-campo { grid-template-columns: minmax(0, 1fr); }
  .mk-campo-testa { grid-template-columns: minmax(0, 1fr); row-gap: 6px; }
  /* Il foglio del Marketing assegna a occhiello, titolo e comandi una riga e
     una colonna precise: su una colonna sola due di loro finivano nella
     stessa cella, uno sopra l'altro. Qui ognuno riprende la sua riga. */
  .mk-campo-testa > *, .mk-campo-nome > * { grid-column: 1 !important; grid-row: auto !important; min-width: 0; }
  .mk-campo-testa .mk-occhio { white-space: normal; }
  /* La telemetria in fondo è una riga di stati: scorre di lato invece di
     finire tagliata a metà parola sul bordo. */
  .mk-telemetria { overflow-x: auto; scrollbar-width: none; flex-wrap: nowrap; }
  .mk-telemetria::-webkit-scrollbar { display: none; }
}

/* --------------------------------------------------------------- 50.11 ---
   IL BANCO DEL PUBLISHER e le testate, sul telefono. */
@media (max-width: 760px), (pointer: coarse) and (max-height: 500px) {
  /* Il titolo di una pagina va a capo invece di troncarsi: « Villa con
     giardino — via Roma 1: » non è il titolo di un contenuto, è un titolo
     tagliato. */
  .page-head h1 { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }

  /* I comandi del banco erano appiccicati al fondo della finestra, ed era la
     scelta giusta per una colonna alta mille pixel accanto a due altre. Sul
     telefono il fondo della finestra è del dock, e il blocco dei comandi —
     due bottoni, una nota e la spiegazione della programmazione — alto un
     terzo di schermo, appiccicato, copriva i canali mentre li si sceglieva.
     Sta alla fine della colonna, dove la lettura dei canali finisce. */
  .pub-azioni { position: static; }
  .pub-azioni-riga .btn { flex: 1 1 0; min-height: 48px; }
}

/* L'account pubblicitario letto dal Marketing: una scelta, sotto la
   connessione che la rende possibile. */
.conn-account { display: grid; gap: .4rem; padding: .6rem 0; border-top: 1px solid var(--border); }
.conn-account select { max-width: 100%; min-height: 36px; font: inherit; }
.conn-account .btn { justify-self: start; }
/* Le campagne attive che nel periodo non hanno consegnato: esistono, e si
   nominano, ma senza numeri che non ci sono. */
.mk-senza-consegna { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: .2rem; font-size: var(--fs-0, .8rem); }
.mk-senza-consegna .sub { opacity: .7; margin-left: .3rem; }
/* La copertina della scheda porta width/height (il riquadro esiste prima dei
   byte): l'altezza la decide il rapporto 4:3 di tef.css, non l'attributo. */
.tef-copertina img[height] { height: auto; }

/* ============================ COLLEGAMENTI (3.6) ==========================
   Due canali per riga, lo stato in alto a destra, i due permessi di Meta come
   riquadri interni, e «che cosa sa fare» come una fisarmonica su fondo grigio.
   ========================================================================== */
body[data-page="collegamenti"] .canali { grid-template-columns: repeat(auto-fill, minmax(min(100%, 420px), 1fr)); }
body[data-page="collegamenti"] .canale-testa { grid-template-columns: 40px minmax(0, 1fr) auto; }
body[data-page="collegamenti"] .canale-segno { grid-row: span 1; align-self: center; }
body[data-page="collegamenti"] .canale-nome { display: grid; gap: 2px; }
body[data-page="collegamenti"] .canale-nome em { font-style: normal; font-size: 13px; }
body[data-page="collegamenti"] .canale-stato { grid-column: 3; grid-row: 1; justify-self: end; }
.scopo { border-left: 0; padding: var(--s-4); border-radius: var(--r-md); box-shadow: inset 0 0 0 1px var(--line); gap: var(--s-2); }
.scopo-collegato { border-left-color: transparent; }
.scopo-testa strong { font-size: 14px; }
.conn-riga { padding: var(--s-2) 0; border-top: 1px solid var(--line); }
.canale-capacita { margin-top: var(--s-1); border-radius: var(--r-md); background: var(--panel); padding: 0 var(--s-4); }
.canale-capacita > summary { cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center;
  padding: 12px 0; font: 500 13.5px var(--sans); color: var(--ink); }
.canale-capacita > summary::-webkit-details-marker { display: none; }
.canale-capacita > summary::after { content: ""; width: 8px; height: 8px; border-right: 2px solid var(--ink-2); border-bottom: 2px solid var(--ink-2);
  transform: rotate(45deg) translateY(-2px); transition: transform var(--t-panel) var(--ease-out); }
.canale-capacita[open] > summary::after { transform: rotate(225deg); }
.canale-capacita[open] { padding-bottom: var(--s-3); }
.elenco-capacita .cap { border-top: 1px solid var(--line); font-size: 13.5px; }
.cap-stato { font-size: 12.5px; }
.cap-assente .cap-stato, .cap-da_verificare .cap-stato { color: var(--ink-2); }

/* ======================= IL CONTENUTO DEI MODULI (3.6) =====================
   Il riquadro scorre da sé (§ 9 di quadra.css): qui le parti che lo compongono
   non devono più stringersi per starci, e restano poche e uguali per tutte le
   plance. Sezioni separate da un filo, etichetta maiuscoletta, cifra in
   Quadra Display con la sua parola accanto in Inter, liste di riferimenti,
   tele dei grafici che prendono l'altezza che resta. */
.mod-sez { display: flex; flex-direction: column; gap: 6px; min-height: 0; flex: none; }
.mod-sez:has(.mod-tela) { flex: 1 1 auto; }
.mod-sez + .mod-sez { margin-top: var(--s-1); padding-top: var(--s-3); border-top: 1px solid var(--line); }
.mod-sez-piede { margin-top: auto; }
.mod-sez-t { margin: 0; font: 500 11.5px/1.3 var(--sans); letter-spacing: .07em; text-transform: uppercase; color: var(--ink-2); }
.mod-cifra { margin: 0; font: 400 clamp(26px, 2.4vw, 34px)/1 var(--display); font-variant-numeric: tabular-nums; letter-spacing: -.01em; color: var(--ink); }
.mod-cifra em { font: 400 13px/1.3 var(--sans); font-style: normal; color: var(--ink-2); margin-left: 6px; letter-spacing: 0; }
.mod-cifra-riga { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 6px; }
.mod-cifra-riga em { margin-left: 0; }
.mod-cifra-min { font-size: 22px; }
.mod-coppia { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); }
.mod-frase { margin: 0; font-size: 13px; line-height: 1.45; color: var(--ink-2); }
.mod-frase strong, .mod-frase-cifre strong { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.mod-frase.bad strong { color: var(--err); }
.mod-frase.warn strong { color: var(--warn); }
.mod-frase.ok strong { color: var(--ok); }
/* Una colonna che si può stringere (`minmax(0, 1fr)`): senza, una riga con un
   nome che non va a capo si allargava oltre il riquadro sul telefono. */
.mod-lista { display: grid; grid-template-columns: minmax(0, 1fr); margin: 0; padding: 0; list-style: none; }
.mod-lista li, .mod-lista > div { display: flex; align-items: baseline; gap: var(--s-2); padding: 8px 0; border-top: 1px solid var(--line); font-size: 13.5px; line-height: 1.35; }
.mod-lista li:first-child, .mod-lista > div:first-child { border-top: 0; }
.mod-lista .l-n { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ink); }
.mod-lista .l-v { flex: none; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink); }
.mod-lista .l-t { flex: none; font-size: 12px; color: var(--ink-2); }
.mod-tela { position: relative; flex: 1 1 auto; min-height: 110px; }
.mod-tela > canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }
.mod-tela-striscia { min-height: 80px; }
.mod-vuoto { margin: 0; font-size: 13px; color: var(--ink-2); }
/* il territorio in una colonna: nome, fascia, quota e contatti */
.mod-corpo .territorio { gap: 4px; }
.mod-corpo .terr-fascia { grid-template-columns: 92px minmax(0, 1fr) 70px; gap: 10px; min-height: 36px; }
.mod-corpo .terr-nome { display: grid; gap: 0; font-size: 12.5px; white-space: normal; line-height: 1.2; }
.mod-corpo .terr-nome b { font-weight: 500; }
.mod-corpo .terr-pista { height: 24px; }
.mod-corpo .terr-cella span { display: none; }
.terr-cifre { display: grid; justify-items: end; line-height: 1.2; }
.terr-cifre b { font-weight: 600; font-variant-numeric: tabular-nums; }
.terr-cifre em { font-style: normal; font-size: 11.5px; color: var(--ink-2); white-space: nowrap; }
/* più letture in un modulo: una alla volta, scelte dal selettore */
.mod-viste { display: flex; flex-direction: column; gap: var(--s-3); min-height: 0; flex: 1 1 auto; }
.mod-viste > .ui-seg { align-self: flex-start; flex: none; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.mod-viste > [data-vista-pannello] { display: flex; flex-direction: column; gap: var(--s-3); min-height: 0; flex: 1 1 auto; }
.mod-viste > [data-vista-pannello][hidden] { display: none; }
.senza-js .mod-viste > [data-vista-pannello][hidden] { display: flex !important; }
.senza-js .mod-viste > .ui-seg { display: none; }

/* ===========================================================================
   §51 · LE FORME DENTRO IL RIQUADRO (2026-09-28)

   La regola generale sta nella § 9b di quadra.css: la forma si misura sul
   corpo del modulo (`container: corpo`), le letture secondarie cedono
   (`.cede-1`, `.cede-2`) quando l'altezza manca, e dove manca la larghezza
   cambia la scrittura, non il dato. Qui ogni forma della plancia la applica.
   Le regole sono dichiarate DOPO gli strati precedenti di questo foglio e ne
   vincono le soglie di finestra (881 px, 940 px…): la misura che conta è il
   riquadro, non lo schermo.

   Ciò che divide l'ALTEZZA (righe che si spartiscono il corpo, lati in
   `cqh`) sta dentro `@container corpo (min-height: 1px)`: la condizione è
   vera solo dove il corpo è un contenitore in altezza, cioè sulla plancia a
   una schermata. Impilata (telefono, finestre sotto 1100 × 680) il riquadro è
   alto quanto il contenuto e ogni forma riprende la sua misura naturale.
   =========================================================================== */

/* ------------------------------------------------ 51.1 · le viste di un modulo
   Il selettore e il pannello sono una cosa sola: nessun filo fra i due (lo
   metteva `.mod-sez + .mod-sez`, perché i pannelli nascosti restano fratelli
   nel documento). Dove quattro voci non stanno in una riga, due righe da
   due: una voce tagliata a metà non si sceglie. */
.mod-viste { gap: var(--s-3); }
.mod-viste > .ui-seg { max-width: 100%; }
@container corpo (max-width: 359px) {
  .mod-viste > .ui-seg { display: grid; grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr));
    align-self: stretch; overflow: visible; border-radius: var(--r-lg); gap: 2px; }
  .mod-viste > .ui-seg > button { border-radius: var(--r-md); padding: 0 var(--s-2); }
}
@container corpo (max-width: 239px) {
  .mod-viste > .ui-seg > button { height: auto; min-height: 30px; padding: 3px var(--s-1); white-space: normal;
    text-align: center; line-height: 1.15; hyphens: manual; }
}
.mod-viste > [data-vista-pannello] { border-top: 0; margin-top: 0; padding-top: 0; }

/* --------------------------------------------------- 51.2 · Visibilità: flusso
   Sopra il percorso una cifra per tappa, nell'ordine delle colonne (le prime
   tre partono dove parte il loro nodo, l'ultima finisce dove finisce il
   suo); sotto, chi non arriva al contatto e perché. */
.flusso-tappe { list-style: none; margin: 0; padding: 0; display: grid; flex: none;
  grid-template-columns: repeat(3, minmax(0, 1fr)) minmax(0, .8fr); gap: var(--s-2); }
.flusso-tappe li { display: grid; gap: 2px; align-content: start; min-width: 0; }
.flusso-tappe li:last-child { text-align: right; }
.flusso-tappe b { font: 400 clamp(18px, 7.5cqw, 26px)/1 var(--display); font-variant-numeric: tabular-nums; color: var(--ink); }
.flusso-tappe span { font-size: 11.5px; line-height: 1.25; color: var(--ink-2); overflow-wrap: anywhere; }
.vista-pan .sk-mini { flex: 1 1 auto; min-height: 56px; }
/* Stretto: quattro colonne da cinquanta pixel spezzerebbero «portafoglio» a
   metà. Due righe da due, cifra e nome sulla stessa riga. */
@container corpo (max-width: 299px) {
  .flusso-tappe { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-1) var(--s-3); }
  .flusso-tappe li:last-child { text-align: left; }
  .flusso-tappe b { font-size: 18px; }
  .flusso-tappe span { font-size: 11px; letter-spacing: -.01em; overflow-wrap: normal; }
}
@container corpo (max-height: 259px) { .mod-viste { gap: var(--s-2); } .mod-viste > [data-vista-pannello] { gap: var(--s-2); }
  .vista-pan .sk-mini { min-height: 36px; } }
.flusso-uscite { list-style: none; margin: 0; padding: 0; display: grid; flex: none;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 150px), 1fr)); gap: 2px var(--s-3);
  font-size: 12.5px; line-height: 1.35; color: var(--ink-2); }
.flusso-uscite b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
/* Basso: resta la sola uscita che chiede un'azione, visti e non convertiti. */
@container corpo (max-height: 319px) { .flusso-uscite li:not(.segnalato) { display: none; } }
@container corpo (max-height: 229px) { .flusso-uscite { display: none; } }

/* ---------------------------------------- 51.3 · Visibilità: le due classifiche
   Dieci righe che si dividono l'altezza del modulo (fra 22 e 34 px l'una),
   con il rango davanti: scorrono dentro il riquadro solo se nemmeno il
   pavimento ci sta. */
.mod-corpo .rf-compatta { flex: 1 0 auto; display: flex; flex-direction: column; gap: 0; counter-reset: rf; }
@container corpo (min-height: 1px) { .mod-corpo .rf-compatta li { flex: 1 1 0; max-height: 34px; } }
.mod-corpo .rf-compatta li { min-height: 21px; counter-increment: rf;
  display: grid; grid-template-columns: 2.2ch minmax(0, 1fr) auto auto; align-items: center; gap: var(--s-2);
  padding: 0 var(--s-1); border-top: 1px solid var(--line); font-size: 13px; line-height: 1.2; }
.mod-corpo .rf-compatta li:first-child { border-top: 0; }
.mod-corpo .rf-compatta li::before { content: counter(rf); font-size: 11.5px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.mod-corpo .rf-compatta .rf-r { font-family: var(--sans); font-variant-numeric: tabular-nums; }
.mod-corpo .rf-compatta .rf-u { font-size: 11.5px; }
/* Stretto: il riferimento intero vale più dell'unità, che il nome della
   vista e la frase sotto dicono già. Basso: la frase cede prima delle righe. */
@container corpo (max-width: 239px) { .mod-corpo .rf-compatta .rf-u { display: none; } }
@container corpo (max-height: 299px) { .vista-pan > .rf-compatta + .mod-frase { display: none; } }

/* --------------------------------------------- 51.4 · Visibilità: concentrazione
   La curva prende l'altezza che resta, fra un pavimento e un tetto: sopra
   i 150 px la sua forma non dice niente di più, e lo spazio va alle cifre. */
.conc-tela { flex: 1 1 auto; min-height: 56px; max-height: 150px; }
.mod-terna { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-3); margin: 0; flex: none; }
/* La cifra sopra, che cosa conta sotto: nel documento `dt` viene prima di
   `dd`, come vuole una lista di definizioni; a vista lo mette sotto l'ordine. */
.mod-terna > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.mod-terna dt { order: 2; font-size: 11.5px; line-height: 1.3; color: var(--ink-2); }
.mod-terna dd { order: 1; margin: 0; font: 400 20px/1.1 var(--display); font-variant-numeric: tabular-nums; color: var(--ink); }
.mod-coppia-piccola .mod-cifra { font-size: 20px; }
.mod-coppia-piccola .mod-cifra-riga { flex-wrap: nowrap; align-items: baseline; }
.mod-coppia-piccola .mod-cifra em { font-size: 12px; min-width: 0; }
@container corpo (max-height: 299px) { .conc-tela { min-height: 44px; } .mod-coppia-piccola { display: none; } }
@container corpo (max-height: 239px) { .mod-terna { display: none; } }

/* ------------------------------------------------------------ 51.5 · Anzianità
   Il grafico usciva dal riquadro perché la sua altezza minima era fissa: due
   cifre andate a capo, due righe di etichette e un binario da dieci pixel
   facevano più del corpo nelle caselle basse, e il bordo tagliava le bande.
   Adesso le cifre stanno in una riga, il binario prende ciò che resta e,
   se il corpo è basso, cedono prima la mediana e poi le quote (le dicono il
   cartellino e il dettaglio). Dove le colonne sono strette, il nome della
   banda si scrive con il suo estremo superiore. */
.mod-coppia-eta { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s-3); flex: none; }
.mod-coppia-eta .mod-cifra { flex: 0 1 auto; min-width: 0; }
@container corpo (max-width: 299px) {
  .mod-coppia-eta .mod-cifra { font-size: 26px; display: grid; gap: 2px; }
  .mod-coppia-eta .mod-cifra-min { font-size: 18px; text-align: right; }
  .mod-coppia-eta .mod-cifra em { font-size: 12px; }
}
.mod-corpo .mod-forma-alta { overflow: hidden; }
.mod-corpo .ig { gap: var(--s-1); }
.mod-corpo .ig-pista { min-height: 16px; }
.ig-n-c { display: none; }
@container corpo (max-width: 299px) {
  .mod-corpo .ig-n-l { display: none; }
  .mod-corpo .ig-n-c { display: inline; }
  .mod-corpo .ig-n, .mod-corpo .ig-q { font-size: clamp(10px, 7cqw, 11.5px); letter-spacing: -.01em; }
  .mod-corpo .ig { gap: 3px; }
}
@container corpo (max-height: 129px) {
  .mod-corpo .ig-q { display: none; }
  .mod-coppia-eta .mod-cifra { font-size: 22px; }
  .mod-coppia-eta .mod-cifra em { display: inline; margin-left: var(--s-1); }
}

/* ------------------------------------------------------------ 51.6 · Tipologia
   Senza legenda, l'anello e le sue tre letture sono la composizione intera.
   Affiancati se il corpo è più largo che alto, uno sopra l'altro se no; il
   lato del disco è il minore fra l'altezza e metà della larghezza, quindi
   resta un cerchio in ogni casella. */
.mod-corpo .cia-senza-legenda { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: row; flex-wrap: wrap;
  align-items: center; justify-content: center; gap: var(--s-4) var(--s-5); height: auto; }
.mod-corpo .cia-senza-legenda .cia-anello { flex: none; height: auto; width: clamp(140px, 40cqw, 240px); aspect-ratio: 1; }
.mod-corpo .cia-senza-legenda .cia-col { flex: 1 1 180px; max-width: 280px; min-width: 0; height: auto; align-self: center;
  display: flex; flex-direction: column; justify-content: center; gap: 0; }
@container corpo (min-height: 1px) {
  .mod-corpo .cia-senza-legenda { flex-wrap: nowrap; }
  .mod-corpo .cia-senza-legenda .cia-anello { width: min(100cqh, 48cqw, 320px); }
  .mod-corpo .cia-senza-legenda .cia-col { flex: 0 1 280px; }
}
.mod-corpo .cia-senza-legenda .cia-extra { margin: 0; padding: 0; border: 0; display: grid; gap: var(--s-3); }
.mod-corpo .cia-senza-legenda .cia-extra > div { display: block; }
.mod-corpo .cia-senza-legenda .nt-e { display: block; margin-bottom: 2px; font-size: 11.5px; line-height: 1.2; }
.mod-corpo .cia-senza-legenda .nt-v { font-size: 14px; font-weight: 600; line-height: 1.3; }
.mod-corpo .cia-senza-legenda .nt-s { font-size: 12.5px; line-height: 1.3; }
.mod-corpo .cia-senza-legenda .qt-cifra span { font-size: clamp(16px, 9cqmin, 30px); }
.mod-corpo .cia-senza-legenda .qt-cifra i { font-size: clamp(10px, 2.6cqmin, 11px); }
@container corpo (min-height: 1px) and (aspect-ratio < 1.25) {
  .mod-corpo .cia-senza-legenda { flex-direction: column; gap: var(--s-3); }
  .mod-corpo .cia-senza-legenda .cia-anello { width: min(100cqw, 58cqh, 280px); }
  .mod-corpo .cia-senza-legenda .cia-col { flex: none; align-self: stretch; }
  .mod-corpo .cia-senza-legenda .cia-extra { gap: var(--s-2); }
}
@container corpo (max-height: 199px) {
  .mod-corpo .cia-senza-legenda .cia-extra { gap: var(--s-2); }
  .mod-corpo .cia-senza-legenda .nt-e { display: inline; margin: 0 var(--s-1) 0 0; }
  .mod-corpo .cia-senza-legenda .nt-v { display: inline; font-size: 13px; }
  .mod-corpo .cia-senza-legenda .nt-s { display: block; }
  .mod-corpo .cia-senza-legenda .nt-s::before { content: none; }
}

/* ----------------------------------------------------------- 51.7 · Territorio
   Le fasce si dividono l'altezza del modulo (fra 16 e 64 px), la pista
   segue la fascia, e la scala dei colori sta subito sotto senza filo: è la
   legenda di quella forma, non una sezione nuova. Nelle caselle basse cede
   prima la nota sulle celle grigie, poi le seconde righe (il conteggio della
   zona, i contatti): la quota e la campitura restano. */
.mod-corpo .territorio { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: var(--s-1); }
@container corpo (min-height: 1px) { .mod-corpo .terr-fascia { flex: 1 1 0; min-height: 16px; max-height: 64px; align-items: center; } }
/* L'altezza della pista è una quota di quella che ogni fascia riceve:
   (corpo − scala) ÷ numero di fasce, il 55%, fra 12 e 32 px. `--fasce` lo
   scrive il server sulla forma. */
@container corpo (min-height: 1px) {
  .mod-corpo .terr-pista { height: clamp(12px, calc((100cqh - 56px) / var(--fasce, 6) * .55), 32px); }
}
.mod-corpo .terr-scala { flex: none; margin-top: var(--s-2); padding-top: 0; border-top: 0; gap: var(--s-1) var(--s-4); }
@container corpo (max-width: 359px) {
  .mod-corpo .terr-fascia { grid-template-columns: 72px minmax(0, 1fr) max-content; gap: var(--s-2); }
}
@container corpo (max-height: 199px) {
  .mod-corpo .terr-nome em, .mod-corpo .terr-cifre em { display: none; }
  .mod-corpo .terr-nome { display: block; }
  .mod-corpo .terr-scala { flex-wrap: nowrap; gap: var(--s-3); margin-top: var(--s-1); }
  .mod-corpo .terr-scala .tm-leg-t { flex: 0 1 auto; min-width: 0; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .mod-corpo .terr-scala .tm-leg { flex: none; }
  .mod-corpo .terr-scala .tm-leg-p { white-space: nowrap; }
}

/* ---------------------------------------------------- 51.8 · Domanda sul prezzo
   In un modulo stretto il nome della fascia e lo scarto si prendono la loro
   misura e la pista il resto: a 186 px il valore usciva di sedici pixel. */
@container corpo (max-width: 299px) {
  .mod-corpo .dv-testa, .mod-corpo .dv-riga { grid-template-columns: max-content minmax(24px, 1fr) max-content; gap: var(--s-2); }
  .mod-corpo .dv-nome, .mod-corpo .dv-val { font-size: 12.5px; }
}

/* ------------------------------------------------ 51.9 · il titolo di un modulo
   Nelle celle strette un nome che non sta in una riga va a capo, su due al
   più, invece di finire in «Domanda sul pr…»: un modulo che non si riconosce
   non si sceglie. Sopra i 260 px resta su una riga come sempre. */
@container (max-width: 259px) {
  .mod-testa h2 { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-height: 1.2; }
}
