/* ═══════════════════════════════════════════════════════════════════════════
   NOTE DE REVUE — 2026-08-19  (à lire avant de « corriger » font-display)

   Un audit a signalé que « font-display n'est déclaré nulle part » et
   recommandé de passer les 8 @font-face en `swap`. C'EST FAUX, et le
   correctif serait une régression. Vérifié dans le build SERVI
   (dist_release_v17/fonts/fonts.css) : les 8 @font-face portent bien
   `font-display: optional`, et le fichier servi est identique à celui-ci.

   `optional` n'est pas un oubli, c'est le choix qui rend le CLS DÉTERMINISTE :
     · `auto`/`block` bloque le texte jusqu'à ~3 s  → LCP retardé
     · `swap`  affiche le repli puis PERMUTE        → reflow → CLS mesuré
                                                      0,13-0,30 sur IT/NL/BE/
                                                      DK/NO/CZ/GB
     · `optional` : la police est préchargée ; prête sous ~100 ms elle
       s'affiche sans permutation, sinon le repli est gardé POUR LA SESSION.
       Jamais de blocage, jamais de permutation, donc jamais de CLS de police.

   Le texte n'est donc à AUCUN moment bloqué 3 s : la prémisse de l'audit
   décrit le comportement de `auto`, pas celui qui est en place. Les @font-face
   de repli à métriques ajustées (plus bas) sont ce qui rend `optional`
   acceptable visuellement — ils ne sont pas « inutilisés », ils sont
   précisément ce qui s'affiche quand la webfont n'arrive pas à temps.

   → NE PAS remplacer `optional` par `swap` sans une mesure de CLS AVANT/APRÈS
     sur les pays concernés.

   ─── LE GAIN A ÉTÉ PRIS — MAIS PAS COMME ANNONCÉ (2026-08-19, mesuré) ───────

   La note précédente recommandait de figer `opsz=18` pour passer Newsreader de
   240 Ko à 74 Ko, « à rendu strictement identique ». La prémisse était FAUSSE
   et le correctif aurait été une régression typographique sur tout le site.

   POURQUOI : `font-optical-sizing` vaut `auto` PAR DÉFAUT en CSS. Le navigateur
   pilote donc l'axe `opsz` tout seul, en le fixant à la taille de police en px,
   SANS qu'aucune règle ne mentionne `opsz`. L'axe n'était pas « payé pour
   rien » : il était utilisé en permanence. Mesure (fontTools, wght=400) de
   l'écart entre l'instance figée à 18 et l'instance que le navigateur applique
   réellement :

       opsz auto      largeur de « Simuler ma toiture »   glyphes d'avance
       (= taille px)  vs opsz figé à 18                   modifiée /262
       ─────────────────────────────────────────────────────────────────
       14 px          -8,71 %                             233
       24 px          -1,08 %                             226
       32 px          -2,50 %                             229
       40 px          -3,89 %                             229
       48 px          -5,20 %                             231

   Or les tailles réellement utilisées avec `font-serif` vont de `text-xs`
   (12 px) à `clamp(3.5rem,8vw,6.5rem)` (104 px) : la quasi-totalité du texte
   Newsreader du site aurait changé de chasse, donc de césure de ligne — et le
   metrics-override des fallbacks ci-dessous, calibré sur xAvg=1087, aurait
   dérivé. ⇒ NE PAS FIGER `opsz`. NE PAS POSER `font-optical-sizing: none`.

   CE QUI A ÉTÉ APPLIQUÉ À LA PLACE — restriction du seul axe `wght`, à la
   plage que ces @font-face déclarent (400 800). Les graisses hors plage sont
   INATTEIGNABLES : le navigateur clampe toute demande dans l'intervalle déclaré
   par la @font-face, donc Newsreader 200-400 et Inter 100-400 ne pouvaient
   jamais être instanciés. Les retirer est neutre PAR CONSTRUCTION.

       Newsreader  wght 200-800 → 400-800   (opsz 6-72 INTACT)
       Inter       wght 100-900 → 400-800

       newsreader-latin.woff2        132 000 →  98 636 o   (-25,3 %)  [préchargé]
       newsreader-latin-ext.woff2     86 608 →  63 144 o   (-27,1 %)
       newsreader-vietnamese.woff2    27 248 →  19 976 o   (-26,7 %)
       inter-latin.woff2              48 256 →  37 000 o   (-23,3 %)  [préchargé]
       inter-latin-ext.woff2          85 068 →  60 924 o   (-28,4 %)
       inter-cyrillic.woff2           18 748 →  13 592 o   (-27,5 %)
       inter-greek.woff2              18 996 →  13 708 o   (-27,8 %)
       inter-vietnamese.woff2         10 252 →   7 984 o   (-22,1 %)
       ──────────────────────────────────────────────────────────────
       total 8 fichiers              427 176 → 314 964 o   (-112 212 o)
       dont chemin critique (2 préchargés sur CHAQUE page)  -44 620 o

   PREUVE DE NON-RÉGRESSION (et non « rendu supposé identique ») : pour chaque
   fichier, chaque graisse déclarée (400/500/600/700/800) et 8 valeurs d'`opsz`
   (12→72), les contours et les avances ont été ré-instanciés avant/après et
   comparés glyphe à glyphe — 145 points de grille au total :
       · écart d'avance horizontale ................. 0 unité (Newsreader)
                                                      1 unité /2048 (Inter)
       · écart de contour max ....................... 0,75 unité /2000
                                                      = 0,018 px à 48 px
       · ascent/descent/lineGap/upm/usWin* .......... identiques
       · nombre de glyphes et couverture cmap ....... identiques
       · axe `opsz` .................................. conservé 6-72

   Commande de reproduction (fontTools ≥ 4.61, venv du dépôt) :
       from fontTools.ttLib import TTFont
       from fontTools.varLib import instancer
       t = TTFont(f); instancer.instantiateVariableFont(t, {'wght': (400, 800)},
                       inplace=True, updateFontNames=False)
       t.flavor = 'woff2'; t.save(f)
   ⚠ `pyftsubset --instance=…` n'existe pas : l'instanciation partielle passe
     par `fontTools.varLib.instancer`, pas par le subsetter.

   Si un jour une graisse < 400 est réellement voulue, il faut RE-TÉLÉCHARGER la
   police complète : elle n'est plus dans ces fichiers.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Self-hosted fonts — Sprint #11B RGPD/CLS fix ───────────────────────
   Source: Google Fonts v20 (Inter) / v26 (Newsreader) — downloaded 2026-06-01
   Avantages: pas de requête vers google.com/gstatic.com → conformité RGPD
               + élimination du render-blocking CDN → améliore LCP/CLS
   ─────────────────────────────────────────────────────────────────────── */

/* ── INTER ── */

/* cyrillic */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: optional;
  src: url('/fonts/inter-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: optional;
  src: url('/fonts/inter-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: optional;
  src: url('/fonts/inter-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: optional;
  src: url('/fonts/inter-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;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: optional;
  src: url('/fonts/inter-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;
}

/* ── NEWSREADER ── */

/* vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400 800;
  font-display: optional;
  src: url('/fonts/newsreader-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400 800;
  font-display: optional;
  src: url('/fonts/newsreader-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;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400 800;
  font-display: optional;
  src: url('/fonts/newsreader-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;
}

/* ─── ZÉRO-CLS FALLBACK FONTS (SENIOR perf/CLS — 2026-06-08) ──────────────────
   Avant le swap de la webfont, le navigateur affiche un fallback système. Si
   ses métriques verticales (ascent/descent/line-gap) et son avance moyenne
   diffèrent de la webfont, le bloc de texte change de hauteur au swap → reflow
   = CLS, et l'élément LCP texte « recompte » tard. On déclare des familles
   fallback adossées à des polices SYSTÈME (local(), 0 octet réseau) auxquelles
   on impose les métriques de la webfont via metrics-override → la line-box est
   IDENTIQUE avant/après swap → ZÉRO reflow.

   Valeurs calculées à partir des métriques RÉELLES extraites des .woff2 :
     Newsreader  upm=2000 asc=1470 desc=-530 gap=0 xAvg=1087
     Inter       upm=2048 asc=1984 desc=-494 gap=0 xAvg=1250
   et des métriques publiées (capsize) de Georgia / Arial.
   size-adjust = (web.xAvg/web.upm)/(fb.xAvg/fb.upm) ; ascent/descent/line-gap
   overrides = (web.metric/web.upm)/size-adjust.

   font-display: optional (SENIOR perf/CLS — 2026-06-09) — le metrics-override
   réduit le reflow MAIS ne le neutralise pas à 100% selon les glyphes/pays (CLS
   live IT/NL/BE/DK/NO/CZ/GB 0.13-0.30). « optional » est DÉTERMINISTE : la
   webfont est préchargée (<link rel=preload> latin) → si prête dans la fenêtre
   de blocage (~100ms) elle s'affiche SANS swap ; sinon le navigateur garde le
   fallback POUR TOUTE LA SESSION → ZÉRO swap → ZÉRO reflow → ZÉRO CLS de police.
   Les @font-face fallback ci-dessous (metrics-override) restent ESSENTIELS :
   ils rendent le fallback visuellement proche de la webfont quand il est utilisé
   toute la session sur connexion lente/cold cache. */

/* Fallback Newsreader → Georgia (serif). */
@font-face {
  font-family: 'Newsreader-fallback';
  src: local('Georgia');
  size-adjust: 93.38%;
  ascent-override: 78.71%;
  descent-override: 28.38%;
  line-gap-override: 0%;
}

/* Fallback Inter → Arial (sans-serif). */
@font-face {
  font-family: 'Inter-fallback';
  src: local('Arial');
  size-adjust: 111.21%;
  ascent-override: 87.11%;
  descent-override: 21.69%;
  line-gap-override: 0%;
}
