/* ============================================================
   FONT — 20 dichiarazioni @font-face, 8 file.
   ============================================================
   Le tre famiglie sono font VARIABILI: un solo file contiene tutti i
   pesi. Fino alla v2026.08.19 lo stesso file era però spedito una volta
   per peso, con nomi diversi (Montserrat-400-normal-latin.woff2,
   -600-, -700-, -800-: quattro URL, quattro download, un solo file
   byte-identico). Il browser non può saperlo: vede quattro indirizzi e
   li scarica tutti. Sulla home erano 407 KB di font su 747 KB di
   pagina — il 55%.

   Ora ogni famiglia+stile+intervallo ha UN file, e le dichiarazioni per
   peso restano tutte: puntano allo stesso `src`, quindi il download è
   uno solo e la resa è identica a prima (il peso lo sceglie l'asse
   variabile, come già faceva). Regola per chi tocca questo file:
   **il peso non compare più nel nome del file**. Se serve un peso nuovo
   si aggiunge una regola @font-face, non un file.

   font-display (19/08/2026, PERF-4): Montserrat e Fraunces sono
   `optional`, JetBrains Mono resta `swap`. `optional` significa: se il
   file non è pronto in ~100ms la pagina si disegna col ripiego e il
   font NON entra più in corsa — niente scambio, niente salto, e alla
   pagina dopo è in cache. Vale per i due font PRECARICATI (v. il
   <link rel=preload> in gen.py §4): sono quelli che la corsa la
   vincono quasi sempre. Il mono non è precaricato, quindi `optional`
   lo cancellerebbe dalla prima visita: gli basta il ripiego a metriche
   identiche qui sotto, che non fa saltare niente nemmeno scambiando.

   Da NON fare senza misurare: fare il subset dei glifi rende solo l'8%
   (33 KB in tutto) e costa una dipendenza `fonttools` nella build;
   fissare l'asse `opsz` di Fraunces rende molto di più ma il testo in
   Fraunces va da 14px a 66px, quindi un solo valore ottico è sbagliato
   agli estremi. Misurato il 19/08/2026, v. CHANGELOG.
   ============================================================ */

@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 400;
  font-display: optional;
  src: url('../fonts/Fraunces-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 400;
  font-display: optional;
  src: url('../fonts/Fraunces-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 600;
  font-display: optional;
  src: url('../fonts/Fraunces-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 600;
  font-display: optional;
  src: url('../fonts/Fraunces-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/JetBrainsMono-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/JetBrainsMono-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/JetBrainsMono-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/JetBrainsMono-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  font-style: italic;
  font-weight: 400;
  font-display: optional;
  src: url('../fonts/Montserrat-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: italic;
  font-weight: 400;
  font-display: optional;
  src: url('../fonts/Montserrat-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  font-style: italic;
  font-weight: 600;
  font-display: optional;
  src: url('../fonts/Montserrat-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: italic;
  font-weight: 600;
  font-display: optional;
  src: url('../fonts/Montserrat-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-display: optional;
  src: url('../fonts/Montserrat-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-display: optional;
  src: url('../fonts/Montserrat-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 600;
  font-display: optional;
  src: url('../fonts/Montserrat-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 600;
  font-display: optional;
  src: url('../fonts/Montserrat-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  font-display: optional;
  src: url('../fonts/Montserrat-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  font-display: optional;
  src: url('../fonts/Montserrat-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 800;
  font-display: optional;
  src: url('../fonts/Montserrat-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 800;
  font-display: optional;
  src: url('../fonts/Montserrat-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ------------------------------------------------------------
   Fallback con le metriche di Montserrat (PERF-4, 19/08/2026)
   ------------------------------------------------------------
   Finché il woff2 non è arrivato il testo si disegna col font di
   sistema, che NON ha l'ingombro di Montserrat: i titoli lunghi
   vanno a capo una riga in più (o in meno) e, quando il font vero
   entra, la pagina fa un salto. Su /servizi/marketing/seo-geo.html
   valeva da solo CLS 0,122 — sopra la soglia «buono» di Google —
   con un unico scatto a 241ms: l'h1 passava da 4 righe a 3.

   Qui si dichiara una famiglia finta che prende i glifi da Arial
   (su Linux Chromium risolve `local('Liberation Sans')`, che ha le
   metriche di Arial) e li riscala perché occupino esattamente lo
   spazio di Montserrat:
     size-adjust      = larghezza Montserrat / larghezza del ripiego,
                        misurata a 100px su una riga di testo vero;
     ascent/descent   = metriche di Montserrat (96,8% e 25,1%)
                        divise per size-adjust: dopo il riscalamento
                        tornano quelle, quindi la riga è alta uguale.

   Perché QUATTRO dichiarazioni e non una: Arial ha due soli tagli
   (tondo e nero) mentre Montserrat è variabile, e il divario di
   larghezza cambia col peso — 108,8% a 400, 107,0% a 600, 108,7% a
   700, 110,0% a 800. Con un valore solo i titoli (peso 800, gli
   unici che vanno a capo su più righe) restano fuori del 2%, ed è
   bastato a far saltare /servizi/consulenza-ai.html di 76px. Gli
   intervalli coprono i quattro pesi usati in main.css: 400, 600,
   700, 800. Se se ne aggiunge uno, si aggiunge anche qui — con il
   numero MISURATO, non stimato (v. CHANGELOG per come).

   Va PRIMA di system-ui nello stack: `--font` in main.css.
   ------------------------------------------------------------ */
@font-face {
  font-family: 'Montserrat fallback';
  font-weight: 1 500;
  src: local('Arial'), local('Helvetica'), local('Liberation Sans');
  size-adjust: 108.8%;
  ascent-override: 89.0%;
  descent-override: 23.1%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Montserrat fallback';
  font-weight: 501 650;
  src: local('Arial Bold'), local('Arial-BoldMT'), local('Helvetica Bold'), local('Liberation Sans Bold');
  size-adjust: 107.0%;
  ascent-override: 90.5%;
  descent-override: 23.5%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Montserrat fallback';
  font-weight: 651 750;
  src: local('Arial Bold'), local('Arial-BoldMT'), local('Helvetica Bold'), local('Liberation Sans Bold');
  size-adjust: 108.7%;
  ascent-override: 89.1%;
  descent-override: 23.1%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Montserrat fallback';
  font-weight: 751 1000;
  src: local('Arial Bold'), local('Arial-BoldMT'), local('Helvetica Bold'), local('Liberation Sans Bold');
  size-adjust: 110.0%;
  ascent-override: 88.0%;
  descent-override: 22.8%;
  line-gap-override: 0%;
}

/* ------------------------------------------------------------
   Fallback con le metriche di JetBrains Mono (PERF-4)
   ------------------------------------------------------------
   Il monospaziato è il caso facile: tutti i glifi hanno lo stesso
   avanzamento, quindi basta trovarne uno con lo stesso passo e le
   larghezze combaciano al pixel, senza size-adjust. JetBrains Mono
   avanza 0,6em; Courier New pure (su Linux Chromium risolve
   `local('Liberation Mono')`, stesso passo). Resta da pareggiare
   l'altezza della riga: JetBrains Mono è 1,32em (ascent 102%,
   descent 30%), Courier New 1,13em.

   Non è teoria: le chip del blog sono in mono e, quando il font
   entrava, passavano da 32 a 34px di altezza e la loro riga si
   ricomponeva da due righe a una — la griglia degli articoli
   risaliva di 28px. Da sola: CLS 0,121 su /blog.html.
   Va PRIMA di ui-monospace nello stack: `--mono` in main.css.
   ------------------------------------------------------------ */
@font-face {
  font-family: 'JetBrains Mono fallback';
  src: local('Courier New'), local('CourierNewPSMT'), local('Liberation Mono'), local('DejaVu Sans Mono');
  ascent-override: 102%;
  descent-override: 30%;
  line-gap-override: 0%;
}
