/* =====================================================================
   Olidata - tema "polvere di stelle" per il portale Authelia   [v6]
   ---------------------------------------------------------------------
   Perche' nella v5 le stelle non si vedevano, e cosa e' cambiato:

     * erano singoli pixel con alpha fra 38 e 105 su 255 - fra il 15% e il
       40% di opacita' - poi ancora moltiplicati per l'opacita' del
       livello. Su un fondo #070B14 non emergevano. Ora ogni stella e' una
       gaussiana di almeno un pixel e mezzo, con alpha molto piu' alte.

     * un punto di un pixel, su uno schermo ad alta densita', non resta un
       punto: il browser lo ingrandisce e lo sfoca, spalmandone la luce.
       Per questo le texture sono disegnate al DOPPIO della misura logica e
       qui vengono rimpicciolite con background-size. Su un display 2x il
       disegno e' nitido pixel per pixel; su un display 1x viene ridotto, e
       ridurre conserva la luminosita' mentre ingrandire la disperde.

     * la densita' e' salita molto: circa 4.500 punti di polvere su una
       finestra da 1920x1080. "Non troppo invadente" si ottiene con tante
       stelle piccole di luminosita' media, non con poche stelle tenui -
       quelle diventano solo invisibili.

   Quattro piani, dal fondo verso l'osservatore, piu' due meteoriti:

     0  html::before   nebulosa tenue e banda della Via Lattea  deriva 260s
     1  body::before   il campo di polvere, piano lontano       deriva 170s
     2  body::after    stelle medie con alone                   deriva 100s
     3  html::after    stelle vive, alone e diffrazione         deriva  58s
     -  #root::before  primo meteorite, 4 traiettorie           ogni  5s
     -  #root::after   secondo meteorite, 3 traiettorie         ogni 11s

   5 e 11, non 5 e 10: dieci sarebbe il doppio di cinque, i due si
   sincronizzerebbero e a ogni secondo giro passerebbero in coppia. Con
   undici coincidono una volta ogni 55 secondi.

   A questa frequenza il rischio non e' la luminosita', e' la RIPETIZIONE:
   la stessa scia identica ogni cinque secondi si nota subito. Per questo
   ogni meteorite contiene PIU' PASSAGGI con traiettoria diversa dentro un
   ciclo piu' lungo - quattro passaggi in 20s e tre in 33s. La frequenza
   apparente e' quella voluta, ma il disegno si ripete molto piu' di rado.

   Regola che tiene tutto fluido: si animano SOLTANTO 'transform' e
   'opacity', su livelli promossi - le due proprieta' che il compositore
   muove da se' senza ridisegnare. Le stelle e i loro aloni sono dipinti
   una volta sola in tre texture da 86 KB in tutto, poi solo traslati.
   Le texture sono servite da nginx come file e non incorporate qui: in
   data URI portavano il foglio a 127 KB, e con la cache breve del foglio
   sarebbero state riscaricate ad ogni scadenza. Come file hanno cache di
   30 giorni e il foglio resta leggero.

   Nessun JavaScript, per scelta: su un portale di autenticazione un foglio
   di stile non puo' leggere il campo password, uno script si'.
   ===================================================================== */

:root {
  --oli-teal:   #248CA8;
  --oli-verde:  #82BB25;
  --oli-slate:  #4E6E87;
  --oli-arancio:#E74310;
  --vuoto:      #070B14;
  --luce:       #E8EEF7;
  --luce-tenue: #9FB2C9;
}

html { background: var(--vuoto) !important; }
body { background: transparent !important; color: var(--luce) !important; }

/* ============ piano 0: nebulosa e banda della Via Lattea ============ */
html::before {
  content: ""; position: fixed; inset: -6%; z-index: 0; pointer-events: none;
  background:
    linear-gradient(112deg, transparent 32%, rgba(178,198,235,.042) 44%,
      rgba(214,228,252,.07) 50%, rgba(178,198,235,.038) 56%, transparent 68%),
    radial-gradient(38% 30% at 20% 16%, rgba(36,140,168,.16), transparent 70%),
    radial-gradient(32% 26% at 84% 24%, rgba(78,110,135,.14), transparent 70%),
    radial-gradient(46% 34% at 66% 84%, rgba(58,44,104,.22),  transparent 72%),
    radial-gradient(26% 22% at 10% 76%, rgba(231,67,16,.055), transparent 72%);
  will-change: transform;
  animation: oli-nebulosa 260s ease-in-out infinite alternate;
}
@keyframes oli-nebulosa {
  from { transform: translate3d(-1.3%,-.8%,0); }
  to   { transform: translate3d(1.3%,.8%,0); }
}

/* ======= piano 1: il campo di polvere di stelle, in tutto il tema ==== */
/* Texture da 600px disegnati, rimpiccioliti a 300: e' il rapporto 2:1 che
   la rende nitida sugli schermi ad alta densita'. Piena opacita': nella
   v5 c'era uno 0.85 di troppo che le smorzava ulteriormente.          */
body::before {
  content: ""; position: fixed; inset: -90px; z-index: 1; pointer-events: none;
  background-image: url("/authelia-brand/img/polvere.png");
  background-repeat: repeat; background-size: 300px 300px;
  will-change: transform;
  animation: oli-piano-lontano 170s ease-in-out infinite alternate;
}
@keyframes oli-piano-lontano {
  from { transform: translate3d(-16px,-11px,0); }
  to   { transform: translate3d(16px,11px,0); }
}

/* ============== piano 2: stelle medie, con accenno di alone ========== */
body::after {
  content: ""; position: fixed; inset: -90px; z-index: 2; pointer-events: none;
  background-image: url("/authelia-brand/img/medie.png");
  background-repeat: repeat; background-size: 450px 450px;
  will-change: transform;
  animation: oli-piano-medio 100s ease-in-out infinite alternate;
}
@keyframes oli-piano-medio {
  from { transform: translate3d(-34px,20px,0); }
  to   { transform: translate3d(34px,-20px,0); }
}

/* ==== piano 3: le stelle vive, le piu' vicine e le piu' mobili ======= */
/* Lo scintillio scende solo a 0.82, non a 0.66 come nella v5: in quel
   modo smorzava tutto il cielo per meta' del tempo.                   */
html::after {
  content: ""; position: fixed; inset: -90px; z-index: 3; pointer-events: none;
  background-image: url("/authelia-brand/img/vive.png");
  background-repeat: repeat; background-size: 620px 620px;
  will-change: transform, opacity;
  animation: oli-piano-vicino 58s ease-in-out infinite alternate,
             oli-scintillio 7s ease-in-out infinite alternate;
}
@keyframes oli-piano-vicino {
  from { transform: translate3d(-64px,-40px,0); }
  to   { transform: translate3d(64px,40px,0); }
}
@keyframes oli-scintillio {
  from { opacity: .82; } to { opacity: 1; }
}

/* il contenuto di Authelia sta davanti a tutti i piani del cielo */
#root { position: relative; z-index: 4; }

/* ========================== i due meteoriti ========================= */
/* Ogni meteorite non e' un passaggio che si ripete, ma una sequenza di
   passaggi con inclinazione, quota e lunghezza diverse. Fra un passaggio e
   il successivo l'elemento torna indietro con opacita' zero: si muove, ma
   nessuno lo vede. Costa uguale - sempre solo transform e opacity - e
   toglie l'effetto "scia in loop" che a cinque secondi salterebbe agli
   occhi.

   La forma della trasformazione e' translateY -> rotate -> translateX:
   translateY sposta la quota di partenza, rotate da' l'inclinazione,
   translateX fa correre la scia lungo il proprio asse. In quest'ordine
   perche' le funzioni si applicano da sinistra a destra.

   Entrambi passano DIETRO la scheda di login (z-index -1 dentro #root),
   mai sopra il testo.                                                  */
#root::before, #root::after {
  content: ""; position: fixed; z-index: -1; pointer-events: none;
  border-radius: 2px; opacity: 0;
  will-change: transform, opacity;
}
#root::before {
  top: 9%; left: -22vw; width: 172px; height: 2px;
  background: linear-gradient(90deg, rgba(232,238,247,0) 0%,
    rgba(160,205,245,.46) 70%, rgba(255,255,255,.82) 100%);
  box-shadow: 0 0 8px 1px rgba(170,210,255,.30);
  animation: oli-meteora-a 20s linear infinite;
}
#root::after {
  top: 63%; left: -18vw; width: 126px; height: 1.5px;
  background: linear-gradient(90deg, rgba(232,238,247,0) 0%,
    rgba(186,212,244,.38) 70%, rgba(255,255,255,.68) 100%);
  box-shadow: 0 0 6px 1px rgba(170,210,255,.24);
  /* ritardo negativo: parte a ciclo gia' avviato, cosi' al caricamento
     della pagina i due non partono insieme */
  animation: oli-meteora-b 33s linear infinite;
  animation-delay: -3.4s;
}

/* quattro passaggi in 20 secondi -> uno ogni cinque */
@keyframes oli-meteora-a {
  0%      { opacity: 0;   transform: translateY(0vh)  rotate(24deg) translateX(0); }
  1.5%    { opacity: .72; }
  8%      { opacity: 0;   transform: translateY(0vh)  rotate(24deg) translateX(152vw); }

  25%     { opacity: 0;   transform: translateY(24vh) rotate(33deg) translateX(0); }
  26.5%   { opacity: .60; }
  33%     { opacity: 0;   transform: translateY(24vh) rotate(33deg) translateX(150vw); }

  50%     { opacity: 0;   transform: translateY(48vh) rotate(16deg) translateX(0); }
  51.5%   { opacity: .66; }
  58%     { opacity: 0;   transform: translateY(48vh) rotate(16deg) translateX(155vw); }

  75%     { opacity: 0;   transform: translateY(12vh) rotate(29deg) translateX(0); }
  76.5%   { opacity: .56; }
  83%     { opacity: 0;   transform: translateY(12vh) rotate(29deg) translateX(150vw); }

  /* si richiude sullo stato iniziale: il ciclo non ha scatti alla ripetizione */
  100%    { opacity: 0;   transform: translateY(0vh)  rotate(24deg) translateX(0); }
}

/* tre passaggi in 33 secondi -> uno ogni undici, e piu' lenti: leggono
   come piu' lontani */
@keyframes oli-meteora-b {
  0%      { opacity: 0;   transform: translateY(0vh)   rotate(-14deg) translateX(0); }
  1.4%    { opacity: .52; }
  7%      { opacity: 0;   transform: translateY(0vh)   rotate(-14deg) translateX(148vw); }

  33.3%   { opacity: 0;   transform: translateY(-22vh) rotate(-8deg)  translateX(0); }
  34.7%   { opacity: .46; }
  40.3%   { opacity: 0;   transform: translateY(-22vh) rotate(-8deg)  translateX(150vw); }

  66.6%   { opacity: 0;   transform: translateY(14vh)  rotate(-20deg) translateX(0); }
  68%     { opacity: .55; }
  73.6%   { opacity: 0;   transform: translateY(14vh)  rotate(-20deg) translateX(146vw); }

  100%    { opacity: 0;   transform: translateY(0vh)   rotate(-14deg) translateX(0); }
}

/* ==================== la scheda di login ============================ */
/* Resta senza backdrop-filter: con un cielo che si muove dietro, quella
   sfocatura andava ricalcolata a ogni fotogramma ed era la seconda causa
   degli scatti. L'effetto vetro lo danno fondo, bordo e lumeggiatura.  */
.MuiPaper-root {
  background: rgba(11,19,34,.87) !important;
  background-image: none !important;
  border: 1px solid rgba(78,110,135,.38) !important;
  border-radius: 14px !important;
  box-shadow:
    inset 0 1px 0 rgba(232,238,247,.08),
    0 26px 70px -24px rgba(0,0,0,.88),
    0 0 120px -46px rgba(36,140,168,.6) !important;
}

.MuiTypography-root { color: var(--luce) !important; }
.MuiTypography-subtitle1, .MuiTypography-subtitle2,
.MuiTypography-caption, .MuiTypography-body2 { color: var(--luce-tenue) !important; }
.MuiTypography-h5, .MuiTypography-h6 { letter-spacing: .01em; text-wrap: balance; }

.MuiOutlinedInput-root {
  background: rgba(7,11,20,.62) !important; border-radius: 10px !important;
  transition: box-shadow .18s ease, background .18s ease;
}
.MuiOutlinedInput-input { color: var(--luce) !important; }
.MuiOutlinedInput-notchedOutline { border-color: rgba(78,110,135,.45) !important; }
.MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline {
  border-color: rgba(36,140,168,.60) !important;
}
.MuiOutlinedInput-root.Mui-focused {
  background: rgba(7,11,20,.78) !important; box-shadow: 0 0 0 3px rgba(36,140,168,.22);
}
.MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline {
  border-color: var(--oli-teal) !important; border-width: 1px !important;
}
.MuiInputLabel-root { color: var(--luce-tenue) !important; }
.MuiInputLabel-root.Mui-focused { color: var(--oli-teal) !important; }

input[inputmode="numeric"], input[autocomplete="one-time-code"] {
  font-variant-numeric: tabular-nums; letter-spacing: .32em; text-align: center;
}

.MuiButton-contained {
  background: linear-gradient(180deg, #2A9DBB 0%, var(--oli-teal) 100%) !important;
  color: #04131A !important; font-weight: 650 !important; letter-spacing: .02em;
  border-radius: 10px !important;
  box-shadow: 0 8px 24px -10px rgba(36,140,168,.75) !important;
  transition: transform .12s ease, box-shadow .2s ease, filter .2s ease;
}
.MuiButton-contained:hover {
  filter: brightness(1.08) saturate(1.06);
  box-shadow: 0 12px 32px -10px rgba(130,187,37,.55) !important;
}
.MuiButton-contained:active { transform: translateY(1px); }
.MuiButton-text, .MuiLink-root, a { color: var(--oli-teal) !important; }
.MuiButton-text:hover, .MuiLink-root:hover, a:hover { color: #4FB4CE !important; }

.MuiCheckbox-root { color: rgba(159,178,201,.65) !important; }
.MuiCheckbox-root.Mui-checked { color: var(--oli-verde) !important; }
.MuiCircularProgress-root { color: var(--oli-teal) !important; }

.MuiAlert-root {
  background: rgba(7,11,20,.88) !important;
  border: 1px solid rgba(78,110,135,.35) !important; color: var(--luce) !important;
}
.MuiAlert-standardError   { border-color: rgba(231,67,16,.55) !important; }
.MuiAlert-standardSuccess { border-color: rgba(130,187,37,.55) !important; }
.MuiAlert-icon { color: inherit !important; }

/* ==================== il marchio che gira =========================== */
/* Nella v2 avevo dichiarato 'transform: translateZ(0)' come base per
   promuovere il livello, e cosi' il keyframe interpolava da matrice a
   matrice: translateZ(0) e rotate(360deg) sono entrambe la matrice
   identita', quindi l'animazione andava da identita' a identita' e il
   marchio stava fermo. Ora i keyframe sono espliciti da 0 a 360 gradi e
   la promozione la chiede 'will-change', senza toccare 'transform'.
   Il bagliore e' un gradiente di SFONDO, non un drop-shadow: si dipinge
   una volta e, essendo radialmente simmetrico, la rotazione non lo tocca. */
#root img {
  width: 116px !important; height: 116px !important;
  background-image: radial-gradient(circle at 50% 50%,
    rgba(36,140,168,.24) 0%, rgba(36,140,168,.08) 38%, transparent 64%);
  animation: oli-giro 18s linear infinite;
  will-change: transform;
}
@keyframes oli-giro {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ==================== accessibilita' ================================ */
/* Chi ha chiesto meno movimento nel sistema operativo vede un cielo
   completamente fermo: le stelle restano, si spegne solo il moto.     */
@media (prefers-reduced-motion: reduce) {
  html::before, html::after, body::before, body::after,
  #root::before, #root::after, #root img { animation: none !important; }
  #root::before, #root::after { display: none !important; }
}

:focus-visible { outline: 2px solid var(--oli-teal) !important; outline-offset: 2px; }

@media (max-height: 620px) {
  #root img { width: 84px !important; height: 84px !important; }
}

/* ============== la scritta "Powered by Authelia" rimossa ============ */
/* La via supportata non funziona: e' una chiave di localizzazione, ma
   Authelia RIFIUTA di partire se il valore tradotto perde il segnaposto
   {{authelia}}, quindi non si puo' svuotare. Va rimossa qui.

   Nel bundle il collegamento non si trova: href e testo sono offuscati
   in base64 e decodificati a runtime
   (href: atob(String.fromCodePoint(...))). Ma il CSS non lavora sul
   bundle, lavora sul DOM: a quel punto l'attributo href e' in chiaro e
   il selettore aggancia. Si nasconde il contenitore del collegamento,
   non solo il collegamento, altrimenti resterebbe il suo spazio; e con
   lui il separatore verticale che lo segue, altrimenti resterebbe una
   stanghetta sospesa nel vuoto.                                       */
a[href*="authelia.com"] { display: none !important; }
*:has(> a[href*="authelia.com"]) { display: none !important; }
*:has(> a[href*="authelia.com"]) + .MuiDivider-root { display: none !important; }
