/* ============================================================
     I MATTONI: un colore non si scrive mai a mano nel resto del
     file, si prende da qui. Cambiare tema o densita' = cambiare
     questi valori, non andare a caccia di colori nel CSS.
     ============================================================ */
  :root {   /* tavolozza-inizio */
    /* superfici, dal fondo verso l'alto */
    --fondo:      #0f1115;   /* la pagina */
    --superficie: #171a21;   /* riquadri, tabella, finestre */
    --rialzo:     #1d222c;   /* riquadro dentro un riquadro, riga sotto il mouse */
    --bordo:      #262b36;   /* l'unica riga di separazione, sempre 1px */
    --bordo-vivo: #3a4150;   /* bordo di un campo su cui stai scrivendo */
    /* testo: tre livelli, non dieci */
    --testo:      #e6e6e6;   /* quello che conta */
    --testo-2:    #9aa4b2;   /* dettagli tecnici, note */
    --testo-3:    #6b7280;   /* roba di servizio: orari, conteggi */
    /* stato: gli unici colori vivi della pagina */
    --ok:     #4ade80;  --ok-fondo:     #123d2a;  --ok-bordo:   #1d6b46;
    --attesa: #fbbf24;  --attesa-fondo: #3d3312;
    --male:   #f87171;  --male-fondo:   #4a1620;  --male-bordo: #5b2430;
    --scelto: #7dd3fc;  --scelto-fondo: #1e3a5f;
    /* i tre che mancavano, e che erano il motivo dei colori scritti a mano */
    --incasso:      #0b0e13;  /* dentro un campo: piu' basso della superficie */
    --bordo-scelto: #3f6ea8;  /* bordo di cio' che stai scrivendo o hai scelto */
    --su-scelto:    #cfe3ff;  /* testo SOPRA uno sfondo blu */
    --codice:       #a5f3c4;  /* comandi e query: si distinguono dal testo */
    /* Testo scritto SOPRA la foto del telefono: la foto non segue il
       tema, quindi qui il bianco e' giusto in tutti e due. */
    --su-foto: #ffffff;
    --bat-lum:      52%;      /* quanto e' chiara la barra della batteria */
    /* spazi: una scala sola, niente numeri a caso */
    --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;
    --raggio: 8px;
    --riga: 34px;            /* altezza di una riga di tabella */
    /* testo: tre misure in tutto */
    --t-grande: 15px; --t-normale: 13px; --t-piccolo: 12px;
    --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  }/* tavolozza-fine */

  body { font-family: system-ui, sans-serif; margin:0; background:var(--fondo);
         color:var(--testo); font-size:var(--t-normale); line-height:1.5; }

  /* Respiro: la pagina non e' piu' incollata ai bordi e non si allarga
     all'infinito su uno schermo largo (righe lunghissime = illeggibili). */
  .contenuto { max-width:1500px; margin:0 auto; padding:0 var(--s5); }

  header { padding:var(--s5) 0 var(--s4); border-bottom:1px solid var(--bordo);
           background:var(--fondo); }
  header h1 { margin:0; font-size:18px; font-weight:600; letter-spacing:-.2px; }
  header p { margin:var(--s2) 0 0; color:var(--testo-2); font-size:var(--t-normale);
             max-width:78ch; }

  /* Barra di servizio: capacita' e coda. E' un riquadro, non testo sciolto. */
  .barra-cap { display:flex; flex-wrap:wrap; align-items:center; gap:var(--s4);
               background:var(--superficie); border:1px solid var(--bordo);
               border-radius:var(--raggio); padding:var(--s3) var(--s4);
               margin:var(--s4) 0; font-size:var(--t-normale); }
  /* ⭐ La barra di avanzamento del download dell'immagine (28/08). Serve a una
     cosa sola: dire che sta succedendo qualcosa e quanto manca. Il numero in
     MB sta nella riga sotto — una barra senza numeri non fa capire se sono
     due minuti o mezz'ora. */
  .barra-avanz { height:10px; background:var(--incasso); border:1px solid var(--bordo);
                 border-radius:999px; overflow:hidden; margin:var(--s4) 0 var(--s2); }
  .ba-dentro { height:100%; width:0; background:var(--ok);
               transition:width .3s ease; }
  .ba-dentro.male { background:var(--male); }
  /* ⚠️ Quando Docker non dice il totale non si finge di saperlo: la barra
     scorre avanti e indietro invece di mostrare una percentuale inventata. */
  .ba-dentro.ignota { background:linear-gradient(90deg,
                        var(--bordo) 0 40%, var(--ok) 40% 60%, var(--bordo) 60%);
                      background-size:250% 100%; animation:scorre 1.3s linear infinite; }
  @keyframes scorre { from { background-position:100% 0; }
                      to   { background-position:-150% 0; } }
  .barra-cap .voce { color:var(--testo-2); }
  .barra-cap .voce b { color:var(--testo); font-weight:600; }
  .barra-cap .spinta { margin-left:auto; }

  /* La tabella vive dentro un riquadro: bordo da 1px, niente ombre.
     ⭐ IL RESPIRO (2026-08-21, osservazione dell'utente). Il riquadro non
     aveva nessun margine interno: lo spazio arrivava solo dai figli, quindi
     le tabelle stavano bene e OGNI TESTO finiva incollato al bordo — in tutta
     la webapp, non solo nel Costruttore. Adesso il respiro sta nel riquadro,
     cioe' nel posto che vale per tutti. */
  .riquadro { background:var(--superficie); border:1px solid var(--bordo);
              border-radius:var(--raggio); overflow:hidden;
              padding:var(--s4); }
  /* ...tranne le tabelle, che il loro bordo interno ce l'hanno gia' e devono
     arrivare da un lato all'altro: senza questo si vedrebbe una cornice
     doppia. Il -s4 in alto vale solo quando la tabella e' la prima cosa. */
  .riquadro > table { width:calc(100% + var(--s4) * 2);
                      margin:0 calc(var(--s4) * -1) calc(var(--s4) * -1); }
  .riquadro > table:first-child { margin-top:calc(var(--s4) * -1); }
  .riquadro > h2:first-child, .riquadro > h3:first-child { margin-top:0; }
  table { width:100%; border-collapse:collapse; }
  th, td { padding:var(--s3) var(--s4); text-align:left;
           border-bottom:1px solid var(--bordo); font-size:var(--t-normale);
           vertical-align:top; }
  tbody tr:last-child td { border-bottom:0; }
  th { color:var(--testo-3); font-weight:600; font-size:11px; letter-spacing:.6px;
       text-transform:uppercase; background:var(--fondo); padding-top:var(--s2);
       padding-bottom:var(--s2); }
  /* ⭐ LE LARGHEZZE (24/08, scelta dell'utente). Erano quattro percentuali
     fisse, tarate su quando lo stato era una frase lunga: adesso che e' una
     parola sola, "Stato" teneva un quarto della pagina vuoto mentre il nome
     dell'istanza finiva nei puntini a fianco.
     ⭐ La regola nuova: **misura fissa a chi ha contenuto prevedibile, tutto
     il resto a chi ha il testo lungo.** Le tre colonne di destra sanno quanto
     sono larghe (una parola, una batteria con le coordinate, tre pulsanti);
     la colonna Istanza non ha una `width`, e con `table-layout:fixed` questo
     vuol dire "prenditi quello che avanza" — quindi si allarga con la
     finestra e non lascia buchi.
     ⚠️ Restano misure FISSE e non "auto": con auto le colonne cambierebbero
     larghezza a ogni aggiornamento (ogni 3 secondi) a seconda di cosa c'e'
     dentro, e una tabella che balla mentre la guardi non si legge. */
  #tab-istanze { table-layout:fixed; }
  /* Stato e Task sono due parole sole: piu' larghi sarebbero due buchi. */
  #tab-istanze .c-stato    { width:140px; }
  #tab-istanze .c-task     { width:100px; }
  /* ⭐ 25/08 (osservazione di Emanuele): piu' larga. Dentro ci stanno batteria,
     coordinate, "in giro / a casa" e il link alla mappa — e allargandola si
     sposta anche Stato piu' a sinistra, che era l'altra meta' della richiesta:
     la colonna Istanza e' quella che prende cio' che avanza. */
  #tab-istanze .c-telefono { width:330px; }
  #tab-istanze .c-azioni   { width:250px; }
  #tab-istanze td { vertical-align:middle; }
  /* ⭐ CONNESSIONI (25/08, osservazione di Emanuele): stessa regola di sopra —
     misura fissa a chi ha contenuto prevedibile, e il nome si prende quel che
     avanza. Prima le colonne erano automatiche e il motivo di una caduta (il
     comando fallito, lunghissimo) mandava a capo la cella: la riga diventava
     alta il doppio, i comandi finivano su due file e la tabella sembrava
     disordinata. Adesso il motivo sta dietro la ⓘ e le larghezze non ballano. */
  #tab-conn { table-layout:fixed; }
  #tab-conn .c-paese   { width:130px; }
  #tab-conn .c-stato   { width:130px; }
  #tab-conn .c-ip      { width:130px; }
  #tab-conn .c-istanze { width:80px; }
  /* I comandi su UNA riga: `nowrap` glielo impone, la larghezza glielo
     permette. Se un giorno non ci stessero, il posto da guardare e' questo. */
  #tab-conn .c-azioni  { width:400px; white-space:nowrap; text-align:right; }
  #tab-conn td { vertical-align:middle; }
  tbody tr:hover { background:var(--rialzo); }
  /* Un'istanza bloccata si riconosce dalla riga, non solo dalla scritta. */
  tr.riga-bloccata td:first-child { box-shadow:inset 3px 0 0 var(--male); }
  /* Fuori servizio non e' un allarme: e' una scelta di chi comanda. Quindi
     riga smorzata e barretta grigia, non rossa - il rosso deve restare raro,
     altrimenti smette di voler dire "guarda qui". */
  tr.riga-fuori td:first-child { box-shadow:inset 3px 0 0 var(--testo-2); }
  tr.riga-fuori { opacity:.62; }

  /* Gerarchia: il nome in chiaro e in grassetto, i dettagli tecnici sotto in
     grigio piccolo. Stessa misura, importanza diversa (peso, non dimensione). */
  .titolo-riga { font-weight:600; font-size:var(--t-grande); }
  .sotto { color:var(--testo-2); font-size:var(--t-piccolo); margin-top:2px; }
  /* ⭐ UNA RIGA PER ISTANZA (24/08, scelta dell'utente): nome e telefono di
     fianco, batteria e posizione di fianco. A quaranta istanze la lista si
     scorre con l'occhio invece che con la rotella — ed e' il motivo per cui
     questa pagina e' una lista e non un mazzo di schede.
     `min-width:0` sui figli: senza, dentro un flex il troncamento non parte e
     la riga si allarga oltre la colonna invece di mettere i puntini. */
  .riga-uno { display:flex; align-items:baseline; gap:var(--s2);
              min-width:0; }
  .riga-uno > * { min-width:0; }
  .riga-uno .sotto { margin-top:0; }
  .riga-uno .bat { align-self:center; }
  .sotto .num, .num { font-family:var(--mono); font-variant-numeric:tabular-nums; }
  .tronca { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

  .pill { display:inline-block; padding:2px 10px; border-radius:999px;
          font-size:var(--t-piccolo); font-weight:600; }
  .running { background:var(--ok-fondo); color:var(--ok); }
  /* ⭐ 25/08: le tinte delle pillole per NOME dello stato mancavano dal foglio
     di stile, pur essendo usate in tre punti (stato di una connessione, coda
     del device, esiti). Senza, la pillola era testo nudo con dieci pixel di
     rientro: sembrava una parola scritta storta, e "Da creare" si leggeva
     uguale a "Caduta". Stesse tinte di .running/.stopped, cosi' verde, giallo
     e rosso vogliono dire la stessa cosa in tutta la webapp. */
  .pill.ok     { background:var(--ok-fondo);     color:var(--ok); }
  .pill.attesa { background:var(--attesa-fondo); color:var(--attesa); }
  .pill.male   { background:var(--male-fondo);   color:var(--male); }
  .pill.spento { background:var(--rialzo);       color:var(--testo-3); }
  /* ⭐ 24/08: era grigia come le cose spente, e "ferma" si leggeva come un
     dettaglio. Gialla: non e' un allarme, e' "guarda qui". */
  .stopped { background:var(--attesa-fondo); color:var(--attesa); }
  /* ⭐ Lo stato dell'automazione: la PAROLA colorata, senza riquadro
     (scelta dell'utente). Il fondo pieno la faceva pesare come un'etichetta,
     mentre e' un dato in mezzo agli altri della riga. Le tinte sono le stesse
     delle pillole, cosi' verde e giallo vogliono dire la stessa cosa ovunque. */
  .stato { font-size:var(--t-piccolo); font-weight:600; background:none;
           padding:0; }
  .stato.running { color:var(--ok); }
  .stato.stopped, .stato.paused { color:var(--attesa); }
  .stato.blocked { color:var(--male); }
  /* ⭐ Telefono spento: la parola e' "Spento" ed e' grigia come tutto il resto
     della riga. Non e' un allarme — e' una scelta di chi comanda, come "fuori
     servizio": il rosso deve restare raro per continuare a voler dire qualcosa. */
  .stato.spento { color:var(--testo-3); }
  .paused  { background:var(--attesa-fondo); color:var(--attesa); }
  .blocked { background:var(--male-fondo); color:var(--male); }
  .fuori   { background:var(--rialzo); color:var(--testo-2);
             border:1px dashed var(--bordo); }
  .sem { display:inline-flex; align-items:center; gap:var(--s2);
         cursor:help; }
  .dot { width:9px; height:9px; border-radius:50%; display:inline-block;
         flex:none; }
  /* Stato e pallino della maschera sulla stessa riga: rispondono alla stessa
     domanda — "sta lavorando, ed e' protetta?" */
  .riga-stato { display:flex; align-items:center; gap:var(--s2); }
  .dot.on  { background:var(--ok); }
  .dot.off { background:var(--male); }
  /* Le animazioni sono un allarme, non una decorazione: lampeggia SOLO la
     spia di una maschera caduta mentre l'istanza sta lavorando. */
  .dot.allarme { animation:pulsa 1.1s ease-in-out infinite; }
  @keyframes pulsa { 50% { opacity:.25; } }
  .motivo { color:var(--male); font-size:var(--t-piccolo); margin-top:var(--s1); }

  /* ⭐ Batteria finta: il colore va dal verde al rosso passando per il giallo,
     quindi il livello si vede prima ancora di leggere il numero. È l'unico
     punto della pagina dove il colore è una scala e non uno stato secco: una
     batteria non è "buona o rotta", è una quantità.
     La tinta la calcola il JavaScript (--h, 0=rosso 120=verde); qui si decide
     solo quanto è chiara, perché lo stesso verde su fondo bianco sparisce. */
  .bat { display:inline-flex; align-items:center; gap:var(--s2); }
  /* Piccola: e' un dato di contorno, non il soggetto della riga. Piu' grande
     di cosi' pesava quanto il nome dell'istanza. */
  /* ⭐ 25/08: piu' grande, perche' adesso la percentuale sta DENTRO. Resta
     comunque un dato di contorno: e' larga quanto due parole corte. */
  .bat-guscio { position:relative; width:40px; height:16px; flex:none;
                border:1.5px solid var(--testo-3); border-radius:3px;
                padding:1px; overflow:hidden; }
  /* il puntino del polo positivo: senza, sembra una barra qualsiasi */
  .bat-guscio::after { content:""; position:absolute; right:-3.5px; top:3px;
                       width:2.5px; height:4px; background:var(--testo-3);
                       border-radius:0 2px 2px 0; }
  .bat-riempi { display:block; height:100%; border-radius:1px;
                background:hsl(var(--h, 120) 62% var(--bat-lum)); }
  /* Col telefono spento la carica non e' un semaforo: e' un dato in attesa. */
  .bat-riempi.grigia { background:var(--testo-3); }
  /* ⭐ "Smorzato": tutto lo stesso grigio, un tono solo. Si legge ancora (sono
     i valori che un'app vedrebbe appena riacceso il telefono) ma non attira
     l'occhio come se stesse succedendo adesso, perche' non sta succedendo. */
  .smorzato, .smorzato * { color:var(--testo-3) !important; }
  .smorzato .in-giro, .smorzato .bat-fulmine { color:var(--testo-3) !important; }
  .bat b { font-variant-numeric:tabular-nums; }
  /* Il numero dentro il guscio: sta sopra il riempimento, quindi ha bisogno di
     staccarsi sia dal colore pieno sia dal fondo vuoto. L'ombra chiara e' il
     modo piu' semplice per leggersi su tutti e due senza cambiare tinta. */
  .bat-num { position:absolute; inset:0; display:flex; align-items:center;
             justify-content:center; font-size:9px; font-weight:700;
             font-variant-numeric:tabular-nums; color:var(--testo);
             text-shadow:0 0 2px var(--superficie), 0 0 3px var(--superficie);
             letter-spacing:-.2px; }
  .bat-fulmine { color:var(--attesa); }
  .in-giro { color:var(--scelto); }
  .link-mappa { color:var(--testo-3); text-decoration:none; border-bottom:1px dotted; }
  .link-mappa:hover { color:var(--scelto); }

  /* Pulsanti a tre pesi: primario (l'azione principale), normale (aprire una
     finestra), pericoloso (ferma, sblocca, spegni la maschera). */
  button { background:var(--rialzo); color:var(--testo); border:1px solid var(--bordo-vivo);
           border-radius:6px; padding:5px 11px; font-size:var(--t-normale);
           font-family:inherit; cursor:pointer; }
  button:hover { background:var(--bordo-vivo); }
  button.primario { background:var(--ok-fondo); border-color:var(--ok-bordo); color:var(--ok);
                    font-weight:600; }
  button.primario:hover { background:var(--ok-fondo); filter:brightness(1.35); }
  button.pericolo, button.sblocca { background:transparent; border-color:var(--male-bordo);
                                    color:var(--male); }
  button.pericolo:hover, button.sblocca:hover { background:var(--male-fondo); }
  /* ⭐ Un pulsante SPENTO si vede che è spento (28/08). Prima "disabled" era
     solo un pulsante che non reagiva al click: identico agli altri, quindi si
     insisteva a premerlo pensando che la pagina fosse bloccata. La freccia del
     mouse lo dice anche prima del colore.
     ⚠️ Vale per i pulsanti d'azione in testa alla pagina, non per gli
     interruttori (`.int2`), dove "disabled" segna il lato già scelto: lì
     smorzarlo direbbe il contrario di quello che è. */
  .testa-azioni button:disabled, .testa-azioni button:disabled:hover {
    opacity:.45; cursor:not-allowed; filter:none; }
  /* Pulsanti raggruppati per significato, con un vuoto fra un gruppo e l'altro. */
  .azioni { display:flex; flex-wrap:wrap; gap:var(--s1) var(--s4); }
  .gruppo { display:flex; flex-wrap:wrap; gap:var(--s1); align-items:center; }
  /* ⭐ I comandi di UNA riga stanno su UNA riga (25/08): andando a capo la riga
     diventava alta il doppio e l'ingranaggio finiva staccato dal suo device.
     Con quaranta istanze e' il doppio di pagina da scorrere per niente. */
  #tab-istanze .azioni .gruppo { flex-wrap:nowrap; }

  /* ⭐ Interruttore a due meta' (Spento | Acceso): la meta' in evidenza dice
     com'e' messo adesso, l'altra e' l'unica premibile. Due pulsanti separati
     costringerebbero a leggere da un'altra parte per sapere lo stato — e
     nella lista delle istanze lo stato del telefono e' la cosa che si guarda
     per prima. Un solo blocco, quindi, largo quanto una parola sola. */
  .int2 { display:inline-flex; border:1px solid var(--bordo-vivo);
          border-radius:6px; overflow:hidden; }
  .int2 button { border:none; border-radius:0; background:transparent;
                 color:var(--testo-3); padding:5px 10px; }
  .int2 button + button { border-left:1px solid var(--bordo-vivo); }
  .int2 button:not(:disabled):hover { background:var(--rialzo); color:var(--testo); }
  /* La meta' accesa e' colorata come lo stato che rappresenta: spento =
     smorzato (e' una scelta, non un guasto), acceso = verde. */
  .int2 .int-off.qui { background:var(--rialzo); color:var(--testo);
                       font-weight:600; }
  .int2 .int-on.qui  { background:var(--ok-fondo); color:var(--ok);
                       font-weight:600; }
  /* "Disabilitato" qui vuol dire "e' gia' cosi'", non "non si puo'": resta
     leggibile, non sbiadito, e il cursore dice solo che non c'e' da cliccare. */
  .int2 button:disabled { cursor:default; }

  /* Solo la rotella, un po' piu' grande: e' l'unica porta verso la pagina del
     device e la si cerca con l'occhio, non leggendo. La parola "Impostazioni"
     accanto raddoppiava la larghezza della colonna per non dire niente di piu'. */
  /* (il selettore ripete "a.bottone" perche' quella regola sta piu' in basso
     nel foglio e altrimenti vincerebbe lei su misura e spaziatura) */
  a.bottone.ingranaggio, .ingranaggio { font-size:18px; line-height:1.1;
                                        padding:3px 9px; }

  .vuoto { padding:var(--s6); text-align:center; color:var(--testo-2); }
  .vuoto b { display:block; color:var(--testo); font-size:var(--t-grande);
             margin-bottom:var(--s2); }
  footer { padding:var(--s3) 0 var(--s5); color:var(--testo-3);
           font-size:var(--t-piccolo); }
  /* Finestrella per guardare il device: sfondo scuro + riquadro al centro */
  .velo { position:fixed; inset:0; background:rgba(0,0,0,.7); display:none;
          align-items:center; justify-content:center; z-index:10; padding:var(--s5); }
  .velo.aperto { display:flex; }
  /* ⭐ Tre fasce: testa e piede FISSI, corpo che scorre. Prima la finestra
     cresceva a piacere e il pulsante "Chiudi" finiva fuori dallo schermo. */
  .finestra { background:var(--superficie); border:1px solid var(--bordo);
              border-radius:10px; max-width:100%; max-height:100%;
              display:flex; flex-direction:column; min-height:0; }
  .f-testa { flex:none; padding:var(--s3) var(--s4);
             border-bottom:1px solid var(--bordo); }
  .f-corpo { flex:1 1 auto; overflow:auto; padding:var(--s4); min-height:0; }
  .f-piede { flex:none; padding:var(--s3) var(--s4); border-top:1px solid var(--bordo);
             display:flex; flex-wrap:wrap; gap:var(--s2); align-items:center;
             background:var(--fondo); border-radius:0 0 10px 10px; }
  .finestra h2 { margin:0; font-size:var(--t-grande); font-weight:600; }
  .finestra .nota { margin:var(--s1) 0 0; color:var(--testo-2); font-size:var(--t-piccolo); }
  .f-corpo .nota { margin:0 0 var(--s2); }
  /* Lo schermo del telefono resta nero in tutti e due i temi: non e' una
     superficie della webapp, e' un apparecchio spento. */
  .finestra img { display:block; max-height:70vh; border-radius:6px; background:#000; }
  .finestra .errore { color:var(--male); font-size:var(--t-normale); padding:var(--s4) 0; }
  /* Larghezza secondo il contenuto: il Database prende quasi tutto lo schermo,
     il Telefono no. */
  .f-larga  { width:92vw; }
  .f-media  { width:min(820px, 92vw); }

  /* ⭐ COSA DEVE FARE: la coda del device -----------------------------------
     Una riga = un'operazione. L'ora a sinistra in colonna dritta (cifre della
     stessa larghezza), la frase al centro, lo stato a destra: si scorre con
     l'occhio in verticale, che e' come si legge un programma di lavoro. */
  .task-gruppo { border:1px solid var(--bordo); border-radius:8px;
                 margin-bottom:var(--s3); overflow:hidden; }
  /* La testata e' la maniglia che apre e chiude la sessione: dev'essere
     evidentemente cliccabile, e la freccetta deve dire da che parte sta. */
  .task-testa { background:var(--rialzo); padding:6px var(--s3);
                font-weight:600; font-size:var(--t-normale);
                cursor:pointer; user-select:none; list-style:none;
                display:flex; align-items:center; gap:var(--s2);
                flex-wrap:wrap; }
  .task-testa::-webkit-details-marker { display:none; }
  .task-testa::before { content:'\25B8'; color:var(--testo-3); flex:none;
                        transition:transform .12s; }
  details.task-gruppo[open] > .task-testa::before { transform:rotate(90deg); }
  .task-testa:hover { background:var(--bordo); }
  .task-testa .nota { margin-left:auto; }
  .task-riga { display:flex; align-items:center; gap:var(--s3); flex-wrap:wrap;
               padding:5px var(--s3); border-top:1px solid var(--bordo); }
  .task-ora { font-variant-numeric:tabular-nums; color:var(--testo-2);
              font-size:var(--t-piccolo); flex:none; width:44px; }
  .task-dice { flex:1 1 220px; min-width:0; }
  .task-quando { flex:none; }
  .task-perche { flex-basis:100%; color:var(--male); font-size:var(--t-piccolo);
                 padding-left:56px; }
  .task-azioni { flex:none; display:flex; gap:var(--s1); }
  .pill.grigio { background:var(--rialzo); color:var(--testo-3); }

  /* ⭐ IL COSTRUTTORE DI SEQUENZE (Task Builder) --------------------------
     Un passo si legge come una frase numerata, col comando vero in piccolo di
     fianco. Prima ogni riga era il JSON grezzo del comando: chi non ha scritto
     il codice non poteva capire cosa avrebbe fatto la macro. */
  .guida-tb { margin:4px 0 10px; padding-left:20px; color:var(--testo-2);
              font-size:var(--t-piccolo); line-height:1.6; }
  .guida-tb b { color:var(--testo); }
  ol.passi { margin:0; padding:0; list-style:none; counter-reset:passo; }
  li.passo { border:1px solid var(--bordo); border-radius:6px; padding:5px 8px;
             margin-bottom:5px; background:var(--fondo); }
  li.passo.con-buco { border-color:var(--bordo-scelto); }
  .passo-testa { display:flex; align-items:center; gap:var(--s2); }
  .passo-n { flex:none; width:20px; height:20px; border-radius:50%;
             background:var(--rialzo); color:var(--testo-2);
             font-size:var(--t-piccolo); display:flex; align-items:center;
             justify-content:center; }
  .passo-dice { flex:1 1 auto; min-width:0; }
  .passo-azioni { flex:none; display:flex; gap:3px; }
  /* Il comando vero resta a portata di mano ma non ruba la scena: serve il
     giorno che qualcosa non va, non mentre si costruisce. */
  .passo-grezzo { display:block; margin-top:2px; opacity:.55;
                  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  button.mini { padding:1px 6px; font-size:var(--t-piccolo); }
  .gruppi-passi { display:flex; flex-wrap:wrap; gap:var(--s2) var(--s4);
                  margin-top:var(--s3); }
  .gruppo-passi { display:flex; align-items:center; gap:4px;
                  border:1px dashed var(--bordo); border-radius:6px;
                  padding:4px 8px; }
  .barra-salva { display:flex; gap:var(--s2); align-items:center;
                 margin-top:var(--s3); }
  /* Il player: sta suonando o no. Verde solo quando la musica va davvero. */
  .player-riga { padding:6px 0; }
  .player-on  { color:var(--ok); font-weight:600; }
  .player-off { color:var(--testo-2); }

  /* ⭐ Le domande e gli avvisi: stessa finestra di tutto il resto ------------
     Prima erano alert()/confirm()/prompt() del browser: riquadri grigi con
     scritto "127.0.0.1:8080 dice", fuori tema e fuori posto. Riusano .velo e
     .finestra, quindi seguono da soli tema chiaro/scuro e densita'. */
  .velo-dialogo { z-index:20; }              /* sopra le altre finestre */
  .f-dialogo { width:min(440px, 92vw); }
  /* I "a capo" scritti nel messaggio si vedono davvero: i testi sono scritti
     a paragrafi (riga vuota fra un'idea e l'altra) e vanno letti cosi'. */
  .d-testo { margin:0; white-space:pre-line; line-height:1.5; }
  .d-nota { margin:var(--s3) 0 0; color:var(--testo-2); font-size:var(--t-piccolo); }
  .d-campo { width:100%; margin-top:var(--s3); box-sizing:border-box; }
  /* Nelle altre finestre i pulsanti stanno a sinistra (Chiudi, Rileggi...);
     in una domanda la risposta si cerca in basso a destra. */
  .d-piede { justify-content:flex-end; }
  /* Una striscia di colore in cima dice il peso della domanda prima di
     leggerla: neutra per un avviso, gialla per un "guarda che...", rossa per
     le cose che non si tornano indietro (spegnere, cancellare, rifare). */
  .f-dialogo .f-testa { border-top:3px solid var(--bordo-vivo);
                        border-radius:10px 10px 0 0; }
  .f-dialogo.d-attenzione .f-testa { border-top-color:var(--attesa); }
  .f-dialogo.d-pericolo   .f-testa { border-top-color:var(--male); }
  /* Schermo ricostruito: i riquadri dei pulsanti disegnati in scala.
     Non e' una foto: e' una mappa cliccabile, e funziona anche dove la foto
     viene nera (le app che proteggono le schermate). */
  .tb { display:flex; gap:16px; align-items:flex-start; }
  .telaio { position:relative; background:#05070a; border:1px solid var(--bordo);
            border-radius:8px; overflow:hidden; flex:none; }
  .box { position:absolute; border:1px solid var(--bordo-scelto); background:rgba(63,110,168,.12);
         color:var(--su-scelto); font-size:10px; line-height:1.1; overflow:hidden;
         cursor:pointer; padding:1px 2px; box-sizing:border-box; }
  .box.click { border-color:var(--ok); background:rgba(74,222,128,.13); color:var(--ok); }
  .box:hover { background:rgba(255,255,255,.22); }
  .box.scelto { border-color:var(--attesa); background:rgba(251,191,36,.25);
                color:var(--su-scelto); }
  .pannello { width:360px; font-size:13px; }
  .pannello pre { background:var(--incasso); border:1px solid var(--bordo); border-radius:6px;
                  padding:9px; font-size:12px; white-space:pre-wrap; color:var(--codice); }
  .pannello .avviso { color:var(--attesa); font-size:12px; }
  .pannello .esito { margin-top:8px; font-size:12px; }
  /* Registratore di macro: la fila di azioni in costruzione */
  .registratore { width:380px; max-height:74vh; overflow:auto; }
  .passi { margin:0 0 8px; padding-left:22px; }
  .passi li { margin-bottom:6px; }
  .passi .azione { color:var(--codice); }
  .passi .buco { color:var(--attesa); }
  .passi .mini { background:none; border:0; color:var(--scelto); cursor:pointer;
                 font-size:11px; padding:0 4px; margin:0; }
  .buco { color:var(--attesa); }
  .extra { margin-top:6px; display:flex; flex-wrap:wrap; gap:4px; align-items:center; }
  .extra select { background:var(--incasso); color:var(--testo); border:1px solid var(--bordo);
                  border-radius:5px; padding:4px 6px; font-size:12px; }
  .extra input { background:var(--incasso); color:var(--testo); border:1px solid var(--bordo);
                 border-radius:5px; padding:4px 6px; font-size:12px; }
  .registratore input[type=text], .registratore input:not([type]) { background:var(--incasso);
      color:var(--testo); border:1px solid var(--bordo); border-radius:5px; padding:4px 6px; }
  /* Editor del database: griglia fitta, come un foglio di calcolo */
  .db { display:flex; gap:12px; align-items:flex-start; }
  .db .lista { width:210px; max-height:76vh; overflow:auto; font-size:13px; }
  .db .lista div { padding:5px 7px; border-radius:5px; cursor:pointer; }
  .db .lista div:hover { background:var(--rialzo); }
  .db .lista div.scelta { background:var(--scelto-fondo); color:var(--su-scelto); }
  .db .lista .conta { color:var(--testo-3); font-size:11px; }
  .db .centro { flex:1; min-width:0; }
  .griglia { max-height:46vh; overflow:auto; border:1px solid var(--bordo); border-radius:6px; }
  .griglia table { border-collapse:collapse; width:auto; min-width:100%; }
  .griglia th, .griglia td { padding:3px 6px; font-size:12px; border:1px solid var(--rialzo);
                             white-space:nowrap; text-transform:none; }
  .griglia th { position:sticky; top:0; background:var(--superficie); cursor:pointer; z-index:1; }
  .griglia th small { display:block; color:var(--testo-3); font-weight:400; font-size:10px; }
  .griglia td.cella:hover { background:var(--rialzo); cursor:text; }
  .griglia td.nullo { color:var(--testo-3); font-style:italic; }
  .griglia td input { width:100%; background:var(--incasso); color:var(--testo);
                      border:1px solid var(--bordo-scelto);
                      border-radius:3px; padding:2px 4px; font-size:12px; }
  .griglia td.salvata { background:var(--ok-fondo); }
  .griglia td.errata { background:var(--male-fondo); }
  /* ⭐ La riga su cui stai lavorando resta accesa anche dopo che il mouse se
     n'e' andato: in un foglio largo, tornando con gli occhi da destra a
     sinistra si perde la riga, ed e' cosi' che si corregge la cella sbagliata. */
  .griglia tr.sel td { background:var(--scelto-fondo); }
  .griglia tr.sel td.cella:hover { background:var(--scelto-fondo); filter:brightness(1.2); }
  /* La colonna del numero di riga e' servizio, non dato: stretta e grigia. */
  .griglia td.n-riga, .griglia th.n-riga { width:1%; color:var(--testo-3);
                       background:var(--fondo); text-align:right; font-style:normal; }
  /* Appiglio per allargare una colonna: 6px sul bordo destro dell'intestazione.
     Sta DENTRO il <th> (position:relative) cosi' non serve nessuna misura
     calcolata a mano, che con la testata appiccicata in alto si sfaserebbe.
     (Il <th> e' gia' position:sticky, che basta a fare da riferimento.) */
  .griglia th .tira { position:absolute; top:0; right:0; width:6px; height:100%;
                      cursor:col-resize; user-select:none; }
  .griglia th .tira:hover { background:var(--bordo-scelto); }
  .griglia.in-tiro { cursor:col-resize; user-select:none; }
  .sql { width:100%; box-sizing:border-box; background:var(--incasso); color:var(--codice);
         border:1px solid var(--bordo); border-radius:6px; padding:8px; font-size:13px;
         font-family:ui-monospace, monospace; min-height:70px; }
  .suggeritore { position:absolute; background:var(--superficie); border:1px solid var(--bordo-scelto);
                 border-radius:6px; font-size:12px; z-index:20; max-height:180px;
                 overflow:auto; display:none; }
  .suggeritore div { padding:3px 9px; cursor:pointer; }
  .suggeritore div.scelto, .suggeritore div:hover { background:var(--scelto-fondo); }

/* ============================================================
   GUSCIO: barra in alto, menu a pannello, schede.
   Tutto quello che sta sopra le pagine. 📄 _file_di_lavoro/pagine.md
   ============================================================ */
.barra-alto { background:var(--superficie); border-bottom:1px solid var(--bordo);
              position:sticky; top:0; z-index:6; }
.barra-dentro { display:flex; align-items:center; gap:var(--s3);
                height:44px; }
.barra-dentro .spinta { margin-left:auto; }
.briciola { color:var(--testo-2); font-size:var(--t-piccolo); }

/* L'icona a tre righe, disegnata con tre <span>: nessuna icona scaricata. */
.ham { display:flex; flex-direction:column; justify-content:center; gap:4px;
       width:32px; height:28px; padding:0 6px; background:transparent;
       border-color:transparent; }
.ham span { display:block; height:2px; background:var(--testo-2);
            border-radius:2px; }
.ham:hover { background:var(--rialzo); }
.ham:hover span { background:var(--testo); }

.logo { display:flex; align-items:center; gap:var(--s2); color:var(--testo);
        text-decoration:none; }
.logo svg { fill:currentColor; color:var(--su-scelto); }
.logo-testo { font-size:var(--t-piccolo); font-weight:700; letter-spacing:2.4px; }

/* Il pannello sta SOPRA la pagina: se la spostasse, la tabella che stai
   leggendo ballerebbe a ogni apertura. */
.velo-menu { position:fixed; inset:0; background:rgba(0,0,0,.55); display:none;
             z-index:8; }
.velo-menu.aperto { display:block; }
.pannello-menu { position:fixed; top:0; left:0; bottom:0; width:230px; z-index:9;
                 background:var(--superficie); border-right:1px solid var(--bordo);
                 transform:translateX(-102%); transition:transform .15s ease;
                 padding:var(--s3) 0; overflow:auto; }
.pannello-menu.aperto { transform:translateX(0); }
.pm-testa { display:flex; align-items:center; justify-content:space-between;
            padding:var(--s2) var(--s4) var(--s4); }
.mini-x { background:transparent; border-color:transparent; color:var(--testo-2);
          font-size:18px; line-height:1; padding:0 6px; }
.pm-voce { display:flex; align-items:center; justify-content:space-between;
           padding:7px var(--s4); color:var(--testo-2); text-decoration:none;
           font-size:var(--t-normale); }
.pm-voce:hover { background:var(--rialzo); color:var(--testo); }
.pm-voce.qui { background:var(--rialzo); color:var(--testo); font-weight:600;
               box-shadow:inset 2px 0 0 var(--scelto); }
.pm-titolo { padding:var(--s4) var(--s4) var(--s1); color:var(--testo-3);
             font-size:11px; letter-spacing:.6px; text-transform:uppercase; }
.pm-dev { font-family:var(--mono); font-size:var(--t-piccolo); }
.pm-vuoto { padding:var(--s2) var(--s4); color:var(--testo-3);
            font-size:var(--t-piccolo); }
.freccia { color:var(--testo-3); }

.pagina { padding-top:var(--s5); padding-bottom:var(--s6); }
/* Titolo a sinistra, i pulsanti della pagina a destra sulla stessa riga: sono
   gesti che si fanno di rado (creare, clonare), quindi non devono rubare la
   riga a quello che si guarda sempre. */
.testa-pagina { margin-bottom:var(--s4); display:flex; align-items:center;
                gap:var(--s3); flex-wrap:wrap; }
.testa-pagina .testa-azioni { margin-left:auto; display:flex; gap:var(--s2); }
/* ⭐ GLI AVVISI ACCANTO AL TITOLO (25/08). Un riquadro definito, con la sua ×:
   dice cosa sta succedendo senza fermare le mani, e resta li' finche' non lo
   chiudi tu — un avviso che sparisce da solo mentre guardi altrove non l'hai
   letto. Sta nella riga del titolo perche' e' li' che l'occhio torna dopo aver
   cliccato qualcosa in tabella. */
.avvisi-testa:empty { display:none; }
.avvisi-testa { flex:1 1 320px; min-width:0; }
.av-testa { display:flex; align-items:flex-start; gap:var(--s2);
            background:var(--rialzo); border:1px solid var(--bordo);
            border-left:3px solid var(--scelto); border-radius:6px;
            padding:6px var(--s2); font-size:var(--t-piccolo);
            color:var(--testo-2); }
.av-testa.male { border-left-color:var(--male); background:var(--male-fondo);
                 color:var(--male); }
.av-chiudi { margin-left:auto; background:none; border:0; padding:0 2px;
             color:var(--testo-3); cursor:pointer; font-size:15px;
             line-height:1; }
.av-chiudi:hover { background:none; color:var(--testo); }
/* Una lista semplice di voci (istanze da spuntare, indirizzi IP, provider):
   righe leggibili senza fare una tabella per tre parole. */
.lista-semplice .voce-lista { display:flex; align-items:center; gap:var(--s2);
                              padding:var(--s2) 0;
                              border-bottom:1px solid var(--bordo); }
.lista-semplice .voce-lista:last-child { border-bottom:none; }
.riga-campi { display:flex; gap:var(--s3); flex-wrap:wrap; }
.riga-campi label { flex:1 1 180px; }
.testa-pagina h1 { margin:0; font-size:20px; font-weight:600; letter-spacing:-.2px; }
.testa-pagina .una-riga { margin:var(--s2) 0 0; color:var(--testo-2); }
.spiega { margin-top:var(--s2); padding:var(--s3); background:var(--superficie);
          border:1px solid var(--bordo); border-radius:var(--raggio);
          color:var(--testo-2); font-size:var(--t-piccolo); max-width:90ch; }

/* Un testo che si clicca resta un testo: non gli si mette un bordo da
   pulsante, altrimenti torniamo alla fila di nove pulsanti uguali. */
button.link { background:none; border:0; padding:0; color:var(--scelto);
              cursor:pointer; font-size:inherit; font-family:inherit;
              text-decoration:underline; text-underline-offset:2px; }
button.link:hover { background:none; color:var(--scelto); }
/* Una parola rossa si vede da lontano; il racconto del guasto sta nel modale,
   insieme ai pulsanti che lo sistemano. */
button.alert { background:transparent; border:0; padding:2px 0; color:var(--male);
               font-weight:600; cursor:pointer; font-size:var(--t-piccolo); }
button.alert:hover { background:none; text-decoration:underline; }
/* Un link che deve sembrare un pulsante (⚙ Impostazioni). */
a.bottone { display:inline-block; background:var(--rialzo); color:var(--testo);
            border:1px solid var(--bordo-vivo); border-radius:6px;
            padding:5px 11px; font-size:var(--t-normale); text-decoration:none; }
a.bottone:hover { background:var(--bordo-vivo); }

/* Tabella dei dati (Dettagli, Riepilogo): etichetta a sinistra, valore a
   destra in carattere fisso, e il valore si copia con un click. */
table.dati { width:100%; border-collapse:collapse; }
table.dati th { width:190px; text-align:left; color:var(--testo-2);
                font-weight:400; text-transform:none; letter-spacing:0;
                font-size:var(--t-normale); background:transparent;
                padding:5px var(--s3) 5px 0; border-bottom:1px solid var(--bordo); }
table.dati td { padding:5px 0; border-bottom:1px solid var(--bordo); }
.copia { font-family:var(--mono); cursor:pointer; border-radius:4px;
         padding:1px 4px; }
.copia:hover { background:var(--rialzo); }
.copia.copiato { background:var(--ok-fondo); color:var(--ok); }

/* Schede (device, database): sono una scelta di vista, non comandi. */
.schede { display:flex; flex-wrap:wrap; gap:var(--s1); margin:var(--s4) 0 0;
          border-bottom:1px solid var(--bordo); }
.scheda { background:transparent; border:0; border-bottom:2px solid transparent;
          border-radius:0; color:var(--testo-2); padding:7px var(--s3);
          margin-bottom:-1px; }
.scheda:hover { background:var(--rialzo); color:var(--testo); }
.scheda.qui { color:var(--testo); font-weight:600; border-bottom-color:var(--scelto); }
.pannello-scheda { padding:var(--s4); border-radius:0 0 var(--raggio) var(--raggio); }

/* Testa della pagina device */
.testa-device { display:flex; align-items:flex-start; gap:var(--s4);
                flex-wrap:wrap; }
.testa-device h1 { margin:var(--s1) 0 0; font-size:20px; font-weight:600; }
.testa-device .azioni { margin-left:auto; align-items:center; }
.indietro { color:var(--testo-2); text-decoration:none; font-size:var(--t-piccolo); }
.indietro:hover { color:var(--testo); }

/* Riepilogo: istantanea a sinistra, dati a destra */
.riep { display:flex; gap:var(--s5); flex-wrap:wrap; align-items:flex-start; }
.riep-foto { flex:none; width:260px; }
.telaio-foto { background:#05070a; border:1px solid var(--bordo); border-radius:8px;
               min-height:300px; display:flex; align-items:center;
               justify-content:center; overflow:hidden; }
.telaio-foto img { display:none; max-width:100%; max-height:60vh; }
.riep-vuoto { color:var(--testo-3); font-size:var(--t-piccolo); }
.riep-sotto { display:flex; align-items:center; gap:var(--s2); margin-top:var(--s2); }
.riep .dati, .riep table.dati { flex:1; min-width:280px; }
/* Il pulsantino che gira mentre scatta: e' l'unica animazione oltre
   all'allarme, e dura quanto l'attesa. */
.gira { width:28px; height:28px; font-size:15px; line-height:1; padding:0;
        display:inline-flex; align-items:center; justify-content:center; }
/* ⭐ 2026-08-22: la rotella e "Rileggi" alti uguali. Erano 28px e ~20px
   affiancati: due pulsanti che fanno la stessa cosa (rifare la lettura) e
   sembravano di due famiglie diverse. */
.col-testa .gira, .col-testa .mini { height:28px; }
.col-testa .mini { display:inline-flex; align-items:center; padding:0 10px; }
.gira.girando { animation:ruota .9s linear infinite; color:var(--scelto); }
@keyframes ruota { to { transform:rotate(360deg); } }

.in-arrivo { color:var(--testo-2); }
.in-arrivo b { color:var(--testo); font-size:var(--t-grande); }

/* Pagina Database: la griglia sta in pagina, non piu' dentro una finestra. */
.db .lista { padding:var(--s2); max-height:70vh; }
.db .centro { flex:1; min-width:0; }
.griglia { max-height:56vh; }

/* ============================================================
   TEMA CHIARO. Stesse variabili, altri valori: nient'altro del CSS cambia.
   Tre valori possibili (automation.md §4.0): automatico (qui sotto,
   `prefers-color-scheme`), oppure chiaro/scuro FORZATI con data-tema, che
   vince sempre sul sistema.
   ⚠️ Restano in giro dei colori scritti a mano (griglia del database, telaio
   dello schermo): si sistemano con le rifiniture. 📄 pagine.md §7
   ============================================================ */
@media (prefers-color-scheme: light) {
  :root:not([data-tema]) {   /* tavolozza-inizio */
    --fondo:#f7f8fa; --superficie:#ffffff; --rialzo:#eef1f5;
    --bordo:#dfe3ea; --bordo-vivo:#c3cad6;
    --testo:#1b1f27; --testo-2:#5b6472; --testo-3:#8b93a1;
    --ok:#15803d;  --ok-fondo:#dcfce7;  --ok-bordo:#86c9a4;
    --attesa:#a16207; --attesa-fondo:#fef3c7;
    --male:#b91c1c; --male-fondo:#fee2e2;  --male-bordo:#e9a8a8;
    --scelto:#0369a1; --scelto-fondo:#e0f2fe;
    --incasso:#ffffff; --bordo-scelto:#7ba7d8;
    --su-scelto:#0c3a63; --codice:#166534; --bat-lum:38%;
  --su-foto:#ffffff;
  }/* tavolozza-fine */
}
:root[data-tema="chiaro"] {   /* tavolozza-inizio */
  --fondo:#f7f8fa; --superficie:#ffffff; --rialzo:#eef1f5;
  --bordo:#dfe3ea; --bordo-vivo:#c3cad6;
  --testo:#1b1f27; --testo-2:#5b6472; --testo-3:#8b93a1;
  --ok:#15803d;  --ok-fondo:#dcfce7;  --ok-bordo:#86c9a4;
  --attesa:#a16207; --attesa-fondo:#fef3c7;
  --male:#b91c1c; --male-fondo:#fee2e2;  --male-bordo:#e9a8a8;
  --scelto:#0369a1; --scelto-fondo:#e0f2fe;
  --incasso:#ffffff; --bordo-scelto:#7ba7d8;
  --su-scelto:#0c3a63; --codice:#166534; --bat-lum:38%;
  --su-foto:#ffffff;
}/* tavolozza-fine */
/* Qui c'erano due eccezioni per il tema chiaro (pulsante sotto il mouse e
   colore del logo), scritte a mano. Non servono piu': adesso quei due punti
   prendono `--bordo-vivo` e `--su-scelto`, che nella tavolozza chiara sono
   gia' i valori giusti. Un'eccezione in meno e' un posto in meno da
   ricordare quando si tocca la tavolozza. */

/* ============================================================
   QUANDO SI ASPETTA: righe grigie della forma giusta (*skeleton*), non la
   scritta "Carico...". ⭐ Non e' un vezzo: la scritta e' un'altra cosa da
   leggere, e quando arrivano i dati la pagina salta perche' cambia altezza.
   Le barre invece hanno gia' l'ingombro delle righe vere, quindi non salta
   niente e la pagina *sembra* piu' veloce a parita' di secondi.
   ============================================================ */
.osso { display:block; height:10px; border-radius:5px; background:var(--rialzo);
        animation:respira 1.4s ease-in-out infinite; }
.osso + .osso { margin-top:6px; }
.osso.corto { width:35%; } .osso.medio { width:60%; } .osso.lungo { width:85%; }
@keyframes respira { 50% { opacity:.42; } }
/* Chi ha chiesto "niente animazioni" non le riceve: resta il grigio fermo. */
@media (prefers-reduced-motion: reduce) {
  .osso, .dot.allarme, .ba-dentro.ignota { animation:none; }
  .ba-dentro { transition:none; }
}

/* Esito di un salvataggio: verde se e' andata, rosso se no. I colori si
   prendono dalle variabili, quindi valgono anche in tema chiaro (altrove
   ci sono ancora colori scritti a mano: si sistemano con le rifiniture). */
.esito { margin-top:var(--s3); font-size:var(--t-piccolo); color:var(--testo-2); }
.esito.ok { color:var(--ok); }
.esito.male { color:var(--male); }

/* ============================================================
   DENSITA' COMPATTA. Come il tema: si cambiano i mattoni, non il resto
   del CSS. Serve a vedere piu' righe insieme quando le istanze saranno
   quaranta invece di due; il testo pero' NON scende sotto i 12px, perche'
   una tabella che non si legge non fa risparmiare niente.
   ============================================================ */
:root[data-densita="compatta"] {
  --s3: 6px; --s4: 10px; --s5: 16px; --s6: 22px;
  --riga: 26px;
  --t-grande: 14px; --t-normale: 12px; --t-piccolo: 11px;
}

/* I pulsanti di una scheda stanno in fondo al riquadro, come il piede di una
   finestra: stesso posto di prima, senza il "Chiudi" (sei dentro la scheda). */
.barra-azioni { display:flex; flex-wrap:wrap; gap:var(--s2); align-items:center;
                margin-top:var(--s4); padding-top:var(--s3);
                border-top:1px solid var(--bordo); }
.riep-destra { flex:1; min-width:280px; }
/* Dentro una scheda il Task Builder non ha piu' il fondo di una finestra */
.pannello-scheda .tb { flex-wrap:wrap; }

/* ============================================================
   COSA VEDE UN'APP. Due sole regole di lettura:
   1) il verdetto si legge PRIMA del numero (un "3 su 26" da solo non dice a
      nessuno se e' un buon risultato), quindi il riquadro grande ha la frase
      accanto alla cifra;
   2) il segnale si distingue senza leggere: il colore E' il simbolo (✓/✗),
      perche' un rosso da solo non basta a chi distingue male i colori.
   ============================================================ */
.verdetto { display:flex; align-items:center; gap:var(--s4); margin-top:var(--s3);
            padding:var(--s3) var(--s4); border-radius:var(--raggio);
            border:1px solid var(--bordo); background:var(--rialzo); }
.verdetto.bene { background:var(--ok-fondo);   border-color:var(--ok-bordo); }
.verdetto.male { background:var(--male-fondo); border-color:var(--male-bordo); }
.verdetto-num { font-size:26px; font-weight:700; line-height:1; flex:none;
                font-variant-numeric:tabular-nums; }
.verdetto-num span { font-size:var(--t-piccolo); font-weight:400;
                     color:var(--testo-2); }
.verdetto.bene .verdetto-num { color:var(--ok); }
.verdetto.male .verdetto-num { color:var(--male); }

.ril-gruppo { margin-top:var(--s4); border:1px solid var(--bordo);
              border-radius:var(--raggio); overflow:hidden; }
.ril-testa { padding:var(--s2) var(--s4); background:var(--fondo);
             border-bottom:1px solid var(--bordo); }
.ril-testa .nota { margin-left:var(--s2); }
.ril-gruppo td { vertical-align:top; }
.ril-gruppo td:last-child { max-width:320px; }
.ril-segno { width:24px; color:var(--ok); font-weight:700; text-align:center; }
.ril-male .ril-segno { color:var(--male); }
/* La riga col problema si riconosce dal bordo, come l'istanza bloccata in
   Home: stesso linguaggio in tutta la webapp. */
.ril-male td:first-child { box-shadow:inset 3px 0 0 var(--male); }
.ril-male .titolo-riga { color:var(--male); }

/* ============================================================
   RICONTROLLA I PULSANTI. Tre stati, non due: verde "a posto", rosso
   "sparito" e ⭐ GRIGIO "non controllato" — i passi dopo quello rotto, dove
   non siamo mai arrivati. Dipingerli di verde sarebbe la bugia peggiore,
   perche' e' quella che fa chiudere il caso.
   ============================================================ */
.ric-ok     .ril-segno { color:var(--ok); font-weight:700; }
.ric-male   .ril-segno { color:var(--male); font-weight:700; }
.ric-grigio .ril-segno { color:var(--testo-3); font-weight:700; }
.ric-male td:first-child { box-shadow:inset 3px 0 0 var(--male); }
.ric-grigio td { color:var(--testo-3); }
.verdetto-riga.bene   { background:var(--ok-fondo); }
.verdetto-riga.male   { background:var(--male-fondo); }
.verdetto-riga.attesa { background:var(--attesa-fondo); }

/* ============================================================
   SCHEDA ORARI. Due colonne affiancate: a sinistra i campi, a destra le
   stesse scelte scritte a parole. Non e' decorazione: il senso della scheda
   e' vedere la CONSEGUENZA mentre si cambia il numero, e una conseguenza che
   sta sotto la piega dello schermo non la legge nessuno.
   ============================================================ */
.or-card { border:1px solid var(--bordo); border-radius:var(--raggio);
           padding:var(--s4); margin-bottom:var(--s4);
           background:var(--superficie); }
.or-testa { display:flex; align-items:center; gap:var(--s3); flex-wrap:wrap;
            padding-bottom:var(--s3); border-bottom:1px solid var(--bordo); }
.or-testa .or-int { margin-left:auto; font-size:var(--t-piccolo);
                    color:var(--testo-2); }
.or-corpo { display:flex; gap:var(--s5); flex-wrap:wrap; margin-top:var(--s4); }
.or-campi { flex:1; min-width:320px; }
.or-parole { flex:1; min-width:300px; background:var(--fondo);
             border:1px solid var(--bordo); border-radius:var(--raggio);
             padding:var(--s3) var(--s4); }
.or-riga { margin-bottom:var(--s4); }
.or-riga > label { display:block; font-size:var(--t-piccolo);
                   color:var(--testo-2); margin-bottom:4px; }
.or-riga input[type="number"] { width:70px; }
/* ⭐ LA ⓘ (24/08): le spiegazioni non stanno in pagina, stanno qui dentro.
   Deve leggersi come un pulsante piccolo e discreto — se pesasse come gli
   altri, tornerebbe a essere il rumore che si voleva togliere. */
.info { width:17px; height:17px; padding:0; border-radius:50%;
        border:1px solid var(--bordo); background:var(--rialzo);
        color:var(--testo-3); font-size:11px; font-weight:700;
        font-style:italic; line-height:15px; cursor:help;
        vertical-align:middle; margin-left:5px; flex:none; }
.info:hover { color:var(--testo); border-color:var(--testo-3); }

/* Il riquadro "Adesso: ..." sotto la tendina del modello: un cartello, non
   una riga di testo. La barretta gialla dice "guarda qui prima di salvare";
   niente rosso, perche' non e' un guasto — e' com'e' fatto adesso. */
.cartello { background:var(--rialzo); border:1px solid var(--bordo);
            border-left:3px solid var(--attesa); border-radius:6px;
            padding:8px var(--s3); margin:0 0 var(--s3);
            font-size:var(--t-piccolo); line-height:1.5; }

.or-gio { display:inline-flex; align-items:center; gap:3px; margin-right:var(--s3);
          font-size:var(--t-piccolo); color:var(--testo-2); }
.or-pesi { display:flex; gap:var(--s3); flex-wrap:wrap; }
.or-peso { display:flex; flex-direction:column; gap:2px;
           font-size:var(--t-piccolo); color:var(--testo-2); }
.or-peso input { width:56px; }
/* Il % attaccato alla casella: e' l'unita' di misura del numero che sta li',
   non una nota a parte. */
.or-cassa { display:inline-flex; align-items:center; gap:3px; }
.or-unita { color:var(--testo-3); }
.or-titolo { font-size:var(--t-piccolo); color:var(--testo-3);
             text-transform:uppercase; letter-spacing:.6px; margin-bottom:var(--s2); }
.or-frasi { margin:0 0 var(--s4); padding-left:18px; }
.or-frasi li { margin-bottom:6px; color:var(--testo-2); line-height:1.45; }
.or-frasi li b { color:var(--testo); }
.or-esempio { width:100%; border-collapse:collapse; }
.or-esempio td { padding:3px var(--s3) 3px 0; border-bottom:1px solid var(--bordo); }

/* ============================================================
   ⭐ CREDENZIALI (promemoria cifrato). Sta CHIUSA di suo: e' la cosa che si
   apre una volta ogni tanto, non quella che si guarda tutti i giorni - e una
   password non deve stare a video per il solo fatto di aver aperto la scheda.
   ============================================================ */
.cred { margin-top:var(--s3); border-top:1px solid var(--bordo);
        padding-top:var(--s3); }
.cred > summary { cursor:pointer; font-size:var(--t-piccolo);
                  color:var(--testo-2); }
.cred > summary:hover { color:var(--testo); }
.cred-riga { display:flex; align-items:center; gap:var(--s3); padding:3px 0;
             border-bottom:1px solid var(--bordo); }
.cred-campo { min-width:110px; font-size:var(--t-piccolo); color:var(--testo-2); }
.cred-val { font-family:var(--mono); flex:1; word-break:break-all; }
/* I pallini non si selezionano col mouse: copiarli e incollarli altrove
   sarebbe una copia di niente, ma sembrerebbe la password. */
.cred-val.segreto { letter-spacing:2px; user-select:none; color:var(--testo-2); }
.cred-val.rotto { color:var(--male); font-family:inherit;
                  font-size:var(--t-piccolo); }

/* ============================================================
   ⭐ PAGINA SEQUENZE. Un riquadro per APP, non per telefono: la forma della
   pagina e' gia' meta' della spiegazione. Dentro ogni riquadro, una tabella
   con le sequenze di quell'app.
   ============================================================ */
.riepilogo-seq { margin-bottom:var(--s4); }
.tot-seq { display:flex; gap:var(--s6); align-items:baseline;
           flex-wrap:wrap; }
.tot-uno { display:flex; flex-direction:column; gap:2px; }
/* Il numero grande e' l'unica cosa che si legge da lontano: sotto, piccola,
   la parola che dice cosa vuol dire. Un numero senza parola non si interpreta. */
.num-grande { font-size:var(--t-grande); font-family:var(--mono);
              font-variant-numeric:tabular-nums; }
.num-grande.bene   { color:var(--ok); }
.num-grande.attesa { color:var(--attesa); }
.num-grande.male   { color:var(--male); }
.num-grande.neutro { color:var(--testo-2); }

.seq-app { margin-bottom:var(--s4); }
.seq-testa { display:flex; align-items:baseline; gap:var(--s3);
             flex-wrap:wrap; margin-bottom:var(--s3);
             border-bottom:1px solid var(--bordo); padding-bottom:var(--s2); }
.seq-testa h2 { margin:0; font-size:var(--t-grande); }
.seq-testa .spinta { margin-left:auto; }

.tab-seq { width:100%; }
.tab-seq .c-seq-nome   { width:46%; }
.tab-seq .c-seq-azioni { width:16%; }
.tab-seq .c-seq-coppia { width:24%; }
.tab-seq .c-seq-azione { width:14%; text-align:right; white-space:nowrap; }
.seq-buchi { margin-top:2px; }

/* ⭐ IL PALLINO DI STATO (2026-08-22, richiesta dell'utente). Verde = si puo'
   usare, giallo = in prova, rosso = c'e' qualcosa che la ferma. Sostituisce
   una pillola con la parola scritta PIU' una riga di spiegazione sotto: in un
   elenco quella spiegazione si legge una volta e poi e' rumore, quindi adesso
   sta nel titolo che compare col mouse. */
.pallino { display:inline-block; width:9px; height:9px; border-radius:50%;
           margin-right:7px; vertical-align:middle; cursor:help; }
.pallino.bene   { background:var(--ok); }
.pallino.attesa { background:var(--attesa); }
.pallino.male   { background:var(--male); }
.pallino.neutro { background:var(--testo-3); }
/* I due simboli in fondo alla riga: matita (apri) e ingranaggio (impostazioni).
   Grandi abbastanza da cliccarli, silenziosi finche' non ci passi sopra. */
.mini-i { display:inline-flex; align-items:center; justify-content:center;
          width:28px; height:28px; margin:0 0 0 4px; padding:0; font-size:15px;
          line-height:1; border:1px solid var(--bordo);
          border-radius:var(--raggio); background:var(--rialzo);
          color:var(--testo-2); text-decoration:none; cursor:pointer; }
.mini-i:hover { color:var(--scelto); border-color:var(--scelto); }
.seq-ecc { display:flex; align-items:center; gap:8px; flex-wrap:wrap;
           margin:6px 0; }
.seq-ecc > .nota { min-width:210px; }

/* La manopola a tre posizioni: un solo pulsante acceso alla volta, come un
   interruttore a scatti. Sostituisce il campo numerico, che prometteva scelte
   (7? 12?) che la pianificazione non usa. */
.seg { display:inline-flex; border:1px solid var(--bordo);
       border-radius:var(--raggio); overflow:hidden; }
.seg-b { padding:5px 12px; font-size:13px; line-height:1.2; border:0;
         border-left:1px solid var(--bordo); background:var(--rialzo);
         color:var(--testo-2); cursor:pointer; }
.seg-b:first-child { border-left:0; }
.seg-b:hover { color:var(--scelto); }
.seg-b.scelto { background:var(--scelto-fondo); color:var(--su-scelto);
                font-weight:600; }

/* Gli stati di una sequenza: gli stessi quattro colori di tutto il resto
   della webapp, cosi' "giallo = si sta aspettando qualcosa" vale ovunque. */
.st-bene   { background:var(--ok-fondo);     color:var(--ok); }
.st-attesa { background:var(--attesa-fondo);  color:var(--attesa); }
.st-male   { background:var(--male-fondo);    color:var(--male); }
.st-neutro { background:var(--rialzo);        color:var(--testo-2); }

/* ============================================================
   ⭐ COSTRUTTORE. In testa le due scelte: l'APP (il soggetto) e il TELEFONO DI
   PROVA (l'ingrediente). Stanno una accanto all'altra e non nascoste in un
   menu: sono la cosa che spiega di chi e' la sequenza.
   ============================================================ */
.costr-testa { margin-bottom:var(--s3); }
/* ⭐ ALLINEATI IN BASSO, non al centro (2026-08-22, osservazione dell'utente).
   Ogni campo ha la sua etichetta SOPRA, quindi e' piu' alto di un pulsante:
   centrandoli, Salva e Svuota finivano a mezza altezza del campo "Nome della
   sequenza" e sembravano appartenere a un'altra riga. */
.costr-scelte { display:flex; align-items:flex-end; gap:var(--s4);
                flex-wrap:wrap; }
.costr-scelte label { display:flex; flex-direction:column; gap:2px;
                      font-size:var(--t-piccolo); color:var(--testo-2); }
.costr-scelte select { min-width:200px; }
.costr-scelte .spinta { margin-left:auto; }
/* I pulsanti alti come i campi accanto: allineati in basso, un pulsante piu'
   basso del campo si legge come "premuto". */
.costr-scelte button { margin:0; }
.testa-riga { display:flex; align-items:baseline; gap:var(--s3); }

/* La coppia nell'elenco delle sequenze e nel Task Builder: "finisce con ...".
   Quando manca si scrive in rosso, perche' e' la cosa che impedisce alla
   sequenza di lavorare — non un dettaglio in piu'. */
.seq-coppia .manca { color:var(--male); }
.costr-scelte #mc-nome { min-width:230px; }

/* ⭐ L'ELENCO CERCABILE DELLE CHIUSURE (2026-08-22). Era una tendina con le
   sole chiusure di quest'app; adesso sono quelle di tutte, perche' una
   sequenza puo' finire su un'app diversa da quella con cui e' cominciata.
   Con l'elenco lungo serve una riga di ricerca, come su qualunque sito. */
.ch-cerca { display:flex; align-items:center; gap:var(--s3);
            margin-bottom:var(--s2); flex-wrap:wrap; }
.ch-cerca input { min-width:260px; }
.ch-lista { border:1px solid var(--bordo); border-radius:var(--raggio);
            max-height:260px; overflow:auto; }
.ch-riga { display:flex; align-items:center; gap:var(--s2);
           padding:var(--s2) var(--s3); cursor:pointer;
           border-bottom:1px solid var(--bordo); }
.ch-riga:last-child { border-bottom:0; }
.ch-riga:hover { background:var(--rialzo); }
.ch-riga.scelta { background:var(--rialzo); }
.ch-riga.scelta b { color:var(--scelto); }

/* ------------------------------------------------------------
   ⭐ LE SCHEDE DEL COSTRUTTORE (2026-08-21) — stile RoboTask.
   Prima era tutto in una colonna sola: strumenti, passi, elenco delle
   sequenze salvate, pesi per account e manutenzione. Sono quattro lavori
   diversi, e messi insieme non si distinguevano: la prima cosa che serviva
   era separarli.
   ------------------------------------------------------------ */
.costr-schede { display:flex; gap:2px; margin-bottom:-1px; position:relative;
                z-index:1; flex-wrap:wrap; }
.cs-btn { background:var(--rialzo); color:var(--testo-2);
          border:1px solid var(--bordo); border-bottom-color:transparent;
          border-radius:var(--raggio) var(--raggio) 0 0;
          padding:var(--s2) var(--s4); margin:0; cursor:pointer; }
.cs-btn:hover { color:var(--testo); }
.cs-btn.attiva { background:var(--superficie); color:var(--testo);
                 font-weight:600; border-bottom-color:var(--superficie); }
.costr-scheda > .riquadro { border-radius:0 var(--raggio) var(--raggio) var(--raggio); }
.costr-scheda > .riquadro + .riquadro { border-radius:var(--raggio);
                                        margin-top:var(--s3); }

/* ------------------------------------------------------------
   ⭐ LE TRE COLONNE, e il loro ordine di lettura (scelta dell'utente):
   1 dove PRENDO le cose (lo schermo del telefono)
   2 cosa POSSO fare (gli strumenti)
   3 cosa HO SCRITTO (le azioni della sequenza)
   La terza e' la piu' larga perche' e' il risultato: le altre due servono a
   riempirla. Sotto i 1100px si impilano invece di stringersi: tre colonne
   strette sono peggio di tre righe larghe.
   ------------------------------------------------------------ */
.costr3 { display:grid; grid-template-columns:auto 320px minmax(340px, 1fr);
          gap:var(--s3); align-items:start; }
/* Il respiro dentro i tre riquadri: con il padding normale le scritte
   toccavano l'angolo arrotondato e la colonna sembrava piena anche da vuota. */
.costr3 > .riquadro { border-radius:var(--raggio); margin:0;
                      padding:var(--s4) var(--s4) var(--s5);
                      max-height:80vh; overflow:auto; }
.costr3 > .riquadro > p.nota { margin:0 0 var(--s3); }
.costr3 > .col-schermo { border-radius:0 var(--raggio) var(--raggio) var(--raggio); }
@media (max-width: 1100px) { .costr3 { grid-template-columns:1fr; } }
/* Finestra stretta: le tre colonne fisse si stringono, cosi' al nome
   dell'istanza resta comunque qualcosa. Sotto questa misura il nome vince
   sulle coordinate: senza sapere DI CHI e' la riga, il resto non serve. */
@media (max-width: 1000px) {
  #tab-istanze .c-stato    { width:110px; }
  #tab-istanze .c-task     { width:84px; }
  #tab-istanze .c-telefono { width:150px; }
  #tab-istanze .c-azioni   { width:230px; }
}
.col-testa { display:flex; align-items:center; gap:var(--s2);
             margin:0 0 var(--s3); padding-bottom:var(--s2);
             border-bottom:1px solid var(--bordo); }
.col-testa .spinta { margin-left:auto; }
/* ⭐ Il ▶ che prova TUTTA la sequenza sta accanto al titolo della colonna, non
   fra i pulsanti in fondo: e' il gesto del debug, si cerca guardando l'elenco
   delle azioni. Verde come il ▶ delle singole righe, cosi' si capisce da solo
   che fa la stessa cosa su tutte. */
#mc-prova-tutto { background:none; border:1px solid var(--bordo); border-radius:5px;
                  color:var(--scelto); cursor:pointer; font-size:12px;
                  line-height:1; padding:3px 7px; margin:0; }
#mc-prova-tutto:hover { border-color:var(--scelto); }
/* ⭐ Il flag "in prova" accanto al ▶ (22/08): riguarda la sequenza aperta,
   quindi sta dove la sequenza si scrive. Spento finche' non e' salvata: non
   c'e' ancora niente da promuovere. */
/* "Riservata all'account del dispositivo": titolo sopra e casella sotto, come
   ogni altro campo della riga — non casella-e-poi-scritta, che si leggeva al
   contrario di tutti i suoi vicini. */
.co-riservata { cursor:pointer; }
.co-riservata input { align-self:flex-start; margin:3px 0 0; }
.co-riservata input:disabled { cursor:default; }
.mc-flag { display:inline-flex; align-items:center; gap:4px; cursor:pointer; }
.mc-flag.spenta { opacity:.5; cursor:default; }
#mc-elimina { margin-left:var(--s2); }
/* ⭐ 22/08: la colonna 1 e' larga quanto il telefono, non quanto le sue
   scritte. La misura la scrive il codice quando arriva la foto (`caricaSchermo`);
   qui resta solo il valore di partenza, prima che una foto ci sia. Le scritte
   vanno a capo: e' il telefono il soggetto della colonna. */
.col-schermo { width:max-content; max-width:100%; }
.col-schermo .col-testa { flex-wrap:wrap; }
.col-azioni > .passi { margin-bottom:0; }

/* ⚠️ 2026-08-22: qui c'era `.maschera-riga`, la spia verde/rossa in cima alla
   colonna 1 col pulsante Riaggancia. Tolta con la sua funzione: `apri_app`
   aspetta la maschera confermata e la riaggancia da solo (automation.md §3-0). */

/* ⭐ LA FOTO A PIENA LUCE E I RIQUADRI SPENTI (2026-08-21, osservazione
   dell'utente). Prima erano accesi tutti insieme: su una schermata vera sono
   decine di rettangoli sovrapposti, illeggibili, e coprivano proprio la foto
   che dovevano spiegare. Adesso sono trasparenti e cliccabili, si accendono
   passandoci sopra, e quello scelto dentro uno strumento si accende da solo:
   la domanda vera e' "«Brani che ti piacciono» dov'e'?", non "quanti elementi
   ci sono".
   ⚠️ Due limiti dichiarati: nelle app che proteggono le schermate la foto e'
   nera, e su queste istanze (redroid, GL software) esce spesso strappata. La
   mappa arriva da `uiautomator dump`: la verita' e' quella, la foto e' contesto. */
.telaio.con-foto { background-size:100% 100%; background-repeat:no-repeat; }
.telaio .box { border-color:transparent; background:transparent;
               color:transparent; transition:background .08s; }
.telaio .box:hover { border-color:var(--ok); background:rgba(74,222,128,.20);
                     color:var(--su-foto); text-shadow:0 1px 2px #000; }
/* Acceso: quello scelto adesso dentro uno strumento. Giallo pieno, perche' e'
   l'unica cosa che deve saltare all'occhio sulla foto. */
.telaio .box.scelto { border-color:var(--attesa); border-width:2px;
                      background:rgba(251,191,36,.30); color:var(--su-foto);
                      text-shadow:0 1px 2px #000;
                      box-shadow:0 0 0 2px rgba(0,0,0,.55); }
/* La casella "mostrali tutti insieme": la vista di prima, quando serve. */
.telaio.mostra-tutti .box { border-color:var(--bordo-scelto);
                            background:rgba(63,110,168,.12); color:var(--su-scelto); }
.telaio.mostra-tutti .box.click { border-color:var(--ok);
                                  background:rgba(74,222,128,.13); color:var(--ok); }
.telaio-opz { display:block; margin-top:var(--s2); }

/* ⭐ 22/08: le finestre-strumento tornano AL CENTRO, come tutte le altre della
   webapp (erano ancorate in alto a destra e sembravano sfuggite via). Il velo
   resta leggero: cosi' il telefono a sinistra si intravede lo stesso e si vede
   accendersi l'elemento scelto, che era il motivo per cui stavano di lato. */
.velo-strumento { background:rgba(0,0,0,.28); }

/* Il collegamento "non e' un passo, e' un fastidio": sotto la tendina degli
   elementi, in piccolo — e' una scorciatoia, non la scelta principale. */
.st-fastidio { display:block; margin-top:var(--s2); text-align:left;
               font-size:12px; }

/* ------------------------------------------------------------
   ⭐ GLI STRUMENTI: un albero per famiglie, come le "Available actions" di
   RoboTask. Si cerca per famiglia ("devo aspettare qualcosa" -> Tempo)
   invece di leggere una fila di pulsanti tutti uguali.
   Il mirino ◎ segna quelli che chiedono di cliccare un pulsante sullo schermo:
   e' l'unica cosa che il nome da solo non direbbe.
   ------------------------------------------------------------ */
.st-cerca { width:100%; box-sizing:border-box; margin-bottom:var(--s2); }
.st-elenco { display:flex; flex-direction:column; gap:var(--s2); }
.st-titolo { font-size:var(--t-piccolo); text-transform:uppercase;
             letter-spacing:.04em; color:var(--testo-3);
             padding:0 0 2px 2px; border-bottom:1px solid var(--bordo);
             margin-bottom:2px; }
.st-voce { display:block; width:100%; text-align:left; margin:0 0 2px;
           background:none; border:1px solid transparent; color:var(--testo);
           padding:5px 7px; border-radius:5px; cursor:pointer;
           font-size:var(--t-normale); }
.st-voce:hover { background:var(--rialzo); }
.st-voce.attiva { background:var(--scelto-fondo); color:var(--su-scelto);
                  border-color:var(--bordo-scelto); }
.st-mira { color:var(--ok); font-size:11px; }

/* ⭐ La finestra dello strumento, come in RoboTask: si clicca l'azione e si
   aprono LE SUE opzioni. Le cose che si possono solo scegliere (quale app,
   quale pulsante) sono tendine con dentro i valori veri letti dal telefono:
   un nome tecnico battuto a mano e' il modo piu' facile per scrivere una
   sequenza che non funziona e non dice perche'. */
.f-strumento { width:min(520px, 94vw); }
.f-strumento .f-corpo { display:flex; flex-direction:column; gap:2px; }
.f-strumento select { width:100%; }
.st-campo { display:flex; flex-direction:column; gap:2px; margin-top:var(--s3);
            font-size:var(--t-piccolo); color:var(--testo-2); }
.st-campo input { background:var(--incasso); color:var(--testo);
                  border:1px solid var(--bordo); border-radius:5px;
                  padding:4px 6px; font-size:var(--t-normale); }
.st-campo.spunta { flex-direction:row; align-items:center; gap:var(--s2); }
.st-campo.spunta input { width:auto; }
.st-nota { margin-top:2px; }
/* Il cassetto "riservato all'account": staccato dal resto da una riga, perche'
   non riguarda il passo che stai costruendo ma i Contenuti del device. */
.st-contenuto { margin-top:var(--s3); padding-top:var(--s3);
                border-top:1px solid var(--bordo); }
.st-mirino:empty { display:none; }
.st-mirino { margin-top:var(--s1); padding-left:2px; }
/* Il buco già presente su un passo: si vede il nome ({playlist}) invece del
   pulsante "rendi variabile". Prima il pulsante compariva su ogni riga uguale
   e faceva credere che ci fosse una variabile anche dove non c'era. */
.buco-pill { color:var(--attesa); background:var(--attesa-fondo);
             border:1px solid var(--attesa); border-radius:10px;
             padding:0 7px; font-size:var(--t-piccolo); white-space:nowrap; }

/* ------------------------------------------------------------
   ⭐ LE AZIONI: ogni riga si prova da sola (il triangolo ▶). Serviva perche'
   oggi, quando una sequenza fallisce, si sa CHE e' fallita e non DOVE.
   ------------------------------------------------------------ */
.vuoto-passi { border:1px dashed var(--bordo-scelto); border-radius:6px;
               padding:var(--s4); color:var(--testo-2);
               font-size:var(--t-piccolo); line-height:1.6; }
.vuoto-passi b { display:block; color:var(--testo); margin-bottom:4px;
                 font-size:var(--t-normale); }
.passo-piede { display:flex; align-items:center; gap:var(--s2);
               flex-wrap:wrap; padding-left:26px; }
.passo-piede .passo-grezzo { flex:1 1 auto; min-width:0; margin:0; }
.prova-passo { flex:none; color:var(--ok); border-color:var(--bordo);
               line-height:1; }
.passo-esito:empty { display:none; }
.passo-esito { padding-left:26px; font-size:var(--t-piccolo); margin-top:2px; }

/* ------------------------------------------------------------
   ⭐ L'INTRO: apertura o chiusura? (richiesta dell'utente, 21/08)
   Due carte grandi invece di una tendina: e' la prima decisione, non un
   dettaglio da cercare in un'altra scheda a lavoro finito.
   ------------------------------------------------------------ */
.co-intro { border-radius:0 var(--raggio) var(--raggio) var(--raggio); }
.intro-scelte { display:flex; gap:var(--s3); flex-wrap:wrap;
                margin-top:var(--s3); }
.intro-carta { flex:1 1 280px; text-align:left; margin:0;
               background:var(--rialzo); border:1px solid var(--bordo);
               border-radius:var(--raggio); padding:var(--s4);
               cursor:pointer; display:flex; flex-direction:column; gap:6px; }
.intro-carta:hover { border-color:var(--bordo-scelto); background:var(--scelto-fondo); }
.intro-carta b { font-size:var(--t-grande); color:var(--testo); }
.intro-carta .nota { line-height:1.55; white-space:normal; }

/* Le aperture da agganciare a una chiusura: una riga per apertura, con
   scritto accanto cosa cambia spuntandola. */
.ap-lista { display:flex; flex-direction:column; gap:var(--s1);
            margin:var(--s2) 0 var(--s3); }
.ap-riga { display:flex; align-items:center; gap:var(--s2);
           padding:5px 7px; border:1px solid var(--bordo); border-radius:6px;
           background:var(--rialzo); cursor:pointer; }
.ap-riga:hover { border-color:var(--bordo-scelto); }
.ap-riga .manca { color:var(--attesa); }

/* ============================================================
   ⭐ BARRA DEGLI AVVISI (pagina del device). Tre gravita' e tre colori gia'
   in uso altrove, cosi' "rosso = guarda subito" vale in tutta la webapp.
   Il rosso deve restare raro: e' solo per cio' che ferma il lavoro o scopre
   l'identita'. "Fuori servizio" e' una scelta di chi comanda, quindi grigio.
   ============================================================ */
.barra-avvisi { display:flex; flex-direction:column; gap:var(--s2);
                margin-bottom:var(--s4); }
.avv { border:1px solid var(--bordo); border-left-width:3px;
       border-radius:6px; padding:var(--s2) var(--s3);
       background:var(--rialzo); }
.avv-titolo { margin-right:var(--s2); }
.avv-cosa { color:var(--testo-2); }
.avv-fare { display:block; margin-top:2px; }
.av-rosso  { border-left-color:var(--male);   background:var(--male-fondo); }
.av-rosso .avv-titolo  { color:var(--male); }
.av-giallo { border-left-color:var(--attesa); background:var(--attesa-fondo); }
.av-giallo .avv-titolo { color:var(--attesa); }
.av-grigio { border-left-color:var(--bordo); }
.av-grigio .avv-titolo { color:var(--testo-2); }

/* ============================================================
   MODULO: un gruppo di campi da compilare (pagina Connessioni, finestre).
   Prima le etichette erano inline, quindi il titolo finiva ACCANTO al campo —
   e con una casella alta, all'altezza della sua ULTIMA riga: e' il testo che
   si accavallava nella pagina Connessioni. Un modulo si legge dall'alto in
   basso: titolo sopra, campo sotto, largo quanto il riquadro che lo contiene.
   ============================================================ */
.modulo { display:flex; flex-direction:column; gap:var(--s3); }
.modulo > label, .modulo .riga-campi > label, .modulo details > label {
        display:block; font-size:var(--t-piccolo); color:var(--testo-2); }
.modulo input, .modulo select, .modulo textarea {
        display:block; width:100%; margin-top:3px; box-sizing:border-box;
        background:var(--incasso); color:var(--testo);
        border:1px solid var(--bordo); border-radius:6px;
        padding:5px 8px; font-size:var(--t-normale); font-family:inherit; }
.modulo input:focus, .modulo select:focus, .modulo textarea:focus {
        outline:none; border-color:var(--scelto); }
.modulo .nota { margin:0; }
/* Il file .ovpn e' lungo e va riletto: casella larga quanto il modulo, a
   caratteri fissi. Si allunga in verticale (il testo e' tanto), non in
   orizzontale: la' romperebbe l'impaginazione della pagina. */
.modulo textarea.conf { font-family:var(--mono); font-size:var(--t-piccolo);
        min-height:170px; resize:vertical; white-space:pre; overflow:auto; }

/* Nella lista dei provider i comandi stanno a destra, staccati dal nome:
   il nome si legge, i pulsanti si cercano solo quando servono. */
.lista-semplice .voce-lista .spinta { margin-left:auto; }

/* ============================================================
   LA STRADA (28/08) - i blocchi del wizard "apri da fuori casa".
   ⚠️ NON usano .pannello-scheda apposta: quella classe deve restare
   riservata alle schede del device, che un controllo del guscio
   conta per accorgersi se una finisce dentro un'altra. Qui siamo
   dentro una finestra, quindi piu' in profondita': riusare quella
   classe avrebbe fatto sballare il controllo, e la cura sarebbe
   stata togliere il controllo -- cioe' perdere il guardiano.
   ============================================================ */
.strada-blocco { padding:var(--s4); border-radius:var(--raggio); }
.strada-blocco code { font-size:var(--t-piccolo); }

/* ============================================================
   IL NOME DI QUESTA ANDROMEDA, accanto al logo (28/08).
   Discreto ma sempre visibile: non e' un avviso, e' un'etichetta.
   Compare solo quando un nome c'e' -- chi ne ha una sola non ha
   niente da distinguere, e una riga fissa che ripete l'ovvio
   diventa sfondo.
   ============================================================ */
.nome-andromeda { margin-left:var(--s3); padding:2px var(--s3);
                  border:1px solid var(--bordo); border-radius:var(--raggio);
                  font-size:var(--t-piccolo); color:var(--testo-2);
                  letter-spacing:.04em; white-space:nowrap; }

/* ============================================================
   LA i CERCHIATA - i dettagli che a un utente normale non servono.
   ⭐ Richiesta di Emanuele (28/08): i passi del wizard in due
   righe, e il perche' dietro una ⓘ da aprire solo se lo si
   vuole. *Un riquadro pieno di ragioni si salta tutto, comprese
   le due righe che servivano.*
   ⚠️ Sono <details> del browser, non JavaScript: si aprono anche
   se un pezzo di pagina va storto, e stampando la pagina ci sono.
   ============================================================ */
details.info { display:inline; }
details.info > summary {
  display:inline; cursor:pointer; margin-left:6px;
  color:var(--scelto); list-style:none; white-space:nowrap;
  font-weight:600; }
details.info > summary::-webkit-details-marker { display:none; }
details.info > summary::before { content:"\24D8"; margin-right:3px; }
details.info > summary:hover { text-decoration:underline; }
details.info[open] { display:block; margin-top:6px; }
details.info[open] > summary { display:block; margin:0 0 4px 0; }
details.info[open] > summary::before { content:"\24D8"; }


/* ⭐ IL PULSANTE DELLO ZIP (28/08). Scegliere un file e' un gesto come premere
   un pulsante: deve avere la stessa faccia. L'input vero resta li' (e' lui che
   apre la finestra del sistema), ma non si vede. */
.prog-scegli { display:inline-flex; align-items:center; gap:6px;
               background:var(--rialzo); color:var(--testo);
               border:1px solid var(--bordo); border-radius:6px;
               padding:5px 10px; font-size:var(--t-piccolo); cursor:pointer; }
.prog-scegli:hover { border-color:var(--testo-3); }
.prog-scegli input[type=file] { display:none; }
