/* Demo CantieriOS, sistema grafico.
   Identità distinta dalle altre demo (navy/ambra Secondo Cervello, teal Recupero
   Pazienti, graphite/cobalto Cruscotto Finanza, verde petrolio Dashboard
   Finanziaria PMI): sfondo chiaro "cantiere/carta tecnica", accento arancio
   sicurezza, blu acciaio come secondo accento. Titoli Space Grotesk, testo
   Inter, numeri JetBrains Mono. Contrasti verificati con la formula WCAG
   (luminanza relativa) prima di scrivere il resto del file, non ad occhio:
   ogni coppia testo/sfondo qui sotto è ≥4.5:1 per testo piccolo, ≥3:1 per i
   titoli grandi. */

/* niente overflow-x:hidden qui: su html/body rompe position:sticky nei
   discendenti (la sidebar smette di restare agganciata durante lo scroll).
   Lo scroll orizzontale è evitato a livello di singolo elemento (min-width:0
   su flex/grid, .table-wrap con overflow-x:auto, box-sizing ovunque),
   verificato con scrollWidth/clientWidth prima del deploy. */
html, body { margin: 0; padding: 0; background: #F1EFEA; }

.gc {
  --bg:         #F1EFEA;
  --surface:    #FFFFFF;
  --surface-2:  #E8E5DD;
  --line:       rgba(28,35,33,.12);
  --line-2:     rgba(28,35,33,.20);
  --text:       #1C2321;
  --muted:      #5B645F;
  --faint:      #63685E;

  --accent:      #C24A08;
  --accent-rgb:  194,74,8;
  --accent-2:    #2B4C6F;
  --accent-2-rgb: 43,76,111;
  --accent-soft: rgba(194,74,8,.10);
  --accent-2-soft: rgba(43,76,111,.10);

  --good:      #167048;
  --good-soft: #DCEEE4;
  --warn:      #895A0D;
  --warn-soft: #F2E6D3;
  --bad:       #BB3434;
  --bad-soft:  #F8DEDE;
  /* rosso più acceso di --bad, solo per il testo del timer sotto i 2
     minuti: --bad su sfondo chiaro non passa il contrasto minimo (4.38:1,
     verificato con la formula WCAG, serve 4.5), questo sì (4.94:1). */
  --bad-vivid: #B91C1C;

  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 18px;
  --shadow: 0 16px 40px -22px rgba(28,35,33,.22);
  --sidebar-w: 236px;
  --topbar-h: 56px;

  font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  /* niente overflow-x:hidden qui: .gc non è il livello giusto per tagliare lo
     scroll orizzontale, rischierebbe di ritagliare i figli position:fixed
     (sidebar mobile, modali). Il blocco è su html,body sopra. */
}
.gc *, .gc *::before, .gc *::after { box-sizing: border-box; }
/* qualunque classe qui sotto imposta un display esplicito (.btn, .card,
   .kpi...) batte in specificità il [hidden] del browser e lo terrebbe
   visibile lo stesso: successo davvero sul bottone "Genera analisi AI",
   restava scritto "Sto analizzando..." per sempre nonostante hidden=true.
   Regola generale, protegge ogni elemento nascosto via .hidden = true
   ovunque nell'app, non solo quello trovato oggi. */
.gc [hidden] { display: none !important; }
.gc .mono { font-family: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace; font-variant-numeric: tabular-nums; }
.gc h1, .gc h2, .gc h3 { font-family: "Space Grotesk", system-ui, sans-serif; font-weight: 700; margin: 0; color: var(--text); }
.gc button { font-family: inherit; }
.gc img, .gc svg { max-width: 100%; }

/* ===================== struttura: topbar + sidebar + contenuto ===================== */
.topbar {
  position: sticky; top: 0; z-index: 60; height: var(--topbar-h);
  background: rgba(241,239,234,.94); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between;
  padding-inline: 14px; gap: 10px;
}
.topbar-left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.hamburger {
  display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: var(--r-sm); border: 1px solid var(--line-2);
  background: var(--surface); color: var(--text); cursor: pointer; flex-shrink: 0;
}
@media (min-width: 960px) { .hamburger { display: none; } }
.brand { display: flex; align-items: center; gap: 8px; font-family: "Space Grotesk", sans-serif; font-weight: 700; font-size: 20px; letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.brand .chip { width: 20px; height: 20px; border-radius: 6px; background: var(--accent); flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.brand .chip svg { width: 100%; height: 100%; }
.brand small { display: block; font-family: "Inter", sans-serif; font-weight: 500; font-size: 11px; color: var(--muted); letter-spacing: 0; }

/* colore del testo del timer nella fascia privacy (unico punto dove si
   vede, tolta la bolla bianca in topbar): verde 5:00→3:00, arancione
   3:00→2:00, rosso acceso 2:00→0. */
.timer-verde { color: var(--good); }
.timer-arancione { color: var(--warn); }
.timer-rosso { color: var(--bad-vivid); }

.privacy {
  background: var(--accent-soft); border-bottom: 1px solid rgba(var(--accent-rgb),.18);
  padding-block: 8px; padding-inline: 14px; font-size: 18px; color: #8A3606; text-align: center; line-height: 1.4;
}
.privacy b { font-weight: 700; }

.app-shell { display: flex; align-items: flex-start; }

.sidebar {
  position: fixed; top: var(--topbar-h); left: 0; bottom: 0; width: var(--sidebar-w); z-index: 55;
  background: var(--surface); border-right: 1px solid var(--line); padding: 14px 10px;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  transform: translateX(-100%); transition: transform .22s ease;
}
.sidebar.open { transform: translateX(0); }
@media (min-width: 960px) { .sidebar { transform: none; position: sticky; height: calc(100vh - var(--topbar-h)); } }

.drawer-scrim {
  position: fixed; inset: var(--topbar-h) 0 0 0; background: rgba(28,35,33,.45); z-index: 50;
  opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
.drawer-scrim.open { opacity: 1; pointer-events: auto; }
@media (min-width: 960px) { .drawer-scrim { display: none; } }

.nav-list { display: flex; flex-direction: column; gap: 3px; list-style: none; margin: 0; padding: 0; }
.nav-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 10px 12px; border-radius: var(--r-sm); border: none; background: none;
  color: var(--muted); font-weight: 600; font-size: 13.5px; cursor: pointer;
}
.nav-item .ic { width: 18px; height: 18px; flex-shrink: 0; display: flex; }
.nav-item .ic svg { width: 100%; height: 100%; }
.nav-item:hover { background: var(--surface-2); color: var(--text); }
.nav-item.active { background: var(--accent-soft); color: var(--accent); }
.nav-sep { height: 1px; background: var(--line); margin: 10px 4px; }
.nav-foot { padding: 12px 12px 4px; font-size: 11px; color: var(--faint); line-height: 1.5; }

/* niente margin-left qui: da 960px in su la sidebar è position:sticky, cioè
   dentro il flusso flex normale, quindi occupa già la sua colonna nella riga
   .app-shell. Un margin-left aggiuntivo pari alla sua larghezza contava lo
   stesso spazio due volte, spingendo il contenuto via dalla sidebar con un
   vuoto vistoso in mezzo (bug reale segnalato da Stefano con screenshot).
   flex:1 basta da solo a far crescere main-col su tutto lo spazio rimasto. */
.main-col { flex: 1; min-width: 0; width: 100%; }

/* ancorato a sinistra (non centrato): su schermi larghi il contenuto deve
   attaccare alla sidebar, non fluttuare con un vuoto vistoso in mezzo. Lo
   spazio in più, se c'è, resta solo sul bordo destro, dove non stona.
   margin:0 invece di margin:0 auto non cambia nulla da mobile: sotto i
   1180px l'elemento riempie comunque tutta la larghezza disponibile,
   auto o no. */
.wrap { max-width: 1180px; margin: 0; padding-inline: clamp(14px, 3vw, 28px); min-width: 0; }

/* ===================== hero ===================== */
.hero { padding-block: 22px 16px; }
.kicker { font-size: 12px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-2); margin-bottom: 8px; }
.gc h1.page-title { font-size: clamp(22px,4.4vw,30px); line-height: 1.15; letter-spacing: -.01em; text-wrap: balance; margin-bottom: 8px; }
.hero p, .section-head p { color: var(--muted); font-size: clamp(13.5px,1.6vw,15px); max-width: 62ch; line-height: 1.55; margin: 0; }

/* ===================== sezioni / card ===================== */
.view { display: none; }
.view.active { display: block; }
.section { margin-block: 22px; }
.section-head { margin-bottom: 12px; display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.section-head h2 { font-size: 18px; margin-bottom: 4px; }
.section-head .head-text { min-width: 0; }
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: clamp(14px,3vw,20px); box-shadow: var(--shadow); min-width: 0; }
.card + .card { margin-top: 14px; }
.card-title { font-family: "Space Grotesk", sans-serif; font-weight: 700; font-size: 14.5px; margin-bottom: 3px; }
.card-sub { color: var(--muted); font-size: 12.5px; margin: 0 0 12px; }

.grid-2 { display: grid; grid-template-columns: minmax(0,1fr); gap: 14px; }
@media (min-width: 800px) { .grid-2 { grid-template-columns: minmax(0,1fr) minmax(0,1fr); } }

/* ===================== KPI ===================== */
.kpi-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 10px; margin-block: 16px; }
@media (min-width: 620px) { .kpi-grid { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (min-width: 960px) { .kpi-grid { grid-template-columns: repeat(5, minmax(0,1fr)); } }
.kpi { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: 13px; display: flex; flex-direction: column; gap: 5px; box-shadow: var(--shadow); min-width: 0; }
.kpi .lbl { font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .02em; overflow-wrap: break-word; }
.kpi .val { font-family: "JetBrains Mono", monospace; font-weight: 600; font-size: clamp(16px,3.4vw,20px); overflow-wrap: break-word; }
.kpi .pill { align-self: flex-start; font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 999px; text-transform: uppercase; letter-spacing: .02em; }
.pill.good { background: var(--good-soft); color: var(--good); }
.pill.warn { background: var(--warn-soft); color: var(--warn); }
.pill.bad  { background: var(--bad-soft);  color: var(--bad); }
.pill.neutral { background: var(--surface-2); color: var(--muted); }

/* ===================== alert ===================== */
.alert-list { display: flex; flex-direction: column; gap: 10px; }
.alert-banner { border-radius: var(--r-md); padding: 13px 15px; font-size: 13.5px; line-height: 1.5; border: 1px solid; display: flex; gap: 10px; align-items: flex-start; }
.alert-banner .ic { width: 22px; height: 22px; flex-shrink: 0; margin-top: 1px; }
.alert-banner .ic svg { width: 100%; height: 100%; }
.alert-banner b { font-weight: 700; }
.alert-banner.good { background: var(--good-soft); border-color: rgba(22,112,72,.28); color: #0E5236; }
.alert-banner.warn { background: var(--warn-soft); border-color: rgba(137,90,13,.3); color: #6B4409; }
.alert-banner.bad  { background: var(--bad-soft);  border-color: rgba(187,52,52,.3); color: #8F2727; }
.alert-empty { color: var(--muted); font-size: 13.5px; padding: 6px 2px; }

/* ===================== funzioni AI: badge, pannelli, domande, stima ===================== */
.ai-badge {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 999px;
  background: var(--accent-2-soft); color: var(--accent-2); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em; vertical-align: middle; white-space: nowrap;
}
.section-head h2 .ai-badge, .card-title .ai-badge { margin-right: 8px; }
.ai-panel-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.ai-panel-title { font-family: "Space Grotesk", sans-serif; font-weight: 700; font-size: 14.5px; }
.ai-output {
  background: var(--accent-2-soft); border-radius: var(--r-md); padding: 13px 15px;
  font-size: 13.5px; line-height: 1.55; color: var(--text); margin: 12px 0 0;
}
.ai-output.loading { color: var(--muted); font-style: italic; }
.ai-ask-row { display: flex; gap: 8px; margin-bottom: 12px; }
.ai-ask-row input {
  flex: 1; min-width: 0; background: var(--bg); border: 1px solid var(--line-2); border-radius: var(--r-sm);
  padding: 10px 12px; font-size: 14px; color: var(--text); font-family: "Inter", sans-serif;
}
.ai-ask-row input:focus { outline: none; border-color: var(--accent-2); box-shadow: 0 0 0 3px var(--accent-2-soft); }
.ai-suggestions { display: flex; flex-wrap: wrap; gap: 7px; }
@media (max-width: 480px) { .ai-ask-row { flex-direction: column; } }

/* stima costi AI dentro il form Nuovo Cantiere */
.ai-stima { background: var(--accent-2-soft); border-radius: var(--r-md); padding: 14px; margin: 2px 0 4px; }
.ai-stima-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; font-family: "Space Grotesk", sans-serif; font-weight: 700; font-size: 13px; }
.ai-stima-rows { display: flex; flex-direction: column; gap: 6px; }
.ai-stima-row { display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px; }
.ai-stima-row .cat { color: var(--text); }
.ai-stima-row .val { font-family: "JetBrains Mono", monospace; color: var(--muted); font-weight: 600; white-space: nowrap; }
.ai-stima-total { display: flex; justify-content: space-between; font-size: 12.5px; font-weight: 700; margin-top: 8px; padding-top: 8px; border-top: 1px solid rgba(43,76,111,.2); }
.ai-stima-margine { border-top: none; margin-top: 2px; padding-top: 0; color: var(--accent-2); }
.ai-stima-nota { font-size: 11px; color: var(--faint); margin: 8px 0 0; line-height: 1.4; }

/* ===================== grafici (SVG generati a runtime) ===================== */
.chart-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; gap: 10px; flex-wrap: wrap; }
.chart-tabs { display: flex; gap: 6px; flex-wrap: wrap; }
.chip-btn {
  padding: 7px 12px; border-radius: 999px; border: 1px solid var(--line-2); background: var(--surface-2);
  color: var(--muted); font-weight: 600; font-size: 12.5px; font-family: inherit; cursor: pointer;
}
.chip-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.chip-select {
  padding: 7px 11px; border-radius: var(--r-sm); border: 1px solid var(--line-2); background: var(--surface);
  color: var(--text); font-weight: 600; font-size: 12.5px; font-family: inherit;
}

.chart-bars { width: 100%; overflow: visible; display: block; }
/* etichetta di un grafico a barre tagliata con l'ellissi: tap/click per
   vedere il nome intero in un tooltip (vedi #tapTooltip in app.js). Il
   trattino sotto compare solo se il nome è stato davvero tagliato, non su
   tutte le etichette. */
.chart-bars .bar-label-full { cursor: pointer; }
.chart-bars .bar-label-full text { text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 3px; }
.chart-bars .bar-label-hit { fill: transparent; }
.chart-legend { display: flex; flex-wrap: wrap; gap: 12px; font-size: 11.5px; color: var(--muted); margin-top: 10px; }
.chart-legend span { display: inline-flex; align-items: center; gap: 6px; }
.chart-legend .sw { width: 9px; height: 9px; border-radius: 3px; flex-shrink: 0; }

.donut-wrap { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.donut-wrap svg { width: 148px; height: 148px; flex-shrink: 0; }
.donut-legend { display: flex; flex-direction: column; gap: 7px; font-size: 12.5px; min-width: 0; flex: 1; }
.donut-legend .row { display: flex; align-items: baseline; flex-wrap: wrap; justify-content: space-between; column-gap: 12px; row-gap: 0; padding-block: 2px; }
.donut-legend .row .name { display: inline-flex; align-items: center; gap: 7px; color: var(--text); min-width: 0; overflow-wrap: break-word; }
.donut-legend .sw { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.donut-legend .num { font-family: "JetBrains Mono", monospace; color: var(--muted); font-weight: 600; white-space: nowrap; margin-left: auto; }

/* ===================== timeline / gantt ===================== */
.timeline { display: flex; flex-direction: column; gap: 10px; }
.timeline-row { display: grid; grid-template-columns: minmax(96px,148px) 1fr; gap: 10px; align-items: center; }
.timeline-label { font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; cursor: pointer; text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 3px; }
.timeline-track { position: relative; height: 22px; background: var(--surface-2); border-radius: 999px; overflow: hidden; min-width: 0; }
.timeline-bar { position: absolute; top: 0; bottom: 0; border-radius: 999px; background: rgba(var(--accent-2-rgb),.28); }
.timeline-bar .fill { position: absolute; top: 0; left: 0; bottom: 0; border-radius: 999px; background: var(--accent-2); }
.timeline-bar.bad .fill { background: var(--bad); }
.timeline-bar.warn .fill { background: var(--warn); }
.timeline-today { position: absolute; top: -4px; bottom: -4px; width: 2px; background: var(--accent); z-index: 2; }
.timeline-axis { display: flex; justify-content: space-between; font-size: 10.5px; color: var(--faint); padding-left: calc(148px + 10px); }
@media (max-width: 560px) { .timeline-row { grid-template-columns: minmax(72px,96px) 1fr; } .timeline-axis { padding-left: calc(96px + 10px); } }

/* ===================== tabelle ===================== */
.table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--r-md); border: 1px solid var(--line); }
table.data { width: 100%; min-width: 560px; border-collapse: collapse; font-size: 13px; }
table.data th, table.data td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--line); white-space: nowrap; }
table.data th { background: var(--surface-2); color: var(--muted); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: .02em; position: sticky; top: 0; }
table.data tbody tr:last-child td { border-bottom: none; }
table.data tbody tr:hover { background: var(--accent-soft); }
table.data td.num, table.data th.num { font-family: "JetBrains Mono", monospace; text-align: right; }
table.data td.row-actions { white-space: nowrap; text-align: right; }

/* sotto i 640px niente più tabella da scorrere di lato: ogni riga diventa
   una scheda, l'etichetta di colonna passa da <thead> a un'etichetta sopra
   ogni valore (da data-label sul <td>, scritto da app.js), il bottone
   Modifica è sempre l'ultima riga della scheda, mai fuori vista. */
@media (max-width: 640px) {
  .table-wrap { overflow-x: visible; border: none; }
  table.data { min-width: 0; display: block; }
  table.data thead { display: none; }
  table.data tbody { display: block; }
  table.data tr {
    display: block; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
    padding: 2px 0; margin-bottom: 10px; box-shadow: var(--shadow);
  }
  table.data tr:last-child { margin-bottom: 0; }
  table.data td {
    display: block; white-space: normal; text-align: left;
    border-bottom: 1px solid var(--line); padding: 8px 13px;
  }
  table.data tr td:last-of-type { border-bottom: none; }
  table.data td::before {
    content: attr(data-label); display: block; font-weight: 600; color: var(--muted); font-size: 10.5px;
    text-transform: uppercase; letter-spacing: .02em; margin-bottom: 2px;
  }
  table.data td.row-actions { text-align: right; border-bottom: none; padding-top: 6px; padding-bottom: 12px; }
  table.data td.row-actions::before { content: none; }
  table.data td.row-actions .icon-btn { width: 40px; height: 40px; }
}

/* ===================== liste entità (cantieri, fornitori...) ===================== */
.entity-grid { display: grid; grid-template-columns: minmax(0,1fr); gap: 12px; }
@media (min-width: 720px) { .entity-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }
.entity-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: 15px;
  box-shadow: var(--shadow); cursor: pointer; display: flex; flex-direction: column; gap: 8px; min-width: 0;
  transition: border-color .15s;
}
.entity-card:hover { border-color: var(--accent); }
/* il nome prende sempre tutta la larghezza della card, la tag sta sotto:
   così un nome cantiere lungo non è mai costretto a spartirsi lo spazio con
   la tag e non va mai a capo parola per parola (bug reale trovato in
   verifica su schede a 3 colonne con nomi lunghi). */
.entity-card .row1 { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.entity-card .nome { font-family: "Space Grotesk", sans-serif; font-weight: 700; font-size: 15px; line-height: 1.3; overflow-wrap: break-word; min-width: 0; }
.entity-card .cliente { color: var(--muted); font-size: 12.5px; }
.entity-card .tag { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; padding: 3px 9px; border-radius: 999px; background: var(--surface-2); color: var(--muted); white-space: nowrap; flex-shrink: 0; }
.entity-card .num-row { display: flex; justify-content: space-between; font-size: 12.5px; color: var(--muted); gap: 8px; }
.entity-card .num-row b { color: var(--text); font-family: "JetBrains Mono", monospace; font-weight: 600; }
.sal-track { height: 8px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.sal-fill { height: 100%; border-radius: 999px; background: var(--accent-2); }

/* ===================== bottoni ===================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 11px 20px; border-radius: 999px;
  border: 0; background: var(--accent); color: #fff; font-weight: 700; font-size: 13.5px;
  font-family: "Inter", sans-serif; cursor: pointer; transition: filter .15s, transform .15s; white-space: nowrap;
}
.btn:hover { filter: brightness(1.08); transform: translateY(-1px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn.block { width: 100%; }
.btn.ghost { background: var(--surface); color: var(--text); border: 1px solid var(--line-2); }
.btn.ghost:hover { border-color: var(--accent); }
.btn.danger { background: var(--bad); }
.btn.sm { padding: 8px 14px; font-size: 12.5px; }
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 8px;
  border: 1px solid var(--line-2); background: var(--surface); color: var(--muted); cursor: pointer; flex-shrink: 0;
}
.icon-btn:hover { border-color: var(--accent); color: var(--accent); }
.icon-btn svg { width: 15px; height: 15px; }

/* ===================== form / campi ===================== */
.field-grid { display: grid; grid-template-columns: minmax(0,1fr); gap: 12px; }
@media (min-width: 520px) { .field-grid.cols-2 { grid-template-columns: minmax(0,1fr) minmax(0,1fr); } }
@media (min-width: 720px) { .field-grid.cols-3 { grid-template-columns: repeat(3, minmax(0,1fr)); } }
.field { min-width: 0; }
.field label { display: block; font-size: 11.5px; font-weight: 600; color: var(--muted); margin-bottom: 5px; }
.field .hint { display: block; font-size: 10.5px; color: var(--faint); margin-top: 4px; }
.field input, .field select, .field textarea {
  width: 100%; background: var(--bg); border: 1px solid var(--line-2); border-radius: var(--r-sm);
  padding: 10px 11px; font-size: 14px; color: var(--text); font-family: "Inter", sans-serif; min-width: 0;
}
.field input.mono, .field .euro input { font-family: "JetBrains Mono", monospace; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.field textarea { resize: vertical; min-height: 64px; }
.field-euro { position: relative; }
.field-euro input { padding-left: 24px; }
.field-euro::before { content: "€"; position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--faint); font-size: 13px; pointer-events: none; }
.field-pct { position: relative; }
.field-pct input { padding-right: 26px; }
.field-pct::after { content: "%"; position: absolute; right: 11px; top: 50%; transform: translateY(-50%); color: var(--faint); font-size: 13px; pointer-events: none; }

.choice-col { display: flex; flex-direction: column; gap: 6px; }
.choice-btn {
  padding: 10px 13px; border-radius: var(--r-sm); border: 1px solid var(--line-2); background: var(--bg);
  color: var(--text); font-weight: 600; font-size: 13px; font-family: inherit; cursor: pointer; text-align: left;
  width: 100%; min-width: 0;
}
.choice-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }

.field-check label { display: flex; align-items: flex-start; gap: 8px; font-size: 12px; color: var(--muted); line-height: 1.45; cursor: pointer; }
.field-check input[type="checkbox"] { margin-top: 2px; width: 16px; height: 16px; flex-shrink: 0; accent-color: var(--accent); cursor: pointer; }
.field-check a { color: var(--accent-2); text-decoration: underline; }

.form-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; flex-wrap: wrap; }

/* ===================== dimensione economica: fieldset a fisarmonica ===================== */
.econ-group { border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); overflow: hidden; margin-bottom: 12px; }
.econ-group summary {
  cursor: pointer; font-family: "Space Grotesk", sans-serif; font-weight: 700; font-size: 14.5px; padding: 15px 18px;
  list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 10px; color: var(--text);
}
.econ-group summary::-webkit-details-marker { display: none; }
.econ-group summary .n { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 7px; background: var(--accent-soft); color: var(--accent); font-family: "JetBrains Mono", monospace; font-size: 12px; font-weight: 700; margin-right: 10px; flex-shrink: 0; }
.econ-group summary .arrow { transition: transform .2s; color: var(--muted); flex-shrink: 0; }
.econ-group[open] summary .arrow { transform: rotate(180deg); }
.econ-group summary .head-txt { display: flex; align-items: center; min-width: 0; flex: 1; }
.econ-group summary .head-txt .lbl-wrap { min-width: 0; }
.econ-group summary .sub { display: block; font-weight: 500; font-size: 11.5px; color: var(--muted); font-family: "Inter", sans-serif; margin-top: 2px; }
.econ-body { padding: 4px 18px 18px; }
.econ-grid { display: grid; grid-template-columns: minmax(0,1fr); gap: 12px; }
@media (min-width: 640px) { .econ-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (min-width: 1040px) { .econ-grid { grid-template-columns: repeat(3, minmax(0,1fr)); } }

.summary-strip { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 10px; margin-bottom: 16px; }
@media (min-width: 620px) { .summary-strip { grid-template-columns: repeat(4, minmax(0,1fr)); } }

/* ===================== CTA finale ===================== */
.cta-final { text-align: center; padding-block: 26px; }
.cta-final h2 { font-size: 20px; margin-bottom: 8px; text-wrap: balance; }
.cta-final p { color: var(--muted); font-size: 13.5px; margin: 0 0 16px; }
/* +75% rispetto al .btn di base (13.5px/11px 20px → 24px/20px 36px), solo
   su questo bottone: .btn resta invariato per tutti gli altri usi in giro
   per l'app. white-space:normal (il base è nowrap) perché a questa
   dimensione il testo intero non ci sta su una riga sola da mobile stretto:
   va a capo invece di sforare la larghezza dello schermo. */
#ctaFinalBtn { font-size: 24px; padding: 20px 36px; white-space: normal; max-width: 100%; line-height: 1.25; }

.foot { text-align: center; padding: 18px 14px 40px; color: var(--faint); font-size: 12px; }
.foot a { color: var(--accent-2); text-decoration: underline; }

/* ===================== modale (lead + entità) ===================== */
.scrim {
  position: fixed; inset: 0; background: rgba(28,35,33,.55); backdrop-filter: blur(2px);
  display: flex; align-items: flex-end; justify-content: center; z-index: 100;
  opacity: 0; pointer-events: none; transition: opacity .25s ease; padding: 0;
}
@media (min-width: 640px) { .scrim { align-items: center; padding: 20px; } }
.scrim.open { opacity: 1; pointer-events: auto; }
/* solo quando il tempo è scaduto davvero (non per exit-intent, cambio app o
   CTA manuale, che restano lo scrim scuro richiudibile di sempre): stesso
   gradiente arancio dello splash, opaco, così sotto non si vede più nulla. */
.scrim.scaduto { background: radial-gradient(circle at 50% 45%, var(--accent) 0%, var(--accent) 60%, #8A3708 82%, #6E2C06 100%); }
.modal {
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-lg) var(--r-lg) 0 0;
  max-width: 480px; width: 100%; max-height: 88vh; overflow-y: auto; padding: 22px; position: relative; box-shadow: var(--shadow);
  transform: translateY(24px); transition: transform .25s ease; min-width: 0;
}
.modal.wide { max-width: 640px; }
@media (min-width: 640px) { .modal { border-radius: var(--r-lg); } }
.scrim.open .modal { transform: translateY(0); }
.modal-close { position: absolute; top: 14px; right: 14px; width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line-2); background: var(--surface); color: var(--muted); cursor: pointer; display: flex; align-items: center; justify-content: center; z-index: 2; }
.modal h2 { font-size: 19px; line-height: 1.2; margin-bottom: 8px; max-width: 30ch; padding-right: 30px; }
.modal p.lead { color: var(--muted); font-size: 13.5px; margin: 0 0 16px; }
.modal .fine { font-size: 11px; color: var(--faint); text-align: center; margin-top: 11px; }
.modal .thanks { display: none; text-align: center; padding: 10px 0; }
.modal .thanks .tick { width: 44px; height: 44px; border-radius: 50%; background: var(--good-soft); display: flex; align-items: center; justify-content: center; margin: 0 auto 14px; color: var(--good); }
.modal .thanks .tick svg { width: 22px; height: 22px; }
.modal.sent .form-state { display: none; }
.modal.sent .thanks { display: block; }
/* campi dentro un modale: sempre una sola colonna, mai a griglia larga.
   Il modale resta stretto (max 480/640px) indipendentemente da quanto è
   larga la finestra, quindi qui .field-grid.cols-2/.cols-3 non si attivano mai. */
.modal .field-grid.cols-2, .modal .field-grid.cols-3 { grid-template-columns: minmax(0,1fr); }
@media (min-width: 460px) { .modal.wide .field-grid.cols-2 { grid-template-columns: minmax(0,1fr) minmax(0,1fr); } }

/* solo il popup lead (#scrim/#modal, non l'entityModal): sempre centrato e
   sempre in 2 colonne/griglia, anche da telefono stretto, così la CTA finale
   sta dentro lo schermo senza dover scrollare. Selettori per id apposta,
   per non toccare l'entityModal che resta a foglio/bottom-sheet com'era. */
#scrim { align-items: center; padding: 16px; }
#modal { border-radius: var(--r-lg); padding: 18px 18px 14px; }
#modal .field-grid.cols-2 { grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 10px; }
#modal h2 { margin-bottom: 6px; }
#modal p.lead { margin-bottom: 10px; }
#modal .fine { margin-top: 6px; }
#ldRuolo { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }

/* ===================== tour: 4 schermate "come funziona", stesso sfondo/animazioni dello splash ===================== */
/* .tour condivide la classe .splash (sfondo, vignettatura, griglia, glow,
   dissolvenza di apertura/chiusura): qui solo il contenuto proprio, un
   passo alla volta. La testata (titolo+sottotitolo+riga) compare solo sul
   primo passo; dal secondo in poi resta solo icona+titolo+testo del passo,
   stesso blocco #tourStep, dimensioni identiche. */
/* un gradino sotto lo splash (300): quando lo splash chiude, il tour è già
   scoperto (sotto) e a piena opacità, così lo splash che sfuma rivela
   direttamente il tour, mai il portale sotto per un istante in mezzo. */
.tour { z-index: 299; }
.tour-content { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; text-align: center; padding: 0 24px; max-width: min(640px, 92vw); }
.tour-head { margin-bottom: clamp(18px,4vw,26px); }
/* selettore composto, non solo la classe: stessa collisione di specificità
   già trovata su .splash-title con ".gc h1, .gc h2, .gc h3 { color:
   var(--text) }", che altrimenti vince lei ed esce testo scuro. */
.tour .tour-title { margin: 0 0 10px; color: #fff; font-family: "Space Grotesk", sans-serif; font-weight: 700; font-size: clamp(26px, 5.5vw, 44px); letter-spacing: -.01em; line-height: 1.1; text-shadow: 0 8px 28px rgba(0,0,0,.2); }
.tour-sub { margin: 0; color: #fff; font-size: clamp(13.5px, 2.2vw, 16px); font-weight: 500; line-height: 1.5; max-width: 42ch; margin-inline: auto; }
.tour-head .splash-rule { margin: clamp(16px,3vw,22px) auto 0; }
.tour-ic { width: clamp(52px,9vw,64px); height: clamp(52px,9vw,64px); border-radius: 50%; background: rgba(255,255,255,.16); color: #fff; display: flex; align-items: center; justify-content: center; margin: 0 auto clamp(16px,3vw,22px); }
.tour-ic svg { width: 44%; height: 44%; }
/* dolore grande, beneficio "leggermente più piccolo" (non dimezzato):
   34px vs 22px al massimo, un salto netto ma non drastico. Stesso bianco
   pieno di tutto il resto, la differenza la fa la dimensione e il peso,
   non un colore diverso (rosso su arancio sarebbe anche poco leggibile). */
.tour .tour-pain { margin: 0 0 10px; color: #fff; font-family: "Space Grotesk", sans-serif; font-weight: 700; font-size: clamp(23px, 5.2vw, 34px); letter-spacing: -.005em; line-height: 1.3; }
.tour-benefit { margin: 0 auto; color: #fff; font-size: clamp(16px, 3vw, 22px); font-weight: 500; line-height: 1.45; max-width: 46ch; }
.tour-dots { display: flex; gap: 8px; justify-content: center; margin-top: clamp(20px,4vw,28px); }
.tour-dots span { width: 7px; height: 7px; border-radius: 50%; background: rgba(255,255,255,.35); transition: background .25s ease, transform .25s ease; }
.tour-dots span.active { background: #fff; transform: scale(1.25); }

/* ===================== menu tour: 11 tappe sopra la dashboard vera =====================
   Non più uno sfondo arancio pieno con un'illustrazione (versione precedente, tolta perché
   "troppo lunga"): ora punta agli elementi veri, menu a sinistra aperto per le prime 7 tappe
   poi richiuso per le ultime 4 (i pezzi della dashboard). Tecnica delle "4 fasce + finestra":
   4 rettangoli color arancio semitrasparente coprono tutto lo schermo TRANNE un buco esatto
   sull'elemento da mostrare (calcolato in JS da getBoundingClientRect, non da CSS fisso: deve
   funzionare su un elemento vero che può stare ovunque nella pagina). La "finestra" è un quinto
   rettangolo trasparente esattamente sopra il buco: intercetta il click lì sopra così anche
   toccando l'elemento vero si avanza di tappa, non si apre per sbaglio quello vero sotto.
   Frecca e riquadro (bianco, testo nero, stessa scelta di prima) si spostano sopra o sotto
   l'elemento a seconda di dove sta nello schermo, calcolato anche questo in JS. */
/* transform:translateZ(0) non decorativo: senza, su desktop (dove la sidebar
   è position:sticky, non fixed) il browser a volte compone la sidebar sopra
   a questo overlay anche se il suo z-index è più basso, un bug di
   compositing noto di position:sticky. Forzando questo elemento sul suo
   livello grafico si evita, verificato con lo screenshot dopo il fix. */
.mtour2 { position: fixed; inset: 0; z-index: 150; opacity: 1; transition: opacity .3s ease; transform: translateZ(0); }
.mtour2[hidden] { display: none; }
.mtour2.closing { opacity: 0; }
/* fissa in alto a destra su tutte le 11 tappe (non si sposta con la finestra),
   z-index sopra a tutto il resto dell'overlay: deve restare sempre cliccabile.
   Stesso linguaggio visivo di .modal-close ma bianco traslucido invece che a
   sfondo pieno, per leggersi sopra sia al velo arancio sia alla dashboard vera. */
.mtour2-close {
  position: fixed; top: 14px; right: 14px; z-index: 160; width: 34px; height: 34px; border-radius: 9px;
  border: 1px solid rgba(255,255,255,.4); background: rgba(255,255,255,.16); color: #fff;
  display: flex; align-items: center; justify-content: center; cursor: pointer; backdrop-filter: blur(3px);
}
.mtour2-close:hover { background: rgba(255,255,255,.3); }
.mtour2-mask {
  position: fixed; background: rgba(194,74,8,.76);
  transition: top .3s ease, bottom .3s ease, left .3s ease, right .3s ease, width .3s ease, height .3s ease;
}
.mtour2-window { position: fixed; background: transparent; cursor: pointer; border-radius: 10px; transition: top .3s ease, left .3s ease, width .3s ease, height .3s ease; }
.mtour2-arrow {
  position: fixed; width: 26px; height: 18px; color: #fff; pointer-events: none;
  filter: drop-shadow(0 2px 5px rgba(0,0,0,.35));
  transition: top .3s ease, bottom .3s ease, left .3s ease, transform .3s ease;
}
.mtour2-arrow svg { width: 100%; height: 100%; display: block; }
/* sfondo bianco e testo nero: unico punto di tutto splash/tour dove il testo non è bianco,
   richiesta esplicita di Stefano. Contrasto altissimo (quasi nero su bianco), nessun dubbio
   WCAG. cursor:pointer perché anche il riquadro fa parte dell'area su cui si tocca per avanzare. */
.mtour2-box {
  position: fixed; background: #fff; color: var(--text); border-radius: var(--r-lg); padding: 16px 20px;
  width: min(320px, calc(100vw - 32px)); box-shadow: 0 16px 38px rgba(0,0,0,.32); cursor: pointer;
  transition: top .3s ease, bottom .3s ease, left .3s ease;
}
.mtour2-box p { margin: 0 0 12px; font-size: 15.5px; line-height: 1.5; font-weight: 500; }
/* dots e hint riusano .tour-dots/.splash-hint (già nel foglio, pensati per bianco su arancio):
   qui il contenitore è bianco, quindi solo qui i toni si invertono in scuro su chiaro. */
.mtour2-dots { margin-top: 0; margin-bottom: 10px; justify-content: flex-start; }
.mtour2-dots span { background: rgba(28,35,33,.18); }
.mtour2-dots span.active { background: var(--accent); transform: scale(1.25); }
.mtour2-hint { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }

/* rientrata a ogni passo: tolta e rimessa via JS (con un reflow forzato in
   mezzo, altrimenti il browser non la ripete) ogni volta che il contenuto
   cambia, non solo alla primissima apparizione. */
.tour-step { }
@media (prefers-reduced-motion: no-preference) {
  .tour-step { opacity: 0; transform: translateY(12px); }
  .tour-step.enter { animation: splashRise .5s ease forwards; }
}

/* ===================== empty state ===================== */
.empty-state { text-align: center; padding: 34px 16px; color: var(--muted); }
.empty-state p { margin: 6px 0 16px; font-size: 13.5px; }

/* ===================== toast ===================== */
.toast { position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%) translateY(12px); background: var(--text); color: #fff; padding: 10px 18px; border-radius: 999px; font-size: 13px; font-weight: 600; z-index: 200; opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s; box-shadow: var(--shadow); }
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ===================== tooltip a tap (nomi tagliati: timeline, grafici) ===================== */
.tap-tooltip {
  position: fixed; z-index: 210; background: var(--text); color: #fff; padding: 8px 12px; border-radius: 8px;
  font-size: 12.5px; font-weight: 600; line-height: 1.35; max-width: min(260px, calc(100vw - 24px));
  box-shadow: var(--shadow); opacity: 0; pointer-events: none; transition: opacity .15s ease;
}
.tap-tooltip.show { opacity: 1; }

/* ===================== splash iniziale (schermo intero) ===================== */
/* Sfondo: gradiente radiale ma piatto sul colore accento già verificato
   (4.91:1 con testo bianco, stessa formula WCAG di cima file) per tutto il
   raggio dove può cadere il testo; si scurisce solo nell'anello esterno
   verso i bordi, non schiarisce mai dietro al contenuto. Il testo resta
   sempre bianco pieno, mai un'opacità ridotta: un bianco al 92% sembra
   identico a occhio ma scende sotto il 4.5:1 richiesto, verificato con la
   stessa formula, non lasciato al caso. */
.splash {
  position: fixed; inset: 0; z-index: 300;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 45%, var(--accent) 0%, var(--accent) 60%, #8A3708 82%, #6E2C06 100%);
  overflow: hidden; cursor: pointer;
}
.splash[hidden] { display: none; }
.splash.closing { opacity: 0; }

.splash-grid {
  position: absolute; inset: -2px; pointer-events: none;
  background-image:
    linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size: 46px 46px;
}
.splash-glow { position: absolute; border-radius: 50%; pointer-events: none; background: radial-gradient(circle, rgba(255,255,255,.16) 0%, rgba(255,255,255,0) 70%); }
.splash-glow-a { width: 52vmax; height: 52vmax; top: -18%; left: -14%; }
.splash-glow-b { width: 40vmax; height: 40vmax; bottom: -16%; right: -10%; opacity: .8; }

/* max-height + overflow-y: rete di sicurezza. Con due paragrafi di testo
   (aggiunti dopo, prima c'era solo un sottotitolo corto) il contenuto può
   diventare più alto dello schermo su un telefono basso/in orizzontale: qui
   si scorre dentro il box invece di essere tagliato in silenzio, che con
   .splash a inset:0 senza scroll proprio non si vedrebbe mai. */
.splash-content { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; text-align: center; padding: 24px; max-width: min(640px, 92vw); max-height: 100vh; overflow-y: auto; }
.splash-mark { display: flex; align-items: flex-end; gap: clamp(6px,1.6vw,9px); height: clamp(28px,7vw,42px); margin-bottom: clamp(16px,4vw,26px); }
.splash-mark span { display: block; width: clamp(8px,2vw,11px); border-radius: 3px 3px 1px 1px; background: #fff; }
.splash-mark span:nth-child(1) { height: 42%; }
.splash-mark span:nth-child(2) { height: 72%; }
.splash-mark span:nth-child(3) { height: 100%; }

/* selettore composto (non solo .splash-title): la regola generica
   ".gc h1, .gc h2, .gc h3 { color: var(--text) }" ha specificità più alta
   di una singola classe e vinceva lei, testo scuro su sfondo arancio. */
.splash .splash-title { margin: 0; color: #fff; font-family: "Space Grotesk", sans-serif; font-weight: 700; font-size: clamp(38px, 9vw, 76px); letter-spacing: -.01em; line-height: 1; text-shadow: 0 10px 34px rgba(0,0,0,.22); }
.splash-rule { width: min(120px, 30vw); height: 2px; background: rgba(255,255,255,.5); margin: clamp(14px,3vw,20px) 0; border-radius: 2px; }
/* fisso a 20px su mobile e desktop, non più un clamp() responsive: misura
   esatta chiesta da Stefano. Niente più grassetto qui: si è spostato sulla
   prima frase del paragrafo sotto, non c'è più un <b> in questo. */
.splash-sub { margin: 0; color: #fff; font-size: 20px; font-weight: 500; line-height: 1.4; max-width: 46ch; }
/* più leggero di .splash-sub apposta (400 invece di 500): è il dettaglio a
   supporto del messaggio principale sopra, non deve pesare uguale. Bianco
   pieno come tutto il resto dello splash, non un'opacità ridotta: stessa
   regola di sempre in questo file, un bianco più tenue sotto al 4.5:1
   richiesto. Fisso a 18px su mobile e desktop, stessa misura esatta di
   .splash-sub sopra. */
/* niente max-width qui (c'era, 54ch): con gli "a capo" scelti a mano
   (<br>) dentro il testo, un limite di larghezza più stretto della frase
   più lunga la spezzava un'altra volta, in un punto non scelto. Resta
   comunque dentro min(640px,92vw) di .splash-content, non sfora. */
.splash-sub2 { margin: clamp(10px,2vw,14px) 0 0; color: #fff; font-size: 18px; font-weight: 400; line-height: 1.4; }
.splash-hint { position: absolute; left: 0; right: 0; bottom: clamp(20px,5vh,40px); text-align: center; color: #fff; font-size: 12px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; }

/* La coreografia (dissolvenze, salita del testo, barre che crescono) vive
   solo qui dentro: chi preferisce niente animazioni vede lo splash intero
   già a posto dal primo frame, nessun elemento resta bloccato invisibile in
   attesa di un'animazione che non parte mai. */
@media (prefers-reduced-motion: no-preference) {
  .splash { opacity: 0; animation: splashIn .5s ease forwards; }
  /* il tour NON sfuma per conto suo all'apertura (per questo viene scoperto
     a piena opacità già in chiudiSplash): se sfumasse anche lui 0→1 nello
     stesso momento in cui lo splash sfuma 1→0, per un attimo sarebbero
     entrambi a metà opacità insieme, ed è proprio lì che si intravede il
     portale sotto. Chiude ancora con la stessa splashOut di sempre: la
     regola sotto vince per ordine, essendo più specifica a parità di peso. */
  .splash.tour { opacity: 1; animation: none; }
  /* stessa specificità della regola sopra (due classi): questa vince sul
     tour in chiusura solo perché viene dopo nel foglio, non per altro. */
  .splash.closing { animation: splashOut .5s ease forwards; }
  .splash-grid { opacity: 0; animation: splashFade 1.4s ease .1s forwards; }
  .splash-glow-a { animation: splashDriftA 7s ease-in-out infinite; }
  .splash-glow-b { animation: splashDriftB 8.5s ease-in-out infinite; }
  .splash-mark span { transform: scaleY(0); transform-origin: bottom; animation: splashBar .55s cubic-bezier(.25,.9,.3,1.25) forwards; }
  .splash-mark span:nth-child(1) { animation-delay: .15s; }
  .splash-mark span:nth-child(2) { animation-delay: .30s; }
  .splash-mark span:nth-child(3) { animation-delay: .45s; }
  .splash-title { opacity: 0; transform: translateY(14px); animation: splashRise .6s ease .55s forwards; }
  .splash-rule { width: 0; animation: splashRule .5s ease .85s forwards; }
  .splash-sub { opacity: 0; transform: translateY(10px); animation: splashRise .6s ease 1.05s forwards; }
  /* seconda linea, stessa animazione della prima ma più avanti nella
     sequenza: tolto e rimesso il ritardo, non il resto (larghezza,
     colore...), già uguale perché condivide la classe .splash-rule. */
  .splash-rule-2 { animation-delay: 1.35s; }
  .splash-sub2 { opacity: 0; transform: translateY(8px); animation: splashRise .6s ease 1.55s forwards; }
  .splash-hint { opacity: 0; animation: splashFade .6s ease 2.2s forwards; }
}
@keyframes splashIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes splashOut { from { opacity: 1; } to { opacity: 0; } }
@keyframes splashFade { to { opacity: 1; } }
@keyframes splashBar { to { transform: scaleY(1); } }
@keyframes splashRise { to { opacity: 1; transform: translateY(0); } }
@keyframes splashRule { to { width: min(120px, 30vw); } }
@keyframes splashDriftA { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(2%,3%) scale(1.08); } }
@keyframes splashDriftB { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(-2%,-3%) scale(1.1); } }

@media (prefers-reduced-motion: reduce) {
  .scrim, .modal, .sidebar, .drawer-scrim, .chip-btn, .entity-card, .tap-tooltip { transition: none; }
  .mtour2, .mtour2-mask, .mtour2-window, .mtour2-arrow, .mtour2-box { transition: none; }
}
