/* ══ REPÈRE MAINTENANCE ═════════════════════════════════════════════════
   Extension de home-v2.css, jamais un second système. Même règle que les
   guides Loi 25 : aucune police, aucun rayon, aucune durée, aucun point de
   rupture qui ne soit déjà dans la feuille d'accueil. Ce fichier ne fait
   que donner une forme aux objets que l'accueil n'a pas — l'espace client,
   le tableau des forfaits, les réserves, le formulaire de demande.

   Il se charge TOUJOURS après home-v2.css, dont il réutilise les jetons,
   les composants (.hero, .section-heading, .method-flow, .offer, .family,
   .closing, .button) et les images-clés de mouvement (lever, compter).

   LE BRONZE. Maintenance garde une teinte propre, mais en accent SECOND :
   le vert de la famille porte les boutons, les liens et les titres ; le
   bronze ne marque que ce qui appartient au service — le sur-titre, les
   numéros d'étape, la barre de temps utilisé. Un visiteur doit voir un
   site Repère d'abord, et un site Maintenance ensuite.
   ═════════════════════════════════════════════════════════════════════ */

:root {
  /* L'ACCENT. Maintenance garde sa couleur : le bronze prend la place du
     vert partout où l'accueil pose son accent — boutons, liens, focus,
     flèches, numéros d'étape. On reteinte les trois jetons d'accent plutôt
     que de reprendre un à un les vingt et un composants qui s'en servent :
     une seule source, aucune dérive possible.

     Le reste du nuancier ne bouge pas. Les papiers, l'encre, le marine du
     bas de page et le jaune du surligneur restent ceux de l'accueil — c'est
     là que se lit l'appartenance à la famille, et le surligneur en est la
     signature.

     Contrastes mesurés : blanc sur #8a5a2b donne 5,80:1, blanc sur le
     survol 6,54:1, et le bronze sur le papier 5,30:1. Tous au-dessus du
     seuil AA pour du texte courant. */
  --green: #8a5a2b;
  --green-dark: #6d4620;
  --green-light: #f0e5d6;

  /* Alias lisibles, pour que le reste de cette feuille dise « bronze »
     quand elle parle de bronze. */
  --bronze: var(--green);
  --bronze-fonce: var(--green-dark);
  --bronze-voile: var(--green-light);
}

/* Le survol des boutons pleins mérite sa propre teinte. Assombrir le bronze
   le désature : #6d4620 tombe à 55 % de saturation et se lit comme un brun
   mat sur une surface pleine. Celle-ci perd trois points de clarté et en
   gagne neuf en saturation — elle s'assombrit sans se ternir. Blanc dessus :
   6,54:1. --green-dark reste réservé au texte, où son contraste sert. */
.maintenance-page .button:hover { background: #82521f; }

/* ── Les petits libellés ─────────────────────────────────────────────── */

/* Même correction que sur les guides : Public Sans, casse naturelle, pas
   d'interlettrage. Le sur-titre prend le bronze — c'est le seul endroit du
   haut de page où le service se nomme en couleur. */
.maintenance-page .eyebrow {
  color: var(--bronze);
  font-family: var(--text);
  font-size: 0.86rem;
  font-weight: 650;
  letter-spacing: 0;
  text-transform: none;
}

/* Les numéros d'étape suivent la même correction que les guides : Public
   Sans, chiffres tabulaires, plus de monospace. Ils prennent le bronze —
   c'est le second endroit, avec le sur-titre, où le service se signe. */
.maintenance-page .method-flow li::before {
  color: var(--bronze);
  font-family: var(--text);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
}

/* Le déroulement compte quatre étapes, l'accueil en dessine trois. Même
   gouttière, même filet : seule la répartition change, et seulement à
   partir de la largeur où quatre colonnes tiennent. */
/* L'accueil dessine trois étapes et leur donne un titre de 2,35 rem : à
   quatre étapes empilées sur téléphone, cette échelle ajoute près de deux
   cents pixels sans rien dire de plus. Le titre descend d'un cran, la
   hiérarchie reste — le numéro et le filet la portent déjà. */
.maintenance-page .method-flow h3 { font-size: clamp(1.32rem, 2vw, 1.7rem); }

@media (min-width: 961px) {
  .maintenance-page .method-flow { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (min-width: 721px) and (max-width: 960px) {
  .maintenance-page .method-flow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── Réservé aux lecteurs d'écran ────────────────────────────────────── */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── Le problème ─────────────────────────────────────────────────────── */

.constats-entretien {
  display: grid;
  margin: 0;
  padding: 0;
  gap: 0;
  list-style: none;
}

.constats-entretien li {
  padding: clamp(20px, 2.2vw, 28px) 0;
  border-top: 1px solid var(--line);
}

.constats-entretien li:last-child { border-bottom: 1px solid var(--line); }

.constats-entretien b {
  display: block;
  margin-bottom: 6px;
  color: var(--ink);
  font-family: var(--display);
  font-size: clamp(1.05rem, 1.6vw, 1.18rem);
  font-weight: 600;
}

.constats-entretien p {
  max-width: 62ch;
  margin: 0;
  color: var(--body);
}

/* ── Ce qui est pris en charge ───────────────────────────────────────── */

.charges {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
  gap: clamp(24px, 2.6vw, 38px);
}

.charge {
  display: flex;
  flex-direction: column;
  padding: clamp(26px, 2.6vw, 34px);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--white);
}

.charge h3 {
  margin: 0 0 10px;
  color: var(--ink);
  font-family: var(--display);
  font-size: clamp(1.1rem, 1.7vw, 1.24rem);
  font-weight: 600;
}

.charge p { margin: 0; color: var(--body); }

/* ── Le rythme vertical ──────────────────────────────────────────────── */

/* « .reserves » n'est pas un composant de l'accueil et n'héritait donc
   d'aucune respiration : elle prenait la cadence de son seul titre et se
   collait à ses voisines. Même clamp que « .method ». */
.reserves { padding: clamp(84px, 7vw, 108px) 0; }

/* Les guides reprennent la liste des réserves, à dessein : c'est le
   composant le plus sobre de la page, et cette section ne doit pas
   concurrencer les forfaits. Fond blanc pour la détacher sans l'alourdir. */
/* Section secondaire : elle indique le cluster, elle ne le vend pas. Sa
   respiration est donc plus courte que celle des sections principales, et
   le titre suffit sans phrase d'introduction. */
.guides-maintenance {
  padding: clamp(56px, 4.6vw, 72px) 0;
  background: var(--white);
}

.guides-maintenance .section-heading { margin-bottom: clamp(26px, 2.4vw, 34px); }

.guides-maintenance .reserves-liste li { padding: clamp(13px, 1.5vw, 17px) 0; }

.guides-maintenance .reserves-liste b a {
  color: var(--ink);
  text-decoration-color: var(--line);
  text-underline-offset: 3px;
}

.guides-maintenance .reserves-liste b a:hover { color: var(--bronze); }

/* ── Le carnet dans le hero ──────────────────────────────────────────── */

/* L'accueil met une photo à droite du titre. Ici c'est le carnet : montrer
   ce que Repère fait vaut mieux que de le raconter, et un carnet honnête
   vaut mieux qu'une photo d'illustration. La figure garde le bloc jaune
   décalé et l'entrée en scène de l'accueil ; seul l'enfant change. */
.hero-carnet .portail-cadre {
  position: relative;
  z-index: 1;
  box-shadow: 0 20px 48px -22px rgba(13, 53, 39, 0.35);
}

/* Le bloc jaune décalé de l'accueil se cale sur la figure. Ici la figure
   porte aussi une légende, et le bloc se retrouvait soixante pixels sous le
   carnet, flottant tout seul. Il passe donc sur un conteneur qui n'entoure
   que le carnet, et la légende cesse de le déplacer. */
.hero-carnet::before { content: none; }

.hero-carnet-bloc { position: relative; }

.hero-carnet-bloc::before {
  position: absolute;
  right: -18px;
  bottom: -18px;
  width: 42%;
  height: 38%;
  background: var(--yellow);
  content: "";
}

/* L'accueil rentre son bloc sous 720 px, sinon il sort de la fenêtre : à
   375 px la colonne fait 351, et dix-huit pixels de débord la poussent à
   381. Le conteneur reprend l'ajustement, qu'il n'hérite plus depuis qu'il
   ne porte plus la classe .hero-art. */
@media (max-width: 720px) {
  .hero-carnet-bloc::before { right: -8px; bottom: -10px; }
}

.hero-carnet figcaption {
  position: relative;
  z-index: 1;
  margin-top: 18px;
  color: var(--muted);
  font-size: 0.86rem;
  max-width: 46ch;
}

/* Dans un hero, le carnet se resserre : moins de souffle qu'en pleine
   section, pour que le titre garde la priorité de lecture. */
.hero-carnet .portail-tete,
.hero-carnet .portail-pied { padding: 18px 22px; }

.hero-carnet .portail-lignes li { padding: 0 22px; }

@media (min-width: 721px) {
  .hero-carnet .portail-lignes { --rangee: 74px; }
}

/* ── L'espace client ─────────────────────────────────────────────────── */

/* Représentation du portail réel : un site suivi, des demandes qui portent
   un numéro et un statut, des interventions datées, un temps utilisé. Les
   libellés sont neutres à dessein — aucun nom de client, aucun chiffre
   présenté comme une performance. C'est la forme du produit, pas une
   démonstration commerciale. */

.portail-cadre {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-surface);
  background: var(--white);
}

.portail-tete {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  padding: clamp(18px, 2vw, 24px) clamp(20px, 2.4vw, 30px);
  border-bottom: 1px solid var(--line);
  gap: 8px 20px;
}

.portail-site {
  color: var(--ink);
  font-family: var(--display);
  font-size: 1.02rem;
  font-weight: 600;
}

.portail-periode {
  color: var(--muted);
  font-size: 0.88rem;
  font-variant-numeric: tabular-nums;
}

/* La liste ne respire pas. Trois rangées de hauteur fixe, et ce qui déborde
   est coupé : sans cela le cadre grandissait de 178 px et rétrécissait à
   chaque tour, pour deux raisons cumulées — la ligne sortante cohabite un
   instant avec l'entrante, ce qui en fait quatre, et le texte des rangées
   ne se renvoie pas à la ligne au même endroit. Un cadre qui change de
   taille pendant qu'on le lit annule tout le calme qu'on cherche. */
.portail-lignes {
  --rangee: 106px;
  height: calc(3 * var(--rangee));
  margin: 0;
  padding: 0;
  overflow: hidden;
  list-style: none;
}

.portail-lignes li {
  display: grid;
  height: var(--rangee);
  align-content: center;
  align-items: baseline;
  padding: 0 clamp(20px, 2.4vw, 30px);
  border-bottom: 1px solid var(--line);
  gap: 4px 18px;
  grid-template-columns: 92px minmax(0, 1fr) auto;
  overflow: hidden;
}

.portail-date,
.portail-duree {
  color: var(--muted);
  font-size: 0.86rem;
  font-variant-numeric: tabular-nums;
}

.portail-duree { text-align: right; }

.portail-objet { color: var(--ink); }

.portail-objet {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

.portail-objet span {
  display: block;
  overflow: hidden;
  margin-top: 2px;
  color: var(--muted);
  font-size: 0.86rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Le temps utilisé. La barre est la seule animation propre à Maintenance :
   elle se remplit une fois, à l'entrée dans le champ de vision, et son état
   d'arrivée est celui du repos. */
.portail-pied {
  display: grid;
  padding: clamp(18px, 2vw, 24px) clamp(20px, 2.4vw, 30px);
  gap: 10px;
}

.portail-mesure {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}

.portail-mesure span { color: var(--muted); font-size: 0.9rem; }

.portail-mesure b {
  color: var(--ink);
  font-family: var(--display);
  font-size: 1.06rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  /* Une durée ne se coupe pas : « 1 h 30 sur 2 h » passait à la ligne
     entre le 2 et son unité. */
  white-space: nowrap;
}

/* Sur téléphone, le libellé et la durée ne tiennent plus côte à côte sans
   que l'un des deux se serre. Ils s'empilent, la durée dessous. */
@media (max-width: 720px) {
  .portail-mesure { display: grid; gap: 2px; }
}

.portail-jauge {
  overflow: hidden;
  height: 6px;
  border-radius: 999px;
  background: var(--paper-deep);
}

.portail-jauge i {
  display: block;
  /* La part est une valeur de la feuille et non du balisage : « style-src
     'self' » interdit les attributs de style en ligne, et il a raison. */
  width: 75%;
  height: 100%;
  border-radius: inherit;
  background: var(--bronze);
}

@media (prefers-reduced-motion: no-preference) {
  .portail-jauge i {
    animation: remplir 1.1s var(--ease-out) both;
    animation-timeline: view();
    animation-range: entry 12% cover 34%;
  }

  .sans-vue-native .portail-jauge i { animation: none; }
  .sans-vue-native .est-vu .portail-jauge i { animation: remplir 1.1s var(--ease-out) both; }
}

@keyframes remplir {
  from { transform: scaleX(0); transform-origin: left center; }
  to { transform: scaleX(1); transform-origin: left center; }
}

.portail-note {
  margin: clamp(18px, 2vw, 26px) 0 0;
  max-width: 68ch;
  color: var(--muted);
  font-size: 0.92rem;
}

/* ── Les forfaits ────────────────────────────────────────────────────── */

/* Un tableau, et non trois cartes : ce que le visiteur veut faire ici est
   comparer ligne à ligne, ce que trois colonnes séparées empêchent. */

.forfaits-cadre {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-surface);
  background: var(--white);
}

.forfaits-table {
  width: 100%;
  border-collapse: collapse;
  min-width: 620px;
}

.forfaits-table th,
.forfaits-table td {
  padding: clamp(14px, 1.5vw, 18px) clamp(14px, 1.6vw, 22px);
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}

.forfaits-table tbody tr:last-child th,
.forfaits-table tbody tr:last-child td { border-bottom: 0; }

.forfaits-table thead th {
  border-bottom: 1px solid var(--ink);
  color: var(--ink);
  font-family: var(--display);
  font-size: clamp(1.02rem, 1.5vw, 1.15rem);
  font-weight: 600;
}

.forfaits-table tbody th {
  width: 30%;
  color: var(--muted);
  font-size: 0.92rem;
  font-weight: 500;
}

.forfaits-table td {
  color: var(--body);
  font-variant-numeric: tabular-nums;
}

.forfaits-table td b { color: var(--ink); font-weight: 600; }

.forfait-courant {
  display: block;
  margin-top: 4px;
  color: var(--bronze);
  font-size: 0.84rem;
  font-weight: 600;
}

/* ── Adoucir la lecture du tableau ───────────────────────────────────── */

/* Un tableau de sept lignes sur trois colonnes se lit mal quand rien ne
   guide l'œil : on perd sa ligne en traversant, et rien ne dit par où
   commencer. Trois gestes, aucun décoratif.

   1. Une teinte très légère une ligne sur deux. Elle ne se voit pas
      vraiment, elle se sent : le regard garde sa ligne jusqu'au bout.
   2. La colonne recommandée est posée sur son propre fond, du bronze très
      dilué, et coiffée d'un filet. C'est le seul endroit où l'œil doit
      atterrir en premier.
   3. Les intitulés de ligne se détachent du corps du tableau par un filet
      vertical, pour qu'on sache toujours de quoi parle la valeur qu'on lit. */

.forfaits-table tbody tr:nth-child(odd) td,
.forfaits-table tbody tr:nth-child(odd) th { background: rgba(16, 37, 28, 0.022); }

.forfaits-table tbody th { border-right: 1px solid var(--line); }

.forfaits-table thead th:nth-child(3),
.forfaits-table tbody td:nth-child(3) { background: rgba(138, 90, 43, 0.05); }

.forfaits-table tbody tr:nth-child(odd) td:nth-child(3) { background: rgba(138, 90, 43, 0.075); }

.forfaits-table thead th:nth-child(3) {
  border-top: 2px solid var(--bronze);
  border-bottom-color: var(--bronze);
}

/* Le coin supérieur du tableau reste net : la colonne teintée ne doit pas
   déborder du rayon du cadre. */
.forfaits-table thead th:nth-child(3) { border-radius: 0; }

.forfaits-table tbody tr:last-child td:nth-child(3) { padding-bottom: clamp(18px, 1.9vw, 24px); }

.forfaits-note {
  margin: clamp(20px, 2.2vw, 28px) 0 0;
  max-width: 68ch;
  color: var(--body);
}

.forfaits-note b { color: var(--ink); }

/* L'indication de glissement ne paraît qu'aux largeurs où le tableau
   dépasse réellement son cadre. Au-dessus, elle mentirait. Déclarée avant
   la requête média qui l'affiche : l'inverse l'annulerait, à spécificité
   égale c'est l'ordre du fichier qui tranche. */
.forfaits-glisser {
  display: none;
  margin: 12px 0 0;
  color: var(--muted);
  font-size: 0.86rem;
}

/* Sur téléphone, une largeur minimale de 620 px transforme le tableau en
   couloir : on ne voit qu'une colonne et demie, et comparer redevient
   impossible — exactement ce que le tableau devait résoudre. En dessous de
   720 px il renonce donc à sa largeur plancher et se resserre : les cellules
   passent sur deux ou trois lignes, mais les trois forfaits sont là, côte à
   côte, lisibles d'un seul regard. */
@media (max-width: 720px) {
  /* Assez resserré pour montrer deux forfaits entiers, jamais au point de
     hacher les mots : « Hebdomadaire » dans 76 px donnerait six caractères
     par ligne. Le troisième s'atteint d'un glissement, et la page le dit. */
  .forfaits-table { min-width: 384px; font-size: 0.86rem; }

  .forfaits-table th,
  .forfaits-table td { padding: 12px 8px; }

  .forfaits-table tbody th { width: 24%; font-size: 0.8rem; }

  .forfaits-table thead th { font-size: 0.95rem; }

  .forfait-courant { font-size: 0.74rem; }

  .forfaits-glisser { display: block; }
}


/* ── Les vignettes ───────────────────────────────────────────────────── */

/* Quatre dessins au trait, un par prise en charge. Pas des icônes : chacun
   dit son idée — le cycle qui revient, la reprise qui recoud, la ligne
   qu'on réécrit, la trace qui se lit. Ils prennent la couleur du texte,
   n'ajoutent aucune requête, et tiennent en un trait de 1,5 px comme les
   filets de l'accueil.

   Aucun n'est annoncé aux lecteurs d'écran : le titre juste dessous dit la
   même chose, et mieux. */

.vignette {
  display: block;
  width: 52px;
  height: 52px;
  margin-bottom: 18px;
  color: var(--bronze);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.vignette .v-fond { opacity: 0.32; }

.vignette circle.v-moyeu,
.vignette circle.v-jalon,
.vignette circle.v-mobile { fill: currentColor; stroke: none; }

.vignette circle.v-jalon { opacity: 0.32; }

.vignette .v-lecteur { fill: none; stroke-width: 1.5; }

.vignette .v-jalons { opacity: 0.32; }

.vignette .v-fracture { opacity: 0.55; }

/* ── Ce qui bouge dans les vignettes ─────────────────────────────────── */

@media (prefers-reduced-motion: no-preference) {
  /* L'entretien revient : l'aiguille fait un tour, indéfiniment. */
  .vignette-cycle .v-aiguille {
    transform-origin: 28px 28px;
    animation: vignette-tour 7s linear infinite;
  }

  /* La reprise recoud : le point traverse la coupure et la couture se
     referme derrière lui, puis tout se rouvre. */
  .vignette-reprise .v-mobile { animation: vignette-traverser 3400ms var(--ease-out) infinite; }
  .vignette-reprise .v-couture {
    stroke-dasharray: 22;
    animation: vignette-coudre 3400ms var(--ease-out) infinite;
  }

  /* La réécriture : la ligne du milieu change de longueur, le curseur la
     suit. */
  .vignette-reecriture .v-ligne-changeante {
    transform-origin: 9px 28px;
    animation: vignette-reecrire 4200ms var(--ease-out) infinite;
  }
  .vignette-reecriture .v-curseur { animation: vignette-clignoter 1100ms steps(1, end) infinite; }

  /* La trace se lit : le lecteur descend d'une entrée à l'autre. */
  .vignette-trace .v-lecteur { animation: vignette-descendre 4200ms var(--ease-out) infinite; }

  .maintenance-page.js-mouvement.onglet-cache .vignette * { animation-play-state: paused; }
}

@keyframes vignette-tour {
  to { transform: rotate(360deg); }
}

@keyframes vignette-traverser {
  0%, 8% { transform: none; }
  46%, 62% { transform: translateY(22px); }
  100% { transform: none; }
}

@keyframes vignette-coudre {
  0%, 8% { stroke-dashoffset: 22; }
  46%, 70% { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: 22; }
}

@keyframes vignette-reecrire {
  0%, 12% { transform: scaleX(1); }
  40%, 56% { transform: scaleX(0.42); }
  84%, 100% { transform: scaleX(1); }
}

@keyframes vignette-clignoter {
  0%, 50% { opacity: 1; }
  50.01%, 100% { opacity: 0.15; }
}

@keyframes vignette-descendre {
  0%, 10% { transform: none; }
  36%, 46% { transform: translateY(12px); }
  72%, 82% { transform: translateY(24px); }
  100% { transform: none; }
}

/* ══ LE MOUVEMENT CONTINU ═══════════════════════════════════════════════
   L'accueil pose une doctrine : trois gestes, l'état d'arrivée est celui
   du repos. Maintenance en prend le contre-pied, à la demande — mais dans
   le vocabulaire de l'accueil, qui possède déjà ses boucles infinies : le
   surligneur du titre tourne sur neuf secondes, la tête de lecture du scan
   sur 4,2. On les étend ici plutôt que d'inventer un second langage.

   Toutes obéissent aux mêmes règles que l'accueil : rien ne tourne hors
   écran, rien ne tourne dans un onglet caché, rien ne tourne du tout si le
   système demande moins de mouvement.
   ═════════════════════════════════════════════════════════════════════ */

/* ── La tête de lecture des étapes ───────────────────────────────────── */

/* Le même passage que la liste des dix points de l'accueil, sur les quatre
   étapes du déroulement. Propriétés longues et jamais la forme raccourcie :
   « animation: … » remettrait animation-delay à zéro, et les décalages par
   rang ont une spécificité plus faible. */
@media (prefers-reduced-motion: no-preference) {
  .maintenance-page .method-flow li::before {
    animation-name: passage-numero;
    animation-duration: 4200ms;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-timeline: auto;
  }

  /* Avec le script, la boucle attend d'être à l'écran. */
  .js-mouvement .maintenance-page .method-flow li::before,
  .maintenance-page.js-mouvement .method-flow li::before { animation-name: none; }

  .maintenance-page.js-mouvement .method-flow.tourne li::before { animation-name: passage-numero; }

  .maintenance-page.js-mouvement.onglet-cache .method-flow li::before { animation-play-state: paused; }

  .maintenance-page .method-flow li:nth-child(1)::before { animation-delay: -4200ms; }
  .maintenance-page .method-flow li:nth-child(2)::before { animation-delay: -3780ms; }
  .maintenance-page .method-flow li:nth-child(3)::before { animation-delay: -3360ms; }
  .maintenance-page .method-flow li:nth-child(4)::before { animation-delay: -2940ms; }
}

/* ── Le témoin de période ────────────────────────────────────────────── */

/* Un point qui bat lentement à côté de « Période en cours ». Il ne décore
   pas : il dit que la période court, et qu'elle court en ce moment. */
.portail-periode { display: inline-flex; align-items: center; gap: 8px; }

.portail-periode::before {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--bronze);
  content: "";
  flex: none;
}

@media (prefers-reduced-motion: no-preference) {
  .portail-periode::before {
    animation: battre 2600ms var(--ease-out) infinite;
  }

  .maintenance-page.js-mouvement.onglet-cache .portail-periode::before { animation-play-state: paused; }
}

@keyframes battre {
  0%, 62%, 100% { opacity: 1; transform: scale(1); }
  18% { opacity: 0.35; transform: scale(0.72); }
}

/* ── Le carnet vivant ────────────────────────────────────────────────── */

/* Le carnet ne s'arrête pas : une intervention arrive, la plus ancienne
   sort, le temps utilisé avance, et la période finit par se refermer sur
   un solde remis à zéro. C'est le service lui-même qui est continu, pas
   seulement l'animation. Le détail est piloté par « carnet.js ». */

/* Ces deux attributs ne sont posés que par « carnet.js », qui s'arrête de
   lui-même en mode calme. La garde est quand même là : la feuille doit
   tenir seule, sans compter sur le script pour ne pas animer. */
@media (prefers-reduced-motion: no-preference) {
  .portail-lignes li[data-arrivee] { animation: lever 520ms var(--ease-out) both; }
  .portail-lignes li[data-sortie] { animation: partir 420ms var(--ease-out) both; }
}

@keyframes partir {
  from { opacity: 1; transform: none; }
  to { opacity: 0; transform: translateY(-10px); }
}

/* La jauge se déplace d'une valeur à l'autre plutôt que de sauter. Elle
   perd son remplissage d'entrée : elle est désormais toujours en train
   d'aller quelque part. */
.portail-jauge i {
  transition: width 900ms var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
  .portail-jauge i { transition: none; }
}

/* Le total du temps utilisé change en même temps que la jauge. Un très
   court effacement évite que le chiffre saute d'une valeur à l'autre sans
   qu'on l'ait vu changer. */
.portail-mesure b { transition: opacity 220ms var(--ease-out); }

.portail-mesure b[data-change] { opacity: 0.25; }

/* ── Les réserves ────────────────────────────────────────────────────── */

.reserves-liste {
  display: grid;
  margin: 0;
  padding: 0;
  gap: 0;
  list-style: none;
}

.reserves-liste li {
  display: grid;
  align-items: baseline;
  padding: clamp(16px, 1.8vw, 22px) 0;
  border-top: 1px solid var(--line);
  gap: 4px 26px;
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 721px) {
  .reserves-liste li { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); }
}

.reserves-liste li:last-child { border-bottom: 1px solid var(--line); }

.reserves-liste b {
  color: var(--ink);
  font-family: var(--display);
  font-size: 1.02rem;
  font-weight: 600;
}

.reserves-liste p { margin: 0; color: var(--body); }

.reserves-liste a { color: var(--green); }

/* Le fondateur ouvre la section famille : il en est le premier élément, pas
   une section à lui seul. L'espace qui les sépare vaut celui d'un titre. */
.maintenance-page .family .fondateur { margin-bottom: clamp(48px, 5vw, 82px); }

/* ── Les questions ───────────────────────────────────────────────────── */

.questions {
  margin: 0;
  border-top: 1px solid var(--line);
}

.questions details { border-bottom: 1px solid var(--line); }

.questions summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: clamp(18px, 2vw, 24px) 0;
  color: var(--ink);
  cursor: pointer;
  font-family: var(--display);
  font-size: clamp(1.02rem, 1.6vw, 1.14rem);
  font-weight: 600;
  gap: 20px;
  list-style: none;
}

.questions summary::-webkit-details-marker { display: none; }

.questions summary::after {
  color: var(--muted);
  content: "+";
  font-weight: 500;
  transition: transform 0.2s var(--ease-out);
}

.questions details[open] summary::after { transform: rotate(45deg); }

.questions summary:hover { color: var(--green); }

.questions p {
  max-width: 68ch;
  margin: 0 0 clamp(18px, 2vw, 24px);
  color: var(--body);
}

/* ── La demande ──────────────────────────────────────────────────────── */

/* Dernière section, sur le fond sombre de la famille : la page se termine
   sur une seule action. Le titre porte la promesse, la carte porte le
   formulaire. */

.demande {
  padding: clamp(72px, 8vw, 128px) 0;
  background: var(--navy);
  color: var(--white);
}

.demande-layout {
  display: grid;
  align-items: start;
  gap: clamp(36px, 4.5vw, 68px);
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 961px) {
  .demande-layout { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); }
}

.demande-copie h2 {
  margin: 0 0 20px;
  color: var(--white);
  font-family: var(--display);
  font-size: clamp(2.1rem, 3.8vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.06;
  text-wrap: balance;
}

.demande-copie p {
  max-width: 46ch;
  margin: 0 0 14px;
  color: rgba(253, 254, 252, 0.82);
}

.demande-copie p:last-child { margin-bottom: 0; }

.demande-carte {
  display: grid;
  padding: clamp(26px, 3vw, 40px);
  border-radius: var(--radius-surface);
  background: var(--white);
  color: var(--body);
  gap: 18px;
}

.champ { display: grid; margin: 0; gap: 7px; }

.champ label {
  color: var(--ink);
  font-size: 0.94rem;
  font-weight: 600;
}

.champ .facultatif {
  color: var(--muted);
  font-weight: 400;
}

/* 16 px au minimum : en dessous, iOS agrandit la page à la mise au point du
   champ, et le visiteur perd le formulaire des yeux. */
.champ input,
.champ select,
.champ textarea {
  width: 100%;
  min-height: 48px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--text);
  font-size: 16px;
  transition: border-color 0.18s var(--ease-out);
}

.champ textarea { min-height: 108px; resize: vertical; }

.champ input:focus,
.champ select:focus,
.champ textarea:focus {
  border-color: var(--green);
  outline: 2px solid var(--green);
  outline-offset: 1px;
}

.demande-carte .button { width: 100%; margin-top: 4px; }

.demande-secours {
  margin: 0;
  color: var(--muted);
  font-size: 0.9rem;
  text-align: center;
}

.demande-secours a { color: var(--green); }

/* Le piège à robots. Sorti du flux plutôt que masqué par « display:none »,
   que certains robots savent lire. Aucune personne ne l'atteint : il n'est
   ni visible, ni dans l'ordre de tabulation, ni annoncé aux lecteurs
   d'écran. */
.piege {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ── Les pages de retour ─────────────────────────────────────────────── */

.retour {
  display: grid;
  min-height: 62vh;
  align-content: center;
  padding: clamp(64px, 9vw, 132px) 0;
}

.retour h1 {
  margin: 0 0 20px;
  max-width: 18ch;
  color: var(--ink);
  font-family: var(--display);
  font-size: clamp(2.2rem, 4.4vw, 3.4rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.06;
}

.retour p { max-width: 58ch; margin: 0 0 14px; }

.retour-actions {
  display: flex;
  flex-wrap: wrap;
  margin-top: 14px;
  gap: 16px 24px;
}
