/* ==========================================================================
   FARTEC — Demo della croce LED
   Due mondi affiancati: a sinistra la scena, che deve sembrare una croce vera
   accesa al crepuscolo; a destra i comandi, che devono sparire dietro a
   quello che fanno. Il fondo scuro non è una scelta di gusto — è l'ora in cui
   una croce si guarda davvero.
   ========================================================================== */

/* Le proporzioni della sagoma vengono dalla matrice reale: 96 LED di lato,
   angoli spenti da 32, cioè bracci larghi esattamente un terzo (33.333%).
   Tenerle qui in una variabile impedisce che il ritaglio in CSS e il disegno
   in JS divergano. */
.crossdemo {
  --arm: 33.3333%;
  --arm-end: 66.6667%;
  --led: #22e276;
  --led-soft: rgba(34, 226, 118, .55);
  --ui: #5c9dff;
  --ui-soft: rgba(10, 108, 255, .16);
  --scene-1: #0d1a13;
  --scene-2: #060b08;
  --panel-ink: #eaf5ee;
  --panel-dim: #9db3a6;
  --panel-line: rgba(255, 255, 255, .12);
  --panel-face: rgba(255, 255, 255, .05);

  display: grid;
  gap: 0;
  grid-template-columns: 1fr;
  min-height: 0;
  color: var(--panel-ink);
  border-radius: 18px;
  overflow: hidden;
  background: var(--scene-2);
}

/* Sopra i 820px scena e comandi stanno affiancati. La scena prende più spazio
   perché è lei il motivo per cui si apre la demo. min-height:0 su entrambe le
   colonne è ciò che permette al pannello di scorrere invece di sfondare il
   modale: senza, una griglia con molte pagine cresce oltre il max-height del
   contenitore e l'eccesso finisce sotto l'overflow:hidden, invisibile. */
@media (min-width: 820px) {
  .crossdemo { grid-template-columns: 1.15fr .85fr; }
}
.crossdemo > * { min-height: 0; min-width: 0; }

/* --------------------------------------------------------------- la scena */

.crossdemo-scene {
  position: relative;
  display: grid;
  place-items: center;
  padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 44px);
  background:
    radial-gradient(120% 90% at 50% 8%, var(--scene-1) 0%, var(--scene-2) 62%, #030504 100%);
  isolation: isolate;
}

/* Una texture di scanline appena percettibile: toglie al fondo la piattezza
   del gradiente puro e fa leggere la scena come una superficie, non come un
   riempimento. */
.crossdemo-scene::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, .18) 0 1px, transparent 1px 3px);
  mix-blend-mode: multiply;
  opacity: .5;
}

/* L'alone. È la cosa che si vede da lontano di una croce accesa: non un
   contorno, ma la luce che invade l'aria attorno. Respira più lentamente del
   simbolo, così i due movimenti non vanno a tempo e la scena non pulsa
   tutta insieme come un cuore. */
.crossdemo-halo {
  position: absolute;
  width: min(88%, 460px);
  aspect-ratio: 1;
  background: radial-gradient(circle, var(--led-soft) 0%, rgba(34, 226, 118, .12) 45%, transparent 68%);
  filter: blur(30px);
  animation: crossdemo-halo 5.2s ease-in-out infinite;
  z-index: 0;
}
@keyframes crossdemo-halo {
  0%, 100% { opacity: .62; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.05); }
}

/* Il cassonetto. Lo spessore è finto ma nasce da un dato vero: 125 mm di
   profondità su 1068 di lato, cioè poco più di un decimo — abbastanza da
   vedersi di taglio. Le ombre a gradini scure fanno il fianco estruso, quella
   morbida in fondo lo stacca dal muro, l'ultima è la luce che il pannello
   stesso getta attorno. */
.crossdemo-box {
  position: relative;
  z-index: 1;
  width: min(100%, 360px);
  aspect-ratio: 1;
  clip-path: polygon(
    var(--arm) 0, var(--arm-end) 0,
    var(--arm-end) var(--arm), 100% var(--arm),
    100% var(--arm-end), var(--arm-end) var(--arm-end),
    var(--arm-end) 100%, var(--arm) 100%,
    var(--arm) var(--arm-end), 0 var(--arm-end),
    0 var(--arm), var(--arm) var(--arm)
  );
  /* Il fianco è scuro e neutro, non verde: nelle riprese il cassonetto è un
     profilo di alluminio nero, e solo la faccia dei LED è verde. Le ombre
     verdi lo facevano sembrare un oggetto di plastica colorata. L'ultima
     ombra è la luce che il pannello getta attorno a sé, ampia perché su una
     croce vera arriva a tingere tutto il muro. */
  filter:
    drop-shadow(2px 2px 0 #14181a) drop-shadow(4px 4px 0 #0f1315)
    drop-shadow(6px 6px 0 #0a0e0f) drop-shadow(8px 9px 0 #070a0b)
    drop-shadow(14px 20px 22px rgba(0, 0, 0, .75))
    drop-shadow(0 0 60px rgba(34, 226, 118, .5));
}

/* Il canvas riempie il riquadro, senza misure proprie in pagina: la sua
   dimensione la decide il cassonetto, e il JS fissa solo la risoluzione del
   bitmap. È la condizione perché sagoma disegnata e sagoma ritagliata
   coincidano al pixel. */
.crossdemo-canvas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }

/* Il riflesso sul policarbonato. Diagonale, appena accennato: una lastra
   davanti ai LED prende sempre un po' di cielo. */
.crossdemo-gloss {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: .42;
  background: linear-gradient(128deg, rgba(255, 255, 255, .26) 0%, rgba(255, 255, 255, 0) 46%);
}

/* La luce che cade a terra sotto l'insegna. Senza, la croce galleggia. */
.crossdemo-floor {
  position: absolute;
  bottom: clamp(14px, 3vw, 30px);
  width: min(70%, 320px);
  height: 42px;
  background: radial-gradient(ellipse at center, rgba(34, 226, 118, .22), transparent 70%);
  filter: blur(12px);
  z-index: 0;
}

/* ------------------------------------------------------------- i comandi */

.crossdemo-panel {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: clamp(20px, 3vw, 30px);
  overflow-y: auto;
  background: #0b120e;
  border-left: 1px solid var(--panel-line);
  font-size: 16px;
}
@media (max-width: 819px) {
  .crossdemo {
    height: 100%;
    grid-template-rows: minmax(180px, 40vh) minmax(0, 1fr);
    grid-template-rows: minmax(180px, 40dvh) minmax(0, 1fr);
  }
  .crossdemo-scene { padding: clamp(14px, 3vh, 24px) clamp(16px, 4vw, 28px); }
  .crossdemo-box {
    width: min(100%, calc(40vh - 40px), 320px);
    width: min(100%, calc(40dvh - 40px), 320px);
  }
  .crossdemo-panel {
    min-height: 0;
    border-left: 0;
    border-top: 1px solid var(--panel-line);
  }
}

/* In landscape basso le colonne restano affiancate, ma il cassonetto non
   deve superare l'altezza utile del modale. */
@media (min-width: 820px) and (max-height: 600px) {
  .crossdemo-scene { padding: 16px; }
  .crossdemo-box {
    width: min(100%, 360px, calc(100vh - 190px));
    width: min(100%, 360px, calc(100dvh - 190px));
  }
}

.crossdemo-title {
  font-size: 16px; font-weight: 600; letter-spacing: -0.01em;
  color: var(--panel-ink);
}
.crossdemo-field { display: flex; flex-direction: column; gap: 7px; }
.crossdemo-label { font-size: 16px; color: var(--panel-dim); }
.crossdemo-note { font-size: 15px; color: var(--panel-dim); }

/* Il campo del nome è l'azione principale della demo: è più grande di tutto
   il resto e ha il colore dei LED, così si capisce dove si scrive prima di
   leggere l'etichetta. */
.crossdemo-name-input {
  font: inherit;
  font-size: 21px;
  font-weight: 600;
  letter-spacing: .01em;
  padding: 13px 15px;
  min-height: 52px;
  color: var(--led);
  background: #060a07;
  border: 1px solid rgba(34, 226, 118, .35);
  border-radius: 11px;
  transition: border-color .2s var(--ease, ease), box-shadow .2s var(--ease, ease);
}
.crossdemo-name-input::placeholder { color: rgba(157, 179, 166, .75); }
.crossdemo-name-input:focus {
  outline: none;
  border-color: var(--ui);
  box-shadow: 0 0 0 3px var(--ui-soft);
}

.crossdemo-input, .crossdemo-select {
  font: inherit; font-size: 16px;
  padding: 8px 10px; min-height: 40px;
  color: var(--panel-ink);
  background: var(--panel-face);
  border: 1px solid var(--panel-line);
  border-radius: 9px;
}
.crossdemo-select { cursor: pointer; }
.crossdemo-input:disabled { color: var(--panel-dim); }
.crossdemo-input:focus-visible, .crossdemo-select:focus-visible,
.crossdemo-page button:focus-visible, .crossdemo-range:focus-visible,
.crossdemo-add:focus-visible, .crossdemo-name-input:focus-visible {
  outline: 2px solid var(--ui); outline-offset: 2px;
}

.crossdemo-playback {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
}
.crossdemo-playback-status {
  min-width: 0;
  color: var(--panel-dim);
  font-size: 15px;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.crossdemo-playback-button {
  flex: 0 0 auto;
  min-height: 40px;
  padding: 8px 14px;
  border: 0;
  border-radius: 999px;
  color: #fff;
  background: #0a6cff;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color .2s cubic-bezier(.25, 1, .5, 1), transform .12s ease-out;
}
.crossdemo-playback-button:hover { background: #0a4da8; }
.crossdemo-playback-button:active { transform: scale(.96); }
.crossdemo-playback-button:focus-visible { outline: 2px solid var(--ui); outline-offset: 2px; }
.crossdemo-motion-note {
  margin: -4px 0 0;
  color: var(--panel-dim);
  font-size: 14px;
  line-height: 1.45;
}

/* Una pagina per riga, tenuta bassa: il palinsesto deve restare leggibile
   senza trasformare il pannello in un modulo da compilare. */
.crossdemo-pages { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.crossdemo-page {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 7px 8px;
  border: 1px solid var(--panel-line);
  border-radius: 10px;
  background: var(--panel-face);
  transition: background-color .2s cubic-bezier(.25, 1, .5, 1), border-color .2s cubic-bezier(.25, 1, .5, 1);
}
.crossdemo-page.is-active {
  border-color: rgba(92, 157, 255, .68);
  background: rgba(10, 108, 255, .14);
}
.crossdemo-page.is-off { background: transparent; border-style: dashed; }
.crossdemo-page.is-off .crossdemo-kind { color: var(--panel-dim); }
.crossdemo-page button {
  font: inherit; font-size: 16px;
  min-width: 40px; min-height: 40px;
  display: grid; place-items: center;
  cursor: pointer;
  color: var(--panel-ink);
  background: transparent;
  border: 1px solid var(--panel-line);
  border-radius: 8px;
  transition: background-color .15s ease, border-color .15s ease;
}
.crossdemo-page button:hover:not(:disabled) { background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .24); }
.crossdemo-page button:disabled { opacity: .4; cursor: not-allowed; }
/* Il pulsante di accensione porta il colore dei LED quando la pagina è in
   palinsesto; il blu resta riservato alla riga attualmente in anteprima. */
.crossdemo-toggle[aria-pressed="true"] { color: var(--led); border-color: rgba(34, 226, 118, .45); }
.crossdemo-preview { color: var(--panel-dim); }
.crossdemo-page.is-active .crossdemo-preview { color: var(--ui); border-color: rgba(92, 157, 255, .6); }

.crossdemo-kind { font-size: 15px; color: var(--panel-ink); min-width: 92px; }
.crossdemo-text { flex: 1 1 130px; min-width: 0; }
.crossdemo-auto { flex: 1 1 130px; font-size: 15px; color: var(--panel-dim); }
.crossdemo-sec { width: 62px; }
.crossdemo-secs { font-size: 15px; color: var(--panel-dim); }
.crossdemo-state {
  font-size: 14px; letter-spacing: .02em;
  color: var(--panel-dim);
  border: 1px solid var(--panel-line); border-radius: 999px;
  padding: 2px 9px;
}

.crossdemo-add {
  font: inherit; font-size: 16px;
  align-self: flex-start;
  padding: 9px 15px; min-height: 44px;
  color: var(--panel-ink);
  background: transparent;
  border: 1px dashed var(--panel-line);
  border-radius: 10px;
  cursor: pointer;
}
.crossdemo-add:hover:not(:disabled) { border-color: var(--ui); color: var(--ui); }
.crossdemo-add:disabled { opacity: .45; cursor: not-allowed; }

/* Il cursore giorno/notte: la traccia è il cielo che attraversa. */
.crossdemo-range {
  width: 100%; min-height: 40px;
  accent-color: var(--ui);
  background: transparent;
}
.crossdemo-daynight {
  display: flex; justify-content: space-between;
  font-size: 14px; color: var(--panel-dim);
}

/* Regione live per lo screen reader (vedi notify() in cross-demo.js): nascosta
   solo agli occhi. Niente display:none o visibility:hidden, che la
   toglierebbero anche dall'albero di accessibilità e vanificherebbero
   l'annuncio; il ritaglio a 1px con clip resta lo standard per questo scopo. */
.crossdemo-sr-live {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Sui dispositivi che si toccano i bersagli tornano a 44px: 40 basta al
   puntatore, non al pollice. */
@media (pointer: coarse) {
  .crossdemo-page button { min-width: 44px; min-height: 44px; }
  .crossdemo-input, .crossdemo-select { min-height: 44px; }
  .crossdemo-playback-button { min-height: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  .crossdemo *, .crossdemo *::before, .crossdemo *::after {
    transition: none !important; animation: none !important;
  }
  .crossdemo-halo { opacity: .8; transform: none; }
}
