/* Susan Landing Page
 *
 * ⚠️ I caratteri sono OSPITATI QUI, non presi da Google Fonts (cambiato il 2026-08-09).
 * Un <link> a fonts.googleapis.com fa arrivare l'indirizzo IP di ogni visitatore ai server
 * di Google prima ancora che possa dire di sì: è esattamente il trasferimento che il GDPR
 * vuole consentito, ed è ciò che obbligherebbe il sito a un banner di consenso vero (con
 * "rifiuta") invece di un semplice avviso. Ospitandoli qui non parte più nessuna richiesta
 * verso terzi, e la pagina è pure più veloce (niente due connessioni in più da aprire).
 *
 * I file stanno in `css/fonts/` e il build ne fa una copia in
 * `wordpress-plugin/assets/fonts/`. Gli `url()` qui sotto sono RELATIVI apposta: un url in
 * un CSS si risolve rispetto al FOGLIO, non alla pagina, quindi la stessa riga funziona sia
 * in locale (`css/fonts/…`) sia online (`…/plugins/susan-editor/assets/fonts/…`). Non
 * metterci un indirizzo assoluto: in locale diventerebbe una richiesta cross-origin e i
 * caratteri non si vedrebbero.
 *
 * Sono i sottoinsiemi latin + latin-ext degli stessi Cinzel e Cormorant di prima (licenza
 * SIL Open Font License, ridistribuibili). `unicode-range` fa scaricare solo ciò che serve.
 * Per rigenerarli: `node scripts/fetch-fonts.mjs`.
 */
@font-face {
    font-family: 'Cinzel';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/cinzel-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Cinzel';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/cinzel-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Cormorant';
    font-style: italic;
    font-weight: 300 400;
    font-display: swap;
    src: url('fonts/cormorant-italic-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Cormorant';
    font-style: italic;
    font-weight: 300 400;
    font-display: swap;
    src: url('fonts/cormorant-italic-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Cormorant';
    font-style: normal;
    font-weight: 300 400;
    font-display: swap;
    src: url('fonts/cormorant-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Cormorant';
    font-style: normal;
    font-weight: 300 400;
    font-display: swap;
    src: url('fonts/cormorant-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* ============================
   Design tokens
   ============================
   The glow used to be hand-typed at every call site, which is why it drifted: the body
   lines carried the same four-layer halo as the titles, while ABOUT had almost none.
   Three steps, declared once — headings the most, body a hint, the CTA its own gold. */
:root {
    --c-cyan: #85F5FF;
    --c-gold: #F0D680;

    --glow-heading:
        0 0 10px #85F5FF,
        0 0 22px rgba(133, 245, 255, .75),
        0 0 45px rgba(133, 245, 255, .45),
        0 0 85px rgba(133, 245, 255, .25);
    --glow-body:
        0 0 6px rgba(133, 245, 255, .45),
        0 0 16px rgba(133, 245, 255, .22);
    --glow-cta:
        0 0 12px rgba(240, 214, 128, .95),
        0 0 30px rgba(240, 214, 128, .65),
        0 0 60px rgba(240, 214, 128, .40);
    --glow-cta-hover:
        0 0 18px rgba(240, 214, 128, 1),
        0 0 42px rgba(240, 214, 128, .80),
        0 0 75px rgba(240, 214, 128, .50);

    /* The veil over the photo. Lower = brighter background.
       Nasce scuro perché la foto è ricca di dettaglio chiaro e il testo bianco con alone
       ciano ci si perdeva dentro. Alzarlo sopra ~.75 e la foto sparisce.
       Schiarito due volte il 2026-08-07, del 15% ogni volta: .64 → .544 → .4624.
       ⚠️ Sotto questo valore l'acqua torna a contendere la scena al testo: se si scende
       ancora, va ricontrollata la leggibilità delle righe hero, non solo la foto. */
    --veil: rgba(1, 17, 38, 0.4624);

    /* I blocchi di testo. Il sito è cresciuto a pezzi e ogni blocco aveva la sua larghezza,
       il suo corpo e il suo colore: «A STORY FROM THE DEEP» largo 1400px accanto a un ABOUT
       da 845, 2.3rem contro 2rem, ciano con alone contro ciano senza. Tre token, dichiarati
       una volta, usati da tutti — così restano uguali anche fra sei mesi.
       ⚠️ `--c-body` è il ciano più bianco delle vecchie descrizioni dei capitoli: sopra
       l'acqua chiara legge senza bisogno dell'alone, che sui titoli invece resta. */
    --tw-body: 860px;
    --fs-body: 2rem;
    --c-body: #b9f9ff;

    --divider-w: 220px;
    /* Altezza della barra incollata, usata dalle ancore per non finirci sotto.
       ⚠️ Misurata, non stimata: 64px era 4px meno del vero (60px di voci + i due filetti
       dorati), e ABOUT/CONTACT atterravano con la prima riga mezza coperta. Sul telefono la
       barra è più bassa, quindi qui avanza solo un po' d'aria — che non fa danno. */
    --nav-h: 72px;
}

*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html, body {
    width: 100%;
    min-height: 100vh;
    font-family: 'Cinzel', serif;
    color: #ffffff;
}

/* ⚠️ Due difetti che si vedono SOLO su un telefono vero, non nel simulatore:
   1. iOS Safari e Chrome Android ingrandiscono da soli il testo dei blocchi stretti quando
      si ruota in orizzontale ("text inflation"). Le tre righe dell'hero uscivano dallo
      schermo e nessun media query lo spiegava. Va dichiarato col prefisso E senza: Safari
      conosce solo la forma -webkit-.
   2. Il riquadro grigio che lampeggia al tocco su ogni link è il default di WebKit. Spento
      del tutto toglie ogni riscontro al dito, quindi diventa un lampo ciano del sito. */
html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

/* Niente rimbalzo, né in cima né in fondo. Sul telefono la pagina si trascinava oltre la
   fine e sotto l'ultima riga compariva una striscia di fondo — un vuoto che sembrava un
   pezzo mancante di sito, non un effetto. Spegne anche il "tira per aggiornare" di Chrome
   Android, che su una pagina lunga scattava per sbaglio.
   ⚠️ Il valore che conta è quello su <html>: è la radice a propagarlo alla finestra. Su
   <body> da solo non fa niente, ma tenerlo anche lì è la ricaduta per i browser che
   guardano ancora il vecchio contenitore. Diverso da `overflow-x: hidden`, che su <html>
   invece romperebbe la barra incollata (vedi il commento più in basso). */
html, body { overscroll-behavior: none; }

/* ⚠️ Il pizzico che RIMPICCIOLISCE è la radice di due difetti che sembravano diversi:
   la pagina in miniatura fra due bande di colore, e la foto di sfondo che «si ringrandisce»
   al primo scorrimento (su iOS, a pagina rimpicciolita, i livelli `position: fixed` si
   riagganciano alla finestra VISIVA appena si scorre: lo sfondo scatta da grande-quanto-il-
   layout a grande-quanto-lo-schermo). Il meta viewport non li ferma su iOS — vedi il
   commento lì e initPinchGuard in js/susan-app.js, che è la terza gamba di questo rimedio.
   Qui basta dichiararlo sulla RADICE: il gesto consentito è l'intersezione fra l'elemento
   toccato e tutti i suoi antenati, quindi togliere `pinch-zoom` a <html> lo toglie ovunque.
   `pan-x pan-y` lascia passare lo scorrimento in tutte e due le direzioni; cade insieme al
   pizzico anche lo zoom col doppio tocco, che per il browser è lo stesso gesto. */
html { touch-action: pan-x pan-y; }

a, button, input, summary, [role="button"] {
    -webkit-tap-highlight-color: rgba(133, 245, 255, .16);
}

/* Il colore di sicurezza sta SOLO su <html>, che lo propaga alla tela della pagina.
   ⚠️ Se lo si rimette anche su body, la foto sparisce e nessuno capisce perché: il layer
   .susan-bg è `z-index: -1`, quindi nell'ordine di disegno viene PRIMA degli sfondi dei
   blocchi — e lo sfondo opaco di body, disegnato dopo, lo copre per intero. Era esattamente
   il bug: sembrava che l'immagine non fosse mai stata messa.

   ⚠️ Questo colore NON è una formalità: è tutto ciò che si vede fuori dalla finestra di
   layout. `.susan-bg` è `position: fixed`, quindi copre la finestra di LAYOUT, non quella
   VISIVA: appena si pizzica per rimpicciolire — e su iOS si può, `minimum-scale` viene
   ignorato per accessibilità dal 2016 — la pagina si rimpicciolisce e attorno resta questa
   tinta. Col vecchio blu quasi nero (#011126) sembrava una figurina appoggiata su una
   lastra scura; è il difetto delle «bande blu». Ora il valore è la MEDIA della foto GIÀ
   velata (media #094c58 sotto il velo `--veil`), quindi fuori dal bordo l'acqua sembra
   continuare invece di finire di netto. Cambiando `--veil` o la foto, va ricalcolato. */
html { background-color: #053141; }
body { background-color: transparent; }

/* Il renderer scrive width/height sulle immagini (per non far saltare il layout mentre
   caricano). Quegli attributi valgono come regole CSS a specificità zero: se il foglio
   imposta solo la larghezza, l'altezza resta quella dell'attributo e l'immagine si
   deforma — è così che le cover Part I/II erano diventate 480×960. Una riga qui lo
   impedisce per QUALSIASI immagine, comprese quelle che aggiungeremo domani. */
img { height: auto; }

/* The background is its own fixed layer instead of a property of html/body.
   `background-attachment: fixed` is disabled on mobile browsers, so on a phone the image
   was anchored to the top of the DOCUMENT: it scrolled away and ended in a hard horizontal
   edge right after the first section. A fixed element with `cover` stays put everywhere,
   and one rule closes all three of Susan's mobile background complaints. */
/* ⚠️ La striscia scura che compariva in fondo allo schermo su Android è QUESTA regola, per
   due motivi che sommandosi sembravano un difetto della foto:
   1. `inset: 0` rende il riquadro alto quanto la finestra CORRENTE. Mentre la barra
      dell'indirizzo si ritira lo schermo cresce in basso più in fretta di quanto il layer
      fisso venga ricalcolato, e per quei ~56px si vedeva il `#011126` di <html>. `lvh` è
      l'altezza GRANDE — quella a barra nascosta — quindi il riquadro è già alto abbastanza
      e non deve inseguire niente. La riga `vh` prima resta come ricaduta.
   2. Con `z-index: -1` il livello sta sotto a tutto il contenuto che scorre: senza un
      contesto di composizione suo, Chrome lo ridipinge a ogni fotogramma e durante uno
      scorrimento veloce il bordo che avanza resta un attimo non dipinto. `translateZ(0)`
      lo promuove a livello del compositore e la ridipintura sparisce.
   ⚠️ La stessa misura va data al velo `body::after`, che ha la stessa geometria: sistemando
   solo lo sfondo la banda smette di essere blu e diventa una striscia di foto SENZA velo,
   più difficile ancora da riconoscere come lo stesso difetto.
   ⚠️ NIENTE `will-change: transform` qui, e non è una pulizia: su iOS era il motivo per cui
   la foto SI RINGRANDIVA scorrendo. Questo livello non si anima mai — la dichiarazione
   diceva al browser il contrario, e lui teneva in memoria un'immagine già disegnata a una
   certa misura. Quando la barra dell'indirizzo si ritira, Safari non ridisegna il livello:
   SCALA quella copia. Il risultato è una foto che cresce e si sfoca per un istante a ogni
   scorrimento. `translateZ(0)` da solo tiene il livello separato (che è ciò che serviva
   contro la striscia di Android) senza congelarne il disegno. */
.susan-bg {
    position: fixed;
    inset: 0;
    height: 100vh;
    height: 100lvh;
    z-index: -1;
    pointer-events: none;
    transform: translateZ(0);
    /* La media della foto NUDA. Sotto il velo dà esattamente la tinta di <html>, così finché
       la webp non è arrivata (o fuori dal bordo, se si pizzica) la tela è tutta dello stesso
       colore invece di mostrare un rettangolo più scuro grande quanto la finestra. */
    background-color: #094c58;
    background-image: url('https://devouredaudionovel.com/wp-content/plugins/susan-editor/assets/img/bg-2560.webp');
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
}

/* Phones get the 1280-wide copy: a third of the bytes, indistinguishable at that size. */
@media (max-width: 900px) {
    .susan-bg {
        background-image: url('https://devouredaudionovel.com/wp-content/plugins/susan-editor/assets/img/bg-1280.webp');
    }
}

/* Stessa geometria di `.susan-bg` e stesse due misure: vedi il commento lì sopra —
   `will-change` tolto anche qui, o il velo si scalerebbe per conto suo e la foto sotto no. */
body::after {
    content: '';
    position: fixed;
    inset: 0;
    height: 100vh;
    height: 100lvh;
    background: var(--veil);
    pointer-events: none;
    transform: translateZ(0);
    z-index: 1;
}

/* Drifting motes. One canvas, no pointer input — see initParticles().
   Fisso e sempre acceso: le particelle appartengono a tutta la pagina, non solo alla
   testata, quindi continuano a salire anche in fondo ai capitoli e al contatto. */
.susan-particles {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 100;
    opacity: 1;
}

/* Anchored sections must clear the sticky navbar when jumped to. */
#about, #contact, #listen { scroll-margin-top: var(--nav-h); }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

.susan-section {
    position: relative;
    z-index: 2;
}


/* ⚠️ `100vh` sul telefono NON è l'altezza che si vede: è quella che si vedrebbe con la barra
   dell'indirizzo nascosta. Con la barra a schermo l'hero è più alto della finestra e il
   bottone play finisce sotto il bordo — sembra che manchi. `svh` è la misura piccola, quella
   garantita. La riga `vh` resta prima come ricaduta per i browser che non conoscono `svh`. */
.susan-hero {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 2rem;
    min-height: 100vh;
    min-height: 100svh;
    color: #85F5FF;
}

.susan-container {
    max-width: 1200px;
    width: 100%;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    min-height: 100vh;
    min-height: 100svh;
    justify-content: flex-start;
}

/* ⚠️ Il logo ora sta dentro un <a> (ritorno alla home), e questo cambia CHI misura cosa.
   La larghezza in percentuale dell'immagine si misurerebbe sull'ancora, non più sul
   contenitore dell'hero: lasciata sull'<img>, il logo si rimpicciolirebbe a ogni breakpoint.
   Perciò le misure stanno sull'ANCORA (`.susan-logo-home`, che tutti i media query qui sotto
   regolano insieme a `.susan-logo`) e l'immagine dentro si limita a riempirla. */
.susan-logo-home,
.susan-logo {
    max-width: 600px;
    width: 100%;
    margin-top: 28vh;
}

.susan-logo-home {
    display: block;
    text-decoration: none;
    line-height: 0;
}

/* Dentro l'ancora l'immagine non ha più misure sue: le prende dal genitore, che è
   esattamente l'area cliccabile. Il margine è già sull'ancora, qui va azzerato o si somma. */
.susan-logo-home > .susan-logo {
    width: 100%;
    max-width: 100%;
    margin-top: 0;
}

.susan-logo {
    height: auto;
    transform: translateY(-50%);
    animation: susanLogoEmerge 3s ease-out forwards;
}

.footer-home {
    display: inline-block;
    line-height: 0;
    text-decoration: none;
}

@keyframes susanLogoEmerge {
    0% {
        opacity: 0;
        transform: translateY(-50%) scale(1.15);
    }
    100% {
        opacity: 1;
        transform: translateY(-50%) scale(1);
    }
}

.susan-texts {
    margin-top: 0;
}

@media (max-width: 768px) {
    .susan-texts {
        margin-top: 200px;
    }
}

.susan-text {
    font-family: 'Cinzel', serif;
    font-weight: 400;
    letter-spacing: 0.3em;
    color: #ffffff;
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 1s ease-out, transform 1s ease-out;
}

.susan-text.visible {
    opacity: 1;
    transform: translateY(0);
    color: #85F5FF;
    text-shadow: var(--glow-heading);
}

.susan-svg-filters {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.susan-text-1 {
    font-size: 1rem;
}

.susan-text-2 {
    font-size: 2rem;
    margin-top: 9rem;
}

.susan-text-3 {
    font-size: 2.5rem;
    margin-top: 9rem;
    animation-delay: 1.9s;
}

/* Play Button */
.susan-player {
    margin-top: 9rem;
    margin-bottom: 100px;
}

@keyframes susanFloat {
    0% { transform: translateY(0); }
    50% { transform: translateY(-8px); }
    100% { transform: translateY(0); }
}

/* ============================
   Pallini della testata (solo desktop)
   ============================
   Quattro pallini, e valgono SOLO per la prima sezione: uno per ognuna delle tre righe che
   compaiono scorrendo, il quarto per il bottone play. Non sono più un indice delle sezioni —
   quel lavoro lo fa già la barra del menu, e averlo in due posti diceva due volte la stessa
   cosa. Finita la testata spariscono (`.is-gone`, scritto dal JS).
   `z-index: 400` è scelto, non casuale — sopra le sezioni (2), il velo (1) e le particelle
   (100), sotto la barra del menu (500) e i modali legali (1000).
   ⚠️ L'area toccabile è il BOTTONE da 44px; il pallino visibile è il ::before da 10. La
   vecchia versione dipingeva pallini da 6-8px con 22px fra i centri: sotto il minimo di 24
   di WCAG 2.2 §2.5.8, che verify-live.mjs ora misura davvero. */
.susan-scroll-dots {
    position: fixed;
    top: 50%;
    right: 18px;
    transform: translateY(-50%);
    z-index: 400;
    /* Accesi dal JS: senza JavaScript non porterebbero da nessuna parte. */
    display: none;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    transition: opacity .45s ease, visibility .45s ease;
}
.susan-scroll-dots.is-ready { display: flex; }

/* ⚠️ Si spengono con opacity+visibility, NON con `display: none`: da `flex` a `none` non
   c'è transizione, e sparirebbero di scatto proprio mentre la barra del menu si incolla.
   `visibility` toglie i bottoni anche al Tab, che `opacity: 0` da sola non fa. */
.susan-scroll-dots.is-gone {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

.susan-scroll-dot {
    position: relative;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

.susan-scroll-dot::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 10px;
    height: 10px;
    margin: -5px 0 0 -5px;
    border-radius: 50%;
    border: 1px solid rgba(133, 245, 255, .5);
    transition: background .3s ease, border-color .3s ease, box-shadow .3s ease;
}

.susan-scroll-dot:hover::before {
    border-color: rgba(133, 245, 255, .9);
    box-shadow: 0 0 10px rgba(133, 245, 255, .45);
}

/* Lo stato attivo sta su aria-current, non su una classe: il pallino pieno e ciò che un
   lettore di schermo annuncia ("corrente") sono la stessa informazione, scritta una volta. */
.susan-scroll-dot[aria-current="true"]::before {
    background: #85F5FF;
    border-color: #85F5FF;
    box-shadow: 0 0 10px rgba(133, 245, 255, .6), 0 0 22px rgba(133, 245, 255, .35);
}

/* Le righe già comparse restano segnate, ma spente: la colonna racconta a che punto è la
   sequenza, non solo dove si è adesso. */
.susan-scroll-dot.is-done::before {
    background: rgba(133, 245, 255, .5);
    border-color: rgba(133, 245, 255, .5);
}

.susan-scroll-dot:focus-visible {
    outline: 2px solid rgba(133, 245, 255, .8);
    outline-offset: -8px;
    border-radius: 50%;
}

/* Un pallino la cui sezione non esiste si nasconde invece di puntare nel vuoto. */
.susan-scroll-dot.is-missing { display: none; }

/* Sul telefono spariscono, e non è una rinuncia: duplicherebbero la barra del menu — già
   incollata in alto e con le stesse voci — occupando l'11% di uno schermo da 390px, proprio
   nella colonna dove il carosello ascolta il dito per sfogliare le parti.
   ⚠️ `!important`: `.susan-scroll-dots.is-ready` ha due classi e vincerebbe. */
@media (max-width: 768px) {
    .susan-scroll-dots { display: none !important; }
}
/* Il telefono coricato è largo (844, 932…) ma bassissimo: cade fuori dal breakpoint qui
   sopra e i pallini tornerebbero, su uno schermo alto 390px. */
@media (max-height: 500px) and (orientation: landscape) {
    .susan-scroll-dots { display: none !important; }
}

/* Navbar */
.susan-navbar-wrapper {
    position: relative;
    z-index: 500;
}

/* ⚠️ Chi si incolla è la SEZIONE, non lo <header> dentro.
   `position: sticky` non porta mai un elemento fuori dalla scatola del suo genitore: il
   <header> stava dentro una <section> alta quanto lui, quindi si "incollava" per zero pixel
   e spariva col resto della pagina — sembrava che sticky non funzionasse affatto.
   Incollando la sezione (che è figlia diretta di #susan-root, alto tutta la pagina) la barra
   resta in cima per davvero da quando la si raggiunge in poi. */
.susan-blk[data-sbt="navbar"] {
    position: sticky;
    top: 0;
    z-index: 500;
}

.susan-navbar {
    text-align: center;
    width: 100%;
    z-index: 500;
    background: transparent;
    backdrop-filter: blur(30px) saturate(1.2);
    -webkit-backdrop-filter: blur(30px) saturate(1.2);
    transition: background .35s ease, box-shadow .35s ease;
}

/* Una volta staccata dal flusso serve un fondo suo: sopra la foto, il testo delle voci si
   confondeva con l'acqua chiara mentre le sezioni le scorrevano sotto. */
.susan-navbar.is-stuck {
    background: rgba(1, 17, 38, 0.82);
    box-shadow: 0 6px 28px rgba(0, 0, 0, .45);
}

.susan-navbar-line {
    width: 80%;
    margin: 0 auto;
    height: 2px;
    background: linear-gradient(90deg, transparent 0%, rgba(180, 155, 80, 0.15) 10%, rgba(201, 185, 122, 0.6) 35%, rgba(240, 214, 128, 1) 50%, rgba(201, 185, 122, 0.6) 65%, rgba(180, 155, 80, 0.15) 90%, transparent 100%);
    position: relative;
    border-radius: 50%;
}

.susan-navbar-glow {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 40px;
    height: 3px;
    border-radius: 50%;
    background: rgba(255, 240, 200, 0.6);
    box-shadow: 0 0 8px 2px rgba(240, 214, 128, 0.4);
}

.susan-navbar-links {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem 0;
    background: transparent;
}

/* ⚠️ L'area toccabile di una voce era alta quanto il testo (22px), non quanto la barra: su
   un tablet bisognava centrare la parola. `min-height` + centratura la portano a 44px SENZA
   cambiare l'altezza della barra — i 19px di padding che la riga sopra ha perso tornano qui
   dentro, quindi il totale resta quello di prima. Un padding verticale su un <a> inline non
   basterebbe; qui però le voci sono figlie di un flex container, quindi sono già blocchi. */
.susan-navbar-link {
    font-family: 'Cinzel', serif;
    font-weight: 400;
    font-size: 1rem;
    letter-spacing: 0.25em;
    color: #85F5FF;
    text-decoration: none;
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0 2rem;
    transition: color 0.3s ease, text-shadow 0.3s ease;
    text-shadow: 0 0 15px rgba(133, 245, 255, 0.5), 0 0 40px rgba(133, 245, 255, 0.25), 0 0 60px rgba(133, 245, 255, 0.1);
}

/* ⚠️ Il valore di riposo qui sopra è 15/40/60px di alone: la vecchia riga di hover ne
   metteva UNO da 8px, cioè il menu si SPEGNEVA quando ci passavi sopra. Ogni valore qui
   dentro va tenuto sopra a quello di riposo, o il bug torna senza farsi notare. */
.susan-navbar-link:hover {
    color: #eafeff;
    text-shadow: 0 0 12px rgba(133, 245, 255, 0.9), 0 0 30px rgba(133, 245, 255, 0.55), 0 0 60px rgba(133, 245, 255, 0.3);
}

.susan-navbar-link.active {
    color: #b8f9ff;
    text-shadow: 0 0 10px rgba(133, 245, 255, 0.5);
}

.susan-navbar-link-center {
    font-size: 1.2rem;
    font-weight: 700;
}

.susan-navbar-divider {
    width: 1px;
    height: 18px;
    background: rgba(133, 245, 255, 0.5);
}

/* Navbar reflection - removed to keep bg within golden borders */

/* ============================
   Container 1 - Sky bg + centered text
   ============================ */
.susan-container1 {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 0 2rem;
    position: relative;
}


.susan-c1-content {
    max-width: var(--tw-body);
    width: 100%;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding-top: 250px;
}
/* ============================
   Section 2 - Left column texts (A VOICE FROM THE DEEP)
   ============================ */

.susan-s2-title {
    font-family: 'Cinzel', serif;
    font-weight: 400;
    font-size: 2.4rem;
    letter-spacing: 0.2em;
    color: #85F5FF;
    /* ⚠️ Zero, NON 20px come sembrerebbe naturale: la distanza dal filetto la decide da sola
       la `margin-top` di `.susan-divider`. Il motivo è che i due titoli vivono in due
       contesti diversi — l'intro dentro un FLEX (`.susan-c1-content`), ABOUT dentro un
       blocco normale — e i margini fra fratelli si fondono solo nel secondo. Con 20px qui
       l'intro faceva 20+18=38 e ABOUT 20: è per questo che la riga d'oro sotto «A STORY FROM
       THE DEEP» sembrava caduta. Tenendo la misura in un posto solo restano uguali. */
    margin-bottom: 0;
    line-height: 1.3;
    text-shadow: var(--glow-heading);
}

.susan-s2-italic {
    font-family: 'Cormorant', serif;
    font-weight: 300;
    font-style: italic;
    font-size: 1.50rem;
    color: var(--c-body);
    margin-top: 50px;
    margin-bottom: 2rem;
}

.susan-s2-cta {
    font-family: 'Cinzel', serif;
    font-weight: 400;
    font-size: 1.5rem;
    letter-spacing: 0.2em;
    color: #cbba9b;
    text-decoration: none;
    display: inline-block;
    position: relative;
    border: none;
    transition: color 0.3s ease, text-shadow 0.3s ease;
    text-shadow: var(--glow-cta);
    animation: susanCtaFloat 3s ease-in-out infinite;
}

/* È l'invito principale della pagina ma è testo nudo: col dito era alto 17px. Il riquadro
   toccabile arriva a 44px con un velo invisibile centrato sul testo, come per i pallini del
   carosello — così NON cambia di un pixel la spaziatura attorno, che è calibrata a mano nel
   JSON dei contenuti. Sopra e sotto c'è abbastanza aria perché non tocchi nient'altro. */
.susan-s2-cta::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    height: 44px;
    transform: translateY(-50%);
}

@keyframes susanCtaFloat {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-6px); }
}

.susan-s2-cta:hover {
    color: #fff0c8;
    text-shadow: var(--glow-cta-hover);
}

/* ===== PART BLOCK (V2 — hero logo + 4 chapters) ===== */
/* ===== PARTS CAROUSEL (lateral slide between parts) ===== */
.parts-carousel {
    padding-top: 300px;
    position: relative;
    overflow: hidden;
}

/* ⚠️ `align-items: flex-start` + l'altezza scritta da initPartsCarousel() sono una cosa sola.
   Senza, il binario è alto quanto la diapositiva PIÙ ALTA (la Parte I, coi suoi quattro
   capitoli scritti): passando alla Parte II — quattro righe "Coming Soon" — restava mezzo
   schermo di acqua vuota sotto, e sul telefono sembrava che la pagina fosse finita.
   Con `stretch` (il default) le diapositive si allungherebbero comunque tutte uguali e
   misurarle non servirebbe a niente. */
.parts-track {
    display: flex;
    align-items: flex-start;
    transition: transform .6s cubic-bezier(.4, 0, .2, 1), height .45s cubic-bezier(.4, 0, .2, 1);
    will-change: transform;
}

.part-slide {
    flex: 0 0 100%;
    width: 100%;
    min-width: 0;
    transition: opacity .5s ease, filter .5s ease;
}

/* the part not currently centered dims & blurs slightly */
.part-slide.is-inactive {
    opacity: .35;
    filter: blur(1px);
    pointer-events: none;
}

/* La testa della diapositiva: copertina (Parte I) o pannello "Coming soon" (Parte II).
   TUTTE le misure stanno qui, non sull'immagine dentro — così la cornice di scintille e
   quello che incornicia sono lo stesso riquadro, e restano concentrici a ogni larghezza. */
.part-cover {
    position: relative;
    max-width: 480px;
    width: 80%;
    margin: 0 auto 70px;
}

/* ⚠️ Niente `display` qui dentro: questo selettore ha DUE classi e batterebbe il
   `display: flex` di `.part-panel` più sotto — il pannello tornerebbe un blocco normale col
   titolo appiccicato in alto a sinistra. È già successo. Il `display: block` serve solo
   all'immagine, che di suo è inline e lascerebbe una riga di spazio sotto. */
.part-cover > .part-logo,
.part-cover > .part-panel {
    position: relative;
    z-index: 1;
    width: 100%;
    margin: 0;
}

/* ===== la cornice di scintille =====
   Funziona per un motivo verificato coi byte, non per fortuna: `part-i-cover-960.webp` è un
   WebP OPACO (nessun canale alpha) e il pannello della Parte II ha un fondo pieno. La
   polvere sta DIETRO (z-index 0 contro 1) e sborda: quella che cade dentro il riquadro è
   coperta dall'artwork, e resta visibile solo la fascia esterna — cioè una cornice. Niente
   maschere, niente @supports, niente ricadute.
   ⚠️ Il giorno in cui arrivasse una copertina CON canale alpha, la polvere si vedrebbe in
   mezzo all'immagine: controlla il file prima di sostituirlo.

   Sono TRE strati, e ognuno fa una cosa che gli altri non sanno fare:
     ::after   → dodici scintille VIVE, ferme, calibrate a mano lungo il bordo;
     .part-dust        → la polvere fine, tre trame ripetute che scorrono in diagonale;
     .part-dust::before/::after → le stelle a quattro punte, accese a turno.
   ⚠️ Le percentuali di `::after` sono calibrate sullo sbordo del 7%: allargarlo stacca le
   scintille dal bordo. La polvere, che deve allargarsi, ha il suo sbordo più ampio.
   ⚠️ C'era un quarto strato, `::before`: otto dischi sfocati (bokeh) che ruotavano piano
   attorno al riquadro. Tolto su richiesta di Susan il 2026-08-08 — con le scintille vere
   della tela sotto, quelle macchie sfocate si leggevano come sporco sull'obiettivo. Non
   rimetterlo "perché la cornice sembra vuota": la cornice la fa la tela. */
.part-cover::after {
    content: '';
    position: absolute;
    inset: -7%;
    z-index: 0;
    pointer-events: none;
}

/* Le scintille vive: dodici punti fermi, messi a mano lungo il bordo. Servono a rompere il
   ritmo della polvere ripetuta qui sotto — senza, ai fianchi si legge una griglia di puntini
   equidistanti invece che della polvere. Sono quelle che si notano. */
.part-cover::after {
    background-image:
        radial-gradient(circle at 3% 9%,  rgba(255,255,255,.95), rgba(255,255,255,0) 2.2px),
        radial-gradient(circle at 1.5% 41%, rgba(200,248,255,.85), rgba(200,248,255,0) 1.8px),
        radial-gradient(circle at 4% 78%, rgba(240,214,128,.8), rgba(240,214,128,0) 2px),
        radial-gradient(circle at 19% 2%, rgba(255,255,255,.9), rgba(255,255,255,0) 1.9px),
        radial-gradient(circle at 44% 4.5%, rgba(200,248,255,.8), rgba(200,248,255,0) 2.1px),
        radial-gradient(circle at 71% 1%,  rgba(255,255,255,.85), rgba(255,255,255,0) 1.7px),
        radial-gradient(circle at 96.5% 17%, rgba(255,255,255,.9), rgba(255,255,255,0) 2px),
        radial-gradient(circle at 98.5% 53%, rgba(240,214,128,.75), rgba(240,214,128,0) 1.9px),
        radial-gradient(circle at 96% 88%, rgba(200,248,255,.85), rgba(200,248,255,0) 2.1px),
        radial-gradient(circle at 79% 98.5%, rgba(255,255,255,.9), rgba(255,255,255,0) 1.8px),
        radial-gradient(circle at 52% 96.5%, rgba(255,255,255,.8), rgba(255,255,255,0) 2px),
        radial-gradient(circle at 26% 99%, rgba(240,214,128,.7), rgba(240,214,128,0) 1.7px);
    animation: partDust 6s ease-in-out infinite;
}

@keyframes partDust {
    0%, 100% { opacity: .5; }
    50%      { opacity: 1; }
}

/* ===== la polvere fine, quella che si muove =====
   Cinque trame ripetute a passi 37/53/71/43/61px: numeri senza divisori comuni, quindi il
   disegno si riallinea solo dopo un numero di pixel che nessuno schermo raggiunge.
   ⚠️ I passi diversi NON bastano da soli, ed è stato l'errore della prima stesura di questo
   strato: con la goccia sempre al centro della piastrella si leggevano lo stesso righe e
   colonne allineate — una griglia, non della polvere. La goccia è spostata in un punto
   diverso dentro ogni piastrella (`circle at X% Y%`), ed è quello che rompe il ritmo.
   ⚠️ L'animazione sposta ogni strato di ESATTAMENTE un suo passo (37, 53, 71, 43, 61 px, con
   segni alternati): è l'unico modo perché il giro si chiuda senza scatto. Un numero qualsiasi
   fa saltare tutta la polvere di posto una volta per ciclo. */
.part-dust {
    position: absolute;
    inset: -10%;
    z-index: 0;
    pointer-events: none;
    background-image:
        radial-gradient(circle at 22% 68%, rgba(255,255,255,.85) 0 .75px, rgba(255,255,255,0) 1.8px),
        radial-gradient(circle at 71% 24%, rgba(200,248,255,.72) 0 .65px, rgba(200,248,255,0) 1.6px),
        radial-gradient(circle at 39% 87%, rgba(240,214,128,.62) 0 .6px, rgba(240,214,128,0) 1.5px),
        radial-gradient(circle at 84% 61%, rgba(255,255,255,.66) 0 .55px, rgba(255,255,255,0) 1.4px),
        radial-gradient(circle at 12% 33%, rgba(200,248,255,.55) 0 .5px, rgba(200,248,255,0) 1.3px);
    background-size: 37px 37px, 53px 53px, 71px 71px, 43px 43px, 61px 61px;
    animation: partDrift 30s linear infinite;
    /* La polvere si dirada verso l'esterno invece di finire di netto: due sfumature
       incrociate, una per asse. ⚠️ Serve `mask-composite`, altrimenti i due strati si
       SOMMANO (è il valore predefinito) e la maschera diventa opaca dappertutto — cioè non
       fa niente. Dove `mask-composite` non esiste è esattamente quello che succede: nessuna
       sfumatura, ma nemmeno un buco. */
    -webkit-mask-image:
        linear-gradient(to bottom, transparent 0, #000 8%, #000 92%, transparent 100%),
        linear-gradient(to right,  transparent 0, #000 8%, #000 92%, transparent 100%);
    mask-image:
        linear-gradient(to bottom, transparent 0, #000 8%, #000 92%, transparent 100%),
        linear-gradient(to right,  transparent 0, #000 8%, #000 92%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-composite: intersect;
}

@keyframes partDrift {
    from { background-position: 0 0,        11px 19px,  23px 7px,   5px 29px,  31px 3px; }
    to   { background-position: 37px -37px, -42px 72px, 94px -64px, 48px -14px, -30px 64px; }
}

/* Le stelle a quattro punte: due ellissi incrociate per ognuna, otto strati per
   pseudo-elemento. Due gruppi che pulsano in controtempo (`animation-delay`) così non si
   accendono mai tutte insieme — è quello che le fa sembrare scintille e non lampadine. */
.part-dust::before,
.part-dust::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-repeat: no-repeat;
    animation: partStar 5.2s ease-in-out infinite;
}

.part-dust::before {
    background-image:
        radial-gradient(ellipse 46% 5% at 50% 50%, rgba(255,255,255,.95), rgba(255,255,255,0) 72%),
        radial-gradient(ellipse 5% 46% at 50% 50%, rgba(255,255,255,.95), rgba(255,255,255,0) 72%),
        radial-gradient(ellipse 46% 5% at 50% 50%, rgba(200,248,255,.9), rgba(200,248,255,0) 72%),
        radial-gradient(ellipse 5% 46% at 50% 50%, rgba(200,248,255,.9), rgba(200,248,255,0) 72%),
        radial-gradient(ellipse 46% 5% at 50% 50%, rgba(255,255,255,.85), rgba(255,255,255,0) 72%),
        radial-gradient(ellipse 5% 46% at 50% 50%, rgba(255,255,255,.85), rgba(255,255,255,0) 72%),
        radial-gradient(ellipse 46% 5% at 50% 50%, rgba(240,214,128,.8), rgba(240,214,128,0) 72%),
        radial-gradient(ellipse 5% 46% at 50% 50%, rgba(240,214,128,.8), rgba(240,214,128,0) 72%);
    background-size: 46px 46px, 46px 46px, 32px 32px, 32px 32px, 38px 38px, 38px 38px, 28px 28px, 28px 28px;
    background-position: 9% 22%, 9% 22%, 40% 9%, 40% 9%, 88% 12%, 88% 12%, 11% 86%, 11% 86%;
}

.part-dust::after {
    animation-delay: 2.6s;
    background-image:
        radial-gradient(ellipse 46% 5% at 50% 50%, rgba(255,255,255,.95), rgba(255,255,255,0) 72%),
        radial-gradient(ellipse 5% 46% at 50% 50%, rgba(255,255,255,.95), rgba(255,255,255,0) 72%),
        radial-gradient(ellipse 46% 5% at 50% 50%, rgba(200,248,255,.9), rgba(200,248,255,0) 72%),
        radial-gradient(ellipse 5% 46% at 50% 50%, rgba(200,248,255,.9), rgba(200,248,255,0) 72%),
        radial-gradient(ellipse 46% 5% at 50% 50%, rgba(255,255,255,.85), rgba(255,255,255,0) 72%),
        radial-gradient(ellipse 5% 46% at 50% 50%, rgba(255,255,255,.85), rgba(255,255,255,0) 72%),
        radial-gradient(ellipse 46% 5% at 50% 50%, rgba(240,214,128,.75), rgba(240,214,128,0) 72%),
        radial-gradient(ellipse 5% 46% at 50% 50%, rgba(240,214,128,.75), rgba(240,214,128,0) 72%);
    background-size: 42px 42px, 42px 42px, 34px 34px, 34px 34px, 30px 30px, 30px 30px, 26px 26px, 26px 26px;
    background-position: 91% 46%, 91% 46%, 62% 91%, 62% 91%, 24% 90%, 24% 90%, 89% 76%, 89% 76%;
}

@keyframes partStar {
    0%, 100% { opacity: .12; transform: scale(.92); }
    50%      { opacity: 1;   transform: scale(1.05); }
}

/* ===== la tela: le scintille che ESCONO dall'immagine =====
   La cornice qui sopra è ferma per costruzione — trame ripetute e punti scritti a mano non
   possono nascere da un bordo e volare via. Quando JavaScript è vivo la sostituisce una tela
   che emette dal perimetro della copertina verso fuori (`initSparkles`).
   ⚠️ Sta a `z-index: 0`, cioè DIETRO l'artwork come la vecchia polvere: è quello a far
   sembrare che le scintille escano da sotto l'immagine invece di comparire nell'aria. Se
   passasse davanti, si vedrebbero anche in mezzo alla copertina.
   Sotto la tela non resta più niente di decorativo: il bokeh è stato tolto e le scintille
   ferme di `::after` sono ricaduta. L'unica luce che rimane è quella diffusa della
   `.part-logo`, che lega la copertina all'acqua. */
.part-spark-canvas {
    position: absolute;
    z-index: 0;
    pointer-events: none;
}

.part-cover.spark-live::after,
.part-cover.spark-live .part-dust { display: none; }

/* Il `drop-shadow` di prima era la vecchia "cornice": ora la fa la polvere qui sopra. La
   luce diffusa attorno al riquadro, invece, è dell'artwork: è lei a legare la cornice di
   scintille alla copertina invece di lasciarle due cose sovrapposte. */
.part-logo {
    display: block;
    width: 100%;
    box-shadow: 0 0 60px rgba(133, 245, 255, .14);
}

/* Il pannello della Parte II: prende il posto della copertina, non ne è una versione
   sfocata. Nella foto che Susan ha mandato è un VUOTO — quasi nero al centro, appena più
   blu verso i bordi, dove l'acqua torna a intravedersi. Nessuna riga a delimitarlo: il
   confine lo disegnano le scintille.
   ⚠️ Sul pannello stesso NON va più nessun fondo: ce l'aveva, ed era un rettangolo pieno
   con quattro spigoli netti che si stagliavano sull'acqua — esattamente il contrario di un
   vuoto. Il buio ora lo disegna `::before` qui sotto e si dissolve prima del bordo. */
.part-panel {
    aspect-ratio: 1 / 1;
    min-height: 260px;          /* ricaduta dove `aspect-ratio` non esiste */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 2rem 1.5rem;
    background: none;
    border: 0;
    box-shadow: none;
}

/* Il vuoto vero e proprio: un elemento suo (`PART_VOID` nel renderer), non il fondo del
   pannello. Due motivi, ed entrambi sono stati sbagliati prima di arrivare qui:
   1. ORDINE DI DISEGNO. Da fondo del pannello starebbe SOPRA la tela delle scintille
      (`.part-panel` ha `z-index: 1`) e ne smorzerebbe tutta la fascia interna: la cornice
      di luce si spegneva a metà. Qui sta a `z-index: 0` e prima della tela nel DOM, quindi
      le scintille passano intatte sopra il buio.
   2. La sfumatura del bordo si fa con due `mask-image` incrociate, e una maschera sul
      pannello si porterebbe dietro anche la scritta, sbiadendola ai lati.
   ⚠️ Il gradiente è al contrario di come si scriverebbe d'istinto: il punto CHIARO sta ai
   bordi e lo scuro al centro. La prima versione faceva il contrario (centro #04182b) e il
   riquadro si leggeva come un pannello illuminato appoggiato sull'acqua, non come un buco.
   ⚠️ Servono `mask-composite: intersect` (+ `-webkit-mask-composite: source-in`): senza,
   i due strati si SOMMANO invece di intersecarsi e la maschera diventa opaca dappertutto,
   cioè non fa niente — tornerebbero gli spigoli netti. Stessa trappola di `.part-dust`.
   ⚠️ Lo sbordo negativo e le fermate della maschera sono UNA COSA SOLA, e sbagliarne il
   conto si vede subito: lo strato è largo 136% del pannello, quindi la parte piena va da
   −18% + 13%·136% ≈ 0 a −18% + 87%·136% ≈ 100% — cioè il buio è pieno fino al bordo del
   riquadro e si dissolve da lì in fuori, proprio dove la tela accende le scintille. Con la
   dissolvenza tutta DENTRO (la prima stesura: −5% e 17%) il vuoto finiva prima e restava
   un anello di acqua chiara fra il buio e le scintille. */
.part-void {
    position: absolute;
    inset: -18%;
    z-index: 0;
    pointer-events: none;
    background: radial-gradient(104% 104% at 50% 46%, rgba(0, 3, 5, .62) 0%, rgba(0, 6, 11, .56) 46%, rgba(1, 13, 23, .44) 82%, rgba(2, 24, 38, .3) 100%);
    /* ⚠️ La rampa non è dritta, ed è voluto: una `linear-gradient` da 0 a 100% in linea
       retta lascia uno SCALINO percettibile là dove riparte il pieno (banda di Mach), e a
       occhio quello scalino si legge ancora come il bordo di un rettangolo — cioè
       esattamente il difetto che si voleva togliere. I sei punti qui sotto disegnano una
       curva a S: partenza lentissima, discesa in mezzo, arrivo morbido. */
    -webkit-mask-image:
        linear-gradient(to bottom, rgba(0,0,0,0) 0, rgba(0,0,0,.06) 3.5%, rgba(0,0,0,.26) 7%, rgba(0,0,0,.62) 10.5%, rgba(0,0,0,.9) 13%, #000 16%, #000 84%, rgba(0,0,0,.9) 87%, rgba(0,0,0,.62) 89.5%, rgba(0,0,0,.26) 93%, rgba(0,0,0,.06) 96.5%, rgba(0,0,0,0) 100%),
        linear-gradient(to right,  rgba(0,0,0,0) 0, rgba(0,0,0,.06) 3.5%, rgba(0,0,0,.26) 7%, rgba(0,0,0,.62) 10.5%, rgba(0,0,0,.9) 13%, #000 16%, #000 84%, rgba(0,0,0,.9) 87%, rgba(0,0,0,.62) 89.5%, rgba(0,0,0,.26) 93%, rgba(0,0,0,.06) 96.5%, rgba(0,0,0,0) 100%);
    mask-image:
        linear-gradient(to bottom, rgba(0,0,0,0) 0, rgba(0,0,0,.06) 3.5%, rgba(0,0,0,.26) 7%, rgba(0,0,0,.62) 10.5%, rgba(0,0,0,.9) 13%, #000 16%, #000 84%, rgba(0,0,0,.9) 87%, rgba(0,0,0,.62) 89.5%, rgba(0,0,0,.26) 93%, rgba(0,0,0,.06) 96.5%, rgba(0,0,0,0) 100%),
        linear-gradient(to right,  rgba(0,0,0,0) 0, rgba(0,0,0,.06) 3.5%, rgba(0,0,0,.26) 7%, rgba(0,0,0,.62) 10.5%, rgba(0,0,0,.9) 13%, #000 16%, #000 84%, rgba(0,0,0,.9) 87%, rgba(0,0,0,.62) 89.5%, rgba(0,0,0,.26) 93%, rgba(0,0,0,.06) 96.5%, rgba(0,0,0,0) 100%);
    -webkit-mask-composite: source-in;
    mask-composite: intersect;
}

/* Il titolo: nella foto è una parola compatta e molto accesa, non una riga di lettere
   distanziate che attraversa il riquadro. La spaziatura larga (.3em) lo faceva arrivare a
   metà del lato; qui sta in un terzo scarso e l'alone ha spazio per essere un alone. */
.part-panel-title {
    font-family: 'Cinzel', serif;
    font-size: 2.7rem;
    font-weight: 400;
    letter-spacing: .1em;
    margin: 0;
    color: #cdf6ff;
    text-shadow:
        0 0 6px #ffffff,
        0 0 16px #85F5FF,
        0 0 34px rgba(133, 245, 255, .85),
        0 0 62px rgba(133, 245, 255, .55),
        0 0 110px rgba(133, 245, 255, .3);
}

.part-panel-sub {
    font-family: 'Cormorant', serif;
    font-style: italic;
    font-size: 1.35rem;
    letter-spacing: .06em;
    color: #f2fdff;
    text-shadow: var(--glow-body);
}

/* Il respiro laterale sta QUI e non su `.parts-carousel`: la carrellata ritaglia col bordo
   esterno, quindi un padding lì lascerebbe sbucare un dito della diapositiva accanto nella
   fascia di margine. Sotto i 1000px, senza, i capitoli toccavano il bordo dello schermo. */
.part-wrap {
    max-width: 1000px;
    margin: 0 auto;
    padding: 0 24px 40px;
}

/* Text title used as a placeholder logo (Part II) */
.part-logo-text {
    font-family: 'Cinzel', serif;
    font-size: 3rem;
    font-weight: 400;
    letter-spacing: .3em;
    text-align: center;
    margin: 0;
    padding: 0 1rem 70px;
    min-height: 220px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #a9eef7;
    text-shadow: var(--glow-heading);
}

/* ===== carousel navigation ===== */
.parts-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 24px;
    margin-top: 30px;
    padding-bottom: 40px;
}

.parts-nav-center {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}

/* Su quale parte sono. Sta fra le due frecce, sotto i capitoli, su ogni misura: sul telefono
   è più grande perché lì è l'unica conferma di cosa si è appena scorso. */
.parts-label {
    font-family: 'Cinzel', serif;
    font-size: .72rem;
    letter-spacing: .3em;
    color: rgba(133, 245, 255, .8);
    text-shadow: var(--glow-body);
}

.parts-arrow {
    background: none;
    border: 1px solid rgba(133,245,255,.25);
    color: #85F5FF;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    font-size: 1.2rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all .3s ease;
}
.parts-arrow:hover:not(:disabled) {
    border-color: rgba(133,245,255,.6);
    box-shadow: 0 0 12px rgba(133,245,255,.2);
}
.parts-arrow:disabled {
    opacity: .25;
    cursor: default;
}

.parts-dots {
    display: flex;
    gap: 18px;
}
.parts-dot {
    position: relative;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 1px solid rgba(133,245,255,.5);
    background: none;
    cursor: pointer;
    padding: 0;
    transition: all .3s ease;
}

/* Il pallino resta di 10px, l'area che si prende no: il velo invisibile la porta a 28px
   (sopra il minimo di 24 di WCAG 2.2 §2.5.8) anche col mouse e sui tablet, dove prima
   bisognava centrare un decimo di centimetro.
   ⚠️ Il velo e la distanza fra i pallini si muovono INSIEME: 10px di pallino + 18 di
   spazio fanno 28 fra un centro e l'altro, cioè esattamente il lato del velo. Allargando
   uno senza l'altro i due riquadri si sovrappongono e il tocco in mezzo va sul pallino
   sbagliato. Sul telefono la regola più avanti li porta entrambi a 44/34. */
.parts-dot::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 28px;
    height: 28px;
    transform: translate(-50%, -50%);
}
.parts-dot.is-active {
    background: #85F5FF;
    box-shadow: 0 0 10px rgba(133,245,255,.6);
}

.ch-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0;
}

.ch-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 0 18px;
    position: relative;
}

.ch-item::before,
.ch-item::after {
    content: '';
    position: absolute;
    top: 30px;
    height: 1px;
    background: rgba(201,169,110,.3);
    z-index: 0;
}
.ch-item::before { left: 0; width: calc(50% - 35px); }
.ch-item::after { right: 0; width: calc(50% - 35px); }
.ch-item:first-child::before { display: none; }
.ch-item:last-child::after { display: none; }

.ch-icon {
    position: relative;
    z-index: 1;
    width: 60px;
    height: 60px;
    margin-bottom: 20px;
    filter: drop-shadow(0 0 6px rgba(201,169,110,.4));
}

.ch-lock {
    position: relative;
    z-index: 1;
    width: 60px;
    height: 60px;
    margin-bottom: 20px;
    opacity: .75;
    color: #e0c894;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Il disegno non riempie tutto il riquadro: la conchiglia accanto ha il suo margine dentro
   il PNG, e un lucchetto a filo di bordo sarebbe uscito più grande di lei. */
.ch-lock svg {
    width: 62%;
    height: 62%;
    filter: drop-shadow(0 0 7px rgba(201, 169, 110, .45));
}

.ch-label {
    font-family: 'Cinzel', serif;
    font-size: .9rem;
    font-weight: 700;
    letter-spacing: .2em;
    margin-bottom: 10px;
    color: #e8d5a3;
    text-shadow: 0 0 12px rgba(240, 214, 128, .5), 0 0 30px rgba(201, 169, 110, .3);
}

.ch-name {
    font-family: 'Cormorant', serif;
    font-style: italic;
    font-size: 1.7rem;
    line-height: 1.3;
    margin-bottom: 10px;
    color: #a9eef7;
    text-shadow: var(--glow-body);
}

/* ⚠️ Il testo "riempito" col gradiente sta in piedi su DUE proprietà che devono esistere
   ENTRAMBE: `background-clip: text` ritaglia lo sfondo sulla forma delle lettere, e
   `-webkit-text-fill-color: transparent` toglie il colore che altrimenti lo coprirebbe.
   Se il browser conosce la seconda ma non la prima — o se un'estensione/una modalità
   lettura disattiva il ritaglio — il titolo non diventa "meno bello": SPARISCE, e con lui
   il nome di ogni capitolo. Perciò il colore pieno sta nella regola base qui sopra e il
   gradiente vive solo dentro questo @supports, che chiede esplicitamente la proprietà
   critica (con e senza prefisso: Safari a lungo ha conosciuto solo quella -webkit-). */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    .ch-label,
    .ch-name,
    .part-logo-text,
    .part-panel-title {
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        text-shadow: none;
    }

    .ch-label {
        background-image: linear-gradient(180deg, #fff6e0 0%, #f0d68c 25%, #a9936a 50%, #e8d5a3 75%, #8a7550 100%);
        filter: drop-shadow(0 0 12px rgba(240,214,128,.6)) drop-shadow(0 0 30px rgba(201,169,110,.35));
    }

    .ch-name {
        background-image: linear-gradient(180deg, #ffffff 0%, #c8f8ff 20%, #85F5FF 45%, #b8faff 65%, #5ed8e8 100%);
        filter: drop-shadow(0 0 12px rgba(133,245,255,.6)) drop-shadow(0 0 35px rgba(133,245,255,.3));
    }

    .part-logo-text,
    .part-panel-title {
        background-image: linear-gradient(180deg, #ffffff 0%, #c8f8ff 20%, #85F5FF 45%, #b8faff 65%, #5ed8e8 100%);
        filter: drop-shadow(0 0 20px rgba(133,245,255,.6)) drop-shadow(0 0 50px rgba(133,245,255,.3));
    }

    /* ⚠️ Qui il `text-shadow` scritto sulla regola base NON vale: questo @supports lo azzera
       (`text-shadow: none`) perché con `background-clip: text` l'ombra passerebbe SOPRA le
       lettere ritagliate. L'alone della Parte II va quindi cambiato qui, in `filter`, o non
       cambia affatto. Ne serve più che agli altri titoli: la scritta è sospesa nel vuoto,
       non appoggiata a un'immagine, e senza un alone stretto e acceso si spegne sul nero. */
    .part-panel-title {
        filter:
            drop-shadow(0 0 5px rgba(255, 255, 255, .8))
            drop-shadow(0 0 15px rgba(133, 245, 255, .9))
            drop-shadow(0 0 36px rgba(133, 245, 255, .55))
            drop-shadow(0 0 78px rgba(133, 245, 255, .32));
    }
}

.ch-cta {
    font-family: 'Cinzel', serif;
    font-size: .7rem;
    color: #85F5FF;
    text-decoration: none;
    letter-spacing: .12em;
    padding: 6px 14px;
    border: 1px solid rgba(133,245,255,.2);
    border-radius: 16px;
    transition: all .3s ease;
    margin-top: auto;
}
.ch-cta:hover {
    background: rgba(133,245,255,.08);
    border-color: rgba(133,245,255,.4);
}

.ch-cta-wrap {
    display: flex;
    justify-content: center;
    margin-top: 28px;
}
.ch-cta-main {
    font-size: .85rem;
    padding: 12px 32px;
    border-radius: 24px;
    margin-top: 0;
}

.ch-soon {
    font-family: 'Cormorant', serif;
    font-style: italic;
    font-size: 1.1rem;
    color: #85F5FF;
}

.ch-locked { opacity: .35; }

/* ---- Tablet e portatili stretti: quattro colonne diventano due ----
   Sotto i 1000px le quattro colonne lasciavano ~150px di testo a capitolo: su un iPad in
   verticale "The Sea Creature" andava a capo in mezzo alle virgolette e la descrizione
   diventava una colonna di due parole. */
@media (max-width: 999px) {
    .ch-grid { grid-template-columns: repeat(2, 1fr); gap: 54px 0; }

    /* ⚠️ La lineetta dorata unisce due conchiglie DELLA STESSA RIGA. Con le sole regole
       :first-child/:last-child (pensate per una fila unica) in una griglia a due colonne i
       capitoli 2 e 3 tiravano una riga verso il nulla, oltre il bordo dello schermo. */
    .ch-item:nth-child(odd)::before { display: none; }
    .ch-item:nth-child(even)::after { display: none; }
}

@media (max-width: 768px) {
    .parts-carousel { padding-top: 120px; display: flex; flex-direction: column; }
    .part-cover { max-width: 380px; width: 85%; margin-bottom: 44px; }
    .part-wrap { max-width: 100%; }
    .part-logo-text { font-size: 2rem; min-height: 160px; }
    .part-panel { min-height: 200px; }
    .part-panel-title { font-size: 2rem; }
    .part-panel-sub { font-size: 1.1rem; }

    /* Frecce e pallini stanno SOTTO i capitoli, come sul desktop: è la richiesta di Susan.
       (Prima erano `order: -1`, cioè sopra la copertina, perché in colonna singola i quattro
       capitoli li spingevano una schermata più in basso.)
       ⚠️ Il `display: flex; flex-direction: column` qui sopra resta anche ora che nessuno
       riordina più niente: senza, i margini di `.parts-track` — che ha un'altezza SCRITTA dal
       JS — e quelli della barra si fondono, e la distanza salta a ogni cambio parte.
       ⚠️ Con la barra sotto, la sua posizione dipende da quell'altezza, che è animata (.45s):
       cambiando parte le frecce ora SCORRONO. Sul desktop è già così e non è un difetto, ma è
       un bersaglio in movimento sotto il dito: se dà fastidio si accorcia la transizione, non
       la si toglie.
       ⚠️ I 30px di stacco non sono decorativi: sopra i pallini ora c'è la pillola «Listen Now»
       di Part I, e il velo invisibile del pallino (44px) arriva 22px sopra il suo centro.
       Azzerandoli, il velo comincia a mangiare i tocchi della CTA. */
    .parts-nav {
        margin-top: 30px;
        margin-bottom: 0;
        padding-bottom: 0;
        gap: 18px;
    }
    .parts-label { font-size: .9rem; letter-spacing: .35em; }
    /* Col dito si sale a 44px, e la distanza cresce con lui (10 + 34 = 44 fra i centri). */
    .parts-dots { gap: 34px; }
    .parts-dot::after { width: 44px; height: 44px; }
}

/* ============================================================
   Telefoni — i capitoli sono un elenco centrato, senza linee
   ============================================================
   Qui c'era una timeline verticale: conchiglia in posizione assoluta a sinistra su una guida
   dorata e testo a bandiera accanto — la stessa del desktop girata di 90°, alta ~560px invece
   di ~1400. Susan li vuole CENTRATI e senza nessuna linea: conchiglia sopra, poi l'etichetta,
   poi il titolo. È una scelta della cliente, e il prezzo è che l'elenco torna alto ~1100px:
   chi «ottimizza» rimettendo la bandiera sta rifacendo il giro all'indietro.

   ⚠️ Le proprietà vanno RIDICHIARATE, non cancellate. Dentro questa media query non basta
   togliere le righe: `align-items`/`text-align`/`position` tornerebbero a quelle della regola
   base — che per la conchiglia va bene, ma per i tratti `::before`/`::after` no, e la
   lineetta orizzontale della griglia a colonne ricomparirebbe sotto un elenco in colonna. */
@media (max-width: 600px) {
    /* ⚠️ DUE COLONNE, non una (2026-08-12, richiesta di Susan). Qui c'era `1fr`: i quattro
       capitoli in colonna unica facevano un elenco alto ~1100px, e per arrivare in fondo alla
       Parte II si scorreva una schermata e mezza. Affiancati a due si vedono tutti insieme.
       Il `gap: 0` di prima serviva alla colonna unica (la spaziatura la dava il padding di
       .ch-item): con due colonne serve una gronda VERTICALE fra le due righe, e nessuna
       orizzontale — il padding laterale qui sotto tiene già i titoli staccati. */
    .ch-grid { grid-template-columns: repeat(2, 1fr); gap: 30px 0; }

    .ch-item {
        align-items: center;
        text-align: center;
        padding: 0 8px 4px;
        min-height: 44px;
    }
    /* ⚠️ Non più `:last-child`: con due colonne gli ULTIMI DUE stanno sulla stessa riga, e
       togliere il fondo al solo quarto disallineava la coppia. Il padding di fondo lo porta
       la gronda della griglia, quindi qui non serve più nessuna eccezione. */

    .ch-icon,
    .ch-lock {
        position: static;
        width: 46px;
        height: 46px;
        margin: 0 0 12px;
    }

    /* Nessuna linea, in nessuna direzione: né la lineetta orizzontale della griglia a colonne
       né la guida verticale che questa media query disegnava prima. */
    .ch-item::before,
    .ch-item::after { display: none; }

    /* ⚠️ I corpi qui sono un COMPROMESSO misurato, non una preferenza: la colonna è larga
       metà schermo e il vincolo è «The Sea Creature», il titolo più lungo dei quattro. Sopra
       i valori qui sotto va a capo in mezzo alle virgolette — lo stesso guasto che, una
       misura più su (999px), aveva già fatto passare le quattro colonne a due.
       Chi li alza ancora deve rimisurare a 320px, non solo a 390: è lì che sfonda per primo.
       `letter-spacing` resta stretta sull'etichetta perché è tutta maiuscola e spaziata, ed
       è la riga che sborda prima del titolo. */
    .ch-label { font-size: .72rem; letter-spacing: .14em; margin: 0 0 7px; }
    .ch-name { font-size: 1.24rem; margin-bottom: 0; }
    .ch-soon { font-size: 1rem; }
    .ch-cta { margin-top: 12px; font-size: .68rem; padding: 6px 12px; }
    .ch-cta-wrap { margin-top: 36px; }
    .ch-locked { opacity: .5; }   /* .35 su fondo scuro e schermo piccolo era illeggibile */
}

@media (max-width: 480px) {
    .parts-carousel { padding-top: 80px; }
    .part-cover { width: 90%; }
    .part-logo-text { font-size: 1.6rem; letter-spacing: .2em; min-height: 130px; }
    .part-panel { min-height: 170px; gap: 4px; }
    .part-panel-title { font-size: 1.6rem; letter-spacing: .08em; }
    .part-panel-sub { font-size: 1rem; }
    .part-wrap { padding: 0 18px 30px; }
    /* ⚠️ Sotto i 480px la colonna scende a ~140px: qui i corpi calano per forza, non per
       gusto. Restano comunque sopra a dove erano prima delle due colonne, e sono l'ultimo
       gradino prima che «The Sea Creature» vada a capo. Rimisurare A 320px, non a 390. */
    .ch-icon, .ch-lock { width: 42px; height: 42px; margin-bottom: 10px; }
    .ch-name { font-size: 1.08rem; }
    .ch-label { font-size: .64rem; letter-spacing: .1em; }
    .ch-soon { font-size: .9rem; }
}

/* ============================
   About Section (Section 4)
   ============================ */
.about-section {
    max-width: 1000px;
    margin: 0 auto;
    padding: 200px 2rem 100px;
    text-align: center;
}

/* ⚠️ Erano 50px QUI più 50px di `padding-top` su `.about-text` = 100px fra il filetto e la
   prima riga, contro i 2.2rem dell'intro. Le due misure vanno lette insieme: azzerando solo
   una il salto resta. Il valore è lo stesso di `.susan-s2-title + .susan-divider`. */
.about-header {
    margin-bottom: 2.2rem;
}

.about-title {
    font-family: 'Cinzel', serif;
    font-size: 2.4rem;
    font-weight: 400;
    letter-spacing: .25em;
    margin-bottom: 0;   /* vedi la nota su `.susan-s2-title`: la misura sta sul filetto */
    color: #85F5FF;
    text-shadow: var(--glow-heading);
}

.susan-divider,
.about-divider {
    width: var(--divider-w);
    max-width: 80%;
    height: 1px;
    margin: 20px auto 0;
    background: linear-gradient(90deg, transparent, rgba(201, 169, 110, .55), transparent);
}

/* Under a section-1 / generic heading the line needs a little more air below it. */
.susan-s2-title + .susan-divider,
.sb-heading + .susan-divider { margin-bottom: 2.2rem; }

/* ⚠️ Lo spazio fra un paragrafo e l'altro sta TUTTO qui, ora che `.about-text` non ha più
   il suo `padding-top`: quel padding faceva due lavori insieme (staccare il titolo E
   separare i paragrafi) e per questo il titolo era lontano il doppio del dovuto. */
.about-content {
    display: flex;
    flex-direction: column;
    gap: 2.2rem;
}

.about-text {
    font-family: 'Cormorant', serif;
    font-style: italic;
    font-size: var(--fs-body);
    line-height: 1.5;
    color: var(--c-body);
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 1s ease, transform 1s ease;
}

.about-text.visible {
    opacity: 1;
    transform: translateY(0);
}

.about-text-intro {
    max-width: var(--tw-body);
    align-self: center;
}

.about-text-lg {
    font-family: 'Cinzel', serif;
    font-style: normal;
    font-size: 2.3rem;
    font-weight: 400;
    letter-spacing: 0.2em;
}

.about-text-final {
    font-size: 1.4rem;
    color: var(--c-body);
}

.about-text em {
    color: #cbba9b;
    font-style: italic;
    text-shadow: 0 0 10px rgba(201,169,110,.3);
}

.about-cta-wrap {
    margin-top: 30px;
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 1s ease .3s, transform 1s ease .3s;
}

.about-cta-wrap.visible {
    opacity: 1;
    transform: translateY(0);
}

.about-cta {
    font-family: 'Cinzel', serif;
    font-size: .85rem;
    letter-spacing: .2em;
    color: #cbba9b;
    text-decoration: none;
    padding: 10px 28px;
    border: 1px solid rgba(201,169,110,.3);
    border-radius: 30px;
    transition: all .4s ease;
    text-shadow: 0 0 10px rgba(201,169,110,.3);
}

.about-cta:hover {
    border-color: rgba(201,169,110,.6);
    box-shadow: 0 0 20px rgba(201,169,110,.2);
    color: #e0cc9a;
}

/* ============================
   LISTEN NOW — un componente solo, in tre posti
   ============================
   Erano tre cose diverse: testo dorato nudo nell'intro, pillola ciano nel carosello,
   pillola dorata in ABOUT. Nessuna delle tre si leggeva come "premimi" — la richiesta di
   Susan era proprio quella. `listen-cta` la aggiunge il renderer ACCANTO alle classi di
   prima, che restano: `.susan-s2-cta.susan-cinematic.visible` porta ancora l'ondeggio.
   ⚠️ Queste regole devono stare DOPO `.susan-s2-cta`, `.ch-cta-main` e `.about-cta`: sono
   tutte selettori a una classe, quindi a decidere è l'ordine nel foglio, non la specificità.

   Il bordo NON è più una linea: è una catena di puntini luminosi che gira attorno alla
   pillola, con quattro stelle che si accendono a turno — la pillola che Susan ha mandato.
   ⚠️ Perché un tratteggio SVG e non dei `radial-gradient` come prima: i puntini devono
   seguire una pillola, cioè due semicerchi e due rette. Con un'immagine di sfondo i puntini
   agli angoli o si stiravano o sparivano, e la pillola vive in TRE larghezze diverse
   (intro, carosello, about). Il tratteggio segue il contorno per costruzione. */
.listen-cta {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: 'Cinzel', serif;
    font-size: 1rem;
    font-weight: 400;
    letter-spacing: .22em;
    text-transform: uppercase;
    /* Nella foto le lettere sono di un ciano PIENO, non un bianco appena azzurrato: è
       quello a farle stare nello stesso mondo dell'anello invece di sembrarci appoggiate. */
    color: #6fe3ff;
    text-decoration: none;
    padding: 16px 44px;
    /* Il raggio della pillola, in UN posto solo: lo usano i quattro contorni dell'anello,
       che stanno a distanze diverse dal bordo e devono restare concentrici. Cambia per
       fascia insieme al padding — l'altezza della pillola la decide quello. */
    --cta-r: 27px;
    /* Il contorno lo disegna l'anello di puntini: una riga vera qui sotto si vedrebbe
       come un secondo bordo continuo dietro le scintille. */
    border: 0;
    border-radius: 999px;
    /* Nella foto dentro la pillola c'è l'acqua e basta. Questo velo è quasi niente e serve
       solo a tenere leggibile il serif dove l'onda schiarisce: più scuro si vedeva come una
       targa appoggiata sopra il mare. */
    background: rgba(1, 17, 38, .12);
    /* Nella foto le lettere sono CIANO, non bianche, e la luce che buttano è larga: è quella
       a legare il testo all'anello invece di lasciarli due cose sovrapposte. */
    text-shadow: 0 0 8px rgba(133,245,255,.95), 0 0 22px rgba(74,205,255,.6), 0 0 44px rgba(74,205,255,.3);
    /* ⚠️ Niente `box-shadow`: era un alone sfocato attorno alla pillola e si vedeva come una
       macchia di luce, non come delle scintille. La luce la fanno le particelle. */
    transition: color .3s ease, box-shadow .35s ease, background .35s ease;
    /* ⚠️ `visible`, ed è il contrario di prima: puntini e stelle stanno per METÀ fuori dal
       riquadro (il tratto è centrato sul contorno). Con `hidden` si vedeva una corona di
       mezzelune tagliate di netto. */
    overflow: visible;
    -webkit-tap-highlight-color: transparent;
}

/* L'etichetta ha bisogno di un elemento suo: sopra il testo nudo ora ci sono l'anello e le
   stelle, e senza uno strato dichiarato finirebbe sotto le scintille. */
.cta-label {
    position: relative;
    z-index: 2;
}

/* ⚠️ Nessun viewBox sull'SVG: così un'unità dell'immagine È un pixel CSS e `width="100%"`
   segue la pillola da sé, senza stirare nulla. `overflow: visible` per la metà di tratto
   che cade fuori dal riquadro. */
.cta-ring {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
    overflow: visible;
    pointer-events: none;
}

/* Il trucco dei puntini: un tratteggio coi capi TONDI e la parte piena lunga quasi zero.
   Ogni trattino collassa in un disco largo quanto il tratto — decine di puntini lungo una
   pillola, scritti in due righe invece che a mano uno per uno.

   ⚠️ Un solo strato di puntini NON somiglia alla foto, ed è stato l'errore della prima
   stesura: puntini tutti uguali, tutti alla stessa distanza dal bordo, si leggono come una
   CUCITURA — una collana di perline, non delle scintille. Nella foto sono tre cose insieme:
     · un alone ciano CONTINUO in cui la pillola è immersa (nessun puntino: è la luce);
     · scintille di grandezza diversa sparse su una banda, non su una riga;
     · qualche bagliore a quattro punte più forte degli altri.
   Da qui i quattro contorni: stanno a distanze diverse dal bordo (+5, 0, −4 px) e hanno
   passi senza divisori comuni (15, 9, 5), quindi i puntini non si allineano mai fra strati.

   La geometria è scritta in CSS (`x`/`y`/`width`/`height` sono proprietà, non solo
   attributi): è l'unico modo di spostare un contorno verso fuori o verso dentro senza
   sapere quanto è larga la pillola, che vive in tre misure diverse. Gli attributi nel
   markup restano la ricaduta per chi non conosce le proprietà geometriche — lì i quattro
   contorni ricadono uno sull'altro, che è brutto ma non rotto. */
.cta-ring-halo,
.cta-ring-outer,
.cta-ring-dots,
.cta-ring-fine {
    fill: none;
    stroke-linecap: round;
    /* Metà dell'altezza vera della pillola: qui il raggio diventa quello di una pillola
       esatta, mentre l'attributo `rx`/`ry` nel markup (22) resta la ricaduta prudente.
       Le altezze sono note per fascia — le decide il `padding`, non il testo. */
    rx: var(--cta-r);
    ry: var(--cta-r);
}

/* 1. L'alone continuo. ⚠️ Vive SOLO nella ricaduta senza JavaScript: dove la tela c'è,
   sparisce con gli altri. Con le particelle vere sotto diventava una macchia sfocata
   attorno alla pillola — la luce buona è quella dei granelli, non un velo che li copre.
   Nella ricaduta invece serve, o restano tre tratteggi appoggiati sull'acqua. */
.cta-ring-halo {
    stroke: rgba(74, 205, 255, .42);
    stroke-width: 9;
    filter: blur(6px);
    animation: ctaBloom 4.8s ease-in-out infinite;
    transition: stroke .3s ease;
}

@keyframes ctaBloom {
    0%, 100% { opacity: .7; }
    50%      { opacity: 1; }
}

/* 2. Le scintille grosse, un filo FUORI dal bordo: sono quelle che si staccano dall'anello
   e gli danno spessore. Passo largo (15) → poche e sparse. */
.cta-ring-outer {
    x: -5px; y: -5px;
    width: calc(100% + 10px);
    height: calc(100% + 10px);
    rx: calc(var(--cta-r) + 5px);
    ry: calc(var(--cta-r) + 5px);
    stroke: rgba(226, 250, 255, .85);
    stroke-width: 3.2;
    filter: blur(.5px);
    /* ⚠️ Ogni scorrimento deve chiudersi su un MULTIPLO del suo passo (15 × 4 = 60), o a
       fine giro tutti i puntini saltano di posto una volta per ciclo. */
    animation: ctaDriftOuter 9s linear infinite, ctaFlicker 2.9s ease-in-out infinite;
    stroke-dasharray: .1 15;
}

/* 3. La catena principale, sul bordo esatto. */
.cta-ring-dots {
    stroke: #eafeff;
    stroke-width: 2;
    stroke-dasharray: .1 9;
    animation: ctaRingDrift 4.5s linear infinite;
    transition: stroke .3s ease, stroke-width .3s ease;
}

/* 4. La polvere fine, un filo DENTRO: fitta, tenue, veloce. Da sola non si nota — serve a
   riempire i vuoti fra le scintille grosse, che è quello che nella foto fa "banda". */
.cta-ring-fine {
    x: 4px; y: 4px;
    width: calc(100% - 8px);
    height: calc(100% - 8px);
    rx: calc(var(--cta-r) - 4px);
    ry: calc(var(--cta-r) - 4px);
    stroke: rgba(150, 232, 255, .7);
    stroke-width: 1.1;
    stroke-dasharray: .1 5;
    animation: ctaDriftFine 3.2s linear infinite, ctaFlicker 1.7s ease-in-out infinite reverse;
}

@keyframes ctaRingDrift {
    from { stroke-dashoffset: 0; }
    to   { stroke-dashoffset: -36; }   /* 9 × 4 */
}

@keyframes ctaDriftOuter {
    from { stroke-dashoffset: 0; }
    to   { stroke-dashoffset: 60; }    /* 15 × 4, e nel verso opposto agli altri */
}

@keyframes ctaDriftFine {
    from { stroke-dashoffset: 0; }
    to   { stroke-dashoffset: -40; }   /* 5 × 8 */
}

/* Il tremolio: due strati che si schiariscono e si spengono con ritmi diversi. Non è un
   dettaglio — è ciò che impedisce all'anello di leggersi come un disegno fermo. */
@keyframes ctaFlicker {
    0%, 100% { opacity: 1; }
    50%      { opacity: .45; }
}

/* Le stelle a quattro punte: due ellissi incrociate più un nucleo tondo. Sono elementi e
   non pseudo-elementi perché un elemento ne offre due, e due non bastano a girare attorno
   a una pillola. Sei e non quattro: nella foto ce ne sono sempre due o tre accese insieme,
   e con quattro a turno capitava di vederne una sola. */
.cta-star {
    position: absolute;
    z-index: 1;
    width: 30px;
    height: 30px;
    margin: -15px 0 0 -15px;
    opacity: 0;
    pointer-events: none;
    /* I raggi sono più lunghi e più sottili di prima (48% × 3.5% invece di 46% × 5%): è la
       proporzione dei bagliori nella foto, dove le punte arrivano lontano dal nucleo. */
    background:
        radial-gradient(ellipse 48% 3.5% at 50% 50%, rgba(255,255,255,.98), rgba(255,255,255,0) 74%),
        radial-gradient(ellipse 3.5% 48% at 50% 50%, rgba(255,255,255,.98), rgba(255,255,255,0) 74%),
        radial-gradient(circle at 50% 50%, rgba(255,255,255,.95) 0, rgba(133,245,255,.55) 14%, rgba(74,205,255,0) 48%);
    animation: ctaStar 3.6s ease-in-out infinite;
}

/* Sparse attorno al contorno, non a caso: mai due vicine, così in qualunque istante
   l'accensione capita da una parte diversa. */
.cta-star-1 { left: 2%;  top: 64%; }
.cta-star-2 { left: 24%; top: 0%;   animation-delay: .6s; }
.cta-star-3 { left: 69%; top: 100%; animation-delay: 1.2s; width: 24px; height: 24px; margin: -12px 0 0 -12px; }
.cta-star-4 { left: 98%; top: 30%;  animation-delay: 1.8s; width: 22px; height: 22px; margin: -11px 0 0 -11px; }
.cta-star-5 { left: 46%; top: 2%;   animation-delay: 2.4s; width: 20px; height: 20px; margin: -10px 0 0 -10px; }
.cta-star-6 { left: 13%; top: 98%;  animation-delay: 3s;   width: 26px; height: 26px; margin: -13px 0 0 -13px; }

@keyframes ctaStar {
    0%, 62%, 100% { opacity: 0;   transform: scale(.3) rotate(0deg); }
    10%           { opacity: 1;   transform: scale(1) rotate(14deg); }
    28%           { opacity: .22; transform: scale(.65) rotate(24deg); }
}

.listen-cta:hover {
    color: #ffffff;
    background: rgba(133, 245, 255, .10);
}

.listen-cta:hover .cta-ring-dots { stroke: #ffffff; stroke-width: 2.6; }
.listen-cta:hover .cta-ring-halo { stroke: rgba(96, 218, 255, .8); }

.listen-cta:focus-visible {
    outline: 2px solid var(--c-gold);
    outline-offset: 6px;
}

/* ===== la tela delle scintille =====
   Quando JavaScript è vivo le scintille le disegna una tela (`initSparkles`), che può dare a
   ognuna una posizione, una grandezza e un luccichio suoi — cose che un tratteggio non ha.
   I tre contorni tratteggiati restano la RICADUTA: si vedono solo dove la tela non c'è
   (niente JS, oppure "riduci il movimento"). L'alone continuo invece resta sempre: è la
   luce in cui la pillola è immersa, e la tela non la rifà.
   ⚠️ `spark-live` la mette il JS DOPO aver creato la tela, non prima: se la creazione
   fallisse, i puntini devono restare al loro posto. */
.cta-spark-canvas {
    position: absolute;
    z-index: 1;
    pointer-events: none;
}

/* ⚠️ Le sei stelle CSS spariscono con gli altri strati di ricaduta, ed è stata una richiesta
   esplicita (11 agosto 2026): «rimuovi l'effetto lampeggio che si muove». Erano `ctaStar` —
   comparivano dal nulla, ruotavano di 14° e si rimpicciolivano, sempre negli stessi sei punti
   e sempre con la stessa cadenza. Accanto a una tela di scintille che ora stanno FERME e
   luccicano piano, quei sei lampi rotanti erano l'unica cosa che si muoveva sulla pillola: si
   leggevano come un difetto, non come magia.
   Restano dove la tela non c'è (niente JavaScript, o "riduci il movimento"): là sono l'unico
   bagliore a quattro punte che la pillola abbia. */
.listen-cta.spark-live .cta-ring-halo,
.listen-cta.spark-live .cta-ring-outer,
.listen-cta.spark-live .cta-ring-dots,
.listen-cta.spark-live .cta-ring-fine,
.listen-cta.spark-live .cta-star { display: none; }

@media (max-width: 768px) {
    .listen-cta { font-size: .85rem; letter-spacing: .18em; padding: 14px 34px; --cta-r: 24px; }
    .cta-star { width: 24px; height: 24px; margin: -12px 0 0 -12px; }
    .cta-star-4, .cta-star-5 { width: 18px; height: 18px; margin: -9px 0 0 -9px; }
}

@media (max-width: 480px) {
    .listen-cta { font-size: .78rem; letter-spacing: .15em; padding: 13px 26px; --cta-r: 21px; }
    .cta-ring-dots { stroke-width: 1.8 }
    .cta-ring-outer { stroke-width: 2.6 }
    .cta-ring-halo { stroke-width: 9 }
}

/* ============================
   Play button — now a real control
   ============================
   It used to be a picture with no audio behind it, so there was nothing to signal. The ring
   fills with the track's progress, the artwork dims behind a pause glyph, and the idle float
   stops: a button that has stopped bobbing reads as "this is running". */
.susan-play-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 132px;
    height: 132px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.susan-play-btn:focus-visible {
    outline: 2px solid var(--c-cyan);
    outline-offset: 6px;
    border-radius: 50%;
}

.susan-play-ring {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);   /* start the sweep at 12 o'clock */
    pointer-events: none;
    /* L'alone sfocato esce dal riquadro del disegno: ritagliato, si taglierebbe di netto. */
    overflow: visible;
}

.susan-play-ring circle { fill: none; }
/* Nessun cerchio attorno al bottone: l'artwork del play basta da solo, il contorno lo
   incorniciava e basta. Il binario resta nel DOM (l'arco di avanzamento ci gira sopra) ma
   non si disegna. */
.susan-play-ring-bg { stroke: transparent; }

/* L'avanzamento è la stessa cosa che gira attorno al LISTEN NOW: non una linea, ma una
   catena di scintille. Il trucco è quello di lassù (vedi `.cta-ring-dots`) — un tratteggio
   coi capi TONDI e la parte piena lunga quasi zero, così ogni trattino collassa in un disco.
   ⚠️ Qui però il tratteggio dice anche QUANTO si è ascoltato: la lista la scrive
   susan-app.js, e il CSS non deve toccare `stroke-dasharray` o si perde l'avanzamento.
   Due strati: l'alone sfocato che immerge la catena nella luce, e le scintille sopra. Il
   dorato è caduto: il disegno del bottone è dorato e i due si confondevano — questo bianco
   ciano è lo stesso della pillola, e a Susan gira già attorno a tre bottoni. */
.susan-play-ring-halo,
.susan-play-ring-bar {
    stroke-linecap: round;
    opacity: 0;
    transition: opacity .4s ease;
}

.susan-play-ring-halo {
    stroke: rgba(74, 205, 255, .55);
    stroke-width: 4.5;
    filter: blur(2.5px);
    animation: ctaBloom 4.8s ease-in-out infinite;
}

.susan-play-ring-bar {
    stroke: #eafeff;
    stroke-width: 1.8;
    /* Uno scorrimento di UN passo esatto: a fine ciclo la catena è sovrapposta a com'era e
       il giro si chiude senza scatti. Muove anche la scintilla di testa, di pochissimo —
       è quello che le fa sembrare vive invece che stampate. */
    animation: susanRingDrift 4.5s linear infinite;
}

@keyframes susanRingDrift {
    from { stroke-dashoffset: 0; }
    to   { stroke-dashoffset: -6; }
}

.susan-player.is-playing .susan-play-ring-halo,
.susan-player.is-playing .susan-play-ring-bar { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
    .susan-play-ring-bar { animation: none; }
}

/* La tela con le particelle vere — la stessa sabbia luminosa che gira attorno ai LISTEN NOW.
   Sta DIETRO l'artwork (z-index 0 contro 1 e 2): i granelli che vanno verso l'interno
   scompaiono sotto al bottone invece di attraversarlo. */
.play-spark-canvas {
    position: absolute;
    z-index: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity .5s ease;
}

.susan-player.is-playing .play-spark-canvas { opacity: 1; }

/* ⚠️ I due contorni dell'SVG sono la RICADUTA: senza JavaScript, o con "meno movimento"
   chiesto dal sistema, la tela non nasce e restano loro. Dove nasce, vanno tolti o si
   vedono due anelli sovrapposti — uno di puntini fermi e uno di scintille. */
.susan-play-btn.spark-live .susan-play-ring-halo,
.susan-play-btn.spark-live .susan-play-ring-bar { display: none; }

.susan-play-img {
    position: relative;
    z-index: 1;
    width: var(--play-size);
    height: auto;
    cursor: pointer;
    animation: susanFloat 3s ease-in-out infinite;
    transition: opacity .3s ease;
}

/* ⚠️ Mentre suona, l'artwork del play sparisce DEL TUTTO (prima si smorzava a .18, quando
   sopra c'erano solo due sbarre). Il disegno della pausa è un ANELLO: attraverso il suo
   buco si vedrebbe il play rimasto sotto, e sarebbero due bottoni sovrapposti. */
.susan-player.is-playing .susan-play-img { animation: none; opacity: 0; }

/* Il disegno della pausa, sovrapposto al play. Sta in mezzo per conto suo invece di stare
   in fila nel flex: i due devono occupare lo STESSO posto, non uno accanto all'altro.
   Le due immagini sono larghe uguale (--play-size) e i loro disegni riempiono la tela nella
   stessa misura — 194x199 e 195x199 su 256 — quindi si sovrappongono senza scarti. */
.susan-pause-img {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 2;
    width: var(--play-size);
    height: auto;
    opacity: 0;
    transition: opacity .3s ease;
    pointer-events: none;
}

.susan-player.is-playing .susan-pause-img { opacity: 1; }

/* Two bars, drawn only while playing. */
.susan-play-pause {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    opacity: 0;
    transition: opacity .3s ease;
    pointer-events: none;
}

.susan-play-pause::before,
.susan-play-pause::after {
    content: '';
    width: 8px;
    height: 34px;
    border-radius: 3px;
    background: var(--c-cyan);
    box-shadow: 0 0 12px rgba(133, 245, 255, .8);
}

.susan-player.is-playing .susan-play-pause { opacity: 1; }

/* No track supplied yet: keep the button visible but stop promising a response. */
.susan-player.is-silent .susan-play-btn { cursor: default; }

/* "Now Playing — Part I Sample", che compare mentre suona.
   ⚠️ È SOSPESA (`position: absolute`) sotto al bottone e non in fila con lui: entrando nel
   flusso spingerebbe in giù tutto ciò che sta sotto proprio nell'istante del click, e il
   sito partirebbe con un sussulto. Il posto c'è già: `.susan-player` ha 100px di margine
   in basso.
   `visibility` oltre a `opacity` perché una riga trasparente resta leggibile ai lettori di
   schermo e cliccabile: da ferma non deve esistere per nessuno. */
/* ⚠️ La misura del disegno del bottone sta QUI e in nessun altro posto: play e pausa devono
   restare grandi uguali, e prima erano due `width` da ricordarsi in tre media query. */
.susan-player {
    position: relative;
    --play-size: 100px;
}

.susan-now-playing {
    position: absolute;
    left: 50%;
    top: calc(100% + 14px);
    transform: translate(-50%, 6px);
    width: max-content;
    max-width: min(92vw, 460px);
    font-family: 'Cinzel', serif;
    font-size: .8rem;
    font-weight: 400;
    letter-spacing: .28em;
    line-height: 1.4;
    color: var(--c-cyan);
    text-shadow: 0 0 18px rgba(133, 245, 255, .45);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .45s ease, transform .45s ease, visibility 0s linear .45s;
}

.susan-player.is-playing .susan-now-playing {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
    transition: opacity .45s ease, transform .45s ease, visibility 0s;
    animation: susanNowPlaying 3.2s ease-in-out infinite;
}

/* Un respiro appena accennato: dice "sta andando" senza rubare l'occhio alla scritta. */
@keyframes susanNowPlaying {
    0%, 100% { text-shadow: 0 0 18px rgba(133, 245, 255, .45); }
    50%      { text-shadow: 0 0 26px rgba(133, 245, 255, .85); }
}

@media (prefers-reduced-motion: reduce) {
    .susan-player.is-playing .susan-now-playing { animation: none; }
}

/* ============================
   Contact + newsletter
   ============================ */
.contact-section {
    max-width: 1000px;
    margin: 0 auto;
    padding: 160px 2rem 100px;
    text-align: center;
}

.contact-title { color: var(--c-cyan); }

.contact-content {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 1s ease, transform 1s ease;
}

.contact-content.visible { opacity: 1; transform: translateY(0); }

.contact-subtitle {
    font-family: 'Cinzel', serif;
    font-weight: 400;
    font-size: 1.6rem;
    letter-spacing: .2em;
    color: var(--c-cyan);
    margin-bottom: 18px;
    text-shadow: var(--glow-body);
}

.contact-text {
    font-family: 'Cormorant', serif;
    font-style: italic;
    font-size: 1.5rem;
    line-height: 1.5;
    color: var(--c-body);
    margin-bottom: 34px;
}

.contact-form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 14px;
}

/* Label kept for screen readers — the visible cue is the placeholder. */
/* `clip` è deprecata ma è l'unica che alcuni lettori di schermo vecchi capiscono;
   `clip-path` è quella viva. Tenerle entrambe è la ricetta standard. */
.contact-sr {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Il segnaposto «Email address» era l'unica cosa allineata a sinistra in una sezione tutta
   centrata, e sullo schermo stretto si notava più del campo. Vale anche col mouse: quello che
   si scrive dentro resta centrato come il resto. */
.contact-input {
    font-family: 'Cormorant', serif;
    font-size: 1.1rem;
    color: #ffffff;
    text-align: center;
    width: 100%;
    max-width: 330px;
    padding: 13px 18px;
    background: rgba(1, 17, 38, .55);
    border: 1px solid rgba(133, 245, 255, .3);
    border-radius: 30px;
    transition: border-color .3s ease, box-shadow .3s ease;
}

.contact-input::placeholder { color: rgba(185, 249, 255, .5); }

.contact-input:focus {
    outline: none;
    border-color: rgba(133, 245, 255, .75);
    box-shadow: 0 0 16px rgba(133, 245, 255, .22);
}

/* Honeypot: off-screen and out of the tab order, but not display:none — bots skip that. */
.contact-hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    opacity: 0;
}

.contact-btn {
    font-family: 'Cinzel', serif;
    font-size: .85rem;
    letter-spacing: .2em;
    color: #cbba9b;
    background: none;
    padding: 13px 30px;
    border: 1px solid rgba(201, 169, 110, .35);
    border-radius: 30px;
    cursor: pointer;
    transition: all .35s ease;
    text-shadow: 0 0 10px rgba(201, 169, 110, .3);
}

.contact-btn:hover:not(:disabled) {
    border-color: rgba(201, 169, 110, .65);
    box-shadow: 0 0 20px rgba(201, 169, 110, .2);
    color: #e0cc9a;
}

.contact-btn:disabled { opacity: .45; cursor: default; }

.contact-status {
    font-family: 'Cormorant', serif;
    font-size: 1.05rem;
    min-height: 1.6em;
    margin-top: 16px;
    color: #b9f9ff;
}

.contact-status.ok { color: #9dffc8; }
.contact-status.err { color: #ffb0b0; }

/* Bianche su richiesta di Susan (2026-08-09), non del ciano smorzato: erano le due righe
   più spente della pagina e la seconda annuncia un indirizzo, cioè va letta. */
.contact-note {
    font-family: 'Cormorant', serif;
    font-style: italic;
    font-size: .95rem;
    color: #ffffff;
    margin-top: 6px;
}

/* ⚠️ Questa riga era nata SENZA regola: ereditava il Cinzel di <body>, che è un carattere
   tutto maiuscolo (le minuscole sono maiuscoletti), e il link restava il blu sottolineato
   del browser. Sembrava un avviso urlato appiccicato al modulo. Il testo ora è solo il
   rimando alla policy — l'informativa vera la dà `.contact-note` sopra — e vale meno della
   riga bianca che la precede: è un link di servizio, come quelli del piede. */
.contact-consent {
    font-family: 'Cormorant', serif;
    font-style: italic;
    font-size: .85rem;
    letter-spacing: .04em;
    color: rgba(185, 249, 255, .75);
    margin-top: 4px;
}

.contact-consent a {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid rgba(185, 249, 255, .35);
    cursor: pointer;
}

.contact-consent a:hover {
    color: #ffffff;
    border-bottom-color: #ffffff;
}

.contact-mail {
    font-family: 'Cormorant', serif;
    font-size: 1.05rem;
    color: rgba(185, 249, 255, .8);
    margin-top: 40px;
}

.contact-mail-label { color: #ffffff; }

.contact-mail-link {
    color: var(--c-cyan);
    text-decoration: none;
    border-bottom: 1px solid rgba(133, 245, 255, .3);
    transition: border-color .3s ease;
}

.contact-mail-link:hover { border-bottom-color: var(--c-cyan); }

@media (max-width: 768px) {
    .contact-section { padding: 100px 1.5rem 60px; }
    .contact-subtitle { font-size: 1.2rem; }
    .contact-text { font-size: 1.15rem; }
    .contact-input, .contact-btn { width: 100%; max-width: 320px; }
    .susan-play-btn { width: 100px; height: 100px; }
    .susan-play-pause::before, .susan-play-pause::after { height: 26px; width: 6px; }
}

@media (max-width: 480px) {
    .contact-section { padding: 70px 1rem 40px; }
    .contact-subtitle { font-size: 1.05rem; }
    .contact-text { font-size: 1.0625rem; }
    .susan-play-btn { width: 76px; height: 76px; }
    .susan-play-pause::before, .susan-play-pause::after { height: 20px; width: 5px; }
}

/* ============================
   Footer
   ============================ */
.susan-footer {
    position: relative;
    z-index: 2;
    padding: 20px 2rem 40px;
}

.susan-footer::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(201,169,110,.55) 10%, rgba(201,169,110,.55) 90%, transparent);
}

.footer-content {
    max-width: 700px;
    margin: 0 auto;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
}

/* Il piede era quasi invisibile: logo al 40%, link al 50% di ciano e un separatore al 20%
   su una foto già scura. Tutto alzato di un gradino e il copyright non è più grigio-su-blu. */
.footer-logo {
    width: 350px;
    height: auto;
    opacity: .8;
    transition: opacity .3s ease;
}

.footer-logo:hover { opacity: 1; }


/* ⚠️ Su una riga sola i quattro social non ci stanno sotto i ~370px: a 320px "Instagram"
   era tagliato a sinistra e "Pinterest" a destra, e non si vedeva perché `overflow-x: hidden`
   su <body> nasconde la barra di scorrimento invece di mostrare il problema. */
.footer-links {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 6px 12px;
}

/* Il padding verticale è tutto per il dito: 16px di testo sono metà del minimo di 24px
   (WCAG 2.2 §2.5.8). Solo verticale, perché in orizzontale i quattro social e le barrette
   che li separano sono già al limite della larghezza a 320px. */
.footer-link {
    font-family: 'Cinzel', serif;
    font-size: 1rem;
    letter-spacing: .15em;
    color: rgba(133,245,255,.92);
    text-decoration: none;
    text-shadow: var(--glow-body);
    padding: 6px 0;
    transition: color .3s ease, text-shadow .3s ease;
}

.footer-link:hover {
    color: #eafeff;
    text-shadow: var(--glow-heading);
}

.footer-sep {
    color: rgba(201,169,110,.5);
    font-size: 1rem;
}

.footer-copy {
    font-family: 'Cormorant', serif;
    font-size: .95rem;
    color: #ffffff;
    letter-spacing: .05em;
}

/* La riga legale sta sotto ai social e pesa meno: sono link di servizio, non di navigazione. */
.footer-legal {
    margin-top: -6px;
}

/* Bianchi pieni, non un bianco velato: sopra la foto scura un 72% leggeva grigio.
   ⚠️ Serve la specificità di due classi — `.footer-link` da solo li colorerebbe di ciano. */
.footer-link.footer-legal-link {
    font-family: 'Cormorant', serif;
    font-size: .95rem;
    letter-spacing: .08em;
    color: #ffffff;
    text-shadow: none;
    cursor: pointer;
}

.footer-link.footer-legal-link:hover {
    color: #ffffff;
    text-shadow: var(--glow-body);
}

/* ============================
   Modali legali (Privacy / Cookie)
   ============================
   Un solo elemento in fondo al <body>, riempito al volo: due modali identici tranne il testo
   sarebbero due punti da tenere allineati. `z-index` sopra le particelle (100) e sopra la
   barra incollata (500), altrimenti la barra ci passerebbe davanti. */
.susan-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 5vh 1.5rem;
    background: rgba(0, 6, 16, .78);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    opacity: 0;
    visibility: hidden;
    transition: opacity .28s ease, visibility .28s ease;
}

.susan-modal.is-open {
    opacity: 1;
    visibility: visible;
}

/* La finestra NON cresce col testo: si ferma all'altezza dello schermo e a scorrere è il
   corpo, non la pagina dietro. È tutto il senso della richiesta "scroll fatto bene". */
.susan-modal-box {
    position: relative;
    width: 100%;
    max-width: 760px;
    max-height: 90vh;
    max-height: 90dvh;   /* col telefono, `vh` conta anche la barra dell'indirizzo: la finestra usciva sotto */
    display: flex;
    flex-direction: column;
    background: rgba(3, 20, 44, .97);
    border: 1px solid rgba(201, 169, 110, .45);
    border-radius: 10px;
    box-shadow: 0 30px 80px rgba(0, 0, 0, .6);
    transform: translateY(18px) scale(.98);
    transition: transform .28s ease;
}

.susan-modal.is-open .susan-modal-box { transform: translateY(0) scale(1); }

.susan-modal-head {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 22px 24px 16px;
    border-bottom: 1px solid rgba(201, 169, 110, .3);
}

.susan-modal-title {
    font-family: 'Cinzel', serif;
    font-size: 1.35rem;
    letter-spacing: .14em;
    color: var(--c-gold);
    margin: 0;
}

.susan-modal-close {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;           /* 40px: si prende col dito senza mirare */
    border: 1px solid rgba(201, 169, 110, .4);
    border-radius: 50%;
    background: transparent;
    color: var(--c-gold);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
    transition: background .25s ease, color .25s ease;
}

.susan-modal-close:hover { background: rgba(240, 214, 128, .14); }
.susan-modal-close:focus-visible { outline: 2px solid var(--c-cyan); outline-offset: 2px; }

/* `min-height: 0` è obbligatorio: senza, un figlio flex non si lascia rimpicciolire sotto il
   suo contenuto e la scrollbar non compare mai — la finestra sfonderebbe lo schermo. */
.susan-modal-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;   /* arrivati in fondo NON si trascina la pagina dietro */
    -webkit-overflow-scrolling: touch;
    padding: 20px 24px 28px;
}

.susan-modal-body::-webkit-scrollbar { width: 10px; }
.susan-modal-body::-webkit-scrollbar-track { background: rgba(255, 255, 255, .05); border-radius: 8px; }
.susan-modal-body::-webkit-scrollbar-thumb {
    background: rgba(201, 169, 110, .5);
    border-radius: 8px;
    border: 2px solid transparent;
    background-clip: content-box;
}
.susan-modal-body::-webkit-scrollbar-thumb:hover { background: rgba(240, 214, 128, .75); background-clip: content-box; }
.susan-modal-body { scrollbar-width: thin; scrollbar-color: rgba(201, 169, 110, .6) rgba(255, 255, 255, .05); }

.susan-modal-body h3 {
    font-family: 'Cinzel', serif;
    font-size: 1rem;
    letter-spacing: .1em;
    color: var(--c-cyan);
    margin: 22px 0 8px;
}

.susan-modal-body h3:first-child { margin-top: 0; }

.susan-modal-body p,
.susan-modal-body li {
    font-family: 'Cormorant', serif;
    font-size: 1.1rem;
    line-height: 1.65;
    color: #ffffff;
    margin: 0 0 10px;
}

.susan-modal-body ul { margin: 0 0 12px; padding-left: 1.3rem; }
.susan-modal-body li { margin-bottom: 6px; }
.susan-modal-body a { color: var(--c-cyan); }

/* La data in cima al documento: c'è per obbligo, non deve pesare come il testo. */
.susan-modal-body .legal-updated,
.legal-doc-body .legal-updated {
    font-style: italic;
    color: rgba(255, 255, 255, .55);
    font-size: .95rem;
}

/* Mentre il modale è aperto la pagina dietro non deve scorrere. */
body.susan-modal-open { overflow: hidden; }

@media (max-width: 600px) {
    .susan-modal { padding: 0; }
    .susan-modal-box {
        max-height: 100vh;
        max-height: 100dvh;
        height: 100%;
        border-radius: 0;
        border-left: 0;
        border-right: 0;
    }
    .susan-modal-title { font-size: 1.05rem; }
    .susan-modal-body p, .susan-modal-body li { font-size: 1.0625rem; }
}

/* ============================
   Documenti legali stampati nella pagina
   ============================
   Privacy e cookie policy stanno DENTRO index.html, in fondo, e non nel JavaScript: se il
   bundle non arriva (lo serve WordPress) i due link del piede devono comunque portare a un
   testo. Di norma sono nascosti; `:target` li apre senza una riga di script, ed è la via che
   percorre chi non ha JavaScript. Con JavaScript acceso il click viene intercettato prima e
   il testo compare nel modale, quindi qui sotto non ci si arriva quasi mai. */
.legal-doc { display: none; }

.legal-doc:target {
    display: block;
    max-width: 760px;
    margin: 0 auto 4rem;
    padding: 2rem 1.5rem 1.5rem;
    background: rgba(3, 20, 44, .92);
    border: 1px solid rgba(201, 169, 110, .45);
    border-radius: 10px;
    /* La barra del menu è incollata in alto: senza questo, l'ancora porta il titolo
       esattamente sotto di essa e sembra che il documento cominci dal secondo paragrafo. */
    scroll-margin-top: 90px;
}

.legal-doc-title {
    font-family: 'Cinzel', serif;
    font-size: 1.2rem;
    letter-spacing: .12em;
    color: var(--c-gold);
    margin: 0 0 1rem;
}

.legal-doc-body h3 {
    font-family: 'Cinzel', serif;
    font-size: 1rem;
    letter-spacing: .1em;
    color: var(--c-cyan);
    margin: 22px 0 8px;
}

.legal-doc-body h3:first-child { margin-top: 0; }

.legal-doc-body p,
.legal-doc-body li {
    font-family: 'Cormorant', serif;
    font-size: 1.1rem;
    line-height: 1.65;
    color: #ffffff;
    margin: 0 0 10px;
}

.legal-doc-body ul { margin: 0 0 12px; padding-left: 1.3rem; }
.legal-doc-body li { margin-bottom: 6px; }
.legal-doc-body a { color: var(--c-cyan); }

.legal-doc-close { margin: 1.5rem 0 0; }
.legal-doc-close a {
    font-family: 'Cinzel', serif;
    font-size: .8rem;
    letter-spacing: .12em;
    color: var(--c-gold);
    text-decoration: none;
}
/* Nel modale il documento si chiude con la ×: la riga «torna in cima» servirebbe solo a
   portare la pagina DIETRO al modale in cima, cioè a niente. Il clone parte da
   `.legal-doc-body`, quindi normalmente non la contiene — la regola è la rete di sicurezza. */
.susan-modal-body .legal-doc-close { display: none; }

/* ============================
   Avviso su cookie e dati
   ============================
   ⚠️ È un AVVISO, non un banner di consenso, e la differenza è voluta: il sito non mette
   cookie, non ha statistiche né pubblicità e non carica niente da terzi (i caratteri sono
   ospitati qui dal 2026-08-09). Non c'è nulla da autorizzare, quindi non c'è un "rifiuta" —
   un bottone che non rifiuta niente è teatro. Se un giorno entrano statistiche o un player
   incorporato, questo va rifatto come consenso vero. Il dettaglio in js/susan-app.js.

   `z-index` sotto il modale (1000): dai link dell'avviso si aprono le policy, e l'avviso non
   deve restare davanti al testo che ha appena aperto. */
.susan-notice {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 900;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .75rem 1.25rem;
    padding: .85rem 1.25rem;
    /* `env(safe-area-inset-bottom)`: sull'iPhone la barra gesti mangerebbe il bottone. */
    padding-bottom: calc(.85rem + env(safe-area-inset-bottom, 0px));
    background: rgba(3, 20, 44, .96);
    border-top: 1px solid rgba(201, 169, 110, .45);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    box-shadow: 0 -14px 40px rgba(0, 0, 0, .45);
    transform: translateY(110%);
    transition: transform .35s ease;
}

.susan-notice.is-open { transform: translateY(0); }

/* ⚠️ Finché l'avviso è aperto la pagina si allunga della sua altezza, altrimenti la barra si
   siede sopra i due link delle policy nel piede: si vedono e non si cliccano. L'altezza la
   misura il JavaScript (il testo va a capo diversamente a ogni larghezza) e la scrive qui. */
body.susan-notice-on { padding-bottom: var(--susan-notice-h, 0px); }

.susan-notice-text {
    font-family: 'Cormorant', serif;
    font-size: 1.02rem;
    line-height: 1.5;
    color: #ffffff;
    margin: 0;
    text-align: center;
}

.susan-notice-link { color: var(--c-cyan); }

.susan-notice-btn {
    flex: 0 0 auto;
    /* 44px pieni: è un bersaglio da dito, e il resto del sito è già a quella misura. */
    min-height: 44px;
    padding: .5rem 1.5rem;
    font-family: 'Cinzel', serif;
    font-size: .8rem;
    letter-spacing: .12em;
    color: #03142c;
    background: var(--c-gold);
    border: 0;
    border-radius: 999px;
    cursor: pointer;
    transition: filter .2s ease;
}

.susan-notice-btn:hover { filter: brightness(1.12); }
.susan-notice-btn:focus-visible { outline: 2px solid var(--c-cyan); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
    .susan-notice { transition: none; }
}

@media (max-width: 600px) {
    .susan-notice { gap: .6rem; padding: .75rem 1rem; }
    .susan-notice-text { font-size: .95rem; }
    .legal-doc:target { margin: 0 .75rem 3rem; padding: 1.5rem 1.1rem 1.1rem; }
}

/* ============================
   Cinematic fade-in (Section 1 & 2)
   ============================ */
.susan-cinematic {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 1.2s ease, transform 1.2s ease;
}

.susan-cinematic.visible {
    opacity: 1;
    transform: translateY(0);
}

.susan-s2-cta.susan-cinematic.visible {
    animation: susanCtaFloat 3s ease-in-out infinite;
}

.susan-s2-body-line {
    font-family: 'Cormorant', serif;
    font-weight: 400;
    font-size: var(--fs-body);
    font-style: italic;
    line-height: 1.5;
    color: var(--c-body);
    margin-bottom: 0.6rem;
}


/* ============================
   Responsive — Clean
   ============================ */

/* Prevent horizontal overflow.
   ⚠️ `overflow-x: hidden` va su <body>, MAI su <html>: su <html> il documento diventa lui
   stesso il contenitore che scorre, e in quel caso `position: sticky` non ha più un
   antenato scorrevole rispetto a cui incollarsi — la barra del menu smette di funzionare
   in mezzo browser senza che nulla lo lasci intuire. Su <body> il taglio orizzontale
   resta identico e lo sticky continua a funzionare. */
body { overflow-x: hidden; }

/* Titoli centrati: `balance` distribuisce le righe invece di lasciare una parola sola
   sull'ultima — è il difetto tipico di un titolo lungo su uno schermo stretto. `pretty`
   fa lo stesso lavoro sui paragrafi, ma solo sull'ultima riga. Dove non esistono, i
   browser le ignorano: nessuna ricaduta da gestire. */
.susan-s2-title,
.about-title,
.contact-subtitle,
.part-logo-text,
.part-panel-title,
.ch-name {
    text-wrap: balance;
}

.susan-s2-body-line,
.about-text,
.contact-text,
.contact-note {
    text-wrap: pretty;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* Lapide: qui c'era `html, body { background-attachment: scroll }` sotto i 1024px. Non serve
   più a niente da quando la foto ha un layer suo (`.susan-bg`): html e body non hanno più
   nessuna immagine di sfondo su cui quella proprietà possa agire. Rimessa "per sicurezza"
   non farebbe danni, ma manderebbe di nuovo a cercare il difetto della banda scura nel posto
   sbagliato — sta nell'altezza del layer fisso, non nell'ancoraggio dello sfondo. */

/* Tablet (768px - 1024px) */
@media (max-width: 1024px) {
    /* ⚠️ Il corpo scende una volta sola, sul token: `.susan-s2-body-line`, `.about-text` e
       `.about-text-intro` lo leggono tutti e tre. Riscriverne uno solo qui è esattamente
       il modo in cui le tre misure erano andate alla deriva. */
    :root { --fs-body: 1.6rem; }
    .susan-s2-title { font-size: 1.8rem; }
    .susan-c1-content { padding-top: 150px; }
    .about-section { padding: 150px 2rem 80px; }
    .about-title { font-size: 2rem; }
    .about-content { gap: 1.8rem; }
    .footer-logo { width: 280px; }
}

/* Mobile (480px - 768px) */
@media (max-width: 768px) {
    /* Hero */
    .susan-hero { padding: 2rem 0; overflow: hidden; }
    .susan-logo-home, .susan-logo { width: 82%; max-width: 420px; margin-top: 24vh; padding: 0; }
    .susan-texts { margin-top: 150px; }
    .susan-text { font-size: 0.85rem; letter-spacing: 0.2em; }
    .susan-text-2 { font-size: 1.4rem; margin-top: 6rem; }
    .susan-text-3 { font-size: 1.6rem; margin-top: 6rem; }
    .susan-player { margin-top: 5rem; --play-size: 70px; }

    /* Navbar.
       ⚠️ L'area toccabile di una voce era alta quanto il testo: ~15px, un terzo dei 44px
       minimi (WCAG 2.5.8). Il padding verticale su un <a> inline non allarga la riga; qui
       però le voci sono figlie di un flex container, quindi sono già "blocchi" e una
       min-height le fa crescere davvero. Il fondo della barra resta sotto i 64px di
       --nav-h, che è la misura con cui le ancore evitano di finirci sotto. */
    .susan-navbar-links { flex-wrap: wrap; gap: 0.25rem; padding: 0.3rem 0; }
    .susan-navbar-link {
        display: flex;
        align-items: center;
        min-height: 44px;
        padding: 0 0.8rem;
        font-size: 0.78rem;
        letter-spacing: 0.15em;
    }
    .susan-navbar-link-center { font-size: 0.85rem; }
    .susan-navbar-divider { display: none; }
    .susan-navbar-line { width: 90%; }

    /* Section 2 */
    .susan-container1 { padding: 2rem 1.5rem; }
    .susan-c1-content { padding-top: 80px; }

    /* ⚠️ Stessa trappola della copertina: `margin-top:-92px` arriva come stile INLINE da
       default-layout.json. Al desktop il titolo ha ~190px di aria sotto la barra e quei 92px
       lo accostano soltanto; sul telefono l'aria scende a ~14px, quindi il titolo finisce
       DENTRO la barra — e la barra è trasparente finché non è `is-stuck`, così "A STORY FROM
       THE DEEP" si legge attraverso le voci del menu. Serve !important: è l'unico modo di
       annullare un inline senza togliere l'accostamento anche al desktop. */
    .susan-s2-title { margin-top: 0 !important; }
    .susan-s2-body-line[style] { margin-top: 0 !important; }

    :root { --fs-body: 1.2rem; }
    .susan-s2-title { font-size: 1.4rem; letter-spacing: 0.15em; }
    .susan-s2-italic { font-size: 0.96875rem; margin-top: 30px; }


    /* About */
    .about-section { padding: 120px 1.5rem 60px; }
    /* Solo sul telefono il nome di Susanna sta in grassetto: il corsivo da solo, alle
       misure piccole, non lo staccava abbastanza dal resto del paragrafo. */
    .about-text em { font-weight: 700; }
    .about-title { font-size: 1.8rem; letter-spacing: 0.15em; }
    .about-content { gap: 1.4rem; }
    .about-text-intro { max-width: 100%; }
    :root { --divider-w: 140px; }

    /* Footer */
    .footer-logo { width: 200px; }
    .footer-link { font-size: 0.85rem; }
    .footer-sep { font-size: 0.85rem; }
    .footer-links { gap: 10px; }

}

/* Il telefono in orizzontale è LARGO (844, 932…) ma bassissimo: cade fuori dai 768px qui
   sopra e si riprendeva tutti i -92px del titolo, lasciando 5px fra "A STORY FROM THE DEEP"
   e la riga d'oro della barra. Qui il discriminante giusto non è la larghezza ma l'altezza. */
@media (max-height: 500px) and (orientation: landscape) {
    .susan-s2-title { margin-top: 0 !important; }
    .susan-s2-body-line[style] { margin-top: 0 !important; }
}

/* Small mobile (320px - 480px) */
@media (max-width: 480px) {
    /* Hero */
    .susan-logo-home, .susan-logo { width: 86%; max-width: 300px; margin-top: 20vh; padding: 0; }
    .susan-texts { margin-top: 80px; }
    .susan-text { font-size: 0.7rem; letter-spacing: 0.12em; }
    .susan-text-2 { font-size: 1.1rem; margin-top: 4rem; }
    .susan-text-3 { font-size: 1.3rem; margin-top: 4rem; }
    .susan-player { margin-top: 3rem; margin-bottom: 40px; --play-size: 50px; }
    /* Sul telefono la riga con .28em di spaziatura andava a capo storta: qui sta stretta. */
    .susan-now-playing { font-size: .66rem; letter-spacing: .18em; top: calc(100% + 10px); }

    /* Navbar (l'altezza minima di 44px arriva dal breakpoint sopra e resta) */
    .susan-navbar-links { padding: 0.2rem 0; }
    .susan-navbar-link { padding: 0 0.55rem; font-size: 0.68rem; letter-spacing: 0.1em; }
    .susan-navbar-link-center { font-size: 0.76rem; }
    .susan-navbar-line { width: 95%; }

    /* Section 2 */
    .susan-c1-content { padding-top: 50px; }
    :root { --fs-body: 1.0625rem; }
    .susan-s2-title { font-size: 1.1rem; letter-spacing: 0.1em; }
    .susan-s2-italic { font-size: 0.96875rem; margin-top: 20px; }


    /* About */
    .about-section { padding: 80px 1rem 40px; }
    .about-title { font-size: 1.4rem; letter-spacing: 0.1em; }
    .about-content { gap: 1.2rem; }
    :root { --divider-w: 100px; }

    /* Footer. I fianchi da 2rem, su uno schermo da 320-480px, sono fino al 20% della
       larghezza: è quello che mandava a capo i quattro social. */
    .susan-footer { padding: 20px 1rem 32px; }
    .footer-logo { width: 160px; }
    .footer-link { font-size: 0.75rem; }
    .footer-sep { font-size: 0.75rem; }
    .footer-links { gap: 6px 8px; }
    .footer-copy { font-size: 0.7rem; }
}

/* Schermi minuscoli (Galaxy Fold chiuso ≈ 280px, iPhone SE 1ª ≈ 320px).
   ⚠️ La soglia è 374px e non un numero tondo: MISURATA. La fila dei quattro social con le
   barrette chiede 336px, e con i fianchi da 1rem del piede quella misura entra a partire da
   375px (l'iPhone SE 2ª/3ª). Sotto, la riga va a capo e l'ultima finirebbe con un "|"
   appeso nel vuoto — quindi lì le barrette spariscono e a separare resta lo spazio. */
@media (max-width: 374px) {
    .footer-sep { display: none; }
    .footer-links { gap: 8px 18px; }
    .contact-mail { font-size: .95rem; }
    .contact-mail-link { overflow-wrap: anywhere; }
}

/* Landscape mobile */
@media (orientation: landscape) and (max-height: 500px) {
    .susan-hero { min-height: auto; padding: 1rem; }
    .susan-container { min-height: auto; }
    .susan-logo-home, .susan-logo { margin-top: 8vh; max-width: 260px; width: 70%; }
    .susan-texts { margin-top: 30px; }
    .susan-text-2 { margin-top: 2rem; }
    .susan-text-3 { margin-top: 2rem; }
    .susan-player { margin-top: 2rem; margin-bottom: 20px; }

    /* Il telefono coricato è largo ma bassissimo: una copertina all'85% della larghezza è
       quadrata, quindi diventa più alta dello schermo e da sola riempie tutta la vista.
       Qui il limite lo detta l'ALTEZZA disponibile, non la larghezza. */
    .parts-carousel { padding-top: 70px; }
    .part-cover { max-width: min(380px, 62vh); }
    .part-logo-text { min-height: 110px; font-size: 1.6rem; }
    .part-panel { min-height: 110px; }
    .part-panel-title { font-size: 1.6rem; }
    .about-section { padding: 80px 1.5rem 50px; }
}

/* Touch devices - disable hover effects.
   ⚠️ Su un dispositivo touch il :hover resta APPICCICATO dopo il tocco, quindi qui va
   riportato il valore normale, non uno diverso: la vecchia riga del piede lasciava il link
   toccato a metà ciano (.5 contro .92) — cioè più spento di prima di toccarlo. */
@media (hover: none) {
    .susan-navbar-link:hover { color: #85F5FF; text-shadow: 0 0 15px rgba(133,245,255,.5), 0 0 40px rgba(133,245,255,.25), 0 0 60px rgba(133,245,255,.1); }
    .footer-link:hover { color: rgba(133,245,255,.92); text-shadow: var(--glow-body); }
    .footer-link.footer-legal-link:hover { color: #ffffff; text-shadow: none; }
    .ch-cta:hover { background: none; border-color: rgba(133,245,255,.2); }
    /* Un tablet largo tiene i pallini: senza questa riga quello toccato resterebbe acceso
       come se fosse la sezione corrente, contraddicendo l'aria-current vero. */
    .susan-scroll-dot:hover::before { border-color: rgba(133, 245, 255, .5); box-shadow: none; }
    .susan-scroll-dot[aria-current="true"]:hover::before {
        border-color: #85F5FF;
        box-shadow: 0 0 10px rgba(133, 245, 255, .6), 0 0 22px rgba(133, 245, 255, .35);
    }
    .parts-arrow:hover:not(:disabled) { border-color: rgba(133,245,255,.25); box-shadow: none; }
    /* ⚠️ Serve anche qui, non solo per pignoleria: senza, la pillola toccata sul telefono
       resta accesa al massimo finché non si tocca altrove, e sembra "selezionata". */
    .listen-cta:hover {
        color: #d7f7ff;
        background: rgba(1, 17, 38, .12);
    }
    .listen-cta:hover .cta-ring-dots { stroke: #eafeff; stroke-width: 2; }
    .listen-cta:hover .cta-ring-halo { stroke: rgba(74, 205, 255, .5); }
    .about-cta:hover, .contact-btn:hover:not(:disabled) {
        border-color: rgba(201,169,110,.3);
        box-shadow: none;
        color: #cbba9b;
    }
}

/* Backdrop-filter fallback.
   ⚠️ La condizione va scritta come "né l'una né l'altra": chiedendo solo la forma senza
   prefisso, Safari (che per anni ha conosciuto solo `-webkit-backdrop-filter`) entrava
   comunque nel ramo di ricaduta e si prendeva DUE fondi sovrapposti. E dove la sfocatura
   davvero non esiste, senza un fondo pieno le voci del menu restano illeggibili sopra
   l'acqua chiara. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .susan-navbar { background: rgba(1, 17, 38, 0.85); }
    .susan-modal { background: rgba(0, 6, 16, .94); }
}


/* ============================
   «WHERE TO LISTEN» — IL MOLO (listen.html → /listen)
   ============================
   I tre LISTEN NOW non fanno più niente da soli: portano qui, e qui si sceglie dove ascoltare.

   ⚠️ TRE DISEGNI IN UN GIORNO (14 agosto 2026), e vale la pena sapere perché, o il prossimo
   giro ricomincia dal primo.
   1. Tredici RIGHE col lucchetto: si leggevano come un fallimento ripetuto tredici volte.
   2. Una COSTA di fari accesi sull'orizzonte: bella, e con un difetto che si vede solo
      usandola — chi cerca «Spotify» cerca il VERDE di Spotify, non un nome in Cinzel sotto
      una lampada. Su una pagina che esiste per SCEGLIERE, il marchio non è decorazione: è
      l'unica cosa che l'occhio cerca davvero.
   3. Ogni piattaforma un RIQUADRO DI VETRO col suo marchio vero, in griglia, i tre gruppi su
      tre ripiani.
   4. (12 agosto 2026, chiesto da Susan): NESSUNA ICONA, e una COLONNA SOLA. I riquadri
      di vetro restano, i marchi no, i gruppi sì. Il numero 2 diceva che chi cerca Spotify
      cerca il verde di Spotify: vero quando i marchi sono sparsi in una griglia da guardare a
      colpo d'occhio — meno quando la stessa lista si legge dall'alto in basso, dove a guidare
      è il GRUPPO («si compra», «c'è nell'abbonamento», «la presta la biblioteca») e non il
      colore. Tolti i marchi, la pagina torna al linguaggio del resto del sito: aria, luce,
      lettere. Se un giorno si vuole tornare al 3, si torna interi — non con un'iconcina.
   5. QUESTO (12 agosto 2026, stesso giorno, chiesto da Susan): NIENTE CORNICI. Via anche i
      riquadri di vetro: restano i nomi in fila, e a sinistra scende una CORRENTE — un filo di
      luce con un pallino per riga, che si accende scendendo. È il passo che il numero 4 aveva
      cominciato: senza marchi, il vetro non conteneva più niente da contenere: teneva insieme
      dei nomi che il filo tiene insieme meglio, perché lo fa una volta sola per tutta la
      colonna invece di tredici volte. E la pagina torna a essere fatta di acqua e luce.

   ⚠️ IL PROBLEMA CHE IL VETRO RISOLVEVA NON È SPARITO CON LUI, e chiunque tolga qualcosa qui
   deve saperlo: sull'acqua CHIARA (la foto sotto non è scura dappertutto) dei nomi nudi si
   perdono — è già successo al disegno numero 1, che si portava dietro un velo scuro su tutta
   la colonna, tolto l'11 agosto perché si vedeva come un rettangolo. La cura, oggi, è l'ALONE
   SCURO SUL TESTO (vedi `.lh-name`): si attacca alle lettere, non ha bordi, e non si vede mai
   come una forma. È la stessa di tutto il resto del sito. Se un giorno i nomi tornassero a
   impastarsi col fondo, si rinforza QUELLO — non si rimette un pannello, né «un contorno
   leggero», che è una cornice con un altro nome.

   ⚠️ Lo decide sempre e solo l'INDIRIZZO nel JSON: senza href la riga è smorzata e non è un
   link. Lo stato MISTO (poche aperte e molte no) è il caso per cui il disegno è fatto: a
   distinguerle sono il PALLINO sul filo (pieno di luce se è aperta, un cerchietto vuoto se
   no) e la promessa «Listen» d'oro subito accanto al nome — che c'è solo dove si può premere,
   e che si legge insieme al nome invece che a mezzo schermo di distanza.

   ⚠️ La pagina NON ha la barra del menu della home, ed è voluto: da qui si torna indietro,
   non si naviga. Le due vie di ritorno (il logo in cima, la riga in fondo) bastano. */
.listen-hall {
    /* Alta almeno quanto lo schermo: sotto, il molo finirebbe a metà pagina con l'acqua
       vuota sotto, e sembrerebbe un pezzo staccato. */
    min-height: 100vh;
    min-height: 100lvh;
    display: flex;
    align-items: flex-start;
    justify-content: center;
}

.lh-wrap {
    position: relative;
    width: 100%;
    max-width: 940px;
    margin: 0 auto;
    padding: 76px 2rem 110px;
    text-align: center;
}

/* ⚠️ QUI C'ERA UN VELO SCURO, ED È STATO TOLTO (11 agosto 2026, chiesto da Susan).
   Era una fascia di buio su tutta la colonna — nata quando la pagina era una LISTA di nomi
   nudi, che sull'acqua chiara non si leggevano. Con i riquadri di vetro quel problema non
   esiste più: ogni marchio si porta il suo fondo. Restava solo il danno, e si vedeva —
   un rettangolo scuro dai bordi sfumati appoggiato dietro il logo e il titolo, che li
   spegneva. Il velo era l'unico posto della pagina in cui si vedeva un pannello.

   La leggibilità di ciò che sta sull'acqua nuda (il logo, il titolo, i nomi dei ripiani, il
   link di ritorno) ora la fa un ALONE SCURO SUL TESTO invece che un riquadro dietro: si
   attacca alle lettere, non ha bordi, e non si vede mai come una forma. È la stessa idea del
   resto del sito, dove ogni scritta porta la sua luce.
   ⚠️ Se un giorno torna del testo nudo su acqua chiara, la cura è quella — non un velo. */

.lh-home {
    display: inline-block;
    line-height: 0;
}

.lh-logo {
    width: 300px;
    max-width: 72%;
    height: auto;
    /* Due ombre e non una: la prima è la LUCE del logo, la seconda è il suo stacco
       dall'acqua. Con la sola luce dorata, su un mare mosso e chiaro il logo si impastava
       col fondo — ed è il primo che si vede. */
    filter: drop-shadow(0 0 26px rgba(240, 214, 128, .42))
            drop-shadow(0 3px 18px rgba(0, 8, 18, .85));
    transition: filter .35s ease;
}

.lh-home:hover .lh-logo {
    filter: drop-shadow(0 0 34px rgba(240, 214, 128, .62))
            drop-shadow(0 3px 18px rgba(0, 8, 18, .85));
}

.lh-title {
    font-family: 'Cinzel', serif;
    font-size: 2.2rem;
    font-weight: 400;
    letter-spacing: .25em;
    color: var(--c-cyan);
    /* L'alone del sito PIÙ un'ombra scura stretta: è quest'ultima a staccare le lettere
       dall'acqua senza mettere niente dietro di loro. Va per ultima o le luci ciano le
       passano sopra e non si vede. */
    text-shadow: var(--glow-heading), 0 2px 20px rgba(0, 8, 18, .9);
    margin: 2.6rem 0 0;
}

.lh-intro {
    font-family: 'Cormorant', serif;
    font-size: 1.25rem;
    line-height: 1.6;
    color: var(--c-body);
    max-width: 600px;
    margin: 2.2rem auto 0;
}

.lh-italic {
    font-family: 'Cormorant', serif;
    font-style: italic;
    font-weight: 300;
    font-size: 1.5rem;
    color: var(--c-cyan);
    text-shadow: var(--glow-body), 0 2px 16px rgba(0, 8, 18, .9);
    margin: 1.1rem 0 0;
}

/* ---- il molo ----
   ⚠️ Una COLONNA, e stretta: 560px di testo, non i 940 della testata. Dal 12 agosto 2026 le
   piattaforme sono nomi senza marchio (vedi `beacon()` nel renderer), e un nome scritto in
   Cinzel dentro una barra larga tutta la pagina è una riga di testo con mezzo metro di vuoto
   a destra — si legge come una tabella, non come un elenco da cui si sceglie. Stretta, la
   colonna si guarda dall'alto in basso in un colpo solo, che è il gesto giusto qui.
   ⚠️ `margin: auto` sui lati: il contenitore è più stretto della pagina, e senza resterebbe
   attaccato a sinistra sotto un titolo centrato.

   ⚠️ 12 agosto 2026, secondo giro (chiesto da Susan): VIA LE CORNICI, DENTRO LA CORRENTE.
   Il molo non ha più tredici riquadri di vetro ma tredici NOMI NUDI in fila, e a tenerli
   insieme è un filo di luce che scende sul lato sinistro. Le due cose sono una cosa sola: la
   cornice serviva a dire «questi tredici stanno insieme e sono cose su cui si preme», e la
   diceva tredici volte, una per riga; il filo lo dice UNA VOLTA SOLA per tutta la colonna,
   e in più dice da dove si comincia e dove si finisce. Tolte le cornici, il fondo del sito
   torna a vedersi attraverso l'elenco invece di essere coperto da tredici rettangoli.
   ⚠️ Non si rimetta «solo un contorno leggero» per far capire che si può premere: è
   esattamente ciò che è stato tolto. A dirlo sono il pallino sul filo, il «Listen →» d'oro
   sul margine e lo scarto di lato sotto il cursore.
   ⚠️ Le due misure del filo stanno QUI e non nelle regole che lo usano: le usano in tre
   (il filo, i pallini, i rientri), e su tre numeri scritti a mano il pallino si scentra di
   un pixel al primo che ne cambia uno.
   `--rail-x` è dove corre il filo dentro il molo, `--rail` quanto la colonna si scosta da
   lui: il pallino sta a `--rail-x - --rail` dal bordo della riga, cioè esattamente sul filo. */
.lh-coast {
    --rail-x: 7px;
    --rail: 30px;
    position: relative;
    max-width: 590px;
    margin: 3rem auto 0;
    padding-left: var(--rail);
    text-align: left;
}

/* ---- la corrente ----
   Il filo che scende a sinistra dell'elenco, e che è la ragione per cui le cornici hanno
   potuto andarsene. Tre livelli sovrapposti, ognuno con un compito diverso, ed è la somma a
   farlo leggere come acqua che scorre invece che come un bordo:
     1. il filo a riposo (questo elemento) — oro tenue, sfumato ai due capi come tutti i
        divisori del sito: un filo che comincia e finisce di netto sembra tagliato;
     2. `.lh-stream-flow` — la parte ACCESA, ciano, che cresce dall'alto verso il basso man
        mano che si scende (`--flow`, mosso da GSAP sullo scorrimento);
     3. `.lh-stream-comet` — la luce che scivola giù in continuazione, da sola.
   ⚠️ `aria-hidden` nel markup e nessun testo qui dentro: è un disegno, e a chi legge con le
   orecchie l'elenco arriva già in ordine dal suo `<ul>`.
   ⚠️ Sta DENTRO `.lh-coast` e non dentro i singoli ripiani: è una corrente sola per tutta la
   costa, quindi attraversa anche le intestazioni. Uno spezzone per ripiano darebbe tre fili
   staccati, cioè tre elenchi invece di uno. */
.lh-stream {
    position: absolute;
    left: var(--rail-x);
    top: .4rem;
    bottom: .4rem;
    width: 1px;
    pointer-events: none;
    background: linear-gradient(180deg,
        rgba(201, 169, 110, 0),
        rgba(201, 169, 110, .3) 7%,
        rgba(201, 169, 110, .3) 93%,
        rgba(201, 169, 110, 0));
}

/* La parte accesa. `--flow` va da 0 a 1 sullo scorrimento; il valore di riposo è 1, cioè la
   corrente TUTTA ACCESA — senza JavaScript, o con «meno movimento», la pagina è quella
   completa. È la stessa scelta di `--lit` sui ripiani, e per la stessa ragione.
   ⚠️ `scaleY` e non `height`: l'altezza rifà il calcolo della pagina a ogni fotogramma dello
   scorrimento, la scala no. `transform-origin` in cima o la corrente crescerebbe dal centro
   verso i due capi, che è l'esatto contrario di ciò che deve raccontare. */
.lh-stream-flow {
    position: absolute;
    inset: 0;
    transform-origin: 50% 0;
    transform: scaleY(var(--flow, 1));
    background: linear-gradient(180deg,
        rgba(133, 245, 255, .8),
        rgba(133, 245, 255, .34));
    box-shadow: 0 0 10px rgba(133, 245, 255, .4);
}

/* La luce che scende. Si muove SEMPRE, anche a pagina ferma: è l'unica cosa viva di questa
   pagina, e senza di lei il filo è un bordo.
   ⚠️ Si muove il DISEGNO DI FONDO, non l'elemento: una macchia alta 120px dentro un elemento
   alto quanto tutta la costa, spostata da `background-position`. Con un elemento vero e un
   `translateY` servirebbe l'altezza della costa in pixel — cioè un numero che JavaScript
   dovrebbe rimisurare a ogni cambio di larghezza, per un effetto che il CSS sa fare da solo.
   ⚠️ L'elemento sborda di un pixel per lato (`left/right: -1px`) perché la sfocatura ha
   bisogno di posto: dentro un contenitore largo un pixel la luce resterebbe una riga secca. */
.lh-stream-comet {
    position: absolute;
    left: -1px;
    right: -1px;
    top: 0;
    bottom: 0;
    filter: blur(1.4px);
    background-repeat: no-repeat;
    background-size: 100% 120px;
    background-image: linear-gradient(180deg,
        rgba(133, 245, 255, 0),
        rgba(214, 250, 255, .75) 46%,
        rgba(255, 255, 255, .95) 56%,
        rgba(133, 245, 255, 0));
    animation: lh-drift 7.5s linear infinite;
}

/* Parte da sopra il capo del filo e finisce sotto l'altro: entra ed esce dal buio, e non
   compare né sparisce a mezza corsa. */
@keyframes lh-drift {
    from { background-position: 0 -140px; }
    to   { background-position: 0 calc(100% + 140px); }
}

/* ⚠️ Chi ha chiesto meno movimento perde la luce che scende, non la corrente: il filo e la
   sua parte accesa restano (il riposo di `--flow` è 1), e l'elenco si legge uguale. */
@media (prefers-reduced-motion: reduce) {
    .lh-stream-comet { animation: none; opacity: 0; }
}

/* ---- le scintille del filo ----
   La tela con le particelle vere: la STESSA sabbia luminosa dell'anello del bottone play della
   home, stesa su una retta (vedi `streamDraw` in susan-app.js). Sborda di 9px per lato — il
   filo è largo un pixel e la banda di sabbia ha bisogno di posto — quindi il canvas si prende
   più spazio dell'ospite, e non deve mangiarsi i clic delle righe che gli stanno accanto.
   ⚠️ `z-index: 1` per stare sopra il filo d'oro, ma sotto niente: la colonna dei nomi non lo
   incrocia mai, perché il molo si scosta di `--rail`. */
.stream-spark-canvas {
    position: absolute;
    z-index: 1;
    pointer-events: none;
}

/* ⚠️ Dove la tela nasce, le due parti CSS della corrente vanno tolte, o si vedono due
   correnti sovrapposte: una di scintille e una di luce liscia. Restano la RICADUTA — niente
   JavaScript, o «meno movimento» — ed è per questo che non sono state cancellate quando sono
   arrivate le scintille: sono la stessa corrente disegnata con ciò che c'è.
   ⚠️ Il filo d'oro sotto (`.lh-stream` e il suo fondo) RESTA anche con la tela: è lui a dire
   dove passa la corrente prima che la luce ci arrivi, e la sabbia accende solo la parte già
   percorsa. Toglierlo lascerebbe il molo senza binario. */
.lh-stream.spark-live .lh-stream-flow,
.lh-stream.spark-live .lh-stream-comet { display: none; }

/* `--far` è la distanza del ripiano (0 = il primo). Serve solo alle comparse; sulle righe
   non tocca niente, perché un nome smorzato è un nome che non si legge — ed è l'unica cosa
   per cui la gente è venuta qui.
   `--lit` è quanto il ripiano è stato raggiunto dallo sguardo (0…1): lo muove GSAP sullo
   scorrimento. Prima accendeva il vetro; dalla rimozione delle cornici accende i PALLINI sul
   filo e la riga che gli sta accanto. Il valore di riposo è 1, cioè il molo ILLUMINATO: senza
   JavaScript, o con «meno movimento», la pagina è quella completa. */
.lh-shore {
    --far: 0;
    --lit: 1;
    margin: 0 0 2.5rem;
}

.lh-shore:last-child { margin-bottom: 0; }

/* L'intestazione del ripiano: etichetta d'oro col suo filetto sulla PRIMA riga, e la nota in
   corsivo A CAPO sotto di lei. È il filetto a farla leggere come l'etichetta di uno scaffale
   invece che come un titoletto sospeso in mezzo all'acqua.
   ⚠️ Su DUE righe, e non più tutto in fila (chiesto da Susan, 12 agosto 2026): affiancate, la
   maiuscoletta d'oro e il corsivo facevano una riga sola lunga e a due voci, e l'occhio non
   sapeva quale delle due era il titolo. A capo, l'oro è il titolo e il corsivo è la sua
   spiegazione — che è il rapporto vero fra le due.
   ⚠️ È l'`order` a mandarla sotto, non l'ordine del markup: nel documento la nota resta
   attaccata al suo titolo (è la sua spiegazione, e chi legge con le orecchie la sente lì), il
   filetto resta ultimo perché è un disegno. Riscrivere il markup per ottenere lo stesso
   effetto spezzerebbe quel legame per una ragione di stile.
   ⚠️ Il `gap` verticale ora c'è (.2rem): a zero, sulle due righe il corsivo si incollava
   sotto la maiuscoletta. */
.lh-shore-head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: .2rem .9rem;
    margin: 0 0 .85rem;
    padding: 0 2px;
}

.lh-shore-title {
    font-family: 'Cinzel', serif;
    font-size: .82rem;
    font-weight: 400;
    letter-spacing: .28em;
    text-transform: uppercase;
    color: var(--c-gold);
    text-shadow: 0 0 10px rgba(240, 214, 128, .45), 0 2px 14px rgba(0, 8, 18, .9);
    margin: 0;
}

/* `flex: 0 0 100%` più `order: 2`: prende una riga tutta sua, e la prende SOTTO — è questo il
   ritorno a capo, non un `<br>` nel testo. Il testo nel JSON resta una frase e basta. */
.lh-shore-note {
    order: 2;
    flex: 0 0 100%;
    font-family: 'Cormorant', serif;
    font-style: italic;
    font-size: 1.02rem;
    color: rgba(199, 251, 255, .78);
    text-shadow: 0 2px 14px rgba(0, 8, 18, .9);
    margin: 0;
}

/* Sfuma prima di finire, come tutti i divisori del sito: un filo che si interrompe di netto
   sembra tagliato. `flex: 1` e `min-width: 0` così non forza mai un ritorno a capo — su uno
   schermo stretto si riduce a niente invece di sfondare la riga.
   ⚠️ `order: 1`: resta sulla PRIMA riga, accanto al titolo, anche se nel markup viene dopo la
   nota. È lui a chiudere l'etichetta dello scaffale; sotto, accanto al corsivo, sarebbe una
   sottolineatura a caso. */
.lh-shore-rule {
    order: 1;
    flex: 1 1 40px;
    min-width: 0;
    height: 1px;
    align-self: center;
    background: linear-gradient(90deg, rgba(201, 169, 110, .38), rgba(201, 169, 110, 0));
}

/* ---- il ripiano ----
   ⚠️ QUI C'ERA UNA GRIGLIA (`repeat(auto-fill, minmax(210px, 1fr))`, due colonne sul telefono)
   e ora è UNA COLONNA SOLA, su tutte le larghezze — chiesto il 12 agosto 2026 insieme alla
   rimozione dei marchi. Le due cose sono una cosa sola: la griglia serviva alle TESSERE, cioè
   a mettere tredici marchi quadrati sotto gli occhi tutti insieme; senza marchi restano
   tredici NOMI, e dei nomi si legge una lista, non una scacchiera. Uno sotto l'altro si
   scorrono nell'ordine in cui sono raggruppati, che è il modo in cui questa pagina va letta.
   ⚠️ Il prezzo, e va saputo: la pagina è più lunga da scorrere (prima i tredici riquadri
   stavano in poco più di uno schermo). È il compromesso accettato — se un giorno torna il
   bisogno di «vedere l'insieme», la risposta è accorciare le righe, non rimettere le colonne.
   ⚠️ `flex` e non `grid` a una colonna: con `gap` fanno la stessa cosa, ma qui non c'è più
   niente da allineare fra righe diverse, e una lista che è una lista si scrive come tale. */
/* ⚠️ Lo spazio fra le righe è cresciuto (da 8px a 2px di stacco più il respiro dentro la
   riga): senza cornice, sono l'aria e i pallini a dire dove finisce un nome e dove comincia
   il prossimo. Con la spaziatura stretta di prima i tredici nomi diventavano un blocco unico
   di maiuscole. */
.lh-sea {
    display: flex;
    flex-direction: column;
    gap: 2px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.lh-beacon {
    position: relative;
    display: flex;
}

/* ---- il pallino sul filo ----
   Uno per riga, appoggiato esattamente sulla corrente: è lui a legare il nome al filo, e
   senza di lui l'elenco è un testo scritto accanto a una riga verticale per caso.
   ⚠️ La misura viene dalle due variabili del molo (`--rail-x - --rail`), non da un numero
   scritto a mano: è l'unico modo perché resti centrato sul filo quando si cambia il rientro.
   ⚠️ `top` in `em` e non in pixel: deve stare sulla PRIMA RIGA del nome anche quando il nome
   va a capo («Barnes & Noble / NOOK» sul telefono), e quella riga si muove col carattere.
   ⚠️ Sta nel `<li>` e NON dentro il link: il link si sposta di lato sotto il cursore, e un
   pallino che scivola via dal filo è la cosa che rompe l'illusione della corrente. */
.lh-node {
    position: absolute;
    left: calc(var(--rail-x) - var(--rail));
    top: 1.05em;
    width: 7px;
    height: 7px;
    margin-left: -3px;
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(circle at 50% 50%,
        #ffffff, rgba(214, 250, 255, .95) 30%, rgba(133, 245, 255, .5) 58%, rgba(133, 245, 255, 0) 76%);
    /* Acceso quanto il suo ripiano: da appena visibile a pieno mentre si scende.
       ⚠️ Nemmeno il pallino parte da zero: a pagina ferma il primo ripiano è già sotto gli
       occhi, e un filo senza pallini è un bordo — cioè la cosa che le cornici facevano e che
       il filo deve fare meglio. .34 è «c'è, ma non è ancora acceso». */
    opacity: calc(.34 + .66 * var(--lit));
    transform: scale(calc(.8 + .2 * var(--lit)));
    transition: opacity .34s ease, transform .34s cubic-bezier(.22, .9, .3, 1);
}

/* ---- la riga ----
   ⚠️ QUI C'ERA IL RIQUADRO DI VETRO: fondo tinto, sfocatura di ciò che stava sotto, contorno
   d'oro, filo di luce sul bordo alto e riflesso obliquo (`.lh-sheen`). Tolto tutto il
   12 agosto 2026 su richiesta di Susan — niente cornici. Con lui se ne sono andati anche
   `overflow: hidden` (e quindi il rischio del nome tagliato a metà in silenzio) e la ricaduta
   `@supports` per i browser senza `backdrop-filter`: senza vetro non c'è niente da sfocare.
   ⚠️ Il fondo se n'è andato, il CONTRASTO no: sull'acqua chiara ci pensa l'alone scuro sul
   testo (`.lh-name`), che è la cura già usata dal resto della pagina — un velo o un contorno
   «leggero» qui rimetterebbe la cornice sotto un altro nome.
   Il rientro a destra è zero e a sinistra pure: la riga comincia dove comincia la colonna,
   e il suo margine sinistro è il filo. */
.lh-post {
    position: relative;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1.4rem;
    width: 100%;
    padding: 10px 2px 10px 0;
    text-decoration: none;
    color: inherit;
    /* La riga si smorza col suo ripiano: è ciò che resta dell'accensione, ora che non c'è più
       un contorno da schiarire.
       ⚠️ Il fondo della scala è ALTO di proposito (.72, non zero e nemmeno .5): il primo
       ripiano è già sotto gli occhi a pagina ferma, e a .5 i sette nomi che si vedono per
       primi sembrano disattivati invece che «non ancora raggiunti dalla luce». L'accensione qui
       è un di più che si nota scendendo — a portare il peso sono i pallini sul filo, che
       partono molto più bassi perché sono un disegno e non una parola da leggere. */
    opacity: calc(.72 + .28 * var(--lit));
    transition: transform .34s cubic-bezier(.22, .9, .3, 1), opacity .34s ease;
}

/* ⚠️ QUI STAVANO `.lh-mark` E `.lh-mark-img`, il quadrato col marchio dell'app. Tolti il 12
   agosto 2026 con l'HTML che li portava: la pagina non ha PIÙ NESSUNA ICONA, ed è la richiesta,
   non una semplificazione. Se tornassero, tornerebbero anche queste regole (misure fisse e
   `flex: none`, perché tredici marchi di tredici disegnatori diversi non si allineano da soli)
   — ma prima va riletto il perché sono andati via: uno sotto l'altro erano un muro di sponsor.
   Con loro se n'è andata anche la variabile `--mark`, che serviva solo a dar loro la misura. */

/* Nome e «Listen →» sulla STESSA riga, e ATTACCATI: la promessa segue il nome a un dito di
   distanza invece di andare a cercarsi il margine destro (chiesto da Susan, 12 agosto 2026).
   ⚠️ Prima stava al margine, e la ragione era buona finché la riga era un riquadro di vetro:
   dentro una cornice, i due capi opposti sono due angoli della stessa scatola. Tolta la
   cornice, quel «Listen» restava sospeso in mezzo all'acqua a mezzo schermo dal suo nome —
   tredici parole d'oro incolonnate che sembravano una seconda lista invece dell'attributo di
   quella che c'è. Accanto al nome è ciò che è: la porta di QUELLA riga.
   ⚠️ Il prezzo, e va saputo: i «Listen» non sono più incolonnati fra loro, perché i nomi hanno
   lunghezze diverse. È voluto — l'elenco che si legge è quello dei NOMI, e il margine
   frastagliato lo dice invece di nasconderlo. Non si allinei «per pulizia» con una larghezza
   fissa sul nome: si tornerebbe alla colonna di prima con un altro trucco.
   ⚠️ Il vuoto che avanza va DOPO la coppia, e ci va con `margin-right: auto` su «Listen» (più
   `justify-content: flex-start` qui). Attenzione a QUALE dei due porta il margine automatico,
   perché è la differenza fra le due versioni della pagina e a leggere la regola sembra un
   dettaglio: sul NOME, quel margine si mangia tutto lo spazio libero e rispedisce «Listen» al
   margine destro — cioè esattamente il disegno di prima, rifatto per sbaglio. Misurato:
   ~400px di stacco invece di ~18. Sul «Listen», il vuoto resta dopo di lui e i due pezzi
   stanno insieme.
   ⚠️ `min-width: 0` regge il ritorno a capo del nome lungo dentro un flex. */
.lh-plate {
    display: flex;
    align-items: baseline;
    justify-content: flex-start;
    flex: 1 1 auto;
    gap: 1.15rem;
    min-width: 0;
}

/* ⚠️ Il nome può andare a capo, e deve: «Barnes & Noble / NOOK» su un telefono stretto non ci
   sta accanto a «Listen» su una riga sola. In colonna una riga in più non spaia niente — le
   righe non sono più affiancate.
   Senza marchio il nome è l'unica cosa della riga, e può crescere: da .78 a .88rem. */
/* ⚠️ DUE ombre, e la seconda non è un abbellimento: è quella scura, stretta, che stacca le
   lettere dall'acqua ora che sotto non c'è più il vetro a farlo. Va per ultima o l'alone
   ciano le passa sopra e non si vede. Toglierla rimette il nome «appeso in aria» sui fotogrammi
   chiari del fondo — il difetto per cui, quando la pagina era una lista di nomi nudi, erano
   arrivate le cornici. */
.lh-name {
    font-family: 'Cinzel', serif;
    font-size: .88rem;
    line-height: 1.4;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: #eafaff;
    text-shadow: 0 0 12px rgba(133, 245, 255, .22), 0 2px 14px rgba(0, 8, 18, .92);
    transition: color .3s ease, text-shadow .3s ease;
}

/* `flex: none` + `nowrap`: la promessa non va MAI a capo — spezzata in due righe sposta la
   linea di base del nome e la riga si sfalsa a occhio. È il nome a cedere spazio, non lei.
   ⚠️ Sta accanto al nome, non al margine (vedi `.lh-plate`), quindi è più vicina all'occhio di
   prima: il colore è restato quello smorzato apposta. Accesa come sotto il cursore, tredici
   volte, coprirebbe i nomi che è lì per servire. */
.lh-open {
    font-family: 'Cinzel', serif;
    flex: none;
    margin-right: auto;
    white-space: nowrap;
    font-size: .58rem;
    letter-spacing: .19em;
    text-transform: uppercase;
    color: rgba(240, 214, 128, .82);
    text-shadow: 0 2px 12px rgba(0, 8, 18, .9);
    transition: color .3s ease, text-shadow .3s ease;
}

.lh-open::after {
    content: '\2192';
    margin-left: .5em;
    transition: margin-left .3s ease;
}

/* ---- quello che non è ancora aperto ----
   A dire «non ancora» sono il nome più smorzato, il pallino VUOTO sul filo (un cerchietto
   d'oro invece di una luce) e l'assenza del «Listen» accanto al nome. Non è un link e non
   prende il fuoco della tastiera: nessun clic promesso e non mantenuto.
   ⚠️ Il pallino vuoto è la sola cosa che distingue una riga spenta a colpo d'occhio, ora che
   non c'è più un vetro da spegnere: se un giorno si tocca, si tocchi sapendolo. */
.lh-beacon.is-soon .lh-name { color: rgba(223, 247, 255, .6); }
.lh-beacon.is-soon .lh-post { opacity: calc(.56 + .24 * var(--lit)); }

.lh-beacon.is-soon .lh-node {
    background: none;
    border: 1px solid rgba(201, 169, 110, .55);
    width: 6px;
    height: 6px;
    margin-left: -3px;
}

/* ---- sotto il dito, o sotto il cursore ----
   ⚠️ Si sposta DI LATO e non in su. In una griglia il riquadro toccato si sollevava dagli
   altri; in una colonna un sollevamento lo fa sembrare staccato dalla riga sopra e sotto — di
   lato, invece, si legge come un passo verso il link, che è ciò che sta per succedere. Senza
   cornice lo scarto conta il doppio: è rimasto l'unico movimento che dice «questa qui».
   ⚠️ Il pallino NON si sposta con la riga (sta nel `<li>`): si limita a crescere sul filo. È
   la riga che si scosta dalla corrente, non la corrente che si storce. */
.lh-post:hover {
    transform: translateX(7px);
    opacity: 1;
}

.lh-post:hover .lh-name { color: #ffffff; text-shadow: var(--glow-body), 0 2px 14px rgba(0, 8, 18, .92); }
.lh-post:hover .lh-open { color: var(--c-gold); text-shadow: var(--glow-cta); }
.lh-post:hover .lh-open::after { margin-left: .85em; }

.lh-beacon:hover .lh-node {
    opacity: 1;
    transform: scale(1.5);
}

.lh-post:focus-visible {
    outline: 1px solid rgba(133, 245, 255, .85);
    outline-offset: 4px;
    border-radius: 4px;
}

/* Sul telefono un :hover resta appiccicato dopo il tocco: la riga toccata resterebbe scostata
   e il suo pallino gonfio, come se fosse stata scelta per sempre. */
@media (hover: none) {
    .lh-post:hover {
        transform: none;
        opacity: calc(.72 + .28 * var(--lit));
    }
    .lh-post:hover .lh-name { color: #eafaff; text-shadow: 0 0 12px rgba(133, 245, 255, .22), 0 2px 14px rgba(0, 8, 18, .92); }
    .lh-post:hover .lh-open { color: rgba(240, 214, 128, .82); text-shadow: 0 2px 12px rgba(0, 8, 18, .9); }
    .lh-beacon:hover .lh-node { transform: scale(calc(.8 + .2 * var(--lit))); opacity: calc(.34 + .66 * var(--lit)); }
}

/* ---- il modulo «avvisami», se il JSON ce l'ha ----
   ⚠️ Dal 14 agosto 2026 questo blocco NON è nella pagina (tolto su richiesta di Susan
   insieme al paragrafo d'introduzione). Il renderer lo sa ancora fare: torna intero
   riscrivendo `notify` in `listenPage`, e queste regole servono a quel giorno. Il modulo è
   quello del CONTATTO della home, classe per classe: lo accende lo stesso codice
   (initContactForm cerca `.contact-form` dentro #susan-root). */
.lh-notify {
    position: relative;
    margin-top: 5rem;
    padding-top: 3.6rem;
    text-align: center;
}

.lh-notify-rule {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 1px;
    transform-origin: 50% 50%;
    background: linear-gradient(90deg, transparent, rgba(201, 169, 110, .45), transparent);
}

/* La lanterna: prende la tela delle scintille (`spark-ring`), quindi il suo anello è fatto di
   particelle vere come quello dei LISTEN NOW. */
.lh-lantern {
    position: relative;
    display: block;
    width: 54px;
    height: 54px;
    margin: 0 auto 1.9rem;
}

.lh-lantern .lh-glass {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: radial-gradient(circle at 50% 44%,
        #ffffff, #fff7db 18%, rgba(240, 214, 128, .92) 44%, rgba(240, 214, 128, 0) 74%);
    box-shadow:
        0 0 16px rgba(255, 246, 216, .95),
        0 0 44px rgba(240, 214, 128, .6),
        0 0 100px rgba(133, 245, 255, .32);
}

.lh-notify-title {
    font-family: 'Cinzel', serif;
    font-size: 1.25rem;
    font-weight: 400;
    letter-spacing: .22em;
    color: var(--c-gold);
    text-shadow: var(--glow-cta);
    margin: 0 0 1.4rem;
}

.lh-notify .contact-text { font-size: 1.25rem; }

.lh-back {
    margin: 3.4rem 0 0;
    text-align: center;
}

.lh-back a {
    font-family: 'Cinzel', serif;
    font-size: .8rem;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: rgba(240, 214, 128, .92);
    text-shadow: 0 2px 14px rgba(0, 8, 18, .9);
    text-decoration: none;
    transition: color .3s ease, text-shadow .3s ease;
}

/* La freccia sta nel CSS e non nel testo: l'etichetta nel JSON deve restare una frase che si
   può riscrivere senza portarsi dietro un segno tipografico. */
.lh-back a::before {
    content: '\2190';
    margin-right: .6em;
}

.lh-back a:hover {
    color: var(--c-gold);
    text-shadow: var(--glow-cta), 0 2px 14px rgba(0, 8, 18, .9);
}

@media (max-width: 768px) {
    .lh-wrap { padding: 54px 1.4rem 90px; }
    .lh-title { font-size: 1.7rem; letter-spacing: .2em; margin-top: 2rem; }
    .lh-intro { font-size: 1.12rem; margin-top: 1.8rem; }
    .lh-italic { font-size: 1.3rem; }
    /* Il filo si stringe alla colonna: 30px di rientro su un telefono sono un decimo della
       larghezza tolti ai nomi, e «Barnes & Noble / NOOK» va a capo per colpa del filo. */
    .lh-coast { --rail: 22px; --rail-x: 5px; margin-top: 2.6rem; }
    .lh-sea { gap: 2px; }
    .lh-shore { margin-bottom: 2rem; }
    .lh-shore-title { font-size: .74rem; letter-spacing: .2em; }
    .lh-shore-note { font-size: .96rem; }
    .lh-post { padding: 9px 2px 9px 0; gap: 1rem; }
    .lh-plate { gap: 1rem; }
    .lh-name { font-size: .78rem; letter-spacing: .09em; }
    .lh-notify { margin-top: 3.8rem; padding-top: 2.8rem; }
    .lh-lantern { width: 46px; height: 46px; margin-bottom: 1.6rem; }
    /* Con le misure del computer «BE THE FIRST TO HEAR IT» andava a capo lasciando «IT» da
       solo sulla seconda riga: una spaziatura da titolo, su 390px, è troppo larga. */
    .lh-notify-title { font-size: 1.02rem; letter-spacing: .14em; }
    .lh-notify .contact-text { font-size: 1.12rem; }
}

/* ⚠️ Sotto i 460px ci finiscono TUTTI i telefoni. Qui c'erano DUE COLONNE con il marchio sopra
   e il nome sotto (15 agosto 2026), ed è stato tolto tutto insieme ai marchi il 12 agosto 2026:
   la richiesta è una colonna sola, ovunque. Sul telefono resta una lista di righe piene, che è
   la forma che un telefono legge meglio di qualsiasi altra — al prezzo, saputo, di una pagina
   più lunga da scorrere.

   ⚠️ Il nome lungo. Col riquadro di vetro (`overflow: hidden`) un nome troppo lungo non
   sbordava: SPARIVA A METÀ, in silenzio. Senza cornice non sparisce più — va a capo, e basta.
   Resta però il caso di sempre, «Barnes & Noble / NOOK», che qui ha tutta la larghezza dello
   schermo meno il filo e meno «Listen»: se si aggiunge una piattaforma dal nome lungo si
   riguarda a 390, 360 e 320px che non spinga la pagina di lato. Provato fino a 320px — sotto
   quella larghezza non c'è telefono. */
@media (max-width: 460px) {
    .lh-coast { --rail: 20px; --rail-x: 4px; }
    .lh-sea { gap: 2px; }
    .lh-post { padding: 8px 2px 8px 0; gap: .9rem; }
    .lh-plate { gap: .9rem; }
    .lh-name { font-size: .72rem; letter-spacing: .07em; }
    .lh-open { font-size: .54rem; letter-spacing: .15em; }
    .lh-shore-head { margin-bottom: .6rem; }
    .lh-node { width: 6px; height: 6px; margin-left: -3px; }
}

/* ⚠️ Chi ha chiesto meno movimento non deve trovare la pagina a metà: GSAP in quel caso non
   crea nessuna animazione, quindi il molo resta come l'ha scritto il CSS. Ed è esattamente
   per questo che il valore di riposo di `--lit` è 1 e non 0: la pagina ferma è la pagina
   COMPLETA — vetro acceso, contorni pieni, filetti aperti. Non c'è niente da rimettere a
   posto qui, e va tenuto così. */
