/* ═══════════════════════════════════════════════════════════════════════
   DigiBite Render — kiosk demo, monitor touch 75"

   Polo estetico: GALLERY SCURO sull'ink DigiBite. Il fondo si ritira nel
   quasi-nero di brand, l'immagine è l'unica fonte di luce — come in un museo.
   Regge la luce variabile di uno showroom, dove un fondo chiaro su 75"
   abbaglia e appiattisce le foto.

   Brand — FONTE UNICA: skill `.claude/skills/digibite-brand-guidelines`
   (palette, loghi, font Sansation). Gli asset sono COPIATI in public/assets/
   perché l'app deployata deve essere autonoma: si aggiornano dalla skill,
   mai a mano qui (vedi public/assets/README.md).

   Grammatica (workspace /lp-reference):
   · spigoli vivi: border-radius 0 sui rettangoli, 50% sui cerchi, nulla in mezzo
   · un solo accento — il verde DigiBite — su ~2% di superficie; sul nero illumina
   · tracking solo sotto i 20px, un unico valore per sistema
   · interlinea corpo ≥1.7 contro titoli ≤1.15
   · su schermo grande scala il TIPO, non il vuoto

   Scala: tutte le misure portanti sono fluide (clamp + vw) perché lo stesso
   file serve il 75" dello showroom (1080p o 4K) e il portatile in demo.

   Contrasto: i rapporti WCAG annotati sui token sono MISURATI
   (_verifica-brand/contrasto.mjs), non stimati a occhio. Soglia: nessun testo
   sotto 4.5:1 sul fondale più chiaro su cui può comparire (--panel-2).
   ═══════════════════════════════════════════════════════════════════════ */

/* Sansation — font di brand, locale (public/assets/fonts/, copia della skill).
   Solo titoli e display; il corpo usa il font di sistema, così il kiosk non
   dipende da nessun servizio esterno (niente Google Fonts). */
@font-face{font-family:"Sansation";src:url("../assets/fonts/Sansation-Regular.ttf") format("truetype");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Sansation";src:url("../assets/fonts/Sansation-Bold.ttf") format("truetype");font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:"Sansation";src:url("../assets/fonts/Sansation-Italic.ttf") format("truetype");font-weight:400;font-style:italic;font-display:swap}

:root{
  /* Fondali — derivati dall'ink di brand #1d1d1b, un gradino più chiaro a ogni livello */
  --void:#1d1d1b;       /* ink DigiBite: fondo pagina */
  --void-2:#222220;
  --panel:#292927;
  --panel-2:#31312e;    /* il fondale più chiaro: caso peggiore per ogni contrasto annotato */

  /* Inchiostri su scuro — rapporto su --panel-2 / su --void */
  --ink:#f5f7ee;        /* mist di brand come testo principale: 12.07 / 15.61 */
  --ink-2:#d2d6cb;      /* 8.84 / 11.43 */
  --muted:#a6adaa;      /* slate #565f5f schiarito fino a leggersi: 5.70 / 7.38 */
  --faint:#969d9b;      /* suggerimenti, segnaposto, disabilitati: 4.72 / 6.10 */

  /* Accento unico: verde DigiBite. I nomi --brass* restano per non toccare
     app.js e ambiti.css; --accent* sono alias con lo stesso valore. */
  --brass:#a4c631;      /* verde primario; come testo: 6.65 su --panel-2, 8.60 su --void */
  --brass-2:#c3dc62;    /* verde chiaro per testo e stati attivi su scuro: 8.53 / 11.04 */
  --brass-deep:#7e9c1f; /* verde scuro di brand: SOLO riempimenti (hover dei bottoni pieni,
                           con testo ink sopra: 5.36). Come testo su --panel-2 farebbe 4.14. */
  --brass-dim:rgba(164,198,49,.16);
  --on-accent:#1d1d1b;  /* testo su verde: 8.60 su --brass, 5.36 su --brass-deep */
  --accent:var(--brass); --accent-2:var(--brass-2); --accent-deep:var(--brass-deep); --accent-dim:var(--brass-dim);
  --mist:#f5f7ee;       /* superficie chiara di brand; testo ink sopra: 15.61 */

  --line:rgba(245,247,238,.12);
  --line-2:rgba(245,247,238,.22);

  --shadow:0 40px 120px rgba(0,0,0,.65);
  --glow:0 0 0 1px var(--brass-dim), 0 30px 80px rgba(164,198,49,.10);

  /* Font: Sansation per titoli e display, sistema per il corpo */
  --font-display:"Sansation","Segoe UI",system-ui,sans-serif;
  --font-body:system-ui,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;

  /* Tipo fluido — riferimento 1920px, cresce fino al 4K */
  --t-hero:clamp(52px, 5.6vw, 132px);
  --t-h2:clamp(34px, 3.1vw, 74px);
  --t-h3:clamp(20px, 1.35vw, 32px);
  --t-lede:clamp(19px, 1.25vw, 30px);
  --t-body:clamp(16px, .95vw, 23px);
  --t-small:clamp(13px, .72vw, 18px);
  --t-micro:clamp(11px, .58vw, 15px);

  /* Ritmo: 120px con sottrazione del margine card (120−30=90) */
  --pad-x:clamp(32px, 3.6vw, 92px);
  --pad-y:clamp(24px, 2.2vw, 56px);
  --gap:clamp(16px, 1.3vw, 32px);

  --tap:clamp(64px, 4.6vw, 104px);   /* altezza minima dei bersagli touch */
  --tap-s:clamp(52px, 3.4vw, 96px);  /* bersagli della barra in alto */
  --pg:clamp(56px, 3.6vw, 96px);     /* gutter con le frecce di pagina del catalogo */
  --dot:clamp(22px, 1.45vw, 56px);   /* pallino numerato dei passi */
  /* La barra dei passi ha un suo tipo: --t-micro si ferma a 15px e sul 75"
     a 4K le etichette dei passi sarebbero illeggibili a tre metri. */
  --t-step:clamp(12px, .72vw, 28px);
  --ease:cubic-bezier(.16,.84,.36,1);
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{height:100%;margin:0}

/* L'attributo `hidden` vale display:none solo per il foglio di stile del
   browser: qualsiasi regola di classe con un `display` esplicito lo batte per
   specificità. Senza questa riga l'overlay di generazione (display:grid) non
   si toglierebbe MAI dal render finito. Il JS usa `hidden`: qui lo si rende
   vincolante una volta per tutte. */
[hidden]{display:none !important}

/* Niente scrollbar sul totem. Le schermate sono disegnate per stare nel
   campo visivo (catalogo a pagine, colonne ad altezza piena, azioni
   ancorate); dove un contenitore dovesse comunque eccedere — rete di
   sicurezza — il dito lo fa scorrere, ma nessuna barra compare. In finestra
   (html:not(.kiosk)) le barre restano: lì c'è un mouse. */
html.kiosk *{scrollbar-width:none}
html.kiosk *::-webkit-scrollbar{display:none;width:0;height:0}
/* Il viewport lascia lo zoom all'utente (accessibilità sul telefono); sul
   totem il pizzico non deve ingrandire la pagina: pan-x pan-y ammette la
   panoramica dei contenitori di sicurezza e nega solo il pinch-zoom. */
html.kiosk body{touch-action:pan-x pan-y}
body{
  background:var(--void); color:var(--ink);
  font-family:var(--font-body);
  font-size:var(--t-body); font-weight:400; line-height:1.75;
  overflow:hidden; user-select:none;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
button,a.ghost{font:inherit;cursor:pointer}

/* Il kiosk non ha tastiera, ma il focus visibile resta: serve in demo da
   portatile e all'accessibilità. Non si cancella l'outline, si ridisegna. */
:focus-visible{outline:2px solid var(--brass);outline-offset:3px}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-delay:0s !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}
}

#app{height:100dvh;display:flex;flex-direction:column;overflow:hidden}

/* ═══ Barra: marchio · avanzamento · comandi ═══════════════════════════
   UNA sola barra per tutte le schermate (niente più variante sottile per le
   fasi interne). Tre zone in griglia — marchio a sinistra, comandi a destra,
   i quattro passi in mezzo — così i nodi restano centrati sullo SCHERMO e non
   sullo spazio che avanza: cambiando schermata il passo attivo non si sposta
   di un pixel, ed è l'informazione che il visitatore cerca per prima. */
.topbar{
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  gap:var(--gap);
  padding:clamp(10px,.85vw,20px) var(--pad-x) clamp(6px,.5vw,12px);
  border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,rgba(29,29,27,.96),rgba(29,29,27,.72));
  backdrop-filter:blur(14px);
  position:relative;z-index:40;flex:0 0 auto;
}
.topbar .mark{height:clamp(30px,2.1vw,80px);width:auto;opacity:.96}
.tools{display:flex;align-items:center;gap:clamp(8px,.7vw,16px);justify-self:end}

/* Durante la generazione la navigazione è ferma: si dice con l'aspetto, non
   solo rifiutando i tocchi. "Ricomincia" resta acceso — è la via d'uscita. */
body.generando .progress{opacity:.35;transition:opacity .3s var(--ease)}

/* ── Avanzamento: quattro nodi numerati ────────────────────────────────
   Colonne di uguale larghezza: i pallini restano equidistanti qualunque sia
   la lunghezza delle etichette tradotte, e il filo che li unisce ha sempre
   la stessa misura (lo disegna ogni nodo verso il precedente). */
.progress{
  justify-self:center;align-self:stretch;
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  width:clamp(400px,40vw,1040px);
}
.node{
  position:relative;
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
  gap:clamp(6px,.5vw,11px);
  padding:0 clamp(4px,.4vw,10px) clamp(9px,.75vw,17px);
  background:none;border:0;color:var(--faint);
  font-size:var(--t-step);letter-spacing:.2em;text-transform:uppercase;line-height:1;
  transition:color .4s var(--ease);
  pointer-events:none;                 /* si toccano solo i passi già percorsi */
}
.node .dot{
  width:var(--dot);height:var(--dot);border-radius:50%;
  display:grid;place-items:center;
  border:1px solid currentColor;
  font-size:calc(var(--t-step) * 1.02);letter-spacing:0;
  transition:.4s var(--ease);
}
.node .lb{position:relative;white-space:nowrap}
/* Il filo va dal pallino precedente a questo: mezza colonna a sinistra (le
   colonne sono uguali) meno il raggio dei due pallini e l'aria attorno. */
.node + .node::before{
  content:'';position:absolute;height:1px;background:var(--line-2);
  top:calc(var(--dot) / 2);
  left:calc(-50% + var(--dot) / 2 + clamp(9px,.75vw,18px));
  right:calc(50% + var(--dot) / 2 + clamp(9px,.75vw,18px));
}
.node.done{color:var(--muted);cursor:pointer;pointer-events:auto}
.node.done:hover{color:var(--ink)}
.node.done .dot{color:var(--ink-2)}
.node.now{color:var(--brass)}
.node.now .dot{border-color:var(--brass);color:var(--brass)}
/* Sottolineatura del passo in corso: larga quanto la sua etichetta e
   appoggiata al filetto della barra (il nodo è alto quanto la barra). */
.node.now .lb::after{
  content:'';position:absolute;left:-.45em;right:-.45em;
  bottom:calc(-1 * clamp(9px,.75vw,17px));
  height:2px;background:var(--brass);
}
/* Finestra stretta (demo dal portatile): i quattro nodi non ci stanno più. */
@media(max-width:1000px){.progress{display:none}}

/* ── Menu lingua: tendina compatta ─────────────────────────────────────
   Un pulsante con la sigla corrente; il tocco apre l'elenco delle lingue,
   ciascuna col proprio nome. Costruito da app.js (initLangMenu). */
.lang-menu{position:relative;flex:0 0 auto}
.lang-cur{
  display:inline-flex;align-items:center;gap:8px;
  height:var(--tap-s);padding:0 clamp(14px,1.1vw,24px);
  background:transparent;border:1px solid var(--line-2);color:var(--ink-2);
  font:inherit;font-size:var(--t-small);letter-spacing:.14em;border-radius:0;
  transition:.3s var(--ease);
}
.lang-cur svg{width:1em;height:1em;transition:transform .3s var(--ease)}
.lang-cur:hover,.lang-cur[aria-expanded="true"]{border-color:var(--brass);color:var(--brass-2)}
.lang-cur[aria-expanded="true"] svg{transform:rotate(180deg)}
.lang-list{
  position:absolute;top:calc(100% + 6px);right:0;z-index:70;
  margin:0;padding:0;list-style:none;min-width:clamp(190px,12vw,270px);
  background:var(--panel);border:1px solid var(--line-2);box-shadow:var(--shadow);
  animation:rise .25s var(--ease) both;
}
.lang-list li{
  display:flex;align-items:center;gap:clamp(12px,.9vw,18px);
  min-height:var(--tap-s);padding:0 clamp(16px,1.2vw,24px);
  color:var(--ink-2);font-size:var(--t-small);cursor:pointer;
  border-top:1px solid var(--line);white-space:nowrap;
}
.lang-list li:first-child{border-top:0}
.lang-list li b{font-weight:500;letter-spacing:.14em;font-size:var(--t-micro);color:var(--muted);min-width:2.4em}
.lang-list li:hover{background:var(--panel-2);color:var(--ink)}
.lang-list li[aria-selected="true"]{color:var(--brass-2)}
.lang-list li[aria-selected="true"] b{color:var(--brass)}

.icon-btn{
  width:var(--tap-s);height:var(--tap-s);flex:0 0 auto;
  display:grid;place-items:center;
  background:transparent;border:1px solid var(--line-2);color:var(--ink-2);
  transition:.3s var(--ease);
}
.icon-btn:hover{border-color:var(--brass);color:var(--brass-2)}
.icon-btn svg{width:44%;height:44%}
/* Sulla home «Indietro» non ha dove tornare: resta al suo posto, spento. */
.icon-btn:disabled{opacity:.32;pointer-events:none}

/* ═══ Palco ════════════════════════════════════════════════════════════ */
.stage{flex:1;position:relative;min-height:0}
.screen{
  position:absolute;inset:0;
  display:none;flex-direction:column;
  padding:clamp(28px,2.6vw,72px) var(--pad-x) var(--pad-y);
  overflow:hidden;
}
.screen.active{display:flex;animation:rise .7s var(--ease) both}
@keyframes rise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}

.screen-head{flex:0 0 auto;margin-bottom:clamp(20px,1.9vw,44px)}
.screen-head.row{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--gap)}

h1,h2{
  font-family:var(--font-display);
  font-weight:300;line-height:1.06;margin:0;
  letter-spacing:-.005em;
}
h1{font-size:var(--t-hero)}
h2{font-size:var(--t-h2)}
h1 em,h2 em{font-style:italic;color:var(--brass-2)}

.eyebrow{
  margin:0 0 clamp(14px,1.1vw,26px);
  font-size:var(--t-micro);letter-spacing:.3em;text-transform:uppercase;
  color:var(--brass);font-weight:400;
}
.sub{margin:clamp(10px,.8vw,18px) 0 0;color:var(--muted);font-size:var(--t-body);max-width:52ch}
.lede{margin:clamp(18px,1.5vw,34px) 0 0;color:var(--ink-2);font-size:var(--t-lede);line-height:1.62}
.hint{margin:clamp(20px,1.6vw,36px) 0 0;color:var(--faint);font-size:var(--t-small)}
.hint em,.lasso-hint em{font-style:normal;color:var(--brass);font-weight:400}

/* ═══ 1 · Home: titolo + tre strade ════════════════════════════════════
   L'invito e la scelta della sorgente sono la STESSA schermata: il titolo
   accoglie, le tre tessere partono. Le tessere hanno la medesima struttura —
   vetrina in alto, testo, bottone in fondo — così i tre bottoni cadono sulla
   stessa riga e la scelta si legge in un colpo d'occhio da tre metri. */
.home-head{flex:0 0 auto;text-align:center;margin-bottom:clamp(18px,1.7vw,44px)}
/* Il titolo divide lo spazio con le tessere: un gradino sotto l'hero della
   vecchia copertina, che aveva la schermata tutta per sé. */
.home-head h1{font-size:clamp(30px,3.5vw,84px);line-height:1.1}
.home-head h1 em{font-style:normal;color:var(--brass)}
.home-sub{
  margin:clamp(10px,.8vw,20px) auto 0;max-width:64ch;
  color:var(--muted);font-size:var(--t-lede);line-height:1.5;
}

.ways{
  flex:1;min-height:0;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(14px,1.4vw,34px);
}
.way{
  position:relative;overflow:hidden;min-width:0;
  display:flex;flex-direction:column;align-items:center;text-align:center;
  padding:clamp(18px,1.6vw,42px);
  background:var(--panel);border:1px solid var(--line-2);border-radius:0;
  color:var(--ink);font:inherit;
  transition:.35s var(--ease);
}
.way:hover{border-color:var(--brass);background:var(--panel-2)}
.way:active{transform:scale(.995)}
.way-t{
  font-family:var(--font-display);font-weight:300;
  font-size:clamp(25px,2.45vw,58px);line-height:1.1;color:var(--ink);
}
.way-s{margin-top:clamp(6px,.5vw,13px);color:var(--ink-2);font-size:var(--t-body);line-height:1.45}
.way-note{
  margin:clamp(12px,1.1vw,26px) auto 0;max-width:30ch;
  color:var(--muted);font-size:var(--t-body);line-height:1.45;
}
.way .eyebrow{margin:0 0 clamp(7px,.55vw,14px)}
/* Il bottone è l'ultima cosa della tessera: nelle due tessere con icona lo
   spinge in fondo la vetrina (che si prende lo spazio che avanza), in quella
   degli ambienti il margine qui sotto — ed è lo stesso stacco in tutte e tre,
   così i tre bottoni cadono sulla stessa riga. */
.way .cta{
  margin-top:clamp(20px,1.9vw,44px);width:100%;justify-content:center;
  text-transform:uppercase;letter-spacing:.12em;font-size:var(--t-small);
}
.way:hover .cta{background:var(--brass-deep)}
/* La vetrina prende lo spazio che avanza: le icone crescono col monitor. */
.way-icon{
  flex:1 1 auto;min-height:0;width:100%;
  display:flex;align-items:center;justify-content:center;
  padding:clamp(10px,1vw,26px) 0 clamp(14px,1.3vw,32px);
  color:var(--brass);
}
.way-icon svg{max-height:100%;max-width:100%}
.way-qr .way-icon svg{width:clamp(96px,7.4vw,240px);height:auto}
.way-say .way-icon svg{width:100%;height:auto}

/* Tessera degli ambienti: una vetrina, non un riquadro con un'icona. Le foto
   si dissolvono l'una nell'altra con una lenta deriva (il movimento vive
   nell'immagine, non nell'interfaccia — era lo sfondo della copertina) e il
   testo sta in basso, su un velo che gli garantisce il contrasto qualunque
   sia la foto sotto. */
.way-env{padding:0;justify-content:flex-end;text-align:left}
.way-bg{position:absolute;inset:0;overflow:hidden;background:var(--void-2)}
.way-bg .slide{
  position:absolute;inset:0;
  background-size:cover;background-position:center;
  opacity:0;transform:scale(1.06);
  transition:opacity 2.4s var(--ease);
  will-change:opacity,transform;
}
.way-bg .slide.on{opacity:1;animation:drift 14s linear both}
@keyframes drift{from{transform:scale(1.04)}to{transform:scale(1.14)}}
/* Il velo è tarato sulla foto PIÙ CHIARA del ciclo: sulle scene bianche il
   testo in basso deve reggere il contrasto come su quelle scure. */
.way-veil{
  position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(29,29,27,.18) 0%,rgba(29,29,27,.62) 40%,rgba(29,29,27,.96) 100%);
}
.way-body{
  position:relative;z-index:2;width:100%;
  display:flex;flex-direction:column;align-items:flex-start;
  padding:clamp(18px,1.6vw,42px);
}

/* ═══ Bottoni ══════════════════════════════════════════════════════════ */
.cta{
  display:inline-flex;align-items:center;gap:16px;
  min-height:var(--tap);padding:0 clamp(28px,2.2vw,52px);
  background:var(--brass);color:var(--on-accent);border:0;border-radius:0;
  font-size:var(--t-body);font-weight:500;letter-spacing:.02em;
  transition:.3s var(--ease);
}
.cta svg{width:1.25em;height:1.25em;transition:transform .3s var(--ease)}
.cta:hover{background:var(--brass-deep)}
.cta:hover svg{transform:translateX(6px)}
.cta:active{transform:scale(.985)}
.cta:disabled{background:var(--panel-2);color:var(--faint);pointer-events:none}
.cta.wide,.ghost.wide{width:100%;justify-content:center}
/* Solo collaudo: il caricamento da PC sotto il QR, come un tasto secondario. */
.dev-upload{margin-top:clamp(10px,.9vw,20px);cursor:pointer;max-width:520px}
/* «Scegli dal catalogo» mentre la foto si sta ancora leggendo: spento, con il
   filo verde che batte — non è un tasto morto, sta aspettando. */
.cta.reading{background:var(--panel-2);color:var(--ink-2)}
.cta.reading::before{content:"";width:9px;height:9px;border-radius:50%;background:var(--brass);animation:beat 1.6s ease-in-out infinite;flex:0 0 auto}

.ghost{
  display:inline-flex;align-items:center;justify-content:center;gap:12px;
  min-height:var(--tap);padding:0 clamp(24px,1.9vw,44px);
  background:transparent;color:var(--ink-2);
  border:1px solid var(--line-2);border-radius:0;
  font-size:var(--t-small);letter-spacing:.1em;text-transform:uppercase;
  text-decoration:none;transition:.3s var(--ease);
}
.ghost:hover{border-color:var(--brass);color:var(--brass-2)}
.ghost svg{width:1.2em;height:1.2em;flex:0 0 auto}
.ghost:disabled{border-color:var(--line);color:var(--faint);pointer-events:none}
.linkish{background:none;border:0;color:var(--brass-2);text-decoration:underline;font:inherit;padding:0}

/* ═══ 1a · 1b · 1c — le tre strade in dettaglio ════════════════════════
   Ogni strada ha la sua schermata a tutto campo (gli ambienti in griglia, il
   QR grande e da solo, la descrizione con la tastiera a schermo): restano
   tutte dentro il passo 1 della barra in alto, perché sono modi diversi di
   fare lo stesso passo. Tre colonne strette in una schermata sola erano il
   compromesso di prima: il QR nasceva piccolo e la descrizione pure. */

/* Testata centrata: le tre schermate figlie della home ne condividono il
   ritmo — occhiello, titolo, una riga di spiegazione. */
.screen-head.mid{text-align:center}
.screen-head.mid .sub{margin-left:auto;margin-right:auto;max-width:64ch}
.panel-title{
  margin:0 0 clamp(14px,1.2vw,28px);
  font-size:var(--t-micro);letter-spacing:.28em;text-transform:uppercase;
  color:var(--brass);font-weight:400;
}

/* ── 1a · Modelli pronti ──────────────────────────────────────────── */
.env-grid{
  flex:1;min-height:0;overflow-y:auto;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(clamp(200px,15vw,320px),1fr));
  grid-auto-rows:max-content;
  gap:var(--gap);align-content:start;
  -webkit-overflow-scrolling:touch;
}
/* Sul totem i sei ambienti demo stanno SEMPRE in 3×2 e si dividono l'altezza
   disponibile: con un rapporto fisso, a tutto campo, la seconda riga finiva
   sotto la piega. Le righe elastiche stanno nel campo visivo a ogni scala. */
html.kiosk .env-grid{
  grid-template-columns:repeat(3,minmax(0,1fr));
  grid-auto-rows:minmax(0,1fr);
  align-content:stretch;overflow:hidden;
}
.env{
  position:relative;border:1px solid var(--line);background:var(--void-2);
  overflow:hidden;cursor:pointer;transition:.35s var(--ease);
  aspect-ratio:4/3;
}
html.kiosk .env{aspect-ratio:auto;min-height:0}
.env img{width:100%;height:100%;object-fit:cover;transition:transform .8s var(--ease);opacity:.82}
.env:hover{border-color:var(--brass)}
.env:hover img{transform:scale(1.06);opacity:1}
.env:active{transform:scale(.99)}
.env figcaption{
  position:absolute;left:0;right:0;bottom:0;
  padding:clamp(30px,2.6vw,52px) clamp(14px,1vw,22px) clamp(12px,.9vw,20px);
  background:linear-gradient(180deg,transparent,rgba(29,29,27,.94));
}
.env .nm{font-family:var(--font-display);font-size:var(--t-h3);line-height:1.1;color:var(--ink)}
.env .rm{font-size:var(--t-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--brass);margin-top:6px}

/* ── 1b · La tua foto: il QR grande e da solo ──────────────────────── */
/* Il codice ha la schermata tutta per sé: è il momento in cui il visitatore
   ha il telefono in mano, e da tre metri un QR piccolo non si inquadra. */
.qr-stage{
  flex:1;min-height:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(16px,1.5vw,40px);
}
.qr-frame{position:relative;background:#fff;padding:clamp(12px,1vw,20px);overflow:hidden}
/* Il lato del QR è il minore fra quanto concede la larghezza e quanto ne
   resta in altezza: su schermo basso si stringe invece di sfondare. */
.qr-frame img{width:min(clamp(150px,13vw,300px), 26vh);height:auto}
.qr-stage .qr-frame img{width:min(clamp(220px,19vw,470px), 40vh)}
/* I tre passi in riga sotto al codice: in colonna occuperebbero l'altezza
   che serve al QR. */
.qr-stage .steps{
  display:flex;gap:clamp(14px,1.4vw,36px);
  width:clamp(320px,50vw,1300px);margin:0;
}
.qr-stage .steps li{flex:1 1 0;padding-bottom:0}
/* Filo verde che scorre: dice "sto aspettando" senza uno spinner */
.qr-scan{
  position:absolute;left:0;right:0;height:2px;top:0;
  background:linear-gradient(90deg,transparent,var(--brass),transparent);
  animation:scan 2.8s var(--ease) infinite;
}
@keyframes scan{0%{top:2%;opacity:0}12%{opacity:1}88%{opacity:1}100%{top:98%;opacity:0}}
.steps{list-style:none;counter-reset:s;padding:0;margin:clamp(12px,1vw,22px) 0 0;text-align:left;width:100%}
.steps li{
  counter-increment:s;position:relative;
  padding:clamp(7px,.55vw,12px) 0 clamp(7px,.55vw,12px) clamp(32px,2.4vw,48px);
  border-top:1px solid var(--line);color:var(--ink-2);font-size:var(--t-small);line-height:1.45;
}
.steps li::before{
  content:counter(s,decimal-leading-zero);
  position:absolute;left:0;top:50%;transform:translateY(-50%);
  color:var(--brass);font-size:var(--t-micro);letter-spacing:.1em;
}
.waiting{
  margin:clamp(12px,1vw,20px) 0 0;color:var(--muted);font-size:var(--t-small);
  display:flex;align-items:center;gap:12px;
}

/* ── 1b-bis · Scatto / galleria (telefono) ──────────────────────────── */
/* Lo smartphone non può inquadrare sé stesso: al posto del QR due bersagli
   grandi, uno pieno (la fotocamera) e uno a filo (la galleria). Le misure
   sono in clamp perché la stessa schermata si prova anche da PC (?mobile=1). */
.up-stage{
  margin:auto;width:min(100%,560px);
  display:flex;flex-direction:column;align-items:stretch;gap:clamp(10px,1vw,18px);
}
.up-btn{
  display:flex;align-items:center;gap:clamp(12px,1vw,18px);
  min-height:clamp(72px,9vh,110px);padding:clamp(12px,1vw,18px) clamp(16px,1.4vw,24px);
  background:var(--panel);border:1px solid var(--line-2);color:var(--ink);
  cursor:pointer;transition:.25s var(--ease);
}
.up-btn.primary{background:var(--brass);border-color:var(--brass);color:var(--on-accent)}
.up-btn svg{width:clamp(28px,2.4vw,40px);height:auto;flex:0 0 auto;color:var(--brass)}
.up-btn.primary svg{color:var(--on-accent)}
.up-btn .up-tx{display:flex;flex-direction:column;gap:2px;min-width:0}
.up-btn .up-t{font-family:var(--font-display);font-size:var(--t-h3);line-height:1.15}
.up-btn .up-s{font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.up-btn.primary .up-s{color:var(--on-accent);opacity:.72}
.up-btn:hover{border-color:var(--brass)}
.up-btn:active{transform:scale(.99)}
.up-btn.busy{pointer-events:none;opacity:.55}
.up-msg{margin:0;min-height:1.6em;text-align:center;font-size:var(--t-small);color:var(--muted);overflow-wrap:anywhere}
.up-msg.err{color:#F3A9A9}
.up-hint{margin:0;text-align:center}
/* Ricerca con la tastiera di sistema (telefono): il campo vero al posto del
   tasto; stessa veste. */
.search .q-native{
  cursor:text;font:inherit;font-size:var(--t-small);color:var(--ink);
  -webkit-appearance:none;appearance:none;
}
.search .q-native::placeholder{color:var(--faint)}
.search .q-native:focus{outline:none;border-color:var(--brass)}
.search .q-native::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
html.phone #envDesc{caret-color:var(--brass);cursor:text}
html.phone .kbd{display:none}
/* Tessera «Usa una tua foto»: QR sul totem, fotocamera sul telefono. */
html.phone .way-qr .ic-qr{display:none}
html:not(.phone) .way-qr .ic-cam{display:none}
.way-qr .way-icon .ic-cam{width:clamp(96px,7.4vw,240px);height:auto}
.pulse{width:9px;height:9px;border-radius:50%;background:var(--brass);animation:beat 1.6s ease-in-out infinite}
@keyframes beat{0%,100%{opacity:1;box-shadow:0 0 0 0 var(--brass-dim)}50%{opacity:.35;box-shadow:0 0 0 9px transparent}}

/* ── 1c · Ambiente ex novo ─────────────────────────────────────────── */
/* Descrizione dettata o scritta con la tastiera a schermo. Il campo è
   readonly (la tastiera di sistema non compare) e il tocco apre il
   foglio-tastiera. La colonna è centrata e larga il giusto: una riga di
   testo lunga quanto il monitor non si rilegge. */
.say-stage{
  flex:1;min-height:0;width:clamp(320px,54vw,1500px);margin:0 auto;
  display:flex;flex-direction:column;justify-content:center;
}
.env-desc-wrap{position:relative;flex:0 1 auto;min-height:0;display:flex}
#envDesc{
  display:block;width:100%;flex:1 1 auto;min-height:clamp(140px,26vh,460px);
  padding:clamp(12px,.9vw,18px) clamp(64px,5vw,92px) clamp(12px,.9vw,18px) clamp(14px,1.1vw,22px);
  background:var(--void);border:1px solid var(--line-2);color:var(--ink);
  font:inherit;font-size:var(--t-body);line-height:1.5;border-radius:0;resize:none;
  caret-color:transparent;cursor:pointer;
}
#envDesc::placeholder{color:var(--faint)}
#envDesc:focus{outline:none;border-color:var(--brass)}
.dictate{
  position:absolute;right:clamp(8px,.6vw,12px);top:clamp(8px,.6vw,12px);
  display:flex;flex-direction:column;align-items:center;gap:3px;
  min-width:clamp(48px,3.6vw,64px);padding:clamp(7px,.55vw,11px) clamp(8px,.6vw,12px);
  background:var(--panel-2);border:1px solid var(--line);color:var(--ink-2);
  font:inherit;font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase;
  border-radius:0;transition:.15s var(--ease);
}
.dictate svg{width:clamp(18px,1.4vw,24px);height:auto}
.dictate:hover{border-color:var(--line-2);color:var(--ink)}
.dictate.rec{background:var(--brass);border-color:var(--brass);color:var(--on-accent);animation:beat 1.6s ease-in-out infinite}
.say-stage .cta.wide{margin-top:clamp(14px,1.2vw,28px);flex:0 0 auto}
/* Anteprime parziali della generazione (provider in streaming) */
.env-preview{position:relative;flex:0 1 auto;min-height:0;margin-top:clamp(10px,.9vw,16px);border:1px solid var(--line);background:var(--void);overflow:hidden}
.env-preview img{display:block;width:100%;height:auto;max-height:26vh;object-fit:cover;opacity:.92}
.env-preview img:not([src]){display:none}
.env-preview-msg{
  margin:0;padding:clamp(8px,.65vw,13px) clamp(12px,1vw,18px);
  color:var(--muted);font-size:var(--t-small);
  display:flex;align-items:center;gap:10px;
}
.env-preview-msg::before{
  content:'';width:9px;height:9px;border-radius:50%;flex:0 0 auto;
  background:var(--brass);animation:beat 1.6s ease-in-out infinite;
}

/* ═══ 2 · Studio ═══════════════════════════════════════════════════════ */
.studio{
  flex:1;min-height:0;
  display:grid;grid-template-columns:1fr clamp(320px,26vw,560px);
  gap:clamp(20px,1.9vw,48px);
}
.canvas-wrap{display:flex;flex-direction:column;min-height:0;gap:var(--gap)}
.canvas-hold{
  position:relative;flex:1;min-height:0;
  border:1px solid var(--line);background:var(--void-2);
  overflow:hidden;
}
.canvas-hold img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
#lasso{position:absolute;inset:0;width:100%;height:100%;touch-action:none;cursor:crosshair}
.lasso-hint{
  position:absolute;left:50%;bottom:clamp(14px,1.2vw,26px);transform:translateX(-50%);
  margin:0;padding:clamp(9px,.7vw,15px) clamp(16px,1.3vw,28px);
  background:rgba(29,29,27,.82);backdrop-filter:blur(10px);
  border:1px solid var(--line);
  color:var(--ink-2);font-size:var(--t-small);white-space:nowrap;
  transition:opacity .4s var(--ease);
}
.lasso-hint.gone{opacity:0}
.clear-lasso{
  position:absolute;right:clamp(12px,1vw,20px);top:clamp(12px,1vw,20px);
  min-height:0;padding:clamp(8px,.6vw,13px) clamp(14px,1.1vw,22px);
  background:rgba(29,29,27,.86);backdrop-filter:blur(10px);
  border:1px solid var(--brass);color:var(--brass-2);
  font-size:var(--t-small);
}
/* Avvertenza AI sulla base di lavoro (ambiente generato o render adottato) */
.ai-base-note{
  position:absolute;left:clamp(12px,1vw,20px);top:clamp(12px,1vw,20px);
  margin:0;padding:clamp(7px,.55vw,12px) clamp(12px,1vw,20px);
  display:flex;align-items:center;gap:9px;
  background:rgba(29,29,27,.82);backdrop-filter:blur(10px);
  border:1px solid var(--line);color:var(--muted);font-size:var(--t-micro);
  pointer-events:none;
}
.ai-base-note svg{width:clamp(14px,1vw,18px);height:auto;flex:0 0 auto;color:var(--brass)}
.thumbs{flex:0 0 auto;display:flex;gap:var(--gap);overflow-x:auto;padding-bottom:4px}
.thumbs img{
  height:clamp(66px,5.6vw,120px);width:auto;flex:0 0 auto;
  border:2px solid transparent;opacity:.5;object-fit:cover;
  cursor:pointer;transition:.3s var(--ease);
}
.thumbs img:hover{opacity:.85}
.thumbs img.sel{border-color:var(--brass);opacity:1}

.side{display:flex;flex-direction:column;min-height:0}
.side h2{flex:0 0 auto}
.surf-list{
  flex:1;min-height:0;overflow-y:auto;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(clamp(130px,10vw,200px),1fr));
  grid-auto-rows:max-content;
  gap:clamp(10px,.8vw,18px);
  align-content:start;
  margin:clamp(18px,1.6vw,38px) 0;
}
.surf{
  min-height:var(--tap);padding:clamp(12px,1vw,20px);
  background:var(--panel);border:1px solid var(--line);color:var(--ink-2);
  font-size:var(--t-small);text-align:left;line-height:1.3;
  transition:.28s var(--ease);
}
.surf:hover{border-color:var(--line-2);color:var(--ink)}
.surf.sel{border-color:var(--brass);background:var(--brass-dim);color:var(--brass-2)}
/* Mentre si capisce che cosa è stato cerchiato, l'elenco resta usabile: chi
   sa già cosa vuole tocca la superficie e non aspetta nessuno. */
.surf-list.guessing .surf{opacity:.72;transition:opacity .3s var(--ease)}

/* Attesa del riconoscimento: dura un paio di secondi e va detto, altrimenti
   l'elenco vuoto sembra un errore. */
.surf-wait{
  grid-column:1/-1;margin:0;display:flex;align-items:center;gap:12px;
  color:var(--muted);font-size:var(--t-small);
}

/* ═══ 3 · Catalogo ═════════════════════════════════════════════════════ */
/* Filtri a FISARMONICA: una riga di selettori (uno per dimensione, col
   valore scelto) e, sotto, i valori della sola dimensione aperta. Con
   quasi 400 superfici e una quarantina di collezioni, tutti i chip insieme
   si mangiavano metà dell'altezza del catalogo — e sul totem non si scorre. */
.filters{
  flex:0 0 auto;display:flex;flex-direction:column;gap:clamp(8px,.65vw,14px);
  margin-bottom:clamp(14px,1.2vw,28px);
}
.fsel{display:flex;align-items:center;gap:clamp(8px,.65vw,14px);flex-wrap:wrap}
.fsel .flabel{
  font-size:var(--t-micro);letter-spacing:.2em;text-transform:uppercase;
  color:var(--faint);margin-right:4px;
}
.fbtn{
  display:inline-flex;align-items:center;gap:.6em;
  min-height:clamp(40px,2.9vw,60px);padding:0 clamp(14px,1.1vw,24px);
  background:transparent;border:1px solid var(--line);color:var(--ink-2);
  font-size:var(--t-small);white-space:nowrap;transition:.25s var(--ease);border-radius:0;
}
.fbtn .k{color:var(--faint);letter-spacing:.08em;text-transform:uppercase;font-size:var(--t-micro)}
.fbtn .v{color:var(--ink-2)}
.fbtn .c{color:var(--faint);font-size:var(--t-micro)}
.fbtn:hover{border-color:var(--line-2);color:var(--ink)}
.fbtn.on{border-color:var(--brass);background:var(--brass-dim)}
.fbtn.on .v{color:var(--brass-2)}
.fbtn.open{border-color:var(--brass)}
.fbtn.open .c{color:var(--brass)}
.fvals{
  display:flex;flex-wrap:wrap;gap:clamp(6px,.5vw,10px);
  padding:clamp(8px,.6vw,12px) clamp(10px,.8vw,16px);
  border:1px solid var(--line);background:var(--panel);
}
.chip{
  min-height:clamp(40px,2.9vw,60px);padding:0 clamp(14px,1.1vw,24px);
  background:transparent;border:1px solid var(--line);color:var(--ink-2);
  font-size:var(--t-small);white-space:nowrap;transition:.25s var(--ease);
}
.chip:hover{border-color:var(--line-2);color:var(--ink)}
.chip.on{border-color:var(--brass);background:var(--brass-dim);color:var(--brass-2)}
.chip .n{color:var(--faint);margin-left:8px;font-size:var(--t-micro)}
.chip.on .n{color:var(--brass)}
.chip.reset{border-color:transparent;color:var(--faint);text-decoration:underline}

/* Catalogo a PAGINE fra due gutter con le frecce. Le colonne le decide
   app.js (--cols, gridCapacity) perché le tessere stiano nell'altezza
   disponibile; ciò che non entra sta nella pagina dopo. overflow:hidden è
   una garanzia, non un ripiego: qui non si scorre mai. */
.slab-wrap{
  flex:1;min-height:0;
  display:grid;grid-template-columns:var(--pg) minmax(0,1fr) var(--pg);
  gap:clamp(8px,.8vw,20px);
}
/* Celle ESPLICITE: con le frecce nascoste (display:none) la griglia
   diventerebbe il primo figlio e scivolerebbe nella colonna del gutter,
   larga 96px — e la capienza calcolata su quella larghezza farebbe
   ricomparire le frecce, in un'oscillazione senza fine. */
.pg-btn.prev{grid-column:1}
.pg-btn.next{grid-column:3}
.slab-grid{
  grid-column:2;
  /* overflow-y:auto (barra nascosta in kiosk) è la rete di sicurezza per
     altezze fuori progetto (< ~720px): le tessere restano raggiungibili col
     dito invece di sparire sotto il bordo. pan-y lascia al browser la sola
     panoramica verticale: la strisciata ORIZZONTALE resta ai pointer event
     (senza, il tocco finiva in pointercancel e la pagina non girava). */
  min-height:0;overflow-y:auto;touch-action:pan-y;
  display:grid;grid-template-columns:repeat(var(--cols,6),minmax(0,1fr));
  /* max-content, non auto: dentro un contenitore ad altezza definita le righe
     `auto` vengono compresse e `.slab{overflow:hidden}` decapita la didascalia
     dell'elemento. Le righe devono sempre valere quanto il loro contenuto. */
  grid-auto-rows:max-content;
  gap:var(--gap);align-content:start;
}
/* Frecce di pagina: gutter a tutta altezza, bersaglio enorme per il dito.
   Con una pagina sola spariscono, ma i gutter restano: la griglia non
   cambia larghezza — e quindi capienza — a seconda del numero di pagine. */
.pg-btn{
  align-self:stretch;display:grid;place-items:center;
  background:transparent;border:1px solid var(--line);color:var(--ink-2);
  border-radius:0;transition:.25s var(--ease);
}
.pg-btn svg{width:clamp(26px,2vw,40px);height:auto}
.pg-btn:hover{border-color:var(--brass);color:var(--brass-2)}
.pg-btn:disabled{opacity:.25;pointer-events:none}
#pgInfo{color:var(--brass)}
.slab{
  position:relative;border:1px solid var(--line);background:var(--panel);
  overflow:hidden;cursor:pointer;transition:.35s var(--ease);
  animation:pop .5s var(--ease) both;
}
@keyframes pop{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.slab img{width:100%;aspect-ratio:1/1.05;object-fit:cover;transition:transform .8s var(--ease)}
.slab:hover{border-color:var(--brass);box-shadow:var(--glow)}
.slab:hover img{transform:scale(1.05)}
.slab:active{transform:scale(.99)}
.slab .meta{padding:clamp(12px,1vw,20px)}
/* Didascalia ad altezza FISSA: così l'altezza di una tessera è nota e la
   capienza di una pagina si calcola senza sorprese. Il NOME va su DUE righe
   riservate e si legge per intero — un nome lungo si stringe nel corpo
   (fitNames in app.js) invece di finire nei puntini; collezione e finitura
   restano su una riga. */
.slab .nm{
  font-family:var(--font-display);font-size:var(--t-h3);line-height:1.12;color:var(--ink);
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
  /* L'altezza è ancorata al corpo di BASE (--t-h3), non all'em: quando il
     nome si stringe la tessera non cambia altezza. */
  height:calc(2 * 1.12 * var(--t-h3));overflow:hidden;overflow-wrap:anywhere;
}
/* Nome lunghissimo: tre righe fitte nella stessa altezza tengono un corpo
   più grande di due righe strette (fitNames decide quando). */
.slab .nm.l3{-webkit-line-clamp:3;line-height:1}
.slab .cl{margin-top:6px;font-size:var(--t-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--brass);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.slab .fx{margin-top:4px;font-size:var(--t-micro);color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Marchio della proposta dell'assistente vocale */
.slab.suggested{border-color:var(--brass)}
.slab.suggested::before{
  content:'consigliata';position:absolute;z-index:2;top:0;left:0;
  padding:7px 12px;background:var(--brass);color:var(--on-accent);
  font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase;
}
.empty{color:var(--muted);font-size:var(--t-body);margin:clamp(20px,2vw,44px) 0}

/* Tre comandi nella testata del catalogo (ricerca + consigli + ritorno) */
.head-actions{display:flex;align-items:center;gap:clamp(10px,.8vw,18px);flex:0 0 auto}
/* Ricerca per nome: un campo che si legge (la parola cercata, o l'invito) e
   si tocca — apre il foglio-tastiera. La × a fianco azzera. */
.search{display:flex;align-items:stretch;width:clamp(190px,15vw,360px)}
.search .q{
  flex:1;min-width:0;display:flex;align-items:center;gap:.6em;
  min-height:clamp(40px,2.9vw,60px);padding:0 clamp(12px,1vw,22px);
  background:transparent;border:1px solid var(--line);color:var(--ink);
  font-size:var(--t-small);text-align:left;border-radius:0;transition:.25s var(--ease);
}
.search .q:hover{border-color:var(--line-2)}
.search .q svg{width:1.2em;height:1.2em;flex:0 0 auto;color:var(--brass)}
.search .q span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.search .q span.empty{color:var(--faint)}
.search.on .q{border-color:var(--brass);background:var(--brass-dim);color:var(--brass-2)}
.search .x{
  flex:0 0 auto;min-width:var(--tap);border:1px solid var(--brass);border-left:0;
  background:var(--brass-dim);color:var(--brass-2);font-size:var(--t-lede);line-height:1;border-radius:0;
}
.search .x:hover{background:var(--brass);color:var(--on-accent)}
/* Mentre il modello guarda la foto, la stella pulsa: la risposta arriva in
   qualche secondo e il bottone non deve sembrare morto. */
#suggestBtn.working{border-color:var(--brass);color:var(--brass-2)}
#suggestBtn.working svg{animation:pulsa 1.1s ease-in-out infinite}
@keyframes pulsa{0%,100%{opacity:.35;transform:scale(.9)}50%{opacity:1;transform:scale(1.08)}}

/* Barra di nota: motivazione del consiglio o stato "sto aggiungendo" */
.note-bar{
  flex:0 0 auto;margin:0 0 clamp(14px,1.2vw,26px);
  padding:clamp(11px,.85vw,18px) clamp(14px,1.1vw,22px);
  border-left:2px solid var(--brass);background:var(--panel);
  color:var(--ink-2);font-size:var(--t-small);line-height:1.55;
}
.note-bar .linkish{margin-left:2px}

/* Elemento già in scena nel confronto */
/* Non idonea alla superficie scelta (regole di idoneità del catalogo): resta in
   griglia, spenta, e dice perché. Non si tocca: il tocco avvisa e basta. */
.slab.unfit img{filter:grayscale(.85) brightness(.45)}
.slab.unfit .nm,.slab.unfit .cl,.slab.unfit .fx{opacity:.5}
.slab.unfit .why{margin-top:6px;font-size:var(--t-micro);color:var(--brass);line-height:1.3;white-space:normal}
.slab.unfit:hover{border-color:transparent;box-shadow:none}
.slab.unfit:hover img{transform:none}
.slab.in-compare{border-color:var(--brass-dim)}
.slab.in-compare::after{
  content:'a confronto';position:absolute;z-index:2;top:0;right:0;
  padding:7px 12px;background:rgba(29,29,27,.86);border-left:1px solid var(--brass-dim);
  border-bottom:1px solid var(--brass-dim);color:var(--brass-2);
  font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase;
}

/* ═══ 4 · Risultato ════════════════════════════════════════════════════ */
.result-wrap{
  flex:1;min-height:0;
  display:grid;
  grid-template-columns:1fr clamp(300px,23vw,480px);
  /* Il palco prende l'altezza che avanza, l'avvertenza AI si prende la sua e
     resta sempre visibile: non è un dettaglio estetico, è un obbligo. In
     mezzo, quando c'è una storia da mostrare, la striscia dei passaggi. */
  grid-template-rows:minmax(0,1fr) auto auto;
  grid-template-areas:"stage side" "vers side" "note side";
  gap:clamp(12px,1vw,26px) clamp(20px,1.9vw,48px);
}
.compare{grid-area:stage}
.vers{grid-area:vers}
.result-wrap > .ai-note{grid-area:note}
.result-side{grid-area:side}

/* ── I passaggi della sessione ──────────────────────────────────────────
   La foto di partenza e ogni render adottato: toccarne uno lo mostra intero
   (la maniglia del prima/dopo corre a fondo corsa), «Render attuale» riporta
   al confronto. Il riquadro acceso segue la maniglia, non un flag a parte. */
.vers{display:flex;align-items:center;gap:clamp(12px,1vw,26px);min-width:0}
.vers-lb{
  flex:0 0 auto;
  font-size:var(--t-micro);letter-spacing:.24em;text-transform:uppercase;color:var(--brass);
}
/* Niente scorrimento nemmeno qui (regola del totem): al crescere della
   catena i riquadri si STRINGONO, fino a un minimo sotto il quale la
   didascalia non si leggerebbe più. Ogni passaggio costa un render, quindi
   in una sessione reale sono pochi e lo spazio basta. */
.vers-strip{display:flex;gap:clamp(8px,.7vw,16px);min-width:0;overflow:hidden}
.vth{
  flex:0 1 auto;width:clamp(104px,8.4vw,240px);min-width:clamp(72px,5vw,120px);
  display:block;padding:0;overflow:hidden;
  background:var(--void-2);border:1px solid var(--line);color:var(--muted);
  font:inherit;text-align:left;transition:.25s var(--ease);
}
.vth img{width:100%;height:clamp(50px,4vw,112px);object-fit:cover;opacity:.7;transition:.35s var(--ease)}
.vth-lb{
  display:block;padding:clamp(5px,.4vw,9px) clamp(7px,.55vw,12px);
  font-size:var(--t-micro);letter-spacing:.12em;text-transform:uppercase;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.vth:hover{border-color:var(--line-2);color:var(--ink-2)}
.vth:hover img{opacity:.92}
.vth.on{border-color:var(--brass);color:var(--brass-2)}
.vth.on img{opacity:1}
.compare{
  position:relative;overflow:hidden;
  border:1px solid var(--line);background:var(--void-2);
  min-height:0;touch-action:none;
}
.compare img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
.cmp-before,.cmp-after{position:absolute;inset:0}
/* La parte "dopo" viene ritagliata dal trascinamento della maniglia.
   Attenzione: questo 25% e quello di `.cmp-handle` sono percentuali del
   RIQUADRO e valgono solo per il primo disegno, prima che il codice entri in
   gioco. Appena c'è una foto, app.js li ricalcola sulla foto visibile — che
   con `contain` non riempie il riquadro. La posizione di riposo vera è
   CMP_REST in app.js: è lì che si cambia. */
.cmp-after{clip-path:inset(0 0 0 25%)}
.cmp-handle{
  position:absolute;top:0;bottom:0;left:25%;width:clamp(56px,4vw,88px);
  transform:translateX(-50%);cursor:ew-resize;z-index:3;
  display:grid;place-items:center;background:none;border:0;
}
.cmp-handle .bar{position:absolute;top:0;bottom:0;width:1px;background:var(--brass);box-shadow:0 0 24px rgba(164,198,49,.45)}
.cmp-handle .grip{
  width:clamp(52px,3.6vw,80px);height:clamp(52px,3.6vw,80px);border-radius:50%;
  display:grid;place-items:center;
  background:var(--brass);color:var(--on-accent);
  box-shadow:0 12px 40px rgba(0,0,0,.6);
}
.cmp-handle .grip svg{width:52%;height:52%}
.cmp-tag{
  position:absolute;top:clamp(14px,1.1vw,24px);z-index:2;
  padding:clamp(7px,.55vw,12px) clamp(13px,1vw,20px);
  background:rgba(29,29,27,.78);backdrop-filter:blur(10px);border:1px solid var(--line);
  font-size:var(--t-micro);letter-spacing:.2em;text-transform:uppercase;color:var(--ink-2);
}
.cmp-tag.left{left:clamp(14px,1.1vw,24px)}
.cmp-tag.right{right:clamp(14px,1.1vw,24px);color:var(--brass-2);border-color:var(--brass-dim)}
.compare.loading .cmp-handle,.compare.loading .cmp-tag{display:none}

/* Ingrandimento: bersaglio in basso a destra, dove non incrocia le targhe
   PRIMA/DOPO né il ritorno al confronto. */
.stage-zoom{
  position:absolute;right:clamp(14px,1.1vw,24px);bottom:clamp(14px,1.1vw,24px);z-index:4;
  width:clamp(48px,3.2vw,76px);height:clamp(48px,3.2vw,76px);
  display:grid;place-items:center;
  background:rgba(29,29,27,.78);backdrop-filter:blur(10px);
  border:1px solid var(--line-2);color:var(--ink-2);border-radius:0;
}
.stage-zoom svg{width:46%;height:46%}
.stage-zoom:hover{border-color:var(--brass);color:var(--brass-2)}

/* ── Curiosità durante l'attesa ─────────────────────────────────────────
   Sopra al velo di generazione (z 5) perché è lì che va letta, e vale anche
   nel confronto affiancato, dove il velo non c'è. */
.tip{
  position:absolute;left:50%;bottom:clamp(14px,1.1vw,28px);transform:translateX(-50%);z-index:6;
  /* Non intercetta il dito: nel confronto affiancato copre una fascia dei
     riquadri, che restano toccabili per portarli a tutto palco. */
  pointer-events:none;
  margin:0;max-width:min(88%,58ch);
  padding:clamp(10px,.8vw,18px) clamp(18px,1.4vw,32px);
  background:rgba(29,29,27,.84);backdrop-filter:blur(10px);
  border:1px solid var(--line-2);text-align:center;
}
.tip-k{
  display:block;margin-bottom:clamp(4px,.35vw,8px);
  font-size:var(--t-micro);letter-spacing:.28em;text-transform:uppercase;color:var(--brass);
}
/* Si legge a tre metri, come tutto il resto del totem: qui il corpo del
   testo, non il piccolo delle didascalie. */
.tip-t{display:block;font-size:var(--t-body);color:var(--ink-2);line-height:1.5}
/* Nel confronto affiancato in basso ci sono le didascalie dei riquadri: la
   curiosità sale in cima, dove il ritorno al confronto non c'è. */
.compare.multi-on .tip{top:clamp(14px,1.1vw,28px);bottom:auto}
.tip-t.in{animation:tipin .6s var(--ease) both}
@keyframes tipin{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}

/* Generazione: una lama di luce attraversa il buio, come un pannello che si
   rivela sotto un faretto. Nessuno spinner. */
.gen{position:absolute;inset:0;z-index:5;display:grid;place-items:center;background:rgba(29,29,27,.90);backdrop-filter:blur(6px)}
/* Con un'anteprima parziale sotto (render in streaming) il velo si fa
   leggero: l'immagine che nasce si intravede, il titolo resta leggibile. */
.gen.peek{background:rgba(29,29,27,.42);backdrop-filter:blur(1.5px)}
.gen-inner{text-align:center;padding:0 var(--pad-x);position:relative;width:100%}
.gen-sweep{
  position:absolute;left:0;right:0;top:50%;height:1px;
  background:linear-gradient(90deg,transparent,var(--brass),transparent);
  transform:translateY(-50%);animation:sweep 2.2s var(--ease) infinite;
}
@keyframes sweep{0%{opacity:0;transform:translateY(-50%) scaleX(.2)}35%{opacity:1}100%{opacity:0;transform:translateY(-50%) scaleX(1)}}
.gen-title{
  margin:0;font-family:var(--font-display);font-size:var(--t-h2);
  font-weight:300;color:var(--ink);line-height:1.1;
}
.gen-sub{margin:clamp(12px,1vw,22px) 0 0;font-size:var(--t-micro);letter-spacing:.28em;text-transform:uppercase;color:var(--brass)}

/* min-width:0 — senza, un nome di elemento lungo allarga la traccia e spinge
   fuori schermo il resto della colonna. */
.result-side{display:flex;flex-direction:column;min-height:0;min-width:0;overflow:hidden}
/* La scheda cede, le azioni no: se lo spazio manca è la scheda a scorrere
   (senza barra), le quattro azioni restano ancorate in basso e visibili. */
.result-info{flex:1 1 auto;min-height:0;overflow-y:auto;display:flex;flex-direction:column}
/* Il nome dell'elemento nella colonna stretta: un gradino sotto l'h2 di
   pagina, altrimenti due righe di titolo spingono fuori le specifiche. */
.result-side h2{overflow-wrap:break-word;font-size:clamp(28px,2.4vw,58px)}
/* Specifiche su due colonne, etichetta sopra il valore: tre righe invece
   di sei, e la scheda sta nel campo visivo anche a 1080p. */
.specs{
  margin:clamp(12px,1vw,24px) 0 0;padding:0;
  display:grid;grid-template-columns:1fr 1fr;column-gap:clamp(12px,1vw,22px);row-gap:0;
}
.specs div{display:flex;flex-direction:column;gap:3px;min-width:0;padding:clamp(7px,.6vw,13px) 0;border-top:1px solid var(--line)}
.specs dt{color:var(--faint);font-size:var(--t-micro);letter-spacing:.16em;text-transform:uppercase}
.specs dd{margin:0;color:var(--ink);font-size:var(--t-small);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Portata del gesto, nello studio: colonna stretta → i due chip si impilano
   a tutta larghezza invece di sbordare l'uno sull'altro. */
.scope-row{flex:0 0 auto;margin-top:clamp(12px,1vw,22px)}
.scope-row .opt-chips{display:grid;grid-template-columns:1fr;gap:clamp(7px,.55vw,12px)}
.scope-row .chip{width:100%;justify-content:center}

.gen-meta{
  margin:clamp(9px,.7vw,14px) 0 0;padding-top:clamp(9px,.7vw,14px);
  border-top:1px solid var(--line);
  color:var(--faint);font-size:var(--t-micro);letter-spacing:.08em;line-height:1.6;
}
/* Le quattro azioni del risultato: griglia 2×2 ancorata in basso. */
.result-actions{
  flex:0 0 auto;margin-top:auto;padding-top:clamp(14px,1.2vw,28px);
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(8px,.7vw,14px);
}
/* Tessera d'azione: icona grande sopra, etichetta corta, sottotitolo micro.
   Bersaglio generoso per il dito, spigoli vivi. La consegna dell'immagine
   è l'azione principale (verde pieno): è quella che porta il contatto.
   (.act-tile, non .act: «act» è già la classe dei tasti speciali della
   tastiera a schermo.) */
.act-tile{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(4px,.35vw,8px);min-width:0;
  min-height:clamp(88px,6.2vw,210px);padding:clamp(10px,.8vw,16px) clamp(8px,.6vw,12px);
  background:var(--panel);border:1px solid var(--line-2);color:var(--ink);
  border-radius:0;text-align:center;transition:.25s var(--ease);
}
.act-tile svg{width:clamp(28px,2.2vw,60px);height:clamp(28px,2.2vw,60px);color:var(--brass);flex:0 0 auto}
.act-tile .act-lb{font-size:var(--t-small);font-weight:500;letter-spacing:.06em;text-transform:uppercase;line-height:1.2}
.act-tile .act-sub{font-size:var(--t-micro);color:var(--muted);line-height:1.3;min-height:1.3em}
.act-tile:hover{border-color:var(--brass);background:var(--panel-2)}
.act-tile:active{transform:scale(.985)}
.act-tile:disabled{opacity:.4;pointer-events:none}
.act-tile.primary{background:var(--brass);border-color:var(--brass);color:var(--on-accent)}
.act-tile.primary svg{color:var(--on-accent)}
.act-tile.primary .act-sub{color:var(--on-accent);opacity:.7}
.act-tile.primary:hover{background:var(--brass-deep);border-color:var(--brass-deep)}
.ai-note{
  margin:0;padding:clamp(11px,.85vw,18px) clamp(14px,1.1vw,22px);
  border:1px solid var(--line);background:var(--panel);
  display:flex;gap:12px;align-items:center;
  color:var(--muted);font-size:var(--t-micro);line-height:1.55;
}
.ai-note svg{width:1.5em;height:1.5em;flex:0 0 auto;margin-top:.15em;color:var(--brass);opacity:.85}

/* ── Opzioni dell'elemento in scena: luce e vista ───────────────────────── */
/* Etichetta sopra e non a fianco: nella colonna stretta del risultato tre
   chip più l'etichetta sulla stessa riga superano la larghezza disponibile e
   il contenitore, che scorre in verticale, taglia via i valori a destra. */
.opt-row{
  flex:0 0 auto;display:flex;flex-direction:column;align-items:stretch;
  gap:clamp(6px,.5vw,10px);margin-top:clamp(12px,1vw,22px);
}
.opt-label{
  font-size:var(--t-micro);letter-spacing:.2em;text-transform:uppercase;
  color:var(--faint);
}
.opt-chips{display:flex;gap:clamp(6px,.5vw,10px);width:100%;min-width:0}
/* flex-basis 0 + min-width 0: le chip si dividono lo spazio e SANNO
   rimpicciolirsi, invece di imporre la propria larghezza alla colonna. */
.opt-chips .chip{
  flex:1 1 0;min-width:0;min-height:clamp(44px,3vw,62px);
  padding:0 clamp(6px,.5vw,14px);text-align:center;
  overflow:hidden;text-overflow:ellipsis;
}
.chip:disabled{opacity:.45;pointer-events:none}

/* ── Confronto fra elementi (fino a 3 riquadri) ──────────────────────────── */
/* La griglia copre il palco del prima/dopo: le due modalità non convivono,
   e tenerle sovrapposte evita di ricostruire il DOM a ogni cambio di vista. */
.multi{
  position:absolute;inset:0;z-index:4;
  display:grid;grid-auto-flow:column;grid-auto-columns:1fr;
  gap:1px;background:var(--line);
}
.compare.multi-on .cmp-handle,.compare.multi-on .cmp-tag{display:none}

.mpane{
  position:relative;margin:0;min-width:0;overflow:hidden;
  background:var(--void-2);border:0;padding:0;cursor:pointer;
  transition:.3s var(--ease);
}
.mpane img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
.mpane .mvoid{position:absolute;inset:0;background:var(--void-2)}
/* Il riquadro in primo piano è quello a cui si riferiscono le specifiche
   nella colonna di destra: senza questo segno il legame non si vede. */
.mpane.on{box-shadow:inset 0 0 0 2px var(--brass)}
.mpane.failed{background:#1A1214}
.mpane figcaption{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  padding:clamp(10px,.9vw,20px) clamp(12px,1vw,22px);
  display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  background:linear-gradient(180deg,rgba(29,29,27,0),rgba(29,29,27,.92) 45%);
}
.mpane .nm{
  font-family:var(--font-display);font-size:var(--t-h3);
  line-height:1.1;color:var(--ink);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.mpane .lg{font-size:var(--t-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--brass);flex:0 0 auto}
.mpane .mx{
  position:absolute;top:clamp(8px,.6vw,14px);right:clamp(8px,.6vw,14px);z-index:3;
  width:clamp(38px,2.6vw,52px);height:clamp(38px,2.6vw,52px);
  display:grid;place-items:center;
  background:rgba(29,29,27,.78);backdrop-filter:blur(6px);
  border:1px solid var(--line-2);color:var(--ink-2);border-radius:0;
}
.mpane .mx svg{width:46%;height:46%}
.mpane .mx:hover{border-color:var(--brass);color:var(--brass-2)}
/* Segno che il riquadro si può ingrandire: su touch non c'è hover che lo riveli */
.mpane .mzoom{
  position:absolute;top:clamp(8px,.6vw,14px);left:clamp(8px,.6vw,14px);z-index:3;
  width:clamp(32px,2.2vw,44px);height:clamp(32px,2.2vw,44px);
  display:grid;place-items:center;
  background:rgba(29,29,27,.7);border:1px solid var(--line);color:var(--ink-2);
  opacity:.75;transition:.25s var(--ease);pointer-events:none;
}
.mpane .mzoom svg{width:52%;height:52%}
.mpane:hover .mzoom{opacity:1;border-color:var(--brass);color:var(--brass-2)}

/* Ritorno al confronto, sul palco dell'elemento ingrandita */
.back-multi{
  position:absolute;top:clamp(14px,1.1vw,24px);left:50%;transform:translateX(-50%);z-index:4;
  display:inline-flex;align-items:center;gap:10px;
  padding:clamp(8px,.6vw,13px) clamp(14px,1.1vw,22px);
  background:rgba(29,29,27,.82);backdrop-filter:blur(10px);
  border:1px solid var(--line-2);color:var(--ink-2);border-radius:0;
  font-size:var(--t-micro);letter-spacing:.2em;text-transform:uppercase;
}
.back-multi svg{width:1.15em;height:1.15em}
.back-multi:hover{border-color:var(--brass);color:var(--brass-2)}
.compare.multi-on .back-multi{display:none}

.mpane .msweep{
  position:absolute;left:0;right:0;top:50%;z-index:2;height:1px;
  background:linear-gradient(90deg,transparent,var(--brass),transparent);
  animation:sweep 2.2s var(--ease) infinite;
}
.mpane.loading{background:rgba(29,29,27,.94)}
/* Anteprima parziale nel riquadro del confronto: attenuata, per non farla
   passare per il risultato finale. */
.mpane img.mpartial{opacity:.6}
.mpane .merr{
  position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);z-index:2;
  margin:0;padding:0 clamp(14px,1.1vw,22px);text-align:center;
  color:#F3A9A9;font-size:var(--t-micro);line-height:1.5;
}
/* Il «+» è un riquadro come gli altri: sul touch è un bersaglio enorme e
   dice da solo che al confronto manca ancora un posto. */
.mpane.add{
  display:grid;place-items:center;align-content:center;gap:clamp(8px,.6vw,14px);
  background:var(--panel);border:1px dashed var(--line-2);color:var(--ink-2);
  font:inherit;
}
.mpane.add:hover{border-color:var(--brass);color:var(--brass-2);background:var(--panel-2)}
/* Spento durante una generazione: si spegne il CONTENUTO, non il riquadro.
   Con `opacity` sull'elemento intero il fondo diventava translucido e sotto
   si vedeva il render in arrivo sul palco del prima/dopo — il terzo slot
   sembrava bucato. */
.mpane.add:disabled{pointer-events:none;border-color:var(--line);color:var(--faint)}
.mpane.add:disabled .plus{color:var(--faint);opacity:.55}
.mpane.add .plus{font-size:clamp(34px,3vw,64px);line-height:1;font-weight:200;color:var(--brass)}
.mpane.add .lb{font-size:var(--t-micro);letter-spacing:.2em;text-transform:uppercase}

/* ═══ Foglio-tastiera (descrizione dell'ambiente) ══════════════════════
   Il totem non ha tastiera: toccando il campo si apre dal basso questo
   foglio con la tastiera «testo». Copre parte della schermata, quindi
   ripete in testa ciò che si sta scrivendo. «Fatto» (o un tocco fuori)
   lo chiude; il testo è già nel campo. */
.sheet{
  position:fixed;inset:0;z-index:85;
  display:flex;align-items:flex-end;justify-content:center;
  background:rgba(29,29,27,.55);backdrop-filter:blur(4px);
}
.sheet-inner{
  width:min(1500px,96vw);
  padding:clamp(14px,1.2vw,26px) clamp(18px,1.5vw,34px) clamp(18px,1.5vw,34px);
  background:rgba(41,41,39,.98);border:1px solid var(--line-2);border-bottom:0;
  box-shadow:var(--shadow);animation:sheet .3s var(--ease) both;
}
@keyframes sheet{from{transform:translateY(24px);opacity:0}to{transform:none;opacity:1}}
.sheet-head{display:flex;align-items:center;gap:clamp(14px,1.2vw,26px);margin-bottom:clamp(10px,.9vw,18px)}
/* Due righe visibili, ma le ULTIME: il JS tiene la riga scorsa in fondo
   (scrollTop), così ciò che si sta scrivendo è sempre sotto gli occhi. */
.sheet-echo{
  flex:1;min-width:0;margin:0;
  min-height:var(--tap);max-height:calc(1.4em * 2 + 2 * clamp(10px,.8vw,16px));
  padding:clamp(10px,.8vw,16px) clamp(14px,1.1vw,22px);
  background:var(--void);border:1px solid var(--brass);color:var(--ink);
  font-size:var(--t-lede);line-height:1.4;overflow:hidden;overflow-wrap:anywhere;
}
.sheet-echo::after{content:'▏';color:var(--brass);animation:beat 1.1s steps(2) infinite}
.sheet-echo.empty{color:var(--faint)}
/* Specificità doppia (.kbd.kbd-text): la regola generica .kbd button sta
   più in basso nel foglio e a parità la vincerebbe. */
.kbd.kbd-text{margin:0}
.kbd.kbd-text button{min-height:clamp(52px,3.6vw,80px);font-size:var(--t-lede)}
.kbd.kbd-text button.space{flex:5 1 0;font-size:var(--t-small);letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}

/* ═══ Toast ════════════════════════════════════════════════════════════ */
.toast{
  position:fixed;left:50%;top:clamp(96px,8vw,150px);transform:translateX(-50%) translateY(-24px);
  z-index:80;opacity:0;pointer-events:none;
  padding:clamp(13px,1vw,20px) clamp(22px,1.7vw,36px);
  background:var(--panel-2);border:1px solid var(--line-2);color:var(--ink);
  font-size:var(--t-small);max-width:min(72ch,84vw);text-align:center;
  box-shadow:var(--shadow);transition:.4s var(--ease);
}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.toast.err{border-color:#8C3A3A;color:#F3C9C9}

/* ═══ Adattamenti ══════════════════════════════════════════════════════ */
/* Sotto i 1200px (portatile in demo) le colonne si impilano: il pannello
   laterale scende sotto il palco invece di stringersi fino a rompersi. */
@media(max-width:1200px){
  .studio,.result-wrap{grid-template-columns:1fr;overflow-y:auto}
  .result-wrap{grid-template-rows:none;grid-template-areas:"stage" "vers" "note" "side"}
  .canvas-hold{min-height:46vh}
  .compare{min-height:52vh}
  /* Le tre strade si impilano: affiancate diventerebbero tre colonne da
     nulla, con l'icona più grande del testo che la spiega. */
  .ways{grid-template-columns:1fr}
  .way-env{min-height:46vh}
  .say-stage,.qr-stage .steps{width:auto}
  /* Su schermo stretto tre colonne renderebbero ogni elemento illeggibile:
     il confronto si impila. */
  .multi{grid-auto-flow:row;grid-auto-rows:1fr;grid-auto-columns:auto}
  .head-actions{flex-wrap:wrap;justify-content:flex-end}
}
/* Schermi molto larghi e bassi (75" in 21:9 o barra di sistema visibile) */
@media(min-aspect-ratio:2/1){
  :root{--t-hero:clamp(48px,4.4vw,110px);--t-h2:clamp(30px,2.5vw,60px)}
}

/* ═══ Consegna dell'immagine (modale + tastiera a schermo) ═════════════════
   Sul monitor dello showroom non c'è tastiera fisica: il campo email è
   `readonly` e si compila con la tastiera qui sotto, così non compare quella
   di sistema e i tasti restano grandi abbastanza per il dito. */
.modal{
  position:fixed;inset:0;z-index:90;
  display:grid;place-items:center;
  background:rgba(29,29,27,.86);backdrop-filter:blur(10px);
  padding:var(--pad-y) var(--pad-x);
  animation:rise .35s var(--ease) both;
}
.modal-card{
  position:relative;
  width:min(1280px,100%);max-height:100%;overflow-y:auto;
  background:var(--panel);border:1px solid var(--line-2);
  padding:clamp(20px,1.8vw,42px);
  box-shadow:var(--shadow);
}
.modal-x{position:absolute;top:clamp(14px,1.1vw,22px);right:clamp(14px,1.1vw,22px)}
.modal-card h2{margin-bottom:clamp(14px,1.2vw,26px)}

.deliver-grid{
  display:grid;grid-template-columns:clamp(280px,26vw,420px) 1fr;
  gap:clamp(24px,2.4vw,56px);align-items:start;
}
.dl-col{display:flex;flex-direction:column;min-width:0}
.dl-col .qr-frame{align-self:center}
.dl-col .steps{margin-top:clamp(14px,1.2vw,24px)}

.f{display:block;font-size:var(--t-micro);letter-spacing:.2em;text-transform:uppercase;
  color:var(--muted);margin:0 0 10px}
#dlEmail{
  width:100%;min-height:var(--tap);padding:0 clamp(16px,1.2vw,24px);
  background:var(--void);border:1px solid var(--line-2);color:var(--ink);
  font:inherit;font-size:var(--t-lede);border-radius:0;
  caret-color:var(--brass);
}
#dlEmail::placeholder{color:var(--faint)}
#dlEmail.filled{border-color:var(--brass)}

.consent{display:flex;gap:14px;align-items:flex-start;margin:clamp(16px,1.3vw,26px) 0 0;cursor:pointer}
.consent input{
  appearance:none;-webkit-appearance:none;flex:0 0 auto;
  width:clamp(28px,2vw,36px);height:clamp(28px,2vw,36px);margin:0;
  border:1px solid var(--line-2);background:var(--void);cursor:pointer;transition:.2s var(--ease);
}
.consent input:checked{background:var(--brass);border-color:var(--brass)}
.consent input:checked::after{
  content:'✓';display:grid;place-items:center;height:100%;
  color:var(--on-accent);font-size:clamp(17px,1.3vw,23px);
}
.consent span{font-size:var(--t-small);color:var(--ink-2);line-height:1.5}
.privacy{margin:clamp(10px,.8vw,16px) 0 0;font-size:var(--t-micro);color:var(--faint);line-height:1.55}

/* Tastiera a schermo */
.kbd{display:flex;flex-direction:column;gap:clamp(5px,.42vw,9px);margin:clamp(12px,1vw,20px) 0}
.kbd .row{display:flex;gap:clamp(6px,.5vw,10px);justify-content:center}
.kbd button{
  flex:1 1 0;min-width:0;
  min-height:clamp(44px,3.0vw,58px);
  background:var(--panel-2);border:1px solid var(--line);color:var(--ink);
  font:inherit;font-size:var(--t-body);border-radius:0;
  transition:.12s var(--ease);
}
.kbd button:hover{border-color:var(--line-2)}
.kbd button:active{background:var(--brass);color:var(--on-accent);border-color:var(--brass);transform:scale(.96)}
.kbd button.wide{flex:2 1 0;font-size:var(--t-small);letter-spacing:.06em}
.kbd button.act{color:var(--brass-2);border-color:var(--brass-dim)}

.dl-msg{margin:clamp(12px,1vw,20px) 0 0;font-size:var(--t-small);min-height:1.6em;text-align:center;color:var(--muted)}
.dl-msg.ok{color:var(--brass-2)}
.dl-msg.err{color:#F3A9A9}

@media(max-width:1200px){
  .deliver-grid{grid-template-columns:1fr}
}

/* Consenso mancante: la spunta si segnala da sola invece di lasciare
   l'utente a cercare il motivo del rifiuto in un messaggio piccolo. */
.consent.manca input{border-color:#E58A8A;animation:scuoti .4s var(--ease)}
.consent.manca span{color:#F3A9A9}
@keyframes scuoti{0%,100%{transform:translateX(0)}25%{transform:translateX(-5px)}75%{transform:translateX(5px)}}

/* ═══ Ingrandimento del render ═════════════════════════════════════════════
   Il render a tutto schermo, con pizzico e trascinamento: sul 75" è l'unico
   modo di giudicare una venatura da vicino senza avvicinarsi al monitor.
   `touch-action:none` sul palco perché i gesti li governa il JS. */
.zoom{
  position:fixed;inset:0;z-index:95;
  display:flex;flex-direction:column;
  /* Fondo pieno, non un velo: qui si guarda un'immagine, e l'interfaccia
     che traspare dietro ne falsa il giudizio. */
  background:var(--void);
  animation:rise .3s var(--ease) both;
}
.zoom-stage{
  flex:1;min-height:0;position:relative;overflow:hidden;
  display:grid;place-items:center;touch-action:none;
}
.zoom-stage img{
  max-width:100%;max-height:100%;width:auto;height:auto;
  transform-origin:center center;will-change:transform;
  -webkit-user-drag:none;
}
.zoom-bar{
  flex:0 0 auto;
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  gap:clamp(10px,.9vw,20px);
  padding:clamp(10px,.9vw,22px) var(--pad-x);
  border-top:1px solid var(--line);background:var(--void);
}
.zoom-ctl{display:flex;align-items:center;gap:clamp(8px,.7vw,16px);justify-self:center}
.zoom-val{min-width:5ch;text-align:center;font-size:var(--t-small);color:var(--ink-2);letter-spacing:.1em}
.zoom-hint{justify-self:start;font-size:var(--t-micro);color:var(--faint);letter-spacing:.06em}
#zoomClose{justify-self:end}
@media(max-width:900px){.zoom-hint{display:none}}

/* ═══ Modalità finestra (html:not(.kiosk)) ═════════════════════════════════
   Il layout a viewport fissa — pagina che non scorre, pannelli nel campo
   visivo, catalogo a pagine — è quello del totem, che gira SEMPRE a tutto
   schermo: PWA installata (display: fullscreen nel manifest), F11, Chrome
   --kiosk. La classe `kiosk` la mette app.js leggendo display-mode, e si
   forza con `?kiosk` nell'URL per provare il totem in una finestra.
   Fuori da lì — una finestra di browser qualsiasi, per la demo dal
   portatile — la pagina torna un documento che scorre: un layout a
   viewport fissa in una finestra bassa comprime i pannelli fino a
   romperli. Sul totem vero non si entra mai in questo ramo. */
html:not(.kiosk) body{overflow:auto}
html:not(.kiosk) #app{height:auto;min-height:100dvh;overflow:visible}
/* La barra resta a portata di mano mentre la pagina scorre. */
html:not(.kiosk) .topbar{position:sticky;top:0}
html:not(.kiosk) .screen{position:relative;overflow:visible}
/* La home resta una copertina: riempie quasi tutta la finestra anche
   quando il contenuto è poco (150px ≈ la barra in alto). */
html:not(.kiosk) .screen[data-step="home"]{min-height:calc(100dvh - 150px)}
/* Niente più altezze «che avanzano»: ogni blocco è alto quanto il contenuto.
   Le tessere della home e le vetrine delle icone, che sul totem si prendono
   lo spazio che avanza, qui devono dichiarare un'altezza propria. */
html:not(.kiosk) .ways,html:not(.kiosk) .studio,html:not(.kiosk) .result-wrap,
html:not(.kiosk) .qr-stage,html:not(.kiosk) .say-stage,
html:not(.kiosk) .env-grid,html:not(.kiosk) .slab-wrap,html:not(.kiosk) .surf-list{flex:none;min-height:0}
html:not(.kiosk) .ways{grid-auto-rows:minmax(clamp(380px,56vh,620px),auto)}
html:not(.kiosk) .way-icon{min-height:clamp(150px,22vh,280px)}
html:not(.kiosk) .way-say .way-icon svg{max-width:clamp(240px,30vw,620px)}
html:not(.kiosk) .env-grid,html:not(.kiosk) .slab-grid,html:not(.kiosk) .surf-list,
html:not(.kiosk) .result-side,html:not(.kiosk) .result-info{overflow:visible}
/* Catalogo intero, a scorrimento: colonne automatiche, niente pagine e
   niente gutter per le frecce (che qui non compaiono mai). */
html:not(.kiosk) .slab-wrap{grid-template-columns:minmax(0,1fr)}
html:not(.kiosk) .slab-grid{grid-column:1;grid-template-columns:repeat(auto-fill,minmax(clamp(150px,11.5vw,250px),1fr))}
html:not(.kiosk) #envDesc{min-height:7em}
/* Il palco delle immagini non ha più un'altezza «che avanza»: gliene
   serve una sua, abbastanza generosa da giudicare un render. */
html:not(.kiosk) .canvas-hold{min-height:56vh}
html:not(.kiosk) .compare{min-height:56vh}

/* ═══ 1a-bis · Progetti realizzati ═════════════════════════════════════ */
/* La striscia sotto i sei ambienti: annuncia i progetti veri e li apre.
   Sul totem cede altezza alla griglia (righe elastiche): un'unica riga. */
.proj-strip{
  flex:0 0 auto;margin-top:var(--gap);
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;
  gap:clamp(16px,1.5vw,40px);
  padding:clamp(10px,.9vw,20px) clamp(16px,1.4vw,32px);
  background:var(--panel);border:1px solid var(--line);color:var(--ink);text-align:left;
  cursor:pointer;transition:.3s var(--ease);border-radius:0;font:inherit;
}
.proj-strip:hover{border-color:var(--brass)}
.proj-strip:active{transform:scale(.995)}
.ps-text{display:flex;flex-direction:column;gap:3px;min-width:0}
.ps-t{font-family:var(--font-display);font-size:var(--t-h3);line-height:1.1;color:var(--ink)}
.ps-s{font-size:var(--t-small);color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ps-covers{
  display:flex;gap:clamp(6px,.5vw,10px);justify-content:center;min-width:0;overflow:hidden;
  height:clamp(54px,4.4vw,100px);
}
.ps-covers img{height:100%;width:auto;aspect-ratio:4/3;object-fit:cover;opacity:.85;border:1px solid var(--line);flex:0 0 auto}
.proj-strip .cta{flex:0 0 auto}

/* La griglia dei progetti (o delle foto di un progetto), a pagine fra due
   gutter con le frecce: stessa meccanica del catalogo. */
.proj-wrap{
  flex:1;min-height:0;
  display:grid;grid-template-columns:var(--pg) minmax(0,1fr) var(--pg);
  gap:clamp(8px,.8vw,20px);
}
.proj-grid{
  grid-column:2;min-height:0;overflow-y:auto;touch-action:pan-y;
  display:grid;grid-template-columns:repeat(var(--cols,5),minmax(0,1fr));
  grid-auto-rows:max-content;gap:var(--gap);align-content:start;
}
.proj{
  position:relative;margin:0;border:1px solid var(--line);background:var(--void-2);
  overflow:hidden;cursor:pointer;transition:.35s var(--ease);
  aspect-ratio:4/3;animation:pop .5s var(--ease) both;
}
.proj img{width:100%;height:100%;object-fit:cover;opacity:.85;transition:transform .8s var(--ease)}
.proj:hover{border-color:var(--brass)}
.proj:hover img{transform:scale(1.05);opacity:1}
.proj:active{transform:scale(.99)}
.proj figcaption{
  position:absolute;left:0;right:0;bottom:0;
  padding:clamp(22px,2vw,40px) clamp(10px,.8vw,18px) clamp(8px,.7vw,14px);
  background:linear-gradient(180deg,transparent,rgba(29,29,27,.92));
}
.proj .nm{
  font-family:var(--font-display);font-size:var(--t-h3);line-height:1.1;color:var(--ink);
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;overflow-wrap:anywhere;
}
/* Nome lunghissimo («Ambiente Diamond Cristallo Macchiavecchia Polished
   Starlit»): tre righe fitte, come per gli elementi (fitNames). */
.proj .nm.l3{-webkit-line-clamp:3;line-height:1}
.proj .rm{font-size:var(--t-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--brass);margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* In finestra: tutto l'elenco, a scorrimento, senza gutter. */
html:not(.kiosk) .proj-wrap{grid-template-columns:minmax(0,1fr);flex:none;min-height:0}
html:not(.kiosk) .proj-grid{grid-column:1;grid-template-columns:repeat(auto-fill,minmax(clamp(180px,14vw,300px),1fr));overflow:visible}
html:not(.kiosk) .proj-strip{margin-top:var(--gap)}

/* ═══ Smartphone e tablet ══════════════════════════════════════════════════
   Sotto i 900 px (telefono, tablet in verticale) l'app è un DOCUMENTO CHE
   SCORRE: app.js toglie `kiosk` (syncKiosk), quindi qui valgono anche le
   regole di «Modalità finestra» qui sopra. Si ridimensionano tipo, ritmo e
   bersagli (≥ 44 px), ogni schermata si mette in colonna, nulla sborda in
   orizzontale. Il totem (≥ 1200 px, landscape) non passa mai di qui.
   Le parti del flusso a più ambiti (tessere, vassoio, note) sono in
   ambiti.css, nello stesso punto di rottura. */
@media(max-width:900px){
  :root{
    --t-hero:clamp(30px,7.5vw,48px);--t-h2:clamp(24px,5.4vw,34px);--t-h3:clamp(17px,3.8vw,20px);
    --t-lede:16px;--t-body:15px;--t-small:13px;--t-micro:11px;
    --pad-x:16px;--pad-y:16px;--gap:12px;
    --tap:52px;--tap-s:44px;--dot:26px;--t-step:12px;
  }
  /* A scorrere è il VIEWPORT (overflow sull'html), non il body: con
     `overflow` su entrambi il body diventa un contenitore a sé, e lo
     scrollTo(0,0) di go() al cambio di schermata non farebbe nulla. */
  html{overflow-x:hidden;overflow-y:auto}
  html:not(.kiosk) body{overflow:visible;height:auto;min-height:100%}
  body{line-height:1.6}
  /* Entrata in sola dissolvenza: `rise` anima `transform`, e un antenato con
     transform (anche a fine animazione, con fill both) diventa il riferimento
     degli elementi `position:fixed` — il vassoio finiva in fondo al
     documento invece che in fondo allo schermo. */
  .screen.active{animation-name:fadein}
  @keyframes fadein{from{opacity:0}to{opacity:1}}

  /* Barra su due righe: marchio e comandi sopra, i quattro passi (soli
     numeri) sotto — su una riga sola non ci starebbero. */
  .topbar{
    grid-template-columns:auto 1fr;grid-template-areas:"mark tools" "steps steps";
    gap:6px 12px;padding:8px var(--pad-x) 4px;
  }
  .topbar .mark{grid-area:mark;height:24px}
  .tools{grid-area:tools;gap:8px}
  .progress{grid-area:steps;display:grid;justify-self:center;align-self:auto;width:auto}
  .node{padding:0 12px;gap:0;min-height:44px;justify-content:center}
  .node .lb{display:none}
  .node + .node::before{top:50%;left:calc(-50% + var(--dot) / 2 + 4px);right:calc(50% + var(--dot) / 2 + 4px)}
  .node.now .dot{background:var(--brass);color:var(--on-accent)}
  .scope-btn{width:44px;min-width:44px;max-width:44px;padding:0;justify-content:center;gap:0}
  .scope-btn .sb-ic{width:1.6em;height:1.6em}
  .scope-btn .sb-lb,.scope-btn .sb-x{display:none}
  .lang-cur{padding:0 10px;gap:4px}
  .toast{top:100px}

  /* Palco e testate */
  .screen{padding:14px var(--pad-x) var(--pad-y)}
  .screen-head{margin-bottom:14px}
  .screen-head.row{flex-direction:column;align-items:stretch}
  .head-actions{flex-wrap:wrap;justify-content:flex-start;gap:8px}
  .search{width:100%}
  .eyebrow{margin-bottom:8px}
  .sub{margin-top:6px}
  .hint{margin-top:12px}
  .home-head{margin-bottom:12px}
  .home-head h1{font-size:var(--t-hero)}
  .home-sub{font-size:var(--t-body);margin-top:6px}
  html:not(.kiosk) .screen[data-step="home"]{min-height:0}

  /* Home: le tre strade in colonna, compatte (vetrina 200 px, icone piccole). */
  html:not(.kiosk) .ways{grid-auto-rows:auto;gap:12px}
  .way{padding:16px}
  .way-env{min-height:200px}
  .way-body{padding:16px}
  html:not(.kiosk) .way-icon{min-height:0;padding:6px 0 10px}
  .way-qr .way-icon svg{width:64px}
  html:not(.kiosk) .way-say .way-icon svg{max-width:220px}
  .way-t{font-size:22px}
  .way-s,.way-note{font-size:var(--t-small)}
  .way-note{margin-top:8px}
  .way .cta{margin-top:14px;min-height:48px}

  /* Modelli: due colonne (la <figure> perde i margini UA di 40 px). */
  html:not(.kiosk) .env-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .env{margin:0}
  .env figcaption{padding:22px 10px 10px}
  .env .nm{font-size:15px}
  .env .rm{margin-top:3px}

  /* QR (finestra stretta senza telefono) e scatto/galleria. */
  .qr-stage{gap:14px}
  .qr-stage .steps{flex-direction:column;gap:0}
  .up-btn{min-height:76px}

  /* Descrizione */
  html:not(.kiosk) #envDesc{min-height:8em;padding-right:72px}
  .dictate{min-width:56px}
  .say-stage .cta.wide{margin-top:12px}

  /* Studio: foto a tutta larghezza, alta quanto la foto (--ar), zone come
     chip che scorrono in orizzontale, lazo col dito (touch-action:none sul
     canvas, già nella regola base). */
  html:not(.kiosk) .studio{gap:14px;overflow:visible}
  html:not(.kiosk) .canvas-hold{min-height:0;aspect-ratio:var(--ar,4/3);max-height:48vh}
  .lasso-hint{white-space:normal;max-width:calc(100% - 24px);text-align:center;font-size:var(--t-micro);padding:8px 12px;bottom:10px}
  .clear-lasso{min-height:44px;top:10px;right:10px}
  .ai-base-note{top:10px;left:10px}
  .thumbs img{height:60px}
  .side h2{font-size:var(--t-h2)}
  html:not(.kiosk) .surf-list{
    display:flex;flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;gap:8px;margin:12px 0;padding-bottom:4px;
    scrollbar-width:none;-webkit-overflow-scrolling:touch;
  }
  .surf-list::-webkit-scrollbar{display:none}
  .surf{flex:0 0 auto;min-height:44px;padding:10px 16px;white-space:nowrap;font-size:var(--t-small)}
  .surf-wait{flex:0 0 auto}
  .scope-row .opt-chips{grid-template-columns:1fr 1fr}

  /* Catalogo: tre colonne (due sotto i 600 px), niente pagine. */
  .filters{margin-bottom:12px}
  .fsel{gap:8px}
  .fbtn,.chip{min-height:44px;padding:0 14px}
  .search .q{min-height:44px}
  .search .x{min-width:44px}
  html:not(.kiosk) .slab-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
  .slab .meta{padding:10px}
  .slab .cl{margin-top:4px}
  .note-bar{margin-bottom:12px;padding:10px 12px}
  .pg-btn{display:none}

  /* Modali (indicazioni, consegna) a tutto schermo. */
  .modal{padding:0;place-items:stretch;overflow:hidden}
  .modal-card{
    width:100%;max-height:100dvh;min-height:100dvh;border:0;overflow-y:auto;
    padding:20px var(--pad-x) calc(20px + env(safe-area-inset-bottom));
  }
  .modal-x{top:10px;right:10px}
  .modal-card .eyebrow,.modal-card h2{padding-right:52px}
  .modal-card h2{margin-bottom:10px}
  .deliver-grid{gap:20px}
  .dl-col .steps{margin-top:10px}
  .consent{margin-top:14px}
  #dlEmail{min-height:52px;font-size:16px}

  /* Risultato: immagine sopra (alta quanto la foto), pannello sotto.
     Il palco lascia scorrere la pagina (pan-y): la maniglia no. */
  html:not(.kiosk) .result-wrap{gap:12px;overflow:visible}
  html:not(.kiosk) .compare{min-height:0;aspect-ratio:var(--ar,4/3);max-height:58vh;touch-action:pan-y}
  html:not(.kiosk) .compare.multi-on{aspect-ratio:auto;max-height:none;min-height:70vh}
  .cmp-handle{touch-action:none}
  .cmp-tag{top:10px;padding:5px 9px}
  .cmp-tag.left{left:10px}
  .cmp-tag.right{right:10px}
  .stage-zoom{width:44px;height:44px;right:10px;bottom:10px}
  .back-multi{min-height:44px;top:10px}
  .mpane .mx{width:44px;height:44px}
  .tip{bottom:10px;padding:8px 12px;max-width:92%}
  .gen-inner{padding:0 var(--pad-x)}
  .vers{gap:10px}
  .vth{width:96px;min-width:72px}
  .result-side h2{font-size:var(--t-h2)}
  .result-actions{gap:8px;padding-top:12px}
  .act-tile{min-height:84px}
  .zoom-bar{padding:10px var(--pad-x)}
}

/* Telefono vero e proprio: due colonne di catalogo, tessere di scelta
   dell'ambito come righe (ambiti.css). */
@media(max-width:600px){
  html:not(.kiosk) .slab-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .specs{column-gap:10px}
  .deliver-grid{grid-template-columns:1fr}
}

/* Tablet largo e portatile (900–1200 px) in modalità totem: le colonne si
   sono già impilate (vedi «Adattamenti»); qui solo i bersagli e le griglie
   che altrimenti resterebbero troppo fitte. */
@media(min-width:901px) and (max-width:1200px){
  html.kiosk .env-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .fbtn,.chip{min-height:44px}
}
