/* ==========================================================
   aris.merlix.monkoun.com — feuille de style partagée
   Utilisée par l'accueil, la liste des articles et les articles.
   Sections : thème et jetons · haut de page · accueil · liste des articles · article ·
   composants d'article · plan · paliers · formules · mots-clés et filtres · popup vidéos grand écran ·
   petits écrans.
   Organisation du dépôt et circuit d'un article : README.md.
   ========================================================== */

/* Thème : clair et sombre, mêmes valeurs que palette.light / palette.dark de site.json (vérifié par
   tools/build.py --check). Sombre par défaut sans préférence mémorisée ; light-dark() suit
   color-scheme, forcé par html[data-theme="light"|"dark"] (posé avant le premier rendu par le script
   de templates/base.html, bouton de la barre pour basculer, mémorisé par assets/site.js). */
:root {
  color-scheme: light dark;
  --paper:         light-dark(#f8fafc, #0c0f1a);
  --ink:           light-dark(#17232E, #E6EAEE);
  --muted:         light-dark(#4B5A66, #98A4AE);
  --line:          light-dark(#CBD2D7, #232B36);
  --accent:        light-dark(#2E6E67, #5DB8AC);
  --accent-strong: light-dark(#24544F, #86CFC5);
  --accent-soft:   light-dark(#E8EFF0, #17272E);
  --accent-2:      light-dark(#C2703E, #E39A6A);
  --surface:       light-dark(#ffffff, #131826);
  --code-bg:       light-dark(#EDF0F2, #141A28);
  --teal:          light-dark(#2E6E67, #5DB8AC);
  --orange:        light-dark(#C2703E, #E39A6A);
  --blue:          light-dark(#4A6FA5, #82A4DA);
  --purple:        light-dark(#7B5EA7, #AE95D6);
  --pink:          light-dark(#B85C7A, #DA8FAB);
  --gold:          light-dark(#B8962E, #DCC066);
  --grey:          light-dark(#9AA5AD, #6E7A86);
  /* Matières des schémas : tons neutres du plus proche du fond au plus contrasté, écrans, parchemin */
  --tone-1:        light-dark(#DDE2E6, #181D2A);
  --tone-2:        light-dark(#C9D0D6, #222937);
  --tone-3:        light-dark(#AEB7BF, #303A4A);
  --tone-4:        light-dark(#8F9BA6, #4A5668);
  --tint-blue:     light-dark(#C8D8E8, #1F2D45);
  --tint-warm:     light-dark(#F7EFE2, #2B2519);
  --tint-warm-2:   light-dark(#E0D8C6, #3A3222);
  --pre-bg:        light-dark(#17232E, #141A28);   /* blocs de code : sombres en clair, ardoise en sombre */
  --pre-fg:        light-dark(#f8fafc, #E6EAEE);
  --page-pad: clamp(1.5rem, 4vw, 3rem);   /* marge identique sur les quatre côtés de la page */
  --article-col: 48rem;                    /* colonne de texte d'un article sur grand écran */
  --rail-w: 18rem;                         /* rail du plan, affiché à partir de 1600px */
  --topbar-h: 3rem;                        /* hauteur de la barre fixe des pages secondaires (liste, articles) */
  --figure-width: 100%;                    /* largeur par défaut des figures dans la colonne (ex. 80%) ; par figure : style="--width: 60%" */
  /* Police système Apple : adresses et identifiants, intertitres de niveau 3 et 4, chiffres des listes */
  --police-systeme: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', sans-serif;
  /* Code (pseudocode, requêtes…) : Roboto Mono, dont le zéro n'est ni barré ni pointé. */
  --police-code: 'Roboto Mono', ui-monospace, Menlo, Consolas, monospace;
  /* Binaire et quaternaire (dont l'ADN) : JetBrains Mono. */
  --police-binaire-quaternaire: 'JetBrains Mono', var(--police-code);
}

:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

/* Fondu natif entre deux pages (changement de langue compris), sans JavaScript ; ignoré des
   navigateurs qui ne le prennent pas en charge (navigation normale). Absent si l'utilisateur préfère
   moins de mouvement. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}

/* Barres de défilement fines, page et rail compris */
html { scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }

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

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

body {
  background: var(--paper);
  color: var(--ink);
  font-family: 'Instrument Sans', system-ui, sans-serif;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* Le conteneur de page fait exactement la hauteur de l'écran.
   Tout ce qu'une extension de navigateur injecte dans <body> tombe après lui, hors écran. */
.page {
  min-height: 100vh;
  min-height: 100dvh; /* suit la barre d'adresse mobile quand elle se rétracte */
  display: flex;
  flex-direction: column;
  /* Même marge sur les quatre côtés : haut → wordmark = pied → bas */
  padding: var(--page-pad);
}

.serif { font-family: 'Instrument Serif', Georgia, serif; font-weight: 400; }

/* ---- Haut de page ---- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--muted);
}

.topbar a { color: inherit; text-decoration: none; }
.topbar a:hover { color: var(--ink); }

.wordmark { letter-spacing: 0.01em; }

/* Variante des pages secondaires (liste des articles, articles) : la barre reste figée en haut,
   avec le titre courant et un filet de progression. Elle déborde sur la marge de page pour
   couvrir toute la largeur. */
.topbar-sticky {
  position: sticky;
  top: 0;
  z-index: 10;
  min-height: var(--topbar-h);
  margin: -0.75rem calc(-1 * var(--page-pad)) 0;
  padding: 0.75rem var(--page-pad);
  background: var(--paper);
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease;
}

.topbar-sticky.is-stuck { border-bottom-color: var(--line); }

.topbar-title {
  /* Centré sur l'axe de la page, donc sur celui de la colonne de texte ; même largeur qu'elle.
     Masqué sur écran étroit, où il chevaucherait le wordmark. */
  display: none;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(var(--article-col), calc(100% - 30rem));
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: 'Instrument Serif', Georgia, serif;
  font-size: 1.05rem;
  color: var(--ink);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.topbar-sticky.show-title .topbar-title { opacity: 1; }

.topbar-progress {
  position: absolute;
  left: 0;
  bottom: -1px;
  height: 2px;
  width: 0;
  background: var(--accent);
}

/* À droite : les pages (nav), puis, derrière un filet, les outils (langue, thème). Deux groupes,
   pour qu'un lien de page ne se confonde jamais avec un réglage. */
.topbar-end { display: flex; align-items: center; }
/* nav.topnav (lien « Articles ») masquée : reste dans le HTML (gabarit, accessibilité), retirer
   cette règle pour la réafficher. */
.topnav { display: none; gap: 1.25rem; }
.topnav a[aria-current="page"] { color: var(--ink); }
.topbar-tools {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: 1rem;
  padding-left: 1rem;
  border-left: 1px solid var(--line);
}

/* Bascule de langue : le code de la langue cible (EN, FR), en capsule de la hauteur du bouton de thème */
.lang-switch {
  display: inline-flex;
  align-items: center;
  height: 1.5rem;
  padding: 0 0.5rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1;
  transition: border-color 0.18s ease, color 0.18s ease;
}
.topbar .lang-switch:hover { color: var(--ink); border-color: var(--ink); }
.lang-switch:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* Bouton clair / sombre : soleil en mode sombre, lune en mode clair (l'icône annonce ce qu'on obtient) */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  margin: -0.25rem -0.35rem -0.25rem 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: inherit;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease;
}
.theme-toggle:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 7%, transparent); }
.theme-toggle:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.theme-toggle svg { width: 1rem; height: 1rem; }
.theme-toggle .sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .sun { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .moon { display: none; }
}
:root[data-theme="dark"] .theme-toggle .sun { display: block; }
:root[data-theme="dark"] .theme-toggle .moon { display: none; }

/* ---- Bloc principal ---- */
/* Le bloc central prend tout l'espace restant et centre son contenu ;
   le pied de page reste ainsi collé en bas même si un élément est injecté après lui. */
main {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: 60rem;
  margin: clamp(2rem, 6vh, 5rem) 0;
}

.name {
  font-family: 'Instrument Serif', Georgia, serif;
  font-weight: 400;
  font-size: clamp(2.75rem, 9vw, 5.75rem);
  line-height: 1.02;
  letter-spacing: -0.01em;
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

.roles {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.9rem;
  font-size: clamp(1.05rem, 2.6vw, 1.55rem);
  color: var(--ink);
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem);
}

.roles .role-2 { white-space: nowrap; }

/* Croix tracée : haute comme les minuscules (1ex = hauteur d'x de la police), posée sur la ligne de base */
.roles .x {
  display: inline-block;
  width: 1ex;
  height: 1ex;
  vertical-align: baseline;
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linecap: round;
  margin-right: 0.4em;
  flex-shrink: 0;
}

/* Le texte de présentation, avec ses liens intégrés */
.intro {
  max-width: 40rem;
  font-size: clamp(1.15rem, 2.6vw, 1.6rem);
  line-height: 1.55;
  color: var(--ink);
}

.intro a,
.intro .linklike {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: color 0.18s ease;
}

.intro a:hover,
.intro .linklike:hover {
  color: var(--accent-strong);
  text-decoration-thickness: 2px;
}

.intro a:focus-visible,
.intro .linklike:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Un bouton qui se présente comme un lien dans une phrase */
.linklike {
  font: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

/* ---- Popup vidéos ---- */
dialog.videos {
  margin: auto;
  border: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  border-radius: 4px;
  width: min(26rem, calc(100vw - 2rem));
  box-shadow: 0 24px 60px color-mix(in srgb, var(--ink) 25%, transparent);
}

dialog.videos::backdrop { background: color-mix(in srgb, var(--ink) 45%, transparent); }

.videos-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.25rem 1.25rem 1rem;
}

.videos-head h2 {
  font-family: 'Instrument Serif', Georgia, serif;
  font-weight: 400;
  font-size: 1.6rem;
  line-height: 1.1;
}

.videos-close {
  font: inherit;
  font-size: 1.5rem;
  line-height: 1;
  background: none;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  padding: 0.15rem 0.35rem;
}

.videos-close:hover { color: var(--ink); }
.videos-close:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; border-radius: 2px; }

.videos-option {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-top: 1px solid var(--line);
  color: var(--ink);
  text-decoration: none;
  transition: background 0.18s ease;
}

.videos-option:hover { background: var(--accent-soft); }
.videos-option:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }

.videos-option svg { width: 22px; height: 22px; flex-shrink: 0; color: var(--accent); }

.videos-option span { flex: 1; }
.videos-option strong { display: block; font-weight: 500; }
.videos-option small { display: block; color: var(--muted); font-size: 0.85rem; }

.videos-option .arrow { width: 15px; height: 15px; color: var(--muted); }

/* ---- Pied de page ---- */
.footer {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--muted);
}

.footer a { color: inherit; text-decoration: none; }
.footer a:hover { color: var(--ink); }

/* Adresses et identifiants : police système Apple. .email est posée dans le HTML (rendu sans JavaScript),
   .at est ajoutée par site.js autour de tout mot contenant un « @ ». */
.email,
.at {
  font-family: var(--police-systeme);
}

/* ==========================================================
   Liste des articles
   ========================================================== */

.page-title {
  font-family: 'Instrument Serif', Georgia, serif;
  font-weight: 400;
  font-size: clamp(2.25rem, 6vw, 3.75rem);
  line-height: 1.05;
  letter-spacing: -0.01em;
  margin-bottom: 0.75rem;
}

.lead {
  max-width: 36rem;
  color: var(--muted);
  font-size: clamp(1rem, 2.2vw, 1.125rem);
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
}

.posts { list-style: none; max-width: 44rem; }

.post {
  display: grid;
  grid-template-columns: 7.5rem 1fr;
  gap: 0.5rem 1.5rem;
  padding: 1.35rem 0;
  border-top: 1px solid var(--line);
}

.post:last-child { border-bottom: 1px solid var(--line); }

.post time { color: var(--muted); font-size: 0.9rem; padding-top: 0.25rem; }

.post h2 {
  font-family: 'Instrument Serif', Georgia, serif;
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 1.2;
  margin-bottom: 0.35rem;
}

.post h2 a { color: var(--ink); text-decoration: none; }
.post h2 a:hover { color: var(--accent); }

.post p { color: var(--muted); font-size: 0.975rem; }

/* ==========================================================
   Article
   ========================================================== */

/* Sur une page d'article, main ne plafonne plus à 60rem et ne centre pas verticalement */
main.article-main { position: relative; max-width: none; justify-content: flex-start; }

.article { width: 100%; max-width: var(--article-col); margin-inline: auto; }

.back {
  display: inline-block;
  font-size: 0.9rem;
  color: var(--muted);
  text-decoration: none;
  margin-bottom: 2rem;
}

.back:hover { color: var(--ink); }

.article h1 {
  font-family: 'Instrument Serif', Georgia, serif;
  font-weight: 400;
  font-size: clamp(2rem, 5vw, 3.25rem);
  line-height: 1.1;
  letter-spacing: -0.01em;
  margin-bottom: 1rem;
}

.meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.75rem;
  color: var(--muted);
  font-size: 0.9rem;
  margin-bottom: clamp(2rem, 5vw, 3rem);
}

.meta .sep { color: var(--line); }

.prose { font-size: 1rem; line-height: 1.7; }

/* Notations mathématiques dans le texte : même police que les formules (Instrument Serif),
   variables en italique, symboles et indices droits. Les <span class="math"> enveloppent
   les expressions, les <var> isolées suffisent pour une lettre seule. */
.prose var, .prose .math { font-family: 'Instrument Serif', Georgia, serif; font-size: 1.12em; line-height: 1; }
.prose var { font-style: normal; }
.prose .math { font-style: normal; }
.prose .math var { font-size: 1em; }
.prose .math sub, .prose .math sup, .prose var + sub, .prose var + sup { font-size: 0.7em; }

/* Aucun italique dans le corps des articles : les <em>, <i> et <cite> restent sémantiques mais droits */
.prose em, .prose i, .prose cite, .prose .chapo { font-style: normal; }

/* Texte justifié, avec césure (lang="fr" sur <html>) pour éviter les lézardes */
.prose p, .prose li { text-align: justify; -webkit-hyphens: auto; hyphens: auto; }

.prose > * + * { margin-top: 1.25em; }

.prose .chapo {
  font-family: 'Instrument Serif', Georgia, serif;
  font-size: 1.35em;
  line-height: 1.4;
  color: var(--muted);
}

/* Intertitres : h2 se distingue de h3/h4 par la police et le filet, pas par la seule taille.
   h3 et h4, eux, partagent exactement le même style (taille, graisse, police, interligne) : leur
   hiérarchie se lit au numéro (1.1 contre 1.1.1), jamais au style du texte. Seul h2 garde
   Instrument Serif, comme le titre de l'article ; h3 et h4 passent en police système, ce qui les
   détache du corps du texte (Instrument Sans). */
.prose h2 {
  font-family: 'Instrument Serif', Georgia, serif;
  font-weight: 400;
  font-size: 2em;
  line-height: 1.15;
  /* Le filet à égale distance du texte qui précède et du texte qui suit : même valeur des deux côtés.
     En rem, pas en em : sinon la taille du h2 (2em) multiplie chaque distance une seconde fois. */
  margin-top: 2.25rem;
  padding-top: 2.25rem;
  border-top: 1px solid var(--line);
}

/* h3/h4 : mêmes dimensions visuelles, jamais la taille du corps de texte (sinon plus rien ne les
   distingue du paragraphe qui suit). Seul l'espace au-dessus reste propre à chaque niveau. */
.prose h3, .prose h4 {
  font-family: var(--police-systeme);
  font-weight: 600;
  font-size: 1.1em;
  line-height: 1.3;
}

.prose h3 { margin-top: 2.5em; }
.prose h4 { margin-top: 2em; }

/* Titre collé à un autre titre, sans texte entre les deux : même distance à chaque niveau
   (2 → 1.1 comme 1.1 → 1.1.1), en rem pour ne pas dépendre de la taille propre de chacun. */
.prose h2 + h3, .prose h3 + h4 { margin-top: 2rem; }

/* Premier intertitre du corps : pas de filet, il n'y a rien à séparer au-dessus */
.prose > h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

/* Numérotation des intertitres, dérivée : le texte d'un h2/h3/h4 ne contient jamais son numéro
   (tools/build.py --check le signale). Même règle que textify.Numerotation, qui numérote le plan
   et le Markdown de llms-full.txt. Un intertitre .liminaire (Résumé, Introduction, Conclusion,
   Bibliographie) n'est pas numéroté et ne consomme pas de numéro ; .prose.sans-numeros
   (article.json → "numerotation": false) les masque tous. Le numéro n'a pas de style propre : il
   hérite de la police et de la taille de son intertitre, seule sa couleur change. */
.prose { counter-reset: h2 h3 h4; }
.prose h2 { counter-set: h3 0 h4 0; }   /* counter-set, et non counter-reset : remet à zéro le */
.prose h3 { counter-set: h4 0; }        /* compteur existant au lieu d'en imbriquer un nouveau */
.prose h2:not(.liminaire) { counter-increment: h2; }
.prose h3:not(.liminaire) { counter-increment: h3; }
.prose h4:not(.liminaire) { counter-increment: h4; }

.prose h2:not(.liminaire)::before { content: counter(h2) "."; }
.prose h3:not(.liminaire)::before { content: counter(h2) "." counter(h3); }
.prose h4:not(.liminaire)::before { content: counter(h2) "." counter(h3) "." counter(h4); }

.prose h2::before, .prose h3::before, .prose h4::before { color: var(--accent); margin-right: 0.45em; }

.prose.sans-numeros h2::before, .prose.sans-numeros h3::before, .prose.sans-numeros h4::before { content: none; }

.prose a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}

.prose a:hover { color: var(--accent-strong); }

.prose ul, .prose ol { padding-left: 1.4em; }
.prose li + li { margin-top: 0.4em; }
/* Les chiffres d'une liste numérotée appartiennent à la numérotation de l'article : même police
   que les numéros d'intertitre. Les puces et les ronds creux restent ceux du navigateur. */
.prose ol > li::marker { font-family: var(--police-systeme); }

/* Un élément de liste peut porter plusieurs blocs (liste imbriquée, formule, encadré) : ils sont
   espacés comme le reste, alors que .prose > * + * ne touche que les enfants directs de la colonne. */
.prose li > :is(p, div, ul, ol, pre, figure) { margin-top: 0.5em; }

/* Terme défini en tête d'un élément de liste ou d'un paragraphe : « La méthode lexicographique : … ».
   Deux-points, jamais un point, et une graisse au-dessus du texte courant — de quoi le repérer en
   parcourant la page, pas de quoi crier. */
.prose .terme { font-weight: 500; }

.prose blockquote {
  border-left: 2px solid var(--accent);
  padding-left: 1.25em;
  font-family: 'Instrument Serif', Georgia, serif;
  font-style: normal;
  font-size: 1.2em;
  line-height: 1.45;
  color: var(--muted);
}

.prose code {
  font-family: var(--police-code);
  font-size: 0.9em;
  background: color-mix(in srgb, var(--ink) 7%, transparent);
  padding: 0.1em 0.35em;
  border-radius: 2px;
}

.prose pre {
  /* Fond sombre + « scroll-shadow » : deux caches qui défilent avec le contenu (local) recouvrent
     deux lueurs fixes (scroll). Une lueur n'apparaît que du côté où il reste du contenu hors champ ;
     rien n'est visible quand le bloc tient en largeur. */
  background:
    linear-gradient(to right, var(--pre-bg) 40%, transparent) 0 0 / 3rem 100% no-repeat local,
    linear-gradient(to left,  var(--pre-bg) 40%, transparent) 100% 0 / 3rem 100% no-repeat local,
    linear-gradient(to right, color-mix(in srgb, var(--pre-fg) 22%, transparent), transparent) 0 0 / 1.25rem 100% no-repeat scroll,
    linear-gradient(to left,  color-mix(in srgb, var(--pre-fg) 22%, transparent), transparent) 100% 0 / 1.25rem 100% no-repeat scroll,
    var(--pre-bg);
  color: var(--pre-fg);
  padding: 1rem 1.25rem;
  border-radius: 3px;
  overflow-x: auto;
  line-height: 1.55;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

.prose pre code { background: none; padding: 0; font-size: 0.85em; color: inherit; }

.prose figure { margin-top: 2em; margin-bottom: 2em; }
.prose img { display: block; max-width: 100%; height: auto; border-radius: 2px; }
/* Largeur d'une figure : --width posée sur le <figure> (style="--width: 60%") prime sur le
   réglage global --figure-width de :root. */
.prose figure > svg, .prose figure > img { display: block; width: var(--width, var(--figure-width)); max-width: 100%; height: auto; margin-inline: auto; }
/* Netteté : les traits gardent leur épaisseur en pixels quelle que soit l'échelle (sauf les points,
   dont le trait est la forme), et les axes, cadres et graduations sont rendus sans anticrénelage. */
.prose figure svg [stroke]:not(.dots) { vector-effect: non-scaling-stroke; }
.prose figure svg .crisp { shape-rendering: crispEdges; }
.prose figcaption { text-align: center; }                            /* légende centrée sous l'image, sur toute sa largeur */
.prose figcaption { margin-top: 0.6em; font-size: 0.85em; color: var(--muted); }
.prose h2[id], .prose h3[id], .prose h4[id] { scroll-margin-top: calc(var(--topbar-h) + 1rem); }

.prose hr { border: 0; border-top: 1px solid var(--line); margin: 2.5em 0; }

.prose table { width: 100%; border-collapse: collapse; font-size: 0.95em; }
.prose th, .prose td { text-align: left; padding: 0.6em 0.75em; border-bottom: 1px solid var(--line); vertical-align: top; }
.prose th { font-weight: 500; }
.prose .table-wrap { overflow-x: auto; }

/* ---- Composants d'article ----
   Blocs facultatifs, tous montrés dans articles/_gabarit/index.html. */

/* Encadré : remarque, précision, réserve sur une source */
.prose .note {
  font-size: 0.95em;
  color: var(--muted);
  padding: 0.9em 1.25em;
  background: var(--accent-soft);
  border-radius: 3px;
}

/* Étapes d'un algorithme : liste numérotée aux items plus espacés */
.prose ol.algo li + li { margin-top: 0.6em; }

/* Bibliographie : liste numérotée un peu plus petite */
.prose .refs { font-size: 0.925em; }
.prose .refs li { margin-top: 0.6em; }

/* Tableau compact : petites cellules sur une ligne ; à mettre dans .table-wrap pour défiler si besoin */
.prose table.compact { font-size: 0.8em; }
.prose table.compact th, .prose table.compact td { padding: 0.45em 0.5em; white-space: nowrap; }

/* Codes (.codes, sur table ou pre) : binaire, quaternaire, bases ADN. Colonnes à partir de la 3e
   d'un tableau (chasse fixe, pour que des codes de même longueur logique aient la même largeur
   visuelle) ; police dédiée dans les deux cas (--police-binaire-quaternaire). */
.prose table.codes td:nth-child(n+3), .prose pre.codes code { font-family: var(--police-binaire-quaternaire); }

.article-end {
  margin-top: 3.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  font-size: 0.95rem;
  color: var(--muted);
}

.article-end a { color: var(--accent); text-decoration: none; }
.article-end a:hover { color: var(--accent-strong); text-decoration: underline; }

/* ==========================================================
   Plan de l'article (nav.outline)
   Bloc au-dessus du texte par défaut ; rail collant à gauche
   sur grand écran (voir les paliers ci-dessous).
   ========================================================== */

.outline { font-size: 0.875rem; line-height: 1.45; color: var(--muted); }

.outline-title {
  font-family: 'Instrument Serif', Georgia, serif;
  font-size: 1.1rem;
  color: var(--ink);
  margin-bottom: 0.5rem;
}

.outline ol { list-style: none; padding-left: 0; }
.outline > ol > li { border-left: 1px solid var(--line); break-inside: avoid; }
.outline > ol > li + li { margin-top: 0.35rem; }
.outline ol ol { margin-top: 0.1rem; font-size: 0.94em; }

.outline a {
  position: relative;
  display: block;
  padding: 0.15rem 0 0.15rem 0.85rem;
  color: inherit;
  text-decoration: none;
}

.outline ol ol a { padding-left: 1.75rem; }
.outline-num { font-variant-numeric: lining-nums tabular-nums; }   /* numéro dérivé, comme dans la prose */
.outline a:hover { color: var(--ink); }
.outline a.active { color: var(--accent); }

/* Repère sur le filet vertical, au niveau de l'entrée active */
.outline a.active::before {
  content: "";
  position: absolute;
  left: -1px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--accent);
}

 /* Le plan n'existe qu'en rail, sur les écrans assez larges (seuil ci-dessous) */
.rail { display: none; }

/* ---- Paliers de la page d'article ---- */

/* À partir de 900px la colonne atteint 48rem : corps un peu plus grand */
@media (min-width: 56.25em) {
  .prose { font-size: 1.0625rem; }
  .topbar-title { display: block; }
}

/* ≥ 1600px (au-delà d'un MacBook Air 13" en réglage par défaut, 1470px) : le plan apparaît
   en rail collant, calé au bord gauche de la page ; la colonne de texte reste centrée dans la
   fenêtre, indépendamment du rail. Le rail s'arrête avec main, il ne recouvre jamais le pied.
   En dessous de ce seuil, le plan n'est pas affiché. */
@media (min-width: 100em) {
  .rail {
    display: block;
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: var(--rail-w);
  }

  .rail > .outline {
    position: sticky;
    top: calc(var(--topbar-h) + 1rem);
    padding-right: 0.75rem;
    max-height: calc(100vh - var(--topbar-h) - 2rem);
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--line) transparent;
    font-size: 0.9rem;
  }
}

/* ==========================================================
   Formules (KaTeX)
   Les expressions portent data-tex ; une fois rendues (.is-tex) elles prennent la police
   Computer Modern de KaTeX, le HTML de repli garde les réglages ci-dessous.
   ========================================================== */

.prose .math.is-tex { white-space: nowrap; }
.prose .katex { font-size: 1.06em; }                  /* équilibre avec Instrument Sans */

/* Formule en bloc, composée en Instrument Serif comme les notations du texte */
.prose .formula {
  font-family: 'Instrument Serif', Georgia, serif;
  font-size: 1.15em;
  line-height: 1.6;
  padding: 0.75em 1.25em;
  border-left: 2px solid var(--line);
  overflow-x: auto;
}
.prose .formula var { font-style: normal; }

/* Correspondance en colonnes (a → b) : un span par cellule, trois par ligne ; les flèches restent alignées
   quelle que soit la largeur des chiffres. */
.prose .formula.map {
  display: grid;
  grid-template-columns: repeat(3, max-content);
  column-gap: 0.45em;
  align-items: baseline;
}
.prose .formula.map > :nth-child(3n + 1) { text-align: right; }

.prose .formula.is-tex {
  font-family: inherit;
  font-size: inherit;
  padding: 0.25em 0;
  border-left: 0;
  text-align: center;
}
.prose .formula.is-tex .katex-display { margin: 0; }
.prose .formula.is-tex .katex { font-size: 1.12em; }

/* ==========================================================
   Mots-clés et filtres
   ========================================================== */

.tags { display: flex; flex-wrap: wrap; gap: 0.4rem; list-style: none; }

.tag {
  display: inline-block;
  font-size: 0.8rem;
  line-height: 1.3;
  padding: 0.2rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--muted);
  text-decoration: none;
  background: none;
  font-family: inherit;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.tag::first-letter { text-transform: uppercase; }
.tag:hover { color: var(--ink); border-color: var(--muted); }
.tag.is-on { color: var(--accent-strong); border-color: var(--accent); background: var(--accent-soft); }
.tag:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.article .tags { margin-top: -1rem; margin-bottom: clamp(2rem, 5vw, 3rem); }

/* Barre de filtres de la liste des articles (affichée par le script) */
.filters {
  max-width: 44rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1rem;
  margin-bottom: 1.5rem;
  font-size: 0.9rem;
  color: var(--muted);
}

.filters .tags { flex: 1 1 100%; }

/* Sélecteurs type/année : rendu natif du <select> désactivé (le contour arrondi et la double
   flèche du système, notamment sous Safari, juraient avec le reste, sobre et sans encadrés) ;
   même filet que les autres réglages de la page, chevron fin dessiné à la main. */
.select-wrap { position: relative; display: inline-flex; align-items: center; }

.filters select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  font: inherit;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  margin: 0;
  padding: 0.2rem 1.15em 0.2rem 0;
  cursor: pointer;
}

.select-wrap:hover select { border-color: var(--muted); }
.filters select:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.select-arrow {
  position: absolute;
  right: 0;
  width: 0.7em;
  height: 0.7em;
  fill: none;
  stroke: var(--muted);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

.filters-reset {
  font: inherit;
  font-size: 0.9rem;
  color: var(--accent);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

.filters-count { margin-left: auto; }

.post[hidden] { display: none; }
.post .tags { margin-top: 0.6rem; }
.post .tag { font-size: 0.75rem; }

.posts-empty {
  max-width: 44rem;
  padding: 1.5rem 0;
  font-family: 'Instrument Serif', Georgia, serif;
  font-style: italic;
  color: var(--muted);
}

/* ---- Accessibilité et petits écrans ---- */
/* Popup vidéos sur grand écran : fond flouté (verre dépoli), carte translucide, les deux icônes en
   vedette côte à côte. En dessous de 900px, on garde la liste compacte (et la feuille sur téléphone). */
@media (min-width: 56.25em) {
  dialog.videos::backdrop {
    background: color-mix(in srgb, var(--paper) 55%, transparent);
    -webkit-backdrop-filter: blur(18px) saturate(1.3);
    backdrop-filter: blur(18px) saturate(1.3);
  }

  dialog.videos {
    width: min(34rem, calc(100vw - 4rem));
    padding: 1.75rem 1.75rem 1.9rem;
    border-radius: 22px;
    background: color-mix(in srgb, var(--surface) 62%, transparent);
    -webkit-backdrop-filter: blur(28px) saturate(1.4);
    backdrop-filter: blur(28px) saturate(1.4);
    box-shadow: 0 1px 0 color-mix(in srgb, var(--surface) 70%, transparent) inset, 0 30px 80px color-mix(in srgb, var(--ink) 22%, transparent), 0 4px 16px color-mix(in srgb, var(--ink) 8%, transparent);
  }

  dialog.videos[open] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    animation: videos-in 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
  }

  dialog.videos[open]::backdrop { animation: videos-backdrop 0.28s ease; }

  /* Sortie : le chemin inverse, un peu plus court (assets/site.js pose is-closing puis attend la fin) */
  dialog.videos[open].is-closing { animation: videos-out 0.2s cubic-bezier(0.4, 0, 1, 1) forwards; }
  dialog.videos[open].is-closing::backdrop { animation: videos-backdrop-out 0.2s ease forwards; }

  .videos-head {
    grid-column: 1 / -1;
    justify-content: center;
    padding: 0 0 0.35rem;
    position: relative;
  }

  .videos-head h2 { font-size: 1.85rem; text-align: center; }

  .videos-close {
    position: absolute;
    top: -0.5rem;
    right: -0.6rem;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border-radius: 50%;
    font-size: 1.25rem;
    background: color-mix(in srgb, var(--ink) 6%, transparent);
    transition: background 0.18s ease, color 0.18s ease;
  }

  .videos-close:hover { background: color-mix(in srgb, var(--ink) 12%, transparent); }
  .videos-close:focus-visible { border-radius: 50%; outline-offset: 1px; }

  /* Chaque option devient une tuile : grande icône dans un carré arrondi, nom et identifiant dessous */
  .videos-option {
    flex-direction: column;
    gap: 0.9rem;
    padding: 1.6rem 1rem 1.35rem;
    border: 0;
    border-radius: 18px;
    background: color-mix(in srgb, var(--surface) 55%, transparent);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 6%, transparent);
    text-align: center;
    transition: background 0.18s ease, transform 0.22s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.22s ease;
  }

  .videos-option:hover {
    background: color-mix(in srgb, var(--surface) 85%, transparent);
    transform: translateY(-2px);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent), 0 12px 28px color-mix(in srgb, var(--ink) 12%, transparent);
  }

  .videos-option:focus-visible { outline-offset: 2px; border-radius: 18px; }

  .videos-option > svg:first-child {
    width: 4.5rem;
    height: 4.5rem;
    padding: 1.1rem;
    border-radius: 1.35rem;
    color: var(--paper);
    background: var(--accent);
    box-shadow: 0 8px 20px color-mix(in srgb, var(--accent) 28%, transparent);
    transition: transform 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
  }

  .videos-option:hover > svg:first-child { transform: scale(1.06); }

  .videos-option span { flex: initial; }
  .videos-option strong { font-size: 1.05rem; }
  .videos-option .arrow { display: none; }
}

@keyframes videos-in {
  from { opacity: 0; transform: translateY(10px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}

@keyframes videos-backdrop {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes videos-out {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(8px) scale(0.97); }
}

@keyframes videos-backdrop-out {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* Sous 900px (carte compacte, feuille sur téléphone) : simple fondu à la fermeture */
@media (max-width: 56.24em) {
  dialog.videos[open].is-closing { animation: videos-backdrop-out 0.16s ease forwards; }
  dialog.videos[open].is-closing::backdrop { animation: videos-backdrop-out 0.16s ease forwards; }
}

@media (prefers-reduced-motion: reduce) {
  .intro a, .intro .linklike, .videos-option, .videos-option > svg:first-child, .videos-close { transition: none; }
  dialog.videos[open], dialog.videos[open]::backdrop, dialog.videos[open].is-closing, dialog.videos[open].is-closing::backdrop { animation: none; }
}

@media (max-width: 560px) {
  .roles {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.35rem;
  }

  /* Taille calée pour que chaque ligne du texte tienne sans se couper */
  .intro { font-size: clamp(0.95rem, 4.3vw, 1.6rem); line-height: 1.6; }

  /* Accroche de la liste : « et ce que j'apprends en chemin. » sur sa propre ligne */
  .lead .lead-line { display: block; }

  .post { grid-template-columns: 1fr; gap: 0.25rem; }
  .filters-count { margin-left: 0; flex-basis: 100%; }

  /* Fin d'article : « ou retrouvez-moi sur LinkedIn. » sur sa propre ligne */
  .article-end-alt { display: block; }

  /* La popup devient une feuille qui monte du bas */
  dialog.videos {
    margin: auto 0 0;
    width: 100%;
    max-width: none;
    border-radius: 12px 12px 0 0;
    padding-bottom: env(safe-area-inset-bottom);
  }

  .videos-option { padding: 1.1rem 1.25rem; }

  /* Article sur téléphone : corps fluide (15px à 375, 15,4 à 430, 16 dès ~530) et mesure courte,
     donc interligne un peu réduit ; fer à gauche, la justification creuse des lézardes sur une
     colonne étroite (la césure reste active). */
  .prose { font-size: clamp(0.9375rem, 0.8rem + 0.6vw, 1rem); line-height: 1.65; }
  .prose p, .prose li { text-align: start; }

  /* Blocs de code : lignes intactes, défilement horizontal signalé par la lueur de .prose pre */
  .prose pre { padding: 0.85rem 1rem; }
  .prose pre code { font-size: 0.8em; line-height: 1.5; }
  .prose .formula { font-size: 1.05em; padding: 0.6em 0.9em; }
  .prose .formula.is-tex .katex { font-size: 1em; }
}

@media (max-width: 460px) {
  .footer { flex-direction: column; gap: 0.35rem; }
}
