/* =============================================================================
   Ho.Bag — style.css — foglio di stile unico del bundle statico
   -----------------------------------------------------------------------------
   Ordine delle sezioni
     01. @font-face Montserrat (self-hosted, nessun CDN)
     02. Token di design (:root) + temi di area
     03. Reset e base
     04. Layout: container, band, section head, prose
     05. Bottoni, link, icone, chip
     06. Header: barra superiore, nav a pillola, mega menu, burger, lingua, ricerca
     07. Breadcrumb
     08. Hero
     09. Media + testo, feature
     10. Griglie e card
     11. Punti, checklist
     12. Catalogo: filtri, griglia prodotti, contatore, stato vuoto
     13. Scheda prodotto: galleria, tab, tabella specifiche
     14. FAQ
     15. CTA band
     16. News / blog / paginazione
     17. Form, newsletter, contatti, sedi, mappa
     18. Footer
     19. Consent banner
     19b. Banner pop-up (public.banners)
     20. Pagine speciali: policy, ricerca, 404
     21. Responsive (1440 / 1280 / 1024 / 767) + guardie anti-overflow
     22. Stampa
     23. prefers-reduced-motion
   Convenzioni
     - percorsi relativi al file (assets/css/ -> ../fonts/, ../img/): mai root-absolute
     - stati applicati da static/js/main.js: .is-open, .is-active, [aria-expanded],
       [aria-selected], [aria-current], [hidden]
     - niente background-image per contenuti editoriali (solo decorazioni)
   ============================================================================= */

/* Montserrat — self-hosted (SIL OFL 1.1), nessun CDN.
   E' il file VARIABILE di Google (asse wght 100-900): un solo woff2 copre tutti i
   pesi che usa il sito (400/500/600/700). Prima ogni peso aveva la sua @font-face
   con un file diverso, ma i file erano lo stesso identico binario: il browser ne
   scaricava quattro copie per pagina. Restano due soli file, uno per subset, e il
   latin-ext si scarica solo se in pagina compaiono i suoi caratteri. */
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/montserrat-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/montserrat-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* =============================================================================
   02. TOKEN DI DESIGN
   ============================================================================= */
:root {
  /* --- colori di marca (Figma 1920) ------------------------------------- */
  --navy: #103B5E;          /* titoli, footer, bottone primario */
  --navy-2: #0C2E4A;        /* navy scurito: hover del pulsante blu e dei link su card */
  --ink: #727272;           /* testo corrente */
  --cipria: #DAC6C5;
  --cipria-2: #C3AEAD;      /* h1 pagine interne, card, bottone rosa */
  --pesca: #DFA494;
  --salvia: #A2A681;
  --beige: #DBC1AE;
  --azzurro: #B0C7D7;
  --grigio-1: #5B5F69;
  --grigio-2: #7D818D;
  --bordeaux: #870D27;      /* cerchio decorativo hero */
  --bg: #FAFAFA;            /* sfondo pagina */
  --white: #fff;

  /* accento di pagina: sovrascritto dalle classi .theme-* su <main> */
  --accent: var(--navy);
  --accent-ink: var(--white);      /* testo sopra --accent */
  /* --accent-strong: variante scurita dell'accento, conforme AA su fondo chiaro.
     NON e' piu' usata dai titoli: il cliente (2026-09-04) ha confermato le tinte piene
     del Figma per H1/H2 (#DBC1AE, #C3AEAD, #A2A681), contrasto 1,5-1,9:1 accettato come
     scelta grafica. Resta definita: basta rimettere var(--accent-strong) su .hero__title
     e .media-text__body h2 per tornare alla versione conforme. */
  --accent-strong: var(--navy);

  /* --- colori derivati (superfici, bordi, stati) ------------------------- */
  --sand: #F8F3EF;          /* #F1D7C5 al 20% su --bg: fascia hero (header compreso) e pannelli */
  /* Fondo delle fasce in tinta: nel Figma e' l'accento della pagina steso su --bg
     (hero al 20%, fascia interna al 10-20%). Il default vale per le pagine senza
     tinta dichiarata; i temi che il Figma definisce lo sovrascrivono piu' sotto. */
  --tint-hero: #F8F3EF;     /* misurato: azienda-chi-siamo.png */
  --tint-band: #F8F3EF;     /* fascia/pannello in tinta: su chi-siamo coincide con l'hero */
  --sand-2: #F4F1F0;        /* fondo dei comandi dell'header: ricerca, hamburger, lingua */
  --sand-3: #F7F5F5;        /* #DAC6C5 al 10% su --bg: fascia card della home */
  /* fondo delle card recapiti e del pannello sedi di /contatti/ (Figma contatti.png:
     cipria #DAC6C5 al 10% su --bg) */
  --tint-contatti: #F7F5F5;
  --surface: var(--white);
  --surface-2: #F1F2EE;     /* box immagine prodotto, mappa statica */
  --line: #E7E3E0;          /* bordi 1px */
  --line-2: #EDEBE9;
  --menu-line: #E0E0E0;     /* stroke della barra del menu e delle tendine */
  --menu-hover: #F5F5F5;    /* riempimento hover delle voci di tendina (Figma) */
  --menu-hover-ink: #988988;
  --field-bg: var(--white);
  --field-line: #E3E1DE;
  --muted: var(--grigio-2);
  --footer-line: rgba(255, 255, 255, .18);
  --footer-ink: rgba(255, 255, 255, .82);
  /* Il Figma usa testo bianco sulle superfici in tinta (cipria, pesca, salvia...):
     contrasto ~2,1:1, sotto la soglia AA, ma e' la scelta grafica confermata dal
     cliente (card della home, bottone della CTA di packaging.png). Per tornare
     conformi: --on-tint: var(--navy). */
  --on-tint: var(--white);

  /* --- tipografia -------------------------------------------------------- */
  --ff: "Montserrat", "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
  --h1: clamp(38px, 3.65vw, 70px);
  /* il Figma usa 70px / interlinea 80px per l'H1 di TUTTE le pagine interne
     (chi-siamo, sostenibilita, produzione, flaconi, prodotto): stessa scala dell'home */
  --h1-inner: clamp(34px, 3.65vw, 70px);
  --h2: clamp(33px, 2.6vw, 50px);
  --h3: clamp(24px, 1.56vw, 30px);
  --h4: clamp(20px, 1.2vw, 23px);
  /* corpo del testo: 20px a 1920 su tutto il sito (regola del cliente, 2026-09-07).
     Alimenta <body>, .prose e ogni paragrafo che non dichiara una misura propria. */
  --body: clamp(16px, 1.04vw, 20px);
  --small: 15px;
  --label: 17px;
  --lh-body: 1.45;
  --lh-head: 1.16;

  /* --- griglia e spaziature ---------------------------------------------- */
  --gutter: 20px;
  --content: 1273px;        /* colonna di contenuto: 12 col + gutter 20 */
  --page-pad: 32px;
  --band-pad: clamp(48px, 4.6vw, 88px);   /* distanza fra fasce nel Figma: ~88px a 1920 */
  --stack: clamp(20px, 2vw, 32px);
  --footer-gap: clamp(12px, 3.6vw, 68px);

  /* --- raggi -------------------------------------------------------------- */
  --r-card: 16px;           /* box NON fotografici: card icona, faq, contatti */
  --r-pill: 999px;
  --r-img: 20px;            /* box delle immagini, ovunque nel sito (Figma) */
  /* la foto dell'hero split fa eccezione: nel Figma ha rectangleCornerRadii
     [42,0,0,42], cioe' 42 sui due angoli di sinistra e vivo a destra, dove esce
     dallo schermo. Misurato sull'arco di flaconi.png: a 3px dal bordo il profilo
     scende di 25, a 8px di 16 — un raggio da 42, non da 20. */
  --r-hero: 42px;
  --r-footer: 70px;
  --r-field: 10px;
  --r-panel: 24px;
  --r-menu: 32px;           /* barra + tendina packaging aperte: un corpo unico */
  --r-chip: 12px;           /* riempimento hover delle sottovoci + angoli bassi delle tendine */

  /* --- ombre --------------------------------------------------------------*/
  --sh-nav: 0 10px 30px rgba(16, 59, 94, .10);
  --sh-card: 0 4px 18px rgba(16, 59, 94, .06);
  --sh-card-hover: 0 12px 30px rgba(16, 59, 94, .12);
  /* ombra GRIGIA: le altre sono velate di navy e sulla foto prodotto si leggono
     come un alone azzurro. Richiesta cliente: l'hover dell'immagine e' grigio. */
  --sh-img-hover: 0 12px 30px rgba(114, 114, 114, .18);
  --sh-panel: 0 18px 46px rgba(16, 59, 94, .14);

  /* --- misure componenti --------------------------------------------------*/
  --btn-h: 57px;
  --icon: 24px;
  --focus: 3px;
  /* fuori da <main> (header, footer) non c'e' una .theme-*: vale la sabbia */
  --accent-soft: var(--sand);
}

/* --- temi di area: build.py stampa .theme-<x> su <main> ---------------------
   --accent-soft: la tinta della sezione al 20%, per le superfici tenui che devono
   seguire l'area (l'etichetta sopra il nome del prodotto). Su --bg #FAFAFA il
   cipria appiattisce a #F4F0EF, lo stesso valore misurato sui frame packaging. */
.theme-navy    { --accent: var(--navy);     --accent-ink: var(--white);    --accent-strong: var(--navy); --accent-soft: rgba(16, 59, 94, .2); }
.theme-cipria  { --accent: var(--cipria-2); --accent-ink: var(--on-tint);  --accent-strong: #756867; --accent-soft: rgba(218, 198, 197, .2); }  /* 4,72:1 su hero chiaro */
.theme-pesca   { --accent: var(--pesca);    --accent-ink: var(--on-tint);  --accent-strong: #856258; --accent-soft: rgba(223, 164, 148, .2); }  /* 4,78:1 */
.theme-salvia  { --accent: var(--salvia);   --accent-ink: var(--on-tint);  --accent-strong: #61634D; --accent-soft: rgba(162, 166, 129, .2); }  /* 5,46:1 */
.theme-azzurro { --accent: var(--azzurro);  --accent-ink: var(--on-tint);  --accent-strong: #697781; --accent-soft: rgba(176, 199, 215, .2); }  /* 4,07:1 */
.theme-beige   { --accent: var(--beige);   --accent-ink: var(--on-tint);  --accent-strong: #76685E; --accent-soft: rgba(219, 193, 174, .2); }  /* #DBC1AE */

/* Tinte di pagina misurate sui PNG del Figma: salvia (azienda-sostenibilita.png:
   hero #E8E9E2 = salvia 20%, fascia #F1F2EE = salvia 10%) e cipria (packaging.png,
   flaconi.png: #F4F0EF = cipria 20%). Stanno sul <body> perche' la tinta serve anche
   all'header, che vive fuori da <main> dove sta la classe .theme-*. */
body:has(main.theme-salvia) { --tint-hero: #E8E9E2; --tint-band: #F1F2EE; }
/* #F4F0EF = --cipria #DAC6C5 al 20% su --bg #FAFAFA (verificato pixel per pixel
   su flaconi-in-vetro.png, flaconi.png, packaging.png, vasi.png: sfondo #F4F0EF) */
body:has(main.theme-cipria) { --tint-hero: #F4F0EF; --tint-band: #F4F0EF; }

/* =============================================================================
   03. RESET E BASE
   ============================================================================= */
*, *::before, *::after { box-sizing: border-box; }

html {
  overflow-x: clip;                 /* guardia: nessuno scroll orizzontale */
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  overflow-x: clip;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--ff);
  font-size: var(--body);
  font-weight: 400;
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0 0 .5em;
  color: var(--navy);
  font-family: var(--ff);
  font-weight: 700;
  line-height: var(--lh-head);
  letter-spacing: -.01em;
  text-wrap: balance;
}
h1 { font-size: var(--h1-inner); }
h2 { font-size: var(--h2); }
h3 { font-size: var(--h3); }
h4 { font-size: var(--h4); }
h5, h6 { font-size: var(--label); }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--navy); text-decoration: none; }
a:hover { text-decoration: underline; }

ul, ol { margin: 0 0 1em; padding-left: 1.25em; }
li { margin-bottom: .35em; }

strong, b { font-weight: 700; }
small { font-size: var(--small); }

img, svg, video, canvas { max-width: 100%; height: auto; display: block; }

figure { margin: 0; }
dl, dd { margin: 0; }
address { font-style: normal; }

button, input, select, textarea { font: inherit; color: inherit; margin: 0; }
button { cursor: pointer; background: none; border: 0; padding: 0; }

table { border-collapse: collapse; width: 100%; }

hr { border: 0; border-top: 1px solid var(--line); margin: var(--stack) 0; }

[hidden] { display: none !important; }

/* --- utilita ---------------------------------------------------------------*/
.sr-only,
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100px; left: var(--page-pad);
  z-index: 200;
  padding: 12px 22px;
  background: var(--navy);
  color: var(--white);
  border-radius: 0 0 12px 12px;
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { top: 0; }

:focus-visible {
  outline: var(--focus) solid var(--navy);
  outline-offset: 2px;
  border-radius: 4px;
}
.site-footer :focus-visible,
.hero--full :focus-visible { outline-color: var(--white); }

::selection { background: var(--cipria); color: var(--navy); }

.muted { color: var(--muted); }
.text-center { text-align: center; }

/* =============================================================================
   04. LAYOUT: container, band, section head, prose
   ============================================================================= */
.container {
  width: 100%;
  max-width: calc(var(--content) + 2 * var(--page-pad));
  margin-inline: auto;
  padding-inline: var(--page-pad);
}

/* ogni fascia editoriale e' <section class="band band--<tipo>"> figlia di <main> */
.band {
  position: relative;
  padding-block: var(--band-pad);
}
.band + .band { padding-top: 0; }        /* nessuna doppia spaziatura fra fasce */
/* ...tranne le fasce con fondo proprio: li' la spaziatura sta DENTRO al colore e serve
   tutta, sopra e sotto (senza questa regola .band + .band gliela azzerava). */
.band + .band.band--tinted { padding-top: var(--band-pad); }
.page--home .band + .band.cards-band--cipria { padding-top: var(--band-pad); }
.band--hero + .band,
.band--tinted + .band,
.page--home .cards-band--cipria + .band { padding-top: var(--band-pad); }
.band > .container > :last-child { margin-bottom: 0; }

/* fasce con fondo proprio: spaziatura piena sopra e sotto */
.band.band--tinted,
.page--home .band.cards-band--cipria { padding-block: var(--band-pad); }

/* il fondo in tinta della fascia cipria e lo sfalsamento delle tile sono della home
   (Figma homepage.png): su flaconi.png la stessa fascia sta su --bg, tile allineate */
.page--home .cards-band--cipria { background: var(--sand-3); }
.band--tinted { background: var(--tint-band); }
/* Pagine categoria: la tinta non attacca sotto i "plus", li scavalca.
   Misurato su sources/figma/vasi.png a 1920: le card in basso stanno a 1410-1738 e
   la fascia in tinta comincia a 1672, cioe' 66px PRIMA che le card finiscano — il
   loro bordo basso poggia gia' sul colore. Da noi partiva 89px dopo.
   La risalita e' quindi il vuoto fra le card e la fascia (--band-pad) piu' quei 66.
   Il padding NON la compensa tutta: nel frame l'h2 sta 97px sotto il fondo delle
   card (1835 contro 1738), mentre compensandola per intero finirebbe a 184. Con
   --band-pad + --tint-overlap l'intestazione cade dove la vuole il Figma.
   La regola va scritta con due classi per lato: `.band + .band.band--tinted` piu'
   in alto ha tre classi e vincerebbe sul padding, lasciando risalire il contenuto
   insieme alla fascia (era il difetto del primo tentativo).
   z-index sulle card: la fascia viene dopo nel DOM, senza questo il suo fondo
   coprirebbe i 66px di card invece di passarci sotto. */
.cards-band--icon { z-index: 1; }
.band.cards-band--icon + .band.band--tinted {
  --tint-overlap: clamp(28px, 3.44vw, 66px);
  margin-top: calc(-1 * (var(--band-pad) + var(--tint-overlap)));
  padding-top: calc(var(--band-pad) + var(--tint-overlap));
}

.section__head {
  max-width: 900px;
  margin-bottom: clamp(28px, 3vw, 48px);
}
/* fasce a card: la testata usa tutta la colonna, cosi il titolo resta su una riga
   ("Soluzioni di packaging per ogni applicazione" e' largo 1170px nel Figma) e
   anche l'introduzione arriva al bordo destro (nel Figma la prima riga e' 1252px,
   contro i 68ch = ~610px del limite di lettura della prosa). */
.cards-band .section__head:not(.section__head--center) { max-width: none; }
.cards-band .section__head:not(.section__head--center) .prose { max-width: none; }
.section__head > :last-child { margin-bottom: 0; }
.section__head--center {
  max-width: 860px;
  margin-inline: auto;
  text-align: center;
}
.section__head--center .prose { margin-inline: auto; }

.band__sub {
  margin-bottom: 1em;
  color: var(--grigio-1);
  font-size: var(--label);
  font-weight: 500;
}
.band__cta { margin: clamp(24px, 3vw, 40px) 0 0; }
.band__figure {
  margin-bottom: clamp(28px, 3.4vw, 56px);
  border-radius: var(--r-img);
  overflow: hidden;
}
.band__figure img { width: 100%; aspect-ratio: 1273 / 545; object-fit: cover; }

/* prosa multi-paragrafo: un solo contenitore per fascia (regola R4) */
.prose {
  max-width: 68ch;
  color: var(--ink);
  font-size: var(--body);
  line-height: var(--lh-body);
}
.prose > :last-child { margin-bottom: 0; }
.prose ul, .prose ol { margin-bottom: 1em; padding-left: 1.15em; }
.prose li::marker { color: var(--accent); }
.prose a { color: var(--navy); text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { color: var(--accent); }
.prose h3, .prose h4 { margin-top: 1.4em; }
.prose--wide { max-width: none; }

/* =============================================================================
   05. BOTTONI, LINK, ICONE, CHIP
   ============================================================================= */
/* pillola h57 con freccia cerchiata (macro btn di macros/ui.html.j2:
   <a class="btn btn--blu"><span class="btn__label">..</span><span class="btn__icon">..</span></a>) */
.btn {
  --btn-bg: var(--navy);
  --btn-fg: var(--white);
  --btn-ring: rgba(255, 255, 255, .30);
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-height: var(--btn-h);
  max-width: 100%;
  padding: 10px 10px 10px 30px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: 20px;                    /* etichetta dei pulsanti (Figma) */
  font-weight: 600;
  line-height: 1.2;
  text-align: left;
  text-decoration: none;
  transition: background-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.prose a.btn,
.prose a.link,
.site-footer a.btn:hover,
.site-footer a.link:hover,
.btn:focus-visible { text-decoration: none; }
.btn:hover {
  color: var(--btn-fg);
  text-decoration: none;
  box-shadow: var(--sh-card-hover);
  transform: translateY(-1px);
}
.btn:active { transform: translateY(0); }
.btn__label { display: inline-block; }
.btn__label:only-child { padding-right: 20px; }   /* bottone senza freccia */

/* l'icona arrow-circle porta gia' il proprio cerchio: niente doppio anello */
.btn__icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 37px;
  height: 37px;
  border-radius: var(--r-pill);
  color: inherit;
}
.btn__icon .icon { width: 28px; height: 28px; }
.btn__icon--ring { border: 1.5px solid var(--btn-ring); }

.btn--blu,
.btn--primary { --btn-bg: var(--navy);     --btn-fg: var(--white); }
.btn--blu:hover,
.btn--primary:hover { --btn-bg: var(--navy-2); }
.btn--rosa    { --btn-tint: var(--cipria-2); }
.btn--cipria  { --btn-tint: var(--cipria);   }
.btn--pesca   { --btn-tint: var(--pesca);    }
.btn--azzurro { --btn-tint: var(--azzurro);  }
.btn--salvia  { --btn-tint: var(--salvia);   }
.btn--accent  { --btn-tint: var(--accent);   }
/* riposo: pieno nella tinta e scritta bianca, come nel Figma (decisione cliente 04/09/2026) */
.btn--rosa,
.btn--cipria,
.btn--pesca,
.btn--azzurro,
.btn--salvia,
.btn--accent  { --btn-bg: var(--btn-tint); --btn-fg: var(--white); --btn-ring: rgba(255, 255, 255, .35); }
/* hover: il pieno si svuota — fondo bianco, bordo e testo nella tinta, senza ombra */
.btn--rosa:hover,
.btn--cipria:hover,
.btn--pesca:hover,
.btn--azzurro:hover,
.btn--salvia:hover,
.btn--accent:hover {
  --btn-bg: var(--white);
  --btn-fg: var(--btn-tint);
  --btn-ring: var(--btn-tint);
  box-shadow: inset 0 0 0 2px var(--btn-tint);
}
.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--navy);
  --btn-ring: rgba(16, 59, 94, .35);
  box-shadow: inset 0 0 0 1.5px var(--navy);
}
.btn--ghost:hover { --btn-bg: var(--navy); --btn-fg: var(--white); }
.btn--white { --btn-bg: var(--white); --btn-fg: var(--navy); --btn-ring: rgba(16, 59, 94, .35); }
/* hover: il bianco si riempie di navy, come .btn--ghost. Era l'unica variante senza
   stato hover: restava il solo sollevamento di 1px di .btn, quindi i "Scopri di piu'"
   bianchi sulle foto delle categorie sembravano spenti accanto agli altri pulsanti.
   Il Figma non ha frame di hover: qui si segue la convenzione del foglio di stile
   (blu si scurisce, tinte si svuotano, vuoti si riempiono). */
.btn--white:hover { --btn-bg: var(--navy); --btn-fg: var(--white); --btn-ring: rgba(255, 255, 255, .35); }
/* la freccia cerchiata del pulsante bianco e' rosa pesca #DFA494, misurata sul
   "Scopri di piu'" di flaconi.png; in hover, che riempie di navy, torna bianca */
.btn--white .btn__icon { color: var(--pesca); }
.btn--white:hover .btn__icon { color: inherit; }
.btn--sm { min-height: 46px; padding-left: 24px; font-size: var(--small); }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .55; pointer-events: none; }

/* link testuale con sottolineatura animata */
/* pulsante testuale ("Scopri di piu'"): nessuna sottolineatura, ne' ferma ne' in
   hover (richiesta cliente). Il ritorno visivo e' lo schiarimento del testo. */
.link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--navy);
  font-size: var(--small);
  font-weight: 600;
  text-decoration: none;
  transition: opacity .18s ease, color .18s ease;
}
.link:hover,
a:hover > .link,
.card:hover .link { opacity: .72; text-decoration: none; }
/* freccia del Figma dopo l'etichetta: la disegna una maschera, cosi prende il
   colore del testo (navy, accento o bianco sulle card in tinta). Con @supports
   perche' senza mask-image resterebbe un quadratino pieno. */
@supports ((-webkit-mask-image: url("../icons/arrow-right.svg")) or (mask-image: url("../icons/arrow-right.svg"))) {
  .link::after {
    content: "";
    flex: none;
    width: 1.05em;
    height: 1.05em;
    background: currentColor;
    -webkit-mask: url("../icons/arrow-right.svg") no-repeat center / contain;
    mask: url("../icons/arrow-right.svg") no-repeat center / contain;
    transition: transform .18s ease;
  }
  .link:hover::after,
  a:hover > .link::after,
  .card:hover .link::after { transform: translateX(3px); }
  /* link di servizio del footer: resta un link di testo, senza freccia */
  .site-footer__consent::after { content: none; }
}
.link--accent { color: var(--accent); }
.link--white { color: var(--white); }
.link-list { margin: 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 12px 28px; }
.link-list li { margin: 0; }
.link-list a { color: var(--navy); font-weight: 600; }

/* icona SVG inline: <span class="icon icon--<nome>"><svg></span> */
.icon {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: var(--icon);
  height: var(--icon);
  color: currentColor;
  line-height: 0;
}
.icon svg { width: 100%; height: 100%; display: block; fill: currentColor; }
/* le icone di categoria non sono quadre (Figma: flaconi 21x45, vasi 33x25,
   pilloliere 19x31, airless 18x40, foamer 19x46): stanno alla misura nativa e
   rimpiccioliscono in proporzione solo se il box non le contiene, mai stirate.
   Stessa regola per le icone dei contatti (export cliente MEDIA/icone: indirizzo
   35x39, telefono 37x42, fax 46x42, mail 50x40; le varianti -form sono 26x26 con
   la spaziatura ottica gia' dentro il box) */
.icon--cat-flacone svg,
.icon--cat-vaso svg,
.icon--cat-pilloliera svg,
.icon--cat-airless svg,
.icon--cat-foamer svg,
.icon--pin svg,
.icon--phone svg,
.icon--fax svg,
.icon--mail svg,
.icon--user svg,
.icon--briefcase svg,
.icon--mail-form svg,
.icon--phone-form svg { width: auto; height: auto; max-width: 100%; max-height: 100%; }
.icon--logo-hobag,
.icon--logo-hobag-white { width: 148px; height: 46px; }
.icon--logo-mark { width: 30px; height: 44px; }
.icon--flag-it, .icon--flag-en { width: 22px; height: 16px; }
.icon--instagram, .icon--linkedin, .icon--facebook { width: 19px; height: 19px; }
.icon--chevron-down { width: 12px; height: 12px; }   /* Figma: freccia larga 12px */
.icon--search { width: 21px; height: 21px; }
.icon--menu, .icon--close { width: 22px; height: 22px; }
.icon--arrow-circle { width: 28px; height: 28px; }
.icon--check { width: 18px; height: 18px; }

/* chip: filtri blog, etichette tassonomia */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 18px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--sand-2);
  color: var(--grigio-1);
  font-size: var(--small);
  font-weight: 500;
  text-decoration: none;
  transition: background-color .18s ease, color .18s ease;
}
.chip:hover { background: var(--cipria); color: var(--navy); text-decoration: none; }
.chip[aria-current="true"],
.chip.is-active { background: #E4EBF0; color: var(--navy); font-weight: 600; }
/* Etichetta sopra il nome del prodotto: fondo e testo seguono la sezione, non un
   rosa fisso. Le schede packaging sono .theme-cipria (fondo #DAC6C5 al 20%, testo
   #C3AEAD), quelle accessori .theme-beige (#DBC1AE al 20% e #DBC1AE). */
.chip--tint { background: var(--accent-soft); color: var(--accent); }
.chip--tint:hover { background: var(--accent); color: var(--navy); }

/* =============================================================================
   06. HEADER
   Struttura (partials/_header.html.j2):
   header.site-header
     .site-header__top   > .container.site-header__top-inner   [logo, lang-switch]
     .site-header__bar   > .container.site-header__bar-inner   [mark, burger,
                            nav.site-nav > ul.nav-tree, form.site-search]
   Il pannello .mega e' figlio del <li> e viene aperto/chiuso da main.js
   togliendo/mettendo l'attributo hidden (nessuno stato solo-CSS).
   ============================================================================= */
/* Nessun fondo proprio: l'unica cosa opaca dell'header e' la pillola del menu, tutto
   il resto lascia vedere la pagina. Sulla home spariva cosi' la striscia bianca dietro
   al logo, che nel frame non c'e' (homepage.png in cima e' --bg #FAFAFA).

   Allo scroll resta su solo la pillola: logo e bandiere scorrono via insieme.
   NON si ottiene rendendo sticky la sola .site-header__bar — un elemento sticky non
   esce mai dal box del genitore, e l'header e' alto ~155px, quindi la pillola si
   sgancerebbe dopo un dito di scroll. Si tiene sticky l'header intero e lo si incolla
   a un top NEGATIVO: la striscia esce dallo schermo e in cima resta la riga della
   pillola. La misura si ferma alla BASE DEL LOGO, non al fondo della striscia: cosi'
   quello che resta visibile sopra la pillola e' esattamente il padding basso della
   striscia (8px, 6 sotto i 1024), che diventa lo stacco dal bordo. Un valore piu'
   grande lascerebbe spuntare l'ultima fetta del logo. */
.site-header {
  --header-logo-h: 62px;     /* 16 di padding alto + 46 di logo */
  position: sticky;
  top: calc(-1 * var(--header-logo-h));
  z-index: 60;
  background: none;
}

/* --- barra superiore: logo centrato, bandiere a destra ---------------------
   Il padding BASSO e' anche lo stacco della pillola dal bordo alto quando si scrolla:
   l'header si incolla alla base del logo, quindi quello che resta visibile sopra la
   pillola e' esattamente questo. Era 8, il frame ne ha 34 fra base del logo e pillola. */
.site-header__top { padding-block: 16px 20px; }
.site-header__top-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
}
.site-header__logo {
  grid-column: 2;
  justify-self: center;
  display: inline-flex;
  color: var(--navy);
}
/* marchio raster: si fissa l'altezza (la stessa dell'SVG che sostituisce) e si
   lascia libera la larghezza, cosi il rapporto nativo 181x72 resta intatto. */
.site-header__logo-img {
  display: block;
  width: auto;
  height: 46px;
}
.site-header__logo:hover { text-decoration: none; }
.lang-switch { grid-column: 3; justify-self: end; }
.lang-switch__list {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.lang-switch__item { margin: 0; }
.lang-switch__link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 5px;
  border-radius: 6px;
  color: var(--grigio-1);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
}
.lang-switch__link:hover { background: var(--sand-2); text-decoration: none; }
.lang-switch__link.is-current { color: var(--navy); background: var(--sand-2); }
.lang-switch__link.is-disabled { opacity: .45; cursor: not-allowed; }
.lang-switch__code { line-height: 1; }

/* --- barra di navigazione: pillola bianca con ombra ------------------------ */
.site-header__bar { position: relative; }
.site-header__bar-inner {
  position: relative;                 /* ancora del mega menu e del pannello */
  display: flex;
  align-items: center;
  gap: clamp(8px, 1.2vw, 20px);
  /* Larghezza: la griglia del sito e basta, a ogni risoluzione. Nel frame la pillola
     misura 1289-1295 contro i 1273 della colonna di contenuto, cioe' sporge di ~11px
     per lato: il cliente la vuole allineata, quindi --content senza aggiunte. Sotto i
     ~1340 di finestra il tetto non morde e pillola e contenuto coincidono comunque,
     perche' partono dallo stesso calc(100% - 2 * --page-pad).
     Altezza: 85 e non i 100 del Figma — 15px tolti su richiesta del cliente.
     --pill-h la dichiara una volta sola perche' ci si misura anche la sporgenza. */
  --pill-h: 85px;
  /* --pill-pad: il padding orizzontale, dichiarato una volta perche' ci si allinea
     anche la tendina della ricerca (a filo della lente); sotto i 1280 passa a 16 */
  --pill-pad: clamp(20px, 2.5vw, 48px);
  width: calc(100% - 2 * var(--page-pad));
  max-width: var(--content);
  min-height: var(--pill-h);
  margin-bottom: -26px;               /* la pillola scavalca la fascia sotto */
  padding: 6px var(--pill-pad);
  border: 2px solid var(--menu-line); /* Figma: stroke 2px #E0E0E0, nessuna ombra */
  border-radius: var(--r-pill);
  background: var(--white);
}
/* Home: la foto dell'hero parte a META' della pillola. Misurato su homepage.png —
   pillola y 137-234, bordo alto della foto y 186, cioe' 49 su 97. Sulle pagine interne
   non c'e' sovrapposizione (la pillola galleggia sulla tinta dell'hero, che le passa
   dietro), per questo la sporgenza piena sta solo qui e non sulla regola di sopra. */
.page--home .site-header__bar-inner { margin-bottom: calc(var(--pill-h) / -2); }

.site-header__mark {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Figma: il pittogramma poggia sul bianco della barra, senza pastiglia dietro */
  height: 44px;
  color: var(--navy);
}
.site-header__mark:hover { text-decoration: none; }

/* nav e voci alte quanto la barra: cosi la tendina compatta si aggancia al
   bordo inferiore della barra e non a meta' della voce */
.site-nav {
  flex: 1 1 auto;
  min-width: 0;
  align-self: stretch;
  display: flex;
  align-items: stretch;
}
.nav-tree {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  justify-content: center;            /* Figma: il gruppo e' centrato fra pittogramma e lente */
  gap: clamp(4px, 1.5vw, 28px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.nav-tree > li { margin: 0; }
/* Seconda lingua: le voci inglesi sono piu' lunghe (Accessories, Services) e a 1920 il menu
   andava a capo per 6 px. Si riduce solo lo spazio fra le voci, solo in inglese e solo col
   menu orizzontale (sotto i 1024 px la tendina ha gap 0 e resta com'e'). */
@media (min-width: 1025px) {
  html[lang="en"] .nav-tree { gap: clamp(4px, 1.35vw, 24px); }
}

.nav-item {
  --nav-pad: 14px;                    /* rientro della label: ci si allinea la tendina */
  position: relative;
  display: flex;
  align-items: center;
}
.nav-item.has-mega--wide { position: static; }   /* la tendina larga si ancora alla barra */

/* Figma: dietro la voce non c'e' nessun riquadro, nemmeno a menu aperto.
   L'hover cambia il colore di voce E freccia insieme (restano un blocco solo). */
.nav-item:hover > .nav-item__link,
.nav-item:hover > .nav-item__toggle,
.nav-item:focus-within > .nav-item__link,
.nav-item:focus-within > .nav-item__toggle,
.nav-item.is-open > .nav-item__link,
.nav-item.is-open > .nav-item__toggle,
.nav-item__link[aria-current="page"],
.nav-item:has(> a[aria-current="page"]) > .nav-item__toggle { color: var(--menu-hover-ink); }
.nav-item__link {
  display: inline-flex;
  align-items: center;
  padding: 10px var(--nav-pad);       /* area cliccabile attorno alla label */
  color: var(--navy);
  font-size: 20px;                    /* Figma frame 1920 */
  font-weight: 600;
  white-space: nowrap;
}
.nav-item__link { transition: color .18s ease; }
/* voce di sezione senza landing (Servizi): stessa etichetta, ma non e' un link */
.nav-item__link--plain { cursor: default; }
.nav-item__link:hover,
.nav-item__link:focus-visible { text-decoration: none; }

/* la freccia sta a 12px dall'etichetta (Figma): 6 di padding del link + 6 del bottone */
.nav-item.has-mega > .nav-item__link { padding-right: 6px; }
.nav-item__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: var(--r-pill);
  color: var(--navy);
  transition: transform .2s ease, color .18s ease;
}
.nav-item__toggle[aria-expanded="true"] { transform: rotate(180deg); }
/* chevron disegnato in CSS se il pulsante viene generato da main.js */
.nav-item__toggle:empty::after {
  content: "";
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}

/* --- tendine ---------------------------------------------------------------
   Due varianti (Figma):
   .mega          = tendina compatta, attaccata al bordo inferiore della barra in
                    corrispondenza della voce (Azienda, Accessori, Settori,
                    Servizi): niente stroke, il bianco copre la linea della
                    pillola per la propria larghezza;
   .mega--wide    = tendina larga quanto la barra (solo Packaging, nav.yaml
                    mega: full): barra e pannello formano un corpo unico, senza
                    linea di giunzione, con angoli --r-menu.
   Apertura/chiusura: main.js toglie/mette l'attributo hidden. -------------- */
.mega {
  position: absolute;
  /* la voce e' alta quanto la barra meno il padding: +6px = sul bordo inferiore
     della pillola, che resta coperto dal bianco della tendina */
  top: calc(100% + 6px);
  /* il testo delle voci cade esattamente sotto la label della barra (Figma):
     19px = padding della tendina (19) + chip (10) - sbordo della chip (10) */
  left: calc(var(--nav-pad) - 19px);
  z-index: 5;
  /* larghezza dal Figma, dichiarata voce per voce in nav.yaml (mega_width) */
  width: var(--mega-w, max-content);
  padding: 20px 19px 22px;
  border-radius: 0 0 var(--r-chip) var(--r-chip);
  background: var(--white);
  opacity: 1;
  /* niente fill 'both': se l'animazione non parte (motion ridotto, browser che la salta)
     il pannello resterebbe a opacita' 0 e invisibile pur essendo aperto. */
  animation: megaIn .18s ease;
}
@keyframes megaIn {
  /* si anima solo lo scorrimento: se l'animazione non parte il pannello resta comunque visibile */
  from { transform: translateY(-10px); }
  to { transform: translateY(0); }
}

/* tendina larga: esce da sotto la barra e ne prosegue il bordo */
.mega--wide {
  top: 100%;                          /* il bordo inferiore della barra e' trasparente: nessuna giunzione */
  border: 2px solid var(--menu-line); /* prosegue il profilo della barra */
  /* -2px: il pannello e' posizionato dentro il bordo della barra, cosi i bordi esterni coincidono */
  left: -2px;
  right: -2px;
  width: auto;                        /* la larghezza la danno left/right */
  padding: 36px 0 46px;
  border-top: 0;
  border-radius: 0 0 var(--r-menu) var(--r-menu);
}

/* la barra, con la tendina larga aperta, perde gli angoli bassi e la linea di
   giunzione: barra + pannello diventano una sola forma (Figma) */
@media (min-width: 1025px) {
  .site-header__bar-inner:has(.mega--wide:not([hidden])) {
    border-bottom-color: transparent;
    border-radius: var(--r-menu) var(--r-menu) 0 0;
  }
}

.mega__inner { max-width: none; }
.mega--wide .mega__inner {
  /* Figma: le colonne partono a ~48px dal bordo del pannello */
  max-width: calc(var(--content) + 2 * var(--page-pad));
  padding-inline: clamp(20px, 2.6vw, 48px);
}
.mega__cols {
  /* compatta: una colonna sola, oppure colonne affiancate se hanno sottovoci */
  display: flex;
  flex-direction: column;
  gap: 10px;                          /* Figma: passo 51px fra le voci */
  margin: 0;
  padding: 0;
  list-style: none;
}
.mega__cols:has(.mega__col-list) { flex-direction: row; gap: 44px; }
/* tendina compatta a due colonne (Accessori): si dividono la larghezza dichiarata */
.mega:not(.mega--wide) .mega__cols:has(.mega__col-list) > .mega__col { flex: 1 1 0; min-width: 0; }
.mega--wide .mega__cols {
  /* Figma: colonne da 200px con passo 256 (gap 56), allineate a sinistra.
     auto-flow column = le categorie stanno sempre su una riga sola e si
     stringono sotto i 200px se la barra e' piu' stretta (niente a capo). */
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 200px);
  justify-content: start;
  gap: 28px clamp(24px, 3vw, 56px);
}
.mega__col { margin: 0; min-width: 0; }
.mega__col-title {
  display: block;
  margin: 0 -10px 2px;                /* lo spazio sotto lo da' il padding della chip */
  color: var(--navy);
  font-size: 20px;                    /* Figma: categoria (Flaconi, Chiusure...) */
  font-weight: 700;
}

/* Il rientro e' comune a tutte le voci di tendina (tiene l'allineamento del Figma),
   ma il riempimento e' solo del terzo livello: categorie e voci di secondo
   livello cambiano soltanto colore. */
.mega__col-title,
.mega__item a {
  padding: 8px 10px;
  transition: background-color .18s ease, color .18s ease;
}
/* Ogni voce cliccabile della tendina reagisce allo stesso modo: chip di sfondo
   piu' cambio di colore. Prima il riempimento era solo del terzo livello, quindi
   nelle tendine compatte (Azienda, Settori, Servizi), fatte di soli col-title,
   le voci cambiavano soltanto colore. */
.mega__col-title,
.mega__item a { border-radius: var(--r-chip); }
.mega__col-title:hover,
.mega__col-title:focus-visible,
.mega__item a:hover,
.mega__item a:focus-visible {
  background: var(--menu-hover);
  color: var(--menu-hover-ink);
  text-decoration: none;
}

/* nella tendina compatta senza sottovoci il titolo E' la voce di menu:
   stessa misura delle sottovoci */
.mega__col:not(:has(.mega__col-list)) > .mega__col-title {
  margin-bottom: 0;
  font-size: 16px;
  font-weight: 600;
}
.mega__col-list { margin: 0; padding: 0; list-style: none; }
.mega__item { margin: 0 0 2px; }
.mega__item a {
  display: block;
  margin-inline: -10px;               /* il riempimento sborda, il testo resta in colonna */
  color: #3E6688;
  font-size: 16px;                    /* Figma: sottovoce (Flaconi in vetro...) */
  font-weight: 500;
}
/* `is-empty` = sottocategoria senza prodotti a catalogo (Spatole). Resta come
   aggancio dati, ma non si sbiadisce piu': la pagina esiste, ha i suoi testi e la
   sua CTA, quindi la voce si legge come tutte le altre. */

/* <ul> annidata promossa a pannello dal binder (Layer 2 DB) */
ul.mega { list-style: none; }
ul.mega > li { margin: 0 0 10px; }
ul.mega > li > a { color: var(--navy); font-weight: 700; }
ul.mega ul { margin: 8px 0 0; padding: 0; list-style: none; }
ul.mega ul a { color: #3E6688; font-size: 15px; font-weight: 500; }

/* --- ricerca nella pillola: si apre al focus o al clic sulla lente --------- */
.site-search {
  position: static;                   /* campo e X si ancorano alla PILLOLA (.site-header__bar-inner) */
  flex: none;
  display: flex;
  align-items: center;
  margin-left: auto;
}
/* Il campo e' una TENDINA SOTTO la pillola, allineata a destra come la lente: come le
   tendine del menu, non copre nulla. Fino al 25/09 si apriva DENTRO la pillola, sopra
   le ultime voci (Servizi, Blog): la cliente ha bocciato la sovrapposizione. Prima
   ancora spingeva le voci e la barra «ballava». Chiuso: larghezza 0 e trasparente,
   cosi' la transizione di apertura resta quella di sempre. */
.site-search__input {
  position: absolute;
  top: calc(100% + 8px);
  right: var(--pill-pad);             /* il padding orizzontale della pillola: a filo della lente */
  z-index: 5;
  width: 0;
  min-width: 0;
  padding: 0;
  border: 2px solid transparent;      /* lo stesso filo della pillola e delle tendine */
  border-radius: var(--r-pill);
  background: var(--white);
  color: var(--grigio-1);
  font-size: var(--small);
  opacity: 0;
  pointer-events: none;
  transition: width .22s ease, opacity .18s ease, padding .22s ease;
}
.site-search.is-open .site-search__input,
.site-search:focus-within .site-search__input {
  width: clamp(280px, 24vw, 380px);
  padding: 12px 52px 12px 22px;       /* a destra lo spazio della X */
  border-color: var(--menu-line);
  box-shadow: var(--sh-nav);
  opacity: 1;
  pointer-events: auto;
}
.site-search__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--r-pill);
  color: var(--navy);
  transition: background-color .18s ease;
}
.site-search__submit:hover { background: var(--sand-2); }
/* La X dentro il campo (richiesta della cliente del 25/09, «sia per mobile che per
   desktop»): chiude la ricerca e svuota il campo. Sta nell'angolo destro del campo e
   compare solo a campo aperto — le stesse due condizioni che aprono il campo. Navy su
   pastiglia sabbia, 36px con il glifo a 20: la prima versione, grigia e nuda, «si
   vedeva molto poco». Il clic lo gestisce main.js (data-search-close).
   Il centro verticale: 8px di stacco + meta' del campo (12+22+12 di testo, 2+2 di
   filo = 50 -> 25). */
.site-search__close {
  position: absolute;
  top: calc(100% + 8px + 25px);
  right: calc(var(--pill-pad) + 8px);
  z-index: 6;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--r-pill);
  background: var(--sand-2);
  color: var(--navy);
  translate: 0 -50%;
  /* chiusa: invisibile, fuori dal tab order e dal clic. Non `display: none`, cosi'
     l'opacita' puo' arrivare con un ritardo quando il campo si apre (vedi <= 1024:
     la pillola deve allargarsi prima che la X le compaia dentro). */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .1s ease, visibility 0s linear .1s, background-color .18s ease;
}
.site-search.is-open .site-search__close,
.site-search:focus-within .site-search__close {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity .12s ease .1s, visibility 0s linear .1s, background-color .18s ease;
}
.site-search__close:hover { background: var(--cipria); }
.site-search__close .icon { width: 20px; height: 20px; }
/* il campo e' type="search": Chrome e Safari ci disegnano un LORO pulsante di
   cancellazione appena c'e' del testo, accanto alla X del sito — due X (misurato
   dalla verifica del 25/09, 151 pixel scuri in piu' a 390 in WebKit). Resta solo la
   nostra, che fa anche di piu' (chiude). */
.site-search__input::-webkit-search-cancel-button,
.site-search__input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }

/* --- hamburger (visibile sotto 1024) --------------------------------------- */
.nav-burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--r-pill);
  color: var(--navy);
  transition: background-color .18s ease;
}
.nav-burger:hover { background: var(--sand-2); }
.nav-burger__close { display: none; }
.nav-burger[aria-expanded="true"] .nav-burger__close { display: inline-flex; }
.nav-burger[aria-expanded="true"] .nav-burger__open { display: none; }

/* =============================================================================
   07. BREADCRUMB (partials/_breadcrumb.html.j2: nav.breadcrumb > ol.breadcrumb__list)
   ============================================================================= */
/* piu' aria fra header e breadcrumb (richiesta Nico 2026-09-08): era 44px a 1920 */
.breadcrumb { padding-top: clamp(28px, 3.2vw, 56px); }
/* nel Figma la tinta dell'hero parte dal bordo alto della pagina: header e breadcrumb
   poggiano sulla stessa sabbia, non sul fondo pagina (la pillola del menu resta bianca).
   Vale solo dove la PRIMA fascia e' un hero split in tinta (editoriali, categorie, hub,
   settori); home (hero--full), prodotto e pagine a hero bianco restano su --bg, come nei
   frame homepage.png, prodotto-alpha.png, contatti.png, faq.png, servizi-produzione.png.
   La breadcrumb resta in flusso sotto l'header (R15), cambia solo il fondo.

   LA TINTA E' IL TERRENO DELLA PAGINA, NON L'HEADER (25/09). Fino a quel giorno stava
   su .site-header::before — uno strato dietro l'header sticky — e un JS la spegneva
   (body.is-past-hero) quando la fascia passava sotto; ma finche' non scattava, la
   striscia restava stesa sopra la foto dell'hero che scorreva sotto (sostenibilita'
   a 390: «l'header si porta dietro un po' di colore»). Ora e' una striscia in cima al
   fondo del <body>, alta 300px: piu' dell'header e sempre coperta da elementi della
   stessa tinta (breadcrumb e hero, che e' opaco e piu' alto). Da fermo non c'e' un
   confine; scorrendo, l'header non ha piu' nulla da portarsi dietro e mostra cio' che
   gli passa sotto, come gia' fa sulla home e sulle schede. Niente JS. */
body:has(main > .band--hero.hero--split:first-child),
/* stessa cosa su categorie e sottocategorie con l'hero di solo testo: sono le pagine
   accessori (chiusure e altri-accessori, ma anche le foglie tipo applicatori), dove
   il Figma porta la sabbia fino al bordo alto. Blog, ricerca e legali usano la stessa
   variante ma nei loro frame l'header poggia su --bg (blog.png): restano fuori. */
body.page--category:has(main > .band--hero.hero--plain:first-child),
body.page--subcategory:has(main > .band--hero.hero--plain:first-child),
/* ...e il blog (cliente, 25/09): il suo hero e' in tinta come quello degli accessori,
   quindi la tinta sale fino al bordo alto come sulle altre pagine. Ricerca e legali
   restano fuori, come nei loro frame. */
body.page--blog-landing:has(main > .band--hero.hero--plain:first-child) {
  background: linear-gradient(var(--tint-hero), var(--tint-hero)) 0 0 / 100% 300px no-repeat var(--bg);
}
body:has(main > .band--hero.hero--split:first-child) .breadcrumb,
body.page--category:has(main > .band--hero.hero--plain:first-child) .breadcrumb,
body.page--subcategory:has(main > .band--hero.hero--plain:first-child) .breadcrumb,
body.page--blog-landing:has(main > .band--hero.hero--plain:first-child) .breadcrumb { background: var(--tint-hero); }
.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 14px;
}
.breadcrumb__item {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}
.breadcrumb__item + .breadcrumb__item::before {
  content: "/";
  color: var(--grigio-2);
  opacity: .7;
}
.breadcrumb__link { color: var(--grigio-1); }
.breadcrumb__link:hover { color: var(--navy); }
.breadcrumb__current { color: var(--navy); font-weight: 500; }

/* =============================================================================
   08. HERO
   varianti: split (testo + foto a filo destro) | full (foto full-bleed, testo
   bianco) | center (titolo centrato, foto larga sotto) | plain (solo testo)
   ============================================================================= */
.band--hero {
  overflow: clip;                   /* contiene il cerchio decorativo */
  padding-block: clamp(48px, 5vw, 96px);
}
.hero--split,
.hero--plain { background: var(--tint-hero); }
/* il centrato no: nel frame servizi-produzione.png poggia su --bg, come la breadcrumb */
.hero--split { padding-block: 0; }

.hero__inner { position: relative; }

.hero__text { position: relative; z-index: 1; max-width: 640px; }
/* hero delle hub/categoria: colonna da 760px, come nel Figma (paragrafo su tre
   righe). Il limite di 52ch della prosa lo terrebbe a meta' larghezza. */
.hero--split .hero__text { max-width: 760px; }
/* paragrafo nella stessa tinta dell'h1 (richiesta cliente, confermata dai frame:
   flaconi-in-vetro/flaconi/vasi/pilloliere/packaging/airless/foamer #C3AEAD,
   chiusure/altri-accessori/chi-siamo #DBC1AE, settori-* #DFA494, sostenibilita
   #A2A681 - nel testo dell'hero in tinta non compare mai --ink). Restano su --ink
   gli hero su fondo pagina: --center (servizi-*.png), --bare (faq, contatti) e
   --plain, dove i frame mostrano il paragrafo #727272.
   Contrasto 1,6-2,1:1: sotto la soglia AA, stessa scelta grafica gia' accettata
   per H1/H2 (vedi nota su --accent-strong). */
.hero--split .hero__text .prose { max-width: none; color: var(--accent); }
.hero__title {
  margin-bottom: .35em;
  color: var(--accent);             /* tinta piena del Figma (vedi nota su --accent-strong) */
  font-size: var(--h1-inner);
}
.hero--full .hero__title,
.hero--home .hero__title { font-size: var(--h1); }
.hero__sub {
  margin-bottom: 1em;
  color: var(--grigio-1);
  font-size: var(--label);
  font-weight: 500;
}
/* Il paragrafo dell'hero segue sempre la tinta dell'h1, non solo negli hero split:
   sulle categorie accessori (hero--plain) restava --ink e stonava con il titolo.
   Su chiusure/altri-accessori l'accento e' --beige #DBC1AE, sulle categorie
   packaging --cipria-2 #C3AEAD. */
.hero__text .prose { color: var(--accent); max-width: 52ch; }
.hero__cta { margin: clamp(22px, 2.6vw, 36px) 0 0; }

.hero__media { position: relative; }
.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--r-img);
  /* --media-focus lo dichiara la fascia nella YAML (`media_focus:`) quando il taglio
     centrato perde il soggetto. Sta qui sul contenitore comune, non sulla singola
     variante, perche' ogni hero ritaglia: split e sector di lato, full e center in
     altezza. Senza valore vale `center`, cioe' esattamente la resa di prima. */
  object-position: var(--media-focus, center);
}

/* --- split: testo a sinistra, foto a filo del bordo destro -----------------
   Resa di categorie, hub e settori (Figma flaconi.png, packaging.png, vasi.png). */
.hero--split .hero__inner {
  display: grid;
  /* la foto e' un box di 780x575 a 1920 (Figma packaging.png, flaconi.png, vasi.png):
     larghezza dichiarata, non frazione della griglia, cosi resta 780 a filo destro */
  grid-template-columns: minmax(0, 1fr) clamp(300px, 40.63vw, 780px);
  align-items: center;
  gap: clamp(28px, 4vw, 72px);
  max-width: none;                  /* la foto arriva al bordo destro */
  padding-right: 0;
  padding-left: max(var(--page-pad), (100% - var(--content)) / 2);
  padding-block: clamp(40px, 4.4vw, 84px);
}
.hero--split .hero__media {
  align-self: stretch;
  /* 575px a 1920: stessa scala della larghezza, il box resta 780/575 */
  min-height: clamp(221px, 29.95vw, 575px);
}
/* immagine in posizione assoluta: l'altezza la decide il testo, non la foto */
.hero--split .hero__media img {
  position: absolute;
  inset: 0;
  border-radius: var(--r-hero) 0 0 var(--r-hero);
}

/* --- split "settore": foto dentro la colonna, verticale ----------------------
   Figma settori-cosmetico.png / settori-alimentare.png / settori-erboristico.png,
   identici a 1920: testo 592, gronda 79, foto 627x779 con il bordo destro a filo
   della colonna di contenuto (non del viewport) e raggi uniformi.
   Il segno grafico non c'e': .hero__deco lo stampa solo la variante split. */
.hero--sector .hero__inner {
  grid-template-columns: minmax(0, 1fr) clamp(260px, 32.66vw, 627px);
  gap: clamp(24px, 4.11vw, 79px);
  max-width: calc(var(--content) + 2 * var(--page-pad));
  padding-inline: var(--page-pad);
}
.hero--sector .hero__media { align-self: center; min-height: 0; }
.hero--sector .hero__media img {
  position: static;
  height: auto;
  aspect-ratio: 627 / 779;
  border-radius: var(--r-img);
}

/* --- split "inset": foto DENTRO la colonna di contenuto (pagine editoriali) --
   Figma azienda-chi-siamo.png e azienda-sostenibilita.png: a 1920 il testo occupa
   702px, la foto 471x576 con il bordo destro a filo della colonna (non del viewport)
   e i raggi asimmetrici "a foglia" 150 / 56 / 170 / 0. */
.hero--inset .hero__inner {
  grid-template-columns: minmax(0, 1.49fr) minmax(0, 1fr);
  gap: clamp(24px, 6.6vw, 127px);
  max-width: calc(var(--content) + 2 * var(--page-pad));
  padding-inline: var(--page-pad);
  padding-block: clamp(12px, 1.1vw, 22px) clamp(32px, 3.4vw, 64px);
}
.hero--inset .hero__text { max-width: none; }   /* la colonna la decide la griglia */
.hero--inset .hero__text .prose { font-size: clamp(17px, 1.1vw, 21px); line-height: 1.42; }
.hero--inset .hero__media { align-self: center; min-height: 0; }
.hero--inset .hero__media img {
  position: static;
  height: auto;
  aspect-ratio: 471 / 576;
  border-radius:
    clamp(40px, 7.8vw, 150px)
    clamp(16px, 2.9vw, 56px)
    clamp(44px, 8.85vw, 170px)
    0;
}

/* cerchio decorativo bordeaux con spicchio bianco (solo decorazione) */
/* Segno grafico dell'hero: e' il marchio Ho.Bag scomposto (mezzo tondo bordeaux +
   foglia bianca), a filo del bordo sinistro e in alto nella fascia. Misure dal Figma
   packaging.png / flaconi.png: bordeaux 37x74 visibile, foglia 123x122, insieme
   124x159 con il tondo che parte dal bordo alto dell'hero. */
.hero__deco {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  width: clamp(76px, 6.46vw, 124px);
  aspect-ratio: 124 / 159;
  background: url("../img/hobag-chi-siamo-segno-grafico.svg") no-repeat left top / contain;
  pointer-events: none;
}
/* sulle editoriali il segno grafico e' l'asset reale del brand (mezza lente bordeaux +
   foglia bianca, 124x159 a 1920), a filo del bordo sinistro e in basso nella fascia.
   Resta decorazione: background su uno <span aria-hidden>, non un'immagine editoriale. */
/* nell'hero inset (chi-siamo, sostenibilita) lo stesso segno sta in basso */
.hero--inset .hero__deco {
  top: auto;
  bottom: clamp(24px, 2.8vw, 54px);
  background-position: left bottom;
}
/* hero di solo testo: il segno grafico va a DESTRA (pagine accessori)
   ---------------------------------------------------------------------------
   E' lo stesso marchio scomposto di .hero__deco, SPECCHIATO. Misurato sui tre
   frame dell'area, identici a 1920 (chiusure.png, altri-accessori.png,
   "Chiusure - applicatori.jpg"): riquadro 154x197 col bordo destro a filo del
   viewport e il bordo alto 50px sotto l'attacco della fascia; dentro, calotta
   bordeaux da 92 tagliata a meta' dal bordo (46 visibili) e foglia bianca 153.
   Prima erano due cerchi PIENI da 200: stessa idea, forma e misure sbagliate.
   Lo scope per classe di pagina lo vuole il Figma: blog, ricerca e legali usano
   la stessa variante ma nei loro frame l'hero e' nudo (blog.png). */
.page--category .hero--plain::before,
.page--subcategory .hero--plain::before {
  content: "";
  position: absolute;
  /* Nei tre frame accessori il segno sta a y 447-645 dal bordo alto della pagina,
     fisso qualunque sia la lunghezza dell'H1: centro 546 contro il 477 della fascia,
     quindi nel Figma e' 69px sotto la meta'. Su richiesta del cliente qui va invece
     centrato insieme a titolo e testo, quindi top 50% e non piu' una misura fissa.
     Il translateY va PRIMA dello scaleX: specchiando dopo si ribalterebbe anche lo
     spostamento verticale (su questo asse e' innocuo, ma l'ordine resta quello). */
  top: 50%;
  right: 0;
  z-index: 0;
  width: clamp(94px, 8.02vw, 154px);
  aspect-ratio: 124 / 159;
  background: url("../img/hobag-chi-siamo-segno-grafico.svg") no-repeat center / contain;
  transform: translateY(-50%) scaleX(-1);
  pointer-events: none;
}
/* Altezza della fascia in tinta sulle pagine accessori.
   Misurata sui tre frame a 1920 (chiusure.png, altri-accessori.png,
   chiusure-applicatori.png): la sabbia finisce SEMPRE a y=955 dal bordo alto della
   pagina, anche se l'H1 sta su 6, 3 o 5 righe. Nel Figma quindi il blocco ha
   un'altezza fissa e il testo ci sta dentro, non e' il testo a dettarla.
   I 750px sono 955 meno l'ingombro di header e breadcrumb, calcolato dal CSS:
     topbar   16 + 46 (marchio) + 8            =  70
     pillola  85 (min-height) - 26 (margine)   =  59
     breadcrumb 56 (padding) + 20 (riga a 14)  =  76
                                            totale 205 -> 955 - 205 = 750
   Se cambiano l'altezza della pillola o del marchio, questo numero va rifatto: e'
   l'unico punto del foglio che li somma.
   Il contenuto (titolo, testo, segno grafico) sta CENTRATO in quest'altezza, cioe'
   a meta' fra la breadcrumb e il bordo basso della fascia: e' una richiesta del
   cliente, non il Figma, dove il testo e' piu' in alto e lo spazio cade tutto sotto.
   La colonna con justify-content invece di align-items tiene il container a piena
   larghezza: in riga i suoi margin-inline auto lo restringerebbero. */
body.page--category .hero--plain,
body.page--subcategory .hero--plain {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: clamp(360px, 39.06vw, 750px);
}
.hero--plain .hero__inner { position: relative; z-index: 2; }
.hero--plain .hero__text { max-width: 760px; }
/* Figma Chiusure.jpg: sulle pagine accessori il titolo va a TRE righe (la piu' larga
   misura 1120 sui 1273 della colonna) e la prosa arriva quasi a filo: con i 760px di
   default l'H1 si spezzava in cinque righe. Scopato a categoria/sottocategoria come le
   altre regole di questa variante: blog, ricerca e legali restano sui 760. */
body.page--category .hero--plain .hero__text,
body.page--subcategory .hero--plain .hero__text { max-width: none; }
/* 1140 e' il default (Chiusure); una pagina puo' stringere il box del titolo con
   `title_width` nella YAML, perche' nei frame il capoverso dell'H1 e' una scelta per
   pagina: applicatori spezza dopo "per" a 942px di testo, con 1140 starebbe in riga. */
body.page--category .hero--plain .hero__title,
body.page--subcategory .hero--plain .hero__title { max-width: var(--hero-title-w, 1140px); }
body.page--category .hero--plain .hero__text .prose,
body.page--subcategory .hero--plain .hero__text .prose { max-width: 1090px; }

/* --- bare: solo il titolo, senza tinta e senza segno grafico ----------------
   Figma contatti.png: l'h1 poggia su --bg subito sotto la breadcrumb (29px) e la
   fascia successiva parte 30px piu' sotto; nessun cerchio decorativo (la variante
   non dichiara ::before/::after, quindi non eredita quelli di .hero--plain). */
.hero--bare { padding-block: clamp(16px, 1.51vw, 29px) 0; }
.hero--bare .hero__text { max-width: none; }
.hero--bare .hero__title { margin-bottom: 0; }
/* occhiello: nel frame della FAQ e' navy e occupa tutta la colonna (va a capo sul
   bordo, non su una misura di lettura). Il corpo resta quello del sito (--body, 20px):
   nel frame misura 22, ma la regola dei 20px vale ovunque. I margini portano la
   fascia successiva a 77px dall'ultima riga, come nel frame. */
.hero--bare .hero__text .prose {
  max-width: none;
  margin-top: clamp(18px, 1.98vw, 38px);
  margin-bottom: clamp(20px, 2.45vw, 47px);
  color: var(--navy);
  line-height: 1.23;
}
.band--hero.hero--bare + .band { padding-top: clamp(18px, 1.56vw, 30px); }

/* --- full: foto a tutta larghezza, testo bianco --------------------------- */
.hero--full {
  position: relative;
  padding: 0;
  background: var(--navy);
}
.hero--full > .hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;                        /* sotto la velatura: senza z-index espliciti l'immagine coprirebbe ::before */
}
.hero--full > .hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
}
.hero--full .hero__inner {
  position: relative;
  z-index: 2;                        /* testo sopra velatura e immagine */
  display: flex;
  align-items: center;
  min-height: clamp(420px, 38vw, 660px);
  padding-block: clamp(48px, 5vw, 90px);
}
.hero--full .hero__text { max-width: 720px; }
.hero--full .hero__title,
.hero--full .hero__sub,
.hero--full .prose { color: var(--white); }
.hero--full .hero__sub,
.hero--full .prose { font-weight: 500; }
/* VELATURA TOLTA — richiesta della cliente del 23/09: «il gradiente grigio da una
   sensazione molto "smorta" si puo' variare? Per far emergere il colore e la foto?
   Altrimenti non mettiamo gradienti e noi creeremo delle foto dedicate che tengano
   l'area a sinistra libera affinche' il testo sia leggibile». Scelta confermata da
   Nico: si toglie, e le foto dedicate arrivano da loro.

   ⚠️ LA FOTO DEDICATA E' UN PREREQUISITO, non una rifinitura. Misurato sul servito
   il 2026-09-23, riquadro del titolo, sfondo senza il testo davanti:
       con la velatura   7,38:1 medio · 5,66:1 sul 5% piu' chiaro
       senza             3,40:1 medio · 2,80:1 sul 5% piu' chiaro
   La soglia e' 4,5:1 per il testo normale (il sottotitolo) e 3:1 per quello grande
   (il titolo). Con lo scatto di oggi, senza velatura, il sottotitolo non e' leggibile
   a norma e il titolo passa solo dove la foto e' scura. Se la foto dedicata tardasse,
   la via di mezzo e' rimettere QUESTA regola alleggerita (opacita' .62 -> ~.35): il
   contrasto torna sopra 4,5:1 e la foto resta molto piu' viva di prima.

   `.hero--full` e' solo l'hero della home: una pagina, una foto. */
.hero--full::before { content: none; }

/* --- slider dell'hero (macro hero_slider): le fasce condividono la stessa cella
   della griglia, visibile una per volta. Niente position: absolute, cosi l'altezza
   resta quella della slide piu' alta e non ci sono salti di layout. ---------- */
.hero-slider { position: relative; }
.hero-slider__viewport { display: grid; }
.hero-slider__slide {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;               /* toglie la slide inattiva anche allo screen reader */
  transition: opacity .5s ease, visibility 0s linear .5s;
}
.hero-slider__slide.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity .5s ease;
}
.hero-slider__dots {
  position: absolute;
  left: 50%;
  bottom: clamp(10px, 1.4vw, 22px);
  z-index: 3;                       /* sopra velatura e testo della slide */
  display: flex;
  gap: 4px;
  transform: translateX(-50%);
}
/* il bottone e' 24x24 (bersaglio minimo WCAG 2.5.8), il pallino lo disegna ::before */
.hero-slider__dot {
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: none;
  cursor: pointer;
  transition: width .2s ease;
}
.hero-slider__dot::before {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
  margin-inline: auto;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .5);
  transition: background-color .2s ease, width .2s ease;
}
.hero-slider__dot:hover::before { background: rgba(255, 255, 255, .8); }
.hero-slider__dot[aria-current="true"] { width: 42px; }
.hero-slider__dot[aria-current="true"]::before { width: 28px; background: var(--white); }

/* --- center: titolo centrato, foto larga sotto ---------------------------- */
/* --- center: h1 e occhiello centrati, foto larga sotto ----------------------
   Figma servizi-produzione.png a 1920: h1 70/700 su due righe (a capo dopo "nostra"),
   occhiello 20/24 su tre righe, entrambi larghi tutta la colonna; foto 1295x567 a
   55px dall'occhiello. La fascia parte 35px sotto la breadcrumb e finisce sulla
   foto: lo stacco con quella dopo lo da' --band-pad. */
.hero--center { padding-block: clamp(20px, 1.82vw, 35px) 0; text-align: center; }
.hero--center .hero__text { max-width: none; margin-inline: auto; }
.hero--center .hero__text .prose { max-width: none; margin-inline: auto; line-height: 1.2; }
.hero--center .hero__media--wide { margin-top: clamp(32px, 3.6vw, 56px); }
.hero--center .hero__media--wide img { aspect-ratio: 1295 / 567; border-radius: var(--r-img); }

/* --- plain / secondo hero (h2) -------------------------------------------- */
.hero--plain { padding-block: clamp(44px, 5vw, 96px); }
.hero--hero-2 {
  background: var(--bg);
  padding-block: var(--band-pad) 0;
}
.hero--hero-2::before,
.hero--hero-2::after { display: none; }
.hero--hero-2 .hero__title { color: var(--navy); }

/* =============================================================================
   09. MEDIA + TESTO, FEATURE
   ============================================================================= */
.media-text__media img {
  width: 100%;
  border-radius: var(--r-img);
  object-fit: cover;
  /* --media-focus lo dichiara la fascia nella YAML (media_focus), come sull'hero
     settore: il frame a volte ritaglia la foto fuori centro e il taglio centrato
     perderebbe il soggetto. */
  object-position: var(--media-focus, center);
}
.media-text__body > :last-child { margin-bottom: 0; }
/* nel Figma l'H2 delle fasce editoriali porta la tinta della pagina o della fascia
   (`accent:` nella YAML): chi-siamo usa #DBC1AE, la fascia missione #C3AEAD, la fascia
   qualita #A2A681 */
.media-text__body h2 { margin-bottom: .5em; color: var(--accent); }

/* --- split / box: due colonne di pari peso -----------------------------------
   Il box foto standard del Figma e' 602x620 a 1920 (ricorre su azienda-chi-siamo,
   servizi-produzione e azienda-sostenibilita): con gap 72px su colonna 1273 la
   colonna vale 601px, quindi la foto la riempie e l'altezza la da' `--media-ar`.
   Una fascia puo' dichiarare un box diverso con `media_box: <w>x<h>` nella YAML:
   la macro ne ricava `--media-ar` e, se la foto e' piu' stretta del box standard,
   `--media-w` (allineata al bordo esterno della colonna, come nel Figma). */
.media-text--split > .container,
.media-text--box .media-text__panel {
  display: grid;
  align-items: center;
  gap: clamp(28px, 3.75vw, 72px);
}
.media-text--split > .container { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.media-text--split .media-text__media,
.media-text--box .media-text__media { align-self: center; }
.media-text--split .media-text__media { width: var(--media-w, 100%); justify-self: start; }
.media-text--split.media-text--reverse .media-text__media { justify-self: end; }
.media-text--split .media-text__media img,
.media-text--box .media-text__media img { aspect-ratio: var(--media-ar, 602 / 620); }
.media-text--reverse .media-text__media { order: 2; }
.media-text--reverse .media-text__body { order: 1; }

/* --- box: split dentro il pannello sabbia arrotondato del Figma --------------
   Pannello 1298x508 con padding 48; dentro, foto 420x420 a sinistra e testo 537
   a destra: le colonne valgono 35% e 44,7% dell'interno, il resto e' respiro. */
.media-text--box .media-text__panel {
  grid-template-columns: minmax(0, 35fr) minmax(0, 44.7fr);
  gap: 20.3%;
  padding: clamp(24px, 2.5vw, 48px);
  background: var(--tint-band);
  border-radius: var(--r-card);       /* Figma: ~16px su chi-siamo e sostenibilita */
}
.media-text--box .media-text__media img { aspect-ratio: var(--media-ar, 1 / 1); }

/* --- cover: foto di fondo, velatura e testo centrato bianco -------------------
   Figma azienda-sostenibilita.png "Filiera corta": box 1294x537 a filo colonna,
   angoli --r-img, testo centrato su velatura scura. */
.media-text--cover .media-text__cover {
  position: relative;
  display: grid;
  place-items: center;
  min-height: clamp(300px, 28vw, 537px);
  padding: clamp(36px, 4.6vw, 88px) clamp(24px, 4vw, 96px);
  border-radius: var(--r-img);
  overflow: clip;
  text-align: center;
}
.media-text--cover .media-text__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.media-text--cover .media-text__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
}
.media-text--cover .media-text__cover::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  /* la velatura tiene il bianco leggibile anche sul taglio piu' chiaro della foto */
  background: rgba(18, 28, 38, .38);
}
.media-text--cover .media-text__body {
  position: relative;
  z-index: 2;
  max-width: 900px;
}
.media-text--cover h2,
.media-text--cover .prose { color: var(--white); }
.media-text--cover .prose { margin-inline: auto; }

/* --- aside: titolo, foto + pannello a sinistra, card degli highlight a destra --
   Figma azienda-sostenibilita.png "Il nostro approccio": colonne 913 + 325, gap 58;
   le tre card riempiono in altezza la colonna di sinistra (foto 537 + pannello 251). */
.media-text--aside .media-text__aside {
  display: grid;
  grid-template-columns: minmax(0, 913fr) minmax(0, 325fr);
  gap: clamp(20px, 3vw, 58px);
  align-items: stretch;
  margin-top: clamp(24px, 3vw, 46px);
}
.media-text--aside .media-text__col { display: flex; flex-direction: column; gap: clamp(16px, 1.6vw, 23px); }
.media-text--aside .media-text__media img { aspect-ratio: var(--media-ar, 913 / 537); }
.media-text--aside .media-text__panel {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  padding: clamp(22px, 2.4vw, 44px);
  border-radius: var(--r-chip);
  background: var(--tint-band);
}
.media-text--aside .media-text__panel .prose { max-width: none; margin-bottom: 0; }
.feature-cards {
  display: grid;
  grid-auto-rows: 1fr;
  gap: clamp(14px, 1.7vw, 30px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.feature-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin: 0;
  padding: 20px;
  border-radius: var(--r-chip);
  background: var(--tint-band);
  color: var(--accent);
  font-size: var(--label);
  font-weight: 600;
  text-align: center;
}
/* icone delle card (export Figma): nel frame azienda-sostenibilita.png misurano
   74px dentro card da 325x257. Misura fissa, non in vw: la colonna e' larga
   --content (1273px) fino a 1024, quindi la card non rimpicciolisce con lo schermo */
.feature-card__icon { width: 74px; height: 74px; }

/* --- wide: foto larga sopra, prosa su tutta la colonna ---------------------- */
.media-text--wide .media-text__media--wide { margin-bottom: clamp(24px, 3.1vw, 52px); }
.media-text--wide .media-text__media--wide img { aspect-ratio: var(--media-ar, 1295 / 540); }
.media-text--wide .prose { max-width: none; }

/* nel frame la prosa non ha misura di lettura: va a capo sul bordo della colonna */
.media-text--stack .prose { max-width: none; }
/* Il titolo della fascia impilata riempie la riga fino al bordo destro della griglia.
   Gli heading del sito hanno `text-wrap: balance` (vedi h1-h6), che pareggia le righe:
   su un titolo lungo nessuna delle due arriva al bordo e resta un vuoto largo mezza
   colonna. Qui serve l'opposto, quindi si torna all'andata a capo normale: la prima
   riga si riempie e va sotto solo quello che non ci sta. Il valore giusto e' `wrap`,
   non `normal`: `normal` non esiste per questa proprieta' (i valori sono wrap | nowrap |
   balance | pretty | stable), il browser scarterebbe la riga e il bilanciamento
   resterebbe acceso. `wrap` e' lo shorthand e rimette text-wrap-style ad `auto`.
   Misurato sul font del sito (Montserrat 700, 50px, colonna 1273):
   contagocce passa da 675px a 1164 di prima riga, spray da 675 a 1106. Oltre non si
   puo' senza spezzare una parola: la parola dopo, da sola, sfonderebbe la griglia. */
.media-text--stack .media-text__body h2 { text-wrap: wrap; }
.media-text--stack .media-text__media--wide { margin-top: clamp(28px, 3.4vw, 52px); }
.media-text--stack .media-text__media--wide img { aspect-ratio: 1273 / 545; border-radius: var(--r-img); }
/* Fascia di solo testo (/contatti/): la colonna e' larga quanto serve al titolo su
   UNA riga e al paragrafo su DUE. Misurato sul font reale (static/fonts/montserrat):
   a 1920 l'H2 "Progettiamo insieme il tuo packaging" (50px/700) occupa 974px e il
   paragrafo (18px/400) passa a due righe da 920px in su. 1040 tiene il margine. */
.media-text--text .media-text__body { max-width: 1040px; }
.media-text--text .prose { max-width: none; }

/* Fascia testo con riquadri a icona (`tiles:` nella YAML, macro text_band).
   Figma servizi, «Prodotti e personalizzazione su misura per ogni mercato»: titolo,
   testo, una fila di quattro riquadri chiari con un'icona a filo nella tinta della
   pagina, bottone sotto. Misure lette sul frame e riportate a 1920: riquadri alti
   235, stacco 12, raggio della card; icone alte circa 105. I riquadri NON sono
   uguali (proporzioni 1,9 : 1 : 1,35 : 2,4): la larghezza relativa la dichiara la
   YAML con `weight`, che qui diventa flex-grow. Sotto i 640 px due colonne uguali. */
.media-text--tiles .media-text__body { max-width: none; }
.media-text--tiles .prose { max-width: 1180px; }
.icon-tiles {
  display: flex;
  gap: clamp(8px, .63vw, 12px);
  margin: clamp(28px, 2.97vw, 57px) 0 0;
  padding: 0;
  list-style: none;
}
.icon-tile { flex: var(--tile-w, 1) 1 0; min-width: 0; margin: 0; }
.icon-tile__box {
  display: flex;
  align-items: center;
  justify-content: center;
  height: clamp(118px, 12.24vw, 235px);
  border-radius: var(--r-card);
  background: var(--sand-2);
  color: var(--accent);
  transition: background-color .2s ease;
}
a.icon-tile__box:hover,
a.icon-tile__box:focus-visible { background: var(--line-2); text-decoration: none; }
.icon-tile__icon { display: block; width: auto; height: clamp(54px, 5.47vw, 105px); }
.icon-tile__icon svg { display: block; width: auto; height: 100%; }
@media (max-width: 640px) {
  .icon-tiles { flex-wrap: wrap; }
  .icon-tile { flex: 1 1 calc(50% - 8px); }
}

/* --- link a documento (`documents:` nella YAML, macro text_band) --------------
   Chi-siamo, «Qualita' Made in Italy certificata»: due piccole icone col nome del
   certificato, fra il testo e il pulsante (richiesta della cliente del 25/09).
   Ogni <a class="doc-badge"> nasce `hidden` e senza href: e' il pannello a legare il
   PDF (hook data-pf-file) e a mostrarlo. L'elenco sparisce quando nessuna voce e'
   visibile, cosi' senza documenti non resta nemmeno il suo spazio. Icona e hover
   nella tinta della fascia (`accent:` -> --accent), il nome in navy come i link. */
.doc-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  margin: clamp(16px, 1.6vw, 24px) 0 0;
  padding: 0;
  list-style: none;
}
.doc-badges:not(:has(.doc-badge:not([hidden]))) { display: none; }
.doc-badges__item { margin: 0; }
.doc-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--navy);
  font-size: var(--small);
  font-weight: 600;
}
.doc-badge:hover { color: var(--accent); text-decoration: none; }
.doc-badge__icon { width: 28px; height: 28px; color: var(--accent); }

/* fascia feature: titolo, foto grande, riga bottone + prosa */
.feature__media { margin-bottom: clamp(24px, 3vw, 44px); }
.feature__media img {
  width: 100%;
  aspect-ratio: 1295 / 540;
  border-radius: var(--r-img);
  object-fit: cover;
  /* il box e' 2.40 e le foto di reparto sono 1.50: il ritaglio mangia oltre un terzo
     dell'altezza, e sul flacone in mano di homepage.png il collo finiva fuori.
     `media_focus:` nella YAML della fascia sposta l'inquadratura. */
  object-position: var(--media-focus, center);
}
/* Nel frame il titolo della fascia prende la tinta del suo pulsante: la prima resta
   navy, la seconda ("Dalla progettazione alla realizzazione") e' --pesca #DFA494,
   misurato su homepage.png (223, 164, 148). */
.feature--pesca h2 { color: var(--pesca); }
/* Misure su homepage.png, valide per tutte e due le fasce feature: la prosa non parte
   dalla meta' ma da x 971 e chiude a 1596, cioe' 625 di colonna contro i 592 del
   pulsante (592 + 56 di gap + 625 = 1273). Prima era .8fr/1.5fr, cioe' 423/794: la
   colonna del testo era larga 170px di troppo. */
.feature__row {
  display: grid;
  grid-template-columns: minmax(220px, 592fr) minmax(0, 625fr);
  align-items: start;
  gap: clamp(24px, 3vw, 56px);
}
.feature__cta { padding-top: 4px; }
.feature__body { color: var(--ink); }

/* =============================================================================
   10. GRIGLIE E CARD
   ============================================================================= */
.grid {
  display: grid;
  grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr));
  gap: clamp(20px, 2.2vw, 32px) var(--gutter);
  align-items: start;
}
.grid--1, .grid--fixed-1 { --cols: 1; }
.grid--2, .grid--fixed-2 { --cols: 2; }
.grid--3, .grid--fixed-3 { --cols: 3; }
.grid--4, .grid--fixed-4 { --cols: 4; }
.grid--5, .grid--fixed-5 { --cols: 3; }
.grid--6, .grid--fixed-6 { --cols: 3; }
.grid--7, .grid--fixed-7 { --cols: 4; }
.grid--8, .grid--fixed-8 { --cols: 4; }
.grid--fixed-1 { max-width: 640px; }

/* Figma flaconi.png: nella fascia "Perche scegliere" il blocco titolo + prosa e' la
   PRIMA CELLA della griglia, non un'intestazione a tutta larghezza sopra le card */
.cards-band--head-inline .section__head {
  max-width: none;
  margin-bottom: 0;
  align-self: start;
  /* niente rientro: nel Figma l'H2 sta su due righe e la prima ("Perche' scegliere")
     e' larga 430px, cioe' quasi tutta la colonna da 449 */
  padding-right: 0;
}

/* Quante colonne prende la testata lo dice `head_span:` nella YAML, non il numero di
   card: flaconi e pilloliere ne hanno tre e i frame le impaginano diverso, e lo stesso
   vale per vasi contro airless e foamer, che ne hanno quattro.

   Testata su UNA colonna (Figma flaconi.png, airless.png, foamer.png): 449 + due card
   da 375x280, gap 37. Le card oltre la seconda vanno a capo sotto la testata e restano
   larghe 375, non si stirano sulla colonna. Le fr sommano lo spazio disponibile a
   --content 1273, quindi a 1920 escono le misure del frame. */
.cards-band--head-inline .grid {
  grid-template-columns: minmax(0, 449fr) minmax(0, 375fr) minmax(0, 375fr);
  column-gap: clamp(20px, 1.93vw, 37px);
}
/* Testata su DUE colonne (Figma vasi.png, pilloliere.png): tre colonne uguali, una
   sola card le sta a destra e le altre aprono la seconda riga.
   Il divario era 87px qui e 37 sulle altre tre pagine, perche' i due frame lo
   disegnano diverso. RICHIESTA CLIENTE 23/09: «in ogni pagina in cui compare questa
   composizione lo spazio tra i rettangoli sia uguale per tutti» — quindi 37 ovunque,
   ereditato dalla regola qui sopra. Le colonne restano quelle del frame (qui uguali,
   li' 449/375/375): cambia lo spazio, non la composizione. */
.cards-band--head-inline.cards-band--head-span-2 .grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.cards-band--head-inline.cards-band--head-span-2 .section__head { grid-column: span 2; }
/* RICHIESTA CLIENTE 23/09: «i blocchi di testo siano tutti allungati... tutti della
   stessa dimensione». Prima ogni card si fermava al proprio contenuto (280, 282, 308 e
   333 nella stessa fascia) perche' `height: auto` annullava il 100% di .card e la
   griglia allineava in alto: fedele al frame, ma a video i rettangoli erano di quattro
   misure diverse. Ora riempiono la colonna, e `grid-auto-rows: 1fr` pareggia anche le
   righe fra loro. La testata NON si stira: ha `align-self: start` poco sopra. */
.cards-band--head-inline .grid {
  align-items: stretch;
  grid-auto-rows: 1fr;
}
.cards-band--head-inline .card--icon {
  justify-self: stretch;
  width: 100%;
  min-height: 280px;
}

/* card generica */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: 100%;
  color: inherit;
  text-decoration: none;
}
.card > :last-child { margin-bottom: 0; }
.card p { color: var(--ink); font-size: var(--small); }
.card__title {
  margin: 0;
  color: var(--navy);
  font-size: var(--h4);
  font-weight: 700;
  line-height: 1.25;
}
/* I titoli dei "plus" delle pagine categoria stanno a 20px, non ai 23 di --h4:
   sono le cinque fasce .cards-band--icon (flaconi, vasi, pilloliere, airless,
   foamer). Il token resta com'e' per tutte le altre card. */
.cards-band--icon .card__title { font-size: 20px; }
.card__icon { width: 34px; height: 34px; margin-bottom: 4px; color: var(--accent); }
/* card con icona delle pagine categoria (Figma vasi.png, airless.png, foamer.png,
   pilloliere.png, flaconi.png): il disegno del cliente sta alla sua misura nativa
   (44x47, 47x58, 63x60, 83x61...), non dentro un quadrato di 34. Misurato sul
   frame vasi.png: "Varieta di materiali" e' 45x56 a 34px dal bordo della card. */
.card--icon .card__icon {
  align-self: flex-start;
  width: auto;
  height: auto;
  max-width: 100%;
  margin-bottom: 10px;
}
.card--icon .card__icon svg { width: auto; height: auto; max-width: 100%; }
/* il disegno di categoria e' navy in tutti i frame (misurato #103B5E su packaging.png,
   vasi.png, airless.png, foamer.png), anche dentro il pastiglione in tinta: non segue
   l'accento di pagina, che su packaging e' .theme-cipria e lo farebbe rosa.
   Sulle tile cipria resta bianco: la regola piu' sotto ha la stessa specificita'
   e vince perche' viene dopo. */
.card__icon[class*="icon--cat-"] { color: var(--navy); }
/* Icone editoriali esportate dal cliente (static/icons/<pagina>-<voce>.svg): ognuna
   ha la sua misura nei frame — flaconi 72x60, 59x79, 83x61, vasi 44x47..63x60, e cosi'
   via — quindi niente box quadrato. Poggiano tutte sulla stessa linea, a 111px dal
   bordo alto della card (32 di padding + 79 di area icona). L'area vale quanto l'icona
   piu' alta delle ventisei (flaconi-accessori-chiusure, 59x79): i 96px di prima ne
   sprecavano 17, che sono esattamente quelli che tenevano la card a 297 invece che ai
   280 dichiarati. La tinta e' --cipria
   #DAC6C5, non l'accento di pagina (--cipria-2). Vale per le cinque pagine categoria,
   che sono le uniche con la testata dentro la griglia. */
.cards-band--head-inline .card--icon .card__icon {
  align-self: flex-start;   /* nei frame l'icona e' a filo del testo, non centrata */
  align-items: flex-end;
  width: auto;
  height: 79px;
  margin-bottom: 14px;
  color: var(--cipria);
}
.cards-band--head-inline .card--icon .card__icon svg { width: auto; height: auto; }

/* le tre card "plus" delle pagine categoria: nel frame il testo e' corpo pieno
   (--body, 20px), non --small */
.cards-band--head-inline .card--icon p { font-size: var(--body); line-height: 1.3; }
/* interlinea 26 come nel frame (--lh-body 1.45 farebbe righe da 29 e la card
   crescerebbe oltre i 280 dichiarati) */
.card__cta { margin-top: auto; padding-top: 12px; }
.card__body { display: flex; flex-direction: column; gap: 10px; }

/* card con box bianco e icona */
.card--icon {
  padding: clamp(22px, 2.2vw, 32px);
  border: 1px solid var(--line-2);
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--sh-card);
  transition: box-shadow .2s ease, transform .2s ease;
}
/* sollevamento in hover con l'ombra grigia (--sh-img-hover), la stessa delle card
   prodotto del catalogo: quella blu di --sh-card-hover tingeva il bordo di navy */
.card--link:hover { box-shadow: var(--sh-img-hover); transform: translateY(-3px); text-decoration: none; }
.card--icon .link { margin-top: auto; padding-top: 10px; }

/* tile cipria (home: Flaconi / Vasi / Pilloliere / Airless) */
.card--cipria {
  min-height: 230px;
  padding: clamp(22px, 2.2vw, 30px);
  border-radius: var(--r-card);
  background: var(--cipria-2);
  /* Figma: sul box cipria testo, link e icona sono bianchi. Il contrasto e' 2,1:1,
     sotto la soglia AA: stessa scelta grafica gia' accettata per i titoli in tinta
     piena. Per tornare conforme basta rimettere var(--on-tint) su queste quattro regole. */
  color: var(--white);
  transition: box-shadow .2s ease, transform .2s ease;
}
.card--cipria .card__title,
.card--cipria .link { color: var(--white); }
.card--cipria p { color: var(--white); }
.card--cipria .card__icon { color: var(--white); }
.card--cipria:hover { box-shadow: var(--sh-img-hover); transform: translateY(-3px); text-decoration: none; }
.card--cipria .link { margin-top: auto; padding-top: 14px; }

/* Figma flaconi.png, fascia "Scopri tutti gli altri prodotti": tre tile 400x495
   con gap 40 e rientro interno 38 (sulla home la stessa fascia e' a quattro colonne
   e piu' bassa, per quello la misura sta sul grid--fixed-3). */
.cards-band--cipria .grid--fixed-3 { column-gap: clamp(20px, 2.08vw, 40px); }
.cards-band--cipria .grid--fixed-3 .card--cipria {
  min-height: 495px;
  padding: clamp(22px, 2vw, 38px);
}
/* dentro la tile da 495 il frame porta tutto piu' grande: icona appoggiata a 153px
   dal bordo alto (quindi area di 115 sotto il padding), titolo 40, testo 20, link 24 */
.cards-band--cipria .grid--fixed-3 .card__icon {
  align-self: flex-start;
  align-items: flex-end;
  width: auto;
  height: 115px;
}
/* altezze dell'icona misurate sui frame (flaconi.png, vasi.png, pilloliere.png):
   il disegno di ogni famiglia ha la sua, non sono normalizzate */
.cards-band--cipria .grid--fixed-3 .icon--cat-vaso svg       { width: auto; height: 62px; }
.cards-band--cipria .grid--fixed-3 .icon--cat-pilloliera svg { width: auto; height: 59px; }
.cards-band--cipria .grid--fixed-3 .icon--cat-airless svg    { width: auto; height: 102px; }
.cards-band--cipria .grid--fixed-3 .icon--cat-flacone svg    { width: auto; height: 106px; }
.cards-band--cipria .grid--fixed-3 .icon--cat-foamer svg     { width: auto; height: 106px; }
.cards-band--cipria .grid--fixed-3 .card__icon { margin-bottom: 37px; }  /* 59px fra base icona e titolo */
/* SCALA RIVISTA IL 24/09, su richiesta dell'utente: «i testi nei box rosa sono un po'
   troppo grandi rispetto al resto». Misurato su /packaging/vasi/ prima del cambio:
   titolo 30, testo 20, link 24, dentro una tile larga 398 — mentre nella STESSA pagina
   le card «perche' scegliere» hanno il titolo a 20 e quelle «scegli il materiale» a 23,
   e la STESSA fascia in homepage (quattro colonne) sta a 23/15/15.
   Il frame chiedeva ancora piu' grande (titolo 40, testo 20, link 24) e il titolo era
   gia' stato ridotto a --h3 in sviluppo: questo e' un secondo passo nella stessa
   direzione, deciso con l'utente e non una svista da correggere. Se un giorno la
   cliente rivuole la misura del Figma, il numero e' 40 sul titolo.
   Il titolo non ha piu' una regola sua: --h4 e' gia' la misura di .card__title, cioe'
   quella delle altre card della pagina. Testo e link stanno a --label, una tacca sopra
   la homepage, perche' qui la tile e' alta 495 e a 15 resterebbe vuota. */
.cards-band--cipria .grid--fixed-3 .card--cipria p { font-size: var(--label); line-height: 1.2; }
.cards-band--cipria .grid--fixed-3 .card--cipria .link { font-size: var(--label); }
/* nel frame la tile chiude con la sola scritta, senza la freccia di .link */
.cards-band--cipria .grid--fixed-3 .card--cipria .link::after { content: none; }

/* Fascia card della home, misurata su homepage.png a 1920.
   Titolo e introduzione sono in --cipria-2 #C3AEAD sul fondo --sand-3 #F7F5F5: il
   contrasto e' 1,9:1, sotto la soglia AA. E' la stessa scelta grafica gia' accettata
   per il testo bianco dentro le tile qui sotto, e nel frame e' cosi'. */
.page--home .cards-band--cipria .section__head h2,
.page--home .cards-band--cipria .section__head .prose { color: var(--cipria-2); }
/* L'introduzione deve arrivare a tutta la griglia: nel frame la riga piu' larga e'
   1251px. Non basta toglierle il max-width, perche' a stringerla era il contenitore:
   .section__head--center sta a 860. Va allargato quello, e il titolo ripreso a 860 per
   conto suo — a tutta griglia si spezzerebbe 1195/314, tagliando in due la coppia
   "dal contenitore / all'accessorio". A 860 chiude sui due punti come nel frame. */
.page--home .cards-band--cipria .section__head--center { max-width: none; }
.page--home .cards-band--cipria .section__head--center .prose { max-width: none; }
.page--home .cards-band--cipria .section__head--center h2 {
  max-width: 860px;
  margin-inline: auto;
}
/* tile 300x375 (nel frame 302x374). Le quattro colonne sono fisse a 300 e
   space-between ricava il vuoto dalla griglia: (1273 - 1200) / 3 = 24px, per questo
   column-gap parte da zero invece che da --gutter. */
.page--home .cards-band--cipria .grid {
  grid-template-columns: repeat(4, 300px);
  justify-content: space-between;
  column-gap: 0;
}
/* Il contenuto della tile parte piu' in basso: nel frame l'icona attacca a 72px dal
   bordo alto contro i 30 di padding di tutte le altre card, e sotto resta 37 di aria.
   Misurato sulla tile "Pilloliere" di homepage.png (x 975-1277, y 2439-2813). */
.page--home .cards-band--cipria .card--cipria {
  min-height: 375px;
  padding-top: clamp(30px, 3.75vw, 72px);
}

/* Sfalsamento verticale delle tile (home). `translate`, NON `transform`: la
   proprieta' indipendente si COMPONE con transform invece di litigarci, e qui
   due cose litigavano davvero (misurate in browser il 2026-09-17).
   1. La comparsa allo scroll anima `transform` e finisce su `none`: durante
      l'ingresso le tile pari perdevano lo scalino e la riga si appiattiva, poi a
      fine animazione ricadevano di 28px una dopo l'altra, con uno scatto.
   2. il sollevamento al passaggio del mouse, che su .card--cipria:hover vale
      translateY(-3px), e' meno specifico di questa regola: sulle tile pari non
      avveniva affatto (misurato: 0px invece di 3).
   Con `translate` lo scalino resta il fondo su cui gli altri movimenti si
   sommano: l'ingresso atterra sulla posizione giusta e l'hover solleva da li'. */
.page--home .cards-band--cipria .grid > *:nth-child(even) { translate: 0 28px; }
.page--home .cards-band--cipria .grid { margin-bottom: 28px; }

/* Figma flaconi.png "Flaconi per ogni esigenza": la testata centrata usa tutta la
   colonna (titolo su 2 righe, riga piu' larga 1104px; prosa su 3 righe, 1244px),
   e sotto la foto nome e pulsante sono centrati. */
.cards-band--photo .section__head--center,
.cards-band--photo .section__head--center .prose { max-width: none; }
/* l'introduzione di questa fascia e' corpo pieno: con --body a 20px le tre righe
   tornano larghe 1244/1106/268 px come nel frame */
.cards-band--photo .section__head--center .prose { font-size: var(--body); }
.cards-band--photo .card--photo .card__title,
.cards-band--photo .card--photo .card__cta { text-align: center; }

/* Le card foto misurano 404 con gap 32 in tutti i frame (flaconi, vasi, pilloliere,
   airless, foamer). Quando sono una o due — pilloliere ne ha due, airless e foamer
   una — non si allargano: restano 404 e la riga si centra, come nei frame. */
.cards-band--photo .grid {
  grid-template-columns: repeat(var(--cols), minmax(0, 404px));
  justify-content: center;
  column-gap: clamp(20px, 1.67vw, 32px);
  max-width: none;
}

/* `media_focus:` sulla singola card della YAML. Regola di base a specificita' minima
   (0,1,1): le varianti qui sotto non dichiarano object-position, quindi la ereditano,
   mentre la compensazione di `photo_align: side` — che e' `img[srcset]` dentro due
   classi in piu' — continua a vincere. Senza valore vale `center`: nessun cambio di resa. */
.card__media img { object-position: var(--media-focus, center); }

/* card con foto */
.card--photo .card__media,
.card--tile .card__media {
  margin-bottom: 6px;
  border-radius: var(--r-img);
  overflow: hidden;
  background: var(--surface-2);
}
.card--photo .card__media img,
.card--tile .card__media img {
  width: 100%;
  aspect-ratio: 4 / 4.6;
  object-fit: cover;
  transition: transform .35s ease;
}
/* `photo_align: side` nella YAML. Le foto SEGNAPOSTO delle sottocategorie sono
   orizzontali (3:2) dentro un box verticale (4:4.6): il ritaglio taglia comunque i lati,
   la dichiarazione sceglie quale meta' resta. Nei frame flaconi.png, vasi.png e
   pilloliere.png il prodotto non sta al centro del box ma di lato, appoggiato al bordo
   destro, con la luce del fondo a sinistra: ancorare il ritaglio a sinistra tiene il
   primo 58% della sorgente e il prodotto, che in quelle foto sta fra il 21% e il 91%,
   scivola a destra e sborda. Il frame del foamer invece centra il suo unico prodotto,
   e resta com'e'.
   La compensazione vale SOLO per i segnaposto cotti dal build, riconoscibili dal
   `srcset` che il build timbra su ogni <img> agganciato: quando l'admin lega una foto
   diversa, il binder (pages-binding.js, setPfImage) toglie `srcset` e `sizes`, e la
   foto del cliente — gia' ritagliata nel formato del box, 404x466 come il frame — deve
   rendere a `cover` pieno, senza zoom ne' spostamento. Misurato sullo staging il
   2026-09-15 con lo zoom ancora applicato alle foto dell'admin: nel box 403x463 la
   foto occupava 451x519 spostata di 56 px verso l'alto, e il flacone usciva dal bordo
   destro. Se il binder smettesse di togliere `srcset`, lo zoom tornerebbe anche sulle
   foto del cliente: e' questa la dipendenza da tenere d'occhio a ogni sync del template. */
.cards-band--photo-side .card--photo .card__media img[srcset] {
  object-position: left center;
  /* `left` e' gia' il bordo sinistro della sorgente: per spostare il prodotto ancora
     piu' di lato bisogna stringere il ritaglio, non muoverlo. La scala e' ancorata a
     sinistra in basso perche' in queste foto il prodotto poggia sul bordo inferiore ed
     e' li' che va tenuto: cresce verso destra e verso l'alto, dove ha aria. */
  transform: scale(1.12);
  transform-origin: left bottom;
}
/* lo zoom dell'hover parte da 1.12, non da 1. Senza questa riga vincerebbe l'hover
   generico piu' sotto: stessa specificita' ma scritto dopo, riporterebbe la foto a
   scale(1.03) e il prodotto tornerebbe indietro di scatto al passaggio del mouse.
   Le foto dell'admin (senza `srcset`) prendono l'hover generico a 1.03 come ogni
   altra card con foto. */
.cards-band--photo-side .card--photo:hover .card__media img[srcset] { transform: scale(1.155); }
.card--photo:hover .card__media img,
.card--tile:hover .card__media img { transform: scale(1.03); }
/* RICHIESTA CLIENTE 23/09 («rendere anche le tre foto cliccabili... ora possiamo
   cliccare solo la scritta»): il bersaglio diventa l'intera card. Stessa tecnica di
   .card--row: si stende uno pseudo-elemento del pulsante, che RESTA l'unico <a> —
   cosi' la destinazione e' un vero href su un vero <a>, che e' cio' che permette al
   pannello di renderla modificabile (data-pf-href vive solo su un `kind: cta`).
   Fra il pulsante e la card non c'e' nessun antenato posizionato: .card e'
   `position: relative` e .card__media non e' posizionata, quindi `inset: 0` copre
   davvero tutta la card — e' la trappola che su .card--row costo' una misura. */
.card--photo .card__cta .btn::before { content: ""; position: absolute; inset: 0; z-index: 2; }
/* CORREZIONE 24/09 — qui il pulsante NON si solleva al passaggio del mouse, e non e'
   un vezzo tolto per distrazione. `transform` fa dell'elemento il BLOCCO CONTENITORE
   dei suoi discendenti in posizione assoluta: con il `translateY(-1px)` di `.btn:hover`
   lo pseudo-elemento steso della riga sopra smetteva di essere ancorato alla card e si
   ritirava sulla pillola. Il puntatore, che sta sulla foto, restava fuori: l'hover
   cadeva, il transform spariva, lo pseudo si ristendeva sotto il puntatore e l'hover
   tornava. Misurato sullo staging il 24/09 col mouse FERMO al centro della foto:
   39 cambi di stato su 39 frame, ombra lampeggiante, e il bersaglio del clic che
   alternava fra il link e l'immagine a ogni frame.
   Vale anche per `:active`, che dichiara `translateY(0)`: non sposta niente ma e'
   pur sempre un transform e crea lo stesso blocco contenitore, cosi' fra mousedown e
   mouseup il bersaglio poteva cambiare e il clic sulla foto non apriva la pagina.
   Perche' la stessa tecnica su `.card--row` non ha mai dato problemi: li' l'hover e'
   `opacity: .72`, che crea un contesto di impilamento ma NON un blocco contenitore.
   Il ritorno visivo resta: l'ombra del pulsante e lo zoom della foto a 1.03. Se un
   giorno serve di nuovo un sollevamento, va messo sulla CARD, mai sull'elemento che
   porta lo pseudo-elemento steso. */
.card--photo .card__cta .btn:hover,
.card--photo .card__cta .btn:active { transform: none; }
.card--tile a { display: flex; flex-direction: column; gap: 10px; height: 100%; }
.card--tile a:hover { text-decoration: none; }

/* card a rivelazione: a riposo solo la foto, in hover il pannello bianco
   -----------------------------------------------------------------------------
   Figma Chiusure.jpg: la griglia delle tipologie e' una scacchiera di sole foto.
   In hover il pannello bianco con titolo, testo e "Scopri di piu'" SOSTITUISCE la foto
   nello stesso box (non e' un pannello che si apre sotto): la griglia non si muove e le
   righe restano quelle del frame. Si apre anche col focus da tastiera. */
.card--reveal { position: relative; }
.card--reveal > a { display: block; }
.card--reveal > a:hover { text-decoration: none; }
.card--reveal .card__media {
  border-radius: var(--r-img);
  overflow: hidden;
  background: var(--surface-2);
}
.card--reveal .card__media img {
  width: 100%;
  /* Il frame a 1920 le disegna 408x462, verticali. RICHIESTA CLIENTE 23/09: «le foto di
     anteprima sono molto grandi, quindi e' difficile vedere tutte le categorie di
     accessori» — con due righe da 465 la seconda restava sotto la piega. Riquadro
     abbassato a 408x320: le due righe stanno insieme nello schermo e il soggetto,
     centrato e in `cover`, resta dentro. Il pannello che si apre in hover ha `inset: 0`
     e segue la stessa misura: sotto i 300 il suo testo comincia a non entrare. */
  aspect-ratio: 408 / 320;
  object-fit: cover;
}
/* niente zoom: in hover la foto viene coperta dal pannello, non ingrandita */
.card--reveal .card__panel {
  position: absolute;
  inset: 0;                     /* stesso box della foto: e' una sostituzione, non un pannello sotto */
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(24px, 1.93vw, 37px);
  border-radius: var(--r-img);
  background: var(--surface);
  /* solo opacita': con visibility:hidden il testo uscirebbe anche dall'albero di
     accessibilita', e la tile resterebbe un link il cui nome e' solo l'alt della foto.
     Cosi' titolo, descrizione e "Scopri di piu'" restano leggibili allo screen reader
     e ai crawler anche quando non si vedono. */
  opacity: 0;
  transition: opacity .22s ease;
}
.card--reveal:hover .card__panel,
.card--reveal:focus-within .card__panel { opacity: 1; }
.card--reveal .card__title {
  margin: 0 0 clamp(14px, 1.2vw, 23px);
  /* tinta d'accento della pagina, non il rosa fisso: su chiusure e altri-accessori
     (.theme-beige) diventa #DBC1AE come chiesto, altrove resta --cipria-2 */
  color: var(--accent);
  font-size: var(--h3);
  line-height: 1.2;
}
.card--reveal .card__panel p { margin: 0 0 clamp(18px, 1.56vw, 30px); }
.card--reveal .link { align-self: flex-start; color: var(--accent); font-size: var(--body); }
/* la freccia del pannello e' quella cerchiata dei pulsanti, non la freccia nuda */
@supports ((-webkit-mask-image: url("../icons/arrow-circle.svg")) or (mask-image: url("../icons/arrow-circle.svg"))) {
  .card--reveal .link::after {
    width: 1.6em;
    height: 1.6em;
    -webkit-mask-image: url("../icons/arrow-circle.svg");
    mask-image: url("../icons/arrow-circle.svg");
  }
}
/* la griglia di sole foto respira piu' delle tile con titolo: 45px fra le righe */
.cards-band--reveal .grid { row-gap: clamp(28px, 2.34vw, 45px); }
/* touch: senza puntatore fine l'hover non esiste mai. Li' il pannello sta in
   flusso sotto la foto, sempre aperto: la tile non puo' restare una foto muta. */
@media (hover: none) {
  .card--reveal .card__panel {
    position: static;
    margin-top: 12px;
    padding: 0;
    border-radius: 0;
    background: none;
    opacity: 1;
  }
  .card--reveal .card__panel p { margin-bottom: 10px; }
}
.card--empty { opacity: .72; }
.card--empty .card__title::after {
  content: " ";
  display: inline;
}

/* card riga: foto e testo affiancati, alternati */
/* riga della hub (Figma packaging.png): foto 824 + card bianca 470 affiancate,
   senza spazio fra loro, ognuna con i propri angoli; il blocco e' alto 451 a 1920 */
.cards-band--row .grid { --cols: 1; gap: clamp(24px, 3vw, 58px); }
.card--row {
  display: grid;
  grid-template-columns: minmax(0, 824fr) minmax(0, 470fr);
  align-items: stretch;
  gap: 0;
  /* altezza fissa: con min-height la foto (che ha un suo rapporto intrinseco)
     alzava la riga oltre i 450 e ogni fascia veniva di un'altezza diversa */
  height: 450px;
  padding-block: 0;
}
/* la foto sborda sotto la card bianca e resta in secondo piano: i due angoli
   arrotondati non si affrontano piu' e sparisce lo stacco fra i due box */
.card--row { --row-overlap: clamp(40px, 5vw, 90px); }
.card--row .card__media {
  width: calc(100% + var(--row-overlap));
  border-radius: var(--r-img);
  overflow: hidden;
}
.card--row .card__body { z-index: 1; }
.card--row .card__media { position: relative; z-index: 0; }
/* riga invertita: card stretta a sinistra, foto larga a destra che sborda a sinistra */
.card--row-reverse { grid-template-columns: minmax(0, 470fr) minmax(0, 824fr); }
.card--row-reverse .card__media { margin-left: calc(-1 * var(--row-overlap)); }
.card--row .card__media img {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;                 /* l'altezza la fissa la fascia (450px) */
  object-fit: cover;
  transition: transform .35s ease;    /* come .card--photo e .card--tile: senza, lo zoom scatta */
}
/* La card e' un <a> per intero (macro `row`, stessa forma delle cipria): due
   conseguenze da neutralizzare, entrambe ereditate da `a`.
   1. La regola di riga 238 sottolinea i link in hover e vince per specificita' su
      `.card`, quindi sottolineerebbe titolo e testo al passaggio del mouse.
   2. Il ritorno visivo e' lo zoom della foto, non l'ombra: `.card--row` e' per due
      terzi fotografia e `.card__media` ha gia' overflow hidden piu' raggio, quindi lo
      zoom resta dentro l'angolo. Un'ombra disegnerebbe invece un rettangolo attorno a
      un contenitore trasparente alto 450px, tagliando la foto che sborda. */
/* Tutta la card porta alla categoria, ma il link RESTA l'<a class="link">: si
   stende un suo pseudo-elemento sopra l'intera card. Cosi' il bersaglio e'
   grande quanto la card e la destinazione e' un vero href su un vero <a> —
   che e' cio' che permette al pannello di renderla modificabile.
   `::before` e non `::after`: l'after e' gia' la freccia del Figma (riga 525).
   z-index 2 perche' .card--row .card__body sta a 1 e coprirebbe lo pseudo. */
.card--row { position: relative; }
.card--row .card__body .link::before { content: ""; position: absolute; inset: 0; z-index: 2; }
.card--row:hover .card__media img { transform: scale(1.03); }
.card--row .card__body {
  justify-content: center;
  gap: 14px;
  padding: clamp(24px, 3vw, 48px);
  border-radius: var(--r-img);
  background: var(--white);
  box-shadow: var(--sh-card);
}
/* icona di categoria dentro il pastiglione in tinta (Figma: accento al 20% sul bianco) */
.card--row .card__icon {
  width: 66px;
  height: 66px;
  margin-bottom: 6px;
  /* nel Figma (packaging.png) il pastiglione e' 66x66 e il disegno ci sta dentro
     alla misura nativa: il piu' alto e' il foamer con 46px, quindi 10 di margine */
  padding: 10px;
  border-radius: var(--r-pill);
  background: var(--sand-2);
  background: color-mix(in srgb, var(--accent) 20%, #fff);
}
.card--row-reverse .card__media { order: 2; }
.card--row-reverse .card__body { order: 1; }
.card--row .card__title { font-size: var(--h3); }
.card--row .link { color: var(--accent); }   /* Figma: CTA nella tinta della pagina */
.card--row p { font-size: var(--body); }

/* =============================================================================
   11. PUNTI E CHECKLIST
   ============================================================================= */
/* Nel frame le quattro colonne hanno passo ~341 su una colonna di 1295: la
   colonna e' larga ~271 e la gronda ~70, non i 20 del gutter standard. */
.cards-band--point .grid { column-gap: clamp(24px, 3.65vw, 70px); }
.point {
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: 100%;
}
/* Figma settori-cosmetico.png / -alimentare.png / -erboristico.png: il glifo sta
   da solo nella tinta della pagina, senza pastiglione (misurati 25x50, 29x51,
   34x50 e 34x30: disegni di proporzioni diverse, quindi altezza fissa e larghezza
   libera, mai stirati). Anche il titolo e' nella tinta, non navy. */
.point__icon {
  /* .icon e' inline-flex centrato: dentro la colonna flex di .point si stirerebbe
     a tutta larghezza e il glifo finirebbe al centro invece che a filo sinistro */
  align-self: flex-start;
  width: auto;
  height: 50px;
  padding: 0;
  border-radius: 0;
  background: none;
  color: var(--accent);
}
.point__icon svg { width: auto; height: 100%; max-width: 100%; }
.point__title { margin: 6px 0 0; color: var(--accent); font-size: var(--h4); }
/* 18px fissi (richiesta cliente): nel Figma il testo del punto occupa 5 righe
   nella colonna, con --small (15px) ne bastavano 4 */
.point p { color: var(--ink); font-size: 18px; }
.point__cta { margin-top: auto; padding-top: 12px; }

.checklist {
  margin: 0 0 1em;
  padding: 0;
  list-style: none;
}
.checklist li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 10px;
  color: var(--ink);
  font-size: var(--small);
}
.checklist .icon {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 4px;
  color: var(--accent);
}
.highlights { margin-top: clamp(18px, 2vw, 28px); }
/* Home: i due punti forti e le loro spunte sono in --cipria-2 #C3AEAD (misurato su
   homepage.png), non nel grigio del testo con la spunta d'accento. Vale solo qui:
   su sostenibilita il frame rende gli stessi highlights come card verdi. */
.page--home .highlights li,
.page--home .highlights .icon { color: var(--cipria-2); }
/* e a corpo pieno: 20px come il resto del sito, non i --small della checklist */
.page--home .highlights li { font-size: 20px; }

/* =============================================================================
   12. CATALOGO: filtri, griglia prodotti, contatore, stato vuoto
   ============================================================================= */
/* come le fasce a card: la testata del catalogo usa tutta la colonna. Nel Figma
   (settori-cosmetico.png) "Packaging cosmetico per ogni tipologia di prodotto" e'
   largo 1077px su UNA riga e l'introduzione arriva a 1180: con il tetto di 900px
   di .section__head il titolo andava a capo e la prosa si fermava a 805. */
.band--catalog .section__head { max-width: none; margin-bottom: clamp(22px, 2.4vw, 34px); }
.band--catalog .section__head .prose { max-width: none; }
/* il titolo del catalogo e' piu' piccolo dell'h2 standard: nel Figma la "P" misura
   28px di altezza contro i 35 dell'h2 di packaging.png (che vale --h2 = 50).
   40px e' quello che tiene "Packaging cosmetico per ogni tipologia di prodotto"
   su una riga sola, come nel frame. */
.band--catalog .section__head h2 { font-size: clamp(28px, 2.08vw, 40px); }
/* Sottocategorie: il catalogo E' la fascia principale della pagina, e il suo titolo
   torna alla misura piena dell'h2 (50 a 1920); i 40 qui sopra restano ai settori,
   dove il frame vuole il titolo su una riga. La fascia impilata che segue nell'area
   accessori («Applicatori compatibili con i flaconi Ho.Bag», layout stack, modello
   unico dell'area) scende a quella misura: cosi' il catalogo sta sopra e i
   «prodotti da associare» sotto. Richiesta della cliente del 25/09: «"Catalogo
   prodotti" e' piu' piccolo del titolo relativo ai prodotti da associare e non va
   bene». Vale per tutte le sottocategorie, chiusure e altri accessori: sono lo
   stesso modello. La misura sotto i 767 sta nel blocco responsive. */
body.page--subcategory .band--catalog .section__head h2 { font-size: var(--h2); }
body.page--subcategory .media-text--stack .media-text__body h2 { font-size: clamp(28px, 2.08vw, 40px); }

.filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 16px 20px;
  margin-bottom: clamp(24px, 2.8vw, 40px);
}
.filters__groups {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 20px;
  margin: 0;
  padding: 0;
  border: 0;
}
.filters__reset {
  padding: 12px 20px;
  border-radius: var(--r-pill);
  color: var(--grigio-1);
  font-size: var(--small);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.filters__reset:hover { color: var(--navy); }

/* Parti del pannello laterale dei filtri (macro catalog_filters): sul desktop non
   esistono. Il pulsante «Filtri», la testata del pannello e «Mostra N prodotti» si
   accendono solo nel blocco (max-width: 767px) and (scripting: enabled) piu' sotto;
   l'involucro delle azioni si dissolve, cosi' «Azzera i filtri» resta un fratello
   delle tendine, come prima. */
.filters-toggle,
.filters__head,
.filters__apply { display: none; }
/* lo sfondo del pannello (un div che main.js aggiunge in fondo al body) esiste solo
   dentro la regola del telefono: fuori era un blocco statico senza stile, e col
   pannello aperto il passaggio da 767 a 768 portava Chrome in fondo alla pagina
   (scrollY 246 -> 7901, verifica del 25/09) */
.filters-backdrop { display: none; }
.filters__actions { display: contents; }

.filter { position: relative; min-width: 220px; }
.filter__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 14px 20px;
  border: 1px solid var(--field-line);
  border-radius: var(--r-pill);
  background: var(--white);
  color: var(--grigio-1);
  font-size: var(--small);
  font-weight: 500;
  cursor: pointer;
  list-style: none;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.filter__summary::-webkit-details-marker { display: none; }
.filter__summary::after {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  margin-right: 2px;
  border-right: 2px solid var(--navy);
  border-bottom: 2px solid var(--navy);
  transform: translateY(-2px) rotate(45deg);
  transition: transform .2s ease;
}
/* filtro aperto: bordo grigio, non navy (richiesta cliente, come l'hover) */
.filter[open] > .filter__summary { border-color: var(--grigio-2); box-shadow: var(--sh-card); }
.filter[open] > .filter__summary::after { transform: translateY(2px) rotate(225deg); }
.filter__label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.filter__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--navy);
  color: var(--white);
  font-size: 12px;
  font-weight: 700;
}
.filter__options {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: max-content;
  min-width: 100%;
  max-width: calc(100vw - 2 * var(--page-pad));
  max-height: 320px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--white);
  box-shadow: var(--sh-panel);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.filter__option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 8px;
  color: var(--grigio-1);
  font-size: var(--small);
  cursor: pointer;
}
/* hover di una voce del filtro aperto: lo stesso grigio chiaro delle tendine del
   menu, senza virare il testo al navy (richiesta cliente) */
.filter__option:hover { background: var(--menu-hover); }
.filter__option input {
  flex: none;
  width: 17px;
  height: 17px;
  accent-color: var(--navy);
}
.filter__option input:checked + span { color: var(--navy); font-weight: 600; }

.catalog__count {
  margin: 0 0 18px;
  color: var(--grigio-2);
  font-size: var(--small);
  font-weight: 500;
}
.catalog__empty {
  margin: 24px 0 0;
  padding: 28px 30px;
  border: 1px dashed var(--line);
  border-radius: var(--r-card);
  background: var(--white);
  color: var(--grigio-1);
  text-align: center;
}

/* Riga sopra la griglia: il contatore a sinistra e, solo sul telefono, l'interruttore
   «un prodotto per riga / due per riga» a destra (richiesta della cliente del 25/09).
   Lo stato lo tiene main.js (initGridSwitch, localStorage) mettendo
   .product-grid--cols-1 sulla griglia; il pulsante attivo porta aria-pressed. */
.catalog__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 18px;
}
.catalog__bar .catalog__count { margin: 0; }
.grid-switch { display: none; gap: 4px; }
.grid-switch__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--field-line);
  border-radius: 10px;
  background: var(--white);
  color: var(--grigio-2);
  transition: border-color .18s ease, color .18s ease;
}
.grid-switch__btn[aria-pressed="true"] { border-color: var(--navy); color: var(--navy); }
.grid-switch__btn .icon { width: 18px; height: 18px; }

.product-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(24px, 2.6vw, 38px) var(--gutter);
  align-items: start;
}
/* correlati in fondo alla scheda prodotto: 4 colonne (Figma prodotto-alpha.png) */
.product-grid--compact { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* catalogo stretto: 5 colonne sulla colonna di contenuto, box immagine 240x267 e
   titolo centrato sotto, senza descrizione ne' "Scopri di piu'". Nasce sui settori
   (Figma settori-cosmetico.png / -alimentare.png / -erboristico.png) e vale ovunque
   un frame chieda quella griglia: le card stanno a 315/577/839/1101/1363, le stesse
   coordinate di "Chiusure - applicatori.jpg". Lo dichiara la pagina, non l'area. */
.product-grid--slim { grid-template-columns: repeat(5, minmax(0, 1fr)); }

.product-card { position: relative; }
.product-card > a {
  display: flex;
  flex-direction: column;
  gap: 8px;
  height: 100%;
  color: inherit;
  text-decoration: none;
}
.product-card > a:hover { text-decoration: none; }
.product-card img {
  width: 100%;
  aspect-ratio: 1 / 1.06;
  padding: 16px;
  border-radius: var(--r-img);
  background: var(--white);
  object-fit: contain;
  transition: box-shadow .2s ease, transform .2s ease;
}
.product-card > a:hover img { box-shadow: var(--sh-img-hover); transform: translateY(-3px); }
.product-card h3 {
  margin: 8px 0 0;
  color: var(--navy);
  font-size: var(--label);
  font-weight: 700;
}
.product-card p {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  margin: 0;
  overflow: hidden;
  color: var(--ink);
  font-size: 14px;
  line-height: 1.4;
}
.product-card .link { margin-top: 2px; color: var(--cipria-2); font-size: 14px; }
/* "Scopri di piu'" in hover: --navy-2, lo stesso blu dell'hover del pulsante
   "Iscriviti" (.btn--blu:hover) indicato dal cliente. Senza opacity:1 vince la
   velatura di `a:hover > .link` (.72) e il blu si legge slavato. */
.product-card > a:hover .link { color: var(--navy-2); opacity: 1; }
/* etichetta di famiglia ("Tappi a vite"): dentro il box immagine, in alto a
   sinistra (richiesta cliente). Il contenitore e' .product-card, gia' relative. */
.product-card__label {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 1;
  padding: 4px 12px;
  border-radius: var(--r-pill);
  background: var(--sand);
  color: var(--cipria-2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
}
/* Correlati: la foto RIEMPIE il riquadro, non ci sta dentro con un bordo bianco
   (richiesta della cliente del 25/09, «sia qui che sul desktop le immagini non devono
   essere boxate dentro a un quadrante ma questo quadrante deve essere riempito
   dall'immagine stessa»): riquadro 1:1, niente padding, `cover`. Le foto prodotto sono
   648x545 col soggetto al centro su fondo chiaro: il taglio ai lati (16%) non tocca il
   prodotto. Vale per le card dei correlati-prodotto e per quelle dei correlati per
   categoria (.product-card--cat, stessa griglia). Il catalogo resta a `contain`. */
.product-card--compact img,
.band--related .product-card img { aspect-ratio: 1 / 1; padding: 0; object-fit: cover; }
.product-card--compact h3 { font-size: var(--small); }
/* card del catalogo stretto: box 240x267 e nome centrato sotto (Figma settori-*.png,
   "Chiusure - applicatori.jpg").
   Stanno qui e non accanto a .product-grid--slim: hanno la stessa specificita' di
   .product-card img, quindi devono venire dopo per vincere la cascata. */
.product-card--slim img { aspect-ratio: 240 / 267; padding: 12px; }
.product-card--slim h3 { font-size: var(--small); text-align: center; }
.product-card[hidden] { display: none !important; }

/* =============================================================================
   13. SCHEDA PRODOTTO: intestazione, galleria, tab, tabella specifiche
   ============================================================================= */
.product-head {
  display: grid;
  grid-template-columns: minmax(0, .92fr) minmax(0, 1fr);
  align-items: start;
  gap: clamp(28px, 3.6vw, 64px);
}
.product-head .prose { max-width: 46ch; }
.product-head h1 { margin-top: .2em; }

.gallery { display: flex; flex-direction: column; gap: 16px; }
.gallery__main {
  border-radius: var(--r-img);
  background: var(--white);
  overflow: hidden;
}
.gallery__main img {
  width: 100%;
  aspect-ratio: 1 / .85;
  padding: 24px;
  object-fit: contain;
}
.gallery__thumbs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.gallery__thumb-item { margin: 0; }
.gallery__thumb {
  display: block;
  width: 100%;
  padding: 8px;
  border: 1px solid var(--line-2);
  border-radius: 12px;
  background: var(--white);
  cursor: pointer;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.gallery__thumb img { width: 100%; aspect-ratio: 1 / .92; object-fit: contain; }
.gallery__thumb:hover { border-color: var(--cipria-2); }
.gallery__thumb[aria-current="true"],
.gallery__thumb[aria-pressed="true"] { border-color: var(--navy); box-shadow: var(--sh-card); }

/* tab informazioni tecniche / dimensioni / MOQ / documenti */
.tabs {
  margin-top: clamp(36px, 4vw, 64px);
  border: 1px solid var(--line-2);
  border-radius: var(--r-card);
  background: var(--white);
  overflow: hidden;
}
.tabs__list {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
}
/* Linguette a segmenti: filo #EDEDED e nessun riempimento. I -1px tolgono il
   raddoppio del bordo fra due tab adiacenti, cosi la linea di giunzione resta di
   1px sola. La linguetta attiva passa al bianco e si salda al pannello. */
.tabs__tab {
  flex: 1 1 auto;
  display: block;
  margin-left: -1px;
  padding: 18px 22px;
  border: 1px solid #EDEDED;
  background: none;
  color: var(--grigio-2);
  font-size: var(--small);
  font-weight: 600;
  text-align: center;
  white-space: nowrap;
  transition: color .18s ease, background-color .18s ease;
}
.tabs__tab:first-child { margin-left: 0; }
.tabs__tab:hover { color: var(--navy); }
/* Linguetta attiva: la riga di apertura sul pannello e' rosa (--cipria-2), non piu'
   navy. Sta come box-shadow interna e non come border piu' spesso, cosi i 2px non
   rubano un pixel alla scatola e la linguetta non balla rispetto alle altre. */
.tabs__tab[aria-selected="true"] {
  background: var(--white);
  border-bottom-color: var(--cipria-2);
  box-shadow: inset 0 -2px 0 var(--cipria-2);
  color: var(--navy);
}
.tabs__panel { padding: clamp(24px, 2.6vw, 40px); }
.tabs__panel > :last-child { margin-bottom: 0; }
.tabs__panel img { border-radius: var(--r-img); }
/* MOQ e Documenti sono testo corrente, non tabelle: corpo a 15px */
.tabs__panel[id$="-panel-moq"],
.tabs__panel[id$="-panel-documenti"] { font-size: 15px; }
.tabs__panel[id$="-panel-moq"] .prose { font-size: inherit; }

.spec-table { width: 100%; font-size: var(--small); }
.spec-table th,
.spec-table td {
  padding: 14px 10px;
  border-bottom: 1px solid var(--line-2);
  text-align: left;
  vertical-align: top;
}
.spec-table th {
  width: 34%;
  color: var(--navy);
  font-weight: 600;
}
.spec-table td { color: var(--ink); }
/* I settori sono una RIGA della tabella dal 2026-09-18 (prima: <p class="product-sectors">
   sotto di essa). Sono link — un settore e' una pagina — e nella cella devono leggersi
   come tali: stessa convenzione di `.prose a`, navy + sottolineatura staccata. */
.spec-table td a { color: var(--navy); text-decoration: underline; text-underline-offset: 3px; }
.spec-table tr:last-child th,
.spec-table tr:last-child td { border-bottom: 0; }
.spec-table thead th {
  width: auto;
  color: var(--grigio-2);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.spec-table tbody th { width: 34%; }
.spec-table caption { margin-bottom: 12px; color: var(--grigio-2); text-align: left; }
.table-wrap { overflow-x: auto; }
.table-wrap + .table-wrap { margin-top: 20px; }

.doc-list { margin: 0; padding: 0; list-style: none; }
.doc-list li { margin-bottom: 12px; }
.doc-list a { display: inline-flex; align-items: center; gap: 10px; font-weight: 600; }

/* =============================================================================
   14. FAQ
   ============================================================================= */
/* Accordion FAQ — misure dal frame a 1920 (sources/figma/faq.png): card larga la
   colonna di contenuto con bordo 1px #E7E9ED e raggio 20, nessun riempimento (il
   fondo e' quello della pagina) e nessuna ombra da aperta; passo fra le card 34.
   Riga del summary alta 78: pastiglia numero 44 a 18 dal bordo, domanda a 78,
   icona 29 a 19 dal bordo destro. La risposta e' incolonnata sotto la domanda. */
.faq-list { display: flex; flex-direction: column; gap: clamp(16px, 1.77vw, 34px); }
.faq-list--numbered { margin: 0; padding: 0; list-style: none; }
/* niente margine sui <li>: l'elenco e' gia' un flex con `gap`, il margine lo
   raddoppiava (28px invece di 14 nella versione precedente) */
.faq-list--numbered > li { margin: 0; }

.faq {
  border: 1px solid #E7E9ED;
  border-radius: 20px;
  background: none;
}
.faq > summary {
  display: flex;
  align-items: center;
  gap: clamp(10px, .83vw, 16px);
  padding: clamp(12px, .89vw, 17px) clamp(14px, .99vw, 19px) clamp(12px, .89vw, 17px) clamp(14px, .94vw, 18px);
  cursor: pointer;
  list-style: none;
}
.faq > summary::-webkit-details-marker { display: none; }
/* pastiglia del numero: 44 di diametro, fondo cipria al 10% su --bg, cifra navy
   in tondo (nel frame non e' in grassetto) */
.faq__num {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(32px, 2.29vw, 44px);
  height: clamp(32px, 2.29vw, 44px);
  border-radius: var(--r-pill);
  background: #F0EAEA;
  color: var(--navy);
  font-size: clamp(15px, 1.04vw, 20px);
  font-weight: 400;
}
.faq__q {
  flex: 1 1 auto;
  color: var(--navy);
  font-size: clamp(17px, 1.25vw, 24px);
  font-weight: 700;
  line-height: 1.3;
}
/* cerchio sottile con la croce: nel frame e' identico su tutte le voci, aperte e
   chiuse, e qui e' riprodotto com'e'. Per farlo diventare un piu' quando la voce e'
   chiusa basta rimettere `transform: rotate(45deg)` qui e `rotate(0)` su .faq[open]. */
.faq__icon {
  flex: none;
  width: clamp(24px, 1.51vw, 29px);
  height: clamp(24px, 1.51vw, 29px);
  padding: clamp(5px, .42vw, 8px);
  border: 1px solid #727272;
  border-radius: var(--r-pill);
  color: #727272;
  transition: transform .22s ease, color .18s ease, border-color .18s ease;
}
/* Il segno esportato e' una croce sottile (icons/close-thin.svg). Nel frame la voce
   chiusa porta un piu' e quella aperta la croce: la croce girata di 45 gradi E' il
   piu', quindi si ruota da chiusa e si lascia dritta da aperta. In chiusura conta
   .faq--closing, perche' `open` sta ancora sul <details> fino a fine animazione. */
.faq__icon { transform: rotate(45deg); }
.faq[open] .faq__icon { transform: none; }
.faq.faq--closing .faq__icon { transform: rotate(45deg); }
.faq > summary:hover .faq__icon { color: var(--navy); border-color: var(--navy); }
/* risposta incolonnata sotto la domanda (78 a sinistra come a destra) */
.faq .prose {
  max-width: none;
  padding: 0 clamp(14px, 4.06vw, 78px) clamp(16px, 1.35vw, 26px);
  color: var(--ink);
  font-size: clamp(16px, 1.04vw, 20px);
  line-height: 1.3;
}
.faq-list:not(.faq-list--numbered) .prose { padding-left: clamp(14px, .94vw, 18px); }

/* Accordion delle fasce FAQ dentro le pagine di contenuto (misure da flaconi.png,
   confermate su vasi.png e airless.png): il box non e' bianco, e' solo un bordo 1px
   #E7E9ED sul fondo pagina; domanda 23px in --ink (non navy), risposta 18px con
   interlinea 22; voce chiusa alta 59, voce aperta 181, distanza fra le voci 26.
   Nella pagina FAQ l'elenco e' numerato e faq.png tiene la domanda navy su fondo
   bianco: quella non la tocca. */
.faq-list:not(.faq-list--numbered) { gap: 26px; }
.faq-list:not(.faq-list--numbered) .faq {
  border-color: #E7E9ED;
  background: transparent;
}
.faq-list:not(.faq-list--numbered) .faq[open] { box-shadow: none; }
/* Il summary tiene gli stessi rientri da chiusa e da aperta, cosi' la domanda non
   si sposta mai: nel frame la voce aperta ne ha 29 sopra invece di 13,5, ma quello
   e' un mockup fermo — nell'interazione significherebbe far scattare il titolo in
   alto a fine chiusura. I 15px di differenza li recupera il pannello, che e' quello
   che si anima: cosi' la voce aperta resta alta 181 e la chiusa 59 come nel frame. */
.faq-list:not(.faq-list--numbered) .faq > summary { padding: 13.5px 24px 13.5px 35px; }
.faq-list:not(.faq-list--numbered) .faq__q {
  color: var(--ink);
  font-size: 23px;
}
.faq-list:not(.faq-list--numbered) .faq__icon { color: var(--ink); border-color: currentColor; }
.faq-list:not(.faq-list--numbered) .faq[open] .faq__icon { color: var(--ink); border-color: currentColor; }
.faq-list:not(.faq-list--numbered) .faq > summary:hover .faq__icon { color: var(--navy); border-color: var(--navy); }

/* durante la chiusura animata l'attributo `open` e' ancora sul <details> (lo toglie
   il JS a fine corsa): la crocetta deve tornare subito un piu', non allo scatto */
.faq-list:not(.faq-list--numbered) .faq.faq--closing .faq__icon { transform: rotate(45deg); }
.faq-list:not(.faq-list--numbered) .prose {
  /* 12 sopra: sommati ai 13,5 di padding-bottom del summary danno gli stessi 31px
     di bianco fra domanda e risposta che misura il frame (prima erano 45) */
  padding: 12px 35px 29px;
  font-size: 18px;      /* qui il frame sta due punti sotto --body: righe da 22 */
  line-height: 1.22;
}

/* =============================================================================
   15. CTA BAND
   ============================================================================= */
.band--cta { padding-bottom: var(--band-pad); }
/* variante con foto (Figma packaging.png, faq.png, settori-*.png): foto full-bleed
   e pannello bianco che ne scavalca il bordo inferiore.

   LA FOTO FINISCE A META' DEL PANNELLO, a ogni larghezza (richiesta della cliente del
   25/09, su tutte le fasce foto + box CTA). Prima il pannello risaliva di una misura
   fissa (133px a 1920, 41 sulla FAQ) e l'incrocio cadeva dove capitava: sulla FAQ a
   un sesto del pannello, a 390 a un quarto. Un margine non puo' valere «meta' della
   propria altezza», una griglia si': tre righe — la parte di foto sopra il pannello
   (fissa, --cta-photo-top), poi due righe `auto` che il pannello occupa insieme. Una
   voce che attraversa due righe `auto` vuote le riempie in parti uguali (algoritmo di
   dimensionamento delle griglie, «distribute extra space»), quindi ognuna vale
   esattamente meta' pannello. La foto occupa le prime due righe: finisce sulla linea
   di mezzo. L'<img> e' in posizione assoluta dentro il suo riquadro, cosi' non
   contribuisce all'altezza delle righe (la sua altezza naturale le gonfierebbe).
   Il markup non cambia: il manifesto e il binder (setPfImage) vedono lo stesso <img>. */
.band--cta-photo {
  --cta-photo-top: clamp(240px, 33.7vw, 647px);   /* 780 - 133 a 1920: la stessa foto visibile di prima */
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: var(--cta-photo-top) auto auto;
  padding-top: 0;
}
.band--cta-photo > .band__media {
  grid-area: 1 / 1 / 3 / 2;
  position: relative;
  min-height: 0;
  overflow: hidden;
}
/* La foto della FAQ NEL BUNDLE (hobag-sito-faq-cta-1-*.webp, 1920x625) e' un ritaglio
   del frame Figma e porta nei suoi ultimi 41px il bordo alto del pannello bianco, piu'
   largo del pannello vero. Il vecchio pannello saliva di 41px esatti e lo copriva; con
   l'incrocio a meta' pannello la foto cresce e la striscia usciva ai lati. Si taglia
   il fondo di QUESTA foto (img piu' alta del riquadro del 7,5%, ancorata in alto: il
   7% sparisce sotto il bordo, la striscia e' il 6,6%) — la regola e' legata al nome
   del file, come il ritaglio di data-focus-img: se dal pannello arriva un'altra foto,
   non vale piu'. Il file non si tocca (optimize_media lo rigenererebbe uguale). */
.band--cta-photo .band__media img[src*="hobag-sito-faq-cta-1"] {
  height: 107.5%;
  object-position: 50% 0;
}
.band--cta-photo .band__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
}
.band--cta-photo > .container {
  grid-area: 2 / 1 / 4 / 2;
  position: relative;
  z-index: 1;
}
/* Pannello di chiusura: unico in tutto il sito, cambia solo la tinta (.theme-*
   da' --accent a titolo e bottone). Misure dal Figma a 1920, identiche in ogni
   frame (settori-cosmetico, servizi-produzione, flaconi, chiusure, faq,
   prodotto-alpha, altri-accessori): pannello 1292x241 sulla colonna di contenuto,
   testo a 72px dal bordo sinistro, pillola alta 57 centrata in verticale. */
.cta-band {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: none;
  align-items: center;
  gap: clamp(24px, 3vw, 56px);
  /* 241px a 1920: l'altezza non segue il testo, e' la stessa con una o due righe
     di titolo e con o senza paragrafo. Resta min- per non tagliare copy piu' lunghe. */
  min-height: clamp(150px, 12.55vw, 241px);
  padding: clamp(28px, 2.9vw, 56px) clamp(28px, 3.65vw, 70px);
  border-radius: var(--r-panel);
  background: var(--white);
  box-shadow: var(--sh-card);
}
.cta-band__body { min-width: 0; }
.cta-band__body > :last-child { margin-bottom: 0; }
/* nel frame titolo e seconda frase sono un blocco unico: stessa misura, stesso peso,
   stessa tinta e stesso ritmo di riga (35px a 1920), senza stacco fra i due */
.cta-band__title,
.cta-band h2 {
  /* stacco fra titolo e paragrafo: 29px fra gli ink nei frame settori-cosmetico.png
     e servizi-produzione.png, cioe' 22px di box (il resto lo mettono le due
     interlinee). Era 0 da quando la prosa era stilata come un secondo titolo.
     La FAQ, che nel suo frame ne ha 19, tiene il proprio .4em piu' sotto. */
  margin-bottom: .74em;
  color: var(--accent);
  font-size: var(--h3);
}
.cta-band__sub { margin-bottom: .6em; color: var(--grigio-1); font-weight: 500; }
/* Il testo sotto il titolo della CTA e' un paragrafo, non un secondo titolo:
   nei frame (settori-cosmetico.png, servizi-produzione.png, faq.png) l'ink delle
   sue righe misura 15-19px contro i 30 del titolo, cioe' corpo --body a peso
   normale, nella tinta della pagina. Prima ereditava --h3/700 e si leggeva come
   un occhiello. */
.cta-band .prose {
  /* colonna di 610px: la prima riga del paragrafo misura 604 su settori-cosmetico,
     593 su servizi-produzione e 593 su faq, cioe' la stessa in tutti i frame */
  max-width: 610px;
  color: var(--accent);
  font-size: var(--body);
  font-weight: 400;
  line-height: var(--lh-body);
}
.cta-band__actions,
.cta-band .band__cta { margin: 0; }
.cta-band > :first-child { margin-top: 0; }
.cta-band--tinted { background: var(--sand); }
/* La FAQ ha la sua misura: nel frame la foto e' alta 625 a 1920 e il pannello ci
   entrava per 41px. Resta la stessa parte di foto visibile sopra il pannello
   (625 - 41 = 584); l'incrocio, come ovunque, a meta' pannello. */
.page--faq .band--cta-photo { --cta-photo-top: clamp(220px, 30.4vw, 584px); }
/* ...e la sua seconda frase NON e' parte del titolo, come invece su packaging.png:
   nel frame e' un paragrafo di testo: corpo, peso e tinta stanno ora sulla regola
   base .cta-band .prose, perche' valgono su tutto il sito. */
.page--faq .cta-band__title { margin-bottom: .4em; }
/* la colonna a 610px non e' piu' una particolarita' della FAQ: vale in tutti i
   frame, quindi sta sulla regola base */

/* =============================================================================
   16. NEWS / BLOG / PAGINAZIONE
   ============================================================================= */
.news-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(24px, 2.6vw, 36px) var(--gutter);
  align-items: start;
}
.news-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Home: nel frame il titolo della fascia news sta su due righe (513 e 405px), non su
   una da 868. A 620 va a capo dove va a capo il frame, dopo "dal". Solo sulla home:
   il blog usa la stessa fascia con un titolo suo. */
.page--home .band--news h2 { max-width: 620px; }

.news-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: 100%;
  padding-bottom: 4px;
}
.news-card__media {
  margin-bottom: 6px;
  border-radius: var(--r-img);
  background: var(--surface-2);
  overflow: hidden;
}
.news-card__media img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  transition: transform .35s ease;
}
.news-card:hover .news-card__media img { transform: scale(1.03); }
.news-card__meta {
  margin: 0;
  color: var(--cipria-2);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.news-card__title {
  margin: 0;
  color: var(--navy);
  font-size: var(--h4);
  font-weight: 700;
  line-height: 1.28;
}
.news-card p { color: var(--ink); font-size: var(--small); }
.news-card .link { margin-top: auto; padding-top: 10px; }
/* fascia senza foto: tinta unita al posto dell'icona segnaposto (decisione cliente 2026-09-04) */
.img-tint { background: #EFEAE7; object-fit: cover; }
.news-card--placeholder { opacity: .78; }
.news-card--placeholder .news-card__media img { object-fit: contain; padding: 20px; }

.blog-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: clamp(26px, 3vw, 44px);
  padding: 0;
  list-style: none;
}
.blog-filters li { margin: 0; }

.article__meta {
  margin-bottom: 1.2em;
  color: var(--grigio-2);
  font-size: var(--small);
}
.article__body { max-width: 74ch; }
.article__body img { margin: 1.6em 0; border-radius: var(--r-img); }

.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: clamp(32px, 3.6vw, 56px) 0 0;
  padding: 0;
  list-style: none;
}
.pagination li { margin: 0; }
.pagination a,
.pagination span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  height: 42px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  color: var(--grigio-1);
  font-size: var(--small);
  font-weight: 600;
}
.pagination a:hover { border-color: var(--navy); color: var(--navy); text-decoration: none; }
.pagination [aria-current="page"] { background: var(--navy); border-color: var(--navy); color: var(--white); }

/* =============================================================================
   17. FORM, NEWSLETTER, CONTATTI, SEDI, MAPPA
   Markup: partials/_form-contatti.html.j2 (form.form-card > .field[data-field])
   e partials/_footer.html.j2 (form.newsletter__form).
   ============================================================================= */
.band--form > .container {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  gap: clamp(28px, 3.4vw, 56px);
}
/* mappa + modulo affiancati (pagina contatti): a 1920 la mappa e' 586, il modulo
   638, la gronda fra i due 71 (Figma contatti.png) */
.band--form > .container:has(.map-static) {
  grid-template-columns: minmax(0, 586fr) minmax(0, 638fr);
  column-gap: clamp(24px, 3.7vw, 71px);
  /* le due colonne pari in altezza: cosi il pulsante Maps, spinto in fondo alla
     colonna mappa, si allinea a "Invia richiesta", ultimo elemento del modulo */
  align-items: stretch;
}
.band--form .section__head { grid-column: 1 / -1; }
.band--form .form-card { max-width: none; }

.form-card {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 18px;
  width: 100%;
  max-width: 760px;
  padding: clamp(24px, 2.6vw, 36px);
  border: 1px solid var(--line-2);
  border-radius: var(--r-panel);
  background: var(--white);
  box-shadow: var(--sh-card);
}
.form-card > h2,
.form-card > h3,
.form-card > p,
.form-card > .prose,
.form-card > .btn,
.form-card > .hp,
.form-card .field--wide,
.form-card .field--consent { grid-column: 1 / -1; }

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > label {
  color: var(--navy);
  font-size: 14px;
  font-weight: 600;
}
.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 14px 18px;
  border: 1px solid var(--field-line);
  border-radius: var(--r-field);
  background: var(--field-bg);
  color: var(--grigio-1);
  font-size: var(--small);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.field textarea { min-height: 150px; resize: vertical; }
.field select { appearance: none; padding-right: 42px; }
.field input::placeholder,
.field textarea::placeholder { color: var(--grigio-2); opacity: .8; }
.field input:hover,
.field textarea:hover,
.field select:hover { border-color: var(--cipria-2); }
.field input:focus-visible,
.field textarea:focus-visible,
.field select:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 0;
  border-color: var(--navy);
}
.field.is-invalid input,
.field.is-invalid textarea,
.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"] { border-color: var(--bordeaux); }
.field__error { color: var(--bordeaux); font-size: 13px; font-weight: 500; }

.field--consent {
  flex-direction: row;
  align-items: flex-start;
  gap: 12px;
  margin-top: 2px;
}
.field--consent input {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 3px;
  padding: 0;
  accent-color: var(--navy);
}
.field--consent label {
  color: var(--ink);
  font-size: 13px;
  font-weight: 400;
  line-height: 1.45;
}
.field--consent a { color: var(--navy); text-decoration: underline; }

/* honeypot: fuori schermo, mai display:none (i bot lo compilano lo stesso) */
.hp {
  position: absolute !important;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-card__note,
.form__status {
  margin: 0;
  color: var(--grigio-1);
  font-size: 14px;
}
.form-card__note--error,
.form__status--error { color: var(--bordeaux); }
.form-card__note--ok,
.form__status--ok { color: #2F6B43; }
.form-card__required { color: var(--grigio-2); font-size: 13px; }
.form-card > .btn { justify-self: start; margin-top: 6px; }

/* --- modulo a pillole: pagina contatti (Figma contatti.png) -----------------
   Niente pannello: i campi sono pillole bianche su --bg, con l'icona a sinistra e
   l'etichetta usata come placeholder. La <label> resta nel DOM (fuori schermo): e'
   lei a dare il nome accessibile, il placeholder e' solo l'affordance visiva.
   Misure a 1920: pillola 636x62 a raggio pieno, icona 26 a 27 dal bordo, testo a 99,
   passo verticale 28; textarea 638x251 raggio 27 con il testo a 32/26; consenso
   checkbox 24 + testo 17/20,7; bottone 233x60. Il markup non cambia: la palette di
   campi e gli hook data-field restano quelli del contratto §3.1. */
.form-card--pill {
  grid-template-columns: minmax(0, 1fr);
  align-content: start;               /* colonne pari: le righe restano alla loro altezza */
  gap: clamp(16px, 1.46vw, 28px);
  max-width: none;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}
.form-card--pill .field { position: relative; display: block; }
/* etichetta fuori schermo (stesso trattamento di .sr-only): il placeholder la ripete */
.form-card--pill .field:not(.field--consent) > label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip-path: inset(50%);
  white-space: nowrap;
  overflow: hidden;
}
.form-card--pill .field__icon {
  position: absolute;
  top: 50%;
  left: clamp(16px, 1.41vw, 27px);
  width: clamp(22px, 1.35vw, 26px);
  height: clamp(22px, 1.35vw, 26px);
  color: var(--cipria-2);
  transform: translateY(-50%);
  pointer-events: none;
}
.form-card--pill .field input,
.form-card--pill .field select,
.form-card--pill .field textarea {
  border: 0;
  background: var(--white);
  color: var(--grigio-1);
  font-size: clamp(16px, 1.04vw, 20px);
  font-weight: 500;
  line-height: 1.22;
}
.form-card--pill .field input,
.form-card--pill .field select {
  min-height: clamp(52px, 3.23vw, 62px);
  padding: 0 clamp(20px, 1.67vw, 32px) 0 clamp(50px, 5.16vw, 99px);
  border-radius: var(--r-pill);
}
/* campi della palette senza icona (piva, oggetto, tipologia): il testo parte dal bordo */
.form-card--pill .field:not(:has(.field__icon)) input,
.form-card--pill .field:not(:has(.field__icon)) select { padding-left: clamp(20px, 1.67vw, 32px); }
.form-card--pill .field textarea {
  min-height: clamp(160px, 13.07vw, 251px);
  padding: clamp(18px, 1.35vw, 26px) clamp(20px, 1.67vw, 32px);
  border-radius: 27px;              /* Figma: raggio dei pannelli di questa pagina */
}
.form-card--pill .field input::placeholder,
.form-card--pill .field textarea::placeholder { color: var(--grigio-1); opacity: 1; }
.form-card--pill .field input:hover,
.form-card--pill .field select:hover,
.form-card--pill .field textarea:hover { border-color: transparent; box-shadow: var(--sh-card); }

.form-card--pill .field--consent {
  display: flex;
  align-items: flex-start;
  gap: clamp(12px, .99vw, 19px);
  margin-top: clamp(2px, .21vw, 4px);
}
.form-card--pill .field--consent input {
  width: clamp(20px, 1.25vw, 24px);
  height: clamp(20px, 1.25vw, 24px);
  min-height: 0;
  margin-top: 2px;
  padding: 0;
  border-radius: 4px;
  background: none;
}
.form-card--pill .field--consent label {
  color: var(--grigio-1);
  font-size: clamp(14px, .89vw, 17px);
  font-weight: 500;
  line-height: 1.22;
}
.form-card--pill > .btn {
  justify-content: center;
  min-width: clamp(190px, 12.14vw, 233px);
  min-height: clamp(50px, 3.13vw, 60px);
  margin-top: clamp(10px, 1.09vw, 21px);
  padding-inline: clamp(28px, 2.4vw, 46px);
  font-weight: 500;
}
.form-card--pill > .btn .btn__label:only-child { padding-right: 0; }

/* --- newsletter (fratello di data-footer, dentro il blocco navy) ----------- */
.newsletter__title {
  margin-bottom: 8px;
  color: var(--white);
  font-size: var(--label);
  font-weight: 700;
}
.newsletter__text {
  margin-bottom: 14px;
  color: var(--footer-ink);
  font-size: 13px;
}
.newsletter__form { display: flex; flex-direction: column; gap: 12px; max-width: 320px; }
.newsletter__form .field { gap: 4px; }
.newsletter__form .field > label {
  color: var(--footer-ink);
  font-size: 12px;
  font-weight: 500;
}
.newsletter__form input[type="email"] {
  padding: 12px 16px;
  border: 1px solid rgba(255, 255, 255, .35);
  border-radius: 8px;
  background: rgba(255, 255, 255, .08);
  color: var(--white);
  font-size: 14px;
}
.newsletter__form input[type="email"]::placeholder { color: rgba(255, 255, 255, .6); }
.newsletter__form input[type="email"]:hover { border-color: rgba(255, 255, 255, .6); }
.newsletter__form input[type="email"]:focus-visible { outline-color: var(--white); border-color: var(--white); }
.newsletter__form .field--consent label { color: var(--footer-ink); font-size: 12px; }
.newsletter__form .field--consent a { color: var(--white); }
.newsletter__form .field--consent input { accent-color: var(--white); }
.newsletter__form .btn { align-self: flex-start; min-height: 46px; padding-left: 24px; font-size: var(--small); }
.newsletter__form .form-card__note { color: var(--footer-ink); font-size: 13px; }

/* --- card contatto (indirizzo, telefono, fax, mail) ------------------------ */
.contact-cards {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gutter);
  margin: clamp(28px, 3.4vw, 48px) 0 0;
  padding: 0;
  list-style: none;
}
.contact-cards > li { display: flex; margin: 0; }
/* Figma contatti.png: card 295x226, il disegno dell'icona e' alto ~41 con il bordo
   alto a 60 dal bordo card e il recapito 48 sotto. La dicitura (INDIRIZZO, TELEFONO,
   FAX, EMAIL) non c'e': resta nel DOM fuori schermo perche' e' l'unico contesto del
   valore per chi legge con lo screen reader. */
.contact-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(22px, 2.5vw, 48px);
  width: 100%;
  min-height: clamp(160px, 11.77vw, 226px);
  padding: clamp(28px, 3.13vw, 60px) 18px clamp(24px, 2.7vw, 52px);
  border-radius: var(--r-card);
  background: var(--tint-contatti);
  color: var(--cipria-2);
  font-size: 14px;
  font-weight: 500;
  text-align: center;
}
.contact-card__icon {
  width: auto;
  height: clamp(28px, 2.14vw, 41px);
  color: var(--cipria-2);
}
.contact-card__value {
  color: var(--cipria-2);
  font-size: clamp(15px, 1.04vw, 20px);
  font-weight: 700;
  line-height: 1.22;
}
a.contact-card__value:hover { color: var(--navy); }

/* --- sedi ------------------------------------------------------------------*/
/* Pannello sedi — Figma contatti.png: 1294x456 a 1920, padding 79/86, fondo
   --tint-contatti. Le due colonne partono dove le mette il frame (0 e 647 dentro un
   box interno di 1122), quindi la prima e' piu' larga della seconda: e' per questo
   che li' "UFFICIO DI RAPPRESENTANZA IN POLONIA" (500px a 22) sta su una riga.
   Nessuna gronda dichiarata: lo stacco fra le colonne e' l'aria che avanza al testo,
   come nel frame. */
.locations {
  display: grid;
  grid-template-columns: minmax(0, 647fr) minmax(0, 474fr);
  align-content: center;
  column-gap: 0;
  row-gap: clamp(26px, 3.02vw, 58px);
  min-height: clamp(240px, 23.44vw, 450px);
  margin: clamp(28px, 3.4vw, 48px) 0 0;
  padding: clamp(28px, 4.11vw, 79px) clamp(20px, 4.48vw, 86px);
  border-radius: var(--r-card);
  background: var(--tint-contatti);
  list-style: none;
}
.locations > li { margin: 0; }
/* Tipografia: il frame ha titolo 22/700 e indirizzo 20/600, ma le etichette reali
   sono piu' lunghe di quelle disegnate ("UFFICIO DI RAPPRESENTANZA IN POLONIA" a 22
   vuole 501px in una colonna da 466 e va a capo). Scelta del cliente (2026-09-07):
   tutta la fascia a 18, indirizzi e orari in regular. Cosi' ogni riga sta in una riga
   sola — la piu' stretta, Polonia, avanza 56px — e la scatola torna nei 450 dichiarati.
   Interlinea 2 su entrambi (36px), tinta cipria, nessuna spaziatura fra lettere. */
.location__title {
  margin-bottom: clamp(10px, 1.04vw, 20px);
  color: var(--cipria-2);
  font-size: clamp(16px, .94vw, 18px);
  font-weight: 700;
  letter-spacing: 0;
  line-height: 2;
  text-transform: uppercase;
}
.location__address,
.location__hours {
  margin: 0;
  color: var(--cipria-2);
  font-size: clamp(16px, .94vw, 18px);
  font-style: normal;
  font-weight: 400;
  line-height: 2;
}
.location a { color: var(--grigio-1); }

.map-static,
[data-locations-map] {
  margin: 0;
  border-radius: var(--r-img);
  background: var(--surface-2);
  overflow: hidden;
}
.map-static__img,
.map-static img,
[data-locations-map] img { width: 100%; height: 100%; object-fit: cover; }
/* mappa personalizzata Ho.Bag: immagine statica 586x854 (Figma contatti.png) */
.map-static { aspect-ratio: 586 / 854; min-height: 0; }
/* colonna sinistra della fascia form: la mappa e, sotto, il pulsante Google Maps */
.map-block {
  display: flex;
  flex-direction: column;
  justify-content: space-between;      /* mappa in alto, pulsante a filo del fondo colonna */
  gap: clamp(16px, 1.46vw, 28px);
}
.map-block__cta { margin: 0; }
/* stessa pillola del bottone del modulo (Figma: 60 di altezza, etichetta 20/500) */
.map-block__cta .btn {
  justify-content: center;
  min-height: clamp(50px, 3.13vw, 60px);
  padding-inline: clamp(28px, 2.4vw, 46px);
  font-weight: 500;
}
.map-block__cta .btn .btn__label:only-child { padding-right: 0; }

/* ---------------------------------------------------------- MAPPA INTERATTIVA
   La foto statica resta il primo disegno e lo slot editabile del pannello
   (`form_img`): la mappa vera le va sopra solo dopo il clic, e con essa le
   mattonelle di OpenStreetMap/CARTO — prima di quel gesto la pagina non fa una
   sola richiesta verso l'esterno. Motore: static/js/hobag-map.js.
   `z-index: 0` non e' decorativo: apre un contesto di impilamento e tiene i
   comandi di Leaflet (che arrivano a z-index 1000) dentro il riquadro, invece
   di farli passare sopra l'intestazione del sito allo scorrimento. */
.map-static { position: relative; }
.map-live {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  visibility: hidden;
}
.map-static.is-map-live .map-live { visibility: visible; }
.map-static.is-map-live .map-static__img,
.map-static.is-map-live .map-live__start { visibility: hidden; }

/* pulsante di avvio, steso sulla foto: velo blu + pastiglia leggibile */
.map-live__start {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(8px, .63vw, 12px);
  width: 100%;
  padding: 16px;
  border: 0;
  border-radius: inherit;
  background: rgba(16, 59, 94, .42);   /* --navy al 42% */
  color: #fff;
  font: inherit;
  text-align: center;
  cursor: pointer;
}
.map-live__start-label {
  display: inline-block;
  padding: clamp(11px, .73vw, 14px) clamp(18px, 1.15vw, 22px);
  border-radius: 999px;
  background: var(--navy);
  color: #fff;
  font-size: clamp(15px, .94vw, 17px);
  font-weight: 600;
  line-height: 1.2;
}
.map-live__start:hover .map-live__start-label { background: var(--navy-2); }
.map-live__start-note {
  max-width: 34ch;
  font-size: clamp(12px, .73vw, 13px);
  line-height: 1.5;
  text-shadow: 0 1px 3px rgba(12, 46, 74, .65);
}
.map-live__start:focus-visible { outline: 3px solid var(--azzurro); outline-offset: -3px; }
.map-live__msg {
  position: absolute;
  left: 50%;
  bottom: 14px;
  z-index: 2;
  margin: 0;
  padding: 8px 14px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: var(--navy);
  color: #fff;
  font-size: 13px;
}

/* La tinta delle mattonelle la mette una MATRICE DI COLORE, definita in linea nel
   markup della pagina contatti (filter id="hobag-map-tint"). Bersaglio: la mappa
   del Figma, che e' CHIARISSIMA — fondo #edf3f7 sull'84% dei pixel, luminanza
   media 237/255.

   Come sono usciti i numeri (misura sull'export static/img/hobag-sito-mappa-sedi).
   L'export ha quattro fasce: fondo #edf3f7, strade #f1f8fc, acqua e aree #d2dadf,
   testi e bordi #9aa8ac. Le ancore sono le due che coprono quasi tutta la
   superficie: il TERRENO delle mattonelle OSM (#f2efe9) deve diventare il fondo
   Figma, e la loro ACQUA (#aad3df) la fascia media. Una retta per canale su quei
   due punti da' out = a*lum + b, che sulle mattonelle vere rende terreno #edf3f7,
   acqua #d2dadf, bosco #ced6db, strade #f9feff, etichette #60717a.

   Le ancore erano prima fondo+testi: usciva una retta a contrasto quasi 1:1 che a
   quello zoom lasciava emergere l'ombreggiatura dei rilievi come chiazze grigie.
   Queste due appiattiscono (pendenza ~0.7) ed e' cio' che rende il disegno.

   NON si riproduce qui il velo navy al 42%: quello appartiene allo stato CHIUSO,
   dove fa da fondo leggibile al pulsante «Mostra la mappa». Cuocerlo dentro le
   mattonelle rendeva scura anche la mappa aperta (arrivava a #90a1b9), che e' il
   difetto corretto il 2026-09-17.

   Quattro righe, non tre: senza quella dell'alfa la matrice ha 15 valori invece di
   20, e il browser SCARTA il filtro in silenzio — le mattonelle restano grezze.

   Agisce sul solo piano delle mattonelle: segnaposti, fumetti e comandi restano
   dei loro colori. Per schiarire o scurire si sposta l'ultima colonna (l'offset)
   delle tre righe di colore, non i pesi. */
.map-live .leaflet-tile-pane { filter: url(#hobag-map-tint); }
.map-tint-def { position: absolute; width: 0; height: 0; overflow: hidden; }
.map-live .leaflet-container {
  /* si vede ai bordi e mentre le mattonelle arrivano: il fondo del Figma, non
     --azzurro (#B0C7D7), che lampeggiava blu su una mappa pallida */
  background: #edf3f8;
  font-family: inherit;
}
.map-pin { color: var(--navy); }
.map-pin svg { display: block; filter: drop-shadow(0 2px 3px rgba(12, 46, 74, .35)); }
/* Piu' sedi sullo stesso punto dello schermo: un solo segnaposto col numero.
   Tre delle cinque sedi stanno a San Vendemiano e a un'inquadratura che comprenda
   Parma sono mezzo pixel l'una dall'altra — senza questo numero si legge «una
   sede». Il pallino sta in alto a destra, fuori dalla goccia ma dentro i 30x38
   dell'icona, cosi' non sposta l'ancoraggio del pin sulla sua coordinata. */
.map-pin--gruppo { cursor: pointer; }
.map-pin__conta {
  position: absolute;
  top: -2px;
  right: -6px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--bordeaux);
  box-shadow: 0 1px 3px rgba(12, 46, 74, .4);
  color: var(--white);
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.map-live .leaflet-popup-content-wrapper {
  border-radius: 14px;
  box-shadow: 0 10px 28px rgba(12, 46, 74, .18);
}
.map-live .leaflet-popup-content { margin: 14px 16px; font-size: 15px; line-height: 1.5; }
.map-popup__title { margin: 0 0 4px; color: var(--navy); font-size: 16px; font-weight: 700; }
.map-popup__addr { margin: 0; color: var(--grigio-1); font-style: normal; }
.map-live .leaflet-control-zoom a {
  color: var(--navy);
  background: #fff;
  border-radius: 8px;
}
.map-live .leaflet-control-zoom a:hover { background: var(--sand-2); }
.map-live .leaflet-control-attribution {
  background: rgba(255, 255, 255, .84);
  color: var(--navy);
  font-size: 11px;
}
.map-live .leaflet-control-attribution a { color: var(--navy); }
.locations-fallback { margin: 16px 0 0; padding-left: 1.1em; color: var(--grigio-1); font-size: var(--small); }

/* =============================================================================
   18. FOOTER
   Struttura (partials/_footer.html.j2):
   footer.site-footer > .container > [ .site-footer__inner[data-footer]
       ( .site-footer__brand, nav.site-footer__nav > .site-footer__col,
         ul.site-footer__legal ),
     .site-footer__newsletter, .site-footer__bottom ]
   La newsletter sta FUORI da data-footer: il binder ricostruisce solo __inner:
   per questo le 4 tracce stanno sul .container e __inner e' display:contents,
   cosi' la newsletter cade nella stessa traccia di "Settori" (Figma homepage,
   footer y=5619: Packaging | Accessori+Servizi | Settori, newsletter sotto).
   ============================================================================= */
.site-footer {
  /* lo spazio prima del footer lo da' gia' il padding di chiusura dell'ultima
     fascia (--band-pad): sommarci anche un margine lo raddoppiava rispetto al
     Figma, dove fra ultimo contenuto e blocco navy corrono ~85px */
  margin: 0 var(--footer-gap) var(--footer-gap);
  padding: clamp(40px, 4vw, 64px) 0 24px;
  border-radius: var(--r-footer);
  background: var(--navy);
  color: var(--footer-ink);
  font-size: var(--small);
}
.site-footer > .container {
  display: grid;
  /* misurate su Group 772: le colonne partono a 0, 407, 624 e 952 sui 1273 della
     colonna di contenuto. Non sono tre tracce uguali - Packaging e' la piu' stretta,
     Settori/Newsletter la piu' larga - quindi niente repeat(3, 1fr). */
  grid-template-columns: minmax(240px, 2.08fr) minmax(0, 1fr) minmax(0, 1.63fr) minmax(0, 1.82fr);
  gap: clamp(28px, 3vw, 44px) clamp(24px, 2.6vw, 40px);
  align-items: start;
}
.site-footer a { color: var(--footer-ink); }
.site-footer a:hover { color: var(--white); text-decoration: underline; }
.site-footer h2, .site-footer h3, .site-footer h4 { color: var(--white); }

.site-footer__inner { display: contents; }
.site-footer__brand {
  grid-column: 1;
  grid-row: 1 / span 2;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.site-footer__logo { display: inline-flex; }
/* Group 772: il logo e' largo quanto "HO.BAG CORPORATE S.R.L." (misurati 298 e 300px).
   Prima era vincolato a 52px di altezza e usciva sui 135, meno della meta'. 298px e'
   anche la larghezza NATURALE del file (298x115), quindi non lo si ingrandisce: la
   nostra scritta a 21px misura 308px col font reale, dieci pixel che non si vedono. */
.site-footer__logo-img { display: block; width: 298px; height: auto; max-width: 100%; }
.site-footer__legal-name {
  margin: 4px 0 6px;
  color: var(--white);
  font-size: 21px;              /* Group 772: alta quanto i titoli di colonna, un filo di piu' */
  font-weight: 700;
  letter-spacing: .02em;
}
.site-footer__contacts { margin: 0; padding: 0; list-style: none; }
/* tel/fax/email alla stessa misura delle voci di navigazione del footer, 18px
   (richiesta Nico 2026-09-08): erano 14 e si leggevano come una didascalia.
   L'icona cresce in proporzione, se no resta sotto la riga di testo. */
.site-footer__contact {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  font-size: 18px;
}
/* Group 772: "Tel." ha lo stesso colore e peso del numero (misurata la luminosita':
   208,9 contro 209,8). L'icona davanti non c'e' proprio: tolta dal markup. */
.site-footer__contact-label { color: inherit; font-weight: inherit; }
.site-footer__follow { margin: 14px 0 10px; font-size: 18px; }   /* Group 772 */
.site-footer__social {
  display: flex;
  gap: 16px;                    /* Group 772 */
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-footer__social li { margin: 0; }
/* Group 772: i social sono glifi nudi, senza pastiglia, allineati al bordo sinistro
   della colonna come il testo sopra. Misurati 18px di inchiostro con 16px di stacco. */
.site-footer__social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--white);
  transition: opacity .18s ease;
}
.site-footer__social-link:hover { opacity: .7; }
.site-footer__social-link.is-disabled { opacity: .45; cursor: not-allowed; }
.site-footer__social-link .icon { width: 20px; height: 20px; }

.site-footer__nav {
  grid-column: 2 / -1;
  grid-row: 1;
  display: grid;
  /* Le tre colonne del menu NON possono essere uguali: questa griglia e' annidata
     dentro le tracce 2-4 del container, mentre i legali e la newsletter stanno sulla
     griglia del container. Se le proporzioni non coincidono, "Cookie Policy" non cade
     mai sotto "Accessori" e la newsletter non cade sotto "Settori": si allineerebbero
     solo per caso. Stessi rapporti delle tracce 2/3/4 (1 : 1.63 : 1.82) e stesso
     column-gap, cosi' le tre griglie combaciano. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.63fr) minmax(0, 1.82fr);
  grid-template-rows: auto auto;
  /* Group 772: "Servizi" e' alto quanto "Airless", cioe' esattamente due passi di riga
     sotto "Altri accessori". Misurato sul rendering vero: col vecchio stacco da 36px
     con 36px la distanza era 99px invece di 81, con 18px le BASI del testo restavano
     sfalsate di 10 (Airless e Profumeria appoggiano a 242, "Servizi" a 252). Cio' che
     deve coincidere e' la linea di base, non il riquadro: il titolo e' 20px e le voci
     18, quindi allineare le scatole lascia comunque il testo piu' basso. Con 8px le
     con 8px restavano 4px sotto, con 4px ne restavano 2. Valore finale VERIFICATO sul
     rendering vero (Chrome headless a 1920, non sull'aritmetica del foglio): "Servizi"
     appoggia a 247, "Airless" e "Profumeria" a 246. Un pixel e' l'arrotondamento del
     rendering, e ce l'ha anche il Figma (245 contro 246). Non inseguirlo oltre.
     Fisso e non fluido: se cambia, le due colonne si sfasano. */
  gap: 2px clamp(24px, 2.6vw, 40px);
  align-items: start;
}
/* Figma: Packaging da solo, Servizi sotto Accessori, Settori da solo */
.site-footer__col:nth-child(1) { grid-column: 1; grid-row: 1 / span 2; }
.site-footer__col:nth-child(2) { grid-column: 2; grid-row: 1; }
.site-footer__col:nth-child(3) { grid-column: 2; grid-row: 2; }
.site-footer__col:nth-child(4) { grid-column: 3; grid-row: 1 / span 2; }
.site-footer__col { min-width: 0; }
.site-footer__col-title {
  margin: 0 0 14px;
  font-size: 20px;
  font-weight: 700;
}
/* «Packaging» e' l'unico titolo di colonna che e' anche un link: stesso bianco
   velato degli altri titoli, non il bianco pieno dei link (cliente, 25/09:
   «uniforma "packaging" al resto delle voci principali»); pieno solo in hover */
.site-footer__col-title a { color: inherit; }
.site-footer__col-title a:hover { color: var(--white); }
.site-footer__col-list { margin: 0; padding: 0; list-style: none; }
.site-footer__col-list li { margin: 0 0 14px; }
.site-footer__col-list a { font-size: 18px; }

.site-footer__legal {
  grid-column: 2 / 4;
  grid-row: 2;
  /* Dal 25/09 tre link IN FILA, nell'ordine dello schema della cliente:
     Privacy Policy · Info Legali · Cookie Policy (modello geminiconsult.it).
     Prima erano cinque in una griglia a due colonne allineate alle tracce. */
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px clamp(24px, 2.6vw, 40px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-footer__legal li { margin: 0; }
.site-footer__legal a { font-size: 18px; font-weight: 600; }

/* la newsletter cade nell'ultima traccia, sotto "Settori" */
.site-footer__newsletter { grid-column: 4 / -1; grid-row: 2; }

.site-footer__bottom {
  grid-column: 1 / -1;
  grid-row: 3;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 24px;
  padding-top: 28px;
  /* Group 772: nessun filetto sopra la riga di chiusura */
  color: rgba(255, 255, 255, .7);
  font-size: 17px;
}
.site-footer__bottom p { margin: 0; }
.site-footer__consent {
  color: rgba(255, 255, 255, .7);
  font-size: 17px;
  font-weight: 600;
}
.site-footer__consent:hover { color: var(--white); }

/* =============================================================================
   19. CONSENT (banner + pannello preferenze — docs/consent-spec.md)
   Vincoli che NON sono gusto ma requisiti del consulente privacy (IND p.1):
   - il banner deve essere una DISCONTINUITA' nella pagina: fondo navy pieno su
     pagina #FAFAFA, non un riquadro chiaro che si confonde;
   - i pulsanti hanno tutti la STESSA classe, altezza, corpo e contrasto: nessun
     "primario" evidenziato, perche' evidenziarne uno e' un dark pattern;
   - testi >= 16px e contrasto >= 4.5:1;
   - su telefono il banner non copre il contenuto: max 60vh e scorre dentro.
   ============================================================================= */
.consent { position: fixed; inset: auto 0 0 0; z-index: 120; }
.consent[hidden] { display: none; }

.consent__banner,
.consent__panel {
  position: fixed;
  left: 50%;
  bottom: clamp(12px, 1.6vw, 24px);
  transform: translateX(-50%);
  width: min(var(--content), calc(100vw - 2 * var(--page-pad)));
  max-height: 60vh;
  overflow-y: auto;
  padding: clamp(22px, 2.4vw, 34px) clamp(20px, 2.4vw, 40px);
  border-radius: var(--r-panel);
  background: var(--navy);
  color: var(--white);
  box-shadow: 0 18px 48px rgba(16, 59, 94, .28);
}
.consent__banner[hidden],
.consent__panel[hidden] { display: none; }
/* il pannello e' modale: velatura sotto, per separarlo dalla pagina */
.consent__panel::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: rgba(16, 59, 94, .45);
}
.consent__inner { position: relative; }
.consent__title {
  margin: 0 0 10px;
  color: var(--white);
  font-size: clamp(20px, 1.5vw, 24px);
  line-height: 1.2;
}
.consent__text,
.consent__cat-desc,
.consent__status {
  margin: 0 0 14px;
  color: var(--white);
  font-size: 16px;            /* soglia minima del consulente, non ridurre */
  line-height: 1.5;
}
.consent__text a,
.consent__cat-desc a { color: var(--white); text-decoration: underline; }

/* i tre pulsanti sono lo STESSO oggetto: cambia solo l'etichetta */
.consent__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 18px; }
.consent__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 22px;
  border: 2px solid var(--white);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--white);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
.consent__btn:hover { background: var(--white); color: var(--navy); text-decoration: none; }

/* la X e la sua dicitura: la chiusura E' un rifiuto e va scritto (VAL p.2) */
.consent__close {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--white);
  cursor: pointer;
}
.consent__close-mark { position: relative; display: block; width: 18px; height: 18px; margin: auto; }
.consent__close-mark::before,
.consent__close-mark::after {
  content: "";
  position: absolute;
  top: 8px;
  left: 0;
  width: 18px;
  height: 2px;
  background: currentColor;
}
.consent__close-mark::before { transform: rotate(45deg); }
.consent__close-mark::after { transform: rotate(-45deg); }
.consent__close-note { margin: 12px 0 0; color: var(--white); font-size: 14px; opacity: .85; }

/* pannello: una riga per categoria, interruttore a destra */
.consent__cats { margin: 18px 0 0; padding: 0; list-style: none; }
.consent__cat { padding: 16px 0; border-top: 1px solid rgba(255, 255, 255, .22); }
.consent__cat-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.consent__cat-label { font-size: 17px; font-weight: 600; }
.consent__switch {
  flex: none;
  width: 52px;
  height: 30px;
  padding: 3px;
  border: 2px solid var(--white);
  border-radius: var(--r-pill);
  background: transparent;
  cursor: pointer;
}
.consent__switch-knob {
  display: block;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--white);
  transition: transform .18s ease;
}
.consent__switch[aria-checked="true"] { background: var(--white); }
.consent__switch[aria-checked="true"] .consent__switch-knob { transform: translateX(22px); background: var(--navy); }
.consent__switch[disabled] { opacity: .55; cursor: default; }
.consent__tags { margin: 8px 0 0; padding-left: 18px; font-size: 14px; opacity: .85; }
.consent__links { display: flex; flex-wrap: wrap; gap: 18px; margin: 16px 0 0; }
.consent__links .link { border: 0; background: none; color: var(--white); font-size: 15px; cursor: pointer; text-decoration: underline; }
.consent__live { margin: 10px 0 0; color: var(--white); font-size: 14px; }
.consent :focus-visible { outline: 3px solid var(--white); outline-offset: 3px; }

/* =============================================================================
   19b. BANNER POP-UP (public.banners)
   Il markup lo inietta il binder (pages-binding.js, initBanners) dentro l'host
   <div data-banners> di base.html.j2: qui ci sono SOLO le classi che emette.
   Linguaggio dei dialoghi del sito: raggio --r-panel, ombra --sh-panel, navy.
   Livelli: sopra header (60) e mega, SOTTO il consent (120) — la scelta sui cookie
   resta sempre cliccabile — e sotto lo skip-link (200).
   La CTA e' un <a class="btn"> con testo NUDO, senza .btn__label: il padding destro
   simmetrico lo da' solo `.btn__label:only-child`, quindi va scritto qui, altrimenti
   la pill esce storta (30px a sinistra, 10 a destra).
   ============================================================================= */
.banner-popup {
  position: fixed;
  inset: 0;
  z-index: 110;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--page-pad);
  background: rgba(16, 59, 94, .45);
}
.banner-popup__card {
  position: relative;
  width: min(560px, 100%);
  max-height: calc(100vh - 2 * var(--page-pad));
  overflow-y: auto;
  padding: clamp(24px, 2.4vw, 40px);
  background: var(--white);
  color: var(--ink);
  border-radius: var(--r-panel);
  box-shadow: var(--sh-panel);
}
.banner-popup__close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--navy);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}
.banner-popup__close:hover { background: var(--sand-2); }
.banner-popup__img { display: block; width: 100%; height: auto; border-radius: var(--r-img); margin: 0 0 18px; }
.banner-popup__title { margin: 0 34px 10px 0; font-size: var(--h3); color: var(--navy); }
.banner-popup__body { margin: 0 0 20px; font-size: var(--body); }
.banner-popup__cta.btn { padding-right: 30px; }

/* =============================================================================
   20. PAGINE SPECIALI: policy, ricerca, 404, articolo, documenti
   ============================================================================= */
.band--policy .prose,
.band--consent .prose { max-width: 80ch; }
.band--policy h2 { margin-top: 1.2em; font-size: var(--h3); }
.band--policy h3 { font-size: var(--h4); }
.band--policy table { margin: 1.4em 0; font-size: var(--small); }
.band--policy th,
.band--policy td { padding: 12px 14px; border: 1px solid var(--line); text-align: left; }
.band--policy th { background: var(--sand-2); color: var(--navy); }
.policy__meta { display: flex; flex-wrap: wrap; gap: 6px 20px; color: var(--grigio-2); font-size: var(--small); }
.policy__updated, .policy__version { margin: 0; }
/* PDF delle informative (front-matter `pdfs`): uno sotto l'altro sul telefono,
   in fila da tablet in su. Tabelle dei cookie generate: scorrono in orizzontale
   dentro .table-wrap invece di allargare la pagina (390 px: 6 colonne). */
.policy__pdfs { display: flex; flex-wrap: wrap; gap: 12px; margin: 1.6em 0 0; padding: 0; list-style: none; }
.policy__pdfs li { margin: 0; }
.band--policy .table-wrap { margin: 1.4em 0; }
.band--policy .table-wrap table { margin: 0; min-width: 640px; }
/* .prose code (piu' sotto) va a capo ovunque: nei nomi dei cookie no */
.table--cookie td:first-child, .prose .table--cookie code { white-space: nowrap; word-break: normal; overflow-wrap: normal; }
.table--cookie code { font-size: .95em; }

.search-form {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  max-width: 760px;
  margin-bottom: clamp(20px, 2.4vw, 32px);
}
.search-form input[type="search"] {
  flex: 1 1 260px;
  min-width: 0;
  padding: 16px 22px;
  border: 1px solid var(--field-line);
  border-radius: var(--r-pill);
  background: var(--white);
}
.search__hint { color: var(--grigio-2); font-size: var(--small); }
.search__count { margin: 0 0 6px; color: var(--grigio-1); font-size: var(--small); font-weight: 600; }
.search-results { margin: clamp(20px, 2.4vw, 32px) 0 0; padding: 0; list-style: none; }
.search-results__list { display: flex; flex-direction: column; gap: 12px; }
/* Riga di un prodotto trovato (richiesta della cliente del 25/09: «foto a sx, testo,
   piccola descrizione e pulsante a dx»): il markup lo scrive main.js (searchCard).
   Foto e nome sono link alla scheda; il pulsante e' la pillola del sito senza freccia.
   Niente link steso sull'intera riga: la pillola ha un transform in hover e uno
   pseudo-elemento steso lampeggerebbe (vedi la nota su .card--photo). */
.search-result {
  display: grid;
  grid-template-columns: 112px minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(14px, 1.6vw, 28px);
  padding: 14px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-card);
  background: var(--white);
  box-shadow: var(--sh-card);
}
.search-result__media {
  display: block;
  border-radius: 12px;
  background: var(--surface-2);
  overflow: hidden;
}
/* la foto riempie il riquadro, come nei correlati (cliente, 25/09) */
.search-result__media img { width: 100%; aspect-ratio: 1 / 1; padding: 0; object-fit: cover; }
.search-result__family {
  margin: 0 0 4px;
  color: var(--cipria-2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.search-result__title { margin: 0 0 6px; font-size: var(--h4); }
.search-result__title a { color: var(--navy); }
.search-result__text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  margin: 0;
  overflow: hidden;
  color: var(--ink);
  font-size: var(--small);
  line-height: 1.4;
}
.search-result__specs { margin: 6px 0 0; color: var(--grigio-2); font-size: 13px; font-weight: 500; }
.search-result__cta { margin: 0; }
/* «Scopri di piu'» e' un bottone senza freccia: l'etichetta porta 20px di padding a
   destra (`.btn__label:only-child`) e stava fuori centro (24 a sinistra, 30 a destra
   a 1920; 14 e 34 sul telefono). Cliente, 25/09: «la devi tenere centrata». */
.search-result__cta .btn { justify-content: center; padding-right: 24px; }
.search-result__cta .btn .btn__label:only-child { padding-right: 0; }
/* ricerca senza risultati: sei prodotti suggeriti, uno per famiglia, sotto il messaggio */
.search-suggested { margin-top: clamp(24px, 3vw, 40px); }
.search-suggested__title { margin-bottom: 14px; font-size: var(--h4); }
.search__suggestions-title { margin-top: clamp(28px, 3vw, 44px); font-size: var(--h4); }
.search__suggestions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.search__suggestions li { margin: 0; }

.notfound__code {
  margin-bottom: 10px;
  color: var(--cipria-2);
  font-size: var(--small);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.band--links .link-list { gap: 14px 32px; }

/* articolo del blog */
.band--article-head .article__title { margin-bottom: .3em; }
.article__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  margin: 0 0 1.2em;
  color: var(--grigio-2);
  font-size: var(--small);
}
.article__cat { color: var(--cipria-2); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.article__date { color: var(--grigio-2); }
.article__excerpt { max-width: 68ch; color: var(--grigio-1); font-size: var(--label); }
.article__cover { margin: clamp(22px, 2.6vw, 40px) 0 0; border-radius: var(--r-img); overflow: hidden; }
.article__cover img { width: 100%; aspect-ratio: 16 / 7; object-fit: cover; }
.article__body { max-width: 74ch; }
.article__body img { margin: 1.6em 0; border-radius: var(--r-img); }
.article__back { margin-top: clamp(24px, 3vw, 40px); }

/* blog: filtri, lista, ricerca interna */
.blog-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 clamp(24px, 3vw, 40px);
  padding: 0;
  list-style: none;
}
.blog-filters li { margin: 0; }
.blog-search { max-width: 420px; margin-bottom: clamp(20px, 2.4vw, 32px); }
.blog-search input[type="search"] {
  width: 100%;
  padding: 14px 20px;
  border: 1px solid var(--field-line);
  border-radius: var(--r-pill);
  background: var(--white);
}
.blog-search__empty { margin-top: 14px; color: var(--grigio-2); font-size: var(--small); }
.blog-list { margin: 0; padding: 0; list-style: none; }
/* La CTA boxata attaccava all'ultima riga di articoli: `.band + .band` azzera il
   padding sopra e restava solo il fondo della lista (richiesta Nico 2026-09-08). */
.band--news.blog-list + .band--cta { padding-top: var(--band-pad); }

/* documenti e tabelle tecniche */
.doc-list { margin: 0; padding: 0; list-style: none; }
.doc-list li { margin: 0 0 12px; }
.doc-link { display: inline-flex; align-items: center; gap: 10px; color: var(--navy); font-weight: 600; }
/* Quota dimensionale: fascia propria fra i tab e i correlati (la figura non sta
   piu' dentro il pannello). Box stondato alto 555px, disegno centrato dentro. */
.dim-box {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 555px;
  margin: 0;
  padding: clamp(20px, 2.4vw, 40px);
  border-radius: var(--r-card);
  background: var(--white);
  overflow: hidden;
}
.dim-box__img {
  width: auto;
  max-width: 100%;
  height: 100%;
  object-fit: contain;
}
.dim-table { font-size: 14px; }
.dim-table th,
.dim-table td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--line-2);
  text-align: left;
  white-space: nowrap;
}
.dim-table thead th {
  color: var(--navy);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
}
.catalog__pending { color: var(--grigio-2); font-size: var(--small); }
.band__note { margin-top: 14px; color: var(--grigio-2); font-size: 14px; }

/* intestazione scheda prodotto */
.product-head__cat { margin-bottom: 18px; }
.product-head__title { margin-bottom: .4em; }

/* --- scheda prodotto: sfondo, correlati, CTA finale -------------------------
   Qui c'era una regola che rimetteva --bg sull'header: serviva quando l'header era
   bianco e ritagliava una striscia piu' chiara sul grigio di pagina. Ora l'header non
   ha nessun fondo, quindi la striscia non esiste e la regola non serve piu'. */

/* fascia "Sai gia' con cosa abbinarlo?": tutto incolonnato al centro della pagina */
/* icona della macro-categoria sopra il titolo, dentro un tondo in tinta sabbia.
   Il disegno resta navy come sulle card della pagina packaging e sta alla misura
   nativa dentro un box di 28: ci pensa la regola .icon--cat-* svg a contenerlo
   senza stirarlo, che le famiglie siano larghe (vasi 33x25) o alte (flaconi 21x45). */
.band--related .related__badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 84px;
  height: 84px;
  margin: 0 auto 20px;
  border-radius: 50%;
  /* --cipria #DAC6C5 al 40%: tinta unica per ogni famiglia, non segue il tema
     della pagina. Su --bg #FAFAFA appiattisce a #EDE5E5. */
  background: rgba(218, 198, 197, .4);
  color: var(--navy);
}
.band--related .related__badge .icon { width: 44px; height: 44px; }
.band--related h2,
.band--related .prose,
.band--related .band__cta { text-align: center; }
/* la prosa ha un max-width proprio: senza margin auto resterebbe a sinistra.
   Il margine sotto e' quello che la stacca dalla griglia dei correlati. */
.band--related .prose {
  max-width: 68ch;
  margin-inline: auto;
  margin-bottom: clamp(28px, 3.2vw, 48px);
}
/* I correlati sono 2, 3 o 4 a seconda del prodotto: con una griglia a 4 colonne
   fisse restavano appoggiati a sinistra. In flex le card tengono la stessa misura
   della griglia a 4 (stesso gutter) ma la riga si centra qualunque sia il numero. */
.band--related .product-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
.band--related .product-grid > .product-card {
  flex: 0 1 calc((100% - 3 * var(--gutter)) / 4);
  max-width: calc((100% - 3 * var(--gutter)) / 4);
}
/* Card di una CATEGORIA correlata (richiesta della cliente del 23/09, col suo mock-up:
   foto di anteprima al posto del pulsante di testo). Eredita tutto da .product-card:
   qui resta solo cio' che una categoria non ha — niente etichetta di famiglia, niente
   descrizione — e il nome un filo piu' grande, perche' e' l'unica scritta della card. */
.product-card--cat h3 { font-size: var(--h4); }

/* Correlati per CATEGORIA (la cliente indica «Spray, Dispenser…» e non dei prodotti): al
   posto della griglia una riga di pulsanti vuoti, centrata come tutto il resto. La griglia
   vuota resta nel markup (e' un contenitore dichiarato dal contratto) ma con `hidden`, che
   qui vince grazie alla regola globale sull'attributo hidden (riga 260, con !important):
   `:empty` non basterebbe, il template lascia un a capo dentro il div. */
.band--related .related__cats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px 16px;
  max-width: 980px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

/* =============================================================================
   21b. ALIAS DI STATO SCRITTI DA main.js
   (il mega menu non ha uno stato solo-CSS: apre e chiude via attributo hidden)
   ============================================================================= */
/* Stesso trattamento della regola [aria-selected="true"]: questa arriva dopo e
   vincerebbe, quindi la riga di apertura deve essere rosa anche qui, altrimenti
   sotto l'ombra rosa resta il filo navy e si vedono due colori sovrapposti. */
.tabs__tab.is-active {
  background: var(--white);
  border-bottom-color: var(--cipria-2);
  box-shadow: inset 0 -2px 0 var(--cipria-2);
  color: var(--navy);
}
.filters__reset[hidden] { display: none !important; }

/* shell di paginazione idratata dal binder (macro pagination_placeholder) */
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: clamp(32px, 3.6vw, 56px) 0 0;
}
.pager a,
.pager button,
.pager span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  height: 42px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  color: var(--grigio-1);
  font-size: var(--small);
  font-weight: 600;
}
.pager a:hover,
.pager button:not([disabled]):hover { border-color: var(--navy); color: var(--navy); text-decoration: none; }
.pager [aria-current="page"] { background: var(--navy); border-color: var(--navy); color: var(--white); }
/* frecce spente ai due estremi: restano nel DOM per non far ballare la barra */
.pager button { background: none; cursor: pointer; }
.pager button[disabled] { opacity: .38; cursor: default; }
.pager span { min-width: 0; border: 0; padding: 0 2px; }

.product-head__text,
.product-head__media { min-width: 0; }

/* =============================================================================
   21. RESPONSIVE (1440 / 1280 / 1024 / 767) + GUARDIE ANTI-OVERFLOW
   ============================================================================= */
/* --- guardie generali: nessun contenuto puo' allargare la pagina ----------- */
.filter__options { max-width: calc(100vw - 2 * var(--page-pad)); }
/* Il banner non e' piu' un riquadro da 560: e' largo quanto la griglia e si
   centra da solo, quindi la guardia sul viewport ce l'ha gia' nella sua regola.
   Qui resta solo il respiro laterale sul telefono. */
.consent__banner,
.consent__panel { padding-inline: var(--page-pad); border-radius: var(--r-card); }

.table-wrap,
.tabs__panel { overflow-x: auto; }
.spec-table { min-width: 420px; }
.prose pre,
.prose code { white-space: pre-wrap; word-break: break-word; }
.prose table { display: block; overflow-x: auto; }

@media (max-width: 1440px) {
  :root { --page-pad: 28px; }
}

@media (max-width: 1280px) {
  :root {
    --page-pad: 24px;
    --band-pad: clamp(48px, 5.6vw, 84px);
  }
  .site-header__bar-inner { gap: 8px; --pill-pad: 16px; }   /* la tendina della ricerca segue */
  .mega--wide .mega__cols { column-gap: 24px; }
  .nav-item { --nav-pad: 8px; }
  .nav-item__link { font-size: 17px; }
  .nav-item__toggle { width: 20px; }
  .product-grid,
  .product-grid--compact,
  .product-grid--slim { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid--4, .grid--fixed-4,
  .grid--7, .grid--fixed-7,
  .grid--8, .grid--fixed-8 { --cols: 2; }
  /* le tile della home sono fisse a 300px: quattro non ci stanno piu' nella griglia
     (a 1024 sarebbero 1200 su 984 disponibili), quindi qui tornano fluide e seguono
     --cols come tutte le altre */
  .page--home .cards-band--cipria .grid {
    grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
    column-gap: var(--gutter);
  }
  .contact-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- <= 1024: hamburger + accordion, colonne dimezzate --------------------- */
@media (max-width: 1024px) {
  :root {
    --page-pad: 20px;
    --band-pad: clamp(40px, 6vw, 64px);
    --r-footer: 44px;
  }

  /* header: nella pillola restano marchio, lente e hamburger */
  .site-header { --header-logo-h: 58px; }  /* 12 di padding alto + 46 di logo */
  .site-header__top { padding-block: 12px 16px; }
  .site-header__bar-inner {
    flex-wrap: wrap;
    justify-content: flex-end;  /* lente e hamburger a destra, dentro la pillola compatta */
    --pill-h: 56px;             /* min-height e sporgenza della home seguono */
    margin-bottom: -20px;
    padding: 8px 12px;
  }
  .nav-burger { display: inline-flex; order: 3; }
  /* PILLOLA COMPATTA (richiesta della cliente del 25/09): la barra contiene solo la
     lente e il menu (e il pittogramma fra 768 e 1024), a destra, e si allarga su tutta
     la larghezza solo quando si apre la ricerca. Il contenitore resta largo quanto la
     griglia — e' il blocco contenitore del pannello del menu, del campo e della X, e
     restringerlo sposterebbe tutti e tre — mentre la pillola visibile (bordo e bianco)
     passa a uno pseudo-elemento ancorato a destra, che si allarga da 120px al 100%.
     120 = padding 12 + lente 44 + stacco 8 + hamburger 44 + padding 12; fra 768 e
     1024 anche pittogramma 30 + stacco 8 = 158, portati a 168 perche' il
     pittogramma, alto 44 in una pillola alta 60, tocca il bordo curvo agli angoli
     del suo riquadro. Il filo da 2px NON si somma: il padding del contenitore parte
     dal bordo esterno, e contarlo lasciava 14px a sinistra e 10 a destra
     (verifica del 25/09). */
  .site-header__bar-inner {
    --pill-compact: 168px;
    border: 0;
    background: none;
  }
  .site-header__bar-inner::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: -1;                       /* sotto lente e hamburger (l'header non ha altri strati) */
    width: var(--pill-compact);
    border: 2px solid var(--menu-line);
    border-radius: var(--r-pill);
    background: var(--white);
    /* in chiusura aspetta che il campo sia sparito (.1s), poi si stringe */
    transition: width .22s ease .1s;
  }
  .site-header__bar-inner:has(.site-search.is-open)::before,
  .site-header__bar-inner:has(.site-search:focus-within)::before,
  .site-header__bar-inner.is-search-open::before {   /* la classe e' il ripiego senza :has() (main.js, setSearchOpen) */
    width: 100%;
    transition: width .25s ease;
  }
  .site-header__mark { order: 1; margin-left: auto; }   /* dentro la pillola compatta, a destra */
  .site-search { order: 2; margin-left: 0; }
  /* Campo di ricerca sul telefono: dal bordo sinistro della pillola aperta fino alla
     lente, e piu' basso di lei. I due bordi si dichiarano in assoluto rispetto al
     contenitore: 12 = padding orizzontale della pillola; 116 = lente 44 + stacco 8 +
     hamburger 44 + stacco 8 + padding 12. Altezza 40 contro i 64 della pillola. Le
     regole desktop (tendina sotto la pillola) vengono azzerate una per una. */
  .site-search__input {
    top: 50%;
    right: 116px;
    left: auto;
    translate: 0 -50%;
    border-width: 1px;
    background: var(--sand-2);
    /* `width: auto` e `left` non si interpolano: qui si anima solo l'opacita'. In
       apertura il campo aspetta .16s che la pillola si sia allargata (misurato: senza
       ritardo stava FUORI dal bianco per ~180ms); in chiusura sparisce in .1s, prima
       che la pillola cominci a stringersi (ritardo .1s sullo pseudo). */
    transition: opacity .1s ease;
  }
  .site-search.is-open .site-search__input,
  .site-search:focus-within .site-search__input {
    left: 12px;
    width: auto;
    padding: 8px 44px 8px 16px;
    border-color: var(--field-line);
    box-shadow: none;
    transition: opacity .12s ease .16s;
  }
  .site-search__close { top: 50%; right: 121px; background: var(--white); }   /* qui il campo e' sabbia: la pastiglia stacca in bianco */
  .site-search.is-open .site-search__close,
  .site-search:focus-within .site-search__close { transition: opacity .12s ease .18s, visibility 0s linear .18s, background-color .18s ease; }

  /* pannello di navigazione: chiuso di default, aperto da main.js (.is-open) */
  .site-nav {
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    right: 0;
    z-index: 20;
    display: none;
    max-height: calc(100vh - 170px);
    padding: 10px 18px 18px;
    border-radius: var(--r-panel);
    background: var(--white);
    box-shadow: var(--sh-panel);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .site-header.is-open .site-nav { display: block; }
  .nav-tree { flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 0; }
  .nav-tree > li { border-bottom: 1px solid var(--line-2); }
  .nav-tree > li:last-child { border-bottom: 0; }
  .nav-item { flex-wrap: wrap; justify-content: space-between; }
  .nav-item__link { flex: 1 1 auto; padding: 14px 4px; font-size: 16px; }
  .nav-item__toggle { width: 44px; height: 44px; background: var(--sand-2); }

  /* mega menu -> accordion nel pannello (una sola sezione aperta).
     TUTTE le voci a bandiera, nessun rientro (richiesta della cliente del 25/09):
     il pannello non rientra e le chip delle sottovoci non hanno padding laterale,
     cosi' «Azienda», «Flaconi» e «Flaconi in plastica» partono dalla stessa x. */
  .mega__col-title,
  .mega__item a { margin-inline: 0; padding-inline: 0; }
  .nav-item__link { padding-inline: 0; }
  .mega,
  .mega--wide {
    position: static;
    width: 100%;
    min-width: 0;
    max-width: 100%;
    padding: 0 0 16px;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    animation: none;
  }
  ul.mega { padding: 0 0 16px; }
  .mega__inner,
  .mega--wide .mega__inner { max-width: none; padding-inline: 0; }
  .mega__cols,
  .mega--wide .mega__cols,
  .mega__cols:has(.mega__col-list) { display: flex; flex-direction: column; gap: 16px; }
  .mega--wide .mega__cols { grid-auto-flow: row; }
  .mega__col { width: 100%; }
  .mega__col:not(:has(.mega__col-list)) > .mega__col-title { padding: 6px 0; }
  /* Tutte le voci alla misura di «Packaging» (richiesta della cliente del 25/09:
     «"Flaconi" non puo' essere piu' grande di "Packaging"»): 16px su ogni livello,
     i pesi distinguono i livelli (600 le sezioni e le famiglie, 500 le sottovoci). */
  .mega__col-title { font-size: 16px; font-weight: 600; }
  .mega__item a,
  ul.mega ul a { font-size: 16px; }

  /* hero */
  .hero--split .hero__inner {
    grid-template-columns: minmax(0, 1fr);
    padding-inline: var(--page-pad);
    padding-block: clamp(32px, 6vw, 56px);
  }
  .hero--split .hero__media { min-height: 0; }
  /* torna nel flusso: sotto i 1024 la foto sta sotto al testo */
  .hero--split .hero__media img {
    position: static;
    aspect-ratio: 16 / 11;
    border-radius: var(--r-img);
  }
  /* .hero--sector e .hero--inset portano ANCHE la classe .hero--split (si
     appoggiano al suo impilamento sotto i 1024): senza queste due regole la
     riga qui sopra vince a parita' di specificita' (stessa coppia di classi,
     ma viene dopo nel foglio) e le loro foto — verticali, 627x779 e 471x576 —
     perderebbero rapporto e raggi "a foglia" per il 16/11 rettangolare pensato
     per lo split. Si ripete qui il valore desktop, gia' fluido (clamp/vw). */
  .hero--sector .hero__media img { aspect-ratio: 627 / 779; }
  .hero--inset .hero__media img {
    aspect-ratio: 471 / 576;
    border-radius:
      clamp(40px, 7.8vw, 150px)
      clamp(16px, 2.9vw, 56px)
      clamp(44px, 8.85vw, 170px)
      0;
  }
  .hero__deco { --deco-d: 150px; top: -6%; left: -70px; }
  .hero--inset .hero__deco { width: 82px; bottom: 20px; }
  .hero--inset .hero__inner { padding-block: clamp(12px, 2vw, 24px) clamp(32px, 6vw, 56px); }
  /* il segno grafico segue la colonna: resta a filo destro, solo piu' piccolo.
     Il `top` NON si tocca: sotto i 1024 vale ancora il 50% della regola base, se no
     il segno tornerebbe a una misura fissa e si scollegherebbe da titolo e testo,
     che restano centrati. */
  .page--category .hero--plain::before,
  .page--subcategory .hero--plain::before { width: 116px; }
  .hero--full .hero__inner { min-height: 380px; }

  /* contenuti */
  .media-text--split > .container,
  .media-text--box .media-text__panel,
  .media-text--aside .media-text__aside,
  .card--row,
  .product-head,
  .feature__row { grid-template-columns: minmax(0, 1fr); }
  /* impilate: l'altezza fissa di 450px non ha senso, la foto torna a proporzione */
  .card--row { height: auto; }
  .card--row .card__media img { aspect-ratio: 824 / 451; height: auto; }
  /* aside: sotto i 1024 le card degli highlight vanno in riga sotto foto e pannello */
  .feature-cards { grid-auto-rows: auto; grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .feature-card { min-height: 150px; }
  .media-text--reverse .media-text__media,
  .card--row-reverse .card__media,
  .media-text--reverse .media-text__body,
  .card--row-reverse .card__body { order: 0; }
  .media-text--split .media-text__media,
  .media-text--box .media-text__media { min-height: 0; }
  .media-text--split .media-text__media { width: 100%; }
  .media-text--box .media-text__panel { gap: clamp(24px, 4vw, 40px); }
  .media-text--split .media-text__media img,
  .media-text--box .media-text__media img { position: static; aspect-ratio: 16 / 10; }

  .grid { --cols: 2; }
  .grid--1, .grid--fixed-1 { --cols: 1; }
  /* le colonne della fascia "Perche' scegliere" sono dichiarate in px-fr, quindi
     --cols non le tocca: qui la testata torna a tutta larghezza e le card vanno
     a due per riga. */
  .cards-band--head-inline .grid,
  .cards-band--head-inline.cards-band--head-span-2 .grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--gutter);
  }
  .cards-band--head-inline .section__head,
  .cards-band--head-inline.cards-band--head-span-2 .section__head {
    grid-column: 1 / -1;
    margin-bottom: clamp(20px, 2.2vw, 32px);
  }
  /* le card restavano ferme a 375px (misura del Figma a 1920, dove la colonna
     avanzava dello spazio della testata): nella griglia a 2 colonne di qui sotto
     la traccia e' molto piu' larga di 375 e justify-self:start le lasciava a
     sinistra con un vuoto a destra. Tolto il tetto, riempiono la loro traccia. */
  .cards-band--head-inline .card--icon {
    justify-self: stretch;
    width: auto;
    max-width: none;
  }
  .page--home .cards-band--cipria .grid > *:nth-child(even) { translate: none; }
  .page--home .cards-band--cipria .grid { margin-bottom: 0; }
  .product-grid,
  .product-grid--compact,
  .product-grid--slim { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .news-grid,
  .news-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .cta-band { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .tabs__list { flex-wrap: nowrap; overflow-x: auto; }
  .tabs__tab { flex: 0 0 auto; }

  .locations { grid-template-columns: minmax(0, 1fr); }
  /* la regola desktop e' su :has(.map-static): qui serve la stessa specificita' */
  .band--form > .container,
  .band--form > .container:has(.map-static) { grid-template-columns: minmax(0, 1fr); }
  /* mappa in pila sotto il modulo: il ritaglio 586x854 diventa orizzontale */
  .map-block { order: 2; }
  /* NIENTE min-height accanto ad aspect-ratio. Con `3 / 2` piu' `min-height: 260px`
     Safari trasferisce il minimo d'altezza in un minimo di LARGHEZZA attraverso il
     rapporto (260 x 1,5 = 390): a 390 di schermo la mappa usciva a destra di 40px
     mentre Chrome, che non trasferisce, la teneva a 350. E' il difetto segnalato
     dalla cliente il 25/09 («esce dal quadrante del sito lato destro»), misurato in
     WebKit. Il 4/3 da' 262px a 350 di colonna, la stessa altezza di prima, senza
     il minimo che la produceva. */
  .map-static { aspect-ratio: 1 / 1; min-height: 0; }
  .map-static__img { object-position: 50% 43%; }
  /* Quadrato e non 4/3 (cliente, 25/09: «la cartina deve avere la vista su Europa»):
     la mappa servita e' verticale, da Amburgo al Kosovo, e in un riquadro orizzontale
     restava la sola fascia centrale — fuori i segnaposti di Parma e San Vendemiano in
     basso e quello di Varsavia in alto. I segnaposti stanno fra il 16% e l'80%
     dell'altezza della foto (Varsavia in cima, Parma in fondo); il quadrato ne mostra
     il 69% e il fuoco al 43% lo centra su di loro (dal 13,5% all'82%), con lo stesso
     margine sopra e sotto. Sul tablet questa e' la misura; il telefono va in 3/4
     (regola <= 767): il 3/4, che qui a 984 di colonna faceva 1312px di mappa su uno
     schermo di 768, e' stato misurato dalla verifica del 25/09. */

  /* footer: brand, nav 2x2, legal e newsletter in pila (niente piazzamenti) */
  .site-footer > .container { grid-template-columns: minmax(0, 1fr); }
  .site-footer__brand,
  .site-footer__nav,
  .site-footer__legal,
  .site-footer__newsletter,
  .site-footer__bottom { grid-column: 1; grid-row: auto; }
  /* :nth-child(n) per pareggiare la specificita' dei piazzamenti desktop */
  .site-footer__col:nth-child(n) { grid-column: auto; grid-row: auto; }
  .site-footer__nav { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: none; }
  .site-footer__newsletter { max-width: 100%; }
  .site-footer__bottom { flex-direction: column; align-items: flex-start; }
}

/* --- <= 767 con JavaScript: i filtri in un PANNELLO LATERALE ----------------------
   Richiesta del 25/09: sul telefono un solo pulsante «Filtri» che apre da destra un
   pannello con i gruppi incolonnati (a fisarmonica), il pulsante per azzerarli e
   «Mostra N prodotti», che chiude il pannello sulla griglia gia' filtrata (i filtri
   si applicano mentre si spuntano, come sul desktop).
   Perche' `(scripting: enabled)`: il pannello si apre solo col JS. Dove il JS non
   gira, o la media query non esiste (Safari < 17), queste regole non valgono e i
   filtri restano in pagina come sul desktop: nessuno resta senza filtri.
   Perche' `translate` e non `transform` per far scorrere il pannello: il form e' un
   figlio del .container, quindi le comparse allo scroll (animations.css) gli animano
   `transform`; un'animazione batte una dichiarazione, e il pannello chiuso sarebbe
   riapparso per tutta la comparsa. `translate` e' una proprieta' a parte e si somma.
   Livelli: sopra l'header (60), i banner (110) e anche il banner dei cookie (120),
   che altrimenti coprirebbe «Mostra N prodotti» a chi non ha ancora scelto: il
   pannello e' un modale aperto dall'utente, e chiudendolo il banner e' li'. Il
   pulsante del widget di accessibilita' (#a11y-fab, livello 2147483000 per
   costruzione) si nasconde mentre il pannello e' aperto: copriva «Azzera i filtri». */
@media (max-width: 767px) and (scripting: enabled) {
  /* il pulsante e il contatore stanno sulla stessa riga: il form, fisso, esce dal
     flusso, e la riga «Filtri | N prodotti ... 1|2» si forma da sola */
  .band--catalog > .container {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 12px;
  }
  .band--catalog > .container > * { flex: 1 1 100%; min-width: 0; }
  .band--catalog > .container > .filters-toggle { flex: 0 0 auto; margin: 0 0 18px; }
  .band--catalog > .container > .catalog__bar { flex: 1 1 0; }

  /* RIGA INCOLLATA (cliente, 25/09: «non e' il caso che resti fissa allo scroll?
     altrimenti la perdi»). «Filtri», contatore e 1|2 restano sotto la pillola finche'
     si scorre la griglia, e si staccano a fine fascia (il blocco contenitore dello
     sticky e' il .container della fascia catalogo). Sono due elementi fratelli sulla
     stessa riga: ognuno e' sticky per conto suo, allo stesso `top`, e il pulsante
     scende di 6px perche' e' alto 40 contro i 52 della barra (allineamento al centro).
     --catalog-row-top: 76 e' il fondo della pillola incollata (16 di stacco + 60),
     piu' 2. La barra porta il fondo: un'ombra piena larga quanto lo schermo, tagliata
     da clip-path alla sua altezza; da incollata (.is-stuck, main.js) il taglio sale
     fino al bordo alto, cosi' ai lati della pillola compatta non scorrono i prodotti.
     Il padding verticale della barra (8+8) e' compensato dai margini: nel flusso la
     riga occupa lo stesso spazio di prima. */
  .band--catalog > .container { --catalog-row-top: 78px; }
  .band--catalog > .container > .filters-toggle {
    position: sticky;
    top: calc(var(--catalog-row-top) + 6px);
    z-index: 7;
  }
  .band--catalog > .container > .catalog__bar {
    position: sticky;
    top: var(--catalog-row-top);
    z-index: 6;
    margin: -8px 0 10px;
    padding-block: 8px;
    background: var(--bg);
    box-shadow: 0 0 0 100vmax var(--bg);
    clip-path: inset(0 -100vmax);
  }
  .band--catalog > .container > .catalog__bar.is-stuck {
    clip-path: inset(calc(-1 * var(--catalog-row-top)) -100vmax 0);
  }

  .filters-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 40px;
    padding: 8px 16px 8px 14px;
    border: 1px solid var(--field-line);
    border-radius: var(--r-pill);
    background: var(--white);
    color: var(--navy);
    font-size: 15px;
    font-weight: 600;
  }
  .filters-toggle[aria-expanded="true"] { border-color: var(--navy); }
  .filters-toggle__icon { width: 20px; height: 20px; }
  .filters-toggle__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: var(--r-pill);
    background: var(--navy);
    color: var(--white);
    font-size: 12px;
    font-weight: 700;
  }

  .filters {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 126;
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 0;
    width: min(88vw, 380px);
    margin: 0;
    background: var(--white);
    box-shadow: var(--sh-panel);
    translate: 100% 0;
    visibility: hidden;
    transition: translate .28s ease, visibility 0s linear .28s;
  }
  .filters.is-drawer-open {
    translate: 0 0;
    visibility: visible;
    transition: translate .28s ease;
  }
  .filters__head {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 14px 14px 20px;
    border-bottom: 1px solid var(--line-2);
  }
  .filters__title { color: var(--navy); font-size: 18px; font-weight: 700; }
  .filters__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--r-pill);
    background: var(--sand-2);
    color: var(--navy);
  }
  .filters__close .icon { width: 20px; height: 20px; }
  .filters__groups {
    flex: 1 1 auto;
    display: block;
    width: auto;
    min-height: 0;
    padding: 4px 20px 12px;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .filters .filter { min-width: 0; border-bottom: 1px solid var(--line-2); }
  .filters .filter__summary {
    padding: 16px 2px;
    border: 0;
    border-radius: 0;
    background: none;
    color: var(--navy);
    font-size: 16px;
    font-weight: 600;
  }
  .filters .filter[open] > .filter__summary { border-color: transparent; box-shadow: none; }
  .filters .filter__options {
    position: static;
    width: auto;
    min-width: 0;
    max-width: none;
    max-height: none;
    padding: 0 0 12px;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    overflow: visible;
  }
  .filters .filter__option { padding: 11px 6px; font-size: 15px; }
  .filters .filter__option input { width: 20px; height: 20px; }
  .filters__actions {
    flex: none;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 20px calc(14px + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--line-2);
    background: var(--white);
  }
  /* «Azzera i filtri» e «Mostra N prodotti» stanno sulla stessa riga solo se
     l'etichetta di «Mostra» ci entra intera: altrimenti «Mostra» va a capo da solo,
     largo quanto il pannello, e «Azzera» resta sopra, centrato. Prima «Mostra 1 /
     prodotto» andava su due righe dentro il pulsante appena compariva «Azzera»
     (26 pagine su 26 a 320 e 360, 11 a 390 — verifica del 25/09). La base e' la
     larghezza del testo (`width: max-content`), il tetto il pannello: l'etichetta
     lunga di zero risultati va comunque a capo dentro il pulsante invece di sbordare. */
  .filters__actions { flex-wrap: wrap; justify-content: center; row-gap: 4px; }
  .filters .filters__reset { flex: none; padding: 12px 2px; }
  .filters .filters__apply {   /* due classi: la .btn del blocco <= 767, che viene dopo, rifarebbe il padding asimmetrico */
    display: inline-flex;
    flex: 1 1 auto;
    width: max-content;
    max-width: 100%;
    justify-content: center;
    min-height: 48px;
    padding: 8px 20px;
  }
  .filters__apply .btn__label:only-child { padding-right: 0; }

  .filters-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 125;
    background: rgba(16, 59, 94, .45);
    opacity: 0;
    visibility: hidden;
    transition: opacity .28s ease, visibility 0s linear .28s;
  }
  .filters-backdrop.is-visible { opacity: 1; visibility: visible; transition: opacity .28s ease; }
  /* mentre svanisce lo sfondo non deve mangiarsi i tocchi: un tap su una card subito
     dopo la chiusura non navigava (verifica del 25/09, entrambi i motori) */
  .filters-backdrop:not(.is-visible) { pointer-events: none; }
  html.has-filters-drawer,
  html.has-filters-drawer body { overflow: hidden; }
  /* il pannello NON e' contenuto che «compare allo scroll»: animations.js lo marcava
     come figlio del .container e nel primo secondo dopo il caricamento entrava
     spostato di 30px e semitrasparente (verifica del 25/09). Sul desktop il form
     resta nel flusso e la comparsa vale. */
  html.js-reveal .filters[data-ar-reveal],
  html.js-reveal .filters[data-ar-reveal].is-revealing { opacity: 1; animation: none; }
  html.has-filters-drawer #a11y-fab { display: none; }
  /* il contatore del gruppo accanto all'etichetta, la freccia a destra */
  .filters .filter__summary { justify-content: flex-start; }
  .filters .filter__summary::after { margin-left: auto; }
}
/* Sotto i 360 la riga «Filtri | N prodotti | 1|2» non ci stava: il contatore andava
   su due righe (5 pagine su 26 a filtri spenti, 26 su 26 col contatore acceso sul
   pulsante) e l'interruttore sbordava di 5px nel margine (verifica del 25/09, 320).
   Si stringono stacchi e imbottiture — 16px in tutto — e il contatore non va a capo. */
@media (max-width: 359px) and (scripting: enabled) {
  .band--catalog > .container { column-gap: 8px; }
  .filters-toggle { gap: 6px; padding-inline: 12px 10px; }
  .catalog__bar { gap: 8px; }
  .catalog__bar .catalog__count { white-space: nowrap; }
}

/* --- 768-1199: il testo dell'hero accessori lascia libera la colonna del segno --
   Sul desktop largo il testo finisce molto prima del bordo e il segno grafico (a filo
   destro, centrato in altezza) sta nell'aria. Sotto i ~1200 il contenitore arriva
   quasi al bordo: l'arco bianco del segno passava SOTTO la fine delle righe del
   paragrafo (14 pagine su 14 a 768-1024, verifica del 25/09). Il testo si ferma 16px
   prima del segno: larghezza del segno + 16 - il margine della pagina. Sotto i 767 il
   segno sta sopra il titolo e questa regola non serve. */
@media (min-width: 768px) and (max-width: 1199px) {
  body.page--category .hero--plain .hero__text,
  body.page--subcategory .hero--plain .hero__text { padding-right: calc(clamp(94px, 8.02vw, 154px) + 16px - var(--page-pad)); }
}
@media (min-width: 768px) and (max-width: 1024px) {
  body.page--category .hero--plain .hero__text,
  body.page--subcategory .hero--plain .hero__text { padding-right: calc(116px + 16px - var(--page-pad)); }
}

/* --- 768-1024: la pillola compatta porta anche il pittogramma ----------------
   Il campo aperto va dal bordo della pillola al PITTOGRAMMA, non alla lente: con i
   116px di sotto (lente + hamburger) copriva il pittogramma, che spariva sotto la
   sabbia del campo e non era piu' cliccabile (misurato a 768, 900 e 1024).
   154 = 116 + pittogramma 30 + stacco 8. Sul telefono il pittogramma c'e' anche lui,
   ma a ricerca aperta si ritira e il campo torna a 116 (regola <= 767). */
@media (min-width: 768px) and (max-width: 1024px) {
  .site-search__input { right: 154px; }
  .site-search__close { right: 159px; }
}

/* --- <= 767: una colonna, breadcrumb compatto ------------------------------ */
@media (max-width: 767px) {
  .banner-popup { padding: var(--page-pad); }
  .banner-popup__card { width: 100%; }
  .feature-cards { grid-template-columns: minmax(0, 1fr); }
  :root {
    --page-pad: 20px;
    --gutter: 16px;
    --band-pad: clamp(36px, 9vw, 56px);
    --btn-h: 48px;
    --r-card: 14px;
    /* SCALA DEI TITOLI SUL TELEFONO (richiesta della cliente del 25/09: «gli H in
       generale sono troppo grandi»). Prima stavano su h1/h2/h3 come elementi, e i
       titoli che leggono i token direttamente (.hero__title, .cta-band__title, le
       card) non li vedevano: l'h1 della home restava a 38. Ora cambiano i token,
       cosi' vale per tutti. A 390: h1 home 30 (era 38), h1 interne 28 (era 34), h2
       24 (era 28,9), h3 20 (era 21,8), h4 18 (era 20). */
    --h1: clamp(28px, 7.7vw, 34px);
    --h1-inner: clamp(26px, 7.2vw, 32px);
    --h2: clamp(22px, 6.2vw, 27px);
    --h3: clamp(19px, 5.1vw, 22px);
    --h4: 18px;
  }
  /* il pittogramma «b» resta a vista anche sul telefono (cliente, 25/09: «cosi'
     chiunque puo' tornare alla home cliccandola»), ma DA SOLO, a sinistra, in una
     pastiglia tonda sua con lo stesso filo e lo stesso bianco della pillola, e piu'
     piccolo (22x33 invece di 30x44) — seconda richiesta dello stesso giorno. La
     pillola a destra torna a 120 (lente + menu). Il tondo e' alto quanto la pillola
     (60) e parte dal margine della pagina: i margini negativi annullano il padding
     della barra (8 sopra e sotto, 12 a sinistra). Quando la ricerca e' aperta il
     pittogramma si ritira e il campo tiene la larghezza di prima, fino alla lente. */
  .site-header__bar-inner { --pill-compact: 120px; }
  .site-header__mark {
    order: 0;
    width: 60px;
    height: 60px;
    margin: -8px auto -8px -12px;
    border: 2px solid var(--menu-line);
    border-radius: 50%;
    background: var(--white);
    transition: opacity .1s ease;
  }
  .site-header__mark .icon--logo-mark { width: 22px; height: 33px; }
  .site-header__bar-inner:has(.site-search.is-open) .site-header__mark,
  .site-header__bar-inner:has(.site-search:focus-within) .site-header__mark,
  .site-header__bar-inner.is-search-open .site-header__mark {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
  /* i titoli con una misura propria, non a token, scendono con gli altri */
  .band--catalog .section__head h2 { font-size: var(--h2); }
  .cards-band--icon .card__title { font-size: var(--h4); }
  .faq-list:not(.faq-list--numbered) .faq__q { font-size: 16px; }
  /* Pulsanti (stessa richiesta): etichetta 17 invece di 20, pillola 48 invece di 57,
     freccia 24 in un tondo di 32 */
  .btn { gap: 8px; padding: 8px 8px 8px 20px; font-size: 17px; }
  .btn--sm { font-size: var(--small); }      /* il «piccolo» resta piccolo: la regola sopra lo batteva per ordine */
  .btn__icon { width: 32px; height: 32px; }
  .btn__icon .icon { width: 24px; height: 24px; }
  .form-card--pill > .btn,
  .map-block__cta .btn { min-height: 48px; }
  /* «Richiedi una consulenza» (281px) deve entrare nel pannello CTA anche a 360:
     con 28px di padding la colonna interna era 264 e l'etichetta andava su due
     righe; con 18 e' 284 (misura della verifica del 25/09, faq/ a 360-384) */
  .cta-band { padding-inline: 18px; }

  .site-header__top-inner { grid-template-columns: 1fr auto; }
  .site-header__logo { grid-column: 1; justify-self: start; }
  .site-header { --header-logo-h: 50px; }  /* 12 di padding alto + 38 di logo */
  .site-header__logo-img { height: 38px; }
  .lang-switch { grid-column: 2; }

  /* briciole: tolte sul telefono (cliente, 25/09). Il ritorno alla home e' il marchio
     «b» nella pillola, sempre a vista; il markup e lo schema BreadcrumbList restano,
     perche' sul desktop le briciole si vedono ancora. */
  .breadcrumb { display: none; }

  .grid,
  .news-grid,
  .news-grid--2,
  .contact-cards { --cols: 1; grid-template-columns: minmax(0, 1fr); }
  .cards-band--head-inline .grid,
  .cards-band--head-inline.cards-band--head-span-2 .grid { grid-template-columns: minmax(0, 1fr); }
  .product-grid,
  .product-grid--compact,
  .product-grid--slim { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .product-card h3 { font-size: 15px; }
  .product-card p { display: none; }

  .filter { min-width: 100%; }
  .filters__groups { width: 100%; }
  .filter__options { max-width: 100%; }

  .hero--split .hero__media img { aspect-ratio: 4 / 3; }
  /* stessa collisione della regola ≤1024: .hero--sector/.hero--inset portano anche
     .hero--split, quindi senza ripeterle qui perderebbero di nuovo il loro rapporto
     (e .hero--inset i raggi a foglia) per il 4/3 appena dichiarato sopra. */
  .hero--sector .hero__media img { aspect-ratio: 627 / 779; }
  .hero--inset .hero__media img {
    aspect-ratio: 471 / 576;
    border-radius:
      clamp(40px, 7.8vw, 150px)
      clamp(16px, 2.9vw, 56px)
      clamp(44px, 8.85vw, 170px)
      0;
  }
  /* le foto larghe non devono ridursi a una striscia sul telefono */
  .media-text--wide .media-text__media--wide img,
  .media-text--stack .media-text__media--wide img { aspect-ratio: 16 / 10; }
  /* hero della home piu' alto sul telefono (cliente, 25/09): quasi due terzi dello
     schermo, con un pavimento per gli schermi bassi e un tetto per quelli lunghi.
     Era 320 + i padding (356 misurati a 390) */
  .hero--full .hero__inner { min-height: clamp(460px, 62vh, 560px); }
  /* ...e con l'hero piu' alto la foto (3:2, scalata sull'altezza) mostra meno della
     meta' della sua larghezza: centrata, i prodotti — che in entrambi gli scatti stanno
     a destra, fra il 37% e il 94% — uscivano dal riquadro (cliente, 25/09: «vengono
     completamente tagliate»). All'88% la finestra a 390 va dal 47% al 94%. Solo X:
     l'altezza della foto coincide con quella dell'hero, quindi Y non taglia nulla.
     `--media-focus-sm` e' lo spazio per un'inquadratura per-foto, se arriva uno
     scatto con il soggetto altrove. */
  .hero--full > .hero__media img { object-position: var(--media-focus-sm, 88% 50%); }
  /* la mappa dei contatti sul telefono: 3/4, la foto ne perde solo il 4% sopra e
     sotto (il quadrato e' del tablet, regola <= 1024) */
  .map-static { aspect-ratio: 3 / 4; }
  /* Segno grafico delle pagine accessori (hero di solo testo): dal 7/09 qui era
     spento, perche' a destra e centrato come sul desktop copriva il testo, che sul
     telefono va a tutta larghezza. Torna (cliente, 25/09: «dov'e' finito il segno
     grafico dell'hero?») piu' piccolo e IN ALTO a destra, sopra il titolo: il padding
     alto della fascia gli fa posto — 20 di stacco + 82 di segno + 16 — cosi' non
     tocca mai il testo, anche con un titolo su piu' righe. */
  .page--category .hero--plain::before,
  .page--subcategory .hero--plain::before {
    top: 20px;
    width: 64px;
    transform: scaleX(-1);
  }
  body.page--category .hero--plain,
  body.page--subcategory .hero--plain { padding-top: 118px; }

  .faq > summary { gap: 12px; padding: 16px 18px; }
  .faq .prose { padding: 0 18px 20px; }
  .faq-list .faq .prose { padding-left: 18px; }
  /* Domanda e risposta alla stessa misura, 16: la domanda si distingue per il peso.
     Prima la risposta era PIU' GRANDE della domanda — 16 contro 15 sulla pagina FAQ,
     18 contro 16 nelle fasce FAQ delle categorie (cliente, 25/09: «uniformiamo»). */
  .faq__q { font-size: 16px; }
  .faq .prose,
  .faq-list:not(.faq-list--numbered) .prose { font-size: 16px; line-height: 1.4; }
  /* FAQ delle categorie (le grigie): domanda e risposta sulla stessa linea a sinistra,
     18px dal bordo della card. La domanda partiva a 35 (rientro del frame desktop) e
     la risposta a 18 (cliente, 25/09: «tutte allineate a sinistra, sia titolo che
     paragrafo»). Stesso selettore della regola desktop, che qui viene battuta per ordine. */
  .faq-list:not(.faq-list--numbered) .faq > summary { padding: 13.5px 16px 13.5px 18px; }

  .gallery__thumbs { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }

  /* SCHEDA TECNICA SENZA SCORRIMENTO ORIZZONTALE (cliente, 25/09). Tre cause, tre cure:
     - le linguette (Informazioni tecniche / Dimensioni / MOQ / Documenti) erano una
       riga da 486px in 348: ora una griglia a due colonne, righe separate da un filo
       di 1px (il fondo della lista che si vede nel `gap`), l'ultima dispari a tutta
       larghezza; l'etichetta puo' andare a capo;
     - la tabella tecnica aveva `min-width: 320px` in 300 disponibili;
     - la tabella delle dimensioni aveva intestazioni e celle `nowrap` (489px): ora
       colonne fisse, intestazioni che vanno a capo e senza maiuscoletto. Resta una
       TABELLA (fino a 21 righe per 4 colonne: in schede impilate sarebbe lunga metri). */
  .tabs__list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1px;
    overflow: visible;
    background: #EDEDED;
    border-bottom: 1px solid #EDEDED;
  }
  .tabs__tab {
    margin: 0;
    padding: 12px 10px;
    border: 0;
    background: var(--white);
    font-size: 14px;
    line-height: 1.25;
    white-space: normal;
  }
  .tabs__tab:last-child:nth-child(odd) { grid-column: 1 / -1; }
  /* anello di focus DENTRO la linguetta: fuori (offset +2) lo tagliava l'overflow
     di .tabs e lo copriva il bianco della linguetta accanto — da tastiera la prima
     tab non mostrava nessun segno di focus (verifica del 25/09, Chrome e WebKit) */
  .tabs__tab:focus-visible { outline-offset: -5px; }
  .tabs__tab[aria-selected="true"],
  .tabs__tab.is-active { border-bottom-color: transparent; }
  .tabs__panel { padding: 18px 16px; }
  .spec-table { min-width: 0; font-size: 14px; }
  .spec-table th,
  .spec-table td { padding: 11px 6px; }
  .spec-table th,
  .spec-table tbody th { width: 40%; }
  /* Colonne AUTOMATICHE e sillabazione italiana (<html lang="it">): con colonne fisse
     e `overflow-wrap: anywhere` le parole si spezzavano a caso e senza trattino
     («Capacit/à», «Larghez/za», «PFP2/8») in 123 schede su 211 a 320px. Qui le
     intestazioni vanno a capo con il trattino («Capaci-tà») e i codici (24/410)
     restano interi; `break-word` interviene solo se una parola non ci sta proprio,
     e non restringe le colonne come faceva `anywhere`. */
  /* Sillabazione SOLO nelle intestazioni, con i limiti in entrambe le sintassi (WebKit
     ignora hyphenate-limit-chars e spezzava «Ca-pacità» dopo due lettere). Le celle non
     si spezzano mai: sono misure e codici («PFP28», «24/410»), e `break-word` in una
     cella WebKit lo conta nella larghezza minima della colonna, cioe' li spezzava. */
  .dim-table { table-layout: auto; font-size: 13px; }
  .dim-table th,
  .dim-table td { padding: 9px 4px; white-space: normal; overflow-wrap: normal; }
  .dim-table thead th {
    font-size: 12px;
    letter-spacing: 0;
    text-transform: none;
    line-height: 1.25;
    -webkit-hyphens: auto;
    hyphens: auto;
    hyphenate-limit-chars: 7 3 3;
    -webkit-hyphenate-limit-before: 3;
    -webkit-hyphenate-limit-after: 3;
  }

  .form-card { grid-template-columns: minmax(0, 1fr); padding: 20px; }
  /* il modulo a pillole (contatti) non ha pannello: i 20px qui sopra gli toglievano
     40px di larghezza ai campi (310 su 350). Richiesta della cliente del 25/09:
     «allarga i campi di compilazione... larghi quanto la larghezza del sito». */
  .form-card--pill { padding: 0; }

  /* --- Richieste della cliente del 25/09 sul telefono ------------------------ */

  /* Gerarchia dei titoli nelle sottocategorie (vedi la regola desktop in §12): il
     catalogo prende l'h2 del telefono, la fascia impilata scende all'h3. */
  body.page--subcategory .band--catalog .section__head h2 { font-size: var(--h2); }
  body.page--subcategory .media-text--stack .media-text__body h2 { font-size: var(--h3); }

  /* Testi a bandiera sinistra su tutto il sito: le testate e i blocchi che il
     desktop centra tornano a sinistra insieme al loro contenitore (margin-inline
     auto -> 0, place-items, justify-content), altrimenti restano centrati come
     scatola e allineati a sinistra come testo, che e' peggio di entrambi. */
  .section__head--center,
  .hero--center,
  .hero--center .hero__text,
  .cta-band,
  .cta-band__body,
  .band--related h2,
  .band--related .prose,
  .band--related .band__cta,
  .media-text--cover .media-text__cover,
  .feature-card,
  .contact-card,
  .cards-band--photo .card--photo .card__title,
  .cards-band--photo .card--photo .card__cta,
  .product-card--slim h3,
  .catalog__empty { text-align: left; }
  .section__head--center,
  .section__head--center .prose,
  .page--home .cards-band--cipria .section__head--center h2,
  .hero--center .hero__text,
  .hero--center .hero__text .prose,
  .band--related .prose,
  .band--related .related__badge,
  .media-text--cover .prose { margin-inline: 0; }
  .band--related .product-grid,
  .cards-band--photo .grid { justify-content: flex-start; }
  .media-text--cover .media-text__cover { place-items: start; }
  .feature-card { align-items: flex-start; }

  /* Box (tile cipria della home e delle categorie, card «perche' scegliere»):
     icona, testo e pulsante al centro dell'altezza, non in alto. Il link non
     spinge piu' verso il fondo (margin-top: auto), il padding torna simmetrico.
     Le tile non hanno piu' un'altezza minima (seconda richiesta del 25/09: «i box
     rosa possiamo farli piu' stretti in termini di altezza»): a tutta larghezza il
     contenuto sta in 210px e i 375/495 del desktop, tarati su tre o quattro colonne,
     lasciavano 80px di vuoto sopra e sotto. Restano 26px di aria per lato. */
  .card--cipria,
  .card--icon { justify-content: center; }
  .card--cipria .link,
  .card--icon .link { margin-top: 0; }
  .card--cipria,
  .page--home .cards-band--cipria .card--cipria,
  .cards-band--cipria .grid--fixed-3 .card--cipria { min-height: 0; padding: 26px 22px; }
  /* ...e l'icona delle tile di categoria torna a misura da telefono: le regole
     desktop (area icona 115 + 37 di margine, disegni da 59 a 106) la tenevano a
     152px e la tile restava 373 anche senza altezza minima (verifica del 25/09).
     Con 44px, come le altre icone di card, la tile scende sotto i 280. */
  .cards-band--cipria .grid--fixed-3 .card__icon { height: 44px; margin-bottom: 10px; }
  .cards-band--cipria .grid--fixed-3 .card__icon svg { width: auto; height: 44px; }

  /* Interruttore un/due prodotti per riga (macro product_grid): esiste solo qui.
     A una colonna la card mostra anche la descrizione, che a due e' nascosta
     (regola piu' sopra in questo blocco). */
  .grid-switch { display: inline-flex; }
  .product-grid--cols-1 { grid-template-columns: minmax(0, 1fr); }
  .product-grid--cols-1 .product-card p { display: block; }

  /* Scheda prodotto: la foto grande e' un rettangolo orizzontale anche sul telefono.
     Era 1/.85, poi 3:2 (25/09, prima consegna) — «ancora troppo alta»: 16:9, con il
     bordo bianco ridotto a 10 perche' la foto (648x545) ci sta in altezza e non deve
     rimpicciolire troppo. Resta `contain`: e' la foto principale del prodotto e un
     taglio ai lati toglierebbe pezzi di scatti larghi. */
  .gallery__main img { aspect-ratio: 16 / 9; padding: 10px; }

  /* Correlati: da griglia 2x2 a scorrimento orizzontale, se ne vede uno e mezzo
     (64% della colonna, quindi 1,56 card a 390). Lo scorrimento sfonda i margini
     della pagina e il primo elemento parte dal bordo del contenuto (scroll-padding);
     le card si agganciano a sinistra. Vale anche per i correlati per categoria, che
     stanno nella stessa griglia. `grid-template-columns: none` toglie le due colonne
     esplicite di .product-grid--compact, che altrimenti verrebbero prima delle
     colonne implicite. */
  .band--related .product-grid {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 64%;
    grid-template-columns: none;
    gap: 12px;
    justify-content: start;
    margin-inline: calc(-1 * var(--page-pad));
    padding: 4px var(--page-pad) 10px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--page-pad);
    scrollbar-width: none;
  }
  .band--related .product-grid::-webkit-scrollbar { display: none; }
  .band--related .product-grid > .product-card { max-width: none; scroll-snap-align: start; }

  /* Risultati della ricerca: la riga tiene foto e testo affiancati, il pulsante
     scende sotto il testo (nella colonna del testo). */
  .search-result { grid-template-columns: 84px minmax(0, 1fr); gap: 10px 12px; padding: 12px; }
  .search-result__cta { grid-column: 2; justify-self: start; }
  .search-result__title { font-size: 17px; }
  /* il pulsante della riga a misura di didascalia: a 46px di altezza «prendeva il
     sopravvento visivo su tutto il resto» (cliente, 25/09) */
  .search-result__cta .btn { min-height: 34px; padding: 5px 14px; font-size: 13px; }

  /* Contatti: i recapiti in righe compatte (icona a sinistra, valore accanto) al
     posto delle card da 160px, e il pannello sedi senza l'altezza minima e con
     l'interlinea del desktop dimezzata: «le informazioni generali non le lascerei
     dentro a box cosi' grandi». */
  .contact-cards { gap: 10px; margin-top: 24px; }
  .contact-card {
    flex-direction: row;
    align-items: center;
    gap: 14px;
    min-height: 0;
    padding: 12px 16px;
  }
  .contact-card__icon { flex: none; height: 24px; }
  .contact-card__value { font-size: 15px; }
  .locations { min-height: 0; margin-top: 24px; padding: 20px 18px; row-gap: 16px; }
  .location__title { margin-bottom: 2px; line-height: 1.4; }
  .location__address,
  .location__hours { line-height: 1.5; }

  /* Footer compatto (richiesta 25/09: era alto 2150px, tre schermate; scelta
     dell'utente: due colonne affiancate e testi compatti, niente fisarmonica).
     Corpo 15, passi stretti, e le quattro colonne del menu a coppie con le righe
     pareggiate: Packaging (6 voci) con Accessori (2) sotto a sinistra, Settori (8)
     con Servizi (3) sotto a destra — cosi' la riga alta e' 8 e la bassa 3, invece di
     8 + 6 se Packaging e Settori stessero una sopra l'altra. Le regole sotto i 1024
     rimettono i piazzamenti ad `auto` con :nth-child(n): questi vengono dopo e
     hanno la stessa specificita'. */
  .site-footer { margin-inline: 12px; padding: 36px 0 20px; }
  .site-footer > .container { gap: 24px; }
  .site-footer__brand { gap: 6px; }
  .site-footer__logo-img { width: 150px; }   /* «il logo footer mobile fallo piu' piccolo» (25/09) */
  .site-footer__legal-name { margin: 2px 0 4px; font-size: 17px; }
  .site-footer__contact { margin-bottom: 4px; font-size: 15px; }
  .site-footer__follow { margin: 10px 0 6px; font-size: 15px; }
  .site-footer__nav { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto auto; gap: 18px 16px; }
  .site-footer__col:nth-child(1) { grid-column: 1; grid-row: 1; }
  .site-footer__col:nth-child(2) { grid-column: 1; grid-row: 2; }
  .site-footer__col:nth-child(3) { grid-column: 2; grid-row: 2; }
  .site-footer__col:nth-child(4) { grid-column: 2; grid-row: 1; }
  .site-footer__col-title { margin-bottom: 8px; font-size: 16px; }
  .site-footer__col-list li { margin-bottom: 5px; }
  .site-footer__col-list a { font-size: 15px; }
  .site-footer__legal { gap: 8px 14px; }
  .site-footer__legal a { font-size: 15px; }
  .newsletter__form { max-width: none; }
  .newsletter__title { margin-bottom: 4px; }
  .newsletter__text { margin-bottom: 10px; }
  /* «Email» sopra il campo: tolta a video sul telefono (cliente, 25/09), non dal
     documento — e' l'etichetta del campo e lo screen reader continua a leggerla; a
     vista basta il segnaposto «La tua email». Stessa tecnica di .sr-only. */
  .newsletter__form .field[data-field="email"] > label {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
  /* «Iscriviti» a colori invertiti (cliente, 25/09): navy sul navy del footer, senza
     un hover che lo sveli, sul telefono si leggeva come testo semplice. Bianco con
     scritta e freccia navy; la regola batte anche .btn--blu:hover (stessa
     specificita', viene dopo), cosi' dopo un tocco non torna blu. Desktop invariato. */
  .newsletter__form .btn { --btn-bg: var(--white); --btn-fg: var(--navy); }
  .site-footer__bottom { gap: 4px; padding-top: 18px; font-size: 14px; }
  .site-footer__consent { font-size: 14px; }
  .consent { left: 12px; right: 12px; bottom: 12px; width: auto; }
}
/* Telefono girato: il pavimento di 460 dell'hero della home, pensato per il
   verticale, lo faceva alto 1,4 schermi e la CTA finiva sotto la piega (667x375,
   740x360, 640x360 — verifica del 25/09). In orizzontale torna ai 320 di prima. */
@media (max-width: 767px) and (max-height: 500px) {
  .hero--full .hero__inner { min-height: 320px; }
  /* ...e la mappa dei contatti prende il quadrato del tablet: in 3/4 a 667x375 era
     alta 836px, piu' di due schermi */
  .map-static { aspect-ratio: 1 / 1; }
}
/* A 320 «Richiedi una consulenza» chiede 281px contro i 280 della colonna e andava
   su due righe (anche prima del 25/09): 4px di imbottitura in meno la tengono su una. */
@media (max-width: 340px) {
  .hero--full .hero__cta .btn { padding-left: 16px; }
}

/* --- senza JS il menu resta navigabile (nessun flash: la query non matcha
   quando lo scripting e' attivo) ------------------------------------------- */
@media (scripting: none) {
  /* lo slider dell'hero non puo' scorrere: le slide tornano una sotto l'altra */
  .hero-slider__viewport { display: block; }
  .hero-slider__slide { opacity: 1; visibility: visible; }
  .hero-slider__dots { display: none; }
  /* i filtri non filtrano (vivono solo in main.js) e il pannello del telefono non
     si apre: meglio non mostrare comandi inerti. Resta la griglia intera, che e'
     il ripiego onesto. */
  .filters,
  .filters-toggle { display: none !important; }
  .mega { display: none !important; }
  .nav-item:hover > .mega,
  .nav-item:focus-within > .mega { display: block !important; }
  .site-header__bar-inner:has(.nav-item.has-mega--wide:hover),
  .site-header__bar-inner:has(.nav-item.has-mega--wide:focus-within) {
    border-bottom-color: transparent;
    border-radius: var(--r-menu) var(--r-menu) 0 0;
  }
}

@media (max-width: 1024px) and (scripting: none) {
  .site-nav { position: static; display: block; max-height: none; padding: 8px 0 0; box-shadow: none; }
  .nav-burger { display: none; }
  .mega { display: block !important; }
  .site-header__bar-inner { flex-direction: column; align-items: stretch; }
  /* col menu esploso l'header e' alto quanto una pagina (2437px misurati): incollato
     allo scorrimento copriva TUTTO cio' che stava sotto. Senza JS resta in cima. */
  .site-header { position: static; }
}

/* =============================================================================
   22. STAMPA
   ============================================================================= */
@media print {
  :root { --band-pad: 18px; --page-pad: 0; }
  html, body { background: #fff; color: #000; font-size: 12pt; }
  .site-header, .site-footer, .consent, .skip-link,
  .filters, .site-search, .nav-burger, .breadcrumb, .hero-slider__dots,
  .band--cta, .band--related, .band--news { display: none !important; }
  /* in stampa le slide dell'hero escono tutte, una sotto l'altra */
  .hero-slider__viewport { display: block; }
  .hero-slider__slide { opacity: 1; visibility: visible; }
  .band { padding-block: 12pt; break-inside: avoid; }
  .card, .faq, .form-card, .tabs { box-shadow: none; border: 1px solid #ccc; }
  .grid, .product-grid, .news-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  a { color: #000; text-decoration: underline; }
  .btn { border: 1px solid #000; background: none; color: #000; }
  img { max-width: 100%; break-inside: avoid; }
  .tabs__panel[hidden] { display: block !important; }
  .faq .prose { display: block; }
}

/* =============================================================================
   23. PREFERS-REDUCED-MOTION
   ============================================================================= */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .card--link:hover,
  .card--cipria:hover,
  .btn:hover,
  .product-card > a:hover img,
  .card--photo:hover .card__media img,
  .card--tile:hover .card__media img,
  .card--row:hover .card__media img,
  .news-card:hover .news-card__media img { transform: none; }
  .mega { animation: none; }
  /* niente ritardo sulla visibilita' del pannello dei filtri e del suo sfondo: la
     regola generale qui sopra accorcia la durata, non il delay, e per 280ms lo sfondo
     invisibile inghiottiva i tocchi (verifica del 25/09) */
  .filters,
  .filters-backdrop { transition: none !important; }
}
