/* ============================================================================
   MLR Core — foglio di stile
   Tema "deep field": fondo quasi nero con nebule violetto/indaco.
   Il colore non è decorativo: ogni strato del motore ha una tinta propria e
   la firma del brand e' lo spettro che le attraversa (indigo -> viola -> cyan).
   ========================================================================== */

:root {
  /* fondo */
  --void:   #04040c;
  --deep:   #0a0820;
  --deeper: #06061a;

  /* spettro degli strati */
  --esd:    #f472b6;   /* magenta   — evoluzione / auto-rifinitura */
  --cbr:    #38bdf8;   /* azzurro   — instradamento per contenuto */
  --flow:   #34d399;   /* smeraldo  — gestione dei flussi */
  --ratio:  #fbbf24;   /* ambra     — bilanciamento / quote */

  /* firma del brand */
  --a1: #818cf8;        /* indigo */
  --a2: #c084fc;        /* violet */
  --a3: #22d3ee;        /* cyan */

  /* testo */
  --ink:      #f2f0fb;
  --ink-soft: #b9b5d4;
  --ink-dim:  #827da3;
  --ink-mute: #5a5678;

  /* superficie */
  --line:  rgba(160, 140, 255, 0.16);
  --line-2: rgba(160, 140, 255, 0.075);
  --glass:  rgba(28, 20, 58, 0.42);

  --accent: var(--a1);

  --r-sm: 8px;
  --r:    14px;
  --r-lg: 22px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  --maxw: 1180px;
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--void);
  color: var(--ink);
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* fondo globale: nebulose che pulsano lentamente attraverso lo spettro */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(64rem 42rem at 80% -6%,  rgba(129, 140, 248, 0.20), transparent 62%),
    radial-gradient(54rem 40rem at 6% 16%,    rgba(34, 211, 238, 0.13), transparent 60%),
    radial-gradient(50rem 34rem at 96% 62%,    rgba(192, 132, 252, 0.13), transparent 62%),
    radial-gradient(76rem 56rem at 50% 112%,  rgba(244, 114, 182, 0.10), transparent 66%),
    linear-gradient(180deg, var(--void), var(--deeper) 48%, var(--deep) 78%, var(--void));
  animation: nebula 34s ease-in-out infinite alternate;
}
@keyframes nebula {
  0%   { filter: hue-rotate(0deg)   saturate(1);    }
  100% { filter: hue-rotate(-28deg) saturate(1.18); }
}

/* griglia tecnica sottile, "engineering blueprint" */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(var(--line-2) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-2) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(90rem 60rem at 50% 30%, #000 25%, transparent 78%);
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }

h1, h2, h3, h4 { line-height: 1.12; margin: 0 0 0.5em; font-weight: 700; letter-spacing: -0.022em; }
p { margin: 0 0 1em; color: var(--ink-soft); }

.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 28px; }

.mono {
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
  font-size: 0.82em;
  letter-spacing: 0.02em;
}

.eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.72rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--a1);
  margin-bottom: 22px;
}
.eyebrow::before {
  content: ""; width: 26px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--a1));
}

.grad {
  background: linear-gradient(96deg, var(--a1), var(--a2) 46%, var(--a3));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}

/* ============================== NAV ============================== */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  display: flex; align-items: center; gap: 28px;
  padding: 16px 28px;
  transition: background .35s var(--ease), border-color .35s var(--ease), backdrop-filter .35s;
  border-bottom: 1px solid transparent;
}
.nav.scrolled {
  background: rgba(5, 7, 13, 0.72);
  backdrop-filter: blur(18px) saturate(150%);
  border-bottom-color: var(--line);
}
.nav .brand {
  font-weight: 800; letter-spacing: -0.03em; font-size: 1.06rem;
  display: flex; align-items: center; gap: 10px;
}
.nav .brand b { color: var(--a1); font-weight: 800; }
.nav .brand .dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--a1);
  box-shadow: 0 0 12px var(--a2), 0 0 30px rgba(192,132,252,.55);
  animation: breathe 3.4s ease-in-out infinite;
}
@keyframes breathe { 0%,100%{opacity:1; transform:scale(1)} 50%{opacity:.55; transform:scale(.82)} }

.nav .links { display: flex; gap: 26px; margin-left: auto; font-size: 0.9rem; }
.nav .links a { color: var(--ink-dim); transition: color .2s; }
.nav .links a:hover { color: var(--ink); }

/* La nav non ha piu' il badge "Rivolgiti a MLR Core": la stessa azione e'
   gia' nell'hero e nella sezione di contatto, e ripeterla tre volte costringeva
   la barra a stringersi sui link su schermi stretti. */
@media (max-width: 900px) { .nav .links { display: none; } }

/* ============================== HERO ============================== */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex; align-items: center;
  padding: 120px 0 70px;
  overflow: hidden;
}
#scene {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: 0;
  opacity: 0.92;
}
/* Vignettatura per far leggere il testo sopra il canvas.
   Su schermo largo la scena sta nella colonna destra (vedi layout() in
   scene.js), quindi la zona da schermare e' quella del testo: piu' larga e
   piu' a sinistra. Su schermo stretto la scena torna al centro e basta una
   velatura uniforme. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(5,4,16,.54), transparent 22%, transparent 62%, var(--void) 96%);
}
@media (min-aspect-ratio: 12/10) {
  .hero::after {
    background:
      linear-gradient(96deg, rgba(5,4,16,.92) 0%, rgba(5,4,16,.86) 26%, rgba(5,4,16,.42) 46%, transparent 62%),
      linear-gradient(180deg, rgba(5,4,16,.54), transparent 22%, transparent 62%, var(--void) 96%);
  }
}
.hero .wrap { position: relative; z-index: 2; }

.hero h1 {
  font-size: clamp(2.6rem, 6.6vw, 5.1rem);
  max-width: 20ch;
  margin-bottom: 26px;
}
.hero .lead {
  font-size: clamp(1.02rem, 1.9vw, 1.24rem);
  max-width: 56ch;
  color: var(--ink-soft);
  margin-bottom: 38px;
}
.hero .lead b { color: var(--ink); font-weight: 600; }

/* Il margin-bottom che c'era qui separava i pulsanti dal pannello di
   telemetria, che non c'e' piu': senza, l'hero si chiude con 150px di vuoto
   sotto l'ultimo bottone e il testo sembra affondare. */
.hero .actions { display: flex; flex-wrap: wrap; gap: 14px; }

.btn {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 13px 26px; border-radius: 999px;
  font-weight: 650; font-size: 0.94rem;
  border: 1px solid transparent;
  transition: transform .2s var(--ease), box-shadow .2s var(--ease),
              background-color .2s var(--ease), border-color .2s, color .2s;
  cursor: pointer;
}
/* Pulsanti senza sfondo a gradiente. Un gradiente a tre colori su un bottone
   fa concorrenza al testo e all'illustrazione: qui il colore unico dice "questa
   e' l'azione", il resto del sito resta libero di portare i tre colori dello
   spettro. Il colore resta pieno perche' il contrasto del testo scuro su
   indaco e' alto, e il bordo netto tiene la forma senza ombra colorata. */
.btn-primary {
  background: var(--a1);
  border-color: var(--a1);
  color: #08061a;
}
.btn-primary:hover {
  transform: translateY(-2px);
  background: #95a0fb;
  box-shadow: 0 12px 30px rgba(129,140,248,.28);
}
.btn-ghost { border-color: var(--line); color: var(--ink); background: rgba(255,255,255,.03); }
.btn-ghost:hover { border-color: var(--a1); transform: translateY(-2px); }

/* ============================== SEZIONI ============================== */
section { position: relative; padding: 120px 0; }
section.tight { padding: 84px 0; }

.sec-head { max-width: 62ch; margin-bottom: 62px; }
.sec-head h2 { font-size: clamp(2rem, 4vw, 3.05rem); }
.sec-head p { font-size: 1.05rem; }

.rule {
  height: 1px; border: 0; margin: 0;
  background: linear-gradient(90deg, transparent, var(--line), transparent);
}

/* ============================== GRIGLIA CARD ============================== */
.grid { display: grid; gap: 20px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

/* quattro strati: 2x2 esplicito, evita la card orfana che auto-fit
   lascerebbe su una riga tutta sua alle larghezze di desktop */
.grid-quad { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 820px) { .grid-quad { grid-template-columns: 1fr; } }

.card {
  position: relative;
  padding: 28px 26px 30px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: linear-gradient(165deg, rgba(30,22,62,.55), rgba(10,8,26,.34));
  backdrop-filter: blur(8px);
  overflow: hidden;
  transition: transform .35s var(--ease), border-color .35s, box-shadow .35s;
}
.card::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(28rem 16rem at 50% -30%, var(--tint, rgba(129,140,248,.20)), transparent 70%);
  opacity: 0; transition: opacity .35s var(--ease);
}
.card:hover {
  transform: translateY(-5px);
  border-color: rgba(129,140,248,.50);
  box-shadow: 0 20px 48px rgba(0,0,0,.42);
}
.card:hover::before { opacity: 1; }
.card > * { position: relative; }

.card .num {
  font-family: ui-monospace, Menlo, monospace;
  font-size: 0.7rem; letter-spacing: 0.16em;
  color: var(--ink-mute); margin-bottom: 14px;
}
.card h3 { font-size: 1.28rem; margin-bottom: 10px; }
.card p { font-size: 0.94rem; margin-bottom: 0; }

/* card con elenco di strati: le famiglie del motore */
.card-stack { display: flex; flex-direction: column; }
.card-stack .stack-lead {
  font-size: 0.94rem; color: var(--ink-dim); margin-bottom: 20px;
}
.stack {
  list-style: none; margin: 0; padding: 18px 0 0;
  border-top: 1px solid var(--line-2);
  display: flex; flex-direction: column; gap: 13px;
}
.stack li {
  position: relative;
  font-size: 0.86rem; line-height: 1.5; color: var(--ink-soft);
  padding-left: 18px;
}
.stack li::before {
  content: ''; position: absolute; left: 0; top: 0.52em;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--tint-border, var(--a1));
  box-shadow: 0 0 8px var(--tint-border, var(--a1));
}
.stack li b { color: var(--ink); font-weight: 600; }

.card .ico {
  width: 44px; height: 44px; border-radius: 12px;
  display: grid; place-items: center;
  margin-bottom: 18px;
  background: var(--tint-solid, rgba(129,140,248,.20));
  border: 1px solid var(--tint-border, rgba(129,140,248,.40));
}
.card .ico svg { width: 22px; height: 22px; }

/* ============================== PIPELINE ============================== */
.pipeline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
  margin-top: 8px;
}
.stage {
  position: relative;
  padding: 22px 18px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: rgba(24,18,52,.38);
}
.stage .tag {
  font-family: ui-monospace, Menlo, monospace;
  font-size: 0.66rem; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--ink-mute); margin-bottom: 9px;
}
.stage h3 { font-size: 1rem; margin-bottom: 6px; }
.stage p { font-size: 0.83rem; margin: 0; color: var(--ink-dim); }
.stage .bar {
  position: absolute; left: 0; right: 0; top: 0; height: 2px;
  border-radius: var(--r) var(--r) 0 0;
  background: linear-gradient(90deg, var(--tint, var(--a1)), transparent);
  overflow: hidden;
}
/* la luce che attraversa gli stadi in sequenza: fa leggere il percorso
   di una richiesta come traffico in movimento, non come elenco di caselle */
.stage .bar::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent 0%, #fff 50%, transparent 100%);
  opacity: 0; transform: translateX(-100%);
}
.stage.in .bar::after { animation: stageSweep 2.6s ease-in-out infinite; }
.stage:nth-child(1).in .bar::after { animation-delay: 0s; }
.stage:nth-child(2).in .bar::after { animation-delay: .34s; }
.stage:nth-child(3).in .bar::after { animation-delay: .68s; }
.stage:nth-child(4).in .bar::after { animation-delay: 1.02s; }
.stage:nth-child(5).in .bar::after { animation-delay: 1.36s; }

@keyframes stageSweep {
  0%   { opacity: 0;  transform: translateX(-100%); }
  22%  { opacity: .95; }
  60%  { opacity: .55; }
  100% { opacity: 0;  transform: translateX(100%); }
}
.stage.in { box-shadow: 0 0 0 1px var(--tint-border, transparent) inset; }

/* ============================== CODICE ============================== */
.code {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: rgba(6,5,20,.76);
  overflow: hidden;
}
.code .bar-top {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: rgba(30,22,62,.46);
  font-family: ui-monospace, Menlo, monospace;
  font-size: 0.74rem; color: var(--ink-dim);
}
.code .bar-top .d { width: 10px; height: 10px; border-radius: 50%; }
.code pre {
  margin: 0; padding: 20px 18px;
  overflow-x: auto;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.82rem; line-height: 1.75; color: var(--ink-soft);
}
.code .c { color: #5f7791; }  /* commento */
.code .s { color: var(--a2); }
.code .k { color: var(--violet); }
.code .n { color: var(--cyan); }
.code .f { color: var(--green); }

.copy-row { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.copy-btn {
  font-family: ui-monospace, Menlo, monospace;
  font-size: 0.75rem;
  padding: 8px 15px; border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: rgba(255,255,255,.03); color: var(--ink-soft);
  cursor: pointer; transition: all .2s var(--ease);
}
.copy-btn:hover { border-color: var(--a1); color: var(--ink); }
.copy-btn.ok { border-color: var(--green); color: var(--green); }

/* ============================== UPSTREAM STRIP ============================== */
.ups { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px; }
.up {
  padding: 20px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--tint, var(--a1));
  border-radius: var(--r-sm);
  background: rgba(10,31,61,.3);
  transition: transform .3s var(--ease), background .3s;
}
.up:hover { transform: translateX(4px); background: rgba(30,22,62,.50); }
.up .alias { font-weight: 700; color: var(--ink); margin-bottom: 4px; }
.up .model { font-family: ui-monospace, Menlo, monospace; font-size: 0.74rem; color: var(--tint, var(--a1)); }
.up .meta { font-size: 0.8rem; color: var(--ink-dim); margin-top: 9px; }

/* ============================== FEATURE LIST ============================== */
.checks { list-style: none; padding: 0; margin: 0; display: grid; gap: 13px; }
.checks li {
  display: flex; gap: 13px; align-items: flex-start;
  font-size: 0.96rem; color: var(--ink-soft);
}
.checks svg { flex: 0 0 auto; margin-top: 4px; color: var(--green); }

/* ============================== CTA ============================== */
.cta-box {
  text-align: center;
  padding: 76px 32px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background:
    radial-gradient(40rem 22rem at 50% -30%, rgba(129,140,248,.26), transparent 70%),
    linear-gradient(165deg, rgba(34,24,70,.62), rgba(10,8,26,.44));
}
.cta-box h2 { font-size: clamp(1.9rem, 4vw, 2.9rem); }
.cta-box p { max-width: 52ch; margin: 0 auto 34px; }

/* L'invito finale e' un'azione, quindi e' un pulsante come tutti gli altri del
   sito, non un testo con un colore diverso. */
.cta-box .mail {
  display: flex; flex-direction: column; align-items: center; gap: 16px;
}

/* ============================== FOOTER ============================== */
footer {
  padding: 54px 0 46px;
  border-top: 1px solid var(--line);
  font-size: 0.86rem; color: var(--ink-mute);
}
footer .cols {
  display: flex; flex-wrap: wrap; gap: 26px;
  align-items: center; justify-content: space-between;
}
footer .links { display: flex; gap: 22px; flex-wrap: wrap; }
footer a:hover { color: var(--a1); }
/* Crediti delle due societa': la sottolineatura dice "qui si puo' uscire dal
   sito", che il colore da solo non dice. Il tratto parte da --line e si
   accende di indaco al passaggio, cosi' la riga resta calma a riposo. */
footer .credit a {
  color: var(--ink-dim);
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-underline-offset: 4px;
  transition: color .2s, text-decoration-color .2s;
}
footer .credit a:hover { color: var(--a1); text-decoration-color: var(--a1); }
/* Riga delle informazioni legali. Sopra il filetto, non dentro le voci: sono
   link che si aprono e portano via dal sito, e non devono sembrare una voce
   di navigazione tra le altre. */
footer .legal-row {
  margin-top: 34px;
  padding-top: 22px;
  border-top: 1px solid var(--line-2);
}
footer .legal-links { display: flex; gap: 20px; flex-wrap: wrap; }
footer .legal-links a { color: var(--ink-mute); }
footer .legal-links a:hover { color: var(--a1); }

/* ============================== SCROLL REVEAL ============================== */
.reveal {
  opacity: 0; transform: translateY(26px);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
}
.reveal.in { opacity: 1; transform: none; }
.reveal.d1 { transition-delay: .08s; }
.reveal.d2 { transition-delay: .16s; }
.reveal.d3 { transition-delay: .24s; }
.reveal.d4 { transition-delay: .32s; }

/* ============================== RESPONSIVE ============================== */
@media (max-width: 900px) {
  /* Sotto i 900px non c'e' una colonna libera: la scena sta al centro e il
     testo le passa sopra. Una velatura non basta piu' — dietro al paragrafo
     il contrasto crolla e il testo diventa illeggibile. La scena scende
     quindi sotto al contenuto, dove non compete con nessuno. */
  #scene {
    top: auto; bottom: 0; height: 62%;
    opacity: 0.5;
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 34%);
    mask-image: linear-gradient(180deg, transparent, #000 34%);
  }
  .hero { position: relative; }
  .hero .wrap { position: relative; z-index: 2; }
  .hero::after { background: linear-gradient(180deg, rgba(5,4,16,.54), transparent 22%, transparent 48%, rgba(5,4,16,.72) 72%); }
}

@media (max-width: 720px) {
  .hero { padding-top: 100px; }
  section { padding: 80px 0; }
  .wrap { padding: 0 20px; }
  .card { padding: 22px 20px 24px; }
}

/* ============================== ACCESSIBILITA' ============================== */
:focus-visible {
  outline: 2px solid var(--a1);
  outline-offset: 3px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .nav .brand .dot { animation: none; }
  .stage.in .bar::after { animation: none; opacity: 0; }
  * { scroll-behavior: auto !important; }
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
/* ================== SCENA: TOPOLOGIA DELLE CONNESSIONI ================== */
.net-stage {
  position: relative;
  width: 100%;
  height: clamp(340px, 46vh, 520px);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background:
    radial-gradient(60% 80% at 50% 50%, rgba(129,140,248,.09), transparent 70%),
    linear-gradient(180deg, rgba(12,9,34,.55), rgba(4,4,12,.25));
  overflow: hidden;
}
.net-stage canvas { display: block; width: 100%; height: 100%; }
/* velo in alto: le didascalie stanno nella fascia alta del riquadro e le
   piste passano sotto. Il velo le stacca dal fondo senza spegnerle. */
.net-stage::before {
  content: "";
  position: absolute; inset: 0 0 auto 0; height: 46%;
  background: linear-gradient(180deg, rgba(5, 4, 16, .72), transparent);
  pointer-events: none;
  z-index: 1;
}

/* Le didascalie stanno DENTRO la grafica, sovrapposte al canvas e ancorate
   ai nodi: main.js proietta gli ancoraggi 3D sulla camera e le posiziona li'.
   Non e' piu' una riga allineata sotto la scena, perche' una riga dice "ecco
   quattro livelli in fila" mentre l'ordine dei livelli e' anche il loro ordine
   spaziale: le didascalie devono stare dove sta il pezzo che descrivono.

   Restano HTML e non sprite: nitide a ogni risoluzione, selezionabili e
   leggibili dagli screen reader. Il fondo ha un velo perche' passano sopra
   il canvas, e senza si perdono nel pulviscolo. */
.net-rail {
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 2;
}
.net-label {
  position: absolute; left: 0; top: 0;
  transform: translate(-50%, -50%);
  text-align: center;
  white-space: nowrap;
  opacity: 0;
  transition: opacity .6s ease;
  padding: 7px 12px;
  border-radius: 10px;
  background: rgba(6, 5, 20, .68);
  border: 1px solid var(--line-2);
  -webkit-backdrop-filter: blur(7px);
  backdrop-filter: blur(7px);
}
/* il filetto: una linea verticale che scende dalla didascalia al nodo piu'
   alto del suo livello. Senza, quattro didascalie allineate in fila sembrano
   quattro etichette di una legenda, non quattro pezzi della grafica. */
.net-label::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 100%;
  width: 1px;
  height: var(--lead, 0px);
  background: linear-gradient(180deg, var(--line), transparent);
  transform: translateX(-50%);
  pointer-events: none;
}
/* il core scrive SOTTO: il filetto sale dal bordo superiore invece di
   scendere da quello inferiore */
.net-label.nl-below::after {
  top: auto; bottom: 100%;
  background: linear-gradient(0deg, var(--line), transparent);
}
/* la rail diventa "ready" quando la proiezione ha posizionato le etichette:
   prima di quel momento restano invisibili per non lampeggiare al centro */
.net-rail.ready .net-label { opacity: 1; }
.net-label .nl-t {
  display: block;
  font-size: .84rem; font-weight: 600;
  color: var(--ink);
}
.net-label .nl-s {
  display: block;
  margin-top: 3px;
  font-family: ui-monospace, Menlo, monospace;
  font-size: .6rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-mute);
}
.net-label.nl-core .nl-t { font-size: 1.06rem; color: #fff; }
.net-label.nl-core .nl-s { color: var(--a1); }

/* Sotto gli schermi stretti i quattro nodi sono troppo vicini per ospitare
   quattro didascalie ai propri posti: si sovrapporrebbero e il risultato
   sarebbe illeggibile. Restano dentro la grafica, ma in fondo in fila
   nell'ordine della catena, che e' anche l'ordine da sinistra a destra. */
@media (max-width: 820px) {
  .net-rail {
    top: auto; height: auto;
    left: 10px; right: 10px; bottom: 10px;
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px;
  }
  .net-label {
    position: static; transform: none;
    white-space: normal; text-align: center;
    padding: 6px 4px;
  }
  .net-label .nl-t { font-size: .72rem; }
  .net-label.nl-core .nl-t { font-size: .82rem; }
  .net-label .nl-s { display: none; }
  /* il filetto non serve piu': in fila le didascalie non sono piu' ancorate al
     nodo, e il trattino resterebbe sospeso sopra ogni nome senza dire niente */
  .net-label::after { display: none; }
  /* La fascia alta e' quella delle didascalie, quindi il velo che le protegge
     sul desktop qui coprirebbe proprio la scena: via. E il riquadro si
     allunga, perche' i nodi devono stare SOPRA la riga dei nomi. */
  .net-stage::before { display: none; }
  .net-stage { height: clamp(320px, 46vh, 460px); }
}

/* legenda sotto la scena */
.net-legend {
  display: flex; flex-wrap: wrap; gap: 10px 26px;
  justify-content: center;
  margin-top: 26px;
  font-size: .82rem; color: var(--ink-dim);
}
.net-legend span { display: inline-flex; align-items: center; gap: 8px; }
.net-legend i {
  width: 22px; height: 2px; border-radius: 2px;
  background: var(--c, var(--a1));
  box-shadow: 0 0 10px var(--c, var(--a1));
}

/* ============================ AURORA DI SFONDO ============================ */
/* due lenti di colore che derivano lentamente: il fondo non resta mai fermo,
   senza aggiungere un peso di rendering (solo due gradienti sfocati) */
.aurora { overflow: hidden; }
.aurora::before {
  content: '';
  position: absolute; inset: -18% -12% auto -12%; height: 72%;
  pointer-events: none; z-index: 0;
  background:
    radial-gradient(48% 58% at 28% 42%, rgba(129,140,248,.15), transparent 70%),
    radial-gradient(42% 52% at 72% 32%, rgba(192,132,252,.13), transparent 70%),
    radial-gradient(38% 46% at 52% 72%, rgba(34,211,238,.08), transparent 72%);
  filter: blur(34px);
  animation: auroraDrift 19s ease-in-out infinite alternate;
}
.aurora > .wrap { position: relative; z-index: 1; }

@keyframes auroraDrift {
  from { transform: translate3d(-4%, -2%, 0) scale(1); }
  to   { transform: translate3d(5%, 7%, 0) scale(1.16); }
}
@media (prefers-reduced-motion: reduce) {
  .aurora::before { animation: none; }
}
