@import url('fonts/noto-fonts.css');

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* Font dei tre temi, auto-ospitati (Google Fonts, file in /fonts): sostituti liberi
   metric-compatible di Arial/Courier New/Georgia, scelti da Google apposta per questo scopo, così
   il testo è identico su ogni dispositivo invece di dipendere da cosa c'è installato localmente. */
@font-face {
  font-family: 'Arimo';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/Arimo-Regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Arimo';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/Arimo-Italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Gelasio';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/Gelasio-Regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Gelasio';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/Gelasio-Italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Courier Prime';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/CourierPrime-Regular.woff2') format('woff2');
}
@font-face {
  /* Il vero taglio Bold ha tratti troppo spessi/compressi nel tema scuro (vedi nota più sotto):
     il peso 700 punta di proposito al file Regular, così il "grassetto" resta leggero, con la
     stessa spaziatura dei caratteri della Regular da cui parte. */
  font-family: 'Courier Prime';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/CourierPrime-Regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Courier Prime';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/CourierPrime-Italic.woff2') format('woff2');
}
.cn-brand { font-family: 'Courier Prime', monospace; }
/* .cn-brand.cn-brand: stesso selettore raddoppiato solo per alzare la specificità (0,2,0) sopra
   quella di .cn-title (0,1,0) e di .cn-auth-logo span (0,1,1), così la scritta del marchio resta
   sempre in peso normale indipendentemente da quale altra classe di titolo le sta accanto. Anche
   la dimensione è fissata in rem (non em): A-/A+ cambia --cn-font-size sul documento, e un valore
   in em la seguirebbe; il marchio deve restare della stessa dimensione a qualunque zoom. */
.cn-brand.cn-brand { font-weight: 400; font-size: .95rem; }
.cn-auth-logo .cn-brand.cn-brand { font-size: 1.15rem; }

/* Coda comune ai tre temi: copertura di arabo/cinese/giapponese/coreano, indipendente dal tema
   (un solo font scelto per ciascuna scrittura, non uno stile diverso per tema — vedi Noto sopra). */

/* --cn-accent resta il colore "di richiamo" (bordi attivi, link, anello dei temi); i pulsanti
   pieni (.cn-btn) usano invece --cn-btn-bg/--cn-btn-text a sé stanti — sul tema chiaro l'accento
   teal risultava troppo simile al nero del tema scuro, e sul seppia il goldenrod era "troppo
   marrone": qui si può correggere il colore dei pulsanti senza toccare gli altri usi di --cn-accent. */
[data-theme="minimal"] {
  --cn-bg: #ffffff;
  --cn-text: #1a202c;
  --cn-font: Arimo, -apple-system, "Segoe UI", Arial, "Noto Naskh Arabic", "Noto Serif SC", "Noto Serif JP", "Noto Serif KR", sans-serif;
  --cn-accent: #166ca2;
  --cn-btn-bg: #166ca2;
  --cn-btn-text: #ffffff;
  --cn-border: rgba(22, 108, 162, 0.3);
  --cn-icon-bg: rgba(22, 108, 162, 0.1);
  --cn-icon-border: #166ca2;
  --cn-muted: rgba(26, 32, 44, 0.6);
  --cn-avviso-bg: #eaf3f9; --cn-avviso-text: #1a202c; --cn-avviso-border: rgba(22, 108, 162, 0.35);
  --cn-errore-bg: #fdecec; --cn-errore-text: #9b1c1c; --cn-errore-border: rgba(224, 82, 82, 0.45);
}
/* Il peso 700 di Courier Prime punta al file Regular (vedi @font-face più sopra): senza altro
   sarebbe identico alla Regular, non "leggermente in grassetto". Un filo di contorno via
   text-stroke aggiunge un po' di peso ai tratti — meno del vero Bold — senza cambiare font né
   larghezza dei caratteri (a differenza di font-weight, non rompe l'allineamento monospaziato). */
[data-theme="dark"] :is(b, strong, h1, h2, h3, h4, h5, h6) { -webkit-text-stroke: .9px currentColor; }
[data-theme="dark"] {
  --cn-bg: #0a0e1a;
  --cn-text: #e7fbff;
  --cn-font: "Courier Prime", "Courier New", Courier, "Noto Naskh Arabic", "Noto Serif SC", "Noto Serif JP", "Noto Serif KR", monospace;
  --cn-accent: #00e5ff;
  --cn-btn-bg: #00e5ff;
  --cn-btn-text: #041014;
  --cn-border: rgba(0, 229, 255, 0.25);
  --cn-icon-bg: rgba(0, 229, 255, 0.12);
  --cn-icon-border: #00e5ff;
  --cn-muted: rgba(231, 251, 255, 0.6);
  --cn-avviso-bg: #101c2c; --cn-avviso-text: #e7fbff; --cn-avviso-border: rgba(0, 229, 255, 0.35);
  --cn-errore-bg: #2a1219; --cn-errore-text: #ffb4bb; --cn-errore-border: rgba(255, 99, 115, 0.45);
}
[data-theme="papyrus"] {
  --cn-bg: #f3ede1;
  --cn-text: #2b2015;
  --cn-font: Gelasio, Georgia, "Times New Roman", "Noto Naskh Arabic", "Noto Serif SC", "Noto Serif JP", "Noto Serif KR", serif;
  --cn-accent: #b8860b;
  --cn-btn-bg: #d9a635;
  --cn-btn-text: #2b2015;
  --cn-border: rgba(184, 134, 11, 0.3);
  --cn-icon-bg: rgba(184, 134, 11, 0.12);
  --cn-icon-border: #b8860b;
  --cn-muted: rgba(43, 32, 21, 0.6);
  --cn-avviso-bg: #e8dbc0; --cn-avviso-text: #2b2015; --cn-avviso-border: rgba(184, 134, 11, 0.45);
  --cn-errore-bg: #f3d9cb; --cn-errore-text: #7a2913; --cn-errore-border: rgba(168, 72, 38, 0.45);
}

/* Alto contrasto per i lettori e-ink (2026-10-02, decisione dell'autore): nero su bianco, bordi netti, niente sfondi grigi
   né ombre o sfumature (sull'e-ink diventano retini sporchi). Si sceglie solo dal quarto tondino in Impostazioni; i tondini
   dei temi spariscono dalla barra. Il carattere è uno dei tre dei temi, scelto in Impostazioni (applyCustomThemeOverrides). */
[data-theme="eink"] {
  --cn-bg: #ffffff;
  --cn-text: #000000;
  --cn-font: Arimo, -apple-system, "Segoe UI", Arial, "Noto Naskh Arabic", "Noto Serif SC", "Noto Serif JP", "Noto Serif KR", sans-serif;
  --cn-accent: #000000;
  --cn-btn-bg: #ffffff;
  --cn-btn-text: #000000;
  --cn-border: #000000;
  --cn-icon-bg: #ffffff;
  --cn-icon-border: #000000;
  --cn-muted: #000000;
  --cn-avviso-bg: #ffffff; --cn-avviso-text: #000000; --cn-avviso-border: #000000;
  --cn-errore-bg: #ffffff; --cn-errore-text: #000000; --cn-errore-border: #000000;
}
[data-theme="eink"] *, [data-theme="eink"] *::before, [data-theme="eink"] *::after { box-shadow: none !important; text-shadow: none !important; transition: none !important; }
[data-theme="eink"] .cn-btn, [data-theme="eink"] .cn-icon-btn { border: 2px solid #000000; }
[data-theme="eink"] .cn-btn:hover, [data-theme="eink"] .cn-icon-btn:hover { filter: none; }
[data-theme="eink"] .cn-btn:disabled { opacity: 1; border-style: dashed; }
[data-theme="eink"] .cn-icon-btn.is-active { outline: 2px solid #000000; outline-offset: 2px; }
[data-theme="eink"] .cn-toolbar .cn-theme-selector { display: none !important; }
/* Courier Prime non ha un vero grassetto (vedi @font-face): come nel tema scuro, un filo di contorno. */
[data-theme="eink"][data-eink-font="dark"] :is(b, strong, h1, h2, h3, h4, h5, h6) { -webkit-text-stroke: .6px currentColor; }

body {
  background: var(--cn-bg);
  color: var(--cn-text);
  font-family: var(--cn-font);
  font-size: var(--cn-font-size, 1rem);
  transition: background .2s ease, color .2s ease;
  min-height: 100vh;
  /* Sul telefono (iPhone, Chrome e Safari) 100vh è l'altezza con le barre del browser nascoste: la pagina risultava più alta dello schermo
     visibile di qualche decina di punti e toccando un pulsante scorreva fin lì, facendo "saltare" il testo verso l'alto (2026-10-09, visto
     dall'autore anche con la versione dell'8 ottobre). 100svh = l'altezza visibile con le barre del browser mostrate. */
  min-height: 100svh;
}
/* Ogni testo che non fissa una propria dimensione eredita quella di body, quindi A-/A+ (che
   cambiano --cn-font-size) ingrandiscono anche pulsanti/etichette, non solo il testo del romanzo.
   Le dimensioni sotto sono apposta in "em" (relative al genitore), non "rem" (fisse sulla radice),
   per scalare insieme; misure di layout (padding, gap, larghezze) restano invece in rem, così
   cambia il testo ma non le proporzioni dell'impaginazione. */
/* Pagine statiche (elenco romanzi, privacy, chi siamo): il footer resta ancorato in fondo
   alla finestra anche quando il contenuto è breve, invece di seguire subito il contenuto. */
body.cn-page-body { display: flex; flex-direction: column; }
body.cn-page-body .cn-page { flex: 1 0 auto; }
body.cn-page-body .cn-footer { margin-top: auto; }
/* Pagine statiche (Chi siamo, Prezzi, FAQ, Privacy, Termini, Rimborso, Segnala un problema): un paio di righe in meno tra
   l'ultima riga del testo e il footer "CiaoNovel.com" (prima 4rem + 2rem). */
body.cn-pagina-statica .cn-page { padding-bottom: 1.5rem; }
body.cn-pagina-statica .cn-footer { padding-top: 1.5rem; }

a { color: var(--cn-accent); }

/* Senza questa regola il placeholder di input/textarea usa il colore di default del browser
   (pensato per sfondi chiari): nel tema scuro risultava un grigio scuro poco leggibile sullo
   sfondo quasi nero. --cn-muted è già il "testo secondario" di ciascun tema, qui applicato anche
   ai placeholder con opacity:1 per non sommare un'ulteriore trasparenza a quella già nel colore. */
::placeholder { color: var(--cn-muted); opacity: 1; }

/* ---------- toolbar (a comparsa) ---------- */
.cn-toolbar {
  position: sticky;
  top: 0;
  z-index: 25;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: .5rem;
  padding: .75rem 1rem;
  border-bottom: 1px solid var(--cn-border);
  background: var(--cn-bg);
  transition: transform .2s ease, opacity .2s ease;
}
.cn-toolbar.is-hidden { transform: translateY(-100%); opacity: 0; pointer-events: none; }
.cn-toolbar > .cn-toolbar-group:first-child { justify-self: start; }
.cn-toolbar > .cn-toolbar-group:nth-child(2) { justify-self: center; }
.cn-toolbar > .cn-toolbar-group:last-child { justify-self: end; }

.cn-toolbar-reveal {
  position: fixed; top: .75rem; right: 1rem; z-index: 22;
  width: 2.2rem; height: 2.2rem; border-radius: 50%;
  /* Sfondo PIENO (--cn-bg, non --cn-icon-bg): questo pulsante fluttua sopra il testo del romanzo
     mentre la barra è nascosta (vedi initBarraLettore), --cn-icon-bg è troppo trasparente (alpha
     bassa) per restare leggibile sopra al testo che scorre sotto — stesso criterio già usato per
     le altre icone a comparsa sopra un contenuto, es. .cn-libreria-elimina. */
  border: 1px solid var(--cn-icon-border); background: var(--cn-bg); color: inherit;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
.cn-toolbar-reveal.is-visible { opacity: 1; pointer-events: auto; }
.cn-toolbar-group { display: flex; align-items: center; gap: .35rem; }
.cn-logo-link { display: flex; align-items: center; gap: .5rem; text-decoration: none; color: inherit; }
.cn-title { font-weight: 600; font-size: .95em; opacity: .85; }
/* Titolo troppo lungo nella barra: una riga sola, tagliato con i tre puntini; il pulsante indietro e le icone non si deformano. */
.cn-toolbar > .cn-toolbar-group:first-child { min-width: 0; max-width: 100%; }
.cn-toolbar .cn-toolbar-group .cn-logo-link { min-width: 0; }
.cn-toolbar .cn-toolbar-group .cn-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cn-toolbar .cn-icon-btn, .cn-toolbar .cn-logo { flex-shrink: 0; }
/* Telefono in orizzontale: il titolo lungo andrebbe a capo e ingrandirebbe la barra, quindi non si mostra. */
@media (pointer: coarse) and (max-height: 500px) { .cn-title { display: none; } }
/* Indicatore "usati/tetto" dei crediti IA (prova gratuita o Premium, vedi renderCreditoBadge() in
   app.js): un badge piccolo e discreto accanto al titolo del romanzo, non un elemento che debba
   attirare l'attenzione. */
.cn-credito-badge {
  font-size: .75em; opacity: .6; white-space: nowrap;
  border: 1px solid var(--cn-icon-border); border-radius: 1em; padding: .1rem .55rem;
}
.cn-logo { width: 2.1rem; height: 2.1rem; object-fit: contain; background: transparent; }
/* Sfondo trasparente su tema chiaro/seppia (colore naturale dell'icona); sul tema scuro l'icona
   (glifo scuro su alpha) viene invertita in bianco, sempre a sfondo trasparente. */
[data-theme="dark"] .cn-logo { filter: invert(1); }

.cn-icon-btn {
  width: 2.2rem; height: 2.2rem; border-radius: 50%;
  border: 1px solid var(--cn-icon-border);
  background: var(--cn-icon-bg);
  color: inherit; font-size: 1em;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.cn-icon-btn:hover { filter: brightness(0.95); }
.cn-icon-btn.is-active { box-shadow: 0 0 0 2px var(--cn-accent); }
/* A-/A+ cambiano --cn-font-size: se scalassero anche loro (ereditando da body) diventerebbero
   sempre più grandi/piccoli a ogni click. Restano fissi in rem, ancorati alla radice. */
#font-minus, #font-plus, #font-plus-mobile { font-size: 1rem; }
/* #font-plus-mobile e #btn-drawer-toggle-mobile esistono solo per la riga a comparsa su telefono
   (vedi il blocco @media più sotto): su schermi larghi i pulsanti "veri" (A+/Faro) bastano già da
   soli, quindi questi restano sempre nascosti finché quel blocco non li riporta in vita. */
#font-plus-mobile, #btn-drawer-toggle-mobile { display: none; }
/* Pulsanti di pagina raccolti sotto un innesco su telefono (libro-gioco, vedi il blocco @media più
   sotto e initToolbarMobileGroups in app.js): su schermi larghi il contenitore non esiste per il
   layout e l'innesco resta nascosto. */
.cn-toolbar-extra { display: contents; }
#btn-toolbar-altro { display: none; }

.cn-icon { display: inline-flex; position: relative; width: 1.1rem; height: 1.1rem; }
.cn-icon svg, .cn-icon img { width: 100%; height: 100%; display: block; }
/* Le icone sono PNG nere fisse (vedi icon() in icons.js): sul tema scuro, dove il testo è chiaro
   su sfondo scuro, un'icona nera sarebbe pressoché invisibile — stessa inversione già usata per
   .cn-logo qui sopra, stesso motivo. */
[data-theme="dark"] .cn-icon img { filter: invert(1); }
.cn-btn .cn-icon { width: 1rem; height: 1rem; margin-right: .35rem; vertical-align: -2px; }
.cn-btn .cn-icon.cn-icona-leggi { vertical-align: -3px; }
.cn-icon-btn .cn-icon { width: 1.05rem; height: 1.05rem; }

/* Icona "vista del testo" in reader/leggi.html (Originale/Tradotto/Affiancati): al click mostra le
   tre icone rotonde originali — niente riquadro/sfondo proprio dietro di loro, solo attorno alle
   singole icone. .cn-icon-btn usa di norma uno sfondo translucido (--cn-icon-bg): va bene dentro
   la barra, che ha già il suo sfondo pieno sotto (stesso ragionamento del blocco commentato più
   sopra per il gruppo A-/A+ su telefono) — queste però galleggiano sopra il testo della pagina
   (position:absolute), quindi qui serve uno sfondo pieno per restare leggibili invece di lasciar
   trasparire il testo sotto. */
.cn-vista-testo-wrap { position: relative; display: inline-flex; }
.cn-vista-testo-menu {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%); margin-top: .4rem;
  display: flex; gap: .35rem; z-index: 30;
}
.cn-vista-testo-menu[hidden] { display: none; }
.cn-vista-testo-menu .cn-icon-btn { background: var(--cn-bg); box-shadow: 0 2px 8px rgba(0, 0, 0, .15); }

.cn-theme-btn { width: 1.8rem; height: 1.8rem; border-radius: 50%; cursor: pointer; padding: 0; border: 2px solid var(--cn-icon-border); }
.cn-theme-btn.is-active { box-shadow: 0 0 0 2px var(--cn-accent); }
.cn-theme-btn[data-theme-choice="minimal"] { background: #ffffff; }
.cn-theme-btn[data-theme-choice="dark"] { background: #0a0e1a; }
.cn-theme-btn[data-theme-choice="papyrus"] { background: #f3ede1; }
/* I tre temi nella barra in alto ci sono solo nelle pagine principali (homepage, I tuoi scritti, Reader, Chat; 2026-10-02):
   le altre pagine non hanno il selettore e dentro una conversazione della chat si nasconde. */
body.cn-chat-in-conversazione .cn-toolbar .cn-theme-selector { display: none; }
/* Quarto tondino (Impostazioni): mezzo nero e mezzo bianco, un po' staccato dagli altri tre. */
.cn-theme-btn[data-theme-choice="eink"] { background: linear-gradient(90deg, #000000 50%, #ffffff 50%); border-color: #000000; margin-inline-start: .9rem; }
.cn-theme-selector { display: flex; align-items: center; gap: .35rem; }

/* ---------- reading column ---------- */
.cn-content {
  max-width: 42rem;
  margin: 0 auto;
  line-height: 1.7;
  padding: 2rem 1.5rem 6rem;
}
@media (max-width: 40rem) { .cn-content { padding: 1.5rem 1rem 5rem; } }

/* ---------- schermi stretti (telefoni): barra più compatta ---------- */
@media (max-width: 40rem) {
  /* Marchio/titolo del romanzo accanto al logo: tolto per fare spazio alle icone, il logo da
     solo basta a identificare la pagina. */
  .cn-title { display: none; }
  /* Con il badge dei crediti visibile il logo si toglie: il badge è più utile dello spazio che occupa. */
  .cn-logo-link:has(~ #credito-badge:not([hidden])) { display: none; }
  /* Nella barra in alto (non nel selettore dentro Impostazioni > Personalizza tema, che è un
     contesto diverso, sempre con spazio a sufficienza) resta visibile solo il pallino del tema
     attivo, finché il selettore non viene espanso (vedi initTheme in app.js) o non lo è già il
     gruppo A-/A+ che lo contiene (vedi sotto): libera lo spazio che serviva a leggere-ad-alta-voce
     e impostazioni, spinti fuori schermo su telefoni stretti. */
  .cn-toolbar .cn-theme-selector:not(.is-espanso) .cn-theme-btn:not(.is-active) { display: none; }
  #toolbar-group-font.is-espanso .cn-theme-selector .cn-theme-btn { display: inline-block; }

  /* Editor su telefono (vedi scrivi.js): troppi pulsanti in barra durante la scrittura
     (impostazioni, faro, scrittura a più mani, A-/A+, temi, vista lettura). Restano sempre
     visibili solo A+, leggi-ad-alta-voce e Faro; A+ e Faro sono anche l'innesco che apre sotto,
     al tocco, il resto del proprio gruppo (stesso schema del pallino del tema qui sopra: primo
     tocco apre, non agisce). Entrambi gli inneschi sempre visibili (A+ e Faro, cioè #font-plus e
     #btn-drawer-toggle) fanno SOLO questo su telefono, mai l'azione vera (vedi
     initToolbarMobileGroups in scrivi.js): l'azione vera è nei loro gemelli dentro la riga a
     comparsa, #font-plus-mobile e #btn-drawer-toggle-mobile (nascosti di default fuori da questo
     blocco, vedi sopra), riportati in vita qui sotto solo quando il gruppo è espanso. */
  #toolbar-group-font:not(.is-espanso) #font-minus,
  #toolbar-group-font:not(.is-espanso) .cn-theme-selector { display: none; }
  #toolbar-group-menu:not(.is-espanso) #btn-view-toggle,
  #toolbar-group-menu:not(.is-espanso) #btn-collab,
  #toolbar-group-menu:not(.is-espanso) #btn-debug,
  #toolbar-group-menu:not(.is-espanso) #btn-settings { display: none; }
  /* Da espansi, il resto del gruppo compare in una riga assolutamente posizionata sotto l'innesco
     (position:absolute, non flex-wrap): così non partecipa più al flusso del gruppo e non ne
     allarga la riga, quindi né l'altezza della barra né la posizione degli altri pulsanti/gruppi
     si spostano, si vedono solo i nuovi pulsanti comparire sotto. */
  #toolbar-group-font, #toolbar-group-menu { position: relative; }
  #toolbar-group-font.is-espanso #font-minus,
  #toolbar-group-font.is-espanso .cn-theme-selector {
    position: absolute;
    top: calc(100% + .5rem);
  }
  #toolbar-group-font.is-espanso #font-plus-mobile {
    display: flex;
    position: absolute;
    top: calc(100% + .5rem);
  }
  /* Esattamente sotto A+ (primo pulsante visibile del gruppo, quindi bordo sinistro del gruppo
     stesso): A- allineato a sinistra, subito a destra il vero A+ (#font-plus-mobile, accanto ad
     A- come richiesto), poi i temi. */
  #toolbar-group-font.is-espanso #font-minus { left: 0; }
  #toolbar-group-font.is-espanso #font-plus-mobile { left: 2.55rem; }
  #toolbar-group-font.is-espanso .cn-theme-selector { left: 5.1rem; }
  #toolbar-group-menu.is-espanso #btn-view-toggle,
  #toolbar-group-menu.is-espanso #btn-collab,
  #toolbar-group-menu.is-espanso #btn-debug,
  #toolbar-group-menu.is-espanso #btn-settings {
    position: absolute;
    top: calc(100% + .5rem);
  }
  #toolbar-group-menu.is-espanso #btn-drawer-toggle-mobile {
    display: flex;
    position: absolute;
    top: calc(100% + .5rem);
  }
  /* Il gruppo, da chiuso, è largo solo quanto l'innesco Faro (#btn-drawer-toggle) ed è ancorato al
     bordo destro della barra: le extra si allineano allo stesso bordo destro, non a sinistra,
     altrimenti sconfinerebbero fuori schermo. #btn-debug (solo admin) resta più a sinistra di
     tutte così, quando nascosto (utenti non admin), non lascia un buco fra le altre tre. Esattamente
     sotto l'innesco Faro compare il suo gemello vero #btn-drawer-toggle-mobile (right:0, come A+
     nell'altro gruppo), le altre spinte più a sinistra di conseguenza. */
  #toolbar-group-menu.is-espanso #btn-drawer-toggle-mobile { right: 0; }
  #toolbar-group-menu.is-espanso #btn-settings { right: 2.55rem; }
  #toolbar-group-menu.is-espanso #btn-collab { right: 5.1rem; }
  #toolbar-group-menu.is-espanso #btn-view-toggle { right: 7.65rem; }
  #toolbar-group-menu.is-espanso #btn-debug { right: 10.2rem; }
  /* Libro-gioco: collab, personaggi e impostazioni stanno in un contenitore che, da chiuso, sparisce;
     da aperto è una riga allineata a destra sotto l'innesco (flex, così i pulsanti nascosti non
     lasciano buchi). */
  #btn-toolbar-altro { display: flex; }
  #toolbar-group-menu:not(.is-espanso) .cn-toolbar-extra { display: none; }
  #toolbar-group-menu.is-espanso .cn-toolbar-extra {
    display: flex; gap: .35rem;
    position: absolute; top: calc(100% + .5rem); right: 0;
  }
  /* Senza questo le regole dell'editor qui sopra (#btn-collab e #btn-settings posizionati a mano) spostavano due dei tre
     pulsanti su una seconda riga, lasciando Personaggi da solo. */
  #toolbar-group-menu.is-espanso .cn-toolbar-extra #btn-collab,
  #toolbar-group-menu.is-espanso .cn-toolbar-extra #btn-settings { position: static; }
  #toolbar-group-menu.is-espanso .cn-toolbar-extra .cn-icon-btn {
    background: var(--cn-bg);
    box-shadow: 0 2px 8px rgba(0, 0, 0, .15);
  }
  /* .cn-icon-btn usa di norma uno sfondo translucido (--cn-icon-bg): va bene dentro la barra,
     che ha già il suo sfondo pieno sotto. Questi però galleggiano sopra il contenuto della
     pagina (position:absolute), quindi serve uno sfondo pieno per restare leggibili. */
  #toolbar-group-font.is-espanso #font-minus,
  #toolbar-group-font.is-espanso #font-plus-mobile,
  #toolbar-group-menu.is-espanso #btn-view-toggle,
  #toolbar-group-menu.is-espanso #btn-collab,
  #toolbar-group-menu.is-espanso #btn-debug,
  #toolbar-group-menu.is-espanso #btn-settings,
  #toolbar-group-menu.is-espanso #btn-drawer-toggle-mobile {
    background: var(--cn-bg);
    box-shadow: 0 2px 8px rgba(0, 0, 0, .15);
  }
  /* La larghezza personalizzata del paragrafo di scrittura (trascinabile su desktop, vedi
     initParagraphResize) non ha senso su uno schermo già stretto: usa sempre tutto lo spazio
     disponibile, a prescindere da un valore salvato in una sessione desktop precedente. */
  .cn-format-wrap-paragrafo { max-width: 100% !important; }
  /* Indietro/Avanti/Concludi il capitolo/Concludi il romanzo in fila: su schermi stretti nowrap
     li stringe abbastanza da spezzare "Concludi il capitolo/romanzo" su tre righe e da far
     debordare la riga oltre il bordo destro. Vanno bene su due righe. */
  .cn-draft-controls { flex-wrap: wrap; }
}

.cn-paragraph { margin-top: 0; margin-bottom: 1.25rem; white-space: pre-wrap; }
/* Numero di paragrafo nel romanzo: nascosto di norma (rumore per chi scrive/legge), mostrato solo
   mentre la scheda "Controlla" del drawer è aperta, per capire a quale paragrafo si riferisce un
   avviso (vedi renderCoerenzaHtml/renderStory in scrivi.js). */
.cn-numero-paragrafo { display: none; }
body.cn-mostra-numeri-paragrafo .cn-numero-paragrafo {
  display: block;
  font-family: monospace;
  font-size: .75rem;
  opacity: .55;
  margin-bottom: .25rem;
}
.cn-paragraph.is-draft[contenteditable="true"], textarea.is-draft {
  outline: 1px solid var(--cn-accent);
  border-radius: .4rem;
  padding: .75rem;
  cursor: text;
}
textarea.is-draft {
  width: 100%; font: inherit; resize: vertical; border: none; background: transparent; color: var(--cn-text);
}
.cn-draft-controls { display: flex; gap: .5rem; margin: .75rem 0 2rem; }
/* Bozza del paragrafo (Rigenera, Approva, Approva e finisci il capitolo): allineati a destra come gli altri pulsanti sotto un campo. */
.cn-draft-controls-destra { justify-content: flex-end; }
.cn-draft-stile-riga { display: flex; justify-content: flex-end; margin-top: .35rem; }
.cn-draft-stile-nome {
  background: none; border: none; font: inherit; font-size: .75em; opacity: .6;
  cursor: pointer; padding: .15rem .3rem; color: inherit;
}
.cn-draft-stile-nome:hover { opacity: .9; text-decoration: underline; }
.cn-draft-stile-riga select {
  font-size: .75em; padding: .15rem .3rem; border-radius: .3rem;
  border: 1px solid var(--cn-border); background: var(--cn-bg); color: var(--cn-text);
}
/* "Indietro" e il bottone di conferma condividono questa riga quando possibile (allineata a
   destra), tornando su due righe solo se lo spazio non basta — flex-wrap fa tutto da solo, senza
   bisogno di media query dedicate. */
.cn-indietro-sotto { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: .5rem; margin-top: 1rem; }
/* "Indietro" sempre a sinistra (in arabo a destra), anche quando sta nella stessa riga di Invia/Continua (2026-10-02). */
.cn-btn.cn-btn-indietro { margin-inline-end: auto; }
/* margin-bottom oltre al margin-top: senza, il pulsante "Rigenera" (alternative del turno,
   scrivi.js) restava incollato senza spazio al campo "O spiegami cosa vorresti..." subito sotto —
   .cn-field ha margine solo in basso su di sé, nessuno in cima. */
.cn-concludi-romanzo { display: flex; justify-content: flex-end; margin: 1.5rem 0; }
/* Sotto le alternative del turno: "Concludi il capitolo" e "Concludi il romanzo" su due righe, allineati a destra. */
.cn-concludi-colonna { flex-direction: column; align-items: flex-end; gap: .5rem; }
.cn-concluso-azioni { display: flex; gap: .5rem; margin-top: .75rem; align-items: center; }

.cn-actions { display: flex; flex-direction: column; gap: .5rem; margin: 1.5rem 0; }
/* Stessa dimensione delle opzioni sottostanti (.cn-action-btn): a differenza di .cn-punto-meta,
   qui è un titolo di sezione, non una nota secondaria, quindi niente rimpicciolimento/opacità. */
.cn-scegli-titolo { font-size: .95em; margin: 0; font-style: italic; }
.cn-action-btn {
  text-align: left; padding: .75rem 1rem; border-radius: .5rem;
  border: 1px solid var(--cn-border); background: var(--cn-icon-bg);
  color: inherit; font: inherit; font-size: .95em; cursor: pointer;
}
.cn-action-btn:hover { border-color: var(--cn-accent); }
/* renderStileScelta (scrivi.js/demo.js): descrizione di uno stile preconfigurato, dentro al suo
   stesso pulsante — a differenza di .cn-punto-meta niente opacità ridotta (stesso colore del
   titolo sopra, eredita .cn-action-btn { color: inherit }), solo un filo più grande di una nota
   secondaria perché qui è il contenuto vero e proprio, non un'annotazione. */
.cn-stile-preset-desc { font-size: .85em; margin-top: .15rem; }
/* espandiStiliPersonali (scrivi.js): un div normale non fa stretchare i <button> a piena larghezza
   come .cn-actions (flex column, cross-axis stretch di default) — senza questa regola i pulsanti
   degli stili personali restavano larghi solo quanto il loro testo, molto più stretti degli altri
   pulsanti stile sopra di loro. */
.cn-stile-personali-lista { display: flex; flex-direction: column; gap: .5rem; }
.cn-action-free { display: flex; gap: .5rem; }
/* Invia (spiega) e Inserisci (continua) dopo le alternative proposte dall'IA: stessa larghezza,
   non quella intrinseca del testo del pulsante, così il paio risulta visivamente allineato. */
#btn-spiega-invia, #btn-continua-invia { flex: 0 0 7rem; width: 7rem; text-align: center; }
.cn-action-free input, .cn-action-free textarea {
  flex: 1; padding: .65rem .8rem; border-radius: .5rem;
  border: 1px solid var(--cn-border); background: transparent; color: inherit; font: inherit;
}

.cn-btn {
  padding: .55rem 1.1rem; border-radius: .5rem; border: 1px solid var(--cn-btn-bg);
  background: var(--cn-btn-bg); color: var(--cn-btn-text); font: inherit; font-size: .9em; font-weight: 600; cursor: pointer;
  text-decoration: none; display: inline-block;
}
/* .cn-btn imposta display e batterebbe l'attributo hidden: senza questa riga un pulsante "nascosto" resta visibile. */
.cn-btn[hidden] { display: none; }
.cn-btn:hover { filter: brightness(1.05); }
.cn-btn.secondary { background: transparent; color: inherit; border-color: var(--cn-border); font-weight: 400; }
.cn-btn:disabled { opacity: .5; cursor: not-allowed; }
.cn-btn.cn-btn-piccolo { padding: .3rem .6rem; font-size: .78em; white-space: nowrap; }
/* Pulsantino in linea con una riga di testo (Impostazioni: "Passa a Premium" accanto al piano): stessa grandezza del testo. */
.cn-btn.cn-btn-inline { display: inline-block; width: auto; margin: 0 0 0 .5rem; padding: 0 .5em; font-size: inherit; line-height: inherit; white-space: nowrap; vertical-align: baseline; opacity: 1; }
.cn-drawer-header h2 { min-width: 0; overflow-wrap: anywhere; }

.cn-page-indicator { text-align: center; font-size: .8em; opacity: .5; padding-bottom: 2rem; }

/* ---------- drawer (Faro / Punti aperti / Schede / Analisi) ---------- */
.cn-drawer {
  position: fixed; top: 3.75rem; right: 0; width: min(var(--cn-drawer-width, 23.6rem), 100vw); height: calc(100vh - 3.75rem);
  background: var(--cn-bg); color: var(--cn-text); border-left: 1px solid var(--cn-border);
  box-shadow: -6px 0 24px rgba(0, 0, 0, .18);
  transform: translateX(100%);
  transition: transform .25s ease;
  z-index: 20; overflow-y: auto; padding: 1.5rem 1.5rem 4rem;
}
/* Sul telefono 100vh comprende anche la barra del browser, quindi il fondo della barra laterale (con "Salva le modifiche") restava
   nascosto: dove esiste si usa l'altezza visibile vera (dvh), e sotto l'ultimo pulsante resta sempre spazio vuoto (padding sopra). */
@supports (height: 100dvh) {
  .cn-drawer { height: calc(100dvh - 3.75rem); }
}
.cn-drawer.is-open { transform: translateX(0); }
/* Admin in sola lettura (vedi render() in scrivi.js, .cn-sola-lettura su body): disabilita in
   blocco ogni form del cassetto invece di dover intervenire pannello per pannello — i pulsanti di
   navigazione/tab restano invece cliccabili (fuori da .cn-drawer-panel), solo il CONTENUTO dei
   pannelli diventa inerte. */
.cn-sola-lettura .cn-drawer-panel input,
.cn-sola-lettura .cn-drawer-panel textarea,
.cn-sola-lettura .cn-drawer-panel select,
.cn-sola-lettura .cn-drawer-panel button {
  pointer-events: none; opacity: .55;
}
/* La transizione è su transform, non su width: il ridimensionamento trascinato (che cambia solo
   --cn-drawer-width, vedi wireDrawerResizeHandle in app.js) segue il mouse 1:1 senza ritardo,
   indipendentemente da questa regola. */
/* Maniglia sul bordo sinistro del drawer Faro per ridimensionarlo trascinando col mouse (vedi
   initDrawerResize() in scrivi.js): larga 8px ma centrata sul bordo (-4px) così l'area cliccabile
   sporge un po' su entrambi i lati, più facile da agganciare col cursore. */
.cn-drawer-resize-handle {
  position: absolute; left: -4px; top: 0; width: 8px; height: 100%; cursor: ew-resize; z-index: 5;
}

.cn-drawer-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; }
/* "Impostazioni" e "Dietro le quinte": stessa dimensione di un titolo di capitolo (.cn-capitolo-titolo). */
.cn-drawer-header h2, .cn-drawer-header strong { font-size: 1.15em; margin: 0; }
/* Pulsante "x" delle Impostazioni: stessa altezza esatta del pulsante "Esci"/"Accedi" affiancato
   (box-sizing:border-box globale rende height/width la misura vera del pulsante), non la misura
   rotonda standard di .cn-icon-btn (2.2rem), più alta. */
#settings-drawer .cn-drawer-header .cn-btn-piccolo,
#settings-drawer .cn-drawer-header .cn-drawer-close { height: 1.9rem; }
#settings-drawer .cn-drawer-header .cn-drawer-close { width: 1.9rem; }
.cn-drawer-tabs { display: flex; gap: .35rem; flex-wrap: wrap; margin-bottom: 1rem; }
.cn-tab { padding: .35rem .7rem; border-radius: 999px; border: 2px solid var(--cn-border); background: transparent; color: inherit; font: inherit; font-size: .8em; cursor: pointer; }
.cn-tab.is-active { background: transparent; color: var(--cn-accent); border-color: var(--cn-accent); }
.cn-drawer-panel { display: none; }
.cn-drawer-panel.is-active { display: block; }

/* Badge "Tradotto" (vedi badgeTradotto() in app.js): stesso linguaggio visivo pillola di .cn-tab,
   ma non cliccabile — solo un'etichetta. */
.cn-badge-tradotto { display: inline-flex; align-items: center; gap: .3em; padding: .2rem .6rem; border-radius: 999px; border: 1px solid var(--cn-icon-border); background: var(--cn-icon-bg); font-size: .8em; }
.cn-badge-tradotto .cn-icon { width: .9em; height: .9em; }

.cn-drawer-section { margin-top: 1.5rem; }
.cn-drawer-section h3, .cn-drawer-collapse-header h3 { font-size: .78em; text-transform: uppercase; opacity: .55; letter-spacing: .06em; margin: 0 0 .6rem; }
.cn-drawer-section > .cn-btn { margin-bottom: .6rem; }

/* Sezioni "a comparsa" del drawer Impostazioni (tema personalizzato, pagamenti, cambio dati
   account): contratte di default, mostrano solo il titolo finché non si clicca per espanderle —
   evita che la barra risulti troppo lunga con tutto sempre visibile. */
.cn-drawer-collapse { margin-top: 1.5rem; }
.cn-drawer-collapse-header {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem; width: 100%;
  background: transparent; border: none; padding: 0; margin: 0 0 .6rem; cursor: pointer;
  color: inherit; font: inherit; text-align: left;
}
.cn-drawer-collapse-header h3 { flex: 1; }
.cn-drawer-collapse-header svg { width: 1em; height: 1em; opacity: .55; flex-shrink: 0; transition: transform .2s ease; }
.cn-drawer-collapse.is-espanso .cn-drawer-collapse-header svg { transform: rotate(180deg); }
.cn-drawer-collapse-body { display: none; }
.cn-drawer-collapse.is-espanso .cn-drawer-collapse-body { display: block; }
/* Pannello admin > Provider IA: i titoli dei blocchi (Modello principale, Modello secondario,
   Controllo testo e copertina, IA Admin) sono a comparsa come le altre sezioni del drawer, ma in
   evidenza (scuri, non piccoli/discreti) perché sono la navigazione principale di questa scheda,
   non un dettaglio secondario. */
#admin-content .cn-drawer-collapse-header h3 { font-size: .95em; text-transform: none; letter-spacing: normal; opacity: 1; color: var(--cn-text); font-weight: 700; }
.cn-field { margin-bottom: .8rem; }
/* 1em, non 1.05em: né l'etichetta né il testo dei campi del drawer (Faro, Impostazioni, ...) devono
   avere una dimensione diversa dal testo del romanzo — entrambi ereditano da --cn-font-size senza
   alcuna moltiplicazione, esattamente come .cn-paragraph. */
.cn-field label { display: block; font-size: 1em; opacity: .8; margin-bottom: .35rem; }
.cn-field textarea, .cn-field input:not([type="radio"]):not([type="checkbox"]), .cn-field select {
  width: 100%; padding: .55rem; border-radius: .4rem; border: 1px solid var(--cn-border);
  background: transparent; color: inherit; font: inherit; font-size: 1em;
}
.cn-field textarea { resize: vertical; min-height: 4rem; }
/* Schede dei personaggi e dei luoghi: niente altezza minima, il campo è alto quanto il suo testo (vedi campoSchedaHtml). */
.cn-field textarea.cn-campo-scheda, textarea.cn-campo-scheda#onboarding-input { min-height: 0; field-sizing: content; }
/* Nome del capitolo in Dietro le quinte > Capitoli: non sta in un .cn-field, e senza queste regole il browser lo mostrava
   bianco invece che con i colori del tema. */
.capitolo-nome-input {
  width: 100%; padding: .55rem; border-radius: .4rem; border: 1px solid var(--cn-border);
  background: transparent; color: inherit; font: inherit; font-size: 1em; font-weight: 700; margin-bottom: .35rem;
}
/* Campi fuori da un .cn-field (es. ricerca e ordinamento dell'elenco utenti in admin): senza queste regole il browser li mostra bianchi. */
.cn-campo-libero {
  padding: .45rem .55rem; border-radius: .4rem; border: 1px solid var(--cn-border);
  background: transparent; color: inherit; font: inherit; font-size: 1em;
}
/* Campo con il corsivo vero (campoRiccoHtml in scrivi.js), stesso aspetto di una textarea. */
.cn-campo-ricco {
  width: 100%; padding: .55rem; border-radius: .4rem; border: 1px solid var(--cn-border);
  background: transparent; color: inherit; font: inherit; font-size: 1em; line-height: 1.5; overflow-wrap: anywhere;
}
.cn-campo-ricco:empty::before { content: attr(data-placeholder); opacity: .5; pointer-events: none; }
.cn-file-picker { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }

/* Chrome/Safari colorano di giallo/blu i campi che riconoscono come credenziali di login
   (tipicamente username e password, non email o conferma password) appena l'autofill li tocca,
   sovrascrivendo lo sfondo trasparente del template sopra. Il box-shadow enorme "riempie" il
   campo con lo sfondo del tema invece del giallo nativo, senza toccare bordo/testo. */
.cn-field input:-webkit-autofill,
.cn-field input:-webkit-autofill:hover,
.cn-field input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--cn-text);
  box-shadow: 0 0 0 1000px var(--cn-bg) inset;
  transition: background-color 5000s ease-in-out 0s;
}

/* Radio/checkbox dentro .cn-field ereditavano width:100%/padding/border dalla regola sopra,
   destinata a testarea/input di testo/select: li deformava in riquadri enormi, disallineati dal
   testo dell'etichetta. Qui vengono resettati alla loro dimensione naturale e allineati in riga. */
.cn-field input[type="radio"], .cn-field input[type="checkbox"] {
  width: auto; flex-shrink: 0; margin: 0;
}
.cn-field label:has(> input[type="radio"]) {
  display: inline-flex; align-items: center; gap: .45em; margin: 0 1.2rem .35rem 0;
}
/* Checkbox associato a un testo lungo (es. dichiarazione di responsabilità in pubblicazione): allineato
   in alto sulla prima riga invece che al centro di tutto il blocco di testo andato a capo. */
.cn-field label:has(> input[type="checkbox"]) {
  display: flex; align-items: flex-start; gap: .45em; margin: 0 0 .35rem 0;
}
.cn-field label:has(> input[type="checkbox"]) input { margin-top: .2em; }

/* Textarea dei Punti aperti: NON dentro un .cn-field (è un elemento libero in .cn-punto), quindi
   senza questa regola resta con lo sfondo bianco di default del browser invece di quello del tema. */
.punto-descrizione {
  width: 100%; padding: .55rem; border-radius: .4rem; border: 1px solid var(--cn-border);
  background: transparent; color: inherit; font: inherit; font-size: 1em; resize: vertical;
}

/* Nome dei personaggi principali (Faro) e nome nelle Schede (personaggio/oggetto/luogo): risalta
   rispetto agli altri campi nella stessa card. Specificità .cn-field input.xxx (0,3,0) necessaria
   per battere ".cn-field input" (0,2,0), la cui "font: inherit" shorthand azzererebbe altrimenti
   il font-weight impostato qui. */
.cn-field input.fp-nome, .cn-field input.frp-nome, .cn-field input.scheda-nome { font-weight: 700; }
/* Schede del motore della storia (revisione dopo l'analisi e Dietro le quinte): nome in grassetto, textarea di una riga. */
.cn-field textarea.vs-nome { font-weight: 700; }
.cn-field textarea[rows="1"] { min-height: 0; }
/* Pulsante classico sotto un campo di testo, allineato a destra (incipit, "Richiedi una modifica" sulla bozza, "O spiegami", "O continua tu"). */
.cn-pulsanti-sotto { display: flex; justify-content: flex-end; align-items: center; gap: .5rem; margin-top: .8rem; }
/* Stessa distanza tra campo e pulsante in tutti i casi: una textarea è inline-block e lasciava sotto di sé qualche pixel in più
   ("O spiegami" risultava più distante di "O continua tu", che sta in un .cn-format-wrap con la textarea a blocco). */
.cn-field textarea:has(+ .cn-pulsanti-sotto), .cn-field input:has(+ .cn-pulsanti-sotto) { display: block; margin-bottom: 0; }

/* I <select> nativi non ereditano colori dal tema come input/textarea: senza queste regole
   restano con lo sfondo bianco di default del browser anche nei temi scuro/papiro. */
select {
  background: var(--cn-bg); color: var(--cn-text); font: inherit;
  border: 1px solid var(--cn-border); border-radius: .4rem; padding: .4rem .5rem;
}
select option { background: var(--cn-bg); color: var(--cn-text); }
/* Freccia dei menu a tendina disegnata da noi (quella del browser sta attaccata al bordo destro e non si sposta): due triangoli
   nel colore del testo, a .75rem dal bordo. !important perché tante regole più sotto riscrivono `background` e `padding` per intero. */
select:not([multiple]):not([size]) {
  -webkit-appearance: none; appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%) !important;
  background-position: calc(100% - .75rem - 4px) 52%, calc(100% - .75rem) 52% !important;
  background-size: 4px 4px, 4px 4px !important;
  background-repeat: no-repeat !important;
  padding-right: 2rem !important;
}

.cn-punto, .cn-scheda-card, .cn-avviso, .cn-correzione {
  padding: .6rem .7rem; border-radius: .4rem; border: 1px solid var(--cn-border);
  margin-bottom: .5rem; font-size: .85em;
}
.cn-punto.is-risolto { opacity: .5; text-decoration: line-through; }
.cn-scheda-card-cliccabile { cursor: pointer; }
.cn-scheda-card-cliccabile:hover { border-color: var(--cn-accent); }
/* Stile attivo sulla creazione corrente (vedi renderStiliPanel): sfondo tenue invece del solo
   bordo, per essere riconoscibile a colpo d'occhio tra più voci della libreria. */
.cn-scheda-card.is-attivo {
  border-color: var(--cn-accent);
  background: color-mix(in srgb, var(--cn-accent) 12%, transparent);
}
/* Segreto aperto dal link di un avviso sotto la bozza (apriSegretoInDrawer in scrivi.js). */
.cn-scheda-card.vs-segreto.is-evidenziato {
  border: 2px solid var(--cn-accent);
  background: color-mix(in srgb, var(--cn-accent) 12%, transparent);
}
.cn-punto-meta, .cn-scheda-meta { font-size: .75em; opacity: .6; margin-top: .2rem; }
/* Email nella barra Impostazioni: attaccata al nome utente, con uno spazio sotto, e nessuna sottolineatura (anche quando il
   browser la trasforma da solo in un link). */
.cn-punto-meta.cn-email-utente { margin: 0 0 .6rem; }
.cn-email-utente, .cn-email-utente a { text-decoration: none !important; color: inherit !important; }
/* renderStileScelta (scrivi.js/demo.js): la nota "puoi comunque cambiare stile più avanti" resta
   un'annotazione secondaria (stessa opacità ridotta di .cn-punto-meta) ma un filo più leggibile
   delle altre note della stessa classe, essendo sopra a un intero elenco di pulsanti e non accanto
   a un singolo elemento. */
.cn-stile-nota-modificabile { font-size: .85em; }
.cn-avviso.gravita-alta { border-color: #e05252; }
.cn-credito-ia { margin-bottom: .8rem; }
.cn-credito-ia p { margin: 0; }
.cn-avviso-actions { display: flex; gap: .4rem; margin-top: .4rem; }
/* Schede di personaggi, luoghi e segreti (revisione dei vincoli, Dietro le quinte, Crea trama): il cestino a destra come gli altri pulsanti. */
.vs-azioni { justify-content: flex-end; align-items: center; }
/* Segreti fissi di un prequel (il futuro del romanzo originale): solo da leggere, sotto l’elenco modificabile. */
.vs-fissi { margin-top: 1.25rem; }
.vs-fisso { margin: 0; white-space: pre-wrap; }
.cn-avviso-actions button { font-size: .75em; padding: .25rem .6rem; }

.cn-proposta { border: 1px solid var(--cn-accent); border-radius: .5rem; padding: .75rem; margin-bottom: 1rem; font-size: .85em; }
.cn-proposta-actions { display: flex; gap: .5rem; margin-top: .6rem; }

/* ---------- conversazione (chat) view ---------- */
.cn-turn { margin-bottom: 1.75rem; }
.cn-turn[contenteditable="true"] { cursor: text; border-radius: .4rem; }
.cn-turn[contenteditable="true"]:focus { outline: 1px solid var(--cn-accent); padding: .5rem; }
.cn-modifica-inline { margin: .75rem 0 1.75rem; }
/* Libro-gioco (gioca.html): la mossa del giocatore sopra il paragrafo che ne è nato. */
.cn-gioco-intro { font-style: italic; color: var(--cn-muted); margin: 0 0 2rem; padding-bottom: 1.25rem; border-bottom: 1px solid var(--cn-border); }
.cn-gioco-intro p { margin: 0 0 .75rem; }
.cn-book-librogioco { font-size: .8em; font-style: italic; }

/* ---------- capitoli ---------- */
.cn-capitolo-titolo { text-align: center; font-weight: 700; font-size: 1.3em; margin: 2.5rem 0 1.25rem; }
.cn-capitolo-marker {
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  font-weight: 700; font-size: 1.15em; margin: 2.5rem 0 1rem; text-align: center;
}
.cn-capitolo-marker .cn-icon-btn { opacity: .5; }
.cn-capitolo-marker .cn-icon-btn:hover { opacity: 1; }
.cn-capitolo-nome[contenteditable="true"] { cursor: text; border-radius: .3rem; padding: .1rem .3rem; }
.cn-capitolo-nome[contenteditable="true"]:hover { outline: 1px solid var(--cn-border); }
.cn-capitolo-nome[contenteditable="true"]:focus { outline: 1px solid var(--cn-accent); }
/* Diario (diario.js): il titolo del giorno aperto si modifica come il nome di un capitolo; i giorni precedenti si riaprono con un clic. */
.cn-diario-titolo {
  font: inherit; font-size: .85em; font-weight: 700; text-align: center; color: inherit; background: transparent;
  border: 1px solid transparent; border-radius: .3rem; padding: .1rem .3rem; width: min(100%, 32rem);
  resize: none; overflow: hidden; display: block; margin: 0 auto; line-height: 1.3;
}
.cn-diario-titolo:hover { border-color: var(--cn-border); }
.cn-diario-titolo:focus { outline: none; border: 1px solid var(--cn-accent); }
.cn-diario-giorno { cursor: pointer; }
/* Paragrafo che è un titolo (pulsante T), aperto nella casella: grande e in grassetto come il nome di un capitolo, senza segni. */
#d-testo.cn-diario-testo-titolo { font-weight: 700; font-size: 1.15em; text-align: center; }
/* Titolo del giorno con annulla/ripeti, cestino, B e I in sovrimpressione in basso, come le caselle di prosa. */
.cn-diario-titolo-wrap { position: relative; width: min(100%, 32rem); margin: 0 auto; }
.cn-diario-titolo-wrap .cn-diario-titolo { width: 100%; }
/* Lo spazio per i comandi (annulla, cestino, B, I) si apre sotto il titolo solo mentre lo si modifica: il paragrafo sotto si abbassa. */
.cn-diario-titolo-wrap:focus-within { padding-bottom: 2.2rem; }
body.cn-diario-lettura .cn-diario-titolo-wrap .cn-format-row { display: none; }
body.cn-diario-lettura .cn-diario-titolo-wrap:has(.cn-diario-titolo:placeholder-shown) { display: none; }
/* Annulla/ripeti, cestino, B, I e T si vedono solo sul campo che si sta modificando (titolo del giorno o paragrafo aperto). */
#turn-area .cn-diario-titolo-wrap:not(:focus-within) .cn-format-row,
#turn-area .cn-format-wrap:not(:focus-within) .cn-format-row { opacity: 0; pointer-events: none; }
body.cn-diario-lettura .cn-diario-titolo-wrap:focus-within { padding-bottom: 0; }
/* Il titolo del giorno sta subito sotto la barra: il margine grande dei nomi di capitolo serve solo a staccarlo dal giorno prima. */
#turn-area > .cn-capitolo-marker { margin-top: 1rem; }
/* Pulsanti sotto le caselle: se non ci stanno in una riga, quelli in più vanno sulla riga sotto. */
.cn-diario-pulsanti { flex-wrap: wrap; align-items: flex-start; }
/* I due Rielabora: larghi come il paragrafo, aspetto delle mosse del libro-gioco (.cn-action-btn) col testo centrato; il menu dello
   stile sotto il secondo, a destra, carattere piccolo. */
.cn-diario-lista { margin: 0; padding-inline-start: 1.6em; }
.cn-diario-lista li { margin: .25em 0; }
.cn-diario-rielabora-blocco { display: flex; flex-direction: column; gap: .5rem; margin-top: .8rem; }
.cn-diario-rielabora-blocco .cn-action-btn { text-align: center; font-size: .85em; }
/* Riquadro "Richiedi una modifica" sotto i Rielabora: testo piccolo come loro. */
.cn-diario-modifica-testo textarea { font-size: .85em; }
/* Stesso spazio che separa i due Rielabora; "Applica" con il carattere e lo sfondo dei Rielabora (2026-10-01). */
.cn-diario-modifica-testo .cn-richiesta-modifica { margin-top: .5rem; }
.cn-diario-modifica-testo .cn-richiesta-modifica > .cn-btn { font-size: .85em; background: var(--cn-icon-bg); border: 1px solid var(--cn-border); }
/* "Usa questa versione" con lo sfondo dei Rielabora; l'"Applica" sotto la proposta resta senza (lo ha solo quello accanto ai Rielabora). */
#d-usa { background: var(--cn-icon-bg); border: 1px solid var(--cn-border); }
.cn-diario-rielabora-blocco .cn-diario-stile { align-self: flex-end; }
.cn-diario-arricchita { display: flex; flex-direction: column; align-items: stretch; gap: .25rem; }
.cn-diario-stile { display: flex; flex-direction: column; gap: .25rem; font-size: .75em; }
.cn-diario-stile select, .cn-diario-stile input {
  font: inherit; max-width: 100%; padding: .3rem .4rem; border-radius: .4rem; border: 1px solid var(--cn-border);
  background: transparent; color: inherit;
}
.cn-diario-stile select option { background: var(--cn-bg); color: inherit; }
/* Riquadro del testo del giorno: stesso bordo del paragrafo in modifica nel romanzo (.cn-turn[contenteditable]:focus). */
#d-testo, #d-testo:focus { border: 1px solid var(--cn-accent); border-radius: .4rem; outline: none; }
/* Sola lettura del diario (modoLettura in diario.js, pulsante nella barra): via pulsanti, campi, bordi e proposte; il paragrafo aperto si
   legge come gli altri (#d-testo-lettura, nascosto mentre si scrive). */
.cn-diario-lettura-testo { display: none; }
body.cn-diario-lettura .cn-diario-lettura-testo { display: block; }
body.cn-diario-lettura #turn-area .cn-format-wrap,
body.cn-diario-lettura #turn-area .cn-pulsanti-sotto,
body.cn-diario-lettura #turn-area .cn-diario-rielabora-blocco,
body.cn-diario-lettura #d-proposte,
body.cn-diario-lettura #turn-area .cn-diario-stile,
body.cn-diario-lettura #turn-area .cn-diario-modifica-testo,
body.cn-diario-lettura #d-avviso-lungo,
body.cn-diario-lettura #turn-area .cn-concludi-romanzo { display: none; }
body.cn-diario-lettura .cn-diario-titolo, body.cn-diario-lettura .cn-diario-titolo:hover { border-color: transparent; cursor: default; }
.cn-aggiungi-capitolo {
  display: none; align-items: center; gap: .3rem; margin: 1.5rem auto 1rem;
  font-size: .78em; padding: .3rem .7rem; opacity: .45;
}
.cn-aggiungi-capitolo:hover { opacity: 1; }
/* Il pulsante compare solo sopra e sotto il paragrafo che si sta modificando (bordo tratteggiato,
   vedi .cn-turn[contenteditable="true"]:focus sopra), non su ogni paragrafo del romanzo: sopra è il
   pulsante del blocco stesso, sotto è quello del blocco successivo (vedi wrapping .cn-paragrafo-
   blocco in renderStory, scrivi.js). Il marker di un capitolo già esistente resta sempre visibile,
   non è toccato da questa regola. */
.cn-paragrafo-blocco:has(.cn-turn:focus) .cn-aggiungi-capitolo,
.cn-paragrafo-blocco:has(.cn-turn:focus) + .cn-paragrafo-blocco .cn-aggiungi-capitolo {
  display: flex;
}

/* ---------- misc ---------- */
.cn-empty { opacity: .55; font-size: .9em; }

/* Barra di avanzamento minimale (es. importazione manoscritto, un blocco alla volta): niente di
   più di un contorno sottile e un riempimento pieno, coerente con lo stile essenziale del resto
   dei controlli dell'app. */
.cn-progress-bar {
  width: 100%; height: .5rem; border: 1px solid var(--cn-border); border-radius: .3rem;
  overflow: hidden; margin: .75rem 0 .35rem;
}
.cn-progress-bar-fill { height: 100%; background: var(--cn-accent); transition: width .3s ease; }
/* Finché non si conosce ancora il numero totale di blocchi (validazione file, o subito dopo aver
   premuto "Riprova"), una barra ferma allo 0% è indistinguibile da una pagina bloccata: questa
   variante scorre avanti e indietro per mostrare che qualcosa sta comunque succedendo. */
.cn-progress-bar-fill.is-indeterminate {
  width: 40% !important; animation: cn-progress-indeterminate 1.1s ease-in-out infinite;
}
@keyframes cn-progress-indeterminate {
  0% { margin-left: 0%; }
  50% { margin-left: 60%; }
  100% { margin-left: 0%; }
}
/* Anello che gira usato da attesaIaHtml() (app.js) dopo il messaggio d'attesa di ogni chiamata IA:
   stesso colore del testo (currentColor, niente accento colorato), coerente con un sito
   minimalista — niente puntini (molti messaggi d'attesa finiscono già con "…" nel testo), niente
   icona disegnata, niente barra di avanzamento (tutte scartate). */
.cn-ia-spinner {
  display: inline-block; width: .8em; height: .8em; margin-left: .4em; vertical-align: -.1em;
  border: 2px solid currentColor; border-top-color: transparent; border-radius: 50%;
  opacity: .6; animation: cn-ia-girare .8s linear infinite;
}
@keyframes cn-ia-girare { to { transform: rotate(360deg); } }
.cn-toast-container { position: fixed; bottom: 1rem; left: 50%; transform: translateX(-50%); z-index: 50; display: flex; flex-direction: column; gap: .5rem; align-items: center; }
/* Avvisi in basso intonati al tema (2026-09-30): sfondo tenue nel colore d'accento, errori in un rosso adatto a ogni tema. */
.cn-toast { padding: .5rem 1rem; border-radius: .4rem; background: var(--cn-avviso-bg); color: var(--cn-avviso-text); border: 1px solid var(--cn-avviso-border); font-size: .78em; box-shadow: 0 4px 14px rgba(0,0,0,.12); }
.cn-toast.error { background: var(--cn-errore-bg); color: var(--cn-errore-text); border-color: var(--cn-errore-border); }
.cn-avviso-sito { position: fixed; top: 0; left: 0; right: 0; z-index: 70; display: flex; align-items: center; justify-content: center; gap: .8rem; padding: .55rem 1rem; background: #e05252; color: #fff; font-size: .9em; line-height: 1.4; text-align: center; box-shadow: 0 2px 10px rgba(0,0,0,.25); }
.cn-avviso-sito-chiudi { background: none; border: 0; color: inherit; font-size: 1.4em; line-height: 1; cursor: pointer; padding: 0 .3rem; }
/* Blocchi del superadmin (app.js, mostraBloccoSito/mostraAvvisoIaBloccata/disegnaPromemoriaBlocchi). */
.cn-blocco-testo { white-space: pre-line; line-height: 1.55; margin: 0; }
.cn-blocco-barra { padding: .8rem 1rem; background: #e05252; color: #fff; text-align: center; font-size: .95em; }
.cn-blocco-schermo { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 1rem; background: var(--cn-bg); color: var(--cn-text); overflow-y: auto; }
.cn-blocco-riquadro { max-width: 34rem; display: flex; flex-direction: column; align-items: center; gap: 1.4rem; text-align: center; font-size: 1.05em; }
.cn-blocco-ia { z-index: 80; }
.cn-blocco-riquadro .cn-blocco-logo { margin-bottom: 0; }
.cn-blocco-riquadro .cn-blocco-logo img { width: 3.2rem; height: 3.2rem; }
.cn-blocco-riquadro .cn-blocco-titolo { margin: 0; font-size: 1.4em; }
.cn-blocco-barra .cn-blocco-titolo { display: block; margin-bottom: .3rem; font-size: 1.05em; }
.cn-blocco-barra-logo { display: block; width: 2rem; height: 2rem; margin: 0 auto .4rem; object-fit: contain; filter: brightness(0) invert(1); }
.cn-promemoria-blocchi { position: fixed; left: .75rem; bottom: .75rem; z-index: 70; max-width: calc(100vw - 1.5rem); padding: .35rem .7rem; border-radius: .4rem; background: #e05252; color: #fff; font-size: .8em; box-shadow: 0 2px 8px rgba(0,0,0,.2); pointer-events: none; }

.cn-modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.4); display: flex; align-items: center; justify-content: center; z-index: 40; }
.cn-modal { background: var(--cn-bg); color: var(--cn-text); border-radius: .6rem; padding: 1.5rem; width: min(30rem, 92vw); max-height: 85vh; overflow-y: auto; }
.cn-modal h2 { margin-top: 0; }
.cn-modal-intro { font-size: .9em; opacity: .8; }
.cn-modal-header { display: flex; align-items: center; justify-content: space-between; gap: .75rem; }
.cn-modal-header h2 { margin: 0; font-size: 1.05em; }
.cn-modal-header .cn-icon-btn { flex-shrink: 0; width: 1.9rem; height: 1.9rem; }
.cn-modal-actions { display: flex; justify-content: flex-end; gap: .5rem; margin-top: 1.25rem; }
.cn-modal-largo { width: min(46rem, 92vw); }

/* Mappa dei rami (Registra nuova demo, vedi scrivi.js apriMappaRami) */
.cn-mappa-rami { margin-top: 1rem; }
.cn-mappa-nodo-testo { font-size: .9em; }
.cn-mappa-opzioni { list-style: none; margin: .4rem 0 .8rem; padding-left: 1.1rem; border-left: 2px solid var(--cn-border, currentColor); display: flex; flex-direction: column; gap: .6rem; }
.cn-mappa-opzione { font-size: .9em; }
.cn-mappa-opzione-azione { font-style: italic; opacity: .85; margin-bottom: .25rem; }
.cn-mappa-opzione.is-completata .cn-mappa-opzione-azione { color: #2f9e64; }
.cn-mappa-opzione.is-bozza .cn-mappa-opzione-azione { color: #c8850f; }
.cn-mappa-nodo-nota { font-size: .85em; opacity: .7; margin: .25rem 0 0; }
.cn-mappa-badge { display: inline-block; font-size: .75em; font-weight: 600; padding: .1rem .4rem; border-radius: .3rem; background: var(--cn-icon-bg); margin-left: .35rem; }
.cn-mappa-badge-finale { color: #2f9e64; }
.cn-mappa-badge-qui { color: var(--cn-accent); }
.cn-mappa-vai { font-size: .85em; padding: .3rem .6rem; }

.cn-auth-logo { display: flex; align-items: center; gap: .6rem; justify-content: center; margin-bottom: 1.25rem; }
.cn-auth-logo img { width: 2.4rem; height: 2.4rem; object-fit: contain; }
[data-theme="dark"] .cn-auth-logo img { filter: invert(1); }
.cn-auth-logo span { font-weight: 700; font-size: 1.15em; }

/* ---------- index.html (project list) ---------- */
.cn-page { max-width: 42rem; width: 100%; margin: 0 auto; padding: 2rem 1.5rem 4rem; }
/* Ritmo verticale dei titoli di sezione e dei paragrafi: più spazio sopra i titoli (li stacca dal
   paragrafo precedente), meno spazio sotto (li avvicina al testo che introducono), leggermente
   meno spazio fra un paragrafo e l'altro. Margine solo in basso sui paragrafi così il distacco
   dipende sempre dall'elemento sopra, senza ambiguità di collasso dei margini. */
.cn-page h2 { margin-top: 30px; margin-bottom: .5em; font-size: 1.15em; }
.cn-page p { margin-top: 0; margin-bottom: .8em; }
.cn-page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; gap: .75rem; flex-wrap: wrap; }
.cn-page-header-actions { position: relative; display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.cn-project-card { display: flex; align-items: center; justify-content: space-between; gap: .75rem; padding: 1rem; border: 1px solid var(--cn-border); border-radius: .6rem; margin-bottom: .75rem; cursor: pointer; }
.cn-project-card-top { display: flex; align-items: center; gap: .75rem; min-width: 0; flex: 1; }
.cn-project-cover-thumb { width: 2.4rem; height: 3.6rem; object-fit: cover; border-radius: .25rem; flex-shrink: 0; background: var(--cn-border); }
.cn-project-card:hover { border-color: var(--cn-accent); }
.cn-project-card-main { min-width: 0; flex: 1; }
/* Un titolo lungo (anche una parola sola senza spazi) va a capo dentro il riquadro invece di uscirne. */
.cn-project-card .cn-project-titolo { font-weight: 600; margin-bottom: .25rem; overflow-wrap: anywhere; }
.cn-project-card .cn-project-meta { font-size: .8em; opacity: .6; }
/* "Ordina per…" sopra la lista di I tuoi scritti: piccolo, a destra; chiuso mostra sempre "Ordina per…" (index.js). */
.cn-ordina-wrap { display: flex; justify-content: flex-end; align-items: center; gap: .6rem; margin: -.3rem 0 .6rem; }
/* Pulsantini tondi del filtro per tipo (Leggi, filtroTipi in reader/index.js; in "I tuoi scritti" tolti il 2026-10-09). */
.cn-filtro-tipi { display: flex; flex-wrap: wrap; gap: .35rem; }
.cn-filtro-tipo { width: 2.1rem; height: 2.1rem; border-radius: 50%; padding: 0; display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  background: var(--cn-icon-bg); border: 1px solid var(--cn-icon-border); opacity: .45; transition: opacity .15s ease, border-color .15s ease; }
.cn-filtro-tipo.is-attivo { opacity: 1; border: 2px solid var(--cn-accent); }
.cn-filtro-tipo img { width: 1.3rem; height: 1.3rem; object-fit: contain; }
/* Nome del pulsantino toccato, per un attimo (solo sul telefono): sopra il pulsantino, dal suo bordo sinistro (left/top da
   posizionaEtichettaFiltro in app.js), sopra il resto della pagina, così niente si sposta. */
.cn-filtro-tipi { position: relative; }
.cn-filtro-etichetta { position: absolute; left: 0; top: 0; transform: translateY(calc(-100% - .3rem)); z-index: 5; font-size: .75em;
  white-space: nowrap; padding: .15rem .45rem; border-radius: .4rem; background: var(--cn-bg); border: 1px solid var(--cn-border); }
[data-theme="dark"] .cn-filtro-tipo img { filter: invert(1); }
.cn-ordina-wrap[hidden] { display: none; }
.cn-ordina { font-size: .8em; padding: .2rem .4rem; cursor: pointer; }
.cn-project-card-actions { display: flex; gap: .35rem; flex-shrink: 0; }
.cn-project-card-actions .cn-icon-btn { width: 1.9rem; height: 1.9rem; padding: 0; }
/* Cestino negli elenchi di romanzi e trame un po' più grande delle altre icone della card. Senza
   padding: 0 qui sopra il padding predefinito del browser sui <button> lasciava meno largo che alto
   e l'icona, stretta in larghezza, si deformava (più stretta e lunga). */
.cn-project-card-actions [data-action="elimina"] .cn-icon { width: 1.25rem; height: 1.25rem; flex-shrink: 0; }
/* Sul cellulare una card a due colonne (testo a sinistra, icone a destra) stringe troppo il
   testo: sotto i 40rem diventa una sola colonna, con le icone su una riga a sé sotto tutto il
   testo invece che schiacciate di fianco. */
@media (max-width: 40rem) {
  .cn-project-card { flex-direction: column; align-items: stretch; }
  .cn-project-card-actions { justify-content: flex-end; }
}

/* ---------- scrittura a più mani (pagina spettatore + pannello editor) ---------- */
.cn-empty-state { max-width: 30rem; margin: 3rem auto; text-align: center; }
.cn-empty-state h1 { font-size: 1.2em; margin-bottom: .6em; }
.cn-empty-state p { opacity: .75; margin-bottom: 1.25em; }
.cn-collab-badge { font-size: .8em; opacity: .65; white-space: nowrap; display: inline-flex; align-items: center; gap: .4em; }
.cn-collab-live-dot { display: inline-block; width: .5em; height: .5em; border-radius: 50%; background: #e0303f; flex-shrink: 0; }
.cn-collab-storia .cn-paragraph { cursor: default; }
.cn-collab-storia .cn-capitolo-marker { text-align: center; opacity: .6; font-size: .85em; margin: 1.5em 0 .75em; }

/* Badge di voto lato autore: piccolo bottone a sé accanto (mai al posto di) ogni bottone/campo
   reale — vedi collabVotoHtml in scrivi.js. */
.cn-collab-voto-btn {
  display: inline-flex; align-items: center; gap: .3rem;
  height: 1.9rem; padding: 0 .55rem; border-radius: 999px;
  border: 1px solid var(--cn-icon-border); background: var(--cn-icon-bg); color: inherit;
  font-size: .8em; cursor: pointer; vertical-align: middle;
}
.cn-collab-voto-btn:hover { filter: brightness(0.95); }
.cn-collab-voto-btn.is-active { box-shadow: 0 0 0 2px var(--cn-accent); }
.cn-collab-voto-btn .cn-icon { width: .9rem; height: .9rem; margin: 0; }
.cn-collab-voto-conteggio { min-width: 1em; text-align: center; }
/* .cn-actions (le alternative fra cui scegliere) è una colonna flex: senza questo wrapper riga per
   riga, il badge di voto affiancato a ciascuna opzione (collabVotoHtml) finiva come figlio
   diretto della colonna, quindi su una propria riga a piena larghezza sotto l'opzione — un'ovale
   di testo seguita da una barra lunga col conteggio, invece dei due affiancati. */
.cn-collab-opzione-riga { display: flex; align-items: stretch; gap: .5rem; }
.cn-collab-opzione-riga .cn-action-btn { flex: 1; }
.cn-collab-opzione-riga .cn-collab-voto-btn { flex-shrink: 0; align-self: center; }
.cn-collab-banner { background: var(--cn-icon-bg); border: 1px solid var(--cn-accent); border-radius: .5rem; padding: .6rem .9rem; margin-bottom: 1rem; font-size: .9em; }

/* Opzioni lato spettatore (collab.js): stesso look di .cn-action-btn, col pallino di voto fuori
   dal rettangolo dell'opzione (dentro .cn-collab-opzione-riga, condivisa con le alternative lato
   autore in scrivi.js) invece che incollato dentro il bottone — stessa impostazione visiva da
   entrambi i lati, un solo ovale "esterno" col conteggio invece di uno annidato nell'altro. */
.cn-collab-opzioni { display: flex; flex-direction: column; gap: .5rem; margin: .75rem 0; }
/* Il click di voto è sull'intera .cn-collab-opzione-riga (vedi renderPuntoDecisione in
   collab.js), non solo sul bottone di testo al suo interno: senza cursor:pointer qui il pallino
   del conteggio, essendo fuori dal bottone, sembrava non cliccabile. */
.cn-collab-opzioni .cn-collab-opzione-riga { cursor: pointer; }
.cn-collab-spett-opt { text-align: left; }
.cn-collab-opzione-riga.is-active .cn-collab-spett-opt { border-color: var(--cn-accent); box-shadow: 0 0 0 1px var(--cn-accent); }
/* Stesso ovale (icona spunta + numero, sfondo arrotondato) usato per il voto indicativo
   dell'autore (.cn-collab-voto-btn): qui non è un bottone a sé — il voto scatta cliccando
   l'intera opzione — quindi niente cursor/hover propri, solo l'aspetto. */
.cn-collab-voto-pill {
  display: inline-flex; align-items: center; gap: .3rem;
  height: 1.9rem; padding: 0 .55rem; border-radius: 999px;
  border: 1px solid var(--cn-icon-border); background: var(--cn-icon-bg); color: inherit;
  font-size: .8em; flex-shrink: 0; align-self: center;
}
.cn-collab-voto-pill .cn-icon { width: .9rem; height: .9rem; margin: 0; }
.cn-collab-opzione-riga.is-active .cn-collab-voto-pill { box-shadow: 0 0 0 2px var(--cn-accent); }

/* ---------- chat flottante della scrittura a più mani ---------- */
/* Posizione di default: affiancata a destra della colonna di testo (.cn-content, 42rem centrata
   nel viewport), non più nell'angolo in basso a destra — lì restava fuori dal campo visivo di chi
   sta scrivendo nel paragrafo, sopra al quale la si voleva invece sempre visibile senza dover
   cliccare "Chat" per accorgersi che c'era già. */
.cn-collab-chat {
  position: fixed; left: calc(50% + 22.5rem); top: 4.75rem; z-index: 40;
  width: 20rem; height: 16rem; min-width: 220px; min-height: 180px;
  max-width: calc(100vw - 1.5rem); max-height: calc(100vh - 1.5rem);
  display: flex; flex-direction: column;
  background: var(--cn-bg); border: 1px solid var(--cn-border); border-radius: .6rem;
  box-shadow: 0 4px 18px rgba(0,0,0,.18);
}
/* Senza questa riga il display:flex qui sopra vince comunque sull'attributo hidden (stessa
   regola già serve a .cn-footer-menu/.cn-header-menu): impostare el.hidden = true sul bottone di
   chiusura non nascondeva la finestra, restava visibile. */
.cn-collab-chat[hidden] { display: none; }
/* Sotto questa larghezza non c'è spazio per affiancare la chat alla colonna di testo (42rem di
   contenuto + margini) senza farla uscire dal viewport: torna nell'angolo in basso a destra,
   come overlay flottante. */
@media (max-width: 88rem) {
  .cn-collab-chat { left: auto; top: auto; right: 1.5rem; bottom: 1.5rem; }
}
/* Su schermi stretti una geometria salvata da una sessione desktop (localStorage, vedi
   apriWidgetChatCollab in app.js) potrebbe uscire dal viewport: qui si forza una posizione/misura
   sicura, ignorando lo style inline impostato dal trascinamento. */
@media (max-width: 480px) {
  .cn-collab-chat { left: auto !important; top: auto !important; right: .75rem !important; bottom: .75rem !important; width: calc(100vw - 1.5rem) !important; height: 60vh !important; }
}
.cn-collab-chat-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: .5rem .75rem; border-bottom: 1px solid var(--cn-border);
  font-weight: 600; font-size: .85em; cursor: move; user-select: none;
}
.cn-collab-chat-header .cn-icon-btn { width: 1.6rem; height: 1.6rem; }
/* Titolo "Chat" + badge online raggruppati a sinistra: lo spazio fra i due resta fisso (gap)
   invece di essere spinto dallo justify-content:space-between dell'header, che altrimenti
   distribuirebbe i tre elementi (titolo, badge, chiudi) a distanza uguale l'uno dall'altro. */
.cn-collab-chat-header-info { display: flex; align-items: center; gap: .6rem; font-weight: 400; }
.cn-collab-chat-header-info > span:first-child { font-weight: 600; }
/* Link e chiudi raggruppati stretti a destra: senza questo lo justify-content:space-between
   dell'header li spargerebbe a distanza uguale invece di tenerli accostati. */
.cn-collab-chat-header-azioni { display: flex; align-items: center; gap: .2rem; }
.cn-collab-chat-messaggi { flex: 1; overflow-y: auto; padding: .5rem .75rem; font-size: .85em; }
.cn-collab-chat-msg { margin-bottom: .4em; line-height: 1.4; }
.cn-collab-chat-nome { font-weight: 600; margin-right: .35em; }
.cn-collab-chat-avviso { margin: 0; padding: .4rem .75rem; font-size: .8em; color: var(--cn-muted, inherit); border-top: 1px solid var(--cn-border); }
.cn-collab-chat-invio { display: flex; gap: .4rem; padding: .5rem .75rem; border-top: 1px solid var(--cn-border); }
.cn-collab-chat-invio input {
  flex: 1; font-size: .85em; padding: .4rem .6rem; border-radius: .4rem;
  border: 1px solid var(--cn-border); background: transparent; color: inherit; font-family: inherit;
}
.cn-collab-chat-invio .cn-icon-btn { width: 1.9rem; height: 1.9rem; flex-shrink: 0; }
.cn-collab-chat-resize {
  position: absolute; right: 0; bottom: 0; width: 1rem; height: 1rem; cursor: nwse-resize;
  background: linear-gradient(135deg, transparent 50%, var(--cn-border) 50%);
  border-bottom-right-radius: .6rem;
}

/* ---------- galleria copertine (modale Esporta/Pubblica) ---------- */
.cn-cover-gallery { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: .75rem; }
.cn-cover-thumb { display: flex; flex-direction: column; gap: .35rem; }
.cn-cover-riga { display: flex; align-items: flex-start; gap: .4rem; }
.cn-cover-scelta { display: flex; align-items: center; gap: .35rem; font-size: .85em; cursor: pointer; }
.cn-cover-thumb img { width: 6.5rem; aspect-ratio: 2/3; object-fit: cover; border-radius: .3rem; border: 2px solid var(--cn-border); display: block; cursor: zoom-in; }
.cn-cover-delete { width: 1.6rem; height: 1.6rem; border: none; background: transparent; }

/* ---------- Homepage: due CTA verso Writer/Reader ---------- */
.cn-home-cta { display: flex; gap: 1.25rem; flex-wrap: wrap; margin: 2rem 0; }
.cn-home-cta .cn-btn { display: block; flex: 1; min-width: 14rem; padding: 1.25rem 1.5rem; text-align: left; text-decoration: none; }
.cn-home-cta-logo { display: block; width: 2.4rem; height: 2.4rem; margin-bottom: .6rem; object-fit: contain; }
/* I due pulsanti in alto hanno lo stesso trattamento di quelli duplicati più in basso, in "Due porte,
   un solo account" (.cn-home-cta-btn-solido, sotto): sfondo pieno del colore del tema, che al
   passaggio del mouse diventa trasparente. Come nell'app. Il logo (nero su trasparente, con zone
   interne bianche) resta normale di default e nel tema scuro si inverte solo al passaggio del mouse,
   quando lo sfondo pieno sparisce. */
.cn-btn.cn-home-cta-btn { background: var(--cn-btn-bg); color: var(--cn-btn-text); border-width: 2px; border-color: var(--cn-btn-bg); font-weight: 400; }
.cn-home-cta-btn:hover { background: transparent; color: inherit; }
[data-theme="dark"] .cn-home-cta-btn:hover .cn-home-cta-logo { filter: invert(1); }
/* Tema minimale: icone nere su pulsante blu pieno poco leggibili; contorno bianco NETTO di 1 px (4 drop-shadow senza sfumatura, seguono la sagoma del PNG). Niente blur: faceva un alone. */
[data-theme="minimal"] .cn-home-cta-btn .cn-home-cta-logo { filter: drop-shadow(1px 0 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 1px 0 #fff) drop-shadow(0 -1px 0 #fff); }
[data-theme="minimal"] .cn-reader-tab .cn-reader-tab-icona { filter: drop-shadow(1px 0 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 1px 0 #fff) drop-shadow(0 -1px 0 #fff); }

/* Pulsanti duplicati nella sezione "Due porte, un solo account" più in basso: stesso aspetto di
   quelli in alto (pieni di default, trasparenti al passaggio del mouse). Nel tema minimal l'icona
   resta sempre normale, mai invertita. */
.cn-btn.cn-home-cta-btn-solido { border-width: 2px; border-color: var(--cn-btn-bg); }
.cn-home-cta-btn-solido:hover { background: transparent; color: inherit; }
[data-theme="dark"] .cn-home-cta-btn-solido:hover .cn-home-cta-logo { filter: invert(1); }
.cn-rte-box { border: 1px solid var(--cn-accent); border-radius: .5rem; padding: 1rem 1.25rem; margin: 1rem 0; background: color-mix(in srgb, var(--cn-accent) 8%, transparent); }
/* Pulsante a larghezza automatica inseribile nei riquadri della homepage: <a class="cn-btn"> è di
   base un elemento inline, quindi si allarga o restringe da solo in base al testo che contiene
   (anche quando l'autore lo modifica), senza bisogno di calcolarne la larghezza via JS. */
.cn-rte-pulsante { margin: 0 .2rem; }
/* Spazio extra fra un paragrafo e l'altro, inseribile al cursore. */
.cn-rte-spazio { height: 1.4em; }
/* Immagini caricate nei riquadri della homepage: senza un limite non potrebbero mai superare lo
   schermo su schermi stretti. La manopola di ridimensionamento (sotto) può comunque ingrandirle
   fino a quel limite, mai oltre. */
.cn-hp-blocco-testo img, .cn-hp-colonna img, .cn-rte-box img { max-width: 100%; height: auto; }
/* Icone PNG (faro/orme/strada/penna/altoparlante/nuvola/download/cuore) davanti ai titoli in
   grassetto dei riquadri della homepage. cn-icon resta per eventuali icone SVG residue. */
.cn-hp-blocco-testo strong .cn-icon, .cn-hp-blocco-testo b .cn-icon,
.cn-hp-blocco-testo strong .cn-icon-img, .cn-hp-blocco-testo b .cn-icon-img,
.cn-hp-blocco-testo h2 .cn-icon, .cn-hp-blocco-testo h2 .cn-icon-img {
  width: 1.65em; height: 1.65em; vertical-align: -.35em; margin-right: .4rem; object-fit: contain; display: inline-block;
}
/* Alcune sagome (es. il cuore di "Come supportare il progetto") riempiono quasi tutto il loro
   riquadro, quindi a parità di larghezza dichiarata sembrano più grandi delle altre icone: vanno
   rimpicciolite apposta con questo modificatore. */
.cn-hp-blocco-testo strong .cn-icon.cn-icon-piccola, .cn-hp-blocco-testo b .cn-icon.cn-icon-piccola,
.cn-hp-blocco-testo strong .cn-icon-img.cn-icon-piccola, .cn-hp-blocco-testo b .cn-icon-img.cn-icon-piccola,
.cn-hp-blocco-testo h2 .cn-icon.cn-icon-piccola, .cn-hp-blocco-testo h2 .cn-icon-img.cn-icon-piccola {
  width: 1.25em; height: 1.25em;
}
/* Tutte le icone PNG della homepage sono sagome nere su sfondo trasparente: nel tema scuro,
   sullo sfondo quasi nero della pagina, sparirebbero senza invertirle in bianco. */
[data-theme="dark"] .cn-hp-blocco-testo .cn-icon-img { filter: invert(1); }
/* Più spazio fra il titoletto in grassetto (es. "Installazione locale — completamente gratis") e
   il paragrafo sotto: il <br> che li separa nell'HTML salvato normalmente dà solo l'interlinea
   di una riga vuota, poco distinguibile dal resto. display:block + margin-top su un <br> è una
   tecnica CSS valida e supportata per allargare apposta quel singolo a-capo. */
.cn-hp-blocco-testo strong + br, .cn-hp-colonna strong + br,
.cn-hp-blocco-testo b + br, .cn-hp-colonna b + br,
#hp-intro strong + br, #hp-intro b + br {
  display: block; content: ""; margin-top: 1.15rem;
}
/* Più respiro fra i punti di un elenco puntato dentro i riquadri della homepage (es. i due punti
   in "Versione cloud — cosa aggiunge"): di base sono attaccati uno all'altro. */
.cn-hp-blocco-testo li, .cn-hp-colonna li { margin-bottom: .6rem; }
.cn-hp-blocco-testo li:last-child, .cn-hp-colonna li:last-child { margin-bottom: 0; }
/* Il pulsante "Crea un account" (in alto sotto i riquadri Writer/Reader, e in fondo alla pagina)
   è un link: senza questa regola avrebbe la sottolineatura di default di un <a>. */
a[data-azione="apri-registrazione"] { text-decoration: none; }
a[data-azione="apri-registrazione"]:hover { background: transparent; color: inherit; border-width: 2px; margin: -1px; }
/* Icone social per condividere la homepage (Facebook, X, WhatsApp, LinkedIn): stesso trattamento
   in bianco e nero dei loghi PNG usati altrove nella homepage, con leggero effetto hover. */
.cn-hp-social-riga { display: flex; gap: .85rem; margin: .75rem 0; align-items: center; }
.cn-hp-social-link { display: inline-flex; line-height: 0; opacity: .8; }
.cn-hp-social-link:hover { opacity: 1; }
.cn-hp-social-link .cn-icon-img { width: 1.7em; height: 1.7em; object-fit: contain; }

/* ---------- blocchi extra homepage: riquadri a colonna intera o a due colonne ---------- */
.cn-hp-blocco-full, .cn-hp-blocco-due-colonne { position: relative; margin: .5rem 0; }
.cn-hp-blocco-due-colonne { display: flex; gap: 1rem; }
/* .cn-hp-colonna stessa si allarga già alla pari (flex:1 dentro un flex-parent stretch di
   default), ma il pulsante VISIBILE al suo interno (il bordo/sfondo che si vede) è display:block
   e resta alto quanto il proprio contenuto: con descrizioni Writer/Reader di lunghezza diversa
   (righe diverse) restava visibilmente più basso uno dei due nonostante il contenitore invisibile
   fosse già alla pari. display:flex sul contenitore + flex:1 sul pulsante lo fa combaciare. */
.cn-hp-blocco-due-colonne > .cn-hp-colonna { flex: 1; min-width: 0; display: flex; }
.cn-hp-colonna > .cn-home-cta-btn-solido { flex: 1; }

/* ---------- Reader: filtri, griglia libri, pagina di dettaglio/lettura ---------- */
.cn-reader-filtri { margin-bottom: 1rem; font-size: .8em; }
/* Pannello di Reader più piccolo (2026-09-30): campi e pulsante più bassi del resto del sito. */
.cn-reader-filtri .cn-field { margin-bottom: .5rem; }
.cn-reader-filtri label { margin-bottom: .15rem; }
.cn-reader-filtri input, .cn-reader-filtri select { padding: .3rem .5rem; font-size: 1em; }
.cn-reader-filtri .cn-btn { padding: .3rem .8rem; font-size: 1em; }
/* Andando a capo (pagina stretta) la riga sotto sta alla stessa distanza che c'è fra Cerca e Ordina per: solo il margine dei campi. */
.cn-reader-filtri .cn-reader-filtri-riga { row-gap: 0; }
.cn-reader-filtri-riga { display: flex; gap: 1rem; flex-wrap: wrap; }
.cn-reader-filtri-riga .cn-field { flex: 1; min-width: 9rem; }

.cn-book-grid { display: flex; flex-wrap: wrap; gap: 1.25rem; }
.cn-book-card { width: 10rem; cursor: pointer; }
.cn-book-card:hover .cn-book-titolo { color: var(--cn-accent); }
.cn-book-cover img, .cn-book-cover-vuota {
  width: 100%; aspect-ratio: 2/3; object-fit: cover; border-radius: .4rem;
  border: 1px solid var(--cn-border); display: block; background: var(--cn-icon-bg);
}
/* Pulsante "ritira pubblicazione" sulla propria pagina autore (vedi renderLibri in autore.js):
   nascosto finché non si passa sopra la copertina, come i pulsanti di eliminazione già usati
   altrove sulle card libro. */
.cn-book-card-azione {
  display: none; position: absolute; top: .3rem; right: .3rem; width: 1.7rem; height: 1.7rem;
  background: var(--cn-bg); z-index: 2;
}
.cn-book-cover:hover .cn-book-card-azione { display: flex; }
.cn-book-titolo { font-weight: 600; margin-top: .5rem; font-size: .92em; }
.cn-book-autore { font-size: .8em; opacity: .65; }
/* Badge "traduzione automatica disponibile" in Vetrina (vedi bookCardHtml in reader/index.js): una
   piccola icona tonda accanto al numero di paragrafi — l'immagine della copertina resta libera
   da sovrapposizioni. Ripetuto anche nella legenda in cima alla Vetrina. */
/* Icona "traduzione automatica disponibile": solo il simbolo, senza tondino né sfondo (prova del 2026-09-30). */
.cn-book-badge-traduzione { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.cn-book-badge-traduzione .cn-icon { width: 1rem; height: 1rem; }
/* Legenda in cima alla Vetrina: cosa indicano i due simboli delle card. */
.cn-reader-legenda {
  display: flex; flex-wrap: wrap; gap: .4rem 1.5rem; margin-bottom: 1.25rem;
  font-size: .8em; opacity: .8;
}
.cn-reader-legenda-voce { display: inline-flex; align-items: center; gap: .4rem; }
.cn-reader-legenda .cn-icon { width: 1em; height: 1em; }
.cn-book-valutazione { display: flex; align-items: center; gap: .3rem; margin-top: .3rem; }
.cn-book-valutazione .cn-stelle .cn-icon { width: .85rem; height: .85rem; }
.cn-book-meta { display: flex; justify-content: space-between; align-items: center; font-size: .8em; margin-top: .3rem; opacity: .8; }
.cn-book-meta .cn-icon { width: 1em; height: 1em; }
/* align-items:center su .cn-book-meta centra lo <span> del numero di paragrafi rispetto al prezzo,
   ma non l'icona rispetto al numero DENTRO quello span: senza questa regola icona e testo restano
   allineati sulla baseline di default, leggermente sfalsati invece che centrati fra loro. */
.cn-book-paragrafi { display: inline-flex; align-items: center; gap: .3rem; }
.cn-book-meta-sx { display: inline-flex; align-items: center; gap: .5rem; }
.cn-book-prezzo { font-weight: 600; }
/* Titoli di sezione in "La mia libreria": romanzi acquistati/gratuiti, poi i file caricati dall'utente. */
.cn-libreria-sezione { font-size: 1em; margin: 1.5rem 0 .75rem; opacity: .85; }

/* ---------- Reader: schede in alto (La mia libreria / Vetrina / Pubblicati / Archivio) ----------
   Dal 2026-10-09 (decisione dell'autore) quadrati come i pulsanti della homepage di chi ha fatto l'accesso (.cn-home-cta-btn): sfondo
   pieno del tema, icona sopra e nome sotto, tutti larghi uguali sulla stessa riga; la scheda aperta resta piena come le altre. */
.cn-reader-tab-nav { display: flex; gap: .75rem; flex-wrap: wrap; justify-content: center; margin-bottom: 1.5rem; }
.cn-reader-tab {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .5rem;
  padding: 1rem .6rem; border-radius: .5rem; border: 2px solid var(--cn-btn-bg); background: var(--cn-btn-bg);
  color: var(--cn-btn-text); font: inherit; font-weight: 700; text-align: center; cursor: pointer;
}
.cn-reader-tab > span { max-width: 100%; overflow-wrap: anywhere; hyphens: auto; line-height: 1.25; }
.cn-reader-tab:hover { background: transparent; color: inherit; }
/* Scheda aperta: piena come le altre, senza bordi in più (2026-10-09, decisione dell'autore). */
.cn-reader-tab.is-active, .cn-reader-tab.is-active:hover { background: var(--cn-btn-bg); color: var(--cn-btn-text); }
.cn-reader-tab-icona { width: 2.4rem; height: 2.4rem; object-fit: contain; }
.cn-reader-tab-icona-grande { width: 2.4rem; height: 2.4rem; }
.cn-reader-tab-icona-traduci { width: 1.65em; height: 1.65em; }
/* Riga sopra le schede di Reader (2026-10-04): "Cerca" a sinistra, pulsantini tondi del filtro per categoria a destra (stessi di
   "I tuoi scritti", .cn-filtro-tipo). Il nome toccato sul telefono compare a sinistra dei pulsantini, non dopo l'ultimo. */
.cn-reader-barra { display: flex; justify-content: space-between; align-items: center; gap: .6rem; margin: 0 0 1rem; }
.cn-reader-cerca-apri { font-size: .8em; padding: .3rem .8rem; }
.cn-reader-cerca-apri.is-attivo { border-color: var(--cn-accent); }
.cn-filtro-tipi-destra { justify-content: flex-end; }
.cn-reader-filtri[hidden] { display: none; }
/* Icone delle voci di visualizzazione (filtro e titoli delle sezioni), come quelle delle schede. */
.cn-reader-tipo-icona { width: 1.4em; height: 1.4em; object-fit: contain; vertical-align: middle; margin-right: .35em; }
[data-theme="dark"] .cn-reader-tipo-icona { filter: invert(1); }
.cn-libreria-sezione .cn-reader-tipo-icona.is-penna { margin-right: .15em; }
/* Come il logo dei pulsanti della homepage: normale sullo sfondo pieno, invertito nel tema scuro solo quando il pulsante è trasparente. */
[data-theme="dark"] .cn-reader-tab:not(.is-active):hover .cn-reader-tab-icona { filter: invert(1); }

/* ---------- La mia libreria: upload locale + copertina rimovibile sul riquadro ---------- */
.cn-libreria-azioni { display: flex; flex-direction: column; align-items: flex-start; gap: .5rem; margin-bottom: 1.5rem; }
/* Il vertical-align basato sulla baseline del testo (usato per le altre .cn-icon) non è
   affidabile qui perché #lib-carica-icona è un <span> vuoto riempito via JS con icon('carica'),
   quindi un secondo livello di <span class="cn-icon"> annidato attorno all'svg: qualunque
   offset in px va storto appena cambiano font-size/line-height del tema. Si centra invece
   #lib-carica-btn stesso con flexbox, che allinea icona e testo in base alla loro altezza reale
   invece che alla baseline sintetizzata. */
#lib-carica-btn { display: inline-flex; align-items: center; }
.cn-libreria-azioni .cn-icon { width: 1rem; height: 1rem; margin-right: .35rem; }
.cn-book-cover { position: relative; }
.cn-libreria-elimina {
  display: none; position: absolute; top: .3rem; right: .3rem; width: 1.7rem; height: 1.7rem;
  background: var(--cn-bg); z-index: 2;
}
.cn-libreria-modifica {
  display: none; position: absolute; top: .3rem; left: .3rem; width: 1.7rem; height: 1.7rem;
  background: var(--cn-bg); z-index: 2;
}
.cn-libreria-traduci {
  display: none; position: absolute; bottom: .3rem; left: .3rem; width: 1.7rem; height: 1.7rem;
  background: var(--cn-bg); z-index: 2;
}
.cn-book-cover:hover .cn-libreria-elimina, .cn-book-cover:hover .cn-libreria-modifica, .cn-book-cover:hover .cn-libreria-traduci { display: flex; }
/* Su touch (nessun hover) i pulsanti sulla copertina sarebbero irraggiungibili: sempre visibili. */
@media (hover: none) {
  .cn-libreria-elimina, .cn-libreria-modifica, .cn-libreria-traduci { display: flex; }
}
.cn-libreria-copertina-anteprima { width: 9rem; margin: 0 auto 1rem; }
.cn-libreria-copertina-anteprima img, .cn-libreria-copertina-anteprima .cn-book-cover-vuota {
  width: 100%; aspect-ratio: 2/3; object-fit: cover; border-radius: .4rem; border: 1px solid var(--cn-border);
  display: block; background: var(--cn-icon-bg);
}

.cn-libro-intestazione { display: flex; gap: 1.5rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.cn-libro-copertina { width: 11rem; aspect-ratio: 2/3; object-fit: cover; border-radius: .5rem; border: 1px solid var(--cn-border); flex-shrink: 0; }
.cn-libro-info { flex: 1; min-width: 14rem; }
.cn-libro-prezzo { font-weight: 700; font-size: 1.1em; margin: .5rem 0; }
.cn-libro-autore { font-size: 1.05em; margin: 0 0 .5rem; }
.cn-libro-azioni { display: flex; gap: .5rem; flex-wrap: wrap; }
.cn-libro-sinossi { font-style: italic; opacity: .85; margin: 1.5rem 0; padding: 1rem; border-left: 3px solid var(--cn-border); }
.cn-libro-testo { margin-top: 2rem; }
.cn-libro-testo .cn-paragraph { margin-bottom: 1.1em; }

/* ---------- Recensioni (stelline + testo, scheda del romanzo) ---------- */
.cn-recensioni { margin-top: 2.5rem; border-top: 1px solid var(--cn-border); padding-top: 1.5rem; }
.cn-recensioni-intestazione { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-bottom: 1rem; }
.cn-recensioni-media { font-weight: 700; }
/* Stessa icona 'star' di icons.js ovunque (media, singola recensione, selettore del form): PNG,
   non più SVG, quindi il riempimento non può più essere un fill via currentColor — icon() per
   'star' scrive due <img> sovrapposte (vuota/piena, vedi icons.js), qui si mostra solo quella
   giusta in base alla classe .is-piena sul contenitore .cn-icon. */
.cn-icon-piena { position: absolute; inset: 0; opacity: 0; }
.cn-icon.is-piena .cn-icon-vuota { opacity: 0; }
.cn-icon.is-piena .cn-icon-piena { opacity: 1; }
.cn-recensioni-intestazione .cn-icon { color: var(--cn-accent); width: 1.2rem; height: 1.2rem; }
.cn-stelle { display: inline-flex; gap: .1rem; color: var(--cn-accent); }
.cn-stelle .cn-icon { width: 1.05rem; height: 1.05rem; }
/* Selettore interattivo nel form: stelle più grandi e cliccabili, con hover che anticipa il voto
   fino alla stella sorvolata (vedi wireStelleInput in reader/libro.js). */
.cn-stelle-input { display: inline-flex; gap: .15rem; }
.cn-stelle-input button { background: none; border: none; padding: .15rem; margin: 0; cursor: pointer; color: var(--cn-accent); line-height: 0; }
.cn-stelle-input .cn-icon { width: 1.6rem; height: 1.6rem; }
.cn-recensione-form { margin-bottom: 1.5rem; padding: 1rem; border: 1px solid var(--cn-border); border-radius: .5rem; }
.cn-recensione-form textarea {
  width: 100%; min-height: 5rem; margin: .7rem 0; padding: .55rem; border-radius: .4rem;
  border: 1px solid var(--cn-border); background: transparent; color: inherit; font: inherit; resize: vertical;
}
.cn-recensione-card { padding: 1rem 0; border-top: 1px solid var(--cn-border); }
.cn-recensione-card:first-child { border-top: none; padding-top: 0; }
.cn-recensione-autore { display: flex; align-items: center; gap: .5rem; margin-bottom: .3rem; }
.cn-recensione-avatar { width: 1.8rem; height: 1.8rem; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.cn-recensione-avatar-vuoto { width: 1.8rem; height: 1.8rem; border-radius: 50%; background: var(--cn-icon-bg); flex-shrink: 0; }
.cn-recensione-testo { margin: .4rem 0 0; white-space: pre-wrap; }

/* ---------- Lettore (reader/leggi.html): titolo/autore in barra + colonna ridimensionabile ---------- */
.cn-leggi-titolo { display: flex; flex-direction: column; gap: 0; line-height: 1.2; }
.cn-leggi-titolo .cn-title { font-size: .95em; }
.cn-leggi-titolo .cn-punto-meta { margin: 0; }

/* Larghezza della colonna di lettura, separata da --cn-paragraph-width di Writer: qui non c'è un
   drawer laterale di cui tener conto, il massimo è solo la larghezza della finestra. */
.cn-leggi-viewport { position: relative; max-width: var(--cn-reader-width, 42rem); }
/* Testo non selezionabile/copiabile SOLO per le copie tradotte automaticamente dalla funzione
   Traduci lato Reader (vedi 'tradotto' in reader/api/libro.php): a tutela del testo dell'autore
   per una traduzione non rivista da nessuno, non una vera protezione anti-copia (chi vuole
   aggirarla può comunque farlo dagli strumenti sviluppatore). Classe generica (non legata a
   .cn-leggi-viewport): leggi.js la mette sull'intero viewport in vista "Tradotto"
   (impostaVistaTesto) o sulla sola colonna destra in "Affiancati" (vedi .cn-leggi-affiancati-
   colonna sotto e il markup in leggi.html) — mai sui romanzi ORIGINALI (anche un'edizione in
   un'altra lingua pubblicata deliberatamente dall'autore, non una copia personale di un lettore),
   che restano selezionabili apposta per la traduzione automatica nativa del dispositivo. Non si
   applica comunque a "La mia libreria" (leggi-locale.js/.cn-leggi-locale-area), file propri
   dell'utente caricati da un file che possiede già. */
.is-traduzione-ia { user-select: none; -webkit-user-select: none; }
.is-traduzione-ia input, .is-traduzione-ia textarea { user-select: text; -webkit-user-select: text; }

/* Vista "Affiancati" (vedi impostaVistaTesto/renderAffiancati in leggi.js): due colonne, una sopra
   l'altra ("metà schermo" ciascuna, non fianco a fianco — più leggibile su schermi stretti), ognuna
   con scorrimento proprio sincronizzato per paragrafo con l'altra. L'altezza è impostata inline da
   JS (stessa .altezzaPaginaPx() già usata da scatti, per tenere conto della barra in alto),
   non fissabile qui in CSS perché dipende dall'altezza reale della finestra e della barra. */
.cn-leggi-affiancati { display: flex; flex-direction: column; }
.cn-leggi-affiancati-colonna {
  flex: 1 1 0; min-height: 0; overflow-y: auto; background: var(--cn-bg);
  padding: 1.25rem 1.5rem; line-height: 1.7; max-width: var(--cn-reader-width, 42rem);
  margin: 0 auto; width: 100%; box-sizing: border-box;
}
@media (max-width: 40rem) { .cn-leggi-affiancati-colonna { padding: 1rem; } }
/* Separatore fra le due colonne: una linea tratteggiata, stesso stile del bordo che compare
   intorno a un paragrafo mentre lo si modifica in Writer (vedi .cn-turn[contenteditable]:focus),
   non più uno sfondo colorato — con un po' di margine sopra e sotto invece di stare incollata a
   entrambi i testi. flex: 0 0 auto perché è l'unico elemento di altezza fissa tra le due colonne
   che si dividono il resto dello spazio (flex: 1 1 0 sopra). */
.cn-leggi-affiancati-separatore { flex: 0 0 auto; margin: .75rem 0; border-top: 2px dashed var(--cn-accent); }
/* Separatore fra capitoli di un epub caricato in "La mia libreria" (vedi leggi-locale.js): niente
   titoli di capitolo propri (l'OPF non li fornisce in modo affidabile, vedi libreria.js), solo un
   confine visibile fra un capitolo e il successivo. */
.cn-leggi-locale-capitolo { margin-bottom: 2rem; padding-bottom: 2rem; border-bottom: 1px solid var(--cn-border); }
.cn-leggi-locale-capitolo:last-child { border-bottom: none; }
.cn-leggi-locale-capitolo img { max-width: 100%; height: auto; display: block; margin: 1rem auto; }
/* Titoli dentro un epub/txt della libreria: senza regole prendevano il default del browser (h1 = 2em); ora grandi come i capitoli del romanzo (.cn-capitolo-titolo). */
.cn-leggi-locale-capitolo :is(h1, h2) { text-align: center; font-weight: 700; font-size: 1.3em; margin: 2.5rem 0 1.25rem; }
.cn-leggi-locale-capitolo :is(h3, h4, h5, h6) { font-weight: 700; font-size: 1.1em; margin: 1.5rem 0 .75rem; }

/* ---------- "La mia libreria": lettura, modalità continuo/scatti (leggi-locale.js) ---------- */
/* Stesso contenitore per entrambe le modalità (niente contenuto duplicato): in "continuo" è un
   normale flusso verticale (la pagina scorre col resto del sito); in "scatti" diventa colonne CSS
   larghe quanto il riquadro (column-width impostato inline da JS in ricalcolaPagine()) spostate con
   translateX SENZA transizione — un vero cambio pagina animato (rotazione 3D, scorrimento
   laterale...) è stato provato e scartato: a schermo risultava innaturale, un salto netto "a
   scatti" (da cui il nome) è più onesto di un'animazione che non convince. */
.cn-leggi-locale-area {
  max-width: 42rem;
  margin: 0 auto;
  padding: 1.5rem 1.5rem 4rem;
}
.cn-leggi-locale-area.is-scatti {
  height: calc(100vh - 4.5rem);
  min-height: 20rem;
  overflow: hidden;
  cursor: pointer;
}
.cn-leggi-locale-corpo { line-height: 1.7; }
.cn-leggi-locale-area.is-scatti .cn-leggi-locale-corpo { height: 100%; column-fill: auto; }
@media (max-width: 40rem) {
  .cn-leggi-locale-area { padding: 1.25rem 1rem 3rem; }
}

/* Segnalibro: un simbolo ancorato al paragrafo dove è stato messo — figlio del blocco stesso
   (aggiornaSimboloSegnalibro in leggi.js, con più segnalibri per romanzo; in leggi-locale.js, con
   uno solo per libro), quindi scorre insieme al testo invece di restare fermo sullo schermo. Sta
   appeso al bordo destro del paragrafo; il blocco che lo ospita riceve .cn-segnalibro-ospite
   (position:relative) solo finché il segnalibro c'è. Condiviso da entrambe le pagine. */
.cn-segnalibro-ospite { position: relative; }
.cn-segnalibro-ancorato {
  position: absolute;
  top: -.1rem;
  right: -.5rem;
  z-index: 2;
  width: 1.4rem;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .3));
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}
.cn-segnalibro-ancorato .cn-icon img { width: 100%; height: auto; display: block; }
#btn-segnalibro.is-active { opacity: 1; background: var(--cn-icon-bg); }
.cn-leggi-resize-handle {
  display: none; position: absolute; top: 0; bottom: 0; width: 14px; cursor: ew-resize; z-index: 6;
}
.cn-leggi-resize-handle.left { left: -14px; border-right: 2px dashed var(--cn-accent); }
.cn-leggi-resize-handle.right { right: -14px; border-left: 2px dashed var(--cn-accent); }
.cn-leggi-viewport.is-resizable .cn-leggi-resize-handle { display: block; }

/* Riga non ultima di un turno spezzato per l'impaginazione (vedi blocchiPerImpaginazione in
   leggi.js): niente spazio sotto, resta "attaccata" alla riga successiva come nel modo continuo,
   invece di sembrare un paragrafo vuoto. */
.cn-paragraph.cn-paragraph-stretto { margin-bottom: 0; }

/* ---------- modo "a scatti": una facciata alla volta ---------- */
.cn-leggi-libro { position: relative; overflow: hidden; min-height: 60vh; }
.cn-leggi-pagina-statica { position: relative; z-index: 1; }

/* Il paragrafo (colonna di lettura, --cn-reader-width) diviso in 3 colonne virtuali: il terzo di
   sinistra e quello di destra, ALLARGATI fino a inglobare anche il margine esterno fino al bordo
   dello SCHERMO, cambiano pagina; il terzo centrale (mai coperto da queste zone: ci passa sotto il
   click normale del lettore) fa comparire/nascondere la barra in alto, gestito da initBarraLettore
   sul #viewport stesso. Un tocco/click su una zona cambia pagina. Distanza dal bordo
   SCHERMO al confine interno della zona: metà schermo meno UN SESTO della colonna (= margine
   esterno intero + il primo/ultimo terzo della colonna). Sugli schermi dove la colonna riempie
   tutta la larghezza (mobile, margine 0) la formula degrada da sola a "un terzo dello schermo",
   niente pavimento minimo dedicato da mantenere a parte. Attive solo in scatti — in continuo
   restano inerti (pointer-events:none), e temporaneamente inerti anche quando le maniglie di
   ridimensionamento sono attive (vedi cn-reader-resize-mode più sotto), per non coprirle. */
.cn-leggi-zona-nav {
  position: fixed; top: 0; bottom: 0; z-index: 8; cursor: pointer; pointer-events: none;
  width: max(2rem, calc(50vw - (var(--cn-reader-width, 42rem) / 6)));
}
.cn-leggi-zona-nav.sinistra { left: 0; }
.cn-leggi-zona-nav.destra { right: 0; }
body.cn-zone-nav-attive .cn-leggi-zona-nav { pointer-events: auto; }
body.cn-reader-resize-mode .cn-leggi-zona-nav { pointer-events: none; }

/* Numero di pagina sempre nello stesso punto dello SCHERMO, non del documento: di base
   .cn-page-indicator scorre in fondo al contenuto (giusto per Writer, dove segna la fine del
   flusso), qui invece va ancorato al viewport perché resti fermo cambiando facciata o modo. */
.cn-leggi-indicatore-fisso {
  position: fixed; left: 50%; bottom: .75rem; transform: translateX(-50%);
  padding-bottom: 0; z-index: 6; pointer-events: none;
}

/* ---------- indice del Lettore: capitoli / segnalibri / ricerca (riusa .cn-drawer di Writer) ---------- */
.cn-indice-voce {
  display: block; width: 100%; text-align: left; background: none; border: none; font: inherit;
  color: inherit; padding: .5rem .3rem; border-radius: .3rem; cursor: pointer; font-size: .9em;
}
.cn-indice-voce:hover { background: var(--cn-icon-bg); }
.cn-indice-anteprima { opacity: .6; font-style: italic; }
.cn-indice-riga { display: flex; align-items: center; gap: .3rem; }
.cn-indice-riga .cn-indice-voce { flex: 1; }
.cn-indice-elimina { width: 1.8rem; height: 1.8rem; flex-shrink: 0; }
.cn-indice-elimina .cn-icon { width: .8rem; height: .8rem; }
.cn-indice-voce-cerca mark { background: color-mix(in srgb, var(--cn-accent) 35%, transparent); color: inherit; border-radius: .15rem; }
.cn-cerca-panel { font-size: .9em; }
#cerca-input {
  width: 100%; padding: .55rem; border-radius: .4rem; border: 1px solid var(--cn-border);
  background: transparent; color: inherit; font: inherit;
}

/* ---------- copertina ingrandibile (reader/libro.js) ---------- */
.cn-libro-copertina { cursor: zoom-in; }
.cn-lightbox-backdrop {
  position: fixed; inset: 0; background: rgba(0, 0, 0, .85); z-index: 60;
  display: flex; align-items: center; justify-content: center; cursor: zoom-out; padding: 2rem;
}
.cn-lightbox-backdrop:has(.cn-lightbox-scarica) { padding-bottom: 4.5rem; }
.cn-lightbox-scarica { position: absolute; bottom: 1rem; left: 50%; transform: translateX(-50%); cursor: pointer; text-decoration: none; }
.cn-lightbox-backdrop img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: .4rem; box-shadow: 0 8px 40px rgba(0, 0, 0, .5); }

.cn-autore-intestazione { display: flex; align-items: center; gap: 1.25rem; margin-bottom: 1.5rem; }
.cn-autore-avatar-wrap { position: relative; width: 5rem; height: 5rem; flex-shrink: 0; }
.cn-autore-avatar, .cn-autore-avatar-vuoto {
  width: 5rem; height: 5rem; border-radius: 50%; object-fit: cover;
  border: 1px solid var(--cn-border); background: var(--cn-icon-bg); display: block;
}
.cn-autore-avatar-modifica { position: absolute; right: -.3rem; bottom: -.3rem; width: 1.8rem; height: 1.8rem; }
.cn-autore-bio textarea {
  width: 100%; padding: .55rem; border-radius: .4rem; border: 1px solid var(--cn-border);
  background: transparent; color: inherit; font: inherit; font-size: 1em; resize: vertical; min-height: 4rem;
}
.cn-autore-bio-testo { white-space: pre-wrap; opacity: .85; }

.cn-footer { display: flex; align-items: center; justify-content: center; text-align: center; padding: 2rem 1.5rem 3rem; font-size: .8em; }
.cn-footer-inline { position: relative; display: inline-flex; }
.cn-footer-trigger {
  display: inline-flex; align-items: center; gap: .4rem; background: none; border: none; cursor: pointer;
  color: var(--cn-accent); font: inherit; font-size: 1em; padding: .3rem .5rem; opacity: .85;
}
.cn-footer-trigger:hover, .cn-footer-trigger[aria-expanded="true"] { opacity: 1; }
.cn-footer-favicon {
  width: 1.5em; height: 1.5em; display: inline-block; flex-shrink: 0;
  background-color: var(--cn-accent);
  -webkit-mask-image: url('logoCiaoNovel.png'); mask-image: url('logoCiaoNovel.png');
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
}
.cn-footer-menu {
  position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); margin-bottom: .3rem;
  background: var(--cn-bg); color: var(--cn-text); border: 1px solid var(--cn-border); border-radius: .5rem;
  padding: .4rem 0; display: flex; flex-direction: column; min-width: 12rem; box-shadow: 0 4px 16px rgba(0,0,0,.18); z-index: 30;
}
.cn-footer-menu[hidden] { display: none; }
.cn-footer-menu a { padding: .5rem 1rem; color: inherit; text-decoration: none; white-space: nowrap; text-align: left; }
.cn-footer-menu a:hover { background: var(--cn-border); text-decoration: underline; }

.cn-header-menu-wrap { display: inline-flex; position: relative; }
.cn-header-menu {
  /* Ancorato a .cn-header-menu-wrap (il solo pulsante "+"), non a .cn-page-header-actions: parte
     da sotto il "+" che lo apre. Con right:0 sul contenitore intero era allineato al bordo destro
     del pulsante "Nuovo romanzo", che sul cellulare può stare molto più a destra del "+" — la
     larghezza minima del riquadro lo spingeva così fuori dallo schermo a sinistra. */
  position: absolute; top: 100%; left: 0; margin-top: .3rem;
  background: var(--cn-bg); color: var(--cn-text); border: 1px solid var(--cn-border); border-radius: .5rem;
  padding: .4rem 0; display: flex; flex-direction: column; min-width: 12rem; box-shadow: 0 4px 16px rgba(0,0,0,.18); z-index: 30;
}
.cn-header-menu[hidden] { display: none; }
.cn-header-menu button { background: none; border: none; font: inherit; font-size: 1em; padding: .5rem 1rem; color: inherit; text-align: left; cursor: pointer; white-space: nowrap; }
.cn-header-menu button:hover { background: var(--cn-border); }

/* ---------- onboarding conversazionale (nuovo romanzo) ---------- */
.cn-question { display: flex; align-items: flex-start; gap: .6rem; margin-bottom: 1rem; }
.cn-question p { margin: 0; flex: 1; }
.cn-question .cn-icon-btn { flex-shrink: 0; width: 1.9rem; height: 1.9rem; }
.cn-onboarding-answer { margin-bottom: 2rem; }
/* Pulsanti rapidi ("Lo decido più avanti", "Proponilo tu"…) sopra il campo: lo spazio abituale tra un pulsante e un campo (2026-10-01). */
.cn-onboarding-answer > .cn-actions { margin-bottom: .8rem; }
/* renderStileScelta (scrivi.js/demo.js): unico punto dove un <label> nudo compare come prima riga
   di .cn-onboarding-answer invece del solito .cn-question — senza questa regola il browser non gli
   dà nessun margine e il testo tocca la textarea sotto. */
.cn-onboarding-answer > label { display: block; margin-bottom: .5rem; }
/* Campo di una riga (titolo, nome dell'autore...) con "Invia" accanto, alto quanto il campo e con lo sfondo dei pulsanti di
   risposta sopra (.cn-action-btn); "Indietro" resta sotto, a sinistra (2026-10-02). */
.cn-campo-invia { display: flex; align-items: stretch; gap: .5rem; margin-bottom: .8rem; }
.cn-campo-invia > .cn-field { flex: 1; min-width: 0; margin-bottom: 0; }
.cn-campo-invia > .cn-field input { height: 100%; box-sizing: border-box; }
.cn-btn.cn-btn-invia-campo {
  flex-shrink: 0; background: var(--cn-icon-bg); border: 1px solid var(--cn-border); color: inherit; font-weight: 400;
}
.cn-btn.cn-btn-invia-campo:hover { filter: none; border-color: var(--cn-accent); }
.cn-campo-invia + .cn-indietro-sotto { margin-top: 0; }

/* ---------- cerchietti annulla/ripeti (sinistra) e B/I (destra) sui campi di prosa (bozza IA,
   "continua tu la storia", paragrafi già scritti in vista conversazione quando cliccati per la
   modifica — vedi onParagraphClickedPerModifica) ---------- */
.cn-format-wrap { position: relative; }
.cn-format-wrap textarea { width: 100%; }
.cn-format-wrap .cn-paragraph.is-draft[contenteditable="true"],
.cn-format-wrap .cn-turn[contenteditable="true"] { padding-bottom: 2.2rem; }
/* Riga unica con i due gruppi agli estremi opposti (annulla/ripeti a sinistra, B/I a destra), in
   sovrimpressione in basso al riquadro di default. */
.cn-format-row {
  position: absolute; left: .4rem; right: .4rem; bottom: .4rem;
  display: flex; justify-content: space-between; gap: .3rem; z-index: 4;
}
.cn-undo-redo-btns, .cn-format-btns { display: flex; gap: .3rem; }
/* Nelle <textarea> di testo che finisce nel romanzo così com'è ("O continua tu la storia", incipit scritto dall'autore) la riga
   sta DENTRO il riquadro, in basso, come nella bozza tratteggiata (2026-09-27). Lo spazio in fondo le evita di coprire il testo;
   l'angolo nativo di ridimensionamento finirebbe sotto B/I, quindi niente resize: il campo cresce da solo con il testo
   (adattaAltezzaTextarea in scrivi.js). */
/* display:block: una textarea è inline-block di default e lascia sotto di sé lo spazio della riga di testo (qualche pixel): il
   contenitore risultava più alto del campo e la riga, misurata dal fondo del contenitore, finiva sopra il bordo. */
.cn-format-wrap textarea { display: block; margin: 0; padding-bottom: 2.4rem; resize: none; overflow-y: hidden; }
/* Carattere e grandezza del tema anche fuori da un .cn-field (riquadro dell'idea, "O continua tu la storia", incipit scritto
   dall'autore): senza, la textarea prendeva il carattere piccolo del browser (2026-10-02). :where = nessuna precedenza in più, le
   regole più precise (titolo del diario, richiesta piccola) restano valide. */
:where(.cn-format-wrap) textarea { font: inherit; font-size: 1em; line-height: inherit; color: inherit; }
.cn-format-btn {
  width: 1.5rem; height: 1.5rem; border-radius: 50%; border: 1px solid var(--cn-icon-border);
  /* --cn-icon-bg è semitrasparente: sopra lo sfondo della pagina diventa opaco, così il testo che scorre sotto non si vede (2026-10-02). */
  background: linear-gradient(var(--cn-icon-bg), var(--cn-icon-bg)), var(--cn-bg); color: inherit; font-size: .68rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center; line-height: 1; padding: 0; cursor: pointer;
}
.cn-format-btn[data-format="italic"] { font-style: italic; }
.cn-format-btn[data-history] .cn-icon { width: .85rem; height: .85rem; }

/* ---------- larghezza regolabile del riquadro tratteggiato in scrittura (bozza IA o paragrafo
   cliccato per la modifica in vista conversazione): passando il mouse sul bordo tratteggiato
   compare il cursore "doppia freccia", trascinando si allarga/restringe restando centrato (vedi
   initParagraphResize in scrivi.js). Solo sui riquadri di prosa vera, non su .cn-format-wrap
   generico (che include anche la textarea di "continua tu la storia", non regolabile). */
.cn-format-wrap-paragrafo {
  max-width: var(--cn-paragraph-width, 100%); margin-left: auto; margin-right: auto;
}
/* Le maniglie di ridimensionamento sopra reagiscono solo a mousedown/mousemove/mouseup (vedi
   initParagraphResize in scrivi.js), quindi su un dispositivo touch non sono mai utilizzabili:
   --cn-paragraph-width può comunque restare valorizzata in localStorage da una sessione col mouse
   precedente (stesso dispositivo in modalità desktop, o un trackpad/stilo) e quel valore in rem è
   fisso, non ricalcolato alla rotazione — capitava che il riquadro tratteggiato restasse stretto
   quanto in verticale anche ruotando lo schermo in orizzontale, mentre i paragrafi già scritti (che
   non usano questa variabile) si allargavano regolarmente. Su touch la larghezza personalizzata non
   ha senso: si ignora sempre, restando piena come gli altri paragrafi. */
@media (pointer: coarse) {
  .cn-format-wrap-paragrafo { max-width: 100%; }
}
.cn-paragraph-resize-handle {
  position: absolute; top: 0; bottom: 0; width: 10px; cursor: ew-resize; z-index: 3;
}
.cn-paragraph-resize-handle.left { left: -5px; }
.cn-paragraph-resize-handle.right { right: -5px; }

/* ---------- pannello Debug (solo admin, vedi btn-debug/renderDebugBox in scrivi.js): mostra fra
   un paragrafo e l'altro esattamente il prompt inviato all'IA (e la risposta grezza, solo se
   diversa da quella pubblicata) — sfondo nero "da codice", volutamente fuori stile dal resto
   dell'interfaccia perché sia inequivocabile che è un pannello tecnico, non contenuto del romanzo. */
.cn-debug-box {
  background: #111; color: #d8d8d8; border-radius: .5rem; padding: 1rem;
  margin: 1rem 0; font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: .8em; line-height: 1.5;
}
.cn-debug-box-titolo {
  color: #8a8a8a; text-transform: uppercase; letter-spacing: .05em; font-size: .85em;
  margin: 1rem 0 .35rem;
}
.cn-debug-box-titolo:first-child { margin-top: 0; }
.cn-debug-box pre {
  white-space: pre-wrap; word-break: break-word; margin: 0; max-height: 16rem; overflow-y: auto;
}
/* Debug IA (2026-10-08, vedi DebugIa.php): un riquadro richiudibile per chiamata, "codice inviato" o "codice ricevuto". */
details.cn-debug-box { padding: .6rem 1rem; margin: .5rem 0; }
details.cn-debug-box > summary { cursor: pointer; margin: 0; text-transform: none; word-break: break-word; }
details.cn-debug-box[open] > summary { margin-bottom: .5rem; }
details.cn-debug-box pre { max-height: 28rem; }

/* ---------- coppia selettore colore + campo hex (Impostazioni > Personalizza colori tema) ---------- */
.cn-color-field { display: flex; gap: .5rem; align-items: center; }
.cn-color-field input[type="color"] {
  flex: 0 0 2.6rem; width: 2.6rem; height: 2.6rem; padding: .2rem; border-radius: .4rem;
  border: 1px solid var(--cn-border); background: transparent; cursor: pointer;
}
.cn-color-field input[type="text"] { flex: 1; }

/* ---------- grafico a barre o a linee (statistiche account e admin, vedi graficoHtml in app.js) ---------- */
.cn-graf { direction: ltr; font-size: .75em; margin-bottom: 1rem; }
.cn-graf-testa { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: .4rem 1rem; margin-bottom: .6rem; }
.cn-graf-legenda { display: flex; flex-wrap: wrap; gap: .3rem 1rem; }
.cn-graf-legenda span { display: inline-flex; align-items: center; gap: .35rem; }
.cn-graf-legenda i { display: inline-block; width: .7rem; height: .7rem; border-radius: .15rem; }
.cn-graf-legenda small { opacity: .6; font-size: 1em; }
.cn-graf-tipo { display: inline-flex; border: 1px solid var(--cn-border); border-radius: .4rem; overflow: hidden; }
.cn-graf-tipo button { border: 0; background: transparent; color: inherit; font: inherit; padding: .15rem .6rem; cursor: pointer; }
.cn-graf-tipo button.is-active { background: var(--cn-icon-bg); font-weight: 600; }
.cn-graf svg text { font-family: inherit; }
.cn-graf [data-grafico-vista] rect[fill="transparent"]:hover { fill: var(--cn-icon-bg); }

/* ---------- Corso di scrittura creativa (corso.html, corso.js) ---------- */
.cn-corso-intro { margin: 0 0 1.5rem; line-height: 1.6; }
.cn-corso-intro p { margin: 0 0 .8rem; opacity: .85; }
.cn-corso-sezione { font-size: 1.05em; margin: 2rem 0 .8rem; }
.cn-corso-corso { border: 1px solid var(--cn-border); border-radius: .6rem; padding: 1rem 1.1rem; margin-bottom: 1rem; }
.cn-corso-corso.is-bloccato { opacity: .6; }
.cn-corso-corso-testa { display: flex; align-items: center; justify-content: space-between; gap: .6rem; flex-wrap: wrap; }
.cn-corso-corso h2 { margin: 0; font-size: 1.1em; }
.cn-corso-desc { margin: .3rem 0 .8rem; opacity: .75; font-size: .9em; }
.cn-corso-programma-titolo { margin: .8rem 0 .3rem; font-size: .85em; font-weight: 600; }
.cn-corso-programma { margin: 0; padding-left: 1.2rem; font-size: .9em; opacity: .8; }
.cn-corso-lezioni { list-style: none; margin: 0; padding: 0; }
.cn-corso-lezione-voce {
  display: flex; align-items: center; gap: .75rem; width: 100%; padding: .6rem .3rem; background: none; border: none;
  border-top: 1px solid var(--cn-border); font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.cn-corso-lezione-voce:hover:not([disabled]) { background: var(--cn-icon-bg); }
.cn-corso-lezione-voce[disabled] { opacity: .5; cursor: default; }
.cn-corso-lezione-num {
  flex: 0 0 auto; width: 1.6rem; height: 1.6rem; border-radius: 50%; border: 1px solid var(--cn-icon-border);
  display: flex; align-items: center; justify-content: center; font-size: .8em;
}
.cn-corso-lezione-titolo { flex: 1; min-width: 0; }
.cn-corso-stato { flex: 0 0 auto; font-size: .75em; padding: .15rem .55rem; border-radius: 1rem; border: 1px solid var(--cn-border); opacity: .85; white-space: nowrap; }
.cn-corso-stato.is-completata { border-color: var(--cn-accent); color: var(--cn-accent); opacity: 1; }
.cn-corso-stato.is-in_corso { border-style: dashed; border-color: var(--cn-accent); opacity: 1; }

.cn-corso-lezione-h1 { font-size: 1.4em; margin: .4rem 0 1.2rem; }
.cn-corso-spiegazione p { margin: 0 0 .9rem; }
.cn-corso-esempi { display: grid; gap: .8rem; margin: 1.2rem 0; }
@media (min-width: 720px) { .cn-corso-esempi { grid-template-columns: 1fr 1fr; } }
.cn-corso-esempio { border: 1px solid var(--cn-border); border-left-width: 4px; border-radius: .5rem; padding: .7rem .9rem; }
.cn-corso-esempio.is-riuscito { border-left-color: var(--cn-accent); }
.cn-corso-esempio.is-debole { border-left-color: var(--cn-muted); }
.cn-corso-esempio p { margin: 0 0 .4rem; }
.cn-corso-esempio-etichetta { font-size: .75em; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; opacity: .7; }
.cn-corso-esempio-testo { font-style: italic; white-space: pre-line; }
.cn-corso-esempio .cn-punto-meta { font-size: .95em; opacity: .8; line-height: 1.5; }
.cn-corso-consegna { margin: 1.6rem 0 1rem; padding: .9rem 1.1rem; border-radius: .6rem; background: var(--cn-icon-bg); }
.cn-corso-consegna h3 { margin: 0 0 .4rem; font-size: 1em; }
.cn-corso-consegna p { margin: 0 0 .3rem; }

/* La casella di scrittura: bordo continuo nel colore d'accento, come "qui scrivi tu". */
.cn-corso-casella {
  display: block; width: 100%; min-height: 12rem; box-sizing: border-box; padding: .9rem 1rem;
  border: 1px solid var(--cn-accent); border-radius: .6rem; background: transparent; color: inherit;
  font: inherit; line-height: 1.6; resize: vertical;
}
.cn-corso-casella:focus { outline: none; }
.cn-corso-casella:disabled { opacity: .6; }
.cn-corso-sotto-casella { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin-top: .6rem; }
.cn-corso-tentativo-etichetta { margin: 1.4rem 0 .5rem; font-size: .85em; font-weight: 600; opacity: .8; }
.cn-corso-scrittura .cn-corso-tentativo-etichetta { margin-top: 2.6rem; }
#corso-invia:disabled { opacity: 1; }
.cn-corso-brano { white-space: pre-wrap; padding: .8rem 1rem; border-radius: .6rem; border: 1px dashed var(--cn-border); margin-bottom: .8rem; }
.cn-corso-feedback { border: 1px solid var(--cn-border); border-left: 4px solid var(--cn-accent); border-radius: .5rem; padding: .3rem 1rem; }
.cn-corso-fb-blocco { padding: .5rem 0; }
.cn-corso-fb-blocco + .cn-corso-fb-blocco { border-top: 1px solid var(--cn-border); }
.cn-corso-fb-blocco h4 { margin: 0 0 .25rem; font-size: .85em; text-transform: uppercase; letter-spacing: .04em; color: var(--cn-text); }
.cn-corso-fb-blocco p { margin: 0; }
.cn-corso-fb-blocco blockquote { margin: 0 0 .4rem; padding-left: .8rem; border-left: 3px solid var(--cn-border); font-style: italic; }
.cn-corso-chiusura { margin-top: 1.8rem; padding: 1rem 1.1rem; border-radius: .6rem; border: 1px solid var(--cn-accent); }
.cn-corso-chiusura h3 { margin: 0 0 .5rem; font-size: 1.05em; }
.cn-corso-chiusura p { margin: 0 0 .6rem; }
.cn-corso-azioni { display: flex; gap: .6rem; flex-wrap: wrap; margin-top: .8rem; }
.cn-corso-storico { margin-top: 2rem; }
.cn-corso-storico summary { cursor: pointer; font-weight: 600; }
.cn-corso-giro { margin-top: 1rem; padding-top: .4rem; border-top: 1px solid var(--cn-border); }
.cn-corso-giro h4 { margin: .5rem 0 0; font-size: .95em; }

/* ---------- Analisi del manoscritto (struttura e stile), vedi analisi.js ---------- */
.cn-analisi-scelta { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--cn-border); }
.cn-analisi-scelta h3 { margin: 0 0 .25rem; font-size: 1.05em; }
.cn-analisi-check { display: flex; gap: .6rem; align-items: flex-start; margin: .75rem 0; cursor: pointer; font-size: .92em; line-height: 1.45; }
.cn-analisi-check input { margin-top: .3rem; flex-shrink: 0; }
.cn-analisi-check-inline { margin: .5rem 0; }
.cn-analisi-costo { margin: .75rem 0 .25rem; font-size: .95em; }
.cn-analisi-avviso { color: #b3261e; font-size: .9em; }
.cn-analisi-pannello { display: flex; flex-direction: column; gap: 1.5rem; }
.cn-analisi-sezione h3 { margin: 0 0 .5rem; font-size: 1.05em; }
.cn-analisi-sezione h4 { margin: 1rem 0 .4rem; font-size: .95em; }
.cn-analisi-punto { border: 1px solid var(--cn-border); border-left-width: 4px; border-radius: .4rem; padding: .6rem .75rem; margin: .6rem 0; }
.cn-analisi-punto p { margin: .35rem 0; font-size: .92em; }
.cn-analisi-punto-testa { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.cn-analisi-badge { font-size: .75em; padding: .1rem .5rem; border-radius: 1rem; border: 1px solid var(--cn-border); white-space: nowrap; }
.cn-analisi-regge { border-left-color: #2e7d32; }
.cn-analisi-debole { border-left-color: #e8a317; }
.cn-analisi-manca { border-left-color: #c62828; }
.cn-analisi-non_ancora { border-left-color: var(--cn-border); opacity: .8; }
.cn-analisi-link { background: none; border: none; padding: 0; font: inherit; font-size: .85em; color: var(--cn-accent); cursor: pointer; text-decoration: underline; text-align: left; }
.cn-analisi-pattern { display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem; margin: .3rem 0; }
.cn-analisi-pattern.is-silenziato { opacity: .6; }
.cn-analisi-sugg { opacity: .9; }

/* Sottolineature di stile nel testo: un tratto diverso per ciascuna categoria, così il peso
   dell'osservazione si vede prima ancora di leggere la scheda. */
.cn-seg { text-decoration-line: underline; text-decoration-thickness: 2px; text-underline-offset: .18em; cursor: help; }
.cn-seg-errore { text-decoration-style: wavy; text-decoration-color: #d93025; }
.cn-seg-certa { text-decoration-style: solid; text-decoration-color: #e8a317; }
.cn-seg-soggettiva { text-decoration-style: dotted; text-decoration-color: #4a86e8; }
.cn-seg-card { position: fixed; z-index: 60; width: min(22rem, calc(100vw - 16px)); background: var(--cn-bg); color: var(--cn-text); border: 1px solid var(--cn-border); border-radius: .5rem; padding: .75rem .85rem; box-shadow: 0 6px 24px rgba(0,0,0,.22); font-size: .9rem; line-height: 1.45; }
.cn-seg-card p { margin: .4rem 0; }
.cn-seg-card-testa { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.cn-seg-tag { font-size: .72em; font-weight: 600; padding: .1rem .5rem; border-radius: 1rem; color: #fff; }
.cn-seg-tag-errore { background: #d93025; }
.cn-seg-tag-certa { background: #b97d00; }
.cn-seg-tag-soggettiva { background: #3b6fc7; }
.cn-seg-proposta { margin: .5rem 0; padding: .45rem .6rem; border-left: 3px solid var(--cn-accent); background: rgba(127,127,127,.09); border-radius: .25rem; }
.cn-seg-proposta strong { display: block; font-size: .8em; opacity: .7; margin-bottom: .15rem; }
.cn-seg-azioni { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .6rem; }
.cn-seg-azioni .cn-btn { padding: .3rem .7rem; font-size: .85em; }

/* Chat con l'insegnante, tra il primo feedback e il secondo tentativo */
.cn-corso-chat { margin-top: 1rem; border: 1px solid var(--cn-border); border-radius: .6rem; padding: .6rem 1rem .8rem; }
.cn-corso-chat summary { cursor: pointer; font-weight: 600; }
.cn-corso-chat-lista { display: flex; flex-direction: column; gap: .6rem; margin: .8rem 0 .6rem; }
.cn-corso-bolla { max-width: 92%; padding: .55rem .8rem; border-radius: .7rem; border: 1px solid var(--cn-border); }
.cn-corso-bolla p { margin: .15rem 0 0; white-space: pre-wrap; line-height: 1.5; }
.cn-corso-bolla-chi { font-size: .72em; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; opacity: .65; }
.cn-corso-bolla.is-utente { align-self: flex-end; background: var(--cn-icon-bg); }
.cn-corso-bolla.is-insegnante { align-self: flex-start; }
.cn-corso-chat-form textarea {
  display: block; width: 100%; box-sizing: border-box; padding: .6rem .8rem; border: 1px solid var(--cn-border); border-radius: .5rem;
  background: transparent; color: inherit; font: inherit; line-height: 1.5; resize: vertical;
}
.cn-corso-chat-form textarea:focus { outline: none; border-color: var(--cn-accent); }

/* Testo originale mostrato sopra la proposta di modifica di un punto della struttura (analisi.js). */
.cn-analisi-originale { max-height: 14rem; overflow-y: auto; margin: .6rem 0 1rem; padding: .6rem .9rem; border: 1px dashed var(--cn-border); border-radius: .5rem; font-size: .9em; line-height: 1.5; }
.cn-analisi-originale h4 { margin: 0 0 .4rem; font-size: .8em; text-transform: uppercase; letter-spacing: .04em; opacity: .7; }
.cn-analisi-originale p { margin: 0 0 .6rem; white-space: pre-wrap; }

/* Pagina "Il tuo account": titoli delle sezioni più scuri del testo e un poco più grandi; mesi gratuiti in evidenza. */
.cn-account .cn-drawer-section h3 { font-size: .95em; opacity: 1; color: var(--cn-text); font-weight: 700; }
.cn-referral-mesi { margin: 1.5rem 0 .4rem; font-size: 1em; opacity: .8; }
.cn-gioco-modalita { display: flex; gap: .75rem; align-items: flex-start; padding: .9rem 1rem; margin: 0 0 .75rem; border: 1px solid var(--cn-border); border-radius: .6rem; cursor: pointer; }
.cn-gioco-modalita.is-scelta { border-color: var(--cn-accent); box-shadow: 0 0 0 1px var(--cn-accent); }
.cn-gioco-modalita input { margin-top: .25rem; }
.cn-collab-opzione-riga > .cn-gioco-modalita { flex: 1; }

/* ---------- Campi di testo senza i colori del browser (2026-09-29, decisione dell'autore) ----------
   Cliccando in un campo il browser aggiungeva il suo contorno (blu in Chrome/Safari), e caselle e pulsanti di scelta avevano il suo
   colore: in tutto CiaoNovel (Writer, Reader, homepage) i campi restano nei colori del tema scelto. Il contorno del browser sparisce,
   al suo posto il bordo del campo prende il colore d'accento del tema; i riquadri con un loro stile (bordo del paragrafo in
   modifica, titolo del giorno del diario...) hanno regole più precise e restano com'erano. Per chi usa la tastiera, i pulsanti mostrano
   ancora dove si trova il cursore, ma con il colore d'accento. */
input:focus, textarea:focus, select:focus, [contenteditable]:focus { outline: none; }
input:not([type="radio"]):not([type="checkbox"]):not([type="range"]):focus, textarea:focus, select:focus { border-color: var(--cn-accent); }
input[type="radio"], input[type="checkbox"], input[type="range"], progress { accent-color: var(--cn-accent); }
/* Riquadro dell'idea di una storia (campoIdeaHtml in app.js): bordato come la bozza anche mentre si scrive (prima il bordo
   spariva al clic per la regola qui sopra), annulla/ripeti in basso a sinistra sempre visibili, nessun B/I quindi l'angolo per
   allungarlo resta. */
.cn-campo-idea textarea, .cn-campo-idea textarea:focus {
  outline: 1px solid var(--cn-accent); outline-offset: 0; border: none; border-radius: .4rem;
  padding: .75rem .75rem 2.4rem; background: transparent; color: var(--cn-text); resize: vertical; overflow-y: auto;
}
#turn-area .cn-campo-idea:not(:focus-within) .cn-format-row { opacity: 1; pointer-events: auto; }
textarea.is-draft:focus { outline: 1px solid var(--cn-accent); }
button:focus-visible, a:focus-visible, summary:focus-visible { outline: 2px solid var(--cn-accent); outline-offset: 2px; }
button:focus:not(:focus-visible), a:focus:not(:focus-visible) { outline: none; }

/* Riquadro "Richiedi una modifica" (richiestaModificaHtml in app.js, 2026-09-30): la domanda è il segnaposto, "Applica" a destra. */
.cn-richiesta-modifica { display: flex; align-items: stretch; gap: .5rem; margin-top: .8rem; }
.cn-field.cn-richiesta-modifica textarea { flex: 1; min-width: 0; min-height: 0; }
.cn-richiesta-modifica > .cn-btn { flex-shrink: 0; }
.cn-richiesta-modifica > .cn-collab-voto-btn { align-self: flex-end; }
/* Diario: "Rimetti il testo originale" e i due Rielabora un po' più piccoli (2026-09-30). */
.cn-btn.cn-diario-rielabora { font-size: .85em; }

/* Attese lunghe (attesaLungaHtml/attesaLungaSotto in app.js): barra che avanza da sola sotto il messaggio. */
.cn-attesa-lunga-sotto { margin-top: 12px; width: 100%; }
.cn-attesa-lunga-sotto .cn-empty { margin: 0; }

/* ---------- Chat fra utenti (chat.html, chat.js) ---------- */
/* overflow: clip (non hidden): un elemento hidden si può ancora far scorrere da codice (focus, scrollIntoView) e la chat
   finiva sotto la barra in alto, che copriva il primo messaggio. */
body.cn-chat-pagina { height: 100vh; height: 100dvh; overflow: hidden; overflow: clip; }
.cn-chat { flex: 1; min-height: 0; display: flex; width: 100%; max-width: 64rem; margin: 0 auto; overflow: hidden; overflow: clip; }
.cn-chat > .cn-empty, .cn-chat > .cn-empty-state { flex: 1; padding: 2rem 1rem; }
.cn-chat-lista { width: 20rem; flex-shrink: 0; overflow-y: auto; padding: 1rem; border-right: 1px solid var(--cn-border); }
.cn-chat-lista-azioni { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: 1rem; }
.cn-chat-lista-azioni .cn-btn { font-size: .85em; }
/* "Nuova chat": il + tondo come quello di "I tuoi scritti", in fondo a destra; a sinistra Il tuo codice e Rubrica. */
.cn-chat-lista-azioni { align-items: center; }
.cn-chat-nuova { margin-left: auto; }
.cn-chat-riga { display: flex; align-items: center; gap: .15rem; border-bottom: 1px solid var(--cn-border); }
.cn-chat-riga.is-aperta { background: color-mix(in srgb, var(--cn-accent) 12%, transparent); }
.cn-chat-voce { display: flex; align-items: center; gap: .5rem; flex: 1; min-width: 0; padding: .7rem .5rem; background: none; border: 0; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.cn-chat-riga-btn { flex-shrink: 0; width: 1.9rem; height: 1.9rem; padding: 0; }
.cn-chat-riga-btn .cn-icon { width: 1rem; height: 1rem; }
.cn-chat-voce-nome { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.cn-chat-voce-ora { font-size: .75em; opacity: .65; flex-shrink: 0; }
.cn-chat-pallino { display: inline-block; width: .55em; height: .55em; border-radius: 50%; background: #e0303f; flex-shrink: 0; }
.cn-chat-conversazione { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* Senza questa riga il display:flex vinceva sull'attributo hidden: la conversazione restava sempre nella pagina accanto all'elenco. */
.cn-chat-conversazione[hidden] { display: none; }
.cn-chat-messaggi { flex: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: .4rem; }
.cn-chat-bolla { max-width: 78%; align-self: flex-start; padding: .45rem .7rem; border-radius: .8rem; border: 1px solid var(--cn-border); line-height: 1.4; }
.cn-chat-bolla.is-mia { align-self: flex-end; background: color-mix(in srgb, var(--cn-accent) 16%, var(--cn-bg)); border-color: transparent; }
.cn-chat-bolla-testo { white-space: pre-wrap; overflow-wrap: anywhere; }
.cn-chat-bolla-nome { font-size: .75em; font-weight: 700; color: var(--cn-accent); }
.cn-chat-bolla-ora { font-size: .7em; opacity: .6; text-align: right; }
.cn-chat-evento { align-self: center; font-size: .78em; opacity: .7; text-align: center; padding: .2rem .5rem; font-style: italic; }
.cn-chat-emoji { display: flex; flex-wrap: wrap; gap: .1rem; padding: .4rem 1rem; border-top: 1px solid var(--cn-border); }
.cn-chat-emoji[hidden] { display: none; }
.cn-chat-emoji-voce { background: none; border: 0; font-size: 1.4em; padding: .15rem; cursor: pointer; line-height: 1; }
.cn-chat-invio { display: flex; align-items: flex-end; gap: .4rem; padding: .6rem 1rem; border-top: 1px solid var(--cn-border); }
.cn-chat-invio textarea { flex: 1; resize: none; font: inherit; color: inherit; background: var(--cn-bg); border: 1px solid var(--cn-border); border-radius: .6rem; padding: .45rem .6rem; max-height: 160px; }
.cn-chat-riga-persona { display: flex; align-items: center; justify-content: space-between; gap: .5rem 1rem; padding: .45rem 0; border-bottom: 1px solid var(--cn-border); flex-wrap: wrap; }
.cn-chat-persona-nome { flex: 1 1 8rem; min-width: 0; overflow-wrap: anywhere; }
/* Scrivi, Blocca, Rimuovi: stessa altezza, mai a capo dentro un pulsante né uno sopra l'altro; se non ci stanno accanto al nome vanno sotto, a destra. */
.cn-chat-persona-azioni { display: flex; flex-wrap: nowrap; gap: .4rem; margin-left: auto; flex-shrink: 0; }
.cn-chat-persona-azioni .cn-btn.cn-btn-inline { margin: 0; padding: .3em .7em; line-height: 1.3; white-space: nowrap; }
/* Pulsante della chat nella barra di ogni pagina, con il pallino dei messaggi non letti (disegnaPallinoChat in app.js). */
.cn-chat-barra-btn { position: relative; }
.cn-chat-barra-btn .cn-icon { width: 1.5rem; height: 1.5rem; margin: -.2rem; }
.cn-chat-barra-btn .cn-chat-pallino { position: absolute; top: .15rem; right: .15rem; width: .5em; height: .5em; }
@media (max-width: 699px) {
  .cn-chat-lista { width: 100%; border-right: 0; }
  body.cn-chat-in-conversazione .cn-chat-lista { display: none; }
}

/* Homepage di chi ha fatto l'accesso (index.html, mostraHomeUtente): al posto del testo della homepage. */
html:not(.cn-home-utente) #hp-utente, html.cn-home-utente #hp-contenuto-editabile { display: none; }
/* I sei quadrati in un solo contenitore: 3 per riga (3 sopra e 3 sotto), anche sul telefono, o 2 per riga se un nome non ci sta;
   tutti della stessa misura (attivaPulsantiUniformi con perRiga [3, 2]). */
#hp-utente .cn-home-cta, .cn-hp-sei-categorie { flex-wrap: nowrap; gap: .75rem; }
#hp-utente .cn-home-cta-prima, .cn-hp-sei-categorie { flex-wrap: wrap; justify-content: center; }
#hp-utente .cn-home-cta .cn-btn, .cn-hp-sei-categorie .cn-btn { min-width: 0; padding: 1rem .9rem; text-align: center; }
#hp-utente .cn-home-cta-logo, .cn-hp-sei-categorie .cn-home-cta-logo { margin-left: auto; margin-right: auto; }
/* Una riga brevissima sotto il nome: cosa si fa lì (home.desc_*). */
#hp-utente .cn-home-cta-desc, .cn-hp-sei-categorie .cn-home-cta-desc { font-size: .88em; font-weight: 400; opacity: .7; margin-top: .3rem; line-height: 1.3; white-space: normal; }
/* Sul telefono solo il nome, senza la riga sotto (decisione dell'autore, 2026-10-08). */
@media (max-width: 699px) { #hp-utente .cn-home-cta-desc, .cn-hp-sei-categorie .cn-home-cta-desc { display: none; } }
/* Quadrati della homepage e scelte delle sezioni: larghi un terzo della riga. */
#hp-utente .cn-home-area { justify-content: center; margin-top: -1.25rem; }
#hp-utente .cn-home-cta-prima .cn-btn, .cn-hp-sei-categorie .cn-btn, #hp-utente .cn-home-area .cn-btn { flex: 0 0 calc((100% - 1.5rem) / 3); }
#hp-utente .cn-home-area[hidden] { display: none; }
/* Titolo "CiaoNovel.com" in cima alla homepage, come quello dei visitori (#hp-titolo), e meno spazio sopra di loro. */
.cn-hp-titolo-sito, #hp-titolo { font-size: 1.6em; text-align: center; margin-top: 0; }
/* Sottotitolo "Scrivi. Leggi. Gioca." sotto il titolo dei visitatori (2026-10-12). */
#hp-titolo { line-height: 1.25; margin-bottom: .2rem; }
.cn-hp-sottotitolo { text-align: center; font-size: 1em; line-height: 1.4; margin: 0 0 1.5rem; opacity: .85; }
.cn-hp-sei-categorie { margin: 1.5rem 0; }
/* Pagina di Gioca, Impara o Appunti (index.html?area=…): solo le scelte a quadrati, senza titolo della sezione (2026-10-09), su più
   righe se serve (Gioca: due sopra e uno sotto, .cn-home-a-capo). */
.cn-home-area-titolo { display: none; }
#hp-utente .cn-home-area { flex-wrap: wrap; row-gap: .75rem; }
.cn-home-a-capo { flex-basis: 100%; height: 0; }
html.cn-home-area-pagina #hp-utente .cn-home-cta-prima, html.cn-home-area-pagina .cn-hp-titolo-sito { display: none; }
html.cn-home-area-pagina #hp-utente .cn-home-area { margin-top: 0; }
/* Nomi lunghi nei quadrati ("Multigiocatore", o con il carattere grande): vanno a capo dentro il quadrato invece di uscirne. */
#hp-utente .cn-home-cta-btn > div, .cn-hp-sei-categorie .cn-home-cta-btn > div { max-width: 100%; overflow-wrap: anywhere; hyphens: auto; }
#hp-utente .cn-home-cta-btn.is-attivo { background: transparent; color: inherit; }
#hp-utente svg.cn-home-cta-logo { color: var(--cn-btn-text); }
#hp-utente .cn-home-cta-btn:hover svg.cn-home-cta-logo, #hp-utente .cn-home-cta-btn.is-attivo svg.cn-home-cta-logo { color: var(--cn-text); }
.cn-home-cta-chat { position: relative; }
.cn-home-cta-chat .cn-chat-pallino { position: absolute; top: .9rem; right: .9rem; width: .7em; height: .7em; }
.cn-project-card.cn-home-scritto { flex-direction: row; }
.cn-home-scritto { display: flex; align-items: center; gap: .8rem; min-width: 0; max-width: 100%; box-sizing: border-box; color: inherit; text-decoration: none; padding: .55rem 1rem; margin-bottom: .5rem; }
/* Colonna a destra dell'icona: nome e descrizione sulla stessa riga, la descrizione va sotto se non ci sta. */
.cn-home-scritto-testo { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; column-gap: .6rem; row-gap: .1rem; }
/* Titolo e "tipo · paragrafi" sulla stessa riga: schede più basse. Il titolo lungo si accorcia con i puntini. */
.cn-home-scritto .cn-project-titolo { margin-bottom: 0; min-width: 0; max-width: 100%; flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Con il carattere grande (A+) "tipo · paragrafi" non ci sta più accanto al titolo: va sotto invece di spingere fuori il riquadro. */
.cn-home-scritto .cn-project-meta { flex-shrink: 0; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Mappa del mondo aperto (writer/mappa.js), a tutto schermo. */
.cn-mappa-overlay { position: fixed; inset: 0; z-index: 900; display: flex; align-items: center; justify-content: center; padding: 1rem; background: rgba(0, 0, 0, .55); }
.cn-mappa-finestra { width: min(100%, 64rem); max-height: 100%; overflow: auto; background: var(--cn-bg); color: var(--cn-text); border: 1px solid var(--cn-border); border-radius: 10px; padding: .75rem; }
.cn-mappa-testata { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin-bottom: .5rem; }
.cn-mappa-canvas { display: block; width: 100%; border-radius: 6px; touch-action: none; cursor: grab; }
.cn-mappa-canvas:active { cursor: grabbing; }
/* Zoom della mappa (mappa.js): pulsanti in basso a destra sopra il disegno, con lo sfondo pieno. */
.cn-mappa-area { position: relative; }
.cn-mappa-zoom { position: absolute; right: .5rem; bottom: .5rem; display: flex; gap: .35rem; }
.cn-mappa-zoom .cn-btn { min-width: 2.2rem; padding: .25rem .6rem; font-size: .95em; line-height: 1.2; background: var(--cn-bg); }
.cn-mappa-zoom .cn-btn[hidden] { display: none; }
.cn-mappa-legenda { margin: .4rem 0 0; font-size: .8em; opacity: .75; }
.cn-mappa-amici { position: absolute; left: .5rem; bottom: .5rem; max-width: 60%; padding: .5rem .75rem; background: var(--cn-bg); color: var(--cn-text); border: 1px solid var(--cn-border); border-radius: 8px; font-size: .9em; cursor: pointer; }
.cn-mappa-amici ul { margin: .25rem 0 0; padding-left: 1.1rem; }
.btn-con-pallino { position: relative; }
.btn-con-pallino .cn-pallino-mappa { position: absolute; top: .15rem; right: .15rem; width: .5em; height: .5em; border-radius: 50%; background: #e0303f; }
:root[data-theme="eink"] .cn-mappa-overlay { background: #fff; }

/* Libro-gioco multigiocatore (gioca.js, 2026-10-05). Barra del tempo sempre visibile in cima mentre si gioca: giorno, parte del
   giorno, luogo e mosse rimaste. */
.cn-barra-tempo { position: sticky; top: 0; z-index: 5; background: var(--cn-bg); border-bottom: 1px solid var(--cn-border); padding: .45rem .2rem; margin: 0 0 .8rem; font-size: .88em; text-align: center; }
.cn-barra-tempo strong { font-weight: 600; }
.cn-barra-tempo[hidden] { display: none; }
.cn-con-pallino-mondo { position: relative; }
.cn-con-pallino-mondo .cn-pallino-mondo { position: absolute; top: .15rem; right: .15rem; width: .5em; height: .5em; }
#hp-utente .cn-con-pallino-mondo .cn-pallino-mondo { top: .9rem; right: .9rem; width: .7em; height: .7em; }
.cn-sala-giocatore { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; padding: .4rem 0; border-bottom: 1px solid var(--cn-border); }
.cn-sala-invito { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }
.cn-sala-codice { font-family: monospace; font-size: 1.2em; letter-spacing: .1em; }
.cn-sala-qr { display: block; max-width: 180px; image-rendering: pixelated; margin: .6rem 0; }
.cn-riposo { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: .6rem; }
.cn-riposo select { flex: 1; min-width: 12rem; }

/* Partita a due (partita.js): scelte personali e proposta in corso nella creazione condivisa. */
.cn-field label.cn-partita-scelta { display: flex; gap: .5rem; align-items: center; font-weight: normal; margin: .3rem 0; }
.cn-partita-proposta { margin: .6rem 0 1rem; }
.cn-partita-turno { margin: 1rem 0; padding: .7rem .9rem; border: 1px solid var(--cn-border); border-radius: 8px; }
.cn-partita-autore { font-size: .78em; font-style: italic; opacity: .65; margin: 1.2rem 0 .2rem; }

/* Insegnante IA (insegnante.js, 2026-10-08). Riusa le classi del corso di scrittura (cn-corso-*) per elenchi, esempi, chat. */
.cn-ins-avviso { border: 1px solid var(--cn-errore-border); background: var(--cn-errore-bg); color: var(--cn-errore-text); border-radius: .6rem; padding: .9rem 1.1rem; margin: 0 0 1.4rem; }
.cn-ins-avviso h2 { margin: 0 0 .5rem; font-size: 1.05em; }
.cn-ins-avviso p { margin: 0 0 .6rem; line-height: 1.5; }
.cn-ins-capito { display: flex; align-items: center; gap: .5rem; cursor: pointer; font-weight: 400; font-size: 1em; line-height: 1.5; margin-top: .4rem; }
/* .cn-page p (margine sopra 0) vinceva sulla classe sola: serve il selettore più specifico. */
.cn-page .cn-ins-avviso-riga, .cn-ins-avviso-riga { margin: 2rem 0 .5rem; font-size: .78em; opacity: .7; text-align: start; }
/* Avvio del corso a domande: la risposta già data (tornando con "Indietro") ha il bordo del colore d'accento. */
.cn-action-btn.is-scelto { border-color: var(--cn-accent); }
.cn-ins-unita-prog { margin-top: .9rem; }
.cn-ins-unita-prog h3 { margin: 0 0 .3rem; font-size: 1em; }
.cn-ins-unita-prog ol { margin: 0; padding-left: 1.4rem; }
.cn-ins-unita-prog li { margin: .25rem 0; }
.cn-ins-ripasso-oggi { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .6rem; padding: .7rem 1rem; border-radius: .6rem; background: var(--cn-icon-bg); margin: 0 0 1rem; }
.cn-ins-numero { display: inline-flex; align-items: center; justify-content: center; min-width: 1.4em; padding: 0 .35em; border-radius: 1em; font-size: .75em; background: var(--cn-accent); color: var(--cn-bg); font-weight: 700; }
.cn-ins-btn-ripassa { padding: .25rem .7rem; font-size: .85em; }
.cn-ins-lezione-riga { display: flex; align-items: center; gap: .3rem; }
.cn-ins-lezione-riga .cn-corso-lezione-voce { flex: 1; min-width: 0; }
/* Numero della lezione ("2.10", "10.1"…) sempre dentro il cerchietto: misure in em, così crescono con il testo (A+), e cerchio più largo. */
.cn-ins-lezione-riga .cn-corso-lezione-num { width: 3.6em; height: 3.6em; font-size: .64em; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cn-ins-ripassa-lezione { position: relative; flex: 0 0 auto; }
.cn-ins-ripassa-lezione .cn-ins-numero { position: absolute; top: -.3rem; right: -.3rem; }
.cn-ins-testo p { line-height: 1.65; }
.cn-ins-elenco { margin: .3rem 0 .6rem; padding-left: 1.3rem; }
.cn-ins-elenco li { margin: .2rem 0; }
.cn-ins-esempi { display: grid; gap: .8rem; margin: 1.2rem 0; }
.cn-ins-esercizio { border: 1px solid var(--cn-border); border-radius: .6rem; padding: .8rem 1rem; margin: 0 0 1rem; }
.cn-ins-esercizio-num { margin: 0 0 .3rem; font-size: .78em; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; opacity: .7; }
.cn-ins-domanda { margin-bottom: .7rem; font-weight: 600; }
.cn-ins-opzioni { display: flex; flex-direction: column; gap: .45rem; }
.cn-ins-opzione { display: flex; align-items: flex-start; gap: .6rem; text-align: start; width: 100%; padding: .55rem .75rem; border: 1px solid var(--cn-border); border-radius: .5rem; background: transparent; color: inherit; font: inherit; cursor: pointer; }
.cn-ins-opzione:hover:not([disabled]) { background: var(--cn-icon-bg); }
.cn-ins-opzione[disabled] { cursor: default; }
.cn-ins-opzione.is-giusta { border-color: var(--cn-accent); border-width: 2px; }
.cn-ins-opzione.is-sbagliata { border-color: var(--cn-errore-border); background: var(--cn-errore-bg); color: var(--cn-errore-text); }
.cn-ins-lettera { flex: 0 0 auto; font-weight: 700; opacity: .7; }
.cn-ins-esito { margin: .7rem 0 .4rem; padding: .6rem .8rem; border-radius: .5rem; border-left: 4px solid var(--cn-accent); background: var(--cn-icon-bg); }
.cn-ins-esito.is-errata { border-left-color: var(--cn-errore-border); background: var(--cn-errore-bg); color: var(--cn-errore-text); }
.cn-ins-esito.is-parziale { border-left-style: dashed; }
.cn-ins-esito > div { margin-top: .3rem; }
.cn-ins-errori-lista { margin: .4rem 0 0; padding-left: 1.2rem; font-size: .92em; }
.cn-ins-rifai { margin-top: .3rem; }
.cn-ins-soluzione { margin: .4rem 0; }
.cn-ins-soluzione summary { cursor: pointer; font-size: .9em; }
.cn-ins-soluzione > div { margin-top: .4rem; padding: .5rem .8rem; border-radius: .5rem; background: var(--cn-icon-bg); }
.cn-ins-risposta { margin-top: .6rem; }
.cn-ins-bolla-testo { margin-top: .15rem; line-height: 1.5; }
.cn-ins-voti { display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem; margin-top: .8rem; }
.cn-ins-voti .cn-btn { display: flex; flex-direction: column; align-items: center; gap: .1rem; padding: .5rem .3rem; }
.cn-ins-voti small { font-size: .75em; opacity: .8; font-weight: 400; }
.cn-ins-carta { border: 1px solid var(--cn-accent); border-radius: .7rem; padding: 1rem 1.1rem; margin: 0 0 1.4rem; }
.cn-ins-carta-fronte { font-size: 1.1em; font-weight: 600; margin: .4rem 0; }
.cn-ins-carta-retro { margin: .4rem 0; }
.cn-ins-carta-voce { padding: .7rem 0; border-top: 1px solid var(--cn-border); }
.cn-ins-carta-voce .cn-ins-carta-fronte { font-size: 1em; }
.cn-ins-errori { list-style: none; margin: 0; padding: 0; }
.cn-ins-errori li { padding: .7rem 0; border-top: 1px solid var(--cn-border); }
.cn-ins-errori li.is-risolto { opacity: .55; }
.cn-ins-nuova-carta { margin-top: 1rem; }
.cn-ins-nuova-carta summary { cursor: pointer; font-weight: 600; }
#ins-main .katex-display { overflow-x: auto; overflow-y: hidden; padding: .2rem 0; }
@media (max-width: 480px) { .cn-ins-voti { grid-template-columns: repeat(2, 1fr); } }

/* Scheda laterale "Dati della storia" del superadmin (2026-10-08, apriDatiStoria in app.js): ogni dato salvato dal motore, a albero. */
.cn-dati-storia details > summary { cursor: pointer; }
.cn-dati-albero { margin: 0; font-size: .88em; }
.cn-dati-albero dt { font-weight: 600; opacity: .75; margin-top: .35rem; }
.cn-dati-albero dd { margin: 0 0 0 .8rem; }
.cn-dati-lista { margin: .2rem 0; padding-inline-start: 1.3rem; }
.cn-dati-lista > li { margin-bottom: .3rem; }
.cn-dati-testo { white-space: pre-wrap; word-break: break-word; }

/* ---------- Focus Timer (writer/focus.html, 2026-10-09): come quello del lettore e-ink ----------
   Tre schede in alto a tutta larghezza (quella aperta piena), l'ora sotto, al centro nome, icona e cifre grandi, in basso i comandi
   con il principale (Avvia / Pausa / Riprendi) sempre sull'ultima riga. A fine tempo i colori si invertono un secondo sì e uno no. */
.cn-page.cn-focus-pagina { padding-top: .6rem; }
.cn-focus { display: flex; flex-direction: column; align-items: stretch; min-height: 70vh; }
.cn-focus-schede { display: flex; border: 2px solid var(--cn-btn-bg); border-radius: .5rem; overflow: hidden; }
.cn-focus-scheda { flex: 1 1 0; min-width: 0; padding: .7rem .4rem; border: none; background: transparent; color: inherit; font: inherit; font-weight: 700; cursor: pointer; }
.cn-focus-scheda + .cn-focus-scheda { border-left: 2px solid var(--cn-btn-bg); }
.cn-focus-scheda.is-attiva { background: var(--cn-btn-bg); color: var(--cn-btn-text); }
.cn-focus-testa { display: flex; justify-content: space-between; align-items: center; margin: 0 .2rem; line-height: 1.1; }
.cn-focus-ora { font-size: 1.6em; }
.cn-focus-ciclo { font-size: 1.05em; opacity: .8; }
.cn-focus-corpo { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 1.5rem 0; }
.cn-focus-nome { margin: 0 0 1rem; font-size: 1.3em; text-transform: uppercase; letter-spacing: .04em; }
.cn-focus-icona { width: min(40vw, 11rem); height: min(40vw, 11rem); object-fit: contain; }
[data-theme="dark"] .cn-focus-icona { filter: invert(1); }
.cn-focus-cifre { font-size: clamp(3.5rem, 18vw, 7rem); font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.1; margin-top: 1rem; }
.cn-focus-stato { min-height: 1.4em; font-weight: 700; }
.cn-focus-tocca { font-weight: 400; }
.cn-focus-basso { display: flex; flex-direction: column; gap: .75rem; padding-bottom: 1rem; }
.cn-focus-riga { display: flex; gap: .6rem; min-height: 2.6rem; }
.cn-focus-riga .cn-btn { flex: 1 1 0; min-width: 0; font-weight: 700; }
.cn-focus-imp { display: flex; flex-direction: column; gap: .75rem; width: 100%; max-width: 28rem; }
.cn-focus-imp-riga { display: grid; grid-template-columns: 1fr 3rem 5.5rem 3rem; align-items: center; gap: .5rem; text-align: left; }
.cn-focus-imp-riga strong { text-align: center; }
.cn-focus-imp-riga .cn-btn { padding: .4rem 0; font-size: 1.2em; }
.cn-focus-imp-suoni .cn-btn { grid-column: 2 / 5; font-size: 1em; }
body.cn-focus-lampeggio { filter: invert(1); }

/* Icona del tipo nei riquadri degli scritti (2026-10-09, decisione dell'autore): in basso a sinistra, sulla stessa riga del titolo,
   nella homepage e nelle pagine delle sezioni; in "I tuoi scritti" all'inizio della riga sotto il titolo (.cn-project-tipo-icona). */
.cn-home-scritto-icona { width: 2.1em; height: 2.1em; object-fit: contain; flex-shrink: 0; }
.cn-project-tipo-icona { width: 1.25em; height: 1.25em; object-fit: contain; vertical-align: -.25em; margin-right: .4em; }
/* "I tuoi scritti": l'icona del tipo sta sulla riga dei pulsanti, a sinistra; sul telefono (riga a tutta larghezza) va al bordo sinistro. */
.cn-project-card-actions { align-items: center; }
.cn-project-card > .cn-project-tipo-icona { width: 2.1em; height: 2.1em; margin: 0; vertical-align: baseline; flex-shrink: 0; }
/* Liste della homepage con i pulsanti (Gioca, Appunti, Impara): il pulsante di esportazione a destra della riga. */
.cn-home-scritto-azioni { display: flex; gap: .35rem; flex-shrink: 0; align-items: center; }
.cn-home-scritto-azioni .cn-icon-btn { width: 1.9rem; height: 1.9rem; padding: 0; }
.cn-home-scritto-azioni [data-action="elimina"] .cn-icon { width: 1.25rem; height: 1.25rem; flex-shrink: 0; }
/* Telefono: con tanti pulsanti la riga va a capo e i pulsanti stanno sotto, a destra. */
@media (max-width: 40rem) {
  .cn-project-card.cn-home-scritto:has(.cn-home-scritto-azioni) { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: .8rem; row-gap: .5rem; align-items: center; }
  /* L'icona sta al centro di TUTTA la riga (testo e pulsanti insieme), non solo del testo (2026-10-10). */
  .cn-project-card.cn-home-scritto:has(.cn-home-scritto-azioni) > .cn-home-scritto-icona { grid-column: 1; grid-row: 1 / 3; }
  .cn-project-card.cn-home-scritto:has(.cn-home-scritto-azioni) > .cn-home-scritto-testo { grid-column: 2; grid-row: 1; }
  .cn-project-card.cn-home-scritto:has(.cn-home-scritto-azioni) > .cn-home-scritto-azioni { grid-column: 2; grid-row: 2; justify-self: end; }
  /* "I tuoi scritti": stessa cosa, l'icona al centro della scheda con i pulsanti sotto il testo. */
  .cn-project-card:has(> .cn-project-tipo-icona) { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: .75rem; row-gap: .5rem; align-items: center; }
  .cn-project-card > .cn-project-tipo-icona { grid-column: 1; grid-row: 1 / 3; }
  .cn-project-card:has(> .cn-project-tipo-icona) > .cn-project-card-top { grid-column: 2; grid-row: 1; }
  .cn-project-card:has(> .cn-project-tipo-icona) > .cn-project-card-actions { grid-column: 2; grid-row: 2; }
}
[data-theme="dark"] .cn-home-scritto-icona, [data-theme="dark"] .cn-project-tipo-icona { filter: invert(1); }


/* Avvio della pagina (2026-10-09): invisibile finché tema, carattere e barra non sono a posto (classe cn-avvio, tolta dallo script in
   <head> al DOMContentLoaded, cioè dopo tutti gli script della pagina, e solo quando i caratteri del sito sono arrivati: document.fonts.ready;
   se arrivavano dopo, i quadrati della homepage e le schede di Leggi cambiavano misura e il testo sotto saltava). Prima si mostrava comunque dopo 1,5 s: sul telefono, con la rete
   lenta, la pagina compariva prima degli script e poi si risistemava, e il testo saltava. Riserva di sicurezza a 8 s. */
html.cn-avvio body { visibility: hidden; }
html.cn-diario-attesa #viewport { visibility: hidden; }

/* Barra delle funzioni: un titolo della pagina uguale al nome della funzione accanto all'icona non si ripete (nascondiTitoliDoppi). */
.cn-toolbar .cn-title.cn-titolo-doppio { display: none; }

/* Modulo guidato per creare un mondo condiviso (writer/mondo-form.js, solo superadmin). */
.cn-mc-mappa { position: relative; width: 100%; max-width: 28rem; aspect-ratio: 1 / 1; margin: .5rem 0; border: 1px solid var(--cn-border); border-radius: .5rem; background: var(--cn-icon-bg); cursor: crosshair; touch-action: manipulation; }
.cn-mc-punto { position: absolute; transform: translate(-50%, -50%); width: 1.7rem; height: 1.7rem; padding: 0; border-radius: 50%; border: 2px solid var(--cn-accent); background: var(--cn-bg); color: var(--cn-text); font: inherit; font-size: .75em; line-height: 1; cursor: pointer; }
.cn-mc-punto.is-scelto { background: var(--cn-accent); color: var(--cn-btn-text); }
.cn-mc-citta { border: 1px solid var(--cn-border); border-radius: .5rem; padding: .7rem; margin: .9rem 0; }
.cn-mc-luogo { border-left: 3px solid transparent; padding: .3rem 0 .3rem .6rem; margin: .7rem 0; }
.cn-mc-luogo.is-scelto { border-left-color: var(--cn-accent); }
.cn-mc-vicini { display: flex; flex-wrap: wrap; gap: .3rem .9rem; }
.cn-mc-vicino { display: inline-flex; align-items: center; gap: .35rem; }
/* Breve descrizione di ogni categoria sotto i sei pulsanti dei visitatori (2026-10-12). */
/* Stessa distanza fra paragrafi e voci su tutta la homepage dei visitatori (2026-10-12). */
#hp-contenuto-editabile { --cn-hp-spazio: 1rem; }
#hp-contenuto-editabile .cn-hp-blocco-full, #hp-contenuto-editabile .cn-hp-cat { margin: 0 0 var(--cn-hp-spazio); }
#hp-contenuto-editabile #hp-testo-ecosistema p { margin: 0 0 var(--cn-hp-spazio); }
#hp-contenuto-editabile #hp-intro > div:has(> br:only-child) { display: none; }
#hp-contenuto-editabile #hp-intro > div + div { margin-top: var(--cn-hp-spazio); }
