/* ===========================================================
   PATCH ARCHIVE                                        (v100)

   La pagina eredita da `.page-shell` (v92_pages_shell.css) misura,
   inchiostro e capelli: qui non si ridichiara una palette parallela,
   si aggiunge soltanto cio' che il resto del sito non ha ancora --
   la scala di minaccia e la scheda di un record.

   La scala cromatica sale dal cyan del sito verso il caldo, e il caldo
   compare UNA SOLA VOLTA, sul livello 05. E' l'unica eccezione
   cromatica del sito ed e' voluta: se comparisse anche altrove
   smetterebbe di voler dire qualcosa.
   =========================================================== */

/* ===========================================================
   La barra di scorrimento, solo qui

   Questa pagina e' lunga per natura e lo scorrimento fa parte di come si
   legge, quindi la barra vale la pena di disegnarla. Ma vale solo per
   questa pagina: la selezione passa da `:has()` sul body, cosi' nessuna
   altra pagina del sito viene toccata e non serve aggiungere una classe
   al documento.

   Il pollice sale dal cyan al viola, gli stessi passaggi della scala di
   minaccia, ma si ferma prima del rosso: quello e' del livello 05 e se
   comparisse anche qui smetterebbe di voler dire qualcosa.

   Firefox ha le sue due proprieta' e non capisce le pseudo-classi di
   WebKit, quindi sono dichiarate entrambe le strade. Su telefono non si
   forza niente: li' la barra e' del sistema, compare da sola quando serve
   e sparisce, e riservarle spazio toglierebbe larghezza al testo per un
   elemento che non si vede quasi mai. Nessuna barra finta in JavaScript.
   =========================================================== */
html:has(> body[data-page="updates"]) {
  scrollbar-width: thin;
  scrollbar-color: #4aa8e6 #030913;
}

@media (hover: hover) and (pointer: fine) {
  html:has(> body[data-page="updates"])::-webkit-scrollbar {
    width: 11px;
  }

  html:has(> body[data-page="updates"])::-webkit-scrollbar-track {
    background: #030913;
    border-left: 1px solid rgba(99, 220, 255, .1);
  }

  html:has(> body[data-page="updates"])::-webkit-scrollbar-thumb {
    border: 3px solid transparent;      /* il bordo trasparente assottiglia
                                           il pollice senza restringere la
                                           zona che si puo' afferrare */
    border-radius: 8px;
    background: linear-gradient(180deg, #58d5ff, #6aa9ff 34%, #a88cff 72%, #d472ff);
    background-clip: content-box;
  }

  html:has(> body[data-page="updates"])::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, #7ee2ff, #86bcff 34%, #bda3ff 72%, #e492ff);
    background-clip: content-box;
  }
}

.patch-page {
  --t1: #58d5ff;   /* TRACE    */
  --t2: #6aa9ff;   /* DRIFT    */
  --t3: #a88cff;   /* ANOMALY  */
  --t4: #d472ff;   /* ABYSS    */
  --t5: #ff5a6e;   /* 4072     */
  --i1: #7fd8ff;   /* LILY        */
  --i2: #9ab6ff;   /* GLITCH LILY */
  --i3: #c79bff;   /* 4072 BLOOM  */
  --patch-mono: "Courier New", ui-monospace, monospace;
}

.patch-page [data-family="patch"][data-threat="1"] { --tinta: var(--t1); }
.patch-page [data-family="patch"][data-threat="2"] { --tinta: var(--t2); }
.patch-page [data-family="patch"][data-threat="3"] { --tinta: var(--t3); }
.patch-page [data-family="patch"][data-threat="4"] { --tinta: var(--t4); }
.patch-page [data-family="patch"][data-threat="5"] { --tinta: var(--t5); }

/* La famiglia delle implementazioni resta nel blu e nel viola e non
   arriva mai al rosso: quello e' del solo livello 05 delle patch, e se
   comparisse anche qui smetterebbe di segnalare qualcosa. */
.patch-page [data-family="impl"][data-threat="1"] { --tinta: var(--i1); }
.patch-page [data-family="impl"][data-threat="2"] { --tinta: var(--i2); }
.patch-page [data-family="impl"][data-threat="3"] { --tinta: var(--i3); }

/* L'intestazione di famiglia sopra ciascuna legenda. */
.patch-famiglia {
  margin: 0 0 .2rem;
  color: var(--t1);
  font: 700 .62rem/1.5 var(--patch-mono);
  letter-spacing: .2em;
}
.patch-famiglia--impl { color: var(--i3); }

/* --- i filtri ------------------------------------------------------- */
.patch-filtri {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: -.2rem;
}
.patch-filtri[hidden] { display: none; }

.patch-filtro {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  min-height: 44px;
  padding: .45rem .9rem;
  border: 1px solid var(--page-hair);
  border-radius: 2px 12px 2px 12px;
  color: rgba(178, 214, 232, .82);
  background: rgba(2, 12, 26, .5);
  font: 700 .62rem/1 var(--patch-mono);
  letter-spacing: .15em;
  cursor: pointer;
  transition: color .16s ease, border-color .16s ease, background-color .16s ease;
}

.patch-filtro em {
  font-style: normal;
  font-size: .92em;
  opacity: .62;
  font-variant-numeric: tabular-nums;
}

.patch-filtro:hover { color: #dcf6ff; border-color: var(--page-hair-strong); }

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

/* Lo stato attivo non e' solo colore: `aria-pressed` lo dice a chi non
   vede quale dei tre e' evidenziato, e il bordo pieno lo dice a chi
   guarda. */
.patch-filtro[aria-pressed="true"] {
  color: #eafcff;
  border-color: rgba(140, 235, 255, .72);
  background: rgba(7, 34, 60, .85);
}

.patch-vuoto {
  margin: 0;
  padding: 1.6rem 0;
  color: rgba(178, 214, 232, .7);
  font: 700 .7rem/1.6 var(--patch-mono);
  letter-spacing: .12em;
}
.patch-vuoto[hidden] { display: none; }

/* --- il riquadro dell'entita' ---------------------------------------
   Stessa misura in ogni record e in ogni voce della legenda: e' il
   confronto a raccontare la crescita, non la dimensione della cornice.
   Se questo riquadro cambiasse taglia da un record all'altro, la scala
   non direbbe piu' niente. */
.patch-teca {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  border: 1px solid var(--page-hair);
  border-radius: 2px 18px 2px 18px;
  background: radial-gradient(circle at 50% 50%, rgba(0, 12, 28, .82), rgba(0, 4, 12, .94));
  overflow: hidden;
}

.patch-teca svg { display: block; width: 100%; height: 100%; }

.patch-teca::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(0deg, rgba(1, 6, 15, .5), transparent 40%);
}

/* --- legenda: i cinque livelli prima di vederli usati ---------------- */
.patch-legend {
  width: min(var(--page-max), 100%);
  margin: clamp(2.4rem, 6vw, 4.2rem) auto 0;
  padding-inline: clamp(1.1rem, 5vw, 4rem);
}

.patch-legend > h2 {
  margin: 0 0 .6rem;
  color: var(--page-ink);
  font-size: clamp(1.3rem, 3vw, 1.85rem);
  letter-spacing: -.02em;
}

.patch-legend > p {
  max-width: var(--page-measure);
  margin: 0 0 clamp(1.4rem, 3vw, 2.2rem);
  color: var(--page-ink-soft);
}

.patch-ladder {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: clamp(.9rem, 2vw, 1.4rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Sul telefono le due colonne sono DICHIARATE, non lasciate decidere al
   `minmax`. Misurato a 375: rientro di pagina 18.75px per lato e gap
   14.4px lasciano 161.5px a colonna, mentre il minimo ne chiedeva 168.
   Mancavano sei pixel e mezzo, e la scala collassava in una colonna sola,
   che a quella larghezza spreca spazio e impedisce il confronto fra gli
   stadi: la legenda esiste proprio per guardarli uno accanto all'altro. */
@media (max-width: 560px) {
  .patch-ladder {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .7rem;
  }
}

.patch-ladder > li {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: .7rem;
  padding: clamp(.8rem, 1.6vw, 1.1rem);
  border: 1px solid var(--page-hair);
  border-radius: 2px 18px 2px 18px;
  background: rgba(2, 12, 26, .42);
}

.patch-ladder .patch-teca { border-radius: 2px 12px 2px 12px; }

/* Nella legenda nome e parola stanno SEMPRE su due righe, in tutte e
   cinque le voci.

   Su una riga sola non ci starebbero comunque tutte: a 320 la voce
   peggiore, ANOMALY piu' HARD, chiede 140px contro i 109 disponibili, e
   ridurre il corpo per farcela non e' una strada. Lasciando decidere al
   flusso, pero', il risultato era peggiore dello sforamento: TRACE
   stava su una riga e le altre quattro su due, quindi le card non si
   somigliavano piu'. La legenda serve a confrontare cinque cose, e il
   confronto regge solo se le cinque schede hanno la stessa forma.

   In colonna la pastiglia si stringe attorno al proprio testo invece di
   allargarsi per tutta la card. */
.patch-ladder .patch-rank {
  flex-direction: column;
  align-items: flex-start;
  gap: .35rem;
}

/* Nella legenda la card ha un suo padding: l'ordinale lo segue, per
   restare appoggiato all'angolo della cornice e non a quello della card. */
.patch-ladder > li > .patch-ord {
  top: calc(clamp(.8rem, 1.6vw, 1.1rem) + 7px);
  left: calc(clamp(.8rem, 1.6vw, 1.1rem) + 9px);
}

.patch-rank {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .3rem .45rem;
}

/* L'ordinale sta sulla cornice, non nella riga del nome.

   Misurato a 320, con 109px disponibili nella card: "03 //" da solo ne
   occupava 43, quasi la meta', e insieme ad ANOMALY (85px) sforava prima
   ancora di arrivare alla parola. Il risultato era che quattro card
   andavano a due righe e una a tre. Qui l'ordinale etichetta la creatura
   invece di contendere lo spazio al nome, e le cinque card tornano
   uguali senza toccare un solo corpo di testo.

   Resta leggibile da uno screen reader: il numero e' ripetuto come testo
   nascosto dentro la riga, e questo marcatore e' `aria-hidden`. */
.patch-ord {
  position: absolute;
  z-index: 2;
  top: 7px;
  left: 9px;
  color: var(--tinta);
  font: 700 .68rem/1 var(--patch-mono);
  letter-spacing: .12em;
  text-shadow: 0 0 8px rgba(0, 6, 16, .95), 0 0 3px rgba(0, 6, 16, 1);
  pointer-events: none;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.patch-rank strong {
  color: var(--page-ink);
  font-size: 1.02rem;
  font-weight: 800;
  letter-spacing: -.01em;
}

/* La parola comprensibile non e' decorativa e non sparisce mai: e'
   l'unica cosa che si capisce senza aver letto il resto. */
.patch-word {
  padding: .18rem .5rem;
  border: 1px solid var(--tinta);
  border-radius: 2px 8px 2px 8px;
  color: var(--tinta);
  font: 700 .62rem/1.35 var(--patch-mono);
  letter-spacing: .16em;
  white-space: nowrap;
}

.patch-ladder p {
  margin: 0;
  color: var(--page-ink-soft);
  font-size: .84rem;
  line-height: 1.55;
}

/* --- lo scorrimento dei record --------------------------------------- */
.patch-stream {
  width: min(var(--page-max), 100%);
  margin: clamp(2.6rem, 7vw, 4.8rem) auto 0;
  padding-inline: clamp(1.1rem, 5vw, 4rem);
  display: flex;
  flex-direction: column;
  gap: clamp(1.2rem, 3vw, 2rem);
}

.patch-stream > h2 {
  margin: 0;
  color: var(--page-ink);
  font-size: clamp(1.3rem, 3vw, 1.85rem);
  letter-spacing: -.02em;
}

.patch-record {
  display: grid;
  grid-template-columns: 190px minmax(0, 1fr);
  gap: clamp(1.1rem, 3vw, 2.1rem);
  padding: clamp(1.1rem, 2.6vw, 1.9rem);
  border: 1px solid var(--page-hair);
  border-radius: 3px 28px 3px 28px;
  background: linear-gradient(145deg, rgba(1, 20, 38, .5), rgba(3, 6, 22, .58) 60%, rgba(18, 9, 48, .5));
}

.patch-threat {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: .7rem;
  min-width: 0;
}

.patch-body {
  display: flex;
  flex-direction: column;
  gap: clamp(.9rem, 2vw, 1.3rem);
  min-width: 0;
}

.patch-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .4rem 1.1rem;
}

.patch-date,
.patch-origin {
  margin: 0;
  font: 700 .64rem/1.5 var(--patch-mono);
  letter-spacing: .15em;
}

.patch-date { color: rgba(160, 205, 224, .62); }
.patch-origin { color: var(--page-accent); }

.patch-head h3 {
  width: 100%;
  margin: 0;
  color: var(--page-ink);
  font-size: clamp(1.25rem, 3.2vw, 1.75rem);
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1.1;
  text-wrap: balance;
}

/* La provenienza compare solo dove una segnalazione e' arrivata davvero,
   e non nomina nessuno. Sta sotto il titolo, in corpo minore: e' una nota
   d'archivio, non una firma. */
.patch-source {
  width: 100%;
  margin: 0;
  color: rgba(150, 200, 222, .62);
  font: 700 .6rem/1.6 var(--patch-mono);
  letter-spacing: .1em;
}

/* --- i controlli di pagina ------------------------------------------- */
.patch-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .7rem;
  margin-top: clamp(.6rem, 2vw, 1.2rem);
  padding-top: clamp(.9rem, 2vw, 1.3rem);
  border-top: 1px solid var(--page-hair);
}

.patch-pager[hidden] { display: none; }

.patch-pager-btn {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  min-height: 44px;
  padding: .5rem .95rem;
  border: 1px solid var(--page-hair-strong);
  border-radius: 2px 12px 2px 12px;
  color: #a8e9ff;
  background: rgba(2, 14, 30, .6);
  font: 700 .64rem/1 var(--patch-mono);
  letter-spacing: .16em;
  cursor: pointer;
  transition: color .16s ease, border-color .16s ease, background-color .16s ease;
}

.patch-pager-btn:hover:not(:disabled),
.patch-pager-btn:focus-visible {
  color: #e6fbff;
  border-color: rgba(140, 235, 255, .7);
  background: rgba(6, 30, 54, .8);
}

.patch-pager-btn:focus-visible {
  outline: 2px solid var(--page-accent);
  outline-offset: 2px;
}

/* Disabilitato vuol dire disabilitato: resta leggibile, ma smette di
   sembrare toccabile. Non lo si nasconde, altrimenti i due comandi
   si sposterebbero a ogni cambio di pagina. */
.patch-pager-btn:disabled {
  color: rgba(140, 185, 205, .38);
  border-color: rgba(99, 220, 255, .12);
  background: rgba(2, 10, 22, .4);
  cursor: default;
}

.patch-pager-count {
  margin: 0;
  color: rgba(170, 215, 235, .8);
  font: 700 .7rem/1 var(--patch-mono);
  letter-spacing: .2em;
  font-variant-numeric: tabular-nums;
}

/* Sul telefono i tre elementi non stanno su una riga: misurato a 320,
   ne servono 313 contro i 285 disponibili. Lasciato al flusso il risultato
   era storto, con il contatore appeso in fondo alla prima riga e
   SUCCESSIVA da sola sotto a sinistra. Qui la disposizione e' dichiarata:
   lo stato sopra, i due comandi affiancati sotto, larghi uguali. */
@media (max-width: 560px) {
  .patch-pager {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .55rem;
  }

  .patch-pager-count {
    grid-column: 1 / -1;
    grid-row: 1;
    text-align: center;
  }

  .patch-pager-btn {
    grid-row: 2;
    justify-content: center;
    padding-inline: .5rem;
  }

  [data-patch-prev] { grid-column: 1; }
  [data-patch-next] { grid-column: 2; }
}

/* Il titolo della sezione riceve il fuoco al cambio pagina: e' un
   bersaglio programmatico, non un elemento interattivo, quindi il
   contorno si mostra solo quando serve davvero. */
.patch-stream > h2:focus { outline: none; }
.patch-stream > h2:focus-visible {
  outline: 2px solid var(--page-accent);
  outline-offset: 4px;
}

/* I tre campi sono termine + descrizione, e il markup lo dice: una
   lista di definizioni, non tre paragrafi con un'etichetta davanti. */
.patch-fields {
  display: flex;
  flex-direction: column;
  gap: .85rem;
  margin: 0;
}

.patch-fields > div {
  display: grid;
  grid-template-columns: 6.2rem minmax(0, 1fr);
  gap: .2rem .9rem;
  align-items: baseline;
}

.patch-fields dt {
  color: rgba(150, 200, 222, .6);
  font: 700 .6rem/1.9 var(--patch-mono);
  letter-spacing: .15em;
}

.patch-fields dd {
  margin: 0;
  max-width: var(--page-measure);
  color: var(--page-ink-soft);
  font-size: .95rem;
  line-height: 1.65;
}

.patch-close {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .9rem;
  padding-top: .9rem;
  border-top: 1px solid var(--page-hair);
}

.patch-status {
  padding: .22rem .6rem;
  border: 1px solid var(--page-hair-strong);
  border-radius: 2px 9px 2px 9px;
  color: #8ee8ff;
  font: 700 .62rem/1.4 var(--patch-mono);
  letter-spacing: .16em;
}

/* L'ironia sta nei dettagli e in un livello soltanto. */
.patch-aside {
  color: rgba(255, 138, 152, .82);
  font: 700 .6rem/1.4 var(--patch-mono);
  letter-spacing: .14em;
}

/* --- la sequenza di comparsa -----------------------------------------
   Nascosto SOLO se il JS c'e' (`.v72-js` lo aggiunge lo script inline in
   testa al documento). Senza JS la pagina si legge tutta, subito.

   L'ordine e' quello approvato: data, origine, titolo, minaccia, testo,
   esito. Sei ritardi dichiarati, non calcolati: si leggono qui. */
.v72-js .patch-record [data-fase] {
  opacity: 0;
  transform: translateY(9px);
}

.v72-js .patch-record.is-live [data-fase] {
  animation: patch-sale .46s cubic-bezier(.22, .78, .3, 1) both;
}

.v72-js .patch-record.is-live [data-fase="1"] { animation-delay: 0ms; }
.v72-js .patch-record.is-live [data-fase="2"] { animation-delay: 90ms; }
.v72-js .patch-record.is-live [data-fase="3"] { animation-delay: 180ms; }
.v72-js .patch-record.is-live [data-fase="4"] { animation-delay: 280ms; }
.v72-js .patch-record.is-live [data-fase="5"] { animation-delay: 400ms; }
.v72-js .patch-record.is-live [data-fase="6"] { animation-delay: 520ms; }

@keyframes patch-sale {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}

/* Le schegge dell'entita' si posano una volta sola.

   `transform-box` vale SOLTANTO qui, sulle schegge, perche' e' l'unica
   cosa che si anima individualmente. Applicarlo anche ai poligoni del
   nucleo cambiava il centro di rotazione dei quarti spezzati e li
   spediva fuori dalla cornice: il nucleo e' animato come gruppo, non
   pezzo per pezzo, e non ne ha bisogno. */
.patch-teca .schegge polygon {
  transform-box: fill-box;
  transform-origin: center;
}

.v72-js .patch-teca:not(.is-live) .schegge,
.v72-js .patch-teca:not(.is-live) .bocciolo { opacity: 0; }

.v72-js .patch-teca.is-live .schegge polygon {
  animation: patch-apri .5s cubic-bezier(.2, .8, .3, 1) both;
}

.v72-js .patch-teca.is-live .cuore {
  animation: patch-batti .38s ease both;
}

/* --- Living Signal Lily ---------------------------------------------
   Tre piani reali: campo/echi dietro, informazione spezzata al centro,
   giglio materico davanti. Il glitch e' sempre una porzione dei sei
   petali originali, mai una particella generica. */
.patch-teca .living-lily {
  --lily-petal-time: 480ms;
  --lily-glitch-time: 0ms;
  --lily-shard-time: 0ms;
  --lily-core-delay: 170ms;
  --lily-breath: 7.2s;
  --lily-story: 9.6s;
  color: var(--tinta);
  isolation: isolate;
}

.patch-teca .living-lily--2 {
  --lily-petal-time: 570ms;
  --lily-glitch-time: 560ms;
  --lily-shard-time: 300ms;
  --lily-core-delay: 20ms;
  --lily-breath: 6.6s;
  --lily-story: 7.2s;
}

.patch-teca .living-lily--3 {
  --lily-petal-time: 600ms;
  --lily-glitch-time: 460ms;
  --lily-shard-time: 240ms;
  --lily-core-delay: 20ms;
  --lily-breath: 6s;
  --lily-story: 18s;
}

.patch-teca .lily-petal,
.patch-teca .lily-petal-aura,
.patch-teca .lily-vein,
.patch-teca .lily-echo-segment,
.patch-teca .lily-shard,
.patch-teca .lily-input-trace,
.patch-teca .lily-field-line,
.patch-teca .lily-halo-piece,
.patch-teca .lily-field-glyph,
.patch-teca .lily-core-diamond,
.patch-teca .lily-core-cross,
.patch-teca .lily-vein-current,
.patch-teca .lily-field-flow-path,
.patch-teca .lily-halo-flow-path {
  vector-effect: non-scaling-stroke;
  shape-rendering: geometricPrecision;
}

.patch-teca .lily-petal,
.patch-teca .lily-petal-aura,
.patch-teca .lily-vein,
.patch-teca .lily-echo-segment,
.patch-teca .lily-shard,
.patch-teca .lily-core-reveal,
.patch-teca .lily-signal-node,
.patch-teca .lily-field-glyph {
  transform-box: fill-box;
  transform-origin: center;
}

.patch-teca .lily-core-idle,
.patch-teca .lily-core-event,
.patch-teca .lily-petal-body-idle,
.patch-teca .lily-petal-idle,
.patch-teca .lily-shard-idle,
.patch-teca .lily-echo-idle,
.patch-teca .lily-field-fracture {
  transform-box: fill-box;
  transform-origin: center;
}

/* FRONT: il fiore e' gia' completo al livello 01. Il secondo stroke crea
   profondita' senza blur e senza una forma piena dietro. */
.patch-teca .lily-petal-aura {
  fill: none;
  stroke: #42dfff;
  stroke-width: 2.7;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  opacity: .18;
}

.patch-teca .lily-petal {
  fill-opacity: .72;
  stroke-width: 1.12;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
}

.patch-teca .living-lily--2 .lily-petal,
.patch-teca .living-lily--3 .lily-petal { fill-opacity: .64; }

.patch-teca .living-lily--2 .lily-petal--unstable,
.patch-teca .living-lily--3 .lily-petal--unstable {
  stroke-dasharray: .43 .035 .18 .055 .3;
}

.patch-teca .lily-vein {
  fill: none;
  stroke: #bdf8ff;
  stroke-width: .66;
  stroke-linecap: round;
  stroke-dasharray: .2 .055 .07 .1;
  opacity: .68;
}

/* La vena luminosa e' un duplicato dedicato soltanto all'idle: il reveal
   continua a possedere i tracciati originali e non compete con questo. */
.patch-teca .lily-vein-current {
  fill: none;
  stroke: #e4fdff;
  stroke-width: .82;
  stroke-linecap: round;
  stroke-dasharray: .075 .925;
}

.patch-teca .lily-vein-current-idle,
.patch-teca .lily-field-flow,
.patch-teca .lily-halo-flow {
  opacity: 0;
}

.patch-teca .living-lily--2 .lily-vein:nth-child(even),
.patch-teca .living-lily--3 .lily-vein:nth-child(even) {
  stroke: #b49aff;
  opacity: .62;
}

.patch-teca .lily-core-diamond {
  fill: rgba(67, 224, 255, .13);
  stroke: #c9fbff;
  stroke-width: .68;
  stroke-dasharray: .48 .12;
}

.patch-teca .lily-core {
  opacity: .98;
}

.patch-teca .lily-core-spark {
  fill: #fff;
  opacity: .96;
}

.patch-teca .lily-core-cross {
  fill: none;
  stroke: var(--tinta);
  stroke-width: .48;
  stroke-linecap: round;
  opacity: .68;
}

/* BACK: niente orbite perfette. Sono traiettorie botaniche interrotte,
   asimmetriche, piu' deboli della materia centrale. */
.patch-teca .lily-input-trace,
.patch-teca .lily-field-line,
.patch-teca .lily-halo-piece {
  fill: none;
  stroke-linecap: round;
}

.patch-teca .lily-input-trace {
  stroke: #54e4ff;
  stroke-width: .7;
  stroke-dasharray: .18 .06 .04 .08;
  opacity: .62;
}

.patch-teca .lily-signal-node {
  fill: #aef8ff;
  opacity: .84;
}

.patch-teca .lily-signal-node--2 { fill: #5ee8ff; opacity: .68; }
.patch-teca .lily-signal-node--3 { fill: #fff; opacity: .92; }

.patch-teca .lily-field-line {
  stroke: #54dbff;
  stroke-width: .58;
  stroke-dasharray: .21 .07 .04 .1;
  opacity: .34;
}

.patch-teca .living-lily--3 .lily-field-line:nth-of-type(2n) {
  stroke: #aa82ff;
  opacity: .31;
}

.patch-teca .lily-halo-piece {
  stroke: #927bff;
  stroke-width: .62;
  stroke-dasharray: .17 .06 .08 .12;
  opacity: .28;
}

.patch-teca .lily-halo-piece--1,
.patch-teca .lily-halo-piece--3 { stroke: #51dfff; }

.patch-teca .lily-field-flow-path,
.patch-teca .lily-halo-flow-path {
  fill: none;
  stroke-linecap: round;
}

.patch-teca .lily-field-flow-path {
  stroke: #94f4ff;
  stroke-width: .72;
  stroke-dasharray: .055 .19 .025 .73;
}

.patch-teca .lily-halo-flow-path {
  stroke: #b69bff;
  stroke-width: .7;
  stroke-dasharray: .045 .22 .035 .7;
}

.patch-teca .lily-field-glyph {
  fill: none;
  stroke: #c3faff;
  stroke-width: .54;
  stroke-linecap: round;
  opacity: .42;
}

/* Gli echi sono soltanto parti del fiore: tre ricostruzioni incomplete,
   ciascuna su un piano e con una cromia diversa. */
.patch-teca .lily-echo-segment {
  fill: none;
  stroke-width: .84;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .25;
}

.patch-teca .lily-echo--cyan {
  --lily-glitch-x: -.72px;
  --lily-glitch-back: .26px;
  stroke: #43e5ff;
}

.patch-teca .lily-echo--violet {
  --lily-glitch-x: .82px;
  --lily-glitch-back: -.3px;
  stroke: #806dff;
  opacity: .23;
}

.patch-teca .lily-echo--lilac {
  --lily-glitch-x: -.46px;
  --lily-glitch-back: .18px;
  stroke: #c28fff;
  opacity: .2;
}

/* L'eco viola del GLITCH LILY e' un attore dell'evento, non un nuovo
   elemento della composizione a riposo. */
.patch-teca .living-lily--2 .lily-echo-idle--violet {
  opacity: 0;
}

/* MID: segmenti degli stessi PETALI, abbastanza luminosi da sembrare
   materia informatica separata dal fiore ma ancora riconoscibile. */
.patch-teca .lily-shard {
  fill: none;
  stroke-width: 2.15;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .74;
}

.patch-teca .lily-shard--cyan   { stroke: #46e8ff; }
.patch-teca .lily-shard--violet { stroke: #8974ff; }
.patch-teca .lily-shard--lilac  { stroke: #c796ff; }
.patch-teca .lily-shard--late   { opacity: .56; }

.patch-teca .lily-mark-4072,
.patch-teca .lily-mark-signal {
  font-size: 3.05px;
  font-weight: 700;
  letter-spacing: .58px;
}

.patch-teca .lily-mark-4072 {
  opacity: .2;
}

.patch-teca .lily-mark-signal {
  opacity: .94;
}

.patch-teca .lily-mark-signal-idle {
  opacity: 0;
}

/* Reveal dedicato: accensione, disegno, rottura, espansione, stabilita'. */
.v72-js .patch-teca.is-live .lily-core-reveal {
  animation: lily-core-ignite 240ms cubic-bezier(.18, .84, .24, 1) both;
  animation-delay: var(--lily-core-delay);
}

.v72-js .patch-teca.is-live .lily-petal-aura {
  animation: lily-petal-aura var(--lily-petal-time) ease-out both;
  animation-delay: var(--lily-delay, 0ms);
}

.v72-js .patch-teca.is-live .lily-petal {
  animation: lily-petal-build var(--lily-petal-time) cubic-bezier(.18, .78, .24, 1) both;
  animation-delay: var(--lily-delay, 0ms);
}

.v72-js .patch-teca.is-live .lily-vein {
  animation: lily-vein-reveal 220ms ease-out both;
  animation-delay: var(--lily-delay, 0ms);
}

.v72-js .patch-teca.is-live .lily-input-trace {
  animation: lily-input-arrive 250ms ease-out both;
}

.v72-js .patch-teca.is-live .lily-signal-node {
  animation: lily-node-acquire 360ms ease-out both;
}

.v72-js .patch-teca.is-live .lily-signal-node--1 { animation-delay: 70ms; }
.v72-js .patch-teca.is-live .lily-signal-node--2 { animation-delay: 140ms; }
.v72-js .patch-teca.is-live .lily-signal-node--3 { animation-delay: 210ms; }

.v72-js .patch-teca.is-live .lily-echo-segment {
  animation: lily-echo-break var(--lily-glitch-time) cubic-bezier(.18, .72, .2, 1) both;
  animation-delay: var(--lily-delay, 0ms);
}

.v72-js .patch-teca.is-live .lily-shard {
  animation: lily-shard-expel var(--lily-shard-time) cubic-bezier(.2, .78, .2, 1) both;
  animation-delay: var(--lily-delay, 0ms);
}

.v72-js .patch-teca.is-live .lily-field-line {
  animation: lily-field-connect 250ms ease-out both;
  animation-delay: var(--lily-delay, 0ms);
}

.v72-js .patch-teca.is-live .living-lily--3 .lily-field-line {
  animation-duration: 300ms;
}

.v72-js .patch-teca.is-live .lily-halo-piece {
  animation: lily-halo-connect 260ms ease-out both;
  animation-delay: var(--lily-delay, 0ms);
}

.v72-js .patch-teca.is-live .lily-field-glyph {
  animation: lily-glyph-arrive 260ms steps(2, end) 1210ms both;
}

.v72-js .patch-teca.is-live .lily-mark-4072 {
  animation: lily-code-discovered 400ms ease-out 1270ms both;
}

/* Appena la sequenza termina il reveal cede ogni proprieta': i suoi nodi
   tornano allo stato base statico. L'idle vive soltanto sui wrapper e sugli
   overlay dedicati, quindi nessun `forwards` puo' coprirlo o sostituirlo. */
.v72-js .patch-teca.is-live.is-settled .lily-core-reveal,
.v72-js .patch-teca.is-live.is-settled .lily-petal-aura,
.v72-js .patch-teca.is-live.is-settled .lily-petal,
.v72-js .patch-teca.is-live.is-settled .lily-vein,
.v72-js .patch-teca.is-live.is-settled .lily-input-trace,
.v72-js .patch-teca.is-live.is-settled .lily-signal-node,
.v72-js .patch-teca.is-live.is-settled .lily-echo-segment,
.v72-js .patch-teca.is-live.is-settled .lily-shard,
.v72-js .patch-teca.is-live.is-settled .lily-field-line,
.v72-js .patch-teca.is-live.is-settled .lily-halo-piece,
.v72-js .patch-teca.is-live.is-settled .lily-field-glyph,
.v72-js .patch-teca.is-live.is-settled .lily-mark-4072 {
  animation: none;
}

/* L'idle non e' un tremolio continuo: ogni livello racconta un evento e
   conserva lunghe zone di quiete. Tutte le animazioni narrative hanno la
   stessa durata del proprio stadio; i piccoli delay servono solo a far
   viaggiare il segnale tra elementi, non a introdurre casualita'. */
.v72-js .patch-teca.is-live.is-settled .lily-core-idle {
  animation-name: lily-core-breathe;
  animation-duration: var(--lily-breath);
  animation-timing-function: ease-in-out;
  animation-delay: .35s;
  animation-iteration-count: infinite;
  animation-fill-mode: none;
}

.v72-js .patch-teca.is-live.is-settled .lily-core-event,
.v72-js .patch-teca.is-live.is-settled .lily-petal-idle--lily-response,
.v72-js .patch-teca.is-live.is-settled .lily-petal-body-idle--desync,
.v72-js .patch-teca.is-live.is-settled .lily-petal-idle--outline-drop,
.v72-js .patch-teca.is-live.is-settled .lily-petal-idle--bloom-response,
.v72-js .patch-teca.is-live.is-settled .lily-vein-current-idle,
.v72-js .patch-teca.is-live.is-settled .lily-echo-idle,
.v72-js .patch-teca.is-live.is-settled .lily-shard-idle--signal,
.v72-js .patch-teca.is-live.is-settled .lily-shard-idle--late,
.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-field-static,
.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-halo-static,
.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-field-fracture--active,
.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-field-flow,
.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-halo-flow,
.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-mark-signal-idle {
  animation-duration: var(--lily-story);
  animation-iteration-count: infinite;
  animation-fill-mode: none;
}

.v72-js .patch-teca.is-live.is-settled .living-lily--1 .lily-core-event {
  animation-name: lily-l1-core-pulse;
  animation-timing-function: ease-in-out;
}

.v72-js .patch-teca.is-live.is-settled .living-lily--1 .lily-vein-current-idle {
  animation-name: lily-l1-vein-pulse;
  animation-timing-function: ease-out;
  animation-delay: calc(var(--lily-seq, 0) * .13s);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--1 .lily-petal-idle--lily-response {
  animation-name: lily-l1-petal-bloom;
  animation-timing-function: ease-in-out;
  animation-delay: calc(var(--lily-seq, 0) * .1s);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--2 .lily-core-event {
  animation-name: lily-l2-core-snap;
  animation-timing-function: cubic-bezier(.2, .74, .18, 1);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--2 .lily-petal-body-idle--desync {
  animation-name: lily-l2-petal-desync;
  animation-timing-function: cubic-bezier(.2, .72, .16, 1);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--2 .lily-petal-idle--outline-drop {
  animation-name: lily-l2-outline-drop;
  animation-timing-function: steps(1, end);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--2 .lily-vein-current-idle {
  animation-name: lily-l2-vein-snap;
  animation-timing-function: ease-out;
  animation-delay: calc(var(--lily-seq, 0) * .08s);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--2 .lily-echo-idle--cyan {
  animation-name: lily-l2-echo-cyan;
  animation-timing-function: steps(1, end);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--2 .lily-echo-idle--violet {
  animation-name: lily-l2-echo-violet;
  animation-timing-function: steps(1, end);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--2 .lily-shard-idle--signal {
  animation-name: lily-l2-fragment-reaction;
  animation-timing-function: steps(1, end);
  animation-delay: calc(var(--lily-seq, 0) * .025s);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-core-event {
  animation-name: lily-l3-core-story;
  animation-timing-function: ease-in-out;
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-petal-idle--bloom-response {
  animation-name: lily-l3-petal-response;
  animation-timing-function: ease-in-out;
  animation-delay: calc(var(--lily-seq, 0) * .08s);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-vein-current-idle {
  animation-name: lily-l3-vein-ripple;
  animation-timing-function: ease-out;
  animation-delay: calc(var(--lily-seq, 0) * .11s);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-echo-idle--cyan {
  animation-name: lily-l3-echo-cyan;
  animation-timing-function: steps(1, end);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-echo-idle--violet {
  animation-name: lily-l3-echo-violet;
  animation-timing-function: steps(1, end);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-echo-idle--lilac {
  animation-name: lily-l3-echo-lilac;
  animation-timing-function: steps(1, end);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-shard-idle--late {
  animation-name: lily-l3-fracture-shard;
  animation-timing-function: steps(1, end);
  animation-delay: calc(var(--lily-seq, 0) * .016s);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-field-static,
.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-halo-static {
  animation-name: lily-l3-field-story;
  animation-timing-function: ease-in-out;
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-field-fracture--active {
  animation-name: lily-l3-arc-fracture;
  animation-timing-function: steps(1, end);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-field-flow {
  animation-name: lily-l3-field-ripple;
  animation-timing-function: ease-out;
  animation-delay: calc(var(--lily-seq, 0) * .12s);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-halo-flow {
  animation-name: lily-l3-halo-ripple;
  animation-timing-function: ease-out;
  animation-delay: calc(var(--lily-seq, 0) * .14s);
}

.v72-js .patch-teca.is-live.is-settled .living-lily--3 .lily-mark-signal-idle {
  animation-name: lily-l3-code-signal;
  animation-timing-function: steps(1, end);
}

/* --- la presenza -----------------------------------------------------

   Dopo che si e' posata, l'entita' non resta un disegno fermo: il cuore
   respira e gli anelli girano lentissimi. L'intensita' la porta una sola
   variabile, `--en`, che vale il numero di livello: piu' e' alto, piu' il
   respiro e' corto e la rotazione e' veloce. Un numero, non cinque
   animazioni diverse.

   E si ferma quando nessuno guarda. `animation-play-state` mette in pausa
   senza smontare niente, quindi al rientro riprende da dov'era invece di
   ricominciare. Non c'e' nessun timer e nessun listener di scroll: e' una
   classe che un osservatore mette e toglie. */
.v72-js .patch-teca.is-live.in-vista .cuore {
  animation: patch-respira calc(4.6s - var(--en, 1) * .42s) ease-in-out .5s infinite;
}

.v72-js .patch-teca.is-live.in-vista .anelli {
  animation: patch-gira calc(58s - var(--en, 1) * 5.6s) linear infinite;
  transform-origin: 50% 50%;
}

.v72-js .patch-teca:not(.in-vista) * {
  animation-play-state: paused !important;
}

@keyframes lily-core-ignite {
  from { opacity: 0; transform: scale(.12); }
  58%  { opacity: 1; transform: scale(1.13); }
  to   { opacity: 1; transform: none; }
}

@keyframes lily-petal-aura {
  from { opacity: 0; stroke-dashoffset: 1; }
  72%  { opacity: .28; }
  to   { stroke-dashoffset: 0; }
}

@keyframes lily-petal-build {
  from { opacity: 0; fill-opacity: 0; stroke-dashoffset: 1; transform: scale(.94); }
  44%  { opacity: .92; fill-opacity: .06; }
  72%  { opacity: 1; fill-opacity: .38; }
  to   { opacity: 1; stroke-dashoffset: 0; transform: none; }
}

@keyframes lily-input-arrive {
  from { opacity: 0; stroke-dashoffset: 1; }
  42%  { opacity: .72; }
  to   { stroke-dashoffset: 0; }
}

@keyframes lily-vein-reveal {
  from { opacity: 0; stroke-dashoffset: 1; }
  58%  { opacity: .86; }
  to   { stroke-dashoffset: 0; }
}

@keyframes lily-field-connect {
  from { opacity: 0; stroke-dashoffset: 1; }
  38%  { opacity: .16; }
  72%  { opacity: .48; }
  to   { stroke-dashoffset: 0; }
}

@keyframes lily-halo-connect {
  from { opacity: 0; stroke-dashoffset: 1; }
  48%  { opacity: .12; }
  to   { stroke-dashoffset: 0; }
}

@keyframes lily-node-acquire {
  from { opacity: 0; transform: scale(.2); }
  66%  { opacity: 1; transform: scale(1.45); }
  to   { transform: none; }
}

@keyframes lily-echo-break {
  from { opacity: 0; transform: none; }
  28%  { opacity: .18; transform: none; }
  40%  { opacity: .78; transform: translateX(var(--lily-glitch-x)); }
  48%  { opacity: .02; transform: translateX(var(--lily-glitch-back)); }
  58%  { opacity: .7; transform: translateX(var(--lily-glitch-x)); }
  67%  { opacity: .08; transform: translateX(var(--lily-glitch-back)); }
  82%  { opacity: .34; transform: translateX(.08px); }
  to   { transform: none; }
}

@keyframes lily-shard-expel {
  from { opacity: 0; transform: scale(.68); }
  42%  { opacity: .94; transform: translate(var(--lily-burst-x), var(--lily-burst-y)) scale(1.06); }
  55%  { opacity: .04; }
  68%  { opacity: .82; transform: translateX(.18px); }
  to   { transform: none; }
}

@keyframes lily-glyph-arrive {
  from { opacity: 0; transform: translateX(-1px); }
  52%  { opacity: .7; }
  to   { transform: none; }
}

@keyframes lily-code-discovered {
  from { opacity: 0; letter-spacing: 1.3px; }
  24%  { opacity: .12; }
  48%  { opacity: .96; letter-spacing: .72px; }
  68%  { opacity: .42; }
  to   { opacity: .2; letter-spacing: .58px; }
}

@keyframes lily-core-breathe {
  0%, 100% { opacity: .82; transform: scale(.965); }
  50%      { opacity: 1; transform: scale(1.055); }
}

/* 01 // LILY ---------------------------------------------------------
   Un unico impulso nasce nel nucleo, passa soltanto in tre vene e trova
   risposta in tre petali alterni. Il resto del ciclo e' vera quiete. */
@keyframes lily-l1-core-pulse {
  0%, 36%, 54%, 100% { opacity: 1; transform: none; }
  39%                 { opacity: 1; transform: scale(1.035); }
  42%                 { opacity: .92; transform: scale(.975); }
  45%                 { opacity: 1; transform: scale(1.145); }
  49%                 { opacity: .98; transform: scale(1.025); }
}

@keyframes lily-l1-vein-pulse {
  0%, 40%, 59%, 100% { opacity: 0; stroke-dashoffset: 0; }
  43%                 { opacity: .16; }
  48%                 { opacity: 1; stroke-dashoffset: -.38; }
  53%                 { opacity: .48; stroke-dashoffset: -.78; }
  58%                 { opacity: 0; stroke-dashoffset: -1.08; }
}

@keyframes lily-l1-petal-bloom {
  0%, 48%, 63%, 100% { opacity: .72; transform: none; }
  52%                 { opacity: .84; transform: scale(1.006); }
  56%                 { opacity: 1; transform: scale(1.025); }
  59%                 { opacity: .78; transform: scale(.995); }
}

/* 02 // GLITCH LILY --------------------------------------------------
   L'evento occupa circa 650ms del ciclo: perdita di fase, piccolo vuoto,
   risposta dei frammenti, impulso del nucleo e SNAP di ricomposizione. */
@keyframes lily-l2-core-snap {
  0%, 45%, 54%, 100% { opacity: 1; transform: none; }
  47%                 { opacity: .98; transform: scale(1.04); }
  49%                 { opacity: .84; transform: scale(.94); }
  51%                 { opacity: 1; transform: scale(1.14); }
  53%                 { opacity: 1; transform: scale(1.015); }
}

@keyframes lily-l2-petal-desync {
  0%, 42%, 54%, 100% { opacity: 1; transform: none; }
  44%                 { opacity: 1; transform: translateX(.2px); }
  46%                 { opacity: .94; transform: translateX(.72px); }
  48%                 { opacity: .86; transform: translateX(.42px); }
  50%                 { opacity: .9; transform: translateX(-.26px); }
  52%                 { opacity: 1; transform: translateX(.12px); }
  53%                 { opacity: 1; transform: scale(1.012); }
}

@keyframes lily-l2-outline-drop {
  0%, 45%, 54%, 100% { opacity: 1; }
  46%                 { opacity: .3; }
  47%                 { opacity: 0; }
  49%                 { opacity: .08; }
  51%                 { opacity: .72; }
  53%                 { opacity: 1; }
}

@keyframes lily-l2-vein-snap {
  0%, 45%, 54%, 100% { opacity: 0; stroke-dashoffset: 0; }
  47%                 { opacity: .24; }
  49%                 { opacity: 1; stroke-dashoffset: -.5; }
  52%                 { opacity: .38; stroke-dashoffset: -.9; }
  53.5%               { opacity: 0; stroke-dashoffset: -1.1; }
}

@keyframes lily-l2-echo-cyan {
  0%, 42%, 54%, 100% { opacity: 1; transform: none; }
  44%                 { opacity: .9; transform: translateX(-.36px); }
  46%                 { opacity: .76; transform: translateX(-1.05px); }
  47%                 { opacity: .14; transform: translateX(-.7px); }
  49%                 { opacity: .94; transform: translateX(.28px); }
  51%                 { opacity: .64; transform: translateX(-.15px); }
  53%                 { opacity: 1; transform: translateX(.04px); }
}

@keyframes lily-l2-echo-violet {
  0%, 42%, 54%, 100% { opacity: 0; transform: none; }
  44%                 { opacity: .22; transform: translateX(.3px); }
  46%                 { opacity: .86; transform: translateX(1.08px); }
  47%                 { opacity: .3; transform: translateX(.74px); }
  49%                 { opacity: .96; transform: translateX(-.32px); }
  51%                 { opacity: .52; transform: translateX(.18px); }
  53%                 { opacity: .08; transform: translateX(-.04px); }
}

@keyframes lily-l2-fragment-reaction {
  0%, 45%, 54%, 100% { opacity: 1; transform: none; }
  47%                 { opacity: .76; transform: translate(var(--lily-shard-x), var(--lily-shard-y)); }
  49%                 { opacity: .08; transform: translate(-.34px, .18px); }
  51%                 { opacity: .94; transform: translate(.18px, -.1px); }
  52.5%               { opacity: .46; transform: none; }
  53.5%               { opacity: 1; transform: none; }
}

/* 03 // 4072 BLOOM ---------------------------------------------------
   Tre capitoli distinti nello stesso ciclo di 18 secondi:
   A 10-31% signal ripple, B 43-55% fracture, C 70-83% codice 4072. */
@keyframes lily-l3-core-story {
  0%, 9%, 25%, 69%, 83%, 100% { opacity: 1; transform: none; }
  12%                          { opacity: 1; transform: scale(1.06); }
  15%                          { opacity: .9; transform: scale(.97); }
  18%                          { opacity: 1; transform: scale(1.16); }
  22%                          { opacity: 1; transform: scale(1.025); }
  73%                          { opacity: .9; transform: scale(.98); }
  76%                          { opacity: 1; transform: scale(1.11); }
  80%                          { opacity: 1; transform: scale(1.02); }
}

@keyframes lily-l3-vein-ripple {
  0%, 11%, 29%, 100% { opacity: 0; stroke-dashoffset: 0; }
  14%                 { opacity: .18; }
  18%                 { opacity: 1; stroke-dashoffset: -.38; }
  23%                 { opacity: .54; stroke-dashoffset: -.78; }
  28%                 { opacity: 0; stroke-dashoffset: -1.12; }
}

@keyframes lily-l3-petal-response {
  0%, 16%, 30%, 72%, 83%, 100% { opacity: .76; transform: none; }
  20%                           { opacity: .88; transform: scale(1.008); }
  24%                           { opacity: 1; transform: scale(1.026); }
  27%                           { opacity: .7; transform: scale(.996); }
  76%                           { opacity: .94; transform: scale(1.014); }
  79%                           { opacity: .64; transform: scale(.998); }
  81%                           { opacity: .84; transform: scale(1.006); }
}

@keyframes lily-l3-echo-cyan {
  0%, 18%, 33%, 42%, 56%, 69%, 84%, 100% { opacity: 1; transform: none; }
  22% { opacity: 1.08; transform: translateX(-.18px); }
  27% { opacity: .78; transform: translateX(.12px); }
  44% { opacity: .92; transform: translate(-.42px, .08px); }
  47% { opacity: .3; transform: translate(-1.18px, .18px); }
  49% { opacity: .08; transform: translate(-.72px, -.12px); }
  52% { opacity: .86; transform: translate(.24px, 0); }
  54% { opacity: 1; transform: translate(-.05px, 0); }
  74% { opacity: .58; transform: translateX(-.24px); }
  77% { opacity: 1.08; transform: translateX(.12px); }
  81% { opacity: .76; transform: none; }
}

@keyframes lily-l3-echo-violet {
  0%, 18%, 33%, 42%, 56%, 69%, 84%, 100% { opacity: 1; transform: none; }
  23% { opacity: 1.06; transform: translateX(.2px); }
  28% { opacity: .72; transform: translateX(-.1px); }
  44% { opacity: .88; transform: translate(.46px, -.08px); }
  47% { opacity: .34; transform: translate(1.22px, -.16px); }
  49% { opacity: .1; transform: translate(.76px, .14px); }
  52% { opacity: .9; transform: translate(-.26px, 0); }
  54% { opacity: 1; transform: translate(.05px, 0); }
  75% { opacity: .54; transform: translateX(.26px); }
  78% { opacity: 1.08; transform: translateX(-.12px); }
  81% { opacity: .72; transform: none; }
}

@keyframes lily-l3-echo-lilac {
  0%, 20%, 34%, 43%, 56%, 71%, 84%, 100% { opacity: 1; transform: none; }
  24% { opacity: .86; transform: translateY(-.16px); }
  29% { opacity: 1.04; transform: translateY(.08px); }
  46% { opacity: .52; transform: translate(-.34px, .28px); }
  49% { opacity: .06; transform: translate(.64px, -.2px); }
  52% { opacity: .82; transform: translate(-.18px, .08px); }
  54% { opacity: 1; transform: none; }
  76% { opacity: .46; transform: translateY(.2px); }
  79% { opacity: .94; transform: translateY(-.08px); }
  82% { opacity: 1; transform: none; }
}

@keyframes lily-l3-fracture-shard {
  0%, 43%, 56%, 100% { opacity: 1; transform: none; }
  45%                 { opacity: .72; transform: translate(var(--lily-shard-x), var(--lily-shard-y)); }
  48%                 { opacity: .06; transform: translate(var(--lily-shard-x), var(--lily-shard-y)); }
  50%                 { opacity: .9; transform: translate(-.28px, .16px); }
  52%                 { opacity: .3; transform: translate(.16px, -.1px); }
  54%                 { opacity: 1; transform: none; }
}

@keyframes lily-l3-field-story {
  0%, 42%, 56%, 69%, 84%, 100% { opacity: 1; }
  45%                           { opacity: .84; }
  48%                           { opacity: .48; }
  52%                           { opacity: .72; }
  54%                           { opacity: 1; }
  72%                           { opacity: .78; }
  75%                           { opacity: .46; }
  78%                           { opacity: .58; }
  82%                           { opacity: .94; }
}

@keyframes lily-l3-arc-fracture {
  0%, 44%, 55%, 100% { opacity: 1; }
  46%                 { opacity: .54; }
  48%                 { opacity: 0; }
  50%                 { opacity: .12; }
  52%                 { opacity: .72; }
  54%                 { opacity: 1; }
}

@keyframes lily-l3-field-ripple {
  0%, 10%, 32%, 72%, 83%, 100% { opacity: 0; stroke-dashoffset: 0; }
  14%                           { opacity: .12; }
  20%                           { opacity: .78; stroke-dashoffset: -.34; }
  25%                           { opacity: 1; stroke-dashoffset: -.68; }
  30%                           { opacity: 0; stroke-dashoffset: -1.12; }
  75%                           { opacity: .18; stroke-dashoffset: -.18; }
  78%                           { opacity: .46; stroke-dashoffset: -.46; }
  81%                           { opacity: 0; stroke-dashoffset: -.82; }
}

@keyframes lily-l3-halo-ripple {
  0%, 15%, 36%, 100% { opacity: 0; stroke-dashoffset: 0; }
  20%                 { opacity: .08; }
  25%                 { opacity: .62; stroke-dashoffset: .32; }
  30%                 { opacity: .88; stroke-dashoffset: .72; }
  35%                 { opacity: 0; stroke-dashoffset: 1.08; }
}

@keyframes lily-l3-code-signal {
  0%, 69%, 83%, 100% { opacity: 0; }
  72%                 { opacity: .12; }
  74%                 { opacity: .48; }
  75%                 { opacity: .96; }
  76%                 { opacity: .18; }
  77%                 { opacity: 1; }
  78%                 { opacity: .42; }
  80%                 { opacity: .88; }
  82%                 { opacity: 0; }
}

@keyframes patch-respira {
  0%, 100% { opacity: .84; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(calc(1 + var(--en, 1) * .018)); }
}

@keyframes patch-gira { to { transform: rotate(360deg); } }

@keyframes patch-apri {
  from { opacity: 0; transform: scale(.3) translateY(2px); }
  to   { opacity: 1; transform: none; }
}

@keyframes patch-batti {
  from { transform: scale(.74); }
  to   { transform: none; }
}

/* --- responsive ------------------------------------------------------
   Sotto i 720px la scheda diventa una colonna, e il riquadro della
   minaccia si affianca alla sua etichetta invece di occupare tutta la
   larghezza: una creatura larga quanto lo schermo, sopra ogni record,
   sposterebbe il testo troppo in basso. */
@media (max-width: 720px) {
  .patch-record {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(.9rem, 3vw, 1.3rem);
  }

  .patch-threat {
    flex-direction: row;
    align-items: center;
    gap: .9rem;
  }

  .patch-threat .patch-teca {
    width: 92px;
    flex: 0 0 92px;
  }

  .patch-fields > div {
    grid-template-columns: minmax(0, 1fr);
    gap: .15rem;
  }
}

@media (max-width: 420px) {
  .patch-threat .patch-teca { width: 76px; flex-basis: 76px; }
  .patch-head h3 { font-size: 1.18rem; }
}

/* --- meno movimento --------------------------------------------------
   Non "piu' lento": praticamente subito. Chi chiede meno movimento non
   sta chiedendo di aspettare di piu'. */
@media (prefers-reduced-motion: reduce) {
  .v72-js .patch-record [data-fase],
  .v72-js .patch-teca .schegge,
  .v72-js .patch-teca .bocciolo {
    opacity: 1;
    transform: none;
  }

  /* Tutto fermo, presenza compresa: chi chiede meno movimento non sta
     chiedendo un movimento piu' lento. */
  .v72-js .patch-teca *,
  .v72-js .patch-record.is-live [data-fase] {
    animation: none !important;
  }
}
