/* MicroBeTech: movimento. Gli stati iniziali nascosti stanno qui e valgono solo
   sotto html.js, senza movimento ridotto e finché motion.js non li spegne con
   html.m-off. Il JavaScript aggiunge .is-in (comparsa) e poi .is-done (fine).
   Si anima con opacity, translate, scale, clip-path e, per i disegni al tratto,
   stroke-dashoffset: mai con la geometria. */

/* boot.js controlla solo site.js: se motion.js non parte entro 4 secondi, tutto si mostra comunque. */
@keyframes m-rescue { to { opacity: 1; translate: none; scale: none; clip-path: none; visibility: visible; } }
@keyframes m-rescue-scale { to { scale: none; } }
html.js:not(.m-on) [data-m], html.js:not(.m-on) [data-m-count] { animation: m-rescue 0.01s 4s both; }
html.js:not(.m-on) [data-m="media"] :is(img, video, canvas) { animation: m-rescue-scale 0.01s 4s both; }

/* Le righe dei titoli sono blocchi: il resto del titolo non cambia posto. Una riga non va mai a capo da sola. */
[data-m="lines"] .m-line, [data-m="lines"] .m-line__in { display: block; }
[data-m="lines"] .m-line__in { white-space: nowrap; }

/* Numeri che scorrono: cifre tabellari, così la larghezza non balla. */
.m-num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }

@media (prefers-reduced-motion: no-preference) {
  /* Comparse. Lo stato finale non dichiara nulla: vale lo stile dell'elemento. */
  html.js:not(.m-off) [data-m="up"]:not(.is-in) { opacity: 0; translate: 0 16px; }
  html.js:not(.m-off) [data-m="up"].is-in:not(.is-done) { transition: opacity 0.8s var(--ease), translate 0.8s var(--ease); transition-delay: var(--m-d, 0ms); will-change: opacity, translate; }
  html.js:not(.m-off) [data-m="fade"]:not(.is-in), html.js:not(.m-off) [data-m-count]:not([data-m]):not(.is-in) { opacity: 0; }
  html.js:not(.m-off) [data-m="fade"].is-in:not(.is-done), html.js:not(.m-off) [data-m-count]:not([data-m]).is-in:not(.is-done) { transition: opacity 0.7s var(--ease); transition-delay: var(--m-d, 0ms); will-change: opacity; }

  /* Titoli: ogni riga sale da dietro una maschera. La maschera è un ritaglio più
     largo della riga (clip-path negativo), così non taglia discendenti e accenti. */
  html.js:not(.m-off) [data-m="lines"]:not(.is-split) { visibility: hidden; }
  html.js:not(.m-off) [data-m="lines"]:not(.is-done) .m-line { clip-path: inset(-0.2em -0.12em); }
  html.js:not(.m-off) [data-m="lines"]:not(.is-in) .m-line__in { translate: 0 calc(100% + 0.4em); }
  html.js:not(.m-off) [data-m="lines"].is-in:not(.is-done) .m-line__in { transition: translate 0.9s var(--ease); transition-delay: calc(var(--m-d, 0ms) + var(--i, 0) * 80ms); will-change: translate; }

  /* Immagini e video: il ritaglio si allarga, il contenuto torna da 1,08 a 1.
     --m-r (il raggio dell'elemento) lo scrive motion.js; --m-clip si può cambiare. */
  html.js:not(.m-off) [data-m="media"]:not(.is-in) { clip-path: inset(var(--m-clip, 10%) round var(--m-r, 0px)); }
  html.js:not(.m-off) [data-m="media"]:not(.is-in) :is(img, video, canvas), html.js:not(.m-off) :is(img, video, canvas)[data-m="media"]:not(.is-in) { scale: 1.08; }
  html.js:not(.m-off) [data-m="media"].is-in:not(.is-done) { clip-path: inset(0 round var(--m-r, 0px)); transition: clip-path 1s var(--ease); transition-delay: var(--m-d, 0ms); will-change: clip-path; }
  html.js:not(.m-off) [data-m="media"].is-in:not(.is-done) :is(img, video, canvas) { transition: scale 1.2s var(--ease); transition-delay: var(--m-d, 0ms); will-change: scale; }
  html.js:not(.m-off) :is(img, video, canvas)[data-m="media"].is-in:not(.is-done) { transition: clip-path 1s var(--ease), scale 1.2s var(--ease); transition-delay: var(--m-d, 0ms); will-change: clip-path, scale; }

  /* Card impilate: la card coperta si rimpicciolisce fino a 0,96 e si scurisce appena.
     motion.js mette .m-stack__card sui figli sticky e scrive --covered da 0 a 1. */
  html.js:not(.m-off) .m-stack__card { transform-origin: 50% 0; scale: calc(1 - 0.04 * var(--covered, 0)); }
  html.js:not(.m-off) .m-stack__card::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--m-shade, var(--night)); opacity: calc(var(--covered, 0) * 0.09); pointer-events: none; }
  html.js:not(.m-off) [data-stack].is-live .m-stack__card { will-change: scale; }
  html.js:not(.m-off) [data-stack].is-live .m-stack__card::after { will-change: opacity; }

  /* Paragrafo che si accende: ogni parola ha la sua opacità (da 0,35 a 1), scritta da motion.js.
     Finché lo script non ha preparato le parole il paragrafo sta al 45%, come le parole spente. */
  html.js:not(.m-off) [data-m="read"]:not(.is-read) { opacity: 0.5; }

  /* Disegno al tratto: motion.js scrive su ogni tracciato la lunghezza (--len), la durata (--d) e
     l'attesa (--s) in millisecondi, e li mette in fila. Il tratteggio è lungo il tracciato più un
     vuoto doppio, così a riposo non resta nessun punto sul capolinea (con i capi arrotondati). Riempimenti,
     testi e linee già tratteggiate non si possono disegnare: compaiono con una dissolvenza. */
  html.js:not(.m-off) [data-m="draw"]:not(.is-ready) { visibility: hidden; }
  html.js:not(.m-off) [data-m="draw"]:not(.is-done) .m-dr:not(.m-dr--fade) { stroke-dasharray: var(--len) calc(var(--len) * 2); }
  html.js:not(.m-off) [data-m="draw"]:not(.is-in) .m-dr:not(.m-dr--fade) { stroke-dashoffset: calc(var(--len) + 1); }
  html.js:not(.m-off) [data-m="draw"]:not(.is-in) .m-dr--fade { opacity: 0; }
  html.js:not(.m-off) [data-m="draw"].is-in:not(.is-done) .m-dr:not(.m-dr--fade) { transition: stroke-dashoffset calc(var(--d, 600) * 1ms) cubic-bezier(0.45, 0, 0.25, 1); transition-delay: calc(var(--m-d, 0ms) + var(--s, 0) * 1ms); }
  html.js:not(.m-off) [data-m="draw"].is-in:not(.is-done) .m-dr--fade { transition: opacity calc(var(--d, 400) * 1ms) var(--ease); transition-delay: calc(var(--m-d, 0ms) + var(--s, 0) * 1ms); }
}

/* Fondo generativo dei pannelli (shader.js), dietro il contenuto. Tre proprietà ereditate, da
   riscrivere sul pannello per cambiarne il colore: --shader-bg è il fondo, --shader-a la fascia
   (di norma un tono appena più chiaro del fondo) e --shader-b l'isolinea sottile tra le due. Di
   partenza è un fondo scuro tono su tono con la linea verde: il testo chiaro del pannello (--snow,
   --snow-2) resta sopra i 4,5:1 su ogni punto del fondo, isolinea compresa. */
:root { --shader-bg: var(--night); --shader-a: var(--night-3); --shader-b: var(--g-700); }
canvas[data-shader] { position: absolute; inset: 0; z-index: -1; display: block; width: 100%; height: 100%; border-radius: inherit; pointer-events: none; }
:where(:has(> canvas[data-shader])) { position: relative; isolation: isolate; }

/* Sequenza (seq.js): colori e corpo delle lettere stanno nelle proprietà --seq-bg, --seq-fg, --seq-hi e --seq-size, che la pagina
   scrive sul canvas o su un suo genitore (si ereditano). Qui non si dichiarano: una dichiarazione sul canvas vincerebbe sul genitore.
   I valori di partenza, che seguono il tema della sezione, sono in seq.js come ripiego di var(). */
canvas[data-seq] { display: block; max-width: 100%; }

@media print {
  [data-m], [data-m-count], [data-m] :is(img, video, canvas), [data-m] .m-line, [data-m] .m-line__in, [data-m="read"] .m-rw { opacity: 1 !important; translate: none !important; scale: none !important; clip-path: none !important; visibility: visible !important; transition: none !important; animation: none !important; }
  [data-m="draw"] .m-dr { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; opacity: 1 !important; transition: none !important; }
  canvas[data-shader], canvas[data-seq] { display: none; }
}

/* Alone che segue il mouse sulle celle scure: data-glow scrive --mx e --my (solo con puntatore fine). Senza, non si vede. */
[data-glow] { position: relative; }
[data-glow]::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), color-mix(in srgb, var(--g-200) 10%, transparent), transparent 62%); opacity: 0; transition: opacity 0.4s var(--ease); }
[data-glow]:hover::after { opacity: 1; }
