/* S4 (2026-05-19) brand allineato a Miele Red ufficiale Brand Manual 2024 pag 27.
   Hover schiarisce ~15% lightness (medio, Andrea 2026-05-19). */
:root {
  --brand: #8C0014;
  --brand-hover: #C00C20; /* hover medio (schiarisce ~15%, era #DA0124 troppo lighter) */
  --brand-dark: #8C0014; /* alias legacy, eventualmente deprecato */
  --brand-soft: #FCEEF1;
  --bg: #F5F6F8;
  --surface: #FFFFFF;
  --ink: #0F1419;
  --ink-2: #4A5568;
  --ink-3: #8A93A4;
  --line: #E4E7EC;
  --ok: #16A34A;
  --warn: #D97706;
  --danger: #DC2626;
  --info: #2563EB;
  --radius: 16px;
  --shadow-card: 0 1px 2px rgba(15,20,25,0.04), 0 6px 18px rgba(15,20,25,0.05);
  /* Padding-x orizzontale uniforme per tutti i container-content di pagina (mobile + desktop).
     Tutti i selettori layout (ios-header, section-title, mkt-*, cust-card, clienti-toolbar, filter-row, timeline, wiz-*, ecc.) usano questa variabile per allinearsi a flush-left con h1. Non sovrascrivere in media query. */
  --page-pad-x: 18px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
/* text-size-adjust 100%: disattiva il text autosizing di Safari iOS (gonfia
   il testo di alcuni blocchi solo su iPhone, allargando il layout oltre il
   viewport -> shrink-to-fit + auto-zoom al focus degli input). Reset standard
   (normalize.css) che mancava. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
html, body { font-family: -apple-system, BlinkMacSystemFont, "Inter", "SF Pro Display", "Segoe UI", Roboto, system-ui, sans-serif; font-size: 16px; line-height: 1.45; color: var(--ink); background: var(--bg); -webkit-font-smoothing: antialiased; }
/* Rete di sicurezza globale: stringhe lunghe senza spazi (email, URL, ID) vanno a
   capo invece di sforare/tagliare i contenitori. Innocuo sul testo normale e sugli
   elementi con white-space:nowrap (badge/pill). Complemento di min-width:0 sui flex. */
body { overflow-wrap: break-word; }
button { font-family: inherit; font-size: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, textarea, select { font-family: inherit; font-size: inherit; }
.i { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; vertical-align: middle; }
.i-sm { width: 14px; height: 14px; }
.i-lg { width: 22px; height: 22px; }
.i-xl { width: 28px; height: 28px; }
.i-2xl { width: 36px; height: 36px; }

/* Legend */
.legend { width: 100%; max-width: 1340px; margin: 0 auto; padding: 26px 28px 8px; text-align: center; color: var(--ink-2); }
.legend h2 { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; margin-bottom: 6px; color: var(--ink); }
.legend p { font-size: 14px; max-width: 760px; margin: 0 auto; }
.legend .pill-info { display: inline-block; background: var(--brand-soft); color: var(--brand); padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 700; margin: 0 4px; }

/* APP container — responsive single page */
.app { min-height: 100vh; display: flex; background: var(--bg); }
.app-sidebar { display: none; }
/* padding-bottom: libera l'ultimo contenuto (bottoni azione, ultima card) dalla
   .bottom-nav fissa (min-height 68 + padding 10 + safe-area). safe-area-aware. */
.app-main { flex: 1; min-width: 0; display: flex; flex-direction: column; padding-bottom: calc(104px + env(safe-area-inset-bottom, 0px)); }
.screen { display: none; }
.screen.active { display: block; }
.statusbar { display: none; }

/* Tablet+ (>= 768px): contenuto piu ampio. Stesso indent del mobile (18px), e padding
   piu generoso solo per .ios-header. Spazio extra prima delle sezioni successive. */
@media (min-width: 768px) {
  .app-main { padding: 0 0 calc(104px + env(safe-area-inset-bottom, 0px)); }
  .ios-header { padding: 20px var(--page-pad-x) 28px; border-bottom: 1px solid var(--line); }
  .ios-header h1 { font-size: 30px; }
  .machine-card { padding: 18px 22px; }
  .machine-card .id-circle { width: 60px; height: 60px; }
  .machine-card .name { font-size: 18px; }
  .domotica-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
  .template-grid { grid-template-columns: repeat(4, 1fr); }
  /* Aria sopra la prima sezione subito dopo l'ios-header */
  .ios-header + .mkt-intro,
  .ios-header + .section-title,
  .ios-header + .concept-note,
  .ios-header + .filter-row,
  .ios-header + .period-card { margin-top: 14px; }
  .mkt-intro { margin-top: 14px; }
}

/* Desktop (>= 1024px): sidebar fissa, no bottom-nav */
@media (min-width: 1024px) {
  /* App-shell (pattern Coolify): il documento NON scrolla; scorre solo il contenuto
     dentro .app-main. La sidebar sta FERMA fuori dallo scroll → niente rubber-band
     macOS che fa "bouncare" tutta la pagina (sidebar inclusa) all'overscroll. La
     sidebar ha la SUA scrollbar se il viewport verticale è basso, e finisce 16px
     prima del fondo → un velo di grigio (--bg) sotto "Gestore".
     CRUCIALE — .app-main deve restare un BLOCCO (display:block), NON flex: in
     WebKit/Safari uno sticky figlio diretto di un flex-container che scrolla collassa
     a ~1px d'altezza → i sub-tab .cli-subtabs di Andamento/Clienti "sparivano" (è il
     motivo del revert c1859d9). Mobile (<1024px) invariato: scroll sul documento. */
  html, body { height: 100%; overflow: hidden; }
  body { background: var(--bg); }
  .app { max-width: 1440px; margin: 0 auto; box-shadow: 0 0 40px rgba(0,0,0,0.04); background: var(--bg); height: 100vh; overflow: hidden; }
  .app-sidebar { display: flex; flex-direction: column; width: 240px; background: var(--surface); border-right: 1px solid var(--line); padding: 22px 14px; flex-shrink: 0; align-self: flex-start; height: calc(100vh - 16px); overflow-y: auto; overscroll-behavior: contain; }
  .app-main { display: block; height: 100vh; overflow-y: auto; overscroll-behavior: contain; padding-bottom: 28px; background: var(--bg); }
  .bottom-nav { display: none !important; }
  .domotica-grid { grid-template-columns: 1fr 1fr 1fr; gap: 14px; }
  .template-grid { grid-template-columns: repeat(4, 1fr); }
  .ios-header h1 { font-size: 32px; }
  .ios-header { padding-bottom: 22px; }
}

/* Sidebar desktop */
.sb-brand { display: flex; align-items: center; gap: 10px; padding: 4px 10px 18px; border-bottom: 1px solid var(--line); margin-bottom: 14px; }
.sb-brand .logo { width: 36px; height: 36px; background: var(--brand); color: #fff; border-radius: 9px; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 16px; }
.sb-brand .text { display: flex; flex-direction: column; }
.sb-brand .name { font-size: 14px; font-weight: 800; line-height: 1.1; }
.sb-brand .store { font-size: 11px; color: var(--ink-3); display: inline-flex; align-items: center; gap: 4px; }
/* sb-brand cliccabile (multi-lavanderia switcher): aspetto pill, hover brand-soft */
/* margin-top:-15 + padding-top:15 = posizione logo invariata MA hover area
   estesa fino al top sidebar (copre i 15px di "vuoto" sopra il logo, evita
   tagli antiestetici sul hover background brand-soft). */
.sb-brand--btn { width: calc(100% + 28px); margin: -15px -14px 14px; padding: 15px 14px; border: 0; background: transparent; cursor: pointer; text-align: left; transition: background 120ms ease; border-bottom: 1px solid var(--line); }
.sb-brand--btn:hover { background: var(--brand-soft); }
.sb-brand--btn:hover .sb-store-chev { color: var(--brand); }
.sb-store-chev { color: var(--ink-3); transition: color 120ms ease; }

/* Lab-pill inline in ios-header (mobile only): sostituisce il subtitle Lavanderia X
   e sta sulla stessa riga della meta info (es. "8 canali · 6 sensori" a destra).
   min-height 28px = stessa altezza visiva di .lab-pill e .hdr-action per
   garantire allineamento ottico tra icona casa (sx) e icona euro (dx). */
.ios-header-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; min-height: 28px; }
.ios-header-row .meta { margin-left: auto; padding: 0; }

/* Riga titolo (h1 + meta opzionale) sotto la ios-header-row.
   Pattern: H1 a sx, meta opzionale a dx (margin-left:auto).
   margin-top 10px: lascia respiro ma mantiene la coesione del blocco header. */
.ios-title-row { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-top: 18px; }
.ios-title-row h1 { margin: 0; }
.ios-title-row .meta { margin-left: auto; }
@media (min-width: 1024px) {
  .ios-header-row { display: none; }
  .ios-title-row { margin-top: 0; }
}

/* Header action mobile ("Rimborsa" nella ios-header-row).
   Stessa altezza visiva di .lab-pill (28px) — padding verticale e min-height
   identici per allineamento ottico perfetto tra icona casa e icona euro.
   Su desktop nascosto: l'azione vive in sidebar (.sb-action). */
.hdr-action { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; min-height: 28px; background: transparent; border: 1px solid var(--brand); font-size: 13px; font-weight: 700; color: var(--brand); cursor: pointer; margin-left: auto; border-radius: 999px; transition: background 120ms ease; -webkit-tap-highlight-color: transparent; }
.hdr-action:hover { background: var(--brand-soft); }
.hdr-action:active { background: var(--brand-soft); opacity: .85; }
.hdr-action:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.hdr-action svg { width: 13px; height: 13px; flex-shrink: 0; }
@media (min-width: 1024px) { .hdr-action { display: none; } }

/* Sidebar action button — outlined, distinto dalle voci nav.
   Desktop only. Margin-top generoso per stacco netto da Impostazioni.
   Selettore qualificato `.sb-nav .sb-action` per vincere su `.sb-nav button`
   (cascade: stessa altezza specificity altrimenti perde su color/font-size). */
/* Stesso stile di .hdr-action mobile: pill outlined brand, font 14/600 come voci nav. */
.sb-nav .sb-action { display: inline-flex; align-self: flex-start; align-items: center; padding: 6px 14px; min-height: 30px; margin-top: 32px; background: transparent; border: 1px solid var(--brand); border-radius: 999px; font-size: 14px; font-weight: 600; color: var(--brand); cursor: pointer; transition: background 120ms ease; width: auto; }
.sb-nav .sb-action:hover { background: var(--brand-soft); color: var(--brand); }
.sb-nav .sb-action svg { width: 14px; height: 14px; flex-shrink: 0; }

/* Reservations disclosure — collapsed di default, apre tabella stile Bloomest. */
.reservations-disclosure { margin: 12px 18px 24px; background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); overflow: hidden; }
.reservations-disclosure summary { display: flex; align-items: center; gap: 8px; padding: 14px 16px; cursor: pointer; font-weight: 700; color: var(--ink); list-style: none; }
.reservations-disclosure summary::-webkit-details-marker { display: none; }
.reservations-disclosure summary::after { content: '+'; font-size: 22px; font-weight: 400; line-height: 1; color: var(--ink-3); margin-left: auto; transition: color 120ms ease; }
.reservations-disclosure[open] summary::after { content: '\00d7'; font-size: 24px; }
.reservations-disclosure summary:hover::after { color: var(--brand); }
.reservations-count { font-size: 12px; font-weight: 500; color: var(--ink-3); margin-left: 4px; vertical-align: baseline; }

/* "Altre azioni possibili" — disclosure soft sotto la mossa della settimana (Oggi). */
.oggi-altre-azioni { margin: 4px 18px 0; }
.oggi-altre-azioni summary { display: flex; align-items: center; padding: 10px 2px; cursor: pointer; font-weight: 600; font-size: 13px; color: var(--ink-3); list-style: none; }
.oggi-altre-azioni summary::-webkit-details-marker { display: none; }
.oggi-altre-azioni summary::after { content: '+'; font-size: 20px; font-weight: 400; line-height: 1; color: var(--ink-3); margin-left: auto; transition: color 120ms ease; }
.oggi-altre-azioni[open] summary::after { content: '\00d7'; font-size: 22px; }
.oggi-altre-azioni summary:hover { color: var(--brand); }
.oggi-altre-azioni summary:hover::after { color: var(--brand); }
.oggi-altre-azioni .u-mx-18-mt-12 { margin-left: 0; margin-right: 0; }
.reservations-empty { padding: 0 16px 18px; margin: 0; font-size: 13px; color: var(--ink-3); line-height: 1.5; }
.reservations-table-wrap { overflow-x: auto; border-top: 1px solid var(--line); }
.reservations-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.reservations-table th { text-align: left; color: var(--brand); font-weight: 700; padding: 12px 14px; border-bottom: 1px solid var(--line); white-space: nowrap; font-size: 12px; }
.reservations-table td { padding: 12px 14px; border-bottom: 1px solid var(--line); white-space: nowrap; vertical-align: middle; color: var(--ink); }
.reservations-table tbody tr:hover { background: var(--bg); }
.reservations-table tr:last-child td { border-bottom: none; }
.dev-badge { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; background: var(--ink); color: #fff; font-weight: 700; font-size: 11px; margin-right: 8px; vertical-align: middle; }
.status-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 8px; vertical-align: middle; }
.status-dot.status-pending { background: #fbcfa4; }
.status-dot.status-confirmed { background: #9be3a8; }
.status-dot.status-cancelled { background: #f5c0c0; }
.status-dot.status-expired { background: #d4d4d4; }
.card-tag { display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px; background: var(--brand); color: #fff; border-radius: 4px; font-family: monospace; font-size: 11px; font-weight: 600; margin-right: 6px; }
.user-tag { display: inline-flex; align-items: center; padding: 4px 10px; background: #2c7fd1; color: #fff; border-radius: 4px; font-size: 12px; font-weight: 500; }
.lab-pill { display: inline-flex; align-items: center; gap: 8px; padding: 4px 8px 4px 6px; margin-left: -8px; min-height: 28px; background: transparent; border: 0; cursor: pointer; font-size: 14px; font-weight: 700; color: var(--ink); border-radius: 999px; transition: background 120ms ease; -webkit-tap-highlight-color: transparent; }
.lab-pill:hover { background: var(--brand-soft); }
.lab-pill:active { background: var(--brand-soft); opacity: .85; }
.lab-pill:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.lab-pill svg { color: var(--brand); flex-shrink: 0; }
.lab-pill .lab-pill-name { font-weight: 800; letter-spacing: -0.005em; }
.lab-pill .lab-pill-count { font-size: 11px; font-weight: 700; color: var(--ink-3); background: var(--bg); padding: 2px 7px; border-radius: 999px; font-variant-numeric: tabular-nums; letter-spacing: 0.01em; }
.lab-pill .lab-pill-chev { color: var(--ink-3); width: 12px; height: 12px; margin-left: -2px; transition: color 120ms ease, transform 120ms ease; }
.lab-pill:hover .lab-pill-chev { color: var(--brand); }
@media (min-width: 1024px) { .lab-pill { display: none; } .ios-header-row .meta { margin-left: 0; } }

/* Modal "Cambia sede" — lista 6 sedi con sede attiva evidenziata */
.lab-list { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.lab-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); text-decoration: none; color: var(--ink); transition: border-color 120ms ease, background 120ms ease; }
.lab-row:hover { border-color: var(--brand); background: var(--brand-soft); }
.lab-row.is-active { border-color: var(--brand); background: var(--brand-soft); }
.lab-row .lab-ico { width: 36px; height: 36px; flex-shrink: 0; border-radius: 10px; background: var(--bg); color: var(--ink-3); display: inline-flex; align-items: center; justify-content: center; }
.lab-row.is-active .lab-ico { background: var(--brand); color: #fff; }
.lab-row .lab-body { flex: 1; min-width: 0; }
.lab-row .lab-name { font-size: 14px; font-weight: 700; color: var(--ink); }
.lab-row .lab-meta { font-size: 12px; color: var(--ink-3); margin-top: 2px; line-height: 1.4; }
.lab-row .lab-check { color: var(--brand); flex-shrink: 0; }
.lab-foot-note { margin-top: 14px; font-size: 11px; color: var(--ink-3); font-style: italic; text-align: center; }

/* Multi-select chip-row "APPLICA A:" — broadcast Promo su più sedi (no bordi, layout piatto) */
.lab-broadcast { padding: 4px 0 12px; }
/* In Crea/Attive il .cli-view parent non ha padding-x (lo hanno solo bonus-reg),
   quindi il broadcast partial va indentato esplicitamente. (Riordino W1: il tab
   "campagne" è diventato "crea" — qui vive l'"Applica a sedi".) */
.cli-view[data-promo-view="crea"] .lab-broadcast { padding-left: var(--page-pad-x); padding-right: var(--page-pad-x); }
.lab-broadcast-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.lab-broadcast-label { font-size: 11px; font-weight: 800; letter-spacing: 0.06em; color: var(--ink-3); }
.lab-broadcast-count { font-size: 11px; font-weight: 700; color: var(--brand); background: var(--brand-soft); padding: 3px 8px; border-radius: 999px; }
.lab-broadcast-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.lab-chip { display: inline-flex; align-items: center; gap: 4px; padding: 6px 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); font-size: 13px; font-weight: 600; color: var(--ink-2); cursor: pointer; transition: border-color 120ms ease, background 120ms ease, color 120ms ease; }
.lab-chip:hover { border-color: var(--brand); color: var(--brand); }
.lab-chip.on { border-color: var(--brand); background: var(--brand); color: #fff; }
.lab-chip .lab-chip-check { display: none; }
.lab-chip .lab-chip-plus { color: var(--ink-3); }
.lab-chip.on .lab-chip-check { display: inline-flex; color: #fff; }
.lab-chip.on .lab-chip-plus { display: none; }
.lab-chip:hover .lab-chip-plus { color: var(--brand); }
.lab-chip.shake { animation: lab-chip-shake 320ms ease-in-out; }
@keyframes lab-chip-shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }
.sb-nav { display: flex; flex-direction: column; gap: 2px; }
.sb-nav button { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 10px; font-size: 14px; font-weight: 600; color: var(--ink-2); text-align: left; width: 100%; }
.sb-nav button:hover { background: var(--bg); }
.sb-nav button.active { background: var(--brand-soft); color: var(--brand); }
.sb-nav button .badge-n { margin-left: auto; background: var(--danger); color: #fff; font-size: 10px; padding: 2px 7px; border-radius: 999px; font-weight: 700; }
.sb-user { margin-top: auto; padding: 18px 14px; display: flex; align-items: center; gap: 10px; border-top: 1px solid var(--line); margin-left: -14px; margin-right: -14px; margin-bottom: -22px; }
.sb-user .av { width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(135deg,#FFD3DC,#FFAFC0); display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--brand-dark); font-size: 13px; flex-shrink: 0; }
/* flex column: forza .name su riga 1 e .role su riga 2 (no spezzamento del role
   in più righe quando la traduzione è più lunga, es. EN "Manager · 6 locations"). */
.sb-user .text { display: flex; flex-direction: column; min-width: 0; }
.sb-user .text .name { font-size: 13px; font-weight: 700; }
.sb-user .text .role { font-size: 11px; color: var(--ink-3); white-space: nowrap; }

/* App header — stile iOS pulito.
   padding: 12px top / 16px bottom = aria simmetrica con line-height del lab-pill.
   border-bottom: hairline morbido per separare dal content senza pesare. */
.ios-header { background: var(--surface); padding: 12px var(--page-pad-x) 24px; border-bottom: 1px solid var(--line); }
.ios-header .clock-row { display: flex; justify-content: space-between; font-size: 13px; color: var(--ink-3); margin-bottom: 4px; }
.ios-header h1 { font-size: 26px; font-weight: 800; letter-spacing: -0.022em; line-height: 1.15; color: var(--ink); }
.ios-header .meta { display: flex; justify-content: space-between; align-items: baseline; margin-top: 4px; gap: 10px; }
.ios-header .meta .city { font-size: 12px; color: var(--ink-3); }
.ios-header .meta .city strong { color: var(--ink-2); font-weight: 600; }
.ios-header .meta .addr { font-size: 12px; color: var(--ink-3); text-align: right; }
.ios-header .meta .addr strong { color: var(--ink-2); font-weight: 600; display: block; }
.ios-header .meta .addr.compact { font-size: 12px; font-weight: 500; color: var(--ink-3); letter-spacing: 0.02em; }
.ios-header .meta .addr.compact strong { display: inline; font-weight: 700; color: var(--ink-2); font-variant-numeric: tabular-nums; letter-spacing: 0; }
.ios-header .meta .city strong { white-space: nowrap; }

/* Desktop ≥1024: padding calibrato per allineare verticalmente l'h1 "Macchine"
   con il logo "B" della sidebar (entrambi center Y ~40px) E il border-bottom
   della top bar con il border della .sb-brand (entrambi Y ~74px).
   DEVE stare dopo `.ios-header { padding: 12px var 24px }` base per vincere
   nel cascade (stessa specificity, ordine sorgente). */
@media (min-width: 1024px) {
  .ios-header { padding: 25px var(--page-pad-x) 18px; }
}

/* Bottom nav iOS-style */
/* min-height (NON height): in PWA standalone il padding-bottom della
   home-indicator si mangiava lo spazio interno (border-box) e le icone
   finivano schiacciate sul bordo superiore della barra. */
.bottom-nav { position: fixed; bottom: 0; left: 0; right: 0; background: var(--surface); border-top: 1px solid var(--line); display: flex; min-height: 68px; padding-bottom: env(safe-area-inset-bottom, 4px); padding-top: 10px; z-index: 50; }
.bottom-nav button { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; font-size: 10px; color: var(--ink-3); font-weight: 600; position: relative; }
.bottom-nav button.active { color: var(--brand); }
.bottom-nav button.active span { font-weight: 800; }
/* "+" centrale (overflow nav) — FAB rosso pieno (brand) con un velo di glass:
   backdrop-filter dove supportato, fallback opaco. Icona bianca per contrasto.
   IA invariata: apre il bottom-sheet "Altro". */
.bottom-nav .nav-plus { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.bottom-nav .nav-plus .plus-fab { width: 52px; height: 52px; margin-top: -14px; border-radius: 999px; background: rgba(140,0,20,0.88); color: #fff; display: flex; align-items: center; justify-content: center; box-shadow: 0 6px 18px rgba(140,0,20,0.30); border: 1px solid rgba(255,255,255,0.30); -webkit-backdrop-filter: blur(14px) saturate(1.3); backdrop-filter: blur(14px) saturate(1.3); transition: transform 80ms ease, box-shadow 120ms ease, border-color 120ms ease, background 120ms ease; }
.bottom-nav .nav-plus:hover .plus-fab { background: rgba(140,0,20,0.96); border-color: rgba(255,255,255,0.45); box-shadow: 0 8px 22px rgba(140,0,20,0.36); }
.bottom-nav .nav-plus:active .plus-fab { transform: scale(0.92); }
.bottom-nav .nav-plus .plus-fab .i { width: 22px; height: 22px; stroke: #fff; stroke-width: 2.25; fill: none; }
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .bottom-nav .nav-plus .plus-fab { background: var(--brand); border-color: rgba(255,255,255,0.30); }
}
/* A11Y · prefers-reduced-transparency — se l'utente chiede meno trasparenza
   (iOS Reduce Transparency, Windows), spegniamo il velo glass e teniamo il FAB
   pieno e opaco. Coerente con design-system principi-design-mobile.md §6. */
@media (prefers-reduced-transparency: reduce) {
  .bottom-nav .nav-plus .plus-fab { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--brand); border-color: rgba(255,255,255,0.30); }
}
/* menu "+" (bottom-sheet con maniglia visibile + X) — sola NAVIGAZIONE, niente azioni */
.more-sheet .sheet-handle { display: block; }
.more-list { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; }
.more-row { display: flex; align-items: center; gap: 14px; padding: 14px 12px; border-radius: 12px; color: var(--ink); text-decoration: none; transition: background 120ms ease, transform 80ms ease; }
.more-row:hover { background: var(--bg); }
.more-row:active { transform: scale(0.98); }
.more-row > .i:first-child { color: var(--ink-2); flex-shrink: 0; }
.more-row > span { flex: 1; font-weight: 600; font-size: 15px; }
.more-row .chev { opacity: 0.5; flex-shrink: 0; }
/* Home "Oggi" — KPI ricavo */
.oggi-kpi { display: flex; flex-direction: column; gap: 2px; padding: 18px; }
.oggi-kpi-label { font-size: 12px; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700; }
.oggi-kpi-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.oggi-kpi-value { font-size: 32px; font-weight: 800; letter-spacing: -0.02em; color: var(--ink); }
.oggi-kpi-delta { font-size: 14px; font-weight: 700; }                 /* 14px bold = soglia "large text" 3:1 */
.oggi-kpi-delta--up { color: var(--ok); }
.oggi-kpi-delta--down { color: var(--danger); }
.oggi-kpi-sub { font-size: 13px; color: var(--ink-3); margin-top: 2px; }
.oggi-note { padding: 0 18px 18px; font-size: 13px; color: var(--ink-3); }

/* Home "Oggi" — segnali "da fare oggi" (control tower, danger->ok) */
.ct-signals { display: flex; flex-direction: column; gap: 10px; padding: 0 var(--page-pad-x); }  /* gutter = --page-pad-x come .machines.cols-2 / .card */
/* Gruppi categoria "Da fare oggi" (Impianto/Assistenza/Amministrazione/Promozioni) */
.ct-group + .ct-group { margin-top: 16px; }
.ct-group-label { padding: 0 var(--page-pad-x); margin: 0 0 6px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-3); }
/* Link "Vedi tutte le azioni" sotto la singola azione del giorno (-> Clienti>Azioni) */
.oggi-azioni-all { display: inline-flex; align-items: center; gap: 2px; margin: 10px var(--page-pad-x) 0; font-size: 13px; font-weight: 600; color: var(--brand); text-decoration: none; }
.oggi-azioni-all:hover { color: var(--brand-hover); }
.signal-card { display: flex; align-items: center; gap: 14px; padding: 14px 16px; }  /* severità = colore dell'icona (.signal-ico), niente rail/baffi */
.signal-card--danger { --ct-accent: var(--danger); }
.signal-card--warn { --ct-accent: var(--warn); }
.signal-card--info { --ct-accent: var(--info); }
.signal-card--ok { --ct-accent: var(--ok); }
.signal-ico { flex: 0 0 auto; display: flex; color: var(--ct-accent, var(--ink-3)); }
.signal-body { flex: 1 1 auto; min-width: 0; }
.signal-title { font-size: 14px; font-weight: 700; color: var(--ink); }
.signal-detail { font-size: 13px; color: var(--ink-2); margin-top: 2px; }
/* Card segnale interamente cliccabile: ring all'hover nel colore della severità +
   chevron come affordance a riposo. Niente baffi/border a riposo → preserva il
   look "ombra-only" dei segnali e non introduce layout shift. */
.signal-card--link { text-decoration: none; color: inherit; cursor: pointer; transition: box-shadow 120ms ease, transform 80ms ease; }
.signal-card--link:hover { box-shadow: var(--shadow-card), 0 0 0 1.5px var(--ct-accent, var(--brand)); }
.signal-card--link:active { transform: scale(0.98); }
/* Chevron "vai" uniforme con le altre card: STESSA classe .chev-right della tile
   HH (.create-alt-tile), 20px; hover nel colore della severità del segnale. */
.signal-card--link > .chev-right { flex-shrink: 0; width: 20px; height: 20px; color: var(--ink-3); transition: color 120ms ease; }
.signal-card--link:hover > .chev-right { color: var(--ct-accent, var(--brand)); }

/* Home "Oggi" — Azioni rapide: card stile Promo (.create-alt-tile, bordo->brand all'hover) */
.create-alt-tile.oggi-assist-soon { opacity: 0.7; cursor: default; }
.create-alt-tile.oggi-assist-soon:hover { border-color: var(--line); }
.create-alt-tile.oggi-assist-soon:hover > svg { color: var(--ink-2); }
.bottom-nav button .badge-n { position: absolute; top: 4px; left: 50%; transform: translateX(0); background: var(--danger); color: #fff; font-size: 9px; padding: 0 4px; border-radius: 999px; font-weight: 700; line-height: 13px; min-width: 13px; height: 13px; text-align: center; border: 2px solid var(--surface); box-sizing: content-box; }
@media (min-width: 1024px) {
  .app-sidebar + .app-main .bottom-nav { display: none; }
}

/* Card pattern */
.card { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 10px var(--page-pad-x) 0; }

.section-title { padding: 20px var(--page-pad-x) 8px; font-size: 13px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.06em; display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.section-title a { color: var(--brand); font-size: 13px; text-decoration: none; font-weight: 600; text-transform: none; letter-spacing: 0; }
/* Contatore x/y accanto a "Da fare oggi": azionabili / totale mostrati.
   Reso solo quando c'e' almeno 1 azionabile (nascosto in giornata tranquilla). */
.section-title .todo-count { font-size: 11px; font-weight: 700; color: var(--brand); background: var(--brand-soft); padding: 2px 8px; border-radius: 999px; text-transform: none; letter-spacing: 0; font-variant-numeric: tabular-nums; }

/* Impostazioni: due gruppi DICHIARATI (sede vs account) — spec avvisi §6.1.
   .imp-group-ttl e' un livello sopra .section-title (che resta per le
   sotto-sezioni Operativita'/Sicurezza/Profilo dentro il gruppo sede): risponde
   a "questa cosa vale per la sede o per me?" prima di elencare le card. */
.imp-group + .imp-group { border-top: 1px solid var(--line); margin-top: 8px; }
.imp-group-ttl { margin: 0; padding: 20px var(--page-pad-x) 0; font-size: 20px; font-weight: 800; letter-spacing: -0.01em; color: var(--ink); }
.imp-group-sub { margin: 0; padding: 4px var(--page-pad-x) 0; font-size: 13px; color: var(--ink-3); }
.imp-group-note { margin: 12px var(--page-pad-x) 0; }

/* Modal "I miei avvisi": MATRICE eventi x canali (righe = eventi, colonne =
   Push | Email, checkbox indipendenti — pattern GitHub/Linear). Ogni riga e'
   un <form> a se' con auto-save (hx-trigger="change"); head e righe
   condividono lo stesso grid-template cosi' le colonne restano allineate
   anche se il titolo "Report" le interrompe. Il selettore sedi per-riga
   (2+ sedi entitled, §6.2) e' nascosto di default e appare solo con
   "alcune sedi" (classe .is-some, toggle inline sul checkbox all_labs). */
.avvisi-mx-head, .avvisi-mx-row { display: grid; grid-template-columns: 1fr 52px 52px; align-items: center; }
.avvisi-mx-head { padding-bottom: 4px; border-bottom: 1px solid var(--line); }
.avvisi-mx-col { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-3); text-align: center; }
.avvisi-mx-lbl { font-size: 14px; color: var(--ink); padding: 6px 0; }
.avvisi-mx-desc { display: block; font-size: 12px; color: var(--ink-3); margin-top: 1px; }
/* Cella = tutta l'area cliccabile (touch target >= 44px, Apple HIG). */
.avvisi-mx-cell { display: flex; align-items: center; justify-content: center; min-height: 44px; cursor: pointer; }
.avvisi-mx-cell input { width: 18px; height: 18px; accent-color: var(--brand); cursor: inherit; }
.avvisi-mx-cell.is-off { cursor: default; opacity: 0.35; }
.avvisi-row { border-bottom: 1px solid var(--line); }
.avvisi-row:last-of-type { border-bottom: none; }
.avvisi-scope { margin: 0 0 10px; }
.avvisi-scope-all { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--ink-2); cursor: pointer; }
.avvisi-scope-labs { display: none; flex-wrap: wrap; gap: 6px 16px; margin-top: 8px; padding-left: 2px; }
.avvisi-scope.is-some .avvisi-scope-labs { display: flex; }
.avvisi-scope-labs label { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--ink-2); cursor: pointer; }

/* ===== Griglia macchine: switch colonne (mobile sempre 1, desktop 2/3) ===== */
.machines { display: grid; grid-template-columns: 1fr; }
.machines .section-title { grid-column: 1 / -1; }
.col-switch-row { display: none; }
.col-switch { display: inline-flex; gap: 2px; background: var(--bg); border-radius: 10px; padding: 3px; }
.col-switch .col-opt { display: inline-flex; align-items: center; gap: 3px; padding: 6px 11px; border-radius: 8px; color: var(--ink-3); background: transparent; cursor: pointer; transition: background 120ms ease, color 120ms ease; }
.col-switch .col-opt span { width: 3px; height: 13px; border-radius: 1.5px; background: currentColor; opacity: 0.55; }
.col-switch .col-opt.active { background: var(--surface); color: var(--brand); box-shadow: var(--shadow-card); }
.col-switch .col-opt.active span { opacity: 1; }
@media (min-width: 768px) {
  .col-switch-row { display: flex; justify-content: flex-end; padding: 12px var(--page-pad-x) 0; }
  .machines.cols-2, .machines.cols-3 { padding: 0 var(--page-pad-x); column-gap: 12px; }
  .machines.cols-2 { grid-template-columns: 1fr 1fr; }
  .machines.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
  .machines.cols-2 .machine-card, .machines.cols-3 .machine-card { margin-left: 0; margin-right: 0; }
  .machines.cols-2 .section-title, .machines.cols-3 .section-title { padding-left: 0; padding-right: 0; }
}

/* ===== Vista Macchine — info-first, gear icon per azioni ===== */
.machine-card { background: var(--surface); border-radius: 16px; box-shadow: var(--shadow-card); margin: 10px var(--page-pad-x) 0; padding: 16px; position: relative; cursor: pointer; transition: box-shadow 120ms ease; }
.machine-card:hover { box-shadow: 0 2px 8px rgba(140,0,20,0.08), var(--shadow-card); }
.machine-card.alert { border: 1.5px solid #FCD3D3; background: #FFFBFB; }
.machine-card .gear-btn { position: absolute; top: 14px; right: 14px; width: 36px; height: 36px; border-radius: 10px; background: var(--bg); color: var(--ink-2); display: flex; align-items: center; justify-content: center; transition: background .12s ease, color .12s ease, transform .08s ease; }
.machine-card .gear-btn:hover { background: var(--line); color: var(--ink); }
.machine-card .gear-btn:active { transform: scale(0.94); background: var(--line); }
.machine-card .top { display: flex; align-items: center; gap: 14px; padding-right: 44px; }
.machine-card .id-circle { width: 52px; height: 52px; border-radius: 16px; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.machine-card.alert .id-circle { background: #FCE4E4; color: var(--danger); }
.machine-card[data-mstatus="free"] .id-circle { background: #DCFCE7; color: var(--ok); }
.machine-card[data-mstatus="busy"] .id-circle { background: var(--brand-soft); color: var(--brand); }
.machine-card[data-mstatus="broken"] .id-circle { background: var(--bg); color: var(--ink-3); }
.machine-card[data-mstatus="booked"] .id-circle { background: #DBEAFE; color: var(--info); }
.machine-card .id-letter { position: absolute; bottom: -4px; right: -4px; background: var(--ink); color: #fff; font-weight: 800; font-size: 13px; width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--surface); display: flex; align-items: center; justify-content: center; }
.id-wrap { position: relative; }
.machine-card .info { flex: 1; min-width: 0; }
.machine-card .name { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.machine-card .model-line { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.machine-card .status-row { margin-top: 14px; display: flex; align-items: center; gap: 10px; }
.machine-card .progress-bar { flex: 1; height: 6px; background: var(--bg); border-radius: 3px; overflow: hidden; }
.machine-card .progress-bar > div { height: 100%; border-radius: 3px; }
.machine-card .progress-bar.busy > div { background: var(--brand); }
.machine-card .progress-bar.broken > div { background: var(--ink-3); }
.machine-card .progress-bar.free > div { background: var(--ok); }
.machine-card .progress-bar.booked > div { background: var(--info); }
.machine-card .details { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); display: flex; justify-content: space-between; font-size: 12px; color: var(--ink-3); }
.machine-card .details strong { color: var(--ink-2); font-weight: 600; }
.machine-card .alert-cta { margin-top: 14px; }
.machine-card .alert-cta button { width: 100%; padding: 13px; border-radius: 12px; background: var(--danger); color: #fff; font-size: 14px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; gap: 8px; }

.status { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; }
.status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.status.free   { background: #E8F8EE; color: var(--ok); }
.status.busy   { background: #FEE2E2; color: var(--danger); }
.status.broken { background: var(--bg); color: var(--ink-3); }
.status.booked { background: #E5EAFE; color: var(--info); }

/* Primary action button — riservato a casi specifici (es. allarme) */
.btn-prim { padding: 14px; border-radius: 12px; font-size: 14px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; gap: 8px; letter-spacing: 0.02em; }
.btn-prim.go { background: var(--ok); color: #fff; }
.btn-prim.stop { background: var(--danger); color: #fff; }
.btn-prim.fix { background: var(--warn); color: #fff; }
.btn-prim.outline { background: var(--surface); color: var(--ink); border: 1.5px solid var(--line); }

/* Conferma azione critica */
.confirm-row { margin-top: 12px; padding: 10px 12px; background: #FFFBED; border: 1px solid #F8DC8E; border-radius: 10px; font-size: 12px; color: #7A5C00; display: flex; align-items: flex-start; gap: 8px; }

/* Filter pills row — wrap su più righe (coerente con clienti/ticket), no scroll horizontale. */
.filter-row { padding: 12px var(--page-pad-x) 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.filter-pill { padding: 7px 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 999px; font-size: 13px; font-weight: 600; color: var(--ink-2); display: inline-flex; align-items: center; gap: 6px; cursor: pointer; transition: border-color 120ms ease, background 120ms ease; }
.filter-pill:hover:not(.active) { border-color: var(--brand); color: var(--ink); }
.filter-pill:active { transform: scale(0.96); }
.filter-pill.active { background: var(--ink); color: #fff; border-color: var(--ink); }
.filter-pill .count { opacity: 0.65; }
.filter-pill.active .count { opacity: 0.7; }

/* ===== DOMOTICA stile iOS ===== */
.dom-card { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 10px 18px 0; padding: 16px; }
.dom-card h3 { font-size: 14px; font-weight: 700; margin-bottom: 12px; }
.dom-card .stato-pill { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; font-size: 12px; font-weight: 700; margin-bottom: 12px; }
.dom-card .stato-pill.connesso { background: #E8F8EE; color: var(--ok); }
.dom-card .stato-pill.disconnesso { background: #FCE4E4; color: var(--danger); }
.dom-card .btn-reboot { width: 100%; padding: 12px; border: 1.5px solid var(--brand); color: var(--brand); border-radius: 10px; font-size: 13px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; background: var(--surface); cursor: pointer; transition: background 120ms ease, transform 80ms ease; }
.dom-card .btn-reboot:hover { background: var(--brand-soft); }
.dom-card .btn-reboot:active { transform: scale(0.97); }

.dom-channel { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 10px 18px 0; padding: 16px; }
.dom-channel-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.dom-channel-head .ico { width: 28px; height: 28px; color: var(--ink-2); }
.dom-channel-head .name { font-size: 15px; font-weight: 700; }
.dom-channel-row { display: flex; align-items: center; justify-content: space-between; padding: 6px 0; }
.dom-channel-row + .dom-channel-row { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 12px; }
/* Gruppo credenziali (LCS + Ricorda password) unito, poi stacco verso i toggle. */
.field.lcs-field { margin-bottom: 6px; }
.dom-channel-row.lcs-remember-row { margin-bottom: 22px; }
.dom-channel-row .lbl { font-size: 14px; font-weight: 500; color: var(--ink-2); }
.toggle-ios { width: 50px; height: 30px; background: var(--line); border-radius: 15px; position: relative; transition: background .2s; flex-shrink: 0; }
.toggle-ios::after { content: ""; position: absolute; top: 2px; left: 2px; width: 26px; height: 26px; background: #fff; border-radius: 50%; transition: transform .2s; box-shadow: 0 2px 4px rgba(0,0,0,0.2); }
.toggle-ios.on { background: var(--brand); }
.toggle-ios.on::after { transform: translateX(20px); }
/* Domotica: toggle bloccato mentre il comando htmx è in volo */
form.htmx-request .toggle-ios { pointer-events: none; }
/* Transizione comando: colore OBIETTIVO ombreggiato che PULSA finché il cloud
   non conferma (pieno solo a conferma — mai stato "finto"). Il pulse è
   l'indicatore di attività NN/g per attese 1-10s, inline sul controllo. */
@keyframes dom-sync-pulse { 0%, 100% { opacity: .3; } 50% { opacity: .6; } }
.toggle-ios.pending-on { background: var(--brand); opacity: .45; pointer-events: none; animation: dom-sync-pulse 1.2s ease-in-out infinite; }
.toggle-ios.pending-on::after { transform: translateX(20px); }
.toggle-ios.pending-off { background: var(--line); opacity: .45; pointer-events: none; animation: dom-sync-pulse 1.2s ease-in-out infinite; }
.toggle-ios.pending-off::after { transform: none; }
@media (prefers-reduced-motion: reduce) {
  .toggle-ios.pending-on, .toggle-ios.pending-off { animation: none; }
}
/* Micro-label di attesa accanto alla label di riga durante il pending */
.dom-sync-note { font-size: 12px; font-weight: 500; color: var(--ink-3); margin-left: 6px; white-space: nowrap; }
/* Attivo in automatico: stato visibile ma non comandabile (governa la centralina) */
.dom-channel .toggle-ios[aria-disabled="true"] { opacity: .55; cursor: not-allowed; pointer-events: none; }
.consent-state { font-size: 13px; font-weight: 700; }
.consent-state.is-on { color: var(--ok, #16a34a); }
.consent-state.is-off { color: var(--ink-3); }

/* Sensor strip */
.sensor-strip { padding: 10px 18px 0; display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
.sensor-cell { background: var(--surface); border-radius: 12px; padding: 12px 8px; box-shadow: var(--shadow-card); text-align: center; }
.sensor-cell .v { font-size: 18px; font-weight: 800; letter-spacing: -0.01em; }
.sensor-cell .l { font-size: 10px; color: var(--ink-3); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; margin-top: 2px; }

/* ===== Modal / sheet ===== */
.modal-backdrop { position: absolute; inset: 0; background: rgba(15,20,25,0.5); display: none; align-items: flex-end; justify-content: center; z-index: 30; }
.modal-backdrop.open { display: flex; }
.sheet { background: var(--surface); border-radius: 24px 24px 0 0; width: 100%; max-height: 92%; min-height: min(60vh, 520px); overflow-y: auto; padding: 20px 18px 24px; animation: slideUp .25s ease; }

@media (min-width: 768px) {
  .modal-backdrop { align-items: center; padding: 24px; }
  .sheet { max-width: 560px; max-height: 90vh; min-height: 0; border-radius: 16px; animation: fadeIn .2s ease; }
}
@keyframes fadeIn { from { opacity: 0; transform: scale(0.98); } to { opacity: 1; transform: scale(1); } }
@keyframes slideUp { from { transform: translateY(100%) } to { transform: translateY(0) } }
/* Trattino (drag handle) nascosto 2026-06-13: era decorativo, non trascinabile (nessun
   swipe-to-dismiss) -> affordance bugiarda. Chiusura via X (.sheet-close) + tap sul backdrop.
   Proprieta' conservate sotto display:none per ripristino se in futuro si implementa il drag. */
.sheet-handle { display: none; width: 44px; height: 4px; background: var(--line); border-radius: 2px; margin: -4px auto 14px; }
/* Close button (X) top-right del sheet modal · stesso look di .gm-close (riquadro grigio arrotondato) */
.sheet { position: relative; }
.sheet-close { position: absolute; top: 16px; right: 16px; width: 32px; height: 32px; border-radius: 8px; background: var(--bg); border: 0; color: var(--ink-2); display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 2; }
.sheet-close:hover { background: var(--line); }
.sheet-close:active { transform: scale(0.9); }
.sheet-close .i { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2.5; fill: none; }
.sheet h3 { font-size: 20px; font-weight: 800; letter-spacing: -0.02em; }
.sheet .sub { font-size: 13px; color: var(--ink-3); margin-top: 2px; margin-bottom: 16px; }
.sheet .sheet-section { font-size: 17px; font-weight: 700; color: var(--ink); letter-spacing: -0.01em; margin: 20px 0 12px; }  /* titolo di sezione 17px scuro: nettamente > etichette 11px (gerarchia) */
.sheet .sheet-section:first-of-type { margin-top: 6px; }

/* Ticket thread modal (dashboard): bubble cliente vs gestore, no accent verde */
.td-thread--modal { display: flex; flex-direction: column; gap: 8px; padding: 0; margin-bottom: 16px; }
.td-thread--modal .td-msg { padding: 10px 14px; border-radius: 14px; max-width: 90%; }
.td-thread--modal .td-msg-meta { font-size: 11px; color: var(--ink-3); margin-bottom: 4px; font-weight: 600; }
.td-thread--modal .td-msg-body { font-size: 13px; line-height: 1.5; color: var(--ink); white-space: pre-wrap; }
.td-thread--modal .td-msg--cliente { background: var(--bg); align-self: flex-start; border-bottom-left-radius: 4px; }
.td-thread--modal .td-msg--gestore { background: #F0FDF4; align-self: flex-end; border-bottom-right-radius: 4px; }

.modal-tabs { display: flex; gap: 4px; padding: 4px; background: var(--bg); border-radius: 10px; margin-bottom: 16px; }
.modal-tabs button { flex: 1; padding: 8px; border-radius: 8px; font-size: 12px; font-weight: 700; color: var(--ink-3); }
.modal-tabs button.active { background: var(--surface); color: var(--ink); box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
.modal-pane { display: none; }
.modal-pane.active { display: block; }

/* === Clienti tab redesign · sub-tabs + slide-in detail === */

/* Sub-tabs (Lista | Gruppi) sotto il titolo, fuori dal 40/60 */
.cli-subtabs { display: flex; padding: 0; border-bottom: 1px solid var(--line); background: var(--surface); margin-bottom: 0; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: none; position: sticky; top: 0; z-index: 20; }
.cli-subtabs::-webkit-scrollbar { display: none; }
.cli-subtab { padding: 12px 18px; border: none; border-bottom: 2px solid transparent; background: transparent; font-size: 14px; font-weight: 700; color: var(--ink-3); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; transition: color .12s, border-color .12s; margin-bottom: -1px; white-space: nowrap; flex-shrink: 0; text-decoration: none; }
.cli-subtab:hover { color: var(--ink); }
.cli-subtab.active { color: var(--brand); border-bottom-color: var(--brand); }
.cli-subtab .chip-count { font-size: 11px; padding: 1px 6px; border-radius: 999px; background: var(--bg); color: var(--ink-2); font-weight: 700; }
.cli-subtab.active .chip-count { background: var(--brand-soft); color: var(--brand); }
.cli-subtab .badge-n { font-size: 10px; padding: 2px 7px; border-radius: 999px; background: var(--danger); color: #fff; font-weight: 700; }
/* Label sub-tab responsive: piena su desktop, abbreviata su mobile (breakpoint = cli-sort-mobile) */
.cli-subtab .lbl-short { display: none; }
@media (max-width: 640px) {
  .cli-subtab .lbl-full { display: none; }
  .cli-subtab .lbl-short { display: inline; }
}

/* Cli views (Lista | Gruppi) · full-width */
.cli-view { display: none; }
.cli-view.active { display: block; padding-bottom: 24px; }
/* Promo sub-tab: respiro tra .cli-subtabs sticky e il primo titolo (era attaccato su mobile) */
.cli-view[data-promo-view].active { padding-top: 14px; }
/* Bonus-reg e Mostra-in-cassa: form a contenuto pieno → serve padding orizzontale di pagina (mkt-intro ce l'ha già: azzero per non duplicare) */
.cli-view[data-promo-view="bonus-reg"].active,
.cli-view[data-promo-view="bonus-compleanno"].active,
.cli-view[data-promo-view="cassa"].active { padding-left: var(--page-pad-x); padding-right: var(--page-pad-x); }
.cli-view[data-promo-view="bonus-reg"] .mkt-intro,
.cli-view[data-promo-view="bonus-compleanno"] .mkt-intro,
.cli-view[data-promo-view="cassa"] .mkt-intro { padding-left: 0; padding-right: 0; }
.cli-view[data-promo-view="bonus-reg"] .section-title,
.cli-view[data-promo-view="bonus-compleanno"] .section-title { padding-left: 0; padding-right: 0; }
.cli-view[data-promo-view="bonus-compleanno"] .u-note-inline-pad { margin-left: 0; margin-right: 0; }
.cli-view[data-promo-view="bonus-reg"] .metric-rows,
.cli-view[data-promo-view="bonus-compleanno"] .metric-rows { margin: 0; }
/* Il disclosure (storico bonus) ha margin orizzontale 18px pensato per pagine
   full-width: nel pane già paddato va a filo con titolo e card. */
.cli-view[data-promo-view="bonus-reg"] .reservations-disclosure { margin-left: 0; margin-right: 0; }
/* Pill range temporale dello Storico campagne (Promo · chip riusate da Fatture) */
.storico-chip-row { display: flex; gap: 8px; flex-wrap: wrap; padding: 0 var(--page-pad-x) 14px; }

/* Slide-in customer detail pane · mobile fullscreen, desktop pannello da destra */
.cust-pane { position: fixed; top: 0; right: 0; bottom: 0; width: 100%; background: var(--surface); transform: translateX(100%); transition: transform .3s ease; z-index: 40; overflow-y: auto; overflow-x: hidden; box-shadow: -12px 0 32px rgba(0,0,0,0.16); padding-top: env(safe-area-inset-top); padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
.cust-pane.open { transform: translateX(0); }
@media (min-width: 1024px) { .cust-pane { width: min(560px, 50vw); border-left: 1px solid var(--line); } }

.cust-pane-head { position: sticky; top: 0; z-index: 5; background: var(--surface); border-bottom: 1px solid var(--line); padding: 14px 18px 12px; display: flex; align-items: center; gap: 12px; }
.cust-pane-head .back { width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center; border-radius: 10px; background: var(--bg); color: var(--ink); cursor: pointer; flex-shrink: 0; }
.cust-pane-head .back:hover { background: var(--line); }
.cust-pane-head .head-body { flex: 1; min-width: 0; }
.cust-pane-head h3 { font-size: 18px; font-weight: 800; letter-spacing: -0.02em; margin: 0; line-height: 1.2; }
.cust-pane-head .sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.cust-pane-tabs { position: sticky; top: 64px; z-index: 4; background: var(--surface); padding: 10px 18px; border-bottom: 1px solid var(--line); }
.cust-pane-tabs .modal-tabs { margin-bottom: 0; }
.cust-pane-body { padding: 16px 18px calc(24px + 68px + env(safe-area-inset-bottom)); }
.cust-pane-body .section-title { padding-left: 0; padding-right: 0; }
.card-banner { border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; margin-bottom: 18px; }
.card-banner-serial { font-size: 15px; font-weight: 700; font-family: 'SF Mono', ui-monospace, monospace; color: var(--ink); letter-spacing: 0.04em; }
.card-banner-meta { display: flex; gap: 18px; margin-top: 6px; font-size: 13px; color: var(--ink-2); }
.card-banner-meta strong { color: var(--ink); font-weight: 700; }
.card-banner-link { display: inline-block; margin-top: 8px; font-size: 13px; font-weight: 600; color: var(--brand); text-decoration: none; }
.card-banner-link:hover { text-decoration: underline; }
.cust-pane-empty { display: none; }

.cust-card.active-pane { background: var(--brand-soft); border-left: 3px solid var(--brand); }

/* Toolbar (pills + ricerca + Ordina) visibile solo nella sub-tab Lista */
body[data-cli-view="gruppi"] .clienti-toolbar,
body[data-cli-view="azioni"] .clienti-toolbar,
body[data-cli-view="ticket"] .clienti-toolbar { display: none; }

/* "Altri filtri": lista verticale (.chip-more-row), non pill — richiesta Andrea. */
.chip-more-list { min-width: 210px; padding: 6px; gap: 2px; }
.chip-more-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 9px 10px; border-radius: 8px; font-size: 13px; font-weight: 600; color: var(--ink-2); text-decoration: none; cursor: pointer; transition: background 120ms ease, color 120ms ease; }
.chip-more-row:hover { background: var(--bg); color: var(--ink); }
.chip-more-row.is-on { background: var(--ink); color: #fff; }
.chip-more-row .chip-count { padding: 1px 7px; border-radius: 999px; background: var(--bg); color: var(--ink-2); font-size: 11px; font-weight: 700; line-height: 1.5; }
.chip-more-row:hover .chip-count { background: var(--brand-soft); color: var(--brand); }
.chip-more-row.is-on .chip-count { background: rgba(255, 255, 255, 0.24); color: #fff; }

/* "Ordina" mobile: select nativo (picker OS, zero problemi iOS). Visibile solo su
   mobile; su desktop si ordina dagli header cliccabili. */
.cli-sort-mobile { display: flex; align-items: center; gap: 8px; }
.cli-sort-lbl { flex-shrink: 0; font-size: 13px; font-weight: 700; color: var(--ink-2); }
.cli-sort-mobile select { flex: 1; min-width: 0; height: 42px; border: 1px solid var(--line); border-radius: 999px; padding: 0 38px 0 14px; font-size: 16px; font-weight: 600; color: var(--ink); background-color: var(--surface); cursor: pointer; -webkit-appearance: none; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238A93A4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; background-size: 16px; }
.cli-sort-mobile select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
@media (min-width: 800px) { .cli-sort-mobile { display: none; } }

.cface { display: none; }
.cface.active { display: block; }

/* Stepper Azioni (Clienti → banner A4 + attivazione campagna) */
.az-stepper { max-width: 560px; margin: 0 auto; }
/* margin-right riserva lo spazio della .sheet-close (X assoluta: 32px + 16px right):
   senza, l'ultimo segmento della progress finisce sotto la X e ne rompe l'allineamento. */
.az-step-progress { display: flex; gap: 6px; margin: -4px 44px 12px 0; }
.az-step-progress > span { flex: 1; height: 4px; border-radius: 2px; background: var(--line); }
.az-step-progress > span.done { background: var(--brand); }
.az-step-num { font-size: 11px; font-weight: 800; color: var(--brand); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px; }
.az-step-ttl { font-size: 20px; font-weight: 800; letter-spacing: -0.02em; color: var(--ink); line-height: 1.25; }
.az-step-sub { font-size: 13px; color: var(--ink-2); line-height: 1.5; margin-top: 6px; margin-bottom: 16px; }
.az-step-actions { display: flex; gap: 8px; margin-top: 18px; flex-wrap: wrap; }
.az-step-actions > button { flex: 1; min-width: 120px; padding: 10px 14px; font-size: 13px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
/* Banner A4 preview */
.az-banner-preview { background: #fff; border: 2px dashed var(--line); border-radius: 12px; padding: 32px 28px; text-align: center; aspect-ratio: 1 / 1.414; max-height: 380px; margin: 0 auto; display: flex; flex-direction: column; justify-content: space-between; box-shadow: 0 4px 16px rgba(0,0,0,0.05); }
.azb-content { display: flex; flex-direction: column; justify-content: center; flex: 1; }
.azb-headline { font-size: 32px; font-weight: 900; color: var(--brand); letter-spacing: -0.03em; line-height: 1.1; }
.azb-body { font-size: 15px; color: var(--ink); font-weight: 600; line-height: 1.4; margin-top: 12px; }
.azb-logo { padding-top: 14px; border-top: 1.5px solid var(--brand); display: flex; justify-content: center; }
.azb-logo img { max-width: 70%; height: 28px; object-fit: contain; }
.az-banner-edit { background: var(--bg); border-radius: 10px; padding: 12px 14px; margin-top: 14px; }
.az-banner-edit .abe-ttl { font-size: 12px; font-weight: 700; color: var(--ink); margin-bottom: 10px; }
.az-banner-edit .abe-ttl small { font-weight: 500; color: var(--ink-3); font-size: 11px; }
.az-banner-edit .field { margin-bottom: 10px; }
.az-banner-edit .field:last-child { margin-bottom: 0; }
.az-banner-edit label { display: block; font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 4px; }
.az-banner-edit input, .az-banner-edit textarea { width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 16px; font-family: inherit; background: var(--surface); }
.az-banner-edit textarea { resize: vertical; min-height: 50px; }
.az-banner-edit .abe-hint { font-size: 11px; color: var(--ink-3); margin-top: 8px; line-height: 1.4; font-style: italic; }
/* (Campaign summary box ora usa .metric-rows/.metric-row di Promo direttamente) */
.az-done-ico { text-align: center; margin: 8px 0 16px; }
.az-done-ico svg { width: 56px; height: 56px; padding: 14px; border-radius: 50%; background: #E8F8EE; }

/* "Azioni in lavanderia" (ex "azioni dai dati cliente"): stessa struttura di
   "Azioni rapide" + Happy Hour — section-title al top + tile .create-alt-tile in
   .u-mx-18-mt-12, NIENTE riquadro. Prova storica reale (Parte 2): riga sotto il
   sub, resa solo se l'azione ha history_line (es. reactivate -> dormienti). */
.create-alt-tile .as-proof { font-size: 11px; font-weight: 700; color: var(--ink-2); margin-top: 2px; font-variant-numeric: tabular-nums; }

/* Toolbar Clienti · chips sopra + ricerca canonica full-width sotto (colonna
   a ogni breakpoint: la .search-bar sta SEMPRE subito sopra la lista). */
.clienti-toolbar { padding: 12px var(--page-pad-x); display: flex; flex-direction: column; gap: 10px; background: var(--surface); border-bottom: 1px solid var(--line); }
/* 2 filtri principali + "Altri filtri": stanno su una riga, niente scroll. */
.clienti-toolbar .filter-row { padding: 0; margin: 0; align-items: center; flex-wrap: wrap; gap: 6px; }
.cface-empty { text-align: center; padding: 48px 24px; color: var(--ink-3); }
.cface-empty .ttl { font-size: 16px; font-weight: 700; color: var(--ink-2); margin-bottom: 6px; }
.cface-empty .sub { font-size: 13px; line-height: 1.5; }

.cat-card { display: flex; align-items: center; gap: 12px; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 14px; margin: 0 18px 8px; cursor: pointer; transition: border-color .12s; }
.cat-card:hover { border-color: var(--brand); }
.cat-card .cat-ico { width: 40px; height: 40px; border-radius: 10px; background: var(--brand-soft); color: var(--brand); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.cat-card .cat-body { flex: 1; min-width: 0; }
.cat-card .cat-name { font-size: 14px; font-weight: 700; color: var(--ink); }
.cat-card .cat-meta { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.cat-card .cat-count { font-size: 18px; font-weight: 800; color: var(--ink); margin-right: 4px; }
.cat-card .cat-settings { width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px; color: var(--ink-3); }
.cat-card .cat-settings:hover { background: var(--bg); color: var(--brand); }

/* nowrap + .ttl restringibile: col wrap il flex spezzava la riga sulla larghezza
   NATURALE del titolo (prima di restringerlo), così i nomi/sub lunghi buttavano
   .head-actions sotto il blocco titolo. Il sub va a capo dentro .ttl, il bottone
   resta in alto a dx. */
.cat-detail-head { display: flex; align-items: center; gap: 12px; padding: 16px 18px 12px; }
/* Back = bottone circolare col linguaggio dei bottoni del progetto (surface +
   bordo --line, hover come .btn-secondary): visibile e tappabile, non un
   chevron che galleggia sul fondo pagina. */
.cat-detail-head .back { width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--ink); cursor: pointer; flex-shrink: 0; transition: background .15s, border-color .15s; }
.cat-detail-head .back:hover { border-color: var(--ink-3); background: var(--bg); }
.cat-detail-head .back svg { width: 18px; height: 18px; }
.cat-detail-head .ttl { flex: 1 1 auto; min-width: 0; }
.cat-detail-head .ttl h2 { font-size: 18px; font-weight: 800; letter-spacing: -0.02em; margin: 0; }
.cat-detail-head .ttl .sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.cat-detail-head .settings-btn { width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px; background: var(--bg); color: var(--ink-2); cursor: pointer; }
.cat-detail-head .settings-btn:hover { background: var(--brand-soft); color: var(--brand); }
/* A dx dell'header resta SOLO l'azione di gestione (Configura gruppo):
   identità a sx, gestione a dx. align-self: start lo tiene sulla riga del nome
   (non centrato fra nome e sub) anche quando il sub va a capo. */
.cat-detail-head .head-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; align-self: flex-start; flex-shrink: 0; }
/* Riga azioni marketing del gruppo, sotto l'header: CTA primario (Invia
   messaggio) + Attiva offerta. Su schermi stretti i bottoni si allargano. */
.cat-detail-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 0 var(--page-pad-x); margin: 2px 0 8px; }
@media (max-width: 640px) {
  .cat-detail-actions .btn-primary, .cat-detail-actions .btn-secondary { flex: 1; }
}
/* I bottoni secondari di questa vista (Configura, Attiva offerta) vivono
   DIRETTAMENTE sul fondo pagina (--bg): lo sfondo grigio di .btn-secondary li
   mimetizzava. Stesso linguaggio del .back qui sopra → surface (bianco) + bordo
   --line; l'hover scende a --bg per dare feedback. */
.cat-detail-head .head-actions .btn-secondary,
.cat-detail-actions .btn-secondary { background: var(--surface); }
.cat-detail-head .head-actions .btn-secondary:hover,
.cat-detail-actions .btn-secondary:hover { background: var(--bg); }
/* Descrizione custom del gruppo (da Configura gruppo); hidden se non impostata. */
.cat-detail-desc { padding: 0 var(--page-pad-x); margin: 4px 0 4px; font-size: 13px; color: var(--ink-2); line-height: 1.5; max-width: 640px; }

.cust-card.with-check { padding-left: 8px; }
.cust-card .check { width: 22px; height: 22px; border: 2px solid var(--line); border-radius: 6px; display: none; align-items: center; justify-content: center; flex-shrink: 0; background: var(--surface); }
.cust-card.with-check .check { display: inline-flex; }
body[data-op-select="on"] [data-cli-view="lista"] .cust-card .check { display: inline-flex; }
body[data-op-select="on"] [data-cli-view="lista"] .cust-card { padding-left: 8px; }
.cust-card.selected { border-color: var(--brand); background: var(--brand-soft); }
.cust-card.selected .check { background: var(--brand); border-color: var(--brand); color: #fff; }
.cust-card.selected .check svg { display: block; }
.cust-card .check svg { display: none; width: 14px; height: 14px; stroke: #fff; stroke-width: 3; }

.bulk-bar { position: sticky; bottom: calc(68px + env(safe-area-inset-bottom, 0px)); background: var(--surface); color: var(--ink); padding: 14px 18px 16px; margin: 16px 18px 0; border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 8px 24px rgba(15,20,25,0.12); display: none; z-index: 49; }
@media (min-width: 1024px) { .bulk-bar { bottom: 12px; margin: 16px 18px 12px; } }
.bulk-bar.active { display: block; }
.bulk-bar .bulk-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; font-size: 13px; }
.bulk-bar .bulk-count { font-weight: 700; color: var(--brand); }
.bulk-bar .bulk-clear { color: var(--ink-3); cursor: pointer; font-size: 12px; font-weight: 600; }
.bulk-bar .bulk-clear:hover { color: var(--ink); text-decoration: underline; }
.bulk-bar .bulk-actions { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.bulk-bar .bulk-action { padding: 12px 6px; background: var(--bg); color: var(--ink); border-radius: 10px; font-size: 12px; font-weight: 700; display: flex; flex-direction: column; align-items: center; gap: 6px; border: 1px solid var(--line); cursor: pointer; line-height: 1.2; text-align: center; }
.bulk-bar .bulk-action:hover { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); }
.bulk-bar .bulk-action svg { width: 20px; height: 20px; color: var(--brand); stroke-width: 2; }

.field { margin-bottom: 18px; }
.field label { display: block; font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 6px; }
.field input, .field select, .field textarea { width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--ink); font-size: 16px; font-family: inherit; font-weight: 500; transition: border-color 120ms ease, box-shadow 120ms ease; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
/* Select: nascondi chrome browser, applica chevron custom coerente con input style */
.field select { -webkit-appearance: none; -moz-appearance: none; appearance: none; padding-right: 38px; cursor: pointer; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238A93A4' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>"); background-repeat: no-repeat; background-position: right 12px center; background-size: 14px 14px; }
.field select:focus { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238C0014' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>"); }
.field textarea { min-height: 80px; resize: vertical; }
.field.half { max-width: calc(50% - 5px); }
/* Validazione: messaggio errore con stile nostro (sostituisce il bubble nativo del browser) */
.field-error { color: var(--danger); font-size: 12px; font-weight: 600; margin-top: 6px; padding-left: 2px; }
.field input[aria-invalid="true"], .field select[aria-invalid="true"], .field textarea[aria-invalid="true"],
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.15);
}
.field.third { max-width: calc(33% - 5px); }
.field.wide { max-width: calc(70% - 5px); }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.field-row.city-cap { grid-template-columns: 1fr 2fr; }
.field-inline { display: flex; gap: 8px; align-items: center; }
.field-prefix { display: flex; align-items: center; gap: 0; flex: 1; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); padding-left: 12px; transition: border-color 120ms ease, box-shadow 120ms ease; }
.field-prefix:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.field-prefix .prefix { font-size: 16px; font-weight: 600; color: var(--ink); flex-shrink: 0; }
.field-prefix input { border: none !important; background: none !important; box-shadow: none !important; padding-left: 4px; flex: 1; min-width: 0; }
.field.req label::after { content: ' *'; color: var(--danger); font-weight: 700; }
.field.is-err input, .field.is-err select { border-color: var(--danger); }
.field .field-err { color: var(--danger); font-size: 11px; margin-top: 4px; }
.field-suffix { display: flex; align-items: center; gap: 6px; }
.field-suffix input { flex: 1; }
.field-suffix .suffix { font-size: 16px; font-weight: 600; color: var(--ink-3); flex-shrink: 0; }

/* Form Happy Hour (planner solo cassa): i controlli stanno in <fieldset> (fuori da
   .field), quindi legend, righe checkbox e fasce orarie vanno stilati esplicitamente. */
.happy_hour_form fieldset { border: 0; padding: 0; margin: 0 0 18px; }
.happy_hour_form legend { font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 8px; padding: 0; }
.happy_hour_form .field-row .field { margin-bottom: 0; }
.happy_hour_form .chk-row { display: flex; flex-wrap: wrap; gap: 10px 16px; }
.happy_hour_form .chk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px 16px; }
.happy_hour_form .chk-all { display: flex; padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid var(--line); }
.happy_hour_form .chk { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 500; color: var(--ink); cursor: pointer; }
.happy_hour_form .chk input { width: auto; margin: 0; accent-color: var(--brand); flex-shrink: 0; }
.happy_hour_form .time-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.happy_hour_form .time-row:last-child { margin-bottom: 0; }
.happy_hour_form .time-row input { flex: 1; min-width: 0; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--ink); font-size: 16px; font-family: inherit; font-weight: 500; }
.happy_hour_form .time-row input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.happy_hour_form .time-row span { color: var(--ink-3); font-weight: 600; flex-shrink: 0; }
/* Header: titolo + badge "solo cassa" non devono finire sotto la X (assoluta top-right) */
.happy_hour_form h3 { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding-right: 44px; line-height: 1.25; margin-bottom: 20px; }
/* Date Dal/Al col calendario del progetto (.dt-field). NB: .field-row è display:flex
   (definizione globale che vince), quindi qui si ragiona in flex, non in grid: su
   mobile i due campi data (trigger largo con icona) si impilano a piena larghezza,
   da ≥480px stanno su due colonne uguali che si restringono (min-width:0 → niente
   overflow oltre il bordo del modale). */
.happy_hour_form .hh-dates { align-items: start; flex-wrap: wrap; }
.happy_hour_form .hh-dates .dt-field { flex: 1 1 100%; min-width: 0; }
@media (min-width: 480px) { .happy_hour_form .hh-dates .dt-field { flex: 1 1 0; } }
.happy_hour_form .hh-dates .dt-trigger { min-width: 0; width: 100%; }
/* iOS zooma sugli input con font < 16px: il testo data deve stare a 16px (e si legge meglio) */
.happy_hour_form .dt-trigger .dt-display { font-size: 16px; }
/* Dal/Al sono in fondo al modale scrollabile: apri il popover VERSO L'ALTO così
   non viene clippato dall'overflow del .sheet (solo desktop; su touch è display:none
   e si usa il picker OS nativo). */
.happy_hour_form .hh-dates .dt-popover { top: auto; bottom: calc(100% + 6px); }
/* la colonna Al allinea il popover a destra per non sforare il bordo del modale */
.happy_hour_form .hh-dates .dt-field:last-child .dt-popover { left: auto; right: 0; }
.cal-nav-row { display: flex; align-items: center; justify-content: center; gap: 12px; padding: 8px 18px; }
.cal-nav-btn { width: 30px; height: 30px; border-radius: 8px; background: var(--bg); display: inline-flex; align-items: center; justify-content: center; font-size: 16px; color: var(--ink); cursor: pointer; text-decoration: none; }
.cal-nav-btn:hover { background: var(--line); }
.cal-nav-btn.u-disabled { opacity: .3; pointer-events: none; }
.cal-nav-label { font-size: 14px; font-weight: 700; text-transform: capitalize; min-width: 120px; text-align: center; }
.fatture-chip-row { padding: 8px var(--page-pad-x) 16px; }
.fatture-disclaimer { padding: 20px var(--page-pad-x) 12px; color: var(--ink-3); font-size: 16px; line-height: 1.6; }
.fattura-desc-input { border: none; border-bottom: 1px dashed var(--line); background: transparent; font-size: 13px; padding: 4px 2px; width: 100%; min-width: 280px; color: var(--ink); }
.fattura-desc-input:focus { border-bottom-color: var(--brand); outline: none; }
.fattura-desc-input::placeholder { color: var(--ink-3); }
/* iOS zooma al focus se il font e' < 16px: su touch sale a 16px (come .dt-filter-input).
   Conta con l'autofocus sul primo campo, che altrimenti zooma all'apertura di Fatture.
   min-width piu' larga col font 16px: la descrizione tipo ("Servizi di lavanderia
   self-service") deve leggersi intera — un input non wrappa e il placeholder non
   scorre; la tabella scrolla gia' in orizzontale (mov-table-wrap). */
@media (hover: none) and (pointer: coarse) {
  .fattura-desc-input { font-size: 16px; min-width: 340px; }
}

/* Gestione detersivi — grid card con stato consumo (ok/warn/alarm/empty) */
.and-pane-head { padding: 14px var(--page-pad-x) 0; }
.and-pane-head h3 { font-size: 20px; font-weight: 800; letter-spacing: -0.01em; color: var(--ink); margin-bottom: 4px; }
.and-pane-head .and-pane-sub { font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.detersivi-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; padding: 14px var(--page-pad-x) 0; }
.detersivo-card { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 14px; display: flex; flex-direction: column; gap: 10px; transition: border-color 120ms ease, box-shadow 120ms ease; }
.detersivo-card--ok { border-color: var(--line); }
.detersivo-card--warn { border-color: #F5D9B5; background: linear-gradient(180deg, #FFFCF7 0%, var(--surface) 70%); }
.detersivo-card--alarm { border-color: #FCA5A5; background: linear-gradient(180deg, #FEF6F6 0%, var(--surface) 70%); box-shadow: 0 0 0 1px #FCA5A5; }
.detersivo-card--empty { opacity: 0.7; background: var(--bg); }
.detersivo-card .dc-head { display: flex; flex-direction: column; gap: 2px; position: relative; }
.detersivo-card .dc-name { font-size: 15px; font-weight: 700; color: var(--ink); }
.detersivo-card .dc-desc { font-size: 12px; color: var(--ink-3); }
.detersivo-card .dc-badge { position: absolute; top: 0; right: 0; background: var(--danger); color: #fff; padding: 3px 8px; border-radius: 999px; font-size: 10px; font-weight: 700; letter-spacing: 0.05em; }
.detersivo-card .dc-body { display: flex; flex-direction: column; gap: 10px; }
.detersivo-card .dc-progress { display: flex; flex-direction: column; gap: 4px; }
.detersivo-card .dc-progress-bar { width: 100%; height: 8px; background: var(--bg); border-radius: 999px; overflow: hidden; }
.detersivo-card .dc-progress-fill { height: 100%; background: var(--ok); border-radius: 999px; transition: width 200ms ease; }
.detersivo-card--warn .dc-progress-fill { background: var(--warn); }
.detersivo-card--alarm .dc-progress-fill { background: var(--danger); }
.detersivo-card .dc-progress-meta { display: flex; justify-content: space-between; font-size: 12px; }
.detersivo-card .dc-pct { font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }
.detersivo-card--warn .dc-pct { color: var(--warn); }
.detersivo-card--alarm .dc-pct { color: var(--danger); }
.detersivo-card .dc-litri { color: var(--ink-3); }
.detersivo-card .dc-meta-row { display: flex; justify-content: space-between; align-items: center; font-size: 13px; }
.detersivo-card .dc-meta-lbl { color: var(--ink-2); }
.detersivo-card .dc-meta-val { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.detersivo-card .dc-empty-note { font-size: 12px; color: var(--ink-3); font-style: italic; padding-top: 4px; }
.dc-stepper { display: inline-flex; align-items: center; gap: 4px; touch-action: manipulation; }
.dc-stepper .dc-step-btn { width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--line); background: var(--surface); color: var(--ink); font-size: 16px; font-weight: 700; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0; line-height: 1; touch-action: manipulation; -webkit-user-select: none; user-select: none; }
.dc-stepper .dc-step-btn:hover { border-color: var(--brand); color: var(--brand); }
.dc-stepper input { width: 44px; padding: 5px 6px; border: 1px solid var(--line); border-radius: 8px; text-align: center; font-size: 16px; font-weight: 700; font-family: inherit; color: var(--ink); background: var(--surface); font-variant-numeric: tabular-nums; }
.dc-stepper input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
/* Variante modal macchina (minuti asciugatrice): bottoni 36px con glifo 20px ben
   visibile ma non ingombrante, input 16px per non zoomare su iOS al focus. */
.dc-stepper--lg { gap: 6px; }
.dc-stepper--lg .dc-step-btn { width: 40px; height: 40px; font-size: 22px; border-radius: 10px; }
.dc-stepper--lg input { width: 60px; height: 40px; font-size: 16px; }

/* LCS Password: campo type="text" mascherato come password SENZA essere un
   password field (così iOS Safari non propone "usa password sicura"/autofill).
   Fallback plaintext su browser senza -webkit-text-security (raro; il codice
   LCS non è segreto — si imposta fisicamente nell'LCS in lavanderia). */
.lcs-pw { -webkit-text-security: disc; }

/* Prices grid — modal macchina tab Prezzi: 2 gruppi (Cash · Loyalty card) con header brand */
.prices-grid { display: flex; flex-direction: column; gap: 12px; }
.prices-group { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--surface); }
.prices-group-head { padding: 10px 14px; background: var(--brand); color: #fff; font-size: 13px; font-weight: 700; letter-spacing: 0.02em; text-align: center; }
.prices-group-head .prices-group-alias { display: inline-block; font-size: 11px; font-weight: 400; opacity: 0.78; margin-left: 4px; }
/* Slot table macro/sub alias (asciugatrice modal Macchina + Listini bulk) */
.slot-prices-table thead tr.slot-th-group th .macro-alias { display: block; font-size: 10px; font-weight: 400; color: rgba(255,255,255,0.78); text-transform: none; letter-spacing: 0; margin-top: 2px; }
.slot-prices-table thead tr.slot-th-sub th .sub-alias { display: block; font-size: 10px; font-weight: 400; color: var(--ink-3); text-transform: none; letter-spacing: 0; margin-top: 2px; opacity: 0.75; }
.slot-prices-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.prices-group-body { padding: 12px 14px 6px; }
.prices-group-body--3col { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; }
.prices-group-body .field { margin-bottom: 6px; }
.prices-group-body .field label { text-align: center; }
.prices-group-body .field input { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
@media (max-width: 480px) {
  .prices-group-body--3col { grid-template-columns: 1fr; }
}
.dt-field.half { display: flex; }
.dt-field.half .dt-trigger { min-width: 0; width: 100%; }
.field-inline input { flex: 1; }

.radio-group { display: flex; gap: 8px; }
.radio-group label { flex: 1; padding: 10px; background: var(--bg); border: 1px solid var(--line); border-radius: 10px; text-align: center; font-size: 13px; font-weight: 600; cursor: pointer; }
.radio-group input { display: none; }
.radio-group input:checked + label { background: var(--brand); color: #fff; border-color: var(--brand); }
.radio-group label small { display: block; font-size: 11px; font-weight: 500; opacity: 0.75; margin-top: 2px; }

.sheet-actions-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
.sheet-action { padding: 14px 8px; border-radius: 12px; display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; border: 1px solid var(--line); background: var(--surface); color: var(--ink); cursor: pointer; transition: border-color 120ms ease, background 120ms ease, transform 80ms ease; text-decoration: none; }
.sheet-action:hover { border-color: var(--brand); background: var(--brand-soft); }
.sheet-action:active { transform: scale(0.95); }
.sheet-action.brand:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
.sheet-action.go:hover { background: #15803D; border-color: #15803D; }
.sheet-action.warn:hover { background: #B8721A; border-color: #B8721A; }
.sheet-action.stop:hover { background: #B91C1C; border-color: #B91C1C; }
.sheet-action.u-disabled { opacity: 0.45; cursor: not-allowed; }
.sheet-action.u-disabled:hover { border-color: var(--line); background: var(--surface); }
.sheet-action.u-disabled:active { transform: none; }
.sheet-action.go { background: var(--ok); color: #fff; border-color: var(--ok); }
.sheet-action.warn { background: var(--warn); color: #fff; border-color: var(--warn); }
.sheet-action.stop { background: var(--danger); color: #fff; border-color: var(--danger); }
.sheet-action.brand { background: var(--brand); color: #fff; border-color: var(--brand); }

.btn-primary { background: var(--brand); color: #fff; padding: 12px 16px; border-radius: 10px; font-size: 14px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; gap: 6px; cursor: pointer; transition: background 120ms ease, transform 80ms ease; }
.btn-primary:hover { background: var(--brand-hover); }
.btn-primary:active { transform: scale(0.97); }
.btn-secondary { background: var(--bg); color: var(--ink); padding: 12px 16px; border-radius: 10px; font-size: 14px; font-weight: 700; border: 1px solid var(--line); display: inline-flex; align-items: center; justify-content: center; gap: 6px; cursor: pointer; text-decoration: none; transition: background 120ms ease, border-color 120ms ease, transform 80ms ease; }
.btn-secondary:hover { background: var(--surface); border-color: var(--ink-3); }
.btn-secondary:active { transform: scale(0.97); }
.btn-danger { background: var(--danger); color: #fff; padding: 12px 16px; border-radius: 10px; font-size: 14px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; gap: 6px; cursor: pointer; transition: background 120ms ease, transform 80ms ease; }
.btn-danger:hover { background: #B91C1C; }
.btn-danger:active { transform: scale(0.97); }
.btn-danger-ghost { width: 100%; margin-top: 12px; padding: 10px 12px; background: transparent; border: 1px solid #FCA5A5; color: var(--danger); border-radius: 10px; font-size: 13px; font-weight: 700; cursor: pointer; transition: background .12s; }
.btn-danger-ghost:hover { background: #FEE2E2; }

.warn-note { margin-top: 12px; padding: 10px 12px; background: #FFF8DB; border: 1px solid #FCE4A0; border-radius: 10px; font-size: 12px; color: #8B6500; display: flex; gap: 8px; align-items: flex-start; }

/* ===== ANDAMENTO sub-tab ===== */
.chips { padding: 12px 18px 0; display: flex; gap: 6px; overflow-x: auto; flex-shrink: 0; }
.chips::-webkit-scrollbar { display: none; }
.chip { flex-shrink: 0; padding: 7px 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 999px; font-size: 13px; font-weight: 600; color: var(--ink-2); white-space: nowrap; cursor: pointer; transition: border-color 120ms ease, background 120ms ease; }
.chip:hover:not(.active):not(.chip-on) { border-color: var(--brand); color: var(--ink); }
.chip:active { transform: scale(0.96); }
.chip.active,
.chip.chip-on { background: var(--ink); color: #fff; border-color: var(--ink); }
/* Count come badge staccato dal nome (prima era testo inline → "sembrava parte del nome"). */
.chip .chip-count { display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px; background: var(--bg); color: var(--ink-2); font-size: 11px; font-weight: 700; line-height: 1.5; vertical-align: baseline; }
.chip:not(.chip-on):not(.active):hover .chip-count { background: var(--brand-soft); color: var(--brand); }
.chip.active .chip-count,
.chip.chip-on .chip-count { background: rgba(255, 255, 255, 0.24); color: #fff; }
/* Punto 8 — popover "Altri filtri": summary = chip, panel assoluto coi filtri secondari. */
.chip-more { position: relative; flex-shrink: 0; }
/* NON impostare display:flex/inline-flex sul <summary>: rompe il toggle nativo del
   <details> su Safari/iOS. Il layout (testo+chevron) va su un wrapper interno. */
.chip-more > summary { list-style: none; cursor: pointer; }
.chip-more > summary::-webkit-details-marker { display: none; }
.chip-more > summary::marker { content: ""; }
.chip-more-inner { display: inline-flex; align-items: center; gap: 4px; }
/* iOS: il tap deve colpire il <summary>, non i suoi figli (toggle JS in app.js). */
.chip-more-inner, .chip-more-inner * { pointer-events: none; }
.chip-more .chip-more-chev { transition: transform 120ms ease; }
.chip-more[open] .chip-more-chev { transform: rotate(180deg); }
.chip-more-panel { position: absolute; top: calc(100% + 6px); right: 0; z-index: 40; display: flex; flex-direction: column; gap: 6px; padding: 10px; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-card); min-width: 190px; }
.chip-more-panel .chip { display: flex; align-items: center; justify-content: space-between; width: 100%; }
.period-info { padding: 6px 18px 0; font-size: 11px; color: var(--ink-3); font-family: ui-monospace, monospace; }

.sub-chips { padding: 12px 18px 0; display: flex; gap: 6px; overflow-x: auto; flex-shrink: 0; }
.sub-chips::-webkit-scrollbar { display: none; }
.sub-chip { flex-shrink: 0; padding: 6px 12px; background: var(--surface); border-radius: 8px; font-size: 12px; font-weight: 600; color: var(--ink-2); border: 1px solid var(--line); white-space: nowrap; cursor: pointer; transition: border-color 120ms ease, background 120ms ease; }
.sub-chip:hover:not(.active) { border-color: var(--brand); color: var(--ink); }
.sub-chip:active { transform: scale(0.96); }
.sub-chip.active { background: var(--brand-soft); color: var(--brand); border-color: var(--brand-soft); }

.kpi-banner { margin: 14px 18px 0; background: linear-gradient(135deg, var(--brand) 0%, var(--brand-dark) 100%); color: #fff; border-radius: 14px; padding: 16px 18px; box-shadow: 0 6px 16px rgba(140,0,20,0.25); }
.kpi-banner .label { font-size: 12px; opacity: 0.92; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.kpi-banner .big { font-size: 34px; font-weight: 800; margin: 4px 0 2px; letter-spacing: -0.02em; }
.kpi-banner .delta { font-size: 13px; opacity: 0.92; display: inline-flex; align-items: center; gap: 4px; }
.bars { display: flex; gap: 4px; align-items: flex-end; margin-top: 12px; height: 60px; }
.bar { flex: 1; background: rgba(255,255,255,0.3); border-radius: 3px 3px 0 0; }
.bar.peak { background: rgba(255,255,255,0.95); }

/* KPI banner · daily bars chart with tooltip */
.kpi-chart { margin-top: 14px; position: relative; }
.kpi-chart .chart-head { display: flex; justify-content: space-between; align-items: baseline; font-size: 11px; opacity: 0.85; margin-bottom: 6px; font-weight: 500; }
.kpi-chart .chart-head .chart-axis-label { font-variant-numeric: tabular-nums; }
.kpi-chart .chart-avg { font-size: 11px; opacity: 0.85; display: inline-flex; align-items: center; gap: 4px; }
.kpi-chart .chart-avg::before { content: ''; display: inline-block; width: 14px; height: 0; border-top: 1.5px dashed rgba(255,255,255,0.5); }

.bars-grid { display: grid; grid-template-columns: repeat(30, 1fr); gap: 2px; align-items: flex-end; height: 64px; position: relative; }
.bars-grid::before { content: ''; position: absolute; left: 0; right: 0; border-top: 1px dashed rgba(255,255,255,0.35); pointer-events: none; }
.bars-grid:has(.bars-empty)::before { display: none; }
.bars-empty { grid-column: 1 / -1; display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 64px; color: rgba(255,255,255,0.82); font-size: 13px; font-weight: 600; letter-spacing: 0.01em; padding: 8px 14px; }
.bars-empty .i { width: 20px; height: 20px; opacity: 0.78; flex-shrink: 0; }
.day-bar { padding: 0; border: none; background: rgba(255,255,255,0.42); border-radius: 2px; cursor: pointer; position: relative; min-height: 4px; transition: background 0.12s, transform 0.12s; align-self: flex-end; }
.day-bar:hover, .day-bar.pinned { background: #fff; transform: scaleY(1.04); transform-origin: bottom; }
.day-bar.peak { background: rgba(255,255,255,0.85); }
.day-bar.peak:hover, .day-bar.peak.pinned { background: #fff; }
.day-bar.today { box-shadow: inset 0 -2px 0 0 #FFD700; background: rgba(255,255,255,0.55); }
.day-bar.today:hover, .day-bar.today.pinned { background: #fff; }
.day-bar.holiday { background: rgba(255,255,255,0.22); }

.bar-tip { position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%); background: rgba(15,20,25,0.96); color: #fff; padding: 8px 10px; border-radius: 8px; white-space: nowrap; opacity: 0; pointer-events: none; z-index: 20; transition: opacity 0.12s; box-shadow: 0 8px 24px rgba(0,0,0,0.3); }
.bar-tip::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: rgba(15,20,25,0.96); }
.bar-tip strong { display: block; font-size: 14px; font-weight: 800; font-variant-numeric: tabular-nums; }
.bar-tip small { display: block; font-size: 10px; opacity: 0.75; font-weight: 500; text-transform: capitalize; margin-top: 1px; }
.day-bar:hover .bar-tip, .day-bar.pinned .bar-tip { opacity: 1; }
.day-bar:focus { outline: 2px solid rgba(255,255,255,0.6); outline-offset: 1px; }
.day-bar:focus:not(:focus-visible) { outline: none; }

.bars-axis { display: flex; justify-content: space-between; font-size: 10px; opacity: 0.7; font-weight: 500; margin-top: 6px; padding: 0 2px; font-variant-numeric: tabular-nums; }

.bars-legend { display: flex; align-items: center; gap: 14px; font-size: 11px; opacity: 0.9; margin-top: 10px; flex-wrap: wrap; }
.bars-legend .lg-item { display: inline-flex; align-items: center; gap: 5px; }
.bars-legend .lg-swatch { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
.bars-legend .lg-swatch.peak { background: rgba(255,255,255,0.85); }
.bars-legend .lg-swatch.today { background: rgba(255,255,255,0.55); box-shadow: inset 0 -2px 0 0 #FFD700; }
.bars-legend .lg-swatch.normal { background: rgba(255,255,255,0.42); }

@media (max-width: 720px) {
  .bars-legend { gap: 8px; font-size: 10px; }
  .bar-tip { white-space: normal; max-width: 160px; }
}

.metric-rows { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 10px 18px 0; overflow: hidden; }
.metric-row { padding: 14px 16px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--line); gap: 10px; }
.metric-row:last-child { border-bottom: none; }
.metric-row .lbl { font-size: 14px; color: var(--ink-2); display: inline-flex; align-items: center; gap: 8px; min-width: 0; flex: 1 1 auto; flex-wrap: wrap; overflow-wrap: anywhere; }
.metric-row .val { font-size: 15px; font-weight: 700; }
/* Il controllo/valore a destra non si schiaccia quando la label (es. email lunga) cresce. */
.metric-row > .val,
.metric-row > .toggle-ios { flex-shrink: 0; }

.list-row { padding: 14px 16px; display: flex; align-items: center; gap: 14px; background: var(--surface); border-bottom: 1px solid var(--line); cursor: pointer; transition: background 120ms ease; }
.list-row:hover { background: var(--bg); }
.list-row:active { background: var(--line); }
.list-row:last-child { border-bottom: none; }
.list-row .ico { width: 36px; height: 36px; border-radius: 10px; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.list-row .body { flex: 1; }
.list-row .ttl { font-size: 14px; font-weight: 600; }
.list-row .sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.list-row .chevron { color: var(--ink-3); }

/* Clienti · Gruppi (sub-tab "Groups"). Stesso pattern di .list-row ma su <a>. */
/* Lista gruppi: niente riquadro bianco esterno (richiesta Andrea) — stesso pattern
   della Lista: eyebrow .section-title + righe .cat-card direttamente sul grigio
   (entrambi hanno già il gutter orizzontale page-pad-x). */
[data-cat-list] { margin: 0; }
.cat-row { padding: 14px 16px; display: flex; align-items: center; gap: 14px; background: var(--surface); border-bottom: 1px solid var(--line); cursor: pointer; color: inherit; text-decoration: none; transition: background 120ms ease; }
.cat-row:hover { background: var(--bg); text-decoration: none; }
.cat-row:active { background: var(--line); }
.cat-row:last-child { border-bottom: none; }
.cat-row-icon { width: 36px; height: 36px; border-radius: 10px; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.cat-row-body { flex: 1; min-width: 0; }
.cat-row-name { font-size: 15px; font-weight: 600; color: var(--ink); }
.cat-row-sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }

.list-group { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 10px 18px 0; overflow: hidden; }
.list-group .list-row:last-child { border-bottom: none; }

.pill { font-size: 11px; padding: 3px 8px; border-radius: 999px; font-weight: 700; display: inline-flex; align-items: center; gap: 4px; }
.pill.ok { background: #E8F8EE; color: var(--ok); }
.pill.warn { background: #FFF3E0; color: var(--warn); }
.pill.danger { background: #FCE4E4; color: var(--danger); }

/* Riga cliente = griglia "tabella". Mobile: card (nome a sx; saldo sopra, email+push+visita
   sotto a dx). Desktop (≥800px): 7 colonne allineate all'header .cust-table-head. */
.cust-card { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 10px var(--page-pad-x) 0; padding: 14px; display: grid; grid-template-columns: 44px 1fr auto; grid-template-areas: "av name balance" "av details details"; column-gap: 12px; row-gap: 2px; align-items: center; cursor: pointer; }
/* Avatar: colonna propria che copre entrambe le righe → centrato verticalmente
   sull'intera card (come prima dell'estrazione dal blocco nome). */
.cust-cell-av { grid-area: av; display: flex; align-items: center; justify-content: center; }
.cust-cell-name { grid-area: name; display: flex; align-items: center; gap: 12px; min-width: 0; }
/* Mobile: la riga dettagli occupa la larghezza delle colonne nome+saldo (span, sotto
   l'avatar) → non riserva spazio accanto al nome, così nome+badge sulla riga 1
   arrivano fino al saldo. Il codice (meta-mobile) sta a sinistra sotto il nome,
   icone/Tipo/data a destra. Su desktop il wrapper diventa display:contents
   (vedi ≥800px) e le celle tornano colonne della tabella. */
.cust-cell-details { grid-area: details; display: flex; align-items: center; gap: 12px; min-width: 0; }
.cust-cell-details .meta-mobile { margin: 0 auto 0 0; }
.meta-desktop { display: none; }
.cust-cell-email { grid-area: email; justify-self: end; display: inline-flex; align-items: center; }
.cust-cell-push { grid-area: push; justify-self: end; display: inline-flex; align-items: center; }
.cust-cell-sconto { grid-area: sconto; justify-self: end; display: inline-flex; align-items: center; }
.cust-cell-tipo { grid-area: tipo; justify-self: end; font-size: 12px; color: var(--ink-3); white-space: nowrap; }
.cust-cell-visit { grid-area: visit; justify-self: end; font-size: 12px; color: var(--ink-3); white-space: nowrap; }
.cust-email { width: 18px; height: 18px; }
.cust-email.is-on { color: var(--brand); }
.cust-email.is-off { color: var(--line); }
.cust-push { width: 18px; height: 18px; }
.cust-push.is-on { color: var(--brand); }
.cust-push.is-off { color: var(--line); }
.cust-sconto { width: 18px; height: 18px; }
.cust-sconto.is-on { color: var(--brand); }
.cust-sconto.is-off { color: var(--line); }
.cust-table-head { display: none; }
.cth-sort { cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; gap: 3px; color: inherit; }
.cth-sort:hover { color: var(--brand); }
.cth-arrow { width: 12px; height: 12px; opacity: 0; transition: transform .12s ease; }
/* Idle (colonna ordinabile ma non ordinata): freccia ↕ sempre visibile, tenue,
   così è ovvio che si può ordinare. La colonna ordinata mostra ▲/▼ pieno. */
.cth-arrow-idle { opacity: .4; }
.cth-sort:hover .cth-arrow-idle { opacity: .7; }
.cth-sort.is-sorted { color: var(--ink); }
.cth-sort.is-sorted .cth-arrow { opacity: 1; }
.cth-sort.dir-asc .cth-arrow { transform: rotate(180deg); }
/* La tabella a 8 colonne (avatar + 7) richiede spazio: sotto 800px si resta sul
   layout a card (nome pieno), che regge fino a ~640px e oltre. Fra 641 e 799 la
   tabella schiacciava la colonna Cliente e il codice card andava a capo verticale. */
@media (min-width: 800px) {
  .cust-card { grid-template-columns: 44px 1fr 56px 56px 56px 64px 116px 124px; grid-template-areas: "av name email push sconto tipo balance visit"; row-gap: 0; column-gap: 8px; }
  /* Il wrapper mobile si dissolve: le celle tornano grid-item diretti e riprendono
     le loro grid-area (email/push/sconto/tipo/visit), allineate all'header. Il codice
     torna sotto il nome (meta-desktop); la copia mobile sparisce. */
  .cust-cell-details { display: contents; }
  .meta-desktop { display: block; }
  .meta-mobile { display: none; }
  .cust-cell-email { justify-self: center; }
  .cust-cell-push { justify-self: center; }
  .cust-cell-sconto { justify-self: center; }
  /* "Tipo N" = codice corto a lunghezza fissa → centrato (skill table-alignment),
     coerente con le colonne icona adiacenti. */
  .cust-cell-tipo { font-size: 13px; justify-self: center; }
  /* Ultima visita = etichette testuali ("oggi", "5 mag"), non numeri → allineate a
     sinistra (header + valore), coerente con la skill table-alignment. Saldo (valuta)
     resta a destra per il confronto delle grandezze. */
  .cust-cell-visit { font-size: 13px; justify-self: start; }
  .cust-table-head { display: grid; grid-template-columns: 44px 1fr 56px 56px 56px 64px 116px 124px; align-items: center; column-gap: 8px; padding: 6px 14px 2px; margin: 8px var(--page-pad-x) 0; }
  /* L'intestazione "Cliente" copre le due prime colonne del body (avatar + nome). */
  .cust-table-head .cth-nome { grid-column: 1 / 3; }
  .cust-table-head .cth { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-3); }
  .cust-table-head .cth-email { justify-self: center; }
  .cust-table-head .cth-push { justify-self: center; }
  .cust-table-head .cth-sconto { justify-self: center; }
  .cust-table-head .cth-tipo { justify-self: center; }
  .cust-table-head .cth-saldo { justify-self: end; }
  .cust-table-head .cth-ultima_visita { justify-self: start; }
}
.cust-card .av { width: 44px; height: 44px; border-radius: 50%; background: linear-gradient(135deg, #FFD3DC, #FFAFC0); color: var(--brand-dark); display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 15px; flex-shrink: 0; }
.cust-card .info { flex: 1; min-width: 0; }
.cust-card .name { font-size: 14px; font-weight: 700; display: flex; align-items: center; gap: 6px; min-width: 0; }
.cust-card .name .name-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cust-card .name .badge { flex-shrink: 0; }
.badge { font-size: 10px; padding: 2px 8px; border-radius: 999px; font-weight: 700; }
.badge.vip { background: #FFEEDB; color: #B45309; }
.badge.bb { background: #DCEAFE; color: #1E40AF; }
.badge.dormant { background: #F3F4F6; color: #6B7280; }
.cust-card .meta { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.cust-cell-balance { grid-area: balance; justify-self: end; font-size: 14px; font-weight: 800; color: var(--brand); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Card membro nel dettaglio Gruppo (renderCategoryMembers, app.js): NON è la riga
   della tabella Lista (no colonne push/visita) → layout flex semplice
   [check][avatar][nome+card][saldo], non la griglia di .cust-card. Riusa gli stili
   figli (.check/.av/.info/.name/.meta), sovrascrive solo il display. */
.cust-card.cust-card--member { display: flex; align-items: center; gap: 12px; }
.cust-card--member .info { flex: 1 1 auto; min-width: 0; }
.cust-card--member .balance { flex-shrink: 0; font-size: 14px; font-weight: 800; color: var(--brand); white-space: nowrap; font-variant-numeric: tabular-nums; }

.composer-channels { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; margin-bottom: 14px; }
.composer-channels input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.composer-channels label { position: relative; padding: 16px 12px; background: var(--surface); border: 2px solid var(--line); border-radius: 12px; text-align: center; font-size: 13px; font-weight: 700; color: var(--ink-3); cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 6px; transition: border-color 120ms ease, background 120ms ease, color 120ms ease; }
.composer-channels label:hover { border-color: var(--brand); color: var(--brand); }
.composer-channels label:active { transform: scale(0.97); }
.composer-channels input:checked + label { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); }
.composer-channels input:focus-visible + label { outline: 2px solid var(--brand); outline-offset: 2px; }
.composer-channels .ch-check { position: absolute; top: 8px; right: 8px; width: 18px; height: 18px; border-radius: 999px; background: var(--brand); color: #fff; display: none; align-items: center; justify-content: center; }
.composer-channels .ch-check .i { width: 12px; height: 12px; stroke-width: 2.6; }
.composer-channels input:checked + label .ch-check { display: inline-flex; }
.segment-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.segment-tag { padding: 6px 12px; background: var(--bg); border: 1px solid var(--line); border-radius: 999px; font-size: 12px; font-weight: 600; color: var(--ink-2); display: inline-flex; align-items: center; gap: 4px; }
.segment-tag.active { background: var(--brand); color: #fff; border-color: var(--brand); }

.concept-note { margin: 30px 18px 24px; font-size: 11px; color: var(--ink-3); text-align: center; line-height: 1.5; }
.and-pane { display: none; }
.and-pane.active { display: block; }
.dt-and-pane { display: none; }
.dt-and-pane.active { display: block; }

/* ===== DESKTOP ===== */
.dt-stage { width: 100%; max-width: 1340px; margin: 24px auto 60px; padding: 0 24px; }
.dt-frame { background: #1a1a1a; border-radius: 14px 14px 18px 18px; padding: 8px 8px 10px; box-shadow: 0 30px 80px rgba(15,20,25,0.22); }
.dt-titlebar { display: flex; align-items: center; gap: 8px; padding: 4px 6px 8px; }
.dt-titlebar .dot { width: 12px; height: 12px; border-radius: 50%; }
.dt-titlebar .dot.r { background: #FF5F57; } .dt-titlebar .dot.y { background: #FEBC2E; } .dt-titlebar .dot.g { background: #28C840; }
.dt-titlebar .url { background: #2a2a2a; color: #aaa; font-size: 12px; padding: 4px 14px; border-radius: 6px; margin-left: 16px; font-family: ui-monospace, monospace; }
.dt-app { background: var(--bg); border-radius: 8px; display: grid; grid-template-columns: 240px 1fr; min-height: 800px; overflow: hidden; }
.dt-sidebar { background: var(--surface); border-right: 1px solid var(--line); padding: 20px 14px; display: flex; flex-direction: column; }
.dt-brand { display: flex; align-items: center; gap: 10px; padding: 4px 10px 18px; border-bottom: 1px solid var(--line); margin-bottom: 14px; }
.dt-brand .logo { width: 36px; height: 36px; background: var(--brand); color: #fff; border-radius: 9px; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 16px; }
.dt-brand .text { display: flex; flex-direction: column; }
.dt-brand .name { font-size: 14px; font-weight: 800; line-height: 1.1; }
.dt-brand .store { font-size: 11px; color: var(--ink-3); }
.dt-nav { display: flex; flex-direction: column; gap: 2px; }
.dt-nav button { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 10px; font-size: 14px; font-weight: 600; color: var(--ink-2); text-align: left; width: 100%; }
.dt-nav button:hover { background: var(--bg); }
.dt-nav button.active { background: var(--brand-soft); color: var(--brand); }
.dt-nav button .badge-n { margin-left: auto; background: var(--danger); color: #fff; font-size: 10px; padding: 2px 7px; border-radius: 999px; font-weight: 700; }
.dt-user { margin-top: auto; padding: 12px 14px; display: flex; align-items: center; gap: 10px; border-top: 1px solid var(--line); margin-left: -14px; margin-right: -14px; margin-bottom: -20px; }
.dt-user .av { width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(135deg,#FFD3DC,#FFAFC0); display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--brand-dark); font-size: 13px; }
.dt-user .text .name { font-size: 13px; font-weight: 700; }
.dt-user .text .role { font-size: 11px; color: var(--ink-3); }

.dt-main { display: flex; flex-direction: column; overflow: hidden; }
.dt-topbar { background: var(--surface); border-bottom: 1px solid var(--line); padding: 14px 28px; display: flex; align-items: center; gap: 18px; }
.dt-topbar h1 { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; }
.dt-topbar .subdate { font-size: 13px; color: var(--ink-3); }
.dt-topbar .search { margin-left: auto; width: 280px; padding: 9px 14px; border-radius: 10px; border: 1px solid var(--line); background: var(--bg); font-size: 13px; }
.dt-topbar .ico-btn { width: 38px; height: 38px; border-radius: 10px; background: var(--bg); display: flex; align-items: center; justify-content: center; position: relative; color: var(--ink-2); }
.dt-topbar .ico-btn .badge { position: absolute; top: 6px; right: 6px; background: var(--danger); color: #fff; font-size: 10px; min-width: 16px; height: 16px; border-radius: 8px; display: flex; align-items: center; justify-content: center; padding: 0 4px; }
.dt-body { padding: 22px 28px 28px; overflow-y: auto; }
.dt-view { display: none; }
.dt-view.active { display: block; }

/* Desktop common pieces */
.dt-kpi-row { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 14px; margin-bottom: 18px; }
.dt-kpi-hero { background: linear-gradient(135deg, var(--brand) 0%, var(--brand-dark) 100%); color: #fff; border-radius: var(--radius); padding: 18px 20px; display: flex; flex-direction: column; gap: 4px; box-shadow: 0 8px 20px rgba(140,0,20,0.22); }
.dt-kpi-hero .l { font-size: 12px; opacity: 0.9; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.dt-kpi-hero .v { font-size: 36px; font-weight: 800; letter-spacing: -0.02em; line-height: 1; margin-top: 2px; }
.dt-kpi-hero .d { font-size: 13px; opacity: 0.95; margin-top: 4px; display: inline-flex; align-items: center; gap: 4px; }
.dt-kpi-card { background: var(--surface); border-radius: var(--radius); padding: 14px 16px; box-shadow: var(--shadow-card); display: flex; flex-direction: column; gap: 4px; }
.dt-kpi-card .l { font-size: 11px; color: var(--ink-3); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
.dt-kpi-card .v { font-size: 24px; font-weight: 800; letter-spacing: -0.01em; }
.dt-kpi-card .d { font-size: 12px; color: var(--ok); font-weight: 600; }
.dt-kpi-card .d.danger { color: var(--danger); }

.dt-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 18px; }
.dt-card { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow-card); overflow: hidden; }
.dt-card-head { padding: 16px 20px; display: flex; align-items: center; justify-content: space-between; gap: 8px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.dt-card-head h3 { font-size: 15px; font-weight: 700; }
.dt-card-head .actions { display: flex; gap: 6px; flex-wrap: wrap; }
.dt-card-body { padding: 8px 0; }

.pill-btn { font-size: 12px; padding: 6px 12px; border-radius: 999px; background: var(--bg); color: var(--ink-2); font-weight: 600; display: inline-flex; align-items: center; gap: 4px; border: none; cursor: pointer; }
.pill-btn:hover { background: var(--line); }
.pill-btn.active { background: var(--ink); color: #fff; }
.pill-btn.brand { background: var(--brand); color: #fff; }
.pill-btn.brand:hover { background: var(--brand-hover); }
a.pill-btn { text-decoration: none; }

.setting-row { display: flex; align-items: center; gap: 14px; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.setting-row .ico { width: 36px; height: 36px; border-radius: 10px; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.setting-row .body { flex: 1; }
.setting-row .ttl { font-size: 14px; font-weight: 600; }
.setting-row .sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }

.dt-table { width: 100%; border-collapse: collapse; }
.dt-table thead th { text-align: left; padding: 10px 14px; font-size: 11px; color: var(--ink-3); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; border-bottom: 1px solid var(--line); white-space: nowrap; }
.dt-table tbody td { padding: 12px 14px; font-size: 13px; border-bottom: 1px solid var(--line); vertical-align: middle; white-space: nowrap; }
.dt-table tbody tr:hover { background: var(--bg); cursor: pointer; }
.dt-table tbody tr:last-child td { border-bottom: none; }
.dt-table td.num, .dt-table th.num, .dt-table .num { text-align: right !important; font-variant-numeric: tabular-nums; }
.dt-table th.th-group { text-align: center !important; color: var(--brand); border-bottom: 1px solid var(--line); }
.dt-table .av { width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(135deg,#FFD3DC,#FFAFC0); color: var(--brand-dark); display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 12px; margin-right: 10px; vertical-align: middle; }
.dt-table .codecell { font-family: ui-monospace, monospace; color: var(--ink-3); font-size: 11.5px; }
/* Riga filtri nel thead (.dt-filter-row): select/input compatti sotto i th.
   Niente uppercase/letter-spacing ereditati dai th: sono controlli, non label.
   Sfondo --bg: la riga si legge come fascia-strumenti, staccata dalle label. */
.dt-table .dt-filter-row th { padding: 10px 14px 12px; background: var(--bg); text-transform: none; letter-spacing: normal; font-weight: 400; border-bottom: 1px solid var(--line); }
.dt-filter-select, .dt-filter-input { width: 100%; min-width: 90px; max-width: 200px; height: 32px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; background-color: var(--surface); color: var(--ink-2); font-size: 12.5px; font-family: inherit; transition: border-color 120ms ease, box-shadow 120ms ease; }
/* Chevron custom (colore = --ink-3): quello nativo sta incollato al bordo. */
.dt-filter-select { cursor: pointer; appearance: none; -webkit-appearance: none; padding-right: 30px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238A93A4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; background-size: 14px; }
.dt-filter-select:hover, .dt-filter-input:hover { border-color: var(--ink-3); }
.dt-filter-select:focus, .dt-filter-input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
/* iOS zooma la viewport al focus di campi con font < 16px: su touch i
   controlli salgono a 16px (stessa ragione del 16px sulla .search-bar). */
@media (hover: none) and (pointer: coarse) {
  .dt-filter-select, .dt-filter-input { font-size: 16px; height: 38px; }
}
.dt-filter-input::placeholder { color: var(--ink-3); }
/* Nei Movimenti il bottone vive a fianco della search (stessa altezza/radius
   del campo: il pill 6px accanto a un input da 40px sembrava un refuso). */
.search-bar .dt-filter-btn { flex-shrink: 0; align-self: stretch; padding: 0 14px; font-size: 13px; border: 1px solid var(--line); background: var(--surface); border-radius: 10px; }
/* Bottone "Filtri" a fianco (card head / section-title): la riga filtri parte
   hidden e si apre al click (dtFilterToggle). Stati: aperto (aria-expanded)
   e filtri server-side attivi (is-filtering, evidenziato anche a riga chiusa). */
.dt-filter-btn[aria-expanded="true"], .dt-filter-btn.is-filtering { background: var(--brand-soft); color: var(--brand); }
.section-title .pill-btn { text-transform: none; letter-spacing: normal; }
/* Barra compatta porta-bottone per tabelle senza card-head (storico fidelity) */
.dt-filter-bar { display: flex; justify-content: flex-end; padding: 10px 14px 0; }
/* F8 · variante compatta tabelle eco per stare in viewport mobile senza scroll-x. */
.dt-table--compact thead th { padding: 6px 8px; font-size: 10px; white-space: normal; line-height: 1.25; }
.dt-table--compact tbody td { padding: 6px 8px; font-size: 11px; white-space: normal; line-height: 1.3; }

/* === Menu di colonna type-aware (Movimenti, direzione 2) ================
   Ogni header e' un bottone che apre un popover (Ordina up/down + filtro per
   tipo). Freccia di sort sempre visibile: idle (#i-sort) / ordinata
   (#i-chevron-down, ruotata per asc). Popover fixed via JS (fuori dal
   table-wrap che ha overflow-x:auto, design-system §14). */
.dt-table thead th.mov-th { padding: 0; }
.mov-th-btn { display: inline-flex; align-items: center; gap: 5px; width: 100%; padding: 11px 14px; background: none; border: 0; font: inherit; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-3); cursor: pointer; text-align: left; }
.mov-th.num .mov-th-btn { justify-content: flex-end; }
.mov-th-btn:hover { color: var(--ink); }
.mov-th-label { white-space: nowrap; }
.mov-th-arrow { width: 12px; height: 12px; flex-shrink: 0; opacity: .4; transition: transform .12s ease; }
.mov-th-arrow-idle { opacity: .35; }
.mov-th-btn:hover .mov-th-arrow { opacity: .7; }
.mov-th.is-sorted .mov-th-btn { color: var(--ink); }
.mov-th.is-sorted .mov-th-arrow { opacity: 1; }
.mov-th.is-sorted.dir-asc .mov-th-arrow { transform: rotate(180deg); }
.mov-th-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--brand); flex-shrink: 0; }

.colmenu-pop { position: fixed; z-index: 60; min-width: 200px; max-width: 280px; max-height: 70vh; overflow-y: auto; display: flex; flex-direction: column; padding: 6px; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-card); }
/* display:flex (author) batterebbe [hidden]{display:none} (UA): lo stato nascosto
   deve vincere, altrimenti tutti i popover restano visibili al load. */
.colmenu-pop[hidden] { display: none; }
.colmenu-sort { display: flex; flex-direction: column; gap: 2px; }
.colmenu-sort-row { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 8px; font-size: 13px; font-weight: 600; color: var(--ink-2); text-decoration: none; }
.colmenu-sort-row .i { width: 14px; height: 14px; color: var(--ink-3); flex-shrink: 0; }
.colmenu-sort-row:hover { background: var(--bg); color: var(--ink); }
.colmenu-sort-row.is-active { background: var(--brand-soft); color: var(--brand); }
.colmenu-sort-row.is-active .i { color: var(--brand); }
.colmenu-arr-down { transform: rotate(180deg); }
.colmenu-filter { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; padding-top: 8px; border-top: 1px solid var(--line); }
.colmenu-search, .colmenu-contains { width: 100%; height: 34px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; background-color: var(--surface); color: var(--ink); font-size: 13px; font-family: inherit; }
.colmenu-search:focus, .colmenu-contains:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.colmenu-list { display: flex; flex-direction: column; gap: 1px; max-height: 220px; overflow-y: auto; }
.colmenu-opt { display: flex; align-items: center; gap: 9px; padding: 7px 8px; border-radius: 8px; font-size: 13px; font-weight: 500; color: var(--ink-2); cursor: pointer; }
.colmenu-opt:hover { background: var(--bg); color: var(--ink); }
.colmenu-opt input { width: 16px; height: 16px; flex-shrink: 0; accent-color: var(--brand); cursor: pointer; }
.colmenu-opt-lbl { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.colmenu-empty { margin: 0; padding: 8px; font-size: 13px; color: var(--ink-3); }
.colmenu-range { display: flex; gap: 8px; }
.colmenu-range-fld { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; font-size: 11px; font-weight: 600; color: var(--ink-3); text-transform: uppercase; letter-spacing: .03em; }
.colmenu-range-fld input { width: 100%; height: 34px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; background-color: var(--surface); color: var(--ink); font-size: 13px; font-family: inherit; }
.colmenu-range-fld input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.colmenu-apply { height: 36px; border: 0; border-radius: 8px; background: var(--ink); color: #fff; font-size: 13px; font-weight: 700; font-family: inherit; cursor: pointer; }
.colmenu-apply:hover { background: var(--brand); }
/* iOS zooma al focus se il font < 16px: su touch i campi salgono a 16px. */
@media (hover: none) {
  .colmenu-search, .colmenu-contains, .colmenu-range-fld input { font-size: 16px; }
}
.dt-table--compact tbody td:first-child { word-break: break-word; }
/* Override .mov-table-wrap min-width:760px (pensato per tabelle larghe).
   Doppia classe .dt-table.dt-table--compact = specificity (0,0,3,0) per
   battere `.mov-table-wrap .dt-table` (0,0,2,0) che viene definito DOPO
   nel file e altrimenti vincerebbe per ordine cascade. */
.mov-table-wrap .dt-table.dt-table--compact { min-width: 0; table-layout: fixed; width: 100%; }
.dt-table.dt-table--compact thead th:first-child,
.dt-table.dt-table--compact tbody td:first-child { width: 38%; }
.dt-table--compact tbody td strong { font-size: 12px; }

.action-btn { width: 32px; height: 32px; border-radius: 8px; background: var(--bg); color: var(--ink-2); display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--line); cursor: pointer; }
.action-btn:hover { background: var(--line); }

/* MACCHINE desktop — info-first, gear icon per gestione */
.dt-machines-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 16px; }
.dt-mc { background: var(--surface); border-radius: 16px; padding: 18px; box-shadow: var(--shadow-card); position: relative; }
.dt-mc.alert { border: 1.5px solid #FCD3D3; background: #FFFBFB; }
.dt-mc .gear-btn { position: absolute; top: 16px; right: 16px; width: 36px; height: 36px; border-radius: 10px; background: var(--bg); color: var(--ink-2); display: flex; align-items: center; justify-content: center; cursor: pointer; }
.dt-mc .gear-btn:hover { background: var(--line); }
.dt-mc .head { display: flex; gap: 14px; align-items: center; padding-right: 44px; }
.dt-mc .id-circle { width: 56px; height: 56px; border-radius: 18px; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; position: relative; }
.dt-mc.alert .id-circle { background: #FCE4E4; color: var(--danger); }
.dt-mc .id-circle .id-letter { position: absolute; bottom: -4px; right: -4px; background: var(--ink); color: #fff; font-weight: 800; font-size: 13px; width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--surface); display: flex; align-items: center; justify-content: center; }
.dt-mc .name { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
.dt-mc .prices { font-size: 13px; color: var(--ink-3); margin-top: 2px; }
.dt-mc .status-row { margin-top: 14px; display: flex; align-items: center; gap: 10px; }
.dt-mc .progress-bar { flex: 1; height: 8px; background: var(--bg); border-radius: 4px; overflow: hidden; }
.dt-mc .progress-bar > div { height: 100%; }
.dt-mc .progress-bar.busy > div { background: var(--warn); }
.dt-mc .progress-bar.broken > div { background: var(--danger); }
.dt-mc .progress-bar.free > div { background: var(--ok); }
.dt-mc .details { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); display: flex; justify-content: space-between; font-size: 12px; color: var(--ink-3); }
.dt-mc .details strong { color: var(--ink-2); font-weight: 600; }
.dt-mc .alert-cta { margin-top: 12px; }
.dt-mc .alert-cta button { width: 100%; padding: 11px; border-radius: 10px; background: var(--danger); color: #fff; font-size: 13px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; gap: 8px; }

/* DOMOTICA desktop */
.dt-dom { display: grid; grid-template-columns: 2fr 1fr; gap: 18px; }

@media (max-width: 1100px) {
  .dt-app { grid-template-columns: 80px 1fr; }
  .dt-nav button span:not(.badge-n) { display: none; }
  .dt-brand .text, .dt-user .text { display: none; }
  .dt-dom { grid-template-columns: 1fr; }
}

/* Global modals (impostazioni) */
.gmodal { position: fixed; inset: 0; background: rgba(15,20,25,0.5); display: none; align-items: center; justify-content: center; z-index: 200; padding: 20px; }
.gmodal.open { display: flex; }
/* NB (2026-06-23): tentativo di convertire i .gmodal a bottom-sheet su mobile (.gm-sheet)
   REVERTATO — riapre il glitch iOS Safari del fix gm-card-wide. I .gmodal restano
   full-screen page-like su mobile (sicuro), con la .gm-close (X) sempre presente.
   Il bottom-sheet vero si usa solo per i modali su pattern .sheet (es. menu "+"). */
/* .sheet-fs: porta un .sheet (bottom-sheet) a FULL-SCREEN page-like su MOBILE (sicuro iOS,
   stesso principio dei .gm-card-wide). Per i .sheet che in bottom-sheet si rompono su iOS
   (es. "Comunica"/Contatta cliente). Desktop invariato (centrato). La X (.sheet-close) resta. */
@media (max-width: 760px), (max-height: 540px) {
  .modal-backdrop.sheet-fs { align-items: stretch; padding: 0; }
  .modal-backdrop.sheet-fs > .sheet { width: 100%; max-width: none; max-height: none; min-height: 100vh; min-height: 100dvh; border-radius: 0; animation: none; padding: 18px 16px max(14px, env(safe-area-inset-bottom)); }
  .modal-backdrop.sheet-fs > .sheet .sheet-handle { display: none; }
}
.gmodal .gm-card { background: var(--surface); border-radius: 16px; max-width: 600px; width: 100%; max-height: 90vh; overflow-y: auto; padding: 28px; box-shadow: 0 30px 80px rgba(15,20,25,0.3); }
/* Mobile: padding-bottom extra dentro la card per non far finire i bottoni
   "Salva/Annulla" sotto la Safari bottom-bar (iOS) quando si scrolla in fondo. */
@media (max-width: 600px) { .gmodal .gm-card { padding-bottom: 64px; } }

/* Lab map picker — riusa .gmodal/.gm-card, aggiunge solo viewport mappa + tools. */
.lmp-overlay { z-index: 250; }
.lmp-card { display: flex; flex-direction: column; height: min(700px, 88vh); }
.lmp-toolbar { display: flex; gap: 8px; margin: 10px 0; }
.lmp-map { flex: 1; min-height: 360px; border-radius: 12px; border: 1px solid var(--line); overflow: hidden; }
.lmp-coords { margin-top: 8px; font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; text-align: center; }
.leaflet-container { z-index: 0; }
.leaflet-top, .leaflet-bottom { z-index: 400; }

/* Profilo lavanderia · geolocate buttons (mobile vs desktop).
   Desktop: 3ª colonna della field-row, bottone primary allineato al bottom
            degli input lat/lng (stessa altezza), niente hint sotto.
   Mobile:  field-row 2 colonne lat/lng, sotto un bottone primary full-width
            "Geolocalizza lavanderia" (usa GPS), incollato a 4px. */
.geo-fieldrow { grid-template-columns: 1fr 1fr auto; }
/* Il bottone è dentro un .field con label vuota → si allinea automaticamente
   sotto la label come gli altri input, alla stessa altezza riga. Padding
   simmetrico verticale = padding input (10px) così l'altezza matcha esatta. */
.geo-field-desktop .geo-btn-desktop { padding: 10px 16px; line-height: 1.2; box-sizing: border-box; }
.geo-btn-mobile { display: none; }
@media (max-width: 600px) {
  .geo-fieldrow { grid-template-columns: 1fr 1fr; }
  .geo-field-desktop { display: none; }
  .geo-btn-desktop { display: none; }
  /* margin-top/-bottom impostati inline sul bottone (spacing one-off). */
  .geo-btn-mobile {
    display: inline-flex; width: 100%;
    padding: 14px 18px;
    font-size: 15px;
  }
}
.gmodal .gm-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 4px; }
.gmodal h3 { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; display: flex; align-items: center; }
.gmodal .gm-sub { font-size: 14px; color: var(--ink-3); margin-bottom: 22px; }
.gmodal .gm-close { width: 32px; height: 32px; border-radius: 8px; background: var(--bg); color: var(--ink-2); display: flex; align-items: center; justify-content: center; cursor: pointer; border: none; }
/* Listini prezzi — modal grande per desktop con tabella che scrolla internamente.
   Solo il wrapper della tabella scrolla (orizzontale), header/disclaimer/actions
   restano sempre visibili. Input testuali (no spinner browser). */
.gmodal .gm-card.gm-card-wide {
  max-width: 1100px;
  width: 100%;
  max-height: min(85vh, 800px);
  display: flex;
  flex-direction: column;
  padding: 24px 28px 22px;
  overflow: hidden;
}
.gmodal .gm-card.gm-card-wide > .gm-head,
.gmodal .gm-card.gm-card-wide > .gm-sub { flex-shrink: 0; }
.gmodal .gm-card.gm-card-wide > form { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.gmodal .gm-card.gm-card-wide .listini-table-wrap { flex: 1; min-height: 0; overflow: auto; }
.gmodal .gm-card.gm-card-wide .warn-note,
.gmodal .gm-card.gm-card-wide .gm-actions { flex-shrink: 0; }

/* Listini wrap: solo container, NO border (i border stanno sui .listini-section figli).
   Su mobile (vedi @media sotto) il container diventa visible/no-scroll, lasciando
   alla viewport il compito di scrollare. */
.listini-table-wrap { width: 100%; margin: 14px 0 4px; }
/* Ogni section ha proprio scroll-x: il border-radius clip-pa gli angoli e
   lo scroll orizzontale funziona se la tabella interna eccede in larghezza. */
.listini-section { border: 1px solid var(--line); border-radius: 12px; overflow-x: auto; overflow-y: hidden; background: var(--surface); -webkit-overflow-scrolling: touch; }
.listini-section + .listini-section { margin-top: 32px; }
.listini-table { width: 100%; border-collapse: collapse; min-width: 540px; font-size: 14px; }
/* Dispenser: solo 2 colonne (Prodotto + Prezzo), il min-width listini multi-colonna fa clippare il prezzo su mobile. */
.gmodal[data-gm="dispenser"] .listini-table { min-width: 0; }
/* Dispenser prodotti: campo prezzo = componente .numfield (€ dentro il box), come i
   prezzi macchine. Scopato a [data-gm="dispenser"] per vincere sulla vecchia regola input. */
.gmodal[data-gm="dispenser"] .listini-table .numfield { display: inline-flex; align-items: center; gap: 3px; background: var(--surface); border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; height: 34px; cursor: text; }
.gmodal[data-gm="dispenser"] .listini-table .numfield:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in oklab, var(--brand) 18%, transparent); }
.gmodal[data-gm="dispenser"] .listini-table .numfield input { flex: 0 1 auto; width: 48px; min-width: 40px; border: 0; outline: 0; background: transparent; box-shadow: none; padding: 0; font-weight: 700; font-size: 16px; text-align: right; color: var(--ink); font-variant-numeric: tabular-nums; }
.gmodal[data-gm="dispenser"] .listini-table .numfield-suffix { color: var(--ink-3); font-size: 13px; font-weight: 700; flex-shrink: 0; }
.gmodal[data-gm="dispenser"] .listini-table .col-machine { white-space: normal; min-width: 0; }
.gmodal[data-gm="dispenser"] .listini-table .col-machine .model { white-space: normal; display: block; font-size: 12px; margin-top: 2px; color: var(--ink-3); }
.listini-table thead th { padding: 10px 12px; background: var(--bg); color: var(--ink-2); font-weight: 700; font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; text-align: left; border-bottom: 1px solid var(--line); }
.listini-table tbody td { padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.listini-table tr.group-header > th { padding: 10px 12px; background: var(--bg); color: var(--ink-3); font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; text-align: left; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.listini-table tr.group-header:first-child > th { border-top: none; }
/* Macro-header (Senza Card / Con Card) + sub-header (Tipo 0/1/2) per modal Prezzi macchine.
   Dual-naming inline: nome dashboard (primary) + nome cassa POS (secondary in parens). */
.listini-table tr.macro-header > th { padding: 10px 12px; background: var(--bg); color: var(--ink-2); font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; text-align: center; border-bottom: 1px solid var(--line); vertical-align: top; }
.listini-table tr.macro-header > th.col-machine { text-align: left; }
.listini-table tr.macro-header > th.col-time,
.listini-table tr.macro-header > th.col-cash,
.listini-table tr.macro-header > th.col-card { background: #C7DBED; color: #1F4977; }
.listini-table tr.macro-header > th.col-time .macro-alias,
.listini-table tr.macro-header > th.col-cash .macro-alias,
.listini-table tr.macro-header > th.col-card .macro-alias { color: rgba(0,0,0,0.55); }
.listini-table tr.sub-header > th.col-cash,
.listini-table tr.sub-header > th.col-card,
.listini-table tbody td.col-cash,
.listini-table tbody td.col-card,
.listini-table tbody td.col-time { background: #EEF4FA; }
.listini-table .macro-alias { display: block; font-size: 10px; font-weight: 500; color: var(--ink-3); text-transform: none; letter-spacing: 0; margin-top: 2px; }
.listini-table tr.sub-header > th { padding: 8px 10px; background: var(--bg); color: var(--ink-3); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; text-align: center; border-bottom: 1px solid var(--line); }
.sub-alias { display: block; font-size: 10px; font-weight: 400; color: var(--ink-3); text-transform: none; letter-spacing: 0; margin-top: 2px; opacity: 0.75; }
.listini-table tr.slot-first td.col-machine { border-top: 2px solid var(--line); }
.listini-table .slot-cell-n,
.listini-table .slot-cell-min { text-align: center; font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.listini-table .slot-cell-readonly { color: var(--ink-3); font-size: 13px; }
/* Machine-header row dentro tabella asciugatrici: blocco compatto con N° slot + durata slot 1 */
.listini-table tr.machine-header > td { padding: 12px 14px; background: var(--bg); border-top: 2px solid var(--line); border-bottom: 1px solid var(--line); }
.listini-table tr.machine-header:first-of-type > td { border-top: none; }
.listini-table .machine-header-body { display: flex; align-items: center; justify-content: space-between; gap: 18px; flex-wrap: wrap; }
.listini-table .machine-header-body .machine-id strong { font-size: 14px; color: var(--ink); margin-right: 6px; }
.listini-table .machine-header-body .machine-id .model { font-size: 12px; color: var(--ink-3); }
.listini-table .machine-header-body .machine-config { display: flex; gap: 14px; align-items: center; }
.listini-table .machine-header-body .machine-config label { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; }
.listini-table .machine-header-body .machine-config input { width: 60px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; font-size: 16px; font-weight: 600; color: var(--ink); background: var(--surface); text-align: right; font-variant-numeric: tabular-nums; }
.listini-table tbody tr:last-child td { border-bottom: none; }
.listini-table .col-machine { white-space: nowrap; min-width: 140px; background: #FBF7EE; border-right: 1px solid #ECE3D0; }
.listini-table thead .col-machine { background: var(--bg); z-index: 3; }
.listini-table .col-machine strong { color: var(--ink); margin-right: 6px; }
.listini-table .col-machine .model { color: var(--ink-3); font-size: 12px; white-space: nowrap; }
/* Input testuale per i prezzi — niente spinner browser, scrittura libera da tastiera */
.listini-table input { width: 92px; padding: 7px 9px; border: 1px solid var(--line); border-radius: 8px; font-size: 16px; font-weight: 600; color: var(--ink); background: var(--surface); font-family: inherit; font-variant-numeric: tabular-nums; text-align: right; -moz-appearance: textfield; appearance: none; }
.listini-table input::-webkit-outer-spin-button,
.listini-table input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.listini-table input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.listini-table input::placeholder { color: var(--ink-3); font-weight: 500; }
.listini-table .empty { padding: 20px; text-align: center; color: var(--ink-3); }
/* Mobile: prima colonna macchina con model wrap (no sticky — su iOS Safari crea glitch). */
@media (max-width: 640px) {
  .listini-table .col-machine .model { display: block; font-size: 11px; margin-top: 2px; }
}

/* Mobile (portrait + landscape, ≤ 760px o altezza piccola): modal full-width come PAGINA
   normale scrollabile. Niente flex-fix interno, niente header/actions sticky: tutto
   scorre con la viewport (richiesta esplicita Andrea per fix iOS Safari glitch). */
@media (max-width: 760px), (max-height: 540px) {
  .gmodal { padding: 0; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; align-items: flex-start; }
  .gmodal .gm-card.gm-card-wide {
    max-width: 100vw;
    width: 100vw;
    height: auto;
    max-height: none;
    /* 100dvh = dynamic viewport height (Safari 15.4+, dic 2021): si adatta
       quando URL bar appare/sparisce, evitando il "jump" che mangia i bottoni. */
    min-height: 100vh;          /* fallback browser senza dvh */
    min-height: 100dvh;
    border-radius: 0;
    /* Safe-area inset bottom: i bottoni Annulla/Salva escono da sotto la barra
       iOS browser, niente doppio-tap. `max()` garantisce padding minimo anche
       quando env() restituisce 0 (no notch / non-iOS). */
    padding: 18px 16px max(14px, env(safe-area-inset-bottom));
    display: block;
    overflow: visible;
  }
  /* Disattiva il flex-layout interno: tutti i children tornano a flow naturale. */
  .gmodal .gm-card.gm-card-wide > form { display: block; flex: none; min-height: 0; }
  .gmodal .gm-card.gm-card-wide .listini-table-wrap { flex: none; overflow: visible; margin: 10px 0 4px; }
  .gmodal .gm-card.gm-card-wide .gm-sub { font-size: 13px; }
}

/* Toast notification — append in body via htmx hx-swap=beforeend.
   Auto-fade dopo 3s via CSS animation. Cleanup via JS htmx:afterSettle. */
.toast { position: fixed; top: 20px; right: 20px; padding: 12px 18px; background: var(--ok); color: #fff; border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,0.18); font-size: 14px; font-weight: 600; z-index: 1000; animation: toast-in 200ms ease-out, toast-out 280ms ease-in 3s forwards; pointer-events: none; }
.toast-warn { background: var(--warn); }
.toast-danger { background: var(--danger); }
@keyframes toast-in { from { transform: translateY(-12px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@keyframes toast-out { from { transform: translateY(0); opacity: 1; } to { transform: translateY(-12px); opacity: 0; } }

/* Confirm variant — sostituisce window.confirm() del browser con stile Bloomest */
.gmodal.gm-confirm .gm-card { max-width: 440px; padding: 24px; }
.gmodal.gm-confirm h3 { font-size: 18px; font-weight: 700; margin-bottom: 8px; letter-spacing: -0.01em; }
.gmodal.gm-confirm .gm-body { font-size: 14px; color: var(--ink-2); line-height: 1.5; margin-bottom: 20px; }
.gmodal.gm-confirm .gm-actions { display: flex; gap: 10px; }
.gmodal.gm-confirm .gm-actions > button { flex: 1; padding: 11px 16px; border-radius: 10px; font-size: 14px; font-weight: 700; cursor: pointer; border: 1px solid var(--line); font-family: inherit; }
.gmodal.gm-confirm .gm-actions .gm-cancel { background: var(--surface); color: var(--ink-2); }
.gmodal.gm-confirm .gm-actions .gm-cancel:hover { background: var(--bg); border-color: var(--ink-3); }
.gmodal.gm-confirm .gm-actions .gm-ok { background: var(--brand); color: #fff; border-color: var(--brand); }
.gmodal.gm-confirm .gm-actions .gm-ok:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
.gmodal.gm-confirm .gm-actions .gm-ok.danger { background: var(--danger); border-color: var(--danger); }
.gmodal.gm-confirm .gm-actions .gm-ok.danger:hover { background: #B91C1C; border-color: #B91C1C; }
.gmodal .gm-close:hover { background: var(--line); }
.gmodal .gm-close:active { transform: scale(0.9); }
.gmodal .gm-actions { display: flex; gap: 10px; margin-top: 22px; }
.gmodal .gm-actions button { flex: 1; }

.notes-panel { max-width: 380px; padding-top: 6px; }
.notes-panel h3 { font-size: 18px; font-weight: 800; margin: 0 0 8px; }
.notes-panel ul { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 10px; font-size: 13px; color: var(--ink-2); }
.notes-panel li { padding: 12px 14px; background: var(--surface); border-radius: 10px; box-shadow: var(--shadow-card); }
.notes-panel li strong { color: var(--ink); display: block; margin-bottom: 2px; }
.notes-panel li.warn { background: #FFF8DB; border: 1px solid #FCE4A0; }
.notes-panel li.warn strong { color: #8B6500; }

/* ====== Ricerca canonica (componente condiviso a TUTTE le viste) ======
   .search-bar = riga full-width posizionata SEMPRE subito sopra la tabella/
   lista: campo di ricerca (icona lente, input, azzera) + bottone "Filtri"
   opzionale a destra. Canone visivo: Movimenti. Variante .search-bar--bare =
   senza cornice, per quando la riga vive dentro un contenitore che ha già la
   sua (es. .clienti-toolbar, modali). */
.search-bar { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--line); flex-wrap: wrap; background: var(--surface); }
.search-bar .search-field { flex: 1; min-width: 180px; position: relative; }
.search-bar .search-field svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--ink-3); pointer-events: none; }
.search-bar .search-field input { width: 100%; padding: 10px 12px 10px 36px; border: 1px solid var(--line); border-radius: 10px; font-size: 16px; line-height: 1.2; background: var(--bg); }
.search-bar .search-field input:focus { outline: none; border-color: var(--brand); background: var(--surface); }
.search-bar .search-field input:not(:placeholder-shown) { padding-right: 36px; }
.search-bar .search-field input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.search-bar .search-clear { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: 0; background: none; color: var(--ink-2); font-size: 24px; line-height: 1; cursor: pointer; }
.search-bar .search-clear:hover { color: var(--ink); }
.search-bar .search-field input:placeholder-shown ~ .search-clear { display: none; }
.search-bar--bare { padding: 0; border-bottom: 0; background: none; }

/* Bottone "Filtri" della search-bar: outline neutro da spento, accento +
   badge col numero quando ci sono filtri attivi. Stesso linguaggio di
   .filter-dd. Nei Movimenti apre il popover .mov-filters-pop coi chip. */
.search-bar .filters-btn { flex-shrink: 0; display: inline-flex; align-items: center; gap: 8px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); font-size: 14px; font-weight: 600; color: var(--ink); cursor: pointer; transition: background .15s, border-color .15s, color .15s; }
.search-bar .filters-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.search-bar .filters-btn:hover { border-color: var(--ink-3); background: var(--bg); }
.search-bar .filters-btn.is-on { border-color: var(--brand); background: var(--brand-soft); color: var(--brand); }
.search-bar .filters-count { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px; background: var(--brand); color: #fff; font-size: 12px; font-weight: 700; line-height: 1; }

/* ====== Movimenti · multi-select dropdown + table chrome ====== */
.mov-filters-pop { gap: 6px; }
.mov-filters-list { display: flex; flex-direction: column; gap: 4px; }
.mov-filter-chip { display: inline-flex; align-items: center; justify-content: space-between; gap: 8px; padding: 7px 10px; border-radius: 8px; background: var(--bg); color: var(--ink); font-size: 13px; font-weight: 500; text-decoration: none; }
.mov-filter-chip:hover { background: var(--brand-soft); color: var(--brand); }
.mov-filter-chip svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--ink-3); }
.mov-filter-chip:hover svg { color: var(--brand); }
.mov-filters-clear-all { display: block; margin-top: 4px; padding: 7px 10px; border-top: 1px solid var(--line); color: var(--ink-2); font-size: 13px; font-weight: 600; text-decoration: none; text-align: center; }
.mov-filters-clear-all:hover { color: var(--danger, #c0392b); }

.filter-dd { position: relative; }
.filter-dd > summary { list-style: none; display: inline-flex; align-items: center; gap: 8px; padding: 10px 12px 10px 14px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); font-size: 14px; font-weight: 600; color: var(--ink); cursor: pointer; user-select: none; transition: background .15s, border-color .15s; }
.filter-dd > summary::-webkit-details-marker { display: none; }
.filter-dd > summary::marker { display: none; }
.filter-dd > summary:hover { border-color: var(--ink-3); background: var(--bg); }
.filter-dd[open] > summary,
.filter-dd.has-filter > summary { border-color: var(--brand); background: var(--brand-soft); color: var(--brand); }
.filter-dd .filter-ico { width: 16px; height: 16px; flex-shrink: 0; }
.filter-dd .filter-state { display: inline-flex; align-items: center; min-width: 22px; height: 22px; padding: 0 8px; border-radius: 999px; background: var(--ink); color: #fff; font-size: 12px; font-weight: 700; line-height: 1; }
.filter-dd[open] .filter-state,
.filter-dd.has-filter .filter-state { background: var(--brand); color: #fff; }
.filter-dd .chev { width: 18px; height: 18px; transition: transform .2s; stroke-width: 2.5; }
.filter-dd[open] .chev { transform: rotate(180deg); }

.filter-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 50; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 12px 32px rgba(15,20,25,0.14); min-width: 280px; padding: 6px 4px 4px; }
.filter-menu-head { display: flex; align-items: center; justify-content: space-between; padding: 6px 12px 10px; border-bottom: 1px solid var(--line); margin-bottom: 4px; }
.filter-menu-head strong { font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-3); }
.filter-menu-head .text-btn { background: none; border: none; color: var(--brand); font-size: 12px; font-weight: 600; cursor: pointer; padding: 2px 4px; }
.filter-menu-head .text-btn:hover { text-decoration: underline; }
.filter-menu label { display: flex; align-items: center; gap: 10px; padding: 8px 12px; font-size: 14px; color: var(--ink); cursor: pointer; border-radius: 6px; }
.filter-menu label:hover { background: var(--bg); }
.filter-menu input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--brand); cursor: pointer; }
.filter-menu-foot { padding: 8px 12px 6px; margin-top: 4px; border-top: 1px solid var(--line); font-size: 11px; color: var(--ink-3); display: flex; align-items: center; gap: 6px; }
.filter-menu-foot svg { width: 12px; height: 12px; flex-shrink: 0; }

/* ====== Movimenti · device badge + cells ====== */
.dev-badge { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; }
.dev-badge .ltr { width: 22px; height: 22px; border-radius: 50%; background: #6B7280; color: #fff; font-weight: 700; font-size: 11px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.dev-badge .mod { color: var(--ink-2); font-weight: 600; }

.desc-cell { display: flex; flex-direction: column; gap: 4px; }
.desc-cell .price-tag { display: inline-flex; align-self: flex-start; background: #2F7BB9; color: #fff; font-size: 10px; padding: 2px 8px; border-radius: 3px; font-weight: 600; }

.fc-cell { display: flex; flex-direction: column; gap: 3px; align-items: flex-start; }
.fc-cell .fc-id { background: var(--brand); color: #fff; font-family: ui-monospace, monospace; font-size: 11px; padding: 2px 7px; border-radius: 3px; font-weight: 600; }
.fc-cell .fc-user { background: #2F7BB9; color: #fff; font-size: 11px; padding: 2px 7px; border-radius: 3px; font-weight: 500; }

.val-cell { font-weight: 600; }
.val-cell.neg { color: var(--danger); }

/* ====== Movimenti · responsive table wrapper ====== */
.mov-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.mov-table-wrap .dt-table { min-width: 760px; }
.mov-table-wrap tbody { transition: opacity .18s ease; }
.mov-table-wrap tbody.is-changing { opacity: 0.25; }
.mov-footer { padding: 12px 16px; font-size: 12px; color: var(--ink-3); border-top: 1px solid var(--line); display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.mov-chips { gap: 6px; padding: 12px 16px; border-bottom: 1px solid var(--line); display: flex; flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.mov-chips::-webkit-scrollbar { display: none; }
.mov-chip { display: inline-flex; align-items: center; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); font-size: 13px; font-weight: 500; text-decoration: none; transition: background .15s ease, color .15s ease, border-color .15s ease; }
.mov-chip:hover { background: var(--bg); color: var(--ink); }
.mov-chip.is-active { background: var(--ink); color: #fff; border-color: var(--ink); }
.mov-pager { display: inline-flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; }
.mov-pager-btn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); text-decoration: none; font-size: 16px; line-height: 1; }
.mov-pager-btn:hover:not(.is-disabled) { background: var(--bg); color: var(--ink); }
.mov-pager-btn.is-disabled { opacity: 0.35; cursor: not-allowed; }
.mov-pager-curr { padding: 0 6px; }
/* Salto pagina: input numerico inline ("pagina [N] di Y") */
.mov-pager-jump { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-variant-numeric: tabular-nums; color: var(--ink-3); }
.mov-pager-input { width: 3.5em; padding: 4px 6px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink); font-size: 12px; text-align: center; -moz-appearance: textfield; appearance: textfield; }
.mov-pager-input::-webkit-outer-spin-button, .mov-pager-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.mov-pager-input:focus { outline: none; border-color: var(--brand); }
th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { color: var(--ink); }
.sort-arrow { font-size: 10px; color: var(--ink-3); }
.cassa-subtotal td { border-top: 2px solid var(--line); font-weight: 700; }
.mov-per-form { margin: 0; }
.mov-per-form select { padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink-2); font-size: 12px; cursor: pointer; }
.mov-per-form select:focus { outline: none; border-color: var(--brand); }
.u-vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
/* Vendite/Cicli per dispositivo · estensione minimale di .dt-table (L705).
   Stessa estetica della tabella Movimenti: no zebra, no avatar pill, footer
   discreto coerente con tbody style. Scroll orizzontale su mobile via
   .mov-table-wrap overflow-x: auto (no stack mode, dati comparabili a colonne). */
.vpm-table .num, .vpm-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.vpm-table tbody tr:hover { cursor: default; }
.vpm-table tfoot td { padding: 12px 14px; font-size: 13px; font-weight: 700; border-top: 1px solid var(--line); white-space: nowrap; }
/* Importo-link dentro cella numerica (es. "di cui da fatturare" → tab Fatture).
   Chevron PRIMA del numero: la cifra resta a filo destro, decimali incolonnati
   con le righe senza link. */
.cell-link { display: inline-flex; align-items: center; gap: 3px; color: var(--brand); font-weight: 600; text-decoration: none; }
.cell-link .i { width: 13px; height: 13px; transition: transform 120ms ease; }
.cell-link:hover { color: var(--brand-dark); }
.cell-link:hover .i { transform: translateX(2px); }
.cell-link:active { opacity: 0.7; }
/* Corrispettivi · card-form (commercialista + esporta periodo): i controlli
   vivono dentro una dt-card, non sciolti sul fondo pagina. La hairline separa
   impostazioni e azione di invio dentro la stessa card (full-bleed). */
.corr-card { padding: 16px 18px; }
.corr-card .metric-rows--flat { margin: 0 0 14px; box-shadow: none; border: 1px solid var(--line); }
.corr-card-sep { height: 1px; background: var(--line); margin: 16px -18px; }
/* "Esporta un periodo": una sola riga Dal | Al | bottoni, allineata in basso
   (le label delle date stanno sopra). Campi a larghezza media: 220px = il
   min-width di design del .dt-trigger; sotto (mobile), il trigger si comprime
   (min-width:0 come .hh-dates) invece di sbordare. */
.corr-periodo-form { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
.corr-periodo-fld { width: 220px; max-width: 100%; }
.corr-periodo-fld .dt-field { display: flex; min-width: 0; width: 100%; }
.corr-periodo-fld .dt-trigger { min-width: 0; width: 100%; }

/* Riepilogo · column-aligned metric values (amount + percent/count) */
/* text-align right: senza, un valore che wrappa su 2 righe (es. data+ora su
   mobile stretto) allinea la seconda riga a sinistra dentro il flex item. */
.metric-row .val { display: inline-flex; align-items: baseline; gap: 10px; justify-content: flex-end; text-align: right; }
.metric-row .val .col-amt { font-weight: 700; min-width: 96px; text-align: right; flex-shrink: 0; font-variant-numeric: tabular-nums; }
.metric-row .val .col-pct { color: var(--ink-3); font-weight: 500; font-size: 12px; min-width: 40px; text-align: right; flex-shrink: 0; font-variant-numeric: tabular-nums; }
.metric-row .val .col-cnt { color: var(--ink-3); font-weight: 600; font-size: 13px; min-width: 96px; text-align: right; flex-shrink: 0; font-variant-numeric: tabular-nums; }
.metric-row .val .col-sub { color: var(--ink-3); font-weight: 500; font-size: 12px; }

/* Period filter — utility card grouping chips + pill + range picker */
.period-card { margin: 12px 18px 0; padding: 14px 16px; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 2px 8px rgba(15,20,25,0.04); position: relative; }
.period-card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.period-card-ico { width: 16px; height: 16px; color: var(--brand); flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.period-card-label { font-size: 11px; color: var(--ink); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 800; }
.period-card-hint { font-size: 11px; color: var(--ink-3); font-weight: 500; font-style: italic; margin-left: auto; }
.period-card-value { font-size: 13px; color: var(--brand); background: var(--brand-soft); font-weight: 800; font-family: ui-monospace, monospace; margin-left: 6px; padding: 4px 12px; border-radius: 999px; letter-spacing: 0.02em; line-height: 1.2; }
.period-card .chips { padding: 0; margin: 0; gap: 6px; }
.period-card .mov-range { margin: 12px 0 0; padding: 12px; background: var(--bg); border: 1px solid var(--line); box-shadow: none; border-radius: 10px; }
@media (max-width: 720px) {
  .period-card-hint { display: none; }
  .period-card .chips { flex-wrap: wrap; overflow-x: visible; row-gap: 8px; }
  .period-card .chip { flex: 0 0 auto; min-height: 36px; padding: 8px 14px; }
}

/* Period info as a pill connected to chips */
.period-info.mov-period { display: inline-flex; align-items: center; gap: 6px; padding: 4px 12px; margin: 10px 0 0; background: var(--brand-soft); color: var(--brand); border-radius: 999px; font-size: 12px; font-family: -apple-system, BlinkMacSystemFont, system-ui, sans-serif; font-weight: 600; transition: transform .2s, box-shadow .2s; }
.period-info.mov-period.flash { animation: periodFlash 0.5s ease; }
@keyframes periodFlash {
  0% { transform: scale(1); }
  40% { transform: scale(1.06); box-shadow: 0 6px 18px rgba(140,0,20,0.18); }
  100% { transform: scale(1); }
}

/* Custom date+time range picker */
.mov-range { display: none; align-items: flex-end; gap: 10px; padding: 12px 18px; margin: 8px 18px 0; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 4px 12px rgba(15,20,25,0.06); flex-wrap: wrap; }
.mov-range.open { display: flex; }
.mov-range .range-arrow { color: var(--ink-3); font-size: 18px; line-height: 1; display: inline-flex; align-items: center; justify-content: center; height: 42px; width: 24px; padding: 0; align-self: flex-end; }
.mov-range .range-apply { padding: 0 18px; background: var(--brand); color: #fff; border: none; border-radius: 10px; font-size: 13px; font-weight: 700; cursor: pointer; height: 42px; align-self: flex-end; }
.mov-range .range-apply:hover { background: var(--brand-hover); }

/* dt-field — desktop custom widget + native fallback */
.dt-field { display: inline-flex; flex-direction: column; gap: 4px; position: relative; }
.dt-field > label { font-size: 11px; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700; }
.dt-trigger { padding: 0; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); min-width: 220px; display: inline-flex; align-items: center; gap: 0; font-family: inherit; overflow: hidden; transition: border-color 120ms ease, background 120ms ease; }
.dt-trigger:hover { border-color: var(--ink-3); background: var(--surface); }
.dt-field.open .dt-trigger,
.dt-trigger:focus-within { border-color: var(--brand); background: var(--surface); box-shadow: 0 0 0 3px var(--brand-soft); }
.dt-trigger .dt-display { flex: 1; min-width: 0; padding: 10px 4px 10px 12px; border: none; outline: none; background: transparent; font-size: 14px; font-weight: 600; color: var(--ink); font-family: inherit; letter-spacing: 0; }
.dt-trigger .dt-display::placeholder { color: var(--ink-3); font-weight: 500; }
.dt-trigger .dt-icon-btn { width: 36px; height: 38px; padding: 0; border: none; background: transparent; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; color: var(--brand); border-left: 1px solid var(--line); transition: background 120ms ease; flex-shrink: 0; }
.dt-trigger .dt-icon-btn:hover { background: var(--brand-soft); }
.dt-trigger svg.cal-ico { width: 18px; height: 18px; color: var(--brand); stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }

.dt-popover { position: absolute; top: calc(100% + 6px); left: 0; z-index: 100; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 16px 40px rgba(15,20,25,0.16); padding: 14px; min-width: 296px; display: none; }
.dt-field.open .dt-popover { display: block; }

.cal-head { display: flex; align-items: center; justify-content: space-between; padding: 0 4px 10px; }
.cal-head button { width: 30px; height: 30px; border: none; background: var(--bg); border-radius: 8px; cursor: pointer; color: var(--ink); font-size: 16px; display: inline-flex; align-items: center; justify-content: center; padding: 0; }
.cal-head button:hover { background: var(--line); }
.cal-head .cal-month { font-size: 14px; font-weight: 700; color: var(--ink); text-transform: capitalize; display: flex; gap: 6px; align-items: center; }
.cal-sel-month, .cal-sel-year { font-size: 14px; font-weight: 700; color: var(--ink); border: none; background: transparent; cursor: pointer; font-family: inherit; padding: 2px 0; -webkit-appearance: none; appearance: none; text-transform: capitalize; }
.cal-sel-year { width: 60px; text-align: center; }

.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; padding: 4px 0 10px; }
.cal-dow { font-size: 10px; color: var(--ink-3); text-align: center; font-weight: 700; text-transform: uppercase; padding: 4px 0 6px; }
.cal-day { height: 34px; display: inline-flex; align-items: center; justify-content: center; font-size: 13px; cursor: pointer; border-radius: 8px; color: var(--ink); user-select: none; transition: background .12s, color .12s; font-weight: 500; }
.cal-day:hover { background: var(--brand-soft); color: var(--brand); }
.cal-day.other { color: var(--ink-3); opacity: 0.4; }
.cal-day.today { font-weight: 800; box-shadow: inset 0 0 0 1.5px var(--brand); }
.cal-day.selected { background: var(--brand); color: #fff; font-weight: 700; }
.cal-day.selected:hover { background: var(--brand-hover); color: #fff; }
.cal-day.disabled { color: var(--ink-3); opacity: 0.3; cursor: not-allowed; }
.cal-day.disabled:hover { background: transparent; color: var(--ink-3); }

.cal-time { display: flex; align-items: center; gap: 8px; padding: 10px 4px; border-top: 1px solid var(--line); margin-top: 4px; }
.cal-time .cal-time-lbl { font-size: 11px; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700; flex: 1; display: inline-flex; align-items: center; gap: 6px; }
.cal-time .cal-time-lbl svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.cal-time select { padding: 7px 8px; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; background: var(--bg); cursor: pointer; font-family: inherit; color: var(--ink); font-weight: 600; min-width: 56px; }
.cal-time select:focus { outline: none; border-color: var(--brand); background: var(--surface); }
.cal-time .sep { color: var(--ink-3); font-weight: 700; }

.cal-foot { display: flex; justify-content: space-between; gap: 8px; padding-top: 10px; border-top: 1px solid var(--line); }
.cal-foot .text-btn { background: none; border: none; color: var(--brand); font-size: 13px; font-weight: 600; cursor: pointer; padding: 6px 10px; border-radius: 6px; }
.cal-foot .text-btn:hover { background: var(--brand-soft); }
.cal-foot .ok-btn { padding: 8px 18px; background: var(--brand); color: #fff; border: none; border-radius: 8px; font-size: 13px; font-weight: 700; cursor: pointer; }
.cal-foot .ok-btn:hover { background: var(--brand-hover); }

/* dt-native is an invisible overlay on touch devices — keeps the styled trigger visible while letting iOS/Android open their wheel picker */
.dt-native { position: absolute; left: 0; right: 0; bottom: 0; height: 44px; opacity: 0.001; border: 0; padding: 0; margin: 0; font-size: 16px; background: transparent; color: transparent; pointer-events: none; z-index: 1; }

@media (pointer: coarse) {
  .dt-field { width: 100%; }
  .dt-trigger { width: 100%; pointer-events: none; }
  .dt-popover { display: none !important; }
  .dt-native { pointer-events: auto; }
}

@media (max-width: 720px) {
  .search-bar { padding: 10px 12px; }
  .search-bar--bare { padding: 0; }
  .filter-dd > summary { padding: 8px 10px; font-size: 12px; }
  .filter-menu { right: auto; left: 0; }
  .mov-range { flex-direction: column; align-items: stretch; gap: 10px; }
  .mov-range .dt-field { width: 100%; }
  .mov-range .dt-trigger { width: 100%; }
  .mov-range .range-apply { width: 100%; }
  .mov-range .range-arrow { display: none; }
}

/* =========================================================
   MARKETING — outcome-first design
   ========================================================= */

/* Bottom-nav: 4 voci + "+" → la label resta a 10px (≥ soglia leggibilità) anche su mobile */
@media (max-width: 480px) { .bottom-nav button span { font-size: 10px; } }

/* Info tip — label sottolineato tratteggiato, popover on hover (no più `?` separato) */
.info-tip { position: relative; cursor: help; text-decoration: underline dashed var(--ink-3); text-decoration-thickness: 1px; text-underline-offset: 3px; }
.info-tip:hover, .info-tip:focus-visible { color: var(--brand); text-decoration-color: var(--brand); outline: none; }
.info-popover { position: absolute; top: calc(100% + 8px); left: 0; background: var(--surface); color: var(--ink); border: 1px solid var(--line); padding: 12px 14px; border-radius: 10px; font-size: 13px; font-weight: 400; line-height: 1.5; width: 280px; max-width: calc(100vw - 32px); box-shadow: 0 10px 30px rgba(15,20,25,0.14); display: none; z-index: 200; text-align: left; letter-spacing: 0; pointer-events: none; font-family: inherit; white-space: normal; }
.info-tip:hover .info-popover, .info-tip:focus-visible .info-popover { display: block; }
.info-popover::before { content: ''; position: absolute; top: -7px; left: 20px; transform: rotate(45deg); width: 12px; height: 12px; background: var(--surface); border-left: 1px solid var(--line); border-top: 1px solid var(--line); }
.info-popover strong { color: var(--ink); font-weight: 700; }
.info-popover .ex { display: block; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); color: var(--ink-2); font-style: italic; }

/* Wizard avanzato (5 step condensati dai 9 Bloomest) */
.wiz-stepper { display: flex; align-items: center; padding: 0 var(--page-pad-x) 8px; gap: 0; }
@media (min-width: 768px) { .wiz-stepper { padding: 0 var(--page-pad-x) 12px; } }
.wiz-stepper .dot { flex: 0 0 28px; width: 28px; height: 28px; border-radius: 50%; background: var(--bg); color: var(--ink-3); border: 2px solid var(--line); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px; font-variant-numeric: tabular-nums; }
.wiz-stepper .dot.done { background: var(--ok); color: #fff; border-color: var(--ok); }
.wiz-stepper .dot.current { background: var(--brand); color: #fff; border-color: var(--brand); box-shadow: 0 0 0 4px var(--brand-soft); }
.wiz-stepper .seg { flex: 1; height: 2px; background: var(--line); }
.wiz-stepper .seg.done { background: var(--ok); }

.wiz-content { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 16px; margin: 12px var(--page-pad-x); }
@media (min-width: 768px) { .wiz-content { padding: 22px 24px; margin: 14px var(--page-pad-x); } }
.wiz-error { display: flex; gap: 8px; align-items: center; margin-bottom: 14px; padding: 10px 12px; border-radius: 10px; background: var(--brand-soft); border: 1px solid var(--brand); color: var(--brand); font-size: 13px; font-weight: 600; line-height: 1.4; }
.wiz-error .i { flex: 0 0 auto; }
.wiz-content h3 { font-size: 17px; font-weight: 700; color: var(--ink); margin-bottom: 6px; line-height: 1.3; }
.wiz-content .hint { font-size: 13px; color: var(--ink-2); line-height: 1.5; margin-bottom: 16px; }
/* Option card radio — componente condiviso (wizard Promo, card bonus).
   La classe nuda .opt e' usata SOLO con questo pattern (verifica 2026-07-05). */
/* position:relative: ancora i radio nascosti (position:absolute) alla lista.
   Senza, il loro containing block e' la pagina: in WebKit si stirano a tutta
   larghezza dal bordo card (+34px oltre il viewport su iPhone) scavalcando
   l'overflow:hidden della card -> shrink-to-fit + auto-zoom al focus. */
.opt-list { display: flex; flex-direction: column; gap: 10px; position: relative; }
.opt { padding: 14px; border: 1px solid var(--line); border-radius: 12px; cursor: pointer; display: flex; gap: 12px; align-items: flex-start; transition: border-color .12s, background .12s; background: var(--surface); }
.opt:hover { border-color: var(--brand); }
.opt.selected,
.opt-list input[type="radio"]:checked + .opt { border-color: var(--brand); background: var(--brand-soft); }
.opt .opt-radio { flex: 0 0 20px; width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line); margin-top: 2px; position: relative; background: var(--surface); }
.opt.selected .opt-radio,
.opt-list input[type="radio"]:checked + .opt .opt-radio { border-color: var(--brand); }
.opt.selected .opt-radio::after,
.opt-list input[type="radio"]:checked + .opt .opt-radio::after { content: ''; position: absolute; top: 3px; left: 3px; width: 10px; height: 10px; border-radius: 50%; background: var(--brand); }
.opt-list input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; font-size: 16px; }
.opt .opt-body { flex: 1; }
.opt .opt-title { font-size: 14px; font-weight: 700; color: var(--ink); margin-bottom: 2px; }
.opt .opt-desc { font-size: 12px; color: var(--ink-2); line-height: 1.4; }
/* .opt dentro un .field (pane Bonus reg./Compleanno): il label eyebrow
   (.field label, piu' specifico) vincerebbe sul componente — display:block
   impila la radio sopra il testo e l'uppercase 11px si eredita su titolo e
   descrizione. Ripristina il componente in quel contesto. */
.field label.opt { display: flex; font-size: 14px; font-weight: 400; text-transform: none; letter-spacing: normal; color: var(--ink); margin-bottom: 0; }
.wiz-content .sub-field { margin-top: 14px; padding: 14px; background: var(--bg); border-radius: 12px; }
.wiz-content .sub-field label { display: block; font-size: 12px; font-weight: 600; color: var(--ink-2); margin-bottom: 6px; }
.wiz-content .sub-field input[type="number"], .wiz-content .sub-field input[type="text"], .wiz-content .sub-field input[type="date"], .wiz-content .sub-field select, .wiz-content .sub-field textarea { width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; font-size: 16px; background: var(--surface); color: var(--ink); }
.wiz-content .sub-field input:focus, .wiz-content .sub-field select:focus, .wiz-content .sub-field textarea:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.wiz-content .sub-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 480px) { .wiz-content .sub-field-row { grid-template-columns: 1fr; } }
/* Campi data wizard: componente .dt-field condiviso (niente <input type=date> nudo →
   niente calendario nativo su desktop). La regola .sub-field input{width:100%} sopra
   colpirebbe gli input INTERNI del componente (.dt-display testo, .dt-native overlay):
   li riportiamo al loro stile trasparente. Mobile/touch: resta l'overlay nativo (≈1501). */
.wiz-content .sub-field .dt-field { width: 100%; }
.wiz-content .sub-field .dt-field .dt-trigger { min-width: 0; width: 100%; }
.wiz-content .sub-field-row > div:last-child .dt-popover { left: auto; right: 0; }
.wiz-content .sub-field .dt-field .dt-display { width: 100%; border: 0; background: transparent; padding: 10px 4px 10px 12px; font-size: 14px; }
.wiz-content .sub-field .dt-field .dt-display:focus { box-shadow: none; }
.wiz-content .sub-field .dt-field .dt-native { width: auto; border: 0; padding: 0; background: transparent; }
/* Wroblewski: la larghezza del campo suggerisce la lunghezza del dato atteso. I campi
   numerici corti (%, conteggi, importi) NON vanno a tutta riga. */
.wiz-content .sub-field .fld-narrow { max-width: 6rem; }
.wiz-content .sub-field .fld-mid { max-width: 9rem; }
/* Checkbox giorni cashback "a giorno": riuso visivo del pattern .chk-row/.chk di
   Happy Hour, scoped a .wiz-content (le regole .happy_hour_form .chk* non si
   applicano fuori dal planner Happy Hour). */
.wiz-content .sub-field .chk-row { display: flex; flex-wrap: wrap; gap: 10px 16px; margin-top: 4px; }
.wiz-content .sub-field .chk { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 500; color: var(--ink); cursor: pointer; }
.wiz-content .sub-field .chk input { width: auto; margin: 0; accent-color: var(--brand); flex-shrink: 0; }
.wiz-content .notice { padding: 10px 12px; background: var(--brand-soft); border-radius: 8px; font-size: 12px; color: var(--brand); line-height: 1.5; margin-top: 12px; }

/* Nota "Quando premi Attiva" — chiarisce se la cassa applica da sola o serve la cassa. */
.wiz-activate-note { padding: 12px 14px; border-radius: 12px; background: var(--brand-soft); color: var(--ink-2); font-size: 13px; line-height: 1.5; }
.wiz-activate-note strong { color: var(--ink); }

.wiz-summary { display: flex; flex-direction: column; gap: 0; }
.wiz-summary .sum-row { display: grid; grid-template-columns: 130px 1fr; gap: 16px; padding: 12px 0; border-bottom: 1px dashed var(--line); align-items: flex-start; }
.wiz-summary .sum-row:last-child { border-bottom: none; }
.wiz-summary .sum-row .lbl { font-size: 13px; color: var(--ink-2); }
.wiz-summary .sum-row .val { font-size: 14px; font-weight: 700; color: var(--ink); }
@media (max-width: 480px) { .wiz-summary .sum-row { grid-template-columns: 1fr; gap: 2px; } }

.wiz-nav { display: flex; gap: 10px; padding: 16px var(--page-pad-x); flex-wrap: wrap; }
@media (min-width: 768px) { .wiz-nav { padding: 14px var(--page-pad-x) 24px; } }
.wiz-nav button { flex: 1; min-width: 140px; }
.wiz-nav button[disabled] { opacity: 0.4; cursor: not-allowed; }

/* Modal Marketing: layout grid label-sx + value-sx (override .val display:inline-flex / justify-content:flex-end di linea 551) */
[data-gm="credenziali"] .metric-row,
[data-modal="azioni-stepper"] .metric-row { display: grid; grid-template-columns: 130px 1fr; gap: 16px; align-items: flex-start; }
[data-gm="credenziali"] .metric-row .lbl,
[data-modal="azioni-stepper"] .metric-row .lbl { padding-top: 1px; }
[data-gm="credenziali"] .metric-row .val,
[data-modal="azioni-stepper"] .metric-row .val { display: block; text-align: left; line-height: 1.4; min-width: 0; justify-content: flex-start; }
/* Credenziali: email lunga senza spazi va a capo invece di essere tagliata da .metric-rows{overflow:hidden} su schermo stretto */
[data-gm="credenziali"] .metric-row .val { overflow-wrap: anywhere; }

/* Marketing home — Cosa vuoi ottenere? */
.mkt-intro { padding: 0 var(--page-pad-x) 4px; }
/* Titolo sezione: stesso formato di .section-title (piccolo, maiuscolo, grigio)
   invece del titolone bold — coerenza tipografica (review Andrea, riordino W1). */
.mkt-intro h2 { font-size: 13px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 6px; }
.mkt-intro p { font-size: 14px; color: var(--ink-2); }
@media (min-width: 768px) { .mkt-intro { padding: 0 var(--page-pad-x) 8px; } }

.mkt-goals { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; padding: 12px var(--page-pad-x); }
@media (min-width: 768px) { .mkt-goals { gap: 16px; padding: 14px var(--page-pad-x); } }
@media (min-width: 1100px) { .mkt-goals { grid-template-columns: repeat(4, 1fr); } }

.goal-card { background: var(--surface); border-radius: var(--radius); padding: 16px 14px 14px; border: 1px solid var(--line); cursor: pointer; transition: transform .12s, box-shadow .12s; display: flex; flex-direction: column; gap: 10px; min-height: 142px; position: relative; overflow: hidden; }
.goal-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-card); }
.goal-card:active { transform: scale(0.98); }
.goal-card .goal-dot { width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #fff; }
.goal-card .goal-title { font-size: 15px; font-weight: 700; color: var(--ink); line-height: 1.2; }
.goal-card .goal-stat { font-size: 12px; color: var(--ink-2); line-height: 1.35; }
/* Prova storica reale (Parte 2): riga muted neutra sotto la stat dell'obiettivo,
   resa solo se la card ha history_line (campagne concluse attribuibili). */
.goal-card .goal-proof { font-size: 11px; font-weight: 600; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.goal-card[data-goal="dormienti"] .goal-dot { background: var(--danger); }
.goal-card[data-goal="spendere"] .goal-dot { background: var(--warn); }
.goal-card[data-goal="gratificare"] .goal-dot { background: var(--ok); }
.goal-card[data-goal="frequenza"] .goal-dot { background: var(--info); }

/* Obiettivi in formato RIGA (riordino W1): stile lista come "Campagne attive"
   (.mkt-active-row) + icona colorata dell'obiettivo a sinistra. */
.mkt-goal-list { display: flex; flex-direction: column; gap: 8px; padding: 12px var(--page-pad-x); }
.goal-row .goal-dot { width: 38px; height: 38px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #fff; flex-shrink: 0; }
.goal-row .row-top { align-items: center; }
.goal-row .name { line-height: 1.25; }
.goal-row .goal-proof { font-size: 11px; font-weight: 600; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.goal-row[data-goal="dormienti"] .goal-dot { background: var(--danger); }
.goal-row[data-goal="spendere"] .goal-dot { background: var(--warn); }
.goal-row[data-goal="gratificare"] .goal-dot { background: var(--ok); }
.goal-row[data-goal="frequenza"] .goal-dot { background: var(--info); }
/* Comunica: riga full-width come gli obiettivi ma azione (non obiettivo) → dot
   brand. Su <button> serve il reset (la riga obiettivo nativa e' un <a>). */
.goal-row[data-goal="comunica"] .goal-dot { background: var(--brand); }
button.mkt-active-row { width: 100%; font: inherit; text-align: left; }

/* Proposte per obiettivo (screen proposals, server-rendered da presets) */
.mkt-proposals-list { display: flex; flex-direction: column; gap: 12px; padding: 12px var(--page-pad-x); }
.proposal-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; position: relative; }
.proposal-card.recommended { border-color: var(--ok); }
.prop-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 700; color: var(--ok); margin-bottom: 10px; }
.prop-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.prop-ico { width: 36px; height: 36px; border-radius: 50%; background: var(--bg); display: flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--ink-2); }
.prop-name { font-size: 15px; font-weight: 700; color: var(--ink); line-height: 1.2; }
.prop-actions { display: flex; gap: 8px; margin-top: 12px; }
/* "Meccanismo" è una descrizione lunga: nel layout .metric-row il .val (flex-shrink:0)
   non si restringe e schiacciava la label "Meccanismo" a un carattere per riga.
   La impiliamo: label sopra, descrizione sotto a tutta larghezza. */
.proposal-card .metric-row.prop-mech { display: block; }
.proposal-card .metric-row.prop-mech .lbl { display: block; margin-bottom: 4px; }
.proposal-card .metric-row.prop-mech .val { display: block; text-align: left; justify-content: flex-start; font-weight: 600; overflow-wrap: anywhere; }

/* Campagne attive — lista compatta */
.mkt-active-list { display: flex; flex-direction: column; gap: 8px; padding: 0 var(--page-pad-x); }
@media (min-width: 768px) { .mkt-active-list { padding: 0 var(--page-pad-x); } }
.mkt-active-row { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 14px 18px; cursor: pointer; display: flex; align-items: center; gap: 20px; text-decoration: none; color: inherit; }
.mkt-active-row-conclusa { cursor: default; opacity: 0.85; }
.mkt-active-row:hover { border-color: var(--brand); }
.mkt-active-row .row-content { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.mkt-active-row .row-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.mkt-active-row .name { font-size: 14px; font-weight: 700; color: var(--ink); }
/* Status .name (es. "Livello OK/basso" nel Riepilogo Resti): le utility u-c-* da sole
   perdono per specificita' contro ".mkt-active-row .name". Override scoped → vince il colore stato. */
.mkt-active-row .name.u-c-ok { color: var(--ok); }
.mkt-active-row .name.u-c-warn { color: var(--warn); }
/* Badge promo importata da Bloomest (sola lettura) + raggruppamento col nome */
.name-group { display: flex; align-items: center; gap: 6px; min-width: 0; }
.name-group .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.badge-external { flex-shrink: 0; font-size: 10px; font-weight: 700; padding: 2px 8px;
                  border-radius: 999px; background: #EDE9FE; color: #5B21B6; }
.mkt-active-row .days-left { font-size: 12px; color: var(--ink-3); font-weight: 600; }
.mkt-active-row > .chev-right,
.create-alt-tile > .chev-right,
.cat-card > .chev-right { flex-shrink: 0; color: var(--ink-3); width: 20px; height: 20px; }
.mkt-active-row:hover > .chev-right,
.create-alt-tile:hover > .chev-right,
.cat-card:hover > .chev-right { color: var(--brand); }
.mkt-active-row .row-meta { display: flex; gap: 12px; font-size: 12px; color: var(--ink-2); }
.mkt-active-row .row-meta .lift-up { color: var(--ok); font-weight: 700; }
.mkt-active-row .row-meta .lift-down { color: var(--danger); font-weight: 700; }
.mkt-progress-bar { height: 4px; background: var(--bg); border-radius: 999px; overflow: hidden; }
.mkt-progress-bar > div { height: 100%; background: linear-gradient(90deg, var(--brand) 0%, var(--brand-dark) 100%); border-radius: 999px; }

/* === FASE 2 lifecycle — sezioni Campagne (in corso/in pausa/bozze) + Storico === */
.mkt-section { margin-bottom: 8px; }
.mkt-section-h { padding: 10px var(--page-pad-x) 6px; font-size: 12px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.05em; }
.pill-paused { background: #FFF3E0; color: var(--warn); }
.pill-draft { background: var(--bg); color: var(--ink-3); }
.pill-measured { background: #E8F8EE; color: var(--ok); }
.pill-pending { background: var(--bg); color: var(--ink-3); }
.mkt-card-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.row-act { font-size: 13px; font-weight: 600; color: var(--brand); background: transparent; border: 0; padding: 0; cursor: pointer; text-decoration: none; }
.row-act:hover { text-decoration: underline; }
.row-act-danger { color: var(--danger); }
.mkt-active-row .row-reactivate { color: var(--brand); font-weight: 600; font-size: 13px; flex-shrink: 0; white-space: nowrap; }
.mkt-summary-strip { margin: 0 var(--page-pad-x) 10px; padding: 10px 14px; background: var(--brand-soft); color: var(--brand); border-radius: 10px; font-size: 13px; font-weight: 700; }
/* Storico: <details> nativo per il drill-down (no JS) */
.storico-row { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 0 18px 2px; }
.storico-row-head { display: flex; align-items: center; gap: 12px; padding: 14px 0; cursor: pointer; list-style: none; }
.storico-row-head::-webkit-details-marker { display: none; }
.storico-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.storico-row-title { display: flex; align-items: center; gap: 8px; min-width: 0; }
.storico-row-head .name { min-width: 0; font-size: 14px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.storico-meta { font-size: 12px; color: var(--ink-3); }
.storico-analisi { flex-shrink: 0; display: inline-flex; align-items: center; gap: 5px; font-size: 13px; font-weight: 600; color: var(--brand); line-height: 1; }
.storico-analisi svg { width: 16px; height: 16px; display: block; transition: transform 150ms ease; }
.storico-row[open] .storico-analisi svg { transform: rotate(45deg); }
.storico-row[open] .storico-row-head { border-bottom: 1px solid var(--line); }

.mkt-cta-free { margin: 18px var(--page-pad-x) 8px; padding: 14px; border: 1px dashed var(--line); border-radius: 12px; background: transparent; color: var(--ink-2); font-weight: 600; display: flex; align-items: center; justify-content: center; gap: 8px; cursor: pointer; font-size: 14px; width: calc(100% - 36px); }
.mkt-cta-free:hover { border-color: var(--brand); color: var(--brand); }
@media (min-width: 768px) { .mkt-cta-free { margin: 18px var(--page-pad-x) 16px; width: calc(100% - 36px); } }

/* === Gerarchia Promo (2026-06-18) === */
/* L4 · azione di pagina nell'header (visibile desktop+mobile, vs .hdr-action mobile-only) */
.page-action { display: inline-flex; align-items: center; align-self: center; gap: 6px; margin-left: 12px; padding: 6px 14px; border: 1px solid var(--brand); border-radius: 999px; background: transparent; color: var(--brand); font-size: 13px; font-weight: 700; cursor: pointer; transition: background 120ms ease, transform 80ms ease; }
.page-action:hover { background: var(--brand-soft); }
.page-action:active { transform: scale(0.97); }
.page-action svg { width: 14px; height: 14px; flex-shrink: 0; }
/* Variante "link": stesso colore/icona ma senza pillola (bordo+padding), per
   azioni header secondarie come "Comunica" accanto al titolo Promo. */
.page-action.page-action-link { border: 0; padding: 4px 2px; align-self: flex-end; }
.page-action.page-action-link:hover { background: transparent; opacity: 0.7; }

/* L3 · azione testuale a destra del section-title (es. refresh "Aggiorna") */
.section-title button.sec-action { display: inline-flex; align-items: center; gap: 6px; background: transparent; border: 0; padding: 0; cursor: pointer; color: var(--brand); font-size: 13px; font-weight: 600; text-transform: none; letter-spacing: 0; transition: opacity 120ms ease; }
.section-title button.sec-action:hover { opacity: 0.7; }
.section-title button.sec-action:active { transform: scale(0.96); }
.section-title button.sec-action svg { width: 14px; height: 14px; flex-shrink: 0; }

/* L2 · "Altri modi di creare": 2 tile secondarie neutre, distinte da goal-card (colorate) e dal vecchio ghost tratteggiato */
.mkt-create-alt { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; padding: 0 var(--page-pad-x) 8px; }
.create-alt-tile { display: flex; width: 100%; align-items: center; gap: 12px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); color: inherit; text-decoration: none; text-align: left; cursor: pointer; transition: border-color 120ms ease, transform 80ms ease; }
.create-alt-tile:hover { border-color: var(--brand); }
.create-alt-tile:active { transform: scale(0.98); }
.create-alt-tile > svg { width: 22px; height: 22px; flex-shrink: 0; color: var(--ink-2); transition: color 120ms ease; }
.create-alt-tile:hover > svg { color: var(--brand); }
.create-alt-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.create-alt-title { font-size: 14px; font-weight: 700; color: var(--ink); }
/* Descrittore "chi …" su riga propria sotto il titolo (peso normale, attenuato):
   prima era inline nel titolo a 700 e si confondeva col grassetto. */
.create-alt-desc { font-size: 13px; font-weight: 400; color: var(--ink-2); }
.create-alt-sub { font-size: 12px; color: var(--ink-3); }
@media (max-width: 560px) { .mkt-create-alt { grid-template-columns: 1fr; } }

/* Proposals screen */
/* Back link pattern globale — icon-button quadrato + label inline.
   Riutilizzabile in ogni sub-page (Promo proposals/detail/wizard, modali,
   ecc.). Niente underline, hover anima icona + label verso il brand. */
.back-link { display: inline-flex; align-items: center; gap: 10px; padding: 14px var(--page-pad-x) 6px; color: var(--ink-2); font-size: 14px; font-weight: 600; text-decoration: none; background: none; border: none; cursor: pointer; }
.back-link .back-icon { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 10px; background: var(--bg); color: var(--ink-2); transition: background 120ms ease, color 120ms ease, transform 120ms ease; flex-shrink: 0; }
.back-link .back-icon .i { width: 18px; height: 18px; stroke-width: 2.2; }
.back-link:hover { color: var(--brand); }
.back-link:hover .back-icon { background: var(--brand-soft); color: var(--brand); transform: translateX(-2px); }
.back-link:focus-visible { outline: none; }
.back-link:focus-visible .back-icon { box-shadow: 0 0 0 3px var(--brand-soft); }
@media (min-width: 768px) { .back-link { padding: 18px var(--page-pad-x) 8px; } .back-link .back-icon { width: 40px; height: 40px; } .back-link .back-icon .i { width: 20px; height: 20px; } }

.mkt-proposal { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; margin: 12px var(--page-pad-x); display: flex; flex-direction: column; gap: 12px; }
@media (min-width: 768px) { .mkt-proposal { margin: 14px var(--page-pad-x); padding: 20px; } }
.mkt-proposal .head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.mkt-proposal .head h3 { font-size: 16px; font-weight: 700; color: var(--ink); line-height: 1.25; }
.mkt-proposal .mech { font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.mkt-proposal .kpi-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; padding: 12px; background: var(--bg); border-radius: 12px; }
.mkt-proposal .kpi { display: flex; flex-direction: column; gap: 2px; }
.mkt-proposal .kpi .lbl { font-size: 11px; color: var(--ink-3); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.mkt-proposal .kpi .val { font-size: 15px; font-weight: 700; color: var(--ink); }
.mkt-proposal .kpi.lift .val { color: var(--ok); }
.mkt-proposal .needs { background: #FEF3C7; border-left: 3px solid var(--warn); padding: 10px 12px; border-radius: 6px; font-size: 12px; color: #78350F; }
.mkt-proposal .actions { display: flex; gap: 8px; }
.mkt-proposal .actions > * { flex: 1; }
/* Campaign detail — timeline milestone */
.mkt-detail-head { padding: 16px var(--page-pad-x); }
@media (min-width: 768px) { .mkt-detail-head { padding: 18px var(--page-pad-x); } }
.mkt-detail-head h2 { font-size: 20px; font-weight: 800; letter-spacing: -0.02em; color: var(--ink); margin-bottom: 6px; }
.mkt-detail-head .meta { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; font-size: 13px; color: var(--ink-2); }
.mkt-detail-head .status-pill { background: var(--ok); color: #fff; padding: 3px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
.mkt-detail-head .status-pill.done { background: var(--ink-3); }

.timeline { display: flex; align-items: center; padding: 0 var(--page-pad-x) 8px; gap: 0; position: relative; }
@media (min-width: 768px) { .timeline { padding: 0 var(--page-pad-x) 12px; } }
.timeline .ms { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; position: relative; }
.timeline .ms .dot { width: 14px; height: 14px; border-radius: 50%; background: var(--line); border: 2px solid var(--surface); z-index: 2; }
.timeline .ms.done .dot { background: var(--ok); }
.timeline .ms.current .dot { background: var(--brand); box-shadow: 0 0 0 4px var(--brand-soft); }
.timeline .ms.future .dot { background: var(--surface); border: 2px solid var(--line); }
.timeline .ms .lbl { font-size: 11px; font-weight: 700; color: var(--ink-2); text-align: center; line-height: 1.2; }
.timeline .ms .date { font-size: 10px; color: var(--ink-3); }
.timeline .seg { flex: 1; height: 2px; background: var(--line); margin-top: -22px; }
.timeline .seg.done { background: var(--ok); }

.milestone-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; margin: 10px var(--page-pad-x); }
@media (min-width: 768px) { .milestone-card { margin: 12px var(--page-pad-x); padding: 20px; } }
.milestone-card .ms-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; gap: 10px; }
.milestone-card .ms-head h4 { font-size: 15px; font-weight: 700; color: var(--ink); }
.milestone-card .ms-head .ms-status { font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 999px; text-transform: uppercase; letter-spacing: 0.04em; }
.milestone-card .ms-head .ms-status.done { background: #D1FAE5; color: #065F46; }
.milestone-card .ms-head .ms-status.future { background: var(--bg); color: var(--ink-3); }
.milestone-card .ms-rows { display: flex; flex-direction: column; gap: 8px; }
.milestone-card .ms-row { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; padding: 6px 0; border-bottom: 1px dashed var(--line); }
.milestone-card .ms-row:last-child { border-bottom: none; }
.milestone-card .ms-row .lbl { color: var(--ink-2); }
.milestone-card .ms-row .val { color: var(--ink); font-weight: 700; }
.milestone-card .ms-row .val.up { color: var(--ok); }
.milestone-card .ms-row .val.down { color: var(--danger); }
.milestone-card .ms-suggest { margin-top: 10px; padding: 10px 12px; border-radius: 8px; font-size: 13px; font-weight: 600; display: flex; align-items: flex-start; gap: 6px; }
.milestone-card .ms-suggest.go { background: #D1FAE5; color: #065F46; }
.milestone-card .ms-suggest.stop { background: #FEE2E2; color: #7F1D1D; }
.milestone-card .ms-suggest.expand { background: #DBEAFE; color: #1E3A8A; }
.milestone-card .ms-suggest.launch { background: #DBEAFE; color: #1E3A8A; }
.milestone-card .ms-head .ms-status.current { background: #DBEAFE; color: #1E3A8A; }
.milestone-card .ms-future-note { font-size: 12px; color: var(--ink-3); line-height: 1.5; padding: 8px 0; }

/* ===== Modal Macchina (gear → cambio stato) ===== */
.modal-machine-head { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 14px; }
.modal-machine-head h3 { font-size: 18px; font-weight: 800; letter-spacing: -0.02em; margin: 0; }
.modal-machine-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 16px; padding-top: 12px; }
.modal-machine-actions .btn-primary,
.modal-machine-actions .btn-secondary { width: 100%; }

/* Backdrop: assicura overlay full-screen centrato (era modal-overlay) */
.modal-backdrop { position: fixed; inset: 0; }
.modal-backdrop.open { z-index: 100; }

/* =========================================================
   Utility classes (dashboard) — sostituiscono inline style
   Prefisso .u- per chiarezza; usati nei template Django
   ========================================================= */

/* Display */
.u-hidden { display: none; }
.az-step--off { display: none; }
.u-block { display: block; }
.u-flex { display: flex; }
.u-inline-flex { display: inline-flex; }
.u-grid { display: grid; }

/* Flex */
.u-flex-col { flex-direction: column; }
.u-flex-wrap { flex-wrap: wrap; }
.u-flex-1 { flex: 1; }
.u-flex-2 { flex: 2; }
.u-flex-0-90 { flex: 0 0 90px; }
.u-flex-0-100 { flex: 0 0 100px; }
.u-flex-0-140 { flex: 0 0 140px; }
.u-flex-0-180 { flex: 0 0 180px; }
.u-flex-0-220 { flex: 0 0 220px; }
.u-flex-min-140 { flex: 1; min-width: 140px; }
.u-flex-min-140-danger { flex: 1; min-width: 140px; color: var(--danger); border-color: var(--danger); }

/* Alignment */
.u-items-center { align-items: center; }
.u-items-start { align-items: flex-start; }
.u-items-end { align-items: flex-end; }
.u-justify-between { justify-content: space-between; }
.u-justify-center { justify-content: center; }
.u-text-center { text-align: center; }

/* Gap */
.u-gap-4 { gap: 4px; }
.u-gap-6 { gap: 6px; }
.u-gap-8 { gap: 8px; }
.u-gap-10 { gap: 10px; }
.u-gap-12 { gap: 12px; }

/* Width */
.u-w-full { width: 100%; }
.u-w-50 { width: 50%; }
.u-w-icon-12 { width: 12px; height: 12px; color: var(--brand); }

/* Max-width */
.u-mw-140 { max-width: 140px; }
.u-mw-160 { max-width: 160px; }
.u-mw-200 { max-width: 200px; }
.u-mw-260 { max-width: 260px; }
.u-mw-280 { max-width: 280px; }
.u-mw-320 { max-width: 320px; }
.u-mw-420 { max-width: 420px; }
.u-mw-520 { max-width: 520px; }
.u-mw-540 { max-width: 540px; }
.u-mw-560 { max-width: 560px; }
.u-mw-580 { max-width: 580px; }
.u-mw-600 { max-width: 600px; }
.u-mw-640 { max-width: 640px; }

/* Margin */
.u-m-0 { margin: 0; }
.u-mt-8 { margin-top: 8px; }
.u-mt-10 { margin-top: 10px; }
.u-mt-12 { margin-top: 12px; }
.u-mt-14 { margin-top: 14px; }
.u-mt-18 { margin-top: 18px; }
.u-mb-6 { margin-bottom: 6px; }
.u-mb-8 { margin-bottom: 8px; }
.u-mb-10 { margin-bottom: 10px; }
.u-mb-14 { margin-bottom: 14px; }
.u-mb-18 { margin-bottom: 18px; }
.u-mr-6 { margin-right: 6px; }
.u-ml-auto { margin-left: auto; }
.u-ml-6 { margin-left: 6px; }
.u-mx-18-mt-10 { margin: 10px 18px 0; }
.u-mx-18-mt-12 { margin: 12px 18px 0; }
.u-mx-18-mt-14 { margin: 14px 18px 0; }
.u-px-page { padding-left: var(--page-pad-x); padding-right: var(--page-pad-x); }
.u-mx-18-mt-24 { margin: 24px 18px; color: var(--ink-3); font-size: 14px; }
.u-mx-18-mt-24-plain { margin: 24px 18px; }
.u-m-0-0-14 { margin: 0 0 14px; }
.u-m-0-0-16 { margin: 0 0 16px; }
.u-m-0-0-18 { margin: 0 0 18px; }
.u-m-18-0-8 { margin: 18px 0 8px; }

/* Padding */
.u-p-0 { padding: 0; }
.u-pt-8 { padding-top: 8px; }
.u-pb-14 { padding-bottom: 14px; color: var(--ink-3); }
.u-p-8-14 { padding: 8px 14px; }
.u-p-4-10 { padding: 4px 10px; font-size: 13px; }

/* Position */
.u-pos-absolute { position: absolute; }
.u-left-14 { left: 14px; }

/* Z-index */
.u-z-40 { z-index: 40; }
.u-z-40-hidden { z-index: 40; display: none; }
.u-z-60-hidden { z-index: 60; display: none; }

/* Cursor */
.u-cursor-pointer { cursor: pointer; }

/* Background */
.u-bg-soft { background: var(--bg); }
.u-bg-soft-radius { background: var(--bg); border-radius: 10px; padding: 10px; }
.u-bg-soft-pad { padding: 12px 14px; border-radius: 10px; border: 1px solid var(--line); }
.u-bg-soft-pad-mb { padding: 12px 14px; border-radius: 10px; border: 1px solid var(--line); margin-bottom: 8px; }
.u-bg-soft-pad-mb-14 { padding: 12px 14px; border-radius: 10px; border: 1px solid var(--line); margin-bottom: 14px; cursor: pointer; }
.u-bg-soft-mono { background: var(--bg); font-family: ui-monospace, monospace; }
.u-bg-soft-ink-3 { background: var(--bg); color: var(--ink-3); }
.u-bg-soft-ink-3-12 { background: var(--bg); color: var(--ink-3); font-size: 12px; }
.u-bg-brand-warn { background: #FFF3E0; color: var(--warn); }
.u-bg-brand-danger { background: #FCE4E4; color: var(--danger); }
.u-bg-brand-soft-pink { background: #FDE7EA; color: var(--brand); }
.u-bg-brand-card { background: var(--brand-soft); border-radius: 12px; padding: 14px; margin-bottom: 14px; }
.u-bg-soft-card { background: var(--bg); border-radius: 12px; padding: 14px; margin-bottom: 14px; }

/* Color */
.u-c-ink { color: var(--ink); }
.u-c-ink-3 { color: var(--ink-3); }
.u-c-ink-3-ml-6 { color: var(--ink-3); margin-left: 6px; }
.u-c-brand { color: var(--brand); }
.u-c-ok { color: var(--ok); }
.u-c-warn { color: var(--warn); }
.u-c-danger { color: var(--danger); }

/* Typography */
.u-fs-10 { font-size: 10px; }
.u-fs-11 { font-size: 11px; }
.u-fs-12 { font-size: 12px; }
.u-fs-13 { font-size: 13px; }
.u-fs-14 { font-size: 14px; }
.u-fs-16 { font-size: 16px; }
.u-fs-18-b { font-size: 18px; font-weight: 800; }
.u-fw-600 { font-weight: 600; }
.u-fw-700 { font-weight: 700; }
.u-mono { font-family: ui-monospace, monospace; letter-spacing: 0.08em; }
.u-mono-b { font-family: ui-monospace, monospace; font-size: 16px; font-weight: 700; }
/* color: inherit -> il link "Gestisci" eredita il rosso di .u-note-danger invece
   di cadere sul blu <a> di default del browser. Resta riconoscibile come link
   per bold + underline. */
.u-underline-b { font-weight: 700; text-decoration: underline; color: inherit; }

/* Section heading (label/eyebrow) */
.u-eyebrow { font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; }
.u-eyebrow-600 { font-size: 11px; font-weight: 600; color: var(--ink-3); text-transform: uppercase; }
.u-eyebrow-mb-6 { font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 6px; }
.u-eyebrow-block { font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; display: block; margin-bottom: 8px; }
.u-section-title { font-size: 13px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 10px; }
.u-card-title { font-size: 14px; font-weight: 700; margin-bottom: 10px; }
.u-card-title-ink { font-size: 14px; font-weight: 700; margin-bottom: 10px; color: var(--ink); }
.u-card-title-flat { font-size: 14px; font-weight: 700; }

/* Opacity */
.u-opacity-55 { opacity: 0.55; }

/* SVG / icon vertical alignment helpers */
.u-svg-mid { vertical-align: middle; }
.u-svg--2 { vertical-align: -2px; }
.u-svg--3 { vertical-align: -3px; }
.u-svg--3-mr-6-ink-3 { vertical-align: -3px; margin-right: 6px; color: var(--ink-3); }
.u-svg--3-mr-6 { vertical-align: -3px; margin-right: 6px; }
.u-svg--4-mr-6-brand { vertical-align: -4px; margin-right: 6px; color: var(--brand); }
.u-svg--4-mr-6-danger { vertical-align: -4px; margin-right: 6px; color: var(--danger, #d83a3a); }
.u-svg-flip { transform: scaleX(-1); }
.u-svg-stroke-white { stroke: #fff; }

/* Borders */
.u-border-top { border-top: 1px solid var(--line); }

/* Layout composites */
.u-row-between { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.u-row-gap-12 { display: flex; gap: 12px; }
.u-row-gap-12-wrap { display: flex; gap: 12px; flex-wrap: wrap; }
.u-row-form-end { display: flex; gap: 12px; align-items: flex-end; margin-bottom: 8px; }
.u-row-form-end-14 { display: flex; gap: 12px; align-items: flex-end; margin-bottom: 14px; }
.u-row-start { display: flex; align-items: flex-start; gap: 10px; }
.u-row-gap-8 { display: flex; gap: 8px; }
.u-row-gap-8-mt-6 { display: flex; gap: 8px; margin-top: 6px; }
.u-row-gap-8-mt-12 { display: flex; gap: 8px; margin-top: 12px; }
.u-row-gap-8-mt-14 { display: flex; gap: 8px; margin-top: 14px; }
.u-row-gap-8-pad-wrap { display: flex; gap: 8px; padding: 16px; flex-wrap: wrap; }
.u-col-gap-8 { display: flex; flex-direction: column; gap: 8px; }
.u-pad-col-gap-8 { padding: 0 18px; display: flex; flex-direction: column; gap: 8px; }
.u-grid-3-gap-8 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 14px; }
.u-grid-fullcol-empty { grid-column: 1/-1; color: var(--ink-3); font-size: 14px; }

/* Empty state */
.u-empty-soft { text-align: center; padding: 30px 20px; background: var(--bg); border-radius: 10px; color: var(--ink-3); font-size: 14px; }
.u-empty-plain { text-align: center; padding: 32px 14px; color: var(--ink-3); font-size: 13px; }

/* Note bubble (info panel inside pane) */
.u-note { margin: 14px 0 4px; padding: 12px 14px; background: var(--brand-soft); border-radius: 10px; font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.u-note-2 { margin: 10px 0 4px; padding: 12px 14px; background: var(--brand-soft); border-radius: 10px; font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.u-note-stack { background: var(--brand-soft); border-radius: 10px; padding: 12px; margin: 8px 0 14px; font-size: 12px; color: var(--ink-2); line-height: 1.5; }

/* Hopper banner gradients (andamento_pane_hopper) */
.u-hopper-ok { background: linear-gradient(135deg, var(--ok) 0%, #138A3F 100%); }
.u-hopper-warn { background: linear-gradient(135deg, var(--warn) 0%, #B8721A 100%); }

/* Lang option (impostazioni_modal_lingua) */
.u-lang-opt { display: flex; align-items: center; gap: 12px; padding: 14px; border: 1.5px solid var(--line); border-radius: 10px; background: transparent; cursor: pointer; }
.u-lang-opt.is-current { border-color: var(--brand); background: var(--brand-soft); }
.u-note-inline-pad { margin: 8px 18px; color: var(--ink-3); font-size: 13px; }
.u-note-info-blue { margin: 14px 18px 0; padding: 12px 14px; background: #DEEBF6; border: 1px solid #B5D2E9; border-radius: 10px; font-size: 12px; color: #2C5577; line-height: 1.5; }
.u-note-danger { margin: 14px 18px 0; background: #FEE2E2; border-color: #FCD3D3; color: var(--danger); }

/* Misc inline-positioned */
.u-pad-12 { padding: 12px; }
.u-ta-center { text-align: center; }
.u-pad-soft-ink { padding: 16px; color: var(--ink-3); font-size: 13px; }
.u-pad-soft-ink-14 { padding: 14px; color: var(--ink-3); font-size: 13px; }
.u-pad-soft-ink-12 { color: var(--ink-3); font-size: 12px; padding: 14px; }
.u-meta-note { font-size: 12px; color: var(--ink-3); margin-top: 14px; padding: 10px 14px; background: var(--bg); border-radius: 10px; line-height: 1.5; }
.u-meta-note-sm { font-size: 12px; color: var(--ink-3); margin-top: 4px; line-height: 1.45; }
.u-meta-note-sm.fatture-disclaimer { font-size: 14px; line-height: 1.55; margin-top: 18px; }
.u-help-text { margin-top: 8px; color: var(--ink-2); font-size: 13px; }
/* Requisiti nuova password (credenziali gestore): checklist live, spunta verde = requisito ok */
.pw-req { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 5px; }
.pw-req li { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-3); }
.pw-req .pw-req-ico { color: var(--line); flex-shrink: 0; transition: color 120ms ease; }
.pw-req li.ok { color: var(--ink-2); }
.pw-req li.ok .pw-req-ico { color: var(--ok); }

/* Formazione KB (Impostazioni → Formazione & guide): indice riuso .list-group
   dentro un modal (no margini pagina, no shadow) + tipografia del corpo articolo. */
.list-group--in-modal { margin: 0; box-shadow: none; border: 1px solid var(--line); }
.kb-article { font-size: 14px; line-height: 1.6; color: var(--ink); }
.kb-article > :first-child { margin-top: 0; }
.kb-article h4 { font-size: 15px; font-weight: 700; margin: 16px 0 6px; color: var(--ink); }
.kb-article p { margin: 0 0 10px; }
.kb-article ul, .kb-article ol { margin: 0 0 10px; padding-left: 20px; }
.kb-article li { margin-bottom: 4px; }
.kb-article strong { font-weight: 600; }
.kb-article .kb-tip { background: var(--brand-soft); color: var(--ink); border-radius: 10px; padding: 10px 12px; margin: 12px 0 0; font-size: 13px; }
.u-text-body { font-size: 13px; color: var(--ink); line-height: 1.5; }
.u-row-strong { display: flex; align-items: center; justify-content: space-between; }
.u-w100-mb-14 { width: 100%; margin-bottom: 14px; }
.u-w100-mb-18 { width: 100%; margin-bottom: 18px; }
.u-pad-0-mb-14 { padding: 0; margin-bottom: 14px; }
.u-accent-brand { accent-color: var(--brand); }

/* Pill / badge */
.u-pill-sm { font-size: 11px; padding: 5px 10px; text-transform: none; letter-spacing: 0; font-weight: 700; }
.u-pill-md { font-size: 12px; padding: 6px 12px; display: inline-flex; align-items: center; gap: 4px; }
.u-pill-brand-flat { color: var(--brand); text-transform: none; letter-spacing: 0; font-size: 13px; }
.u-pill-brand-fw { color: var(--brand); font-weight: 600; text-transform: none; letter-spacing: 0; }
.u-pill-warn-fw { color: var(--warn); font-weight: 600; text-transform: none; letter-spacing: 0; }

/* Icon + text helpers */
.u-brand-icon-top { color: var(--brand); flex-shrink: 0; margin-top: 2px; }
.u-ml-auto-brand { margin-left: auto; color: var(--brand); }
.u-mr-6-svg--3 { margin-right: 6px; vertical-align: -3px; }
.u-c-ink-3-13 { color: var(--ink-3); font-size: 13px; }
/* Nota inline accanto al conteggio raggiungibili nel composer: stessa size/case
   del pill (non eredita l'uppercase/spacing dell'eyebrow contenitore). */
.reach-note { text-transform: none; letter-spacing: 0; font-weight: 400; font-size: 13px; color: var(--ink-3); }
.u-c-ink-3-400 { color: var(--ink-3); font-weight: 400; }
.u-c-ink-3-fw { color: var(--ink-3); font-weight: 400; }
.u-c-ok-light { color: var(--ok); }
.u-block-center { display: block; margin: 0 auto 8px; }

/* Progress bar (width:0% used for js fill) */
.u-bar-empty { width: 0%; }
.u-bar-half { width: 50%; }

/* Bar heights 0-100% for kpi day-bar chart (riepilogo) */
.bar-h-0 { height: 0%; } .bar-h-1 { height: 1%; } .bar-h-2 { height: 2%; } .bar-h-3 { height: 3%; } .bar-h-4 { height: 4%; } .bar-h-5 { height: 5%; } .bar-h-6 { height: 6%; } .bar-h-7 { height: 7%; } .bar-h-8 { height: 8%; } .bar-h-9 { height: 9%; } .bar-h-10 { height: 10%; } .bar-h-11 { height: 11%; } .bar-h-12 { height: 12%; } .bar-h-13 { height: 13%; } .bar-h-14 { height: 14%; } .bar-h-15 { height: 15%; } .bar-h-16 { height: 16%; } .bar-h-17 { height: 17%; } .bar-h-18 { height: 18%; } .bar-h-19 { height: 19%; } .bar-h-20 { height: 20%; } .bar-h-21 { height: 21%; } .bar-h-22 { height: 22%; } .bar-h-23 { height: 23%; } .bar-h-24 { height: 24%; } .bar-h-25 { height: 25%; } .bar-h-26 { height: 26%; } .bar-h-27 { height: 27%; } .bar-h-28 { height: 28%; } .bar-h-29 { height: 29%; } .bar-h-30 { height: 30%; } .bar-h-31 { height: 31%; } .bar-h-32 { height: 32%; } .bar-h-33 { height: 33%; } .bar-h-34 { height: 34%; } .bar-h-35 { height: 35%; } .bar-h-36 { height: 36%; } .bar-h-37 { height: 37%; } .bar-h-38 { height: 38%; } .bar-h-39 { height: 39%; } .bar-h-40 { height: 40%; } .bar-h-41 { height: 41%; } .bar-h-42 { height: 42%; } .bar-h-43 { height: 43%; } .bar-h-44 { height: 44%; } .bar-h-45 { height: 45%; } .bar-h-46 { height: 46%; } .bar-h-47 { height: 47%; } .bar-h-48 { height: 48%; } .bar-h-49 { height: 49%; } .bar-h-50 { height: 50%; } .bar-h-51 { height: 51%; } .bar-h-52 { height: 52%; } .bar-h-53 { height: 53%; } .bar-h-54 { height: 54%; } .bar-h-55 { height: 55%; } .bar-h-56 { height: 56%; } .bar-h-57 { height: 57%; } .bar-h-58 { height: 58%; } .bar-h-59 { height: 59%; } .bar-h-60 { height: 60%; } .bar-h-61 { height: 61%; } .bar-h-62 { height: 62%; } .bar-h-63 { height: 63%; } .bar-h-64 { height: 64%; } .bar-h-65 { height: 65%; } .bar-h-66 { height: 66%; } .bar-h-67 { height: 67%; } .bar-h-68 { height: 68%; } .bar-h-69 { height: 69%; } .bar-h-70 { height: 70%; } .bar-h-71 { height: 71%; } .bar-h-72 { height: 72%; } .bar-h-73 { height: 73%; } .bar-h-74 { height: 74%; } .bar-h-75 { height: 75%; } .bar-h-76 { height: 76%; } .bar-h-77 { height: 77%; } .bar-h-78 { height: 78%; } .bar-h-79 { height: 79%; } .bar-h-80 { height: 80%; } .bar-h-81 { height: 81%; } .bar-h-82 { height: 82%; } .bar-h-83 { height: 83%; } .bar-h-84 { height: 84%; } .bar-h-85 { height: 85%; } .bar-h-86 { height: 86%; } .bar-h-87 { height: 87%; } .bar-h-88 { height: 88%; } .bar-h-89 { height: 89%; } .bar-h-90 { height: 90%; } .bar-h-91 { height: 91%; } .bar-h-92 { height: 92%; } .bar-h-93 { height: 93%; } .bar-h-94 { height: 94%; } .bar-h-95 { height: 95%; } .bar-h-96 { height: 96%; } .bar-h-97 { height: 97%; } .bar-h-98 { height: 98%; } .bar-h-99 { height: 99%; } .bar-h-100 { height: 100%; }

/* Semantic color modifiers for metric rows (row.color → class via template if/elif) */
.u-row-c-brand { color: var(--brand); }
.u-row-c-ok { color: var(--ok); }
.u-row-c-warn { color: var(--warn); }
.u-row-c-danger { color: var(--danger); }

/* ===== Chip / filter-pill: nessuna sottolineatura (anche se sono <a>) ===== */
.chip, .filter-pill, .sub-chip { text-decoration: none; color: inherit; }
.chip:hover, .filter-pill:hover, .sub-chip:hover { text-decoration: none; }

/* Lavatrici/Asciugatrici usano la regola globale .section-title (stessa di Andamento/Impostazioni/Domotica) */

/* ===== Modal Macchina · field-row e modal-pane attivo (compl. al toggle JS) ===== */
.field-row { display: flex; gap: 12px; margin-bottom: 12px; }
.field-row .field { flex: 1; }
.modal-pane.active { display: block; }

/* ===== Macchina card: cliente row + hopper info + program info ===== */
.machine-card .meta-line { display: flex; justify-content: space-between; align-items: center; font-size: 11px; color: var(--ink-3); margin-top: 8px; padding: 0 16px 12px; }
.machine-card .meta-line .meta-left { font-weight: 600; }
.machine-card .meta-line .meta-right { color: var(--ink-3); }

/* Background/padding/radius utility per row interne ai modal (mockup pattern) */
.u-bg-pad-radius { background: var(--bg); padding: 12px 14px; border-radius: 10px; margin-bottom: 8px; }

/* ===== Goal card e mkt-cta-free ora <a>: rimuovi underline ===== */
a.goal-card, a.mkt-cta-free { color: inherit; text-decoration: none; }
a.goal-card:hover, a.mkt-cta-free:hover { text-decoration: none; }

/* ===== DOB widget dentro modal cliente (cust-pane) =====
   1. Trigger compatto (lukew: proporzionato al contenuto "12 Giugno 1982").
   2. Telefono prende lo spazio rimanente, DOB resta auto-width.
   3. Popover ancorato a destra: cust-pane ha overflow-y:auto che implica
      overflow-x:clip, quindi un popover left:0 esce e viene tagliato. */
.cust-pane .dt-field { width: auto; }
.cust-pane .dt-trigger {
  width: auto;
  min-width: 200px;
  background: var(--surface);
  text-align: left;
}
.cust-pane .dt-trigger .dt-display { text-align: left; }
.cust-pane .dt-popover { left: auto; right: 0; }

/* Link inline brand (no underline) dentro note descrittive del modal cliente */
.cust-pane .u-meta-note-sm a { color: var(--brand); text-decoration: none; font-weight: 600; }
.cust-pane .u-meta-note-sm a:hover { text-decoration: underline; }

/* Re-invio magic-link: link di testo brand sotto l'email (stile .oggi-azioni-all
   "Vedi tutte le azioni"), niente riga bordata né icona. */
.resend-magiclink-link {
  display: inline-block;
  margin-top: 8px;
  padding: 0;
  border: 0;
  background: none;
  font-size: 13px;
  font-weight: 600;
  color: var(--brand);
  cursor: pointer;
}
.resend-magiclink-link:hover { color: var(--brand-hover); text-decoration: underline; }

/* ===== Profilo cliente (modal): field-system allineato 1:1 al form "Dati
   personali" dell'app cliente (.form-screen). Scoped al pane Profilo per non
   toccare gli altri tab/modali che usano .field-row flex + .field--w-* a pixel
   della dashboard. Larghezze percentuali su campi standalone, righe a colonne. */
.cust-pane [data-cpane="profile"] .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; }
.cust-pane [data-cpane="profile"] .field-row .field { margin-bottom: 18px; min-width: 0; }
/* min-width:0 anche sugli input: in grid hanno min-width intrinseca (~20 char) che
   i track fr non comprimono → la riga CAP/Città/Prov deborderebbe (Prov tagliata). */
.cust-pane [data-cpane="profile"] .field input, .cust-pane [data-cpane="profile"] .field select { min-width: 0; }
.cust-pane [data-cpane="profile"] .field-row--phone-dob { grid-template-columns: 1fr 50%; }  /* Data nascita 50% (col mese corto ci sta); Telefono prende il resto */
.cust-pane [data-cpane="profile"] .field-row--loc { grid-template-columns: 3fr 5fr 2fr; }    /* CAP 30 · Città 50 · Prov 20 */
.cust-pane [data-cpane="profile"] .field-row--loc:has([data-b2b-province].u-hidden) { grid-template-columns: 3fr 7fr; }
.cust-pane [data-cpane="profile"] .field-row--loc label { white-space: nowrap; }
.cust-pane [data-cpane="profile"] .field--w-30 { width: 30%; min-width: 110px; }
.cust-pane [data-cpane="profile"] .field--w-40 { width: 40%; min-width: 140px; }
.cust-pane [data-cpane="profile"] .field--w-50 { width: 50%; min-width: 170px; }  /* vero 50% dove c'è spazio; 170px = minimo per non tagliare "Scegli il Paese" */
.cust-pane [data-cpane="profile"] .field--w-60 { width: 60%; min-width: 170px; }
.cust-pane [data-cpane="profile"] .field--w-80 { width: 80%; min-width: 200px; }
/* DOB nella colonna 50% della riga: lascia riempire la cella (no min-width 200px). */
.cust-pane [data-cpane="profile"] .dt-trigger { min-width: 0; }

/* Sezioni Gruppi di sistema / manuali: la classe .section-title fa già tutto,
   bastano un paio di tweak per strong inline + bottone allineato. */
.section-title strong { color: var(--ink); font-weight: 800; }

/* ===== Modal "Aggiungi a campagna" · righe campagna selezionabili (radio) ===== */
.promo-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; margin-bottom: 8px; cursor: pointer; transition: border-color 120ms ease, background 120ms ease; }
.promo-row:hover { border-color: var(--brand); background: var(--brand-soft); }
.promo-row:has(input[type="radio"]:checked) { border-color: var(--brand); background: var(--brand-soft); }
.promo-row input[type="radio"] { margin: 0; flex-shrink: 0; accent-color: var(--brand); }
.promo-row-ico { width: 40px; height: 40px; border-radius: 10px; background: var(--brand-soft); color: var(--brand); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.promo-row-body { flex: 1; min-width: 0; }
.promo-row-name { font-size: 15px; font-weight: 700; color: var(--ink); }
.promo-row-meta { font-size: 12px; color: var(--ink-3); margin-top: 2px; line-height: 1.3; }
.promo-row--in { opacity: 0.55; cursor: not-allowed; }
.promo-row--in:hover { border-color: var(--line); background: transparent; }
.cat-list-wrap { margin-bottom: 12px; }

/* ===== Blocco DESIDERATA (modal macchina · funzioni cassa POS non ancora API) ===== */
.desiderata-block { margin-top: 18px; padding: 14px; border: 1px dashed var(--ink-3); border-radius: 12px; background: var(--bg); opacity: 0.85; }
.desiderata-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.desiderata-badge { font-size: 10px; font-weight: 800; letter-spacing: 0.1em; color: var(--brand); background: var(--brand-soft); padding: 3px 8px; border-radius: 4px; }
.desiderata-title { font-size: 12px; color: var(--ink-3); font-weight: 600; flex: 1; min-width: 0; }
.desiderata-block .field input:disabled { opacity: 0.6; cursor: not-allowed; background: var(--bg); }
.desiderata-block .toggle-ios[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; pointer-events: none; }
.prices-group-body--2col { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* ===== Tabella prezzi per-slot (asciugatrice) · stile gestionale Bloomest web ===== */
.slot-prices-table { width: 100%; border-collapse: collapse; margin-top: 14px; font-size: 13px; }
.slot-prices-table thead tr.slot-th-group th { background: var(--brand); color: #fff; padding: 10px 6px; font-weight: 800; text-align: center; font-size: 13px; vertical-align: top; }
.slot-prices-table thead tr.slot-th-sub th { background: transparent; color: var(--ink); padding: 10px 6px 8px; font-weight: 700; text-align: center; font-size: 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
.slot-prices-table tbody td { padding: 10px 6px; text-align: center; vertical-align: middle; border-bottom: 1px solid var(--line); }
/* Palette unica azzurrina per gruppi colonne (richiesta Andrea 2026-05-14):
   bandone = #C7DBED carico (ink navy), sub+tbody = #EEF4FA tenue. */
.slot-prices-table thead tr.slot-th-group th.col-time,
.slot-prices-table thead tr.slot-th-group th.col-cash,
.slot-prices-table thead tr.slot-th-group th.col-card { background: #C7DBED; color: #1F4977; }
.slot-prices-table thead tr.slot-th-group th.col-time .macro-alias,
.slot-prices-table thead tr.slot-th-group th.col-cash .macro-alias,
.slot-prices-table thead tr.slot-th-group th.col-card .macro-alias { color: rgba(0,0,0,0.55); }
.slot-prices-table thead tr.slot-th-sub th.col-time,
.slot-prices-table thead tr.slot-th-sub th.col-cash,
.slot-prices-table thead tr.slot-th-sub th.col-card,
.slot-prices-table tbody td.col-time,
.slot-prices-table tbody td.col-cash,
.slot-prices-table tbody td.col-card { background: #EEF4FA; }
.slot-prices-table tbody td:first-child { font-weight: 700; color: var(--ink); }
.slot-prices-table .slot-cell-n { font-weight: 700; color: var(--ink); }
.slot-prices-table .slot-cell-readonly { color: var(--ink); font-weight: 600; }
.slot-prices-table input { width: 70px; max-width: 70px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink); font-size: 16px; font-weight: 600; font-family: inherit; text-align: right; box-sizing: border-box; }
.slot-prices-table input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-soft); }
.slot-prices-table .pct-wrap,
.listini-table .pct-wrap { display: inline-flex; align-items: center; gap: 4px; justify-content: flex-end; width: 100%; }
.slot-prices-table .pct-wrap input,
.listini-table .pct-wrap input { width: 70px; max-width: 70px; }
.slot-prices-table .pct-wrap .pct-suffix,
.listini-table .pct-wrap .pct-suffix { color: var(--ink-3); font-weight: 700; font-size: 13px; }
.slot-prices-table .pct-derived { display: block; margin-top: 3px; text-align: right; font-size: 11px; color: var(--ink-3); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Allineamento a destra per colonne valori (Andrea 2026-05-14) */
.slot-prices-table tbody td.col-cash,
.slot-prices-table tbody td.col-card,
.listini-table tbody td.col-cash,
.listini-table tbody td.col-card { text-align: right; }
/* Vertical-align top sui cell valori in modo che gli input box siano allineati
   alla stessa altezza in tutte e 4 le colonne (slot 1 ha derived sotto Tipo 1/2,
   senza top alignment gli input apparirebbero sfalsati verticalmente). */
.slot-prices-table tbody td.col-cash,
.slot-prices-table tbody td.col-card { vertical-align: top; }
.slot-prices-table tbody td.col-cash .slot-cell-readonly,
.slot-prices-table tbody td.col-card .slot-cell-readonly,
.listini-table tbody td.col-cash .slot-cell-readonly,
.listini-table tbody td.col-card .slot-cell-readonly { display: inline-block; text-align: right; }
/* Anti-orfano "Tipo 0" su sub-alias multi-riga */
.sub-alias .nowrap { white-space: nowrap; }

/* ===== Chip status per Ticket (3 stati: aperto/in_lavorazione/chiuso) ===== */
.chip-status { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: 0.02em; }
.chip-status.chip-aperto { background: rgba(220, 53, 69, 0.12); color: var(--danger); }
.chip-status.chip-in_lavorazione { background: rgba(245, 158, 11, 0.16); color: #B45309; }
.chip-status.chip-chiuso { background: rgba(120, 120, 120, 0.15); color: var(--ink-3); }

/* ===== Collapsible details (registra nuovo ticket nel pane) ===== */
.cust-collapsible { border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin: 8px 0 14px; background: var(--surface); }
.cust-collapsible summary { display: flex; align-items: center; justify-content: space-between; cursor: pointer; list-style: none; margin: 0; padding: 0; }
.cust-collapsible summary::-webkit-details-marker { display: none; }
.cust-collapsible summary svg { transition: transform 0.2s ease; }
.cust-collapsible[open] summary svg { transform: rotate(180deg); }
.cust-collapsible[open] summary { margin-bottom: 12px; }

/* ===== Menu group/row · liste compatte clickabili (lista ticket, ecc.) ===== */
.menu-group { display: flex; flex-direction: column; gap: 6px; padding: 0 var(--page-pad-x); margin: 8px 0 16px; }
.menu-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; text-decoration: none; color: var(--ink); flex-wrap: nowrap; min-width: 0; }
.menu-row:hover { border-color: var(--brand); }
.menu-row:active { background: var(--bg); }
.menu-row .ico { width: 36px; height: 36px; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; background: var(--bg); color: var(--ink-3); }
.menu-row .ico.problem { background: rgba(245, 158, 11, 0.16); color: #B45309; }
.menu-row .ico.brand { background: var(--brand-soft); color: var(--brand); }
.menu-row .ico.wa { background: rgba(120, 120, 120, 0.15); color: var(--ink-3); }
.menu-row .ttl { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; color: var(--ink); overflow: hidden; }
.menu-row .ttl small { display: block; color: var(--ink-3); font-size: 12px; font-weight: 500; margin-top: 2px; line-height: 1.3; }
.menu-row .arr { width: 14px; height: 14px; color: var(--ink-3); flex-shrink: 0; margin-left: auto; }

/* ===== Empty state lista (cface-empty) ===== */
.cface-empty { padding: 32px 16px; text-align: center; }
.cface-empty .ttl { font-size: 15px; font-weight: 700; color: var(--ink); margin-bottom: 6px; }
.cface-empty .sub { font-size: 13px; color: var(--ink-3); line-height: 1.4; max-width: 320px; margin: 0 auto; }

/* ===== Sub-tab Ticket: filter-row chip wrap su mobile ===== */
[data-cli-view="ticket"] .filter-row { padding: 12px var(--page-pad-x) 8px; flex-wrap: wrap; overflow-x: visible; }
/* l'eyebrow Ticket usa il padding standard di .section-title (20px/8px), come Gruppi/Lista — niente override */

/* ===== Promo · card bonus (Bonus reg. + Compleanno): metric-rows bianca con
   riga toggle-ios in testa e sezioni form sotto (bordo top al posto del
   border-bottom della row, cosi' la card chiusa non ha bordi appesi). ===== */
.bonus-card .metric-row { border-bottom: none; }
.bonus-card .bonus-card-body { border-top: 1px solid var(--line); padding: 14px 16px; }
.bonus-card .bonus-card-body .field { margin-bottom: 0; }
/* importo € stretto (form-design regola 1, min-width per il font 16px mobile anti-zoom) */
.bonus-card .fld-mid { max-width: 9rem; min-width: 7rem; }
.bonus-card-note { padding: 0 16px 14px; margin: 0; font-size: 12px; color: var(--ink-3); line-height: 1.4; }
/* Pool QR compleanno · righe statistiche nude dentro la bonus-card (niente
   .metric-rows annidata: card-in-card raddoppiava shadow e margini). */
.qr-pool-stats { margin: 4px 0 12px; }
.qr-pool-stats .row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.qr-pool-stats .row:last-child { border-bottom: none; }
.qr-pool-stats .lbl { color: var(--ink-2); }
.qr-pool-stats .val { font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
/* File-picker custom (il control nativo del browser e' in inglese e non
   stilizzabile). position:relative: ancora l'input nascosto (abspos,
   dimensioni 0) al wrapper — mai un abspos nascosto senza ancestor
   posizionato (bug zoom iOS 2026-07-05). */
.qr-pool-steps { margin: 4px 0 12px; padding-left: 20px; font-size: 13px; color: var(--ink-2); line-height: 1.55; }
.qr-pool-steps li { margin-bottom: 6px; }
.qr-pool-steps li::marker { font-weight: 700; color: var(--ink); }
.field-hint { margin: 4px 0 0; font-size: 12px; color: var(--ink-3); line-height: 1.4; }
.file-pick { position: relative; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.file-pick-count { font-size: 13px; color: var(--ink-3); }
.file-pick-input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
/* Il popover del datepicker vive dentro la .bonus-card (overflow:hidden per
   il border-radius): a calendario aperto la card lo lascia uscire, altrimenti
   esce tagliato. */
.bonus-card:has(.dt-field.open) { overflow: visible; }
/* nota descrittiva sotto un .section-title (pane paddato, niente padding-x proprio) */
.sec-note { margin: -2px 0 10px; font-size: 12px; color: var(--ink-3); line-height: 1.4; }
.metric-row > .pill-btn { flex-shrink: 0; }
/* disclosure dentro una card metric-rows (anteprima compleanni): si fonde come riga */
.metric-rows .reservations-disclosure { margin: 0; box-shadow: none; border-radius: 0; border-bottom: 1px solid var(--line); }
.metric-rows .reservations-disclosure summary { font-size: 14px; color: var(--ink-2); font-weight: 400; }

/* Messaggio in cassa */
.cash-msg-range { display:flex; align-items:flex-end; gap:10px; flex-wrap:wrap; }
.cash-msg-counter { font-size:12px; color:var(--ink-3,#9ca3af); text-align:right; }
.cash-msg-history-title { font-size:14px; font-weight:700; margin:18px 0 8px; color:var(--ink); }
.cash-msg-list { margin-top:8px; }
.cash-msg-row { display:flex; align-items:center; gap:10px; padding:8px 0; border-bottom:1px solid var(--line,#e5e7eb); }
.cash-msg-period { font-size:12px; color:var(--ink-2,#6b7280); white-space:nowrap; }
.cash-msg-text { flex:1; font-size:13px; }
.cash-msg-actions { display:flex; align-items:center; }
.cash-msg-del { background:none; border:none; cursor:pointer; color:var(--ink-3); padding:4px; line-height:1; }
.cash-msg-del:hover { color:var(--danger,#ef4444); }
.cash-msg-history-hint { font-size:13px; color:var(--ink-3); margin:8px 0; }
.badge-ok { background:#dcfce7; color:#166534; border-radius:6px; padding:1px 6px; font-size:11px; }
.badge-external { background:#e0e7ff; color:#3730a3; border-radius:6px; padding:1px 6px; font-size:11px; }

/* ============================================================
   Listini prezzi modal — claudedesign port (2026-05-14)
   Pattern: inline-editable, sub-header descrittivo, derived =€
   ============================================================ */
.gm-card-listini { max-width: 1180px; width: 100%; max-height: 92vh; padding: 0; }
.gm-card-listini .gm-head { padding: 24px 28px 4px; }
.gm-card-listini .listini-form { display: flex; flex-direction: column; flex: 1; min-height: 0; overflow: hidden; }
.gm-card-listini .listini-cd-wrap { flex: 1; min-height: 0; overflow-y: auto; padding: 12px 28px 4px; }
.gm-card-listini .gm-actions { flex-shrink: 0; padding: 16px 28px 24px; border-top: 1px solid var(--line); display: flex; gap: 12px; justify-content: flex-end; align-items: center; }

/* ---------- Info banner ---------- */
.info-banner { display: grid; grid-template-columns: auto 1fr; gap: 14px; background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--brand); border-radius: 8px; padding: 14px 18px; margin-bottom: 18px; }
.info-banner-icon { width: 26px; height: 26px; border-radius: 50%; background: var(--brand); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 700; font-style: italic; flex-shrink: 0; }
.info-banner-title { font-size: 14px; font-weight: 700; margin: 0 0 4px; color: var(--ink); }
.info-banner-text { margin: 0; font-size: 13px; color: var(--ink-2); line-height: 1.55; }
.info-banner-text strong { color: var(--ink); font-weight: 700; }
.info-banner-text em { font-style: italic; color: var(--ink-2); }

/* ---------- Section ---------- */
.tbl-section { background: var(--surface); border: 1px solid var(--line); border-radius: 8px; margin-bottom: 18px; }
.tbl-section-head { padding: 18px 20px 12px; border-bottom: 1px solid var(--line); }
.tbl-section-headline { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 6px; }
.tbl-section-headline .eyebrow { color: var(--brand); font-size: 12px; font-weight: 800; letter-spacing: 0.15em; text-transform: uppercase; }
.tbl-section-count { font-size: 13px; color: var(--ink-3); }
.tbl-section-sub { margin: 0; color: var(--ink-2); font-size: 13px; max-width: 80ch; line-height: 1.55; }
.tbl-section-sub strong { color: var(--ink); font-weight: 700; }

/* ---------- Table base ---------- */
.tbl-section .tbl { display: block; width: 100%; }
.tbl-section .tbl-row { display: grid; align-items: stretch; }
.tbl-section .cell { display: flex; align-items: center; padding: 12px 16px; font-size: 13px; color: var(--ink); min-width: 0; }

/* Column header — eyebrow + sub */
.tbl-section .colhead { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; }
.tbl-section .colhead-label { text-transform: uppercase; letter-spacing: 0.12em; font-size: 11px; color: var(--ink); font-weight: 800; }
.tbl-section .colhead-sub { font-size: 11px; color: var(--ink-3); letter-spacing: 0; text-transform: none; line-height: 1.3; }

/* Align headers right per money/pct cells (right-aligned con i valori sotto) */
.tbl-lav .tbl-row-h .cell:not(.cell-machine),
.tbl-dryer .tbl-row-h .cell:not(.cell-slot):not(.cell-min) { justify-content: flex-end; }
.tbl-lav .tbl-row-h .cell:not(.cell-machine) .colhead,
.tbl-dryer .tbl-row-h .cell:not(.cell-slot):not(.cell-min) .colhead { align-items: flex-end; text-align: right; }

/* ---------- LAVATRICI grid ---------- */
.tbl-lav .tbl-row { grid-template-columns: minmax(200px, 1.4fr) minmax(110px, 1fr) minmax(110px, 1fr) minmax(140px, 1.1fr) minmax(140px, 1.1fr); }
.tbl-lav .tbl-row-hgrp { background: var(--bg); }
.tbl-lav .tbl-row-hgrp .cell { padding-top: 10px; padding-bottom: 4px; font-size: 11px; color: var(--ink-2); }
.tbl-lav .tbl-row-hgrp .cell-grp .grp-tag { display: inline-flex; align-items: center; text-transform: uppercase; letter-spacing: 0.15em; font-size: 10px; color: var(--ink-3); font-weight: 700; }
.tbl-lav .tbl-row-hgrp .grp-card .grp-tag::before { content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--brand); margin-right: 6px; }
.tbl-lav .tbl-row-h { background: var(--bg); border-bottom: 1px solid var(--line); }
.tbl-lav .tbl-row-h .cell { padding-top: 4px; padding-bottom: 12px; align-items: flex-end; }
.tbl-lav .tbl-row-hgrp .grp-card,
.tbl-lav .tbl-row-h .cell:nth-child(3),
.tbl-lav .tbl-row-data .cell:nth-child(3) { border-left: 1px solid var(--line); }
.tbl-lav .tbl-row-data { border-bottom: 1px solid var(--line); }
.tbl-lav .tbl-row-data:last-child { border-bottom: 0; }
.tbl-lav .tbl-row-data:hover { background: color-mix(in oklab, var(--bg) 50%, var(--surface)); }

/* ---------- Machine cell ---------- */
.tbl-section .cell-machine { gap: 12px; }
.m-letter { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 6px; background: var(--bg); border: 1px solid var(--line); font-weight: 700; font-size: 14px; color: var(--ink); flex-shrink: 0; }
.m-meta { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.m-name { font-size: 13px; font-weight: 700; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.m-code { font-size: 11px; color: var(--ink-3); letter-spacing: 0.02em; text-transform: uppercase; }

/* ---------- NumField (bordo visibile sempre, focus = brand ring) ----------
   Scope doppio: .tbl-section = bulk editor listini, .slot-prices-table =
   modal macchina tab Prezzi. STESSO componente nei due contesti (mai
   reintrodurre pct-wrap o input nudi per i campi money/%). */
.tbl-section .cell-money, .tbl-section .cell-pct { justify-content: flex-end; }
.tbl-section .numfield,
.slot-prices-table .numfield { display: inline-flex; align-items: center; gap: 3px; background: var(--surface); border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; height: 32px; transition: border-color 120ms ease, box-shadow 120ms ease; cursor: text; position: relative; }
.tbl-section .numfield:hover,
.slot-prices-table .numfield:hover { border-color: var(--ink-3); }
.tbl-section .numfield:focus-within,
.slot-prices-table .numfield:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in oklab, var(--brand) 18%, transparent); }
.tbl-section .numfield input,
.slot-prices-table .numfield input { flex: 1; min-width: 0; width: 48px; max-width: none; border: 0; outline: 0; background: transparent; font-weight: 700; font-size: 16px; color: var(--ink); padding: 0; font-variant-numeric: tabular-nums; text-align: right; cursor: text; font-family: inherit; box-shadow: none; }
.tbl-section .numfield-suffix,
.slot-prices-table .numfield-suffix { color: var(--ink-3); font-size: 13px; font-weight: 700; flex-shrink: 0; }
.tbl-section .numfield-money input,
.slot-prices-table .numfield-money input { min-width: 44px; }
.tbl-section .numfield-pct input,
.slot-prices-table .numfield-pct input { min-width: 28px; }
.tbl-section .numfield-readonly { opacity: 0.6; }
.tbl-section .numfield-readonly input { cursor: not-allowed; }

/* IntField stepper */
.tbl-section .numfield-int { padding: 2px 4px; gap: 2px; background: var(--surface); border-color: var(--line); }
.tbl-section .numfield-int input { text-align: center; min-width: 28px; max-width: 40px; width: 40px; }
.tbl-section .numfield-step { width: 22px; height: 22px; border: 0; background: transparent; border-radius: 4px; color: var(--ink-3); font-size: 16px; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: background 120ms ease, color 120ms ease; flex-shrink: 0; padding: 0; }
.tbl-section .numfield-step:hover { background: var(--bg); color: var(--ink); }

/* Derived (read-only computed) */
.tbl-section .derived { display: inline-flex; align-items: baseline; gap: 3px; font-variant-numeric: tabular-nums; font-weight: 700; font-size: 13px; color: var(--ink); }
.tbl-section .derived.is-muted { color: var(--ink-3); font-weight: 600; }

/* % cell derived line */
.tbl-section .cell-pct { flex-direction: column; align-items: flex-end; gap: 2px; }
.tbl-section .pct-derived { font-size: 11px; color: var(--ink-3); font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ---------- ASCIUGATRICI ---------- */
/* min-width:0: .dryer-block è grid item di .dryer-stack; senza questo il
   min-width:auto di default impedirebbe al blocco di restringersi sotto i 760px
   del contenuto (min-width head/body) → la .tbl-dryer non scrollerebbe e
   sforerebbe la viewport su mobile. Le lavatrici non hanno il problema: la
   .tbl-lav è figlia diretta di un .tbl-section block. */
.dryer-stack { display: grid; gap: 0; min-width: 0; }
.dryer-block { border-bottom: 1px solid var(--line); min-width: 0; }
.dryer-block:last-child { border-bottom: 0; }
.dryer-bar { display: grid; grid-template-columns: minmax(220px, 1fr) auto; align-items: center; gap: 16px; padding: 12px 16px; background: var(--bg); border-bottom: 1px solid var(--line); }
.dryer-id { display: flex; align-items: center; gap: 12px; }
.dryer-id .m-letter { background: var(--surface); }
.dryer-controls { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.ctrl { display: inline-flex; align-items: center; gap: 8px; }
.ctrl-label { display: inline-flex; align-items: center; gap: 6px; text-transform: uppercase; letter-spacing: 0.12em; font-size: 10px; color: var(--ink-3); font-weight: 800; white-space: nowrap; }
.ctrl-label .desiderata-badge { letter-spacing: 0.08em; padding: 2px 6px; }

/* Segmented control Auto/Manuale */
.seg { display: inline-flex; background: var(--surface); border: 1px solid var(--line); border-radius: 6px; padding: 2px; gap: 2px; height: 30px; }
.seg-opt { border: 0; background: transparent; font-weight: 700; font-size: 12px; color: var(--ink-2); padding: 0 12px; border-radius: 4px; cursor: pointer; transition: background 120ms ease, color 120ms ease; font-family: inherit; }
.seg-opt:hover { color: var(--ink); }
.seg-opt:active { transform: scale(0.96); }
.seg-opt.is-on { background: var(--ink); color: var(--surface); }

/* Dryer slot table */
.tbl-dryer .tbl-row { grid-template-columns: 70px 90px minmax(110px, 1fr) minmax(110px, 1fr) minmax(140px, 1.1fr) minmax(140px, 1.1fr); }
.tbl-dryer .tbl-row-h { background: var(--surface); border-bottom: 1px solid var(--line); }
.tbl-dryer .tbl-row-h .cell { padding-top: 12px; padding-bottom: 12px; align-items: flex-end; }
.tbl-dryer .tbl-row-data { border-bottom: 1px solid var(--line); }
.tbl-dryer .tbl-row-data:last-child { border-bottom: 0; }
.tbl-dryer .tbl-row-data:hover { background: color-mix(in oklab, var(--bg) 40%, var(--surface)); }
.tbl-dryer .cell-slot, .tbl-dryer .cell-min { padding-left: 16px; }

/* Slot pill */
.slot-n { display: inline-flex; align-items: center; justify-content: center; min-width: 28px; height: 28px; padding: 0 10px; border-radius: 999px; background: var(--bg); border: 1px solid var(--line); font-weight: 700; font-size: 13px; font-variant-numeric: tabular-nums; color: var(--ink); }
.tbl-dryer .tbl-row-data.is-base .slot-n { background: var(--brand); color: #fff; border-color: var(--brand); }
.slot-min { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--ink); }
.slot-min-u { font-size: 11px; color: var(--ink-3); margin-left: 3px; font-weight: 600; }

/* Hint sotto dryer slots */
.dryer-hint { margin: 0; padding: 10px 16px; font-size: 12px; color: var(--ink-3); background: color-mix(in oklab, var(--bg) 60%, var(--surface)); border-top: 1px solid var(--line); display: flex; align-items: center; gap: 8px; }
.dryer-hint strong { color: var(--ink); font-weight: 700; }
.dryer-hint .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--brand); flex-shrink: 0; }

/* Footer caption */
.listini-foot { padding: 8px 0 0; }
.listini-foot .t-caption { margin: 0; font-size: 12px; color: var(--ink-3); }
.listini-foot strong { color: var(--ink); }
.listini-foot em { font-style: italic; color: var(--ink-2); }

/* ---------- Responsive listini: scroll orizzontale, no stacking ---------- */
.tbl-section .tbl { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Min-width sulle sub-container (head/body) forza la grid a 760px; con .tbl overflow-x:auto, attiva lo scroll orizzontale. */
.tbl-lav .tbl-head,
.tbl-lav .tbl-body,
.tbl-dryer .tbl-head,
.tbl-dryer .tbl-body { min-width: 760px; }

@media (max-width: 960px) {
  .gm-card-listini .listini-cd-wrap,
  .gm-card-listini .gm-head,
  .gm-card-listini .gm-actions { padding-left: 14px; padding-right: 14px; }
  .dryer-bar { grid-template-columns: 1fr; gap: 10px; }
  .dryer-controls { gap: 12px; flex-wrap: wrap; }
}
@media (max-width: 560px) {
  .dryer-controls { gap: 8px; }
  .ctrl { gap: 6px; }
  .seg-opt { padding: 0 10px; font-size: 11px; }
}

/* ==========================================================
   UTILITY CLASSES (task H · 2026-05-18) — dashboard
   Feedback PAI `feedback_no_inline_css_default`. Dynamic vars
   `var(--*)` restano inline come permesso.
   ========================================================== */

/* Sub-text */
.u-meta-ink-3 { font-size: 12px; color: var(--ink-3); }
.u-meta-ink-2 { font-size: 13px; color: var(--ink-2); }
.u-section-title-tight { padding: 14px 0 6px; }
.u-section-title-flush { padding-left: 0 !important; padding-right: 0 !important; }
.u-section-title-mid { padding: 18px 0 6px; }

/* Soft body box (ticket modal "descrizione cliente") */
.u-soft-body-box {
  background: var(--bg);
  padding: 12px 14px;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
  color: var(--ink);
}

/* Form host flex */
.u-form-flex-2 { flex: 2; }

/* Tiny spacing helpers */
.u-mt-6 { margin-top: 6px; }

/* Field-row flex variants (impostazioni profilo modal) */
.field--flex-220 { flex: 2 1 220px; }
.field--flex-180 { flex: 2 1 180px; }
.field--flex-160 { flex: 1 1 160px; }
.field--w-100 { flex: 0 0 100px; }
.field--w-110 { flex: 0 0 110px; }
.field--w-80 { flex: 0 0 80px; }

/* Listino + Sconto sulla stessa riga nel modal cliente, split 70/30. Scoped:
   batte .field-row .field{flex:1} solo per questa riga. align-items:start così
   le note di altezza diversa non stirano i campi. Numero sconto allineato a dx. */
.cust-pane .field-row.lst-sct-row { align-items: flex-start; }
.cust-pane .field-row.lst-sct-row > .field { flex: 7 1 0; }
.cust-pane .field-row.lst-sct-row > .field.sct-field { flex: 3 1 0; }
.cust-pane .field-row.lst-sct-row .sct-field input { text-align: right; }

/* Stesso split 70/30 nel modal Configura categoria (in .sheet, fuori da .cust-pane). */
[data-modal="cat-config"] .field-row.lst-sct-row { align-items: flex-start; }
[data-modal="cat-config"] .field-row.lst-sct-row > .field { flex: 7 1 0; }
[data-modal="cat-config"] .field-row.lst-sct-row > .field.sct-field { flex: 3 1 0; }
[data-modal="cat-config"] .field-row.lst-sct-row .sct-field input { text-align: right; }
[data-modal="cat-config"] .u-meta-note-sm a { color: var(--brand); text-decoration: none; font-weight: 600; }
[data-modal="cat-config"] .u-meta-note-sm a:hover { text-decoration: underline; }

/* Tabella "cosa paga questa card": riusa .dt-table (pattern Vendite per macchina).
   Modificatore: margine sotto il section-title, niente cursore "clic" (righe non
   cliccabili), prezzo in grassetto. Numeri a dx + tabular-nums li dà .dt-table .num. */
/* Card bianca su modale bianco: l'ombra .dt-card (0.04) non basta a staccarla →
   bordo 1px per incorniciare la tabella prezzi. */
.card-price-card { margin-top: 6px; border: 1px solid var(--line); }
.card-price-table tbody tr:hover { cursor: default; background: transparent; }
.card-price-table td.num { font-weight: 600; }

/* Storico modale: l'accordion movimenti (.reservations-disclosure, nato per la
   pagina Prenotazioni con inset 18px) nel modale raddoppiava l'indentazione (il
   body .cust-pane ha già padding 18px) → i movimenti erano 18px più indentati e
   più stretti del resto. Azzeriamo il margine orizzontale solo qui: flush con le
   metric-rows sopra. */
.cust-pane .reservations-disclosure { margin-left: 0; margin-right: 0; }

/* Province input uppercase */
.input-uppercase { text-transform: uppercase; }

/* Grid form-row 2-col */
.field-row--grid-2 {
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.field-row--grid-2-mb {
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 12px;
}

/* Banner amber/info */
.banner-amber {
  padding: 16px;
  border-radius: 8px;
  background: #FEF3C7;
  color: #78350F;
  margin-bottom: 16px;
}
.banner-amber--margin-y {
  padding: 14px 16px;
  border-radius: 8px;
  background: #FEF3C7;
  color: #78350F;
  margin: 18px 0;
  line-height: 1.5;
}

/* Modal listini grid column span 3 */
.col-span-3 { grid-column: span 3; }

/* Impostazioni list-row tight padding */
.list-row--padded { padding: 18px 16px; }
.list-row-ttl--brand { color: var(--brand); }

/* Clienti ticket modal trigger row */
.ticket-trigger-row { cursor: pointer; }
.ticket-disabled-row { cursor: default; opacity: 0.7; }

/* Meta note small with margin-top 12 */
.u-meta-note-sm--mt-12 { margin-top: 12px; }

/* Lab primary-lab hint (impostazioni profilo) */
.lab-primary-hint {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: -4px;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
}

/* === S1b auth (ADR 0024) ===
   Token substitution rispetto al plan (tokens originali non esistono in shared/tokens.css):
   --bg-elev1   -> --surface       (white card)
   --border     -> --line          (grigio chiaro divisorio)
   --brand-hover -> --brand-dark   (rosso scuro hover)
   --err-bg     -> --brand-soft    (pink chiaro, unico soft-bg disponibile)
   --err-text   -> --danger        (rosso #DC2626 WCAG AA su --brand-soft) */
.auth-container { max-width: 420px; margin: 60px auto; padding: 32px; background: var(--surface); border-radius: 12px; }
.auth-container h1 { font-size: 24px; margin-bottom: 24px; }
.auth-field { margin-bottom: 16px; }
.auth-field label { display: block; font-weight: 600; margin-bottom: 6px; color: var(--ink-2); }
.auth-field input { width: 100%; padding: 12px; font-size: 16px; border: 1px solid var(--line); border-radius: 8px; }
.auth-field input:focus { outline: 2px solid var(--brand); }
.auth-error { background: var(--brand-soft); color: var(--danger); padding: 12px; border-radius: 8px; margin-bottom: 16px; }
.auth-intro { margin: 0 0 24px; color: var(--ink-2); }
.auth-help { margin: 6px 0 0; font-size: 13px; }
.auth-help a { color: var(--ink-3); text-decoration: underline; }
.auth-help a:hover { color: var(--ink); }
.auth-link { margin-top: 16px; text-align: center; }
.auth-container .btn-primary { width: 100%; padding: 12px; font-size: 16px; font-weight: 600; background: var(--brand); color: white; border: 0; border-radius: 8px; cursor: pointer; }
.auth-container .btn-primary:hover { background: var(--brand-hover); }

/* Countdown row sotto progress-bar nella card macchina in_uso (live Miele MOVE).
   Pattern label-piccola-sopra + valore-grande-sotto in 2 colonne (sx Tempo
   residuo / dx Fine prevista). */
.machine-card .countdown-row { display: flex; justify-content: space-between; align-items: flex-start; margin-top: 10px; padding: 0 16px 4px; gap: 16px; }
.machine-card .countdown-row .cd-cell { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.machine-card .countdown-row .cd-right { align-items: flex-end; text-align: right; }
.machine-card .countdown-row .cd-lbl { font-size: 11px; color: var(--ink-3); font-weight: 600; }

/* F8 · eco aggregato tokens + component classes (2026-05-21).
   --alarm / --service: colori insight severi + manutenzione.
   --warn-bg / --info-bg / --alarm-bg / --service-bg: sfondi tono pastello.
   --info-200..800: rampa intensità per heatmap (crescente dal chiaro al scuro). */
:root {
  --alarm:       #C1432D;
  --alarm-bg:    #FEF2F0;
  --service:     #D97706;
  --service-bg:  #fff4d6;
  --warn-bg:     #fff4d6;
  --info-bg:     #eaf2ff;
  --info-200:    #a8c7e8;
  --info-400:    #5b8dbf;
  --info-600:    #2d5bc4;
  --info-800:    #1e3d8a;
}

.eco-insight {
  padding: 10px 14px;
  border-left: 3px solid var(--ink-3);
  border-radius: 4px;
  margin-bottom: 8px;
  font-size: 13px;
  background: var(--surface);
}
.eco-insight--warn    { border-left-color: var(--warn);    background: var(--warn-bg); }
.eco-insight--alarm   { border-left-color: var(--alarm);   background: var(--alarm-bg); }
.eco-insight--info    { border-left-color: var(--info);    background: var(--info-bg); }
.eco-insight--service { border-left-color: var(--service); background: var(--service-bg); }
.eco-insight a { font-weight: 600; }

.bar-cell { display: block; }
.bar-fill {
  display: inline-block;
  padding: 2px 6px;
  border-radius: 3px;
  background: var(--info);
  color: #fff;
  font-size: 11px;
}
.bar-fill--muted { background: var(--info-bg); color: var(--ink); }

.hm-grid {
  display: grid;
  grid-template-columns: 32px repeat(8, 1fr);
  gap: 2px;
  font-size: 10px;
}
.hm-cell {
  height: 16px;
  border-radius: 1px;
}
.hm-cell--lvl0 { background: var(--info-bg); }
.hm-cell--lvl1 { background: var(--info-200); }
.hm-cell--lvl2 { background: var(--info-400); }
.hm-cell--lvl3 { background: var(--info-600); }
.hm-cell--lvl4 { background: var(--info-800); }
.hm-cell--peak { outline: 2px solid var(--alarm); }
.machine-card .countdown-row .cd-val { font-size: 16px; color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ========== Riepilogo v4 (Andamento) ========== */
.kpi-hero-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 14px var(--page-pad-x) 0; }
.kpi-hero-card { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); padding: 16px; }
.kpi-hero-card .kh-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-3); margin-bottom: 4px; }
.kpi-hero-card .kh-value { font-size: 26px; font-weight: 800; color: var(--ink); line-height: 1.1; }
.kpi-hero-card .kh-value.branded { color: var(--brand); }
.kpi-hero-card .kh-delta { display: inline-flex; align-items: center; gap: 3px; margin-top: 6px; font-size: 12px; font-weight: 700; padding: 4px 10px; border-radius: 999px; line-height: 1.35; }
.kpi-hero-card .kh-delta.up { background: #E8F8EE; color: var(--ok-text); }
.kpi-hero-card .kh-delta.down { background: #FCE4E4; color: var(--danger); }
.kpi-hero-card .kh-delta.flat { background: var(--bg); color: var(--ink-3); }
.and-riepilogo .dual-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 10px var(--page-pad-x) 0; }
.and-riepilogo .dual-grid .dt-card { margin: 0; overflow: hidden; }
.and-riepilogo .dual-grid .metric-rows { margin: 0; }
.and-riepilogo .dual-grid .dt-table th,
.and-riepilogo .dual-grid .dt-table td { white-space: normal; }
.and-riepilogo .dual-grid .dt-table .num { width: 1%; white-space: nowrap; }
.u-c-ink-3-fw { color: var(--ink-3); font-weight: 400; }
/* AdE pane: griglia 3 colonne fisse — allinea titolo|descrizione|valore su tutte le card */
/* AdE Esporta: 3 bottoni in riga su desktop, stacked su mobile */
.ade-export-row { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 var(--page-pad-x); }
.ade-export-row > a { flex: 1 1 auto; min-width: 0; }
@media (max-width: 720px) { .ade-export-row { flex-direction: column; } .ade-export-row > a { width: 100%; } }
.ade-rows .metric-row { display: grid; grid-template-columns: 28% 100px 1fr; gap: 4px 10px; align-items: center; }
.ade-rows .ade-title { font-size: 14px; color: var(--ink); }
.ade-rows .ade-desc { font-size: 12px; color: var(--ink-3); line-height: 1.4; }
.ade-rows .metric-row .val { white-space: nowrap; text-align: right; font-variant-numeric: tabular-nums; font-weight: 500; }
.ade-rows .metric-row .val strong { font-weight: 700; }
/* Riepilogo: prima colonna wrappabile (evita overflow tabella su mobile) + respiro dx */
.and-riepilogo .dt-table td:first-child { white-space: normal; }
.and-riepilogo .dt-table td:last-child,
.and-riepilogo .dt-table th:last-child { padding-right: 18px; }
/* Riepilogo: colonne fisse sulle tabelle a 3 colonne (Servizio, Pagamento, Ricariche) */
.and-riepilogo .dt-table.riepilogo-3col th:nth-child(2),
.and-riepilogo .dt-table.riepilogo-3col td:nth-child(2) { width: 100px; }
.and-riepilogo .dt-table.riepilogo-3col th:nth-child(3),
.and-riepilogo .dt-table.riepilogo-3col td:nth-child(3) { width: 50px; }
.and-riepilogo .row-total { border-top: 2px solid var(--line); }
.and-riepilogo .row-dim { opacity: 0.4; }
.and-riepilogo .row-bonus { opacity: 0.6; }
.and-riepilogo .mkt-active-list { padding: 0; margin: 10px var(--page-pad-x) 0; }
.kpi-hero-row.cols-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 720px) {
  .kpi-hero-row { grid-template-columns: 1fr 1fr; }
  .kpi-hero-row.cols-3 { grid-template-columns: 1fr; }
  .and-riepilogo .dual-grid { grid-template-columns: 1fr; }
}

/* ========== HOVER + ACTIVE sweep (vitalità UI) ==========
   Ogni elemento interattivo ha feedback :hover (desktop) e :active (tap mobile).
   Pattern: scale(0.97) per card/row, scale(0.96) per bottoni piccoli. */

/* Cards / rows cliccabili — :active mancante */
.machine-card:active { transform: scale(0.98); }
.cust-card { transition: border-color 120ms ease, background 120ms ease; }
.cust-card:hover { border-color: var(--brand); }
.cust-card:active { background: var(--bg); }
.cat-card:active { transform: scale(0.98); }
.mkt-active-row:active { background: var(--bg); }
.action-suggestions .as-card:active { transform: scale(0.98); }
.promo-row:active { background: var(--brand-soft); }
.ticket-trigger-row { transition: border-color 120ms ease, background 120ms ease; }
.ticket-trigger-row:hover { background: var(--bg); }
.ticket-trigger-row:active { background: var(--line); }
.mkt-cta-free:active { transform: scale(0.98); }
.mkt-proposal:active { transform: scale(0.99); }

/* Sidebar */
.sb-brand--btn:active { background: var(--brand-soft); opacity: 0.85; }
.sb-nav .sb-action:active { transform: scale(0.96); }

/* Sub-tabs */
.cli-subtab { transition: color 120ms ease, border-color 120ms ease; }
.cli-subtab:active { opacity: 0.8; }

/* Back / settings buttons */
.cust-pane-head .back:active { transform: scale(0.92); }
.cat-detail-head .back:active { transform: scale(0.92); }
.cat-detail-head .settings-btn:active { transform: scale(0.92); }
.back-link:active .back-icon { transform: translateX(-4px) scale(0.92); }

/* Bulk actions */
.bulk-bar .bulk-action:active { transform: scale(0.95); }
.bulk-bar .bulk-clear:active { opacity: 0.7; }

/* Chips */
.lab-chip:active { transform: scale(0.95); }
.sub-chip:active { transform: scale(0.95); }

/* Buttons / controls */
.btn-danger-ghost:active { transform: scale(0.97); }
.pill-btn:active { transform: scale(0.95); }
.action-btn:active { transform: scale(0.92); }
.dt-mc .gear-btn:active { transform: scale(0.92); background: var(--line); }
.mov-range .range-apply:active { transform: scale(0.97); }
.dt-trigger .dt-icon-btn:active { background: var(--brand-soft); }
.cal-head button:active { transform: scale(0.9); }
.cal-day:active { transform: scale(0.9); }
.cal-foot .text-btn:active { transform: scale(0.96); }
.cal-foot .ok-btn:active { transform: scale(0.96); }
.dc-stepper .dc-step-btn:active { transform: scale(0.9); background: var(--brand-soft); }
.tbl-section .numfield-step:active { transform: scale(0.88); background: var(--line); }
th.sortable:active { opacity: 0.7; }

/* Form elements */
.radio-group label { transition: border-color 120ms ease, background 120ms ease; }
.radio-group label:hover { border-color: var(--brand); }
.radio-group label:active { transform: scale(0.97); }
.u-lang-opt { transition: border-color 120ms ease, background 120ms ease; }
.u-lang-opt:hover { border-color: var(--brand); background: var(--brand-soft); }
.u-lang-opt:active { transform: scale(0.98); }

/* Disclosures / collapsibles */
.reservations-disclosure summary:active { opacity: 0.8; }
.cust-collapsible summary { transition: background 120ms ease; }
.cust-collapsible summary:hover { background: var(--bg); }
.cust-collapsible summary:active { opacity: 0.8; }
.filter-dd > summary:active { transform: scale(0.97); }

/* Filter menu */
.filter-menu label:active { background: var(--brand-soft); }

/* Confirm modal buttons */
.gmodal.gm-confirm .gm-actions > button:active { transform: scale(0.97); }

/* ========== A11Y · prefers-reduced-motion guard (C11) ==========
   Stessa logica di app.css S5 M5: 0.01ms per far firare transitionend. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Modale passkey gestore: lista credenziali registrate (Fase 1) */
.pk-list { margin: 4px 0 12px; }
.pk-item { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.pk-item:last-child { border-bottom: none; }
.pk-item-ico { color: var(--brand); flex-shrink: 0; line-height: 0; }
.pk-item-label { flex: 1; min-width: 0; font-size: 14px; color: var(--ink); overflow-wrap: anywhere; }
.pk-item-del { background: none; border: none; color: var(--ink-3); cursor: pointer; padding: 4px; line-height: 0; flex-shrink: 0; }
.pk-empty { font-size: 14px; color: var(--ink-2); padding: 8px 0 14px; }

/* Login biometrico gestore (Fase 2) */
.auth-passkey { margin-top: 18px; }
.auth-divider { display: flex; align-items: center; gap: 10px; color: var(--ink-3); font-size: 13px; margin: 14px 0; }
.auth-divider::before, .auth-divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.auth-passkey .btn-secondary { width: 100%; }
.auth-passkey-status { font-size: 13px; margin-top: 8px; text-align: center; color: var(--ink-2); }

/* ========== Happy Hour — badge cassa, heatmap, ROI ========== */
.badge-cassa { background: #fde68a; color: #78350f; border-radius: 6px; padding: 1px 6px; font-size: 11px; font-weight: 600; }

/* --- Schermata dettaglio ROI: colonna leggibile + sezioni in card ---
   .app-main non ha padding-x: il gutter va sul wrapper della schermata.
   max-width evita le righe full-bleed (la guida cassa diventava illeggibile). */
.hh-detail { max-width: 760px; padding: 0 var(--page-pad-x); }
.hh-detail .u-row-gap-8-pad-wrap { padding: 16px 0 0; }

.hh-roi > h3 { font-size: 20px; font-weight: 800; letter-spacing: -0.02em; color: var(--ink); margin: 6px 0 4px; display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.hh-reward { font-size: 14px; color: var(--ink-2); margin: 0 0 4px; }

/* Ogni sezione (heatmap, verdetto, guida) è una card, come il resto della dashboard. */
.hh-heatmap, .hh-after, .hh-guide { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 14px; margin-top: 12px; }
.hh-heatmap { overflow-x: auto; }
.hh-heatmap h4, .hh-after h4, .hh-guide h4 { font-size: 15px; font-weight: 700; color: var(--ink); margin: 0 0 8px; }
.hh-suggest { font-size: 13px; color: var(--ink-2); margin: 0 0 10px; }

/* Heatmap grid */
.hh-grid { border-collapse: collapse; font-size: 10px; }
.hh-grid th, .hh-grid td { border: 1px solid var(--line, #e5e7eb); width: 18px; height: 18px; text-align: center; }
.hh-grid td[data-v="0"] { background: #f8fafc; color: #cbd5e1; }
.hh-grid td { background: #dbeafe; }

/* Verdetto "Sta funzionando?" — card standard, senza accento colorato:
   lo stato è già nel testo ("Funziona" / "Troppo presto per dirlo"…). */
.hh-after p { font-size: 14px; color: var(--ink-2); margin: 0; }
.hh-after ul { margin: 10px 0 0; padding-left: 20px; font-size: 14px; color: var(--ink-2); }
.hh-after ul li { margin: 4px 0; }

/* Guida cassa */
.hh-guide { font-size: 13px; color: var(--ink-2); }
.hh-guide ol { margin: 0; padding-left: 20px; }
.hh-guide li { margin: 6px 0; line-height: 1.5; }

.hh-roi-link { font-size: 13px; color: var(--brand); font-weight: 600; text-decoration: none; }
.hh-roi-link:hover { text-decoration: underline; }

/* Happy Hour 1-tap — sheet attiva-e-annuncia. Colori via token. */
.hh-move-muted { color: var(--ink-3); font-weight: 400; text-transform: none; letter-spacing: 0; }
.hh-reach { font-size: 13px; }
.hh-warn { font-weight: 600; margin-top: 10px; }

/* Blocco "Risultati (misurato)" — dettaglio campagna (Task 4) */
.mkt-measured { margin: 16px 0; padding: 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--bg); }
.mkt-measured-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.mkt-measured-head h3 { font-size: 15px; margin: 0; }
.mkt-measured-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.mkt-measured-grid .mm-cell { display: flex; flex-direction: column; gap: 2px; }
.mkt-measured-grid .mm-val { font-size: 20px; font-weight: 700; }
.mkt-measured-grid .mm-val.up { color: #157a3c; }
.mkt-measured-grid .mm-pct { font-size: 13px; font-weight: 500; color: var(--ink-2); }
.mkt-measured-grid .mm-lbl { font-size: 12px; color: var(--ink-2); }
.mkt-measured-estimate { display: flex; align-items: center; gap: 10px; margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line); font-size: 13px; }
.mkt-measured-estimate .mm-est { font-weight: 600; }
.mkt-measured-estimate .mm-gap { color: var(--ink-2); }
.mkt-measured-empty { font-size: 13px; color: var(--ink-2); margin: 4px 0 0; }

/* ========== Volantino A5 (W5/F2) — modal form ridisegnato ========== */
/* Testo descrittivo sotto section-title dentro .sheet */
.mkt-intro-sub { font-size: 13px; color: var(--ink-2); margin: -4px 0 12px; line-height: 1.5; padding: 0 var(--page-pad-x); }
/* Checkbox + label inline (es. "Includi QR") */
.check-inline { display: flex; align-items: flex-start; gap: 8px; font-size: 14px; color: var(--ink); margin-bottom: 12px; cursor: pointer; }
.check-inline input[type="checkbox"] { margin-top: 2px; flex-shrink: 0; width: 16px; height: 16px; accent-color: var(--brand); cursor: pointer; }
/* Blocco AI: sfondo tenue per distinguerlo visivamente */
.flyer-ai { background: var(--bg); border-radius: 12px; padding: 0 0 4px; margin: 0 0 14px; }
.flyer-ai .section-title { padding-left: 0; padding-right: 0; }
.flyer-ai .mkt-intro-sub { padding-left: 0; padding-right: 0; }
.flyer-ai .field { margin-bottom: 10px; }
/* Chip riga occasione dentro il form volantino — usa .chip globale già esistente */
.chip-row { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; }
/* Sub-field-row scoped al form volantino (analoga alla versione .wiz-content) */
.flyer-form .sub-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 480px) { .flyer-form .sub-field-row { grid-template-columns: 1fr; } }
/* Photo picker: griglia 2 colonne con radio nascosto */
.photo-pick { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 16px; }
.photo-opt { position: relative; cursor: pointer; border-radius: 10px; overflow: hidden; border: 2px solid var(--line); transition: border-color 120ms ease; }
.photo-opt input[type="radio"] { position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%; cursor: pointer; margin: 0; }
.photo-opt img { display: block; width: 100%; height: 80px; object-fit: cover; pointer-events: none; }
.photo-opt:has(input:checked) { border-color: var(--brand); }
.photo-opt .cap { display: block; padding: 4px 8px; font-size: 12px; color: var(--ink-2); text-align: center; }
.photo-opt:has(input:checked) .cap { color: var(--brand); font-weight: 700; }
/* Template picker: mini-thumbnail fronte/retro + stato selezionato del tile */
.flyer-tpl-tile { gap: 10px; }
.flyer-tpl-tile.selected { border-color: var(--brand); background: var(--brand-soft); }
.flyer-tile-thumbs { display: flex; gap: 4px; flex: 0 0 auto; }
.flyer-tile-thumbs img { width: 44px; height: auto; border: 1px solid var(--line); border-radius: 4px; background: #fff; }
/* Preview live fronte/retro dentro il form Personalizza */
.flyer-preview { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 0 0 14px; }
.flyer-preview img { width: 100%; height: auto; border: 1px solid var(--line); border-radius: 8px; background: #fff; }
/* Azioni in fondo: Anteprima + Scarica PDF affiancate */
.flyer-actions { display: flex; gap: 8px; margin-top: 18px; }
.flyer-actions .btn-secondary,
.flyer-actions .btn-primary { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }

/* htmx indicator — includeIndicatorStyles:false nel meta htmx-config: lo
   <style> che htmx inietterebbe non ha nonce e la CSP lo bloccherebbe al
   flip in enforcing. Regole identiche al default htmx. */
.htmx-indicator{opacity:0}
.htmx-request .htmx-indicator{opacity:1; transition: opacity 200ms ease-in;}
.htmx-request.htmx-indicator{opacity:1; transition: opacity 200ms ease-in;}

/* Banner riarmo notifiche push: barra in cima, mostrata da push.js quando
   l'intent server è attivo ma il permesso/subscription manca (tipico dopo la
   reinstallazione della PWA su iOS). Nascosto di default via attributo hidden. */
.push-rearm { display: flex; align-items: center; gap: 10px; padding: calc(10px + env(safe-area-inset-top)) 16px 10px; background: var(--brand-soft); border-bottom: 1px solid #F3D6DC; color: var(--brand); font-size: 13px; font-weight: 700; }
.push-rearm[hidden] { display: none; }
.push-rearm__ico { color: var(--brand); flex-shrink: 0; }
.push-rearm__txt { flex: 1; }
.push-rearm__cta { padding: 7px 14px; background: var(--brand); color: #fff; border: 0; border-radius: 999px; font-size: 13px; font-weight: 800; font-family: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; flex-shrink: 0; }
.push-rearm__cta:active { background: var(--brand-hover); }
.push-rearm__cta:disabled { opacity: 0.6; }
.push-rearm__close { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; background: transparent; border: 0; color: var(--brand); cursor: pointer; flex-shrink: 0; -webkit-tap-highlight-color: transparent; }
