/* =========================================================================
   BlissPoint — foglio di stile unico.
   Sostituisce Bootstrap (232 KB da CDN) e gli attributi style= inline.

   IDENTITÀ: BLU DI BASE, VIOLA COME FIRMA
   Il colore dell'interfaccia è il blu del marchio, #005FF9 (RGB 0, 95, 249).
   È il blu a portare titoli, collegamenti, icone, bordi, interruttori, barre
   informative e il portafoglio a rischio minimo: praticamente tutto.

   I DUE COLORI NON CAMBIANO CON IL TEMA, E NON È UN DETTAGLIO
   Prima il fondo scuro li sostituiva con due versioni schiarite — #5AA6F0 al
   posto del blu, #AF83E2 al posto del viola — per guadagnare contrasto sul
   testo. Ma un colore identitario che al buio diventa un'altra tinta non è
   più identitario: chi guarda il sito di sera vede un azzurro e un lilla che
   non sono quelli del marchio. Adesso #005FF9 e #6F2DBD valgono tali e quali
   nei due temi, ovunque: pieni, barre, testo, filetti, punti del grafico.
   Le sole varianti rimaste sono gli STATI — il colore del passaggio del
   mouse su un collegamento o su un pulsante — che non sono colori a riposo e
   non si vedono su un telefono.

   COSA COSTA, DETTO CHIARO
   Su fondo scuro #005FF9 sta a 3,2:1 e #6F2DBD a 2,2:1 rispetto alla
   superficie delle card. Per un pieno o una barra va bene; per il testo
   piccolo sono sotto la soglia consigliata, e un numero viola su fondo notte
   si legge peggio di prima. È una scelta d'identità presa sapendolo: se un
   punto diventa illeggibile si alza il contrasto della SUPERFICIE sotto, non
   si cambia il colore sopra.

   Il viola è #6F2DBD (RGB 111, 45, 189). Non è una seconda tinta
   d'arredamento, è una firma. Compare in sei punti in tutto il sito e in
   nessun altro:

     1. il pulsante d'azione principale;
     2. la voce di menu in cui ci si trova;
     3. il segmentato sulla voce scelta;
     4. IL PUNTEGGIO PIÙ ALTO — da 80 in su, in cima alla scala rosso →
        giallo → verde → viola (vedi «LA SCALA DEI VOTI» più sotto);
     5. la scheda portafoglio mentre se ne cambia il nome;
     6. il gradino più alto della scala dello Sharpe nel grafico, che è il
        punto 4 detto su un'altra scala: viola vuol dire «il meglio», e lo
        vuol dire in tutte e due.

   IL PORTAFOGLIO OTTIMALE, INVECE, È CORALLO — E NON È UNA SVISTA
   Ha il suo colore da sempre (#D9543C, più chiaro al buio) e se lo tiene:
   il filetto in cima alla sua card, la sua icona, le sue barre, il suo
   punto e la sua retta nel grafico, la sua voce in legenda. È un
   colore-DATO, non un colore d'identità: serve a distinguerlo dal
   portafoglio a rischio minimo, che è blu, e i due devono leggersi come
   una coppia. Per un momento è stato viola, e il risultato era che il
   viola non diceva più «il meglio» ma «uno dei due portafogli».

   Erano sette: l'interruttore del confronto e le iniziali B e P del claim
   sono passati al blu del marchio. Le iniziali, in particolare, ripetono il
   logo che sta lì accanto, e ripeterlo in un altro colore era una stonatura.

   Quando si vede quel colore c'è qualcosa che conta. Il suo valore sta nel
   fatto che si usa poco: aggiungerlo altrove lo annacqua e basta.

   Nessuna estetica da exchange: niente neon, niente gradienti colorati a
   riempire i fondi, niente cromature. Angoli morbidi, bordi sottili, ombre
   appena percepibili, molto spazio bianco.

   Struttura: 1 token · 2 base · 3 layout · 4 testata/piè · 5 componenti
              6 form · 7 ottimizzatore · 8 risultati · 9 stati · 10 pagine
              11 utilità · 12 movimento · 13 responsive · 14 stampa
   ========================================================================= */

/* ---------- 1. TOKEN ---------------------------------------------------- */
:root {
  /* Neutri freddi: la stessa famiglia del blu, desaturata quasi del tutto.
     È questo che tiene insieme le superfici e fa sembrare le card parti di un
     unico sistema invece che riquadri aggiunti uno alla volta. */
  --ground: #f5f7fa;
  --surface: #ffffff;
  --surface-2: #eef2f7;
  /* La superficie delle card di servizio — quote, salvataggio, metodologia.
     E' un token a parte e non `--surface-2` riusato, perche' nei due temi va
     in DIREZIONI OPPOSTE: sul chiaro deve essere piu' scura del bianco per
     arretrare, sul fondo scuro deve essere piu' SCURA della superficie
     normale, mentre `--surface-2` li' e' piu' chiara e la card di servizio
     sarebbe finita per risaltare piu' del risultato. E' esattamente il tipo
     di errore che un token riusato per comodita' produce. */
  --surface-quieta: #eef2f7;
  --surface-3: #e3e9f1;
  --ink: #0d1b2a;
  --ink-2: #46586e;
  --ink-3: #5f7288;
  --line: #dfe5ee;
  --line-2: #c8d2df;

  /* Il blu dell'interfaccia: la tinta del logo (#005CF4) portata a 5.9:1 sul
     bianco, così regge anche come colore di testo. È il colore che si vede
     ovunque — collegamenti, icone, bordi attivi, barre informative. */
  --brand: #005ff9;
  /* IL BLU QUANDO FA DA TESTO, NON DA FORMA.
     #005FF9 su fondo scuro sta a 3,2:1 rispetto alla superficie di una card:
     per un pieno, un bordo o un interruttore va benissimo, per una riga di
     testo che si puo' toccare no — e sono proprio i collegamenti a doversi
     leggere al primo colpo. Sul chiaro `--brand-ink` E' #005FF9; sul fondo
     scuro passa a #5294FF, che ha lo stesso H 217° e la stessa saturazione,
     e cambia solo la luminosita' (L 66% invece di 49%): sale a 5,7:1.
     La regola e' semplice: FORMA -> `--brand`, TESTO -> `--brand-ink`. */
  --brand-ink: #005ff9;
  /* Solo per il passaggio del mouse: e' uno STATO, non un colore a riposo. */
  --brand-2: #0049c4;
  --on-brand: #ffffff;
  --brand-soft: #e6efff;
  --ring: rgba(0, 95, 249, .22);

  /* IL VIOLA — la firma, non l'arredamento.
     #6F2DBD, RGB 111 45 189: H 267°, S 62%, L 46%. Sostituisce il #6D3F5B
     precedente, che era un viola-rosso desaturato e a schermo leggeva piu'
     come prugna che come viola.
     Come pieno porta il bianco sopra a 7,5:1, e come TESTO su fondo chiaro
     sta anch'esso a 7,5:1. Nel tema chiaro, quindi, il colore si usa tale e
     quale dappertutto: pieni e testo.
     `--accent-ink` resta come nome per i punti in cui il viola fa da TESTO o
     da segno sottile, ma ora vale #6F2DBD come `--accent`: il colore del
     marchio non cambia con il tema. Il nome serve ancora, perche' dice quali
     usi andrebbero rivisti per primi se un giorno servisse piu' contrasto al
     buio — la' si alzera' la superficie sotto, non la tinta sopra. */
  --accent: #6f2dbd;
  --accent-ink: #6f2dbd;
  --accent-soft: #f4effb;
  /* Il pieno del pulsante quando ci passi sopra: sul chiaro si scurisce,
     sullo scuro si schiarisce, così il bianco sopra resta sempre sopra 6:1. */
  --accent-hover: #57238e;
  --on-accent: #ffffff;
  --ring-accent: rgba(111, 45, 189, .30);

  /* Colori-dato: sono gli stessi valori con cui il motore disegna i due
     punti del grafico — vedi `TEMI_GRAFICO` in app.py, dove sono copiati uno
     per uno. Cambiarli qui senza cambiarli là vorrebbe dire che la legenda
     smette di corrispondere all'immagine.
     `--blue` è il blu del marchio: il portafoglio a rischio minimo è una
     delle cose che il blu porta, non un colore a parte. Il corallo, invece,
     non è del marchio — è la retta della liquidità, l'unica riga del grafico
     che non appartiene alla nuvola — e quello sì si schiarisce al buio. */
  --blue: #2e7fd4;
  --coral: #d9543c;
  /* IL VERDE SCURO DEL PORTAFOGLIO CHE L'UTENTE POSSIEDE DAVVERO.
     #00843D esatto sul chiaro: 4,9:1 sul bianco, quindi regge anche come
     testo. Non e' un colore del marchio ed e' voluto — come il blu e il
     corallo dei due portafogli calcolati e' un colore-DATO, serve a
     riconoscere una cosa sola, e non deve poter essere scambiato per un
     elemento dell'interfaccia.
     `--mio-soft` e' il fondo tenue della colonna e della card. */
  --mio: #00843D;
  --mio-ink: #00843D;
  --mio-soft: #e6f4ec;

  /* Semantici: distinti dall'accento e dai colori-dato. */
  --pos: #0b7a5c;
  --neg: #b62b22;
  --warn: #8a5a08;
  --pos-soft: #e3f4ee;
  --neg-soft: #fceceb;
  --warn-soft: #fbf1de;

  /* Ombre: due strati appena accennati. Una card non deve galleggiare, deve
     staccarsi dal fondo quel tanto che basta a leggersi come superficie. */
  --shadow-s: 0 1px 2px rgba(13, 27, 42, .05);
  --shadow: 0 1px 2px rgba(13, 27, 42, .05), 0 10px 30px -18px rgba(13, 27, 42, .2);
  --shadow-m: 0 2px 4px rgba(13, 27, 42, .06), 0 18px 40px -22px rgba(13, 27, 42, .26);
  /* L'unica ombra colorata del sito, e sta sotto al solo pulsante d'azione:
     appena accennata, non un alone. */
  --shadow-accent: 0 8px 22px -14px rgba(111, 45, 189, .55);

  /* IBM Plex, servito dal nostro dominio: nessuna dipendenza esterna.
     Se i file non ci sono, i fallback di sistema reggono la pagina. */
  /* GLI IDEOGRAMMI NON STANNO IN IBM PLEX, E VANNO CHIESTI AL SISTEMA
     IBM Plex Sans non contiene un solo carattere cinese. Senza queste voci
     in coda, ogni pagina in cinese cadrebbe sul generico `sans-serif`, cioe'
     su qualunque cosa il browser scelga — spesso un carattere con
     proporzioni diverse, che fa ballare l'impaginazione da una riga
     all'altra. Elencandoli, il browser prende il carattere di sistema giusto
     per gli ideogrammi e continua a usare Plex per lettere e cifre: la
     scelta la fa segno per segno, non blocco per blocco.
     PingFang e Hiragino sono di Apple, Microsoft YaHei di Windows, Noto Sans
     CJK di Android e Linux: coprono tutto senza scaricare niente. */
  --font-ui: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
             Roboto, Helvetica, Arial,
             "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
             "Noto Sans CJK SC", "Noto Sans SC", "Source Han Sans SC",
             "WenQuanYi Micro Hei", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono",
               Menlo, Consolas, "Liberation Mono",
               "Noto Sans Mono CJK SC", "Microsoft YaHei", monospace;

  /* Scala di spaziatura: multipli di 4, niente valori a occhio. */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 20px; --s6: 32px; --s7: 48px; --s8: 64px;

  /* Raggi: la scala che dà alle card la forma morbida. */
  --r-xl: 24px;
  --r-l: 20px;
  --r: 16px;
  --r-s: 11px;
  --r-xs: 8px;
  --r-pill: 999px;

  --max: 1200px;
  /* La colonna stretta: pagine che sono una sola sequenza di testo e moduli —
     il profilo, le pagine legali. A 1200 px una card con dentro un paragrafo
     e un pulsante e' vuota per due terzi, e una fila di scatole quasi vuote
     e' esattamente cio' che fa sembrare improvvisata una pagina curata. */
  --max-colonna: 860px;

  /* L'ALTEZZA DELLA TESTATA, DICHIARATA UNA VOLTA SOLA.
     La barra e' appiccicata in cima, quindi ogni salto a un'ancora deve
     fermarsi PIU' SOTTO di quanto farebbe da solo, o il titolo di
     destinazione finisce nascosto dietro la barra. Prima il valore era
     scritto a mano (84 px) su tre soli identificativi: valeva per i
     risultati e non per «#ottimizzatore», cioe' proprio per il salto che fa
     il pulsante principale della prima pagina. Qui e' un token, e sotto e'
     `scroll-padding-top` sull'intero documento: vale per ogni ancora, anche
     per quelle che verranno. */
  --topbar-h: 64px;

  /* Movimento: una sola curva e tre durate, così tutto il sito accelera e
     rallenta nello stesso modo. */
  --ease: cubic-bezier(.22, .61, .36, 1);
  --dur-s: .14s;
  --dur: .22s;
  --dur-l: .5s;
}

/* Il tema scuro ridefinisce SOLO i token: nessuna regola di componente vive
   dentro un blocco di tema, così una superficie non può esistere in un tema
   e mancare nell'altro.
   Sul fondo scuro le due tinte si schiariscono per restare leggibili, e i
   pieni (pulsante d'azione) prendono il testo scuro invece che bianco. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #0a121b; --surface: #111e2a; --surface-2: #16242f; --surface-3: #1d2e3b;
    --surface-quieta: #0d1720;
    --ink: #e7eef6; --ink-2: #a2b4c8; --ink-3: #8296ab;
    --line: #22333f; --line-2: #2e4252;
    --brand: #005ff9; --brand-ink: #5294ff; --brand-2: #7fb0ff; --on-brand: #ffffff;
    --brand-soft: #0d2444;
    --ring: rgba(0, 95, 249, .38);
    --accent: #6f2dbd; --accent-ink: #6f2dbd; --accent-soft: #220e3a;
    --accent-hover: #8442d2; --on-accent: #ffffff; --ring-accent: rgba(111, 45, 189, .40);
    --blue: #5aa6f0; --coral: #ee7159;
  /* Il verde tiene il valore esatto come pieno — un rombo, una
     barra, un bordo — e si schiarisce SOLO quando fa da testo:
     #00843D su fondo notte sta sotto 2:1 e una cifra scritta
     cosi' non si legge. Stessa regola di `--brand`/`--brand-ink`. */
  --mio: #00843D; --mio-ink: #3fbe7a; --mio-soft: #0f2a1d;
    --pos: #33b18c; --neg: #e4695b; --warn: #d3a04a;
    --pos-soft: #12312a; --neg-soft: #33201d; --warn-soft: #33291a;
    --shadow-s: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 12px 30px -18px rgba(0, 0, 0, .85);
    --shadow-m: 0 2px 4px rgba(0, 0, 0, .45), 0 20px 44px -22px rgba(0, 0, 0, .9);
    --shadow-accent: 0 10px 26px -16px rgba(111, 45, 189, .55);
  }
}
:root[data-theme="dark"] {
  --ground: #0a121b; --surface: #111e2a; --surface-2: #16242f; --surface-3: #1d2e3b;
    --surface-quieta: #0d1720;
  --ink: #e7eef6; --ink-2: #a2b4c8; --ink-3: #8296ab;
  --line: #22333f; --line-2: #2e4252;
  --brand: #005ff9; --brand-ink: #5294ff; --brand-2: #7fb0ff; --on-brand: #ffffff;
  --brand-soft: #0d2444;
  --ring: rgba(0, 95, 249, .38);
  --accent: #6f2dbd; --accent-ink: #6f2dbd; --accent-soft: #220e3a;
  --accent-hover: #8442d2; --on-accent: #ffffff; --ring-accent: rgba(111, 45, 189, .40);
  --blue: #5aa6f0; --coral: #ee7159;
  /* Il verde tiene il valore esatto come pieno — un rombo, una
     barra, un bordo — e si schiarisce SOLO quando fa da testo:
     #00843D su fondo notte sta sotto 2:1 e una cifra scritta
     cosi' non si legge. Stessa regola di `--brand`/`--brand-ink`. */
  --mio: #00843D; --mio-ink: #3fbe7a; --mio-soft: #0f2a1d;
  --pos: #33b18c; --neg: #e4695b; --warn: #d3a04a;
  --pos-soft: #12312a; --neg-soft: #33201d; --warn-soft: #33291a;
  --shadow-s: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 12px 30px -18px rgba(0, 0, 0, .85);
  --shadow-m: 0 2px 4px rgba(0, 0, 0, .45), 0 20px 44px -22px rgba(0, 0, 0, .9);
  --shadow-accent: 0 10px 26px -16px rgba(111, 45, 189, .55);
}

/* ---------- 2. BASE ----------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

/* Ogni salto a un'ancora si ferma sotto la barra appiccicata in cima: vedi
   `--topbar-h`. Qui e non sui singoli identificativi, cosi' vale anche per il
   salto al contenuto e per «#ottimizzatore». */
html { scroll-padding-top: calc(var(--topbar-h) + var(--s5)); }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* IL PIE' DI PAGINA STA IN FONDO ALLO SCHERMO, NON A META'.
     Su ogni pagina corta — accesso, conferma, errore, esempio non
     disponibile — il contenuto finiva a meta' altezza, il piè di pagina lo
     seguiva subito e sotto restava una striscia di fondo vuota alta un
     terzo di schermo: la pagina sembrava troncata. Colonna alta almeno
     quanto la finestra, con il contenuto che si prende lo spazio che avanza
     (`main { flex: 1 0 auto }`) e spinge il piè di pagina in fondo. Nelle
     pagine lunghe non cambia niente. */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

h1, h2, h3, h4 { margin: 0; line-height: 1.2; text-wrap: balance; font-weight: 600; }
h1 { font-size: clamp(30px, 4.4vw, 42px); letter-spacing: -.028em; }
h2 { font-size: clamp(21px, 2.6vw, 26px); letter-spacing: -.02em; }
h3 { font-size: 17px; letter-spacing: -.008em; }
h4 {
  font-family: var(--font-mono); font-size: 12px; font-weight: 500;
  text-transform: uppercase; letter-spacing: .09em; color: var(--ink-3);
}
p { margin: 0; }
a { color: var(--brand-ink); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--brand-2); }
img { max-width: 100%; height: auto; }

:where(a, button, input, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

code, .num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
code {
  font-size: .87em; background: var(--surface-2); color: var(--ink-2);
  padding: .12em .38em; border-radius: var(--r-xs);
}
.muted { color: var(--ink-2); }
.small { font-size: 13.5px; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Salto al contenuto: fuori dallo schermo finche' non lo si raggiunge col
   tabulatore, e allora scende in alto a sinistra sopra ogni altra cosa.
   Non usa `.visually-hidden` perche' quello resta invisibile anche col fuoco
   sopra: un comando che non si vede nel momento in cui lo si sta usando non
   e' un comando. `z-index` alto perche' la testata e' appiccicata in cima. */
.skip-link {
  position: absolute; left: var(--s3); top: -100px; z-index: 999;
  background: var(--brand); color: var(--on-brand);
  padding: .6rem 1rem; border-radius: var(--r-xs);
  font-weight: 600; text-decoration: none;
  transition: top .12s ease-out;
}
.skip-link:focus {
  top: var(--s3); color: var(--on-brand);
  outline: 2px solid var(--ink); outline-offset: 2px;
}
/* Il bersaglio del salto riceve il fuoco: senza `tabindex="-1"` sul <main>
   alcuni browser spostano solo la barra di scorrimento e il tabulatore
   successivo riparte dalla testata, cioe' dal punto da cui si voleva uscire.
   Il contorno pero' non si disegna: e' una destinazione, non un comando. */
#contenuto:focus { outline: none; }

/* ---------- 3. LAYOUT --------------------------------------------------- */
.wrap { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 var(--s5); }
/* La colonna stretta di `--max-colonna`: si dichiara sul `.wrap` della
   testata E su quello del corpo, cosi' titolo e contenuto restano allineati
   sullo stesso asse invece di scivolare uno rispetto all'altro. */
.wrap--colonna { max-width: var(--max-colonna); }
.page { padding: var(--s7) 0 var(--s8); }
/* LE SEZIONI DI UNA PAGINA NON SONO LE RIGHE DI UNA SEZIONE.
   La colonna del contenuto usava `.stack-lg`, cioe' 32 px, sia fra il modulo
   e «come funziona» sia fra due card dentro lo stesso capitolo: la pagina si
   leggeva come un elenco piatto di riquadri tutti alla stessa distanza, e
   dove finiva un discorso e cominciava il successivo lo si capiva solo
   leggendo i titoli. Al primo livello — il figlio diretto di `.page` — lo
   stacco sale a 48 px. Dentro le sezioni non cambia niente: la gerarchia la
   fa la differenza fra le due misure, non la misura in se'. */
.page > .wrap.stack-lg { gap: var(--s7); }
/* Il contenuto si prende tutto lo spazio che avanza fra testata e piè di
   pagina; `0 auto` e non `1` perche' una base automatica evita che una
   pagina lunga venga schiacciata dal flex. */
main { flex: 1 0 auto; }
.prose { max-width: 68ch; display: flex; flex-direction: column; gap: var(--s4); }
.prose h2 { margin-top: var(--s5); }
.stack { display: flex; flex-direction: column; gap: var(--s5); }
.stack-s { display: flex; flex-direction: column; gap: var(--s3); }
.stack-lg { display: flex; flex-direction: column; gap: var(--s6); }
.row { display: flex; gap: var(--s3); align-items: center; flex-wrap: wrap; }
.row--split { justify-content: space-between; }
.center-narrow { max-width: 460px; margin: 0 auto; }

/* ---------- 4. TESTATA E PIÈ DI PAGINA ---------------------------------- */
.topbar {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  backdrop-filter: saturate(1.5) blur(14px);
  border-bottom: 1px solid var(--line);
}
.topbar .wrap {
  display: flex; align-items: center; gap: var(--s4);
  min-height: 64px; padding-block: var(--s2);
}
.brand { display: flex; align-items: center; gap: var(--s2); font-weight: 600;
         color: var(--ink); text-decoration: none; flex: none; }
.brand img { width: 26px; height: 26px; border-radius: var(--r-xs); display: block; }
.brand .wordmark { font-size: 17px; }

/* ---- IL NOME SCRITTO COME UN MARCHIO -------------------------------------
   Era un `<span>` di testo normale, con il peso del resto della barra: in
   pagina «BlissPoint» si leggeva come una parola qualunque, non come il nome
   di qualcosa. Qui non si scarica un carattere da un'altra parte — il sito
   non fa nessuna richiesta a server di font, e non comincia adesso per una
   parola — si lavora sulla forma: due pesi, due colori e la spaziatura
   stretta, che è il modo in cui un logotipo si distingue da una scritta.
   IN BLU CI VANNO LE DUE INIZIALI, NON MEZZA PAROLA.
   Prima «Bliss» stava in nero e «Point» tutto in blu: due blocchi di colore
   che tagliavano il nome a metà, e l'icona qui accanto — che porta una B e
   una P — non c'entrava niente con la scritta. Adesso il blu sta sulle due
   lettere che stanno anche nell'icona, e il resto della parola tiene
   l'inchiostro: il logotipo e il segno dicono la stessa cosa.
   `font-feature-settings` accende i tagli tipografici del carattere dove ci
   sono, e dove non ci sono non succede niente. */
.wordmark {
  font-family: var(--font-ui);
  font-weight: 500; letter-spacing: -.03em;
  font-feature-settings: "ss02" 1, "cv05" 1;
  white-space: nowrap; line-height: 1.1;
}
.wordmark b { font-weight: 700; color: var(--brand); }
/* Il resto delle lettere è NERO PIENO. Un inchiostro più tenue era stato
   provato e non va: il nome è un marchio, e un marchio non si scrive in
   grigio. Le due iniziali blu bastano da sole a fare la distinzione.
   La `<a class="brand">` impone il suo colore ai discendenti, quindi la
   regola va ripetuta con la sua specificità o non si vede mai. */
.wordmark { color: var(--ink); }
.brand .wordmark { color: var(--ink); }
.wordmark--grande { font-size: clamp(30px, 4.2vw, 44px); letter-spacing: -.04em; }

.nav { display: flex; gap: 2px; margin-left: var(--s3); flex: 1; }
.nav a {
  position: relative; color: var(--ink-2); text-decoration: none; font-size: 14px;
  padding: 8px 12px; border-radius: var(--r-s);
  transition: background var(--dur-s) var(--ease), color var(--dur-s) var(--ease);
}
.nav a:hover { background: var(--surface-2); color: var(--ink); }
.nav a[aria-current="page"] { color: var(--ink); background: var(--surface-2); font-weight: 500; }
/* Il filetto viola sotto la voce corrente: l'unico posto della barra in cui
   il colore identitario compare, e basta a dire dove si è. */
.nav a[aria-current="page"]::after {
  content: ""; position: absolute; left: 12px; right: 12px; bottom: 4px;
  height: 2px; border-radius: 2px; background: var(--accent);
}

.topbar-end { display: flex; align-items: center; gap: var(--s2); flex: none; }

/* Selettore lingua: form GET, funziona anche senza JavaScript. */
.langpick { position: relative; display: flex; }
.langpick select {
  appearance: none; font-family: var(--font-ui); font-size: 13.5px;
  color: var(--ink-2); background: transparent; border: 1px solid var(--line-2);
  border-radius: var(--r-s); padding: 8px 28px 8px 11px; cursor: pointer;
  transition: border-color var(--dur-s) var(--ease), color var(--dur-s) var(--ease);
}
.langpick::after {
  content: ""; position: absolute; right: 11px; top: 50%; width: 6px; height: 6px;
  border-right: 1.5px solid var(--ink-3); border-bottom: 1.5px solid var(--ink-3);
  transform: translateY(-70%) rotate(45deg); pointer-events: none;
}
.langpick select:hover { border-color: var(--brand); color: var(--ink); }

/* Menu account: <details>, nessun JavaScript. */
.menu { position: relative; }
.menu > summary {
  list-style: none; cursor: pointer; font-size: 14px; color: var(--ink);
  padding: 8px 13px; border: 1px solid var(--line-2); border-radius: var(--r-s);
  display: flex; align-items: center; gap: 7px; user-select: none;
  transition: background var(--dur-s) var(--ease), border-color var(--dur-s) var(--ease);
}
.menu > summary::-webkit-details-marker { display: none; }
.menu > summary::after {
  content: ""; width: 5px; height: 5px; border-right: 1.5px solid var(--ink-3);
  border-bottom: 1.5px solid var(--ink-3); transform: translateY(-2px) rotate(45deg);
  transition: transform var(--dur) var(--ease);
}
.menu > summary:hover { background: var(--surface-2); border-color: var(--brand); }
.menu[open] > summary { background: var(--surface-2); }
.menu[open] > summary::after { transform: translateY(1px) rotate(225deg); }
.menu-body {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 200px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--shadow-m); padding: var(--s1);
  display: flex; flex-direction: column; z-index: 60;
  animation: cala var(--dur) var(--ease) both;
}
.menu-body a, .menu-body button {
  display: block; width: 100%; text-align: left; background: none; border: 0;
  font: inherit; font-size: 14px; color: var(--ink-2); text-decoration: none;
  padding: 9px 12px; border-radius: var(--r-s); cursor: pointer;
  transition: background var(--dur-s) var(--ease), color var(--dur-s) var(--ease);
}
.menu-body a:hover, .menu-body button:hover { background: var(--brand-soft); color: var(--brand-ink); }
.menu-body hr { border: 0; border-top: 1px solid var(--line); margin: var(--s1) 0; }

.footer { border-top: 1px solid var(--line); background: var(--surface); }
.footer .wrap {
  display: flex; flex-wrap: wrap; gap: var(--s4) var(--s5);
  align-items: center; justify-content: space-between;
  padding-block: var(--s6); font-size: 13.5px; color: var(--ink-3);
}
.footer nav { display: flex; gap: var(--s4); flex-wrap: wrap; }
.footer a { color: var(--ink-2); text-decoration: none; }
.footer a:hover { color: var(--brand-ink); }
/* La riga che dice che questi sono calcoli e non consigli va a capo da sola,
   sotto i collegamenti: non compete con loro per lo spazio, e si legge. */
.footer-disclaimer { flex-basis: 100%; margin: 0; max-width: 90ch;
                     font-size: 12.5px; color: var(--ink-3); }

/* ---------- 5. COMPONENTI ----------------------------------------------- */
/* La card è UNA sola forma, dichiarata una volta sola: stesso raggio, stesso
   bordo, stessa ombra. Le varianti cambiano la spaziatura o aggiungono un
   filetto, mai la forma. */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-l); padding: var(--s5) var(--s6);
  box-shadow: var(--shadow-s);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}

/* Sollevamento su hover: solo per le card che sono davvero un bersaglio —
   una scheda cliccabile, un portafoglio, un passo. Le card di sola lettura
   restano ferme, altrimenti la pagina intera reagisce al passaggio del mouse
   e il movimento smette di voler dire qualcosa. */
.contactcard:hover, .pf-voce:hover, .step-card:hover {
  border-color: var(--line-2);
  box-shadow: var(--shadow);
  transform: translateY(-2px);
}

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  font-family: var(--font-ui); font-size: 14px; font-weight: 500; line-height: 1.2;
  padding: 11px 20px; border-radius: var(--r-pill); border: 1px solid transparent;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background var(--dur-s) var(--ease), border-color var(--dur-s) var(--ease),
              color var(--dur-s) var(--ease), box-shadow var(--dur) var(--ease),
              transform var(--dur-s) var(--ease);
}
.btn:active { transform: translateY(1px); }
/* Il pulsante d'azione: l'uso più visibile del viola di BlissPoint, ed è
   voluto — è il posto in cui il colore deve dire «premi qui». */
.btn-primary { background: var(--accent); color: var(--on-accent); box-shadow: var(--shadow-accent); }
.btn-primary:hover { background: var(--accent-hover); color: var(--on-accent); }
.btn-primary:focus-visible { outline-color: var(--accent-hover); }
.btn-secondary { background: var(--surface); color: var(--ink); border-color: var(--line-2); }
.btn-secondary:hover { background: var(--brand-soft); color: var(--brand-ink); border-color: var(--brand-ink); }
.btn-ghost { background: transparent; color: var(--ink-2); padding-inline: 14px; }
.btn-ghost:hover { background: var(--surface-2); color: var(--ink); }
.btn-lg { font-size: 15px; padding: 14px 26px; }
.btn-sm { font-size: 13px; padding: 7px 14px; gap: 6px; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; box-shadow: none; }
.btn[disabled]:active { transform: none; }
/* UN PULSANTE NON ANCORA PRONTO NON È UN PULSANTE ROTTO.
   Il pulsante d'azione spento a metà opacità diventava un viola slavato su
   bianco: il testo scendeva sotto la soglia di leggibilità e la forma
   sembrava un errore di caricamento, proprio dov'è invece un'istruzione —
   «Scegli un titolo» è la frase che dice cosa manca per proseguire.
   Spento è una superficie neutra con il testo leggibile: si vede che è la
   fine del modulo e si legge cosa fare perché si accenda. */
.btn-primary[disabled], .btn-primary[aria-disabled="true"] {
  opacity: 1;
  background: var(--surface-2); color: var(--ink-3);
  border-color: var(--line-2); box-shadow: none;
}
.btn-block { width: 100%; }
/* Chiudere un account o cancellare un portafoglio non si annulla: il bottone
   lo dice, senza per questo nascondersi in fondo a un menu. */
.btn-danger { background: transparent; color: var(--neg); border-color: color-mix(in srgb, var(--neg) 45%, transparent); }
.btn-danger:hover { background: var(--neg); color: #fff; border-color: var(--neg); }

/* Occhiello e testa di sezione: la coppia che apre ogni blocco. */
.eyebrow {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-3); display: block; margin-bottom: 7px;
}
.sectionhead { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--s5); }
.sectionhead p { color: var(--ink-2); max-width: 68ch; font-size: 14.5px; }
/* Testa di sezione senza titolo visibile — resta la sola riga di conteggio,
   che è una didascalia e non un capitolo: meno stacco sotto. */
.sectionhead--conta { margin-bottom: var(--s4); }

/* ---- I TRE ATTI DELLA PAGINA DEI RISULTATI ----------------------------
   IL RISULTATO -> QUANTO VALE -> I DATI. Sono tre domande diverse, e prima
   si susseguivano con lo stesso stacco che separa due card qualunque: la
   pagina si leggeva come un elenco lungo di riquadri tutti uguali, in cui
   «salva questi titoli» pesava quanto il portafoglio ottimale.

   Il filetto e lo spazio in piu' dicono «si cambia discorso» senza bisogno di
   scriverlo, e costano una riga di stile invece di un titolo da tradurre in
   cinque lingue. */
.sectionhead--atto,
.card--atto {
  margin-top: var(--s4);
  padding-top: var(--s7);
  border-top: 1px solid var(--line);
}
/* La card che apre un atto porta gia' il suo bordo tutt'intorno: il filetto
   dell'atto le andrebbe a sovrapporre due righe a un pixel l'una dall'altra.
   Li' lo stacco lo fa il solo spazio. */
.card--atto { border-top-color: transparent; padding-top: var(--s5); margin-top: var(--s6); }

/* ---- LE CARD DI SERVIZIO SONO SFONDO, NON RISULTATO -------------------
   Quote titolo per titolo, salvataggio, provenienza dei dati: servono, ma
   nessuna delle tre e' cio' per cui si e' lanciato un calcolo. Stessa forma
   delle altre — il raggio e il bordo non cambiano mai — su superficie piu'
   tenue e senza ombra: si posano sul fondo invece di sollevarsi da esso. */
.card--quieta {
  background: var(--surface-quieta);
  box-shadow: none;
  border-color: color-mix(in srgb, var(--line) 70%, transparent);
}
/* Dentro una card tenue le tabelle e i riquadri tornano bianchi, altrimenti
   spariscono nel fondo su cui poggiano. */
.card--quieta .tablewrap,
.card--quieta .dq { background: var(--surface); }

/* Icone SVG (sostituiscono gli emoji). */
.ico {
  width: 40px; height: 40px; border-radius: var(--r-s); flex: none;
  display: grid; place-items: center; background: var(--brand-soft); color: var(--brand-ink);
}
.ico svg { width: 20px; height: 20px; stroke-width: 1.8; fill: none;
           stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }
.ico--min { background: color-mix(in srgb, var(--blue) 14%, transparent); color: var(--blue); }
.ico--opt { background: color-mix(in srgb, var(--coral) 14%, transparent); color: var(--coral); }
.ico--mio { background: color-mix(in srgb, var(--mio) 14%, transparent); color: var(--mio-ink); }
.ico--pos { background: var(--pos-soft); color: var(--pos); }

/* ---------- 6. FORM ----------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-size: 13.5px; font-weight: 500; color: var(--ink-2); }
/* ---- 16 PIXEL, E NON È UNA SCELTA DI GUSTO ---------------------------
   Safari su iPhone ingrandisce la pagina da solo quando si tocca un campo
   con il testo sotto i 16 px: la pagina salta, il resto esce dallo schermo, e
   quando si esce dal campo lo zoom RESTA. È un fastidio serio su un modulo
   fatto di venti caselle numeriche.

   Il rimedio scorretto sarebbe `user-scalable=no` nel viewport: toglie
   l'ingrandimento automatico e insieme quello che l'utente fa con le dita,
   cioè un requisito di accessibilità. Il rimedio giusto è quello qui sotto —
   16 px pieni su tutto ciò che si può toccare e scrivere. Il pizzico per
   ingrandire continua a funzionare, perché nel viewport non c'è nessun
   limite: vedi base.html. */
.input, select.input, textarea.input, input, select, textarea { font-size: 16px; }

.input {
  width: 100%; font-family: var(--font-ui); font-size: 16px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--r-s); padding: 12px 14px;
  transition: border-color var(--dur-s) var(--ease), box-shadow var(--dur-s) var(--ease);
}
.input::placeholder { color: var(--ink-3); }
.input:hover { border-color: color-mix(in srgb, var(--brand) 45%, var(--line-2)); }
.input:focus { outline: 0; border-color: var(--brand); box-shadow: 0 0 0 4px var(--ring); }
.input[aria-invalid="true"] { border-color: var(--neg); box-shadow: 0 0 0 4px color-mix(in srgb, var(--neg) 16%, transparent); }
.input-wrap { position: relative; display: flex; }
.input-wrap .input { padding-right: 48px; }
.reveal {
  position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
  background: none; border: 0; cursor: pointer; color: var(--ink-3);
  font-size: 12px; font-family: var(--font-mono); padding: 8px 10px; border-radius: var(--r-xs);
}
.reveal:hover { color: var(--brand-ink); background: var(--brand-soft); }
.field-error { font-size: 12.5px; color: var(--neg); min-height: 1em; }
/* DODICI PIXEL E MEZZO ERANO POCHI PER UNA RIGA CHE SPIEGA.
   Le note sotto i campi non sono decorazione: dicono cosa scrivere, cosa
   comporta un interruttore, perche' una data serve. A 12,5 px in `--ink-3`
   si leggevano come una didascalia da saltare, e su un telefono si saltavano
   davvero. 13 px e un'interlinea dichiarata: restano più piccole
   dell'etichetta sopra — la gerarchia non cambia — ma si leggono. */
.field-hint { font-size: 13px; line-height: 1.55; color: var(--ink-3); }
/* Il riquadro «non sono un robot» di Cloudflare. Ha misure sue e arriva
   dentro un iframe: qui si decide solo dove sta, non com'e' fatto. Lo spazio
   e' riservato anche prima che carichi, altrimenti la pagina fa un salto e il
   pulsante «Crea account» si sposta sotto il dito di chi stava per premerlo. */
.turnstile { min-height: 65px; }

/* IL CAMPO TRAPPOLA: fuori dallo schermo, mai `display:none`.
   `display:none` e `visibility:hidden` sono le due righe che un programma
   scritto bene controlla prima di compilare un campo — trovarle vorrebbe dire
   saltarlo, cioe' disattivare la trappola. Spostato fuori dalla pagina invece
   resta un campo a tutti gli effetti per chi legge il codice, e non esiste per
   chi guarda lo schermo.
   `position: fixed` e non `absolute`: `absolute` si ancora al primo antenato
   posizionato, e se un giorno il modulo ne guadagnasse uno il campo potrebbe
   riaffiorare dentro la scheda. `fixed` guarda solo la finestra.
   Nessun `width: 0`: un campo largo zero e' un altro indizio riconoscibile.
   A tenerlo lontano da chi non vede ci pensano `aria-hidden` e
   `tabindex="-1"` nel modello, non questo foglio di stile. */
.trappola {
  position: fixed;
  left: -9999px;
  top: -9999px;
  opacity: 0;
}
/* La stampa impagina anche cio' che sta fuori dallo schermo. */
@media print { .trappola { display: none; } }

/* Registrazione a blocchi e caselle di consenso: un modulo lungo tutto uguale
   sembra un interrogatorio, a gruppi si legge come tre domande. */
.gruppo { border: 0; padding: 0; margin: 0; display: flex; flex-direction: column;
          gap: var(--s4); }
/* Il filetto che separa i gruppi sta sulla <legend>, non sul <fieldset>: il
   browser disegna la legenda SOPRA il bordo superiore del fieldset, e la riga
   finiva per passare in mezzo alle lettere. Sulla legenda il filetto le sta
   sopra, con il suo respiro, ed è lì che deve stare. */
.gruppo + .gruppo { margin-top: var(--s5); }
.gruppo legend { font-size: 11px; letter-spacing: .13em; text-transform: uppercase;
                 color: var(--ink-3); font-family: var(--font-mono);
                 padding: 0; margin-bottom: var(--s3); width: 100%; }
.gruppo + .gruppo legend { border-top: 1px solid var(--line); padding-top: var(--s5); }
.duecolonne { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); }

/* Casella e testo allineati in alto: con due righe di testo il quadratino
   restava centrato a mezz'aria. L'area cliccabile è tutta l'etichetta. */
.spunta { display: grid; grid-template-columns: auto 1fr; gap: var(--s3);
          align-items: start; cursor: pointer; font-size: 14px; line-height: 1.5; }
.spunta input { margin-top: 3px; width: 17px; height: 17px; accent-color: var(--brand);
                flex: none; cursor: pointer; }
.spunta a { text-decoration: underline; }

/* Profilo: scheda, registro dei consensi. */
.scheda { display: grid; gap: 0; margin: 0; }
.scheda > div { display: grid; grid-template-columns: 220px 1fr; gap: var(--s4);
                padding: var(--s3) 0; border-bottom: 1px solid var(--line); }
.scheda > div:last-child { border-bottom: 0; }
.scheda dt { font-size: 13.5px; color: var(--ink-3); }
.scheda dd { margin: 0; font-size: 14.5px; color: var(--ink); }

.registro { list-style: none; margin: 0; padding: 0;
            display: flex; flex-direction: column; }
.registro li { display: grid; grid-template-columns: 1fr auto; gap: 4px var(--s4);
               padding: var(--s3) 0; border-bottom: 1px solid var(--line); }
.registro li:last-child { border-bottom: 0; }
.registro-cosa { font-size: 14px; font-weight: 500; }
.registro-stato { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em;
                  text-transform: uppercase; padding: 3px 9px; border-radius: var(--r-pill);
                  justify-self: end; align-self: start; }
.stato--dato { background: var(--pos-soft); color: var(--pos); }
.stato--revocato { background: var(--surface-2); color: var(--ink-3); }
.registro-quando { grid-column: 1 / -1; font-family: var(--font-mono);
                   font-size: 12px; color: var(--ink-3); }

/* ---------- 7. OTTIMIZZATORE -------------------------------------------- */
.tickerbox {
  display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center;
  background: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--r); padding: 12px 13px; min-height: 60px;
  transition: border-color var(--dur-s) var(--ease), box-shadow var(--dur-s) var(--ease);
}
.tickerbox:hover { border-color: color-mix(in srgb, var(--brand) 45%, var(--line-2)); }
.tickerbox:focus-within { border-color: var(--brand); box-shadow: 0 0 0 4px var(--ring); }

.chip {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-pill); padding: 5px 6px 5px 12px;
  font-family: var(--font-mono); font-size: 12.5px; letter-spacing: .02em; color: var(--ink);
  transition: border-color var(--dur-s) var(--ease), background var(--dur-s) var(--ease);
}
.chip:hover { border-color: var(--line-2); }
.chip button {
  border: 0; background: transparent; color: var(--ink-3); cursor: pointer;
  font-size: 15px; line-height: 1; padding: 3px 6px; border-radius: 50%;
  transition: background var(--dur-s) var(--ease), color var(--dur-s) var(--ease);
}
.chip button:hover { background: var(--neg-soft); color: var(--neg); }
/* Le chip mostrano il nome; il simbolo resta un dettaglio secondario. */
.chip--titolo { padding-left: 12px; }
.chip-nome { font-family: var(--font-ui); font-size: 13px; color: var(--ink); }
.chip-sim {
  font-family: var(--font-mono); font-size: 11px; color: var(--ink-3);
  padding-left: 8px; margin-left: 1px; border-left: 1px solid var(--line-2);
}
/* Un titolo che entra e uno che esce si vedono: è l'unico modo per essere
   sicuri che il clic sia arrivato. Le classi le mette lo script. */
.chip.is-new { animation: chip-entra .26s var(--ease) both; }
.chip.is-out { animation: chip-esce .16s var(--ease) both; }

.chip-campo { position: relative; flex: 1; min-width: 220px; display: block; }
.chip-input {
  width: 100%; border: 0; outline: 0; background: transparent;
  color: var(--ink); font-family: var(--font-ui); font-size: 16px; padding: 7px 4px;
}
.chip-input::placeholder { font-family: var(--font-ui); color: var(--ink-3); }

.tickermeta {
  display: flex; justify-content: space-between; gap: var(--s4);
  flex-wrap: wrap; margin-top: var(--s2); font-size: 12.5px; color: var(--ink-3);
}
/* La riga che dice cosa scrivere e quella che conta i titoli sono due note
   dello stesso campo, e vanno lette come una coppia: appaiate stretto sotto
   la casella invece che a passo pieno, dove sembravano due paragrafi
   indipendenti sospesi fra un campo e l'altro. Il margine negativo toglie
   quattro pixel al passo del contenitore, qualunque dei due sia — nel modulo
   e dentro un `.field` il passo e' diverso, la coppia si stringe uguale. */
.campo-aiuto + .tickermeta { margin-top: calc(var(--s1) * -1); }
.tickermeta .is-pulse { display: inline-block; animation: pulsa .4s var(--ease); }
/* «Cancella tutti»: un comando, non un bottone. Sta accanto al conto dei
   titoli, ha il peso di un collegamento e prende il colore d'allarme solo
   quando ci si passa sopra — cancellare ottanta titoli e' un gesto che non
   deve invitare, ma nemmeno nascondersi. */
.link-azione {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: var(--ink-3); text-decoration: underline;
  text-underline-offset: 3px; transition: color var(--dur) var(--ease);
}
.link-azione:hover, .link-azione:focus-visible { color: var(--neg); }
.link-azione[hidden] { display: none; }

.suggerimenti {
  position: absolute; left: -6px; right: -6px; top: calc(100% + 12px);
  z-index: 40; margin: 0; padding: var(--s1); list-style: none;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--shadow-m);
  max-height: 340px; overflow-y: auto;
  animation: cala var(--dur) var(--ease) both;
}
.suggerimenti[hidden] { display: none; }
.sugg {
  display: flex; flex-direction: column; gap: 2px; cursor: pointer;
  padding: 9px 13px; border-radius: var(--r-s);
}
.sugg:hover, .sugg.is-on { background: var(--brand-soft); }
.sugg-nome { font-size: 14px; color: var(--ink); line-height: 1.35; }
.sugg-nome mark { background: none; color: var(--brand-ink); font-weight: 600; }
.sugg-meta {
  font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3);
  letter-spacing: .02em;
}

/* Confronto con un altro portafoglio: un interruttore e, quando è acceso,
   due strade fra cui sceglierne una. Ad aprire e chiudere è il CSS, non lo
   script: `:has()` legge lo stato della casella, quindi il blocco è già nella
   forma giusta al primo disegno — nessun lampo di contenuto. */
/* I tre interruttori facoltativi — carica un portafoglio, aggiungi un
   vincolo, confronta — come un gruppo solo, alla stessa distanza l'uno
   dall'altro. Prima ognuno si teneva il suo margine e il confronto per giunta
   una riga orizzontale sopra: tre distanze diverse e un taglio in mezzo che
   sembrava la fine del modulo, con il tasto «calcola» al di là. */
/* L'intestazione del gruppo: un filetto e una parola, esattamente la forma
   delle legende del modulo di registrazione (`.gruppo legend`). Il modulo
   dell'ottimizzatore e quello dell'iscrizione sono i due moduli lunghi del
   sito: farli leggere allo stesso modo è metà del lavoro. */
.opzioni-testa {
  margin-top: var(--s5); padding-top: var(--s4);
  border-top: 1px solid var(--line);
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--ink-3);
}

/* GLI INTERRUTTORI USANO LA LARGHEZZA CHE HANNO.
   Erano tre righe corte incolonnate a sinistra dentro una card larga
   1.100 px: sotto il campo dei titoli, che la larghezza la prende tutta,
   restavano due terzi di card vuoti e la parte bassa del modulo sembrava
   non finita. Affiancati riempiono la riga e, soprattutto, si vedono tutti
   e tre in un colpo d'occhio invece di uno sotto l'altro.
   Quello che si accende passa a riga intera: il suo corpo — la tabella dei
   pesi minimi, il campo dei titoli del confronto — ha bisogno di tutta la
   larghezza, e stretto in una colonna su tre sarebbe illeggibile. */
/* GLI INTERRUTTORI SPENTI NON HANNO UNA CORNICE, E NON DEVONO AVERLA.
   Per un giro l'hanno avuta: un bordo e una superficie per casella, cosi'
   che una riga incompleta — quattro interruttori su una griglia da tre —
   leggesse come una piastrella in meno invece che come un allineamento
   rotto. Su schermo largo funzionava; su un telefono, dove la griglia e' a
   una colonna sola, diventava una pila di sei scatole vuote alte uguali, e
   il modulo sembrava piu' pesante di quello che chiede. La cornice torna a
   essere quello che era: il segno che dice «questo interruttore e' acceso e
   qui sotto c'e' il suo corpo», e vale per uno solo per volta. */
.opzioni {
  display: grid; gap: var(--s4) var(--s5);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  align-items: start;
  margin-top: var(--s2);
}
/* TRE PER RIGA SULLO SCHERMO LARGO, NON «QUANTI CE NE STANNO».
   Gli interruttori facoltativi sono sei. Con `auto-fit` il numero di colonne
   lo decideva la larghezza della finestra: quattro e due su un monitor
   grande, cinque e uno su un altro — una riga piena e una monca, che legge
   come se l'ultimo interruttore fosse rimasto fuori dal gruppo. Tre e tre
   sono due righe uguali, e il gruppo si vede come un gruppo. */
@media (min-width: 900px) {
  .opzioni { grid-template-columns: repeat(3, 1fr); }
}
/* Acceso: riga intera e, soprattutto, un riquadro tutto suo. Con tre
   interruttori aperti uno sotto l'altro — tendina, tabella dei vincoli,
   secondo campo dei titoli — non si capiva piu' dove finisse uno e
   cominciasse l'altro: erano tre corpi allo stesso indento sotto tre
   etichette uguali. La superficie tenue e' quella che il foglio usa gia'
   per le parti di servizio dentro una card bianca. */
.opzioni > :has(.switch-input:checked) {
  grid-column: 1 / -1;
  background: var(--surface-quieta);
  border: 1px solid var(--line);
  border-radius: var(--r-s);
  padding: var(--s4);
}
/* Sotto i 720 px le colonne sono una sola: due interruttori affiancati su un
   telefono darebbero due etichette spezzate su tre righe ciascuna. */
@media (max-width: 720px) {
  .opzioni { grid-template-columns: 1fr; }
}

/* La riga che chiude il modulo. Il filetto dice «le domande sono finite»:
   sotto c'è solo il pulsante. */
.row--azione {
  margin-top: var(--s4); padding-top: var(--s5);
  border-top: 1px solid var(--line);
}
/* Sul telefono il pulsante che chiude il modulo prende tutta la riga: è
   l'unica cosa da premere in quel punto, e a mezza larghezza costringe il
   pollice a cercarla.
   `.row.row--azione` e non `.row--azione`: sotto i 420 px la sezione
   responsive dichiara `.row > .btn-lg { width: auto }` per impedire che ogni
   azione piccola dentro una riga diventi una barra. Quella regola pesa quanto
   questa e viene dopo nel foglio, quindi vincerebbe: qui la classe in piu'
   dice che questa riga e' un caso a parte, ed e' vero — contiene un pulsante
   solo, che e' la fine del modulo. */
@media (max-width: 560px) {
  .row.row--azione { display: block; }
  .row.row--azione .btn { width: 100%; }
}

.switch { position: relative; display: inline-flex; align-items: center;
          gap: var(--s3); cursor: pointer; }
.switch-input { position: absolute; top: 0; left: 0; width: 1px; height: 1px;
                opacity: 0; margin: 0; }
.switch-pista {
  position: relative; flex: none; width: 42px; height: 24px; border-radius: var(--r-pill);
  background: var(--surface-3); border: 1px solid var(--line-2);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.switch-perno {
  position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
  border-radius: 50%; background: var(--surface); box-shadow: var(--shadow-s);
  transition: transform var(--dur) var(--ease);
}
/* Acceso: blu del marchio. Il viola è riservato a cinque punti (vedi
   l'intestazione del file) e un interruttore di opzione non è uno di quelli:
   accendere il confronto è una scelta di percorso, non l'azione principale
   della pagina. */
.switch-input:checked + .switch-pista { background: var(--brand); border-color: var(--brand); }
.switch-input:checked + .switch-pista .switch-perno { transform: translateX(18px); }
.switch-input:focus-visible + .switch-pista { box-shadow: 0 0 0 4px var(--ring); }
.switch-testo { font-size: 14px; font-weight: 500; color: var(--ink); }

/* Parti da un portafoglio salvato: stesso interruttore del confronto, stesso
   modo di aprirsi. Sono due domande gemelle poste nello stesso modulo, e
   farle sembrare due cose diverse sarebbe stato peggio che ripetersi. */
.caricapf-corpo { display: none; }
.caricapf:has(.switch-input:checked) .caricapf-corpo {
  display: flex; flex-direction: column; gap: var(--s3); margin-top: var(--s4);
  animation: apri var(--dur-l) var(--ease) both;
}
/* Vuoto finche' non si carica niente: senza questo la riga occuperebbe spazio
   da subito e il blocco si muoverebbe sotto le dita al primo caricamento. */
.caricapf-esito:empty { display: none; }
.caricapf-esito { font-size: 13px; color: var(--pos); margin: 0; }

/* Pesi minimi imposti a singoli titoli: terzo interruttore dello stesso
   modulo, quindi terza volta lo stesso gesto. Chiuso di suo — quasi nessuna
   analisi ha bisogno di vincoli, e una tabella sempre aperta sarebbe una
   domanda in più per chi voleva solo premere «calcola». */
.minimi-corpo { display: none; }
.minimi:has(.switch-input:checked) .minimi-corpo {
  display: flex; flex-direction: column; gap: var(--s3); margin-top: var(--s4);
  animation: apri var(--dur-l) var(--ease) both;
}
.minimi-righe, .gruppi-righe { display: flex; flex-direction: column; gap: var(--s3); }
.minimi-righe:empty, .gruppi-righe:empty { display: none; }

/* ---- I MINIMI PER CATEGORIA ----------------------------------------------
   Stessa riga dei minimi per titolo — categoria, percentuale, croce — dentro
   lo stesso blocco, separata da un filetto e da una riga di titolo: sono due
   modi di dire la stessa cosa a due livelli diversi, non due funzioni. */
.gruppi { margin-top: var(--s5); padding-top: var(--s4);
          border-top: 1px dashed var(--line); }
.gruppi-riga {
  display: grid; gap: var(--s2) var(--s3); align-items: end;
  grid-template-columns: minmax(10rem, 26rem) 8.5rem auto minmax(0, 1fr);
}
.gruppi-riga label { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.gruppi-riga:not(:first-child) .minimi-eti {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.gruppi-scelta { text-overflow: ellipsis; }
.gruppi-avviso { margin-top: var(--s2); }

/* Titolo, percentuale, croce: la riga si legge da sinistra a destra come si
   legge la frase «Apple almeno 10%». La tendina è larga perché dentro ci sta
   un nome intero — «iShares € Corp Bond BBB-BB UCITS ETF EUR (Dist)» — non un
   simbolo di quattro lettere; ma non prende tutta la pagina: l'ultima colonna
   è vuota apposta, ed è lei che si prende lo spazio che avanza. */
.minimi-riga {
  display: grid; gap: var(--s2) var(--s3); align-items: end;
  grid-template-columns: minmax(10rem, 26rem) 8.5rem auto minmax(0, 1fr);
}
/* Il nome che non ci sta si taglia con i puntini invece di allargare la
   tendina oltre la sua colonna. */
.minimi-scelta { text-overflow: ellipsis; }
.minimi-riga label {
  display: flex; flex-direction: column; gap: 6px; min-width: 0;
}
/* `.minimi-eti` e non `label > span`: dentro l'etichetta della percentuale
   c'è un secondo span — il guscio che porta il segno «%» — e prenderli tutti
   e due voleva dire nascondere il campo insieme alla sua didascalia. */
.minimi-eti {
  font-size: 12px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
}
/* Le intestazioni si scrivono una volta sola, sulla prima riga: ripetere
   «TITOLO / ALMENO» sopra ogni coppia di campi trasforma tre vincoli in sei
   etichette da rileggere. Restano però nel documento per chi naviga a voce,
   dove ogni campo va nominato per conto suo. */
.minimi-riga:not(:first-child) .minimi-eti {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* Il segno di percentuale dentro il campo, non accanto: così è chiaro che
   «10» vuol dire dieci per cento e non dieci euro. Le frecce native del campo
   numerico se ne vanno: comparivano solo al passaggio del mouse e finivano
   addosso al segno. Minimo, massimo e passo restano, e valgono comunque. */
.minimi-quota { position: relative; display: block; }
.minimi-quota .input { width: 100%; padding-right: 2.1rem; }
.minimi-quota .input::-webkit-outer-spin-button,
.minimi-quota .input::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
.minimi-quota .input { -moz-appearance: textfield; appearance: textfield; }
.minimi-quota i {
  position: absolute; right: .75rem; top: 50%; transform: translateY(-50%);
  font-style: normal; font-size: 13px; color: var(--muted); pointer-events: none;
}
.minimi-togli {
  padding: 0; width: 2.4rem; height: 2.4rem; line-height: 1;
  font-size: 20px; color: var(--muted); flex: none;
}
.minimi-togli:hover { color: var(--neg); }
.minimi-nota[hidden] { display: none; }
.minimi-nota { margin: 0; }
#minimi-aggiungi, #gruppi-aggiungi { align-self: flex-start; }
#minimi-aggiungi[disabled], #gruppi-aggiungi[disabled] { opacity: .5; cursor: not-allowed; }
.gruppi-togli { padding: 0; width: 2.4rem; height: 2.4rem; line-height: 1;
                font-size: 20px; color: var(--muted); flex: none; }
.gruppi-togli:hover { color: var(--neg); }

@media (max-width: 560px) {
  /* Su un telefono la tendina prende tutta la riga, e percentuale e croce
     vanno sotto. Stretta accanto agli altri campi mostrava «Microsoft Co…»:
     il nome del titolo è tutto il motivo per cui c'è una tendina invece di un
     simbolo, e tagliato a metà non serve a niente. */
  .minimi-riga, .gruppi-riga { grid-template-columns: minmax(0, 1fr) auto; }
  .minimi-riga label:first-child, .gruppi-riga label:first-child { grid-column: 1 / -1; }
  .minimi-riga label:nth-child(2), .gruppi-riga label:nth-child(2) { grid-column: 1; max-width: 9rem; }
  .minimi-togli, .gruppi-togli { grid-column: 2; justify-self: end; }
  /* Due righe alte il doppio hanno bisogno di un confine: senza, la
     percentuale di sopra sembra appartenere al titolo di sotto. */
  .minimi-riga:not(:last-child), .gruppi-riga:not(:last-child) {
    border-bottom: 1px solid var(--line); padding-bottom: var(--s3);
  }
}

/* I vincoli dichiarati accanto ai risultati. Riquadro tranquillo, non un
   avviso: non è successo niente di anomalo — è l'utente che ha chiesto
   questo, e qui lo ritrova verificato. */
.vincoli {
  border: 1px solid var(--line); border-radius: var(--r-s);
  background: var(--surface-quieta); padding: var(--s4); margin-top: var(--s4);
}
.vincoli > b { display: block; font-size: 14px; margin-bottom: var(--s3); }
.vincoli ul { list-style: none; margin: 0; padding: 0; display: flex;
  flex-direction: column; gap: 6px; }
.vincoli li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px var(--s3);
  font-size: 14px;
}
.vincoli li > span { font-weight: 600; color: var(--ink); }
.vincoli li > em { font-style: normal; color: var(--muted); }
/* Il riquadro e' l'elenco e basta: i pesi usciti nei due portafogli, la
   parola «rispettato» e il paragrafo che spiegava cosa sia un vincolo sono
   stati tolti — chi ha appena scritto quei vincoli lo sa gia'. Restano il
   nome e la quota, che sono le due cose che aveva chiesto. */

/* LA RIGA DEL CAMBIO SI VEDE SOLO QUANDO L'INTERRUTTORE E' ACCESO.
   Spiega la conseguenza di aver ESCLUSO il rischio di cambio, quindi a
   interruttore spento parlerebbe di una cosa che non sta succedendo — una
   riga sempre presente che non riguarda nessuno. `:has()` sul contenitore:
   niente JavaScript, come per gli altri interruttori del modulo. */
.cambio-nota { display: none; }
.cambio:has(.switch-input:checked) .cambio-nota {
  display: block; margin-top: var(--s2);
}

/* SALVA QUESTA SELEZIONE: ancora lo stesso interruttore, ancora lo stesso
   modo di aprirsi. È l'ultimo del modulo e chiede la sola cosa che serve —
   un nome — perché tutto il resto lo ha già detto chi ha compilato sopra.
   L'esito resta lì sotto dopo il calcolo: verde quando la selezione è finita
   fra i portafogli salvati, rosso quando non ci è potuta entrare. */
.salvasel-corpo { display: none; }
.salvasel:has(.switch-input:checked) .salvasel-corpo {
  display: flex; flex-direction: column; gap: var(--s3); margin-top: var(--s4);
  animation: apri var(--dur-l) var(--ease) both;
}
.salvasel-esito { font-size: 13px; color: var(--pos); margin: var(--s3) 0 0; }
.salvasel-esito.is-errore { color: var(--neg); }

.confronta-corpo { display: none; }
.confronta:has(.switch-input:checked) .confronta-corpo {
  display: flex; flex-direction: column; gap: var(--s4); margin-top: var(--s4);
  animation: apri var(--dur-l) var(--ease) both;
}
/* Una strada per volta. Senza portafogli salvati non c'è nessun segmentato:
   nessuna delle regole scatta e resta aperta la sola strada esistente.

   Scritte come «nascondi tutte tranne la sua» e non come un elenco di coppie:
   con due modi le coppie erano due, con tre sarebbero sei, e con quattro
   dodici. Così ogni modo nuovo è una riga, non una tabellina. */
.confronta:has(input[name="confronta_modo"][value="salvato"]:checked) .confronta-strada:not([data-modo="salvato"]),
.confronta:has(input[name="confronta_modo"][value="nuovo"]:checked) .confronta-strada:not([data-modo="nuovo"]),
.confronta:has(input[name="confronta_modo"][value="due_salvati"]:checked) .confronta-strada:not([data-modo="due_salvati"]) {
  display: none;
}

/* Le due tendine del confronto fra portafogli salvati: affiancate, perché
   sono i due termini della stessa domanda e leggerle in colonna farebbe
   sembrare la seconda un ripensamento. Sotto i 560 px vanno in fila. */
.confronta-due-campi {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4);
}
@media (max-width: 560px) {
  .confronta-due-campi { grid-template-columns: 1fr; }
}

/* La valuta è una scelta corta: il campo non deve prendersi tutta la riga
   come fa quello dei titoli, o sembrerebbe altrettanto importante. */
.valuta-base select { max-width: 22rem; }
/* Uno stacco piu' largo di quello fra le righe del modulo: il conto dei
   titoli e «come funziona la ricerca» appartengono al campo qui sopra, la
   valuta e' la domanda dopo. Con tutte le distanze uguali i quattro pezzi si
   leggevano come quattro campi alla pari.
   Da 12 a 20 px: con due righe di nota sotto il campo dei titoli — il conto e
   l'istruzione di ricerca — dodici pixel non bastavano a far vedere che la
   seconda domanda cominciava li'. La regola resta la stessa: dentro una
   domanda le distanze sono quelle del modulo, fra una domanda e l'altra sono
   piu' larghe. */
.valuta-base { margin-top: var(--s5); }

.segmentato {
  display: inline-flex; align-self: flex-start; flex-wrap: wrap; gap: 3px;
  padding: 3px; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--r-pill);
}
.segmento { position: relative; display: block; }
.segmento input { position: absolute; inset: 0; width: 100%; height: 100%;
                  margin: 0; opacity: 0; cursor: pointer; }
.segmento span {
  display: block; padding: 7px 16px; border-radius: var(--r-pill);
  font-size: 13px; color: var(--ink-2);
  transition: background var(--dur-s) var(--ease), color var(--dur-s) var(--ease);
}
.segmento input:checked + span {
  background: var(--surface); color: var(--accent-ink); font-weight: 500;
  box-shadow: var(--shadow-s);
}
.segmento input:focus-visible + span { outline: 2px solid var(--brand); outline-offset: 1px; }

/* ---------- 8. RISULTATI ------------------------------------------------ */
/* ---- I DUE PORTAFOGLI, CON UNA GERARCHIA ------------------------------
   Erano due colonne uguali (`auto-fit, minmax(300px, 1fr)`), e due cose
   uguali si leggono come alternative pari: chi arriva qui non sa da quale
   cominciare. La domanda che lo ha portato fin qui e' pero' «qual e' il
   portafoglio migliore», e la risposta e' il tangente.

   Due terzi contro un terzo. Il rischio minimo resta leggibile per intero,
   con gli stessi dati: non contende la scena, e basta. Sotto i 900 px
   tornano in colonna, l'ottimale sempre per primo. */
/* LE CARD AFFIANCATE SONO ALTE UGUALE.
   Con `align-items: start` ognuna era alta quanto il suo contenuto, e la
   frase di presentazione dell'ottimale — più lunga di quella del rischio
   minimo, e per giunta in una colonna più larga — bastava a farle finire su
   due altezze diverse. Due riquadri affiancati e disallineati leggono come
   se al secondo mancasse qualcosa. Larghezze diverse sì, è la gerarchia;
   altezze diverse no. */
.risultato-hero {
  display: grid; gap: var(--s5); align-items: stretch;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
}
@media (max-width: 900px) { .risultato-hero { grid-template-columns: 1fr; } }
/* Con un titolo solo la card e' una sola e prende tutta la riga: non c'e' una
   seconda cosa da affiancarle. */
.risultato-hero--sola { grid-template-columns: 1fr; }
/* CON TRE CARD LA GRIGLIA CAMBIA FORMA E CAMBIA CHI COMANDA.
   Due colonne da due terzi e un terzo con dentro tre riquadri lascerebbero il
   terzo sotto il primo e un buco a destra grande quanto una card. Quando c'è
   anche il portafoglio dichiarato, la riga di sopra la prende per intero
   QUELLO — e' la card `kpi--principale`, vedi `_risultati.html` — perche' chi
   ha scritto cosa possiede e' venuto a vedere prima il suo; sotto ci stanno
   appaiati l'ottimale e il rischio minimo, che sono i due termini di paragone
   e fra loro hanno lo stesso peso. Senza portafoglio dichiarato non cambia
   niente: due colonne, l'ottimale primo e piu' largo. */
.risultato-hero:has(.kpi--mio) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.risultato-hero:has(.kpi--mio) .kpi--principale { grid-column: 1 / -1; }
@media (max-width: 900px) {
  .risultato-hero:has(.kpi--mio) { grid-template-columns: 1fr; }
}
/* Niente filetto colorato sulla scheda: il colore in cima alle due card serve
   a distinguerle fra loro, e qui non c'e' niente da distinguere. */
.kpi--scheda::before { background: var(--brand); }

/* ---- LA SCHEDA DI UN TITOLO: DRAWDOWN, ANNI, CUMULATO -----------------
   Tre riquadri in fila, stessa forma dei riquadri gia' usati altrove nel
   sito. Ognuno porta il numero grande, l'etichetta e una frase che dice
   perche' quel numero conta: sono misure che la maggior parte di chi legge
   non incontra tutti i giorni, e un numero senza spiegazione qui non
   servirebbe a niente. */
.scheda-serie {
  display: grid; gap: var(--s4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
}
.scheda-voce {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-l); padding: var(--s5);
  display: flex; flex-direction: column; gap: 3px;
}
.scheda-num {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: clamp(24px, 3vw, 32px); letter-spacing: -.035em; line-height: 1;
  color: var(--ink);
}
.scheda-num i { font-style: normal; font-size: .58em; margin-left: 1px; color: var(--ink-3); }
.scheda-num.is-pos { color: var(--pos); }
.scheda-num.is-neg { color: var(--neg); }
.scheda-eti { font-size: 11px; color: var(--ink-3); line-height: 1.3; }
.scheda-voce p {
  font-size: 12.5px; color: var(--ink-2); line-height: 1.5; margin-top: var(--s3);
}
/* Anno migliore e peggiore stanno nello stesso riquadro: sono la stessa
   domanda posta ai due estremi, e separarli avrebbe voluto dire due riquadri
   che si leggono solo insieme. */
.scheda-anni { display: flex; align-items: baseline; gap: var(--s2); }
.scheda-anni b {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: 20px; letter-spacing: -.03em;
}
.scheda-anni b.is-pos { color: var(--pos); }
.scheda-anni b.is-neg { color: var(--neg); }
.scheda-anni i { font-style: normal; font-size: 12.5px; color: var(--ink-3); }
.scheda-voce .scheda-anni + .scheda-eti { margin-bottom: var(--s3); }

/* L'invito ad aggiungere un secondo titolo: e' il motivo per cui la scheda
   esiste, quindi non e' una nota a pie' di pagina. Riquadro chiaro con il
   filetto del marchio a sinistra, come gli altri richiami del sito. */
.scheda-invito {
  border-left: 3px solid var(--brand); background: var(--brand-soft);
  padding: var(--s4) var(--s5); border-radius: 0 var(--r-s) var(--r-s) 0;
  font-size: 14px; color: var(--ink-2); line-height: 1.55; max-width: 74ch;
}
.kpi { position: relative; overflow: hidden; display: flex; flex-direction: column; }
/* La card principale respira di piu' e si stacca dal fondo: piu' spazio
   dentro, ombra piu' profonda, filetto in cima piu' spesso. Sono tre segnali
   piccoli che insieme fanno una gerarchia evidente senza colorare niente. */
.kpi--principale { padding: var(--s6); box-shadow: var(--shadow-m); }
.kpi--principale::before { height: 5px; }
.kpi--secondario { background: var(--surface); }
/* Il filetto di colore non è più una barra a sinistra ma una riga sottile in
   cima, larga quanto la card: si legge come intestazione, non come cicatrice. */
.kpi::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px;
               background: var(--line-2); }
.kpi--min::before { background: var(--blue); }
.kpi--opt::before { background: var(--coral); }
/* La card del portafoglio dichiarato porta il verde in cima come le
   altre due portano il loro colore, e in piu' un fondo appena tinto:
   e' l'unica delle tre che parla di chi sta leggendo. */
.kpi--mio::before { background: var(--mio); }
.kpi--mio { background: var(--mio-soft); }
.kpi-head { display: flex; align-items: center; gap: var(--s3); margin-bottom: var(--s5); }
.kpi-head b { font-size: 15px; letter-spacing: -.008em; flex: 1; }
.kpi-badge {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .07em;
  text-transform: uppercase; padding: 4px 9px; border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--ink-3); white-space: nowrap;
}
/* ---- IL TRITTICO: RENDIMENTO, RISCHIO, SHARPE -------------------------
   Il numero grande era lo Sharpe da solo; rendimento e rischio stavano sotto
   in corpo 13, in mezzo alle tre righe del VaR. Ma uno Sharpe di 1,2 non si
   legge senza gli altri due: puo' venire da un 8% con poca oscillazione o da
   un 30% con molta, e sono due portafogli diversissimi.

   I tre stanno quindi in fila, stessa dimensione, etichetta sotto. Le cifre
   sono monospaziate e tabulari: incolonnate fra le due card si confrontano a
   colpo d'occhio. */
.metriche {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s3); align-items: start;
}
.metrica { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.metrica-num {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  letter-spacing: -.035em; line-height: 1; color: var(--ink);
  font-size: clamp(21px, 2.5vw, 30px);
}
/* Il simbolo di percentuale non e' il numero: piu' piccolo e piu' chiaro,
   cosi' l'occhio prende la cifra e non l'unita'. */
.metrica-num i { font-style: normal; font-size: .58em; margin-left: 1px; color: var(--ink-3); }
.metrica-eti { font-size: 11px; color: var(--ink-3); line-height: 1.3; }
/* La card principale porta i numeri piu' grandi: e' l'ultimo dei tre segnali
   di gerarchia, e il piu' immediato. */
.kpi--principale .metrica-num { font-size: clamp(26px, 3.4vw, 40px); }
/* Il livello dello Sharpe scende sotto la sua etichetta invece di stare di
   fianco al numero: di fianco allargava la colonna e rompeva le tre parti
   uguali. */
.metrica--sharpe .livello { margin-top: 5px; align-self: start; font-size: 11.5px; padding: 3px 10px; }
/* LA FRASE SOTTO LO SHARPE È STATA TOLTA (vedi `_risultati.html`), E CON LEI
   IL SUO MESTIERE SECONDARIO.
   Era anche il cuscinetto — `flex: 1 1 0` — che assorbiva la differenza di
   altezza fra le card e teneva la riga del VaR alla stessa quota in tutte e
   tre. Adesso quel compito ce l'ha la riga del VaR, che si spinge da sola in
   fondo alla card: stesso risultato, senza un paragrafo che esiste per
   riempire. Vedi `.kpi-var` più sotto. */

/* La pillola del livello — negativo, basso, moderato, buono, molto alto.
   Stessi colori della scala dei voti: rosso, giallo, verde, viola in cima. */
.livello {
  display: inline-flex; align-items: center; white-space: nowrap;
  font-size: 12.5px; font-weight: 600; letter-spacing: -.002em;
  padding: 5px 13px; border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--ink-2);
}
.livello--verylow, .livello--low { background: var(--neg-soft); color: var(--neg); }
.livello--medium { background: var(--warn-soft); color: var(--warn); }
.livello--good { background: var(--pos-soft); color: var(--pos); }
.livello--high { background: var(--accent-soft); color: var(--accent-ink); }
/* ---- IL VaR, UNA RIGA INVECE DI TRE ----------------------------------
   I tre livelli restano tutti e tre, ma in fila: impilati pesavano quanto i
   numeri principali senza esserlo, e occupavano meta' dell'altezza della
   card. Qui si leggono come una nota a pie' di card, che e' il loro rango. */
.kpi-var {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--s2) var(--s4);
  /* `auto` e non una distanza fissa: è questa riga a spingersi in fondo alla
     card e ad assorbire la differenza di altezza fra le tre, così i VaR
     restano allineati e si leggono in orizzontale. Prima lo faceva il
     paragrafo sotto lo Sharpe, che non c'è più. `padding-top` tiene comunque
     l'aria minima quando la card è piena. */
  margin-top: auto; padding-top: var(--s5); border-top: 1px solid var(--line);
}
.kpi-var-eti { font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
               color: var(--ink-3); }
.kpi-var-v { display: inline-flex; align-items: baseline; gap: 5px; }
.kpi-var-v i { font-style: normal; font-size: 11px; color: var(--ink-3); }
.kpi-var-v em {
  font-style: normal; font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: 13px; color: var(--ink);
}
.kpi-var-v em.is-neg { color: var(--neg); }
.kpi-var-v em.muted { color: var(--ink-3); }

.kpi-rows { margin-top: var(--s5); padding-top: var(--s4); border-top: 1px solid var(--line);
            display: flex; flex-direction: column; gap: 10px; }
.kpi-row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3); font-size: 13px; }
.kpi-row span { color: var(--ink-2); }
.kpi-row em {
  font-style: normal; font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: 13.5px; color: var(--ink);
}
.kpi-row em.is-neg { color: var(--neg); }
/* Un rendimento atteso positivo si legge verde, come ogni altro numero
   positivo del sito. Prima restava del colore del testo e sembrava neutro. */
.kpi-row em.is-pos { color: var(--pos); }

/* La riga del cambio e' una SOTTORIGA di «Rischio annuo»: non e' un'altra
   misura in fila con le altre, e' un pezzo di quella subito sopra. Il
   rientro e il trattino lo dicono senza bisogno di scriverlo, e il colore
   piu' tenue la tiene un gradino sotto nella gerarchia. Niente verde e
   niente rosso: un contributo negativo qui vuol dire «abbassa il rischio»,
   che con i colori del sito si leggerebbe al contrario. */
.kpi-row--fx { margin-top: -4px; padding-left: var(--s4); font-size: 12.5px; }
.kpi-row--fx span { color: var(--ink-3); }
.kpi-row--fx span::before { content: "└ "; opacity: .55; }
.kpi-row--fx em { color: var(--ink-2); font-size: 12.5px; }

/* Il tasso privo di rischio, sotto lo Sharpe che ha contribuito a produrre.
   Sta in mezzo fra il numero grande e la tabella delle altre misure perche'
   e' meta' del numeratore dello Sharpe, non un dettaglio tecnico. */
/* IL TASSO PRIVO DI RISCHIO, UN RIQUADRO SOLO NELLA SCHEDA DEI DATI.
   Stava sotto lo Sharpe di ognuna delle tre card — stesso numero, stessa
   fonte, stessa data, tre volte in una schermata. Il tasso non e' un dato del
   portafoglio ma dell'analisi, come la finestra storica e i giorni di borsa
   che gli stanno accanto adesso. Ha la forma degli altri riquadri `.dq`, con
   il numero grande e sotto da dove viene. */
/* ---- IL TASSO PRIVO DI RISCHIO E LA RIGA DEL CAMBIO ------------------
   Il tasso è una tessera `.dq` come le altre quattro, e non ha più niente di
   suo: numero grande, etichetta sotto, stessa forma e stessa distanza. Era
   una fascia larga tutta la riga con il valore a sinistra e la fonte
   spinta all'estremo destro — due isole con mezzo metro di bianco in mezzo,
   che in pagina non somigliavano a niente. Un dato dell'analisi si legge
   come gli altri dati dell'analisi.

   Restano solo le righe di eccezione (tasso misto su più valute, ripiego
   dichiarato) e le note che valgono per tutta l'analisi — chi è rimasto fuori
   e cosa è stato convertito — che non sono tessere perché non portano un
   numero: stanno larghe SOTTO le cinque tessere, con la superficie tenue
   delle parti di servizio.

   E SOTTO VUOL DIRE SOTTO TUTTE.
   La nota del cambio si era infilata fra la quarta tessera e il tasso: la
   griglia si leggeva «quattro riquadri, una fascia grigia, un riquadro
   solo», e l'ultimo sembrava un pezzo avanzato di un'altra scheda invece
   della quinta cosa che si dice dell'analisi. L'ordine adesso è quello della
   lettura: prima i cinque numeri, poi le note. */
.dq-nota {
  grid-column: 1 / -1;
  background: var(--surface-quieta); border: 1px solid var(--line);
  border-radius: var(--r-s); padding: var(--s3) var(--s4);
}
.dq-nota-eti { font-size: 13px; font-weight: 650; color: var(--ink-2); }
/* L'elenco dei titoli esclusi compare anche qui, fuori da un `.msg`: senza
   colore d'avviso addosso deve prendere quello delle note di servizio, o
   resterebbe nero pieno in mezzo a due righe grigie. */
.dq-nota .scartati { font-size: 12.5px; color: var(--ink-3); }
.dq-nota .scartati b { color: var(--ink-2); font-weight: 600; }
.rf-fonte { font-size: 12px; color: var(--ink-3); line-height: 1.5;
            margin-top: 6px; max-width: 70ch; }
.kpi-explain { font-size: 12.5px; color: var(--ink-2); margin-top: var(--s4);
               padding-top: var(--s4); border-top: 1px dashed var(--line);
               line-height: 1.55; }

/* Allocazione: la barra rende immediato ciò che prima andava letto in tabella. */
.alloc {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 0 var(--s6); align-content: start;
}
.alloc-legend { display: flex; gap: var(--s4); flex-wrap: wrap; padding-bottom: var(--s3);
                border-bottom: 1px solid var(--line); margin-bottom: var(--s2); }
.alloc-legend span { display: inline-flex; align-items: center; gap: 7px;
                     font-size: 12.5px; color: var(--ink-2); }
.alloc-legend i { width: 10px; height: 10px; border-radius: 3px; display: block; flex: none; }
.alloc-legend i.is-opt { background: var(--coral); }
.alloc-legend i.is-min { background: var(--blue); }
.alloc-legend i.is-mio { background: var(--mio); }

.alloc-item { display: flex; flex-direction: column;
              padding: var(--s3) 0; border-bottom: 1px solid var(--line); }
.alloc-item:last-child { border-bottom: 1px solid var(--line); }
.alloc-item .alloc-line:last-child { margin-top: auto; padding-top: 5px; }
.alloc-head { display: flex; justify-content: space-between; align-items: baseline;
              gap: var(--s3); margin-bottom: var(--s2); }
.alloc-title { font-size: 13.5px; font-weight: 600; letter-spacing: -.004em; }
.alloc-title .sym { font-family: var(--font-mono); color: var(--ink-3);
                    font-weight: 500; font-size: 12.5px; margin-left: 6px; }
.alloc-title .sym--solo { margin-left: 0; color: var(--ink); }
.alloc-line { display: grid; grid-template-columns: 74px 1fr 58px; gap: var(--s3);
              align-items: center; margin-top: 5px; }
.alloc-line--nuda { grid-template-columns: 1fr 58px; }
.alloc-line .who { font-size: 11.5px; color: var(--ink-3); }
.alloc-line .num { font-size: 12.5px; text-align: right; color: var(--ink); }
.alloc-item.is-zero { opacity: .5; }
.alloc-item.is-zero .num { color: var(--ink-3); }
/* Senza barre la riga del titolo scartato non ha bisogno di stacco sotto. */
.alloc-item.is-zero .alloc-head { margin-bottom: 0; }
.alloc--singola { grid-template-columns: 1fr; gap: 0; }

.alloc-track { display: block; height: 8px; background: var(--surface-2);
               border-radius: var(--r-pill); overflow: hidden; }
.alloc-fill { display: block; height: 100%; border-radius: var(--r-pill); background: var(--coral); }
.alloc-fill--min { background: var(--blue); }
/* La terza barra: quanto ce n'e' davvero nel portafoglio di chi legge.
   Il verde e' pieno in tutti e due i temi — e' una forma, non un testo. */
.alloc-fill--mio { background: var(--mio); }

/* Riquadri numerici: UNA sola griglia per tre usi — qualità dei dati, metriche
   della diversificazione, parti del punteggio. Prima erano tre blocchi di
   regole identiche scritti tre volte.

   PERCHE' TESSERE SEPARATE E NON UN BLOCCO UNICO
   Prima i riquadri erano incollati fra loro da un reticolo di 1 px ottenuto
   colorando il fondo del contenitore. Funzionava finché le celle riempivano
   tutte le righe: con tre voci su due colonne — cosa che succede di continuo
   nella scheda della concentrazione — l'ultimo posto restava vuoto e al suo
   posto compariva un rettangolo del colore del reticolo, cioè una macchia
   grigia senza significato. Tessere separate con il loro bordo non hanno
   questo problema, e stanno meglio con il resto del sistema. */
.dataquality, .diversif-metriche, .lenti {
  display: grid; gap: var(--s3);
}
.dataquality { grid-template-columns: repeat(auto-fit, minmax(min(100%, 170px), 1fr)); }
.diversif-metriche { grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }
.dq, .lenti > li {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-s);
}
.dq { padding: var(--s4) var(--s5); }
.dq b { display: block; font-family: var(--font-mono); font-variant-numeric: tabular-nums;
        font-size: 22px; letter-spacing: -.025em; color: var(--ink); line-height: 1.2; }
.dq span { display: block; font-size: 12px; color: var(--ink-3); margin-top: 6px; }
/* Il «/100» accanto al punteggio deve restare in linea. */
.dq b span.dq-su { display: inline; font-size: 14px; color: var(--ink-3); font-weight: 400; margin: 0; }
.dq .qual { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-ui);
            font-size: 16px; font-weight: 600; letter-spacing: 0; }
.dq .dot { width: 9px; height: 9px; border-radius: 50%; display: block; }
.dq .dot.hi { background: var(--pos); } .dq .dot.mid { background: var(--warn); }
.dq .dot.lo { background: var(--neg); }
.diversif-metriche .dq p { margin-top: var(--s2); line-height: 1.45; }
.dq b.dq-coppia { color: var(--ink-2); }
/* Grafico. */
.chart figure { margin: 0; margin-top: var(--s4); }
.chart img {
  width: 100%; max-width: 100%; height: auto; display: block;
  /* Il PNG è a fondo trasparente e poggia sulla superficie della card: niente
     cornice, niente rettangolo bianco. */
  background: transparent;
}

/* UN GRAFICO PER TEMA
   Il motore disegna lo stesso grafico due volte, una tavolozza per tema (vedi
   `TEMI_GRAFICO` in app.py): un PNG non sa in che tema sta la pagina, e la
   versione precedente — una sola immagine a fondo bianco, con la luminanza
   abbassata al buio — era un cerotto su quel problema, non una soluzione.
   Qui si sceglie l'immagine giusta, e i colori dei punti corrispondono
   finalmente a quelli della legenda qui sotto in TUTTI E DUE i temi.
   Quella che non serve è `display:none`, quindi non la leggono nemmeno gli
   screen reader. */
/* `.chart img` qui sopra dichiara `display:block`, che come selettore pesa
   piu' di una classe sola: se queste regole fossero scritte
   `.chart-img--scuro`, perderebbero il confronto e uscirebbero tutte e due le
   immagini. Da qui l'elemento ripetuto in ogni selettore. */
.chart img.chart-img--scuro { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chart img.chart-img--chiaro { display: none; }
  :root:not([data-theme="light"]) .chart img.chart-img--scuro { display: block; }
}
:root[data-theme="dark"] .chart img.chart-img--chiaro { display: none; }
:root[data-theme="dark"] .chart img.chart-img--scuro { display: block; }
:root[data-theme="light"] .chart img.chart-img--chiaro { display: block; }
:root[data-theme="light"] .chart img.chart-img--scuro { display: none; }
.chart figcaption { font-size: 12.5px; color: var(--ink-3); margin-top: var(--s3); line-height: 1.5; }
/* L'immagine si ferma a 640 px e sta in mezzo: e' disegnata per essere letta
   a quella larghezza (vedi `render_frontier_plot` in app.py). Ingrandirla
   oltre non aggiunge dettaglio — e' un PNG — ingrandisce solo le scritte
   finche' sembrano fuori scala. Legenda e didascalia sono testo vero e
   restano un po' piu' larghe, cosi' non vanno a capo ogni due parole. */
.chart-viewport { max-width: 560px; margin-inline: auto; }
.chart--sola .legend,
.chart--sola figcaption { max-width: 760px; margin-inline: auto; }
.chart--sola figure img { display: block; }
.legend { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s4); margin-top: var(--s4); }
.legend span { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--ink-2); }
.legend i { width: 11px; height: 11px; border-radius: 3px; display: block; flex: none; }
.legend i.is-min { background: var(--blue); }
.legend i.is-opt { background: var(--coral); }
/* Il rombo del portafoglio dichiarato: ruotato di 45 gradi, come nel
   disegno. La forma conta quanto il colore — chi non distingue il verde
   dal blu deve poter leggere lo stesso la legenda. */
.legend i.is-mio { background: var(--mio); border-radius: 2px;
                   transform: rotate(45deg); width: 9px; height: 9px; }
.legend i.is-frontier { background: var(--ink); }
/* Il ramo inferiore è tratteggiato anche nella legenda. */
.legend i.is-lower { background: repeating-linear-gradient(90deg, var(--ink-3) 0 4px, transparent 4px 7px);
                     border-radius: 0; height: 3px; }
/* E così la retta della liquidità, che nel grafico è tratteggiata corallo. */
.legend i.is-cml { background: repeating-linear-gradient(90deg, var(--coral) 0 5px, transparent 5px 8px);
                   border-radius: 0; height: 3px; }

/* Tabella: scorre dentro il suo contenitore, mai il corpo pagina. */
.tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); }
.tablewrap table { border-collapse: collapse; width: 100%; min-width: 460px; font-size: 14px; }
.tablewrap th {
  text-align: left; font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
  padding: 13px 18px; border-bottom: 1px solid var(--line); white-space: nowrap;
}
.tablewrap td {
  padding: 12px 18px; border-bottom: 1px solid var(--line); color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.tablewrap td:first-child, .tablewrap th:first-child { color: var(--ink); }
.tablewrap tbody tr { transition: background var(--dur-s) var(--ease); }
.tablewrap tbody tr:hover { background: var(--surface-2); }
.tablewrap tr:last-child td { border-bottom: 0; }

/* ---------- LA NOTA TECNICA --------------------------------------------
   Una pagina che si legge come un paper: colonna misurata, sezioni ed
   equazioni numerate, indice in spalla. Non introduce nessun colore e
   nessun carattere nuovo — sono i token di sempre, con una gerarchia
   diversa, perché una nota tecnica non è un'altra marca. */
.metodo { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s6); }
@media (min-width: 1080px) {
  .metodo { grid-template-columns: 14rem minmax(0, 44rem); gap: var(--s8); }
}
.metodo-indice { font-size: 13.5px; }
@media (min-width: 1080px) {
  /* Resta ferma mentre si scorre: in un documento di quattordici sezioni
     l'indice serve a metà lettura, non solo all'inizio. */
  /* L'altezza della barra è quella dichiarata da `--topbar-h`, non un 80
     scritto a mano che nessuno ricorderebbe di aggiornare. */
  .metodo-indice { position: sticky; top: calc(var(--topbar-h) + var(--s4));
                   align-self: start;
                   max-height: calc(100dvh - var(--topbar-h) - var(--s6));
                   overflow-y: auto; }
}
.metodo-indice h2 {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-3); font-weight: 500;
  margin: 0 0 var(--s3);
}
.metodo-indice ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.metodo-indice a {
  color: var(--ink-2); text-decoration: none; line-height: 1.35;
  display: grid; grid-template-columns: 1.8rem 1fr;
  transition: color var(--dur-s) var(--ease);
}
.metodo-indice a:hover { color: var(--brand-ink); }
.metodo-indice a span {
  font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3);
}

.metodo-corpo { min-width: 0; }
.metodo-corpo > section { margin-bottom: var(--s7); }
.metodo-corpo h2 {
  font-size: 23px; letter-spacing: -.018em; line-height: 1.2;
  margin: 0 0 var(--s4); display: grid; grid-template-columns: 2.6rem 1fr;
  align-items: baseline;
}
.metodo-corpo h2 > span {
  font-family: var(--font-mono); font-size: 14px; font-weight: 400;
  color: var(--brand-ink); letter-spacing: 0;
}
.metodo-corpo h3 {
  font-size: 16.5px; margin: var(--s6) 0 var(--s2);
  display: grid; grid-template-columns: 2.6rem 1fr; align-items: baseline;
}
.metodo-corpo h3 > span {
  font-family: var(--font-mono); font-size: 12.5px; font-weight: 400; color: var(--ink-3);
}
.metodo-corpo p { margin: 0 0 var(--s4); color: var(--ink-2); line-height: 1.7; }
.metodo-corpo section > p,
.metodo-corpo section > ul { margin-left: 2.6rem; }
.metodo-corpo ul { padding-left: 1.1rem; margin-bottom: var(--s4); }
.metodo-corpo li { color: var(--ink-2); line-height: 1.7; margin-bottom: 7px; }
.metodo-corpo li::marker { color: var(--ink-3); }
.metodo-corpo b { color: var(--ink); font-weight: 500; }

/* Il sommario: la sola card della pagina, perché è la sola cosa che si legge
   fuori dall'ordine delle sezioni. */
.metodo-sommario {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  padding: var(--s5) var(--s5) var(--s4); margin-bottom: var(--s7);
}
.metodo-sommario h2 {
  display: block; font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3);
  font-weight: 500; margin: 0 0 var(--s3);
}
.metodo-sommario p { margin-bottom: var(--s3); }
.metodo-sommario p:last-child { margin-bottom: 0; }

/* Equazioni: MathML nativo, numerate a destra nel viola della firma. */
.metodo-corpo .eq {
  margin: var(--s5) 0 var(--s5) 2.6rem; padding: 2px 0;
  display: grid; grid-template-columns: minmax(0, 1fr) 3rem;
  align-items: center; gap: var(--s2); overflow-x: auto;
}
.metodo-corpo .eq math {
  display: block; margin: 0 auto; font-size: 1.12em; font-family: var(--font-ui);
}
.metodo-corpo .eq-n {
  font-family: var(--font-mono); font-size: 12.5px; color: var(--accent-ink);
  text-align: right;
}

/* Il riquadro laterale: filetto viola, superficie normale. Ne compaiono
   parecchi lungo il documento, e un pieno colorato ripetuto otto volte
   smetterebbe di essere un'eccezione. */
.metodo-nota {
  margin: var(--s5) 0 var(--s5) 2.6rem; padding: var(--s4) var(--s5);
  background: var(--surface); border: 1px solid var(--line);
  border-left: 2px solid var(--accent-ink); border-radius: 0 var(--r-s) var(--r-s) 0;
}
.metodo-nota > b {
  display: block; font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--accent-ink);
  font-weight: 500; margin-bottom: var(--s2);
}
.metodo-nota p { font-size: 14.5px; margin-bottom: var(--s2); }
.metodo-nota p:last-child { margin-bottom: 0; }

.metodo-tab { margin: var(--s5) 0 var(--s5) 2.6rem; }
.metodo-tab table { min-width: 22rem; }
.metodo-tab td.n, .metodo-tab th.n {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  white-space: nowrap; color: var(--ink);
}
.metodo-tab td.s, .metodo-tab th.s { white-space: nowrap; color: var(--ink); }
.metodo-cap {
  margin: 0; padding: var(--s3) var(--s5); font-size: 12.5px; color: var(--ink-3);
  border-top: 1px solid var(--line); line-height: 1.5;
}
.metodo-colofone {
  margin: 0; padding-top: var(--s5); border-top: 1px solid var(--line);
  font-size: 13px; color: var(--ink-3);
}

@media (max-width: 720px) {
  .metodo-corpo section > p,
  .metodo-corpo section > ul,
  .metodo-corpo .eq,
  .metodo-corpo .metodo-nota,
  .metodo-corpo .metodo-tab { margin-left: 0; }
  .metodo-corpo h2, .metodo-corpo h3 { grid-template-columns: 2.1rem 1fr; }
}

/* Riquadro richiudibile. */
details.info { border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); }
details.info > summary {
  cursor: pointer; padding: var(--s4) var(--s5); font-size: 14.5px; font-weight: 500;
  list-style: none; display: flex; align-items: center; gap: var(--s3);
  border-radius: var(--r);
  transition: color var(--dur-s) var(--ease);
}
details.info > summary:hover { color: var(--brand-ink); }
details.info > summary::-webkit-details-marker { display: none; }
details.info > summary::before {
  content: ""; width: 6px; height: 6px; border-right: 1.5px solid var(--ink-3);
  border-bottom: 1.5px solid var(--ink-3); transform: rotate(-45deg);
  transition: transform var(--dur) var(--ease);
}
details.info[open] > summary::before { transform: rotate(45deg); }
details.info .info-body {
  padding: 0 var(--s5) var(--s5); color: var(--ink-2); font-size: 14px;
  display: flex; flex-direction: column; gap: var(--s3);
  animation: apri var(--dur-l) var(--ease) both;
}
details.info .info-body ul { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 7px; }
details.info .info-body li::marker { color: var(--ink-3); }

/* La legenda delle metriche: su schermo largo sta su due colonne, così non
   spinge il grafico troppo in basso quando è aperta. `columns` non ha effetto
   su un contenitore flex, quindi qui corpo e lista tornano blocchi normali. */
details.info.legend-metrics .info-body,
details.info.legend-metrics .info-body ul { display: block; }
details.info.legend-metrics .info-body li + li { margin-top: 7px; }
details.info.legend-metrics .info-body > * + * { margin-top: var(--s3); }
@media (min-width: 900px) {
  details.info.legend-metrics .info-body { columns: 2; column-gap: var(--s7); }
  details.info.legend-metrics .info-body li,
  details.info.legend-metrics .info-body p { break-inside: avoid; }
  details.info.legend-metrics .info-body h4 { break-after: avoid; margin-top: 0; }
}

/* Suggerimento richiudibile in linea. */
.hint-inline > summary {
  cursor: pointer; list-style: none; font-size: 13px; color: var(--ink-2);
  display: inline-flex; align-items: center; gap: 7px; padding: 2px 0;
}
.hint-inline > summary::-webkit-details-marker { display: none; }
.hint-inline > summary::before {
  content: ""; width: 5px; height: 5px; border-right: 1.5px solid var(--ink-3);
  border-bottom: 1.5px solid var(--ink-3); transform: rotate(-45deg);
  transition: transform var(--dur) var(--ease);
}
.hint-inline[open] > summary::before { transform: rotate(45deg); }
.hint-inline > summary:hover { color: var(--brand-ink); }
.hint-inline p { font-size: 13px; color: var(--ink-2); margin-top: var(--s2);
                 max-width: 68ch; line-height: 1.55; }

/* ---------- il voto: il numero più importante della pagina --------------
   Prima era un riquadrino da 30 px in un angolo. È il dato che riassume
   tutto il resto: qui prende la dimensione che gli spetta, con il viola a
   fare da cornice quando il punteggio è alto. */
.voto {
  display: inline-flex; align-items: baseline; gap: 2px; flex: none;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  padding: var(--s3) var(--s5); border-radius: var(--r);
  border: 1px solid var(--line); background: var(--surface-2);
}
.voto-num { font-size: 34px; font-weight: 600; letter-spacing: -.035em; line-height: 1; }
.voto-su { font-size: 14px; color: var(--ink-3); }
/* ---------- LA SCALA DEI VOTI ------------------------------------------
   Quattro gradini, e il quarto è il viola di BlissPoint:

     0-39   rosso   il punteggio è basso
     40-59  giallo  è a metà strada
     60-79  verde   è buono
     80-100 VIOLA   è il migliore

   Il viola in cima non è una scelta grafica qualunque: è lo stesso colore
   della firma del sito, e finisce sul punteggio più alto. Vederlo comparire
   vuol dire «qui sei arrivato in fondo alla scala», ed è per questo che negli
   altri ottanta punti non compare.
   La scala vale per tutti i voti — punteggio d'insieme, diversificazione,
   concentrazione, composizione e le tre lenti — e sta scritta qui una volta
   sola. Le soglie invece vivono in `fascia_voto()` dentro app.py: il template
   chiama quella, così non esistono due elenchi di numeri da tenere in pari. */
.voto--verylow, .voto--low { background: var(--neg-soft); border-color: transparent; }
.voto--verylow .voto-num, .voto--low .voto-num { color: var(--neg); }
.voto--medium { background: var(--warn-soft); border-color: transparent; }
.voto--medium .voto-num { color: var(--warn); }
.voto--good { background: var(--pos-soft); border-color: transparent; }
.voto--good .voto-num { color: var(--pos); }
.voto--high { background: var(--accent-soft); border-color: transparent; }
.voto--high .voto-num { color: var(--accent-ink); }

/* Il voto grande del punteggio d'insieme. */
.voto--hero { padding: var(--s4) var(--s6); border-radius: var(--r-l); }
.voto--hero .voto-num { font-size: clamp(46px, 6.5vw, 62px); }
.voto--hero .voto-su { font-size: 17px; }

/* Il voto della concentrazione va sempre accompagnato da cosa misura. */
.voto-blocco { display: flex; flex-direction: column; align-items: flex-end;
               gap: 7px; flex: none; }
.voto-etichetta { font-size: 11.5px; color: var(--ink-3); text-align: right;
                  max-width: 18ch; line-height: 1.3; margin: 0; }

/* Le tre schede di valutazione condividono la stessa gerarchia: occhiello e
   titolo a sinistra, voto a destra, giudizio, barra. */
.diversif, .concentr, .composiz, .punteggio { display: flex; flex-direction: column; gap: var(--s4); }
.diversif-testa { display: flex; align-items: flex-start; justify-content: space-between;
                  gap: var(--s5); flex-wrap: wrap; }
.diversif-testa .sectionhead { margin-bottom: 0; }
.diversif-giudizio { color: var(--ink-2); font-size: 14.5px; max-width: 70ch; }
.diversif-giudizio b { color: var(--ink); }

.diversif-barra { display: block; height: 9px; border-radius: var(--r-pill);
                  background: var(--surface-2); overflow: hidden; }
/* Tinta unita, non un gradiente: una barra al 9% con dentro tutto il passaggio
   da rosso a verde finiva proprio sul verde, cioè diceva il contrario del
   punteggio che accompagnava. */
/* Le barre seguono la stessa scala dei riquadri qui sopra: `.fill--*` vale
   sia per la barra grande di una scheda sia per quella piccola di una lente,
   così lo stesso voto ha lo stesso colore ovunque compaia. */
.diversif-fill, .parte-fill { display: block; height: 100%; border-radius: var(--r-pill);
                              background: var(--ink-3); }
.fill--verylow, .fill--low { background: var(--neg); }
.fill--medium { background: var(--warn); }
.fill--good { background: var(--pos); }
/* Anche il pieno della barra passa da `--accent-ink`: il binario è
   `--surface-2`, e sul tema scuro un #6D3F5B lì sopra sta a 2,4:1 — sotto il
   3:1 che serve perché una barra si veda come barra. */
.fill--high { background: var(--accent-ink); }

/* ---------- punteggio d'insieme -----------------------------------------
   È la media delle tre lenti e apre la sintesi: su schermo largo si apre in
   due colonne — a sinistra il voto grande con il giudizio, a destra le tre
   parti da cui esce — così smette di essere l'ennesima card in colonna e
   diventa il punto in cui l'occhio si ferma. */
.punteggio { gap: var(--s5); }
/* `.punteggio-corpo` non c'e' piu': era la griglia a due colonne che teneva
   il voto grande a sinistra e le tre lenti a destra. Adesso le lenti sono
   righe apribili e stanno in colonna sotto il voto, dove l'apertura di una
   spinge in giu' quelle dopo invece di scavalcare la colonna accanto. */
.punteggio-sx { display: flex; flex-direction: column; gap: var(--s4); }
.punteggio-voto { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; }
/* LA DIDASCALIA DEL VOTO GRANDE VA A SINISTRA, NON A DESTRA.
   `.voto-etichetta` nasce dentro `.voto-blocco`, dove il voto e la sua
   didascalia sono incolonnati contro il bordo destro di una card: li' il
   testo allineato a destra e' giusto. Qui la stessa classe sta ACCANTO al
   numero, e a destra di esso: allineata a destra dentro un riquadro da 18
   caratteri produceva due righe scalate verso sinistra con mezza card di
   vuoto dopo — una didascalia che sembrava spinta via dal numero invece che
   attaccata a lui. Accanto a un numero da sessanta pixel serve anche un
   corpo che si legga, non undici pixel e mezzo. */
.punteggio-voto .voto-etichetta {
  text-align: left; max-width: 24ch; font-size: 13px; line-height: 1.4;
}

/* LE TRE LENTI: IL VOTO SI VEDE, LA SPIEGAZIONE SI APRE.
   Erano tre riquadri col numero, e poi tre CARD INTERE più sotto che
   ridicevano ognuna lo stesso numero con accanto la frase che lo spiega: lo
   stesso voto due volte a mezza schermata di distanza, e la seconda volta chi
   leggeva doveva fermarsi a capire se fosse lo stesso.
   Adesso ogni lente è una riga apribile: chiusa porta nome, voto e barra;
   aperta il giudizio per esteso e, quando il voto è basso, cosa lo farebbe
   salire. Sono `<details>`, quindi funzionano a JavaScript spento. */
.lenti { list-style: none; margin: 0; padding: 0;
         grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
/* Il peso di ogni voce dentro il voto d'insieme: una cifra piccola accanto al
   nome, non un'altra colonna. Serve a dire perché la media viene quella. */
.bp-peso { font-style: normal; font-size: 11px; color: var(--ink-3);
           font-family: var(--font-mono); margin-left: 6px; }
/* Con sei righe invece di tre, la lista sta in colonna anche su schermo largo:
   affiancate diventavano sei riquadri stretti in due file, e l'ordine — la
   performance per prima, poi la struttura — non si leggeva più. */
.lenti { grid-template-columns: 1fr; }
.lenti > li { padding: 0; display: block; position: relative; }
.lente > summary {
  cursor: pointer; list-style: none; display: block;
  padding: var(--s4) var(--s5) var(--s4) var(--s4);
  position: relative; border-radius: inherit;
}
.lente > summary::-webkit-details-marker { display: none; }
/* La freccia: piccola, a destra del voto, e ruota all'apertura. È l'unico
   segno che la riga si tocca, quindi non può essere più tenue del testo. */
.lente > summary::after {
  content: ""; position: absolute; right: var(--s4); top: 26px;
  width: 8px; height: 8px; border-right: 2px solid var(--ink-2);
  border-bottom: 2px solid var(--ink-2); border-radius: 1px;
  transform: rotate(45deg);
  transition: transform var(--dur-s) var(--ease);
}
.lente[open] > summary::after { transform: rotate(225deg); }
.lente > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
/* Il numero non deve finire sotto la freccia. */
.lente > summary .parte-testa { padding-right: var(--s5); }
.lente-corpo { padding: 0 var(--s5) var(--s5) var(--s4);
               display: flex; flex-direction: column; gap: var(--s3); }
.lente-corpo > p { font-size: 13.5px; color: var(--ink-2); line-height: 1.6;
                   max-width: 68ch; }
/* La tendina sotto il voto d'insieme dell'efficienza: sta in una card che non
   è una riga di elenco, quindi si porta il bordo da sé. */
.lente--sola { border-top: 1px solid var(--line); }
.lente--sola > summary { padding-left: 0; padding-bottom: var(--s3); }
.lente--sola > summary::after { right: 2px; top: 22px; }
.lente--sola .lente-corpo { padding-left: 0; padding-right: 0; }
/* I tre voti della varietà, dentro la sua tendina: righe più fitte, senza
   riquadro proprio — il riquadro è già la tendina che li contiene. */
.composiz-voti { list-style: none; margin: 0; padding: 0;
                 display: flex; flex-direction: column; gap: var(--s3); }
.parte-testa { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3); }
.parte-testa > span { font-size: 12.5px; color: var(--ink-2); line-height: 1.35; }
/* Il nome della categoria sta accanto al voto, la domanda che la definisce
   sotto e più piccola: prima la riga era la sola domanda, lunga, e le tre
   categorie non avevano un nome con cui nominarle. */
.parte-testa .parte-nome { font-size: 15px; font-weight: 500; color: var(--ink); }
.parte-sotto { font-size: 12px; color: var(--ink-3); line-height: 1.4; }
.parte-barra { margin-top: var(--s2); }
/* Il colore di partenza sta in `:where()`, cioè a specificità zero: così le
   classi `.num--*` della scala dei voti lo scavalcano sempre, senza dover
   ripetere il selettore lungo per ognuna delle quattro fasce. */
.parte-testa b { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
                 font-size: 24px; letter-spacing: -.025em; white-space: nowrap; }
:where(.parte-testa b) { color: var(--ink); }
.parte-testa b .dq-su { font-size: 12.5px; color: var(--ink-3); font-weight: 400; }
.parte-barra { display: block; height: 6px; border-radius: var(--r-pill);
               background: var(--surface-2); overflow: hidden; }
/* Un numero colorato dalla sua fascia. Stessa scala dei riquadri e delle
   barre, applicata al testo: così lo stesso voto ha lo stesso colore che sia
   scritto grande in un riquadro, disegnato in una barra o stampato accanto al
   titolo di un gruppo. */
.num--verylow, .num--low { color: var(--neg); }
.num--medium { color: var(--warn); }
.num--good { color: var(--pos); }
/* Il viola come TESTO passa sempre da `--accent-ink`: sul tema chiaro è
   #6D3F5B tale e quale, sul tema scuro è lo stesso tono schiarito. Il pieno
   #6D3F5B scritto su superficie scura starebbe a 1,6:1, cioè invisibile. */
.num--high, .lente-voto.num--high { color: var(--accent-ink); }
/* LA LENTE PIÙ BASSA NON PORTA PIÙ NESSUN SEGNO.
   Era un filetto grigio disegnato DENTRO il riquadro (`box-shadow: inset`):
   correva lungo il bordo sinistro senza seguirne gli angoli tondi, e il
   risultato era un secondo contorno storto incollato al primo — su fondo
   scuro, dove il grigio è chiaro, si vedeva più della tessera stessa.
   E non serviva: quale delle tre sia la più bassa lo dicono già il numero
   e la barra, che portano il colore della loro fascia, e la frase sopra il
   gruppo dice per esteso di guardare i tre punteggi. Un segnale in più che
   ripete un'informazione già data è solo un contorno in più. */

/* Su schermo largo il punteggio si apre in due colonne asimmetriche: a
   sinistra il voto grande, a destra le tre lenti una sopra l'altra. */
/* Le lenti restano in colonna a qualunque larghezza: sono righe apribili, e
   tre tendine affiancate che si aprono a altezze diverse fanno saltare la
   riga sotto. In colonna l'apertura spinge in giù e basta. */
@media (min-width: 860px) {
  .lenti { grid-template-columns: 1fr; }
}

/* Le due schede di analisi affiancate su schermo largo: prima erano due card
   identiche una sotto l'altra, cioè la parte più monotona della pagina. */
/* `auto-fit` e non due colonne fisse: quando la scheda è una sola — capita,
   la concentrazione non si calcola sempre — la card occupa tutta la riga
   invece di lasciare mezza pagina vuota. */
.griglia-due { display: grid; gap: var(--s6); align-items: start;
                   grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr)); }

/* Composizione del portafoglio: tre ripartizioni affiancate. */
.composiz-gruppi {
  display: grid; gap: var(--s5) var(--s6);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
/* La ripartizione per esteso vive dentro un `details`, che ha una regola
   generica per gli elenchi: pallini e rientro. Qui non servono — sono barre
   con una percentuale, non un elenco puntato — e senza queste due righe la
   griglia delle voci si rompe appena il riquadro viene aperto. */
details.info .info-body .composiz-gruppi { display: grid; }
details.info .info-body .composiz-voci { padding-left: 0; display: block; }
.composiz-gruppi--stretti { grid-template-columns: 1fr; gap: var(--s5); }
.composiz-gruppo { display: flex; flex-direction: column; gap: var(--s2);
                   padding: var(--s4) var(--s5); border: 1px solid var(--line);
                   border-radius: var(--r); background: var(--surface); }
.composiz-gruppo h4 { margin-bottom: 0; display: flex; align-items: baseline;
                      justify-content: space-between; gap: var(--s3); color: var(--ink); }
/* Il voto della singola ripartizione: piccolo, accanto al titolo del gruppo.
   Serve a far vedere quale delle tre tira giù la media complessiva. */
.lente-voto { font-family: var(--font-mono); font-size: 12px; font-weight: 500;
              white-space: nowrap; letter-spacing: 0; text-transform: none; }
:where(.lente-voto) { color: var(--ink-3); }
.composiz-quota { font-size: 12px; color: var(--ink-3); margin-bottom: var(--s2); }
.composiz-voci { list-style: none; margin: 0; padding: 0;
                 display: flex; flex-direction: column; gap: var(--s3); }
/* La barra cresce con il gruppo invece di restare un moncone di 64 px: quando
   una sola ripartizione occupa tutta la riga — un portafoglio di soli ETF ha
   il tipo e basta — il nome prendeva mille pixel e la barra restava larga
   quanto un dito. Il minimo tiene in piedi anche la colonna stretta. */
.composiz-voci li { display: grid;
                    grid-template-columns: minmax(0, 1fr) minmax(64px, 26%) 48px;
                    gap: var(--s3); align-items: center; }
.composiz-nome { font-size: 13px; color: var(--ink-2);
                 overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.composiz-barra { display: block; height: 7px; border-radius: var(--r-pill);
                  background: var(--surface-2); overflow: hidden; }
.composiz-fill { display: block; height: 100%; border-radius: var(--r-pill); background: var(--brand); }
.composiz-voci .num { font-size: 12.5px; text-align: right; color: var(--ink); }
/* La parte non classificata: si vede che c'e' ed e' chiaro che non e' una
   categoria come le altre — barra tratteggiata e testo smorzato. Chiude la
   somma al 100%, cosi' chi conta i propri titoli ritrova il conto. */
.composiz-resto .composiz-nome,
.composiz-resto .num { color: var(--muted); }
.composiz-fill--resto {
  background: repeating-linear-gradient(135deg,
    var(--muted) 0 4px, transparent 4px 8px);
  opacity: .55;
}
.composiz-quali {
  display: block; font-size: 11.5px; color: var(--muted);
  overflow-wrap: anywhere;
}

/* Come si migliora: compare solo con un voto basso. Riquadro neutro, non
   allarmato — non c'è niente di rotto, c'è una cosa da sapere. */
.migliora { border: 1px solid var(--line); border-radius: var(--r);
            padding: var(--s4) var(--s5); background: var(--surface-2);
            border-left: 3px solid var(--brand); }
.migliora h4 { font-size: 14.5px; margin-bottom: 2px; color: var(--ink);
               font-family: var(--font-ui); text-transform: none; letter-spacing: -.006em; }
.migliora ul { list-style: none; margin: var(--s3) 0 0; padding: 0;
               display: flex; flex-direction: column; gap: var(--s3); }
.migliora li { position: relative; padding-left: var(--s4); font-size: 13.5px;
               color: var(--ink-2); line-height: 1.5; max-width: 78ch; }
.migliora li::before { content: ""; position: absolute; left: 0; top: .62em;
                       width: 5px; height: 5px; border-radius: 50%;
                       background: var(--brand); }

.tag-excluded { font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em;
                text-transform: uppercase; padding: 3px 9px; border-radius: var(--r-pill);
                background: var(--neg-soft); color: var(--neg); }

/* ---------- 9. STATI ---------------------------------------------------- */
.msg {
  display: flex; gap: var(--s3); align-items: flex-start;
  padding: 15px 18px; border-radius: var(--r); font-size: 14px;
  border: 1px solid transparent;
}
.msg b { display: block; margin-bottom: 3px; }
.msg p { font-size: 13.5px; opacity: .9; }
.msg-icon { font-family: var(--font-mono); font-weight: 700; flex: none; line-height: 1.5; }
.msg--err { background: var(--neg-soft); color: var(--neg); border-color: color-mix(in srgb, var(--neg) 22%, transparent); }
.msg--warn { background: var(--warn-soft); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 22%, transparent); }
.msg--ok { background: var(--pos-soft); color: var(--pos); border-color: color-mix(in srgb, var(--pos) 22%, transparent); }
.msg--info { background: var(--brand-soft); color: var(--brand-ink); border-color: color-mix(in srgb, var(--brand) 25%, transparent); }
.msg a { color: inherit; font-weight: 500; }
.msg--block { text-align: left; }
/* Il messaggio che spiega perche' si e' arrivati alla registrazione: e' una
   spiegazione, non un avviso di sistema, quindi ha il respiro di un
   paragrafo invece della compattezza di una riga d'errore. */
.msg.muro { align-items: flex-start; padding: var(--s4); line-height: 1.55; }
.msg.muro b { font-size: 15px; margin-bottom: 5px; }

/* L'INVITO A CREARSI UN ACCOUNT, DOPO IL RISULTATO
   Compare solo a chi non ne ha uno, e solo sotto un'analisi vera: e' il
   momento in cui sa gia' cosa riceve, quindi non chiede niente a scatola
   chiusa. Sta fuori dalle card del risultato perche' non e' un dato: e' la
   voce del sito. */
.invito-account {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--s3) var(--s4);
  padding: var(--s4) var(--s5);
  border: 1px solid color-mix(in srgb, var(--brand) 25%, transparent);
  border-radius: var(--r);
  background: var(--brand-soft);
}
.invito-account p { margin: 0; max-width: 62ch; font-size: 14.5px; color: var(--ink); }
.invito-account .btn { flex: none; }
/* Elenco dei titoli lasciati fuori: vive dentro un .msg, quindi eredita il
   colore dell'avviso. */
.scartati { list-style: none; margin: var(--s3) 0 0; padding: 0;
            display: flex; flex-direction: column; gap: 5px; font-size: 13.5px; }
.scartati li { display: flex; flex-wrap: wrap; gap: 0 8px; align-items: baseline; }
.scartati b { display: inline; }
.scartati span { opacity: .85; }

/* Fasi reali del calcolo. */
/* L'elenco delle fasi nasce attaccato al pulsante che l'ha fatto partire:
   sullo schermo di un telefono la prima riga finiva sotto il bordo tondo del
   bottone e le due cose si leggevano come una sola. Sono due momenti diversi
   — il comando e il resoconto — e fra un comando e il suo resoconto ci vuole
   uno stacco che si veda. */
.progress { display: none; }
.progress[data-on] { display: flex; flex-direction: column; gap: 12px;
                     margin-top: var(--s6); padding-top: var(--s5);
                     border-top: 1px solid var(--line);
                     animation: apri var(--dur-l) var(--ease) both; }
.step { display: flex; align-items: center; gap: 12px; font-size: 13.5px; color: var(--ink-3);
        transition: color var(--dur) var(--ease); }
.step-dot { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--line-2); flex: none;
            transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.step.is-done { color: var(--ink-2); }
.step.is-done .step-dot { background: var(--pos); border-color: var(--pos); }
.step.is-now { color: var(--ink); font-weight: 500; }
.step.is-now .step-dot { border-color: var(--brand); border-right-color: transparent; animation: spin .8s linear infinite; }

.empty { text-align: center; padding: var(--s7) var(--s5); color: var(--ink-3); }
.empty h3 { color: var(--ink); margin-bottom: var(--s2); }

/* ---------- 10. PAGINE --------------------------------------------------- */

/* ---------- hero della homepage: skyline finanziaria come sfondo -------- */
.hero {
  position: relative; isolation: isolate; overflow: hidden;
  background:
    radial-gradient(90ch 52ch at 4% -34%, var(--brand-soft) 0%, transparent 62%),
    var(--surface);
  border-bottom: 1px solid var(--line);
}
/* La skyline vive nel fondo, non in una card. È ancorata in basso a destra e
   le maschere la fanno svanire verso sinistra e verso l'alto, cioè dove
   passano claim, titolo e pulsante: il testo resta sempre su fondo pieno. */
.skyline {
  position: absolute; inset: auto 0 0 0; width: 100%; height: 78%;
  color: var(--brand); z-index: -1; pointer-events: none;
  filter: saturate(.5) blur(1.1px);
  opacity: .5;
}
/* Velo che scende dall'alto: chiude qualsiasi stacco fra sfondo e città. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(180deg,
    var(--surface) 0%, color-mix(in srgb, var(--surface) 62%, transparent) 34%,
    transparent 68%);
}
.hero-inner { position: relative; padding-block: clamp(56px, 8vw, 112px);
              display: grid; gap: var(--s7); align-items: center; }
.hero-testo { max-width: 40rem; gap: var(--s5); }
.hero h1 { font-size: clamp(32px, 4.8vw, 50px); letter-spacing: -.03em; }
.hero h1 .accent { color: var(--brand-ink); }
.hero h1 .accent-2 { color: var(--coral); }
.hero .lede { font-size: clamp(16px, 1.5vw, 19px); color: var(--ink-2); max-width: 46ch; }
/* L'AVVERTENZA: TERZO LIVELLO, NON SECONDO.
   Sotto il paragrafo c'e' la riga che dice che questi sono calcoli su dati
   passati. Deve leggersi — per questo e' uscita dalla coda del paragrafo —
   ma non deve pesare quanto la descrizione del prodotto, o l'hero
   diventerebbe due paragrafi alla pari e il titolo perderebbe il primo
   posto. Quindi: piu' piccola, piu' tenue, e attaccata al paragrafo di sopra
   (il margine negativo stringe il passo di `.stack-s` da dodici a otto) cosi'
   si vede che e' la sua nota e non una frase nuova. */
.hero .lede-nota {
  margin-top: calc(var(--s1) * -1);
  font-size: 13.5px; line-height: 1.55;
  color: var(--ink-3); max-width: 52ch;
}
.hero-actions { display: flex; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s2); }
/* LE DUE AZIONI DELL'HERO SONO UNA COPPIA, E DEVONO SEMBRARLO.
   «Vedi un esempio» era un `.btn-ghost`: nessun bordo, nessun fondo, il peso
   di una parola lasciata lì accanto al pulsante pieno. Sul telefono, dove i
   due vanno uno sotto l'altro, si leggeva come una didascalia del pulsante e
   non come la seconda strada — che è invece l'unica cosa che chi non ha un
   account può guardare prima di decidere.
   Un bordo, e basta: nessun colore nuovo, il pieno resta uno solo. */
.hero-actions .btn-ghost {
  border-color: var(--line-2); background: var(--surface); color: var(--ink);
}
.hero-actions .btn-ghost:hover {
  border-color: var(--brand-ink); background: var(--brand-soft); color: var(--brand-ink);
}

/* IL CLAIM E' IL MARCHIO, NON UNA DIDASCALIA
   Prima era una firma da 11,5 px sotto il logo: si leggeva dopo il titolo,
   dopo l'occhiello e dopo il pulsante, cioe' praticamente mai. Ma «Balance
   your portfolio. Power your future.» non e' una nota a margine — e' la sola
   riga del sito che dice cos'e' BlissPoint, ed e' la stessa in tutte e cinque
   le lingue, quindi e' letteralmente il marchio scritto per esteso.
   Adesso apre l'hero e ha la misura di un titolo. */
.claim {
  display: flex; align-items: center; gap: 14px; margin-bottom: var(--s2);
  font-family: var(--font-mono);
  font-size: clamp(15px, 2vw, 23px);
  line-height: 1.3;
  letter-spacing: .04em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink);
  text-wrap: balance;
}
/* LE DUE INIZIALI SONO IL LOGO DETTO A PAROLE
   B di Balance e P di Power sono le stesse due lettere del marchio che sta
   lì accanto: ingrandite e in blu diventano il monogramma BP, e il claim
   smette di essere una frase per diventare la spiegazione della sigla.
   Blu come il logo, non viola: il marchio accanto è quello, e sono la stessa
   sigla scritta due volte — una per segno e una per parola.
   `line-height: 0` le fa crescere senza allargare la riga sotto. */
/* La parola che porta l'iniziale non si spezza mai: senza questo, il
   riquadro `inline-block` della lettera offre al browser un punto in cui
   andare a capo, e la P finiva su una riga e «ower» su quella dopo. */
.claim-parola { white-space: nowrap; }
/* Le due frasi del claim, una per riga: vedi `claim_monogramma` in app.py.
   E' questa riga a rendere l'altezza del blocco prevedibile, e quindi a
   permettere al marchio di essere alto esattamente quanto lui. */
.claim-frase { display: block; }
.claim b {
  display: inline-block;
  font-size: 1.46em;
  font-weight: 700;
  color: var(--brand);
  letter-spacing: 0;
  /* `line-height: 1` e non 0: da inline-block un'altezza nulla farebbe
     scivolare la lettera fuori dal suo posto sulla riga. Il rientro sotto la
     linea di base lo toglie il margine negativo, che non tocca il flusso. */
  line-height: 1;
  margin-bottom: -.06em;
  animation: monogramma 900ms var(--ease) both;
}
/* LE DUE LETTERE ARRIVANO IN RITARDO, E UNA DOPO L'ALTRA
   La riga entra per prima come tutto il resto dell'hero; poi la B e la P si
   accendono, a un decimo di secondo l'una dall'altra. E' quel ritardo a farle
   leggere come una cosa a se' — il monogramma del logo che sta li' accanto —
   invece che come due lettere colorate dentro una frase. */
.claim b:nth-of-type(1) { animation-delay: .30s; }
.claim b:nth-of-type(2) { animation-delay: .44s; }

/* La lettera sale, supera di poco la misura giusta e ci si assesta, mentre il
   colore passa dal grigio del testo al blu del marchio e un alone si apre e
   si richiude. Una volta sola, al caricamento: un'animazione che si ripete in
   un'intestazione diventa un tic. */
@keyframes monogramma {
  0% {
    opacity: 0;
    transform: translateY(.18em) scale(.72);
    color: var(--ink-3);
    text-shadow: none;
  }
  58% {
    opacity: 1;
    transform: translateY(0) scale(1.12);
    color: var(--brand);
    /* `--ring` e' l'alone blu del marchio, gia' definito nei due temi: sul
       fondo scuro e' piu' opaco, quindi l'alone si vede anche di notte
       senza una seconda regola. */
    text-shadow: 0 0 22px var(--ring);
  }
  100% {
    opacity: 1;
    transform: none;
    color: var(--brand);
    text-shadow: none;
  }
}

/* IL MARCHIO E' ALTO QUANTO IL CLAIM, NON QUANTO UNA RIGA.
   Era un quadrotto da 42 px — 30 sul telefono — accanto a un blocco di due
   righe: piu' piccolo del testo che accompagna, e per giunta allineato in
   alto sul telefono, cosi' che sembrava appoggiato di sbieco sulla prima
   riga invece che messo davanti alla frase.
   L'altezza e' DUE RIGHE del claim, dichiarate in `em` cosi' seguono il
   `clamp` del corpo: 1,45em l'una — non 1,3em, che e' l'interlinea
   nominale, perche' su ogni riga c'e' un'iniziale da 1,46em che alza la
   riga a se'. Due righe perche' due sono le frasi del claim, e sono due in
   tutte e sette le lingue: «Balance your portfolio.» e «Power your
   future.» hanno il punto in mezzo e vanno a capo li'.
   Non `align-self: stretch`, che sarebbe stato la soluzione adattiva ma
   qui si morde la coda: l'immagine ha una dimensione propria (384 x 369) e
   contribuisce all'altezza della riga flex, quindi «riempi la riga» voleva
   dire «riempi te stessa» e il logo cresceva a 369 px trascinandosi dietro
   tutto il blocco.
   La larghezza la ricava `aspect-ratio` dalle proporzioni vere del file,
   quindi il logo non si deforma mai. */
.claim-mark {
  height: 2.9em; width: auto; aspect-ratio: 384 / 369;
  display: block; flex: none;
  animation: marchio 700ms var(--ease) both;
}
/* Il marchio entra per primo e da fermo: e' il punto di partenza da cui le
   due lettere sembrano staccarsi. */
@keyframes marchio {
  from { opacity: 0; transform: scale(.82); }
  to   { opacity: 1; transform: none; }
}

/* Le tre caratteristiche non sono cifre ma benefici: su schermo largo si
   staccano dalla colonna del titolo e diventano un pannello a fianco, così
   la sezione smette di essere una colonna sola e lo spazio orizzontale del
   desktop viene usato per davvero. */
.hero-stats {
  display: flex; flex-direction: column; gap: 1px; list-style: none;
  padding: 0; margin: 0;
  background: var(--line); border: 1px solid var(--line);
  border-radius: var(--r-l); overflow: hidden;
}
.hero-stat { display: flex; flex-direction: column; gap: 3px;
             background: color-mix(in srgb, var(--surface) 92%, transparent);
             padding: var(--s4) var(--s5); }
.hero-stat b { font-family: var(--font-ui); font-size: 15px; letter-spacing: -.012em; color: var(--ink); }
.hero-stat span { font-size: 12.5px; color: var(--ink-3); line-height: 1.45; }

@media (min-width: 1000px) {
  .hero-inner { grid-template-columns: minmax(0, 1.25fr) minmax(280px, .75fr); }
}

/* ---------- testata delle pagine editoriali e di servizio --------------- */
.pagehead { border-bottom: 1px solid var(--line); background: var(--surface);
            background-image: radial-gradient(70ch 30ch at 8% -30%, var(--brand-soft) 0%, transparent 60%); }
.pagehead .wrap { padding-block: clamp(40px, 6vw, 72px); }
.pagehead h1 { max-width: 20ch; }
.pagehead .lede { font-size: clamp(16px, 1.5vw, 18px); color: var(--ink-2); max-width: 60ch; margin-top: var(--s3); }

/* ---------- come funziona: tre passi in fila ----------------------------
   Prima erano tre card identiche in griglia. Ora il numero è dentro un
   pallino viola e una linea sottile lega i tre passi: si legge come un
   percorso, che è quello che sono. */
.steps {
  display: grid; gap: var(--s5); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  list-style: none; margin: 0; padding: 0; counter-reset: passo;
}
/* Il titolo e il corpo sono una cosa sola, il numero e' l'etichetta che gli
   sta davanti: otto pixel fra titolo e testo, sedici fra il numero e il
   titolo. Con tre distanze uguali le tre parti pesavano uguale e la card si
   leggeva come un elenco di tre righe scollegate. */
.step-card { position: relative; display: flex; flex-direction: column; gap: var(--s2); }
.step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--brand); color: var(--on-brand);
  font-family: var(--font-mono); font-size: 14px; font-weight: 600;
  margin-bottom: var(--s2);
}
.step-card h3 { font-size: 16.5px; }
.step-card p { color: var(--ink-2); font-size: 14.5px; }

/* ---------- domande frequenti ------------------------------------------- */
/* Due colonne separate da 64 px e non da 32: il filetto a sinistra di ogni
   domanda e' quello che dice dove comincia una colonna, e con lo stesso
   stacco fra le colonne e fra le righe le due colonne si leggevano come una
   griglia unica di quattro celle per riga. */
.faq { display: grid; gap: var(--s6) var(--s8);
       grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); }
.faq-item { padding-left: var(--s5); border-left: 2px solid var(--line);
            transition: border-color var(--dur) var(--ease); }
.faq-item:hover { border-left-color: var(--brand); }
.faq-item h3 { font-size: 16.5px; margin-bottom: var(--s2); }
.faq-item p { color: var(--ink-2); font-size: 14.5px; }

/* ---------- pagine editoriali (About, Contatti) ------------------------- */
.editorial { display: grid; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); gap: var(--s5); }
.editorial article { display: flex; flex-direction: column; gap: var(--s3); }
/* Le schede usano h2 per non saltare un livello dopo l'h1, ma visivamente
   devono restare titoli di scheda, non di sezione. */
.editorial h2, .editorial h3 { font-size: 16.5px; letter-spacing: -.008em; }
.editorial p { color: var(--ink-2); font-size: 14.5px; }

.contactcard { display: flex; gap: var(--s4); align-items: center; text-decoration: none;
               color: inherit; }
.contactcard:hover { border-color: var(--brand); background: var(--brand-soft); color: inherit; }
.contactcard .txt b { display: block; font-size: 15px; margin-bottom: 2px; }
.contactcard .txt span { font-family: var(--font-mono); font-size: 13.5px; color: var(--brand-ink); }

.disclaimer { border-left: 2px solid var(--line-2); padding-left: var(--s4);
              font-size: 13px; color: var(--ink-3); max-width: 72ch; }

/* ---------- riga d'invito (donazione, richiami) -------------------------- */
.donate { display: flex; gap: var(--s5); align-items: center; justify-content: space-between;
          flex-wrap: wrap; }
.donate .txt b { display: block; font-size: 15px; margin-bottom: 2px; }
.donate .txt p { font-size: 13.5px; color: var(--ink-2); }
.donate .left { display: flex; gap: var(--s4); align-items: center; }

.btn-paypal {
  background: #ffc439; color: #253b80; border-color: #f0b429; font-weight: 600;
  box-shadow: none;
}
.btn-paypal:hover { background: #f2ba36; color: #253b80; }
.btn-paypal svg { height: 17px; width: auto; display: block; }

/* ---------- pagine legali ------------------------------------------------ */
.legal { display: flex; flex-direction: column; gap: var(--s6); max-width: 72ch; }
.legal section { display: flex; flex-direction: column; gap: var(--s3); }
.legal h2 { font-size: 19px; letter-spacing: -.014em; }
.legal p { color: var(--ink-2); font-size: 15px; line-height: 1.68; }

/* ---------- 10b. I MIEI PORTAFOGLI --------------------------------------- */
.pf-gratis {
  display: inline-block; margin-top: var(--s3);
  font-size: 12.5px; color: var(--pos); background: var(--pos-soft);
  padding: 4px 12px; border-radius: var(--r-pill);
}

.pf-elenco { list-style: none; margin: 0; padding: 0;
             display: grid; gap: var(--s5);
             grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr)); }
.pf-voce { display: flex; flex-direction: column; gap: var(--s4); }
.pf-testa { display: flex; align-items: center; justify-content: space-between;
            gap: var(--s4); flex-wrap: wrap; }
.pf-nome { flex: 1; min-width: 220px; }
.pf-nome-testo { display: block; font-size: 18px; letter-spacing: -.014em; }
.pf-meta { flex: 1; min-width: 160px; }
/* «Analizza» si ripete su ogni scheda dell'elenco, e un colore che compare
   cinque volte di fila smette di voler dire «questo conta». Nella lista
   l'azione resta piena ma blu; il viola torna dove è unico — «Confronta»,
   «Salva», il pulsante d'azione della homepage. */
.pf-azione { flex: none; }
.pf-azione .btn-primary { background: var(--brand); color: var(--on-brand); box-shadow: none; }
.pf-azione .btn-primary:hover { background: var(--brand-2); color: var(--on-brand); }
.pf-azioni { display: flex; gap: var(--s2); align-items: center; flex: none; flex-wrap: wrap; }

/* ---------- rinomina in linea -------------------------------------------
   Prima il campo del nome stava sempre aperto in fondo alla scheda: una
   barretta grigia con dentro il nome già scritto, che nessuno capiva a cosa
   servisse finché non provava a premere «Rinomina».
   Ora «Rinomina» apre il campo ESATTAMENTE dove il nome è scritto — stessa
   posizione, stessa dimensione del testo — e la scheda entra in modo
   modifica. Ad aprire e chiudere è una casella nascosta letta da `:has()`,
   quindi funziona anche senza JavaScript; lo script aggiunge solo il fuoco
   sul campo, la selezione del testo e la chiusura con Esc. */
.pf-edit-flag {
  position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.pf-edit-flag:focus-visible + .btn { outline: 2px solid var(--brand); outline-offset: 2px; }

/* A riposo: il nome si vede, il modulo no. */
.pf-rinomina { display: none; }
.pf-voce:has(.pf-edit-flag:checked) .pf-rinomina {
  display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center;
  animation: apri var(--dur) var(--ease) both;
}
.pf-voce:has(.pf-edit-flag:checked) .pf-nome-testo,
.pf-voce:has(.pf-edit-flag:checked) .pf-apri-rinomina { display: none; }
/* In modo modifica la scheda si segnala con il bordo viola — è uno stato
   attivo, non un allarme. Niente alone attorno: l'anello azzurro del fuoco sta
   già sul campo, e due cerchi colorati uno dentro l'altro sono rumore. */
.pf-voce:has(.pf-edit-flag:checked) { border-color: var(--accent); }
/* Mentre si scrive il nome, «Analizza» non è l'azione che si sta per fare:
   si fa da parte e lascia il viola al solo «Salva». */
.pf-voce:has(.pf-edit-flag:checked) .pf-azione .btn {
  background: var(--surface); color: var(--ink);
  border-color: var(--line-2); box-shadow: none;
}
/* Il campo prende la stessa forma del nome che sostituisce. */
.pf-nome-campo {
  flex: 1; min-width: 200px; font-size: 17px; font-weight: 600;
  letter-spacing: -.014em; padding: 8px 12px;
}

.pf-titoli { list-style: none; margin: 0; padding: 0;
             display: flex; flex-wrap: wrap; gap: var(--s2); }
.pf-titoli li {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-pill); padding: 5px 12px; font-size: 12.5px; color: var(--ink);
}
.pf-sim { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3);
          padding-left: 7px; border-left: 1px solid var(--line-2); }

/* I TITOLI DIETRO UNA FRECCIA.
   Venti simboli sotto ogni nome erano quattro righe per scheda in un elenco
   che si scorre. Chiusa, è una riga sola che dice quanti sono; aperta, c'è
   l'elenco e sotto il bottone per cambiarli. È un <details>: funziona anche a
   JavaScript spento, come le altre tendine del sito. */
/* La tendina dei vincoli si apre come quella dei titoli: stessa freccia,
   stesso peso, stessa distanza. Sono due domande gemelle sulla stessa
   scheda — «cosa c'è dentro» e «com'è impostato» — e farle sembrare due cose
   diverse sarebbe peggio che ripetere il selettore. */
.pf-vincoli-tendina { margin-top: var(--s3); }
.pf-vincoli-tendina > summary,
.pf-titoli-tendina > summary {
  cursor: pointer; list-style: none;
  display: inline-flex; align-items: center; gap: var(--s2);
  font-size: 13px; font-weight: 600; color: var(--brand-ink);
}
.pf-vincoli-tendina > summary::-webkit-details-marker { display: none; }
.pf-titoli-tendina > summary::-webkit-details-marker { display: none; }
.pf-vincoli-tendina > summary::after,
.pf-titoli-tendina > summary::after {
  content: ""; flex: none;
  width: 6px; height: 6px; border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor; border-radius: 1px;
  transform: rotate(45deg) translateY(-2px);
  transition: transform var(--dur-s) var(--ease);
}
.pf-vincoli-tendina[open] > summary::after,
.pf-titoli-tendina[open] > summary::after { transform: rotate(225deg) translateY(1px); }
.pf-vincoli-tendina > summary:focus-visible,
.pf-titoli-tendina > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: var(--r-s); }
.pf-vincoli-tendina[open] > summary,
.pf-titoli-tendina[open] > summary { margin-bottom: var(--s3); }
.pf-titoli-modifica { margin-top: var(--s3); }

/* Il piede della scheda: a sinistra cosa contiene, a destra le due azioni
   secondarie. «Elimina» sta il più lontano possibile da «Analizza». */
.pf-strumenti { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: center;
                justify-content: space-between;
                padding-top: var(--s4); border-top: 1px solid var(--line); }

.pf-salva { display: flex; gap: var(--s3); align-items: flex-end; flex-wrap: wrap; }
.pf-salva .field { flex: 1; min-width: 240px; }

/* La conferma del salvataggio, che compare al posto del cambio di pagina.
   Finché è vuota non occupa nulla — nessuno spazio riservato a un messaggio
   che non c'è — e appena lo script ci mette dentro l'esito prende l'aspetto
   degli altri avvisi, perché è la stessa cosa detta nello stesso modo. */
.pf-salva-esito:empty { display: none; }
.pf-salva-esito { margin-top: var(--s3); font-size: 14px; }

.pf-confronto { display: flex; gap: var(--s4); align-items: flex-end; flex-wrap: wrap; }
.pf-confronto .field { flex: 1; min-width: 200px; }

.pf-vuoto { display: flex; flex-direction: column; align-items: center; gap: var(--s4); }
.pf-vuoto p { max-width: 52ch; }

.pf-modelli { list-style: none; margin: 0; padding: 0;
              display: grid; gap: var(--s3);
              grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.pf-modelli li { padding: var(--s3) var(--s4); background: var(--surface-2);
                 border-radius: var(--r-s); border: 1px solid transparent;
                 transition: border-color var(--dur-s) var(--ease); }
.pf-modelli li:hover { border-color: var(--line-2); }
.pf-modelli b { display: block; font-size: 14px; }
.pf-modelli span { font-family: var(--font-mono); }
/* La casella e il nome sullo stesso rigo, il nome che occupa quel che resta:
   la riga intera è cliccabile perché sta dentro la <label>. */
.pf-modelli label { display: flex; align-items: flex-start; gap: var(--s3);
                    cursor: pointer; }
.pf-modelli label > span { flex: 1; min-width: 0; font-family: inherit; }
.pf-modelli input[type="checkbox"] { margin-top: 3px; flex: none;
                                     accent-color: var(--brand); }

/* ---------- 10c. CONFRONTO ----------------------------------------------- */
.cf-contro { color: var(--ink-3); font-weight: 400; }

/* La colonna della differenza NON è colorata di verde o di rosso, ed è una
   scelta: dare un colore di merito a un rendimento passato vorrebbe dire dire
   quale portafoglio è migliore, che è esattamente ciò che questa pagina non
   fa. Resta in evidenza per peso, non per tinta. */
.cf-tabella th[scope="row"] { font-weight: 400; color: var(--ink-2);
                              text-transform: none; letter-spacing: 0;
                              font-family: var(--font-ui); font-size: 13.5px; }
.cf-tabella td { text-align: right; }
.cf-tabella thead th { text-align: right; }
.cf-tabella thead th:first-child { text-align: left; }
.cf-diff { color: var(--ink); font-weight: 500; border-left: 1px solid var(--line); }

/* Il punteggio d'insieme dei due, affiancato. */
.cf-punteggi { display: grid; gap: var(--s5);
               grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.cf-punteggio { display: flex; flex-direction: column; align-items: flex-start;
                gap: var(--s3); padding: var(--s5); border: 1px solid var(--line);
                border-radius: var(--r); background: var(--surface); }
.cf-punteggio-nome { font-size: 14.5px; font-weight: 600; }

/* Il raffronto finale. La frase del verdetto e' l'unica cosa in evidenza del
   blocco: piu' grande del corpo, ma senza colore proprio — il colore qui
   dentro vuol dire gia' «fascia del punteggio», e un secondo significato
   sullo stesso segnale non si legge piu'. */
.cf-verdetto { font-size: 17px; line-height: 1.5; font-weight: 600;
               color: var(--ink); max-width: 62ch; }
.cf-perche { font-size: 14.5px; line-height: 1.6; color: var(--ink-2); max-width: 70ch; }

.cf-insiemi { display: grid; gap: var(--s5);
              grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.cf-insieme h3, .cf-insieme h4 { font-size: 12px; color: var(--ink-3); margin-bottom: var(--s3);
                                 font-family: var(--font-mono); text-transform: uppercase;
                                 letter-spacing: .09em; font-weight: 500; }

/* Chi sono «portafoglio 1» e «portafoglio 2». */
.cf-chi { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2);
          grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.cf-chi li { display: flex; align-items: baseline; gap: var(--s2); flex-wrap: wrap;
             padding: var(--s3) var(--s4); background: var(--surface-2);
             border-radius: var(--r-s); font-size: 13px; color: var(--ink-2); }
.cf-chi b { color: var(--ink); font-size: 13.5px; }

.cf-colonne { display: grid; gap: var(--s6);
              grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.cf-colonna > h3 { font-size: 15px; margin-bottom: var(--s3);
                   padding-bottom: var(--s2); border-bottom: 1px solid var(--line); }

/* Le due analisi complete di un confronto: ognuna è lo stesso blocco di
   risultati, ripetuto riga per riga. Quello che le distingue è l'intestazione,
   che fa da segnale di «qui comincia l'altro» mentre si scorre.
   Lo stacco sotto la barra appiccicata non si dichiara più qui: lo dà
   `scroll-padding-top` sull'intero documento (vedi `--topbar-h`), che vale
   per ogni ancora e non solo per queste tre. */

.analisi-blocco { display: flex; flex-direction: column; gap: var(--s5); }
.analisi-testa {
  display: flex; align-items: center; gap: var(--s4);
  padding: var(--s4) var(--s6); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-l);
  position: relative; overflow: hidden;
}
.analisi-testa::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--brand);
}
.analisi-testa h2 { font-size: clamp(19px, 2.2vw, 24px); letter-spacing: -.018em; }
.analisi-testa p { font-size: 13.5px; color: var(--ink-3); margin-top: 2px; }
.analisi-num {
  flex: none; width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--brand-soft); color: var(--brand-ink);
  font-family: var(--font-mono); font-size: 18px; font-weight: 600;
}

/* ---------- posizioni pubblicitarie -------------------------------------
   Rese solo quando lo slot corrispondente è configurato (vedi
   templates/_annuncio.html). `contain-intrinsic-size` riserva l'altezza in
   anticipo, così l'arrivo dell'annuncio non fa saltare la pagina. */
.ad {
  display: block; margin: var(--s6) auto 0; max-width: 728px; width: 100%;
  padding: var(--s3); border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface-2);
  content-visibility: auto; contain-intrinsic-size: auto 280px;
}
.ad-label {
  display: block; margin-bottom: var(--s2);
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-3);
}
.ad .adsbygoogle { display: block; min-height: 250px; }
.ad--risultati { margin-top: var(--s7); }

/* ---------- 11. UTILITÀ --------------------------------------------------
   Ne restano poche, e sono quelle davvero usate dai template. La revisione ha
   tolto una dozzina di classi che nessuna pagina chiamava più — `.panel`,
   `.pill`, `.grid`, `.skel`, `.explain`, `.measure`, i modificatori delle
   barre — insieme alle regole doppie che le sezioni 12 e 13 del vecchio foglio
   ridichiaravano sopra le prime (hero, claim, allocazione, grafico erano
   scritte due volte, e vinceva l'ultima). */
.tc { text-align: center; }

/* ---------- 12. MOVIMENTO ------------------------------------------------
   Poche animazioni, tutte con lo stesso ritmo, tutte al servizio di una cosa
   sola: far capire che qualcosa è cambiato. Niente decorazione.
   Chi ha chiesto meno movimento al sistema operativo le vede spegnersi tutte
   in fondo a questa sezione. */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes sali {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes cala {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
@keyframes apri {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
@keyframes barra {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
@keyframes chip-entra {
  0%   { opacity: 0; transform: scale(.82); }
  60%  { opacity: 1; transform: scale(1.04); }
  100% { opacity: 1; transform: none; }
}
@keyframes chip-esce {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: scale(.8); }
}
@keyframes pulsa {
  0%   { transform: none; }
  40%  { transform: translateY(-2px); }
  100% { transform: none; }
}

/* Le barre crescono da sinistra. Si anima la scala, non la larghezza: la
   larghezza è scritta nell'attributo style dal server e non va toccata. */
.diversif-fill, .parte-fill, .composiz-fill, .alloc-fill {
  transform-origin: left center;
  animation: barra .7s var(--ease) both;
}

/* Comparsa progressiva dei blocchi principali. Il ritardo è a scaletta e si
   ferma al sesto: oltre, l'attesa si noterebbe. */
.page > .wrap > * { animation: sali var(--dur-l) var(--ease) both; }
.page > .wrap > *:nth-child(1) { animation-delay: 0s; }
.page > .wrap > *:nth-child(2) { animation-delay: .05s; }
.page > .wrap > *:nth-child(3) { animation-delay: .1s; }
.page > .wrap > *:nth-child(4) { animation-delay: .15s; }
.page > .wrap > *:nth-child(5) { animation-delay: .2s; }
.page > .wrap > *:nth-child(n+6) { animation-delay: .25s; }
.hero-testo > *, .hero-stats { animation: sali var(--dur-l) var(--ease) both; }
.hero-testo > *:nth-child(2) { animation-delay: .06s; }
.hero-testo > *:nth-child(3) { animation-delay: .12s; }
.hero-stats { animation-delay: .18s; }

/* Il numero che sale: lo script scrive i valori intermedi, il CSS si limita a
   tenere la cifra ferma nella sua colonna mentre cambia. */
.voto-num { font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .contactcard:hover, .pf-voce:hover, .step-card:hover { transform: none; }
}

/* ---------- 13. RESPONSIVE ----------------------------------------------- */
/* IL GRAFICO SUL TELEFONO
   Qui c'era uno scorrimento laterale: il PNG era largo 828 px con dentro
   etichette da 10 punti, e ridotto a 340 px quelle scritte scendevano sotto i
   cinque pixel — quindi invece di rimpicciolirlo lo si faceva scorrere. Ma
   scorrere vuol dire non vedere mai il grafico intero, e un grafico che non
   si vede intero non serve a niente: la forma della frontiera, la nuvola e i
   due punti hanno senso solo tutti insieme.
   Adesso il PNG e' disegnato stretto e con caratteri grandi (5,6 pollici,
   12 punti), quindi entra per intero in qualunque schermo e non serve nessuna
   regola di scorrimento: `width: 100%` piu' il tetto di 560 px valgono per
   tutti. Qui resta solo la cornice bianca attorno al PNG, che si assottiglia:
   su 390 px di schermo dodici pixel per lato erano il 7% della larghezza
   sottratti al disegno, e il disegno e' l'unica cosa che serve. */
@media (max-width: 700px) {
  .chart img { padding: 5px; }
}

/* La tabella del confronto sul telefono: quattro colonne non entrano in
   360 px. Sotto i 720 px si apre in blocchi — ogni riga diventa una scheda con
   il nome della grandezza in cima e i tre valori sotto, ognuno con la sua
   etichetta presa da `data-col`. Niente scorrimento laterale. */
@media (max-width: 720px) {
  .tablewrap--confronto { overflow-x: visible; border: 0; background: none; }
  .tablewrap--confronto table { min-width: 0; width: 100%; }
  .cf-tabella, .cf-tabella tbody, .cf-tabella tr, .cf-tabella td,
  .cf-tabella th { display: block; }
  .cf-tabella thead { display: none; }
  .cf-tabella tr {
    border: 1px solid var(--line); border-radius: var(--r);
    background: var(--surface); padding: var(--s3) var(--s4);
    margin-bottom: var(--s3);
  }
  .cf-tabella tr:last-child { margin-bottom: 0; }
  .cf-tabella tr:hover { background: var(--surface); }
  .cf-tabella th[scope="row"] {
    padding: 0 0 var(--s2); border-bottom: 1px solid var(--line);
    margin-bottom: var(--s2); color: var(--ink); font-size: 14px;
  }
  .cf-tabella td {
    display: flex; justify-content: space-between; align-items: baseline;
    gap: var(--s4); padding: 5px 0; border: 0; text-align: right;
  }
  .cf-tabella td::before {
    content: attr(data-col); font-family: var(--font-ui); font-size: 12.5px;
    color: var(--ink-3); text-align: left; font-variant-numeric: normal;
  }
  .cf-tabella td.cf-diff {
    border-left: 0; border-top: 1px solid var(--line);
    margin-top: 5px; padding-top: 8px;
  }
}

/* Su schermo stretto le due etichette del segmentato non stanno su una riga:
   invece di spezzare la pillola a metà, i due modi diventano due righe piene. */
@media (max-width: 560px) {
  .segmentato { align-self: stretch; border-radius: var(--r); }
  .segmento { flex: 1 1 100%; }
  .segmento span { border-radius: var(--r-s); text-align: center; }
  /* Il claim in maiuscoletto spaziato va a capo su piu' righe: il marchio si
     allinea in alto, non a meta' del blocco. La misura la decide il `clamp`
     qui sopra, che sul telefono e' gia' al minimo — qui resta solo da
     stringere la spaziatura, che sul piccolo mangia larghezza. */
  /* `align-items` resta `center` come sopra: il marchio e' alto quanto il
     testo, quindi allinearlo in alto lo farebbe solo sbucare sopra la
     prima riga. Qui si stringe soltanto lo spazio fra i due. */
  .claim { gap: 10px; }
  .claim span { letter-spacing: .02em; }
}

@media (max-width: 900px) {
  /* Su schermo stretto la città resta un accenno in fondo: il testo occupa
     tutta la larghezza e non deve mai competere con lo sfondo. */
  .skyline { height: 42%; opacity: .3; }
  .hero-inner { padding-block: clamp(40px, 9vw, 60px); gap: var(--s6); }
}

@media (max-width: 760px) {
  /* La barra qui sotto e' alta due piani invece di uno: le ancore devono
     fermarsi piu' in basso di conseguenza. */
  :root { --topbar-h: 124px; }
  .duecolonne { grid-template-columns: 1fr; }
  .scheda > div { grid-template-columns: 1fr; gap: 2px; }
  .page { padding: var(--s6) 0 var(--s7); }
  .wrap { padding-inline: var(--s4); }
  .card { padding: var(--s5); border-radius: var(--r); }
  .analisi-testa { padding: var(--s4) var(--s5); border-radius: var(--r); }

  /* ── LA TESTATA SUL TELEFONO: DUE PIANI, NON TRE ──────────────────────
     Le sei voci andavano a capo su DUE righe, e «Scarica l'app» — spinto a
     destra dal suo `margin-left: auto` — restava solo in fondo con mezzo
     schermo di vuoto accanto: sembrava un errore di impaginazione. Fra
     quelle due righe e la riga del marchio la barra arrivava a 170 px, e
     siccome e' appiccicata in cima se li teneva per tutto lo scorrimento —
     un quinto di uno schermo da 844 px, su ogni pagina.
     Adesso le voci stanno su una riga sola che si scorre col dito, come le
     schede di un'app: la barra scende a 124 px. Niente e' nascosto dietro
     un menu — «Scarica l'app» in particolare resta SEMPRE visibile perche'
     e' appiccicato al bordo destro del nastro, e le altre voci gli passano
     sotto: e' quel passaggio, con la sfumatura che lo accompagna, a dire
     che il nastro si scorre. */
  .nav {
    order: 3; flex: 1 0 100%; margin-left: 0; flex-wrap: nowrap;
    border-top: 1px solid var(--line); padding-top: var(--s2);
    overflow-x: auto; overflow-y: hidden;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
    /* Il contorno del fuoco non deve finire tagliato dal bordo del nastro. */
    padding-bottom: 3px;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { flex: none; }
  /* Sul telefono la barra è a tinta piena invece che velata: il pulsante
     appiccicato qui sotto deve coprire per davvero le voci che gli passano
     sotto, e la sua tinta piena su un fondo semitrasparente si staccava
     dalla barra come una toppa — poco sul chiaro, molto sul fondo scuro. */
  .topbar { background: var(--surface); backdrop-filter: none; }
  /* Appiccicato al bordo destro del nastro, con il fondo della barra sotto:
     le altre voci gli scorrono sotto invece di sovrapporsi.
     `.nav a.nav-app` e non `.nav-app`: la posizione la dichiara gia'
     `.nav a { position: relative }`, che pesa di piu' e vincerebbe. */
  .nav a.nav-app {
    position: sticky; right: 0; margin-left: var(--s2);
    background: var(--surface);
  }
  /* La voce che passa sotto sfuma invece di essere tagliata a meta' di una
     parola: e' la sfumatura a far leggere il pulsante come qualcosa che sta
     SOPRA il nastro, e quindi il nastro come qualcosa che si scorre. */
  .nav a.nav-app::before {
    content: ""; position: absolute; right: 100%; top: 0; bottom: 0; width: 26px;
    background: linear-gradient(90deg, transparent, var(--surface));
    pointer-events: none;
  }
  .topbar .wrap { flex-wrap: wrap; padding-block: var(--s3); gap: var(--s2); }
  .topbar-end { margin-left: auto; }
  .footer .wrap { flex-direction: column; align-items: flex-start; }
  /* Su schermo stretto i tre numeri restano in fila — sono corti e si
     confrontano solo stando accanto — ma il passo si stringe e il livello
     dello Sharpe va a capo sotto il suo gruppo. */
  .metriche { gap: var(--s2); }
  .metrica-eti { font-size: 10.5px; }
  .voto--hero { padding: var(--s3) var(--s5); }
  .faq-item { padding-left: var(--s4); }
}

@media (max-width: 620px) {
  .pf-testa { flex-direction: column; align-items: stretch; }
  .pf-azioni { width: 100%; }
  .pf-azione, .pf-azione .btn { width: 100%; }
  .pf-nome { min-width: 0; }
  /* Il campo prende tutta la riga e le due azioni vanno sotto, affiancate:
     con «Salva» accanto al campo, «Annulla» finiva da solo su una terza riga. */
  .pf-nome-campo { flex: 1 1 100%; min-width: 0; }
  .diversif-testa { flex-direction: column; }
  .voto-blocco { align-items: flex-start; }
  .voto-etichetta { text-align: left; }
}

@media (max-width: 520px) {
  .composiz-voci li { grid-template-columns: 1fr 52px 44px; }
  .alloc-line { grid-template-columns: 62px 1fr 52px; gap: var(--s2); }
  .donate { flex-direction: column; align-items: stretch; }
}

@media (max-width: 420px) {
  .brand span { display: none; }
  /* Solo i pulsanti che chiudono un modulo diventano pieni: prima lo
     diventavano tutti, comprese le azioni piccole di una scheda. */
  .btn-lg, .btn-block { width: 100%; }
  .row > .btn-lg { width: auto; }
}

/* ---------- 14. STAMPA ---------------------------------------------------- */
@media print {
  .topbar, .footer, .btn, .ad { display: none; }
  body { background: #fff; }
  .card { box-shadow: none; border-color: #ddd; }
  * { animation: none !important; }
}

/* ---------- 14. «SCARICA L'APP» ----------------------------------------- */
/* `hidden` da solo non basta: `display:flex`/`inline-flex` qui sotto lo
   vincerebbe, e un pulsante nascosto ricomparirebbe. */
.installa[hidden], .striscia-app[hidden] { display: none; }
.installa {
  display: inline-flex; align-items: center; gap: 7px;
  white-space: nowrap;
}
.installa svg {
  width: 16px; height: 16px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.9;
  stroke-linecap: round; stroke-linejoin: round;
}

/* LA VOCE IN TESTATA.
   Non e' piu' un pulsante schiacciato in fondo a destra fra la lingua e
   «Registrati» — la' sotto i 720 px perdeva il testo e restava una freccia
   muta. Qui e' una voce di menu come le altre, con il testo sempre leggibile,
   staccata dalle altre dal margine automatico e riconoscibile dalla freccia.
   Porta a /app: il pulsante vero e i passaggi stanno li'. */
.nav-app {
  display: inline-flex; align-items: center; gap: 7px;
  margin-left: auto; white-space: nowrap; font-weight: 500;
  color: var(--brand-ink);
}
.nav-app svg {
  width: 15px; height: 15px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.9;
  stroke-linecap: round; stroke-linejoin: round;
}
.nav a.nav-app:hover { background: var(--brand-soft); color: var(--brand-ink); }

/* LA SCHEDA IN PRIMA PAGINA.
   Icona vera dell'app a sinistra, due righe di testo, il pulsante grande a
   destra. Sta fra «Come funziona» e le domande frequenti, nella colonna del
   contenuto: e' una `.card` come la riga della donazione poco piu' sotto,
   non una fascia a tutta larghezza — quelle spezzano la lettura, e qui la
   lettura e' proprio quello che porta la gente fin qui. */
.striscia-app {
  display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap;
}
/* L'ICONA HA GIA' I SUOI ANGOLI TONDI E LO SFONDO TRASPARENTE.
   Quindi l'ombra va presa dalla FORMA (`drop-shadow`, che segue il canale
   alfa) e non dal riquadro (`box-shadow`, che segue la scatola): con
   `box-shadow` negli angoli trasparenti restava un alone quadrato — visibile
   sul chiaro e ancora di piu' sul fondo scuro, dove sembrava un riquadro
   bianco intorno all'icona. */
.striscia-icona {
  width: 64px; height: 64px; flex: none;
  filter: drop-shadow(0 6px 14px rgba(0, 95, 249, .3));
}
.striscia-testo { flex: 1 1 18rem; min-width: 0; }
.striscia-testo b {
  display: block; font-size: 17px; letter-spacing: -.01em; color: var(--ink);
}
.striscia-testo p {
  margin: 3px 0 0; color: var(--ink-2); font-size: 14.5px; line-height: 1.5;
  max-width: 52ch;
}
.striscia-azioni {
  display: flex; align-items: center; gap: var(--s4); flex: none;
}
.striscia-come { font-size: 14px; color: var(--ink-2); white-space: nowrap; }
.striscia-come:hover { color: var(--brand-ink); }

@media (max-width: 700px) {
  /* Il pulsante prende tutta la riga e «Come si installa» gli va sotto: in
     fila, su schermo stretto, il pulsante si stringeva fino a mandare a capo
     «Scarica l'app» in mezzo alla parola. */
  .striscia-app { gap: var(--s4); }
  /* L'ICONA NON RESTA DA SOLA SULLA SUA RIGA.
     La base del testo era 18rem: su un telefono da 390 px non ci stava
     accanto all'icona, andava a capo, e in cima alla scheda restava un
     quadratino di 52 px con mezzo schermo di vuoto a destra — la parte piu'
     visibile della scheda occupata da niente. Con una base piu' corta icona e
     testo tornano sulla stessa riga, che e' come la scheda e' disegnata. */
  .striscia-testo { flex: 1 1 11rem; }
  .striscia-azioni {
    flex: 1 0 100%; flex-direction: column; align-items: center; gap: var(--s3);
  }
  /* Largo quanto serve e non quanto la riga: a 700 px un pulsante da 670 px
     sembra una barra, non un pulsante. Sul telefono il tetto non morde e
     prende tutta la larghezza, che li' e' giusto. */
  .striscia-azioni .installa {
    justify-content: center; width: 100%; max-width: 22rem;
  }
  .striscia-icona { width: 52px; height: 52px; }
}

/* Le istruzioni per iPhone. `<dialog>` nativo: la finestra modale, il fondo
   scurito e la chiusura con Esc li fa il browser, senza una riga di script. */
.installa-ios {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface); color: var(--ink);
  max-width: 34rem; padding: var(--s5);
  box-shadow: 0 18px 48px rgba(0, 0, 0, .22);
}
.installa-ios::backdrop { background: rgba(6, 12, 20, .55); }
/* Sul telefono il riquadro arrivava a filo dei due bordi dello schermo, con
   gli angoli tondi tagliati a metà dal vetro: sembrava una fascia, non una
   finestra. Un margine, e torna a essere una scheda posata sopra la pagina. */
@media (max-width: 560px) {
  .installa-ios { width: calc(100% - 2 * var(--s4)); margin-inline: var(--s4); }
}
.installa-ios h2 { font-size: 1.15rem; margin: 0 0 var(--s3); }
.installa-ios p { margin: 0 0 var(--s3); line-height: 1.55; }
.installa-ios .muted { font-size: 13.5px; }
.installa-ios b { font-weight: 600; color: var(--brand-ink); }
.installa-ios form { margin: 0; display: flex; justify-content: flex-end; }

/* ---------- 15. LA PAGINA «SCARICA L'APP» ------------------------------- */
/* La scheda in cima: icona grande a sinistra, testo e pulsante a destra —
   l'impaginazione che ha una scheda di uno store, senza fingere di esserlo. */
.app-scheda {
  display: flex; align-items: center; gap: var(--s6); flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); padding: var(--s6);
}
/* Stessa ragione della striscia: l'ombra segue la forma, non la scatola. */
.app-icona {
  width: 132px; height: 132px; flex: none;
  filter: drop-shadow(0 12px 26px rgba(0, 95, 249, .3));
}
.app-testo { flex: 1 1 20rem; display: flex; flex-direction: column; gap: var(--s3); }
.app-testo h1 { margin: 0; }
/* I tre fatti in fila: gratis, non pesa, si aggiorna. Sono la parte che in
   uno store starebbe sotto il nome, ed e' quella che la gente legge. */
.app-fatti {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4);
  font-family: var(--font-mono); font-size: 12px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-3);
}
.app-fatti li { display: flex; align-items: center; gap: 7px; }
.app-fatti li::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--pos); flex: none;
}
.installa-grande { align-self: flex-start; margin-top: var(--s2); }
.installa-grande svg { width: 19px; height: 19px; }
/* `.app-nostore` non esiste piu': la riga che spiegava perche' l'app non sta
   negli store e' stata tolta dalla pagina. */

/* ═══════════════════════════════════════════════════════════════════════
   IL PORTAFOGLIO CHE L'UTENTE HA DAVVERO
   ═══════════════════════════════════════════════════════════════════════
   Lo stesso pannello in tre posti: fra le opzioni facoltative del modulo di
   analisi, sotto le due card del risultato, e dentro «I miei portafogli».
   Le regole qui sotto valgono per tutti e tre, perché i campi sono gli stessi
   (vedi la macro in _mio_campi.html).

   IL VERDE MARCA, NON GIUDICA.
   `--mio` dice «questo sei tu» e nient'altro: non c'è un verde «bene» e un
   rosso «male» su queste tabelle, per la stessa ragione per cui non ce n'è
   sul confronto fra due portafogli. Gli unici due colori di giudizio restano
   `--pos` e `--neg`, e dove compaiono — sul rendimento realizzato — dicono
   soltanto il segno di un numero.
   ═══════════════════════════════════════════════════════════════════════ */
.mio { margin-top: var(--s6); display: flex; flex-direction: column; gap: var(--s5); }
.mio-modulo, .mio-opzione {
  border: 1px solid var(--line); border-radius: var(--r);
  padding: var(--s5); background: var(--surface-quieta);
}
/* Dentro il modulo di analisi il pannello è già in un contenitore di opzioni:
   niente cornice nella cornice, solo lo stacco che hanno gli altri
   interruttori. Quando si accende, la cornice gliela da'
   `.opzioni > :has(.switch-input:checked)`, che è più specifica: è quella la
   regola che vale per tutti e sei, e questo pannello non fa eccezione. */
.opzioni .mio-opzione { border: 0; padding: 0; background: none; }

/* Il pannello è chiuso finché l'interruttore è spento: stessa meccanica dei
   tre interruttori del modulo di analisi, `:has()` e nient'altro. */
.mio-corpo { display: none; }
.mio-modulo:has(.switch-input:checked) .mio-corpo,
.mio-opzione:has(.switch-input:checked) .mio-corpo {
  display: flex; flex-direction: column; gap: var(--s4); margin-top: var(--s4);
  animation: apri var(--dur-l) var(--ease) both;
}

/* ---- LE RIGHE: UN TITOLO, QUANTO NE HAI, QUANTO HA RESO --------------- */
.mio-righe { display: flex; flex-direction: column; gap: var(--s2); }
/* Intestazione scritta una volta sola in cima invece che su ogni riga: venti
   righe con «Quante ne hai» ripetuto venti volte sono rumore. Sparisce sul
   telefono, dove le righe si impilano e ogni campo si porta la sua etichetta. */
/* La terza colonna è il rendimento, ed è la più stretta delle tre pur essendo
   quella che ha più cose dentro: il tasto del segno a sinistra (40 px) e il
   segno di percentuale a destra (42 px) mangiavano 82 dei suoi 108 px, e di
   quello che si scriveva ne restavano visibili due cifre. Adesso la larghezza
   è quella del campo PIÙ i due ornamenti, così il numero si legge per intero
   mentre lo si scrive. */
.mio-intestazione, .mio-riga {
  display: grid; gap: var(--s3); align-items: center;
  grid-template-columns: minmax(0, 1fr) 132px 158px;
}
.mio-intestazione {
  font-size: 11px; color: var(--ink-3); padding-bottom: var(--s2);
  border-bottom: 1px solid var(--line);
}
.mio-intestazione > span:not(:first-child) { text-align: left; }
.mio-riga { padding: var(--s2) 0; border-bottom: 1px solid var(--line); }
.mio-riga:last-child { border-bottom: 0; }
.mio-nome { font-size: 13.5px; font-weight: 600; letter-spacing: -.004em;
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mio-campo { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
/* L'etichetta dentro il campo serve solo dove l'intestazione non c'è: sul
   telefono, e nella riga di un modulo che si apre stretto. */
.mio-eti { font-size: 11px; color: var(--ink-3); display: none; }

/* ---- UN MODO ALLA VOLTA ----------------------------------------------
   Le tre colonne — quantità, importo, percentuale — esistono tutte e tre nel
   documento e il foglio di stile ne mostra una. Senza JavaScript restano
   visibili tutte: il server legge quella indicata dal radio, quindi nessuno
   resta fuori, si vedono solo due campi in più. */
.mio-blocco[data-modo="quantita"] .mio-campo--importo,
.mio-blocco[data-modo="quantita"] .mio-campo--peso,
.mio-blocco[data-modo="quantita"] .mio-eti-importo,
.mio-blocco[data-modo="quantita"] .mio-eti-peso,
.mio-blocco[data-modo="importo"] .mio-campo--quantita,
.mio-blocco[data-modo="importo"] .mio-campo--peso,
.mio-blocco[data-modo="importo"] .mio-eti-quantita,
.mio-blocco[data-modo="importo"] .mio-eti-peso,
.mio-blocco[data-modo="peso"] .mio-campo--quantita,
.mio-blocco[data-modo="peso"] .mio-campo--importo,
.mio-blocco[data-modo="peso"] .mio-eti-quantita,
.mio-blocco[data-modo="peso"] .mio-eti-importo { display: none; }
/* Il valore complessivo serve a un modo solo su tre. */
.mio-blocco[data-modo="quantita"] .mio-valore,
.mio-blocco[data-modo="importo"] .mio-valore { display: none; }
.mio-valore { max-width: 340px; }

/* Il simbolo dell'unità dentro il campo, come nei pesi minimi. */
.mio-quota { position: relative; display: block; }
.mio-quota .input { padding-right: 42px; }
.mio-quota i {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  font-style: normal; font-size: 12.5px; color: var(--ink-3); pointer-events: none;
}
/* Il tasto del segno, dentro il campo del rendimento: su iPhone la tastiera
   decimale non ha il meno, e una perdita non si riuscirebbe a scrivere. Sta a
   sinistra perché è lì che il segno va, davanti al numero. */
.mio-quota--segno .input { padding-left: 40px; }
.mio-segno {
  position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
  border: 0; background: var(--surface-2); color: var(--ink-2);
  font-size: 12px; line-height: 1; padding: 6px 7px; border-radius: var(--r-s);
  cursor: pointer; font-family: var(--font-mono);
}
.mio-segno:hover { background: var(--surface-3); color: var(--ink); }
.mio-segno:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }

.mio-vuoto-avviso { font-size: 13px; color: var(--ink-3); }
/* Con almeno una riga, l'invito a scegliere i titoli non serve più. */
.mio-righe:has(.mio-riga) ~ .mio-vuoto-avviso,
.mio-corpo:has(.mio-riga) .mio-vuoto-avviso { display: none; }

/* ---- LE SCHEDE DEL RISULTATO ----------------------------------------- */
/* Il filetto verde in cima alla card non c'e' piu'. Serviva a dire «questa
   parte parla del tuo portafoglio», ma qui sotto il verde c'e' gia' ovunque —
   occhiello, numeri, etichette — e un bordo in piu' era un secondo segnale per
   una cosa gia' detta. Le card di questa sezione sono card come le altre. */
.eyebrow--mio { color: var(--mio-ink); }
.mio-numeri {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--s5); align-items: start;
}
.num--mio { color: var(--mio-ink); }
.mio-sotto { font-size: 11px; color: var(--ink-3); line-height: 1.4; max-width: 34ch; }

/* Da dove viene il numero e di che momento parla: una riga sola, sotto i
   numeri, mai una nota in fondo alla pagina. */
.mio-quando { font-size: 12.5px; color: var(--ink-2); margin-top: var(--s4);
              display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
              /* La stessa riga porta anche la frase che spiega la base — da
                 dove esce il capitale investito e quale dei tre numeri si
                 muovera' domani — e una frase intera larga tutta la card si
                 legge male: qui vale la stessa misura del resto del testo. */
              max-width: 74ch; line-height: 1.55; }
.mio-badge {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .07em;
  text-transform: uppercase; padding: 3px 8px; border-radius: var(--r-pill);
  white-space: nowrap;
}
/* Dichiarata dall'utente: verde, perché è una cosa che ha fatto lui.
   Calcolata sui prezzi: neutra, perché è una cosa che ha fatto il sito. */
.mio-badge--dich { background: var(--mio-soft); color: var(--mio-ink); }
.mio-badge--calc { background: var(--surface-2); color: var(--ink-3); }

.mio-nota {
  font-size: 12.5px; color: var(--ink-2); line-height: 1.55; max-width: 74ch;
  margin-top: var(--s4); padding-top: var(--s4); border-top: 1px dashed var(--line);
}
.mio-esito { font-size: 13px; color: var(--ink-2); margin-top: var(--s3); }
.mio-esito.is-ok { color: var(--mio-ink); }

/* ---- LE TABELLE CHE NON SCORRONO -------------------------------------
   Una tabella dentro `.tablewrap` scorre di lato: ha una larghezza minima, e
   sotto quella il contenitore mostra una barra. Va bene per la tabella dei
   pesi, che ha cinque colonne di numeri lunghi; non va bene qui, dove il
   punto è vedere le tre colonne INSIEME. Un confronto che costringe a
   scorrere per leggere la terza colonna non è un confronto.

   Quindi: nessun contenitore che scorre, `table-layout: fixed` perché le
   colonne non dipendano dal contenuto, larghezze in percentuale, e sul
   telefono intestazioni corte e caratteri più stretti. Ci sta sempre. */
.tab-fissa {
  width: 100%; table-layout: fixed; border-collapse: collapse;
  font-size: 13.5px; margin-top: var(--s4);
}
.tab-fissa th, .tab-fissa td {
  padding: var(--s3) var(--s2); border-bottom: 1px solid var(--line);
  overflow: hidden; text-overflow: ellipsis;
}
.tab-fissa thead th {
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3);
  text-align: right; vertical-align: bottom; white-space: normal;
  /* Le intestazioni vanno a capo, non si troncano: «Investimento ottimale»
     tagliato a «Ottimal…» non dice piu' che cosa sia quella colonna. Le celle
     dei numeri restano su una riga sola — li' il troncamento non capita, e
     spezzare una cifra sarebbe peggio di tutto. */
  overflow: visible; text-overflow: clip; overflow-wrap: break-word;
}
.tab-fissa thead th:first-child { text-align: left; }
.tab-fissa tbody td {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  text-align: right; white-space: nowrap;
}
.tab-fissa tbody th[scope="row"] {
  text-align: left; font-weight: 500; color: var(--ink-2); font-size: 13px;
  /* Il nome della misura va a capo, non si tronca: «Concentrazione» tagliato
     a «Concentrazi…» e' una riga che non si sa piu' cosa misuri. Le celle dei
     numeri restano su una riga sola, che li' il troncamento non capita. */
  overflow: visible; text-overflow: clip; overflow-wrap: anywhere;
}
.tab-fissa tbody tr:last-child th, .tab-fissa tbody tr:last-child td {
  border-bottom: 0;
}
.tab-fissa .is-pos { color: var(--pos); }
.tab-fissa .is-neg { color: var(--neg); }
/* Le tre colonne dei numeri hanno la stessa larghezza: sono la stessa misura
   detta per tre portafogli, e una più larga suggerirebbe un peso che non ha. */
.tab-tre thead th:not(:first-child) { width: 21%; }
.tab-righe thead th:not(:first-child) { width: 19%; }
.tab-storico thead th:not(:first-child) { width: 30%; }
/* LA COLONNA DEL TUO PORTAFOGLIO NON E' PIU' EVIDENZIATA.
   Aveva fondo verde tenue e un filetto in cima, per staccarla dalle altre
   due. Ma l'intestazione dice gia' «IL TUO», ed e' l'unica delle tre a dirlo:
   il colore non aggiungeva un'informazione, aggiungeva un'enfasi — e in una
   tabella di confronto l'enfasi su una colonna suggerisce che quella sia la
   risposta, che e' esattamente cio' che questa tabella non vuole dire. Resta
   il nome in verde nell'intestazione, che e' il filo con le card sopra.
   Le tre colonne adesso si leggono alla pari, che e' quello che sono. */
.tab-tre thead th.col-mio { color: var(--mio-ink); }
/* Intestazioni lunghe su schermo largo, sigle sul telefono: è il modo di non
   scorrere senza rinunciare a dire cosa sono le colonne. */
.tab-corto { display: none; }

@media (max-width: 720px) {
  .tab-fissa { font-size: 12.5px; }
  .tab-fissa th, .tab-fissa td { padding: var(--s2) 4px; }
  /* Le intestazioni sono in maiuscoletto spaziato: su una colonna larga un
     quinto dello schermo quella spaziatura è l'unica cosa che manda a capo
     «OTTIMALE» dopo la settima lettera. Sul telefono si toglie. */
  .tab-fissa thead th { letter-spacing: 0; font-size: 10px; }
  .tab-lungo { display: none; }
  .tab-corto { display: inline; }
  /* Sul telefono la colonna dei nomi si prende piu'spazio: i numeri
     sono corti, i nomi delle misure no. */
  .tab-tre thead th:not(:first-child) { width: 20%; }
}

@media (max-width: 640px) {
  /* Su telefono il nome del titolo va sopra i campi: tre colonne su uno
     schermo da 340 px non ci stanno, e stringerle vorrebbe dire un campo
     numerico in cui non si legge quello che si sta scrivendo. */
  .mio-intestazione { display: none; }
  .mio-riga { grid-template-columns: 1fr 1fr; }
  .mio-nome { grid-column: 1 / -1; }
  .mio-eti { display: block; }
}

/* ---- «Quanto ne possiedi», dentro I miei portafogli ------------------- */
.pf-reale { margin-top: var(--s4); padding-top: var(--s4); border-top: 1px solid var(--line); }
/* I numeri stanno FUORI dal blocco richiudibile: sono la ragione per cui uno
   torna sulla pagina, e nasconderli dietro un clic vorrebbe dire farsi
   cercare. Dentro il `<details>` resta solo il modulo per correggerli. */
.pf-reale-sintesi {
  background: var(--mio-soft); border-radius: var(--r-s);
  padding: var(--s4); margin-bottom: var(--s3);
  border-left: 3px solid var(--mio);
  display: flex; flex-direction: column; gap: var(--s3);
}
.pf-reale-numeri { display: flex; flex-wrap: wrap; gap: var(--s6); }
.pf-reale-numeri .metrica-num { font-size: clamp(19px, 2.2vw, 25px); }
/* La data non è una quantità: stessa famiglia monospaziata per allineamento,
   corpo più piccolo perché non compete con il valore. */
.metrica-num--data { font-size: 15px !important; color: var(--ink-2); }

.pf-reale-comp { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s3);
                 list-style: none; padding: 0; margin: 0; }
.pf-reale-comp li {
  display: inline-flex; align-items: baseline; gap: 6px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-pill); padding: 3px 10px; font-size: 12.5px;
  max-width: 100%;
}
.pf-reale-tk { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-reale-q { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
              color: var(--ink-2); font-size: 12px; flex: none; }
/* I due pulsanti in fondo al modulo stavano attaccati alla riga di testo che
   li precede, alla stessa distanza che c'è fra due campi: sembravano parte
   della frase invece che la fine del modulo. Un filetto e un respiro sopra
   dicono «le domande sono finite, qui si decide», come in fondo al modulo
   dell'analisi. Lo spazio grande vale solo per la riga che chiude il modulo:
   quella accanto ai numeri — «aggiorna il valore» — resta com'era. */
.pf-reale-azioni { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; }
form > .pf-reale-azioni {
  margin-top: var(--s5); padding-top: var(--s4);
  border-top: 1px solid var(--line);
}

/* Il modulo di modifica: chiuso di suo, e senza JavaScript — `<details>` è
   l'unico elemento che si apre e si chiude da solo in ogni browser. */
.pf-reale-modulo > summary {
  cursor: pointer; font-size: 13px; color: var(--brand-ink); padding: var(--s2) 0;
  list-style-position: inside;
}
.pf-reale-modulo > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.pf-reale-modulo[open] { padding-bottom: var(--s3); }
.pf-reale-modulo .mio-righe { margin-top: var(--s3); }
.pf-reale-modulo .mio-totali { margin-top: var(--s4); }

/* ---- IL MODULO CHE SI RICHIUDE DOPO UN CALCOLO -----------------------
   Con venti titoli scelti, il modulo aperto sono parecchie schermate da
   scorrere prima di arrivare al risultato che si è appena chiesto. Chiuso, è
   una riga che dice cosa contiene e si riapre con un tocco. È un `<details>`,
   quindi funziona anche a JavaScript spento. */
.ottimizza > summary {
  cursor: pointer; list-style: none;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s4);
}
.ottimizza > summary::-webkit-details-marker { display: none; }
.ottimizza > summary h2 { margin: 0; }
/* UN BOTTONE, NON UNA FRECCIA.
   Qui c'era una freccina di 9 px in fondo alla riga: chi arrivava sulla
   pagina dei risultati non capiva che il riquadro chiuso si potesse aprire, e
   quindi non lo apriva. Adesso c'è un bordo, un fondo, un po' di aria e una
   parola dentro — «Modifica» quando è chiuso, «Chiudi» quando è aperto — che
   è il modo in cui si è sempre detto «questo si tocca». La freccia resta,
   accanto alla parola, perché dice l'altra metà: da che parte si va.
   Non è un <button>: sta dentro un <summary>, che il tocco se lo prende già
   tutto lui su tutta la riga. Ne ha solo la forma, ed è la forma che serve. */
.ottimizza-tocca {
  margin-left: auto; flex: none;
  display: inline-flex; align-items: center; gap: var(--s2);
  padding: 8px 14px; border-radius: 999px;
  border: 1px solid var(--brand); background: var(--brand-soft);
  color: var(--brand-ink); font-size: 14px; font-weight: 650; line-height: 1;
  transition: background var(--dur-s) var(--ease);
}
.ottimizza-tocca::after {
  content: ""; flex: none;
  width: 7px; height: 7px; border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor; border-radius: 1px;
  transform: rotate(45deg) translateY(-2px);
  transition: transform var(--dur-s) var(--ease);
}
.ottimizza[open] .ottimizza-tocca::after { transform: rotate(225deg) translateY(1px); }
/* Le due parole stanno tutte e due nell'HTML e se ne vede una sola: così lo
   stato non dipende da JavaScript. */
.ottimizza .tocca-chiudi, .ottimizza[open] .tocca-apri { display: none; }
.ottimizza[open] .tocca-chiudi { display: inline; }
.ottimizza > summary:hover .ottimizza-tocca { background: var(--surface-2); }
.ottimizza > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; border-radius: var(--r-s); }
.ottimizza-conta { font-size: 13px; color: var(--ink-2); }
.ottimizza[open] > summary { margin-bottom: var(--s4); }
/* IL MODULO E' LA COSA PIU' GRANDE DELLA PAGINA E PUO' PERMETTERSI L'ARIA.
   Venti pixel sopra e sotto sono la misura giusta per una card che porta due
   righe di testo; qui dentro ci stanno un campo, una tendina, sei
   interruttori e una tabella di vincoli, e il contenuto arrivava a un dito
   dal bordo. Trentadue tutt'intorno solo da 720 px in su: sul telefono lo
   spazio orizzontale e' proprio quello che manca, e la card lo terrebbe per
   se'. */
@media (min-width: 720px) {
  .ottimizza { padding: var(--s6); }
}
/* Chiuso, il riquadro non deve sembrare una card vuota: il titolo e la riga
   di riepilogo stanno su una sola altezza. */
.ottimizza:not([open]) { padding-top: var(--s5); padding-bottom: var(--s5); }
/* PRIMA DEL PRIMO CALCOLO NON SI CHIUDE.
   Senza risultati in pagina questo modulo è l'unica cosa da fare, ed è
   obbligatorio: il bottone «Chiudi» non viene proprio scritto nell'HTML, e qui
   si spegne anche il tocco sul <summary>, che da solo lo chiuderebbe lo
   stesso lasciando una scheda vuota. Il titolo torna a essere un titolo. */
.ottimizza--fisso > summary { cursor: default; pointer-events: none; }

/* ---- DI QUALE PORTAFOGLIO SONO QUESTI VOTI ---------------------------
   Le tre schede di giudizio misurano i PESI, e in pagina di pesi ce ne sono
   due o tre. Il selettore le fa cambiare AL LORO POSTO: la pagina non si
   allunga di una riga, cambiano i numeri dentro riquadri che stanno già lì.

   Le tre copie sono tutte nell'HTML e se ne vede una: così funziona senza
   JavaScript, come il resto della pagina. Il CSS non cerca i radio per `id`
   — con due analisi in una pagina gli `id` portano un prefisso e una regola
   fissa non li troverebbe — ma per `value`, con `:has()` sul contenitore. */
.giudizio { display: contents; }
/* I RADIO STANNO DENTRO LA BARRA, E LA BARRA È POSIZIONATA.
   Erano figli di `.giudizio`, che è un `display: contents`: un elemento
   assoluto senza `top` dentro un genitore senza scatola prende la posizione
   statica del primo antenato posizionato, cioè della pagina, e finiva in cima
   al documento. Toccare un'etichetta gli dava fuoco, il browser lo portava in
   vista e la pagina saltava all'inizio: la scheda cambiava, ma non la vedeva
   più nessuno. Dentro la barra il fuoco casca dove sta il dito. */
.quale-barra {
  position: relative;
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 5px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--line);
}
.giudizio .quale-radio {
  position: absolute; top: 0; left: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; pointer-events: none; appearance: none;
}
.quale-eti {
  flex: 1 1 auto; text-align: center; cursor: pointer;
  padding: 9px 14px; border-radius: 999px;
  font-size: 14px; font-weight: 600; color: var(--ink-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: background var(--dur-s) var(--ease), color var(--dur-s) var(--ease);
}
.quale-eti:hover { color: var(--ink); }
/* Il pannello scelto si vede, gli altri no. Niente `hidden`: `display:none`
   li toglie anche dal flusso, così non lasciano spazio bianco. */
.giudizio .quale { display: none; }
.giudizio:has(.quale-radio[value="mio"]:checked) .quale[data-quale="mio"],
.giudizio:has(.quale-radio[value="opt"]:checked) .quale[data-quale="opt"],
.giudizio:has(.quale-radio[value="min"]:checked) .quale[data-quale="min"] {
  display: contents;
}
.giudizio:has(.quale-radio[value="mio"]:checked) .quale-eti[data-quale="mio"],
.giudizio:has(.quale-radio[value="opt"]:checked) .quale-eti[data-quale="opt"],
.giudizio:has(.quale-radio[value="min"]:checked) .quale-eti[data-quale="min"] {
  background: var(--surface); color: var(--ink); box-shadow: var(--shadow-s);
}
/* Il portafoglio dichiarato tiene il suo verde anche qui: è lo stesso colore
   della sua card in cima e della sua colonna nella tabella. */
.giudizio:has(.quale-radio[value="mio"]:checked) .quale-eti[data-quale="mio"] {
  color: var(--mio-ink);
}
/* Con un solo portafoglio in pagina il selettore non c'è, e l'unico pannello
   deve vedersi lo stesso: senza radio dentro, nessuna delle regole `:has()`
   sopra scatta. */
.giudizio:not(:has(.quale-radio)) .quale { display: contents; }
/* Il fuoco da tastiera si vede sulla barra: i radio sono dentro, quindi non
   sono più fratelli di quella e la si prende con `:has()`. */
.quale-barra:has(.quale-radio:focus-visible) {
  outline: 2px solid var(--brand); outline-offset: 3px;
}

/* ---- LE ETICHETTE DELLE RIGHE, LUNGHE E CORTE ------------------------
   «Quanto è diversificato questo portafoglio» su uno schermo da 390 px o va a
   capo tre volte o si tronca. Su schermo largo si legge per intero, sul
   telefono diventa «Diversificazione»: stessa riga, stesso significato, e
   nessun numero che si spezza per far posto al testo. */
.tab-fissa tbody th[scope="row"] .tab-corto { display: none; }
@media (max-width: 720px) {
  .tab-fissa tbody th[scope="row"] .tab-lungo { display: none; }
  .tab-fissa tbody th[scope="row"] .tab-corto { display: inline; }
}

/* ---- LA TABELLA PER TITOLO, SUL TELEFONO, DIVENTA UNA SCHEDA ----------
   Cinque colonne su 390 px vogliono dire importi troncati a «9.433…», che
   non è un numero: è il posto dove c'era un numero. Sotto i 640 px ogni riga
   diventa un blocco — il nome per intero in cima, i quattro valori sotto con
   la loro etichetta — e ogni cifra si legge tutta.

   Solo per `.tab-righe`: il confronto a tre colonne ci sta e resta tabella,
   che è il modo giusto di leggere tre valori affiancati. */
@media (max-width: 640px) {
  .tab-righe, .tab-righe tbody, .tab-righe tr, .tab-righe th, .tab-righe td {
    display: block; width: auto;
  }
  .tab-righe thead { display: none; }
  .tab-righe tr {
    padding: var(--s3) 0; border-bottom: 1px solid var(--line);
  }
  .tab-righe tr:last-child { border-bottom: 0; }
  .tab-righe tbody th[scope="row"] {
    font-size: 14px; font-weight: 600; color: var(--ink);
    border: 0; padding: 0 0 var(--s2);
  }
  .tab-righe td {
    display: flex; justify-content: space-between; align-items: baseline;
    gap: var(--s3); border: 0; padding: 3px 0; font-size: 13px;
  }
  /* L'etichetta che nell'intestazione non c'è più. */
  .tab-righe td::before {
    content: attr(data-eti); font-family: var(--font-ui);
    font-size: 12px; color: var(--ink-3); font-variant-numeric: normal;
  }
}

/* --- LA SALA D'ATTESA -----------------------------------------------------
   Il numero della posizione in fila. E' grande perche' e' l'unica cosa che
   chi aspetta vuole sapere, ed e' l'unico indicatore che ci sia: non c'e'
   nessuna barra di avanzamento, perche' nessuno sa quanto durera' l'analisi
   di chi sta davanti e una barra inventata sarebbe peggio del silenzio. */
.coda-numero {
  font-size: 64px; line-height: 1; font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--brand-ink);
  text-align: center; padding: var(--s3) 0;
}
/* Chi ha chiesto di non vedere animazioni non deve vedere nemmeno questa. */
@media (prefers-reduced-motion: no-preference) {
  .coda-numero { transition: opacity .2s ease; }
}

/* --- L'ELENCO DEI TITOLI CON SERIE ESTESA ---------------------------------
   Era srotolato dentro la frase e su un paniere grande diventava tre righe
   di nomi in mezzo a una scheda che parla d'altro. La frase resta, i nomi
   si aprono a richiesta. La freccetta e' quella del browser: una freccia
   disegnata a mano sarebbe una cosa in piu' da mantenere e da tradurre per
   i lettori di schermo, che questa la annunciano gia' per conto loro. */
.dettaglio-estesi > summary {
  cursor: pointer;
  list-style-position: outside;
}
.dettaglio-estesi > summary:focus-visible {
  outline: 2px solid var(--ring); outline-offset: 2px; border-radius: 3px;
}
.dettaglio-estesi > .pf-titoli { margin-top: var(--s2); }

/* --- QUALE PORTAFOGLIO C'E' IN QUESTA COLONNA -----------------------------
   Sotto il nome della colonna, minuscolo: da quando si puo' scegliere fra
   ottimale, rischio minimo e il proprio, due colonne di numeri non sono piu'
   per forza due ottimali — e leggerle come tali sarebbe l'errore che questa
   riga esiste per impedire. */
.cf-tipo {
  display: block; font-weight: 400; font-size: 12px;
  color: var(--ink-3); letter-spacing: .01em;
}
/* Le due tendine che scelgono cosa confrontare, affiancate quando c'e' posto. */
.confronta-tipi {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s3); margin-top: var(--s3);
}
