:root {
  color-scheme: dark;
  --bg: #0f172a;
  --bg-inset: #0b1222;
  --panel-bg: #1e293b;
  --panel-bg-alt: #24324a;
  --border: #334155;
  --border-strong: #475569;
  --text: #e2e8f0;
  --text-muted: #8b9bb4;
  --accent: #3b82f6;
  --accent-strong: #60a5fa;
  --positive: #22c55e;
  --negative: #f59e0b;
  --danger: #ef4444;

  --badge-produzione-bg: rgba(59, 130, 246, 0.16);
  --badge-produzione-text: #93c5fd;
  --badge-produzione-border: #3b82f6;

  --badge-buffer-bg: rgba(245, 158, 11, 0.14);
  --badge-buffer-text: #fbbf24;
  --badge-buffer-border: #f59e0b;

  --badge-ok-bg: rgba(34, 197, 94, 0.16);
  --badge-ok-text: #86efac;
  --badge-ok-border: #22c55e;

  --badge-alert-bg: rgba(239, 68, 68, 0.16);
  --badge-alert-text: #fca5a5;
  --badge-alert-border: #ef4444;

  --badge-neutral-bg: rgba(148, 163, 184, 0.16);
  --badge-neutral-text: #cbd5e1;
  --badge-neutral-border: #64748b;

  --badge-progress-bg: rgba(59, 130, 246, 0.16);
  --badge-progress-text: #93c5fd;
  --badge-progress-border: #3b82f6;

  --badge-imprevisto-bg: #9333ea;
  --badge-imprevisto-text: #ffffff;
  --badge-imprevisto-border: #7e22ce;

  --row-imprevisto-bg: rgba(147, 51, 234, 0.15);
  --row-imprevisto-bg-hover: rgba(147, 51, 234, 0.24);
  --row-imprevisto-text: #c084fc;

  --badge-pronto-bg: rgba(234, 179, 8, 0.18);
  --badge-pronto-text: #fde047;
  --badge-pronto-border: #eab308;

  --badge-pronto-inattivo-bg: rgba(148, 163, 184, 0.1);
  --badge-pronto-inattivo-text: var(--text-muted);
  --badge-pronto-inattivo-border: var(--border-strong);

  --row-pronto-bg: rgba(234, 179, 8, 0.1);
  --row-pronto-bg-hover: rgba(234, 179, 8, 0.18);

  --row-fatto-bg: rgba(34, 197, 94, 0.14);
  --row-fatto-bg-hover: rgba(34, 197, 94, 0.22);

  /* giallo pastello PIENO (non un overlay rgba() come gli altri sfondi di
     riga sopra: su questo tema scuro un rgba() trasparente risultava troppo
     spento/scuro invece che un'evidenziazione chiara — verificato e
     abbandonato). Stessa identica coppia in entrambi i temi, non serve un
     override nel blocco :root[data-theme="light"] piu' sotto. Il testo
     scuro fisso (non var(--text), pensato per sfondi scuri) e' necessario
     per restare leggibile su questo giallo chiaro in ENTRAMBI i temi. */
  --row-in-lavorazione-bg: #ffffd0;
  --row-in-lavorazione-bg-hover: #f5f5b4;
  --row-in-lavorazione-text: #1a1a1a;

  /* testo della riga di sub-totale (tabulator-calcs): sempre a contrasto
     massimo sopra --bg-inset, che pero' si inverte da scuro a chiaro col
     tema, quindi non puo' restare un valore fisso come nella versione
     originale (era #f8fafc, illeggibile su sfondo chiaro) */
  --calc-row-text: #f8fafc;
  /* traccia di sfondo della barra di avanzamento commessa: un velo bianco
     trasparente si vede solo su sfondo scuro, va invertito in chiaro */
  --progress-track-bg: rgba(255, 255, 255, 0.12);

  --badge-totale-com-bg: rgba(245, 158, 11, 0.18);
  --badge-totale-com-text: #fbbf24;
  --badge-totale-com-border: #f59e0b;

  --mono-font: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
}

/* Theme Switcher: tema chiaro, attivato impostando data-theme="light" su
   <html> (vedi applicaTema/toggleTema in app.js, che legge/scrive la
   preferenza in localStorage). Il tema scuro industriale resta il default
   di :root sopra; qui si ridefiniscono solo i token che devono invertirsi
   (superfici, testo, bordi, palette semantica dei badge) cosi' ogni
   componente della dashboard, gia' costruito sopra i custom properties,
   si adatta automaticamente senza bisogno di regole duplicate. */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f1f5f9;
  --bg-inset: #e2e8f0;
  --panel-bg: #ffffff;
  --panel-bg-alt: #f8fafc;
  --border: #cbd5e1;
  --border-strong: #94a3b8;
  --text: #1e293b;
  --text-muted: #64748b;
  --accent: #2563eb;
  --accent-strong: #1d4ed8;
  --positive: #16a34a;
  --negative: #d97706;
  --danger: #dc2626;

  --badge-produzione-bg: rgba(37, 99, 235, 0.12);
  --badge-produzione-text: #1d4ed8;
  --badge-produzione-border: #2563eb;

  --badge-buffer-bg: rgba(217, 119, 6, 0.12);
  --badge-buffer-text: #b45309;
  --badge-buffer-border: #d97706;

  --badge-ok-bg: rgba(22, 163, 74, 0.12);
  --badge-ok-text: #15803d;
  --badge-ok-border: #16a34a;

  --badge-alert-bg: rgba(220, 38, 38, 0.12);
  --badge-alert-text: #b91c1c;
  --badge-alert-border: #dc2626;

  --badge-neutral-bg: rgba(100, 116, 139, 0.14);
  --badge-neutral-text: #475569;
  --badge-neutral-border: #64748b;

  --badge-progress-bg: rgba(37, 99, 235, 0.12);
  --badge-progress-text: #1d4ed8;
  --badge-progress-border: #2563eb;

  --row-imprevisto-bg: rgba(147, 51, 234, 0.1);
  --row-imprevisto-bg-hover: rgba(147, 51, 234, 0.16);
  --row-imprevisto-text: #7e22ce;

  --badge-pronto-bg: rgba(202, 138, 4, 0.14);
  --badge-pronto-text: #a16207;
  --badge-pronto-border: #ca8a04;

  --badge-pronto-inattivo-bg: rgba(100, 116, 139, 0.1);

  --row-pronto-bg: rgba(202, 138, 4, 0.08);
  --row-pronto-bg-hover: rgba(202, 138, 4, 0.16);

  --row-fatto-bg: rgba(22, 163, 74, 0.1);
  --row-fatto-bg-hover: rgba(22, 163, 74, 0.16);

  --calc-row-text: #0f172a;
  --progress-track-bg: rgba(15, 23, 42, 0.12);

  --badge-totale-com-bg: rgba(217, 119, 6, 0.14);
  --badge-totale-com-text: #b45309;
  --badge-totale-com-border: #d97706;
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

/* dashboard a tutto schermo, senza scroll di pagina (solo desktop: vedi
   override in fondo al file per il breakpoint mobile) */
html,
body {
  height: 100vh;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

body {
  display: flex;
  flex-direction: column;
  font-family: -apple-system, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
}

/* scrollbar in tema con il pannello scuro */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: var(--bg-inset);
}
::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 6px;
}

header {
  display: flex;
  flex-wrap: wrap;
  flex-shrink: 0;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 2rem;
  background: var(--bg-inset);
  border-bottom: 1px solid var(--border);
}

.header-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

header h1 {
  font-size: 1.25rem;
  margin: 0;
  letter-spacing: 0.02em;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.25rem 0.65rem;
  border-radius: 999px;
  background: var(--badge-ok-bg);
  border: 1px solid var(--badge-ok-border);
  color: var(--badge-ok-text);
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.version-tag {
  text-transform: none;
  font-weight: 600;
  opacity: 0.75;
  letter-spacing: 0.02em;
}

.status-pill .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--positive);
  box-shadow: 0 0 6px 1px var(--positive);
  animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

.header-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}

.header-actions select,
.header-actions a {
  padding: 0.65rem 1rem;
  min-height: 44px;
  border-radius: 6px;
  border: 1px solid var(--border);
  font-size: 16px;
  background: var(--panel-bg);
  color: var(--text);
}

.header-actions a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.header-actions select:focus,
.filters select:focus,
.filters input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
}

.header-actions a {
  background: var(--accent);
  color: #f8fafc;
  text-decoration: none;
  border-color: var(--accent);
  font-weight: 600;
  transition: background 0.15s ease;
}

.header-actions a:hover {
  background: var(--accent-strong);
}

.btn {
  padding: 0.6rem 1rem;
  min-height: 44px;
  border-radius: 6px;
  border: 1px solid var(--border);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--accent);
  color: #f8fafc;
  border-color: var(--accent);
}

.btn-primary:hover:not(:disabled) {
  background: var(--accent-strong);
}

.btn-secondary {
  background: var(--panel-bg);
  color: var(--text);
}

.btn-secondary:hover:not(:disabled) {
  background: var(--panel-bg-alt);
  border-color: var(--border-strong);
}

.btn-warning {
  background: var(--badge-pronto-border);
  color: #1c1305;
  border-color: var(--badge-pronto-border);
}

.btn-warning:hover:not(:disabled) {
  background: var(--badge-pronto-text);
  border-color: var(--badge-pronto-text);
}

/* pulsante icona-soltanto per il Theme Switcher: stessa altezza minima di
   tocco (44px) degli altri controlli dell'header, ma quadrato invece che
   allungato dal padding orizzontale di .btn */
.theme-toggle-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  padding: 0;
  font-size: 1.2rem;
  line-height: 1;
}

/* finestra di conferma per la duplicazione dello Sprint */
.app-dialog {
  background: var(--panel-bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1.5rem;
  max-width: 420px;
  width: calc(100% - 2rem);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
}

.app-dialog::backdrop {
  background: rgba(0, 0, 0, 0.55);
}

.app-dialog h2 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
}

.app-dialog p {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.85rem;
  line-height: 1.45;
}

/* messaggio d'errore nei dialog (es. PIN amministratore errato): piu'
   specifico di ".app-dialog p" sopra, che lo renderebbe altrimenti muted */
.app-dialog .dialog-error {
  color: var(--danger);
  font-weight: 600;
}

.dialog-input {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 0.65rem 0.85rem;
  margin: 0.85rem 0 1.1rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg-inset);
  color: var(--text);
  font-size: 16px;
  box-sizing: border-box;
}

.dialog-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
}

.dialog-checkbox {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-height: 44px;
  padding: 0.65rem 0.85rem;
  margin: 1.1rem 0;
  background: var(--bg-inset);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.9rem;
  cursor: pointer;
}

.dialog-checkbox input[type="checkbox"] {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  accent-color: var(--accent);
  cursor: pointer;
}

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.75rem;
}

@media (max-width: 480px) {
  .dialog-actions {
    flex-direction: column-reverse;
  }

  .dialog-actions .btn {
    width: 100%;
  }
}

/* modal "Carico per persona" ingrandito: <dialog> nativo, largo (80-90% del
   viewport), che ospita la stessa tabella #carico-table SPOSTATA (non
   clonata) al suo interno mentre e' aperto — vedi apriModalCarico /
   riportaTabellaCaricoNellaSidebar in app.js. Il dialog nativo chiude gia'
   da solo su Escape; il click sul backdrop e' gestito confrontando le
   coordinate del click col rettangolo del dialog (vedi app.js), perche'
   ::backdrop non e' un elemento su cui si possa mettere un listener diretto. */
.modal-carico-dialog {
  width: min(90vw, 1200px);
  max-width: min(90vw, 1200px);
  max-height: 85vh;
  padding: 0;
}

.modal-carico-dialog[open] {
  display: flex;
  flex-direction: column;
}

.modal-carico-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  padding: 1.1rem 1.5rem;
  border-bottom: 1px solid var(--border);
}

.modal-carico-header h2 {
  margin: 0;
  font-size: 1.05rem;
}

.modal-carico-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 1.5rem;
}

/* dentro il modal c'e' spazio abbondante: niente scroll orizzontale e
   colonne piu' respirate rispetto alla stessa tabella nella sidebar stretta */
.modal-carico-body .table-scroll {
  overflow-x: visible;
}

.modal-carico-body #carico-table {
  width: 100%;
}

.modal-carico-body #carico-table th,
.modal-carico-body #carico-table td {
  padding: 0.85rem 1.1rem;
  font-size: 0.95rem;
}

@media (max-width: 720px) {
  .modal-carico-dialog {
    width: calc(100% - 2rem);
  }
}

main {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  padding: 1.5rem 2rem 1.5rem;
  max-width: 100%;
  margin: 0 auto;
  width: 100%;
  box-sizing: border-box;
  overflow: hidden;
}

.cards {
  display: grid;
  flex-shrink: 0;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1rem;
}

.card {
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1rem;
  position: relative;
  overflow: hidden;
}

.card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--accent);
  opacity: 0.7;
}

.card .label {
  display: block;
  font-size: 0.72rem;
  color: var(--text-muted);
  margin-bottom: 0.35rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.card .value {
  font-size: 1.6rem;
  font-weight: 600;
  font-family: var(--mono-font);
  color: var(--text);
}

/* card con selettore di data (Inizio sprint / Review) */
.card-date {
  display: flex;
  flex-direction: column;
}

.card-field-input {
  color-scheme: dark;
  width: 100%;
  min-height: 44px;
  padding: 0.5rem 0.65rem;
  border-radius: 8px;
  border: 1px solid var(--border-strong);
  background: var(--bg-inset);
  color: var(--text);
  font-family: var(--mono-font);
  font-size: 16px;
  box-sizing: border-box;
}

.card-field-input::-webkit-calendar-picker-indicator {
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  filter: invert(0.85);
}

/* nel tema chiaro l'input torna a un color-scheme nativo chiaro (l'icona del
   calendario e' gia' scura di suo: l'invert del tema scuro qui sopra la
   renderebbe illeggibile su sfondo chiaro) */
:root[data-theme="light"] .card-field-input {
  color-scheme: light;
}

:root[data-theme="light"] .card-field-input::-webkit-calendar-picker-indicator {
  filter: none;
}

.card-field-input::-webkit-calendar-picker-indicator:hover {
  background: var(--panel-bg-alt);
}

.card-field-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
}

/* editor "Scadenza" della tabella Task (vedi scadenzaEditor in app.js): un
   <input type="date"> nativo. Le dimensioni/lo sfondo arrivano gia' dalla
   regola generica ".tabulator-cell.tabulator-editing input" in fondo al
   file; qui serve solo l'icona del calendario, con lo stesso trattamento
   scuro/chiaro di .card-field-input sopra (altrimenti resta nera anche sullo
   sfondo scuro dell'editor, quasi invisibile) */
.tabulator-editor-scadenza::-webkit-calendar-picker-indicator {
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  filter: invert(0.85);
}

:root[data-theme="light"] .tabulator-editor-scadenza::-webkit-calendar-picker-indicator {
  filter: none;
}

.panel {
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1.25rem;
  margin-bottom: 1.5rem;
  max-width: 100%;
  flex-shrink: 0;
}

/* pannello Task: unica sezione che deve occupare lo spazio verticale
   residuo ed eseguire lo scroll internamente (griglia Tabulator), cosi'
   la pagina intera non scorre mai su desktop */
.panel-task {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.panel-task .panel-header,
.panel-task .filters {
  flex-shrink: 0;
}

/* contenitore di scroll orizzontale dedicato alle tabelle: solo la tabella
   scorre lateralmente, non l'intero pannello (titolo/filtri restano fissi) */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: 8px;
}

.table-scroll::-webkit-scrollbar {
  height: 8px;
}

.panel h2 {
  margin-top: 0;
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

.panel-header h2 {
  margin: 0;
}

.panel-header-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* varianti compatte dei pulsanti (es. Comprimi/Espandi tutti i gruppi):
   stessa palette di .btn-secondary ma dimensioni ridotte, per non competere
   visivamente con l'azione primaria "+ Nuovo task" */
.btn-compact {
  padding: 0.4rem 0.75rem;
  min-height: 34px;
  font-size: 0.78rem;
}

/* pannello a scomparsa generico (Riepilogo Sprint, Carico per persona,
   entrambi dentro la sidebar KPI/Carico qui sotto): header cliccabile (h2 o
   pulsante freccia) + contenuto che collassa in modo fluido */
.panel-collapsible {
  transition: padding-bottom 0.25s ease;
}

.panel-collapsible.collapsed {
  padding-bottom: 0.85rem;
}

/* sidebar KPI/Carico: pannello laterale a scomparsa (slide-in da destra),
   apre/chiude con #kpi-sidebar-toggle-btn nell'header (vedi toggleSidebarKpi
   in app.js). E' un overlay non modale — a differenza dei dialog di conferma
   dell'app, non ha un backdrop che blocca il resto della pagina: contiene
   campi editabili (giorni, date, velocita' target) pensati per restare
   consultabili/modificabili mentre si lavora sulla tabella Task sottostante.
   Posizionata fixed, quindi fuori dal flusso normale: aprirla/chiuderla non
   fa mai ridimensionare il pannello Task (occupa sempre tutto lo spazio
   verticale disponibile in main, che ora contiene solo lui). */
.kpi-sidebar {
  position: fixed;
  /* parte da sotto l'header (altezza misurata in JS, vedi
     impostaAltezzaHeader in app.js: l'header non ha un'altezza fissa,
     cambia col wrapping su schermi stretti), non da top:0 — altrimenti
     coprirebbe l'header stesso, incluso il pulsante che la apre/chiude */
  top: var(--header-height, 68px);
  right: 0;
  height: calc(100vh - var(--header-height, 68px));
  width: min(420px, 100vw);
  background: var(--panel-bg);
  border-left: 1px solid var(--border);
  box-shadow: -12px 0 32px rgba(0, 0, 0, 0.35);
  transform: translateX(100%);
  transition: transform 0.28s ease;
  z-index: 40;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.kpi-sidebar.open {
  transform: translateX(0);
}

.kpi-sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  padding: 1.1rem 1.25rem;
  border-bottom: 1px solid var(--border);
}

.kpi-sidebar-header h2 {
  margin: 0;
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}

.kpi-sidebar-close-btn {
  width: 32px;
  font-size: 0.85rem;
}

.kpi-sidebar-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* lo spazio tra i due pannelli lo da' il "gap" del contenitore flex qui
   sopra: senza azzerare il margin-bottom ereditato da .panel (pensato per
   pannelli affiancati orizzontalmente in main) lo spazio raddoppierebbe */
.kpi-sidebar-body .panel {
  margin-bottom: 0;
}

/* nella sidebar stretta (max 420px) le card KPI stanno meglio su colonne
   piu' strette che nell'area piena di main */
.kpi-sidebar .cards {
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
}

@media (max-width: 480px) {
  .kpi-sidebar {
    width: 100vw;
  }
}

.panel-header-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  cursor: pointer;
  user-select: none;
}

.panel-header-toggle h2 {
  margin: 0;
}

/* raggruppa il pulsante "Espandi" (modal Carico per persona) e la freccia
   di comprimi/espandi nello stesso angolo dell'header, cosi' il layout
   space-between del contenitore resta a due soli elementi (titolo + azioni) */
.panel-header-toggle-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.panel-toggle-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  min-width: 32px;
  flex-shrink: 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.panel-toggle-btn:hover {
  background: var(--panel-bg-alt);
  border-color: var(--border-strong);
}

.panel-toggle-icon {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid var(--text-muted);
  transition: transform 0.25s ease;
}

/* freccia verso il basso = espanso, ruotata = collassato */
.panel-toggle-btn[aria-expanded="false"] .panel-toggle-icon {
  transform: rotate(-90deg);
}

.collapsible {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 0.25s ease;
}

.collapsible.collapsed {
  grid-template-rows: 0fr;
}

.collapsible-inner {
  overflow: hidden;
  min-height: 0;
}

.collapsible-inner > .table-scroll {
  margin-top: 0.75rem;
}

.filters {
  display: flex;
  gap: 1rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}

.filters label {
  display: flex;
  flex-direction: column;
  font-size: 0.72rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  gap: 0.3rem;
}

.filters select,
.filters input {
  padding: 0.65rem 0.75rem;
  min-height: 44px;
  border-radius: 6px;
  border: 1px solid var(--border);
  font-size: 16px;
  background: var(--bg-inset);
  color: var(--text);
}

.filters input::placeholder {
  color: var(--text-muted);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

th, td {
  text-align: left;
  padding: 0.55rem 0.6rem;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

td.wrap {
  white-space: normal;
  min-width: 200px;
}

td.numeric {
  font-family: var(--mono-font);
}

th {
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--panel-bg-alt);
  position: sticky;
  top: 0;
}

tbody tr:hover {
  background: var(--panel-bg-alt);
}

/* riga dei totali (es. Capacita' teorica totale nel Carico per persona) */
tfoot .totals-row td {
  border-top: 2px solid var(--border-strong);
  border-bottom: none;
  background: var(--panel-bg-alt);
  color: var(--text);
  font-weight: 700;
  font-family: var(--mono-font);
}

tfoot .totals-row td:first-child {
  font-family: inherit;
  text-transform: uppercase;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

/* badge di stato / origine, in stile pannello di controllo industriale */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.badge-produzione {
  background: var(--badge-produzione-bg);
  color: var(--badge-produzione-text);
  border-color: var(--badge-produzione-border);
}

.badge-buffer {
  background: var(--badge-buffer-bg);
  color: var(--badge-buffer-text);
  border-color: var(--badge-buffer-border);
}

.badge-pronto-attivo {
  background: var(--badge-pronto-bg);
  color: var(--badge-pronto-text);
  border-color: var(--badge-pronto-border);
}

.badge-pronto-inattivo {
  background: var(--badge-pronto-inattivo-bg);
  color: var(--badge-pronto-inattivo-text);
  border-color: var(--badge-pronto-inattivo-border);
}

/* badge Origine come toggle button: tocco/click commuta subito
   Produzione <-> Buffer (vedi toggleOrigine in app.js). Compatto come gli
   altri badge della tabella (Stato, Delta, ecc.) invece che a dimensione
   "pulsante", cosi' non occupa spazio eccessivo nella cella. */
.badge-toggle {
  min-height: 22px;
  padding: 2px 7px;
  border-radius: 999px;
  border-width: 1.5px;
  font-family: inherit;
  font-size: 0.7rem;
  cursor: pointer;
  gap: 0.3rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: transform 0.1s ease, box-shadow 0.1s ease, filter 0.15s ease;
}

.badge-toggle:hover {
  filter: brightness(1.15);
}

.badge-toggle:active {
  transform: scale(0.96);
  box-shadow: none;
}

.badge-toggle:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
}

.badge-toggle-icon {
  font-size: 0.85em;
  opacity: 0.8;
}

.badge-delta-ok {
  background: var(--badge-ok-bg);
  color: var(--badge-ok-text);
  border-color: var(--badge-ok-border);
}

.badge-delta-alert {
  background: var(--badge-alert-bg);
  color: var(--badge-alert-text);
  border-color: var(--badge-alert-border);
}

.badge-persona {
  background: var(--panel-bg-alt);
  color: var(--text);
  border-color: var(--border-strong);
  font-family: var(--mono-font);
}

.badge-stato-da-fare {
  background: var(--badge-neutral-bg);
  color: var(--badge-neutral-text);
  border-color: var(--badge-neutral-border);
}

.badge-stato-in-corso {
  background: var(--badge-progress-bg);
  color: var(--badge-progress-text);
  border-color: var(--badge-progress-border);
}

.badge-stato-bloccato {
  background: var(--badge-alert-bg);
  color: var(--badge-alert-text);
  border-color: var(--badge-alert-border);
}

.badge-stato-fatto {
  background: var(--badge-ok-bg);
  color: var(--badge-ok-text);
  border-color: var(--badge-ok-border);
}

.badge-stato-imprevisto {
  background: var(--badge-imprevisto-bg);
  color: var(--badge-imprevisto-text);
  border-color: var(--badge-imprevisto-border);
  font-weight: 800;
}

.empty-state {
  color: var(--text-muted);
  font-size: 0.9rem;
}

/* --- Tabulator: adattamento al tema dark industriale --- */
/* l'altezza NON e' piu' affidata a flex:1 + Tabulator height:"100%": viene
   calcolata esplicitamente in JS (calcolaAltezzaTabellaTask in app.js) e
   applicata da Tabulator stesso come inline style. Con flex:1 il container
   e Tabulator si "rincorrevano" ad ogni frame della transizione CSS del
   pannello Carico (ResizeObserver -> redraw -> nuova misura -> resize...),
   bloccando la pagina per diversi secondi (riprodotto e verificato). */
#task-table {
  margin-top: 0.5rem;
  width: 100%;
  max-width: 100%;
  flex: none;
  overflow-x: auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

#task-table .tabulator-tableholder {
  overflow-y: auto;
}

/* con layout:"fitColumns" Tabulator prova a comprimere le colonne per
   stare nel container, ma non scende sotto la larghezza minima di ognuna:
   su schermi stretti (molte colonne come Progetto/Cliente/User story) il
   contenuto resta comunque piu' largo della viewport e scorre in
   orizzontale. .tabulator-tableholder e' il contenitore che scorre e deve
   restare ancorato al 100% della viewport (altrimenti non ci sarebbe nulla
   da scorrere); .tabulator-table invece e' il contenuto reale delle righe e
   deve potersi ESTENDERE oltre il 100% quando le colonne lo richiedono
   (min-width:max-content), altrimenti lo sfondo di righe/gruppi si
   interrompe prima delle colonne piu' a destra durante lo scroll. */
#task-table .tabulator-tableholder {
  width: 100% !important;
  min-width: 100% !important;
}

#task-table .tabulator-table {
  width: 100% !important;
  min-width: max-content !important;
}

/* riduce i micro-scatti durante lo scroll e l'espandi/comprimi di un
   gruppo Commessa: "contain: content" isola il layout/paint di questo
   sottoalbero (un cambio di altezza dentro non forza il ricalcolo del
   resto della pagina), "will-change: transform" prepara in anticipo un
   layer compositato per lo scroll, che il browser altrimenti creerebbe (e
   scarterebbe) ad ogni gesto di scroll */
#task-table .tabulator-tableholder {
  contain: content;
  will-change: transform;
}

.tabulator {
  background: var(--bg-inset);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.85rem;
  color: var(--text);
  max-width: 100%;
  height: 100%;
}

.tabulator .tabulator-header {
  background: var(--panel-bg-alt);
  border-bottom: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.tabulator .tabulator-header .tabulator-col {
  background: var(--panel-bg-alt);
  border-right: 1px solid var(--border);
}

.tabulator .tabulator-header .tabulator-col-content {
  padding: 0.55rem 0.6rem;
}

.tabulator-row {
  background: var(--bg-inset);
  color: var(--text);
  border-bottom: 1px solid var(--border);
}

/* le righe devono potersi estendere oltre il 100% della viewport quando le
   colonne non ci stanno tutte (vedi .tabulator-table sopra): altrimenti lo
   sfondo/evidenziazione (anche "IMPREVISTO", vedi .row-imprevisto piu'
   sotto) copre solo la parte inizialmente visibile invece che l'intera
   larghezza scorrevole fino all'ultima colonna */
#task-table .tabulator-row {
  width: 100% !important;
  min-width: max-content !important;
}

.tabulator-row.tabulator-row-even {
  background: var(--panel-bg);
}

.tabulator-row:hover {
  background: var(--panel-bg-alt) !important;
}

.tabulator-row .tabulator-cell {
  border-right: 1px solid var(--border);
  padding: 0.5rem 0.6rem;
}

.tabulator-row .tabulator-cell.tabulator-editing {
  /* la cella (e quindi la riga, che non ha un'altezza fissa: vedi
     .tabulator-row nel resto del file) segue l'altezza naturale del suo
     contenuto — con l'editor "textarea" sotto in flusso normale (non piu'
     position:absolute come in una versione precedente di questa regola,
     che faceva "fluttuare" il testo sopra le righe sottostanti SENZA far
     crescere la riga stessa, dando l'impressione che si fosse ristretta)
     questo e' cio' che permette alla riga di allargarsi ed espandere
     tutto il testo multilinea invece di tagliarlo */
  height: auto !important;
  min-height: 100% !important;
  overflow: visible !important;
  border: 1px solid var(--accent);
  background: var(--panel-bg-alt);
}

/* editor in-place delle celle (input testuali/numerici e "select" a tendina
   come Origine/Persona/Stato, che Tabulator renderizza come input + popup
   lista): stessa dimensione di font/riga/padding della cella non in
   modifica ("stile Excel" — la riga non deve ne' ingrandirsi ne' cambiare
   font passando in editing), non piu' ingrandito a 16px con padding
   generoso come in precedenza. L'input nativo scrolla gia' da solo il
   testo internamente quando supera la larghezza (il cursore resta sempre
   visibile durante la digitazione): "width/height:100%" qui non taglia
   quindi nulla, e' solo il contorno dell'editor a coincidere con la cella. */
.tabulator-row .tabulator-cell.tabulator-editing input,
.tabulator-row .tabulator-cell.tabulator-editing textarea,
.tabulator-row .tabulator-cell.tabulator-editing select {
  font-size: inherit !important;
  font-family: inherit !important;
  line-height: inherit !important;
  padding: 2px 4px !important;
  box-sizing: border-box !important;
  width: 100% !important;
  height: 100% !important;
  border-radius: 4px;
  background: var(--panel-bg-alt);
  color: var(--text);
  border: 1px solid var(--border-strong);
}

/* editor "textarea" (tutte le colonne testuali modificabili — Com,
   Progetto, Cliente, P.O., User story, Task, Note — vedi taskColumns in
   app.js): in
   flusso normale (non piu' position:absolute), cosi' la crescita in
   altezza del textarea fa crescere la CELLA e quindi l'intera riga —
   niente testo tagliato ne' riga che sembra "restringersi" durante la
   modifica. Il ridimensionamento automatico mentre si digita (il testo
   incollato/scritto che aggiunge righe) e' gestito in app.js
   (autoRidimensionaTextareaEditor): l'altezza di un <textarea> non si
   adatta da sola al contenuto via solo CSS, serve leggere scrollHeight e
   riscriverlo come altezza esplicita ad ogni input. "resize: vertical"
   resta comunque disponibile come maniglia manuale di scorta. */
.tabulator-row .tabulator-cell.tabulator-editing textarea {
  height: auto !important;
  min-height: 100% !important;
  width: 100% !important;
  box-sizing: border-box !important;
  white-space: pre-wrap !important;
  word-wrap: break-word !important;
  resize: vertical;
}

/* su mobile la leggibilita'/il tocco preciso contano piu' della resa
   "in-cella": un font-size sotto i 16px fa scattare lo zoom automatico di
   iOS Safari al focus di un input (problema reale gia' risolto in una
   versione precedente di questa regola) — qui viene ripristinato
   esplicitamente, altrimenti "font-size: inherit" qui sopra (che sulla
   tabella Task vale circa 0.85rem, 13.6px) lo reintrodurrebbe. Stesso
   breakpoint di BREAKPOINT_MOBILE_PX in app.js. */
@media (max-width: 640px) {
  .tabulator-row .tabulator-cell.tabulator-editing input,
  .tabulator-row .tabulator-cell.tabulator-editing textarea,
  .tabulator-row .tabulator-cell.tabulator-editing select {
    font-size: 16px !important;
    min-height: 42px;
    padding: 6px 12px !important;
  }
}

.tabulator .tabulator-footer {
  background: var(--panel-bg-alt);
  border-top: 1px solid var(--border);
  color: var(--text-muted);
}

/* popup a tendina dell'editor "list" (Origine, Persona, Stato): opzioni
   ben distanziate per evitare tocchi errati su schermi touch */
.tabulator-edit-list {
  background: var(--panel-bg);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  color: var(--text);
  overflow: hidden;
}

.tabulator-edit-list-item {
  min-height: 42px;
  padding: 10px 12px;
  font-size: 16px;
  color: var(--text);
  border-bottom: 1px solid var(--border);
  box-sizing: border-box;
}

.tabulator-edit-list-item:last-child {
  border-bottom: none;
}

.tabulator-edit-list-item.active,
.tabulator-edit-list-item:hover {
  background: var(--accent);
  color: #f8fafc;
}

.row-duplicate-btn {
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
  border-radius: 6px;
  width: 26px;
  height: 26px;
  line-height: 1;
  cursor: pointer;
  font-size: 0.8rem;
  margin-right: 6px;
}

.row-duplicate-btn:hover {
  background: var(--panel-bg-alt);
  border-color: var(--accent);
  color: var(--text);
}

.row-delete-btn {
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--danger);
  border-radius: 6px;
  width: 26px;
  height: 26px;
  line-height: 1;
  cursor: pointer;
  font-size: 0.8rem;
}

.row-delete-btn:hover {
  background: var(--badge-alert-bg);
  border-color: var(--danger);
}

/* riga di un task con Stato "Fatto": evidenziazione in verde tenue, stessa
   logica parziale delle altre (Origine esclusa, cosi' il badge PRODUZIONE/
   BUFFER resta leggibile). Dichiarata PRIMA di "pronto" e "IMPREVISTO" qui
   sotto cosi', nei rari casi in cui un task risulti anche in una di quelle
   condizioni, vince la piu' urgente da segnalare (un task "Fatto" e
   "IMPREVISTO" non possono coesistere: sono valori diversi dello stesso
   campo stato, ma un task "Fatto" marcato anche "pronto per produzione" e'
   un caso limite possibile). */
#task-table .tabulator-row.row-fatto .tabulator-cell:not([tabulator-field="origine"]) {
  background: var(--row-fatto-bg) !important;
}

#task-table .tabulator-row.row-fatto:hover .tabulator-cell:not([tabulator-field="origine"]) {
  background: var(--row-fatto-bg-hover) !important;
}

/* riga di un task in Buffer marcato "pronto per produzione" (vedi
   badgePronto/toggleProntoProduzione in app.js): evidenziazione in giallo
   tenue, stessa logica parziale dell'IMPREVISTO qui sotto (Origine esclusa).
   Dichiarata PRIMA della regola IMPREVISTO cosi', nel raro caso in cui un
   task risulti sia IMPREVISTO che "pronto", vince quest'ultima (piu' urgente
   da segnalare). */
#task-table .tabulator-row.row-pronto .tabulator-cell:not([tabulator-field="origine"]) {
  background: var(--row-pronto-bg) !important;
}

#task-table .tabulator-row.row-pronto:hover .tabulator-cell:not([tabulator-field="origine"]) {
  background: var(--row-pronto-bg-hover) !important;
}

/* riga di un task "in lavorazione" (vedi isTaskInLavorazione in app.js:
   team Impianti, origine Produzione, e Stato "In corso" oppure
   0 < fatti < punti anche se lo Stato non e' stato aggiornato a mano):
   giallo pastello pieno — va per questo sopra "fatto" e "pronto" (piu'
   urgente da segnalare: lavoro attivo, non solo pianificato o gia'
   concluso) ma sotto "IMPREVISTO" qui sotto, ancora piu' urgente perche'
   segnala uno sforamento. */
#task-table .tabulator-row.row-in-lavorazione .tabulator-cell:not([tabulator-field="origine"]) {
  background: var(--row-in-lavorazione-bg) !important;
  color: var(--row-in-lavorazione-text);
}

#task-table .tabulator-row.row-in-lavorazione:hover .tabulator-cell:not([tabulator-field="origine"]) {
  background: var(--row-in-lavorazione-bg-hover) !important;
  color: var(--row-in-lavorazione-text);
}

/* riga di un task "IMPREVISTO" (fatti > punti preventivati, impostato in
   automatico da calcolaStatoAutomatico in app.js): evidenziazione parziale,
   dalla colonna Com in poi. La cella Origine resta sullo sfondo standard
   della riga, cosi' il badge PRODUZIONE/BUFFER non viene alterato. Il
   colore testo si applica alla cella, non al badge Stato/Persona/Delta, che
   dichiarano un proprio colore piu' specifico e restano quindi leggibili
   con la loro palette dedicata. */
#task-table .tabulator-row.row-imprevisto .tabulator-cell:not([tabulator-field="origine"]) {
  background: var(--row-imprevisto-bg) !important;
  color: var(--row-imprevisto-text);
}

#task-table .tabulator-row.row-imprevisto:hover .tabulator-cell:not([tabulator-field="origine"]) {
  background: var(--row-imprevisto-bg-hover) !important;
}

/* intestazione di gruppo per Commessa (COM) nella tabella task: etichetta +
   conteggio task + barra di avanzamento a sinistra, pulsanti di priorita'
   spinti a destra (margin-left:auto sul loro contenitore, vedi piu' sotto).
   Selettori con #task-table e !important per vincere sempre sul CSS di
   base di Tabulator, che usa lo stesso identico livello di specificita'
   con sfondo chiaro. La riga deve occupare esattamente la stessa
   larghezza/box delle righe dati sottostanti (stesso box-sizing, nessun
   padding esterno che la restringa), altrimenti sfondo/etichetta risultano
   disallineati dalla griglia colonne. Nota: Tabulator 6.4 non genera una
   classe ".tabulator-group-header" — il contenitore reale della riga di
   gruppo e' ".tabulator-row.tabulator-group" (verificato nel DOM). */
#task-table .tabulator-row.tabulator-group {
  width: 100% !important;
  min-width: max-content !important;
  box-sizing: border-box;
  display: flex !important;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  overflow: hidden;
  background: var(--panel-bg-alt) !important;
  border-top: 2px solid var(--border-strong);
  color: var(--text) !important;
  font-weight: 700;
}

#task-table .tabulator-row.tabulator-group:hover {
  background: var(--panel-bg-alt) !important;
}

/* wrapper puramente semantico (vedi formattaGruppoCommessa in app.js):
   "contents" lo rende invisibile al layout flex della riga di gruppo, cosi'
   le sue "figlie" (frecce priorita', label, conteggio, barre avanzamento)
   restano spaziate dallo stesso gap:8px come se fossero fratelli diretti —
   nessuna differenza visiva rispetto a prima che questo wrapper esistesse */
#task-table .com-group-content {
  display: contents;
}

#task-table .tabulator-row.tabulator-group .tabulator-arrow {
  border-bottom-color: var(--text-muted);
}

/* Tabulator applica di default un margin-left dinamico (via JS, pari allo
   scrollLeft corrente) a .tabulator-group-toggle per tenere la freccia
   visibile durante lo scroll orizzontale. Con lo sfondo/etichetta custom di
   questo gruppo l'effetto e' un "onda": la freccia (e tutto cio' che la
   segue nel flusso: etichetta, conteggio, barra di avanzamento) resta
   ancorata al bordo sinistro mentre le colonne sotto scorrono normalmente,
   disallineando l'intera intestazione dalla griglia. Annullando il margin-
   left dinamico l'intestazione torna a scorrere in sync con le celle. */
#task-table .tabulator-group-toggle {
  margin-left: 0 !important;
}

#task-table .tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow {
  border-top-color: var(--text-muted);
}

/* etichetta e conteggio si accorciano con ellipsis quando lo spazio
   scarseggia (mobile), cosi' la percentuale a destra resta sempre visibile
   invece di uscire dallo schermo */
/* cliccabile: stessa azione della freccia nativa di espandi/comprimi (il
   click e' inoltrato via JS all'elemento .tabulator-group-toggle, vedi
   init() in app.js), cosi' anche il codice COM stesso diventa un bersaglio
   comodo, non solo la piccola freccia */
#task-table .com-group-label {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text);
  min-width: 0;
  flex-grow: 1;
  flex-shrink: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
  border-radius: 4px;
  padding: 0.1rem 0.35rem;
  margin: -0.1rem -0.35rem;
  transition: background 0.15s ease, color 0.15s ease;
}

#task-table .com-group-label:hover {
  background: var(--panel-bg-alt);
  color: var(--accent);
}

#task-table .com-group-count {
  margin-left: 0.6rem;
  font-weight: 400;
  font-size: 0.72rem;
  color: var(--text-muted);
  min-width: 0;
  flex-shrink: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* due indicatori di avanzamento affiancati (Sprint attivo / Globale
   storico della commessa, vedi progressBarCommessa in app.js): il
   contenitore segue subito etichetta/conteggio nel flusso normale (non
   piu' margin-left:auto, che lo spingerebbe all'estremo destro dell'INTERA
   riga di gruppo — ora larga quanto tutte le colonne, vedi
   min-width:max-content sopra — invece che restare accanto al resto del
   contenuto sempre visibile senza scroll). Mai comprimibile
   (flex-shrink:0), cosi' non sparisce mai quando etichetta/conteggio si
   accorciano con ellipsis. */
#task-table .com-group-progress-group {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  margin-left: 0.6rem;
  flex-shrink: 0;
  vertical-align: middle;
}

#task-table .com-group-progress {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

/* "S"/"G" davanti a ciascuna mini-barra: il dettaglio completo (Sprint:
   x/y (z%) | Globale: x/y (z%)) resta nel title dell'intero gruppo, questa
   e' solo l'etichetta minima per distinguerle a colpo d'occhio */
#task-table .com-group-progress-label {
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--text-muted);
}

#task-table .com-group-progress-track {
  position: relative;
  width: 84px;
  height: 6px;
  border-radius: 999px;
  background: var(--progress-track-bg);
  overflow: hidden;
}

#task-table .com-group-progress-fill {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: 999px;
  transition: width 0.3s ease;
}

#task-table .com-group-progress-pct {
  min-width: 2.6em;
  font-family: var(--mono-font);
  font-size: 0.72rem;
  font-weight: 700;
  text-align: right;
}

#task-table .com-group-progress-fill.com-group-progress-danger {
  background: var(--danger);
}

#task-table .com-group-progress-fill.com-group-progress-warning {
  background: var(--negative);
}

#task-table .com-group-progress-fill.com-group-progress-ok {
  background: var(--positive);
}

#task-table .com-group-progress-pct.com-group-progress-danger {
  color: var(--badge-alert-text);
}

#task-table .com-group-progress-pct.com-group-progress-warning {
  color: var(--badge-buffer-text);
}

#task-table .com-group-progress-pct.com-group-progress-ok {
  color: var(--badge-ok-text);
}

/* commessa oltre il 100% di avanzamento (es. dopo aver ereditato punti
   fatti in Produzione dallo sprint precedente, vedi progressBarCommessa in
   app.js): stesso viola usato per i task "IMPREVISTO", per segnalarla come
   un caso fuori scala rispetto ai livelli standard rosso/arancione/verde */
#task-table .com-group-progress-fill.progress-over-100 {
  background: var(--badge-imprevisto-bg);
}

#task-table .com-group-progress-pct.progress-over-100 {
  color: var(--row-imprevisto-text);
}

/* frecce di riordino priorita' commessa: la riga di gruppo e' un flex
   container con gap:8px (vedi .tabulator-row.tabulator-group sopra), quindi
   questo blocco resta ancorato subito dopo la freccia di espansione/
   compressione nativa e prima dell'etichetta Commessa, senza sovrapposizioni. */
#task-table .com-group-priority-actions {
  display: flex;
  gap: 0.35rem;
  flex-shrink: 0;
}

#task-table .com-group-priority-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border-radius: 6px;
  border: 1px solid var(--border-strong);
  background: var(--bg-inset);
  color: var(--text-muted);
  font-size: 0.7rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

#task-table .com-group-priority-btn:hover {
  background: var(--panel-bg);
  color: var(--text);
  border-color: var(--accent);
}

#task-table .com-group-priority-btn:active {
  background: var(--accent);
  color: #f8fafc;
}

/* riga di sub-totale in fondo al gruppo (Punti/Fatti/Delta): riga di calcolo
   nativa di Tabulator (bottomCalc + columnCalcs:"group" in app.js) — usa le
   stesse celle/colonne dei task, quindi l'incolonnamento sotto le rispettive
   intestazioni e' garantito automaticamente, non simulato via CSS. */
#task-table .tabulator-row.tabulator-calcs {
  width: 100% !important;
  min-width: max-content !important;
  background: var(--bg-inset) !important;
  color: var(--calc-row-text) !important;
  font-size: 1.05rem;
  font-weight: 700;
  border-top: 1px solid var(--border);
  border-bottom: 2px solid var(--border-strong) !important;
}

#task-table .tabulator-row.tabulator-calcs .tabulator-cell {
  font-family: var(--mono-font);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--calc-row-text);
}

/* il badge del Delta ha un font-size proprio fisso: va ingrandito a parte
   perche' non eredita quello, piu' grande, della riga di sub-totale */
#task-table .tabulator-row.tabulator-calcs .badge {
  font-size: 0.85rem;
  padding: 0.3rem 0.75rem;
}

/* etichetta "TOTALE [COM]" sulla riga di sub-totale: deve risaltare
   immediatamente rispetto al resto della riga, gia' chiara e in grassetto */
.badge-totale-com {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.9rem;
  border-radius: 999px;
  background: var(--badge-totale-com-bg);
  color: var(--badge-totale-com-text);
  border: 1.5px solid var(--badge-totale-com-border);
  font-weight: 800;
  font-size: 1rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* header di gruppo Commessa compatto sotto i 768px: gap/margini ridotti e
   barra di avanzamento visuale nascosta (resta solo la percentuale in
   testo), cosi' il nome commessa ha priorita' sullo spazio disponibile e
   non viene troncato per codici come MOCK1/VP26. Va dichiarato PRIMA del
   blocco @media (max-width:640px) qui sotto per il corretto ordine di
   cascata sulle altre regole condivise. */
@media (max-width: 768px) {
  #task-table .tabulator-row.tabulator-group {
    gap: 6px;
  }

  #task-table .com-group-count {
    margin-left: 0.4rem;
  }

  #task-table .com-group-progress-group {
    gap: 0.4rem;
    padding-left: 0.35rem;
  }

  /* su mobile lo spazio va prioritariamente al nome commessa: la barra
     visuale di avanzamento viene nascosta, resta visibile solo la
     percentuale in testo (es. "13%"); l'etichetta S/G resta, e' un solo
     carattere */
  #task-table .com-group-progress-track {
    display: none;
  }

  #task-table .com-group-priority-actions {
    gap: 0.25rem;
  }

  #task-table .com-group-priority-btn {
    width: 24px;
    height: 24px;
    font-size: 0.65rem;
  }
}

/* --- Mobile responsive --- */
@media (max-width: 640px) {
  /* su mobile lo spazio verticale e' limitato: si torna allo scroll di
     pagina normale invece del layout "app-shell" a tutto schermo */
  html,
  body {
    height: auto;
    overflow: visible;
  }

  body {
    display: block;
  }

  main {
    display: block;
    flex: none;
    overflow: visible;
  }

  .panel-task {
    flex: none;
    overflow: visible;
  }

  #task-table {
    flex: none;
    height: 500px;
  }

  header {
    flex-direction: column;
    align-items: stretch;
    padding: 0.85rem 1rem;
  }

  header h1 {
    font-size: 1.05rem;
  }

  .header-title {
    justify-content: space-between;
  }

  .header-actions {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }

  .header-actions select,
  .header-actions a,
  .header-actions .btn {
    width: 100%;
  }

  main {
    padding: 1rem 1rem 2rem;
  }

  .cards {
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 0.75rem;
  }

  .panel {
    padding: 1rem;
  }

  .panel-header {
    flex-wrap: wrap;
    gap: 0.75rem;
  }

  .panel-header .btn {
    width: 100%;
  }

  .panel-header-actions {
    width: 100%;
    flex-direction: column;
  }

  .btn-compact {
    min-height: 44px;
    font-size: 0.9rem;
  }

  .filters {
    flex-direction: column;
    align-items: stretch;
  }

  .filters label {
    width: 100%;
  }

  /* su schermi piccoli le opzioni della tendina Origine/Persona/Stato
     restano ancora più spaziate, per un tocco preciso col dito */
  .tabulator-edit-list-item {
    min-height: 44px;
    padding: 12px 14px;
  }
}
