/* components.css — contract_textile. Vetrina di prodotti di pregio: bianco dominante, BANDE PIENE di
   marca che incorniciano la pagina, fotografia grande a colori pieni, spazi ariosi.
   I colori arrivano SOLO dai token (tokens.css): qui non si dichiarano hex.
   ⚠ Contratto a11y: --azure è SUPERFICIE (mai testo, non regge nemmeno il bianco); il testo azzurro è
   --azure-ink. La CTA piena è --deep + bianco. Vedi l'intestazione di tokens.css. */

:root { --dur: 200ms; --ease: cubic-bezier(.2,.6,.2,1); }

/* ============================ Bottoni ============================
   Il cliente ha chiesto di "valorizzare i CTA con delle ombreggiature": la CTA piena porta un'ombra
   di marca (blu, non grigia) che si alza all'hover. Pill, come il lettering tondo del logo. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-6);
  font-family: var(--font-body); font-weight: 700; font-size: .95rem;
  border-radius: var(--radius-pill); border: 2px solid transparent;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
/* ⚠ Fondo --deep, MAI --azure: bianco su azzurro fa 4.49 (sotto AA). Su --deep fa 15.26. */
.btn--accent { background: var(--deep); color: var(--on-dark); box-shadow: var(--shadow-cta); }
.btn--accent:hover { background: var(--navy); box-shadow: var(--shadow-cta-hover); transform: translateY(-2px); }
.btn--ghost { border-color: var(--azure); color: var(--azure-ink); background: transparent; }
.btn--ghost:hover { background: var(--azure); color: var(--on-dark); border-color: var(--azure); }
/* Su fondo scuro il contorno è bianco: --azure-ink su navy sarebbe 3.19. */
.btn--ghost-on-dark { border-color: var(--on-dark); color: var(--on-dark); background: transparent; }
.btn--ghost-on-dark:hover { background: var(--on-dark); color: var(--deep); }
@media (prefers-reduced-motion: reduce) { .btn:hover { transform: none; } }

/* ============================ Header: BARRA BIANCA, UNA RIGA ============================
   Il cliente vuole il logo "fuori la foto oppure su barra bianca" e le voci di menu "in blu, che diventano
   azzurre". Su banda navy l'azzurro del logo scende a 3.69 ⇒ barra BIANCA (la banda di marca vive nel
   footer e negli scrim). ⚠ Header a UNA RIGA (come gli altri siti), centrato verticalmente: logo + 8 voci
   + CTA ci stanno perché il TELEFONO NON è in header (ridondante: footer, Contatti, e il CTA dice già
   "Contattaci"). La nav inline sta in riga fino a ~1150px; sotto, hamburger (WP collassa solo a 600px →
   la soglia la alziamo noi). */
.site-header { background: var(--paper); border-bottom: 1px solid var(--line); position: relative; z-index: 20; }
.site-header__row {
  display: flex; align-items: center; gap: clamp(0.75rem, 0.1rem + 1vw, 1.5rem);
  padding-block: var(--space-3); flex-wrap: nowrap; max-width: 1500px;
}
/* Un margine di blocco su un figlio lo spinge fuori dal centro della riga. */
.site-header__row > * { align-self: center; margin-block: 0; }
.site-nav { flex: 1 1 auto; }   /* la nav prende lo spazio in mezzo e allinea le voci a destra */

/* Logo: GRANDE (era il reclamo). Il lockup è un'immagine sola, non ridotta a un mark quadrato.
   max-width alto: il wordmark è largo per natura e non va strozzato. */
.wordmark { display: inline-flex; align-items: center; gap: var(--space-3); flex: none; }
.wordmark__logo { height: 32px; width: auto; max-width: min(50vw, 400px); object-fit: contain; }
.wordmark__txt {
  font-family: var(--font-display); font-weight: 700; font-size: 1.5rem; color: var(--deep);
  letter-spacing: -0.01em; line-height: 1.05; display: inline-flex; flex-direction: column;
}
.wordmark__txt small { font-family: var(--font-body); font-weight: 600; font-size: .62rem;
  letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-muted); }
.site-footer .wordmark__logo { height: 32px; }

/* Nav: Sentence case (richiesta esplicita), voci in --deep, ATTIVA/hover in --azure-ink col filetto
   --azure sotto. ⚠ Niente text-transform:uppercase: il maiuscolo è largo ed è metà del motivo per cui
   il menu del sito bocciato andava a capo. */
.site-nav .wp-block-navigation__container { gap: clamp(.4rem, .05rem + .7vw, 1.05rem); flex-wrap: nowrap; }
.site-nav .wp-block-navigation-item__content {
  font-family: var(--font-display); font-weight: 600; font-size: .95rem;
  color: var(--deep); text-transform: none; white-space: nowrap;
  padding-block: 0.5rem; position: relative;
  transition: color var(--dur) var(--ease);
}
.site-nav .wp-block-navigation-item__content::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--azure); border-radius: 2px; transform: scaleX(0);
  transform-origin: left; transition: transform var(--dur) var(--ease);
}
.site-nav .wp-block-navigation-item__content:hover { color: var(--azure-ink); }
.site-nav .wp-block-navigation-item__content:hover::after { transform: scaleX(1); }
/* Stato ATTIVO: la pagina in cui ci si trova. WP marca la voce con .current-menu-item. */
.site-nav .wp-block-navigation-item.current-menu-item > .wp-block-navigation-item__content,
.site-nav .wp-block-navigation-item.current_page_item > .wp-block-navigation-item__content {
  color: var(--azure-ink);
}
.site-nav .wp-block-navigation-item.current-menu-item > .wp-block-navigation-item__content::after,
.site-nav .wp-block-navigation-item.current_page_item > .wp-block-navigation-item__content::after {
  transform: scaleX(1);
}

.site-header__cta { flex: none; padding-block: var(--space-2); font-size: .9rem; }

/* ⚠ La nav inline con 8 voci sta in riga solo ≳1200px. WP collassa a hamburger solo a 600px, lasciando
   un buco 600–1200px dove la nav sborda. Alzo la soglia a 1200px: sotto, forzo l'hamburger (mostro il
   bottone di WP, nascondo la lista inline). L'overlay è lo stesso (già a prova di regola 23). */
@media (max-width: 1200px) {
  .wp-block-navigation__responsive-container-open { display: flex !important; }
  .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container { display: none; }
  /* L'hamburger va a DESTRA, staccato dal logo: margin-left:auto lo spinge al bordo destro della riga. */
  .site-nav { flex: 0 0 auto; margin-left: auto; }
  /* Hamburger a 3 barrette (l'icona di WP ne ha solo 2): la nascondo e la ridisegno. */
  .wp-block-navigation__responsive-container-open {
    width: 34px; height: 34px; padding: 0; border: 0; background: transparent; cursor: pointer; position: relative;
  }
  .wp-block-navigation__responsive-container-open svg { display: none; }
  .wp-block-navigation__responsive-container-open::before {
    content: ""; position: absolute; left: 6px; right: 6px; top: 9px; height: 2.5px;
    background: var(--deep); border-radius: 2px;
    box-shadow: 0 7px 0 var(--deep), 0 14px 0 var(--deep);   /* + linea centrale + linea inferiore = 3 */
  }
}
/* Sotto i 900px: CTA fuori (è nella cta-bar fissa) e logo un filo più piccolo. */
@media (max-width: 900px) {
  .wordmark__logo { height: 30px; }
  .site-header__cta { display: none; }
}

/* Overlay mobile di wp:navigation: FISSO a tutto schermo, fondo --deep.
   ⚠⚠ REGOLA 23: il fondo BIANCO dell'overlay viene da WP con selettore a specificità 0,4,0
   (`.wp-block-navigation:not(.has-background) …:not(.disable-default-overlay)`) e le VOCI sono bianche →
   bianco-su-bianco, l'overlay sembra vuoto. Un `.is-menu-open{background}` (0,2,0) PERDE. Si vince solo
   RICOPIANDO il suo schema di specificità. Idem per la posizione/altezza. */
.wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay),
.wp-block-navigation__responsive-container.is-menu-open {
  position: fixed; inset: 0; z-index: 99999;
  height: 100vh; width: 100vw; overflow-y: auto; background: var(--deep);
  padding: 5rem var(--gutter) 6rem; display: flex; flex-direction: column; justify-content: center;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
  color: var(--on-dark); font-size: 1.25rem; width: 100%; padding-block: var(--space-3);
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content::after { display: none; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container { gap: 0; flex-wrap: wrap; }
.wp-block-navigation__responsive-container-close, .wp-block-navigation__responsive-container-open { color: var(--deep); }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close { color: var(--on-dark); }

/* ============================ Hero: foto grande, testo centrato ============================
   Il cliente si lamenta che l'header foto è "sgranato": qui la foto è full-bleed e va scelta hero-grade
   (>=1600x900) o presa dai RENDER. Senza foto (demo) resta una banda navy piena: mai una foto finta. */
.hero {
  position: relative; background: var(--navy); color: var(--on-dark);
  min-height: min(80vh, 680px); display: flex; align-items: center;
  overflow: hidden; isolation: isolate; text-align: center;
}
.hero-media { position: absolute; inset: 0; z-index: -2; overflow: hidden; background: var(--navy); }
.hero-slide { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; }
.hero-slide:nth-child(1) { opacity: 1; }
/* ⚠ Uno scrim NON basta a garantire il contrasto: queste foto (camere d'albergo, barche, dehors) hanno
   finestre e soffitti BIANCHI PURI. Misurato: col solo scrim il bianco sul pixel peggiore fa 2,96 — sotto
   perfino la soglia 3:1 del testo grande — e axe NON lo vede (non valuta il testo sopra un'immagine).
   Quindi il testo sta su una TARGA piena: targa .55 + scrim .25 = alpha efficace .66 -> bianco 5,55 sul
   pixel peggiore possibile. Il contrasto non dipende più dal fotogramma, e lo scrim leggero lascia viva la
   foto (sono prodotti di pregio: la foto è il prodotto). */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(var(--navy-rgb),.30) 0%, rgba(var(--navy-rgb),.22) 45%, rgba(var(--navy-rgb),.38) 100%);
}
.hero__inner { position: relative; padding-block: var(--space-9); width: 100%; }
.hero__text {
  max-width: 48rem; margin-inline: auto; display: flex; flex-direction: column;
  gap: var(--space-5); align-items: center;
  background: rgba(var(--navy-rgb), .55);
  padding: clamp(2rem, 1.4rem + 2.4vw, 3.25rem) clamp(1.5rem, 1rem + 2vw, 3rem);
  border-radius: var(--radius-lg);
}
.hero__text h1 { color: var(--on-dark); }
/* ⚠ Sulla TARGA il testo è SOLO bianco. I token "on dark" (--azure-lt 6,42 · --muted-on-dark 10,24) sono
   tarati sulla banda navy PIENA: sulla targa semitrasparente il fondo è più chiaro (misurato 102,98,137)
   e lì scendono a 2,22 e 3,54. axe non lo coglie (sopra un'immagine non valuta), quindi la regola è esplicita. */
.hero__text .eyebrow--light { color: var(--on-dark); }
.hero__text .eyebrow--light::before { background: var(--on-dark); }
/* La misura di lettura sta sul PARAGRAFO, mai sul contenitore del display: un max-width sul wrapper
   strozzerebbe anche il titolo (errore ripetuto 4 volte in questo repo). */
.hero__text .lead { color: var(--on-dark); max-width: 42rem; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-4); justify-content: center; }

@media (prefers-reduced-motion: no-preference) {
  .hero-slide { animation: fp-hero-fade 32s linear infinite; }
  .hero-slide:nth-child(2) { animation-delay: 8s; }
  .hero-slide:nth-child(3) { animation-delay: 16s; }
  .hero-slide:nth-child(4) { animation-delay: 24s; }
}
@keyframes fp-hero-fade {
  0%   { opacity: 0; transform: scale(1.0); }
  3%   { opacity: 1; }
  22%  { opacity: 1; }
  27%  { opacity: 0; }
  100% { opacity: 0; transform: scale(1.06); }
}

/* ============================ Intro di sezione ============================ */
.section-intro { max-width: 52rem; }
.section-intro--center { margin-inline: auto; text-align: center; align-items: center; }
.section-intro--center .lead { margin-inline: auto; max-width: 44rem; }

/* ============================ Manifesto (Chi siamo) ============================ */
.manifesto__grid { display: grid; grid-template-columns: 1fr; gap: var(--space-6); align-items: start; }
@media (min-width: 900px) { .manifesto__grid { grid-template-columns: 0.85fr 1fr 0.8fr; gap: var(--space-7); align-items: center; } }
/* La tessera chiude la riga: senza, «Chi siamo» è una colonna di prosa e basta — il "spoglio" del cliente. */
.manifesto__fig { margin: 0; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card-hover); }
.manifesto__fig img { width: 100%; aspect-ratio: 3/4; object-fit: cover; display: block; }
@media (max-width: 899px) { .manifesto__fig { display: none; } }
.manifesto__body { display: flex; flex-direction: column; gap: var(--space-4); max-width: 62ch; }
/* Size PROPRIA e non --text-2xl: la copy reale del cliente supera i 100 caratteri, dove una size da
   titolo breve frantuma la colonna (lezione DeMartini: 123 char su una size tarata su 67). */
.statement { font-family: var(--font-display); font-weight: 600; color: var(--deep);
  font-size: clamp(1.6rem, 1.1rem + 1.9vw, 2.3rem); line-height: var(--lh-snug); }

/* Striscia credenziali: dà autorità subito dopo il "Chi siamo", chiude la sezione con ritmo.
   Filetto azzurro in cima a ogni voce, numerali nel display. */
.creds { display: grid; grid-template-columns: 1fr; gap: var(--frame-gap); margin-top: var(--space-8); }
@media (min-width: 560px) { .creds { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px) { .creds { grid-template-columns: repeat(4, 1fr); } }
.creds__item { border-top: 3px solid var(--azure); padding-top: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.creds__n { font-family: var(--font-display); font-weight: 700; font-size: 1.35rem; color: var(--deep); }
.creds__l { color: var(--ink-muted); font-size: .9rem; line-height: 1.4; }

/* ============================ Offerta: card = foto + BANDA di caption ============================
   È il dispositivo del template: la foto non è mai nuda, porta una banda piena di marca col titolo.
   Il cliente vuole le foto "staccate da una cornice o bordatura", MAI appiccicate: gutter netto +
   cornice bianca + filetto azzurro. */
/* Flex e non grid: le categorie sono CINQUE e in una griglia a 3 colonne le ultime due restano appese a
   sinistra come un avanzo. Col flex la riga orfana si centra da sola, qualunque sia il numero di voci. */
.ocards { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--frame-gap); margin-top: var(--space-7); }
.ocard { flex: 0 1 100%; }
@media (min-width: 640px) { .ocard { flex-basis: calc(50% - var(--frame-gap) / 2); } }
@media (min-width: 1000px) { .ocard { flex-basis: calc(33.333% - var(--frame-gap) * 2 / 3); } }
.ocard {
  display: flex; flex-direction: column; background: var(--paper);
  border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: var(--shadow-card); transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.ocard:hover { box-shadow: var(--shadow-card-hover); transform: translateY(-3px); }
.ocard:focus-within { outline: 2px solid var(--focus); outline-offset: 3px; }
.ocard__media { display: block; aspect-ratio: 4 / 3; background: var(--surface); overflow: hidden; }
.ocard__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 600ms var(--ease); }
.ocard:hover .ocard__media img { transform: scale(1.04); }
/* La banda: piena, testo bianco su --navy (16.5:1). */
.ocard__band {
  display: block; background: var(--navy); color: var(--on-dark);
  font-family: var(--font-display); font-weight: 600; font-size: 1.1rem;
  padding: var(--space-3) var(--space-5);
}
.ocard__text { display: block; padding: var(--space-5); color: var(--ink-muted); font-size: .95rem; }
@media (prefers-reduced-motion: reduce) {
  .ocard:hover { transform: none; }
  .ocard:hover .ocard__media img { transform: none; }
}


/* Chip dei settori (Gallery): pastiglie a filetto, non bottoni. */
.chips { display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: center; margin-top: var(--space-6); }
.chip { font-family: var(--font-display); font-weight: 600; font-size: .95rem; color: var(--deep);
  padding: var(--space-2) var(--space-5); border: 1px solid var(--azure); border-radius: var(--radius-pill); }

/* Card offerta: affordance "Scopri" che appare all'hover (2026, senza rumore). */
.ocard__go { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--azure-ink);
  font-weight: 700; font-size: .9rem; padding: 0 var(--space-5) var(--space-5); opacity: 0;
  transform: translateX(-4px); transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease); }
.ocard:hover .ocard__go, .ocard:focus-within .ocard__go { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .ocard__go { opacity: 1; transform: none; } }

/* ============================ Metodo: quattro passi ============================ */
.pattern-steps { display: grid; gap: var(--space-6); grid-template-columns: 1fr; margin-top: var(--space-7); }
@media (min-width: 700px) { .pattern-steps { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .pattern-steps { grid-template-columns: repeat(4, 1fr); } }
.pstep { padding: var(--space-5); border-top: 3px solid var(--azure); background: var(--paper);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
.pstep__n { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; color: var(--azure-ink);
  letter-spacing: var(--tracking-label); display: block; margin-bottom: var(--space-2); }
.pstep h3 { margin-bottom: var(--space-2); }
.pstep__text { color: var(--ink-muted); font-size: .95rem; }

/* ============================ Settori: banda navy piena + tessere foto ============================ */
.settori__head { display: grid; grid-template-columns: 1fr; gap: var(--space-5); align-items: end; }
@media (min-width: 900px) { .settori__head { grid-template-columns: 1fr 1fr; gap: var(--space-8); } }
.settori__body { max-width: 60ch; }
.stiles { display: grid; gap: var(--frame-gap); grid-template-columns: 1fr; margin-top: var(--space-7); }
@media (min-width: 640px) { .stiles { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .stiles { grid-template-columns: repeat(4, 1fr); } }
/* Cornice chiara attorno alla foto: staccata dalla banda navy, mai a filo. */
.stile { background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.16);
  border-radius: var(--radius-lg); overflow: hidden; display: flex; flex-direction: column; }
.stile__media { display: block; aspect-ratio: 3 / 4; background: rgba(255,255,255,.08); overflow: hidden; }
.stile__media img { width: 100%; height: 100%; object-fit: cover; }
.stile__cap { display: block; padding: var(--space-4) var(--space-5) var(--space-5); }
.stile__title { display: block; font-family: var(--font-display); font-weight: 600; font-size: 1.15rem;
  color: var(--on-dark); margin-bottom: var(--space-2); }
.stile__text { display: block; color: var(--muted-on-dark); font-size: .9rem; line-height: 1.55; }

/* ============================ Banda contatti (CTA finale) ============================ */
.cband__box { max-width: 46rem; margin-inline: auto; text-align: center;
  display: flex; flex-direction: column; gap: var(--space-4); align-items: center; }
.cband__actions { display: flex; flex-wrap: wrap; gap: var(--space-4); justify-content: center; margin-top: var(--space-3); }

/* ============================ Page-head (pagine interne) ============================
   Compatta: l'h1 NON usa la size dell'hero. Vale per tutte le pagine interne, si sistema una volta sola. */
.page-head { background: var(--surface); border-bottom: 1px solid var(--line); text-align: center;
  padding-block: clamp(2.5rem, 1.8rem + 3vw, 4rem); }
.page-head h1 { font-size: var(--text-2xl); color: var(--deep); }
.page-head .container { display: flex; flex-direction: column; gap: var(--space-4); align-items: center; }
.page-head .lead { max-width: 48rem; }

/* ============================ Pagina categoria ============================ */
.cat-split { display: grid; grid-template-columns: 1fr; gap: var(--space-6); align-items: start; }
@media (min-width: 900px) { .cat-split { grid-template-columns: 1.05fr .95fr; gap: var(--space-8); } }
.cat-split__text { max-width: 62ch; display: flex; flex-direction: column; gap: var(--space-4); }
.cat-split__fig { margin: 0; border-radius: var(--radius-lg); overflow: hidden; background: var(--surface);
  border: 1px solid var(--line); box-shadow: var(--shadow-card); min-height: 260px; }
.cat-split__fig img { width: 100%; height: 100%; object-fit: cover; }
.prose > * + * { margin-top: var(--space-4); }

/* ============================ Gallery: foto INCORNICIATE e STACCATE ============================
   Reclamo esplicito del cliente sui caroselli: mai foto a filo. Cornice bianca + filetto + gutter. */
.gal-grid { display: grid; gap: var(--frame-gap); grid-template-columns: 1fr; }
@media (min-width: 640px) { .gal-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .gal-grid { grid-template-columns: repeat(3, 1fr); } }
.gframe {
  margin: 0; background: var(--paper); padding: var(--frame-pad);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card); overflow: hidden;
  aspect-ratio: 4 / 3; min-height: 200px;
  transition: box-shadow var(--dur) var(--ease);
}
.gframe:hover { box-shadow: var(--shadow-card-hover); }
.gframe img { width: 100%; height: 100%; object-fit: cover; border-radius: 2px; }

/* ============================ Banda «I nostri brand» ============================
   Il docx la vuole «a fondo pagina HOME» coi marchi «che devono girare a catena»: nastro infinito.
   ⚠ I marchi VERI non ci sono ancora (lo dice il cliente: «dobbiamo richiedere a casa madre») e qui
   stanno dei SEGNAPOSTO NEUTRI, dichiarati tali: non si disegnano imitazioni di marchi altrui.
   Il nastro è duplicato e scorre di -50%: l'anello è continuo senza salti. La copia duplicata è
   aria-hidden e il viewport ha un aria-label unico (uno screen reader non legge 30 etichette). */
.brands { background: var(--paper); overflow: hidden; padding-block: var(--space-7);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.brands .eyebrow { justify-content: center; margin-bottom: var(--space-6); }
.brands__viewport { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.brands__track { display: flex; gap: clamp(2rem, 1rem + 3vw, 4.5rem); width: max-content; align-items: center; }
.brandmark {
  font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; white-space: nowrap;
  color: var(--deep); opacity: .72; letter-spacing: .04em;
  padding: var(--space-3) var(--space-5); border: 1px solid var(--line); border-radius: var(--radius);
  transition: opacity var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.brands__viewport:hover .brandmark { opacity: 1; border-color: var(--azure); }
.brands__note { color: var(--ink-muted); font-size: .8rem; text-align: center; margin-top: var(--space-5); }
@media (prefers-reduced-motion: no-preference) {
  .brands__track { animation: fp-marquee 42s linear infinite; }
  /* Il nastro si ferma al passaggio del mouse: si legge il marchio invece di inseguirlo. */
  .brands__viewport:hover .brands__track { animation-play-state: paused; }
}
@keyframes fp-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ============================ Pagina categoria: banda hero fotografica ============================
   Le pagine interne non vivono di una page-head tinta e basta: sono la VETRINA di un mestiere. La banda
   porta la foto grande (le foto sono del cliente) e il titolo su TARGA — stesso contratto dell'hero:
   il contrasto non dipende dal fotogramma. */
.page-hero { position: relative; min-height: clamp(320px, 34vw, 460px); display: flex; align-items: center;
  overflow: hidden; isolation: isolate; background: var(--navy); text-align: center; }
.page-hero__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: -2; }
.page-hero::after { content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(var(--navy-rgb),.32) 0%, rgba(var(--navy-rgb),.26) 50%, rgba(var(--navy-rgb),.42) 100%); }
.page-hero__plate { max-width: 46rem; margin-inline: auto; background: rgba(var(--navy-rgb), .55);
  padding: clamp(1.75rem, 1.2rem + 2vw, 2.75rem) clamp(1.25rem, 1rem + 1.6vw, 2.5rem);
  border-radius: var(--radius-lg); display: flex; flex-direction: column; gap: var(--space-4); align-items: center; }
.page-hero__plate h1 { color: var(--on-dark); font-size: var(--text-2xl); }
/* Sulla targa il testo è SOLO bianco: i token "on dark" sono tarati sulla banda PIENA (vedi hero). */
.page-hero__plate .eyebrow--light { color: var(--on-dark); }
.page-hero__plate .eyebrow--light::before { background: var(--on-dark); }
.page-hero__plate .lead { color: var(--on-dark); max-width: 40rem; }

/* Intro della categoria: statement + prosa, con una TESSERA che SCAVALCA la banda sopra (dispositivo
   Pafundi: dà profondità e lega le due sezioni invece di impilarle). */
.cat-intro { position: relative; }
.cat-intro__grid { display: grid; grid-template-columns: 1fr; gap: var(--space-6); align-items: start; }
@media (min-width: 900px) { .cat-intro__grid { grid-template-columns: 0.95fr 1.05fr; gap: var(--space-8); } }
.cat-intro__body { max-width: 62ch; display: flex; flex-direction: column; gap: var(--space-4); }
.cat-intro__tile { margin: 0; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card-hover);
  border: 6px solid var(--paper); }
@media (min-width: 900px) { .cat-intro__tile { margin-top: -6rem; } }   /* scavalca la banda */
.cat-intro__tile img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }

/* Blocchi alternati testo/foto: è ciò che toglie il "muro di prosa" alle pagine del cliente, che sono
   testi LUNGHI. Le foto si alternano di lato (mai una colonna sola di testo che scorre). */
.cat-block { display: grid; grid-template-columns: 1fr; gap: var(--space-6); align-items: center; }
/* Il margine sta TRA i blocchi, mai sul primo (col padding della banda collasserebbe e il titolo toccherebbe il bordo). */
.cat-block + .cat-block { margin-top: var(--space-8); }
@media (min-width: 900px) {
  .cat-block { grid-template-columns: 1fr 1fr; gap: var(--space-8); }
  .cat-block--flip .cat-block__fig { order: -1; }   /* sfalsate: la foto cambia lato a ogni blocco */
}
.cat-block__text { max-width: 60ch; display: flex; flex-direction: column; gap: var(--space-4); }
.cat-block__text h2 { margin-bottom: var(--space-2); }
.cat-block__fig { margin: 0; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card); }
.cat-block__fig img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block;
  transition: transform 700ms var(--ease); }
.cat-block__fig:hover img { transform: scale(1.03); }
@media (prefers-reduced-motion: reduce) { .cat-block__fig:hover img { transform: none; } }

/* Elenchi dei mestieri: pastiglie col filetto azzurro, non pallini di sistema. */
.checks { display: grid; grid-template-columns: 1fr; gap: var(--space-3); }
@media (min-width: 560px) { .checks { grid-template-columns: 1fr 1fr; } }
.checks li { display: flex; gap: var(--space-3); align-items: flex-start; color: var(--ink);
  padding: var(--space-3) var(--space-4); background: var(--surface); border-radius: var(--radius);
  border-left: 3px solid var(--azure); font-size: .95rem; }

/* ============================ Mosaico fotografico ============================
   Griglia ASIMMETRICA (alcune tessere scavalcano due colonne/righe): una griglia piatta di quadrati è
   quello che il cliente chiama "disordinato e spoglio". Cornice + gutter: il cliente vuole le foto
   STACCATE, mai appiccicate. */
/* Griglia UNIFORME: tutte le tessere 4/3, stessa dimensione → allineata, nessun buco (gli span
   sfalsati creavano vuoti brutti). Gutter + cornice: le foto restano staccate. */
.mosaic { display: grid; gap: var(--frame-gap); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 700px) { .mosaic { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1100px) { .mosaic { grid-template-columns: repeat(4, 1fr); } }
.mosaic figure { margin: 0; position: relative; overflow: hidden; border-radius: var(--radius-lg);
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-card);
  aspect-ratio: 4/3; transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease); }
.mosaic figure:hover { box-shadow: 0 16px 40px rgba(32,24,100,.20); transform: translateY(-4px); z-index: 2; }
.mosaic img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 800ms var(--ease); }
.mosaic figure:hover img { transform: scale(1.06); }
@media (prefers-reduced-motion: reduce) {
  .mosaic figure:hover { transform: none; }
  .mosaic figure:hover img { transform: none; }
}


/* «Perché noi»: tre tessere a numerali, riempiono il respiro sotto la scheda recapiti. */
.why { display: grid; grid-template-columns: 1fr; gap: var(--frame-gap); margin-top: var(--space-7); }
@media (min-width: 760px) { .why { grid-template-columns: repeat(3, 1fr); } }
.why__card { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: var(--space-6); box-shadow: var(--shadow-card); }
.why__n { font-family: var(--font-display); font-weight: 700; color: var(--azure-ink); font-size: 1.1rem;
  letter-spacing: var(--tracking-label); display: block; margin-bottom: var(--space-3); }
.why__card h3 { margin-bottom: var(--space-2); }
.why__card p { color: var(--ink-muted); font-size: .95rem; }

/* ============================ Pagina Contatti ============================
   Due colonne: a sinistra la foto della sede, a destra i recapiti in una scheda CHIARA (mai la banda
   scura dell'home-band: qui il fondo è bianco). Il markup è per-progetto (pages.json), ma le classi
   vivono QUI — un cliente non deve scrivere CSS. */
.contact-cols { display: grid; grid-template-columns: 1fr; gap: var(--space-6); align-items: start; }
@media (min-width: 900px) { .contact-cols { grid-template-columns: 1.15fr .85fr; gap: var(--space-8); } }
.contact-main h2, .contact-info h2 { margin-bottom: var(--space-4); }
.contact-hero { margin: 0; border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--line);
  box-shadow: var(--shadow-card); }
.contact-hero img { width: 100%; height: 100%; object-fit: cover; }
/* La didascalia dice COSA si sta guardando: senza, una foto di un loro lavoro sotto un titolo di sezione
   si legge come se fosse la loro sede. */
.contact-hero figcaption { padding: var(--space-3) var(--space-4); background: var(--surface);
  color: var(--ink-muted); font-size: .88rem; }
.contact-main > p { margin-bottom: var(--space-5); }
.contact-info { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: var(--space-6); }
.contact-info h3 { margin: var(--space-6) 0 var(--space-3); }
.contact-info .btn { margin-top: var(--space-5); }
.map-link { color: var(--azure-ink); text-decoration: underline; text-underline-offset: 3px;
  display: inline-block; margin-top: var(--space-4); }

/* Tabella orari: una TABELLA vera, non uno screenshot (nel materiale di questi clienti gli orari
   arrivano come immagini di tabelle Word: illeggibili per uno screen reader e invisibili a Google). */
.hours { border-collapse: collapse; width: 100%; }
.hours th, .hours td { text-align: left; padding: var(--space-2) 0; border-bottom: 1px solid var(--line);
  font-weight: 400; }
.hours th { color: var(--deep); font-weight: 700; padding-right: var(--space-4); white-space: nowrap; }
.hours td { color: var(--ink-muted); }
.hours .is-closed { color: var(--ink-muted); font-style: italic; }


/* Form di contatto first-party ([fp_contact_form]): campi puliti, moderni. */
.contact-form { display: flex; flex-direction: column; gap: var(--space-4); }
.contact-form .row { display: grid; grid-template-columns: 1fr; gap: var(--space-4); }
@media (min-width: 560px) { .contact-form .row { grid-template-columns: 1fr 1fr; } }
.contact-form .field { display: flex; flex-direction: column; gap: var(--space-2); }
.contact-form label { font-weight: 700; font-size: .9rem; color: var(--deep); }
.contact-form input, .contact-form textarea {
  font: inherit; color: var(--ink); background: var(--paper);
  border: 1px solid var(--line); border-radius: var(--radius); padding: var(--space-3) var(--space-4);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.contact-form input:focus, .contact-form textarea:focus {
  outline: none; border-color: var(--azure); box-shadow: 0 0 0 3px rgba(92,116,188,.18);
}
.contact-form textarea { resize: vertical; min-height: 8rem; }
.contact-form .consent { display: flex; gap: var(--space-3); align-items: flex-start; font-size: .9rem; color: var(--ink-muted); font-weight: 400; }
.contact-form .consent input { width: 1.1rem; height: 1.1rem; flex: none; margin-top: .15rem; }
.contact-form .btn { align-self: flex-start; margin-top: var(--space-2); }
.fp-form-notice { padding: var(--space-3) var(--space-4); border-radius: var(--radius); font-size: .95rem; }
.fp-form-notice.is-error { background: #fdecec; color: #8a1f1f; border: 1px solid #f0b8b8; }
.fp-form-notice.is-ok { background: var(--surface); color: var(--deep); border: 1px solid var(--azure); }

/* ============================ Footer ============================
   Il cliente vuole il logo "fuori la foto oppure su barra bianca", "non andare a capo" e un uso migliore
   del bold. Barra bianca col logo + banda navy a 3 colonne con etichette in bold e valori regular. */
.site-footer__logobar { background: var(--paper); border-top: 1px solid var(--line); padding-block: var(--space-5); }
.site-footer__main { background: var(--navy); color: var(--on-dark); }
.site-footer__inner { padding-block: var(--space-8) var(--space-5); }
.site-footer__grid { display: grid; grid-template-columns: 1fr; gap: var(--space-7); }
@media (min-width: 760px) { .site-footer__grid { grid-template-columns: 1.5fr 1.1fr 0.9fr; gap: var(--space-7); } }
.site-footer__col h4 { font-family: var(--font-display); font-weight: 600; font-size: 1.1rem;
  color: var(--on-dark); margin-bottom: var(--space-4); }
.site-footer__col a { color: var(--on-dark); text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: rgba(255,255,255,.4); }
.site-footer__col a:hover { text-decoration-color: var(--on-dark); }
.site-footer__col .muted, .site-footer__tag { color: var(--muted-on-dark); }
.site-footer__tag { font-size: .9rem; margin-top: var(--space-4); max-width: 34ch; }
.site-footer__demo { color: var(--muted-on-dark); font-size: .82rem; margin-top: var(--space-4); }

/* Il bold porta l'etichetta, il regular il valore: è la gerarchia che il cliente ha chiesto.
   ⚠ Niente a capo: l'etichetta non si spezza e il valore resta sulla sua riga.
   ⚠⚠ `.finfo` è un componente CONDIVISO chiaro/scuro: nasce SCURO-SU-CHIARO (il caso generale — la
   pagina Contatti) ed è il FOOTER a ridipingerlo per la sua banda navy. Il contrario — colori "on dark"
   di default — rende le etichette BIANCHE SU BIANCO fuori dal footer: invisibili, e axe non le segnala
   nemmeno (segnala solo i valori). Verificato dal vivo, non dedotto. */
.finfo { display: grid; grid-template-columns: auto 1fr; gap: var(--space-2) var(--space-3); align-items: baseline; }
.finfo dt { font-weight: 700; color: var(--deep); white-space: nowrap; }
.finfo dd { margin: 0; color: var(--ink-muted); text-wrap: pretty; }
.finfo dd a { color: var(--azure-ink); }
.site-footer .finfo dt { color: var(--on-dark); }
.site-footer .finfo dd, .site-footer .finfo dd a { color: var(--muted-on-dark); }
@media (max-width: 420px) { .finfo { grid-template-columns: 1fr; gap: 0 0; } .finfo dd { margin-bottom: var(--space-3); } }

.flinks { display: flex; flex-direction: column; gap: var(--space-3); }
.flinks a { display: inline-flex; align-items: center; gap: var(--space-3); }
.flinks a::before { content: ""; width: 6px; height: 6px; border-radius: 50%;
  border: 1.5px solid var(--azure-lt); flex: none; }

.site-footer__legal {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-4);
  margin-top: var(--space-7); padding-top: var(--space-5);
  border-top: 1px solid rgba(255,255,255,.18); color: var(--muted-on-dark); font-size: .85rem;
}
.site-footer__dgitaly { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--muted-on-dark); }
.site-footer__dgitaly img { width: 20px; height: 20px; }

/* ============================ Barra CTA mobile ============================ */
.cta-bar { display: none; }
@media (max-width: 760px) {
  .cta-bar {
    display: grid; grid-template-columns: 1fr 1fr; gap: 1px; position: fixed; left: 0; right: 0; bottom: 0;
    z-index: 40; background: var(--line); box-shadow: 0 -4px 18px rgba(28,34,51,.18);
  }
  .cta-bar a { background: var(--paper); color: var(--deep); text-align: center;
    padding: var(--space-4); font-weight: 700; font-family: var(--font-display); }
  /* ⚠ Specificità: `.cta-bar a` (0,1,1) batterebbe `.cta-bar__call` (0,1,0) — il selettore va qualificato. */
  a.cta-bar__call { background: var(--deep); color: var(--on-dark); }
  /* ⚠ Fondo --azure-ink e non --azure: bianco su --azure fa 4.49 (sotto AA). Si legge azzurro lo stesso. */
  a.cta-bar__wa { background: var(--azure-ink); color: var(--on-dark); }
  body { padding-bottom: 4rem; }
}

/* ============================ Foto apribili (lightbox) ============================
   Le foto dei lavori sono `a.zoom`: cursore d'ingrandimento + un'icona che appare all'hover. Il lightbox
   (JS bundlato, guardato) mostra l'immagine a PIENA risoluzione (1200×900): a schermo intero ci sta senza
   upscale, quindi non si sgrana. */
a.zoom { display: block; position: relative; cursor: zoom-in; }
a.zoom::after {
  content: ""; position: absolute; right: var(--space-3); bottom: var(--space-3); width: 30px; height: 30px;
  border-radius: 50%; background: rgba(27,21,80,.72);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M21 21l-4.3-4.3M11 8v6M8 11h6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; background-size: 16px;
  opacity: 0; transform: translateY(4px); transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
a.zoom:hover::after, a.zoom:focus-visible::after { opacity: 1; transform: none; }

.fp-lb {
  position: fixed; inset: 0; z-index: 100000; display: none;
  align-items: center; justify-content: center; padding: 5vh 4vw;
  background: rgba(27,21,80,.94); cursor: zoom-out;
}
.fp-lb.is-open { display: flex; animation: fp-lb-in 200ms var(--ease); }
@keyframes fp-lb-in { from { opacity: 0; } to { opacity: 1; } }
.fp-lb__img { max-width: 92vw; max-height: 88vh; object-fit: contain; border-radius: var(--radius);
  box-shadow: 0 20px 60px rgba(0,0,0,.5); cursor: default; }
.fp-lb__x { position: absolute; top: max(1rem, 3vh); right: max(1rem, 3vw); width: 44px; height: 44px;
  border: 0; border-radius: 50%; background: rgba(255,255,255,.14); color: #fff; font-size: 1.8rem; line-height: 1;
  cursor: pointer; transition: background var(--dur) var(--ease); }
.fp-lb__x:hover { background: rgba(255,255,255,.28); }
@media (prefers-reduced-motion: reduce) { .fp-lb.is-open { animation: none; } }

/* ============================ Pulsante WhatsApp con glow ============================
   Come su K Edilizia: il WhatsApp "vive" con un anello che pulsa (richiama l'attenzione senza rumore).
   ⚠ Palette del cliente = solo blu/azzurro: il bottone resta --deep (non verde WhatsApp) e l'anello pulsa
   in azzurro. Fail-safe: reduced-motion → niente pulsazione. */
.btn--wa { position: relative; }
.btn--wa svg { width: 1.15em; height: 1.15em; fill: currentColor; }
@media (prefers-reduced-motion: no-preference) {
  .btn--wa { animation: fp-wa-pulse 2.6s ease-in-out infinite; }
}
@keyframes fp-wa-pulse {
  0%, 70%, 100% { box-shadow: var(--shadow-cta), 0 0 0 0 rgba(92,116,188,.55); }
  35% { box-shadow: var(--shadow-cta), 0 0 0 12px rgba(92,116,188,0); }
}
/* Anche il tasto WhatsApp della cta-bar mobile pulsa. */
@media (max-width: 760px) and (prefers-reduced-motion: no-preference) {
  a.cta-bar__wa { position: relative; animation: fp-wa-pulse-bar 2.6s ease-in-out infinite; }
}
@keyframes fp-wa-pulse-bar {
  0%, 70%, 100% { box-shadow: inset 0 0 0 0 rgba(255,255,255,.0); }
  35% { box-shadow: inset 0 0 22px 0 rgba(255,255,255,.22); }
}

/* ============================ 404 ============================ */
.nf { text-align: center; padding-block: var(--space-9); }
/* --azure-ink anche qui: la regola "l'azzurro non è testo" resta assoluta, senza eccezioni da ricordare. */
.nf__code { font-family: var(--font-display); font-weight: 700; font-size: clamp(3.5rem, 2rem + 7vw, 7rem);
  color: var(--azure-ink); line-height: 1; }
.nf__actions { display: flex; gap: var(--space-4); justify-content: center; flex-wrap: wrap; margin-top: var(--space-6); }

/* ============================ Scroll-reveal (micro-JS IntersectionObserver) ============================
   ⚠⚠ Il reveal MUOVE, non sfuma. Due motivi, entrambi pagati altrove: un'opacità intermedia COMPONE il
   testo col fondo e un --ink-muted (5.75 sul tint) scende sotto AA a metà transizione; e un contenitore
   trasparente non fa scaricare le immagini che contiene. Fail-visible: senza JS resta tutto visibile. */
.js .reveal { opacity: 1; transform: translateY(24px); }
.js .reveal.is-visible { transform: none; transition: transform 620ms var(--ease);
  transition-delay: calc(var(--reveal-i, 0) * 90ms); }
@media (prefers-reduced-motion: reduce) { .js .reveal { transform: none; } }

/* --- Stagger: i figli di una griglia entrano a scalare, non tutti insieme. In SOLO transform (le foto
   dentro devono scaricarsi comunque) e senza toccare l'opacità del testo. --- */
.js .stagger > * { transform: translateY(20px); transition: transform 640ms var(--ease); }
.js .stagger.is-visible > * { transform: none; }
.js .stagger.is-visible > *:nth-child(1) { transition-delay: 0ms; }
.js .stagger.is-visible > *:nth-child(2) { transition-delay: 70ms; }
.js .stagger.is-visible > *:nth-child(3) { transition-delay: 140ms; }
.js .stagger.is-visible > *:nth-child(4) { transition-delay: 210ms; }
.js .stagger.is-visible > *:nth-child(5) { transition-delay: 280ms; }
.js .stagger.is-visible > *:nth-child(6) { transition-delay: 350ms; }
.js .stagger.is-visible > *:nth-child(7) { transition-delay: 420ms; }
.js .stagger.is-visible > *:nth-child(8) { transition-delay: 490ms; }
.js .stagger.is-visible > *:nth-child(n+9) { transition-delay: 560ms; }
@media (prefers-reduced-motion: reduce) { .js .stagger > * { transform: none; } }

/* --- Wipe: la foto si SCOPRE da sinistra invece di comparire. È il gesto che fa "2026" senza chiedere
   nulla al contenuto. ⚠ clip-path e non opacity: un'immagine trasparente non si scarica, e il wipe
   lascia il testo accanto sempre pieno (mai un testo che attraversa la soglia AA sfumando). --- */
.js .wipe img, .js img.wipe { clip-path: inset(0 100% 0 0); transform: scale(1.04); }
.js .wipe.is-visible img, .js img.wipe.is-visible {
  clip-path: inset(0 0 0 0); transform: none;
  transition: clip-path 900ms cubic-bezier(.22,.8,.24,1), transform 1200ms cubic-bezier(.22,.8,.24,1);
}
@media (prefers-reduced-motion: reduce) {
  .js .wipe img, .js img.wipe { clip-path: none; transform: none; }
}

/* --- Il titolo di sezione porta un filetto che si tira da sinistra: piccolo, sobrio, percepibile. --- */
.js .section-intro h2 { position: relative; }
.js .section-intro.is-visible h2::after {
  content: ""; position: absolute; left: 50%; transform: translateX(-50%); bottom: -14px;
  width: 0; height: 3px; background: var(--azure); border-radius: 3px;
  animation: fp-rule 700ms 240ms var(--ease) forwards;
}
@keyframes fp-rule { to { width: 64px; } }
@media (prefers-reduced-motion: reduce) { .js .section-intro.is-visible h2::after { width: 64px; animation: none; } }

/* Bottone hamburger di wp:navigation: WP lo mostra solo sotto il breakpoint (overlayMenu:"mobile").
   Sta sulla barra BIANCA dell'header, quindi porta --deep. */
.wp-block-navigation__responsive-container-open { background: none; border: 0; font-size: 1.6rem; line-height: 1; color: var(--deep); padding: var(--space-2); }
@media (min-width: 901px) { .wp-block-navigation__responsive-container-open { display: none; } }
@media (max-width: 900px) { .site-nav > .wp-block-navigation__container { display: none; } }
