/* Font auto-ospitati (Manrope, IBM Plex Mono): niente richieste a Google
   Fonts da un portale che mostra dati clinici di pazienti su ogni pagina
   autenticata. Manrope arriva come un solo file variabile (i pesi 400-700
   sono la stessa fisionomia disegnata su un asse continuo, non quattro
   disegni diversi): un file, quattro @font-face che ne dichiarano il peso,
   il browser sceglie l'istanza giusta sull'asse. IBM Plex Mono e' invece
   un font statico: un file per peso. */
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/manrope-variable.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/plexmono-400.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/plexmono-500.woff2") format("woff2");
}

/* Corsivo usato solo per il saluto in intestazione: riprende il tratto
   calligrafico del logo restando leggibile (il Pinyon Script che c'era in
   origine non lo era). Serve un solo peso, e in un solo punto del portale. */
@font-face {
  font-family: "Italianno";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/italianno-400.woff2") format("woff2");
}

/* Tema "Nocturne" (scuro) applicato alla parte autenticata del portale (I
   miei lavori, Nuovo lavoro): le variabili --colore-* mantengono gli
   stessi nomi usati in tutto il resto del foglio di stile. Accento
   primario spostato dal viola a un ciano-acciaio: e' il colore di uno
   strumento di misura piu' che di un'app generica, e lascia il vecchio
   lilla libero per un solo significato, quello dello stato "in
   lavorazione". Vengono ridefinite localmente dentro .scena-accesso per
   conservare l'aspetto chiaro della schermata di login/registrazione. */
:root {
  --font-ui: "Manrope", system-ui, -apple-system, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", monospace;

  /* Tema chiaro: sfondo bianco, testo scuro. L'accento resta lo stesso
     ciano-acciaio di sempre, ma qui serve anche come colore di testo (link,
     focus, icone): la tinta chiara usata sullo sfondo scuro era illeggibile
     su bianco, quindi per il testo si usa la stessa tinta scura gia'
     definita per il riempimento dei pulsanti. */
  --colore-primario: #1c7f92;
  --colore-primario-scuro: #145c6b;
  /* Il testo dei pulsanti pieni e' bianco puro, e il fondo e' volutamente
     scuro: con il teal piu' chiaro di prima il bianco sopra si leggeva a
     fatica, al punto da sembrare dello stesso colore del pulsante. Al
     passaggio del mouse il fondo si scurisce ancora invece di schiarirsi,
     cosi' il contrasto non cala mai. */
  --colore-pulsante: #17788c;
  --colore-pulsante-chiaro: #12626f;
  --colore-pulsante-testo: #ffffff;
  --colore-testo: #1a2030;
  --colore-testo-secondario: #5b6478;
  --colore-sfondo: #ffffff;
  --colore-superficie: #f4f6fa;
  --colore-superficie-elevata: #eaeef5;
  --colore-bordo: color-mix(in srgb, #1a2030 12%, transparent);
  --colore-bordo-forte: color-mix(in srgb, #1a2030 22%, transparent);

  --colore-successo: oklch(38% 0.11 145);
  --colore-successo-sfondo: oklch(94% 0.05 145);
  --colore-errore: oklch(42% 0.14 25);
  --colore-errore-sfondo: oklch(94% 0.06 25);
  /* Per gli avvisi che non sono un errore ne' un successo - es. "effettua
     l'accesso per continuare" quando si arriva su una pagina che lo
     richiede: non e' andato storto niente, quindi non deve leggersi come
     un errore in rosso. */
  --colore-info: oklch(40% 0.10 220);
  --colore-info-sfondo: oklch(94% 0.04 220);
  --colore-attesa: oklch(40% 0.13 65);
  --colore-attesa-sfondo: oklch(94% 0.07 65);
  --colore-lavorazione: #4a3f8a;
  --colore-lavorazione-sfondo: #ece9fb;
  --colore-pronto: oklch(38% 0.11 150);
  --colore-pronto-sfondo: oklch(94% 0.05 150);
  --colore-consegnato: #565f78;
  --colore-consegnato-sfondo: #eceff5;

  --colore-neutro-900: #eef1f6;
  --colore-neutro-800: #dde2ec;
  --colore-neutro-700: #aab1c4;
  --colore-neutro-500: #5b6478;
  --colore-accento-900: #e3f5f8;
  --colore-accento-800: #cdeef3;
  --colore-accento-700: #79c3d2;
  --colore-accento-200: #0d4e59;

  --raggio-piccolo: 6px;
  --raggio-medio: 10px;
  --raggio-grande: 18px;
  --ombra-piccola: 0 1px 2px rgba(20, 24, 38, 0.08), 0 0 0 1px var(--colore-bordo);
  --ombra-media: 0 10px 28px rgba(20, 24, 38, 0.12), 0 0 0 1px var(--colore-bordo);
  --ombra-grande: 0 28px 72px rgba(20, 24, 38, 0.22);
  --easing: cubic-bezier(0.4, 0, 0.2, 1);
}

* {
  box-sizing: border-box;
}

html {
  color-scheme: light;
}

body {
  margin: 0;
  font-family: var(--font-ui);
  background: var(--colore-sfondo);
  color: var(--colore-testo);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* Un anello di focus unico e coerente per tutto il portale, visibile solo
   a chi naviga da tastiera (non lampeggia per ogni clic del mouse). I
   componenti con un trattamento di focus piu' specifico (input, schede
   visive, denti) lo sovrascrivono qui sotto. */
:focus-visible {
  outline: 2px solid var(--colore-primario);
  outline-offset: 2px;
}

/* Chi ha chiesto al sistema di ridurre le animazioni le vede tutte
   azzerate, non solo quella del saluto: e' una preferenza che riguarda
   l'intero portale, non un singolo componente. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Un link senza classe (es. dentro un testo lungo come l'informativa
   privacy) prende altrimenti il blu di default del browser: scuro e quasi
   invisibile sullo sfondo scuro del tema. Le classi piu' specifiche
   (.piede-pagina a, .intestazione nav a, ecc.) vincono comunque su questa. */
a {
  color: var(--colore-primario);
}

a:visited {
  color: var(--colore-primario);
}

a:hover {
  text-decoration: underline;
}

/* Il saluto sta esattamente al centro dello schermo, non a meta' dello
   spazio che avanza tra logo e menu: essendo logo e menu di larghezze
   diverse, "in mezzo a loro" non e' "in mezzo allo schermo". Per riuscirci
   esce dal flusso e si ancora al 50% della fascia (che e' centrata a sua
   volta), spostandosi indietro di meta' della propria larghezza. */
.saluto-intestazione {
  /* Dentro il flusso normale del flex .intestazione-contenuto (non piu'
     fuori con position:absolute): prima era centrato "alla cieca" sullo
     schermo, senza sapere quanto spazio lasciassero liberi il logo a
     sinistra e il menu a destra. Con un nome o una ragione sociale lunga
     restava comunque alla sua larghezza piena e finiva sopra il menu.
     flex-shrink puo' farlo restringere, min-width:0 e' quello che lo
     lascia restringere DAVVERO sotto la sua larghezza naturale (di
     default un elemento flex non si restringe mai sotto il contenuto),
     overflow+text-overflow tagliano con i puntini quello che non ci sta:
     cosi' non puo' piu' invadere il menu, strutturalmente, qualunque sia
     la larghezza dello schermo. */
  flex: 1 1 auto;
  min-width: 0;
  text-align: center;
  /* Corsivo calligrafico, come il logo. Va scritto piu' grande degli altri
     caratteri: i corsivi hanno lettere minuscole molto basse rispetto al
     corpo dichiarato, e alla dimensione del resto dell'interfaccia
     risulterebbe minuscolo. */
  font-family: "Italianno", cursive;
  font-size: clamp(30px, 3.4vw, 46px);
  font-weight: 400;
  line-height: 1.1;
  color: var(--colore-primario);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Il testo viene svelato da sinistra a destra ritagliando progressivamente
   il lato destro: sembra l'inchiostro che compare sul foglio mentre una
   mano scrive, senza far "saltare" le lettere una per una. */
.saluto-intestazione .testo-saluto {
  display: inline-block;
  clip-path: inset(0 100% 0 0);
  animation: scrivi-a-mano var(--durata-scrittura, 2s) linear forwards;
}

@keyframes scrivi-a-mano {
  to { clip-path: inset(0 0 0 0); }
}

/* Gia' scritta in questa sessione del browser (vedi saluto.js): compare
   gia' completa invece di rifare da capo l'animazione ad ogni pagina. */
.saluto-intestazione .testo-saluto.gia-visto {
  animation: none;
  clip-path: none;
}

@media (prefers-reduced-motion: reduce) {
  .saluto-intestazione .testo-saluto {
    animation: none;
    clip-path: none;
  }
}

/* Su schermi non larghissimi logo e menu si avvicinano al centro: il saluto,
   che ora e' sovrapposto e non piu' nel flusso, finirebbe accavallato sopra
   di loro. Meglio non mostrarlo che mostrarlo storto. (Sotto i 768px lo
   nasconde gia' mobile.css.) */
@media (max-width: 1250px) {
  .saluto-intestazione {
    display: none;
  }
}

/* Banner + intestazione insieme, incollati in cima: il banner da solo non
   basterebbe a "restare sullo schermo" scorrendo la pagina, perche' senza
   questo contenitore sarebbe l'intestazione (sticky per conto suo) a
   coprirlo appena si scrolla. */
.fascia-fissa {
  position: sticky;
  top: 0;
  z-index: 100;
}

.banner-scadenza {
  display: block;
  background: #e65100;
  color: #fff;
  font-weight: 700;
  text-align: center;
  padding: 10px 16px;
  font-size: clamp(14px, 2vw, 16px);
  text-decoration: none;
  transition: background-color 0.15s var(--easing);
}

/* Senza questa riga, un cliente che ha gia' visitato /pagamenti (il link a
   cui rimanda questo banner) vede la scritta tornare al colore primario
   invece di restare bianca: "a:visited" (0,1,1) e' piu' specifico di
   ".banner-scadenza" (0,1,0) e vince, anche se scritto prima nel foglio di
   stile. Stesso identico bug gia' preso e risolto sui pulsanti. */
.banner-scadenza:visited {
  color: #fff;
}

.banner-scadenza:hover {
  background: #bf4400;
}

.banner-scadenza-scaduta {
  background: #e65100;
}

.banner-scadenza-scaduta:hover {
  background: #bf4400;
}

/* Avviso di limite di credito raggiunto: stesso arancione e stesso testo
   bianco del banner scadenza qui sopra, cosi' se compaiono insieme si
   presentano come un avviso unico e coerente, non due colori diversi.
   E' un div, non un link (nessuna pagina dedicata a cui rimandare), quindi
   niente stato :hover. */
.banner-limite-credito {
  background: #e65100;
}

.intestazione {
  background: var(--colore-superficie);
  border-bottom: 1px solid var(--colore-bordo);
  padding: 0 clamp(16px, 3vw, 40px);
  width: 100%;
}

.intestazione-contenuto {
  /* Stessa larghezza massima del contenuto delle pagine (.contenitore):
     cosi' il menu arriva fino al bordo destro della pagina invece di
     fermarsi prima, disallineato rispetto a tutto il resto. */
  max-width: 1800px;
  margin: 0 auto;
  padding: 16px 0;
  display: flex;
  align-items: center;
  gap: 24px;
  /* Riferimento per il saluto, che va centrato sullo schermo (vedi sotto). */
  position: relative;
}

.intestazione .logo {
  display: flex;
  align-items: center;
  text-decoration: none;
  flex-shrink: 0;
}

.intestazione .logo-immagine {
  height: 110px;
  width: auto;
  display: block;
  transition: opacity 0.2s var(--easing);
}

.intestazione .logo:hover .logo-immagine {
  opacity: 0.85;
}

.intestazione nav {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  /* Il saluto e' fuori dal flusso (posizionato al centro dello schermo),
     quindi non "spinge" piu' il menu: ci pensa questo margine a mandarlo
     tutto a destra. */
  margin-left: auto;
}

.intestazione nav a {
  position: relative;
  color: var(--colore-testo-secondario);
  text-decoration: none;
  font-size: 17px;
  font-weight: 600;
  white-space: nowrap;
  padding: 10px 16px;
  border-radius: var(--raggio-piccolo);
  transition: color 0.15s var(--easing), background-color 0.15s var(--easing);
}

/* Sottolineatura animata: si allarga dal centro invece di apparire di
   scatto, lo stesso linguaggio del resto dei micro-movimenti del portale. */
.intestazione nav a::after {
  content: "";
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 2px;
  height: 2px;
  border-radius: 2px;
  background: var(--colore-primario);
  transform: scaleX(0);
  transition: transform 0.2s var(--easing);
}

.intestazione nav a:hover {
  color: var(--colore-testo);
  background: color-mix(in srgb, var(--colore-testo) 6%, transparent);
}

.intestazione nav a[aria-current="page"] {
  color: var(--colore-testo);
}

.intestazione nav a[aria-current="page"]::after {
  transform: scaleX(1);
}

.intestazione .dentista-loggato {
  font-size: 16px;
  color: var(--colore-testo-secondario);
  padding: 10px 16px;
}

/* Il contenuto usa tutto lo spazio disponibile su schermi grandi (fino a
   un tetto ragionevole per la leggibilita'), restando comunque fluido e
   con un margine laterale minimo su schermi piccoli. */
.contenitore {
  width: min(98%, 1800px);
  margin: 0 auto;
  padding: 40px clamp(4px, 1.5vw, 32px) 64px;
}

.contenitore-stretto {
  width: min(92%, 460px);
  margin: 48px auto;
  padding: 0 20px;
}

.piede-pagina {
  text-align: center;
  padding: 24px 20px 40px;
  font-size: 13px;
}

.piede-pagina a {
  color: var(--colore-testo-secondario);
  text-decoration: none;
}

.piede-pagina a:hover {
  color: var(--colore-primario);
  text-decoration: underline;
}

.logo-accesso {
  text-align: center;
  margin-bottom: 28px;
  animation: comparsa-dallalto 0.5s var(--easing) both;
}

.logo-accesso img {
  height: 280px;
  width: auto;
  max-width: 100%;
}

.scheda {
  background: var(--colore-superficie);
  border: none;
  border-radius: var(--raggio-grande);
  padding: clamp(20px, 2.5vw, 36px);
  box-shadow: var(--ombra-piccola);
}

/* Scheda "larga": usata dal form Nuovo lavoro, che con il selettore visivo
   a schede beneficia di piu' spazio orizzontale su schermi grandi. */
.scheda-larga {
  max-width: 1800px;
  margin: 0 auto;
  padding: clamp(28px, 3vw, 56px);
}

/* Animazione di comparsa generica, usata per il contenuto principale
   quando la pagina si carica: un fade + leggero slide dal basso. */
.anima-comparsa {
  animation: comparsa-dalbasso 0.45s var(--easing) both;
}

@keyframes comparsa-dalbasso {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes comparsa-dallalto {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---------------------------------------------------------------------
   "Nuovo lavoro": il pulsante si trasforma nella card del wizard.
   ---------------------------------------------------------------------
   Il portale e' pagine renderizzate dal server, non una SPA: il cambio
   schermata resta una navigazione vera (stesso link, vedi interazioni.js).
   L'illusione del morph e' costruita cosi':
   - fase 1 (press): micro-feedback sul pulsante stesso, qui sotto;
   - fase 2-3 (morph): un overlay temporaneo, creato e rimosso da
     interazioni.js (nessun nodo nel markup), cresce dalla forma/colore
     esatti del pulsante (misurati con getBoundingClientRect) fino a
     forma/colore della card, con una sottile luce che ne percorre il
     bordo mentre si assesta;
   - fase 4-5 (titolo e contenuto): quando la pagina del wizard arriva, la
     card vera prosegue da dove l'overlay si e' fermato (stessa superficie,
     stesso raggio: nessuno scale/slide vistoso, solo un assestamento
     morbido), poi titolo e campi principali entrano con uno stagger
     leggero qui sotto. */

/* Fase 1 - press: piccolo feedback fisico al clic, piu' deciso del normale
   :active (che si annulla non appena si rilascia il mouse). */
.pulsante-nuovo-lavoro {
  position: relative;
}

.pulsante-nuovo-lavoro.in-partenza {
  animation: pulsante-nuovo-lavoro-avvio 0.28s var(--easing) both;
}

@keyframes pulsante-nuovo-lavoro-avvio {
  0%   { transform: scale(1); }
  40%  { transform: scale(0.95); box-shadow: var(--ombra-media); }
  100% { transform: scale(1); }
}

/* Il "+" reagisce con una micro-rotazione, non un giro completo: una
   reazione, non una trasformazione (quella arriva dopo, con l'overlay). */
.pulsante-nuovo-lavoro.in-partenza .icona-piu-nuovo-lavoro {
  animation: icona-piu-nuovo-lavoro-avvio 0.28s var(--easing) both;
}

@keyframes icona-piu-nuovo-lavoro-avvio {
  0%   { transform: rotate(0deg); }
  50%  { transform: rotate(25deg); }
  100% { transform: rotate(0deg); }
}

/* Fasi 2-3 - iride: un cerchio nato dal pulsante (creato via JS, classi
   definite qui, nessun markup aggiunto alle pagine) si espande fino a
   coprire l'intero schermo, passando dal colore del pulsante a quello di
   sfondo del portale - un'apertura verso la luce. Dimensione relativa al
   viewport, mai a una card: non deve indovinare/combaciare con niente di
   preciso, funziona identica a prescindere da cosa arriva dopo. Lo scrim
   attenua e sfoca quel poco di sfondo che il cerchio non ha ancora
   coperto. */
.morph-scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--colore-testo);
  opacity: 0;
  backdrop-filter: blur(0);
  transition: opacity 0.5s var(--easing), backdrop-filter 0.5s var(--easing);
  pointer-events: none;
}

.morph-scrim.attivo {
  opacity: 0.22;
  backdrop-filter: blur(3px);
}

.iride-morph {
  position: fixed;
  z-index: 61;
  border-radius: 50%;
  pointer-events: none;
  /* Solo transform e background-color: niente top/left/width/height come
     nella versione a rettangolo, quindi il browser non deve mai
     ricalcolare il layout durante l'espansione, solo comporre. */
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.55s var(--easing);
}

/* Dettaglio premium: un sottilissimo anello di luce, nel colore
   dell'accento del portale, che accompagna il cerchio mentre si espande e
   si dissolve - quasi impercettibile, non un bagliore fisso. Cresce con lo
   stesso "transform: scale()" del cerchio (e' un suo pseudo-elemento),
   quindi resta sempre un rim sottile rispetto alla dimensione attuale. */
.iride-morph::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--colore-primario) 55%, transparent);
  opacity: 0;
}

.iride-morph.scansione::after {
  animation: iride-anello 0.55s var(--easing) both;
}

@keyframes iride-anello {
  0%   { opacity: 0; }
  35%  { opacity: 0.6; }
  100% { opacity: 0; }
}

/* Fasi 4-5 - la card vera, quando la pagina del wizard arriva: prosegue da
   dove l'overlay si e' fermato (stessa superficie, stesso raggio), quindi
   qui resta solo un assestamento morbido - non uno scale/slide vistoso,
   quello era gia' successo nell'overlay. */
.anima-comparsa-wizard {
  position: relative;
  animation: comparsa-wizard 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes comparsa-wizard {
  0% {
    transform: scale(0.99);
    filter: blur(2px);
    box-shadow: var(--ombra-media);
  }
  100% {
    transform: scale(1);
    filter: blur(0);
    box-shadow: var(--ombra-piccola);
  }
}

/* Fase 4 - titolo: opacity + translateY + blur -> nitido, molto morbido. */
.anima-comparsa-wizard > h1,
.anima-comparsa-wizard > .sottotitolo {
  animation: comparsa-titolo-wizard 0.42s var(--easing) both;
}

.anima-comparsa-wizard > h1 { animation-delay: 0.06s; }
.anima-comparsa-wizard > .sottotitolo { animation-delay: 0.16s; }

@keyframes comparsa-titolo-wizard {
  from { opacity: 0; transform: translateY(10px); filter: blur(4px); }
  to   { opacity: 1; transform: translateY(0); filter: blur(0); }
}

/* Fase 5 - contenuto del wizard: stagger leggero ma percepibile sui blocchi
   principali della prima schermata. Agganciato a id/classi/attributi gia'
   presenti nel form (non alla posizione dei campi), cosi' non dipende
   dalla struttura interna e non tocca nomi/validazione/logica. */
.anima-comparsa-wizard > .passi-wizard,
.anima-comparsa-wizard label[for="nome_paziente"],
.anima-comparsa-wizard #nome_paziente,
.anima-comparsa-wizard form label:has(+ #griglia-tipo-lavoro),
.anima-comparsa-wizard #griglia-tipo-lavoro,
.anima-comparsa-wizard label[for="data_consegna"],
.anima-comparsa-wizard #data_consegna,
.anima-comparsa-wizard #nota-data-consegna,
.anima-comparsa-wizard #form-nuovo-lavoro button[type="submit"],
.anima-comparsa-wizard #form-nuovo-lavoro .pulsante-secondario {
  animation: comparsa-dalbasso 0.32s var(--easing) both;
}

.anima-comparsa-wizard > .passi-wizard { animation-delay: 0.26s; }
.anima-comparsa-wizard label[for="nome_paziente"],
.anima-comparsa-wizard #nome_paziente { animation-delay: 0.32s; }
.anima-comparsa-wizard form label:has(+ #griglia-tipo-lavoro),
.anima-comparsa-wizard #griglia-tipo-lavoro { animation-delay: 0.38s; }
.anima-comparsa-wizard label[for="data_consegna"],
.anima-comparsa-wizard #data_consegna,
.anima-comparsa-wizard #nota-data-consegna { animation-delay: 0.44s; }
.anima-comparsa-wizard #form-nuovo-lavoro button[type="submit"],
.anima-comparsa-wizard #form-nuovo-lavoro .pulsante-secondario { animation-delay: 0.5s; }

h1 {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0 0 6px;
}

h2 {
  font-size: 18px;
  font-weight: 600;
  margin: 0 0 20px;
}

.sottotitolo {
  color: var(--colore-testo-secondario);
  font-size: 14px;
  line-height: 1.5;
  margin-bottom: 28px;
}

.intestazione-pagina {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 8px;
  margin-top: 20px;
  color: var(--colore-testo-secondario);
}

label:first-of-type {
  margin-top: 0;
}

/* Checkbox singola con etichetta affiancata (es. "E' un impianto?" nel
   passo finale del wizard Nuovo lavoro): a differenza delle <label> di
   campo qui sopra, resta minuscola e in linea con il quadratino. */
.etichetta-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  text-transform: none;
  letter-spacing: normal;
  font-size: 14px;
  font-weight: 400;
  color: var(--colore-testo);
  cursor: pointer;
}

.etichetta-checkbox input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--colore-primario);
  cursor: pointer;
}

/* Come .campo-accesso qui sopra: il colore del tema scuro (--colore-testo,
   chiaro) sullo sfondo bianco della scena di accesso restava illeggibile. */
.scena-accesso .etichetta-checkbox {
  color: #013a4a;
}

#blocco-impianto {
  margin-top: 14px;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="date"],
input[type="search"],
select,
textarea {
  width: 100%;
  min-height: 42px;
  padding: 9px 13px;
  border: 1px solid var(--colore-bordo);
  border-radius: var(--raggio-medio);
  font-size: 14px;
  font-family: inherit;
  color: var(--colore-testo);
  background: var(--colore-superficie);
  transition: border-color 0.15s var(--easing), box-shadow 0.15s var(--easing);
}

input[type="date"] {
  cursor: pointer;
  color-scheme: light;
}

input[type="file"] {
  display: block;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--colore-bordo);
  border-radius: var(--raggio-medio);
  font-size: 13px;
  font-family: inherit;
  color: var(--colore-testo);
  background: var(--colore-superficie);
  box-sizing: border-box;
}

input[type="file"]::file-selector-button {
  margin-right: 12px;
  padding: 7px 14px;
  border: 1px solid var(--colore-primario);
  border-radius: var(--raggio-medio);
  background: color-mix(in srgb, var(--colore-primario) 8%, transparent);
  color: var(--colore-primario);
  font-size: 13px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: background-color 0.15s var(--easing);
}

input[type="file"]::file-selector-button:hover {
  background: color-mix(in srgb, var(--colore-primario) 12%, transparent);
}

input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--colore-primario);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--colore-primario) 22%, transparent);
}

textarea {
  resize: vertical;
  min-height: 80px;
}

.riga-campi {
  display: flex;
  gap: 16px;
}

.riga-campi > div {
  flex: 1;
}

/* Pulsante primario: superficie piena, non solo un contorno. E' l'unica
   azione a colpo pieno della pagina, cosi' lo sguardo sa sempre dove
   andare a cliccare senza doverlo cercare. */
.pulsante {
  /* Impedisce al browser di "correggere" da solo questi due colori (alcuni
     lo fanno sulle pagine chiare, con risultati imprevedibili sui pulsanti
     a sfondo pieno): qui il contrasto testo/sfondo e' gia' voluto cosi'. */
  forced-color-adjust: none;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--colore-pulsante);
  color: var(--colore-pulsante-testo);
  border: 1px solid var(--colore-pulsante);
  padding: 10px 20px;
  border-radius: var(--raggio-medio);
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
  margin-top: 24px;
  transition: background-color 0.15s var(--easing), border-color 0.15s var(--easing),
    transform 0.1s var(--easing), box-shadow 0.15s var(--easing);
}

/* Un pulsante puo' essere un collegamento (es. "Nuovo lavoro", "Invia il tuo
   primo lavoro", "Indietro"). La regola generale "a:visited" piu' in alto in
   questo foglio ha, per le regole del CSS, la precedenza su una semplice
   classe: senza queste righe, appena il cliente ha visitato una volta la
   pagina di destinazione il testo del pulsante passava al colore dei link
   visitati - teal su teal, quindi illeggibile. */
.pulsante:visited {
  color: var(--colore-pulsante-testo);
}

.pulsante-secondario:visited {
  color: var(--colore-testo);
}

.pulsante-pericolo:visited {
  color: #c0392b;
}

.pulsante:hover {
  background: var(--colore-pulsante-chiaro);
  border-color: var(--colore-pulsante-chiaro);
}

/* Il pulsante "cede" leggermente al clic: e' il feedback tattile che manca
   a un bottone puramente piatto. */
.pulsante:active {
  transform: translateY(1px) scale(0.98);
}

.pulsante:focus-visible {
  outline: 2px solid var(--colore-testo);
  outline-offset: 2px;
}

.pulsante:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

.pulsante-secondario {
  background: var(--colore-superficie-elevata);
  color: var(--colore-testo);
  border-color: var(--colore-bordo-forte);
}

.pulsante-secondario:hover {
  background: var(--colore-neutro-800);
  border-color: var(--colore-bordo-forte);
  color: var(--colore-testo);
}

/* Pulsante di un'azione irreversibile (eliminazione lavori): resta un
   contorno (non e' l'azione principale della pagina), ma si riempie di
   rosso all'hover per segnalare che e' un'azione a cui pensarci due volte. */
.pulsante-pericolo {
  background: color-mix(in srgb, #c0392b 8%, transparent);
  color: #c0392b;
  border-color: color-mix(in srgb, #c0392b 45%, transparent);
}

.pulsante-pericolo:hover:not(:disabled) {
  background: #c0392b;
  border-color: #c0392b;
  color: #fff;
}

.pulsante-pericolo:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Stato "invio in corso" applicato dallo script condiviso static/js/interazioni.js
   al pulsante di un form appena inviato: un piccolo anello che gira al
   posto dell'icona, per dire "sto lavorando" senza inventare una finestra
   di caricamento. Il testo del pulsante resta leggibile (basta lasciargli
   spazio), il clic ripetuto non fa danni perche' il puntatore e' disattivato. */
.pulsante.pulsante--in-corso {
  pointer-events: none;
  opacity: 0.85;
}

.pulsante.pulsante--in-corso::after {
  content: "";
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, currentColor 35%, transparent);
  border-top-color: currentColor;
  animation: girotondo 0.7s linear infinite;
}

@keyframes girotondo {
  to { transform: rotate(360deg); }
}

/* Barra sopra la tabella "I miei lavori": conteggio della selezione,
   pulsante di eliminazione e spiegazione di Ctrl/Shift. */
.barra-selezione {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.barra-selezione .pulsante {
  margin-top: 0;
}

.conteggio-selezione {
  font-size: 13px;
  font-weight: 500;
  color: var(--colore-testo-secondario);
  font-variant-numeric: tabular-nums;
}

.suggerimento-selezione {
  flex: 1 1 320px;
  margin: 0;
}

/* Le istruzioni cambiano in base a come si usa il portale: con il mouse si
   parla di Ctrl/Shift, col dito no (quei tasti non esistono). */
.aiuto-tocco { display: none; }

@media (pointer: coarse) {
  .aiuto-mouse { display: none; }
  .aiuto-tocco { display: inline; }
}

.ricerca-lavori {
  margin-bottom: 16px;
}

.ricerca-lavori .campo-ricerca {
  max-width: 360px;
}

.ricerca-lavori .testo-aiuto {
  display: block;
  margin-top: 6px;
}

/* -----------------------------------------------------------------------
   Fascia di riepilogo in cima a "I miei lavori": il primo colpo d'occhio
   deve rispondere da solo a "quanti lavori ho, cosa sta succedendo, cosa
   devo guardare" senza dover scorrere la tabella. Una sola striscia con
   separatori verticali, non quattro card separate con ombra: i quattro
   numeri appartengono alla stessa domanda, non a quattro widget diversi.
   ----------------------------------------------------------------------- */
.riepilogo-lavori {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin-bottom: 20px;
  background: var(--colore-superficie);
  border-radius: var(--raggio-grande);
  box-shadow: var(--ombra-piccola);
  overflow: hidden;
}

.riepilogo-voce {
  padding: 18px 24px;
  border-right: 1px solid var(--colore-bordo);
}

.riepilogo-voce:last-child {
  border-right: none;
}

.riepilogo-numero {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 30px;
  font-weight: 500;
  line-height: 1;
  color: var(--colore-testo);
  font-variant-numeric: tabular-nums;
}

.riepilogo-voce--vuota .riepilogo-numero {
  color: var(--colore-testo-secondario);
}

.riepilogo-pallino {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
}

.riepilogo-voce--lavorazione .riepilogo-pallino { background: var(--colore-lavorazione); }
.riepilogo-voce--pronto .riepilogo-pallino { background: var(--colore-pronto); }

.riepilogo-etichetta {
  display: block;
  margin-top: 4px;
  font-size: 12.5px;
  color: var(--colore-testo-secondario);
}

.riepilogo-consegna {
  font-family: var(--font-mono);
  font-size: 19px;
  font-weight: 500;
  color: var(--colore-testo);
}

/* Solo i lavori ancora eliminabili reagiscono al clic: sugli altri il
   cursore resta quello normale, cosi' si capisce che non sono selezionabili. */
table tbody tr.riga-selezionabile {
  cursor: pointer;
  user-select: none;
  /* Su telefono il browser dipinge un suo riquadro colorato sull'elemento
     toccato, che coprirebbe il colore di "selezionato": lo disattivo, tanto
     l'evidenziazione la gestiamo noi. */
  -webkit-tap-highlight-color: transparent;
}

table tbody tr.selezionata,
table tbody tr.selezionata:hover {
  background-color: color-mix(in srgb, var(--colore-primario) 16%, transparent);
}

.link-secondario {
  display: block;
  text-align: center;
  margin-top: 18px;
  font-size: 13px;
  color: var(--colore-testo-secondario);
}

.link-secondario a {
  color: var(--colore-primario);
  font-weight: 600;
  text-decoration: none;
}

.messaggio {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-radius: var(--raggio-medio);
  font-size: 14px;
  margin-bottom: 18px;
  animation: comparsa-dallalto 0.3s var(--easing) both;
}

.messaggio.successo {
  background: var(--colore-successo-sfondo);
  color: var(--colore-successo);
}

.messaggio.errore {
  background: var(--colore-errore-sfondo);
  color: var(--colore-errore);
}

.messaggio.info {
  background: var(--colore-info-sfondo);
  color: var(--colore-info);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

th, td {
  text-align: left;
  padding: 12px 10px;
}

th {
  color: var(--colore-testo-secondario);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* Le righe (intestazione compresa) dipingono da sole la linea di
   separazione, con una sfumatura che svanisce ai due estremi invece di
   fermarsi di netto: firma visiva del design system "Nocturne". */
thead tr {
  background: linear-gradient(to right,
    transparent, var(--colore-bordo) 48px,
    var(--colore-bordo) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}

tbody tr {
  background: linear-gradient(to right,
    transparent, var(--colore-bordo) 48px,
    var(--colore-bordo) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}

/* Le colonne che sono davvero un valore numerico/di data (numero lavoro,
   date) usano un font monospaziato: sono la lettura piu' veloce di una
   tabella, la stessa logica di uno strumento di misura con display a
   cifre fisse. Non e' decorazione: le cifre restano allineate colonna per
   colonna anche quando cambiano. */
.cella-mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--colore-testo-secondario);
  font-size: 13px;
}

td.cella-mono:first-child {
  color: var(--colore-testo);
  font-weight: 500;
}

.badge-stato {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 8px;
  border-radius: 20px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  transition: background-color 0.3s var(--easing), color 0.3s var(--easing);
}

.badge-stato::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

table tbody tr {
  animation: comparsa-dalbasso 0.35s var(--easing) both;
  transition: background-color 0.15s var(--easing);
}

table tbody tr:hover {
  background-color: color-mix(in srgb, var(--colore-testo) 4%, transparent);
}

/* Piccolo effetto "a cascata": ogni riga compare con un ritardo leggermente
   maggiore della precedente, per le prime righe della tabella. */
table tbody tr:nth-child(1) { animation-delay: 0.02s; }
table tbody tr:nth-child(2) { animation-delay: 0.06s; }
table tbody tr:nth-child(3) { animation-delay: 0.1s; }
table tbody tr:nth-child(4) { animation-delay: 0.14s; }
table tbody tr:nth-child(5) { animation-delay: 0.18s; }
table tbody tr:nth-child(n+6) { animation-delay: 0.2s; }

.badge-stato.in-attesa      { background: var(--colore-attesa-sfondo);      color: var(--colore-attesa); }
.badge-stato.in-lavorazione { background: var(--colore-lavorazione-sfondo); color: var(--colore-lavorazione); }
.badge-stato.pronto         { background: var(--colore-pronto-sfondo);      color: var(--colore-pronto); }
.badge-stato.consegnato     { background: var(--colore-consegnato-sfondo);  color: var(--colore-consegnato); }

/* Il cliente ha chiesto di annullare il lavoro e il laboratorio non ha ancora
   risposto. Non e' un errore ne' un successo: e' un'attesa, quindi non si usa
   il rosso. */
.nota-annullamento {
  display: inline-block;
  margin-top: 4px;
  color: var(--colore-attesa);
  font-weight: 600;
}

.stato-vuoto {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 56px 20px;
  color: var(--colore-testo-secondario);
}

.stato-vuoto svg {
  margin-bottom: 14px;
  opacity: 0.5;
}

.stato-vuoto p {
  margin: 0 0 18px;
  font-size: 14.5px;
}

.stato-vuoto .pulsante {
  margin-top: 0;
}

/* Indicatore "aggiornato ora" mostrato brevemente quando il portale
   riceve dati nuovi dal laboratorio senza bisogno di ricaricare la pagina. */
.indicatore-aggiornamento {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: 0.75rem;
  padding: 0.15rem 0.6rem 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 500;
  background: var(--colore-pronto-sfondo);
  color: var(--colore-pronto);
  animation: notifica-comparsa 2.6s var(--easing) forwards;
}

.indicatore-aggiornamento::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

@keyframes notifica-comparsa {
  0%   { opacity: 0; transform: translateY(-3px) scale(0.92); }
  10%  { opacity: 1; transform: translateY(0) scale(1); }
  75%  { opacity: 1; transform: translateY(0) scale(1); }
  100% { opacity: 0; transform: translateY(-3px) scale(0.96); }
}

.testo-aiuto {
  display: block;
  margin-top: 0.4rem;
  margin-bottom: 1rem;
  color: var(--colore-testo-secondario);
  font-size: 0.8rem;
  line-height: 1.4;
}

/* Selettore visivo "Nuovo lavoro": schede con foto + nome, in stile
   configuratore (tipo di lavoro e materiale). L'input radio resta nel
   flusso ma e' nascosto visivamente; la label (la scheda vera e propria)
   e' cliccabile ed evidenzia la selezione con :checked + label. */
.griglia-schede {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 14px;
  margin: 0.5rem 0 1.25rem;
}

.input-scheda-visiva {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.scheda-visiva {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 12px;
  /* Queste schede sono <label>: azzera margin/testo del selettore
     generico "label" qui sotto (pensato per le etichette dei campi, es.
     "SOTTOTIPO*"), altrimenti "label:first-of-type { margin-top: 0 }"
     fa si' che la prima scheda di ogni griglia si allunghi rispetto alle
     altre (la riga della grid si allarga per il margine delle altre
     schede, e la prima - senza margine - si allunga per riempirla). */
  margin: 0;
  border: 1.5px solid var(--colore-bordo);
  border-radius: var(--raggio-medio);
  cursor: pointer;
  text-align: center;
  transition: border-color 0.15s var(--easing), background-color 0.15s var(--easing),
    transform 0.15s var(--easing), box-shadow 0.15s var(--easing);
  background: var(--colore-superficie);
}

.scheda-visiva:hover {
  border-color: var(--colore-primario);
  transform: translateY(-2px);
  box-shadow: var(--ombra-media);
}

.input-scheda-visiva:checked + .scheda-visiva {
  border-color: var(--colore-primario);
  background-color: var(--colore-accento-900);
  font-weight: 500;
  transform: none;
  box-shadow: 0 0 0 1px var(--colore-accento-700);
}

.input-scheda-visiva:focus-visible + .scheda-visiva {
  outline: 2px solid var(--colore-primario);
  outline-offset: 2px;
}

.scheda-visiva img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  object-position: center;
  border-radius: var(--raggio-piccolo);
  background: var(--colore-neutro-900);
}

/* Variante del selettore visivo per il sottotipo (passo 2): niente foto,
   solo l'etichetta centrata in una scheda un po' piu' alta. */
.griglia-schede--sottotipo {
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}

.scheda-visiva--sottotipo {
  min-height: 80px;
  justify-content: center;
}

.scheda-visiva--sottotipo span {
  font-size: 17px;
}

/* Selettore visivo del materiale (passo 3): schede solo testo, piu'
   compatte delle schede con foto usate per tipo di lavoro/sottotipo. */
.griglia-materiali {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(155px, 1fr));
  gap: 10px;
  margin: 0.5rem 0 1.25rem;
}

/* Due caselle affiancate, sola lettura (diametro e tipo dell'impianto scelto). */
.griglia-due-colonne {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

/* Riquadro di un singolo impianto del lavoro: un lavoro puo' averne piu'
   d'uno (ponte su impianti, barra) e quello "attivo" e' quello a cui vengono
   assegnati i denti cliccati sulla tabella. */
.scheda-impianto {
  border: 1px solid var(--colore-bordo);
  border-radius: var(--raggio-medio);
  padding: 14px 16px;
  margin-bottom: 12px;
  cursor: pointer;
  background: var(--colore-superficie);
  transition: border-color 0.15s var(--easing), background-color 0.15s var(--easing);
}

.scheda-impianto:hover {
  border-color: color-mix(in srgb, var(--colore-primario) 45%, var(--colore-bordo));
}

.scheda-impianto.attiva {
  border-color: var(--colore-primario);
  background: color-mix(in srgb, var(--colore-primario) 7%, transparent);
}

.intestazione-impianto {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}

/* Pallino del colore assegnato all'impianto: e' lo stesso colore che
   prendono i suoi denti nella tabella, ed e' il collegamento visivo tra le
   due cose. */
.pallino-impianto {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 18%, transparent);
}

.denti-impianto {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--colore-testo-secondario);
  margin-left: auto;
}

.rimuovi-impianto {
  border: 1px solid color-mix(in srgb, #c0392b 45%, transparent);
  background: transparent;
  color: #c0392b;
  border-radius: var(--raggio-medio);
  padding: 4px 10px;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  transition: background-color 0.15s var(--easing);
}

.rimuovi-impianto:hover {
  background: color-mix(in srgb, #c0392b 12%, transparent);
}

#aggiungi-impianto {
  margin-top: 0;
  margin-bottom: 8px;
}

/* Le quattro caratteristiche tecniche dell'impianto (tipologia ingaggio,
   foro inclinato, filetto estrattivo, vite) contengono valori corti: stanno
   affiancate in caselle piu' piccole, senza allargarsi per tutta la scheda
   come gli altri campi. Su telefono tornano una sotto l'altra (vedi
   mobile.css). */
.griglia-caratteristiche-impianto {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px;
  max-width: 780px;
}

/* I due pulsanti Si/No di "Serve la vite?": affiancati e ben distanziati,
   non un menu a tendina come le altre caratteristiche - scelta esplicita
   del titolare per questa domanda. */
.gruppo-radio-si-no {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  gap: 14px;
  align-items: center;
  height: 100%;
}

/* E' anch'essa una <label>, quindi eredita di default lo stile maiuscolo e
   spaziato delle etichette di campo (vedi "label" piu' sopra): qui va
   azzerato, altrimenti il pallino del radio (dimensione non impostata,
   quella di sistema) e il testo minuscolo finiscono disallineati fra loro -
   stessa correzione gia' fatta per .etichetta-checkbox. */
.opzione-radio-si-no {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: 4px;
  text-transform: none;
  letter-spacing: normal;
  font-size: 14px;
  font-weight: 400;
  white-space: nowrap;
  cursor: pointer;
  margin: 0;
}

.opzione-radio-si-no input[type="radio"] {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--colore-primario);
  cursor: pointer;
}

.scheda-materiale {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 10px 14px;
  /* Anche questa e' un <label>: stessa correzione di .scheda-visiva qui
     sopra, altrimenti la prima scheda di ogni riga risulta piu' alta
     delle altre. */
  margin: 0;
  cursor: pointer;
  user-select: none;
  text-align: center;
  border: 1.5px solid var(--colore-bordo);
  border-radius: var(--raggio-medio);
  background: var(--colore-superficie);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--colore-testo);
  transition: border-color 0.15s var(--easing), background-color 0.15s var(--easing);
}

.scheda-materiale:hover {
  border-color: var(--colore-primario);
}

.input-scheda-visiva:checked + .scheda-materiale {
  border-color: var(--colore-primario);
  background: var(--colore-accento-900);
  color: var(--colore-accento-200);
}

.input-scheda-visiva:focus-visible + .scheda-materiale {
  outline: 2px solid var(--colore-primario);
  outline-offset: 2px;
}

/* Contenitore dell'immagine nelle schede visive: permette di sovrapporre
   il badge "da file" (icona di un documento) sopra la foto, per
   distinguere a colpo d'occhio le lavorazioni avviate da file digitale
   rispetto a quelle da modello fisico. */
.immagine-scheda {
  position: relative;
  display: block;
  width: 100%;
}

.badge-da-file {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background-color: var(--colore-accento-700);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.35);
  background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/%3E%3Cpolyline points='14 2 14 8 20 8'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 15px 15px;
}

.scheda-visiva span {
  font-size: 1.05rem;
  font-weight: 500;
  line-height: 1.3;
  color: var(--colore-testo);
}

/* -----------------------------------------------------------------------
   Schema dentale interattivo (notazione FDI) nel passo "Materiale e invio"
   del wizard Nuovo lavoro: rettangolo con i denti in griglia, stessa
   disposizione della tabella stampata sul foglietto scatola (vedi
   shared/services/gestione_fogli_scatola.py e static/js/denti.js), cosi'
   quello che si vede a schermo corrisponde a quello che finisce sul PDF.
   La cornice con le etichette "Arcata superiore/inferiore" e il divisore
   centrale piu' marcato lo fanno leggere come lo schema clinico che e',
   non come una tastiera di pulsanti qualunque.
   ----------------------------------------------------------------------- */
.arcata-dentale-cornice {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin-top: 0.5rem;
}

.arcata-etichetta {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--colore-testo-secondario);
}

.arcata-dentale {
  position: relative;
  display: grid;
  grid-template-columns: repeat(16, 1fr);
  gap: 0;
  width: min(720px, 100%);
  margin: 0;
  border: 1px solid var(--colore-bordo-forte);
  border-radius: var(--raggio-medio);
  overflow: hidden;
  background: var(--colore-neutro-900);
}

/* Linea mediana che separa arcata destra e sinistra del paziente: un
   riferimento continuo dall'alto in basso, non solo un bordo piu' spesso
   sulle celle, per leggere lo schema come un disegno tecnico. */
.arcata-dentale::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1px;
  background: color-mix(in srgb, var(--colore-primario) 55%, transparent);
  pointer-events: none;
}

.dente {
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-right: 1px solid var(--colore-bordo);
  border-bottom: 1px solid var(--colore-bordo);
  border-radius: 0;
  background: var(--colore-superficie);
  color: var(--colore-neutro-500);
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  padding: 0;
  transition: background-color 0.15s var(--easing), color 0.15s var(--easing),
    transform 0.1s var(--easing);
}

/* Divisore piu' marcato tra arcata superiore/inferiore, come nella tabella
   del foglietto stampato (il divisore sinistra/destra e' ora la linea
   mediana continua qui sopra). */
.dente:nth-child(-n+16) {
  border-bottom: 2px solid var(--colore-bordo-forte);
}

.dente:hover {
  border-color: var(--colore-primario);
  background: var(--colore-accento-900);
  color: var(--colore-testo);
}

.dente.selezionato {
  background-color: var(--colore-accento-800);
  color: var(--colore-accento-200);
  font-weight: 600;
}

.dente:focus-visible {
  outline: 2px solid var(--colore-primario);
  outline-offset: -2px;
  z-index: 1;
}

/* Piccolo "scatto" al tocco (classe aggiunta e rimossa da static/js/denti.js
   ad ogni clic, sia in modo normale che in modo impianti): il feedback che
   ci si aspetta premendo un tasto vero, non solo un cambio di colore. */
.dente.dente--tocco {
  animation: dente-tocco 0.22s var(--easing);
}

@keyframes dente-tocco {
  0%   { transform: scale(1); }
  40%  { transform: scale(0.82); }
  100% { transform: scale(1); }
}

/* Anteprima "Consegna prevista" nel form Nuovo lavoro, calcolata dal
   server con la stessa logica del programma desktop appena si sceglie
   il tipo di lavoro. */
.anteprima-consegna {
  margin: -0.5rem 0 1.25rem;
  padding: 0.6rem 0.9rem;
  border-radius: var(--raggio-medio);
  font-size: 0.9rem;
  animation: comparsa-dalbasso 0.3s var(--easing) both;
}

.anteprima-consegna.automatica {
  background: var(--colore-pronto-sfondo);
  color: var(--colore-pronto);
}

.anteprima-consegna.manuale {
  background: var(--colore-neutro-900);
  color: var(--colore-testo-secondario);
}

/* Indicatore "Passo X di Y" del wizard "Nuovo lavoro" (tipo di lavoro ->
   sottotipo -> materiale/note/allegati), uguale su tutte e tre le pagine
   cosi' il cliente capisce sempre a che punto e' arrivato. */
.passi-wizard {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 1.5rem;
}

.passo-wizard {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  color: var(--colore-testo-secondario);
}

.numero-passo-wizard {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid var(--colore-neutro-700);
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--colore-neutro-500);
  flex-shrink: 0;
  transition: border-color 0.2s var(--easing), background-color 0.2s var(--easing),
    color 0.2s var(--easing);
}

.passo-wizard.completato .numero-passo-wizard {
  border-color: var(--colore-pulsante);
  background: var(--colore-pulsante);
  color: var(--colore-pulsante-testo);
  font-size: 0;
}

.passo-wizard.completato .numero-passo-wizard::after {
  content: "\2713";
  font-size: 12px;
}

.passo-wizard.attivo .numero-passo-wizard {
  border-color: var(--colore-primario);
  color: var(--colore-primario);
}

.passo-wizard.attivo span.etichetta-passo {
  color: var(--colore-testo);
  font-weight: 600;
}

.separatore-passo-wizard {
  flex: 1;
  height: 1px;
  background: var(--colore-neutro-800);
  min-width: 16px;
}

/* Scelte dello scheletrato: due o tre caselle affiancate finche' c'e' spazio,
   impilate sul telefono (vedi templates/nuovo_lavoro_dettagli.html). */
.griglia-scheletrato {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px 20px;
  margin-bottom: 14px;
}

.griglia-scheletrato > div[hidden] {
  display: none;
}

.riepilogo-scelte-precedenti {
  background: var(--colore-neutro-900);
  border: 1px solid var(--colore-neutro-800);
  border-radius: var(--raggio-medio);
  padding: 8px 14px;
  margin: 0 0 1.25rem;
  font-size: 0.9rem;
  color: var(--colore-testo-secondario);
}

.riepilogo-scelte-precedenti strong {
  color: var(--colore-testo);
}

/* Schermata di accesso: sostituisce per intero lo sfondo chiaro standard
   con la stessa estetica scura del mockup fornito (sfondo a gradiente
   radiale, scheda bianca arrotondata). E' un elemento fisso a schermo
   intero che copre il wrapper chiaro predefinito di base.html (rimane nel
   DOM ma invisibile). All'apertura il dente e' gia' visibile e "respira";
   il testo del logo gli si affianca senza che il dente sparisca o si
   sposti, poi compaiono sottotitolo e form. Le fasi sono gestite in
   static/js/splash.js aggiungendo classi a #scena-accesso. */
.scena-accesso {
  /* Login/registrazione restano nel loro stile chiaro originale (non fanno
     parte del redesign scuro "Nocturne"): queste variabili sovrascrivono
     localmente, solo dentro la scena, i token usati dai discendenti
     (es. .messaggio per gli errori del form, .scena-accesso-link). */
  --colore-testo-secondario: #5a7680;
  --colore-successo: #2e7d32;
  --colore-successo-sfondo: #e8f5e9;
  --colore-errore: #c62828;
  --colore-errore-sfondo: #fdecea;
  --colore-info: #01586e;
  --colore-info-sfondo: #e3f3f7;
}

/* La regola generale "a { color: ... }" e' pensata per lo sfondo scuro del
   resto del portale: dentro la scena di accesso, che resta bianca apposta
   (vedi sopra), lo stesso ciano chiaro ci si leggerebbe appena. */
.scena-accesso a {
  color: #0288a8;
}

.scena-accesso {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow-y: auto;
  padding: 16px;
  background: radial-gradient(ellipse at 50% 40%, #015472 0%, #013a4a 70%);
  background-size: 130% 130%;
  font-family: var(--font-ui);
  /* Il fondo si sposta appena, lentissimo: non si "vede muoversi", si
     sente solo che la schermata non e' un'immagine ferma mentre si aspetta. */
  animation: scena-accesso-respiro-sfondo 12s ease-in-out infinite;
}

@keyframes scena-accesso-respiro-sfondo {
  0%, 100% { background-position: 50% 40%; }
  50%      { background-position: 47% 44%; }
}

.scena-accesso.scena-accesso--senza-animazione {
  animation: none;
}

.scena-accesso-scheda {
  background: #fff;
  border-radius: 28px;
  /* Meno alta di prima (era 36px sopra e sotto): il modulo di attivazione,
     con cinque campi invece dei due dell'accesso, con lo spazio di prima
     non ci stava in altezza su uno schermo normale - bisognava scorrere
     dentro una scena che dovrebbe invece vedersi tutta in un colpo. */
  padding: 24px 56px;
  width: 620px;
  max-width: 100%;
  box-shadow: var(--ombra-grande);
  animation: scena-accesso-comparsa 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

@keyframes scena-accesso-comparsa {
  from { opacity: 0; transform: scale(0.92); }
  to   { opacity: 1; transform: scale(1); }
}

.scena-accesso-palco {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}

/* Alone che pulsa intorno al dente finche' la scena sta ancora "pensando":
   un anello, non uno spinner generico, per restare nel linguaggio dello
   schema dentale del resto del portale. Sparisce non appena il logo si
   affianca (classe --unita): a quel punto il caricamento e' finito, l'alone
   ha detto quello che doveva dire. */
.scena-accesso-alone {
  position: relative;
  display: inline-flex;
}

.scena-accesso-alone::before {
  content: "";
  position: absolute;
  inset: -16px;
  border-radius: 50%;
  border: 1.5px solid rgba(2, 136, 168, 0.55);
  opacity: 0;
  animation: alone-comparsa 0.4s ease 0.2s both, alone-pulsa 2.1s ease-in-out 0.2s infinite;
}

@keyframes alone-comparsa {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes alone-pulsa {
  0%, 100% { transform: scale(0.94); opacity: 0.6; }
  50%      { transform: scale(1.14); opacity: 0; }
}

.scena-accesso.scena-accesso--unita .scena-accesso-alone::before {
  animation: alone-esce 0.5s ease both;
}

@keyframes alone-esce {
  from { opacity: 0.6; transform: scale(1); }
  to   { opacity: 0; transform: scale(1.3); }
}

.scena-accesso-dente {
  height: 72px;
  width: auto;
  display: block;
  animation: scena-accesso-respiro 2.4s ease-in-out infinite;
  user-select: none;
  -webkit-user-drag: none;
}

.scena-accesso.scena-accesso--unita .scena-accesso-dente {
  animation: none;
}

@keyframes scena-accesso-respiro {
  0%, 100% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(2, 136, 168, 0)); }
  50%      { transform: scale(1.06); filter: drop-shadow(0 0 10px rgba(2, 136, 168, 0.45)); }
}

/* Il testo del logo resta sempre nel flusso (niente "salto" di layout
   quando compare): parte trasparente e leggermente spostato verso il
   dente, poi si affianca stabilmente senza che il dente si muova o
   scompaia. */
.scena-accesso-testo {
  height: 40px;
  width: auto;
  display: block;
  opacity: 0;
  transform: translateX(-14px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.4, 0, 0.2, 1);
  user-select: none;
  -webkit-user-drag: none;
}

.scena-accesso.scena-accesso--unita .scena-accesso-testo {
  opacity: 1;
  transform: translateX(0);
}

.scena-accesso-sottotitolo {
  text-align: center;
  color: #5a7680;
  font-size: 15px;
  margin: 6px 0 0;
  font-family: var(--font-ui);
  letter-spacing: 0.2px;
  opacity: 0;
  transition: opacity 0.6s ease;
}

/* Prima passava da altezza 0 ad altezza piena in un solo istante (era in
   transizione solo l'opacita', non l'altezza: "max-height: none" non si puo'
   animare) - la scheda si allargava di scatto sotto un testo che stava
   ancora sfumando, il contrario di un'apparizione morbida. Si anima anche
   "max-height", verso un valore fisso abbastanza alto da contenere sia il
   modulo corto di accesso sia quello piu' lungo di attivazione (mai
   raggiunto per davvero, ma basta perche' la crescita risulti fluida): il
   blocco si apre e il testo dentro sfuma insieme, non uno scatto e poi una
   dissolvenza. */
.scena-accesso-corpo {
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transform: translateY(-10px);
  transition: opacity 0.55s ease, max-height 0.55s var(--easing),
    transform 0.55s var(--easing);
}

.scena-accesso.scena-accesso--pronta .scena-accesso-sottotitolo {
  opacity: 1;
}

.scena-accesso.scena-accesso--pronta .scena-accesso-corpo {
  opacity: 1;
  /* Valore di scorta, usato solo se lo script (static/js/splash.js) non
     e' partito: normalmente lui misura l'altezza vera del modulo (accesso
     o attivazione, diversi di lunghezza) e la scrive qui sopra come stile
     in linea, che vince su questo. */
  max-height: 900px;
  transform: translateY(0);
  margin-top: 12px;
}

/* Ogni riga del form (etichetta, campo, bottone) compare per conto suo con
   un lieve ritardo crescente invece che tutte insieme: la stessa cascata
   gia' usata per le righe della tabella lavori, qui applicata a un form di
   due-tre campi soltanto, quindi appena percettibile ma non piatta. */
.scena-accesso-corpo form > * {
  opacity: 0;
}

.scena-accesso.scena-accesso--pronta .scena-accesso-corpo form > * {
  animation: comparsa-dalbasso 0.45s var(--easing) both;
}

.scena-accesso.scena-accesso--pronta .scena-accesso-corpo form > *:nth-child(1) { animation-delay: 0.05s; }
.scena-accesso.scena-accesso--pronta .scena-accesso-corpo form > *:nth-child(2) { animation-delay: 0.1s; }
.scena-accesso.scena-accesso--pronta .scena-accesso-corpo form > *:nth-child(3) { animation-delay: 0.15s; }
.scena-accesso.scena-accesso--pronta .scena-accesso-corpo form > *:nth-child(4) { animation-delay: 0.2s; }
.scena-accesso.scena-accesso--pronta .scena-accesso-corpo form > *:nth-child(5) { animation-delay: 0.25s; }
.scena-accesso.scena-accesso--pronta .scena-accesso-corpo form > *:nth-child(n+6) { animation-delay: 0.3s; }

.scena-accesso-corpo form {
  display: flex;
  flex-direction: column;
  /* Era 14px: il modulo di attivazione ha cinque campi invece di due, e
     quello spazio moltiplicato per tutte le righe pesava parecchio
     sull'altezza totale della scena (vedi .scena-accesso-scheda). */
  gap: 10px;
}

.etichetta-accesso {
  display: block;
  font-size: 14.5px;
  font-weight: 650;
  color: #013a4a;
  letter-spacing: 0;
  font-family: var(--font-ui);
  margin: 0 0 5px;
}

/* Selettori qualificati con .scena-accesso (anziche' solo .campo-accesso)
   per battere in specificita' le regole generiche "input[type=...]" del
   tema scuro qui sopra - altrimenti, avendo quelle un selettore
   elemento+attributo, vincerebbero loro anche se dichiarate prima. */
.scena-accesso .campo-accesso {
  border: 1.5px solid #d0dde2;
  border-radius: 10px;
  padding: 12px 16px;
  min-height: 0;
  font-size: 16px;
  font-family: var(--font-ui);
  color: #1a2a30;
  background: #f7fbfc;
  width: 100%;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.scena-accesso .campo-accesso:focus {
  border-color: #0288a8;
  box-shadow: 0 0 0 3px rgba(2, 136, 168, 0.18);
  outline: none;
}

.nota-campo-accesso {
  display: block;
  margin: -6px 0 0;
  color: #5a7680;
  font-size: 13px;
  font-family: var(--font-ui);
}

/* Il tasto "Mostra/Nascondi" che static/js/password_visibile.js aggiunge
   dentro ogni campo password: il campo diventa il contenitore relativo, il
   tasto ci galleggia sopra a destra invece di prendersi una riga sua, che
   avrebbe allungato ancora la scena. */
.campo-accesso-password {
  position: relative;
}

.campo-accesso-password .campo-accesso {
  padding-right: 86px;
}

.pulsante-mostra-password {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  background: none;
  border: none;
  color: #0288a8;
  font-size: 13.5px;
  font-weight: 600;
  font-family: var(--font-ui);
  cursor: pointer;
  padding: 7px 9px;
  border-radius: 6px;
}

.pulsante-mostra-password:hover {
  background: rgba(2, 136, 168, 0.09);
}

.pulsante-mostra-password:focus-visible {
  outline: 2px solid #0288a8;
  outline-offset: 1px;
}

.pulsante-accesso {
  position: relative;
  background: #013a4a;
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 14px;
  font-size: 16px;
  font-weight: 600;
  font-family: var(--font-ui);
  cursor: pointer;
  letter-spacing: 0.2px;
  transition: background-color 0.2s ease, transform 0.1s var(--easing);
  width: 100%;
}

.pulsante-accesso:hover {
  background: #01586e;
}

.pulsante-accesso:active {
  transform: scale(0.99);
}

.pulsante-accesso.pulsante--in-corso {
  pointer-events: none;
  opacity: 0.85;
}

.pulsante-accesso.pulsante--in-corso::after {
  content: "";
  display: inline-block;
  width: 15px;
  height: 15px;
  margin-left: 10px;
  vertical-align: -3px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  animation: girotondo 0.7s linear infinite;
}

.scena-accesso-link {
  text-align: center;
  margin: 10px 0 0;
  font-family: var(--font-ui);
  font-size: 14.5px;
  color: var(--colore-testo-secondario);
  /* Aspetta il resto della scena invece di comparire subito: e' l'ultima
     riga del percorso "dente -> logo -> form", non un elemento a parte. */
  opacity: 0;
  transition: opacity 0.5s ease;
}

.scena-accesso.scena-accesso--pronta .scena-accesso-link {
  opacity: 1;
  transition-delay: 0.35s;
}

.scena-accesso-link a {
  color: #0288a8;
  font-weight: 600;
  text-decoration: none;
}

.scena-accesso-link a:hover {
  text-decoration: underline;
}

/* Compare solo dopo un errore di password (vedi password_sbagliata in
   web/app/auth/routes.py): un avviso in piu', non un link su cui cliccare,
   quindi stesso stile di .scena-accesso-link ma senza il colore da link. */
.scena-accesso-password-dimenticata {
  margin-top: 4px;
}

/* Quando la scena e' gia' stata vista in questa sessione del browser
   (vedi static/js/splash.js), niente animazioni: scheda, dente, testo,
   sottotitolo e form compaiono gia' nel loro stato finale, senza attese. */
.scena-accesso.scena-accesso--senza-animazione,
.scena-accesso.scena-accesso--senza-animazione .scena-accesso-scheda,
.scena-accesso.scena-accesso--senza-animazione .scena-accesso-dente,
.scena-accesso.scena-accesso--senza-animazione .scena-accesso-testo,
.scena-accesso.scena-accesso--senza-animazione .scena-accesso-sottotitolo,
.scena-accesso.scena-accesso--senza-animazione .scena-accesso-corpo,
.scena-accesso.scena-accesso--senza-animazione .scena-accesso-corpo form > *,
.scena-accesso.scena-accesso--senza-animazione .scena-accesso-link {
  animation: none !important;
  transition: none !important;
  opacity: 1 !important;
}

/* L'alone e' un segnale di attesa: chi ha gia' visto la scena in questa
   sessione non deve trovarselo disegnato per sempre intorno al dente. */
.scena-accesso.scena-accesso--senza-animazione .scena-accesso-alone::before {
  animation: none !important;
  transition: none !important;
  opacity: 0 !important;
}

/* Sezioni del passo finale del wizard (Materiale, Denti interessati, Note,
   Allegati, azioni): ogni blocco e' separato da un filo orizzontale che
   sfuma ai due estremi invece di fermarsi di netto (stessa firma visiva
   usata dalla tabella), con respiro verticale generoso. */
.sezione-campo {
  margin-top: 2rem;
  padding-top: 2rem;
  background: linear-gradient(to right,
    transparent, var(--colore-bordo) 48px,
    var(--colore-bordo) calc(100% - 48px), transparent) no-repeat top / 100% 1px;
}

/* Zona "trascina qui i file" degli allegati (passo finale del wizard):
   il vero <input type="file"> resta accessibile ma nascosto (la label
   che lo avvolge apre gia' il selettore file al click, in tutti i
   browser). Il drag&drop e l'elenco dei nomi file sono gestiti in
   static/js/allegati.js. */
.zona-allegati {
  display: block;
  border: 1.5px dashed var(--colore-bordo-forte);
  border-radius: var(--raggio-medio);
  padding: 32px 24px;
  text-align: center;
  color: var(--colore-testo-secondario);
  cursor: pointer;
  transition: border-color 0.15s var(--easing), background-color 0.15s var(--easing);
  /* Reset delle proprieta' tipografiche delle <label> (maiuscolo,
     letter-spacing, peso) ereditate altrimenti dai figli, dato che
     questa label viene usata come contenitore/zona di sgancio e non
     come didascalia di campo. */
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
  margin: 0;
}

.zona-allegati:hover,
.zona-allegati.zona-allegati--sopra {
  border-color: var(--colore-primario);
  background: color-mix(in srgb, var(--colore-primario) 6%, transparent);
}

.zona-allegati.zona-allegati--sopra {
  transform: scale(1.005);
}

.zona-allegati svg {
  margin: 0 auto 10px;
  display: block;
  opacity: 0.5;
}

.zona-allegati p {
  margin: 0 0 4px;
  font-size: 14px;
  color: var(--colore-testo);
}

.zona-allegati-sfoglia {
  color: var(--colore-primario);
  text-decoration: underline;
}

.zona-allegati small {
  font-size: 12px;
  opacity: 0.65;
}

.zona-allegati-elenco {
  margin-top: 10px;
  font-size: 12px;
  color: var(--colore-testo);
  word-break: break-word;
}

/* Qualificato come "input.input-file-nascosto" (elemento + classe) per
   battere in specificita' la regola generica "input[type=file]" qui
   sopra, che altrimenti vincerebbe imponendo di nuovo bordo/larghezza
   piena e renderebbe visibile il campo che deve restare nascosto. */
input.input-file-nascosto {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  padding: 0;
  border: none;
  pointer-events: none;
}

.azioni-wizard {
  display: flex;
  align-items: center;
  gap: 12px;
}

.azioni-wizard .pulsante {
  margin-top: 0;
}

/* -----------------------------------------------------------------------
   Animazione di invio del wizard "Nuovo lavoro" (vedi static/js/invio_lavoro.js).
   Il resto del progetto non tocca queste classi: sono usate solo li'.
   ----------------------------------------------------------------------- */

/* La scheda del wizard si chiude cosi', appena il server conferma che il
   lavoro e' stato creato: un lieve movimento verso l'alto, non uno scatto. */
.scheda-nuovo-lavoro--inviata {
  animation: scheda-nuovo-lavoro-esce 0.32s var(--easing) forwards;
  pointer-events: none;
}

@keyframes scheda-nuovo-lavoro-esce {
  to { opacity: 0; transform: translateY(-14px); }
}

.overlay-invio-lavoro {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Niente velo colorato a schermo intero: prima c'era, e sotto di lui il
     pulsante "Nuovo lavoro" (teal con testo bianco) appariva slavato, con
     testo e sfondo praticamente dello stesso colore. Se poi il browser
     sbagliava a ridisegnare quella zona quando il velo spariva, il pulsante
     restava congelato cosi'. Ora il contenitore e' completamente
     trasparente e non intercetta mai i clic: la conferma e' una scheda per
     conto suo, al centro, e il resto della pagina non viene mai coperto. */
  background: none;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s var(--easing);
}

.overlay-invio-lavoro--visibile {
  opacity: 1;
}

/* La conferma vera e propria: una scheda compatta al centro, con il suo
   sfondo, invece di una spunta appoggiata sopra tutta la pagina. */
.overlay-invio-lavoro-contenuto {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 32px 44px;
  background: var(--colore-sfondo);
  border-radius: var(--raggio-grande);
  box-shadow: var(--ombra-media);
  transform: scale(0.94);
  transition: transform 0.35s cubic-bezier(0.34, 1.4, 0.64, 1);
}

.overlay-invio-lavoro--visibile .overlay-invio-lavoro-contenuto {
  transform: scale(1);
}

.spunta-invio-svg {
  overflow: visible;
}

/* Spunta disegnata a tratto (cerchio + segno), non un'icona statica che
   compare e basta: la stessa tecnica del "disegno che si completa" gia'
   usata per il saluto in intestazione (.testo-saluto). Il tratteggio resta
   fermo (dashoffset = lunghezza intera) finche' l'overlay non diventa
   visibile: senza questo si vedrebbe gia' tracciato al primo caricamento
   della pagina, ben prima dell'invio. */
.spunta-invio-cerchio {
  stroke: var(--colore-pronto);
  stroke-width: 2.5;
  stroke-dasharray: 151;
  stroke-dashoffset: 151;
}

.spunta-invio-segno {
  stroke: var(--colore-pronto);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 36;
  stroke-dashoffset: 36;
}

.messaggio-invio-lavoro {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--colore-testo);
  opacity: 0;
}

.overlay-invio-lavoro--visibile .spunta-invio-cerchio {
  animation: spunta-cerchio 0.5s var(--easing) 0.05s forwards,
    spunta-glow 0.9s ease 0.5s both;
}

.overlay-invio-lavoro--visibile .spunta-invio-segno {
  animation: spunta-segno 0.35s var(--easing) 0.45s forwards;
}

/* Il messaggio arriva con la stessa comparsa gia' usata in tutta l'app
   (.anima-comparsa) invece di inventarne una nuova. */
.overlay-invio-lavoro--visibile .messaggio-invio-lavoro {
  animation: comparsa-dalbasso 0.4s var(--easing) 0.55s forwards;
}

@keyframes spunta-cerchio {
  to { stroke-dashoffset: 0; }
}

@keyframes spunta-segno {
  to { stroke-dashoffset: 0; }
}

/* Bagliore molto discreto intorno alla spunta appena il tratto e'
   completo: un respiro solo, non un lampeggio. */
@keyframes spunta-glow {
  0%   { filter: drop-shadow(0 0 0 transparent); }
  45%  { filter: drop-shadow(0 0 9px color-mix(in srgb, var(--colore-pronto) 55%, transparent)); }
  100% { filter: drop-shadow(0 0 0 transparent); }
}

@media (prefers-reduced-motion: reduce) {
  .overlay-invio-lavoro--visibile .spunta-invio-cerchio,
  .overlay-invio-lavoro--visibile .spunta-invio-segno {
    stroke-dashoffset: 0;
  }
}
