@import "tailwindcss"; /* Carattere servito dall'applicazione, non da un CDN esterno: questo gestionale tiene nomi e indirizzi di persone, e una richiesta a un dominio di terze parti a ogni pagina caricata sarebbe un dato in uscita che nessuno ha chiesto. Il pacchetto e' una dipendenza npm, quindi finisce nel bundle e funziona anche senza rete. */ @import "@fontsource-variable/figtree"; /* ═══════════════════════════════════════════════════════════════════════════ TerManager2 — sistema visivo I token stanno qui e in nessun altro posto. Ridefinire le scale `gray` e `indigo` di Tailwind e' deliberato: le trentasette viste dell'applicazione sono scritte con le utility (`text-gray-600`, `bg-indigo-50`), e cambiare la scala le riallinea tutte insieme invece di costringere a riscriverle una per una — con il rischio, a ogni vista dimenticata, di lasciare in giro il grigio di prima accanto a quello nuovo. Due scelte di fondo: I grigi sono caldi. Il grigio di serie di Tailwind tira al blu e, sommato a un accento indaco, dava a tutta l'interfaccia una dominante fredda da pannello di controllo. Su carta questi elenchi diventano moduli che passano di mano: un fondo caldo li avvicina a quello che sono. L'accento e' uno. Prima ce n'erano cinque (indaco, verde, blu, rosso, ambra) usati come decorazione. Ora il colore vuol dire qualcosa: indaco = azione, verde = fatto, ambra = in sospeso, rosso = distrugge dati. Se non rientra in queste quattro, e' grigio. ═══════════════════════════════════════════════════════════════════════════ */ @theme { --font-sans: "Figtree Variable", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* Grigi caldi: una sola famiglia, nessuna mescolanza caldo/freddo. */ --color-gray-50: #f7f6f4; --color-gray-100: #efedea; --color-gray-200: #e3e0da; --color-gray-300: #cfcbc2; --color-gray-400: #a8a29a; --color-gray-500: #837d74; --color-gray-600: #625c54; --color-gray-700: #4a453f; --color-gray-800: #302c28; --color-gray-900: #1c1a17; --color-gray-950: #12100e; /* Indaco smorzato: stessa identita' di prima, meno stridente. */ --color-indigo-50: #eeeef9; --color-indigo-100: #dedef3; --color-indigo-200: #c3c2e8; --color-indigo-300: #a09ed8; --color-indigo-400: #7c79c5; --color-indigo-500: #605cb2; --color-indigo-600: #4a45a8; --color-indigo-700: #3b3789; --color-indigo-800: #2f2c6c; --color-indigo-900: #262350; --color-indigo-950: #16142f; } :root { --tm-fondo: #f7f6f4; --tm-superficie: #ffffff; --tm-superficie-alt: #faf9f7; --tm-bordo: #e3e0da; --tm-bordo-forte: #cfcbc2; --tm-testo: #1c1a17; --tm-testo-medio: #4a453f; --tm-testo-tenue: #837d74; --tm-accento: #4a45a8; --tm-accento-scuro: #3b3789; --tm-accento-tenue: #eeeef9; --tm-ok: #2f6f4e; --tm-ok-tenue: #e8f2ec; --tm-attesa: #a06a22; --tm-attesa-tenue: #fbf1e2; --tm-pericolo: #b3352c; --tm-pericolo-tenue: #fbeceb; /* Le ombre portano la tinta del fondo invece del nero puro: su una superficie calda un'ombra neutra sporca di grigio. */ --tm-ombra-1: 0 1px 2px rgba(43, 37, 28, .05); --tm-ombra-2: 0 2px 4px rgba(43, 37, 28, .05), 0 6px 16px -8px rgba(43, 37, 28, .10); --tm-ombra-3: 0 8px 28px -10px rgba(43, 37, 28, .18); --tm-raggio: 14px; --tm-raggio-interno: 10px; } html.tm-app, body { background: var(--tm-fondo); color: var(--tm-testo); } body { font-family: var(--font-sans); font-synthesis-weight: none; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } /* I titoli devono avere peso e stare stretti: alla dimensione di prima, con spaziatura di serie, si leggevano come testo qualsiasi in grassetto. */ h1, h2, h3 { letter-spacing: -.018em; text-wrap: balance; } /* Le cifre incolonnate vogliono larghezza fissa, altrimenti in un elenco di date e numeri di territorio le colonne ballano riga per riga. */ table, .tm-tabella, .tm-cifre { font-variant-numeric: tabular-nums; } p { text-wrap: pretty; } /* Alpine nasconde con x-cloak solo se il foglio di stile lo dice: la regola non arriva col pacchetto. Senza, gli elementi marcati x-cloak (le barre di avanzamento, i messaggi d'errore) lampeggiano a ogni caricamento prima che Alpine parta. */ [x-cloak] { display: none !important; } html { scroll-behavior: smooth; } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } } /* Chi naviga da tastiera deve poter saltare la barra laterale invece di percorrerla a ogni pagina. */ .tm-salta { position: absolute; left: -9999px; z-index: 100; padding: 10px 16px; border-radius: var(--tm-raggio-interno); background: var(--tm-accento); color: #fff; font-size: 14px; font-weight: 600; } .tm-salta:focus { left: 12px; top: 12px; } .tm-solo-lettori { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; } /* ─── Superfici ──────────────────────────────────────────────────────────── Una card esiste quando l'elevazione dice qualcosa. Il bordo fa il lavoro principale, l'ombra e' appena percepibile: bordo + ombra marcata + fondo bianco insieme e' il riquadro di serie che si vede ovunque. */ .card-hover { transition: transform .18s ease, box-shadow .18s ease; } .card-hover:hover { transform: translateY(-2px); box-shadow: var(--tm-ombra-3); } /* Bordo d'accento sulle schede di riepilogo: quattro significati, non cinque tinte decorative. */ .card-accent-indigo { border-left: 3px solid var(--tm-accento); } .card-accent-green { border-left: 3px solid var(--tm-ok); } .card-accent-blue { border-left: 3px solid var(--tm-accento); } .card-accent-red { border-left: 3px solid var(--tm-pericolo); } .card-accent-amber { border-left: 3px solid var(--tm-attesa); } .table-striped tbody tr:nth-child(even) { background-color: var(--tm-superficie-alt); } /* La testata era un gradiente indaco a 45 gradi — la firma piu' riconoscibile di un'interfaccia generata. Adesso e' una tinta piena e profonda, con un solo velo verticale appena accennato per non essere piatta come un francobollo. */ .header-gradient { background: linear-gradient(180deg, #333072 0%, #2b2860 100%); } .sidebar-active { background: var(--tm-accento-tenue); border-right: 3px solid var(--tm-accento); color: var(--tm-accento-scuro); font-weight: 600; } .page-enter { animation: fadeSlideIn .28s cubic-bezier(.22, .61, .36, 1); } @keyframes fadeSlideIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } } .empty-state { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 2.5rem 1rem; color: var(--tm-testo-tenue); } .empty-state svg { width: 44px; height: 44px; opacity: .35; } .badge-pulse { animation: pulse 2s infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .7; } } /* ─── Impaginazione ───────────────────────────────────────────────────────── */ .tm-pagina-testata { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 28px; } .tm-pagina-titolo { margin: 0; font-size: clamp(1.5rem, 1.2rem + 1vw, 1.9rem); font-weight: 600; line-height: 1.15; color: var(--tm-testo); } .tm-pagina-nota { margin: 6px 0 0; max-width: 62ch; font-size: 14px; line-height: 1.6; color: var(--tm-testo-medio); } .tm-card { background: var(--tm-superficie); border: 1px solid var(--tm-bordo); border-radius: var(--tm-raggio); box-shadow: var(--tm-ombra-1); /* Il basso ottico vuole un filo piu' del sopra, altrimenti il blocco sembra appoggiato storto. */ padding: 20px 22px 24px; margin-bottom: 20px; } .tm-card-testata { margin-bottom: 18px; } /* Scheda che apre la pagina: è il presupposto di tutto quello che segue, e deve leggersi come tale prima ancora di aver letto il titolo. Il rilievo glielo danno la barra d'accento e il fondo appena caldo, non un colore acceso — che a fianco di un avviso vero ne ruberebbe la voce. */ .tm-card-primaria { position: relative; padding-left: 26px; background: linear-gradient(180deg, var(--tm-superficie-alt) 0%, var(--tm-superficie) 60%); box-shadow: var(--tm-ombra-2); } .tm-card-primaria::before { content: ""; position: absolute; left: 0; top: -1px; bottom: -1px; width: 4px; border-radius: var(--tm-raggio) 0 0 var(--tm-raggio); background: var(--tm-accento); } /* Finché il KML manca, l'accento diventa ambra: è un lavoro da fare. */ .tm-card-manca::before { background: var(--tm-attesa); } .tm-card-manca { border-color: #e8d3ae; background: linear-gradient(180deg, var(--tm-attesa-tenue) 0%, var(--tm-superficie) 65%); } .tm-card-testata-icona { display: flex; align-items: flex-start; gap: 14px; } .tm-card-icona { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 40px; height: 40px; border-radius: var(--tm-raggio-interno); border: 1px solid var(--tm-bordo); background: var(--tm-superficie); color: var(--tm-accento); } .tm-card-icona svg { width: 21px; height: 21px; } .tm-card-manca .tm-card-icona { color: var(--tm-attesa); border-color: #e8d3ae; } /* Chiosa accanto all'etichetta di un campo: spiega dove finisce quel valore senza spingere la spiegazione sotto, dove verrebbe letta dopo la scelta. */ .tm-campo-nota { margin-left: 6px; font-size: 11.5px; font-weight: 500; color: var(--tm-testo-tenue); } .tm-card-titolo { display: flex; align-items: center; gap: 10px; margin: 0; font-size: 1.02rem; font-weight: 600; color: var(--tm-testo); } .tm-card-nota { margin: 5px 0 0; max-width: 68ch; font-size: 13px; line-height: 1.6; color: var(--tm-testo-tenue); } .tm-conteggio { display: inline-flex; align-items: center; min-width: 22px; height: 22px; padding: 0 7px; border-radius: 999px; background: var(--tm-superficie-alt); border: 1px solid var(--tm-bordo); font-size: 12px; font-weight: 600; color: var(--tm-testo-medio); } .tm-griglia-2 { display: grid; grid-template-columns: 1fr; gap: 22px; } @media (min-width: 900px) { .tm-griglia-2 { grid-template-columns: 1fr 1fr; gap: 28px; } } /* ─── Campi ───────────────────────────────────────────────────────────────── */ .tm-campo { display: flex; flex-direction: column; gap: 7px; } .tm-campo > label { font-size: 13px; font-weight: 600; color: var(--tm-testo-medio); } .tm-campo input[type="text"], .tm-campo input[type="number"], .tm-campo select, .tm-elenco-pannello select { width: 100%; min-height: 40px; padding: 8px 12px; border: 1px solid var(--tm-bordo-forte); border-radius: var(--tm-raggio-interno); background: var(--tm-superficie); color: var(--tm-testo); font-family: inherit; font-size: 14px; transition: border-color .15s ease, box-shadow .15s ease; } .tm-campo input:focus, .tm-campo select:focus, .tm-elenco-pannello select:focus { outline: none; border-color: var(--tm-accento); box-shadow: 0 0 0 3px var(--tm-accento-tenue); } .tm-campo input::placeholder { color: var(--tm-testo-tenue); } .tm-campo textarea { width: 100%; min-height: 120px; padding: 10px 12px; border: 1px solid var(--tm-bordo-forte); border-radius: var(--tm-raggio-interno); background: var(--tm-superficie); color: var(--tm-testo); font-family: inherit; font-size: 14px; line-height: 1.55; resize: vertical; transition: border-color .15s ease, box-shadow .15s ease; } .tm-campo textarea:focus { outline: none; border-color: var(--tm-accento); box-shadow: 0 0 0 3px var(--tm-accento-tenue); } .tm-campo textarea::placeholder { color: var(--tm-testo-tenue); } /* Gruppo di campi: dà un nome a una parte della scheda senza trasformarla in una scatola dentro la scatola — solo una riga di separazione e l'etichetta. */ .tm-gruppo { display: flex; flex-direction: column; gap: 16px; margin: 0; padding: 0; border: 0; } .tm-gruppo + .tm-gruppo { padding-top: 20px; border-top: 1px solid var(--tm-bordo); } .tm-gruppo > legend { padding: 0; margin-bottom: 2px; font-size: 11.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--tm-testo-tenue); } /* La riga "crea quello che manca": sta sotto la tendina a cui appartiene, e si legge come una sua appendice invece che come un campo a sé. */ .tm-campo-crea { gap: 8px; padding-left: 10px; border-left: 2px solid var(--tm-bordo); } .tm-campo-crea input { min-height: 34px; font-size: 13px; } .tm-campo-riga { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; } .tm-campo-riga input, .tm-campo-riga select { flex: 1 1 180px; } .tm-file { width: 100%; font-size: 14px; color: var(--tm-testo-medio); } .tm-file::file-selector-button { margin-right: 12px; padding: 8px 14px; border: 1px solid var(--tm-bordo-forte); border-radius: var(--tm-raggio-interno); background: var(--tm-superficie-alt); color: var(--tm-testo-medio); font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer; transition: background-color .15s ease; } .tm-file::file-selector-button:hover { background: var(--tm-bordo); } .tm-campo-aiuto { margin: 0; max-width: 62ch; font-size: 12.5px; line-height: 1.55; color: var(--tm-testo-tenue); } .tm-campo-aiuto-attesa { color: var(--tm-attesa); } .tm-campo-errore { margin: 0; font-size: 12.5px; font-weight: 500; color: var(--tm-pericolo); } /* ─── Elenchi ─────────────────────────────────────────────────────────────── */ .tm-elenco { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--tm-bordo); } .tm-elenco-riga { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; padding: 14px 2px; border-bottom: 1px solid var(--tm-bordo); } .tm-elenco-intestazione { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; flex: 1 1 260px; min-width: 0; } .tm-elenco-nome { font-size: 14.5px; font-weight: 600; color: var(--tm-testo); text-decoration: none; border-bottom: 1px solid transparent; transition: border-color .15s ease, color .15s ease; } .tm-elenco-nome:hover { color: var(--tm-accento); border-bottom-color: var(--tm-accento); } .tm-elenco-stato { font-size: 12.5px; color: var(--tm-testo-tenue); } .tm-elenco-stato-ok { color: var(--tm-ok); } .tm-elenco-azioni { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; } .tm-elenco-pannello { flex: 1 1 100%; display: flex; flex-direction: column; gap: 8px; margin-top: 4px; padding: 14px; border: 1px solid var(--tm-bordo); border-radius: var(--tm-raggio-interno); background: var(--tm-superficie-alt); } /* ─── Assegnazione appena fatta: il link da mandare ──────────────────────── */ .tm-da-inviare { display: flex; flex-direction: column; gap: 14px; max-width: 48rem; margin-bottom: 20px; padding: 18px 20px; border: 2px solid var(--tm-accento); border-radius: var(--tm-raggio); background: var(--tm-accento-tenue); box-shadow: var(--tm-ombra-2); } /* Lo stesso riquadro come finestra sopra la pagina (invio del link dopo l'assegnazione): sfondo pieno, perché sotto c'è il velo scuro. */ .tm-da-inviare-finestra { width: 100%; max-width: 34rem; margin-bottom: 0; background: var(--tm-superficie, #fff); } .tm-da-inviare-titolo { margin: 0; font-size: 16px; font-weight: 700; color: var(--tm-accento-scuro); } .tm-da-inviare-link { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; } .tm-da-inviare-link code { flex: 1 1 260px; min-width: 0; padding: 8px 12px; border: 1px solid var(--tm-bordo); border-radius: var(--tm-raggio-interno); background: var(--tm-superficie); font-size: 13px; color: var(--tm-testo); word-break: break-all; cursor: text; } .tm-da-inviare-azioni { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; } .tm-da-inviare-scelta { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; padding-top: 12px; border-top: 1px solid var(--tm-bordo); } .tm-da-inviare-scelta p { margin: 0; font-size: 14px; font-weight: 600; color: var(--tm-testo); } .tm-da-inviare-scelta > div { display: flex; flex-wrap: wrap; gap: 8px; } /* ─── Ricerca e filtri sopra un elenco ───────────────────────────────────── */ .tm-filtri { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 14px; } .tm-filtri-cerca { flex: 1 1 220px; min-width: 0; padding: 7px 11px; border: 1px solid var(--tm-bordo-forte); border-radius: var(--tm-raggio-interno); background: var(--tm-superficie); font-size: 14px; color: var(--tm-testo); } .tm-filtri-cerca:focus { outline: 2px solid var(--tm-accento); outline-offset: 1px; } .tm-filtri-schede { display: flex; flex-wrap: wrap; gap: 6px; } .tm-filtri-scheda { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border: 1px solid var(--tm-bordo); border-radius: 999px; background: var(--tm-superficie); font-size: 13px; font-weight: 500; color: var(--tm-testo-medio); cursor: pointer; } .tm-filtri-scheda:hover { border-color: var(--tm-bordo-forte); } .tm-filtri-scheda:focus-visible { outline: 2px solid var(--tm-accento); outline-offset: 2px; } .tm-filtri-scheda-attiva { border-color: var(--tm-accento); background: var(--tm-accento-tenue); color: var(--tm-accento-scuro); } .tm-filtri-scheda .tm-conteggio { min-width: 18px; height: 18px; padding: 0 5px; font-size: 11px; } /* ─── Etichette di stato ──────────────────────────────────────────────────── */ .tm-tag { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 5px; border: 1px solid var(--tm-bordo-forte); background: var(--tm-superficie-alt); font-size: 11.5px; font-weight: 600; letter-spacing: .01em; color: var(--tm-testo-medio); } .tm-tag-attesa { border-color: #e8d3ae; background: var(--tm-attesa-tenue); color: var(--tm-attesa); } .tm-tag-ok { border-color: #bcd9c9; background: var(--tm-ok-tenue); color: var(--tm-ok); } .tm-nota { padding: 12px 14px; border: 1px solid var(--tm-bordo); border-radius: var(--tm-raggio-interno); background: var(--tm-superficie-alt); font-size: 13px; color: var(--tm-testo-medio); } .tm-nota p { margin: 0 0 8px; } .tm-nota-attesa { border-color: #e8d3ae; background: var(--tm-attesa-tenue); color: var(--tm-attesa); } .tm-collegamento { font-size: 13px; font-weight: 500; color: var(--tm-accento); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--tm-accento) 35%, transparent); transition: border-color .15s ease; } .tm-collegamento:hover { border-bottom-color: var(--tm-accento); } /* ─── Stato vuoto ─────────────────────────────────────────────────────────── */ .tm-vuoto { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 40px 20px 44px; text-align: center; color: var(--tm-testo-tenue); } .tm-vuoto svg { width: 40px; height: 40px; opacity: .3; } .tm-vuoto p { margin: 0; font-size: 14px; } /* ─── Tabelle ─────────────────────────────────────────────────────────────── */ .tm-tabella-scorre { overflow-x: auto; } .tm-tabella { width: 100%; border-collapse: collapse; font-size: 14px; } .tm-tabella thead th { padding: 0 12px 10px 0; border-bottom: 1px solid var(--tm-bordo); text-align: left; font-size: 11.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--tm-testo-tenue); } .tm-tabella tbody td { padding: 11px 12px 11px 0; border-bottom: 1px solid var(--tm-bordo); color: var(--tm-testo-medio); vertical-align: middle; } .tm-tabella tbody tr:last-child td { border-bottom: 0; } .tm-tabella-forte { font-weight: 600; color: var(--tm-testo) !important; } .tm-tabella .cell-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; padding-right: 0; } /* ─── Pulsanti ───────────────────────────────────────────────────────────── Un solo sistema per tutta l'applicazione, definito qui e in nessun altro posto. Si usa dal componente , mai scrivendo queste classi a mano. Da dove veniamo: quattro vocabolari in circolazione contemporaneamente — style= inline con i colori scritti a mano (piu' onmouseover per l'hover), catene di utility Tailwind ripetute a memoria, .btn-action* in sei tinte, e .btn-primary-* in due. La stessa azione cambiava aspetto da una pagina all'altra, un "Rientra" era rosso quanto un "Elimina", e nessuno di questi pulsanti aveva uno stato di focus: chi naviga da tastiera non vedeva dove si trovava. Due assi, ortogonali: variante primary l'azione principale. Una sola per schermata o zona. secondary tutto il resto (dettaglio, modifica, scarica, filtra) danger SOLO dove si cancellano o si sovrascrivono dati ghost annulla, chiudi, pulisci tono solido il pieno. Per le azioni isolate. tenue la tinta chiara. Per le azioni dentro le righe di un elenco, dove cinquanta pulsanti pieni urlerebbero. La dimensione `sm` e' quella delle righe di elenco; `icona` toglie il testo e lascia il quadrato. Le regole stanno fuori da @layer, quindi vincono sulle utility di Tailwind: un pulsante non puo' essere ritoccato per meta' con le classi. */ .tm-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 40px; padding: 10px 16px; border-radius: var(--tm-raggio-interno); border: 1px solid transparent; font-family: inherit; font-size: 14px; font-weight: 600; line-height: 1.2; white-space: nowrap; text-decoration: none; cursor: pointer; transition: background-color .15s ease, border-color .15s ease, color .15s ease, transform .1s ease; } .tm-btn svg { width: 16px; height: 16px; flex: none; } /* Un premuto che si sente: senza, il pulsante resta un rettangolo che non risponde finche' la pagina non torna dal server. */ .tm-btn:active:not(:disabled) { transform: translateY(1px); } /* Un anello unico per ogni variante: il colore del focus non deve dipendere da quello del pulsante, altrimenti su rosso o su bianco cambia visibilita' proprio dove serve di piu'. Il doppio contorno (chiaro + scuro) lo tiene leggibile sia sulle card bianche sia sui riquadri colorati. */ .tm-btn:focus-visible, .tm-console-btn:focus-visible, .tm-nav-zona:focus-visible, .tm-editor-torna:focus-visible, .tm-collegamento:focus-visible, .tm-elenco-nome:focus-visible { outline: 3px solid var(--tm-accento); outline-offset: 2px; box-shadow: 0 0 0 5px #fff; } .tm-btn:disabled, .tm-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; } .tm-btn-primary { background: var(--tm-accento); border-color: var(--tm-accento-scuro); color: #fff; } .tm-btn-primary:hover:not(:disabled) { background: var(--tm-accento-scuro); } .tm-btn-danger { background: var(--tm-pericolo); border-color: #8e2a23; color: #fff; } .tm-btn-danger:hover:not(:disabled) { background: #8e2a23; } .tm-btn-secondary { background: var(--tm-superficie); border-color: var(--tm-bordo-forte); color: var(--tm-testo-medio); } .tm-btn-secondary:hover:not(:disabled) { background: var(--tm-superficie-alt); border-color: var(--tm-testo-tenue); color: var(--tm-testo); } .tm-btn-ghost { background: transparent; border-color: transparent; color: var(--tm-testo-medio); min-height: 32px; padding: 4px 8px; font-size: 13px; font-weight: 500; text-decoration: underline; text-underline-offset: 3px; } .tm-btn-ghost:hover:not(:disabled) { color: var(--tm-testo); background: #efedea; } /* Tono tenue: stessa gerarchia, voce piu' bassa. Nelle righe di un elenco i pulsanti sono tanti quanti i record, e il pieno li trasforma in rumore — soprattutto il rosso, che smette di significare "attenzione" quando compare cinquanta volte di fila. */ .tm-btn-tenue { border-color: transparent; font-weight: 600; } .tm-btn-tenue.tm-btn-primary { background: var(--tm-accento-tenue); color: var(--tm-accento-scuro); } .tm-btn-tenue.tm-btn-primary:hover:not(:disabled) { background: #dedef3; } .tm-btn-tenue.tm-btn-danger { background: var(--tm-pericolo-tenue); color: var(--tm-pericolo); } .tm-btn-tenue.tm-btn-danger:hover:not(:disabled) { background: #f6dcda; } .tm-btn-tenue.tm-btn-secondary { background: #efedea; color: var(--tm-testo-medio); } .tm-btn-tenue.tm-btn-secondary:hover:not(:disabled) { background: #e3e0da; color: var(--tm-testo); } /* Tono velato: per i comandi che stanno SOPRA una superficie colorata — oggi solo la testata. Un pulsante bianco o indaco lì sopra sarebbe una toppa; qui il colore lo dà lo sfondo e il pulsante si limita a velarlo. Il focus diventa bianco, perche' l'anello indaco su indaco non si distingue. */ .tm-btn-velato { background: rgba(255, 255, 255, .12); border-color: transparent; color: rgba(255, 255, 255, .92); } .tm-btn-velato:hover:not(:disabled) { background: rgba(255, 255, 255, .22); color: #fff; } .tm-btn-velato:focus-visible { outline: 3px solid #fff; outline-offset: 2px; box-shadow: 0 0 0 5px rgba(0, 0, 0, .35); } .tm-btn-sm { min-height: 32px; padding: 6px 12px; font-size: 13px; gap: 5px; } .tm-btn-sm svg { width: 14px; height: 14px; } /* Solo icona: quadrato, senza testo. Serve sempre un aria-label, altrimenti chi usa un lettore di schermo trova un pulsante senza nome. */ .tm-btn-icona { padding-left: 8px; padding-right: 8px; } .tm-btn-sm.tm-btn-icona { padding-left: 7px; padding-right: 7px; } /* ─── Zone della pagina ──────────────────────────────────────────────────── Ogni sezione e' un bersaglio di navigazione: premendo un pulsante o una voce dell'indice la pagina ci si porta sopra e la zona lampeggia, cosi' e' chiaro *dove* e' finita l'attenzione invece di dover indovinare cosa e' cambiato. scroll-margin-top tiene la testata della zona sotto la barra dell'indice, che e' appiccicata in alto: senza, l'ancora finirebbe coperta. */ .tm-zona { scroll-margin-top: 84px; } /* Lampeggio d'arrivo. Non usa `outline` perche' si somma male ai bordi delle card; box-shadow non occupa spazio e non fa saltare il layout. */ .tm-zona-evidenziata { animation: tmEvidenzia 1.6s ease-out; } @keyframes tmEvidenzia { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tm-accento) 60%, transparent); } 12% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--tm-accento) 32%, transparent); } 100% { box-shadow: 0 0 0 0 transparent; } } /* Zona con un'operazione in corso: resta marcata finche' dura, cosi' anche tornando sulla pagina dopo un ricaricamento si vede subito chi sta lavorando. */ .tm-zona-attiva { box-shadow: 0 0 0 2px var(--tm-accento); } /* Chi ha chiesto meno animazioni riceve comunque il segnale, fermo. */ @media (prefers-reduced-motion: reduce) { .tm-zona-evidenziata { animation: none; box-shadow: 0 0 0 3px var(--tm-accento); } .tm-btn, .card-hover, .page-enter { transition: none; animation: none; } } /* Indice delle zone, appiccicato in alto. */ .tm-nav-zone { position: sticky; top: 0; z-index: 20; display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 12px; margin: -4px 0 0; border: 1px solid var(--tm-bordo); border-radius: var(--tm-raggio); background: rgba(255, 255, 255, .9); backdrop-filter: blur(8px); } .tm-nav-zona { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border-radius: 999px; border: 1px solid var(--tm-bordo); background: var(--tm-superficie); color: var(--tm-testo-medio); font-size: 12px; font-weight: 500; text-decoration: none; cursor: pointer; transition: background-color .15s ease, border-color .15s ease, color .15s ease; } .tm-nav-zona:hover { background: var(--tm-accento-tenue); border-color: var(--tm-accento); color: var(--tm-accento-scuro); } .tm-nav-zona-pericolo { color: var(--tm-pericolo); border-color: #edc9c6; } .tm-nav-zona-pericolo:hover { background: var(--tm-pericolo-tenue); border-color: var(--tm-pericolo); color: #8e2a23; } /* ─── Console delle operazioni ───────────────────────────────────────────── Una sola finestra per tutte le operazioni lunghe, agganciata in fondo alla finestra del browser: quello che sta succedendo non deve uscire dallo schermo mentre si scorre la pagina. Chiusa e' una striscia alta 44px. */ .tm-console { position: fixed; left: 0; right: 0; bottom: 0; z-index: 45; display: flex; flex-direction: column; background: #17161f; border-top: 1px solid #2c2a38; box-shadow: 0 -8px 28px -14px rgba(20, 16, 12, .6); color: #e6e3dd; } .tm-console-testata { display: flex; align-items: center; gap: 10px; padding: 8px 12px; min-height: 44px; } .tm-console-titolo { display: inline-flex; align-items: center; gap: 8px; background: none; border: 0; padding: 0; color: #e6e3dd; font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer; } .tm-console-btn { background: transparent; border: 1px solid #3d3a4a; border-radius: 8px; padding: 4px 10px; color: #cfcbc2; font-family: inherit; font-size: 12px; cursor: pointer; transition: background-color .15s ease, color .15s ease; } .tm-console-btn:hover { background: #2c2a38; color: #fff; } /* Il corpo scorre; l'altezza e' in vh perche' su un portatile basso una finestra fissa in pixel si mangerebbe mezza pagina. */ .tm-console-corpo { max-height: min(38vh, 340px); overflow-y: auto; padding: 4px 12px 12px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.55; } .tm-console-riga { display: flex; gap: 8px; white-space: pre-wrap; word-break: break-word; } .tm-console-ora { color: #837d74; flex: none; } .tm-console-sorgente { color: #a09ed8; flex: none; } .tm-console-riga-errore .tm-console-testo { color: #e8a09a; font-weight: 600; } .tm-console-riga-ok .tm-console-testo { color: #8fd0ac; } .tm-console-riga-attesa .tm-console-testo { color: #e2bd7e; } .tm-console-barra { flex: 1; height: 6px; min-width: 60px; border-radius: 999px; background: #2c2a38; overflow: hidden; } .tm-console-barra > div { height: 100%; border-radius: 999px; background: #7c79c5; transition: width .3s ease; } .tm-console-barra-ok > div { background: #3f8b64; } .tm-console-barra-errore > div { background: #c9564c; } .tm-console-torna { align-self: center; margin: 0 12px 8px; background: #2f2c6c; border: 1px solid var(--tm-accento); border-radius: 999px; padding: 3px 12px; color: #dedef3; font-family: inherit; font-size: 11px; cursor: pointer; } @media (max-width: 640px) { .tm-console-corpo { max-height: 45vh; font-size: 11px; } .tm-console-sorgente { display: none; } } /* ─── Editor delle piantine, a schermo intero ────────────────────────────── La mappa prende tutta la finestra e i comandi stanno in una striscia sottile in alto. Tagliare un confine su una cartografia grande un terzo di schermo vuol dire sbagliarlo, e questo disegno finisce stampato su un modulo che poi gira di mano in mano. */ .tm-schermo { height: 100dvh; display: flex; flex-direction: column; } .tm-editor { display: flex; flex-direction: column; height: 100%; min-height: 0; } .tm-editor-barra { display: flex; align-items: center; gap: 10px; flex: none; padding: 8px 14px; background: var(--tm-superficie); border-bottom: 1px solid var(--tm-bordo); box-shadow: var(--tm-ombra-1); z-index: 10; } .tm-editor-torna { display: inline-flex; align-items: center; gap: 5px; flex: none; padding: 5px 8px 5px 4px; border-radius: 8px; color: var(--tm-testo-medio); font-size: 13.5px; font-weight: 600; text-decoration: none; transition: background-color .15s ease, color .15s ease; } .tm-editor-torna:hover { background: var(--tm-superficie-alt); color: var(--tm-testo); } .tm-editor-torna svg { width: 17px; height: 17px; } .tm-editor-sep { width: 1px; height: 22px; flex: none; background: var(--tm-bordo); } .tm-editor-titolo { display: flex; align-items: center; gap: 9px; flex: 1 1 auto; min-width: 0; } .tm-editor-titolo h1 { margin: 0; font-size: 15px; font-weight: 600; color: var(--tm-testo); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .tm-editor-salvato { font-size: 12px; color: var(--tm-testo-tenue); white-space: nowrap; } .tm-editor-azioni { display: flex; align-items: center; gap: 8px; flex: none; } /* Le tre zone: elenco, mappa, pannello. Elenco e pannello galleggiano sopra la mappa invece di restringerla: se togliessero spazio, aprirli per cambiare un nome sposterebbe il disegno sotto il puntatore. */ .tm-editor-corpo { position: relative; flex: 1 1 auto; min-height: 0; /* Lo spazio che elenco e pannello aperti tolgono ai lati: barra degli strumenti e controlli della mappa stanno nella parte libera, invece di finire sotto (o sopra) un pannello. */ --libero-sx: 12px; --libero-dx: 12px; } .tm-editor-corpo.con-elenco { --libero-sx: calc(min(270px, 100vw - 24px) + 24px); } .tm-editor-corpo.con-pannello { --libero-dx: calc(min(370px, 100vw - 24px) + 24px); } .tm-mappa .leaflet-left { left: calc(var(--libero-sx) - 12px); } .tm-mappa .leaflet-right { right: calc(var(--libero-dx) - 12px); } .tm-editor-mappa { position: absolute; inset: 0; } .tm-mappa { position: absolute; inset: 0; background: #efedea; } .tm-editor-nota { position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 500; max-width: min(92vw, 460px); margin: 0; padding: 9px 14px; border: 1px solid #e8d3ae; border-radius: 999px; background: var(--tm-attesa-tenue); box-shadow: var(--tm-ombra-2); font-size: 12.5px; text-align: center; color: var(--tm-attesa); } .tm-editor-nota a { color: inherit; font-weight: 600; } /* ── Barra degli strumenti di disegno ── */ .tm-strumenti { position: absolute; top: 12px; left: var(--libero-sx); right: var(--libero-dx); z-index: 650; display: flex; align-items: center; gap: 6px; width: fit-content; margin-inline: auto; padding: 5px; border: 1px solid var(--tm-bordo); border-radius: 12px; background: var(--tm-superficie); box-shadow: var(--tm-ombra-3); overflow-x: auto; } .tm-strumenti:empty { display: none; } .tm-strumento { flex: none; min-height: 34px; padding: 6px 12px; border: 1px solid transparent; border-radius: 8px; background: none; font: inherit; font-size: 13px; font-weight: 600; color: var(--tm-testo-medio); white-space: nowrap; cursor: pointer; transition: background-color .15s ease, color .15s ease; } .tm-strumento:hover { background: var(--tm-superficie-alt); color: var(--tm-testo); } .tm-strumento:focus-visible { outline: 2px solid var(--tm-accento); outline-offset: 1px; } .tm-strumento-principale { background: var(--tm-accento); color: #fff; } .tm-strumento-principale:hover { background: var(--tm-accento-scuro); color: #fff; } .tm-strumenti-modo { flex: none; padding: 0 8px 0 6px; font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--tm-pericolo); } /* ── Elenco ── */ .tm-editor-elenco { position: absolute; top: 12px; left: 12px; bottom: 12px; z-index: 600; width: min(270px, calc(100vw - 24px)); display: flex; flex-direction: column; border: 1px solid var(--tm-bordo); border-radius: var(--tm-raggio); background: var(--tm-superficie); box-shadow: var(--tm-ombra-3); overflow: hidden; } .tm-editor-elenco-cerca { flex: none; padding: 10px; border-bottom: 1px solid var(--tm-bordo); } .tm-editor-elenco-cerca input { width: 100%; padding: 8px 10px; border: 1px solid var(--tm-bordo-forte); border-radius: 8px; font: inherit; font-size: 13.5px; } .tm-editor-elenco-righe { flex: 1 1 auto; margin: 0; padding: 6px; list-style: none; overflow-y: auto; } .tm-editor-elenco-voce { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; min-height: 38px; padding: 7px 10px; border: 0; border-radius: 8px; background: none; font: inherit; font-size: 13.5px; text-align: left; color: var(--tm-testo); cursor: pointer; } .tm-editor-elenco-voce:hover { background: var(--tm-superficie-alt); } .tm-editor-elenco-voce.is-selezionata { background: var(--tm-accento-tenue); color: var(--tm-accento-scuro); font-weight: 600; } .tm-editor-elenco-stato { flex: none; font-size: 11px; font-weight: 600; color: var(--tm-testo-tenue); } .tm-stato-bozza, .tm-stato-modificata { color: var(--tm-attesa); } .tm-stato-pubblicata { color: var(--tm-ok); } .tm-editor-elenco-vuoto { padding: 14px 10px; font-size: 13px; color: var(--tm-testo-tenue); } /* ── Pannello della piantina ── */ .tm-editor-pannello { position: absolute; top: 12px; right: 12px; bottom: 12px; z-index: 600; width: min(370px, calc(100vw - 24px)); display: flex; flex-direction: column; border: 1px solid var(--tm-bordo); border-radius: var(--tm-raggio); background: var(--tm-superficie); box-shadow: var(--tm-ombra-3); overflow: hidden; } .tm-editor-pannello-testata { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex: none; padding: 12px 16px; border-bottom: 1px solid var(--tm-bordo); } .tm-editor-pannello-testata h2 { margin: 0; font-size: 14px; font-weight: 600; } .tm-editor-chiudi { background: none; border: 0; padding: 2px 6px; border-radius: 7px; color: var(--tm-testo-tenue); font-size: 20px; line-height: 1; cursor: pointer; transition: background-color .15s ease, color .15s ease; } .tm-editor-chiudi:hover { background: var(--tm-superficie-alt); color: var(--tm-testo); } .tm-editor-pannello-corpo { display: flex; flex-direction: column; gap: 20px; padding: 16px; overflow-y: auto; } .tm-editor-pannello-piede { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 10px; padding-top: 16px; border-top: 1px solid var(--tm-bordo); } .tm-editor-aiuto { margin: 0; font-size: 12.5px; line-height: 1.55; color: var(--tm-testo-tenue); } .tm-stato-piantina p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--tm-testo-medio); } .tm-azioni-riga { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; } .tm-azioni-riga:empty { display: none; } .tm-passi { margin: 0; padding-left: 20px; font-size: 13.5px; line-height: 1.6; color: var(--tm-testo-medio); } .tm-collegamento-piccolo { align-self: flex-start; padding: 0; border-top: 0; border-left: 0; border-right: 0; background: none; font: inherit; font-size: 12.5px; cursor: pointer; } .tm-solo-stretto { display: none; } /* Tablet: l'elenco si apre a richiesta e copre la mappa per il tempo della scelta. */ @media (max-width: 1099px) { .tm-editor-elenco { width: min(300px, calc(100vw - 24px)); } .tm-editor-corpo.con-elenco { --libero-sx: calc(min(300px, 100vw - 24px) + 24px); } } /* Telefono e tablet in verticale: il pannello sale dal basso. */ @media (max-width: 720px) { .tm-editor-barra { flex-wrap: wrap; } .tm-editor-titolo { order: 3; flex-basis: 100%; } .tm-editor-azioni .tm-btn span { display: none; } .tm-solo-stretto { display: inline-flex; } .tm-editor-pannello { top: auto; left: 0; right: 0; bottom: 0; width: auto; height: min(62dvh, 520px); border-radius: var(--tm-raggio) var(--tm-raggio) 0 0; } /* Elenco e pannello qui coprono la mappa per intero o dal basso: la barra resta in alto, sopra il foglio del pannello. */ .tm-editor-corpo, .tm-editor-corpo.con-elenco, .tm-editor-corpo.con-pannello { --libero-sx: 12px; --libero-dx: 12px; } /* A destra dei pulsanti dello zoom, e su più righe invece di uscire dallo schermo. */ .tm-strumenti { left: 58px; flex-wrap: wrap; } .tm-mappa .leaflet-left { left: 0; } /* Il foglio copre crediti e scala della mappa finché è aperto, invece di averli stampati sopra i campi. */ .tm-editor-pannello { z-index: 1001; } } /* Dita, non puntatore: vertici e maniglie di leaflet-draw più grandi, così si prendono senza zoomare al massimo. */ @media (pointer: coarse) { .leaflet-editing-icon, .leaflet-touch-icon { width: 22px !important; height: 22px !important; margin-left: -11px !important; margin-top: -11px !important; } .tm-strumento { min-height: 42px; padding: 8px 14px; } } /* ─── Finestra di pubblicazione ───────────────────────────────────────────── */ .tm-modale-sfondo { position: fixed; inset: 0; z-index: 800; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(28, 26, 23, .45); } .tm-modale { display: flex; flex-direction: column; width: 100%; max-width: 460px; max-height: calc(100dvh - 32px); border-radius: var(--tm-raggio); background: var(--tm-superficie); box-shadow: var(--tm-ombra-3); overflow: hidden; } .tm-modale-larga { max-width: 820px; } .tm-modale-testata { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 14px 18px; border-bottom: 1px solid var(--tm-bordo); } .tm-modale-testata h2 { margin: 0; font-size: 15px; font-weight: 600; } .tm-modale-corpo { display: flex; flex-direction: column; gap: 12px; padding: 18px; overflow-y: auto; } .tm-modale-piede { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--tm-bordo); } .tm-anteprima-pdf { width: 100%; height: min(62dvh, 640px); border: 1px solid var(--tm-bordo); border-radius: var(--tm-raggio-interno); background: var(--tm-superficie-alt); } .tm-attesa { display: flex; align-items: flex-start; gap: 14px; padding: 18px 4px; } .tm-attesa-titolo { margin: 0 0 4px; font-size: 14px; font-weight: 600; } .tm-attesa-giro { flex: none; width: 22px; height: 22px; border: 3px solid var(--tm-accento-tenue); border-top-color: var(--tm-accento); border-radius: 50%; animation: tm-giro .9s linear infinite; } @keyframes tm-giro { to { transform: rotate(360deg); } } @media (prefers-reduced-motion: reduce) { .tm-attesa-giro { animation-duration: 3s; } } .tm-nota-errore { border-color: #edc9c6; background: var(--tm-pericolo-tenue); color: var(--tm-pericolo); } /* ─── Avvisi galleggianti (componente ) ───────────────────── */ .tm-avvisi { position: fixed; top: 14px; left: 50%; transform: translateX(-50%); z-index: 900; display: flex; flex-direction: column; gap: 8px; width: min(92vw, 520px); pointer-events: none; } .tm-avviso { display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-radius: var(--tm-raggio-interno); border: 1px solid var(--tm-bordo); background: var(--tm-superficie); box-shadow: var(--tm-ombra-3); font-size: 13.5px; pointer-events: auto; } .tm-avviso svg { width: 18px; height: 18px; flex: none; } .tm-avviso-ok { border-color: #bcd9c9; background: var(--tm-ok-tenue); color: var(--tm-ok); } .tm-avviso-errore { border-color: #edc9c6; background: var(--tm-pericolo-tenue); color: var(--tm-pericolo); } .tm-avviso-chiudi { margin-left: auto; background: none; border: 0; padding: 0 4px; color: inherit; font-size: 19px; line-height: 1; opacity: .6; cursor: pointer; } .tm-avviso-chiudi:hover { opacity: 1; } /* ─── Responsive list tables ─────────────────────────────────────────────── Under 640px (a phone held in portrait; rotate to landscape and the width grows past the breakpoint, restoring the normal table) every table with the `table-cards` class reflows: the header is hidden and each row becomes a card, with each cell shown as "LABEL … value" (the label comes from the cell's data-label attribute). Cells with no data-label (the actions column, marked `.cell-actions`) span the row full width. */ @media (max-width: 640px) { table.table-cards, table.table-cards tbody { display: block; width: 100%; } table.table-cards thead { display: none; } table.table-cards tr { display: block; border: 1px solid var(--tm-bordo); border-radius: var(--tm-raggio-interno); margin-bottom: 12px; padding: 4px 2px; background: var(--tm-superficie); } /* zebra striping would fight the card borders */ table.table-cards.table-striped tbody tr:nth-child(even) { background: var(--tm-superficie); } table.table-cards td { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; text-align: right; padding: 6px 12px; border: none !important; } table.table-cards td[data-label]::before { content: attr(data-label); flex: 0 0 auto; margin-right: auto; text-align: left; font-size: 11px; font-weight: 600; color: var(--tm-testo-tenue); text-transform: uppercase; letter-spacing: .04em; } /* Actions row: full width, buttons wrapped to the right */ table.table-cards td.cell-actions { justify-content: flex-end; flex-wrap: wrap; margin-top: 2px; padding-top: 10px; border-top: 1px solid var(--tm-bordo) !important; } /* Riga di separazione di un gruppo (l'anno teocratico negli storici): resta un titolo, non diventa una scheda. */ table.table-cards tr.tm-riga-gruppo { border: none; background: transparent; padding: 0; margin: 16px 0 6px; } table.table-cards tr.tm-riga-gruppo th { display: block; padding: 0 2px; } /* Cells spanning all columns (empty state, inline edit form) stay full width and block, so their inner layout isn't squeezed by the flex row. */ table.table-cards td[colspan] { display: block; text-align: center; } } /* ─── Campo di scelta con ricerca () ────────────────────────────── Al posto delle tendine di territori e proclamatori. Pensato anche per il telefono: testo a 16px (sotto, iOS ingrandisce la pagina al tocco), voci alte almeno 44px, elenco che scorre dentro mezzo schermo. I selettori battono `.tm-campo input[type="text"]` dell'editor delle piantine. */ .tm-scelta { position: relative; width: 100%; } .tm-scelta-campo { position: relative; display: flex; align-items: center; } .tm-scelta input.tm-scelta-input { width: 100%; min-height: 44px; padding: 8px 76px 8px 12px; border: 1px solid var(--tm-bordo-forte); border-radius: var(--tm-raggio-interno); background: var(--tm-superficie); color: var(--tm-testo); font-family: inherit; font-size: 16px; line-height: 1.3; transition: border-color .15s ease, box-shadow .15s ease; } @media (min-width: 640px) { .tm-scelta input.tm-scelta-input { min-height: 40px; font-size: 14px; } } .tm-scelta input.tm-scelta-input:focus { outline: none; border-color: var(--tm-accento); box-shadow: 0 0 0 3px var(--tm-accento-tenue); } .tm-scelta input.tm-scelta-input:disabled { padding-right: 12px; background: var(--tm-superficie-alt); color: var(--tm-testo-medio); } .tm-scelta input.tm-scelta-input::placeholder { color: var(--tm-testo-tenue); } .tm-scelta-pulisci, .tm-scelta-apri { position: absolute; top: 50%; display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; margin-top: -18px; border: 0; border-radius: 8px; background: transparent; color: var(--tm-testo-tenue); cursor: pointer; } .tm-scelta-pulisci { right: 38px; } .tm-scelta-apri { right: 2px; } .tm-scelta-pulisci:hover, .tm-scelta-apri:hover { color: var(--tm-testo); background: var(--tm-superficie-alt); } .tm-scelta-pulisci svg, .tm-scelta-apri svg { width: 18px; height: 18px; transition: transform .15s ease; } .tm-scelta-apri svg.tm-scelta-giu { transform: rotate(180deg); } .tm-scelta-elenco { position: absolute; z-index: 40; top: calc(100% + 4px); left: 0; right: 0; max-height: min(50vh, 20rem); margin: 0; padding: 4px; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; list-style: none; border: 1px solid var(--tm-bordo); border-radius: var(--tm-raggio-interno); background: var(--tm-superficie); box-shadow: var(--tm-ombra-3); } .tm-scelta-voce { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 8px; row-gap: 2px; min-height: 44px; padding: 10px 12px; border-radius: 8px; color: var(--tm-testo); font-size: 15px; cursor: pointer; -webkit-tap-highlight-color: transparent; } @media (min-width: 640px) { .tm-scelta-voce { min-height: 36px; padding: 7px 10px; font-size: 14px; } } .tm-scelta-voce-attiva { background: var(--tm-accento-tenue); } .tm-scelta-voce-scelta .tm-scelta-etichetta { font-weight: 700; color: var(--tm-accento-scuro); } .tm-scelta-voce-speciale { color: var(--tm-testo-medio); } .tm-scelta-voce-spenta { cursor: not-allowed; color: var(--tm-testo-tenue); } .tm-scelta-voce-spenta.tm-scelta-voce-attiva { background: var(--tm-superficie-alt); } .tm-scelta-dettaglio { font-size: 13px; color: var(--tm-testo-tenue); } .tm-scelta-motivo { flex-basis: 100%; font-size: 12px; color: var(--tm-attesa); } .tm-scelta-forse { padding: 1px 6px; border-radius: 999px; background: var(--tm-attesa-tenue); color: var(--tm-attesa); font-size: 11px; font-weight: 600; } .tm-scelta-vuoto { padding: 12px; color: var(--tm-testo-tenue); font-size: 14px; } /* ─── Elenco dei territori assegnati (pagina Assegna) ─────────────────────── Classi brevi al posto delle catene di utility: le righe sono ~80 e ogni byte si moltiplica (ElencoAssegnati, AssegnaPrestazioniTest). */ .tm-assegnato { padding: 16px 20px; } .tm-assegnato svg { width: 16px; height: 16px; fill: none; stroke: currentColor; flex: none; } .tm-assegnato-testa { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 8px 24px; } .tm-assegnato-numero { color: #4f46e5; font-size: 14px; font-weight: 700; } .tm-assegnato-numero:hover { text-decoration: underline; } /* Campo trappola del modulo pubblico delle richieste: fuori dallo schermo, non `display:none` (alcuni programmi saltano i campi nascosti così). */ .tm-trappola { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; } /* Il numero come pulsante ("Il mio gruppo": apre l'anteprima): stesso aspetto. */ button.tm-assegnato-numero { background: none; border: 0; padding: 0; cursor: pointer; font-family: inherit; line-height: inherit; } button.tm-assegnato-numero:focus-visible { outline: 2px solid var(--tm-accento); outline-offset: 2px; border-radius: 2px; } .tm-assegnato-zona { margin-left: 6px; padding: 2px 6px; border-radius: 4px; background: #f3f4f6; color: #9ca3af; font-size: 12px; } /* Il proclamatore ha chiesto la cartolina cartacea (elenco Cartacei). */ .tm-cartaceo { margin-left: 4px; padding: 2px 6px; border-radius: 4px; background: #fffbeb; color: #b45309; font-size: 12px; font-weight: 600; } .tm-assegnato-info { color: #6b7280; font-size: 12px; } .tm-assegnato-info b { color: #1f2937; font-size: 14px; font-weight: 500; } .tm-assegnato-giorni { padding: 2px 8px; border-radius: 999px; background: #f3f4f6; color: #6b7280; font-weight: 600; } .tm-assegnato-giorni.tm-g-presto { background: #fffbeb; color: #d97706; } .tm-assegnato-giorni.tm-g-tardi { background: #fef2f2; color: #dc2626; } .tm-assegnato-sospeso { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; padding: 6px 12px; border: 1px solid #fde68a; border-radius: 6px; background: #fffbeb; color: #92400e; font-size: 12px; font-weight: 600; } .tm-assegnato-link { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; } .tm-assegnato-link > * { flex: none; } .tm-assegnato-link code { flex: 1 1 0; min-width: 0; padding: 8px 12px; border: 1px solid #e5e7eb; border-radius: 6px; background: #f9fafb; color: #4b5563; font-size: 12px; word-break: break-all; user-select: all; cursor: text; } .tm-assegnato-senza { margin-top: 8px; color: #d1d5db; font-size: 12px; } /* Pulsante copia: la spunta al posto dell'icona per due secondi. */ .tm-copia svg + svg, .tm-copia.tm-copiato svg:first-child { display: none; } .tm-copia.tm-copiato svg + svg { display: block; color: #16a34a; }