    /* ==================================================================
       Rubrique blog : le seul ajout aux feuilles de la page contact et des
       pages légales, dont les trois vues reprennent l'en-tête, le pied, le
       menu mobile, le titre animé et l'habillage du texte long.

       Trois choses ici, et rien d'autre : une grille de cartes, une rangée
       de filtres, une pagination. Plus ce qu'un article ajoute à une page
       légale — un visuel à la une, des légendes.
       ================================================================== */

    /* ==================================================================
       Rangée de filtres

       Des liens, pas des boutons : chaque vue filtrée a son adresse. Sous
       la largeur d'un téléphone, la rangée défile dans sa propre boîte
       plutôt que de passer à la ligne sur quatre rangs — et surtout,
       plutôt que de faire défiler la page.
       ================================================================== */
    .b-filters {
      margin: 3.25rem 0 0;
      /* La boîte de défilement doit pouvoir dépasser la gouttière du
         conteneur, sinon la dernière pastille reste collée au bord. */
      margin-inline: -0.35rem;
    }

    .b-filters-list {
      display: flex;
      gap: 0.5rem;
      list-style: none;
      overflow-x: auto;
      padding: 0.35rem;
      scrollbar-width: none;
      -ms-overflow-style: none;
    }

    .b-filters-list::-webkit-scrollbar { display: none; }

    .b-filter {
      display: block;
      white-space: nowrap;
      padding: 0.55rem 1.05rem;
      border: 1px solid rgba(18, 18, 78, 0.12);
      border-radius: 999px;
      font-size: 0.875rem;
      font-weight: 600;
      color: #4E4C74;
      text-decoration: none;
      transition: border-color 0.3s ease, color 0.3s ease, background 0.3s ease;
    }

    .b-filter:hover {
      border-color: rgba(104, 94, 248, 0.45);
      color: #12124E;
    }

    .b-filter.is-current {
      background: #12124E;
      border-color: #12124E;
      color: #FDFCFE;
    }

    /* ==================================================================
       Grille de cartes

       Trois colonnes, deux, puis une. Un nombre fixe par palier plutôt
       qu'auto-fill : la largeur de carte doit être la même quel que soit le
       nombre d'articles de la dernière rangée. minmax(0, 1fr) — et non
       simplement 1fr — empêche un titre insécable d'élargir sa colonne au
       détriment des deux autres.
       ================================================================== */
    .b-grid {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 2rem;
      margin: 2.75rem 0 0;
    }

    /* Une seule page de résultats : sans .b-pager pour porter l'espace
       avant le pied de page (voir plus bas), la grille doit le porter
       elle-même. Ciblée par :last-child, cette règle ne s'applique que
       lorsque la pagination est absente — sa présence fournit déjà cet
       espace, et les deux ne doivent pas s'additionner. */
    .b-grid:last-child {
      margin-bottom: 6.5rem;
    }

    .b-card {
      position: relative;
      display: flex;
      flex-direction: column;
      /* Toutes les cartes d'une rangée ont la même hauteur — c'est la
         grille qui l'impose — et leur pied reste aligné grâce au
         margin-top: auto du bloc de date. */
      background: #FFFFFF;
      border: 1px solid rgba(18, 18, 78, 0.08);
      border-radius: 18px;
      overflow: hidden;
      transition: transform 0.4s var(--ease-out), box-shadow 0.4s ease,
                  border-color 0.4s ease;
    }

    .b-card:hover {
      transform: translateY(-4px);
      border-color: rgba(104, 94, 248, 0.28);
      box-shadow: 0 18px 40px -24px rgba(18, 18, 78, 0.28);
    }

    /* Le visuel : rapport fixe, donc aucun saut de mise en page pendant le
       chargement, et une carte sans image à la une garde les proportions
       de ses voisines. */
    .b-card-media {
      position: relative;
      aspect-ratio: 16 / 9;
      overflow: hidden;
      background: rgba(104, 94, 248, 0.07);
    }

    .b-card-media img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: transform 0.6s var(--ease-out);
    }

    .b-card:hover .b-card-media img { transform: scale(1.035); }

    /* Ni image à la une, ni visuel de remplacement : un aplat de la palette,
       traversé du même filet que les tokens de section. La carte garde ses
       proportions, et rien ne ressemble à une image qui n'a pas chargé. */
    .b-card-media.is-blank {
      background: linear-gradient(135deg, rgba(104, 94, 248, 0.12), rgba(155, 160, 250, 0.06));
    }

    .b-card-media.is-blank::after {
      content: '';
      position: absolute;
      left: 1.5rem;
      bottom: 1.5rem;
      width: 8px;
      height: 8px;
      border-radius: 2px;
      background: rgba(104, 94, 248, 0.55);
    }

    .b-card-body {
      display: flex;
      flex-direction: column;
      flex: 1;
      padding: 1.5rem 1.5rem 1.35rem;
    }

    .b-card-cat {
      align-self: flex-start;
      font-size: 0.75rem;
      font-weight: 600;
      letter-spacing: 0.1em;
      text-transform: uppercase;
      color: #685EF8;
    }

    .b-card-title {
      margin: 0.7rem 0 0;
      font-size: 1.1875rem;
      font-weight: 600;
      line-height: 1.35;
      letter-spacing: -0.01em;
      color: #12124E;
      /* Un titre très long ne doit pas repousser l'extrait hors de la
         carte : trois lignes, puis l'ellipse. La hauteur de la carte reste
         celle de la rangée. */
      display: -webkit-box;
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }

    .b-card-excerpt {
      margin: 0.7rem 0 0;
      font-size: 0.9375rem;
      line-height: 1.6;
      color: #4E4C74;
      display: -webkit-box;
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }

    .b-card-foot {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 1rem;
      /* C'est ce qui aligne les pieds de carte d'une même rangée, quelle
         que soit la longueur des titres au-dessus. */
      margin-top: auto;
      padding-top: 1.35rem;
      font-size: 0.8125rem;
      color: #6F6C93;
    }

    .b-card-cta {
      display: inline-flex;
      align-items: center;
      gap: 0.35rem;
      font-weight: 600;
      color: #685EF8;
    }

    .b-card-cta svg {
      width: 15px;
      height: 15px;
      transition: transform 0.3s var(--ease-out);
    }

    .b-card:hover .b-card-cta svg { transform: translateX(3px); }

    /* Le lien de couverture : une seule destination annoncée pour toute la
       carte. Il est posé au-dessus du contenu, mais reste sous le survol
       des transformations puisqu'il ne peint rien. */
    .b-card-link {
      position: absolute;
      inset: 0;
      z-index: 2;
      border-radius: inherit;
    }

    .b-card-link:focus-visible {
      outline: 2px solid #685EF8;
      outline-offset: 3px;
    }

    /* ==================================================================
       Pagination

       Numérotée, en liens : elle fonctionne sans JavaScript, se partage et
       s'indexe. Les bornes désactivées restent affichées — leur
       disparition ferait sauter la rangée d'une page à l'autre.
       ================================================================== */
    .b-pager {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 1rem;
      margin: 3.5rem 0 6.5rem;
      font-size: 0.875rem;
    }

    .b-pager-step {
      display: inline-flex;
      align-items: center;
      gap: 0.45rem;
      font-weight: 600;
      color: #685EF8;
      text-decoration: none;
      white-space: nowrap;
    }

    .b-pager-step svg { width: 16px; height: 16px; }

    .b-pager-step.is-off {
      color: rgba(18, 18, 78, 0.28);
      pointer-events: none;
    }

    .b-pager-nums {
      display: flex;
      gap: 0.3rem;
      list-style: none;
    }

    .b-pager-num {
      display: grid;
      place-items: center;
      min-width: 2.25rem;
      height: 2.25rem;
      padding: 0 0.5rem;
      border-radius: 10px;
      font-weight: 600;
      color: #4E4C74;
      text-decoration: none;
      transition: background 0.25s ease, color 0.25s ease;
    }

    .b-pager-num:hover { background: rgba(104, 94, 248, 0.1); color: #12124E; }

    .b-pager-num.is-current { background: #12124E; color: #FDFCFE; }

    /* ==================================================================
       Liste vide

       Une rubrique sans article et une catégorie sans article publié dans
       la langue consultée aboutissent ici. La page garde son en-tête et
       son pied : le visiteur doit pouvoir repartir.
       ================================================================== */
    .b-empty {
      max-width: 34rem;
      padding: 3.5rem 0 7rem;
    }

    .b-empty h2 {
      font-size: 1.5rem;
      font-weight: 600;
      letter-spacing: -0.01em;
      color: #12124E;
    }

    .b-empty-body {
      margin-top: 0.9rem;
      font-size: 1rem;
      line-height: 1.7;
      color: #4E4C74;
    }

    /* ==================================================================
       Page d'article

       Le corps porte la classe « legal » — l'habillage de texte long du
       site — et n'ajoute ici que ce qu'un article a de plus : un visuel à
       la une, des légendes, des images intégrées au texte.
       ================================================================== */

    /* Le titre d'un article est une phrase, pas un mot : sans plafond, il
       occuperait un écran entier avant la première ligne. Même correction
       que sur les pages légales. */
    .page-head h1 { font-size: clamp(2.5rem, 7vw, 4.5rem); }

    .b-meta {
      margin-top: 1.1rem;
      font-size: 0.875rem;
      color: #6F6C93;
    }

    .b-hero {
      margin: 3rem 0 0;
      max-width: 60rem;
    }

    .b-hero img {
      display: block;
      width: 100%;
      height: auto;
      border-radius: 18px;
    }

    /* Le visuel à la une n'a plus de légende ; celle-ci ne s'applique
       donc qu'aux images légendées par l'auteur dans le corps du texte. */
    .b-body figcaption {
      margin-top: 0.7rem;
      font-size: 0.8125rem;
      line-height: 1.6;
      color: #6F6C93;
    }

    .b-body {
      /* .legal plafonne à 46rem — pensé pour les pages légales, du texte
         seul, sans visuel. Un article porte une image à la une plafonnée à
         60rem (.b-hero) : lui laisser la colonne à 46rem aurait rendu le
         texte visiblement plus étroit que l'image juste au-dessus, comme
         si le contenu n'utilisait pas toute la largeur disponible. La
         colonne du corps est donc alignée sur celle du visuel. Cette règle
         gagne sur celle de legal.css par l'ordre de chargement : blog.css
         est enfilé après, à spécificité égale.
         L'article n'ajoute qu'un peu d'air au-dessus, le visuel à la une
         l'ayant déjà précédé. */
      max-width: 60rem;
      padding-top: 2.5rem;
      padding-bottom: 3rem;
    }

    .b-body img {
      display: block;
      max-width: 100%;
      height: auto;
      border-radius: 14px;
    }

    .b-body figure { margin: 2rem 0; }

    .b-body .alignleft,
    .b-body .alignright,
    .b-body .aligncenter { margin-inline: auto; }

    /* Une citation : un filet, pas une boîte. Le même vocabulaire que les
       filets de tableau des pages légales. */
    .b-body blockquote {
      margin: 2rem 0;
      padding: 0.35rem 0 0.35rem 1.5rem;
      border-left: 2px solid rgba(104, 94, 248, 0.45);
      font-size: 1.0625rem;
      line-height: 1.7;
      color: #12124E;
    }

    .b-body blockquote p:first-child { margin-top: 0; }
    .b-body blockquote p:last-child { margin-bottom: 0; }

    /* Les blocs qui ne se compriment pas — code, contenu embarqué — défilent
       dans leur propre boîte. La page, elle, ne défile jamais
       horizontalement. */
    .b-body pre {
      margin: 1.75rem 0;
      padding: 1.1rem 1.25rem;
      overflow-x: auto;
      background: rgba(18, 18, 78, 0.04);
      border-radius: 12px;
      font-size: 0.875rem;
      line-height: 1.6;
    }

    .b-body code {
      font-size: 0.9em;
      background: rgba(104, 94, 248, 0.09);
      padding: 0.1em 0.35em;
      border-radius: 5px;
    }

    .b-body pre code { background: none; padding: 0; }

    .b-body .wp-block-embed,
    .b-body iframe {
      max-width: 100%;
    }

    /* Au-dessus de l'article, quoi qu'il arrive : tant que sa révélation
       n'est pas jouée, l'article reste décalé de son --rv-d et son bas
       recouvrait ce lien, qui ne répondait plus au clic. */
    .b-back {
      position: relative;
      z-index: 1;
      padding-bottom: 6.5rem;
      font-size: 0.9375rem;
    }

    .b-back a {
      display: inline-flex;
      align-items: center;
      gap: 0.45rem;
      font-weight: 600;
      color: #685EF8;
      text-decoration: none;
    }

    .b-back svg {
      width: 16px;
      height: 16px;
      transition: transform 0.3s var(--ease-out);
    }

    .b-back a:hover svg { transform: translateX(-3px); }

    /* ==================================================================
       Largeurs intermédiaires et téléphone
       ================================================================== */
    @media (max-width: 1000px) {
      .b-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 1.5rem;
      }

      .b-hero { margin-top: 2.25rem; }
    }

    @media (max-width: 640px) {
      .b-grid {
        grid-template-columns: minmax(0, 1fr);
        gap: 1.25rem;
        margin-top: 2rem;
      }

      .b-grid:last-child {
        margin-bottom: 4.5rem;
      }

      .b-filters { margin-top: 2.25rem; }

      .b-card-body { padding: 1.25rem 1.25rem 1.15rem; }

      .b-card-title { font-size: 1.0625rem; }

      /* La pagination passe en colonne : trois blocs sur une ligne de
         320 px se chevauchaient. Les numéros défilent dans leur boîte
         plutôt que de déborder — au-delà d'une dizaine de pages, une
         rangée de numéros ne tient pas sur un téléphone. */
      .b-pager {
        flex-direction: column;
        gap: 1.25rem;
        margin: 2.5rem 0 4.5rem;
      }

      .b-pager-nums {
        order: -1;
        max-width: 100%;
        overflow-x: auto;
        scrollbar-width: none;
      }

      .b-pager-nums::-webkit-scrollbar { display: none; }

      .b-empty { padding: 2.5rem 0 5rem; }

      .b-hero img,
      .b-body img { border-radius: 12px; }

      .b-body { padding-top: 1.75rem; }

      .b-back { padding-bottom: 4.5rem; }
    }

    /* ==================================================================
       Révélations

       Même doctrine que les autres pages : rien n'est masqué par défaut,
       le décalage n'est posé que si l'observateur est disponible et que le
       visiteur n'a pas demandé moins d'animation.
       ================================================================== */
    @media (prefers-reduced-motion: no-preference) {
      html.rv-on .b-card[data-rv="rise"],
      html.rv-on .b-filters[data-rv="rise"] {
        transform: translateY(var(--rv-d, 26px));
        transition: transform 0.85s var(--ease-out);
        transition-delay: var(--rv-delay, 0s);
      }

      html.rv-on .b-card[data-rv="rise"].rv-in,
      html.rv-on .b-filters[data-rv="rise"].rv-in { transform: translateY(0); }
    }
