/* ==========================================================================
   SKYNET — COUCHE INTERNATIONALE
   Écritures non latines (arabe · japonais · coréen · chinois) + latin étendu
   (polonais) + miroir droite-à-gauche.

   Créé le 07/08/2026. Fondé sur les rapports ninja du 06/08 (polices + RTL),
   relus et intégrés par Claudia (le CSS global lui appartient).

   · Chargée UNIQUEMENT par les pages traduites (injectée par _i18n-generer.py
     juste avant </head>), APRÈS les 4 feuilles de marque. Le français n'en a
     pas besoin : Poppins couvre le latin.
   · ZÉRO ressource externe : polices SYSTÈME du visiteur + sous-ensembles
     Poppins auto-hébergés. CSP stricte et RGPD intacts.
   · Le tri se fait par :lang() et [dir] — aucune page latine n'est affectée.
   ========================================================================== */

/* ──────────────────────────────────────────────────────────────────────────
   1. POLONAIS — rendre à Poppins ses ł ż ą ę ś ć ń ź
   🔴 CES 5 FICHIERS N'EXISTENT TOUJOURS PAS — mesuré le 09/08/2026.
      `find . -name "*latinext*"` → aucun résultat, nulle part dans le projet.

   CE QUE ÇA CASSE EXACTEMENT, et il faut être précis :
   Nos `poppins-*-latin.woff2` pèsent 7,8 Ko et déclarent `U+0000-00FF` —
   du Latin-1 STRICT. Ils ne contiennent donc PAS ł ą ę ś ż ź ć ń (polonais).
   Ces caractères retombent sur une police SYSTÈME.

   ⚠️ ET C'EST UN « FAUX VERT » PARFAIT : sur Windows, le repli est proche de
      Poppins et la page polonaise paraît impeccable. Sur un Mac, un Linux ou
      un Windows plus ancien, le repli sera visiblement différent — mélange de
      deux dessins de lettres DANS LE MÊME MOT (« zespół » : le ó en Poppins,
      le ł en police de secours).
      → Ça marche ICI. Ça ne veut pas dire que ça marche.

   POURQUOI ON GARDE CES 5 RÈGLES malgré tout : elles sont JUSTES, et elles
   fonctionneront le jour où les fichiers arriveront. Les retirer donnerait
   l'illusion d'un problème réglé alors que le polonais retomberait toujours.
   Le coût actuel est borné : grâce à `unicode-range`, seuls les navigateurs
   affichant du latin étendu les demandent — donc les visiteurs POLONAIS, et
   eux seuls, subissent 5 requêtes en échec.

   CE QU'IL FAUT DÉPOSER (≈ 8 Ko chacun, même origine que les 5 latin déjà
   présents, licence SIL Open Font — Poppins est libre) :
      assets/fonts/poppins-400-latinext.woff2
      assets/fonts/poppins-500-latinext.woff2
      assets/fonts/poppins-600-latinext.woff2
      assets/fonts/poppins-700-latinext.woff2
      assets/fonts/poppins-800-latinext.woff2
      (sous-ensembles OFL, ~10 Ko pièce, téléchargés UNE FOIS au build).
      TANT QU'ILS NE SONT PAS LÀ : le polonais retombe sur la police système
      (comportement actuel, aucune régression). Dès qu'ils sont posés, les
      diacritiques polonais passent en Poppins automatiquement.
   L'unicode-range garantit que les visiteurs FR/EN/DE ne téléchargent RIEN
   de plus : seuls les navigateurs affichant du latin étendu les demandent.
   ────────────────────────────────────────────────────────────────────────── */
@font-face{font-family:"Poppins";font-style:normal;font-weight:400;font-display:swap;
  src:url(fonts/poppins-400-latinext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0300-0303,U+0305-0307,U+0309-0328,U+032A-0370,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Poppins";font-style:normal;font-weight:500;font-display:swap;
  src:url(fonts/poppins-500-latinext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0300-0303,U+0305-0307,U+0309-0328,U+032A-0370,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Poppins";font-style:normal;font-weight:600;font-display:swap;
  src:url(fonts/poppins-600-latinext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0300-0303,U+0305-0307,U+0309-0328,U+032A-0370,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Poppins";font-style:normal;font-weight:700;font-display:swap;
  src:url(fonts/poppins-700-latinext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0300-0303,U+0305-0307,U+0309-0328,U+032A-0370,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Poppins";font-style:normal;font-weight:800;font-display:swap;
  src:url(fonts/poppins-800-latinext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0300-0303,U+0305-0307,U+0309-0328,U+032A-0370,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

/* ──────────────────────────────────────────────────────────────────────────
   2. LES PILES PAR ÉCRITURE — on surcharge --police, écriture par écriture
   Poppins RESTE en tête : son unicode-range la cantonne au latin, donc
   « SkyNet », « TellMiz », « ESN » et les chiffres restent dans la police de
   marque au milieu du texte étranger. Cohérence visuelle gratuite.
   « Poppins repli » (une Arial aux métriques latines forcées) DISPARAÎT des
   piles non latines : sous Windows, Arial contient l'arabe et l'attraperait
   avec des hampes coupées.
   ────────────────────────────────────────────────────────────────────────── */
:root:lang(ar){--police:"Poppins","Segoe UI","Noto Sans Arabic","Geeza Pro",Tahoma,Arial,sans-serif}
:root:lang(ja){--police:"Poppins","Hiragino Sans","Hiragino Kaku Gothic ProN","Yu Gothic","Meiryo","Noto Sans JP",sans-serif}
:root:lang(ko){--police:"Poppins","Apple SD Gothic Neo","Malgun Gothic","Noto Sans KR",sans-serif}
:root:lang(zh-Hans),:root:lang(zh){--police:"Poppins","PingFang SC","Microsoft YaHei","Noto Sans SC",sans-serif}

/* ──────────────────────────────────────────────────────────────────────────
   3. ARABE — neutraliser le tracking, aérer les lignes
   L'arabe est CURSIF : chaque lettre se lie à la suivante. Le resserrage
   optique des titres et le tracking .16em des kickers insèrent des blancs
   DANS les mots et disloquent l'écriture. letter-spacing:0 obligatoire.
   Et les voyelles courtes (fatha, kasra…) vivent au-dessus/en dessous de la
   ligne : à 1.02-1.15 elles mordent la ligne voisine.
   ────────────────────────────────────────────────────────────────────────── */
:lang(ar) :is(h1,h2,h3,h4,h5,.display,.titre-xl,.titre-md,.kicker,.sur-titre,
  .bande-tech-titre,.pied h4,th,.frise-item .quand,.cine-mot,.cine-fin-detail){letter-spacing:0}
:lang(ar) :is(h1,h2,h3,.display,.titre-xl,.titre-md){line-height:1.35}
:lang(ar) body{line-height:1.9}

/* ──────────────────────────────────────────────────────────────────────────
   4. CJK — de l'air, et pas de faux-gras
   Les polices CJK système n'ont pas de graisse 800 : le navigateur fabrique
   un faux-gras hideux sur les idéogrammes. On plafonne à 700.
   Le CJK sans espaces entre mots a besoin de plus d'interligne.
   ────────────────────────────────────────────────────────────────────────── */
:lang(ja) :is(h1,h2,h3,h4,h5,.display,.titre-xl),
:lang(ko) :is(h1,h2,h3,h4,h5,.display,.titre-xl),
:lang(zh) :is(h1,h2,h3,h4,h5,.display,.titre-xl){font-weight:700;letter-spacing:0}
:lang(ja) body,:lang(ko) body,:lang(zh) body{line-height:1.8}
:lang(ko){word-break:keep-all}   /* sinon les mots hangul se coupent n'importe où */

/* ──────────────────────────────────────────────────────────────────────────
   5. MIROIR DROITE-À-GAUCHE (arabe)
   Écrit en propriétés LOGIQUES (inline-start/end) : identiques en FR, seul
   l'arabe bascule, zéro média query, zéro régression sur les 11 autres langues.
   Trois cas n'ont pas de forme logique (dégradé orienté, glyphe ‹›, flèche) :
   override [dir="rtl"] explicite.
   ────────────────────────────────────────────────────────────────────────── */

/* B4/B5 — alignements de texte codés à gauche → logique */
:lang(ar) :is(th,td),
[dir="rtl"] :is(th,td,caption,.tableau-wrap caption){text-align:start}

/* B5 — le parcours numéroté mobile : rail et pastilles du bon côté */
@media(max-width:860px){
  [dir="rtl"] .parcours::before{inset-inline-start:21px;inset-inline-end:auto;left:auto;right:auto}
  [dir="rtl"] .etape{text-align:start;padding-inline-start:68px;padding-left:0}
  [dir="rtl"] .etape::before{inset-inline-start:0;left:auto;transform:none;top:0}
}

/* G1 — fil d'Ariane : le chevron pointe dans le sens de lecture */
[dir="rtl"] .fil li+li::before{content:"‹";margin-inline-end:var(--s2);margin-right:0}

/* G2 — puces des listes : réserve et carré côté début de ligne */
[dir="rtl"] .liste li{padding-inline-start:1.6rem;padding-left:0}
[dir="rtl"] .liste li::before{inset-inline-start:0;left:auto}
[dir="rtl"] .liste-check li::before{inset-inline-start:3px;left:auto}

/* G3 — encadré .note : liseré signature et arrondis côté début */
[dir="rtl"] .note{
  border-inline-start:3px solid var(--cyan-500);border-left:0;
  border-start-start-radius:0;border-end-start-radius:0;
  border-start-end-radius:var(--r);border-end-end-radius:var(--r)}
[dir="rtl"] .note-alerte{border-inline-start-color:#C4463A}
[dir="rtl"] .nuit .note{border-inline-start-color:var(--a1)}

/* B3 — le voile des bandeaux photo, peint pour un texte à gauche, retourné.
   Un dégradé n'a pas de forme logique : override explicite obligatoire. */
[dir="rtl"] .bande::before{
  background:linear-gradient(260deg,rgba(10,18,48,.92) 0%,rgba(10,18,48,.72) 46%,rgba(10,18,48,.34) 100%)}
[dir="rtl"] .photo-bandeau::after{
  background:linear-gradient(260deg,rgba(10,18,48,.95) 0%,rgba(10,18,48,.78) 45%,rgba(10,18,48,.35) 100%)}

/* ──────────────────────────────────────────────────────────────────────────
   🔴 B0 — LE DÉFAUT QUI RENDAIT LA PAGE ARABE ENTIÈREMENT BLANCHE
   Trouvé le 07/08 en la photographiant : capture de 9 Ko contre 480 Ko pour
   l'anglais. Le HTML était intact, le DOM complet, le JavaScript exécuté —
   mais RIEN n'était peint. Preuve par élimination : la même page SANS
   dir="rtl" s'affiche (202 Ko).

   LA CAUSE : la technique « pleine largeur » de skynet-clair.css:695-698
   sort les bandeaux du conteneur avec une marge NÉGATIVE calculée :
       margin-inline: calc(50% - 50vw + …)
   « inline » est une propriété LOGIQUE : en RTL, ses deux côtés s'inversent.
   La marge négative part alors du mauvais côté, chaque bandeau déborde de
   l'écran, et la page entière est poussée hors du cadre visible.

   LE CORRECTIF : en RTL on repasse en propriétés PHYSIQUES. Ici c'est
   volontairement l'inverse de la bonne pratique — parce qu'un débordement
   pleine largeur est SYMÉTRIQUE : il doit valoir autant à gauche qu'à
   droite, donc il ne doit surtout PAS suivre le sens de lecture.
   ⚠️ La leçon : « propriété logique » n'est pas toujours la bonne réponse.
      Ce qui est symétrique reste physique.
   ────────────────────────────────────────────────────────────────────────── */
[dir="rtl"] .pleine{
  margin-inline:0;
  margin-left:calc(50% - 50vw + var(--barre-defilement, 0px) / 2);
  margin-right:calc(50% - 50vw + var(--barre-defilement, 0px) / 2)}

/* ──────────────────────────────────────────────────────────────────────────
   6. LE SÉLECTEUR DE LANGUE
   Bâti sur <details> : il s'ouvre et se ferme SANS JavaScript. Donc il marche
   moteur désactivé, il est indexable, et ses entrées sont de vrais liens que
   Google suit vers les 11 autres versions.
   ⚠️ Les styles vivent ici et non dans les feuilles de marque : le sélecteur
   n'existe que sur les pages traduites.
   ────────────────────────────────────────────────────────────────────────── */
.lang-choix{position:relative;flex-shrink:0}
.lang-choix>summary{
  list-style:none;cursor:pointer;user-select:none;
  display:inline-flex;align-items:center;gap:.4em;
  min-height:44px;padding:0 .75rem;            /* 44 px : la cible tactile minimale */
  font-size:.92rem;font-weight:600;line-height:1;
  color:var(--encre);border:1px solid var(--gris-300);border-radius:var(--r);
  background:transparent;white-space:nowrap}
.lang-choix>summary::-webkit-details-marker{display:none}
.lang-choix>summary::marker{content:""}
.lang-choix>summary:hover{border-color:var(--indigo-600)}
.lang-choix[open]>summary{border-color:var(--indigo-600)}

.lang-choix>ul{
  position:absolute;z-index:60;top:calc(100% + .4rem);
  inset-inline-end:0;                          /* ⚠️ logique : s'ouvre du bon
        côté en arabe. Avec « right:0 » le menu sortirait de l'écran en RTL. */
  margin:0;padding:.35rem;list-style:none;
  min-width:12rem;max-height:min(70vh,26rem);overflow-y:auto;
  background:var(--blanc);border:1px solid var(--gris-300);
  border-radius:var(--r);box-shadow:0 12px 32px rgba(10,18,48,.16)}
.lang-choix>ul a{
  display:flex;align-items:center;gap:.6em;    /* flex : aligne drapeau et nom */
  padding:.55rem .7rem;border-radius:calc(var(--r) - 2px);
  color:var(--encre);text-decoration:none;font-size:.95rem;line-height:1.3;
  text-align:start}                            /* logique : juste en RTL */
.lang-choix>ul a:hover{background:var(--gris-100)}
.lang-choix>ul a[aria-current]{font-weight:700;color:var(--indigo-600)}
.lang-choix>ul a:focus-visible{outline:3px solid var(--indigo-600);outline-offset:-3px}

/* Le fond du menu doit suivre le thème sombre, sinon texte clair sur blanc. */
.nuit .lang-choix>ul{background:#0F1937;border-color:rgba(255,255,255,.18)}
.nuit .lang-choix>ul a{color:#E9ECF7}
.nuit .lang-choix>ul a:hover{background:rgba(255,255,255,.08)}
.nuit .lang-choix>summary{color:#E9ECF7;border-color:rgba(255,255,255,.28)}

/* ──────────────────────────────────────────────────────────────────────────
   6 bis. LES DRAPEAUX SVG — demande de Yann du 09/08/2026.

   ⚠️ LA RÈGLE QUI ÉVITE LE PIÈGE : un drapeau désigne un PAYS, pas une LANGUE.
   Il ne s'affiche donc JAMAIS seul — le nom de la langue, écrit dans cette
   langue, l'accompagne toujours. Sauf sous 560 px, où l'en-tête est saturé :
   là le drapeau reste seul, mais le bouton garde son aria-label, donc le
   lecteur d'écran annonce toujours « Langue ».
   ────────────────────────────────────────────────────────────────────────── */

/* Le bloc qui porte les 12 dessins. ⚠️ JAMAIS display:none : Safari cesse
   alors de résoudre les <use>. On le sort du flux à taille nulle. */
.lang-sprite{position:absolute;width:0;height:0;overflow:hidden}

.lang-drapeau{
  width:1.45em;height:calc(1.45em * 2 / 3);     /* ratio 3:2, comme les viewBox */
  flex:0 0 auto;                                /* ne se comprime jamais */
  border-radius:2px;
  /* Un liseré, sinon le Japon et la Pologne (à dominante blanche) disparaissent
     sur fond blanc. En couleur relative : il suit automatiquement le thème. */
  box-shadow:0 0 0 1px rgba(10,18,48,.16);
  /* Le drapeau n'est PAS du texte : il ne doit pas se retourner en arabe. */
  transform:none}
.nuit .lang-drapeau{box-shadow:0 0 0 1px rgba(255,255,255,.28)}

/* Le nom de la langue s'écrit toujours dans SA graphie : on neutralise
   l'interlettrage hérité, qui casse les liaisons de l'arabe. */
.lang-choix>ul a>span,.lang-choix>summary>span{letter-spacing:0}

/* ⚠️ LE BOUTON FERMÉ N'AFFICHE QUE LE CODE (« DE », « JA »), PAS LE NOM ENTIER.
   Mesuré au navigateur le 09/08 : avec « Deutsch » en toutes lettres, l'en-tête
   allemand débordait et le bouton d'appel à l'action était coupé — l'allemand a
   des mots longs, et le sélecteur a pris les derniers pixels disponibles.
   Le nom complet reste dans le menu déroulant ET dans l'aria-label du bouton :
   rien n'est perdu pour le lecteur d'écran, on gagne ~60 px dans l'en-tête.
   C'est la leçon déjà payée trois fois : TOUTE ENTRÉE AJOUTÉE À L'EN-TÊTE
   OBLIGE À LE RE-MESURER. */
.lang-code{
  font-variant-numeric:tabular-nums;
  font-size:.86em;font-weight:700;letter-spacing:.04em}

/* Sous 560 px, l'en-tête est saturé : on ne garde que le drapeau.
   Le code disparaît à l'œil, jamais pour le lecteur d'écran. */
@media(max-width:560px){
  .lang-choix>summary{padding:0 .55rem;gap:0}
  .lang-choix>summary>span{display:none}
  .lang-choix>summary .lang-drapeau{width:1.7em;height:calc(1.7em * 2 / 3)}
}

/* Écran à contraste renforcé : on remplace l'ombre par une vraie bordure,
   que le mode « contraste élevé » de Windows ne supprime pas. */
@media(forced-colors:active){
  .lang-drapeau{box-shadow:none;border:1px solid CanvasText}
}

/* ──────────────────────────────────────────────────────────────────────────
   7. LES NOMBRES ET LES ADRESSES EN LECTURE DROITE-À-GAUCHE
   Défaut VU sur la capture de la page arabe le 09/08/2026 : le numéro de
   téléphone s'affichait « 66 66 81 78 02 » au lieu de « 02 78 81 66 66 ».

   ⚠️ CE N'EST PAS UN BUG DU SITE, C'EST LA NORME UNICODE QUI S'APPLIQUE.
   L'algorithme bidirectionnel traite chaque groupe de chiffres séparé par un
   espace comme un morceau indépendant, puis les REMET DANS L'ORDRE DE LECTURE
   DE LA PAGE. En arabe, l'ordre s'inverse. Les chiffres eux-mêmes restent
   lisibles de gauche à droite — ce sont les GROUPES qui basculent.
   Un client arabophone composerait un numéro qui n'existe pas.

   LA PARADE : isoler ces éléments dans leur propre direction.
   `unicode-bidi:isolate` les sort du calcul bidirectionnel de la phrase qui
   les entoure, sans rien changer au reste de la ligne.

   ⚠️ Portée volontairement STRICTE — uniquement en RTL, uniquement sur ce qui
   doit se lire de gauche à droite quelle que soit la langue : un numéro de
   téléphone, une adresse e-mail, un identifiant légal, une adresse postale.
   On ne touche à RIEN dans les 10 autres langues.

   🚨 CORRIGÉ LE 09/08/2026 — LE PREMIER CORRECTIF ÉTAIT TROP LARGE.
   `a[href^="tel:"]` forçait TOUT le lien en LTR. Ça marche quand le lien ne
   contient QUE le numéro (en-tête, pied de page) — mais un lien du type
   « الاتصال بنا — 02 78 81 66 66 » mélange un LABEL ARABE et le numéro dans
   UNE SEULE chaîne. Forcer tout le lien en LTR inversait alors la POSITION
   du texte arabe par rapport au numéro : un défaut différent, pas une
   correction. Trouvé par l'audit adverse, sur ce lien précis.

   → LA RÈGLE NE PORTE PLUS QUE SUR `.ltr` : c'est le générateur
     (_i18n-generer.py) qui pose désormais cette classe UNIQUEMENT autour du
     numéro lui-même, après traduction — jamais sur tout le lien qui l'entoure.
   ────────────────────────────────────────────────────────────────────────── */
[dir="rtl"] a[href^="mailto:"],
[dir="rtl"] .ltr{
  direction:ltr;
  unicode-bidi:isolate;
  /* `start` et non `left` : dans le conteneur isolé, « start » VAUT gauche —
     et si un jour ce sélecteur servait ailleurs, il resterait juste. */
  text-align:start}

/* Les enfants héritent, mais un <span> imbriqué peut recréer son propre
   contexte : on isole aussi explicitement. */
[dir="rtl"] a[href^="mailto:"] span{unicode-bidi:isolate}

/* ──────────────────────────────────────────────────────────────────────────
   8. LES ILLUSTRATIONS EN LECTURE DROITE-À-GAUCHE
   Défaut MESURÉ le 09/08/2026, après la traduction des 368 libellés SVG :
   sur 696 libellés rendus dans 12 langues, **11 langues à ZÉRO débordement**
   et **l'arabe à 9**, TOUJOURS du côté gauche, jusqu'à 72 px hors du cadre.

   ⚠️ CE N'EST PAS UN PROBLÈME DE LONGUEUR DE TRADUCTION.
   Les libellés arabes sont plus COURTS que les français. Ce qui bascule, c'est
   l'ANCRAGE : un <text> sans « text-anchor » démarre au point d'ancrage et
   grandit dans le sens de lecture. La page étant en RTL, il grandit vers la
   GAUCHE — et sort du dessin, qui a été composé pour l'autre sens.

   LA CORRECTION, ET POURQUOI ELLE EST LA BONNE :
   **un schéma est une IMAGE, pas une phrase.** Son sens de lecture ne doit pas
   s'inverser : les flèches, les étapes et les colonnes gardent leur ordre.
   On remet donc le SVG en `direction:ltr` — ce qui restaure l'ancrage d'origine —
   et on isole chaque <text>, pour que le texte arabe qu'il contient reste, LUI,
   lu de droite à gauche. Deux niveaux, deux règles, chacune à sa place.
   ────────────────────────────────────────────────────────────────────────── */
[dir="rtl"] svg{direction:ltr}
[dir="rtl"] svg text,
[dir="rtl"] svg tspan{unicode-bidi:isolate}
