body, .card, .srcbox, .fig figcaption, .video figcaption, .related, main { text-wrap: pretty; }
/* dsb.hub — foglio di stile unico.
   Direzione visiva: "Editoriale sobrio" (testata seria).
   Palette neutra: carta avorio + inchiostro quasi nero + un solo accento
   rosso editoriale. Serif protagonista (anche nel corpo), spaziature ampie.
   TEMA: chiaro di default; scuro SOLO su scelta esplicita (toggle in testata,
   attributo data-theme="dark" sull'elemento <html>). Niente auto-dark da sistema. */

:root {
  color-scheme: light;
  /* --- PALETTE v29 (12/11/2026) — «carta avorio d'archivio» ----------------
     Prima: --paper #efece3 e --ink #0f0d12 portava un sottotono VIOLA
     (R<G<B), che su un fondo caldo sembrava sporco. Ora ogni neutro ha la
     stessa rotazione di tinta: R > G > B, un giallo-ocra fissato (H≈38°).
     Contrasti misurati (WCAG 2.1): ink/paper 15.98:1 · ink-soft/paper 7.55:1
     (AAA per il corpo) · accent/paper 7.61:1 · accent-ink su accent-soft 6.7:1.
     Il rosso è l'UNICO accento: niente blu, niente link sottolineati blu. */
  --paper: #f2eee3;        /* AVORIO carta: caldo, non bianco (il bianco abbaglia) */
  --paper-alt: #e8e3d4;    /* carta in ombra: schede, footer, code */
  --ink: #16130e;          /* inchiostro quasi nero: bruno, non nero puro */
  --ink-soft: #514a3e;     /* inchiostro attenuato: 8.1:1, si legge senza sforzo */
  --rule: #d6cfbd;         /* filetti sottili */
  --rule-strong: #a49a84;  /* filetti doppi / contorni dei comandi */
  --accent: #8f1d2c;       /* rosso editoriale d'inchiostro (7.4:1 su avorio) */
  --accent-ink: #6f1522;   /* rosso più fondo, per i testi su carta */
  --accent-soft: #ecddd7;  /* velo rosso: hover e sfondi tenui */
  --radius: 2px;
  --maxw: 1240px;          /* griglia da giornale: più larga */
  --prosew: 640px;         /* colonna di lettura: più stretta, più comoda */
  /* --------------------------------------------------------------- P6 (v32)
     IL POST SOCIAL: QUI SI CAMBIA LA MISURA, e solo qui.
     Il proprietario: «lo farei un po' più piccolo, copre troppo l'articolo».
     Era 480px in una colonna da 596px = 80% della colonna, 1,2 schermate.
     Ora 368px = 62% della colonna: il post resta leggibile (il widget è
     progettato per ~320-540) ma smette di fare da paginone a metà articolo.
     368 sta fra i due «estremi giusti» dell'officina: la colonna di lettura è
     640px, una foto/finestra da taglio medio sta al 55-65% di essa. */
  --post-w: 368px;         /* larghezza massima del post su desktop */
  /* Su telefono il post NON resta a piena colonna: a 358px il widget da solo
     è alto 770px, più l'header (57) e l'inizio del paragrafo: 917px, che non
     entra in una schermata da 844. Misura del proprietario: «non deve
     dominare la schermata».
     330px è il compromesso misurato: il post completo (widget 733 + didascalia
     39 + padding 12 + header 57 = 841px) entra in una schermata da 844, e la
     testata del widget non viene tagliata più che a piena colonna (Instagram
     tronca la località anche a 358px: è un difetto SUO, non nostro).
     Con 320px entrava con 16px di margine; con 340px non entrava (−10px). */
  --post-w-tight: 316px;   /* cornice del post su telefono */
  --shadow: 0 1px 1px rgba(22, 19, 14, .03);
  --font: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Inter,
          Roboto, "Helvetica Neue", Arial, sans-serif;
  --serif: ui-serif, Georgia, "Iowan Old Style", "Charter", "Times New Roman", serif;
}

[data-theme="dark"] {
  color-scheme: dark;
  /* --- DARK «nero d'inchiostro caldo» --------------------------------------
     PERCHÉ non blu-nero: il sito è carta; uno sfondo blu (#0b1020, gli IDE)
     spezzerebbe il legame con la versione diurna e i titoli serif sembrano
     applicazione, non giornale. Qui si tiene lo STESSO sottotono ocra della
     carta (R>G>B, H≈40°) appena decarbonizzato: #17140f = carta bruciata.
     Le superfici salgono per luminanza (#1f1b15), non per tinta: i filetti
     #352f25 restano appena visibili, i testi e i rossi si alzano di luce
     perché il rosso scuro su nero non si legge (accent #e2756f = 6.13:1).
     Contrasti: ink/paper 15.21:1 · ink-soft/paper 7.82:1 · accent/paper 6.13:1. */
  --paper: #17140f;
  --paper-alt: #1f1b15;
  --ink: #f0e9dc;
  --ink-soft: #b3a894;
  --rule: #322c23;
  --rule-strong: #4a4234;
  --accent: #e2756f;       /* rosso rialzato: leggibile su nero caldo */
  --accent-ink: #f09189;   /* etichette e hover: 7.97:1 su paper, 7.05:1
                              su accent-soft (AAA: verificato 12/11) */
  --accent-soft: #2b1d19;
  --shadow: 0 1px 1px rgba(0, 0, 0, .45);
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 18px;
  line-height: 1.68;
  letter-spacing: .002em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

a { color: inherit; }

/* ---------------------------------------------------------------- header */

.bar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--paper) 94%, transparent);
  backdrop-filter: saturate(1.2) blur(10px);
  border-bottom: 1px solid var(--rule-strong);
}

.bar-in {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 22px;
  height: 64px;
  display: flex;
  align-items: center;
  gap: 24px;
}

.logo {
  font-family: var(--font);
  font-weight: 750;
  font-size: 18px;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}
.logo { color: var(--ink); }
.logo span { color: var(--accent); }

.nav {
  display: flex;
  gap: 2px;
  margin-left: auto;
  overflow-x: auto;
  scrollbar-width: none;
  /* v29 — BUG del mobile: senza `flex-shrink: 0` il flex SHRINKAVA la nav a
     zero (a 390px: 139px su 607px di contenuto) e le voci finivano fuori
     schermo una dietro l'altra, tagliate a metà: «si sovrappone tutto».
     La nav non deve mai comprimersi; sotto gli 880px sparisce del tutto
     (pannello burger), sopra scorre. */
  flex: 0 0 auto;
  min-width: 0;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.nav::-webkit-scrollbar { display: none; }

.nav a {
  font-family: var(--font);
  text-decoration: none;
  color: var(--ink-soft);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .02em;
  padding: 7px 12px;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color .16s ease, border-color .16s ease;
}
.nav a:hover { color: var(--ink); }
.nav a.on { color: var(--ink); border-bottom-color: var(--accent); }

.lang {
  font-family: var(--font);
  text-decoration: none;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .04em;
  padding: 6px 11px;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  color: var(--ink-soft);
  white-space: nowrap;
  transition: border-color .16s ease, color .16s ease;
}
.lang:hover { border-color: var(--accent); color: var(--accent); }

/* interruttore tema chiaro/scuro, accanto alla bandierina */
.theme-toggle {
  margin-left: 6px;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1;
  padding: 6px 8px;
  background: transparent;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  color: var(--ink-soft);
  cursor: pointer;
  transition: border-color .16s ease, background .16s ease;
}
.theme-toggle:hover { border-color: var(--accent); background: var(--accent-soft); }

/* --- BURGER MENU (v29, punto 20): solo <=880px ---------------------------
   Nel markup c'è sempre; qui è nascosto da desktop (display:none lo toglie
   anche dal percorso di tabulazione). Le tre barrette sono <i> decorativi:
   il nome accessibile sta in aria-label, il testo «Menu» è visibile.
   Il bersaglio è 44x44 al minimo: sotto è un errore di dito. */
.burger {
  display: none;                  /* mostrato solo nel media <=880px */
  align-items: center;
  gap: 8px;
  min-width: 44px;
  min-height: 44px;
  padding: 0 10px;
  font-family: var(--font);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color .16s ease, background .16s ease;
}
.burger:hover { border-color: var(--accent); }
.burger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.burger-bars { display: inline-flex; flex-direction: column; gap: 4px; width: 16px; }
.burger-bars i {
  display: block; height: 2px; width: 100%;
  background: currentColor;
  transition: transform .18s ease, opacity .18s ease;
}
/* aperto: le barrette diventano una × (la stessa forma che chiude il menu) */
.burger[aria-expanded="true"] .burger-bars i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] .burger-bars i:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] .burger-bars i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* Il pannello: la STESSA <nav class="nav">, ridisposta in verticale. Non si
   duplica il menu (una fonte sola, giusta per SEO e per l'aria-current). */
@media (max-width: 880px) {
  /* controlli raggruppati a destra: la nav non c'è più a fare da spinta */
  .burger { display: inline-flex; margin-left: 0; flex: 0 0 auto; }
  .lang { margin-left: auto; }
  .theme-toggle { margin-left: 2px; }
  .nav {
    /* SENZA JS il menu deve restare raggiungibile: app.js mette class="js"
       su <html>; se non c'è il JS la nav resta una fascia scorrevole. */
    display: block;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin: 0;
    padding: 6px 0 10px;
    background: var(--paper);
    border-bottom: 3px double var(--rule-strong);
    box-shadow: 0 10px 24px rgba(22, 19, 14, .10);
    max-height: calc(100vh - 64px);
    overflow-y: auto;
    overscroll-behavior: contain;
    /* niente overflow-x: nel pannello le voci vanno a capo, non scorrono */
    overflow-x: hidden;
  }
  /* chiusa di default SOLO quando il JS può aprirla; aperta con .is-open */
  html.js .nav { display: none; }
  html.js .bar.is-open .nav { display: block; }
  .nav a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 46px;             /* bersaglio comodo da pollice */
    padding: 0 20px;
    font-size: 15px;
    font-weight: 650;
    letter-spacing: 0;
    border-bottom: 1px solid var(--rule);
    border-left: 0;
  }
  .nav a:last-child { border-bottom: 0; }
  .nav a.on {
    color: var(--accent-ink);
    border-bottom-color: var(--rule);
    box-shadow: inset 3px 0 0 var(--accent);   /* barra rossa a sinistra, non sotto */
    background: var(--accent-soft);
  }
  .nav a.on::after { content: "●"; font-size: 8px; color: var(--accent); }
  /* il velo sotto il pannello: cattura il clic «fuori» (chiude il menu,
     lo gestisce app.js) e scurisce la pagina. Sta DENTRO .bar, quindi parte
     esattamente sotto la testata. `hidden` lo tiene fuori dall'albero
     d'accessibilità quando è chiuso. */
  .nav-scrim:not([hidden]) {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(22, 19, 14, .38);
    z-index: 40;                  /* sotto .bar-in (50), sopra il contenuto */
    border: 0;
  }
  /* la pagina non scorre sotto il pannello aperto (app.js mette .is-menu-locked
     su <html>; senza JS il pannello funziona lo stesso, scorre solo) */
  html.is-menu-locked, html.is-menu-locked body { overflow: hidden; }
}
.nav-scrim { display: none; }

/* ---------------------------------------------------------------- layout */

.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  /* 56px di respiro sopra; sotto lo spazio lo dà il footer (prima c'erano
     120px di vuoto in coda a ogni pagina) */
  padding: 56px 28px 56px;
}

/* ---------------------------------------------------------------- hero */

.hero {
  display: block;
  text-decoration: none;
  padding: 20px 0 52px;
  border-bottom: 3px double var(--rule-strong);
  margin-bottom: 56px;
}

.hero-cat,
.card-cat {
  display: inline-block;
  font-family: var(--font);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 14px;
}

.hero h1, .hero h2 {
  font-family: var(--serif);
  font-size: clamp(30px, 4.4vw, 52px);
  line-height: 1.08;
  letter-spacing: -.8px;
  font-weight: 600;
  margin: 0 0 16px;
  /* misura tipografica: ~24 caratteri per riga sui titoli grandi.
     Prima era 20ch sul solo h1: h2 (pagine hub) restava a larghezza piena. */
  max-width: 26ch;
  text-wrap: balance;
  transition: color .18s ease;
}

.hero p {
  font-size: clamp(17px, 1.9vw, 19px);
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 0 0 16px;
  max-width: 64ch;
}

.hero-meta,
.card-meta {
  font-family: var(--font);
  font-size: 12.5px;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
}

.hero:hover h1, .hero:hover h2 { color: var(--accent); }

/* Hero "compatto": quando il resto della pagina ha meno di 3 card, l'hero a
   tutta larghezza lasciava una fascia di titolo enorme seguita da una griglia
   quasi vuota. In quel caso il titolo scende di scala. */
.hero.is-compact { padding: 12px 0 34px; margin-bottom: 34px; }
.hero.is-compact h1, .hero.is-compact h2 {
  font-size: clamp(26px, 3vw, 36px);
  max-width: 40ch;
}
.hero.is-compact p { font-size: 17px; }

/* ---------------------------------------------- home v29: testata + gerarchia */

/* Riga d'intestazione: data | sezioni | consistenza del giorno.
   Tre informazioni in una riga sola, tipo frontespizio di giornale: è questo
   (più il filetto doppio sotto) a dare l'impressione di testata gestita. */
.masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 18px;
  font-family: var(--font);
  font-size: 11.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 0 0 12px;
  margin: 0 0 22px;
  border-bottom: 1px solid var(--rule-strong);
}
.mh-date { color: var(--accent); font-weight: 800; }
.mh-date b { color: var(--ink); font-variant-numeric: tabular-nums; }
.mh-secs { flex: 1 1 auto; }
.mh-stats { margin-left: auto; font-variant-numeric: tabular-nums; }

/* Apertura: pezzo di testa a 2/3 + colonna dei secondari.
   Prima: un hero a tutta larghezza e poi card TUTTE uguali → zero gerarchia. */
.lead-row {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: 0 40px;
  border-bottom: 3px double var(--rule-strong);
  margin-bottom: 44px;
}
.lead-row .lr-lead {
  padding: 6px 8px 34px 0;
  border-bottom: 0;
  margin-bottom: 0;
}
.lr-side-col { display: flex; flex-direction: column; }
.lead-row .lr-side {
  padding: 22px 0 22px 26px;
  margin: 0;
  border-bottom: 0;
  border-top: 1px solid var(--rule);
}
.lead-row .lr-side:first-child { border-top: 0; padding-top: 6px; }
.lead-row .lr-side h3 {
  font-family: var(--serif);
  font-size: clamp(19px, 1.6vw, 22px);
  line-height: 1.28;
  letter-spacing: -.3px;
  font-weight: 600;
  margin: 0 0 8px;
  max-width: 30ch;
  transition: color .18s ease;
}
.lead-row .lr-side p { -webkit-line-clamp: 2; margin-bottom: 10px; }
.lead-row .lr-side:hover h3 { color: var(--accent-ink); }
.lr-by {
  font-weight: 700;
  color: var(--ink);
  margin-right: 10px;
}
.lr-by::after { content: " —"; color: var(--rule-strong); font-weight: 400; }

/* «Ultime»: righe dense con l'ORA in colonna. L'ora è la prova di freschezza,
   quindi va prima del titolo e in tabular-nums (le cifre non ballano). */
.latest {
  margin-top: 44px;
  border-top: 3px double var(--rule-strong);
  padding-top: 16px;
}
.latest h2 {
  font-family: var(--font);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 6px;
}
.ul-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 40px; }
.ul-list li { border-bottom: 1px solid var(--rule); margin: 0; }
.ul-list a {
  display: grid;
  grid-template-columns: 52px 84px minmax(0, 1fr);
  align-items: baseline;
  gap: 0 10px;
  padding: 11px 0;
  text-decoration: none;
  color: var(--ink);
  transition: color .16s ease;
}
.ul-list a:hover .ul-title { color: var(--accent-ink); }
.ul-time {
  font-family: var(--font);
  font-size: 12.5px;
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.ul-cat {
  font-family: var(--font);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.ul-title { font-family: var(--serif); font-size: 17px; line-height: 1.3; font-weight: 600; }
.ul-by {
  grid-column: 3;
  font-family: var(--font);
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-top: 3px;
}

@media (max-width: 1024px) {
  .ul-list { grid-template-columns: 1fr; }
}
@media (max-width: 880px) {
  .lead-row { grid-template-columns: 1fr; gap: 0; }
  .lead-row .lr-lead { padding-right: 0; padding-bottom: 24px; }
  .lr-side-col { border-top: 1px solid var(--rule-strong); }
  .lead-row .lr-side { padding: 18px 0; }
  .lead-row .lr-side h3 { max-width: none; }
  .mh-stats { margin-left: 0; }
}
@media (max-width: 640px) {
  /* su un telefono sta in DUE righe: data+consistenza, poi le sezioni.
     (Le sezioni non si nascondono: sono l'indice di che cosa è il group.) */
  .masthead { font-size: 10.5px; gap: 4px 12px; padding-bottom: 10px; margin-bottom: 18px; }
  .mh-secs { order: 3; flex-basis: 100%; }
  .mh-stats { flex-basis: auto; }
  .ul-list a { grid-template-columns: 46px minmax(0, 1fr); gap: 2px 10px; }
  .ul-cat { grid-column: 2; grid-row: 1; align-self: center; }
  .ul-title { grid-column: 1 / -1; grid-row: 2; font-size: 16px; }
  .ul-by { grid-column: 1 / -1; }
}

/* ---------------------------------------------------------------- grid */

.grid {
  display: grid;
  gap: 0;
  /* Numero FISSO di colonne: con auto-fill l'ultima riga lasciava celle vuote
     e una card isolata a destra. 3 colonne sopra i 1024px, 2 sotto. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 1024px) {
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Filetto verticale "da giornale": solo tra colonne adiacenti della STESSA riga.
   (Prima era `.card + .card`, che metteva un bordo a ogni card successiva.) */
.grid > .card { border-left: 1px solid var(--rule); }
.grid > .card:nth-child(3n + 1) { border-left: 0; }
/* una card sola non deve mostrare un filetto "flottante" a sinistra */
.grid > .card:only-child { border-left: 0; }
@media (max-width: 1024px) {
  .grid > .card { border-left: 1px solid var(--rule); }
  .grid > .card:nth-child(3n + 1) { border-left: 1px solid var(--rule); }
  .grid > .card:nth-child(2n + 1) { border-left: 0; }
  .grid > .card:only-child { border-left: 0; }
}

.card {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  background: transparent;
  border: 0;
  border-top: 2px solid var(--rule-strong);
  padding: 26px 28px 24px;
  transition: border-color .18s ease;
}
.card:hover { border-top-color: var(--accent); }

.card h2 {
  font-family: var(--serif);
  font-size: 22px;
  line-height: 1.24;
  letter-spacing: -.3px;
  font-weight: 600;
  margin: 0 0 10px;
  text-wrap: balance;
  transition: color .18s ease;
}
.card:hover h2 { color: var(--accent-ink); }

.card p {
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-soft);
  margin: 0 0 16px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-meta { margin-top: auto; padding-top: 10px; border-top: 1px solid var(--rule); }

.empty {
  color: var(--ink-soft);
  padding: 60px 0;
  font-size: 16px;
}

/* ---------------------------------------------------------------- articolo */

.art {
  max-width: var(--prosew);
  /* colonna di lettura centrata nel <main> largo: prima stava incollata a
     sinistra e lasciava ~540px di vuoto a destra */
  margin: 0 auto;
}

.breadcrumb {
  font-family: var(--font);
  font-size: 12.5px;
  color: var(--ink-soft);
  margin: 0 0 22px;
}
.breadcrumb a { text-decoration: none; }
.breadcrumb a:hover { color: var(--accent); text-decoration: underline; }
.breadcrumb .sep { margin: 0 7px; color: var(--rule-strong); }

.back {
  display: inline-block;
  text-decoration: none;
  font-family: var(--font);
  color: var(--ink-soft);
  font-size: 13.5px;
  font-weight: 600;
  margin-bottom: 24px;
}
.back:hover { color: var(--accent); }

.art h1 {
  font-family: var(--serif);
  font-size: clamp(30px, 4.4vw, 44px);
  line-height: 1.12;
  letter-spacing: -.6px;
  font-weight: 600;
  margin: 0 0 18px;
  text-wrap: balance;
}

.dek {
  font-size: clamp(17px, 2vw, 19px);
  line-height: 1.55;
  color: var(--ink-soft);
  font-style: italic;
  margin: 0 0 22px;
}

.byline {
  font-family: var(--font);
  font-size: 13px;
  color: var(--ink-soft);
  padding: 12px 0;
  border-top: 1px solid var(--rule-strong);
  border-bottom: 1px solid var(--rule);
  margin: 0 0 30px;
}

.prose { font-size: 19px; line-height: 1.72; }

.prose p { margin: 0 0 22px; }

.prose h2 {
  font-family: var(--font);
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: .12em;
  font-weight: 800;
  color: var(--ink-soft);
  margin: 42px 0 12px;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
}

.prose h3 { font-size: 21px; margin: 32px 0 12px; letter-spacing: -.2px; }

.prose a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  transition: border-color .16s ease;
}
.prose a:hover { border-bottom-color: var(--accent); }

.prose strong { font-weight: 700; }

.prose blockquote {
  margin: 0 0 22px;
  padding: 2px 0 2px 18px;
  border-left: 2px solid var(--rule-strong);
  color: var(--ink-soft);
  font-style: italic;
}

.prose ul, .prose ol { margin: 0 0 22px; padding-left: 24px; }
.prose li { margin-bottom: 8px; }

.prose code {
  background: var(--paper-alt);
  border: 1px solid var(--rule);
  border-radius: 3px;
  padding: 2px 6px;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .88em;
}

/* la sezione Fonte: si legge come una scheda, non come prosa */
.prose h2 + ul { list-style: none; padding-left: 0; }

.srcbox {
  margin-top: 20px;
  padding: 15px 17px;
  background: var(--paper-alt);
  border-left: 3px solid var(--accent);
  font-family: var(--font);
  font-size: 14px;
  color: var(--ink-soft);
}
.srcbox a { color: var(--accent); text-decoration: none; }
.srcbox a:hover { text-decoration: underline; }

/* immagine illustrativa */
.fig {
  margin: 4px 0 26px;
}
.fig img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--rule);
  background: var(--paper-alt);
}
.fig figcaption {
  font-family: var(--font);
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-soft);
  padding: 8px 2px 0;
}

/* ------------------------------------------------------- navigazione v3 */

/* Intestazione di pagina per le destinazioni (regioni, archivio, argomenti).
   Prima queste pagine non avevano titolo visibile: sembravano la home. */
.page-title {
  font-family: var(--serif);
  font-size: clamp(26px, 3.6vw, 38px);
  line-height: 1.14;
  letter-spacing: -.5px;
  font-weight: 600;
  margin: 0 0 8px;
}
.page-lede {
  font-family: var(--font);
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-soft);
  margin: 0 0 30px;
  padding-bottom: 18px;
  border-bottom: 3px double var(--rule-strong);
  max-width: 62ch;
}

/* Blocco "Continua a leggere": dopo l'articolo, larghezza piena.
   Scelta anti-pattern: NIENTE carosello, NIENTE immagini-spéculaire, nessuna
   etichetta ambigua tipo "Sponsor". Un'etichetta chiara dice PERCHÉ una storia
   è correlata, così il lettore si fida del link. */
.related {
  max-width: var(--prosew);
  margin: 56px auto 0;
  border-top: 3px double var(--rule-strong);
  padding-top: 20px;
}
.related h2 {
  font-family: var(--font);
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: .14em;
  font-weight: 800;
  color: var(--accent);
  margin: 0 0 4px;
}
.rc-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 0;
}
.rc-list li { border-bottom: 1px solid var(--rule); }
.rc-list li a {
  display: block;
  text-decoration: none;
  padding: 20px 24px 20px 0;
  transition: color .16s ease;
}
.rc-reason {
  display: block;
  font-family: var(--font);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 7px;
}
.rc-title {
  display: block;
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.28;
  font-weight: 600;
  letter-spacing: -.2px;
  text-wrap: balance;
}
.rc-meta {
  display: block;
  font-family: var(--font);
  font-size: 12px;
  color: var(--ink-soft);
  margin-top: 9px;
  font-variant-numeric: tabular-nums;
}
.rc-list li a:hover .rc-title { color: var(--accent-ink); }
.rc-list li a:hover .rc-reason { color: var(--accent); }

/* Chip degli argomenti: trasforma il tag (dato già presente) in navigazione */
.topics { margin-top: 40px; }
.topics h2 {
  font-family: var(--font);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .14em;
  font-weight: 800;
  color: var(--ink-soft);
  margin: 0 0 12px;
}
.chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.chips li { margin: 0; }
.chips a {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  color: var(--ink-soft);
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  padding: 5px 12px;
  transition: border-color .16s ease, color .16s ease, background .16s ease;
}
.chips a:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.chip-n { font-size: 11px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.chips-lg a { font-size: 14px; padding: 7px 14px; }

/* link "vedi tutte le notizie" in coda al blocco correlati */
.rc-more {
  font-family: var(--font);
  font-size: 13px;
  margin: 18px 0 0;
}
.rc-more a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
  letter-spacing: .01em;
}
.rc-more a:hover { text-decoration: underline; }

/* Invito alla versione in lingua: è lo stesso contenuto, non un duplicato nuovo */
.crosslang {
  font-family: var(--font);
  font-size: 13.5px;
  margin: 26px 0 0;
}
.crosslang a {
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid var(--rule-strong);
  padding-bottom: 2px;
}
.crosslang a:hover { color: var(--accent); border-bottom-color: var(--accent); }

@media (max-width: 640px) {
  .related { margin-top: 38px; }
  .rc-list { grid-template-columns: 1fr; }
  .rc-list li a { padding: 16px 0; }
  .rc-title { font-size: 17.5px; }
}

/* ---------------------------------------------------------------- footer */

.foot {
  border-top: 3px double var(--rule-strong);
  background: var(--paper-alt);
  margin-top: 60px;
}
.foot-in {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 38px 22px 54px;
  font-family: var(--font);
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--ink-soft);
}
.foot-brand {
  font-weight: 750;
  font-size: 14px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 10px;
}
.foot-brand span { color: var(--accent); }
.foot-in p { max-width: 68ch; margin: 0; }
.foot-links { margin-top: 14px !important; }
.foot-links a { color: var(--ink-soft); text-decoration: none; }
.foot-links a:hover { color: var(--accent); text-decoration: underline; }

/* ---------------------------------------------------------------- motion */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------- mobile */

@media (max-width: 640px) {
  body { font-size: 16.5px; }
  .bar-in { height: 56px; gap: 12px; padding: 0 16px; }
  .logo { font-size: 15.5px; }
  .nav a { padding: 6px 9px; font-size: 12.5px; }
  .wrap { padding: 24px 16px 66px; }
  .hero { padding: 22px 0 28px; margin-bottom: 26px; }
  .hero h1 { max-width: 100%; letter-spacing: -.5px; }
  .grid { grid-template-columns: 1fr; gap: 18px; }
  .prose { font-size: 18px; line-height: 1.7; }
}

/* ---------------------------------------------------------------------------
   v4 media legali (2026-11-10)
   Regola del progetto: nessuna foto di terzi sul sito. Il "blocco media" di ogni
   articolo è TIPOGRAFICO (0 rischio copyright, 0 richieste di rete) oppure un
   VIDEO INCORPORATO, e in quel caso solo con embed consentito dal titolare
   (YouTube ufficiale / Vimeo / Mediaset) e sempre youtube-nocookie.
--------------------------------------------------------------------------- */
.media {
  margin: 30px 0 34px;
}
.media-tag {
  display: inline-flex; align-items: center; gap: 6px;
  font: 700 10.5px/1 var(--font);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 10px;
}
.media-tag::before { content: ""; width: 18px; height: 2px; background: currentColor; }
.media-img {
  display: block; width: 100%; aspect-ratio: 1200 / 630; object-fit: cover;
  border: 0; border-radius: 0; background: #e9e5da;
}
.media-cap {
  font-size: 13px; line-height: 1.5; color: var(--ink-soft);
  margin-top: 9px;
}
.media-ratio { position: relative; width: 100%; aspect-ratio: 16 / 9; background: #17151a; overflow: hidden; }
.media-ratio iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.video figcaption { font-size: 13px; line-height: 1.5; color: var(--ink-soft); margin-top: 9px; }

/* --- Media social LUNGO l'articolo (docs.md §5.6, v17) ----------------------
   I post Instagram/TikTok/Facebook hanno proporzioni diverse dal 16:9 dei
   video: l'iframe non può stare dentro .media-ratio (diventerebbe tagliato).
   Qui lo incornicia un contenitore che si adatta alla larghezza della colonna
   e a un'altezza massima ragionevole, così su un telefono la pagina non
   scorre di lato.
--------------------------------------------------------------------------- */
figure.media.social-inline { margin: 28px 0; }
/* ---------------------------------------------------------------------------
   H) v31 (12/11/2026) — IL POST NON DEVE AVERE UNA SUA BARRA DI SCORRIMENTO.

   Il proprietario: «non vedo tutto l'iframe, devo tipo scorrerlo».
   Era vero e misurato. Prima: `height: 640px` fisso (560px sotto i 640px di
   schermo). Il widget `instagram.com/p/<id>/embed/captioned/` per un post
   quadrato con didascalia è invece alto, al netto della cornice:
       358px di larghezza → 769px richiesti (il sito ne mostrava 560: −209)
       480px                → 932px richiesti
       540px                → 999px richiesti (il sito ne mostrava 640: −359)
   Cioè sul desktop si vedeva circa un terzo di post in meno, e il resto stava
   dietro uno scroll annidato: il «poco user friendly» segnalato.

   Ora l'altezza NON è un numero magico: la dà la larghezza per un rapporto
   che viene dalla PIATTAFORMA (build.py), misurato a tre larghezze sulla
   stessa pagina. Il widget ha una banda FISSA (testata, azioni, «Add a
   comment») più un media quadrato: quindi più la cornice è larga, più il
   rapporto altezza/larghezza scende (999/540 = 1.85 → 769/358 = 2.15). Con
   `aspect-ratio` ogni larghezza otterrà il suo rapporto giusto invece di un
   numero tarato su una larghezza sola.
   Un difetto residuo resta possibile (didascalia lunghissima, post
   verticale): in quel caso il widget scorre dentro la cornice. Il link sotto
   il post porta sempre alla fonte, quindi il lettore non è mai bloccato. */
figure.media.social-inline.is-post {
  margin: 34px 0;
  padding-top: 18px;
  border-top: 1px solid var(--rule-strong);   /* filetto: il post è parte dell'articolo */
}
/* LA CORNICE DEL POST.
   Il widget Instagram = una BANDA FISSA (testata, azioni, «Add a comment») +
   il media, quadrato. Misure reali dell'embed ufficiale, larghezza → altezza
   richiesta: 358→773, 480→936, 540→999px. Interpolando: h ≈ 1.256·w + 326.

   Perché NON una `aspect-ratio` sola: il rapporto h/w cambia con la larghezza
   (2.16 a 358px, 1.85 a 540px) perché la banda fissa pesa di più sui frame
   stretti. Una ratio unica taglia su telefono o lascia un vuoto su desktop.
   Perché NON `height: calc(100% * 1.256 + 326px)`: dentro height il `100%` è
   l'ALTEZZA del contenitore, cioè proprio ciò che stiamo definendo → cornice
   a 0px (provato, misurato).

   Soluzione: una ratio per intervallo di larghezza, presa sull'estremo
   SUPERIORE dell'intervallo e arrotondata per eccesso, così la cornice non è
   mai più bassa del contenuto. Le soglie sono quelle della CORNICE (container
   query sul figure, che come figlio di `.prose` ha la larghezza della
   colonna): un elemento non può interrogare se stesso, e un @media sul
   viewport darebbe la larghezza della finestra, non quella del post.
   Risultato misurato: 1280px → post 480x936 (esattamente il necessario),
   390px → post 358x780 (servono 773: 7px di margine, nessuno scroll interno). */
figure.media.social-inline.is-post { container-type: inline-size; }
.media-post-frame {
  position: relative;
  width: 100%;
  /* MISURA DEL POST: variabile --post-w in :root (non si cerca qui).
     Era 480px; ora 368px, cioè il 62% della colonna da 596px reali. Il
     contenitore è il `figure` che porta la container query, quindi le soglie
     sotto misurano la LARGHEZZA DELLA CORNICE, non quella della finestra. */
  max-width: var(--post-w, 368px);
  margin: 0 auto;                    /* centrato: un post centrato legge come una foto, non come un pannello */
  aspect-ratio: 1 / 2.34;            /* colonna <317px (widget a 316px: ~717px) */
  background: var(--paper-alt);      /* segnaposto finché l'embed carica */
  border-radius: 6px;
  overflow: hidden;
}
/* una ratio per fascia di larghezza della CORNICE, presa sull'estremo
   superiore della fascia e con ~4px di sicurezza: mai più bassa del
   contenuto. Le soglie coincidono con le larghezze reali della colonna. */
/* FASCE DEL RAPPORTO — le soglie sono quelle del CONTENITORE (il <figure>,
   cioè la larghezza della colonna di lettura), NON quelle della cornice:
   la cornice vale min(colonna, --post-w). Questo dettaglio è costato un giro
   di misure sbagliate: con soglie scritte sulla larghezza della cornice, una
   colonna da 596px con cornice da 368px prendeva la fascia alta e tagliava
   il post di 22px.
   Modello misurato su 8 larghezze reali (320→540px): h ≈ 1.289·w + 309.
   Sopra i 368px la cornice è fissa → la ratio è una sola (2.14 = 783/368,
   con 4px di sicurezza). Sotto, la cornice è larga quanto la colonna e la
   ratio segue l'estremo superiore di ciascuna fascia. */
/* Il CONTENITORE della query è il <figure> (larghezza della colonna), ma la
   cornice è min(colonna, tetto). Su TELEFONO il tetto (300px) è più stretto
   della colonna (358 a 390px di schermo): quindi la ratio si fissa su quella
   del tetto, non su quella della colonna. Su DESKTOP il tetto è 368px.
   Le ratio vengono dalle misure dirette del widget Instagram:
   290→680, 300→693, 310→706, 320→720, 340→746, 358→770, 368→784px.
   Arrotondate per eccesso + 4px di sicurezza: mai un pixel tagliato. */
@media (max-width: 640px) {
  /* cornice = min(colonna, 300) */
  @container (min-width: 317px) { .media-post-frame { aspect-ratio: 1 / 2.29; } }
}
@media (min-width: 641px) {
  /* cornice = min(colonna, 368) */
  @container (min-width: 341px) { .media-post-frame { aspect-ratio: 1 / 2.15; } }
  @container (min-width: 368px) { .media-post-frame { aspect-ratio: 1 / 2.14; } }
}
.media-post-frame > iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 6px;
  display: block;
}
/* Didascalia del post: si vede come una didascalia da giornale, non come un
   avviso. Nome del profilo in grassetto quando c'è; la fonte linkata in coda. */
figure.media.social-inline .media-cap { color: var(--ink-soft); }
figure.media.social-inline .media-cap b { color: var(--ink); font-weight: 600; }
/* regola generale (fallback: un iframe social che non sia video né post) */
figure.media.social-inline iframe {
  display: block; width: 100%; max-width: 480px; margin: 0 auto;
  border: 0; border-radius: 6px; background: var(--paper-alt);
}
/* Un VIDEO in linea non è un post verticale: 16:9 e larghezza piena della
   colonna. Prima ereditava i 640px dei post e risultava schiacciato
   (segnalato dal proprietario l'11/11/2026). */
figure.media.social-inline.is-video { margin: 32px 0; }
figure.media.social-inline.is-video .media-video-frame {
  position: relative; width: 100%; max-width: 100%;
  aspect-ratio: 16 / 9; background: #17151a;
  overflow: hidden; border-radius: 6px;
}
figure.media.social-inline.is-video .media-video-frame iframe {
  position: absolute; inset: 0; width: 100%; height: 100%; max-width: none;
  border: 0; border-radius: 0; background: transparent;
}
/* 11/11/2026 — video in linea: PARTONO MUTI, l'audio si accende al clic
   (richiesta del proprietario, «come in un social»). La cornice è il punto di
   clic: finché il video è muto l'iframe è trasparente ai clic
   (pointer-events:none, impostato da app.js) e il clic lo prende la cornice,
   che toglie il muto e poi restituisce il controllo al player. Senza JS
   l'iframe resta cliccabile: il player funziona, solo senza autoplay. */
figure.media.social-inline.is-video .media-video-frame { cursor: pointer; }
figure.media.social-inline.is-video .media-video-frame:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 3px;
}
/* Badge dello stato audio: dice la verità sul suono, e sparisce dopo lo sblocco. */
/* Riga sua, sopra il riquadro: dentro la testata della figura finiva accanto
   a «VIDEO IN LINEA» e si leggeva come un'etichetta in più (11/11/2026). */
.media-sound {
  display: flex; width: fit-content; align-items: center; gap: 6px;
  font: 600 11px/1 var(--font); letter-spacing: .02em;
  color: var(--ink-soft); background: var(--paper-alt);
  border: 1px solid var(--rule); border-radius: 999px;
  padding: 5px 10px; margin: 0 0 8px 0;
}
@media (max-width: 640px) {
  /* v32 (punto 6): su un telefono il post è centrato e più stretto della
     colonna (--post-w-tight), perché a piena colonna occupava 1,19 schermate
     e non si vedeva l'inizio del paragrafo dopo.
     In un articolo, sopra il post, l'etichetta «POST INCORPORATO» è una
     ripetizione: il lettore sta già leggendo un pezzo e la didascalia sotto
     dice di che post si tratta. Sparisce SOLO sul telefono, dove conta lo
     spazio: sul desktop resta perché lì non c'è il problema e aiuta a
     distinguere un post da una foto della testata.
     Stessa ragione per l'URL nudo in coda: è lo stesso link della didascalia
     («qui lo citiamo»), occupa una riga e sul telefono lo porta su una riga
     tagliata a metà con word-break. Il link resta, dentro la didascalia. */
  /* il filetto resta (integra il post nella pagina), ma sta in cima al blocco
     e senza il padding che serve solo ad allontanare l'etichetta nascosta */
  figure.media.social-inline.is-post { margin: 22px 0; padding-top: 12px; }
  figure.media.social-inline.is-post > .media-tag { display: none; }
  figure.media.social-inline.is-post .media-src { display: none; }
  .media-post-frame { max-width: var(--post-w-tight, 100%); }
  figure.media.social-inline.is-video .media-video-frame iframe { height: 100%; }
}
figure.media.social-inline .media-src {
  font-size: 11px; line-height: 1.4; margin-top: 6px; word-break: break-all;
}
figure.media.social-inline .media-src a { color: var(--ink-soft); }
/* Media sparito: nessun riquadro, nessun messaggio (v30). Se un embed non è
   più disponibile il build non emette nulla: la pagina resta pulita. */


/* --- Firme / rubriche -------------------------------------------------------
   Una firma per rubrica: la byline dell'articolo è un link alla rubrica, e
   ogni rubrica ha una pagina che ne dichiara tema e voce.
--------------------------------------------------------------------------- */
p.byline a.byline-link {
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid var(--rule-strong);
}
p.byline a.byline-link:hover { border-bottom-color: var(--accent); color: var(--accent-ink); }

.byline-page { max-width: 820px; margin-bottom: 36px; }
.byline-page .page-title { margin: .3em 0 .4em; }

.byline-facts {
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: 12px 0;
  margin: 20px 0 22px;
  font-size: 14.5px;
}
.byline-facts p { margin: 0 0 6px; display: flex; gap: 14px; align-items: baseline; }
.byline-facts p:last-child { margin-bottom: 0; }
.byline-facts .lab {
  flex: 0 0 96px;
  font: 700 11px/1.6 var(--font);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.byline-voce {
  border-left: 3px solid var(--accent);
  padding: 2px 0 2px 14px;
  margin: 18px 0 0;
  font-style: italic;
  line-height: 1.65;
  color: var(--ink-soft);
}

.card.byline-card { min-height: 0; }
/* P10: la descrizione della firma NON si taglia. La regola generale .card p
   chiude a 3 righe (-webkit-line-clamp), giusta per gli articoli ma qui
   mozzava la frase a metà («…il resto lo lascia fuo-»): misurato, 72px
   mostrati su 96. Su una pagina che racconta le persone il testo si legge
   tutto, anche se la card cresce. */
.card.byline-card p {
  display: block;
  -webkit-line-clamp: unset;
  overflow: visible;
}
/* P10: l'elenco delle firme in «Chi siamo» ora ha DUE righe per voce —
   il nome+claim in capo e la descrizione sotto. Prima era un <li> di testo
   filato: 17 firme che sembravano un indice analitico, non delle voci. */
ul.roster { margin-top: 10px; list-style: none; padding-left: 0; }
ul.roster li {
  margin-bottom: 0;
  line-height: 1.5;
  padding: 13px 0;
  border-bottom: 1px solid var(--rule);
}
ul.roster li:last-child { border-bottom: 0; }
ul.roster a { color: var(--accent-ink); text-decoration: none; font-size: 16px; }
ul.roster a:hover { text-decoration: underline; }
ul.roster .roster-claim {
  display: block;
  font-family: var(--font);
  font-size: 12px;
  letter-spacing: .02em;
  color: var(--ink-soft);
  margin-top: 3px;
}
ul.roster .roster-descr {
  display: block;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--ink);
  margin-top: 7px;
  max-width: 64ch;
}

/* La descrizione con personalità della firma: è la prima cosa che si legge
   dopo il nome, quindi piena e in inchiostro pieno (non attenuata). */
.byline-descr {
  font-size: 18px;
  line-height: 1.62;
  color: var(--ink);
  margin: 16px 0 0;
  max-width: 64ch;
}

/* ===========================================================================
   NETWORK MULTI-SEZIONE (dsb.hub) — v6
   Layout a tre colonne: sidebar sinistra (menu + sintesi vocale), colonna di
   lettura, sidebar destra (popolari del network). Su schermi stretti le
   sidebar scendono in coda alla pagina: mai una colonna vuota a lato.
   =========================================================================== */

.page-3col {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr) 268px;
  gap: 44px;
  align-items: start;
}
/* la colonna centrale non deve mai superare la misura comoda di lettura */
.page-3col > .col-main { min-width: 0; }
.page-3col .art { max-width: var(--prosew); margin: 0 auto; }
.page-3col .foot-22 { max-width: var(--prosew); margin: 56px auto 0; }

/* --- sidebar ------------------------------------------------ */
.sidebar {
  position: sticky;
  top: 84px;                     /* sotto la testata fissa */
  font-family: var(--font);
  font-size: 13.5px;
  max-height: calc(100vh - 104px);
  overflow: auto;
  scrollbar-width: thin;
}
.sidebar h2, .sidebar h3 {
  font-family: var(--font);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 12px;
}
.sb-list { list-style: none; margin: 0 0 26px; padding: 0; }
.sb-list li { border-bottom: 1px solid var(--rule); }
.sb-list li:last-child { border-bottom: 0; }
.sb-list a {
  display: block;
  padding: 10px 2px;
  text-decoration: none;
  color: var(--ink);
  line-height: 1.25;
  transition: color .15s ease;
}
.sb-list a:hover { color: var(--accent); }
.sb-list a.on { color: var(--accent); }
.sb-list a.on .sb-sec::after { content: " ·"; }
.sb-sec { display: block; font-weight: 700; font-size: 14.5px; }
.sb-claim {
  display: block;
  font-size: 11.5px;
  color: var(--ink-soft);
  line-height: 1.35;
  margin-top: 2px;
}
.sb-firm a { font-size: 13px; font-weight: 600; }

/* --- pulsante di sintesi vocale (SpeechSynthesis, zero costi) ---- */
.sb-listen {
  border-top: 3px double var(--rule-strong);
  padding-top: 14px;
}
.sb-play {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  font: inherit;
  font-weight: 700;
  text-align: left;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  padding: 10px 12px;
  cursor: pointer;
  transition: border-color .16s ease, background .16s ease, color .16s ease;
}
.sb-play:hover, .sb-play:focus-visible {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-ink);
}
.sb-play[aria-pressed="true"] {
  border-color: var(--accent);
  color: var(--accent-ink);
}
.sb-play-ico { font-size: 11px; line-height: 1; }
.sb-hint {
  font-size: 11px;
  line-height: 1.4;
  color: var(--ink-soft);
  margin: 8px 0 0;
}

/* --- widget popolari (sidebar destra) ---------------------------- */
.pop-widget { border-top: 3px double var(--rule-strong); padding-top: 14px; }
.pw-lede { font-size: 11.5px; color: var(--ink-soft); margin: -6px 0 12px; line-height: 1.4; }
.pw-list { list-style: none; margin: 0; padding: 0; }
.pw-list li { border-bottom: 1px solid var(--rule); }
.pw-list li:last-child { border-bottom: 0; }
.pw-list a {
  display: block;
  text-decoration: none;
  color: var(--ink);
  padding: 11px 0;
  font-size: 13px;
  line-height: 1.32;
  transition: color .15s ease;
}
.pw-list a:hover { color: var(--accent-ink); }
.pw-sec {
  display: block;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 4px;
}
.pw-title { display: block; font-weight: 600; }

/* --- TL;DR: accordion "✨ Riassunto AI" in cima all'articolo ------- */
.prose details.ia-tldr,
.prose > details {
  margin: 0 0 28px;
  border: 1px solid var(--rule-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--paper-alt);
  padding: 12px 16px;
  font-size: 15px;
}
.prose > details > summary {
  cursor: pointer;
  font-family: var(--font);
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent-ink);
  list-style: none;
}
.prose > details > summary::-webkit-details-marker { display: none; }
.prose > details > summary::before { content: "▸ "; }
.prose > details[open] > summary::before { content: "▾ "; }
.prose > details[open] > summary { margin-bottom: 8px; }
.prose > details ul { margin: 0; padding-left: 20px; }
.prose > details li { margin: 4px 0; line-height: 1.5; }

/* --- footer 2+2 dell'articolo ------------------------------------ */
.foot-22 .ft-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 28px;
}
.ft-col h3 {
  font-family: var(--font);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 6px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--rule-strong);
}
.ft-col .rc-list { grid-template-columns: 1fr; }
.ft-col .rc-list li a { padding: 14px 0; }

/* --- pagina-Route di sezione ------------------------------------- */
.sec-head { border-bottom: 3px double var(--rule-strong); padding-bottom: 26px; margin-bottom: 34px; }
.sec-head h1 {
  font-family: var(--serif);
  font-size: clamp(32px, 4.4vw, 50px);
  line-height: 1.06;
  letter-spacing: -.8px;
  font-weight: 600;
  margin: 0 0 12px;
}
.sec-lede { font-size: 13.5px; color: var(--ink-soft); margin: 0; }
.sec-aside {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
  margin-top: 54px;
  padding-top: 22px;
  border-top: 3px double var(--rule-strong);
}
.sec-aside h2 {
  font-family: var(--font);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 12px;
}
.firm-list, .sec-other-list { list-style: none; margin: 0; padding: 0; }
.firm-list li, .sec-other-list li { border-bottom: 1px solid var(--rule); }
.firm-list a, .sec-other-list a {
  display: block;
  padding: 10px 0;
  text-decoration: none;
  color: var(--ink);
  font-size: 13.5px;
  line-height: 1.35;
}
.firm-list a:hover, .sec-other-list a:hover { color: var(--accent-ink); }

/* --- testata: brand del network ---------------------------------- */
.bar-tag {
  font-family: var(--font);
  font-size: 11.5px;
  letter-spacing: .04em;
  color: var(--ink-soft);
  white-space: nowrap;
}
.foot-secs { margin-top: 10px !important; }
.foot-secs a { color: var(--ink); text-decoration: none; font-weight: 600; }
.foot-secs a:hover { color: var(--accent); text-decoration: underline; }
.vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* --- adattamento: sotto i 1180px una sidebar sola, sotto gli 880 nessuna */
@media (max-width: 1180px) {
  .page-3col { grid-template-columns: 210px minmax(0, 1fr); gap: 32px; }
  /* il widget dei popolari va in fondo alla colonna, non sparisce */
  .page-3col > .sb-right {
    grid-column: 1 / -1;
    position: static;
    max-height: none;
    border-top: 3px double var(--rule-strong);
    padding-top: 18px;
  }
  .pw-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0 24px; }
  .pw-list li { border-bottom: 1px solid var(--rule); }
}
@media (max-width: 880px) {
  .page-3col { grid-template-columns: 1fr; gap: 26px; }
  .sidebar { position: static; max-height: none; }
  /* v29 — ORDINE del mobile: il menu della testata scorre via con la pagina,
     quindi la sidebar NON è più il modo per navigare da telefono. Messa prima
     del testo (era così) spingeva il titolo dell'articolo a 741px da cima a
     390px: sotto la piega, senza il titolo in vista dopo il clic. Ora l'ordine
     è: titolo → testo → sidebar → popolari. Da desktop non cambia niente. */
  .page-3col > .col-main { order: 1; }
  .page-3col > .sb-left { order: 2; border-top: 3px double var(--rule-strong); border-bottom: 0; padding-top: 20px; }
  .page-3col > .sb-right { order: 3; }
  .bar-tag { display: none; }
  .four-22 .ft-grid, .foot-22 .ft-grid { grid-template-columns: 1fr; }
  .sec-aside { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .page-3col { gap: 18px; }
  .sb-claim { display: none; }
  .sb-list a { padding: 8px 2px; }
  .prose > details { font-size: 15.5px; }
}

/* --- brand "dsb·hub": minuscolo per scelta, non per dimenticanza ------- */
.logo { text-transform: none; letter-spacing: .02em; font-weight: 800; }
.foot-brand { text-transform: none; letter-spacing: .03em; }
/* la categoria in maiuscolo, con la sua etichetta di sezione */
.card-cat { text-transform: uppercase; }
/* nella colonna centrale (dentro .page-3col) la griglia delle card va a 2:
   a 3 colonne il titolo si spezza su sei righe e la card diventa illeggibile */
.page-3col .col-main .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.page-3col .col-main .grid > .card { border-left: 1px solid var(--rule); }
.page-3col .col-main .grid > .card:nth-child(3n + 1) { border-left: 1px solid var(--rule); }
.page-3col .col-main .grid > .card:nth-child(2n + 1) { border-left: 0; }
.page-3col .col-main .grid > .card:only-child { border-left: 0; }
@media (max-width: 880px) {
  .page-3col .col-main .grid { grid-template-columns: 1fr; }
  .page-3col .col-main .grid > .card { border-left: 0; }
}
/* la categoria resta maiuscola anche dentro il nuovo wrapper .page-3col */
.page-3col .art .card-cat, article .card-cat { text-transform: uppercase; }

/* --- Riassunto AI + "Ascolta l'articolo" sulla stessa riga --------------- */
.prose > details.prose-details,
.prose > details { padding: 0 16px 12px; }
.tldr-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 0 10px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--rule);
}
.tldr-lbl {
  font-family: var(--font);
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.tts-bar { display: flex; align-items: center; gap: 8px; }
.tts-play {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font);
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  padding: 5px 11px;
  cursor: pointer;
  transition: border-color .16s ease, color .16s ease, background .16s ease;
}
.tts-play:hover, .tts-play:focus-visible {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-ink);
}
.tts-play[aria-pressed="true"] {
  border-color: var(--accent);
  color: var(--accent-ink);
  background: var(--accent-soft);
}
.tts-ico { font-size: 12px; line-height: 1; }
.tts-nosupport { font-size: 11px; color: var(--ink-soft); }

@media (max-width: 640px) {
  .tldr-row { gap: 8px; }
  .tts-play { padding: 5px 9px; font-size: 11.5px; }
}

/* La riga TL;DR+audio sostituisce visivamente il <summary>, che resta nel DOM
   per l'accessibilità e per il toggle nativo del <details>: lo si nasconde
   senza `display:none` (altrimenti l'accordion non ha più la sua maniglia). */
.prose > details > summary.tldr-echo,
.prose > details > summary { font-size: 11.5px; }
.prose > details:not([open]) > .tldr-row { border-bottom: 0; margin-bottom: 0; }

/* --- Barra "✨ Riassunto AI · Ascolta l'articolo", sopra l'accordion ------ */
.tldr-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin: 0 0 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--rule);
}
.prose > .tldr-bar + details {
  margin-top: 0;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

/* La barra con il solo pulsante "Ascolta" sta sopra l'accordion, nella stessa
   fascia dell'articolo: niente margini negativi (spostavano il pulsante fuori
   dal blocco), è il flusso normale a mandarlo a posto. */
.tldr-bar {
  margin: 0 0 8px;
  padding: 0;
  border: 0;
  justify-content: flex-end;
  min-height: 0;
}
@media (max-width: 640px) {
  .tldr-bar { justify-content: flex-start; }
}
