/* La palette del marchio swaipe.me: fondo NERO, pannelli viola scurissimo, giallo
   per l'azione principale e l'arcobaleno del logo come unico lusso. I valori
   vengono dal Figma; le misure no — quelle restano le nostre, verificate a 390 e a
   1280, perché le posizioni esportate da Figma sono assolute e non responsive.
   I nomi dei token sono rimasti quelli di prima: così tutto il foglio, che già li
   usava, ha cambiato aspetto senza cambiare regole. */
:root {
  /* ⚠ Il sito è SEMPRE scuro, e il browser deve saperlo: con `color-scheme: dark` i
     controlli nativi (il menu di un <select>, le barre di scorrimento, il cursore)
     si disegnano scuri. Senza, un menu a tendina aperto usciva bianco su nero. */
  color-scheme: dark;

  --bg: #000000;
  --card: #15051F;          /* i pannelli: il form, il listino, i fogli che salgono */
  --surface: #3D3045;       /* le celle del form, le domande frequenti */
  --line: rgb(255 255 255 / .18);
  --text: #FFFFFF;
  --muted: #AE9FB6;
  --primary: #F4D755;       /* il giallo: "Genera", il bordo del prompt */
  --primary-fg: #000000;
  --err: #FF3E41;           /* il rosso del logo: su nero si legge, #e40014 no */
  --ring: #AE9FB6;
  --orange: #FE6220;
  /* Il ripiano di un elemento che si tocca: su un fondo nero un grigio chiaro fisso
     (#f5f5f5, com'era) diventerebbe un rettangolo abbagliante sotto al dito. */
  --hover: rgb(255 255 255 / .08);

  /* L'arcobaleno del logo, in due forme: in riga per le fasce, a giro per i bordi. */
  --spectrum: linear-gradient(90deg, #FF3E41, #FD9D51, #F4D755, #29DD76, #2B8EFF, #B987F4);
  --spectrum-giro: conic-gradient(from 200deg, #2B8EFF, #29DD76, #F4D755, #FD9D51, #FF3E41, #B987F4, #2B8EFF);

  --f-display: 'Unbounded', 'Arial Black', system-ui, sans-serif;
  --f-body: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
  --f-mono: 'Fragment Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  --radius: .625rem;                          /* 10px */
  --radius-sm: calc(var(--radius) - 2px);     /* controlli piccoli */
  --radius-lg: calc(var(--radius) + 4px);     /* le schede */

  /* Larghezza di una scheda e del nastro che la contiene: dalla differenza fra le
     due nasce lo spiraglio sulle schede vicine. Su desktop va stretto anche il
     nastro, non solo la scheda, altrimenti nella finestra ne entrano quattro. */
  --cardw: min(90vw, 400px);
  --deckw: 100vw;
}

/* Il display: none dell'attributo hidden perde contro qualsiasi classe che dichiari
   un display proprio: .tokenbar e .actions sono entrambe flex. Vale per tutta la pagina. */
[hidden] { display: none !important; }

* { box-sizing: border-box; }
svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Mobile first: una schermata sola. Si scorre di lato, mai in verticale. */
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.5 var(--f-body), "Apple Color Emoji", "Segoe UI Emoji";
  -webkit-font-smoothing: antialiased;
}

/* ---- barra in alto ---- */
.topbar { flex: none; background: var(--card); border-bottom: 1px solid var(--line); padding: .8rem 1rem .9rem; }
.bar-inner, .payoff, .composer, .hint, .tokenbar { max-width: 620px; margin-left: auto; margin-right: auto; }
.bar-inner { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0; }

.brand { display: inline-block; line-height: 0; color: var(--text); text-decoration: none; }
.brand span { color: var(--muted); }
/* Il logo in pagina: l'immagine è 999×392, se ne fissa l'altezza e la larghezza
   segue. */
.brand-logo { display: block; height: var(--logo-h); width: auto; }

/* Nascosto alla vista, presente per chi legge con un lettore di schermo. */
.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.payoff { margin: .2rem auto .8rem; font-size: .875rem; color: var(--muted); }

/* Il modulo è una frase, non tre controlli affiancati: i menu e il campo sono
   parole riempite dentro il testo. Le scatole sparite non sono un vezzo — con i
   bordi la frase si leggeva come un elenco e la riga si spezzava dove capitava. */
.composer { display: flex; flex-direction: column; gap: .8rem; }

.say {
  margin: 0;
  /* ⚠ Righe VERE, una per clausola, invece di lasciarle andare a capo da sole: solo
     così i controlli di coda — la foto, la sagoma, la foto di stile — possono stare
     tutti sullo stesso bordo destro. A capo libero ogni riga finiva dove capitava. */
  display: flex; flex-direction: column; align-items: stretch;
  gap: .2rem .55rem;
  /* Larghezza e altezza dei controlli di coda: una sola, o non si allineano. */
  --coda: 9.5rem;
  --coda-h: 2.3rem;
  font-size: clamp(1.15rem, 4.4vw, 1.45rem);
  line-height: 1.9;
  color: var(--text);
  letter-spacing: -.015em;
}

/* I connettivi in corsivo: si distinguono a colpo d'occhio da ciò che si sceglie. */
.say em { font-style: italic; font-weight: 400; color: var(--muted); }

/* Un connettivo e il suo controllo vanno a capo insieme, mai separati. */
.clause { display: flex; align-items: center; gap: .35rem; white-space: nowrap; width: 100%; }
/* Il menu si prende lo spazio che avanza, così ciò che lo segue finisce a destra. */
.clause select { flex: 1 1 auto; min-width: 0; }
/* ⚠ `flex: none` e non `1 1 13rem`: da quando `.say` è una COLONNA il flex-basis non
   è più una larghezza ma un'ALTEZZA, e quelle 13rem diventavano 208 px di riga vuota
   sotto al campo. In una colonna l'altezza la deve fare il contenuto. */
.subject { flex: none; min-width: 0; white-space: normal; flex-wrap: wrap; row-gap: .35rem; }
/* ⚠ "of" si prende una riga tutta sua (`flex-basis: 100%`), e campo e foto si
   dividono quella sotto. Serve perché `.say input` è `width: 100%`: lasciato com'era
   si mangiava la riga intera e spingeva la foto fuori dallo schermo del telefono.
   Il campo si accorcia quanto basta — `flex: 1 1 6rem` — invece di far scendere la
   foto sotto: sono due parti della stessa frase e si leggono insieme. */
/* ⚠ "with" non sta più qui dentro forzato a capo dal flex: chiude la clausola del
   prodotto, nell'HTML. Andava a capo solo finché la riga era piena, e bastava un
   cambio di larghezza perché risalisse. Il posto giusto per una parola è la frase. */

/* Il soggetto è l'unica parte che si SCRIVE, e ha un riquadro suo con i comandi
   della foto dentro. Le altre clausole sono menu e restano parole sottolineate.
   ⚠ Il bordo sta sul CONTENITORE, non sul campo: è quello che fa sembrare i due
   pulsanti parte della casella invece che due cose appoggiate accanto. */
.prompt-box {
  flex: 1 1 10rem; min-width: 0;
  display: flex; align-items: center; flex-wrap: wrap; gap: .3rem;
  padding: .25rem .3rem .25rem .7rem;
  border: 1px solid var(--line); background: var(--card);
  /* ⚠ Non 999px: il riquadro va a capo quando lo schermo è stretto, e una pillola
     su due righe diventa uno stadio. Con 1,25rem sembra una pillola su una riga e
     una casella arrotondata su due. */
  border-radius: 1.25rem;
  transition: border-color .12s ease;
}
.prompt-box:hover { border-color: var(--ring); }
.prompt-box:focus-within { border-color: var(--primary); }
/* Dentro al riquadro il campo non ha più una sua riga: la farebbe il bordo due volte. */
/* ⚠ Base 14rem, non 4: è la larghezza sotto la quale il campo si stringerebbe
   troppo per leggere quello che si è scritto. Sopra, campo e pulsanti stanno in
   riga; sotto, i pulsanti scendono sulla riga dopo DENTRO lo stesso riquadro,
   invece di spremere il testo in tre parole visibili. */
.say .prompt-box input {
  width: auto; flex: 1 1 14rem; min-width: 0;
  border-bottom: 0; padding: .25rem 0; font-size: .95em;
}
/* ⚠ Il pulsante dentro al riquadro è largo `--coda` MENO l'imbottitura del
   riquadro: così il suo bordo destro cade dove cade quello degli altri due, che
   stanno fuori da qualunque riquadro. */
.prompt-box .foto-cta { flex: 0 0 auto; margin-left: auto; }
.prompt-box .foto-pick { width: calc(var(--coda) - .6rem); justify-content: center; }
.say .prompt-box input:hover, .say .prompt-box input:focus { border-bottom-color: transparent; }

/* ---- il selettore a forme ---- */
/* Le forme al posto dei nomi: "shaped like Stella" si legge, ma una stella si
   riconosce prima. Le icone le disegna il server con la maschera vera
   (GET /api/v1/images/shapes/{id}/icon.png), quindi l'icona è il ritaglio. */
.shape-pick { position: relative; display: inline-flex; flex: none; }
.shape-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .3rem;
  width: var(--coda); height: var(--coda-h); padding: 0 .6rem;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); cursor: pointer; line-height: 0;
}
.shape-btn:hover { border-color: var(--ring); }
.shape-btn img { width: 22px; height: 22px; display: block; }
.shape-btn svg {
  width: 13px; height: 13px; fill: none; stroke: var(--muted);
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
/* Il pannello: una griglia di forme, non un elenco di parole. */
.shape-menu {
  /* ⚠ Ancorato a DESTRA: il selettore sta in fondo alla riga dello stile, e un
     pannello che cresce verso destra usciva dallo schermo. Crescendo a sinistra
     resta dentro, perché a sinistra c'è tutta la frase. */
  position: absolute; z-index: 30; top: calc(100% + .35rem); right: 0;
  display: grid; grid-template-columns: repeat(6, 1fr); gap: .15rem;
  width: max-content; max-width: min(21rem, 88vw); padding: .35rem;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 12px 28px -12px rgb(10 10 10 / .4);
}
/* ⚠ Nell'editor il pannello si apre verso l'ALTO. Il modulo AI sta in fondo alla
   finestra dell'editor, che ha un'altezza sua e ritaglia quello che esce: aprendo
   verso il basso le forme finivano tagliate a metà. Sopra c'è tutto il resto del
   modulo, quindi lo spazio c'è. È una classe e non `#ed-shape-menu` perché il
   selettore è parametrico (`shapePicker`): il giorno che ne compare un terzo in
   fondo a un pannello, si aggiunge `su` nell'HTML e basta. */
.shape-menu.su { top: auto; bottom: calc(100% + .35rem); }
.shape-opt {
  display: grid; place-items: center; gap: .1rem;
  width: 3rem; padding: .3rem .15rem;
  border: 1px solid transparent; border-radius: var(--radius-sm);
  background: none; cursor: pointer;
}
.shape-opt:hover { background: var(--bg); }
.shape-opt.on { border-color: var(--primary); }
.shape-opt img { width: 24px; height: 24px; display: block; }
/* Il nome resta sotto, piccolo: le forme dicono tutto a chi guarda, niente a chi
   ascolta, e "Sole" e "Fiore" a occhio si somigliano. */
.shape-opt span {
  font: inherit; font-size: .5625rem; font-weight: 500; line-height: 1.1;
  color: var(--muted); text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.shape-opt.on span { color: var(--text); }

/* Parole sottolineate, non caselle. */
.say input, .say select {
  font: inherit; font-weight: 600; letter-spacing: inherit;
  color: var(--text); background: transparent;
  border: 0; border-bottom: 2px solid var(--line); border-radius: 0;
  padding: 0 .05rem .1rem; min-width: 0;
  transition: border-color .12s ease;
}
.say input { flex: 1 1 auto; width: 100%; }
.say input::placeholder { font-weight: 400; font-style: italic; color: var(--muted); }
.say input:hover, .say select:hover { border-bottom-color: var(--ring); }
.say input:focus, .say select:focus {
  outline: none; border-bottom-color: var(--primary); box-shadow: none;
}

/* appearance: none toglie anche la freccia, quindi la ridisegno: senza, un menu
   non si distingue da una parola qualunque della frase. */
.say select {
  cursor: pointer;
  appearance: none; -webkit-appearance: none;
  padding-right: 1.05em;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23737373' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .05em center; background-size: .62em;
}

.composer-actions { display: flex; gap: .5rem; }
.composer-actions .primary { flex: 1 1 auto; }
/* Da tablet in su il pulsante torna della sua larghezza: a tutta riga sembrerebbe
   una barra, non un pulsante. */
@media (min-width: 560px) { .composer-actions .primary { flex: 0 0 auto; } }

/* La foto DENTRO la frase, accanto a ciò che si scrive. È una e sta sempre lì: il
   filtro scelto le dà un significato, non la fa comparire e sparire.
   ⚠ `baseline` e non `center`: la frase è allineata alle basi delle lettere, e un
   pulsante centrato ci galleggerebbe in mezzo. */
/* ⚠ Due pulsanti SEPARATI, non uno diviso in due. Il pulsante unico sembrava più
   elegante ma si rompeva: nello stato "serve una foto" il contorno rosso correva
   attorno al contenitore E attorno alle due metà, e si vedevano tre linee dove ne
   serviva una. Separati, ognuno ha il suo bordo e non c'è niente da far combaciare.
   L'etichetta è UNA, sul primo: il secondo è lo stesso comando, dato in un altro
   modo, e ripetere la parola lo farebbe sembrare una funzione a parte. */
.foto-cta {
  display: inline-flex; align-items: center; gap: .3rem;
  min-width: 0; vertical-align: baseline; white-space: nowrap;
}
/* ⚠ `.foto-cta .foto-pick` e non `.foto-pick`: `.ghost` sta più in basso in questo
   foglio e porta il suo raggio da 10px — a parità di specificità vince l'ultima, e i
   due pulsanti uscivano squadrati mentre sagoma e foto di stile erano pillole. */
/* Due pulsanti di sola icona, tondi e uguali: sono due modi di dare la stessa cosa.
   Il nome di quella cosa lo dice l'etichetta accanto, una volta sola. */
.foto-cta .foto-pick, .foto-cta .foto-cam {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--coda-h); height: var(--coda-h); padding: 0; min-width: 0;
  border-radius: 999px;
  font-size: .8125rem; line-height: 1.2;
}
.foto-label {
  font-size: .8125rem; font-weight: 500; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
/* La miniatura prende il posto dell'icona, non le si affianca. */
.foto-pick img { width: 22px; height: 22px; flex: none; border-radius: 999px; object-fit: cover; }
.foto-cta.filled .foto-pick svg { display: none; }
/* Dentro al riquadro del prompt i pulsanti sono pieni, non fantasma: su un fondo
   bianco un contorno chiaro dentro un altro contorno chiaro sparisce. */
.prompt-box .foto-pick, .prompt-box .foto-cam {
  border-color: transparent; background: var(--bg);
}
.prompt-box .foto-pick:hover, .prompt-box .foto-cam:hover { background: var(--line); }
.foto-pick span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.foto-pick svg, .foto-cam svg {
  flex: none; width: 17px; height: 17px;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
/* "Serve una foto": il bordo dei pulsanti e l'etichetta, che è dove si legge cosa
   manca. */
.foto-cta.serve .foto-pick, .foto-cta.serve .foto-cam { border-color: var(--err); color: var(--err); }
.foto-cta.serve .foto-label { color: var(--err); }
/* A foto presente il nome non è più un promemoria ma una didascalia: si smorza. */
.foto-cta.filled .foto-label { color: var(--text); }
/* A foto caricata il pulsante si veste: si deve capire a colpo d'occhio che c'è,
   perché da qui in poi è quella che finisce in ogni filtro che chiede un'immagine. */
.foto-cta.filled .foto-pick { border-color: var(--primary); }
.foto-togli {
  flex: none; width: 1.5rem; height: 1.5rem; padding: 0;
  border: 0; border-radius: 999px; background: var(--bg); color: var(--muted);
  font-size: 1rem; line-height: 1; cursor: pointer;
}
.foto-togli:hover { background: var(--err); color: #fff; }
/* Le foto del filtro, accanto al menu del filtro. Stessa forma della CTA: sono la
   stessa cosa — un'immagine da caricare — e nella frase devono sembrarlo.
   Il riquadro tratteggiato alto 84px resta nell'EDITOR, dove c'è spazio. */
/* ⚠ `flex-basis: 100%`: dentro al riquadro del prompt la foto di stile deve stare
   sulla RIGA SOTTO a quella del viso, non accanto. In fondo a destra, sulla stessa
   colonna dell'altra. */
.filter-drops {
  display: flex; flex: 1 0 100%; gap: .3rem;
  justify-content: flex-end; align-items: center;
}
.filter-drops:empty { display: none; }
.filter-drops:empty { display: none; }
/* Esattamente la forma della foto accanto al prompt: il nome fuori a sinistra, poi
   due tondi di sola icona. Sono la stessa cosa — un'immagine da caricare — e nella
   frase devono sembrarlo. Il riquadro tratteggiato alto 84px resta nell'EDITOR. */
.drop-wrap { display: inline-flex; align-items: center; gap: .3rem; min-width: 0; }
.filter-drops .drop {
  flex: none; width: var(--coda-h); height: var(--coda-h); min-width: 0;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  border-style: solid; border-radius: 999px;
  font-size: .8125rem; line-height: 1.2; overflow: visible;
}
.filter-drops .drop svg { width: 17px; height: 17px; }
/* L'anteprima è una miniatura tonda dentro al pulsante, non il fondo del riquadro. */
.filter-drops .drop img {
  position: static; inset: auto; width: 22px; height: 22px;
  border-radius: 999px; flex: none;
}
/* ⚠ Il nome ora sta fuori: dentro al pulsante non ci deve stare niente oltre
   all'icona, o alla miniatura che la sostituisce. */
.filter-drops .drop span { display: none; }
.filter-drops .drop.filled svg { display: none; }
.filter-drops .drop.filled { border-color: var(--primary); }
/* La fotocamera è un pulsante accanto, non un bottoncino appoggiato sull'anteprima. */
.filter-drops .drop-scatta {
  position: static; flex: none;
  width: var(--coda-h); height: var(--coda-h); padding: .55rem;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--muted);
}
.filter-drops .drop-scatta:hover { border-color: var(--ring); color: var(--text); }
/* "Serve una foto", uguale a quello del viso: è la stessa generazione a chiederle. */
.drop-wrap.serve .foto-label { color: var(--err); }
.drop-wrap.serve .drop, .drop-wrap.serve .drop-scatta { border-color: var(--err); color: var(--err); }

/* L'anello di focus del sistema, per i campi che sono ancora caselle. */
.tokenbar input:focus {
  outline: none; border-color: var(--ring); box-shadow: 0 0 0 3px rgb(115 115 115 / .16);
}

.primary {
  flex: 0 0 auto; padding: .5rem 1rem; border: 1px solid transparent; border-radius: var(--radius);
  cursor: pointer; background: var(--primary); color: var(--primary-fg);
  font: inherit; font-size: .875rem; font-weight: 500;
  transition: opacity .12s ease;
}
.primary:hover:not(:disabled) { opacity: .9; }
.primary:disabled { opacity: .5; cursor: not-allowed; }

.tokenbar { display: flex; gap: .5rem; margin-top: .6rem; }
.tokenbar input {
  flex: 1 1 auto; min-width: 0; padding: .5rem .75rem; background: var(--card); color: var(--text);
  border: 1px solid var(--err); border-radius: var(--radius); font: inherit; font-size: .875rem;
}
.ghost {
  flex: none; background: var(--card); border: 1px solid var(--line); color: var(--text);
  border-radius: var(--radius); padding: .5rem .75rem; font: inherit; font-size: .875rem;
  font-weight: 500; cursor: pointer;
}
.ghost:hover { background: var(--hover); }

/* L'avviso sotto al modulo. Era testo grigio piccolo e non lo notava nessuno:
   ora è una pastiglia con l'icona, e il colore dice subito se è una conferma o un
   problema. Vale anche per i messaggi del carrello, che usano la stessa classe. */
/* ⚠ I messaggi sono un LIVELLO, non un paragrafo dentro il form.
   Stavano in cima alla colonna di sinistra: scorrendo sul nastro uscivano dallo
   schermo, e con l'editor aperto (z-index 80) finivano proprio dietro — "Aggiunto al
   carrello" non lo vedeva nessuno. Lo z-index sta sopra a tutto: editor (80),
   visore (70), carrello (60) e foglio di conferma.
   pointer-events: none perché un avviso che passa non deve mai intercettare un click. */
.hint {
  position: fixed; z-index: 95; pointer-events: none;
  top: calc(.9rem + env(safe-area-inset-top)); left: 50%; transform: translateX(-50%);
  max-width: min(520px, calc(100vw - 1.6rem));
  margin: 0; font-size: .8125rem; font-weight: 500; line-height: 1.4;
  display: inline-flex; align-items: flex-start; gap: .45rem;
  padding: .6rem .9rem; border-radius: 999px; text-align: left;
  background: var(--card); border: 1px solid var(--line); color: var(--text);
  box-shadow: 0 6px 22px rgb(10 10 10 / .16);
}
.hint:empty { display: none; }
.hint::before {
  content: 'i'; flex: none; width: 16px; height: 16px; margin-top: .1rem;
  border-radius: 50%; display: grid; place-items: center;
  font-size: .68rem; font-weight: 700; font-style: italic;
  background: var(--muted); color: var(--card);
}
.hint[data-kind="ok"] {
  background: #f0fdf4; border-color: #86efac; color: #14532d;
}
.hint[data-kind="ok"]::before { content: '✓'; background: var(--ok, #16a34a); font-style: normal; }
.hint[data-kind="bad"] {
  background: #fef2f2; border-color: #fca5a5; color: #7f1d1d;
}
.hint[data-kind="bad"]::before { content: '!'; background: var(--err, #dc2626); font-style: normal; }

/* Un avviso che compare senza muoversi si nota poco: un tocco di movimento basta. */
@media (prefers-reduced-motion: no-preference) {
  .hint:not(:empty) { animation: hint-in .22s ease-out both; }
  @keyframes hint-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
  }
}

/* ---- il mazzo di schede ---- */
.deck {
  flex: 1 1 auto; min-height: 0;
  display: flex; align-items: stretch; gap: .8rem;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  width: var(--deckw);
  margin-inline: auto;
  /* Il padding laterale centra anche la prima e l'ultima scheda: niente spaziatori finti. */
  padding: 1rem calc((var(--deckw) - var(--cardw)) / 2);
  scrollbar-width: none;
}
.deck::-webkit-scrollbar { display: none; }

/* Trascinare seleziona il testo delle didascalie e fa partire il drag nativo
   delle immagini: due gesti che qui non servono e che rompevano lo scorrimento. */
.deck { user-select: none; -webkit-user-select: none; }
.deck img { -webkit-user-drag: none; user-drag: none; }
.deck.dragging { cursor: grabbing; }

.card {
  flex: 0 0 var(--cardw);
  scroll-snap-align: center;
  display: flex; flex-direction: column; min-height: 0;
}

.frame {
  flex: 1 1 auto; min-height: 0; position: relative;
  background: #ffffff; border: 1px solid var(--line);
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: 0 1px 2px rgb(10 10 10 / .05);
}
.frame img { width: 100%; height: 100%; object-fit: contain; display: block; opacity: 0; transition: opacity .45s ease; }
.frame img.ready { opacity: 1; }

.skeleton { position: absolute; inset: 0; background: linear-gradient(100deg, #1d0f28 30%, #2c1c38 50%, #1d0f28 70%); background-size: 220% 100%; animation: sweep 1.4s linear infinite; }
@keyframes sweep { to { background-position: -220% 0; } }

.stage {
  position: absolute; bottom: .8rem; left: .8rem;
  font-size: .75rem; color: var(--muted);
  background: rgb(255 255 255 / .92); border: 1px solid var(--line);
  padding: .2rem .55rem; border-radius: 999px;
}

/* La matita sta SULL'immagine, in basso a destra: è un'azione su quella scheda,
   non una terza voce della barra in fondo, che resta a due sole scelte. */
/* L'unica azione rimasta sull'immagine: la lente. La matita è scesa fra i pulsanti. */
.zoom {
  position: absolute; right: .7rem; top: .7rem;
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: var(--card); border: 1px solid var(--line); color: var(--text);
  box-shadow: 0 1px 2px rgb(10 10 10 / .05);
}
.zoom:hover { background: var(--hover); border-color: var(--ring); }
.zoom svg { width: 17px; height: 17px; }

/* ---- il visore ---- */
.lightbox {
  /* Sopra al pannello del carrello (z-index 60): l'immagine si ingrandisce anche da
     lì dentro, e aprirsi dietro al pannello vorrebbe dire non aprirsi affatto. */
  position: fixed; inset: 0; z-index: 70;
  display: grid; place-items: center;
  padding: 1.5rem;
  background: rgb(10 10 10 / .88);
  /* Il fondo scuro qui non contraddice il tema chiaro: serve a togliere di mezzo
     la pagina, ed è quello che fa qualunque visore di immagini. */
}
.lightbox img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--radius-lg); }
.lightbox-close {
  position: absolute; top: 1rem; right: 1rem;
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: rgb(255 255 255 / .12); border: 1px solid rgb(255 255 255 / .25); color: #fff;
}
.lightbox-close:hover { background: rgb(255 255 255 / .22); }
.lightbox-close svg { width: 20px; height: 20px; }

.cap { flex: none; padding: .65rem .25rem 0; }
.cap-title { display: block; font-size: .875rem; font-weight: 500; letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cap-sub { display: block; font-size: .75rem; color: var(--muted); overflow-wrap: anywhere; }
.card.failed .cap-sub { color: var(--err); }

/* ---- le due azioni in fondo ---- */
.actions {
  flex: none; display: flex; justify-content: center; align-items: center; gap: 2rem;
  padding: .7rem 0 calc(.9rem + env(safe-area-inset-bottom));
}
.act {
  width: 60px; height: 60px; flex: none; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: var(--card); border: 1px solid var(--line);
  box-shadow: 0 1px 2px rgb(10 10 10 / .05);
  transition: transform .12s ease, opacity .12s ease, border-color .12s ease;
}
.act:active { transform: scale(.92); }
.act svg { width: 25px; height: 25px; stroke-width: 2; }

.act-skip { color: var(--err); }
.act-skip:hover { border-color: var(--err); }

/* La matita è l'azione di mezzo: neutra, perché non è né uno scarto né un acquisto. */
.act-edit { color: var(--text); }
.act-edit:hover { border-color: var(--ring); }

/* Il carrello è l'azione primaria: stesso trattamento del bottone "Genera". */
.act-cart { color: var(--primary-fg); background: var(--primary); border-color: transparent; }
.act-cart:hover { opacity: .9; }

/* Da tablet in su: stesso rapporto del telefono — una scheda al centro e appena
   uno spiraglio su quelle a fianco. La proporzione fra scheda e nastro resta ~90%. */
@media (min-width: 560px) {
  :root { --cardw: 420px; --deckw: 480px; }
}

/* ---- filtri: il pulsante, il modulo che cambia, il pannello ---- */
.filters-btn {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; gap: .35rem;
  padding: .5rem .75rem; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--card); color: var(--text); font: inherit; font-size: .875rem;
  font-weight: 500; cursor: pointer; white-space: nowrap;
}
.filters-btn:hover { background: var(--hover); }
.filters-btn svg { width: 16px; height: 16px; }

.filter-inputs { min-width: 0; display: flex; flex-direction: column; gap: .5rem; }

.chip {
  align-self: flex-start; display: inline-flex; align-items: center; gap: .4rem;
  padding: .3rem .4rem .3rem .7rem; border-radius: 999px;
  background: var(--primary); color: var(--primary-fg); font-size: .8125rem; font-weight: 500;
}
.chip button { display: grid; place-items: center; width: 20px; height: 20px; padding: 0;
  border: 0; border-radius: 50%; background: rgb(255 255 255 / .18); color: inherit; cursor: pointer; }
.chip svg { width: 12px; height: 12px; stroke-width: 2.5; }

/* Una casella per foto richiesta: quante ne servono si vede a colpo d'occhio. */
.drops { display: flex; gap: .5rem; flex-wrap: wrap; }
.drop {
  position: relative; flex: 1 1 8rem; min-width: 0; height: 84px;
  display: grid; place-items: center; gap: .15rem; align-content: center;
  border: 1px dashed var(--line); border-radius: var(--radius);
  background: var(--card); color: var(--muted); font-size: .75rem;
  text-align: center; padding: .4rem; cursor: pointer; overflow: hidden;
}
.drop:hover { border-color: var(--ring); color: var(--text); }
.drop svg { width: 18px; height: 18px; }
.drop img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.drop.filled { border-style: solid; }
/* A foto caricata restano solo i pixel: l'icona e l'etichetta sparirebbero sotto. */
.drop.filled svg, .drop.filled span { display: none; }

/* Il pulsante "scatta": sopra all'anteprima, o a foto caricata sparirebbe sotto i
   pixel insieme all'icona. Resta anche a riquadro pieno, perché rifare lo scatto è
   la cosa che si vuole fare più spesso subito dopo averlo fatto male. */
.drop-scatta {
  position: absolute; top: .3rem; right: .3rem; z-index: 1;
  width: 1.75rem; height: 1.75rem; padding: .25rem;
  display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--muted); cursor: pointer;
}
.drop-scatta svg {
  width: 100%; height: 100%; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linejoin: round;
}
/* ⚠ La regola qui sopra che nasconde le svg a riquadro pieno prenderebbe anche
   questa: la si riaccende, altrimenti resta un cerchio vuoto sopra la foto. */
.drop.filled .drop-scatta svg { display: block; }
.drop.filled .drop-scatta { background: rgb(255 255 255 / .92); color: var(--text); }

/* Etichetta sopra e non a fianco: "Il nuovo sfondo" accanto al campo non entra
   nella larghezza di un telefono. */
.field { display: flex; flex-direction: column; gap: .25rem; min-width: 0; font-size: .75rem; color: var(--muted); }
.field select, .field input {
  width: 100%; min-width: 0; padding: .5rem .75rem; background: var(--card); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius); font: inherit; font-size: .875rem;
}
.field select:focus, .field input:focus {
  outline: none; border-color: var(--ring); box-shadow: 0 0 0 3px rgb(115 115 115 / .16);
}
@media (max-width: 559px) { .field select, .field input { font-size: 16px; } }

/* Il pannello: a tutta pagina sul telefono, riquadro centrato da tablet in su. */
.sheet {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: end center;
  background: rgb(10 10 10 / .5);
}
.sheet-panel {
  width: 100%; max-width: min(760px, 100vw); max-height: 88dvh;
  display: flex; flex-direction: column;
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 1rem 1rem calc(1rem + env(safe-area-inset-bottom));
  /* Niente può sporgere dal pannello: sul telefono la riga dei tag è più larga
     dello schermo e senza questo trascinava con sé tutto il pannello. */
  overflow: hidden;
}
/* flex: none su tutto ciò che non scorre. In un flex in colonna lo shrink agisce
   sull'ALTEZZA: senza, quando le schede non ci stanno nel max-height il pannello
   comprime intestazione, tag e nota, e i pill dei tag si accartocciano. */
.sheet-head { flex: none; display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.sheet-head h2 { margin: 0; font-size: 1.125rem; font-weight: 600; letter-spacing: -.02em; }
.sheet-sub { margin: .15rem 0 0; font-size: .8125rem; color: var(--muted); }
.sheet-close {
  flex: none; width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center;
  background: var(--card); border: 1px solid var(--line); color: var(--text); cursor: pointer;
}
.sheet-close:hover { background: var(--hover); }

/* ---- foglio di conferma prima del carrello ------------------------------- */
.ok-body {
  flex: none; display: flex; align-items: center; gap: .9rem;
  margin: 1rem 0 0; padding: .8rem; border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--card);
}
.ok-img {
  flex: none; width: 92px; height: 120px; object-fit: cover;
  border-radius: var(--radius-sm); border: 1px solid var(--line); background: #fff;
}
.ok-info { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.ok-info strong { font-size: .95rem; font-weight: 600; }
.ok-info span { font-size: .8125rem; color: var(--muted); }

/* La taglia nel foglio di conferma: stesso menu del carrello, con la sua parola
   davanti — qui è una riga sola in mezzo a del testo, e un menu senza etichetta
   accanto a "taglia M" scritto sopra si legge come una ripetizione. */
.ok-size { display: flex; align-items: center; gap: .45rem; margin-top: .25rem; }
.ok-size > span { font-size: .8125rem; color: var(--muted); }

.ok-actions { flex: none; display: flex; gap: .6rem; margin-top: 1rem; }
.ok-cancel, .ok-go {
  flex: 1 1 auto; padding: .8rem 1rem; border-radius: 999px;
  font: inherit; font-weight: 600; cursor: pointer;
}
/* Annullare dev'essere facile quanto confermare, ma non attirare il dito: il
   pulsante che conta è uno solo, e non è questo. */
.ok-cancel { background: var(--card); color: var(--text); border: 1px solid var(--line); }
.ok-cancel:hover { background: var(--hover); }
.ok-go { background: var(--primary); color: var(--primary-fg); border: 0; }
.sheet-close svg { width: 18px; height: 18px; }

/* Sei tag non stanno nella larghezza di un telefono: la riga scorre col dito.
   I margini negativi la portano da bordo a bordo del pannello, il padding uguale
   e contrario rimette in riga il primo e l'ultimo con il resto del contenuto —
   così l'ultimo tag si raggiunge invece di restare tagliato sotto il bordo. */
.tags {
  flex: none;
  display: flex; flex-wrap: nowrap; gap: .4rem; align-items: center;
  min-width: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x;
  scrollbar-width: none;
  margin-inline: -1rem;
  padding: .8rem 1rem;
}
.tags::-webkit-scrollbar { display: none; }
.tag {
  flex: none; padding: .4rem .8rem; border-radius: 999px; cursor: pointer;
  line-height: 1.3; white-space: nowrap;
  background: var(--card); border: 1px solid var(--line); color: var(--muted);
  font: inherit; font-size: .8125rem; font-weight: 500;
}
.tag.on { background: var(--primary); border-color: transparent; color: var(--primary-fg); }

.sheet-grid {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  display: grid; grid-template-columns: 1fr; gap: .5rem;
}
@media (min-width: 560px) { .sheet-grid { grid-template-columns: 1fr 1fr; } }

.tile {
  display: flex; align-items: flex-start; gap: .7rem; text-align: left; cursor: pointer;
  padding: .7rem; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); font: inherit; color: var(--text);
}
.tile:hover { border-color: var(--ring); }
.tile.on { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }

.tile-art { flex: none; width: 44px; height: 44px; border-radius: var(--radius-sm); display: grid; place-items: center; }
.tile-art svg { width: 21px; height: 21px; }
/* Una tinta per categoria: si ritrova la famiglia scorrendo, senza leggere i tag. */
.tile-face    { background: #eef2ff; color: #4338ca; }
.tile-product { background: #ecfdf5; color: #047857; }
.tile-style   { background: #fdf2f8; color: #be185d; }
.tile-retouch { background: #fffbeb; color: #b45309; }
.tile-format  { background: #f1f5f9; color: #334155; }

.tile { min-width: 0; }
.tile-body { min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.tile-name, .tile-desc { overflow-wrap: anywhere; }
.tile-name { font-size: .875rem; font-weight: 600; letter-spacing: -.01em; }
.tile-desc { font-size: .8125rem; color: var(--muted); }
.tile-needs { margin-top: .2rem; font-size: .6875rem; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }

.sheet-note { flex: none; margin: .8rem 0 0; font-size: .75rem; color: var(--muted); text-align: center; }

/* Sotto i 16px iOS ingrandisce la pagina appena tocchi un campo, e da lì non torna
   più indietro da solo. Sul telefono i controlli restano a 16px esatti. */
@media (max-width: 559px) {
  /* Sotto i 16px iOS ingrandisce la pagina al primo tocco. La frase è già più
     grande di così, quindi qui basta proteggere gli altri campi. */
  .tokenbar input { font-size: 16px; }
}

/* Schermi bassi (telefono in orizzontale): la barra in alto ruba tutta l'altezza. */
@media (max-height: 560px) {
  .payoff { display: none; }
  .act { width: 50px; height: 50px; }
  .act svg { width: 21px; height: 21px; }
}

/* ===== homepage ============================================================
   In home la pagina scorre in verticale come un sito normale; nel feed occupa
   una schermata sola e si scorre di lato. Sono due layout diversi, quindi il
   corpo cambia classe invece di accumulare eccezioni sugli stessi selettori. */

.home { max-width: 960px; margin: 0 auto; padding: .6rem 1rem 4rem; }
.home-bar { display: flex; align-items: center; justify-content: space-between; padding: .3rem 0; }
.brand-wrap { --logo-h: 4rem; position: relative; min-width: 0; }

/* Il payoff sta sotto al logo a ogni larghezza: il titolo grande è nascosto, ed è
   questa la frase che dice cos'è il sito. Rientra di quanto l'icona è larga, così
   comincia sotto alla parola e non sotto all'arcobaleno. */
/* ⚠ Il payoff sta A DESTRA DELL'ICONA, come nella barra di Figma
   (hero-Barra-in-alto.jpg), non sotto il logo. Nel PNG (999x392) l'icona è un
   cerchio largo quanto l'altezza (x 0-381) e la scritta ne occupa solo lo spicchio
   in alto a destra: sotto la scritta c'è ancora l'anello. Messo in flusso sotto
   l'immagine il payoff cadeva sotto a tutto; messo sotto la "S" finiva sopra
   l'anello. Le posizioni sono frazioni di `--logo-h`, così seguono il logo;
   rimisurare se cambia il PNG. */
.brand-payoff {
  position: absolute; left: calc(var(--logo-h) * 1.1); top: calc(var(--logo-h) * .56);
  margin: 0;
  font-family: var(--f-body); font-weight: 400; font-size: .875rem; line-height: 1.2;
  color: var(--text); white-space: nowrap;
}
/* "endless" nei colori del logo, come nel Figma: testo vero con lo sfondo a
   sfumatura ritagliato sulle lettere. */
.brand-payoff em {
  font-style: normal;
  background: linear-gradient(90deg, #FD9D51, #F4D755, #7ED957);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

@media (max-width: 720px) {
  /* Sul telefono il payoff deve finire prima dei due pulsanti a destra (a 390 px
     cominciano a 290): logo e carattere un po' più piccoli. */
  .brand-wrap { --logo-h: 3rem; }
  .brand-payoff { font-size: .6875rem; }
}
.block { margin-bottom: 2.6rem; }
.block h2 { margin: 0 0 .2rem; font-size: 1.25rem; font-weight: 600; letter-spacing: -.02em; }
.block-sub { margin: .2rem 0 1rem; font-size: .875rem; color: var(--muted); }

/* ---- come funziona ---- */
.steps { display: grid; grid-template-columns: 1fr; gap: .7rem; margin-top: 1rem; }
@media (min-width: 720px) { .steps { grid-template-columns: repeat(3, 1fr); } }

.step {
  position: relative; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 1.1rem;
  box-shadow: 0 1px 2px rgb(10 10 10 / .05);
}
.step-n {
  position: absolute; top: 1.1rem; right: 1.1rem;
  font-size: .75rem; font-weight: 600; color: var(--muted);
}
.step-icon {
  display: grid; place-items: center; width: 40px; height: 40px;
  border-radius: var(--radius-sm); background: #f1f5f9; color: #334155; margin-bottom: .7rem;
}
.step-icon svg { width: 20px; height: 20px; }
.step h3 { margin: 0 0 .15rem; font-size: .9375rem; font-weight: 600; }
.step p { margin: 0; font-size: .875rem; color: var(--muted); }

/* ---- casi d'uso: un nastro, come il mazzo del feed ---- */
.cases {
  display: flex; gap: .8rem; overflow-x: auto;
  scroll-snap-type: x proximity; overscroll-behavior-x: contain;
  scrollbar-width: none;
  /* Bordo a bordo sul telefono: la prima e l'ultima scheda restano allineate
     al contenuto, ma il gesto parte dal bordo dello schermo. */
  margin-inline: -1rem; padding: .2rem 1rem 1rem;
}
.cases::-webkit-scrollbar { display: none; }

.case {
  flex: 0 0 min(74vw, 260px); scroll-snap-align: start; cursor: pointer;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: 0 1px 2px rgb(10 10 10 / .05);
  transition: border-color .12s ease, transform .12s ease;
}
.case:hover { border-color: var(--ring); transform: translateY(-2px); }

.case-media { position: relative; aspect-ratio: 3 / 4; background: #fafafa; }
.case-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.case-tile { position: absolute; inset: 0; display: grid; place-items: center; }
.case-tile svg { width: 38px; height: 38px; }

.badge {
  position: absolute; left: .6rem; top: .6rem;
  padding: .15rem .5rem; border-radius: 999px;
  background: rgb(10 10 10 / .72); color: #fff;
  font-size: .6875rem; font-weight: 500; letter-spacing: .01em;
}
/* Verde per ciò che si può fare adesso, scuro per il resto: la differenza fra
   promessa e realtà deve leggersi a colpo d'occhio. */
.badge.live { background: #047857; }

.case h3 { margin: .7rem .8rem .1rem; font-size: .9375rem; font-weight: 600; }
.case p { margin: 0 .8rem .9rem; font-size: .8125rem; color: var(--muted); }

/* ---- prezzi ---- */
/* ---- domande frequenti --------------------------------------------------- */
.faq {
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--card); margin-top: .5rem; overflow: hidden;
}
.faq summary {
  list-style: none; cursor: pointer; padding: .85rem 2.4rem .85rem .9rem;
  position: relative; font-size: .9375rem; font-weight: 600;
}
.faq summary::-webkit-details-marker { display: none; }
/* Il segno è un + che diventa −: due caratteri, nessuna icona da caricare. */
.faq summary::after {
  content: '+'; position: absolute; right: .9rem; top: 50%; transform: translateY(-50%);
  font-size: 1.1rem; font-weight: 400; color: var(--muted); line-height: 1;
}
.faq[open] summary::after { content: '−'; }
.faq summary:hover { background: var(--hover); }
.faq p {
  margin: 0; padding: 0 .9rem .9rem; font-size: .875rem; line-height: 1.55;
  color: var(--muted); max-width: 62ch;
}

/* ---- l'invito finale ------------------------------------------------------ */
.cta {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 1rem; padding: 1.4rem; border-radius: var(--radius-lg);
  background: var(--text); color: var(--bg);
}
.cta h2 { margin: 0; color: inherit; }
.cta p { margin: .25rem 0 0; font-size: .9375rem; opacity: .75; }
.cta-go {
  flex: none; padding: .85rem 1.5rem; border-radius: 999px; border: 0; cursor: pointer;
  background: var(--bg); color: var(--text); font: inherit; font-weight: 600;
}
.cta-go:hover { background: var(--hover); }

/* ---- piede ---------------------------------------------------------------- */
.site-foot { border-top: 1px solid var(--line); background: var(--card); }
.foot-in {
  max-width: 960px; margin: 0 auto;
  padding: 2rem 1rem calc(2rem + env(safe-area-inset-bottom));
}
.foot-brand { display: inline-block; margin-bottom: .5rem; font-size: 1.05rem; }
/* ⚠ Niente limite di caratteri: 52ch tagliava il payoff a metà frase — "Stampa e
   spedizione in" / "Unione Europea" — dentro a un piede largo 928px, cioè andava a
   capo per una regola, non perché lo spazio fosse finito. Su schermo stretto va a
   capo lo stesso, ma lì è la larghezza vera a deciderlo. */
.site-foot p { margin: 0; font-size: .875rem; color: var(--muted); }
/* ⚠ Più larga delle altre righe del piede: i dati della società sono una riga sola
   di legge, e con i 52ch del paragrafo sopra diventava una colonnina di sei righe. */
.foot-link { margin-top: .6rem !important; }
.foot-link a { color: var(--muted); }
.foot-small { margin-top: .6rem !important; font-size: .8125rem !important; max-width: none !important; }

.pricing {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: 0 1px 2px rgb(10 10 10 / .05);
}
/* ⚠ Una GRIGLIA a tre colonne, non un flex con space-between, e la terza colonna
   esiste anche dove la "i" non c'è. I prezzi di un listino si leggono in colonna: con
   space-between lo spazio libero finiva FRA gli elementi invece che prima del prezzo,
   e bastava un nome più lungo per spostare l'importo. Misurato: le righe con la "i"
   chiudevano a 780 px e quelle senza a 1080, e fra loro ballavano di 15 px. */
.price-row {
  display: grid; grid-template-columns: 1fr auto 1.5rem;
  align-items: center; gap: 1rem;
  padding: .9rem 1rem; border-top: 1px solid var(--line);
}
.price-row > :first-child { min-width: 0; }
.price-row.first { border-top: 0; }
.price-row strong { display: block; font-size: .9375rem; font-weight: 600; }
.price-row small { display: block; font-size: .8125rem; color: var(--muted); }
.price-row .amount { font-size: 1rem; font-weight: 600; white-space: nowrap; text-align: right; }
.price-row.first .amount { font-size: 1.25rem; }

/* ---- la "i" e la scheda tecnica ---- */
/* Il pulsante sta in fondo alla riga, DOPO il prezzo: prima del prezzo spingeva
   l'importo fuori allineamento fra una riga e l'altra, e le cifre di un listino si
   leggono in colonna. */
.info-btn {
  width: 1.5rem; height: 1.5rem; padding: 0;
  border: 1px solid var(--line); border-radius: 999px; background: var(--card);
  color: var(--muted); font: inherit; font-size: .8125rem; font-style: italic;
  font-weight: 600; line-height: 1; cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.info-btn:hover { border-color: var(--primary); color: var(--text); }
.info-btn[aria-expanded="true"] { background: var(--primary); border-color: var(--primary); color: var(--primary-fg); }

/* Il pannello è un fratello della riga e occupa tutta la larghezza: `.pricing` è una
   colonna, quindi cade esattamente sotto la riga che l'ha aperto. */
.price-info { padding: 0 1rem 1rem; }
.pi-desc { margin: 0 0 .7rem; font-size: .8125rem; line-height: 1.5; color: var(--muted); }
/* Due colonne: etichetta e valore. Su schermo stretto vanno a capo da sole perché la
   prima colonna è a contenuto e la seconda prende quello che resta. */
.pi-dati {
  display: grid; grid-template-columns: auto 1fr; gap: .25rem .8rem;
  margin: 0; font-size: .8125rem;
}
.pi-dati dt { color: var(--muted); }
.pi-dati dd { margin: 0; }

/* La tabella delle taglie. `overflow-x: auto` perché su un telefono tre colonne di
   centimetri non ci stanno, ed è l'unica eccezione alla regola "niente scorrimento
   orizzontale" (vedi la nota sulle tabelle in fondo al foglio). */
.pi-taglie { margin-top: .8rem; overflow-x: auto; }
.pi-taglie table { border-collapse: collapse; font-size: .8125rem; min-width: 100%; }
.pi-taglie th, .pi-taglie td {
  padding: .3rem .7rem .3rem 0; text-align: left; white-space: nowrap;
  border-bottom: 1px solid var(--line);
}
.pi-taglie th { color: var(--muted); font-weight: 500; }
.pi-taglie tr:last-child td { border-bottom: 0; }

.price-example { margin: .8rem 0 0; font-size: .875rem; color: var(--text); }

/* L'aggancio emotivo va letto per primo: è quello che dice a cosa serve il filtro
   nella vita di chi guarda. Il nome tecnico viene dopo, più piccolo. */
.case-body { padding: .8rem; }
.case .hook { margin: 0 0 .35rem; font-size: .9375rem; font-weight: 600; line-height: 1.35; letter-spacing: -.01em; }
.case h3 { margin: 0; font-size: .75rem; font-weight: 500; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.case .what { margin: .3rem 0 0; font-size: .8125rem; color: var(--muted); }
.case-tile.tile-photo { background: #f5f3ff; color: #6d28d9; }

/* Un filtro non ancora collegato si vede che non si può scegliere: spento e con
   l'etichetta. Lasciarlo identico agli altri sarebbe una promessa che il server
   poi rifiuta. */
.tile.off { opacity: .55; cursor: default; position: relative; }
.tile.off:hover { border-color: var(--line); }
.tile-soon {
  position: absolute; right: .6rem; top: .6rem;
  padding: .1rem .45rem; border-radius: 999px;
  background: #ebebeb; color: var(--muted);
  font-size: .6875rem; font-weight: 500;
}

/* ---- carrello ---- */
.bar-right { display: flex; align-items: center; gap: .5rem; }
/* ⚠ `text-decoration`: una delle due porte è un <a>, e senza questo si porterebbe
   dietro la sottolineatura dei link. Il `color` lo mette già la regola qui sotto. */
.cart-btn {
  position: relative; display: grid; place-items: center; text-decoration: none;
  width: 38px; height: 38px; border-radius: 50%; cursor: pointer;
  background: var(--card); border: 1px solid var(--line); color: var(--text);
}
.cart-btn:hover { border-color: var(--ring); }
.cart-btn svg { width: 19px; height: 19px; }
.cart-count {
  position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px;
  display: grid; place-items: center; padding: 0 .25rem;
  border-radius: 999px; background: var(--primary); color: var(--primary-fg);
  font-size: .6875rem; font-weight: 600;
}

.cart-items { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.cart-row {
  display: flex; align-items: center; gap: .7rem; padding: .7rem 0;
  border-bottom: 1px solid var(--line);
}
.cart-row img { width: 56px; height: 74px; object-fit: cover; flex: none;
                border-radius: var(--radius-sm); border: 1px solid var(--line); background: #fff; }
.cart-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: .2rem; }
.cart-body strong { font-size: .875rem; font-weight: 600; overflow: hidden;
                    text-overflow: ellipsis; white-space: nowrap; }
.cart-body small { font-size: .8125rem; color: var(--muted); }
/* Taglia e quantità sulla stessa riga: sono le due cose che si cambiano nel
   carrello, e in colonna allungavano la riga di un prodotto senza motivo. Vanno a
   capo da sole su uno schermo stretto. */
.cart-opts { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-top: .1rem; }
.cart-opt { display: flex; align-items: center; gap: .35rem; }
.cart-opt > span { font-size: .8125rem; color: var(--muted); }

.cart-size, .cart-qty select, .ok-size select {
  align-self: flex-start; padding: .3rem .5rem; font: inherit; font-size: .8125rem;
  background: var(--card); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.cart-del {
  flex: none; width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
  display: grid; place-items: center;
  background: transparent; border: 1px solid var(--line); color: var(--muted);
}
.cart-del:hover { color: var(--err); border-color: var(--err); }
.cart-del svg { width: 13px; height: 13px; }

/* Tre righe, non una: sul telefono paese, totale e pulsante sulla stessa riga si
   schiacciavano, il totale andava a capo fra il simbolo e la cifra e la nota di
   spedizione finiva incolonnata in una striscia di sei parole. */
.cart-foot {
  flex: none; display: grid; gap: .5rem .8rem; padding-top: .9rem;
  /* minmax(0, …) e non 1fr: il minimo di una colonna 1fr è il contenuto, e la nota
     di spedizione — che occupa entrambe le colonne — ci scaricava dentro la sua
     larghezza a riga unica, gonfiando la prima colonna e spingendo il pulsante
     fuori dallo schermo. */
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "paese    paese"
    "consenso consenso"
    "totale   paga"
    "nota     nota";
  align-items: center;
}
.cart-country { grid-area: paese; }

/* La spunta del consenso, in cassa e nell'area ordini: stessa forma, perché è la
   stessa promessa. Allineata in alto, o su due righe il quadratino finirebbe a metà
   del testo invece che accanto alla prima riga. */
.consenso {
  grid-area: consenso;
  display: flex; align-items: flex-start; gap: .55rem;
  margin: .2rem 0 .1rem; font-size: .8125rem; color: var(--muted); cursor: pointer;
}
.consenso input {
  flex: none; width: 17px; height: 17px; margin: .15rem 0 0; accent-color: var(--text);
}
.consenso a { color: var(--text); }
.consenso strong { color: var(--text); font-weight: 600; }
/* Rosso quando si preme senza aver spuntato: l'avviso va dove si deve guardare. */
.consenso.serve, .consenso.serve a, .consenso.serve strong { color: var(--err); }
.cart-total {
  grid-area: totale; font-size: 1.25rem; font-weight: 600;
  white-space: nowrap;   /* "€ 100,90" non si spezza mai fra simbolo e cifra */
}
#cart-pay { grid-area: paga; }
.cart-ship { grid-area: nota; min-width: 0; font-size: .75rem; color: var(--muted); }

/* Uno stile non chiede foto e non ha un "cosa serve": la tessera è più bassa e
   si distingue dai filtri, che invece hanno requisiti. */
.style-tile .tile-desc { font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; }
.style-tile.on { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }

/* ---- frecce del carosello ---- */
.cases-wrap { position: relative; }
.cases { user-select: none; -webkit-user-select: none; }
.cases img { -webkit-user-drag: none; user-drag: none; }
.cases.dragging { cursor: grabbing; }

.cases-nav {
  position: absolute; top: calc(50% - 1.2rem); z-index: 2;
  width: 36px; height: 36px; border-radius: 50%;
  display: none; place-items: center; cursor: pointer;
  background: var(--card); border: 1px solid var(--line); color: var(--text);
  box-shadow: 0 2px 8px rgb(10 10 10 / .12);
}
.cases-nav.prev { left: -6px; }
.cases-nav.next { right: -6px; }
.cases-nav svg { width: 17px; height: 17px; }
.cases-nav:disabled { opacity: .35; cursor: default; }
.cases-nav:not(:disabled):hover { border-color: var(--ring); }

/* Solo dove c'è un puntatore: sul telefono il dito basta e le frecce sarebbero
   due ostacoli sopra le schede. E solo se c'è davvero qualcosa da scorrere. */
@media (hover: hover) and (pointer: fine) {
  .cases-wrap.scrollable .cases-nav { display: grid; }
}

/* ===== hero ================================================================
   La grana di stampa, il serif da tipografia e la maglietta che si inclina sono
   i tre segnali che dicono "oggetto stampato", non "app". Nessuna libreria. */
body::before {
  /* Grana: un feTurbulence inline, fissa sopra tutto, quasi invisibile. È quello
     che separa una pagina web da un foglio stampato. */
  content: ""; position: fixed; inset: 0; z-index: 99; pointer-events: none;
  opacity: .055; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* minmax(0, 1fr) e non 1fr: il minimo di una colonna 1fr e' la larghezza del
   contenuto, e le schede del mazzo (titoli nowrap, foto) gonfiavano la colonna
   oltre la finestra — il pulsante Genera usciva a destra sul telefono. */
/* ⚠ Lo scambio si fa con le AREE, non spostando i blocchi nell'HTML: così il
   prodotto si vede per primo ma nel documento viene ancora prima il modulo, e chi
   naviga da tastiera o con un lettore di schermo arriva subito a ciò su cui si
   agisce invece di attraversare una vetrina. */
.hero {
  display: grid; grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "stage" "copy" "chips";
  gap: 1rem; align-items: start; padding: 1rem 0 1.2rem;
}
.hero-copy { grid-area: copy; min-width: 0; }
.hero-stage { grid-area: stage; min-width: 0; }
.hero-chips { grid-area: chips; min-width: 0; }
@media (min-width: 860px) {
  .hero {
    grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr);
    grid-template-areas: "stage copy" "stage chips";
    gap: .6rem 2.5rem; align-items: center; padding: 1rem 0 1.2rem;
  }
}
/* Rete di sicurezza: se qualcosa sporge, non deve creare uno scroll laterale. */
.home { overflow-x: clip; }

.headline {
  margin: 0 0 1rem;
  font-family: "Fraunces", Georgia, "Times New Roman", serif;
  font-optical-sizing: auto;
  /* Il minimo torna sotto il massimo: su un telefono 2,6rem fisse mandavano il titolo
     a tre righe e mangiavano lo schermo prima ancora del prodotto. */
  font-size: clamp(1.6rem, 7.5vw, 2.6rem); line-height: .98; font-weight: 700;
  letter-spacing: -.03em;
}
.headline em {
  font-style: italic; font-weight: 500;
  /* Una sottolineatura che sembra un tratto di pennarello, non una riga di CSS. */
  background: linear-gradient(120deg, transparent 0 4%, #ffe66d 4% 96%, transparent 96%) no-repeat 0 78% / 100% .28em;
}

.hero-say {
  margin: 0 0 .7rem;
  font-size: clamp(1.05rem, 2.6vw, 1.3rem); line-height: 1.75; color: var(--text);
  letter-spacing: -.01em; min-height: 3.5em;
}
.hs-dim { font-style: italic; color: var(--muted); }
.hs-word { font-weight: 600; border-bottom: 2px solid var(--line); padding-bottom: .05em; }
#hero-typed { border-bottom-color: var(--primary); }
.caret {
  display: inline-block; width: 2px; height: 1.05em; margin: 0 .35rem 0 .08rem;
  vertical-align: -.15em; background: var(--primary);
  animation: blink 1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

.hero-sub { margin: 0 0 1.1rem; font-size: .9375rem; color: var(--muted); max-width: 34rem; }

.chips { display: flex; flex-wrap: wrap; gap: .45rem; }
.chip-try {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .28rem .6rem .28rem .45rem; border-radius: 999px; cursor: pointer;
  background: var(--card); border: 1px solid var(--line); color: var(--text);
  font: inherit; font-size: .75rem; font-weight: 500;
  transition: transform .12s ease, border-color .12s ease;
}
.chip-try:hover { border-color: var(--primary); transform: translateY(-1px); }
.chip-emoji { font-size: .85rem; }

/* La maglietta: una tela con prospettiva. Chi passa il mouse la vede inclinarsi;
   ferma, respira appena. */
.hero-stage { position: relative; perspective: 1100px; }
.shirt {
  position: relative; aspect-ratio: 3 / 4; max-width: 440px; margin: 0 auto;
  border-radius: 22px; overflow: hidden;
  background: #fff; border: 1px solid var(--line);
  box-shadow: 0 30px 60px -30px rgb(10 10 10 / .35), 0 1px 2px rgb(10 10 10 / .06);
  transform-style: preserve-3d; transition: transform .25s ease;
  animation: float 6s ease-in-out infinite;
}
.shirt img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity .6s ease;
}
.shirt img.on { opacity: 1; }
@keyframes float { 50% { translate: 0 -6px; } }

.stage-tag {
  position: absolute; left: 50%; bottom: -.9rem; transform: translateX(-50%);
  max-width: 92%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding: .3rem .7rem; border-radius: 999px;
  background: var(--primary); color: var(--primary-fg);
  font-size: .75rem; font-weight: 500;
}

/* ---- il nastro ---- */
/* Un vero contenitore a scorrimento, non un'animazione: il JS lo fa avanzare
   da solo, ma si puo' trascinare col mouse e sfogliare col dito, e fermarsi
   su una maglietta. Bordo a bordo, con i lati sfumati. */
.ticker-block h2 { margin-bottom: .5rem; }
.ticker {
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
  margin: 0 -1rem; padding: .4rem 1rem .9rem;
  mask: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  user-select: none; -webkit-user-select: none;
}
.ticker::-webkit-scrollbar { display: none; }
.ticker.dragging { cursor: grabbing; }
.ticker-track { display: flex; gap: 1rem; width: max-content; }
/* ⚠ La tessera è grande: dentro c'è un prodotto fotografato, e la stampa ci sta
   dentro alla sua misura vera — a 150 px il disegno era un francobollo e lo stile,
   che è il motivo per cui questo nastro esiste, non si distingueva. */
.tk {
  position: relative; flex: none; width: 260px; aspect-ratio: 3 / 4; margin: 0;
  border-radius: 14px; overflow: hidden; border: 1px solid var(--line); background: #fff;
  transform: rotate(var(--tilt, 0deg));
  box-shadow: 0 8px 18px -12px rgb(10 10 10 / .35);
}
.tk img { width: 100%; height: 100%; object-fit: cover; display: block; -webkit-user-drag: none; user-drag: none; }
/* L'etichetta sopra ogni maglietta: cio' che le e' stato applicato. */
.tk { cursor: pointer; }
.tk:hover .tk-chip { background: var(--primary); }
.tk-chip {
  position: absolute; left: .5rem; bottom: .5rem; max-width: calc(100% - 1rem);
  padding: .2rem .55rem; border-radius: 999px;
  background: rgb(10 10 10 / .78); color: #fff;
  font-size: .8125rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Su un telefono 260 px sono quasi tutto lo schermo: si vede una tessera e mezza,
   che è comunque meglio di quattro illeggibili. */
@media (max-width: 480px) {
  .tk { width: 210px; }
}

/* ---- i filtri: una griglia ---- */
/* Una griglia e non un nastro: le due immagini di una scheda si leggono insieme,
   e su qualcosa che scorre la prima sarebbe già uscita quando arriva la seconda.
   `auto-fill` con un minimo di 300 px dà tre colonne sul desktop, due sul tablet
   e una sul telefono, senza un solo media query. */
.filtri {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.fl {
  margin: 0; padding: .9rem;
  border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--card);
  box-shadow: 0 8px 18px -14px rgb(10 10 10 / .35);
}
.fl.cliccabile { cursor: pointer; transition: border-color .2s ease, transform .2s ease; }
.fl.cliccabile:hover { border-color: var(--primary); transform: translateY(-2px); }

/* prima → dopo. La freccia sta in mezzo e non si stringe. */
/* I due lati si allineano in ALTO, non al centro: quando un filtro ha due immagini
   di partenza quelle stanno affiancate e sono più basse del risultato, e centrandole
   le due didascalie finivano a due altezze diverse. La freccia si ricentra da sola. */
.fl-coppia { display: grid; grid-template-columns: 1fr auto 1fr; gap: .6rem; align-items: start; }
.fl-freccia { align-self: center; }
.fl-lato { min-width: 0; }
.fl-imgs { display: flex; gap: .3rem; }
.fl-imgs img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover; display: block;
  border-radius: 10px; background: var(--bg);
}
/* Due immagini di partenza stanno affiancate nello stesso spazio di una: sono
   due ingressi dello stesso filtro, non due esempi.
   ⚠ Metà larghezza vuol dire metà altezza se restano quadrate, e sotto la coppia
   restava una banda vuota alta quanto mezza scheda. Con 1/2 la coppia è alta
   esattamente quanto il risultato accanto; il ritaglio lo fa object-fit. */
.fl-imgs.due img { width: calc(50% - .15rem); aspect-ratio: 1 / 2; }
.fl-freccia { font-size: 1.1rem; color: var(--muted); line-height: 1; }
.fl-cap {
  display: block; margin-top: .35rem;
  font-size: .75rem; line-height: 1.25; color: var(--muted);
}
.fl-nome { margin: .7rem 0 .15rem; font-size: 1rem; }
.fl-hook { margin: 0; font-size: .8125rem; color: var(--muted); }

/* ---- le sezioni entrano scorrendo ---- */
.reveal { opacity: 0; transform: translateY(14px); transition: opacity .6s ease, transform .6s ease; }
.reveal.in { opacity: 1; transform: none; }

/* Chi chiede meno movimento lo ottiene: niente nastro, niente respiro, niente
   cursore che lampeggia. Le sezioni sono già visibili. */
/* Maglietta e nastro seguono la demo anche qui (vedi l'avvio in home.js):
   fermi restano solo gli extra. */
@media (prefers-reduced-motion: reduce) {
  .caret { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
}


/* ===== il modulo nella hero e il mazzo nello stage =========================== */
/* La frase nella colonna della hero e' piu' stretta che nella vecchia barra:
   un corpo appena piu' piccolo evita di andare a capo a ogni parola. */
.hero .say { font-size: clamp(1rem, 3.2vw, 1.25rem); line-height: 1.8; }
.hero .composer { gap: .6rem; }
.chips-title { margin: 1rem 0 .45rem; font-size: .75rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }

.hero-stage { width: 100%; max-width: min(440px, 100%); margin: 0 auto; }
.card { min-width: 0; }   /* il titolo nowrap non deve allargare la scheda */

/* Il mazzo eredita le misure dallo stage, non dalla finestra: le schede sono
   una frazione del contenitore e la prima e l'ultima si centrano col padding. */
.hero-stage .deck {
  --deckw: 100%; --cardw: 88%;
  width: 100%; aspect-ratio: 3 / 4; margin: 0; padding: 0 6%; gap: .6rem;
  min-height: 0;
}
.hero-stage .deck .frame { border-radius: 22px; }
.hero-stage .actions { padding: .9rem 0 0; }


/* ===== telefono: hero compatta durante la ricerca ============================
   Con una ricerca attiva il titolo ha gia' fatto il suo lavoro: sparisce, il
   modulo sale in cima e il risultato arriva subito sotto. I chip diventano una
   riga sola scorrevole, cosi' non spingono il mazzo piu' in basso. */
@media (max-width: 859px) {
  body.searching .headline,
  body.searching .hero-frase,
  body.searching .hero-sub { display: none; }

  /* Il soggetto prende una riga intera: "I want to buy a T-shirt of" / il soggetto /
     "in style Sticker" si legge, un a capo a metà frase no.
     ⚠ La soglia è 859 e non 559: fino a 859 la hero è a colonna sola, e in quella
     fascia il campo del prompt tornava in riga schiacciato a ~200 px contro i 469
     che ha appena sotto. Il salto si vedeva proprio fra i 560 e i 660. */
  .subject { flex: 1 1 100%; }

  /* ⚠ La riga scorrevole solo DURANTE una ricerca, quando i chip non devono
     spingere giù il mazzo. Prima, cinque chip vanno a capo come nel disegno:
     su una riga sola se ne vedevano uno e mezzo. */
  body.searching .hero-chips .chips {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    margin-inline: -1rem; padding: .1rem 1rem .4rem;
  }
  .hero-chips .chips::-webkit-scrollbar { display: none; }
  body.searching .chip-try { flex: none; white-space: nowrap; }
  .chips-title { margin-top: .6rem; }
}


/* ===== come funziona, con le immagini ======================================= */
.step { padding: .7rem .7rem 1rem; }
.step-media {
  position: relative; aspect-ratio: 4 / 3; border-radius: 12px; overflow: hidden;
  background: #f3f3f3; border: 1px solid var(--line); margin-bottom: .8rem;
}
.step-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Tre magliette a ventaglio: la variante si vede, non si spiega. --k vale -1, 0, 1. */
.step-media.fan img {
  inset: auto; left: 50%; top: 7%; width: 54%; height: auto; aspect-ratio: 3 / 4;
  border-radius: 10px; border: 1px solid var(--line); background: #fff;
  box-shadow: 0 10px 24px -14px rgb(10 10 10 / .5);
  transform: translateX(calc(-50% + var(--k) * 30%)) rotate(calc(var(--k) * 7deg));
}
.step-media.fan img:nth-child(2) { z-index: 1; }
/* Il chip del passo: sotto l'immagine, in flusso. Sovrapposto copriva il prodotto
   nel punto in cui lo si guarda, e sul ventaglio delle tre varianti non ci stava. */
.step-cap {
  display: inline-block; max-width: 100%; margin: -.25rem 0 .55rem;
  padding: .2rem .55rem; border-radius: 999px;
  background: rgb(10 10 10 / .78); color: #fff;
  font-size: .8125rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Su un telefono 260 px sono quasi tutto lo schermo: si vede una tessera e mezza,
   che è comunque meglio di quattro illeggibili. */
@media (max-width: 480px) {
  .tk { width: 210px; }
}
/* Il numero del passo sta sull'immagine: un dischetto bianco, non un grigio che sparisce. */
.step-n {
  top: 1.3rem; right: 1.3rem; width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center; background: var(--card); border: 1px solid var(--line);
  color: var(--text); font-size: .7rem; font-weight: 600;
}
.step h3 { margin-top: .1rem; }


/* Il paese di consegna, sopra il totale del carrello. */
.cart-country { display: flex; align-items: center; gap: .5rem; font-size: .85rem; }
.cart-country span { color: var(--muted); flex: none; }
.cart-country select {
  flex: 1 1 auto; min-width: 0; padding: .35rem .5rem; border-radius: 8px;
  border: 1px solid var(--line); background: var(--card); color: var(--text); font: inherit;
}

/* L'immagine nel carrello si ingrandisce: il pulsante non deve sembrare un pulsante,
   solo comportarsi come tale. La lente compare al passaggio del mouse. */
.cart-zoom {
  position: relative; padding: 0; border: 0; background: none; cursor: zoom-in;
  border-radius: 10px; overflow: hidden; flex: none; line-height: 0;
}
.cart-zoom::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: rgb(10 10 10 / 0) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-4-4M11 8v6M8 11h6'/%3E%3C/svg%3E") center / 22px no-repeat;
  opacity: 0; transition: opacity .15s ease;
}
.cart-zoom:hover::after, .cart-zoom:focus-visible::after {
  background-color: rgb(10 10 10 / .45); opacity: 1;
}

/* I colori del capo, in basso a sinistra sulla scheda: si scelgono guardando il
   prodotto, non da un menu lontano. Compaiono solo dove c'è più di un colore. */
.swatches {
  position: absolute; left: .6rem; bottom: .6rem; z-index: 2;
  display: flex; gap: .3rem; flex-wrap: wrap; max-width: calc(100% - 4rem);
}
.sw {
  width: 20px; height: 20px; border-radius: 50%; padding: 0; cursor: pointer;
  border: 1px solid rgb(10 10 10 / .25); box-shadow: 0 1px 3px rgb(10 10 10 / .25);
  transition: transform .12s ease;
}
.sw-light { border-color: rgb(10 10 10 / .35); }   /* i chiari sul bianco sparirebbero */
.sw:hover { transform: scale(1.15); }
.sw.on {
  /* L'anello è fuori dal quadratino: dentro coprirebbe proprio il colore da giudicare. */
  box-shadow: 0 0 0 2px var(--card), 0 0 0 3.5px var(--primary);
}
.sw.loading { opacity: .45; cursor: progress; }

/* ===== editor ================================================================
   Un layer a tutto schermo. Sta sopra al carrello (60) e al visore (70): da qui
   si compone ciò che verrà stampato, e niente deve coprirlo. */
.ed {
  position: fixed; inset: 0; z-index: 80;
  display: flex; flex-direction: column;
  background: var(--bg); color: var(--text);
}
.ed[hidden] { display: none; }

/* Il menu della categoria e la X sulla stessa riga. L'intestazione con il logo
   non c'e' piu' - si e' dentro un layer a tutto schermo - e nemmeno l'etichetta
   sopra il menu, che ripeteva quello che il menu stesso mostra. Insieme valevano
   quasi 90 px, tolti al prodotto proprio dove ce n'e' meno. */
.ed-head { display: flex; align-items: center; gap: .6rem; }
.ed-head .ed-select { flex: 1 1 auto; min-width: 0; }
.ed-x {
  flex: none;
  width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
  background: var(--card); border: 1px solid var(--line); color: var(--text); cursor: pointer;
}
.ed-x svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

/* ⚠ Colonna flex, non un semplice blocco che scorre: cosi' .ed-view puo'
   prendersi TUTTO lo spazio che avanza fra i colori e la fascia del prezzo,
   invece di avere un'altezza fissa che su uno schermo alto lascia un vuoto e su
   uno basso fa uscire il contenuto. Su mobile la barra di scorrimento e' un
   velo che sparisce: se il contenuto sborda non se ne accorge nessuno, quindi
   la cosa giusta e' farlo stare dentro. */
.ed-scroll {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  overflow-y: auto; padding: .85rem 1rem 1rem;
}

.ed-select {
  width: 100%; padding: .6rem .7rem; font: inherit; font-weight: 600;
  background: var(--card); color: var(--text);
  border: 1px solid var(--line); border-radius: 10px;
}

.ed-colors { display: flex; flex-wrap: wrap; gap: .4rem; margin: .7rem 0 .8rem; }
.ed-sw {
  width: 26px; height: 26px; border-radius: 50%; padding: 0; cursor: pointer;
  border: 1px solid rgb(10 10 10 / .25);
}
.ed-sw.light { border-color: rgb(10 10 10 / .35); }
.ed-sw.on { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--primary); }

/* Fronte e retro: due chips SULLA foto, non una riga sotto i colori. Sono sempre
   e solo due e devono dire a colpo d'occhio su quale faccia si sta disegnando —
   per farlo non serve una riga intera, che su mobile vale 46 px di prodotto in
   meno. Stessa lingua dei comandi dello zoom, dall'altro lato della finestra. */
.ed-sides {
  position: absolute; top: .5rem; left: 50%; transform: translateX(-50%); z-index: 3;
  display: flex; gap: .2rem;
  background: rgb(255 255 255 / .92); border: 1px solid var(--line);
  border-radius: 999px; padding: .2rem;
}
/* ⚠ Serve esplicito: .ed-sides dichiara display:flex, che vince sul display:none
   che il browser dà a [hidden]. Senza, l'interruttore restava visibile anche su
   grembiule e cappellino, dove il retro non si stampa. */
.ed-sides[hidden] { display: none; }
.ed-side {
  padding: .3rem .85rem; border: 0; border-radius: 999px; background: none;
  font: inherit; font-size: .78rem; font-weight: 600; line-height: 1.2;
  cursor: pointer; color: var(--muted);
}
.ed-side.on { color: var(--bg); background: var(--text); }
/* Il pallino dice che su quella faccia c'e' gia' qualcosa: senza, il disegno del
   retro sparirebbe alla vista e sembrerebbe perso. */
.ed-side.has::after { content: ' •'; }

/* La finestra ritaglia: dentro ci sta il prodotto ingrandito quanto serve perché
   l'area di stampa sia grande abbastanza da lavorarci. Sul prodotto intero l'area
   della t-shirt è il 30% della larghezza — un francobollo. */
.ed-view {
  position: relative; overflow: hidden;
  /* Cresce fino a riempire lo spazio libero. Il minimo e' quanto serve per
     lavorarci davvero: sotto, l'area di stampa torna un francobollo. */
  flex: 1 1 auto; min-height: 200px;
  margin: 0 auto; width: 100%; max-width: 560px;
  border: 1px solid var(--line); border-radius: 12px; background: #f5f5f5;
  touch-action: none;
}

/* Il palco combacia con la foto, perché l'area di stampa è posizionata in
   percentuale SULL'IMMAGINE: ancorandola alla finestra scivolerebbe fuori posto
   appena la foto si sposta. Misure e posizione le calcola layoutStage(). */
.ed-stage { position: absolute; }
.ed-mockup { display: block; width: 100%; height: auto; }

/* I comandi dello zoom stanno sulla finestra, non sotto: si guarda il prodotto
   mentre ci si avvicina. */
.ed-zoom {
  position: absolute; right: .5rem; bottom: .5rem; z-index: 3;
  display: flex; gap: .25rem;
  background: rgb(255 255 255 / .9); border: 1px solid var(--line);
  border-radius: 999px; padding: .2rem;
}
.ed-zoom button {
  min-width: 30px; height: 26px; padding: 0 .5rem; border: 0; cursor: pointer;
  border-radius: 999px; background: none; color: var(--text);
  font: inherit; font-size: .78rem; font-weight: 600; line-height: 1;
}
.ed-zoom button:hover { background: var(--hover); }

/* Il tratteggio NON è decorativo: è il limite oltre il quale non si stampa. */
.ed-area { position: absolute; outline: 2px dashed #e6b800; outline-offset: 0; }

/* La mascherina che sbianca il fuori-area. Un'ombra enorme e piatta è il modo più
   semplice di "bucare" un rettangolo: niente clip-path, niente quattro div. Sta
   SOPRA i livelli — sotto, un disegno sbordante la coprirebbe e non si capirebbe
   più dove finisce la stampa. */
.ed-matte {
  position: absolute; z-index: 2; pointer-events: none;
  box-shadow: 0 0 0 9999px rgb(255 255 255 / .62);
}

/* Le guide: sottili e sopra a tutto, visibili solo durante il gesto. */
.ed-guide { position: absolute; z-index: 4; pointer-events: none; background: #e6007e; }
.ed-guide-x { width: 1px; }
.ed-guide-y { height: 1px; }

/* I righelli dell'area di stampa. Il palco è stretto — a zoom 0,85 restano ~7% di
   margine per lato — quindi la misura sta ADDOSSO alla linea e si allunga lungo di
   essa, come in un disegno tecnico: messa di fianco non ci starebbe e verrebbe
   tagliata dalla finestra. */
.ed-ruler { position: absolute; z-index: 2; pointer-events: none; color: #7a6a00; }
.ed-ruler span {
  position: absolute; padding: 0 .3rem;
  background: rgb(255 255 255 / .88); border-radius: 3px;
  font-size: .6875rem; font-weight: 600; line-height: 1.3; white-space: nowrap;
}
/* La larghezza: linea sotto l'area, trattini agli estremi. */
.ed-ruler-w { border-top: 1px solid currentColor; }
.ed-ruler-w::before, .ed-ruler-w::after {
  content: ''; position: absolute; top: -4px; width: 1px; height: 9px; background: currentColor;
}
.ed-ruler-w::before { left: 0; }
.ed-ruler-w::after { right: 0; }
.ed-ruler-w span { left: 50%; top: 50%; transform: translate(-50%, -50%); }
/* L'altezza: linea a sinistra, misura girata come sui disegni quotati. */
.ed-ruler-h { border-left: 1px solid currentColor; }
.ed-ruler-h::before, .ed-ruler-h::after {
  content: ''; position: absolute; left: -4px; height: 1px; width: 9px; background: currentColor;
}
.ed-ruler-h::before { top: 0; }
.ed-ruler-h::after { bottom: 0; }
.ed-ruler-h span { top: 50%; left: 50%; transform: translate(-50%, -50%) rotate(-90deg); }

/* container-type sul LIVELLO, non sul testo: le unità cq guardano il contenitore,
   e un elemento non può essere contenitore di se stesso. */
.ed-layer { position: absolute; touch-action: none; cursor: grab; container-type: size; }
.ed-layer canvas, .ed-txt { display: block; width: 100%; height: 100%; }
.ed-txt {
  display: grid; place-items: center; text-align: center;
  font-weight: 700; line-height: 1; overflow: hidden;
  /* Il testo riempie il riquadro: l'altezza del box la decide chi trascina. */
  font-size: 92cqh;
}
.ed-layer.on { outline: 1.5px solid var(--primary); }
.ed-layer .ed-kill, .ed-layer .ed-grip, .ed-layer .ed-turn, .ed-layer .ed-altro { display: none; }
.ed-layer.on .ed-kill, .ed-layer.on .ed-grip, .ed-layer.on .ed-turn,
.ed-layer.on .ed-altro { display: grid; }

/* ⚠ Le maniglie girano col riquadro — è quello che le tiene coerenti col gesto —
   ma i loro SIMBOLI no: una × e una freccia a testa in giù non si leggono.
   --rot è l'angolo del livello cambiato di segno, lo scrive drawLayer(). */
/* ⚠ Il cestino sta SOPRA il riquadro, al centro, non più sull'angolo in alto a
   sinistra: lì copriva per intero la maniglia di quell'angolo — è più grande e
   sta più in alto nello stacking — e tirarla non ridimensionava niente.
   Sopra il cestino, sotto la rotazione: due gesti diversi, due posti diversi. */
/* ⚠ 30px e non 24: sono i due comandi che si toccano con un dito su un telefono,
   e sotto i 28 il bersaglio è più piccolo del polpastrello. Il `top` segue l'altezza
   (-40 invece di -34) o il filo che li lega al riquadro si accorcia. */
.ed-kill {
  position: absolute; left: 50%; top: -40px; z-index: 3;
  width: 30px; height: 30px; margin-left: -32px; border-radius: 50%;
  place-items: center;
  background: var(--err); color: #fff; border: 0; cursor: pointer;
  font-size: 18px; line-height: 1;
  transform: rotate(var(--rot, 0deg)) scale(var(--flip-x, 1), var(--flip-y, 1));
}
/* Il "..." affianca il cestino sopra al riquadro. Stessa riga e stessa contro-
   rotazione: due comandi che si usano guardando, non trascinando. */
.ed-altro {
  position: absolute; left: 50%; top: -40px; z-index: 3;
  width: 30px; height: 30px; margin-left: 2px; border-radius: 50%;
  place-items: center;
  background: var(--primary); color: var(--primary-fg); border: 0; cursor: pointer;
  font-size: 18px; line-height: 1;
  transform: rotate(var(--rot, 0deg)) scale(var(--flip-x, 1), var(--flip-y, 1));
}

/* Il menu sta nella FINESTRA dell'editor, non nel livello: dentro erediterebbe la
   rotazione e uscirebbe storto. */
.ed-menu {
  position: absolute; z-index: 20; width: 210px; padding: .25rem;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 12px 28px -12px rgb(10 10 10 / .4);
  display: flex; flex-direction: column;
  /* ⚠ Da quando in fondo ci sono anche i filtri AI le voci non sono più un numero
     noto: arrivano dal server e uno in più allunga il menu. Il TETTO all'altezza lo
     mette `apriMenu` misurando la finestra dell'editor — qui non si può, perché una
     percentuale del viewport non dice niente su quanto è alta quella finestra. */
  overflow-y: auto;
}
.ed-menu button {
  display: flex; align-items: center; gap: .55rem;
  /* ⚠ `flex: none` come per l'hr qui sotto: in un menu che deborda, le voci
     verrebbero schiacciate per far stare tutto, invece di lasciar scorrere. */
  flex: none;
  padding: .45rem .6rem; border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--text); font: inherit; font-size: .8125rem;
  text-align: left; cursor: pointer;
}
/* Tutte di contorno e con lo stesso tratto: a 16 px la differenza fra un'icona
   piena e una vuota si nota più del disegno, e il menu sembrerebbe raccogliticcio. */
.ed-menu svg {
  flex: none; width: 16px; height: 16px; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
  color: var(--muted);
}
.ed-menu button:hover svg { color: var(--text); }
.ed-menu button:hover { background: var(--bg); }
/* ⚠ `flex: none`, o la riga non si vede. È alta 1px e in un contenitore flex può
   RESTRINGERSI: da quando il menu ha un tetto all'altezza, il flex ha cercato di far
   stare diciassette voci in 520 px e l'unico figlio che poteva cedere era proprio
   l'hr — schiacciato a 0. Restavano gli spazi fra i gruppi e nessuna linea, senza
   nessun errore. Stessa famiglia della trappola del `flex-basis` in un contenitore a
   colonna: in un flex le misure sono richieste, non ordini. */
.ed-menu hr {
  flex: none;
  height: 1px; margin: .35rem .3rem; border: 0; background: var(--line);
}

/* Il filo che li lega al riquadro, come per la rotazione. Parte dal cestino perché
   è il più vicino al centro: con i due bottoni affiancati, uno solo basta. */
.ed-kill::after {
  content: ''; position: absolute; left: 50%; bottom: -10px;
  width: 1px; height: 10px; background: var(--primary);
}

/* Quattro angoli: si ridimensiona da quello che si ha più comodo, e quello
   opposto resta fermo. Il cursore segue la diagonale dell'angolo. */
.ed-grip {
  position: absolute; z-index: 2;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--primary); border: 2px solid var(--bg);
}
.ed-grip-tl { left: -9px;  top: -9px;    cursor: nwse-resize; }
.ed-grip-tr { right: -9px; top: -9px;    cursor: nesw-resize; }
.ed-grip-bl { left: -9px;  bottom: -9px; cursor: nesw-resize; }
.ed-grip-br { right: -9px; bottom: -9px; cursor: nwse-resize; }

/* La rotazione sta staccata SOTTO il riquadro: dentro finirebbe sopra al disegno
   e, con un dito, sarebbe indistinguibile dal trascinamento. */
.ed-turn {
  position: absolute; left: 50%; bottom: -38px; z-index: 3;
  width: 26px; height: 26px; margin-left: -13px; border-radius: 50%;
  place-items: center; cursor: grab;
  background: var(--bg); border: 1px solid var(--line);
  box-shadow: 0 1px 3px rgb(10 10 10 / .18);
  transform: rotate(var(--rot, 0deg)) scale(var(--flip-x, 1), var(--flip-y, 1));
}
.ed-turn svg {
  width: 15px; height: 15px; fill: none; stroke: var(--text);
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
/* Il filo che lega la maniglia al riquadro: senza, sembra un pulsante sciolto. */
.ed-turn::before {
  content: ''; position: absolute; left: 50%; top: -12px;
  width: 1px; height: 12px; background: var(--primary);
}

.ed-foot {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: .8rem 1rem; border-top: 1px solid var(--line);
}
.ed-info { display: flex; flex-direction: column; min-width: 0; }
.ed-info span { color: var(--muted); font-size: .9rem; }
.ed-buy {
  flex: none; padding: .8rem 1.4rem; border-radius: 999px; border: 0; cursor: pointer;
  background: var(--primary); color: var(--primary-fg); font: inherit; font-weight: 600;
}
.ed-buy:disabled { opacity: .6; cursor: progress; }

.ed-tools {
  flex: none; display: flex; justify-content: center; gap: 3rem;
  padding: .6rem 0 calc(.8rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
}
.ed-tool {
  display: grid; justify-items: center; gap: .2rem;
  background: none; border: 0; cursor: pointer; color: var(--text);
  font: inherit; font-size: .7rem;
}
.ed-tool svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.ed-tool.on { color: var(--primary); }

/* I pannelli si aprono sopra la barra, uno alla volta: due aperti insieme
   coprirebbero il prodotto, che è la cosa che si sta guardando. */
.ed-panel {
  flex: none; display: flex; flex-direction: column; gap: .5rem;
  padding: .8rem 1rem; border-top: 1px solid var(--line); background: var(--card);
}
.ed-panel[hidden] { display: none; }
.ed-panel textarea, .ed-panel input[type="text"], .ed-panel select {
  width: 100%; padding: .55rem .7rem; font: inherit;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--line); border-radius: 10px;
}
/* ⚠ Dentro alla frase i controlli tornano parole sottolineate: la regola qui sopra
   vale per gli altri pannelli dell'editor (testo, carattere), dove le caselle
   servono davvero. */
.ed-say input[type="text"], .ed-say select {
  width: auto; padding: 0 .05rem .1rem; background: transparent;
  border: 0; border-bottom: 2px solid var(--line); border-radius: 0;
}
.ed-say .prompt-box input[type="text"] { border-bottom: 0; padding: .25rem 0; }
/* La frase dentro all'editor: stesse classi della home, ma più piccola — il
   pannello è largo quanto un telefono anche su un monitor. */
.ed-say { font-size: .9375rem; line-height: 1.6; gap: .35rem; }
.ed-say .clause { gap: .3rem; }
.ed-say .prompt-box { padding: .2rem .25rem .2rem .6rem; }
.ed-say .say em, .ed-say em { font-size: .875rem; }

.ed-row { display: flex; gap: .5rem; align-items: center; }
.ed-row select { flex: 1 1 auto; min-width: 0; }
.ed-row input[type="color"] {
  flex: none; width: 44px; height: 38px; padding: 2px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--bg);
}
.ed-go {
  padding: .65rem 1rem; border-radius: 10px; border: 0; cursor: pointer;
  background: var(--primary); color: var(--primary-fg); font: inherit; font-weight: 600;
}
.ed-go:disabled { opacity: .6; cursor: progress; }

/* Da tablet in su il palco non deve gonfiarsi: resta della misura di un prodotto. */
@media (min-width: 720px) {
  /* Su schermi alti il palco smette di crescere: un prodotto grande due metri
     non si guarda meglio, e i comandi finirebbero lontanissimi. */
  .ed-view { max-height: 520px; max-width: 620px; }
}

/* Il layer copre lo schermo, il CONTENUTO no: si ferma alla stessa larghezza del
   feed (960px). Su un monitor largo una barra di comandi distesa da bordo a bordo
   allontana i pulsanti dal prodotto, che è la cosa che si sta guardando.
   Si fa col padding invece che con un contenitore interno, così i bordi delle
   fasce restano pieni e il markup non cresce. */
.ed-scroll, .ed-foot, .ed-tools, .ed-panel {
  padding-inline: max(1rem, calc((100% - 960px) / 2));
}

/* I campi che il filtro aggiunge dentro il pannello AI: stesso aspetto della frase
   della pagina, perché è lo stesso codice a costruirli. */
.ed-inputs { display: flex; flex-direction: column; gap: .5rem; }
.ed-inputs[hidden] { display: none; }
.ed-inputs .drops { display: flex; gap: .5rem; }
.ed-inputs .field { display: flex; flex-direction: column; gap: .2rem; font-size: .8rem; }
.ed-mini { flex: none; font-style: italic; color: var(--muted); font-size: .85rem; }


/* ===== il modulo a celle (redesign 2026-09) ================================== */
/* ⚠ Tutto sotto `.composer`: il pannello AI dell'editor usa ancora la frase (`.say`,
   `.prompt-box`, `.clause`) e quelle regole più su restano per lui. Il form della
   home non ha più nessuna di quelle classi. */

/* Il pannello: fondo viola scurissimo e il bordo arcobaleno. Il bordo è un fondo
   conico MASCHERATO, non un `border-image`: quello non rispetta il raggio. */
.composer {
  position: relative; isolation: isolate;
  gap: .7rem; padding: .9rem;
  background: var(--card); border-radius: var(--radius);
}
.composer::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  padding: 1.5px; border-radius: inherit;
  background: var(--spectrum-giro);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}

/* ---- le tre celle */
.celle { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .55rem; }
.cella {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .45rem; min-width: 0; aspect-ratio: 6 / 5; padding: .85rem .7rem;
  background: var(--surface); color: var(--text);
  border: .5px solid rgb(255 255 255 / .22); border-radius: 6px;
  font: inherit; cursor: pointer;
  transition: border-color .12s ease, transform .12s ease;
}
.cella:hover { border-color: rgb(255 255 255 / .5); }
.cella:active { transform: scale(.98); }
.cella:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.cella-img {
  position: relative; display: grid; place-items: center;
  width: auto; height: 58%; aspect-ratio: 1 / 1; flex: none;
  border-radius: 8px; overflow: hidden; background: #fff;
}
.cella-img > img:not(.cella-sagoma) { width: 100%; height: 100%; object-fit: cover; display: block; }
#cella-prodotto .cella-img > img { object-fit: contain; }
.cella-img > img[hidden] { display: none; }
/* Lo stile in un tondo, come nel disegno: si distingue a colpo d'occhio dal prodotto. */
.cella-tonda { border-radius: 50%; overflow: visible; background: transparent; }
.cella-tonda > img:not(.cella-sagoma) { border-radius: 50%; }
:is(#cella-stile, #ed-cella-stile).vuota .cella-tonda { background: var(--bg); border: 1px dashed rgb(255 255 255 / .3); }
/* Il ritaglio, in piccolo in basso a destra dello stile. */
.cella-sagoma {
  position: absolute; right: -8%; bottom: -8%;
  width: 38%; height: 38%; padding: 3px;
  background: var(--surface); border: 1px solid rgb(255 255 255 / .3); border-radius: 50%;
}
.cella-sagoma[hidden] { display: none; }
/* Il filtro: l'esempio se c'è, altrimenti l'icona, senza fondo bianco. */
:is(#cella-filtro, #ed-cella-filtro) .cella-img { background: transparent; }
:is(#cella-filtro, #ed-cella-filtro) .cella-img:has(> img:not([hidden])) { background: #fff; }
.cella-icona {
  width: 78%; height: 78%; fill: none; stroke: var(--muted);
  stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round;
}
.cella-icona[hidden] { display: none; }
.cella.spenta .cella-icona { opacity: .5; }
.cella-nome {
  max-width: 100%; font-family: var(--f-mono); font-size: .6875rem; line-height: 1.25;
  color: var(--muted); text-align: center;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* ---- la foto: una riga tratteggiata, due pulsanti di sola icona e l'etichetta */
.foto-riga { display: flex; flex-direction: column; gap: .4rem; }
:is(.composer, #ed-panel-ai) .foto-cta {
  display: flex; align-items: stretch; gap: 0; width: 100%;
  min-height: 2.75rem; background: var(--bg);
  border: 1px dashed rgb(255 255 255 / .35); border-radius: 6px;
}
:is(.composer, #ed-panel-ai) .foto-cta .foto-pick, :is(.composer, #ed-panel-ai) .foto-cta .foto-cam {
  flex: none; width: 3rem; height: auto; min-height: 2.75rem;
  background: transparent; color: var(--muted);
  border: 0; border-right: 1px dashed rgb(255 255 255 / .35); border-radius: 0;
}
:is(.composer, #ed-panel-ai) .foto-cta .foto-pick:hover, :is(.composer, #ed-panel-ai) .foto-cta .foto-cam:hover { background: var(--hover); color: var(--text); }
:is(.composer, #ed-panel-ai) .foto-cta .foto-cam[hidden] { display: none; }
:is(.composer, #ed-panel-ai) .foto-pick svg, :is(.composer, #ed-panel-ai) .foto-cam svg { width: 22px; height: 22px; stroke-width: 1.4; }
:is(.composer, #ed-panel-ai) .foto-pick img { width: 30px; height: 30px; border-radius: 4px; }
:is(.composer, #ed-panel-ai) .foto-label {
  flex: 1 1 auto; align-self: center; padding: 0 .75rem;
  font-size: .875rem; font-weight: 400; text-align: center; color: var(--muted);
}
:is(.composer, #ed-panel-ai) .foto-togli { align-self: center; margin-right: .5rem; background: var(--surface); }
/* Gli stati restano quelli di prima: rosso quando serve, giallo quando c'è. */
:is(.composer, #ed-panel-ai) .foto-cta.serve { border-color: var(--err); }
:is(.composer, #ed-panel-ai) .foto-cta.serve .foto-pick, :is(.composer, #ed-panel-ai) .foto-cta.serve .foto-cam { color: var(--err); border-right-color: var(--err); }
:is(.composer, #ed-panel-ai) .foto-cta.filled { border-style: solid; border-color: var(--primary); }
:is(.composer, #ed-panel-ai) .foto-cta.filled .foto-pick { border-right-color: rgb(255 255 255 / .2); }

/* Le foto in più chieste da un filtro: sotto, a destra, come una riga della stessa. */
:is(.composer, #ed-panel-ai) .filter-drops { --coda-h: 2.6rem; justify-content: flex-end; }
:is(.composer, #ed-panel-ai) .filter-drops .foto-label { font-size: .8125rem; padding: 0; }
:is(.composer, #ed-panel-ai) .filter-drops .drop, :is(.composer, #ed-panel-ai) .filter-drops .drop-scatta {
  background: var(--bg); border: 1px dashed rgb(255 255 255 / .35); border-radius: 6px; color: var(--muted);
}
:is(.composer, #ed-panel-ai) .filter-drops .drop.filled { border: 1px solid var(--primary); }
:is(.composer, #ed-panel-ai) .drop-wrap.serve .drop, :is(.composer, #ed-panel-ai) .drop-wrap.serve .drop-scatta { border-color: var(--err); color: var(--err); }

/* ---- il prompt: nero, bordo giallo, testo pieno */
.prompt-campo {
  width: 100%; min-width: 0; height: 2.75rem; padding: 0 1rem;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--primary); border-radius: 6px;
  font: inherit; font-size: 1rem; font-weight: 700; caret-color: var(--primary);
}
.prompt-campo::placeholder { font-weight: 400; color: var(--muted); }
.prompt-campo:focus { outline: none; box-shadow: 0 0 0 3px rgb(244 215 85 / .25); }
@media (max-width: 559px) { .prompt-campo { font-size: 16px; } }

/* ---- "Genera": la pillola gialla con la freccia a destra */
.genera {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  width: 100%; height: 2.75rem; padding: 0 1.5rem 0 1.7rem;
  background: var(--primary); color: var(--primary-fg);
  border: 0; border-radius: 999px; cursor: pointer;
  font-family: var(--f-display); font-size: .975rem; font-weight: 800; letter-spacing: .01em;
  transition: filter .12s ease, transform .12s ease, opacity .12s ease;
}
.genera svg {
  width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.genera:hover:not(:disabled) { filter: brightness(1.06); }
.genera:active:not(:disabled) { transform: scale(.99); }
.genera:disabled { opacity: .45; cursor: not-allowed; }
.genera:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }

/* ---- i chip "prova con": pillole di solo contorno */
.chips-title {
  font-family: var(--f-display); font-size: .625rem; font-weight: 700;
  letter-spacing: .12em; color: var(--muted);
}
.chips { gap: .5rem; }
.chip-try {
  padding: .3rem .7rem; background: transparent;
  border: 1px solid var(--muted); color: var(--muted);
  font-size: .8125rem; font-weight: 400;
}
.chip-try:hover { border-color: var(--text); color: var(--text); transform: none; }
.chip-emoji:empty { display: none; }

/* ===== il layer delle scelte ================================================= */
body.scelta-aperta { overflow: hidden; }
.sheet-scelta { background: rgb(0 0 0 / .6); }
.sheet-scelta .sheet-panel {
  max-width: min(760px, 100vw); max-height: 92dvh; padding: .6rem 0 0;
  background: var(--bg); border-color: rgb(255 255 255 / .12);
  border-radius: 18px 18px 0 0;
}
/* La maniglia: dice che il pannello sale dal basso, anche se si chiude col pulsante. */
.sheet-maniglia {
  flex: none; align-self: center; width: 4rem; height: 5px; margin-bottom: .8rem;
  border-radius: 999px; background: var(--surface);
}
.sheet-scelta .sheet-head { padding: 0 1.1rem; align-items: flex-start; }
.sheet-scelta .sheet-head h2 {
  font-family: var(--f-display); font-size: clamp(1.1rem, 5vw, 1.45rem);
  font-weight: 700; line-height: 1.18; letter-spacing: -.01em;
}
.sheet-scelta .sheet-close { background: var(--surface); border-color: transparent; }
.scelta-corpo {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: 1.1rem 1.1rem 1rem;
}

/* "Hai selezionato": l'immagine a sinistra e i dati a destra. */
.scelta-sel {
  display: grid; grid-template-columns: minmax(0, 36%) minmax(0, 1fr);
  gap: 1rem; align-items: start; margin-bottom: 1.6rem;
}
.scelta-sel-img {
  position: relative; aspect-ratio: 1 / 1; border-radius: 10px; overflow: hidden;
  background: var(--card); display: grid; place-items: center;
}
.scelta-sel-img.chiara { background: #fff; }
.scelta-sel-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.scelta-sel-img.chiara img { object-fit: contain; }
.scelta-sel-img img[hidden] { display: none; }
.scelta-sel-info { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: .45rem; }
.scelta-sel-cap { margin: 0; font-size: .8125rem; color: var(--muted); }
#scelta-sel-nome { font-size: 1.05rem; font-weight: 700; line-height: 1.2; }
.scelta-sel-desc { margin: 0; font-size: .875rem; line-height: 1.35; color: var(--text); }
.scelta-sel-desc[hidden], .scelta-sel-colori[hidden], .scelta-sel-prezzo[hidden] { display: none; }
.scelta-sel-colori { display: flex; flex-wrap: wrap; gap: .35rem; }
.scelta-colore {
  width: 1.25rem; height: 1.25rem; border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / .25);
}
.scelta-sel-prezzo { font-size: 1rem; }

/* Il ritaglio, dentro il layer degli stili: un menu a tutta larghezza. */
.scelta-sagoma { display: flex; width: 100%; margin-top: .3rem; }
.scelta-sagoma[hidden] { display: none; }
.scelta-sagoma .shape-btn {
  width: 100%; max-width: 16rem; height: 2.8rem; justify-content: flex-start; gap: .6rem;
  padding: 0 .8rem; background: var(--surface);
  border: .5px solid rgb(255 255 255 / .22); border-radius: 6px; line-height: 1.2;
}
.scelta-sagoma .shape-btn img { width: 24px; height: 24px; }
.shape-nome { flex: 1 1 auto; text-align: left; font-size: .9375rem; color: var(--text); }
.scelta-sagoma .shape-btn:disabled { cursor: not-allowed; opacity: .55; }
.scelta-sagoma .shape-menu { left: 0; right: auto; background: var(--surface); }
.scelta-sagoma .shape-opt:hover { background: var(--card); }

/* La griglia: tre colonne sul telefono, quattro dove c'è spazio. */
.scelta-griglia {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.1rem .8rem;
}
@media (min-width: 560px) { .scelta-griglia { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.scelta-tessera {
  display: flex; flex-direction: column; align-items: flex-start; gap: .35rem; min-width: 0;
  padding: 0; background: none; border: 0; color: var(--text); font: inherit;
  text-align: left; cursor: pointer;
}
.scelta-tessera:disabled { opacity: .4; cursor: not-allowed; }
.scelta-fig {
  display: grid; place-items: center; width: 100%; aspect-ratio: 1 / 1;
  border-radius: 10px; overflow: hidden; background: var(--card);
  outline: 2px solid transparent; outline-offset: 2px;
  transition: outline-color .12s ease, transform .12s ease;
}
.scelta-fig.chiara { background: #fff; }
.scelta-fig img { width: 100%; height: 100%; object-fit: cover; display: block; }
.scelta-fig.chiara img { object-fit: contain; }
.scelta-tessera:hover:not(:disabled) .scelta-fig { transform: translateY(-2px); }
.scelta-tessera.on .scelta-fig { outline-color: var(--primary); }
.scelta-tessera:focus-visible { outline: none; }
.scelta-tessera:focus-visible .scelta-fig { outline-color: var(--text); }
.scelta-tessera strong { font-size: .8125rem; font-weight: 700; line-height: 1.2; }
.scelta-prezzo { margin-top: -.2rem; font-size: .8125rem; }
.scelta-segnaposto { display: grid; place-items: center; width: 100%; height: 100%; }
.scelta-segnaposto svg {
  width: 45%; height: 45%; fill: none; stroke: var(--muted);
  stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round;
}

/* "Conferma": fermo in fondo, sempre raggiungibile col pollice. */
.scelta-ok {
  flex: none; width: auto;
  margin: 0 1.1rem calc(.9rem + env(safe-area-inset-bottom));
}
/* Sul desktop il riquadro resta una miniatura: a 36% di 760 px schiacciava la griglia sotto. */
@media (min-width: 560px) { .scelta-sel { grid-template-columns: 11rem minmax(0, 1fr); } }


/* ===== la foto e il form, allineati (desktop) =============================== */
/* ⚠ Comanda la FOTO: è larga quanto la sua colonna e alta 4/3, come prima. Il
   form si allinea al suo bordo alto, e i chip gli stanno SUBITO SOTTO — sia "Prova
   con" sia "Varianti". Appoggiarli al fondo della foto li faceva scendere: durante
   una ricerca sotto la scheda ci sono anche colori e pulsanti, e i chip finivano
   lontanissimi dal form, staccati da quello che modificano.
   Le righe sono "auto 1fr": la prima la fa il form, la seconda si prende il resto
   dell'altezza della foto, e i chip stanno in cima a quella.
   Si era provato anche la foto alta quanto il form: allineata, ma piccola, perché
   il form è molto più basso di una foto a piena colonna. */
@media (min-width: 860px) {
  .hero {
    grid-template-rows: auto 1fr;
    align-items: start;
  }
  .hero-stage { align-self: start; }
  .hero-chips { align-self: start; }
}

/* ===== lo sfondo: l'aurora della bozza, più tenue ============================ */
/* Quattro macchie di colore sfocate dietro a tutto, come in Swaipe.me.html, con
   l'opacità abbassata: sopra ci stanno foto di prodotti su fondo bianco, e uno
   sfondo troppo acceso le fa sembrare grigie.
   ⚠ `z-index: -1` e non un fondo sul body: il fondo del body passa al canvas, che
   sta SOTTO a tutto, e l'aurora ci si dipinge sopra senza coprire la pagina. */
body { background: #0B0716; }
.aurora { position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.aurora i {
  position: absolute; border-radius: 50%; filter: blur(80px);
  opacity: .32; mix-blend-mode: screen; will-change: transform;
  animation: aurora 18s ease-in-out infinite alternate;
}
.aurora i:nth-child(1) { width: 60vw; height: 60vw; left: -18vw; top: -22vw; background: #8261EE; }
.aurora i:nth-child(2) { width: 46vw; height: 46vw; right: -14vw; top: 6vw; background: #3EA8E6; animation-delay: -5s; }
.aurora i:nth-child(3) { width: 40vw; height: 40vw; left: 30vw; top: 32vw; background: #FF3E41; opacity: .18; animation-delay: -9s; }
.aurora i:nth-child(4) { width: 34vw; height: 34vw; right: 8vw; bottom: -10vw; background: #4EDD8B; opacity: .16; animation-delay: -12s; }
/* Scendendo la pagina il colore si spegne: resta un'atmosfera in alto, non un
   fondo a macchie sotto al listino. */
.aurora::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 0, rgb(11 7 22 / .5) 60vh, rgb(11 7 22 / .8) 140vh);
}
@keyframes aurora { to { transform: translate3d(6vw, 5vw, 0) scale(1.15); } }
@media (max-width: 720px) { .aurora i { filter: blur(60px); } }
@media (prefers-reduced-motion: reduce) { .aurora i { animation: none; } }

/* ===== la frase sopra il form ================================================ */
/* Unbounded come i titoli del disegno. `text-wrap: balance`: su due righe le
   spezza a metà invece di lasciare una parola sola sotto. */
.hero-frase {
  margin: 0 0 .9rem;
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.3rem, 5.4vw, 1.9rem); line-height: 1.15; letter-spacing: -.01em;
  color: var(--text); text-wrap: balance;
}
/* Sul telefono sopra la frase c'è l'etichetta gialla della foto, che sporge sotto
   la scheda: senza spazio la frase ci si attaccava. */
@media (max-width: 859px) { .hero-frase { margin-top: .9rem; } }


/* ===== le sezioni sotto la hero (redesign 2026-09) ============================ */
/* Solo CSS: markup e testi sono quelli di prima. Valori da Figma
   (home-mobile-css-figma.txt) e dalla bozza Swaipe.me.html; i caratteri sono i
   nostri. Sta in fondo al foglio apposta: vince sulle regole più su senza doverle
   riscrivere una per una. */

/* ---- i titoli: Unbounded, col pallino giallo del disegno */
.block { margin-bottom: 3.2rem; }
.block h2 {
  display: flex; align-items: baseline; gap: .55rem;
  margin: 0 0 .5rem;
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.35rem, 4.6vw, 1.9rem); line-height: 1.15; letter-spacing: -.01em;
}
.block h2::before {
  content: ""; flex: none; width: .36em; height: .36em; border-radius: 50%;
  background: var(--primary); transform: translateY(-.05em);
}
.block-sub { margin: .3rem 0 1.2rem; font-size: .9375rem; line-height: 1.5; color: var(--muted); max-width: 62ch; }

/* ---- come funziona: tre card piene, giallo / viola / verde */
.steps { gap: 1rem; margin-top: 1.2rem; }
.step {
  padding: .9rem .9rem 1.3rem; border: 0; border-radius: 16px;
  color: #0B0716; box-shadow: none;
  transition: transform .25s ease;
}
.step:nth-child(1) { background: #F4D755; }
.step:nth-child(2) { background: #B987F4; }
.step:nth-child(3) { background: #54DF97; }
@media (hover: hover) { .step:hover { transform: translateY(-4px) rotate(-.5deg); } }
.step-media { border: 0; background: #fff; border-radius: 12px; }
.step-cap { background: #0B0716; color: #fff; }
.step-n {
  background: #0B0716; border: 0; color: #fff;
  font-family: var(--f-display); font-weight: 700;
}
.step h3 {
  margin: .2rem 0 .35rem; font-family: var(--f-display); font-weight: 700;
  font-size: 1.35rem; line-height: 1.1; letter-spacing: -.01em;
}
.step p { color: rgb(11 7 22 / .8); font-size: .9375rem; line-height: 1.45; }

/* ---- quanto costa: la prima riga gialla, le altre sul viola scuro */
.pricing {
  background: var(--card); border: 1px solid rgb(255 255 255 / .18);
  border-radius: 14px; box-shadow: none;
}
.price-row { border-top-color: rgb(255 255 255 / .12); padding: 1rem 1.1rem; }
.price-row strong { font-family: var(--f-display); font-weight: 700; font-size: .875rem; letter-spacing: .005em; }
.price-row small { margin-top: .15rem; }
.price-row .amount { font-family: var(--f-display); font-weight: 700; font-size: .9375rem; }
.price-row.first { background: var(--primary); color: #0B0716; }
.price-row.first small { color: rgb(11 7 22 / .65); }
.price-row.first .amount { font-size: 1.25rem; }
.price-row.first .info-btn { background: transparent; border-color: rgb(11 7 22 / .35); color: #0B0716; }
.price-row.first .info-btn:hover { border-color: #0B0716; }
.price-row.first .info-btn[aria-expanded="true"] { background: #0B0716; border-color: #0B0716; color: var(--primary); }
.info-btn { background: transparent; border-color: rgb(255 255 255 / .3); }
.price-info { padding: .9rem 1.1rem 1.1rem; background: rgb(255 255 255 / .03); }
.pi-taglie th, .pi-taglie td { border-bottom-color: rgb(255 255 255 / .12); }
.price-example { margin-top: 1rem; font-size: .9375rem; line-height: 1.5; }

/* ---- i filtri: la freccia gialla, il nome in Unbounded */
.fl { border-color: rgb(255 255 255 / .14); border-radius: 16px; box-shadow: none; }
.fl-freccia { color: var(--primary); font-size: 1.3rem; font-weight: 700; }
.fl-nome { font-family: var(--f-display); font-weight: 700; font-size: 1.05rem; letter-spacing: -.005em; }
.fl-hook { font-size: .875rem; }

/* ---- le domande: viola chiaro, il + arancione */
.faq {
  margin-top: .55rem; background: var(--surface);
  border: .5px solid rgb(255 255 255 / .22); border-radius: 8px;
}
.faq summary { padding: 1rem 2.8rem 1rem 1.1rem; font-weight: 700; font-size: .9375rem; }
.faq summary::after {
  right: 1.1rem; color: var(--orange); font-size: 1.5rem; font-weight: 300;
  transition: transform .2s ease;
}
/* Il + gira e diventa una ×, invece di cambiare carattere: si vede che è lo stesso
   comando, che ora chiude. */
.faq[open] summary::after { content: '+'; transform: translateY(-50%) rotate(45deg); }
.faq[open] { background: #4a3c53; }
.faq p { padding: 0 1.1rem 1.1rem; color: #d8cde0; font-size: .9375rem; }

/* ---- ora tocca a te: il bordo arcobaleno del form e il pulsante giallo */
.cta {
  position: relative; isolation: isolate;
  padding: 1.6rem 1.4rem; border-radius: 16px;
  background: var(--card); color: var(--text);
}
.cta::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  padding: 1.5px; border-radius: inherit; background: var(--spectrum-giro);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
/* Il titolo dell'invito è l'unico senza pallino: sta dentro a un riquadro, e il
   pallino segna l'inizio di una sezione. */
.cta h2::before { content: none; }
.cta h2 { font-size: clamp(1.4rem, 5vw, 2.1rem); }
.cta p { color: var(--muted); opacity: 1; }
.cta-go {
  padding: .9rem 1.6rem; background: var(--primary); color: var(--primary-fg);
  font-family: var(--f-display); font-weight: 700; font-size: .9375rem;
  transition: filter .12s ease, transform .12s ease;
}
.cta-go:hover { background: var(--primary); filter: brightness(1.06); transform: translateY(-1px); }

/* ---- il piede: la barra arcobaleno in cima, il nome col ".me" a colori */
.site-foot {
  position: relative; border-top: 0;
  background: rgb(0 0 0 / .35);
}
.site-foot::before { content: ""; display: block; height: 6px; background: var(--spectrum); }
.foot-brand {
  font-family: var(--f-display); font-weight: 700; font-size: 1.2rem; letter-spacing: -.01em;
}
.foot-brand span {
  background: var(--spectrum); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.foot-link a:hover { color: var(--primary); }

/* ===== residui del tema chiaro (redesign 2026-09) ============================= */
/* ⚠ Qui c'erano sfondi bianchi pensati per testo scuro. Col testo diventato bianco
   lo zoom dell'editor era una pillola bianca VUOTA: i pulsanti c'erano, le scritte
   bianche su bianco no. Stesso rischio per chiunque metta `background: #fff` e
   lasci `color: var(--text)`. */
.ed-sides, .ed-zoom {
  background: rgb(11 7 22 / .86); border-color: rgb(255 255 255 / .18);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.ed-side { color: var(--muted); }
.ed-side.on { color: var(--primary-fg); background: var(--primary); }
.stage { background: rgb(11 7 22 / .82); border-color: transparent; color: #fff; }

/* I messaggi: scuri come il resto, il colore sta nel bordo e nell'icona. */
.hint[data-kind="ok"] { background: #0e2419; border-color: #29DD76; color: #c9f7dc; }
.hint[data-kind="ok"]::before { background: #29DD76; color: #0B0716; }
.hint[data-kind="bad"] { background: #2a0d12; border-color: var(--err); color: #ffd3d4; }
.hint[data-kind="bad"]::before { color: #fff; }

/* Titoli dei fogli (carrello, conferma) e pulsanti principali nei caratteri nuovi. */
.sheet-head h2 { font-family: var(--f-display); font-weight: 700; font-size: 1.2rem; letter-spacing: -.005em; }
.primary { font-family: var(--f-display); font-weight: 700; }


/* ===== la striscia bianca fra il form e "Come funziona" ======================= */
/* ⚠ Il ritaglio orizzontale sta sul BODY, non più su `.home`: la striscia è larga
   quanto la finestra ed esce dalla colonna di 960 px, e `.home` la tagliava ai suoi
   bordi. Sul body fa lo stesso lavoro di prima — niente scorrimento laterale della
   pagina — senza fermare quello che deve uscire dalla colonna. */
body { overflow-x: clip; }
.home { overflow-x: visible; }

/* ⚠ Il ritaglio sta QUI, su un contenitore largo esattamente quanto lo schermo, e
   non solo sul body. La striscia è larga 40 px più dello schermo (sotto): sul
   telefono il browser allargava la pagina per farcela stare — 411 px su uno schermo
   da 390 — e tutto ciò che è fisso a destra, come la ✕ dell'editor, usciva di
   qualche pixel. `overflow-x: clip` taglia solo di lato: in verticale la striscia
   inclinata sporge sopra e sotto senza essere tagliata. */
.band-wrap {
  width: 100vw; margin: 1.4rem 0 2.6rem calc(50% - 50vw);
  overflow-x: clip;
}
.band {
  /* 40 px più dello schermo: girata di 2 gradi, una striscia larga esattamente
     quanto la finestra lascerebbe scoperti due triangoli agli angoli. */
  width: calc(100% + 40px); margin-left: -20px;
  transform: rotate(-2deg);
  background: #fff; color: #0B0716;
  padding: .55rem 0; overflow: hidden;
  box-shadow: 0 20px 50px rgb(0 0 0 / .45);
}
.band-track { display: flex; width: max-content; animation: band 26s linear infinite; }
.band-meta { display: flex; align-items: center; flex: none; }
.band-meta span {
  font-family: var(--f-display); font-weight: 800; text-transform: uppercase;
  font-size: clamp(1rem, 3.6vw, 1.5rem); letter-spacing: -.005em; white-space: nowrap;
}
.band-freccia {
  width: .9em; height: .9em; margin: 0 .45em; flex: none;
  fill: none; stroke: #8261EE; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
  font-size: clamp(1rem, 3.6vw, 1.5rem);
}
.band-stella {
  width: 1em; height: 1em; margin: 0 .6em; flex: none; fill: #8261EE;
  font-size: clamp(1rem, 3.6vw, 1.5rem);
}
@keyframes band { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .band-track { animation: none; } }

/* ===== come funziona: le card di Figma ======================================= */
/* L'occhiello col pallino e sotto il titolo vero. Qui il pallino sta sull'occhiello,
   quindi il titolo non lo ripete. */
.eyebrow {
  display: flex; align-items: center; gap: .5rem; margin: 0 0 .7rem;
  font-family: var(--f-display); font-weight: 700; font-size: .8125rem;
}
.eyebrow::before {
  content: ""; width: .6rem; height: .6rem; border-radius: 50%; background: var(--primary);
}
.eyebrow + h2::before { content: none; }
.come h2 { max-width: 16ch; }

.come .steps { gap: .9rem; margin-top: 1.4rem; align-items: stretch; }
.come .step {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column;
  padding: 1.05rem 1.1rem 1.15rem; border-radius: 14px;
}
.come .step:hover { transform: none; }
.come .step-swipe { min-height: 17.5rem; }
.come .step-buy { min-height: 16rem; }

.come .step .step-num {
  margin: 0; font-family: var(--f-display); font-weight: 700; text-transform: uppercase;
  font-size: .5625rem; letter-spacing: .35em;
}
.come .step h3 {
  position: relative; z-index: 2;
  margin: .85rem 0 .9rem; font-size: 1.15rem; line-height: 1.12;
}
/* Nelle card con la persona il titolo e il testo stanno nella metà sinistra: la
   destra è della foto. */
.step-swipe h3, .step-buy h3 { max-width: 62%; }
.come .step .step-txt {
  position: relative; z-index: 0;
  margin: auto 0 0; padding-top: .9rem;
  font-size: .8125rem; line-height: 1.35; color: rgb(11 7 22 / .85);
}
.come .step-swipe .step-txt, .come .step-buy .step-txt { max-width: 50%; }

/* 01: il campo bianco in cui si scrive, col cursore giallo. */
.step-input {
  display: flex; align-items: center; height: 2.6rem; padding: 0 .85rem;
  background: #fff; border-radius: 5px;
  font-weight: 700; font-size: .875rem; color: #0B0716; white-space: nowrap; overflow: hidden;
}
.step-caret {
  flex: none; width: 2px; height: 1.1em; margin-left: .3rem; background: var(--primary);
  animation: blink 1s steps(1) infinite;
}
@media (prefers-reduced-motion: reduce) { .step-caret { animation: none; } }

/* 02 e 03: il riquadro più scuro coi pulsanti del feed, e la persona davanti. */
.step-panel {
  position: relative; z-index: 0;
  display: flex; align-items: center; gap: .7rem;
  height: 6.6rem; padding-left: 3.4rem; border-radius: 12px;
}
.step-swipe .step-panel { background: rgb(60 20 120 / .16); }
.step-buy .step-panel { height: 5.6rem; padding-left: 1.4rem; background: rgb(0 70 35 / .16); }
.step-tasto {
  display: grid; place-items: center; width: 2.3rem; height: 2.3rem; border-radius: 50%; flex: none;
}
.step-tasto svg {
  width: 1rem; height: 1rem; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.step-tasto.giallo { background: var(--primary); color: #0B0716; }
.step-tasto.vuoto { border: 1.5px solid rgb(255 255 255 / .85); color: #fff; }
/* ⚠ `object-fit` e non una larghezza fissa: la foto è alta quanto la card, e sul
   desktop, dove le tre card si allungano alla più alta, una coppia larga come la
   sua altezza coprirebbe tutto il testo. Così non passa mai la metà della card. */
.step-persona {
  position: absolute; right: 0; bottom: 0; z-index: 1;
  height: 100%; width: 50%; object-fit: contain; object-position: right bottom;
  pointer-events: none;
}

/* ===== il pannello AI dell'editor, come il form (redesign 2026-09) =========== */
/* Stesse classi del form in home (celle, riga della foto, prompt, "Genera"); qui
   solo quello che cambia perché il pannello sta in fondo a una finestra già piena. */
#ed-panel-ai { gap: .6rem; padding-top: .9rem; padding-bottom: .9rem; }
#ed-panel-ai > * { width: 100%; max-width: 560px; margin-inline: auto; }

/* Celle in riga: immagine a sinistra, nome a destra. Quadrate come in home, sul
   desktop due celle larghe 280 px sarebbero alte 280, cioè mezzo schermo. */
.ed-celle { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ed-celle .cella {
  aspect-ratio: auto; height: 3.6rem; flex-direction: row; justify-content: flex-start;
  gap: .65rem; padding: .45rem .7rem;
}
.ed-celle .cella-img { height: 100%; width: auto; }
.ed-celle .cella-nome { text-align: left; -webkit-line-clamp: 2; }

/* ⚠ `.ed-panel input[type="text"]` più su dà a ogni campo del pannello un bordo
   grigio e un raggio da 10 px, e pesa più di `.prompt-campo`: il prompt va
   rimesso qui, col suo bordo giallo. */
#ed-panel-ai .prompt-campo {
  height: 2.75rem; padding: 0 1rem; background: var(--bg);
  border: 1px solid var(--primary); border-radius: 6px;
  font-size: 1rem; font-weight: 700;
}
@media (max-width: 559px) { #ed-panel-ai .prompt-campo { font-size: 16px; } }

/* La freccia di "Genera e aggiungi" è un fondo mascherato: il testo del pulsante lo
   riscrive editor.js mentre genera, e un SVG dentro sparirebbe. */
.ed-genera::after {
  content: ""; width: 20px; height: 20px; flex: none; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h16M14 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h16M14 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Il layer delle scelte si apre anche dall'editor, che sta a 80: deve stare sopra.
   Sotto ai messaggi (95), che devono restare leggibili su tutto. */
.sheet-scelta { z-index: 90; }

/* La cella spenta dal filtro di ritocco: si vede che non si può toccare. */
.cella:disabled { opacity: .45; cursor: not-allowed; }
.cella:disabled:hover { border-color: rgb(255 255 255 / .22); }
.cella:disabled:active { transform: none; }

/* ===== la miniatura del retro sulla scheda di un montaggio =================== */
/* Sta dove sulle altre schede ci sono i colori, in basso a sinistra: un montaggio
   non ha colori da scegliere, e quello spazio serve a mostrare l'altra faccia. */
.retro-thumb {
  display: flex; flex-direction: column; align-items: center; gap: .15rem;
  width: 3.6rem; padding: .2rem .2rem .15rem; cursor: pointer;
  background: #fff; border: 1px solid rgb(11 7 22 / .15); border-radius: 8px;
  box-shadow: 0 4px 12px rgb(11 7 22 / .25);
  transition: transform .12s ease, border-color .12s ease;
}
/* ⚠ `.frame .retro-thumb img` e non `.retro-thumb img`: la miniatura sta dentro la
   cornice della scheda, e `.frame img` tiene ogni immagine a opacità 0 (e alta
   quanto la cornice) finché la principale non è pronta. La miniatura restava bianca. */
.frame .retro-thumb img {
  width: 100%; height: auto; aspect-ratio: 3 / 4; object-fit: cover;
  border-radius: 5px; display: block; opacity: 1;
}
.retro-thumb span { font-size: .625rem; font-weight: 700; color: #0B0716; line-height: 1.1; }
.retro-thumb:hover { transform: translateY(-2px); border-color: var(--primary); }
.retro-thumb:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* ===== la cella e il layer del ritaglio ====================================== */
/* ⚠ Le icone delle forme le disegna il server in grigio scuro su trasparente: su un
   fondo scuro sparirebbero. Stanno su bianco, come i prodotti, e con un margine
   dentro — sono sagome, non foto da ritagliare a filo. */
.cella-forma { background: #fff; }
.cella-forma > img:not(.cella-sagoma) { object-fit: contain; padding: 16%; }
.scelta-fig.forma, .scelta-sel-img.forma { background: #fff; }
.scelta-fig.forma img, .scelta-sel-img.forma img { object-fit: contain; padding: 22%; }


/* ===== il form a passi (1_ 2_ 3_ 4_), come nel disegno ======================== */
/* ⚠ `#composer` e non `.composer`: le regole della riga foto più su usano
   `:is(.composer, #ed-panel-ai)`, che pesa quanto un id — con una classe queste qui
   perderebbero anche stando più in basso. Valgono solo per la home: il pannello AI
   dell'editor non ha i passi e resta com'è. */
#composer { gap: 1.5rem; padding: 1.5rem 1.4rem; }
#composer .celle { gap: 1rem; align-items: end; }
.passo { display: flex; flex-direction: column; gap: .75rem; min-width: 0; }

.passo-titolo {
  display: flex; align-items: center; gap: .5rem; margin: 0;
  font-family: var(--f-display); font-weight: 700; line-height: 1.08;
  font-size: clamp(.68rem, 1.35vw, .95rem); color: var(--text);
}
.passo-n { flex: none; color: var(--primary); font-size: 1.05em; align-self: flex-end; }
.passo-titolo em { font-style: normal; color: var(--primary); }

/* Le celle: più alte, l'immagine quadrata e arrotondata (anche lo stile: il tondo
   era un'idea del primo disegno, questo usa il quadrato). */
#composer .cella { border-radius: 10px; padding: 1rem .7rem; gap: .7rem; }
/* ⚠ Il riquadro è quadrato perché ha una LARGHEZZA e `aspect-ratio: 1`, con
   l'altezza automatica. Prima aveva larghezza e altezza tutte e due (52% e 58%) e
   usciva 55×48, con l'immagine 55×55 dentro: il cerchio del ritaglio perdeva il
   fondo. E l'altezza in percentuale da sola non si risolve (la cella non ha
   un'altezza definita): il riquadro la prendeva dall'immagine. */
#composer .cella-img { width: 56%; height: auto; border-radius: 12px; }
#composer .cella-tonda, #composer .cella-tonda > img:not(.cella-sagoma) { border-radius: 12px; }
#composer .cella-nome { font-size: .8125rem; }
/* La forma del ritaglio in grigio chiaro sulla cella, senza riquadro bianco. Le
   icone arrivano grigio scuro su trasparente: si invertono e si smorzano. Nel layer
   delle forme invece restano su bianco (`.scelta-fig.forma`). */
#composer .cella-forma { background: transparent; }
#composer .cella-forma > img { padding: 4%; filter: invert(1); opacity: .42; }

/* Il passo 4: il testo a sinistra, il riquadro dei pulsanti a destra. */
#composer .passo-foto {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
  gap: .6rem 1.2rem;
}
#composer .passo-foto .filter-drops { grid-column: 1 / -1; }
#composer .passo-foto .passo-titolo { font-size: clamp(.78rem, 1.5vw, 1rem); }
#composer .foto-cta {
  width: auto; min-height: 0; height: 3.8rem;
  border: 1px solid rgb(255 255 255 / .55); border-style: solid; border-radius: 12px;
  background: #000; overflow: hidden;
}
#composer .foto-cta .foto-pick, #composer .foto-cta .foto-cam {
  width: 5rem; min-height: 0; height: 100%; color: rgb(255 255 255 / .75);
  border: 0; border-right: 1px solid rgb(255 255 255 / .35); border-radius: 0;
}
#composer .foto-cta > :is(.foto-pick, .foto-cam):last-of-type { border-right: 0; }
#composer .foto-cta .foto-cam[hidden] + .foto-label + .foto-togli,
#composer .foto-cta .foto-pick { border-right-color: rgb(255 255 255 / .35); }
#composer .foto-pick svg, #composer .foto-cam svg { width: 26px; height: 26px; stroke-width: 1.4; }
#composer .foto-pick img { width: 40px; height: 40px; border-radius: 6px; object-fit: cover; }
/* L'etichetta: fuori dalla vista, dentro all'albero (vedi il commento nell'HTML). */
#composer .foto-label {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
#composer .foto-togli {
  align-self: center; margin: 0 .6rem; background: var(--surface); color: var(--text);
}
#composer .foto-cta.filled { border-color: var(--primary); }
#composer .foto-cta.serve { border-color: var(--err); }
#composer .foto-cta.serve .foto-pick, #composer .foto-cta.serve .foto-cam { color: var(--err); }

/* Prompt e "Genera" più alti, come nel disegno. */
#composer .prompt-campo { height: 3.6rem; padding: 0 1.3rem; font-size: 1.2rem; border-radius: 10px; }
#composer .genera { height: 3.6rem; padding: 0 1.9rem 0 2.2rem; font-size: 1.25rem; }
#composer .genera svg { width: 24px; height: 24px; }

@media (max-width: 559px) {
  #composer { gap: 1.2rem; padding: 1.1rem .9rem; }
  #composer .celle { gap: .55rem; }
  .passo { gap: .5rem; }
  .passo-titolo { font-size: .66rem; gap: .3rem; }
  #composer .cella { padding: .7rem .4rem; gap: .45rem; }
  #composer .cella-nome { font-size: .6875rem; }
  #composer .passo-foto .passo-titolo { font-size: .75rem; }
  #composer .foto-cta { height: 3.2rem; }
  #composer .foto-cta .foto-pick, #composer .foto-cta .foto-cam { width: 3.6rem; }
  #composer .prompt-campo { height: 3.1rem; font-size: 16px; }
  #composer .genera { height: 3.1rem; font-size: 1.05rem; }
}

/* ⚠ L'immagine della cella si inchioda ai bordi del riquadro. Dentro una griglia
   `height: 100%` non si risolve (la riga ha altezza automatica) e l'immagine prende la
   SUA proporzione: la foto del prodotto, che è 3:4, usciva 77×103 in un riquadro
   77×77 e restava tagliata sopra e sotto. Con `inset: 0` vale per ogni proporzione,
   e `object-fit` decide come starci dentro. */
.cella-img > img:not(.cella-sagoma) { position: absolute; inset: 0; }

/* ===== i passi allineati fra loro ============================================= */
/* ⚠ Ogni passo (titolo + cella) era una colonna a sé: un titolo su tre righe, o un
   nome di stile su due ("Graffiti / street art"), spostava solo la sua colonna, e
   titoli e celle finivano a altezze diverse. Ora la griglia ha DUE righe condivise
   — tutti i titoli nella prima, tutte le celle nella seconda — e ogni passo ci si
   aggancia con `subgrid`: i titoli si allineano in basso, sullo stesso rigo, e le
   celle diventano alte quanto la più alta. */
#composer .celle { grid-template-rows: auto auto; row-gap: .75rem; align-items: stretch; }
#composer .passo { display: grid; grid-row: span 2; grid-template-rows: subgrid; }
#composer .passo > .passo-titolo { align-self: end; }
/* ⚠ Niente `aspect-ratio` qui: allungata dalla riga, una cella con la proporzione
   fissa 6:5 si ALLARGAVA di conseguenza e usciva dalla sua colonna, sopra a quella
   accanto. L'altezza la fa il contenuto (immagine + nome) e la riga porta tutte le
   celle alla più alta. */
#composer .passo > .cella { aspect-ratio: auto; align-self: stretch; width: 100%; min-width: 0; }
@media (max-width: 559px) { #composer .celle { row-gap: .5rem; } }
/* Le tre immagini alla stessa altezza anche quando un nome va su due righe: il nome
   ha sempre lo spazio di due righe, e il contenuto parte dall'alto. Centrato, un
   nome lungo spingeva in su la sua immagine rispetto alle altre. */
#composer .passo > .cella { justify-content: flex-start; }
#composer .cella-nome { min-height: 2.5em; }

/* Le etichette dei passi un po' più piccole (circa -12%), numeri compresi: sono una
   guida alla lettura, non devono competere con la frase sopra il form. */
.passo-titolo { font-size: clamp(.6rem, 1.2vw, .84rem); }
#composer .passo-foto .passo-titolo { font-size: clamp(.68rem, 1.3vw, .88rem); }
@media (max-width: 559px) {
  .passo-titolo { font-size: .6rem; }
  #composer .passo-foto .passo-titolo { font-size: .68rem; }
}

/* La frase sopra il form un po' più piccola (circa -15%). */
.hero-frase { font-size: clamp(1.1rem, 4.6vw, 1.6rem); }


/* Il payoff sotto il logo, nascosto (2026-09-28): resta nell'HTML, ma la testata è
   solo logo e pulsanti. La frase sopra il form fa già da titolo. */
.brand-payoff { display: none; }


/* ===== 01 . Prompt: il campo, le foto e i due tondi ========================== */
/* Il riquadro giallo più scuro sta DIETRO al campo e alle foto: parte a metà del
   campo, e le foto ne escono sotto, come nel disegno. Posizioni e rotazioni in
   percentuale, così la composizione è la stessa a ogni larghezza della card. */
.step-demo-prompt { position: relative; margin: .2rem 0 .4rem; isolation: isolate; }
.step-demo-prompt::before {
  content: ""; position: absolute; z-index: -1;
  left: -2%; right: -2%; top: 1.3rem; bottom: 9%;
  background: rgb(160 120 0 / .16); border-radius: 16px;
}
.step-demo-prompt .step-input { position: relative; z-index: 2; margin: 0 6%; box-shadow: 0 2px 0 rgb(160 120 0 / .25); }
.step-foto { position: relative; aspect-ratio: 2.35 / 1; margin: .7rem -1% 0; }
.step-foto img {
  position: absolute; width: 27%; aspect-ratio: 1 / 1.08; object-fit: cover;
  border-radius: 8px; box-shadow: 0 6px 14px -6px rgb(0 0 0 / .45);
}
.step-foto .f1 { left: 0;   top: 16%; transform: rotate(-4deg); z-index: 2; }
.step-foto .f2 { left: 21%; top: -2%; transform: rotate(6deg);  z-index: 1; }
.step-foto .f3 { left: 37%; top: 22%; transform: rotate(-2deg); z-index: 4; }
.step-foto .f4 { left: 55%; top: 4%;  transform: rotate(-6deg); z-index: 1; }
.step-foto .f5 { left: 72%; top: 8%;  transform: rotate(5deg);  z-index: 3; }
.step-tondo {
  position: absolute; z-index: 5; bottom: -10%;
  display: grid; place-items: center; width: 15%; aspect-ratio: 1; border-radius: 50%;
}
.step-tondo svg { width: 48%; height: 48%; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.step-tondo.nero { right: 12%; background: #111; color: #fff; }
.step-tondo.verde { right: 0; background: #54DF97; color: #0B0716; }
@media (prefers-reduced-motion: no-preference) {
  .step-foto img { transition: transform .3s ease; }
  .step-prompt:hover .step-foto img { transform: rotate(0deg) translateY(-3px); }
}
/* Sul desktop la card è un terzo della pagina: il campo si allarga un po' e il testo
   scende di un filo, o la frase più lunga della demo usciva dal bordo. */
@media (min-width: 720px) {
  .step-demo-prompt .step-input { margin: 0 2%; padding: 0 .7rem; font-size: .8125rem; }
}
/* ⚠ Il campo della demo può andare a capo: fra 720 e ~1000 px le tre card sono
   strette, e la frase più lunga non stava in una riga nemmeno a 10 px. Rimpicciolire
   ancora la rendeva illeggibile; su due righe resta leggibile e dice la stessa cosa. */
.step-demo-prompt .step-input {
  white-space: normal; height: auto; min-height: 2.6rem;
  padding-top: .45rem; padding-bottom: .45rem; line-height: 1.25;
}


/* ===== il nastro "Usa gli stili", come nel disegno =========================== */
/* La tessera è una card bianca inclinata; le etichette le stanno SOPRA e la frase
   esce dal bordo in basso. ⚠ Per questo la tessera non ritaglia più (overflow
   visibile): il ritaglio lo fa il riquadro della foto dentro, e il nastro ha più
   spazio sotto per la frase che sporge. */
.ticker { padding-bottom: 2.4rem; padding-top: 1rem; }
.ticker-track { gap: 1.6rem; }
.tk {
  overflow: visible; border: 0; border-radius: 12px; background: #fff;
  box-shadow: 0 14px 30px -18px rgb(0 0 0 / .6);
}
.tk-foto { width: 100%; height: 100%; border-radius: 12px; overflow: hidden; }
.tk-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tk-prodotto, .tk-stile, .tk-frase {
  position: absolute; font-family: var(--f-mono); line-height: 1; white-space: nowrap;
  border-radius: 999px; pointer-events: none;
}
.tk-prodotto {
  top: .8rem; right: .7rem; padding: .45rem .85rem;
  background: #54DF97; color: #0B0716; font-size: .8125rem;
  transform: rotate(2deg);
}
.tk-prodotto[hidden] { display: none; }
.tk-stile {
  left: .6rem; bottom: 1.3rem; max-width: calc(100% - 1.2rem);
  padding: .55rem 1rem; background: #F4D755; color: #0B0716; font-size: .875rem;
  overflow: hidden; text-overflow: ellipsis; transform: rotate(-3deg);
}
.tk-frase {
  left: 8%; bottom: -1.1rem; max-width: 88%;
  padding: .5rem .9rem; background: #3D3045; color: #d9cde0; font-size: .75rem;
  overflow: hidden; text-overflow: ellipsis; transform: rotate(-1deg);
}
/* Al passaggio l'etichetta dello stile si inverte (scura, testo giallo) e la tessera
   si alza: prima diventava BIANCA, cioè sparivano sul bianco della card. */
.tk { transition: transform .2s ease, box-shadow .2s ease; }
.tk:hover { transform: rotate(var(--tilt, 0deg)) translateY(-4px); box-shadow: 0 20px 34px -18px rgb(0 0 0 / .7); }
.tk:hover .tk-stile { background: #0B0716; color: #F4D755; }
@media (max-width: 480px) {
  .tk-prodotto { font-size: .6875rem; padding: .38rem .7rem; }
  .tk-stile { font-size: .75rem; padding: .45rem .8rem; bottom: 1.1rem; }
  .tk-frase { font-size: .6875rem; }
}
/* Le etichette per intero: la frase e i nomi di stile più lunghi ("Fotografico
   cinematografico") uscivano coi puntini. Un filo di carattere e di margine in meno. */
.tk-stile { padding: .5rem .8rem; font-size: .8125rem; letter-spacing: -.02em; }
.tk-frase { left: 4%; max-width: 96%; padding: .45rem .75rem; font-size: .6875rem; letter-spacing: -.02em; }
@media (max-width: 480px) {
  .tk-stile { font-size: .6875rem; padding: .42rem .7rem; }
  .tk-frase { font-size: .625rem; }
}

/* Senza il pulsante "Conferma" il fondo del layer resta alla griglia: un po' d'aria
   sotto, e lo spazio per la barra del telefono. */
.sheet-scelta .scelta-corpo { padding-bottom: calc(1.4rem + env(safe-area-inset-bottom)); }

/* La barra in basso dell'editor si nasconde col pannello AI aperto (aggiornaPiede):
   `display: flex` vincerebbe sul `hidden` del browser. */
.ed-foot[hidden] { display: none; }


/* ===== pannelli dell'editor: "Annulla" e i caratteri a tessere ============== */
/* Annulla + il pulsante del pannello sulla stessa riga: il giallo resta l'azione,
   Annulla è un contorno. */
.ed-azioni { display: flex; gap: .6rem; align-items: stretch; }
.ed-azioni .genera { flex: 1 1 auto; width: auto; }
.ed-annulla {
  flex: none; padding: 0 1.3rem; border-radius: 999px; cursor: pointer;
  background: transparent; color: var(--text); border: 1px solid rgb(255 255 255 / .45);
  font-family: var(--f-display); font-weight: 700; font-size: .875rem;
}
.ed-annulla:hover { border-color: var(--text); background: var(--hover); }

/* Il pannello del testo, come quello AI. */
#ed-panel-text { gap: .65rem; padding-top: .9rem; padding-bottom: .9rem; }
#ed-panel-text > * { width: 100%; max-width: 560px; margin-inline: auto; }
#ed-panel-text .prompt-campo {
  height: 2.75rem; padding: 0 1rem; background: var(--bg);
  border: 1px solid var(--primary); border-radius: 6px; font-size: 1rem; font-weight: 700;
}
@media (max-width: 559px) { #ed-panel-text .prompt-campo { font-size: 16px; } }
.ed-font-head { display: flex; align-items: center; justify-content: space-between; }
.ed-etichetta { font-family: var(--f-display); font-weight: 700; font-size: .8125rem; }
.ed-colore { display: inline-flex; align-items: center; gap: .5rem; cursor: pointer; }
.ed-colore input[type="color"] {
  width: 38px; height: 30px; padding: 2px; border-radius: 8px;
  border: 1px solid rgb(255 255 255 / .3); background: var(--bg); cursor: pointer;
}

/* Le tessere: "abc" nel carattere e il nome. Quattro per riga sul telefono, e un
   tetto d'altezza: sono tredici, e tutte insieme spingerebbero il palco fuori
   dalla finestra — il resto si scorre. */
.ed-fonts {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .45rem;
  max-height: 10.5rem; overflow-y: auto; overscroll-behavior: contain; padding: 2px;
}
@media (min-width: 560px) { .ed-fonts { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.ed-font-opt {
  display: flex; flex-direction: column; align-items: center; gap: .1rem;
  padding: .35rem .2rem .45rem; cursor: pointer; min-width: 0;
  background: var(--surface); color: var(--muted);
  border: 1px solid rgb(255 255 255 / .16); border-radius: 8px; font: inherit;
}
.ed-font-opt img { width: 100%; max-width: 88px; aspect-ratio: 240 / 110; display: block; }
.ed-font-opt span {
  max-width: 100%; font-size: .6875rem; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ed-font-opt:hover { border-color: rgb(255 255 255 / .45); }
.ed-font-opt.on { border: 2px solid var(--primary); color: var(--text); background: #4a3c53; }

/* L'anteprima larga quanto la tessera: con un tetto a 88 px "abc" usciva minuscolo. */
.ed-font-opt img { max-width: none; aspect-ratio: 200 / 90; }
/* Annulla e il pulsante giallo su una riga anche sul telefono: "Genera e aggiungi"
   accanto ad Annulla andava a capo su due righe. */
.ed-azioni .genera { padding: 0 1.1rem 0 1.3rem; font-size: .95rem; white-space: nowrap; }
.ed-annulla { padding: 0 1.05rem; }
@media (max-width: 400px) { .ed-azioni .genera { font-size: .875rem; gap: .5rem; } }
/* La barra di scorrimento delle tessere, sottile e nei colori del tema. */
.ed-fonts { scrollbar-width: thin; scrollbar-color: #5a4a66 transparent; }

/* Il bottone fluttuante di iubenda (la chiave in un angolo) copriva le etichette del
   carrello. Le preferenze si riaprono dal link "Preferenze cookie" nel piede, che fa la
   stessa cosa. ⚠ Solo quello con [data-tp-float]: anche il link del piede ha la classe
   iubenda-cs-preferences-link. Il selettore pesa più di quelli di iubenda, che il
   widget aggiunge DOPO il nostro foglio e a parità vincerebbero. */
html body button.iubenda-tp-btn.iubenda-tp-btn[data-tp-float] { display: none !important; }

/* Il selettore delle lingue nel piede (lo riempie js/i18n.js). ⚠ `[hidden]` va
   riscritto: `display: flex` batterebbe l'attributo, e finché il sito ha una lingua
   sola resterebbe una riga vuota nel piede. Il margine ha `!important` come quello di
   .foot-link, per battere `.site-foot p { margin: 0 }`. */
.foot-lingue { display: flex; flex-wrap: wrap; gap: .2rem .9rem; margin-top: .6rem !important; }
.foot-lingue[hidden] { display: none; }
.foot-lingue button {
  padding: .25rem 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: .8125rem; letter-spacing: .08em; color: var(--muted);
}
.foot-lingue button:hover { color: var(--primary); }
.foot-lingue button[aria-pressed="true"] {
  color: var(--text); font-weight: 700; text-decoration: underline; text-underline-offset: .25em;
}
