/* Studio Legal 42 — feuille propre au site. Site AUTONOME : ni base.css ni tokens.
   Écrite à la main (T2), grammaire empruntée à Hermès : du vide, une idée par
   écran, des titres qui portent, une grille irrégulière.
   Aucune ressource externe. Aucun script. */

/* ── Fontes ────────────────────────────────────────────────────────────
   Un site AUTONOME ne reçoit PAS base.css, donc pas non plus ses `@font-face`.
   Cette feuille nommait « Source Serif 4 » et « Source Sans 3 » en tête de ses
   piles sans les déclarer nulle part : la production rendait en Charter et en
   Helvetica, sans qu'aucun test ni aucun contrôle ne le signale. La direction
   visuelle repose sur sa typographie — c'était la perdre en silence.

   Le couple a CHANGÉ le 01/09/2026 : Source Serif 4 / Source Sans 3 est le
   DÉFAUT DE PLATEFORME, et le site d'agence le partageait avec un cabinet
   client. `docs/fonts.md` l'interdit deux fois — « ce n'est pas un état
   livrable » et « ne pas répéter le même couple d'un cabinet à l'autre ». Un
   prospect qui compare deux de nos sites y voyait la même typographie.
   EB Garamond / Archivo : couple « ancien, littéraire » du même document, dont
   les licences attendaient déjà sous docs/licences/.

   Les fichiers vivent dans CE dossier (art. III), et non en référence à
   `/static/fonts/` : un site autonome qui dépendrait d'un actif de plateforme
   verrait son rendu changer sans que son dossier bouge. Chemins relatifs à
   cette feuille, servie depuis /static/sites/studiolegal42/. Aucune requête hors
   du domaine (art. V). Licences : docs/licences/. */
@font-face {
  font-family: "EB Garamond";
  src: url("fonts/ebgaramond-400.5e8f01a6bb12.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "EB Garamond";
  src: url("fonts/ebgaramond-700.e1acce9f96c0.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Archivo";
  src: url("fonts/archivo-400.28fb74b0bc6d.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ── Socle ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
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; }

:root {
  /* VOCABULAIRE FERMÉ. Ces six noms ne sont pas un goût : ce sont ceux que le
     harnais sait confronter aux seuils WCAG (contrôle 4). Un site qui invente
     ses propres noms de couleurs rend la vérification automatique impossible.
     Tout token de couleur SUPPLÉMENTAIRE est permis, mais il échappe au
     contrôle — d'où --color-rule, tenu à l'œil plutôt que par la machine. */
  --color-text:        #14100D;
  --color-background:  #EDE3D1;  /* sable franc, pas un blanc cassé */
  --color-surface:     #E0D2B9;
  --color-primary:     #B03A0F;  /* terre vive — 4,77:1 sur le fond */
  --color-on-primary:  #FEFBF6;
  --color-muted:       #564C42;
  --color-rule:        #C9B896;
  /* EB Garamond a une hauteur d'x BASSE et Archivo une hauteur d'x HAUTE :
     à taille égale, les titres paraissent plus petits et le texte plus gros
     qu'avec le couple précédent. Les tailles ci-dessous ont été reprises en
     conséquence, pas seulement les noms de familles. */
  --serif:    "EB Garamond", "Adobe Garamond Pro", Garamond, Georgia, serif;
  --sans:     "Archivo", "Helvetica Neue", Arial, sans-serif;
  --marge:    clamp(1.5rem, 6vw, 9rem);
  --souffle:  clamp(5rem, 14vw, 13rem);   /* l'air entre deux sections */
  --colonne:  min(100% - 2 * var(--marge), 82rem);
}

body {
  margin: 0;
  background: var(--color-background);
  color: var(--color-text);
  font-family: var(--sans);
  font-size: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
  line-height: 1.65;
  font-synthesis: none;
  /* Curseur dessiné : une flèche en CONTOURS, terracotta. Fichiers du
     dossier, jamais une URL distante.
     Quatre variantes, et chacune a une raison :
       — la flèche seule sur le corps du texte ;
       — la flèche + un disque plein sur ce qui se clique, pour que le
         pointeur distingue encore un lien d'un paragraphe. Poser la MÊME
         image partout est exactement le défaut corrigé le 02/09 ;
       — deux versions claires pour le bandeau de clôture, dont le fond EST
         le terracotta : un curseur terracotta y serait invisible.
     Repli : Safari ne sait pas afficher un curseur SVG et retombe sur
     `auto` / `pointer`, ce qui reste correct. Le hotspot est sur la pointe
     de la flèche, en 2 2 — pas au centre de l'image. */
  cursor: url("img/curseur.da2ba7689182.svg") 2 2, auto;
}

/* Le curseur signé reste sur le CORPS, jamais sur ce qui se clique. Jusqu'au
   02/09/2026 cette règle posait la MÊME image sur les liens que sur le body,
   seul le repli changeant : le pointeur ne variait donc plus entre un
   paragraphe et un lien, et les liens de nav n'ont pas de soulignement pour
   compenser. C'était supprimer l'indice d'interactivité le plus universel du
   web au profit d'une signature qu'on ne voit pas bouger. */
a, button, summary, label { cursor: url("img/curseur-lien.df92bdd2a84a.svg") 2 2, pointer; }
input, textarea, select { cursor: text; }

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

a {
  color: inherit;
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
}
:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 3px; }

/* `.skip-link` vit dans le SOCLE de plateforme (sites/_base/assets/chrome.css)
   depuis le 25/08 : le lien d'évitement est rendu par le layout, sur toutes
   les pages, et son masquage n'est pas un choix de dessin. Deux cabinets en
   avaient écrit deux versions, dont l'une posait un fond sans couleur de
   texte. Le redéclarer ici superposerait deux mécanismes de masquage — c'est
   exactement ce qui l'a rendu invisible au focus pendant une heure. */

/* ── En-tête et pied : rendus par le layout, habillés ici ──────────────── */
.header { padding: 2rem var(--marge); }
.header__inner { display: flex; align-items: baseline; gap: 2rem; flex-wrap: wrap; }
.header__name { font-family: var(--serif); font-size: 1.4rem; letter-spacing: 0.02em; text-decoration: none; }
.header__logo { display: none; }
.nav { display: flex; gap: 1.25rem; flex-wrap: wrap; font-size: 0.875rem; letter-spacing: 0.04em; text-transform: uppercase; align-items: center; }
/* WCAG 2.2 — 2.5.8 « taille de cible » : 24 px CSS au minimum, 44 visés au
   doigt. Ces liens n'avaient aucun rembourrage vertical : leur hauteur
   cliquable était celle du texte, 16 px, mesurée le 02/09/2026 sur toute la
   navigation. Le rembourrage est POSÉ ICI et non dans le gap, pour que la
   surface grandisse au lieu de seulement s'écarter. */
.nav__link, .nav .button {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding-inline: 0.25rem;
  text-decoration: none;
  color: var(--color-muted);
  background-image: linear-gradient(var(--color-primary), var(--color-primary));
  background-size: 0 1px;
  /* Calé sur le TEXTE, pas sur le bas de la boîte : depuis que le lien porte
     une hauteur de cible de 2,75 rem, un `100%` détacherait le trait du mot
     d'une douzaine de pixels. */
  background-position: 0 calc(50% + 0.85em);
  background-repeat: no-repeat;
}
.nav-repli { display: none; }
/* Le socle chrome.css replie dès `nav-repliee`. Ici le seuil reste 52 rem,
   y compris quand la classe est posée : la rangée tient plus longtemps. */
body.nav-repliee .nav-desktop { display: flex; }
body.nav-repliee .nav-repli { display: none; }
@media (max-width: 52rem) {
  .nav-desktop,
  body.nav-repliee .nav-desktop { display: none; }
  /* `text-align: right` et non un `margin-left` sur le résumé : `summary` est
     ici `inline-flex`, et les marges automatiques ne poussent pas un élément
     de niveau inline. Sans cela le déclencheur reste calé au bord gauche du
     bloc, désaligné de sa propre colonne de liens. */
  .nav-repli,
  body.nav-repliee .nav-repli { display: block; margin-left: auto; text-align: right; }
  .nav-repli summary {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    font-size: 0.875rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }
  /* La colonne se cale sur SON déclencheur, à droite. Alignée à gauche, elle
     flottait au milieu de l'écran — ni sur le logo, ni sur le bord — parce
     que le `<details>` est poussé à droite par `margin-left: auto`. Constaté
     en recette le 02/09/2026, après le passage des cibles à 2,75 rem. */
  .nav-repli .nav {
    flex-direction: column;
    align-items: flex-end;
    text-align: right;
    gap: 0.25rem;
    padding-top: 0.5rem;
  }
}

/* ── 1. Ouverture ──────────────────────────────────────────────────────── */
.ouverture { padding: clamp(4rem, 14vw, 12rem) 0 var(--souffle); }
.ouverture .mesure { position: relative; }
.ouverture__titre {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(3.15rem, 1.6rem + 6.9vw, 9rem);
  line-height: 0.94;
  letter-spacing: -0.012em;
  max-width: 16ch;
  text-wrap: balance;
}

/* Constellation : le vide à droite du titre, grand écran seulement. Au
   téléphone le titre occupe déjà tout l'écran ; une décoration par-dessus
   le casserait. Aucune phrase, aucun lien : aria-hidden dans le gabarit. */
.constellation { display: none; }
@media (min-width: 60rem) {
  .constellation {
    display: block;
    position: absolute;
    top: 0.5rem;
    right: 0;
    width: min(22rem, 40%);
    height: 16rem;
    pointer-events: auto;
  }
}
/* Sept formes, une seule règle de base. Aucune couleur littérale : tout passe
   par les tokens, donc par le contrôle de contraste du harnais. */
.forme { position: absolute; background: var(--color-primary); }

/* L'anneau — la forme la plus travaillée, et celle qui donne le ton :
   un contour épais, rien à l'intérieur. */
.forme--anneau {
  width: 8.5rem;
  height: 8.5rem;
  border: 0.32rem solid var(--color-primary);
  background: none;
  border-radius: 50%;
  top: -0.75rem;
  right: 0.5rem;
}
.forme--disque {
  width: 3.1rem;
  height: 3.1rem;
  border-radius: 50%;
  top: 6.25rem;
  right: 6.5rem;
}
/* L'arc : un demi-disque, obtenu par des rayons asymétriques. */
.forme--arc {
  width: 4.6rem;
  height: 2.3rem;
  border-radius: 999px 999px 0 0;
  top: 1.5rem;
  right: 8.75rem;
  background: var(--color-text);
}
/* Le losange : un carré pivoté, dont le pivot sert aussi d'assise à
   l'animation de rotation lente. */
.forme--losange {
  width: 2.6rem;
  height: 2.6rem;
  border: 0.2rem solid var(--color-muted);
  background: none;
  top: 10.5rem;
  right: 10.25rem;
  transform: rotate(45deg);
}
.forme--barre {
  width: 0.85rem;
  height: 6.5rem;
  border-radius: 999px;
  top: 4.25rem;
  right: 12.5rem;
  background: var(--color-muted);
}
.forme--trait {
  width: 7.25rem;
  height: 0.32rem;
  border-radius: 999px;
  top: 14.5rem;
  right: 1.5rem;
}
/* La colonne de points : un dégradé radial répété, zéro balise
   supplémentaire. La couleur reste un token. */
.forme--points {
  width: 0.5rem;
  height: 5.5rem;
  top: 1.25rem;
  right: 13.5rem;
  background: radial-gradient(
    circle at center,
    var(--color-primary) 0 22%,
    transparent 24%
  );
  background-size: 0.5rem 1.1rem;
  background-repeat: repeat-y;
}
.ouverture__chapo {
  margin-top: clamp(2rem, 5vw, 4rem);
  margin-left: auto;
  max-width: 34ch;
  color: var(--color-muted);
  font-size: clamp(1rem, 0.9rem + 0.4vw, 1.25rem);
}
.ouverture__action { margin-top: 2.5rem; margin-left: auto; max-width: 34ch; }
.ouverture__action a:not(.bouton) { font-size: 1.0625rem; }

/* ── 2. La planche photographique, à fond perdu ────────────────────────── */
.planche { margin-bottom: var(--souffle); }
.planche img { width: 100%; max-height: 82vh; object-fit: cover; }

/* ── Titres de section : discrets, ce sont les contenus qui parlent ────── */
.section__titre {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.8125rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-muted);
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--color-rule);
}

/* ── 3. Les offres en escalier — la grille délibérément irrégulière ────── */
.offres { padding-bottom: var(--souffle); }
.escalier { width: var(--colonne); margin-inline: auto; }
.palier { padding: clamp(3rem, 7vw, 6rem) 0; border-bottom: 1px solid var(--color-rule); }
.palier__rang {
  display: block;
  font-family: var(--serif);
  font-size: 1rem;
  color: var(--color-primary);
  margin-bottom: 1rem;
}
.palier__titre {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.2rem, 1.4rem + 3vw, 4.6rem);
  line-height: 1;
  letter-spacing: -0.015em;
}
.palier__titre a { text-decoration: none; }
.palier__resume { margin-top: 1.5rem; max-width: 46ch; color: var(--color-muted); }

/* Le décalage : chaque palier avance un peu plus que le précédent. C'est ce
   qu'aucun token ne sait faire, et c'est tout l'intérêt d'écrire à la main. */
@media (min-width: 60rem) {
  .palier { padding-left: 0; }
  .palier:nth-child(2) { padding-left: 14%; }
  .palier:nth-child(3) { padding-left: 28%; }
  .palier:nth-child(n+4) { padding-left: 42%; }
}

/* La liste des ARTICLES se lit en colonne droite : le décalage est réservé
   aux services de l'accueil, où quatre marches suffisent à le dire. Sept
   articles décalés finiraient tous au même retrait de 42 %, serrés sur la
   moitié droite de la page. Posé APRÈS le bloc des retraits : à spécificité
   égale (0,2,0), c'est l'ordre qui tranche. */
.escalier--droit .palier { padding-left: 0; }

/* ── 4. Les questions ──────────────────────────────────────────────────── */
.questions { padding-bottom: var(--souffle); }
.serie { margin-top: clamp(2.5rem, 6vw, 5rem); }
.serie__q {
  font-family: var(--serif);
  font-size: clamp(1.4rem, 1.1rem + 1vw, 2rem);
  line-height: 1.25;
  padding-top: 2.5rem;
}
.serie__r { margin: 0.85rem 0 2.5rem; max-width: 58ch; color: var(--color-muted); }
.serie__r + .serie__q { border-top: 1px solid var(--color-rule); }

/* ── 5. L'équipe ───────────────────────────────────────────────────────── */
.equipe { padding-bottom: var(--souffle); }
.signatures {
  margin-top: clamp(2.5rem, 6vw, 5rem);
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}
.signature__nom { font-family: var(--serif); font-size: 2rem; line-height: 1.15; }
.signature__role { margin-top: 0.35rem; font-size: 0.8125rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--color-primary); }
.signature__bio { margin-top: 1.25rem; color: var(--color-muted); max-width: 42ch; }

/* ── 6. Clore — LE bandeau de couleur ───────────────────────────────────
   Seule surface du site où le primaire porte du texte, et elle le fait par
   --color-on-primary : la paire est mesurée par le harnais (5,88:1). Partout
   ailleurs la couleur principale ne sert qu'aux filets et aux surtitres. */
.clore {
  background: var(--color-primary);
  color: var(--color-on-primary);
  padding: var(--souffle) 0;
  margin-bottom: 0;
}
/* Le fond de cette section EST le terracotta : le curseur y passe en clair,
   sans quoi il disparaît purement et simplement. */
.clore { cursor: url("img/curseur-clair.405a842caa17.svg") 2 2, auto; }
.clore a,
.clore button,
.clore .bouton { cursor: url("img/curseur-lien-clair.ee8f4939f640.svg") 2 2, pointer; }

/* :not(.bouton) — sans quoi cette règle (0,1,1) bat .bouton--sur-primaire
   (0,1,0) et rend le bouton crème sur crème. */
.clore a:not(.bouton) { color: inherit; }
.clore :focus-visible { outline-color: var(--color-on-primary); }
.clore__phrase {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2rem, 1.15rem + 3.7vw, 5.2rem);
  line-height: 1.02;
  letter-spacing: -0.01em;
  max-width: 20ch;
}
.clore__action { margin-top: 2.5rem; font-size: 1.0625rem; }
.clore__coordonnees { margin-top: clamp(3rem, 6vw, 5rem); font-style: normal; line-height: 2; opacity: 0.86; }

/* ── Pied ────────────────────────────────────────────────────────────────
   Variante servie : colonnes (défaut de plateforme). Sans ces règles le
   pied s'empilait à gauche : le site est autonome, il ne reçoit pas la
   grille de base.css. Le padding horizontal est sur .container, pas ici —
   sinon le pied est rentré deux fois et ne s'aligne plus sur .mesure. */
.footer {
  background: var(--color-surface);
  border-top: 1px solid var(--color-rule);
  padding-block: clamp(3rem, 6vw, 5rem);
  font-size: 0.875rem;
  color: var(--color-muted);
}
.footer__inner {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem) clamp(2rem, 5vw, 4rem);
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  align-items: start;
}
.footer__identity { font-family: var(--serif); font-size: 1.1rem; color: var(--color-text); }
.footer__heading {
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin-bottom: 1rem;
}
.footer__contact, .footer__hours, .footer__areas { font-style: normal; line-height: 1.9; }
.footer__contact, .footer__hours { margin-top: 1.25rem; }
.footer__legal { margin-top: 3rem; padding-top: 1.5rem; border-top: 1px solid var(--color-rule); }
.footer-links { display: flex; gap: 1.5rem; flex-wrap: wrap; }
.footer__col .footer-links { flex-direction: column; gap: 0.15rem; }
/* Même plancher de cible qu'en navigation : ces liens faisaient 16 px de
   haut. Le rembourrage vertical remplace une partie du gap, pour que la
   colonne ne s'allonge pas. */
.footer__link {
  color: inherit;
  display: inline-block;
  padding-block: 0.3rem;
}

/* ── Mouvement : se tait si le visiteur l'a demandé ───────────────────────
   Apparitions au scroll : animation-timeline: view(), zéro script. Sans
   support, les blocs restent simplement visibles — le contenu n'attend pas. */
/* Trois révélations, et non une seule appliquée partout : le mouvement dit
   quelque chose de l'élément qu'il révèle.
     — `apparaitre` : la montée sobre, pour le corps de texte ;
     — `devoiler`   : un rideau vertical, pour les grands titres ;
     — `glisser`    : une entrée latérale, pour l'escalier des services, dont
                      le décalage horizontal est déjà le parti pris. */
@keyframes apparaitre {
  from { opacity: 0; transform: translateY(1.25rem); }
  to { opacity: 1; transform: none; }
}

@keyframes devoiler {
  from { opacity: 0; clip-path: inset(0 0 100% 0); transform: translateY(0.5rem); }
  to { opacity: 1; clip-path: inset(0 0 -0.25em 0); transform: none; }
}

@keyframes glisser {
  from { opacity: 0; transform: translateX(-1.75rem); }
  to { opacity: 1; transform: none; }
}

/* Le flottement des formes passe par `translate` — la propriété INDIVIDUELLE,
   pas `transform`. C'est ce qui permet au survol de garder `transform` pour
   lui : les deux se composent au lieu de s'écraser. Une animation bat
   toujours une transition dans la cascade ; animer `transform` ici aurait
   donc tué la réaction au survol, en silence. */
@keyframes flotter {
  from { translate: 0 0; }
  50%  { translate: 0 -0.85rem; }
  to   { translate: 0 0; }
}

@keyframes flotter-large {
  from { translate: 0 0; }
  50%  { translate: -0.55rem 0.7rem; }
  to   { translate: 0 0; }
}

@media (prefers-reduced-motion: no-preference) {
  a, .bouton, .nav__link, .nav .button, .header__name, summary {
    transition:
      color 220ms ease,
      background-color 220ms ease,
      background-size 220ms ease,
      border-color 220ms ease,
      text-decoration-color 220ms ease,
      text-underline-offset 220ms ease,
      text-decoration-thickness 220ms ease,
      transform 220ms ease;
  }

  /* Le flottement des formes tourne en continu, chacune à son rythme et sur
     sa propre phase : sans ces décalages, sept formes montant à l'unisson
     ressemblent à un seul bloc qui respire. */
  .forme--anneau  { animation: flotter-large 13s ease-in-out infinite; }
  .forme--disque  { animation: flotter 9s ease-in-out infinite 0.4s; }
  .forme--arc     { animation: flotter 11s ease-in-out infinite 1.2s; }
  .forme--losange { animation: flotter-large 15s ease-in-out infinite 0.8s; }
  .forme--barre   { animation: flotter 10s ease-in-out infinite 2s; }
  .forme--trait   { animation: flotter 12s ease-in-out infinite 1.6s; }
  .forme--points  { animation: flotter 14s ease-in-out infinite 0.6s; }

  @supports (animation-timeline: view()) {
    /* La montée sobre : le corps de texte et les blocs de contenu. */
    .serie__q,
    .serie__r,
    .signature,
    .clore__action,
    .clore__coordonnees,
    .reponse-directe,
    .prose > p,
    .prose h3,
    .prose ul,
    .prose ol,
    .table-defilante,
    .pied-article,
    .avertissement,
    .champ,
    .aparte,
    .footer__col {
      animation: apparaitre 0.8s cubic-bezier(0.2, 0.7, 0.2, 1) both;
      animation-timeline: view();
      animation-range: entry 0% entry 55%;
    }

    /* Le rideau : réservé aux titres, qui portent la page. */
    .section__titre,
    .clore__phrase,
    .prose h2 {
      animation: devoiler 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both;
      animation-timeline: view();
      animation-range: entry 0% entry 58%;
    }

    /* L'entrée latérale : l'escalier, et lui seul. */
    .palier {
      animation: glisser 0.85s cubic-bezier(0.2, 0.7, 0.2, 1) both;
      animation-timeline: view();
      animation-range: entry 0% entry 55%;
    }

    /* Un échelonnement RÉEL au scroll. `animation-delay` ne servirait à rien
       ici : sur une timeline de défilement, le délai se compte en
       progression, pas en secondes. On décale donc la PLAGE. */
    .palier:nth-child(2),
    .serie__r + .serie__q { animation-range: entry 8% entry 63%; }
    .palier:nth-child(3),
    .signatures > .signature:nth-child(2) { animation-range: entry 16% entry 71%; }
    .palier:nth-child(n + 4) { animation-range: entry 22% entry 77%; }
  }
}

/* ── Mouvement réduit : on retire le DÉPLACEMENT, pas la vie ──────────────
   Jusqu'au 02/09/2026, tout le mouvement du site vivait sous
   `no-preference` : un visiteur ayant activé « Réduire les animations »
   (macOS : Réglages > Accessibilité > Affichage) ne voyait donc AUCUNE
   animation, pas même un fondu. C'est une lecture trop stricte de la norme.
   Ce que `reduce` demande d'épargner, ce sont les mouvements — translations,
   rotations, zooms, parallaxes — qui déclenchent les troubles vestibulaires.
   Un fondu d'opacité, lui, n'en déclenche pas.
   Les apparitions au défilement sont donc CONSERVÉES ici, en opacité seule
   et sans un pixel de déplacement ; le flottement des formes, qui est un
   vrai mouvement, reste supprimé. */
@keyframes fondre {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  @supports (animation-timeline: view()) {
    .palier,
    .section__titre,
    .clore__phrase,
    .clore__action,
    .clore__coordonnees,
    .serie__q,
    .serie__r,
    .signature,
    .reponse-directe,
    .prose h2,
    .prose h3,
    .prose > p,
    .prose ul,
    .prose ol,
    .table-defilante,
    .pied-article,
    .avertissement,
    .champ,
    .aparte,
    .footer__col {
      animation: fondre 0.6s ease both;
      animation-timeline: view();
      animation-range: entry 0% entry 55%;
    }
  }
}

@media (prefers-reduced-motion: no-preference) and (hover: hover) {
  a:hover {
    color: var(--color-primary);
    text-decoration-color: var(--color-primary);
    text-underline-offset: 0.38em;
  }
  .header__name:hover { color: var(--color-primary); }
  .nav__link:hover, .nav .button:hover {
    color: var(--color-primary);
    background-size: 100% 1px;
  }
  .palier__titre a:hover { color: var(--color-primary); }
  .parcours__lien:hover .parcours__titre { color: var(--color-primary); }
  .footer__link:hover { color: var(--color-primary); }
  .clore a:hover {
    color: inherit;
    text-decoration-color: currentColor;
    text-decoration-thickness: 2px;
    text-underline-offset: 0.38em;
  }
  .bouton:hover { transform: translateY(-0.12rem); }
  /* Le survol se joue sur `transform`, le flottement sur `translate` : les
     deux se composent, la constellation se déploie sans perdre sa
     respiration. La rotation de base du losange est REPRISE dans son état de
     survol — l'omettre le remettrait droit d'un coup. */
  .forme { transition: transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1); }
  .constellation:hover .forme--anneau { transform: translate(0.9rem, -0.9rem) scale(1.05); }
  .constellation:hover .forme--disque { transform: translate(1.4rem, -1.6rem) scale(1.12); }
  .constellation:hover .forme--arc { transform: translate(-1rem, -1.2rem) rotate(-12deg); }
  .constellation:hover .forme--losange { transform: rotate(70deg) scale(1.08); }
  .constellation:hover .forme--barre { transform: translate(-1.2rem, -1.4rem) rotate(9deg); }
  .constellation:hover .forme--trait { transform: translate(1.3rem, 0.6rem) rotate(-7deg); }
  .constellation:hover .forme--points { transform: translate(-0.7rem, 1.1rem); }
}

/* ── Contact ────────────────────────────────────────────────────────────
   Deux colonnes inégales à partir du grand écran : le formulaire porte, la
   colonne d'à-côté commente. Même parti pris d'asymétrie que l'escalier. */
.ouverture--courte { padding-bottom: clamp(3rem, 8vw, 6rem); }
.ouverture__titre--court { font-size: clamp(2.6rem, 1.6rem + 4.6vw, 6.3rem); }

.formulaire { padding-bottom: var(--souffle); }
.formulaire__grille { display: grid; gap: clamp(3rem, 7vw, 6rem); }
@media (min-width: 62rem) {
  .formulaire__grille { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }
}

.champ { margin-bottom: 2rem; }
.champ__etiquette {
  display: block;
  margin-bottom: 0.5rem;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
}
/* La bordure d'un champ est le SEUL indice de la zone de saisie : elle relève
   du contraste non textuel (WCAG 1.4.11, plancher 3:1) et non de la
   décoration. Elle était tracée en --color-rule, mesuré à 1,53:1 sur le fond
   le 02/09/2026 — deux fois trop clair. Le filet passe donc sur
   --color-muted, l'un des six tokens que le harnais CONFRONTE aux seuils
   (6,58:1 sur le fond) : le contrôle couvre désormais cette bordure au lieu
   de la laisser à l'œil. Ne pas la ramener sur --color-rule, qui reste
   réservé aux séparateurs décoratifs. */
.field__input {
  width: 100%;
  padding: 0.9rem 0;
  border: 0;
  border-bottom: 1px solid var(--color-muted);
  background: transparent;
  color: var(--color-text);
  font-family: inherit;
  font-size: 1.0625rem;
  line-height: 1.5;
}
.field__input:hover { border-bottom-color: var(--color-text); }
.field__input:focus-visible { outline: 0; border-bottom: 2px solid var(--color-primary); }
textarea.field__input { resize: vertical; }
.champ--faute .field__input { border-bottom-color: var(--color-primary); }
.champ__faute { display: block; margin-top: 0.5rem; font-size: 0.9375rem; color: var(--color-primary); }

/* DOCTRINE (AGENTS.md § 3) : « la couleur principale ne porte JAMAIS de texte —
   elle trace et remplit les boutons, où elle s'associe à --color-on-primary ».
   Cette feuille faisait l'inverse jusqu'au 01/09/2026 : le bouton était rempli
   de --color-text, et ne devenait primaire qu'AU SURVOL. L'état de repos
   contredisait la règle, l'état de survol l'appliquait — le seul état qu'un
   visiteur au clavier ou au doigt ne voit jamais.
   La paire primaire / sur-primaire est l'une des six que le harnais mesure. */
.bouton {
  display: inline-block;
  padding: 1rem 2.5rem;
  border: 1px solid var(--color-primary);
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-family: inherit;
  font-size: 0.9375rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
}
.bouton:hover { background: var(--color-text); border-color: var(--color-text); color: var(--color-background); }

/* Sur le bandeau de clôture, le fond EST déjà le primaire : un bouton primaire
   y serait invisible. On inverse la même paire mesurée, on n'en introduit pas
   une septième. */
.bouton--sur-primaire {
  border-color: var(--color-on-primary);
  background: var(--color-on-primary);
  color: var(--color-primary);
}
.bouton--sur-primaire:hover {
  background: transparent;
  border-color: var(--color-on-primary);
  color: var(--color-on-primary);
}

.aparte { padding-top: 0.5rem; }
.aparte__avis { color: var(--color-muted); max-width: 40ch; }
.aparte__coordonnees,
.aparte__horaires { margin-top: 2.5rem; font-style: normal; line-height: 2; color: var(--color-muted); }

/* ── Pages intérieures ──────────────────────────────────────────────────── */
.surtitre {
  font-size: 0.8125rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-primary);
  margin-bottom: 1.25rem;
}
.corps { padding-bottom: var(--souffle); }

.prose { max-width: 62ch; }
.prose > * + * { margin-top: 1.35em; }
.prose h2 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.7rem, 1.25rem + 1.6vw, 2.6rem);
  line-height: 1.2;
  margin-top: 2.5em;
}
.prose h3 { font-family: var(--serif); font-weight: 400; font-size: 1.55rem; margin-top: 2em; }
.prose ul, .prose ol { padding-left: 1.4em; }
.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
.prose li + li { margin-top: 0.5em; }
/* Archivo n'est chargée QU'EN 400, et `font-synthesis: none` (body) interdit
   le faux gras : `font-weight: 600` rendait au pixel près comme 400, et les
   amorces de /notre-offre/ et /a-propos/ ne se distinguaient pas du texte.
   Mesuré le 01/09/2026 — largeur identique à la décimale. On emploie donc la
   graisse qu'on POSSÈDE : EB Garamond 700, en amorce. Ne pas remettre un
   `font-weight` sans le fichier qui va avec. */
.prose strong {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 1.08em;
  letter-spacing: -0.005em;
}

/* ── Tableaux de la prose ────────────────────────────────────────────────
   Un site AUTONOME n'habille que ce qu'il déclare : la grille tarifaire de
   /notre-offre/ rendait sans filets ni rythme avant le 02/09/2026, faute de
   toute règle ici. Le conteneur défile seul plutôt que de pousser la page
   au débordement horizontal sur un téléphone. */
.table-defilante { overflow-x: auto; }
.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}
.prose caption {
  text-align: left;
  padding-bottom: 0.9rem;
  color: var(--color-muted);
  font-size: 0.875rem;
}
.prose th,
.prose td {
  text-align: left;
  vertical-align: top;
  padding: 0.9rem 1.25rem 0.9rem 0;
  border-bottom: 1px solid var(--color-rule);
}
.prose thead th {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.prose tbody th {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.2rem;
  line-height: 1.3;
}
/* Les montants s'alignent chiffre à chiffre d'une ligne à l'autre. */
.prose td { font-variant-numeric: tabular-nums; }

/* ── /notre-offre/ : les trois portes d'entrée, zéro script ──────────────
   L'équivalent d'un sélecteur « où en êtes-vous ? » sans configurateur :
   trois liens pleins, un par situation, chacun menant à une PAGE — donc à
   une adresse qu'un moteur de réponse sait citer. Même grammaire que
   l'escalier de l'accueil : filets, serif, prix en chiffres tabulaires.
   Comme les titres de l'escalier, le lien ne se souligne pas : la carte
   entière est la cible, et le survol la colore. */
.prose .parcours { list-style: none; padding-left: 0; }
.prose .parcours .parcours__item + .parcours__item { margin-top: 0; }
.parcours__item { border-top: 1px solid var(--color-rule); }
.parcours__item:last-child { border-bottom: 1px solid var(--color-rule); }
.parcours__lien { display: block; padding: 1.6rem 0 1.9rem; text-decoration: none; }
.parcours__situation { font-size: 0.9375rem; color: var(--color-muted); }
.prose .parcours .parcours__titre {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.65rem, 1.25rem + 1.5vw, 2.4rem);
  line-height: 1.08;
  margin: 0.4rem 0 0.65rem;
}
.parcours__prix { font-size: 0.9375rem; color: var(--color-muted); font-variant-numeric: tabular-nums; }

/* ── Réalisations : la fenêtre de navigateur ─────────────────────────────
   Un aperçu du site montré, SANS iframe : charger un autre domaine dans la
   page violerait la souveraineté que le site vend (art. V). La capture est
   un fichier du dossier, posé dans un cadre de fenêtre dessiné ici. Le nom
   du fichier est DATÉ : /static se sert immutable en production, remplacer
   une capture passe donc par un nouveau nom, jamais par une réécriture. */
.fenetre {
  border: 1px solid var(--color-muted);
  background: var(--color-surface);
}
.fenetre__barre {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 1rem;
  border-bottom: 1px solid var(--color-rule);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: var(--color-muted);
}
/* Les trois pastilles : une seule boîte, deux ombres portées. Les couleurs
   restent des tokens, comme partout. */
.fenetre__pastilles {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--color-primary);
  box-shadow: 0.95rem 0 0 var(--color-muted), 1.9rem 0 0 var(--color-rule);
  margin-right: 1.6rem;
}
.fenetre__lien { display: block; }
.fenetre img { width: 100%; }
.fenetre__legende {
  padding: 0.7rem 1rem;
  border-top: 1px solid var(--color-rule);
  font-size: 0.875rem;
  color: var(--color-muted);
}

/* La réponse directe ouvre l'article : c'est le bloc que citent les moteurs.
   Elle se distingue par un filet épais côté texte, jamais par un fond de
   couleur principale — la doctrine tient. */
.reponse-directe {
  border-left: 3px solid var(--color-primary);
  padding: 0.25rem 0 0.25rem 1.75rem;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
  max-width: 62ch;
}
.reponse-directe__texte {
  font-family: var(--serif);
  font-size: clamp(1.3rem, 1.1rem + 0.7vw, 1.7rem);
  line-height: 1.45;
}

.pied-article {
  margin-top: clamp(3rem, 6vw, 5rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--color-rule);
  max-width: 62ch;
}
.pied-article__meta { font-size: 0.9375rem; color: var(--color-muted); }
.pied-article__meta + .pied-article__meta { margin-top: 0.5rem; }

.avertissement {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding: 1.25rem 1.5rem;
  background: var(--color-surface);
  color: var(--color-muted);
  font-size: 0.9375rem;
  max-width: 62ch;
}

.pagination {
  display: flex;
  gap: 2rem;
  align-items: baseline;
  padding-top: clamp(2.5rem, 5vw, 4rem);
  font-size: 0.9375rem;
}
.pagination__etat { color: var(--color-muted); }

/* ── Pages LÉGALES — servies par le gabarit de plateforme ────────────────
   Mentions légales et politique de confidentialité ne sont pas des surfaces
   de design : leur structure est dictée par la loi et identique chez tous les
   clients. Les recopier dans ce dossier ferait diverger un texte juridique
   d'un site à l'autre, pour un gain esthétique nul. On les habille, on ne les
   réécrit pas — d'où ces sélecteurs, seuls vestiges du vocabulaire de
   base.css dans cette feuille. */
.section { padding-bottom: var(--souffle); }
.container { width: var(--colonne); margin-inline: auto; }
.container--narrow { max-width: 62ch; }
.page-header { padding: clamp(4rem, 10vw, 8rem) 0 clamp(2rem, 4vw, 3rem); }
.page-header__eyebrow {
  font-size: 0.8125rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-primary);
  margin-bottom: 1.25rem;
}
.page-header__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.6rem, 1.6rem + 4.6vw, 6.3rem);
  line-height: 0.98;
  letter-spacing: -0.011em;
}
.lede { color: var(--color-muted); max-width: 46ch; margin-top: 1.5rem; }
