/* components.css — componenti di sezione e chrome del verticale stone_atelier.
   Tesi: atelier lapideo (marmista di pregio). Il carattere lo danno i BLOCCHI PIENI di colore-pietra
   (basalto/bronzo), le CAPITALI INCISE e il filo di bronzo (la «vena»), NON la fotografia: il materiale di
   questi clienti è murato a ~1000px e non regge un hero a piena larghezza. Le foto stanno in TESSERE misurate,
   sempre con gutter — mai a contatto tra loro. I colori arrivano da tokens.css: qui non si dichiarano valori. */

/* ============================ Chrome: header ============================ */
/* Header fisso "a vetro". ⚠ backdrop-filter crea un containing-block per il position:fixed → l'overlay
   del menu mobile va forzato a 100vh (vedi .is-menu-open in fondo), altrimenti si confina all'header. */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: saturate(1.3) blur(10px);
  border-bottom: var(--border);
}
/* Il wrapper WP del template-part limiterebbe lo sticky: display:contents lo toglie di mezzo. */
.wp-block-template-part { display: contents; }

/* Riga header CENTRATA verticalmente: align-items:center + azzeramento dei margini di blocco WP,
   che spingerebbero nav e CTA sotto il centro. */
.site-header__row {
  display: flex; align-items: center; gap: var(--space-5);
  min-height: 74px; padding-block: var(--space-3);
}
.site-header__row > * { align-self: center; margin-block: 0; }

/* Wordmark in capitali incise (Cinzel): il nome del laboratorio, scolpito. */
.wordmark { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; font-size: 1.35rem; line-height: 1; display: flex; align-items: center; gap: var(--space-3); }
.wordmark small { display: block; font-family: var(--font-body); font-weight: 600; font-size: var(--text-sm); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-muted); margin-top: .25rem; }
.wordmark--logo .wordmark__mark { flex: none; }
.wordmark__txt { display: block; }

.site-nav { margin-left: auto; }
.site-nav a { font-family: var(--font-body); font-weight: 600; font-size: .95rem; }
.site-nav a:hover { color: var(--accent-text); }

/* Sotto-menu DESKTOP: il default WP è una card bianca squadrata, estranea al resto. Qui è un pannello
   basalto col filo di bronzo in testa — lo stesso segno delle tessere e della vena.
   ⚠ SPECIFICITÀ: WP dichiara `.wp-block-navigation .wp-block-navigation__submenu-container{background-color:#fff;border:1px solid rgba(0,0,0,.15)}` — stesso peso (0,2,0) del selettore `.site-nav …`, ma il CSS dei
   blocchi è iniettato DOPO il tema, quindi a parità vince WP e il pannello resta BIANCO. Serve un livello
   in più (`.site-header .site-nav …`). Stessa trappola del bottone header e dell'overlay del menu. */
.site-header .site-nav .wp-block-navigation__submenu-container {
  background: var(--brand);
  border: none; border-top: 2px solid var(--accent-deco);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding-block: var(--space-3);
  min-width: 15rem;
}
.site-header .site-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
  color: var(--on-dark); padding: var(--space-3) var(--space-5); width: 100%;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.site-header .site-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
  background: color-mix(in srgb, var(--on-dark) 10%, transparent); color: var(--accent-lt);
}
.site-header__tel { font-family: var(--font-body); font-weight: 600; white-space: nowrap; }
.site-header__cta { white-space: nowrap; }
/* Su mobile telefono e CTA escono dall'header (che ha già logo + hamburger) e lo fanno sbordare in
   orizzontale: li porta la .cta-bar fissa in basso, quindi qui sono ridondanti.
   ⚠ Selettore discendente NON per vezzo: `.site-header__cta` e `.btn` hanno la stessa specificità e
   `.btn{display:inline-flex}` è dichiarato DOPO — la media query non aggiunge specificità, quindi una
   regola piatta qui verrebbe sovrascritta e il bottone resterebbe visibile (sbordando). */
@media (max-width: 820px) {
  .site-header .site-header__tel, .site-header .site-header__cta { display: none; }
}

/* ============================ Bottoni ============================ */
/* Monocromo: il bottone primario è NERO-marmo (--ink) con testo bianco (14.5:1). Il secondario è ghost (bordo). */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  font-family: var(--font-body); font-weight: 600; font-size: .95rem;
  border: 1px solid transparent; border-radius: var(--radius);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn--accent { background: var(--ink); color: var(--on-dark); }
.btn--accent:hover { background: #34363a; }
.btn--ink { background: var(--brand); color: var(--on-dark); }
.btn--ink:hover { background: var(--night); }
.btn--ghost { border-color: currentColor; }
.btn--ghost:hover { background: var(--brand); color: var(--on-dark); border-color: var(--brand); }
/* Ghost su banda scura: il bordo eredita --on-dark, l'hover inverte. */
.band--dark .btn--ghost:hover { background: var(--on-dark); color: var(--brand); }

/* ============================ Hero: due campi ============================ */
/* Banda basalto piena + tessera foto VERTICALE che la scavalca. Il testo NON sta sopra la foto:
   il contrasto non dipende dal fotogramma, e la foto (piccola, ~1000px) non deve reggere l'intera banda. */
/* Profondità moderna: un gradiente radiale (alto-sx più chiaro) invece del nero piatto. Il testo resta su
   fondo scuro (AA garantito: la parte più chiara è ~13:1 col testo marmo). */
.hero { position: relative; background: radial-gradient(120% 130% at 12% 8%, #26282c 0%, var(--brand) 42%, var(--night) 100%); color: var(--on-dark); overflow: visible; isolation: isolate; }
.hero__inner { display: grid; grid-template-columns: 1fr 1.04fr; gap: clamp(2rem, 4vw, 4.5rem); align-items: center; padding-block: clamp(4rem, 2.5rem + 6vw, 8rem); }
/* ⚠ NIENTE max-width sulla colonna: la misura di lettura (~46ch) vale per la LEAD, non per il display —
   strozzata a 34ch, l'h1 andrebbe a più righe. La misura si mette sul paragrafo, mai sul contenitore del titolo. */
.hero__text { }
/* ⚠ Size PROPRIA, non --text-3xl a caso: il titolo del cliente sta in COLONNA, non su riga piena, ed è in
   CAPITALI (corre largo) → tenerlo breve e misurato. */
.hero h1 { color: var(--on-dark); font-size: clamp(2.3rem, 1.5rem + 2.9vw, 3.8rem); margin-block: var(--space-4) var(--space-5); }
.hero .lead { color: var(--on-dark); opacity: .92; max-width: 46ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-6); }
/* La tessera scavalca la banda in basso: margine negativo + z-index. Ratio verticale = il formato che il
   materiale tipico ha davvero (lavori fotografati in piedi: colonne, meridiane, pareti). */
/* Tessera GRANDE che scavalca la banda: ombra profonda (depth moderna) + sbordo marcato. */
.hero__tile { position: relative; z-index: 1; aspect-ratio: 4 / 5; margin-bottom: calc(var(--section-y) * -0.58); border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: 0 44px 88px rgba(0,0,0,.5), 0 16px 36px rgba(0,0,0,.38); }
.hero__tile img { width: 100%; height: 100%; object-fit: cover; }
/* La vena di grigio che rifinisce la tessera (decoro, non testo). */
.hero__tile::after { content: ""; position: absolute; inset: auto 0 0 0; height: 3px; background: var(--accent-deco); z-index: 2; }
/* Slideshow della tessera: 3 slide-marmo in crossfade + Ken Burns leggero. reduced-motion → 1ª foto fissa.
   ⚠ img loading="eager" (nell'HTML): a opacity:0 le lazy NON si scaricano, le eager sì (lezione le-parisien). */
.hero__slide { position: absolute; inset: 0; opacity: 0; }
.hero__slide:first-child { opacity: 1; }
.hero__slide img { width: 100%; height: 100%; object-fit: cover; display: block; }
.js .hero__slide { opacity: 0; animation: fp-hero-slide 21s ease-in-out infinite; }
.js .hero__slide:nth-child(1) { animation-delay: 0s; }
.js .hero__slide:nth-child(2) { animation-delay: 7s; }
.js .hero__slide:nth-child(3) { animation-delay: 14s; }
@keyframes fp-hero-slide {
  0% { opacity: 0; transform: scale(1.001); }
  4% { opacity: 1; }
  29% { opacity: 1; }
  36% { opacity: 0; transform: scale(1.08); }
  100% { opacity: 0; transform: scale(1.08); }
}
@media (prefers-reduced-motion: reduce) {
  .js .hero__slide { animation: none; opacity: 0; transform: none; }
  .js .hero__slide:first-child { opacity: 1; }
}
@media (max-width: 860px) {
  .hero__inner { grid-template-columns: 1fr; }
  .hero__tile { display: none; }   /* su mobile la banda piena basta: la foto piccola non aggiunge nulla */
}

/* ============================ Manifesto (featured) ============================ */
.manifesto__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gutter) clamp(2rem, 6vw, 5rem); align-items: start; }
.manifesto__body { color: var(--ink); }
/* Attacco editoriale: il primo capoverso è la voce dell'artigiano. Nessun campo nuovo nell'IR: è il body
   che c'è già, trattato tipograficamente. ⚠ NON in Cinzel: le capitali non reggono un capoverso lungo. È
   Source Sans, più grande e in bronzo, con la vena a sinistra. */
.manifesto__body > p:first-child { font-size: var(--text-md); font-weight: 600; color: var(--accent-text); border-left: 2px solid var(--accent-deco); padding-left: var(--space-5); margin-bottom: var(--space-5); }
@media (max-width: 860px) { .manifesto__grid { grid-template-columns: 1fr; } }

/* ============================ Servizi / lavorazioni (services) ============================ */
/* Mosaico di tessere CON GUTTER (mai a contatto: è il difetto tipico delle gallerie di questi clienti).
   Due tessere PIENE di colore danno il carattere senza chiedere nulla alla fotografia: stando in posizione
   alterna (2ª e 4ª) scendono in diagonale, ed è LÌ che sta il ritmo — non in un disallineamento delle celle.
   ⚠ Le celle si allungano tutte alla riga (stretch, il default della griglia): una tessera piena non ha la
   foto che le occupa la parte alta, quindi da sola verrebbe alta quasi la metà di una card con foto. Un
   offset sfalsato SOPRA altezze diverse non si legge come scala, si legge come disallineamento: perché una
   discesa sia leggibile le tessere devono prima essere alte uguali. */
.works { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--tile-gap); }
.work { position: relative; display: flex; flex-direction: column; background: var(--paper); border: var(--border); border-radius: var(--radius); overflow: hidden; transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.work:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.work__media { aspect-ratio: 4 / 3; overflow: hidden; background: var(--surface); }
.work__media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur) var(--ease); }
.work:hover .work__media img { transform: scale(1.03); }
/* Il link copre il corpo della card: la tessera intera è cliccabile e porta DIRITTO alla pagina del
   servizio (mai a un hub intermedio). Gli URL sono di pagine solo-progetto → hardcodati nel pattern. */
.work__link { display: flex; flex-direction: column; flex: 1; color: inherit; }
.work__link:hover h3 { color: var(--accent-text); }
.work--filled-ink .work__link:hover h3, .work--filled-accent .work__link:hover h3 { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.work__body { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); flex: 1; }
.work h3 { color: var(--ink); }
.work__text { color: var(--ink-muted); font-size: .95rem; }
/* Tessere piene monocrome: 2ª nero-marmo, 4ª grafite — due toni scuri, testo bianco. Ritmo tonale, non colore.
   Non avendo la foto che occupa la parte alta, il loro testo va CENTRATO nella cella. */
.work--filled-ink, .work--filled-accent { min-height: 15rem; }
.work--filled-ink .work__body, .work--filled-accent .work__body { justify-content: center; }
.work--filled-ink { background: var(--brand); border-color: var(--brand); }
.work--filled-ink h3, .work--filled-ink .work__text { color: var(--on-dark); }
.work--filled-ink .work__text { opacity: .9; }
.work--filled-accent { background: #34363a; border-color: #34363a; }
.work--filled-accent h3, .work--filled-accent .work__text { color: var(--on-dark); }
.work--filled-accent .work__text { opacity: .9; }
/* L'incisione: un filo SOLIDO inciso lungo il bordo interno, come lo scalpello che rifila la lastra. È il
   segno del mestiere — sta SOLO sulle tessere piene (dove non c'è la foto), altrimenti diventa decorazione. */
.work--filled-ink::before, .work--filled-accent::before {
  content: ""; position: absolute; inset: 10px; border-radius: var(--radius); pointer-events: none;
  border: 1px solid color-mix(in srgb, var(--on-dark) 32%, transparent);
}
@media (max-width: 980px) { .works { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .works { grid-template-columns: 1fr; } }

/* ============================ Movimento ============================ */
/* Il movimento è quello del mestiere: la lastra si posa, l'incisione si rifila a lavoro finito, le tessere
   entrano come pietre messe una dopo l'altra. Tutto si aggancia a .reveal/.is-visible (reveal.js), quindi
   resta fail-visible senza JS; gli stati di riposo sono gli stessi che il CSS dichiara sopra.
   ⚠ Le tessere si muovono in SOLO transform, MAI in opacity: un elemento trasparente non fa scaricare le
   immagini che contiene, e sono quelle dei lavori. */
.js .work.reveal { opacity: 1; transform: translateY(22px);
  transition: transform .65s var(--ease), box-shadow var(--dur) var(--ease); }
.js .work.reveal.is-visible { transform: none; transition-delay: calc(var(--reveal-i, 0) * 80ms); }
.js .work.reveal.is-visible:hover { transform: translateY(-3px); transition-delay: 0s; }
/* L'incisione arriva DOPO la lastra e si stringe al bordo: è il taglio dato a lavoro finito. */
.js .work.reveal::before { opacity: 0; inset: 3px;
  transition: opacity .5s var(--ease), inset .7s var(--ease); }
.js .work.reveal.is-visible::before { opacity: 1; inset: 10px;
  transition-delay: calc(var(--reveal-i, 0) * 80ms + 280ms); }

/* La posa in opera: entrano i passaggi e la vena li rincorre da sinistra a destra. Il contenitore non
   sfuma, altrimenti il passaggio sfumerebbe due volte (una col gruppo, una per sé).
   ⚠ I passaggi si muovono in SOLO transform: il loro testo è --ink-muted, che sul tint sta appena sopra la
   soglia AA — un'opacità intermedia lo comporrebbe col fondo e lo porterebbe sotto per tutta la dissolvenza.
   Un testo non deve mai attraversare la soglia. */
.js .pattern-steps.reveal { opacity: 1; transform: none; }
.js .pattern-steps.reveal .pstep { opacity: 1; transform: translateY(14px);
  transition: transform .5s var(--ease); }
.js .pattern-steps.reveal.is-visible .pstep { transform: none; }
.js .pattern-steps.reveal .pstep::before { transform: scaleX(0); transform-origin: left;
  transition: transform .55s var(--ease); }
.js .pattern-steps.reveal.is-visible .pstep::before { transform: scaleX(1); }
.js .pattern-steps.reveal.is-visible .pstep:nth-child(1) { transition-delay: 0ms; }
.js .pattern-steps.reveal.is-visible .pstep:nth-child(2) { transition-delay: 110ms; }
.js .pattern-steps.reveal.is-visible .pstep:nth-child(3) { transition-delay: 220ms; }
.js .pattern-steps.reveal.is-visible .pstep:nth-child(4) { transition-delay: 330ms; }
.js .pattern-steps.reveal.is-visible .pstep:nth-child(1)::before { transition-delay: 120ms; }
.js .pattern-steps.reveal.is-visible .pstep:nth-child(2)::before { transition-delay: 230ms; }
.js .pattern-steps.reveal.is-visible .pstep:nth-child(3)::before { transition-delay: 340ms; }
.js .pattern-steps.reveal.is-visible .pstep:nth-child(4)::before { transition-delay: 450ms; }

/* L'occhiello: il filo si tira prima della parola. */
.js .reveal .eyebrow::before { width: 0; transition: width .5s var(--ease) .15s; }
.js .reveal.is-visible .eyebrow::before { width: 1.6em; }

/* La tessera dell'hero si posa. Sta sopra la piega: solo transform, la foto deve scaricarsi subito. */
@keyframes fp-tile-settle { from { transform: translateY(26px); } to { transform: none; } }
.js .hero__tile { animation: fp-tile-settle .9s var(--ease) .1s both; }

/* Il filo sotto la voce di menu cresce da sinistra, come una vena che corre. */
.site-header .site-nav .wp-block-navigation-item__content { position: relative; }
.site-header .site-nav .wp-block-navigation-item__content::after { content: ""; position: absolute;
  left: 0; right: 100%; bottom: -3px; height: 1px; background: var(--accent-deco);
  transition: right .32s var(--ease); }
.site-header .site-nav .wp-block-navigation-item__content:hover::after { right: 0; }

/* Chi ha disattivato le animazioni vede gli stati finali, subito e senza transizioni. */
@media (prefers-reduced-motion: reduce) {
  .js .work.reveal, .js .pattern-steps.reveal .pstep, .js .hero__tile { transform: none; opacity: 1; animation: none; }
  .js .work.reveal::before { opacity: 1; inset: 10px; }
  .js .pattern-steps.reveal .pstep::before, .tcard::before { transform: none; }
  .js .reveal .eyebrow::before { width: 1.6em; }
  .js .work.reveal, .js .work.reveal::before, .js .pattern-steps.reveal .pstep,
  .js .pattern-steps.reveal .pstep::before, .tcard::before, .btn,
  .site-header .site-nav .wp-block-navigation-item__content::after { transition: none; }
}

/* ============================ Intro di pagina categoria ============================ */
/* Il testo introduttivo da solo in colonna stretta lascia mezza pagina vuota (difetto tipico: "spoglia").
   Regola: la foto sta ACCANTO alla descrizione, non relegata in una banda a fondo pagina. */
.cat-intro { display: grid; grid-template-columns: .92fr 1.08fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.cat-intro__text > p + p { margin-top: var(--space-4); }
.cat-intro__media { border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-md); position: relative; }
.cat-intro__media img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 5 / 4; transition: transform .7s var(--ease); }
.cat-intro__media:hover img { transform: scale(1.04); }
/* vena di bronzo: lo stesso segno della tessera hero */
.cat-intro__media::after { content: ""; position: absolute; inset: auto 0 0 0; height: 3px; background: var(--accent-deco); }
@media (max-width: 860px) { .cat-intro { grid-template-columns: 1fr; } }

/* ============================ Metodo: la posa in opera ============================ */
/* Numerali incisi grandi in colonna, legati da una vena di bronzo orizzontale — dal progetto alla posa. */
.pattern-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gutter); }
.pstep { position: relative; padding-top: var(--space-6); }
.pstep__n { font-family: var(--font-display); font-weight: 600; font-size: 3rem; line-height: 1; color: var(--accent-text); display: block; }
.pstep h3 { margin-block: var(--space-3) var(--space-2); color: var(--ink); }
.pstep__text { color: var(--ink-muted); font-size: .95rem; }
/* Vena orizzontale che lega gli step (si spegne a una colonna). */
.pstep::before { content: ""; position: absolute; top: var(--space-6); left: 0; right: calc(var(--gutter) * -1); height: 1px; background: var(--accent-deco); opacity: .5; }
.pstep:last-child::before { right: 0; }
@media (max-width: 980px) { .pattern-steps { grid-template-columns: repeat(2, 1fr); } .pstep::before { display: none; } }
@media (max-width: 560px) { .pattern-steps { grid-template-columns: 1fr; } }

/* ============================ Fiducia (trust) ============================ */
.trust__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gutter); align-items: start; }
.trust__items { display: grid; gap: var(--space-5); }
.tcard { position: relative; overflow: hidden; padding: var(--space-5); background: var(--paper);
  border: var(--border); border-radius: var(--radius);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
/* La vena: il filo di bronzo corre lungo il lato della scheda, come sul bordo del manifesto — senza
   chiedere nulla alla fotografia, che qui non c'è. Scende quando la sezione entra. */
.tcard::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--accent-deco); transform: scaleY(0); transform-origin: top;
  transition: transform .6s var(--ease); }
.js .trust__grid.reveal.is-visible .tcard::before { transform: scaleY(1); }
.js .trust__grid.reveal.is-visible .tcard:nth-child(1)::before { transition-delay: 180ms; }
.js .trust__grid.reveal.is-visible .tcard:nth-child(2)::before { transition-delay: 320ms; }
.tcard:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.tcard h3 { color: var(--ink); margin-bottom: var(--space-2); }
.tcard__text { color: var(--ink-muted); font-size: .95rem; }
@media (max-width: 860px) { .trust__grid { grid-template-columns: 1fr; } }

/* ============================ Banda contatti ============================ */
.band--dark { background: var(--brand); color: var(--on-dark); }
.band--dark h2 { color: var(--on-dark); }
.band--dark .lead { color: var(--on-dark); opacity: .92; }
.contact-band__inner { display: flex; flex-wrap: wrap; gap: var(--space-6); align-items: center; justify-content: space-between; }
.contact-band__text { max-width: 46ch; }

/* ============================ Testata di pagina ============================ */
/* ⚠ La page-head NON riusa la size dell'hero (--text-3xl): è una testata, non un hero. Un gradino sotto
   + padding contenuto, altrimenti "occupa mezza schermata". È CONDIVISA da tutte le pagine interne. */
.page-head { background: var(--surface); padding-block: clamp(2.5rem, 1.5rem + 3vw, 4rem); border-bottom: var(--border); }
.page-head h1 { font-size: var(--text-2xl); }
.page-head p { color: var(--ink-muted); }

/* Intro di sezione: colonna di misura leggibile, non riga piena. */
.section-intro { max-width: 48rem; margin-bottom: var(--space-7); }
/* ⚠ Il titolo di sezione sta in colonna e in CAPITALI → resta a --text-xl (mai --text-2xl):
   una size da riga piena qui manda i titoli lunghi del cliente a due righe. */

/* ============================ Pagina Contatti (2 colonne) ============================ */
/* Form a SINISTRA + recapiti in scheda CHIARA a destra. ⚠ La scheda NON riusa gli stili da fondo scuro:
   sul fondo chiaro della pagina i colori si invertirebbero. */
.contact-cols { display: grid; grid-template-columns: 1.1fr .9fr; gap: clamp(2rem, 5vw, 4rem); align-items: start; }
.contact-cols h2 { margin-bottom: var(--space-5); }
.contact-form { display: grid; gap: var(--space-4); }
/* Coppie di campi affiancate (Nome | Telefono). */
.contact-form .row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
/* Il campo è una colonna: label SOPRA il controllo, mai di fianco (il default inline è illeggibile). */
.field { display: grid; gap: var(--space-2); }
.field label { font-family: var(--font-body); font-size: var(--text-sm); font-weight: 600; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-muted); }
.field input, .field textarea {
  font: inherit; color: var(--ink); width: 100%;
  padding: var(--space-3) var(--space-4);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
}
.field textarea { resize: vertical; min-height: 8rem; }
.field input:focus-visible, .field textarea:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; border-color: var(--accent-deco); }
/* ⚠ .consent è un flex: il testo (link incluso) va TUTTO in uno <span>, altrimenti l'<a> diventa
   un flex-item a sé e la riga si spezza. */
.consent { display: flex; align-items: flex-start; gap: var(--space-3); font-size: .95rem; color: var(--ink-muted); }
.consent input { margin-top: .25rem; flex: none; }
.consent a { color: var(--accent-text); text-decoration: underline; }
.contact-form button { justify-self: start; }
.form-note { margin-top: var(--space-1); }
/* Aside dei recapiti: scheda chiara, non la banda scura dell'home. */
.contact-info { background: var(--surface); border: var(--border); border-radius: var(--radius); padding: var(--space-6); }
.contact-info dl { display: grid; gap: var(--space-4); margin: 0; }
.contact-info dt { font-family: var(--font-body); font-size: var(--text-sm); font-weight: 600; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--accent-text); }
.contact-info dd { margin: var(--space-1) 0 0; line-height: 1.6; }
.contact-info a { text-decoration: underline; text-underline-offset: 2px; }
.contact-info .btn { margin-top: var(--space-5); text-decoration: none; }
@media (max-width: 860px) {
  .contact-cols { grid-template-columns: 1fr; }
  .contact-form .row { grid-template-columns: 1fr; }
}

/* ============================ Footer ============================ */
.site-footer { background: var(--night); color: var(--on-dark); padding-block: var(--space-8) var(--space-6); }
.site-footer a:hover { color: var(--accent-lt); }
.site-footer__grid { display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: var(--gutter); }
.site-footer h4 { font-family: var(--font-body); font-size: var(--text-sm); font-weight: 600; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--accent-lt); margin-bottom: var(--space-4); }
/* Il wordmark è condiviso con l'header (fondo chiaro), dove il suo <small> è --ink-muted: sul fondo scuro
   del footer quel bruno scende sotto soglia → qui va il testo secondario da fondo scuro (contratto palette). */
.site-footer .wordmark small { color: var(--muted-on-dark); }
.site-footer p { color: var(--on-dark); opacity: .92; font-size: .95rem; }
.site-footer__tag { margin-top: var(--space-4); max-width: 34ch; }
.site-footer__demo { margin-top: var(--space-4); color: var(--muted-on-dark); font-size: var(--text-sm); }
/* Legal a 3 celle: nome + P.IVA a sinistra, «Powered by Dgitaly» VERAMENTE al centro (grid 1fr auto 1fr —
   space-between NON centra il mediano se le celle esterne hanno larghezze diverse), Privacy a destra. */
.site-footer__legal { margin-top: var(--space-7); padding-top: var(--space-5); border-top: 1px solid color-mix(in srgb, var(--on-dark) 18%, transparent); display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--space-4); color: var(--muted-on-dark); font-size: var(--text-sm); }
.legal-l { grid-column: 1; justify-self: start; }
.legal-c { grid-column: 2; justify-self: center; }
.legal-r { grid-column: 3; justify-self: end; }
@media (max-width: 680px) { .site-footer__legal { grid-template-columns: 1fr; justify-items: center; text-align: center; } .legal-l, .legal-c, .legal-r { grid-column: 1; justify-self: center; } }
/* Powered by Dgitaly (fence fp:real: solo progetti reali). */
.site-footer__dgitaly { display: inline-flex; align-items: center; gap: var(--space-2); }
.site-footer__dgitaly img { display: inline-block; }
@media (max-width: 860px) { .site-footer__grid { grid-template-columns: 1fr; } }

/* ============================ CTA bar mobile ============================ */
/* Barra fissa solo su mobile: il preventivo telefonico è l'obiettivo di conversione del verticale.
   ⚠ Il menu overlay ha padding-bottom generoso per non finire sotto questa barra. */
.cta-bar { display: none; }
@media (max-width: 820px) {
  .cta-bar {
    position: fixed; inset: auto 0 0 0; z-index: 40;
    display: grid; grid-template-columns: 1fr 1fr;
    background: var(--night); border-top: 1px solid color-mix(in srgb, var(--on-dark) 18%, transparent);
  }
  .cta-bar a { padding: var(--space-4); text-align: center; color: var(--on-dark); font-weight: 600; font-size: .95rem; }
  /* ⚠ SPECIFICITÀ: `.cta-bar a` pesa (0,1,1) e batte `.cta-bar__call` (0,1,0) QUALUNQUE sia l'ordine →
     serve un selettore di pari peso: `a.cta-bar__call`. Monocromo: «Chiama» = tessera marmo chiara su nero. */
  .cta-bar a.cta-bar__call { background: var(--on-dark); color: var(--ink); }   /* marmo su nero, testo ink (14.5:1) */
  body { padding-bottom: 56px; }
}

/* ============================ Menu mobile (overlay wp:navigation) ============================ */
/* ⚠ L'header ha backdrop-filter → containing-block per il fixed: senza questo, l'overlay si confina
   all'altezza dell'header (~74px) e il menu risulta "rotto". */
/* ⚠ SPECIFICITÀ: WP dichiara `.wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay){background-color:#fff}` (0,4,0). Una regola
   piatta sul container (0,2,0) NON vince e l'overlay resta BIANCO. Va ripreso lo stesso schema. */
.site-nav:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay),
.wp-block-navigation__responsive-container.is-menu-open {
  height: 100vh; max-height: 100vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: var(--brand); color: var(--on-dark);
}
/* Le voci vanno a SINISTRA: `justifyContent:right` (desktop) in colonna diventa align-items:flex-end.
   ⚠ Va messo su TUTTA la catena, non solo sul `__container`: è il PADRE
   `__responsive-container-content` (largo quanto il viewport) che, restando flex-end, spinge a destra
   il blocco delle voci — correggere il solo figlio non sposta nulla. */
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content,
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container,
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item,
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container {
  align-items: flex-start; justify-content: flex-start;
}
/* Aria a sinistra: le voci non devono toccare il bordo dello schermo. */
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content { padding-left: var(--gutter); }
/* La X di chiusura: il default è sottile e incollata all'angolo. Più marcata (stroke sul path, che WP
   disegna in solo fill) e con aria sopra e di lato — l'area di tocco cresce con lei. */
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close {
  top: var(--space-4); right: var(--space-4);
  padding: var(--space-3); color: var(--on-dark);
  border-radius: var(--radius);
}
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close:hover { background: color-mix(in srgb, var(--on-dark) 12%, transparent); }
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close svg {
  width: 28px; height: 28px;
  stroke: currentColor; stroke-width: 1.4;   /* l'icona WP è solo `fill`: lo stroke la ingrossa */
}
/* ⚠ La nav desktop ha `justifyContent:right`: nell'overlay (flex COLUMN) quel valore si traduce in
   `align-items:flex-end` → le voci si incolonnano a DESTRA e restano larghe quanto il testo, col sotto-menu
   che sborda. Vanno rimessi allineamento e larghezza sul container E sull'item: agire solo sul `__content`
   non basta. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container { align-items: flex-start; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item { width: 100%; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content { width: 100%; text-align: left; }
/* Il sotto-menu «Materiali» va inline e indentato, non come card-dropdown desktop. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item { width: 100%; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-icon { margin-left: auto; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content { padding-bottom: 96px; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container {
  position: static !important; border: none !important; box-shadow: none !important; background: none !important; padding-left: var(--space-5);
}

/* ============================ Scroll-reveal (micro-JS IntersectionObserver) ============================ */
/* Fail-visible: senza JS (.js assente) il contenuto è già visibile. reduced-motion rivela tutto.
   ⚠ MAI mettere `.reveal` su un contenitore di IMMAGINI (es. la griglia `.works`): con `opacity:0` il browser
   NON scarica le img che contiene — né lazy né eager — finché l'osservatore non lo rivela. Il reveal sta sui
   blocchi di TESTO (intro, step, card). */
.js .reveal { opacity: 0; transform: translateY(24px); }
/* Rete di sicurezza: una griglia foto non deve mai restare invisibile, nemmeno se qualcuno le rimette .reveal. */
.js .works, .js .works.reveal { opacity: 1; transform: none; }
.js .reveal.is-visible { opacity: 1; transform: none; transition: opacity 620ms var(--ease), transform 620ms var(--ease); transition-delay: calc(var(--reveal-i, 0) * 90ms); }
@media (prefers-reduced-motion: reduce) { .js .reveal { opacity: 1; transform: none; } }

/* Reveal DIREZIONALE (le foto entrano da sinistra/destra). ⚠ SOLO transform, MAI opacity: un contenitore
   trasparente non fa scaricare le immagini che contiene. Sovrascrive l'opacity:0 del reveal base (più specifico). */
.js .reveal.from-left { opacity: 1; transform: translateX(-46px); }
.js .reveal.from-right { opacity: 1; transform: translateX(46px); }
.js .reveal.from-left.is-visible, .js .reveal.from-right.is-visible { transform: none; transition: transform 820ms var(--ease); }
@media (prefers-reduced-motion: reduce) { .js .reveal.from-left, .js .reveal.from-right { transform: none; } }

/* ============================ Lightbox (gallery) ============================ */
/* Le foto marcate a.zoom si aprono a piena risoluzione (reveal.js lightbox(): overlay .fp-lb). */
a.zoom { display: block; cursor: zoom-in; position: relative; }
a.zoom::after {
  content: ""; position: absolute; right: var(--space-3); bottom: var(--space-3); width: 2.1rem; height: 2.1rem;
  background: rgba(27,28,30,.82) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F4F4F2' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M16.5 16.5 L21 21'/%3E%3C/svg%3E") center / 1.05rem no-repeat;
  border-radius: 50%; opacity: 0; transform: scale(.85);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease); pointer-events: none;
}
.work:hover a.zoom::after, a.zoom:hover::after, a.zoom:focus-visible::after { opacity: 1; transform: none; }
.fp-lb { position: fixed; inset: 0; z-index: 200; display: none; align-items: center; justify-content: center;
  background: rgba(21,22,26,.93); padding: var(--space-6); }
.fp-lb.is-open { display: flex; }
.fp-lb__img { max-width: min(92vw, 1400px); max-height: 88vh; width: auto; height: auto; border-radius: var(--radius); box-shadow: var(--shadow-md); }
.fp-lb__x { position: absolute; top: var(--space-5); right: var(--space-5); width: 2.6rem; height: 2.6rem;
  background: none; border: 0; color: var(--on-dark); font-size: 2rem; line-height: 1; cursor: pointer; border-radius: var(--radius); }
.fp-lb__x:hover { background: color-mix(in srgb, var(--on-dark) 14%, transparent); }

/* ============================ /goal design: banda marmo full-bleed ============================ */
/* Immagine di marmo a piena larghezza (edge-to-edge): imagery grande = registro 2026. NIENTE testo sopra la
   foto; l'eventuale etichetta sta su un chip SOLIDO (a11y). */
.marble-band-sec { padding: 0; }
.marble-band { position: relative; width: 100vw; margin-left: calc(50% - 50vw); height: clamp(260px, 32vw, 520px); overflow: hidden; background: var(--brand); }
.marble-band img { width: 100%; height: 100%; object-fit: cover; display: block; }
.marble-band__tag { position: absolute; left: clamp(1rem, 4vw, 3rem); bottom: clamp(1rem, 4vw, 3rem); background: var(--brand); color: var(--on-dark);
  padding: var(--space-3) var(--space-5); font-family: var(--font-display); font-weight: 600; text-transform: uppercase; letter-spacing: var(--tracking-display); font-size: var(--text-sm); }
/* Ken-Burns lento: solo transform (nessuna opacity → l'immagine si scarica sempre), reduced-motion la ferma. */
.js .marble-band img { animation: fp-kenburns 22s var(--ease) infinite alternate; }
@keyframes fp-kenburns { from { transform: scale(1.005); } to { transform: scale(1.07); } }
@media (prefers-reduced-motion: reduce) { .js .marble-band img { animation: none; } }

/* ============================ /goal design: schede per ambiente (Materiali) ============================ */
/* Ogni ambiente (bagno/cucina/salotto/pavimenti) è una scheda foto + testo VERBATIM. Testo su superficie SOLIDA. */
.mat-cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--tile-gap); }
.mat-card { display: flex; flex-direction: column; background: var(--surface); border: var(--border); border-radius: var(--radius); overflow: hidden;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.mat-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.mat-card__media { aspect-ratio: 16 / 10; overflow: hidden; background: var(--brand); }
.mat-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
.mat-card:hover .mat-card__media img { transform: scale(1.05); }
.mat-card__body { padding: var(--space-6); }
.mat-card h3 { color: var(--ink); }
.mat-card__text { color: var(--ink-muted); font-size: .97rem; margin-top: var(--space-2); line-height: 1.55; }
@media (max-width: 720px) { .mat-cards { grid-template-columns: 1fr; } }

/* ============================ /goal design: gallery a tessere GRANDI + banner Contatti ============================ */
.works--gallery { grid-template-columns: repeat(2, 1fr); gap: var(--tile-gap); }
.works--gallery .work__media { aspect-ratio: 3 / 2; }
/* la 1ª tessera è protagonista (span 2 colonne) */
.works--gallery .work:first-child { grid-column: 1 / -1; }
.works--gallery .work:first-child .work__media { aspect-ratio: 21 / 8; }
@media (max-width: 720px) { .works--gallery { grid-template-columns: 1fr; } .works--gallery .work:first-child .work__media { aspect-ratio: 3 / 2; } }

/* Banner immagine in cima a Contatti (nessun testo sopra: pura imagery). */
.contact-hero { width: 100vw; margin-left: calc(50% - 50vw); height: clamp(220px, 26vw, 380px); overflow: hidden; background: var(--brand); }
.contact-hero img { width: 100%; height: 100%; object-fit: cover; }

/* ============================ /goal design: marquee dei marmi (nomi VERBATIM dai Materiali) ============================ */
.marquee-sec { padding: 0; }
.marquee { overflow: hidden; border-block: 1px solid var(--line); background: var(--surface); padding-block: var(--space-5); }
.marquee__track { display: inline-flex; align-items: center; white-space: nowrap; will-change: transform;
  font-family: var(--font-display); font-weight: 600; text-transform: uppercase; letter-spacing: var(--tracking-display);
  font-size: clamp(1.3rem, .9rem + 2vw, 2.3rem); color: var(--ink); }
.marquee__item { display: inline-flex; align-items: center; padding-inline: clamp(1rem, 3vw, 2.4rem); }
.marquee__item::after { content: "◆"; color: var(--accent-deco); font-size: .5em; margin-left: clamp(1rem, 3vw, 2.4rem); }
.js .marquee__track { animation: fp-marquee 48s linear infinite; }
.marquee:hover .marquee__track { animation-play-state: paused; }
@keyframes fp-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .js .marquee__track { animation: none; } }

/* Micro-interazione: sottolineatura animata dei link testuali (moderno) + hover foto più deciso. */
.prose a, .contact-info a { background-image: linear-gradient(var(--accent-text), var(--accent-text)); background-size: 0% 1px;
  background-position: 0 100%; background-repeat: no-repeat; transition: background-size .32s var(--ease); text-decoration: none; }
.prose a:hover, .contact-info a:hover { background-size: 100% 1px; }

/* ============================ /goal design: striscia "fatti" (dati VERBATIM) ============================ */
.facts-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1rem, 3vw, 2.4rem); border-block: 1px solid var(--line); padding-block: var(--space-7); }
.fact__n { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: 0;
  font-size: clamp(1.25rem, .95rem + 1vw, 1.75rem); color: var(--ink); line-height: 1.08; hyphens: none; }
.fact__l { color: var(--ink-muted); font-size: var(--text-sm); text-transform: uppercase; letter-spacing: var(--tracking-label); margin-top: var(--space-3); }
.fact { position: relative; padding-left: var(--space-4); min-width: 0; }
.fact::before { content: ""; position: absolute; left: 0; top: .1em; width: 2px; height: 1.1em; background: var(--accent-deco); }
@media (max-width: 900px) { .facts-strip { grid-template-columns: repeat(2, 1fr); gap: var(--space-6); } }
@media (max-width: 560px) { .facts-strip { grid-template-columns: 1fr; gap: var(--space-5); } }

/* Variante mosaico a tessere GRANDI (pagina Servizi): 2 colonne, foto più ampie = più imagery/impatto. */
.works--big { grid-template-columns: repeat(2, 1fr); }
.works--big .work__media { aspect-ratio: 16 / 10; }
@media (max-width: 720px) { .works--big { grid-template-columns: 1fr; } }
