/* ==========================================================================
   GIFR, refonte 2026 : page d'article et page de guide
   --------------------------------------------------------------------------
   A charger APRES gi-tokens.css, gi-accueil.css et gi-archive.css.
   Ne redefinit aucun token.

   VERSION 3, 29/07/2026, apres lecture de deux articles reels exportes.

   CE QUE LES DEUX EXPORTS ONT APPRIS, ET QUI CHANGE TOUT
   Les redacteurs ne travaillent PAS dans l'editeur WordPress. Ils batissent
   l'article AU BUILDER : `post-content` sort une arborescence
   section > row > column > modules, et le texte vit dans des modules Texte
   qui contiennent du HTML brut. Un article reel, la 5.8, compte 16 modules
   Texte, 19 modules Image et 3 modules Video.

   Consequence directe sur l'ecriture du CSS : les selecteurs d'enfant
   direct ne suffisent plus, le texte est a quatre niveaux de profondeur.
   Ce fichier tient donc LES DEUX FORMES, contenu d'editeur et contenu bati
   au Builder, et il les rend identiques. C'est l'objet de la partie C9.

   LA REGLE QUI GOUVERNE LES PARTIES C4 A C9
   Le contenu n'est pas a nous : ni les balises, ni leur ordre, ni leur
   imbrication. Le CSS y vise des ELEMENTS et des CLASSES DE DIVI, jamais
   des classes a nous. Un redacteur ne doit jamais avoir a poser une classe,
   ni a ouvrir un champ de CSS.

   Paliers : 1080, 760, 620, 400. Ceux de gi-accueil.css.
   ========================================================================== */

.gi-art-body {
  --art-col: 980px;
  --rail-w: 360px;
  --art-gap: clamp(1.8rem, 0.6rem + 2.6vw, 3.5rem);
  --art-pad: clamp(1.15rem, 0.2rem + 3.2vw, 3.5rem);
  /* LA MESURE DE LECTURE, EN REM ET NON EN CH. `--gi-measure` vaut 68ch, et
     `ch` se resout sur la police de l'element qui le porte : le chapo, un
     cran plus gros, se donnait 884 px la ou le corps en prenait 694. Deux
     largeurs de colonne dans la meme page, pour une seule regle. En rem, la
     mesure suit le reglage racine comme le reste du projet.
     43,5rem = 68 caracteres d'Inter a 17 px. */
  --art-measure: 43.5rem;
  /* 74 px = hauteur de .gi-header__inner au repos. Le second terme est
     l'air SOUS le menu quand la bande est collee : a 1,25 rem elle paraissait
     posee sur la barre de navigation. */
  --art-stick: calc(74px + 2rem);
}


/* ==========================================================================
   C1. MISE EN PAGE
   ========================================================================== */
/* LES POUSSIERES DU FOND. Meme moteur et meme reglage que le corps des
   archives, `gi-particles.js`, a une densite plus basse : sous un article on
   veut une presence, pas un decor. Le canevas se coupe tout seul sous 900 px
   et sur `prefers-reduced-motion`, c'est le script qui le decide.

   `z-index: 0` ET NON `-1` : la section est en `isolation: isolate`, elle
   forme son propre contexte d'empilement, et un rang negatif enverrait le
   canevas DERRIERE le fond de la section, ou personne ne le verrait. Zero le
   place au-dessus du fond et sous le grain, le vignetage et la rangee, qui
   valent 2, 3 et 4. */
.gi-art-body__particules {
  /* COLLANT ET HAUT D'UN ECRAN, PAS ETIRE SUR TOUTE LA SECTION, ET LA
     RAISON EST MESUREE. Un article fait 8 000 a 12 000 px de haut : en
     `inset: 0`, le canevas faisait 1440 x 12 081, soit prés de 70 Mo de
     memoire graphique pour un decor, et les particules se repartissaient sur
     dix ecrans dont un seul se voyait. Colle, il ne fait jamais plus d'un
     ecran, il coute dix fois moins, et toute la quantite demandee tombe
     exactement dans le champ de vision.

     `margin-bottom: -100vh` lui rend sa hauteur : le canevas reste un
     element en flux, donc collant, mais ne pousse plus rien. */
  position: sticky;
  top: 0;
  z-index: 0;
  width: 100%;
  height: 100vh;
  margin-bottom: -100vh;
  pointer-events: none;
}
.gi-art-body {
  position: relative;
  isolation: isolate;
  /* `clip-path` ET NON `overflow: hidden`, ET LA NUANCE EST MESUREE. Les
     deux detourent le contenu, mais `overflow: hidden` fait de l'element une
     BOITE DE DEFILEMENT : un enfant en `position: sticky` se cale alors sur
     elle, qui ne defile pas, et il cesse de coller. Ca vaut pour le canevas
     de poussieres comme pour la bande laterale. `clip-path` detoure a la
     peinture et ne cree aucune boite de defilement. */
  clip-path: inset(0);
  padding-block: clamp(1.5rem, 0.9rem + 2.4vw, 3rem)
                 clamp(2.5rem, 1.4rem + 3.4vw, 4.5rem);
  background: linear-gradient(180deg, var(--gi-ink-900), var(--gi-ink-950));
}

.gi-art-layout {
  display: grid;
  grid-template-columns: minmax(0, var(--art-col)) minmax(0, var(--rail-w));
  justify-content: center;
  align-items: start;
  gap: var(--art-gap);
}

/* min-width 0, sinon un tableau large pousse la piste et fait deborder
   toute la page horizontalement. */
.gi-art-main { min-width: 0; }


/* ==========================================================================
   C2. LA COLONNE PARCHEMIN
   --------------------------------------------------------------------------
   LE PARCHEMIN N'A PAS DE MARGE INTERIEURE. Ce sont ses blocs qui portent
   la leur. C'est ce qui permet a l'image a la une d'etre bord a bord sans
   marge negative, donc sans valeur a tenir en correspondance a deux
   endroits.
   ========================================================================== */
.gi-art-paper {
  padding: 0;
  padding-bottom: clamp(1.5rem, 0.8rem + 2.4vw, 3rem);
  overflow: hidden;
}
.gi-art-paper__corners {
  inset: 10px;
  color: rgba(129, 86, 34, 0.5);
  z-index: 6;
}

.gi-art-head__body,
.gi-prose,
.gi-art-foot { padding-inline: var(--art-pad); }


/* ==========================================================================
   C3. L'EN-TETE, DANS LE PARCHEMIN
   --------------------------------------------------------------------------
   Image a la une, etiquette, titre, signature. Sous Divi c'est un seul
   module, `divi/post-title`, avec image.advanced.enabled = on.
   ========================================================================== */

/* L'IMAGE A LA UNE EST EN 16/9, PAS EN 21/8, et ce n'est pas un choix de
   dessin : toutes les images a la une du site sont produites en 1920x1080.
   Le cadre epouse donc la source, et le redacteur voit a l'ecran ce qu'il a
   depose. Aucun recadrage, donc aucune surprise. */
.gi-art-cover {
  position: relative;
  margin: 0;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--gi-ink-800);
}
.gi-art-cover img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Un fondu bas tres court : il assied l'image sur le papier au lieu de la
   laisser flotter, et il rattrape les visuels clairs en bas de cadre. */
.gi-art-cover::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 26%;
  background: linear-gradient(180deg,
    rgba(129, 86, 34, 0), rgba(112, 74, 28, 0.24));
}

/* LES TROIS ECARTS DE L'EN-TETE SONT SERRES D'UN CRAN, ET C'EST UNE
   CORRECTION DEMANDEE SUR LE RENDU REEL. Sur la maquette, avec une image de
   demonstration, ces valeurs passaient ; sur une vraie image a la une en
   16/9 pleine largeur, l'air entre l'image et les etiquettes se lisait
   comme un trou. Les trois valeurs bougent ENSEMBLE, ici et en C3 bis, pour
   que la maquette et le gabarit ne divergent pas d'un pixel. */
.gi-art-head__body {
  padding-top: clamp(0.85rem, 0.6rem + 0.9vw, 1.25rem);
  padding-bottom: clamp(1.2rem, 0.7rem + 1.8vw, 2rem);
}
/* L'en-tete se cale sur LA COLONNE DE TEXTE, pas sur la largeur du bloc.
   Etiquette, titre et signature partagent donc le bord gauche des
   paragraphes, et seuls les medias sortent de cette colonne. */
.gi-art-head__body > * {
  max-width: var(--art-measure);
  margin-inline: auto;
}

.gi-art-head__tags {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
  margin-bottom: 0.55rem;
}

/* ETIQUETTES SUR PAPIER. Les variantes de gi-tokens.css sont dessinees pour
   le fond sombre : texte clair sur teinte translucide. Posees telles quelles
   sur un beige a 88 % de clarte, elles disparaissent. Ce modifieur garde la
   teinte et retourne la valeur. */
.gi-tag--paper {
  background: rgba(129, 86, 34, 0.10);
  color: var(--gi-on-paper-accent);
  box-shadow: inset 0 0 0 1px rgba(129, 86, 34, 0.34);
}
.gi-tag--paper.gi-tag--maj {
  background: rgba(79, 166, 227, 0.16);
  color: #1D5C87;
  box-shadow: inset 0 0 0 1px rgba(79, 166, 227, 0.45);
}
.gi-tag--paper.gi-tag--guide {
  background: rgba(177, 137, 221, 0.20);
  color: #5B3E80;
  box-shadow: inset 0 0 0 1px rgba(177, 137, 221, 0.5);
}
.gi-tag--paper.gi-tag--event {
  background: rgba(143, 201, 58, 0.20);
  color: #4A6B14;
  box-shadow: inset 0 0 0 1px rgba(143, 201, 58, 0.5);
}
.gi-tag--paper.gi-tag--live {
  background: rgba(228, 105, 74, 0.18);
  color: #8C3418;
  box-shadow: inset 0 0 0 1px rgba(228, 105, 74, 0.48);
}

.gi-art-head__cat {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-family: var(--gi-font-display);
  font-weight: 700;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps-md);
  color: var(--gi-on-paper-accent);
  text-decoration: none;
}
.gi-art-head__cat svg { width: 12px; height: 12px; transition: translate var(--t-base) var(--ease-out); }
.gi-art-head__cat:hover svg { translate: 3px 0; }

/* LE TITRE EST EN INTER, PAS EN CINZEL : Cinzel porte des intitules, Inter
   porte des phrases. Un titre d'article est une phrase. */
.gi-art-title {
  font-family: var(--gi-font-body);
  font-weight: 700;
  font-size: clamp(1.7rem, 1.05rem + 2.2vw, 2.75rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--gi-on-paper);
}

/* LE TITRE REMPLIT SES LIGNES, MAIS IL RESTE DANS LA COLONNE DE TEXTE.

   `text-wrap: balance` EGALISAIT LES LIGNES, et c'est ce qui se voyait : la
   premiere s'arretait bien avant le bord parce que le navigateur cherchait
   deux lignes de meme longueur. `pretty` les remplit normalement et se
   contente d'eviter le mot seul en fin de titre. C'etait ca, le defaut.

   UN ESSAI A ETE FAIT ET RETIRE : elargir le titre a toute la place restante
   a sa droite, au motif que 43,5 rem valent 68 signes a 17 px mais seulement
   25 a 44 px. C'etait vrai sur le papier et faux a l'oeil. Le bord gauche
   restait aligne sur les paragraphes, le bord droit non, et une ligne de
   titre depassait la colonne de lecture d'une dizaine de caracteres. Un
   alignement sur deux ne se lit pas comme une largeur voulue, il se lit
   comme un debordement. Le titre tient donc la MEME mesure que le corps, et
   c'est `pretty` seul qui regle le retour a la ligne. */
.gi-art-title,
.gi-art-paper h1.entry-title { text-wrap: pretty; }

.gi-art-meta {
  display: flex;
  align-items: center;
  gap: 0.5rem 0.9rem;
  flex-wrap: wrap;
  margin-top: var(--sp-4);
  padding-top: 0.7rem;
  font-size: var(--fs-sm);
  color: var(--gi-on-paper-muted);
  border-top: 1px solid rgba(129, 86, 34, 0.24);
}
.gi-art-meta__item { display: inline-flex; align-items: center; gap: 0.4rem; }
.gi-art-meta__item svg { width: 15px; height: 15px; flex: none; color: var(--gi-gold-700); }
.gi-art-meta a {
  color: var(--gi-on-paper-accent);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: rgba(129, 86, 34, 0.42);
  text-underline-offset: 3px;
}
.gi-art-meta a:hover { color: #6A4519; }
.gi-art-meta__sep {
  width: 4px; height: 4px; flex: none;
  rotate: 45deg;
  background: var(--gi-gold-600);
}


/* ==========================================================================
   C3 bis. LE MEME EN-TETE, RENDU PAR `divi/post-title`
   --------------------------------------------------------------------------
   Au portage, l'en-tete ci-dessus n'est pas ecrit a la main : c'est le
   module `divi/post-title` qui le sort. Le HTML rendu donne son ordre, et
   IL EST DANS LE MAUVAIS SENS :

     .et_pb_post_title
      ├ .et_pb_title_container        → <h1 class="entry-title">, puis la meta
      └ .et_pb_title_featured_container → <span class="et_pb_image_wrap"><img>

   L'image a la une sort APRES le titre. Or elle est demandee en haut du
   parchemin, bord a bord. Divi 4 reglait ca avec `featured_placement`,
   aucun equivalent n'apparait dans les exports Divi 5.

   La parade coute deux declarations et aucune ligne de PHP : le module
   passe en colonne flex, et le conteneur d'image prend `order: -1`. Le
   repli connu, un module Image separe pose au-dessus, n'est plus
   necessaire.
   ========================================================================== */
.gi-art-paper .et_pb_post_title {
  display: flex;
  flex-direction: column;
  padding: 0;
  background: none;
}
.gi-art-paper .et_pb_title_featured_container {
  order: -1;
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--gi-ink-800);
}
/* Le meme fondu bas que `.gi-art-cover` de la maquette : il assied l'image
   sur le papier au lieu de la laisser flotter. */
.gi-art-paper .et_pb_title_featured_container::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 26%;
  background: linear-gradient(180deg,
    rgba(129, 86, 34, 0), rgba(112, 74, 28, 0.24));
}
.gi-art-paper .et_pb_title_featured_container :is(span, a) {
  display: block;
  width: 100%;
  height: 100%;
}
.gi-art-paper .et_pb_title_featured_container img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
  box-shadow: none;
}
/* LA COUTURE ENTRE L'IMAGE ET LE PAPIER. Le fondu seul asseyait l'image sans
   la separer : sur un visuel sombre en bas de cadre, elle se fondait dans le
   parchemin et l'en-tete n'avait plus de depart. Un filet dore d'un pixel,
   allume au centre et eteint aux deux bouts, tranche la question : c'est la
   meme grammaire que les filets de section du reste du site.

   IL VIT SUR ::before ET NON SUR ::after, avec un rang au-dessus : les deux
   pseudos sont peints dans l'ordre du document, et le fondu, qui est
   justement le plus dense en bas de cadre, l'aurait mange. */
.gi-art-cover::before,
.gi-art-paper .et_pb_title_featured_container::before {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  z-index: 3;
  height: 1px;
  background: linear-gradient(90deg,
    rgba(198, 165, 93, 0) 0%,
    rgba(198, 165, 93, 0.55) 18%,
    rgba(247, 235, 201, 0.9) 50%,
    rgba(198, 165, 93, 0.55) 82%,
    rgba(198, 165, 93, 0) 100%);
}
.gi-art-cover::after,
.gi-art-paper .et_pb_title_featured_container::after { z-index: 2; }

/* Le titre et la signature se calent sur la colonne de texte, exactement
   comme `.gi-art-head__body` de la maquette. */
.gi-art-paper .et_pb_title_container {
  padding-inline: var(--art-pad);
  padding-top: clamp(0.85rem, 0.6rem + 0.9vw, 1.25rem);
  padding-bottom: clamp(1.2rem, 0.7rem + 1.8vw, 2rem);
}
/* LES MARGES DE DIVI SUR LE TITRE ET SUR LA META SONT REMISES A PLAT, et
   c'est la vraie cause de l'ecart signale en front. `.entry-title` sort avec
   le `padding-bottom` de la feuille de Divi et le paragraphe de signature
   avec sa marge de paragraphe : elles s'ajoutaient a nos propres valeurs, et
   l'ecart titre -> filet -> signature faisait presque le double de la
   maquette. Deux classes suffisent a passer devant. */
.gi-art-paper h1.entry-title { margin-block: 0; padding: 0; }
/* Divi pose une marge basse sur le conteneur d'image a la une : elle
   s'ajoutait au remplissage haut du bloc de titre, et l'ecart entre l'image
   et le fil d'Ariane faisait presque le double de la maquette. */
.gi-art-paper .et_pb_title_featured_container { margin: 0; padding: 0; }
.gi-art-paper .et_pb_title_meta_container { margin-bottom: 0; padding-bottom: 0; }
.gi-art-paper .gi-art-head__tags { margin-bottom: 0.55rem; }
.gi-art-paper .et_pb_title_container > * {
  max-width: var(--art-measure);
  margin-inline: auto;
}
.gi-art-paper .entry-title { font: inherit; }
.gi-art-paper h1.entry-title {
  font-family: var(--gi-font-body);
  font-weight: 700;
  font-size: clamp(1.7rem, 1.05rem + 2.2vw, 2.75rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--gi-on-paper);
}
/* `gi-article.js` pose `gi-art-meta` sur ce paragraphe et remplace les
   barres verticales du module par les losanges du site : la ligne se lit
   alors exactement comme celle de la maquette. */
.gi-art-paper .et_pb_title_meta_container {
  display: flex;
  align-items: center;
  gap: 0.5rem 0.9rem;
  flex-wrap: wrap;
  margin-top: var(--sp-4);
  padding-top: 0.7rem;
  font-size: var(--fs-sm);
  color: var(--gi-on-paper-muted);
  border-top: 1px solid rgba(129, 86, 34, 0.24);
}
.gi-art-paper .et_pb_title_meta_container a {
  color: var(--gi-on-paper-accent);
  font-weight: 500;
  text-underline-offset: 3px;
}
/* LE COMPTEUR DE COMMENTAIRES NE SE CACHE PAS EN CSS, et il ne s'eteint pas
   non plus dans le module : le reglage pose au gabarit n'a pas pris au rendu,
   `<span class="comments-number">` est ressorti. La meta rendue est une seule
   phrase ou les separateurs sont du texte nu :
   `par <span class="author">…</span> | <span class="published">…</span> | …`
   Le masquer en CSS laisserait la barre verticale qui le precede, orpheline
   en fin de ligne. C'est donc `gi-article.js` qui retire les deux d'un coup,
   le noeud ET sa barre. Une regle `display:none` ici ne suffirait pas. */


/* ==========================================================================
   C4. LES DEUX LARGEURS
   --------------------------------------------------------------------------
   Le TEXTE est ramene a la mesure de lecture et centre. Les MEDIAS, images,
   videos, tableaux, blocs de code, accordeons, prennent toute la largeur du
   bloc. C'est ce qui permet a la page d'etre large comme le reste du site
   sans qu'une ligne depasse 70 caracteres.

   LA LISTE DES PORTEURS DE TEXTE compte trois entrees et non une, parce que
   le contenu peut arriver sous deux formes :
   - `.gi-prose`, quand le contenu vient de l'editeur ;
   - `.et_pb_text` et `.et_pb_text_inner`, quand il vient d'un module Texte
     du Builder. C'est le cas reel sur ce site.
   ========================================================================== */
.gi-prose {
  font-family: var(--gi-font-body);
  font-size: 1.0625rem;       /* 17 px, la lecture longue merite un cran   */
  line-height: 1.78;
  color: var(--gi-on-paper-body);
  overflow-wrap: break-word;
}

:is(.gi-prose, .gi-prose .et_pb_text, .gi-prose .et_pb_text_inner)
  > :is(p, h1, h2, h3, h4, h5, h6, ul, ol, dl, blockquote) {
  max-width: var(--art-measure);
  margin-inline: auto;
}

/* L'ENCADRE A SA PROPRE REGLE, ET CE N'EST PAS UN DETAIL DE STYLE. Range
   dans le :is() ci-dessus, sa classe faisait monter TOUT le selecteur d'un
   cran, et la regle :has() juste en dessous perdait. Une image posee nue
   dans un paragraphe sortait alors a la mesure de lecture pendant que la
   meme image en module prenait la pleine largeur : deux comportements pour
   la meme image, exactement ce que la partie C5 existe pour empecher. */
.gi-prose .gi-callout {
  max-width: var(--art-measure);
  margin-inline: auto;
}

/* Un paragraphe qui ne contient qu'une image est un media, pas du texte.
   Si :has() n'est pas la, l'image sort simplement a la mesure de lecture :
   la degradation est moche, elle n'est pas cassee. */
:is(.gi-prose, .gi-prose .et_pb_text, .gi-prose .et_pb_text_inner)
  > p:has(> img) { max-width: none; }

.gi-prose > * + * { margin-top: 1.15em; }
.gi-prose > :last-child { margin-bottom: 0; }


/* ==========================================================================
   C4 bis. LA TYPOGRAPHIE DU CONTENU
   --------------------------------------------------------------------------
   Tous les selecteurs sont EN DESCENDANCE et non en enfant direct : sous le
   Builder, un paragraphe est a quatre niveaux de `.gi-prose`.
   ========================================================================== */

/* --- Le chapo -------------------------------------------------------- */
/* `first-of-type` et non `first-child` : gi-hover.js insere un canvas en
   premier enfant au survol, et toute regle en first-child tomberait. */
.gi-prose > p:first-of-type,
.gi-prose > .et_pb_text:first-of-type .et_pb_text_inner > p:first-of-type {
  font-size: 1.2rem;
  line-height: 1.62;
  color: var(--gi-on-paper);
  font-weight: 450;
}

/* --- Intertitres ------------------------------------------------------ */
/* h2 : un filet dore en travers, une etoile posee a gauche dessus. C'est le
   meme masque que les titres de section de l'accueil, et c'est ce qui
   rattache le corps d'article au reste du site.

   LA REGLE PORTE AUSSI SUR h3 QUAND L'ARTICLE N'A PAS DE h2. Les articles
   reels ouvrent leurs sections en h3, l'habitude est prise et on ne va pas
   demander a la redaction de la changer. Un script pose `gi-prose--h3` sur
   le bloc quand le plus haut niveau rencontre est h3, et h3 recoit alors le
   traitement de section. Personne n'a rien a faire. */
.gi-prose h2,
.gi-prose--h3 h3 {
  position: relative;
  margin-top: 2.9rem;
  margin-bottom: 0.9rem;
  padding-top: 1.5rem;
  /* L'ETOILE EST EN LIGNE, DEVANT LE TITRE, ET C'EST UNE CORRECTION
     DEMANDEE. Elle etait posee en absolu sur le filet, donc SUR LA LIGNE
     AU-DESSUS du titre : de loin ca ne se lisait pas comme un ornement de
     titre mais comme une poussiere. Le titre passe en boite flex et
     l'etoile, qui vit sur ::after, remonte en premier avec `order: -1`.
     Le filet garde ::before et reste en absolu : les deux pseudos servent,
     aucun n'est en trop. */
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  font-family: var(--gi-font-body);
  font-weight: 700;
  font-size: clamp(1.38rem, 1.15rem + 0.9vw, 1.7rem);
  line-height: 1.24;
  letter-spacing: -0.016em;
  color: var(--gi-on-paper);
  text-wrap: balance;
  /* Le sommaire flottant amene ici par ancre : le titre ne doit pas passer
     sous l'en-tete colle. */
  scroll-margin-top: calc(74px + 1.5rem);
}
.gi-prose h2::before,
.gi-prose--h3 h3::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  width: auto; height: 1px;
  rotate: none;
  translate: none;
  background: linear-gradient(90deg,
    rgba(129, 86, 34, 0.55), rgba(129, 86, 34, 0.16) 46%, rgba(129, 86, 34, 0));
}
/* L'ETOILE SE MESURE EN `em` ET SE CALE SUR LA HAUTEUR DE CAPITALE, PAS SUR
   LA LIGNE DE BASE. Un pseudo-element sans texte n'a pas de ligne de base :
   la boite flex lui en synthetise une SUR SON BORD BAS, si bien qu'il se
   posait ASSIS sur la ligne d'ecriture, donc trop bas d'a peu pres la moitie
   d'une capitale. Il fallait le remonter de la difference : 0,36 em, la
   demi-capitale d'Inter, moins son propre demi-cote.

   La taille en `em` n'est pas de la coquetterie : le titre est en `clamp()`,
   il fait 22 px sur telephone et 27 px sur grand ecran. En pixels fixes,
   l'etoile etait juste a une seule largeur d'ecran. */
.gi-prose h2::after,
.gi-prose--h3 h3::after {
  content: "";
  order: -1;
  flex: none;
  width: 0.42em; height: 0.42em;
  translate: 0 -0.15em;
  background: var(--gi-on-paper-accent);
  -webkit-mask: var(--gi-star) center / contain no-repeat;
          mask: var(--gi-star) center / contain no-repeat;
}
/* Les redacteurs ecrivent `<h3><strong>Titre</strong></h3>` : le gras est
   deja porte par le titre, le doubler l'epaissit sans rien dire. */
.gi-prose :is(h1, h2, h3, h4, h5, h6) strong { font-weight: inherit; }

/* h3 : un losange dore en tete de ligne, sans filet. Uniquement quand
   l'article a de vrais h2 au-dessus.

   `:not(.gi-prose--h3)` N'EST PAS UNE PRECAUTION, C'EST LA CORRECTION D'UN
   CONFLIT DE CASCADE CONSTATE EN FRONT. Ecrit `.gi-prose h3`, ce bloc valait
   (0,1,1), exactement comme `.gi-prose--h3 h3` juste au-dessus, et il
   arrivait APRES : dans un article sans h2, il reprenait la main sur le
   traitement de section. Pire, `.gi-prose h3::before` redefinissait la
   taille et le fond du filet SANS toucher a `position: absolute` : le filet
   devenait un carre dore de 7 px flottant a 1,5 rem du bord, sur la ligne
   du dessus. C'est ce que la redaction voyait. Un seul `:not()` et les deux
   traitements cessent de se croiser. */
.gi-prose:not(.gi-prose--h3) h3 {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-top: 2.1rem;
  margin-bottom: 0.6rem;
  font-family: var(--gi-font-body);
  font-weight: 600;
  font-size: 1.19rem;
  line-height: 1.35;
  letter-spacing: -0.012em;
  color: var(--gi-on-paper);
  scroll-margin-top: calc(74px + 1.5rem);
}
/* Meme calage que l'etoile de h2, meme raison, meme unite. Le losange est
   tourne de 45 degres : `translate` s'applique AVANT `rotate` dans l'ordre
   fixe des proprietes individuelles, donc le decalage se lit bien a la
   verticale et non de biais. */
.gi-prose:not(.gi-prose--h3) h3::before {
  content: "";
  position: static;
  width: 0.38em; height: 0.38em; flex: none;
  rotate: 45deg;
  translate: 0 -0.17em;
  background: var(--gi-gold-600);
}

/* h4 : le seul intertitre en Cinzel, parce qu'a ce niveau ce sont des
   intitules courts et non des phrases. */
.gi-prose h4 {
  margin-top: 1.8rem;
  margin-bottom: 0.4rem;
  font-family: var(--gi-font-display);
  font-weight: 700;
  font-size: 0.86rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps-md);
  color: var(--gi-on-paper-muted);
}

/* h5 et h6. LE HTML RENDU A MONTRE QU'ILS SERVENT VRAIMENT, et pas comme
   des restes : l'article de Mona ouvre ses blocs de build en h5, avec un
   picto de personnage ou d'element en tete de ligne. Sans regle ils
   tombaient sur le style par defaut du navigateur, plus petits que le corps
   et en gras noir.

   `:not(.et_pb_toggle_title)` N'EST PAS UNE PRECAUTION : l'intitule de
   l'accordeon de Divi EST un h5. Constate au rendu :
   `<h5 class="et_pb_toggle_title">Cliquez pour afficher le build</h5>`.
   Sans ce retrait, un intitule d'accordeon recevait la casse haute et le
   filet de section. */
.gi-prose h5:not(.et_pb_toggle_title) {
  margin-top: 1.9rem;
  margin-bottom: 0.35rem;
  font-family: var(--gi-font-body);
  font-weight: 650;
  font-size: 1.06rem;
  line-height: 1.4;
  color: var(--gi-on-paper);
  scroll-margin-top: calc(74px + 1.5rem);
}
.gi-prose h6 {
  margin-top: 1.6rem;
  margin-bottom: 0.3rem;
  font-family: var(--gi-font-body);
  font-weight: 650;
  font-size: 0.98rem;
  line-height: 1.4;
  color: var(--gi-on-paper-muted);
}

/* --- Enrichissements de texte ---------------------------------------- */
.gi-prose p { margin-top: 1.15em; }
.gi-prose strong, .gi-prose b { font-weight: 650; color: var(--gi-on-paper); }
.gi-prose em, .gi-prose i { font-style: italic; }

/* LES LIENS SONT EN BRONZE, JAMAIS EN OR. L'or a 57 % de clarte sur un
   beige a 88 % echoue au contraste et se noie. */
.gi-prose a {
  color: var(--gi-on-paper-accent);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(129, 86, 34, 0.42);
  text-underline-offset: 3px;
  transition: color var(--t-fast), text-decoration-color var(--t-fast);
}
.gi-prose a:hover {
  color: #6A4519;
  text-decoration-thickness: 2px;
  text-decoration-color: rgba(129, 86, 34, 0.9);
}

.gi-prose mark {
  background: rgba(219, 192, 132, 0.42);
  color: var(--gi-on-paper);
  padding: 0.05em 0.22em;
  border-radius: 3px;
}
.gi-prose abbr[title] { text-decoration: underline dotted rgba(129, 86, 34, 0.6); }
.gi-prose sup, .gi-prose sub { font-size: 0.72em; }

/* --- Listes ----------------------------------------------------------- */
/* LES PUCES SONT DES LOSANGES DORES, partout, sans que le redacteur ait
   quoi que ce soit a faire : il pose une liste a puces normale. */
.gi-prose ul,
.gi-prose ol {
  margin-top: 1.15em;
  padding-left: 1.6rem;
  list-style: none;
}
.gi-prose li { position: relative; margin-block: 0.42em; }
.gi-prose li > ul,
.gi-prose li > ol { margin-top: 0.42em; margin-bottom: 0.2em; }

.gi-prose ul > li::before {
  content: "";
  position: absolute;
  left: -1.25rem; top: 0.68em;
  width: 7px; height: 7px;
  rotate: 45deg;
  background: var(--gi-gold-600);
}
/* Deuxieme niveau : le losange se creuse au lieu de changer de couleur. */
.gi-prose li ul > li::before {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--gi-gold-700);
}

.gi-prose ol { counter-reset: gi-ol; }
.gi-prose ol > li { counter-increment: gi-ol; padding-left: 0.15rem; }
.gi-prose ol > li::before {
  content: counter(gi-ol);
  position: absolute;
  left: -1.85rem; top: 0.02em;
  width: 1.4rem;
  text-align: right;
  font-family: var(--gi-font-display);
  font-weight: 700;
  font-size: 0.88rem;
  color: var(--gi-on-paper-accent);
}

.gi-prose dl { margin-top: 1.15em; }
.gi-prose dt { font-weight: 650; color: var(--gi-on-paper); margin-top: 0.8em; }
.gi-prose dd { margin-left: 1.2rem; }

/* UN BLOCKQUOTE VIDE NE S'AFFICHE PAS. Les articles en contiennent, laisses
   par l'editeur : rendus, ils dessinaient un bloc beige de 3 rem au milieu
   du texte, sans un mot dedans. `:empty` attrape `<blockquote></blockquote>`,
   qui est le cas reel constate ; ceux qui ne contiennent que du blanc ou un
   `&nbsp;` ne sont PAS vides au sens de CSS, et c'est `gi-article.js` qui
   les retire. Les deux se completent, aucun ne suffit seul. */
.gi-prose blockquote:empty { display: none; }

/* --- Le blockquote, QUI N'EST PAS UNE CITATION ------------------------- */
/* LE HTML RENDU A TRANCHE. On avait dessine un bloc de citation, guillemet
   ornemental et corps plus gros. Ce n'est pas de ca que la redaction se
   sert. Dans l'article de Mona, les blockquote contiennent :

     <blockquote><p><strong>Sommaire :</strong></p><ul><li><a>...</a></li></ul>
     <blockquote><p><strong>Personnages hexeres :</strong></p>...
     <blockquote><p><strong>Mona C6 DPS :</strong></p>...

   Ce sont des ENCADRES : un sommaire local, une liste d'a-cotes, un conseil
   de build. Jamais une parole rapportee. Un guillemet geant devant
   « Sommaire : » ment sur le contenu, et grossir le texte d'une liste de
   liens la rend plus lourde que la section qu'elle annonce.

   Donc : meme papier, meme filet dore a gauche, mais AUCUN glyphe et la
   taille du corps. Le bloc se lit comme un a-cote, pas comme une envolee.

   `margin-inline: auto` et non 0 : le navigateur pose 40 px de marge
   laterale par defaut sur blockquote et sur figure. Sans ce retrait les
   deux blocs partaient en biais du reste de la colonne. */
.gi-prose blockquote {
  position: relative;
  margin-top: 2rem;
  margin-bottom: 2rem;
  padding: 1.15rem 1.35rem 1.15rem 1.5rem;
  border-radius: var(--r-md);
  background: linear-gradient(180deg,
    rgba(255, 252, 242, 0.62), rgba(211, 193, 166, 0.26));
  box-shadow:
    inset 3px 0 0 var(--gi-gold-600),
    inset 0 0 0 1px rgba(129, 86, 34, 0.18);
  color: var(--gi-on-paper-body);
  font-size: 1rem;
  line-height: 1.7;
}
/* L'intitule d'ouverture, « Sommaire : », « Personnages hexeres : ». Il est
   toujours ecrit en gras dans un premier paragraphe : on le traite comme le
   titre de l'encadre plutot que comme du gras au milieu du texte. */
.gi-prose blockquote > p:first-of-type strong,
.gi-prose blockquote > p:first-of-type span > strong {
  display: inline-block;
  margin-bottom: 0.1rem;
  font-family: var(--gi-font-display);
  font-weight: 700;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps-md);
  color: var(--gi-on-paper-accent);
}
/* Une liste dans un encadre est deja indentee par l'encadre : elle ne
   redemande pas la gouttiere pleine. */
.gi-prose blockquote :is(ul, ol) { padding-left: 1.35rem; }
.gi-prose blockquote li { margin-block: 0.28em; }
/* Le premier paragraphe ne doit pas repousser le bloc :
   les redacteurs ecrivent toujours <blockquote><p>. */
.gi-prose blockquote > :first-child { margin-top: 0; }
.gi-prose blockquote > :last-child { margin-bottom: 0; }
.gi-prose blockquote cite,
.gi-prose blockquote footer {
  display: block;
  margin-top: 0.8em;
  font-size: var(--fs-sm);
  font-style: normal;
  color: var(--gi-on-paper-muted);
}
.gi-prose blockquote cite::before,
.gi-prose blockquote footer::before { content: "\2014\00A0"; }

/* --- Code -------------------------------------------------------------- */
.gi-prose code,
.gi-prose kbd,
.gi-prose samp {
  font-family: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, monospace;
  font-size: 0.88em;
  padding: 0.12em 0.38em;
  border-radius: var(--r-xs);
  background: rgba(129, 86, 34, 0.11);
  box-shadow: inset 0 0 0 1px rgba(129, 86, 34, 0.2);
  color: #6A4519;
}
.gi-prose pre {
  margin-top: 1.7rem;
  margin-bottom: 1.7rem;
  padding: 1.1rem 1.25rem;
  overflow-x: auto;
  border-radius: var(--r-md);
  background: linear-gradient(165deg, var(--gi-ink-800), var(--gi-ink-950));
  box-shadow: inset 0 0 0 1px rgba(198, 165, 93, 0.22);
  color: var(--gi-sand-100);
  font-size: 0.86rem;
  line-height: 1.6;
}
.gi-prose pre code {
  padding: 0; background: none; box-shadow: none;
  color: inherit; font-size: 1em;
}


/* ==========================================================================
   C5. LE SYSTEME D'IMAGE UNIQUE
   --------------------------------------------------------------------------
   TOUTES LES IMAGES POSEES PAR LES REDACTEURS SORTENT IDENTIQUES.
   Meme largeur, meme rapport de coins, meme ombre, meme legende, que
   l'image vienne d'un module Image du Builder, d'un bloc de l'editeur,
   d'une galerie ou d'une balise collee a la main.

   Ce que ca implique, et qui est le prix a payer :
   - les alignements de l'editeur, alignleft, alignright, aligncenter,
     alignwide, alignfull, sont NEUTRALISES. Plus d'habillage de texte ;
   - une vignette posee en petit est agrandie a la largeur du bloc. La
     parade est de refuser les petites images a la redaction, pas de rouvrir
     une exception ;
   - une image vraiment en ligne, un picto dans une phrase, doit porter la
     classe `gi-inline`. C'est la seule echappatoire, et elle est explicite.
     Le script de page la pose tout seul sur les separateurs en PNG, voir
     la partie C6.

   `!important` est assume ici : les classes d'alignement de WordPress
   arrivent avec leur propre feuille, et le CSS de page de Divi vit en fin
   de body. A specificite egale ils gagnent.
   ========================================================================== */

/* 1. Les conteneurs, ceux de l'editeur ET ceux de Divi. Aucun ne flotte,
      aucun ne se retrecit.

      `a.et_pb_lightbox_image` EST DANS LA LISTE, et ce n'est pas theorique :
      le HTML rendu montre que le module Image enveloppe systematiquement son
      image d'un lien de visionneuse,
      `.et_pb_image > a.et_pb_lightbox_image > span.et_pb_image_wrap > img`.
      Un `<a>` est en ligne par defaut : sans cette entree, l'image se posait
      sur une ligne de texte et heritait de son interligne. */
.gi-prose :is(figure, .wp-block-image, .wp-caption, .gi-figure,
              .et_pb_image, .et_pb_image_wrap, a.et_pb_lightbox_image,
              .et_pb_video, .et_pb_video_box) {
  float: none !important;
  clear: both;
  display: block;
  width: 100% !important;
  max-width: 100% !important;
  margin-inline: 0 !important;
}
.gi-prose :is(figure, .wp-block-image, .wp-caption, .gi-figure,
              .et_pb_image, .et_pb_video) {
  margin-top: 2rem;
  margin-bottom: 2rem;
}

/* 2. Les classes d'alignement de l'editeur, mises hors circuit. */
.gi-prose :is(.alignleft, .alignright, .aligncenter, .alignwide, .alignfull,
              .alignnone) {
  float: none !important;
  width: 100% !important;
  max-width: 100% !important;
  margin-inline: 0 !important;
}

/* 3. L'image elle-meme. Un seul jeu de valeurs, un seul endroit ou le
      changer. */
.gi-prose img,
.gi-prose video,
.gi-prose iframe {
  display: block;
  width: 100%;
  height: auto;
  margin-inline: 0;
  border-radius: var(--r-md);
  box-shadow:
    inset 0 0 0 1px rgba(129, 86, 34, 0.3),
    var(--sh-2);
}
.gi-prose :is(iframe, .et_pb_video_box) { aspect-ratio: 16 / 9; height: auto; }
.gi-prose .et_pb_video_box iframe { height: 100%; }

/* 4. LES DEUX ECHAPPATOIRES, ET ELLES SONT AUTOMATIQUES.

      La regle « toutes les images pareil » est juste tant qu'une image est
      un visuel. Le HTML rendu de l'article de Mona montre qu'elle ne l'est
      pas toujours :

        <h5><img src="Durin-0.png" width="30" height="30"> Durin</h5>
        <h5><img src="Element_Pyro.webp" width="24" height="24"> MDPS Pyro</h5>

      Ce sont des pictos de personnage et d'element poses DANS un intertitre.
      Etires a 858 px ils devenaient des affiches, et l'intertitre passait
      sous elles. La redaction fait ca partout, et lui demander de poser une
      classe reviendrait a lui demander d'ouvrir un champ de CSS.

      Donc deux exceptions, aucune a poser a la main :
      a. une image DANS un intertitre reste un picto en ligne ;
      b. une image de 64 px ou moins reste a sa taille. Le script de page lui
         pose `gi-inline` en lisant ses attributs `width` et `height`, sans
         attendre le chargement. */

/* a. Le picto d'intertitre. */
.gi-prose :is(h1, h2, h3, h4, h5, h6) img {
  display: inline-block;
  width: auto !important;
  max-width: none !important;
  height: auto;
  margin: 0 0.15em 0 0;
  vertical-align: -0.18em;
  border-radius: var(--r-xs);
  box-shadow: none;
}
/* Un h3 est en flex : l'image y est un element de la boite, pas un
   caractere. On lui rend son alignement. */
.gi-prose h3 img { align-self: center; vertical-align: middle; }

/* b. L'echappatoire generale, posee par le script ou a la main. */
.gi-prose img.gi-inline {
  display: inline;
  width: auto !important;
  max-width: 100%;
  height: auto;
  vertical-align: middle;
  border-radius: var(--r-xs);
  box-shadow: none;
}

/* 5. La legende, identique d'ou qu'elle vienne. */
.gi-prose :is(figcaption, .wp-caption-text) {
  margin-top: 0.65rem;
  padding-left: 0.85rem;
  border-left: 2px solid var(--gi-gold-600);
  font-size: var(--fs-sm);
  line-height: 1.5;
  font-style: normal;
  color: var(--gi-on-paper-muted);
  text-align: left;
}

/* 6. Deux images cote a cote. Elles arrivent soit d'une galerie de
      l'editeur, soit d'une rangee a deux colonnes du Builder, qui est la
      facon dont les redacteurs le font vraiment. Les deux sont tenues. */
.gi-prose :is(.wp-block-gallery, .gi-duo) {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  margin-top: 2rem;
  margin-bottom: 2rem;
  list-style: none;
  padding: 0;
}
.gi-prose :is(.wp-block-gallery, .gi-duo) figure { margin: 0; }


/* ==========================================================================
   C6. LE SEPARATEUR
   --------------------------------------------------------------------------
   LE MODULE SEPARATEUR DE DIVI REND L'ORNEMENT DU SITE. Le redacteur pose
   un module Separateur, il obtient le losange et le filet. Il n'a ni classe
   a mettre, ni CSS a ecrire.

   La meme regle vaut pour `<hr>`, pour que les deux formes soient
   interchangeables.

   MIGRATION DES ANCIENS SEPARATEURS. Les articles actuels posent un PNG de
   300 x 9 en guise de trait, dix-sept fois dans le seul article de la 5.8.
   Le script de page le detecte a son rapport de forme et le remplace par un
   vrai separateur. Les anciens articles heritent donc de l'ornement sans
   qu'on y touche.
   ========================================================================== */
.gi-prose :is(hr, .et_pb_divider) {
  position: relative;
  display: block;
  width: auto;
  height: 1px;
  min-height: 0;
  max-width: var(--art-measure);
  margin: 2.6rem auto;
  padding: 0;
  border: 0;
  background: linear-gradient(90deg,
    transparent, rgba(129, 86, 34, 0.35) 30%, rgba(129, 86, 34, 0.35) 70%, transparent);
  overflow: visible;
}
/* CONSTATE dans « Base d'article 2024 » : le module Separateur porte
   `divider.advanced.line.{color, style, position}`, et l'instance reelle y
   met du bleu, `rgba(46, 101, 162, 0.2)`, en `solid` et en `top`. La
   couleur du trait est donc NATIVE, et au portage elle doit passer par un
   preset « GIFR Separateur » plutot que par ce fichier. Ici on eteint le
   trait de Divi, tire sur ::before par une bordure haute, plutot que de se
   battre avec, et on garde ::after pour le losange. */
.gi-prose .et_pb_divider::before,
.gi-prose .et_pb_divider_internal {
  border: 0 !important;
  display: none !important;
}
/* DEUX SEPARATEURS COLLES N'EN FONT QU'UN. Le cas se produit tout seul :
   la conversion des anciens PNG en pose un par image, et les articles en
   alignent parfois deux, une fois pour fermer la section et une fois pour
   ouvrir la suivante. Deux losanges a huit pixels l'un de l'autre se lisent
   comme un defaut d'affichage, pas comme un ornement. */
.gi-prose :is(hr, .et_pb_divider) + :is(hr, .et_pb_divider) { display: none; }
/* Pas de regle en `:first-child` ici, et ce n'est pas un oubli : gi-hover.js
   insere un canvas en premier enfant au survol, toute regle assise sur le
   premier enfant tombe des qu'on passe la souris. */

.gi-prose :is(hr, .et_pb_divider)::after {
  content: "";
  position: absolute;
  left: 50%; top: -4px;
  width: 9px; height: 9px;
  rotate: 45deg;
  translate: -50% 0;
  background: var(--gi-paper-100);
  box-shadow: 0 0 0 1px var(--gi-gold-600), 0 0 0 5px var(--gi-paper-100);
}


/* ==========================================================================
   C7. L'ACCORDEON
   --------------------------------------------------------------------------
   Module frequemment utilise par la redaction. Il est habille ici sous ses
   DEUX formes : les classes de Divi, `.et_pb_accordion` et `.et_pb_toggle`,
   et la balise native `<details>`, qui sert a la maquette et marche sans
   une ligne de JS.

   CE QUE « BASE D'ARTICLE 2024 » A CONSTATE, sur une instance reelle :

     title.decoration.font.font.{color, weight, capitalization}
     openToggle.decoration.{background.color, font.font.color}
     closedToggle.decoration.{background.color, font.font.{color,textAlign}}
     closedToggleIcon.decoration.icon.{unicode, type: "divi", weight}
     content.decoration.bodyFont.body.font.{color, textAlign}
     module.decoration.{background, border.radius, border.styles, spacing}

   Et l'accordeon CONTIENT DES MODULES ENFANTS : dans l'export, un module
   Texte et un module Image sont poses entre ses balises ouvrante et
   fermante. Ce sont donc les regles de contenu de ce fichier qui
   s'appliquent a l'interieur, pas un habillage separe.

   Trois consequences.

   1. FOND, COULEUR, GRAISSE ET TYPOGRAPHIE DU CONTENU SE REGLENT
      NATIVEMENT. Au portage, c'est un preset qui doit les porter, pas ce
      fichier : ca gagne la cascade sans !important et ca reste modifiable
      a la souris.

   2. PIEGE. Le preset existant porte les valeurs de l'ancien site,
      `rgba(2,2,2,0.5)` et du blanc, et l'instance de « Base d'article
      2024 » porte du rouge, `rgba(255,0,0,0.5)`, `#c03f3f`, `#e7bdbd`.
      Sur parchemin c'est illisible, et le CSS de page de Divi vit en fin
      de body : il gagnera contre ces regles-ci. **IL FAUT UN PRESET
      « GIFR Accordeon » aux valeurs papier**, pas esperer que le CSS
      l'emporte.

   3. L'ICONE EST NATIVE, en police d'icones Divi. On la remplace tout de
      meme par un chevron dessine : la police d'icones de Divi n'est pas
      garantie chargee sur nos gabarits, et ses glyphes ne sont pas les
      notres. Notre chevron vit sur ::before du titre, la ou Divi 4 posait
      le sien : il le remplace au lieu de s'ajouter.

   LES CLASSES RENDUES, MAINTENANT CONSTATEES. Le HTML rendu de l'article de
   Mona les donne, et elles corrigent une supposition fausse :

     <div class="et_pb_accordion_0 et_pb_accordion et_pb_module et_block_module">
       <div class="et_pb_accordion_item_0 et_pb_accordion_item et_pb_toggle
                   et_pb_module et_pb_toggle_open et_block_module">
         <h5 class="et_pb_toggle_title">Cliquez pour afficher le build</h5>
         <div class="et_pb_toggle_content">...</div>
       </div>
       <div class="... et_pb_toggle et_pb_module et_pb_toggle_close ...">

   Trois enseignements.
   1. L'etat ferme est `et_pb_toggle_close`, PAS `et_pb_toggle_closed`. La
      regle ecrite au jugé ne se serait jamais appliquee.
   2. L'intitule est un `<h5>`. D'ou le `:not(.et_pb_toggle_title)` sur les
      regles de h5 en partie C4 bis.
   3. Un item porte AUSSI `.et_pb_module`. C'est la raison pour laquelle la
      partie C9 ne neutralise plus `.et_pb_module` en bloc : elle effacait le
      fond parchemin pose ici.
   ========================================================================== */
.gi-prose :is(.et_pb_accordion, .gi-accordion-group) {
  display: grid;
  gap: 0.5rem;
  margin-top: 2rem;
  margin-bottom: 2rem;
}
.gi-prose :is(.et_pb_toggle, .et_pb_accordion_item, details.gi-accordion) {
  border-radius: var(--r-md);
  background: linear-gradient(180deg,
    rgba(255, 252, 242, 0.6), rgba(211, 193, 166, 0.24));
  box-shadow: inset 0 0 0 1px rgba(129, 86, 34, 0.22);
  overflow: hidden;
}
/* L'intitule. `list-style: none` sur summary et le pseudo webkit : sans les
   deux, le triangle natif reste et double le chevron. */
.gi-prose :is(.et_pb_toggle_title, details.gi-accordion > summary) {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0;
  padding: 0.95rem 1.2rem;
  font-family: var(--gi-font-body);
  font-weight: 650;
  font-size: 1.02rem;
  line-height: 1.35;
  color: var(--gi-on-paper);
  cursor: pointer;
  list-style: none;
  transition: background-color var(--t-fast);
}
/* LA COULEUR DE L'INTITULE SE REPREND A (0,5,1), ET LE CHIFFRE EST MESURE.
   Le preset par defaut de l'accordeon porte l'heritage de l'ancien site et
   sort ceci dans le CSS de page, en fin de <body> :

     .preset--module--divi-accordion--default.et_pb_accordion
       .et_pb_toggle_open .et_pb_toggle_title { color:#ffffff }

   Soit (0,4,0). Notre regle ci-dessus vaut (0,2,0) : du blanc sur parchemin,
   c'est-a-dire un intitule invisible, exactement ce que la redaction a
   signale. La bonne reponse RESTE de degraisser ce preset dans Divi ; en
   attendant, on repasse devant sans un seul !important. La balise `h5` du
   selecteur n'est pas decorative, c'est elle qui donne le cran de trop. */
.gi-prose .et_pb_accordion .et_pb_toggle h5.et_pb_toggle_title,
.gi-prose .et_pb_accordion .et_pb_toggle.et_pb_toggle_open h5.et_pb_toggle_title {
  color: var(--gi-on-paper);
}

.gi-prose details.gi-accordion > summary::-webkit-details-marker { display: none; }
.gi-prose :is(.et_pb_toggle_title, details.gi-accordion > summary):hover {
  background: rgba(129, 86, 34, 0.07);
}
/* Le chevron, dessine en deux traits plutot qu'avec la police d'icones de
   Divi : elle n'est pas garantie chargee sur nos gabarits. */
.gi-prose :is(.et_pb_toggle_title, details.gi-accordion > summary)::before {
  content: "";
  order: 2;
  margin-left: auto;
  width: 9px; height: 9px;
  flex: none;
  border-right: 2px solid var(--gi-on-paper-accent);
  border-bottom: 2px solid var(--gi-on-paper-accent);
  rotate: 45deg;
  translate: 0 -2px;
  transition: rotate var(--t-base) var(--ease-out), translate var(--t-base) var(--ease-out);
}
.gi-prose details.gi-accordion[open] > summary::before,
.gi-prose .et_pb_toggle_open .et_pb_toggle_title::before {
  rotate: -135deg;
  translate: 0 2px;
}
/* Divi peut poser son picto sur ::after du titre, ou dans un vrai element
   porte par sa police d'icones. Les deux sont eteints : le chevron dessine
   ci-dessus le remplace. */
.gi-prose .et_pb_toggle_title::after { display: none !important; }
.gi-prose :is(.et_pb_toggle_icon, .et_pb_accordion_toggle_icon,
              .et_pb_toggle_title > .et-pb-icon) { display: none !important; }

/* L'etat ferme, CONSTATE : `et_pb_toggle_close` et non `et_pb_toggle_closed`.
   La regle est doublee ici bien que Divi la pose deja : rien ne garantit que
   la feuille d'accordeon de Divi soit chargee sur un gabarit de Theme
   Builder, et un accordeon qui s'ouvre tout entier au chargement est un
   defaut visible. */
.gi-prose .et_pb_toggle_close .et_pb_toggle_content { display: none; }

.gi-prose :is(.et_pb_toggle_content, details.gi-accordion > :not(summary)) {
  padding: 0 1.2rem 1.1rem;
  font-size: 1rem;
  line-height: 1.7;
}
.gi-prose :is(.et_pb_toggle_content, details.gi-accordion > :not(summary)) > :first-child { margin-top: 0; }
/* Dans un accordeon, le texte ne se re-limite pas : le bloc est deja
   etroit, et une deuxieme mesure dans la mesure creerait un escalier. */
.gi-prose :is(.et_pb_toggle_content, details.gi-accordion) :is(p, ul, ol, blockquote) {
  max-width: none;
}


/* ==========================================================================
   C8. LES TABLEAUX
   --------------------------------------------------------------------------
   AUCUN MODULE TABLEAU N'EXISTE DANS DIVI, ni en 4 ni en 5, et aucun n'a
   ete trouve dans les exports. La voie fiable est donc un tableau HTML
   colle dans un module Texte : un copier-coller depuis un tableur produit
   exactement ca, et l'editeur de Divi l'accepte.

   Le redacteur n'a RIEN a faire : le script de page enveloppe tout seul les
   tableaux nus dans un conteneur a defilement. Aucune classe a poser.

   L'en-tete de tableau est le seul ilot sombre de la colonne claire : il
   sert de barre de titre et rappelle que le site est nocturne.
   ========================================================================== */
.gi-prose :is(.gi-tablewrap, figure.wp-block-table, .wp-block-table) {
  margin-top: 2rem;
  margin-bottom: 2rem;
  overflow-x: auto;
  border-radius: var(--r-md);
  box-shadow: inset 0 0 0 1px rgba(129, 86, 34, 0.22);
}
.gi-prose table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.95rem;
  line-height: 1.5;
}
.gi-prose thead th {
  padding: 0.8rem 1rem;
  text-align: left;
  vertical-align: bottom;
  font-family: var(--gi-font-display);
  font-weight: 700;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps-md);
  color: var(--gi-gold-300);
  background: linear-gradient(180deg, var(--gi-ink-800), var(--gi-ink-900));
  white-space: nowrap;
}
.gi-prose tbody th { font-weight: 650; color: var(--gi-on-paper); text-align: left; }
.gi-prose td,
.gi-prose tbody th {
  padding: 0.7rem 1rem;
  border-top: 1px solid rgba(129, 86, 34, 0.16);
  vertical-align: top;
}
.gi-prose tbody tr:nth-of-type(even) { background: rgba(211, 193, 166, 0.24); }
.gi-prose caption {
  caption-side: bottom;
  padding-top: 0.7rem;
  font-size: var(--fs-sm);
  color: var(--gi-on-paper-muted);
  text-align: left;
}
/* Un tableau sans en-tete reste lisible : la premiere colonne prend le
   relais visuel. Les redacteurs collent souvent sans <thead>. */
.gi-prose table:not(:has(thead)) tbody tr:first-of-type td {
  font-weight: 650;
  color: var(--gi-on-paper);
}

/* --- TABLEPRESS, LA REPONSE A « IL Y A UN MODULE POUR CA ? » ------------
   Il n'y a pas de module tableau dans Divi. Mais le HTML rendu de la page
   montre que TablePress EST DEJA INSTALLE sur le site : ses feuilles
   `tablepress-default-css` et `tablepress-datatables-buttons` sont
   chargees. La redaction a donc deja un editeur de tableau a la souris,
   avec tri et recherche, et un raccourci a coller dans un module Texte.
   Rien a installer, rien a decider : il suffit de l'habiller.

   TablePress arrive avec SES couleurs, blanc et gris clair, posees sur ses
   propres classes `.odd` et `.even`. Sur parchemin ce sont deux taches
   blanches. On les remplace ici, et il n'y a pas de `!important` a mettre :
   ses selecteurs valent (0,1,1), les notres (0,2,2). */
.gi-prose .tablepress {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  margin: 0;
  background: none;
}
.gi-prose .tablepress thead th,
.gi-prose .tablepress tfoot th {
  padding: 0.8rem 1rem;
  border: 0;
  text-align: left;
  font-family: var(--gi-font-display);
  font-weight: 700;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps-md);
  color: var(--gi-gold-300);
  background: linear-gradient(180deg, var(--gi-ink-800), var(--gi-ink-900));
}
.gi-prose .tablepress tbody td {
  padding: 0.7rem 1rem;
  border: 0;
  border-top: 1px solid rgba(129, 86, 34, 0.16);
  vertical-align: top;
  background: none;
  color: var(--gi-on-paper-body);
}
.gi-prose .tablepress tbody tr.even td { background: none; }
.gi-prose .tablepress tbody tr.odd td { background: rgba(211, 193, 166, 0.24); }
.gi-prose .tablepress tbody tr:hover td { background: rgba(198, 165, 93, 0.2); }
/* Le tri de DataTables : la fleche est une image de fond posee a droite de
   l'en-tete. On lui laisse la place plutot que de l'eteindre, elle sert. */
.gi-prose .tablepress thead th:is(.sorting, .sorting_asc, .sorting_desc) {
  cursor: pointer;
  padding-right: 1.9rem;
}
.gi-prose .tablepress-table-description {
  margin-top: 0.65rem;
  font-size: var(--fs-sm);
  color: var(--gi-on-paper-muted);
}
/* L'enveloppe de DataTables porte deja le defilement : elle prend le cadre
   a la place de `.gi-tablewrap`, que le script ne pose pas ici puisque le
   tableau n'est plus nu. */
.gi-prose :is(.dt-container, .dataTables_wrapper) {
  margin-top: 2rem;
  margin-bottom: 2rem;
  overflow-x: auto;
  border-radius: var(--r-md);
  box-shadow: inset 0 0 0 1px rgba(129, 86, 34, 0.22);
}
.gi-prose :is(.dt-container, .dataTables_wrapper) :is(input, select) {
  margin: 0.5rem 0.6rem;
  padding: 0.35rem 0.6rem;
  border: 0;
  border-radius: var(--r-xs);
  background: rgba(255, 252, 242, 0.7);
  box-shadow: inset 0 0 0 1px rgba(129, 86, 34, 0.3);
  color: var(--gi-on-paper);
  font: inherit;
  font-size: var(--fs-sm);
}


/* ==========================================================================
   C9. LE CONTENU BATI AU BUILDER
   --------------------------------------------------------------------------
   Quand l'article est bati au Builder, `post-content` sort une arborescence
   complete : section > row > column > modules, chacune avec SES largeurs,
   SES fonds et SES marges. Posee telle quelle dans le parchemin, elle
   ramene une deuxieme mise en page a l'interieur de la notre.

   On la desactive, on ne se bat pas avec. Les rangees a plusieurs colonnes
   gardent leurs colonnes : c'est comme ca que la redaction pose deux images
   cote a cote, et ca doit continuer de marcher.

   C'est exactement ce que faisait le CSS libre de l'ancien site, en moins
   brutal : lui forcait un fond et un rayon, ici on se contente de rendre
   les conteneurs transparents.

   L'ARBORESCENCE EXACTE, RELEVEE SUR LA PAGE RENDUE ET NON DEDUITE :

     .et_pb_post_content
      └ .et-l.et-l--post
         └ .et_builder_inner_content
            └ .et_pb_section.et_section_regular.et_block_section
               └ .et_pb_row.et_block_row
                  └ .et_pb_column.et_pb_column_4_4.et-last-child.et_block_column
                     └ .et_pb_text.et_pb_module.et_block_module
                        └ .et_pb_text_inner
                           └ <p>

   Deux niveaux manquaient a la liste ecrite de memoire, `.et-l--post` et
   `.et_builder_inner_content`. Ils portent des largeurs a eux : sans les
   neutraliser, la mise en page de Divi reprenait la main a l'interieur du
   parchemin.

   ET SURTOUT : `.et_pb_module` NE FIGURE PLUS DANS LA LISTE. Toutes les
   classes de Divi se cumulent, un item d'accordeon porte
   `et_pb_accordion_item et_pb_toggle et_pb_module`. Neutraliser
   `.et_pb_module` en bloc effacait le fond parchemin pose en partie C7 : le
   generique tuait le particulier. Chaque module a deja sa regle, l'image en
   C5, le separateur en C6, l'accordeon en C7. Il n'y a rien a neutraliser
   au-dessus d'eux.
   ========================================================================== */
.gi-prose :is(.et-l, .et_builder_inner_content,
              .et_pb_section, .et_pb_row, .et_pb_column, .et_pb_text,
              .et_flex_section, .et_flex_row, .et_flex_column, .et_flex_group) {
  background: none;
  max-width: none;
  width: auto;
  padding: 0;
  margin-inline: 0;
}
.gi-prose :is(.et-l, .et_builder_inner_content,
              .et_pb_section, .et_pb_row,
              .et_flex_section, .et_flex_row) { margin-block: 0; }
/* La rangee garde sa repartition en colonnes, elle perd juste sa laisse. */
.gi-prose .et_pb_row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: flex-start;
}
.gi-prose .et_pb_column { flex: 1 1 14rem; min-width: 0; }
/* Une rangee a une seule colonne n'est pas une mise en page, c'est un
   simple empilement : elle ne doit pas creer de gouttiere. */
.gi-prose .et_pb_row > .et_pb_column:only-child { flex: 1 1 100%; }
.gi-prose .et_pb_text { margin-block: 0; }

/* LA GRILLE DE DIVI EST EN FLOTTANTS DANS LE CONTENU D'ARTICLE, et le rendu
   le dit : rangees et colonnes portent en plus `.et_block_row` et
   `.et_block_column`, qui sont les classes de son ancienne grille. Un
   flottant oublie dans une boite flex ne casse rien tout de suite, il casse
   le jour ou une colonne depasse. On le coupe a la source, et `clear` avec,
   sinon la premiere colonne se met a fuir la precedente.

   DEUX GRILLES COEXISTENT, ET C'EST LE POINT. Divi 5.9 rend les mises en
   page BATIES EN DIVI 5 avec `et_flex_section / et_flex_row /
   et_flex_column / et_flex_group`, et les mises en page HERITEES DE DIVI 4,
   comme le contenu des articles existants, avec `et_block_*`. Le meme
   parchemin peut donc contenir les deux. Les deux familles sont listees
   partout ci-dessus, sans quoi la regle ne s'applique qu'a la moitie des
   articles et on croit a un bug de contenu. */
.gi-prose :is(.et_block_row, .et_block_column, .et_pb_column,
              .et_flex_row, .et_flex_column) {
  float: none !important;
  clear: none !important;
}

/* Le separateur : la classe est doublee pour passer devant les regles de
   module ci-dessus, il doit sortir a la meme largeur que le <hr> natif
   puisque les deux sont interchangeables. */
.gi-prose .et_pb_module.et_pb_divider {
  max-width: var(--art-measure);
  margin: 2.6rem auto;
}


/* ==========================================================================
   C10. L'ENCADRE
   ========================================================================== */
.gi-callout {
  display: flex;
  gap: 0.95rem;
  margin-top: 2rem;
  margin-bottom: 2rem;
  padding: 1.15rem 1.35rem;
  border-radius: var(--r-md);
  background: rgba(79, 166, 227, 0.10);
  box-shadow: inset 0 0 0 1px rgba(79, 166, 227, 0.32);
  font-size: 1rem;
  line-height: 1.62;
}
.gi-callout__ico { width: 22px; height: 22px; flex: none; margin-top: 0.14rem; color: #2C6E9C; }
.gi-callout p { margin: 0; }
.gi-callout p + p { margin-top: 0.6em; }
.gi-callout strong { color: var(--gi-on-paper); }
.gi-callout--gold {
  background: rgba(198, 165, 93, 0.16);
  box-shadow: inset 0 0 0 1px rgba(129, 86, 34, 0.34);
}
.gi-callout--gold .gi-callout__ico { color: var(--gi-on-paper-accent); }


/* ==========================================================================
   C11. LE PIED D'ARTICLE
   --------------------------------------------------------------------------
   Les etiquettes, et rien d'autre. Pas de bloc redacteur, pas de
   commentaires : les deux ont ete retires sur demande.
   ========================================================================== */
.gi-art-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: clamp(1.8rem, 1rem + 2.4vw, 2.8rem);
  padding-top: 1.4rem;
  border-top: 1px solid rgba(129, 86, 34, 0.24);
}
/* TANT QUE LES ETIQUETTES N'ONT PAS DE JETON, le pied ne contient que
   « remonter en haut », et `space-between` le laisserait a gauche, ou il a
   l'air d'un oubli. Il part a droite, a sa place de la maquette. Le jour ou
   les etiquettes arrivent, la regle cesse de s'appliquer d'elle-meme : il
   n'y a rien a defaire. */
.gi-art-foot:not(:has(.gi-art-tags)) { justify-content: flex-end; }

/* REMONTER EN HAUT. Il etait dans le bloc « Partager », ou il n'avait rien
   a faire : remonter n'est pas partager, et la question a ete posee des la
   premiere lecture. Il finit l'article, la ou on est quand on veut
   remonter, et il reste utile sur telephone, ou la bande est passee tout en
   bas de la page. */
.gi-art-foot__top {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  flex: none;
  font-family: var(--gi-font-display);
  font-weight: 700;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps-md);
  color: var(--gi-on-paper-accent);
  text-decoration: none;
}
.gi-art-foot__top svg { width: 14px; height: 14px; transition: translate var(--t-base) var(--ease-out); }
.gi-art-foot__top:hover { color: #6A4519; }
.gi-art-foot__top:hover svg { translate: 0 -3px; }

.gi-art-tags {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  list-style: none;
}
.gi-art-tags__label {
  font-family: var(--gi-font-display);
  font-weight: 700;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps-md);
  color: var(--gi-on-paper-muted);
  margin-right: 0.2rem;
}
.gi-art-tags a {
  display: inline-block;
  padding: 0.32rem 0.72rem;
  border-radius: var(--r-pill);
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--gi-on-paper-accent);
  text-decoration: none;
  box-shadow: inset 0 0 0 1px rgba(129, 86, 34, 0.34);
  transition: background-color var(--t-fast), box-shadow var(--t-fast);
}
.gi-art-tags a:hover {
  background: rgba(129, 86, 34, 0.12);
  box-shadow: inset 0 0 0 1px rgba(129, 86, 34, 0.7);
}

.gi-art-main > .gi-pagination { margin-top: var(--sp-5); }


/* ==========================================================================
   C12. LA BANDE LATERALE
   --------------------------------------------------------------------------
   Sombre, collante, dans l'ordre demande : sommaire, articles de la meme
   categorie, partage.

   `max-height` + `overflow-y` sont un filet, pas une mise en page : sur un
   ecran bas, une bande plus haute que la fenetre ne colle a rien et sa fin
   devient inatteignable.
   ========================================================================== */
/* LA BANDE TIENT EN DEUX ELEMENTS, ET CE N'EST PAS UN NIVEAU DE TROP.
   Sous Divi, la colonne et la pile sont deux choses distinctes : la colonne
   est `.et_pb_column`, la pile est un module Groupe pose dedans. La maquette
   epouse donc la meme structure, `.gi-art-rail > .gi-rail-sticky`, pour que
   les memes regles servent des deux cotes sans une seule ligne de rattrapage
   au portage. */
.gi-art-rail {
  position: sticky;
  top: var(--art-stick);
  align-self: start;
  min-width: 0;
  max-height: calc(100vh - var(--art-stick) - 1rem);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--gi-gold-800) transparent;
  padding-right: 2px;
}
.gi-rail-sticky {
  display: grid;
  gap: var(--sp-5);
  min-width: 0;
}

.gi-rail-block {
  position: relative;
  padding: var(--sp-5);
  border-radius: var(--r-lg);
  background: linear-gradient(168deg, var(--gi-ink-850), var(--gi-ink-950));
  box-shadow: inset 0 0 0 1px var(--gi-line), var(--sh-2);
}
.gi-rail-block__title {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: var(--sp-4);
  font-family: var(--gi-font-display);
  font-weight: 700;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-widest);
  color: var(--gi-gold-400);
}
.gi-rail-block__title::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: linear-gradient(90deg, var(--gi-gold-700), transparent);
}

/* --- Le sommaire flottant ---------------------------------------------- */
.gi-summary { max-height: 46vh; overflow-y: auto; scrollbar-width: thin; }
.gi-summary ol { margin: 0; padding: 0; list-style: none; counter-reset: gi-somm; }
.gi-summary li { counter-increment: gi-somm; margin: 0; }
.gi-summary a {
  position: relative;
  display: flex;
  gap: 0.6rem;
  padding: 0.4rem 0.2rem 0.4rem 0.75rem;
  font-size: 0.86rem;
  line-height: 1.4;
  color: var(--gi-sand-300);
  text-decoration: none;
  border-radius: var(--r-sm);
  transition: color var(--t-fast), background-color var(--t-fast);
}
/* Le rail vertical du sommaire vit sur ::before de chaque lien, jamais sur
   le conteneur : une seule barre pour toute la liste supposerait de
   connaitre la hauteur des entrees, qui depend de la longueur des titres. */
.gi-summary a::before {
  content: "";
  position: absolute;
  left: 0; top: 2px; bottom: 2px;
  width: 2px;
  border-radius: 2px;
  background: rgba(198, 165, 93, 0.22);
  transition: background-color var(--t-fast);
}
.gi-summary a::after {
  content: counter(gi-somm, decimal-leading-zero);
  order: -1;
  flex: none;
  font-family: var(--gi-font-display);
  font-weight: 700;
  font-size: 0.72rem;
  color: var(--gi-gold-700);
  transition: color var(--t-fast);
}
.gi-summary a:hover { color: var(--gi-sand-50); background: rgba(198, 165, 93, 0.07); }
.gi-summary a.is-current { color: var(--gi-gold-200); background: rgba(198, 165, 93, 0.10); }
.gi-summary a.is-current::before { background: var(--gi-gold-500); }
.gi-summary a.is-current::after { color: var(--gi-gold-400); }

/* --- Les trois derniers de la categorie -------------------------------- */
.gi-rail-posts { display: grid; gap: 0.35rem; list-style: none; }
.gi-side-post {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.5rem;
  margin: -0.15rem;
  border-radius: var(--r-md);
  text-decoration: none;
  transition: background-color var(--t-fast), transform var(--t-fast) var(--ease-out);
}
.gi-side-post:hover { background: rgba(198, 165, 93, 0.09); transform: translateX(3px); }
.gi-side-post__thumb { width: 74px; height: 58px; flex: none; border-radius: var(--r-sm); }
/* Le corps de carte PREND la place restante, il ne se retracte pas sur son
   contenu : sinon la coupe a trois lignes du titre ne tombe pas au meme
   endroit que sous Divi, ou la case de grille fait toute la largeur. */
.gi-side-post__body { flex: 1 1 auto; min-width: 0; }
.gi-side-post__title {
  font-family: var(--gi-font-body);
  font-weight: 600;
  font-size: 0.875rem;
  line-height: 1.34;
  letter-spacing: -0.012em;
  color: var(--gi-sand-100);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color var(--t-fast);
}
.gi-side-post:hover .gi-side-post__title { color: var(--gi-gold-300); }
/* `display: block` N'EST PAS DECORATIF : en inline, la date heritait de la
   hauteur de ligne de la bande et sa boite de ligne faisait 24 px pour
   14 px de texte. La carte y gagnait 4 px que le module Portfolio de Divi,
   lui, n'avait pas. Deux gabarits de carte pour un seul dessin, et l'ecart
   se voyait a la mesure. */
.gi-side-post__date {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.72rem;
  line-height: 1.3;
  color: var(--gi-sand-500);
}

.gi-rail-block__more {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: var(--sp-4);
  font-family: var(--gi-font-display);
  font-weight: 600;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps-md);
  color: var(--gi-gold-400);
  text-decoration: none;
}
.gi-rail-block__more svg { width: 13px; height: 13px; transition: translate var(--t-base) var(--ease-out); }
.gi-rail-block__more:hover { color: var(--gi-gold-200); }
.gi-rail-block__more:hover svg { translate: 3px 0; }

/* --- Partager, en bas de bande ----------------------------------------- */
/* DEUX RANGS EN GRILLE, ET C'EST UNE CORRECTION DEMANDEE SUR LE RENDU.
   La version precedente mettait « Copier le lien » en pleine largeur et
   deux pastilles rondes de 38 px dessous, alignees a gauche : le rang du
   bas ne remplissait qu'un tiers de la bande et la pile paraissait
   inachevee. Deux colonnes egales, le bouton de copie a cheval sur les
   deux, et les deux reseaux tiennent EXACTEMENT la largeur du bouton du
   dessus. Les pictos gagnent leur libelle au passage : sur un fond sombre,
   un logo X de 17 px se lit mal, et « Discord » ne s'y devine pas.

   UN SEUL GABARIT DE BOUTON pour les trois, `.gi-share__btn` : le bouton de
   copie n'est qu'une variante qui prend les deux colonnes. C'est la regle du
   projet, un seul gabarit sur tout le site. */
.gi-share {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
}
.gi-share__btn,
.gi-share__copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  min-width: 0;
  min-height: 38px;
  padding: 0 0.7rem;
  border: 0;
  border-radius: var(--r-pill);
  background: rgba(36, 53, 71, 0.5);
  box-shadow: inset 0 0 0 1px var(--gi-line-soft);
  font-family: var(--gi-font-display);
  font-weight: 600;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--gi-sand-200);
  text-decoration: none;
  cursor: pointer;
  transition: color var(--t-fast), background-color var(--t-fast), box-shadow var(--t-fast);
}
.gi-share__copy { grid-column: 1 / -1; }
.gi-share__btn svg,
.gi-share__copy svg { width: 15px; height: 15px; flex: none; }
/* Le libelle cede avant le picto : sur une bande etroite, mieux vaut
   « Discor… » avec son logo qu'un logo ecrase a zero. */
.gi-share__btn span,
.gi-share__copy span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gi-share__btn:hover,
.gi-share__copy:hover {
  color: var(--gi-gold-200);
  background: rgba(198, 165, 93, 0.14);
  box-shadow: inset 0 0 0 1px var(--gi-gold-600);
}
.gi-share__copy.is-done { color: var(--gi-gold-300); }


/* ==========================================================================
   C13. LE CAS GUIDE
   --------------------------------------------------------------------------
   Meme forme que gi-archive.css, au tilde : un bloc peut appartenir a
   plusieurs cas. Les valeurs de body sont `article` et `guide`, celles de
   l'archive sont `categorie`, `guides`, `auteur` et `vide` : les deux jeux
   de regles ne se croisent jamais.
   ========================================================================== */
[data-cas="article"] [data-cas-only]:not([data-cas-only~="article"]),
[data-cas="guide"]   [data-cas-only]:not([data-cas-only~="guide"]) { display: none !important; }


/* ==========================================================================
   C15. LE GABARIT DIVI
   --------------------------------------------------------------------------
   Tout ce qui precede decrit la maquette. Cette partie fait atterrir le
   gabarit de Theme Builder EXACTEMENT sur les memes mesures.

   Le corps importe, `divi/corps-article.json`, est batî sur un principe
   simple : les modules ne portent presque aucun reglage, ils portent des
   CLASSES, et le dessin vit ici. La raison est la lecon du chantier des
   archives : on se battait contre un reglage rempli qu'on n'avait pas mis.
   Un reglage vide n'emet pas de CSS de page, donc rien ne se bat.

   Correspondance des elements :

     .gi-art-body    ->  .et_pb_section
     .gi-art-layout  ->  .et_pb_row          (deux colonnes)
     .gi-art-main    ->  .et_pb_column
     .gi-art-paper   ->  module Groupe
     .gi-art-head    ->  divi/post-title
     .gi-prose       ->  divi/post-content
     .gi-art-rail    ->  .et_pb_column
     .gi-rail-sticky ->  module Groupe
     .gi-rail-posts  ->  divi/fullwidth-portfolio

   TOUS LES SELECTEURS D'ICI PORTENT DEUX CLASSES, et ce n'est pas du zele.
   Les regles de Divi valent (0,1,0) : `.et_pb_row`, `.et_pb_column`. A
   specificite egale, le CSS de page de Divi gagne, parce qu'il vit en fin
   de body. Deux classes, (0,2,0), passent devant sans un seul `!important`.
   ========================================================================== */

/* --- La rangee tient le role du conteneur ------------------------------ */
/* En maquette, `.gi-art-layout` vit dans un `.gi-container--wide` qui porte
   la largeur maximale et les gouttieres. Sous Divi il n'y a pas de
   conteneur intermediaire : la rangee prend les deux roles. */
.gi-art-body .gi-art-layout {
  display: grid;
  grid-template-columns: minmax(0, var(--art-col)) minmax(0, var(--rail-w));
  justify-content: center;
  align-items: start;
  gap: var(--art-gap);
  flex-wrap: nowrap;
}
/* LE ROLE DE CONTENEUR NE SE PREND QU'EN ENFANT DIRECT DE LA SECTION, et
   la nuance a ete mesuree. En maquette, `.gi-art-layout` vit dans un
   `.gi-container--wide` qui porte deja la largeur maximale et les
   gouttieres ; ecrit sans le `>`, ce bloc les redonnait une seconde fois et
   la colonne perdait 77 px de chaque cote. Sous Divi il n'y a pas de
   conteneur intermediaire, la rangee est bien enfant direct de la section,
   donc elle seule prend les deux roles. */
.gi-art-body > .gi-art-layout {
  width: 100%;
  max-width: var(--gi-container-wide);
  margin-inline: auto;
  padding-inline: var(--gi-gutter);
  /* LE RANG DE SUPERPOSITION, ET C'EST LA CAUSE DU « VOILE SOMBRE » SIGNALE
     SUR TOUTE LA PAGE. La section porte `gi-grain` et `gi-vignette--soft` :
     deux ornements en pseudo-elements plein cadre, le grain en z-index 2 et
     le vignetage en z-index 3. En maquette, gi-tokens.css remonte le contenu
     au-dessus avec `.gi-vignette--soft > .gi-container { z-index: 4 }`. Sous
     Divi il n'y a pas de `.gi-container` : la regle ne trouvait rien, et les
     deux voiles passaient PAR-DESSUS le parchemin. D'ou le beige eteint, les
     images a la une plus foncees et le gris general. La rangee tenait deja
     le role du conteneur pour la largeur, elle prend aussi son rang. */
  position: relative;
  z-index: 4;
}

/* --- LES ESPACEMENTS, REPRIS A LA FEUILLE -------------------------------
   AUCUN MODULE DU GABARIT NE PORTE PLUS DE REGLAGE D'ESPACEMENT, et c'est
   la correction de fond de cette version. Les mettre a zero dans le module
   paraissait plus propre que d'ecrire du CSS ; ca produisait en realite
   ceci, en fin de <body> :

     .et_pb_row_0_tb_body.et_pb_row,.et_pb_group_0_tb_body,
     .et_pb_group_1_tb_body,.et_pb_group_2_tb_body{...padding:0px!important}

   Un `!important` sur le parchemin, sur la pile et sur le bloc « Derniers
   articles ». Quatre defauts constates en front pour cette seule cause :
   pas d'air en haut de page, intitule « Derniers articles » au ras du bord,
   lien « Toutes les actualites » colle de meme, et « precedent / suivant »
   coince entre le separateur et le pied de page.

   Les reglages sont donc vides, Divi n'emet plus rien pour eux, et ses
   valeurs par defaut, qui valent (0,1,0), sont reprises ici a deux classes.
   ------------------------------------------------------------------------ */
.gi-art-body.et_pb_section {
  padding-block: clamp(1.5rem, 0.9rem + 2.4vw, 3rem)
                 clamp(2.5rem, 1.4rem + 3.4vw, 4.5rem);
  padding-inline: 0;
  margin-block: 0;
}
.gi-art-body .gi-art-layout.et_pb_row { padding-block: 0; margin-block: 0; }
/* Le parchemin ne porte que son remplissage bas : le haut appartient a
   l'image a la une, qui est bord a bord. C'est la valeur de C2. */
.gi-art-body .gi-art-paper.et_pb_module {
  margin: 0;
  padding: 0 0 clamp(1.5rem, 0.8rem + 2.4vw, 3rem);
}

/* --- Les deux colonnes -------------------------------------------------- */
/* Divi ecrit une largeur en pourcentage sur chaque colonne. Dans une
   grille, une largeur en pourcentage se resout sur la piste et non sur le
   parent : la colonne se retrecirait a l'interieur de sa propre piste. */
.gi-art-body .gi-art-main,
.gi-art-body .gi-art-rail {
  width: auto;
  max-width: none;
  margin: 0;
  padding: 0;
  float: none;
}
.gi-art-body .gi-art-main { min-width: 0; }

/* --- Le parchemin ------------------------------------------------------- */
/* Le module Groupe arrive avec la mise en boite flex de Divi. Le parchemin
   est un empilement, pas une rangee. */
.gi-art-body .gi-art-paper {
  display: block;
  width: auto;
  max-width: none;
}

/* --- La bande ----------------------------------------------------------- */
.gi-art-body .gi-rail-sticky {
  display: grid;
  gap: var(--sp-5);
  width: auto;
  max-width: none;
}
/* Les modules Texte de la bande ne portent qu'un conteneur : leur propre
   boite ne doit rien ajouter, ni marge ni fond.
   `.gi-rail-block` EST EXCLU, ET C'EST UNE CORRECTION MESUREE. Sous Divi,
   le bloc « Derniers articles » est un GROUPE, donc un `.et_pb_module` : la
   regle generale, a deux classes, ecrasait son remplissage de 24 px et tout
   le contenu du bloc partait 24 px trop a gauche, jusqu'au bord de la
   bande. C'est exactement la faute deja payee en C9 avec `.et_pb_module`
   pose en bloc, qui effacait le fond parchemin de l'accordeon : le
   generique tuait le particulier. Meme correction, meme raison. */
.gi-art-rail .et_pb_module:not(.gi-rail-block) {
  margin: 0;
  padding: 0;
  background: none;
}
/* Et le bloc lui-meme reprend le remplissage de C12, a deux classes : le
   sien vient de `.gi-rail-block`, qui ne vaut qu'une classe. */
/* LE BLOC EST UNE PILE SIMPLE, ET `display: block` N'EST PAS UN DETAIL.
   Sous Divi 5 le bloc « Derniers articles » est un GROUPE, `et_flex_group`,
   donc une boite flex avec sa propre gouttiere verticale. Elle s'ajoutait a
   nos marges : de l'air en trop entre l'intitule et la liste, beaucoup trop
   entre la liste et « Toutes les actualites », ou la gouttiere s'ajoutait au
   `margin-top` du lien. Remettre la gouttiere a zero supposerait de connaitre
   le nom exact de la propriete personnalisee que Divi emploie ; un conteneur
   en bloc n'a pas de gouttiere du tout, et la question ne se pose plus. Les
   trois ecarts du bloc sont alors les notres, et eux seuls. */
.gi-art-rail .gi-rail-block.et_pb_module {
  display: block;
  gap: 0;
  margin: 0;
  padding: var(--sp-5);
}
/* La remise a plat des hotes ci-dessus efface aussi la marge basse de
   l'intitule, qui est un `p`. On la lui rend, apres. */
.gi-art-rail .gi-rail-titre-hote .gi-rail-block__title { margin-bottom: var(--sp-4); }
/* Le lien « Toutes les actualites » sort enveloppe dans un `<p>` par
   WordPress, et Divi met un `padding-bottom` sur les paragraphes. */
.gi-art-body :is(.gi-art-foot-hote, .gi-rail-more-hote,
                 .gi-rail-titre-hote) :is(p, .et_pb_text_inner) {
  margin: 0;
  padding: 0;
}

/* --- Les trois derniers articles --------------------------------------- */
/* LES REGLES DE DIVI, RELEVEES DANS LA FEUILLE DU SITE ET NON DEDUITES.
   Le premier essai avait ete ecrit contre un DOM suppose, le second contre
   un DOM constate mais des regles supposees. Les voici, verbatim, telles que
   `et-divi-dynamic-*.css` les sert :

     .et_pb_fullwidth_portfolio .et_pb_portfolio_image
       { position:relative; overflow:hidden; width:100%; height:100%; margin:0 }
     .et_pb_fullwidth_portfolio .et_pb_portfolio_image img
       { max-width:100%; height:inherit; min-height:100%; min-width:100% }
     .et_pb_fullwidth_portfolio .et_pb_portfolio_image.landscape img
       { height:100% }
     .et_pb_fullwidth_portfolio .et_pb_portfolio_image .meta
       { position:absolute; opacity:0; z-index:-1; inset:0 0 auto 0;
         width:100%; height:100%; transition:all .3s }
     .et_pb_fullwidth_portfolio .et_pb_portfolio_image:hover .meta
       { z-index:3; opacity:1 }
     .et_pb_fullwidth_portfolio .et_pb_portfolio_image
       :is(.et_pb_module_header, h3, p)
       { display:block; position:relative; float:left; z-index:5;
         width:100%; text-align:center }
     .et_pb_fullwidth_portfolio .et_pb_portfolio_image
       :is(.et_pb_module_header, h3)   { margin-top:40%; padding:0 5px }
     .et_pb_fullwidth_portfolio .et_pb_portfolio_image .et_overlay+p.post-meta
       { position:absolute; top:50%; left:0; width:100%;
         transform:translateY(-50%) }

   CE QUE CA EXPLIQUE, ET QU'AUCUNE CAPTURE NE DISAIT.

   - l'image trop haute : `height:100%` + `min-height:100%` sur `img`, a
     (0,3,1). Ma regle etait a (0,2,1). Elle perdait, et l'image s'etirait
     sur toute la hauteur de sa case ;
   - le titre invisible hors survol : `.meta` a (0,3,0), ma remise en flux a
     (0,3,0) aussi. A egalite, c'est l'ordre de chargement qui tranche, et il
     ne nous appartient pas ;
   - le titre pousse vers le bas et centre : `margin-top:40%` et `float:left`
     a (0,2,1) contre mes (0,2,0) ;
   - la date par-dessus le titre : `.et_overlay+p.post-meta` en absolu a
     (0,2,2). `display:none` sur `.et_overlay` n'y change RIEN, un selecteur
     de voisinage ne regarde pas si le voisin est affiche.

   TOUT CE QUI SUIT PORTE DONC `.gi-art-rail .gi-rail-posts` EN TETE, ce qui
   met chaque regle un cran au-dessus de son homologue de Divi. Aucune n'est
   ecrite au jugé : chacune repond a une declaration de la liste ci-dessus. */

/* Le portfolio est un module herite de Divi 4 : son orientation de texte
   vaut « centre » par defaut, et Divi la sort en `!important` sans qu'on ait
   rien rempli. C'est le seul `!important` de C15, et il est subi : aucune
   specificite ne passe devant un `!important` sans en etre un. Le bon geste
   serait de poser l'alignement DANS le module, mais le nom de l'attribut
   Divi 5 n'a jamais ete constate, et le deviner est ce que la methode de la
   sonde existe pour eviter.

   QUATRE CLASSES, ET LE CHIFFRE A ETE PAYE. La liste de Divi compte SIX
   selecteurs, et le dernier n'est pas comme les autres :

     .et_pb_fullwidth_portfolio_0_tb_body .et_pb_portfolio_image
       .et_pb_module_header { text-align:center!important }

   Trois classes, comme la premiere version de cette regle. A egalite de
   poids ET d'importance, c'est l'ordre qui tranche : cette declaration-la
   vit dans le CSS DE PAGE, en fin de <body>, donc apres notre feuille. Elle
   gagnait, et le titre des cartes restait centre alors que la date, dont le
   selecteur jumeau ne vaut que (0,2,1), etait bien passee a gauche. Deux
   comportements dans la meme carte : c'est le signe qu'on est a un cran
   pres, pas que la regle ne s'applique pas. */
.gi-art-rail .gi-rail-posts,
.gi-art-rail .gi-rail-posts .et_pb_portfolio_image .et_pb_module_header,
.gi-art-rail .gi-rail-posts .et_pb_portfolio_image .post-meta { text-align: left !important; }

.gi-art-rail .gi-rail-posts { position: static; overflow: visible; margin: 0; }

/* L'ecart entre cartes vient des proprietes personnalisees de la grille de
   Divi, pas d'un `gap` : le poser seul ne suffit pas, `--vertical-gap`
   reinjecte ses 30 px par-dessous. */
.gi-art-rail .gi-rail-posts .et_pb_portfolio_items {
  --vertical-gap: 0px;
  --module-gutter-grid: 0px;
  position: static;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.35rem;
  width: auto;
  overflow: visible;
  margin: 0;
  padding: 0;
}

.gi-art-rail .gi-rail-posts .et_pb_portfolio_item {
  position: relative;
  float: none;
  clear: none;
  width: auto;
  height: auto;
  /* La meme marge negative que `.gi-side-post` de la maquette : la zone de
     survol deborde du bloc d'un quart de son remplissage, sinon les cartes
     paraissent rentrees par rapport a l'intitule. */
  margin: -0.15rem;
  padding: 0.5rem;
  border-radius: var(--r-md);
  background: none;
  transition: background-color var(--t-fast), transform var(--t-fast) var(--ease-out);
}
.gi-art-rail .gi-rail-posts .et_pb_portfolio_item:hover {
  background: rgba(198, 165, 93, 0.09);
  transform: translateX(3px);
}

/* LA CARTE VIT SUR `.et_pb_portfolio_image`, qui n'est PAS la vignette mais
   le conteneur de toute la carte, image ET texte. Image a gauche, bloc meta
   a droite, et plus aucune zone nommee : le titre et la date sont dans un
   vrai conteneur, `.meta`, ils s'empilent tout seuls. */
.gi-art-rail .gi-rail-posts .et_pb_portfolio_image {
  position: static;
  display: grid;
  grid-template-columns: 74px minmax(0, 1fr);
  align-items: center;
  column-gap: 0.8rem;
  width: auto;
  height: auto;
  margin: 0;
  overflow: visible;
  background: none;
}
/* Quatre classes : `.landscape img` de Divi en vaut trois plus une balise. */
.gi-art-rail .gi-rail-posts .et_pb_portfolio_items .et_pb_portfolio_image > img {
  display: block;
  width: 74px;
  min-width: 0;
  max-width: none;
  height: 58px;
  min-height: 0;
  object-fit: cover;
  border-radius: var(--r-sm);
}

/* `position: static` SUFFIT A DESARMER LE SURVOL NATIF : hors position
   absolue, `top`, `z-index` et l'opacite animee n'ont plus de prise. On ne
   combat pas les declarations une par une, on retire ce qui les porte. */
.gi-art-rail .gi-rail-posts .et_pb_portfolio_image .meta,
.gi-art-rail .gi-rail-posts .et_pb_portfolio_image:hover .meta {
  position: static;
  z-index: auto;
  opacity: 1;
  visibility: visible;
  transform: none;
  translate: none;
  transition: none;
  width: auto;
  height: auto;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
}
.gi-art-rail .gi-rail-posts .et_pb_portfolio_image .meta > a {
  display: block;
  min-width: 0;
  padding: 0;
  background: none;
  text-decoration: none;
}
/* LE LIEN NE COUVRE QUE LE TEXTE, LA CARTE ENTIERE DOIT ETRE CLIQUABLE.
   Divi n'enveloppe pas l'image dans l'ancre. Plutot que de deplacer des
   noeuds en JS, l'ancre s'etire sur la carte avec un pseudo : un survol, une
   cible, et le balisage reste celui de Divi. */
.gi-art-rail .gi-rail-posts .et_pb_portfolio_image .meta > a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

/* LE TITRE DE CARTE EST EN INTER, PAS EN CINZEL. Cinzel porte des intitules,
   Inter porte des phrases, et un titre d'article est une phrase. C'est la
   meme regle que sur l'accueil et les archives. */
.gi-art-rail .gi-rail-posts .et_pb_portfolio_image .et_pb_module_header {
  position: static;
  float: none;
  z-index: auto;
  width: auto;
  margin: 0;
  padding: 0;
  font-family: var(--gi-font-body);
  font-weight: 600;
  font-size: 0.875rem;
  line-height: 1.34;
  letter-spacing: -0.012em;
  color: var(--gi-sand-100);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color var(--t-fast);
}
.gi-art-rail .gi-rail-posts .et_pb_portfolio_item:hover .et_pb_module_header {
  color: var(--gi-gold-300);
}
/* Cinq classes et une balise : `.et_overlay + p.post-meta` de Divi pose la
   date en absolu au milieu de la carte, et le voisinage se moque de ce que
   `.et_overlay` soit masque. */
.gi-art-rail .gi-rail-posts .et_pb_portfolio_image .post-meta,
.gi-art-rail .gi-rail-posts .et_pb_portfolio_image .et_overlay + p.post-meta {
  position: static;
  float: none;
  transform: none;
  top: auto;
  left: auto;
  width: auto;
  margin: 0.25rem 0 0;
  padding: 0;
  font-size: 0.72rem;
  line-height: 1.3;
  color: var(--gi-sand-500);
}
.gi-art-rail .gi-rail-posts .post-meta a { color: inherit; text-decoration: none; }
/* La pastille de survol de Divi recouvre la carte pour y poser une loupe :
   elle n'a rien a faire sur une vignette de 74 px. */
.gi-art-rail .gi-rail-posts .et_overlay { display: none; }

/* --- Les hotes : modules Texte qui ne portent qu'un conteneur ------------ */
/* Trois modules Texte du gabarit ne servent qu'a poser un element de la
   maquette dans l'arbre de Divi : le pied d'article, le lien « voir tous
   les articles » et les deux conteneurs montes en JS. Leur propre boite ne
   doit rien ajouter. Les marges sont deja a zero dans le gabarit, A LA
   SOURCE ; ces regles ne sont la que pour le fond et le remplissage que
   Divi pose parfois par preset. */
.gi-art-body :is(.gi-art-foot-hote, .gi-rail-more-hote,
                 .gi-rail-titre-hote, .gi-summary-hote, .gi-share-hote) {
  margin: 0;
  padding: 0;
  background: none;
}


/* LE PARCHEMIN DOIT ETRE UN PARENT POSITIONNE, sinon les quatre equerres,
   qui sont en `position: absolute; inset: 10px`, remontent chercher le
   premier ancetre positionne et se posent autour de toute la page. En
   maquette c'est `.gi-card` qui le donne ; sous Divi la classe est bien la,
   mais un preset de groupe peut la remettre a `static`. On l'affirme. */
.gi-art-body .gi-art-paper { position: relative; overflow: hidden; }

/* PRECEDENT / SUIVANT. Le module `post-nav` sort en enfant direct de la
   colonne, exactement la ou la maquette met sa `nav.gi-pagination`. Ses
   couleurs, son filet et son rayon sont poses DANS le module, pas ici :
   ils emettent du CSS de page qui vit en fin de <body> et gagnerait contre
   la feuille. Ce qui reste ici est ce que le module ne sait pas faire. */
.gi-art-body .gi-art-main > .et_pb_post_nav {
  margin-top: var(--sp-5);
  margin-bottom: var(--sp-4);
}


/* ==========================================================================
   C14. RESPONSIVE
   --------------------------------------------------------------------------
   1080 : la bande passe sous l'article, en deux colonnes.
    760 : la bande repasse sur une colonne, les tableaux nus defilent.
    620 : le parchemin perd ses equerres.
    400 : derniers reglages de taille.

   Il n'y a PAS de palier entre 1440 et 1080 : les deux pistes sont en
   minmax(0, x), elles maigrissent d'elles-memes.
   ========================================================================== */
@media (max-width: 1080px) {
  /* DEUX CLASSES ICI AUSSI, ET C'EST UNE CORRECTION MESUREE. La partie C15
     vise `.gi-art-body .gi-art-layout` pour passer devant le CSS de page de
     Divi. Ecrites sur une seule classe, les regles ci-dessous perdaient
     contre elle malgre le palier, et la bande restait a cote de l'article a
     1080 px au lieu de passer dessous. La specificite l'emporte sur l'ordre,
     un palier ne rattrape pas un cran manquant. */
  .gi-art-body .gi-art-layout {
    grid-template-columns: minmax(0, 1fr);
    justify-content: stretch;
  }
  .gi-art-body .gi-art-main,
  .gi-art-body .gi-art-rail { max-width: var(--art-col); margin-inline: auto; width: 100%; }
  /* Une bande collante qui n'est plus a cote de rien n'a aucun sens : elle
     redevient un bloc ordinaire, et son filet de hauteur saute avec. */
  .gi-art-body .gi-art-rail {
    position: static;
    max-height: none;
    overflow: visible;
  }
  .gi-art-body .gi-rail-sticky {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }
  .gi-summary { max-height: none; }
  .gi-summary ol { columns: 2; column-gap: 1.2rem; }
  .gi-summary li { break-inside: avoid; }
}

@media (max-width: 760px) {
  .gi-art-body .gi-rail-sticky { grid-template-columns: minmax(0, 1fr); }
  .gi-summary ol { columns: 1; }
  /* Sans conteneur, un tableau large pousse la colonne. Le script en
     enveloppe la plupart, cette regle rattrape ceux qu'il aurait manques. */
  .gi-prose table { display: block; overflow-x: auto; }
  .gi-prose { font-size: 1.02rem; line-height: 1.72; }
  .gi-prose > p:first-of-type { font-size: 1.12rem; }
  .gi-prose :is(.wp-block-gallery, .gi-duo) { grid-template-columns: minmax(0, 1fr); }
  /* Deux colonnes du Builder cote a cote sur telephone, c'est deux images
     de 150 px. Elles s'empilent. */
  .gi-prose .et_pb_column { flex: 1 1 100%; }
}

@media (max-width: 620px) {
  .gi-art-paper__corners { display: none; }
  .gi-prose blockquote { padding-left: 1.15rem; padding-right: 1.15rem; }
}

@media (max-width: 400px) {
  .gi-art-body { --art-pad: 1rem; }
  .gi-art-meta { gap: 0.4rem 0.7rem; font-size: var(--fs-xs); }
}

@media (prefers-reduced-motion: reduce) {
  .gi-side-post:hover { transform: none; }
  .gi-rail-block__more:hover svg { translate: none; }
  .gi-art-head__cat:hover svg { translate: none; }
}


/* ==========================================================================
   C16. LE TEXTE DANS LE BUILDER
   --------------------------------------------------------------------------
   POURQUOI CETTE PARTIE EXISTE. Nos feuilles sont DEJA chargees dans le
   Visual Builder : la zone d'edition est une page de front appelee avec
   `?et_fb=1`, elle passe donc par `wp_enqueue_scripts` comme le reste du
   site. Le probleme n'a jamais ete le chargement, c'est LE CROCHET.

   En front, le corps de l'article est le module `divi/post-content` du
   gabarit Theme Builder, et ce module porte notre classe `gi-prose`. C'est
   elle, et elle seule, qui pose l'encre du parchemin (partie C4). Le
   Builder remplace ce module par sa zone d'edition vivante, qui porte
   `et-fb-post-content` et PAS `gi-prose` : toutes les regles en
   `.gi-prose …` tombent d'un coup, et le texte retombe sur la couleur de
   corps du site, un beige clair, pose sur un fond clair. On ecrit en
   aveugle.

   REGLE GENERALE A RETENIR : tout ce qui est accroche a une classe posee
   sur un module du Theme Builder est ABSENT du Builder de l'article.

   DEUX NIVEAUX, ET LE SECOND N'EST PAS UNE PRECAUTION DE STYLE.
   Divi peint le texte du Builder depuis DEUX selecteurs, ecrits dans une
   balise `<style>` du `<head>` posee APRES nos `<link>` :

     body .et-fb-post-content                              -> (0,1,1)
     body .et-fb-root-ancestor-sibling #et-boc .et-l       -> (1,3,1)

   Le second porte un IDENTIFIANT. Aucune regle de classe, meme doublee,
   meme triplee, ne passe devant. Et comme il peint un ANCETRE du
   paragraphe, la couleur arrive par heritage : la bataille ne se joue meme
   pas sur le paragraphe, elle est deja perdue plus haut.

   D'ou la construction en deux temps :
   1. la classe doublee sur la zone d'edition, propre et sans `!important`,
      qui suffit quand c'est `et-fb-post-content` qui gouverne ;
   2. un filet qui vise LES ELEMENTS DE TEXTE EUX-MEMES, en `!important`,
      qui coupe court a l'heritage quel que soit l'ancetre peint par Divi.

   PORTEE : `body.et-fb` n'existe que dans le Builder, `.single` limite aux
   articles et aux guides. Le filet ne descend donc jamais sur l'en-tete ni
   sur le pied de page, qui vivent sur fond sombre et ou l'encre du papier
   serait illisible a son tour. Et rien de tout ceci n'existe sur le site
   publie : ces classes sont propres a l'edition.

   CE QUE CA COUTE. Dans le Builder, une couleur de texte reglee a la main
   sur un module d'article ne se verra pas ; elle sortira normalement en
   front. C'est le prix du `!important`, et il est assume : un corps
   d'article se lit sur le parchemin, pas en couleur libre.

   PORTEE LIMITEE AUX COULEURS, VOLONTAIREMENT. Rejouer toute la
   typographie de l'article dans le Builder (ornements de titre, mesure de
   lecture, marges) demanderait de verifier module par module, et un Builder
   qui ment a moitie est pire qu'un Builder neutre. Ici on rend le texte
   LISIBLE PENDANT QU'ON L'ECRIT. Le rendu se juge en front.
   ========================================================================== */

/* 1. La zone d'edition, quand c'est elle qui gouverne. Classe doublee :
      deux classes contre une classe plus un element, on passe devant sans
      `!important` et sans dependre d'une classe de <body>. */
.et-fb-post-content.et-fb-post-content { color: var(--gi-on-paper-body); }
.et-fb-post-content.et-fb-post-content :is(h1, h2, h3, h4, h5, h6),
.et-fb-post-content.et-fb-post-content :is(strong, b, dt) {
  color: var(--gi-on-paper);
}
.et-fb-post-content.et-fb-post-content :is(a, a:hover) {
  color: var(--gi-on-paper-accent);
}

/* 2. Le filet, pose sur les elements de texte eux-memes pour couper
      l'heritage venu d'un ancetre peint par un selecteur a identifiant. */
body.et-fb.single :is(p, li, dd, dt, td, th, blockquote, address,
                      .et_pb_text_inner, .et_pb_toggle_content) {
  color: var(--gi-on-paper-body) !important;
}
body.et-fb.single :is(h1, h2, h3, h4, h5, h6),
body.et-fb.single :is(strong, b, dt) {
  color: var(--gi-on-paper) !important;
}
body.et-fb.single :is(p, li, td, th, blockquote) a {
  color: var(--gi-on-paper-accent) !important;
}
body.et-fb.single :is(figcaption, cite, small) {
  color: var(--gi-on-paper-muted) !important;
}
