  /* ==== Design tokens (docs/Cuentaduro_Design_System_Delta_Spec.v4.md) ====
     Promoted from the landing-only .landing{} override to :root on
     2026-09-10 — the doc's Definition of Done explicitly requires "il
     prodotto utilizza gli stessi color tokens della landing", so the whole
     app (not just the marketing page) now uses this refined palette.
     --bg/--bg-card/--bg-card-alt/--bg-input/--ink/--muted/--line/--accent/
     --accent-soft keep their original names (every existing rule in the app
     already references them, nothing to rewrite) but carry the doc's
     refined values. --radius stays an alias for --radius-md (10px,
     unchanged) for the same reason. */
  :root{
    --bg:#17191B;
    --bg-card:#1D1F22;
    --bg-card-alt:#222427;
    --bg-input:#141618;
    --ink:#F4F2EC;
    --muted:rgba(244,242,236,0.68);
    --line:rgba(255,255,255,0.08);
    --color-border-strong:rgba(255,255,255,0.14);
    --accent:#F9B900;    /* brand / logo */
    --accent-hover:#FFC21A;
    --accent-soft:rgba(249,185,0,0.12);
    --accent-border:rgba(249,185,0,0.45);
    --teal:#22D3A6;      /* entrate / positivo */
    --teal-soft:rgba(34,211,166,0.12);
    --coral:#FF5C72;     /* uscite / negativo */
    --coral-soft:rgba(255,92,114,0.12);
    --gold:#F5B342;      /* investimenti */
    --gold-soft:rgba(245,179,66,0.12);
    --blue:#5B8CFF;      /* trasferimenti */
    --blue-soft:rgba(91,140,255,0.12);
    --color-success:#4FC3A1;
    --color-success-soft:rgba(79,195,161,0.12);
    --color-warning:#E9A83B;
    --color-warning-soft:rgba(233,168,59,0.12);
    --color-danger:#E76F61;
    --color-danger-soft:rgba(231,111,97,0.12);
    --color-info:#6FA8DC;
    --color-info-soft:rgba(111,168,220,0.12);
    --color-text-tertiary:rgba(244,242,236,0.45);
    --radius:10px;
    --radius-sm:6px; --radius-md:10px; --radius-lg:14px; --radius-xl:18px;
    --font-size-xs:12px; --font-size-sm:14px; --font-size-md:16px; --font-size-lg:18px;
    --font-size-xl:24px; --font-size-2xl:32px; --font-size-3xl:44px; --font-size-display:56px;
    --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px; --space-5:20px;
    --space-6:24px; --space-8:32px; --space-10:40px; --space-12:48px; --space-16:64px;
    --space-20:80px; --space-24:96px;
    --shadow-sm:0 2px 8px rgba(0,0,0,0.18);
    --shadow-md:0 8px 24px rgba(0,0,0,0.22);
    --landing-max:1100px;        /* standard section content width on the marketing landing page (docs/Cuentaduro_Landing_Design_System.md #21) */
    --landing-card-pad:36px 32px;/* standard .landing-card padding */
    --landing-box-gap:24px;      /* horizontal gap between .overview-csp-box items in any landing box row */
    --landing-stack-gap:24px;    /* vertical gap between stacked blocks inside a .landing-card */
    --landing-column-gap:40px;   /* gap between the two columns of a split .landing-card (e.g. the quiz) */
  }
  *{box-sizing:border-box;}
  html, body{overflow-x:hidden; max-width:100%;}
  body{
    margin:0; background:var(--bg); color:var(--ink);
    font-family:'Nunito Sans', sans-serif;
    -webkit-font-smoothing:antialiased;
  }
  .app{max-width:1180px;margin:0 auto;padding:28px 20px 80px; width:100%;}
  header.top{
    display:flex;align-items:center;justify-content:space-between;
    border-bottom:2px solid var(--line); padding-bottom:16px; margin-bottom:20px;
    flex-wrap:wrap; gap:10px;
  }
  header.top h1{margin:0;}
  header.top h1.logo-link{transition:opacity .15s ease;}
  header.top h1.logo-link:hover{opacity:0.8;}
  header.top .sub{font-family:'IBM Plex Mono',monospace; font-size:12px; color:var(--muted); text-transform:uppercase; letter-spacing:1px;}
  .header-right{display:flex; align-items:center; gap:14px; margin-left:auto;}
  .icon-only-btn{
    background:none; border:none; color:var(--muted); font-size:34px; cursor:pointer;
    padding:4px; line-height:1; transition:color .15s ease; display:inline-flex;
    align-items:center; justify-content:center;
  }
  .icon-only-btn:hover, .icon-only-btn.active{color:var(--accent);}
  .icon-only-btn.small{font-size:20px; padding:2px;}
  .view-switch{
    display:inline-flex; border:1.5px solid var(--line); border-radius:8px;
  }
  .view-switch-btn{
    background:var(--bg-card); color:var(--muted); border:none; cursor:pointer;
    padding:7px 12px; display:inline-flex; align-items:center; justify-content:center;
    transition:all .15s ease;
  }
  .view-switch-btn:first-child{border-radius:6.5px 0 0 6.5px;}
  .view-switch-btn:last-child{border-radius:0 6.5px 6.5px 0;}
  .view-switch-btn:not(:last-child){border-right:1.5px solid var(--line);}
  .view-switch-btn.active{background:var(--accent); color:#241503;}
  .view-switch-btn:hover:not(.active){color:var(--ink);}
  .eur-blur{transition:filter .15s ease;}
  .app.blur-active .eur-blur{filter:blur(6px); user-select:none;}
  .user-menu-popover{
    display:none; position:absolute; top:calc(100% + 8px); right:0; z-index:120;
    background:var(--bg-card); border:1px solid var(--line); border-radius:10px;
    box-shadow:0 6px 16px rgba(0,0,0,0.45); padding:16px; width:260px;
  }
  .user-menu-popover.show{display:block;}
  .user-menu-popover .note{margin-bottom:12px;}
  .card-header-row{display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:10px; margin-bottom:14px; cursor:pointer;}
  .card-header-row.no-margin{margin-bottom:0;}
  .card .card-header-row h2, .confirm-box .card-header-row h2{margin:0;}

  nav.tabs{display:flex; gap:6px; flex-wrap:wrap; margin-bottom:22px;}
  nav.tabs button{
    font-family:'Nunito Sans'; font-size:13.5px; font-weight:600;
    padding:9px 16px; border-radius:999px; border:1.5px solid var(--line);
    background:var(--bg-card); color:var(--muted); cursor:pointer;
    transition:all .15s ease; display:inline-flex; align-items:center; gap:7px;
  }
  nav.tabs button.active{background:var(--accent); color:#241503; border-color:var(--accent);}
  nav.tabs .nav-icon{
    width:20px; height:20px; display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto;
  }
  nav.tabs .nav-icon svg{width:100%; height:100%; display:block;}
  /* Desktop only (sotto i 640px vale il blocco mobile più sotto, invariato):
     gap/padding leggermente ridotti per far stare tutte le pill su una sola
     riga anche con più sezioni opzionali attive (Famiglia/Autónomo/Debiti/
     Investimenti/Carta di credito) — stesso font-size/colori/border-radius,
     solo spaziatura più compatta. */
  @media (min-width:641px){
    nav.tabs{gap:4px;}
    nav.tabs button{padding:8px 12px; gap:5px;}
  }

  .subtabs{display:flex; gap:6px; margin-bottom:14px;}
  .subtab-btn{
    font-family:'Nunito Sans'; font-size:12.5px; font-weight:600;
    padding:6px 13px; border-radius:999px; border:1.5px solid var(--line);
    background:transparent; color:var(--muted); cursor:pointer; transition:all .15s ease;
  }
  .subtab-btn.active{background:var(--blue); color:#04122A; border-color:var(--blue);}
  .subtab-btn:hover:not(.active){border-color:var(--blue); color:var(--ink);}
  nav.tabs button:hover:not(.active){border-color:var(--accent); color:var(--ink);}

  section.panel{display:none;}
  section.panel.active{display:block; animation:fade .25s ease;}
  @keyframes fade{from{opacity:0; transform:translateY(4px);} to{opacity:1; transform:translateY(0);}}

  .settings-layout{display:flex; gap:24px; align-items:flex-start;}
  .settings-sidebar{display:flex; flex-direction:column; gap:6px; flex:0 0 200px; position:sticky; top:20px;}
  .settings-sidebar button{
    font-family:'Nunito Sans'; font-size:13.5px; font-weight:600; text-align:left;
    padding:10px 14px; border-radius:10px; border:1.5px solid var(--line);
    background:var(--bg-card); color:var(--muted); cursor:pointer; transition:all .15s ease;
  }
  .settings-sidebar button.active{background:var(--accent); color:#241503; border-color:var(--accent);}
  .settings-sidebar button:hover:not(.active){border-color:var(--accent); color:var(--ink);}
  .settings-content{flex:1; min-width:0;}
  .settings-group{display:none;}
  .settings-group.active{display:block;}
  @media (max-width:640px){
    .settings-layout{flex-direction:column; align-items:stretch;}
    .settings-sidebar{flex-direction:row; flex-wrap:wrap; flex:0 0 auto; position:static; width:100%;}
    .settings-sidebar button{flex:0 0 auto;}
  }
  /* nav.tabs wraps onto several rows on narrow screens by default (the base
     rule earlier in this file), pushing all page content down before you can
     even see it. On mobile it scrolls horizontally in one row instead, closer
     to a native app's tab strip. */
  @media (max-width:640px){
    nav.tabs{
      flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; padding-bottom:4px;
      -webkit-mask-image:linear-gradient(to right, transparent 0, black 20px, black calc(100% - 20px), transparent 100%);
      mask-image:linear-gradient(to right, transparent 0, black 20px, black calc(100% - 20px), transparent 100%);
      scrollbar-width:none; -ms-overflow-style:none;
    }
    nav.tabs::-webkit-scrollbar{display:none;}
    nav.tabs button{flex:0 0 auto;}
    .scroll-x{scrollbar-width:none; -ms-overflow-style:none;}
    .scroll-x::-webkit-scrollbar{display:none;}
  }

  .card{
    background:var(--bg-card); border:1px solid var(--color-border-strong); border-radius:var(--radius);
    padding:18px 20px; margin-bottom:16px;
  }
  .card h2, .confirm-box h2{font-family:'Spectral',serif; font-weight:600; font-size:19px; margin:0 0 14px; color:var(--ink);}
  .confirm-box h2{margin:0;}
  .grid{display:grid; gap:14px;}
  /* minmax(0,1fr), non il semplice 1fr: una traccia "1fr" ha comunque un
     minimo implicito pari al contenuto più largo al suo interno (auto), che
     può superare lo spazio disponibile e far scorrere l'intera pagina in
     orizzontale invece di andare a capo — bug classico di CSS Grid,
     osservato qui con 3 fund-card affiancate su schermi stretti dove il box
     conto investimenti non collassava correttamente. minmax(0,1fr) forza il
     minimo a 0, lasciando che il contenuto vada a capo/tronchi dentro la sua
     colonna invece di spingerla oltre. */
  .grid.cols-3{grid-template-columns:repeat(3,minmax(0,1fr));}
  .grid.cols-2{grid-template-columns:repeat(2,minmax(0,1fr)); align-items:start;}
  @media (max-width:760px){ .grid.cols-3, .grid.cols-2{grid-template-columns:1fr;} }
  /* Griglia dei fondi (Investimenti → box conto): a differenza delle altre
     .grid.cols-3 dell'app (es. box Fondo di emergenza), ogni colonna qui
     contiene una fund-card con due importi affiancati (Investito/Valore
     attuale), che ha bisogno di più spazio minimo per non forzare i numeri
     ad andare a capo carattere per carattere. Un singolo scalino fisso a 1
     colonna (come .grid.cols-3 generico) lasciava le card a piena larghezza
     — leggibili ma sproporzionate — non appena lo spazio scendeva sotto
     quella soglia, invece di affiancarne comunque due appena lo spazio lo
     consente. `repeat(auto-fit, minmax(340px,1fr))` risolve entrambi:
     quante colonne da 340px+ entrano nella larghezza disponibile (1, 2 o 3
     a seconda dei fondi presenti), senza un breakpoint fisso da mantenere.
     340px verificato come il minimo che non fa ancora sovrapporre gli
     importi nella riga Investito/Valore attuale. */
  .grid.cols-3.inv-funds-grid{grid-template-columns:repeat(auto-fit,minmax(340px,1fr));}
  /* Griglia debiti (Debiti): stessa esigenza della griglia fondi qui sopra —
     ogni debt-card ha una riga a 3 colonne (saldo iniziale/residuo/rata),
     ancora più densa dei 2 importi affiancati della fund-card, quindi un
     minimo leggermente più alto. */
  .grid.cols-2.debts-grid{grid-template-columns:repeat(auto-fit,minmax(380px,1fr));}
  .filters-panel{
    background:var(--bg-card-alt); border:1px solid var(--line); border-radius:10px;
    padding:14px 16px; margin-bottom:14px;
  }
  .filters-panel-header{
    display:flex; justify-content:space-between; align-items:center; margin-bottom:12px; cursor:pointer; gap:10px;
  }
  .filters-panel-header.no-margin{margin-bottom:0;}
  .filters-panel-title{
    font-size:11px; text-transform:uppercase; letter-spacing:.8px; color:var(--muted); font-weight:600;
  }
  .filters-grid{
    display:grid; grid-template-columns:repeat(auto-fit, minmax(160px, 1fr)); gap:12px;
  }
  .filters-section-label{
    font-size:12px; text-transform:uppercase; letter-spacing:.6px; color:var(--muted);
    margin:14px 0 8px; font-weight:600;
  }
  .filters-section-label:first-of-type{margin-top:2px;}
  .filters-active-badge{
    display:inline-block; background:var(--accent); color:#241503; font-size:11px; font-weight:700;
    border-radius:999px; padding:1px 8px; margin-left:6px; vertical-align:middle;
  }
  .multiselect-trigger{
    font-family:'Nunito Sans'; font-size:13.5px; padding:7px 9px; border:1px solid var(--line);
    border-radius:6px; background:var(--bg-input); color:var(--ink); width:100%;
    display:flex; align-items:center; justify-content:space-between; gap:8px; cursor:pointer; text-align:left;
  }
  .multiselect-trigger:hover{border-color:var(--muted);}
  .multiselect-arrow{color:var(--muted); font-size:11px;}
  .multiselect-dropdown{
    position:absolute; top:calc(100% + 4px); left:0; right:0; z-index:50;
    background:var(--bg-card); border:1px solid var(--line); border-radius:8px;
    box-shadow:0 8px 24px rgba(0,0,0,0.35); max-height:220px; overflow-y:auto; padding:6px;
  }
  .multiselect-option{
    display:flex; align-items:center; gap:8px; padding:7px 8px; border-radius:6px; cursor:pointer; font-size:13.5px;
  }
  .multiselect-option:hover{background:var(--bg-input);}
  .multiselect-option input{width:auto; margin:0;}
  .multiselect-search{
    width:100%; font-family:'Nunito Sans'; font-size:13px; padding:6px 8px; margin-bottom:6px;
    border:1px solid var(--line); border-radius:6px; background:var(--bg-input); color:var(--ink);
    position:sticky; top:0; z-index:1;
  }
  .multiselect-search:focus{outline:none; border-color:var(--blue);}
  .multiselect-footer{
    display:flex; justify-content:space-between; gap:8px; padding:6px 8px 2px; border-top:1px solid var(--line); margin-top:4px;
  }
  .multiselect-footer button{
    background:none; border:none; color:var(--blue); font-size:12px; cursor:pointer; padding:2px 4px;
  }
  .multiselect-footer button:hover{text-decoration:underline;}
  .floating-action-bar{
    position:fixed; bottom:24px; left:50%; transform:translateX(-50%);
    z-index:1000; max-width:calc(100% - 32px); width:auto;
    background:var(--bg-card); border:1.5px solid var(--line); border-radius:14px;
    padding:12px 16px; box-shadow:0 8px 28px rgba(0,0,0,0.35);
  }
  .fab-header{
    display:flex; align-items:center; justify-content:space-between; gap:16px; margin-bottom:10px;
  }
  .fab-count{font-size:13px; font-weight:600; color:var(--ink);}
  .fab-close{
    background:none; border:none; color:var(--muted); font-size:15px; line-height:1; cursor:pointer;
    padding:2px 6px; border-radius:6px; transition:background .15s ease, color .15s ease;
  }
  .fab-close:hover{background:var(--bg-input); color:var(--ink);}
  .fab-actions{display:flex; flex-wrap:wrap; align-items:center; gap:12px;}
  .fab-group{display:flex; flex-wrap:wrap; align-items:center; gap:6px;}
  .fab-group select{width:auto; min-width:150px;}
  .fab-group-label{
    font-size:11px; text-transform:uppercase; letter-spacing:.5px; color:var(--muted); margin-right:2px;
  }
  .fab-divider{width:1px; align-self:stretch; background:var(--line); margin:2px 2px;}
  .tx-summary-bar{
    display:flex; flex-wrap:wrap; gap:18px; align-items:center;
    background:var(--bg-card-alt); border:1px solid var(--line); border-radius:8px;
    padding:10px 14px; margin-bottom:12px; font-size:13px;
  }
  .tx-summary-bar .tx-summary-item{display:flex; gap:6px; align-items:baseline;}
  .tx-summary-bar .tx-summary-label{color:var(--muted); font-size:11px; text-transform:uppercase; letter-spacing:.4px;}
  .tx-summary-bar .tx-summary-value{font-family:'IBM Plex Mono',monospace; font-weight:600;}
  /* Vista a card di Movimenti per mobile (vedi renderTransactions()/txCardHtml()
     in app.js) — nascosta di default, sostituisce la tabella sotto i 640px:
     più leggibile da scorrere di una tabella stretta, con le azioni (crea
     trasferimento/annulla/salda/modifica) nascoste finché non si tocca la
     card invece di affollare ogni riga di icone. */
  .tx-cards{display:none;}
  @media (max-width:640px){
    #transactions-table-wrap, #recurring-table-wrap, #subscriptions-table-wrap,
    #cc-table-wrap, #investment-history-table-wrap{display:none;}
    .tx-cards{display:block;}
  }
  .tx-card-date-group{
    display:flex; justify-content:space-between; align-items:baseline;
    font-size:11px; text-transform:uppercase; letter-spacing:.5px; color:var(--muted);
    margin:18px 0 8px; font-family:'IBM Plex Mono',monospace;
  }
  .tx-card-date-group:first-child{margin-top:0;}
  .tx-card{
    background:var(--bg-card-alt); border:1px solid var(--line); border-radius:10px;
    margin-bottom:8px; overflow:hidden;
  }
  .tx-card.future{opacity:.75;}
  .tx-card.editing{opacity:1;}
  /* Bordo dorato quando le azioni sono aperte — lo stesso trattamento già
     usato altrove nell'app (nodi del Sankey, box in evidenza) per segnalare
     "questo elemento è attivo/espanso". */
  .tx-card.expanded{border-color:var(--accent);}
  .tx-card-main{padding:12px 14px; cursor:pointer; display:flex; flex-direction:column; gap:6px;}
  /* Card senza azioni da rivelare (es. storico aggiornamenti investimenti):
     stessa struttura/spaziatura di .tx-card-main ma senza il cursore a mano,
     che altrimenti lascerebbe intendere un tap possibile dove non c'è
     nessuna azione dietro. */
  .tx-card-main.static{cursor:default;}
  /* Riga 1: descrizione + importo. */
  .tx-card-row1{display:flex; justify-content:space-between; align-items:baseline; gap:10px;}
  .tx-card-label{font-weight:600; font-size:14px; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1; min-width:0;}
  .tx-card-amount{font-family:'IBM Plex Mono',monospace; font-weight:600; font-size:15px; white-space:nowrap; flex:0 0 auto;}
  /* Riga 2: solo conto/giorno/prossimo addebito, allineato a destra — il
     tipo/stato si è spostato sulla riga 3 insieme alla categoria (a sinistra). */
  .tx-card-row2{display:flex; justify-content:flex-end; align-items:center; gap:10px; font-size:12px;}
  .tx-card-account{color:var(--muted); text-align:right; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; display:flex; align-items:center; gap:4px; justify-content:flex-end;}
  /* Riga 3: tipo/stato + categoria, entrambi a sinistra — con un'iconcina a
     forma di etichetta per segnalare che quel testo è una categoria e non
     un altro dettaglio qualsiasi. flex-wrap perché pill+icona+testo possono
     non stare su una riga sola in una card stretta. */
  .tx-card-row3{display:flex; flex-wrap:wrap; align-items:center; gap:5px 8px; font-size:12px; color:var(--muted);}
  .tx-card-cat-icon{display:inline-flex; color:var(--muted); flex:0 0 auto;}
  /* Le azioni occupano tutta la larghezza della card, divise in parti
     uguali tra i 3 o 4 bottoni presenti (crea trasferimento/annulla/[salda]/
     modifica) — target di tap grandi e inequivocabili invece di quadratini
     piccoli ammassati a sinistra. */
  .tx-card-actions{display:flex; gap:8px; padding:0 14px 12px;}
  .tx-card-actions .icon-action-btn{flex:1; width:auto; height:44px;}
  @media (max-width:640px){
    .tx-card-actions .icon-action-btn{height:48px; font-size:18px;}
  }
  .tx-card-actions .icon-action-btn.reveal-on-hover{opacity:1;}
  .tx-card .inline-edit-panel{margin:0 14px 14px;}
  @media (max-width:640px){
    .fab-divider{display:none;}
    .fab-actions{flex-direction:column; align-items:stretch;}
    .fab-group{justify-content:space-between;}
    .row-inline .field{flex:1 1 100%; min-width:0;}
    .row-inline > button.btn{flex:1 1 100%;}
    /* Fields in "Registra un movimento" stack full-width on mobile (the rule
       above), so the row's own gap becomes the vertical space between them —
       the default 8px reads as cramped once everything's stacked instead of
       side by side. */
    #add-movement-overlay .row-inline{gap:18px;}
    /* Da/A restano affiancati anche su mobile invece di impilarsi come gli
       altri campi (richiesta esplicita): l'ID vince sulla regola generica
       ".row-inline .field" sopra a prescindere dall'ordine nel foglio di
       stile. calc(50% - 9px) tiene conto dei 18px di gap impostati qui sopra
       per questo overlay, così le due select sommano esattamente al 100%. */
    #mv-from-field, #mv-to-field{flex:1 1 calc(50% - 9px);}
    /* Intestazione di Movimenti/Movimenti ricorrenti/Abbonamenti: titolo e
       azione primaria impilati invece di accostati in uno spazio troppo
       stretto, bottone a piena larghezza e più alto (48px, oltre il minimo
       di 44pt) per essere un target di tap inequivocabile — coerente con le
       indicazioni Apple sulla gerarchia visiva delle azioni primarie su
       mobile. Nome generico (non solo "movements"): stesso trattamento
       riusato identico sulle tre schede a lista di Movimenti. */
    .list-panel-header{flex-direction:column; align-items:stretch; gap:12px;}
    .list-panel-header > div{width:100%;}
    .list-panel-primary-btn{width:100%; min-height:48px; font-size:15px;}
    /* La barra di icone secondarie (duplicati/vista/import CSV) si dispone
       centrata e con più margine tra i gruppi, ora che ogni pulsante è
       cresciuto a 44px — con il gap di 8px di prima sarebbero rimasti
       comunque appiccicati anche se singolarmente più grandi. */
    .list-panel-toolbar{justify-content:center; gap:14px;}
  }
  .list-stack{display:flex; flex-direction:column; gap:14px;}

  .dashboard-top-grid{display:grid; grid-template-columns:3fr 2fr; gap:16px; align-items:start; margin-bottom:16px;}
  .right-column-stack{display:flex; flex-direction:column; gap:16px;}
  .dashboard-top-grid .card{margin-bottom:0;}
  @media (max-width:900px){ .dashboard-top-grid{grid-template-columns:1fr;} }

  .overview-csp-grid{display:grid; grid-template-columns:repeat(5,1fr); gap:12px;}
  @media (max-width:900px){ .overview-csp-grid{grid-template-columns:repeat(3,1fr);} }
  @media (max-width:560px){ .overview-csp-grid{grid-template-columns:repeat(2,1fr);} }
  .overview-csp-box{
    background:var(--bg-card-alt); border:1px solid var(--line); border-radius:8px;
    padding:16px 10px; display:flex; flex-direction:column; gap:4px; text-align:center;
  }
  .overview-csp-box .value{font-family:'IBM Plex Mono',monospace; font-size:19px; font-weight:600; color:var(--ink);}
  .overview-csp-box .label{font-family:'Nunito Sans'; font-size:11.5px; color:var(--muted);}
  /* Plan mobile (docs/Cuentaduro_Design_System_Delta_Spec.v4.md #4): "il
     blocco Plan deve dare maggiore importanza ai valori numerici" — non
     cambia la griglia 2x2, solo la gerarchia tipografica al suo interno:
     con 2 colonne invece di 5 ogni box ha più larghezza reale, quindi il
     valore può essere più grande senza mai andare a capo. */
  @media (max-width:560px){
    .overview-csp-box{padding:18px 12px;}
    .overview-csp-box .value{font-size:24px;}
  }
  .overview-csp-box-highlight{border-color:var(--accent); background:var(--accent-soft);}
  .csp-bar{position:relative; height:8px; border-radius:4px; background:var(--bg); border:1px solid var(--line); margin-top:8px;}
  .csp-bar-ideal{position:absolute; top:0; bottom:0; background:var(--accent-soft); border-radius:4px;}
  .csp-bar-actual{position:absolute; top:-3px; bottom:-3px; width:3px; margin-left:-1.5px; border-radius:1.5px; background:var(--ink);}
  .csp-bar-actual.in-range{background:var(--teal);}
  .csp-bar-actual.out-range{background:var(--coral);}
  .csp-bar-caption{font-family:'IBM Plex Mono',monospace; font-size:11px; color:var(--ink); margin-top:6px;}
  .muted-inline{font-family:'Nunito Sans'; color:var(--muted);}

  /* Larghezza minima assoluta: i nodi sono posizionati in percentuale sul
     contenitore (NODE_W_PCT in renderRecurringFlowChart(), fino al 20%),
     quindi su schermi stretti si stringono fino a diventare illeggibili
     invece di restare leggibili scorrendo. #recurring-flow-content (vedi
     .scroll-x in index.html) fa scorrere solo questo grafico entro il
     proprio box, senza spingere in larghezza il resto della card. Un primo
     tentativo a 700px dava solo ~140px per nodo (20% di 700) — ancora
     troppo poco per icona+nome+importo sulla stessa riga senza troncare
     (segnalato dall'utente con screenshot). 1200px dà ~240px per nodo,
     verificato leggibile anche coi nomi conto più lunghi presenti nei dati
     reali. */
  .recurring-flow-sankey{position:relative; height:420px; min-width:1200px;}
  .recurring-flow-sankey-svg{position:absolute; top:0; left:0; width:100%; height:100%; display:block;}
  .recurring-flow-sankey-node{
    position:absolute; display:flex; align-items:center; gap:6px; box-sizing:border-box;
    background:var(--bg-card-alt); border:1px solid var(--accent); border-radius:6px;
    padding:4px 8px; overflow:hidden;
  }
  .recurring-flow-sankey-node-name{font-size:11.5px; font-weight:600; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1; min-width:0;}
  .recurring-flow-sankey-node-amt{font-family:'IBM Plex Mono',monospace; font-size:10.5px; color:var(--muted); white-space:nowrap; flex:0 0 auto; margin-left:auto; padding-left:6px;}
  @media (max-width:640px){
    .recurring-flow-sankey-node-name{font-size:10px;}
    .recurring-flow-sankey-node-amt{font-size:9px;}
  }
  .overview-csp-box-highlight .value{color:var(--accent);}

  .stat{
    border:1px solid var(--line); border-radius:var(--radius); padding:14px 16px;
    background:var(--bg-card-alt); display:flex; justify-content:space-between; align-items:center; gap:10px;
  }
  .stat .label{font-size:11.5px; text-transform:uppercase; letter-spacing:.8px; color:var(--muted); font-weight:600;}
  .bank-badge{
    display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px;
    border-radius:50%; font-size:9.5px; font-weight:700; color:#fff; margin-right:7px;
    vertical-align:middle; font-family:'Nunito Sans', sans-serif; letter-spacing:0.3px;
  }
  .bank-badge-img{
    width:22px; height:22px; border-radius:6px; margin-right:7px; vertical-align:middle;
    object-fit:cover; box-shadow:0 0 0 1px rgba(255,255,255,0.08);
  }
  .stat .value{font-family:'IBM Plex Mono',monospace; font-size:24px; font-weight:600; color:var(--ink); white-space:nowrap;}
  .onb-banks-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(170px, 1fr)); gap:10px 16px; max-height:340px; overflow-y:auto; padding-right:4px;}
  .onb-bank-row{display:flex; align-items:center; gap:8px; font-size:13.5px; color:var(--ink); cursor:pointer;}
  /* Rimossa la regola .stat.total .value{color:var(--teal);} (documento delta
     v4, sez. 6 Financial Metric: "non colorare automaticamente tutti i
     numeri" — un valore normale deve restare colore primario, non un teal
     incondizionato solo perché sta dentro un box .stat.total). Coloriva
     indiscriminatamente saldo dovuto carta di credito, mesi per saldare un
     debito, mesi coperti dal fondo di emergenza ed entrate nette Autonomo,
     nessuno dei quali è genuinamente un "guadagno" — es. un debito da
     pagare appariva in verde. .stat .value{color:var(--ink);} sopra resta
     il colore di base; dove un valore ha davvero uno stato positivo/
     negativo (es. Saldo IVA, guadagno/perdita fondi) la colorazione è ora
     esplicita nella funzione che lo genera, non ereditata da questa
     classe. */
  /* debt-forecast-months can show a text message ("Nunca al ritmo actual") instead
     of a short amount — nowrap (needed for monetary values elsewhere) would force
     the whole card to scroll horizontally on mobile for that longer text. */
  #debt-forecast-months{white-space:normal; word-break:break-word;}
  .stat.has-sub{flex-direction:column; align-items:stretch; gap:6px;}
  .stat-row{display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:4px 12px;}
  .credit-note{font-size:11.5px; color:var(--muted); font-family:'IBM Plex Mono',monospace;}

  details.bank-detail{cursor:pointer; display:block;}
  details.bank-detail summary{
    list-style:none; cursor:pointer; display:flex; justify-content:space-between; align-items:center;
  }
  details.bank-detail summary::-webkit-details-marker{display:none;}
  details.bank-detail summary::marker{content:'';}
  details.bank-detail summary::after{
    content:'◂'; font-size:20px; color:var(--muted); margin-left:8px; font-family:'IBM Plex Mono',monospace;
    display:inline-block; transition:transform .15s ease;
  }
  details.bank-detail[open] summary::after{transform:rotate(-90deg);}
  .collapse-arrow{
    display:inline-block; font-size:20px; color:var(--muted); font-family:'IBM Plex Mono',monospace;
    transition:transform .15s ease;
  }
  .collapse-arrow.open{transform:rotate(-90deg);}
  details.bank-detail summary .label{flex:1;}
  .detail-list{margin-top:12px; border-top:1px solid var(--line); padding-top:8px;}
  .detail-row{display:flex; justify-content:space-between; align-items:baseline; padding:8px 8px; gap:10px; border-radius:6px;}
  .detail-row:nth-child(even){background:rgba(255,255,255,0.03);}
  /* Memo rows (interest accrued, monthly reserve, guilty-free spending) are
     wrapped by app.js in a .detail-memo-group container — a distinct boxed
     section with its own background, so they read as a summary/footnote
     under the account list rather than more rows of the same table. */
  .detail-memo-group{
    margin-top:12px; padding:6px 8px; border:1px solid var(--line); border-radius:8px;
    background:rgba(255,255,255,0.025);
  }
  .detail-memo-group-title{
    font-size:12px; text-transform:uppercase; letter-spacing:.6px; color:var(--muted);
    font-weight:600; padding:6px 8px 2px;
  }
  .detail-row.detail-memo{font-style:italic;}
  .detail-row.detail-memo:nth-child(even){background:none;}
  .detail-row.detail-memo .detail-name{color:var(--muted);}
  .detail-row.detail-memo .detail-bal{color:var(--gold);}
  .detail-row.detail-nested{padding-left:18px; border-left:1px dashed var(--line); margin-left:4px;}
  .detail-row.detail-nested-2{padding-left:34px; border-left:1px dashed var(--line); margin-left:20px;}
  .detail-name{font-size:13px; color:var(--ink); display:flex; flex-direction:column;}
  .pocket-name-row{display:inline-flex; align-items:center; gap:6px;}
  .detail-type{font-size:12px; color:var(--muted); font-weight:400;}
  .detail-bal{font-family:'IBM Plex Mono',monospace; font-size:13px; color:var(--ink); white-space:nowrap;}

  /* Stamp calendar - signature element, terminal-ticker style on dark */
  .stampstrip{display:flex; gap:14px; overflow-x:auto; padding:6px 2px 14px;}
  .stamp{
    flex:0 0 auto; width:150px; border:1.5px dashed var(--gold); border-radius:50%/18%;
    padding:16px 10px; text-align:center; position:relative; background:var(--gold-soft);
    transform:rotate(-2deg);
  }
  .stamp:nth-child(even){transform:rotate(2deg); border-color:var(--blue); background:var(--blue-soft);}
  .stamp .day{font-family:'Spectral',serif; font-style:italic; font-size:15px; font-weight:600; color:var(--ink);}
  .stamp .amt{font-family:'IBM Plex Mono',monospace; font-size:17px; font-weight:600; margin-top:4px; color:var(--ink);}
  .stamp .cnt{font-size:11px; color:var(--muted); margin-top:2px;}
  .stamp.stamp-today{border-style:solid; border-color:var(--teal); background:var(--teal-soft); border-width:2px; transform:rotate(0deg);}
  .stamp.stamp-today .day{color:var(--teal);}

  /* Donut charts */
  .donut-wrap{display:flex; align-items:center; gap:20px; flex-wrap:wrap;}
  .donut-chart{
    width:140px; height:140px; min-width:140px; border-radius:50%; position:relative;
  }
  .donut-hole{
    position:absolute; inset:20px; background:var(--bg-card); border-radius:50%;
    display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; padding:4px;
  }
  .donut-center-label{font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.5px;}
  .donut-center-value{font-family:'IBM Plex Mono',monospace; font-size:15px; font-weight:600; color:var(--ink); margin-top:2px;}
  .donut-legend{display:flex; flex-direction:column; gap:7px; flex:1; min-width:150px;}
  .donut-legend-item{display:flex; align-items:center; gap:8px; font-size:12.5px;}
  .donut-swatch{width:10px; height:10px; border-radius:3px; flex:0 0 auto;}
  .donut-legend-label{flex:1; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  .donut-legend-value{font-family:'IBM Plex Mono',monospace; color:var(--muted); white-space:nowrap; font-size:12px;}

  .growth-chart-value{font-family:'IBM Plex Mono',monospace; font-size:20px; font-weight:600; color:var(--gold); margin-bottom:8px;}
  .growth-chart-svg{width:100%; height:180px; display:block;}
  .growth-chart-labels{display:flex; justify-content:space-between; font-size:11px; color:var(--muted); margin-top:6px;}

  table{width:100%; border-collapse:collapse; font-size:13.5px;}
  th{
    text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.6px;
    color:var(--muted); border-bottom:1.5px solid var(--line); padding:8px 8px;
  }
  td{padding:9px 8px; border-bottom:1px solid var(--line); vertical-align:middle; color:var(--ink);}
  tr:hover td{background:rgba(91,140,255,0.05);}
  tr.row-selected td{background:rgba(91,140,255,0.05);}
  td.num, th.num{font-family:'IBM Plex Mono',monospace; text-align:right;}
  .cc-table{table-layout:fixed; min-width:600px;}
  tr.date-group-row:hover td{background:none;}
  tr.date-group-row td{padding:0; border-bottom:none;}
  .date-group-header{
    display:flex; justify-content:space-between; align-items:center;
    font-family:'Nunito Sans', sans-serif; font-weight:600; font-size:13px; color:var(--ink);
    background:var(--bg-card-alt); border:1px solid var(--line); border-radius:8px;
    padding:10px 14px; margin:18px 0 8px;
  }
  tr.date-group-row:first-child .date-group-header{margin-top:0;}
  .date-group-total{font-family:'IBM Plex Mono',monospace; font-style:normal; font-weight:600; font-size:13px;}
  .cc-table td, .cc-table th{overflow-wrap:break-word; word-break:break-word;}
  th.sortable{cursor:pointer; user-select:none; transition:color .15s ease;}
  th.sortable:hover{color:var(--teal);}
  .sort-indicator{display:inline-block; margin-left:4px; font-size:10px; color:var(--teal); width:8px;}
  input, select, textarea{
    font-family:'Nunito Sans'; font-size:13.5px; padding:7px 9px; border:1px solid var(--line);
    border-radius:6px; background:var(--bg-input); color:var(--ink); width:100%;
  }
  /* Indicatore di focus accent (documento delta v4, sez. 11 Borders: focus →
     strong/accent) — prima l'unico focus ring esistente era scoped a .landing,
     il resto del prodotto non aveva alcun indicatore visivo per la navigazione
     da tastiera. Stesso trattamento già usato lì. */
  input:focus, select:focus, textarea:focus{
    outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft);
  }
  textarea{resize:vertical; min-height:90px;}
  input::placeholder, textarea::placeholder{color:#4E5866;}
  input[type=number]{font-family:'IBM Plex Mono',monospace;}
  input[type=date]{cursor:pointer;}
  input[type=file]{padding:8px;}
  input[type=color]{width:52px; height:38px; padding:3px; cursor:pointer;}
  input[type=checkbox]{
    appearance:none; -webkit-appearance:none;
    width:16px; height:16px; min-width:16px; padding:0;
    border:1.5px solid var(--line); border-radius:4px;
    background:var(--bg-input); cursor:pointer; position:relative;
    flex-shrink:0; vertical-align:middle;
    transition:background .15s ease, border-color .15s ease;
  }
  input[type=checkbox]:hover{border-color:var(--accent);}
  input[type=checkbox]:checked{background:var(--accent); border-color:var(--accent);}
  input[type=checkbox]:checked::after{
    content:''; position:absolute; left:4px; top:1px;
    width:4px; height:8px;
    border:solid #241503; border-width:0 2px 2px 0;
    transform:rotate(45deg);
  }
  /* Toggle-switch look for a checkbox (class="switch" on the input) — same
     checked/unchecked semantics, just a bigger and clearer target on mobile
     than the small square box. */
  input[type=checkbox].switch{
    width:40px; height:24px; min-width:40px; border-radius:999px;
  }
  input[type=checkbox].switch::after{
    content:''; position:absolute; top:2px; left:2px;
    width:18px; height:18px; border-radius:50%; border:none;
    background:var(--muted); transition:transform .15s ease, background .15s ease;
  }
  input[type=checkbox].switch:checked::after{transform:translateX(16px); background:#241503;}
  .row-inline{display:flex; gap:8px; flex-wrap:wrap; align-items:flex-end;}
  .field{display:flex; flex-direction:column; gap:4px; min-width:0;}
  .field label{font-size:11px; text-transform:uppercase; letter-spacing:.5px; color:var(--muted); font-weight:600;}
  /* Importo accepts simple arithmetic (e.g. "12.50+8.30") for summing several
     receipts at once, resolved to a plain number on blur — see
     resolveAmountField()/evaluateAmountExpression() in app.js. The + button
     appends an operator without needing the keyboard's symbol layer, since
     inputmode="decimal" hides it on most mobile keyboards. */
  .amount-input-wrap{display:flex; gap:6px; align-items:center;}
  .amount-input-wrap input{flex:1; min-width:0;}
  .amount-add-btn{
    flex:0 0 auto; width:36px; height:36px; border-radius:8px; border:1px solid var(--line);
    background:var(--bg-input); color:var(--muted); font-size:20px; font-weight:600; cursor:pointer;
    display:inline-flex; align-items:center; justify-content:center; padding:0; line-height:1;
  }
  .amount-add-btn:hover{color:var(--accent); border-color:var(--accent);}

  button.btn{
    font-family:'Nunito Sans'; font-weight:600; font-size:13px; cursor:pointer;
    border:none; border-radius:6px; padding:8px 14px; background:var(--accent); color:#241503;
  }
  button.btn:hover{filter:brightness(1.1);}
  button.btn.ghost{background:transparent; color:var(--ink); border:1.5px solid var(--line);}
  button.btn.ghost:hover{border-color:var(--ink);}
  button.btn.small{padding:5px 10px; font-size:12px;}
  button.btn.danger{background:var(--coral); color:#2A0006;}
  button.btn.gold{background:var(--gold); color:#241503;}
  button.btn.blue{background:var(--blue); color:#04122A;}
  button.btn.ghost.active{background:var(--accent); color:#241503; border-color:var(--accent);}
  button.btn:disabled{opacity:.35; cursor:not-allowed;}
  button.btn.btn-icon-label{display:inline-flex; align-items:center; justify-content:center; gap:8px;}

  /* Type-first entry: pick income/expense/transfer before anything else shows,
     so registering a movement is one tap instead of scanning a whole form. */
  .mv-type-picker{display:flex; gap:10px; margin-bottom:4px;}
  .mv-type-choice{
    flex:1; display:flex; flex-direction:column; align-items:center; gap:6px;
    padding:16px 10px; border-radius:10px; border:1.5px solid var(--line);
    background:var(--bg-card-alt); color:var(--muted); cursor:pointer;
    font-family:'Nunito Sans'; font-weight:600; font-size:13px;
    transition:border-color .15s ease, color .15s ease, background .15s ease;
  }
  .mv-type-choice:hover{border-color:var(--ink); color:var(--ink);}
  .mv-type-choice.expense.active{background:var(--coral-soft); border-color:var(--coral); color:var(--coral);}
  .mv-type-choice.income.active{background:var(--teal-soft); border-color:var(--teal); color:var(--teal);}
  .mv-type-choice.transfer.active{background:var(--blue-soft); border-color:var(--blue); color:var(--blue);}

  /* Status Badge (docs/Cuentaduro_Design_System_Delta_Spec.v4.md #10): un
     unico componente (.pill) con varianti semantiche — success/danger/
     info/warning/neutral — invece di legare il colore direttamente al
     significato di business di ogni schermata. Le vere "status" pill
     (entrata/uscita/trasferimento/in attesa/saldato/futuro) sono rimappate
     sui token semantici qui sotto; i pill che sono in realtà TAG
     categoriali (couple/contribution/value-update — non uno stato) restano
     sui colori diretti già esistenti (gold/blue), coerenti con l'uso di
     quei colori altrove nell'app (es. gold = investimenti). */
  .pill{display:inline-block; padding:2px 9px; border-radius:999px; font-size:11px; font-weight:600;}
  .pill.success, .pill.income, .pill.settled{background:var(--color-success-soft); color:var(--color-success);}
  .pill.danger, .pill.expense{background:var(--color-danger-soft); color:var(--color-danger);}
  .pill.info, .pill.transfer, .pill.future{background:var(--color-info-soft); color:var(--color-info);}
  .pill.warning, .pill.pending{background:var(--color-warning-soft); color:var(--color-warning);}
  .pill.neutral, .pill.off{background:rgba(179,179,179,0.14); color:var(--muted);}
  .pill.couple{background:var(--gold-soft); color:var(--gold);}
  .pill.contribution{background:var(--gold-soft); color:var(--gold);}
  .pill.value-update{background:var(--blue-soft); color:var(--blue);}

  .categories-wrap{display:flex; flex-wrap:wrap; gap:8px;}
  .reserve-list{display:flex; flex-direction:column; gap:2px;}
  .reserve-row{
    display:flex; flex-wrap:wrap; align-items:center; padding:8px 4px;
    border-bottom:1px dashed var(--line); gap:10px;
  }
  .reserve-row:last-child{border-bottom:none;}
  /* Etichetta+valore, sempre visibili — separati dalle azioni sotto, che su
     mobile restano nascoste finché non si tocca questo blocco. */
  .reserve-row-main{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px; flex:1; min-width:0;}
  .reserve-label{font-size:13.5px; color:var(--ink); flex:1; min-width:0;}
  .reserve-value{font-family:'IBM Plex Mono',monospace; font-size:13.5px; color:var(--ink); white-space:nowrap; flex:0 0 auto;}
  .reserve-row-actions{display:flex; align-items:center; gap:6px; flex:0 0 auto;}
  /* Righe della Riserva mensile come card vere e proprie su mobile (stesso
     linguaggio visivo — sfondo, bordo, radius — di .tx-card usato da
     Movimenti/Carta di credito/Investimenti), con le azioni nascoste finché
     non si tocca la riga — stesso pattern tap-to-reveal di .tx-card-actions,
     invece di lasciarle sempre visibili come sul desktop (mouse). Segnalato
     dall'utente: i bottoni dovevano comportarsi come le altre card. Stessa
     soglia 640px della vista a card di Movimenti, per coerenza. */
  @media (max-width:640px){
    /* Stessa divisione di responsabilità di .tx-card/.tx-card-main/
       .tx-card-actions: il guscio .reserve-row non ha padding proprio,
       lo gestiscono i due figli — altrimenti il padding della riga si
       sommava al margin-top delle azioni, lasciando un vuoto doppio tra
       etichetta/valore e i bottoni (segnalato dall'utente). */
    .reserve-row{
      background:var(--bg-card-alt); border:1px solid var(--line); border-radius:10px;
      margin-bottom:8px; padding:0; gap:0;
      flex-direction:column; align-items:stretch;
    }
    .reserve-row:last-child{margin-bottom:0;}
    .reserve-row-main{padding:12px 14px;}
    .reserve-row-main.tappable{cursor:pointer;}
    /* Bottoni a piena larghezza divisi in parti uguali, stessa identica
       misura di .tx-card-actions .icon-action-btn — non icone quadrate
       allineate a destra (segnalato dall'utente: "i bottoni non occupano
       tutto lo spazio"). */
    .reserve-row-actions{display:none; gap:8px; padding:0 14px 12px;}
    .reserve-row-actions .icon-action-btn{flex:1; width:auto; height:48px; font-size:18px;}
    .reserve-row.expanded{border-color:var(--accent);}
    .reserve-row.expanded .reserve-row-actions{display:flex;}
  }
  .reserve-row-editing{align-items:stretch;}
  /* Family / personal-tax / auto-card rows are rendered as separate
     .reserve-group blocks so the three categories never blend visually —
     see renderReserveGroup() in app.js. */
  .reserve-group{margin-bottom:10px;}
  .reserve-group:last-child{margin-bottom:0;}
  .reserve-group-title{
    display:flex; justify-content:space-between; align-items:center;
    font-size:12px; text-transform:uppercase; letter-spacing:.6px; color:var(--muted);
    font-weight:600; padding:4px 4px;
  }
  .reserve-group-subtotal{font-family:'IBM Plex Mono',monospace; font-weight:600;}
  .reserve-group .reserve-row:first-child{border-top:1px solid var(--line);}
  @media (max-width:640px){
    .reserve-group .reserve-row:first-child{border-top:none;}
  }
  #interest-quick-list{display:grid; grid-template-columns:repeat(auto-fit, minmax(240px, 1fr)); gap:12px;}
  .interest-row{
    display:flex; flex-wrap:wrap; align-items:center; gap:10px; padding:12px;
    border:1px solid var(--line); border-radius:8px;
  }
  .interest-row .interest-name{flex:1 1 100%; font-size:13.5px; color:var(--ink);}
  .interest-row .interest-total{font-family:'IBM Plex Mono',monospace; font-size:12px; color:var(--muted); white-space:nowrap;}
  .interest-row input{width:110px; text-align:right; flex:0 0 auto;}
  #shortcut-review-list{display:flex; flex-direction:column; gap:10px;}
  .shortcut-review-row{
    display:flex; flex-wrap:wrap; align-items:center; gap:10px; padding:12px;
    border:1px solid var(--gold); border-radius:8px; background:rgba(245,179,66,0.06);
  }
  .shortcut-review-row .shortcut-review-info{flex:1 1 260px; font-size:13.5px; color:var(--ink); display:flex; flex-direction:column; gap:2px;}
  .shortcut-review-row select{width:auto; min-width:160px; flex:0 0 auto;}
  .reserve-row input{width:130px; text-align:right; flex:0 0 auto;}
  .reserve-total{
    display:flex; justify-content:space-between; align-items:center; margin-top:12px;
    padding-top:12px; border-top:1.5px solid var(--line); font-size:13.5px; color:var(--muted);
  }
  .salary-percentage{margin-top:14px; padding-top:14px; border-top:1px dashed var(--line);}
  .salary-percentage .label{font-size:11.5px; text-transform:uppercase; letter-spacing:.8px; color:var(--muted); font-weight:600; display:block;}
  /* Shown only when the card is collapsed (icon lacks .open) — a quick glance
     at the weight percentage without having to reopen the card. */
  .salary-pct-header{display:none; font-family:'IBM Plex Mono',monospace; font-weight:600; font-size:14px;}
  .card-header-row:has(.collapse-arrow:not(.open)) .salary-pct-header{display:inline;}
  tr.total-row td{font-weight:700; border-top:2px solid var(--line); color:var(--ink);}
  tr.rounded-row td{font-style:italic; color:var(--muted); font-size:12.5px;}
  .category-pill{
    display:flex; align-items:center; gap:8px; background:var(--bg-input); border:1px solid var(--line);
    border-radius:999px; padding:6px 8px 6px 14px; font-size:12.5px; color:var(--ink);
  }
  .category-pill.custom{border-color:var(--gold); background:var(--gold-soft); color:var(--gold);}
  .category-pill-remove, .share-pill-remove{
    background:none; border:none; color:var(--muted); font-size:15px; line-height:1; cursor:pointer;
    width:18px; height:18px; border-radius:50%; padding:0;
  }
  .share-row{
    border:1px solid var(--line); border-radius:var(--radius); background:var(--bg-input);
    padding:10px 12px; margin-bottom:8px;
  }
  .share-row-header{display:flex; justify-content:space-between; align-items:center; gap:8px; font-size:13px; color:var(--ink); margin-bottom:8px;}
  .share-row-options{display:flex; flex-wrap:wrap; gap:12px; font-size:12px; color:var(--muted);}
  .share-row-options label{display:flex; align-items:center; gap:5px; cursor:pointer;}
  .category-pill-remove:hover, .share-pill-remove:hover{color:var(--coral); background:var(--coral-soft);}
  .future-date{color:var(--blue); font-weight:600;}
  tr.future-row td{background:rgba(91,140,255,0.05);}

  .bankgroup{margin-bottom:18px;}
  .bankgroup h3{font-family:'Spectral',serif; font-size:16px; margin:0 0 10px; color:var(--muted); font-style:italic; display:flex; align-items:center;}

  .account-card{
    border:1px solid var(--line); border-radius:var(--radius); background:var(--bg-card-alt);
    padding:12px 14px; margin-bottom:10px;
  }
  .account-top{display:flex; align-items:center; gap:10px; flex-wrap:nowrap;}
  .account-top .account-name-display{
    flex:1; min-width:0; font-weight:600; color:var(--ink); font-size:14px;
    padding:5px 6px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  .bullet-sep{color:var(--muted); margin:0 6px;}
  .note-inline{font-size:11.5px; color:var(--muted); font-weight:400;}
  .account-top .balance-display{
    font-family:'IBM Plex Mono',monospace; color:var(--ink); font-size:14px; font-weight:600;
    padding:0 8px; white-space:nowrap; flex:0 0 auto;
  }
  .balance-display.computed-gold, .account-details-grid .computed-note{color:var(--gold);}
  .account-details-grid .computed-note{
    font-family:'IBM Plex Mono',monospace; font-size:13px; padding:7px 0; display:inline-block;
  }

  /* Custom HTML tooltips (replace native title= tooltips) */
  .has-tooltip{position:relative;}
  /* display:none (not opacity:0) so the pseudo-element has zero geometry until
     actually shown — an absolutely-positioned element still counts toward a
     scrollable ancestor's scrollWidth even at opacity:0, which was silently
     widening tables (e.g. Movimenti's actions column) on every device,
     hover-capable or not. Trade-off: no fade/slide transition on appear. */
  .has-tooltip::after{
    content:attr(data-tooltip); position:absolute; bottom:calc(100% + 8px); left:50%;
    transform:translateX(-50%); background:var(--bg-input); color:var(--ink);
    font-family:'Nunito Sans', sans-serif; font-size:11.5px; font-weight:500; line-height:1.4;
    padding:7px 10px; border-radius:7px; width:max-content; max-width:220px; text-align:center;
    white-space:normal; border:1px solid var(--line); box-shadow:0 6px 16px rgba(0,0,0,0.45);
    display:none; pointer-events:none; z-index:80;
  }
  .has-tooltip::before{
    content:''; position:absolute; bottom:calc(100% + 3px); left:50%; transform:translateX(-50%);
    border:5px solid transparent; border-top-color:var(--bg-input);
    display:none; pointer-events:none; z-index:80;
  }
  .has-tooltip:hover::after, .has-tooltip:hover::before{display:block;}
  /* Box alignment set at hover-time by a delegated mouseover listener in app.js,
     based on which half of the screen the trigger is in, so a tooltip near a
     screen edge doesn't run off it. The arrow (::before) always stays centered
     on the trigger regardless — only the text box shifts. */
  .has-tooltip.tooltip-align-left::after{left:0; transform:none;}
  .has-tooltip.tooltip-align-right::after{left:auto; right:0; transform:none;}

  /* Custom date picker (matches tooltip styling: dark card, border, shadow) */
  input.datepicker-input{cursor:pointer; background:var(--bg-input);}
  .datepicker-popover{
    display:none; position:fixed; z-index:1100; background:var(--bg-input); color:var(--ink);
    border:1px solid var(--line); border-radius:10px; box-shadow:0 6px 16px rgba(0,0,0,0.45);
    padding:12px; width:240px; font-family:'Nunito Sans', sans-serif;
  }
  .datepicker-popover.show{display:block;}
  .dp-header{display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;}
  .dp-title{font-family:'Spectral',serif; font-weight:600; font-size:14px; color:var(--ink);}
  .dp-nav{
    background:none; border:1px solid var(--line); color:var(--muted); width:26px; height:26px;
    border-radius:6px; cursor:pointer; font-size:14px; line-height:1;
  }
  .dp-nav:hover{color:var(--teal); border-color:var(--teal);}
  .dp-weekdays{display:grid; grid-template-columns:repeat(7,1fr); gap:2px; margin-bottom:4px;}
  .dp-weekdays span{text-align:center; font-size:10px; color:var(--muted); text-transform:uppercase;}
  .dp-grid{display:grid; grid-template-columns:repeat(7,1fr); gap:2px;}
  .dp-day{
    background:none; border:none; color:var(--ink); font-family:'IBM Plex Mono',monospace; font-size:12px;
    padding:6px 0; border-radius:6px; cursor:pointer; text-align:center;
  }
  .dp-day:hover{background:rgba(34,211,166,0.12); color:var(--teal);}
  .dp-day.dp-empty{cursor:default; pointer-events:none;}
  .dp-day.dp-today{color:var(--gold); font-weight:600;}
  .dp-day.dp-selected{background:var(--teal); color:#04120D; font-weight:600;}
  .dp-footer{margin-top:8px; text-align:center; border-top:1px solid var(--line); padding-top:8px;}
  .dp-today-btn{
    background:none; border:none; color:var(--blue); font-size:11.5px; font-weight:600;
    cursor:pointer; text-transform:uppercase; letter-spacing:.4px;
  }
  .dp-today-btn:hover{color:var(--teal);}
  .icon-edit-btn{
    background:none; border:none; color:var(--muted); font-size:16px; cursor:pointer;
    padding:4px 6px; border-radius:5px; flex:0 0 auto;
  }
  .icon-edit-btn:hover{color:var(--teal); background:rgba(34,211,166,0.1);}
  .icon-action-btn{
    background:none; border:1px solid var(--line); color:var(--muted); width:28px; height:28px;
    border-radius:6px; font-size:14px; cursor:pointer; display:inline-flex; align-items:center;
    justify-content:center; padding:0;
  }
  .icon-action-btn:hover{color:var(--teal); border-color:var(--teal);}
  /* Target di tap minimo 44×44pt su mobile (Apple Human Interface Guidelines)
     — questi pulsanti sono dimensionati per il mouse (20-28px) e diventano
     difficili da toccare con precisione col dito. Ingranditi solo sotto i
     640px, per non alterare la densità dell'interfaccia desktop. Riguarda
     ogni .icon-only-btn.small/.view-switch-btn/.icon-action-btn dell'app,
     non solo Movimenti — la stessa mano che tocca un'icona in Impostazioni
     tocca quella di una card movimento. */
  @media (max-width:640px){
    .icon-only-btn.small{min-width:44px; min-height:44px;}
    .view-switch-btn{min-height:44px; padding:12px 16px;}
    .icon-action-btn{width:40px; height:40px; font-size:16px;}
  }
  /* Stato "attivo" (es. spostamento mese carta di credito, l'unico uso di
     questa classe) sui token semantici del documento delta v4 invece del
     riempimento pieno --blue/testo scuro hardcoded — stessa coppia soft-bg/
     colore-testo già usata da .pill.info. */
  .icon-action-btn.active{background:var(--color-info-soft); color:var(--color-info); border-color:var(--color-info);}
  .icon-action-btn.danger:hover{color:var(--color-danger); border-color:var(--color-danger);}
  /* Varianti semantiche aggiuntive (es. Riserva mensile: "+" riporta al
     valore previsto, "−" azzera) — stesso pattern hover-only di .danger,
     sui token success/warning invece di introdurre nuovi colori. */
  .icon-action-btn.success:hover{color:var(--color-success); border-color:var(--color-success);}
  .icon-action-btn.warning:hover{color:var(--color-warning); border-color:var(--color-warning);}
  .icon-action-btn.reveal-on-hover{opacity:0; transition:opacity .15s ease;}
  tr:hover .icon-action-btn.reveal-on-hover{opacity:1;}
  /* Read-only shared-data view (see switchViewingContext() in app.js). This is
     best-effort UX, not the security boundary — the RLS policies on finance_data
     and the guard in persist()/flushPersist() are what actually stop writes. */
  .read-only-banner{display:none;}
  body.read-only-mode .read-only-banner{
    display:block; background:var(--gold-soft); color:var(--gold); border:1px solid var(--gold);
    border-radius:var(--radius); padding:10px 14px; margin:0 0 16px; font-size:13px;
    text-align:center; font-weight:600;
  }
  /* "Add to home screen" banner (mobile only, shown once per browser — see
     maybeShowA2HSBanner()/installA2HS()/dismissA2HSBanner() in app.js). Hidden
     by default via inline style, toggled by JS. Deliberately a floating card
     (margin from every edge, rounded corners, accent-color border, shadow)
     rather than an edge-to-edge bar — meant to read as a distinct brand
     moment, not another strip of app chrome. The two .a2hs-text spans are
     both in the DOM (for applyTranslations()) but only one is shown at a time
     via .show-android/.show-ios on the banner itself, since Android (native
     install prompt) and iOS Safari (no such API, instructions only) need
     different copy and only Android gets the "Instalar" button. */
  .a2hs-banner{
    position:fixed; left:16px; right:16px; bottom:16px; z-index:1000;
    background:var(--bg-card); border:2px solid var(--accent);
    border-radius:14px; box-shadow:0 8px 28px rgba(0,0,0,.45);
    padding:14px 16px; align-items:center; gap:12px;
    font-size:12.5px; max-width:420px; margin:0 auto;
  }
  .a2hs-icon{width:44px; height:44px; border-radius:11px; flex-shrink:0;}
  .a2hs-body{flex:1; min-width:0; display:flex; flex-direction:column; gap:2px;}
  .a2hs-title{font-family:'Spectral', serif; font-size:15px; color:var(--accent);}
  .a2hs-banner .a2hs-text{display:none; color:var(--muted); line-height:1.35;}
  .a2hs-text-ios strong{color:var(--ink); font-weight:700;}
  .a2hs-banner.show-android .a2hs-text-android{display:block;}
  .a2hs-banner.show-ios .a2hs-text-ios{display:block;}
  .a2hs-banner .a2hs-install-btn{display:none;}
  .a2hs-banner.show-android .a2hs-install-btn{display:inline-block;}
  .a2hs-banner .a2hs-actions{display:flex; flex-direction:column; align-items:center; gap:8px; flex-shrink:0;}
  /* Free-trial tag next to the logo (see trialDaysRemaining()/updateTrialBanner()
     in app.js). Hidden by default (inline style, toggled by JS); shown only while
     days remaining > 0 — never for an admin or a lifetime-free grant. */
  .trial-tag{
    display:none; align-items:center; font-family:'Nunito Sans', sans-serif;
    font-size:11px; font-weight:700; letter-spacing:.3px; white-space:nowrap;
    color:var(--teal); background:var(--teal-soft); border:1px solid var(--teal);
    border-radius:6px; padding:2px 8px; margin-left:8px;
  }
  /* Step counter tag (e.g. "1/3") top-right of each onboarding wizard step's
     header — .card-header-row is already flex/space-between, so this just
     needs to be the row's second child. */
  .onb-step-tag{
    font-family:'Nunito Sans', sans-serif; font-size:11px; font-weight:700;
    letter-spacing:.3px; white-space:nowrap; color:var(--muted);
    background:var(--bg-card-alt); border:1px solid var(--line);
    border-radius:6px; padding:2px 8px; flex-shrink:0;
  }
  body.read-only-mode .icon-action-btn,
  body.read-only-mode .icon-edit-btn,
  body.read-only-mode .category-pill-remove,
  body.read-only-mode .mutation-btn{display:none;}
  /* Elements that double as a value display AND an edit trigger (e.g. tap the
     fund's invested/current-value figure to edit it) must stay visible in
     read-only mode — only their click-to-edit affordance goes away. */
  body.read-only-mode .mutation-value{pointer-events:none; cursor:default;}
  .account-details-panel{margin-top:10px;}
  .funds-list-panel{margin-top:10px; padding:12px; background:var(--bg-input); border-radius:8px;}
  .funds-list-rows{display:flex; flex-direction:column; gap:8px;}
  .fund-list-row{display:flex; align-items:center; gap:10px; font-size:13px;}
  .fund-list-name{flex:1; color:var(--ink); font-weight:600;}
  .fund-list-isin{font-family:'IBM Plex Mono',monospace; color:var(--muted); font-size:12px;}
  .fund-list-invested-value{
    width:90px; flex:0 0 auto; font-family:'IBM Plex Mono',monospace; font-size:12.5px;
    padding:6px 8px; text-align:right; color:var(--ink);
    cursor:pointer; border-bottom:1px dashed var(--muted); transition:color .15s ease, border-color .15s ease;
  }
  .fund-list-invested-value:hover{color:var(--accent); border-color:var(--accent);}
  .fund-edit-panel{
    margin-top:10px; padding:12px; background:var(--bg-input); border-radius:8px;
    display:flex; flex-direction:column; gap:10px;
  }
  .account-details-section{margin-bottom:10px;}
  .account-details-standalone-field{margin-bottom:10px;}
  .account-details-section-title{
    font-size:11px; text-transform:uppercase; letter-spacing:.6px; color:var(--muted);
    font-weight:600; margin:0 0 6px 2px;
  }
  .account-details-grid{
    display:grid; grid-template-columns:repeat(auto-fit, minmax(160px,1fr)); gap:10px;
    padding:12px; background:var(--bg-input); border-radius:8px;
  }
  .account-details-actions{display:flex; justify-content:space-between; align-items:center; margin-top:10px;}
  .inline-edit-panel{
    background:var(--bg-input); border:1px solid var(--line); border-radius:8px; padding:14px;
  }
  tr.edit-row td{padding:10px 8px; background:rgba(91,140,255,0.04);}

  .note{font-size:12px; color:var(--muted); font-style:normal;}
  .empty{padding:20px; text-align:center; color:var(--muted); font-style:italic;}
  .overview-empty-state{padding:56px 20px; text-align:center;}
  .overview-empty-state p{color:var(--muted); margin:0 0 18px; font-size:14px;}
  .toast{
    position:fixed; bottom:20px; right:20px; background:var(--ink); color:var(--bg);
    padding:10px 16px; border-radius:8px; font-size:13px; opacity:0; transition:opacity .3s;
    pointer-events:none; font-weight:600; z-index:1300;
  }
  .toast.show{opacity:1;}
  .toast.error{background:var(--coral); color:#2A0006;}
  .toast.success{background:var(--teal); color:#04120D;}
  .toast.warning{background:var(--gold); color:#241503;}
  .toast.with-action{pointer-events:auto; display:flex; align-items:center; gap:12px;}
  .toast-undo-btn{
    background:none; border:1.5px solid var(--bg); color:var(--bg); border-radius:6px;
    padding:3px 10px; font-size:12px; font-weight:700; cursor:pointer; white-space:nowrap;
  }
  .toast-undo-btn:hover{background:var(--bg); color:var(--ink);}
  .actions-cell{display:flex; gap:6px; flex-wrap:nowrap; justify-content:flex-end;}
  .fund-card{border:1px solid var(--line); border-radius:var(--radius); padding:16px; background:var(--bg-card-alt);}
  .fund-card.expanded{border-color:var(--accent);}
  .fund-card .label{font-size:11.5px; text-transform:uppercase; letter-spacing:.8px; color:var(--muted); font-weight:600;}
  .fund-card .value{font-family:'IBM Plex Mono',monospace; font-size:22px; font-weight:600; margin-top:4px; color:var(--gold);}
  /* Card debito (debtCardHtml): riusa .tx-card-actions per le icone azione
     tap-to-reveal, ma .fund-card ha già il proprio padding su tutti i lati —
     tolto il padding orizzontale/inferiore duplicato di .tx-card-actions,
     aggiunto solo lo spazio sopra per separarla dal contenuto principale. */
  .fund-card .tx-card-actions{padding:12px 0 0;}
  /* Riga a 3 colonne (saldo iniziale/residuo/rata) della card debito:
     affiancate su desktop/tablet, ma sotto ~480px (card ridotta al minimo
     di .debts-grid, 380px) anche 3 colonne strette fanno andare a capo le
     etichette maiuscole ("SALDO INICIAL"/"SALDO PENDIENTE") su due righe —
     sotto quella soglia si impilano una per riga, piena larghezza, stessa
     soglia già usata per .reserve-row-actions qui sopra. */
  .debt-stat-row{flex-wrap:nowrap; gap:16px 24px;}
  .debt-stat-col{min-width:0;}
  .debt-stat-col .value{font-size:16px; white-space:normal; overflow-wrap:anywhere;}
  .debt-stat-col-end{text-align:right;}
  @media (max-width:480px){
    .debt-stat-row{flex-direction:column; align-items:stretch; gap:10px;}
    .debt-stat-col-end{text-align:left;}
  }
  .csv-hint{font-size:12px; color:var(--muted); margin-top:6px;}
  .scroll-x{overflow-x:auto;}

  .confirm-overlay{
    display:none; position:fixed; inset:0; background:rgba(4,6,9,0.72);
    backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
    align-items:center; justify-content:center; z-index:1000; padding:20px;
  }
  .confirm-overlay.show{display:flex;}
  .confirm-box{
    background:var(--bg-card); border:1px solid var(--line); border-radius:var(--radius);
    padding:22px 24px; max-width:380px; width:100%;
    max-height:85vh; overflow-y:auto;
  }
  .confirm-box.wide{max-width:640px;}

  .auth-gate{
    min-height:100vh; display:flex; flex-direction:column; background:var(--bg); overflow-x:hidden;
  }
  /* Il design system era scoped qui (.landing) finché riguardava solo la
     marketing page — ora che i token sono promossi a :root (vedi sopra) e
     usati da tutto il prodotto, questa regola non ha più bisogno di
     ridefinire nulla. */
  .landing{width:100%;}
  .landing-header{
    display:flex; align-items:center; justify-content:space-between;
    max-width:var(--landing-max); margin:0 auto; padding:20px 24px;
  }
  .landing-header-logo{height:32px; width:auto; display:block;}
  .landing-header-right{display:flex; align-items:center; gap:10px;}
  .landing-lang-switch{display:flex; gap:4px;}
  @media (max-width:480px){ .landing-lang-switch button{padding:5px 8px; font-size:11px;} }
  .landing-hero{
    max-width:1100px; margin:0 auto; padding:40px 24px var(--space-24); text-align:center;
  }
  .landing-hero-icon{width:64px; height:64px; margin:0 auto 20px; display:block; animation:landing-float 4s ease-in-out infinite;}
  @keyframes landing-float{0%,100%{transform:translateY(0);} 50%{transform:translateY(-8px);}}
  .landing-badge{
    display:inline-flex; align-items:center; gap:8px; padding:6px 14px; border-radius:999px;
    background:var(--accent-soft); border:1px solid var(--accent); margin-bottom:20px;
    font-family:'Nunito Sans'; font-size:12px; font-weight:700; color:var(--accent); letter-spacing:.3px;
  }
  .landing-badge-dot{width:7px; height:7px; border-radius:50%; background:var(--accent); animation:landing-pulse 2s ease-in-out infinite;}
  @keyframes landing-pulse{0%,100%{opacity:1;} 50%{opacity:.35;}}
  .landing-hero h1{
    font-family:'Spectral',serif; font-weight:600; font-size:clamp(28px,5vw,46px);
    line-height:1.15; margin:0 0 16px; color:var(--ink);
  }
  /* Una sola riga solo da una larghezza dove il testo più lungo (IT, ~947px
     a 46px) ci sta davvero comodo nel container da 1100px — sotto questa
     soglia (inclusi laptop/finestre strette, non solo mobile in senso
     stretto) si torna al wrapping naturale invece di tagliare il testo. */
  @media (min-width:1024px){ .landing-hero h1{white-space:nowrap;} }
  .landing-hero-sub{font-size:16px; line-height:1.6; color:var(--muted); max-width:520px; margin:0 auto 28px;}
  .landing-hero-note{margin-top:12px;}
  button.btn.large{padding:13px 26px; font-size:15px; border-radius:8px;}
  .landing-teaser{max-width:800px; margin:0 auto; padding:0 24px var(--space-24); text-align:center;}
  .landing-teaser-sentence{
    font-family:'Spectral',serif; font-size:28px; font-weight:600; line-height:1.5; color:var(--ink); margin:0;
  }
  @media (max-width:640px){ .landing-teaser-sentence{font-size:22px;} }
  .landing-teaser-sentence strong{color:var(--accent); white-space:nowrap;}
  .landing-teaser-inline-field{color:var(--accent); white-space:nowrap;}
  .landing-teaser-inline-field input{
    font-family:'IBM Plex Mono',monospace; font-size:inherit; font-weight:inherit; color:var(--accent);
    background:transparent; border:none; border-bottom:2px solid var(--accent);
    text-align:center; width:5ch; padding:0 2px;
  }
  .landing-teaser-inline-field input:focus{outline:none;}
  .landing-teaser-inline-field input::-webkit-outer-spin-button, .landing-teaser-inline-field input::-webkit-inner-spin-button{
    -webkit-appearance:none; margin:0;
  }
  .landing-teaser-inline-field input[type=number]{ -moz-appearance:textfield; }
  .landing-features{max-width:var(--landing-max); margin:0 auto; padding:24px 24px var(--space-24);}
  .landing-features h2, .landing-pricing h2, .landing-faq h2{
    font-family:'Spectral',serif; font-weight:600; font-size:32px; text-align:center; color:var(--ink); margin:0 0 36px;
  }
  .landing-features-grid{display:grid; grid-template-columns:repeat(4,1fr); gap:16px;}
  @media (max-width:900px){.landing-features-grid{grid-template-columns:repeat(2,1fr);}}
  @media (max-width:560px){.landing-features-grid{grid-template-columns:1fr;}}
  .landing-feature-card{
    background:var(--bg-card); border:1px solid var(--line); border-radius:var(--radius); padding:22px;
  }
  .landing-feature-icon{
    width:44px; height:44px; border-radius:10px; background:var(--accent-soft); color:var(--accent);
    display:flex; align-items:center; justify-content:center; margin-bottom:14px;
  }
  .landing-feature-card h3{font-family:'Spectral',serif; font-weight:600; font-size:16px; color:var(--ink); margin:0 0 8px;}
  .landing-feature-card p{font-size:13.5px; line-height:1.55; color:var(--muted); margin:0;}
  /* ==== Landing page reusable components ====
     .landing-card is the standard wide content card (background/border/
     radius/padding + centered text by default) used for any full-width or
     half-width explanatory box on the landing page — currently the CSP
     philosophy card and the quiz card. Any value+label box row (bucket
     grids, calculator results, etc.) reuses the app-wide .overview-csp-box/
     .overview-csp-box-highlight component (defined earlier, near Panoramica)
     instead of introducing a new one-off box style — spaced with the shared
     --landing-box-gap token. Two intentional non-.landing-card variants:
     .landing-feature-card (compact tile, smaller padding, for the 4-across
     value-prop grid) and .landing-pricing-card (single highlighted box with
     an accent border, not a generic content card). */
  .landing-card{
    background:var(--bg-card); border:1px solid var(--line); border-radius:var(--radius);
    padding:var(--landing-card-pad); text-align:center;
  }
  .landing-card-kicker{
    font-family:'Nunito Sans'; font-size:12px; font-weight:700; letter-spacing:.5px; text-transform:uppercase;
    color:var(--accent); margin-bottom:10px;
  }
  .landing-card h2{
    font-family:'Spectral',serif; font-weight:600; font-size:28px; color:var(--ink); margin:0 0 16px;
  }
  .landing-card p{
    font-size:14px; line-height:1.65; color:var(--muted); margin:0 0 var(--landing-stack-gap);
  }
  .landing-card-claim{
    font-family:'Spectral',serif; font-weight:600; font-size:17px; color:var(--ink); margin:0 0 12px;
  }
  .landing-philosophy{max-width:var(--landing-max); margin:0 auto; padding:0 24px var(--space-20);}
  /* Category cards (Vivir/Proteger/Crecer/Disfrutar): a richer variant of
     .overview-csp-box with a title + description, used only here — the
     compact value+label box stays the shared component for the calculator's
     result rows, where space is tighter and the description is unnecessary
     (docs/Cuentaduro_Landing_Design_System.md #3). */
  .landing-plan-categories{
    display:grid; grid-template-columns:repeat(4,1fr); gap:var(--landing-box-gap); margin:0 auto;
  }
  @media (max-width:820px){ .landing-plan-categories{grid-template-columns:repeat(2,1fr);} }
  @media (max-width:480px){ .landing-plan-categories{grid-template-columns:1fr;} }
  .landing-plan-category{
    background:var(--bg-card-alt); border:1px solid var(--line); border-radius:var(--radius-md);
    padding:var(--space-5); text-align:left;
  }
  .landing-plan-category-pct{font-family:'IBM Plex Mono',monospace; font-size:var(--font-size-xl); font-weight:700; color:var(--ink);}
  .landing-plan-category-title{font-family:'Spectral',serif; font-weight:600; font-size:var(--font-size-lg); color:var(--ink); margin:var(--space-2) 0 var(--space-2);}
  .landing-plan-category-desc{font-size:var(--font-size-sm); line-height:1.5; color:var(--muted); margin:0;}
  .landing-plan-category-highlight{border-color:var(--accent-border); background:var(--accent-soft);}
  .landing-plan-category-highlight .landing-plan-category-pct{color:var(--accent);}
  .landing-philosophy-card .landing-plan-methodnote{
    font-size:var(--font-size-xs); font-style:italic; color:var(--color-text-tertiary); text-align:center;
    margin:var(--space-8) 0 0;
  }
  .landing-plan-keyline{max-width:720px; margin:0 auto; padding:0 24px var(--space-24); text-align:center;}
  .landing-plan-keyline h2{
    font-family:'Spectral',serif; font-weight:600; font-size:var(--font-size-2xl); line-height:1.25; color:var(--ink); margin:0 0 var(--space-4);
  }
  @media (max-width:640px){ .landing-plan-keyline h2{font-size:var(--font-size-xl);} }
  .landing-plan-keyline p{font-size:var(--font-size-md); line-height:1.6; color:var(--muted); margin:0;}
  .field-helper{font-size:var(--font-size-xs); color:var(--muted); margin:0;}
  .landing-quiz{max-width:var(--landing-max); margin:0 auto; padding:0 24px var(--space-24);}
  .landing-quiz-columns{display:grid; grid-template-columns:1fr 1fr; gap:var(--landing-column-gap); align-items:start; text-align:left;}
  @media (max-width:800px){ .landing-quiz-columns{grid-template-columns:1fr;} }
  .landing-quiz-grid{display:flex; flex-direction:column; gap:var(--landing-stack-gap);}
  .landing-quiz-right{display:flex; flex-direction:column; gap:var(--landing-stack-gap);}
  /* Box "Disfrutar" evidenziato (#quiz-guiltfree-box, ora il PRIMO elemento
     della colonna destra — docs/Cuentaduro_Delta_Spec_Webmaster.v3.md #9:
     "Mantener Disfrutar como resultado principal"): stesso contenitore
     .overview-csp-box-highlight degli altri box, ma contenuto interamente
     personalizzato (planHighlightHtml() in app.js) invece del value/label/
     bar generico — gap più ampio del default (4px) perché qui impiliamo più
     elementi con ruoli diversi (etichetta, valore, tag, descrizione, stato). */
  #quiz-guiltfree-box{gap:8px;}
  .landing-plan-highlight-label{font-size:13px; color:var(--muted);}
  .landing-plan-highlight-value{font-family:'IBM Plex Mono',monospace; font-size:34px; font-weight:700; color:var(--accent);}
  .landing-plan-highlight-value .unit{font-family:'Nunito Sans'; font-size:14px; font-weight:500; color:var(--muted); margin-left:4px;}
  .landing-plan-highlight-tag{font-family:'Spectral',serif; font-weight:600; font-size:15px; color:var(--ink);}
  .landing-plan-highlight-desc{font-size:13px; line-height:1.5; color:var(--muted); margin:4px 0 0;}
  .landing-plan-highlight-status{font-size:12.5px; font-weight:600; color:var(--muted);}
  .landing-plan-highlight-status.is-within{color:var(--color-success);}
  .landing-plan-highlight-negative{font-family:'Spectral',serif; font-weight:600; font-size:17px; line-height:1.4; color:var(--color-danger);}
  /* "Primero Proteger, después Crecer" — appare solo quando Disfrutar è
     negativo E l'utente sta già versando qualcosa a Crecer (vedi
     updateLandingQuiz() in app.js). Box separato, tono informativo non
     critico, stesso bg-card-alt delle category card. */
  .landing-plan-priority-tip{
    background:var(--bg-card-alt); border:1px solid var(--line); border-radius:var(--radius-md);
    padding:var(--space-4); text-align:left;
  }
  .landing-plan-priority-tip-title{font-family:'Spectral',serif; font-weight:600; font-size:var(--font-size-md); color:var(--ink); margin-bottom:4px;}
  .landing-plan-priority-tip p{font-size:var(--font-size-sm); line-height:1.5; color:var(--muted); margin:0;}
  /* Indicatore di range per Disfrutar in euro (min----●----max, con "Tú" alla
     posizione reale) — sostituisce la vecchia barra segmentata a 4 colori,
     ora scoped al solo risultato principale invece che al riepilogo di
     tutte e 4 le categorie (quello vive nella tabella di confronto sotto). */
  .landing-plan-range-track{
    position:relative; height:6px; border-radius:var(--radius-sm); background:var(--bg-card-alt); margin-top:var(--space-2);
  }
  .landing-plan-range-zone{position:absolute; top:0; bottom:0; background:var(--accent-soft); border-radius:var(--radius-sm);}
  .landing-plan-range-dot{
    position:absolute; top:-4px; width:14px; height:14px; margin-left:-7px; border-radius:50%;
    background:var(--muted); border:2px solid var(--bg-card);
  }
  .landing-plan-range-dot.is-within{background:var(--color-success);}
  .landing-plan-range-labels{display:flex; justify-content:space-between; margin-top:var(--space-2); font-size:var(--font-size-xs); color:var(--muted);}
  .landing-plan-range-you{font-weight:700; color:var(--ink);}
  /* Comparazione compatta delle 4 categorie (righe, non nuove card). */
  .landing-plan-compare{display:flex; flex-direction:column;}
  .landing-plan-compare-row{
    display:grid; grid-template-columns:1fr auto auto auto 20px; align-items:center; gap:var(--space-3);
    padding:var(--space-3) 0; border-bottom:1px solid var(--line); font-size:var(--font-size-sm);
  }
  .landing-plan-compare-row:last-child{border-bottom:none;}
  .landing-plan-compare-label{color:var(--ink); font-weight:600;}
  .landing-plan-compare-amount{font-family:'IBM Plex Mono',monospace; color:var(--ink); text-align:right;}
  .landing-plan-compare-pct{color:var(--muted); text-align:right; font-size:var(--font-size-xs);}
  .landing-plan-compare-range{color:var(--color-text-tertiary); text-align:right; font-size:var(--font-size-xs); white-space:nowrap;}
  .landing-plan-compare-check{color:var(--color-success); font-weight:700;}
  @media (max-width:480px){
    .landing-plan-compare-row{grid-template-columns:1fr auto auto 18px; font-size:var(--font-size-xs);}
    .landing-plan-compare-range{display:none;}
  }
  .landing-quiz-cta{text-align:center;}
  .landing-quiz-cta h3{font-family:'Spectral',serif; font-weight:600; font-size:18px; color:var(--ink); margin:0 0 8px;}
  .landing-quiz-cta p{font-size:13.5px; line-height:1.55; color:var(--muted); margin:0 0 16px;}
  .landing-quiz-cta .note{margin-top:10px;}
  .landing-quiz-grid .field label{color:var(--ink);}
  /* Inputs/bottoni normalizzati solo dentro .landing (design doc #27-28):
     stesso comportamento visivo del resto dell'app altrove, qui solo più
     alti/con un focus ring visibile, per un calculator che si senta come
     uno strumento, non un form qualsiasi. */
  .landing input:focus, .landing select:focus, .landing textarea:focus{
    outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft);
  }
  .landing-quiz-grid .field input{height:46px; border-radius:8px;}
  .landing button.btn.large{min-height:48px; border-radius:8px;}
  .landing-pricing{max-width:var(--landing-max); margin:0 auto; padding:24px 24px var(--space-24);}
  .landing-pricing-sub{text-align:center; color:var(--muted); font-size:14px; margin:-24px 0 32px;}
  .landing-pricing-card{
    max-width:380px; margin:0 auto; background:var(--bg-card); border:1.5px solid var(--accent);
    border-radius:var(--radius); padding:32px 28px; text-align:center;
  }
  .landing-trial-badge{
    display:inline-block; padding:5px 12px; border-radius:999px; background:var(--teal-soft); color:var(--teal);
    font-family:'Nunito Sans'; font-size:12px; font-weight:700; margin-bottom:14px;
  }
  .landing-price{
    font-family:'IBM Plex Mono',monospace; font-size:40px; font-weight:600; color:var(--ink); margin-bottom:4px;
  }
  .landing-price span{font-family:'Nunito Sans'; font-size:15px; font-weight:600; color:var(--muted); margin-left:2px;}
  .landing-price-vat-note{font-family:'Nunito Sans'; font-size:11.5px; color:var(--muted); margin-bottom:20px;}
  .landing-pricing-list{list-style:none; margin:0 0 24px; padding:0; text-align:left; display:flex; flex-direction:column; gap:10px;}
  .landing-pricing-list li{
    font-size:13.5px; color:var(--ink); padding-left:24px; position:relative; line-height:1.4;
  }
  .landing-pricing-list li::before{
    content:'✓'; position:absolute; left:0; top:0; color:var(--accent); font-weight:700;
  }
  .landing-pricing-note{margin-top:14px;}
  .landing-faq{max-width:680px; margin:0 auto; padding:24px 24px var(--space-24);}
  .landing-faq-item{
    border-bottom:1px solid var(--line); padding:16px 0;
  }
  .landing-faq-item summary{
    cursor:pointer; font-family:'Nunito Sans'; font-weight:600; font-size:14.5px; color:var(--ink); list-style:none;
  }
  .landing-faq-item summary::-webkit-details-marker{display:none;}
  .landing-faq-item summary::before{content:'+'; display:inline-block; width:16px; color:var(--accent); font-weight:700;}
  .landing-faq-item[open] summary::before{content:'–';}
  .landing-faq-item p{margin:10px 0 0 16px; font-size:13.5px; line-height:1.55; color:var(--muted);}
  .landing-footer{
    display:flex; flex-direction:column; align-items:center; gap:10px;
    padding:28px 24px; border-top:1px solid var(--line);
    font-size:12.5px; color:var(--muted); text-align:center;
  }
  .landing-footer-row{display:flex; align-items:center; gap:10px;}
  .landing-footer-icon{width:22px; height:22px; border-radius:6px;}
  .landing-footer-links{display:flex; align-items:center; gap:8px; font-size:12px;}
  .landing-footer-links a, .landing-footer-links a:visited{color:var(--muted); text-decoration:none;}
  .landing-footer-links a:hover{color:var(--accent);}
  .landing-footer-links span{color:var(--line);}
  /* Plain <a> tags with no other styling (e.g. the legal-page links at the
     bottom of Impostazioni) otherwise fall back to the browser's default
     link colors (blue/purple), including a distinct :visited color — pin
     both states to the same muted color so a visited link never looks
     different from an unvisited one. */
  .settings-legal-links a, .settings-legal-links a:visited{color:var(--muted); text-decoration:none;}
  .settings-legal-links a:hover{color:var(--accent);}
  .confirm-box p{margin:0 0 18px; font-size:14px; line-height:1.5; color:var(--ink);}
  .confirm-box .note{color:var(--muted); font-size:12px; line-height:normal;}
  .confirm-actions{display:flex; justify-content:flex-end; gap:10px;}

  /* iOS Safari auto-zooms the page on focusing any input/select whose computed
     font-size is under 16px — that's the "page grows and pans sideways when I
     tap a field" behaviour. Keeping form fields at >=16px on mobile only (the
     compact look under 16px stays on desktop) avoids triggering it at all.
     Keep this block LAST in the file: every rule above sets font-size on some
     input/select variant at equal or higher specificity than plain `input,
     select`, so with an unconditional cascade, whichever rule is written last
     wins regardless of the media query — this one needs to out-rank all of
     them, including ones added after this comment was written. */
  @media (max-width:640px){
    input, select, .multiselect-search{font-size:16px;}
  }

  /* Tooltips only make sense with a real hover state — on touch they either
     never appear or need an extra tap that eats the first tap meant for the
     button underneath. Turn them off on touch devices everywhere except
     Pareja, where the user still wants them. Same equal-specificity-vs-
     source-order situation as the font-size block above (both this rule and
     the base .has-tooltip:hover::after are `.has-tooltip:hover::after`), so
     this also needs to stay LAST in the file. */
  @media (hover:none) and (pointer:coarse){
    .has-tooltip:hover::after, .has-tooltip:hover::before{display:none;}
    #panel-pareja .has-tooltip:hover::after, #panel-pareja .has-tooltip:hover::before{display:block;}
  }
