/* components.css — i componenti di thermo_hydraulic_store. Consuma SOLO i token di tokens.css.
   ⚠ Il CSS si verifica nel DOM CALCOLATO, mai «a lettura»: a parità di specificità VINCE WordPress, perché
   il CSS dei blocchi è iniettato DOPO il tema. Dove serve battere WP-core il selettore è più lungo di
   proposito e il motivo è scritto sul posto. */

/* ==========================================================================
   1. Barra istituzionale + testata
   ========================================================================== */

.topbar {
  background: linear-gradient(92deg, var(--brand-dark) 0%, var(--brand-dark) 62%, #123f76 100%);
  color: var(--on-dark-muted);
  font-size: var(--text-sm);
}
.topbar__row {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-5);
  padding-block: 0.5rem;
}
.topbar__item { display: inline-flex; align-items: center; gap: var(--space-2); }
.topbar a { color: var(--on-dark); text-decoration: none; }
.topbar a:hover { color: var(--accent-lt); text-decoration: underline; }
.topbar__spacer { margin-left: auto; }
/* L'orario è l'informazione più cercata di un negozio che riceve: sta in chiaro, non in tenue. */
.topbar__hours { color: var(--on-dark); font-weight: 500; }
/* ⚠ Il focus si RIBALTA su campitura blu: --focus (blu) su blu sarebbe invisibile. */
.topbar :focus-visible { outline-color: var(--accent-lt); }

/* ⚠⚠ La striscia bianca sotto la testata: `header` e `main` sono fratelli nel TEMPLATE, non figli del
   post-content, quindi l'azzeramento dei margini dei figli del post-content non li tocca. Il filetto
   inferiore poi separava la testata dalla banda anche quando i due erano a contatto. */
.wp-block-post-content, main, main > * { margin-block: 0; }
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--paper);
  transition: box-shadow .2s ease, padding .2s ease;
}
.site-header.is-stuck { box-shadow: var(--shadow-md); }

.site-header__row {
  display: flex; align-items: center; gap: var(--space-5);
  padding-block: var(--space-4);
}
/* Regola 16: testata centrata verticalmente. nav e CTA hanno un margine di blocco (WP) che li spinge
   ~12px sotto il centro: si azzera e si allinea ognuno al centro. Misurare col getBoundingClientRect. */
.site-header__row > * { align-self: center; margin-block: 0; }

.wordmark {
  display: inline-flex; align-items: center; gap: var(--space-3);
  text-decoration: none; color: var(--ink); flex: none;
}
/* ⚠⚠ Un marchio SVG si misura sulla LARGHEZZA, non sull'altezza, e si misura l'INCHIOSTRO non il box:
   con `height` fissa dentro un flex item riducibile, la riga piena gli stringe la larghezza e l'SVG si
   ridisegna DENTRO il box — non risulta deformato, risulta PICCOLO, e nessuna misura del box lo denuncia.
   Qui la larghezza è dichiarata e il flex NON lo comprime (`flex:none` sul .wordmark). */
.wordmark__mark { inline-size: 44px; block-size: 44px; border-radius: 10px; flex: none; }
.wordmark__txt { display: flex; flex-direction: column; line-height: 1.1; }
.wordmark__name {
  font-family: var(--font-display); font-weight: 800; font-size: 1.32rem;
  letter-spacing: -0.02em; color: var(--ink);
}
.wordmark__tag {
  font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--accent-ink); font-weight: 600;
}

/* --- Navigazione ---
   ⚠⚠ Specificità contro WP-core. `.wp-block-navigation .wp-block-navigation-item__content` è (0,2,0):
   una regola a (0,2,0) dichiarata dal tema PERDE, perché il CSS dei blocchi arriva dopo. Servono TRE
   classi, e il colore va messo anche sullo `__label`, che WP colora a sua volta. */
.site-header .site-nav { margin-left: auto; }
/* ⚠ Il layout della riga di navigazione si DICHIARA qui, non si eredita dal CSS di block-support di WP:
   fidarsi di quello è dove si perde (arriva dopo il tema, e fuori da WordPress non arriva affatto — la
   preview statica mostrerebbe un elenco puntato impilato, cioè mentirebbe sulla testata). */
.site-header .site-nav .wp-block-navigation__container {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  list-style: none; margin: 0; padding: 0;
}
.site-header .site-nav .wp-block-navigation-item__content {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--ink);
  text-decoration: none;
  padding-block: 0.35rem;
}
.site-header .site-nav .wp-block-navigation-item__content .wp-block-navigation-item__label { color: var(--ink); }
.site-header .site-nav .wp-block-navigation-item__content:hover,
.site-header .site-nav .wp-block-navigation-item__content:hover .wp-block-navigation-item__label { color: var(--brand); }
.site-header .site-nav .current-menu-item > .wp-block-navigation-item__content .wp-block-navigation-item__label { color: var(--brand); }

/* ⚠ La `ul` di `wp:navigation` nasce `flex-wrap: wrap`: con `margin-left:auto` una voce in più va ORFANA
   su due righe. Sopra i 900px si vieta l'andare a capo. */
@media (min-width: 900px) {
  .site-header .site-nav .wp-block-navigation__container { flex-wrap: nowrap; }
}

/* Tendina: WP la tiene BIANCA con (0,2,0) — si vince con un livello in più, ricopiando il suo schema. */
.site-header .site-nav .wp-block-navigation__submenu-container {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  padding-block: var(--space-2);
  min-inline-size: 15rem;
}
.site-header .site-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
  padding: 0.5rem var(--space-4);
  font-weight: 600;
}

/* --- Overlay mobile del menu ---
   ⚠⚠ L'overlay di WP resta BIANCO per una regola a (0,4,0) che usa `:not(.has-background)` e
   `:not(.disable-default-overlay)`: si vince solo RICOPIANDO il suo schema di selettore.
   ⚠⚠ E se la testata avesse `backdrop-filter`, quel filtro creerebbe un containing-block per il
   `position:fixed` e l'overlay si limiterebbe all'ALTEZZA DELL'HEADER: l'altezza si forza a 100vh. */
.wp-block-navigation__responsive-container.is-menu-open:not(.has-background):not(.disable-default-overlay) {
  background: var(--paper);
  color: var(--ink);
}
.wp-block-navigation__responsive-container.is-menu-open {
  height: 100vh; max-height: 100vh;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: var(--space-6) var(--gutter);
}
/* ⚠⚠ Il contenitore del contenuto è un flex-column largo quanto il viewport e allineato a FLEX-END: le
   voci finivano a destra e TAGLIATE oltre il bordo. Non basta dare `width:100%` all'ancora — va
   corretto il PADRE, che è il primo antenato largo quanto lo schermo con l'allineamento contrario. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
  padding-bottom: 96px;
  inline-size: 100%;
  align-items: stretch !important;
  justify-content: flex-start !important;
}
/* ⚠⚠ MISURATO risalendo la catena dei genitori: dialog, container-content e la `ul` erano TUTTI larghi
   390px con margine destro ZERO, e le voci toccavano il bordo. Il padding va messo sui GENITORI con
   abbastanza specificità (tre classi) — sull'overlay da solo non agganciava — e la `ul` reale porta la
   classe `wp-block-navigation`, non `__container`: targettizzare solo quella non la toccava. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
  box-sizing: border-box;
  padding-inline: var(--gutter);
  inline-size: 100%;
}
.wp-block-navigation__responsive-container.is-menu-open ul.wp-block-navigation,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
  inline-size: 100%; align-items: stretch; justify-content: flex-start; gap: 0;
  padding-inline: 0; margin-inline: 0; list-style: none;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-link,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-submenu {
  inline-size: 100%; text-align: left;
}
/* La X: era minuscola e senza stile. Diventa un bottone tondo, tocco ≥44px come esige la a11y. */
.wp-block-navigation__responsive-container-close,
.wp-block-navigation__responsive-container-open {
  inline-size: 2.75rem; block-size: 2.75rem;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--brand-dark);
  background: var(--surface-2);
}
.wp-block-navigation__responsive-container-close svg,
.wp-block-navigation__responsive-container-open svg { inline-size: 1.35rem; block-size: 1.35rem; }
.wp-block-navigation__responsive-container-close:hover { background: var(--accent-tint); color: var(--accent-ink); }
.wp-block-navigation__responsive-container-close:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog { padding-top: var(--space-6); }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
  /* ⚠ L'`<a>` è `display:block` shrink: dentro un flex-column finisce allineato a DESTRA.
     Con `width:100%` + `text-align:left` torna a sinistra. */
  inline-size: 100%;
  text-align: left;
  padding-block: 0.85rem;
  border-bottom: 1px solid var(--line);
  font-size: var(--text-md);
}
/* Sotto-menu INLINE nell'overlay: il default di WP li rende come card-dropdown, illeggibili su mobile. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container {
  position: static !important;
  border: 0 !important;
  box-shadow: none !important;
  background: none !important;
  padding-left: var(--space-5);
  min-inline-size: 0;
}

.site-header__cta { flex: none; }


/* --- Sorgente delle maschere delle icone ---
   ⚠⚠ Le proprietà di posizione/ripetizione/taglia NON bastano: senza `mask-image` il `background-color`
   dell'elemento si vede per TUTTO il riquadro e l'icona diventa un QUADRATO PIENO. Leggendo il foglio non
   si nota (le regole sembrano complete): lo dice solo la pagina resa.
   ⚠ La maschera vive QUI, nel CSS del verticale, e MAI in uno style inline nel `post_content`: `rewriteOf`
   riscrive `../assets/` solo nei `.php` del tema, quindi nel DB quell'URL non si risolverebbe. Nel foglio
   invece `url()` si risolve rispetto al FOGLIO, che è ciò che serve.
   L'attributo `data-icon` arriva dall'IR (`items.N.icon`), non è cablato per slot nel pattern: l'icona
   segue il SIGNIFICATO della voce, non la sua posizione. */
[data-icon] {
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
}
[data-icon="acqua"] { -webkit-mask-image: url("../assets/img/icons/acqua.svg"); mask-image: url("../assets/img/icons/acqua.svg"); }
[data-icon="assistenza"] { -webkit-mask-image: url("../assets/img/icons/assistenza.svg"); mask-image: url("../assets/img/icons/assistenza.svg"); }
[data-icon="bagno"] { -webkit-mask-image: url("../assets/img/icons/bagno.svg"); mask-image: url("../assets/img/icons/bagno.svg"); }
[data-icon="caldaia"] { -webkit-mask-image: url("../assets/img/icons/caldaia.svg"); mask-image: url("../assets/img/icons/caldaia.svg"); }
[data-icon="ceramica"] { -webkit-mask-image: url("../assets/img/icons/ceramica.svg"); mask-image: url("../assets/img/icons/ceramica.svg"); }
[data-icon="check"] { -webkit-mask-image: url("../assets/img/icons/check.svg"); mask-image: url("../assets/img/icons/check.svg"); }
[data-icon="clima"] { -webkit-mask-image: url("../assets/img/icons/clima.svg"); mask-image: url("../assets/img/icons/clima.svg"); }
[data-icon="consulenza"] { -webkit-mask-image: url("../assets/img/icons/consulenza.svg"); mask-image: url("../assets/img/icons/consulenza.svg"); }
[data-icon="ibridi"] { -webkit-mask-image: url("../assets/img/icons/ibridi.svg"); mask-image: url("../assets/img/icons/ibridi.svg"); }
[data-icon="idraulica"] { -webkit-mask-image: url("../assets/img/icons/idraulica.svg"); mask-image: url("../assets/img/icons/idraulica.svg"); }
[data-icon="idraulico"] { -webkit-mask-image: url("../assets/img/icons/idraulico.svg"); mask-image: url("../assets/img/icons/idraulico.svg"); }
[data-icon="offerte"] { -webkit-mask-image: url("../assets/img/icons/offerte.svg"); mask-image: url("../assets/img/icons/offerte.svg"); }
[data-icon="pompe"] { -webkit-mask-image: url("../assets/img/icons/pompe.svg"); mask-image: url("../assets/img/icons/pompe.svg"); }
[data-icon="preventivo"] { -webkit-mask-image: url("../assets/img/icons/preventivo.svg"); mask-image: url("../assets/img/icons/preventivo.svg"); }
[data-icon="riscaldamento"] { -webkit-mask-image: url("../assets/img/icons/riscaldamento.svg"); mask-image: url("../assets/img/icons/riscaldamento.svg"); }
[data-icon="termico"] { -webkit-mask-image: url("../assets/img/icons/termico.svg"); mask-image: url("../assets/img/icons/termico.svg"); }

/* ==========================================================================
   2. Testata (hero) — pannello di testo + fotografia affiancati
   ==========================================================================
   ⚠⚠ Il titolo NON sta sopra la fotografia. In questo mestiere la fotografia è di PRODOTTO SU FONDO
   CHIARO (rubinetterie in studio, prodotti scontornati su bianco): un titolo bianco sopra uno scatto così
   scende sotto AA per costruzione, e axe non lo vedrebbe perché non valuta il testo sopra una foto.
   Qui il contrasto è STRUTTURALE: testo su campo chiaro piatto (16,54:1), foto accanto. */

.hero {
  position: relative;
  isolation: isolate;
  min-block-size: clamp(30rem, 78vh, 46rem);
  display: grid;
  align-items: center;
  overflow: clip;
  background: var(--brand-dark);
}
/* La fotografia riempie la banda intera. */
.hero__media {
  position: absolute; inset: 0; z-index: 0;
  background: var(--brand-dark);
}
.hero__media img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; }
/* ⚠⚠ VELO A GRADIENTE, non un'opacità piatta: annegare la foto per far leggere il testo è una resa.
   Sul lato del testo il velo è il blu profondo PIENO (bianco sopra = 10,39 misurato), e si apre verso
   destra lasciando la fotografia intera. Il contrasto è STRUTTURALE: non dipende dal fotogramma. */
.hero__scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    /* vampa CALDA dal basso a destra: è l'arancione del marchio che entra nel blu e lo rende meno statico */
    radial-gradient(120% 90% at 88% 108%, rgba(248,136,56,.34) 0%, rgba(248,136,56,.12) 38%, rgba(248,136,56,0) 68%),
    linear-gradient(96deg, var(--brand-dark) 0%, var(--brand-dark) 22%, rgba(11,63,125,.88) 40%, rgba(11,63,125,.44) 58%, rgba(11,63,125,.10) 80%, rgba(11,63,125,0) 100%),
    linear-gradient(0deg, rgba(7,23,38,.34) 0%, rgba(7,23,38,0) 30%);
}
/* Un filo d'arancione sul bordo inferiore: il segno caldo che entra nel blu. */
.hero::after {
  content: ""; position: absolute; z-index: 2; inset-inline: 0; inset-block-end: 0; block-size: 4px;
  background: linear-gradient(90deg, var(--accent) 0%, var(--accent) 34%, var(--brand-mid) 100%);
}
.hero__inner { position: relative; z-index: 3; padding-block: clamp(3rem, 8vh, 6rem); }
.hero__panel { max-width: 40rem; }
.hero .eyebrow { color: var(--accent-lt); }
.hero .eyebrow::before { background: linear-gradient(90deg, var(--accent) 0%, var(--accent-lt) 100%); }
.hero h1 { color: var(--on-dark); margin-bottom: var(--space-4); text-shadow: 0 1px 24px rgba(7,23,38,.28); }
.hero__lead {
  font-size: var(--text-md); color: var(--on-dark); margin-bottom: var(--space-5); max-width: 40ch;
  text-shadow: 0 1px 18px rgba(7,23,38,.3);
}
.hero__checks {
  list-style: none; margin: 0 0 var(--space-6); padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5);
}
.hero__checks li {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-sm); font-weight: 600; color: var(--on-dark);
}
.hero__checks li::before {
  content: ""; inline-size: 1.25rem; block-size: 1.25rem; flex: none; border-radius: 50%;
  background: var(--accent);
  -webkit-mask: url("../assets/img/icons/check.svg") center / 0.72rem 0.72rem no-repeat;
  mask: url("../assets/img/icons/check.svg") center / 0.72rem 0.72rem no-repeat;
}
.hero :focus-visible { outline-color: var(--accent-lt); }

/* ⭐ Effetto «simil video»: crossfade fra le slide + Ken Burns lento. Il ciclo parte OPACO (una testata
   non si presenta vuota) e le slide sono `eager`. Il parallasse NON serve qui: la banda è già piena. */
.hero__slide { position: absolute; inset: 0; opacity: 0; animation: ths-hero-fade 36s linear infinite; }
.hero__slide img { animation: ths-hero-zoom 36s ease-in-out infinite; transform-origin: 58% 45%; }
.hero__slide:nth-child(1), .hero__slide:nth-child(1) img { animation-delay: 0s; }
.hero__slide:nth-child(2), .hero__slide:nth-child(2) img { animation-delay: 9s; }
.hero__slide:nth-child(3), .hero__slide:nth-child(3) img { animation-delay: 18s; }
.hero__slide:nth-child(4), .hero__slide:nth-child(4) img { animation-delay: 27s; }
@keyframes ths-hero-fade { 0% { opacity: 1; } 22% { opacity: 1; } 25% { opacity: 0; } 97% { opacity: 0; } 100% { opacity: 1; } }
@keyframes ths-hero-zoom { 0% { transform: scale(1.04); } 25% { transform: scale(1.13); } 100% { transform: scale(1.04); } }
@media (prefers-reduced-motion: reduce) {
  .hero__slide { animation: none; opacity: 0; }
  .hero__slide:nth-child(1) { opacity: 1; }
  .hero__slide img { animation: none; transform: scale(1.04); }
}

/* Variante DESIGN: senza foto idonee la banda è una campitura col segno del verticale. Nessuna foto finta. */
.hero--design { background: linear-gradient(122deg, var(--brand-dark) 0%, var(--brand) 52%, var(--accent-dark) 100%); }
.hero--design .hero__figure {
  position: absolute; inset: 0; z-index: 0; display: grid; place-items: center; opacity: .16;
}
.hero--design .hero__figure::after {
  content: ""; inline-size: min(38vw, 26rem); aspect-ratio: 1;
  background: var(--paper);
  -webkit-mask: url("../assets/img/icons/acqua.svg") center / contain no-repeat;
  mask: url("../assets/img/icons/acqua.svg") center / contain no-repeat;
}

@media (max-width: 900px) {
  .hero { min-block-size: clamp(26rem, 70vh, 34rem); }
  .hero__panel { max-width: none; }
  .hero__scrim {
    background:
      linear-gradient(180deg, rgba(11,63,125,.72) 0%, rgba(11,63,125,.86) 46%, var(--brand-dark) 100%),
      linear-gradient(0deg, rgba(7,23,38,.3) 0%, rgba(7,23,38,0) 40%);
  }
}

/* Terza campitura: calda. L'alternanza a due tempi (bianco/ghiaccio) legge come un modulo; con una terza
   superficie il ritmo si indovina dalla seconda riga e non dalla prima. */
.section--warm {
  background:
    radial-gradient(80% 70% at 4% 0%, rgba(16,88,168,.08) 0%, rgba(16,88,168,0) 60%),
    linear-gradient(174deg, var(--accent-tint) 0%, var(--paper) 100%);
}
.section--ink {
  background:
    radial-gradient(90% 90% at 92% 8%, rgba(248,136,56,.20) 0%, rgba(248,136,56,0) 58%),
    linear-gradient(160deg, var(--brand-dark) 0%, var(--brand) 100%);
  color: var(--on-dark);
}
.section--ink h2, .section--ink .cat__title { color: var(--on-dark); }
.section--ink .lead, .section--ink .cat__text { color: var(--on-dark-muted); }
.section--ink .eyebrow { color: var(--accent-lt); }
.section--ink .eyebrow::before { background: linear-gradient(90deg, var(--accent) 0%, var(--accent-lt) 100%); }
.section--ink :focus-visible { outline-color: var(--accent-lt); }
/* ⚠⚠ UN COMPONENTE CONDIVISO NASCE CHIARO: `.btn--ghost` porta il blu di marca e un filetto tarati sul
   fondo BIANCO, e su una campitura blu misurano 1,48 e 2,96 — il bottone «Scrivi su WhatsApp» risultava
   invisibile. Il colore lo dichiara la BANDA, non il componente: chi mette un fondo scuro si prende la
   responsabilità di ciò che ci va sopra. Vale per ogni superficie scura del verticale, non per un caso. */
.section--ink .btn--ghost,
.brands .btn--ghost,
.hero .btn--ghost,
.site-footer .btn--ghost,
.band-photo__plate .btn--ghost {
  color: var(--on-dark);
  border-color: rgba(255,255,255,.5);
  background: transparent;
}
.section--ink .btn--ghost:hover,
.brands .btn--ghost:hover,
.hero .btn--ghost:hover,
.site-footer .btn--ghost:hover,
.band-photo__plate .btn--ghost:hover {
  color: var(--on-dark);
  border-color: var(--on-dark);
  background: rgba(255,255,255,.12);
}

/* ==========================================================================
   3. I reparti — il mosaico a TEMPERATURA (il segno del verticale)
   ==========================================================================
   Ogni tessera porta la temperatura della propria famiglia di prodotto: freddo (si toglie calore), caldo
   (si dà calore), neutro (né l'uno né l'altro). I sistemi IBRIDI portano entrambi i segni, perché fanno
   entrambe le cose. Serve a dare colore a decine di tessere altrimenti identiche su fondo bianco: qui è
   il COLORE che separa, non la fotografia — che in questo mestiere è di prodotto e si somiglia tutta. */

.cats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4); }
.cat {
  position: relative;
  display: flex; flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  border-radius: var(--radius);
  background: var(--t-neutral-bg);
  color: var(--ink);
  text-decoration: none;
  overflow: hidden;
  transition: transform .2s ease, box-shadow .2s ease;
}
.cat:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
/* Il SEGNO: un filetto in cima, nel colore della temperatura. È ciò che si vede da lontano.
   ⚠⚠ Il segno caldo NON è l'arancione di marca: --accent sul proprio tint fa 2,20 e non si vedrebbe.
   Il caldo è --accent-ink (5,31 sul tint caldo), il freddo --brand (6,04), il neutro --ink-muted (6,45). */
.cat::before {
  content: ""; position: absolute; inset-inline: 0; top: 0; block-size: 4px;
  background: var(--t-neutral);
}
.cat__ico {
  inline-size: 2.15rem; block-size: 2.15rem; flex: none;
  background: var(--t-neutral);
  /* ⚠ La maschera vive QUI, nel CSS del verticale: un `mask-image:url('../assets/…')` in uno style inline
     NON risolve nel `post_content`, perché `rewriteOf` riscrive `../assets/` solo nei `.php` del tema. */
}
.cat__title { font-family: var(--font-display); font-weight: 800; font-size: var(--text-md); margin: 0; letter-spacing: -0.01em; }
.cat__text { font-size: var(--text-sm); color: var(--ink-muted); margin: 0; flex: 1 1 auto; }
.cat__more {
  font-family: var(--font-display); font-weight: 700; font-size: var(--text-sm);
  color: var(--t-neutral); display: inline-flex; align-items: center; gap: var(--space-2);
}
.cat:hover .cat__more { gap: var(--space-3); }

/* Temperature. Il vocabolario è CHIUSO: freddo, caldo, neutro, ibrido. */
.cat--cold { background: linear-gradient(150deg, var(--t-cold-bg) 0%, var(--t-cold-bg2) 100%); }
.cat--cold::before, .cat--cold .cat__ico, .cat--cold .cat__more { background-color: var(--t-cold); }
.cat--cold .cat__more { background: none; color: var(--t-cold); }
.cat--warm { background: linear-gradient(150deg, var(--t-warm-bg) 0%, var(--t-warm-bg2) 100%); }
.cat--warm::before, .cat--warm .cat__ico { background-color: var(--t-warm); }
.cat--warm .cat__more { color: var(--t-warm); }
.cat--neutral { background: var(--t-neutral-bg); }
.cat--neutral::before, .cat--neutral .cat__ico { background-color: var(--t-neutral); }
.cat--neutral .cat__more { color: var(--t-neutral); }
/* IBRIDO: porta i due segni insieme. È l'unica tessera con un filetto sfumato, e non è un vezzo — è
   letteralmente ciò che fa un sistema ibrido (caldaia + pompa di calore che si alternano). */
.cat--hybrid { background: linear-gradient(115deg, var(--t-cold-bg) 0%, var(--t-cold-bg) 44%, var(--t-warm-bg) 56%, var(--t-warm-bg) 100%); }
.cat--hybrid::before { background: linear-gradient(90deg, var(--t-cold) 0%, var(--t-warm) 100%); }
.cat--hybrid .cat__ico { background-color: var(--t-cold); }
.cat--hybrid .cat__more { color: var(--t-cold); }

/* La prima tessera è più grande: un mosaico si indovina dalla seconda riga, e una griglia 4×2 tutta
   uguale legge come un listino. ⚠ Nessuna tessera resta orfana: 8 tessere in 4 colonne con la prima a
   2×2 fanno esattamente 3 righe piene. */
.cat--lead { grid-column: span 2; grid-row: span 2; justify-content: space-between; }
/* ⚠⚠ La tessera LARGA non è un vezzo: è aritmetica. 8 tessere in 4 colonne con la prima a 2×2 fanno 11
   celle su 12 e ne lascia una ORFANA — e «nessuna tessera resta orfana». Una seconda tessera a 2×1 porta
   il conto a 12, cioè 3 righe piene. Tocca ai SISTEMI IBRIDI perché è la sezione senza foto grandi: la
   tessera larga a due temperature è il suo trattamento, non un ripiego. */
.cat--wide { grid-column: span 2; }
/* ⚠⚠ ARITMETICA: guida 2×2 (4 celle) + 6 tessere singole + una larga (2) = 12 = tre righe PIENE su quattro
   colonne. Senza l'ultima larga restano 11 celle e l'ultima riga ha un buco a destra. */
.cat--tail { grid-column: span 2; }
@media (max-width: 1080px) { .cat--tail { grid-column: span 2; } }
@media (max-width: 620px) { .cat--tail { grid-column: auto; } }
.cat--lead .cat__title { font-size: var(--text-lg); }
.cat--lead .cat__text { font-size: var(--text-base); }
.cat--lead .cat__ico { inline-size: 2.9rem; block-size: 2.9rem; }

@media (max-width: 1080px) {
  .cats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cat--lead { grid-column: span 2; grid-row: auto; }
}
@media (max-width: 620px) {
  .cats { grid-template-columns: 1fr; }
  /* ⚠⚠ ENTRAMBE le tessere che si allargano vanno riportate a una colonna. Su una griglia a `1fr` uno
     `grid-column: span 2` NON viene ignorato: crea una colonna IMPLICITA e la griglia torna a due colonne
     strettissime, col testo spezzato una lettera per riga. Dimenticarne una sola basta a rompere tutto. */
  .cat--lead, .cat--wide { grid-column: auto; grid-row: auto; }
}

/* ==========================================================================
   4. Le offerte — schede di prodotto con la condizione economica
   ==========================================================================
   ⚠ Non esiste carrello: la scheda porta al PREVENTIVO. La condizione economica è copy `needs_human`,
   confermata dal cliente prima della pubblicazione. */

.offers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-5); }
.offer {
  display: flex; flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.offer:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); border-color: var(--line-strong); }
.offer__media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: linear-gradient(160deg, var(--surface) 0%, var(--t-cold-bg) 100%);
  display: grid; place-items: center;
  border-bottom: 1px solid var(--line);
}
/* ⚠⚠ `contain`, NON `cover`: le foto di prodotto di questo settore sono SCONTORNATE SU BIANCO
   (misurato: luminosità fino a 0,99), e `cover` le taglia. Il fondo è la superficie di marca. */
.offer__media img {
  position: absolute; inset: 0;
  inline-size: 100%; block-size: 100%;
  object-fit: contain;
  padding: var(--space-4);
}
.offer__ico {
  inline-size: 2.4rem; block-size: 2.4rem;
  background: var(--line-strong);
}
.offer__body { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); flex: 1 1 auto; }
.offer__title { font-family: var(--font-display); font-weight: 800; font-size: var(--text-md); margin: 0; letter-spacing: -0.01em; }
/* La condizione economica: si legge come un dato, in arancione-testo (5,93 su bianco). */
.offer__terms {
  font-family: var(--font-display); font-weight: 700; font-size: var(--text-base);
  color: var(--accent-ink); margin: 0;
}
.offer__cta { margin-top: auto; }
/* ⚠ La targhetta finiva SOTTO la fotografia: nel markup viene prima dell'`<img>`, e senza un ordine di
   pila dichiarato è l'immagine a dipingere sopra. Serve lo z-index — spostarla non basterebbe, la
   sovrapposizione tornerebbe con un prodotto più largo. Un filo più a sinistra e più in alto, così sta
   nell'angolo della tessera e non sul bordo dello scatto. */
.offer__badge {
  position: absolute; z-index: 2; top: var(--space-2); left: var(--space-2);
  background: var(--accent); color: var(--ink);
  font-family: var(--font-display); font-weight: 700; font-size: 0.72rem;
  letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.25rem 0.6rem; border-radius: 999px;
}
@media (max-width: 1080px) { .offers { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .offers { grid-template-columns: 1fr; } }

/* ==========================================================================
   5. Chi siamo
   ========================================================================== */

.about { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.86fr); gap: clamp(var(--space-6), 4vw, var(--space-8)); align-items: center; }
/* ⭐ La fotografia SCAVALCA il bordo inferiore della banda di uno `--overlap` dichiarato, e la sezione
   seguente apre lo spazio esatto: nessuna dipendenza da quale colonna sia più alta. */
.about__media {
  position: relative; z-index: 2;
  border-radius: var(--radius-lg); overflow: clip; aspect-ratio: 5 / 4;
  background: var(--surface-2); box-shadow: var(--shadow-lift);
}
.about__par { position: absolute; inset: -15% 0; will-change: transform; }
.about__media img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; }
/* Lo spazio per lo scavalcamento lo apre CHI VIENE DOPO, con lo stesso valore dichiarato. */
.section--overlapped { padding-top: calc(var(--section-y) + var(--overlap)); }
/* La targa: un riquadro pieno d'accento tenue che regge il testo (blu su tint caldo = 6,31). */
.about__plate {
  margin-top: var(--space-5);
  padding: var(--space-5);
  background: var(--accent-tint);
  border-radius: var(--radius);
  border-left: 4px solid var(--accent);
}
.about__plate p { margin: 0; color: var(--ink); }
@media (max-width: 900px) { .about { grid-template-columns: 1fr; } }

/* --- Banda fotografica a cavallo di due campi ---
   ⭐ Lo scavalcamento qui è STRUTTURALE e non dipende da nessuna altezza: il fondo è metà bianco e metà
   ghiaccio, e la cornice della fotografia sta esattamente sulla linea di confine. Il parallasse è più
   ampio che nella testata perché la banda è alta e la deriva ha spazio per leggersi. */
.band-photo { position: relative; padding: 0; background: linear-gradient(180deg, var(--paper) 0 50%, var(--surface) 50% 100%); }
.band-photo { padding-block: 0; }
.band-photo .container { max-width: none; padding-inline: 0; }
.band-photo__frame {
  position: relative; overflow: clip;
  block-size: clamp(20rem, 46vw, 38rem);
  border-radius: 0;
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  box-shadow: var(--shadow-lift);
}
.band-photo__par { position: absolute; inset: -20% 0; will-change: transform; }
.band-photo__frame img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; }
.band-photo__frame::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(90% 80% at 8% 100%, rgba(11,63,125,.52) 0%, rgba(11,63,125,0) 62%),
    radial-gradient(70% 70% at 96% 6%, rgba(248,136,56,.22) 0%, rgba(248,136,56,0) 60%);
}
/* Una targa sulla fotografia: il testo sta su campo PIENO, non sopra i pixel — il contrasto è strutturale. */
/* La targa entra nel margine del contenitore, non al bordo assoluto dello schermo. */
.band-photo__plate {
  position: absolute; z-index: 2; inset-block-end: clamp(1.5rem, 4vw, 3rem);
  inset-inline-start: max(var(--gutter), (100vw - var(--container)) / 2);
  max-inline-size: min(34rem, 78%);
  border-radius: var(--radius);
  background: var(--brand-dark); color: var(--on-dark);
  padding: var(--space-5) var(--space-6);
}
.band-photo__plate p { margin: 0; color: var(--on-dark); font-family: var(--font-display); font-weight: 700; font-size: var(--text-md); line-height: var(--lh-snug); }
.band-photo__plate :focus-visible { outline-color: var(--accent-lt); }

/* ==========================================================================
   6. Come lavoriamo — i passi
   ========================================================================== */

.steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-5); }
.step {
  position: relative;
  background: linear-gradient(166deg, var(--paper) 0%, var(--surface) 100%);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-6) var(--space-5) var(--space-5);
}
/* Il numerale grande e chiaro è il registro della vetrina contemporanea: si legge come struttura, non
   come decorazione, e non compete col titolo perché sta dietro. */
.step__n {
  position: absolute; top: var(--space-3); right: var(--space-4);
  font-family: var(--font-display); font-weight: 800; font-size: 3.4rem; line-height: 1;
  color: var(--line-strong);
  pointer-events: none;
}
.step__ico {
  inline-size: 2.4rem; block-size: 2.4rem; margin-bottom: var(--space-4);
  background: var(--brand);
}
.step__title { font-family: var(--font-display); font-weight: 800; font-size: var(--text-md); margin: 0 0 var(--space-2); }
.step__text { font-size: var(--text-sm); color: var(--ink-muted); margin: 0; }
@media (max-width: 900px) { .steps { grid-template-columns: 1fr; } }

/* ==========================================================================
   7. I marchi
   ==========================================================================
   Il muro di LOGHI è materiale di PROGETTO (canale @design): il verticale rende i reparti, perché quali
   marchi un negozio tratta non è deducibile dal mestiere. */

/* ⚠⚠ Il gradiente resta fra brand-dark e brand, MISURATO: arrivando a brand-mid il testo tenue scende a
   4,03 e l'arancione chiaro a 3,86. Un fondo sfumato va misurato ai DUE estremi, e il punto peggiore
   decide — axe non lo coglie, perché risolve il fondo sugli antenati. */
.brands {
  background:
    radial-gradient(90% 120% at 96% 4%, rgba(248,136,56,.26) 0%, rgba(248,136,56,0) 58%),
    radial-gradient(80% 100% at 2% 96%, rgba(248,136,56,.16) 0%, rgba(248,136,56,0) 54%),
    linear-gradient(158deg, var(--brand-dark) 0%, var(--brand) 54%, var(--brand-dark) 100%);
  color: var(--on-dark); padding-block: var(--section-y);
}
.brands .eyebrow { color: var(--accent-lt); }
.brands .eyebrow::before { background: var(--accent-lt); }
.brands h2 { color: var(--on-dark); }
.brands .section-intro .lead { color: var(--on-dark-muted); }
/* ⚠ Il focus si RIBALTA sulla campitura blu. */
.brands :focus-visible { outline-color: var(--accent-lt); }
.brands__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-6); }
.brands__group { border-top: 3px solid var(--accent); padding-top: var(--space-4); }
.brands__ico {
  inline-size: 2rem; block-size: 2rem; margin-bottom: var(--space-3);
  background: var(--accent-lt);
}
/* ⚠ Un componente condiviso NASCE CHIARO: qui il titolo va dichiarato su fondo scuro, sennò eredita
   l'inchiostro e diventa invisibile sul blu. È il difetto che axe NON segnala (guarda i valori, non le
   etichette): scuro su scuro può passare. */
.brands__title { font-family: var(--font-display); font-weight: 800; font-size: var(--text-md); color: var(--on-dark); margin: 0 0 var(--space-2); }
.brands__text { font-size: var(--text-sm); color: var(--on-dark-muted); margin: 0; }
@media (max-width: 900px) { .brands__grid { grid-template-columns: 1fr; gap: var(--space-5); } }

/* --- Nastro continuo dei marchi ---
   ⭐ Due piste identiche affiancate che scorrono: l'anello si chiude senza salto. Il micro-JS duplica la
   pista e forza le immagini a `eager` — dentro un nastro una `lazy` non intersecherebbe MAI il viewport e
   resterebbe incompleta per sempre.
   ⚠ `overflow: clip`, mai `hidden`: `hidden` romperebbe lo sticky della testata. */
.ribbon-band {
  padding-block: var(--space-6);
  background: linear-gradient(92deg, var(--surface) 0%, var(--paper) 42%, var(--accent-tint) 100%);
  border-block: 1px solid var(--line);
}
.ribbon-band__label {
  display: block; text-align: center; margin-bottom: var(--space-4);
  font-family: var(--font-display); font-size: 0.74rem; font-weight: 700;
  letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--accent-ink);
}
.ribbon { display: flex; gap: clamp(2rem, 4vw, 3.5rem); overflow: clip; }
.ribbon__track {
  display: flex; align-items: center; gap: clamp(2rem, 4vw, 3.5rem); flex: none;
  animation: ths-ribbon 46s linear infinite;
}
.ribbon img {
  block-size: 2.1rem; inline-size: auto; max-inline-size: none; flex: none;
  /* ⚠ Nessun filtro: i loghi hanno fondo BIANCO, e un `brightness(0) invert(1)` li cancellava in
     rettangoli bianchi pieni. Restano nei propri colori, su fondo chiaro. */
  opacity: .88;
}
@keyframes ths-ribbon { from { transform: translateX(0); } to { transform: translateX(-100%); } }
@media (prefers-reduced-motion: reduce) {
  .ribbon { flex-wrap: wrap; justify-content: center; row-gap: var(--space-4); }
  .ribbon__track { animation: none; flex-wrap: wrap; justify-content: center; }
  /* Il clone serve solo a chiudere l'anello in movimento: fermo, è una ripetizione visibile. */
  .ribbon .is-clone { display: none; }
}

/* --- Parete dei marchi (asset di progetto sul canale @design) ---
   ⚠ I loghi arrivano dal TEMA, non da Media Library: un logo non è una fotografia e non passa le soglie
   asset. Sono già RIFILATI dal bianco in fase di preparazione, così la parete legge allineata invece che
   sfalsata dall'aria che ogni file porta con sé. L'altezza è normalizzata e la larghezza libera: un marchio
   si misura sulla LARGHEZZA, e bloccarne due lati lo deformerebbe. */
.brandwall {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr));
  gap: var(--space-5) var(--space-6);
  align-items: center;
}
.brandwall__item { display: flex; align-items: center; justify-content: center; min-block-size: 3.5rem; }
.brandwall__item img {
  max-block-size: 2.6rem; inline-size: auto; max-inline-size: 100%;
  filter: grayscale(1); opacity: .72;
  transition: filter .22s ease, opacity .22s ease;
}
.brandwall__item img:hover { filter: none; opacity: 1; }
@media (prefers-reduced-motion: reduce) { .brandwall__item img { transition: none; } }

/* --- Mosaico fotografico ---
   ⭐ Le tessere hanno taglie DIVERSE e alcune scavalcano due colonne o due righe: una griglia uniforme
   legge come un listino, ed è esattamente l'accusa di «vuoto e triste». Le foto sono cliccabili
   (`a.zoom` accende la lightbox già costruita nel micro-JS del tema).
   ⚠ L'ordine delle taglie è dichiarato con `nth-child`, non casuale: la resa deve restare deterministica. */
.mosaic {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: clamp(8rem, 13vw, 13rem);
  gap: var(--space-3);
}
.mosaic__t {
  position: relative; display: block; overflow: clip;
  border-radius: var(--radius);
  background: var(--surface-2);
  box-shadow: var(--shadow-sm);
  transition: transform .22s ease, box-shadow .22s ease;
}
.mosaic__t img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; transition: transform .5s ease; }
/* Il gruppo che deriva è sovradimensionato quanto l'ampiezza chiede: sennò scopre un bordo. */
.mosaic__par { position: absolute; inset: -14% 0; }
.mosaic__par img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; }
.mosaic__t:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); z-index: 2; }
.mosaic__t:hover img { transform: scale(1.05); }
.mosaic__t:focus-visible { outline: 3px solid var(--brand); outline-offset: 3px; z-index: 2; }
/* Le tessere SCONTORNATE (prodotto su fondo di marca) non si tagliano: `contain` su campo tinto. */
.mosaic__t--cut { background: var(--t-cold-bg); }
.mosaic__t--cut img { object-fit: contain; padding: var(--space-3); }
/* Ritmo delle taglie: 1ª grande, poi due alte, poi larghe — si indovina dalla SECONDA riga, non dalla prima. */
.mosaic__t:nth-child(6n+1) { grid-column: span 3; grid-row: span 2; }
.mosaic__t:nth-child(6n+4) { grid-row: span 2; }
.mosaic__t:nth-child(6n+6) { grid-column: span 2; }
@media (max-width: 900px) {
  .mosaic { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: clamp(6rem, 26vw, 10rem); }
  .mosaic__t:nth-child(6n+1) { grid-column: span 3; grid-row: span 2; }
  .mosaic__t:nth-child(6n+4) { grid-row: span 1; }
  .mosaic__t:nth-child(6n+6) { grid-column: span 2; }
}
@media (prefers-reduced-motion: reduce) { .mosaic__t, .mosaic__t img, .mosaic__t:hover, .mosaic__t:hover img { transition: none; transform: none; } }

/* --- Tessera di reparto CON FOTOGRAFIA ---
   L'accusa era «card senza immagini». La foto entra nella tessera e il testo sta su una targa piena in
   basso: il contrasto è strutturale e non dipende dal fotogramma. */
.cat--photo { padding: 0; min-block-size: clamp(13rem, 20vw, 17rem); justify-content: flex-end; overflow: clip; }
.cat--photo .cat__shot { position: absolute; inset: 0; z-index: 0; }
.cat--photo .cat__shot img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; transition: transform .5s ease; }
.cat--photo:hover .cat__shot img { transform: scale(1.06); }
.cat--photo .cat__body {
  position: relative; z-index: 2; padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-2);
  background: linear-gradient(0deg, var(--brand-dark) 0%, rgba(11,63,125,.92) 58%, rgba(11,63,125,0) 100%);
}
.cat--photo .cat__title, .cat--photo .cat__text { color: var(--on-dark); }
.cat--photo .cat__text { color: var(--on-dark-muted); }
.cat--photo .cat__more { color: var(--accent-lt); }
.cat--photo .cat__ico { position: absolute; z-index: 2; inset-block-start: var(--space-4); inset-inline-start: var(--space-4); background: var(--on-dark); }
.cat--photo::before { z-index: 3; }
.cat--photo:focus-visible { outline: 3px solid var(--brand); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .cat--photo .cat__shot img, .cat--photo:hover .cat__shot img { transition: none; transform: none; } }

/* ==========================================================================
   8. Fascia contatti + piè di pagina
   ==========================================================================
   ⚠ Un MESTIERE per blocco: la fascia AGISCE (chiama, scrivi, vieni), il piè ORIENTA (mappa del sito).
   Ripetere indirizzo e orari a 150px di distanza sullo stesso colore è il difetto. */

/* Gradiente ghiaccio → tint caldo: chiude la pagina sul lato CALDO, che è il lato dell'azione.
   Misurato ai due estremi: inchiostro 15,35/14,82 · tenue 6,79/6,56 · arancione-testo 5,50/5,31. */
.cta-band {
  background: linear-gradient(112deg, var(--surface) 0%, var(--surface) 38%, var(--accent-tint) 100%);
  padding-block: var(--section-y); border-top: 1px solid var(--line);
}
.cta-band__grid { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); gap: clamp(var(--space-6), 4vw, var(--space-8)); align-items: start; }
.cta-band h2 { margin-bottom: var(--space-3); }
.cta-band__lead { color: var(--ink-muted); font-size: var(--text-md); margin-bottom: var(--space-5); }
.facts { display: grid; gap: var(--space-4); margin: 0; }
.facts > div { display: grid; gap: 0.2rem; }
.facts dt { font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--accent-ink); font-weight: 700; }
.facts dd { margin: 0; color: var(--ink); }
.facts a { color: var(--brand); font-weight: 600; }
.hours { list-style: none; margin: 0; padding: 0; }
.hours li { display: flex; justify-content: space-between; gap: var(--space-4); padding-block: 0.3rem; border-bottom: 1px dashed var(--line); }
.hours li:last-child { border-bottom: 0; }
.hours span:first-child { color: var(--ink-muted); }
.hours span:last-child { font-weight: 600; }
@media (max-width: 900px) { .cta-band__grid { grid-template-columns: 1fr; } }

.site-footer {
  background:
    radial-gradient(70% 120% at 92% 0%, rgba(248,136,56,.18) 0%, rgba(248,136,56,0) 60%),
    linear-gradient(180deg, var(--brand) 0%, var(--brand-dark) 62%);
  color: var(--on-dark-muted); padding-block: var(--space-8) var(--space-5);
}
.site-footer :focus-visible { outline-color: var(--accent-lt); }
.site-footer__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: var(--space-6); }
.site-footer h3 { font-size: 0.76rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent-lt); margin: 0 0 var(--space-3); font-weight: 700; }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.45rem; }
.site-footer a { color: var(--on-dark); text-decoration: none; }
.site-footer a:hover { color: var(--accent-lt); text-decoration: underline; }
.site-footer .wordmark__name { color: var(--on-dark); }
.site-footer .wordmark__tag { color: var(--accent-lt); }
.site-footer__about { font-size: var(--text-sm); margin-top: var(--space-3); color: var(--on-dark-muted); }
/* ⚠ Gli orari nel piè stanno in una colonna STRETTA: la riga «giorni | fasce» di `.hours` ci si spezza e
   le due parti si accavallano. Nel piè si impilano — etichetta sopra, fasce sotto — invece di forzare una
   riga che non c'entra nella colonna. */
.site-footer .hours li { display: block; border-bottom-color: rgba(255,255,255,.16); font-size: var(--text-sm); }
.site-footer .hours span:first-child { display: block; color: var(--accent-lt); font-weight: 600; }
.site-footer .hours span:last-child { display: block; color: var(--on-dark); font-weight: 400; }
/* ⚠ Tre elementi in `space-between` NON centrano il mediano: serve una griglia 1fr auto 1fr, che tiene
   «Powered by Dgitaly» al centro esatto qualunque sia la lunghezza dei due lati. */
.site-footer__bar {
  margin-top: var(--space-7); padding-top: var(--space-4);
  border-top: 1px solid rgba(255,255,255,.16);
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--space-4);
  font-size: var(--text-sm);
}
.site-footer__bar > :last-child { justify-self: end; }
.site-footer__bar .powered { justify-self: center; }
@media (max-width: 700px) {
  .site-footer__bar { grid-template-columns: 1fr; justify-items: center; text-align: center; }
  .site-footer__bar > :last-child, .site-footer__bar .powered { justify-self: center; }
}
/* Regola 1: «Powered by Dgitaly» in ogni sito reale. Il marchio è un badge QUADRATO senza scritta: il
   testo è nostro e il logo non si deforma. */
.powered { display: inline-flex; align-items: center; gap: 0.4rem; color: var(--on-dark-muted); text-decoration: none; }
.powered img { inline-size: 20px; block-size: 20px; }
.powered:hover { color: var(--on-dark); }
@media (max-width: 900px) { .site-footer__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .site-footer__grid { grid-template-columns: 1fr; } }

/* --- Lightbox ---
   ⚠⚠ A RIPOSO l'overlay deve essere NASCOSTO e non intercettare nulla: senza `display:none` resta nel
   flusso, e poiché il micro-JS spegne lo scroll all'apertura la pagina si blocca senza via d'uscita.
   È il difetto che su un altro sito l'ha trovato il cliente, e qui si è ripetuto. */
.fp-lb { display: none; }
.fp-lb.is-open {
  display: grid; place-items: center;
  position: fixed; inset: 0; z-index: 200;
  background: rgba(7,23,38,.92);
  padding: clamp(1rem, 4vw, 3rem);
}
.fp-lb__img {
  max-inline-size: min(96vw, 1400px); max-block-size: 88vh;
  inline-size: auto; block-size: auto;
  border-radius: var(--radius); box-shadow: 0 24px 60px rgba(0,0,0,.5);
}
.fp-lb__x {
  position: absolute; inset-block-start: clamp(.75rem, 2vw, 1.5rem); inset-inline-end: clamp(.75rem, 2vw, 1.5rem);
  inline-size: 2.75rem; block-size: 2.75rem;
  display: grid; place-items: center;
  font-size: 1.6rem; line-height: 1;
  color: var(--ink); background: var(--paper);
  border: 0; border-radius: 50%; cursor: pointer;
}
.fp-lb__x:hover { background: var(--accent); }
.fp-lb__nav {
  position: absolute; inset-block-start: 50%; transform: translateY(-50%);
  inline-size: 3rem; block-size: 3rem;
  display: grid; place-items: center;
  color: var(--ink); background: var(--paper);
  border: 0; border-radius: 50%; cursor: pointer;
}
.fp-lb__nav svg { inline-size: 1.4rem; block-size: 1.4rem; }
.fp-lb__nav:hover { background: var(--accent); }
.fp-lb__prev { inset-inline-start: clamp(.5rem, 2vw, 1.5rem); }
.fp-lb__next { inset-inline-end: clamp(.5rem, 2vw, 1.5rem); }
.fp-lb :focus-visible { outline: 3px solid var(--accent-lt); outline-offset: 3px; }

/* ==========================================================================
   9. Barra CTA fissa mobile
   ========================================================================== */

.cta-bar {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 90;
  display: none;
  background: var(--paper);
  border-top: 1px solid var(--line);
  box-shadow: 0 -6px 20px rgba(16,32,47,.10);
  padding: var(--space-3) var(--gutter);
  padding-bottom: max(var(--space-3), env(safe-area-inset-bottom));
}
.cta-bar__row { display: flex; gap: var(--space-3); }
.cta-bar .btn { flex: 1 1 0; }
/* ⚠ In mobile la barra istituzionale andava a capo su tre righe: orari ed e-mail spariscono e resta la
   sola via, che è l'informazione che serve a chi cerca il negozio dal telefono. */
@media (max-width: 780px) {
  .topbar__hours, .topbar__spacer { display: none; }
  .topbar__row { padding-block: 0.4rem; }
  .topbar__item { font-size: 0.8rem; }
  .cta-bar { display: block; }
  body { padding-bottom: 5.5rem; }
  /* ⚠⚠ Le media query NON aggiungono specificità: `.btn{display:inline-flex}` dichiarata DOPO batterebbe
     una `.site-header__cta{display:none}` a pari specificità. Due classi, e la regola sta QUI in fondo. */
  .site-header .site-header__cta { display: none; }
}

/* --- Bolla WhatsApp flottante ---
   ⚠ È un LINK `wa.me`, non il widget ufficiale: quello caricherebbe JS di terzi e violerebbe lo
   zero-live. Sta sopra la barra CTA mobile e non le finisce sotto. */
.wa-float {
  position: fixed; z-index: 95;
  inset-inline-end: clamp(1rem, 2.5vw, 2rem);
  inset-block-end: clamp(1rem, 2.5vw, 2rem);
  inline-size: 3.5rem; block-size: 3.5rem;
  display: grid; place-items: center;
  border-radius: 50%;
  background: #1FA855;                     /* verde WhatsApp: marchio di terzi, non un token nostro */
  box-shadow: 0 6px 16px rgba(16,32,47,.22), 0 2px 6px rgba(16,32,47,.14);
  transition: transform .18s ease, box-shadow .18s ease;
}
.wa-float:hover { transform: translateY(-2px) scale(1.04); box-shadow: 0 10px 24px rgba(16,32,47,.28); }
.wa-float:focus-visible { outline: 3px solid var(--brand); outline-offset: 3px; }
.wa-float__ico {
  inline-size: 2rem; block-size: 2rem; background: #FFFFFF;
  -webkit-mask: url("../assets/img/icons/whatsapp.svg") center / contain no-repeat;
  mask: url("../assets/img/icons/whatsapp.svg") center / contain no-repeat;
}
@media (prefers-reduced-motion: reduce) { .wa-float, .wa-float:hover { transition: none; transform: none; } }
@media (max-width: 780px) { .wa-float { inset-block-end: 5.5rem; } }

/* --- Pagina di reparto: due colonne ---
   ⚠⚠ Una colonna di prosa da 68ch dentro un container da 1280px lascia METÀ PAGINA vuota a destra: era
   l'accusa «si crea quello spazio a destra che non ha senso». La prosa e la colonna di servizio stanno
   affiancate, così la larghezza è occupata da contenuto e non da nulla. */
.rep-cols {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: clamp(var(--space-6), 4vw, var(--space-8));
  align-items: start;
}
.rep-cols .prose { max-width: none; }
.rep-aside {
  background: linear-gradient(168deg, var(--surface) 0%, var(--accent-tint) 100%);
  border-radius: var(--radius); padding: var(--space-6);
  border-top: 4px solid var(--accent);
  position: sticky; top: calc(var(--space-8) + 2.5rem);
}
.rep-aside h2 { font-size: var(--text-lg); margin-bottom: var(--space-4); }
.rep-aside .btn { inline-size: 100%; }
@media (max-width: 980px) { .rep-cols { grid-template-columns: 1fr; } .rep-aside { position: static; } }

/* --- FAQ ---
   ⚠ `<details>` NATIVO: nessun JavaScript, che la CSP vieta inline e che qui non serve. */
.faq { display: grid; gap: var(--space-3); max-width: 62rem; }
.faq__q {
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--space-4) var(--space-5);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.faq__q[open] { border-color: var(--accent); box-shadow: var(--shadow-sm); }
.faq__q summary {
  cursor: pointer; font-family: var(--font-display); font-weight: 700; font-size: var(--text-md);
  color: var(--ink); list-style: none; display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
}
.faq__q summary::-webkit-details-marker { display: none; }
.faq__q summary::after {
  content: ""; inline-size: 1.1rem; block-size: 1.1rem; flex: none;
  background: var(--accent-ink);
  -webkit-mask: url("../assets/img/icons/idraulico.svg") center / contain no-repeat;
  mask: url("../assets/img/icons/idraulico.svg") center / contain no-repeat;
  transition: transform .2s ease;
}
.faq__q[open] summary::after { transform: rotate(45deg); }
.faq__q p { margin: var(--space-3) 0 0; color: var(--ink-muted); }
.faq__q:focus-within { outline: none; }
.faq__q summary:focus-visible { outline: 3px solid var(--brand); outline-offset: 3px; border-radius: 4px; }
@media (prefers-reduced-motion: reduce) { .faq__q, .faq__q summary::after { transition: none; } }

/* ==========================================================================
   10. Testate di pagina e pagine interne
   ========================================================================== */

/* ⚠ La `.page-head` NON riusa la size dell'hero (--text-3xl): è una testata di pagina, non un hero, e col
   gradino dell'hero «occupa mezza schermata». È CONDIVISA da tutte le pagine interne: si sistema una volta. */
.page-head {
  background:
    radial-gradient(70% 90% at 96% 0%, rgba(248,136,56,.13) 0%, rgba(248,136,56,0) 62%),
    linear-gradient(172deg, var(--surface-2) 0%, var(--surface) 62%, var(--paper) 100%); padding-block: clamp(2rem, 1.2rem + 3vw, 3.5rem); border-bottom: 1px solid var(--line); }
.page-head h1 { font-size: var(--text-2xl); margin-bottom: var(--space-3); }
.page-head .lead { color: var(--ink-muted); font-size: var(--text-md); max-width: 62ch; margin: 0; }

/* Pagina Prodotti: hub dei reparti. Le tessere linkano DIRITTO al reparto (regola 12), mai a un hub
   intermedio identico — l'utente crederebbe che il click non abbia funzionato. */
.hub { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)); gap: var(--space-4); }

/* Pagina Contatti: due colonne, modulo a sinistra e recapiti a destra (regola 19). */
.contact-cols { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(var(--space-6), 4vw, var(--space-8)); align-items: start; }
.contact-form { display: grid; gap: var(--space-4); }
.field { display: grid; gap: 0.35rem; }
.field label { font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; color: var(--ink-muted); }
/* ⚠ Il bordo di un campo DEVE vedersi: --line fa 1,3 su bianco, sotto il 3,0 di WCAG 1.4.11.
   Qui si usa --line-strong (3,51). */
.field input, .field textarea {
  font: inherit; color: var(--ink);
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--paper);
}
.field input:focus-visible, .field textarea:focus-visible { border-color: var(--brand); }
.row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
/* ⚠ `.consent` è un flex: se il testo contiene un `<a>` si spezzerebbe in più flex-item — TUTTO il testo,
   link incluso, va in un solo `<span>`. */
.consent { display: flex; align-items: flex-start; gap: var(--space-3); font-size: var(--text-sm); color: var(--ink-muted); }
.consent input { margin-top: 0.25rem; flex: none; }
.contact-info { background: linear-gradient(168deg, var(--surface) 0%, var(--surface-2) 100%); border-radius: var(--radius); padding: var(--space-6); }
.contact-info h2 { font-size: var(--text-lg); margin-bottom: var(--space-4); }
@media (max-width: 900px) { .contact-cols { grid-template-columns: 1fr; } .row { grid-template-columns: 1fr; } }

/* Pagina Privacy e testi legali. */
.legal { padding-block: var(--section-y); }
.legal h2 { font-size: var(--text-lg); margin-top: var(--space-6); }
.legal h2:first-child { margin-top: 0; }
.legal ul { color: var(--ink-muted); padding-left: 1.2rem; }

/* 404 */
.notfound { padding-block: var(--space-10); text-align: center; }
.notfound .btn-row { justify-content: center; }
