/* ==========================================================================
   Lab Medicinae — components.css
   --------------------------------------------------------------------------
   Componenti del DS (dev/components, section 67:545): link, bottoni (3
   grammatiche, §4.6), card, label di sezione, step del metodo.
   Regole non negoziabili (§4): radius 0 · pieno solo CTA · Sage solo segno ·
   White solo surface attiva · stato nel testo, colore = rinforzo.
   ========================================================================== */

/* --- Link (67:552) --------------------------------------------------------
   Nessun underline a riposo; hover/corrente underline (§5).
   Padding 8 → target ≥30px (§4.9).
   -------------------------------------------------------------------------- */

.link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-8);
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text);
  transition: color var(--duration-base) var(--ease-base);
}

/* Hover = colore (variante 67:555); lo STATO corrente resta underline:
   canale non-colore, mai colore da solo (§4.7). Hover gated: sui touch
   il tap non deve lasciare falsi hover. */
@media (hover: hover) and (pointer: fine) {
  .link:hover { color: var(--accent-text); }
}

.link[aria-current="page"] {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Link sottolineato stabile (link-under 216:705 — per corpi testo) */
.link-under {
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color var(--duration-base) var(--ease-base);
}

/* hover: Coral Dark, l'underline resta (variante 216:708) */
@media (hover: hover) and (pointer: fine) {
  .link-under:hover { color: var(--accent-text); }
}

/* --- Bottoni: tre grammatiche (§4.6) -------------------------------------- */

/* 1 · CTA piena (button-main 67:546) — il pieno è grammatica esclusiva
   delle CTA. Fondo Coral Dark (accent-text): il Coral pieno non regge il
   contrasto AA con la label bianca. */
.button-main {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* riferimento di sistema: CTA home mobile, 16/24 → h46 (decisione 2026-07-17) */
  padding: var(--space-16) var(--space-24);
  background: var(--accent-text);
  color: var(--white);
  font-family: var(--font-ui);
  font-weight: var(--weight-medium);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  text-align: center;
  transition: background-color var(--duration-base) var(--ease-base),
              color var(--duration-base) var(--ease-base),
              transform var(--duration-fast) var(--ease-out);
}

/* hover: Sage + label al negativo (variante 67:549) */
@media (hover: hover) and (pointer: fine) {
  .button-main:hover {
    background: var(--support);
    color: var(--text);
  }
}

/* pressione: feedback immediato, scala appena percettibile */
.button-main:active { transform: scale(0.97); }

@media (prefers-reduced-motion: reduce) {
  .button-main { transition: background-color var(--duration-base) var(--ease-base), color var(--duration-base) var(--ease-base); }
  .button-main:active { transform: none; }
}

/* CTA hero/form mobile: full-width (il padding 16 è ora la base di sistema) */
.button-main--block {
  width: 100%;
}

/* 2 · Disabled — bordo light-gray + label muted regular */
.button-disabled {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 15px 23px; /* bordo dentro l'altezza: h46 come le altre grammatiche */
  background: transparent;
  border: 1px solid var(--light-gray);
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  cursor: default;
}

/* 3 · Azione secondaria — bordo text + label ui/14-medium + segno direzionale
   (il segno vive nel testo, es. "Mostra altri strumenti ↓") */
.button-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 15/23 = 16/24 col bordo DENTRO l'altezza (come stroke inside in Figma):
     h totale 46, identica alla CTA piena */
  padding: 15px 23px;
  background: transparent;
  border: 1px solid var(--text);
  color: var(--text);
  font-family: var(--font-ui);
  font-weight: var(--weight-medium);
  font-size: var(--size-14);
  line-height: var(--leading-14);
}

/* Dentro colonne flex (.prose) l'azione secondaria resta hug-content */
.prose .button-secondary {
  align-self: flex-start;
}

/* --- Label di sezione (mono, §4.8) ---------------------------------------- */

.section-label {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text);
}

.section-label--accent { color: var(--accent-text); }

/* --- Card (67:760 · 67:727) ------------------------------------------------
   Bordo 1px text, padding 48/64, radius 0. Attiva: surface White (§4.5).
   Disabled: resta su surface, titolo muted, meta/desc disabled.
   -------------------------------------------------------------------------- */

.card {
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
  width: 100%;
  padding: var(--space-64) var(--space-48);
  background: var(--surface);
  border: 1px solid var(--text);
}

.card--active { background: var(--surface-white); }

/* Interattività card attiva (le ghost restano inerti): scala leggera dal
   centro (skill emil: hover frequente = drasticamente sottile, solo transform).
   Sostituisce il translateY che leggeva come scatto (deciso 2026-07-17). */
.card--active {
  transition: transform var(--duration-base) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .card--active:hover { transform: scale(1.01); }
}

.card--active:focus-within {
  transform: scale(1.01);
}

@media (prefers-reduced-motion: reduce) {
  .card--active { transition: none; }
  .card--active:hover,
  .card--active:focus-within { transform: none; }
}

.card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* Icona radar 64px — SEMPRE generata da radar.js (§6), hook vuoto fino al passo 4 */
.card__icon { width: 64px; height: 64px; }

/* Stato: quadrato 16px (mai cerchio, §4.1) + label. Stato nel testo,
   colore = rinforzo (§4.7). Sage = attivo · Brown = in preparazione. */
.card__status {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

.status-dot { width: 16px; height: 16px; }
.status-dot--active { background: var(--support); }
.status-dot--pending { background: var(--support-muted); }

.card__status-label {
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text);
}

.card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
  align-items: flex-start;
}

.card__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
}

.card__title-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.card__title {
  font-family: var(--font-content);
  font-weight: var(--weight-semibold);
  font-size: var(--size-36);
  line-height: var(--leading-40);
  color: var(--text);
}

.card__meta {
  font-family: var(--font-mono);
  font-weight: var(--weight-bold);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text-secondary);
}

.card__desc {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text);
}

/* Variante disabled: gerarchia spenta a opacità (mai grigi nuovi, §3) */
.card--disabled .card__title { color: var(--text-muted); }
.card--disabled .card__meta,
.card--disabled .card__desc  { color: var(--text-disabled); }

/* --- Metodo: step (76:2093 · 167:695) --------------------------------------
   Mobile: striscia orizzontale full-bleed, overflow-x + scroll-snap, no JS.
   Step verticali 260px con peek del successivo (§5).
   Desktop: 3 step in riga, num + descrizione affiancati.
   -------------------------------------------------------------------------- */

.steps {
  display: flex;
  gap: var(--space-16);
  list-style: none;
  padding: 0;
  /* mobile: striscia scorrevole */
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  /* niente scrollbar visibile (Chrome/Windows la mostrano fissa sotto la
     strip): l'affordance è il passo successivo che spunta dal bordo */
  scrollbar-width: none;
}

.steps::-webkit-scrollbar { display: none; }

.step {
  display: flex;
  flex-direction: column;   /* mobile: num sopra, testo sotto */
  align-items: flex-start;  /* num e testo allineati a sinistra */
  gap: var(--space-8);
  flex: 0 0 260px;          /* larghezza fissa → peek del successivo */
  scroll-snap-align: start;
}

.step__num {
  font-family: var(--font-mono);
  font-weight: var(--weight-bold);
  font-size: var(--size-128);
  line-height: var(--leading-128);
  letter-spacing: -0.05em;
  color: var(--accent-text);
}

.step__desc {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-28);
  line-height: var(--leading-33);
  color: var(--text-secondary);
}

/* --- Home: hero (76:2074 · 167:678) ---------------------------------------- */

.hero {
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
  align-items: flex-start;
}

.hero__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);   /* canonico mobile 167:679; desktop → 16 */
}

.hero__title {
  font-family: var(--font-content);
  font-weight: var(--weight-semibold);
  font-size: var(--size-48);      /* display/48 mobile → display/64 desktop */
  line-height: var(--leading-48);
  color: var(--text);
}

.hero__sub {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text-secondary);
}

/* --- Home: griglia strumenti (76:2080 · 167:684) ---------------------------- */

.tools {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.cards {
  display: flex;              /* mobile: colonna */
  flex-direction: column;
  gap: var(--space-16);
}

/* Mobile: 3 card visibili, il resto si espande in pagina (§5).
   Senza JS tutte visibili; main.js attiva il collasso + il bottone. */
.show-more { display: none; }

@media (max-width: 767.98px) {
  .cards[data-collapsed="true"] > .card:nth-of-type(n+4) { display: none; }
  .show-more.is-active { display: inline-flex; width: 100%; }
}

/* --- Text page (lab-page-testo-v1: Info · Privacy · Disclaimer · Colophon) --
   Mobile: header (kicker + titolo) sopra, prose sotto (gap 80 dal .page main).
   Desktop: due colonne — title-col 400 + prose 608, gap 16.
   -------------------------------------------------------------------------- */

.textpage {
  display: flex;
  flex-direction: column;
  gap: var(--space-80);
  align-items: flex-start;
}

.textpage__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
}

.page-title {
  font-family: var(--font-content);
  font-weight: var(--weight-semibold);
  font-size: var(--size-48);      /* display/48 mobile → display/64 desktop */
  line-height: var(--leading-48);
  color: var(--text);
}

/* max-width e non width: da sola in colonna la prose deve tenere la stessa
   misura di riga del canonico (608), non allargarsi quanto il contenitore.
   Senza, fra 768 e 1080 la riga arrivava a ~950px. */
.prose {
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
  max-width: 608px;
}

.prose section {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.prose h2 {
  font-family: var(--font-content);
  font-weight: var(--weight-regular); /* step/28: titoletti regular, non bold */
  font-size: var(--size-28);
  line-height: var(--leading-33);
  color: var(--text);
}

/* :where() = specificità zero sul p: i componenti dentro la colonna prose
   (errori form, conferma) definiti più avanti vincono senza escalation */
.prose :where(p) {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text-secondary);
}

/* --- Comitato (pagina Metodo — canonici 427:938 · 427:1321) ------------------
   Griglia tipografica, niente foto (decisione sessione 15). Il ritmo verticale
   è quello della prose: 32 fra le schede come fra i blocchi, dentro la scheda
   la hairline si stacca di 16, ruolo e nome restano uniti a 4, poi 8 verso la
   bio come fra titolo e corpo di una sezione. La LINE del canonico è un rect
   1px → qui border-top.
   -------------------------------------------------------------------------- */

.comitato-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
  padding-top: var(--space-24);  /* + gap 8 della section = 32 dal cappello */
  margin: 0;
  padding-left: 0;
  list-style: none;
}

.comitato-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  border-top: 1px solid var(--border);
  padding-top: var(--space-16);
}

.comitato-card__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* label/14 mono: una riga, un ruolo — l'interlinea è 100%, un wrap è rotto
   per costruzione (regola sessione 15) */
.comitato-card__role {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--accent-text);
}

.comitato-card__name {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text);
}

/* --- 404 (lab-404-v1: 252:396 · 252:832) -------------------------------------
   Codice in num/128 su --text (mai accent: l'errore non urla, §5 handoff 09).
   Stessa scala di .step__num, colore diverso.
   -------------------------------------------------------------------------- */

.error-code {
  font-family: var(--font-mono);
  font-weight: var(--weight-bold);
  font-size: var(--size-128);
  line-height: var(--leading-128);
  letter-spacing: -0.05em;
  color: var(--text);
}

/* --- Form Contatti (224:388 · spec stato inviato 224:797) --------------------
   Label mono 14 sentence-case sopra i campi · bordi Brown (mai light-gray) ·
   placeholder body/20 muted, padding 16 · focus = surface White + bordo text ·
   checkbox 16px quadrato · conferma inline che SOSTITUISCE il form (§5).
   -------------------------------------------------------------------------- */

.form {
  display: flex;
  flex-direction: column;
  align-items: flex-start; /* la CTA desktop resta compatta (i campi hanno width 100%) */
  gap: var(--space-24);
  width: 100%;
}

/* Honeypot anti-spam (sessione 06): fuori schermo, mai display:none
   (i bot più furbi saltano i campi display:none) */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  width: 100%;
}

.field__label {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text); /* sentence-case: mai maiuscole (§5) */
}

.field__input {
  width: 100%;
  padding: var(--space-16);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 0;
  appearance: none;
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text);
  transition: background-color var(--duration-fast) var(--ease-base),
              border-color var(--duration-fast) var(--ease-base);
}

.field__input::placeholder { color: var(--text-muted); opacity: 1; }

textarea.field__input {
  min-height: 160px; /* canonico 224:430 */
  resize: vertical;
}

/* focus: surface White + bordo text (doppio segnale, §5) */
.field__input:focus-visible {
  outline: none;
  background: var(--surface-white);
  border-color: var(--text);
}

.consent {
  display: flex;
  align-items: flex-start;
  gap: 12px; /* canonico 224:431 */
  width: 100%;
}

.consent__checkbox {
  appearance: none;
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  margin: 0;
  background: transparent;
  border: 1px solid var(--text);
  border-radius: 0; /* quadrato, mai cerchio (§4.1) */
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-base),
              border-color var(--duration-fast) var(--ease-base);
}

.consent__checkbox:checked { background: var(--text); }

.consent__checkbox:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

.consent__label {
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-secondary);
}

/* Stati errore (handoff 09 §3 — spec 249:377). Testo+colore = doppio canale. */

.field--error .field__input,
.field--error .consent__checkbox { border-color: var(--accent-text); }

.field__error {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--accent-text);
}

/* Errore server: blocco sopra la CTA, il form resta compilato */
.form-server-error {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  width: 100%;
}

.form-server-error__title {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--accent-text);
}

.form-server-error__text {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text-secondary);
}

/* Stato inviato: sostituisce il form, stessa colonna (spec 224:797).
   Stato nel testo, dot Sage = rinforzo, non canale unico (§4.7). */
.form-confirm {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  align-items: flex-start;
}

.form-confirm__title {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-28);
  line-height: var(--leading-33);
  color: var(--text);
}

.form-confirm__dot {
  width: 16px;
  height: 16px;
  background: var(--support);
}

.form-confirm__text {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text-secondary);
}

/* --- Design System (lab-design-system-v1: 253:413 · 255:473) -----------------
   Vetrina del metodo (handoff 09 §6). Requisito chiave: i campioni LEGGONO
   tokens.css — swatch = background: var(--…), type ramp = classi .ts-* di
   produzione, radar = radar.js live. Niente valori duplicati a mano.
   Separatori e bordi chip = --line-2 (canonico). Annotazioni: 78% = secondary,
   54% = muted (letti dai fill del canonico).
   NB: la strip Primitives mostra i primitivi DI PROPOSITO — è l'unica pagina
   dove appaiono fuori da tokens.css (è la vetrina della sorgente).
   -------------------------------------------------------------------------- */

.ds-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  align-items: flex-start;
}

.ds-header .intro { max-width: 608px; }

.ds-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
  align-items: flex-start;
}

.ds-section > h2 {
  font-family: var(--font-content);
  font-weight: var(--weight-regular); /* step/28, come i titoletti prose */
  font-size: var(--size-28);
  line-height: var(--leading-33);
  color: var(--text);
}

/* annotazioni ricorrenti */
.ds-note {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-secondary);
}

.ds-body {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text-secondary);
  max-width: 608px;
}

/* Colori · strip primitives */
.ds-swatches {
  display: flex;
  flex-wrap: wrap; /* mobile: wrap (canonico 255:473) */
  gap: var(--space-16);
  width: 100%;
}

.ds-swatch {
  flex: 1 1 140px;
  display: flex;
  flex-direction: column;
  gap: 12px; /* canonico: chip→label→hex a passi di 12 */
}

.ds-swatch__chip {
  height: 96px;
  border: 1px solid var(--line-2); /* anche White resta leggibile su surface */
}

.ds-swatch__name {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text);
}

.ds-swatch__hex {
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-muted);
}

/* Colori · tabella semantica */
.ds-table {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.ds-table__caption { margin-bottom: var(--space-16); }

.ds-row {
  display: grid;
  grid-template-columns: 48px 1fr; /* mobile: chip + colonna testi */
  column-gap: var(--space-24);
  row-gap: var(--space-8);
  align-items: center;
  padding-block: 20px; /* canonico: riga 88 = 20 + chip 48 + 20 */
  border-top: 1px solid var(--line-2);
}

.ds-row:last-child { border-bottom: 1px solid var(--line-2); }

.ds-row > :nth-child(n+3) { grid-column: 2; } /* mobile: alias e uso sotto il nome */

.ds-row__chip {
  width: 48px;
  height: 48px;
  border: 1px solid var(--line-2);
  align-self: start;
}

.ds-row__name {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text);
}

.ds-row__alias {
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-muted);
}

.ds-row__use {
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-secondary);
}

/* --- Motion (sezione DS, sessione 13) -------------------------------------
   La tabella dei token motion non ha il chip colore: nome · valore · uso.
   Mobile impila (come .ds-row), desktop tre colonne.
   -------------------------------------------------------------------------- */

.ds-row--motion { grid-template-columns: 1fr; }

/* il valore è codice: mono, come il nome */
.ds-row__value {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text);
}

/* Specimen vivi: due quadrati (radius 0 come tutto), uno si muove con
   ease/out e uno cambia colore con ease/base — la differenza fra le due
   curve si legge solo vedendola. Segno = sage, come i quadrati di stato. */
.ds-motion-samples {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-32);
  margin-top: var(--space-32);
}

.ds-motion-sample {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  flex: 1 1 240px;
}

/* la nota va a riga sua sotto i due specimen */
.ds-motion-samples > .ds-note { flex: 1 1 100%; }

.ds-motion-sample__label {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-muted);
}

.ds-motion-sample__stage {
  display: flex;
  align-items: center;
  padding-block: var(--space-16);
  border-top: 1px solid var(--line-2);
}

.ds-motion-mark { width: 16px; height: 16px; }

.ds-motion-mark--move {
  background: var(--support);
  transition: transform var(--duration-base) var(--ease-out);
}

.ds-motion-mark--tint {
  background: var(--support-muted);
  transition: background-color var(--duration-base) var(--ease-base);
}

@media (hover: hover) and (pointer: fine) {
  .ds-motion-sample:hover .ds-motion-mark--move { transform: translateX(96px); }
  .ds-motion-sample:hover .ds-motion-mark--tint { background: var(--support); }
}

@media (prefers-reduced-motion: reduce) {
  .ds-motion-mark--move,
  .ds-motion-mark--tint { transition: none; }
  .ds-motion-sample:hover .ds-motion-mark--move { transform: none; }
}

/* Tipografia · famiglie */
.ds-fams {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.ds-fam {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  padding-block: var(--space-16);
  border-top: 1px solid var(--line-2);
}

.ds-fam__token {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text);
}

.ds-fam__name {
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-secondary);
}

.ds-fam__use {
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-muted);
}

/* Tipografia · type ramp: gli specimen usano le classi .ts-* di produzione */
.ds-ramp {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.ds-ramp-row {
  display: flex;
  flex-direction: column; /* mobile: specimen sopra, etichetta sotto (§6) */
  gap: var(--space-8);
  padding-block: var(--space-24);
  border-top: 1px solid var(--line-2);
}

.ds-ramp-row .specimen { color: var(--text); overflow-wrap: anywhere; }

.ds-ramp-row .ds-ramp__label {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-muted);
}

/* Segni */
.ds-lines {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  width: 100%;
}

.ds-line {
  display: grid;
  grid-template-columns: 120px 1fr;
  column-gap: var(--space-24);
  align-items: center;
}

.ds-line__label {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-secondary);
}

.ds-line__sample { border-top: 1px solid; }
.ds-line__sample--1 { border-color: var(--line-1); }
.ds-line__sample--2 { border-color: var(--line-2); }
.ds-line__sample--3 { border-color: var(--line-3); }

.ds-status {
  display: flex;
  align-items: center;
  gap: var(--space-24);
}

.ds-buttons {
  display: flex;
  flex-wrap: wrap; /* mobile: bottoni in wrap (§6) */
  align-items: center;
  gap: var(--space-32);
}

.ds-dots {
  display: flex;
  align-items: center;
  gap: var(--space-24);
}

.ds-dots__dot {
  width: 3px;
  height: 3px;
  border-radius: 50%; /* texture, non segno di stato: il canonico usa ellissi */
  background: color-mix(in srgb, var(--text) 10%, transparent);
}

/* Radar · SEMPRE radar.js live (§6), mai asset statici */
.ds-radar-family {
  display: flex;
  gap: var(--space-24); /* mobile (§6); desktop → 48 */
  pointer-events: none;
}

.ds-radar-icon { width: 64px; height: 64px; }

/* Brand kit */
.ds-downloads {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-16);
}

/* --- Home: metodo ----------------------------------------------------------- */

.steps {
  padding-inline: var(--space-24);        /* mobile: striscia full-bleed */
  scroll-padding-inline: var(--space-24); /* lo snap rispetta il margine */
}

/* ==========================================================================
   Desktop
   ========================================================================== */

@media (min-width: 768px) {

  .page-title {
    font-size: var(--size-64);
    line-height: var(--leading-64);
  }

  .hero__text { gap: var(--space-16); } /* canonico 76:2075 */

  .hero__title {
    font-size: var(--size-64);
    line-height: var(--leading-64);
    max-width: 760px;  /* canonico 76:2077 */
    text-wrap: balance;  /* sotto i ~971px il container stringe il cap: tiene le righe pari
                            invece di lasciare «minuti.» orfano */
  }

  .hero__sub {
    max-width: 560px;  /* canonico 76:2078 */
    text-wrap: balance;
  }

  .cards {
    display: grid;   /* 3×2, gap 16 (canonico 1232 = 3×400 + 2×16) */
    grid-template-columns: repeat(3, 1fr);
  }

  .steps { padding-inline: var(--space-104); }

  .button-main--block {
    /* desktop: torna hug-content, l'altezza resta quella di sistema */
    width: auto;
  }

  .steps {
    overflow-x: visible;
    scroll-snap-type: none;
  }

  .step {
    flex: 1 1 0;
    flex-direction: row;    /* num a sinistra, testo a destra */
    align-items: center;
    gap: var(--space-16);
  }

  .step__desc { max-width: 236px; } /* canonico: colonna testo ~233–236px */

  /* --- Design System (canonico 253:413) --- */

  .ds-swatch { flex: 1 1 0; } /* 8 chip su una riga (140 su canvas 1232) */

  .ds-row {
    grid-template-columns: 48px 220px 180px 1fr;
    column-gap: var(--space-24);
  }

  /* tre colonne: senza chip, e il valore più largo per i cubic-bezier
     (deve stare su una riga sola come nel canonico) */
  .ds-row--motion { grid-template-columns: 220px 300px 1fr; }

  .ds-row > :nth-child(n+3) { grid-column: auto; }
  .ds-row__chip { align-self: center; }

  .ds-fam {
    grid-template-columns: 220px 180px 1fr;
    column-gap: var(--space-24);
  }

  .ds-ramp-row {
    display: grid;
    grid-template-columns: 1fr 360px; /* specimen 840 + etichetta 360 (canonico) */
    column-gap: var(--space-32);
    align-items: center;
  }

  .ds-radar-family { gap: var(--space-48); }
}

/* --- Questionario Esposòma (fase 3, blocco 2 — canonici pagina `questionario`:
   intro 312:1168 · 317:1338, domanda 182:631 · 316:17, anagrafica 301:1135 ·
   316:1211). Senza JS la pagina flusso è un form lungo unico; quest.js
   (blocco 3) la trasforma in schermate riusando questi stessi componenti.
   -------------------------------------------------------------------------- */

/* Intro: colonna lead + indice + CTA + disclaimer (gap 24 dal canonico) */
.quest-intro {
  display: flex;
  flex-direction: column;
  gap: var(--space-24);
  width: 100%;
}

.quest-intro__lead {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: 26px; /* valore raw nel canonico (312:1231): niente token leading-26 */
  color: var(--text);
}

/* Indice domini: righe hairline non cliccabili (ghost: nessun cursor pointer) */
.quest-index {
  list-style: none;
  padding: 0;
  margin: 0;
  width: 100%;
}

.quest-index__row {
  display: flex;
  gap: var(--space-16);
  align-items: flex-start;
  padding-block: 14px; /* canonico 312:1235 */
  border-top: 1px solid var(--text); /* LINE canonica → border-top */
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: 20px; /* canonico: riga compatta 20/20 */
  color: var(--text);
}

.quest-index__numeral {
  flex-shrink: 0;
  width: 44px; /* colonna numerale canonica */
  font-family: var(--font-mono);
  font-size: var(--size-14);
  line-height: 20px; /* allineato al filo del titolo */
  color: var(--accent-text);
}

/* CTA intro: full-width anche desktop (canonico 317:1451, larga quanto la colonna) */
.quest-intro__cta { width: 100%; }

.quest-intro__disclaimer {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: 20px; /* canonico 312:1276 */
  color: var(--text-muted);
  /* respiro extra sopra il disclaimer (taratura: canonico mobile lo stacca a 80,
     desktop a 24; qui 24 dal gap + 24 di margine) */
  margin-block-start: var(--space-24);
}

/* Form flusso: un blocco per dominio (+ anagrafica), ritmo verticale 80 */
.quest-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-80);
  width: 100%;
  /* niente footer nel flusso: chiusura pagina come i canonici (pb 48) */
  padding-block-end: var(--space-48);
}

.quest-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-16); /* label dominio → prima domanda (come il question-header canonico) */
  width: 100%;
}

/* tra una domanda e la successiva: 48 totali (16 di gap + 32) */
.quest-q + .quest-q { margin-block-start: var(--space-32); }

/* Blocco domanda: fieldset azzerato, legend = testo domanda in step/28 */
.quest-q {
  display: flex;
  flex-direction: column;
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
  width: 100%;
}

.quest-q__legend {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-28);
  line-height: var(--leading-33);
  color: var(--text);
  padding: 0;
  /* la legend non partecipa al gap del flex (quirk fieldset): margine esplicito.
     24 nel form lungo; nel flusso a schermate il canonico usa 48 (blocco 3) */
  margin-block-end: var(--space-24);
}

.quest-options {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  width: 100%;
}

/* Opzione risposta (182:672): radio nativa stilizzata, il quadrato È l'input */
.quest-option {
  display: flex;
  align-items: center;
  gap: var(--space-16);
  padding: var(--space-16);
  border: 1px solid var(--light-gray);
  background: transparent;
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-base),
              background-color var(--duration-fast) var(--ease-base);
}

.quest-option__input {
  appearance: none;
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  margin: 0;
  background: transparent;
  border: 1px solid var(--light-gray);
  border-radius: 0; /* quadrato, mai cerchio (§4.1) */
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-base),
              border-color var(--duration-fast) var(--ease-base);
}

/* Selezionata: quadrato sage; card bordo text + surface White (deciso blocco 2:
   White come da motion spec — il canonico 182:675 resta su surface, discrepanza
   chiusa in chat). Fallback senza :has(): cambia solo il quadrato. */
.quest-option__input:checked {
  background: var(--support);
  border-color: var(--support);
}

.quest-option:has(.quest-option__input:checked) {
  border-color: var(--text);
  background: var(--surface-white);
}

.quest-option__input:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

/* Hover desktop: bordo text, nessun movimento (motion spec) */
@media (hover: hover) and (pointer: fine) {
  .quest-option:hover { border-color: var(--text); }
}

.quest-option__text {
  flex: 1;
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text);
}

/* Anagrafica: campi in colonna su mobile (301:1174), in riga su desktop */
.quest-fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  width: 100%;
}

.quest-bmi {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text);
  margin-block-start: var(--space-8);
}

.quest-submit { width: 100%; }

/* Nota informativa sotto il submit (sessione 11, DPO): stessa grammatica
   del consent__label — ui/14 regular secondario */
/* Note di servizio del questionario: la 18+ sotto la CTA e quella sui tre
   dati anagrafici (sessione 13). Stessa grammatica, ritmo dato dal margine
   perché .quest-q e .quest-submit non usano gap. */
.quest-submit__note,
.quest-q__note {
  margin-top: var(--space-16);
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-secondary);
}

@media (min-width: 768px) {

  /* Intro desktop: colonna destra 608 come .prose (canonico 317:1408) */
  .quest-intro { width: 608px; }

  /* Colonna flusso desktop: 608 centrata (canonico 316:17 @1440: x 416, w 608).
     Il padding del .container (104) va azzerato: 608 è la colonna piena */
  .quest-form {
    width: 608px;
    padding-inline: 0;
    margin-inline: auto;
  }

  /* Anagrafica desktop: tre campi in riga (316:1211) */
  .quest-fields {
    flex-direction: row;
    gap: var(--space-16);
  }

  .quest-fields .field {
    flex: 1 1 0;
    min-width: 0;
  }
}

/* --- Questionario: flusso a schermate (quest.js, blocco 3) -------------------
   Motion spec docs/lab-quest-motion-spec.md. Le classi .quest-screen--* sono
   montate/rimosse da quest.js; senza JS nulla di questo si attiva.
   ---------------------------------------------------------------------------- */

.quest-form--flow {
  /* token motion della spec (D3: scoped qui, non in tokens.css — speculari
     alle Variables `quest/*` nella collection Motion, sync sessione 12) */
  --quest-fast: 150ms;
  --quest-base: 400ms;
  --quest-ease: cubic-bezier(0.2, 0, 0, 1);

  position: relative; /* la schermata uscente esce in assoluto, senza salti */
  gap: 0;
}

/* il form lungo sparisce: restano solo le schermate montate da quest.js
   (i radio nei blocchi nascosti restano vivi e verranno inviati col submit) */
.quest-form--flow > .quest-block,
.quest-form--flow > .quest-submit { display: none; }

.quest-screen {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  width: 100%;
  transition: transform var(--quest-base) var(--quest-ease),
              opacity var(--quest-base) var(--quest-ease);
}

/* Header persistente del flusso: label + progress fuori dalle transizioni
   (revisione 2026-07-22 — le schermate scorrono, la barra resta) */
.quest-flowhead {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  width: 100%;
}

/* le schermate vivono in un wrapper relativo: l'uscente va in assoluto
   senza sovrapporsi all'header */
.quest-screens {
  position: relative;
  width: 100%;
  margin-block-start: var(--space-16); /* progress → domanda, come il canonico */
}

/* nel flusso la domanda respira come nel canonico (48 verso le risposte);
   nel form lungo senza JS resta il 24 della regola base */
.quest-form--flow .quest-q__legend { margin-block-end: var(--space-48); }

/* Progress: 8 segmenti dominio (canonico 182:660) — fatti --text, corrente
   --accent (si riempie in 200ms linear), futuri light-gray */
.quest-progress {
  display: flex;
  gap: var(--space-4);
  width: 100%;
}

.quest-progress__seg {
  flex: 1 1 0;
  min-width: 1px;
  height: 2px;
  background: var(--light-gray);
  overflow: hidden;
}

.quest-progress__fill {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
  /* linear voluto: su una barra la velocità costante è il senso del segno */
  transition: width var(--duration-base) linear;
}

.quest-progress__seg--done .quest-progress__fill {
  width: 100%;
  background: var(--text);
}

.quest-progress__seg--current .quest-progress__fill {
  width: 100%;
  background: var(--accent);
}

/* Nav di schermata: ← Indietro a sinistra, hint/CTA a destra (canonico 182:684) */
.quest-screen__nav {
  margin-block-start: var(--space-32);
  padding-block-end: var(--space-48);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-16);
  width: 100%;
}

.quest-screen__nav-right {
  display: flex;
  align-items: center;
  gap: var(--space-24);
}

.quest-back {
  appearance: none;
  background: none;
  border: 0;
  padding: var(--space-8);
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}

/* quando nella riga c'è una CTA, l'hint lascia spazio (canonico desktop lo
   mostra solo sulle schermate senza CTA in riga — taratura da Italo) */
.quest-screen__nav-right:has(.button-main) .quest-hint { display: none; }

/* Hint tastiera: solo desktop, mono muted (canonici 316:17 · 316:1211) */
.quest-hint {
  display: none;
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-muted);
}

/* Schermate di stato (ripresa/errore — canonico 317:1455) */
.quest-screen__text {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: 26px; /* come il lead (valore raw nei canonici) */
  color: var(--text);
  outline: none;
}

.quest-resume-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-16);
  margin-block-start: var(--space-8);
}

/* Transizioni di vista: avanti = il contenuto sale, indietro = scende (spec).
   L'entrata parte a metà dell'uscita (--delayed). */
.quest-screen--leaving {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
}

.quest-screen--leave-up          { transform: translateY(-24px); opacity: 0; }
.quest-screen--leave-down        { transform: translateY(24px);  opacity: 0; }
.quest-screen--enter-from-bottom { transform: translateY(24px);  opacity: 0; }
.quest-screen--enter-from-top    { transform: translateY(-24px); opacity: 0; }
.quest-screen--delayed           { transition-delay: calc(var(--quest-base) / 2); }

/* Errore "Invio senza risposta": shake ±4px, 3 oscillazioni, 250ms + messaggio
   testuale (il colore/movimento non è mai canale unico) */
@keyframes quest-shake {
  0%, 100% { transform: translateX(0); }
  16% { transform: translateX(-4px); }
  33% { transform: translateX(4px); }
  50% { transform: translateX(-4px); }
  66% { transform: translateX(4px); }
  83% { transform: translateX(-2px); }
}

.quest-screen--shake .quest-options { animation: quest-shake 250ms; }

@media (prefers-reduced-motion: reduce) {
  .quest-screen { transition: none; }
  .quest-progress__fill { transition: none; }
  .quest-screen--shake .quest-options { animation: none; }
}

@media (min-width: 768px) {
  .quest-hint { display: block; }
}

/* --- Esito Esposòma (blocco 5 — canonici 307:5 mobile · 317:20 desktop) ------
   Desktop = pattern textpage: title-col 400 (label + NN/100 + copy fascia) +
   colonna 608. Mobile: tutto in colonna, il copy fascia sta sopra il radar
   (due nodi, uno per breakpoint: il canonico li posiziona diversamente).
   ---------------------------------------------------------------------------- */

.esito-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-80);
  width: 100%;
}

.esito-copy {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24); /* mobile 307:1198; desktop → 26 */
  color: var(--text);
}

.esito-copy--desktop { display: none; }

.esito-composito {
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
  width: 100%;
}

.esito-radar {
  display: flex;
  justify-content: center;
  width: 100%;
}

.esito-sez {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.esito-h2 {
  font-family: var(--font-content);
  font-weight: var(--weight-regular); /* step/28 come i titoletti prose */
  font-size: var(--size-28);
  line-height: var(--leading-33);
  color: var(--text);
  margin-block-end: var(--space-24);
}

/* Righe priorità (309:12): hairline, titolo 20, score mono accent */
.esito-prio {
  appearance: none;
  background: none;
  border: 0;
  border-top: 1px solid var(--text); /* LINE canonica → border-top */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-8);
  padding: var(--space-8) 0 var(--space-16);
  width: 100%;
  text-align: left;
  cursor: pointer;
}

.esito-prio__title {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text);
}

.esito-prio__score {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--accent-text);
}

/* Righe dettaglio (310:11): head cliccabile py16, score a destra w80 */
.esito-row { width: 100%; }

.esito-row__head {
  appearance: none;
  background: none;
  border: 0;
  border-top: 1px solid var(--text);
  display: flex;
  align-items: center;
  gap: var(--space-16);
  padding: var(--space-16) 0;
  width: 100%;
  text-align: left;
  cursor: pointer;
}

.esito-row__title {
  flex: 1;
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text);
}

.esito-row__score {
  flex-shrink: 0;
  width: 80px;
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--accent-text);
  text-align: right;
}

.esito-row__panel {
  display: flex;
  flex-direction: column;
  gap: 12px; /* canonico 310:17 */
  padding-block-end: var(--space-24);
}

.esito-row__testo p {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: 26px;
  color: var(--text-secondary);
}

.esito-row__label {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--accent-text);
}

/* nota di dominio (fuori canonico, contenuto di sicurezza: taratura Italo) */
.esito-row__nota {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: 20px;
  color: var(--text-muted);
}

/* Sezioni testuali e azioni (sez-base 312:10 · referto 312:1147) */
.esito-testo { gap: var(--space-16); }
.esito-testo .esito-h2 { margin-block-end: 0; }

.esito-nota {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: 26px;
  color: var(--text-secondary);
}

.esito-voce {
  font-family: var(--font-content);
  font-weight: var(--weight-regular);
  font-size: var(--size-20);
  line-height: 26px;
  color: var(--text);
}

.esito-azioni { gap: var(--space-24); }
.esito-azioni .esito-h2 { margin-block-end: 0; }

.esito-form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-24);
  width: 100%;
}

@media (min-width: 768px) {

  .esito-copy--desktop { display: block; }
  .esito-copy--mobile  { display: none; }
  .esito-copy { line-height: 26px; } /* canonico desktop 317:96 */

  .esito-col { width: 608px; }

  /* radar 420 in testa alla colonna, allineato a sinistra (317:1225) */
  .esito-radar { justify-content: flex-start; }
}

/* --- Esito reveal (spec v1.1, approvata 2026-07-22) --------------------------
   Cascata sovrapposta: numero → copy → radar → sezioni. Le classi sono
   montate da quest-esito.js; con prefers-reduced-motion tutto è statico.
   ---------------------------------------------------------------------------- */

/* il numero non fa ballare il layout mentre conta */
[data-esito-score] { font-variant-numeric: tabular-nums; }

/* copy fascia: fade mentre il numero si posa (delay inline dal JS) */
.esito-fade {
  opacity: 0;
  transition: opacity 400ms var(--ease-base);
}

.esito-fade--in { opacity: 1; }

/* sezioni: fade + salita 24px con l'ease-out forte di sistema (skill emil:
   entrata = ease-out, mai ease-in). Lo sfalsamento è inline dal JS. */
.esito-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 400ms var(--ease-out),
              transform 400ms var(--ease-out);
}

.esito-reveal--in {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .esito-fade,
  .esito-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ============================================================
   Admin — gestionale v1 (sessione 10, sola lettura, /admin/).
   Strumento interno: fuori dal file Figma per decisione chiusa
   (deroga approvata da Italo). Tabelle dati: componente nuovo,
   solo token semantici, radius 0 come tutto il resto.
   ============================================================ */

/* il gap 80 di .page main è il ritmo delle pagine pubbliche: qui il
   ritmo è dei margini espliciti dei blocchi (16/32). main.admin per
   vincere la specificità di .page main */
main.admin {
  /* 24 in testa (era 48): "Gestionale" è passato nella nav in sessione 13
     e lo spazio che occupava sopra le tab restava vuoto */
  padding-block: 24px 96px;
  gap: 0;
}

/* login: colonna stretta come i form del sito */
.admin-login {
  max-width: 432px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.admin-login .page-title { margin-bottom: 8px; }

/* logout nella nav: bottone nudo con la grammatica del .link */
.admin-logout {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

/* wordmark + "Gestionale" nella nav (sessione 13): il contesto sta accanto
   al logo, non in una riga sua */
.admin-brand {
  display: flex;
  align-items: center;
  gap: var(--space-16);
}

/* nav delle viste: sta SOPRA la riga (la riga è di .admin-controls) */
.admin-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

.admin-tab {
  font-family: var(--font-mono);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-secondary);
  text-decoration: none;
}

a.admin-tab:hover { color: var(--text); }

.admin-tab[aria-current="page"] {
  color: var(--text);
  font-weight: var(--weight-bold);
}

.admin-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 24px;
  margin-top: 32px;
}

.admin-count {
  font-family: var(--font-mono);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-secondary);
}

/* stato sempre nel testo, il colore è rinforzo */
.admin-flag { color: var(--accent-text); }

.admin-empty {
  margin-top: 16px;
  color: var(--text-secondary);
}

/* le tabelle larghe scorrono nel loro contenitore, mai la pagina */
.admin-scroll {
  margin-top: 16px;
  overflow-x: auto;
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--size-14);
  line-height: var(--leading-24);
}

/* testata = grammatica label form: Geist Mono 14 sentence-case */
.admin-table th {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-secondary);
  text-align: left;
  padding: 8px 16px 8px 0;
  border-bottom: 1px solid var(--text);
  white-space: nowrap;
}

/* celle su una riga: la tabella si allarga e scorre nel contenitore
   (.admin-scroll), mai date spezzate su piu righe (sessione 10) */
.admin-table td {
  padding: 10px 16px 10px 0;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
  white-space: nowrap;
}

.admin-table .is-num { text-align: right; }
.is-mono { font-family: var(--font-mono); }
.admin-table .is-prose { max-width: 608px; white-space: normal; }

/* riga sotto la linea (sessione 13): filtro di contesto a sinistra, cerca
   spinto a destra da margin-left auto (resta a destra anche nelle viste
   senza filtro). La LINE è border-top, come in tutto il build. */
.admin-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-16);
  margin-top: var(--space-16);
  border-top: 1px solid var(--border);
  padding-top: var(--space-16);
}

/* filtro per strumento (appare solo con piu questionari nel DB) */
.admin-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 16px;
}

.admin-filter__label {
  font-family: var(--font-mono);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-muted);
}

/* strumento in preparazione: grigio, non cliccabile (grammatica ghost) */
.admin-tab--ghost { color: var(--text-muted); }

/* nell'admin la nav del sito NON è sticky: la barra pinnata è una sola,
   la testata del gestionale (altrimenti si sovrappongono in cima) */
.nav--static { position: static; }

/* testata sticky: resta in vista sullo scroll delle righe. Fondo surface
   pieno + filo border sotto; z-index sopra le righe della tabella.
   Convive con overflow-x: clip su html/body (clip non crea scroll
   container, a differenza di hidden). Selettore main.admin > per battere
   il position: relative di `.page main > *` (base.css). */
main.admin > .admin-sticky {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface);
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}

/* campo di ricerca (Submissions/Contatti/Iscritti; la vista Ricerca è
   anonima: niente search) */
.admin-search {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-left: auto;
}

/* DEROGA d'altezza, solo nell'admin (sessione 13): il campo del sito è 58px
   (padding 16 + riga 24 + bordi), qui sta in una barra di controlli densa →
   32px, il gradino base-8 più vicino alla metà e sopra il minimo di target
   a11y (24px). Testo mono 14 = la stessa grammatica delle label form e
   delle tab accanto. Altezza esplicita + padding orizzontale: il testo di
   un input a riga singola si centra da sé nella scatola. */
.admin-search__input {
  max-width: 320px;
  height: 32px;
  padding: 0 var(--space-8);
  font-family: var(--font-mono);
  font-size: var(--size-14);
  line-height: var(--leading-14);
}

/* Conferma eliminazione (v1.1, sessione 11) — l'unica azione distruttiva
   dell'admin: stato dichiarato nel testo, accent come rinforzo, CTA piena
   per il gesto definitivo */
.admin-confirm {
  margin-top: var(--space-16);
  padding: var(--space-16);
  border: 1px solid var(--accent-text);
  max-width: 608px;
}

.admin-confirm__text {
  font-size: var(--size-14);
  line-height: var(--leading-14);
}

.admin-confirm__actions {
  margin-top: var(--space-16);
  display: flex;
  align-items: center;
  gap: var(--space-16);
}

.admin-note {
  margin-top: 32px;
  max-width: 608px;
  font-size: var(--size-14);
  color: var(--text-muted);
}

/* --- Statistiche (sessione 13) ----------------------------------------
   Contatore first-party: la vista è tutta lettura, tabelle e conteggi.
   Numeri sempre nel testo, la barra è solo un rinforzo visivo. */

/* sommario: riquadri che si ridistribuiscono da soli, filo in testa come
   la riga di testata delle tabelle */
/* colonne larghe abbastanza per il valore più lungo ("12 min 34 s") su una
   riga sola: se il numero va a capo, le etichette della riga si sfalsano */
.admin-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-16);
  margin-top: var(--space-16);
}

.admin-stat {
  border-top: 1px solid var(--text);
  padding-top: var(--space-8);
}

.admin-stat__value {
  font-family: var(--font-mono);
  font-size: var(--size-28);
  line-height: var(--leading-33);
  white-space: nowrap;
}

.admin-stat__label {
  font-family: var(--font-mono);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-muted);
}

.admin-block { margin-top: var(--space-32); }

.admin-block__figures { margin-top: var(--space-8); }

/* nota di metodo attaccata al titolo del blocco, non al fondo pagina */
.admin-note--tight { margin-top: var(--space-8); }

/* barra dei conteggi: neutra (line/3, come le hairline), MAI un pieno di
   marca — il pieno resta grammatica delle CTA. Il numero sta sempre nella
   cella accanto: la barra non è l'unico canale del dato. */
.admin-bar-cell {
  width: 30%;
  min-width: 96px;
  vertical-align: middle;
}

.admin-bar {
  display: block;
  height: 4px;
  background: var(--line-3);
}

/* ==========================================================================
   Modulo metriche — Colophon (canonici 440:952 desktop, 441:952 mobile)
   --------------------------------------------------------------------------
   Il numero è il valore misurato, la barra è il punteggio Lighthouse della
   metrica: due canali, mai il colore da solo. Senza JS numeri e riempimenti
   sono già al loro posto — l'animazione è un enhancement e si spegne con
   prefers-reduced-motion.
   Mobile: Lighthouse 2×2 (a quattro colonne la label "Performance" andrebbe
   a capo, e label/14 ha interlinea 100%), colonne Desktop/Mobile impilate.
   ========================================================================== */

/* Il numero di colonne dipende da quanto è largo IL MODULO, non la finestra:
   fra 768px e ~1080px la prose sta a 377px e quattro colonne spezzerebbero
   "Accessibilità" (109px in label/14, che ha interlinea 100% → il wrap si
   sovrappone). Misurato in pagina: prose 377 a 926px di viewport, 608 a 1280,
   cioè la larghezza del canonico. Da qui le container query. */
.metrics {
  container: metrics / inline-size;
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
  /* 24 + gap 8 della section = 32 su entrambi i lati, il ritmo della prose.
     Il paragrafo sta SOTTO il modulo: su mobile, sopra, spingeva le celle
     fuori dalla piega (misurato: 295px fuori a 390×844, zero spostandolo). */
  margin-top: var(--space-24);
  margin-bottom: var(--space-24);
  padding: var(--space-32) 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.metrics__block,
.metrics__col {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
}

.metrics__label {
  font-family: var(--font-ui);
  font-weight: var(--weight-medium);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text);
}

.metrics__cols {
  display: flex;
  flex-direction: column;
  gap: var(--space-24);
}

.metrics__col { container: metricscol / inline-size; }

/* minmax(0, 1fr) e non 1fr: con 1fr la cella più larga si prende lo spazio
   delle altre e le colonne escono disuguali (92 · 109 · 67 · 36 nel primo
   render). */
.metrics__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16) var(--space-24);
}

/* 256 = due celle da 116 più un gap da 24. Sotto, una colonna sola: a 768px
   di viewport la prose del textpage scende a 154px (misurato) e nemmeno due
   ci starebbero. */
@container metrics (min-width: 256px) {
  .metrics__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* i Core Web Vitals restano a due anche quando la riga Lighthouse scende a
   una: "140 ms" sta in 50px, quindi due colonne reggono fino in fondo */
.metrics__grid--cwv {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-8);
}

/* 536 = quattro celle da 116 (la label più lunga sta in 109) più tre gap da 24 */
@container metrics (min-width: 536px) {
  .metrics__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .metrics__cols { flex-direction: row; }
  .metrics__col { flex: 1 1 0; }
}

/* 248 = quattro celle da 56 ("140 ms" sta in 50) più tre gap da 8 */
@container metricscol (min-width: 248px) {
  .metrics__grid--cwv { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.metric {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.metric__value {
  font-family: var(--font-mono);
  font-weight: var(--weight-bold);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.metric__value--sm {
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
}

/* stessa grammatica della barra dei conteggi dell'admin: il segno è line/3,
   neutro, mai un pieno — il pieno resta delle CTA. La traccia scende a line/1
   per tenere leggibile il salto fra vuoto e pieno. */
.metric__track {
  display: block;
  height: 4px;
  background: var(--line-1);
}

/* la percentuale arriva dal markup come --score: senza JS la barra è già
   al suo posto, e l'animazione la scavalca scrivendo width inline */
.metric__fill {
  display: block;
  width: var(--score, 0%);
  height: 100%;
  background: var(--line-3);
}

.metric__name,
.metrics__col-label,
.metrics__caption {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-secondary);   /* mai --text-muted: 3,58:1 sul fondo pagina */
}

.metrics__caption { line-height: var(--leading-24); }

/* stato di partenza dell'animazione: lo mette JS, così senza JS non esiste */
.metrics.is-anim .metric__fill { width: 0; }
.metrics.is-anim .metric__value,
.metrics.is-anim .metric__name { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .metrics.is-anim .metric__fill,
  .metrics.is-anim .metric__value,
  .metrics.is-anim .metric__name { transition: none !important; }
}

/* ==========================================================================
   Textpage a due colonne — solo quando c'è davvero posto
   --------------------------------------------------------------------------
   400 (title-col) + 16 (gap) + 608 (prose) + 208 (padding del container, 104
   per lato sopra i 768) = 1232, più il margine per la scrollbar → 1248.
   Sotto quella soglia la prose è un flex item che si comprime, e a 768px di
   viewport scendeva a 154px: misurato su info (187), privacy (199), metodo
   (164). Il breakpoint era a 768 e la riga di testo si spezzava su sette
   pagine. Sotto 1248 la pagina resta impilata, con la prose a 608 di misura.
   Default dichiarato (sessione 16): la soglia è 1248, da spostare a occhio.
   ========================================================================== */

@media (min-width: 1248px) {
  .textpage {
    flex-direction: row;
    gap: var(--space-16);
  }

  .textpage__head { width: 400px; flex-shrink: 0; }

  .prose { width: 608px; }
}
