/* ==========================================================================
   Renaissance Executives — thème Ghost
   Éditorial noir, typographie géométrique massive, rouge en accent
   (#840000, la couleur de marque d'Anne — voir la note sur les DEUX rouges § Tokens).
   Titres en Outfit (la grammaire de robertwalters.co.uk, référence design d'origine),
   corps en Inter. Les deux auto-hébergées — voir la nuance sur jsdelivr plus bas.

   11/08/2026 — passe adoucissante demandée par Anne (« moins noir, moins rouge,
   plus de gris ») : texture de connexions neuronales en fond (§ 7), rouge retiré
   de tout ce qui en portait par défaut (§ Tokens), noirs de fond relevés, et un
   rayon de 6px sur les boutons et les objets isolés. L'ossature éditoriale — la
   grille des thématiques, les bordures de stats — reste vive : voir .card-grid.

   Zéro dépendance : polices auto-hébergées, aucun framework, aucun CDN appelé
   par le thème. Calendly n'est chargé qu'au clic, sur /book/ seulement.

   Nuance honnête : le site contacte malgré tout cdn.jsdelivr.net, car Ghost y
   charge son widget de recherche (sodo-search) depuis {{ghost_head}} — hors de
   portée du thème, et non désactivable par un réglage. Audit réseau du
   17/07/2026 : c'est le SEUL tiers au chargement, et zéro cookie est posé.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Polices auto-hébergées (variables, subset latin, OFL)
   -------------------------------------------------------------------------- */

@font-face {
    font-family: 'Outfit';
    src: url('../fonts/outfit-latin-var.woff2') format('woff2-variations');
    font-weight: 300 800;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                   U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                   U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Inter';
    src: url('../fonts/inter-latin-var.woff2') format('woff2-variations');
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                   U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                   U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --------------------------------------------------------------------------
   2. Tokens
   -------------------------------------------------------------------------- */

:root {
    /* Palette — noir dominant, blanc cassé, rouge Renaissance.
       Contrastes mesurés sur --black (#0E0E0E), WCAG 2.x :
         --cream     17.1:1  AAA
         --cream-70   8.6:1  AAA
         --cream-55   5.7:1  AA  ← seuil AA (4.5:1) atteint dès 0.48
         --red        5.7:1  AA
       --cream-15 et --cream-08 sont sous le seuil : filets, bordures et fonds
       uniquement, jamais de texte.

       🔴 DEUX ROUGES, ET CE N'EST PAS UNE COQUETTERIE.

       #840000 est la couleur de marque donnée par Anne (07/08/2026) — c'est celle
       des boutons de son Webflow. Sur le noir du thème elle plafonne à **1,8:1** :
       inutilisable en texte, et invisible en anneau de focus. Elle ne sert donc
       QUE d'aplat, avec du crème par-dessus (10,6:1, AAA).

       Partout où l'ancien --gold servait de COULEUR DE TEXTE — eyebrows, liens,
       chiffres, filets, marqueurs, focus — c'est --red qui prend le relais.

       Ne jamais intervertir les deux. Mettre --red-deep sur du texte, ou --red en
       fond d'un bouton à texte crème (2,9:1), casse la recette axe-core du site.

       11/08/2026 — Anne trouve le site trop noir et trop rouge. Le rouge n'est pas
       parti des boutons (c'est sa couleur de marque) : il est parti de tout ce qui
       en portait par DÉFAUT et sans raison — eyebrows, numéros de cartes, titres de
       colonne du footer, les trois grands chiffres. Ces éléments sont passés à
       --cream-55 / --cream. Le rouge est redevenu ce qu'il devait être : un accent,
       pas une couleur de corps de texte. Et les deux noirs de fond sont relevés
       d'un cran vers le gris. */
    --black:        #0E0E0E;
    --black-soft:   #191919;  /* était #161616 — relevé le 11/08 */
    --black-lift:   #262626;  /* était #1F1F1F — relevé le 11/08 */
    --cream:        #F4F1EA;
    --cream-70:     rgba(244, 241, 234, 0.70);
    --cream-55:     rgba(244, 241, 234, 0.55);
    --cream-15:     rgba(244, 241, 234, 0.15);
    --cream-08:     rgba(244, 241, 234, 0.08);
    --red-deep:     #840000;  /* aplats uniquement, texte crème par-dessus */
    --red-deep-h:   #A00000;  /* hover des aplats — crème à 8,4:1 */
    --red:          #E0574A;  /* texte, liens, filets, focus */
    --red-bright:   #F07A6D;  /* hover du texte accent */

    /* Typo */
    --font-display: 'Outfit', 'Avenir Next', 'Segoe UI', system-ui, sans-serif;
    --font-body:    'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

    /* Layout.

       Le thème était à --radius: 0 partout (grammaire Robert Walters). Anne a
       demandé le 11/08 un léger arrondi sur les boutons ; 6px adoucit sans
       basculer dans le rendu « application ».

       Ce token ne s'applique PAS à tout : les cartes thématiques et les bordures
       de stats restent vives. Voir la note sur .card-grid — leurs filets sont
       dessinés par des ombres jointives dans un gap de 1px, et un rayon y ouvre
       une encoche à chaque jonction. */
    --container:    1240px;
    --content:      680px;
    --gutter:       clamp(1.25rem, 5vw, 4rem);
    --radius:       6px;

    /* Rythme vertical */
    --section-y:    clamp(4.5rem, 11vw, 9rem);
}

/* --------------------------------------------------------------------------
   3. Reset & base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

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

body {
    margin: 0;
    background: var(--black);
    color: var(--cream);
    font-family: var(--font-body);
    font-size: 1.0625rem;
    line-height: 1.65;
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
}

img, svg, video { max-width: 100%; height: auto; display: block; }

a { color: inherit; text-decoration: none; }

button { font: inherit; cursor: pointer; border: 0; background: none; color: inherit; }

h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 600;
    line-height: 1.05;
    letter-spacing: -0.02em;
    margin: 0;
}

p { margin: 0 0 1.25em; }

::selection { background: var(--red-deep); color: var(--cream); }

/* L'anneau de focus est un indicateur, pas une décoration : WCAG lui impose 3:1
   contre le fond adjacent. --red-deep y est à 1,8:1, donc c'est --red ici — sinon
   la navigation au clavier devient invisible sur tout le site.

   🔴 Et il RESTE rouge malgré le dé-rougissement du 11/08. Le passer en crème
   paraît cohérent avec le reste et casserait la recette : .cta-band est sur fond
   crème, un anneau crème y serait à 1:1, donc littéralement absent de la seule
   section qui porte la conversion. --red tient 3,32:1 sur le crème et 5,7:1 sur
   le noir — c'est la seule des deux valeurs qui marche des deux côtés. */
:focus-visible {
    outline: 2px solid var(--red);
    outline-offset: 3px;
}

.skip-link {
    position: absolute;
    top: -100%;
    left: var(--gutter);
    z-index: 200;
    padding: 0.75rem 1.25rem;
    background: var(--red-deep);
    color: var(--cream);
    font-weight: 600;
    border-radius: var(--radius);
}
.skip-link:focus { top: 1rem; }

/* --------------------------------------------------------------------------
   4. Primitives
   -------------------------------------------------------------------------- */

.container {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }

.section--soft { background: var(--black-soft); }

/* Filet rouge : la signature graphique du thème.

   C'est un aplat, mais il ne porte aucun texte — il doit se VOIR sur le noir.
   D'où --red et non --red-deep, qui donnerait un filet quasi invisible (1,8:1). */
.rule {
    width: 4.5rem;
    height: 3px;
    background: var(--red);
    border: 0;
    margin: 0 0 2rem;
}

/* Micro-label capitales — le contrepoint des titres massifs.

   Rouge jusqu'au 11/08/2026. C'était la plus grosse source de rouge du site :
   .eyebrow coiffe CHAQUE section de chaque page. En crème atténué, la couleur de
   marque redevient un accent au lieu d'un ton dominant — c'est très exactement ce
   qu'Anne demandait. */
.eyebrow {
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--cream-55);
    margin: 0 0 1.25rem;
}

.lede {
    font-size: clamp(1.125rem, 1.9vw, 1.375rem);
    line-height: 1.55;
    color: var(--cream-70);
    max-width: 46ch;
}

/* Lien dans un paragraphe : le reset pose `a { color: inherit; text-decoration:
   none }`, donc un lien en pleine prose serait invisible sans ceci. */
.inline-link {
    color: var(--red);
    text-decoration: underline;
    text-underline-offset: 0.2em;
}
.inline-link:hover { color: var(--red-bright); }

/* Titres de section */
.section-title {
    font-size: clamp(2.25rem, 5vw, 3.75rem);
}

.section-head { margin-bottom: clamp(2.5rem, 5vw, 4rem); }

/* --------------------------------------------------------------------------
   5. Boutons — légèrement arrondis depuis le 11/08, contraste maximal
   -------------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    padding: 1.0625rem 2rem;
    font-family: var(--font-body);
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    border-radius: var(--radius);
    transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.btn__arrow { transition: transform 0.2s ease; }
.btn:hover .btn__arrow { transform: translateX(4px); }

/* Le CTA principal reprend exactement le bouton du Webflow d'Anne : aplat #840000,
   texte clair. Le texte passe en crème et non en noir — sur ce rouge sombre, du
   noir tomberait à 1,5:1. */
.btn--primary {
    background: var(--red-deep);
    color: var(--cream);
}
.btn--primary:hover { background: var(--red-deep-h); }

/* Sur fond clair (bande CTA inversée) */
.btn--invert {
    background: var(--black);
    color: var(--cream);
}
.btn--invert:hover { background: var(--black-lift); }

.btn-note {
    font-size: 0.875rem;
    color: var(--cream-55);
    letter-spacing: 0.02em;
}

.btn-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.25rem;
}

/* --------------------------------------------------------------------------
   6. Header
   -------------------------------------------------------------------------- */

.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: rgba(14, 14, 14, 0.85);
    backdrop-filter: saturate(160%) blur(12px);
    -webkit-backdrop-filter: saturate(160%) blur(12px);
    border-bottom: 1px solid var(--cream-08);
}

.site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    min-height: 76px;
}

/* Logotype typographique — net sur du noir, quelques octets, jamais flou */
/* Logotype — « RENAISSANCE. EXECUTIVES »

   L'ancien réglage était un serif capitales à 0.14em : à 20 px, la chasse écartée
   diluait le mot et faisait maison d'édition plutôt que cabinet. Outfit est
   géométrique et supporte les capitales serrées ; on descend à 0.08em, ce qui
   rend le logotype nettement plus net à taille réelle.

   Le nom est écrit en entier (voir logotype.hbs) : « Executives » est plus léger
   et plus discret, pour hiérarchiser sans allonger la barre de navigation. */
.logotype {
    display: inline-flex;
    align-items: baseline;
    gap: 0.45rem;
    font-family: var(--font-display);
    font-size: 1.125rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--cream);
    white-space: nowrap;
}
.logotype em {
    font-style: normal;
    color: var(--red);
    margin-left: -0.4rem;
}
.logotype__sub {
    font-weight: 300;
    letter-spacing: 0.14em;
    color: var(--cream-70);
}
.logotype img { max-height: 34px; width: auto; }

/* 🔴 `flex-shrink: 0` et `white-space: nowrap`, posés le 19/08/2026 en même temps
   que la 6ᵉ entrée de nav (« Reviews »).

   Le problème n'était PAS un manque de place : à 1440 px le contenu demande
   ~1150 px pour 1240 px disponibles. C'est le `flex-shrink: 1` par défaut qui
   comprimait la nav et le bouton sous leur largeur de contenu — « How we work
   with you » et « Book a discovery chat » passaient chacun sur deux lignes et la
   barre montait à 76 px de haut. Un flex item se laisse écraser en silence.

   Le gap descend de 2.25rem à 1.5rem : six entrées à 36 px d'écart ne tenaient
   plus qu'en rognant ailleurs. */
.nav {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    margin-left: auto;
    flex-shrink: 0;
}

.nav a {
    white-space: nowrap;
    font-size: 0.9375rem;
    font-weight: 500;
    color: var(--cream-70);
    position: relative;
    padding-block: 0.25rem;
    transition: color 0.2s ease;
}
.nav a::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 0;
    height: 2px;
    background: var(--red);
    transition: width 0.25s ease;
}
.nav a:hover, .nav li.nav-current a { color: var(--cream); }
.nav a:hover::after, .nav li.nav-current a::after { width: 100%; }

.nav ul {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.site-header .btn {
    padding: 0.8125rem 1.25rem;
    flex-shrink: 0;
    white-space: nowrap;
}

/* Burger */
.burger {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 44px;
    height: 44px;
    margin-right: -10px;
}
.burger span {
    display: block;
    height: 2px;
    width: 24px;
    background: var(--cream);
    margin-inline: auto;
    transition: transform 0.25s ease, opacity 0.2s ease;
}
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Menu mobile */
.mobile-menu {
    display: none;
    border-top: 1px solid var(--cream-08);
    background: var(--black);
    padding: 1.5rem var(--gutter) 2.5rem;
}
.mobile-menu.is-open { display: block; }
.mobile-menu ul { list-style: none; margin: 0 0 1.75rem; padding: 0; }
.mobile-menu li { border-bottom: 1px solid var(--cream-08); }
.mobile-menu a {
    display: block;
    padding: 1rem 0;
    font-family: var(--font-display);
    font-size: 1.375rem;
    font-weight: 600;
}
.mobile-menu .btn { width: 100%; justify-content: center; }

/* --------------------------------------------------------------------------
   7. Hero éditorial — le LCP reste un bloc de texte
   -------------------------------------------------------------------------- */

.hero {
    padding-block: clamp(5rem, 13vw, 10.5rem) clamp(3.5rem, 8vw, 6rem);
    position: relative;
    overflow: hidden;
}

/* Connexion neuronale — l'image fournie par Anne le 11/08/2026, qui remplace le
   réseau qu'on avait redessiné en SVG. Elle demandait un site moins noir et plus
   doux : une texture grise fait ce qu'un tracé vectoriel net ne fait pas.

   🔴 LE FICHIER SOURCE PORTAIT UN ALPHA UNIFORME DE 133/255 CUIT DEDANS.
   Il a été jeté à la conversion (voir assets-sources/neurolink-source.png) :
   sinon l'opacité s'applique deux fois — une fois dans le PNG, une fois ici — et
   plus aucune valeur de ce fichier ne veut dire ce qu'elle dit. Le WebP servi
   est opaque, du noir au blanc pur, et le CSS pilote seul.

   Ni z-index ni empilement explicite : .hero__texture et .hero__inner sont tous
   deux en z-index auto et se peignent dans l'ordre du DOM. La texture est
   déclarée AVANT le contenu dans home.hbs, elle passe donc dessous. Ajouter un
   z-index ici créerait un contexte d'empilement dont on n'a pas besoin.

   🔴 LES OPACITÉS SONT BORNÉES PAR LE CONTRASTE, PAS CHOISIES À L'ŒIL.
   --cream-55 (les crédentiels, les .btn-note) est à 5,7:1 sur --black : environ
   1,2× de marge avant de tomber sous le seuil AA de 4,5:1. Composite du pixel le
   plus clair de l'image (255) sur --black, pour --cream-55 :
       α .12 → 4,9:1 ✅   α .15 → 4,6:1 ✅   α .18 → 4,3:1 ❌   α .30 → 3,1:1 ❌
   D'où 0.30 ici mais SOUS MASQUE — le texte vit dans la zone éteinte et ne voit
   au pire que 0.15 — et 0.14 sur mobile où le masque tombe.

   ⚠️ axe-core ne sait pas mesurer un contraste au-dessus d'une image de fond : il
   répond `incomplete`, pas `pass`. La recette ne prouve plus ce point toute
   seule, c'est l'arithmétique ci-dessus qui le tient. Ne pas remonter ces
   valeurs sans la refaire. */
.hero__texture {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: url('../images/neurolink.webp') center right / cover no-repeat;
    opacity: 0.30;
    /* Le masque éteint le motif à gauche, là où vit le texte. Sans support de
       `mask-image` la texture reste visible partout — dégradé acceptable : à
       0.30, --cream reste à 6,4:1 même sur un nœud blanc pur. */
    -webkit-mask-image: linear-gradient(100deg, transparent 30%, rgba(0,0,0,0.5) 58%, #000 82%);
            mask-image: linear-gradient(100deg, transparent 30%, rgba(0,0,0,0.5) 58%, #000 82%);
}

/* Mobile : le texte occupe toute la largeur, il n'y a plus de « côté droit » à
   réserver au motif. Garder le masque latéral revenait à effacer la connexion
   neuronale de l'écran sur lequel la majorité des visiteurs arrivent (vérifié
   à 390px le 07/08/2026 : elle était invisible).

   On lève donc le masque et on descend l'opacité. 0.11 et pas 0.14 : mesuré sur
   le rendu réel (pixel le plus clair sous les glyphes, pas sous la boîte), 0.14
   laissait l'eyebrow et la note du CTA à 4,70:1 — au-dessus du seuil, mais à 4 %
   près. Sur un site public, 4 % n'est pas une marge, c'est une coïncidence.
   0.11 les remonte autour de 5:1. */
@media (max-width: 768px) {
    .hero__texture {
        -webkit-mask-image: none;
                mask-image: none;
        opacity: 0.11;
    }
}

/* Texture discrète sur le reste du site — c'est elle qui adoucit les pages
   internes, et pas seulement la home.

   0.07 : le composite plafonne à #1F1F1F, où --cream-55 tient encore 5,6:1.
   Autrement dit, aucun texte du site ne change de statut.

   `isolation: isolate` + `z-index: -1` : le pseudo-élément passe sous le contenu
   sans sortir de son parent. Sans l'isolation, un z-index négatif remonterait
   jusqu'au contexte racine et disparaîtrait derrière le fond du body.

   Pas de texture sur .cta-band : elle est sur fond crème, l'image y jouerait à
   l'envers (des nœuds sombres sur du clair). */
.section--soft,
.page-hero {
    position: relative;
    isolation: isolate;
}
.section--soft::before,
.page-hero::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: url('../images/neurolink.webp') center / cover no-repeat;
    opacity: 0.07;
}

.hero__inner { position: relative; }

.hero__eyebrow {
    font-family: var(--font-body);
    font-size: clamp(0.8125rem, 1.4vw, 0.9375rem);
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--cream-55);
    margin: 0 0 1.5rem;
}

.hero__title {
    font-size: clamp(3rem, 8.5vw, 7rem);
    line-height: 0.94;
    letter-spacing: -0.035em;
    font-weight: 600;
    max-width: 15ch;
    margin-bottom: 2rem;
}

/* Titre long — la phrase de bienvenue d'Anne (07/08/2026) fait 200 caractères.
   La taille par défaut est calibrée pour trois mots ; à 7rem cette phrase
   remplirait trois écrans. Modificateur plutôt que changement du token : un
   futur titre court doit rester possible sans revenir sur ce fichier. */
.hero__title--statement {
    font-size: clamp(1.75rem, 3.4vw, 2.75rem);
    line-height: 1.15;
    letter-spacing: -0.02em;
    max-width: 26ch;
}

/* Outfit n'a pas d'italique dessiné : `font-style: italic` produirait un faux
   oblique. L'accent du titre passe donc par la couleur seule. */
.hero__title em {
    font-style: normal;
    color: var(--red);
}

.hero__lede {
    font-size: clamp(1.125rem, 2vw, 1.5rem);
    line-height: 1.5;
    color: var(--cream-70);
    max-width: 44ch;
    margin-bottom: 2.75rem;
}

.hero__cta { margin-bottom: clamp(3rem, 7vw, 5rem); }

/* Barre de crédibilités — la preuve dès le premier écran */
.credentials {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.5rem;
    padding-top: 2rem;
    border-top: 1px solid var(--cream-15);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--cream-55);
}
.credentials__dot { color: var(--red); }

/* --------------------------------------------------------------------------
   8. Bande de statistiques
   -------------------------------------------------------------------------- */

.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    border-top: 1px solid var(--cream-15);
}

.stat {
    padding: clamp(2rem, 4vw, 3rem) clamp(1.25rem, 3vw, 2.5rem);
    border-bottom: 1px solid var(--cream-15);
    border-right: 1px solid var(--cream-15);
}
.stat:last-child { border-right: 0; }

/* Crème et non rouge depuis le 11/08/2026 : trois chiffres de 4,5rem en rouge
   étaient, en surface colorée, le plus gros aplat de la home. En crème ils
   frappent autant — c'est leur taille qui porte, pas leur couleur. */
.stat__figure {
    font-family: var(--font-display);
    font-size: clamp(3rem, 6vw, 4.5rem);
    font-weight: 600;
    line-height: 1;
    color: var(--cream);
    letter-spacing: -0.03em;
    margin-bottom: 0.75rem;
}

.stat__label {
    font-size: 0.9375rem;
    color: var(--cream-70);
    line-height: 1.5;
    margin: 0;
    max-width: 30ch;
}

.stat__source {
    display: block;
    margin-top: 0.75rem;
    font-size: 0.75rem;
    color: var(--cream-55);
    letter-spacing: 0.04em;
}

/* --------------------------------------------------------------------------
   9. Cartes thématiques
   -------------------------------------------------------------------------- */

/* Les filets sont portés par la CARTE (box-shadow), pas par le fond de la grille.

   La technique classique — `gap: 1px` sur un fond clair, cartes en noir par-dessus —
   dessine de jolis filets tant que la dernière rangée est pleine. Avec 8 thématiques
   sur 3 colonnes, la 9e cellule reste vide et le fond --cream-15 transparaît : un
   rectangle gris franc en bas de grille. Vu à l'écran le 17/07/2026.

   Ici chaque carte projette son propre filet de 1px ; les ombres des cartes voisines
   se rejoignent dans le gap de 1px et forment une ligne nette. Une cellule vide ne
   projette rien, donc ne montre rien. Le nombre de thématiques devient indifférent. */
/* 🔴 PAS DE border-radius SUR CETTE GRILLE, ni sur ses cartes, ni sur leurs
   vignettes — même après l'arrondi général du 11/08/2026.

   Les filets sont des ombres de 1px qui se rejoignent dans le gap : arrondir une
   carte ouvre une encoche à chacune des jonctions et la grille cesse de se lire
   comme une grille. Et la vignette déborde volontairement aux bords de la carte
   par marges négatives — l'arrondir sans arrondir la carte laisse un décrochage
   visible dans les coins. Les objets isolés (boutons, vidéo, citations, tarifs)
   sont arrondis ; l'ossature éditoriale reste vive. */
.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
    gap: 1px;
}

.therapy-card {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    padding: clamp(1.75rem, 3vw, 2.5rem);
    background: var(--black);
    /* Le filet de la grille : chaque carte porte le sien. Voir .card-grid. */
    box-shadow: 0 0 0 1px var(--cream-15);
    transition: background-color 0.25s ease;
    position: relative;
}
.therapy-card:hover { background: var(--black-lift); }

/* Vignette de carte. Marges négatives : l'image touche les bords de la carte
   alors que le texte garde son padding. */
.therapy-card__media {
    margin: calc(-1 * clamp(1.75rem, 3vw, 2.5rem));
    margin-bottom: 0.5rem;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    background: var(--black-lift);
}
.therapy-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Les sources sont déjà en noir et blanc ; le filtre ne fait qu'harmoniser
       les quelques dominantes qui restent, comme sur .team-card__media. */
    filter: grayscale(100%) contrast(1.05);
    transition: filter 0.4s ease, transform 0.6s ease;
}
.therapy-card:hover .therapy-card__media img {
    filter: grayscale(0%) contrast(1);
    transform: scale(1.04);
}

.therapy-card__num {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    color: var(--cream-55);
}

.therapy-card__title {
    font-size: 1.5rem;
    line-height: 1.15;
}

.therapy-card__text {
    font-size: 0.9375rem;
    color: var(--cream-70);
    margin: 0;
    flex: 1;
}

/* Crème et non rouge (11/08/2026) — et le survol passe en crème plein, pas en
   rouge : sur le fond relevé d'une carte survolée (--black-lift), --red tombe à
   4,1:1, sous le seuil AA pour ce corps. Le rouge y était déjà limite avant que
   --black-lift ne soit éclairci ; on ne prolonge pas le problème. */
.therapy-card__more {
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--cream-55);
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    transition: color 0.2s ease;
}
.therapy-card:hover .therapy-card__more { color: var(--cream); }
.therapy-card:hover .therapy-card__more .btn__arrow { transform: translateX(4px); }

/* Toute la carte est cliquable, sans imbriquer de lien dans un lien */
.therapy-card__link::after {
    content: '';
    position: absolute;
    inset: 0;
}

/* --------------------------------------------------------------------------
   9 bis. Vidéo — façade cliquable, YouTube chargé au clic (voir global.js)
   -------------------------------------------------------------------------- */

.video { max-width: 900px; }

/* aspect-ratio sur le conteneur ET width/height sur l'image : la place est
   réservée avant le décodage du poster, donc aucun décalage de mise en page
   au chargement. C'est aussi la boîte que l'iframe viendra remplir. */
.video__facade {
    position: relative;
    display: block;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--black-lift);
    box-shadow: 0 0 0 1px var(--cream-15);
    border-radius: var(--radius);
}

.video__poster {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Le poster est en couleur ; le site est en noir et blanc partout ailleurs
       (voir .team-card__media). On aligne, et la couleur revient au survol. */
    filter: grayscale(100%) contrast(1.05);
    transition: filter 0.4s ease, transform 0.6s ease;
}
.video__facade:hover .video__poster {
    filter: grayscale(0%) contrast(1);
    transform: scale(1.02);
}

/* Angles vifs comme tout le reste du thème — pas de pastille ronde façon
   YouTube. Aplat --red-deep, glyphe crème : 10,6:1. */
.video__play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: grid;
    place-items: center;
    width: 4.5rem;
    height: 4.5rem;
    background: var(--red-deep);
    color: var(--cream);
    transition: background-color 0.2s ease;
    border-radius: var(--radius);
}
.video__facade:hover .video__play { background: var(--red-deep-h); }

/* Le nom accessible du lien. Visible : sur un poster, un triangle seul ne dit
   pas ce qu'on va déclencher — ici, le chargement d'un tiers. */
.video__label {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 2.5rem 1.5rem 1.25rem;
    background: linear-gradient(transparent, rgba(14, 14, 14, 0.85));
    color: var(--cream);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    text-align: center;
}

.video__note {
    display: block;
    margin: 1rem 0 0;
    max-width: 52ch;
}

/* Une fois l'iframe posée, la façade disparaît et le conteneur devient la boîte
   16/9 de la vidéo. */
.video.is-loaded .video__facade { display: none; }
.video.is-loaded .video__frame {
    aspect-ratio: 16 / 9;
    width: 100%;
    box-shadow: 0 0 0 1px var(--cream-15);
    border-radius: var(--radius);
    overflow: hidden;
}
.video.is-loaded .video__frame iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

/* --------------------------------------------------------------------------
   10. Témoignages
   -------------------------------------------------------------------------- */

.quote-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: clamp(1.5rem, 3vw, 2.5rem);
}

.quote {
    padding: clamp(1.75rem, 3vw, 2.5rem);
    background: var(--black);
    border-left: 3px solid var(--red);
    margin: 0;
    border-radius: var(--radius);
}

.quote__text {
    font-family: var(--font-display);
    font-size: clamp(1.125rem, 1.8vw, 1.375rem);
    line-height: 1.4;
    /* Pas d'italique : Outfit n'en a pas (faux oblique). Le guillemet ouvrant et le
       filet rouge portent déjà la citation. */
    font-weight: 300;
    margin: 0 0 1.5rem;
}

/* L'attribution passe en crème atténué (11/08) ; c'est le filet gauche de la
   citation qui garde le rouge. Un accent par citation suffit. */
.quote__author {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--cream-55);
    font-style: normal;
}

/* Bandeau de témoignages des pages intérieures (18/08/2026).
   Même composant .quote que la home, volontairement affaibli : sur une page de
   contenu il accompagne, il ne concurrence pas. Le filet rouge tombe à --cream-15
   et le corps rétrécit — trois citations à pleine force juste au-dessus de la
   bande CTA feraient deux blocs qui se disputent la fin de page. */
.testimonial-band {
    border-top: 1px solid var(--cream-15);
}

.testimonial-band__label {
    margin-bottom: clamp(1.5rem, 3vw, 2rem);
}

.quote-grid--band {
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

.quote-grid--band .quote {
    padding: 0 0 0 1.25rem;
    background: none;
    border-left-color: var(--cream-15);
    border-radius: 0;
}

.quote-grid--band .quote__text {
    font-size: clamp(1rem, 1.3vw, 1.125rem);
    color: var(--cream-70);
    margin-bottom: 1rem;
}

/* Méta d'article — date et auteur. Ouvert avec le blog le 18/08/2026. */
.post-meta {
    margin: 1.5rem 0 0;
    font-size: 0.8125rem;
    letter-spacing: 0.04em;
    color: var(--cream-55);
}

.post-meta__sep { margin: 0 0.5rem; }

/* Formulaire d'inscription à la newsletter — /newsletter/, 19/08/2026.

   Ghost pose les classes d'état (loading, success, error) SUR LE <form>, pas sur
   le champ : d'où les sélecteurs descendants ci-dessous. Les trois messages sont
   toujours dans le DOM, à l'intérieur d'une région aria-live rendue en
   permanence — une région live créée au moment du changement n'est pas annoncée
   de façon fiable par les lecteurs d'écran.

   Le champ est en fond --black-lift et non transparent : sur .page-hero, un champ
   sans fond propre laisserait passer la texture derrière le texte saisi. */
.members-form {
    max-width: 34rem;
}

.members-form__label {
    display: block;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--cream-55);
    margin-bottom: 0.75rem;
}

.members-form__row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.members-form__input {
    flex: 1 1 16rem;
    min-width: 0;
    padding: 0.9rem 1.1rem;
    font: inherit;
    font-size: 1rem;
    color: var(--cream);
    background: var(--black-lift);
    border: 1px solid var(--cream-15);
    border-radius: var(--radius);
}

.members-form__input::placeholder { color: var(--cream-55); }

/* Le champ garde l'anneau de focus rouge du site. Voir la note sur :focus-visible
   au § accessibilité : --red est la seule valeur qui tienne sur le noir ET sur la
   bande CTA crème, et il ne faut pas y toucher. */
.members-form__input:focus-visible {
    outline: 2px solid var(--red);
    outline-offset: 2px;
    border-color: var(--red);
}

/* Les messages : cachés par défaut, révélés par l'état posé sur le formulaire. */
.members-form__msg {
    display: none;
    margin: 1rem 0 0;
    font-size: 0.9375rem;
    line-height: 1.5;
}

.members-form.loading .members-form__msg--loading,
.members-form.success .members-form__msg--success,
.members-form.error   .members-form__msg--error { display: block; }

.members-form__msg--loading { color: var(--cream-55); }
.members-form__msg--success { color: var(--cream); }
.members-form__msg--error   { color: var(--red); }

/* Une fois inscrit, le champ et le bouton n'ont plus de raison d'être : les
   laisser invite à réessayer et à recevoir un second lien. */
.members-form.success .members-form__row,
.members-form.success .members-form__label,
.members-form.success .members-form__note { display: none; }

.members-form__note { margin-top: 1.25rem; }

/* --------------------------------------------------------------------------
   11. Équipe
   -------------------------------------------------------------------------- */

.team-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: clamp(1.5rem, 3vw, 2.5rem);
}

.team-card { position: relative; }

.team-card__media {
    aspect-ratio: 3 / 4;
    overflow: hidden;
    background: var(--black-lift);
    margin-bottom: 1.25rem;
    position: relative;
    border-radius: var(--radius);
}
.team-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: grayscale(100%) contrast(1.05);
    transition: filter 0.4s ease, transform 0.6s ease;
}
.team-card:hover .team-card__media img {
    filter: grayscale(0%) contrast(1);
    transform: scale(1.03);
}

/* Repli quand aucune photo n'est fournie : monogramme, jamais une image cassée */
.team-card__fallback {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-family: var(--font-display);
    font-size: 3.5rem;
    font-weight: 600;
    color: var(--red);
    background: var(--black-lift);
}

.team-card__name {
    font-size: 1.375rem;
    margin-bottom: 0.25rem;
}

.team-card__role {
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--cream-55);
    margin: 0;
}

/* --------------------------------------------------------------------------
   12. Bande CTA inversée — le seul bloc clair du site, donc le plus fort
   -------------------------------------------------------------------------- */

.cta-band {
    background: var(--cream);
    color: var(--black);
    padding-block: clamp(3.5rem, 8vw, 6rem);
}

.cta-band__title {
    font-size: clamp(2rem, 4.5vw, 3.5rem);
    max-width: 20ch;
    margin-bottom: 1.5rem;
}

.cta-band__text {
    font-size: 1.125rem;
    color: rgba(14, 14, 14, 0.70);
    max-width: 48ch;
    margin-bottom: 2.5rem;
}

/* 0.62 et pas 0.55 : sur le crème de la bande, 0.55 tombe à 4.18:1 (échoue AA
   en petit corps). 0.62 donne 5.22:1. */
.cta-band .btn-note { color: rgba(14, 14, 14, 0.62); }

.cta-band .rule { background: var(--black); }

/* --------------------------------------------------------------------------
   13. FAQ — toggle cards natives de Ghost

   La FAQ est du CONTENU, pas du thème : Anne l'édite depuis l'éditeur Ghost.
   On style donc les toggle cards natives (.kg-toggle-card) plutôt que d'imposer
   un markup <details> maison — Ghost re-parse le HTML custom et détruit les
   classes hors marqueurs kg-card, et card_assets: true fournit déjà le
   comportement d'ouverture/fermeture.

   Classes vérifiées sur le HTML réellement généré par Ghost 6.52 (sonde du
   17/07/2026), pas supposées : le titre est .kg-toggle-heading-text (et non
   .kg-toggle-card-heading), et l'état est data-kg-toggle-state="close"|"open".
   -------------------------------------------------------------------------- */

.kg-toggle-card {
    border-bottom: 1px solid var(--cream-15);
    padding: 0;
}
.kg-toggle-card:first-of-type { border-top: 1px solid var(--cream-15); }

.kg-toggle-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    padding: 1.75rem 0;
    cursor: pointer;
}

.kg-toggle-heading-text {
    font-family: var(--font-display);
    font-size: clamp(1.125rem, 1.6vw, 1.375rem);
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: -0.01em;
    margin: 0;
    transition: color 0.2s ease;
}
.kg-toggle-heading:hover .kg-toggle-heading-text { color: var(--red); }

.kg-toggle-card-icon {
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    color: var(--red);
    transition: transform 0.25s ease;
}
.kg-toggle-card[data-kg-toggle-state="open"] .kg-toggle-card-icon {
    transform: rotate(45deg);
}

.kg-toggle-content {
    color: var(--cream-70);
    max-width: 62ch;
}
.kg-toggle-card[data-kg-toggle-state="open"] .kg-toggle-content {
    padding-bottom: 1.75rem;
}
.kg-toggle-content > :last-child { margin-bottom: 0; }
.kg-toggle-content a { color: var(--red); text-decoration: underline; text-underline-offset: 0.2em; }

/* --------------------------------------------------------------------------
   14. Footer
   -------------------------------------------------------------------------- */

.site-footer {
    border-top: 1px solid var(--cream-15);
    padding-block: clamp(3rem, 6vw, 4.5rem) 2rem;
    background: var(--black);
}

.site-footer__top {
    display: grid;
    grid-template-columns: 1.5fr 1fr 1fr;
    gap: clamp(2rem, 5vw, 4rem);
    margin-bottom: 3.5rem;
}

.site-footer__tagline {
    color: var(--cream-55);
    font-size: 0.9375rem;
    max-width: 32ch;
    margin: 1.25rem 0 0;
}

.footer-col__title {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--cream-55);
    margin: 0 0 1.25rem;
}

.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li { margin-bottom: 0.75rem; }
.footer-col a, .footer-col span {
    font-size: 0.9375rem;
    color: var(--cream-70);
    transition: color 0.2s ease;
}
.footer-col a:hover { color: var(--red); }

.site-footer__bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 1rem;
    padding-top: 2rem;
    border-top: 1px solid var(--cream-08);
    font-size: 0.8125rem;
    color: var(--cream-55);
}
.site-footer__bottom a:hover { color: var(--red); }

/* --------------------------------------------------------------------------
   15. Contenu éditeur Ghost (prose)
   -------------------------------------------------------------------------- */

.prose {
    max-width: var(--content);
    font-size: 1.125rem;
    line-height: 1.7;
    color: var(--cream-70);
}

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

.prose h2 {
    font-size: clamp(1.75rem, 3.2vw, 2.5rem);
    color: var(--cream);
    margin-top: 2.5em;
}
.prose h3 {
    font-size: clamp(1.25rem, 2.2vw, 1.625rem);
    color: var(--cream);
    margin-top: 2em;
}

.prose strong { color: var(--cream); font-weight: 600; }

.prose a {
    color: var(--red);
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
}
.prose a:hover { color: var(--red-bright); }

.prose ul, .prose ol { padding-left: 1.25em; }
.prose li { margin-bottom: 0.625em; }
.prose li::marker { color: var(--red); }

.prose blockquote {
    margin: 2em 0;
    padding-left: 1.5rem;
    border-left: 3px solid var(--red);
    font-family: var(--font-display);
    font-weight: 300;
    font-size: 1.375rem;
    line-height: 1.4;
    color: var(--cream);
}

.prose hr {
    border: 0;
    border-top: 1px solid var(--cream-15);
    margin: 3em 0;
}

.prose figure { margin: 2.5em 0; }
.prose figcaption {
    font-size: 0.8125rem;
    color: var(--cream-55);
    text-align: center;
    margin-top: 0.75rem;
}

/* Cards Ghost pleine largeur */
.prose :is(.kg-width-wide, .kg-width-full) {
    max-width: min(100vw - 2 * var(--gutter), 1100px);
    margin-inline: auto;
}

/* --------------------------------------------------------------------------
   16. Page hero (pages internes)
   -------------------------------------------------------------------------- */

.page-hero {
    padding-block: clamp(4rem, 9vw, 7rem) clamp(2.5rem, 5vw, 4rem);
    border-bottom: 1px solid var(--cream-15);
}

.page-hero__title {
    font-size: clamp(2.5rem, 6vw, 4.5rem);
    max-width: 18ch;
    letter-spacing: -0.03em;
}

/* --------------------------------------------------------------------------
   Tarifs — /pricing/

   Le markup vit dans le CONTENU de la page, entre marqueurs kg-card : Anne doit
   pouvoir changer un prix sans commit. Sans ces marqueurs, Ghost re-parse le
   HTML à l'enregistrement et détruit les classes — la grille perdrait tout son
   style, silencieusement (cf. feedback_ghost-contenu).
   -------------------------------------------------------------------------- */

.pricing {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: 1px;
    background: var(--cream-15);
    border: 1px solid var(--cream-15);
    margin: 2.5rem 0;
    /* overflow: hidden est OBLIGATOIRE avec le rayon : les .pricing__item sont
       collés au gap de 1px et ressortiraient carrés dans les coins arrondis. */
    border-radius: var(--radius);
    overflow: hidden;
}

.pricing__item {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    padding: clamp(1.75rem, 3vw, 2.25rem);
    background: var(--black);
}

/* La formule mise en avant : un fond légèrement relevé, pas un badge criard */
.pricing__item--lead { background: var(--black-lift); }

.pricing__label {
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--cream-55);
    margin: 0;
}

.pricing__figure {
    font-family: var(--font-display);
    font-size: clamp(2rem, 3.4vw, 2.75rem);
    font-weight: 600;
    line-height: 1;
    letter-spacing: -0.02em;
}

.pricing__meta {
    font-size: 0.8125rem;
    color: var(--cream-55);
    margin: 0;
}

.pricing__text {
    font-size: 0.9375rem;
    line-height: 1.6;
    color: var(--cream-70);
    margin: 0;
}

/* --------------------------------------------------------------------------
   Calendly — /book/ uniquement, chargé au clic (voir global.js)
   -------------------------------------------------------------------------- */

.calendly__note {
    display: block;
    margin: 1rem 0 0;
    max-width: 46ch;
}

/* 🔴 L'IFRAME DOIT AVOIR UNE HAUTEUR EXPLICITE.

   Sans cette règle, l'iframe injectée par Calendly retombe sur les 150px par
   défaut du HTML — et le calendrier s'écrase dans un filet de 150px au milieu
   d'un conteneur de 1000px. C'est ce que voyait Jérémie le 17/07/2026 : « la
   fenêtre semble coupée ». Agrandir le conteneur n'y changeait rien, le problème
   n'était pas là.

   Pourquoi ça ne marche pas tout seul : le widget.css de Calendly pose bien
   `height: 100%`, mais sur `.calendly-inline-widget` — une classe que notre
   conteneur n'a pas, puisqu'on l'initialise par `parentElement` et non par
   `data-url`. On refait donc le travail nous-mêmes. */
.calendly.is-loaded iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
    border-radius: var(--radius);
}

/* La hauteur réelle est posée en inline par global.js, à l'écoute du message
   `calendly.page_height` que Calendly émet : le calendrier ne fait pas la même
   taille selon l'étape (choix de date, puis formulaire), donc aucun chiffre figé
   ne convient aux deux. Ce min-height n'est qu'un garde-fou pour la fraction de
   seconde qui précède le premier message — et pour le cas où il n'arriverait
   jamais.

   ⚠️ Ne pas descendre ce plancher : l'iframe Calendly NE DÉFILE PAS en interne
   (la molette au-dessus fait défiler la page). Trop court = la dernière semaine
   de dates et le sélecteur de fuseau sont inatteignables, sur la page dont c'est
   l'unique but. Voir knowledge/feedback_calendly-embed-height-throttle.md */
/* `height` explicite et PAS `min-height` seul : une hauteur en pourcentage sur
   l'enfant ne se résout que contre une hauteur définie du parent. Avec un
   min-height seul, la hauteur du parent reste `auto` et le `height: 100%` de
   l'iframe retombe... sur 150px. C'est-à-dire le bug qu'on vient de corriger. */
.calendly.is-loaded {
    height: 1000px;
    transition: height 0.25s ease;
}

/* Mobile : Calendly empile son calendrier, il lui faut davantage. */
@media (max-width: 640px) {
    .calendly.is-loaded { height: 1150px; }
}

/* Widget injoignable (bloqueur, réseau, throttle Calendly) : le repli redevient
   la voie principale plutôt qu'une note en petits caractères. */
.calendly.is-failed .calendly__note {
    font-size: 1rem;
    color: var(--cream);
}

/* Feature image d'une page — sous le hero, dans le flux du conteneur. */
.page-hero__media {
    margin: 0 0 clamp(2rem, 4vw, 3.5rem);
}
.page-hero__media img {
    width: 100%;
    object-fit: cover;
    border-radius: var(--radius);
}
.page-hero__media figcaption {
    margin-top: 0.875rem;
    font-size: 0.8125rem;
    color: var(--cream-55);
}

.breadcrumb {
    font-size: 0.8125rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--cream-55);
    margin-bottom: 1.5rem;
}
.breadcrumb a:hover { color: var(--red); }

/* Le titre de la page courante est du contenu : il hérite du --cream-55 de
   .breadcrumb (5.7:1). Seul le séparateur est décoratif — il est sorti de
   l'arbre d'accessibilité par aria-hidden, donc exempté du seuil de contraste. */
.breadcrumb__sep {
    color: var(--cream-15);
    margin-inline: 0.5rem;
}

/* --------------------------------------------------------------------------
   17. Utilitaires
   -------------------------------------------------------------------------- */

.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------------------
   18. Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
    .site-footer__top { grid-template-columns: 1fr 1fr; }
    .site-footer__brand { grid-column: 1 / -1; }
    .stat { border-right: 0; }
}

/* Bascule vers le burger. 1080px et non 768 depuis le 19/08/2026 : avec six
   entrées, la barre complète ne tient plus en dessous. Le seuil est aussi écrit
   dans global.js (fermeture du menu au redimensionnement) — les deux doivent
   bouger ensemble. */
@media (max-width: 1080px) {
    .nav, .site-header .btn--desktop { display: none; }
    .burger { display: flex; }
}

@media (max-width: 768px) {
    .hero__title { font-size: clamp(2.75rem, 12vw, 4rem); }
    /* Ce bloc vient APRÈS .hero__title--statement dans le fichier et a la même
       spécificité (une classe) : sans cette seconde règle, il l'écraserait et
       servirait la phrase de 200 caractères en 4rem sur mobile. */
    .hero__title--statement { font-size: clamp(1.5rem, 5.6vw, 2rem); }
    .btn-row { flex-direction: column; align-items: stretch; }
    .btn-row .btn { justify-content: center; }
    .btn-note { text-align: center; }
}

@media (max-width: 520px) {
    .site-footer__top { grid-template-columns: 1fr; }
    .quote { padding-inline: 1.25rem; }
}

/* --------------------------------------------------------------------------
   19. Accessibilité — respect strict de prefers-reduced-motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* Apparition au scroll — seulement si JS a posé la classe et si le mouvement est accepté */
@media (prefers-reduced-motion: no-preference) {
    .anim-ready .reveal {
        opacity: 0;
        transform: translateY(18px);
        transition: opacity 0.7s ease, transform 0.7s ease;
    }
    .anim-ready .reveal.is-visible {
        opacity: 1;
        transform: none;
    }
}

@media print {
    .site-header, .site-footer, .btn { display: none; }
    body { background: #fff; color: #000; }
}
