/* ═══════════════════════════════════════════════════════════════════════════
   Drai Associés — feuille AUTONOME. Elle répond entièrement du rendu du site :
   ce qu'elle n'habille pas n'est habillé nulle part (aucun base.css derrière,
   seul le socle chrome.css la précède : lien d'évitement, anneau de focus,
   modèle de boîte).

   DIRECTION — révision du 23/09/2026 : la géométrie Harbottle (bandes,
   angles vifs) reste. La palette est désormais le nuancier Abricot,
   dix-sept marches d'un seul orangé de tuile. Plus de bleu.

   • ACCUEIL : les marches qui se tiennent ensemble et qui portent
     l'encre — crème #F2CDB0, argile #F4B281, corail #F4A469, glacier
     #F29456, miel #F08441, vermillon #EB752F, taupe #E26629. L'ambre
     #6B2D16 est la seule bande sombre (le texte y passe au papier).
   • LOGO ET COULEUR PRINCIPALE : le plus foncé, #5C2814, au repos.
     Au survol, la marque saute entre les dix-sept marches, dans un
     ordre mêlé. Elle ne se mélange pas aux bandes.
   • DIX-SEPT AVOCATS : une marche chacun, du plus foncé au plus clair,
     sur la page Équipe. L'aperçu de l'accueil n'en montre que trois,
     espacées (#F4A469, #F08441, #E26629) pour qu'elles se lisent côte
     à côte.
   • ANGLES VIFS. Aucun rayon, nulle part — sauf le fond de l'ouverture,
     une vague (sable, mousse, mer) dont le contour se déforme. Le reste
     — titres, filets, cartes — reste des rectangles.
   • FOND DE PAGE : la crème #F2CDB0, marche la plus claire. Le papier
     #FFFBF7 ne peint plus la page — il reste le texte sur l'ambre et le
     fond des champs.
   • ENCRE NOIRE sur les bandes claires. Papier sur l'ambre, blanc sur
     les huit premières cartes d'avocats (fonds trop sombres pour l'encre).
   • CAPITALES pour tout ce qui structure : navigation, libellés, boutons,
     titres d'élément (domaines, profils, articles). Leurs titres d'élément
     sont en sans 600 capitales, 32/34 — interligne plus serré que le corps.
   • SÉRIF pour le texte : chapôs immenses (40/44 chez eux), corps en sérif.
   • Liens sans fond ni bordure : capitales, lettrage espacé, chevron.

   TROIS RÈGLES QUE CETTE FEUILLE NE PEUT PAS ENFREINDRE (AGENTS.md § 3) :
   1. Vocabulaire de couleur FERMÉ — les six noms du contrat sont déclarés dans
      `:root`, et ce sont eux que le harnais mesure sur six paires. Les bandes
      supplémentaires sont AUSSI dans `:root` (donc aucune couleur littérale
      ailleurs), mais elles échappent au contrôle : l'encre est mesurée sur
      chacune, et le ratio est écrit à côté.
   2. Sur une bande claire, tout texte est `--color-text`. `--color-muted` n'y
      tient pas (2,02:1 sur le vermillon) : la règle `.bande-couleur` le ramène
      donc à l'encre, atténués compris. Exception unique : l'ambre #6B2D16 est
      sombre, l'encre y tombe à 1,72:1. Le teaser, seule bande ambre qui porte
      du texte, passe au papier (10,14:1).
   3. Tout mouvement se tait sous `prefers-reduced-motion`, et les révélations
      au défilement n'animent QUE `transform` (voir le bloc « Mouvement »).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Fontes auto-hébergées (art. V : zéro ressource externe) ─────────────── */

@font-face {
  font-family: "Spectral";
  src: url("fonts/spectral-400.6ec1900716de.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Spectral";
  src: url("fonts/spectral-600.ccd396b92abd.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* Italique réelle (17/09). Le contenu repris du WordPress porte 298 <em> — des
   titres d'ouvrages, des locutions latines, un intitulé allemand — que le
   navigateur penchait mécaniquement faute de fichier. Sous-ensemble latin,
   SIL OFL, licence déjà déposée en docs/licences/OFL-spectral.txt. */
@font-face {
  font-family: "Spectral";
  src: url("fonts/spectral-400-italic.dac97c9667ed.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Libre Franklin";
  src: url("fonts/librefranklin-400.6b939122bafb.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Libre Franklin";
  src: url("fonts/librefranklin-600.6c5ae80149ae.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* ── Remise à zéro ──────────────────────────────────────────────────────── */

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

html {
  -webkit-text-size-adjust: 100%;
  /* L'en-tête est COLLANT : sans cette réserve, une ancre (`/#domaines`)
     dépose sa cible sous la barre — mesuré à 26 px avalés, le titre de
     section à moitié caché. Vaut pour la navigation par fragment ET pour
     `scrollIntoView`, ce qu'un `scroll-margin-top` posé cible par cible
     n'aurait pas couvert. 6 rem = la barre (87 px) plus une respiration. */
  scroll-padding-top: 6rem;
}

body,
h1,
h2,
h3,
p,
ul,
ol,
dl,
dd,
figure,
address {
  margin: 0;
  padding: 0;
}

ul,
ol {
  list-style: none;
}

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

input,
textarea,
button {
  font: inherit;
  color: inherit;
}

/* ── Jetons ─────────────────────────────────────────────────────────────────

   Les SIX premiers sont le contrat. Ratios mesurés (tenants/wcag.py) :
     texte / fond .................. 17,45:1
     texte / surface ............... 12,09:1
     sur-principale / principale ... 11,87:1
     principale / fond ............. 11,53:1
     atténué / fond ................. 6,68:1
     atténué / surface .............. 4,63:1

   Les BANDES qui suivent échappent au contrôle automatique. L'encre y est
   mesurée à la main : 5,28:1 sur la taupe (le pire cas des bandes claires),
   6,09 sur le vermillon, ≥ 6,91 sur les autres. L'ambre #6B2D16 est sombre :
   l'encre y est à 1,72:1, le papier à 10,14:1. Le teaser porte donc le
   papier, et lui seul.
   ───────────────────────────────────────────────────────────────────────── */

:root {
  --color-background: #FFFBF7;
  --color-surface: #F2CDB0;
  --color-text: #1A1614;
  --color-primary: #5C2814;
  --color-on-primary: #FFFFFF;
  --color-muted: #645850;

  /* Filet. Le trait fin prend une marche claire du nuancier ; le fort
     reste l'encre. */
  --color-rule: #F29456;
  --color-rule-fort: #1A1614;

  /* Bandes de l'accueil — marches espacées du nuancier Abricot, toutes
     assez claires pour l'encre, sauf l'ambre. Le #5C2814 n'y figure pas :
     il est réservé au logo et à --color-primary. */
  --creme: #F2CDB0;
  --argile: #F4B281;
  --corail: #F4A469;
  --glacier: #F29456;
  --miel: #F08441;
  --vermillon: #EB752F;
  --taupe: #E26629;
  --ambre: #6B2D16;

  /* Une marche par avocat, du plus clair au plus foncé. 01 à 09 portent
     l'encre (≥ 4,59:1). À partir de 10, l'encre tombe sous 4,5:1 : le
     texte passe au blanc (4,55:1 sur la 10, puis au-delà). */
  --avocat-01: #F2CDB0;
  --avocat-02: #F3C099;
  --avocat-03: #F4B281;
  --avocat-04: #F4A469;
  --avocat-05: #F29456;
  --avocat-06: #F08441;
  --avocat-07: #EB752F;
  --avocat-08: #E26629;
  --avocat-09: #D95822;
  --avocat-10: #CB4D1E;
  --avocat-11: #BB481D;
  --avocat-12: #AA421C;
  --avocat-13: #9A3D1A;
  --avocat-14: #8A3819;
  --avocat-15: #7A3218;
  --avocat-16: #6B2D16;
  --avocat-17: #5C2814;

  /* Bande COURANTE — réaffectée par bloc, sans jamais poser de littéral. */
  --bande: var(--glacier);

  --serif: "Spectral", "Iowan Old Style", "Palatino Linotype", Palatino, serif;
  --sans: "Libre Franklin", "Helvetica Neue", Arial, sans-serif;

  --marge: clamp(1.25rem, 4vw, 4.5rem);
  --souffle: clamp(3.5rem, 9vw, 7.5rem);
  --colonne: min(100% - 2 * var(--marge), 84rem);
  --mesure: 60ch;

  /* Lettrage des capitales d'interface — la valeur de Harbottle (0,7 px sur
     14 px) ramenée en em pour suivre l'échelle. */
  --lettrage: 0.05em;
}

body {
  /* Crème, marche la plus claire du nuancier. Le papier #FFFBF7 reste le
     jeton --color-background : il sert de texte sur l'ambre et de fond
     aux champs, il ne peint plus la page. L'encre y est à 12,09:1,
     l'atténué à 4,63:1 — les deux paires déjà mesurées sur la surface. */
  background: var(--creme);
  color: var(--color-text);
  /* Corps en SÉRIF, comme leur page About : c'est ce qui donne le ton
     éditorial. Le sans-sérif est réservé à l'interface et aux capitales. */
  font-family: var(--serif);
  font-size: clamp(1.0625rem, 1rem + 0.25vw, 1.1875rem);
  line-height: 1.6;
  overflow-wrap: break-word;
}

h1,
h2,
h3 {
  font-weight: 400;
}

p + p {
  margin-top: 1.15rem;
}

a {
  color: var(--color-text);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 3px solid var(--color-text);
  outline-offset: 3px;
}

/* ── Mouvement ──────────────────────────────────────────────────────────────

   Un seul endroit pour tout ce qui bouge, un seul interrupteur pour tout
   éteindre. Les images-clés qui ouvrent à `opacity: 0` sont jouées en `both` :
   sous `reduce`, la durée tombe à 0,01 ms et l'élément saute à son état FINAL,
   visible. Aucun contenu ne peut rester caché.
   ───────────────────────────────────────────────────────────────────────── */

@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;
  }
}

/* Transitions ENTRE pages, sans une ligne de script : le navigateur capture
   l'ancienne page, charge la nouvelle, et anime de l'une à l'autre. Un
   navigateur qui ne connaît pas la règle change de page comme avant.

   PIÈGE : la règle ci-dessus vise `*`, et `*` n'atteint PAS les
   pseudo-éléments `::view-transition-*`. Sans ce second bloc, un visiteur qui
   a demandé moins de mouvement subirait quand même le volet à chaque clic. */
@view-transition {
  navigation: auto;
}

@media (prefers-reduced-motion: reduce) {
  @view-transition {
    navigation: none;
  }
}

/* L'ancienne page remonte et se replie vers le haut, découvrant l'orangé de
   l'ouverture ; la nouvelle se déplie depuis le bas. Les `clip-path` ne vivent
   que le temps de la transition : les pseudo-éléments disparaissent avec
   elle, aucune couche ne reste (voir « volet-bas » plus bas). */
::view-transition-group(root) {
  background: var(--vermillon);
}

::view-transition-old(root) {
  animation: page-sortir 0.45s cubic-bezier(0.7, 0, 0.84, 0) both;
}

::view-transition-new(root) {
  animation: page-entrer 0.8s cubic-bezier(0.22, 1, 0.36, 1) 0.3s both;
}

@keyframes page-sortir {
  from {
    transform: translateY(0);
    clip-path: inset(0 0 0 0);
  }

  to {
    transform: translateY(-3rem);
    clip-path: inset(0 0 100% 0);
  }
}

@keyframes page-entrer {
  from {
    transform: translateY(3rem);
    clip-path: inset(100% 0 0 0);
  }

  to {
    transform: translateY(0);
    clip-path: inset(0 0 0 0);
  }
}

@keyframes apparaitre {
  from {
    opacity: 0;
    transform: translateY(1.5rem);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Volet : un bloc de couleur qui se découvre depuis le bas. Il n'anime
   qu'un `clip-path` — rien qui puisse laisser un contenu invisible. Un
   `clip-path` qui RESTE après l'animation, même no-op, fabrique une couche
   de composition WebKit : sur iPad, elle se décale d'une tuile au défilement
   et clippe l'aplat. D'où `animation-fill-mode: backwards` partout où il
   sert : le `from` tient pendant le délai, puis le `clip-path` disparaît. */
@keyframes volet-bas {
  from {
    clip-path: inset(100% 0 0 0);
  }

  to {
    clip-path: inset(0 0 0 0);
  }
}

/* Révélation au défilement, en `translate` : un `transform` animé
   écrasait le `transform` du survol (`.portrait:hover`), qui ne jouait plus
   une fois la carte révélée. */
@keyframes revele {
  from {
    translate: 0 3rem;
  }

  to {
    translate: 0 0;
  }
}

/* Un mot du titre monte de sous son masque. */
@keyframes monter {
  from {
    transform: translateY(110%);
  }

  to {
    transform: translateY(0);
  }
}

/* Un filet se trace de gauche à droite. */
@keyframes tracer {
  from {
    transform: scaleX(0);
  }

  to {
    transform: scaleX(1);
  }
}

/* Une photo de portrait se dévoile : elle arrive serrée et décalée vers le
   bas, puis se recadre. Rien ne la masque ni ne la décolore — figée à
   mi-course, elle reste la photo, un peu plus serrée. */
@keyframes devoiler-photo {
  from {
    scale: 1.2;
    translate: 0 8%;
  }

  to {
    scale: 1;
    translate: 0 0;
  }
}

/* Le carré de rang d'un domaine se pose en tournant. */
@keyframes poser {
  from {
    transform: scale(0.3) rotate(-90deg);
  }

  to {
    transform: scale(1) rotate(0deg);
  }
}

/* Défilé des domaines : six créneaux de 3 s sur un cycle de 18 s. Chaque
   intitulé monte, tient, puis sort par le haut pendant que le suivant entre
   par le bas — 3 % du cycle ≈ 0,54 s de passage. Animation au TEMPS, et non
   au défilement : elle joue dans tous les navigateurs. */
@keyframes defiler {
  0% {
    translate: 0 110%;
  }

  3%,
  14% {
    translate: 0 0;
  }

  17%,
  100% {
    translate: 0 -110%;
  }
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }

  a,
  .bouton,
  .button,
  .nav__link,
  .poles__lien,
  .poles__titre,
  .portrait,
  .portrait__photo,
  .question,
  .card,
  .liste__item,
  .champ input,
  .champ textarea {
    transition:
      background-color 0.3s cubic-bezier(0.22, 1, 0.36, 1),
      color 0.3s ease,
      border-color 0.3s ease,
      transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
      opacity 0.2s ease;
  }
}

/* Révélations au défilement — et la règle qui les rend sûres.

   Elles n'animent QUE `transform`, jamais l'opacité. Motif constaté sur cette
   feuille même : une capture pleine page (outil de recette, export PDF, webvue
   de très grande hauteur) recalcule la progression d'une timeline `view()` et
   peut la figer à 0. Avec un fondu, la page se rend VIDE — la régression qui
   ne casse aucun test (art. IV). Avec une translation, le pire cas est un
   contenu décalé de 3 rem, entièrement lisible. Même règle pour les filets
   et les carrés de rang : figés, ils manquent ; le texte, lui, reste.

   `@supports` en plus : sans `animation-timeline`, aucune règle ne s'applique. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .bloc__titre,
    .section__title,
    .page-header__title,
    .poles__item,
    .portrait,
    .question,
    .liste__item,
    .card,
    .declaration__texte {
      animation: revele linear both;
      animation-timeline: view();
      animation-range: entry 5% entry 60%;
    }

    /* CASCADE : les cartes d'une même rangée ont la même timeline ; des
       plages décalées les font arriver l'une après l'autre. */
    .portraits--apercu .portrait:nth-child(3n + 2),
    .cards .card:nth-child(3n + 2) {
      animation-range: entry 15% entry 75%;
    }

    .portraits--apercu .portrait:nth-child(3n + 3),
    .cards .card:nth-child(3n + 3) {
      animation-range: entry 25% entry 90%;
    }

    /* PHOTOS DE PORTRAIT — accueil, équipe, partenaires. La photo lit la
       timeline NOMMÉE de sa carte, jamais `view()` : la carte est en
       `overflow: hidden`, donc conteneur de défilement, et un `view()` posé
       sur la photo s'y rattacherait — une boîte qui ne défile pas, photo
       figée d'emblée à son état final (constaté à la recette). La plage
       dépasse celle de la carte : la carte est posée que la photo se
       recadre encore. Dans l'aperçu, la cascade décale aussi les photos. */
    .portrait {
      view-timeline-name: --portrait;
    }

    .portrait__photo {
      animation: devoiler-photo linear both;
      animation-timeline: --portrait;
      animation-range: entry 0% entry 85%;
    }

    .portraits--apercu .portrait:nth-child(3n + 2) .portrait__photo {
      animation-range: entry 10% entry 95%;
    }

    .portraits--apercu .portrait:nth-child(3n + 3) .portrait__photo {
      animation-range: entry 20% entry 100%;
    }

    /* Le carré de rang d'un domaine se pose APRÈS sa rangée : il lit la
       timeline de la rangée, pas la sienne. */
    .poles__item {
      view-timeline-name: --pole;
    }

    .poles__rang {
      animation: poser linear both;
      animation-timeline: --pole;
      animation-range: entry 30% entry 100%;
    }

    /* FILETS : un pseudo-élément de 2 px n'a pas de timeline utile — elle
       serait consommée en deux pixels de défilement. Il lit donc celle de
       la liste qu'il surmonte. */
    .poles,
    .liste {
      view-timeline-name: --filet;
    }

    .poles::before,
    .liste::before {
      animation: tracer linear both;
      animation-timeline: --filet;
      animation-range: cover 0% cover 30%;
    }

  }
}

/* ── Trame ──────────────────────────────────────────────────────────────────
   Les bandes vont d'un bord à l'autre ; seul le contenu est mis en colonne. */

.mesure,
.container {
  width: var(--colonne);
  margin-inline: auto;
}

.mesure--etroite,
.container--narrow {
  max-width: var(--mesure);
}

.bloc,
.section {
  position: relative;
  padding-block: var(--souffle);
  /* Pas d'`overflow: clip` ici. WebKit (iPad en tête) implémente `clip`
     comme un `clip-path` de composition : au défilement, la tuile se
     décale d'une frame et l'aplat — surtout le vermillon — apparaît
     coupé. `hidden` sur une section n'est pas davantage nécessaire :
     rien ne dépasse, et `hidden` sur <body> (la leçon d'août) est une
     autre histoire, celle d'une boîte de défilement qui fige scrollY. */
}

.section--surface {
  background: var(--color-surface);
}

.section--entete,
.section:has(.page-header) {
  padding-bottom: 0;
}

.section:has(.page-header) + .section {
  padding-top: 2rem;
}

/* Toute bande de couleur ramène le texte à l'encre — atténués compris. C'est
   la règle 2 de l'en-tête de cette feuille, et elle est ici, en un seul
   endroit, pour qu'aucune bande future ne l'oublie. */
.bande-couleur,
.bande-couleur .attenue,
.bande-couleur .chapo,
.bande-couleur .teaser__chapo,
.bande-couleur .poles__resume,
.bande-couleur .portrait__bio,
/* Les boutons sont exclus : plus spécifique que `.bouton`, cette règle leur
   imposait l'encre sur leur fond brun — 1,6:1, illisible (constaté le 23/09
   sur le bouton de l'ouverture). Le blanc du bouton reste le sien. */
.bande-couleur a:not(.bouton, .button) {
  color: var(--color-text);
}

/* ── Titres, libellés, chapôs ───────────────────────────────────────────────
   Deux échelles, et il ne faut pas les confondre. Les TITRES DE PAGE sont en
   sérif capitales, très grands. Les TITRES D'ÉLÉMENT (un domaine, un profil,
   un article) sont en sans 600 capitales, interligne serré — c'est leur
   signature, et c'est ce qui fait « catalogue » plutôt que « magazine ». */

.bloc__titre,
.section__title,
.page-header__title {
  font-family: var(--serif);
  font-size: clamp(2.35rem, 1.3rem + 3.6vw, 4.5rem);
  font-weight: 600;
  line-height: 0.98;
  letter-spacing: -0.015em;
  text-transform: uppercase;
}

/* Libellé de section : capitales sérif, petites, lettrées — leur « FEATURED
   NEWS & INSIGHTS ». Un carré de couleur le précède, jamais un disque. */
.surtitre,
.page-header__eyebrow,
.section__label {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  line-height: 1.2;
  text-transform: uppercase;
  color: var(--color-text);
}

.section__label {
  margin-bottom: 2.5rem;
}

.surtitre::before,
.page-header__eyebrow::before,
.section__label::before {
  content: "";
  width: 0.7rem;
  height: 0.7rem;
  background: var(--bande);
  flex: none;
}

/* Chapô : leur grand sérif, 40/44. Ici il suit la largeur de la fenêtre. */
.chapo,
.ouverture__chapo,
.lede,
.teaser__chapo {
  max-width: 46ch;
  margin-top: 1.75rem;
  font-family: var(--serif);
  font-size: clamp(1.25rem, 1rem + 1vw, 1.9rem);
  line-height: 1.22;
  color: var(--color-text);
}

/* Le chapô d'une page intérieure reste un chapô, pas un titre : il descend
   d'un cran et passe à l'atténué. */
.bloc .chapo,
.section .chapo {
  font-size: clamp(1.15rem, 1rem + 0.5vw, 1.45rem);
  color: var(--color-muted);
}

.attenue {
  color: var(--color-muted);
  font-family: var(--sans);
  font-size: 0.875rem;
  letter-spacing: 0.02em;
}

/* ── En-tête ────────────────────────────────────────────────────────────────
   Barre blanche, mince, collante. Nom à gauche, MENU à droite, tout en
   capitales lettrées. Sous la barre, le filet des dix couleurs de la palette :
   c'est la seule chose de cette feuille qui ne soit pas chez eux, et elle y
   est parce qu'elle dit la palette avant que la page ne la montre. */

.header {
  position: sticky;
  top: 0;
  z-index: 50;
  /* Vermillon, comme l'ouverture (23/09) : la barre et la première bande ne
     font qu'un aplat. L'encre y tient à 6,09:1. Tout survol qui passait AU
     vermillon s'y dissoudrait — menu et bouton se vident à la place. */
  background: var(--vermillon);
  /* Nommée, la barre est capturée à part pendant une transition de page :
     elle reste en place pendant que le corps change sous elle. */
  view-transition-name: entete;
}

.header::after {
  content: "";
  display: block;
  height: 6px;
  /* Tracé une fois au chargement, de gauche à droite — et donc à chaque
     page, comme une barre de progression qui dit la palette. */
  transform-origin: left;
  animation: tracer 1.4s cubic-bezier(0.22, 1, 0.36, 1) 0.15s both;
  /* Filet de six pixels. Les marches les plus claires disparaissent sur le
     papier à cette épaisseur : on part de #F29456, assez loin du blanc
     pour se lire, jusqu'à l'ambre. Le #5C2814 reste au logo. */
  background: linear-gradient(
    90deg,
    var(--glacier) 0 12.5%,
    var(--miel) 12.5% 25%,
    var(--vermillon) 25% 37.5%,
    var(--taupe) 37.5% 50%,
    var(--avocat-09) 50% 62.5%,
    var(--avocat-11) 62.5% 75%,
    var(--avocat-13) 75% 87.5%,
    var(--ambre) 87.5% 100%
  );
}

.header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.6rem;
  width: var(--colonne);
  margin-inline: auto;
}

.header__name {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  min-height: 40px;
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  text-decoration: none;
}

.header__logo {
  width: 1.85rem;
  height: 1.85rem;
  /* Le fichier porte le CHAMP en papier — capitales évidées et bloc « drai »
     transparents. Au repos, la marque est le plus foncé du nuancier,
     #5C2814, le même que --color-primary. Sans effet sur Open Graph, qui
     prend le héros (content/schema.py). */
  background-color: var(--color-primary);
}

/* Au survol du lien (logo et nom), la marque saute d'une marche à l'autre.
   L'ordre est mêlé, pas celui du nuancier. `step-end` interdit
   l'interpolation : chaque palier est l'une des dix-sept couleurs, rien
   entre. Le mouvement s'arrête avec le pointeur, et il se tait sous
   prefers-reduced-motion comme le reste de la feuille. */
@media (prefers-reduced-motion: no-preference) {
  .header__name:hover .header__logo,
  .header__name:focus-visible .header__logo {
    animation: logo-hasard 8.5s linear infinite;
  }
}

@keyframes logo-hasard {
  0% {
    background-color: var(--avocat-04);
    animation-timing-function: step-end;
  }

  5.882% {
    background-color: var(--avocat-15);
    animation-timing-function: step-end;
  }

  11.765% {
    background-color: var(--avocat-07);
    animation-timing-function: step-end;
  }

  17.647% {
    background-color: var(--avocat-16);
    animation-timing-function: step-end;
  }

  23.529% {
    background-color: var(--avocat-02);
    animation-timing-function: step-end;
  }

  29.412% {
    background-color: var(--avocat-12);
    animation-timing-function: step-end;
  }

  35.294% {
    background-color: var(--avocat-06);
    animation-timing-function: step-end;
  }

  41.176% {
    background-color: var(--avocat-17);
    animation-timing-function: step-end;
  }

  47.059% {
    background-color: var(--avocat-01);
    animation-timing-function: step-end;
  }

  52.941% {
    background-color: var(--avocat-13);
    animation-timing-function: step-end;
  }

  58.824% {
    background-color: var(--avocat-08);
    animation-timing-function: step-end;
  }

  64.706% {
    background-color: var(--avocat-14);
    animation-timing-function: step-end;
  }

  70.588% {
    background-color: var(--avocat-03);
    animation-timing-function: step-end;
  }

  76.471% {
    background-color: var(--avocat-11);
    animation-timing-function: step-end;
  }

  82.353% {
    background-color: var(--avocat-05);
    animation-timing-function: step-end;
  }

  88.235% {
    background-color: var(--avocat-10);
    animation-timing-function: step-end;
  }

  94.118% {
    background-color: var(--avocat-09);
    animation-timing-function: step-end;
  }

  100% {
    background-color: var(--avocat-04);
  }
}

.nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.6rem;
}

/* Décision du jalon du 25/08 : l'entrée « Le cabinet » doublait la page
   /equipe/. Même geste le 20/09 pour « Domaines d'intervention », qui
   doublait /nos-competences/. Masquées, pas retirées — le partial de nav
   est plateforme. */
.nav__item:has(> .nav__link[href="/#cabinet"]),
.nav__item:has(> .nav__link[href="/#domaines"]) {
  display: none;
}

.nav__link {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: var(--lettrage);
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 2px solid transparent;
}

.nav__link:hover {
  border-bottom-color: var(--color-text);
  text-decoration: none;
}

.header .button,
.header .button--primary {
  margin-top: 0;
  min-height: 40px;
  padding: 0.5rem 1.1rem;
  font-size: 0.75rem;
}

/* MENU : le même brun que le logo, texte blanc. Pas de rayon. */
.nav-repli {
  display: none;
}

@media (max-width: 62rem) {
  .nav-desktop {
    display: none;
  }

  .nav-repli {
    display: block;
  }
}

body.nav-repliee .nav-desktop {
  display: none;
}

body.nav-repliee .nav-repli {
  display: block;
}

.nav-repli > summary {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 40px;
  padding: 0.35rem 1rem;
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  cursor: pointer;
  list-style: none;
}

.nav-repli > summary::-webkit-details-marker {
  display: none;
}

.nav-repli > summary::marker {
  content: "";
}

/* Trois barres, DESSINÉES : le glyphe « ☰ » dépend d'une fonte, ces traits
   non. Ouvert, elles deviennent une croix — deux bandes centrées, la boîte
   pivotée de 45°. La version précédente n'en gardait qu'une et affichait un
   trait vertical solitaire. */
.nav-repli > summary::after {
  content: "";
  flex: none;
  width: 1rem;
  height: 1rem;
  background:
    linear-gradient(currentcolor 0 0) left top / 100% 2px no-repeat,
    linear-gradient(currentcolor 0 0) left center / 100% 2px no-repeat,
    linear-gradient(currentcolor 0 0) left bottom / 100% 2px no-repeat;
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.nav-repli > summary:hover {
  background: transparent;
  color: var(--color-text);
  box-shadow: inset 0 0 0 2px var(--color-text);
}

.nav-repli[open] > summary {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.nav-repli[open] > summary::after {
  background:
    linear-gradient(currentcolor 0 0) center / 100% 2px no-repeat,
    linear-gradient(currentcolor 0 0) center / 2px 100% no-repeat;
  transform: rotate(45deg);
}

/* ── Panneau du menu ────────────────────────────────────────────────────────

   Le défaut corrigé le 26/08 : la liste s'ouvrait DANS la barre, en flux. La
   barre grandissait de 350 px, le nom du cabinet se retrouvait centré au
   milieu d'un grand vide et les liens flottaient sur la page sans fond.

   Le panneau est donc SORTI du flux : il se pose sous la barre, sur un aplat
   crème opaque. `.header` est `sticky`, donc positionné : c'est lui qui sert
   de référence, et `top: 100%` place le panneau sous le filet de palette,
   pas dessus.

   Depuis le 23/09, ce n'est plus un rideau d'un bord à l'autre : il couvrait
   la page entière. C'est un panneau de 20 rem, calé sous le bouton Menu, au
   bord droit de la colonne. */
.nav-repli {
  position: static;
}

.nav-repli > .nav {
  position: absolute;
  top: 100%;
  right: max(var(--marge), calc((100% - var(--colonne)) / 2));
  width: min(20rem, 100% - 2 * var(--marge));
  z-index: 40;
  flex-direction: column;
  align-items: stretch;
  /* `.nav` est en `flex-wrap: wrap` ; en colonne, le wrap fait repartir les
     entrées en une SECONDE colonne dès que `max-height` est atteinte, et
     celles-là sortent du panneau. `nowrap` les garde empilées, le
     `overflow-y` fait le reste. */
  flex-wrap: nowrap;
  gap: 0;
  padding: 0.5rem 1.25rem 1.25rem;
  background: var(--creme);
  /* Bord franc tout autour : sans lui, la crème se fondrait dans la bande de
     la page, et l'on ne verrait plus où le menu s'arrête. */
  border: 2px solid var(--color-text);
  /* `100vh` est le viewport LARGE : barres du navigateur déployées, le bas du
     panneau passe dessous sur iOS. `100dvh` suit la hauteur réellement
     visible. Les deux lignes, dans cet ordre : un navigateur sans `dvh`
     ignore la seconde et garde le comportement d'avant. */
  max-height: calc(100vh - 100%);
  max-height: calc(100dvh - 100%);
  overflow-y: auto;
  /* FERMÉ : relevé de 0,75 rem et transparent. Ce n'est un état VISIBLE
     que le temps de la transition de fermeture — hors d'elle, le <details>
     fermé ne rend pas son contenu. */
  translate: 0 -0.75rem;
  opacity: 0;
  transition:
    translate 0.3s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.2s ease;
}

.nav-repli[open] > .nav {
  translate: 0 0;
  opacity: 1;
}

/* OUVERTURE : sans `@starting-style`, le panneau naîtrait directement dans
   son état ouvert — rien à animer. */
@starting-style {
  .nav-repli[open] > .nav {
    translate: 0 -0.75rem;
    opacity: 0;
  }
}

/* FERMETURE : le navigateur masque le contenu d'un <details> à l'instant où
   il se ferme. `allow-discrete` retarde ce masquage de la durée de la
   transition, le temps que le panneau remonte. Un navigateur sans
   `::details-content` ferme sec, comme avant — rien ne reste affiché. */
.nav-repli::details-content {
  transition: content-visibility 0.3s allow-discrete;
}

/* `*` n'atteint pas `::details-content` : la règle globale de réduction du
   mouvement ne le couvre pas. */
@media (prefers-reduced-motion: reduce) {
  .nav-repli::details-content {
    transition: none;
  }
}

/* Les entrées prennent l'échelle des titres d'élément : capitales sans 600,
   un filet entre chacune, et la ligne se remplit de sa couleur au survol —
   le même geste que l'index des domaines. */
.nav-repli > .nav .nav__item {
  border-top: 1px solid var(--taupe);
}

.nav-repli > .nav .nav__item:last-child {
  border-top: 0;
}

/* La ligne déborde du rembourrage du panneau pour que son aplat de survol
   aille d'un bord à l'autre ; `width: auto` et non `100 %`, sans quoi elle
   ne débordait qu'à gauche. */
.nav-repli > .nav .nav__link {
  display: block;
  width: auto;
  padding: 0.7rem 1.25rem;
  margin-inline: -1.25rem;
  font-size: 0.9375rem;
  letter-spacing: 0.04em;
  border-bottom: 0;
}

.nav-repli > .nav .nav__item:nth-child(5n + 1) {
  --bande: var(--vermillon);
}

.nav-repli > .nav .nav__item:nth-child(5n + 2) {
  --bande: var(--glacier);
}

.nav-repli > .nav .nav__item:nth-child(5n + 3) {
  --bande: var(--miel);
}

.nav-repli > .nav .nav__item:nth-child(5n + 4) {
  --bande: var(--corail);
}

.nav-repli > .nav .nav__item:nth-child(5n + 5) {
  --bande: var(--argile);
}

.nav-repli > .nav .nav__link:hover {
  background: var(--bande);
  border-bottom: 0;
  text-decoration: none;
}

/* Le bouton de contact ferme la liste : rectangle d'encre, aligné à gauche
   comme les entrées, et non étiré sur toute la largeur. */
.nav-repli > .nav .button,
.nav-repli > .nav .button--primary {
  align-self: flex-start;
  margin-top: 1rem;
  min-height: 44px;
  padding: 0.55rem 1.25rem;
  font-size: 0.75rem;
}

/* ── Liens et boutons ───────────────────────────────────────────────────────
   Chez eux, un « bouton » est un lien en capitales avec un chevron. Le
   rectangle plein est réservé à l'action principale — et il n'a pas de rayon. */

.bouton,
.button {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 48px;
  margin-top: 2.25rem;
  padding: 0.65rem 1.6rem;
  border: 2px solid var(--color-primary);
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
}

.bouton::after,
.button::after {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  border-top: 2px solid currentcolor;
  border-right: 2px solid currentcolor;
  transform: rotate(45deg);
}

.bouton:hover,
.button:hover {
  background: var(--vermillon);
  border-color: var(--vermillon);
  color: var(--color-text);
  text-decoration: none;
}

/* Sur une bande de couleur, le survol orange se confondrait avec l'ouverture.
   Le bouton se vide et laisse l'encre sur la bande (6,09:1 sur le vermillon,
   le pire cas des bandes claires). */
.bande-couleur .bouton:hover,
.bande-couleur .button:hover,
.header .bouton:hover,
.header .button:hover {
  background: transparent;
  border-color: var(--color-text);
  color: var(--color-text);
}

.bouton--ghost {
  background: transparent;
  border-color: var(--color-primary);
  color: var(--color-text);
}

.bouton--ghost:hover {
  background: var(--color-text);
  border-color: var(--color-text);
  color: var(--color-background);
}

/* ── Ouverture ──────────────────────────────────────────────────────────────
   L'écran entier, sans photographie : le sable du nuancier, une vague
   qui s'échoue et se retire, et le défilé des domaines. Pas de vidéo —
   demande explicite. `100svh` et non `100vh` : sur mobile, la barre
   d'adresse repliée ne doit pas pousser le bouton hors de l'écran. */

.ouverture {
  position: relative;
  display: grid;
  min-height: calc(100vh - 4rem);
  min-height: calc(100svh - 4rem);
  background: var(--avocat-01);
  container-type: inline-size;
}

.ouverture__texte {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(2.5rem, 4.5vw, 4.5rem) var(--marge);
}

/* Au-dessus de la vague. Pas de z-index négatif sur le décor : Blink
   vide alors la frame en blanc, le temps de rogner un rayon animé. */
.ouverture__texte > :not(.decor) {
  position: relative;
  z-index: 1;
}

.ouverture__texte > .ouverture__titre {
  /* 58 % : sur un téléphone, 14ch irait sous la mer. Les marches 10 à 17
     restent à droite de cette ligne. */
  max-width: min(14ch, 58%);
  font-size: clamp(2.3rem, 1rem + 4.4vw, 5.75rem);
}

/* Le DÉFILÉ. Les six intitulés partagent une seule cellule de grille : la
   hauteur est celle du plus long, rien ne saute quand ils se relaient. Le
   masque est la liste elle-même — une liste, pas une section. */
.defile {
  display: grid;
  max-width: min(22ch, 58%);
  margin: clamp(1.75rem, 3.5vw, 3rem) 0 0;
  padding: 0.12em 0 0.08em;
  overflow: hidden;
  list-style: none;
  border-top: 2px solid var(--color-text);
  font-family: var(--sans);
  font-size: clamp(1.35rem, 0.7rem + 2.6vw, 3.1rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.015em;
  text-transform: uppercase;
}

/* Chaque intitulé occupe la cellule ENTIÈRE, texte calé en bas : `110 %`
   vaut alors la hauteur de la cellule. Calé sur sa seule ligne
   (`align-self: end`), un intitulé court ne sortait que d'une ligne et
   restait visible dans une cellule de deux — chevauchement constaté. */
.defile__item {
  grid-area: 1 / 1;
  display: flex;
  align-items: flex-end;
  translate: 0 110%;
  animation: defiler 18s cubic-bezier(0.76, 0, 0.24, 1) 1.1s infinite both;
}

.defile__item:nth-child(2) { animation-delay: 4.1s; }
.defile__item:nth-child(3) { animation-delay: 7.1s; }
.defile__item:nth-child(4) { animation-delay: 10.1s; }
.defile__item:nth-child(5) { animation-delay: 13.1s; }
.defile__item:nth-child(6) { animation-delay: 16.1s; }

/* Survoler le DÉFILÉ l'arrête : le temps de lire. Pas l'ouverture entière —
   elle tient l'écran, le pointeur s'y pose presque toujours, et le défilé
   restait figé (constaté sous Safari, 23/09). */
.defile:hover .defile__item {
  animation-play-state: paused;
}

/* Moins de mouvement demandé : la règle globale jouerait le cycle en
   0,01 ms et laisserait CHAQUE intitulé à son état final, sorti par le
   haut — une liste vide. Le premier reste donc posé, les autres se taisent. */
@media (prefers-reduced-motion: reduce) {
  .defile__item {
    animation-name: none;
    translate: none;
  }

  .defile__item + .defile__item {
    visibility: hidden;
  }
}

.ouverture .surtitre {
  animation: apparaitre 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.ouverture .surtitre::before {
  background: var(--color-primary);
}

.ouverture__titre {
  margin-top: 1.5rem;
  max-width: 17ch;
  font-family: var(--serif);
  font-size: clamp(2.6rem, 1.1rem + 5.6vw, 6.5rem);
  font-weight: 600;
  line-height: 0.94;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  animation: apparaitre 0.85s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Le titre d'ouverture se compose MOT PAR MOT : il ne s'anime plus en bloc. */
.ouverture__titre {
  animation: none;
}

/* Le masque. Il déborde un peu de la boîte du mot — l'accent de « À » et
   les jambages sortent d'un interligne de 0,94 — et des marges négatives
   rendent ce débord à la ligne, qui garde sa hauteur. */
.mot {
  display: inline-block;
  overflow: hidden;
  padding: 0.14em 0.06em 0.1em;
  margin: -0.14em -0.06em -0.1em;
  vertical-align: top;
}

.mot__in {
  display: inline-block;
  animation: monter 1.1s cubic-bezier(0.22, 1, 0.36, 1) 0.15s both;
}

.mot:nth-child(2) .mot__in { animation-delay: 0.24s; }
.mot:nth-child(3) .mot__in { animation-delay: 0.33s; }
.mot:nth-child(4) .mot__in { animation-delay: 0.42s; }
.mot:nth-child(5) .mot__in { animation-delay: 0.51s; }
.mot:nth-child(6) .mot__in { animation-delay: 0.6s; }
.mot:nth-child(7) .mot__in { animation-delay: 0.69s; }
.mot:nth-child(n + 8) .mot__in { animation-delay: 0.78s; }

/* Le dernier mot passe en italique, casse d'origine : le contrepoint des
   capitales, à la manière d'un « et l'audace ». Spectral n'a d'italique
   qu'en 400 — la graisse suit, plutôt qu'un gras simulé. */
.mot:last-child .mot__in {
  font-style: italic;
  font-weight: 400;
  text-transform: none;
  letter-spacing: -0.01em;
}

.ouverture__chapo {
  max-width: min(40ch, 58%);
  animation: apparaitre 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.7s both;
}

.ouverture .bouton {
  animation: apparaitre 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.85s both;
}

/* Deux actions sous le chapô : le contact reste le rectangle plein,
   la plaquette est le bouton vide. Le retrait du haut est sur la rangée,
   pas sur chaque bouton, pour qu'un retour à la ligne ne double l'écart. */
.ouverture__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 1.25rem;
  row-gap: 0.75rem;
  margin-top: 2.25rem;
}

.ouverture__actions .bouton {
  margin-top: 0;
}

/* Décor : une vague, sans filtre. Safari fige un `feTurbulence` et, avec
   lui, toute animation posée sur le même calque. Le geste est un pendule
   horizontal — `ease-in-out` et `alternate`, aller et retour sur la même
   courbe — et un rayon qui change à chaque palier. WebKit peint les deux.
   Les marches 10 à 17 ne tiennent pas l'encre (l'ambre est à 1,72:1) :
   elles restent à droite des mots.
   `overflow: hidden` sur le calque seul : les nappes débordent, et sans
   ce bord la page défilerait en largeur. Jamais sur la section.
   Blink vide en blanc le calque d'un `transform` dès que le rayon change
   — Chrome et l'aperçu Cursor. Une capture d'écran ne le montre pas.
   Le va-et-vient est donc un `left` et une `width`, peints avec le
   rayon, et le rognage n'a pas de transform. */
.decor {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--avocat-01);
}

.nappe {
  position: absolute;
  display: block;
  animation: var(--geste, aller-sable) var(--duree, 11s) ease-in-out var(--decalage, 0s) infinite alternate;
}

/* Le rayon seul. Pas de transform : le partager avec le déplacement
   fait scintiller le rectangle du calque. */
.nappe__forme {
  position: absolute;
  inset: 0;
  display: block;
  background: var(--encre, transparent);
  border-radius: var(--rayon, 50%);
  animation: var(--contour, contour-sable) var(--duree, 11s) ease-in-out var(--decalage, 0s) infinite alternate;
}

/* Le sable s'étale vers la mer (`--origine: 0`, le bord gauche reste).
   La mousse et la mer s'étalent vers le sable (`--origine: 1`) : la
   largeur gagnée recule le bord gauche, le bord droit ne sort pas.
   `--dx` est un nombre, une fraction de la largeur de la nappe. */
.nappe--sable {
  --geste: aller-sable;
  --contour: contour-sable;
  --rayon: 42% 58% 63% 37% / 48% 52% 44% 56%;
  --dx: -0.06;
  --etalement: 1.06;
  --origine: 0;
}

.nappe--mousse {
  --geste: aller-mousse;
  --contour: contour-mousse;
  --rayon: 28% 72% 64% 36% / 70% 30% 48% 52%;
  --dx: -0.16;
  --etalement: 1.2;
  --origine: 1;
}

.nappe--mer {
  --geste: aller-mer;
  --contour: contour-mer;
  --rayon: 58% 42% 48% 52% / 44% 56% 62% 38%;
  --dx: -0.05;
  --etalement: 1.06;
  --origine: 1;
}

@keyframes aller-sable {
  0% {
    left: var(--gauche, 0%);
    width: var(--largeur, 50%);
  }

  30% {
    left: calc(var(--gauche, 0%) + var(--largeur, 50%) * ((1 - (1 + (var(--etalement, 1.06) - 1) * 0.3)) * var(--origine, 0) + var(--dx, -0.06) * 0.3));
    width: calc(var(--largeur, 50%) * (1 + (var(--etalement, 1.06) - 1) * 0.3));
  }

  62% {
    left: calc(var(--gauche, 0%) + var(--largeur, 50%) * ((1 - (1 + (var(--etalement, 1.06) - 1) * 0.62)) * var(--origine, 0) + var(--dx, -0.06) * 0.62));
    width: calc(var(--largeur, 50%) * (1 + (var(--etalement, 1.06) - 1) * 0.62));
  }

  100% {
    left: calc(var(--gauche, 0%) + var(--largeur, 50%) * ((1 - var(--etalement, 1.06)) * var(--origine, 0) + var(--dx, -0.06)));
    width: calc(var(--largeur, 50%) * var(--etalement, 1.06));
  }
}

@keyframes contour-sable {
  0% { border-radius: 42% 58% 63% 37% / 48% 52% 44% 56%; }
  30% { border-radius: 55% 45% 38% 62% / 60% 40% 58% 42%; }
  62% { border-radius: 36% 64% 52% 48% / 42% 58% 66% 34%; }
  100% { border-radius: 60% 40% 46% 54% / 54% 46% 38% 62%; }
}

@keyframes aller-mousse {
  0% {
    left: var(--gauche, 0%);
    width: var(--largeur, 50%);
  }

  30% {
    left: calc(var(--gauche, 0%) + var(--largeur, 50%) * ((1 - (1 + (var(--etalement, 1.2) - 1) * 0.3)) * var(--origine, 1) + var(--dx, -0.16) * 0.3));
    width: calc(var(--largeur, 50%) * (1 + (var(--etalement, 1.2) - 1) * 0.3));
  }

  62% {
    left: calc(var(--gauche, 0%) + var(--largeur, 50%) * ((1 - (1 + (var(--etalement, 1.2) - 1) * 0.62)) * var(--origine, 1) + var(--dx, -0.16) * 0.62));
    width: calc(var(--largeur, 50%) * (1 + (var(--etalement, 1.2) - 1) * 0.62));
  }

  100% {
    left: calc(var(--gauche, 0%) + var(--largeur, 50%) * ((1 - var(--etalement, 1.2)) * var(--origine, 1) + var(--dx, -0.16)));
    width: calc(var(--largeur, 50%) * var(--etalement, 1.2));
  }
}

@keyframes contour-mousse {
  0% { border-radius: 28% 72% 64% 36% / 70% 30% 48% 52%; }
  30% { border-radius: 66% 34% 22% 78% / 36% 64% 72% 28%; }
  62% { border-radius: 18% 82% 58% 42% / 62% 38% 24% 76%; }
  100% { border-radius: 74% 26% 40% 60% / 30% 70% 56% 44%; }
}

@keyframes aller-mer {
  0% {
    left: var(--gauche, 0%);
    width: var(--largeur, 50%);
  }

  30% {
    left: calc(var(--gauche, 0%) + var(--largeur, 50%) * ((1 - (1 + (var(--etalement, 1.06) - 1) * 0.3)) * var(--origine, 1) + var(--dx, -0.05) * 0.3));
    width: calc(var(--largeur, 50%) * (1 + (var(--etalement, 1.06) - 1) * 0.3));
  }

  62% {
    left: calc(var(--gauche, 0%) + var(--largeur, 50%) * ((1 - (1 + (var(--etalement, 1.06) - 1) * 0.62)) * var(--origine, 1) + var(--dx, -0.05) * 0.62));
    width: calc(var(--largeur, 50%) * (1 + (var(--etalement, 1.06) - 1) * 0.62));
  }

  100% {
    left: calc(var(--gauche, 0%) + var(--largeur, 50%) * ((1 - var(--etalement, 1.06)) * var(--origine, 1) + var(--dx, -0.05)));
    width: calc(var(--largeur, 50%) * var(--etalement, 1.06));
  }
}

@keyframes contour-mer {
  0% { border-radius: 58% 42% 48% 52% / 44% 56% 62% 38%; }
  30% { border-radius: 40% 60% 70% 30% / 66% 34% 42% 58%; }
  62% { border-radius: 72% 28% 36% 64% / 38% 62% 54% 46%; }
  100% { border-radius: 34% 66% 58% 42% / 60% 40% 30% 70%; }
}

/* Plus hautes que le cadre : le calque rogne le haut et le bas, on ne voit
   qu'un front. Une nappe courte se lisait comme une pilule qui glisse. */

/* Sable — les plus claires, sous les mots. L'encre y tient. Leur bord
   droit s'arrête avant la mer : la plage reste visible. */
.nappe--01 {
  top: -42%;
  left: -28%;
  width: 78%;
  height: 184%;
  --gauche: -28%;
  --largeur: 78%;
  --encre: var(--avocat-01);
  --duree: 14s;
  --decalage: -1.2s;
  --dx: -0.04;
  --etalement: 1.04;
}

.nappe--02 {
  top: -30%;
  left: -36%;
  width: 70%;
  height: 170%;
  --gauche: -36%;
  --largeur: 70%;
  --encre: var(--avocat-02);
  --duree: 12s;
  --decalage: -4.8s;
  --dx: -0.06;
  --etalement: 1.06;
}

.nappe--03 {
  top: -50%;
  left: -18%;
  width: 62%;
  height: 190%;
  --gauche: -18%;
  --largeur: 62%;
  --encre: var(--avocat-03);
  --duree: 13s;
  --decalage: -7.4s;
  --dx: -0.05;
  --etalement: 1.05;
}

.nappe--04 {
  top: -24%;
  left: -42%;
  width: 80%;
  height: 164%;
  --gauche: -42%;
  --largeur: 80%;
  --encre: var(--avocat-04);
  --duree: 11s;
  --decalage: -2.6s;
  --dx: -0.07;
  --etalement: 1.08;
}

.nappe--05 {
  top: -46%;
  left: -12%;
  width: 64%;
  height: 186%;
  --gauche: -12%;
  --largeur: 64%;
  --encre: var(--avocat-05);
  --duree: 13.5s;
  --decalage: -9.1s;
  --dx: -0.05;
  --etalement: 1.05;
}

.nappe--06 {
  top: -34%;
  left: -22%;
  width: 72%;
  height: 174%;
  --gauche: -22%;
  --largeur: 72%;
  --encre: var(--avocat-06);
  --duree: 10.5s;
  --decalage: -5.5s;
  --dx: -0.06;
  --etalement: 1.07;
}

/* Mer — les plus profondes, derrière, à droite des mots. Le `left` et la
   course sont calculés pour que le front, échelle comprise, reste au-delà
   de 62 % du cadre. La 17, la plus foncée, est la plus à droite. */
.nappe--12 {
  top: -40%;
  left: 68%;
  width: 70%;
  height: 180%;
  --gauche: 68%;
  --largeur: 70%;
  --encre: var(--avocat-12);
  --duree: 12s;
  --decalage: -1.7s;
  --dx: -0.03;
  --etalement: 1.03;
}

.nappe--13 {
  top: -52%;
  left: 72%;
  width: 64%;
  height: 196%;
  --gauche: 72%;
  --largeur: 64%;
  --encre: var(--avocat-13);
  --duree: 14s;
  --decalage: -5.9s;
  --dx: -0.03;
  --etalement: 1.04;
}

.nappe--14 {
  top: -34%;
  left: 74%;
  width: 58%;
  height: 174%;
  --gauche: 74%;
  --largeur: 58%;
  --encre: var(--avocat-14);
  --duree: 11s;
  --decalage: -3.8s;
  --dx: -0.03;
  --etalement: 1.03;
}

.nappe--15 {
  top: -46%;
  left: 80%;
  width: 52%;
  height: 188%;
  --gauche: 80%;
  --largeur: 52%;
  --encre: var(--avocat-15);
  --duree: 13s;
  --decalage: -10.2s;
  --dx: -0.02;
  --etalement: 1.03;
}

.nappe--16 {
  top: -56%;
  left: 86%;
  width: 48%;
  height: 204%;
  --gauche: 86%;
  --largeur: 48%;
  --encre: var(--avocat-16);
  --duree: 9.5s;
  --decalage: -0.9s;
  --dx: -0.02;
  --etalement: 1.02;
}

.nappe--17 {
  top: -28%;
  left: 91%;
  width: 42%;
  height: 168%;
  --gauche: 91%;
  --largeur: 42%;
  --encre: var(--avocat-17);
  --duree: 12.5s;
  --decalage: -7.7s;
  --dx: -0.02;
  --etalement: 1.02;
}

/* Mousse — liseré du front, entre la plage et la mer. 07 à 09 s'échouent
   sur le sable (l'encre y tient). 10 et 11 restent avec la mer. */
.nappe--07 {
  top: -44%;
  left: 40%;
  width: 36%;
  height: 188%;
  --gauche: 40%;
  --largeur: 36%;
  --encre: var(--avocat-07);
  --duree: 8s;
  --decalage: -0.6s;
  --dx: -0.22;
  --etalement: 1.2;
}

.nappe--08 {
  top: -26%;
  left: 48%;
  width: 30%;
  height: 164%;
  --gauche: 48%;
  --largeur: 30%;
  --encre: var(--avocat-08);
  --duree: 9.5s;
  --decalage: -3.4s;
  --dx: -0.20;
  --etalement: 1.18;
}

.nappe--09 {
  top: -52%;
  left: 44%;
  width: 34%;
  height: 196%;
  --gauche: 44%;
  --largeur: 34%;
  --encre: var(--avocat-09);
  --duree: 8.5s;
  --decalage: -6.8s;
  --dx: -0.22;
  --etalement: 1.2;
}

.nappe--10 {
  top: -36%;
  left: 66%;
  width: 32%;
  height: 176%;
  --gauche: 66%;
  --largeur: 32%;
  --encre: var(--avocat-10);
  --duree: 10s;
  --decalage: -2.1s;
  --dx: -0.04;
  --etalement: 1.04;
}

.nappe--11 {
  top: -48%;
  left: 70%;
  width: 28%;
  height: 190%;
  --gauche: 70%;
  --largeur: 28%;
  --encre: var(--avocat-11);
  --duree: 11s;
  --decalage: -8.3s;
  --dx: -0.04;
  --etalement: 1.04;
}

@media (prefers-reduced-motion: reduce) {
  .nappe {
    animation: none;
  }

  .nappe__forme {
    animation: none;
  }
}

/* ── Domaines d'intervention ────────────────────────────────────────────────
   Leur « OUR SERVICES » : un index. Titres en sans 600 capitales, filets
   horizontaux, et la ligne entière se remplit de sa couleur au survol. Chaque
   ligne porte la sienne, prise dans la palette. */

.expertises {
  position: relative;
  padding-block: var(--souffle);
}

/* Le filet fort de tête est un pseudo-élément et non une bordure : une
   bordure ne se trace pas. `padding-top` lui rend les deux pixels qu'elle
   occupait. Au repos, et sans timeline, il est entier. */
.poles,
.liste {
  position: relative;
  padding-top: 2px;
}

.poles::before,
.liste::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--color-rule-fort);
  transform-origin: left;
}

.poles__item {
  position: relative;
  margin-inline: -1.5rem;
  border-bottom: 1px solid var(--color-rule);
}

/* La rangée ENTIÈRE est le lien — titre, résumé, rang et flèche. Un calque
   `::after` sur le titre laissait la flèche (pseudo de l'item, peinte
   au-dessus, transformée) hors de la cible. */
.poles__lien {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0.75rem 2rem;
  padding: 2rem 1.5rem;
  color: inherit;
  text-decoration: none;
}

.poles__item:nth-child(5n + 1) {
  --bande: var(--vermillon);
}

.poles__item:nth-child(5n + 2) {
  --bande: var(--glacier);
}

.poles__item:nth-child(5n + 3) {
  --bande: var(--miel);
}

.poles__item:nth-child(5n + 4) {
  --bande: var(--argile);
}

.poles__item:nth-child(5n + 5) {
  --bande: var(--corail);
}

.poles__lien:hover,
.poles__lien:focus-visible {
  background: var(--bande);
  text-decoration: none;
}

/* Le rang : un CARRÉ de couleur, encre par-dessus. Au survol de la ligne il
   passe à l'encre pleine — l'inversion qu'ils pratiquent partout. */
.poles__rang {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  height: 3.25rem;
  background: var(--bande);
  color: var(--color-text);
  font-family: var(--sans);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.06em;
}

.poles__lien:hover .poles__rang,
.poles__lien:focus-visible .poles__rang {
  background: var(--color-text);
  color: var(--color-background);
}

.poles__titre {
  font-family: var(--sans);
  font-size: clamp(1.35rem, 1rem + 1.5vw, 2.35rem);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.005em;
  text-transform: uppercase;
}

.poles__resume {
  grid-column: 2;
  margin-top: 0.9rem;
  max-width: 62ch;
  color: var(--color-muted);
  font-size: 1.0625rem;
}

.poles__lien:hover .poles__resume,
.poles__lien:focus-visible .poles__resume {
  color: var(--color-text);
}

.poles__lien::after {
  content: "";
  grid-column: 3;
  grid-row: 1;
  align-self: center;
  width: 0.85rem;
  height: 0.85rem;
  border-top: 2px solid var(--color-text);
  border-right: 2px solid var(--color-text);
  transform: rotate(45deg);
}

.poles__lien:hover::after,
.poles__lien:focus-visible::after {
  transform: translateX(0.5rem) rotate(45deg);
}

/* ── Déclaration ────────────────────────────────────────────────────────────
   Leur « WE WORK WITH THE BIG AND THE SMALL. » : une bande de couleur pleine,
   une phrase énorme, un lien en capitales. Ici c'est l'encart engagements. */

.teaser {
  position: relative;
  padding-block: clamp(4rem, 10vw, 8rem);
  background: var(--ambre);
}

.teaser .section__label::before {
  background: var(--color-background);
}

/* L'ambre #6B2D16 est un brun sombre. L'encre de `.bande-couleur` y
   disparaît : le libellé et le chapô passent au papier (10,14:1). Le
   bouton aussi — le brun principal se fondrait dans la bande. */
.teaser.bande-couleur,
.teaser.bande-couleur .section__label,
.teaser.bande-couleur .teaser__chapo {
  color: var(--color-background);
}

/* Le brun du bouton se fond dans l'ambre (deux bruns). Le rectangle
   passe au papier, l'encre dessus (17,45:1). Au survol il se vide. */
.teaser.bande-couleur .bouton,
.teaser.bande-couleur .button {
  background: var(--color-background);
  border-color: var(--color-background);
  color: var(--color-text);
}

.teaser.bande-couleur .bouton:hover,
.teaser.bande-couleur .button:hover {
  background: transparent;
  border-color: var(--color-background);
  color: var(--color-background);
}

.teaser__chapo {
  max-width: 34ch;
  margin-top: 1.5rem;
  font-family: var(--serif);
  font-size: clamp(1.9rem, 1.1rem + 3.4vw, 4.25rem);
  font-weight: 600;
  line-height: 0.99;
  letter-spacing: -0.015em;
  text-transform: uppercase;
}

/* Deux rectangles d'encre en fond de bande, à droite : ils rappellent le
   décor de l'ouverture sans jamais croiser le texte. */
.teaser::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: clamp(3rem, 9vw, 9rem);
  height: 40%;
  background: var(--miel);
}

.teaser::after {
  content: "";
  position: absolute;
  bottom: 0;
  right: clamp(3rem, 9vw, 9rem);
  width: clamp(2rem, 6vw, 6rem);
  height: 28%;
  background: var(--color-background);
}

.teaser > .mesure {
  position: relative;
  z-index: 1;
}

/* ── Équipe ─────────────────────────────────────────────────────────────────
   Leur « OUR PEOPLE » : des cartes. Fond crème pour la bande, une couleur par
   carte, photo à ras, rôle en capitales fines, nom en capitales grasses. */

.equipe {
  position: relative;
  padding-block: var(--souffle);
  background: var(--creme);
}

/* `align-items: start` : sans lui la grille est en `stretch`, et comme
   `.portrait` porte un aplat de couleur, la carte la plus courte d'une rangée
   s'étire jusqu'à la plus haute et traîne une bande vide. Les corps de profils
   vont de 471 o à 3 678 o — un rapport de 1 à 8 (constaté le 17/09). */
.portraits {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 2rem;
  align-items: start;
}

/* APERÇU (accueil) : photo, nom, rôle. Colonnes plus étroites, puisqu'il n'y a
   plus de biographie à loger — l'accueil passait de 12 écrans à 4.
   `stretch` ici seulement : sans bio, l'aplat DOIT descendre jusqu'au bas de
   la rangée, sinon un rôle de trois lignes (Sarah) laisse les deux autres
   cadres plus courts. Les fiches gardent `start` — un vide coloré sous une
   bio courte serait pire. */
.portraits--apercu {
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1.5rem;
  align-items: stretch;
}

.portrait__lien {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
}

/* Le nom est le seul texte de l'aperçu : il porte le soulignement au survol,
   jamais la couleur seule (doctrine du projet). */
.portrait__lien:hover .portrait__nom,
.portrait__lien:focus-visible .portrait__nom {
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

.portraits--apercu .portrait__lien {
  flex: 1;
}

.portraits--apercu .portrait__nom {
  margin-top: auto;
  font-size: clamp(1rem, 0.9rem + 0.35vw, 1.2rem);
}

/* FICHES (/nos-avocats/) : une personne par rangée. La grille en colonnes
   égalisait des cartes de 813 à 2690 px ; en liste, chacune prend sa hauteur. */
.portraits--fiches {
  grid-template-columns: 1fr;
  gap: 3rem;
}

@media (min-width: 48rem) {
  .portraits--fiches .portrait {
    display: grid;
    grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
    column-gap: 2.5rem;
    align-items: start;
  }

  .portraits--fiches .portrait__photo {
    grid-row: 1 / span 4;
    margin-bottom: 0;
  }

  .portraits--fiches .portrait .attenue,
  .portraits--fiches .portrait__nom,
  .portraits--fiches .portrait__diplomes,
  .portraits--fiches .portrait__bio {
    grid-column: 2;
  }

  /* Une fiche sans photo (Wilfrid Jeandidier) ne laisse pas une colonne vide. */
  .portraits--fiches .portrait:not(:has(.portrait__photo)) .attenue,
  .portraits--fiches .portrait:not(:has(.portrait__photo)) .portrait__nom,
  .portraits--fiches .portrait:not(:has(.portrait__photo)) .portrait__diplomes,
  .portraits--fiches .portrait:not(:has(.portrait__photo)) .portrait__bio {
    grid-column: 1 / -1;
  }
}

/* `overflow: hidden` et non `clip` : la photo se dévoile et zoome au survol
   DANS son cadre. `clip` est, sous WebKit, le `clip-path` de composition
   dont la note de `.bloc` décrit le décalage au défilement. */
.portrait {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bande);
  padding-bottom: 1.75rem;
}

/* Page Équipe : une marche du nuancier par avocat, du plus foncé au plus
   clair. Les huit premières marches (jusqu'à #CB4D1E) sont trop sombres
   pour l'encre ; le blanc y tient (4,55:1 au plus clair de ces huit). */
.portraits--fiches .portrait:nth-child(1) { --bande: var(--avocat-17); }
.portraits--fiches .portrait:nth-child(2) { --bande: var(--avocat-16); }
.portraits--fiches .portrait:nth-child(3) { --bande: var(--avocat-15); }
.portraits--fiches .portrait:nth-child(4) { --bande: var(--avocat-14); }
.portraits--fiches .portrait:nth-child(5) { --bande: var(--avocat-13); }
.portraits--fiches .portrait:nth-child(6) { --bande: var(--avocat-12); }
.portraits--fiches .portrait:nth-child(7) { --bande: var(--avocat-11); }
.portraits--fiches .portrait:nth-child(8) { --bande: var(--avocat-10); }
.portraits--fiches .portrait:nth-child(9) { --bande: var(--avocat-09); }
.portraits--fiches .portrait:nth-child(10) { --bande: var(--avocat-08); }
.portraits--fiches .portrait:nth-child(11) { --bande: var(--avocat-07); }
.portraits--fiches .portrait:nth-child(12) { --bande: var(--avocat-06); }
.portraits--fiches .portrait:nth-child(13) { --bande: var(--avocat-05); }
.portraits--fiches .portrait:nth-child(14) { --bande: var(--avocat-04); }
.portraits--fiches .portrait:nth-child(15) { --bande: var(--avocat-03); }
.portraits--fiches .portrait:nth-child(16) { --bande: var(--avocat-02); }
.portraits--fiches .portrait:nth-child(17) { --bande: var(--avocat-01); }

.portraits--fiches .portrait:nth-child(-n + 8),
.portraits--fiches .portrait:nth-child(-n + 8) .attenue,
.portraits--fiches .portrait:nth-child(-n + 8) .portrait__bio,
.portraits--fiches .portrait:nth-child(-n + 8) a {
  color: var(--color-on-primary);
}

/* Accueil : trois cartes côte à côte. Les trois premières marches du
   nuancier sont trop proches ; on prend trois orangés espacés, tous
   assez clairs pour l'encre. */
.portraits--apercu .portrait:nth-child(1) { --bande: var(--avocat-04); }
.portraits--apercu .portrait:nth-child(2) { --bande: var(--avocat-06); }
.portraits--apercu .portrait:nth-child(3) { --bande: var(--avocat-08); }

.portrait:hover {
  transform: translateY(-0.5rem);
}

/* Au survol, la photo avance d'un cran. `transform`, pas `scale` : la
   propriété `scale` appartient au dévoilement au défilement, et les deux se
   composent au lieu de s'écraser. */
.portrait:hover .portrait__photo {
  transform: scale(1.05);
}

.portrait__photo {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  margin-bottom: 1.5rem;
}

/* Le rôle vient AVANT le nom chez eux : « CO-MANAGING PARTNER » puis le nom.
   Notre gabarit rend le nom d'abord ; l'ordre visuel est rétabli en CSS, et
   l'ordre du DOM — celui que lisent les moteurs et les lecteurs d'écran —
   reste le nom en premier. */
.portrait__nom {
  order: 2;
  padding-inline: 1.5rem;
  font-family: var(--sans);
  font-size: clamp(1.25rem, 1rem + 0.7vw, 1.65rem);
  font-weight: 600;
  line-height: 1.05;
  text-transform: uppercase;
}

.portrait .attenue {
  order: 1;
  padding-inline: 1.5rem;
  margin-bottom: 0.5rem;
  color: var(--color-text);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.portrait__bio {
  order: 3;
  padding-inline: 1.5rem;
  margin-top: 1rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--color-text);
}

/* Le CORPS d'un profil est du HTML repris du WordPress : des paragraphes, des
   rubriques et des listes. La remise à zéro pose `list-style: none` et
   `font-weight: 400` sur les titres, et aucun sélecteur descendant n'existait
   ici : les puces et le rythme manquaient (constaté le 17/09). On reprend la
   grammaire déjà écrite pour `.prose`, à l'échelle de la carte. */
.portrait__bio p + p {
  margin-top: 0.8rem;
}

.portrait__bio h3 {
  margin-top: 1.5rem;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.portrait__bio ul {
  list-style: disc;
  padding-left: 1.2rem;
  margin-top: 0.6rem;
}

.portrait__bio li + li {
  margin-top: 0.3rem;
}

.portrait__bio li::marker {
  color: var(--color-primary);
}

/* Les diplômes s'énumèrent, ils ne se racontent pas : une liste sèche, sous le
   rôle et avant la biographie. */
.portrait__diplomes {
  order: 3;
  padding-inline: 1.5rem;
  margin-top: 1rem;
  list-style: disc;
  padding-left: 2.7rem;
  font-size: 0.875rem;
  line-height: 1.45;
}

.portrait__diplomes li + li {
  margin-top: 0.3rem;
}

.portrait__diplomes li::marker {
  color: var(--color-primary);
}

/* Les puces des huit fiches sombres suivent le texte blanc. Placées après
   les règles générales, sinon le brun du logo se perd sur le fond. */
.portraits--fiches .portrait:nth-child(-n + 8) li::marker {
  color: var(--color-on-primary);
}

.portraits--fiches .portrait__bio,
.portraits--fiches .portrait__diplomes {
  font-size: 1rem;
}

.equipe__suite {
  margin-top: 2.5rem;
}

/* ── Fil d'Ariane ───────────────────────────────────────────────────────────
   Le JSON-LD l'émettait déjà ; il manquait à l'écran. Séparateur DESSINÉ en
   ::before, jamais un caractère dans le gabarit : un lecteur d'écran n'a pas à
   épeler un chevron. */

.fil {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.fil > * + *::before {
  content: "";
  display: inline-block;
  width: 0.55rem;
  height: 0.55rem;
  margin-right: 0.5rem;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  transform: rotate(45deg) translateY(0.05rem);
}

.fil a {
  text-underline-offset: 0.22em;
}

.fil__actuel {
  color: var(--color-muted);
}

/* Le fil est posé sur le ruban de couleur. Le gris atténué y tombe sous
   4,5:1 (2,33:1 sur le vermillon, le pire cas). Tout le fil repasse à
   l'encre, comme sur les autres bandes. */
.entete__ruban .fil,
.entete__ruban .fil__actuel {
  color: var(--color-text);
}

/* ── Renvois de fin de page et index serrés ─────────────────────────────────
   Blocs de MAILLAGE : ils lient sans qu'une phrase soit écrite dans un fichier
   de contenu. Avant eux, le corps de l'accueil ne pointait vers aucune page
   libre, et une page d'article était un cul-de-sac (17/09). */

.renvois {
  padding-block: var(--souffle);
}

.liens-serres {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.5rem;
  margin-top: 1.25rem;
  list-style: none;
  padding-left: 0;
}

.liens-serres a {
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-underline-offset: 0.22em;
}

.apres .liens-serres {
  margin-bottom: 1.25rem;
}

/* ── Questions fréquentes ───────────────────────────────────────────────────
   Rangées à filets, marqueur en croix dessinée. Les DEUX états sont habillés :
   fermé, la rangée est blanche et la croix pleine ; ouvert, la rangée prend sa
   couleur, la croix devient un moins, la réponse arrive (11.18). */

.faq {
  position: relative;
  padding-block: var(--souffle);
}

.question {
  border-top: 1px solid var(--color-rule);
  padding-inline: 1.5rem;
  margin-inline: -1.5rem;
}

.question:last-of-type {
  border-bottom: 1px solid var(--color-rule);
}

.question:nth-of-type(5n + 1) {
  --bande: var(--glacier);
}

.question:nth-of-type(5n + 2) {
  --bande: var(--miel);
}

.question:nth-of-type(5n + 3) {
  --bande: var(--argile);
}

.question:nth-of-type(5n + 4) {
  --bande: var(--corail);
}

.question:nth-of-type(5n + 5) {
  --bande: var(--taupe);
}

.question:hover,
.question[open] {
  background: var(--bande);
}

.question__intitule,
.faq__question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 1.35rem;
  font-family: var(--serif);
  font-size: clamp(1.1rem, 1rem + 0.4vw, 1.35rem);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.question__intitule::-webkit-details-marker {
  display: none;
}

.question__intitule::marker {
  content: "";
}

.question__intitule::after {
  content: "";
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  background:
    linear-gradient(var(--color-text) 0 0) center / 100% 2px no-repeat,
    linear-gradient(var(--color-text) 0 0) center / 2px 100% no-repeat;
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.question[open] .question__intitule::after {
  background: linear-gradient(var(--color-text) 0 0) center / 100% 2px no-repeat;
  transform: rotate(180deg);
}

.question p,
.faq__answer {
  padding-bottom: 1.5rem;
  max-width: 68ch;
  animation: apparaitre 0.35s ease both;
}

.disclaimer {
  max-width: 68ch;
  margin-top: 2.5rem;
  padding-top: 1.25rem;
  border-top: 2px solid var(--color-rule-fort);
  font-size: 0.9375rem;
}

.faq--contact {
  margin-top: 4rem;
}

/* ── Réponse directe (invariant GEO des articles) ───────────────────────── */

.reponse-directe {
  margin-top: 2.5rem;
  padding: 1.75rem;
  background: var(--miel);
  font-family: var(--serif);
  font-size: 1.2rem;
}

/* ── Prose ──────────────────────────────────────────────────────────────── */

/* 62ch et non 68 : le corps de page est en Spectral, dont l'œil est petit ;
   à 68ch la ligne dépassait la fourchette de confort sur les textes longs
   repris du WordPress. */
.prose {
  margin-top: 2.5rem;
  max-width: 62ch;
}

/* Échelle des titres de prose. `.prose h3` valait 1.05rem — 16,8 px — sous un
   corps qui monte à 19 px : un sous-titre PLUS PETIT que le texte qu'il titre.
   Ce n'est pas un goût, c'est une échelle inversée (constaté le 17/09). Les
   capitales et le lettrage sont conservés : seule la taille change. */
.prose h2 {
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 2px solid var(--color-rule-fort);
  font-family: var(--sans);
  font-size: clamp(1.5rem, 1.1rem + 0.8vw, 2.1rem);
  font-weight: 600;
  line-height: 1.1;
  text-transform: uppercase;
}

.prose h3 {
  margin-top: 2rem;
  font-family: var(--sans);
  font-size: clamp(1.15rem, 1.05rem + 0.3vw, 1.3rem);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.prose h2 + p,
.prose h3 + p,
.prose h2 + ul,
.prose h3 + ul {
  margin-top: 1rem;
}

.prose ul,
.prose ol {
  list-style: disc;
  padding-left: 1.35rem;
  margin-top: 1.15rem;
}

/* `p + p` espace deux paragraphes. Une phrase qui suit une liste n'est
   pas dans ce cas : sans ceci, elle se colle au dernier item. */
.prose ul + p,
.prose ol + p {
  margin-top: 1.15rem;
}

.prose ol {
  list-style: decimal;
}

.prose li + li {
  margin-top: 0.45rem;
}

.prose li::marker {
  color: var(--color-primary);
}

/* ── Listes d'articles et cartes ────────────────────────────────────────────
   Leur liste d'actualités : date et catégorie en capitales fines, titre en
   capitales grasses, filet au-dessus. */

.liste {
  margin-top: 3rem;
}

.liste__item {
  padding: 2rem 1.5rem;
  margin-inline: -1.5rem;
  border-bottom: 1px solid var(--color-rule);
}

.liste__item:nth-child(4n + 1) {
  --bande: var(--glacier);
}

.liste__item:nth-child(4n + 2) {
  --bande: var(--miel);
}

.liste__item:nth-child(4n + 3) {
  --bande: var(--argile);
}

.liste__item:nth-child(4n + 4) {
  --bande: var(--corail);
}

.liste__item:hover {
  background: var(--bande);
}

.liste__titre {
  font-family: var(--sans);
  font-size: clamp(1.2rem, 1rem + 1vw, 1.9rem);
  font-weight: 600;
  line-height: 1.06;
  text-transform: uppercase;
}

.liste__titre a {
  text-decoration: none;
  /* Un titre sur deux lignes offrait 44,9 px, un titre court 24 px : la cible
     dépendait de la longueur du texte. En bloc, elle tient toute la largeur
     de l'élément et ne dépend plus de rien. */
  display: flex;
  align-items: center;
  min-height: 44px;
}

.liste__item p {
  margin-top: 0.85rem;
  max-width: 62ch;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 2rem;
  margin-top: 3rem;
}

.card {
  padding: 1.75rem;
  background: var(--bande);
}

.card:nth-child(4n + 1) {
  --bande: var(--glacier);
}

.card:nth-child(4n + 2) {
  --bande: var(--corail);
}

.card:nth-child(4n + 3) {
  --bande: var(--argile);
}

.card:nth-child(4n + 4) {
  --bande: var(--miel);
}

.card:hover {
  transform: translateY(-0.5rem);
}

.card__title {
  font-family: var(--sans);
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.1;
  text-transform: uppercase;
}

.card__text {
  margin-top: 0.85rem;
  font-size: 0.9375rem;
}

.apres,
.pages {
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 2px solid var(--color-rule-fort);
}

.pages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem;
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: var(--lettrage);
  text-transform: uppercase;
}

/* ── Formulaire ─────────────────────────────────────────────────────────────
   Champs à angles vifs, étiquettes en capitales, filet d'encre autour.
   Le remplissage est l'argile, pas le papier : le blanc #FFFBF7 jurait
   sur la crème de la page. L'encre y est à 9,87:1. Le filet clair
   (--color-rule, 2,23:1 sur le papier) ne tient pas le contraste d'un
   composant (WCAG 1.4.11, plancher 3:1) : le trait reste l'encre. */

.formulaire {
  max-width: 44rem;
  padding-top: 1.5rem;
  border-top: 2px solid var(--color-rule-fort);
}

.formulaire .champ:first-child {
  margin-top: 0;
}

.champ {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 1.75rem;
}

.champ label {
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.champ input,
.champ textarea {
  width: 100%;
  min-width: 0;
  padding: 0.8rem 0.9rem;
  border: 2px solid var(--color-rule-fort);
  background: var(--argile);
  font-family: var(--serif);
}

.champ--erreur input,
.champ--erreur textarea {
  border-color: var(--color-primary);
  background: var(--miel);
}

.champ__erreur {
  font-family: var(--sans);
  font-size: 0.875rem;
  font-weight: 600;
}

/* ── En-tête de page intérieure ─────────────────────────────────────────────
   Leur page About ouvre sur deux bandes empilées : une mince qui porte le
   libellé, une haute qui porte le titre. C'est ce que fait ce bloc. */

.page-header {
  position: relative;
}

.page-header__eyebrow {
  margin-bottom: 1.25rem;
}

.bloc:first-of-type,
.section:has(.page-header) {
  padding-top: clamp(2.5rem, 6vw, 5rem);
}

.bloc:first-of-type::before,
.section:has(.page-header)::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: clamp(4rem, 14vw, 14rem);
  height: clamp(4rem, 14vw, 14rem);
  background: var(--bande);
  pointer-events: none;
}

.section > .container,
.bloc > .mesure {
  position: relative;
  z-index: 1;
}

/* ── Entête de page intérieure, en deux bandes ──────────────────────────────
   Leur page About ouvre sur un ruban de couleur qui porte le libellé, puis sur
   une bande plus haute qui porte le titre. Les deux vont d'un bord à l'autre.
   Toutes les pages du cabinet ouvrent ainsi : c'est ce qui donne au site son
   unité, plus encore que la palette. */

.entete {
  display: block;
}

.entete__ruban {
  background: var(--bande);
  padding-block: 1.1rem;
}

/* Dans le ruban, le carré du libellé prendrait la couleur du ruban lui-même :
   il passe donc au brun du logo, sinon il disparaît. */
.entete__ruban .surtitre::before {
  background: var(--color-primary);
}

.entete__corps {
  background: var(--creme);
  padding-block: clamp(2.25rem, 6vw, 4.5rem);
}

/* Teinte de PAGE : posée sur l'élément qui enveloppe tout, elle descend au
   ruban de l'entête comme au carré d'angle du bloc de contenu. Une page, une
   couleur. */
.teinte--vermillon {
  --bande: var(--vermillon);
}

.teinte--glacier {
  --bande: var(--glacier);
}

.teinte--miel {
  --bande: var(--miel);
}

.teinte--argile {
  --bande: var(--argile);
}

.teinte--corail {
  --bande: var(--corail);
}

.entete__corps .chapo {
  margin-top: 1.5rem;
  color: var(--color-text);
}

/* Le bloc de contenu qui SUIT une entête garde son carré d'angle, dans la
   couleur de la page : c'est lui qui tient le grand vide à droite d'une
   colonne de texte étroite. Il disparaît sous 62 rem, où il n'y a plus de
   vide à tenir. */
.entete + .bloc::before {
  top: 0;
  right: 0;
}

@media (max-width: 62rem) {
  .bloc:first-of-type::before,
  .section:has(.page-header)::before {
    display: none;
  }
}

/* ── Pied ───────────────────────────────────────────────────────────────────
   Bande crème, encre noire, colonnes en capitales — leur pied exactement, avec
   le filet de palette en rappel au-dessus. */

.footer {
  position: relative;
  padding-block: clamp(1.75rem, 4vw, 2.75rem) 1.35rem;
  background: var(--creme);
}

.footer::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 6px;
  background: linear-gradient(
    90deg,
    var(--ambre) 0 12.5%,
    var(--avocat-13) 12.5% 25%,
    var(--avocat-11) 25% 37.5%,
    var(--avocat-09) 37.5% 50%,
    var(--taupe) 50% 62.5%,
    var(--vermillon) 62.5% 75%,
    var(--miel) 75% 87.5%,
    var(--glacier) 87.5% 100%
  );
}

.footer__inner {
  display: grid;
  /* Le siège et le second bureau pèsent plus lourd que la liste des
     domaines : la première piste est plus large, les deux partent du
     même haut. Les mentions ne tiennent pas une troisième piste — une
     colonne à deux liens laissait un trou sur toute la hauteur. */
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  column-gap: clamp(2rem, 4vw, 4.5rem);
  row-gap: 0.35rem;
  align-items: start;
}

.footer__col {
  min-width: 0;
}

.footer__col:last-child {
  grid-column: 1 / -1;
  margin-top: 1.15rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--taupe);
}

.footer__heading {
  margin-bottom: 0.35rem;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.footer__identity strong {
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.footer__identity,
.footer__contact,
.footer__hours,
.footer__areas,
.footer-links {
  font-size: 0.8125rem;
  line-height: 1.35;
}

.footer__contact {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem 1.75rem;
  align-items: start;
  margin-top: 0.85rem;
  font-style: normal;
}

.footer__bureau::before,
.footer__hours::before {
  display: block;
  margin-bottom: 0.2rem;
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.footer__bureau::before {
  content: "Paris (cabinet principal)";
}

.footer__hours--annexe {
  margin-top: 0;
}

.footer__hours--annexe::before {
  content: "Marseille (cabinet secondaire)";
}

.footer__bureau > .footer__hours {
  margin-top: 0.35rem;
  color: var(--color-muted);
}

.footer__hours li + li {
  margin-top: 0.15rem;
}

.footer__areas li + li,
.footer-links li + li {
  margin-top: 0;
}

.footer__areas,
.footer-links {
  margin-top: 0.15rem;
}

.footer__col:last-child .footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.75rem;
  margin-top: 0;
}

/* Ailleurs le lien remonte pour serrer une liste. Ici il collerait au
   filet et au copyright : on lui rend sa marge. */
.footer__col:last-child .footer__link {
  margin-block: 0;
}

.footer__link {
  color: var(--color-text);
  /* Le texte seul ne fait que 23 px de haut — sous le plancher de 44 px que
     le projet s'est donné. `inline-flex` étend la CIBLE ; les marges
     négatives resserrent le rythme visuel sans réduire la zone cliquable. */
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  max-width: 100%;
  min-height: 44px;
  margin-block: -0.55rem;
}

.footer__copy {
  margin-top: 0.35rem;
  padding-top: 0;
  border-top: none;
  font-family: var(--sans);
  /* Seule phrase en casse normale de la feuille à 12 px — les autres 0,75 rem
     sont des libellés en capitales, gras et lettrés, qui se lisent bien à
     cette taille. Celle-ci non : 13 px. */
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: var(--color-muted);
}

.footer__legal {
  margin-top: 2.5rem;
}

/* Sous 23,5 rem, le nom et le bouton MENU ne tiennent plus sur une ligne :
   la barre passe à deux rangs et enfle de 81 à 141 px — alors qu'elle est
   COLLANTE, soit 18 % de l'écran confisqués en permanence sur un Android de
   360 px, la largeur la plus répandue. On resserre le lettrage et les marges
   plutôt que de laisser passer à la ligne ; au-dessus de 376 px rien ne
   change. */
@media (max-width: 23.5rem) {
  .header__name {
    gap: 0.5rem;
    font-size: 0.9rem;
    letter-spacing: 0.06em;
  }

  .header__logo {
    width: 1.75rem;
    height: 1.75rem;
  }

  .nav-repli > summary {
    gap: 0.5rem;
    padding-inline: 0.85rem;
    letter-spacing: 0.05em;
  }
}

@media (max-width: 52rem) {
  .footer__inner {
    grid-template-columns: 1fr;
    row-gap: 1.35rem;
  }
}

@media (max-width: 40rem) {
  .footer__contact {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 48rem) {
  .poles__item {
    margin-inline: -1rem;
  }

  .poles__lien {
    grid-template-columns: 3rem minmax(0, 1fr);
    gap: 0.6rem 1.25rem;
    padding-inline: 1rem;
  }

  .poles__lien::after {
    display: none;
  }

  .poles__rang {
    width: 2.5rem;
    height: 2.5rem;
    font-size: 0.8125rem;
  }

  .poles__resume {
    grid-column: 1 / -1;
  }

  .question,
  .liste__item {
    padding-inline: 1rem;
    margin-inline: -1rem;
  }
}
