/* ==========================================================================
   Maître Michael Hadji, avocat — feuille de style
   Système : tokens → base → mouvement → composants → pages → impression
   Direction : la nuit du dossier. Noir dominant, rouge du code en signal.
   ========================================================================== */

/* ---------- Polices (auto-hébergées, aucun appel tiers) ---------- */
@font-face { font-family: "Spectral"; src: url("/assets/fonts/spectral-latin-300-normal.woff2") format("woff2"); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: "Spectral"; src: url("/assets/fonts/spectral-latin-400-normal.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Spectral"; src: url("/assets/fonts/spectral-latin-400-italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Spectral"; src: url("/assets/fonts/spectral-latin-600-normal.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Archivo"; src: url("/assets/fonts/archivo-latin-wght-normal.woff2") format("woff2"); font-weight: 100 900; font-style: normal; font-display: swap; }
/* Polices de repli calibrées pour limiter le décalage de mise en page au chargement */
@font-face { font-family: "Spectral Fallback"; src: local("Georgia"), local("Times New Roman"), local("DejaVu Serif"); size-adjust: 96%; ascent-override: 106%; descent-override: 46%; line-gap-override: 0%; }
@font-face { font-family: "Archivo Fallback"; src: local("Helvetica Neue"), local("Arial"), local("DejaVu Sans"); size-adjust: 98%; ascent-override: 88%; descent-override: 21%; line-gap-override: 0%; }

/* ---------- Tokens ---------- */
:root {
  /* Surfaces : du plus profond au plus élevé */
  --c-nuit: #08080a;
  --c-robe: #101014;
  --c-robe-2: #17171c;
  --c-robe-3: #1e1e24;

  /* Encres : ivoire plutôt que blanc pur, la lumière reste chaude */
  --c-rabat: #f4f3f0;      /* 18,0:1 sur la nuit */
  --c-craie-clair: #d6d5d0; /* 13,6:1 */
  --c-craie: #b4b3ae;       /* 9,5:1 */
  --c-plomb: #8a8984;       /* 5,7:1 — mentions secondaires uniquement */

  /* Le rouge du code. Trois valeurs, trois emplois, jamais interchangeables :
     --c-code       structure (aplats, coutures, fonds) — texte ivoire dessus : 8,2:1
     --c-code-vif   filets et soulignements sur noir — 3,4:1, au-dessus du seuil UI de 3:1
     --c-code-haut  petit texte rouge sur noir, en dernier recours — 4,8:1 */
  --c-code: #8c1c22;
  --c-code-fonce: #6e1419;
  --c-code-vif: #c0272f;
  --c-code-haut: #e04049;   /* petit texte rouge sur noir : 4,8:1 */
  --c-code-clair: #ea5f66;  /* idem, mais par-dessus un voile rouge : 5,4:1 */

  /* Filets */
  --c-filet: rgba(244, 243, 240, 0.12);
  --c-filet-fort: rgba(244, 243, 240, 0.28);   /* séparateurs décoratifs */
  --c-bord-ui: rgba(244, 243, 240, 0.40);      /* limite d'un contrôle : 3,5:1 sur la nuit */
  --c-filet-net: rgba(244, 243, 240, 0.55);
  --rule: 1px solid var(--c-filet);
  --rule-strong: 1px solid var(--c-filet-fort);

  --c-succes: #6fcf9a;

  /* Atmosphères : le rouge n'apparaît jamais en aplat plein, seulement en voile */
  --wash-code: radial-gradient(120% 90% at 8% 100%, rgba(140, 28, 34, 0.30) 0%, rgba(140, 28, 34, 0.08) 38%, transparent 70%);
  --wash-haut: radial-gradient(100% 70% at 92% 0%, rgba(140, 28, 34, 0.18) 0%, transparent 62%);
  --fondu-bas: linear-gradient(180deg, transparent 0%, var(--c-nuit) 100%);
  /* Grain : casse le banding des dégradés et donne la matière argentique. 1 fichier, 0 requête. */
  /* Une image posée sur du noir doit y entrer, pas s'y coller : ce voile fond ses bords. */

  /* Typographie */
  --f-serif: "Spectral", "Spectral Fallback", Georgia, "Times New Roman", serif;
  --f-sans: "Archivo", "Archivo Fallback", "Helvetica Neue", Arial, sans-serif;

  --t-chapter: clamp(2.75rem, 1rem + 8.5vw, 10rem);
  --t-display: clamp(2.25rem, 1.5rem + 2.6vw, 4.25rem);
  --t-h2: clamp(2rem, 1.35rem + 2.2vw, 3.5rem);
  --t-h2-prose: clamp(1.625rem, 1.35rem + 0.9vw, 2.25rem);
  --t-h3: clamp(1.25rem, 1.12rem + 0.45vw, 1.5rem);
  --t-lede: clamp(1.1875rem, 1.05rem + 0.45vw, 1.4375rem);
  --t-statement: clamp(1.625rem, 1.1rem + 2vw, 3.25rem);
  --t-body: 1.125rem;
  --t-body-s: 1.0625rem;
  --t-ui: 0.9375rem;
  --t-small: 0.875rem;
  --t-micro: 0.8125rem;
  --t-phone: clamp(2.5rem, 1rem + 5.5vw, 6.5rem);

  /* Espacement (échelle unique) */
  --s-1: 0.25rem; --s-2: 0.5rem; --s-3: 0.75rem; --s-4: 1rem; --s-5: 1.5rem;
  --s-6: 2rem; --s-7: 3rem; --s-8: 4rem; --s-9: 6rem; --s-10: 8rem; --s-11: 12rem;
  --section-y: clamp(5rem, 3rem + 7vw, 10rem);

  /* Mise en page */
  --w-max: 90rem;
  --w-prose: 40rem;
  --gutter: clamp(1.25rem, 5vw, 5rem);
  --header-h: 4.25rem;

  --radius: 0;
  --shadow-sheet: 0 -6px 24px rgba(0, 0, 0, 0.6);

  /* Mouvement */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-soft: cubic-bezier(0.33, 1, 0.68, 1);
  --ease-in: cubic-bezier(0.7, 0, 0.84, 0);
  --dur-1: 140ms;   /* micro-interaction */
  --dur-2: 260ms;   /* transition d'interface */
  --dur-3: 900ms;   /* révélation au défilement */
  --dur-4: 1400ms;  /* entrée de couverture */
  --lift: 1.75rem;  /* course des révélations, réduite sur petit écran */
  --opening-hold: 46svh; /* durée de maintien de la couverture, en écrans */

  /* Plans */
  --z-header: 20;
  --z-callbar: 30;
  --z-menu: 40;
  --z-skip: 50;

  color-scheme: dark;
}
@media (min-width: 75rem) { :root { --header-h: 4.75rem; } }
@media (max-width: 39.99rem) { :root { --lift: 1rem; } }
@media (min-width: 64rem) { :root { --opening-hold: 62svh; --statement-lead: 0.56; } }

/* Points de rupture : 40rem (640) · 64rem (1024) · 75rem (1200) · 90rem (1440) */

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + var(--s-5));
  scrollbar-color: var(--c-robe-3) var(--c-nuit);
  background: var(--c-nuit);
}
body {
  margin: 0;
  /* Pas de fond sur body : la nuit est peinte par html (le canevas). Un fond ici
     recouvrait les plans fixes en z-index négatif — l'atmosphère rouge et le sol
     clair — qui restaient donc invisibles. */
  color: var(--c-rabat);
  font-family: var(--f-serif);
  font-size: var(--t-body);
  line-height: 1.65;
  font-kerning: normal;
  font-variant-ligatures: common-ligatures;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}
img, picture, svg { display: block; max-width: 100%; }
h1, h2, h3, h4 { margin: 0; font-weight: 400; line-height: 1.12; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; }
dl, dd { margin: 0; }
address { font-style: normal; }
table { border-collapse: collapse; }
::selection { background: var(--c-code); color: var(--c-rabat); }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
a:hover { text-decoration-color: var(--c-code-vif); }
:focus-visible { outline: 2px solid var(--c-code-haut); outline-offset: 3px; }
main:focus { outline: none; }
[hidden] { display: none !important; }

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

.skip-link {
  position: absolute; left: var(--s-4); top: -10rem; z-index: var(--z-skip);
  background: var(--c-rabat); color: var(--c-nuit); padding: var(--s-3) var(--s-4);
  font: 600 var(--t-ui)/1 var(--f-sans); text-decoration: none;
}
.skip-link:focus { top: var(--s-4); }

.tel { white-space: nowrap; font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }

/* ==========================================================================
   Mouvement
   Trois mécanismes, trois rôles, aucun qui bloque la lecture :
   1. révélations   — IntersectionObserver → .is-in. Marche partout, JS ou non.
   2. défilement    — animation-timeline, sous @supports. Firefox voit l'état final.
   3. empilement    — position: sticky. Aucun script, aucune API récente.
   Rien n'anime jamais autre chose que transform, opacity et clip-path.
   ========================================================================== */

/* 1. Révélations. Sans JS, rien n'est masqué : .js conditionne l'état initial. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal] {
    opacity: 0;
    transform: translate3d(0, var(--lift), 0);
    transition: opacity var(--dur-3) var(--ease-out), transform var(--dur-3) var(--ease-out);
    transition-delay: var(--reveal-delay, 0ms);
  }
  /* Le volet se lève sur l'image, jamais sur le bloc observé : un élément
     découpé à zéro n'a plus de rectangle d'intersection, et ne serait jamais révélé. */
  .js [data-reveal="mask"] { opacity: 1; transform: none; transition: none; }
  .js [data-reveal="mask"] > .photo,
  .js [data-reveal="mask"] > .photo-slot {
    clip-path: inset(0 0 100% 0);
    transition: clip-path var(--dur-4) var(--ease-out);
    transition-delay: var(--reveal-delay, 0ms);
  }
  .js [data-reveal="mask"].is-in > .photo,
  .js [data-reveal="mask"].is-in > .photo-slot { clip-path: inset(0 0 0 0); }
  .js [data-reveal="rule"] {
    opacity: 1; transform: scaleX(0); transform-origin: left;
    transition: transform var(--dur-3) var(--ease-out);
    transition-delay: var(--reveal-delay, 0ms);
  }
  .js [data-reveal="rise"] { --lift: 3rem; }
  /* Enfants échelonnés : --i est posé par le script, 70 ms d'écart, plafonné. */
  .js [data-stagger] > * { --reveal-delay: calc(min(var(--i, 0), 10) * 70ms); }

  .js [data-reveal].is-in { opacity: 1; transform: none; clip-path: inset(0 0 0 0); }
}

/* 2. Défilement. Toujours dans @supports : la règle n'existe pas là où l'API manque. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Parallaxe : l'image dérive dans son cadre, jamais le cadre. */
    .parallax { overflow: hidden; }
    .parallax > .photo img {
      animation: derive linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
      will-change: transform;
    }
    @keyframes derive {
      from { transform: translate3d(0, -3.5%, 0) scale(1.09); }
      to   { transform: translate3d(0, 3.5%, 0) scale(1.09); }
    }
  }
}
@media (max-width: 39.99rem) {
  @keyframes derive {
    from { transform: translate3d(0, -2%, 0) scale(1.05); }
    to   { transform: translate3d(0, 2%, 0) scale(1.05); }
  }
}

/* 3. Tout se tait si le système le demande. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important; scroll-behavior: auto !important;
  }
  .js [data-reveal] { opacity: 1 !important; transform: none !important; clip-path: none !important; }
}

/* ---------- Éléments d'interface ---------- */
.btn {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: var(--s-4);
  min-height: 3.5rem; padding: var(--s-4) var(--s-5);
  border: 0; border-radius: var(--radius);
  font: 600 1rem/1.2 var(--f-sans); letter-spacing: 0.005em;
  text-decoration: none; cursor: pointer;
  transition: color var(--dur-2) var(--ease-out), transform var(--dur-1) var(--ease-out);
}
/* Le fond glisse depuis la gauche au survol, il ne clignote pas. */
.btn::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur-2) var(--ease-out);
}
.btn > * { position: relative; z-index: 1; }
/* L'appel n'est pas un aplat de couleur de marque : c'est un contour dans le
   noir. Le rouge n'y entre qu'au survol, comme une lueur derrière le verre. */
.btn--call {
  color: var(--c-rabat);
  background: rgba(110, 20, 25, 0.42);
  border: 1px solid rgba(234, 95, 102, 0.55);
}
@supports (backdrop-filter: blur(1px)) {
  .btn--call { -webkit-backdrop-filter: blur(14px) saturate(120%); backdrop-filter: blur(14px) saturate(120%); }
}
.btn--call::before {
  background: radial-gradient(130% 210% at 10% 130%, rgba(192, 39, 47, 0.6) 0%, rgba(140, 28, 34, 0.2) 56%, transparent 100%);
  transform: none; opacity: 0;
  transition: opacity var(--dur-2) var(--ease-out);
}
.btn--call:hover::before, .btn--call:focus-visible::before { opacity: 1; transform: none; }
.btn--call:hover, .btn--call:focus-visible { border-color: rgba(244, 243, 240, 0.72); }
@media (prefers-reduced-transparency: reduce) {
  .btn--call { background: var(--c-robe); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
.btn--ink { background: var(--c-rabat); color: var(--c-nuit); }
.btn--ink::before { background: var(--c-craie-clair); }
.btn--ink:hover::before, .btn--ink:focus-visible::before { transform: scaleX(1); }
.btn:active { transform: translateY(1px); }
.btn__number {
  font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 500;
  padding-left: var(--s-4); border-left: 1px solid currentColor;
}
.btn--call .btn__number { border-left-color: rgba(244, 243, 240, 0.3); color: var(--c-craie-clair); }
.btn--compact { min-height: 2.75rem; padding: var(--s-2) var(--s-4); font-size: var(--t-ui); }
.btn--block { display: flex; width: 100%; justify-content: space-between; }
.btn[aria-disabled="true"], .btn:disabled { opacity: 0.6; cursor: progress; }
.btn[aria-disabled="true"]::before, .btn:disabled::before { transform: scaleX(0); }

.link-strong {
  display: inline-block; margin-top: var(--s-6); padding-block: var(--s-2);
  font: 600 var(--t-ui)/1.4 var(--f-sans); color: var(--c-rabat);
  text-decoration: underline; text-decoration-color: var(--c-code-vif);
  text-decoration-thickness: 2px; text-underline-offset: 0.45em;
  transition: text-underline-offset var(--dur-2) var(--ease-out), color var(--dur-1);
}
.link-strong:hover { text-underline-offset: 0.28em; text-decoration-color: var(--c-code-haut); }
.link-strong--light { color: var(--c-rabat); }
.link-quiet {
  font: 500 var(--t-ui)/1.4 var(--f-sans); color: var(--c-craie-clair);
  text-underline-offset: 0.35em; padding-block: var(--s-3);
  transition: color var(--dur-1);
}
.link-quiet:hover { color: var(--c-rabat); }

/* Un mot de sens, souligné par le trait rouge qui se déploie au survol. */
.mot {
  position: relative; text-decoration: none; color: var(--c-rabat);
  background-image: linear-gradient(var(--c-code-vif), var(--c-code-vif));
  background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
  padding-bottom: 0.12em;
  transition: background-size var(--dur-2) var(--ease-out);
}
.mot:hover, .mot:focus-visible { background-size: 100% 1px; }

/* Adresse : elle est elle-même le lien vers la carte. Deux lignes, rien d'autre. */
.address {
  display: inline-grid; gap: 0.12em;
  color: inherit; text-decoration: none;
  transition: color var(--dur-1) var(--ease-out);
}
.address > span { display: block; }
.address > span:first-child {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
  padding-bottom: 0.15em;
  transition: background-size var(--dur-2) var(--ease-out);
}
.address:hover, .address:focus-visible { color: var(--c-rabat); }
.address:hover > span:first-child, .address:focus-visible > span:first-child { background-size: 100% 1px; }
.portrait__where { margin-top: var(--s-5); font: 400 var(--t-ui)/1.6 var(--f-sans); color: var(--c-craie); }

/* Données à confirmer par le client */
.tbc {
  font-family: var(--f-sans); font-weight: 600; font-size: max(0.82em, 0.8125rem); letter-spacing: 0.01em;
  color: #f2ccce; background: rgba(192, 39, 47, 0.18);
  box-shadow: inset 2px 0 0 var(--c-code-vif);
  padding: 0.12em 0.45em;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
.tbc-block { font-family: var(--f-sans); font-size: var(--t-ui); line-height: 1.55; color: var(--c-craie); }

/* Emplacement photo (tant que les photographies ne sont pas fournies) */
.photo-slot {
  position: relative; display: flex; align-items: flex-end;
  width: 100%; height: 100%; min-height: 12rem;
  background: var(--c-robe-2); color: var(--c-craie);
}
.photo-slot__note {
  display: block; max-width: 30ch; padding: var(--s-5);
  font: 400 var(--t-small)/1.5 var(--f-sans);
}
.photo-slot__note strong { display: block; color: var(--c-rabat); font-weight: 600; margin-bottom: var(--s-1); }
.hero__photo .photo-slot { align-items: flex-start; }
/* la photo remplit la zone sans imposer sa hauteur intrinsèque à la grille */
.photo, .photo img { width: 100%; height: 100%; }
/* Point focal : valeur de photos.json, surchargeable par contexte et par point de rupture. */
/* Le point focal : une règle CSS l'emporte sur la valeur de photos.json, qui ne
   sert que de défaut. C'est ce qui permet de recadrer par point de rupture. */
.photo img { object-fit: cover; object-position: var(--photo-pos, var(--photo-pos-src, 50% 50%)); }

/* Cadre d'image : un tirage net, partout. Plus de bords fondus ni de voile
   sombre — ils faisaient baver l'image dans la page (retour sept. 2026). */
.media-frame { position: relative; }

/* ---------- En-tête ---------- */
.site-header {
  position: sticky; top: 0; z-index: var(--z-header);
  background: color-mix(in srgb, var(--c-nuit) 82%, transparent);
  border-bottom: 1px solid transparent;
  transition: background-color var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out);
}
@supports (backdrop-filter: blur(1px)) {
  .site-header { backdrop-filter: blur(14px) saturate(1.2); -webkit-backdrop-filter: blur(14px) saturate(1.2); }
}
/* Décollé du haut : le fond se densifie et le filet apparaît. */
.site-header.is-stuck { background: color-mix(in srgb, var(--c-nuit) 97%, transparent); }
/* Lisière, pas bordure : le contenu s'efface sous l'en-tête au lieu d'être coupé. */
.site-header::after {
  content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 3rem; pointer-events: none;
  background: linear-gradient(180deg, rgba(8, 8, 10, 0.55), transparent);
  opacity: 0; transition: opacity var(--dur-2) var(--ease-out);
}
.site-header.is-stuck::after { opacity: 1; }
/* Témoin placé avant l'en-tête : dès qu'il sort du cadre, l'en-tête est décollé. */
.page-sentinel { display: block; height: 1px; margin-bottom: -1px; }
.scroll-progress { display: none; }
.site-header__inner {
  display: flex; align-items: center; gap: var(--s-6);
  max-width: var(--w-max); margin-inline: auto; min-height: var(--header-h);
  padding-inline: var(--gutter);
}
.wordmark { display: inline-flex; align-items: baseline; gap: var(--s-3); padding-block: var(--s-3); text-decoration: none; color: var(--c-rabat); margin-right: auto; }
.wordmark__name { font: 400 1.375rem/1 var(--f-serif); letter-spacing: -0.005em; }
/* « Avocat pénaliste » ne tient plus sur la ligne du nom en mobile : il passe
   dessous, en petit, au lieu de casser le nom sur deux lignes. */
.wordmark__name { white-space: nowrap; }
@media (max-width: 47.99rem) {
  .wordmark { flex-direction: column; align-items: flex-start; gap: 0.3rem; }
  .wordmark__role { font-size: 0.8125rem; }
}
.wordmark__role { font: 500 var(--t-small)/1 var(--f-sans); color: var(--c-plomb); }

.primary-nav { display: none; }
.primary-nav ul { display: flex; gap: var(--s-6); list-style: none; }
.primary-nav a {
  position: relative; display: block; padding-block: var(--s-3);
  font: 500 var(--t-ui)/1.2 var(--f-sans); color: var(--c-craie-clair); text-decoration: none;
  transition: color var(--dur-1);
}
.primary-nav a:hover { color: var(--c-rabat); }
.primary-nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--c-code-vif); transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur-2) var(--ease-out);
}
.primary-nav a:hover::after { transform: scaleX(1); }
.primary-nav a[aria-current="page"] { color: var(--c-rabat); }
.primary-nav a[aria-current="page"]::after { transform: scaleX(1); }

.header-phone { display: none; text-decoration: none; color: var(--c-rabat); line-height: 1.15; padding-left: var(--s-6); border-left: var(--rule); }
.header-phone__label { display: block; font: 500 0.8125rem/1.2 var(--f-sans); color: var(--c-plomb); }
.header-phone__number { display: block; font: 600 1.0625rem/1.3 var(--f-sans); font-variant-numeric: tabular-nums; white-space: nowrap; transition: color var(--dur-1); }
.header-phone:hover .header-phone__number { color: var(--c-code-haut); }

.header-mobile-actions { display: flex; align-items: center; gap: var(--s-2); }
.menu-toggle, .menu-fallback, .menu__close {
  min-height: 2.75rem; padding: var(--s-2) var(--s-3);
  background: transparent; border: 1px solid var(--c-bord-ui); border-radius: var(--radius);
  font: 600 var(--t-ui)/1 var(--f-sans); color: var(--c-rabat); text-decoration: none;
  display: inline-flex; align-items: center; cursor: pointer;
  transition: border-color var(--dur-1), color var(--dur-1);
}
.menu-toggle:hover, .menu__close:hover { border-color: var(--c-code-vif); }
.js .menu-fallback { display: none; }

@media (min-width: 75rem) {
  .primary-nav, .header-phone { display: block; }
  .header-mobile-actions { display: none; }
}

/* Menu mobile (dialog natif) */
.menu {
  width: 100%; max-width: none; height: 100%; max-height: none; margin: 0; padding: 0;
  border: 0; background: var(--c-nuit); color: var(--c-rabat);
  background-image: var(--wash-code);
}
.menu[open] { display: flex; flex-direction: column; }
.menu::backdrop { background: rgba(0, 0, 0, 0.7); }
.menu__top { display: flex; align-items: center; justify-content: space-between; min-height: var(--header-h); padding-inline: var(--gutter); border-bottom: var(--rule); }
.menu nav { flex: 1; overflow-y: auto; padding: var(--s-6) var(--gutter); }
.menu__list { list-style: none; }
.menu__list a {
  display: block; padding-block: var(--s-3);
  font: 300 clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem)/1.2 var(--f-serif); color: var(--c-rabat); text-decoration: none;
  transition: transform var(--dur-2) var(--ease-out), color var(--dur-1);
}
.menu__list a:hover { transform: translateX(0.4rem); }
.menu__list a[aria-current="page"] { color: var(--c-craie); }
.menu__foot { padding: var(--s-5) var(--gutter) calc(var(--s-5) + env(safe-area-inset-bottom)); border-top: var(--rule); }
.menu__address { margin-top: var(--s-3); font: 400 var(--t-small)/1.4 var(--f-sans); color: var(--c-plomb); }
@media (prefers-reduced-motion: no-preference) {
  .menu[open] { animation: sheet-in var(--dur-2) var(--ease-out); }
  @keyframes sheet-in { from { opacity: 0; transform: translateY(-0.75rem); } }
  .menu[open] .menu__list a { animation: menu-line 520ms var(--ease-out) both; animation-delay: calc(var(--i, 0) * 45ms + 60ms); }
  @keyframes menu-line { from { opacity: 0; transform: translateY(0.75rem); } }
}

/* ==========================================================================
   Accueil
   ========================================================================== */


/* ==========================================================================
   L'ATMOSPHÈRE — un seul plan lumineux pour tout le document

   Tant que chaque section portait son fond et son lavis, la lumière s'arrêtait
   à chaque couture et le défilement se lisait comme une pile de rectangles.
   Ici le plan est unique, fixe derrière le contenu, et dérive sur toute la
   hauteur du document. Les sections ne peignent plus rien : elles n'ont plus
   de bord à montrer.
   ========================================================================== */
body::before {
  content: ""; position: fixed; inset: -12% -8%; z-index: -1; pointer-events: none;
  background:
    radial-gradient(38% 30% at 82% 12%, rgba(140, 28, 34, 0.22) 0%, rgba(110, 20, 25, 0.07) 46%, transparent 72%),
    radial-gradient(46% 34% at 8% 46%,  rgba(140, 28, 34, 0.16) 0%, transparent 70%),
    radial-gradient(54% 36% at 92% 78%, rgba(140, 28, 34, 0.15) 0%, transparent 72%);
  will-change: transform;
}
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Une seule dérive, du premier au dernier pixel de la page : la lumière
       traverse le document au lieu de se rallumer à chaque section. */
    body::before {
      animation: atmosphere-derive linear both;
      animation-timeline: scroll(root block);
    }
    @keyframes atmosphere-derive {
      from { transform: translate3d(0, 0, 0) scale(1); }
      to   { transform: translate3d(-2.5%, -7%, 0) scale(1.1); }
    }
  }
}

/* ==========================================================================
   LA COUVERTURE — le nom tient lieu d'image

   Sans photographie, il ne reste que trois matières : la typographie, le vide et
   la lumière. Le nom occupe donc la place qu'occupait le portrait — deux lignes
   énormes, coupées par le bord gauche, dont le bord droit en dents de scie fait
   le dessin. À l'opposé, trois lignes minuscules tiennent le coin haut-droit :
   l'écart d'échelle remplace le contraste que l'image apportait.

   Le titre n'a pas de sur-titre. « Maître » chevauche la ligne du prénom, à sa
   taille de ligne de bas de page : un mot qui accompagne, pas une étiquette.
   ========================================================================== */
@property --braise   { syntax: "<number>";     inherits: true; initial-value: 1; }
@property --decouvre { syntax: "<percentage>"; inherits: false; initial-value: 170%; }

.opening { position: relative; }
.page-home .opening { min-height: calc(100svh + var(--opening-hold)); margin-top: calc(var(--header-h) * -1); }
.page-home .page-sentinel { height: 62svh; margin-bottom: -62svh; }
.page-home .site-header:not(.is-stuck) {
  background: transparent; border-bottom-color: transparent;
  -webkit-backdrop-filter: none; backdrop-filter: none;
}

/* Plafond d'échelle : « Michael » mesure environ 3,44 em. En bornant la taille
   par la largeur réellement disponible divisée par 3,5, aucune lettre ne peut
   être rognée par la boîte de découpe, à aucune largeur de fenêtre. */
:root {
  --t-mark-max: calc((min(100vw, var(--w-max)) - var(--gutter) * 2 - 3.5rem) / 3.6);
  --t-mark-haut: calc((100svh - 28rem) / 1.62);
}

.hero {
  position: sticky; top: 0;
  min-height: 100svh;
  display: grid; grid-template-columns: minmax(0, 1fr);
  overflow: hidden; isolation: isolate;
  --px: 0; --py: 0;
}

/* La braise du premier écran. Elle se pose sur l'atmosphère continue de la page
   sans la couper : même couleur, même nature, une intensité de plus. */
.hero__ember {
  grid-area: 1 / 1; position: relative; z-index: 0;
  margin: -6rem; pointer-events: none;
  --drift-x: 26px; --drift-y: 16px;
  background:
    radial-gradient(46% 42% at 74% 30%,
      rgba(140, 28, 34, calc(0.30 * var(--braise))) 0%,
      rgba(110, 20, 25, calc(0.11 * var(--braise))) 44%,
      transparent 74%),
    radial-gradient(70% 44% at 14% 102%,
      rgba(140, 28, 34, calc(0.15 * var(--braise))) 0%,
      transparent 66%);
}

/* Une seule mécanique de dérive, trois amplitudes, sens contraires. */
.hero__drift, .hero__ember {
  transform: translate3d(calc(var(--px) * var(--drift-x, 0px)), calc(var(--py) * var(--drift-y, 0px)), 0);
  transition: transform 760ms cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: transform;
}
.hero__drift--type { display: block; --drift-x: -9px; --drift-y: -6px; }

.hero__frame {
  grid-area: 1 / 1; position: relative; z-index: 2;
  display: grid; align-content: space-between;
  padding: calc(var(--header-h) + var(--s-6)) var(--gutter) calc(var(--s-6) + env(safe-area-inset-bottom));
  min-height: 100svh;
}
.hero__title { display: contents; color: var(--c-rabat); }

/* ---- le nom ---- */
.hero__name { display: block; }
.hero__line {
  display: block; overflow: clip;
  /* La boîte de découpe doit dépasser le bord gauche de la fenêtre : sinon elle
     tranche la première lettre au niveau de la gouttière au lieu de la laisser
     sortir du cadre. */
  /* La boîte de découpe déborde de part et d'autre : `overflow: clip` sert à
     retenir les lettres sous le couvercle pendant qu'elles montent, il ne doit
     pas rogner les jambages ni la marge optique. */
  margin-inline: calc(var(--t-mark) * -0.12);
  padding-inline: calc(var(--t-mark) * 0.12);
}
.hero__word {
  display: block; width: max-content; max-width: none;
  font-family: var(--f-serif); font-weight: 300; font-style: normal;
  font-size: var(--t-mark); line-height: 0.78; letter-spacing: -0.035em;
}
.hero__word > span { display: inline-block; }
/* « Maître » chevauche la ligne du prénom : il l'accompagne au lieu de la coiffer. */
.hero__maitre {
  font: 400 var(--t-micro)/1 var(--f-sans); font-style: normal;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--c-plomb);
  display: inline-block; vertical-align: baseline;
  margin-right: 0.13em; transform: translateY(-0.12em);
}
.hero__word { color: var(--c-craie-clair); }
.hero__line--last .hero__word { color: var(--c-rabat); }

.hero__role {
  display: block; overflow: clip;
  font: 400 clamp(1rem, 0.9rem + 0.4vw, 1.25rem)/1.4 var(--f-sans);
  letter-spacing: 0.02em; color: var(--c-craie);
}
.hero__role > span { display: block; }

/* ---- le contrepoids, minuscule, à l'opposé du nom ---- */
.hero__scope {
  font: 400 var(--t-ui)/1.75 var(--f-serif); color: var(--c-craie-clair);
  letter-spacing: 0.01em;
}
.hero__scope span { display: block; }

.hero__body { align-self: end; }
.hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3) var(--s-5); }
.hero__urgent { margin-top: var(--s-5); font: 500 var(--t-ui)/1.5 var(--f-sans); max-width: 34ch; }
.hero__urgent a {
  display: inline-flex; align-items: baseline; gap: var(--s-3);
  color: var(--c-craie-clair); text-decoration: none; padding-block: var(--s-2);
  transition: color var(--dur-1);
}
.hero__urgent a:hover { color: var(--c-rabat); }
.hero__urgent a span {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 100% 1px; background-repeat: no-repeat; background-position: 0 100%;
  padding-bottom: 0.15em; opacity: 0.55; transition: opacity var(--dur-2);
}
.hero__urgent a:hover span { opacity: 1; }

.hero__place { font: 400 var(--t-micro)/1.5 var(--f-sans); color: var(--c-plomb); letter-spacing: 0.04em; }
.hero__cue {
  overflow: clip;
  font: 500 var(--t-micro)/1.35 var(--f-sans); letter-spacing: 0.24em;
  text-transform: uppercase; color: var(--c-plomb);
}
.hero__cue > span { display: block; }

/* ---- téléphone ---- */
:root { --t-mark: min(clamp(3rem, 1rem + 19vw, 5.5rem), var(--t-mark-max), calc((100svh - 23rem) / 1.62)); }
.hero__frame { grid-template-rows: auto auto auto minmax(var(--s-6), 1fr) auto auto; row-gap: 0; }
.hero__name  { grid-row: 1; }
.hero__role  { grid-row: 2; margin-top: var(--s-5); }
.hero__scope { grid-row: 3; margin: var(--s-6) 0 0; }
.hero__body  { grid-row: 5; }
.hero__cue   { grid-row: 4; display: none; }
.hero__place { grid-row: 6; margin-top: var(--s-6); }
@media (max-width: 22.5rem) {
  .hero__actions .btn { width: 100%; justify-content: space-between; }
}
/* Sous 608 px de haut il n'y a plus la place de tout tenir : on retire le
   contrepoids et le lien d'urgence de la couverture. L'appel, lui, reste. */
@media (max-height: 38rem) {
  .hero__scope, .hero__urgent { display: none; }
}

/* ---- tablette ---- */
@media (min-width: 40rem) {
  :root { --t-mark: min(clamp(4.5rem, 1rem + 13vw, 8.5rem), var(--t-mark-max), calc((100svh - 24rem) / 1.62)); }
}

/* ---- grand écran ----
   Le nom tient les rangs 2 et 3 à gauche ; les trois lignes minuscules tiennent
   le coin haut-droit ; tout le reste s'aligne sur un seul rail, en bas. */
@media (min-width: 64rem) {
  :root { --t-mark: min(24vw, 21rem, var(--t-mark-max), var(--t-mark-haut)); }
  .hero__frame {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-rows: auto minmax(var(--s-5), 1fr) auto auto;
    align-content: stretch; column-gap: var(--s-6); row-gap: 0;
    padding-inline: var(--gutter);
    max-width: var(--w-max); margin-inline: auto; width: 100%;
  }
  .hero__scope { grid-column: 9 / span 4; grid-row: 1; justify-self: end; text-align: right; align-self: start;
                 margin: 0; font-size: clamp(0.9375rem, 0.85rem + 0.3vw, 1.0625rem); }
  .hero__name  { grid-column: 1 / span 12; grid-row: 2; align-self: center; }
  .hero__role  { grid-column: 1 / span 6; grid-row: 3; margin: var(--s-6) 0 0; }
  .hero__body  { grid-column: 1 / span 7; grid-row: 4; align-self: end; margin: var(--s-7) 0 0;
                 display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4) var(--s-6); }
  .hero__body .hero__urgent { margin: 0; }
  .hero__place { grid-column: 10 / span 3; grid-row: 4; align-self: end; justify-self: end; text-align: right; margin: 0; }
  .hero__cue   { display: block; grid-column: 8 / span 2; grid-row: 4; align-self: end; justify-self: center; margin: 0; }
}
@media (min-width: 90rem) {
  :root { --t-mark: min(22vw, 23rem, var(--t-mark-max), var(--t-mark-haut)); }
}

/* ==========================================================================
   L'OUVERTURE — anticipation, révélation, installation

   État 1  la fenêtre est noire, une braise à peine.
   État 2  le nom entre : chaque ligne glisse depuis le bord gauche pendant que
           ses lettres se lèvent une à une derrière le couvercle de leur ligne.
           Deux mouvements composés, douze lettres décalées.
   État 3  le contrepoids, le rôle, l'appel, l'adresse, puis la navigation.

   Rien de tout cela n'est nécessaire à la lecture.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  .page-home .hero__ember { animation: braise-monte 2600ms var(--ease-soft) both; }
  @keyframes braise-monte { from { --braise: 0; } 62% { --braise: 1.3; } to { --braise: 1; } }

  /* Le mot glisse depuis hors-cadre… */
  .page-home .hero__word { animation: mot-entre 1750ms 620ms var(--ease-out) both; }
  .page-home .hero__line--last .hero__word { animation-delay: 880ms; }
  @keyframes mot-entre { from { transform: translate3d(-0.26em, 0, 0); } to { transform: none; } }
  /* …et ses lettres se lèvent une à une derrière le couvercle de la ligne. */
  .page-home .hero__word > span,
  .page-home .hero__maitre {
    animation: lettre-se-leve 1250ms var(--ease-out) both;
    animation-delay: calc(700ms + var(--i, 0) * 74ms);
  }
  .page-home .hero__maitre { animation-delay: 620ms; }
  @keyframes lettre-se-leve { from { transform: translate3d(0, 116%, 0); } to { transform: none; } }

  .page-home .hero__role > span { animation: ligne-se-decouvre 1000ms 1820ms var(--ease-out) both; }
  .page-home .hero__cue > span  { animation: ligne-se-decouvre 1000ms 2320ms var(--ease-out) both; }
  @keyframes ligne-se-decouvre { from { transform: translate3d(0, 118%, 0); } to { transform: none; } }

  /* Le contrepoids et le rail bas se découvrent par un balayage descendant.
     En masque et non en clip-path : un clip-path annule le rectangle
     d'intersection et IntersectionObserver cesse alors de voir le bouton
     d'appel — la barre d'appel du bas se mettait à clignoter. */
  .page-home .hero__scope,
  .page-home .hero__body,
  .page-home .hero__place,
  .page-home .primary-nav,
  .page-home .header-phone,
  .page-home .header-mobile-actions {
    -webkit-mask-image: linear-gradient(180deg, #000 0, #000 var(--decouvre), transparent calc(var(--decouvre) + 24%));
    mask-image: linear-gradient(180deg, #000 0, #000 var(--decouvre), transparent calc(var(--decouvre) + 24%));
  }
  .page-home .hero__scope { animation: bloc-se-pose 1250ms 1600ms var(--ease-out) both; }
  .page-home .hero__body  { animation: bloc-se-pose 1250ms 1980ms var(--ease-out) both; }
  .page-home .hero__place { animation: bloc-se-pose 1250ms 2160ms var(--ease-out) both; }
  @keyframes bloc-se-pose {
    from { transform: translate3d(0, 1.5rem, 0); --decouvre: -24%; }
    to   { transform: none; --decouvre: 170%; }
  }
  .page-home .primary-nav,
  .page-home .header-phone,
  .page-home .header-mobile-actions { animation: bloc-se-pose 1000ms 2400ms var(--ease-out) both; }
}

/* ==========================================================================
   LE PREMIER DÉFILEMENT — un seul geste, cinq voix
   ========================================================================== */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {

    /* Le nom rétrécit vers l'angle et passe le relais à la signature d'en-tête. */
    .page-home .hero__name {
      animation: nom-devient-signature linear both;
      animation-timeline: scroll(root block);
      animation-range: 4svh 52svh;
      transform-origin: 0 0; will-change: transform;
    }
    @keyframes nom-devient-signature {
      from { opacity: 1; transform: none; }
      82%  { opacity: 0.85; }
      to   { opacity: 0; transform: translate3d(1.05rem, -26svh, 0) scale(0.115); }
    }
    .page-home .wordmark {
      animation: signature-prend-le-relais linear both;
      animation-timeline: scroll(root block);
      animation-range: 42svh 56svh;
    }
    @keyframes signature-prend-le-relais {
      from { opacity: 0; transform: translate3d(0, 0.3rem, 0); }
      to   { opacity: 1; transform: none; }
    }
    .page-home .wordmark:focus-visible { opacity: 1; transform: none; }

    /* La braise monte pendant le basculement, puis reflue. */
    .page-home .hero__ember {
      animation: braise-monte 2600ms var(--ease-soft) both,
                 braise-respire linear both;
      animation-timeline: auto, scroll(root block);
      animation-range: normal, 0 84svh;
    }
    @keyframes braise-respire { from { --braise: 1; } 45% { --braise: 1.5; } to { --braise: 0.3; } }

    /* Le petit texte se retire, chacun à son rythme : la couverture se vide par
       étages au lieu de disparaître d'un bloc. */
    .page-home .hero__role,
    .page-home .hero__cue {
      animation: couverture-se-retire linear both;
      animation-timeline: scroll(root block);
    }
    .page-home .hero__role { animation-range: 0 30svh; }
    .page-home .hero__cue  { animation-range: 0 16svh; }

    .page-home .hero__scope {
      animation: bloc-se-pose 1250ms 1600ms var(--ease-out) both, couverture-se-retire linear both;
      animation-timeline: auto, scroll(root block);
      animation-range: normal, 0 26svh;
    }
    .page-home .hero__body {
      animation: bloc-se-pose 1250ms 1980ms var(--ease-out) both, couverture-se-retire linear both;
      animation-timeline: auto, scroll(root block);
      animation-range: normal, 4svh 38svh;
    }
    .page-home .hero__place {
      animation: bloc-se-pose 1250ms 2160ms var(--ease-out) both, couverture-se-retire linear both;
      animation-timeline: auto, scroll(root block);
      animation-range: normal, 0 24svh;
    }
    @keyframes couverture-se-retire { to { opacity: 0; transform: translate3d(0, -2rem, 0); } }
  }
}

/* ---------- Déclaration ---------- */
/* La déclaration n'arrive pas après la couverture : elle monte dessus.
   Son fond part de la transparence — on voit le portrait derrière les premiers
   mots — puis devient noir avant que le texte n'y entre. Aucune animation
   n'est nécessaire pour que ce soit lisible : c'est le dégradé qui garantit le fond.
   DROIT PÉNAL prend exactement la place que le nom vient de quitter : c'est la
   même typographie, à une autre échelle et avec un autre rôle. */
.statement {
  position: relative; z-index: 2;
  margin-top: calc(var(--opening-hold, 0px) * -1);
  padding: calc(var(--opening-hold, 0px) * var(--statement-lead, 0.26) + var(--s-6)) var(--gutter) var(--section-y);
  /* Opaque juste le temps de recouvrir la couverture restée en sticky, puis
     elle se dissout : la section ne se referme pas sur une arête, elle rend la
     main au plan lumineux du document. */
  background: linear-gradient(180deg,
    rgba(8, 8, 10, 0) 0%,
    rgba(8, 8, 10, 0.72) 18%,
    var(--c-nuit) 38%,
    var(--c-nuit) 62%,
    rgba(8, 8, 10, 0.55) 84%,
    rgba(8, 8, 10, 0) 100%);
}
.statement > * { max-width: var(--w-max); margin-inline: auto; width: 100%; }

.statement__mark {
  margin: 0 0 var(--s-7);
  font-family: var(--f-serif); font-weight: 300;
  font-size: var(--t-chapter); line-height: 0.82; letter-spacing: -0.04em;
  color: var(--c-rabat);
}
.statement__line { display: block; overflow: clip; }
.statement__line > span { display: block; }
.statement__line:last-child > span { color: var(--c-craie); }

.statement__text {
  font: 300 var(--t-statement)/1.18 var(--f-serif); letter-spacing: -0.02em; max-width: 20ch;
}
.statement__text em { font-style: normal; color: var(--c-craie); }
.statement__aside { margin-top: var(--s-7); font: 400 var(--t-ui)/1.6 var(--f-sans); color: var(--c-craie); max-width: 42ch; }
@media (min-width: 64rem) {
  .statement__inner {
    display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--s-6); align-items: end;
  }
  .statement__mark  { grid-column: 1 / span 6; grid-row: 1 / span 2; margin-bottom: 0; align-self: start; }
  .statement__text  { grid-column: 8 / span 5; grid-row: 1; align-self: end; max-width: 15ch;
                      font-size: clamp(1.5rem, 0.95rem + 1.3vw, 2.25rem); }
  .statement__aside { grid-column: 8 / span 4; grid-row: 2; align-self: end; margin-top: var(--s-6); }
  .statement { padding-bottom: calc(var(--section-y) * 0.7); }
}

/* Le relais. Les deux mots montent derrière le bord de leur ligne pendant que
   le nom s'en va : un seul geste, deux typographies. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .page-home .statement__line > span {
      animation: word-rises linear both;
      animation-timeline: scroll(root block);
      will-change: transform;
    }
    .page-home .statement__line:first-child > span  { animation-range: 26svh 62svh; }
    .page-home .statement__line:last-child  > span  { animation-range: 34svh 72svh; }
    @keyframes word-rises {
      from { transform: translate3d(0, 105%, 0); }
      to   { transform: none; }
    }
  }
}

/* ---------- Chapitres : les quatre temps de la procédure ----------
   Quatre panneaux empilés en sticky. L'effet tient sans JavaScript et sans
   animation-timeline : c'est position: sticky qui fait le travail. Les
   enrichissements au défilement ne sont que du confort. */
.chapters { position: relative; }
/* Les quatre temps ne sont plus des panneaux qui glissent l'un sur l'autre :
   c'était le geste qui donnait le plus fortement l'impression d'une pile de
   carrés, puisque chaque panneau devait être opaque pour masquer le précédent.
   Ils défilent maintenant dans le flux, sans fond : on traverse une seule nuit
   continue où les mots arrivent et repartent, et où la lumière du document
   passe derrière eux sans jamais rencontrer de bord. */
.chapter {
  position: relative;
  min-height: 64svh; display: grid; align-content: center;
  padding: calc(var(--header-h) + var(--s-7)) var(--gutter) var(--s-8);
}
.chapter > * { position: relative; z-index: 1; }
.chapter__index {
  font: 600 var(--t-micro)/1 var(--f-sans); letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--c-code-clair);
}
.chapter__index b, .chapter__index strong { font-weight: 600; color: var(--c-craie-clair); }
.chapter__word {
  margin-top: var(--s-5);
  font: 300 var(--t-chapter)/0.88 var(--f-serif);
  letter-spacing: -0.035em; text-wrap: nowrap;
}
.chapter__word span { display: block; }
.chapter__note {
  margin-top: var(--s-6); max-width: 30ch;
  font: 400 var(--t-lede)/1.4 var(--f-serif); color: var(--c-craie-clair);
}
.chapter__link { margin-top: var(--s-6); }
@media (min-width: 64rem) {
  .chapter { padding-inline: calc(var(--gutter) * 1.5); }
  /* Le mot partage sa ligne avec la note : sa taille est plafonnée par la largeur
     réellement disponible, sinon « Instruction » déborde de sa colonne entre 1024 et 1440 px. */
  .chapter__word { margin-top: var(--s-6); font-size: min(var(--t-chapter), 8.6vw); }
  .chapter__note { font-size: clamp(1.125rem, 0.95rem + 0.6vw, 1.5rem); max-width: 28ch; }
  /* Sur grand écran la note s'installe à droite du mot, pas sous lui. */
  .chapter__body { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--s-6); align-items: end; }
  .chapter__word { grid-column: 1 / span 7; }
  .chapter__side { grid-column: 9 / span 4; padding-bottom: 0.6rem; }
  .chapter__note { margin-top: 0; }
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Une seule enveloppe : le contenu se lève en entrant, se retire en sortant.
       Les deux bouts sont dans la même animation, donc il n'y a pas de rupture
       entre « le mot est arrivé » et « le mot s'en va ». */
    .chapter > * {
      animation: chapitre-traverse linear both;
      animation-timeline: view();
      animation-range: entry 6% exit 94%;
      will-change: transform;
    }
    /* Le plateau occupe l'essentiel de la course : le mot est lisible presque
       tout le temps où il est à l'écran, et ne se dérobe qu'au tout dernier
       moment — sinon la transition se lit comme un clignotement. */
    @keyframes chapitre-traverse {
      from { opacity: 0; transform: translate3d(0, 2.75rem, 0); }
      15%  { opacity: 1; transform: none; }
      85%  { opacity: 1; transform: none; }
      to   { opacity: 0; transform: translate3d(0, -2.25rem, 0); }
    }
  }
}

/* ---------- Où en êtes-vous ---------- */
.situations { position: relative; }
.situations__inner {
  max-width: var(--w-max); margin-inline: auto;
  padding: var(--section-y) var(--gutter);
  display: grid; gap: var(--s-7);
}
.situations__title { font: 300 var(--t-h2)/1.08 var(--f-serif); letter-spacing: -0.015em; }
.situations__intro p { margin-top: var(--s-5); font-size: var(--t-body-s); color: var(--c-craie); max-width: 34ch; }
.situations__call { font-family: var(--f-sans); font-size: var(--t-ui) !important; font-weight: 500; }
.situations__call a { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--c-rabat); text-decoration-color: var(--c-code-vif); text-decoration-thickness: 2px; text-underline-offset: 0.3em; }
.situations__list { list-style: none; border-top: 1px solid var(--c-filet-net); }
.situation { border-bottom: var(--rule); }
.situation summary {
  display: grid; grid-template-columns: minmax(0, 1fr) 2.75rem; grid-template-areas: "title toggle" "stage toggle";
  column-gap: var(--s-4); row-gap: var(--s-1);
  padding-block: var(--s-5); cursor: pointer; list-style: none;
  transition: padding-left var(--dur-2) var(--ease-out);
}
.situation summary::-webkit-details-marker { display: none; }
.situation__stage { grid-area: stage; font: 500 var(--t-small)/1.3 var(--f-sans); color: var(--c-plomb); transition: color var(--dur-1); }
.situation__title { grid-area: title; font: 400 var(--t-h3)/1.3 var(--f-serif); color: var(--c-craie-clair); transition: color var(--dur-1); }
.situation__toggle {
  grid-area: toggle; align-self: center; justify-self: end; position: relative;
  width: 2.75rem; height: 2.75rem;
}
.situation__toggle::before, .situation__toggle::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 1.125rem; height: 1.5px;
  background: var(--c-craie); transform: translate(-50%, -50%);
  transition: transform var(--dur-2) var(--ease-out), background-color var(--dur-1);
}
.situation__toggle::after { transform: translate(-50%, -50%) rotate(90deg); }
.situation summary:hover .situation__title { color: var(--c-rabat); }
.situation summary:hover .situation__stage { color: var(--c-code-haut); }
.situation summary:hover .situation__toggle::before,
.situation summary:hover .situation__toggle::after { background: var(--c-code-haut); }
.situation details[open] .situation__title { color: var(--c-rabat); }
.situation details[open] .situation__toggle::before,
.situation details[open] .situation__toggle::after { background: var(--c-code-haut); height: 2px; }
.situation details[open] .situation__toggle::after { transform: translate(-50%, -50%) rotate(0deg); }
.situation__body { padding-bottom: var(--s-6); max-width: 60ch; }
.situation__body p { font-size: var(--t-body-s); line-height: 1.65; color: var(--c-craie); }
.situation__body a {
  display: inline-block; margin-top: var(--s-4);
  font: 600 var(--t-ui)/1.4 var(--f-sans); color: var(--c-rabat);
  text-decoration-color: var(--c-code-vif); text-decoration-thickness: 2px; text-underline-offset: 0.35em;
}
@media (min-width: 40rem) {
  .situation summary { grid-template-columns: 8.5rem minmax(0, 1fr) 2.75rem; grid-template-areas: "stage title toggle"; column-gap: var(--s-5); align-items: start; }
  .situation__stage { padding-top: 0.3rem; }
  .situation__body { padding-left: calc(8.5rem + var(--s-5)); padding-right: 4rem; max-width: none; }
  .situation__body p { max-width: 60ch; }
  .situation summary:hover { padding-left: var(--s-3); }
}
@media (min-width: 64rem) {
  .situations__inner { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--s-6); }
  .situations__intro { grid-column: 1 / span 4; align-self: start; position: sticky; top: calc(var(--header-h) + var(--s-6)); }
  .situations__list { grid-column: 6 / span 7; }
}
@supports (interpolate-size: allow-keywords) {
  @media (prefers-reduced-motion: no-preference) {
    .situation details { interpolate-size: allow-keywords; }
    .situation details::details-content {
      block-size: 0; overflow: clip; opacity: 0;
      transition: block-size var(--dur-2) var(--ease-out), opacity var(--dur-2) var(--ease-out), content-visibility var(--dur-2) allow-discrete;
    }
    .situation details[open]::details-content { block-size: auto; opacity: 1; }
  }
}


/* ==========================================================================
   LES SECTIONS CLAIRES — là où l'on voit son visage

   Retour client (sept. 2026) : les passages nuit → ivoire se lisaient comme des
   bandes grises qui défilent. Un dégradé spatial reste une bande, quelle que
   soit sa courbe : on la voit monter dans l'écran.

   Le passage se fait donc dans le temps, pas dans l'espace. Un seul plan clair,
   fixe, couvre toute la fenêtre derrière le contenu ; site.js règle son
   opacité d'après la position des sections claires. C'est la page entière qui
   passe de la nuit au jour pendant qu'une marge vide traverse l'écran — il n'y
   a plus de ligne de partage à voir.

   L'encre suit le sol. Elle bascule quand le sol est à mi-course (entre 45 et
   55 %), sur quelques dizaines de pixels de défilement : un texte clair ne se
   retrouve jamais sur un sol clair, ni un texte sombre sur la nuit. Contraste
   mesuré aux deux bornes de la bascule : 4,9:1 et 5,6:1.

   Sans JavaScript, le fondu spatial d'origine reste en place (plus bas).
   ========================================================================== */
/* La marge doit rester vide pendant tout le changement de sol : au moins un
   tiers d'écran, aussi en mobile. */
.section-claire {
  --pont: max(clamp(10rem, 22vw, 24rem), 32svh);
  position: relative; isolation: isolate;
}
/* Double classe : le raccourci `padding` des sections .feature et .portrait,
   déclaré plus bas, écrasait sinon ces valeurs. La marge est l'endroit où le
   sol change : il faut qu'elle soit vide. */
.section-claire.feature,
.section-claire.portrait {
  padding-top: calc(var(--section-y) + var(--pont));
  padding-bottom: calc(var(--section-y) + var(--pont));
}
.section-claire ::selection { background: var(--c-code); color: #f4f3f0; }
.section-claire :focus-visible { outline-color: var(--c-code); }
/* Pas de filtre sur les photos claires : il décalerait le fond « papier » du
   portrait debout par rapport à l'ivoire de la page. */

/* Les sols. Au-dessus de l'atmosphère (même plan, plus loin dans l'ordre du
   document), sous tout le contenu. L'ivoire pour les sections où l'on voit son
   visage, le bordeaux pour l'appel — qui ne repasse plus à la nuit : la page
   finit sur le rouge, pied de page compris. */
.sol { display: none; }
html.js-sol .sol {
  display: block; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  opacity: 0; will-change: opacity;
}
html.js-sol .sol--ivoire { background: #f4f3f0; }
/* Le haut du plan est exactement #4a0d12 : c'est la couleur que prend l'en-tête. */
html.js-sol .sol--bordeaux { background: radial-gradient(95% 72% at 24% 78%, #761820 0%, #5c1118 52%, #4a0d12 100%); }
/* L'encre, interpolée par --encre (0 = nuit, 1 = jour). site.js n'écrit la
   variable que pendant la bascule : le reste du temps, rien n'est recalculé. */
html.js-sol {
  --encre: 0;
  --c-rabat:       color-mix(in oklab, #f4f3f0, #111114 calc(var(--encre) * 100%));
  --c-craie-clair: color-mix(in oklab, #d6d5d0, #2c2b28 calc(var(--encre) * 100%));
  --c-craie:       color-mix(in oklab, #b4b3ae, #4d4c48 calc(var(--encre) * 100%));
  --c-plomb:       color-mix(in oklab, #8a8984, #5c5b56 calc(var(--encre) * 100%));
  --c-filet:       color-mix(in srgb, rgba(244, 243, 240, 0.12), rgba(17, 17, 20, 0.14) calc(var(--encre) * 100%));
  --c-filet-fort:  color-mix(in srgb, rgba(244, 243, 240, 0.28), rgba(17, 17, 20, 0.28) calc(var(--encre) * 100%));
  --c-filet-net:   color-mix(in srgb, rgba(244, 243, 240, 0.55), rgba(17, 17, 20, 0.45) calc(var(--encre) * 100%));
  --c-bord-ui:     color-mix(in srgb, rgba(244, 243, 240, 0.40), rgba(17, 17, 20, 0.45) calc(var(--encre) * 100%));
  /* rouge de petit texte : #e04049 sur la nuit (4,8:1), #a3202a sur l'ivoire (6,6:1) */
  --c-code-haut:   color-mix(in oklab, #e04049, #a3202a calc(var(--encre) * 100%));
}
/* L'en-tête prend la couleur du sol au lieu de rester une barre noire posée sur
   l'ivoire. --sol-c est écrit par site.js sur l'en-tête seul. */
html.js-sol .site-header {
  --sol-c: #08080a;
  background: color-mix(in srgb, var(--sol-c) 82%, transparent);
  transition: border-color var(--dur-2) var(--ease-out);
}
html.js-sol .site-header.is-stuck { background: color-mix(in srgb, var(--sol-c) 97%, transparent); }
html.js-sol .site-header::after { background: linear-gradient(180deg, color-mix(in srgb, var(--sol-c) 55%, transparent), transparent); }
html.js-sol .page-home .site-header:not(.is-stuck) { background: transparent; }
/* Les surfaces qui portent leur propre fond sombre gardent l'encre claire,
   quel que soit le sol derrière elles. */
html.js-sol .menu, html.js-sol .callbar {
  --c-rabat: #f4f3f0; --c-craie-clair: #d6d5d0; --c-code-haut: #e04049;
  --c-filet-net: rgba(244, 243, 240, 0.55); --c-bord-ui: rgba(244, 243, 240, 0.40);
}
html.js-sol .menu, html.js-sol .callbar { --c-craie: #b4b3ae; --c-plomb: #8a8984; --c-filet: rgba(244, 243, 240, 0.12); --rule: 1px solid rgba(244, 243, 240, 0.12); }

/* Sur le sol bordeaux, les gris secondaires reprennent ceux du bandeau
   d'appel : le #8a8984 de la nuit ne tiendrait que 3,5:1 sur le rouge.
   site.js pose .sol-bordeaux quand ce sol dépasse la moitié de son opacité. */
html.js-sol.sol-bordeaux {
  --c-plomb: rgba(244, 243, 240, 0.74);
  --c-craie: #e6d9d9;
  --c-filet: rgba(244, 243, 240, 0.22);
  /* rouge de focus et de survol : #e04049 tomberait à 2,6:1 sur le bordeaux */
  --c-code-haut: #f4a0a4;
}

/* --- Repli sans JavaScript : le fondu spatial, sur une courbe douce --- */
/* Sans script, l'en-tête ne se décolle jamais : il garde son fond de nuit,
   sinon ses liens clairs disparaîtraient au-dessus des sections ivoire. */
html:not(.js) .page-home .site-header:not(.is-stuck) { background: color-mix(in srgb, var(--c-nuit) 97%, transparent); }
html:not(.js-sol) .section-claire {
  --c-ivoire: #f4f3f0;
  --c-rabat: #111114;
  --c-craie-clair: #2c2b28;
  --c-craie: #4d4c48;
  --c-plomb: #5c5b56;
  --c-filet: rgba(17, 17, 20, 0.14);
  --c-filet-net: rgba(17, 17, 20, 0.45);
  --c-bord-ui: rgba(17, 17, 20, 0.45);
  --c-code-haut: #a3202a;
  --rule: 1px solid rgba(17, 17, 20, 0.14);
  color: var(--c-rabat);
}
html:not(.js-sol) .section-claire::after {
  content: ""; position: absolute; z-index: -2; pointer-events: none;
  top: 0; bottom: 0; left: calc(50% - 50vw); right: calc(50% - 50vw);
  background: linear-gradient(180deg,
    rgba(244, 243, 240, 0) calc(var(--pont) * 0),
    rgba(244, 243, 240, 0.02) calc(var(--pont) * 0.18),
    rgba(244, 243, 240, 0.07) calc(var(--pont) * 0.34),
    rgba(244, 243, 240, 0.16) calc(var(--pont) * 0.48),
    rgba(244, 243, 240, 0.3) calc(var(--pont) * 0.6),
    rgba(244, 243, 240, 0.47) calc(var(--pont) * 0.71),
    rgba(244, 243, 240, 0.64) calc(var(--pont) * 0.8),
    rgba(244, 243, 240, 0.8) calc(var(--pont) * 0.88),
    rgba(244, 243, 240, 0.93) calc(var(--pont) * 0.95),
    rgba(244, 243, 240, 1) calc(var(--pont) * 1),
    rgba(244, 243, 240, 1) calc(100% - var(--pont) * 1),
    rgba(244, 243, 240, 0.93) calc(100% - var(--pont) * 0.95),
    rgba(244, 243, 240, 0.8) calc(100% - var(--pont) * 0.88),
    rgba(244, 243, 240, 0.64) calc(100% - var(--pont) * 0.8),
    rgba(244, 243, 240, 0.47) calc(100% - var(--pont) * 0.71),
    rgba(244, 243, 240, 0.3) calc(100% - var(--pont) * 0.6),
    rgba(244, 243, 240, 0.16) calc(100% - var(--pont) * 0.48),
    rgba(244, 243, 240, 0.07) calc(100% - var(--pont) * 0.34),
    rgba(244, 243, 240, 0.02) calc(100% - var(--pont) * 0.18),
    rgba(244, 243, 240, 0) calc(100% - var(--pont) * 0));
}

/* ---------- Dossiers criminels — le troisième temps fort ----------
   Le portrait n'est pas posé : son ouverture est pilotée par le défilement.
   Quand la section entre dans le cadre, une fente verticale au milieu de
   l'image s'élargit jusqu'à la découvrir entière, pendant que les deux mots
   arrivent de directions opposées — l'un depuis la nuit à gauche, l'autre
   depuis le bord droit. La braise monte derrière, puis reflue.
   ------------------------------------------------------------------- */
@property --ouverture { syntax: "<percentage>"; inherits: true; initial-value: 50%; }

.feature {
  --bleed: var(--gutter);
  position: relative; isolation: isolate;
  max-width: var(--w-max); margin-inline: auto;
  padding: var(--section-y) var(--gutter);
  display: grid; gap: var(--s-7);
}
@media (min-width: 90rem) { .feature { --bleed: calc((100vw - var(--w-max)) / 2 + var(--gutter)); } }


.feature__media {
  position: relative;
  aspect-ratio: 4 / 5; max-height: 70svh; overflow: hidden; background: transparent;
  --photo-pos: 53% 30%;
  margin-left: calc(var(--bleed) * -1); margin-right: calc(var(--gutter) * -0.5);
  /* Sur l'ivoire, la photographie est un tirage : un rectangle net, à fond
     perdu à gauche. Les bords fondus qui la dissolvaient dans la nuit
     laissaient ici un halo gris sale — le fond sombre du bureau qui se
     délave dans le papier. La seule découpe restante est l'ouverture :
     deux bords francs qui s'écartent depuis l'axe du visage, pilotés par
     --ouverture (50 % au repos : l'image entière). */
  -webkit-mask-image: linear-gradient(90deg, transparent calc(50% - var(--ouverture)), #000 calc(50% - var(--ouverture)), #000 calc(50% + var(--ouverture)), transparent calc(50% + var(--ouverture)));
  mask-image: linear-gradient(90deg, transparent calc(50% - var(--ouverture)), #000 calc(50% - var(--ouverture)), #000 calc(50% + var(--ouverture)), transparent calc(50% + var(--ouverture)));
}
.feature__media::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: none;
}

.feature__title {
  font-family: var(--f-serif); font-weight: 300;
  font-size: min(var(--t-chapter), 12vw); line-height: 0.88; letter-spacing: -0.035em;
  color: var(--c-rabat);
}
.feature__line { display: block; overflow: clip; }
.feature__line > span { display: block; transition: transform 1100ms var(--ease-out); }
.feature__line:last-child > span { color: var(--c-craie); transition-delay: 150ms; }
/* Les deux mots n'entrent pas du même côté : le premier monte depuis la nuit,
   le second arrive par la droite. Sans JavaScript, ils sont simplement là. */
.js .feature__title:not(.is-in) .feature__line:first-child > span { transform: translate3d(0, 106%, 0); }
.js .feature__title:not(.is-in) .feature__line:last-child  > span { transform: translate3d(42%, 106%, 0); }

.feature__lede { margin-top: var(--s-6); font: 400 var(--t-lede)/1.5 var(--f-serif); color: var(--c-craie-clair); max-width: 28ch; }
.terms { margin-top: var(--s-7); border-top: 1px solid var(--c-filet-net); }
.terms__row { display: grid; gap: var(--s-2); padding-block: var(--s-5); border-bottom: var(--rule); transition: background-color var(--dur-2); }
.terms__row:hover { background: rgba(244, 243, 240, 0.03); }
.terms dt { font: 600 var(--t-ui)/1.4 var(--f-sans); color: var(--c-rabat); }
.terms dd { font-size: var(--t-body-s); line-height: 1.6; color: var(--c-craie); max-width: 52ch; }
@media (min-width: 40rem) {
  .terms__row { grid-template-columns: 11rem minmax(0, 1fr); gap: var(--s-5); }
  .terms dt { padding-top: 0.15rem; }
}
@media (min-width: 64rem) {
  .feature { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--s-6); align-items: start; }
  .feature__media {
    grid-column: 1 / span 6; grid-row: 1;
    aspect-ratio: auto; height: calc(100svh - var(--header-h) - var(--s-7));
    max-height: none; margin-right: 0;
    position: sticky; top: calc(var(--header-h) + var(--s-5));
    --photo-pos: 53% 32%;
  }
  /* L'image est désormais un tirage net : le texte ne la chevauche plus, il
     commence une colonne après son bord. */
  .feature__text { grid-column: 8 / span 5; grid-row: 1; position: relative; z-index: 1; padding-top: var(--s-9); }
  .feature__lede { font-size: clamp(1.375rem, 1rem + 1vw, 1.875rem); }
}
@media (min-width: 90rem) { .feature__title { font-size: min(var(--t-chapter), 10vw); } }
@media (prefers-reduced-motion: reduce) {
  .js .feature__title:not(.is-in) .feature__line > span { transform: none; }
}

/* La fente s'ouvre au défilement. Pilotée par view() : c'est l'entrée de la
   section dans le cadre qui fait l'ouverture, pas une minuterie. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .feature__media {
      animation: fente-souvre linear both;
      animation-timeline: view();
      animation-range: entry 4% cover 42%;
    }
    @keyframes fente-souvre { from { --ouverture: 4%; } to { --ouverture: 50%; } }

    .feature::before {
      animation: braise-passe linear both;
      animation-timeline: view();
      animation-range: entry 10% exit 40%;
    }
    @keyframes braise-passe { from { --braise: 0.2; } 50% { --braise: 1.25; } to { --braise: 0.25; } }

    /* Le cadrage se resserre très lentement pendant toute la traversée. */
    .feature__media .photo img {
      animation: dossier-se-resserre linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
      transform-origin: 53% 35%; will-change: transform;
    }
    /* 4 % au plus : au-delà, on agrandit des pixels que la source n'a pas. */
    @keyframes dossier-se-resserre { from { transform: scale(1.04); } to { transform: scale(1); } }
  }
}

/* ---------- Dossiers correctionnels (rôle d'audience) ---------- */
.docket { position: relative; }
.docket__inner {
  max-width: var(--w-max); margin-inline: auto;
  padding: var(--section-y) var(--gutter);
  display: grid; gap: var(--s-7);
}
.docket__title { font: 300 var(--t-h2)/1.05 var(--f-serif); letter-spacing: -0.015em; }
.docket__head p { margin-top: var(--s-5); font-size: var(--t-body-s); color: var(--c-craie); max-width: 34ch; }
.docket__table { width: 100%; }
.docket__table thead th {
  text-align: left; padding: 0 var(--s-5) var(--s-3) 0;
  font: 500 var(--t-small)/1.3 var(--f-sans); color: var(--c-plomb);
  border-bottom: 1px solid var(--c-filet-net);
}
.docket__table tbody tr { border-bottom: var(--rule); transition: background-color var(--dur-2); }
.docket__table tbody tr:hover { background: rgba(244, 243, 240, 0.03); }
.docket__table tbody th {
  text-align: left; vertical-align: top; width: 40%;
  padding: var(--s-5) var(--s-6) var(--s-5) 0;
  font: 400 var(--t-h3)/1.3 var(--f-serif); color: var(--c-rabat);
}
.docket__table td { vertical-align: top; padding: var(--s-5) 0; font-size: var(--t-body-s); line-height: 1.6; color: var(--c-craie); }
@media (max-width: 39.99rem) {
  .docket__table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .docket__table, .docket__table tbody, .docket__table tr, .docket__table th, .docket__table td { display: block; width: 100%; }
  .docket__table tbody tr:first-child { border-top: 1px solid var(--c-filet-net); }
  .docket__table tbody th { width: 100%; padding: var(--s-5) 0 var(--s-2); }
  .docket__table td { padding: 0 0 var(--s-5); }
}
@media (min-width: 64rem) {
  .docket__inner { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--s-6); }
  .docket__head { grid-column: 1 / span 4; }
  .docket__table { grid-column: 6 / span 7; }
}

/* ---------- Méthode ---------- */
.method__inner { max-width: var(--w-max); margin-inline: auto; padding: var(--section-y) var(--gutter); }
.method__title { font: 300 var(--t-h2)/1.05 var(--f-serif); letter-spacing: -0.015em; max-width: 14ch; }
.method__list { list-style: none; counter-reset: step; display: grid; gap: var(--s-7) var(--s-6); margin-top: var(--s-8); }
.method__step { counter-increment: step; border-top: 1px solid var(--c-filet-net); padding-top: var(--s-4); }
.method__step::before {
  content: counter(step, decimal-leading-zero); display: block;
  font: 600 var(--t-micro)/1 var(--f-sans); letter-spacing: 0.18em; color: var(--c-code-haut);
  margin-bottom: var(--s-6);
}
.method__step h3 { font: 400 clamp(1.375rem, 1.2rem + 0.8vw, 1.875rem)/1.2 var(--f-serif); color: var(--c-rabat); }
.method__step p { margin-top: var(--s-3); font-size: var(--t-body-s); line-height: 1.6; color: var(--c-craie); max-width: 30ch; }
@media (min-width: 40rem) { .method__list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 75rem) { .method__list { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* ---------- Portrait ---------- */
.portrait {
  --bleed: var(--gutter);
  display: grid; gap: var(--s-7);
  padding: var(--section-y) var(--gutter);
}
/* Portrait en pied sur fond studio : le build ramène ce fond à l'ivoire exact
   de la section (« papier » dans photos.json). Il n'y a pas de cadre à voir,
   Maître Hadji se tient directement sur la page. */
.portrait__media {
  position: relative;
  aspect-ratio: 4 / 5; max-height: 84svh; overflow: hidden;
  background: transparent; --photo-pos: 50% 55%;
  margin-left: calc(var(--bleed) * -1);
  -webkit-mask-image: none; mask-image: none;
}
.portrait__media::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: none;
}
.portrait__title { font: 300 var(--t-display)/1.02 var(--f-serif); letter-spacing: -0.03em; max-width: 12ch; }
.portrait__lede { margin-top: var(--s-5); font: 400 var(--t-lede)/1.5 var(--f-serif); color: var(--c-craie-clair); max-width: 28ch; }
.portrait .tbc-block { margin-top: var(--s-5); max-width: 42ch; }
.legal-meta--stacked { margin-top: var(--s-6); border-top: 1px solid var(--c-filet-net); }
.legal-meta--stacked > div { display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: var(--s-4); padding-block: var(--s-3); border-bottom: var(--rule); }
.legal-meta--stacked dt { font: 500 var(--t-small)/1.5 var(--f-sans); color: var(--c-plomb); }
.legal-meta--stacked dd { font: 500 var(--t-ui)/1.5 var(--f-sans); }
@media (min-width: 64rem) {
  .portrait { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--s-6); align-items: center; max-width: none; }
  .portrait > * { min-width: 0; }
  .portrait__media { grid-column: 1 / span 5; }
  .portrait__text { grid-column: 7 / span 5; }
}
@media (min-width: 90rem) {
  .portrait { --bleed: calc((100vw - var(--w-max)) / 2 + var(--gutter)); padding-inline: var(--bleed); }
}

/* ---------- Bandeau d'appel ---------- */
.contact-band {
  position: relative; isolation: isolate;
  --c-plomb: rgba(244, 243, 240, 0.74);
  --c-craie: #e6d9d9;
  --c-filet: rgba(244, 243, 240, 0.22);
  --rule: 1px solid rgba(244, 243, 240, 0.22);
  --pont: max(clamp(8rem, 12vw, 12rem), 30svh);
}
/* Le rouge en couleur, pas seulement en lumière : la dernière section, celle
   dont le propos est d'être appelée, se lève sur un bordeaux profond. Même
   principe que les sections claires — un fondu, jamais une arête. */
html:not(.js-sol) .contact-band::after {
  content: ""; position: absolute; z-index: -2; inset: 0; pointer-events: none;
  background: linear-gradient(180deg,
    rgba(74, 13, 18, 0) 0,
    #4a0d12 var(--pont),
    #6e1419 55%,
    #4a0d12 calc(100% - var(--pont) * 0.6),
    rgba(74, 13, 18, 0) 100%);
}
.contact-band__inner { padding-top: calc(var(--section-y) + var(--pont)) !important; padding-bottom: calc(var(--section-y) + var(--pont) * 0.4) !important; }
/* La seule section dont le propos est d'être appelée reçoit sa propre braise,
   posée sur l'atmosphère du document : une montée de lumière, une seule fois. */
.contact-band::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(44% 38% at 18% 74%,
    rgba(140, 28, 34, calc(0.26 * var(--braise, 1))) 0%,
    rgba(110, 20, 25, calc(0.08 * var(--braise, 1))) 44%,
    transparent 70%);
}
/* Le numéro EST le titre de la section : « Parler au cabinet » le suit au lieu
   de le coiffer. L'ordre du document ne bouge pas — le h2 reste lu en premier. */
.contact-band__call { display: flex; flex-direction: column-reverse; align-items: flex-start; }
.contact-band__inner { position: relative; z-index: 1; max-width: var(--w-max); margin-inline: auto; padding: var(--section-y) var(--gutter); }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* La lumière se lève sur la chute. Une seule fois, sur la seule section
       dont le propos est d'être appelée. */
    .contact-band::before {
      animation: braise-se-leve linear both;
      animation-timeline: view(); animation-range: entry 10% contain 55%;
    }
    @keyframes braise-se-leve { from { --braise: 0.15; } to { --braise: 1.25; } }
    .contact-band__phone { animation: number-settles linear both; animation-timeline: view(); animation-range: entry 25% contain 30%; }
    @keyframes number-settles {
      from { opacity: 0.35; transform: translate3d(0, 1.25rem, 0) scale(0.975); }
      to   { opacity: 1; transform: none; }
    }
  }
}
.contact-band__title {
  margin-top: var(--s-5);
  font: 500 var(--t-micro)/1 var(--f-sans); color: var(--c-plomb);
  letter-spacing: 0.24em; text-transform: uppercase;
}
.contact-band__phone {
  display: inline-block;
  font: 300 var(--t-phone)/1 var(--f-serif); letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums lining-nums; white-space: nowrap;
  color: var(--c-rabat); text-decoration: none;
  background-image: linear-gradient(var(--c-code-vif), var(--c-code-vif));
  background-size: 0% 3px; background-repeat: no-repeat; background-position: 0 100%;
  padding-bottom: 0.08em;
  transition: background-size 480ms var(--ease-out);
}
.contact-band__phone:hover, .contact-band__phone:focus-visible { background-size: 100% 3px; }
.contact-band__details { display: grid; gap: var(--s-6); margin-top: var(--s-8); padding-top: var(--s-6); border-top: var(--rule); }
.contact-band__hint { font-size: var(--t-body-s); color: var(--c-craie); max-width: 42ch; }
.contact-band__coords { font: 400 var(--t-ui)/1.6 var(--f-sans); display: grid; gap: var(--s-2); color: var(--c-craie-clair); }
.contact-band__coords a { color: var(--c-rabat); text-underline-offset: 0.3em; }
@media (min-width: 64rem) {
  .contact-band__details { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--s-6); }
  .contact-band__hint { grid-column: 1 / span 6; }
  .contact-band__coords { grid-column: 8 / span 5; }
}

/* ---------- Pied de page ---------- */
.site-footer { position: relative; }
.site-footer__inner {
  max-width: var(--w-max); margin-inline: auto;
  padding: var(--s-9) var(--gutter) var(--s-7);
  display: grid; gap: var(--s-7);
  font: 400 var(--t-ui)/1.6 var(--f-sans); color: var(--c-craie);
}
.site-footer__name { font: 400 1.625rem/1.2 var(--f-serif); color: var(--c-rabat); margin-bottom: var(--s-4); }
.site-footer__heading { font: 500 var(--t-small)/1.3 var(--f-sans); color: var(--c-plomb); margin-bottom: var(--s-3); letter-spacing: 0.04em; }
.site-footer ul { list-style: none; display: grid; gap: var(--s-1); }
.site-footer a { color: var(--c-craie-clair); text-underline-offset: 0.25em; transition: color var(--dur-1); }
.site-footer a:not(:hover) { text-decoration-color: var(--c-filet); }
.site-footer a:hover { color: var(--c-rabat); }
.site-footer__contact p { margin-top: var(--s-1); }
.site-footer__contact address { margin-bottom: var(--s-3); }
.footer-phone { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--c-rabat); }
.site-footer__note { margin-top: var(--s-4); font-size: var(--t-small); color: var(--c-plomb); max-width: 30ch; }
.legal-meta > div { display: grid; grid-template-columns: 9.5rem minmax(0, 1fr); gap: var(--s-3); padding-block: 0.2rem; }
.legal-meta dt { color: var(--c-plomb); }
.site-footer__base {
  max-width: var(--w-max); margin-inline: auto;
  padding: var(--s-5) var(--gutter) var(--s-6);
  border-top: var(--rule);
  display: grid; gap: var(--s-3);
  font: 400 var(--t-small)/1.55 var(--f-sans); color: var(--c-plomb);
}
.site-footer__base p:last-child { max-width: 72ch; }
@media (min-width: 40rem) { .site-footer__inner { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 75rem) {
  .site-footer__inner { grid-template-columns: 4fr 3fr 2fr 3fr; }
  .site-footer__base { grid-template-columns: auto 1fr; column-gap: var(--s-8); }
  .site-footer__base p:last-child { justify-self: end; text-align: right; }
}

/* ---------- Barre d'appel mobile ---------- */
.callbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-callbar);
  background: var(--c-robe); color: var(--c-rabat); box-shadow: var(--shadow-sheet);
  padding-bottom: env(safe-area-inset-bottom);
  border-top: 1px solid var(--c-filet);
  transition: transform var(--dur-2) var(--ease-out), visibility var(--dur-2);
}
@supports (backdrop-filter: blur(1px)) {
  .callbar { background: color-mix(in srgb, var(--c-robe) 92%, transparent); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
}
.callbar__link {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  min-height: 3.5rem; padding: var(--s-3) var(--gutter);
  color: var(--c-rabat); text-decoration: none; font: 600 1rem/1.2 var(--f-sans);
}
.callbar { border-left: 2px solid var(--c-code-vif); }
.callbar__label { display: flex; align-items: center; }
.callbar__number { font-variant-numeric: tabular-nums; font-weight: 500; }
.callbar.is-hidden { transform: translateY(110%); visibility: hidden; }
body { padding-bottom: calc(3.5rem + env(safe-area-inset-bottom)); }
html { scroll-padding-bottom: calc(4.5rem + env(safe-area-inset-bottom)); }
@media (min-width: 64rem) {
  .callbar { display: none; }
  body { padding-bottom: 0; }
  html { scroll-padding-bottom: 0; }
}

/* ==========================================================================
   Pages de contenu
   ========================================================================== */
.page-head {
  position: relative;
  max-width: var(--w-max); margin-inline: auto;
  padding: var(--s-7) var(--gutter) var(--s-9);
  border-bottom: var(--rule);
}
.page-head::before {
  content: ""; position: absolute; inset: -1px 0 auto; height: 22rem; z-index: -1; pointer-events: none;
  background: var(--wash-haut);
}
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: var(--s-2); list-style: none; font: 400 var(--t-small)/1.4 var(--f-sans); color: var(--c-plomb); }
.breadcrumb li + li::before { content: "/"; margin-right: var(--s-2); color: var(--c-filet-fort); }
.breadcrumb a { color: var(--c-plomb); transition: color var(--dur-1); }
.breadcrumb a:hover { color: var(--c-craie-clair); }
.page-title { margin-top: var(--s-7); font: 300 var(--t-display)/1.04 var(--f-serif); letter-spacing: -0.025em; max-width: 16ch; }
.page-lede { margin-top: var(--s-6); font: 400 var(--t-lede)/1.5 var(--f-serif); color: var(--c-craie-clair); max-width: 40ch; }
.page-meta { margin-top: var(--s-5); font: 400 var(--t-small)/1.4 var(--f-sans); color: var(--c-plomb); }
.page-head__call { margin-top: var(--s-6); display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3) var(--s-5); }
@media (min-width: 64rem) {
  .page-head { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--s-6); }
  .page-head > * { grid-column: 1 / span 7; }
  .page-head__call {
    grid-column: 9 / span 4; grid-row: 2 / span 3; align-self: start;
    flex-direction: column; align-items: flex-start; gap: var(--s-4); margin-top: var(--s-2);
  }
}

.article {
  max-width: var(--w-max); margin-inline: auto;
  padding: var(--s-7) var(--gutter) var(--section-y);
  display: grid; gap: var(--s-6);
}
.toc { font-family: var(--f-sans); }
.toc details { border-top: 1px solid var(--c-filet-net); border-bottom: var(--rule); }
.toc summary { padding-block: var(--s-4); font: 600 var(--t-ui)/1.3 var(--f-sans); cursor: pointer; list-style: none; display: flex; justify-content: space-between; }
.toc summary::-webkit-details-marker { display: none; }
.toc summary::after { content: "+"; font-weight: 400; }
.toc details[open] summary::after { content: "–"; }
.toc__list { list-style: none; counter-reset: toc; padding-bottom: var(--s-4); }
.toc__list li { counter-increment: toc; }
.toc__list a {
  display: grid; grid-template-columns: 1.75rem 1fr; padding-block: var(--s-2);
  font: 400 var(--t-ui)/1.4 var(--f-sans); color: var(--c-craie); text-decoration: none;
  transition: color var(--dur-1);
}
.toc__list a::before { content: counter(toc, decimal-leading-zero); color: var(--c-plomb); font-variant-numeric: tabular-nums; font-size: var(--t-micro); }
.toc__list a:hover { color: var(--c-rabat); }
.toc__list a.is-active { color: var(--c-rabat); }
.toc__list a.is-active::before { color: var(--c-code-haut); }
.toc__heading { display: none; }

/* Apostille de marge : renvoi au code, dans la colonne libre à droite du texte. */
.margin-note {
  margin: var(--s-5) 0; padding-top: var(--s-3); border-top: var(--rule);
  font: 400 var(--t-small)/1.55 var(--f-sans); color: var(--c-plomb); max-width: 46ch;
}
.margin-note b { display: block; margin-bottom: var(--s-1); font-weight: 600; color: var(--c-craie-clair); }

@media (min-width: 64rem) {
  .article { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--s-6); align-items: start; }
  .toc { grid-column: 1 / span 3; position: sticky; top: calc(var(--header-h) + var(--s-6)); }
  .toc details { border: 0; }
  .toc summary { display: none; }
  .toc__heading { display: block; font: 500 var(--t-small)/1.3 var(--f-sans); color: var(--c-plomb); padding-bottom: var(--s-3); border-bottom: 1px solid var(--c-filet-net); margin-bottom: var(--s-2); }
  .prose { grid-column: 4 / span 6; }
}
@media (min-width: 64rem) and (max-width: 74.99rem) {
  .toc { grid-column: 1 / span 12; position: static; }
  .toc details { border-top: 1px solid var(--c-filet-net); border-bottom: var(--rule); }
  .toc summary { display: flex; }
  .toc__heading { display: none; }
  .prose { grid-column: 1 / span 9; }
}
@media (min-width: 75rem) {
  .margin-note {
    float: right; clear: right; width: 12.5rem; margin: 0.4rem -14.5rem var(--s-5) var(--s-6);
    max-width: none;
  }
}

.prose { min-width: 0; color: var(--c-craie-clair); }
.prose > * + * { margin-top: var(--s-5); }
.prose p, .prose li { font-size: var(--t-body); line-height: 1.72; letter-spacing: 0.002em; max-width: 65ch; }
.prose .intro { font: 400 var(--t-lede)/1.55 var(--f-serif); color: var(--c-rabat); max-width: 40ch; }
.prose h2 {
  margin-top: var(--s-9); padding-top: var(--s-5); border-top: 1px solid var(--c-filet-net);
  font: 400 var(--t-h2-prose)/1.15 var(--f-serif); letter-spacing: -0.01em; color: var(--c-rabat);
}
.prose > h2:first-child { margin-top: 0; }
.prose h3 { margin-top: var(--s-7); font: 600 1.25rem/1.3 var(--f-serif); color: var(--c-rabat); }
.prose h2 + *, .prose h3 + * { margin-top: var(--s-4); }
.prose ul, .prose ol:not(.timeline) { padding-left: 1.25rem; }
.prose ul li::marker { content: "–  "; color: var(--c-code-vif); }
.prose li + li { margin-top: var(--s-2); }
.prose a:not(.btn) { color: var(--c-rabat); text-decoration-color: var(--c-code-vif); text-underline-offset: 0.2em; }
.prose a:not(.btn):hover { text-decoration-color: var(--c-code-haut); }
.prose strong { font-weight: 600; color: var(--c-rabat); }
.prose .note { font: 400 var(--t-ui)/1.6 var(--f-sans); color: var(--c-craie); padding: var(--s-4) 0; border-top: var(--rule); border-bottom: var(--rule); max-width: 65ch; }

/* Chronologie (garde à vue, procès) */
.timeline { list-style: none; border-left: 1px solid var(--c-filet-fort); margin-left: 0.3rem; padding: 0; }
.timeline li { position: relative; padding: 0 0 var(--s-6) var(--s-6); max-width: none; }
.timeline li::before {
  content: ""; position: absolute; left: -0.3125rem; top: 0.55rem;
  width: 0.5625rem; height: 0.5625rem; border-radius: 50%; background: var(--c-nuit); border: 1px solid var(--c-filet-net);
}
.timeline li:first-child::before { background: var(--c-code-vif); border-color: var(--c-code-vif); }
.timeline__when { display: block; font: 600 var(--t-ui)/1.4 var(--f-sans); color: var(--c-rabat); }
.timeline__what { display: block; margin-top: var(--s-1); max-width: 60ch; }

/* Définitions en ligne (lexique) */
.glossary { border-top: 1px solid var(--c-filet-net); }
.glossary > div { padding-block: var(--s-4); border-bottom: var(--rule); }
.glossary dt { font: 600 var(--t-ui)/1.4 var(--f-sans); color: var(--c-rabat); }
.glossary dd { margin-top: var(--s-1); font-size: var(--t-body-s); line-height: 1.65; max-width: 62ch; }

/* Questions fréquentes */
.faq { border-top: 1px solid var(--c-filet-net); }
.faq details { border-bottom: var(--rule); }
.faq summary {
  display: grid; grid-template-columns: minmax(0, 1fr) 1.5rem; gap: var(--s-4);
  padding-block: var(--s-4); cursor: pointer; list-style: none;
  font: 400 1.1875rem/1.4 var(--f-serif); color: var(--c-rabat);
  transition: color var(--dur-1);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font: 400 1.25rem/1.3 var(--f-sans); text-align: right; color: var(--c-plomb); }
.faq details[open] summary::after { content: "–"; color: var(--c-code-haut); }
.faq summary:hover { color: var(--c-craie); }
.faq .faq__answer { padding-bottom: var(--s-5); }
.faq .faq__answer p { font-size: var(--t-body-s); }

/* Liens vers les autres pages */
.related { margin-top: var(--s-9) !important; border-top: 1px solid var(--c-filet-net); padding-top: var(--s-5); }
.related h2 { margin: 0; padding: 0; border: 0; font: 500 var(--t-small)/1.3 var(--f-sans); color: var(--c-plomb); letter-spacing: 0.04em; }
.related ul { list-style: none; padding: 0; margin-top: var(--s-3); }
.related li { max-width: none; }
.related li + li { margin-top: 0; }
.related a {
  display: flex; justify-content: space-between; gap: var(--s-4); padding-block: var(--s-4); border-bottom: var(--rule);
  font: 400 var(--t-h3)/1.3 var(--f-serif); text-decoration: none !important; color: var(--c-craie-clair);
  transition: color var(--dur-1), padding-left var(--dur-2) var(--ease-out);
}
.related a span { font: 400 var(--t-small)/1.8 var(--f-sans); color: var(--c-plomb); text-align: right; }
.related a:hover { color: var(--c-rabat) !important; padding-left: var(--s-3); }

/* ---------- Page cabinet ---------- */
.cabinet-intro {
  max-width: var(--w-max); margin-inline: auto;
  display: grid; gap: var(--s-7);
  padding: var(--s-7) var(--gutter) var(--section-y);
}
.cabinet-intro__media { aspect-ratio: 4 / 5; max-height: 82svh; overflow: hidden; background: var(--c-robe-2); --photo-pos: 53% 32%; }
@media (min-width: 64rem) {
  .cabinet-intro { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--s-6); align-items: start; }
  .cabinet-intro__media { grid-column: 1 / span 5; position: sticky; top: calc(var(--header-h) + var(--s-6)); }
  .cabinet-intro__text { grid-column: 7 / span 6; }
}
.prose .cabinet-intro__lede { font: 400 var(--t-lede)/1.5 var(--f-serif); color: var(--c-rabat); max-width: 34ch; }
.fact-sheet { border-top: 1px solid var(--c-filet-net); }
.fact-sheet > div { display: grid; gap: var(--s-1); padding-block: var(--s-4); border-bottom: var(--rule); }
.fact-sheet dt { font: 500 var(--t-small)/1.4 var(--f-sans); color: var(--c-plomb); }
.fact-sheet dd { font: 400 var(--t-body-s)/1.5 var(--f-serif); color: var(--c-craie-clair); }
@media (min-width: 40rem) { .fact-sheet > div { grid-template-columns: 12rem minmax(0, 1fr); gap: var(--s-5); } }

/* ---------- Contact ---------- */
.contact-layout {
  max-width: var(--w-max); margin-inline: auto;
  padding: var(--s-7) var(--gutter) var(--section-y);
  display: grid; gap: var(--s-9);
}
.contact-direct__label { font: 500 var(--t-small)/1.3 var(--f-sans); color: var(--c-plomb); letter-spacing: 0.04em; }
.contact-direct__phone {
  display: inline-block; margin-top: var(--s-3);
  font: 300 clamp(2.5rem, 1.5rem + 3.4vw, 4.5rem)/1 var(--f-serif); letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; color: var(--c-rabat); text-decoration: none;
  background-image: linear-gradient(var(--c-code-vif), var(--c-code-vif));
  background-size: 0% 2px; background-repeat: no-repeat; background-position: 0 100%;
  padding-bottom: 0.08em; transition: background-size 420ms var(--ease-out);
}
.contact-direct__phone:hover, .contact-direct__phone:focus-visible { background-size: 100% 2px; }
.contact-direct .btn { margin-top: var(--s-5); }
.contact-direct .fact-sheet { margin-top: var(--s-7); }
.prep { margin-top: var(--s-6); padding-top: var(--s-4); border-top: 1px solid var(--c-filet-net); font-family: var(--f-sans); max-width: 44ch; }
.prep h3 { font: 600 var(--t-ui)/1.4 var(--f-sans); color: var(--c-rabat); }
.prep ul { list-style: none; margin-top: var(--s-3); display: grid; gap: var(--s-2); }
.prep li { display: grid; grid-template-columns: 1rem 1fr; font: 400 var(--t-small)/1.55 var(--f-sans); color: var(--c-craie); }
.prep li::before { content: "–"; color: var(--c-code-vif); }
.prep p { margin-top: var(--s-3); font: 400 var(--t-small)/1.5 var(--f-sans); color: var(--c-plomb); }
.contact-direct__hint { margin-top: var(--s-6); font-size: var(--t-body-s); color: var(--c-craie); max-width: 44ch; }
@media (min-width: 64rem) {
  .contact-layout { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--s-6); }
  .contact-direct { grid-column: 1 / span 5; }
  .contact-form-wrap { grid-column: 7 / span 6; }
}

.form-title { font: 300 var(--t-h2-prose)/1.15 var(--f-serif); color: var(--c-rabat); }
.form-intro { margin-top: var(--s-3); font-size: var(--t-body-s); color: var(--c-craie); max-width: 52ch; }
.form { margin-top: var(--s-6); display: grid; gap: var(--s-5); font-family: var(--f-sans); }
.form-row { display: grid; gap: var(--s-5); }
@media (min-width: 40rem) { .form-row { grid-template-columns: 1fr 1fr; } }
.field { display: grid; gap: var(--s-2); align-content: start; }
.field label, .field legend { font: 600 var(--t-ui)/1.3 var(--f-sans); color: var(--c-rabat); }
.field__req { font-weight: 400; color: var(--c-plomb); }
.field__help { font: 400 var(--t-small)/1.45 var(--f-sans); color: var(--c-plomb); }
.field input, .field select, .field textarea {
  width: 100%; min-height: 3.25rem; padding: 0.8rem 0.95rem;
  font: 400 1.0625rem/1.4 var(--f-sans); color: var(--c-rabat);
  background: var(--c-robe-2); border: 1px solid var(--c-bord-ui); border-radius: var(--radius);
  caret-color: var(--c-code-haut); appearance: none;
  transition: border-color var(--dur-1), background-color var(--dur-1);
}
.field textarea { min-height: 9.5rem; resize: vertical; }
.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23f4f3f0' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 1rem center; padding-right: 2.75rem;
}
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--c-filet-net); }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { outline: 2px solid var(--c-code-haut); outline-offset: 2px; border-color: var(--c-craie); background: var(--c-robe-3); }
.field [aria-invalid="true"] { border-color: var(--c-code-haut); box-shadow: inset 3px 0 0 var(--c-code-haut); }
.field__error { font: 600 var(--t-small)/1.45 var(--f-sans); color: var(--c-code-haut); }
.field__error:empty { display: none; }
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form-notice { font: 400 var(--t-small)/1.55 var(--f-sans); color: var(--c-plomb); max-width: 60ch; }
.form-notice a { color: var(--c-craie-clair); }
.form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4); }
.form-status { font: 600 var(--t-ui)/1.5 var(--f-sans); }
.form-status:empty { display: none; }
.form-status--error { color: var(--c-code-haut); }
.form-summary { border: 1px solid var(--c-code-haut); padding: var(--s-4) var(--s-5); font: 400 var(--t-ui)/1.5 var(--f-sans); }
.form-summary h3 { font: 600 var(--t-ui)/1.4 var(--f-sans); color: var(--c-code-haut); }
.form-summary ul { margin-top: var(--s-2); padding-left: 1.1rem; }
.form-summary a { color: var(--c-rabat); }
.form-success { margin-top: var(--s-6); border-top: 2px solid var(--c-succes); padding-top: var(--s-5); }
.form-success h3 { font: 400 var(--t-h3)/1.3 var(--f-serif); color: var(--c-rabat); }
.form-success p { margin-top: var(--s-3); font-size: var(--t-body-s); color: var(--c-craie); max-width: 50ch; }
.form-success:focus { outline: none; }
.target-banner { display: none; border: 1px solid var(--c-code-haut); padding: var(--s-4) var(--s-5); margin-top: var(--s-5); font: 400 var(--t-ui)/1.55 var(--f-sans); }
.target-banner:target { display: block; }
.target-banner strong { color: var(--c-code-haut); }

/* ---------- Pages légales ---------- */
.legal-block { border-top: 1px solid var(--c-filet-net); }
.legal-block > div { display: grid; gap: var(--s-1); padding-block: var(--s-3); border-bottom: var(--rule); }
.legal-block dt { font: 500 var(--t-small)/1.4 var(--f-sans); color: var(--c-plomb); }
.legal-block dd { font: 400 var(--t-body-s)/1.55 var(--f-serif); color: var(--c-craie-clair); }
@media (min-width: 40rem) { .legal-block > div { grid-template-columns: 13rem minmax(0, 1fr); gap: var(--s-5); } }

/* ---------- 404 ---------- */
.notfound { max-width: var(--w-max); margin-inline: auto; padding: var(--s-10) var(--gutter); min-height: 60svh; }
.notfound ul { list-style: none; margin-top: var(--s-6); border-top: 1px solid var(--c-filet-net); max-width: 36rem; }
.notfound li a {
  display: block; padding-block: var(--s-3); border-bottom: var(--rule);
  font: 400 var(--t-h3)/1.3 var(--f-serif); color: var(--c-craie-clair); text-decoration: none;
  transition: color var(--dur-1), padding-left var(--dur-2) var(--ease-out);
}
.notfound li a:hover { color: var(--c-rabat); padding-left: var(--s-3); }

/* ---------- Impression : on repasse sur fond blanc ---------- */
@media print {
  :root { color-scheme: light; }
  .site-header, .callbar, .toc, .contact-band, .hero__photo, .skip-link, .chapters { display: none !important; }
  html, body { background: #fff !important; color: #16161a !important; }
  body { padding: 0; font-size: 11pt; }
  * { background-image: none !important; color: #16161a !important; border-color: #b0b0b0 !important; }
  a[href^="tel:"]::after { content: " (" attr(href) ")"; }
}

/* ---------- Préférences système ----------
   Le mouvement n'est pas la seule chose qu'on peut vouloir en moins. */
@media (prefers-reduced-transparency: reduce) {
  .site-header, .callbar { background: var(--c-nuit); backdrop-filter: none; -webkit-backdrop-filter: none; }
  .site-header.is-stuck { background: var(--c-nuit); }
}
@media (prefers-contrast: more) {
  :root {
    --c-craie: #d8d7d2;
    --c-plomb: #b0afaa;
    --c-filet: rgba(244, 243, 240, 0.30);
    --c-bord-ui: rgba(244, 243, 240, 0.62);
    --c-code-haut: #f0777d;
    --c-code-clair: #f0777d;
  }
  .hero__photo::before { background: linear-gradient(90deg, rgba(8,8,10,0.94) 0%, rgba(8,8,10,0.6) 34%, rgba(8,8,10,0.1) 70%); }
  .chapter::before, .contact-band::after, .chapter::after { display: none; }
}
