/* components.css — composizione del verticale pipeline_rehab.
   Il segno del verticale: testata BIANCA (richiesta del cliente) + fascia fotografica a tutta larghezza
   in slideshow, poi pagina bianca con bande blu come intermezzo. Nessun colore letterale: solo token. */

/* --- contenitori e bande ------------------------------------------------------------------ */
.container { width: min(100% - (var(--gutter) * 2), var(--container)); margin-inline: auto; }
.container--narrow { width: min(100% - (var(--gutter) * 2), var(--container-narrow)); margin-inline: auto; }

.section { padding-block: var(--section-y); background: var(--paper); color: var(--ink); }
.section--alt { background: var(--surface); }
.section--tint { background: var(--grad-tint); }
/* Banda blu: RIDICHIARA gli alias di pagina e il focus su di se'. Senza, l'anello di focus resterebbe
   il blu scuro e contro il blu della banda misurerebbe meno di 3.0. */
.section--brand {
  background: var(--grad-brand); color: var(--on-dark);
  --fg: var(--on-dark); --focus: var(--on-dark); --line: rgba(255,255,255,.26);
 --line-strong: rgba(255,255,255,.65);
}
.section--brand .lead, .section--brand .section-intro p { color: var(--on-dark-muted); }
.section--brand .eyebrow { color: var(--sage-light); }
.section--tight { padding-block: var(--space-8); }

.section-intro { margin-bottom: var(--space-7); }
.section-intro h2 { max-width: 22ch; }

/* --- bottoni ------------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  font-family: var(--font-accent); font-weight: 700; font-size: 0.98rem;
  padding: var(--space-3) var(--space-5); border-radius: var(--radius);
  border: 2px solid transparent; min-height: 48px; text-align: center;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
/* ⚠ Il primario e' --accent-ink, non --accent: sul rosso pieno il bianco fa 4.52, a norma ma col
   margine esaurito; su --accent-dark fa 8.38. Il rosso vivo resta lo stato di passaggio. */
.btn--primary { background: var(--accent-ink); color: var(--on-dark); }
.btn--primary:hover { background: var(--accent); }
/* ⚠ Il contorno prende il colore di PRIMO PIANO della superficie, non l'inchiostro fisso: sulle fasce
   scure il telefono restava blu su blu e non si leggeva (segnalato dall'owner). Le superfici scure
   dichiarano già `--fg`; qui dichiarano anche il filetto. */
.btn--outline { background: transparent; color: var(--fg); border-color: var(--line-strong); }
.btn--outline:hover { border-color: currentColor; background: color-mix(in srgb, currentColor 10%, transparent); }
.btn--soft { background: var(--sage-tint); color: var(--brand); }
.btn--soft:hover { background: var(--sage-light); }
/* --- WhatsApp: icona + pulsazione, RIUSATE da building_supplier (regola owner: non se ne inventa una
   nuova). Il verde è quello scuro del marchio (#0B8043): su bianco regge il testo bianco a 5.2:1,
   mentre il #25D366 chiaro no. ⚠ La guardia `prefers-reduced-motion` non si toglie. --- */
.btn--wa { background: #0B8043; color: #fff; border-color: #0B8043; gap: var(--space-2); }
.btn--wa:hover { background: #0a6f3a; color: #fff; }
.btn--wa svg { flex: none; }
@media (prefers-reduced-motion: no-preference) {
  .btn--wa { animation: fp-wa-pulse 2.8s ease-in-out infinite; }
}
@keyframes fp-wa-pulse {
  0%, 65%, 100% { box-shadow: 0 0 0 0 rgba(11,128,67,.5); }
  32% { box-shadow: 0 0 0 9px rgba(11,128,67,0); }
}
/* Sopra una fotografia il bottone chiaro deve restare LEGGIBILE a prescindere dallo scatto. */
.btn--on-photo { background: var(--paper); color: var(--brand-dark); }

/* --- barra di servizio e testata BIANCA ---------------------------------------------------- */
.topbar { background: var(--brand-dark); color: var(--on-dark-muted); font-size: var(--text-sm); }
.topbar__row { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); padding-block: var(--space-2); justify-content: flex-end; }
.topbar__item { color: var(--on-dark-muted); }
.topbar__item:hover { color: var(--on-dark); }

/* ⚠⚠ Il menu a tendina di WordPress scatta a 600px, ma con OTTO voci lunghe la barra a riga singola
   non ci sta prima dei 1000: fra 600 e 1000 andava a due o tre righe e la testata arrivava a 178px —
   che fissata in alto mangerebbe un quinto dello schermo. Qui si estende il comportamento «mobile»
   di WP fino a 999.98, ricalcando le sue stesse regole. ⚠ La finestra è OBBLIGATORIA: una regola
   piatta sul pulsante lo farebbe comparire anche sul desktop (difetto già pagato su questo sito). */
@media (max-width: 999.98px) {
  /* Con la tendina la testata è una riga sola: 99px misurati. */
  :root { --header-h: 100px; }
  .site-header .wp-block-navigation__responsive-container:not(.is-menu-open) { display: none; }
  .site-header .wp-block-navigation__responsive-container-open:not(.always-shown) { display: flex; }
}

/* ⚠⚠ TESTATA FISSA (richiesta owner): resta in alto mentre la pagina scorre.
   La barra di servizio in cima NON è fissa — scorre via e lascia alla testata i suoi 64px scarsi.
   Il `display: contents` sull'involucro del template part è la chiave: senza, lo sticky avrebbe come
   blocco contenitore quell'involucro alto quanto la testata stessa, e si staccherebbe subito (il
   difetto pagato su Util.Fer). Serve anche uno z-index sopra le fasce con la foto INCHIODATA, che
   sono `position: fixed`. */
.wp-site-blocks > .wp-block-template-part:first-child { display: contents; }
.site-header {
  background: var(--paper); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 60;
}
/* ⚠ `align-items: baseline` sulla riga, `align-self: center` su marchio e CTA: il titolo e la nav hanno
   corpi diversi e centrati cadrebbero su basi diverse. */
.site-header__row { display: flex; align-items: baseline; gap: var(--space-4); padding-block: var(--space-3); }
/* La sottoriga del marchio costa ~120px alla nav: sotto i 1200 sparisce prima delle voci di menu. */
@media (max-width: 1200px) { .wordmark__tag { display: none; } }
/* Fra i 900 (dove entra la barra mobile) e i 1100 la barra di navigazione non ci sta in una riga: il
   primo elemento che cede e' il bottone di testata, perche' la stessa CTA e' ripetuta in ogni fascia
   della pagina e nel pie'. Le voci di menu no: quelle sono la navigazione. */
@media (max-width: 1100px) {
  .site-header__cta { display: none; }
  .site-nav .wp-block-navigation-item__content { font-size: 0.9rem; }
}
.wordmark { display: flex; align-items: center; gap: var(--space-3); align-self: center; flex: none; }
.wordmark__mark { height: 38px; width: auto; }
.wordmark__name { display: flex; flex-direction: column; line-height: 1.1; }
.wordmark__txt { font-family: var(--font-accent); font-weight: 800; font-size: var(--text-md); color: var(--brand); letter-spacing: 0; }
.wordmark__tag { font-size: 0.72rem; color: var(--ink-muted); letter-spacing: 0.04em; }

.site-nav { margin-left: auto; }
/* ⚠ Il vuoto fra le voci lo mette il block-gap di WP (~32px): con 8 voci sono 224px, e la barra andava
   a due righe. Si stringe QUI, sul contenitore che WP genera. */
.site-nav .wp-block-navigation__container { gap: var(--space-3); }
.site-nav .wp-block-navigation-item__content {
  font-family: var(--font-accent); font-weight: 600; font-size: 0.95rem; color: var(--ink);
  padding-block: var(--space-1); border-bottom: 2px solid transparent;
}
.site-nav .wp-block-navigation-item__content:hover,
.site-nav .current-menu-item .wp-block-navigation-item__content { color: var(--brand); border-bottom-color: var(--accent); }

.header-tel { font-family: var(--font-accent); font-weight: 700; color: var(--brand); white-space: nowrap; align-self: center; }
.site-header__cta { align-self: center; flex: none; margin-left: var(--space-3); }

/* ⚠⚠ L'overlay mobile di wp:navigation: il fondo bianco lo impone una regola WP a (0,5,0). La via
   giusta NON e' rincorrere la specificita' ma dichiarare overlayBackgroundColor/overlayTextColor SUL
   BLOCCO — WP genera classi con !important, che vincono per costruzione. Qui resta solo la geometria.
   ⚠ `align-items` governa l'asse ORIZZONTALE: quei contenitori sono flex in COLONNA. Con `flex-start`
   la lista si stringe sul testo e i filetti escono di lunghezze diverse; serve `stretch`. */
/* ⚠⚠ Qui si dichiara SOLO la misura dell'area di tocco: il `display` lo governa WP, che nasconde il
   pulsante sopra il breakpoint. Dichiarandolo qui si vinceva sul suo `display:none` e l'hamburger
   restava visibile anche a 1440, accanto al menu esteso. */
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close { min-width: 50px; min-height: 50px; }

/* ── overlay mobile ─────────────────────────────────────────────────────────────────────────────
   ⚠⚠ `is-menu-open` sta sul CONTENITORE, non su `.site-nav` (che e' la <ul>): una regola scritta
   `.site-nav.is-menu-open …` non aggancia nulla — misurato, le voci restavano in una colonna di
   106px schiacciata a destra.
   ⚠ `align-items` qui governa l'asse ORIZZONTALE, perche' questi contenitori sono flex in COLONNA:
   serve `stretch`, non `flex-start` (che stringerebbe la lista sul testo). */
.wp-block-navigation__responsive-container.is-menu-open { padding: 0; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
  align-items: stretch; width: 100%; padding: var(--space-8) var(--gutter) var(--space-6);
}
/* ⚠⚠ SPECIFICITA': le regole di WP per l'overlay pesano quanto le mie e arrivano DOPO, quindi una
   regola piatta perde — misurato: la lista restava `align-items: flex-start` e il padding della voce
   restava 0, cioe' i filetti uscivano larghi quanto la PAROLA e l'area di tocco era 31px. La classe
   si raddoppia per alzare il peso di uno scalino, che e' come WP stessa risolve i propri conflitti. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container.wp-block-navigation__container {
  align-items: stretch; width: 100%; gap: 0;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item.wp-block-navigation-item {
  align-items: stretch; width: 100%; border-bottom: 1px solid rgba(255,255,255,.18);
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content.wp-block-navigation-item__content {
  display: block; width: 100%; text-align: left;
  font-family: var(--font-accent); font-weight: 700; font-size: var(--text-md);
  color: var(--on-dark); padding: var(--space-4) 0; border-bottom: 0;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:hover,
.wp-block-navigation__responsive-container.is-menu-open .current-menu-item .wp-block-navigation-item__content { color: var(--sage-light); }
/* Il pulsante di chiusura sul gutter delle voci, non appiccicato all'angolo. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close {
  top: var(--space-4); right: var(--gutter); color: var(--on-dark);
}

/* --- HERO: fascia fotografica a tutta larghezza sotto la testata bianca --------------------- */
.hero { position: relative; isolation: isolate; display: grid; align-items: end; min-height: clamp(430px, 52vw, 620px); }
.hero__media { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
/* Slideshow in crossfade: le slide vivono DIETRO lo scrim (z-index negativo dentro l'isolamento). */
/* ⚠ Le slide sono <img>, non sfondi CSS: uno sfondo non e' un'immagine per il browser — non entra
   nel conteggio, non ha alt, non riceve fetchpriority e non partecipa al LCP. */
.hero__slide { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; animation: fp-hero-fade 27s infinite; }
.hero__slide:nth-child(1) { animation-delay: 0s; }
.hero__slide:nth-child(2) { animation-delay: 9s; }
.hero__slide:nth-child(3) { animation-delay: 18s; }
@keyframes fp-hero-fade { 0%, 33.33% { opacity: 1; } 41%, 100% { opacity: 0; } }
.hero::after { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--grad-scrim); }
.hero__in { padding-block: clamp(2.5rem, 5vw, 4.5rem); color: var(--on-dark); }
.hero h1 { color: var(--on-dark); max-width: 19ch; text-wrap: balance; }
.hero .lead { color: var(--on-dark-muted); max-width: 40rem; }
.hero .eyebrow { color: var(--on-dark); }
.hero__cta { display: flex; gap: var(--space-3); flex-wrap: wrap; margin-top: var(--space-6); }
.hero__facts { display: flex; gap: var(--space-7); flex-wrap: wrap; margin-top: var(--space-7); padding-top: var(--space-5); border-top: 1px solid rgba(255,255,255,.28); }
.hero__fact b { display: block; font-family: var(--font-accent); font-size: var(--text-lg); font-weight: 800; color: var(--on-dark); }
.hero__fact span { font-size: 0.9rem; color: var(--on-dark-muted); }
/* Variante design-only: nessuna foto sopra soglia ⇒ campo blu, mai una foto finta. */
.hero--design { background: var(--grad-deep); min-height: auto; }
.hero--design::after { display: none; }

/* --- testata delle pagine interne ---------------------------------------------------------- */
/* ⚠ La page-head NON riusa la size dell'hero: e' una testata di pagina, non un hero. */
.page-head { background: var(--grad-tint); padding-block: var(--space-8); border-bottom: 1px solid var(--line); }
.page-head h1 { font-size: var(--text-2xl); color: var(--brand-dark); max-width: 24ch; }
.page-head p { color: var(--ink-muted); }

/* --- tessere degli argomenti ---------------------------------------------------------------- */
.topics { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-5); }
.topic { background: var(--paper); border: var(--border); border-radius: var(--radius); overflow: hidden; display: flex; flex-direction: column; }
.topic:hover { border-color: var(--brand); }
.topic__media { aspect-ratio: var(--tile-ratio); overflow: hidden; background: var(--surface); }
.topic__media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur) var(--ease); }
.topic:hover .topic__media img { transform: scale(1.04); }
.topic__body { padding: var(--space-4) var(--space-5) var(--space-5); flex: 1; display: flex; flex-direction: column; }
.topic h3 { margin-bottom: var(--space-1); color: var(--brand); }
.topic p { font-size: 0.95rem; color: var(--ink-muted); margin-bottom: 0; }
.topic__more { margin-top: auto; padding-top: var(--space-3); font-family: var(--font-accent); font-weight: 700; font-size: 0.9rem; color: var(--accent-ink); }

/* --- schede dei servizi (filetto di marca a sinistra) --------------------------------------- */
/* ⚠ Le schede dei servizi sono OTTO: su tre colonne l'ultima riga resta coperta a due terzi. Con
   quattro colonne (dove c'è spazio) e due sotto i 1200, ogni riga è piena per costruzione. */
.svc-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4); }
@media (min-width: 1200px) { .svc-grid { grid-template-columns: repeat(4, 1fr); } }
.svc { background: var(--paper); border: var(--border); border-left: 3px solid var(--brand); border-radius: var(--radius); padding: var(--space-4) var(--space-5); }
.svc:hover { border-left-color: var(--accent); }
.svc h3 { font-size: 1.02rem; margin-bottom: var(--space-1); }
.svc p { font-size: 0.9rem; color: var(--ink-muted); margin: 0; }
.section--brand .svc { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.22); border-left-color: var(--accent); }
.section--brand .svc p { color: var(--on-dark-muted); }

/* --- indice dei servizi in home: NON ripete le schede della pagina Servizi -------------------
   Sul sito attuale del cliente la home ERA l'indice dei servizi e il testo stava nelle pagine di
   dettaglio. Qui la home elenca, la pagina Servizi descrive: ogni voce va DIRITTA alla sua ancora,
   mai a un hub intermedio identico (regola 12). */
.svc-index { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); }
/* ⚠ La riga della griglia si dimensiona sulla voce più alta: senza `height:100%` sul link, una voce
   che va a capo lascia le sorelle più corte e la riga si legge sfilacciata. */
.svc-index li { display: flex; }
.svc-index a { height: 100%; }
.svc-index a {
  display: flex; align-items: center; gap: var(--space-3); min-height: 56px;
  padding: var(--space-3) var(--space-4);
  background: var(--paper); border: var(--border); border-left: 3px solid var(--brand);
  border-radius: var(--radius); font-family: var(--font-accent); font-weight: 600; font-size: 0.95rem;
}
.svc-index a::after { content: "→"; margin-left: auto; color: var(--accent-ink); }
.svc-index a:hover { border-left-color: var(--accent); color: var(--brand); }
@media (max-width: 1100px) { .svc-index { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .svc-index { grid-template-columns: 1fr; } }

/* --- fascia testo + foto -------------------------------------------------------------------- */
.split { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: clamp(2rem, 4vw, 3.5rem); align-items: center; }
.split--flip .split__media { order: -1; }
.split__media img { width: 100%; aspect-ratio: var(--tile-ratio); object-fit: cover; border-radius: var(--radius); }
.split .btn { margin-top: var(--space-5); }

/* --- banda di fotografie con didascalia SOTTO ----------------------------------------------- */
.band-photos { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); margin-top: var(--space-7); }
.band-photos figure { margin: 0; }
.band-photos img { width: 100%; aspect-ratio: var(--band-ratio); object-fit: cover; border-radius: var(--radius); }
.band-photos figcaption { font-size: 0.88rem; color: var(--ink-muted); padding-top: var(--space-2); }
.section--brand .band-photos figcaption { color: var(--on-dark-muted); }

/* --- certificazioni ------------------------------------------------------------------------- */
.certs { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.cert { border: var(--border); border-radius: var(--radius); padding: var(--space-4) var(--space-5); background: var(--paper); }
.cert b { font-family: var(--font-accent); font-size: 1.05rem; color: var(--brand); display: block; }
.cert span { font-size: 0.9rem; color: var(--ink-muted); }
.cert a { color: var(--accent-ink); font-weight: 600; font-size: 0.9rem; }

/* --- elenco puntato con segno di marca ------------------------------------------------------ */
.checks { display: grid; gap: var(--space-3); margin-top: var(--space-5); }
.checks li { position: relative; padding-left: var(--space-6); }
.checks li::before { content: ""; position: absolute; left: 0; top: 0.62em; width: 12px; height: 3px; background: var(--accent); }
.section--brand .checks li::before { background: var(--sage-light); }

/* --- banda contatti + piè -------------------------------------------------------------------- */
.contact-band { background: var(--grad-brand); color: var(--on-dark); --fg: var(--on-dark); --focus: var(--on-dark); padding-block: var(--section-y);  --line-strong: rgba(255,255,255,.65);
}
.contact-band__row { display: grid; grid-template-columns: 1.2fr auto; gap: var(--space-6); align-items: center; }
.contact-band h2 { color: var(--on-dark); }
.contact-band p { color: var(--on-dark-muted); max-width: 38rem; }

.contact-cols { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 4vw, 3.5rem); }
/* La scheda non si STIRA sull'altezza della colonna del modulo: resterebbe mezza vuota. */
.contact-card { align-self: start; background: var(--surface); border: var(--border); border-radius: var(--radius); padding: var(--space-6); }
.contact-card dt { font-family: var(--font-accent); font-weight: 700; font-size: 0.82rem; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-muted); }
.contact-card dd { margin: 0 0 var(--space-4); }
.contact-card a { color: var(--brand); }
/* ⚠ Ogni riga d'orario sono DUE span adiacenti: senza separatore rendono «Lun–Ven09:00–13:00». */
.hours { display: grid; gap: var(--space-1); }
.hours li { display: flex; justify-content: space-between; gap: var(--space-4); }
.site-footer .hours li { justify-content: flex-start; }
.site-footer .hours li span:first-child { min-width: 5.5em; }

.site-footer { background: var(--brand-dark); color: var(--on-dark-muted); padding-block: var(--space-8) var(--space-6); font-size: 0.93rem; }
.site-footer__col > p { margin-bottom: var(--space-3); }
.wordmark--logo .wordmark__txt { font-size: var(--text-base); }
.site-footer__cols { display: grid; grid-template-columns: 1.3fr 1fr 1fr 1fr; gap: var(--space-6); }
.site-footer h3 { font-family: var(--font-accent); color: var(--on-dark); font-size: 0.95rem; letter-spacing: 0.06em; text-transform: uppercase; margin: 0 0 var(--space-3); }
.site-footer a:hover { color: var(--on-dark); text-decoration: underline; }
.site-footer ul { display: grid; gap: var(--space-2); }
/* Tre celle `1fr auto 1fr`: solo cosi' il «Powered by» cade DAVVERO a meta'; con space-between cade «circa». */
.site-footer__legal { border-top: 1px solid rgba(255,255,255,.16); margin-top: var(--space-7); padding-top: var(--space-5); display: grid; grid-template-columns: 1fr auto 1fr; gap: var(--space-4); align-items: center; font-size: 0.85rem; }
.site-footer__legal > :last-child { justify-self: end; }
.powered { display: inline-flex; align-items: center; gap: var(--space-1); justify-self: center; }
.powered img { width: 20px; height: 20px; }

/* --- pagina 404 ------------------------------------------------------------------------------ */
.notfound { padding-block: var(--space-10); text-align: center; background: var(--grad-tint); }
.notfound h1 { color: var(--brand-dark); }

/* --- barra CTA mobile ------------------------------------------------------------------------ */
.cta-bar { display: none; }
@media (max-width: 900px) {
  .header-tel, .site-header__cta { display: none; }
  /* ⚠ La riga di testata non si stringeva: `.wordmark` e' `flex:none` e porta la sottoriga con la
     categoria, che e' lunga. Il risultato era il tasto hamburger spinto FUORI dal viewport (417px su
     390) — overflow orizzontale su TUTTE le pagine. La sottoriga e' decorativa: sotto i 900 sparisce,
     e il marchio torna a poter cedere spazio. */
  .wordmark { min-width: 0; }
  .wordmark__tag { display: none; }
  .site-header__row { gap: var(--space-3); }
  .topics { grid-template-columns: repeat(2, 1fr); }
  .svc-grid, .certs, .band-photos, .site-footer__cols { grid-template-columns: repeat(2, 1fr); }
  .split, .contact-cols, .contact-band__row { grid-template-columns: 1fr; }
  .split--flip .split__media { order: 0; }
  .site-footer__legal { grid-template-columns: 1fr; justify-items: center; text-align: center; }
  .site-footer__legal > :last-child { justify-self: center; }
  body { padding-bottom: 78px; }
  .cta-bar {
    display: flex; gap: var(--space-2); position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
    padding: var(--space-2) var(--space-3); background: var(--paper); border-top: 1px solid var(--line);
  }
  /* ⚠⚠ Il block-gap di WP cade sul SECONDO figlio e sfalsa i tasti di 24px esatti: si azzera QUI.
     `flex: 1 1 0` li rende una coppia vera, stessa larghezza e stessa altezza. */
  .cta-bar > * { margin-block: 0; flex: 1 1 0; }
}
@media (max-width: 560px) {
  .topics, .svc-grid, .certs, .band-photos, .site-footer__cols { grid-template-columns: 1fr; }
}

/* --- modulo di contatto (segnaposto statico finche' il progetto non dichiara form.json) ------ */
.contact-form { display: grid; gap: var(--space-4); margin: var(--space-6) 0 var(--space-5); }
/* ⚠⚠ Solo i paragrafi-CAMPO: l'avviso del modulo spento viene inserito DENTRO il <form>, e con una
   regola su tutti i `p` diventava una griglia che mandava a capo ogni link e ogni frammento di testo
   («scrivici a» / «info@…» / «, su» / «WhatsApp» su righe separate). */
.contact-form > p:not(.avviso) { display: grid; gap: var(--space-2); margin: 0; }
.contact-form label { font-family: var(--font-accent); font-weight: 600; font-size: 0.88rem; color: var(--ink-muted); }
/* ⚠ Il bordo di un CONTROLLO vuole 3.0 su bianco (SC 1.4.11): --line (1.63) e' un filetto decorativo
   e qui lascerebbe campi quasi invisibili. Si usa --line-strong (3.46). */
.contact-form input, .contact-form textarea {
  font: inherit; color: var(--ink); background: var(--paper);
  border: 1px solid var(--line-strong); border-radius: var(--field-radius);
  padding: var(--space-3); width: 100%; min-height: 48px;
}
.contact-form textarea { min-height: 120px; resize: vertical; }
.contact-form input:focus-visible, .contact-form textarea:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
/* L'avviso del modulo spento: dichiarato, non nascosto. */
.avviso { background: var(--sage-tint); border-left: 3px solid var(--accent); padding: var(--space-3) var(--space-4); margin: 0 0 var(--space-4); font-size: 0.95rem; }

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   MODERNITÀ — giro di design 2026. Il sito era statico e pieno di vuoti: sei pagine su undici
   avevano copertura fotografica ZERO e nessuna immagine superava il 18% del viewport.
   Qui entrano i device che riempiono senza gonfiare: testate fotografiche, bande a tutta larghezza,
   mosaici editoriali, e — dove una foto non c'è — un GIOCO DI COLORE invece del bianco.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

/* --- superfici che non restano mai spoglie ---------------------------------------------------- */
/* ⚠ Nessuno di questi gradienti porta testo da solo: il contrasto resta quello del colore di base. */
.section--mesh {
  background:
    radial-gradient(60% 80% at 8% 0%, rgba(40,72,149,.10) 0%, rgba(40,72,149,0) 60%),
    radial-gradient(50% 70% at 96% 12%, rgba(228,41,39,.07) 0%, rgba(228,41,39,0) 62%),
    radial-gradient(80% 60% at 50% 100%, rgba(86,104,143,.10) 0%, rgba(86,104,143,0) 70%),
    var(--paper);
}
.section--mesh-deep {
  background:
    radial-gradient(55% 75% at 0% 0%, rgba(58,93,168,.55) 0%, rgba(58,93,168,0) 58%),
    radial-gradient(60% 80% at 100% 100%, rgba(228,41,39,.20) 0%, rgba(228,41,39,0) 60%),
    var(--brand-dark);
  color: var(--on-dark); --fg: var(--on-dark); --focus: var(--on-dark);
 --line-strong: rgba(255,255,255,.65);
}
.section--mesh-deep h2, .section--mesh-deep h3 { color: var(--on-dark); }
.section--mesh-deep p { color: var(--on-dark-muted); }
/* Reticolo sottilissimo: dà MATERIA a una banda che non ha fotografia. */
.section--grid-lines { position: relative; isolation: isolate; }
.section--grid-lines::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: linear-gradient(var(--line) 1px, transparent 1px), linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size: 64px 64px; opacity: .35;
  mask-image: radial-gradient(70% 60% at 50% 40%, #000 0%, transparent 78%);
}

/* --- testata di pagina CON FOTOGRAFIA (full-bleed) -------------------------------------------- */
.page-head--photo {
  position: relative; isolation: isolate; border-bottom: 0;
  min-height: clamp(300px, 34vw, 440px); display: grid; align-items: end;
  padding-block: clamp(2.5rem, 5vw, 4rem); background: var(--brand-dark);
}
.page-head--photo .page-head__bg {
  position: absolute; inset: 0; z-index: -2; overflow: hidden;
}
.page-head--photo .page-head__bg img { width: 100%; height: 100%; object-fit: cover; }
.page-head--photo::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(100deg, rgba(11,20,40,.92) 0%, rgba(11,20,40,.74) 48%, rgba(11,20,40,.36) 100%);
}
.page-head--photo h1 { color: var(--on-dark); max-width: 20ch; }
.page-head--photo .lead { color: var(--on-dark-muted); }
.page-head--photo .eyebrow { color: var(--on-dark); }

/* --- banda fotografica a TUTTA LARGHEZZA, con parallasse leggera ------------------------------ */
.band-wide { position: relative; isolation: isolate; overflow: clip; min-height: clamp(320px, 40vw, 560px); display: grid; align-items: center; }
.band-wide__bg { position: absolute; inset: -12% 0; z-index: -2; }
.band-wide__bg img { width: 100%; height: 100%; object-fit: cover; }
.band-wide::after { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(92deg, rgba(11,20,40,.88) 0%, rgba(11,20,40,.62) 45%, rgba(11,20,40,.22) 100%); }
.band-wide__in { padding-block: clamp(3rem, 6vw, 5rem); color: var(--on-dark); }
.band-wide h2 { color: var(--on-dark); max-width: 18ch; }
.band-wide p { color: var(--on-dark-muted); max-width: 42rem; }
.band-wide .eyebrow { color: var(--sage-light); }

/* --- mosaico editoriale: tessere di misura DIVERSA, non una griglia piatta -------------------- */
.mosaic { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--space-4); }
.mosaic figure { margin: 0; position: relative; overflow: hidden; border-radius: var(--radius); }
.mosaic img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 1.1s var(--ease); }
.mosaic figure:hover img { transform: scale(1.05); }
.mosaic figcaption {
  position: absolute; inset-inline: 0; bottom: 0; padding: var(--space-5) var(--space-4) var(--space-3);
  color: var(--on-dark); font-size: .88rem; line-height: 1.35;
  background: linear-gradient(180deg, rgba(11,20,40,0) 0%, rgba(11,20,40,.82) 62%);
}
/* ⚠⚠ Le misure sono CALCOLATE, non scelte a occhio: su un contenitore da 1220 a sei colonne con vuoti
   da 16, una tessera a 3 colonne rende 602px — e a 16/9 fa 204k px², SOTTO la soglia di «immagine
   grande» (233k a 1440x900). A 4/3 fa 272k e la supera. Un mosaico di tessere tutte sotto soglia si
   legge come un francobollario: qui ogni tessera è un'immagine che si vede davvero. */
.mosaic .m-hero { grid-column: span 6; aspect-ratio: 21 / 9; }
.mosaic .m-lead { grid-column: span 4; aspect-ratio: 16 / 9; }
.mosaic .m-tall { grid-column: span 3; aspect-ratio: 3 / 4; }
.mosaic .m-wide { grid-column: span 3; aspect-ratio: 4 / 3; }
.mosaic .m-sq   { grid-column: span 3; aspect-ratio: 1; }
/* ⚠ Sotto i 901 le aree non valgono e si torna al flusso: se pero' le tessere hanno campate DIVERSE
   (2 e 1), la sequenza apre di nuovo mezze righe vuote — sul telefono si vedevano tre buchi nella
   sola fascia degli interventi. Da 601 a 900 tutte le tessere valgono UNA campata su due colonne;
   sotto i 600 la colonna e' unica e il ritmo lo danno i RAPPORTI, non le larghezze. */
/* ⚠⚠ Le campate della tessera (`.mosaic .m-hero`, 0-2-0) battono un `> figure` piatto (0-1-1): senza
   il selettore di TIPO restavano `span 6` dentro una griglia a una colonna, e la griglia generava
   cinque colonne IMPLICITE larghe 0 — misurato: tessere da 32px, cioe' francobolli. */
@media (min-width: 601px) and (max-width: 900px) {
  .mosaic { grid-template-columns: repeat(2, 1fr); }
  .mosaic > figure.m-hero, .mosaic > figure.m-lead, .mosaic > figure.m-wide,
  .mosaic > figure.m-tall, .mosaic > figure.m-sq { grid-column: span 1; aspect-ratio: 4 / 3; }
  /* Tre o cinque tessere su due colonne: l'ultima resterebbe sola a mezza riga. */
  .mosaic.mosaic--3 > figure:last-child,
  .mosaic.mosaic--5 > figure:last-child { grid-column: span 2; aspect-ratio: 16 / 10; }
}
@media (max-width: 600px) {
  .mosaic { grid-template-columns: 1fr; }
  .mosaic > figure.m-hero, .mosaic > figure.m-lead, .mosaic > figure.m-wide { grid-column: span 1; aspect-ratio: 16 / 10; }
  .mosaic > figure.m-tall { grid-column: span 1; aspect-ratio: 4 / 5; }
  .mosaic > figure.m-sq { grid-column: span 1; aspect-ratio: 1; }
}

/* --- figura che SCAVALCA il confine fra due bande --------------------------------------------- */
/* ⚠ Per uno scavalco servono DUE condizioni: margine negativo maggiore del padding di fine sezione
   E la sezione successiva che non dipinga sopra — quindi si alza la SEZIONE, non il figlio. */
.section--overlap { position: relative; z-index: 2; }
.figure-offset { margin-block-end: calc(var(--section-y) * -0.45); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-md); }
.figure-offset img { width: 100%; display: block; }

/* --- numeri e fatti: struttura senza foto ----------------------------------------------------- */
.facts { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-5); }
/* ⚠ Le didascalie devono stare sulla STESSA riga anche quando l'etichetta sopra va a capo: senza,
   «nei servizi ecologici» scende di una riga rispetto a «automezzi in flotta» e la fascia si legge
   storta. La cella e' gia' alta quanto la riga: la didascalia si appoggia in fondo. */
.fact { padding: var(--space-5) 0; border-top: 2px solid var(--accent); display: flex; flex-direction: column; }
.fact span { margin-top: auto; padding-top: var(--space-2); }
.fact b { display: block; font-family: var(--font-accent); font-size: clamp(1.6rem, 1.1rem + 1.6vw, 2.4rem); font-weight: 800; color: var(--brand); line-height: 1.05; }
.fact span { font-size: .92rem; color: var(--ink-muted); }
.section--mesh-deep .fact { border-top-color: var(--sage-light); }
.section--mesh-deep .fact b { color: var(--on-dark); }
.section--mesh-deep .fact span { color: var(--on-dark-muted); }
@media (max-width: 900px) { .facts { grid-template-columns: repeat(2, 1fr); } }

/* --- varianti di composizione usate dalle pagine ---------------------------------------------- */
.split--tight { gap: clamp(1.5rem, 3vw, 2.5rem); align-items: start; }

/* --- HERO: più alta, con Ken Burns lento. Il movimento è l'unico della pagina above-the-fold. -- */
.hero { min-height: clamp(560px, 76vh, 820px); }
.hero__slide { animation: fp-hero-fade 27s infinite, fp-kenburns 27s infinite; transform-origin: 50% 55%; }
@keyframes fp-kenburns { 0% { transform: scale(1.06); } 100% { transform: scale(1.14); } }
.hero__in { padding-block: clamp(3rem, 7vw, 6rem); }
/* Filo rosso che percorre il bordo basso della testata: un segno, non un ornamento. */
.hero::before {
  content: ""; position: absolute; left: 0; bottom: 0; height: 4px; width: 100%; z-index: 1;
  background: linear-gradient(90deg, var(--accent) 0%, var(--accent) 22%, rgba(228,41,39,0) 22%);
}
/* ⚠⚠ DIFETTO VERO, non di cattura: le slide nascono a `opacity: 0` ed e' l'ANIMAZIONE ad accenderle.
   Spegnendo l'animazione per chi chiede meno movimento restavano tutte e tre invisibili, e l'hero
   diventava una fascia di colore VUOTA — esattamente il vuoto segnalato dall'owner. Chi riduce il
   movimento deve vedere UNA fotografia ferma, non il nulla. */
@media (prefers-reduced-motion: reduce) {
  .hero__slide { animation: none; transform: none; }
  .hero__slide:nth-child(1) { opacity: 1; }
  .hero__slide:nth-child(n + 2) { display: none; }
}

/* ══ ITERAZIONE 2 — colore VARIO e immagine INCHIODATA ═══════════════════════════════════════════
   ⚠ Le campiture si contano per STRINGA: ripetere lo stesso mesh su sei bande dà UNA superficie sola,
   e infatti il conteggio era sceso. Qui ogni variante ha una sua composizione — e si vede. */
.section--mesh-b {
  background:
    radial-gradient(46% 62% at 92% 4%, rgba(228,41,39,.09) 0%, rgba(228,41,39,0) 62%),
    radial-gradient(70% 52% at 6% 86%, rgba(40,72,149,.12) 0%, rgba(40,72,149,0) 66%),
    linear-gradient(178deg, var(--surface) 0%, var(--paper) 68%);
}
.section--mesh-c {
  background:
    conic-gradient(from 220deg at 12% 8%, rgba(40,72,149,.11) 0deg, rgba(40,72,149,0) 120deg),
    radial-gradient(58% 70% at 88% 92%, rgba(86,104,143,.14) 0%, rgba(86,104,143,0) 64%),
    var(--sage-tint);
}
.section--mesh-warm {
  background:
    radial-gradient(64% 74% at 78% 0%, rgba(228,41,39,.10) 0%, rgba(228,41,39,0) 58%),
    radial-gradient(52% 64% at 10% 96%, rgba(184,29,27,.08) 0%, rgba(184,29,27,0) 62%),
    linear-gradient(166deg, var(--paper) 0%, #FBF6F6 100%);
}
.section--steel {
  background: linear-gradient(172deg, var(--sage-tint) 0%, #DDE6F4 55%, var(--surface) 100%);
}
.section--mesh-night {
  background:
    radial-gradient(48% 66% at 84% 6%, rgba(58,93,168,.62) 0%, rgba(58,93,168,0) 60%),
    radial-gradient(66% 58% at 6% 94%, rgba(228,41,39,.16) 0%, rgba(228,41,39,0) 58%),
    linear-gradient(158deg, #1B3C7A 0%, var(--brand-dark) 100%);
  color: var(--on-dark); --fg: var(--on-dark); --focus: var(--on-dark);
 --line-strong: rgba(255,255,255,.65);
}
.section--mesh-night h2, .section--mesh-night h3 { color: var(--on-dark); }
.section--mesh-night p { color: var(--on-dark-muted); }

/* --- L'IMMAGINE INCHIODATA: la fotografia resta ferma e la pagina le passa davanti. -------------
   ⚠ Niente `background-attachment: fixed` (su iOS non si muove e scatta). Il `clip-path` su un
   antenato àncora i figli `fixed` a QUEL riquadro: l'effetto è vero, senza una riga di JS.
   Sotto i 900 e con reduced-motion si torna a una foto normale: su mobile il fixed è instabile. */
[data-parallax] { position: relative; overflow: clip; clip-path: inset(0); }
[data-parallax] > .band-wide__bg,
[data-parallax] > .page-head__bg { position: absolute; inset: 0; }
@media (min-width: 901px) and (prefers-reduced-motion: no-preference) {
  [data-parallax] > .band-wide__bg img,
  [data-parallax] > .page-head__bg img {
    position: fixed; inset: 0; width: 100vw; height: 100vh; object-fit: cover;
  }
}

/* --- entrate DIVERSE: un sito che si rivela sempre allo stesso modo sembra un foglio che scorre --- */
.js .reveal--left  { opacity: 0; transform: translateX(-28px); }
.js .reveal--right { opacity: 0; transform: translateX(28px); }
.js .reveal--scale { opacity: 0; transform: scale(.94); }
.js .reveal--left.is-visible, .js .reveal--right.is-visible, .js .reveal--scale.is-visible {
  opacity: 1; transform: none;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
  transition-delay: calc(var(--reveal-i, 0) * 70ms);
}
@media (prefers-reduced-motion: reduce) {
  .js .reveal--left, .js .reveal--right, .js .reveal--scale,
  .js .reveal--left.is-visible, .js .reveal--right.is-visible, .js .reveal--scale.is-visible { opacity: 1; transform: none; transition: none; }
}

/* --- lo scaglionamento si dichiara sul CONTENITORE: ogni figlio entra col proprio ritardo -------- */
[data-stagger] > * { --reveal-i: 0; }
[data-stagger] > *:nth-child(2) { --reveal-i: 1; }
[data-stagger] > *:nth-child(3) { --reveal-i: 2; }
[data-stagger] > *:nth-child(4) { --reveal-i: 3; }
[data-stagger] > *:nth-child(5) { --reveal-i: 4; }
[data-stagger] > *:nth-child(6) { --reveal-i: 5; }
[data-stagger] > *:nth-child(7) { --reveal-i: 6; }
[data-stagger] > *:nth-child(8) { --reveal-i: 7; }

/* ══ ITERAZIONE 3 — la scheda di servizio porta la propria fotografia ═════════════════════════ */
.svc--photo { padding: 0; overflow: hidden; border-left-width: 3px; display: flex; flex-direction: column; }
.svc--photo .svc__media { aspect-ratio: 3 / 2; overflow: hidden; background: var(--surface); }
.svc--photo .svc__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.1s var(--ease); }
.svc--photo:hover .svc__media img { transform: scale(1.06); }
.svc--photo .svc__body { padding: var(--space-4) var(--space-5) var(--space-5); flex: 1; }
.svc--photo h3 { margin-bottom: var(--space-2); color: var(--brand); }

/* ══ ITERAZIONE 5 — i dettagli che separano un sito «fatto» da uno CURATO ═══════════════════════ */

/* Il numero d'indice di sezione e' stato RIMOSSO su richiesta owner: pesava sul titolo nelle colonne
   strette e nell'indice faceva a pugni con la numerazione della lista. */
.section-intro { position: relative; }

/* --- blocco-dichiarazione: una frase sola, grande, che fa respirare la pagina ------------------ */
.statement { padding-block: clamp(4rem, 8vw, 7rem); }
.statement p {
  font-family: var(--font-accent); font-weight: 700;
  font-size: clamp(1.6rem, 1rem + 2.6vw, 3.1rem); line-height: 1.14;
  letter-spacing: -.015em; max-width: 20ch; margin: 0; color: var(--brand-dark);
  text-wrap: balance;
}
.statement .statement__mark { display: block; width: 64px; height: 4px; background: var(--accent); margin-bottom: var(--space-6); }
.section--mesh-deep .statement p, .section--mesh-night .statement p { color: var(--on-dark); }

/* --- filo verticale che accompagna la lettura di una colonna lunga ---------------------------- */
.rail { position: relative; padding-left: var(--space-7); }
.rail::before { content: ""; position: absolute; left: 0; top: .35em; bottom: .35em; width: 2px; background: linear-gradient(180deg, var(--accent) 0%, var(--sage-light) 45%, transparent 100%); }

/* --- la fotografia che scavalca il confine fra due bande -------------------------------------- */
/* ⚠ Non basta il margine negativo: serve anche che la banda SUCCESSIVA non dipinga sopra, e per
   questo si alza la SEZIONE (z-index sul contesto di impilamento), non la figura. */
.split__media--overlap { position: relative; z-index: 2; margin-block-end: calc(var(--section-y) * -0.4); box-shadow: var(--shadow-md); border-radius: var(--radius); overflow: hidden; }
@media (max-width: 900px) { .split__media--overlap { margin-block-end: 0; } }

/* --- didascalia a filo, discreta --------------------------------------------------------------- */
.mosaic figcaption { font-family: var(--font-body); letter-spacing: .01em; }
.mosaic figure::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 3px; background: var(--accent);
  transform: scaleX(0); transform-origin: 0 50%; transition: transform .5s var(--ease);
}
.mosaic figure:hover::after { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) { .mosaic figure::after { display: none; } }

/* ══ ITERAZIONE 6 — ogni banda una campitura PROPRIA, e il finale che non resta bianco ══════════ */
/* ⚠ Le campiture si contano per stringa: due bande con la stessa classe valgono UNA sola superficie.
   Qui le sezioni «nude» di una pagina prendono a turno una velatura diversa, con `:nth-of-type`,
   cosi' nessuna pagina ripete la stessa campitura due volte di fila. */
.section:not([class*="--mesh"]):not([class*="--steel"]):not(.band-wide):nth-of-type(3n+1) {
  background: linear-gradient(184deg, var(--paper) 0%, #FAFCFE 100%);
}
.section:not([class*="--mesh"]):not([class*="--steel"]):not(.band-wide):nth-of-type(3n+2) {
  background: radial-gradient(72% 58% at 96% 8%, rgba(86,104,143,.07) 0%, rgba(86,104,143,0) 62%), var(--paper);
}
.section:not([class*="--mesh"]):not([class*="--steel"]):not(.band-wide):nth-of-type(3n) {
  background: radial-gradient(64% 66% at 4% 94%, rgba(228,41,39,.05) 0%, rgba(228,41,39,0) 58%), var(--paper);
}
/* Il piè non è un rettangolo piatto: prende la stessa materia delle bande profonde. */
.site-footer {
  background:
    radial-gradient(52% 70% at 88% 0%, rgba(58,93,168,.40) 0%, rgba(58,93,168,0) 62%),
    radial-gradient(60% 56% at 4% 100%, rgba(228,41,39,.14) 0%, rgba(228,41,39,0) 58%),
    var(--brand-dark);
}
/* La barra di servizio in cima prende un filo di marca. */
.topbar { background: linear-gradient(90deg, var(--brand-dark) 0%, #1B3C7A 58%, var(--brand-dark) 100%); }

/* ══ ITERAZIONE 7 — la composizione non lascia BUCHI, e la colonna corta non lascia il vuoto ═════
   Guardando le pagine (non il punteggio): il mosaico a flusso automatico apriva rettangoli vuoti —
   una tessera 3/4 accanto a una 4/3 lascia 350px di niente, e l'ultima riga restava mezza scoperta;
   la colonna di testo della flotta finiva a meta' del mosaico; il sottotitolo toccava il titolo.
   Qui le tessere si posano su AREE dichiarate: ogni cella e' occupata per costruzione. */

/* --- mosaico ad aree: nessuna cella resta scoperta -------------------------------------------- */
@media (min-width: 901px) {
  .mosaic--2, .mosaic--3, .mosaic--4, .mosaic--5, .mosaic--6 { grid-template-columns: repeat(6, 1fr); }
  /* Due tessere: una riga sola, tagliata 4/2 perche' due meta' uguali sono una tabella, non una composizione. */
  .mosaic--2 { grid-template-areas: "a a a a b b"; grid-template-rows: clamp(260px, 28vw, 400px); }
  .mosaic--6 {
    grid-template-areas: "a a a a a a" "b b b c c c" "d d e e f f";
    grid-template-rows: clamp(260px, 29vw, 440px) clamp(280px, 31vw, 460px) clamp(210px, 23vw, 340px);
  }
  .mosaic--5 {
    grid-template-areas: "a a a a a a" "b b c c c c" "d d d d e e";
    grid-template-rows: clamp(260px, 29vw, 440px) clamp(240px, 26vw, 380px) clamp(240px, 26vw, 380px);
  }
  .mosaic--4 {
    grid-template-areas: "a a a a b b" "c c d d d d";
    grid-template-rows: clamp(250px, 27vw, 400px) clamp(250px, 27vw, 400px);
  }
  /* Tre tessere: due fasce a sinistra e una colonna alta a destra, che tiene le due righe. */
  .mosaic--3 {
    grid-template-areas: "a a a a b b" "c c c c b b";
    grid-template-rows: clamp(190px, 20vw, 290px) clamp(190px, 20vw, 290px);
  }
  /* ⚠ L'area VINCE sullo span di colonna solo se la regola pesa di piu': `.mosaic .m-hero` e
     `.mosaic--6 > *:nth-child(1)` pesano uguale, e in parita' deciderebbe l'ordine nel file. Il
     selettore di TIPO (`figure`) aggiunge lo scalino che rende la posa indipendente dall'ordine. */
  .mosaic--2 > figure:nth-child(1), .mosaic--3 > figure:nth-child(1), .mosaic--4 > figure:nth-child(1),
  .mosaic--5 > figure:nth-child(1), .mosaic--6 > figure:nth-child(1) { grid-area: a; }
  .mosaic--2 > figure:nth-child(2), .mosaic--3 > figure:nth-child(2), .mosaic--4 > figure:nth-child(2),
  .mosaic--5 > figure:nth-child(2), .mosaic--6 > figure:nth-child(2) { grid-area: b; }
  .mosaic--3 > figure:nth-child(3), .mosaic--4 > figure:nth-child(3),
  .mosaic--5 > figure:nth-child(3), .mosaic--6 > figure:nth-child(3) { grid-area: c; }
  .mosaic--4 > figure:nth-child(4),
  .mosaic--5 > figure:nth-child(4), .mosaic--6 > figure:nth-child(4) { grid-area: d; }
  .mosaic--5 > figure:nth-child(5), .mosaic--6 > figure:nth-child(5) { grid-area: e; }
  .mosaic--6 > figure:nth-child(6) { grid-area: f; }
  /* ⚠ Una tessera stirata dall'area conserverebbe il proprio `aspect-ratio` e resterebbe PIU' STRETTA
     della cella (misurato: 974px dentro una cella da 1220). Il rapporto si spegne e la fotografia
     riempie — cover ritaglia, non deforma. La classe si ripete perche' `.mosaic .m-hero` pesa (0,2,0)
     e batterebbe un `> figure` piatto (0,1,1). */
  .mosaic.mosaic--2 > figure, .mosaic.mosaic--3 > figure, .mosaic.mosaic--4 > figure,
  .mosaic.mosaic--5 > figure, .mosaic.mosaic--6 > figure { aspect-ratio: auto; height: 100%; }
}

/* --- la colonna corta accompagna quella lunga invece di finire nel vuoto ---------------------- */
/* La lastra di testo resta ferma e le fotografie le scorrono accanto: e' il «fermo mentre la pagina
   passa» chiesto dall'owner, ottenuto con lo sticky, che non costa una riga di JS ne' un reflow. */
@media (min-width: 901px) {
  /* ⚠ Sotto la testata FISSA, non al bordo del viewport: altrimenti la colonna ci scivola sotto. */
  .split--sticky > *:first-child { position: sticky; top: calc(var(--header-h) + var(--space-5)); align-self: start; }
}

/* --- il sottotitolo non tocca il titolo -------------------------------------------------------- */
/* ⚠ `* { margin: 0 }` del reset azzera tutto e il block-gap di WP non entra dentro i blocchi HTML:
   senza questa regola occhiello, titolo e lead restano incollati (si vede in ogni testata). */
h1 + .lead, h2 + .lead, h1 + .prose, h2 + .prose, h2 + .certs { margin-top: var(--space-4); }
.section-intro .lead { margin-top: var(--space-4); }

/* --- indice dei servizi: un indice EDITORIALE, non otto pastiglie sparse ---------------------- */
/* Le pastiglie lasciavano meta' banda bianca a destra del titolo e righe di altezza diversa. */
.split--index { grid-template-columns: 0.82fr 1.18fr; align-items: start; }
.split--index .section-intro { margin-bottom: 0; }
.svc-index--rows { counter-reset: svc; grid-template-columns: repeat(2, 1fr); gap: 0 var(--space-7); }
.svc-index--rows li { display: block; counter-increment: svc; }
.svc-index--rows a {
  display: flex; align-items: baseline; gap: var(--space-4); min-height: 0; height: auto;
  padding: var(--space-4) 0; background: none; border: 0; border-bottom: 1px solid var(--line);
  border-radius: 0; font-size: 1.06rem; font-weight: 600; color: var(--brand-dark);
}
.svc-index--rows a::before {
  content: counter(svc, decimal-leading-zero);
  font-family: var(--font-accent); font-size: .74rem; font-weight: 700;
  letter-spacing: var(--tracking-label); color: var(--accent-ink);
}
.svc-index--rows a::after { transition: transform .35s var(--ease); }
.svc-index--rows a:hover { border-bottom-color: var(--accent); color: var(--brand); }
.svc-index--rows a:hover::after { transform: translateX(6px); }
@media (prefers-reduced-motion: reduce) { .svc-index--rows a::after { transition: none; } }
@media (max-width: 1100px) { .svc-index--rows { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 700px) { .svc-index--rows { grid-template-columns: 1fr; } }

/* --- certificazioni: la lastra alta a sinistra, le sei schede accanto ------------------------- */
/* Prima la colonna di destra portava solo tre righe di testo e restava vuota per 300px accanto a
   una fotografia alta. Le schede salgono ACCANTO alla lastra: nessuna delle due resta scoperta. */
.split--certs { grid-template-columns: 0.86fr 1.14fr; align-items: start; }
.split--certs .split__media { margin: 0; }
.split--certs .split__media img { width: 100%; height: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.certs--two { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 900px) {
  .split--index, .split--certs { grid-template-columns: 1fr; }
  .split--certs .split__media img { aspect-ratio: var(--band-ratio); }
  .certs--two { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) { .certs--two { grid-template-columns: 1fr; } }

/* --- il QUADRO: il testo e' una TESSERA della griglia, non una colonna che finisce a meta' -------
   La colonna di testo era alta 460px accanto a un mosaico di 1100: sotto le quattro voci restavano
   700px di niente. Qui il blocco di testo occupa una cella come le fotografie, e la composizione si
   chiude da sola: nessuna cella scoperta, nessuna colonna orfana. */
.quadro { display: grid; gap: var(--space-4); }
.quadro figure { margin: 0; position: relative; overflow: hidden; border-radius: var(--radius); }
.quadro figure img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 1.1s var(--ease); }
.quadro figure:hover img { transform: scale(1.05); }
.quadro__txt { align-self: stretch; }
.quadro__txt .checks { margin-top: var(--space-5); }
/* ⚠ REGOLA OWNER: testo e fotografie ALLINEATI, mai il testo sopra e le immagini sotto in una colonna
   stretta. La prima riga parte dal testo (`minmax`: non scende sotto una misura minima ma cresce con
   il testo, cosi' la lastra accanto non resta mozza), e le fotografie che avanzano stanno AFFIANCATE
   nella riga sotto, a tutta larghezza. */
@media (min-width: 901px) {
  .quadro {
    grid-template-columns: repeat(6, 1fr);
    grid-template-rows: minmax(clamp(300px, 32vw, 440px), auto) clamp(230px, 25vw, 350px);
  }
  .quadro--1 { grid-template-areas: "t t t a a a"; grid-template-rows: minmax(clamp(300px, 32vw, 440px), auto); }
  .quadro--2 { grid-template-areas: "t t t a a a" "b b b b b b"; }
  .quadro--3 { grid-template-areas: "t t t a a a" "b b b c c c"; }
  .quadro--4 { grid-template-areas: "t t t a a a" "b b c c d d"; }
  .quadro--5 { grid-template-areas: "t t t a a a" "b b c c d d" "e e e e e e";
    grid-template-rows: minmax(clamp(300px, 32vw, 440px), auto) clamp(230px, 25vw, 350px) clamp(230px, 25vw, 350px); }
  .quadro > .quadro__txt { grid-area: t; }
  .quadro > figure:nth-of-type(1) { grid-area: a; }
  .quadro > figure:nth-of-type(2) { grid-area: b; }
  .quadro > figure:nth-of-type(3) { grid-area: c; }
  .quadro > figure:nth-of-type(4) { grid-area: d; }
  .quadro > figure:nth-of-type(5) { grid-area: e; }
}
/* ⚠ Sotto i 901 le aree non valgono e il quadro torna a flusso: con un numero DISPARI di fotografie
   l'ultima restava sola a mezza riga — lo stesso buco corretto sul mosaico. E a 390 due colonne fanno
   tessere da 163px: sul telefono la colonna è UNA sola. */
@media (min-width: 601px) and (max-width: 900px) {
  .quadro { grid-template-columns: repeat(2, 1fr); }
  .quadro__txt { grid-column: span 2; }
  .quadro figure { aspect-ratio: 4 / 3; }
  /* Numero DISPARI di fotografie: l'ultima prende tutta la riga, niente mezza riga scoperta. */
  .quadro--1 > figure, .quadro--3 > figure:last-of-type,
  .quadro--5 > figure:last-of-type { grid-column: span 2; aspect-ratio: 16 / 10; }
}
/* ⚠ La regola delle dispari vale SOLO da 601 in su: sotto, `span 2` (0,2,1) batterebbe un
   `> figure` piatto (0,1,1) e genererebbe una seconda colonna IMPLICITA — misurato: due colonne da
   167 e 159px dove ne serviva una sola. */
@media (max-width: 600px) {
  .quadro { grid-template-columns: 1fr; }
  .quadro__txt { grid-column: auto; }
  .quadro > figure { aspect-ratio: 16 / 10; }
}

/* --- il numero d'indice non deve finire SOTTO il titolo quando la colonna e' stretta ----------- */

/* ══ ITERAZIONE 8 — il ritmo della lettura e le composizioni dentro una colonna ═════════════════ */

/* ⚠ `* { margin: 0 }` toglie anche lo stacco fra due capoversi: misurato 22px, cioe' quanto
   un'interlinea — due paragrafi si leggevano come un blocco unico. La misura torna esplicita. */
.prose p + p, .band-wide__in p + p, .contact-band p + p { margin-top: var(--space-4); }
/* La fascia a tutta larghezza porta il corpo in `<p>` nudo, che la regola sul `.lead` non copriva. */
.band-wide__in h2 + p, .contact-band__row h2 + p, .statement + .prose { margin-top: var(--space-4); }

/* --- un mosaico DENTRO una colonna di split non ha la larghezza per sei campate ---------------- */
/* A meta' larghezza le aree a sei colonne producevano una tessera larga e una fettina di 2/6 che
   sembrava un ritaglio sbagliato: nella colonna le tessere si impilano, con altezze diverse. */
@media (min-width: 901px) {
  .split .mosaic--2, .split .mosaic--3 { grid-template-columns: 1fr; }
  .split .mosaic--2 { grid-template-areas: "a" "b"; grid-template-rows: clamp(220px, 24vw, 330px) clamp(170px, 18vw, 250px); }
  .split .mosaic--3 { grid-template-areas: "a" "b" "c"; grid-template-rows: repeat(3, clamp(150px, 16vw, 220px)); }
}

/* --- il blocco di testo del quadro e' una TESSERA: si appoggia su una lastra, non galleggia ----- */
.quadro__txt {
  background: linear-gradient(168deg, var(--paper) 0%, var(--surface) 100%);
  border-radius: var(--radius); padding: clamp(1.25rem, 2.4vw, 2.25rem);
  border: var(--border);
}

/* --- un blocco di solo testo prende TUTTA la banda, su due colonne ---------------------------- */
/* ⚠ REGOLA OWNER: mai una colonna di testo a sinistra con la meta' destra vuota. Vale anche quando
   la sezione HA fotografie ma il capoverso d'apertura sta da solo sopra di esse. */
.prose--due { max-width: none; columns: 2; column-gap: var(--space-8); }
.prose--due p { max-width: none; }
.prose--due p + p { margin-top: var(--space-4); }
@media (max-width: 860px) { .prose--due { columns: 1; } }

/* --- ordine anche alle larghezze intermedie ---------------------------------------------------- */
/* ⚠ A 1024 le voci dell'indice vanno a capo e la lista cresce: la colonna dell'introduzione restava
   162px più corta. Sotto i 1200 l'indice non è più affiancato: titolo sopra, elenco sotto a tutta
   larghezza. (Misurato con `qa/allineamento.mjs` a 1024 e a 1440.) */
@media (max-width: 1200px) {
  .split--index { grid-template-columns: 1fr; }
  .split--index .section-intro { margin-bottom: var(--space-6); }
}
/* La lastra delle certificazioni si allunga quanto le schede accanto invece di lasciare il vuoto:
   il rapporto 3/4 cede (`aspect-ratio: auto`), la fotografia riempie e `cover` ritaglia. */
.split--certs .split__media { align-self: stretch; }
.split--certs .split__media img { height: 100%; aspect-ratio: auto; min-height: clamp(340px, 38vw, 560px); }

/* --- il DUETTO: due blocchi di testo affiancati invece di due colonne mezze vuote --------------- */
/* ⭐ REGOLA OWNER: «qui si crea uno spazio brutto a destra». Il titolo di sezione e la dichiarazione
   stavano uno sotto l'altro, ciascuno largo metà banda: insieme lasciavano 599×486px di niente.
   Affiancati riempiono la banda e si leggono come un'apertura sola. */
/* ⚠ `stretch`, non `start`: se la colonna di sinistra è più alta, con `start` la destra finisce
   prima e sotto resta il vuoto — misurato 679×206px sulle certificazioni. */
.duetto { display: grid; gap: clamp(1.5rem, 3vw, 3rem); align-items: stretch; }
@media (min-width: 901px) {
  .duetto { grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); }
  .duetto .statement { padding-block: 0; }
}
.duetto .section-intro { margin-bottom: 0; }

/* --- la dichiarazione che sta da sola prende TUTTA la banda ------------------------------------ */
/* Una frase sola, grande, su due righe piene: è un device, non un paragrafo — la misura di lettura
   stretta qui lascerebbe mezza banda vuota. */
.statement--largo p { max-width: none; font-size: clamp(1.5rem, 0.9rem + 2.1vw, 2.6rem); }
/* Quattro numeri accanto a una dichiarazione: due per riga, non una fila che scende sotto. */
.facts--due { grid-template-columns: repeat(2, 1fr); }
