/* Styles the published bundle injected at runtime for the mobile menu.
   Captured from the rendered page so the open state matches the original. */
.framer-0GpIA.framer-1ndubck, .framer-0GpIA .framer-1ndubck { display: block; }
.framer-0GpIA.framer-1yih9un { place-content: flex-start; align-items: flex-start; display: flex; flex-flow: row; gap: 40px; height: min-content; overflow: hidden; padding: 20px 60px 20px 20px; position: relative; width: min-content; will-change: var(--framer-will-change-override, transform); }
.framer-0GpIA .framer-alfdrc, .framer-0GpIA .framer-1ma9rxe, .framer-0GpIA .framer-1lq3icz { place-content: flex-start; align-items: flex-start; display: flex; flex: 0 0 auto; flex-flow: column; gap: 16px; height: min-content; overflow: visible; padding: 0px; position: relative; width: min-content; }
.framer-0GpIA .framer-zdu4sk, .framer-0GpIA .framer-zs7gtf, .framer-0GpIA .framer-1litgjt, .framer-0GpIA .framer-s3v6fh, .framer-0GpIA .framer-1iw9r81, .framer-0GpIA .framer-1pa6kpy, .framer-0GpIA .framer-xti1gv, .framer-0GpIA .framer-1kkvwja, .framer-0GpIA .framer-6q0qan, .framer-0GpIA .framer-x1a7ct, .framer-0GpIA .framer-mtkwnj, .framer-0GpIA .framer-1ejy6ua, .framer-0GpIA .framer-1bfllwb, .framer-0GpIA .framer-1h2yyah { flex: 0 0 auto; height: auto; position: relative; white-space: pre; width: auto; }
.framer-0GpIA.framer-v-jn1cmh.framer-1yih9un { gap: 0px; padding: 20px; will-change: unset; }
.framer-0GpIA.framer-v-jn1cmh .framer-alfdrc { align-content: center; align-items: center; }
.framer-7qS2v .framer-styles-preset-1pd2mh1:not(.rich-text-wrapper), .framer-7qS2v .framer-styles-preset-1pd2mh1.rich-text-wrapper a { --framer-link-current-text-color: var(--token-c774dcb9-5728-45e2-a9f9-c03b0ad3798f, #000000); --framer-link-current-text-decoration: none; --framer-link-hover-text-color: var(--token-f829146a-a813-4023-8c8b-1e71ee7875ee, #035925); --framer-link-hover-text-decoration: none; --framer-link-text-color: var(--token-c774dcb9-5728-45e2-a9f9-c03b0ad3798f, #000000); --framer-link-text-decoration: none; transition: color 0.4s cubic-bezier(0.44, 0, 0.56, 1); }
.framer-EGJjV .framer-styles-preset-15i6j1i:not(.rich-text-wrapper), .framer-EGJjV .framer-styles-preset-15i6j1i.rich-text-wrapper a { --framer-link-current-text-color: var(--token-c774dcb9-5728-45e2-a9f9-c03b0ad3798f, #000000); --framer-link-current-text-decoration: none; --framer-link-hover-text-decoration: none; --framer-link-text-color: var(--token-c774dcb9-5728-45e2-a9f9-c03b0ad3798f, #000000); --framer-link-text-decoration: none; }
.framer-0GpIA[data-border="true"]::after, .framer-0GpIA [data-border="true"]::after { content: ""; border-width: var(--border-top-width, 0) var(--border-right-width, 0) var(--border-bottom-width, 0) var(--border-left-width, 0); border-color: var(--border-color, none); border-style: var(--border-style, none); width: 100%; height: 100%; position: absolute; box-sizing: border-box; left: 0px; top: 0px; border-radius: inherit; corner-shape: inherit; pointer-events: none; }


/* ---- richieste cliente, client pass ---------------------------------- */

/* The CTA buttons carried the brand mark beside the label, in both the
   resting and the hover state. Removed on request: the label carries it. */
.framer-t9x351,
.framer-1x7td5m { display: none !important; }

/* Agency credit. The slot held the previous agency's logo lockup; there is no
   equivalent asset for the new one, so the logo is hidden and the name is set
   as a wordmark instead, with the animated gradient the client asked for. */
.framer-1u5a8u6-container { display: none !important; }

.framer-t5owc6 p::after {
  content: 'Origine Digital Studio';
  font-family: 'Instrument Sans', 'Geist', system-ui, sans-serif;
  font-weight: 700;
  letter-spacing: 0.01em;
  /* Scala scurita: sul bianco del footer gli stop originali passavano per
     giallo #f5d000 (1.51:1), ciano #00b7d8 (2.40:1) e arancio #ff8a00
     (2.36:1) — ed e' un link, quindi la soglia e' 4.5:1. Ogni stop e' stato
     abbassato di luminosita' fino a superare 4.8:1 sul bianco mantenendo la
     tinta; il movimento e' identico. */
  background-image: linear-gradient(
    90deg,
    #e30045, #ab5c00, #847000, #1b824a,
    #007c93, #5a5afc, #9e43e3, #e30045
  );
  background-size: 400% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: elm-rainbow 8s linear infinite;
}

@keyframes elm-rainbow {
  from { background-position: 0% 50%; }
  to   { background-position: 400% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .framer-t5owc6 p::after { animation: none; background-position: 0% 50%; }
}


/* ---- contrasto del testo, correzioni WCAG ----------------------------
   Rapporti "prima" da qa/contrast-report.md e dalla rimisura sui pixel
   (maschera dei glifi, p10). Soglie: 4.5:1 testo normale, 3:1 testo grande.
   Si interviene solo sui fondi: nessun colore di testo viene riscritto. */

/* 1. Barra di navigazione fissa: non prendeva mai un fondo proprio.
      Le due varianti hanno polarita' opposta, quindi anche lo scrim ce l'ha:
        .framer-Ea3l8  (home, contatti)  link bianchi -> scrim scuro
                       misurato 1.00:1 sulle sezioni bianche, 4.05:1 sull'hero
        .framer-P2lqj  (pagine servizio) link scuri  -> scrim chiaro
                       misurato 1.96:1 sulle bande navy #213f65
      In cima alla pagina la barra resta "appoggiata" sull'hero (solo una
      velatura sfumata, dove serve); il fondo pieno compare allo scroll, con
      la classe elm-nav-scrolled applicata da site.js. Lo scrim sta su
      pseudo-elementi con z-index negativo per restare sotto logo e link. */
nav.framer-Ea3l8::before,
nav.framer-Ea3l8::after,
nav.framer-P2lqj::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  transition: opacity 0.25s linear;
}

/* velatura a riposo, solo sulla barra a link bianchi: sull'hero della home i
   link stavano a 4.05:1 e la CTA a 3.90:1 gia' a scroll 0. Le pagine servizio
   a scroll 0 sono sopra soglia, quindi non ricevono nulla. */
nav.framer-Ea3l8::before {
  background: linear-gradient(
    180deg,
    rgba(15, 17, 23, 0.45) 0%,
    rgba(15, 17, 23, 0.32) 70%,
    rgba(15, 17, 23, 0) 100%
  );
}

/* fondo pieno allo scroll */
nav.framer-Ea3l8::after {
  background: rgba(15, 17, 23, 0.8);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  opacity: 0;
}

nav.framer-P2lqj::after {
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  opacity: 0;
}

html.elm-nav-scrolled nav.framer-Ea3l8::before { opacity: 0; }
html.elm-nav-scrolled nav.framer-Ea3l8::after,
html.elm-nav-scrolled nav.framer-P2lqj::after { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  nav.framer-Ea3l8::before,
  nav.framer-Ea3l8::after,
  nav.framer-P2lqj::after { transition: none; }
}

/* 2. CTA della barra su home e contatti: pill di bianco al 20 % con testo
      bianco, misurata 1.09:1 sopra le sezioni chiare. Prende il pieno navy
      che la stessa CTA ha gia' sulle pagine servizio (variante "Variant 4").
      !important: il colore di fondo e' scritto nello style inline generato. */
nav.framer-Ea3l8 a.framer-v-1woht2t {
  background-color: var(--token-f829146a-a813-4023-8c8b-1e71ee7875ee, #213f65) !important;
}

/*    Stessa pill, stesso problema, sulle tre pagine servizio: la variante
      desktop della barra ha gia' il pieno navy, ma le varianti tablet e mobile
      restano al bianco 20 % con etichetta bianca, e allo scroll la barra prende
      il fondo bianco (nav.framer-P2lqj::after) — quindi la CTA sparisce del
      tutto. Le si da' lo stesso pieno della variante desktop, cosi' il bottone
      ha un colore solo su tutti e tre i breakpoint.
      !important: il colore di fondo e' scritto nello style inline generato. */
nav.framer-P2lqj a.framer-v-1woht2t {
  background-color: var(--token-f829146a-a813-4023-8c8b-1e71ee7875ee, #213f65) !important;
}

/* 3. Pill traslucide sopra le foto chiare, negli hero delle tre pagine
      servizio: fondo bianco al 20 % e testo bianco sopra calcestruzzo
      pallido. Misurate 1.43:1 (Finito), 1.46:1
      (Finiture comprese), 1.77:1 (Posato), 1.84:1 (Campione a casa tua),
      2.14:1 (3 mm), 2.25:1 (Cartongesso, Controsoffitti), 2.34:1 (Senza
      demolire), 2.99:1 (Misurato). Stesso componente, una regola sola: il
      fondo diventa scuro e il vetro smerigliato resta. Tocca anche la pill
      dell'hero contatti, che era gia' a posto (5.2:1) e resta sopra soglia.
      !important: fondo scritto nello style inline generato. */
[data-framer-name="Label With Inner Padding"] {
  background-color: rgba(15, 17, 23, 0.6) !important;
}

/* 4. Sezioni CTA di chiusura di superfici e ristrutturazione: titoli bianchi
      da 70 px sopra la foto di muro in finto mattone bianco. Misurati 2.21:1
      ("Vieni a toccare i campioni.") e 2.23:1 ("Vieni a vedere come viene."),
      corpo a 2.13:1 e 2.18:1. Lo strato "BG Color" gia' presente sopra la
      foto, e sotto al testo (z-index 1 contro 2), passa da nero al 25 % a un
      grigio antracite al 62 %: copre titolo, corpo, bottone e pill.
      !important: fondo scritto nello style inline generato. */
.framer-cq3c8f {
  background-color: rgba(15, 17, 23, 0.62) !important;
}

/* 5. Hero della home: tutto il blocco di testo bianco sta su una foto di
      cucina molto chiara. H1 2.50:1, occhiello 2.63:1, sottotitolo 2.11:1,
      link 2.43:1, check 2.78:1. Un solo scrim in gradiente orizzontale sopra
      la foto (dentro "BG Color", quindi sotto al testo): protegge la colonna
      di sinistra e lascia leggibile la foto sul lato della card. */
.framer-q5ok31::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    90deg,
    rgba(15, 17, 23, 0.66) 0%,
    rgba(15, 17, 23, 0.5) 55%,
    rgba(15, 17, 23, 0.16) 100%
  );
}

/* 6. "Due modi per iniziare" su ristrutturazione: le due card hanno gia' due
      strati sopra la foto — "BG Color" (nero piatto al 18 %) e "BG Color Blur"
      (una sfumatura *grigia* in basso, che sulle foto scure schiarisce invece
      di scurire). Titoli a 2.35:1 e 2.98:1, corpo a 3.87:1 e 4.11:1.
      Lo strato piatto diventa un gradiente verticale — il testo sta in basso —
      e la sfumatura grigia diventa neutra scura, senza toccarne la geometria
      ne' il blur. Le due card hanno classi diverse ma lo stesso nome di
      livello, quindi bastano due regole per entrambe. */
.framer-171gsxp [data-framer-name="BG Color"] {
  background-color: transparent;
  background-image: linear-gradient(
    180deg,
    rgba(15, 17, 23, 0.26) 0%,
    rgba(15, 17, 23, 0.6) 38%,
    rgba(15, 17, 23, 0.78) 100%
  );
}

.framer-171gsxp [data-framer-name="BG Color Blur"] {
  background-image: linear-gradient(
    180deg,
    rgba(15, 17, 23, 0) 0%,
    rgba(15, 17, 23, 0.3) 35%,
    rgba(15, 17, 23, 0.5) 100%
  );
}

/* The small brand marks beside eyebrows and inside buttons were the previous
   company's logomark. There is no ELM equivalent at that size - the only asset
   available is a favicon, which at 14px reads as a blob - so they are hidden
   rather than filled with something that looks wrong. Restore by deleting this
   rule once a proper monogram exists. */
.framer-17qqpn2,
.framer-aszvfg { display: none !important; }

/* Le due righe col segno di spunta sotto l'hero della home dicevano solo
   "[DA CONFERMARE: garanzia]" e "[DA CONFERMARE: assicurazione]": tolti i
   segnaposto (scripts/placeholders.py) restava la spunta senza etichetta.
   Si nasconde la riga, non la spunta, e solo dove il testo e' rimasto vuoto:
   le altre righe con lo stesso componente hanno la loro frase. La riga cambia
   classe a ogni breakpoint (framer-y3nfvi a desktop, framer-1hs97ab a mobile),
   quindi l'aggancio e' il contenitore piu' il testo vuoto, non la classe. */
.framer-42vayg > div:has(> [data-framer-name="Body"] > p:empty) {
  display: none !important;
}

/* Riga di cinque stelline nelle card recensione della home rimaste fuori dal
   passaggio a colonne (quelle senza il titolo "Cosa dicono i clienti"): erano
   cinque componenti Framer, non immagini, quindi senza il bundle restava una
   banda vuota da 278x16 sopra ogni citazione. */
.framer-1dlaeim { display: none !important; }

/* Stessa storia nella fascia dei bottoni sotto "Trascina e guarda cosa c'era
   prima" (home, superfici, ristrutturazione): un <div> vuoto da 735x60 di
   fianco alle due CTA, resto di un componente mai renderizzato. */
.framer-1vh9syh { display: none !important; }

/* Slot icona dentro il bottone "Altri lavori" (home, superfici,
   ristrutturazione). Era un componente Framer, non un'immagine: senza il
   bundle resta un <div style="display:contents"> vuoto dentro un box da
   21x21, cioe' un buco di 21px prima dell'etichetta. Nascosto su richiesta
   ("icone qui brutte, no need"), come gli altri slot icona dei bottoni. */
.framer-qkijw7-container { display: none !important; }

/* Hero eyebrow removed on request: it repeated what the headline already says
   and read as filler. The wrapper goes, not just the text, so no empty line
   remains above the title. */
.framer-85qji5 { display: none !important; }


/* ---- layout, secondo giro di feedback del cliente ---------------------- */

/* Footer, tutte e 6 le pagine. Le due meta' del footer si impilavano invece di
   stare affiancate. "Right Content Wrapper" e' width:min-content e la sua
   min-content la decidono le tre pill social: 239px l'una, perche' l'etichetta
   e' il segnaposto "[DA CONFERMARE: social]" al posto degli originali
   "YouTube" / "Instagram" / "Linkedin" (~100px). La meta' sinistra diventa
   cosi' 725px e con le colonne di link a 611-623px la riga non entra piu' nel
   contenitore da 1120-1280px. "Top Content Wrapper" impacchetta le righe
   mandate a capo con align-content:flex-start e senza row-gap, quindi le
   colonne finivano attaccate alla riga social (0px) e tutta la meta' destra
   del footer restava vuota. Misurato su tutte le pagine a 1440 e a 1011.
   ELM non ha profili social (reference/client-pass.md): le pill si tolgono,
   non si allargano. */
footer.framer-PQMxZ .framer-121tm6r { display: none !important; }

/* Tolte le pill, min-content scenderebbe ai 205px del logo e la frase di
   presentazione collasserebbe in una colonna strettissima. Alla meta' sinistra
   serve quindi una larghezza vera, che si stringa quando lo spazio cala.
   Non basta flex-shrink: in un contenitore flex-wrap l'a capo viene deciso
   sulla misura ipotetica dell'elemento, prima che lo shrink entri in gioco, e
   a 1011px la riga andava ancora a capo. Il tetto e' quindi calcolato sul
   contenitore, sottraendo la colonna di link (611-623px sulla variante
   desktop, 541-553px su quella tablet, piu' un margine); il pavimento a 205px
   e' la larghezza del logo, e tiene il calc lontano dai valori negativi.
   Solo le due varianti a riga: sotto i 901px il footer passa alla variante in
   colonna, che ha gia' i suoi 40px di gap. */
footer.framer-v-apbdjh .framer-k3y5yz {
  width: auto;
  max-width: max(205px, min(560px, calc(100% - 640px)));
}

footer.framer-v-b4z7s0 .framer-k3y5yz {
  width: auto;
  max-width: max(205px, min(560px, calc(100% - 580px)));
}

/* Rete di sicurezza: se un domani il testo torna a mandare a capo la riga, le
   due linee mantengono i 40px di ritmo che il footer usa gia' altrove, invece
   di toccarsi. */
footer.framer-PQMxZ .framer-1t8442h { row-gap: 40px; }

/* Lo slot logo "Primary" di fianco ai titoli delle sezioni prima/dopo (home,
   superfici, ristrutturazione) contiene una foto ritagliata: il passaggio
   immagini ha riempito uno slot da marchio con una foto di muro, e accanto a
   "Trascina e guarda cosa c'era prima." si legge come una miniatura capitata
   li' per caso. Nascosto invece che riempito: non esiste un marchio ELM a
   quella misura, stesso motivo di .framer-17qqpn2 qui sopra. */
.framer-16exgxa-container { display: none !important; }

/* Card recensione in home: 3 dei 12 blocchi autore hanno una "Author Image" e
   partono a 80px dal bordo card invece che a 24px come gli altri nove e come
   la citazione sopra di loro. Le foto sono muri e bagni - il passaggio
   immagini ha riempito degli slot da ritratto - e le recensioni sono contenuto
   demo dichiarato, quindi un ritratto finto e' peggio di nessun ritratto.
   Nascondendo lo slot tutti e 12 i blocchi autore tornano allineati a 24px. */
.framer-128nl9r { display: none !important; }

/* FAQ di superfici, ristrutturazione e serramenti: il "+" accanto a ogni
   domanda era il comando di apertura dell'accordion. Il comportamento stava
   nel bundle Framer rimosso; l'icona era stata nascosta perche' prometteva
   un'interazione che non c'era. Su richiesta del cliente l'accordion e' stato
   reimplementato (site.js), quindi il "+" torna e ruota di 45 gradi — cioe'
   diventa una "x" — sulla scheda aperta.

   Il collasso e' su height, con l'altezza misurata da site.js al momento del
   clic. La via senza JavaScript - grid-template-rows da 1fr a 0fr - qui non
   funziona: la risposta e' un flex item di altezza indefinita e l'unita' fr vi
   si risolve a zero, quindi la scheda restava chiusa anche da aperta (provato,
   0px a transizione finita). La scheda e' una flex column con row-gap 20px,
   che a scheda chiusa resterebbe appeso sotto al titolo, quindi anche il gap
   va a zero. Tutto e' dietro html.elm-faq-js, che site.js applica solo dopo
   aver agganciato gli handler: senza JavaScript le risposte restano aperte e
   leggibili come prima. */
html.elm-faq-js .framer-1yjti5f { cursor: pointer; }

html.elm-faq-js .framer-p68da {
  transition: row-gap 0.35s cubic-bezier(0.44, 0, 0.56, 1);
}

html.elm-faq-js .framer-p68da > [data-elm-faq-answer] {
  overflow: hidden;
  transition: height 0.35s cubic-bezier(0.44, 0, 0.56, 1);
}

html.elm-faq-js .framer-p68da:not(.elm-faq-open) { row-gap: 0; }

/* stato a riposo: site.js toglie l'altezza inline a transizione finita, quindi
   da chiusa la scheda torna qui e da aperta segue il contenuto */
html.elm-faq-js .framer-p68da:not(.elm-faq-open) > [data-elm-faq-answer] {
  height: 0;
}

html.elm-faq-js .framer-1nhrhfx {
  transition: transform 0.35s cubic-bezier(0.44, 0, 0.56, 1);
}

/* !important: l'icona ha transform:none nello style inline generato */
html.elm-faq-js .elm-faq-open .framer-1nhrhfx {
  transform: rotate(45deg) !important;
}

@media (prefers-reduced-motion: reduce) {
  html.elm-faq-js .framer-p68da,
  html.elm-faq-js .framer-p68da > [data-elm-faq-answer],
  html.elm-faq-js .framer-1nhrhfx { transition: none; }
}

/* Riga di pill dell'hero su superfici ("Senza fughe / A mano / Anche fuori"):
   rimossa su richiesta. Sta in una flex row a 1440 e in una flex column a 390,
   quindi display:none si porta via anche il gap e non lascia buchi. */
.framer-19mkeio { display: none !important; }

/* Stessa richiesta per la riga di pill dentro la "Bacgroung Card", ma solo su
   superfici: ristrutturazione usa lo stesso componente per una riga diversa e
   voluta ("Un referente / Preventivo chiaro / Chiavi in mano"), e le due
   pagine condividono ogni classe e ogni id. Il link canonical e' l'unico
   aggancio per pagina disponibile senza toccare il markup. Il contenitore e'
   una flex column con gap 70px: togliendo la riga sparisce anche il suo gap. */
html:has(head link[rel="canonical"][href="/servizi/superfici-decorative"]) .framer-1brdv31 {
  display: none !important;
}

/* Riga "Campioni / Colori / Preventivo" dentro la card blu della home
   ("Prima si tocca. Poi si sceglie."): tolta su richiesta. Serramenti usa lo
   stesso componente per una riga diversa e voluta ("Veniamo noi / Passa a
   vedere / Decidi tu") e condivide ogni classe, quindi l'aggancio e' il link
   canonical, come per la riga di superfici piu' sopra. */
html:has(head link[rel="canonical"][href="/"]) .framer-e40z3t {
  display: none !important;
}

/* Hero pill rows removed on request across the service pages: the client
   judged them noise ("TOGLILO"). Hiding the wrapper takes the flex gap with
   it, so nothing is left hanging above the heading. */
.framer-v57okf { display: none !important; }

/* ---- recensioni, componente inviato dal cliente -----------------------
   Il carosello orizzontale e' stato sostituito da colonne verticali che
   scorrono a velocita' diverse (scripts/testimonials.py genera il markup).
   Le card vecchie avevano cinque slot da stellina e un ritratto che erano
   componenti Framer, non immagini: senza il bundle restavano box vuoti - il
   "ancora rotto" del feedback. Qui non ci sono ne' stelline ne' ritratti,
   quindi non c'e' piu' niente da riempire.
   Misure e curve dal componente React ricevuto: gap 24px, card da 320px con
   padding 40px e raggio 24px, finestra alta 740px, sfumatura in dissolvenza
   sopra e sotto, colonne a 15/19/17 secondi. */
.elm-tst {
  display: flex;
  justify-content: center;
  gap: 24px;
  width: 100%;
  margin-top: 40px;
  max-height: 740px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 25%, #000 75%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 25%, #000 75%, transparent);
}

.elm-tst-col { flex: 0 1 320px; min-width: 0; }

/* la seconda e la terza colonna compaiono con lo spazio, come nel componente
   ("hidden md:block" e "hidden lg:block") */
.elm-tst-col-2, .elm-tst-col-3 { display: none; }
@media (min-width: 768px) { .elm-tst-col-2 { display: block; } }
@media (min-width: 1024px) { .elm-tst-col-3 { display: block; } }

.elm-tst-track {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding-bottom: 24px;
  will-change: transform;
  animation: elm-tst-scroll var(--elm-tst-duration, 15s) linear infinite;
}

/* il secondo giro di card e' identico al primo: a -50% la striscia e' tornata
   dov'era e il salto non si vede */
.elm-tst-loop {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding-top: 24px;
}

@keyframes elm-tst-scroll {
  from { transform: translateY(0); }
  to   { transform: translateY(-50%); }
}

/* Nessun effetto sull'hover: fermare la colonna e' stato provato e bocciato
   ("si blocca al hover"), e cambiare velocita' a meta' corsa e' il difetto
   segnalato sugli altri caroselli. Le colonne scorrono e basta. */

.elm-tst-card {
  margin: 0;
  padding: 40px;
  border-radius: 24px;
  border: 1px solid rgba(15, 17, 23, 0.1);
  background: #fff;
  box-shadow: 0 10px 15px -3px rgba(33, 63, 101, 0.1),
              0 4px 6px -4px rgba(33, 63, 101, 0.1);
  font-family: 'Instrument Sans', 'Geist', system-ui, sans-serif;
}

.elm-tst-quote {
  margin: 0;
  font-size: 16px;
  line-height: 1.55;
  letter-spacing: -0.1px;
  color: var(--token-c774dcb9-5728-45e2-a9f9-c03b0ad3798f, #000);
}

.elm-tst-author {
  display: flex;
  flex-direction: column;
  margin-top: 20px;
}

.elm-tst-name {
  font-weight: 500;
  font-size: 16px;
  line-height: 20px;
  letter-spacing: -0.2px;
  color: var(--token-f829146a-a813-4023-8c8b-1e71ee7875ee, #213f65);
}

.elm-tst-role {
  font-size: 15px;
  line-height: 20px;
  letter-spacing: -0.2px;
  opacity: 0.6;
}

@media (max-width: 767.98px) {
  .elm-tst-card { padding: 28px; }
  .elm-tst { max-height: 620px; }
}

/* senza movimento la finestra diventa una colonna di card leggibili invece di
   una striscia tagliata a meta' */
@media (prefers-reduced-motion: reduce) {
  .elm-tst-track { animation: none; }
  .elm-tst {
    max-height: none;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .elm-tst-loop { display: none; }
}

/* ---- cursore magnetico sui titoli, componente inviato dal cliente ------
   Passando sopra un titolo si apre un cerchio pieno che segue il mouse e
   dentro cui lo stesso testo e' a colori invertiti. Il componente React
   originale mostrava una parola diversa dentro il cerchio; qui il testo e'
   lo stesso - i titoli sono contenuto, non un'insegna, e cambiarli sotto il
   mouse renderebbe la pagina illeggibile.
   L'aggancio e' in site.js e solo su h1 e titoli grandi: sotto i 28px la
   pallina da 150px coprirebbe l'intera riga. */
.elm-mag { position: relative; cursor: none; }

.elm-mag-circle {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  border-radius: 50%;
  overflow: hidden;
  pointer-events: none;
  background: var(--elm-mag-fg, currentColor);
  will-change: transform, width, height;
  transition: width 0.5s cubic-bezier(0.33, 1, 0.68, 1),
              height 0.5s cubic-bezier(0.33, 1, 0.68, 1);
}

.elm-mag.elm-mag-on .elm-mag-circle {
  width: var(--elm-mag-size, 150px);
  height: var(--elm-mag-size, 150px);
}

/* la copia del testo e' grande quanto il titolo e si sposta all'opposto del
   cerchio: cosi' resta incollata al testo sotto e il cerchio la ritaglia */
.elm-mag-copy {
  position: absolute;
  top: 50%;
  left: 50%;
  will-change: transform;
}

/* la copia clona gli span del titolo, che portano il colore nello style
   inline: va riscritto su tutto il sottoalbero */
.elm-mag-copy,
.elm-mag-copy * {
  color: var(--elm-mag-bg, #fff) !important;
  -webkit-text-fill-color: var(--elm-mag-bg, #fff) !important;
}

@media (prefers-reduced-motion: reduce) {
  .elm-mag-circle { transition: none; }
}

/* ---- menu flottante, componente inviato dal cliente -------------------
   Pillola gialla fissa in basso al centro: al clic si allarga, un cerchio
   scuro sale dal fondo a riempirla e le voci compaiono una dopo l'altra.
   Passando su una voce le lettere ruotano su se stesse, sfalsate di 30ms.
   Misure e curve sono quelle del componente React ricevuto; font e colori no:
   il giallo #FFE862 e il grigio #242424 sono stati sostituiti dalla coppia
   della pagina - navy #213f65 e bianco - e il font e' quello del sito.
   L'inversione del componente resta: chiusa e' navy con etichetta bianca
   (9.4:1), aperta il cerchio bianco sale e le voci diventano navy su bianco
   (9.4:1), con il bordo navy che la stacca dalla pagina.
   Si aggiunge alla barra in alto, non la sostituisce: quella porta il logo e
   la CTA del preventivo. Il markup lo inietta site.js. */
.elm-fm {
  position: fixed;
  bottom: 40px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  font-family: 'Instrument Sans', 'Geist', system-ui, sans-serif;
  letter-spacing: -0.02em;
}

.elm-fm-shell {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  width: 150px;
  height: 48px;
  border-radius: 72px;
  cursor: pointer;
  transition: width 0.8s cubic-bezier(0.22, 1, 0.36, 1),
              height 0.15s cubic-bezier(0.22, 1, 0.36, 1),
              border-radius 0.8s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}

.elm-fm-shell:hover { transform: scale(1.05); }

/* La pillola resta ferma in basso per tutta la pagina: la dissolvenza allo
   scroll e' stata provata e tolta su richiesta ("tieni fisso il menu"). */

.elm-fm-open .elm-fm-shell {
  width: 320px;
  height: 292px;
  border-radius: 32px;
  cursor: default;
  transform: none;
  transition: width 0.8s cubic-bezier(0.22, 1, 0.36, 1),
              height 0.8s cubic-bezier(0.22, 1, 0.36, 1),
              border-radius 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}

.elm-fm-bg {
  position: absolute;
  inset: 0;
  border: 1px solid var(--token-f829146a-a813-4023-8c8b-1e71ee7875ee, #213f65);
  border-radius: inherit;
  background: var(--token-f829146a-a813-4023-8c8b-1e71ee7875ee, #213f65);
  transition: border-color 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

/* il cerchio scuro parte sotto la pillola e sale a riempirla */
.elm-fm-circle {
  position: absolute;
  left: 50%;
  bottom: -200%;
  width: 200%;
  height: 200%;
  border-radius: 50%;
  background: #fff;
  transform: translateX(-50%);
  transition: bottom 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}

.elm-fm-open .elm-fm-circle { bottom: -20%; transition-delay: 0.1s; }

.elm-fm-items {
  position: relative;
  z-index: 1;
  display: flex;
  flex: 0;
  flex-direction: column;
  gap: 24px;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.elm-fm-open .elm-fm-items { flex: 1; opacity: 1; pointer-events: auto; }

.elm-fm-item {
  display: flex;
  height: 1em;
  overflow: hidden;
  color: var(--token-f829146a-a813-4023-8c8b-1e71ee7875ee, #213f65);
  font-size: 20px;
  line-height: 1;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

/* le voci entrano scalate, come nel componente: 0.4s di attesa piu' 80ms per
   posizione */
.elm-fm-open .elm-fm-item {
  opacity: 1;
  transition-delay: calc(0.4s + var(--elm-fm-i, 0) * 0.08s);
}

.elm-fm-char { display: inline-block; height: 1em; overflow: hidden; }

.elm-fm-roll {
  display: flex;
  flex-direction: column;
  transform: translateY(0);
  /* uscendo si torna su di colpo: rifare la rotazione a ritroso, sfalsata,
     si legge come un errore */
  transition: transform 0s;
}

.elm-fm-item:hover .elm-fm-roll,
.elm-fm-item:focus-visible .elm-fm-roll {
  transform: translateY(-50%);
  transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(var(--elm-fm-c, 0) * 30ms);
}

.elm-fm-roll > span { display: block; height: 1em; line-height: 1em; }

.elm-fm-bar {
  position: relative;
  z-index: 1;
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 48px;
  padding: 0 20px;
  border: 0;
  background: none;
  font: inherit;
  color: #fff;
  cursor: pointer;
  transition: padding 0.8s cubic-bezier(0.22, 1, 0.36, 1),
              color 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.elm-fm-open .elm-fm-bar {
  padding: 0 24px 24px;
  color: var(--token-f829146a-a813-4023-8c8b-1e71ee7875ee, #213f65);
}

.elm-fm-label { font-size: 20px; line-height: 1; }

.elm-fm-burger {
  position: relative;
  width: 24px;
  height: 24px;
}

.elm-fm-burger span {
  position: absolute;
  top: 50%;
  left: 3px;
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 999px;
  background: currentColor;
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.elm-fm-burger span:first-child { transform: translateY(-4px); }
.elm-fm-burger span:last-child  { transform: translateY(2px); }

.elm-fm-open .elm-fm-burger span:first-child { transform: translateY(-1px) rotate(45deg); }
.elm-fm-open .elm-fm-burger span:last-child  { transform: translateY(-1px) rotate(-45deg); }

@media (max-width: 479.98px) {
  .elm-fm { bottom: 24px; }
  .elm-fm-open .elm-fm-shell { width: 300px; }
}

@media (prefers-reduced-motion: reduce) {
  .elm-fm, .elm-fm-shell, .elm-fm-bg, .elm-fm-circle, .elm-fm-items,
  .elm-fm-item, .elm-fm-roll, .elm-fm-bar, .elm-fm-burger span {
    transition: none;
  }
  .elm-fm-shell:hover { transform: none; }
}

/* Hamburger della barra in alto: era il comando del vecchio menu mobile, che
   il menu flottante ha sostituito. Compare solo sotto i 992px - piu' su la
   barra mostra i link per esteso - quindi la regola non ha bisogno di media
   query: sopra quella soglia i due elementi non vengono nemmeno disegnati.
   Il logo e la CTA restano dove sono. Il pannello resta in site.js: per
   riaverlo basta togliere questa regola. */
.framer-ziwl7k,
.framer-1j03o30 { display: none !important; }

/* Framer emitted `width: 1fr` for these grid children, which is not valid CSS
   outside grid-template properties, so the browser drops it. The same rule also
   sets `flex: none`, killing the flex-grow the base rule relied on, so the cards
   fell back to their 1px base width: 473px columns holding 1px cards, text
   wrapping one character per line, a 10530px tall grid. The runtime used to
   paper over this with inline styles. Measured before: card 1x3494px.
   Scoped to the breakpoint where the parent becomes a grid. */
@media (min-width: 992px) and (max-width: 1279.98px) {
.framer-oagWr .framer-1bhbpc0,
.framer-oagWr .framer-1q1l318,
.framer-oagWr .framer-1wlu987,
.framer-oagWr .framer-smlco9,
.framer-oagWr .framer-sr1vng { width: 100% !important; }
}

/* The service-page hero sits in a full-height column pinned to the right, so
   the slot is always tall and narrow (0.47 to 0.84 depending on width). The
   photo there was nearly square and framed at object-position 98.1%, so as the
   window narrowed only a sliver of its right edge stayed visible and the rest
   read as a white gap. Replaced with a portrait image and re-centred. */
.framer-1swtcsa img { object-position: center !important; }

/* Hero eyebrows removed on request ("INFISSI E PORTE · TORINO",
   "Ristrutturazione a Torino"): they restated the page title in caps and read
   as filler. Same treatment already applied to the home eyebrow. The pill
   wrapper goes, not just its text, so no empty chip is left above the heading. */
.framer-1gsrm7q-container,
.framer-yy204y-container { display: none !important; }

/* Pill row over the serramenti hero photo ("Misuriamo / Montiamo / Puliamo"):
   removed on request. Same call the client made for the pill rows on the other
   service pages. Hiding the row takes its flex gap with it. */
.framer-1pt7hr6 { display: none !important; }

/* Riga "Veniamo noi / Passa a vedere / Decidi tu" nella card blu di chiusura
   su serramenti: tolta su richiesta del cliente. La home usa lo stesso
   componente e le stesse classi, e la sua riga e' gia' stata rimossa a parte,
   quindi l'aggancio e' il link canonical come per le altre righe di pill. */
html:has(head link[rel="canonical"][href="/servizi/serramenti"]) .framer-sbsl8e {
  display: none !important;
}
