/* ============================================================================
   Enigma — ALX Studio
   Scheletro: struttura, misure e comportamento. Nessuna direzione artistica.

   Qui dentro non ci sono colori decisi: solo token che ogni tema riempie in
   assets/themes/<id>.css. Se apri questo file cercando «il rosso di Manifesto»
   stai guardando il file sbagliato.

   Il contratto con i temi è l'elenco di token qui sotto: un tema che li
   ridefinisce tutti è già completo, e ne cambia altrettanti solo dove il suo
   mockup si discosta anche nella struttura.
   ========================================================================= */

:root {
  /* --- superfici e inchiostri --- */
  --bg: #f0efe9;
  --ink: #111;
  --ink-2: #6b6a63;
  --ink-3: #a9a69c;
  --line: #d6d4cb;
  --surface: #dcdad2;
  --surface-ink: #111;

  /* --- accento e stati --- */
  --accent: #e63f1c;
  --accent-ink: #fff;
  --ok: #111;
  --ok-ink: #f0efe9;
  --warn: #f2c230;
  --warn-ink: #111;
  --locked: #dcdad2;
  --locked-ink: #a9a69c;
  --hint-locked: rgba(17, 17, 17, .25);

  /* --- schermate a fondo pieno --- */
  --lvl-bg: var(--accent);
  --lvl-ink: #fff;
  --right-bg: #111;
  --right-ink: #f0efe9;
  --wrong-bg: #f2c230;
  --wrong-ink: #111;
  --ask-bg: #111;
  --ask-ink: #f0efe9;
  --full-bg: #1b53d6;
  --full-ink: #fff;

  /* --- coriandoli: li legge motion.js --- */
  --conf-1: #e63f1c;
  --conf-2: #111;
  --conf-3: #f2c230;
  --conf-4: #1b53d6;

  /* --- tipografia --- */
  --font: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-display: var(--font);
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --tt-display: none;      /* i temi che gridano mettono uppercase */
  --tt-label: uppercase;
  --ls-display: -.02em;
  --ls-label: .1em;
  --w-display: 700;
  --w-label: 700;

  /* --- scala tipografica --- */
  --fs-huge: 76px;         /* il numerone della home */
  --fs-title: 34px;
  --fs-lead: 24px;
  --fs-body: 17px;
  --fs-small: 14px;
  --fs-label: 11px;

  /* Il testo di un enigma rimpicciolisce al crescere della sua lunghezza:
     `textLength()` in app.js decide lo scaglione, questi tre numeri decidono di
     quanto. Sono frazioni di `--fs-title`, così un tema che alza il titolo si
     porta dietro anche gli enigmi. Un tema che regge testi lunghi meglio degli
     altri — perché ha un carattere più stretto o più leggibile in piccolo —
     alza la sua frazione invece di riscrivere la regola. */
  --riddle-medio: .78;
  --riddle-lungo: .58;
  --riddle-enorme: .44;

  /* La stella dei preferiti: la misura stava scritta in app.js come attributo
     dell'SVG, dove nessun tema poteva arrivarci. */
  --ico-fav: 20px;

  /* --- comandi a scorrimento --- */
  /* La manopola prende da sé inchiostro e fondo della schermata in cui si
     trova, e nessuna direzione deve dichiarare niente perché si veda. Colore e
     controcolore NON sono token con un valore qui: `--slide-knob-bg` e
     `--slide-knob-ink` esistono come scavalco facoltativo e la regola li legge
     con `var(…, var(--ink))`.

     Non è un capriccio: un token che vale `var(--ink)` viene risolto dove è
     DICHIARATO, cioè qui, e le schermate a fondo pieno ridichiarano `--ink` più
     in basso, sul guscio. Scritto come token, la manopola di Risografia usciva
     blu notte su fondo blu notte — cioè invisibile. */
  --slide-h: 56px;
  --slide-knob-w: 46px;
  --slide-glyph: '▸▸';
  --slide-fill: currentColor;

  /* Quanto può prendersi al massimo il pannello di calcolatrice e appunti: il
     resto della schermata resta all'enigma, che è quello che si sta guardando.
     Il tetto lo tocca solo il tastierino, che è il contenuto più alto: sotto un
     viewport da ~660px la sua ultima riga finisce nello scorrimento interno del
     pannello, che è il modo meno peggio di stare in uno schermo piccolo. */
  --tools-h: min(56dvh, 400px);

  /* --- forma --- */
  --r: 0px;
  --r-lg: 0px;
  --r-pill: 0px;
  --bd: 0px;               /* spessore del bordo dei blocchi */
  --bd-color: var(--line);
  --shadow: none;

  /* --- misure --- */
  --pad: 20px;             /* margine laterale delle schermate */
  --head-top: 22px;
  --head-bottom: 10px;     /* sotto la testata, prima che cominci a scorrere */
  --head-gap: 18px;        /* fra la testata e l'inizio dei contenuti */
  /* Le due sfumature ai capi della zona che scorre: alte quanto il vuoto che
     le ospita, così da ferme non toccano niente di visibile. */
  --head-fade: var(--head-gap);
  --foot-fade: var(--gap-block);
  --gap: 3px;              /* fra elementi di una lista */
  --gap-block: 16px;       /* fra blocchi diversi */
  --block-pad: 18px;
  --btn-pad: 19px;
  --tab-h: 60px;
  --tab-pad: 22px;         /* sopra e sotto l'icona della tab bar */

  /* --- movimento --- */
  --d-fast: 120ms;
  --d-base: 220ms;
  --ease-out: cubic-bezier(.16, 1, .3, 1);

  --kb: 0px;

  /* Fascia dell'indicatore Home. In Safari vale 0 — quella striscia è occupata
     dalla barra del browser — mentre da app installata vale 34px. Va ASSORBITA
     nell'imbottitura che una barra ha già, mai sommata: sommandola, in PWA ogni
     schermata guadagnava fra i 50 e gli 80 px di vuoto in fondo. Da qui la
     forma `max(quello che vuole il disegno, quello che pretende il sistema)`.
     `--safe-tab` sconta l'imbottitura che la tab bar mette già sotto l'icona. */
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-tab: max(0px, calc(var(--safe-b) - 24px));

  /* Stessa storia in cima: la barra di stato è traslucida e ci sta sopra, ma
     l'inset (47-59px) non va sommato ai 22-26px del disegno — va assorbito. */
  --safe-t: env(safe-area-inset-top, 0px);

  color-scheme: light;
}

/* ============================ base ============================ */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; height: 100%; }

body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.45;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
h1, h2, p { margin: 0; }

button, a, .cell, .option { touch-action: manipulation; -webkit-touch-callout: none; user-select: none; }
.riddle__text, .why__text, .hint__text, .solution__value { user-select: text; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ============================ guscio ============================ */

.app {
  display: flex;
  flex-direction: column;
  height: calc(100dvh - var(--kb));
  max-width: 480px;
  margin: 0 auto;
  background: var(--bg);
  color: var(--ink);
  overflow: hidden;
  position: relative;
}

/* Da app installata con la barra di stato traslucida, iOS disegna la web view
   su tutto il vetro ma ne DICHIARA l'altezza corta di `env(safe-area-inset-top)`:
   misurato su iPhone, vetro 852 e viewport 793. Così `100dvh` — e con lui
   `html`/`body` a `height: 100%`, che dal viewport dipendono — si fermano 59px
   prima del fondo, e sotto la tab bar resta una fascia morta che nessuna
   imbottitura spiega.

   Si allunga tutta la catena di quei pixel. Va allungata per intero: bastasse
   il guscio, `body { overflow: hidden }` lo ritaglierebbe subito. `html` prende
   overflow nascosto perché, diventando più alto del viewport dichiarato, senza
   quello la pagina guadagnerebbe 59px di scorrimento.

   `is-fullbleed` e `--glass-fix` li scrive `trackGlass()` in app.js, che lo
   scarto lo MISURA contro `screen.height` invece di darlo per scontato, e solo
   su iOS: su Android lo stesso scarto esiste ma è vero — lo occupa la barra di
   navigazione — e allungare il guscio ci ficcherebbe la tab bar sotto. Non si
   usa `@media (display-mode: standalone)`: quella query dipende dal manifest, e
   su iOS una scorciatoia aggiunta alla Home espone solo `navigator.standalone`.
   Dove non c'è scarto la classe non compare e qui non succede niente. */
html.is-fullbleed {
  height: calc(100% + var(--glass-fix, 0px));
  overflow: hidden;
}

html.is-fullbleed body { height: 100%; }
html.is-fullbleed .app { height: calc(100% - var(--kb)); }

/* `min-width: 0` ovunque: senza, una parola lunghissima di un enigma allarga la
   schermata oltre il guscio e la testata finisce fuori dallo schermo. */
.view { flex: 1; min-height: 0; min-width: 0; display: flex; }
.host { flex: 1; min-height: 0; min-width: 0; display: flex; }

.scr {
  flex: 1;
  min-height: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--ink);
}

/* La maschera sfuma i due capi della zona che scorre: i contenuti si dissolvono
   passando sotto la testata e sopra la barra, invece di essere tagliati di
   netto. Sfuma verso il trasparente e non verso un colore, perché sotto c'è il
   fondo del tema, che spesso non è una tinta piatta. Le due bande sono alte
   quanto i due imbottiti che le ospitano, quindi da fermi non toccano niente. */
.scr__body {
  flex: 1;
  min-height: 0;
  min-width: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* arrivato in fondo, lo scorrimento si ferma qui invece di passare al
     documento e far rimbalzare tutto il guscio */
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: var(--gap-block);
  padding: var(--head-gap) var(--pad) var(--gap-block);
  --scr-mask: linear-gradient(to bottom,
    transparent 0,
    #000 var(--head-fade),
    #000 calc(100% - var(--foot-fade)),
    transparent 100%);
  -webkit-mask-image: var(--scr-mask);
  mask-image: var(--scr-mask);
}

.scr__foot {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  padding: var(--gap-block) var(--pad) max(18px, var(--safe-b));
}

/* le schermate a fondo pieno tingono tutto il guscio, tab bar compresa */
.app[data-scr="livello"] { --bg: var(--lvl-bg); --ink: var(--lvl-ink); }
.app[data-scr="salto"] { --bg: var(--ask-bg); --ink: var(--ask-ink); }
.app[data-scr="completa"] { --bg: var(--full-bg); --ink: var(--full-ink); }
.app[data-scr="giusto"] { --bg: var(--right-bg); --ink: var(--right-ink); }
.app[data-scr="sbagliato"] { --bg: var(--wrong-bg); --ink: var(--wrong-ink); }

/* ============================ testate ============================ */

.head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* I +10px respirano solo dove l'inset comanda, cioè da app installata: in
     Safari l'inset vale 0, vince `--head-top` e l'impaginazione resta quella
     dei mockup. */
  padding: max(var(--head-top), calc(var(--safe-t) + 10px)) var(--pad) var(--head-bottom);
  flex: 0 0 auto;
  /* Le parti ferme non si trascinano: un dito che parte da qui non deve far
     ballare la pagina. I comandi dentro ridichiarano `manipulation` per conto
     loro, quindi restano toccabili. */
  touch-action: none;
}

.head--brand { align-items: flex-end; }
.head--title { align-items: flex-end; }

/* testata con un solo elemento: `space-between` lo spingerebbe a sinistra */
.head--solo { justify-content: flex-end; }

.head__title {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: var(--w-display);
  letter-spacing: var(--ls-display);
  text-transform: var(--tt-display);
  line-height: 1;
}

.head__back {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: var(--w-label);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.head__back::before { content: '◂'; }
.head__back--flat::before { content: none; }

.head__acts { display: flex; align-items: center; gap: 12px; }

.ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: inherit;
}

/* Il CSS vince sull'attributo width/height che app.js mette sull'SVG: così la
   misura della stella torna nelle mani dei temi. */
.ico--fav svg { width: var(--ico-fav); height: var(--ico-fav); }

/* --- marchio --- */

.brand { display: inline-flex; align-items: center; gap: 10px; }

.brand__name {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: var(--w-display);
  letter-spacing: var(--ls-display);
  text-transform: var(--tt-display);
}

.mark { display: flex; flex-direction: column; gap: 3px; width: 20px; flex: 0 0 auto; }
.mark i { display: block; height: 4px; background: currentColor; }
.mark i:nth-child(2) { background: var(--accent); margin-left: 6px; }

.mark--lg { width: 96px; gap: 9px; }
.mark--lg i { height: 22px; }
.mark--lg i:nth-child(2) { margin-left: 30px; }

/* --- monete --- */

.coins {
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: var(--w-label);
  background: var(--ink);
  color: var(--bg);
  padding: 6px 10px;
  border-radius: var(--r);
  flex: 0 0 auto;
  line-height: 1.2;
}

/* ============================ tab bar ============================ */

.tabbar { display: none; }

.app.has-tabs .tabbar {
  display: flex;
  flex: 0 0 auto;
  border-top: 3px solid var(--ink);
  padding-bottom: var(--safe-tab);
  touch-action: none;   /* ferma, come la testata */
}

.tabbar__item {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--tab-pad) 0;
  color: var(--ink);
}

.tabbar__item.is-on { background: var(--ink); color: var(--bg); }
.tabbar__label { display: none; }

body.is-typing .tabbar { display: none !important; }

/* ============================ pulsanti ============================ */

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
  padding: var(--btn-pad) 16px;
  border-radius: var(--r);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  font-weight: var(--w-label);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
  background: var(--surface);
  color: var(--surface-ink);
  border: var(--bd) solid var(--bd-color);
  transition: transform var(--d-fast) var(--ease-out), opacity var(--d-fast);
}

.btn:active { transform: scale(.985); }
.btn[disabled] { opacity: .45; cursor: not-allowed; }

.btn--primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn--ghost { background: none; color: var(--ink-2); border: 3px solid var(--line); }
.btn--inert { background: none; color: var(--ink); border: 3px solid var(--ink); cursor: default; }

/* «attiva il tema»: azione principale, ma di un altro colore rispetto all'acquisto —
   nei mockup comprare è nero e attivare è dell'accento */
.btn--go { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }

/* inerte e spento: il pulsante che non si può ancora usare */
.btn--off { border-color: var(--line); color: var(--ink-3); }

.btn svg { width: 20px; height: 20px; }

/* le frecce sono decorazione del tema, non testo: chi non le vuole le toglie */
.btn[data-arrow="avanti"]::after { content: ' ▸'; }
.btn[data-arrow="indietro"]::before { content: '◂ '; }

/* ==================== comandi a scorrimento ==================== */

/* Non è un elemento nuovo: è una capacità aggiunta a un comando che i temi
   dipingono già — «Scopri soluzione» (`.more`), la riga di un indizio ancora
   chiuso (`.hint`), l'acquisto di un tema (`.btn`). La pista resta quella che
   era, con i suoi colori e la sua forma; qui si aggiungono solo il riempimento
   che segue il dito e la manopola che lo trascina. Così i dieci fogli non hanno
   bisogno di una riga a testa.

   La manopola è un elemento del flusso e non è appoggiata sopra: occupa il suo
   posto in prima colonna e spinge il resto. Un'imbottitura calcolata si sarebbe
   persa al primo tema che ridichiara `padding` sulla stessa riga. */
.slide {
  position: relative;
  overflow: hidden;
  min-height: var(--slide-h);
  justify-content: flex-start;
  align-items: center;
  gap: 12px;
  cursor: grab;
  user-select: none;
  /* verticale sì (la schermata deve poter scorrere sotto il dito), orizzontale
     no: quello è il gesto del comando */
  touch-action: pan-y;
}

/* Gli elementi posizionati si disegnano sopra il testo che non lo è: senza
   questo il riempimento coprirebbe l'etichetta. */
.slide > span { position: relative; }

.slide__fill {
  position: absolute;
  inset: 0;
  transform: scaleX(var(--p, 0));
  transform-origin: left center;
  background: var(--slide-fill);
  opacity: .14;
  pointer-events: none;
}

.slide__knob {
  order: -1;                       /* montata per ultima, ma va in testa */
  position: relative;
  flex: 0 0 var(--slide-knob-w);
  align-self: stretch;
  min-height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--slide-knob-bg, var(--ink));
  color: var(--slide-knob-ink, var(--bg));
  border-radius: var(--r);
  font-size: 14px;
  line-height: 1;
  touch-action: none;              /* il gesto orizzontale non fa scorrere */
  transition: transform var(--d-base) var(--ease-out);
}

.slide__knob::before { content: var(--slide-glyph); letter-spacing: -.08em; }

/* nella riga di un indizio il prezzo resta in fondo, come prima */
.hint.slide .hint__cost { margin-left: auto; }

/* dove l'etichetta era centrata resta centrata, nello spazio che avanza */
.btn.slide > span, .more.slide > span { flex: 1; text-align: center; }

/* il ▾ di `.more` prometteva un pannello che si apre premendo: qui non è più */
.more.slide::after { content: none; }

.slide[data-state="off"] { opacity: .45; }
.slide[data-state="off"] .slide__knob { display: none; }

/* ============================ home ============================ */

.tally { padding-top: 14px; }

.tally__n {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-huge);
  font-weight: var(--w-display);
  line-height: .86;
  letter-spacing: -.05em;
}

/* barra di avanzamento: la mostrano solo i temi che la prevedono */
.tally__bar { display: none; height: 3px; margin-top: 10px; background: var(--line); border-radius: 2px; }
.tally__bar i { display: block; height: 3px; background: var(--ink); border-radius: 2px; }

.tally__label {
  display: block;
  padding-top: 8px;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: var(--w-label);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
}

.resume {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: var(--block-pad);
  border-radius: var(--r);
  background: var(--accent);
  color: var(--accent-ink);
}

.resume__where {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: var(--w-label);
  letter-spacing: .16em;
  text-transform: var(--tt-label);
}

.resume__text {
  font-family: var(--font-display);
  font-size: var(--fs-lead);
  font-weight: var(--w-display);
  line-height: 1.06;
  letter-spacing: var(--ls-display);
  text-transform: var(--tt-display);
}

.resume__cta {
  align-self: flex-start;
  background: var(--ink);
  color: var(--bg);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: var(--w-label);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
  padding: 11px 18px;
  border-radius: var(--r);
}

.resume__cta::after { content: ' ▸'; }
.resume--done .resume__cta { display: none; }

.colls { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); }

.coll {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 14px;
  border-radius: var(--r);
  background: var(--locked);
  color: var(--locked-ink);
  min-width: 0;
}

.coll:nth-child(5) { grid-column: span 2; }
.coll[data-state="done"] { background: var(--ok); color: var(--ok-ink); }
.coll[data-state="current"] { background: var(--full-bg); color: var(--full-ink); }

.coll__count i { font-style: normal; }
.coll__count i::before { content: '/'; }

.coll__count {
  font-family: var(--font-display);
  font-size: var(--fs-lead);
  font-weight: var(--w-display);
  letter-spacing: var(--ls-display);
  line-height: 1;
}

/* nei mockup nome e stato stanno su una riga sola, separati da un punto */
.coll__meta {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: var(--w-label);
  letter-spacing: .06em;
  text-transform: var(--tt-label);
  line-height: 1.3;
}

.coll__name::after { content: ' · '; }

.credits {
  margin-top: auto;
  padding-top: var(--gap-block);
  font-size: 11px;
  line-height: 1.5;
  text-align: center;
  color: var(--ink-3);
}

/* ============================ raccolta ============================ */

.scr__intro { display: flex; flex-direction: column; gap: 6px; padding-top: 10px; }

.scr__eyebrow {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: var(--w-label);
  letter-spacing: .16em;
  text-transform: var(--tt-label);
  color: var(--ink-2);
}

.scr__title {
  font-family: var(--font-display);
  font-size: var(--fs-title);
  font-weight: var(--w-display);
  line-height: .92;
  letter-spacing: var(--ls-display);
  text-transform: var(--tt-display);
  display: flex;
  flex-direction: column;
}

.scr__sub {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: var(--w-label);
  letter-spacing: .08em;
  text-transform: var(--tt-label);
  color: var(--ink-2);
}

.cells { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap); }

.cell {
  position: relative;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r);
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: var(--w-display);
  background: var(--locked);
  color: var(--locked-ink);
  border: var(--bd) solid var(--bd-color);
}

.cell[data-state="solved"] { background: var(--ok); color: var(--ok-ink); }
.cell[data-state="skipped"] { background: var(--warn); color: var(--warn-ink); }
.cell[data-state="open"] { background: var(--surface); color: var(--surface-ink); }
.cell[data-state="current"] {
  background: var(--accent);
  color: var(--accent-ink);
  grid-column: span 2;
  aspect-ratio: 2 / 1;
  font-size: 24px;
}

/* lo mostrano solo i temi che fanno della raccolta un elenco */
.cell__title { display: none; }

.cell__fav { position: absolute; top: 3px; right: 5px; font-size: 16px; line-height: 1; }
.cell__fav::before { content: '★'; }

/* ============================ enigma ============================ */

/* Numero sopra, difficoltà sotto, in colonna e centrati: erano due dati corti
   in fila su una riga sola, e si leggevano come una frase unica. */
.riddle__meta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding-top: 12px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: var(--w-label);
  letter-spacing: .16em;
  text-transform: var(--tt-label);
}

.riddle__num { color: var(--ink); }
.riddle__diff { color: var(--ink-2); }

/* Il testo dell'enigma scala con la sua lunghezza: gli indovinelli del dataset
   vanno da otto parole a mezza pagina, e un corpo solo non può servirli tutti. */
.riddle__text {
  font-family: var(--font-display);
  font-size: var(--fs-title);
  font-weight: var(--w-display);
  line-height: 1.04;
  letter-spacing: var(--ls-display);
  text-transform: var(--tt-display);
  text-wrap: pretty;
  overflow-wrap: anywhere;
  /* Gli enigmi del dataset mandano a capo dove vogliono che si vada a capo, e
     la card condivisa lo rispetta già (`wrap()` in share.js): qui vale lo
     stesso. `pre-line` e non `pre-wrap` perché diversi testi hanno uno spazio
     prima dell'a capo, che così si riassorbe invece di restare appeso. */
  white-space: pre-line;
}

.riddle__text[data-len="medio"] { font-size: calc(var(--fs-title) * var(--riddle-medio)); line-height: 1.1; }
.riddle__text[data-len="lungo"] { font-size: calc(var(--fs-title) * var(--riddle-lungo)); line-height: 1.22; }
.riddle__text[data-len="enorme"] { font-size: calc(var(--fs-title) * var(--riddle-enorme)); line-height: 1.32; }

.riddle__img { border-radius: var(--r); }

.hints { display: flex; flex-direction: column; gap: var(--gap); }

.hint {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px;
  border-radius: var(--r);
  text-align: left;
  width: 100%;
  background: var(--ok);
  color: var(--ok-ink);
}

.hint[data-state="locked"] {
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  background: var(--hint-locked);
  color: inherit;
}

.hint__label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: .14em;
  text-transform: var(--tt-label);
}

.hint__text { font-family: var(--font-mono); font-size: var(--fs-small); line-height: 1.5; }
.hint__cost { font-family: var(--font-mono); font-size: 12px; font-weight: var(--w-label); }

.options { display: flex; flex-direction: column; gap: var(--gap); }

.option {
  padding: 16px;
  border-radius: var(--r);
  text-align: left;
  background: var(--surface);
  color: var(--surface-ink);
  font-family: var(--font-display);
  font-size: var(--fs-body);
  border: var(--bd) solid var(--bd-color);
}

/* --- barra risposta: vive nel flusso, in fondo alla schermata --- */

.app[data-scr="livello"] .scr__foot { padding: 0 0 max(18px, var(--safe-b)); gap: 0; }

.answer { display: flex; border-top: 3px solid var(--ink); }

.answer__input {
  flex: 1;
  min-width: 0;
  padding: 20px 16px;
  border: 0;
  border-radius: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 15px;
}

.answer__input::placeholder { color: var(--ink-3); }
.answer__input:focus { outline: none; }

.answer__send {
  width: 72px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ink);
  color: var(--bg);
  font-size: 22px;
}

.answer__send::before { content: '▸'; }

.skip {
  display: block;
  width: 100%;
  text-align: center;
  padding: 13px 16px;
  background: var(--ink);
  color: var(--bg);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: var(--w-label);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
}

/* --- rilettura di un enigma già risolto --- */

/* Le opzioni e la casella restano dov'erano: da qui l'enigma si può far provare
   a un amico. La barra va a filo come nella schermata di gioco, ma questo piede
   ha i suoi margini — se li sfila. */
.app[data-scr="fatto"] .answer,
.app[data-scr="fatto"] .retry,
.app[data-scr="fatto"] .tools {
  margin-left: calc(var(--pad) * -1);
  margin-right: calc(var(--pad) * -1);
}

/* L'esito di una prova: una striscia che compare e si ritira da sola. Non è una
   schermata — si sta rileggendo, non giocando — e non tocca la partita. Il
   contenitore c'è sempre e sta vuoto, così si riempie senza ridisegnare. */
.retry {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px var(--pad);
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: var(--w-display);
  letter-spacing: var(--ls-display);
  text-transform: var(--tt-display);
  text-align: center;
  overflow-wrap: anywhere;
  animation: rise var(--d-base) var(--ease-out);
}

.retry:not([data-esito]) { display: none; }
.retry[data-esito="giusto"] { background: var(--ok); color: var(--ok-ink); }
.retry[data-esito="sbagliato"] { background: var(--warn); color: var(--warn-ink); }

/* ============================ esiti ============================ */

.verdict { display: flex; flex-direction: column; gap: 14px; padding-top: 24px; }

/* le parole dell'esito le sceglie il tema e possono essere lunghe: nessuna deve
   poter sfondare la schermata */
.verdict__word, .done__title, .ask__title { overflow-wrap: anywhere; }
.done__title span, .ask__title span { min-width: 0; }

.verdict__word {
  font-family: var(--font-display);
  font-size: 64px;
  font-weight: var(--w-display);
  line-height: .9;
  letter-spacing: -.04em;
  text-transform: var(--tt-display);
}

.verdict[data-esito="giusto"] .verdict__word { color: var(--accent); }

.verdict__line {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  font-weight: var(--w-label);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
}

.reward {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: var(--block-pad);
  border-radius: var(--r);
  background: var(--accent);
  color: var(--accent-ink);
}

.reward__label {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: var(--w-label);
  letter-spacing: .14em;
  text-transform: var(--tt-label);
}

.reward__value {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: var(--w-display);
  letter-spacing: var(--ls-display);
  line-height: 1;
}

.reward__note {
  flex: 1 0 100%;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.6;
}

.why {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: var(--block-pad);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--surface-ink);
}

.why__label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--w-label);
  letter-spacing: .16em;
  text-transform: var(--tt-label);
  opacity: .7;
}

.why__text { font-family: var(--font-mono); font-size: var(--fs-small); line-height: 1.6; }

.more {
  display: flex;
  justify-content: space-between;
  width: 100%;
  padding: 15px 16px;
  border: 3px solid var(--line);
  border-radius: var(--r);
  color: var(--ink-2);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: var(--w-label);
  letter-spacing: .12em;
  text-transform: var(--tt-label);
}

.more::after { content: '▾'; }

.solution {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: var(--block-pad);
  border-radius: var(--r);
  background: var(--accent);
  color: var(--accent-ink);
}

.solution__label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--w-label);
  letter-spacing: .16em;
  text-transform: var(--tt-label);
}

.solution__value {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: var(--w-display);
  letter-spacing: var(--ls-display);
  text-transform: var(--tt-display);
  line-height: 1.1;
}

/* --- conferma del salto --- */

.ask { display: flex; flex-direction: column; gap: 16px; padding-top: 20px; }

.ask__title {
  display: flex;
  flex-direction: column;
  font-family: var(--font-display);
  font-size: 44px;
  font-weight: var(--w-display);
  line-height: .94;
  letter-spacing: -.04em;
  text-transform: var(--tt-display);
}

.ask__text { font-family: var(--font-mono); font-size: var(--fs-small); line-height: 1.7; opacity: .8; }

/* --- raccolta completa --- */

.done { display: flex; flex-direction: column; gap: 16px; padding-top: 26px; }

.done__title {
  display: flex;
  flex-direction: column;
  font-family: var(--font-display);
  font-size: 58px;
  font-weight: var(--w-display);
  line-height: .9;
  letter-spacing: -.05em;
  text-transform: var(--tt-display);
}

.done__sub {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  font-weight: var(--w-label);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
}

.unlocked {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: var(--block-pad);
  border-radius: var(--r);
  background: var(--ink);
  color: var(--bg);
}

.unlocked__label {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: var(--w-label);
  letter-spacing: .14em;
  text-transform: var(--tt-label);
}

.unlocked__value {
  font-family: var(--font-display);
  font-size: var(--fs-lead);
  font-weight: var(--w-display);
  letter-spacing: var(--ls-display);
}

/* ============================ preferiti ============================ */

.favs { display: flex; flex-direction: column; gap: var(--gap); }

.fav {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px;
  border-radius: var(--r);
  background: var(--surface);
  color: var(--surface-ink);
}

.fav[data-state="solved"] { background: var(--ok); color: var(--ok-ink); }
.fav[data-state="skipped"] { background: var(--accent); color: var(--accent-ink); }

.fav__where {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--w-label);
  letter-spacing: .14em;
  text-transform: var(--tt-label);
}

.fav__title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: var(--w-display);
  line-height: 1.12;
  letter-spacing: var(--ls-display);
  text-transform: var(--tt-display);
}

.empty {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: var(--block-pad);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--surface-ink);
  text-align: center;
}

.empty strong { font-family: var(--font-display); text-transform: var(--tt-display); }
.empty span { font-size: var(--fs-small); color: var(--ink-2); }

/* ============================ profilo ============================ */

.stats { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); }

.stat {
  padding: 16px;
  border-radius: var(--r);
  background: var(--locked);
  color: var(--locked-ink);
}

.stat[data-tone="ink"] { background: var(--ok); color: var(--ok-ink); }
.stat[data-tone="accent"] { background: var(--full-bg); color: var(--full-ink); }

.stat__value {
  display: block;
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: var(--w-display);
  letter-spacing: -.04em;
  line-height: 1;
}

.stat__label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: var(--w-label);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
}

.themerow {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 4px 12px;
  padding: 16px;
  border: 3px solid var(--ink);
  border-radius: var(--r);
}

.themerow__label {
  grid-column: 1;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--w-label);
  letter-spacing: .14em;
  text-transform: var(--tt-label);
}

.themerow__name {
  grid-column: 1;
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: var(--w-display);
  letter-spacing: var(--ls-display);
  text-transform: var(--tt-display);
  line-height: 1;
}

.themerow__cta {
  grid-column: 2;
  grid-row: 1 / span 2;
  background: var(--ink);
  color: var(--bg);
  padding: 8px 11px;
  border-radius: var(--r);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--w-label);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
}

/* L'unico blocco pieno del profilo: prende l'accento del tema con il suo
   inchiostro di contrasto. Sono una coppia dichiarata da ogni direzione, quindi
   la leggibilità è decisa lì e non da un colore scelto qui. */
.account {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px;
  border-radius: var(--r);
  background: var(--accent);
  color: var(--accent-ink);
}

.account__photo {
  width: 52px;
  height: 52px;
  flex: 0 0 auto;
  border-radius: var(--r-pill);
  object-fit: cover;
}

/* chi la foto non ce l'ha mostra la sua iniziale, nella stessa sagoma */
.account__photo--vuota {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-ink);
  color: var(--accent);
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: var(--w-display);
  line-height: 1;
}

.account__who {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.account__label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--w-label);
  letter-spacing: .14em;
  text-transform: var(--tt-label);
  opacity: .72;
}

.account__name {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: var(--w-display);
  letter-spacing: var(--ls-display);
  text-transform: var(--tt-display);
}

.account__mail {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  opacity: .82;
  word-break: break-all;
}

/* ============================ scorrimento fra enigmi ============================ */

/* Le frecce chiudono il piede, sempre per ultime. È il solo modo di tenerle
   alla stessa altezza dal fondo su tutte le schermate: sopra di loro ci sono
   cose diverse — barra risposta e «Salta» se l'enigma è da risolvere, il
   ritorno se è fatto — e mettendole per prime ballerebbero da una schermata
   all'altra, costringendo a ricercarle ogni volta.

   Restano nel flusso, come la barra risposta: `--kb` accorcia il guscio e il
   piede sale tutto insieme, quindi la distanza dal fondo regge anche con la
   tastiera aperta. */
.pager {
  display: flex;
  justify-content: space-between;
  gap: var(--gap);
  padding-top: var(--gap);
}

.pager__arrow, .pager__tool {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 44px;
  border-radius: var(--r);
  border: var(--bd) solid var(--bd-color);
  color: var(--ink-2);
}

/* Fra le due frecce c'era un vuoto: ci stanno la calcolatrice e gli appunti.
   Sono comandi dell'enigma, non della navigazione, ma è lì che il pollice
   arriva senza spostare la mano. */
.pager__tools { display: flex; gap: var(--gap); }

.pager__tool { position: relative; }
.pager__tool.is-on { background: var(--ink); color: var(--bg); }

/* il segno di «qui dentro c'è già qualcosa»: un appunto lasciato a metà non
   deve richiedere di aprire il pannello per ricordarsene */
.pager__tool[data-full]::after {
  content: '';
  position: absolute;
  top: 7px;
  right: 9px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

.pager__tool.is-on[data-full]::after { background: var(--bg); }

/* La freccia senza destinazione resta al suo posto, spenta: se sparisse,
   l'altra scivolerebbe sotto il dito e si premerebbe quella sbagliata. */
.pager__arrow[data-state="off"] {
  color: var(--ink-3);
  opacity: .38;
  pointer-events: none;
}

/* ==================== calcolatrice e appunti ==================== */

/* Il pannello non è un foglio appoggiato sopra: vive nel flusso, in fondo al
   piede. Il corpo della schermata si accorcia e il testo dell'enigma resta
   leggibile e scorrevole — coprirlo proprio mentre si fanno due conti sarebbe
   il contrario di quello che serve. Con la tastiera aperta sale tutto insieme,
   perché `--kb` accorcia il guscio: stessa storia della barra risposta. */
.tools {
  display: flex;
  flex-direction: column;
  min-height: 0;
  max-height: 0;
  overflow: hidden;
  background: var(--surface);
  color: var(--surface-ink);
  border-top: 3px solid var(--ink);
  transition: max-height var(--d-base) var(--ease-out);
}

.tools.is-open { max-height: var(--tools-h); }

.tools__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex: 0 0 auto;
  padding: 10px var(--pad) 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--w-label);
  letter-spacing: .14em;
  text-transform: var(--tt-label);
}

.tools__close { font-size: 15px; line-height: 1; padding: 4px 6px; color: inherit; }

.tools__body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 var(--pad) 12px;
}

.calc { display: flex; flex-direction: column; gap: 8px; }

.calc__screen {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 2px;
  min-height: 50px;
  padding: 8px 12px;
  border-radius: var(--r);
  background: var(--bg);
  color: var(--ink);
}

.calc__expr {
  font-family: var(--font-mono);
  font-size: 15px;
  text-align: right;
  overflow-wrap: anywhere;
  color: var(--ink-2);
}

.calc__res {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: var(--w-display);
  line-height: 1.1;
  letter-spacing: var(--ls-display);
  overflow-wrap: anywhere;
}

.calc__pad { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap); }

.calc__key {
  padding: 11px 0;
  border-radius: var(--r);
  border: var(--bd) solid var(--bd-color);
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 17px;
  line-height: 1;
}

.calc__key:active { transform: scale(.96); }
.calc__key[data-k="op"] { background: var(--ink); color: var(--bg); }
.calc__key[data-k="cancella"] { color: var(--ink-2); }
.calc__key[data-k="eq"] { background: var(--accent); color: var(--accent-ink); }

.note__area {
  flex: 1;
  min-height: 200px;
  width: 100%;
  resize: none;
  border: 0;
  border-radius: var(--r);
  padding: 12px;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 15px;
  line-height: 1.5;
}

.note__area::placeholder { color: var(--ink-3); }
.note__area:focus { outline: none; }

/* ============================ negozio ============================ */

.shop { display: flex; flex-direction: column; gap: 8px; }
.shop__row { display: block; }

/* L'anteprima di ogni tema è disegnata dal CSS del tema che vende: qui sta solo
   la scatola, uguale per tutti. Vedi `.tpv--<id>` in themes/<id>.css. */
.tpv {
  display: flex;
  align-items: center;
  gap: 12px;
  position: relative;
  overflow: hidden;
  box-sizing: border-box;
}

.tpv--riga { height: 54px; padding: 0 14px; }

/* Nella lista, un tema che non è ancora tuo si vede in bianco e nero: il colore
   è la cosa che si compra, e mostrarlo spento dice il prezzo meglio di
   un'etichetta. La scheda del singolo tema (`.tpv--card`) resta a colori — lì
   si sta decidendo se comprarlo, e va visto per quello che è.

   `filter` invece di una palette grigia perché ogni riga è dipinta dal foglio
   del tema che vende, e qui non si sa nemmeno di che colori si tratti. */
.tpv--riga[data-state="in-vendita"] { filter: grayscale(1); }

.tpv--card {
  height: 200px;
  padding: 22px;
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0;
}

.tpv__name { flex: 1; min-width: 0; }
.tpv--card .tpv__name { flex: 0 0 auto; }
.tpv__deco { display: none; position: absolute; }

.tdesc {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* ============================ caricamento ============================ */

/* L'unica schermata del cancello che il tema veste: qui l'accesso è già fatto e
   `showLoading()` ha applicato il tema ricordato in locale. Tutto viene dai
   token, quindi le dieci direzioni la ereditano senza una riga a testa —
   Manifesto la mostra in Archivo Black maiuscolo su carta, Notturna in
   Cormorant chiaro sul blu, e così via.

   Centrata nei due sensi: `.view` è già flex, e qui si centra il contenuto. */
.loadscr {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  padding: max(24px, var(--safe-t)) var(--pad) max(24px, var(--safe-b));
  background: var(--bg);
  color: var(--ink);
  text-align: center;
}

.loadscr__text {
  font-family: var(--font-display);
  font-size: var(--fs-lead);
  font-weight: var(--w-display);
  letter-spacing: var(--ls-display);
  text-transform: var(--tt-display);
  line-height: 1.15;
  text-wrap: balance;
}

.loadscr__hint {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--w-label);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
  color: var(--ink-2);
}

/* Un filo che scorre e riparte: colore dall'accento del tema, forma dal suo
   raggio. Non è una percentuale vera — quanto manchi non si sa, e fingerlo
   sarebbe peggio che ammetterlo. */
.loadscr__bar {
  width: min(200px, 55%);
  height: 4px;
  border-radius: var(--r-pill);
  background: var(--line);
  overflow: hidden;
}

.loadscr__bar i {
  display: block;
  width: 40%;
  height: 100%;
  border-radius: inherit;
  background: var(--accent);
  animation: loadslide 1.15s var(--ease-out) infinite;
}

@keyframes loadslide {
  from { transform: translateX(-110%); }
  to { transform: translateX(360%); }
}

/* ============================ login (fuori dai temi) ============================ */

/* Il tema si sceglie dopo l'accesso: questa schermata non ne ha uno, e resta
   quella disegnata in coda al tema 01. */

.gate {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #e63f1c;
  color: #fff;
  font-family: 'Archivo Black', var(--font);
}

.app[data-scr="login"] { --bg: #e63f1c; }

.gate__top {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: max(76px, var(--safe-t)) 24px 0;
}

.gate .mark--lg i { background: #fff; }
.gate .mark--lg i:nth-child(2) { background: #111; }

.gate__title { font-size: 60px; line-height: .88; letter-spacing: -.05em; text-transform: uppercase; }

.gate__claim {
  font-family: 'Space Mono', var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  line-height: 1.6;
}

.gate__foot { margin-top: auto; padding: 0 24px max(46px, var(--safe-b)); }

.gate__google {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: #111;
  color: #fff;
  padding: 20px 22px;
  font-family: 'Space Mono', var(--font-mono);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.gate__google[disabled] { opacity: .6; }

.gate__quit {
  width: 100%;
  margin-top: 10px;
  padding: 16px;
  border: 3px solid rgba(255, 255, 255, .5);
  color: #fff;
  font-family: 'Space Mono', var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.gate__fine {
  padding-top: 14px;
  font-family: 'Space Mono', var(--font-mono);
  font-size: 11px;
  line-height: 1.6;
  color: rgba(255, 255, 255, .8);
}

.gate__warn { width: 56px; height: 56px; display: flex; align-items: center; justify-content: center; }

/* ============================ foglio e messaggi ============================ */

.sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgba(0, 0, 0, .5);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  animation: fade var(--d-base) var(--ease-out);
}

.sheet {
  width: 100%;
  max-width: 480px;
  max-height: 88dvh;
  overflow-y: auto;
  background: var(--bg);
  color: var(--ink);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  padding: 10px var(--pad) max(20px, var(--safe-b));
  display: flex;
  flex-direction: column;
  gap: 12px;
  animation: rise var(--d-base) var(--ease-out);
  transition: transform var(--d-base) var(--ease-out);
}

.sheet__grab {
  width: 44px;
  height: 4px;
  border-radius: 999px;
  background: var(--line);
  margin: 0 auto 6px;
}

.sheet h2 {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: var(--w-display);
  text-transform: var(--tt-display);
}

.sheet p { font-size: var(--fs-small); color: var(--ink-2); }
.sheet__preview { display: flex; justify-content: center; }
.sheet__preview img { max-height: 220px; width: auto; border-radius: var(--r); border: 1px solid var(--line); }
.sheet__acts { display: flex; gap: var(--gap); }
.sheet__acts .btn { flex: 1; }
.dim { color: var(--ink-3); font-size: var(--fs-small); }

/* Il toast si appoggia sopra la tab bar dove c'è, e sopra l'indicatore Home
   dove non c'è. `--tabbar-h` lo misura `setChrome()` e vale 0 senza barra: il
   `max()` esterno sceglie da sé quale dei due vincoli comanda, senza sommarli —
   la barra la fascia di sicurezza se la tiene già dentro. */
.toast-host {
  position: fixed;
  left: 50%;
  bottom: max(calc(var(--tabbar-h, 0px) + 12px), max(20px, var(--safe-b)));
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  pointer-events: none;
  width: min(420px, calc(100vw - 32px));
}

.toast {
  background: var(--ink);
  color: var(--bg);
  padding: 12px 16px;
  border-radius: var(--r);
  font-family: var(--font-mono);
  font-size: 13px;
  text-align: center;
  animation: rise var(--d-base) var(--ease-out);
  transition: opacity var(--d-base), transform var(--d-base);
}

.toast--err { background: var(--accent); color: var(--accent-ink); }
.toast--ok { background: var(--ok); color: var(--ok-ink); }
.toast.is-out { opacity: 0; transform: translateY(8px); }

/* ============================ movimento ============================ */

@keyframes fade { from { opacity: 0; } }
@keyframes rise { from { opacity: 0; transform: translateY(16px); } }

.will-enter { animation: enter var(--d-base) var(--ease-out) backwards; animation-delay: calc(var(--i, 0) * 22ms); }
@keyframes enter { from { opacity: 0; transform: translateY(10px); } }

.is-entering { animation: view var(--d-base) var(--ease-out); }
@keyframes view { from { opacity: 0; transform: translateX(12px); } }
.view[data-direction="back"].is-entering { animation-name: viewBack; }
@keyframes viewBack { from { opacity: 0; transform: translateX(-12px); } }

.shake { animation: shake 420ms var(--ease-out); }
@keyframes shake {
  20% { transform: translateX(-7px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(2px); }
}

.confetti { position: fixed; inset: 0; z-index: 70; pointer-events: none; overflow: hidden; }
.confetti i {
  position: absolute;
  width: 8px;
  height: 12px;
  animation: burst 1200ms var(--ease-out) forwards;
}

@keyframes burst {
  from { opacity: 1; transform: translate(0, 0) rotate(0); }
  to { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(var(--rot)); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }

  /* Azzerare la durata lascerebbe il filo fermo a fine corsa, cioè fuori dal
     suo contenitore: la barra sembrerebbe vuota. Meglio piena e immobile. */
  .loadscr__bar i { animation: none; width: 100%; }
}
