/* Computer · Componenti BEM condivisi.
   Shell (#app › sidebar + #content), intestazione, allarme, sidebar con menu, footer,
   pulsanti, superfici in vetro, avvisi.
   Base mobile; la cornice desktop sta in pagine/vetrina.css. */

/* ==========================================================================
   Shell
   ========================================================================== */
.stage {
  position: relative;
  isolation: isolate;
  height: var(--viewport-height, 100dvh);
  overflow: hidden;
  background: var(--color-screen);
}
.device { position: relative; width: 100%; height: 100%; }
.device__body { position: relative; width: 100%; height: 100%; background: var(--color-screen); }
.device__screen {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  overflow: hidden;
  /* LCARS è piatto: fondo nero pieno, niente aloni né vignettature. Le tinte sfumano quando scatta l'allarme rosso. */
  background: var(--color-screen);
  transition: --color-amber var(--dur-color) ease, --color-peach var(--dur-color) ease, --color-lilac var(--dur-color) ease, --color-blue var(--dur-color) ease;
}
.device__screen--alert {
  --color-amber: var(--color-alert-amber);
  --color-peach: var(--color-alert-peach);
  --color-lilac: var(--color-alert-lilac);
  --color-blue: var(--color-alert-blue);
}

.app {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  padding:
    max(var(--space-4), env(safe-area-inset-top))
    max(18px, env(safe-area-inset-right))
    max(9px, env(safe-area-inset-bottom))
    max(13px, env(safe-area-inset-left));
}

.app__body {
  position: relative;
  display: grid;
  flex: 1;
  grid-template-columns: var(--rail-width) minmax(0, 1fr);
  gap: 15px;
  min-height: 0;
  margin-top: 5px;
}
.content { position: relative; min-width: 0; min-height: 0; padding-top: 11px; overflow-x: clip; }   /* clip: il «wipe» non esce dal contenuto */

/* Pannello di una scheda: scorre da solo e sfuma in basso. */
.page {
  height: 100%;
  min-height: 0;
  padding: 0 1px 7px;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-mask-image: linear-gradient(var(--color-black) calc(100% - 12px), transparent);
  mask-image: linear-gradient(var(--color-black) calc(100% - 12px), transparent);
}
.page:not([hidden]) { contain: layout style; animation: page-in .38s var(--ease-out) both; }
/* Cambio di pagina (scripts/schede.js): la pagina entra di lato nella direzione di marcia e un blocco LCARS lilla
   attraversa il contenuto («wipe»). Piatto: colore pieno, niente sfumature. */
.content--cambio[data-verso="avanti"] .page:not([hidden]) { animation: page-avanti .42s var(--ease-out) both; }
.content--cambio[data-verso="indietro"] .page:not([hidden]) { animation: page-indietro .42s var(--ease-out) both; }
.content--cambio::after {
  content: "";
  position: absolute;
  z-index: 2;
  top: 0;
  bottom: 0;
  left: 0;
  width: 26%;
  border-radius: 14px 4px 14px 4px;
  background: var(--color-lilac);
  pointer-events: none;
  animation: wipe-avanti .42s var(--ease-out) both;
}
.content--cambio[data-verso="indietro"]::after { animation-name: wipe-indietro; }
@keyframes page-avanti { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: none; } }
@keyframes page-indietro { from { opacity: 0; transform: translateX(-28px); } to { opacity: 1; transform: none; } }
@keyframes wipe-avanti { from { transform: translateX(400%); opacity: .95; } to { transform: translateX(-110%); opacity: .95; } }
@keyframes wipe-indietro { from { transform: translateX(-110%); opacity: .95; } to { transform: translateX(400%); opacity: .95; } }

/* ==========================================================================
   Blocchi di pagina condivisi (COMPUTER, ISTRUZIONI…): gruppi con barra laterale, pulsanti, spia di stato,
   grafici SVG (scripts/grafici.js), micro card con dettaglio in console.
   ========================================================================== */
/* ---------- Blocco di pagina con gruppi ---------- */
.panel { padding: 0; }
/* Gruppi del blocco: barra laterale colorata sul lato destro (stato in ambra, dati in blu). */
.group { position: relative; padding-right: var(--space-3); }
.group + .group { margin-top: var(--space-3); }
.group::before { content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 3px; border-radius: 2px; background: var(--group-color, var(--color-amber)); }
.group--blu { --group-color: var(--color-chart-primary); }
.group--lilla { --group-color: var(--color-lilac); }

/* Interruttore LCARS: due segmenti uniti OFF | ON, quello attivo pieno. aria-pressed sul pulsante. */
.toggle {
  position: relative;
  display: flex;
  gap: 3px;
  padding: 0;
  border: 0;
  background: transparent;
  font: 600 var(--text-sm)/1 var(--font-display);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}
.toggle::before { content: ""; position: absolute; inset: calc(var(--hit-extend) * -1) 0; }   /* tocco a 44px */
.toggle > span { display: grid; place-items: center; min-width: 46px; height: 26px; padding: 0 var(--space-2); background: color-mix(in srgb, var(--color-lilac) 18%, var(--color-screen)); color: var(--color-lilac-soft); transition: background var(--dur-fast), color var(--dur-fast); }
.toggle__off { border-radius: 13px 2px 2px 13px; }
.toggle__on { border-radius: 2px 13px 13px 2px; }
.toggle[aria-pressed="false"] .toggle__off { background: var(--color-steel); color: var(--color-screen); }
.toggle[aria-pressed="true"] .toggle__on { background: var(--color-green); color: var(--color-screen); }
.panel__top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); margin-bottom: var(--space-1); }
.panel__top .signal { margin: 0; }
.panel__code { color: var(--color-faint); font: var(--text-2xs)/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; }
.panel__note { margin: var(--space-2) 0 0; color: var(--color-muted); font-size: var(--text-md); line-height: 1.4; }
.panel__actions { display: flex; gap: var(--space-1-5); margin-top: var(--space-3); }

/* ---------- Pulsanti ---------- */
.button {
  display: inline-flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  gap: var(--space-1-5);
  min-height: var(--control);
  padding: 0 var(--space-2);
  border: 0;
  border-radius: var(--radius-button);
  font: 600 calc(var(--text-lg) * var(--display-scale))/1 var(--font-display);
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: filter var(--dur-fast);
}
.button--amber { --btn-color: var(--color-amber); background: var(--color-amber); color: var(--color-on-amber); }
.button--lilac { --btn-color: var(--color-lilac); background: var(--color-lilac); color: var(--color-on-lilac); }
.button--peach { --btn-color: var(--color-peach); background: var(--color-peach); color: var(--color-on-amber); }
/* Spento (disabilitato o in attesa): comando LCARS non disponibile — fondo scuro, filo e scritta nel colore del pulsante,
   invece del colore pieno sbiadito dall'opacità (che diventava marrone o grigio). */
.button:disabled {
  opacity: 1;
  background: color-mix(in srgb, var(--btn-color, var(--color-line-2)) 9%, var(--color-screen));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--btn-color, var(--color-line-2)) 45%, transparent);
  color: color-mix(in srgb, var(--btn-color, var(--color-faint)) 65%, var(--color-faint));
}
.button--icon { flex: 0 0 var(--touch); padding: 0; }
.button[aria-busy="true"] .ico { animation: blink 1s steps(2, start) infinite; }
/* Conferma LCARS (scripts/conferma.js): il pulsante armato diventa un blocco rosso con la scritta CONFERMA, che lampeggia
   finché non arriva il secondo tocco o scade il tempo. */
.button--armato::after {
  content: "Conferma";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: inherit;
  background: var(--base-red);
  color: color-mix(in srgb, var(--base-red) 15%, var(--color-black));
  font: inherit;
  letter-spacing: inherit;
  text-transform: uppercase;
  animation: armed-blink .8s steps(2, jump-none) infinite;
}
@keyframes armed-blink { 50% { background: color-mix(in srgb, var(--base-red) 65%, var(--color-black)); } }
.button--icon.button--armato::after { content: "OK"; }   /* pulsante a sola icona: non c'è posto per la parola */

/* ---------- Spia di stato ---------- */
.signal { display: flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-2); }
/* Lampada spenta: anello vuoto ben visibile sul nero; accesa: piena con alone (stati qui sotto). */
.signal__lamp {
  flex-shrink: 0;
  width: 12px;
  height: 12px;
  border-radius: var(--radius-round);
  background: var(--color-screen);
  box-shadow: inset 0 0 0 2px var(--color-faint);
}
.signal__text { font: 600 calc(var(--text-lg) * var(--display-scale))/1 var(--font-display); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
/* Spie: in linea pulsano piano (respiro di 2,6 s), in errore più in fretta, in attesa lampeggiano. Colore pieno. */
.signal[data-stato="ok"] .signal__lamp { background: var(--color-blue); box-shadow: none; animation: lamp-on .7s var(--ease-out), lamp-breathe 2.6s .7s ease-in-out infinite; }
.signal[data-stato="ok"] .signal__text { color: var(--color-blue); }
.signal[data-stato="errore"] .signal__lamp { background: var(--base-red); box-shadow: none; animation: lamp-on .7s var(--ease-out), lamp-breathe 1.2s .7s ease-in-out infinite; }
.signal[data-stato="errore"] .signal__text { color: var(--color-alert-text); }
.signal[data-stato="attesa"] .signal__lamp { background: var(--color-amber); box-shadow: none; animation: blink 1s steps(2, start) infinite; }
.signal[data-stato="attesa"] .signal__text { color: var(--color-amber); }
@keyframes blink { to { visibility: hidden; } }

/* ---------- Letture (etichetta : valore) ---------- */

/* ---------- Grafici (scripts/grafici.js) ---------- */
.chart__track { fill: var(--color-chart-track); }
.chart__primary { fill: var(--color-chart-primary); }
.chart__primary--hi { fill: var(--color-chart-primary-hi); }
.chart__secondary { fill: var(--color-chart-secondary); }
.chart__critical { fill: var(--color-chart-critical); }
.chart__cut { fill: var(--color-screen); }
.chart__average { fill: var(--color-amber); }
.chart__track--dim { opacity: .45; }
/* Blocchetti LCARS con il nome (struttura delle istruzioni): pieni, scritta scura. */
.chart__block--uno { fill: var(--color-lilac); }
.chart__block--sub { fill: color-mix(in srgb, var(--color-lilac) 55%, var(--color-screen)); }
.chart__block--zero { fill: var(--color-steel); }
.chart__block-text { fill: var(--color-screen); font: 600 11px var(--font-display); letter-spacing: .07em; text-transform: uppercase; }   /* tacca della media (tempo di risposta) */
.chart__primary--sub { fill: color-mix(in srgb, var(--color-chart-primary) 60%, var(--color-chart-track)); }   /* sottosezioni */
.chart__label { fill: var(--color-text-2); font: 11px var(--font-mono); }   /* testo nei grafici: colori del testo, mai della serie */
.chart__label--muted { fill: var(--color-faint); }
/* Strumento a riposo (senza dati): forme in trasparenza e scritta «nessun dato». */
.chart__ghost { fill: var(--color-chart-track); opacity: .55; }
.chart__label--rest { fill: var(--color-faint); font: 600 10px var(--font-display); letter-spacing: var(--tracking-label); }
.chart__rest-plate { fill: var(--color-screen); stroke: var(--color-line-2); stroke-width: 1; }
.chart__label--north { fill: var(--color-amber); font: 600 10px var(--font-display); }
.chart__area { fill: color-mix(in srgb, var(--color-chart-primary) 18%, transparent); }
.chart__line { stroke: var(--color-chart-primary-hi); }
.chart__dot { fill: var(--color-amber); }
.chart__tick { stroke: var(--color-line-2); }
.chart__needle { fill: var(--color-amber); }
.chart__sun { fill: var(--color-amber); }
.chart__mark { stroke: var(--color-lilac); }
/* Barra del sole (drawSunStrip): livelli d'altezza del sole, quadratini attenuati tranne l'ora attuale. */
.chart__sol-1, .chart__sol-2, .chart__sol-3, .chart__sol-4 { opacity: .78; }
.chart__sol-0 { fill: var(--base-neutral-700); opacity: .7; }
.chart__sol-1 { fill: color-mix(in srgb, var(--color-amber) 45%, var(--base-neutral-900)); }
.chart__sol-2 { fill: var(--color-amber); }
.chart__sol-3 { fill: color-mix(in srgb, var(--color-amber) 40%, var(--color-yellow)); }
.chart__sol-4 { fill: var(--color-yellow); }
.chart__sol--now { opacity: 1; stroke: var(--color-ink); stroke-width: 1; }
.chart__sol-glow { fill: none; stroke: var(--color-yellow); stroke-width: 1.5; opacity: .8; }
   /* tacca sulle barre oltre la scala */
.chart__ring { stroke: var(--color-chart-track); }

/* ---------- Micro card: dato principale di un gruppo; il tocco scrive il dettaglio in console ---------- */
.micro-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-1-5); }
.micro-card {
  --card-color: var(--color-amber);
  position: relative;
  display: grid;
  gap: var(--space-0-5);
  min-width: 0;
  padding: var(--space-3) var(--space-1) var(--space-1);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  text-align: left;
}
.micro-card::before { content: ""; position: absolute; top: 0; right: 0; left: 0; height: 4px; border-radius: 2px 6px 6px 2px; background: var(--card-color); }
.micro-card--limiti { --card-color: var(--color-blue); }
.micro-card--registro { --card-color: var(--color-lilac); }
.micro-card__label { color: var(--card-color); font: 600 var(--text-sm)/1 var(--font-display); letter-spacing: var(--tracking-label); text-transform: uppercase; }
/* Codice dello strumento davanti al nome (MET—01…), come nei quadri. */
.instrument__label .gauge__code { margin-right: 5px; }
.micro-card__label .gauge__code { display: block; margin-bottom: 3px; }   /* colonne strette: il codice sopra il nome */
.micro-card__chart--cells { height: 10px; margin: var(--space-1) 0 var(--space-0-5); }
.micro-card__value { overflow: hidden; color: var(--color-ink); font: 600 calc(var(--text-2xl) * var(--display-scale))/1.15 var(--font-display); text-overflow: ellipsis; white-space: nowrap; }
.micro-card__chart { display: block; width: 100%; overflow: visible; }
.micro-card__gauge { position: relative; display: grid; place-items: center; justify-self: start; width: 48px; height: 48px; margin: var(--space-0-5) 0 0; }
.micro-card__ring { position: absolute; inset: 0; width: 100%; height: 100%; }
.micro-card__sub { overflow: hidden; color: var(--color-muted); font: var(--text-2xs)/1.2 var(--font-mono); text-overflow: ellipsis; white-space: nowrap; }
.micro-card--allarme .micro-card__value { color: var(--color-alert-text); }
.micro-card--allarme::before { background: var(--base-red); }
.micro-card--eco { animation: card-echo .5s var(--ease-out); }
@keyframes card-echo { from { background: color-mix(in srgb, var(--card-color) 16%, transparent); } }
@media (prefers-reduced-motion: reduce) {
  .signal[data-stato="attesa"] .signal__lamp, .button[aria-busy="true"] .ico, .micro-card--eco { animation: none; }
}

/* Riempimento fino al footer — regola per tutte le pagine (vedi CLAUDE.md).
   .fill: radice del contenuto di una sezione, alta almeno quanto l'area visibile.
   .fill__stretch: ogni contenitore fra la radice e l'elemento elastico (passa lo spazio in giù).
   .fill__grow: l'unico elemento elastico, di solito un grafico; base 0, cresce solo con lo spazio libero.
   Se il contenuto supera l'area, l'elastico scende al minimo (--fill-min) e la pagina scorre. */
.fill { display: flex; flex-direction: column; gap: var(--space-5); min-height: 100%; padding: var(--space-1) 0 var(--space-2); }
.fill__stretch { display: flex; flex: 1; flex-direction: column; }
.fill__grow { flex: 1 1 0; height: 0; min-height: var(--fill-min, 30px); }
@keyframes page-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ==========================================================================
   Accensione degli strumenti (scripts/accensione.js): uno dopo l'altro, --ordine × 70 ms
   ========================================================================== */
.page[data-accensione-attesa] [data-accensione] { opacity: 0; }   /* sezione non ancora accesa: strumenti spenti */
[data-accensione].acceso { animation: power-neon .46s linear both; animation-delay: calc(var(--ordine, 0) * 70ms); }
/* Sfarfallio da neon che si accende: due lampi, poi pieno. */
@keyframes power-neon {
  0% { opacity: 0; } 12% { opacity: .85; } 20% { opacity: .15; } 34% { opacity: .95; } 44% { opacity: .4; } 62%, 100% { opacity: 1; }
}
/* Card: la barretta colorata in testa si riempie da sinistra mentre il contenuto sfarfalla. */
[data-accensione="card"].acceso::before { animation: power-bar .46s var(--ease-out) both; animation-delay: calc(var(--ordine, 0) * 70ms); transform-origin: left; }
@keyframes power-bar { from { transform: scaleX(0); } }
/* Strumenti con la barretta in testa come bordo (Quota, GPS, Sole): la riga si accende da sinistra. */
[data-accensione="strumento"].acceso { animation-name: power-neon, power-top; }
@keyframes power-top { from { border-top-color: transparent; } }
/* Spia: la lampada si accende con un alone che si allarga e rientra. */
[data-accensione="spia"].acceso .signal__lamp { animation: lamp-on .46s var(--ease-out) both; animation-delay: calc(var(--ordine, 0) * 70ms); }

/* Spia che cambia stato (in linea, errore): lampada che si accende con l'alone, in ogni momento. */
@keyframes lamp-on { 0% { transform: scale(.4); } 45% { transform: scale(1.15); } 100% { transform: none; } }
@keyframes lamp-breathe { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* Lampo d'armamento: un comando appena diventato disponibile. */
.armato { animation: armed .7s var(--ease-out); }
@keyframes armed { 0%, 40% { filter: brightness(1.6); box-shadow: 0 0 0 0 var(--btn-color, var(--color-lilac)); } 100% { filter: none; box-shadow: 0 0 0 10px transparent; } }

/* Cambio sezione: le barre laterali dei gruppi si caricano dall'alto. */
.page:not([hidden]) .group::before { animation: group-charge .55s var(--ease-out) both; transform-origin: top; }
@keyframes group-charge { from { transform: scaleY(0); } }

/* Grafici che si accendono (grafici.js, opzione { accendi }): ogni forma ha il suo indice --n; --avvio è il ritardo
   rispetto a ora (negativo se il grafico viene ridisegnato a metà accensione, così riprende da dove era). */
.chart--accendi .chart__seq { animation-duration: .42s; animation-timing-function: var(--ease-out); animation-fill-mode: both; animation-delay: calc(var(--avvio, 0ms) + var(--n, 0) * var(--passo-grafico, 30ms)); }
.chart--accendi[data-effetto="crescita"] .chart__seq { animation-name: chart-grow-y; transform-box: fill-box; transform-origin: bottom; }
.chart--accendi[data-effetto="riempimento"] .chart__seq { --passo-grafico: 120ms; animation-name: chart-grow-x; transform-box: fill-box; transform-origin: left; }
.chart--accendi[data-effetto="righe"] .chart__seq { --passo-grafico: 45ms; animation-name: chart-grow-x; transform-box: fill-box; transform-origin: left; }
.chart--accendi[data-effetto="led"] .chart__seq { --passo-grafico: 22ms; animation-name: chart-led; animation-duration: .3s; }
.chart--accendi[data-effetto="traccia"] .chart__seq { animation-name: chart-trace; animation-duration: .7s; }
.chart--accendi[data-effetto="traccia"] .chart__area.chart__seq { animation-name: chart-fade; animation-delay: calc(var(--avvio, 0ms) + 400ms); }
.chart--accendi[data-effetto="traccia"] .chart__dot.chart__seq { animation-name: chart-pop; animation-delay: calc(var(--avvio, 0ms) + 600ms); transform-box: fill-box; transform-origin: center; }
.chart--accendi[data-effetto="ago"] .chart__seq { animation-name: chart-led; animation-duration: .3s; --passo-grafico: 35ms; }
.chart--accendi[data-effetto="ago"] .chart__needle-turn { animation: chart-needle .9s var(--ease-out) both; animation-delay: calc(var(--avvio, 0ms) + 250ms); transform-box: view-box; transform-origin: 22px 22px; }
.chart--accendi[data-effetto="crescita"] .chart__seq.chart__seq--led { --passo-grafico: 18ms; animation-name: chart-led; animation-duration: .3s; }
@keyframes chart-grow-y { from { transform: scaleY(0); } }
@keyframes chart-grow-x { from { transform: scaleX(0); } }
@keyframes chart-led { 0% { opacity: 0; } 40% { opacity: 1; filter: brightness(1.6); } 100% { opacity: 1; } }
@keyframes chart-trace { from { stroke-dashoffset: 1; } }
@keyframes chart-fade { from { opacity: 0; } }
@keyframes chart-pop { 0% { transform: scale(0); } 70% { transform: scale(1.6); } 100% { transform: none; } }
@keyframes chart-needle { from { transform: rotate(var(--ago-da, 0deg)); } }

/* ==========================================================================
   Intestazione
   ========================================================================== */
.app-header {
  /* Colore del gomito e della barra che ne parte. Gomito, curva interna e barra sono tre pezzi: leggono tutti questa
     sola variabile (registrata come colore, @property in tokens.css), così pressione, lampeggio e allarme li cambiano
     insieme, nello stesso istante, senza rettangoli di colore diverso. --elbow-base è il colore di riposo, cambiato
     dagli allarmi (scripts/allarmi.js); --elbow-color quello mostrato, che ne deriva. */
  --elbow-base: var(--color-amber);
  --elbow-color: var(--elbow-base);
  position: relative;
  transition: --elbow-color var(--dur-color);
  /* Geometria del gomito: spessore della barra in alto, raggio esterno, curva interna.
     La curva interna è un'ellisse proporzionata ai due spessori (23px verticale, 18px orizzontale). */
  --mast-height: 18px;
  --elbow-outer-radius: 28px;
  --elbow-inner-x: 14px;
  --elbow-inner-y: 10px;
  display: grid;
  flex-shrink: 0;
  grid-template-columns: var(--elbow-width) minmax(0, 1fr);
  grid-template-rows: var(--mast-height) 87px;
}
.app-header__elbow {
  position: relative;
  display: flex;
  grid-row: 1 / 3;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: var(--space-2);
  padding-top: 0;
  border: 0;
  border-radius: var(--elbow-outer-radius) 0 0 0;
  background: var(--elbow-color);
}
/* Curva interna: riempie l'angolo tra barra verticale e barra in alto. Il trasparente arriva fino al bordo
   dell'ellisse, così la curva si raccorda alle due barre senza gradini; lo sfondo vero resta visibile. */
.app-header__elbow::after {
  content: "";
  position: absolute;
  top: var(--mast-height);
  left: 100%;
  width: var(--elbow-inner-x);
  height: var(--elbow-inner-y);
  background: radial-gradient(var(--elbow-inner-x) var(--elbow-inner-y) at 100% 100%, transparent calc(100% - .75px), var(--elbow-color) 100%);
  pointer-events: none;
}
.app-header__number { color: var(--color-on-amber); font: 600 var(--text-md) var(--font-display); letter-spacing: .06em; }
.app-header__mast { display: flex; align-items: stretch; gap: var(--space-1); height: var(--mast-height); }
.app-header__brand { flex: 1; background: var(--elbow-color); }

/* Allarmi sul gomito. Critico: rosso pieno che lampeggia. Avviso: ambra chiaro che pulsa. Niente bagliori: colore pieno.
   Lampeggi, pressione e passaggio del mouse cambiano solo --elbow-color sulla testata (niente filter sui singoli pezzi). */
.app-header--critico { --elbow-base: var(--base-red); }
.app-header--avviso { --elbow-base: var(--color-console-avviso); }
/* Gomito e barra sono un comando unico (scripts/allarmi.js): si premono entrambi, al passaggio del mouse si schiariscono
   insieme e alla pressione si scuriscono insieme (niente rimpicciolimento: aprirebbe un vuoto fra i due pezzi).
   Niente menu del tocco lungo: la pressione lunga avvia la prova allarme. */
.app-header:has(#alert-elbow) .app-header__brand { cursor: pointer; }
.app-header__elbow, .app-header:has(#alert-elbow) .app-header__brand { -webkit-touch-callout: none; user-select: none; }
.app-header__elbow:active:not(:disabled) { transform: none; }
@media (hover: hover) {
  .app-header:not(.app-header--premuto):has(.app-header__elbow:hover, #alert-elbow ~ .app-header__mast .app-header__brand:hover) {
    --elbow-color: color-mix(in srgb, var(--elbow-base) 88%, var(--base-white));
  }
}
.app-header--premuto { --elbow-color: color-mix(in srgb, var(--elbow-base) 78%, var(--base-black)); transition-duration: 0s; }
/* Critico: stesso passo e stessa intensità delle barre che lampeggiano con l'allarme rosso (alert-bars, opacità .35). */
.app-header--critico { animation: elbow-critico 1.6s steps(2, jump-none) infinite; }
.app-header--avviso { animation: elbow-avviso 2.8s ease-in-out infinite; }
@keyframes elbow-critico { 50% { --elbow-color: color-mix(in srgb, var(--elbow-base) 35%, var(--color-screen)); } }
@keyframes elbow-avviso { 50% { --elbow-color: color-mix(in srgb, var(--elbow-base) 60%, var(--base-black)); } }
.app-header__block { width: 26px; background: var(--color-peach); }
/* Comandi rapidi nella barra lilla: icone piccole, area di tocco allargata verso il basso (pseudo-elemento). */
.app-header__tools { display: flex; align-items: stretch; justify-content: space-evenly; width: 54px; background: var(--color-lilac); }
.app-header__tool {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-on-lilac);
  font-size: 10px;
}
.app-header__tool::before { content: ""; position: absolute; top: -6px; right: -1px; bottom: -20px; left: -1px; }
.app-header__tool[aria-pressed="true"] { color: var(--color-white); }
.app-header__tool:focus-visible { outline-offset: 1px; }
.app-header__cap { width: 22px; border-radius: 0 10px 10px 0; background: var(--color-blue); }
/* La barretta azzurra apre il menu «Moduli»: icona piccola, area di tocco allargata verso il basso. */
.app-header__cap--menu {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 2px 0 0;
  border: 0;
  color: var(--color-on-blue-soft);
  font-size: 9px;
}
.app-header__cap--menu::before { content: ""; position: absolute; top: -6px; right: -6px; bottom: -20px; left: -4px; }
.app-header__cap--menu[aria-expanded="true"] { color: var(--color-white); }

/* ==========================================================================
   Menu «Sistemi» (#systems, includes/moduli.php)
   ========================================================================== */
/* Menu «Sistemi»: stessa colonna del menu «Stazioni», dallo stesso punto (è dentro la barra viola, includes/sidebar.php),
   con i colori azzurri. Il contenitore non ha misure: la colonna si posiziona sulla barra come quella di «Stazioni». */
.systems--open .rail__menu { width: var(--rail-menu-width); visibility: visible; transition: width .32s var(--ease-out), visibility 0s; }
.systems--open .rail__menu > * { opacity: 1; transition: opacity .2s .12s; }
.systems .rail__menu-title { background: var(--color-blue); color: var(--color-on-blue-soft); }
.systems .rail__list li .rail__item { --item-color: var(--color-blue); }
.systems .rail__list li:nth-child(4n + 2) .rail__item { --item-color: var(--color-steel); }
.systems .rail__list li:nth-child(4n + 3) .rail__item { --item-color: var(--color-green); }
.systems .rail__list li:nth-child(4n + 4) .rail__item { --item-color: var(--color-lilac); }
.systems .rail__item[aria-current="true"] { background: var(--color-amber); }
.systems .rail__fill { background: color-mix(in srgb, var(--color-blue) 30%, var(--color-screen)); }
.systems .rail__close { background: var(--color-blue); }
.app-header__heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2-5);
  min-width: 0;
  padding: 15px 0 var(--space-2) var(--space-3-5);
}
.app-header__copy { min-width: 0; }
.app-header__eyebrow {
  margin-bottom: var(--space-1-5);
  color: var(--color-muted);
  font: 600 var(--text-sm)/1.2 var(--font-display);
  letter-spacing: .13em;
  text-transform: uppercase;
}
/* Transizione LCARS del testo (scripts/transizione.js): la barra copre da sinistra, il testo cambia, la barra si ritira
   verso destra. Larga quanto il testo (fit-content) dove l'elemento è un blocco. */
.wipe { position: relative; }
.wipe::after {
  content: "";
  position: absolute;
  inset: 8% -3px;
  border-radius: 2px;
  background: var(--wipe-color, var(--color-lilac));
  transform: scaleX(0);
  pointer-events: none;
}
.wipe--copre::after { transform-origin: left; animation: wipe-copre .16s ease-in forwards; }
.wipe--scopre::after { transform-origin: right; animation: wipe-scopre .2s ease-out forwards; }
@keyframes wipe-copre { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes wipe-scopre { from { transform: scaleX(1); } to { transform: scaleX(0); } }
.app-header__title.wipe, .app-header__eyebrow.wipe { width: fit-content; }
.app-header__eyebrow { --wipe-color: var(--color-lilac); }
.app-header__title {
  --wipe-color: var(--color-amber);
  color: var(--color-amber);
  font: 600 calc(var(--text-title) * var(--display-scale))/1.05 var(--font-display);
  letter-spacing: -.01em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* ==========================================================================
   Strumento (.gauge): il linguaggio dei quadri. Testata «codice · nome · valore» (INT—01, DIM—02…), sotto il grafico.
   È un pulsante piatto: il tocco scrive il dettaglio in console.
   ========================================================================== */
.gauge {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 5px;
  width: 100%;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  text-align: left;
}
.gauge + .gauge { margin-top: var(--space-3); }
.gauge__head { display: flex; align-items: baseline; gap: var(--space-1-5); min-width: 0; }
.gauge__code { flex-shrink: 0; color: var(--color-faint); font: 600 var(--text-2xs)/1 var(--font-display); letter-spacing: .12em; }
.gauge__label { flex-shrink: 0; color: var(--color-lilac-soft); font: 600 var(--text-sm)/1 var(--font-display); letter-spacing: var(--tracking-label); text-transform: uppercase; }
.gauge__value { overflow: hidden; margin-left: auto; color: var(--color-ink); font: 600 var(--text-lg)/1 var(--font-display); letter-spacing: .03em; text-overflow: ellipsis; white-space: nowrap; }
.gauge__value--muted { color: var(--color-muted); font-size: var(--text-sm); }
.gauge--allarme .gauge__value { color: var(--color-alert-text); }
.gauge__big { color: var(--color-ink); font: 600 26px/1 var(--font-display); letter-spacing: .02em; }

.gauge__cells { display: block; width: 100%; height: 12px; overflow: visible; }
/* Strumenti a riposo con l'ultima misura nota (sensori spenti, scansione vecchia): valori in tenue, «ultima HH:MM». */
.strumenti--memoria :is(.gauge__big, .micro-card__value) { color: var(--color-faint); }
.gauge__sub { color: var(--color-muted); font: 600 var(--text-2xs)/1.1 var(--font-display); letter-spacing: .08em; text-transform: uppercase; }
.gauge__unit { margin-left: 3px; color: var(--color-muted); font-size: .5em; letter-spacing: .06em; }
.gauges-trio { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
.gauges-trio .gauge + .gauge { margin-top: 0; }

/* ==========================================================================
   Barra delle viste (.view-tabs) e monitor incassato (.monitor): componenti delle stazioni con più viste
   ========================================================================== */
.view-tabs { display: grid; grid-auto-columns: minmax(0, 1fr); grid-auto-flow: column; gap: 3px; margin-top: var(--space-2); }
.view-tab {
  position: relative;
  height: 26px;
  padding: 0 var(--space-2);
  border: 0;
  border-radius: 3px;
  background: color-mix(in srgb, var(--color-lilac) 16%, var(--color-screen));
  color: var(--color-lilac-soft);
  font: 600 var(--text-sm)/1 var(--font-display);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}
.view-tab::before { content: ""; position: absolute; inset: -9px 0; }   /* tocco a 44px */
.view-tab:first-child { border-radius: 13px 3px 3px 13px; }
.view-tab:last-child { border-radius: 3px 13px 13px 3px; }
.view-tab[aria-selected="true"] { background: var(--color-lilac); color: var(--color-on-lilac); }
/* Monitor incassato: cornice a parentesi come la console; il contenuto (SVG) lo riempie. */
.monitor {
  --fill-min: 140px;
  position: relative;
  margin-top: var(--space-2-5);
  overflow: hidden;
  border: solid var(--color-lilac);
  border-width: 4px 0 3px 7px;
  border-radius: 14px 0 0 12px;
  background: var(--color-console-bg);
}
.monitor__svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.monitor__label { fill: var(--color-lilac-soft); font: 600 11px var(--font-display); letter-spacing: .1em; text-transform: uppercase; }
.monitor__muted { fill: var(--color-faint); font: 600 11px var(--font-display); letter-spacing: .08em; text-transform: uppercase; }
.monitor__big { fill: var(--color-ink); font: 600 30px var(--font-display); }
.monitor__line { fill: none; stroke: var(--color-chart-primary-hi); stroke-width: 1.6; stroke-linejoin: round; }
.monitor__grid { fill: none; stroke: color-mix(in srgb, var(--color-lilac) 16%, transparent); stroke-width: 1; stroke-dasharray: 2 4; }
.monitor__axis { stroke: color-mix(in srgb, var(--color-lilac) 40%, transparent); stroke-width: 1; }
/* Sensore (accendi / spegni): pulsante LCARS con la lampada, come GPS in Territorio. */
.sensor-button { position: relative; display: flex; align-items: center; gap: 6px; }
.sensor-button__lamp { width: 8px; height: 8px; border-radius: 50%; background: currentColor; opacity: .45; }
.sensor-button[data-stato="attesa"] .sensor-button__lamp { opacity: 1; animation: lamp-breathe .8s ease-in-out infinite; }
.sensor-button[data-stato="ok"] { background: var(--color-green); color: var(--color-screen); }
.sensor-button[data-stato="ok"] .sensor-button__lamp { opacity: 1; }

/* ==========================================================================
   Sistema ON / OFF (scripts/sistema.js): tasto ⏻ a destra del titolo e standby in scala di grigi
   ========================================================================== */
.power-button {
  position: relative;
  display: grid;
  flex-shrink: 0;
  place-items: center;
  width: 46px;
  height: 46px;
  border: 0;
  border-radius: var(--radius-round);
  background: color-mix(in srgb, var(--color-amber) 16%, var(--color-screen));
  color: var(--color-amber);
  font-size: 22px;
  transition: background var(--dur-base), color var(--dur-base);
}
.power-button[aria-pressed="true"] { background: var(--color-amber); color: var(--color-on-amber); }
/* Testata compatta a sistema acceso: titolo più basso e ⏻ più piccolo, più spazio alla pagina. In standby e durante il
   rito d'accensione resta grande (scripts/sistema.js imposta data-sistema su #app). */
.app-header { transition: grid-template-rows .45s var(--ease-out); }
.app-header__title, .app-header__heading { transition: font-size .45s var(--ease-out), padding .45s var(--ease-out); }
.power-button { transition: background var(--dur-base), color var(--dur-base), width .45s var(--ease-out), height .45s var(--ease-out), font-size .45s var(--ease-out); }
.app[data-sistema="acceso"] .app-header { grid-template-rows: var(--mast-height) 62px; }
.app[data-sistema="acceso"] .app-header__heading { padding-top: var(--space-2); padding-bottom: var(--space-1-5); }
.app[data-sistema="acceso"] .app-header__eyebrow { margin-bottom: 3px; }
.app[data-sistema="acceso"] .app-header__title { font-size: calc(1.6rem * var(--display-scale)); }
.app[data-sistema="acceso"] .power-button { width: 36px; height: 36px; font-size: 18px; }
/* Spegnimento armato: rosso che lampeggia finché non si conferma o passa il tempo. */
.power-button.power-button--armato { background: var(--base-red); color: color-mix(in srgb, var(--base-red) 15%, var(--color-black)); animation: armed-blink .8s steps(2, jump-none) infinite; }
/* In standby il tasto respira piano: è l'unica cosa viva insieme al titolo. */
.app[data-sistema="standby"] .power-button { animation: lamp-breathe 2.6s ease-in-out infinite; }
.app:is([data-sistema="console"], [data-sistema="strumenti"]) .power-button { animation: armed-blink .8s steps(2, jump-none) infinite; }

/* Standby: tutto spento (grigio e scuro) tranne titolo e tasto. Si riaccende per gradi: console, strumenti, cornice. */
.app-header__elbow, .app-header__mast, .app-header__eyebrow, .content, .rail, .systems, .dock, .alert-banner {
  transition: filter .6s ease-out, opacity .6s ease-out;
}
.app[data-sistema]:not([data-sistema="acceso"]) :is(.app-header__elbow, .app-header__mast, .app-header__eyebrow, .rail, .dock__elbow, .dock__ribbon, .alert-banner),
.app[data-sistema]:not([data-sistema="acceso"], [data-sistema="strumenti"]) .content,
.app[data-sistema]:not([data-sistema="acceso"], [data-sistema="strumenti"], [data-sistema="console"]) :is(.console, .dock__controls) {
  filter: grayscale(1) brightness(.45);
}
.app[data-sistema]:not([data-sistema="acceso"], [data-sistema="strumenti"], [data-sistema="console"]) .content { opacity: .55; }
/* Prima della scelta (data-sistema="avvio", messo dal server) nessun passaggio animato. */
.app[data-sistema="avvio"] * { transition: none !important; }

/* ==========================================================================
   Pulsante a icona
   ========================================================================== */

@media (hover: hover) {
}

/* ==========================================================================
   Banner dell'allarme rosso
   ========================================================================== */
/* Blocco LCARS rosso pieno: «ALLARME ROSSO» grande, la causa sotto, «Ripristina» come pulsante scuro. Lampeggia piano. */
.alert-banner {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: var(--space-2);
  margin: 5px 0 var(--space-2) 25px;
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
  border-radius: 22px 4px 4px 22px;
  background: var(--base-red);
  color: color-mix(in srgb, var(--base-red) 15%, var(--color-black));
  animation: alert-block 1.6s steps(2, jump-none) infinite;
}
@keyframes alert-block { 50% { background: color-mix(in srgb, var(--base-red) 70%, var(--color-black)); } }
.alert-banner__icon { font-size: 22px; }
.alert-banner__text { flex: 1; min-width: 0; }
.alert-banner__title { display: block; font: 600 calc(var(--text-title) * .62 * var(--display-scale))/1 var(--font-display); letter-spacing: .06em; text-transform: uppercase; }
.alert-banner__sub { display: block; overflow: hidden; margin-top: 4px; font: 600 var(--text-xs)/1.2 var(--font-display); letter-spacing: .08em; text-overflow: ellipsis; text-transform: uppercase; white-space: nowrap; }
.alert-banner__button {
  min-height: var(--control);
  padding: 0 var(--space-2-5);
  border: 0;
  border-radius: 4px 14px 14px 4px;
  background: color-mix(in srgb, var(--base-red) 15%, var(--color-black));
  color: var(--base-red);
  font: 600 var(--text-md) var(--font-display);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}
/* Allarme rosso: le barre LCARS di tutta l'app lampeggiano insieme. */
.device__screen--alert :is(.app-header__block, .app-header__cap, .rail__block, .dock__elbow, .dock__ribbon-bar, .console__frame-bar, .console__frame-cap) {
  animation: alert-bars 1.6s steps(2, jump-none) infinite;
}
@keyframes alert-bars { 50% { opacity: .35; } }

/* ==========================================================================
   Sidebar: binario laterale che si apre in menu
   Chiusa è la barra di sempre; il clic sulla barra viola la allarga sopra il contenuto.
   ========================================================================== */
.rail {
  --rail-blocks: calc(34px + 67px + 22px + 3 * var(--space-1));   /* blocchetti sopra la barra viola, con i loro spazi */
  position: relative;
  z-index: var(--z-menu);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-height: 0;
}
.rail__block { display: block; flex-shrink: 0; }
.rail__block--peach { height: 34px; background: var(--color-peach); }
.rail__block--lilac { height: 67px; background: var(--color-lilac); }
.rail__block--steel { height: 22px; background: var(--color-steel); }
.rail__drawer { position: relative; flex: 1; min-height: 35px; }

/* Barra viola: è il pulsante del menu. L'area di tocco si estende nello spazio verso il contenuto (25px). */
.rail__toggle {
  position: absolute;
  inset: 0;
  width: 100%;
  padding: 0;
  border: 0;
  background: var(--color-plum);
  cursor: pointer;
}
.rail__toggle::after { content: ""; position: absolute; inset: 0 -15px 0 0; }
.rail__toggle:active:not(:disabled) { transform: none; }
.rail__toggle:focus-visible { outline-offset: 2px; }
/* Scritta verticale sulla barra viola chiusa, letta dal basso verso l'alto. */
.rail__label {
  position: absolute;
  bottom: var(--space-3-5);
  left: 0;
  width: var(--rail-width);
  color: var(--color-lilac-soft);
  font: 600 var(--text-2xs) var(--font-display);
  line-height: var(--rail-width);
  letter-spacing: .3em;
  text-transform: uppercase;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
}
/* Menu a colonna LCARS: alto quanto la barra viola, parte largo quanto lei e si allarga. Blocchi di colore pieno uniti
   da 3px di nero, scritte scure in maiuscolo con il codice: niente pannello galleggiante. Chiuso è invisibile e fuori dal
   focus (visibility). Parte dalla cima della barra, sopra i blocchetti colorati, così le stazioni ci stanno tutte;
   se lo spazio non basta ancora, l'elenco scorre. */
.rail__menu {
  position: absolute;
  top: calc(-1 * var(--rail-blocks));
  bottom: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: var(--rail-width);
  overflow: hidden;
  background: var(--color-screen);
  visibility: hidden;
  transition: width .32s var(--ease-out), visibility 0s linear .32s;
}
.rail--open #rail-menu { width: var(--rail-menu-width); visibility: visible; transition: width .32s var(--ease-out), visibility 0s; }
.rail__menu > * { opacity: 0; transition: opacity .15s; }
.rail--open #rail-menu > * { opacity: 1; transition: opacity .2s .12s; }
/* Con un menu aperto il contenuto si spegne: il menu è l'unica cosa da guardare. */
.app__body .content { transition: filter .3s; }
.app__body:has(.rail--open, .systems--open) .content { filter: brightness(.35) grayscale(.6); }

/* Testata: blocco lilla con il nome del menu, angolo esterno arrotondato. */
.rail__menu-title {
  flex-shrink: 0;
  padding: var(--space-2-5) var(--space-3) var(--space-2) var(--space-4);
  border-radius: 0 20px 0 0;
  background: var(--color-lilac);
  color: var(--color-on-lilac);
  font: 600 var(--text-lg)/1 var(--font-display);
  letter-spacing: var(--tracking-label);
  text-align: right;
  text-transform: uppercase;
  white-space: nowrap;
}
/* Le voci stanno sempre tutte nel menu: se manca altezza si accorciano insieme (da 46 a 36 px) e il riempimento scende
   al minimo; solo oltre (non succede con le sezioni di oggi) la lista scorre. */
.rail__list { display: flex; flex: 0 1 auto; flex-direction: column; gap: 3px; min-height: 0; margin: 0; padding: 0; overflow-y: auto; overscroll-behavior: contain; list-style: none; }
.rail__list > li { display: flex; flex: 0 1 46px; min-height: 36px; }
/* Voce: blocco pieno con codice, icona e nome a destra. I colori si alternano come nelle colonne della plancia;
   la sezione aperta è ambra con un segno nero a sinistra. */
.rail__item {
  --item-color: var(--color-peach);
  position: relative;
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) 20px;
  align-items: center;
  gap: var(--space-2);
  flex: 1;
  width: 100%;
  padding: 2px var(--space-3) 2px var(--space-4);
  border: 0;
  border-radius: 0;
  background: color-mix(in srgb, var(--item-color) 78%, var(--color-screen));
  color: var(--color-screen);
  text-align: left;
  white-space: nowrap;
}
.rail__list li:nth-child(4n + 2) .rail__item { --item-color: var(--color-lilac); }
.rail__list li:nth-child(4n + 3) .rail__item { --item-color: var(--color-blue); }
.rail__list li:nth-child(4n + 4) .rail__item { --item-color: var(--color-steel); }
.rail__item[aria-current="true"] { background: var(--color-amber); }
.rail__item[aria-current="true"]::before { content: ""; position: absolute; top: 9px; bottom: 9px; left: 0; width: 6px; background: var(--color-screen); }
.rail__item-code { font: 600 17px/1 var(--font-display); letter-spacing: .02em; }
.rail__item-text { display: grid; gap: 2px; min-width: 0; }
.rail__item-label { overflow: hidden; font: 600 var(--text-lg)/1 var(--font-display); letter-spacing: .08em; text-overflow: ellipsis; text-transform: uppercase; }
.rail__item-sub { overflow: hidden; font: 600 var(--text-2xs)/1.1 var(--font-display); letter-spacing: .06em; opacity: .7; text-overflow: ellipsis; text-transform: uppercase; }
.rail__item-icon { justify-self: center; font-size: 17px; opacity: .85; }
/* Ingresso a cascata: le voci arrivano una dopo l'altra, dal bordo da cui si apre il menu. */
:is(.rail--open #rail-menu, .systems--open) .rail__list li { --da: -14px; animation: menu-voce .28s var(--ease-out) backwards; }
:is(.rail--open #rail-menu, .systems--open) .rail__list li:nth-child(1) { animation-delay: .12s; }
:is(.rail--open #rail-menu, .systems--open) .rail__list li:nth-child(2) { animation-delay: .18s; }
:is(.rail--open #rail-menu, .systems--open) .rail__list li:nth-child(3) { animation-delay: .24s; }
:is(.rail--open #rail-menu, .systems--open) .rail__list li:nth-child(4) { animation-delay: .3s; }
:is(.rail--open #rail-menu, .systems--open) .rail__list li:nth-child(n + 5) { animation-delay: .36s; }
@keyframes menu-voce { from { opacity: 0; transform: translateX(var(--da)); } }
/* Riempimento: un blocco unico fino al fondo, con il codice del menu (quante sezioni ci sono). */
.rail__fill { display: flex; flex: 1 1 0; align-items: flex-end; justify-content: flex-end; min-height: 18px; padding: 0 var(--space-3) var(--space-1-5); background: color-mix(in srgb, var(--color-plum) 85%, var(--color-screen)); }
.rail__fill-code { color: color-mix(in srgb, var(--color-lilac-soft) 75%, transparent); font: 600 var(--text-2xs)/1 var(--font-display); letter-spacing: .14em; }
/* Fondo: «Chiudi» ed «Esci» come due blocchi; «Esci» rosso pesca; è un modulo POST con token CSRF. */
.rail__footer { display: flex; flex-shrink: 0; }
.rail__close {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  min-height: var(--control);
  padding: 0 var(--space-3);
  border: 0;
  border-radius: 0;
  background: var(--color-steel);
  color: var(--color-screen);
  font: 600 var(--text-sm) var(--font-display);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  white-space: nowrap;
}
.rail__footer > .rail__close { border-radius: 0 0 20px 0; }

/* Menu «Stazioni» (da destra): stessa colonna, speculare (angoli arrotondati e testi verso il bordo destro). */

/* ==========================================================================
   Footer dell'app, fisso in tutte le sezioni: console, comandi vocali, striscia di stato
   ========================================================================== */
.dock {
  display: grid;
  flex-shrink: 0;
  grid-template-columns: var(--rail-width) minmax(0, 1fr);
  gap: 15px;
  margin-top: var(--space-3-5);
}
.dock__elbow { border-radius: 0 0 0 var(--radius-md); background: var(--color-lilac); }
.dock__main { position: relative; min-width: 0; }

/* Console: riquadro nero sopra i comandi per le informazioni importanti, incorniciato in alto da una barra LCARS
   (barra lilla con codice e terminale azzurro). Piatto: niente bordo, vetro od ombre.
   Altezza fissa (scelta dell'utente): i contenuti scorrono all'interno senza spostare i comandi. */
.console {
  /* Colonne del testo (regola della console, in pixel perché il carattere è proporzionale): ora, esito, testo.
     Il testo degli eventi e i valori dei pannelli partono dalla stessa colonna (--console-testo). */
  --console-ora: 38px;
  --console-esito: 50px;
  --console-gap: 6px;
  --console-testo: calc(var(--console-ora) + var(--console-esito) + var(--console-gap) * 2);
  /* Schermo incassato: un secondo monitor montato sotto lo strumento. Cornice LCARS a parentesi (bordo spesso a
     sinistra che piega in alto e in basso: gli angoli arrotondati fanno da gomiti), fondo blu-nero proprio. */
  position: relative;
  display: flex;
  flex-direction: column;
  height: var(--console-height);
  margin-bottom: var(--space-2);
  padding: var(--space-1) 0 var(--space-1) var(--space-1-5);
  border: solid var(--color-lilac);
  border-width: 6px 0 3px 8px;
  border-radius: 16px 0 0 12px;
  background: var(--color-console-bg);
}
/* Sul bordo alto: il codice dello schermo (ritaglia il bordo) e il terminale azzurro. */
.console__frame { position: absolute; top: -6px; right: 0; display: flex; align-items: center; gap: 3px; height: 6px; }
.console__frame-bar { display: none; }
.console__frame-code { padding: 0 var(--space-1); background: var(--color-screen); color: var(--color-lilac-soft); font: 600 var(--text-3xs)/1 var(--font-display); letter-spacing: var(--tracking-label); }
.console__frame-cap { width: 22px; height: 100%; border-radius: 0 3px 3px 0; background: var(--color-blue); }
/* Chat: con il campo di testo aperto la sezione si nasconde e la console si allunga fino all'intestazione,
   così la conversazione resta visibile anche con la tastiera dell'iPhone aperta.
   Il passaggio è animato da scripts/comandi.js: la sezione si richiude in altezza e la console sale a prenderne il posto;
   .app--composer-closing tiene la console lunga mentre la sezione si riapre. */
:is(.app--composer-open, .app--composer-closing) .app__body { flex: 0 0 auto; height: 0; overflow: hidden; }
:is(.app--composer-open, .app--composer-closing) .dock { flex: 1; min-height: 0; }
:is(.app--composer-open, .app--composer-closing) .dock__main { display: flex; flex-direction: column; min-height: 0; }
:is(.app--composer-open, .app--composer-closing) .console { flex: 1; height: auto; min-height: 0; }

/* Testata fissa della chat, in cima alla console: stato del collegamento, modello, conversazione e sessione.
   Compare solo in modalità chat (campo di testo aperto); la conversazione scorre sotto. */
.chat-banner {
  display: none;
  flex-shrink: 0;
  gap: 2px;
  margin: 0 0 var(--space-1-5);
  padding: var(--space-1) var(--space-2-5) var(--space-1) var(--space-2);
  border-left: 6px solid var(--color-chart-primary);
  border-radius: 6px 0 0 6px;
  background: color-mix(in srgb, var(--color-chart-primary) 10%, var(--color-screen));
  font: 500 var(--text-md)/1.3 var(--font-display);
  letter-spacing: .03em;
}
:is(.app--composer-open, .app--composer-closing) .chat-banner { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--space-2-5); }
.chat-banner__row { grid-column: 1; }
/* Nuova conversazione: blocchetto azzurro a destra della testata; primo tocco arma (CONFERMA), secondo esegue. */
.chat-banner__new {
  position: relative;
  display: grid;
  grid-column: 2;
  grid-row: 1 / 4;
  align-self: center;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 4px 14px 14px 4px;
  background: var(--color-chart-primary);
  color: var(--color-on-blue-soft);
  font-size: 15px;
}
.chat-banner__new::before { content: ""; position: absolute; inset: -5px; }   /* tocco a 44px */
.chat-banner__new.button--armato::after { content: "OK"; position: absolute; inset: 0; display: grid; place-items: center; border-radius: inherit; background: var(--base-red); color: color-mix(in srgb, var(--base-red) 15%, var(--color-black)); font: 600 var(--text-sm) var(--font-display); letter-spacing: var(--tracking-label); animation: armed-blink .8s steps(2, jump-none) infinite; }
/* Console e chat sono due flussi separati nello stesso riquadro: chat visibile solo in modalità chat. */
.console__body--chat { display: none; }
:is(.app--composer-open, .app--composer-closing) .console__body--chat { display: block; }
:is(.app--composer-open, .app--composer-closing) #console-body { display: none; }
.chat-banner__row { display: flex; align-items: baseline; justify-content: space-between; gap: 1ch; margin: 0; white-space: nowrap; }
.chat-banner__state { display: inline-flex; align-items: center; gap: var(--space-1-5); color: var(--color-console-ok); font: 600 var(--text-base)/1 var(--font-display); letter-spacing: var(--tracking-label); text-transform: uppercase; }
.chat-banner__lamp { width: 7px; height: 7px; border-radius: var(--radius-round); background: currentColor; }
.chat-banner__state[data-stato="ok"] .chat-banner__lamp { animation: lamp-breathe 2.6s ease-in-out infinite; }
.chat-banner__state[data-stato="attesa"] { color: var(--color-console-avviso); }
.chat-banner__state[data-stato="attesa"] .chat-banner__lamp { animation: blink 1s steps(2, start) infinite; }
.chat-banner__state[data-stato="errore"] { color: var(--color-console-errore); }
.chat-banner__state[data-stato="ascolto"] { color: var(--color-lilac); }
.chat-banner__state[data-stato="ascolto"] .chat-banner__lamp { animation: blink 1s steps(2, start) infinite; }
.chat-banner__model { overflow: hidden; color: var(--color-console-tenue); text-overflow: ellipsis; }
.chat-banner__label { color: var(--color-console-etichetta); letter-spacing: .08em; text-transform: uppercase; }
.chat-banner__value { overflow: hidden; color: var(--color-console-numero); text-overflow: ellipsis; }
/* Testo dei display di bordo: carattere condensato (come i pannelli LCARS), righe a colori per tono (scripts/console.js),
   scritto riga per riga. Niente monospazio né cursore a blocco da terminale. */
.console__body {
  position: relative;   /* riferimento per offsetTop delle pagine */
  flex: 1;
  min-height: 0;
  padding-right: var(--space-1);
  overflow-y: auto;
  overscroll-behavior: contain;
  font: 400 var(--text-lg)/1.3 var(--font-display);
  letter-spacing: .025em;
}
/* Pagina: un gruppo di righe scritto dopo un'azione; parte dalla cima della console (scripts/console.js). */
.console__page { padding-top: var(--space-1); }
.console__spacer { flex-shrink: 0; }
.console__line, .console__head, .console__row, .console__event { min-height: 1.3em; margin: 0; overflow-wrap: break-word; white-space: pre-wrap; }
/* Evento: ora ed esito («›», «·» o blocchetto) in colonne fisse; il testo parte sempre da --console-testo, come i
   valori dei pannelli, e va a capo restando allineato a se stesso. */
.console__event { display: grid; grid-template-columns: calc(var(--console-testo) - var(--console-gap)) minmax(0, 1fr); column-gap: var(--console-gap); align-items: baseline; }
.console__event-head { display: grid; grid-template-columns: var(--console-ora) var(--console-esito); column-gap: var(--console-gap); align-items: baseline; white-space: nowrap; }
.console__event-head > :nth-child(2) { justify-self: start; }
.console__event-head > .console__cursor { display: none; }   /* il cursore non sposta le colonne mentre si scrive l'ora */
.console__event-head .console__tag { margin-right: 0; }
.console__event-line { min-height: 1.3em; }
/* Voci di elenco delle risposte: il segno sta in una casella larga fissa, così il rientro sospeso è esatto. */
.console__marker { display: inline-block; width: 1.1em; }
.console__marker--num { width: 1.7em; }
.console__indent { display: inline-block; }
.console__indent--1 { width: 1.1em; }
.console__indent--2 { width: 2.2em; }
.console__indent--3 { width: 3.3em; }
/* Battute della chat: un respiro fra una battuta e l'altra. */
.console__event + .console__event:has(.console__event-line) { margin-top: var(--space-2); }

/* Blocco di dettaglio: barra laterale nel colore della sezione, intestazione con filetto, righe in colonna. */
.console__block { --block-color: var(--color-console-titolo); margin: var(--space-1) 0; padding-left: 6px; border-left: 4px solid var(--block-color); border-radius: 2px; }   /* bordo + rientro = 10px, tolti dalla colonna delle etichette */
.console__block--blu { --block-color: var(--color-chart-primary); }
.console__block--lilla { --block-color: var(--color-lilac); }
.console__block--pesca { --block-color: var(--color-peach); }
/* Intestazione del pannello: titolo, barra LCARS piena (non più un filetto tratteggiato), meta a destra. */
.console__head { display: flex; align-items: center; gap: var(--console-gap); }
.console__head .console__seg--titolo { color: var(--block-color); }
.console__rule {
  flex: 1;
  height: 4px;
  min-width: 16px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--block-color) 45%, var(--color-screen));
  transform-origin: left;
  animation: rule-in .35s var(--ease-out) both;
}
@keyframes rule-in { from { transform: scaleX(0); } }
.console__row { display: grid; grid-template-columns: calc(var(--console-testo) - 10px) minmax(0, 1fr); }
.console__row--full { grid-template-columns: minmax(0, 1fr); }
.console__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Toni del testo (colori pieni, niente bagliori) */
.console__seg--testo { color: var(--color-console-testo); }
.console__seg--tenue { color: var(--color-console-tenue); }
.console__seg--prompt { color: var(--color-console-prompt); font-weight: 600; }
.console__seg--titolo { color: var(--color-console-titolo); font-weight: 600; letter-spacing: .12em; }
.console__seg--etichetta { color: var(--color-console-etichetta); text-transform: uppercase; letter-spacing: .06em; font-size: .9em; }
.console__seg--valore { color: var(--color-console-valore); }
.console__seg--numero { color: var(--color-console-numero); }
.console__seg--ok { color: var(--color-console-ok); }
.console__seg--avviso { color: var(--color-console-avviso); }
.console__seg--errore { color: var(--color-console-errore); }
.console__seg--accento { color: var(--color-console-accento); }

/* Blocchetti LCARS (esito, tipo di chiamata): rettangoli pieni, scritta scura in maiuscolo condensato. */
.console__tag {
  display: inline-block;
  min-width: 2.6em;
  margin-right: var(--console-gap);
  padding: 0 .35em;
  border-radius: 1px;
  background: var(--tag-color, var(--color-console-tenue));
  color: var(--color-screen);
  font-size: .8em;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: .08em;
  text-align: center;
  text-transform: uppercase;
  vertical-align: .08em;
}
.console__tag--ok { --tag-color: var(--color-console-ok); }
.console__tag--errore { --tag-color: var(--color-console-errore); }
.console__tag--avviso { --tag-color: var(--color-console-avviso); }
.console__tag--lilla { --tag-color: var(--color-lilac); }
.console__tag--acciaio { --tag-color: var(--color-steel); }

/* Quadratini: grafici a celle dentro il testo */
.console__squares { display: inline-flex; gap: 2px; margin-right: var(--console-gap); vertical-align: -.02em; }
.console__sq { display: block; width: 5px; height: 8px; border-radius: 1px; background: var(--color-chart-track); }
.console__sq--ok { background: var(--color-console-ok); }
.console__sq--blu { background: var(--color-chart-primary); }
.console__sq--ambra { background: var(--color-chart-secondary); }
.console__sq--avviso { background: var(--color-console-avviso); }
.console__sq--errore { background: var(--color-console-errore); }
.console__sq--lilla { background: var(--color-lilac); }

/* Punto di scrittura: una barretta sottile LCARS mentre il testo arriva; a riposo sparisce (niente cursore da terminale). */
.console__cursor {
  display: none;
  width: 3px;
  height: .9em;
  margin-left: 2px;
  border-radius: 1px;
  vertical-align: -.1em;
  background: var(--color-console-prompt);
}
.console__body--typing .console__cursor { display: inline-block; }

.dock__ribbon { display: flex; align-items: center; gap: var(--space-1); height: 13px; margin-top: 7px; }
.dock__ribbon-bar { display: block; width: 20px; height: 5px; background: var(--color-lilac); }
.dock__ribbon-bar--short { width: 9px; background: var(--color-peach); }
.dock__ribbon-bar--end { width: 23px; border-radius: 0 var(--radius-xs) var(--radius-xs) 0; background: var(--color-steel); }
.dock__status {
  --wipe-color: var(--color-steel);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  color: var(--color-text-3);
  font: 600 var(--text-2xs)/13px var(--font-display);
  letter-spacing: .12em;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Avviso temporaneo (notify): sulla striscia, in ambra, finché non torna lo stato. */
.dock__status--avviso { --wipe-color: var(--color-amber); color: var(--color-amber); }

/* ---------- Comandi vocali: pulsante «Parla al Computer», tastiera, campo di testo ---------- */
.dock__controls { display: flex; gap: 7px; }
/* Conferma di un ordine che scrive: blocco LCARS ambra sopra i comandi, riassunto e due tasti. */
.order-confirm { margin-bottom: var(--space-2); padding: var(--space-2) var(--space-2-5); border-left: 8px solid var(--color-amber); border-radius: 10px 4px 4px 10px; background: color-mix(in srgb, var(--color-amber) 12%, var(--color-screen)); }
.order-confirm__text { margin: 0 0 var(--space-2); color: var(--color-ink); font: 500 var(--text-xl)/1.3 var(--font-display); overflow-wrap: anywhere; }
.order-confirm__actions { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }

.talk-button {
  position: relative;
  isolation: isolate;
  display: flex;
  flex: 1;
  align-items: center;
  gap: var(--space-2-5);
  min-width: 0;
  min-height: var(--control-dock);
  padding: 0 11px;
  border: 0;
  border-radius: 18px 4px 4px 18px;
  background: var(--color-amber);
  color: var(--color-on-amber);
  text-align: left;
  transition: background var(--dur-base);
}
/* Occupato (elaborazione): azzurro pieno che pulsa piano; in ascolto lilla (sotto). Colore pieno, niente aloni. */
.app--busy .talk-button { background: var(--color-blue); animation: talk-pulse 1.3s ease-in-out infinite; }
@keyframes talk-pulse { 50% { filter: brightness(.82); } }
.talk-button__symbol { display: flex; align-items: center; justify-content: center; height: 24px; padding: 0 11px 0 1px; border-right: 1px solid var(--color-divider-amber); }
.talk-button__icon { font-size: 18px; }
.talk-button__copy { min-width: 0; }
.talk-button__title { display: block; font: 600 calc(var(--text-xl) * var(--display-scale))/1.2 var(--font-display); letter-spacing: .005em; }
.talk-button__pulse { display: flex; align-items: center; gap: var(--space-0-5); margin-left: auto; padding-left: var(--space-1); }
.talk-button__pulse-bar { width: 2px; height: 6px; border-radius: 2px; background: var(--color-on-amber-mute); animation: eq 1.4s ease-in-out infinite; }
.talk-button__pulse-bar:nth-child(2) { height: 13px; animation-delay: .18s; }
.talk-button__pulse-bar:nth-child(3) { height: 9px; animation-delay: .36s; }
.app--busy .talk-button__pulse-bar { background: var(--color-on-blue-soft); animation-duration: .6s; }
/* Comunicatore (scripts/chat.js): in ascolto lilla con le barre veloci, mentre la risposta viene letta di nuovo ambra.
   Il titolo mostra la frase riconosciuta mentre si parla: una riga sola, tagliata. */
.app--ascolto .talk-button { background: var(--color-lilac); color: var(--color-on-lilac); animation: talk-pulse 1s ease-in-out infinite; }
.app--ascolto .talk-button__pulse-bar { background: var(--color-on-lilac); animation-duration: .45s; }
.app--parla .talk-button__pulse-bar { animation-duration: .5s; }
.talk-button__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@keyframes eq { 0%, 100% { transform: scaleY(.65); } 50% { transform: scaleY(1.45); } }

.keyboard-button {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 44px;
  min-height: var(--control-dock);
  border: 0;
  border-radius: 4px 16px 16px 4px;
  background: var(--color-steel);
  color: var(--color-on-lilac);
  font-size: 17px;
}
.keyboard-button[aria-expanded="true"] { background: var(--color-lilac); }

/* Campo d'ingresso dati della chat: piatto, nero, incorniciato da blocchi LCARS ai lati. Si scrive con la tastiera di
   bordo sotto (.dock__keyboard), che porta anche il tasto d'invio. */
.composer {
  display: flex;
  flex: 1;
  align-items: stretch;
  gap: 3px;
  min-width: 0;
  min-height: var(--control-dock);
}
.composer::before { content: ""; flex: 0 0 14px; border-radius: 16px 0 0 16px; background: var(--color-lilac); }
.composer__input {
  flex: 1;
  min-width: 0;
  padding: 0 var(--space-2-5);
  border: 0;
  border-top: 2px solid var(--color-lilac);
  border-bottom: 2px solid var(--color-lilac);
  border-radius: 0;
  background: var(--color-screen);
  color: var(--color-ink);
  font: 500 var(--text-2xl) var(--font-display);
  letter-spacing: .02em;
}
.composer__input::placeholder { color: var(--color-placeholder); text-transform: uppercase; letter-spacing: var(--tracking-label); font-size: var(--text-lg); }
/* Il blocco e le linee del campo mostrano già il focus: si schiariscono. */
.composer__input:focus-visible { outline: none; border-color: var(--color-lilac-soft); }
.composer::after { content: ""; flex: 0 0 8px; border-radius: 0 4px 4px 0; background: var(--color-lilac); }
.dock__keyboard { margin-top: var(--space-2); }

/* ==========================================================================
   Elementi piccoli condivisi
   ========================================================================== */

/* Icone del set di bordo (assets/icons/computer.svg, icon() in functions.php): misura dal font-size del contenitore,
   colore dal testo. Allineate alla riga come un carattere. */
.ico { display: inline-block; flex-shrink: 0; width: 1em; height: 1em; overflow: visible; vertical-align: -.14em; }
.button .ico { font-size: 1.15em; }

/* Pulsanti compatti: 36px visibili, area di tocco portata a 44px da un pseudo-elemento invisibile
   (solo in verticale: ai lati i pulsanti vicini sono troppo stretti per allargarla senza sovrapporle). */
.alert-banner__button, .rail__close, .keyboard-button, .button { position: relative; }
.alert-banner__button::before, .rail__close::before, .talk-button::before,
.keyboard-button::before, .button::before {
  content: "";
  position: absolute;
  inset: calc(var(--hit-extend) * -1) 0;
}
/* Il pseudo-elemento parte dentro il bordo: dove c'è il bordo da 1px va compensato. */
.alert-banner__button::before { inset: calc((var(--hit-extend) + 1px) * -1) 0; }

/* ==========================================================================
   Adattamenti per iPhone 14 Pro e successivi, solo in verticale (393–440 × 852–956 px)
   ========================================================================== */
/* Safari con le barre visibili (app non installata): l'altezza utile scende sotto i 740px. */
@media (max-width: 699px) and (max-height: 740px) {
  .app { padding-top: max(var(--space-2-5), env(safe-area-inset-top)); }
  .app-header { --mast-height: 16px; grid-template-rows: var(--mast-height) 73px; }
  .app-header__heading { padding-top: 9px; }
  .app-header__eyebrow { margin-bottom: 5px; }
  .app-header__title { font-size: calc(2rem * var(--display-scale)); }
  .app[data-sistema="acceso"] .app-header { grid-template-rows: var(--mast-height) 54px; }
  .app[data-sistema="acceso"] .app-header__heading { padding-top: 6px; }
  .app[data-sistema="acceso"] .app-header__title { font-size: calc(1.45rem * var(--display-scale)); }
  .dock { margin-top: var(--space-2-5); }
  .console { --console-height: var(--console-height-compact); }
  .dock__ribbon { margin-top: var(--space-1); }
  /* Più spazio alla barra viola (e al menu che ne prende l'altezza): blocchetti sopra più bassi. */
  .rail { --rail-blocks: calc(24px + 40px + 16px + 3 * var(--space-1)); }
  .rail__block--peach { height: 24px; }
  .rail__block--lilac { height: 40px; }
  .rail__block--steel { height: 16px; }
  .rail__fill { min-height: 12px; }
  /* Stazioni (8 voci): solo il nome, così stanno tutte senza scorrere. */
  #rail-menu .rail__item-sub { display: none; }
  #rail-menu .rail__list > li { min-height: 30px; }
}
/* Tastiera aperta: l'area visibile si riduce, meno margine sopra il footer (la console resta: serve alla chat). */
@media (max-height: 600px) {
  .app--composer-open .dock { margin-top: var(--space-2); }
}

/* ==========================================================================
   Orizzontale non supportato: al posto dell'app, l'invito a ruotare l'iPhone
   ========================================================================== */
.rotate-hint { display: none; }
@media (orientation: landscape) and (pointer: coarse) {
  .stage > :not(.rotate-hint) { display: none; }
  .rotate-hint {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    height: 100%;
    padding: var(--space-4);
    color: var(--color-amber);
    font: 600 calc(var(--text-2xl) * var(--display-scale))/1.2 var(--font-display);
    letter-spacing: var(--tracking-label);
    text-align: center;
    text-transform: uppercase;
  }
  .rotate-hint__icon { color: var(--color-lilac); font-size: 2.5rem; transform: rotate(90deg); }
}
