/* Lenis gestisce lo scroll via JS: se il browser applica ANCHE il proprio
   scroll-behavior:smooth (nativo, spesso aggiunto da tema/plugin/cache per
   i link con ancora), i due smoothing si accavallano e lo scroll diventa
   pesante e "a scatto". Va sempre disattivato quando c'è Lenis. */
html{ scroll-behavior: auto !important; }

/* #header è fixed top:0 come la WP admin bar (anch'essa fixed, z-index molto
   alto): da loggati le due si sovrappongono e la parte alta dell'header
   (logo, bottone Menu) diventa difficile da usare in hover/click. WordPress
   aggiunge da solo la classe "admin-bar" al <body> quando la barra è visibile
   (via body_class(), già usata in header.php): la sfruttiamo per spostare
   l'header sotto, con la stessa altezza della admin bar nei due breakpoint
   in cui WP la disegna diversa. */
body.admin-bar #header{ top:32px; }
@media (max-width:782px){
  body.admin-bar #header{ top:46px; }
}

/* Le classi Tailwind (font-display, text-2xl, leading-[1.35], text-panna...)
   messe in Avanzate → CSS Classes su un widget Heading/Text Editor finiscono
   sul div wrapper di Elementor, non sull'<h2>/<p> reale annidato dentro. Il
   Kit di Elementor scrive di suo un default (colore, famiglia, peso, e per
   ogni "Size" del widget anche la dimensione) direttamente sul tag interno,
   con una classe di scope più specifica di quella che possiamo scrivere qui
   a mano: "stessa specificità, carica dopo" non basta a batterlo sempre.
   Soluzione: forziamo la tipografia (non il colore, vedi sotto) a tornare
   a ereditarsi dal wrapper, con !important. Da qui in poi: crei il widget,
   incolli le classi sul wrapper (Avanzate → CSS Classes), il tag interno
   eredita font, peso, dimensione, altezza riga, spaziatura lettere —
   esattamente come nella demo statica. Le uniche impostazioni da NON
   toccare più nel pannello Style di Elementor sono queste (Typography):
   bastano le classi. (Se un domani serve davvero un valore diverso solo
   lì, il pannello Style di quel widget può comunque riprendere il
   controllo scrivendo un !important più specifico — non è un vicolo
   cieco, solo non serve qui.)

   COLORE ESCLUSO DI PROPOSITO: il testo va scelto dal pannello Style di
   ogni widget in Elementor (Text Color), non più forzato a ereditarsi dal
   fondo della sezione. Attenzione: senza un colore impostato lì, il
   widget mostra il default (scuro) del Kit di Elementor, non più il
   crema/chiaro del design system — se manca sembrerà "nero su nero" su
   una sezione scura. */
.elementor-widget-heading .elementor-heading-title,
.elementor-widget-text-editor .elementor-text-editor,
.elementor-widget-text-editor .elementor-text-editor p {
  font-family: inherit !important;
  font-weight: inherit !important;
  font-style: inherit !important;
  font-size: inherit !important;
  line-height: inherit !important;
  letter-spacing: inherit !important;
  text-transform: inherit !important;
  text-align: inherit !important;
}

/* max-width, e qualsiasi altra proprietà Elementor forzi in futuro sui
   widget dentro un Container, non serve più risolverli qui uno a uno: vedi
   "important: true" nella config di Tailwind in functions.php — ogni utility
   Tailwind vince già di suo. */

/* =========================================================
   WP-THEME.CSS
   Non tocca il design system di site.css: aggiunge solo le regole
   necessarie perché l'output di WordPress (wp_nav_menu, CPT brand,
   admin meta box) rispetti lo stesso look "messa a fuoco".
   ========================================================= */

/* ---- Menu overlay: WordPress genera <ul><li><a>, qui gli diamo
   la stessa tipografia che nel sito statico era inline su ogni <a> ---- */
#menu #menu-list{ list-style:none; margin:0; padding:0; }
#menu #menu-list li{ margin:.4rem 0; }
#menu #menu-list a{
  font-family:"Cormorant Garamond", Georgia, serif;
  font-weight:300; font-size:1.6rem; line-height:1;
  color:var(--panna); text-decoration:none; display:inline-block;
}
/* Voci ridotte rispetto all'originale (era 1.875rem/3.75rem, sentito "troppo
   grande" a prescindere dallo schermo): ora il tetto su desktop è 2.75rem
   invece di 3.75rem. Resta il clamp() per scalare senza scatti fra 768 e
   1920px — vedi il fix precedente per il perché serve. */
@media (min-width:768px){
  #menu #menu-list li{ margin:clamp(.55rem, 1.1vw, .9rem) 0; }
  #menu #menu-list a{ font-size:clamp(2rem, 1.5rem + 1.04vw, 2.75rem); line-height:1.08; }
}

/* ---- Menu overlay: voci con figli ----
   Il testo (<a>) e la freccia (.submenu-toggle) sono due target separati
   sulla stessa riga: click sul testo = naviga, click sulla freccia =
   espande/chiude. Il sottomenu (<ul class="sub-menu">, markup standard
   WordPress) va a capo su tutta la riga e parte chiuso — site.js anima
   l'altezza da 0 a scrollHeight, vedi lì per il perché non è un semplice
   max-height. */
#menu #menu-list li.menu-item-has-children{
  display:flex; align-items:center; flex-wrap:wrap; column-gap:.75rem;
}
#menu #menu-list li.menu-item-has-children > a{ flex:0 1 auto; }

#menu .submenu-toggle{
  display:inline-flex; align-items:center; justify-content:center;
  width:40px; height:40px; flex:none;
  background:none; border:0; padding:0; cursor:pointer;
  color:rgba(239,234,225,.55);
  transition:color .35s ease, transform .45s cubic-bezier(.65,0,.35,1);
}
#menu .submenu-toggle svg{ width:40px; height:40px; display:block; }
#menu .submenu-toggle:hover,
#menu .submenu-toggle:focus-visible{ color:var(--ottone); }
#menu .submenu-toggle:focus-visible{ outline:1px solid var(--ottone); outline-offset:4px; }
#menu li.menu-item-has-children.is-open > .submenu-toggle{ color:var(--ottone); transform:rotate(180deg); }

#menu .sub-menu{
  flex-basis:100%; list-style:none; margin:0; padding:0;
  height:0; overflow:hidden;
  transition:height .5s cubic-bezier(.65,0,.35,1);
}
#menu .sub-menu li{ position:relative; margin:.5rem 0 0; padding-left:1.4rem; }
#menu .sub-menu li::before{
  content:""; position:absolute; left:0; top:.85em; width:10px; height:1px; background:transparent;
}
#menu .sub-menu a{
  font-family:"Inter", system-ui, sans-serif;
  font-size:.95rem; font-weight:300; letter-spacing:.02em;
  color:var(--pietra);
}
@media (min-width:768px){
  #menu .sub-menu li{ margin-top:.6rem; }
  #menu .sub-menu a{ font-size:1.1rem; }
}

/* ---- Footer: elenco "Pagine" ---- */
.footer-pagine{ list-style:none; margin:0; padding:0; }
.footer-pagine li{ margin:0; }
.footer-pagine + .footer-pagine{ margin-top:.5rem; }
.footer-pagine li + li{ margin-top:.5rem; }
.footer-pagine a{ color:var(--pietra); font-weight:500; text-decoration:none; }

/* ---- Footer: riga social (aggiunta rispetto al sito statico,
   per soddisfare la gestione backend dei social richiesta) ---- */
.footer-social{ display:flex; align-items:center; gap:1.1rem; }
.footer-social a{
  color:var(--pietra); opacity:.7; transition:opacity .4s ease, color .4s ease;
  display:inline-flex; align-items:center; justify-content:center;
}
.footer-social a:hover{ opacity:1; color:var(--ottone); }
.footer-social svg{ width:16px; height:16px; display:block; }

/* ---- WhatsApp: pulsante flottante opzionale, attivabile dalle
   Impostazioni Optical Store ---- */
#optical-whatsapp{
  position:fixed; z-index:70; right:1.25rem; bottom:1.25rem;
  width:52px; height:52px; border-radius:50%;
  background:var(--ottone); color:var(--ink);
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 8px 30px rgba(0,0,0,.35);
  transition:transform .35s cubic-bezier(.65,0,.35,1);
}
#optical-whatsapp:hover{ transform:scale(1.08); }
#optical-whatsapp svg{ width:26px; height:26px; }

/* ---- Post type "brand": archivio ---- */
.brand-card .brand-logo img{ max-height:100%; width:auto; object-fit:contain; }

/* ---- Brand Showcase: rail desktop, niente ritaglio ----
   Il cliente non vuole immagini tagliate o alterate: qui non c'è più una
   larghezza fissa che forzava object-fit:cover a ritagliare. L'altezza resta
   quella dei 4 variant (il ritmo alto/basso, invariato), la larghezza la
   calcola optical_render_brand_showcase() dal rapporto reale della foto
   (--rail-ar, vedi optical_brand_rail_ratio in PHP) — stessa tecnica di
   --ig-ar/--gc-ar nelle altre due gallery del tema. object-fit:contain (mai
   cover) è solo una rete di sicurezza contro arrotondamenti di un decimo di
   pixel, la larghezza combacia già esattamente con la foto. */
.rail-card{
  height:var(--rail-h);
  width:calc(var(--rail-h) * var(--rail-ar, 1));
}
.rail-img{ width:100%; height:100%; object-fit:contain; }

/* ---- Post type "brand": carosello mobile (esperimento Owl Carousel) ----
   Da desktop .brand-grid resta invariata: qui si stila solo .brand-owl,
   visibile esclusivamente sotto i 768px (vedi archive-brand.php). Lo
   stagePadding in brand-owl.js lascia intravedere la card successiva. */
.brand-owl.owl-carousel{ display:block; position:relative; }
.brand-owl .owl-stage-outer{ overflow:hidden; }
.brand-owl .brand-card{ min-height:210px; margin:0 7px; }
.brand-owl .owl-dots{ display:flex; justify-content:center; gap:.5rem; margin-top:1.75rem; }
.brand-owl .owl-dot span{
  display:block; width:6px; height:6px; border-radius:50%;
  background:rgba(10,10,11,.22); transition:background .3s ease, transform .3s ease;
}
.brand-owl .owl-dot.active span{ background:var(--ottone); transform:scale(1.35); }

/* ---- Nav sottili (frecce), sempre visibili — icona fornita dal cliente.
   Posizionate rispetto a .brand-owl: il "calc(50% - 18px)" scala di circa
   mezza riga di dots per restare centrate sull'area immagine, non sull'
   intero blocco (immagine + dots sotto). ---- */
.brand-owl .owl-nav button.owl-prev,
.brand-owl .owl-nav button.owl-next{
  position:absolute; top:calc(50% - 18px); transform:translateY(-50%);
  width:32px; height:32px; display:flex; align-items:center; justify-content:center;
  color:var(--ottone); background:rgba(20,20,22,.5); backdrop-filter:blur(4px);
  border-radius:50%; transition:background .3s ease, opacity .3s ease, transform .3s ease;
}
.brand-owl .owl-nav button.owl-prev:active,
.brand-owl .owl-nav button.owl-next:active{ transform:translateY(-50%) scale(.92); }
.brand-owl .owl-nav button.owl-prev{ left:6px; }
.brand-owl .owl-nav button.owl-next{ right:6px; }
.brand-owl .owl-nav svg{ width:14px; height:14px; display:block; }
.brand-owl .owl-nav button.owl-prev svg{ transform:scaleX(-1); }
.brand-owl .owl-nav button.disabled{ opacity:.25; pointer-events:none; }

/* ---- Brand Showcase: slide del carosello mobile, sfalsate come il rail
   desktop (che alterna 4 altezze + self-end). Altezza auto, nessun tetto e
   nessun aspect-ratio fisso: segue sempre la proporzione reale della foto
   caricata alla larghezza piena dello slide, così non si ritaglia mai nulla
   (il cliente non vuole immagini tagliate o alterate). Niente vh: dentro un
   carosello e' un'unita' inaffidabile e lasciava vedere lo sfondo scuro di
   .media sotto la foto quando il calcolo non tornava esatto. ---- */
.brand-owl-slide{
  height:auto; margin-top:0;
  transition: margin-top .4s cubic-bezier(.65,0,.35,1);
}
/* Niente max-height + object-fit:cover: quel tetto ritagliava le foto più
   verticali (overflow-hidden è sull'anchor .brand-owl-slide). Ora l'altezza
   segue sempre e comunque la proporzione reale della foto alla larghezza
   piena dello slide — object-fit:contain resta solo come rete di sicurezza,
   qui non c'è mai un'altezza fissa da rispettare. */
.brand-owl .brand-owl-slide img{ height:auto; width:100%; display:block; object-fit:contain; }
.brand-owl .owl-item:nth-child(even) .brand-owl-slide{ margin-top:36px; }

/* ---- Post type "brand": scheda singola ---- */
.brand-hero{ height:100vh; min-height:460px; }
.brand-hero .media img {
  object-position: top;
}
@media (max-width:767px){ .brand-hero{ height:56vh; min-height:400px; } }

.brand-logo-chip{ height:44px; display:flex; align-items:center; }
.brand-logo-chip img{ max-height: 80px;
    width: auto;
    object-fit: contain;
    filter: brightness(0) invert(1);
    height: 80px !important;}

/* ---- Gallery brand, 3 layout a scelta (menu a tendina nel metabox) ----
   Niente crop in nessuno dei tre: ogni media mantiene la sua proporzione
   reale (height:auto), la regola sotto vale per tutti via [data-lightbox-root]. */

/* Layout "split": video impilati a sinistra in colonna, foto a destra. Le
   foto orizzontali occupano l'intera riga (column-span:all), quelle
   verticali/quadre stanno affiancate in coppia — la distinzione arriva dal
   confronto larghezza/altezza dell'allegato, calcolato in PHP. */
.brand-gallery-split{
  display:grid; grid-template-columns:1fr; gap:1.25rem; align-items:start;
}
@media (min-width:1024px){
  .brand-gallery-split{ grid-template-columns:1fr 1fr; }
}
.brand-gallery-videos{
  display:flex; flex-direction:column; gap:1.25rem;
}
/* CSS columns, non Grid: con Grid la riga prende l'altezza della foto più
   alta e lascia un vuoto sotto quella più corta accanto — con le columns
   ogni colonna scorre per conto suo, vero effetto masonry. column-span:all
   fa uscire le orizzontali dalle colonne per una riga intera, poi le colonne
   riprendono sotto. */
.brand-gallery-images{
  column-count:2; column-gap:1.25rem;
}
@media (max-width:599px){ .brand-gallery-images{ column-count:1; } }
.brand-gallery-images .media{ break-inside:avoid; margin-bottom:1.25rem; }
.brand-gallery-images .media.is-landscape{ column-span:all; }

/* Layout "merged" (default): un'unica gallery a colonne (masonry via CSS
   columns, non CSS Grid masonry perche' quest'ultimo e' supportato solo da
   Firefox), foto e video mescolati nell'ordine di caricamento.
   break-inside:avoid evita che un elemento venga tagliato a meta' tra una
   colonna e l'altra. Riusata anche dal layout "featured" per il lato destro
   (li' con meno colonne, essendo affiancata alla colonna del video grande). */
.brand-gallery-masonry{
  column-count:3; column-gap:1.25rem;
}
@media (max-width:1023px){ .brand-gallery-masonry{ column-count:2; } }
@media (max-width:599px){ .brand-gallery-masonry{ column-count:1; } }
.brand-gallery-masonry .media{
  break-inside:avoid; margin-bottom:1.25rem;
}

/* Layout "featured": il primo video, grande e fisso, in una colonna a
   sinistra; il resto (altri video + foto) nella stessa masonry di cui sopra,
   ma a 2 colonne invece di 3 essendo affiancata a una colonna piu' larga. */
.brand-gallery-featured{
  display:grid; grid-template-columns:1fr; gap:1.25rem;
}
@media (min-width:1024px){
  .brand-gallery-featured{ grid-template-columns:minmax(280px, 420px) 1fr; align-items:start; }
}
.brand-gallery-featured .brand-gallery-masonry{ column-count:2; }
@media (max-width:599px){ .brand-gallery-featured .brand-gallery-masonry{ column-count:1; } }

[data-lightbox-root] .media img,
[data-lightbox-root] .media video{
  width:100%; height:auto; display:block; object-fit:initial;
}
/* Niente cursor:zoom-in nativo: il cursore custom del sito (#cursor-dot/
   #cursor-ring in site.js/site.css) mostra qui uno stato dedicato ("zoom",
   il pallino diventa una crocetta sottile) — vedi setState('zoom') in site.js. */

/* ---- Lightbox gallery brand: overlay a schermo intero, stesso media (foto
   o video) ingrandito senza crop (object-fit:contain), navigabile con
   frecce/tastiera fra tutti gli elementi della gallery (video + foto, nello
   stesso ordine in cui compaiono in pagina). Markup fisso gia' in pagina
   (single-brand.php), site.js si limita a riempire .brand-lightbox-stage
   e a togliere/rimettere l'attributo [hidden]. ---- */
.brand-lightbox{
  position:fixed; inset:0; z-index:100;
  background:rgba(10,10,11,.94);
  display:flex; align-items:center; justify-content:center;
}
.brand-lightbox[hidden]{ display:none; }
.brand-lightbox-stage{
  max-width:min(92vw, 1400px); max-height:88vh;
  display:flex; align-items:center; justify-content:center;
}
.brand-lightbox-stage img,
.brand-lightbox-stage video{
  max-width:min(92vw, 1400px); max-height:88vh; width:auto; height:auto;
  display:block; object-fit:contain;
}
.brand-lightbox-close,
.brand-lightbox-arrow{
  position:absolute; border:0; background:rgba(239,234,225,.08); color:var(--panna);
  cursor:pointer; appearance:none; display:flex; align-items:center; justify-content:center;
  border-radius:50%; transition:background .25s ease, color .25s ease;
}
.brand-lightbox-close:hover,
.brand-lightbox-arrow:hover{ background:var(--ottone); color:var(--ink); }
.brand-lightbox-close{ top:20px; right:20px; width:44px; height:44px; font-size:22px; line-height:1; }
.brand-lightbox-arrow{ top:50%; transform:translateY(-50%); width:52px; height:52px; }
.brand-lightbox-arrow svg{ width:22px; height:22px; }
.brand-lightbox-prev{ left:16px; }
.brand-lightbox-next{ right:16px; }
@media (max-width:767px){
  .brand-lightbox-arrow{ width:40px; height:40px; }
  .brand-lightbox-prev{ left:8px; } .brand-lightbox-next{ right:8px; }
  .brand-lightbox-close{ top:10px; right:10px; }
}

/* ---- Bottone play/pausa dei video in gallery: anello color ottone che
   segue l'avanzamento (var(--progress), 0-1, aggiornato in site.js sul
   timeupdate del video), "donut" ritagliato con mask invece che con SVG. ---- */
.video-toggle{
  --progress:0;
  position:absolute; left:14px; bottom:14px; z-index:2;
  width:42px; height:42px; padding:0; border:0; border-radius:50%;
  background:rgba(10,10,11,.45); cursor:pointer; appearance:none;
  display:flex; align-items:center; justify-content:center;
}
.video-toggle-ring{
  position:absolute; inset:0; border-radius:50%;
  background:conic-gradient(var(--ottone) calc(var(--progress) * 360deg), rgba(239,234,225,.3) 0deg);
  -webkit-mask:radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
          mask:radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
}
.video-toggle-icon{ position:relative; width:14px; height:14px; }
.video-toggle-icon::before,
.video-toggle-icon::after{ content:""; position:absolute; top:0; left:1px; width:4px; height:14px; background:var(--panna); }
.video-toggle-icon::after{ left:9px; }
.video-toggle.is-paused .video-toggle-icon::before{
  left:0; width:0; height:0; background:transparent;
  border-style:solid; border-width:7px 0 7px 12px; border-color:transparent transparent transparent var(--panna);
}
.video-toggle.is-paused .video-toggle-icon::after{ display:none; }

/* ---- Elementor free: le classi "data-reveal", "data-reveal-words",
   "data-mask", "data-line", "data-light-section", "data-parallax[-N]"
   (vedi commento in cima a site.js) non hanno stile proprio: site.js le
   trasforma in veri data-attribute all'avvio, quindi qui non serve altro. ---- */

/* ---- Sfondo con zoom/blur allo scroll ----
   Su un Container Elementor con immagine di sfondo: in Avanzate → CSS
   Classes aggiungi "effetto-scroll-img". site.js legge il background-image
   già impostato da Elementor, lo sposta su ::before come variabile CSS e
   anima scala/sfocatura in base alla distanza dal centro schermo — così
   l'immagine si "mette a fuoco" avvicinandosi al centro, coerente con la
   firma del progetto. */
.effetto-scroll-img{ position:relative; overflow:hidden; }
.effetto-scroll-img.effetto-scroll-active{ background-image:none !important; }
.effetto-scroll-active::before{
  content:""; position:absolute; inset:0;
  background-image:var(--optical-bg-image, none);
  background-size:cover; background-position:center; background-repeat:no-repeat;
  transform:scale(var(--optical-bg-scale, 1));
  filter:blur(var(--optical-bg-blur, 0px));
  transform-origin:center;
  transition:transform .1s ease-out, filter .1s ease-out;
  will-change:transform, filter;
  z-index:0; pointer-events:none;
}
.effetto-scroll-active > .e-con-inner{ position:relative; z-index:1; }

/* =========================================================
   SPECIFICITÀ CONTRO ELEMENTOR
   Elementor stila i Container con .e-con — e dove teme di perdere con
   .e-con.e-con, due classi — e fa passare TUTTE le proprietà di scatola
   da variabili con un default sempre valorizzato: height:var(--height)
   con --height:auto, min-height:var(--min-height), display:var(--display),
   overflow:var(--overflow), padding-block-start:var(--padding-block-start)...
   Una nostra regola a classe singola — .page-hero{height:78vh} — pareggia
   o perde, e resta applicato il default di Elementor: la hero collassa.

   La soluzione NON è !important. Un !important da foglio di stile batte
   anche gli stili inline, e GSAP anima scrivendo stili inline: messo qui,
   bloccherebbe al valore di partenza ogni animazione che tocca la stessa
   proprietà. È esattamente il motivo per cui in functions.php Tailwind non
   usa important:true ma l'àncora #optical-app, l'id fisso sul <body>
   (header.php). Stessa scelta qui: specificità 1-1-0, che batte .e-con.e-con
   (0-2-0) restando CSS normale — quindi perde correttamente contro gli
   stili inline di GSAP, come deve.

   Qui sotto vanno SOLO le classi di site.css pensate per finire davvero
   su un Container o su un widget Elementor. Tutto ciò che vive dentro un
   widget HTML (bottoni, filetti, tabelle, campioni materiali) non incontra
   mai .e-con e non ha bisogno di àncora: lasciarlo fuori tiene il file
   corto e site.css identico a quello del sito statico.
   ========================================================= */

/* Hero di pagina — contro .e-con{ height:var(--height); min-height:var(--min-height) }.
   Lasciare vuoto Min Height nel pannello Elementor: ci pensa questa regola. */
#optical-app .page-hero{ height:78vh; min-height:520px; }
@media (max-width:767px){
  #optical-app .page-hero{ height:70vh; min-height:440px; }
}

/* Sfondo con zoom/blur allo scroll — overflow:hidden contro .e-con{ overflow:var(--overflow) }:
   senza, il ::before scalato deborda oltre i bordi della sezione. */
#optical-app .effetto-scroll-img{ position:relative; overflow:hidden; }

/* Contenitore media — il gradiente di fondo contro il background del Container.
   Da usare solo dove dentro c'è un <img>/<video> vero: su un Container con
   immagine di sfondo impostata da Elementor la classe "media" va OMESSA,
   altrimenti questo gradiente copre la foto. */
#optical-app .media{ background: radial-gradient(120% 90% at 30% 20%, #232326 0%, #121214 55%, #0A0A0B 100%); }

/* Griglie — display:grid contro .e-con{ display:var(--display) }, che vale flex. */
#optical-app .materiali-strip{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr));
  gap:1px; background:rgba(239,234,225,.1); border:1px solid rgba(239,234,225,.1);
}

/* Padding e bordi — contro le variabili --padding-* e --border-* di .e-con. */
#optical-app .card-light{ border-top:1px solid rgba(10,10,11,.16); padding-top:1.5rem; }
#optical-app .quote-block{ border-left:1px solid rgba(185,155,107,.5); padding-left:1.75rem; }
#optical-app .tick{ position:relative; padding-left:2rem; }

/* Accordion — height:0 e overflow:hidden sono la chiusura del pannello:
   se .e-con li riporta a auto/visible, l'accordion nasce già aperto. */
#optical-app .acc-head{
  width:100%; display:flex; align-items:center; justify-content:space-between;
  gap:2rem; padding:1.6rem 0; text-align:left;
}
#optical-app .acc-body{ height:0; overflow:hidden; }

/* =========================================================
   HEADER DELLE PAGINE INTERNE
   Sulla home il logo entra in barra dalla hero e l'header cambia aspetto
   legato allo scroll dei video: quel comportamento resta intatto. Qui si
   stila solo il ramo .header-inner di dynamic-header.php — logo statico a
   sinistra, Menu e CTA a destra, barra trasparente in cima che allo scroll
   diventa bianca (classe .is-stuck, messa da site.js oltre gli 80px).
   ========================================================= */

#header{ transition:background-color .45s ease, padding .4s ease, box-shadow .45s ease; }

/* Logo a sinistra: due file reali sovrapposti (chiaro/scuro) in cross-fade,
   come già fa #header-logo-mobile. Il file chiaro resta nel flusso e detta
   l'ingombro del link; lo scuro gli va sopra in assoluto e si accende solo
   nello stato bianco — nessun filtro CSS che "inventa" un colore, coerente
   con la scelta fatta in optical_logo_dark_url(). */
#header.header-inner #header-logo{ position:relative; display:block; flex:none; line-height:0; }
#header.header-inner #header-logo img{
  display:block; height:40px; width:auto; object-fit:contain;
  transition:opacity .4s ease;
}
#header.header-inner #header-logo .logo-dark{ position:absolute; left:0; top:0; opacity:0; }
@media (min-width:768px){
  #header.header-inner #header-logo img{ height:60px; }
}

/* Menu e CTA raggruppati a destra */
#header-actions{ display:flex; align-items:center; gap:1.15rem; }
@media (min-width:768px){ #header-actions{ gap:1.75rem; } }

/* Stato sticky: fondo bianco, logo scuro, testi neri.
   Vale anche .on-light, che ScrollTrigger accende attraversando una sezione
   panna: stesso identico aspetto per logo e testi, così le due condizioni
   non si contraddicono se capitano insieme. */
#header.header-inner.is-stuck{
  background-color:#fff;
  box-shadow:0 1px 0 rgba(10,10,11,.08);
  padding-top:.85rem; padding-bottom:.85rem;
}
#header.header-inner.is-stuck #header-logo .logo-light,
#header.header-inner.on-light #header-logo .logo-light{ opacity:0; }
#header.header-inner.is-stuck #header-logo .logo-dark,
#header.header-inner.on-light #header-logo .logo-dark{ opacity:1; }

#header.header-inner.is-stuck #menu-open{ color:var(--ink); }
#header.header-inner.is-stuck #header-cta{ color:var(--ink); border-color:rgba(10,10,11,.35); }
#header.header-inner.is-stuck #header-cta:hover{ background:var(--ink); color:var(--panna); }

/* Su schermo corto la barra bianca si stringe ancora un po' */
@media (max-width:767px){
  #header.header-inner.is-stuck{ padding-top:.7rem; padding-bottom:.7rem; }
}

/* ---- Nested Accordion di Elementor: icona +/- ----
   Elementor dimensiona l'icona agendo sull'altezza e lasciando alla SVG una
   larghezza fissa, che sulle icone non quadrate la schiaccia o la stira.
   Con width:auto la SVG torna a seguire il proprio rapporto d'aspetto.
   Qui !important non crea i problemi visti sopra con .e-con: nessuna
   animazione GSAP tocca la larghezza di questa SVG, quindi non c'è nessuno
   stile inline da scavalcare. */
.e-n-accordion-item-title-icon svg{ width:auto !important; }

/* =========================================================
   WIDGET "OPTICAL — GALLERIA SERVIZI"
   Testo a sinistra, carosello a destra che prosegue oltre il bordo destro
   dello schermo. Palette, tipografia e bottoni sono quelli del tema: qui
   non si introduce nessun colore o font nuovo.

   PERCHÉ OGNI REGOLA È ANCORATA A #optical-app
   Prima stava scritta a classe singola e le immagini uscivano ognuna con
   la sua altezza naturale: "height:430px" su .gc-figure img (0-2-0) veniva
   scavalcato dal reset che agisce su "img" nudo con l'id davanti (1-0-1) —
   più specifico perché un id pesa più di qualsiasi numero di classi.
   Stessa storia per i margini di p, h2 e figure, che un reset azzera.
   Con #optical-app davanti si arriva a 1-2-0 e si vince restando CSS
   normale, senza !important: la stessa scelta già fatta per Tailwind in
   functions.php e per .page-hero qui sopra.
   ========================================================= */

/* Il widget vive dentro un Container Elementor, che ha i suoi padding e la
   sua larghezza massima. Per uscirne e occupare tutta la finestra si usa il
   full-bleed a 100vw con i margini negativi. Rimosso: quel trucco presuppone
   che il contenitore sia centrato e largo quanto la finestra, e dentro un
   Container Elementor boxed non è vero — "left:50%" sposta di mezzo
   contenitore mentre "margin-left:-50vw" tira indietro di mezza finestra, e
   la differenza fra le due misure buttava la sezione fuori a sinistra,
   tagliando il testo. In più i 100vw comprendono la barra di scorrimento,
   il 100% no.

   Adesso la sezione occupa semplicemente il suo contenitore. Il carosello
   continua a essere tagliato dall'overflow:hidden, solo che il taglio cade
   sul bordo del Container invece che su quello dello schermo: per riavere
   l'uscita fino al bordo finestra basta mettere il widget in un Container
   a tutta larghezza e con padding destro a zero. */
#optical-app .gallery-carousel{
  --gc-gutter: 0px;  /* l'inset a sinistra lo dà il padding del Container */
  --gc-h: 430px;     /* altezza unica di tutte le slide: cambiala qui, non sulle regole sotto */
  position:relative;
  width:100%;
  background:var(--ink);
  padding-block:clamp(4rem, 9vw, 7.5rem);
  overflow:hidden;
}

#optical-app .gc-split{
  display:grid;
  grid-template-columns:minmax(0, 34rem) minmax(0, 1fr);
  gap:clamp(2.5rem, 5vw, 5.5rem);
  align-items:start;
  padding-left:var(--gc-gutter); /* nessun padding a destra: si esce dallo schermo */
}

/* ---- Colonna testo ---- */
#optical-app .gc-content{ padding-top:.35rem; }
#optical-app .gc-content .eyebrow{ display:block; margin:0 0 1.4rem; }

#optical-app .gc-title{
  margin:0 0 1.8rem;
  font-size:clamp(2.4rem, 4.4vw, 3.6rem);
  line-height:1.08;
  color:var(--panna);
  text-wrap:balance;
}

#optical-app .gc-text{ color:var(--pietra); }
#optical-app .gc-text p{
  margin:0 0 1.15rem;
  font-size:1rem; font-weight:300; line-height:1.75;
  max-width:44ch;
}
#optical-app .gc-text p:last-child{ margin-bottom:0; }

#optical-app .gc-actions{ display:flex; flex-wrap:wrap; gap:1rem; margin-top:2.8rem; }

/* ---- Frecce e contatore ---- */
#optical-app .gc-nav{ display:flex; align-items:center; gap:1.1rem; margin-bottom:2.1rem; }

#optical-app .gc-arrow{
  width:52px; height:52px; flex:none;
  display:grid; place-items:center;
  background:none;
  border:1px solid rgba(239,234,225,.22);
  border-radius:50%;
  color:var(--panna);
  cursor:pointer;
  transition:border-color .35s ease, background-color .35s ease, color .35s ease;
}
#optical-app .gc-arrow:hover{ border-color:var(--ottone); background:var(--ottone); color:var(--ink); }
#optical-app .gc-arrow:focus-visible{ outline:1px solid var(--ottone); outline-offset:4px; }
#optical-app .gc-arrow svg{ width:15px; height:15px; display:block; }

#optical-app .gc-counter{
  font-size:.78rem; letter-spacing:.18em;
  color:var(--grigio-antracite) ! important; 
  font-variant-numeric:tabular-nums;
}
#optical-app .gc-counter b{ color:var(--panna); font-weight:500; }

/* ---- Slide ----
   Tutte alte uguale (--gc-h), ognuna larga quanto la propria foto: una
   panoramica resta orizzontale, un ritratto resta verticale. La larghezza
   è altezza × rapporto d'aspetto, e il rapporto arriva dal PHP come
   --gc-ar sulla singola slide (vedi optical_gallery_slide_ratio).

   Il rapporto NON si ricava dall'immagine via CSS di proposito: Owl in
   autoWidth misura le slide all'avvio e, se la larghezza dipendesse dal
   file caricato, alla prima passata le troverebbe a zero. Così invece la
   misura è nota subito, prima ancora che le foto arrivino — niente
   carosello sfasato e niente salto di layout.

   Cambiando --gc-h sulla sezione, le larghezze si riadattano da sole. */
#optical-app .gc-gallery{ min-width:0; }

#optical-app .gc-owl .gc-item{ width:calc(var(--gc-h) * var(--gc-ar, .78)); }

#optical-app .gc-figure{
  margin:0; overflow:hidden;
  height:var(--gc-h);
  background:var(--carbon);
}
#optical-app .gc-figure img{
  display:block; width:100%; height:100%; max-width:none; object-fit:cover;
  transition:transform .8s cubic-bezier(.22,.61,.36,1);
}
#optical-app .gc-item:hover .gc-figure img{ transform:scale(1.05); }

#optical-app .gc-caption{
  margin:.95rem 0 0;
  font-size:.7rem; font-weight:500;
  letter-spacing:.2em; text-transform:uppercase;
  color:rgba(239,234,225,.62);
}

#optical-app .gc-owl.owl-carousel .owl-stage{ display:flex; }
#optical-app .gc-owl.owl-carousel.owl-drag .owl-item{ user-select:none; }

/* ---- Responsive ---- */
@media (max-width:1023px){
  #optical-app .gc-split{ grid-template-columns:1fr; gap:2.6rem; }
  #optical-app .gc-text p{ max-width:100%; }
  #optical-app .gc-actions{ margin-top:2.2rem; padding-right:var(--gc-gutter); }
  #optical-app .gc-nav{ margin-bottom:1.6rem; }
}
@media (max-width:600px){
  /* Basta abbassare l'altezza: le larghezze la seguono da sole, ognuna
     mantenendo il proprio rapporto. */
  #optical-app .gallery-carousel{ --gc-h:330px; }
  #optical-app .gc-actions .btn{ flex:1 1 auto; justify-content:center; }
}

/* Nell'editor Elementor il widget è dentro un'anteprima più stretta della
   finestra vera: i 100vw del full-bleed lo farebbero sbordare e comparire
   una barra di scorrimento orizzontale nel canvas. In editor lo teniamo
   dentro al contenitore — il full-bleed si vede correttamente in anteprima
   e sul sito pubblicato. Le due classi stanno sullo stesso <body> che porta
   l'id, quindi si scrivono attaccate: così questa regola pesa più di quella
   ancorata qui sopra e riesce a disattivarla. */
/* (Qui stava l'annullamento del full-bleed dentro l'editor Elementor: non
   serve più, ora la sezione sta dentro il suo contenitore ovunque — editor,
   anteprima e sito pubblicato si comportano allo stesso modo.) */

/* =========================================================
   WIDGET "OPTICAL — GALLERIA IMMAGINI"
   Galleria generica a due layout intercambiabili, scelti in Elementor:

   OWL   ogni slide è larga --ig-h × --ig-ar (il rapporto reale, MAI
         clampato — vedi optical_image_gallery_ratio in PHP): la larghezza
         combacia sempre esattamente con la foto, quindi object-fit:contain
         non deve mai ritagliare nulla, è solo una rete di sicurezza contro
         arrotondamenti di un decimo di pixel.

   MASONRY  colonne CSS pure (column-count), niente altezza fissa e niente
            object-fit: le foto restano alla loro proporzione naturale per
            costruzione, zero JS necessario.

   Ancorato a #optical-app per lo stesso motivo della Galleria Servizi qui
   sopra: vincere il reset del parent theme senza !important.
   ========================================================= */

/* I --ig-* NON hanno un valore di default dichiarato qui (vedi sotto perché):
   sta tutto nel secondo argomento dei var() dove vengono consumati. */
#optical-app .optical-image-gallery{
  width:100%;
}

/* PERCHÉ I DEFAULT NON STANNO PIÙ QUI SOPRA
   Elementor scrive il valore di ogni controllo "selectors" su un selettore
   tipo ".elementor-element-xxxx .optical-image-gallery.ig-masonry" — due/tre
   classi, specificità 0-N-0. Una dichiarazione qui sopra, ancorata a
   #optical-app, pesa 1-1-0: l'ID batte SEMPRE quel selettore, qualunque sia
   il numero di classi, quindi il valore di Elementor perdeva sempre e il
   controllo (Colonne, Altezza slide, Spaziatura, Arrotondamento...) sembrava
   non fare nulla — è il bug segnalato con le colonne della masonry sempre a 3.
   Ora questa regola non dichiara più --ig-h/--ig-gap/--ig-cols/--ig-radius:
   l'UNICO posto che li dichiara davvero è la regola scritta da Elementor per
   quella istanza, quindi non c'è più nessuno scontro di specificità da
   perdere. Il valore di ripiego (quando il controllo è al suo default e/o
   il markup viene usato fuori da Elementor) vive nel var(--x, fallback) dove
   la proprietà viene letta, qualche riga più sotto. */
#optical-app .ig-figure{
  position:relative;
  overflow:hidden;
  border-radius:var(--ig-radius, 0px);
  background:var(--carbon);
}
#optical-app .ig-figure a{ display:block; }
#optical-app .ig-figure img{ display:block; transition:transform .8s cubic-bezier(.22,.61,.36,1); }
#optical-app .ig-hover-zoom .ig-item:hover img{ transform:scale(1.05); }

#optical-app .ig-caption{
  margin:.85rem 0 0;
  font-size:.7rem; font-weight:500;
  letter-spacing:.2em; text-transform:uppercase;
  color:var(--ig-caption-color, rgba(239,234,225,.62));
}

/* ---- Layout owl: slide larga quanto la propria foto ---- */
#optical-app .ig-owl .ig-item{ width:calc(var(--ig-h, 380px) * var(--ig-ar, 1)); margin:0; }
#optical-app .ig-owl .ig-figure{ height:var(--ig-h, 380px); width:100%; }
#optical-app .ig-owl .ig-figure img{
  width:100%; height:100%; max-width:none;
  object-fit:contain; /* mai cover: qui non deve ritagliare per nessun motivo */
}
#optical-app .ig-owl .owl-stage{ display:flex; }
#optical-app .ig-owl.owl-carousel.owl-drag .owl-item{ user-select:none; }

/* ---- Intestazione: sopratitolo/titolo + frecce/contatore ----
   Tutto sulla stessa riga, sopra le foto — non sotto, dove le metterebbe
   di default Owl. Sopratitolo e titolo sono opzionali: il widget resta
   utilizzabile come pura galleria senza intestazione (vedi $show_head nel
   render PHP). I colori sono personalizzabili da Elementor (selectors sui
   controlli eyebrow_color/title_color/caption_color): qui restano solo i
   valori di ripiego, quelli che si vedono finché non se ne sceglie uno. */
#optical-app .ig-head{
  display:flex; align-items:flex-end; justify-content:space-between; flex-wrap:wrap;
  gap:1.75rem; margin-bottom:1.8rem;
}
#optical-app .ig-eyebrow{ display:block; margin:0 0 .9rem; color:var(--ig-eyebrow-color, var(--ottone)); }
#optical-app .ig-title{
  margin:0; font-size:clamp(1.7rem, 3vw, 2.5rem); line-height:1.12; color:var(--ig-title-color, var(--panna));
}
.blackTitle .ig-title{
    color: var(--e-global-color-text) !important;
}
/* Stessi valori di .gc-arrow/.gc-counter (Galleria Servizi): come lì, ci si
   aspetta di usare questo widget dentro una sezione scura — è il caso mostrato
   nell'anteprima statica della pagina Occhiali da Vista. Su una sezione
   chiara ritocca semplicemente i colori qui sotto. */
#optical-app .ig-nav{ display:flex; align-items:center; gap:1.1rem; flex:none; }
#optical-app .ig-arrow{
  width:48px; height:48px; flex:none;
  display:grid; place-items:center;
  background:none;
  border:1px solid var(--grigio-antracite);
  border-radius:50%;
  color:var(--grigio-antracite);
  cursor:pointer;
  transition:border-color .35s ease, background-color .35s ease, color .35s ease;
}
#optical-app .ig-arrow:hover{ border-color:var(--ottone); background:var(--ottone); color:var(--ink); }
#optical-app .ig-arrow:focus-visible{ outline:1px solid var(--ottone); outline-offset:4px; }
#optical-app .ig-arrow svg{ width:14px; height:14px; display:block; }
#optical-app .ig-counter{
  font-size:.78rem; letter-spacing:.18em;
  color:var(--grigio-antracite) ! important;
  font-variant-numeric:tabular-nums;
}
#optical-app .ig-counter b{ color:var(--grigio-antracite); font-weight:500; }

/* Pallini: nativi di Owl (dots:true dal widget), ricolorati con la palette
   del tema invece dello stile default. */
#optical-app .ig-owl .owl-dots{ margin-top:1.2rem; display:flex; gap:.5rem; justify-content:center; }
#optical-app .ig-owl .owl-dots .owl-dot span{
  display:block; width:7px; height:7px; border-radius:50%;
  background:rgba(239,234,225,.28);
  transition:background-color .3s ease, transform .3s ease;
}
#optical-app .ig-owl .owl-dots .owl-dot.active span{ background:var(--ottone); transform:scale(1.3); }

/* ---- Layout masonry: colonne CSS, altezza naturale ---- */
#optical-app .ig-masonry .ig-track{
  column-count:var(--ig-cols, 3);
  column-gap:var(--ig-gap, 16px);
}
#optical-app .ig-masonry .ig-item{
  display:inline-block; /* Safari: senza, le colonne CSS possono spezzare la figure a metà */
  width:100%;
  margin:0 0 var(--ig-gap, 16px);
  break-inside:avoid;
}
#optical-app .ig-masonry .ig-figure{ height:auto; }
#optical-app .ig-masonry .ig-figure img{ width:100%; height:auto; max-width:100%; } /* nessun object-fit: niente da ritagliare */

/* Sotto i 600px l'altezza scelta in Elementor non deve sparire (stesso bug
   di sopra se qui si riscrivesse --ig-h): min() la lascia intatta quando è
   già piccola e la limita solo se è più alta di 280px, senza bisogno di
   ridichiarare la custom property. */
@media (max-width:600px){
  #optical-app .ig-owl .ig-figure{ height:min(var(--ig-h, 380px), 280px); }
  #optical-app .ig-owl .ig-item{ width:calc(min(var(--ig-h, 380px), 280px) * var(--ig-ar, 1)); }
}

/* =========================================================
   WIDGET "OPTICAL — LOGHI"
   Fascia a scorrimento continuo (marquee), sfondo bianco di default, in
   pausa al passaggio del mouse. Tutto CSS: la lista dei loghi è duplicata
   due volte nel markup (vedi render PHP) e l'animazione trasla il primo
   giro esattamente della metà della larghezza totale (-50%) — a quel punto
   la seconda copia è arrivata dove stava la prima, e il ciclo riparte senza
   che si veda lo scatto. Stessa tecnica di .marquee in site.css (statico),
   qui senza GSAP: per un loop di sfondo continuo non serve JavaScript.
   ========================================================= */
/* Stessa correzione della Galleria Immagini qui sopra: nessuna di queste
   regole dichiara più un valore per le sue --optical-logo-* (il conflitto di
   specificità con #optical-app faceva perdere sempre i controlli Elementor —
   Colonne/Altezza/Sfondo/Velocità sembravano non fare nulla). L'unica cosa
   che dichiara davvero queste custom property è il "selectors" scritto da
   Elementor per quell'istanza; qui sotto restano solo i fallback nei var(). */
#optical-app .optical-logo-strip{
  position:relative; /* contiene le 3 zone hover assolute, vedi sotto */
  background:var(--optical-logo-bg, #fff);
  overflow:hidden;
  padding-block:var(--optical-logo-pad, 28px);
}

#optical-app .optical-logo-track{
  display:flex;
  align-items:center; /* con la scala per-logo le altezze non sono più tutte uguali */
  width:max-content;
  animation:optical-logo-scroll var(--optical-logo-speed, 32s) linear infinite;
  animation-direction:var(--optical-logo-direction, normal);
}
#optical-app .optical-logo-strip:not(.no-pause):hover .optical-logo-track{ animation-play-state:paused; }

/* Zone hover sinistra/centro/destra: al centro pausa (come sopra), ai lati
   il nastro scorre nella direzione di quel lato. Le zone sono 3 elementi
   invisibili sovrapposti ai loghi (position:absolute, quindi già sopra il
   track che è in flusso normale, senza bisogno di z-index) — servono solo
   a intercettare l'hover, i loghi restano sotto senza essere cliccabili.
   :has() non serve dichiararlo con @supports perché senza supporto la
   regola sopra (pausa su tutta la fascia) resta comunque valida: qui sotto
   è solo un potenziamento che, se non c'è, lascia il comportamento base. */
#optical-app .optical-logo-hover-zones{
  position:absolute; inset:0; z-index:2;
  display:flex;
}
/* z-index esplicito indispensabile: .optical-logo-track anima "transform"
   (vedi @keyframes sotto), e in CSS un elemento che anima transform/opacity/
   filter crea da solo un proprio stacking context "a quota 0" — la stessa
   quota di un elemento position:absolute con z-index:auto come queste zone.
   A parità di quota vince l'ultimo nell'ordine del markup, cioè il track
   (che viene dopo): senza questo z-index il track dipingeva sopra le zone
   e il mouse hoverava sempre le immagini, mai le zone invisibili sotto —
   per questo scattava solo la pausa (bolla su tutta la fascia) e mai lo
   scorrimento direzionale. */
#optical-app .optical-logo-zone{ flex:1 1 0; }

#optical-app .optical-logo-strip:not(.no-pause):has(.optical-logo-zone:hover) .optical-logo-track{
  animation-play-state:running;
}
#optical-app .optical-logo-strip:not(.no-pause):has(.optical-logo-zone--center:hover) .optical-logo-track{
  animation-play-state:paused;
}
#optical-app .optical-logo-strip:not(.no-pause):has(.optical-logo-zone--left:hover) .optical-logo-track{
  animation-direction:reverse;
}
#optical-app .optical-logo-strip:not(.no-pause):has(.optical-logo-zone--right:hover) .optical-logo-track{
  animation-direction:normal;
}

/* --optical-logo-gap e --optical-logo-h li scrive Elementor su .optical-logo-strip
   (il contenitore): essendo custom property, arrivano per eredità fino a
   .optical-logo-item senza bisogno che qui sotto le si ridichiari — anzi,
   ridichiararle qui le nasconderebbe (un valore impostato SULL'elemento
   stesso vince sempre su uno solo ereditato, indipendentemente dalla
   specificità). --optical-logo-scale invece è per-brand, in uno style="
   inline sull'item stesso (scheda Brand → "Scala logo"): un inline style
   vince comunque su qualunque regola da foglio esterno, nessun conflitto. */
#optical-app .optical-logo-item{
  flex:none;
  display:flex; align-items:center;
  height:calc(var(--optical-logo-h, 40px) * var(--optical-logo-scale, 1));
  margin-right:var(--optical-logo-gap, 56px);
}
#optical-app .optical-logo-item img{
  height:100%; width:auto; max-width:none; object-fit:contain; display:block;
}

/* Colore al passaggio del mouse: la pausa dell'intera fascia scatta comunque
   passando sopra un punto qualsiasi, questo è solo l'effetto sul singolo logo. */
#optical-app .optical-logo-strip.is-grayscale .optical-logo-item img{
  filter:grayscale(1) opacity(.55); transition:filter .35s ease;
}
#optical-app .optical-logo-strip.is-grayscale .optical-logo-item:hover img{
  filter:grayscale(0) opacity(1);
}

@keyframes optical-logo-scroll{
  from{ transform:translateX(0); }
  to{ transform:translateX(-50%); }
}

@media (prefers-reduced-motion:reduce){
  #optical-app .optical-logo-track{ animation:none; }
}

/* =========================================================
   LIGHTBOX NATIVA DI ELEMENTOR — FRECCE SEMPRE VISIBILI
   Se in lightbox risulta possibile solo lo swipe/trascinamento e non il
   click sulle frecce, il 99% delle volte è un'impostazione del Kit spenta,
   non del tema: Elementor → Impostazioni Sito → Lightbox → "Frecce" va
   attivo (assieme, se vuoi anche il Contatore). Questa regola è solo una
   rete di sicurezza per il caso in cui le frecce ci siano già nel markup
   ma restino invisibili/sotto ad altro (icona scura su fondo scuro,
   opacity ereditata da qualche reset, z-index basso): forza visibilità e
   le ricolora con la palette del tema. Se dopo aver attivato l'impostazione
   del Kit le frecce ancora non si vedono, il problema è probabilmente
   quello che questa regola risolve. */
.elementor-lightbox .elementor-swiper-button{
  display:flex !important;
  opacity:1 !important;
  visibility:visible !important;
  pointer-events:auto !important;
  color:var(--panna) !important;
  z-index:10;
}
.elementor-lightbox .elementor-swiper-button:hover{ color:var(--ottone) !important; }
.elementor-lightbox .elementor-swiper-button.elementor-swiper-button-disabled{ opacity:.35 !important; }

/* =========================================================
   FORM CONTATTI — CONTACT FORM 7
   Stessa estetica del form della pagina statica contatti.html: etichetta che
   sale sopra il campo appena scrivi o metti a fuoco, checkbox disegnata a
   mano, bottone che si riempie. Il template da incollare nella tab "Modulo"
   di Contact Form 7 è nella risposta della chat, non qui — qui c'è solo lo
   stile, ancorato a #optical-app come il resto del file (stessa ragione:
   battere il reset del tema padre su tag nudi come input/textarea/label).

   PERCHÉ .field input:focus + label NON BASTA PIÙ
   Nel form statico l'input e la label erano fratelli diretti nell'HTML.
   CF7 avvolge SEMPRE ogni campo in un suo <span class="wpcf7-form-control-
   wrap">, quindi la label non è più il fratello immediato dell'input — è il
   fratello di quello span. Il combinatore "+" non riesce a saltare dentro lo
   span, per questo sotto si usa :has() sullo span invece che sull'input: è
   supportato da tutti i browser correnti (Chrome/Edge/Safari dal 2023,
   Firefox dal 121/dic. 2023).
   ========================================================= */
#optical-app .cf7-optical{ margin-top:3.5rem; display:grid; gap:2rem; }

#optical-app .cf7-optical .grid-2{ display:grid; gap:2rem; }
@media (min-width:768px){
  #optical-app .cf7-optical .grid-2{ grid-template-columns:1fr 1fr; }
}

#optical-app .cf7-optical .field{ position:relative; }
#optical-app .cf7-optical .field input,
#optical-app .cf7-optical .field textarea{
  width:100%; background:transparent; border:0; border-bottom:1px solid rgba(10,10,11,.25);
  padding:1.5rem 0 .6rem; color:var(--ink); font-weight:300; font-size:1rem;
  font-family:inherit; outline:none; transition:border-color .4s ease;
}
#optical-app .cf7-optical .field textarea{ min-height:5rem; resize:vertical; } /* poche righe di proposito */
#optical-app .cf7-optical .field input:focus,
#optical-app .cf7-optical .field textarea:focus{ border-color:var(--ottone); }
#optical-app .cf7-optical .field input.wpcf7-not-valid,
#optical-app .cf7-optical .field textarea.wpcf7-not-valid{ border-color:#9c4a3c; }

#optical-app .cf7-optical .field label{
  position:absolute; left:0; top:1.4rem; color:rgba(10,10,11,.5);
  font-size:.72rem; letter-spacing:.18em; text-transform:uppercase; pointer-events:none;
  transition:transform .4s cubic-bezier(.65,0,.35,1), color .4s ease;
  transform-origin:left top;
}
/* :has() sull'intero .field (non più sullo span "wpcf7-form-control-wrap" di
   CF7 come fratello diretto della label): così funziona a prescindere da
   come/quanto CF7 annidi il campo dentro quello span — bastava una struttura
   leggermente diversa dal previsto e la label restava ferma, sovrapposta al
   testo appena scritto. "input"/"textarea" sono specificati dentro :has()
   apposta: senza, :has(:not(:placeholder-shown)) sarebbe risultato vero
   SEMPRE, perché anche la label stessa (che non ha un placeholder) soddisfa
   banalmente ":not(:placeholder-shown)" essendo un elemento a cui quello
   pseudo-stato non si applica. */
#optical-app .cf7-optical .field:has(input:focus, textarea:focus) label,
#optical-app .cf7-optical .field:has(input:not(:placeholder-shown), textarea:not(:placeholder-shown)) label{
  transform:translateY(-1.35rem) scale(.85); color:var(--ottone);
}

/* Messaggio di errore/conferma di WordPress sotto al singolo campo */
#optical-app .cf7-optical .wpcf7-not-valid-tip{
  display:block; margin-top:.5rem; font-size:.7rem; letter-spacing:.02em; color:#9c4a3c;
}

/* ---- Checkbox privacy ([acceptance]) ----
   CF7 genera <label><input type="checkbox">testo</label>: niente span da
   stilizzare come "scatola", quindi la scatola è l'input stesso reso
   invisibile (appearance:none), col segno di spunta disegnato via ::after
   (il classico "angolo" ottenuto ruotando un bordo a L) invece di un
   semplice quadrato pieno — tecnica standard per le checkbox custom,
   funziona su un input anche se in teoria gli elementi "replaced" non
   genererebbero pseudo-elementi: tutti i browser correnti fanno eccezione
   proprio per i checkbox. */
#optical-app .cf7-optical .wpcf7-acceptance label{
  display:flex; align-items:flex-start; gap:1rem; cursor:pointer;
  font-weight:300; color:rgba(10,10,11,.75); font-size:.92rem; line-height:1.6;
}
#optical-app .cf7-optical .wpcf7-acceptance input[type="checkbox"]{
  appearance:none; -webkit-appearance:none;
  width:22px; height:22px; flex:none; margin-top:.1rem;
  border:1.5px solid rgba(10,10,11,.35); background:var(--panna); position:relative;
  cursor:pointer; transition:border-color .3s ease, background-color .3s ease, box-shadow .3s ease;
}
#optical-app .cf7-optical .wpcf7-acceptance input[type="checkbox"]:hover{ border-color:var(--ottone); }
#optical-app .cf7-optical .wpcf7-acceptance input[type="checkbox"]::after{
  content:""; position:absolute; left:7px; top:3px;
  width:6px; height:11px;
  border:solid var(--panna); border-width:0 2px 2px 0;
  transform-origin:center; transform:rotate(45deg) scale(0);
  transition:transform .25s cubic-bezier(.65,0,.35,1);
}
#optical-app .cf7-optical .wpcf7-acceptance input[type="checkbox"]:checked{
  background:var(--ottone); border-color:var(--ottone);
  box-shadow:0 2px 10px -2px rgba(185,155,107,.6);
}
#optical-app .cf7-optical .wpcf7-acceptance input[type="checkbox"]:checked::after{ transform:rotate(45deg) scale(1) !important; }
#optical-app .cf7-optical .wpcf7-acceptance input[type="checkbox"]:focus-visible{
  outline:1px solid var(--ottone); outline-offset:4px;
}

/* ---- Bottone d'invio ----
   Resta un <input type="submit">, non un <button>: CF7 lo genera così di
   suo e un elemento "replaced" come questo non supporta ::before/::after in
   nessun browser (a differenza del checkbox sopra) — niente riempimento a
   tendina dal basso come .btn--dark, solo una dissolvenza di sfondo/testo.
   Se un domani serve l'identica animazione delle altre pagine, si può far
   scrivere a CF7 un <button> reale con un filtro PHP di poche righe: dimmelo
   e lo aggiungo. */
#optical-app .cf7-optical .submit-row{ margin-top:.5rem; }
#optical-app .cf7-optical input.wpcf7-submit{
  display:inline-flex; align-items:center; gap:.9rem; cursor:pointer;
  padding:1.05rem 2.4rem; font-size:.7rem; letter-spacing:.24em; text-transform:uppercase;
  font-family:inherit; border:1px solid rgba(10,10,11,.35); border-radius:0;
  color:var(--ink); background:transparent;
  transition:background-color .4s ease, color .4s ease, border-color .4s ease;
}
#optical-app .cf7-optical input.wpcf7-submit:hover{ background:var(--ink); color:var(--panna); border-color:var(--ink); }
#optical-app .cf7-optical input.wpcf7-submit[disabled]{ opacity:.5; cursor:not-allowed; }

/* ---- Esito invio (banner) ---- */
#optical-app .cf7-optical .wpcf7-response-output{
  margin:1.5rem 0 0 !important; padding:1rem 1.25rem !important;
  border:1px solid rgba(10,10,11,.2) !important; border-radius:0 !important;
  font-size:.85rem; font-weight:300; color:var(--ink);
}
#optical-app .cf7-optical .wpcf7-form.sent .wpcf7-response-output{ border-color:var(--ottone); }
#optical-app .cf7-optical .wpcf7-form.invalid .wpcf7-response-output,
#optical-app .cf7-optical .wpcf7-form.failed .wpcf7-response-output,
#optical-app .cf7-optical .wpcf7-form.aborted .wpcf7-response-output,
#optical-app .cf7-optical .wpcf7-form.spam .wpcf7-response-output{ border-color:#9c4a3c; color:#9c4a3c; }
