/* App cliente Bloomest — CSS layout mobile-only 480px container
   Fonte verita': docs/appcliente/index.html (mockup live, read-only)
   Tokens condivisi: backend/static/shared/tokens.css
   ADR-AC-09: separato dal dashboard, mobile-only
   Cache buster: ?v=1 nei template */

@import url("../shared/tokens.020f0d9ded74.css");

* { 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 — stesso fix della dashboard (2026-07-05). */
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; min-height: 100vh; overflow-x: clip; }
/* 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. 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; }
a { color: inherit; text-decoration: none; }
/* W8 chunk 2 · a11y: focus-visible globale per keyboard nav */
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }
button:focus-visible, a:focus-visible, [role="button"]:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
/* Screen-reader-only utility for non-visible accessible names */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
/* Reset UA h1 margin inside sub-header/app-header (otherwise layout breaks) */
.sub-header h1.ttl, .app-header h1 { margin: 0; }
.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; }
.i-3xl { width: 48px; height: 48px; }

/* App container */
.app { min-height: 100vh; max-width: 480px; margin: 0 auto; background: var(--surface); position: relative; padding-bottom: 88px; }
.screen { display: none; min-height: 100vh; }
.screen.active { display: block; }

/* Header (default non sticky: scorre via per liberare spazio nei tab privati) */
.app-header { background: var(--surface); padding: calc(14px + env(safe-area-inset-top)) 18px 16px; display: flex; align-items: center; justify-content: space-between; gap: 12px; border-bottom: 1px solid var(--line); }
/* Vetrina pubblica: header sticky perche' il bottone "Accedi" e' la CTA primaria */
#screen-public .app-header { position: sticky; top: 0; z-index: 10; }
.app-header h1 { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.2; color: var(--ink); }

/* Powered by Miele endorsement (Brand Manual 2024 pag 22-23, 26-27). Badge
   Miele = SVG ufficiale Miele_Logo_M_Red_sRGB (#8C0014 Pantone 704). Use case
   "Promotional" autorizzato per landing pubblica. */
.powered-by-miele { display: flex; align-items: center; gap: 5px; flex-shrink: 0; }
.powered-by-miele .pbm-txt { font-size: 10px; font-weight: 700; color: var(--ink); letter-spacing: 0.01em; white-space: nowrap; }
.powered-by-miele .pbm-svg { height: 11px; width: auto; display: block; }
/* Su iPhone SE 320px nascondiamo il "Powered by" testo lasciando solo il badge SVG, per non rompere il layout. */
@media (max-width: 360px) {
  .powered-by-miele .pbm-txt { display: none; }
}
.app-header h1 .accent { color: var(--brand); }
.app-header .meta { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
/* Sottotitolo header come switch lavanderia (Card/Promo): pill rossa "solita"
   (= .lab-chip) col nome lab + chevron-down; tap apre #labSwitchModal. */
.app-header .meta-switch { display: inline-flex; align-items: center; gap: 4px; margin-top: 5px; font-size: 11px; font-weight: 800; color: var(--brand); background: var(--brand-soft); border: 1px solid #F3D6DC; border-radius: 999px; padding: 3px 10px; font-family: inherit; white-space: nowrap; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.app-header .meta-switch .i-sm { width: 12px; height: 12px; color: var(--brand); }
.app-header .meta-switch:active { opacity: 0.7; }
.app-header .head-actions { display: flex; gap: 8px; align-items: center; }
.app-header .icon-btn { width: 40px; height: 40px; border-radius: 12px; background: var(--bg); color: var(--ink-2); display: flex; align-items: center; justify-content: center; position: relative; }
.app-header .icon-btn:active { transform: scale(0.94); }
.app-header .icon-btn .dot { position: absolute; top: 8px; right: 8px; width: 8px; height: 8px; background: var(--brand); border-radius: 50%; border: 2px solid var(--surface); }

/* Sub-page header (back-button) */
.sub-header { background: var(--surface); padding: calc(14px + env(safe-area-inset-top)) 18px 14px; display: flex; align-items: center; gap: 10px; border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 10; }
.sub-header .back-btn { width: 40px; height: 40px; border-radius: 12px; background: var(--bg); color: var(--ink-2); display: flex; align-items: center; justify-content: center; }
.sub-header .back-btn:active { transform: scale(0.94); }
.sub-header .ttl { font-size: 17px; font-weight: 800; flex: 1; }
.sub-header .step { font-size: 11px; color: var(--ink-3); font-weight: 700; padding: 4px 10px; background: var(--bg); border-radius: 999px; }

.section-title { padding: 20px 18px 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 .small-link { color: var(--brand); font-size: 13px; font-weight: 600; text-transform: none; letter-spacing: 0; }

/* Bottom nav */
.bottom-nav { position: fixed; bottom: 0; left: 50%; transform: translateX(-50%); width: 100%; max-width: 480px; background: var(--surface); border-top: 1px solid var(--line); display: flex; height: 80px; padding-bottom: env(safe-area-inset-bottom); padding-top: 6px; z-index: 50; }
.bottom-nav button, .bottom-nav a { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; font-size: 11px; color: var(--ink-3); font-weight: 600; padding: 8px 4px; text-decoration: none; transition: background 100ms ease; }
.bottom-nav button.active, .bottom-nav a.active { color: var(--brand); }
.bottom-nav button:active, .bottom-nav a:active { background: var(--bg); }
.bottom-nav button.promo, .bottom-nav a.promo { position: relative; }
.bottom-nav button.promo .promo-badge, .bottom-nav a.promo .promo-badge { position: absolute; top: 6px; right: calc(50% - 22px); background: var(--brand); color: #fff; font-size: 10px; min-width: 18px; height: 18px; border-radius: 9px; display: flex; align-items: center; justify-content: center; padding: 0 5px; font-weight: 800; }
/* Badge "risposta non letta" su icona Account (stesso pattern del badge Promo). */
.bottom-nav a.account { position: relative; }
.bottom-nav a.account .nav-badge { position: absolute; top: 6px; right: calc(50% - 22px); background: var(--brand); color: #fff; font-size: 10px; min-width: 18px; height: 18px; border-radius: 9px; display: flex; align-items: center; justify-content: center; padding: 0 5px; font-weight: 800; }

/* ========== LOGIN ========== */
.login-wrap { padding: 32px 24px; min-height: 100vh; display: flex; flex-direction: column; }
.login-wrap .logo { text-align: center; margin-top: 28px; }
.login-wrap .logo img { max-width: 150px; height: auto; }
.login-wrap .lead { font-size: 16px; color: var(--ink-2); text-align: center; margin-top: 18px; line-height: 1.5; }
.login-wrap .lead strong { color: var(--ink); }
.login-wrap .login-sep { border: 0; height: 1px; background: var(--line); margin: 32px 0 0; width: 100%; }
.login-wrap .form-block { margin-top: 32px; display: flex; flex-direction: column; gap: 20px; }
.login-wrap .form-field { display: flex; flex-direction: column; gap: 6px; }
.login-wrap .form-field label { font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.06em; padding: 0 4px; }
.login-wrap .form-field input { width: 100%; padding: 16px; border: 2px solid var(--line); border-radius: 12px; font-size: 16px; background: var(--bg); color: var(--ink); font-weight: 600; }
.login-wrap .form-field input:focus { border-color: var(--brand); background: #fff; outline: none; }
.login-wrap .form-field input.tessera { font-family: ui-monospace, monospace; letter-spacing: 0.1em; font-size: 16px; }
.login-wrap .help-text { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; padding: 0 4px; line-height: 1.45; }
.login-wrap .help-text strong { color: var(--ink-2); }
.input-with-icon { position: relative; }
.input-with-icon input { padding-right: 60px !important; }
.input-with-icon .scan-btn { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); width: 44px; height: 44px; border-radius: 10px; background: var(--brand); color: #fff; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 6px rgba(140,0,20,0.3); }
.input-with-icon .scan-btn:active { transform: translateY(-50%) scale(0.94); }
.btn-primary { padding: 16px; background: var(--brand); color: #fff; border-radius: 12px; font-size: 16px; font-weight: 800; margin-top: 24px; width: 100%; transition: background 120ms ease, transform 80ms ease; }
.btn-primary:active { background: var(--brand-hover); }
.login-wrap .help-link { text-align: center; padding: 18px 0; font-size: 13px; color: var(--ink-3); margin-top: auto; }
.login-wrap .help-link strong { color: var(--brand); font-weight: 700; }
/* Pagine "link inviato": poco contenuto -> niente min-height:100vh + help-link
   inchiodato in fondo (finiva sotto la piega su mobile). Compatto in una schermata. */
.login-wrap--compact { min-height: auto; }
.login-wrap--compact .help-link { margin-top: 24px; }
.login-wrap .login-newuser-hint { text-align: center; font-size: 13px; color: var(--ink-3); margin-top: 24px; line-height: 1.55; padding: 0 8px; }

/* ========== HOME (Lavaggi) ========== */
.balance-strip { margin: 12px 18px 0; background: var(--surface); border-radius: 18px; box-shadow: var(--shadow-card); padding: 16px; display: flex; align-items: center; gap: 12px; cursor: pointer; transition: background 120ms ease; }
.balance-strip:active { background: var(--bg); }
.balance-strip .b-info { flex: 1; }
.balance-strip .b-info .lbl { font-size: 11px; color: var(--ink-3); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }
.balance-strip .b-info .val { font-size: 30px; font-weight: 800; color: var(--brand); letter-spacing: -0.02em; line-height: 1.1; margin-top: 2px; }
.balance-strip .b-info .place { font-size: 12px; color: var(--ink-2); margin-top: 2px; font-weight: 600; }
.balance-strip .b-cta { padding: 10px 16px; background: var(--brand); color: #fff; border-radius: 12px; font-size: 13px; font-weight: 800; cursor: pointer; flex-shrink: 0; border: 0; }
.balance-strip .b-cta:active { background: var(--brand-hover); transform: scale(0.97); }
.balance-strip .chev { color: var(--ink-3); flex-shrink: 0; }

.wash-card { background: var(--surface); border-radius: 18px; box-shadow: var(--shadow-card); margin: 12px 18px 0; padding: 18px; overflow: hidden; border: 1.5px solid transparent; }
.wash-card.live, .wash-card.dryer { color: var(--ink); border-color: var(--brand); }
.wash-card .strip { margin: -18px -18px 14px; padding: 10px 18px; font-size: 13px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.wash-card.live .strip, .wash-card.dryer .strip { background: linear-gradient(135deg, var(--brand) 0%, var(--brand-dark) 100%); color: #fff; }
.wash-card .strip .dot { width: 7px; height: 7px; background: #fff; border-radius: 50%; animation: pulse 1.5s infinite; }
.wash-card .strip .strip-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wash-card .strip .kg-badge { background: rgba(255,255,255,0.22); color: #fff; font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 10px; letter-spacing: 0.02em; flex-shrink: 0; }
.wash-card .header-row { display: flex; gap: 14px; align-items: center; }
.wash-card .header-text { flex: 1; min-width: 0; }
.wash-card .id-circle { width: 52px; height: 52px; border-radius: 16px; background: #FEE2E2; color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; position: relative; }
.wash-card .id-circle .id-letter { position: absolute; bottom: -4px; right: -4px; background: var(--ink); color: #fff; font-weight: 800; font-size: 12px; min-width: 22px; padding: 0 5px; height: 22px; border-radius: 11px; border: 2px solid var(--surface); display: flex; align-items: center; justify-content: center; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
.wash-card .machine-name { font-size: 16px; font-weight: 700; margin-top: 4px; }
.wash-card .program-name { font-size: 13px; color: var(--ink-3); margin-top: 1px; }
.wash-card .phase-detail { font-size: 12px; color: var(--ink-3); margin-top: 4px; display: flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; }
.wash-card .phase-detail .i-arrow { width: 11px; height: 11px; stroke: var(--ink-3); stroke-width: 2; vertical-align: middle; margin: 0 2px; }
.wash-card .phase-detail .pd-sep { color: var(--line); }
.wash-card .phase-detail .pd-rpm { font-weight: 600; color: var(--ink); }
.wash-card .countdown { font-size: 64px; font-weight: 800; letter-spacing: -0.04em; margin-top: 12px; line-height: 1; font-variant-numeric: tabular-nums; color: var(--brand); }
.wash-card .countdown small { font-size: 64px; font-weight: 800; opacity: 1; margin-left: 0; letter-spacing: -0.04em; }
.wash-card .progress-track { height: 6px; background: #FEE2E2; border-radius: 3px; margin-top: 14px; overflow: hidden; }
.wash-card .progress-fill { height: 100%; background: var(--brand); border-radius: 3px; transition: width .5s; }
.wash-card .end-time { font-size: 12px; color: var(--ink-3); margin-top: 8px; display: flex; justify-content: space-between; }
.wash-card .alarm-row { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.wash-card .alarm-label { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 8px; color: var(--ink); }
.wash-card .alarm-sub { font-size: 11px; color: var(--ink-3); margin-top: 2px; }
/* .toggle-ios allineato esattamente a .toggle-row .toggle in notifiche.html:
   stesso layout 50x30, stesso radius, stesso pallino bianco, stesso brand quando ON.
   Override .wash-card non più necessario: stile base coerente in entrambi i contesti. */
.toggle-ios { width: 50px; height: 30px; background: var(--line); border-radius: 15px; position: relative; transition: background .2s; flex-shrink: 0; cursor: pointer; }
.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.15); }
.toggle-ios.on { background: var(--brand); }
.toggle-ios.on::after { transform: translateX(20px); }

/* F6 · Bottone "Notificami fine ciclo" sotto alarm-row nelle wash-card. */
.wash-card .notify-cycle-btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; margin-top: 10px; padding: 12px 14px; border: 1px solid var(--line); background: var(--surface); color: var(--ink); border-radius: 12px; font-size: 13px; font-weight: 700; cursor: pointer; transition: background .15s, border-color .15s; }
.wash-card .notify-cycle-btn:hover:not(:disabled) { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); }
.wash-card .notify-cycle-btn.is-active { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); cursor: default; }
.wash-card .notify-cycle-btn:disabled { opacity: 0.85; }

.empty-state-card { margin: 12px 18px 0; padding: 30px 20px; text-align: center; color: var(--ink-3); background: var(--surface); border-radius: 18px; box-shadow: var(--shadow-card); }
.empty-state-card .ill { width: 72px; height: 72px; margin: 0 auto 12px; background: var(--brand-soft); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--brand); }
.empty-state-card h3 { font-size: 17px; font-weight: 800; color: var(--ink); margin-bottom: 6px; }
.empty-state-card p { font-size: 13px; line-height: 1.5; }
.empty-state-card .empty-state-cta { display: inline-flex; align-items: center; gap: 6px; margin-top: 14px; padding: 12px 18px; background: var(--brand); color: #fff; border-radius: 12px; font-size: 14px; font-weight: 700; text-decoration: none; transition: background 120ms ease; }
.empty-state-card .empty-state-cta:hover, .empty-state-card .empty-state-cta:active { background: var(--brand-hover); }

.notif-preview { margin: 10px 18px 0; padding: 12px 14px; background: #ECFDF5; border: 1px solid #BBF7D0; border-radius: 12px; font-size: 12px; color: #065F46; display: flex; gap: 10px; align-items: flex-start; text-decoration: none; }
.notif-preview svg { color: #16A34A; flex-shrink: 0; }
.notif-preview strong { display: block; color: #064E3B; font-size: 13px; margin-bottom: 1px; }
/* Design system §7 chevron rule: align-self center quando row e flex-start. */
.notif-preview .chev { align-self: center; }

/* M1 · Inbox notifiche (storico ricevute). Pattern card-list neutra, icona
   tone-aware (ok=verde, info=blu, gold=oro promo, brand=rosso promo). */
.notif-list { margin: 4px 18px 0; background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); overflow: hidden; }
.notif-item { padding: 14px; display: flex; gap: 12px; align-items: flex-start; border-bottom: 1px solid var(--line); }
.notif-item:last-child { border-bottom: none; }
/* Icona in cerchietto tinto per tone (PWA iOS >= 16.4 -> color-mix ok) */
.notif-item-ico { flex-shrink: 0; width: 38px; height: 38px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
.notif-item-ico .i { width: 18px; height: 18px; }
.notif-item-ico--ok { background: color-mix(in srgb, var(--ok) 12%, #fff); color: var(--ok); }
.notif-item-ico--info { background: color-mix(in srgb, var(--info) 12%, #fff); color: var(--info); }
.notif-item-ico--gold { background: color-mix(in srgb, var(--gold) 14%, #fff); color: var(--gold); }
.notif-item-ico--brand { background: var(--brand-soft); color: var(--brand); }
.notif-item-main { flex: 1; min-width: 0; }
.notif-item-text { display: block; font-size: 14px; font-weight: 600; color: var(--ink); line-height: 1.35; }
.notif-item-time { display: block; font-size: 12px; color: var(--ink-3); margin-top: 3px; font-weight: 500; }
/* Item espandibile (<details> nativo): anteprima clampata + chevron rotante */
/* display:block esplicito: <details> eredita il flex-row di .notif-item e
   summary + corpo diventavano DUE COLONNE affiancate (chevron disallineati,
   testo espanso in colonnina destra). Block = summary full-width, corpo sotto. */
details.notif-item { display: block; padding: 0; }
.notif-item-row { padding: 14px; display: flex; gap: 12px; align-items: flex-start; cursor: pointer; list-style: none; -webkit-tap-highlight-color: transparent; }
.notif-item-row::-webkit-details-marker { display: none; }
.notif-item-preview { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: 13px; font-weight: 500; color: var(--ink-2); line-height: 1.4; margin-top: 2px; }
/* Toggle espandi/chiudi: + che diventa × da aperto — stesso pattern di
   .borsellino-month-toggle, il progetto non usa chevron per gli accordion. */
.notif-item-toggle { width: 22px; height: 22px; line-height: 22px; text-align: center; font-size: 20px; font-weight: 400; color: var(--ink-3); flex-shrink: 0; align-self: center; }
.notif-item-toggle::before { content: "+"; }
details[open] > .notif-item-row .notif-item-toggle::before { content: "\00d7"; }
details[open] .notif-item-preview { display: none; }
.notif-item-full { padding: 0 14px 14px 64px; animation: notif-expand .18s ease; }
.notif-item-full p { font-size: 14px; color: var(--ink-2); line-height: 1.5; }
.notif-item-link { display: inline-flex; align-items: center; gap: 4px; margin-top: 10px; font-size: 13px; font-weight: 700; color: var(--brand); text-decoration: none; }
@keyframes notif-expand { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
.notif-empty { margin: 14px 18px 0; padding: 24px 18px; background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); text-align: center; }
.notif-empty svg { color: var(--ink-3); margin-bottom: 10px; }
.notif-empty strong { display: block; font-size: 16px; color: var(--ink); margin-bottom: 6px; }
.notif-empty p { font-size: 13px; color: var(--ink-3); margin-bottom: 14px; line-height: 1.45; }
/* .btn-ghost dell'empty-state usa la regola globale (riga ~660): full-width,
   testo centrato, outline. L'override scoped inline-flex rompeva il centrato. */

/* M3 · Borsellino accordion mese (details/summary nativi).
   Mese corrente expanded di default (attr `open` server-side), gli altri
   collapsed. Chevron ruota 180deg quando expanded. Lo style nasconde il
   triangolino nativo di summary per controllo visivo coerente. */
.borsellino-month { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 8px 18px 0; overflow: hidden; }
.borsellino-month-summary { padding: 14px 16px; display: flex; align-items: center; gap: 10px; cursor: pointer; list-style: none; user-select: none; }
.borsellino-month-summary::-webkit-details-marker { display: none; }
.borsellino-month-summary::marker { content: ''; }
.borsellino-month-label { flex: 1; font-size: 14px; font-weight: 700; color: var(--ink); }
.borsellino-month-count { font-size: 12px; color: var(--ink-3); font-weight: 600; padding: 2px 8px; background: var(--bg); border-radius: 999px; }
.borsellino-month-toggle { width: 22px; height: 22px; line-height: 22px; text-align: center; font-size: 20px; font-weight: 400; color: var(--ink-3); flex-shrink: 0; }
.borsellino-month-toggle::before { content: "+"; }
details[open] > .borsellino-month-summary .borsellino-month-toggle::before { content: "\00d7"; }
.borsellino-month-list { border-top: 1px solid var(--line); }

.history-row { background: var(--surface); padding: 14px 16px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid var(--line); }
.history-row:last-child { border-bottom: none; }
.history-row .ico { width: 38px; height: 38px; border-radius: 10px; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.history-row .body { flex: 1; min-width: 0; }
.history-row .ttl { font-size: 14px; font-weight: 600; }
.history-row .sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.history-row .meta-r { text-align: right; font-size: 12px; color: var(--ink-3); }
.history-row .meta-r strong { display: block; color: var(--ink-2); font-size: 13px; font-weight: 700; }
.history-row-chev { width: 16px; height: 16px; color: var(--ink-3); flex-shrink: 0; }
.history-group { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 10px 18px 0; overflow: hidden; }

/* ========== TESSERA ========== */
.card-tessera-v { margin: 14px 18px 0; background: #fff; border-radius: 18px; padding: 20px 22px 36px; box-shadow: 0 16px 40px rgba(15,20,25,0.18); position: relative; overflow: hidden; border: 1px solid var(--line); }
.card-tessera-v .ct-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.card-tessera-v .ct-title { font-size: 13px; font-weight: 800; letter-spacing: 0.06em; color: var(--ink); text-transform: uppercase; }
.card-tessera-v .ct-top-right { display: flex; align-items: center; gap: 10px; }
.card-tessera-v .ct-uid { font-size: 13px; font-weight: 800; letter-spacing: 0.06em; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.card-tessera-v .ct-switch { font-size: 13px; font-weight: 700; color: var(--ink-2); border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px; background: var(--bg); cursor: pointer; -webkit-appearance: none; appearance: none; }
.card-tessera-v .ct-balance { margin-top: 14px; display: flex; align-items: baseline; gap: 8px; }
.card-tessera-v .ct-bal-val { font-size: 34px; font-weight: 800; color: var(--brand); letter-spacing: -0.02em; line-height: 1; font-variant-numeric: tabular-nums; }
.card-tessera-v .ct-bal-lbl { font-size: 11px; color: var(--ink-3); font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; }
.card-tessera-v .ct-meta { margin-top: 16px; font-size: 13px; color: var(--ink-2); line-height: 1.65; }
.card-tessera-v .ct-meta strong { color: var(--ink); font-weight: 800; }
/* Bottone primario Ricarica dentro la card (pattern wallet) */
.card-tessera-v .recharge-divider { border: 0; border-top: 1px solid var(--line); margin: 16px 0 0; }
.card-tessera-v .ct-recharge { display: flex; align-items: center; justify-content: center; gap: 9px; width: 100%; margin: 16px 0 0; padding: 15px; background: var(--brand); color: #fff; border: 0; border-radius: 13px; font-size: 15px; font-weight: 800; cursor: pointer; transition: transform 100ms ease, background-color 120ms ease; }
.card-tessera-v .ct-recharge:active { background: var(--brand-hover); }
.card-tessera-v .ct-recharge svg { width: 18px; height: 18px; color: #fff; flex-shrink: 0; }
/* Due bottoni secondari affiancati sotto la card */
.ct-actions2 { display: flex; gap: 10px; margin: 10px 18px 0; }
.ct-act-btn { flex: 1; display: flex; align-items: center; justify-content: center; gap: 7px; padding: 12px 8px; border: 1px solid var(--line); border-radius: 12px; font-size: 12.5px; font-weight: 700; color: var(--ink-2); background: var(--surface); text-decoration: none; cursor: pointer; transition: transform 100ms ease, background-color 120ms ease; }
.ct-act-btn:active { background: var(--bg); }
.ct-act-btn svg { width: 15px; height: 15px; color: var(--ink-3); flex-shrink: 0; }
.ct-act-btn.danger { color: #c0182e; }
.ct-act-btn.danger svg { color: #c0182e; }
/* Sheet metodi di ricarica (per-lavanderia) */
.recharge-method { display: flex; align-items: center; gap: 12px; padding: 12px 4px; text-decoration: none; color: inherit; border-top: 1px solid var(--line); transition: transform 100ms ease, background-color 120ms ease; }
.recharge-method:active { background: var(--bg); }
.recharge-method:first-of-type { border-top: 0; }
.recharge-method .rm-logo { width: 42px; height: 42px; border-radius: 11px; background: var(--satispay); color: #fff; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.recharge-method .rm-logo svg { width: 24px; height: 24px; color: #fff; fill: none; stroke: currentColor; }
.recharge-method .rm-body { flex: 1; }
.recharge-method .rm-ttl { font-size: 15px; font-weight: 700; }
.recharge-method .rm-sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.recharge-method .arr { color: var(--ink-3); }

.purse-card { background: var(--surface); border-radius: 14px; padding: 14px; box-shadow: var(--shadow-card); margin: 10px 18px 0; display: flex; align-items: center; gap: 14px; cursor: pointer; }
.purse-card:active { background: var(--bg); }
.purse-card.primary { border: 1.5px solid var(--brand); background: linear-gradient(180deg, #fff 60%, var(--brand-soft) 100%); }
.purse-card .star-mark { color: var(--brand); flex-shrink: 0; }
.purse-card .place-ico { width: 40px; height: 40px; border-radius: 12px; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.purse-card .info { flex: 1; min-width: 0; }
.purse-card .info .nm { font-size: 14px; font-weight: 700; display: flex; align-items: center; gap: 6px; }
.purse-card .info .nm small { font-size: 10px; padding: 2px 6px; border-radius: 999px; background: var(--brand); color: #fff; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.purse-card .info .ad { font-size: 11px; color: var(--ink-3); margin-top: 2px; }
.purse-card .balance { text-align: right; }
.purse-card .balance .v { font-size: 18px; font-weight: 800; color: var(--brand); letter-spacing: -0.01em; }
.purse-card .balance .l { font-size: 10px; color: var(--ink-3); text-transform: uppercase; font-weight: 700; letter-spacing: 0.05em; }
.purse-card .arr { color: var(--ink-3); flex-shrink: 0; opacity: 0.6; margin-left: 4px; }

.satispay-cta { margin: 14px 18px 0; padding: 14px 16px; background: var(--surface); border: 1.5px solid var(--line); border-radius: 14px; display: flex; align-items: center; gap: 12px; cursor: pointer; }
.satispay-cta:active { background: var(--bg); }
.satispay-cta .ssp-logo { width: 44px; height: 44px; border-radius: 11px; background: var(--satispay); color: #fff; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.satispay-cta .ssp-logo svg { width: 26px; height: 26px; color: #fff; fill: none; stroke: currentColor; }
.ssp-hero-logo { width: 100px; height: 100px; border-radius: 26px; background: var(--satispay); color: #fff; display: flex; align-items: center; justify-content: center; box-shadow: 0 16px 40px rgba(255,54,37,0.35); animation: pulseGrow 1.5s infinite; }
.ssp-hero-logo svg { width: 56px; height: 56px; color: #fff; fill: none; stroke: currentColor; }
.satispay-cta .body { flex: 1; }
.satispay-cta .ttl { font-size: 14px; font-weight: 700; }
.satispay-cta .sub { font-size: 11px; color: var(--ink-3); margin-top: 2px; }

.in-store-recharge { margin: 12px 0 0; padding: 0 18px; font-size: 12px; color: var(--ink-3); line-height: 1.5; }
.in-store-recharge strong { color: var(--ink-2); font-weight: 700; }
/* Carosello card (una per lavanderia) */
.ct-carousel-wrap { position: relative; }
.ct-carousel { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.ct-carousel::-webkit-scrollbar { display: none; }
.ct-slide { flex: 0 0 100%; scroll-snap-align: center; box-sizing: border-box; display: flex; }
.ct-slide .card-tessera-v { flex: 1; }
.ct-arrow { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2; width: 34px; height: 34px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: var(--shadow-card); }
.ct-arrow-prev { left: 6px; }
.ct-arrow-next { right: 6px; }
.ct-arrow svg { width: 18px; height: 18px; }
.ct-dots { display: flex; justify-content: center; gap: 7px; position: absolute; left: 0; right: 0; bottom: 14px; margin: 0; z-index: 3; }
.ct-dot { width: 7px; height: 7px; border-radius: 999px; border: 0; padding: 0; background: var(--line); cursor: pointer; transition: width 140ms ease, background-color 140ms ease; }
.ct-dot.is-active { background: var(--brand); width: 18px; }
.ct-qr { display: flex; flex-direction: column; align-items: center; gap: 8px; margin: 16px 0 0; }
.ct-qr img { border-radius: 12px; }
.ct-qr-cap { font-size: 12px; color: var(--ink-3); font-weight: 700; }
/* Card attiva (badge) + azione "Usa questa lavanderia" (conferma esplicita) */
.card-tessera-v .ct-active-badge { display: inline-flex; align-items: center; gap: 4px; margin-left: 8px; padding: 2px 8px; border-radius: 999px; background: var(--brand); color: #fff; font-size: 10px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; vertical-align: middle; }
.card-tessera-v .ct-active-badge svg { width: 11px; height: 11px; color: #fff; }
.ct-use-lab-form { margin: 12px 0 0; }
.ct-use-lab { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; padding: 12px; background: var(--surface); color: var(--brand); border: 1px solid var(--brand); border-radius: 12px; font-size: 14px; font-weight: 800; cursor: pointer; transition: background-color 120ms ease; }
.ct-use-lab svg { width: 16px; height: 16px; color: var(--brand); }
.ct-use-lab:active { background: var(--bg); }

/* === Tab Card ridisegno 2026-06-20 · card hero contrasto A, Movimenti(chip lab),
   "I miei saldi", stato senza-card, banner geo (niente carosello) === */
.card-tessera-v--hero { box-shadow: 0 18px 44px rgba(15, 20, 25, 0.20); }
.card-tessera-v--hero .ct-bal-val { font-size: 40px; }

/* Titolo Movimenti + chip della lavanderia attiva (i movimenti sono di quel lab). */
.sec-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 32px 18px 0; }
/* padding:0 -> il testo "Movimenti" parte dal margine del .sec-head (18px), allineato
   a "I miei saldi" (.section-title, padding-left 18px); senza, sommava 18+18=36px. */
.sec-head .section-title { margin: 0; padding: 0; }
.lab-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 800; color: var(--brand); background: var(--brand-soft); border: 1px solid #F3D6DC; border-radius: 999px; padding: 3px 10px; white-space: nowrap; }
.lab-chip svg { width: 12px; height: 12px; }

/* I miei saldi: lista Card del cliente, tap su una riga = POST set_active_lab. */
.saldi { margin: 10px 18px 0; background: var(--surface); border-radius: 16px; box-shadow: var(--shadow-card); overflow: hidden; border: 1px solid var(--line); }
.saldo-row-form { margin: 0; }
.saldo-row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 13px 15px; border: 0; border-bottom: 1px solid var(--line); background: var(--surface); text-align: left; cursor: pointer; -webkit-appearance: none; appearance: none; transition: background 120ms ease; }
.saldo-row-form:last-of-type .saldo-row { border-bottom: 0; }
.saldo-row:active { background: var(--bg); }
.saldo-row.active { background: var(--brand-soft); }
.saldo-row .ic { width: 34px; height: 34px; border-radius: 10px; background: var(--bg); color: var(--ink-3); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.saldo-row.active .ic { background: var(--surface); color: var(--brand); }
.saldo-row .ic svg { width: 17px; height: 17px; }
.saldo-row .bdy { flex: 1; min-width: 0; }
.saldo-row .nm { font-size: 14px; font-weight: 800; color: var(--ink); display: flex; align-items: center; gap: 7px; }
.saldo-row .mini { font-size: 9px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; color: var(--brand); background: var(--surface); border: 1px solid #F3D6DC; border-radius: 999px; padding: 1px 6px; }
.saldo-row .ad { font-size: 12px; color: var(--ink-3); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.saldo-row .bal { font-size: 16px; font-weight: 800; color: var(--brand); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.saldo-foot { display: flex; align-items: center; justify-content: space-between; padding: 11px 15px; font-size: 12px; color: var(--ink-3); border-top: 1px solid var(--line); }
.saldo-foot .v { color: var(--ink); font-weight: 800; }

/* Stato "senza Card a questa lavanderia" (al posto della card hero). */
.nocard { margin: 14px 18px 0; background: var(--surface); border-radius: 18px; box-shadow: var(--shadow-card); border: 1px solid var(--line); padding: 16px; }
.nocard .nc-top { display: flex; align-items: flex-start; gap: 12px; }
.nocard .nc-ico { width: 38px; height: 38px; border-radius: 11px; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.nocard .nc-ico svg { width: 20px; height: 20px; }
.nocard .nc-head-txt { display: flex; flex-direction: column; }
.nocard .nc-h { font-size: 15px; font-weight: 800; line-height: 1.25; color: var(--ink); }
.nocard .nc-place { font-size: 12px; color: var(--ink-3); margin-top: 2px; font-weight: 600; }
.nocard .nc-sub { font-size: 13px; color: var(--ink-2); line-height: 1.5; margin: 12px 0 0; }
.nc-info { margin: 13px 0 0; border-top: 1px solid var(--line); padding-top: 13px; display: flex; flex-direction: column; gap: 11px; }
.nc-item { display: flex; align-items: center; gap: 11px; }
.nc-item .ii { width: 30px; height: 30px; border-radius: 9px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.nc-item .ii.buy { background: var(--brand-soft); color: var(--brand); }
.nc-item .ii.gift { background: var(--gold-soft); color: var(--gold); }
.nc-item .ii svg { width: 16px; height: 16px; }
.nc-item .tt { display: flex; flex-direction: column; flex: 1; min-width: 0; line-height: 1.3; }
.nc-item .q { font-size: 13px; font-weight: 800; color: var(--ink); }
.nc-item .a { font-size: 12px; color: var(--ink-3); }
.nc-cta { margin: 14px 0 0; width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px; background: var(--surface); color: var(--brand); border: 1px solid var(--brand); border-radius: 12px; font-size: 13px; font-weight: 800; text-decoration: none; }
.nc-cta svg { width: 16px; height: 16px; }
.nc-cta:active { background: var(--brand-soft); }

/* Banner geo non-modale, riusato in home e Card. */
.geo-strip { display: flex; align-items: center; gap: 11px; margin: 12px 18px 0; background: var(--brand-soft); border: 1px solid #F3D6DC; border-radius: 14px; padding: 11px 12px; }
.geo-strip .geo-pin { width: 32px; height: 32px; border-radius: 9px; background: var(--surface); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.geo-strip .geo-pin svg { width: 17px; height: 17px; }
.geo-strip .geo-tt { display: flex; flex-direction: column; flex: 1; min-width: 0; line-height: 1.25; }
.geo-strip .geo-q { font-size: 13px; font-weight: 800; color: var(--brand); }
.geo-strip .geo-a { font-size: 11px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.geo-strip .geo-go { flex-shrink: 0; background: var(--brand); color: #fff; font-size: 13px; font-weight: 800; padding: 8px 14px; border-radius: 9px; border: 0; cursor: pointer; }
.geo-strip .geo-go:active { background: var(--brand-hover); }
.geo-strip .geo-x { flex-shrink: 0; width: 28px; height: 28px; border-radius: 8px; background: var(--surface); color: var(--ink-3); display: flex; align-items: center; justify-content: center; border: 0; cursor: pointer; }
.geo-strip .geo-x svg { width: 14px; height: 14px; }

.purse-concept-card { margin: 14px 18px 0; background: var(--brand-soft); border-radius: 12px; padding: 12px 14px; display: flex; align-items: flex-start; gap: 10px; }
.purse-concept-card .info-mark { width: 20px; height: 20px; color: var(--brand); flex-shrink: 0; margin-top: 1px; }
.purse-concept-card .pcc-body { font-size: 13px; color: var(--ink-2); line-height: 1.45; }
.purse-concept-card .pcc-body strong { color: var(--ink); font-weight: 700; display: block; margin-bottom: 2px; }

.concept-note { margin: 24px 18px 18px; font-size: 11.5px; color: var(--ink-3); text-align: center; line-height: 1.5; }

/* ========== PROMO ========== */
.fid-hero { margin: 14px 18px 0; background: linear-gradient(135deg, #FBBF24 0%, #B45309 100%); color: #fff; border-radius: 18px; padding: 20px; box-shadow: 0 12px 28px rgba(180,83,9,0.28); position: relative; overflow: hidden; }
.fid-hero::before { content: ""; position: absolute; top: -30px; right: -30px; width: 130px; height: 130px; background: radial-gradient(circle, rgba(255,255,255,0.25) 0%, transparent 70%); border-radius: 50%; }
.fid-hero .lbl-up { font-size: 11px; font-weight: 700; opacity: 0.95; text-transform: uppercase; letter-spacing: 0.08em; }
.fid-hero h3 { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; margin-top: 4px; line-height: 1.15; }
.fid-hero .progress-line { display: flex; gap: 4px; margin-top: 18px; }
.fid-hero .progress-line span { flex: 1; height: 6px; background: rgba(255,255,255,0.25); border-radius: 3px; }
.fid-hero .progress-line span.done { background: #fff; }
.fid-hero .progress-line span.next { background: rgba(255,255,255,0.6); position: relative; }
.fid-hero .progress-line span.next::after { content: ""; position: absolute; right: 0; top: -3px; width: 12px; height: 12px; background: #fff; border-radius: 50%; box-shadow: 0 0 0 3px rgba(255,255,255,0.4); }
.fid-hero .progress-meta { display: flex; justify-content: space-between; font-size: 12px; margin-top: 10px; opacity: 0.95; font-weight: 600; }

/* Programma fedeltà: sezione bianca (no hero arancione) con progresso a pallini verdi. */
.section-sub { padding: 0 18px 8px; margin: -2px 0 0; font-size: 13px; color: var(--ink-3); }
.fid-program { margin: 0 18px; background: var(--surface); border-radius: 16px; box-shadow: var(--shadow-card); padding: 16px 18px; }
.fid-program-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.fid-program-count { font-size: 20px; font-weight: 800; letter-spacing: -0.01em; color: var(--ink); }
.fid-program-ico { color: var(--ok-text); flex-shrink: 0; }
.progress-line--green { display: flex; gap: 4px; margin-top: 12px; }
.progress-line--green span { flex: 1; height: 6px; background: var(--line); border-radius: 3px; }
.progress-line--green span.done { background: var(--ok-text); }
.fid-program-meta { margin-top: 10px; font-size: 13px; font-weight: 600; color: var(--ink-2); }
.fid-program-expiry { margin-top: 8px; font-size: .86rem; color: var(--ink-3); }
.fid-reward { background: var(--ok-soft); border: 1px solid var(--ok-text); border-radius: 12px; padding: 12px 14px; margin: 8px 18px 14px; }
.fid-reward-top { display: flex; align-items: center; gap: 8px; }
.fid-reward-title { font-weight: 700; text-transform: uppercase; letter-spacing: .02em; font-size: .86rem; }
.fid-reward-body { margin: 6px 0 4px; }
.fid-reward-meta { font-weight: 600; color: var(--ok-text); }

.promo-card { margin: 10px 18px 0; background: var(--surface); border-radius: 16px; box-shadow: var(--shadow-card); overflow: hidden; }
.promo-card .pc-header { padding: 14px 16px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid var(--line); }
.promo-card .pc-header .ic { width: 44px; height: 44px; border-radius: 12px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.promo-card .pc-header .ic.discount { background: var(--brand); color: #fff; }
.promo-card .pc-header .ic.welcome { background: var(--ok-soft); color: var(--ok-text); }
.promo-card .pc-header .ic.ric { background: var(--gold-soft); color: var(--gold); }
.promo-card .pc-header .body { flex: 1; }
.promo-card .pc-header .ttl { font-size: 15px; font-weight: 800; }
.promo-card .pc-header .sub { font-size: 12px; color: var(--ink-3); margin-top: 1px; }
.promo-card .pc-header .badge-end { font-size: 10px; padding: 3px 8px; border-radius: 999px; background: var(--brand-soft); color: var(--brand); font-weight: 700; }
/* Happy Hour in corso ora: bordo verde + pill "in corso ora". */
.promo-card--live { border: 1.5px solid var(--ok-border); }
.promo-card .pc-header .ttl .hh-live { font-size: 11px; font-weight: 700; color: var(--ok-text); background: var(--ok-soft); padding: 1px 7px; border-radius: 999px; margin-left: 4px; }
.promo-card .pc-body { padding: 14px 16px; font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.promo-card .pc-body strong { color: var(--ink); }

/* Card a costo zero · public anon · stile neutro con pill PROMO arancione (Andrea 2026-05-18: no rosso brand, era fuorviante). */
.card-promo-public { margin: 24px 18px 0; padding: 16px 18px; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-card); }
.card-promo-public .cpp-tag { display: inline-block; font-size: 11px; font-weight: 800; letter-spacing: 0.08em; color: var(--warn); background: var(--gold-soft); padding: 4px 10px; border-radius: 999px; text-transform: uppercase; }
.card-promo-public .cpp-title { font-size: 18px; font-weight: 800; color: var(--ink); margin-top: 10px; line-height: 1.25; }
.card-promo-public .cpp-sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
.card-promo-public .cpp-body { font-size: 13px; color: var(--ink-2); line-height: 1.55; margin-top: 10px; }
.card-promo-public .cpp-body strong { color: var(--ink); }

.referral-block { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 10px 18px 0; padding: 16px; }
.referral-block .code-box { padding: 12px 14px; background: var(--brand-soft); border: 1.5px dashed var(--brand); border-radius: 10px; display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; }
.referral-block .code-box .code { font-family: ui-monospace, monospace; font-size: 18px; font-weight: 800; color: var(--brand); letter-spacing: 0.08em; }
.referral-block .code-box button { padding: 6px 14px; background: var(--brand); color: #fff; border-radius: 8px; font-size: 12px; font-weight: 700; }
.referral-block .ref-cta { display: flex; gap: 8px; margin-top: 12px; }
.referral-block .ref-cta a { flex: 1; padding: 10px; border-radius: 10px; background: var(--bg); color: var(--ink-2); display: flex; align-items: center; justify-content: center; gap: 6px; font-size: 12px; font-weight: 700; }
.referral-block .ref-cta a.wa { background: #DCFCE7; color: var(--ok); }

/* ========== ACCOUNT ========== */
.prof-hero { background: var(--surface); padding: 24px 18px 18px; text-align: center; }
.prof-hero .av { width: 72px; height: 72px; border-radius: 50%; background: linear-gradient(135deg, var(--brand) 0%, var(--brand-dark) 100%); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 28px; margin: 0 auto 12px; }
.prof-hero .nm { font-size: 18px; font-weight: 800; }
.prof-hero .em { font-size: 13px; color: var(--ink-3); margin-top: 2px; }

.menu-row { background: var(--surface); padding: 14px 18px; display: flex; align-items: center; gap: 14px; cursor: pointer; transition: background 120ms ease; }
.menu-row:active { background: var(--bg); }
.menu-row .ico { width: 36px; height: 36px; border-radius: 10px; background: var(--bg); color: var(--ink-2); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.menu-row .ico.danger { background: #FCE4E4; color: var(--danger); }
.menu-row .ico.wa { background: var(--brand-soft); color: var(--brand); }
.menu-row .ico.call { background: var(--brand-soft); color: var(--brand); }
.menu-row .ico.problem { background: var(--gold-soft); color: var(--gold); }
.menu-row .ico.bulb { background: var(--brand-soft); color: var(--brand); }
.menu-row .ttl { flex: 1; font-size: 14px; font-weight: 600; }
.menu-row .ttl small { display: block; color: var(--ink-3); font-size: 11px; font-weight: 500; margin-top: 1px; }
.menu-row .arr { color: var(--ink-3); }
/* Badge numerico "risposta non letta" sulla riga "Le mie segnalazioni". */
.menu-row .row-badge { background: var(--brand); color: #fff; font-size: 11px; min-width: 20px; height: 20px; border-radius: 10px; display: flex; align-items: center; justify-content: center; padding: 0 6px; font-weight: 800; flex-shrink: 0; }
.menu-group { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 10px 18px 0; overflow: hidden; }
.menu-group .menu-row { border-bottom: 1px solid var(--line); }
.menu-group .menu-row:last-child { border-bottom: none; }
.app-version { text-align: center; font-size: 11px; color: var(--ink-3); padding: 24px 0 12px; }

/* ========== LAVANDERIA SUB-PAGE ========== */
.lab-hero { padding: 14px 18px 0; }
.lab-hero h2 { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; }
.lab-hero .ad { font-size: 13px; color: var(--ink-3); margin-top: 4px; }
/* Orari "Tutti i giorni …": grigio (come l'indirizzo) ma bold, icona allineata al centro col testo */
.lab-hero .ad.lab-hours { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; }

.contact-strip { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin: 14px 18px 0; }
.contact-strip a { border-radius: 14px; padding: 9px 6px; display: flex; flex-direction: column; align-items: center; gap: 3px; text-align: center; cursor: pointer; text-decoration: none; }
.contact-strip a:active { transform: scale(0.97); }
.contact-strip a.call { background: var(--brand-soft); }
.contact-strip a.wa { background: var(--brand-soft); }
.contact-strip a.dir { background: var(--brand-soft); }
.contact-strip a .ic { width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; background: transparent; }
.contact-strip a .ic .i { width: 20px; height: 20px; }
.contact-strip a.call .ic { color: var(--brand); }
.contact-strip a.wa .ic { color: var(--brand); }
.contact-strip a.dir .ic { color: var(--brand); }
.contact-strip a .ttl { font-size: 12px; font-weight: 800; }
.contact-strip a.call .ttl { color: var(--brand); }
.contact-strip a.wa .ttl { color: var(--brand); }
.contact-strip a.dir .ttl { color: var(--brand); }

.cm-card { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 10px 18px 0; padding: 14px; display: flex; align-items: center; gap: 14px; cursor: pointer; transition: background 120ms ease; }
.cm-card:active { background: var(--bg); }
.cm-card.busy { background: #FFF5F5; }
/* opacity removed (WCAG). Bordo grigio neutro: distingue stato non-disponibile senza allarmismo (Andrea 2026-05-18 chiede il dimming neutro, non un bordo rosso che sembra errore critico). */
.cm-card.broken { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line), var(--shadow-card); }
.cm-card.broken .info .nm { color: var(--ink-2); }
.cm-card.booked { background: #F5F9FF; }
/* Icona macchina — 4 stati: verde libera · rossa occupata · blu prenotata · grigia guasta */
.cm-card .id-circle { width: 52px; height: 52px; border-radius: 16px; background: #DCFCE7; color: var(--ok); display: flex; align-items: center; justify-content: center; flex-shrink: 0; position: relative; }
.cm-card.busy .id-circle { background: #FEE2E2; color: var(--danger); }
.cm-card.booked .id-circle { background: #DBEAFE; color: var(--info); }
.cm-card.broken .id-circle { background: var(--bg); color: var(--ink-3); }
.cm-card .id-circle .id-letter { position: absolute; bottom: -4px; right: -4px; background: var(--ink); color: #fff; font-weight: 800; font-size: 12px; min-width: 22px; padding: 0 5px; height: 22px; border-radius: 11px; border: 2px solid var(--surface); display: flex; align-items: center; justify-content: center; }
.cm-card .info { flex: 1; min-width: 0; }
.cm-card .info .nm { font-size: 14px; font-weight: 700; }
.cm-card .info .price { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.cm-card .right { text-align: right; flex-shrink: 0; }
.cm-card .right .countdown { font-size: 16px; font-weight: 800; letter-spacing: -0.02em; color: var(--danger); font-variant-numeric: tabular-nums; }
.cm-card.booked .right .countdown { color: var(--info); }
.cm-card .right .lbl { font-size: 10px; color: var(--ink-3); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; margin-top: 2px; }
.cm-card .right .lbl .lbl-q { text-transform: none; font-weight: 600; letter-spacing: 0; opacity: 0.85; }
.cm-card .pill-status { font-size: 11px; padding: 3px 9px; border-radius: 999px; font-weight: 700; }
.cm-card .pill-status.free { background: #E8F8EE; color: var(--ok-text); }
.cm-card .pill-status.broken { background: var(--bg); color: var(--ink-3); }
.cm-card .pill-status.booked { background: #DBEAFE; color: var(--info); }
.cm-card .right .arr { color: var(--ink-3); opacity: 0.5; vertical-align: middle; margin-left: 4px; }
/* Menu icona ... sulla card macchina */

/* ========== MODAL ========== */
.modal-backdrop { position: fixed; inset: 0; background: rgba(15,20,25,0.5); display: none; align-items: flex-end; z-index: 100; }
.modal-backdrop.open { display: flex; }
.sheet { background: var(--surface); border-radius: 24px 24px 0 0; width: 100%; max-width: 480px; margin: 0 auto; max-height: 92%; overflow-y: auto; padding: 22px 22px calc(22px + env(safe-area-inset-bottom)); animation: slideUp .25s ease; }
@keyframes slideUp { from { transform: translateY(100%) } to { transform: translateY(0) } }
.sheet-handle { width: 44px; height: 4px; background: var(--line); border-radius: 2px; margin: -6px auto 18px; }
/* Close button (X) in top-right del sheet modal · UX bloccante senza, su mobile non c'e' backdrop tappabile fullscreen. */
.sheet { position: relative; }
.sheet-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--bg);
  border: 0;
  color: var(--ink-2);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 2;
}
.sheet-close:active { background: var(--line); }
.sheet-close .i { width: 20px; height: 20px; stroke: currentColor; stroke-width: 2.5; fill: none; }
.sheet h3 { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; }
.sheet .sub-l { font-size: 13px; color: var(--ink-3); margin-top: 4px; margin-bottom: 18px; }
.sheet .machine-block { padding: 14px; background: var(--bg); border-radius: 12px; display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.sheet .machine-block .id-circle { width: 48px; height: 48px; border-radius: 14px; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; position: relative; }
.sheet .machine-block .id-circle .id-letter { position: absolute; bottom: -4px; right: -4px; background: var(--ink); color: #fff; font-weight: 800; font-size: 11px; min-width: 20px; height: 20px; padding: 0 5px; border-radius: 10px; border: 2px solid var(--surface); display: flex; align-items: center; justify-content: center; }
.sheet .machine-block .nm { font-size: 14px; font-weight: 700; }
.sheet .machine-block .sub-l2 { font-size: 11px; color: var(--ink-3); margin-top: 2px; }

.disclaimer-box { padding: 14px; background: #FFF8DB; border: 1px solid #FCE4A0; border-radius: 12px; font-size: 13px; color: #7A5C00; line-height: 1.55; display: flex; gap: 10px; align-items: flex-start; }
.disclaimer-box svg { color: var(--gold); flex-shrink: 0; margin-top: 1px; }
.disclaimer-box strong { color: #7A4F00; }

.grace-box { margin-top:10px;padding:12px;background:#ECFDF5;border:1px solid #BBF7D0;border-radius:12px;font-size:12.5px;color:#065F46;line-height:1.45;display:flex;gap:10px;align-items:flex-start; }
.grace-box svg { color: var(--ok); flex-shrink: 0; margin-top: 1px; }

.sheet-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }
.btn-confirm { padding: 15px; background: var(--brand); color: #fff; border-radius: 12px; font-size: 15px; font-weight: 800; }
/* CTA disabilitato in modo PERMANENTE (feature gated, es. prenotazione): grigio esplicito.
   NON stilare :disabled globale sui .btn-*: i flussi async (WebAuthn, fetch) disabilitano
   i bottoni per la durata dell'operazione e non devono cambiare aspetto. */
.btn-gated:disabled { background: var(--line); color: var(--ink-3); cursor: not-allowed; }
/* Annulla = neutro leggero (allineato a .btn-secondary del design system), non nero pieno. */
.btn-cancel { padding: 14px; background: var(--bg); color: var(--ink-2); border: 1px solid var(--line); border-radius: 12px; font-size: 14px; font-weight: 700; }
.btn-danger { padding: 15px; background: var(--danger); color: #fff; border-radius: 12px; font-size: 15px; font-weight: 800; }

/* Lost card modal */
.lost-info { padding: 14px 16px; background: var(--bg); border-radius: 12px; margin-bottom: 14px; }
.lost-info .row { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; font-size: 14px; color: var(--ink-2); }
.lost-info .row + .row { border-top: 1px solid var(--line); }
.lost-info .row .v { font-weight: 800; color: var(--ink); }
.lost-actions { display: flex; gap: 10px; margin-top: 18px; }
.lost-actions a { flex: 1; padding: 14px 12px; border-radius: 12px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; font-size: 13px; font-weight: 800; }
.lost-actions a:active { transform: scale(0.97); }
.lost-actions .lost-call { background: var(--brand-soft); color: var(--brand); }
.lost-actions .lost-wa { background: var(--brand-soft); color: var(--brand); }

/* Movimento detail · link di aiuto inline (WhatsApp precompilato / chiamata gestore) */
.mov-help-link { color: var(--brand); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.mov-help-link:active { opacity: 0.7; }

/* Toast obsolete rule rimossa post-C7 (causava stretch height su iOS Safari per
   cascade con .toast top-positioned riga ~554). Regola attiva unica: top-positioned. */

/* Camera modal */
.camera-modal { position: fixed; inset: 0; background: #0a0a0a; display: none; flex-direction: column; z-index: 150; }
.camera-modal.open { display: flex; }
.camera-modal .cm-header { padding: 14px 18px; padding-top: calc(14px + env(safe-area-inset-top)); display: flex; align-items: center; gap: 10px; color: #fff; }
.camera-modal .cm-header button { width: 38px; height: 38px; border-radius: 12px; background: rgba(255,255,255,0.15); color: #fff; display: flex; align-items: center; justify-content: center; }
.camera-modal .cm-header .ttl { flex: 1; text-align: center; font-size: 15px; font-weight: 700; }
.camera-modal .viewport { margin: 0 18px; flex: 1; max-height: 380px; background: #1c1c1c; border-radius: 18px; position: relative; overflow: hidden; display: flex; align-items: center; justify-content: center; }
.camera-modal .viewport .card-mock { width: 240px; aspect-ratio: 1.585; background: #fff; border-radius: 10px; position: relative; transform: rotate(-2deg); box-shadow: 0 8px 24px rgba(0,0,0,0.4); }
.camera-modal .viewport .card-mock .uid { position:absolute;top:8px;right:10px;font-family:ui-monospace,monospace;font-size:11px;font-weight:700;color:var(--ink); }
.camera-modal .viewport .card-mock .lg { position:absolute;top:38%;left:50%;transform:translateX(-50%);font-size:18px;font-weight:800;letter-spacing:-0.04em;color:var(--ink); }
.camera-modal .viewport .ocr-frame { position: absolute; top: 24px; right: 36px; width: 130px; height: 28px; border: 2.5px solid var(--brand); border-radius: 6px; box-shadow: 0 0 30px rgba(140,0,20,0.5); animation: pulseGrow 2s infinite; }
@keyframes pulseGrow { 0%,100% { transform: scale(1); } 50% { transform: scale(1.05); } }
.camera-modal .viewport .corners > div { position: absolute; width: 24px; height: 24px; }
.camera-modal .viewport .corners .tl { top: 14px; left: 14px; border-top: 3px solid #fff; border-left: 3px solid #fff; border-radius: 6px 0 0 0; }
.camera-modal .viewport .corners .tr { top: 14px; right: 14px; border-top: 3px solid #fff; border-right: 3px solid #fff; border-radius: 0 6px 0 0; }
.camera-modal .viewport .corners .bl { bottom: 14px; left: 14px; border-bottom: 3px solid #fff; border-left: 3px solid #fff; border-radius: 0 0 0 6px; }
.camera-modal .viewport .corners .br { bottom: 14px; right: 14px; border-bottom: 3px solid #fff; border-right: 3px solid #fff; border-radius: 0 0 6px 0; }
.camera-modal .recognized { margin: 14px 18px 0; padding: 14px; background: rgba(22,163,74,0.15); border:1px solid rgba(22,163,74,0.4); border-radius: 12px; color:#fff; display:flex; gap:12px; align-items:center; }
.camera-modal .recognized .ic { width: 42px; height: 42px; background: var(--ok); border-radius: 12px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.camera-modal .recognized .lbl { font-size: 11px; opacity: 0.85; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700; }
.camera-modal .recognized .code { font-size: 18px; font-weight: 800; letter-spacing: 0.1em; font-family: ui-monospace, monospace; margin-top: 2px; }
.camera-modal .actions { padding: 18px; padding-bottom: calc(18px + env(safe-area-inset-bottom)); display: flex; flex-direction: column; gap: 10px; }
.camera-modal .actions button.primary { padding: 16px; background: var(--brand); color: #fff; border-radius: 14px; font-size: 15px; font-weight: 800; }
.camera-modal .actions button.ghost { padding: 12px; background: transparent; color: rgba(255,255,255,0.7); font-size: 13px; font-weight: 600; }

/* ========== LAVANDERIA SWITCHER (header) ========== */
.lab-switch { margin: 12px 18px 0; padding: 14px 16px; background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); display: flex; align-items: center; gap: 12px; cursor: pointer; transition: background 120ms ease; }
.lab-switch:active { background: var(--bg); }
.lab-switch .pin-ico { width: 38px; height: 38px; border-radius: 11px; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.lab-switch .body { flex: 1; min-width: 0; }
.lab-switch .lab-label { font-size: 11px; color: var(--ink-3); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }
.lab-switch .lab-name { font-size: 20px; font-weight: 800; letter-spacing: -0.02em; color: var(--ink); line-height: 1.1; margin-top: 2px; display: flex; align-items: center; gap: 4px; }
.lab-switch .lab-addr { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
/* riga orari nella card (scheda lavanderia: mostra gli orari al posto dello status) */
.lab-switch .lab-hours { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ink-3); font-weight: 700; margin-top: 4px; }
.lab-switch .lab-hours .i { width: 13px; height: 13px; flex-shrink: 0; }
.lab-switch .chev { color: var(--ink-3); flex-shrink: 0; }
.lab-switch.with-actions { flex-direction: column; align-items: stretch; cursor: default; }
/* padding interno compensato da margin negativo uguale: lo sfondo hover/active
 * "respira" attorno al testo senza spostare il layout (no shift, divider fermo). */
.lab-switch.with-actions .lab-switch-row { display: flex; align-items: center; gap: 12px; cursor: pointer; border-radius: 12px; margin: -7px -10px; padding: 7px 10px; width: calc(100% + 20px); transition: background 120ms ease; }
/* Card non interamente cliccabile: nessun feedback di sfondo sull'intero container.
 * La riga "Cambia" e le azioni (Chiama/WhatsApp) hanno ciascuna il proprio. */
.lab-switch.with-actions:active { background: var(--surface); }
.lab-switch.with-actions .lab-switch-row:active { background: var(--bg); }
/* Sezione disponibilita': pannello tintato in fondo alla card, separato dalle actions */
/* Banner disponibilità — card a sé sotto la lavanderia (pattern .cm-card).
   Verde = disponibile (spunta + "libere"); "tutte occupate" = warn. Sfondo bianco, niente brand. */
.lab-availability { display: flex; align-items: center; gap: 14px; margin: 10px 18px 0; padding: 14px; background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); cursor: pointer; text-decoration: none; color: inherit; transition: background 120ms ease; }
.lab-availability:active { background: var(--bg); }
.lab-availability .ic { width: 44px; height: 44px; border-radius: 12px; background: #DCFCE7; color: var(--ok); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.lab-availability .body { flex: 1; min-width: 0; }
.lab-availability .ttl { font-size: 14px; font-weight: 700; color: var(--ok-text); }
.lab-availability .sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.lab-availability .chev { color: var(--ink-3); flex-shrink: 0; }
.lab-availability.busy .ic { background: #FEF3C7; color: var(--warn); }
.lab-availability.busy .ttl { color: var(--warn); }
.lab-switch .lab-status { font-size: 12px; margin-top: 4px; display: inline-flex; align-items: center; gap: 6px; font-weight: 700; color: var(--ok-text); }
.lab-switch .lab-status .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); flex-shrink: 0; }
.lab-switch .lab-status.closed { color: var(--brand); }
.lab-switch .lab-status.closed .dot { background: var(--brand); }
.lab-actions { display: flex; gap: 8px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.lab-actions a { flex: 1; padding: 8px 6px; border-radius: 12px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; font-size: 12px; font-weight: 800; }
.lab-actions a .i { width: 20px; height: 20px; }
.lab-actions a:active { transform: scale(0.97); }
.lab-actions a.call { background: var(--brand-soft); color: var(--brand); }
.lab-actions a.wa { background: var(--brand-soft); color: var(--brand); }
.lab-actions a.dir { background: var(--brand-soft); color: var(--brand); }

.availability-pill { margin: 10px 18px 0; padding: 12px 14px; background: #ECFDF5; border: 1px solid #BBF7D0; border-radius: 12px; color: #065F46; display: flex; align-items: center; gap: 10px; font-size: 13px; cursor: pointer; }
.availability-pill:active { background: #DCFCE7; }
.availability-pill .ic { width: 32px; height: 32px; border-radius: 8px; background: var(--ok); color: #fff; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.availability-pill .body { flex: 1; min-width: 0; }
.availability-pill .ttl { font-weight: 700; color: #064E3B; }
.availability-pill .sub { font-size: 11px; opacity: 0.85; margin-top: 1px; }
.availability-pill .chev { color: var(--ok); flex-shrink: 0; opacity: 0.6; }
.availability-pill.busy { background: #FFFBEB; border-color: #FCD34D; color: #92400E; }
.availability-pill.busy .ic { background: var(--warn); }
.availability-pill.busy .ttl { color: #78350F; }
.availability-pill.busy .chev { color: var(--warn); }

/* Modal cambio lavanderia — regole spostate a riga ~1012 (consolidato 2026-05-22) */

.locate-btn { margin: 10px 18px 0; padding: 12px 14px; background: var(--brand-soft); color: var(--brand); border-radius: 12px; display: flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 700; cursor: pointer; }
.locate-btn:active { background: #FBE4EA; }
.locate-btn svg { flex-shrink: 0; }

.lab-list-row { background: var(--surface); padding: 14px 16px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid var(--line); cursor: pointer; }
.lab-list-row:last-child { border-bottom: none; }
.lab-list-row:active { background: var(--bg); }
.lab-list-row.active { background: var(--brand-soft); }
.lab-list-row .ic { width: 38px; height: 38px; border-radius: 10px; background: var(--bg); color: var(--ink-2); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.lab-list-row.active .ic { background: var(--brand); color: #fff; }
.lab-list-row .body { flex: 1; min-width: 0; }
.lab-list-row .nm { font-size: 14px; font-weight: 700; display: flex; align-items: center; gap: 4px; }
.lab-list-row .ad { font-size: 11px; color: var(--ink-3); margin-top: 2px; }
.lab-list-row .balance { text-align: right; font-size: 13px; font-weight: 700; color: var(--brand); flex-shrink: 0; }
.lab-list-row .check { color: var(--brand); flex-shrink: 0; }

/* ========== FORM SCREENS (problema, miglioramento, dati, ecc.) ========== */
.form-screen { padding: 14px 18px 24px; }
.form-screen .intro { font-size: 14px; color: var(--ink-2); line-height: 1.5; margin-bottom: 18px; }
.form-screen .field { margin-bottom: 16px; }
.form-screen .field label { display: block; font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px; padding: 0 4px; }
/* font-size 16px: sotto i 16px iOS Safari zooma sull'input al focus. min-width:0:
   in una riga grid (.field-row) gli <input> hanno una min-width intrinseca (~20
   char) che i track fr non comprimono → la riga deborda (Prov tagliata). */
.form-screen .field input, .form-screen .field textarea, .form-screen .field select { width: 100%; min-width: 0; padding: 14px 16px; border: 1.5px solid var(--line); border-radius: 12px; font-size: 16px; background: var(--surface); color: var(--ink); font-family: inherit; }
.form-screen .field textarea { min-height: 120px; resize: vertical; }
.form-screen .field input:focus, .form-screen .field textarea:focus, .form-screen .field select:focus { border-color: var(--brand); outline: none; }
.form-screen .field .help { font-size: 11px; color: var(--ink-3); margin-top: 4px; padding: 0 4px; }
.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; }
/* Righe form a piu colonne (app cliente) — evita il "monolite" di campi full-width:
   campi correlati appaiati a larghezze diverse, come fanno i form anagrafici ben fatti.
   Pattern allineato a .field-row della dashboard, qui assente. */
.form-screen .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; }
.form-screen .field-row--phone-dob { grid-template-columns: 1fr 50%; }      /* Data nascita 50% (col mese corto "12 giu 1990" ci sta su phone >=360px); Telefono prende il resto */
.form-screen .field-row--loc { grid-template-columns: 3fr 5fr 2fr; }       /* CAP 30 · Città 50 · Prov 20 */
/* Provincia nascosta per-Paese (DE/AT/PT): la riga torna a CAP 30 · Città 70. */
.form-screen .field-row--loc:has([data-b2b-province][hidden]) { grid-template-columns: 3fr 7fr; }
.form-screen .field-row--loc label { white-space: nowrap; }                /* label "PROVINCIA" su una riga */
.form-screen .field-row > .field { min-width: 0; }                         /* i figli grid si comprimono: niente overflow orizzontale (Prov tagliata) */
/* Campi compatti: stesso formato degli altri, ma a larghezza ridotta. */
.form-screen .field--w-30 { width: 30%; min-width: 110px; }
.form-screen .field--w-40 { width: 40%; min-width: 140px; }
.form-screen .field--w-50 { width: 50%; min-width: 170px; }  /* su phone ≥390px è un vero 50% (177px); 170px = minimo che non taglia "Scegli il Paese" (testo 104px + overhead select) sugli schermi stretti */
.form-screen .field--w-60 { width: 60%; min-width: 170px; }
.form-screen .field--w-80 { width: 80%; min-width: 200px; }
/* Select: chevron custom con respiro dal bordo (il nativo Safari resta incollato). */
.form-screen .field select {
  -webkit-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='14'%20height='14'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23666D78'%20stroke-width='2.5'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='m6%209%206%206%206-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 42px;
}

/* Datepicker custom — JS condiviso in static/shared/datepicker.js (stesso della dashboard).
   Stile scopato sotto .form-screen per battere .field input/select.
   Desktop: calendario custom; touch (pointer:coarse): overlay nativo .dt-native. */
.form-screen .dt-field { position: relative; }
.form-screen .dt-trigger { display: flex; align-items: stretch; padding: 0; border: 1.5px solid var(--line); border-radius: 12px; background: var(--surface); overflow: hidden; transition: border-color 120ms ease; }
.form-screen .dt-field.open .dt-trigger,
.form-screen .dt-trigger:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.form-screen .dt-trigger .dt-display { flex: 1; min-width: 0; padding: 14px 4px 14px 16px; border: none; outline: none; background: transparent; font-size: 16px; font-weight: 600; color: var(--ink); font-family: inherit; }
.form-screen .dt-trigger .dt-display::placeholder { color: var(--ink-3); font-weight: 500; }
.form-screen .dt-trigger .dt-icon-btn { width: 46px; 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; }
.form-screen .dt-trigger .dt-icon-btn:active { background: var(--brand-soft); }
.form-screen .dt-trigger svg.cal-ico { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.form-screen .dt-popover { position: absolute; top: calc(100% + 6px); right: 0; left: auto; 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; }
.form-screen .dt-field.open .dt-popover { display: block; }
.form-screen .cal-head { display: flex; align-items: center; justify-content: space-between; padding: 0 4px 10px; }
.form-screen .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; }
.form-screen .cal-head button:active { transform: scale(0.9); }
.form-screen .cal-head .cal-month { font-size: 14px; font-weight: 700; color: var(--ink); display: flex; gap: 6px; align-items: center; }
.form-screen .dt-popover .cal-month select { appearance: auto; -webkit-appearance: auto; background-image: none; width: auto; min-width: 0; padding: 4px 6px; border: 1px solid var(--line); border-radius: 8px; font-size: 16px; font-weight: 700; background-color: var(--bg); color: var(--ink); font-family: inherit; }
.form-screen .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; padding: 4px 0 2px; }
.form-screen .cal-dow { font-size: 10px; color: var(--ink-3); text-align: center; font-weight: 700; text-transform: uppercase; padding: 4px 0 6px; }
.form-screen .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; }
.form-screen .cal-day:active { transform: scale(0.9); }
.form-screen .cal-day.other { color: var(--ink-3); opacity: 0.4; }
.form-screen .cal-day.today { font-weight: 800; box-shadow: inset 0 0 0 1.5px var(--brand); }
.form-screen .cal-day.selected { background: var(--brand); color: #fff; font-weight: 700; }
/* Overlay nativo invisibile: su touch apre il picker OS, su desktop è inerte. */
.form-screen .dt-field .dt-native { position: absolute; left: 0; right: 0; bottom: 0; height: 100%; 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) {
  .form-screen .dt-trigger { pointer-events: none; }
  .form-screen .dt-popover { display: none !important; }
  .form-screen .dt-field .dt-native { pointer-events: auto; }
}
.form-screen .submit-btn { width: 100%; padding: 16px; background: var(--brand); color: #fff; border-radius: 12px; font-size: 15px; font-weight: 800; margin-top: 12px; }
.form-screen .submit-btn:active { background: var(--brand-hover); }
.form-screen .submit-btn:disabled { background: var(--line); color: var(--ink-3); }
.form-screen .photo-upload { display: flex; gap: 12px; padding: 14px; border: 2px dashed var(--line); border-radius: 12px; align-items: center; cursor: pointer; background: var(--bg); }
.form-screen .photo-upload .ic { width: 44px; height: 44px; border-radius: 10px; background: var(--surface); color: var(--ink-2); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.form-screen .photo-upload .body { flex: 1; }
.form-screen .photo-upload .ttl { font-size: 14px; font-weight: 700; color: var(--ink); }
.form-screen .photo-upload .sub { font-size: 11px; color: var(--ink-3); margin-top: 2px; }
.form-screen .radio-group { display: flex; flex-direction: column; gap: 8px; }
.form-screen .radio-tile { padding: 14px 16px; border: 1.5px solid var(--line); border-radius: 12px; background: var(--surface); display: flex; align-items: center; gap: 12px; cursor: pointer; }
.form-screen .radio-tile.selected { border-color: var(--brand); background: var(--brand-soft); }
.form-screen .radio-tile .dot { width: 22px; height: 22px; border: 2px solid var(--line); border-radius: 50%; flex-shrink: 0; position: relative; }
.form-screen .radio-tile.selected .dot { border-color: var(--brand); background: var(--brand); }
.form-screen .radio-tile.selected .dot::after { content: ""; position: absolute; inset: 4px; background: #fff; border-radius: 50%; }
.form-screen .radio-tile .body .ttl { font-size: 14px; font-weight: 700; }
.form-screen .radio-tile .body .sub { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }

/* Toggle setting rows (notifiche) */
.toggle-row { background: var(--surface); padding: 16px 18px; display: flex; align-items: center; gap: 14px; border-bottom: 1px solid var(--line); }
.toggle-row:last-child { border-bottom: none; }
.toggle-row .body { flex: 1; }
.toggle-row .ttl { font-size: 14px; font-weight: 600; color: var(--ink); }
.toggle-row .sub { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; line-height: 1.4; }
.toggle-row .toggle { width: 50px; height: 30px; background: var(--line); border-radius: 15px; position: relative; flex-shrink: 0; cursor: pointer; transition: background 0.2s; }
.toggle-row .toggle::after { content: ""; position: absolute; top: 2px; left: 2px; width: 26px; height: 26px; background: #fff; border-radius: 50%; box-shadow: 0 2px 4px rgba(0,0,0,0.15); transition: transform 0.2s; }
.toggle-row .toggle.on { background: var(--brand); }
.toggle-row .toggle.on::after { transform: translateX(20px); }

/* Receipt list */
.receipt-row { background: var(--surface); padding: 14px 16px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid var(--line); cursor: pointer; }
.receipt-row:last-child { border-bottom: none; }
.receipt-row:active { background: var(--bg); }
.receipt-row .ic { width: 38px; height: 38px; border-radius: 10px; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.receipt-row .body { flex: 1; min-width: 0; }
.receipt-row .ttl { font-size: 14px; font-weight: 700; }
.receipt-row .sub { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.receipt-row .total { text-align: right; flex-shrink: 0; }
.receipt-row .total .v { font-size: 14px; font-weight: 700; color: var(--ink); }
.receipt-row .total .l { font-size: 10px; color: var(--ink-3); margin-top: 2px; }
.receipt-group { background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); margin: 10px 18px 0; overflow: hidden; }

/* Plain content (terms, privacy) */
.content-page { padding: 14px 18px 24px; font-size: 14px; line-height: 1.6; color: var(--ink-2); }
.content-page h2 { font-size: 16px; font-weight: 800; color: var(--ink); margin-top: 22px; margin-bottom: 8px; }
.content-page h2:first-child { margin-top: 0; }
.content-page p { margin-bottom: 12px; }
.content-page strong { color: var(--ink); }

/* Satispay flow */
.recharge-here { margin: 14px 18px 0; padding: 12px 14px; background: var(--brand-soft); border-radius: 10px; display:flex;align-items:center;gap:8px;font-size: 12px; color: var(--brand); }
.amount-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 0 18px; margin-top: 14px; }
.amount-tile { background: var(--surface); border: 2px solid var(--line); border-radius: 16px; padding: 22px 12px; cursor: pointer; text-align: center; position: relative; }
.amount-tile.selected { border-color: var(--brand); background: var(--brand-soft); }
.amount-tile .amount { font-size: 28px; font-weight: 800; color: var(--ink); letter-spacing: -0.02em; }
.amount-tile.selected .amount { color: var(--brand); }
.amount-tile .bonus-pill { position: absolute; top: -10px; right: 10px; background: var(--ok); color: #fff; font-size: 10px; font-weight: 800; padding: 4px 8px; border-radius: 999px; box-shadow: 0 4px 8px rgba(22,163,74,0.3); white-space: nowrap; }
.amount-tile .bonus-line { font-size: 11px; color: var(--ok); font-weight: 700; margin-top: 4px; }
/* Ricarica Satispay (Fase 1): radio nativo nascosto, selezione via :has (no JS) */
.amount-tile input[type="radio"] { position: absolute; opacity: 0; width: 0; height: 0; }
.amount-tile:has(input[type="radio"]:checked) { border-color: var(--brand); background: var(--brand-soft); }
.amount-tile:has(input[type="radio"]:checked) .amount { color: var(--brand); }
.amount-tile-custom { grid-column: 1 / -1; padding: 16px; text-align: left; }
.amount-custom-field { display: flex; align-items: center; gap: 8px; }
.amount-custom-field input[type="number"] { flex: 1; min-width: 0; border: 0; background: transparent; font-size: 24px; font-weight: 800; color: var(--ink); letter-spacing: -0.02em; -moz-appearance: textfield; outline: none; padding: 0; }
.amount-custom-field input[type="number"]::-webkit-outer-spin-button, .amount-custom-field input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.amount-custom-field input[type="number"]::placeholder { color: var(--ink-3); font-weight: 700; font-size: 17px; letter-spacing: normal; }
.amount-custom-field .ac-cur { font-size: 24px; font-weight: 800; color: var(--ink-3); }
.amount-tile-custom:has(input[type="radio"]:checked) .amount-custom-field input,
.amount-tile-custom:has(input[type="radio"]:checked) .amount-custom-field .ac-cur { color: var(--brand); }
.form-error { margin: 14px 18px 0; padding: 10px 14px; background: #fdecea; color: #b3261e; border-radius: 10px; font-size: 13px; font-weight: 600; }
.bonus-active { margin: 14px 18px 0; padding: 14px; background: linear-gradient(135deg, #ECFDF5 0%, #D1FAE5 100%); border: 1px solid #6EE7B7; border-radius: 14px; display: flex; gap: 12px; align-items: flex-start; }
.bonus-active .ic { width: 36px; height: 36px; border-radius: 10px; background: var(--ok); color: #fff; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.bonus-active .body .ttl { font-size: 13px; font-weight: 800; color: #065F46; }
.bonus-active .body .sub { font-size: 12px; color: #047857; margin-top: 2px; line-height: 1.4; }
.btn-pay-satispay { padding: 16px; background: var(--satispay); color: #fff; border-radius: 14px; font-size: 15px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; gap: 10px; width: 100%; }
.btn-pay-satispay .ssp-mini { width: 24px; height: 24px; background: #fff; color: var(--satispay); border-radius: 6px; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px; }
.btn-pay-satispay .ssp-mini svg { width: 16px; height: 16px; fill: none; stroke: currentColor; }
.recap-card { margin: 18px 18px 0; padding: 14px; background: var(--surface); border-radius: 14px; box-shadow: var(--shadow-card); }
.recap-card .row { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; font-size: 13px; }
.recap-card .row .lbl { color: var(--ink-3); }
.recap-card .row .v { font-weight: 700; }
.recap-card .row.bonus .lbl, .recap-card .row.bonus .v { color: var(--ok); }
.recap-card .row.total { font-size: 16px; padding-top: 10px; margin-top: 6px; border-top: 1.5px solid var(--ink-2); font-weight: 800; }
.recap-card .row.total .v { color: var(--brand); }

/* Success generic */
.success-screen { padding: 40px 24px; display: flex; flex-direction: column; align-items: center; }
.success-screen .check-circle { width: 96px; height: 96px; border-radius: 50%; background: #DCFCE7; color: var(--ok); display: flex; align-items: center; justify-content: center; }
.success-screen h2 { font-size: 24px; font-weight: 800; letter-spacing: -0.02em; margin-top: 24px; text-align: center; }
.success-screen .lead { font-size: 14px; color: var(--ink-2); text-align: center; margin-top: 8px; line-height: 1.5; }

/* Video player mock */
.video-player { background: #000; aspect-ratio: 16/9; display: flex; align-items: center; justify-content: center; color: rgba(255,255,255,0.6); position: relative; }
.video-player .play-btn { width: 64px; height: 64px; border-radius: 50%; background: rgba(255,255,255,0.95); color: var(--ink); display: flex; align-items: center; justify-content: center; }
.video-player .play-btn svg { margin-left: 4px; }
.video-player .vid-title { position: absolute; bottom: 14px; left: 18px; right: 18px; color: #fff; font-size: 16px; font-weight: 700; }

/* Hardening tap-friendly su aree interattive (no text selection, link clean) */
a.lab-switch-row, a.lab-availability, a.menu-row, a.purse-card, a.cm-card, a.wash-card,
a.satispay-cta, a.receipt-row, a.promo-card { text-decoration: none; color: inherit; }
.lab-switch-row, .lab-availability, .menu-row, .purse-card, .cm-card,
.wash-card, .satispay-cta, .receipt-row, .promo-card, .toggle-row,
.b-cta, .b-info, .btn-primary, .btn-cancel, .btn-confirm, .btn-danger, .submit-btn,
.bottom-nav button, .bottom-nav a, .menu-row .ttl, .menu-row .ico,
.amount-tile, .radio-tile { -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
/* iOS tap delay kill */
a, button, .menu-row, .lab-switch-row, .lab-availability { touch-action: manipulation; }

/* Toast notification (auto-dismiss 3s).
   Posizionato in alto: evita conflitto con bottom-nav presente/assente e con
   keyboard mobile aperta sotto. translateY iniziale verso l'alto per slide-down. */
/* Toast con varianti semantiche (default=success verde, .warning=arancio, .error=rosso).
   Tutti i bg superano WCAG AA 4.5:1 con white text (success 5.02:1, warning 5.03:1, error 4.86:1). */
.toast { position: fixed; top: calc(60px + env(safe-area-inset-top)); left: 50%; transform: translateX(-50%) translateY(-120%); width: calc(100% - 36px); max-width: 444px; background: var(--ok-text); color: #fff; padding: 14px 18px; border-radius: 14px; font-size: 14px; font-weight: 600; line-height: 1.4; box-shadow: 0 8px 24px rgba(21,128,61,0.25); z-index: 200; opacity: 0; transition: opacity .25s ease, transform .25s ease; pointer-events: none; }
.toast.warning { background: #B45309; box-shadow: 0 8px 24px rgba(180,83,9,0.25); }
.toast.error { background: var(--danger); box-shadow: 0 8px 24px rgba(220,38,38,0.25); }
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* Desktop: limit width but keep mobile feel */
@media (min-width: 768px) {
  .app { box-shadow: 0 0 60px rgba(0,0,0,0.06); }
}

/* ============================================================
   W2 Auth additions (gap segnalati Agent G, fix 2026-05-17)
   ============================================================ */

/* Radio toggle email/whatsapp dentro .login-wrap.
   position:relative: ancora i radio nascosti (position:absolute) al toggle —
   senza ancestor posizionato in WebKit si stirano dal containing block pagina
   (stesso pattern del bug zoom iOS dashboard, 2026-07-05). */
.channel-toggle { display: flex; gap: 8px; margin-top: 8px; position: relative; }
.channel-toggle input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.channel-option { flex: 1; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px 14px; border: 2px solid var(--line); border-radius: 12px; background: var(--bg); color: var(--ink-2); font-size: 15px; font-weight: 700; cursor: pointer; transition: border-color 120ms, background 120ms; }
.channel-option .i { width: 16px; height: 16px; }
.channel-toggle input[type="radio"]:checked + .channel-option { border-color: var(--brand); background: var(--brand-soft); color: var(--brand); }
.channel-toggle .channel-option.wa-option { /* riserva accent verde quando attivo */ }
.channel-toggle input[type="radio"]:checked + .channel-option.wa-option { border-color: var(--whatsapp); background: #DCFCE7; color: #0F5132; }

/* Bottoni: anchor styled as button + secondary ghost + sub-label */
a.btn-link, .btn-link { display: block; text-align: center; text-decoration: none; }
.btn-ghost { display: block; width: 100%; padding: 14px 16px; background: transparent; color: var(--ink-2); border: 2px solid var(--line); border-radius: 12px; font-size: 15px; font-weight: 700; text-align: center; text-decoration: none; margin-top: 12px; }
.btn-ghost:active { background: var(--bg); }
.btn-ghost[disabled], .btn-ghost.is-disabled { opacity: 0.5; pointer-events: none; }
.btn-sub { display: block; font-size: 11px; font-weight: 600; opacity: 0.75; margin-top: 4px; letter-spacing: 0.02em; }

/* Auth feedback icon box (email_sent, whatsapp_sent, invalid_link, welcome) */
.auth-feedback { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 28px 22px; text-align: center; }
.auth-feedback .af-icon { width: 64px; height: 64px; border-radius: 50%; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; }
.auth-feedback .af-icon .i { width: 32px; height: 32px; }
.auth-feedback .af-title { font-size: 20px; font-weight: 800; color: var(--ink); margin-top: 4px; }
.auth-feedback .af-body { font-size: 15px; line-height: 1.5; color: var(--ink-2); }
.auth-feedback .af-body strong { color: var(--ink); font-weight: 700; }
.auth-feedback.wa .af-icon { background: #DCFCE7; color: #0F5132; }
.auth-feedback.warn .af-icon { background: #FEF3C7; color: var(--gold); }
.auth-feedback.note .af-icon { background: var(--bg); color: var(--ink-2); }

/* Welcome bonus box (welcome.html) */
.welcome-bonus { margin: 20px 18px 0; padding: 22px 18px; background: linear-gradient(135deg, var(--brand-soft) 0%, #FFFFFF 100%); border: 1px solid var(--brand-soft); border-radius: 16px; display: flex; align-items: center; gap: 16px; box-shadow: var(--shadow-card); }
.welcome-bonus .wb-icon { width: 56px; height: 56px; border-radius: 14px; background: var(--brand); color: #fff; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.welcome-bonus .wb-icon .i { width: 28px; height: 28px; }
.welcome-bonus .wb-info { flex: 1; min-width: 0; }
.welcome-bonus .wb-amount { font-size: 28px; font-weight: 800; color: var(--brand); letter-spacing: -0.02em; line-height: 1.1; }
.welcome-bonus .wb-label { font-size: 13px; font-weight: 600; color: var(--ink-2); margin-top: 2px; }

/* ============================================================
   W3 Schermate core (gap segnalati Agent I, fix 2026-05-17)
   ============================================================ */

/* Movimento amount color-coded (positivo / negativo) */
.mov-pos { color: var(--ok); }
.mov-neg { color: var(--danger); }

/* Empty state lista movimenti */
.empty-movimenti { padding: 32px 22px; text-align: center; color: var(--ink-3); font-size: 14px; }

/* Bottone "Carica altri" sotto lista paginata */
.load-more-btn { display: block; width: calc(100% - 36px); margin: 16px 18px 0; padding: 14px; background: var(--bg); border: 1px solid var(--line); border-radius: 12px; color: var(--ink-2); font-size: 14px; font-weight: 700; text-align: center; cursor: pointer; }
.load-more-btn:active { background: var(--surface); }

/* Anchor wrapper su menu-row e card-detail (sostituiscono onclick mockup) */
a.menu-row-link, a.card-detail-link { display: block; text-decoration: none; color: inherit; }

/* Empty state Card (tessera.html quando cards e' vuota) */
.empty-card-block { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 40px 22px; text-align: center; }
.empty-card-icon { width: 64px; height: 64px; border-radius: 50%; background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; }
.empty-card-icon .i { width: 32px; height: 32px; }
.empty-card-title { font-size: 18px; font-weight: 800; color: var(--ink); margin-top: 4px; }
.empty-card-text { font-size: 14px; line-height: 1.5; color: var(--ink-2); }

/* Spacer di fondo pagina sopra bottom-nav */
.page-bottom-spacer { height: 24px; }

/* ==========================================================
   W5 · Voucher cliente (lista + dettaglio)
   ========================================================== */

/* Wrapper schermata voucher */
.voucher-screen { padding: 16px 18px 80px; }
.voucher-screen .intro { font-size: 14px; color: var(--ink-2); margin: 4px 2px 14px; }

/* Card voucher in lista — billboard tappable */
.voucher-card {
  display: block;
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px 44px 14px 16px;
  margin-bottom: 12px;
  text-decoration: none;
  color: inherit;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition: background 120ms ease;
}
.voucher-card:active { background: var(--bg); }
.voucher-card .arr {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--ink-3);
}

.vc-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; gap: 10px; }
.vc-amount { font-size: 22px; font-weight: 800; color: var(--ink); letter-spacing: -0.3px; }
.vc-code { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 15px; font-weight: 700; color: var(--brand); letter-spacing: 0.5px; margin-bottom: 4px; }
.vc-meta { font-size: 12px; color: var(--ink-3); display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.vc-sep { opacity: 0.6; }

/* Ticket detail header compatto: icon + kind/category + status chip in riga, meta sotto */
.td-header { padding: 14px 18px 12px; border-bottom: 1px solid var(--line); margin-bottom: 14px; }
.td-header-row { display: flex; align-items: center; gap: 8px; }
.td-header-row .i { width: 18px; height: 18px; color: var(--ink-2); flex-shrink: 0; }
.td-title { font-size: 14px; font-weight: 700; color: var(--ink); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.td-meta { font-size: 12px; color: var(--ink-3); margin-top: 6px; padding-left: 26px; }

/* Ticket detail thread (timeline messaggi cliente ↔ gestore) */
.td-thread { display: flex; flex-direction: column; gap: 10px; padding: 0 18px; margin-bottom: 16px; }
.td-msg { padding: 10px 14px; border-radius: 14px; max-width: 88%; }
.td-msg-meta { font-size: 11px; color: var(--ink-3); margin-bottom: 4px; font-weight: 600; }
.td-msg-body { font-size: 14px; line-height: 1.5; color: var(--ink); white-space: pre-wrap; }
.td-msg--cliente { background: var(--bg); align-self: flex-end; border-bottom-right-radius: 4px; }
.td-msg--gestore { background: #F0FDF4; align-self: flex-start; border-bottom-left-radius: 4px; }
.td-empty { display: flex; align-items: flex-start; gap: 10px; padding: 14px; background: var(--bg); border-radius: 12px; font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.td-empty .i { width: 18px; height: 18px; color: var(--ink-3); flex-shrink: 0; margin-top: 2px; }

/* Form risposta cliente sotto la timeline */
.td-reply-form { padding: 14px 18px 24px; border-top: 1px solid var(--line); margin-top: 6px; }
.td-reply-label { display: block; font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px; padding: 0 4px; }
.td-reply-form textarea { width: 100%; min-height: 90px; padding: 12px 14px; border: 1.5px solid var(--line); border-radius: 12px; font-size: 16px; background: var(--surface); color: var(--ink); font-family: inherit; resize: vertical; }
.td-reply-form textarea:focus { border-color: var(--brand); outline: none; }
.td-reply-form .submit-btn { width: 100%; padding: 14px; background: var(--brand); color: #fff; border-radius: 12px; font-size: 15px; font-weight: 800; margin-top: 10px; }
.td-reply-form .submit-btn:active { background: var(--brand-hover); }

.td-closed-banner { display: flex; align-items: center; gap: 10px; margin: 14px 18px 24px; padding: 14px; background: var(--bg); border-radius: 12px; font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.td-closed-banner .i { width: 20px; height: 20px; color: var(--ok-text); flex-shrink: 0; }

/* Status badge — riusa il pattern del badge ma con varianti voucher */
.status-badge {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
  letter-spacing: 0.2px;
  text-transform: uppercase;
  white-space: nowrap;
}
.status-badge--emesso { background: #e8f5e9; color: #2e7d32; }
.status-badge--riscosso { background: var(--bg); color: var(--ink-2); }
.status-badge--scaduto { background: #fbe9e7; color: #c62828; }
.status-badge--annullato { background: var(--bg); color: var(--ink-3); text-decoration: line-through; }

/* Empty state riusabile (lista voucher vuota, ticket vuoti) */
.empty-state {
  text-align: center;
  padding: 56px 24px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.empty-state .ico {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--brand-soft);
  color: var(--brand);
  display: flex;
  align-items: center;
  justify-content: center;
}
.empty-state .ico .i { width: 36px; height: 36px; }
.empty-state .ttl { font-size: 17px; font-weight: 800; color: var(--ink); margin-top: 4px; }
.empty-state .sub { font-size: 14px; line-height: 1.5; color: var(--ink-2); max-width: 320px; }
.empty-state--inline { padding: 32px 20px 16px; }

/* Voucher detail — QR frame + status banner (Step B userà queste classi) */
.voucher-detail { padding: 16px 18px 80px; }
.voucher-qr-frame {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 24px;
  margin: 18px auto;
  max-width: 320px;
  text-align: center;
}
.voucher-qr-frame img { width: 100%; max-width: 260px; height: auto; image-rendering: pixelated; }
.voucher-qr-frame .vqr-code { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 16px; font-weight: 700; color: var(--brand); letter-spacing: 1px; margin-top: 14px; }
.voucher-qr-frame .vqr-hint { font-size: 12px; color: var(--ink-3); margin-top: 6px; }

.voucher-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 12px;
  margin: 12px 0 16px;
  font-size: 14px;
  font-weight: 600;
}
.voucher-banner--riscosso { background: #e8f5e9; color: #2e7d32; }
.voucher-banner--scaduto { background: #fbe9e7; color: #c62828; }
.voucher-banner--annullato { background: var(--bg); color: var(--ink-2); }
.voucher-banner .i { flex-shrink: 0; }

/* ==========================================================
   W5 · Movimento detail (drill-down lavaggi.html)
   ========================================================== */
.mov-detail { padding: 18px 18px 80px; }

.mov-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 24px 16px 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  margin-bottom: 22px;
  gap: 4px;
}
.mov-hero-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 8px;
}
.mov-hero-icon--in { background: #e8f5e9; color: #2e7d32; }
.mov-hero-icon--out { background: var(--brand-soft); color: var(--brand); }
.mov-hero-icon--neutral { background: var(--bg); color: var(--ink-2); }
.mov-hero-icon .i { width: 32px; height: 32px; }

.mov-hero-label { font-size: 14px; font-weight: 600; color: var(--ink-2); text-transform: uppercase; letter-spacing: 0.5px; }
.mov-hero-amount { font-size: 38px; font-weight: 800; color: var(--ink); letter-spacing: -0.6px; margin: 4px 0 2px; }
.mov-hero-amount--in { color: #2e7d32; }
.mov-hero-amount--out { color: var(--ink); }
.mov-hero-when { font-size: 13px; color: var(--ink-3); text-transform: capitalize; }

/* ==========================================================
   W5 · Ticket form (problema + miglioramento)
   ========================================================== */
.field-error {
  color: #c62828;
  font-size: 12px;
  margin-top: 6px;
  padding-left: 2px;
  font-weight: 600;
}
/* Validazione: bordo rosso sul campo invalido (messaggio = .field-error sopra) */
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] {
  border-color: #c62828;
}
.submit-btn[disabled] {
  opacity: 0.6;
  pointer-events: none;
}

/* ==========================================================
   W6 · Push notifications status card + iOS install banner
   ========================================================== */
/* Push status card · pattern banner tint sottile (allineato a .grace-box/.td-closed-banner),
   no border-left stripe per coerenza UI app cliente. Background varia per stato. */
.push-status-card {
  margin: 16px 14px 0;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px 16px;
}
.push-status-card[data-state="subscribed"] { background: #ECFDF5; border-color: #BBF7D0; }
.push-status-card[data-state="default"],
.push-status-card[data-state="granted"] { background: var(--brand-soft); border-color: rgba(140,0,20,0.18); }
.push-status-card[data-state="denied"] { background: #FEE2E2; border-color: #FCA5A5; }
.push-status-card[data-state="ios-install"],
.push-status-card[data-state="ios-update"],
.push-status-card[data-state="http-required"] { background: #FEF3C7; border-color: #FCD34D; }
.push-status-card[data-state="unsupported"],
.push-status-card[data-state="loading"] { background: var(--bg); border-color: var(--line); }

.push-status-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.psc-body { flex: 1; min-width: 0; }
.psc-title { font-size: 15px; font-weight: 700; color: var(--ink); line-height: 1.3; }
.psc-sub { font-size: 12.5px; color: var(--ink-3); line-height: 1.45; margin-top: 4px; }
.psc-btn {
  background: var(--brand);
  color: #fff;
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  border: 0;
  flex-shrink: 0;
  min-height: 44px;
}
.psc-btn:active { background: var(--brand-hover); }
.psc-btn[disabled] { opacity: 0.6; pointer-events: none; }
.push-status-card[data-state="subscribed"] .psc-btn { background: var(--bg); color: var(--ink-2); }
.push-status-card[data-state="subscribed"] .psc-btn:active { background: var(--line); }

/* iOS install steps · flat dentro la push-status-card (no background/border per
   evitare nested banner). Eredita colore ambra della card padre. */
.ios-install-banner {
  margin-top: 12px;
}
.iib-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 6px;
}
.iib-steps {
  margin: 0;
  padding-left: 20px;
  font-size: 12.5px;
  color: var(--ink-2);
  line-height: 1.6;
}
.iib-steps li { margin-bottom: 2px; }

/* --------------------------------------------------------------------------
 * W7 · WebAuthn passkey
 * -------------------------------------------------------------------------- */

/* Flash success banner (riusabile, prima istanza in sicurezza.html ?deleted=1) */
.flash {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
}
.flash .i { width: 18px; height: 18px; flex-shrink: 0; }
.flash--success {
  background: #DCFCE7;
  color: #166534;
}

/* Card singola passkey nella lista sicurezza.html (estende .menu-row pattern) */
.passkey-card {
  cursor: default;
}
.passkey-card:active { background: var(--surface); }
.passkey-card .ttl { padding-right: 8px; }
.passkey-delete-btn {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--danger);
  font-size: 13px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 8px;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
}
.passkey-delete-btn:active { background: #FCE4E4; }

/* Empty state quando l'utente non ha ancora registrato nessuna passkey */
.passkey-empty-state {
  margin: 8px 18px 0;
  padding: 24px 16px;
  background: var(--surface);
  border: 1px dashed var(--line);
  border-radius: 14px;
  text-align: center;
}
.passkey-empty-state .ico {
  width: 48px;
  height: 48px;
  margin: 0 auto 12px;
  border-radius: 14px;
  background: var(--brand-soft);
  color: var(--brand);
  display: flex;
  align-items: center;
  justify-content: center;
}
.passkey-empty-state .ico .i { width: 24px; height: 24px; }
.passkey-empty-state .ttl {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 4px;
}
.passkey-empty-state .sub {
  font-size: 13px;
  color: var(--ink-2);
  line-height: 1.45;
}

/* CTA "Aggiungi passkey" sotto la lista in sicurezza.html */
.passkey-add-cta .btn-primary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 8px;
}
.passkey-add-cta .btn-primary .i { width: 18px; height: 18px; }

/* Bottone "Accedi con passkey" su login.html — FALLBACK secondario, SOTTO il
   form magic link (redesign input-first 2026-07-09). Il path passkey primario è
   la Conditional UI (autofill sul campo email), questo è il ripiego esplicito. */
.passkey-login-block {
  margin-top: 28px;
  margin-bottom: 0;
}
.passkey-login-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 0;
}
.passkey-login-btn .i { width: 18px; height: 18px; }
.passkey-login-status {
  margin-top: 8px;
  font-size: 13px;
  color: var(--ink-2);
  text-align: center;
  min-height: 18px;
}

/* --------------------------------------------------------------------------
 * W8 fix · #labSwitchModal lab-row + search + locate-btn
 * -------------------------------------------------------------------------- */

.lab-search-bar {
  position: relative;
  margin-bottom: 10px;
}
.lab-search-bar .i {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  display: block;
  color: var(--ink-3);
  width: 18px;
  height: 18px;
  pointer-events: none;
}
.lab-search-bar input {
  width: 100%;
  padding: 12px 14px 12px 38px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 12px;
  font-size: 16px;
  color: var(--ink);
  box-sizing: border-box;
}
.lab-search-bar input::placeholder { color: var(--ink-3); }
.lab-search-bar input:focus {
  border-color: var(--brand);
  background: #fff;
  outline: none;
}

.locate-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 16px;
  background: var(--brand-soft);
  color: var(--brand);
  border-radius: 12px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.locate-btn:active { background: #F8D7DD; }
.locate-btn .i { width: 18px; height: 18px; }

.lab-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
.lab-row:last-child { border-bottom: 0; }
.lab-row:active { background: var(--bg); }
/* "Le tue lavanderie" selezionabili: <button> dentro <form> reso come riga */
.lab-row-form { margin: 0; }
button.lab-row { width: 100%; background: none; border-top: 0; border-left: 0; border-right: 0; font: inherit; text-align: left; box-sizing: border-box; }
#lab-mine .lab-row-form:last-child button.lab-row { border-bottom: 0; }
.lab-row.active {
  background: var(--brand-soft);
}
.lab-row .ic {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--bg);
  color: var(--ink-2);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.lab-row.active .ic {
  background: var(--brand);
  color: #fff;
}
.lab-row .body {
  flex: 1;
  min-width: 0;
}
.lab-row .body .nm {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
}
.lab-row .body .ad {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 2px;
}
.lab-row .bal {
  font-size: 15px;
  font-weight: 700;
  color: var(--brand);
  flex-shrink: 0;
}
.lab-row .check {
  width: 18px;
  height: 18px;
  color: var(--brand);
  flex-shrink: 0;
}
.lab-mockup-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  background: var(--gold-soft);
  color: var(--gold);
  border-radius: 999px;
  font-size: 9.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  vertical-align: 2px;
}

/* Lab actions (Chiama / WhatsApp / Indicazioni) — variante card grande:
 * sostituisce il pattern compatto a 2 card piccole con 3 card icon+ttl+sub. */
.lab-actions--cards {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.lab-actions--cards a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 10px 6px;
  border-radius: 14px;
  text-decoration: none;
}
.lab-actions--cards a:active { transform: scale(0.97); }
.lab-actions--cards a.call { background: var(--brand-soft); }
.lab-actions--cards a.wa { background: var(--brand-soft); }
.lab-actions--cards a.dir { background: var(--brand-soft); }
.lab-actions--cards a .ic {
  width: 36px;
  height: 36px;
  border-radius: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.65);
}
.lab-actions--cards a.call .ic { color: var(--brand); }
.lab-actions--cards a.wa .ic { color: var(--brand); }
.lab-actions--cards a.dir .ic { color: var(--brand); }
.lab-actions--cards a .ttl {
  font-size: 13px;
  font-weight: 800;
}
.lab-actions--cards a.call .ttl { color: var(--brand); }
.lab-actions--cards a.wa .ttl { color: var(--brand); }
.lab-actions--cards a.dir .ttl { color: var(--brand); }
.lab-actions--cards a .sub {
  font-size: 11px;
  color: var(--ink-3);
  font-weight: 600;
}

/* Card pricing dinamico (Acquista in cassa / costo zero) — tessera.html. */
.card-pricing-card {
  position: relative;
  margin: 8px 18px 0;
  padding: 16px 16px 16px 48px;
  background: var(--brand-soft);
  border-radius: 14px;
  font-size: 13px;
  color: var(--ink);
  line-height: 1.55;
}
.card-pricing-card .info-mark {
  position: absolute;
  top: 18px;
  left: 16px;
  width: 22px;
  height: 22px;
  color: var(--brand);
}
.card-pricing-card .cpc-body strong { font-weight: 700; }
.card-pricing-card.has-promo {
  background: #FEF3C7;
  border: 1px solid #FBBF24;
}
.card-pricing-card .cpc-promo-badge {
  display: inline-block;
  margin-top: 10px;
  padding: 4px 10px;
  background: var(--gold);
  color: #fff;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Geo banner soft-ask (ADR 0020 · W8 chunk 5 polish v2)
   Stato gestito da `data-state` (idle|loading|success|error) via JS lab-detect.js.
   Visibilita' iniziale = inline `style="display:none"` (JS la mette flex se eligible). */
.geo-banner {
  margin: 12px 18px 0;
  padding: 14px 16px;
  background: var(--brand-soft);
  border: 1.5px solid var(--brand);
  border-radius: 14px;
  align-items: center;
  gap: 12px;
}
.geo-banner[data-state] { display: flex; }
.geo-banner-icon {
  width: 38px; height: 38px; border-radius: 11px;
  background: var(--brand); color: #fff;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  position: relative;
}
.geo-banner-icon svg { position: absolute; opacity: 0; transition: opacity .2s ease; }
.geo-banner[data-state="idle"]    .geo-icon-idle    { opacity: 1; }
.geo-banner[data-state="loading"] .geo-icon-loading { opacity: 1; animation: geo-spin 1s linear infinite; }
.geo-banner[data-state="success"] .geo-icon-success { opacity: 1; }
.geo-banner[data-state="error"]   .geo-icon-error   { opacity: 1; }
@keyframes geo-spin { to { transform: rotate(360deg); } }
.geo-banner-body { flex: 1; font-size: 13px; color: var(--ink); line-height: 1.4; }
.geo-banner-title { display: block; }
.geo-banner-subtitle { color: var(--ink-3); font-size: 12px; }
.geo-banner[data-state="loading"] .geo-banner-title,
.geo-banner[data-state="success"] .geo-banner-title,
.geo-banner[data-state="error"]   .geo-banner-title,
.geo-banner[data-state="loading"] .geo-banner-subtitle,
.geo-banner[data-state="success"] .geo-banner-subtitle,
.geo-banner[data-state="error"]   .geo-banner-subtitle { display: none; }
.geo-banner[data-state="loading"] .geo-banner-status,
.geo-banner[data-state="success"] .geo-banner-status,
.geo-banner[data-state="error"]   .geo-banner-status {
  position: static; width: auto; height: auto; clip: auto;
  display: block; font-weight: 600;
}
.geo-banner-actions { display: flex; flex-direction: column; gap: 6px; flex-shrink: 0; }
.geo-banner[data-state="loading"] .geo-banner-actions,
.geo-banner[data-state="success"] .geo-banner-actions,
.geo-banner[data-state="error"]   .geo-banner-actions { display: none; }
.geo-banner-btn-primary {
  padding: 8px 14px; background: var(--brand); color: #fff;
  border-radius: 8px; font-size: 12px; font-weight: 700;
}
.geo-banner-btn-secondary {
  padding: 8px 14px; background: transparent; color: var(--ink-3);
  font-size: 12px; font-weight: 600;
}

/* Task E · distance pill nel public landing + sezione "Vicine a te" modal.
 * Visibile solo se active_lab ha coords + cookie user_lat presente. Tap apre
 * il modal `#labSwitchModal` con sezione `#nearbySection` popolata via
 * `window.fetchTopLabs(5)` (lab-detect.js). */
.distance-pill {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 4px;
  margin-top: 4px;
  padding: 3px 9px;
  border-radius: 999px;
  background: #DBEAFE;
  color: var(--info-text);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  border: 0;
  cursor: pointer;
}
.distance-pill:active { opacity: 0.8; }
.distance-pill .i { width: 12px; height: 12px; }

.nearby-section {
  margin-bottom: 14px;
}
.nearby-section .section-title {
  padding: 8px 0;
}
.nearby-section .nearby-list {
  background: var(--surface);
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--line);
}
.nearby-loading,
.nearby-error {
  padding: 12px 14px;
  font-size: 13px;
  color: var(--ink-3);
  text-align: center;
}
.nearby-error { color: var(--brand); }

/* Liste lazy del modale: skeleton a altezza stabile (titolo + 2 righe ~.lab-row)
   + cross-fade al settle htmx. Evita il salto di layout quando lo swap arriva
   mentre lo sheet sta ancora eseguendo slideUp. */
#lab-switch-lists { min-height: 132px; }
#lab-switch-lists .htmx-added { opacity: 0; }
#lab-switch-lists > * { transition: opacity 150ms ease; }
.lab-skel .skel-title { width: 40%; height: 14px; margin: 10px 0; border-radius: 7px; background: var(--bg); }
.lab-skel .skel-row { height: 48px; margin-bottom: 6px; border-radius: 12px; background: var(--bg); }

/* lab_switch_modal classi semantic (post-H follow-up · 2026-05-18) */
.locate-btn.locate-btn--modal { margin: 0 0 14px; width: 100%; border: 0; text-align: left; }
.btn-primary.locate-btn--modal { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 0 0 14px; width: 100%; border: 0; }
.btn-primary.locate-btn--modal .i { width: 18px; height: 18px; flex-shrink: 0; }
.section-title.section-title--tight { padding: 8px 0; }
.section-title.section-title--mid { padding: 16px 0 8px; }
.lab-rows-container { background: var(--surface); border-radius: 12px; overflow: hidden; border: 1px solid var(--line); }
.lab-rows-container.lab-rows-container--with-spacing { margin-bottom: 14px; }

/* ==========================================================
   UTILITY CLASSES (task H · 2026-05-18)
   Feedback PAI `feedback_no_inline_css_default`: niente inline
   CSS statico nei template. Queste classi sostituiscono i
   pattern ricorrenti. Dynamic vars `var(--*)` restano inline.
   ========================================================== */

/* Visibility */
.u-hidden { display: none !important; }

/* Cursors */
.u-cursor-default { cursor: default; }
.u-cursor-pointer { cursor: pointer; }

/* Sizing utility (heights/widths fissi) */
.u-h-20 { height: 20px; }
.u-h-24 { height: 24px; }

/* Spacing */
.u-mt-24 { margin-top: 24px; }
.u-mb-16 { margin-bottom: 16px; }
.u-mb-18 { margin-bottom: 18px; }
.u-gap-10 { gap: 10px; }

/* Flex helpers */
.u-flex-col { display: flex; flex-direction: column; }
.u-flex-1 { flex: 1; }
.u-flex-shrink-0 { flex-shrink: 0; }

/* Text helpers */
.u-text-center { text-align: center; }
.u-link-reset { text-decoration: none; color: inherit; }
.u-color-ink-3 { color: var(--ink-3); }

/* Opacity */
.u-op-85 { opacity: 0.85; }

/* Bullet list compact icon row (used in CTA cards) */
.u-bullet-row { display: flex; align-items: center; gap: 10px; }

/* === Patterns semantici =====================================
   Composite reusabili che evitano "utility soup" nei template. */

/* Brand SVG logo wrap (header) */
.brand-logo-wrap { display: flex; align-items: center; height: 38px; flex-shrink: 0; }
.brand-logo-img { height: 22px; width: auto; display: block; }
.brand-miele-img { height: 14px; width: auto; display: block; }

/* Lab switch action chevron CTA (es. "Cambia >") */
.lab-switch-cta {
  display: flex; align-items: center; gap: 4px;
  color: var(--brand); font-size: 13px; font-weight: 700;
  flex-shrink: 0;
}
/* il chevron segue il colore brand della CTA (vince su .lab-switch .chev = ink-3) */
.lab-switch-cta .chev { color: inherit; }

/* Hint annotativo sotto le sub-pages (es. Listino) */
.page-hint {
  padding: 14px 18px 0;
  font-size: 13px;
  color: var(--ink-2);
  line-height: 1.5;
}

/* Listino tabella prezzi (riusato da public.html + listino.html) */
.listino-table {
  margin: 14px 18px 0;
  background: var(--surface);
  border-radius: 14px;
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.listino-table--inline-public {
  margin: 10px 18px 0;
}
.listino-table .listino-head {
  padding: 14px 16px;
  border-bottom: 1.5px solid var(--line);
  display: flex;
  align-items: flex-end;
  gap: 10px;
}
.listino-table .listino-row {
  padding: 12px 16px;
  display: flex;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--line);
}
.listino-table .listino-row:last-child { border-bottom: 0; }
.listino-table .listino-empty {
  padding: 18px 16px;
  font-size: 13px;
  color: var(--ink-3);
  text-align: center;
}
.listino-col-machine {
  flex: 1;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.listino-col-price {
  width: 70px;
  text-align: right;
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.listino-col-card {
  width: 80px;
  text-align: right;
  font-size: 11px;
  font-weight: 700;
  color: var(--brand);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.listino-col-card--tight { line-height: 1.2; }
/* row body cells */
.listino-row .row-machine {
  flex: 1;
  font-size: 14px;
  color: var(--ink);
}
.listino-row .row-machine--bold {
  font-weight: 600;
  line-height: 1.3;
}
.listino-row .row-price {
  width: 70px;
  text-align: right;
  font-size: 14px;
  color: var(--ink-2);
  font-weight: 600;
}
.listino-row .row-price--strong {
  color: var(--ink);
  font-weight: 700;
}
.listino-row .row-card {
  width: 80px;
  text-align: right;
  font-size: 14px;
  color: var(--brand);
  font-weight: 700;
}
.listino-row .row-card--xbold { font-weight: 800; }

/* Pill badge "X libere su Y" inline al section-title (public.html) */
.libere-pill {
  color: var(--ok-text);
  text-transform: none;
  letter-spacing: 0;
  font-size: 12px;
  font-weight: 700;
}

/* CTA login persuasivo (public.html) — gradient brand card */
.login-cta-card {
  margin: 24px 18px 0;
  padding: 22px 20px;
  background: linear-gradient(135deg, var(--brand) 0%, var(--brand-dark) 100%);
  color: #fff;
  border-radius: 18px;
  box-shadow: 0 12px 28px rgba(182, 17, 45, 0.22);
}
.login-cta-card .cta-eyebrow {
  font-size: 11px;
  font-weight: 800;
  opacity: 0.9;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.login-cta-card .cta-title {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin-top: 6px;
  line-height: 1.2;
}
.login-cta-card .cta-bullets {
  font-size: 13px;
  opacity: 0.95;
  line-height: 1.7;
  margin-top: 12px;
  list-style: none;
  padding: 0;
}
.login-cta-card .cta-btn {
  display: block;
  text-align: center;
  text-decoration: none;
  width: 100%;
  margin-top: 16px;
  padding: 14px;
  background: #fff;
  color: var(--brand);
  border-radius: 12px;
  font-size: 15px;
  font-weight: 800;
}

/* Header icon "Accedi" red (public.html) */
.icon-btn--brand { background: var(--brand); color: #fff; }
.icon-btn--brand:active { background: var(--brand-hover); }

/* Lab switch button reset (button used as div wrapper) */
.btn-reset-row {
  background: transparent;
  border: 0;
  width: 100%;
  text-align: left;
  padding: 0;
}

/* Stat box gradient brand (es. nuovo saldo Satispay success) */
.stat-brand-box {
  width: 100%;
  margin-top: 24px;
  padding: 20px;
  background: linear-gradient(135deg, var(--brand) 0%, var(--brand-dark) 100%);
  color: #fff;
  border-radius: 16px;
  text-align: center;
}
.stat-brand-box .sb-eyebrow {
  font-size: 11px;
  font-weight: 700;
  opacity: 0.9;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.stat-brand-box .sb-value {
  font-size: 42px;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 6px 0 4px;
}
.stat-brand-box .sb-place {
  font-size: 13px;
  opacity: 0.95;
  font-weight: 600;
}

/* Pulsanti-link centrati (Satispay success "Vai al tab Card") */
.btn-link-stack {
  width: 100%;
  margin-top: 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.btn-link-center {
  margin: 0;
  display: block;
  text-align: center;
  text-decoration: none;
}

/* Centered hero block (Satispay step 3) */
.hero-center-block {
  padding: 40px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 80vh;
  justify-content: center;
}
.hero-title {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin-top: 28px;
  text-align: center;
}
.hero-subtitle {
  font-size: 14px;
  color: var(--ink-2);
  text-align: center;
  margin-top: 10px;
  line-height: 1.5;
  max-width: 280px;
}
.btn-primary--narrow {
  margin-top: 32px;
  max-width: 240px;
}

/* Padding wrapper riusato */
.pad-18 { padding: 18px; }

/* Satispay - hint sub */
.satispay-hint {
  padding: 0 18px 4px;
  font-size: 12px;
  color: var(--ink-3);
  line-height: 1.4;
}

/* === Dev inbox styles ====================================== */
.dev-card {
  background: var(--brand-soft);
  border-radius: 12px;
  padding: 14px;
  margin-bottom: 18px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-2);
}
.dev-form {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 18px;
}
.dev-form-field { margin-bottom: 12px; }
.dev-form-field--last { margin-bottom: 14px; }
.dev-form-label {
  display: block;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-2);
  margin-bottom: 6px;
}
.dev-form-input {
  width: 100%;
  padding: 14px;
  border: 2px solid var(--line);
  border-radius: 10px;
  font-size: 16px;
  font-weight: 600;
}
.dev-form-input--sm {
  padding: 12px;
  font-size: 15px;
}
.dev-success {
  background: #DCFCE7;
  border: 1px solid var(--ok);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 18px;
}
.dev-success-label {
  font-size: 12px;
  font-weight: 700;
  color: #0F5132;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 8px;
}
.dev-success-link {
  display: block;
  background: var(--surface);
  border: 1px solid var(--ok);
  border-radius: 8px;
  padding: 12px;
  font-family: ui-monospace, monospace;
  font-size: 12px;
  word-break: break-all;
  color: var(--ink);
  text-decoration: none;
}
.dev-success-hint {
  margin-top: 10px;
  font-size: 11px;
  color: var(--ink-2);
}
.dev-warn {
  background: #FEF3C7;
  border: 1px solid var(--gold);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 18px;
  color: var(--gold);
  font-size: 14px;
  font-weight: 600;
}
.dev-section-h3 {
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-3);
}
.dev-list {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
}
.dev-list-item {
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
}
.dev-list-item:last-child { border-bottom: 0; }
.dev-list-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
}
.dev-list-main { flex: 1; min-width: 0; }
.dev-list-email { font-weight: 700; color: var(--ink); }
.dev-list-meta {
  font-size: 11px;
  color: var(--ink-3);
  margin-top: 2px;
}
.dev-list-id {
  font-size: 11px;
  color: var(--ink-3);
  font-family: ui-monospace, monospace;
}
.dev-list-footer {
  font-size: 11px;
  color: var(--ink-3);
  margin-top: 8px;
  padding: 0 4px;
}
.dev-empty {
  padding: 24px;
  text-align: center;
  color: var(--ink-3);
  font-size: 13px;
}
.dev-header-meta {
  font-size: 11px;
  color: var(--ink-3);
  font-weight: 600;
}
.dev-section-mt8 { margin-top: 8px; }
.btn-primary--reset-mt { margin-top: 0; }

/* Status emphasis */
.status-ok { color: var(--ok); }
.color-brand { color: var(--brand); }
.color-ink-2 { color: var(--ink-2); }

/* lavaggi.html */
/* Balance strip senza Card della lab attiva: testo al posto della cifra. */
.balance-strip .b-info .val--nocard { font-size: 17px; }
.notif-chev { flex-shrink: 0; opacity: 0.6; }

/* === Auth pages (welcome, email_sent, whatsapp_sent, invalid_link) === */
.auth-icon-avatar {
  margin: 40px auto 0;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background: var(--brand-soft);
  color: var(--brand);
  display: flex;
  align-items: center;
  justify-content: center;
}
.auth-icon-avatar--welcome { margin-top: 32px; }
.auth-icon-avatar--whatsapp { background: #DCFCE7; color: var(--whatsapp); }
.auth-icon-avatar--warn { background: #FEF3C7; color: var(--gold); }
.auth-title {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.02em;
  text-align: center;
  margin-top: 24px;
}
.auth-hint-box {
  margin-top: 32px;
  padding: 14px 16px;
  background: var(--bg);
  border-radius: 12px;
  font-size: 12px;
  color: var(--ink-3);
  line-height: 1.5;
}
.auth-actions-stack {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 24px;
}
.auth-btn-primary {
  margin-top: 0;
  display: block;
  text-align: center;
  text-decoration: none;
}
.auth-secondary-link {
  padding: 14px;
  color: var(--ink-3);
  font-size: 13px;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
}
.auth-secondary-link--disabled { opacity: 0.5; }
.auth-secondary-link-sub {
  display: block;
  font-size: 11px;
  opacity: 0.75;
  margin-top: 2px;
}
.auth-demo-tag {
  opacity: 0.7;
  font-size: 11px;
  font-weight: 500;
}

/* Welcome bonus box (riusa stat-brand-box ma con margin diverso) */
.welcome-bonus-box {
  margin: 24px 0 0;
  padding: 20px;
  background: linear-gradient(135deg, var(--brand) 0%, var(--brand-dark) 100%);
  color: #fff;
  border-radius: 16px;
  text-align: center;
}

/* menu-row a usato anche come link: reset look. menu-row gia' definito altrove */
a.menu-row { text-decoration: none; color: inherit; }
.menu-group--mt18 { margin-top: 18px; }
.ttl-danger { color: var(--danger); }

/* btn-secondary · variante "outline neutra" per coppia con btn-primary */
.btn-secondary {
  padding: 16px;
  background: var(--bg);
  color: var(--ink);
  border-radius: 12px;
  font-size: 16px;
  font-weight: 700;
  border: 1px solid var(--line);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  text-align: center;
  transition: background 120ms ease, transform 80ms ease;
}
.btn-secondary:active { background: var(--line); }

/* Selettore lingua app cliente (replica pattern dashboard impostazioni_lingua) */
label.menu-row.lang-row { cursor: pointer; position: relative; }
.lang-row .lang-iso {
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--brand-soft); color: var(--brand);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 800; letter-spacing: 0.04em;
}
/* Feedback visivo selection · CSS :has() su radio:checked (no JS, no server reload) */
.lang-row:has(.lang-radio:checked) {
  background: color-mix(in srgb, var(--brand) 6%, var(--surface));
}
.lang-row .lang-radio {
  position: absolute; opacity: 0; pointer-events: none;
  width: 0; height: 0;
}
.lang-row .lang-check {
  color: var(--brand);
  margin-left: auto;
  flex-shrink: 0;
  display: none;
}
.lang-row:has(.lang-radio:checked) .lang-check { display: block; }


/* Tessera detail */
.btn-cancel--full-narrow {
  margin-top: 14px;
  width: 100%;
}

/* Dati personali form-screen tighter padding */
.form-screen--pad-18 { padding-top: 18px; }
.form-screen--pad-6 { padding-top: 6px; }

/* Voucher banner margin-bottom */
.voucher-banner--mb-16 { margin-bottom: 16px; }

/* Inline tag color ink-2 */
.color-ink-2-text { color: var(--ink-2); }

/* Fatture month summary */
.month-summary-pill {
  font-size: 12px;
  color: var(--ink-3);
  text-transform: none;
  letter-spacing: 0;
}
.partita-iva-cta {
  margin: 18px 18px 24px;
  padding: 14px;
  background: var(--brand-soft);
  border-radius: 12px;
  font-size: 12px;
  color: var(--brand);
  line-height: 1.5;
}
.partita-iva-link {
  text-decoration: underline;
  cursor: pointer;
  font-weight: 700;
}

/* Termini privacy contacts link */
.link-brand {
  color: var(--brand);
  font-weight: 700;
}

/* Field read-only display (es. data nascita lato cliente, memoria feedback_data_nascita_protetta) */
.field-readonly { margin-bottom: 16px; }
.field-readonly .readonly-value {
  padding: 12px 14px;
  background: var(--bg-soft, #F5F6F8);
  border: 1px solid var(--line);
  border-radius: 10px;
  font-size: 15px;
  color: var(--ink-2);
  font-weight: 600;
}
.field-readonly .link-brand { display: inline-block; margin-top: 8px; font-size: 14px; }
.doc-version-tag {
  font-size: 11px;
  color: var(--ink-3);
  margin-top: 24px;
}

/* Borsellino */
.balance-strip--static {
  cursor: default;
  margin-top: 14px;
}
.bors-load-older {
  margin: 12px 18px 0;
  width: calc(100% - 36px);
}

/* Notifiche promo hint */
.promo-hint {
  padding: 0 18px;
  font-size: 11.5px;
  color: var(--ink-3);
  line-height: 1.5;
  margin-bottom: 4px;
}

/* Tessera card (tessera.html) */
a.card-tessera-v {
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  display: block;
}
a.purse-card {
  text-decoration: none;
  color: inherit;
}
.satispay-cta-arrow { color: var(--ink-3); }

/* Lavanderia page */
.lab-star-favorite {
  color: var(--brand);
  vertical-align: -2px;
}
.no-booking-note {
  margin: 14px 18px 0;
  padding: 16px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 14px;
  text-align: center;
  color: var(--ink-2);
  font-size: 13px;
  line-height: 1.5;
}
.libere-pill--ok {
  color: var(--ok-text);
  text-transform: none;
  letter-spacing: 0;
  font-size: 12px;
  font-weight: 700;
}

/* Booking modal saldo/error */
.bm-saldo-info {
  margin-top: 12px;
  font-size: 12px;
  color: var(--ink-3);
  text-align: center;
}
.bm-error {
  margin-top: 12px;
  padding: 12px 14px;
  background: #FEE2E2;
  border: 1px solid var(--danger);
  border-radius: 10px;
  font-size: 13px;
  color: var(--danger);
  font-weight: 600;
}

/* Video player page */
.video-h3 {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.02em;
}
.video-meta {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 4px;
}
.video-desc {
  font-size: 14px;
  color: var(--ink-2);
  line-height: 1.6;
  margin-top: 14px;
}
.tip-box {
  margin-top: 18px;
  padding: 14px;
  background: var(--brand-soft);
  border-radius: 12px;
  font-size: 13px;
  color: var(--brand);
  line-height: 1.5;
}

/* Ticket card (miei_ticket) */
a.voucher-card { padding-right: 16px; display: block; text-decoration: none; color: inherit; }
.ticket-head-icons {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ticket-icon { color: var(--ink-2); }
.ticket-kind-label {
  font-weight: 700;
  font-size: 14px;
}
.ticket-excerpt {
  font-size: 13px;
  color: var(--ink-2);
  margin: 6px 0 8px;
  line-height: 1.4;
}
.ticket-reply-flag {
  color: var(--ok-text);
  font-weight: 700;
}
/* Risposta non ancora letta dal cliente: spicca col colore brand + pallino. */
.ticket-reply-flag--new {
  color: var(--brand);
  font-weight: 800;
}
.ticket-reply-flag--new::before {
  content: "\25CF\00A0";
}

/* Sicurezza passkey flashes */
.flash--margin-page { margin: 12px 18px 0; }

/* passkey add cta */
.passkey-add-cta-wrap { padding: 0 18px; }
.passkey-status-line {
  margin-top: 8px;
  font-size: 13px;
  color: var(--ink-2);
}
.passkey-delete-form { margin: 0; }

/* Promo lista mockup banner (W8 chunk 5 · C6) */
.promo-mockup-banner {
  margin: 12px 18px 0;
  padding: 12px 14px;
  background: var(--info-soft, #EEF4FF);
  border: 1px solid var(--info, #4A6CF7);
  border-radius: 12px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.promo-mockup-banner-icon {
  color: var(--info-text, #2C4DDB);
  flex-shrink: 0;
  margin-top: 2px;
}
.promo-mockup-banner-body {
  flex: 1;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--info-text, #2C4DDB);
}

/* Promo lista — fid hero heading inline icon */
.fid-hero-h3 {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* Fase 2 · blocco reale /app/promo */
/* Banner promo RIUSABILE: stessa struttura di .geo-strip (icona-chip + testo, soft
   bg, bordo, radius 14px, margini 12px 18px 0). Estendibile ad altre promo aggiungendo
   una variante .promo-banner--<tipo> con coppia bg/colore da token.
   --reward = sconto/risparmio (verde token --ok-soft/--ok-text). */
.promo-banner { display: flex; align-items: center; gap: 11px; margin: 12px 18px 0; padding: 11px 12px; border-radius: 14px; border: 1px solid transparent; }
.promo-banner .pb-ico { width: 32px; height: 32px; border-radius: 9px; background: var(--surface); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.promo-banner .pb-ico .i { width: 17px; height: 17px; }
.promo-banner .pb-txt { font-size: 13px; font-weight: 800; line-height: 1.3; }
.promo-banner--reward { background: var(--ok-soft); border-color: var(--ok-border); }
.promo-banner--reward .pb-ico, .promo-banner--reward .pb-txt { color: var(--ok-text); }
/* Banner extra-sconto su due righe: titolo (eredita 13px/800 da .pb-txt) + dettaglio. */
.promo-banner--reward .pb-txt { display: flex; flex-direction: column; gap: 2px; }
.promo-banner .pb-sub { font-size: 12px; font-weight: 600; line-height: 1.3; opacity: .85; }
.promo-storico { margin-top: 8px; }
.promo-empty { margin-top: 8px; }

/* Referral text */
.referral-text {
  font-size: 13px;
  color: var(--ink-2);
  line-height: 1.5;
}
.copy-ico-inline {
  margin-right: 4px;
  vertical-align: -2px;
}

/* Login CTA box compatto (aiuto_public) */
.login-cta-box {
  margin: 24px 18px 0;
  padding: 16px;
  background: var(--brand-soft);
  border-radius: 14px;
  text-align: center;
}
.login-cta-box-text {
  font-size: 13px;
  color: var(--ink-2);
  line-height: 1.5;
}
.login-cta-box-btn {
  display: inline-block;
  text-decoration: none;
  margin-top: 10px;
  padding: 10px 20px;
  background: var(--brand);
  color: #fff;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 700;
}

/* Voucher detail */
.vc-head--compact { margin: 4px 4px 14px; }
.vc-amount--lg { font-size: 32px; }
.voucher-qr-frame--disabled { background: var(--bg); }
.menu-row--static { cursor: default; }
.form-screen--tight { padding-top: 12px; }
.intro-meta {
  font-size: 12px;
  color: var(--ink-3);
  text-align: center;
}

/* Colored ico backgrounds per aiuto.html (categorie video guida) */
.ico-brand { background: var(--brand-soft); color: var(--brand); }
.ico-info { background: #DBEAFE; color: var(--info); }
.ico-gold { background: #FEF3C7; color: var(--gold); }
.ico-purple { background: #DDD6FE; color: #5B21B6; }
.ico-pink { background: #FBCFE8; color: #9D174D; }
.ico-danger { background: #FECACA; color: var(--danger); }

/* Surprise hint (onboarding_complete) */
.surprise-hint {
  margin: 18px 0 0;
  padding: 14px 16px;
  background: var(--brand-soft);
  border-radius: 12px;
  font-size: 12px;
  color: var(--brand);
  line-height: 1.5;
}
.surprise-hint-body {
  color: var(--ink-2);
  font-weight: 500;
}

/* ========== A11Y · prefers-reduced-motion guard (S5 M5) ==========
   Pattern WAI-ARIA / Web Almanac 2023. Uso 0.01ms invece di 0ms per
   permettere ai callback transitionend/animationend di firare comunque.
   Copre: animazioni infinite (pulse, pulseGrow, geo-spin), animazioni
   one-shot (slideUp modal), transition su toggle/toast/channel-option,
   scroll smooth. C11: copre anche le nuove transition 80-120ms sui tap
   state :active (btn, card, menu-row, balance-strip, bottom-nav, lab-switch). */
@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;
  }
}

/* Nudge passkey in home: invita ad attivare la biometria a chi rientra senza averla */
.passkey-nudge { display: flex; align-items: flex-start; gap: 12px; margin: 12px 16px 0; padding: 14px; background: var(--surface); border: 1px solid var(--brand); border-radius: 14px; box-shadow: var(--shadow-card); }
.passkey-nudge-ico { color: var(--brand); flex-shrink: 0; margin-top: 2px; }
.passkey-nudge-body { flex: 1; min-width: 0; }
.passkey-nudge-ttl { font-weight: 700; font-size: 15px; color: var(--ink); }
.passkey-nudge-sub { font-size: 13px; color: var(--ink-2); line-height: 1.35; margin-top: 2px; }
.passkey-nudge-status { font-size: 12px; margin-top: 6px; }
.passkey-nudge-cta { flex-shrink: 0; align-self: center; background: var(--brand); color: #fff; border: none; border-radius: 10px; padding: 8px 14px; font-weight: 700; font-size: 14px; cursor: pointer; }
.passkey-nudge-cta:disabled { opacity: 0.6; }
.passkey-nudge-close { flex-shrink: 0; background: none; border: none; color: var(--ink-3); cursor: pointer; padding: 2px; line-height: 0; }

/* ========== Feedback interattivo · tap + hover (2026-06-11) ==========
   Gli unici controlli "vivi" al tatto erano i 4 con transform scale
   (icon-btn, back-btn, contact-strip, lab-actions): il solo cambio di
   background --bg su bianco e' impercettibile sotto il dito. Qui si
   estende il pattern scale a tutti gli interattivi e si aggiunge lo
   strato :hover per desktop (assente: 1 regola hover in tutto il file
   contro le 103 della dashboard). Token only, niente colori hardcoded. */

/* Tap (touch + click): scale leggero sulle righe/card, piu' marcato sui
   bottoni pieni e sulla bottom nav. Si SOMMA ai background :active gia'
   definiti sopra (proprieta' diverse, nessun override). */
.menu-row:active, .lab-row:active, .lab-list-row:active, .notif-item-row:active,
.purse-card:active, .receipt-row:active, .voucher-card:active, .passkey-card:active,
.cm-card:active, .balance-strip:active, .satispay-cta:active, .load-more-btn:active,
.amount-tile:active, .radio-tile:active, .lab-switch-row:active, .lab-availability:active,
.availability-pill:active, .locate-btn:active,
.ct-act-btn:active, .recharge-method:active { transform: scale(0.985); }

.btn-primary:active, .btn-confirm:active, .btn-danger:active, .btn-cancel:active,
.btn-ghost:active, .btn-secondary:active, .form-screen .submit-btn:active,
.td-reply-form .submit-btn:active, .psc-btn:active,
.btn-pay-satispay:active, .ct-recharge:active { transform: scale(0.97); }

.bottom-nav a:active, .bottom-nav button:active { transform: scale(0.9); border-radius: 14px; }

/* Hover solo su dispositivi con puntatore vero: su touch lo stato hover
   "appiccicoso" post-tap e' un difetto, non un feedback. */
@media (hover: hover) and (pointer: fine) {
  .menu-row:hover, .lab-row:hover, .lab-list-row:hover, .notif-item-row:hover,
  .purse-card:hover, .receipt-row:hover, .voucher-card:hover, .passkey-card:hover,
  .cm-card:hover, .balance-strip:hover, .satispay-cta:hover, .load-more-btn:hover,
  .lab-switch:hover, .lab-list-row:hover, .btn-ghost:hover,
  .btn-secondary:hover, .ct-act-btn:hover, .recharge-method:hover { background: var(--bg); }

  /* .with-actions: l'hover di sfondo NON copre tutta la card — solo la riga "Cambia"
   * (le azioni Chiama/WhatsApp hanno il loro hover sul cerchietto). */
  .lab-switch.with-actions:hover { background: var(--surface); }
  .lab-switch.with-actions .lab-switch-row:hover { background: var(--bg); }

  .amount-tile:hover:not(.selected), .radio-tile:hover:not(.selected) { border-color: var(--ink-3); }

  .btn-primary:hover, .btn-confirm:hover, .form-screen .submit-btn:hover,
  .td-reply-form .submit-btn:hover, .psc-btn:hover,
  .balance-strip .b-cta:hover, .icon-btn--brand:hover, .ct-recharge:hover { background: var(--brand-hover); }

  .btn-danger:hover, .btn-cancel:hover, .btn-pay-satispay:hover { filter: brightness(0.92); }

  .app-header .icon-btn:hover, .sub-header .back-btn:hover, .sheet-close:hover { background: var(--line); }

  .bottom-nav a:hover, .bottom-nav button:hover { background: var(--bg); border-radius: 14px; }

  .contact-strip a:hover, .lab-actions a:hover, .lost-actions a:hover,
  .lab-actions--cards a:hover, .notif-item-link:hover, .mov-help-link:hover,
  .distance-pill:hover { opacity: 0.75; }

  .availability-pill:hover, .lab-availability:hover { background: #DCFCE7; }
  .locate-btn:hover { background: #FBE4EA; }
}

/* 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;}

/* ── Pagina errore 404 (templates/404.html, standalone) ──────────────────
   Condivisa tra tutti gli host: brand neutro, solo token, nessun JS.
   .error-cta adatta .btn-primary all'uso come <a> (block + no underline). */
.error-page { display: flex; min-height: 100vh; min-height: 100dvh; align-items: center; justify-content: center; background: var(--bg); padding: 24px; }
.error-card { background: var(--surface); border-radius: 16px; box-shadow: var(--shadow-card); padding: 40px 28px; max-width: 420px; width: 100%; text-align: center; }
.error-code { font-size: 56px; font-weight: 800; color: var(--brand); letter-spacing: 2px; line-height: 1; }
.error-card h1 { font-size: 20px; font-weight: 800; color: var(--ink); margin-top: 10px; }
.error-text { font-size: 15px; color: var(--ink-2); margin-top: 10px; line-height: 1.5; }
.error-cta { display: block; text-align: center; text-decoration: none; }

/* 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; }
