/* Design system webgas.net — palette e font presi dal sito WordPress esistente
   (giallo #ffd501, nero #0d0d0d, Montserrat + Open Sans) così la migrazione non
   cambia identità mentre cambia infrastruttura.

   Niente Tailwind: 6 template su ~130 pagine non giustificano un build step su
   un progetto che vive di "push e Pages serve la cartella". */

@import url('fonts.css');

:root {
  /* -- La scala dei titoli, una per tutto il sito (2026-09-29) -----------
     ⚠️ E' una DECISIONE, non una misura, e va saputo. `eroe.json` conserva
     la tipografia della fonte presa quando WordPress era vivo: 25 corpi
     diversi per l'`h1` su 190 pagine, da 19px a 198px, e altrettanti per i
     titoli di fascia. Non era sciatteria nostra, era proprio cosi'. Ora che
     la fonte e' spenta per sempre non c'e' piu' niente da copiare, e
     Giovanni ha chiesto una scala sola (2026-09-29).
     ⚠️ I numeri stanno QUI e in nessun altro posto: prima erano quaranta
     regole `font-size` sparse nel foglio, una per famiglia di pagine, che si
     contraddicevano a vicenda. Chi vuole cambiare la scala cambia queste due
     righe.
     ⚠️ NON tocca i titoli delle SCHEDE (`.card h2`, `.cs-testo-col h2`) ne'
     la filigrana decorativa ne' il foglio per la stampa: sono ruoli diversi,
     e uniformarli avrebbe appiattito la gerarchia invece di darle ordine. */
  --titolo-eroe: clamp(36px, 5.5vw, 72px);
  --titolo-fascia: clamp(24px, 2.6vw, 36px);
  /* ⚠️ Il terzo gradino, e serve: `.titolo-minore` e' l'occhiello che sta
     SOPRA un muro di loghi («I nostri partner:», «Abbiamo lavorato anche
     con»). Non e' un titolo di fascia e appiattirlo avrebbe tolto una
     gerarchia vera invece di dare ordine. Quello che si toglie e' la deriva:
     valeva 24px sulla home, 26 altrove e 30 su chi-siamo, cioe' tre numeri
     per lo stesso ruolo. */
  --titolo-minore: clamp(20px, 2.2vw, 26px);
  --yellow: #ffd501;
  /* ⚠️ NON è «il giallo che va bene sul chiaro»: #d9b400 su bianco dà 2,00:1,
     e nemmeno lui passa AA. Resta solo per fondi scuri o per bordi e riempimenti,
     MAI per testo su fondo chiaro — lì va `--ink`, come fa la produzione.
     Il 2026-08-22 un giudice l'ha ritrovato su `about-us` (6 occorrenze) e
     `work-with-us` (8): la variabile era stata corretta nel commento, non negli usi. */
  --yellow-deep: #d9b400;
  --ink: #0d0d0d;
  --ink-soft: #3a3a3a;
  --ink-faint: #6e6e6e;
  --ground: #ffffff;
  --ground-alt: #fafafa;
  --muro-cella: #f5f5f5;
  --rule: #e0e0e0;

  --display: 'Montserrat', system-ui, sans-serif;
  --body: 'Open Sans', system-ui, sans-serif;

  --measure: 68ch;
  --gutter: clamp(20px, 5vw, 64px);
}

/* ⚠️ NIENTE tema scuro automatico.
   webgas.net su WordPress non ha un tema scuro: le sezioni di contenuto sono
   bianche con testo nero, e solo l'eroe e alcune fasce sono nere per scelta
   editoriale. Finché questo file rispettava `prefers-color-scheme`, chi ha il
   Mac in modalità scura vedeva la versione statica in una palette che il sito
   originale non produce mai — bianco e nero invertiti sezione per sezione. È
   questa la ragione per cui il confronto blu/verde sembrava sbagliato nei
   colori e nell'alternanza: non era l'alternanza, era il tema.
   Il blocco `[data-theme="dark"]` resta per una scelta esplicita (oggi non c'è
   nessun interruttore che la imposti); l'@media che lo attivava da solo no. */
:root[data-theme="dark"] {
  --ink: #f2f2f0;
  --ink-soft: #c4c4c0;
  --ink-faint: #8f8f8a;
  --ground: #0d0d0d;
  --ground-alt: #161616;
  --muro-cella: #1c1c1c;
  --rule: #2b2b2b;
  --yellow-deep: #ffd501;
}

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 17px/1.65 var(--body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--display); font-weight: 700; text-wrap: balance; margin: 0; }
/* ⚠️ Peso più alto solo sull'H1: h2/h3 restano a 700 apposta, la gerarchia
   decisa non cambia. Il `<h3>` bare non ha quasi nessun uso reale in pagina
   (`grep` su tre famiglie di pagine: un solo `<h3>Seguici</h3>` nel footer,
   e quello ha già il suo `.foot-follow h3` che sovrascrive tutto) — un
   restyling anche lì non avrebbe cambiato niente di visibile, quindi non
   l'ho toccato. */
h1 { font-size: var(--titolo-eroe); line-height: 1.1; letter-spacing: -0.02em; font-weight: 800; }
h2 { font-size: var(--titolo-fascia); line-height: 1.2; letter-spacing: -0.01em; }
h3 { font-size: 20px; line-height: 1.3; }
p { margin: 0; }
a { color: inherit; }
img { max-width: 100%; height: auto; display: block; }

:focus-visible { outline: 3px solid var(--yellow); outline-offset: 2px; }

/* ⚠️ 1180px meno due gutter da 64px lasciavano 1052px di contenuto, contro i
   1200px misurati in produzione: tutta la pagina rientrava di ~75px per lato. */
.wrap { max-width: calc(1200px + 2 * var(--gutter)); margin: 0 auto;
  padding-inline: var(--gutter); }

/* ⚠️ usata su due titoli dell'HTML e mai definita: "services that make you big"
   e "Still unsure about your needs?" restavano minuscoli, in produzione no. */
.maiuscolo { text-transform: uppercase; }
.prose { max-width: var(--measure); display: flex; flex-direction: column; gap: 20px; }

/* ---- chrome condiviso: modificare qui, non nelle singole pagine ---- */

.site-head {
  border-bottom: 1px solid var(--rule);
  /* ⚠️ NON `sticky`. Misurato in produzione il 2026-09-12 a scroll 1400:
     l'intestazione della fonte e' `position: absolute`, z-index 99, alta
     101px, e SCORRE VIA — a meta' pagina non c'e' piu'. La nostra restava
     incollata in cima su tutte le 97 pagine con l'eroe. AGENTS.md aveva gia'
     misurato «la produzione NON ha uno sticky header» il 2026-08-21 e lo
     script `is-stuck` era stato tolto, ma la BASE del CSS era rimasta
     `sticky`: la regola sopravvissuta alla correzione la rimetteva in piedi. */
  position: relative; z-index: 20;
  background: var(--ground);
  --head-h: 101px;
}

/* Header trasparente sopra l'hero scuro, come il transparent-header di Astra
   (il post ha theme-transparent-header-meta attivo). Resta `position: sticky`
   come la base — non più `absolute` — ma un margine negativo pari alla sua
   stessa altezza (`--head-h`) annulla lo spazio che occuperebbe nel flusso:
   l'eroe parte comunque dal bordo della pagina, e l'header resta agganciabile
   senza cambiare tipo di posizionamento a metà scroll. Vedi il blocco
   `is-stuck` più sotto per il perché di questa scelta. */
.site-head.is-transparent {
  /* ⚠️ `absolute` come la fonte, non `sticky` con un margine negativo: il
     margine faceva partire l'eroe dal bordo ma teneva l'intestazione
     agganciata allo scroll, che e' proprio la differenza da chiudere. */
  position: absolute; top: 0; left: 0; right: 0;
  background: transparent; border-bottom: 0;
  transition: background-color .2s ease;
}
/* ⚠️ L'hamburger disegna le sue tre barre con `currentColor`, e la regola qui
   sopra toglieva il fondo senza mai toccare `color`: ereditava il nero di
   `body` e finiva NERO SU ERO NERO. Invisibile — su 97 pagine su 169, cioè
   tutte quelle con l'eroe scuro, e nessun controllo lo prendeva perché
   meccanicamente il menu funziona: il pulsante c'è, è 44x44, si clicca e si
   apre. Segnalato da un occhio umano il 2026-08-26, non da uno script.
   MISURATO in `?__lane=blue` su iPhone 13: la produzione lo fa BIANCO.
   ⚠️ Il colore non può essere fisso: le 69 pagine articolo hanno il fondo
   chiaro in cima (primo blocco `.post`, non `.hero`) e lì il nero è quello
   giusto — verificato che in produzione, sul blog, l'hamburger è nero. Da qui
   il `:has()`, che il foglio già usa altrove: si guarda cosa c'è sotto.
   Logo e bandiere non mostravano il difetto perché sono immagini coi colori
   propri, e questo lo teneva mimetizzato. */
body:has(> main > .hero) .site-head.is-transparent { color: #fff; }
/* Da bianco su nero a nero su bianco quando l'header si aggancia (vedi
   `is-stuck` più sotto): senza questa, hamburger e frecce delle bandiere
   restano bianchi sopra lo sfondo bianco che arriva con l'aggancio. */
body:has(> main > .hero) .site-head.is-transparent.is-stuck { color: var(--ink); }

/* Il secondo trattamento: la fascia bianca degli articoli. MISURATA in
   `?__lane=blue` il 2026-08-26 — 59px sul telefono, 101px a 1405px,
   `position: relative` (sta NEL flusso e spinge giù il contenuto, non ci passa
   sopra), fondo bianco e nessun filo sotto: la banda scura del titolo attacca
   subito. Il logo lo sceglie `shell()`, che qui usa la variante a scritta
   scura — con quella chiara «WEBGAS.NET» usciva bianco su bianco e restava
   solo la freccia con la tagline.
   ⚠️ Fino al 2026-09-05 questo commento diceva che la base `.site-head` andava
   sovrascritta con `position: relative` perché la produzione non ha un header
   appiccicato (misurato il 2026-08-21: `header_main_stick_meta: disabled`).
   Deciso il 2026-09-05 di ricostruire la funzione APPOSTA, e bene: il blu la
   fa ma rotta (altezza e centratura saltano a metà scroll — segnalato da Tony
   navigando dal vivo). Qui non si eredita più `position: relative`: resta la
   `sticky` della base, così l'header segue lo scroll fin dall'inizio. Vedi
   `is-stuck` più sotto per come si accorcia. */
.site-head.is-piena {
  background: var(--ground); border-bottom: 0;
  transition: box-shadow .2s ease;
}
.has-transparent-head { position: relative; }
/* Il marchio spinge tutto il resto a destra: logo a sinistra, bandiere e
   hamburger appaiati a destra, come in produzione. */
.brand { position: relative; margin-right: auto; }
.brand img { transition: height .2s ease; }

/* ── L'header si aggancia allo scroll ─────────────────────────────────────
   Qui stava, fino al 2026-09-05, la nota su un `is-stuck` tolto perché il blu
   non lo fa. Ricostruito ora: niente lo scambio assoluto→fisso con un
   secondo elemento-clone che usava Astra (`#ast-fixed-header` nascosto,
   sincronizzato a mano con `#masthead` — proprio lì nasceva il salto di
   altezza/centratura visto sul blu). Qui la base resta SEMPRE `position:
   sticky`: un solo elemento, e `galleria.js` aggiunge/toglie `is-stuck`
   oltre 80px di scroll, cambiando solo `--head-h` e lo sfondo.
   `is-piena` non scambia logo: è già scuro su bianco, l'aggancio non cambia
   il contrasto. `is-transparent` invece va da chiaro-su-scuro a scuro-su-
   bianco (richiesto da Tony il 2026-09-05, dopo aver visto la prima versione
   con sfondo scuro anche da agganciato): qui il logo VA scambiato, altrimenti
   la scritta chiara sparisce sul bianco. Niente `src` cambiato via JS — un
   solo elemento, come il resto di questa funzione: si nasconde l'`<img>` e si
   disegna il logo scuro come `background-image` di `.brand` (stesso file già
   servito su ogni pagina `is-piena`, quindi già in cache del browser per chi
   ha visto anche solo un articolo). */
.site-head.is-stuck { --head-h: 62px; }
.site-head.is-stuck .brand img { height: 34px; }
.site-head.is-transparent.is-stuck {
  background: var(--ground); box-shadow: 0 2px 16px rgba(0,0,0,.10);
}
/* L'`<img>` resta nel flusso (solo `opacity`, non `display:none`): è lei a
   dare a `.brand` la sua altezza, e lo pseudo-elemento sotto la riempie. */
.site-head.is-transparent.is-stuck .brand img { opacity: 0; }
.site-head.is-transparent.is-stuck .brand::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: url('/assets/rid/520-wp-content-uploads-2023-10-Logo_WebGas_gold_horizontal_4-1_tagline-1.png')
    left center / auto 100% no-repeat;
}
.site-head.is-piena.is-stuck { box-shadow: 0 2px 16px rgba(0,0,0,.10); }

/* ── Le bandiere ─────────────────────────────────────────────────────────────
   Due, come la produzione, non un interruttore verso l'altra lingua. Stanno
   nella barra accanto all'hamburger, NON dentro il cassetto. */
/* passo 56px fra una bandiera e l'altra, come la fonte (misurato: x=1173 e
   x=1229). Con il riquadro tattile da 44 il gap che lo produce e' 12. */
.lang-flags { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }
.lang-flags a {
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 3px;
  opacity: .55; transition: opacity .15s ease;
}
.lang-flags a:hover, .lang-flags a:focus-visible { opacity: 1; }
/* ⚠️ 18x12 di bandierina è sotto qualunque soglia tattile: il riquadro da 44
   è invisibile ma è ciò che si tocca. La lingua corrente si legge senza dover
   confrontare due immagini.
   ⚠️ L'IMMAGINE è passata a 36x24 il 2026-09-12: è la misura della fonte
   (misurata a 1405px), e le nostre uscivano grandi la metà. Il riquadro
   tattile resta 44x44, quindi la scelta di accessibilità qui sopra è intatta
   — le due cose non erano in conflitto, erano solo state legate.
   ⚠️ E via il contorno sulla lingua corrente: la fonte non ce l'ha
   (`border: 0px none`, misurato), e con la bandiera al doppio più
   l'opacità piena la corrente si distingue lo stesso. `aria-current` resta
   e continua a dirlo a chi legge con lo screen reader. */
.lang-flags a[aria-current="page"] { opacity: 1; }
.lang-flags img { display: block; width: 36px; height: 24px; }
.site-head .wrap {
  display: flex; align-items: center; gap: 16px;
  /* ⚠️ L'intestazione della fonte NON è dentro la colonna da 1200px: occupa
     tutta la larghezza con 45px di margine. Misurato a 1405px — logo a x=45,
     hamburger che finisce a x=1360 — mentre il nostro logo partiva da 103 e
     l'hamburger finiva a 1303, cioè 58px più dentro da tutte e due le parti.
     Solo l'intestazione: il resto della pagina resta nella colonna. */
  max-width: none; padding-inline: 45px;
  /* ⚠️ MISURATO in `?__lane=blue` il 2026-08-26 (commento qui sopra, mai
     applicato finora): 101px a 1405px, 59px sul telefono. Il valore fisso a
     72px era una via di mezzo arbitraria — sistemato il 2026-09-03,
     ri-misurato con Playwright su desktop 1440px: 101.4px sia sull'eroe
     trasparente (home) sia sulla fascia piena (pagine servizio), quindi un
     solo valore per breakpoint basta, non uno per variante.
     Passato a `var(--head-h)` il 2026-09-05: la stessa variabile guida anche
     il margine negativo di `.is-transparent` e l'altezza ridotta di
     `is-stuck`, così i tre non possono disallinearsi. */
  min-height: var(--head-h);
  transition: min-height .2s ease;
}
.brand {
  font-family: var(--display); font-weight: 700; font-size: 19px;
  text-decoration: none; letter-spacing: -0.02em;
  display: inline-flex; align-items: center; gap: 2px;
}
.brand i { font-style: normal; color: var(--yellow-deep); }
.nav { display: flex; gap: 24px; margin-left: auto; flex-wrap: wrap; }
.nav a {
  font-family: var(--display); font-size: 14px; font-weight: 600;
  text-decoration: none; color: var(--ink-soft);
  padding: 4px 0; border-bottom: 2px solid transparent;
}
.nav a:hover, .nav a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--yellow); }

/* CTA a tutta larghezza su giallo pieno, poi il footer scuro: è la chiusura
   di ogni pagina del sito, non solo dei case study. */
.foot-cta { background: var(--yellow); color: #0d0d0d; padding-block: clamp(56px, 8vw, 96px); }
.foot-cta .wrap {
  display: grid; gap: 32px; align-items: center;
  grid-template-columns: minmax(0, 1.4fr) auto;
}
@media (max-width: 820px) { .foot-cta .wrap { grid-template-columns: 1fr; } }
.foot-cta h2 { color: #0d0d0d; font-size: var(--titolo-fascia); }
.foot-cta p { margin-top: 16px; max-width: 46ch; color: #1b1b1b; }
/* ⚠️ Testo bianco, non giallo: misurato in `?__lane=blue` il 2026-09-05 su un
   articolo del blog (`getComputedStyle`, non il CSS statico — il colore vero
   vive in variabili del kit Elementor che non si risolvono da un dump). Nero
   su giallo (il resto della fascia) più bianco sul bottone è lo schema a tre
   toni della produzione; il giallo sul bottone lo appiattiva a due, e sparisce
   quasi contro il nero circostante. Ultimo punto aperto di HQ-11847. */
.btn-solid {
  justify-self: end;
  display: inline-block; background: #0d0d0d; color: #fff;
  font-family: var(--display); font-weight: 600; font-size: 14px;
  letter-spacing: 0.12em; text-transform: uppercase; text-decoration: none;
  padding: 20px 34px; transition: background-color .15s ease;
}
.btn-solid:hover { background: #262626; }
@media (max-width: 820px) { .btn-solid { justify-self: start; } }

.site-foot { background: #141414; color: #c9c9c4; font-size: 15px; }
.foot-grid {
  display: grid; gap: clamp(28px, 5vw, 56px);
  grid-template-columns: minmax(0, 1.2fr) minmax(0, .8fr) minmax(0, 1.4fr);
  padding-block: clamp(48px, 7vw, 76px);
}
@media (max-width: 900px) { .foot-grid { grid-template-columns: 1fr; } }
.foot-brand img { height: 46px; width: auto; }
.foot-legal { margin-top: 14px; font-size: 12.5px; line-height: 1.6; color: #8b8b85; max-width: 40ch; }
.foot-links { display: grid; gap: 11px; align-content: start; }
.foot-links a { color: #e8e8e4; text-decoration: none; font-size: 16px; }
.foot-links a:hover { color: var(--yellow); }
.foot-right { display: grid; gap: 30px; align-content: start; }
.foot-consult {
  justify-self: start; font-family: var(--display); font-weight: 600;
  font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase;
  color: #0d0d0d; background: var(--yellow); padding: 13px 20px; text-decoration: none;
}
.foot-consult:hover { background: #ffe14d; }
.foot-offices { display: grid; gap: 28px; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.foot-offices address {
  font-style: normal; font-size: 14px; line-height: 1.7; color: #b4b4ae;
  padding-left: 24px; position: relative;
}
/* segnaposto della sede: un pin disegnato in CSS, invece di caricare FontAwesome
   intero per due icone */
.foot-offices address::before {
  content: ''; position: absolute; left: 0; top: 4px;
  width: 11px; height: 11px; border: 2px solid var(--yellow); border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
}
.foot-bottom {
  display: flex; flex-wrap: wrap; gap: 20px; justify-content: space-between;
  padding-block: 22px; border-top: 1px solid #2a2a2a;
  font-size: 13.5px; color: #8b8b85;
}
.foot-policies { display: flex; flex-wrap: wrap; gap: 18px; }
.foot-policies a { color: #8b8b85; font-size: 13.5px; }
.foot-policies a:hover { color: #c9c9c4; }

/* ---- case study: struttura fedele al template Elementor ----
   hero scuro a tutta altezza, nome del brand in giallo maiuscolo, hook sotto;
   poi sezioni alternate e la fascia scura dei risultati. */

/* ⚠️ `.hero` è `display: flex` e `.wrap` è un suo elemento: senza
   `min-width: 0` non scende sotto la propria misura di contenuto, e una parola
   lunga nell'h1 («INFRASTRUCTURE») faceva sfondare la pagina di 2px a 320.
   È la stessa trappola delle celle del muro clienti — `min-width: auto` è il
   valore iniziale per gli elementi flex, e va spento a mano. */
.hero > .wrap { min-width: 0; }
.hero {
  background: #1c1c1c;
  background-image: radial-gradient(ellipse at 50% 40%, #333 0%, #141414 70%);
  color: #fff;
  text-align: center;
  padding-block: clamp(120px, 18vh, 190px) clamp(80px, 14vh, 150px);
  display: flex; align-items: center; min-height: 62vh;
}
.hero-eyebrow {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(20px, 2.4vw, 30px); color: #fff; margin-bottom: 4px;
}
.hero h1 {
  /* ⚠️ Il minimo era 46px: su un telefono una parola sola come
     «REPLATFORMING» chiede 415px e la pagina traboccava. MISURATA la
     produzione il 2026-08-22 sulla stessa pagina: a 390px usa **34,47px**, e
     su `lead-generation-funnel` mette pure `overflow-wrap: break-word`. Sono
     gli stessi due strumenti, non una deviazione. Sopra i ~511px non cambia
     niente, perché lì vince il 9vw. */
  font-size: var(--titolo-eroe); overflow-wrap: break-word;
  text-transform: uppercase; color: var(--yellow);
  line-height: 1; letter-spacing: -0.01em;
}
.hero-hook {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(17px, 2.1vw, 26px); color: #fff;
  margin-top: 28px; max-width: 46ch; margin-inline: auto; text-wrap: balance;
}
.hero-industry {
  display: inline-block; margin-top: 26px;
  font-family: var(--display); font-weight: 600; font-size: 13px;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--yellow); border: 1px solid var(--yellow); padding: 7px 14px;
}
/* Il logo del cliente nell'hero del caso studio (HQ-11850): un fondo bianco
   fisso, non lo sfondo scuro dell'hero — il logo arriva da WordPress con
   qualunque combinazione di colori, e solo un fondo neutro lo rende leggibile
   a prescindere da quale sia. */
.hero-logo { display: block; max-height: 44px; width: auto; margin: 22px auto 0;
  background: #fff; padding: 10px 20px; border-radius: 10px; }

.sec { padding-block: clamp(48px, 8vw, 88px); }
.sec-alt { background: var(--ground-alt); }
.sec-grid {
  display: grid; gap: clamp(20px, 4vw, 56px);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
  align-items: start;
}
@media (max-width: 820px) { .sec-grid { grid-template-columns: 1fr; } }
.sec h2 { text-wrap: balance; }
.sec-sub { color: var(--ink-faint); margin-top: 10px; max-width: 60ch; }

.prose p + p, .prose ul { margin-top: 16px; }
.prose ul { padding-left: 0; list-style: none; display: grid; gap: 12px; }
.prose li { padding-left: 26px; position: relative; color: var(--ink-soft); }
.prose li::before {
  content: ''; position: absolute; left: 0; top: 0.62em;
  width: 12px; height: 3px; background: var(--yellow);
}
/* `a { color: inherit }` toglie ogni segnale visivo ai link — invisibili
   dentro una lista di prosa come la rassegna stampa (/it/press/), dove
   sono l'unico contenuto cliccabile della sezione. */
.prose .rassegna a { text-decoration: underline; text-underline-offset: 3px; }
.prose .rassegna a:hover { color: var(--yellow-deep); }

/* I risultati sono il motivo per cui un prospect apre la pagina: fascia scura,
   come nell'originale, così staccano dal resto. */
.sec-dark { background: #141414; color: #fff; }
.sec-dark h2 { color: #fff; }
.sec-dark .sec-sub { color: #b5b5b0; }
.kpis {
  display: grid; gap: 24px; margin-top: 40px;
  grid-template-columns: repeat(auto-fit, minmax(165px, 1fr));
}
/* ⚠️ Sotto i 400px il `minmax(165px)` non entra due volte e i riquadri
   passavano a UNA colonna: su `why-choose-webgas` le cinque fasce di KPI
   pesavano 4.962px, il 33% della pagina, e il telefono era +3.728px rispetto
   alla produzione. Due colonne ne restituiscono circa 2.500. Il gap si stringe
   perché a 320px due colonne da 165 non ci starebbero altrimenti. */
@media (max-width: 480px) {
  .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .kpi { padding: 18px 10px; }
}
.kpi {
  text-align: center; padding: 24px 14px; border: 1px solid #2e2e2e;
  /* il numero scala sulla CARD, non sulla viewport: con 5 KPI le colonne si
     stringono e un valore lungo (+144,5%) usciva dal riquadro sovrapponendosi
     al successivo. min-width:0 serve perché una traccia grid non si restringe
     sotto il contenuto senza. */
  container-type: inline-size;
  min-width: 0;
}
.kpi b {
  display: block; font-family: var(--display); font-weight: 700;
  font-size: clamp(26px, 21cqi, 54px); line-height: 1.05;
  color: var(--yellow); letter-spacing: -0.03em; font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.kpi span { display: block; margin-top: 12px; font-size: 15px; color: #d8d8d4; }
/* ⚠️ HQ-11739 punto 8: sulle pagine col template WordPress vecchio la card ha
   una faccia sul retro che spiega la sigla («CPL Facebook» → «Cost per Lead:
   prezzo per l'acquisizione di un singolo lead tramite Facebook Ads»); qui non
   c'è un retro da girare, quindi la spiegazione sta sotto, più piccola. */
/* ⚠️ Qui stava `.kpi small`, la resa che main dava alla spiegazione del KPI.
   Tolta nella riconciliazione: dopo il merge nessun generatore emette piu' un
   `<small>` dentro una `.kpi` — la spiegazione esce come `.kpi-spiega`, qui
   sotto. Lasciarla sarebbe stato tenere in piedi un secondo modo di stilare la
   stessa cosa, che e' il difetto appena corretto con `.riquadro`/`.promessa`:
   due regole per un contenuto solo si scoprono il giorno in cui una vince. */

/* ── KPI a tab per settore ────────────────────────────────────────────────
   Recuperate il 2026-09-05: su WordPress i 16 KPI del blocco Impact sono
   divisi in 4 schede per settore, non una griglia unica — vedi
   `impact_kpis_tabbed()` in build_services.py. `.kpis`/`.kpi` sopra restano
   IDENTICI: ogni scheda è la stessa griglia di sempre, solo dentro un
   pannello che si mostra o si nasconde. */
.kpi-tabs { margin-top: 40px; }
.kpi-tab-nav {
  display: flex; flex-wrap: wrap; gap: 4px 28px;
  border-bottom: 1px solid #2e2e2e;
}
.kpi-tab-btn {
  background: none; border: none; cursor: pointer; padding: 10px 0 12px;
  font-family: var(--display); font-weight: 600; font-size: 14px;
  color: #b5b5b0; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.kpi-tab-btn.is-active { color: var(--yellow); border-bottom-color: var(--yellow); }
.kpi-tab-btn:hover { color: #fff; }
.kpi-tab-panel { margin-top: 0; }
.kpi-tab-panel[hidden] { display: none; }
.kpi-icon { width: 22px; height: 22px; fill: var(--yellow); margin-bottom: 8px; }
.sec:not(.sec-dark) .kpi-icon { fill: var(--ink); }

/* I 2-3 richiami con icona dopo la playlist video (icon-box SENZA titolo su
   WordPress — vedi `result_bullets()`). Diversi dai `.riquadro` (che sono
   valore+etichetta): qui è icona + una frase sola. */
.result-bullets { margin-top: 28px; display: grid; gap: 16px; max-width: var(--measure); }
.result-bullet { display: flex; align-items: flex-start; gap: 12px; }
.result-bullet svg { width: 20px; height: 20px; fill: var(--yellow-deep); flex: none; margin-top: 2px; }
.result-bullet span { font-size: 15px; line-height: 1.5; color: var(--ink-soft); }

/* L'illustrazione della sezione di apertura, per le pagine che ce l'hanno
   (vedi `apertura_illustrazione()`). Accanto ai pulsanti-àncora, non dentro
   `.prose`: è un'immagine di pagina, non testo. */
/* ⚠️ `margin-inline: auto` (non solo `justify-self`): quest'ultimo funziona
   solo dentro `.sec-grid`, ma dal 2026-09-05 questa classe PUÒ comparire
   anche da sola dentro un `.wrap` semplice, se una pagina avesse l'immagine
   ma non il pulsante — vedi `due_colonne` in build_services.py. Oggi non
   succede (le due pagine in `_APERTURA_IMG_VERIFICATE` hanno entrambi), ma
   senza margin auto l'immagine resterebbe incollata al bordo sinistro il
   giorno in cui succedesse. */
.apertura-img { display: block; width: 100%; height: auto; max-width: 420px;
  margin-inline: auto; justify-self: center; }

.btn {
  display: inline-block; margin-top: 40px;
  font-family: var(--display); font-weight: 600; font-size: 15px;
  color: var(--yellow); text-decoration: none;
  border: 2px solid var(--yellow); padding: 13px 26px;
  transition: background-color .15s ease, color .15s ease;
}
.btn:hover { background: var(--yellow); color: #141414; }

.video { position: relative; aspect-ratio: 16 / 9; background: var(--ground-alt); margin-top: 24px; }
.video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* ⚠️ Senza consenso ai cookie di marketing, Iubenda svuota l'iframe (src a
   "about:blank") e ci appende la classe `_iub_cs_activate` — ma non mostra
   nessun messaggio suo: il riquadro resta vuoto, indistinguibile da un
   errore. Questo overlay ci sta sopra (z-index) finché quella classe c'è;
   la logica che lo aggiunge e lo toglie sta in galleria.js. */
.video-consenso {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; text-align: center; padding: 24px;
}
.video-consenso p { margin: 0; font-size: 14px; color: var(--ink-soft); max-width: 34ch; }
.video-consenso button {
  border: 1px solid var(--ink-soft); background: none; color: var(--ink);
  padding: 10px 20px; font-family: var(--display); font-size: 13px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase; cursor: pointer;
}
.video-consenso button:hover { background: rgba(0, 0, 0, .06); }

.brand img { height: 44px; width: auto; }
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  /* ⚠️ Eccezione VOLUTA, decisa dal committente: il nastro dei marchi scorre
     sempre, per parità con la produzione — che la preferenza non la vede
     nemmeno, perché lì il movimento lo fa Swiper da JavaScript e nessuna media
     query CSS può fermarlo.
     Mitigazioni tenute: la pista si ferma al passaggio del mouse e quando il
     focus entra, così chi ha bisogno di bloccarla può farlo. */
  .nastro-pista { animation: scorri var(--durata, 60s) linear infinite !important; }
}

/* ---- indice case study ---- */

.hero-index { min-height: 40vh; }
.hero-index h1 { text-transform: uppercase; }

.cards {
  display: grid; gap: 24px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.card {
  display: flex; flex-direction: column; gap: 12px;
  padding: 28px 24px 24px;
  border: 1px solid var(--rule); text-decoration: none; color: inherit;
  transition: border-color .15s ease, transform .15s ease;
}
.card:hover { border-color: var(--ink); transform: translateY(-2px); }
.card-sector {
  font-family: var(--display); font-size: 11.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint);
}
.card h2 { font-size: 22px; }
.card-desc { font-size: 14px; line-height: 1.5; color: var(--ink-faint); }
/* i riquadri delle pagine servizio: coppie valore/spiegazione (i widget
   `icon-box` di Elementor). Sono l'ossatura di quelle pagine — su una sezione
   sola ce ne sono fino a 24 — quindi la griglia deve reggere sia i numeri
   («+22,3% ROAS») sia le etichette lunghe («Sessione di convalida strategica»)
   senza cambiare ritmo. Colonne strette: il testo di ognuno è corto, e con
   colonne larghe la riga di descrizione restava orfana in fondo. */
.riquadri {
  display: grid; gap: 26px 30px; margin-top: 26px;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
}
.riquadro { display: flex; flex-direction: column; gap: 6px; }
.riquadro b {
  font-family: var(--display); font-weight: 700; font-size: 17px;
  line-height: 1.25; letter-spacing: -.01em; text-wrap: balance;
}
.riquadro span { font-size: 14px; line-height: 1.55; color: var(--ink-faint); }
.sec-dark .riquadro span { color: #c9c9c4; }

/* i loghi dei partner stanno in un RIQUADRO fisso, non a un'altezza fissa.
   Le proporzioni dei file vanno da 5:1 (Google, 520x103) a 1,3:1 (Shopify,
   520x402): normalizzando la sola altezza, Google usciva largo il triplo di
   Shopify e la fila sembrava sbilanciata. Con un riquadro uguale per tutti e
   `contain`, ogni marchio occupa la stessa area e si adatta dentro. */
.card-logo {
  width: 150px; height: 48px; max-width: 100%;
  object-fit: contain; object-position: left center;
  align-self: flex-start;
}
/* i KPI sono il motivo per cui si clicca: stanno in fondo e pesano.
   Fino a 5 per card (parità con produzione, misurata il 2026-08-24) — ogni
   coppia valore/etichetta resta raggruppata (.card-kpi-item) così un giro
   a capo non separa un numero dalla sua etichetta. */
.card-kpi {
  margin-top: auto; padding-top: 16px; border-top: 1px solid var(--rule);
  display: flex; gap: 14px 20px; flex-wrap: wrap;
}
.card-kpi-item { display: inline-flex; align-items: baseline; gap: 8px; }
.card-kpi b {
  font-family: var(--display); font-weight: 700; font-size: 30px;
  color: var(--yellow-deep); letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.card-kpi span { font-size: 13.5px; color: var(--ink-faint); }
/* ⚠️ La spiegazione del KPI. Su WordPress sta sulla faccia nascosta di una
   scheda che si gira col mouse: chi naviga da tastiera o dal telefono quella
   frase non la raggiunge. Qui e' testo sotto l'etichetta — stesso contenuto,
   senza chiedere un gesto per averlo.
   ⚠️ Il colore si eredita: le schede stanno in una sezione `.sec-dark`, e
   fissarlo qui rifarebbe il nero-su-nero gia' pagato con `.invito`. */
/* ⚠️ La griglia senza nemmeno una scheda non deve lasciare un buco: la sezione
   esce lo stesso perche' la fonte ce l'ha, ma senza schede il `gap` e i margini
   della griglia aprirebbero un vuoto che sembra un errore di caricamento. */
.kpis.kpis-vuota { display: none; }
.kpi .kpi-spiega {
  margin: 8px 0 0; font-size: 13px; line-height: 1.45; opacity: .78;
  max-width: 34ch;
}
/* Le card «titolo + descrizione + Vai al Servizio» di /it/servizi/ e
   /en/services/ — vedi `categorie_servizio()` nel generatore. Qui non serve
   una regola per il fondo scuro: quelle due pagine non ce l'hanno su questa
   sezione (altre due, le agenzie, portano lo stesso widget ma non queste
   card — vedi la nota su `CATEGORIE_PAGINE` nel generatore).
   ⚠️ Stesso `max-width` e `margin-inline: auto` di `.sec-lead .prose` qui
   sotto, e per lo stesso motivo (vedi il suo commento): senza, la griglia
   resta larga quanto `.wrap` (1200px) mentre l'introduzione sopra è
   incolonnata a 78ch — esattamente il difetto segnalato da Tony il
   2026-08-26, riapparso su un widget diverso nella stessa sezione. */
.categorie {
  display: grid; gap: 24px; margin-top: 32px; max-width: 78ch; margin-inline: auto;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.categoria { padding: 24px; border: 1px solid var(--rule); }
.categoria h3 { margin: 0 0 12px; font-family: var(--display); font-size: 16px; letter-spacing: .02em; }
.categoria p { margin: 0; color: var(--ink-soft); font-size: 15px; line-height: 1.6; }
.categoria .card-more { display: inline-block; margin-top: 16px; }

.card-more {
  font-family: var(--display); font-size: 12.5px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  border-bottom: 2px solid var(--yellow); align-self: flex-start; padding-bottom: 2px;
  /* ⚠️ La classe nasce su uno <span> dentro una card cliccabile, dove non c'è
     nessuna sottolineatura da togliere. Usata su un <a> vero — i link d'azione
     delle sezioni — prendeva la sottolineatura del browser SOPRA il bordo
     giallo: due righe sotto la stessa parola. L'affordance è il bordo. */
  text-decoration: none;
}

/* ⚠️ L'invito che NON possiamo far portare da nessuna parte. Nella fonte e' un
   pulsante verso un'altra sezione della pagina («Guarda i risultati dei nostri
   clienti» → #results); noi quelle sezioni le rendiamo senza quegli id, quindi
   il testo lo riproduciamo e il link non lo inventiamo.

   ⚠️ E allora NON deve somigliare a un pulsante: niente bordo giallo, niente
   maiuscoletto. Un elemento che sembra premibile e non lo e' fa cliccare a
   vuoto, ed e' peggio del testo semplice — chi clicca due volte senza risposta
   pensa che sia rotto il sito, non che manchi un link. */
/* ⚠️ Il colore si EREDITA, non si fissa. Scritto `color: var(--ink)` (#0d0d0d)
   diventava nero su #141414 dentro `.sec-dark` — contrasto 1,03:1, testo
   invisibile — e succedeva davvero su `/it/agenzia/agenzia-ecommerce/`. Una
   dichiarazione diretta sull'elemento batte sempre il colore che l'antenato
   scuro passa ai figli, per quanto specifico sia il selettore dell'antenato:
   **il tema scuro non si eredita se qualcuno fissa il colore per strada.** */
.invito {
  font-weight: 600; color: inherit; margin: 14px 0 0;
}
/* ⚠️ L'invito dell'EROE che non possiamo far portare da nessuna parte:
   `#shopify-plus`, `#method` — sezioni precise piu' in basso, di cui non
   abbiamo l'ancora. Come `.invito`, non deve somigliare a un pulsante: qui
   accanto ce n'e' uno vero, e due cose simili di cui una sola si preme sono
   peggio di una sola cosa. */
.hero-invito {
  display: inline-block; margin: 22px 12px 0 0; font-weight: 600;
  color: inherit; opacity: .85;
}

/* ---- servizi ---- */
.hero-cta {
  display: inline-block; margin-top: 34px;
  font-family: var(--display); font-weight: 600; font-size: 14px;
  letter-spacing: .1em; text-transform: uppercase; text-decoration: none;
  background: var(--yellow); color: #0d0d0d; padding: 17px 30px;
  transition: background-color .15s ease;
}
.hero-cta:hover { background: #ffe14d; }

/* «Posizioni Aperte» su `/it/lavora-con-noi/`: sulla fonte e' un PULSANTE
   nero, non una frase. Misurato a 1405px: 308x48, bianco 16px/700 Montserrat
   maiuscolo su #0d0d0d, con una freccia in giu', e porta a `#start`. Da noi
   era un paragrafo grigio 17px allineato a sinistra e largo 758.
   ⚠️ Non riusa `.hero-cta`, che e' GIALLA con testo scuro: qui il fondo e'
   scuro e il testo bianco, ed e' l'unico comando su un eroe giallo — una
   scritta gialla su giallo non si vedrebbe. */
.invito-pulsante {
  /* ⚠️ `width: fit-content` e `align-self: start`: dentro `.prose`, che e' una
     griglia, un `inline-flex` viene comunque stirato a tutta la colonna —
     usciva largo 758 contro i 308 della fonte. `line-height: 1.2` per la
     stessa ragione al contrario: senza, l'altezza andava a 54 invece di 48. */
  display: inline-flex; align-items: center; gap: 12px;
  width: fit-content; align-self: start; line-height: 1.2;
  margin-top: 22px; padding: 14px 52px;   /* 52 e non 28: cosi' esce 308x48, la misura della fonte */
  background: #0d0d0d; color: #fff; text-decoration: none;
  font-family: var(--display); font-size: 16px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  transition: background-color .15s ease;
}
.invito-pulsante::after { content: "\2193"; font-size: 18px; line-height: 1; }
.invito-pulsante:hover { background: #333; }
/* ⚠️ E la colonna che lo contiene non va centrata. `.prose` su queste sezioni
   ha `margin-inline: auto`, che spingeva il pulsante a x=323 mentre il titolo
   sopra sta a 103: un comando rientrato di duecento pixel rispetto alla frase
   che lo introduce. Sulla fonte sono allineati. */
body.page-posizioni .sec-lead .prose { margin-inline: 0; }

/* ── La riga in fondo al piede: IMPILATA e CENTRATA, non affiancata ─────────
   Misurato sulla fonte a 1405px (`/it/`, e uguale su `/en/` e
   `/it/recensioni/`):

     i link legali    y=-258, centrati
     il copyright     y=-127, largo 1405, CENTRATO, SOTTO i link

   Da noi stavano sulla stessa riga, il copyright a sinistra (x=103, largo
   247) e i link a destra (x=836). Due righe centrate contro una riga divisa
   in due: e' la disposizione, non un dettaglio tipografico.

   ⚠️ `column-reverse` e non `column`: nel markup il copyright viene PRIMA dei
   link (lo scrive `shell()`, che e' dell'area B e non si tocca), mentre sulla
   fonte si vede DOPO. Si inverte in CSS invece di chiedere un cambio di
   markup per una cosa che il foglio sa fare da solo — e l'ordine di lettura
   resta quello del documento.

   ⚠️ E il carattere e' Open Sans, non Montserrat: vale sia per il copyright
   sia per la riga «Webgas.net e' un marchio registrato», misurate su sette
   pagine su otto. L'ottava e' `/it/tool/klaviyo-strategy-quiz/`, che carica
   un kit Elementor diverso — la stessa eccezione gia' annotata piu' su per i
   link legali, e le pagine `tool/` sono sei su 429. */
/* ⚠️ `align-items: stretch` e non `center`: centrando gli ELEMENTI il blocco
   del copyright si stringe sul testo (225px) mentre sulla fonte e' largo
   quanto la riga (1405) col testo centrato dentro. A schermo si somigliano,
   ma sono due scatole diverse e ogni confronto futuro lo direbbe. */
.site-foot .foot-bottom {
  flex-direction: column-reverse; align-items: stretch;
  gap: 14px; text-align: center;
}
.site-foot .foot-bottom > div { font-family: var(--body); text-align: center; }
.site-foot .foot-policies { justify-content: center; }
/* ⚠️ `body` davanti: senza, questa riga PERDE contro
   `.site-foot .foot-legal { font-family: var(--display) }` del blocco piu' in
   basso nel foglio — stessa specificita', vince chi viene dopo. Scritta nel
   modo ovvio non applicava, e la riga restava in Montserrat. */
body .site-foot .foot-legal { font-family: var(--body); }

/* ── Le etichette del modulo, misurate sulla fonte ──────────────────────────
   Lette dal modulo #52 vivo su `/it/servizio/cro/` e dal #56 su `/en/contact/`
   il 2026-09-14:

     titolino   <strong>Come ti chiami?</strong>   18px/700   (da noi: assente)
     etichette  18px/500 rgb(13,13,13)             (da noi: 17px/600)
     consenso   18px/400                            (da noi: piu' piccolo)

   Sono 66 pagine che portano questo modulo, e il titolino risultava un testo
   MANCANTE su ognuna.
   ⚠️ Il titolino lo emette `lead_form()` solo per il modulo di default: gli
   altri (risorse, blog, quiz) hanno una loro intestazione o non ne hanno, e
   darlo a tutti sarebbe inventarlo. */
.lead-form .form-titolino { margin: 0 0 4px; }
.lead-form .form-titolino strong { font-size: 18px; font-weight: 700; color: #0d0d0d; }
/* ⚠️ La riga sulle etichette NON sta qui. C'era, a 18px, e PERDEVA: piu' in
   basso nel foglio `.lead-form label { font-size: 14px }` ha la stessa
   specificita' e viene dopo. Il modulo e' rimasto a 14px per giorni con la
   regola giusta scritta e inerte. Ora sta insieme alle altre misure del
   modulo, dove si vede subito chi vince. */

/* ── Due etichette che avevamo di misura sbagliata, su decine di pagine ─────

   «Fai il tuo prossimo grande passo» / «Take your next big step», il titolo
   della fascia contatti: sulla fonte **98,35px** a 1405px di larghezza, cioe'
   7vw. Noi lo scrivevamo a 32px — il testo piu' grande della pagina, reso tre
   volte piu' piccolo. Misurato su cinque pagine a caso fra le quarantadue che
   ce l'hanno: 98,35px/700 nero centrato, cinque su cinque.

   ⚠️ E' in `vw`, non in pixel: misurato a cinque larghezze la fonte fa 7vw
   sopra i 1025px, **6vw** fra 768 e 1024, e di nuovo 7vw sotto — i punti di
   rottura di Elementor. Scritto come numero fisso, a 390px sarebbe uscito un
   titolo da 98px su uno schermo largo 390.

   ⚠️ La classe `.passo-grande` la mette `lead_form()` SOLO dove la fonte ha
   davvero quella fascia (42 pagine su 66, da `modulo-dove.json`). Sulle altre
   24 la mettiamo noi come ripiego commerciale: li' un titolo da 98px
   renderebbe piu' vistoso uno scostamento gia' dichiarato. */
/* ⚠️ SCOSTAMENTO VOLUTO DALLA FONTE, deciso da Giovanni il 2026-09-19.
   Su WordPress questo titolo e' 7vw — 98,35px a 1405px — cioe' PIU' GRANDE
   dell'h1 della pagina, che ne fa 88, e piu' del doppio degli altri titoli di
   sezione, che stanno fra 30 e 40. Segnalato due volte come «troppo grande»:
   la prima volta ho risposto che era identico a WordPress, ed era vero ma non
   era la domanda. Qui la parita' cede a una decisione del committente, presa
   fra tre misure viste a confronto con le altre della pagina.
   40px e' la stessa di «Risultati convalidati dall'analisi» e «Domande
   frequenti»: la fascia contatti chiude la pagina invece di gridarci sopra.
   ⚠️ Per tornare alla fonte: `7vw` sopra i 1025px e `6vw` fra 768 e 1024 — i
   punti di rottura di Elementor. */
/* ⚠️ Era `clamp(28px, 4vw, 40px)`, il valore della fonte per la sola fascia
   contatti. Con la scala unica scende a `--titolo-fascia` come tutti gli
   altri titoli di fascia: il commento qui sopra diceva gia' che 40px «e' la
   stessa di Risultati convalidati e Domande frequenti», e infatti adesso
   quei tre titoli sono di nuovo lo stesso numero — solo che il numero e' 36. */
#contatto-titolo.passo-grande {
  font-size: var(--titolo-fascia); font-weight: 700; color: #000;
  text-transform: none; text-align: center; line-height: 1.15;
}

/* ⚠️ E la fascia va IMPILATA, se no quel titolo non ci sta. Segnalato dal
   committente il 2026-09-14 con uno scatto di `/it/servizi/strategy-data/
   #contatto`: il titolo a 7vw finiva SOPRA i campi del modulo — «prossimo»
   scritto attraverso «Come si chiama la tua azienda?». Difetto mio: ho preso
   la misura giusta dalla fonte e l'ho messa in una colonna larga la meta'.
   Misurata la fonte a 1405px:
       titolo      x=60  w=1285  (tutta la riga, centrato)
       sottotitolo x=60  w=1285
       modulo      x=155 w=1095  SOTTO, centrato
   Da noi erano due colonne affiancate.
   ⚠️ Si usa `:has(> .lead-form)` e non `.sec-grid` in generale: quella classe
   la usano anche altre fasce a due colonne, che vanno bene come sono. */
.wrap.sec-grid:has(> .lead-form) {
  display: block;
}
.wrap.sec-grid:has(> .lead-form) > div { text-align: center; }
.wrap.sec-grid:has(> .lead-form) > .lead-form {
  max-width: 1095px; margin-inline: auto; margin-top: 28px;
}
/* ⚠️ E il titolo NON deve restare appiccicato. Sulle pagine servizio c'e'
   `body.page-service main .sec-grid > :first-child { position: sticky }`
   (riga ~2693), pensata per la colonna sinistra delle sezioni a due colonne.
   Con la fascia contatti impilata quel `sticky` fa scorrere il titolo SOPRA
   il modulo: su `/it/servizio/cro/` e sulla gemella inglese il difetto che il
   committente aveva segnalato restava, identico, anche dopo aver impilato la
   fascia — e il primo controllo sul vivo lo ha ripreso.
   La specificita' deve battere quella riga: `.page-service .wrap.sec-grid
   :has() > :first-child` pesa (0,5,2) contro i suoi (0,4,2). */
body.page-service main .wrap.sec-grid:has(> .lead-form) > :first-child {
  position: static;
}
/* (la variante tablet a 6vw non serve piu': il `clamp` copre tutto) */

/* «Recensioni video» / «Video reviews» e' un'ETICHETTA, non un titolo di
   sezione: 16px/700 rgb(13,13,13) a sinistra, uguale a 1920, 1405, 1000, 768
   e 390px. Noi la scrivevamo a 32, il doppio, su quaranta pagine. */
/* ⚠️ NIENTE `font-size` QUI. Nasceva come ETICHETTA — un occhiello sopra il
   lettore video — a 16px. Su VENTOTTO pagine e' gia' scavalcata da
   `titolo-fonte`, che la porta alla scala del sito; su OTTO no, e li' resta
   l'unico titolo di sezione a 16px mentre tutti gli altri stanno a 36.
   Segnalato dal committente il 2026-09-30 su
   /it/servizi/ux-design-development/ («titolo troppo piccolo e non
   centrato») e censito subito: 8 su 36, sempre 16 contro 36 — le tre
   pilastro italiane, le tre inglesi e le due agenzia-ecommerce.
   Togliendo il corpo, quelle otto prendono la scala come ogni altro `h2` e le
   altre ventotto non si muovono di un pixel, perche' li' il corpo lo dava
   gia' un'altra regola.
   ⚠️ Allineamento e maiuscolo NON si toccano qui. Il primo tentativo li
   metteva su `.etichetta-video` e cambiava TUTTE E 36 le pagine: sulle 28 sane
   spostava il titolo da sinistra al centro senza che nessuno l'avesse
   chiesto. Me ne sono accorto misurando prima e dopo — il commento che avevo
   scritto diceva «le altre non cambiano» ed era falso. Stanno nella regola
   d'ambito qui sotto. */
.etichetta-video {
  font-weight: 700; color: #0d0d0d; text-align: left;
  text-transform: none;
}

/* Sulle pagine pilastro il titolo del video E' un titolo di sezione, e segue
   gli altri: centrato e maiuscolo. Ambito stretto perche' altrove la stessa
   classe fa davvero da etichetta. */
body.page-pilastro .etichetta-video {
  text-align: center; text-transform: uppercase;
}

/* ── L'eroe come lo dipinge la FONTE ────────────────────────────────────────
   Le variabili le scrive `.migration/eroe_fonte.py` sull'elemento, una pagina
   alla volta, da `eroe.json` — misurato dal vivo su 56 pagine, non dedotto.

   Cosa diceva la misura, a 1405px, corsia blu:
     fondo dietro l'h1   44 GIALLO (gradiente 160deg o pieno) su 56
     colore del titolo   52 NERO su 56          noi: giallo su tutte
     trasformazione      54 `none` su 56        noi: MAIUSCOLO su tutte
     allineamento        34 a sinistra          noi: centrato su tutte
     corpo               50px                   noi: fino a 104px

   ⚠️ La parola evidenziata non si puo' rimettere da sola. La classe della
   fonte `.yellow` si rende BIANCO SU NERO, e ha senso solo perche' dietro
   l'eroe e' giallo: su un eroe scuro come il nostro sparirebbe. Fondo,
   titolo e span sono una cosa sola e si applicano insieme.

   ⚠️ E la classe NON dice il colore: `.black` si rende NERO SU GIALLO sopra
   un eroe scuro, cioe' l'esatto contrario di `.yellow`. Per questo qui non
   c'e' nessun nome di classe della fonte — solo i valori calcolati. */
/* ⚠️ NIENTE `background-image: none` qui sotto. C'era, e cancellava il
   gradiente che la riga sopra aveva appena messo: `background` e' una
   scorciatoia che scrive anche `background-image`, quindi la riga dopo la
   azzerava. Risultato: 32 eroi con il fondo BIANCO invece che giallo — la
   correzione sembrava applicata (titolo nero, parola evidenziata al posto
   giusto) e la cosa piu' vistosa non era cambiata. */
.hero.hero-fonte { background: var(--eroe-fondo, #1c1c1c); }
/* ⚠️ E il respiro sopra il titolo: sulla fonte l'`h1` comincia a y=150 su
   cinque pagine su sei misurate (press, blog, casi-studio, risorse,
   partners), da noi a 162 — il nostro `clamp(120px, 18vh, 190px)` a 900px di
   finestra vale 162. Dodici pixel su ogni pagina con l'eroe.
   ⚠️ Solo sopra gli 820px: sotto resta il comportamento responsivo che c'e'
   gia', che sul telefono serve. */
@media (min-width: 821px) {
  /* ⚠️ E `min-height: auto`. `.hero` ha `min-height: 62vh` con il contenuto
     centrato in verticale: quando il titolo e' corto — «REVIEWS», una riga —
     il blocco si centra dentro quei 558px e il titolo scende di 65. Sulla
     fonte l'altezza dell'eroe la fa il PADDING e basta, e infatti l'`h1` di
     `/en/reviews/` comincia a 150 come su tutte le altre.
     Misurato: con la sola correzione del padding quella pagina PEGGIORAVA
     (da +48 a +65), perche' i 12px recuperati in cima venivano restituiti
     dalla centratura. */
  .hero.hero-fonte { padding-block: 150px 80px; min-height: auto; }
}
.hero.hero-fonte > .wrap { text-align: var(--eroe-allin, center); }
.hero.hero-fonte h1 {
  color: var(--eroe-testo, var(--yellow));
  text-transform: none;
  font-size: var(--titolo-eroe);
  font-weight: var(--eroe-peso, 800);
  text-align: var(--eroe-allin, center);
}
/* ── Il corpo dell'eroe: la scala, non piu' la cattura (2026-09-29) ──────
   Qui stavano `--eroe-dim`, il numero misurato sulla fonte a 1405px, e le tre
   media query che lo riscalavano fra 769 e 1404 e sotto i 768 — nate perche'
   un numero fisso non ha punti di rottura e su dodici pagine una parola del
   titolo diventava piu' larga del riquadro («REVIE / WS», «Portfo / lio»).
   Con `--titolo-eroe` il problema si scioglie da solo: un `clamp` scala con la
   finestra a ogni larghezza, e il massimo e' 72px invece di 198.
   ⚠️ Le misure della fonte NON sono state buttate: restano in `eroe.json` e
   `eroe_fonte.py` continua a leggerne fondo, colore, peso e allineamento.
   Solo il corpo adesso lo decide la scala. */

/* ⚠️ Il `padding` arriva dalla fonte perche' cambia: 1px 10px sulla maggior
   parte, 1px 8px 1px 6px dove la parola finisce con i due punti. */
.hero.hero-fonte h1 .risalto {
  color: var(--ris-testo, #fff);
  background: var(--ris-fondo, #000);
  padding: var(--ris-pad, 1px 10px);
  /* il riquadro non deve spezzare la riga a meta' della parola */
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}

/* Sul fondo CHIARO tutto il resto dell'eroe va scurito. Non e' un ritocco:
   l'eroe scuro colora occhiello, gancio e menu in BIANCO, e su giallo il
   bianco non si legge — sono 44 pagine di testo invisibile. Il colore esatto
   di questi elementi non e' stato misurato dalla fonte perche' il rilevatore
   prendeva il testo della banda dei cookie e le voci del menu; la luminanza
   del fondo, quella si' misurata bene, basta a non lasciare bianco su giallo. */
.hero.hero-chiaro { color: #0d0d0d; }
/* ⚠️ `hero-occhiello` va elencata qui accanto a `hero-eyebrow`: ora e'
   BIANCA, e su un eroe chiaro sarebbe invisibile. */
.hero.hero-chiaro .hero-eyebrow,
.hero.hero-chiaro .hero-occhiello,
.hero.hero-chiaro .hero-hook,
.hero.hero-chiaro .hero-invito { color: #0d0d0d; }
.hero.hero-chiaro .hero-cta {
  background: #0d0d0d; color: #fff;
}
.hero.hero-chiaro .hero-cta:hover { background: #333; }
.hero.hero-chiaro .hero-industry { color: #0d0d0d; border-color: #0d0d0d; }

/* L'intestazione trasparente sta SOPRA l'eroe: sul giallo le sue voci bianche
   sparivano. Sulla fonte sono rgb(13,13,13), misurato. Il tratto del menu a
   panino usa `currentColor` (riga ~2263), quindi si tinge da solo. */
/* ⚠️ `> main > .hero.hero-chiaro` e non `.hero-chiaro`: la riga 134 dice
   `body:has(> main > .hero) .site-head.is-transparent { color: #fff }`, che a
   parita' di posizione VINCE — la specificita' di `:has()` e' quella del suo
   argomento piu' specifico, e `> main > .hero` pesa piu' di `.hero-chiaro`.
   Scritta nel modo ovvio la regola non applicava e il menu restava bianco su
   giallo: presente nel foglio, valida, e senza effetto. */
body:has(> main > .hero.hero-chiaro) .site-head.is-transparent,
body:has(> main > .hero.hero-chiaro) .site-head.is-transparent .nav a,
body:has(> main > .hero.hero-chiaro) .site-head.is-transparent .nav summary a { color: #0d0d0d; }

/* ⚠️ MA NON A CASSETTO APERTO. La regola qui sopra scurisce le voci perche'
   dietro l'intestazione trasparente c'e' un eroe CHIARO: giusto finche' il
   menu e' chiuso. Quando si apre, il pannello diventa #1a1a1a e le voci
   restavano #0d0d0d — contrasto 1,12:1, nero su nero. Segnalato dal
   committente il 2026-09-30 su /it/lavora-con-noi/: «il menu si apre di un
   colore nero che non fa vedere nulla». Sono 74 le pagine con l'eroe chiaro.
   ⚠️ La rassegna sul contrasto NON poteva trovarlo: misura a cassetto chiuso,
   dove le voci hanno dimensione zero, e proprio per questo le salta. Anzi,
   aveva segnalato QUESTA coppia di colori su 60 pagine e io l'avevo
   archiviata come falso positivo — il colore era vero, sbagliata era la
   prova. Ora c'e' `_diag-menu-aperto.mjs`, che apre il menu e poi misura.
   ⚠️ `.menu-aperto` la mette gia' il foglio due schermate piu' su, per
   schiarire il pulsante dell'hamburger: lo stato c'era, mancava di usarlo
   anche per le voci. */
body:has(> main > .hero.hero-chiaro) .site-head.is-transparent.menu-aperto,
body:has(> main > .hero.hero-chiaro) .site-head.is-transparent.menu-aperto .nav a,
body:has(> main > .hero.hero-chiaro) .site-head.is-transparent.menu-aperto .nav summary a {
  color: #f2f2f0;
}

/* ⚠️ Il contenitore dell'eroe: la fonte parte da x=103, noi da 246. Il nostro
   `.wrap` e' largo 1200 PIU' due gutter da 64, e il testo comincia dopo il
   gutter; sulla fonte il contenuto e' largo 1200 netti e il gutter non c'e'.
   Centoquarantatre pixel di scarto sul titolo piu' grande della pagina.
   ⚠️ Il gutter resta come TETTO sugli schermi stretti, se no a 390px il
   titolo tocca i bordi. */
.hero.hero-fonte > .wrap {
  max-width: 1200px; padding-inline: 0;
  width: min(1200px, 100% - 2 * var(--gutter));
}

/* ── La CTA dell'eroe ────────────────────────────────────────────────────────
   MISURATA in produzione il 2026-08-22: 400x48, `16px/700`, crenatura **4px**,
   padding `12px 24px`; sotto i 767px scende a 12px (339x42). Il verde aveva
   288x57 con `14px/600` e 1,4px di crenatura.
   ⚠️ NON si cambia `.hero-cta` in generale: i pulsanti della produzione non
   sono uniformi. Censiti sulla home lo stesso giorno, sono cinque stili —
   «See how it helps» e «Take the survey» hanno `letter-spacing: normal` e peso
   600, le tre porte in filo `11px/700` con 4px, «Book a Strategy Call»
   `14px/700`. La nota «crenatura 1,4px contro 4px SU TUTTI» era falsa. */
.hero-home .hero-cta {
  font-size: 16px; font-weight: 700; letter-spacing: 4px; padding: 12px 24px;
  /* il contenuto del pulsante è alto 24px in produzione: 16 x 1,5 */
  line-height: 1.5;
}
@media (max-width: 767px) {
  .hero-home .hero-cta { font-size: 12px; }
  /* ⚠️ Sul telefono la produzione lascia all'eroe 10px di margine per lato,
     non i 20 del `--gutter`. Con 350px di riga invece di 370 il titolo andava
     a capo tre volte invece di due: la prima banda ne chiede 358. Vale solo
     per l'eroe della home — le altre fasce tengono il gutter di sistema. */
  .hero-home > .wrap { padding-inline: 10px; }
}

/* La freccia in giù dopo il testo: in produzione è un SVG Font Awesome
   (`e-fas-long-arrow-alt-down`, viewBox 0 0 256 512) dentro
   `span.elementor-button-icon`, 16x16 e nero — per questo cercarla in
   `::after` non la trovava. Qui è decorativa, quindi sta nel CSS; la maschera
   le fa prendere il colore del testo. */
.hero-home .hero-cta::after {
  content: ""; display: inline-block; vertical-align: -2px;
  width: 16px; height: 16px; margin-left: 10px; background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 512'%3E%3Cpath d='M168 345.941V44c0-6.627-5.373-12-12-12h-56c-6.627 0-12 5.373-12 12v301.941H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.569 9.373 33.941 0l86.059-86.059c15.119-15.119 4.411-40.971-16.971-40.971H168z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 512'%3E%3Cpath d='M168 345.941V44c0-6.627-5.373-12-12-12h-56c-6.627 0-12 5.373-12 12v301.941H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.569 9.373 33.941 0l86.059-86.059c15.119-15.119 4.411-40.971-16.971-40.971H168z'/%3E%3C/svg%3E") center / contain no-repeat;
}
@media (max-width: 767px) { .hero-home .hero-cta::after { width: 12px; height: 12px; } }

.quotes {
  display: grid; gap: 24px; margin-top: 32px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.quotes .quote {
  margin: 0; padding: 26px; background: var(--ground);
  border-left: 4px solid var(--yellow);
}
.quotes .quote p { font-size: 16.5px; line-height: 1.6; }
/* HQ-11865: le stelle recuperate qui sono un <div>, non un <p> — senza
   questo margine restano incollate alla prima riga della citazione,
   perché `p { margin:0 }` non le tocca e questa card (a differenza di
   `.recensione`, un grid con `gap`) non ha respiro automatico fra i figli. */
.quotes .quote .stelle { margin-bottom: 12px; }
.quotes .quote footer {
  margin-top: 14px; font-size: 13.5px; color: var(--ink-faint);
  font-family: var(--display); font-weight: 600;
}

.vids {
  display: grid; gap: 24px; margin-top: 32px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.vid { margin: 0; }
.vid figcaption {
  margin-top: 10px; font-family: var(--display); font-weight: 600;
  font-size: 14px; color: var(--ink-soft);
}

/* Titoli di sezione. ⚠️ Misurati sulla produzione dal vivo: 32px, MAIUSCOLI,
   centrati, senza filetto. Prima erano 40px minuscoli a bandiera con un filetto
   nero da 5px: un sistema diverso, su 7 sezioni. `display:block` resta perche'
   senza di lui i pulsanti tornano ad affiancarsi al titolo e a coprirlo. */
.sec-lead h2 {
  font-size: var(--titolo-fascia);
  text-transform: uppercase;
  text-align: center;
  display: block; width: auto;
  max-width: min(30ch, 100%); margin-inline: auto;
}
.sec-lead.sec-dark h2 { color: var(--yellow); }
.sec-lead .sub {
  font-style: italic; font-size: clamp(16px, 1.9vw, 21px);
  color: var(--ink-soft); margin-top: 14px; max-width: 60ch;
  text-align: center; margin-inline: auto;
}
.sec-lead.sec-dark .sub { color: #c9c9c4; }
/* ⚠️ `margin-inline: auto` non è una rifinitura. Il titolo di `.sec-lead` è
   centrato e il sommario in corsivo pure, ma la colonna di testo restava
   incollata a sinistra: su una pagina larga il titolo stava al centro e il
   paragrafo sotto cominciava 400px più a sinistra, e su una pagina servizio
   quella coppia si ripete anche quindici volte. Segnalato da Tony il
   2026-08-26 come «layout molto meno ottimizzato di WP».
   La colonna si centra, il TESTO dentro resta allineato a sinistra: centrare
   anche le righe renderebbe illeggibile un paragrafo lungo. */
.sec-lead .prose { margin-top: 26px; max-width: 78ch; margin-inline: auto; }
.sec-dark .prose { color: #d8d8d4; }
.sec-dark .acts li { color: #d8d8d4; }

/* fascia loghi clienti */
.logos-sec { padding-block: clamp(40px, 6vw, 64px); }
.logos-title {
  text-align: center; font-family: var(--display); font-weight: 700;
  font-size: 15px; margin-bottom: 30px;
}
.logos {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: clamp(24px, 4vw, 56px);
}
/* ⚠️ Due TETTI, non un'altezza fissa. Con `height: 52px` ogni marchio veniva
   schiacciato alla stessa altezza e uno largo e basso come «Iginio Massari»
   usciva 351x52 contro i 146x22 della fonte: due volte e mezzo piu' largo, e
   sbilanciava tutta la fascia. La fonte li fa entrare in un riquadro di circa
   160x84 conservando le proporzioni — misurato su 47 loghi.
   ⚠️ Da non confondere con `.loghi` (senza la s, riga ~1328): quella e' un'altra
   fascia, e li' l'altezza la calcola `ritaglia_marchi.py` ad area costante e la
   scrive inline. Due classi simili, due meccanismi diversi. */
.logos img {
  max-width: 160px; max-height: 84px; width: auto; height: auto;
  object-fit: contain;
}

/* ⚠️ Qui c'era `filter: grayscale(1); opacity: .72`, con il colore pieno solo
   al passaggio del mouse. Misurata la fonte il 2026-09-13 su
   `/it/servizi/strategy-data/`: `filter: none`, `opacity: 1` — i marchi sono
   a COLORI, fermi. Era un ritocco nostro, e su marchi come Develhope o
   l'Universita' Giustino Fortunato il colore e' meta' del riconoscimento.
   ⚠️ E lo scolorimento al mouse non esisteva proprio su telefono, dove il
   mouse non c'e': meta' dei visitatori vedeva solo la versione grigia. */

/* Il muro dei clienti e' un NASTRO su una riga sola, non una griglia. Sulla
   fonte la fascia e' alta 150px con 51 marchi; da noi era una griglia di 15
   righe alta 1.188px — mille pixel in piu' su tutte e 17 le pagine che la
   portano, subito sotto l'eroe.
   Il passo e' 260px costante, e il marchio ci sta DENTRO conservando la sua
   misura (sulla fonte «marinella» e' 113x80 dentro il suo slot da 260). */
.nastro .logos { flex: none; flex-wrap: nowrap; gap: 0; justify-content: flex-start; }
.logos .logo-slot {
  flex: 0 0 260px; display: flex; align-items: center; justify-content: center;
  min-height: 84px;
}

/* ⚠️ Barra CTA fissa in fondo. Qui c'era scritto «come sull'originale», ed era
   FALSO: misurate le pagine vive, l'unica cosa attaccata in fondo e' il menu a
   scomparsa del telefono (`.ast-mobile-popup-drawer`), e la nostra frase non
   compare su nessuna delle 74 pagine dove la stampiamo.

   E' un componente aggiunto nella ricostruzione, con testo nostro, e Tony l'ha
   confermato il 2026-09-03 dopo averlo misurato: sta su TUTTA la superficie
   commerciale — 34 pagine servizio, 20 partner e agenzia — e su NESSUN articolo
   o caso studio. Su 43 di quelle pagine e' l'unico invito sempre in vista,
   perche' li' la fascia in fondo non c'e' (la fonte non ce l'ha).

   ⚠️ Il testo NON si e' preso dalla fonte, e non per pigrizia: la fonte non ha
   un'etichetta corta adatta a una striscia persistente. «Inizia ora» compare su
   73 pagine su 74 ma porta al quiz, non ai contatti; quelle col senso giusto
   coprono 10-19 pagine ciascuna. Una mappatura per pagina avrebbe avuto bisogno
   di un ripiego, ed e' il ripiego il meccanismo che il 2026-09-03 ci ha fatto
   pubblicare copy inventato in quattro punti diversi.

   ⚠️ Un commento che dice «come sull'originale» quando non e' vero e' peggio di
   nessun commento: chi legge non va a verificare, e ricostruisce una
   convinzione sbagliata. E' cosi' che il pulsante dell'eroe e' rimasto
   inventato per mesi. */
.sticky-cta {
  position: sticky; bottom: 0; z-index: 15;
  background: var(--ground); border-top: 1px solid var(--rule);
  padding-block: 14px;
}
.sticky-cta .wrap {
  display: flex; flex-wrap: wrap; gap: 16px;
  align-items: center; justify-content: space-between;
}
.sticky-cta p { font-size: 15px; }
.sticky-cta a {
  font-family: var(--display); font-weight: 600; font-size: 13.5px;
  background: var(--ink); color: var(--ground); text-decoration: none;
  padding: 12px 22px; white-space: nowrap;
}
.sticky-cta a:hover { background: var(--yellow); color: #0d0d0d; }
/* ⚠️ Sotto i 560px testo e pulsante non stanno più su una riga sola:
   `flex-wrap` li mandava a capo, ma `justify-content: space-between` su una
   riga con un solo elemento lo spinge a SINISTRA — dritto sopra al torna-su
   (`.scroll-top`, stessa bottom:0, stesso angolo). Impilati invece che
   lasciati andare a capo da soli: la riga del pulsante è sempre a piena
   larghezza, mai nell'angolo. Il torna-su si alza di conseguenza — vedi
   `body:has(.sticky-cta) .scroll-top` più sotto nel foglio (la versione per
   telefono sta LÌ, non qui: stessa selettore e stessa specificità, e una
   regola senza media query messa dopo vince comunque su una con media query
   messa prima — misurato il 2026-09-06, la vecchia riga qui non aveva mai
   effetto). */
@media (max-width: 560px) {
  .sticky-cta .wrap { flex-direction: column; align-items: stretch; text-align: center; }
  .sticky-cta a { text-align: center; }
}

/* form di contatto nativo delle pagine servizio */
/* ── Il modulo, misurato sulla fonte ────────────────────────────────────────
   Segnalato dal committente: «il form e' troppo grande». Misurato a 1405px su
   `/it/servizi/strategy-data/`, e il TITOLO non c'entrava — 98,35px su
   entrambe le corsie, identico. E' il modulo:

                     fonte              noi
     altezza totale  1095x629           1095x708
     campo           45px, testo 18px   52px, testo 16px
     riempimento     11px 15px          12px 14px
     area di testo   90px               132px
     etichetta       18px/500           14px

   E sulla fonte EMAIL e CELLULARE stanno sulla STESSA RIGA — 540px ciascuno —
   mentre da noi ogni campo prende tutta la larghezza. */
/* ⚠️ `gap: 22px` e non 14: con 14 il modulo usciva 578 contro i 629 della
   fonte — i campi erano gia' giusti, mancava il respiro fra una riga e
   l'altra. Provati 20, 22 e 24: danno 614, 626 e 638. 22 e' quello che
   atterra piu' vicino, a tre pixel. */
.lead-form { display: grid; gap: 22px; }
.lead-form label {
  display: grid; gap: 6px; font-size: 18px; font-weight: 500; color: #0d0d0d;
}
.lead-form label.check { font-weight: 400; font-size: 16px; }
/* ⚠️ Anche il `select`: dal 2026-09-03 il modulo dei casi studio ha una
   tendina, e senza questa riga era l'unico campo con l'aspetto di default
   del browser in mezzo a cinque campi vestiti. Un campo che sembra di un
   altro modulo fa esitare chi compila. */
.lead-form input, .lead-form textarea, .lead-form select {
  font: inherit; font-size: 18px; padding: 11px 15px;
  border: 1px solid var(--rule); background: var(--ground); color: var(--ink);
  /* ⚠️ `line-height: normal`: con quella EREDITATA (1,6) il campo usciva alto
     54 invece dei 45 della fonte — 18px di testo per 1,6 fanno 29 di riga
     invece di 21, e per cinque campi sono quasi cinquanta pixel di modulo in
     piu'. Il riempimento era gia' giusto: era l'interlinea. */
  line-height: normal;
}
.lead-form textarea { min-height: 90px; height: 90px; line-height: 1.5; }

/* ⚠️ EMAIL e CELLULARE sulla STESSA RIGA, come sulla fonte: li' sono 540px
   ciascuno, da noi prendevano tutta la larghezza a testa. Vale solo per il
   modulo di default (#52 / #56): gli altri — risorse, blog, quiz — hanno
   campi loro, in numero e ordine diversi, e affiancare il secondo col terzo
   li' vorrebbe dire accoppiare due campi a caso.
   ⚠️ E solo sopra gli 820px: sul telefono restano incolonnati. */
@media (min-width: 821px) {
  .lead-form[data-form_id="52"], .lead-form[data-form_id="56"] {
    grid-template-columns: 1fr 1fr;
  }
  .lead-form[data-form_id="52"] > *, .lead-form[data-form_id="56"] > * {
    grid-column: 1 / -1;
  }
  .lead-form[data-form_id="52"] > label:nth-of-type(2),
  .lead-form[data-form_id="56"] > label:nth-of-type(2) { grid-column: 1; }
  .lead-form[data-form_id="52"] > label:nth-of-type(3),
  .lead-form[data-form_id="56"] > label:nth-of-type(3) { grid-column: 2; }
}
.lead-form input:focus, .lead-form textarea:focus, .lead-form select:focus { border-color: var(--ink); outline: none; }
.lead-form .check { grid-auto-flow: column; justify-content: start; align-items: center; gap: 10px; }
.lead-form .check input { width: 18px; height: 18px; accent-color: var(--yellow); }
/* L'avviso dentro il modulo — «i casi studio sono in italiano». Sta fra i campi
   e la privacy, dove lo mette la fonte. ⚠️ Stesso colore delle etichette, non
   piu' tenue: e' l'informazione che evita a un lead inglese di scoprire solo
   aprendo il PDF che non e' nella sua lingua. Sbiadirla sarebbe nasconderla. */
.lead-form .form-nota { margin: 0; font-size: 14px; color: var(--ink-soft); }
/* ⚠️ Prima era `justify-self: start` — largo solo quanto il suo testo,
   «Invia la richiesta», dentro una grid. Il contrasto nero-su-giallo è già
   il più alto possibile: quello che mancava non era colore, era massa
   visiva. A piena larghezza e con un peso più alto è l'ultima cosa che si
   vede prima di diventare un lead — vale la pena che pesi di più. */
.lead-form button {
  justify-self: stretch; margin-top: 6px; cursor: pointer;
  font-family: var(--display); font-weight: 800; font-size: 16px;
  letter-spacing: .06em; text-transform: uppercase;
  background: var(--yellow); color: #0d0d0d; border: 2px solid var(--yellow); padding: 19px 30px;
}
.lead-form button:hover { background: #ffe14d; }
.lead-form button[disabled] { opacity: .6; cursor: default; }
.wg-form-error { margin-top: 12px; color: #b3261e; font-size: 14px; }
.wg-form-ok { font-size: 17px; }

/* Galleria dei progetti di portfolio fusi dentro l'indice dei case study.
   Voci non cliccabili di proposito: quei progetti non hanno una pagina propria,
   e un link che gira a vuoto è peggio di nessun link. Vedi build_galleria.py. */
.sec-galleria { border-top: 1px solid var(--rule); }
.galleria-occhiello { color: var(--soft); margin: 0 0 22px; max-width: 60ch; }
.galleria {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 14px 28px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.galleria li {
  padding: 14px 0; border-top: 1px solid var(--rule);
  display: flex; flex-direction: column; gap: 3px;
}
.galleria li b { font-weight: 620; }
.galleria li span { color: var(--soft); font-size: 14px; }

/* Contenuto del portfolio del cliente portato dentro il suo case study.
   Il titolo resta nella colonna sinistra di .sec-grid, tutte le sottosezioni
   stanno in un solo contenitore a destra. Vedi build_merge_portfolio.py. */
.sec-fuso h3 { font-size: 18px; font-weight: 620; margin: 0 0 8px; }
.sec-fuso .prose + h3 { margin-top: 28px; }

/* Articoli del blog ricostruiti (build_blog.py). Il contenuto arriva pulito dal
   dump REST: qui serve solo dargli una colonna leggibile e una gerarchia. */
/* ⚠️ La testata dell'articolo è una BANDA SCURA col titolo giallo, non testo
   nero su bianco. MISURATA in `?__lane=blue` il 2026-08-26: il contenitore
   sotto l'intestazione porta
   `radial-gradient(rgb(70,70,70) 0%, rgb(26,26,26) 100%)` e l'h1 esce
   `rgb(255,213,1)`. Il verde la serviva chiara, e insieme all'intestazione
   trasparente col logo chiaro faceva sparire il marchio.
   Qui il gradiente è scritto come quello di `.hero` (ellisse), con i colori
   misurati sulla produzione: stessa famiglia visiva del resto del sito. */
.post-head {
  padding: clamp(48px, 8vw, 96px) 0 clamp(40px, 7vw, 80px);
  background-image: radial-gradient(ellipse at 50% 40%, #464646 0%, #1a1a1a 100%);
  color: #fff;
}
.post-head h1 { color: var(--yellow); }
/* L'estratto sotto il titolo, come in produzione. ⚠️ NON si riusa `.hero-hook`:
   quello è centrato (`margin-inline: auto`) e in carattere display, perché
   serve l'eroe centrato; qui la banda è allineata a sinistra. */
.post-hook {
  margin: 20px 0 0; max-width: 62ch; line-height: 1.5;
  font-size: clamp(16px, 2vw, 20px); color: rgba(255, 255, 255, .85);
}
.post-date { color: rgba(255, 255, 255, .7); font-size: 14px; margin: 0 0 12px; }
/* ⚠️ La data era BIANCA SU BIANCO in ogni scheda, e lo era già prima di questo
   blocco: `.card` non ha fondo proprio, quindi sta sul bianco della pagina, e
   `.post-date` nasce chiara perché la sua prima casa è la banda scura della
   testata. Gli indici del blog — `/it/blog/` e `/en/blog/` — stampano la data
   in ogni scheda da sempre e non se ne vede nemmeno una. Un colore che sparisce
   non lancia nessun errore: si trova solo guardando. */
.card .post-date { color: var(--ink-faint); }
.post-head h1 { max-width: 22ch; text-wrap: balance; }

/* «Precedente / Successivo» e «Altri Contenuti Interessanti»: i due blocchi in
   coda all'articolo (build_blog.py). Le schede riusano `.cards`/`.card`
   dell'indice — stesso guscio, così non nasce una seconda idea di scheda che
   poi diverge. */
.post-nav {
  display: grid; gap: 16px; margin-block: clamp(32px, 5vw, 56px);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.post-nav a {
  display: flex; flex-direction: column; gap: 6px;
  padding: 20px 22px; border: 1px solid var(--rule);
  text-decoration: none; color: inherit;
  transition: border-color .15s ease;
}
.post-nav a:hover { border-color: var(--ink); }
/* Il successivo si allinea a destra SOLO quando c'è anche il precedente:
   sull'articolo più recente resterebbe una scheda sola spinta a un bordo. */
.post-nav a + .post-nav-next { text-align: right; }
.post-nav-label {
  font-family: var(--display); font-size: 11.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint);
}
.post-nav-title { font-weight: 620; line-height: 1.35; }
/* I tag: testo, non link — il sito nuovo non ha gli archivi per tag. */
.post-tags {
  margin-block: 0 clamp(32px, 5vw, 56px);
  font-size: 14px; color: var(--ink-faint);
}
/* ⚠️ Il cancelletto NON va in giallo. `--yellow-deep` su bianco dà 2,00:1 e la
   nota su `:root` lo vieta per il testo su fondo chiaro: vale anche per un
   glifo decorativo, che decorativo lo è per chi lo vede. */
.post-tags span { color: var(--ink); font-weight: 700; }
.sec-correlati .card h3 { font-size: 22px; margin: 0; }
/* Le tabelle dentro gli articoli. ⚠️ Il contenitore scorre, la tabella no: su
   telefono una tabella a tre colonne è più larga dello schermo, e senza
   `overflow-x` a scorrere sarebbe la PAGINA intera — tutto il sito trascinato
   di lato da un blocco solo. */
.post-body figure:has(table) { overflow-x: auto; margin-inline: 0; }
/* ⚠️ Una tabella SENZA `<figure>` attorno non ha un contenitore che scorra, e
   con `min-width` porterebbe di lato la pagina intera. Tutte e sei le tabelle
   di oggi vengono dall'editor a blocchi e arrivano dentro una `<figure>`; una
   dell'editor classico no. Qui scorre da sé. */
.post-body > table { display: block; overflow-x: auto; }
.post-body table {
  /* ⚠️ `min-width` sotto la colonna dell'articolo (~530px), altrimenti la
     tabella sfora di una dozzina di pixel e il contenitore mette una barra di
     scorrimento anche sul desktop, dove non serve. */
  border-collapse: collapse; width: 100%; min-width: 30rem;
  font-size: 15px; line-height: 1.45;
}
.post-body th, .post-body td {
  border: 1px solid var(--rule); padding: 10px 14px;
  text-align: left; vertical-align: top;
}
/* ⚠️ In grassetto va SOLO `<th>`. La tentazione è aggiungere
   `tr:first-child td:first-child` per fare la riga di testa quando manca
   `<thead>`: non la fa: ingrassa una cella sola, cioè un dato a caso. Se una
   tabella non dichiara l'intestazione, il posto dove ripararla è il contenuto. */
.post-body th { font-weight: 700; }
.post-body tbody tr:nth-child(odd) { background: var(--ground-alt); }
/* ⚠️ `padding` è una SCORCIATOIA, e qui azzerava anche i lati: `.post-body` è
   `class="wrap post-body"`, quindi quel `0` cancellava il `padding-inline` che
   `.wrap` aveva appena messo. Il testo degli articoli toccava il bordo dello
   schermo — x=0 contro i 30px della produzione, misurato a 390px il
   2026-08-26. `padding-block` i lati non li nomina, e il gutter sopravvive. */
/* ⚠️ Un URL nudo dentro il testo non ha spazi dove andare a capo e sborda dal
   telefono: su `/en/blog/metrics-of-email-marketing-the-9-essentials/` il link
   «https://knowledge.hubspot.com/email/analyze-your-marketing-e…» è largo 374px
   in un viewport da 390 e spingeva la pagina 4px oltre. Quattro pixel bastano a
   far comparire la barra di scorrimento orizzontale, che su mobile si nota.
   `break-word` e non `anywhere`: spezza solo quando la parola non ci sta
   davvero, invece che a ogni occasione. */
.prose, .post-body { overflow-wrap: break-word; }
.post-body { max-width: 68ch; padding-block: 32px clamp(56px, 9vw, 104px); }
.post-body > p, .post-body > ul, .post-body > ol { margin: 0 0 20px; }
.post-body h2 { margin: 44px 0 14px; }
.post-body h3 { margin: 32px 0 10px; font-size: 19px; font-weight: 620; }
.post-body ul, .post-body ol { padding-left: 22px; }
.post-body li { margin: 8px 0; }
.post-body img { max-width: 100%; height: auto; margin: 28px 0; }
.post-body blockquote {
  margin: 28px 0; padding-left: 20px;
  border-left: 3px solid var(--yellow, #f4c430); color: var(--soft, #57524a);
}
.post-body pre { overflow-x: auto; padding: 16px; background: rgba(0,0,0,.04); }

/* Pagine ricostruite dall'albero Elementor (build_pagine.py). Ogni contenitore
   di primo livello diventa una .sec, e due di fila sommavano 176px di vuoto.
   ⚠️ La regola era `.sec + .sec`, che azzerava il respiro anche sopra le fasce
   con un fondo proprio: dalla seconda sezione in poi il titolo stava incollato
   al bordo della banda. Ora la classe la mette `cuci_sezioni()` in fase di
   generazione, e solo quando il fondo è davvero lo stesso di prima. */
.sec.continua { padding-top: 0; }
/* Solo `/it/servizi/` ed `/en/services/` (assegnata in build_services.py,
   vedi `solo_titolo`): un titolo (+ sottotitolo) isolato da una sezione
   `blocks_of()` non riusciva a fondere col blocco successivo — restava un
   vuoto largo quanto un'intera sezione fra due frasi che su WordPress stanno
   insieme. 16px, non 0: misurato dal vivo su `?__lane=blue` il distacco fra
   «No matter your Industry» e la frase sotto — a 0 le due frasi si toccavano,
   separate solo dall'interlinea. Trovato dal vivo il 2026-09-06. */
.sec-titolo-solo { padding-bottom: 16px; }
/* ⚠️ Qui c'era `.sec:has(> .wrap > .fluentform) { padding-top: 0 }`. Colpiva
   due cose sole: `.sec-modulo`, che il padding a zero se lo dà già da sé più
   sotto, e `.sec-quiz` — dove era un difetto. Sulla home il questionario è una
   fascia BIANCA subito sotto una nera: con padding-top 0 il titolo «Non sei
   ancora sicuro delle tue esigenze?» stava incollato al bordo, a 0px dalla
   giuntura. In produzione ce ne sono 56 (misurato il 2026-08-22).
   È lo stesso difetto che questo file racconta per la vecchia `.sec + .sec`,
   entrato da un'altra porta. Cancellata invece che aggirata. */
.ff-form-title, .fluentform .ff-el-group > .ff-el-input--label:empty { display: none; }
.sec > .wrap > h2 + .prose, .sec > .wrap > h1 + .prose { margin-top: 14px; }

/* Immagini nelle pagine ridisegnate dall'albero Elementor. Senza vincolo un logo
   cliente da 1200px riempie la colonna: nell'originale la misura la dava il CSS
   per-elemento di Elementor, che qui non c'è. */
/* Un'immagine isolata dentro una sezione: a piena larghezza un ritratto
   1920×2483 diventava alto 2.500px e occupava tre schermate da solo.
   ⚠️ Centrarla la staccava dalla colonna di testo e la incollava al pulsante
   sopra: resta allineata a sinistra come tutto il resto, con la sua aria. */
.sec > .wrap > img { max-width: 100%; height: auto; display: block;
  /* ⚠️ 46vh su un'illustrazione quadrata da 1080px la faceva alta 374px:
     un'icona di calendario grande come mezzo schermo. Un'immagine isolata
     dentro una sezione di testo è un'illustrazione, non il contenuto. */
  max-height: 320px; max-width: min(100%, 400px); width: auto; margin-top: 34px; }
.sec > .wrap > .loghi { display: flex; flex-wrap: wrap; gap: 32px; align-items: center; }
.sec > .wrap > .loghi img { max-height: 56px; width: auto; opacity: .85; }
.quotes .quote + p { margin-top: -6px; color: var(--ink-faint); font-size: 14px; }

/* Testimonianze: per ogni cliente logo, video e citazione. Senza raggrupparle si
   ottengono dieci lettori video a piena altezza impilati. */
.testimonianze { display: grid; gap: 40px; margin-top: 36px; align-items: start;
  /* ⚠️ `min(340px, 100%)` e non `340px`: a 320px la colonna restava larga 340 e
     la pagina usciva a 360 — misurato su `_anteprima/reviews` (sei
     `article.testimonianza`) e su `_anteprima/about-us` (`div.reparto`).
     Con `min()` la colonna non supera mai il contenitore. */
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); }
.testimonianza { border: 1px solid var(--rule); padding: 24px; display: grid; gap: 16px; }
.testimonianza .marchio { width: auto; max-width: 300px; justify-self: start; }
.testimonianza .marchio { filter: none; }
.testimonianza .video { aspect-ratio: 16/9; }
.testimonianza .video iframe { width: 100%; height: 100%; border: 0; }
.testimonianza blockquote { margin: 0; }
.sec .wrap > img[src*="logo"] { max-height: 60px; width: auto; }

/* Evidenziatore del marchio: nell'originale «FREE CALL» ha fondo giallo e testo
   nero, non testo giallo. È il device che regge i titoli di tutte le landing. */
.mark { background: var(--yellow); color: #0d0d0d; padding: 0 .16em; }

/* Il modulo sta su una scheda chiara che scavalca l'eroe scuro: è così
   nell'originale, ed è ciò che dà contrasto ai campi. */
.sec-modulo { background: transparent; padding-top: 0; }
/* ⚠️ Il respiro fra la testata del modulo e il primo campo. Dal 2026-09-03 le
   pagine lavoro hanno un <h2> e un sottotitolo SOPRA il modulo — prima il
   modulo attaccava direttamente al bordo — e senza questo la riga «Compila il
   form…» finisce incollata all'etichetta «Nome», che sembra la didascalia del
   campo invece dell'introduzione della sezione. */
.sec-modulo > .wrap > .sec-sub { margin-bottom: 26px; }
.sec-modulo > .wrap { background: #fff; color: #16150f; padding: clamp(28px,5vw,56px);
  position: relative; }
/* ⚠️ La scheda risale sull'eroe SOLO se viene subito dopo l'eroe. Applicata
   ovunque, su work-with-us mangiava il titolo «Fill the form on the right»
   che la precede. */
.hero + .sec-modulo > .wrap { margin-top: clamp(-120px, -9vw, -48px); }
.sec-modulo .ff-el-input--label label { color: #16150f; font-weight: 600; }
.sec-modulo .ff-el-form-control {
  background: #f7f7f5; border: 1px solid #dcdcd6; border-radius: 6px;
  padding: 14px 16px; font-size: 15px; color: #16150f; width: 100%;
}
.sec-modulo .ff-el-form-control:focus {
  outline: none; border-color: var(--yellow); background: #fff;
}
.sec-modulo .ff-el-form-control::placeholder { color: #9a9a92; }
.sec-modulo .ff-el-is-error .text-danger, .sec-modulo .ff-el-input--label.asterisk-right label:after,
.sec-modulo .ff_t_c label a { color: #c0392b; }
.sec-modulo .ff-btn-submit {
  background: var(--yellow); color: #0d0d0d; border: 0; border-radius: 6px;
  font-family: var(--display); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; padding: 16px 30px; cursor: pointer;
}
.sec-modulo .ff-btn-submit:hover { background: #ffe14d; }

/* Quando un titolo contiene l'evidenziatore, il resto va in bianco: giallo su
   giallo-evidenziato non si legge, e nell'originale «Book a» è bianco. */
.hero h1:has(.mark) { color: #fff; }

/* ── Il titolo dell'eroe, con le bande gialle ────────────────────────────────
   MISURATO in produzione il 2026-08-22. Le misure sono a scalini, non fluide:
   **56px** da 1025 in su, **36px** fra 768 e 1024, **22px** da 767 in giù.
   L'interlinea è sempre 1,3 (72,8 su 56; 46,8 su 36; 28,6 su 22).

   ⚠️ Lo stacco fra le bande NON si disegna: nasce dalla differenza fra
   interlinea e altezza della banda. In produzione la banda è alta 68 dentro
   un'interlinea di 72,8, e restano ~5px di nero. Qui la banda usciva 76 dentro
   71,92 — più ALTA della riga — e le bande si sovrapponevano di 5px, saldate
   in un blocco unico. La colpa è del padding verticale `.06em` di `.mark`: in
   produzione il padding è `0px 5px`, orizzontale e basta. */
/* ⚠️ `text-wrap: balance` (riga 59, su tutti gli h1/h2/h3) pareggia le righe;
   la produzione invece RIEMPIE. Con lo stesso corpo e lo stesso font le bande
   uscivano 896+817 invece di 1106+623, e il titolo andava a capo dopo «and»
   invece che dopo «Start» — la differenza che l'handoff attribuiva al corpo del
   carattere, e che invece era il bilanciamento. Sugli altri titoli `balance`
   resta: qui si toglie perché la parità lo chiede. */
.hero h1:has(.mark) { font-size: var(--titolo-eroe); line-height: 1.3; text-wrap: wrap; }
/* ⚠️ Il padding di `.mark` nell'eroe sta più sotto, nel blocco `.hero-home`:
   una definizione sola, non due a distanza di 500 righe. */
.sec-dark h2:has(.mark), .sec-dark h3:has(.mark) { color: #fff; }

/* Il campo trappola antispam di CleanTalk: sul mirror lo nasconde il CSS del
   plugin, che qui non carichiamo. Lasciato visibile è un riquadro vuoto sotto
   il pulsante di invio. */
input[name^="apbct"], .apbct-email-encoder, .ff-el-group input[id^="apbct"] { display: none !important; }

/* Link di salto al contenuto: visibile solo con la tastiera. */
/* Testo per i soli lettori di schermo. ⚠️ NON `display:none` e non un
   `aria-label`: nella fonte quel testo sta nel documento, e va lasciato dove
   sta — un attributo non lo sostituisce ne' per chi legge con uno screen
   reader ne' per il collaudo, che confronta il testo della pagina. */
.solo-lettori {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
/* ⚠️ Le stelle NON si ricolorano qui. Piu' in basso in questo stesso foglio
   c'e' gia' `.stelle { color: #8a6600 }` con scritto accanto perche':
   `--yellow-deep` su bianco fa 2,00:1 e le stelle sono caratteri, quindi ogni
   verifica automatica le misura come testo. La prima stesura di queste righe
   riscriveva quel colore con `.quote .stelle`, che essendo piu' specifica
   vinceva sulla regola accessibile — un avviso scritto nel file non basta a
   fermare chi aggiunge una regola piu' specifica duecento righe piu' su.
   Il colore lo decide la regola sotto, per tutte le stelle del sito. */

.skip { position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--yellow); color:#0d0d0d; padding:12px 18px; font-weight:700; }
.skip:focus { left:0; }

/* Torna su: stessa posizione (basso a sinistra) e stesso trigger a scroll
   della produzione (#ast-scroll-top del tema Astra). 48px, non 40: il
   bersaglio tattile più piccolo del sito era proprio questo genere di
   pulsante fisso. */
.scroll-top {
  position: fixed; left: 30px; bottom: 30px; z-index: 30;
  width: 48px; height: 48px; border: 0; border-radius: 50%;
  background: #0d0d0d; cursor: pointer;
  opacity: 0; pointer-events: none; transform: translateY(8px);
  transition: opacity .2s ease, transform .2s ease;
}
.scroll-top.visibile { opacity: 1; pointer-events: auto; transform: translateY(0); }
.scroll-top::before {
  content: ''; position: absolute; inset: 0; margin: auto;
  width: 10px; height: 10px; border: 2px solid #fff; border-width: 2px 0 0 2px;
  transform: translateY(2px) rotate(45deg);
}
.scroll-top:hover { background: var(--yellow); }
.scroll-top:hover::before { border-color: #0d0d0d; }
.scroll-top:focus-visible { outline: 3px solid var(--yellow); outline-offset: 3px; }
@media (max-width: 560px) { .scroll-top { left: 16px; bottom: 16px; } }
@media (prefers-reduced-motion: reduce) { .scroll-top { transition: opacity .2s ease; transform: none; } }
/* ⚠️ Segnalato da Tony il 2026-09-05: sulle pagine con `.sticky-cta` (la
   barra d'invito fissa in fondo) il pulsante torna-su ci finiva sopra,
   coprendo il testo/pulsante della barra — succedeva perché entrambi sono
   ancorati a `bottom: 0` nella stessa fascia. Quando la pagina ha una
   `.sticky-cta`, il torna-su si alza sopra la barra invece di starci dentro.
   110px basta sul desktop, dove la barra sta su una riga sola (misurata
   ~75px + margine). Sotto i 560px la barra va su due righe (vedi il blocco
   `.sticky-cta` più sopra) ed è alta ~116px: serve un valore più alto — QUI,
   non là, perché a parità di specificità vince la regola scritta dopo nel
   foglio, con o senza media query. Misurato con un harness di prova il
   2026-09-06 dopo che il primo tentativo (scritto nel blocco `.sticky-cta`)
   risultava sempre ignorato. */
body:has(.sticky-cta) .scroll-top { bottom: 110px; }
@media (max-width: 560px) { body:has(.sticky-cta) .scroll-top { bottom: 132px; } }

/* ── Correzioni dopo la revisione a due giudici sulla pagina contatti ────────
   I difetti erano tutti dello stesso tipo: componenti nati per la fascia scura
   riusati su fondo chiaro, dove i loro colori non hanno contrasto. */

/* Le quattro tappe del processo vivono in una sezione chiara, non in .sec-dark:
   con i colori originali erano 1,4:1 su bianco, cioè invisibili. */
.sec:not(.sec-dark) .kpi { border-color: var(--rule); }
.sec:not(.sec-dark) .kpi b { color: var(--ink); }
.sec:not(.sec-dark) .kpi span { color: var(--ink-soft); }

/* La scheda del modulo: bianco su bianco in tema chiaro faceva sparire il
   contenitore. Serve un bordo che la stacchi in entrambi i temi. */
.sec-modulo > .wrap { border: 1px solid var(--rule); box-shadow: 0 18px 48px rgba(0,0,0,.10); }

/* I campi ereditavano Arial e la textarea il monospace del browser. */
/* ⚠️ 16px, non 15: sotto i 16px iOS Safari INGRANDISCE la pagina appena si
   tocca un campo, e chi compila deve ripizzicare per rimpicciolire — sul
   modulo principale di conversione del sito. La produzione usa 18px sul
   desktop e 16,4 sul telefono, quindi era anche una regressione. Misurato da
   un giudice il 2026-08-23: 5 campi su 5 sotto soglia.
   ⚠️ Questa regola vince su quella a riga ~616: due definizioni per lo stesso
   elemento, ancora. Se un giorno si consolidano, il corpo va tenuto >= 16. */
.sec-modulo .ff-el-form-control { font: inherit; font-size: 16px; }
.sec-modulo .ff-el-form-control::placeholder { color: #6b6b64; }   /* era 2,64:1 */
.sec-modulo .ff-btn-submit { font-size: 16px; }

/* Il rosso degli obbligatori: la regola di FluentForm ha specificità più alta
   della nostra e usa una variabile che il CSS mancante non definiva mai. */
.sec-modulo { --fluentform-danger: #c0392b; }
.sec-modulo .ff_t_c a, .sec-modulo .ff-el-input--label.ff-el-is-required label:after { color: #c0392b; }
.sec-modulo input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--yellow); }

/* Il focus era spento da una regola più specifica e sostituito da un bordo
   giallo che su bianco fa 1,42:1: chi naviga da tastiera non vedeva dov'era. */
.sec-modulo .ff-el-form-control:focus-visible,
.sec-modulo .ff-btn-submit:focus-visible {
  outline: 3px solid #0d0d0d; outline-offset: 2px; border-color: #0d0d0d;
}

/* (storico) .sec + .sec azzerava la spaziatura anche alle fasce con sfondo: il filetto
   del titolo cadeva esattamente sul bordo della fascia. */
.sec-modulo + .sec { padding-top: clamp(48px, 8vw, 88px); }

/* L'evidenziatore su più righe: senza clone il padding va solo al primo e
   all'ultimo frammento e le bande si toccano. */
.mark { -webkit-box-decoration-break: clone; box-decoration-break: clone;
  padding: .06em .16em; }
h2 .mark, h3 .mark { line-height: 1.45; }

/* ⚠️ Dal 2026-09-05 l'intestazione TORNA ad agganciarsi allo scroll
   (`.site-head` è `position: sticky`, vedi sopra) — questo commento diceva il
   contrario da quando `is-stuck` era stato tolto il 2026-08-21. Un'ancora ora
   ha davvero una barra da scavalcare: 121px resta comunque sufficiente
   perché copre il caso peggiore, l'header a riposo (101px + ~20 di margine);
   agganciato (`is-stuck`, 62px) lascia solo più margine del necessario, mai
   un problema. Tarato sul valore desktop e usato anche sul telefono, dove
   l'header è ancora più basso (59px, 48 agganciato). */
html { scroll-behavior: smooth; scroll-padding-top: 121px; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* I passi di un processo: elenco ordinato, non griglia di metriche. Il numero è
   una posizione — piccolo e in alto a sinistra — non un dato da 54px al centro. */
.passi { list-style: none; margin: 34px 0 0; padding: 0; counter-reset: none;
  display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.passi li { display: grid; gap: 8px; align-content: start;
  padding: 20px 20px 22px; border: 1px solid var(--rule);
  border-top: 3px solid var(--yellow); }
.passi li b { font-family: var(--display); font-size: 26px; font-weight: 700;
  line-height: 1; color: var(--ink); }
.passi li span { font-size: 16px; line-height: 1.45; color: var(--ink); }
.sec-dark .passi li { border-color: #2e2e2e; border-top-color: var(--yellow); }
.sec-dark .passi li b { color: var(--yellow); }
.sec-dark .passi li span { color: #e4e4e0; }

/* Una pagina che porta già un modulo non ha bisogno del richiamo finale ai
   contatti: è l'elemento più grande della pagina e rimanda dove sei già. */
/* ⚠️ La regola nasconde il richiamo finale sulle pagine che portano già un
   modulo di contatto. Sulla home il modulo è un QUESTIONARIO di
   qualificazione a metà pagina, non un contatto: senza questa eccezione
   la pagina più visitata del sito finiva senza chiamata all'azione. */
/* ⚠️ `:not(.home)` non escludeva niente: la classe della home e'
   `page-home`, e `home` da sola non esiste in nessun body del sito. La
   regola colpiva quindi anche le due home, e l'eccezione descritta qui
   sopra non ha mai funzionato — la pagina piu' visitata usciva senza
   chiamata all'azione finale, cioe' proprio cio' che il commento voleva
   evitare. Misurato: `SECTION.foot-cta 0x0 none`, `<h2>Contattaci</h2>`
   nel DOM e invisibile. Stessa famiglia del `.hero-occhiello` inerte:
   un selettore che non seleziona non da' nessun errore.
   Pagine con `ha-modulo`: quattro, di cui due sono le home; sulle altre
   due la fonte non mostra la fascia (verificato su /it/contatti/). */
body.ha-modulo:not(.page-home) .foot-cta { display: none; }

/* Titolo e pulsante in una fascia: erano due inline-block che si contendevano la
   riga, col bottone incollato 3px dopo il titolo e allineato alla sua ultima
   riga. Con la griglia il titolo respira e l'azione sta al suo posto. */
.sec-azione > .wrap {
  display: grid; grid-template-columns: minmax(0, 1.5fr) auto;
  align-items: center; gap: clamp(24px, 4vw, 56px);
}
.sec-azione > .wrap > h2 { max-width: 34ch; margin: 0; }
.sec-azione > .wrap > .hero-cta { margin-top: 0; }
@media (max-width: 720px) {
  .sec-azione > .wrap { grid-template-columns: 1fr; }
}

/* Le posizioni aperte: un elenco cliccabile, non una griglia di schede — sono
   poche e cambiano spesso. */
.offerte { list-style: none; margin: 30px 0 0; padding: 0; border-top: 1px solid var(--rule); }
.offerte li { border-bottom: 1px solid var(--rule); }
/* ⚠️ La riga non e' piu' solo «titolo → Candidati»: sotto c'e' l'attacco
   dell'annuncio, che l'archivio di WordPress stampa e noi perdevamo. Quindi la
   colonna, e la testa resta una riga sua con il titolo e la freccia ai due
   capi. */
.offerte a { display: flex; flex-direction: column; gap: 8px;
             padding: 22px 0; text-decoration: none; color: inherit;
             transition: padding-left .15s ease; }
.offerta-testa { display: flex; justify-content: space-between;
                 align-items: baseline; gap: 20px; }
.offerta-gancio { font-size: 14.5px; line-height: 1.5; color: var(--ink-faint);
                  max-width: 78ch; }
.sec-dark .offerta-gancio { color: #c9c9c4; }
.offerte a:hover { padding-left: 12px; }
/* ⚠️ `.offerte a span` prendeva anche l'attacco e la testa, che ora sono
   <span> pure loro: il titolo si seleziona per posizione dentro la testa. */
.offerta-testa > h3 {
  font-family: var(--display); font-weight: 600; font-size: 18px;
  margin: 0; line-height: inherit; }
.offerta-invito { font-style: normal; font-size: 13px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink); white-space: nowrap; }
.sec-dark .offerta-invito { color: var(--yellow); }
.sec-dark .offerte, .sec-dark .offerte li { border-color: #2e2e2e; }

/* Un pulsante dentro una griglia non deve stirarsi a tutta colonna. */
.hero-cta { justify-self: start; width: fit-content; }


/* Fascia loghi clienti (widget image-carousel: qui sono loghi davvero, lo dice
   il tipo di widget). Scorre orizzontalmente invece di impilarsi. */
.loghi { display: flex; flex-wrap: wrap; gap: 34px 52px; align-items: center; margin-top: 30px; }
/* L'altezza di ciascun marchio la calcola `ritaglia_marchi.py` (area costante)
   e la scrive inline: qui si dice solo come si comportano insieme. */
.loghi img { width: auto; max-width: 300px; opacity: .9; filter: grayscale(1); }
.loghi img:hover { opacity: 1; filter: none; }
.sec-dark .loghi img { filter: grayscale(1) invert(1) brightness(1.6); opacity: .85; }

/* ⚠️ La variante `.riquadro` in griglia di questo ramo e' stata TOLTA, non
   dimenticata. Stilava l'image-box, ma essendo scritta dopo la regola delle
   celle statistiche (piu' su in questo foglio) le sovrascriveva tutte e 612:
   la correzione che portava — la prima colonna che cresce per «+2.279,56%» —
   funzionava solo grazie a quella collisione. Con `.promessa` le due cose
   sono separate e il numero non ha piu' una colonna da sfondare: la cella
   statistica e' una colonna flex, valore sopra ed etichetta sotto. */
/* image-box: immagine con titolo e testo — le "due promesse" della home,
   uniche istanze di questo widget su tutto il sito (2 IT + 2 EN, cercato
   `widgetType":"image-box"` su tutti i dump grezzi).
   ⚠️ Classe `.promessa`, non `.riquadro`: quel nome è già preso, più sotto
   in questo foglio, dalle 612 celle statistiche delle pagine servizio
   (`+22,3% ROAS` e simili). Stessa specificità, nessuno scoping — la
   regola scritta per ultima vince su ogni proprietà condivisa. Trovato in
   review il 2026-09-04 dopo che una correzione pensata per queste 4 celle
   aveva silenziosamente cambiato anche le 612 (icona centrata invece che a
   bandiera su 40 pagine servizio, mai visto perché non è nell'HTML).
   ⚠️ Corretto lo stesso giorno: la produzione usa `elementor-position-top`
   su entrambe le istanze reali, nessuna delle due porta un `position`
   esplicito nelle impostazioni — è il default vero di Elementor, icona
   sopra e centrata, non accanto. Il commento precedente («sta accanto: è
   un'etichetta») descriveva un problema di un tentativo passato — l'icona
   senza un limite di larghezza occupava tutta la riga — non una scelta di
   produzione: qui il limite c'è (84px), quindi lo stesso problema non si
   ripresenta. */
.promessa { display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 14px; margin-top: 8px; }
.promessa img { max-width: 84px; height: auto; }
.promessa h3 { font-size: 20px; font-weight: 620; margin: 0; }

/* Il footer raggruppa i servizi sotto un'intestazione, come l'originale: in fila
   con gli altri link la sezione non si distingueva. */
.foot-gruppo { display: block; margin: 18px 0 6px; font-family: var(--display);
  font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--yellow); }
.foot-links a.foot-sub { padding-left: 14px; position: relative; }
.foot-links a.foot-sub::before { content: ""; position: absolute; left: 0; top: .9em;
  width: 6px; height: 1px; background: currentColor; opacity: .5; }
.foot-prefs { background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: inherit; text-decoration: underline; text-underline-offset: 3px; }

/* ── Footer allineato a quello di WordPress ─────────────────────────────────
   Le differenze non erano nei link ma nella disposizione: i riconoscimenti in
   un riquadro bianco a colori nella colonna destra, «Follow us» con le icone
   sulla stessa riga, le due sedi affiancate, il pulsante sotto i link. */

.foot-col { display: grid; gap: 26px; align-content: start; }

/* I riconoscimenti stanno su un riquadro bianco perché sono loghi a colori
   pensati per fondo chiaro: in grigio su nero non si leggevano e avevano
   altezze diverse fra loro. */
.foot-badges {
  background: #fff; border-radius: 4px; padding: 14px 18px;
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 18px;
}
.foot-badges img { height: 34px; width: auto; object-fit: contain; }

/* Le due sedi affiancate, come nell'originale. */
.foot-offices { display: grid; gap: 26px; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }

/* «Follow us» e le icone sulla stessa riga: erano impilati, e i link a testo
   occupavano una riga intera ciascuno. */
.foot-follow { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.foot-follow h3 { margin: 0; font-family: var(--display); font-size: 17px;
  font-weight: 700; color: var(--yellow); letter-spacing: .01em; text-transform: none; }
/* ⚠️ 44x44, come `.lang-flags a` (riga 159): l'icona resta 18px, il riquadro che
   si tocca no. Prima erano 18x24 — l'unico bersaglio tattile rimasto sotto i
   40px fra le note ancora aperte di HQ-11847. Stesso `gap` di `.lang-flags`
   per lo stesso motivo: coi riquadri più larghi un gap più ampio le sparpaglia.
   ⚠️ Tolta da qui in giù anche la prima definizione di `.foot-follow h3` e
   `.foot-social`/`.foot-social a` (righe ~232 e ~252 di prima): due regole più
   vecchie sugli stessi selettori, già del tutto coperte da quelle qui sotto —
   cascata innocua finché non si tocca uno dei due punti, poi diventa il posto
   sbagliato dove cercare. Trovato in review. */
.foot-social { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.foot-social a {
  width: 44px; height: 44px; display: inline-flex; align-items: center;
  justify-content: center; color: #cfcfc9; text-decoration: none;
  transition: color .15s ease;
}
.foot-social a:hover { color: var(--yellow); }

.foot-right { display: grid; gap: 26px; align-content: start; }

/* Proporzioni del footer: la colonna centrale era 221px, troppo stretta — il
   pulsante andava a tre righe e gli indirizzi spezzavano «Via Generale Giordano
   / Orsini 5». Misurato, non stimato. */
.foot-grid { grid-template-columns: minmax(0, 1.15fr) minmax(230px, .95fr) minmax(0, 1.5fr); }
.foot-consult { justify-self: start; }
@media (min-width: 721px) { .foot-consult { white-space: nowrap; } }
.foot-offices { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

/* I loghi dei riconoscimenti hanno proporzioni molto diverse fra loro: vincolare
   l'altezza li lasciava a 28-59px di larghezza dentro un riquadro da 387. Si
   vincola la larghezza e si lascia libera l'altezza, con un tetto. */
.foot-badges img { height: auto; max-height: 44px; width: auto; max-width: 84px; }
@media (max-width: 900px) {
  .foot-grid { grid-template-columns: 1fr; }
}

/* Fascia gialla: nell'originale alcune sezioni hanno il giallo del marchio come
   fondo pieno. Il testo va scuro, non bianco. */
.sec-giallo { background: var(--yellow); color: #0d0d0d; }
.sec-giallo h2, .sec-giallo h3 { color: #0d0d0d; }
.sec-giallo .prose { color: #24220c; }
.sec-giallo .hero-cta { background: #0d0d0d; color: var(--yellow); }

/* ── Moduli a più passi: resi a pagina unica ─────────────────────────────────
   ⚠️ Difetto grave, non estetico. FluentForm nasconde i passi successivi con
   `.fluentform-step { display:none }` e li rivela aggiungendo `.active` dal suo
   JavaScript — che sul sito statico non gira, perché forms.js clona il form per
   riprendere il controllo dell'invio.
   Risultato misurato sul modulo candidature: 4 campi visibili su 14, «Avanti»
   inerte, e il pulsante di invio MAI raggiungibile. Il canale candidature
   sarebbe morto.
   Rimedio: si mostrano tutti i passi e si nascondono i comandi che non
   funzionano. Il modulo diventa una pagina sola — più lunga, ma completa. */
.fluentform-step { display: block !important; float: none !important;
  height: auto !important; width: 100% !important; overflow: visible !important; }
.ff-step-container, .ff-step-body { width: 100% !important; transform: none !important;
  overflow: visible !important; }
/* ⚠️ I comandi restano nascosti finché il passo-passo NON è cablato: se il JS
   non gira, il modulo deve restare a pagina unica e inviabile. La classe
   `ff-passi` la mette forms.js solo a cablaggio riuscito. */
.ff-step-header, .step-nav, .ff-el-progress { display: none !important; }

form.ff-passi .fluentform-step { display: none !important; }
/* ⚠️ `display: block` NON basta. Il foglio del plugin tiene ogni passo a
   `float:left; height:1px; overflow-x:hidden` e lo apre solo con `.active`.
   Mostrando il passo senza annullare quelle tre proprietà si ottiene una
   scatola alta 1px: misurata sul passo 2, altezza 3px con dentro un campo
   invisibile. Il modulo sembrava avanzare e non mostrava niente. */
form.ff-passi .fluentform-step.attivo {
  display: block !important; float: none !important; height: auto !important;
  width: 100% !important; overflow: visible !important; }
form.ff-passi .fluentform-step + .fluentform-step { margin-top: 0; padding-top: 0;
  border-top: 0; }
/* ⚠️ La barra vive dentro `.ff-step-header`, che la regola sopra nasconde:
   scoprire il figlio non basta se il padre resta `display:none`. */
form.ff-passi .ff-step-header { display: block !important; }
form.ff-passi .ff-el-progress { display: block !important; margin-bottom: 22px; }
/* ⚠️ Misurata sulla fonte: 16,2px/400 rgb(13,13,13), riga alta 27. Da noi era
   13px/600 in grigio chiaro — la meta' del corpo, e sbiadita. */
form.ff-passi .ff-el-progress-status { font-family: var(--display); font-weight: 400;
  font-size: 16.2px; letter-spacing: .04em; color: #0d0d0d; margin-bottom: 8px; }
/* pista e riempimento sono definiti più sotto, in un punto solo:
   `.ff-el-progress` = pista, `.ff-el-progress-bar` = riempimento. */
form.ff-passi .step-nav { display: flex !important; gap: 12px; margin-top: 26px;
  justify-content: flex-end; }
form.ff-passi button.ff-btn-next, form.ff-passi button.ff-btn-prev {
  font-family: var(--display); font-weight: 600; font-size: 14px; letter-spacing: .06em;
  text-transform: uppercase; border: 0; border-radius: 6px; padding: 15px 30px;
  cursor: pointer; float: none !important; box-shadow: none; }
form.ff-passi button.ff-btn-next {
  background: var(--yellow) !important; color: #0d0d0d !important; }
form.ff-passi button.ff-btn-prev {
  background: transparent !important; color: #6e6e6e !important;
  border: 1px solid #d8d8d4 !important; }
/* al primo passo non si torna indietro, all'ultimo non si va avanti */
form.ff-passi .fluentform-step:first-of-type button.ff-btn-prev,
form.ff-passi .fluentform-step:last-of-type button.ff-btn-next { display: none; }
form.ff-passi .ff-manca { outline: 2px solid #c0392b; outline-offset: 6px; border-radius: 4px; }

/* Le quattro scelte devono leggersi come quattro scelte, non come una tabella. */
/* Le quattro scelte devono leggersi come quattro scelte, non come una tabella:
   nell'originale sono separate da 14-15px, qui condividevano i bordi. */
.ff_item_selectable_wrapper { display: flex !important; flex-wrap: wrap; gap: 14px; }
.ff_item_selectable_wrapper .ff_item_selectable {
  border-radius: 10px; border: 1px solid #e0e0dc !important; flex: 1 1 170px; }
.ff_item_selectable_wrapper .ff_item_selectable:hover { border-color: var(--yellow) !important; }

/* Le sezioni del modulo, ora che sono tutte in fila, hanno bisogno di respiro. */
.fluentform-step + .fluentform-step { margin-top: 26px; padding-top: 26px;
  border-top: 1px solid var(--rule); }

/* ── Rifiniture di accessibilità e uso ───────────────────────────────────────
   Misurate: la casella del consenso era 13×13 px (minimo raccomandato 24), i
   link delle policy nel footer avevano un'area di tocco alta 17 px, e tre testi
   scendevano sotto i 13 px. */
input[type="checkbox"], input[type="radio"] {
  width: 22px; height: 22px; accent-color: var(--yellow); flex: 0 0 auto;
}
.ff-el-form-check label, .ff_t_c label {
  display: flex; align-items: flex-start; gap: 10px; line-height: 1.5;
}
.foot-policies a, .foot-prefs { padding: 6px 0; display: inline-block; }
.foot-legal, .foot-badges + .foot-bottom, .galleria li span { font-size: 13px; }
.hero-eyebrow { min-height: 24px; }

/* Le immagini nelle pagine ridisegnate non devono far saltare il testo mentre
   caricano: se il generatore non ha trovato le dimensioni, almeno non collassano. */
.sec img:not([width]) { min-height: 1px; }

/* ── /about-us/ : impaginazione dichiarata a mano ────────────────────────── */
.hero-azioni { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 32px; }
/* `.hero` è `text-align: center` e centra il resto del contenuto (h1, hero-hook),
   ma un flex-container non eredita text-align: senza questa riga i due pulsanti
   restavano allineati a sinistra sotto un testo centrato. Segnalato su chi-siamo
   (e uguale su about-us, stessa impaginazione). */
.hero .hero-azioni { justify-content: center; }
.hero .hero-hook { max-width: 62ch; margin-top: 18px; }

.storia { display: grid; gap: clamp(28px, 5vw, 64px);
  grid-template-columns: minmax(0, 1.35fr) minmax(0, .8fr); align-items: start; }
.storia img { width: 100%; height: auto; }
@media (max-width: 820px) { .storia { grid-template-columns: 1fr; } }

.titolo-minore { font-size: var(--titolo-minore); }

/* La formula del metodo: una riga sola, non cinque sezioni impilate. */
.formula { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px 18px;
  margin: 30px 0 26px; }
/* ⚠️ Scritto `800` dal 2026-08-18, ma fino al 2026-09-04 Montserrat non
   aveva quella faccia (vedi fonts.css): rendeva 700, ed è quello che è
   stato tarato a occhio su questa pagina («metodo TCR», /it/chi-siamo/ e
   /en/about-us/, non toccate in questo giro). Ora che la faccia 800 esiste
   davvero renderebbe diverso — fissato a 700 apposta, per non cambiare due
   pagine fuori dal perimetro di oggi con un effetto collaterale del fix del
   font. Un peso più alto qui è una decisione a sé, da guardare e approvare
   su quelle pagine, non un side-effect. */
.formula .sigla { font-family: var(--display); font-weight: 700;
  font-size: clamp(38px, 6vw, 66px); line-height: 1; color: var(--yellow); }
.formula .segno { font-family: var(--display); font-weight: 700;
  font-size: clamp(24px, 3.4vw, 38px); color: #8f8f8a; }
.formula .voce { font-family: var(--display); font-weight: 600;
  font-size: clamp(15px, 1.7vw, 19px); letter-spacing: .06em; text-transform: uppercase;
  align-self: center; }

.distintivi { display: grid; gap: 26px; margin-top: 32px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.distintivi article { border-top: 3px solid var(--yellow); padding-top: 18px; }
.distintivi h3 { margin: 0 0 10px; font-size: 20px; font-weight: 620; }

.reparti { display: grid; gap: 44px; margin-top: 34px; }
.reparto > h3 { font-family: var(--display); font-size: 13px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink); margin: 0 0 18px; }
.sec-dark .reparto > h3 { color: var(--yellow); }
.squadra { list-style: none; margin: 0; padding: 0; display: grid; gap: 26px;
  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); }
.squadra li { display: grid; gap: 4px; }
.squadra li img { width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; }
.squadra li b { font-size: 17px; font-weight: 620; margin-top: 8px; }
.squadra li span { font-size: 14px; color: var(--ink-faint); }

/* I due fondatori: scheda larga, ritratto a sinistra, biografia accanto. */
.fondatori { display: grid; gap: 26px;
  /* ⚠️ `min(340px, 100%)` e non `340px`: a 320px la colonna restava larga 340 e
     la pagina usciva a 360 — misurato su `_anteprima/reviews` (sei
     `article.testimonianza`) e su `_anteprima/about-us` (`div.reparto`).
     Con `min()` la colonna non supera mai il contenitore. */
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); }
/* ⚠️ La colonna della foto era 148px con `aspect-ratio: 1`, e i fondatori
   uscivano PIU' PICCOLI dei propri collaboratori: 148x148 loro, 219x219 la
   squadra sotto. Segnalato dal committente — «perche' i fondatori sono piu'
   piccoli?» — ed era esattamente cosi'.
   Misurata la fonte a 1405px: la scheda del fondatore e' 585x374 e il
   ritratto 230x374, verticale, che riempie tutta l'altezza della scheda. Non
   e' quadrato e non e' piccolo: e' la meta' sinistra della scheda.
   ⚠️ `align-items: stretch` e non `start`: con `start` la foto resta alta
   quanto la sua proporzione e la scheda le cresce accanto, che e' come
   nasceva il quadratino. */
.fondatori article { display: grid; grid-template-columns: 230px minmax(0, 1fr);
  gap: 24px; align-items: stretch; }
.fondatori img {
  width: 100%; height: 100%; min-height: 374px;
  object-fit: cover; object-position: top center;
}
.fondatori h3 { margin: 0 0 8px; font-size: 21px; font-weight: 650; }
.fondatori .prose { font-size: 15px; }
.fondatori .prose b { color: var(--ink); font-weight: 620; }
.sec-dark .fondatori .prose b { color: var(--yellow); }
.linkedin { display: inline-block; margin-top: 12px; font-size: 14px; font-weight: 600;
  border-bottom: 2px solid var(--yellow); padding-bottom: 2px; }
@media (max-width: 480px) { .fondatori article { grid-template-columns: 108px minmax(0, 1fr); } }
.fondatori .ruolo { display: block; font-family: var(--display); font-size: 13px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink);
  margin: 0 0 14px; }
.sec-dark .fondatori .ruolo { color: var(--yellow); }
.fondatori .prose br + br { display: none; }

/* Le schede della squadra: le righe si impacchettano in alto, altrimenti quando
   un ruolo va a capo la griglia ridistribuisce lo spazio e quella scheda scivola
   fuori allineamento rispetto alle vicine. */
.squadra li { align-content: start; }
.squadra li b { line-height: 1.25; }
.squadra li span { line-height: 1.4; }

/* Immagini che NON sono loghi: fogli di creatività, ritratti della squadra.
   ⚠️ Erano un nastro con `overflow-x: auto`: i fogli 1920×1080 uscivano larghi
   460px e tagliati sul bordo destro, senza alcun segno che si potesse scorrere.
   In griglia ci stanno tutti; la misura della cella la decide la forma. */
.griglia-img { display: grid; gap: 20px; margin-top: 30px;
  grid-template-columns: repeat(auto-fill, minmax(var(--cella), 1fr)); }
.griglia-img.larga { --cella: 320px; }
.griglia-img.ritratti { --cella: 150px; }
.griglia-img img { width: 100%; height: auto; display: block; }

/* I lavori: il collage merita la misura per essere letto, e un nome — un
   collage senza etichetta non dice di chi è. */
.lavori { display: grid; gap: 26px; margin-top: 30px;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); }
.lavoro { margin: 0; }
.lavoro img { width: 100%; height: auto; display: block; }
.lavoro a { text-decoration: none; color: inherit; display: block; }
.lavoro figcaption {
  margin-top: 10px; font-family: var(--display); font-weight: 620; font-size: 15px;
  border-bottom: 2px solid transparent; display: inline-block;
}
.lavoro a:hover figcaption { border-bottom-color: var(--yellow); }
.sec-dark .lavoro figcaption { color: var(--ink); }

/* Due pulsanti di fila si toccavano: fra loro restava solo lo spazio bianco
   fra due inline-block, cinque pixel, e leggevano come un blocco giallo unico
   diviso da un filo. */
.hero-cta + .hero-cta { margin-left: 14px; }

/* Una testimonianza per cliente: marchio, parole, firma, eventuale video.
   ⚠️ I video sono Vimeo con privacy per dominio: rispondono 200 solo con
   Referer webgas.net e 403 altrove. In anteprima restano neri — è la
   configurazione del video, non il markup. */
.testimonianza { align-content: start; }
.testimonianza .dice { font-size: 16px; }
.testimonianza .dice p { margin: 0 0 12px; }
.testimonianza .firma {
  font-style: normal; font-family: var(--display); font-weight: 600;
  font-size: 14px; color: var(--ink-faint); line-height: 1.5;
}
/* Il ruolo va a capo sotto il nome. Prima lo faceva un <br> dentro il markup,
   e quel <br> spezzava la firma in due righe da due e tre parole: sotto il
   pavimento del collaudo sparivano entrambe e la firma risultava PERSA pur
   essendo tutta lì. La riga la manda a capo lo stile, che è il suo mestiere. */
.testimonianza .firma span { display: block; }

/* L'occhiello sopra il titolo dell'eroe: la fonte lo mette li' su due pagine
   servizio, e completa la frase del titolo — «Cambia le regole del gioco con
   il nostro» / «Siti web e UX». Più piccolo del titolo, stessa famiglia. */
/* ⚠️ Misurato sulla fonte su QUATTRO pagine (risorse, creatives-content,
   gestione-ads-data-driven, ecommerce-design-development): l'occhiello e'
   24px/900 in Open Sans BIANCO, e da noi usciva 15px/600 in Montserrat
   grigio chiaro — piccolo e spento dove la fonte lo fa grande e in evidenza.
   Vale per le 24 pagine che emettono questa classe.
   ⚠️ `hero-occhiello` e `hero-eyebrow` sono DUE NOMI per la stessa cosa, non
   una classe morta: 24 pagine usano il primo, 69 il secondo, e il foglio ha
   regole per entrambi. Il commento piu' sotto che dice «quella classe non
   esiste» vale solo per `page-perche`, dove il markup emette l'altra. */
.hero .hero-occhiello {
  font-family: var(--body); font-weight: 900; font-size: 24px;
  letter-spacing: 0; color: #fff; margin: 0 0 6px;
}
.testimonianza .video { aspect-ratio: 16/9; margin-top: 4px; }
.testimonianza .hero-cta { margin-top: 8px; justify-self: start; font-size: 13px; padding: 13px 22px; }

/* ── la lente: il collage a schermo intero ───────────────────────────────── */
.lavoro .apri {
  display: block; width: 100%; padding: 0; border: 0; background: none;
  cursor: zoom-in; position: relative;
}
.lavoro .apri::after {
  content: ''; position: absolute; inset: 0;
  background: rgba(13, 13, 13, 0); transition: background .16s ease;
}
.lavoro .apri:hover::after { background: rgba(13, 13, 13, .06); }
.lavoro .apri:focus-visible { outline: 3px solid var(--yellow); outline-offset: 3px; }
.lavoro figcaption a { color: inherit; text-decoration: none;
  border-bottom: 2px solid transparent; }
.lavoro figcaption a:hover { border-bottom-color: var(--yellow); }

dialog.lente {
  border: 0; padding: 0; max-width: 100vw; max-height: 100vh;
  width: 100%; height: 100%; background: transparent; overflow: hidden;
}
dialog.lente::backdrop { background: rgba(6, 6, 6, .96); backdrop-filter: blur(6px); }
dialog.lente figure {
  margin: 0; height: 100%;
  display: grid; grid-template-rows: 1fr auto; align-items: center; justify-items: center;
  padding: clamp(16px, 4vw, 52px);
}
dialog.lente img {
  max-width: min(1400px, 92vw); max-height: 82vh;
  width: auto; height: auto; object-fit: contain;
}
dialog.lente figcaption {
  display: flex; gap: 16px; align-items: baseline; padding-top: 16px;
  font-family: var(--display); font-size: 14px; color: #f2f2f0;
}
dialog.lente .conta { color: #8f8f8a; font-variant-numeric: tabular-nums; }
dialog.lente button {
  position: absolute; border: 0; background: rgba(255, 255, 255, .1);
  color: #fff; cursor: pointer; line-height: 1;
  width: 48px; height: 48px; font-size: 30px; border-radius: 50%;
  display: grid; place-items: center; transition: background .15s ease;
}
dialog.lente button:hover { background: var(--yellow); color: #0d0d0d; }
dialog.lente button:focus-visible { outline: 3px solid var(--yellow); outline-offset: 3px; }
dialog.lente .chiudi { top: 18px; right: 18px; font-size: 34px; }
dialog.lente .prec { left: 18px; top: 50%; transform: translateY(-50%); }
dialog.lente .succ { right: 18px; top: 50%; transform: translateY(-50%); }
dialog.lente.sola .prec, dialog.lente.sola .succ { display: none; }
@media (max-width: 560px) {
  dialog.lente .prec { left: 10px; } dialog.lente .succ { right: 10px; }
  dialog.lente button { width: 42px; height: 42px; }
}

dialog.lente[open] { animation: lente-entra .2s ease both; }
@keyframes lente-entra { from { opacity: 0; transform: scale(.985); } }
@media (prefers-reduced-motion: reduce) {
  dialog.lente[open] { animation: none; }
  .lavoro .apri::after { transition: none; }
}

/* ── /portfolio/ : un progetto per fascia ────────────────────────────────── */
.progetto-testa { display: flex; align-items: center; gap: clamp(18px, 3vw, 34px);
  flex-wrap: wrap; }
.progetto-testa .marchio { width: auto; max-width: 190px; }
.sec-progetto h2 { margin: 0; font-size: var(--titolo-fascia); }
.sec-progetto .sec-sub { margin: 6px 0 0; font-size: 16px; color: var(--ink-faint);
  font-style: italic; }
.sec-progetto .prose { margin-top: 22px; max-width: 72ch; }
.sec-progetto .lavori { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.sec-progetto .hero-cta { margin-top: 30px; }


/* ── indice dei lavori: muro dei clienti e navigazione insieme ───────────── */
.indice-lavori {
  /* ⚠️ z-index SOTTO quello di `.site-head` (20), non sopra. Il cassetto del
     menu e' `fixed` ma vive dentro l'intestazione, che con il suo z-index
     forma un contesto a parte: a 40 la striscia passava sopra al cassetto
     aperto e ne copriva le voci. Segnalato da Daniele il 2026-10-16. A 10
     resta comunque sopra al contenuto che le scorre sotto. */
  position: sticky; top: 62px; z-index: 10;
  background: var(--ground); border-bottom: 1px solid var(--rule);
  padding-block: 14px;
}
.indice-lavori > .wrap {
  display: flex; gap: clamp(18px, 3vw, 40px); align-items: center;
  overflow-x: auto; scrollbar-width: thin; padding-block: 4px;
}
.indice-lavori a {
  flex: none; display: grid; place-items: center; min-height: 34px;
  text-decoration: none; opacity: .72; transition: opacity .15s ease;
  border-bottom: 2px solid transparent; padding-bottom: 4px;
}
.indice-lavori a:hover, .indice-lavori a:focus-visible { opacity: 1; }
.indice-lavori a[aria-current="true"] { opacity: 1; border-bottom-color: var(--yellow); }
/* ⚠️ niente `grayscale`: il marchio di un cliente si mostra nei suoi colori.
   Il grigio resta dove è un device voluto — la fascia stampa e i badge partner. */
.indice-lavori img { height: 26px; width: auto; max-width: 116px;
  object-fit: contain; }
.indice-lavori span {
  font-family: var(--display); font-weight: 600; font-size: 13px;
  letter-spacing: .04em; color: var(--ink); white-space: nowrap;
}

/* l'ancora non deve finire sotto le due barre appiccicate */
.sec-progetto { scroll-margin-top: 124px; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
@media (max-width: 720px) {
  .indice-lavori { top: 56px; padding-block: 10px; }
  .indice-lavori img { height: 22px; }
}

/* La colonna segue la forma delle immagini del progetto: quattro ritratti 9:16
   in fila stanno bene, due schermate 16:9 pure — mescolarli in celle uguali no.
   Il verso lo calcola il generatore sul rapporto medio, non il CSS. */
.lavori.verticali { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.lavori.orizzontali { grid-template-columns: repeat(auto-fit, minmax(420px, 1fr)); }
.lavori.quadre { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
@media (max-width: 620px) {
  .lavori.verticali, .lavori.orizzontali, .lavori.quadre {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  }
}

/* ══ home ═══════════════════════════════════════════════════════════════════
   ⚠️ L'eroe deve contenere TUTTO: occhiello, titolo, gancio e azione. Nella
   versione generata paragrafo e pulsante cadevano nella sezione bianca dopo,
   e il primo schermo restava senza una chiamata all'azione. */
.hero-home { position: relative; overflow: hidden; text-align: center;
  padding-block: clamp(90px, 13vh, 150px) clamp(80px, 12vh, 140px); }
.hero-home > .wrap { position: relative; z-index: 2; }
.hero-home .hero-hook { max-width: 62ch; margin: 22px auto 0; }
.hero-home .hero-cta { margin-top: 34px; }

/* Il marcatore giallo: due barre con una gola in mezzo, non una lastra unica.
   `box-decoration-break: clone` è ciò che spezza lo sfondo riga per riga. */
/* ⚠️ Il marcatore è un pennarello, non un mattone: in produzione la banda è
   1,43× l'altezza delle maiuscole, qui era 1,82 e le tre righe si saldavano
   con gole da 3px. line-height e padding verticale sono le due leve. */
/* ⚠️ Qui c'erano `line-height: 1.16` e `padding: 0 .16em`, scritti per lo
   stesso problema e senza misurarlo. Erano entrambi morti o dannosi:
   l'interlinea la fissa ora `.hero h1:has(.mark)` a 1,3, che è più specifica;
   e `box-decoration-break: clone` lo dà già `.mark`.
   Il padding invece VINCEVA su una regola scritta più in alto con la stessa
   specificità, solo perché stava più in basso — la trappola delle due
   definizioni per lo stesso elemento, di nuovo.
   In produzione il padding è `0px 5px` a ogni larghezza: fisso, non in em. */
.hero-home h1 .mark { padding: 0 5px; }
/* l'eroe può respirare più largo del resto della pagina */
.hero-home > .wrap { max-width: 1280px; }
.hero-home .hero-hook { font-weight: 400; }

/* Il grafico che si disegna: sta dietro, non ruba il posto al testo. */
/* ⚠️ Era `position: absolute; inset: auto 4% 0 auto`: il grafico stava
   nell'angolo in basso a destra, DIETRO al testo. Misurato dal secondo giudice
   il 2026-08-22: si sovrapponeva al paragrafo dell'eroe per il 25% a 1405px,
   il 32% a 1024 (dove copriva anche il pulsante) e il **49% a 767** — e sotto
   i 768 usciva dallo schermo, 46px tagliati a 767 e 23 a 390.
   In produzione sta SOTTO la CTA, centrato e libero: a 390px il contenitore è
   370x142 a y=438, mentre la CTA finisce a 324. Qui torna nel flusso. */
.hero-anim { width: min(255px, 62%); margin: 30px auto 0;
  aspect-ratio: 862 / 777; opacity: .9; pointer-events: none; }

.occhiello { font-family: var(--display); font-size: 13px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint); margin: 0 0 6px; }

.promesse { display: grid; gap: clamp(22px, 4vw, 48px);
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

/* I servizi sono schede su fondo pieno, non paragrafi impilati: è il secondo
   componente del sistema, e da solo sblocca metà dei rilievi sulla home. */
/* ── Le caselle dei servizi ──────────────────────────────────────────────────
   MISURATA la produzione il 2026-08-22: NON è una griglia di caselle uguali.
   Sono quattro riquadri in 2x2 **asimmetrico** — riga 1: 576x494 e 576x494;
   riga 2: 720x381 e 420x381 (l'invito al questionario). Tutti con fondo
   TRASPARENTE, bordo `2px rgb(69,69,69)`, raggio 24 e padding 40.
   Il verde ne metteva tre uguali da 384x606 in fila e lasciava la quarta
   orfana su una seconda riga: 3+1, che è il modo peggiore di disporne quattro.
   ⚠️ Flexbox e non grid: le due righe hanno proporzioni DIVERSE (50/50 e
   63/37), e un solo `grid-template-columns` non può descriverle entrambe. */
.servizi { display: flex; flex-wrap: wrap; gap: 24px; margin-top: 36px; }
.servizi > * { flex: 1 1 calc(50% - 12px); }
.servizi > :nth-child(3) { flex: 1 1 calc(63% - 12px); }
.servizi > :nth-child(4) { flex: 1 1 calc(37% - 12px); }
@media (max-width: 767px) { .servizi > * { flex: 1 1 100%; } }
/* ⚠️ `align-content: start` lasciava 185px di fondo vuoto — il 39% della
   scheda — perché la griglia le allunga tutte alla più alta. Il blu
   centra, e infatti lo stesso squilibrio lì non si nota. */
.servizio { background: transparent; border: 2px solid #454545; border-radius: 24px;
  padding: clamp(24px, 3vw, 40px);
  display: grid; align-content: center; gap: 14px; }
.servizio h3 { margin: 0; font-family: var(--display); font-weight: 700;
  font-size: 22px; text-transform: uppercase; letter-spacing: .01em; }
.servizio .prose { font-size: 18px; line-height: 1.6; color: #fff; }
.servizio .hero-cta { border-radius: 6px; justify-self: start; margin-top: 6px; font-size: 13px;
  padding: 13px 22px; text-transform: none; letter-spacing: .02em; }

.missione { border-left: 3px solid var(--yellow); padding-left: 22px; margin: 30px 0; }
.missione .kpi { border: 0; padding: 0; text-align: left; }
.missione .kpi b { font-family: var(--body); font-weight: 600; font-size: 17px;
  display: block; margin-bottom: 8px; color: var(--ink); }
.missione .kpi span { font-size: 20px; font-family: var(--display); font-weight: 600;
  color: var(--yellow); font-size: clamp(18px, 2.2vw, 24px); }

/* Il questionario su fondo scuro, come nell'originale: una scheda bianca su
   bianco con un filetto da 1px non si vede. */
/* Il questionario: 56px sopra e sotto, come in produzione — non gli 88 del
   `.sec` generico. */
.sec-quiz { background: #fff; color: var(--ink); padding-block: 56px; }
.sec-quiz .fluentform { margin-top: 30px; }
.sec-quiz h2, .sec-quiz .sec-sub, .sec-quiz > .wrap > .prose { color: var(--ink); }

/* Le testimonianze video: elenco a sinistra, riproduttore a destra. */
/* ⚠️ SPECCHIATA rispetto a prima. Misurata la produzione il 2026-08-21 a
   1405px: il lettore (`e-tabs-content-wrapper`) sta a x=103 ed è largo 804,
   l'elenco (`e-tabs-wrapper`) a x=907 ed è largo 396 — lettore a SINISTRA,
   elenco a destra, e attaccati: fra i due non c'è stacco (907 = 103 + 804).
   Il verde li aveva invertiti e distanziati di 26px.
   ⚠️ Nel DOM l'elenco resta PRIMO, come in produzione: il `tablist` prima dei
   `tabpanel` è anche l'ordine giusto per chi naviga da tastiera. A invertirli
   è solo la griglia, non il markup. */
.playlist { display: grid; gap: 0; margin-top: 32px;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); align-items: start; }
.playlist .riproduttore { grid-column: 1; grid-row: 1; }
.playlist .scelte { grid-column: 2; grid-row: 1;
  display: grid; gap: 2px; max-height: 420px; overflow-y: auto; }
.playlist .scelte button {
  display: flex; align-items: center; gap: 12px;
  background: none; border: 0; border-left: 3px solid transparent; cursor: pointer;
  padding: 10px 14px; text-align: left; color: inherit; font: inherit;
  font-family: var(--display); font-size: 15px; font-weight: 600;
}
/* La miniatura di ogni voce, 75x42 come in produzione. */
.playlist .scelte img { width: 75px; height: 42px; object-fit: cover; flex: 0 0 auto; }
.playlist .scelte span { flex: 1 1 auto; min-width: 0; }
.playlist .scelte button:hover { background: rgba(255,255,255,.06); }
.playlist .scelte button[aria-selected="true"] {
  background: rgba(255,255,255,.09); border-left-color: var(--yellow); }
.playlist .scelte i { font-style: normal; font-size: 13px; color: var(--ink-faint);
  flex: 0 0 auto; }
.playlist .video { aspect-ratio: 16/9; }
.playlist .video iframe { width: 100%; height: 100%; border: 0; }
/* In colonna sola il lettore va per primo: è quello che si guarda. Senza
   rimettere `grid-row: auto` i due si sovrapporrebbero, perché a entrambi la
   griglia sopra assegna la riga 1. */
/* ⚠️ 767px, non 820: MISURATO in produzione il 2026-08-21 — a 768 lettore ed
   elenco sono ancora affiancati (461 + 227), a 767 si impilano. È lo stesso
   salto del muro dei clienti. */
@media (max-width: 767px) {
  .playlist { grid-template-columns: 1fr; gap: 18px; }
  .playlist .riproduttore { grid-column: 1; grid-row: auto; order: -1; }
  .playlist .scelte { grid-column: 1; grid-row: auto; max-height: 200px; }
}
/* ⚠️ La quarta casella aveva un fondo e un bordo suoi per «distinguersi senza
   gridare». In produzione è identica alle altre: stesso bordo 2px, stesso
   fondo trasparente. A distinguerla basta che sia l'ultima e più stretta. */


/* ── Focus visibile ovunque, non solo dentro .sec-modulo ─────────────────────
   ⚠️ La correzione esisteva da tempo ma era scoped su `.sec-modulo`, che la
   home non ha: sui pulsanti gialli, sulle anteprime dei casi studio e sui
   campi del questionario l'anello restava giallo su bianco — 1,42:1, cioè
   invisibile proprio a chi naviga da tastiera. Ora la regola è globale e si
   inverte solo sulle fasce scure. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid #0d0d0d; outline-offset: 3px; border-radius: 2px;
}
.sec-dark :where(a, button, input, select, textarea, [tabindex]):focus-visible,
.hero :where(a, button, [tabindex]):focus-visible,
dialog.lente :where(button, [tabindex]):focus-visible {
  outline-color: var(--yellow);
}

/* ⚠️ Pista e riempimento erano invertiti: in FluentForm `.ff-el-progress` è la
   pista e `.ff-el-progress-bar` è il riempimento. Coloravo lo `span` interno,
   che resta a larghezza zero: la barra leggeva 0% a ogni passo. */
/* La barra, misurata sulla fonte a 1405px: pista alta **23px** su
   rgb(233,236,239), riempimento con dentro la percentuale a 13,5px.
   La nostra era alta 8px e la percentuale non si vedeva affatto —
   `text-indent: -9999px` sul riempimento e `display: none` sullo span.
   ⚠️ SCOSTAMENTO DICHIARATO: sulla fonte il riempimento e' rgb(26,126,251),
   cioe' l'azzurro di default del plugin, che nessuno ha mai messo mano a
   vestire. Qui resta GIALLO, che e' una scelta di marca gia' presa in questo
   foglio. Si copiano la misura e il testo — che erano contenuto mancante — non
   il colore, che era una decisione. Se il committente vuole anche quello,
   bastano due righe. */
form.ff-passi .ff-el-progress { background: #e9ecef; border-radius: 4px;
  height: 23px; overflow: hidden; margin-bottom: 22px; }
form.ff-passi .ff-el-progress-bar { background: var(--yellow); height: 100%;
  width: 0; border-radius: 4px; transition: width .25s ease;
  display: flex; align-items: center; justify-content: center; }
/* ⚠️ Testo SCURO, non bianco come sulla fonte: li' il fondo e' azzurro, qui e'
   giallo, e il bianco su giallo fa 1,4:1 — illeggibile. Il colore del testo
   segue il fondo, se no copiare un valore ne rompe un altro. */
form.ff-passi .ff-el-progress-bar span { display: block; font-size: 13.5px;
  font-weight: 400; color: #0d0d0d; line-height: 1; }

/* ⚠️ `.ff_item_selectable_wrapper` non esiste in nessuna delle due pagine:
   era CSS morto. Le classi vere del plugin sono queste. */
.ff_el_checkable_photo_holders { display: flex !important; flex-wrap: wrap;
  gap: 14px; }
.ff_el_checkable_photo_holders .ff-el-image-holder,
.ff_el_checkable_photo_holders label {
  border-radius: 10px; border: 1px solid #c9c9c2 !important; }


/* ── Schermo stretto ─────────────────────────────────────────────────────────
   ⚠️ Giudizio letto dal codice e poi corretto: NESSUNA media query toccava
   `.site-head`, `.nav` o `.brand`. Sotto i ~700px i sei link andavano a capo su
   due o tre righe e l'intestazione cresceva in altezza — e siccome sull'eroe è
   sovrapposta, le righe in più cadevano sull'occhiello e sul titolo. In più
   `.servizi` chiedeva colonne da 340px dentro un contenitore da 335 (iPhone SE)
   o 320 (Android da 360): la pagina scorreva in orizzontale. */
@media (max-width: 760px) {
  /* ⚠️ Qui `.site-head .wrap` andava a capo e `.nav` diventava un nastro che
     scorreva in orizzontale: servivano quando i link stavano nella barra.
     Ora la barra tiene solo marchio, bandiere e hamburger — non ha niente da
     mandare a capo, e la nav è un cassetto sovrapposto. Regole tolte, non
     sovrascritte. */
  .brand img { height: 34px; }
  /* 59px misurato in `?__lane=blue` sul telefono — vedi il commento su
     `.site-head .wrap` più sopra nel foglio. Passato a `--head-h` il
     2026-09-05 per lo stesso motivo del desktop: un solo valore che guida
     anche il margine negativo di `.is-transparent`. */
  .site-head { --head-h: 59px; }
  .site-head.is-stuck { --head-h: 48px; }
  .site-head.is-stuck .brand img { height: 28px; }
  /* il rientro da 94px del cassetto vale a 1405px, non su 390 */
  .site-head .nav { padding: 76px 24px 28px; }
  .site-head .wrap { padding-inline: 20px; }
  .servizi { grid-template-columns: 1fr; }
  .promesse { grid-template-columns: 1fr; }
  .playlist { grid-template-columns: 1fr; }
  .hero-home > .wrap { max-width: 100%; }
}
@media (max-width: 400px) {
  .servizi, .lavori, .lavori.verticali, .lavori.orizzontali,
  .griglia-img.larga { grid-template-columns: 1fr; }
  .griglia-img:not(.ritratti) { grid-template-columns: 1fr; }
  .griglia-img.ritratti { grid-template-columns: repeat(2, 1fr); gap: 14px; }
}


/* ── Gerarchia dei pulsanti ──────────────────────────────────────────────────
   ⚠️ Tre pulsanti gialli identici in fila vuol dire nessun pulsante primario.
   In produzione ce ne sono tre livelli: giallo pieno per l'azione principale,
   contorno con la freccia per le secondarie. Il verso lo dice il generatore
   (prima azione = primaria), non il CSS. */
/* ⚠️ Bordo `currentColor` e raggio ZERO, misurati in produzione il 2026-08-21:
   «See all Reviews» ha `border: 1px rgb(13,13,13)` — lo stesso colore del
   testo — e `border-radius: 0px`. Il verde usava `var(--rule)` (#e0e0e0, molto
   più pallido) e 6px di raggio.
   ⚠️ E niente freccia: la nota «contorno più freccia, come in produzione» era
   una deduzione, non una misura. In produzione questi pulsanti non ne hanno. */
.hero-cta.secondaria {
  background: transparent; color: var(--ink);
  border: 1px solid currentColor; border-radius: 0;
}
.hero-cta.secondaria:hover { background: transparent; border-color: var(--ink); }
.sec-dark .hero-cta.secondaria, .hero .hero-cta.secondaria {
  color: #f2f2f0; border-color: rgba(255,255,255,.35);
}
/* In produzione i gruppi di pulsanti delle fasce sono centrati: «See all Case
   studies» sta a x=550 in una banda 103–1303, centro 703 su 703. */
.sec-lead .hero-azioni { justify-content: center; }
.sec-dark .hero-cta.secondaria:hover, .hero .hero-cta.secondaria:hover {
  border-color: var(--yellow); color: var(--yellow);
}

/* Le due promesse: in produzione il marcatore è nero con testo bianco, non
   giallo con testo nero. È il contrario di quello che facevo. */
.promesse .mark { background: #0a0a0a; color: #fff; }


/* ── Il taglio diagonale fra le fasce: NON fatto, di proposito ───────────────
   In produzione il passaggio fra fascia scura e chiara è inclinato (misurato in
   BLUE-5: 17px di dislivello su 1447 di larghezza, ~0,7°). Ho provato a
   riprodurlo con uno pseudo-elemento e `clip-path`: la regola non rendeva
   niente di visibile, e una regola che non fa niente è peggio di una mancanza —
   resta lì a far credere che il problema sia risolto. Tolta.
   Se lo si vuole davvero, la strada giusta è un <svg> nel markup come fa
   Elementor (`elementor-shape`), non un trucco in CSS. */

/* ── Il nastro dei marchi ────────────────────────────────────────────────────
   ⚠️ Da fermo il muro dei clienti occupa 1.020px su 8.100 di pagina — il 12% —
   per 58 loghi. In produzione è un nastro che scorre e sta su una riga sola,
   costruito con Swiper: una libreria che qui peserebbe più di tutta la pagina.
   Bastano una lista duplicata e una translazione: nessun JavaScript.

   La durata cresce col numero di marchi, così la VELOCITÀ resta la stessa
   fra il nastro dei clienti (58) e quello dei partner (11): altrimenti il
   secondo sfreccerebbe. */
.nastro { overflow: hidden; margin-top: 30px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent); }
.nastro-pista { display: flex; width: max-content; animation: scorri var(--durata, 60s) linear infinite; }
.nastro .loghi { flex: none; margin-top: 0; flex-wrap: nowrap; gap: 0 52px;
  padding-right: 52px; }
.nastro:hover .nastro-pista, .nastro:focus-within .nastro-pista { animation-play-state: paused; }
@keyframes scorri { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ⚠️ L'anello di fuoco nel piè di pagina era `rgb(13,13,13)` su un fondo
   `rgb(20,20,20)`: **1,05:1**, contro il 3:1 che chiede la 1.4.11. Riguardava
   16 link per pagina su tutte e cinque le pagine. Misurato a pixel da un
   giudice il 2026-08-23, che ha anche verificato che altrove il sistema di
   fuoco è a posto (fra 11,99:1 e 19,44:1): è una regola di colore, non un
   impianto da rifare. */
.site-foot :focus-visible, .foot-cta :focus-visible { outline-color: var(--yellow); }

/* ── I badge dei partner ─────────────────────────────────────────────────────
   MISURATI in produzione il 2026-08-23 su `about-us`: cinque badge su due
   righe — google 189x180 e meta 189x108 sopra, hubspot 121x54, shopify 172x86
   e klaviyo 121x90 sotto. Qui vanno a capo da soli invece di essere fissati
   a due righe: i cinque hanno proporzioni molto diverse e una griglia rigida
   li deformerebbe. */
.badge-partner { display: grid; gap: clamp(22px, 3vw, 40px); margin-top: 30px;
  justify-items: center; }
.badge-primari, .badge-secondari { display: flex; flex-wrap: wrap;
  align-items: center; justify-content: center; }
.badge-primari { gap: clamp(30px, 5vw, 76px); }
.badge-secondari { gap: clamp(24px, 4vw, 60px); }
.badge-partner img { width: auto; height: auto; object-fit: contain; }
/* i due di punta più grandi, gli altri tre più piccoli: le misure sono quelle
   della produzione (189x180 e 189x108 sopra; 121-172 sotto) */
.badge-primari img { max-width: 190px; max-height: 180px; }
.badge-secondari img { max-width: 172px; max-height: 90px; }
@media (max-width: 767px) {
  .badge-primari img { max-width: 132px; max-height: 124px; }
  .badge-secondari img { max-width: 118px; max-height: 62px; }
}

/* ── Le testimonianze firmate ────────────────────────────────────────────────
   Il contenuto viene dalla pagina SPECCHIATA: nell'albero Elementor sta in un
   widget `template` che referenzia un contenuto esterno, e il postmeta non lo
   porta (vedi `testimonianze_da_specchio` in build_pagine.py).
   ⚠️ In produzione sono un carosello Swiper. Qui sono STATICHE, ed è uno
   scostamento voluto: una recensione va letta, e un carosello che si muove la
   contrasta. Le altre decisioni di parità restano; questa è dichiarata. */
.recensioni { display: grid; gap: 24px; margin-top: 34px;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
.recensione { border: 1px solid var(--rule); border-radius: 12px;
  padding: clamp(20px, 3vw, 30px); display: grid; gap: 14px;
  align-content: start; }
.recensione img { width: 68px; height: 68px; border-radius: 50%;
  object-fit: cover; display: block; }
.recensione .quote { margin: 0; }
.recensione .quote p { margin: 0; font-size: 16px; line-height: 1.62; }
.recensione cite { font-style: normal; font-family: var(--display);
  font-weight: 700; font-size: 14px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink); display: block; }
/* il ruolo e l'azienda, sotto il nome: senza, la firma vale molto meno */
.recensione cite span { display: block; margin-top: 4px; font-weight: 500;
  font-size: 12.5px; letter-spacing: .02em; text-transform: none;
  color: var(--ink-soft); }
/* ⚠️ NON `--yellow-deep`: su bianco fa 2,00:1, e le stelle sono un elemento
   grafico che porta significato — la 1.4.11 chiede 3:1. Calcolato: #b8860b dà
   3,25:1 e passerebbe la soglia dei GRAFICI, ma le stelle sono caratteri e ogni
   verifica automatica le misura come testo (4,5). #8a6600 dà 5,27:1: nessuna
   discussione, e resta un oro scuro riconoscibile. Su fondo scuro torna il giallo
   pieno (12,96:1). È lo stesso errore che avevo appena corretto altrove: la
   variabile si chiama «deep» ma non è accessibile sul chiaro. */
/* le stelle valgono anche fuori dalle schede recensione: su
   `why-choose-webgas` stanno nelle schede `.testimonianza` */
.stelle { color: #8a6600; font-size: 15px; letter-spacing: 2px; line-height: 1; }
.sec-dark .stelle { color: var(--yellow); }
.testimonianza .stelle { margin-top: -4px; }
.sec-dark .recensione cite span { color: #c9c9c4; }
.sec-dark .recensione { border-color: #2e2e2e; }
.sec-dark .recensione cite { color: var(--yellow); }

/* ── I ritratti della squadra ────────────────────────────────────────────────
   MISURATI in produzione il 2026-08-22: **156x350**, angoli **20px**, e
   **sfalsati** in verticale — le y alternano 4686 e 4646, 40px di scarto. Il
   verde ne aveva 16 quadrati 154x154 ad angoli vivi, in griglia piatta.
   Il movimento riusa la macchina dei marchi (`.nastro`/`.nastro-pista`), che
   scorre sempre per la decisione già presa sui nastri. */
.nastro-volti .volti { display: flex; flex: none; gap: 18px;
  align-items: flex-start; margin-top: 0; padding-right: 18px; }
.nastro-volti img { width: 156px; height: 350px; object-fit: cover;
  border-radius: 20px; display: block; max-width: none; }
/* uno sì e uno no scende: è lo sfalsamento della produzione */
.nastro-volti .volti img:nth-child(odd) { margin-top: 40px; }
@media (max-width: 767px) {
  .nastro-volti img { width: 112px; height: 252px; }
  .nastro-volti .volti img:nth-child(odd) { margin-top: 28px; }
}

/* ── Il muro dei clienti ─────────────────────────────────────────────────────
   MISURATO in produzione (`?__lane=blue`) il 2026-08-21 a 1405/1200/900/820/
   768/767/700/640/600/390px. Non è un nastro solo: sono OTTO marchi in riquadri
   #F5F5F5, quattro per riga fino a 768px e uno solo da 767 in giù, con la targa
   BIANCA «Partners in Scale» sovrapposta alla giuntura fra le due righe — e
   SOTTO il carosello con tutti gli altri.
   Riquadri: 348x281 a 1405px, 297x240 a 1200px — rapporto 1,24 costante. Il
   logo dentro sta al 70% della cella (244/348, 208/297, 155/222).
   ⚠️ I marchi in evidenza sono a COLORI (`filter: none`, `opacity: 1`): la
   scala di grigi è del nastro, non della griglia. */
.sec-clienti { background: var(--ground); padding-block: 0; }
.muro { position: relative; }
/* ⚠️ `minmax(0, 1fr)` e non `1fr`: con `1fr` gli elementi tengono
   `min-width: auto` e non scendono sotto il contenuto — a 768px le celle
   uscivano 211px invece di 189 e la pagina traboccava di 88px. */
.muro-griglia { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; }
.muro-cella {
  background: var(--muro-cella);
  display: flex; align-items: center; justify-content: center;
  /* ⚠️ Padding solo verticale. Il logo deve essere il **70% della CELLA** —
     244 su 348 in produzione — e una percentuale si risolve sul riquadro di
     contenuto: con padding anche laterale, `width: 70%` valeva il 70% di 268,
     cioè 187. Lo spazio laterale lo fa il 30% che avanza. */
  padding-block: clamp(14px, 2.4vw, 34px); padding-inline: 0;
  /* ⚠️ Il rapporto 1,24 regge sopra i 1000px (348x281 a 1405, 297x240 a 1200:
     esatti). Sotto, la produzione si appiattisce — 222x204 a 900, 189x178 a
     768, cioè ~23vw invece di 20 — e il solo `aspect-ratio` lasciava le celle
     25px troppo basse. Il `min-height` recupera proprio quella curva. */
  /* ⚠️ `width: 100%` NON è ridondante su un elemento di griglia. Con
     `aspect-ratio` e `min-height` insieme, e senza una larghezza definita, il
     browser ricava la LARGHEZZA dall'altezza: a 900px veniva 207x1,24 = 257
     invece dei 222 della colonna, e la pagina traboccava di 35px. Con la
     larghezza fissata, il rapporto governa l'altezza e il `min-height` la
     alza senza toccare i lati. */
  width: 100%; aspect-ratio: 1.24; min-height: clamp(170px, 23vw, 210px);
}
.muro-cella img {
  /* ⚠️ `width` fissa, non `max-width`. Con `max-width: 70%` più
     `max-height: 100%`, per i loghi alti vincolava l'ALTEZZA e la larghezza
     usciva al **56,4%** della cella invece del 70: −19% di lato e −34% di
     area, e il muro si leggeva più vuoto. Misurato dal secondo giudice il
     2026-08-22 (blu 244px, verde 197px a 1405). */
  width: 70%; height: auto; max-height: 100%; object-fit: contain;
  filter: none; opacity: 1;
}
.muro-targa {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  margin: 0; padding: 10px 28px; background: var(--ground); z-index: 1;
  font-family: var(--display); font-weight: 700; color: var(--ink);
  font-size: clamp(18px, 2.3vw, 32px); line-height: 1.3;
  text-align: center; white-space: nowrap;
}
/* ⚠️ 767px è MISURATO, non scelto: a 768 la produzione tiene ancora quattro
   riquadri per riga, a 767 passa a uno. Lì la targa smette di sovrapporsi e
   torna nel flusso, come fa la produzione. */
@media (max-width: 767px) {
  .muro-griglia { grid-template-columns: 1fr; }
  /* ⚠️ Altezza FISSA, non `min-height`. Lasciata al contenuto, ogni cella
     prendeva l'altezza del suo logo: 158, 209, 281, 158, 158, 195, 158, 253 —
     una scaletta, e 208px di pagina in più. In produzione le otto celle sono
     tutte identiche. La curva è lineare e misurata: 158 a 390px, 200 a 600,
     208 a 640, 220 a 700, 233 a 767 — cioè `20vw + 80px`. */
  .muro-cella { aspect-ratio: auto; height: calc(20vw + 80px); min-height: 0; }
  .muro-targa { position: static; transform: none; white-space: normal; padding: 33px 0; }
}
/* In produzione il carosello comincia dove finisce l'ultima riga di riquadri:
   nessuno stacco fra i due. */
.sec-clienti .nastro { margin-top: 0; padding-block: 26px; }

/* Chi ha chiesto meno movimento torna al muro: fermo, ma tutto leggibile. */
/* Il ripiego a muro non serve più: il nastro scorre in ogni caso (scelta del
   committente, vedi l'eccezione a riga ~301). Resta la pausa su hover e focus. */
/* Rete di sicurezza: nel nastro nessun marchio può alzare la riga da solo.
   L'altezza giusta la scrive `ritaglia_marchi.py`; questo è il tetto per
   quelli che dovessero sfuggirgli. */
/* ⚠️ Misura fissa a ogni larghezza: in un contenitore da 350px sul telefono
   entrava un logo e mezzo, e il nastro leggeva come un marchio gigante che
   scorre invece che come una fila di partner. Misurato il 2026-08-23. */
.nastro .loghi img { max-height: 58px; }
@media (max-width: 767px) {
  .nastro .loghi img { max-height: 38px; }
  .nastro .loghi { gap: 0 34px; }
}
@media (max-width: 480px) { .nastro .loghi img { max-height: 30px; } }


/* ── Il menu su telefono ─────────────────────────────────────────────────────
   ⚠️ Misurato con Playwright: in fila i cinque link piu' il selettore di lingua
   occupano ~410px oltre al logo. Su iPhone 13 (390px) il selettore finiva a
   427px, su iPhone SE (320px) anche «Contact», a 376px: fuori dallo schermo e
   senza modo di arrivarci. La produzione li chiude in un off-canvas; qui il
   pannello scende sotto l'intestazione. Sopra i 900px non cambia nulla. */
/* ── Il cassetto della navigazione ───────────────────────────────────────────
   ⚠️ Stava dentro `@media (max-width: 900px)`: sotto i 900px il cassetto, sopra
   cinque link di testo in fila. MISURATA la produzione il 2026-08-21 a 1405,
   1200 e 1024px, in tutte e tre mostra l'hamburger (57x57) e ZERO link di
   testo: la navigazione sta dietro il pulsante a ogni larghezza. La media
   query è caduta, le regole sono le stesse. */
/* ⚠️ 57x57, la misura della fonte (il nostro era 44x44). Sopra il minimo
   tattile di 44, quindi non toglie niente a nessuno. */
.nav-apri {
  display: flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 57px; height: 57px; padding: 0 13px; border: 0; background: none;
  cursor: pointer; flex: 0 0 auto; color: inherit;
}
.nav-apri span { display: block; height: 2px; background: currentColor; border-radius: 2px;
  transition: transform .18s ease, opacity .18s ease; }
.nav-apri[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-apri[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-apri[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ⚠️ Cassetto a DESTRA, non pannello a piena larghezza. Misurato aprendo il
   menu della fonte a 1405px: il pannello parte a x=700 (largo ~605), copre
   l'altezza dello schermo, ha lo sfondo scuro, le voci a 15px/700 Montserrat
   bianche con passo 47px, e l'ultima — «CONSULENZA GRATUITA» — e' un pulsante
   giallo, non un link. Il nostro scendeva sotto l'intestazione per tutta la
   larghezza, con dieci voci separate da righe: un'altra cosa. */
.site-head .nav {
  position: fixed; top: 0; right: 0; bottom: 0; left: auto;
  width: min(705px, 100%); z-index: 30;
  display: none; flex-direction: column; align-items: stretch;
  background: #1a1a1a; padding: 96px 44px 32px 94px;
  overflow-y: auto; overscroll-behavior: contain;
}
/* ⚠️ `flex: 0 0 auto` su ogni figlio, e non e' una rifinitura. In un flex
   column con altezza fissa e contenuto piu' alto, gli elementi si RESTRINGONO
   sotto la propria misura invece di far scorrere: la tendina aperta finiva
   sotto la voce successiva, sovrapposta. */
.site-head .nav > * { flex: 0 0 auto; }
.site-head.menu-aperto .nav { display: flex; }
/* ⚠️ Il pulsante resta SOPRA il cassetto e cliccabile: e' quello che lo
   chiude. Senza, il cassetto ci finisce sopra e il menu non si chiude piu'
   se non ricaricando. */
.site-head .nav-apri { position: relative; z-index: 31; }
/* ⚠️ E anche le bandiere. Il cassetto parte da x=700 e le copriva: col menu
   aperto la lingua non si poteva piu' cambiare. La fonte risolve mettendole
   IN FONDO al pannello; qui restano dove sono, sopra di esso — stesso
   risultato per chi le cerca, e non si spostano fra aperto e chiuso. */
.site-head .lang-flags { position: relative; z-index: 31; }
.site-head.menu-aperto .nav-apri { color: #f2f2f0; }
.site-head .nav a, .site-head .nav summary {
  min-height: 47px; display: flex; align-items: center;
  color: #f2f2f0; font-family: var(--display); font-size: 15px; font-weight: 700;
  border-bottom: 0; text-decoration: none;
}
/* la tendina: `<summary>` porta la freccia, il browser la apre da solo */
.site-head .nav-gruppo > summary {
  list-style: none; cursor: pointer; justify-content: space-between; gap: 12px;
}
.site-head .nav-gruppo > summary::-webkit-details-marker { display: none; }
.site-head .nav-gruppo > summary::after {
  content: ''; width: 9px; height: 9px; flex: 0 0 auto;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-3px, -3px); transition: transform .18s ease;
}
.site-head .nav-gruppo[open] > summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
.site-head .nav-gruppo > summary > a { min-height: 0; flex: 1 1 auto; }
.site-head .nav-sub { display: flex; flex-direction: column; padding-left: 18px; }
.site-head .nav-sub a { font-size: 14px; font-weight: 600; min-height: 42px;
  color: #cfcfcf; }
/* l'ultima voce e' un pulsante, non un link */
.site-head .nav > a:last-child {
  margin-top: 22px; background: var(--yellow); color: var(--ink);
  justify-content: center; padding: 12px 24px; align-self: start;
}
.site-head .nav > a:last-child:hover { background: #ffdf3d; }


/* ═══ STAMPA ═══════════════════════════════════════════════════════════════
   Serve a UNA cosa precisa: il PDF dell'articolo che il lettore chiede via
   email. Su WordPress lo generava un plugin (Dynamic Content for Elementor,
   azione `dce_form_pdf`) leggendo il post; dopo il cutover quel plugin non
   gira più, quindi il PDF si produce da qui — `.migration/pdf_articoli.mjs`
   stampa la pagina vera con Chromium.

   ⚠️ Un PDF non è uno screenshot del sito. Via l'intestazione, il piè di
   pagina, il modulo e i richiami: su carta non si clicca niente, e occupano
   la prima pagina intera. Resta l'articolo.

   ⚠️ E l'eroe scuro diventa chiaro: `#0d0d0d` a piena pagina è inchiostro
   che nessuno vuole stampare, e il titolo giallo su bianco non si legge
   (2,00:1, la stessa ragione per cui `--yellow` non si usa mai come testo su
   fondo chiaro nel resto del foglio). */
@media print {
  .site-head, .foot, .foot-cta, footer, .skip,
  .sec-modulo, #modulo, .lead-form, .nav-apri, .lang-flags,
  .sec-galleria, .card-more, iframe,
  /* ⚠️ Il banner dei cookie va nascosto ESPLICITAMENTE. È `position: fixed`, e
     in stampa un elemento fisso si deposita in cima alla PRIMA pagina: nel
     primo PDF di prova copriva il titolo dell'articolo con mezza pagina di
     informativa, e il titolo non è che mancasse — stava sotto. */
  [id^="iubenda"], [class^="iubenda"], [class*="iub__"], #iubFooterBtn
  { display: none !important; }

  html, body { background: #fff !important; color: #000 !important; }
  body { font-size: 11.5pt; line-height: 1.5; }

  /* la testata dell'articolo: stessa gerarchia, senza il fondo scuro */
  .post-head {
    background: none !important; color: #000 !important;
    padding: 0 0 18pt !important; border-bottom: 1pt solid #999;
  }
  .post-head h1 { color: #000 !important; font-size: 22pt; line-height: 1.15; }
  .post-hook { color: #222 !important; font-size: 12pt; }
  .post-date { color: #444 !important; }

  .wrap { width: auto !important; padding: 0 !important; }
  .post-body { max-width: none !important; padding: 18pt 0 0 !important; }
  .post-body h2 { font-size: 15pt; margin: 16pt 0 6pt; }
  .post-body h3 { font-size: 13pt; margin: 12pt 0 4pt; }

  /* ⚠️ Un titolo in fondo alla pagina con il suo testo su quella dopo è il
     difetto tipico della stampa: si tiene insieme al primo paragrafo. */
  h1, h2, h3 { break-after: avoid-page; page-break-after: avoid; }
  img, figure, table, blockquote, li { break-inside: avoid; page-break-inside: avoid; }
  img { max-width: 100% !important; height: auto !important; }

  /* ⚠️ Su carta un link non si clicca: la sua destinazione va scritta, se no
     l'informazione si perde. Solo per i link ESTERNI e solo se non è già
     l'URL a fare da testo, se no si stampa due volte la stessa riga. */
  .post-body a[href^="http"]:not([href*="webgas.net"])::after {
    content: " (" attr(href) ")"; font-size: 9pt; color: #555; word-break: break-all;
  }

  @page { margin: 16mm 14mm; }
}

/* ═══════════════════════════════════════════════════════════════════════
   RESTYLING PAGINE SERVIZIO — 2026-09-05
   ═══════════════════════════════════════════════════════════════════════
   Decisione presa da Tony il 2026-09-05: "parità con la produzione batte
   il miglioramento" (HANDOFF.md) resta la regola per tutto il sito TRANNE
   le pagine servizio, dove Tony ha chiesto esplicitamente un restyling
   radicale del layout. Approvato con un mockup su /it/servizio/cro/,
   rivisto due volte da due giudici indipendenti (mockup contro WP live).

   ⚠️ Tutto qui sotto è scoped sotto `body.page-service`, e SOLO dentro
   `<main>` — mai l'intestazione, il piè di pagina o `.foot-cta` (chrome
   condiviso da ogni tipo di pagina): cambiarli solo per le pagine servizio
   creerebbe un salto visivo passando da una pagina all'altra dello stesso
   sito. `body.page-service` lo emette `page()` in build_services.py SOLO
   per le pagine `/servizio/`/`/service/` (non contatti, non partner, non
   pilastro) — vedi `e_pagina_servizio` in quel file.

   Il testo non cambia MAI qui dentro: è la stessa regola di sempre, solo
   il layout è nuovo. Nessuna riga qui sotto tocca l'estrazione del
   contenuto in build_services.py. */
body.page-service {
  --ps-ink: #0d0d0d;
  --ps-ink-soft: #4c4c46;
  --ps-ink-faint: #84816f;
  --ps-paper: #fbfaf6;
  --ps-line: #e3ded0;
  --ps-yellow: #ffd501;
  --ps-yellow-deep: #a6820a;
  --ps-stage: #0d0d0d;
  --ps-stage-line: #2a2a24;
  --ps-stage-soft: #c9c6b9;
  --ps-radius: 6px;
}
/* --seam di base qui: se una griglia a bordo-singolo (.kpis/.riquadri/...)
   finisse mai fuori da un .sec/.sec-dark (che lo ridefiniscono sotto), un
   var(--seam) non risolto rende il bordo invalido — sparisce senza
   avviso invece di degradare. Trovato dalla review del 2026-09-05. */
body.page-service main { background: var(--ps-paper); color: var(--ps-ink); --seam: var(--ps-line); }

/* ---------- ritmo delle sezioni ---------- */
body.page-service main .sec { padding-block: clamp(52px, 7vw, 84px); border-bottom: 1px solid var(--ps-line); --seam: var(--ps-line); }
body.page-service main .sec-dark {
  background: var(--ps-stage); color: var(--ps-paper); border-bottom-color: var(--ps-stage-line); --seam: var(--ps-stage-line);
}
body.page-service main .sec-dark h2 { color: #fff; }
body.page-service main .sec-dark .sec-sub { color: var(--ps-stage-soft); }
body.page-service main .sec h2 { font-size: var(--titolo-fascia); line-height: 1.2; text-transform: none; }
/* ⚠️ `.sec-lead h2` altrove nel foglio è MAIUSCOLO centrato, misurato contro
   WP (`site.css:628`) — quella regola resta per tutte le altre pagine.
   Qui la stessa classe prende un trattamento diverso di proposito. */
body.page-service main .sec-lead h2,
body.page-service main .sec-lead.sec-dark h2 { text-transform: none; text-align: left; max-width: none; color: inherit; }
body.page-service main .sec-lead .sub { text-align: left; margin-inline: 0; font-style: normal; color: var(--ps-ink-soft); }
body.page-service main .sec-dark.sec-lead .sub { color: var(--ps-stage-soft); }
@media (min-width: 821px) {
  body.page-service main .sec-grid { grid-template-columns: minmax(0,.6fr) minmax(0,1fr); gap: clamp(24px,4vw,56px); }
  /* La sezione col titolo "appiccicato" a sinistra mentre il testo scorre a
     destra — vedi il mockup approvato. Sotto gli 820px (breakpoint già
     esistente di `.sec-grid`) niente sticky: non c'è più una seconda colonna
     da tenere allineata (già corretto il 2026-09-05 dopo la segnalazione
     di un'altra colonna che si sovrapponeva al testo sotto). */
  body.page-service main .sec-grid > :first-child:not(.hero-azioni) { position: sticky; top: 24px; align-self: start; }
}
/* ⚠️ La regola sopra era SENZA media query e vinceva per specificità sulla
   `.sec-grid { grid-template-columns: 1fr }` di base sotto gli 820px (stessa
   selettore, ma la mia con più classi pesa di più): sul telefono le sezioni
   restavano a due colonne, e il modulo di contatto (dentro la colonna
   stretta) usciva 27px oltre il viewport su iPhone SE. Trovato live il
   2026-09-05 con `.migration/mobile/`. */
body.page-service main .prose p:first-child { font-size: 18px; color: var(--ps-ink); }
body.page-service main .sec-dark .prose p:first-child { color: #f4f2e9; }

/* ---------- eroe ---------- */
body.page-service main .hero {
  background: var(--ps-stage); background-image: none; color: var(--ps-paper);
  padding-block: clamp(72px,12vh,128px) clamp(56px,9vh,96px);
}
/* ⚠️ E il testo dell'eroe DEVE seguire questo fondo, non `--eroe-fondo`.
   `hero-chiaro` viene messa quando la FONTE ha l'eroe chiaro, e porta con se'
   testo #0d0d0d. Su queste pagine pero' il fondo lo decide la riga qui sopra
   — `var(--ps-stage)`, scuro, con specificita' piu' alta di
   `.hero.hero-fonte` — e i due sistemi si contraddicevano: testo #0d0d0d su
   fondo #0d0d0d, cioe' 1:1. Il sottotitolo dell'eroe era INVISIBILE su sei
   pagine: le tre migrazione/replatforming italiane e le tre inglesi.
   Trovato il 2026-09-30 con `_rassegna-contrasto.mjs`, non a occhio: su un
   fondo nero un testo nero non si vede, e nessuno segnala cio' che non vede.
   ⚠️ Si allinea il TESTO al fondo che c'e', non il fondo alla fonte:
   cambiare il fondo vorrebbe dire ridipingere sei eroi oggi pubblicati, e la
   fonte non c'e' piu' per dire quale dei due sistemi avesse ragione. */
body.page-service main .hero.hero-chiaro,
body.page-service main .hero.hero-chiaro .hero-eyebrow,
body.page-service main .hero.hero-chiaro .hero-occhiello,
body.page-service main .hero.hero-chiaro .hero-hook,
body.page-service main .hero.hero-chiaro .hero-invito { color: var(--ps-paper); }
body.page-service main .hero h1 { color: var(--ps-yellow); font-size: var(--titolo-eroe); line-height: .96; }
/* Due titoli-servizio (le due pagine Shopify) sono frasi intere da 96-106
   caratteri, non un nome come «C.R.O»: allo stesso corpo gigante diventavano
   6 righe che spingevano la CTA fuori dal primo schermo (trovato live il
   2026-09-05). La classe è assegnata in build_services.py per lunghezza. */
body.page-service main .hero h1.h1-mid { font-size: var(--titolo-eroe); line-height: 1.05; }
body.page-service main .hero h1.h1-long { font-size: var(--titolo-eroe); line-height: 1.15; }
body.page-service main .hero-hook { color: var(--ps-stage-soft); font-weight: 400; }

/* ---------- pulsanti: una sola forma ---------- */
body.page-service main .hero-cta {
  border-radius: 999px; padding: 15px 26px; letter-spacing: .04em;
  transition: opacity .12s ease; background: var(--ps-yellow); color: #141400;
}
body.page-service main .hero-cta:hover { opacity: .82; background: var(--ps-yellow); }

/* ---------- KPI: griglia piatta e a tab, stesso trattamento ----------
   Il bordo sta sulla singola card (border-right/bottom), non sullo sfondo
   del contenitore dietro un gap di 1px: con un numero di elementi che non
   riempie per intero l'ultima riga (una tab KPI con 3 riquadri invece di 4,
   5 recensioni su una griglia a 3 colonne...) uno sfondo-contenitore
   lasciava la cella vuota "piena" — un riquadro nero fantasma, trovato live
   il 2026-09-05 su /it/servizio/cro/ sia sui KPI sia sulle recensioni. Una
   cella vuota senza sfondo-contenitore resta invece trasparente qualunque
   sia il numero di elementi. */
body.page-service main .kpis {
  gap: 0; border-top: 1px solid var(--seam); border-left: 1px solid var(--seam);
  grid-template-columns: repeat(auto-fit, minmax(165px,1fr));
}
@media (max-width: 700px) { body.page-service main .kpis { grid-template-columns: repeat(2, minmax(0,1fr)); } }
body.page-service main .kpi {
  background: var(--ps-stage); border: none; border-right: 1px solid var(--seam);
  border-bottom: 1px solid var(--seam); border-radius: 0; padding: 22px 16px;
}
/* Il padding piccolo di base (site.css:386) esiste per far stare due
   colonne a 320px — la mia regola sopra non ha media query e la batteva
   per specificità. Il valore del `.kpi b` qui è già più piccolo (28px
   contro 54px) e oggi non trabocca, ma non c'è motivo di lasciare la
   protezione spenta. Trovato dalla review del 2026-09-05. */
@media (max-width: 480px) { body.page-service main .kpi { padding: 18px 10px; } }
body.page-service main .kpi b { font-size: clamp(18px, 15cqi, 28px); letter-spacing: -.02em; }
body.page-service main .kpi span { color: var(--ps-stage-soft); }
body.page-service main .kpi-tabs { margin-top: 28px; }
body.page-service main .kpi-tab-nav { border-bottom-color: var(--ps-stage-line); gap: 4px 22px; }
body.page-service main .kpi-tab-btn { color: var(--ps-stage-soft); font-weight: 600; }
body.page-service main .kpi-tab-btn.is-active { color: var(--ps-yellow); border-bottom-color: var(--ps-yellow); }
body.page-service main .kpi-tab-btn:hover { color: #fff; }
body.page-service main .kpi-icon { fill: var(--ps-yellow); }
/* Oggi ogni `.kpis` di questa migrazione vive dentro un `.sec-dark` (i KPI
   sono sempre forzati scuri in build_services.py), ma la base del sito
   prevede anche un `.kpi` dentro una `.sec` chiara (i "quattro passi del
   processo" — vedi il commento a site.css:1002), e quel caso batte queste
   regole per specificità (`.sec:not(.sec-dark) …` pesa più di
   `body.page-service main …`): un `.kpi` chiaro erediterebbe testo/icona
   quasi neri sullo sfondo quasi nero fissato qui sopra — invisibile, non
   solo brutto. Difensivo, non ancora osservato dal vivo. Trovato dalla
   seconda review del 2026-09-05. */
body.page-service main .sec:not(.sec-dark) .kpi { border-color: var(--seam); }
body.page-service main .sec:not(.sec-dark) .kpi b { color: var(--ps-yellow); }
body.page-service main .sec:not(.sec-dark) .kpi span { color: var(--ps-stage-soft); }
body.page-service main .sec:not(.sec-dark) .kpi-icon { fill: var(--ps-yellow); }

/* ---------- riquadri: stessa griglia piatta a filo, coerente coi KPI ---------- */
body.page-service main .riquadri {
  gap: 0; border-top: 1px solid var(--seam); border-left: 1px solid var(--seam);
  /* auto-fit, non auto-fill: come `.kpis` sopra — auto-fill tiene le tracce
     vuote a piena larghezza (1fr), e senza una card sopra a disegnare il
     bordo destro/inferiore restava una linea in cima che correva a vuoto
     per lo spazio delle tracce non riempite. Trovato dalla review del
     2026-09-05 su 20 delle 34 pagine. */
  grid-template-columns: repeat(auto-fit, minmax(200px,1fr));
}
body.page-service main .riquadro {
  background: var(--ps-paper); border-right: 1px solid var(--seam); border-bottom: 1px solid var(--seam);
  padding: 20px 16px; gap: 6px;
}
body.page-service main .sec-dark .riquadro { background: var(--ps-stage); }

/* ---------- citazioni/testimonianze: una sola idea di card, dovunque
   appaia (il blocco "choose" con .quotes, quello con foto e stelle
   ".recensione") ---------- */
body.page-service main .quotes,
body.page-service main .recensioni {
  gap: 0; border-top: 1px solid var(--seam); border-left: 1px solid var(--seam);
}
body.page-service main .quotes .quote {
  background: var(--ps-paper); border-left: none; border-right: 1px solid var(--seam);
  border-bottom: 1px solid var(--seam); padding: 24px 22px; margin: 0;
}
body.page-service main .sec-dark .quotes .quote { background: var(--ps-stage); }
body.page-service main .recensione {
  background: var(--ps-paper); border: none; border-right: 1px solid var(--seam);
  border-bottom: 1px solid var(--seam); border-radius: 0; padding: 24px 22px 20px;
}
body.page-service main .sec-dark .recensione { background: var(--ps-stage); }
/* #8a6600, non --ps-yellow-deep (#a6820a): su --ps-paper scende a 3,46:1,
   sotto il 5,07:1 del colore di base — trovato dalla review del 2026-09-05. */
body.page-service main .stelle { color: #8a6600; letter-spacing: 1.5px; }
body.page-service main .sec-dark .stelle { color: var(--ps-yellow); }

/* ---------- video ---------- */
body.page-service main .vids { gap: 0; border-top: 1px solid var(--seam); border-left: 1px solid var(--seam); }
body.page-service main .vid { background: var(--ps-paper); border-right: 1px solid var(--seam); border-bottom: 1px solid var(--seam); }
body.page-service main .sec-dark .vid { background: var(--ps-stage); }
body.page-service main .vid .video { margin-top: 0; }
body.page-service main .vid figcaption { padding: 12px 16px; margin-top: 0; }

/* ---------- passi: numerati per davvero (sono un processo in ordine),
   bolla circolare invece del bordo superiore ---------- */
body.page-service main .passi { gap: 0; border-top: 1px solid var(--seam); border-left: 1px solid var(--seam); }
body.page-service main .passi li {
  background: var(--ps-paper); border: none; border-right: 1px solid var(--seam);
  border-bottom: 1px solid var(--seam); padding: 22px 18px;
}
body.page-service main .sec-dark .passi li { background: var(--ps-stage); }
body.page-service main .passi li b {
  display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 50%;
  background: var(--ps-yellow); color: #141400; font-size: 15px;
}
body.page-service main .sec-dark .passi li b { background: var(--ps-yellow); color: #141400; }

/* ---------- badge partner / nastro marchi ---------- */
body.page-service main .badge-partner { gap: clamp(20px,3vw,36px); }
body.page-service main .nastro { margin-top: 26px; }

/* ---------- modulo di contatto ---------- */
body.page-service main .lead-form input,
body.page-service main .lead-form textarea { border-radius: 10px; border-color: var(--ps-line); }
body.page-service main .lead-form input:focus,
body.page-service main .lead-form textarea:focus { outline: 2px solid var(--ps-yellow-deep); outline-offset: 1px; border-color: var(--ps-yellow-deep); }
body.page-service main .lead-form button { border-radius: 999px; background: var(--ps-ink); color: var(--ps-paper); border-color: var(--ps-ink); }
body.page-service main .lead-form button:hover { background: var(--ps-yellow-deep); color: #141400; border-color: var(--ps-yellow-deep); }

/* ---------- loghi clienti ---------- */
body.page-service main .logos-sec { border-top: 1px solid var(--ps-line); border-bottom: none; }

/* ---------- barra fissa in fondo ---------- */
body.page-service main .sticky-cta { background: var(--ps-paper); border-top-color: var(--ps-line); }
body.page-service main .sticky-cta a { border-radius: 999px; background: var(--ps-ink); }
body.page-service main .sticky-cta a:hover { background: var(--ps-yellow); color: #0d0d0d; }

/* ---------- illustrazione+pulsante di apertura (già scoped di suo,
   qui solo l'allineamento col resto del sistema) ---------- */
body.page-service main .apertura-img { border-radius: var(--ps-radius); }

/* ---------- il filtro dell'indice casi studio ----------
   ⚠️ Vive su due pagine sole (/it/casi-studio/, /en/case-studies/), quindi
   resta scoped su `.filtro-casi` invece di prendersi `select` in generale: i
   moduli FluentForm delle altre pagine hanno le loro regole e un selettore
   largo gliele scavalcherebbe.
   ⚠️ `.card[hidden]` con `!important` perché `.card` dichiara
   `display: flex`, che vince su `[hidden]` — è la trappola per cui un
   `hidden` "non funziona" senza che nessuno veda un errore. */
.filtro-casi { display: flex; align-items: center; flex-wrap: wrap; gap: 12px;
  margin-bottom: 28px; }
.filtro-casi label { font-size: 14px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink); }
.filtro-casi select { font: inherit; font-size: 16px; padding: 10px 14px;
  border: 1px solid var(--rule); border-radius: 0; background: #fff;
  color: var(--ink); min-width: 260px; max-width: 100%; }
.filtro-casi select:focus-visible { outline: 3px solid var(--yellow);
  outline-offset: 2px; }
#griglia-casi > .cs-riga[hidden] { display: none !important; }

/* ---------- l'indice dei casi studio, ricalcato su WordPress ----------
   ⚠️ Tutto scoped su `.page-casi-indice`. Le stesse proprietà scritte globali
   romperebbero le altre 253 pagine: sull'indice il titolo va INGRANDITO (158px
   contro i 104 di prima), sulla pagina del singolo caso studio va rimpicciolito
   (la fonte lo mette a 40px). È la trappola di `shell()` che AGENTS.md
   racconta — una modifica al chrome arrivò a 85 pagine e ne lasciò 46 indietro.
   Misure prese dal vivo su ?__lane=blue a 1405px, con locale it-IT. */
.page-casi-indice .hero-index h1 { font-size: var(--titolo-eroe); }
.page-casi-indice .filtro-casi { justify-content: flex-end; }

/* ⚠️ 1348 e non 1220: `.wrap` porta `padding-inline: var(--gutter)` (64px per
   lato) e con `box-sizing: border-box` il max-width lo comprende. A 1220 la
   riga usciva 1092 — misurato — contro i 1220 della fonte. */
.page-casi-indice .cs-elenco { max-width: 1348px; display: flex;
  flex-direction: column; gap: 100px; }
.page-casi-indice .cs-riga { display: grid; grid-template-columns: 420px minmax(0, 1fr);
  gap: 60px; align-items: center; }
/* la fonte alterna copertina a sinistra e a destra: è il ritmo della pagina,
   non un dettaglio — con tutte le copertine dallo stesso lato l'elenco
   diventa una colonna sola e si legge come una lista. */
.page-casi-indice .cs-riga.cs-dx { grid-template-columns: minmax(0, 1fr) 420px; }
.page-casi-indice .cs-riga.cs-dx .cs-copertina { order: 2; }
.page-casi-indice .cs-copertina img { display: block; width: 100%; height: auto; }

.page-casi-indice .cs-testo-col h2 { font-size: 34px; line-height: 1.2; margin: 0; }
.page-casi-indice .cs-testo-col h2 a { text-decoration: none; color: inherit; }
.page-casi-indice .cs-testo-col h2 a:hover { text-decoration: underline; }
.page-casi-indice .cs-sotto { margin: 10px 0 0; font-size: 20px; color: var(--ink-faint); }
.page-casi-indice .cs-testo { margin: 22px 0 0; font-size: 18px; line-height: 1.7; }
.page-casi-indice .cs-scarica { display: inline-block; margin-top: 30px;
  padding: 16px 26px; border: 1px solid var(--ink); font-weight: 700;
  font-size: 15px; letter-spacing: .02em; text-decoration: none; color: var(--ink);
  background: transparent; }
.page-casi-indice .cs-scarica:hover { background: var(--ink); color: #fff; }

/* ⚠️ Sotto i 900px la copertina non può restare a 420px fissi in una griglia
   a due colonne: `minmax(0,1fr)` sull'altra colonna non basta, la traccia
   fissa resta e la pagina trabocca. Si passa a una colonna sola. */
@media (max-width: 900px) {
  .page-casi-indice .cs-riga,
  .page-casi-indice .cs-riga.cs-dx { grid-template-columns: 1fr; gap: 28px; }
  .page-casi-indice .cs-riga.cs-dx .cs-copertina { order: 0; }
  .page-casi-indice .cs-copertina img { max-width: 420px; margin: 0 auto; }
  .page-casi-indice .cs-elenco { gap: 64px; }
}

/* ---------- la home, ricalcata sulla tipografia della fonte ----------
   ⚠️ Scoped su `.page-home`, e non per prudenza: il design system dà 32px a
   ogni titolo di fascia, mentre su questa pagina WordPress li varia fra 16 e
   40. Le stesse regole scritte globali romperebbero le altre 252 pagine —
   è la trappola di `shell()` già pagata su questo repo.
   Misure prese dal vivo su ?__lane=blue, 1405px, locale it-IT (senza quel
   locale si misura la pagina inglese credendo di misurare l'italiana). */

/* i titoli di fascia: la fonte NON li fa tutti uguali.
   ⚠️ I selettori sono quelli VERI del markup generato, non indovinati: il
   primo giro usava `.sec-video h2` e `.sec-partner h2`, classi che non
   esistono, e cinque regole su dieci non facevano niente senza dare errore.
   Verificare che un selettore selezioni, prima di crederlo scritto. */
.page-home .sec:has(> .wrap > .playlist) h2 { font-size: var(--titolo-fascia); text-align: left; }
.page-home .titolo-minore { font-size: var(--titolo-minore); text-align: left; }
.page-home .foot-cta h2 { font-size: var(--titolo-fascia); text-align: left; }

/* l'eroe: peso 700, non 800 */
.page-home .hero h1 { font-weight: 700; }
/* le due promesse: h3 18px/500 nella fonte, da noi uscivano 20px/620 */
.page-home .promessa h3,
.page-home .promessa h3 .mark { font-size: 18px; font-weight: 500; }
/* l'occhiello sopra il titolo: 22px, non 30 */
.page-home .hero .hero-occhiello,
.page-home .hero > .wrap > p:first-child { font-size: 22px; font-weight: 600; }
/* la missione: nella fonte è un h3 da 25px/500, da noi un riquadro KPI a 17px */
/* ⚠️ `.kpi b`, non `.kpi > b`: il markup annida due <b> (`<b><b>La nostra
   missione</b> su Webgas.net…</b>`) e la regola sul solo figlio diretto
   lasciava quello interno a 17px, cioe' proprio le tre parole che si leggono
   per prime. */
.page-home .missione .kpi b { font-size: 25px; font-weight: 500; }

/* ⚠️ I pulsanti della fonte sono CINQUE stili diversi, non uno: censiti in
   AGENTS.md il 2026-08-22, e allora fu allineato solo `.hero-home .hero-cta`.
   Questi sono gli altri quattro, misurati oggi sulla home italiana. */
/* «Scopri come possiamo aiutarti»: trasparente, 12px/700 — da noi giallo
   14px/600. ⚠️ Non ha la classe `.secondaria`: e' il `.hero-cta` che segue
   il riquadro `.missione`, e cercarlo per classe non lo trovava. */
.page-home .missione + .hero-cta { background: transparent; border: 1px solid var(--ink);
  font-size: 12px; font-weight: 700; }
/* «Scopri il Servizio» x3: 16px, non 13 */
.page-home .servizi .hero-cta { font-size: 16px; }
/* «Partecipa al sondaggio»: fondo BIANCO nella fonte, non giallo */
.page-home .servizi .riquadro-quiz .hero-cta,
.page-home .servizi > *:last-child .hero-cta { background: #fff; font-size: 16px; }
/* «Vedi tutti i casi di studio» / «Vedi tutte le recensioni» / «Vai all'area
   stampa»: 11px/700, non 14px/600 */
.page-home .sec .hero-cta.secondaria { font-size: 11px; font-weight: 700; }

/* ---------- la home: la prosa come la fonte ----------
   ⚠️ Misurato con `confronta-ux.mjs` il 2026-09-12: la fonte mette il testo a
   22px GIUSTIFICATO su una colonna di 1200px; noi a 17px a sinistra su 758.
   È la differenza che pesa di più sull'impressione «sembra diversa», più di
   ogni titolo — e nessuno dei due collaudi di testo la vede, perché le parole
   ci sono tutte. */
/* ⚠️ Solo la prosa di FASCIA (`.sec > .wrap > .prose`), non ogni `.prose`
   della pagina: al primo giro la regola larga ha preso anche il sottotitolo
   dell'eroe e le descrizioni delle schede servizio, portandole a 22px
   giustificate quando la fonte le vuole a 24 centrate e a 18 a sinistra.
   Misurato con `confronta-ux.mjs`: le differenze erano scese da 71 a 61 ma
   tre erano NUOVE, create da me. Restringere e rimisurare. */
/* ⚠️ SOLO la fascia che contiene il riquadro della missione. La fonte
   giustifica SETTE nodi di testo su tutta la home; con `.sec > .wrap > .prose`
   ne giustificavo quattordici — la fascia «Dai brand storici alle startup»,
   che la fonte centra a 20px, finiva giustificata a 22. Misurato con
   `confronta-ux.mjs`: allineamenti della fonte center×42 start×42 justify×7,
   i nostri erano start×34 center×31 justify×14.
   ⚠️ Ed e' la SECONDA volta che questa stessa regola esce troppo larga: la
   prima aveva preso il sottotitolo dell'eroe. Una regola di tipografia scritta
   sul contenitore generico prende sempre piu' di quello che si pensa. */
.page-home .sec:has(.missione) > .wrap > .prose { max-width: 1200px; }
.page-home .sec:has(.missione) > .wrap > .prose p { font-size: 22px; text-align: justify; }
/* il riquadro della missione: nella fonte è centrato, in Montserrat 700 */
.page-home .missione .kpi { text-align: center; }
.page-home .missione .kpi b { font-family: var(--display), Montserrat, sans-serif;
  font-weight: 700; }
.page-home .missione .kpi > span { display: block; text-align: center; }
/* i pulsanti: la fonte li centra */
.page-home .hero-azioni,
.page-home .missione + .hero-cta,
.page-home .servizi .hero-cta { text-align: center; }
/* l'etichetta del muro clienti: a sinistra come nella fonte */
.page-home .sec-clienti h2,
.page-home .titolo-clienti { text-align: left; }

/* ---------- home: tre gruppi misurati con confronta-ux.mjs ----------
   ⚠️ Chiudono cluster, non casi singoli: senza raggruppare si finisce a
   scrivere una regola per riga di testo. */
/* ⚠️ NIENTE regola sulla larghezza dei titoli di fascia. Provata
   (`max-width: none`) e misurata: ne allinea due — «Come abbiamo cambiato» e
   «Dai brand storici», che la fonte tiene a 1200 — e ne rompe due che gia'
   combaciavano, «servizi per scalare il tuo Brand» (628) e «Non sei ancora
   sicuro delle tue esigenze?» (823). Somma zero, e due elementi peggiorati:
   la larghezza di un titolo qui e' la larghezza naturale del suo riquadro, non
   una proprieta' da fissare. Scritto per non riprovarci.
*/
/* le descrizioni delle schede servizio: peso 600 nella fonte, 400 da noi */
.page-home .servizio > .prose p { font-weight: 600; }
/* le etichette della playlist video: 18,2px/500 nella fonte, 15px/600 da noi */
.page-home .playlist .scelte span { font-size: 18.2px; font-weight: 500; }
/* la fascia dei volti: la fonte la centra a 20px, non giustificata */
.page-home .volti .prose p { font-size: 20px; text-align: center; }

/* ---------- paginazione degli archivi ----------
   ⚠️ L'indice del blog della fonte mostra 15 articoli per pagina e un
   controllo visibile «1 · 2 · 3 · 4»; il nostro ne metteva 39 su una pagina
   sola, alta il doppio (8.675 contro 4.139). Misurato il 2026-09-12. */
.paginazione { padding: 0 0 clamp(56px, 8vw, 96px); }
.paginazione .wrap { display: flex; gap: 8px; justify-content: center; }
.page-numbers { display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; height: 44px; padding: 0 12px; border: 1px solid var(--rule);
  text-decoration: none; color: var(--ink); font-weight: 600; }
.page-numbers:hover { border-color: var(--ink); }
.page-numbers.current { background: var(--ink); color: #fff; border-color: var(--ink); }

/* ── /it/recensioni/ e /en/reviews/ ─────────────────────────────────────────
   Misurato sulla fonte con un browser a 1405px (`.migration/mobile/
   cattura-recensioni.mjs` e `confronta-ux.mjs`), non dedotto dal markup.
   La pagina della fonte e' fatta di tre fasce in quest'ordine:
     1. quattro testimonianze scritte su DUE colonne (x=94 e x=753, w=559)
     2. dieci righe video a zig-zag: logo da un lato, player 603x339
        dall'altro, ~490px di riga
     3. «Sei in buona compagnia» col carosello delle cinque recensioni
   Il generatore le montava come quattordici schede in una griglia sola e con
   la fascia 3 in cima: stesso testo, 3910px di pagina in piu' e una lettura
   diversa. L'ordine lo rimette `build_services.page()`; qui c'e' la resa.
   ⚠️ Tutto sotto `body.page-recensioni`: `.testimonianza` e `.recensioni`
   sono classi condivise — le usano anche le pagine servizio e chi-siamo —
   e ritoccarle globalmente avrebbe spostato pagine che oggi combaciano. */
/* ⚠️ `13.6vw` e `184px`, non `14vw` e `198px`. Segnalato dal committente il
   2026-09-29 — «da mac la scritta NI va da capo» — ed e' aritmetica, non
   gusto: «RECENSIONI» in Montserrat 800 e' larga 6,495 volte il corpo, quindi
   a 14vw chiede 90,93vw mentre il contenitore (`.wrap`) ne dà 90. Mancavano
   fra i 6 e i 12 pixel, e la parola si spezzava a META' — «RECENSIO / NI» —
   a OGNI larghezza misurata, da 360 a 1512, non solo sul Mac.
   Col tetto: 198px chiedono 1286px e il contenitore massimo e' 1200.
   184 = 1200 / 6,495, cioe' il corpo piu' grande che ci sta. 13,6vw = 90 / 6,495
   con un margine, perche' a 13,857 il pareggio sarebbe esatto.

   ⚠️ 198px E' il valore della fonte (`eroe.json`, misurato a 1405px): NON si
   poteva tenere. Il nostro contenitore e' 1200 e la parola ne vuole 1286 —
   o cresce il riquadro o cala il corpo, e il riquadro e' quello di tutto il
   sito. Il 7% in meno e' una deroga consapevole, chiesta dal committente.
   ⚠️ Non provato contro la corsia blu: quel giorno l'origine WordPress
   rispondeva 522 su ogni tentativo. I numeri qui vengono dal censimento
   `eroe.json` e dalla misura diretta della parola, non dal confronto.
   ⚠️ NON tocca /en/reviews/, che non porta `page-recensioni` e usa il sistema
   generico `--eroe-dim`: li' «REVIEWS» a 198px vuole 970px e si spezza fra i
   768 e i ~1080, dove il contenitore scende sotto. Difetto vero ma diverso,
   su una pagina di area A: segnalato, non corretto qui. */
body.page-recensioni main .hero h1 { font-size: var(--titolo-eroe); line-height: .9; }
body.page-recensioni .hero .prose p { font-size: 24px; font-weight: 400;
  font-family: var(--body); }
body.page-recensioni .hero .hero-cta { font-size: 18px; font-weight: 400;
  font-family: var(--body); }

/* fascia 1 — due colonne fisse, non `auto-fit`: la fonte ne tiene due anche
   quando la scheda e' corta, e `auto-fit` ne faceva quattro in fila */
/* ⚠️ Il contenitore di questa fascia e' piu' largo del `.wrap` comune: sulla
   fonte le due schede stanno a x=60 e x=719 ed sono larghe 627, cioe' un
   blocco da 1286 con 32 di passo; il nostro `.wrap` e' 1200 con passo 60, e
   le schede uscivano 570. Si allarga QUI e non `.wrap`, che e' chrome
   condiviso da tutte e 429 le pagine. */
/* ⚠️ `calc(1286px + 2 * gutter)`: `.wrap` porta il gutter nel PADDING, quindi
   una `max-width` di 1286 lascia 1158 di contenuto e le schede uscivano 559
   invece di 627 — piu' strette di prima della correzione. */
body.page-recensioni .sec-rec-scritte .wrap {
  max-width: calc(1286px + 2 * var(--gutter));
}
body.page-recensioni .sec-rec-scritte .recensioni { grid-template-columns: repeat(2, 1fr);
  gap: 40px 32px; }
/* ⚠️ Qui c'era `border: 0; padding: 0`, e la scheda usciva senza scatola.
   Veniva da una misura sull'elemento SBAGLIATO: il commento sopra annota
   «w=559», che e' il `blockquote` INTERNO. La scheda vera e' 627x638 —
   559 + 32 di padding per lato + 2 di bordo per lato — con
   `border: 2px solid rgb(221,221,221)` e `border-radius: 4px`.
   Misurato il 2026-09-14 smontando la scheda della fonte elemento per
   elemento invece di cercarne uno. Senza la scatola le quattro recensioni
   scivolavano una nell'altra: e' la differenza che si vede aprendo la
   pagina, prima ancora di leggere. */
body.page-recensioni .sec-rec-scritte .testimonianza {
  border: 2px solid #ddd; border-radius: 4px; padding: 32px; gap: 32px;
}
/* La scheda della fonte, smontata figlio per figlio a 1405px:
     y=34  h=100  il logo del cliente
     y=166 h=27   le stelle          (32 di passo dopo il logo)
     y=225 h=291  la citazione       (32 di passo dopo le stelle)
     y=516 h=88   nome e ruolo
   34 + 100 + 32 + 27 + 32 + 291 + 88 + 32 di padding + 2 di bordo = 638.
   Da noi il logo era alto 32 e i passi 12: la scheda usciva 513 invece di 638.
   ⚠️ `height: auto !important` perche' l'altezza di `.marchio` la scrive
   INLINE `ritaglia_marchi.py`, che la calcola ad area costante per le fasce
   di marchi — un criterio giusto la', sbagliato qui, dove la fonte da' ai
   loghi cliente un riquadro da 200x100. Senza `!important` la regola non
   tocca niente e sembra applicata. */
body.page-recensioni .sec-rec-scritte .testimonianza .marchio {
  height: auto !important; max-height: 100px; max-width: 200px;
  object-fit: contain; object-position: left center;
}
/* Nome e ruolo occupano 88px sulla fonte (nome a y=516, ruolo a y=547),
   da noi 54: fra le due righe c'e' piu' respiro di quanto ne dia
   l'interlinea. */
body.page-recensioni .sec-rec-scritte .firma { line-height: 1.55; }
body.page-recensioni .sec-rec-scritte .firma span { margin-top: 6px; }
body.page-recensioni .sec-rec-scritte .dice p,
body.page-recensioni .sec-rec-scritte blockquote p { font-size: 20px; line-height: 1.6;
  color: rgb(63, 68, 75); }
body.page-recensioni .sec-rec-scritte .firma { font-size: 20px; font-weight: 400;
  font-family: var(--body); color: var(--ink); }
/* Il RUOLO e' 16px/700 sulla fonte, non 20px/400 come il nome: sono due
   informazioni diverse e la fonte le distingue. Da noi erano identiche. */
body.page-recensioni .sec-rec-scritte .firma span {
  display: block; font-size: 16px; font-weight: 700; color: #0d0d0d;
}
/* Il grande segno di citazione: sulla fonte e' un `::before` sul blockquote,
   «“» a 80px in rgb(215,215,215). Da noi non c'era. Non e' decorazione: e'
   quello che dice «qui qualcuno sta parlando» prima che tu legga il nome. */
body.page-recensioni .sec-rec-scritte .quote { position: relative; }
body.page-recensioni .sec-rec-scritte .quote::before {
  content: "\201C"; display: block; font-family: var(--body);
  font-size: 80px; line-height: .8; color: #d7d7d7;
}
/* Le stelle sono 27x27 sulla fonte, da noi 15px di corpo.
   ⚠️ Il COLORE resta #8a6600 e non si tocca: le nostre stelle sono
   CARATTERI, non icone, quindi ogni verifica automatica le misura come testo
   e il giallo su bianco fa 2,00:1. Sta scritto due volte in questo foglio,
   ed e' una decisione, non una svista. Qui si cambia solo la misura. */
body.page-recensioni .sec-rec-scritte .stelle { font-size: 27px; line-height: 1; }

/* fascia 2 — una riga per video. `data-lato` dice da che parte sta il LOGO
   nella fonte; il player va dall'altra. Le due colonne sono 1fr/603px e si
   scambiano con `direction`, non duplicando le regole. */
/* il passo fra una riga e l'altra nella fonte e' ~490px con righe alte ~340:
   il vuoto fra due righe vale quanto meta' riga, e con `gap: 56px` la fascia
   usciva 1000px piu' corta */
body.page-recensioni .sec-rec-video .wrap { display: grid; gap: 150px; }
body.page-recensioni .rec-riga { border: 0; padding: 0;
  display: grid; grid-template-columns: 1fr 603px;
  /* ⚠️ `row-gap: 0`, e la spaziatura verticale va sui margini dei figli. Il
     player scavalca le righe implicite della colonna di testo con uno `span`,
     e ogni riga implicita vuota si porta dietro il proprio gap: con `gap: 40px`
     la riga usciva alta 1043px invece di 339 — cinque volte la fonte. */
  row-gap: 0; column-gap: 40px; align-content: center; }
body.page-recensioni .rec-riga[data-lato="dx"] { grid-template-columns: 603px 1fr; }
body.page-recensioni .rec-riga > .marchio { grid-column: 1; grid-row: 1;
  align-self: end; margin-bottom: 22px; }
body.page-recensioni .rec-riga > .dice,
body.page-recensioni .rec-riga > .firma,
body.page-recensioni .rec-riga > .stelle,
body.page-recensioni .rec-riga > .hero-cta { grid-column: 1; }
body.page-recensioni .rec-riga > .video { grid-column: 2; grid-row: 1 / span 10;
  align-self: center; aspect-ratio: 603 / 339; }
body.page-recensioni .rec-riga[data-lato="dx"] > .marchio,
body.page-recensioni .rec-riga[data-lato="dx"] > .dice,
body.page-recensioni .rec-riga[data-lato="dx"] > .firma,
body.page-recensioni .rec-riga[data-lato="dx"] > .stelle,
body.page-recensioni .rec-riga[data-lato="dx"] > .hero-cta { grid-column: 2; }
body.page-recensioni .rec-riga[data-lato="dx"] > .video { grid-column: 1; }
body.page-recensioni .rec-riga .dice { margin-bottom: 18px; }
body.page-recensioni .rec-riga .dice p { font-size: 20px; font-weight: 300; line-height: 1.6; }
body.page-recensioni .rec-riga .hero-cta { font-size: 12px; font-weight: 700; text-align: center;
  justify-self: start; }

/* fascia 3 — il titolo della fonte e' 35px allineato a sinistra, non 32px
   centrato come il resto delle fasce del design system. Le schede sono 580x82
   con la foto tonda da 36px, tutte e cinque su UNA riga: la fonte le fa
   scorrere con Swiper, qui scorrono a mano (stessa impaginazione, niente
   movimento automatico — la nota sopra `.recensioni` spiega perche'). In
   griglia andavano a capo e la fascia usciva 1170px invece di 609. */
body.page-recensioni .sec-lead:has(.recensione) > .wrap > h2 { font-size: var(--titolo-fascia);
  text-align: left; max-width: none; }
body.page-recensioni .sec-lead:has(.recensione) .recensioni { display: flex;
  overflow-x: auto; gap: 22px;
  scroll-snap-type: x mandatory; padding-bottom: 8px; }
body.page-recensioni .sec-lead:has(.recensione) .recensione { flex: 0 0 580px; scroll-snap-align: start;
  border: 0; padding: 0; gap: 10px;
  grid-template-columns: 36px 1fr; align-items: center; }
body.page-recensioni .sec-lead:has(.recensione) .recensione img { width: 36px; height: 36px; grid-row: 1; }
body.page-recensioni .sec-lead:has(.recensione) .recensione cite { grid-column: 2; grid-row: 1; }
body.page-recensioni .sec-lead:has(.recensione) .recensione .quote { grid-column: 1 / -1; }
body.page-recensioni .sec-lead:has(.recensione) .recensione .quote p { font-size: 14px; }

@media (max-width: 1024px) {
  body.page-recensioni .sec-rec-scritte .recensioni,
  body.page-recensioni .rec-riga,
  body.page-recensioni .rec-riga[data-lato="dx"] { grid-template-columns: 1fr; }
  body.page-recensioni .rec-riga > .video,
  body.page-recensioni .rec-riga[data-lato="dx"] > .video { grid-column: 1; grid-row: auto; }
  body.page-recensioni .rec-riga[data-lato="dx"] > .marchio,
  body.page-recensioni .rec-riga[data-lato="dx"] > .dice,
  body.page-recensioni .rec-riga[data-lato="dx"] > .firma,
  body.page-recensioni .rec-riga[data-lato="dx"] > .stelle,
  body.page-recensioni .rec-riga[data-lato="dx"] > .hero-cta { grid-column: 1; }
}

/* ── Le pagine pilastro dei servizi ─────────────────────────────────────────
   `/it/servizi/<slug>/` e `/en/services/<slug>/`. Misurate sulla fonte a
   1405px (`.migration/mobile/cattura-pilastri.mjs`, che scrive
   `.migration/pilastri.json`).

   Il difetto non era il corpo del carattere: era la STRUTTURA. Il dump non
   porta la gerarchia — tutti i titoli sono lo stesso widget Elementor con le
   stesse classi — e il compositore le rendeva tutte allo stesso modo: venti
   sezioni a piena larghezza, titolo centrato a 32px. La fonte ha invece
   titoli di fascia a 40px allineati a sinistra e larghi 1285, e sotto di
   loro le schede in griglia a DUE colonne, 617px l'una, con un filo grigio
   attorno e il titolo a 22px.
   La gerarchia la rimette `impagina_pilastro()`; qui c'e' la resa. */
/* il corpo lo porta la sezione in `--titolo`, misurato per fascia; il 40px
   resta solo come ripiego se il dato manca */
body.page-pilastro .sec-fascia > .wrap > h2 {
  font-size: var(--titolo-fascia); text-align: left; max-width: none; margin-inline: 0;
}
body.page-pilastro .sec-fascia > .wrap > .prose p { font-size: var(--prosa, 18px); }
body.page-pilastro .sec-fascia > .wrap > .sub,
body.page-pilastro .sec-lead > .wrap > .sub {
  text-align: left; margin-inline: 0; max-width: none; font-style: normal;
  font-size: var(--prosa, 18px); color: var(--ink);
}
/* ⚠️ L'allineamento NON e' uguale per tutte le fasce, e per un giro l'ho
   sbagliato: avevo spinto a sinistra ogni titolo, ma sulla fonte «Risultati
   convalidati dall'analisi» e «Piu' che numeri» sono centrate. Chi decide e'
   il dato catturato (`data-allin`), non una regola unica — e il dato guarda
   la geometria, non solo `text-align`: un blocco largo 812 che comincia a
   x=297 e' centrato anche se dentro il testo e' allineato a start.
   Visto in uno screenshot, non in un numero: il conto delle differenze non
   era peggiorato, perche' il comparatore confronta `textAlign` e quello
   combaciava davvero. */
body.page-pilastro .sec-lead > .wrap > h2,
body.page-pilastro [data-allin="left"] > .wrap > h2 { text-align: left; margin-inline: 0; }
/* ⚠️ Centrare il BLOCCO, non il testo: sulla fonte `text-align` resta `start`
   anche sulle fasce centrate, ed e' la scatola a essere centrata. Scrivendo
   `text-align: center` la pagina veniva giusta ma il confronto segnalava una
   differenza vera — e su un titolo che va a capo si vedrebbe. */
body.page-pilastro [data-allin="center"] > .wrap > h2 {
  margin-inline: auto; width: fit-content; max-width: 100%;
}
/* l'allineamento del TESTO e' un dato a parte dal centraggio del BLOCCO */
body.page-pilastro [data-testo="center"] > .wrap > h2 { text-align: center; }
body.page-pilastro [data-testo="start"] > .wrap > h2,
body.page-pilastro [data-testo="left"] > .wrap > h2 { text-align: left; }
body.page-pilastro [data-allin="center"] > .wrap > .prose,
body.page-pilastro [data-allin="center"] > .wrap > .sub {
  text-align: center; margin-inline: auto; max-width: 78ch;
}

/* la fascia gialla: la fonte ne colora due di `rgb(255, 213, 1)`, e le nostre
   uscivano bianche */
body.page-pilastro [data-fondo="giallo"] { background: var(--yellow); }
body.page-pilastro [data-fondo="giallo"] h2,
body.page-pilastro [data-fondo="giallo"] .prose p,
body.page-pilastro [data-fondo="giallo"] .sub { color: var(--ink); }
body.page-pilastro [data-fondo="giallo"] .hero-cta {
  background: var(--ink); color: #fff; border-color: var(--ink);
}

/* le copertine dei casi studio: quattro in fila, 232x299 come la fonte */
body.page-pilastro .fila-copertine {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 68px; margin-top: 34px;
}
body.page-pilastro .fila-copertine img {
  width: 232px; height: auto; display: block;
}
/* ⚠️ `.sec-lead .prose` e' `max-width: 78ch; margin-inline: auto`: il
   paragrafo sotto il titolo di fascia partiva 216px piu' a destra del titolo
   stesso. Sulla fonte comincia esattamente sotto, alla stessa x. */
body.page-pilastro .sec-lead > .wrap > .prose { margin-inline: 0; max-width: none; }
body.page-pilastro .sec-lead > .wrap > .prose p { font-size: var(--prosa, 18px); }
/* ⚠️ Su queste pagine la colonna della fonte e' 1285px (x=60..1345), non i
   1200 del design system: le schede escono 617px l'una invece di 588. Solo
   qui — il resto del sito la colonna ce l'ha giusta. */
body.page-pilastro main .wrap { max-width: calc(1285px + 2 * var(--gutter)); }

/* le schede, due per riga come la fonte (617px l'una in una colonna da 1285) */
body.page-pilastro .griglia-pilastro {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px; margin-top: 28px;
}
body.page-pilastro .scheda-pilastro {
  border: 1px solid #eee; padding: 30px 32px;
  display: grid; gap: 12px; align-content: start;
}
body.page-pilastro .scheda-pilastro h3 {
  font-size: 22px; line-height: 1.25; text-transform: uppercase;
  letter-spacing: 0; margin: 0;
}
/* ⚠️ Nero PURO, non `--ink` (#0d0d0d). Su questa famiglia di pagine la fonte
   usa `rgb(0, 0, 0)` per il testo delle schede — misurato su tutte e dieci.
   Non si tocca `--ink` globale: sulla home la fonte usa ENTRAMBI i neri, 26
   nodi puri e 25 a #0d0d0d, e cambiare la variabile ne aggiusterebbe 26 e ne
   romperebbe 25. Qui invece e' uniforme, quindi si puo' dire. */
body.page-pilastro .scheda-pilastro h3,
body.page-pilastro .scheda-pilastro .sub,
body.page-pilastro .scheda-pilastro p { color: #000; }
body.page-pilastro .scheda-pilastro .sub,
body.page-pilastro .scheda-pilastro p {
  /* il corpo delle schede sulla fonte e' 18px ma in SEMIGRASSETTO */
  font-size: 18px; font-weight: 600; line-height: 1.5;
  font-style: normal; text-align: left; margin: 0; max-width: none;
}

/* la filigrana: sulla fonte e' un titolo da 400px in grigio chiarissimo,
   tagliato dai bordi della pagina — sfondo tipografico, non un titolo da
   leggere. Si copia com'e': il testo resta nel DOM (c'e' anche li'), ma
   `aria-hidden` no, perche' e' l'unico posto dove quella frase compare. */
body.page-pilastro .sec-filigrana { padding-block: 0; overflow: hidden; }
body.page-pilastro .sec-filigrana > .wrap { max-width: none; padding-inline: 60px; }
body.page-pilastro .sec-filigrana > .wrap > h2 {
  font-size: clamp(96px, 28vw, 400px); line-height: .95;
  color: #f1f1f1; white-space: nowrap; text-align: left;
  margin-inline: 0; max-width: none; letter-spacing: -0.03em;
}

@media (max-width: 900px) {
  body.page-pilastro .griglia-pilastro { grid-template-columns: 1fr; }
}

/* l'eroe delle pilastro, misurato sulla fonte a 1405px:
   occhiello 24px Open Sans 400 bianco · h1 88px Montserrat 800 GIALLO ·
   gancio 22px Open Sans 500 bianco a piena colonna · pulsante a CONTORNO
   giallo, testo giallo 15px/700 Open Sans, largo 320.
   Il nostro aveva occhiello 15px grigio Montserrat, h1 104px, gancio 26px/700
   e un pulsante pieno con testo scuro: quattro elementi su quattro diversi. */
body.page-pilastro .hero .hero-occhiello {
  font-size: 24px; font-weight: 400; font-family: var(--body);
  color: #fff; letter-spacing: 0; text-transform: none;
}
body.page-pilastro .hero h1 { font-size: var(--titolo-eroe); font-weight: 800; }
body.page-pilastro .hero .hero-hook {
  font-size: 22px; font-weight: 500; font-family: var(--body);
  color: #fff; max-width: none;
}
body.page-pilastro .hero .hero-cta {
  /* ⚠️ Niente maiuscolo e niente spaziatura: sulla fonte l'etichetta e' in
     tondo, e larga 320px contro i nostri 500 proprio per questo. */
  text-transform: none; letter-spacing: 0;
  font-size: 15px; font-weight: 700; font-family: var(--body);
  background: transparent; color: var(--yellow);
  border: 1px solid var(--yellow); border-radius: 0; padding: 14px 26px;
}
body.page-pilastro .hero .hero-cta:hover { background: var(--yellow); color: var(--ink); }

/* ── Le posizioni aperte, quando NON portano l'attacco ──────────────────────
   `/it/lavora-con-noi/` e `/en/work-with-us/`: la fonte le mette in TRE
   COLONNE, scheda 355x141 su fondo `rgba(241,243,245,.5)` senza bordo, titolo
   nero 18px/700 e sotto «Sono Interessato »» in giallo. Noi le rendevamo come
   un elenco verticale con le righe divisorie — la resa dell'ARCHIVIO.
   ⚠️ Lo scope non e' una classe sul body ma la FORMA del contenuto: le schede
   dell'archivio `/en/job/` hanno `.offerta-gancio`, queste no. Cosi' la regola
   non puo' raggiungere l'archivio nemmeno per sbaglio — ed e' l'archivio che
   l'attacco lo vuole, perche' li' chiudeva 22 buchi di parita' su 25. Serviva
   anche perche' le due pagine passano da due generatori diversi: una classe
   sul body andrebbe aggiunta in due punti, e uno dei due non e' mio. */
.offerte:not(:has(.offerta-gancio)) {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 30px; border-top: 0; margin-top: 34px;
}
.offerte:not(:has(.offerta-gancio)) li {
  border-bottom: 0; background: rgba(241, 243, 245, .5);
}
.offerte:not(:has(.offerta-gancio)) a {
  padding: 30px; gap: 14px; align-items: start; min-height: 141px;
}
.offerte:not(:has(.offerta-gancio)) a:hover { padding-left: 30px; }
.offerte:not(:has(.offerta-gancio)) .offerta-testa { display: block; }
.offerte:not(:has(.offerta-gancio)) .offerta-testa > h3 {
  display: block; font-size: 18px; font-weight: 700; line-height: 1.3; color: #000;
}
/* ⚠️ Etichetta GIALLA su fondo chiarissimo. E' poco leggibile, ed e' quello
   che fa la fonte: misurato `rgb(255,213,1)` su `rgba(241,243,245,.5)`.
   Copiata, non «migliorata»: la consegna e' ricopiare, e un ritocco qui
   sarebbe una nostra decisione mascherata da correzione. */
.offerte:not(:has(.offerta-gancio)) .offerta-invito {
  display: block; margin-top: 12px; font-size: 12px; font-weight: 700;
  color: var(--yellow);
}
@media (max-width: 900px) {
  .offerte:not(:has(.offerta-gancio)) { grid-template-columns: 1fr; gap: 24px; }
}

/* l'eroe di `/it/lavora-con-noi/` e `/en/work-with-us/`: la fonte lo tiene a
   50px, noi a 104. Stesso scope «per forma», stesso motivo. */
/* ⚠️ Qui c'era `body:has(.offerte:not(:has(.offerta-gancio)))`, che NON E' UN
   SELETTORE VALIDO: `:has()` non si annida dentro `:has()`. Il browser
   scartava l'intera regola senza dire niente, e l'h1 che avevo dichiarato
   sistemato e' rimasto a 104px invece di 50 — riportato come risolto in una
   PR. Il controllo che lo trova ora esiste: `.migration/mobile/selettori.mjs`.
   La classe sul body la mette `build_services.py` per l'italiano; l'inglese
   passa da `build_pagine.py` e per ora resta scoperto. */
body.page-posizioni main .hero h1 { font-size: var(--titolo-eroe); }

/* ⚠️ Solo `/it/lavora-con-noi/`, e la gemella inglese NON la tocca: le due
   pagine hanno strutture diverse sulla fonte. In italiano «Entra a far parte
   del Team.» e' testo a 22px/400 sotto l'eroe; in inglese quella riga non
   esiste — l'eroe e' «Join Our Team.» — e la sezione nella stessa posizione e'
   «Open Position», che oggi combacia gia'. Una regola posizionale avrebbe
   aggiustato l'italiano e rotto l'inglese: verificato misurando la gemella
   PRIMA di scriverla. Qui la classe sul body si puo' mettere, perche' quella
   pagina la costruisce `build_services.py`, che e' di quest'area. */
body.page-posizioni main .hero + .sec-lead > .wrap > h2 {
  font-size: var(--titolo-fascia); font-weight: 400; text-transform: none;
  text-align: left; margin-inline: 0; max-width: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   FAMIGLIA «chi siamo» — /it/chi-siamo/ e /en/about-us/  (area B, 2026-09-13)

   Due pagine sole, entrambe composte a mano da `layout_about_us.py`. Tutto
   sotto `body.page-about`: le classi che questa famiglia usava prima
   (`.sec-dark`, `.sec-lead`, `.mark`) sono condivise da 427 pagine e NON vanno
   toccate per far quadrare due pagine.

   Misure prese sulla fonte a 1405px il 2026-09-13 con getComputedStyle +
   getBoundingClientRect, non a occhio. La fonte ha `.wrap` 1285, noi 1200: lo
   scarto e' un difetto globale fuori da questo perimetro, quindi le colonne
   qui sono in PERCENTUALE e non in pixel — inseguire 450px su un contenitore
   piu' stretto avrebbe spostato la proporzione invece di ricopiarla.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── il metodo TCR: fascia CHIARA, due colonne ────────────────────────────
   Fonte: fascia rgba(241,243,245,.5) alta 852, titolo 30px/700 centrato,
   colonna formula 450 + gap 88 + prosa 747 su 1285 (35% / 6.85% / 58%). */
body.page-about .sec-metodo { background: rgba(241, 243, 245, .5); }
body.page-about .sec-metodo h2 {
  font-size: var(--titolo-fascia); font-weight: 700; text-align: center;
}
/* ⚠️ Sulla fonte «metodo inverso» e' bianco su NERO, non scuro su giallo:
   `.mark` di sistema e' giallo con testo #0d0d0d e qui renderebbe il
   contrario esatto. Override scoped, la regola condivisa resta com'e'. */
body.page-about .sec-metodo h2 .mark {
  background: #0d0d0d; color: #fff; padding: .06em .18em;
}
body.page-about .metodo {
  display: grid; grid-template-columns: 35% minmax(0, 1fr); gap: 6.85%;
  align-items: start; margin-top: 34px;
}
body.page-about .metodo .formula {
  display: grid; gap: 14px; justify-items: stretch; margin: 0;
}
/* le tre schede bianche: 450x160 sulla fonte, sigla gialla + voce accanto */
body.page-about .metodo .passo {
  display: flex; align-items: center; gap: 26px; background: #fff;
  min-height: 160px; padding: 20px 30px;
}
body.page-about .metodo .passo .sigla {
  font-family: var(--display); font-weight: 700; line-height: 1;
  font-size: clamp(38px, 6vw, 66px); color: var(--yellow); flex: 0 0 auto;
  min-width: 1.4em; text-align: center;
}
/* ⚠️ 25px/700 in tondo: la fonte NON fa maiuscolo qui, e la regola generale
   `.formula .voce` invece lo fa (uppercase + letter-spacing). */
body.page-about .metodo .passo .voce {
  font-family: var(--display); font-weight: 700; font-size: clamp(18px, 1.9vw, 25px);
  text-transform: none; letter-spacing: 0; align-self: center; text-align: center;
}
body.page-about .metodo .formula .segno {
  font-family: var(--display); font-weight: 700; font-size: clamp(20px, 2.6vw, 30px);
  color: var(--ink); text-align: center; display: block;
}
body.page-about .metodo-prosa .prose { font-size: 17px; }

/* ── il richiamo a Uptonica: fascia nera a se', testo bianco centrato ───── */
body.page-about .sec-uptonica { background: #0d0d0d; padding-block: 34px; }
body.page-about .sec-uptonica .prose,
body.page-about .sec-uptonica .prose p { color: #fff; text-align: center; }
body.page-about .sec-uptonica a { color: var(--yellow); }

/* ── rassegna stampa: titolo a sinistra (422 su 1285 ≈ 33%), marchi accanto ─ */
body.page-about .rassegna {
  display: grid; grid-template-columns: 33% minmax(0, 1fr); align-items: center;
  column-gap: 2%;
}
body.page-about .rassegna h2 { margin: 0; text-align: start; }
body.page-about .rassegna .loghi { margin-top: 0; justify-content: flex-end; }
@media (max-width: 820px) {
  body.page-about .rassegna { grid-template-columns: 1fr; row-gap: 24px; }
  body.page-about .rassegna .loghi { justify-content: flex-start; }
}

/* ── elementi distintivi: schede BIANCHE, non un filetto giallo ───────────
   Fonte: titolo 35px centrato; schede 415x378 con padding 50, h3 25px/700. */
body.page-about .sec-alt:has(.distintivi) h2 {
  font-size: var(--titolo-fascia); text-align: center;
}
body.page-about .distintivi { gap: 20px; }
body.page-about .distintivi article {
  background: #fff; border-top: 0; padding: clamp(24px, 3.4vw, 50px);
}
body.page-about .distintivi h3 { font-size: clamp(19px, 1.9vw, 25px); font-weight: 700; }

/* ── partner ufficiali: Title Case a sinistra su fondo #f5f5f5 ───────────
   Prima ereditava `.sec-lead h2`: MAIUSCOLO e centrato, che la fonte non ha. */
body.page-about .sec-partner { background: #f5f5f5; }
body.page-about .sec-partner h2 {
  font-size: var(--titolo-fascia); font-weight: 700;
  text-transform: none; text-align: start; max-width: none; margin-inline: 0;
}

/* ── invito finale: scheda chiara, non fascia scura col titolo maiuscolo ──
   Fonte: fascia #f5f5f5 alta 510, scheda bianca 1011x350, h2 35px/700 a
   sinistra con padding 50. */
body.page-about .sec-invito { background: #f5f5f5; }
body.page-about .sec-invito .wrap {
  background: #fff; padding: clamp(28px, 4vw, 50px);
  display: flex; flex-wrap: wrap; align-items: center; gap: 24px 40px;
}
body.page-about .sec-invito h2 {
  font-size: var(--titolo-fascia); font-weight: 700; color: var(--ink);
  text-transform: none; text-align: start; max-width: none; margin-inline: 0;
}

/* ── la squadra: tre colonne come la fonte, non quattro strette ───────────
   `.squadra` di sistema impacchetta a minmax(158px,1fr) e su 1200 ne entrano
   quattro; la fonte ne mette tre per riga, piu' larghe. */
body.page-about .squadra { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 30px; }
@media (max-width: 820px) { body.page-about .squadra { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { body.page-about .squadra { grid-template-columns: 1fr; } }

/* ── secondo giro, misurato dopo il primo (2026-09-13) ──────────────────────
   Quello che restava dopo aver rimesso le strutture: tipografia e colonne. */

/* ⚠️ Su questa pagina l'evidenziazione della fonte e' NERA con testo bianco, e
   ricorre tre volte: «metodo inverso», «Da Google a Webgas», «Fondatori».
   `.mark` di sistema e' giallo su testo scuro. L'eroe qui NON usa `.mark`
   (verificato nel markup), quindi scoparla a tutta la pagina non lo tocca. */
body.page-about main .mark { background: #0d0d0d; color: #fff; padding: .06em .18em; }

/* la storia: colonna 835 su 1285 (65%), titolo 20px, prosa 16px */
body.page-about .storia { grid-template-columns: minmax(0, 65%) minmax(0, 1fr); }
body.page-about .storia h2 { font-size: 20px; font-weight: 700; }
body.page-about .storia .prose { font-size: 16px; }

/* la prosa del metodo e delle schede distintive e' 18px sulla fonte, non 17 */
body.page-about .metodo-prosa .prose,
body.page-about .distintivi .prose { font-size: 18px; }

/* «Dicono di noi» e' 30px, non i 26 del `.titolo-minore` di sistema */
body.page-about .rassegna h2 { font-size: var(--titolo-fascia); }

/* «Fondatori»: 35px centrato, non il maiuscoletto 13px di `.reparto > h3` */
body.page-about .reparto > h3 {
  font-size: clamp(24px, 2.6vw, 35px); font-weight: 700; text-align: center;
  text-transform: none; letter-spacing: 0; color: var(--ink); margin: 0 0 26px;
}

/* ⚠️ Il richiamo a Uptonica e' largo 1140 e centrato sulla fonte. Toglierlo
   al solo `p` non bastava: la larghezza sta su `.prose`, che restava stretto
   a 661 e ancorato a sinistra — il testo risultava centrato DENTRO una
   colonna storta, che a occhio sembra quasi giusto e non lo e'. */
body.page-about .sec-uptonica .prose,
body.page-about .sec-uptonica .prose p { max-width: none; margin-inline: auto; }

/* l'eroe: h1 126px e gancio 24px/400 in Open Sans (noi 104 e 26/700 Montserrat) */
body.page-about .hero h1 { font-size: var(--titolo-eroe); }
body.page-about .hero .hero-hook {
  font-size: 24px; font-weight: 400; font-family: var(--body);
}
/* il pulsante «Il nostro metodo»: 18px/400 in tondo, non 14px/600 spaziato */
body.page-about .hero .hero-azioni a {
  font-size: 18px; font-weight: 400; font-family: var(--body);
  text-transform: none; letter-spacing: 0;
}

/* la voce della scheda occupa la colonna come sulla fonte (176 su 450) */
body.page-about .metodo .passo .voce { flex: 1; }

/* ── La rassegna stampa di /it/press/ ───────────────────────────────────────
   Sulla fonte e' una fisarmonica: sette pannelli larghi 1285 e alti 53, fondo
   `rgb(242,245,247)`, filo `rgb(213,216,220)`, imbottitura 12/16, titolo 24px
   in grassetto — il primo aperto, gli altri sei chiusi, con 16px d'aria in
   mezzo (passo misurato 69px). Noi li rendevamo tutti aperti: trentadue
   articoli in vista e 1.092px in piu' della fonte. */
.testata {
  border: 1px solid rgb(213, 216, 220);
  background: rgb(242, 245, 247);
  margin-bottom: 16px;
}
.testata > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 12px 16px; min-height: 53px; box-sizing: border-box;
  font-family: var(--display); font-weight: 700; font-size: 24px;
  color: rgb(31, 33, 36);
}
.testata > summary::-webkit-details-marker { display: none; }
.testata > summary::after {
  content: ''; width: 9px; height: 9px; flex: 0 0 auto;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-3px, -3px); transition: transform .18s ease;
}
.testata[open] > summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
.testata > .rassegna { margin: 0; padding: 4px 16px 14px; background: #fff; }
.testata > .rassegna li { padding-left: 26px; }
.testata > .rassegna a { font-size: 20px; font-weight: 500; line-height: 1.5; }
@media (max-width: 700px) {
  .testata > summary { font-size: 18px; }
  .testata > .rassegna a { font-size: 16px; }
}
/* ═══════════════════════════════════════════════════════════════════════════
   «Altre metriche e storie di valore» — /it/casi-studio/ e /en/case-studies/
   (area B, 2026-09-13)

   Classi esclusive di questa fascia: `.card`/`.cards` vestono 97 pagine e non
   si toccano per impaginarne una. Misure prese sulla fonte a 1405px con
   getBoundingClientRect: racconto x=103 largo 344, KPI a x=652 e x=1080
   (due colonne), titolo di fascia 48px centrato, settore 35px, valori 30px.
   ═══════════════════════════════════════════════════════════════════════════ */
.sec-storie h2 { font-size: var(--titolo-fascia); text-align: center; }
.storie { display: grid; gap: clamp(40px, 5vw, 76px); margin-top: clamp(28px, 3.4vw, 46px); }
.storia {
  display: grid; grid-template-columns: minmax(0, 29%) minmax(0, 1fr);
  /* ⚠️ Il vuoto fra racconto e KPI e' largo quanto una colonna: sulla fonte il
     testo finisce a 447 e i valori cominciano a 652. In percentuale perche'
     il nostro `.wrap` e' 1200 contro i 1285 della fonte: 29% + 17% + 54%. */
  column-gap: 17%; row-gap: 28px; align-items: start;
}
/* due soli KPI: la fonte allarga il racconto e incolonna i valori */
.storia-larga { grid-template-columns: minmax(0, 56%) minmax(0, 1fr); }
.storia-testo h3 {
  font-size: clamp(22px, 2.6vw, 35px); font-weight: 700; margin: 0 0 6px;
}
.storia-settore {
  font-size: clamp(16px, 1.5vw, 20px); color: var(--ink); margin: 0 0 16px;
}
.storia-testo .prose { font-size: 16px; }
.storia-more {
  display: inline-block; margin-top: 18px; padding: 14px 26px;
  border: 1px solid var(--ink); font-size: 15px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
}
.storia-more:hover { background: var(--ink); color: #fff; }
/* ⚠️ Multi-colonna, non griglia: la fonte riempie per COLONNE, non per righe.
   Su «Settore Education» la colonna di sinistra porta +17.362, -79,5% e 7x e
   quella di destra +350% e -59% (misurate le y: 4950/4950, 5110/5110, 5270).
   Con `grid` i cinque valori si incolonnavano in ordine diverso — stessi
   numeri, lettura sfasata — e il conto delle differenze non se ne accorgeva,
   perche' i testi ci sono tutti comunque. */
.storia-kpi { columns: 2; column-gap: clamp(16px, 1.8vw, 26px); }
.storia-voce { break-inside: avoid; margin-bottom: clamp(16px, 1.8vw, 26px); }
.storia-larga .storia-kpi { columns: 1; }
.storia-voce {
  background: #fff; padding: clamp(20px, 2.2vw, 30px);
  display: flex; flex-direction: column; gap: 4px; justify-content: center;
}
.storia-voce b {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(22px, 2.4vw, 30px); line-height: 1.1;
}
.storia-voce span { font-size: 14px; color: var(--ink-faint); }
@media (max-width: 900px) {
  .storia, .storia-larga { grid-template-columns: 1fr; column-gap: 0; }
  .storia-kpi, .storia-larga .storia-kpi { columns: 2; }
}
@media (max-width: 520px) {
  .storia-kpi, .storia-larga .storia-kpi { columns: 1; }
}

/* ── indice casi studio, secondo giro (area B, 2026-09-13) ─────────────────
   Correzioni ai valori che la misura sulla fonte a 1405px smentisce. Il blocco
   `.page-casi-indice` piu' sopra resta: qui si ritoccano solo le proprieta'
   sbagliate, non si riscrive l'impaginazione.

   ⚠️ NON tocco la famiglia dei caratteri, che pure e' diversa: la fonte rende
   la prosa in **Lato** e i sottotitoli in Montserrat, noi Open Sans ovunque.
   Lato non e' fra i font del sito (`fonts.css` carica Montserrat e Open Sans)
   e aggiungerne un terzo e' una decisione di prodotto — peso e FOUT su tutte
   le 427 pagine — non una correzione di parita'. Dichiarata, non fatta. */

/* la colonna di testo della scheda e' 600 sulla fonte, non 740: a cambiare
   e' il GAP (1220 - 420 di copertina - 600 = 200), non la colonna. */
body.page-casi-indice .cs-riga { gap: 200px; }
body.page-casi-indice .cs-testo-col h2 { font-size: 35px; }
/* il sottotitolo e' NERO e in Montserrat sulla fonte, non grigio in Open Sans */
body.page-casi-indice .cs-sotto {
  color: var(--ink); font-family: var(--display); font-weight: 600;
}
/* la descrizione e' 20px e piu' chiara del nero pieno */
body.page-casi-indice .cs-testo { font-size: 20px; color: #3a3a3a; }
body.page-casi-indice .cs-scarica { font-size: 16px; font-weight: 600; color: #000; }

/* il titolo della fascia e' largo quanto il testo, non quanto il contenitore */
body.page-casi-indice .sec-storie h2 { display: inline-block; width: auto;
  margin-inline: auto; }
body.page-casi-indice .sec-storie .wrap { text-align: center; }
body.page-casi-indice .sec-storie .storie { text-align: start; }
/* il valore del KPI e' largo quanto la cifra, non quanto la scheda */
body.page-casi-indice .storia-voce { align-items: flex-start; }
/* la prosa delle storie e' GRIGIA sulla fonte (135), non nera */
body.page-casi-indice .storia-testo .prose { color: #878787; }
body.page-casi-indice .storia-more { font-size: 14px; text-align: center; }

/* l'eroe: occhiello 24px/400 in tondo, non 26/700 in Montserrat */
body.page-casi-indice .hero-index .hero-hook,
body.page-casi-indice .hero-index .sec-sub {
  font-size: 24px; font-weight: 400; font-family: var(--body);
}

/* ═══════════════════════════════════════════════════════════════════════════
   «Perché scegliere Webgas» — /it/perche-scegliere-webgas/ e
   /en/why-choose-webgas/  (area B, 2026-09-13)

   ⚠️ Qui la parita' al pixel NON e' un obiettivo realistico, ed e' meglio
   dirlo che inseguirlo: la fonte stila i titoli uno per uno con il CSS
   per-elemento di Elementor (`post-<id>.css`) e ne ha di cinque misure
   diverse — «Recensioni video» 16px, «Visto su:» 24px, «COSA DICONO DI NOI»
   e «Casi studio» 40px/800 — che nessuna regola generale puo' distinguere
   senza inventare una classe per ciascuno. Si allineano qui le FAMIGLIE
   sistematiche, misurate a 1405px; il resto resta dichiarato.

   ⚠️ Tutto sotto `body.page-perche`: `.kpi`, `.kpis` e `.sec-lead` vestono
   anche le 17 pagine servizio dell'area A, e non si toccano.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── i settori: piccoli e GIALLI su #3a3a3a, non 54px neri su chiaro ──────
   Fonte: fascia bg rgb(58,58,58), titolo 24px/700 giallo centrato, valore ed
   etichetta 18px/500 gialli centrati, in riga. Da noi uscivano come fasce a
   piena larghezza con cifre da 54px: stessi numeri, tutt'altro peso visivo. */
/* ⚠️ Su questa pagina il tono scuro e' #3a3a3a, non il #141414 globale di
   `.sec-dark`: misurato sulla fonte sia sulle fasce settore sia sulle tre
   fasce approccio/squadra/partnership, che sono un unico contenitore. Vale
   per tutte le fasce scure della pagina, non solo per le metriche. */
body.page-perche .sec-dark,
body.page-perche .sec-metriche { background: #3a3a3a; }
body.page-perche .sec-metriche h2 {
  font-size: var(--titolo-fascia); font-weight: 700; color: var(--yellow);
  text-align: center; text-transform: none; letter-spacing: 0;
  max-width: none; margin-inline: auto;
}
body.page-perche .sec-metriche .kpis {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(20px, 3vw, 48px); margin-top: 22px;
}
body.page-perche .sec-metriche .kpi {
  background: none; border: 0; padding: 0; text-align: center; min-width: 0;
  /* ⚠️ `container-type: normal` e' OBBLIGATORIO qui, non una rifinitura.
     `.kpi` di sistema porta `container-type: inline-size` perche' il numero
     scali sulla card, e questo implica `contain: inline-size`: il CONTENUTO
     smette di contribuire alla larghezza. In una griglia va bene — la traccia
     una larghezza ce l'ha — ma nel flex che ho messo qui il 2026-09-13 gli
     elementi collassavano a ZERO: i quattordici KPI delle fasce di settore
     erano nel DOM, `visible`, `opacity: 1`, e larghi 0px. Invisibili sullo
     schermo e invisibili al collaudo, che scarta gli elementi sotto i 4px —
     tanto che sembravano «differenze risolte». */
  container-type: normal;
}
body.page-perche .sec-metriche .kpi b {
  display: block; font-size: 18px; font-weight: 500; color: var(--yellow);
  font-family: var(--body); line-height: 1.3;
}
body.page-perche .sec-metriche .kpi span {
  font-size: 18px; color: var(--yellow); line-height: 1.3;
}

/* ── l'eroe: 60px e allineato a sinistra, non 104px centrato ─────────────
   Fonte: h1 60px · occhiello «Dati. Esperienza. Risultati.» 24px/900 in
   Open Sans · gancio 20px/400 allineato a start e largo 450. */
body.page-perche .hero h1 { font-size: var(--titolo-eroe); }
/* ⚠️ `.hero-eyebrow`, NON `.hero-occhiello`: quella classe non esiste e la
   regola scritta il 2026-09-13 era INERTE — l'occhiello e' rimasto 30px/600 in
   Montserrat contro i 24px/900 in tondo della fonte per un giro intero.
   Verificare che un selettore selezioni davvero, non che sembri giusto. */
body.page-perche .hero .hero-eyebrow {
  font-size: 24px; font-weight: 900; font-family: var(--body);
  text-transform: none; letter-spacing: 0;
}
/* ⚠️ `text-align: start; margin-inline: 0` era la misura della fonte, e
   lasciava la frase a SINISTRA sotto un titolo centrato e sopra un pulsante
   centrato: tre assi in un eroe solo (misurato: titolo e pulsante a 703, la
   frase a 366). Centrata su richiesta di Giovanni il 2026-09-30, insieme ai
   pulsanti. Per tornare alla fonte: `start` e `margin-inline: 0`. */
body.page-perche .hero .hero-hook {
  font-size: 20px; font-weight: 400; font-family: var(--body);
  text-align: center; margin-inline: auto; max-width: 46ch;
}

/* ── le recensioni: 18px/500 centrate, e il nome del cliente 18px ────────── */
body.page-perche .testimonianza .prose,
body.page-perche .testimonianza p { font-size: 18px; font-weight: 500; text-align: center; }
body.page-perche .testimonianza b,
body.page-perche .testimonianza .autore { font-size: 18px; font-weight: 500; color: #000; }

/* ── i pulsanti: 18px/700 in tondo, non 14px/600 spaziati in Montserrat ── */
body.page-perche .sec .btn,
body.page-perche .sec-lead .btn,
body.page-perche main a.btn {
  font-size: 18px; font-weight: 700; font-family: var(--body);
  text-transform: none; letter-spacing: 0;
}

/* ── i punti di metodo: schede impilate larghe, non cinque colonne strette ──
   ⚠️ Difetto PREESISTENTE, emerso togliendo lo stile metriche da questa
   fascia. La fonte rende «È bene conoscere il nostro approccio» come cinque
   schede bianche larghe 900, una per riga, con il titolo a 25px/500
   allineato a sinistra. Da noi finivano in una griglia da cinque colonne da
   221px con il titolo a 40px: le parole si spezzavano a meta'
   («Marketin g performa nte»), che e' il genere di cosa che nessun conteggio
   di differenze segnala e che si vede al primo sguardo.
   `:not(.sec-metriche)` distingue queste dalle fasce di numeri. */
body.page-perche .sec-lead:not(.sec-metriche) .kpis {
  grid-template-columns: minmax(0, 1fr); gap: 18px;
  max-width: 900px; margin-inline: auto;
}
/* ⚠️ E IL COLORE DEL TESTO, o la scheda resta illeggibile. Queste cinque
   schede sono BIANCHE (misurato sulla fonte il 2026-09-13: «cinque schede
   bianche larghe 900, una per riga») ma stanno dentro una `.sec-dark`, che
   dichiara `color: #fff`: il testo ereditava i colori del fondo scuro e
   finiva bianco su bianco.
   Misurato il 2026-09-30 sulla pagina pubblicata:
       titolo   #ffd501 su #fff  =  1,6:1
       testo    #d8d8d4 su #fff  =  1,43:1   ← praticamente invisibile
   Segnalato dal committente come «tanti errori» su questa pagina: e' questo,
   e si vede solo guardandola — nessun conteggio di differenze lo diceva.
   ⚠️ I colori non vengono dalla fonte (non fu catturato il colore di queste
   schede, e ora la fonte non c'e' piu'): sono i token del sito per testo su
   chiaro. E' una DECISIONE, non una copia, e va saputo. Un testo a 1,43:1
   pero' non e' una scelta di nessuno: e' rotto. */
body.page-perche .sec-lead:not(.sec-metriche) .kpi {
  background: #fff; padding: clamp(20px, 2.4vw, 30px); text-align: start;
  color: var(--ink-soft);
}
body.page-perche .sec-lead:not(.sec-metriche) .kpi b { color: var(--ink); }
body.page-perche .sec-lead:not(.sec-metriche) .kpi span { color: var(--ink-soft); }
body.page-perche .sec-lead:not(.sec-metriche) .kpi b {
  display: block; font-size: clamp(19px, 2vw, 25px); font-weight: 500;
  font-family: var(--display); text-align: start; line-height: 1.3;
}
body.page-perche .sec-lead:not(.sec-metriche) .kpi span {
  display: block; margin-top: 8px; font-size: 18px; text-align: start;
}

/* ── Il muro clienti su telefono ────────────────────────────────────────────
   ⚠️ A 390px i 51 loghi si impilavano uno sotto l'altro: 2.300px di muro su
   una pagina che ne ha 11.800. La fonte li tiene in SETTE righe che scorrono
   in orizzontale — 537px in tutto, logo medio 137x64 — e ne mostra tre per
   volta lasciando intuire che continuano.
   Si riproduce la forma con una griglia a righe fisse e scorrimento
   orizzontale: `grid-auto-flow: column` riempie per colonne, quindi le righe
   restano sette e l'eccedenza esce di lato invece che in basso.
   ⚠️ `overflow-x` sta sul CONTENITORE: la pagina non deve scorrere di lato,
   solo il nastro. Verificato con `traboccamento.mjs`. */
@media (max-width: 760px) {
  .logos {
    display: grid; grid-auto-flow: column;
    grid-template-rows: repeat(7, auto);
    justify-content: start; align-items: center;
    gap: 18px 30px; overflow-x: auto; overscroll-behavior-x: contain;
    padding-bottom: 6px; scroll-snap-type: x proximity;
  }
  .logos img { max-width: 120px; max-height: 56px; scroll-snap-align: start; }
}

/* ── La playlist video ──────────────────────────────────────────────────────
   Misure della fonte: riquadro 1200x434 sulle pagine pilastro, lista a destra
   larga 396 con passo di riga 55px e miniatura 75x42; su telefono 370x296, con
   il player che NON c'e' e la sola lista che scorre.
   Prima incorporavamo sette player Vimeo: 2.031px su telefono contro 296, e
   sette embed di terze parti caricati sempre. Ora partono al clic. */
.videolista {
  display: grid; grid-template-columns: minmax(0, 1fr) 396px;
  gap: 0; margin-top: 26px; height: 434px;
  border: 1px solid var(--rule);
}
.pl-schermo {
  position: relative; background: #0d0d0d; display: flex;
  align-items: center; justify-content: center; min-width: 0;
}
.pl-schermo iframe { width: 100%; height: 100%; border: 0; display: block; }
.pl-avvia {
  width: 72px; height: 72px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--yellow); display: flex; align-items: center; justify-content: center;
}
.pl-triangolo {
  width: 0; height: 0; margin-left: 5px;
  border-left: 20px solid var(--ink);
  border-top: 12px solid transparent; border-bottom: 12px solid transparent;
}
.pl-acceso .pl-avvia { display: none; }
.pl-voci {
  list-style: none; margin: 0; padding: 0; overflow-y: auto;
  border-left: 1px solid var(--rule); background: #fff;
}
.pl-voce {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 6px 16px; min-height: 55px; border: 0; background: none;
  cursor: pointer; text-align: left; font: inherit; color: var(--ink);
  border-bottom: 1px solid var(--rule);
}
.pl-voce img { width: 75px; height: 42px; object-fit: cover; flex: 0 0 auto; }
.pl-voce span { font-size: 15px; }
.pl-voce:hover { background: #f4f4f1; }
.pl-voce[aria-current="true"] { background: #f4f4f1; font-weight: 600; }

@media (max-width: 900px) {
  /* la fonte su telefono mostra la SOLA lista, alta 296 e scorrevole: il
     player compare quando si sceglie un video */
  .videolista { grid-template-columns: 1fr; height: auto; }
  .pl-schermo { display: none; aspect-ratio: 16 / 9; }
  .videolista.pl-acceso .pl-schermo { display: block; }
  .pl-voci { border-left: 0; max-height: 296px; }
}

/* ── la home: il riquadro della missione e il suo tasto (area B, 2026-09-13) ─
   Segnalato dal committente: il blocco «La nostra missione» sembrava
   decontestualizzato e il tasto sotto era storto. Non era il copy — la fonte
   lo chiude in un RIQUADRO e noi lo rendevamo come una citazione con un
   filetto giallo a sinistra.

   Misure prese sulla fonte a 1405px: widget 1200x256, `1px solid rgb(13,13,13)`,
   `border-radius: 24px`, `padding: 50px 0`, fondo trasparente, e un trofeo
   giallo da 50px centrato sopra il testo (l'SVG sta in `layout_home.py`).
   `.missione` esiste solo sulle due home — verificato su tutte le 429. */
body.page-home .missione {
  border: 1px solid var(--ink); border-radius: 24px;
  padding: clamp(28px, 4vw, 50px) 0; padding-left: 0;
  margin: 30px 0; text-align: center;
}
body.page-home .missione .trofeo {
  display: block; width: 50px; height: 50px; margin: 0 auto 18px;
  fill: var(--yellow);
}
body.page-home .missione .kpi { text-align: center; }

/* ⚠️ Il tasto e' CENTRATO sulla fonte (x=496 su un contenitore da 1200, largo
   413), non allineato a sinistra come usciva da noi. E porta una freccia in
   giu': aggiunta col CSS e non nel testo, cosi' `comandi.py` continua a
   confrontare la stessa stringa. */
body.page-home .missione + .hero-cta {
  display: block; width: max-content; max-width: 100%;
  margin-inline: auto; text-align: center;
  /* 413x50 sulla fonte contro i nostri 333x56: e' il padding, non il testo */
  padding: 16px 46px;
}
body.page-home .missione + .hero-cta::after { content: " \2193"; }
/* la citazione: 22px/700 nera e su UNA riga come la fonte, non 24px/600 grigia
   su due — erano i 66px che restavano fra il nostro riquadro (322) e il suo
   (256), misurati a 1405px. */
body.page-home .missione .kpi span {
  font-size: 22px; font-weight: 700; color: var(--ink);
}

/* ── «chi siamo» sul telefono (area B, 2026-09-13) ─────────────────────────
   ⚠️ Le regole scoped qui sopra hanno specificita' 0,2,0 e SCAVALCANO le media
   query di sistema, che sono 0,1,0: `.storia` tornava a una colonna sotto gli
   820px grazie a `site.css`, ma `body.page-about .storia` la teneva a due. Il
   risultato a 390px era una colonna di testo larga 204-228 contro i 370 della
   fonte — cioe' meta' schermo sprecato, e nessun traboccamento a segnalarlo.
   Chi scope una griglia si prende anche i suoi punti di rottura.

   Misure della fonte a 390px: prosa della storia 14px larga 370, prosa del
   metodo 16,4px larga 369, schede TCR a piena larghezza (310) col titolo a
   22px, «Dicono di noi» 24px CENTRATO, eroe 49,2px e gancio 16px. */
@media (max-width: 820px) {
  body.page-about .metodo { grid-template-columns: 1fr; row-gap: 26px; }
  body.page-about .storia { grid-template-columns: 1fr; }
  body.page-about .storia .prose { font-size: 14px; }
  body.page-about .storia h2 { font-size: 24px; }
  body.page-about .metodo-prosa .prose { font-size: 16.4px; }
  body.page-about .metodo .passo .voce { font-size: 22px; }
  body.page-about .metodo .passo { min-height: 0; }
  body.page-about .rassegna h2 { text-align: center; }
  body.page-about .hero .hero-hook { font-size: 16px; }
  body.page-about .hero .hero-azioni a { font-size: 14px; }
  /* il nome nella scheda persona: 18px/700 sulla fonte, non 17px/620 */
  body.page-about .squadra li b { font-size: 18px; font-weight: 700; }
}
/* l'eroe: 49,2px sulla fonte a 390px, non i 40 del minimo del clamp */
body.page-about .hero h1 { font-size: var(--titolo-eroe); }
/* ── Il piè di pagina, misurato sulla fonte ─────────────────────────────────
   Sta su tutte e 429 le pagine, quindi ogni scarto qui si moltiplica per 429 —
   ed erano sei scarti, tutti tipografici. Misurato a 1405px su
   `/it/tool/klaviyo-strategy-quiz/`, ma il piè e' lo stesso ovunque.

     voci del menu   fonte 14px/400 Montserrat bianco   noi 16px/400 Open Sans #e8e8e4
     «Seguici»       fonte 20px/700                     noi 17px/700
     righe legali    fonte 12px/500 Montserrat #cecece  noi 13px/400 Open Sans #8b8b85
     riga ©          fonte 12px/500 Montserrat #cecece  noi 13,5px/400 Open Sans
     policy in fondo fonte 14px/400 Montserrat bianco   noi 13,5px Open Sans #8b8b85
     «Prenota una Consulenza Gratuita»  fonte 14px/700  noi 13px/600

   ⚠️ Il piè e' CHROME condiviso fra le due aree di lavoro: qui si tocca solo
   il FOGLIO, non `shell()` in `build_case_studies.py`, che resta dell'area B.
   Annunciato prima di scrivere. */
.site-foot .foot-links a { font-family: var(--display); font-size: 14px; color: #fff; }
.site-foot .foot-legal {
  font-family: var(--display); font-size: 12px; font-weight: 500; color: #cecece;
}
.site-foot .foot-social h3, .site-foot .foot-right h3 { font-size: 20px; }
.site-foot .foot-bottom {
  font-family: var(--display); font-size: 12px; font-weight: 500; color: #cecece;
}
.site-foot .foot-policies a {
  font-family: var(--display); font-size: 14px; font-weight: 400; color: #fff;
}
/* ⚠️ `font-weight` va scritto DOPO l'altra regola e con piu' specificita':
   `.foot-consult` ne dichiara gia' uno (600), e senza `.site-foot` davanti la
   mia riga perdeva a parita' di peso perche' quella sta prima nel foglio. */
.site-foot .foot-consult { font-size: 14px; font-weight: 700; text-align: center; }

/* le voci del piede si stringono sul testo, non riempiono la colonna:
   sulla fonte sono larghe 160-220, da noi 368 */
.site-foot .foot-links { justify-items: start; }
/* ⚠️ L'ultima voce NON e' un pulsante giallo, e per un giro ce l'ho messo io
   (#84). Misurata nel PIEDE della fonte: «CONSULENZA GRATUITA» e' 14px/400
   bianca su fondo scuro, 220x60 — un link come gli altri, solo piu' alto.
   Il 14px/700 su nero che avevo preso per buono era un ALTRO elemento con lo
   stesso testo, in mezzo alla pagina: su `/it/servizi/strategy-data/` quella
   etichetta compare otto volte, in rese diverse. Misurare «una occorrenza» di
   un testo che si ripete non basta: bisogna misurare QUELLA nel punto giusto. */
.site-foot .foot-links a:last-child { min-height: 60px; display: flex; align-items: center; }
/* gli indirizzi sono 12px bianchi, non 14 grigi */
.site-foot .foot-offices address { font-size: 12px; color: #fff; }
/* la colonna del marchio e' larga 440 sulla fonte, non 320 */
.site-foot .foot-legal { max-width: 440px; }

/* ── Correzione alle misure qui sopra: i link legali sono GIALLI ────────────
   Il blocco precedente li dava «14px/400 Montserrat bianco», misurati su
   `/it/tool/klaviyo-strategy-quiz/`. Rimisurati sulla fonte a 1405px su
   quattro pagine (`/it/`, `/it/lavora-con-noi/`, `/en/`,
   `/it/servizio/replatforming/`): il colore e' #ffd501 su TUTTE E QUATTRO, e
   il carattere e' Open Sans su tre — Montserrat solo su `tool/`, che carica
   un kit Elementor diverso. Un solo campione, e per giunta l'eccezione, aveva
   fissato la regola per tutte e 429 le pagine.

   ⚠️ RESTA UN'ECCEZIONE NOTA: sulle 6 pagine `tool/` la fonte scrive davvero
   Montserrat, e questa regola le mette in Open Sans. Non hanno una classe che
   le distingua dalle altre nel `<body>`, e dargliela vuol dire toccare
   `shell()`, che e' dell'area B. Sei pagine col carattere diverso contro 423
   rimesse a posto — e il COLORE giallo e' giusto su tutte e 429, tool
   comprese, che e' lo scarto che si vede. Segnalato all'area B.

   ⚠️ Il pie' e' chrome condiviso: qui si tocca il FOGLIO, non `shell()` in
   `build_case_studies.py`, che resta dell'area B. */
.site-foot .foot-policies a {
  font-family: var(--body); color: var(--yellow); text-decoration: none;
}
/* ⚠️ Sottolineati da noi, non sulla fonte (`text-decoration: none`, 87x27 —
   la larghezza combacia gia' esatta). La sottolineatura torna al passaggio
   del mouse, cosi' il link resta riconoscibile come tale. */
.site-foot .foot-policies a:hover { color: #fff; text-decoration: underline; }

/* Le icone social sono gialle come i link legali, non grigie (#cfcfc9).
   ⚠️ Il riquadro resta 44x44 (`.foot-social a`, riga ~1421): sulla fonte e'
   24x24, ma e' un bersaglio tattile sotto il minimo e l'area B l'ha allargato
   apposta (HQ-11847). Qui si corregge il COLORE, non la misura — la
   deviazione e' voluta e documentata. */
.site-foot .foot-social a { color: var(--yellow); }
.site-foot .foot-social a:hover { color: #fff; }
/* ⚠️ E il glifo e' 12px, non 18: le nostre icone erano meta' piu' grandi di
   quelle della fonte. Si stringe l'ICONA, non il link, che resta 44x44 per il
   bersaglio tattile — sono due misure diverse e vanno tenute separate, ed e'
   proprio per averle confuse che l'icona era finita a 18. */
.site-foot .foot-social a svg { width: 12px; height: 12px; }

/* «Preferenze sulla privacy»: sulla fonte 18px/400 Open Sans gialla, senza
   sottolineatura, 190x27; da noi 12px/500 Montserrat grigia e sottolineata —
   la piu' piccola delle tre voci della riga, quando sulla fonte e' la piu'
   grande. Non e' un dettaglio estetico: e' il comando che riapre la banda dei
   cookie, cioe' l'unico modo che ha un visitatore di cambiare il consenso
   dato. Se non si distingue, non si trova. */
.site-foot .foot-prefs {
  font-family: var(--body); font-size: 18px; font-weight: 400;
  color: var(--yellow); text-decoration: none;
}
.site-foot .foot-prefs:hover { text-decoration: underline; }

/* la fascia gialla «Contattaci», anch'essa su ogni pagina: sulla fonte il
   titolo e' 40px e il sommario 16px in nero pieno, non 46 e 17 in #1b1b1b */
.foot-cta h2 { font-size: var(--titolo-fascia); }
.foot-cta p { font-size: 16px; color: #0d0d0d; }

/* ── «perché scegliere» sul telefono (area B, 2026-09-13) ──────────────────
   Misure della fonte a 390px. ⚠️ Diversi allineamenti si INVERTONO rispetto al
   desktop — il gancio dell'eroe e' centrato sul telefono e a sinistra sul
   desktop, «Visto su:» il contrario — quindi le regole desktop qui sopra vanno
   ridichiarate, non ereditate. */
@media (max-width: 820px) {
  body.page-perche .hero .hero-hook { font-size: 16px; text-align: center; }
  body.page-perche .hero .hero-cta {
    font-size: 15px; font-weight: 700; color: var(--yellow);
  }
  /* i titoli di fascia: 20px/800 sulla fonte, e larghi 228 non 350 */
  body.page-perche .sec-lead > .wrap > h2 { font-weight: 800; }
  /* le recensioni scritte: 16px, non 18 */
  body.page-perche .testimonianza .prose,
  body.page-perche .testimonianza p { font-size: 16px; }
  /* il nome del cliente sotto il video: 18px/500, non 15px/600 */
  body.page-perche .testimonianza b,
  body.page-perche .testimonianza .autore { font-size: 18px; font-weight: 500; }
}

/* ── la home sul telefono: il riquadro della missione (area B, 2026-09-13) ──
   A 390px la fonte rimpicciolisce quello che il desktop tiene grande, e le
   regole qui sopra non scalavano: prosa della fascia 16px contro i nostri 22,
   titolo del riquadro 20px/500 contro 25/700, citazione 18px in tondo contro
   22 in Montserrat. Misurato sulle due corsie. */
@media (max-width: 820px) {
  body.page-home .sec:has(.missione) > .wrap > .prose p { font-size: 16px; }
  body.page-home .missione .kpi b { font-size: 20px; font-weight: 500; }
  body.page-home .missione .kpi span {
    font-size: 18px; font-family: var(--body); font-weight: 700;
  }
  body.page-home .missione { padding: 28px 16px; }
}
/* ── Le domande frequenti ───────────────────────────────────────────────────
   Sulla fonte sono quattro `<details>`, il primo aperto e tre chiusi, senza
   bordi ne' fondo: il sommario e' 18px in TONDO nero (16,4px su telefono),
   alto 27, e fra una voce e l'altra ci sono ~40px. Noi rendevamo domande e
   risposte scollegate — quattro risposte come paragrafi e quattro domande
   come elenco — e tutte aperte: ~900px in piu' su telefono, il salto piu'
   grosso di tutta la pagina. */
.faq { border: 0; margin-bottom: 40px; }
.faq > summary {
  list-style: none; cursor: pointer; display: flex; align-items: start; gap: 12px;
  font-size: 18px; font-weight: 400; line-height: 1.5; color: #000;
}
.faq > summary::-webkit-details-marker { display: none; }
.faq > summary::after {
  content: ''; width: 9px; height: 9px; flex: 0 0 auto; margin-top: .45em;
  margin-left: auto;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-3px, -3px); transition: transform .18s ease;
}
.faq[open] > summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
.faq-risposta { margin-top: 14px; }
.faq-risposta p { font-size: 16px; line-height: 1.6; margin: 0; }
@media (max-width: 760px) {
  .faq { margin-bottom: 30px; }
  .faq > summary { font-size: 16.4px; }
}

/* ⚠️ Su telefono le fasce delle pagine pilastro respirano troppo. `.sec` mette
   `clamp(48px, 8vw, 88px)`, che a 390px si ferma al minimo di 48 sopra e 48
   sotto: 96px per fascia, e su quattordici fasce fanno 1.344px. Le fasce della
   fonte, misurate, ne mettono 16-24. Anche le schede: 30px di imbottitura
   contro i 16 della fonte, per dieci schede.
   ⚠️ Stretto SOLO nello scope pilastro. `.sec` veste 429 pagine e non si tocca
   su un sospetto: per farlo servirebbe misurare la spaziatura della fonte su
   tutta la famiglia, non su una pagina. */
@media (max-width: 760px) {
  body.page-pilastro .sec { padding-block: 28px; }
  body.page-pilastro .griglia-pilastro { gap: 16px; margin-top: 18px; }
  body.page-pilastro .scheda-pilastro { padding: 18px 20px; }
  body.page-pilastro .fila-copertine { gap: 24px; margin-top: 20px; }
}

/* ── indice casi studio sul telefono (area B, 2026-09-13) ──────────────────
   ⚠️ Il `gap: 200px` che allinea la colonna di testo a 600 sul desktop resta
   anche quando la griglia passa a UNA colonna sotto i 900px: duecento pixel di
   vuoto fra la copertina e il suo testo. Chi scope una griglia si prende anche
   i suoi punti di rottura — seconda volta in due giorni, stessa causa.

   Misure della fonte a 390px: titolo della scheda 22px (non 35), sottotitolo
   16px/400 (non 20/600), descrizione 16px, pulsante 14px, titolo della fascia
   «Altre metriche» 24px, settore della storia 20px. */
@media (max-width: 900px) {
  body.page-casi-indice .cs-riga { gap: 28px; }
  body.page-casi-indice .cs-testo-col h2 { font-size: 22px; }
  body.page-casi-indice .cs-sotto { font-size: 16px; font-weight: 400; }
  body.page-casi-indice .cs-testo { font-size: 16px; }
  body.page-casi-indice .cs-scarica { font-size: 14px; }
  body.page-casi-indice .storia-settore { font-size: 20px; }
  body.page-casi-indice .hero-index .hero-hook,
  body.page-casi-indice .hero-index .sec-sub { font-size: 16px; }
  /* l'eroe della fonte e' alto 332 a 390px, il nostro 627: e' il padding
     verticale, non il contenuto. */
  body.page-casi-indice .hero { padding-block: 56px; }
}

/* ── gli articoli del blog: colonna, corpo e titolo (area B, 2026-09-13) ────
   `.post-body` e `.post-head` vestono 69 pagine, tutte del blog — verificato
   su tutte e 429. Misure della fonte a 1405px:

   · colonna del testo larga 700 e CENTRATA (x=353, centro 703); da noi 533,
     perché `max-width: 68ch` a 17px fa 533. In pixel, non in `ch`: la fonte
     non scala la colonna col corpo del testo.
   · corpo 18px, non 17.
   · h1 56px/700 largo 1180; da noi 52px/800 largo 784, perché `max-width:
     22ch` lo stringeva a meno di due terzi.

   ⚠️ NON tocco la famiglia dei caratteri: la fonte rende il corpo in **Lato**,
   noi in Open Sans, ed è la stessa decisione di prodotto già dichiarata sui
   casi studio — un terzo font su 429 pagine non è un ritocco di parità. Vale
   la maggioranza delle differenze che restano su queste pagine. */
/* ⚠️ 828 e non 700: `.post-body` porta anche `.wrap`, cioe'
   `padding-inline: var(--gutter)` (64px per lato), e con `box-sizing:
   border-box` il max-width lo comprende. A 700 il testo usciva largo 572 —
   misurato — contro i 700 della fonte. E' la stessa trappola gia' scritta
   sopra per `.cs-elenco` («1348 e non 1220»): due volte lo stesso errore
   perche' la prima nota non l'ho riletta. */
body:has(> main > .post) .post-body { max-width: 828px; margin-inline: auto; }
body:has(> main > .post) .post-body,
body:has(> main > .post) .post-body p,
body:has(> main > .post) .post-body li { font-size: 18px; }
body:has(> main > .post) .post-head h1 { max-width: none; font-size: var(--titolo-eroe); font-weight: 700; }

/* ── l'indice in cima agli articoli (area B, 2026-09-13) ───────────────────
   Misure della fonte a 1405px: riquadro largo 700 con bordo
   `1px solid rgb(157,165,174)` e raggio 3px, titolo 18px/500, voci 14px/400.
   Sta prima del corpo (y=644 contro i 1233 del primo paragrafo). */
body:has(> main > .post) .indice {
  border: 1px solid rgb(157, 165, 174); border-radius: 3px;
  padding: 20px 24px; margin: 0 0 28px;
}
body:has(> main > .post) .indice summary {
  font-family: var(--display); font-size: 18px; font-weight: 500;
  cursor: pointer; list-style: none;
}
body:has(> main > .post) .indice summary::-webkit-details-marker { display: none; }
body:has(> main > .post) .indice summary::after {
  content: ' ▾'; font-size: 14px;
}
body:has(> main > .post) .indice[open] summary::after { content: ' ▴'; }
/* ⚠️ L'indice NON prende Lato: sulla fonte e' in Montserrat, come i titoli.
   La regola che porta Lato al corpo dell'articolo lo pescava dentro
   `.post-body`, e usciva un indice in Lato dove la fonte ha Montserrat. */
body:has(> main > .post) .indice,
body:has(> main > .post) .indice li,
body:has(> main > .post) .indice a { font-family: var(--display); }
body:has(> main > .post) .indice ol {
  margin: 0; padding-left: 20px; display: grid; gap: 6px;
}
body:has(> main > .post) .indice li { font-size: 14px; }
body:has(> main > .post) .indice a { color: inherit; text-decoration: none; }
body:has(> main > .post) .indice a:hover { text-decoration: underline; }

/* ── Lato dove la fonte lo usa (area B, 2026-09-13) ────────────────────────
   Solo la PROSA di articoli e casi studio: la fonte rende in Lato il corpo
   del testo, non i titoli (che restano Montserrat) ne' l'interfaccia. Contato
   nel browser: 104 elementi in Lato 400 su un articolo, 59 sull'indice dei
   casi studio, piu' 700 e corsivo.

   ⚠️ NON si tocca `--body`: quella variabile veste tutte e 429 le pagine, e la
   fonte usa Open Sans quasi ovunque. Lato vale per il corpo dei contenuti
   editoriali e basta. */
body:has(> main > .post) .post-body,
body:has(> main > .post) .post-body p,
body:has(> main > .post) .post-body li,
body.page-casi-indice .cs-testo,
body.page-casi-indice .storia-testo .prose {
  font-family: 'Lato', var(--body);
}

/* ── l'indice: aperto sul desktop, chiuso sul telefono (area B, 2026-09-13) ─
   La fonte lo tiene CHIUSO a 390px — widget alto 65px contro i 499 del
   desktop — e apribile col pulsante. Sopra gli 820px si forza aperto anche
   senza l'attributo, cosi' il comportamento combacia in entrambe le larghezze
   senza una riga di JavaScript. */
/* niente da forzare: l'indice nasce `open` (vedi build_blog.py) e resta
   chiudibile col clic in qualunque larghezza. */
/* il corpo dell'articolo sul telefono: 16.416px e colonna 330, non 18px e 350.
   ⚠️ 16.416 e NON 16.4: il collaudo confronta i valori esatti, e sedici
   millesimi di pixel bastano a far contare ogni paragrafo come diverso. Col
   16.4 il conteggio non si era mosso di una virgola — 184 prima, 183 dopo —
   pur avendo «corretto» la dimensione. */
@media (max-width: 820px) {
  body:has(> main > .post) .post-body,
  body:has(> main > .post) .post-body p,
  body:has(> main > .post) .post-body li { font-size: 16.416px; }
  /* la fonte lascia 30px per lato a 390, noi 20: contenuto 330 contro 350 */
  body:has(> main > .post) .post-body { padding-inline: 30px; max-width: none; }
}

/* ── l'indice dei servizi (area B su mandato del committente, 2026-09-13) ──
   ⚠️ Pagina di AREA A: ci metto mano perche' il committente me l'ha chiesto,
   e l'ho annunciato sulla issue #95. Tocco solo questa pagina.

   ⚠️ Lo scope e' `body:has(.categorie)` e non una classe sul `<body>`: quella
   andrebbe aggiunta in `build_services.py`, e per un ritocco di CSS non vale
   la pena toccare il loro generatore. `.categorie` esiste solo su
   `/it/servizi/` e `/en/services/` — verificato su tutte e 429.

   Misure della fonte a 1405px. */
body:has(.categorie) .hero h1 { font-size: var(--titolo-eroe); }
body:has(.categorie) .hero .hero-hook {
  font-size: 24px; font-weight: 400; font-family: var(--body);
}
body:has(.categorie) .hero .hero-cta,
body:has(.categorie) .hero .hero-invito {
  font-size: 18px; font-weight: 400; font-family: var(--body);
  text-transform: none; letter-spacing: 0;
}
body:has(.categorie) .hero .hero-invito { color: var(--yellow); }
/* il titolo di fascia e' 40px allineato a sinistra, non 32 centrato */
body:has(.categorie) .sec-lead > .wrap > h2 {
  font-size: var(--titolo-fascia); text-align: start;
  max-width: none; margin-inline: 0;
}
/* le schede: titolo 22px/500, descrizione 18px NERA col peso 300 sul testo
   normale e 700 sul grassetto — la fonte spezza ogni frase in due cosi'. */
body:has(.categorie) .categoria h3 {
  font-size: clamp(18px, 1.6vw, 22px); font-weight: 500; text-transform: none;
}
body:has(.categorie) .categoria p {
  font-size: 18px; font-weight: 300; color: #000;
}
body:has(.categorie) .categoria p strong,
body:has(.categorie) .categoria p b { font-weight: 700; color: #000; }

/* ── le copertine sulle schede del blog (area B, 2026-09-13) ───────────────
   La fonte mostra una copertina 303x303 per articolo: erano 25 delle 34
   immagini dell'indice, e da noi le schede uscivano di solo testo. */
/* ⚠️ `body.page-blog-indice` NON ESISTE: nessun generatore mette quella
   classe, il body dell'indice blog porta il solo `has-transparent-head`.
   Qui il danno non si e' visto perche' il secondo selettore regge da solo;
   sul badge qui sotto, che ce l'aveva come unico selettore, la regola era
   completamente inerte e l'etichetta usciva senza stile. Terza volta in tre
   giorni: `.hero-occhiello` per `.hero-eyebrow`, `:not(.home)` per
   `page-home`, e ora questa. Un selettore che non seleziona non da' errore. */
.cards .card-cover {
  display: block; width: 100%; aspect-ratio: 1; object-fit: cover;
  margin-bottom: 14px;
}

/* ── pagine pilastro: respiro fra le fasce e la CTA come pulsante ──────────
   (area B su mandato del committente, 2026-09-13 — pagine di area A)

   ⚠️ Le fasce con `continua` perdono il `padding-top` per attaccarsi a quella
   sopra, ed e' giusto quando due fasce hanno lo stesso fondo. Ma qui il titolo
   finiva INCOLLATO al bordo: misurato, il titolo stava a y=3868 esattamente
   come l'inizio della sezione, mentre sulla fonte sta 109-122px piu' sotto
   («Risultati convalidati» 4096→4205, «Dietro l'infrastruttura AI» 5515→5637).
   Il respiro si ridà solo alle fasce che hanno un TITOLO: quelle che
   proseguono un discorso restano attaccate. */
body.page-pilastro .sec.continua:has(> .wrap > h2) { padding-top: 104px; }
@media (max-width: 820px) {
  body.page-pilastro .sec.continua:has(> .wrap > h2) { padding-top: 52px; }
}

/* ⚠️ «Prenota una Consulenza Gratuita» e' un PULSANTE sulla fonte — 351x42 su
   fondo nero, 16px/500 in Poppins — e da noi usciva come link di testo alto
   25px. Punta gia' al modulo in fondo pagina (`#contatto`, che esiste): e' lo
   stile a mancare, non il collegamento.
   Poppins e' gia' caricato da `fonts.css` (#100), self-hosted. */
body.page-pilastro .card-more[href="#contatto"] {
  display: inline-block; padding: 11px 26px; margin-top: 18px;
  background: #000; color: #fff; border: 0;
  font-family: 'Poppins', var(--body); font-size: 16px; font-weight: 500;
  text-transform: none; letter-spacing: 0; text-decoration: none;
}
body.page-pilastro .card-more[href="#contatto"]:hover {
  background: var(--yellow); color: #000;
}

/* ── le foto dei fondatori sulle pagine pilastro (area B, 2026-09-14) ──────
   ⚠️ Stanno nella stessa `.fila-copertine` delle copertine dei casi studio,
   ma hanno una forma diversa: la fonte le rende 301x500 e 283x500, ritratti
   ritagliati da un originale quadrato 1200x1200. Con `width: 232px` delle
   copertine uscivano quadrate. Il ritaglio lo fa `object-fit: cover`, come
   sulla fonte.
   Perche' mancavano del tutto: Elementor le teneva a `visibility:hidden`
   con `elementor-invisible` finche' lo scorrimento non le raggiungeva, e la
   cattura — che scorre e torna in cima — le leggeva nascoste. */
body.page-pilastro .fila-ritratti { gap: 40px; align-items: flex-end; }
body.page-pilastro .fila-ritratti img {
  width: 301px; height: 500px; object-fit: cover; object-position: center top;
}
body.page-pilastro .fila-ritratti img:nth-child(2) { width: 283px; }
@media (max-width: 820px) {
  body.page-pilastro .fila-ritratti { gap: 20px; }
  body.page-pilastro .fila-ritratti img,
  body.page-pilastro .fila-ritratti img:nth-child(2) {
    width: min(153px, 42vw); height: 290px;
  }
}

/* ── le copertine degli strumenti (area B, 2026-09-14) ─────────────────────
   ⚠️ Riusano `.card-cover`, che nasce per le schede del BLOG: la' la fonte
   mostra quadrati 303x303 e la regola porta `aspect-ratio: 1` con
   `object-fit: cover`. Qui le miniature sono 1200x628 e la fonte le mostra
   INTERE a 381x199 — col quadrato uscivano 232x232, ritagliate ai fianchi.
   L'ambito e' la pagina che contiene la griglia degli strumenti, non una
   classe nuova sulle schede: il generatore le emette con la stessa classe. */
/* ⚠️ CORRETTA il 2026-09-21: quel «la fonte le mostra INTERE a 381x199» era
   una lettura dell'`<img>`, non di cio' che si vede. Misurato di nuovo, il
   riquadro `.elementor-post__thumbnail` e' 299x197 con `overflow: hidden` e
   l'immagine dentro sta in `position: absolute` a 376,75x197,17 centrata:
   sborda ai fianchi e viene TAGLIATA. Stessa storia della copertina del blog,
   dove 303x303 era l'immagine e 299x197 il riquadro. Due volte lo stesso
   sbaglio: si misura il contenitore, non il contenuto.
   Il rapporto giusto lo porta ora `.cards-articoli .card-cover` in fondo al
   foglio, uguale per blog e strumenti perche' sulla fonte e' un widget solo. */

/* ── i casi studio che la fonte tiene dietro il modulo (area B, 2026-09-14) ─
   Cinque su diciannove per lingua — avalon-italia, climaconvenienza, fusco,
   luxury-fashion, rifo-lab — su WordPress mostrano soltanto intestazione,
   introduzione e il modulo «Scarica subito questo caso di studio»: il corpo
   e' li' nel markup ma con `display: none`, e il resto lo si ottiene
   lasciando i dati. Noi li pubblicavamo interi, e il materiale che l'agenzia
   usa come richiamo per i contatti era leggibile da chiunque.

   ⚠️ Si NASCONDE, non si toglie: il testo resta nel markup esattamente come
   sulla fonte. Toglierlo davvero perderebbe cinque pagine di contenuto
   indicizzato che WordPress invece conserva — e' nascosto alla vista, non
   assente. Qui replicare la fonte vuol dire `display:none`, non cancellare.

   ⚠️ `aria-hidden` lo mette il generatore? NO, e apposta: sulla fonte quelle
   sezioni restano nell'albero di accessibilita' com'e' per un contenuto
   `display:none` — cioe' fuori — senza attributi in piu'. Aggiungerne
   sarebbe discostarsi. */
body.caso-protetto .sec.protetta { display: none; }

/* ── l'etichetta di categoria sulle schede del blog (area B, 2026-09-14) ───
   Misurata sulla fonte, non decisa qui: 10px/400 maiuscolo, bianco su nero,
   `padding: 6px 12px`, `border-radius: 8px`, in posizione assoluta a 15px
   dall'alto della scheda e 19 dal bordo destro (rilevati 241px da sinistra
   su una scheda da 303 con badge largo 43).
   ⚠️ `.card` va messa `relative`: senza, il badge si ancora al primo
   antenato posizionato — che qui e' il `<body>` — e finisce in cima alla
   pagina invece che sulla copertina. */
.cards .card:has(> .card-badge) { position: relative; }
.cards .card-badge {
  position: absolute; top: 15px; right: 19px; margin: 0;
  padding: 6px 12px; border-radius: 8px;
  background: #000; color: #fff;
  font-size: 10px; font-weight: 400; text-transform: uppercase;
  letter-spacing: 0; line-height: 1;
}

/* ── /it/contatti/: l'eroe e il modulo come li fa la fonte (area B, 2026-09-14)
   Pagine di area A, sul mandato del committente («rifai questa su come era su
   WordPress»). Tutti i numeri sono misurati sulla fonte, non scelti qui.

   ⚠️ L'ambito e' `.sec-modulo-nudo`, la sezione che il generatore emette solo
   dove il modulo esce senza la sua colonna di testo: cosi' le altre 34 pagine
   che usano lo stesso `lead-form` non cambiano di un pixel. */

/* l'occhiello sopra il titolo: 26px/400, non 30px/600 */
body.page-contatti .hero-fonte .hero-eyebrow {
  font-size: 26px; font-weight: 400; margin-bottom: 10px;
}

/* il modulo a tutta colonna, come la fonte che lo rende largo 899 */
.sec-modulo-nudo > .wrap { max-width: 1027px; }

/* ⚠️ Le etichette: la fonte le scrive 18px/500 NERE e larghe quanto la parola
   («Nome» = 69px), da noi erano 14px/400 grigie e stirate su tutta la riga —
   `display: grid` le fa larghe quanto il campo. Con `justify-items: start`
   l'etichetta torna della sua misura e il campo resta pieno. */
.sec-modulo-nudo .lead-form label {
  font-size: 18px; font-weight: 500; color: var(--ink); justify-items: start;
}
.sec-modulo-nudo .lead-form label > input,
.sec-modulo-nudo .lead-form label > textarea,
.sec-modulo-nudo .lead-form label > select { width: 100%; }

/* ⚠️ Il pulsante: la fonte lo tiene largo 214px, non a tutta riga, e lo scrive
   18px/900. Un pulsante largo 704 su un modulo di una pagina contatti e' la
   differenza che si nota per prima. */
.sec-modulo-nudo .lead-form button {
  width: auto; justify-self: start; padding: 14px 28px;
  font-size: 18px; font-weight: 900;
}

/* la spunta della privacy resta 18px come il resto, non 14 */
.sec-modulo-nudo .lead-form .check,
.sec-modulo-nudo .lead-form .check span { font-size: 18px; }

/* ── /it/contatti/: la scaletta dei passi come la dispone la fonte ─────────
   (area B, 2026-09-14 — pagina di area A, sul mandato del committente)

   ⚠️ Misurato sulla fonte: QUATTRO passi in fila, tutti larghi 185, a
   x=153/458/763/1068 — passo di 305px. I titoli sono 20px/700 Montserrat, e
   l'invito del primo passo («COMPILA IL MODULO») e' 10px/700 sotto il suo
   titolo. Da noi il primo passo usciva come sezione a se', con un `h2` da
   32px, e gli altri tre in una griglia staccata con titoli 16px/400 in Open
   Sans: due blocchi dove la fonte ne ha uno.

   ⚠️ L'ambito e' questa pagina (`body.page-contatti`): `.passi` la
   usano anche le pagine servizio e `/it/lavora-con-noi/`, dove la fonte le
   rende in schede riquadrate — cambiarle tutte qui sarebbe rompere quelle
   per sistemare questa. */
body.page-contatti .passi {
  grid-template-columns: repeat(4, 185px); gap: 120px; justify-content: start;
  /* ⚠️ La fonte indenta la scaletta di 50px: i passi partono da x=153 mentre
     la colonna comincia a 103. Il passo fra le colonne e' 305 in entrambi. */
  padding-left: 50px;
}
body.page-contatti .passi li {
  padding: 0; border: 0; gap: 6px;
}
body.page-contatti .passi li span {
  font-family: var(--display); font-size: 20px; font-weight: 700; line-height: 1.25;
}
body.page-contatti .passi li .passo-invito {
  font-family: var(--display); font-size: 10px; font-weight: 700;
  letter-spacing: .08em; color: var(--ink); text-decoration: none;
}
body.page-contatti .passi li .passo-invito:hover { text-decoration: underline; }

/* ⚠️ I titoli di fascia: la fonte scrive «Cosa ti aspetta?» a 35px allineato
   a SINISTRA e largo 1200; da noi uscivano 32px centrati su 652 — il centro
   viene da `.sec-lead`, che centra titolo e sottotitolo uno per uno. */
body.page-contatti .sec-lead > .wrap > h2 {
  font-size: var(--titolo-fascia); text-align: left; max-width: none; margin-inline: 0;
}
body.page-contatti .sec-lead > .wrap > .prose { margin-inline: 0; max-width: none; }

@media (max-width: 900px) {
  body.page-contatti .passi {
    grid-template-columns: repeat(auto-fit, minmax(185px, 1fr)); gap: 28px;
  }
}


/* ── «Perché scegliere Webgas»: i titoli ─────────────────────────────────────
   Censite tutte e sedici le sezioni della pagina, sulle due corsie, e
   confrontate una per una a 1405px. Sulla fonte i titoli di sezione sono
   TUTTI 40px; da noi erano 32, e uno 24. Le eccezioni sono tre, e sono vere:

     «Visto su:»            24px, a sinistra, sulla riga dei giornali
     «Recensioni video»     16px  (e' un'etichetta, non un titolo)
     «Portfolio»            72px  — il piu' grande della pagina

   ⚠️ PRIMA LETTURA SBAGLIATA, tenuta qui perche' e' istruttiva. Il confronto
   diceva «allin. start->center» su tre titoli e ne avevo dedotto che la fonte
   li mette a sinistra: falso. Sulla fonte quei blocchi sono STRETTI E
   CENTRATI, e `text-align: start` dentro una scatola centrata cade al centro
   della pagina. Confrontare `text-align` fra due scatole di larghezza diversa
   non dice niente — conta dove cade il TESTO. Misurato: «COSA DICONO DI NOI»
   e' a x=493 w=419 sulla fonte, cioe' centrato, e la mia prima correzione
   l'aveva spostato a sinistra, peggiorandolo.

   ⚠️ SECONDO ERRORE MIO, corretto qui: `h2:has(+ .loghi)` prendeva DUE
   sezioni, non una. «Visto su:» (sezione 3) e «SAPPIAMO TUTTO SULLE
   PARTNERSHIP» (sezione 14) sono tutte e due seguite da `.loghi`, quindi la
   regola dei 24px pensata per la prima schiacciava anche la seconda, che
   sulla fonte e' 40. Si distinguono per la classe `continua`, che la terza
   non ha: e' l'unica differenza nel markup, e non richiede di toccare
   `build_pagine.py` (area B). */
body.page-perche main .sec h2 { font-size: var(--titolo-fascia); }
/* ⚠️ Tranne le fasce dei numeri: «Industria automobilistica», «Industria
   alimentare»... sulla fonte sono 24px (li' sono `<h3>`, da noi `<h2>`), e la
   regola dei 40 qui sopra me li ha portati tutti e quattro a 40. Preso
   ricontrollando i titoli sul sito VIVO dopo aver pubblicato: a schermo erano
   grandi come i titoli di sezione, che e' un'altra gerarchia. */
body.page-perche main .sec-metriche h2 { font-size: var(--titolo-fascia); }
/* «Visto su:»: la sezione SENZA `continua` */
body.page-perche main .sec:not(.continua) h2:has(+ .loghi) {
  font-size: var(--corpo, var(--titolo-fascia)); font-weight: 700; color: #000; text-transform: none;
  text-align: left;
}
/* ⚠️ «Visto su:» sta sulla STESSA RIGA dei loghi, non sopra: sulla fonte il
   titolo e' a x=60 e i marchi gli scorrono accanto. Solo sopra gli 820px —
   con `nowrap` a 390px la pagina scorreva di lato, in tutte e due le lingue,
   e `traboccamento.mjs` l'ha preso al primo giro. */
/* ⚠️ Sotto gli 821px la fascia NON e' piu' una riga — la regola qui sotto
   vale solo sopra — e «Visto su:» restava a sinistra sopra dei loghi
   centrati: l'unico titolo fuori asse della pagina sul telefono. Il `left`
   serve accanto ai loghi, non sopra. Misurato: testo a x=72 contro un centro
   colonna a 195. (Giovanni, 2026-09-30: «allinea al centro».) */
@media (max-width: 820px) {
  body.page-perche main .sec:not(.continua) h2:has(+ .loghi) { text-align: center; }
}
@media (min-width: 821px) {
  body.page-perche main .sec:not(.continua) .wrap:has(> .loghi) {
    display: flex; align-items: center; gap: 28px; flex-wrap: nowrap;
  }
  body.page-perche main .sec:not(.continua) .wrap:has(> .loghi) > h2 {
    flex: 0 0 auto; margin: 0;
  }
  body.page-perche main .sec:not(.continua) .wrap:has(> .loghi) > .loghi {
    flex: 1 1 auto; min-width: 0; justify-content: flex-start;
  }
}
/* «Recensioni video»: un'etichetta, 16px */
body.page-perche main .sec h2:has(+ .playlist) {
  font-size: var(--corpo, var(--titolo-fascia)); font-weight: 700; color: #0d0d0d; text-transform: none;
}
/* «Portfolio»: 72px, il titolo piu' grande della pagina */
/* ⚠️ `clamp` e non 72px fisso: a 390px «Portfolio» a 72 faceva scorrere la
   pagina di lato di 72px esatti, in tutte e due le lingue. Sopra gli 800px
   vale comunque 72, che e' la misura della fonte. */
body.page-perche main .sec h2:has(+ .lavori) { font-size: var(--corpo, var(--titolo-fascia)); }
/* ⚠️ Qui stava «i due inviti dopo i video: 18px/700», con un selettore
   `.wrap > .hero-cta`. Tolta per DUE ragioni, e nessuna delle due si vedeva:
   la #182 ha dato 18px/700 a tutti i `hero-cta` di questa pagina, quindi era
   gia' un doppione; e ora quei pulsanti stanno dentro `.hero-azioni`, quindi
   il figlio diretto non combaciava piu' — una regola inerte che sembrava
   scritta. `controlla_classi_css.py` non l'avrebbe presa: la classe esiste,
   e' la STRUTTURA che era cambiata. */

/* ── chi siamo: la squadra come la scrive la fonte (area B, 2026-09-18) ────
   Tutti i valori misurati su WordPress, non scelti qui. Ambito
   `body.page-about`, che veste solo /it/chi-siamo/ e /en/about-us/.

   ⚠️ I nomi: la fonte li scrive 18px/700 in Montserrat, noi 17px/620 in Open
   Sans — un carattere diverso, non solo un corpo diverso. E i ruoli sono
   16px/700 NERI, mentre da noi erano 14px/400 grigio chiaro: sulla fonte il
   ruolo pesa quanto il nome, da noi spariva sotto. */
body.page-about .squadra li b {
  font-family: var(--display); font-size: 18px; font-weight: 700;
}
body.page-about .squadra li span {
  font-size: 16px; font-weight: 700; color: var(--ink);
}

/* ⚠️ Le celle: 219px sulla fonte contro i nostri 380. Non e' una scelta di
   stile — e' quante persone stanno in fila: con celle quasi doppie la
   squadra si allunga e la pagina cresce di ~900px. */
body.page-about .squadra {
  /* ⚠️ TRE colonne centrate, non quattro a sinistra: misurate sulla fonte,
     i nomi stanno a x=328/611/893 — passo 283 — mentre da noi uscivano a
     103/352/601/850. Con `auto-fill` la griglia ne infilava quattro e la
     squadra si accorciava di una riga. */
  grid-template-columns: repeat(3, 219px);
  justify-content: center;
  column-gap: 64px;
}
@media (max-width: 820px) {
  body.page-about .squadra { grid-template-columns: repeat(2, minmax(0, 219px)); }
}

/* ── chi siamo sul TELEFONO: la squadra a una colonna (area B, 2026-09-21) ──
   Il punto di rottura non e' scelto qui: restringendo la finestra sulla
   corsia blu, la fonte passa da piu' colonne a UNA fra 768 e 767 — il
   breakpoint di Elementor, lo stesso dei titoli e della prosa.

       larghezza   fonte
       390         1 colonna, ritratto 350x302
       600         1 colonna, 350x302, CENTRATA (x=125 su 600 di schermo)
       767         1 colonna, 350x302, centrata (x=209)
       768         piu' colonne, 229x302
       1024        3 colonne, 283x302

   ⚠️ L'altezza del ritratto e' FISSA a 302px a ogni larghezza: cambia solo
   la larghezza della cella. Quindi `height: 302px`, non un `aspect-ratio` —
   il rapporto sulla fonte va da 1,16 a 0,94 a seconda dello schermo.

   ⚠️ Da noi uscivano DUE colonne da 143px anche a 390. La riga che diceva
   una colonna c'era gia' (`@media (max-width: 520px)`, piu' su in questo
   foglio) ma era INERTE: la regola a 820px qui sopra ha la stessa
   specificita' e sta piu' in basso, quindi vinceva. Stesso identico caso di
   `.sec-lead h2` che batteva `.card h2` sulle schede del blog, nello stesso
   giorno. Quando due regole pareggiano, decide la posizione nel foglio.

   ⚠️ Vale anche per i FONDATORI: a 390 la fonte li mostra a tutta larghezza
   come gli altri (350x302), mentre da noi restavano miniature da 108px
   affiancate al testo. */
@media (max-width: 767px) {
  body.page-about .squadra,
  body.page-about .fondatori,
  body.page-about .fondatori article {
    grid-template-columns: min(350px, 100%); justify-content: center;
  }
  /* ⚠️ `min-height: 0` sui fondatori: `.fondatori img` porta
     `min-height: 374px`, e un `min-height` batte un `height` qualunque sia la
     specificita'. Senza azzerarlo il ritratto restava 374 invece di 302 e la
     correzione sembrava non aver preso. */
  body.page-about .squadra li img,
  body.page-about .fondatori img {
    width: 100%; height: 302px; min-height: 0; aspect-ratio: auto;
  }
}

/* ⚠️ I fondatori: «Fondatore» sulla fonte e' 800 in Open Sans, mentre il nome
   sopra e' 20px/700. Da noi il ruolo usciva 400 in Montserrat — piu' leggero
   del nome, dove la fonte lo fa piu' PESANTE. */
body.page-about .fondatori h3 { font-size: 20px; font-weight: 700; }
body.page-about .fondatori .ruolo {
  font-family: var(--body); font-weight: 800;
}
/* i titoli di studio: 12px/700 sulla fonte, non 15px/400 */
body.page-about .fondatori .prose { font-size: 12px; font-weight: 700; }

/* ⚠️ La colonna del testo: la fonte manda a capo a 835px, noi a 622 — e il
   blocco d'apertura sta su 1285 contro i nostri 851. Non e' una rifinitura:
   una colonna piu' stretta del 25% allunga ogni paragrafo di righe, ed erano
   ventisei delle quaranta differenze di resa rimaste su questa pagina.
   ⚠️ `.wrap` ha 64px di padding per lato e `box-sizing: border-box`: per una
   colonna DI TESTO da 835 il contenitore deve essere 835, non 835+128 — qui
   il max-width sta sulla prosa, che e' gia' dentro il `wrap`. */
body.page-about .prose,
body.page-about .sec-lead > .wrap > .prose { max-width: 835px; }
body.page-about .hero .hero-hook { max-width: 1285px; }

/* ── `/it/servizi/` e `/en/services/`: le schede come le fa la fonte ────────
   Chiesto dal committente: «uniformala a WordPress». Misurato a 1405px sulla
   pagina viva, non dedotto:

     paragrafo d'apertura  24px/500 rgb(13,13,13)   x=60  w=1285
     scheda                623x208  x=60   bordo 3px solid rgb(233,233,233)
                           raggio 4px   padding 24px
     titolo della scheda   <h3> 22px/500, x=87 — cioe' 27px dal bordo
                           sinistro della scheda, e SOPRA il bordo
     invito                16px/500 nero su bianco, bordo 1px nero, 150x42

   Da noi: paragrafo 17px in una colonna stretta e spostata a destra, schede
   larghe 365 col bordo da 1px e il titolo dentro, invito come link
   sottolineato.

   ⚠️ Lo scope e' `body:has(.categorie)`, come il blocco gia' esistente piu'
   su: `.categorie` sta solo su queste due pagine, e non c'e' una classe sul
   `<body>` da usare.
   ⚠️ Il titolo sul bordo si fa con `position: absolute` e un fondo bianco che
   INTERROMPE il bordo, non con `<fieldset>`: cambiare il markup vorrebbe dire
   toccare il generatore per un effetto che il foglio sa fare da solo. */
/* ⚠️ Tutto quello che allarga vale SOLO sopra gli 820px. Con due colonne
   fisse e un contenitore da 1285 la pagina scorreva di lato a 390px, su
   tutte e due le lingue — preso da `traboccamento.mjs` al primo giro. Sul
   telefono resta una colonna, che e' l'unica cosa che ci sta. */
@media (min-width: 821px) {
  body:has(.categorie) .sec .wrap { max-width: calc(1285px + 2 * var(--gutter)); }
}
/* ⚠️ Serve anche `max-width: none`: la regola di base (riga ~615) tiene
   `.categorie` a `78ch` — 758px — con `margin-inline: auto`, quindi la
   griglia restava incolonnata al centro e le schede uscivano 360 invece di
   623. Widening del `.wrap` da solo non bastava, e il primo giro l'ho
   pubblicato senza accorgermene. */
@media (min-width: 821px) {
  body:has(.categorie) .categorie {
    grid-template-columns: repeat(2, 1fr); gap: 39px;
    max-width: 1285px; margin-inline: auto;
  }
}
body:has(.categorie) .categoria {
  position: relative; border: 3px solid #e9e9e9; border-radius: 4px;
  padding: 34px 24px 24px;
}
body:has(.categorie) .categoria h3 {
  position: absolute; top: 0; left: 27px; transform: translateY(-50%);
  margin: 0; padding: 0 10px; background: #fff;
  font-size: 22px; font-weight: 500; letter-spacing: 0;
}
/* 18px, non 16: misurato sul testo delle schede della fonte */
body:has(.categorie) .categoria p { font-size: 18px; color: #000; }
/* l'invito: un pulsante bordato, non un link sottolineato */
body:has(.categorie) .categoria .card-more {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 150px; min-height: 42px; padding: 0 18px; margin-top: 18px;
  border: 1px solid #000; background: #fff; color: #000;
  font-family: var(--body); font-size: 16px; font-weight: 500;
  text-decoration: none; text-transform: none; letter-spacing: 0;
  text-align: center;
}
body:has(.categorie) .categoria .card-more:hover { background: #f2f2f0; }
/* il paragrafo d'apertura: 24px su tutta la riga, non 17 in colonna */
/* ⚠️ `:not(.sec-dark)` aggiunto da area B il 2026-09-30. `.sec-lead` veste
   ANCHE la fascia nera «Cosa hanno in comune i nostri servizi?», e li' questo
   `color: #0d0d0d` copriva `.sec-dark .prose` (riga 1113): nero su #141414,
   contrasto 1,05:1. Segnalato dal committente: «non si legge nnt». La fascia
   nera invece e' fedele — `/it/servizi/` sta in `fascia-fondo.json` e la
   cattura da' quel titolo GIALLO e maiuscolo. Sono due pagine sole,
   `/it/servizi/` e `/en/services/`, ed erano rotte tutt'e due. */
body:has(.categorie) .sec-lead:not(.sec-dark) .prose { max-width: none; }
body:has(.categorie) .sec-lead:not(.sec-dark) .prose p { font-size: 24px; font-weight: 500; color: #0d0d0d; }

/* ── /it/risorse/ e /en/resources/: le tre card dell'hub (area B, 2026-09-18)
   Misurate sulla fonte. Ambito `.cards-hub`, che il generatore mette solo su
   queste tre: `.cards` veste anche l'indice blog, gli strumenti e le risorse
   singole, e cambiarla avrebbe spostato griglie che stanno bene.

   ⚠️ I titoli: la fonte li scrive 22px allineati a SINISTRA e larghi quanto
   la parola (223px per «RISORSE GRATUITE»), da noi uscivano 32px CENTRATI su
   652 — una misura che viene da `.sec-lead`, che centra tutto quello che ci
   sta dentro. */
.cards-hub .card h2 {
  font-size: 22px; text-align: left; max-width: none; margin-inline: 0;
}
/* ⚠️ La descrizione: 18px/300 NERA sulla fonte, 14px/400 grigio chiaro da
   noi. Tre card d'invito con la descrizione in grigio piccolo si leggono
   come didascalie, non come inviti. */
.cards-hub .card .card-desc {
  font-size: 18px; font-weight: 300; color: var(--ink);
}
/* ⚠️ Il richiamo: 16px/500 in POPPINS, non 12.5px/600 in Montserrat — e
   Poppins e' gia' caricato self-hosted da `fonts.css`. */
.cards-hub .card .card-more {
  font-family: 'Poppins', var(--body); font-size: 16px; font-weight: 500;
  letter-spacing: 0; text-transform: none;
}

/* ⚠️ I titoli delle tre fasce dell'hub risorse — «RISORSE GRATUITE»,
   «STRUMENTI», «ARTICOLI E GUIDE» — NON stanno nelle card: sono `h2` di
   `sec-lead`, che li centra e li porta a 32px su una colonna da 652. La
   fonte li scrive 22px allineati a SINISTRA e larghi quanto la parola (223,
   135, 210). Ci ero cascato stilando le card, che sono altra cosa.
   L'ambito e' la pagina che contiene l'hub: `body:has(.cards-hub)`. */
body:has(.cards-hub) .sec-lead > .wrap > h2 {
  font-size: var(--titolo-fascia); text-align: left; max-width: none; margin-inline: 0;
}
/* ⚠️ E il sottotitolo: 18px/300 NERO su 569, non 21px/400 grigio centrato
   su 720. Il `.sub` di `sec-lead` centra anche lui. */
body:has(.cards-hub) .sec-lead > .wrap > .sub,
body:has(.cards-hub) .sec-lead > .wrap > .prose > p {
  font-size: 18px; font-weight: 300; color: #000;
  text-align: left; max-width: 569px; margin-inline: 0;
}

/* ── /it/servizi/ e /en/services/: la fascia scura e le recensioni ────────
   (area B, 2026-09-19 — pagina di area A, sul mandato del committente)

   ⚠️ La prosa dentro la fascia scura: la fonte la scrive 32px/400 BIANCA e
   GIUSTIFICATA, da noi usciva 24px/500 nera a sinistra. Il titolo sopra era
   gia' stato allineato (54px/800 giallo) da `titoli_fonte.py`, ma senza
   questo la fascia restava mezza vestita.
   L'ambito e' `body.page-servizi`, che quel passo mette solo sulle pagine
   censite in `fondi-fasce.json`. */
/* ⚠️ Figlio DIRETTO (`> p`), non discendente: le recensioni stanno dentro
   la stessa `.prose` — `.prose > .recensioni > .recensione > blockquote > p`
   — e con `.prose p` la regola le investiva tutte. Risultato: citazioni
   BIANCHE a 32px giustificate dove la fonte le fa nere a 18px, e
   «– Decidiprezzo s.r.l. –» stirato su 1277px. L'ho introdotto io nel giro
   precedente e si vedeva solo guardando le recensioni, non il totale delle
   differenze — che era rimasto fermo a 40 mentre dentro peggiorava. */
/* ⚠️ Solo i PRIMI DUE: sono i paragrafi veri della fascia. Il terzo `<p>`
   diretto e' «– Decidiprezzo s.r.l. –», la firma di una recensione che il
   generatore lascia fuori dalla sua scheda — e a 32px bianca giustificata
   diventava una riga larga 1277px in mezzo alla fascia. La struttura sarebbe
   da sistemare nel generatore; qui almeno non la si gonfia. */
body.page-servizi .sec-dark > .wrap > .prose > p:nth-of-type(-n+2) {
  font-size: 32px; font-weight: 400; text-align: justify; color: #fff;
}
@media (max-width: 820px) {
  body.page-servizi .sec-dark > .wrap > .prose > p:nth-of-type(-n+2) { font-size: 20px; }
}

/* ⚠️ Le schede recensione dentro la fascia scura hanno il loro fondo CHIARO:
   sulla fonte la citazione e' `rgb(13, 13, 13)` — nera — e nera su fondo
   scuro non si leggerebbe. */
body.page-servizi .sec-dark .recensione {
  background: #fff; color: var(--ink); padding: 22px 20px;
}
body.page-servizi .sec-dark .recensione .quote p,
body.page-servizi .sec-dark .recensione cite,
body.page-servizi .sec-dark .recensione cite span {
  color: var(--ink);
}
/* ⚠️ La CITAZIONE la fonte la centra, il NOME no: due elementi della stessa
   scheda con due allineamenti diversi. Applicandolo a tutta la scheda ne
   sbagliavo sempre uno — prima il nome, poi la citazione. */
body.page-servizi .sec-dark .recensione .quote p {
  font-size: 18px; font-weight: 400; text-align: center;
}

/* ⚠️ Le recensioni: la fonte scrive il nome 20px/600 in Open Sans e
   l'azienda 18px/400, tutto CENTRATO; da noi uscivano 14px/700 e 12,5px/500
   in Montserrat allineati a sinistra. Erano quattordici delle quaranta
   differenze rimaste — lo stesso scarto ripetuto per ogni testimonianza. */
/* ⚠️ I selettori sono quelli VERI del markup: `.recensione`, `.quote` e
   `cite` — non `.testimonianza`, `.autore`, `.aziendina`, che su questa
   pagina non esistono. Prima avevo scritto quelli e il controllo delle
   classi me li ha segnati morti: e' lo stesso strumento che ho aggiunto al
   build proprio per non lasciare regole che non selezionano niente. */
/* ⚠️ La fonte allinea a SINISTRA. Nel giro precedente avevo centrato
   leggendo «allin. center->start» come «la fonte centra»: il formato e'
   `fonte->nostro`, quindi diceva l'opposto — ed era su altri elementi. */
body.page-servizi .recensione,
body.page-servizi .recensione .quote { text-align: left; }
body.page-servizi .recensione cite {
  font-family: var(--body); font-size: 20px; font-weight: 600;
  color: #000; font-style: normal;
}
body.page-servizi .recensione cite span {
  font-family: var(--body); font-size: 18px; font-weight: 400; color: #000;
}

/* ── Giostre: i caroselli della fonte ────────────────────────────────────
   MISURATO sulla fonte il 2026-09-19 (`.migration/giostre.json`). Su
   `/it/perche-scegliere-webgas/` la fonte ha cinque caroselli Swiper dove noi
   avevamo cinque griglie ferme; il contenuto combaciava gia', mancava solo il
   movimento. Le schede scheda: 402x364, fondo bianco, bordo 1px #3a3a3a,
   raggio 8px, padding 24, gap interno 16.

   ⚠️ SCOSTAMENTO VOLUTO, stessa ragione delle stelle: le frecce della fonte
   sono `rgba(237,237,237,.9)` su fondo BIANCO — 1,1:1, praticamente invisibili.
   Un comando invisibile non e' un comando (WCAG 1.4.11 chiede 3:1 sui comandi).
   Qui sono #767676, 4,5:1, stessa geometria (25x25) e stessa posizione (fuori
   dalla pista, a meta' altezza). Per tornare alla fonte: `color: #ededed`.

   ⚠️ Senza JavaScript non succede niente di tutto questo e la griglia resta
   quella di prima: e' il motivo per cui le regole qui sotto si agganciano alle
   classi che mette lo script, non a `.testimonianze` da sola. */
.giostra { position: relative; }

.giostra-pista {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  scroll-padding-left: 0; scrollbar-width: none; -ms-overflow-style: none;
  overscroll-behavior-x: contain;
}
.giostra-pista::-webkit-scrollbar { display: none; }
.giostra-pista > * { scroll-snap-align: start; }
.giostra-pista:focus-visible { outline: 2px solid var(--yellow); outline-offset: 4px; }

/* ⚠️ (0,2,0) per battere `.testimonianze { display: grid }`, che sta piu'
   in alto nel foglio: affidarsi all'ordine delle regole qui e' fragile,
   perche' quel blocco non e' mio e puo' spostarsi. */
.testimonianze.giostra-pista { display: flex; gap: 40px; align-items: stretch; }
.testimonianze.giostra-pista > * { flex: 0 0 calc((100% - 80px) / 3); }
@media (max-width: 1024px) {
  .testimonianze.giostra-pista { gap: 20px; }
  .testimonianze.giostra-pista > * { flex: 0 0 100%; }
}

.giostra-freccia {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 25px; height: 25px; padding: 0; border: 0; background: none;
  color: #767676; cursor: pointer; display: none; z-index: 2;
}
.giostra-serve .giostra-freccia { display: block; }
.giostra-freccia svg { width: 25px; height: 25px; display: block; }
.giostra-freccia:hover { color: #0d0d0d; }
.giostra-freccia:focus-visible { outline: 2px solid var(--yellow); outline-offset: 3px; }
.giostra-prec { left: -34px; }
.giostra-prec svg { transform: scaleX(-1); }
.giostra-succ { right: -34px; }
/* sotto i 1180px non c'e' margine fuori dalla pista: le frecce rientrano */
@media (max-width: 1180px) {
  .giostra-prec { left: 0; }
  .giostra-succ { right: 0; }
  .giostra-freccia { background: rgba(255, 255, 255, .85); border-radius: 50%; }
}

/* scheda testimonianza: bordo e raggio della fonte (erano #e0e0e0 e 0) */
.testimonianze.giostra-pista .testimonianza {
  border-color: #3a3a3a; border-radius: 8px; background: #fff;
}

/* nastro continuo: la fila e' duplicata dallo script, si trasla di meta' */
.giostra-nastro {
  display: flex; flex-wrap: nowrap; width: max-content;
  animation: giostra-scorri var(--durata, 30s) linear infinite;
}
.giostra-nastro > * { flex: 0 0 auto; }
@keyframes giostra-scorri {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(calc(var(--corsa) * -1), 0, 0); }
}
.giostra-nastro:hover, .giostra-nastro:focus-within { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .giostra-nastro { animation: none; }
}
/* ⚠️ `.griglia-img img { width: 100% }` dentro un nastro `width: max-content`
   e' CIRCOLARE: il figlio chiede il 100% di un padre che si dimensiona sui
   figli. La prima stesura di questo blocco ha portato lo `scrollWidth` della
   pagina a 406.503px — tutto il sito scorrevole in orizzontale. Nel nastro le
   immagini devono avere una misura propria. */
.griglia-img.ritratti.giostra-nastro { grid-template-columns: none; gap: 18px; }
.griglia-img.giostra-nastro img { width: auto; height: 220px; max-width: none; }
@media (max-width: 1024px) { .griglia-img.giostra-nastro img { height: 190px; } }
@media (max-width: 600px)  { .griglia-img.giostra-nastro img { height: 160px; } }

/* La finestra del nastro e' la sezione, non la colonna: il `.wrap` la
   stringerebbe a 1200px e il nastro sembrerebbe entrare e uscire da un buco. */
.giostra-nastro { max-width: none; }
.giostra-finestra { overflow: hidden; }

/* punti della giostra — MISURATI sulla fonte: 5 pallini neri da 6px,
   margine 0 6px, fila larga 90px, 10px sotto la pista. */
.giostra-punti { display: none; justify-content: center; gap: 12px; margin-top: 10px; }
.giostra-serve .giostra-punti { display: flex; }
.giostra-punto {
  width: 6px; height: 6px; padding: 0; border: 0; border-radius: 50%;
  background: #000; opacity: .2; cursor: pointer;
}
.giostra-punto.e-qui { opacity: 1; }
.giostra-punto:focus-visible { outline: 2px solid var(--yellow); outline-offset: 3px; }

/* dentro la scheda: logo e stelle CENTRATI, come sulla fonte (il contenitore
   del logo e' `text-align: center`, la fila di stelle `justify-content: center`).
   Noi li avevamo a sinistra. */
.testimonianze.giostra-pista .testimonianza { justify-items: center; text-align: center; }

/* ⚠️ `!important` per battere lo `style="height:32px"` che scrive il
   generatore (`build_pagine.py`, area B): il logo della fonte sta in una
   casella 200x64 e il nostro ne occupava 145x32, meno della meta'.
   ⚠️ SCOSTAMENTO: la fonte usa `object-fit: cover`, che su un PNG 500x400
   mostrato in 200x64 taglierebbe via il logo. Qui `contain`: stessa casella,
   marchio intero. */
.testimonianze.giostra-pista .marchio {
  width: 200px !important; height: 64px !important; max-width: 100%;
  object-fit: contain; object-position: center; justify-self: center;
}

/* ⚠️ RITORNO ALLA FONTE, 2026-09-19. Le stelle erano #8a6600 — scelta mia,
   perche' un carattere «★» giallo su bianco fa 2,00:1. Qui tornano al
   #ffd501 della fonte, e alla sua misura (20px): il valore resta leggibile a
   chi non vede, perche' `.stelle` porta `role="img"` e
   `aria-label="Valutazione 5 su 5"` — il colore non e' l'unico modo di
   saperlo, che e' proprio la condizione che WCAG 1.4.11 mette. Vale SOLO
   dentro la giostra: altrove `.stelle` resta #8a6600. */
.testimonianze.giostra-pista .stelle {
  color: #ffd501; font-size: 20px; letter-spacing: 6px; text-indent: 6px;
}

/* Le squadrette agli angoli. MISURATE: due pseudo-elementi sulla scheda,
   100x100 di #3a3a3a, uno a `top:-10 left:-10`, l'altro a `bottom:-10
   right:-10`, dietro al fondo bianco. Quello che si vede e' una cornice a L
   spessa 10px lunga 100 su due angoli opposti.

   ⚠️ La pista ha `overflow-x: auto`, e questo rende `overflow-y` calcolato
   `auto`: senza il padding di 10px qui sotto le squadrette verrebbero
   tagliate via su tutti e quattro i lati e non si vedrebbe niente. Sulla fonte
   lo spazio lo da' la diapositiva, larga 422 attorno a una scheda di 402. */
.testimonianze.giostra-pista { padding: 10px; scroll-padding-inline: 10px; }
.testimonianze.giostra-pista .testimonianza { position: relative; }
.testimonianze.giostra-pista .testimonianza::before,
.testimonianze.giostra-pista .testimonianza::after {
  content: ""; position: absolute; width: 100px; height: 100px;
  background: #3a3a3a; z-index: -1; pointer-events: none;
}
.testimonianze.giostra-pista .testimonianza::before { top: -10px; left: -10px; }
.testimonianze.giostra-pista .testimonianza::after { bottom: -10px; right: -10px; }

/* Ritratti della squadra: la fonte li mostra VERTICALI, non quadrati.
   MISURATO: 168x350 sopra i 1025px, 217x350 fra 768 e 1024, 176x300 sotto;
   raggio 20px; `object-fit: cover` centrato; passo 18px; e uno SFALSAMENTO a
   zigzag di 40px fra un ritratto e il successivo.

   ⚠️ I file sono quadrati (1200x1200) anche sulla fonte: il taglio verticale
   lo fa il riquadro della diapositiva, non l'immagine. Riprodurlo e' fedele.

   ⚠️ RESTA DA FARE, non e' mio: sulla fonte queste tre fasce di fila —
   approccio, squadra, partnership — stanno su UN SOLO contenitore #3a3a3a col
   titolo #ffd501, e da noi escono bianche col titolo nero. Il motivo e' in
   `build_pagine.py:1488 fondo()`, che legge `background_color` dal nodo della
   sezione: qui il colore sta sul contenitore PADRE e i tre figli non ce
   l'hanno. Segnalato all'area B, che quel file lo tiene lei. */
.griglia-img.giostra-nastro { gap: 18px; align-items: flex-start; }
.griglia-img.ritratti.giostra-nastro img {
  width: 168px !important; height: 350px !important;
  object-fit: cover; object-position: 50% 50%; border-radius: 20px;
}
.griglia-img.ritratti.giostra-nastro > *:nth-child(odd) { margin-top: 40px; }
@media (max-width: 1024px) {
  .griglia-img.ritratti.giostra-nastro img { width: 217px !important; height: 350px !important; }
}
@media (max-width: 767px) {
  .griglia-img.ritratti.giostra-nastro img { width: 176px !important; height: 300px !important; }
}

/* ── Modulo a passi: campi e scelte ──────────────────────────────────────
   ⚠️ I campi del questionario a passi erano NUDI: tutto lo stile dei campi
   sta sotto `.sec-modulo`, ma questo modulo vive in `.sec-quiz` e nelle
   chiamate all'azione, dove quel selettore non arriva. Senza nessuna regola
   l'`<input>` prende il corpo di default del browser — 13,33px.

   ⚠️ E 13,33px non e' solo «piccolo»: SOTTO I 16px iOS Safari INGRANDISCE la
   pagina appena tocchi il campo, e da li' l'utente si ritrova il modulo fuori
   schermo e deve rimettere a fuoco a mano. Misurato avanzando davvero al
   passo 2 su un telefono da 390px: noi 13,33px, la fonte 16,416px. Non si
   vedeva guardando la pagina ferma, perche' i campi dei passi 2-4 sono
   nascosti finche' non rispondi alla prima domanda.

   Il selettore e' il modulo A PASSI, non `.sec-quiz`: il questionario sta in
   fondo a ~150 pagine, e su tutte aveva lo stesso difetto. Non tocca i moduli
   di `.sec-modulo`, che sono gia' a 18px e non hanno passi. */
.ff-form-has-steps .ff-el-form-control {
  font-size: 16.4px; background: #fafafa;
}

/* Le scelte con figurina (solo `/it/` e `/en/`).
   ⚠️ Su telefono stavano una per riga, larghe 202px fisse dentro una colonna
   da 344: 140px di vuoto a destra e un modulo alto 1258px invece di 752. Il
   200px fisso viene dal foglio del plugin
   (`fluent-forms-public.css`: `.fluentform .ff-el-image-holder{width:200px}`),
   che sulla fonte un foglio del tema scavalca e da noi no.

   ⚠️ SCOSTAMENTO VOLUTO: sulla fonte, su telefono, le schede si dimensionano
   sul TESTO dell'etichetta e vengono larghe diverse — 156, 146 e 95px — che
   si dispongono 1+2+1 a scalare. Qui sono due per riga tutte uguali. Stessa
   altezza della fonte (175px) e stesso `justify-content: center`; cambia solo
   che non sono sghembe. Per tornare alla fonte: togliere la `width` qui sotto
   e lasciare che sia il contenuto a decidere. */
.fluentform .ff_el_checkable_photo_holders { justify-content: center; }
@media (max-width: 600px) {
  .fluentform .ff_el_checkable_photo_holders { gap: 10px; }
  /* ⚠️ `flex` esplicito, non la sola `width`: con `width` da sola le quattro
     schede uscivano 158, 147, 97 e 82px — la misura del TESTO, non quella
     dichiarata. Qui la base della flessione e' imposta e lo restringimento
     spento, cosi' la larghezza e' quella scritta. `border-box` perche' il
     bordo da 1px del plugin fa sfondare la riga di 2px. */
  .fluentform .ff_el_checkable_photo_holders .ff-el-image-holder {
    flex: 0 0 calc(50% - 5px); width: calc(50% - 5px); box-sizing: border-box;
    margin-right: 0; margin-bottom: 0;
  }
  .fluentform .ff_el_checkable_photo_holders label.ff-el-image-input-src {
    width: 100%; height: 130px; background-size: contain;
  }
}

/* Scheda SCELTA: senza questo, toccarla non si vede.
   ⚠️ Segnalato da Giovanni: «da mobile se clicco sul passo 1 non succede
   nulla». Il tocco funzionava — la casella si spuntava davvero — ma NIENTE
   cambiava a vedersi, e una scelta che non si vede e' una scelta che non e'
   stata fatta. Misurato sulla fonte: al tocco la scheda prende la classe
   `ff_item_selected` e il bordo passa da #dcdfe5 a #fed500. Quella classe la
   mette il JavaScript del plugin, che noi non spediamo: da noi la scheda
   restava grigia.
   Qui la scelta si legge dal DOM con `:has(input:checked)`, senza dipendere da
   nessuno script — e si tiene anche `.ff_item_selected`, per il caso in cui
   qualcosa la aggiunga. `!important` perche' la regola qui sopra impone il
   bordo grigio con `!important`.
   ⚠️ Il riscontro e' tenue anche sulla fonte: un bordo da 1px. Se serve piu'
   evidente e' uno scostamento da decidere, non una svista da correggere. */
.fluentform .ff_el_checkable_photo_holders .ff-el-image-holder:has(input:checked),
.fluentform .ff_el_checkable_photo_holders .ff-el-image-holder.ff_item_selected {
  border-color: #fed500 !important;
}
/* La banda sotto la figura: sulla fonte diventa GIALLA quando la scheda e'
   scelta, e ci resta.
   ⚠️ Avevo preso quella banda per una selezione di testo del telefono e messo
   `user-select: none` per toglierla: sbagliato due volte. Non e' selezione di
   testo — e' lo `<span>` dell'etichetta — e non va tolta, va colorata. Il
   #b3d4fc che si vedeva e' il FUOCO del plugin
   (`.ff_list_buttons .ff-el-form-check label:focus-within span`), che appare
   al tocco e sparisce appena il fuoco se ne va: un lampo azzurro al posto di
   un segno che resta. Misurato sulla fonte scegliendo due schede e poi
   togliendo il fuoco: tutte e due restano #fed500, bordo e banda.
   `user-select: none` resta perche' su un comando da toccare ci sta comunque. */
.fluentform .ff_el_checkable_photo_holders .ff-el-image-holder {
  -webkit-user-select: none; user-select: none;
}
.fluentform .ff_el_checkable_photo_holders .ff-el-image-holder:has(input:checked) span,
.fluentform .ff_el_checkable_photo_holders .ff-el-image-holder.ff_item_selected span {
  background-color: #fed500 !important;
}

/* ── Titoli di fascia: il corpo della FONTE, a tutte le larghezze ────────
   Il corpo arriva in linea come variabile, scritto da `titoli_fonte.py` coi
   valori misurati da `mobile/cattura-fondi-fasce.mjs`. Qui ci sono solo le
   tre fasce di larghezza: i NUMERI non stanno mai nel foglio.

   ⚠️ Nasce da un difetto vero, segnalato da Giovanni il 2026-09-21:
   «/it/servizi/ da iPhone non si vede bene». Il corpo era scritto in linea
   come `font-size`, misurato solo a 1405px, e un `font-size` in linea non ha
   punti di rottura: sul telefono «SERVIZI DI MARKETING» restava a 40px dove
   la fonte ne fa 24, e «Cosa hanno in comune i nostri servizi?» a 54 dove ne
   fa 16. Titoli larghi quanto lo schermo, uno sopra l'altro.

   ⚠️ I punti di rottura sono DUE e sono quelli della fonte, misurati
   restringendo la finestra un pixel alla volta: 768px per «Recensioni video»
   e «Partner Ufficiali», 767px per tutti gli altri. Sembra un capriccio ed e'
   Elementor, che usa `max-width: 768px` in certi widget e 767 in altri. A
   scriverne uno solo, a 768px esatti — un iPad in verticale — due titoli
   sarebbero rimasti grandi.

   ⚠️ `!important`, e non per pigrizia. La prima stesura scriveva
   `body h2.titolo-fonte` (0,1,2) contando di battere `.sec h2` (0,1,1): la
   misurava perdeva lo stesso, perche' a pescare questi titoli c'e'
   `body:has(.categorie) .sec-lead > .wrap > h2`, che pesa (0,3,2) — `:has()`
   porta con se' il peso del suo argomento. «Cosa hanno in comune» restava a
   40px invece di 54 anche sul desktop, cioe' la correzione non correggeva
   niente e i collaudi lo hanno detto subito.
   Rincorrere quel peso con un selettore piu' lungo sarebbe una gara che si
   riperde al prossimo blocco. Qui il senso e' un altro: questo e' il valore
   MISURATO SULLA FONTE, e deve vincere sul design system per definizione, non
   per lunghezza del selettore. `!important` lo dice, e lo dice una volta. */
body h2.titolo-fonte { font-size: var(--titolo-fascia); }

/* ── Prosa sul telefono: 16px, come la fonte ─────────────────────────────
   ⚠️ Segnalato da Giovanni il 2026-09-21 su /it/servizi/ da iPhone. Corretti i
   titoli, e' saltato all'occhio il resto: sulla fonte, SOTTO I 768px, la prosa
   scende tutta a 16px, mentre da noi restava la scala del desktop — 18, 20,
   22, 24px. L'introduzione di /it/servizi/ si mangiava l'intera schermata
   dove sulla fonte ci sta anche la prima scheda.

   ⚠️ Misurato su QUATTRO pagine diverse prima di scrivere una regola larga
   (servizi, strategy-data, chi-siamo, perche-scegliere): a 767px la fonte da'
   ovunque «16px per quasi tutto, 14px per le didascalie». A 768px invece la
   scala del desktop c'e' ancora tutta — lo stesso punto di rottura dei titoli.

   ⚠️ ABBASSA, NON ALZA. Le didascalie che sulla fonte sono 14px restano 14:
   per questo l'elenco nomina i contenitori della prosa lunga invece di
   prendere tutti i `p`. Una regola su `p` avrebbe portato a 16 anche quelle
   tre, allontanandoci dalla fonte mentre credevamo di avvicinarci.

   ⚠️ `!important` per la stessa ragione dei titoli: a tenere alta la prosa
   c'e' `body.page-pilastro .sec-lead > .wrap > .prose p` a (0,3,2), e
   rincorrerlo con un selettore piu' lungo e' una gara che si riperde al
   prossimo blocco. */
@media (max-width: 767px) {
  body .prose p, body .prose li,
  body .categoria p,
  body .scheda-pilastro p, body .scheda-pilastro .sub,
  body .recensione .quote p,
  body .testimonianza .dice p, body .testimonianza .dice blockquote p,
  /* ⚠️ `.hero-eyebrow` E `.hero-occhiello`: esistono TUTTE E DUE, su pagine
     diverse. La prima stesura di questa regola nominava solo l'italiana — lo
     stesso identico scambio che l'intestazione di `controlla_classi_css.py`
     porta come primo esempio di regola morta, rifatto tre schermate piu'
     sotto. Trovato misurando: sulla home restava un occhiello a 22px e su
     /it/contatti/ uno a 26px. */
  body .hero .hero-hook, body .hero .hero-occhiello, body .hero .hero-eyebrow {
    font-size: 16px !important;
  }
  /* ⚠️ ECCEZIONI MISURATE: qui la fonte sta SOTTO i 16px, e la regola larga
     qui sopra le ALZAVA. Trovate confrontando ogni paragrafo a 768 e a 767 su
     tre pagine: su /it/chi-siamo/ tre paragrafi del racconto passavano da 14 a
     16 — il contrario di quello che serviva. La riga che li teneva a 14
     (`@media (max-width: 820px) body.page-about .storia .prose`) era giusta e
     gia' misurata: e' il mio `!important` che la scavalcava.
     Chi aggiunge un corpo sotto i 16px per il telefono lo aggiunga QUI. */
  body.page-about .storia .prose p { font-size: 14px !important; }


}
/* ── le schede-articolo: il widget «Posts» della fonte (area B, 2026-09-21) ─
   Misurate sulla corsia blu a 1405 e a 390, indice blog e /it/strumenti/:
   sulla fonte sono la STESSA scheda, perche' e' lo stesso widget Elementor.

       titolo    16px/600, interlinea 20px, TONDO, a bandiera
       estratto  14px, interlinea 21px, a QUALSIASI larghezza, intero
                 (niente troncamento: 135 caratteri stanno su 4 righe)
       copertina larga quanto la scheda, ritagliata: 299x197 a 1405,
                 370x185 a 390 — cioe' rapporto 0,66 su schermo e 0,5 sul
                 telefono, non un quadrato
       testo     rientrato 16px per lato (scheda 299, titolo 267)

   Da noi la scheda usciva 618px sul telefono contro 409, e 1087 contro 568
   a schermo intero. ⚠️ Il colpevole non era `.card h2` (riga 547, 22px
   giusti) ma `.sec-lead h2`: stessa specificita', PIU' IN BASSO nel foglio,
   quindi vinceva e imponeva `clamp(22px,2.4vw,32px)` + `uppercase` +
   `center`. Un titolo su quattro righe invece che su due, per dodici
   schede, sono i 2.500px di troppo dell'indice blog sul telefono.
   Serve percio' un ambito a due classi (`.cards-articoli .card h2`), non un
   `!important`: la regola che perdeva era giusta, era solo meno specifica.

   ⚠️ La copertina NON e' quadrata. La nota del 2026-09-14 qui sopra diceva
   «la fonte mostra quadrati 303x303»: 303x303 e' l'`<img>`, che pero' sta in
   un contenitore alto 197 che la ritaglia. Misurare l'immagine invece del
   suo riquadro e' lo stesso errore che aveva dato `aspect-ratio: 1`. */
/* ⚠️ `:has(> .card-cover)`, NON `.cards-articoli .card` e basta. La classe la
   mette anche `build_indici.py`, e su /it/risorse-gratuite/ ventisei schede
   NON hanno copertina: senza questa guardia il `padding: 0` incollava il loro
   titolo al bordo di sopra — misurato sul sito pubblicato, primo figlio a 1px
   dal bordo. Il bordo a filo vale solo dove c'e' un'immagine da mandare a
   filo. Le schede senza copertina tengono il `padding` di `.card`. */
.cards-articoli .card:has(> .card-cover) { padding: 0 0 24px; }
.cards-articoli .card:has(> .card-cover) > :not(.card-cover) { margin-inline: 16px; }
.cards-articoli .card-cover {
  width: 100%; aspect-ratio: 299 / 197; object-fit: cover;
  margin: 0 0 2px;
}
.cards-articoli .card:has(> .card-cover) h2 {
  font-size: 16px; font-weight: 600; line-height: 20px;
  text-transform: none; text-align: left;
  max-width: none; margin-inline: 16px;
}
/* ⚠️ L'estratto NON si tocca: `.card-desc` lo porta gia' a 14px/1,5, che e'
   il valore della fonte. C'era qui un `clamp(16.4px, 1.28vw, 18px)` scritto
   il 2026-09-21 e tolto lo stesso giorno: quei 18px erano il `font-size`
   calcolato del DIV `.elementor-post__excerpt`, non del `<p>` dentro, che sta
   a 14px/21px. Misurato il contenitore invece del contenuto — la STESSA
   svista della copertina, nella stessa ora. Chiedere sempre lo stile
   dell'elemento che porta il testo. */
@media (max-width: 767px) {
  .cards-articoli .card-cover { aspect-ratio: 2; }
}

/* ── i due caroselli di /it/servizi/ (area B, 2026-09-21) ──────────────────
   Segnalati dal committente: «da mobile i clienti si vedono male, i
   caroselli». Misurati sulla corsia blu a 390 e a 1405, e le impostazioni
   lette nel `data-settings` di Elementor invece che stimate a occhio.

       Recensioni video   slide 282x473 a 390 (una per volta), 275x608 a 1405
                          (tre per volta) · 5 schede, 5 pallini, 2 frecce
                          · avanza ogni 5000ms · tablet e telefono: 1
       Partner Ufficiali  slide 290x150 a 390 (uno per volta), quattro per
                          schermata sopra i 767px · 7 loghi, 7 pallini
                          · avanza ogni 5000ms · `navigation: both`

   Da noi: le recensioni erano cinque schede impilate (1.985px sul telefono
   contro 511) e i partner un nastro continuo ALTO 30px, in bianco e nero,
   coi loghi tagliati a meta' dai bordi. La fonte ne mostra uno per volta,
   grande e a colori.

   ⚠️ I loghi NON vanno in scala di grigi qui: `.loghi img` porta
   `filter: grayscale(1)` per i marchi dei clienti, ma il carosello partner
   e' a colori sulla fonte — verificato sullo scatto, il logo Google
   Analytics esce giallo/arancione. Per questo la fila ha una classe sua e
   non riusa `.loghi`.
   ⚠️ La misura si prende sul RIQUADRO della diapositiva, non sull'immagine:
   le immagini dentro hanno altezze diverse (46, 58, 75, 91, 150) e sono
   centrate in un riquadro alto 150. Stesso inganno della copertina del blog,
   piu' su in questo foglio. */
.loghi-partner {
  display: flex; flex-wrap: wrap; gap: 24px 40px;
  align-items: center; justify-content: center; margin-top: 30px;
}
.loghi-partner img { height: 150px; width: auto; max-width: 100%; object-fit: contain; }

.loghi-partner.giostra-pista { flex-wrap: nowrap; gap: 0; margin-top: 30px; }
.loghi-partner.giostra-pista > img { flex: 0 0 100%; max-width: 100%; }
@media (min-width: 768px) {
  .loghi-partner.giostra-pista > img { flex: 0 0 25%; max-width: 25%; }
}

.recensioni.giostra-pista { display: flex; gap: 24px; align-items: stretch; }
.recensioni.giostra-pista > * { flex: 0 0 100%; }
@media (min-width: 1025px) {
  .recensioni.giostra-pista > * { flex: 0 0 calc((100% - 48px) / 3); }
}

/* ── giostra su fascia scura (area B, 2026-09-21) ──────────────────────────
   I pallini sono neri al 25% d'opacita' e le frecce #767676: nati per le
   fasce chiare di /it/perche-scegliere-webgas/. Montando la giostra sulle
   recensioni di /it/servizi/, che stanno su fondo #141414, sparivano — e un
   comando che non si vede vale quanto un comando che non c'e'.
   ⚠️ Non e' uno scostamento dalla fonte: e' la stessa forma, ribaltata di
   tono, come gia' fa `.sec-dark .loghi img` piu' su in questo foglio. */
.sec-dark .giostra-punto { background: #fff; }
.sec-dark .giostra-freccia { color: #b9b9b4; }
.sec-dark .giostra-freccia:hover { color: #fff; }
@media (max-width: 1180px) {
  .sec-dark .giostra-freccia { background: rgba(0, 0, 0, .55); }
}

/* ── I settori: otto schede fotografiche ────────────────────────────────
   MISURATE sulla fonte (`.migration/settori.json`): 273x139, quattro per riga
   con 24px di distacco, foto a coprire tutta la scheda, icona bianca da 30px
   sopra il nome, nome bianco 20px/700 al centro.

   ⚠️ Classe `.settori`, non `.riquadri`. Quel componente e' generico — coppie
   valore/descrizione su decine di pagine — e vestirlo da scheda fotografica
   avrebbe trasformato anche tutto il resto. Il markup lo riscrive
   `settori_fonte.py`, e solo dove i nomi combaciano col censimento. */
.settori {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px; margin-top: 26px;
}
.settore {
  position: relative; isolation: isolate; min-height: 139px; padding: 40px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 5px; text-align: center; overflow: hidden; background: #fff;
}
/* ⚠️ Il velo della fonte, MISURATO: `brightness(.51) blur(2px)`. Senza, la
   scheda e' troppo chiara e il nome bianco ci sparisce sopra: misurato sui
   PIXEL DIPINTI, la fonte fa 5,76:1 col bianco e la nostra prima versione
   2,08:1 — cioe' illeggibile. Il filtro sta sull'overlay e non sulla scheda,
   altrimenti sfocherebbe anche l'icona e il nome.
   ⚠️ `inset: -6px` perche' `blur()` sfuma anche i BORDI: con l'overlay a filo
   si vedrebbe una cornice chiara tutt'intorno. */
.settore::before {
  content: ""; position: absolute; inset: -6px; z-index: -1;
  background-image: var(--foto);
  background-size: cover; background-position: 50% 50%; background-repeat: no-repeat;
  filter: brightness(.51) blur(2px);
}
.settore-icona { width: 30px; height: 30px; fill: #fff; flex: none; }
.settore b {
  font-family: var(--display); font-weight: 700; font-size: 20px;
  line-height: 1.2; color: #fff;
}
/* ⚠️ La fonte tiene QUATTRO per riga fino a 768px e poi passa di colpo a
   UNA: non c'e' il passaggio intermedio a due che sembrerebbe naturale.
   Misurato a 1405, 1024, 768, 600 e 390px. E l'altezza della scheda cambia
   con la larghezza — 139, poi 87, poi 97 — quindi non e' una sola misura che
   si adatta, sono tre misure diverse. */
/* ⚠️ Il rientro va stretto INSIEME all'altezza: con `padding: 20px` il
   contenuto (icona 30 + distacco + nome) misurava 104px da solo e la
   `min-height: 87px` non serviva a niente — una misura scritta che il
   contenuto scavalcava. */
@media (max-width: 1024px) {
  .settore { min-height: 87px; padding: 12px 16px; gap: 8px; }
  .settore b { font-size: 18px; }
}
@media (max-width: 767px) {
  .settori { grid-template-columns: 1fr; gap: 16px; }
  .settore { min-height: 97px; }
}

/* ── Pagine pilastro: i titoli di fascia sullo schermo stretto ───────────
   ⚠️ `--titolo` e' misurato a 1405px e applicato a tutte le larghezze: su
   /it/servizi/performance-marketing/ teneva un h2 a 109px su uno schermo da
   390. MISURATO sulla fonte a 1405, 1024, 768, 767 e 390: i titoli di fascia
   scendono a 32px sotto i 1025 e a 20-24px sotto i 768.

   ⚠️ `min()`, non un numero secco: cosi' la regola ABBASSA e non alza mai —
   un titolo gia' piccolo resta com'e'. Il tetto e' il MASSIMO che fa la
   fonte a quella larghezza, non una misura inventata.

   ⚠️ RESTA DA FARE: la fonte varia fra 20 e 24 a seconda della fascia, e
   `cattura-pilastri.mjs` legge una larghezza sola. Per avere il valore esatto
   per fascia va esteso come `cattura-eroe.mjs` e `cattura-fondi-fasce.mjs`,
   che ora misurano a tre larghezze. Qui il tetto e' 24: mai piu' della fonte,
   qualche volta 4px in piu'. */
@media (max-width: 767px) {
  body.page-pilastro .sec-fascia > .wrap > .sub,
  body.page-pilastro .sec-lead > .wrap > .sub { font-size: 16px; }
}

/* ── La filigrana: grande sul desktop, ASSENTE sul telefono ─────────────
   ⚠️ MISURATO sulla fonte a cinque larghezze: la filigrana e' 400px a 1405,
   1024 e 768 — sempre 400, non una misura che si adatta — e sotto i 768
   SPARISCE (riquadro 0x0). E' decorativa: su un telefono sarebbe una parola
   grigia alta un terzo dello schermo.
   Da noi era `clamp(96px, 28vw, 400px)`: 109px su un telefono da 390, e
   appena 287 su un tablet da 1024 dove la fonte ne fa 400. Sbagliata da
   tutte e due le parti. */
@media (min-width: 768px) {
  body.page-pilastro .sec-filigrana > .wrap > h2 { font-size: clamp(96px, 52vw, 400px); }
}
@media (max-width: 767px) {
  body.page-pilastro .sec-filigrana > .wrap > h2 { display: none; }
}

/* ⚠️ Una pista che scorre CONTAGIA l'antenato. Su /it/servizi/ e
   /en/services/ la pagina scorreva in orizzontale a OGNI larghezza — 1906px
   su una finestra da 1405 — e a cercarne il colpevole si trovava solo la
   freccia, che sporge di 34px voluti. Il resto lo mette la pista: ha
   `overflow-x: auto` e taglia per conto suo, ma la sua area scorrevole
   rientra comunque nello `scrollWidth` del `.wrap`.
   Si contiene sul `.wrap`, non sul guscio: il guscio e' largo 1277 dentro un
   `.wrap` da 1405, quindi le frecce a -34px restano dentro e si vedono.
   `clip` e non `hidden`: `hidden` su un asse rende l'altro scorrevole, e la
   pagina si sarebbe ritrovata una barra verticale in mezzo al contenuto.
   ⚠️ Non l'aveva vista la rassegna a 390px: con l'emulazione iPhone il
   browser applica il `<meta viewport>` e `scrollWidth` risponde un'altra
   cosa. Lo stesso difetto, misurato a 360, 768 e 1405, c'era a tutte e tre. */
.wrap:has(> .giostra) { overflow-x: clip; }

/* ── Casi studio: una giostra, una diapositiva per volta ────────────────
   MISURATO sulla fonte il 2026-09-19: quattro diapositive e UNA per
   schermata a ogni larghezza (573x184 a 1405px, 882x157 a 1000, 316x460 a
   390), frecce si, pallini no. Da noi erano quattro fasce impilate, piu' di
   mille pixel dove la fonte ne usa ottocento.
   Il markup lo fonde `casi_giostra.py`; qui c'e' solo la resa. */
.casi.giostra-pista { display: flex; gap: 0; }
.casi.giostra-pista > .caso { flex: 0 0 100%; }
/* ⚠️ E la LARGHEZZA della finestra, che mancava. Il blocco qui sopra citava
   gia' i numeri della cattura ma metteva in opera solo «una diapositiva per
   volta»: la finestra restava larga quanto la colonna, 1200px a schermo
   intero contro i 573 della fonte, e i quattro numeri si spargevano in una
   striscia invece di stare in una scheda. Segnalato da Giovanni il
   2026-09-30: «Industria automobilistica e tutti gli altri casi non credo
   erano cosi' su WordPress».
   Misurato, noi contro la fonte (`giostre.json`, presa dal vivo il
   2026-09-19):
       1405px   noi 1200x133   fonte 573x184
       1000px   noi  900x133   fonte 882x157
        390px   noi  350x468   fonte 316x460
   ⚠️ I tre valori sono esatti perche' misurati a quelle tre larghezze. I
   PUNTI DI ROTTURA fra l'uno e l'altro NON lo sono: la cattura ha tre
   larghezze e basta, e fra 1000 e 1405 la fonte si restringe invece di
   allargarsi — e' un contenitore in percentuale dentro una riga, non una
   media query che possiamo leggere. 1025px e' il punto di rottura
   predefinito di Elementor per il desktop, quindi e' la stima meno
   arbitraria; se un giorno salta fuori una cattura a 1200, si corregge qui.
   ⚠️ L'ALTEZZA non si impone: viene da se' quando la scheda si stringe e i
   quattro numeri vanno a capo. Imporla avrebbe voluto dire tagliare o
   allungare il contenuto per far tornare un numero. */
body.page-perche .casi.giostra-pista { max-width: 882px; margin-inline: auto; }
@media (min-width: 1025px) {
  body.page-perche .casi.giostra-pista { max-width: 573px; }
}
@media (max-width: 768px) {
  body.page-perche .casi.giostra-pista { max-width: 316px; }
}
/* ⚠️ E i quattro numeri restano IN FILA anche quando la scheda si stringe.
   `repeat(auto-fit, minmax(165px, 1fr))` dentro una finestra da 573 da' due
   colonne su due righe, e la scheda cresce a 257px contro i 184 della fonte.
   A 882px le colonne sono gia' quattro e infatti li' l'altezza combaciava
   quasi: e' solo a schermo intero, dove la finestra e' piu' STRETTA, che
   l'auto-fit cambiava idea.
   ⚠️ Sotto i 768 non si tocca: li' la fonte misura 316x460 e noi 316x468,
   otto pixel di scarto con la disposizione che abbiamo. Rifarla per far
   tornare un numero che gia' torna sarebbe cercarsi un difetto. */
@media (min-width: 769px) {
  body.page-perche .casi .caso .kpis {
    /* ⚠️ `flex-wrap`, NON `grid-template-columns`. La prima stesura metteva
       `repeat(4, minmax(0,1fr))` e non faceva assolutamente niente: dentro
       `.sec-metriche` quel `.kpis` e' un FLEX, non una griglia. Nessun
       errore, la regola sembrava scritta, e il numero non si muoveva di un
       pixel. `controlla_classi_css.py` non l'avrebbe presa: la classe esiste,
       e' la proprieta' a essere sull'elemento sbagliato. */
    flex-wrap: nowrap;
    gap: clamp(10px, 1.6vw, 28px);
  }
}
.caso h2 { margin-top: 0; }
.casi-fascia .giostra-freccia { color: #c9c9c4; }
.casi-fascia .giostra-freccia:hover { color: #fff; }

/* ── /en/contact/: la scheda del modulo non deve coprire il titolo ───────
   ⚠️ Segnalato da Giovanni il 2026-09-29: «il form va sopra la scritta».
   Vero: la scheda bianca risale sull'eroe di `clamp(-120px, -9vw, -48px)` e
   a 1405px si mangiava 40px dell'h1, a 1024px dodici. Sul telefono no, per
   questo a occhio poteva sembrare a posto.

   MISURATO sulla fonte (istantanea locale, JavaScript spento perche' gli
   script di WordPress la fanno navigare via): la scheda parte 40px DOPO la
   fine dell'h1 sopra i 1024px e 30px sotto. Ci arriva con un tiro di -150px
   e 190px di giallo sotto il titolo; -80px e 110px alle larghezze minori.

   ⚠️ Il numero che conta non e' il tiro, e' lo SPAZIO SOTTO IL TITOLO: la
   fonte ne lascia 190, noi 80, ed e' li' che nasce la sovrapposizione.
   Copiare il solo tiro (-150 invece di -120) avrebbe peggiorato le cose.

   ⚠️ `.sec-modulo` la mette `forms.js` A RUNTIME: nell'HTML statico non
   c'e', e cercarla col grep nei file da' zero pagine. `:has()` la vede lo
   stesso, perche' si rivaluta quando il DOM cambia. */
body.page-contatti .hero:has(+ .sec-modulo) { padding-bottom: 190px; }
body.page-contatti .hero:has(+ .sec-modulo) + .sec-modulo > .wrap { margin-top: -150px; }
@media (max-width: 1024px) {
  body.page-contatti .hero:has(+ .sec-modulo) { padding-bottom: 110px; }
  body.page-contatti .hero:has(+ .sec-modulo) + .sec-modulo > .wrap { margin-top: -80px; }
}

/* Variante NERA dell'evidenziatore. `.mark` e' giallo, e qualche pagina lo
   ridipinge di nero per tutto il documento; sulle pagine contatti servono
   tutti e due sulla STESSA pagina, quindi il tono e' una classe esplicita.
   MISURATO sulla fonte: «Come funziona il processo?» e' 22px/700 bianco su
   nero, e da noi era 17px/400 grigio — non un carattere piu' piccolo, un
   componente diverso. */
.mark-nero { background: #0d0d0d; color: #fff; }

/* ── /it/contatti/ e /en/contact/: quattro scarti misurati sulla fonte ───
   Letti dall'istantanea locale il 2026-09-29 (WordPress risponde 522).
   ⚠️ Le tolleranze contano: `#000` contro `#0d0d0d` e `left` contro `start`
   NON sono scarti, e inseguirli avrebbe solo sporcato il foglio. Qui ci sono
   solo le differenze che si vedono. */
body.page-contatti .hero-fonte .hero-eyebrow { text-align: left; }
/* il collegamento nel consenso: sulla fonte e' GIALLO e di peso normale,
   da noi nero e semigrassetto */
body.page-contatti .lead-form label.check > span { font-weight: 400; }
/* ⚠️ SCOSTAMENTO VOLUTO, e correzione di un mio errore del 2026-09-29.
   Sulla fonte questo collegamento e' #fed500, e io l'avevo copiato tale e
   quale: su fondo bianco fa 1,43:1, cioe' un link al consenso privacy che non
   si legge. Misurato dopo averlo spedito, non prima — la fedelta' al colore
   non vale la leggibilita' di un collegamento legale, e qui il testo E' la
   sola informazione: non c'e' nessun `aria-label` che la porti, come invece
   succede per le stelle.
   #8a6600 e' il giallo del marchio reso leggibile (5,3:1), lo stesso che il
   foglio usa gia' per le stelle per la stessa ragione. Uguale nelle due
   lingue: lo stesso elemento non puo' essere rosso in inglese e giallo in
   italiano. Per tornare alla fonte: `#fed500`. */
body.page-contatti .lead-form label.check > span > a,
body.page-contatti .ff_t_c p a { color: #8a6600; font-weight: 400; }

/* ── /en/contact/: gli scarti che ho potuto verificare ──────────────────
   ⚠️ NON tocco l'eroe. L'istantanea senza JavaScript lo dava BIANCO, ma
   `eroe.json` — catturato dalla fonte VIVA quando ancora rispondeva — dice
   `rgb(255, 213, 1)`, cioe' giallo come il nostro. Quando due letture si
   contraddicono vince quella presa sul vivo, e la lettura senza JS va
   guardata con sospetto proprio sui fondi.
   ⚠️ IL CORPO NON PIU'. Questa riga, arrivata con la #182, rimetteva il
   corpo MISURATO sulla fonte (`--eroe-dim`, 50px su /en/contact/) al posto
   dei 56px fissi di `.hero h1:has(.mark)`. Era giusta finche' la parita' era
   il criterio; e' stata superata poche ore dopo dalla scala unica chiesta da
   Giovanni, che ha tolto `--eroe-dim` da tutte le pagine. Lasciata com'era,
   questa regola non avrebbe dato errore: `var()` sarebbe caduto sul ripiego
   e l'eroe di /en/contact/ sarebbe rimasto a 56px — l'unico del sito fuori
   scala, e nessuno l'avrebbe visto. Ora segue la scala come gli altri.
   ⚠️ Il resto della #182 su questa pagina resta intatto: il colore del
   collegamento al consenso, il peso delle etichette e la frase evidenziata
   non c'entrano col corpo del titolo. */
body.page-contatti .hero h1:has(.mark) { font-size: var(--titolo-eroe); }
/* le etichette del modulo: peso 500 sulla fonte, 600 da noi */
body.page-contatti .sec-modulo .ff-el-input--label label { font-weight: 500; }
/* la frase evidenziata: 22px come la gemella italiana, non 35 */
body.page-contatti h2 > span.mark { font-size: 22px; }
/* l'invito dentro i passi: centrato sulla fonte */
body.page-contatti ol.passi > li > a.passo-invito { text-align: center; }

/* ── Gli inviti di perche-scegliere, come li fa la fonte ────────────────
   MISURATO il 2026-09-29 sull'istantanea: 18px/700, `padding: 12px 24px`,
   `border-radius: 2px`. Da noi erano 14px/600 con `padding: 17px 30px` e
   angoli vivi — alti 57-64px dove la fonte ne fa 42-46.

   ⚠️ L'ALLINEAMENTO NON E' UN DIFETTO, e per poco non lo «correggevo». Il
   confronto diceva «centro» sulla fonte e «sinistra» da noi: ma sulla fonte
   il contenitore del pulsante e' largo QUANTO IL PULSANTE (261px su 261),
   mentre il nostro `.wrap` e' largo 1328. Misuravo due cose diverse. E'
   esattamente l'errore che mi era gia' costato un titolo spostato a sinistra
   su questa stessa pagina.

   ⚠️ RESTA DA FARE: sulla fonte il FONDO di questi pulsanti CAMBIA —
   «Vedi tutte le recensioni» e' #3a3a3a, «Vai all'area stampa» bianco con un
   bordo da 2px, «Scopri il Servizio» giallo — e da noi sono tutti gialli. Per
   riprodurlo serve un censimento per pulsante, come `giostre.json`: non si
   ricava da una classe. */
body.page-perche .hero-cta {
  font-size: 18px; font-weight: 700; padding: 12px 24px; border-radius: 2px;
  /* ⚠️ Il fondo arriva IN LINEA, uno per pulsante: la fonte dipinge lo stesso
     componente in tre modi (#3a3a3a col testo bianco, bianco con un bordo da
     2px, giallo col testo scuro) e da una classe non si ricava. Lo scrive
     `inviti_fonte.py` coi valori di `inviti.json`; qui c'e' solo il ripiego
     per i pulsanti che il censimento non copre. */
  background: var(--inv-fondo, var(--yellow));
  color: var(--inv-testo, #0d0d0d);
  border: var(--inv-bordo, 0);
  /* ⚠️ E il resto della scatola, misurato: interlinea 1 (18px su 18),
     MINUSCOLO e nessuna spaziatura fra le lettere. Da noi erano 29,7px di
     interlinea, maiuscolo e 1,8px di spaziatura: da soli facevano 353x54
     dove la fonte fa 261x46 — la meta' della differenza non era il rientro,
     era il testo. */
  line-height: 1; text-transform: none; letter-spacing: normal;
  text-align: center;
}
/* ⚠️ Il pulsante dell'EROE fa eccezione: sulla fonte e' 15px, non 18. La
   regola qui sopra li aveva portati tutti a 18 e questo l'aveva peggiorato —
   una misura giusta per otto pulsanti su nove non e' una misura giusta. */
body.page-perche .hero .hero-cta { font-size: 15px; }

/* ── La tabella di confronto delle pagine servizio ──────────────────────
   Sulla fonte e' una tabella a tre colonne — etichetta di riga, «Altre
   agenzie», «Webgas.net» — e da noi era una colonna di paragrafi in fila alta
   1800px, senza intestazioni, dove non si capiva quale cella fosse «loro» e
   quale «noi». Il markup lo ricostruisce `confronto_fonte.py` dal dump.

   ⚠️ `<table>` e non una griglia di `<div>`: sono dati tabulari veri, e con
   `<th scope>` chi naviga a voce sente «Produzione creativa, Webgas.net,
   immagini ottimizzate…» invece di tre frasi sciolte. Su schermo stretto la
   tabella SCORRE dentro la sua cornice invece di spezzarsi: una riga di
   confronto che va a capo perde il confronto, che e' tutto il suo senso. */
.confronto-giro { overflow-x: auto; margin-top: 26px; }
.confronto { border-collapse: collapse; width: 100%; min-width: 640px; font-size: 16px; }
.confronto th, .confronto td {
  border: 1px solid var(--rule); padding: 14px 16px; vertical-align: top;
  text-align: left; line-height: 1.5;
}
.confronto thead th { font-size: 18px; font-weight: 700; background: #f5f5f5; }
.confronto thead th.noi { background: var(--yellow); color: #0d0d0d; }
.confronto thead td { border: 0; }
.confronto tbody th { font-weight: 700; width: 22%; background: #fafafa; }
.confronto td.noi { background: rgba(255, 213, 1, .10); }
.sec-dark .confronto th, .sec-dark .confronto td { border-color: #3f3f3f; }
.sec-dark .confronto thead th { background: #2a2a2a; color: #fff; }
.sec-dark .confronto tbody th { background: #222; color: #fff; }

/* ── perche-scegliere: la frase di apertura e i titoli dei casi ─────────
   ⚠️ Segnalato da Giovanni il 2026-09-30: «non dovrebbe essere in bold o
   comunque più visibile?». Sì. MISURATO sull'istantanea: sulla fonte
   «Sblocchiamo il potenziale di crescita…» e' 21,6px di PESO 700, #0d0d0d,
   CENTRATA e larga 1028px; da noi usciva 17px/400, #24220c, a sinistra e
   larga 758. E' la promessa che apre la pagina, e la rendevamo come una nota.

   ⚠️ Il mio confronto con l'istantanea NON l'aveva segnalata, e quindi il
   rapporto «29 scarti» non era completo: l'elemento non entrava nel censimento
   dei due lati. Un confronto che non vede una differenza non dice che non
   c'e' — dice che non l'ha guardata. Trovata solo misurando l'elemento a mano
   dopo la segnalazione.

   ⚠️ E i titoli delle diapositive dei casi studio: 24px sulla fonte (e li' e'
   un `h3`), 36 da noi — il corpo e' cresciuto quando ho fuso le quattro fasce
   in una giostra, perche' il titolo ha cambiato contesto e ha smesso di
   pescare la regola che lo teneva a 24. Una modifica che ne rompe un'altra a
   distanza: e' il motivo per cui il collaudo va rifatto sulla pagina intera e
   non solo sul pezzo toccato. */
body.page-perche .sec-giallo > .wrap > .prose { max-width: 1028px; margin-inline: auto; }
body.page-perche .sec-giallo > .wrap > .prose p {
  font-size: 21.6px; font-weight: 700; color: #0d0d0d; text-align: center;
  /* ⚠️ Il tetto va sul CONTENITORE, non sul paragrafo: `.prose` e' largo 758
     e un `max-width` sul figlio non puo' farlo crescere. Sulla fonte la
     frase occupa 1028px, e a 758 va a capo in un punto diverso. */
  max-width: none;
}
body.page-perche .casi .caso h2 { font-size: 24px; }

/* ── /it/servizi/ e /en/services/: i titoli di sezione tutti in capitali ───
   Chiesto dal committente il 2026-09-30, dopo aver notato che «Recensioni
   video» non sembrava un titolo come gli altri. Misurato prima di rispondere:
   il CORPO era gia' identico a tutti gli altri — 36px/700 a 1440, 24 sotto i
   768 — e a farlo sembrare minore era la sola CAPITALIZZAZIONE. Sulla pagina
   ne convivevano due: due titoli scritti in capitali nel testo, due resi
   maiuscoli dal `text-transform`, quattro in tondo. Quattro sembravano titoli
   di sezione e quattro no.

   ⚠️ Serve `!important` perche' `titoli_fonte.py` scrive `text-transform` IN
   LINEA su ogni titolo, preso dal censimento della fonte: e uno stile in linea
   batte qualunque regola del foglio. Qui pero' non stiamo correggendo una
   misura sbagliata — la fonte li aveva davvero misti — stiamo SCEGLIENDO
   un'altra cosa. Con WordPress spento non c'e' piu' una fonte da rispettare su
   questo punto, e una decisione dichiarata vale piu' di una fedelta' a un sito
   che non esiste.

   ⚠️ FUORI `.passo-grande`, il titolo della fascia di chiusura: quella banda
   sta su QUARANTADUE pagine, e renderla maiuscola su due sole avrebbe creato
   la stessa incoerenza dall'altro lato. La richiesta riguarda i titoli delle
   sezioni di questa pagina, non il congedo condiviso da tutto il sito. */
body.page-servizi main .sec > .wrap > h2:not(.passo-grande) {
  text-transform: uppercase !important;
}

/* ⚠️ La scala dei titoli della FONTE, dove il committente l'ha chiesta.
   Il sito usa un token unico (`--titolo-fascia`, 36px) scelto dall'area B il
   2026-09-30. Su `/it/perche-scegliere-webgas/` la fonte non ha una scala
   sola — 16, 24, 40, 72 — e Giovanni ha chiesto quella pagina «com'era su
   WordPress». Qui il corpo misurato torna a vincere, e SOLO su quella pagina:
   la decisione globale resta in piedi ovunque. Il ripiego e' il token, cosi'
   un titolo non censito non resta senza misura. */
/* ⚠️ `main .sec` nel mezzo: a batterci c'era
   `body.page-perche main .sec h2` — (0,2,3) contro i miei (0,2,2), un
   elemento di differenza — e le variabili erano scritte in pagina ma non le
   leggeva nessuno. Il corpo restava 36px e sembrava che il passo non avesse
   funzionato. */
body.page-perche main .sec h2.titolo-fonte { font-size: var(--corpo, var(--titolo-fascia)); }
@media (max-width: 768px) {
  body.page-perche main .sec h2.titolo-fonte {
    font-size: var(--corpo-768, var(--corpo, var(--titolo-fascia)));
  }
}
@media (max-width: 767px) {
  body.page-perche main .sec h2.titolo-fonte {
    font-size: var(--corpo-tel, var(--corpo-768, var(--corpo, var(--titolo-fascia))));
  }
}

/* ── perche-scegliere: gli ultimi scarti misurati sull'istantanea ───────
   Giovanni, 2026-09-30: «riportala come era su WordPress». Questi sono i
   resti, uno per uno, col valore della fonte accanto. */
/* le voci della playlist video: 18px/500 NERO, non 15/600 grigio scuro */
body.page-perche .scelte button span { font-size: 18px; font-weight: 500; color: #000; }
/* l'h1 dell'eroe: 60px sulla fonte, 72 da noi */
body.page-perche .hero.hero-fonte h1 { font-size: 60px; }
/* il gancio sotto l'h1 e' allineato a SINISTRA, non centrato */
body.page-perche .hero .prose.hero-hook p { text-align: left; }
/* «Non siamo solo un'agenzia di marketing.»: 24px/700, non 17/400 */
body.page-perche main .sec-lead > .wrap > .prose p strong,
body.page-perche main .sec-lead > .wrap > .prose p b { font-size: 24px; font-weight: 700; }
/* ⚠️ NON tutte le fasce scure di questa pagina sono #3a3a3a. Quella che
   presenta Uptonica e' #0d0d0d col testo bianco e il collegamento giallo: la
   mia regola larga `body.page-perche .sec-dark` le dava a tutte lo stesso
   grigio. Una tinta per famiglia non e' una tinta misurata. */
body.page-perche .sec-dark:has(a[href*="uptonica"]) { background: #0d0d0d; }
body.page-perche .sec-dark:has(a[href*="uptonica"]) .prose p { color: #fff; text-align: center; }
body.page-perche .sec-dark:has(a[href*="uptonica"]) .prose a { color: var(--yellow); }

/* ── Il riquadro dell'eroe non copre la riga sotto (2026-09-30) ───────────
   ⚠️ `.hero h1` sta a `line-height: 1`, e uno `<span>` in linea con fondo e
   `padding` disegna una scatola piu' alta della sua riga: finche' il titolo
   sta su una riga non si vede niente, appena va a capo la scatola copre il
   testo di sotto. Su `/it/lavora-con-noi/` «e fai la differenza!» usciva
   scritta sopra un rettangolo nero.
   Misurato con `mobile/_diag-risalto.mjs`: VENTI pagine su ventisette.
   ⚠️ Il difetto c'era gia', la scala unica dei titoli l'ha portato a galla: a
   50px — la misura della fonte per quella pagina — sbordava di poco, a 72
   taglia le lettere.
   ⚠️ 1,3 e non un numero nuovo: e' lo stesso che il foglio da' gia' a
   `.hero h1:has(.mark)`, che e' lo stesso problema con l'altra classe.
   ⚠️ IN FONDO AL FOGLIO, e con `body main` davanti, non accanto alla regola
   del riquadro: le pagine servizio hanno un loro
   `body.page-service main .hero h1 { line-height: .96 }` piu' in basso, che a
   parita' di peso vinceva. Con la regola scritta dove stava, quattro pagine su
   ventisette restavano rotte — e sembravano un caso a parte invece di un
   problema di ordine. */
/* ⚠️ E le DUE VARIANTI per i titoli lunghi vanno elencate a mano. Le pagine
   servizio danno `line-height: 1,05` a `h1.h1-mid` e `1,15` a `h1.h1-long`:
   una classe in piu' nel selettore, quindi pesano di piu' e vincevano anche
   da qui in fondo. Restavano rotte esattamente quelle quattro, e sembravano
   un caso a parte invece dello stesso problema con un peso diverso. */
body main .hero h1:has(.risalto),
body main .hero h1.h1-mid:has(.risalto),
body main .hero h1.h1-long:has(.risalto) { line-height: 1.3; }

/* ── «Portfolio»: una targhetta VERTICALE, non un titolone ──────────────
   ⚠️ Giovanni: «Portfolio ha il titolo enorme». Il corpo era gia' giusto —
   72px su entrambe le corsie — ma l'ORIENTAMENTO no: sulla fonte quel titolo
   e' `writing-mode: vertical-lr` ruotato di 180°, una targhetta alta 448px e
   larga 72 appoggiata al bordo SINISTRO della fascia. Da noi era un titolo
   orizzontale largo 1200: stesso corpo, effetto opposto. Misurare la
   dimensione e fermarsi li' non basta — 72x448 e 1200x86 sono lo stesso
   «72px» e due disegni diversi.

   ⚠️ `rotate(180deg)` insieme a `vertical-lr` fa leggere dal basso verso
   l'alto, che e' come sta sulla fonte. Da solo, `vertical-lr` lo farebbe
   leggere dall'alto in basso. */
body.page-perche main .sec h2:has(+ .lavori) {
  writing-mode: vertical-lr; transform: rotate(180deg);
  width: max-content; height: 448px; margin: 0; padding: 0;
  line-height: 1; text-align: left;
}
/* la fascia diventa a due colonne: la targhetta a sinistra, i lavori a destra */
body.page-perche main .sec:has(.lavori) > .wrap {
  display: grid; grid-template-columns: max-content minmax(0, 1fr);
  column-gap: 40px; align-items: start;
}
@media (max-width: 900px) {
  /* su schermo stretto la targhetta verticale mangerebbe l'altezza: torna in riga */
  body.page-perche main .sec h2:has(+ .lavori) {
    writing-mode: horizontal-tb; transform: none; height: auto;
  }
  body.page-perche main .sec:has(.lavori) > .wrap { display: block; }
}

/* ⚠️ «SAPPIAMO TUTTO SULLE PARTNERSHIP» stava attaccata alla fascia sopra:
   stacco 0px contro i 150px della fonte, misurati. La fascia e' `continua`,
   e quella classe toglie il respiro apposta — ma qui la fonte il respiro ce
   l'ha. */
/* ⚠️ `:has()` ANNIDATO DENTRO `:has()` NON ESISTE. La prima stesura diceva
   `.sec:has(> .wrap > h2:has(+ .loghi))`: il parser lo accetta — `selettori.mjs`
   ha riportato «0 non validi» — e poi non pesca mai niente. Un selettore che
   non seleziona non da' errore: e' la stessa trappola che quel collaudo e'
   nato per prendere, e qui gli e' passata sotto il naso perche' guarda la
   sintassi, non il risultato.
   Qui basta piatto: e' l'unica fascia SCURA con dei loghi dentro — «Visto su:»
   ha i loghi ma non e' scura. */
/* ⚠️ I 150px di margine qui sopra NON CI SONO PIU'. Giovanni, 2026-09-30:
   «cancella la barra bianca sopra a SAPPIAMO TUTTO SULLE PARTNERSHIP». Erano
   misurati sulla fonte, ma fra due fasce SCURE quel margine mostra il fondo
   della pagina — cioe' una striscia bianca alta 150px in mezzo al nero. Il
   respiro fra le due fasce resta, ma dentro la banda: e' il `padding-top` qui
   sotto, che ha anche il pregio di staccare il TITOLO dal suo bordo invece
   che la fascia da quella sopra. Per tornare alla fonte: `margin-top: 150px`. */
/* ⚠️ E il RESPIRO DENTRO la fascia, che il margine qui sopra non da'. Quella
   fascia e' `continua` — `padding-top: 0` — e il margine la stacca da quella
   prima senza staccare il TITOLO dal suo bordo: sullo scatto «SAPPIAMO TUTTO
   SULLE PARTNERSHIP» comincia dove il grigio diventa nero.
   `_diag-continua.mjs` lo misura da giorni e dice «a 0px dal bordo».
   ⚠️ Perche' `continua` c'e' ancora: il modello dei toni tratta `sec-dark`
   come UN colore, e queste due fasce sono entrambe `sec-dark` nel markup. La
   differenza la fa `:has(a[href*="uptonica"])`, che porta il fondo a #0d0d0d
   — un selettore CSS, non una classe. `cuci_sezioni()` e `ricuci_sezioni.py`
   confrontano le CLASSI: quel cambio di colore non lo possono vedere. Qui si
   rimette il padding con lo STESSO selettore che il colore lo cambia, cosi'
   le due cose restano legate. */
body.page-perche main .sec.sec-dark.continua:has(> .wrap > .loghi) {
  padding-top: clamp(48px, 8vw, 88px);
}


/* ── «Portfolio» centrato quando la targhetta verticale si sdraia ─────────
   ⚠️ Sopra i 900px quel titolo e' una TARGHETTA VERTICALE a sinistra della
   griglia dei lavori, e il `text-align: left` serve. Sotto, la targhetta
   torna orizzontale e la fascia torna a una colonna: li' il `left` resta
   addosso e il titolo e' l'unico fuori asse della pagina sul telefono —
   misurato, testo a x=81 contro un centro colonna a 195, su entrambe le
   lingue. (Giovanni, 2026-09-30: «allinea al centro».)
   ⚠️ Scritta qui in fondo e non dentro il blocco della targhetta, che e'
   dell'altra sessione e di poche ore fa: stesso selettore, quindi vince
   perche' viene dopo. Se un giorno quel blocco si sposta piu' in basso,
   questa smette di funzionare — e `_diag-asse.mjs` lo dice.
   ⚠️ 900px e non 820: e' il punto di rottura della TARGHETTA. «Visto su:»
   usa 820 perche' li' si sdraia la riga dei loghi. Due righe diverse, due
   punti di rottura diversi, misurati ciascuno sul suo. */
/* ⚠️ E `text-align` DA SOLO non basta: la targhetta ha `width: max-content`,
   quindi la scatola stringe sul testo e l'allineamento interno non sposta
   niente — `text-align` diceva «center» e il titolo restava a x=81. Va
   sciolta anche la larghezza e centrata la SCATOLA. E' la stessa trappola
   «misura il contenitore, non il contenuto» applicata al rimedio invece che
   alla diagnosi. */
@media (max-width: 900px) {
  body.page-perche main .sec h2:has(+ .lavori) {
    text-align: center; width: auto; margin-inline: auto;
  }
}


/* ── «Entra a far parte del Team.» centrato come il resto della pagina ────
   ⚠️ Giovanni, 2026-09-30: «il titolo non e' centrato» su
   `/it/lavora-con-noi/`. Centrato l'eroe (in `eroe_fonte.py`), restava a
   bandiera il titolo SUBITO SOTTO — misurato testo a x=341 contro un centro
   colonna a 703 — mentre «POSIZIONI APERTE» e «CANDIDATURA SPONTANEA», piu'
   in basso nella stessa pagina, erano gia' centrati. Un titolo a sinistra fra
   un eroe centrato e due titoli centrati si nota piu' di tutti e tre insieme.
   ⚠️ La regola che lo teneva a sinistra e' misurata e il suo commento spiega
   che era stata verificata anche sulla gemella inglese PRIMA di scriverla.
   Non era sbagliata: e' superata da una richiesta, come il resto di oggi.
   Per tornare indietro si toglie questo blocco.
   ⚠️ Serve anche `margin-inline: auto`: quella regola mette `margin-inline: 0`
   e `max-width: none`, quindi la scatola resta a sinistra e `text-align` da
   solo non sposta un titolo che ha gia' la larghezza della colonna. */
body.page-posizioni main .hero + .sec-lead > .wrap > h2 {
  text-align: center; margin-inline: auto;
}


/* ── Le immagini sciolte dentro una fascia centrata (2026-09-30) ──────────
   ⚠️ Su `/it/perche-scegliere-webgas/` la copertina del caso studio sotto
   «Recensioni video» e il calendario sotto «LA TUA AZIENDA E' PRONTA A
   CRESCERE?» stavano a filo del margine sinistro — misurate a x=226 e x=103
   contro un centro colonna a 703 — dentro fasce in cui titolo, prosa e
   pulsante sono tutti centrati. Una sola cosa fuori asse si nota piu' di
   tutte quelle in asse messe insieme.
   ⚠️ `.sec-lead` centra i suoi figli UNO PER UNO (`margin-inline: auto` su
   `h2`, `.sub`, `.prose`), non con un `text-align` sul `.wrap`: un `<img>`
   e' un elemento a blocco lasciato al suo posto, e nessuno lo aveva mai
   elencato. Non e' un caso isolato mancato: e' una voce che manca da
   quell'elenco.
   ⚠️ Ambito stretto per scelta: le immagini figlie DIRETTE di un `.wrap`
   dentro `.sec-lead` esistono solo su queste due pagine — quattro in tutto,
   contate su tutto il sito. Una regola globale toccherebbe zero pagine in
   piu' oggi e chissa' quante domani. */
body.page-perche main .sec-lead > .wrap > img {
  display: block; margin-inline: auto;
}


/* ── «Guarda le nostre creazioni» al centro della fascia portfolio ────────
   ⚠️ Giovanni, 2026-09-30: «centra questa scritta». Quella fascia e' una
   griglia a due colonne — targhetta verticale a sinistra, lavori a destra —
   e il pulsante, figlio diretto del `.wrap`, cadeva nella PRIMA colonna,
   sotto la targhetta: misurato a x=250 mentre la griglia dei lavori sta a
   870 e il titolo e' la targhetta stessa. Non era un problema di
   allineamento del testo: era una cella sbagliata.
   ⚠️ `grid-column: 1 / -1` e non `justify-self` da solo: senza lo scavalco
   il pulsante resta largo quanto la colonna della targhetta, e centrarlo
   dentro quella colonna lo lascia comunque a sinistra della fascia. E' la
   stessa differenza fra centrare il contenuto e centrare il contenitore che
   mi e' gia' costata due giri su questa pagina.
   ⚠️ Sotto i 900px la griglia torna a una colonna sola e il `.hero-azioni`
   si centra da se': la regola vale comunque, e non fa danno. */
body.page-perche main .sec:has(.lavori) > .wrap > .hero-azioni,
body.page-perche main .sec:has(.lavori) > .wrap > a.hero-cta {
  grid-column: 1 / -1; justify-self: center;
}


/* ── Le cinque schede dei casi studio dentro «CASI STUDIO» (2026-09-30) ───
   Chieste da Giovanni insieme alla rimozione della giostra dei settori:
   «metti tutti i casi studio».
   ⚠️ La copertina NON si ritaglia. `.cards .card-cover` impone
   `aspect-ratio: 1` con `object-fit: cover`, e queste copertine sono
   LOCANDINE verticali (851x1100) che dicono una cosa: tagliate a quadrato
   perdono la riga in basso — «UN CASO REALE DI CRESCITA CONTROLLATA» usciva
   mozzata a meta'. Qui vale il rapporto vero dell'immagine.
   ⚠️ E cinque colonne, non quattro: con `minmax(280px, 1fr)` dentro una
   colonna da 1200 ne entrano quattro e la quinta resta orfana su una riga
   sua. Con `minmax(0, 1fr)` e `repeat(5, ...)` stanno tutte in fila a 224px
   l'una — che per una locandina verticale e' anche la proporzione giusta.
   ⚠️ Sotto i 900px si torna all'automatico: cinque colonne su un telefono
   sarebbero cinque francobolli. */
body.page-perche .cards-casi {
  grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 18px;
}
body.page-perche .cards-casi .card-cover {
  aspect-ratio: auto; height: auto; object-fit: contain;
}
@media (max-width: 900px) {
  body.page-perche .cards-casi {
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  }
}

/* Cliente messo in evidenza dal committente (`"evidenza": true` in
   `.migration/muro-aggiunti.json`): piu' grande degli altri loghi del nastro.
   ⚠️ `!important` sull'altezza perche' `ritaglia_marchi` scrive
   `style="height:…"` in linea a ogni giro, tarato sull'area degli altri. */
.nastro .loghi img.in-evidenza { height: 78px !important; max-height: 78px; max-width: 380px; }
.logos img.in-evidenza { max-width: 240px; }
@media (max-width: 767px) {
  .nastro .loghi img.in-evidenza { height: 52px !important; max-height: 52px; }
  .logos img.in-evidenza { max-width: 170px; }
}
@media (max-width: 480px) { .nastro .loghi img.in-evidenza { height: 42px !important; max-height: 42px; } }
