/* ══ REPÈRE SÉCURITÉ ════════════════════════════════════════════════════
   Extension de home-v2.css, jamais un second système. Même règle que les
   guides Loi 25 et que Maintenance : aucune police, aucun rayon, aucune
   durée, aucun point de rupture qui ne soit déjà dans la feuille d'accueil.
   Ce fichier ne donne forme qu'aux objets que l'accueil n'a pas — la fiche
   de mandat, les familles de contrôles, les limites, les questions et le
   formulaire de demande.

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

   LE BLEU ARDOISE. Sécurité garde une teinte propre, en accent SECOND :
   le bleu prend la place du vert là où l'accueil pose son accent, et le
   reste du nuancier ne bouge pas. Un visiteur doit voir un site Repère
   d'abord, un site Sécurité ensuite.

   LA RÈGLE DE MOUVEMENT. Aucune animation en boucle sur ce site. Un
   élément qui progresse en permanence raconte une surveillance continue,
   que le produit ne fournit pas. Tout mouvement se déclenche au
   défilement, révèle, puis s'arrête. Rien ici n'utilise « data-boucle ».
   ═════════════════════════════════════════════════════════════════════ */

:root {
  /* L'ACCENT. On reteinte les trois jetons d'accent plutôt que de reprendre
     un à un les composants qui s'en servent : une seule source, aucune
     dérive possible. Les deux premières valeurs ne sont pas inventées —
     ce sont les --sec-700 et --sec-600 du styles.css de Sécurité, choisis
     pour ce service.

     Contrastes mesurés : blanc sur #3b5488 donne 7,47:1, blanc sur le
     survol 8,75:1, blanc sur le fond sombre 10,29:1, et l'encre sur le
     voile 13,10:1. Tous très au-dessus du seuil AA. */
  --green: #3b5488;
  --green-dark: #2c4068;
  --green-light: #e3e8f1;

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

  /* Les trois niveaux de sévérité. Ce ne sont pas des accents : ce sont des
     valeurs de données, et elles doivent rester lisibles quelle que soit la
     teinte de marque. Le rouge est sourd volontairement — un constat élevé
     s'annonce, il ne crie pas. */
  --sev-eleve: #8c3a2c;
  --sev-moyen: #7a5a1c;
  --sev-faible: #4a5a6b;
}

/* Le survol des boutons pleins. Assombrir le bleu de quatre points de
   clarté en lui rendant un point et demi de saturation : il s'assombrit
   sans se ternir, et la teinte ne bouge pas d'un degré. Blanc dessus :
   8,75:1. --green-dark reste réservé aux fonds et au texte. */
.securite-page .button:hover { background: #334a7a; }

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

/* Même correction que sur les guides et sur Maintenance : Public Sans,
   casse naturelle, pas d'interlettrage. Le sur-titre prend l'ardoise. */
.securite-page .eyebrow {
  color: var(--ardoise);
  font-family: var(--text);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

/* ── La barre de famille ─────────────────────────────────────────────── */

/* Trois services, un seul groupe, et jusqu'ici aucun moyen de passer de l'un
   à l'autre autrement qu'en descendant jusqu'au pied de page. Sécurité est le
   service le moins connu des trois : c'est celui qui a le plus besoin que le
   visiteur voie d'où il vient et ce qu'il y a à côté.

   La barre ne colle pas. Elle se lit une fois, en haut, puis laisse la place
   à l'en-tête — sans quoi le bandeau collant passerait de 68 à 100 px, ce
   qu'un écran de téléphone ne peut pas se permettre. */
.famille-bande {
  background: var(--paper-deep);
  border-bottom: 1px solid var(--line);
  font-family: var(--text);
  font-size: 0.82rem;
}

.famille-bande .shell {
  display: flex;
  align-items: center;
  min-height: 38px;
  gap: 4px;
  flex-wrap: wrap;
}

.famille-bande a {
  display: inline-flex;
  align-items: center;
  padding: 6px 11px;
  border-radius: 999px;
  color: var(--muted);
  font-weight: 500;
  text-decoration: none;
  transition: color 200ms var(--ease-out), background-color 200ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .famille-bande a:hover { background: rgba(44, 64, 104, 0.09); color: var(--ink); }
}

/* Le service courant est marqué, pas répété : un point suffit à dire « vous
   êtes ici », et le contraste fait le reste. */
.famille-bande a[aria-current="page"] {
  background: var(--white);
  box-shadow: inset 0 0 0 1px rgba(44, 64, 104, 0.22);
  color: var(--ardoise-fonce);
  font-weight: 600;
}

.famille-bande a[aria-current="page"]::before {
  width: 6px;
  height: 6px;
  margin-right: 7px;
  border-radius: 50%;
  background: var(--ardoise);
  content: "";
}

/* Le lien est « inline-flex » : l'espace en fin de <span> est avalé, et on
   lisait « RepèreQuébec ». La marge le rend, et elle disparaît avec le mot. */
.famille-bande a > span { margin-right: 0.3em; }

/* « Repère » disparaît sous 520 px : trois fois le même mot mange la barre,
   et le sceau juste dessous porte déjà la marque. */
@media (max-width: 520px) {
  .famille-bande { font-size: 0.78rem; }
  .famille-bande .shell { min-height: 34px; gap: 2px; }
  .famille-bande a { padding: 5px 9px; }
  .famille-bande a > span { display: none; }
}

/* ── L'en-tête ───────────────────────────────────────────────────────── */

/* LA MARQUE. Le logo de la famille est une image cuite qui dit « Repère
   Québec » : sur Sécurité, elle annonce le mauvais service, et à 44 px son
   mot-symbole devient illisible. On garde le sceau — c'est la marque — et on
   compose le nom en texte : bon service, net à toutes les tailles, et une
   hiérarchie qu'une image ne peut pas porter. */
.securite-page .brand { gap: 11px; text-decoration: none; }

/* Le nom de marque est dans un lien : sans cela il hérite du soulignement
   des liens de contenu, et le sceau se retrouve flanqué de deux traits. */
.brand-nom, .brand-nom span, .brand-nom b { text-decoration: none; }
.securite-page .brand img { height: 34px; }

.brand-nom {
  display: grid;
  color: var(--ink);
  font-family: var(--display);
  line-height: 1.05;
}

.brand-nom span {
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--muted);
}

.brand-nom b {
  font-size: 1.06rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--ardoise-fonce);
}

/* Le lien de navigation : le soulignement de la famille, mais qui pousse
   depuis la gauche au lieu d'apparaître d'un bloc. */
.securite-page .nav-links a {
  background-position: 0 100%;
  background-size: 0 1.5px;
  transition: background-size 260ms var(--ease-out), color 200ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .securite-page .nav-links a:hover { background-size: 100% 1.5px; }
}

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .securite-page .site-header {
      animation: entete-poser linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 140px;
    }
  }
}

/* LE MOBILE. Trois blocs lourds se disputaient 333 px : le sceau, un bouton
   plein de vingt-deux caractères et le menu. Le bouton quitte la barre et
   réapparaît en pied de panneau, pleine largeur — là où la main l'atteint,
   et sans écraser la marque. L'action reste à un geste, et le hero la répète
   quatre cents pixels plus bas. */
.nav-panel-cta { margin-top: 14px; width: 100%; justify-content: center; }

@media (min-width: 721px) {
  .nav-panel-cta { display: none; }
}

@media (max-width: 720px) {
  .securite-page .nav-cta { display: none; }
  .securite-page .brand img { height: 32px; }
  .brand-nom b { font-size: 1rem; }
}

@media (max-width: 390px) {
  .brand-nom span { font-size: 0.72rem; }
  .brand-nom b { font-size: 0.94rem; }
}

/* ── Le hero ─────────────────────────────────────────────────────────── */

/* Le sur-titre porte un court filet : sur un service qui vend l'encadrement,
   une marque de document vaut mieux qu'une majuscule décorative. */
.securite-page .hero .eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
}

.securite-page .hero .eyebrow::before {
  width: 26px;
  height: 2px;
  background: var(--ardoise);
  content: "";
  flex: none;
}

.securite-page .hero h1 {
  letter-spacing: -0.028em;
  text-wrap: balance;
}

/* LE SURLIGNEUR. L'accueil le fait repasser toutes les neuf secondes. Ici
   c'est interdit : une marque qui se retrace sans fin est un mouvement
   perpétuel, et ce site n'en porte aucun. On reprend donc le tracé unique de
   la famille, joué une fois, après l'arrivée de la ligne. */
.securite-page .hero h1 mark {
  animation: tracer-marque 760ms var(--ease-out) 900ms backwards;
  animation-iteration-count: 1;
}

.securite-page .hero-lead { max-width: 46ch; }

/* L'action secondaire : la flèche avance à l'approche, le lien ne bouge pas. */
.securite-page .hero-actions .text-link::after {
  display: inline-block;
  margin-left: 7px;
  content: "\2193";
  transition: transform 240ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .securite-page .hero-actions .text-link:hover::after { transform: translateY(3px); }
}

/* L'ORCHESTRATION. Une seule séquence, dans l'ordre où on lit : le service,
   la promesse, la limite soulignée, l'explication, l'action. La fiche entre
   en même temps que l'explication, puis s'écrit ligne à ligne. Tout est fini
   à 1,3 s et plus rien ne bouge. */
@keyframes hero-entrer {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: no-preference) {
  .securite-page .hero .eyebrow { animation: hero-entrer 520ms var(--ease-out) 40ms backwards; }
  .hero-securite h1 .ligne > span { animation: ligne-monter 900ms cubic-bezier(0.16, 0.84, 0.44, 1) backwards; }
  .hero-securite h1 .ligne:nth-child(1) > span { animation-delay: 100ms; }
  .hero-securite h1 .ligne:nth-child(2) > span { animation-delay: 230ms; }
  .securite-page .hero-lead { animation: hero-entrer 700ms var(--ease-out) 520ms backwards; }
  .securite-page .hero-actions { animation: hero-entrer 700ms var(--ease-out) 650ms backwards; }
  .hero-preuves { animation: hero-entrer 700ms var(--ease-out) 780ms backwards; }
  .securite-page .feuille-mention { animation: hero-entrer 520ms var(--ease-out) 900ms backwards; }
}

/* ── Le hero, en composition centrée ─────────────────────────────────── */

/* La grille de l'accueil pose la copie à gauche et l'image à droite. Ici la
   fiche de mandat n'est pas une illustration d'accompagnement : c'est la
   démonstration de ce que la phrase promet. On centre donc l'annonce et on
   met le document dessous, en pleine largeur — il gagne la place qu'il
   mérite, et la page s'ouvre sur une seule idée au lieu de deux colonnes qui
   se disputent le regard. */
.hero-securite .hero-layout {
  align-items: center;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(40px, 5vw, 76px);
}

@media (min-width: 901px) {
  .hero-securite .hero-layout {
    grid-template-columns: minmax(0, 1.06fr) minmax(340px, 0.94fr);
  }
}

.hero-securite .hero-copy { max-width: 620px; }

/* Beaucoup d'air. Le hero ne porte plus qu'une phrase, une explication et une
   action : ce qui le rend beau, c'est l'espace autour, pas un objet de plus.

   LE FOND. Trois couches, aucune dépendance, aucun script. Les bibliothèques
   qui font ce genre d'atmosphère aujourd'hui passent par React et WebGL ; la
   CSP de ce domaine n'autorise aucun script tiers, et de toute façon un fond
   n'a pas besoin d'un moteur de rendu.

   1. Le grain. C'est lui qui enlève le côté « aplat plat » d'un papier uni.
      Un bruit fractal en SVG, en données dans la feuille — « img-src data: »
      l'autorise, et il ne pèse rien.
   2. Le voile ardoise, très diffus, derrière le titre : de la profondeur là
      où l'œil se pose, sans jamais devenir un dégradé décoratif.
   3. La grille de points, portée par le pseudo-élément plus bas. Sur un
      service qui vend la mesure et le périmètre, du papier millimétré dit
      quelque chose de juste — ce n'est pas un motif choisi au hasard. */
.hero-securite {
  padding-block: clamp(72px, 9vw, 148px) clamp(72px, 9vw, 140px);
  min-height: min(72vh, 720px);
  align-items: center;
}

.hero-securite h1 {
  font-size: clamp(2.25rem, 4.6vw, 3.75rem);
  letter-spacing: -0.034em;
  line-height: 1.01;
}

/* Le masque de ligne. Le débord caché coupe le texte pendant qu'il monte ;
   sans le rembourrage, il couperait aussi les jambages de « signez ». */
.hero-securite h1 .ligne {
  display: block;
  overflow: hidden;
  padding-bottom: 0.1em;
  margin-bottom: -0.1em;
}

.hero-securite h1 .ligne > span { display: block; }

@keyframes ligne-monter {
  from { transform: translateY(108%); }
  to { transform: none; }
}

/* La ligne de preuve. Discrète par construction : elle informe celui qui
   hésite encore, et n'entre pas en concurrence avec le bouton. */
.hero-preuves {
  max-width: 46ch;
  margin: clamp(24px, 2.8vw, 32px) 0 0;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.9;
}

.hero-preuves span {
  margin-inline: 9px;
  color: var(--ardoise);
}

.hero-securite .hero-lead {
  max-width: 46ch;
  font-size: clamp(1.06rem, 1.35vw, 1.22rem);
}

.hero-securite .hero-actions { flex-wrap: wrap; }



.etape-jetons li {
  display: inline-flex;
  align-items: baseline;
  max-width: 100%;
  /* Le master habille « .method-flow li » d'un filet supérieur et d'un
     rembourrage : sélecteur de descendance, donc chaque libellé imbriqué
     héritait d'un trait court flottant au-dessus de lui. */
  padding-top: 0;
  border-top: 0;
  color: var(--muted);
  font-family: var(--text);
  font-size: 0.84rem;
  font-weight: 500;
  gap: 8px;
  line-height: 1.45;
  counter-increment: none;
}

/* Ni pilule, ni coche cerclée. La famille marque ses listes d'un point de
   cinq pixels — « .included » le fait déjà sur l'accueil. Des capsules
   lavande à rayon 999 px n'existent dans aucun jeton et écrasaient le titre
   de la carte. */
.etape-jetons li::before {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ardoise);
  content: "";
  flex: none;
  transform: translateY(-0.32em);
}

/* ── Les vignettes du problème ───────────────────────────────────────── */

/* Sans ces classes, les <rect> d'un SVG retombent sur leur remplissage par
   défaut : du noir plein. C'est exactement ce qui est arrivé quand la
   suppression de l'ancienne grille de cartes les a emportées au passage. */
.vignette-probleme { display: block; overflow: visible; }

.vp-trait { fill: none; stroke: var(--ardoise); stroke-width: 1.6; }
.vp-pale { fill: none; stroke: rgba(44, 64, 104, 0.3); stroke-width: 1.4; stroke-linecap: round; }
.vp-champ { fill: rgba(44, 64, 104, 0.16); stroke: none; }

/* La page intruse : elle n'est pas à vous, donc pointillé rouge, et elle
   dérive lentement par-dessus la vôtre. */
.vp-intrus { fill: var(--white); stroke: var(--sev-eleve); stroke-width: 1.5; stroke-dasharray: 4 3; }
.vp-intrus-ligne { fill: none; stroke: rgba(140, 58, 44, 0.5); stroke-width: 1.4; stroke-linecap: round; }

/* Ce qui part du formulaire vers ailleurs. */
.vp-fuite { fill: none; stroke: var(--sev-eleve); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* Un sceau qui n'a jamais été apposé. */
.vp-absent { fill: none; stroke: var(--sev-eleve); stroke-width: 1.6; stroke-dasharray: 3 4; }

@keyframes vp-deriver {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(3px, -2.5px); }
}

@keyframes vp-fuir {
  0% { stroke-dashoffset: 26; opacity: 0.25; }
  35%, 65% { stroke-dashoffset: 0; opacity: 1; }
  100% { stroke-dashoffset: -26; opacity: 0.25; }
}

@keyframes vp-manquer {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}

/* ── Les boucles ─────────────────────────────────────────────────────── */

/* Toutes les animations permanentes du site vivent ici, ensemble, pour ne
   plus disparaître par accident. Elles passent par « data-boucle », le
   mécanisme de la famille : elles s'arrêtent hors écran et quand l'onglet
   passe en arrière-plan. */

@media (prefers-reduced-motion: no-preference) {
  /* Le hero : la brèche s'ouvre puis se referme. */
  .vue-breche.tourne .vue-fermeture {
    stroke-dasharray: 80;
    animation: breche-fermeture-cycle 7s var(--ease-out) infinite;
  }

  .vue-breche.tourne .vue-sceau,
  .vue-breche.tourne .vue-coche {
    transform-origin: 378px 168px;
    animation: breche-sceau-cycle 7s var(--ease-out) infinite;
  }

  .vue-breche.tourne .vue-breche-bords { animation: breche-bords-cycle 7s var(--ease-out) infinite; }

  /* Les trois vignettes du problème. */
  .bandes.tourne .vp-intrus,
  .bandes.tourne .vp-intrus-ligne { animation: vp-deriver 6s var(--ease-out) infinite; }

  .bandes.tourne .vp-fuite {
    stroke-dasharray: 26;
    animation: vp-fuir 5s linear infinite;
  }

  .bandes.tourne .vp-absent { animation: vp-manquer 4.5s var(--ease-out) infinite; }

  /* La lecture d'en-têtes se rejoue. */
  .lecture.tourne .lecture-lignes span { animation: ligne-cycle 9s steps(26, end) infinite; }
  .lecture.tourne .lecture-lignes b { animation: verdict-cycle 9s var(--ease-out) infinite; }
  .lecture.tourne li:nth-child(1) span, .lecture.tourne li:nth-child(1) b { animation-delay: 0ms; }
  .lecture.tourne li:nth-child(2) span, .lecture.tourne li:nth-child(2) b { animation-delay: 260ms; }
  .lecture.tourne li:nth-child(3) span, .lecture.tourne li:nth-child(3) b { animation-delay: 520ms; }
  .lecture.tourne li:nth-child(4) span, .lecture.tourne li:nth-child(4) b { animation-delay: 780ms; }
  .lecture.tourne li:nth-child(5) span, .lecture.tourne li:nth-child(5) b { animation-delay: 1040ms; }

  /* Le périmètre se retrace. */
  .vue-perimetre.tourne .vue-anime {
    stroke-dasharray: var(--trace, 660);
    animation: perimetre-cycle 11s var(--ease-out) infinite;
  }

  /* L'onglet caché n'a rien à animer. */
  .js-mouvement.onglet-cache .vue-fermeture,
  .js-mouvement.onglet-cache .vue-sceau,
  .js-mouvement.onglet-cache .vue-coche,
  .js-mouvement.onglet-cache .vue-breche-bords,
  .js-mouvement.onglet-cache .vp-intrus,
  .js-mouvement.onglet-cache .vp-intrus-ligne,
  .js-mouvement.onglet-cache .vp-fuite,
  .js-mouvement.onglet-cache .vp-absent,
  .js-mouvement.onglet-cache .lecture-lignes span,
  .js-mouvement.onglet-cache .lecture-lignes b,
  .js-mouvement.onglet-cache .vue-anime { animation-play-state: paused; }
}

/* ── Le problème : trois bandes ──────────────────────────────────────── */

/* Pas une grille de cartes. Trois situations, trois bandes pleine largeur qui
   alternent le dessin et le texte : les illustrations ont la place de se
   lire, et la page cesse de répéter quatre fois la même mise en page. */
.bandes {
  display: grid;
  margin: clamp(40px, 5vw, 64px) 0 0;
  padding: 0;
  gap: clamp(44px, 5.5vw, 82px);
  list-style: none;
}

.bande {
  display: grid;
  align-items: center;
  gap: clamp(24px, 3.4vw, 56px);
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 761px) {
  .bande { grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); }
  /* Une bande sur deux inverse ses moitiés : le regard descend en zigzag au
     lieu de retomber toujours au même endroit. */
  .bande:nth-child(even) .bande-vue { order: 2; }
}

.bande-vue {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(22px, 2.6vw, 34px);
  border: 1px solid var(--line);
  border-radius: var(--radius-surface);
  background: var(--white);
}

.bande-vue .vignette-probleme { width: min(100%, 260px); height: auto; margin: 0; }

.bande-texte h3 {
  margin: 0 0 12px;
  color: var(--ink);
  font-family: var(--display);
  font-size: clamp(1.24rem, 2.2vw, 1.62rem);
  font-weight: 600;
  letter-spacing: -0.014em;
  text-wrap: balance;
}

.bande-texte p { max-width: 52ch; margin: 0; color: var(--body); font-size: clamp(1rem, 1.2vw, 1.08rem); }

/* ── Le déroulement : une frise ──────────────────────────────────────── */

/* L'ordre EST le contenu : six cartes posées en grille le perdaient, une
   frise à fil continu le montre. Le fil relie les jalons ; chaque numéro
   s'assoit dessus sur un fond de papier, ce qui le coupe proprement. */
.frise {
  position: relative;
  display: grid;
  margin: clamp(40px, 5vw, 60px) 0 0;
  padding: 0;
  gap: clamp(30px, 3.4vw, 44px);
  counter-reset: jalons;
  list-style: none;
}

.frise::before {
  position: absolute;
  top: 12px;
  bottom: 12px;
  left: 17px;
  width: 1px;
  background: linear-gradient(var(--line), var(--line));
  content: "";
}

.frise > li {
  position: relative;
  display: grid;
  align-items: start;
  padding: 0;
  border: 0;
  gap: 4px clamp(20px, 2.4vw, 30px);
  grid-template-columns: 36px minmax(0, 1fr);
  counter-increment: jalons;
}

.frise > li::before {
  display: flex;
  width: 36px;
  height: 36px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--paper);
  color: var(--ardoise);
  content: counter(jalons, decimal-leading-zero);
  font-family: var(--mono);
  font-size: 0.76rem;
  grid-row: 1 / span 3;
}

.frise h3 {
  margin: 6px 0 8px;
  color: var(--ink);
  font-family: var(--display);
  font-size: clamp(1.14rem, 1.9vw, 1.4rem);
  font-weight: 600;
  letter-spacing: -0.012em;
}

.frise > li > p { max-width: 62ch; margin: 0; color: var(--body); }

/* ── Les limites : une liste dense ───────────────────────────────────── */

/* Une grille à deux colonnes laissait une sixième cellule vide, et son fond
   gris se lisait comme un bloc mort. Cinq limites, cinq lignes. */
.limites {
  margin: clamp(36px, 4vw, 52px) 0 0;
  padding: 0;
  border-top: 1px solid var(--line);
  list-style: none;
}

.limites > li {
  display: grid;
  align-items: baseline;
  padding: clamp(20px, 2.4vw, 28px) 0;
  border-bottom: 1px solid var(--line);
  gap: 6px 18px;
  grid-template-columns: 18px minmax(0, 1fr);
}

@media (min-width: 761px) {
  .limites > li { grid-template-columns: 18px minmax(0, 0.86fr) minmax(0, 1.14fr); }
  .limites > li::before { grid-row: 1; }
}

.limites b {
  color: var(--ink);
  font-family: var(--display);
  font-size: clamp(1.02rem, 1.5vw, 1.14rem);
  font-weight: 600;
}

.limites p { max-width: 60ch; margin: 0; color: var(--body); font-size: 0.98rem; }

/* ── La lecture d'en-têtes ───────────────────────────────────────────── */

/* Ce que voulait dire « des lignes qui s'écrivent toutes seules », sans le
   faux terminal : de vrais noms d'en-têtes HTTP, qui apparaissent l'un après
   l'autre et reçoivent leur verdict. Ni vert phosphore, ni curseur qui
   clignote, ni code inventé — une lecture de document.

   Aucune valeur n'est affichée et rien ne décrit la configuration de Repère :
   on montre la méthode, jamais notre propre implémentation. */
.lecture {
  max-width: 620px;
  margin: clamp(38px, 4vw, 54px) 0 0;
  padding: clamp(20px, 2.2vw, 28px);
  border: 1px solid rgba(227, 232, 241, 0.22);
  border-radius: var(--radius-card);
  background: rgba(12, 18, 32, 0.34);
}

.lecture-tete {
  display: flex;
  justify-content: space-between;
  margin: 0 0 14px;
  gap: 14px;
  color: #9fb0c8;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  flex-wrap: wrap;
}

.lecture-lignes { margin: 0; padding: 0; list-style: none; }

.lecture-lignes li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 9px 0;
  border-bottom: 1px solid rgba(227, 232, 241, 0.12);
  gap: 16px;
}

.lecture-lignes li:last-child { border-bottom: 0; }

.lecture-lignes span {
  color: #d6dfeb;
  font-family: var(--mono);
  font-size: clamp(0.78rem, 1.5vw, 0.9rem);
  word-break: break-all;
}

.lecture-lignes b {
  font-family: var(--text);
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
}

.est-present b { color: #8fc9ac; }
.est-absent b { color: #e2a08e; }

.lecture-pied {
  margin: 16px 0 0;
  color: #9fb0c8;
  font-size: 0.86rem;
}

/* L'écriture. Chaque ligne se dévoile de la gauche vers la droite — c'est ce
   qui donne l'impression qu'elle s'écrit — puis son verdict tombe. Une seule
   fois, à l'arrivée à l'écran : rien ne se rejoue en boucle. */
@keyframes ligne-ecrire {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}

@keyframes verdict-tomber {
  from { opacity: 0; transform: translateY(-5px); }
  to { opacity: 1; transform: none; }
}

/* La lecture se rejoue. Une écriture unique passait avant que le lecteur
   arrive à cette hauteur de page ; ici la relecture est le geste même du
   service, et elle a donc le droit de se répéter. */
@keyframes ligne-cycle {
  0% { clip-path: inset(0 100% 0 0); }
  9%, 86% { clip-path: inset(0 0 0 0); }
  95%, 100% { clip-path: inset(0 100% 0 0); }
}

@keyframes verdict-cycle {
  0%, 6% { opacity: 0; transform: translateY(-5px); }
  14%, 86% { opacity: 1; transform: none; }
  94%, 100% { opacity: 0; transform: translateY(-5px); }
}

/* ── L'illustration du hero ──────────────────────────────────────────── */

.hero-securite .hero-art { width: min(100%, 460px); margin-inline: auto; }
.hero-securite .hero-art::before { content: none; }

.vue-contour { stroke-width: 1.8; }

/* Les deux bords de la brèche : deux petits traits qui disent « c'est ouvert
   ici » avant que le contour ne soit refermé. */
.vue-breche-bords {
  stroke: var(--sev-eleve);
  stroke-width: 1.6;
  stroke-linecap: round;
}

/* Le trait qui referme. C'est la dernière chose qui arrive, et c'est la
   promesse du second mandat : ce qui était ouvert ne l'est plus. */
.vue-fermeture {
  fill: none;
  stroke: var(--ardoise);
  stroke-width: 3;
  stroke-linecap: round;
}

.vue-sceau { fill: var(--ardoise); }
.vue-coche { fill: none; stroke: var(--white); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

@keyframes contour-tracer {
  from { stroke-dashoffset: 900; }
  to { stroke-dashoffset: 0; }
}

@keyframes fermer-la-breche {
  from { stroke-dashoffset: 80; }
  to { stroke-dashoffset: 0; }
}

@keyframes sceau-poser {
  from { opacity: 0; transform: scale(0.5); }
  to { opacity: 1; transform: none; }
}

@keyframes breche-fermeture-cycle {
  0%, 14% { stroke-dashoffset: 0; }
  30%, 58% { stroke-dashoffset: 80; }
  76%, 100% { stroke-dashoffset: 0; }
}

@keyframes breche-sceau-cycle {
  0%, 12% { opacity: 1; transform: scale(1); }
  26%, 64% { opacity: 0; transform: scale(0.55); }
  88%, 100% { opacity: 1; transform: scale(1); }
}

@keyframes breche-bords-cycle {
  0%, 18% { opacity: 0; }
  34%, 60% { opacity: 1; }
  78%, 100% { opacity: 0; }
}

@media (prefers-reduced-motion: no-preference) {
  .vue-breche.est-vu .vue-contour {
    stroke-dasharray: 900;
    animation: contour-tracer 1200ms var(--ease-out) 200ms both;
  }

}

/* ── Les étapes du déroulement ───────────────────────────────────────── */

/* Le fil d'étapes de l'accueil devient une carte par étape : un numéro, un
   titre, une explication, et ce que l'étape produit réellement. Les pastilles
   ne sont pas des arguments — chacune nomme une sortie du processus. */


/* Trois colonnes tiennent tant que la carte reste lisible. À 768 px elles
   tombaient à 213 px : assez pour un fil d'étapes sans cadre, trop peu pour
   une carte qui porte un numéro, un titre, un paragraphe et des pastilles. */


.etape-jetons {
  display: flex;
  margin: 14px 0 0;
  padding: 18px 0 0;
  border-top: 1px solid var(--line);
  gap: 8px 20px;
  flex-wrap: wrap;
  list-style: none;
}

/* Le compteur d'étapes du master est posé sur « .method-flow li », un
   sélecteur de descendance : chaque pastille, qui est aussi un <li>, le
   faisait avancer. L'étape 2 s'affichait « 04 ». C'est réglé ci-dessus. */

/* Chaque carte se pose à son entrée, et ses pastilles arrivent ensuite —
   l'étape avant ce qu'elle produit. Déclenché au défilement, joué une fois. */
@keyframes jeton-poser {
  from { opacity: 0; transform: translateY(7px) scale(0.97); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: no-preference) {


}

@keyframes hero-partir {
  to { opacity: 0.2; transform: translateY(-46px); }
}

/* Lié à la position du hero dans la fenêtre, donc borné par le défilement :
   ça bouge dès que le lecteur bouge, et ça s'arrête dès qu'il s'arrête. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero-securite .hero-copy {
      animation: hero-partir linear both;
      animation-timeline: view();
      animation-range: exit -5% exit 85%;
    }
  }
}

/* ── La fiche de mandat ──────────────────────────────────────────────── */

/* Le visuel du hero. Ce n'est ni un tableau de bord, ni une capture de
   logiciel : c'est la lecture d'un document. Chaque ligne correspond à un
   champ réel du mandat — périmètre, exclusions, tests interdits, validité,
   constats, revue. Aucun nom de domaine, aucun client, aucune note
   globale : un chiffre unique inviterait à la comparaison et laisserait
   croire qu'un site « bien noté » serait sûr. */

/* LE CARRÉ JAUNE DE L'ACCUEIL EST RETIRÉ. « .hero-art::before » a été dessiné
   pour passer derrière une photographie, dont il débordait comme un calage.
   Derrière une fiche de document il ne cale rien : il flotte à droite, il
   recouvrait la mention légale posée sous la carte, et il n'apporte aucune
   information. Le jaune de la famille reste porté par le surligneur du titre,
   où il souligne les trois mots qui comptent au lieu de meubler un angle. */

.mandat {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-surface);
  background: var(--white);
  box-shadow: 0 18px 44px rgba(16, 37, 28, 0.09);
}

.mandat-tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 16px clamp(20px, 2.4vw, 28px);
  gap: 14px;
  background: var(--ardoise-fonce);
  color: var(--white);
}

.mandat-titre {
  margin: 0;
  font-family: var(--display);
  font-size: 0.98rem;
  font-weight: 600;
}

/* L'état du mandat. « Signé » est le seul mot du hero qui distingue Repère
   d'un outil en ligne : il est donc écrit, pas suggéré. */
.mandat-etat {
  display: inline-flex;
  align-items: center;
  margin: 0;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(253, 254, 252, 0.16);
  color: var(--white);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.mandat-corps { margin: 0; }

.mandat-ligne {
  display: grid;
  align-items: start;
  padding: 14px clamp(20px, 2.4vw, 28px);
  border-bottom: 1px solid var(--line);
  gap: 4px 18px;
  grid-template-columns: 108px minmax(0, 1fr);
}

.mandat-ligne dt {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding-top: 2px;
}

.mandat-ligne dd {
  margin: 0;
  color: var(--ink);
  font-size: 0.96rem;
  line-height: 1.45;
}

/* La répartition par sévérité, à la place d'une note. Les largeurs sont des
   classes et non des attributs « style » : la CSP du domaine interdit le
   style en ligne, et une barre dont la largeur vient du HTML serait aussi
   une donnée non vérifiable. */
.mandat-sev {
  display: flex;
  align-items: center;
  margin: 9px 0 0;
  gap: 5px;
  flex-wrap: wrap;
}

.sev-barre {
  display: inline-block;
  height: 9px;
  border-radius: 3px;
  transform-origin: left center;
}

.sev-eleve { width: 34px; background: var(--sev-eleve); }
.sev-moyen { width: 50px; background: var(--sev-moyen); }
.sev-faible { width: 66px; background: var(--sev-faible); }

.mandat-sev span:last-child {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.76rem;
}

.mandat-pied {
  display: flex;
  align-items: center;
  padding: 14px clamp(20px, 2.4vw, 28px);
  gap: 10px;
  background: var(--ardoise-voile);
}

/* Le tampon de revue. Il arrive en dernier dans la cascade de révélation :
   la relecture humaine clôt la chaîne, elle ne l'ouvre pas. */
.mandat-tampon {
  display: inline-flex;
  align-items: center;
  margin: 0;
  padding: 4px 11px;
  border: 1px solid rgba(44, 64, 104, 0.34);
  border-radius: 999px;
  color: var(--ardoise-fonce);
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.mandat-note {
  display: none;
  margin: 0;
  color: var(--muted);
  font-size: 0.84rem;
}

@media (min-width: 561px) {
  .mandat-note { display: block; }
}

/* La mention passe au-dessus de tout ce qui pourrait la recouvrir : c'est la
   phrase qui dit qu'aucun client n'est représenté, elle doit être lisible. */

/* ── Le rythme des pages longues ─────────────────────────────────────── */

/* Cinq sections « .method » d'affilée se lisent comme un seul bloc. Une bande
   blanche sur deux redonne un repère au lecteur sans rien changer au fond. */
.securite-page .bande-blanche { background: var(--white); }

/* ── Les dessins des pages de contenu ────────────────────────────────── */

/* Même facture que les illustrations de l'accueil : trait fin, deux couleurs,
   aucun aplat. Ils coupent le texte là où il devient long, et chacun dit
   quelque chose que le paragraphe voisin ne dit pas aussi vite. */
.vue-cadre .vue { width: 100%; height: auto; display: block; }

.vue-blanc { fill: var(--white); }
.vue-texte-fort {
  fill: var(--ardoise-fonce);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
}
.vue-objet-cible { stroke-width: 2; }
.vue-champ { stroke: rgba(44, 64, 104, 0.28); stroke-width: 6; stroke-linecap: round; }
.vue-signature { fill: none; stroke: var(--ardoise); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* La signature s'écrit à l'arrivée : c'est le geste que la section décrit. */
@keyframes signer {
  from { stroke-dashoffset: 96; }
  to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: no-preference) {
  .vue-mandat.est-vu .vue-signature {
    stroke-dasharray: 96;
    animation: signer 900ms var(--ease-out) 300ms both;
  }
  .vue-objet.est-vu .vue-objet-cible {
    stroke-dasharray: 660;
    animation: perimetre-trace 1000ms var(--ease-out) 200ms both;
  }
}

/* Les pièces propres aux dessins des guides. */
.vue-remplissage { fill: rgba(44, 64, 104, 0.32); }
.vue-remplissage-fort { fill: var(--ardoise); }
.vue-limite { stroke: rgba(44, 64, 104, 0.4); stroke-width: 1.4; stroke-dasharray: 5 4; }
.vue-dessous { fill: rgba(44, 64, 104, 0.06); }
.vue-gravite { fill: var(--sev-eleve); }
.vue-action { stroke: var(--ardoise); stroke-width: 3; stroke-linecap: round; }
.vue-brique { fill: rgba(44, 64, 104, 0.3); }
.vue-brique-morte { fill: none; stroke: rgba(140, 58, 44, 0.5); stroke-width: 1.3; stroke-dasharray: 3 3; }
.vue-compte-mort { fill: none; stroke: rgba(140, 58, 44, 0.5); stroke-width: 1.3; stroke-dasharray: 3 3; }
.vue-fuite-wp { fill: none; stroke: var(--sev-eleve); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* Le dessin garde une largeur lisible et ne s'étale pas sur toute la page. */
.vue-objet, .vue-mandat, .vue-portee, .vue-surface, .vue-constat, .vue-chantiers,
.vue-composition {
  max-width: 560px;
  margin: clamp(28px, 3.2vw, 40px) 0 0;
}

/* ── Les familles, sur fond clair ────────────────────────────────────── */

/* « .checkpoints » et « .familles » sont dessinés pour la bande ardoise de
   l'accueil : leur texte est blanc cassé par conception. Posés sur du papier,
   ils deviennent illisibles. La landing a donc sa propre liste — et c'est
   mieux ainsi : elle ne redit pas visuellement ce que l'accueil montre déjà.

   Le numéro tient sa colonne, le filet sépare, et rien n'est encadré : six
   cartes de plus alourdiraient une page qui en a déjà. */
.familles-claires {
  display: grid;
  margin: clamp(34px, 4vw, 48px) 0 0;
  padding: 0;
  counter-reset: familles;
  gap: 0;
  grid-template-columns: minmax(0, 1fr);
  list-style: none;
}

.familles-claires > li {
  display: grid;
  min-width: 0;
  padding: clamp(20px, 2.2vw, 26px) 0;
  border-top: 1px solid var(--line);
  gap: 2px 18px;
  grid-template-columns: 34px minmax(0, 1fr);
  color: var(--ink);
  counter-increment: familles;
  font-family: var(--display);
  font-size: clamp(1.04rem, 1.7vw, 1.18rem);
  font-weight: 600;
  letter-spacing: -0.008em;
}

.familles-claires > li::before {
  color: var(--ardoise);
  content: counter(familles, decimal-leading-zero);
  font-family: var(--mono);
  font-size: 0.76rem;
  font-weight: 500;
  grid-row: 1 / span 2;
  padding-top: 0.32em;
}

.familles-claires > li span {
  display: block;
  max-width: 52ch;
  color: var(--body);
  font-family: var(--text);
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.55;
}

@media (min-width: 861px) {
  .familles-claires { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(36px, 4vw, 64px); }
}

/* ── Les familles de contrôles ───────────────────────────────────────── */

/* .checkpoints de l'accueil, avec une ligne d'explication sous chaque
   libellé : le nom d'une famille ne suffit pas à dire ce qu'on regarde.
   Même traitement que la liste des douze points de la Loi 25.

   La règle de rédaction vit dans le HTML, pas ici : chaque famille dit quoi
   et pourquoi, jamais comment. Aucun nom d'outil, aucune charge utile. */
.familles { gap: 28px 56px; }
.familles li { min-height: 0; }

.familles li span {
  display: block;
  margin-top: 7px;
  color: #bcc7d6;
  font-family: var(--text);
  font-size: 0.86rem;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.5;
}

/* ── Les états de sévérité ───────────────────────────────────────────── */

/* .etat de l'accueil ne connaît que « conforme » et « écart ». Un rapport de
   sécurité classe autrement : le schéma porte cinq niveaux, dont trois
   suffisent à montrer la structure sans surcharger l'exemple. */
.etat-eleve { background: rgba(140, 58, 44, 0.13); color: var(--sev-eleve); }
.etat-moyen { background: rgba(122, 90, 28, 0.14); color: var(--sev-moyen); }
.etat-faible { background: rgba(74, 90, 107, 0.13); color: var(--sev-faible); }

.constat-eleve { border-left-color: var(--sev-eleve); }
.constat-moyen { border-left-color: var(--sev-moyen); }
.constat-faible { border-left-color: var(--sev-faible); }

/* ── L'autorisation ──────────────────────────────────────────────────── */

.autorisation { padding: clamp(80px, 7vw, 112px) 0; background: var(--ardoise-voile); }

.autorisation-layout {
  display: grid;
  align-items: center;
  gap: clamp(38px, 5vw, 76px);
  grid-template-columns: minmax(0, 1fr);
}

.autorisation-liste {
  margin: clamp(26px, 3vw, 36px) 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid rgba(44, 64, 104, 0.22);
}

.autorisation-liste li {
  padding: 16px 0;
  border-bottom: 1px solid rgba(44, 64, 104, 0.22);
}

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

.autorisation-liste span {
  display: block;
  margin-top: 5px;
  max-width: 54ch;
  color: var(--body);
  font-size: 0.94rem;
}

/* ── Les trois offres ────────────────────────────────────────────────── */

/* LA JAUGE DE PROFONDEUR. Ce qui sépare réellement les trois offres, c'est
   jusqu'où l'examen descend. Trois barres empilées le disent avant même le
   paragraphe : une remplie pour le diagnostic, trois pour l'audit, trois plus
   une libre pour le sur-mesure. Le crochet de gauche est le mandat, en
   pointillé quand le périmètre se définit avec vous.

   Ce n'est pas un ornement. Depuis que les trois cartes sont identiques,
   c'est la seule chose qui les distingue, et elle se lit sans lire. */
.jauge {
  display: block;
  width: min(100%, 168px);
  height: auto;
  margin: 0 0 clamp(20px, 2.2vw, 28px);
  overflow: visible;
}

.jauge-pleine { fill: var(--ardoise); }
.jauge-vide { fill: rgba(44, 64, 104, 0.13); }
.jauge-libre { fill: none; stroke: var(--ardoise); stroke-width: 1.4; stroke-dasharray: 4 3; }
.jauge-crochet { fill: none; stroke: var(--ardoise); stroke-width: 1.4; stroke-linecap: round; }
.jauge-crochet-libre { fill: none; stroke: var(--ardoise); stroke-width: 1.4; stroke-linecap: round; stroke-dasharray: 4 3; }

/* Les barres se posent l'une après l'autre : la profondeur se lit comme une
   descente, pas comme un état déjà acquis. */
@keyframes jauge-descendre {
  0%, 8% { transform: scaleX(0); opacity: 0; }
  22%, 84% { transform: scaleX(1); opacity: 1; }
  96%, 100% { transform: scaleX(0); opacity: 0; }
}

@media (prefers-reduced-motion: no-preference) {
  .offer-layout.tourne .jauge-pleine,
  .offer-layout.tourne .jauge-libre {
    transform-origin: 26px center;
    animation: jauge-descendre 8s var(--ease-out) infinite;
  }

  .offer-layout.tourne .offer:nth-child(2) .jauge-pleine:nth-of-type(2) { animation-delay: 160ms; }
  .offer-layout.tourne .offer:nth-child(2) .jauge-pleine:nth-of-type(3) { animation-delay: 320ms; }
  .offer-layout.tourne .offer:nth-child(3) .jauge-pleine:nth-of-type(2) { animation-delay: 160ms; }
  .offer-layout.tourne .offer:nth-child(3) .jauge-pleine:nth-of-type(3) { animation-delay: 320ms; }
  .offer-layout.tourne .offer:nth-child(3) .jauge-libre { animation-delay: 480ms; }

  .js-mouvement.onglet-cache .jauge-pleine,
  .js-mouvement.onglet-cache .jauge-libre { animation-play-state: paused; }
}

/* Les trois listes n'ont pas le même nombre d'items : la liste pousse ce qui
   la suit vers le bas pour que les cartes se terminent ensemble. */
.securite-page .offer .included { margin-bottom: auto; }

/* Le master dessine la grille de l'accueil, où DEUX offres se partagent la
   largeur. Sécurité en a trois : sans cette règle, la troisième tombait
   seule sur une deuxième rangée, à la largeur de la première colonne.
   Sous 961 px le master replie déjà tout sur une colonne, ce qui convient
   à trois cartes autant qu'à deux — il n'y a donc rien à y reprendre. */
@media (min-width: 961px) {
  .securite-page .offer-layout { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Les deux offres latérales. « .offer-free » de l'accueil porte le filet,
   mais son nom parle d'une gratuité qui n'existe pas ici. On donne donc la
   surface à « .offer », en excluant explicitement la carte centrale : sans
   ce « :not », cette règle plus spécifique effacerait le marine du master. */
.securite-page .offer {
  border: 1px solid var(--line);
  background: var(--white);
}

.offer-footer {
  max-width: 64ch;
  margin: clamp(26px, 3vw, 36px) 0 0;
  color: var(--muted);
  font-size: 0.95rem;
}

/* ── Les limites ─────────────────────────────────────────────────────── */

/* Sur un service de sécurité, dire la limite vaut plus que promettre
   l'étendue. Cette section est volontairement aussi soignée que l'offre. */




/* Les deux passerelles. Ce ne sont pas des limites mais des renvois : elles
   se distinguent par le voile, pas par un composant de plus. */




/* La lisibilité des listes, et les jauges de profondeur ci-dessous. */

/* « .included » de l'accueil n'a jamais servi que dans la carte marine : son
   texte est en #e1e6e9, un blanc cassé qui disparaît sur fond clair. Les
   trois offres étant désormais claires, la liste reprend l'encre du corps et
   le point passe à l'ardoise. */
.securite-page .included li { color: var(--body); }
.securite-page .included li::before { background: var(--ardoise); }

/* Une seule colonne. À deux, dans une carte de 380 px, chaque item se cassait
   en quatre lignes : « Un / examen / de / surface ». */
.securite-page .included {
  grid-template-columns: minmax(0, 1fr);
  gap: 11px;
}

/* Aucune des trois n'est mise en avant : rien ne dit au visiteur ce que les
   autres achètent, il choisit sur ce dont il a besoin. */
.securite-page .offer h3 {
  max-width: none;
  margin: 0;
  color: var(--ink);
  font-size: clamp(1.5rem, 2.2vw, 1.95rem);
}

.securite-page .offer-delai { color: var(--ardoise); }
.securite-page .offer-intro { color: var(--body); }

/* ── Le fondateur ────────────────────────────────────────────────────── */

/* Le master ne donne à « .credibility » qu'un rembourrage haut : sur
   l'accueil, une bande de sources vient juste après et ferme la section.
   Sécurité n'en a pas, donc la photo et le bouton touchaient le bord. */
.securite-page .credibility { padding-bottom: clamp(84px, 7vw, 106px); }

/* ── Les limites, marquées ───────────────────────────────────────────── */

/* Cinq négations à la suite : un marqueur commun leur donne un rythme et dit
   d'un coup d'œil qu'il s'agit d'exclusions, sans qu'il faille lire les cinq
   intitulés pour le comprendre. Un dessin par ligne aurait été cinq fois le
   même geste, donc du bruit. */
.limites > li::before {
  width: 18px;
  height: 18px;
  align-self: start;
  margin-top: 0.18em;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Ccircle cx='9' cy='9' r='7.4' fill='none' stroke='%238c3a2c' stroke-opacity='.5' stroke-width='1.3'/%3E%3Cline x1='4.6' y1='13.4' x2='13.4' y2='4.6' stroke='%238c3a2c' stroke-opacity='.5' stroke-width='1.3' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat center / 18px 18px;
  content: "";
  grid-row: 1 / span 2;
}

/* ── Les passerelles ─────────────────────────────────────────────────── */

/* Les deux autres services de la maison. C'était le dernier bloc à garder le
   fond lavande retiré partout ailleurs. Il reprend maintenant le sceau et le
   nom composé de l'en-tête : le visiteur reconnaît la marque avant de lire.

   La carte entière est le lien, pas un mot à l'intérieur : la cible est plus
   grande, et il n'y a plus deux gestes possibles pour une seule intention. */
.passerelles-intro {
  margin: clamp(30px, 3.4vw, 44px) 0 16px;
  color: var(--muted);
  font-size: 0.95rem;
}

.passerelles {
  display: grid;
  gap: 14px;
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 761px) {
  .passerelles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.passerelle {
  display: grid;
  align-items: center;
  padding: clamp(18px, 2vw, 24px);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--white);
  gap: 16px;
  grid-template-columns: 44px minmax(0, 1fr) 20px;
  text-decoration: none;
  transition: border-color 240ms var(--ease-out), transform 240ms var(--ease-out), box-shadow 240ms var(--ease-out);
}

.passerelle img { width: 44px; height: 44px; }

.passerelle-corps { display: grid; gap: 6px; min-width: 0; }

.passerelle-nom {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-family: var(--display);
  line-height: 1.1;
}

.passerelle-nom span { color: var(--muted); font-size: 0.86rem; font-weight: 500; }
.passerelle-nom b { color: var(--ardoise-fonce); font-size: 1.08rem; font-weight: 700; letter-spacing: -0.015em; }

.passerelle-quoi { color: var(--body); font-size: 0.92rem; line-height: 1.5; }

.passerelle-fleche {
  color: var(--ardoise);
  font-size: 1.05rem;
  transition: transform 240ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .passerelle:hover {
    border-color: rgba(44, 64, 104, 0.4);
    transform: translateY(-2px);
    box-shadow: 0 16px 34px -24px rgba(16, 37, 28, 0.5);
  }

  .passerelle:hover .passerelle-fleche { transform: translate(3px, -3px); }
}

@media (max-width: 420px) {
  .passerelle { grid-template-columns: 36px minmax(0, 1fr); }
  .passerelle img { width: 36px; height: 36px; }
  .passerelle-fleche { display: none; }
}

/* ── 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;
  gap: 20px;
  color: var(--ink);
  cursor: pointer;
  font-family: var(--display);
  font-size: clamp(1.02rem, 1.7vw, 1.18rem);
  font-weight: 600;
  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(--ardoise); }

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

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

/* Dernière section, sur le marine de la famille : la page se termine sur une
   seule action. Le formulaire crée une fiche au CRM — pas un audit, pas une
   autorisation. La copie le dit, et le bouton porte le seul libellé retenu
   pour tout le site. */

.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);
}

.demande-copie h2 {
  margin: 0 0 20px;
  color: var(--white);
  font-family: var(--display);
  font-size: clamp(2rem, 3.6vw, 2.85rem);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.08;
}

.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-rappel {
  margin-top: 22px;
  padding: 16px 18px;
  border-left: 2px solid var(--yellow);
  background: rgba(253, 254, 252, 0.06);
}

.demande-rappel p { max-width: 44ch; margin: 0; color: rgba(253, 254, 252, 0.9); font-size: 0.94rem; }

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

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

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

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

.champ-aide { margin: 0; color: var(--muted); font-size: 0.86rem; }

/* 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(--white);
  color: var(--ink);
  font-family: var(--text);
  font-size: 1rem;
}

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

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

/* La case d'autorité. Elle est obligatoire côté serveur autant que côté
   navigateur : c'est une déclaration, pas la signature du mandat, et la
   copie le dit pour que personne ne les confonde. */
.champ-case {
  display: grid;
  align-items: start;
  gap: 10px;
  grid-template-columns: 20px minmax(0, 1fr);
}

.champ-case input { width: 20px; height: 20px; min-height: 0; margin-top: 3px; }
.champ-case label { color: var(--body); font-size: 0.92rem; font-weight: 400; }

/* 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. Le serveur applique la même règle de son côté. */
.piege { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.formulaire-etat { margin: 0; padding: 12px 14px; border-radius: var(--radius-control); font-size: 0.94rem; }
.formulaire-etat.est-succes { background: var(--ardoise-voile); color: var(--ardoise-fonce); }
.formulaire-etat.est-erreur { background: rgba(140, 58, 44, 0.12); color: var(--sev-eleve); }
.formulaire-etat:focus-visible { outline: 2px solid var(--ardoise); outline-offset: 2px; }

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

/* Atteintes seulement par le repli sans JavaScript : le chemin normal reste
   sur la page et affiche sa confirmation en place. */
.retour { padding: clamp(88px, 9vw, 140px) 0 clamp(72px, 7vw, 108px); }
.retour h1 { margin: 12px 0 18px; }
.retour p { max-width: 60ch; }
.retour-actions { display: flex; align-items: center; margin-top: 30px; gap: 22px; flex-wrap: wrap; }

/* ── Les illustrations ───────────────────────────────────────────────── */

/* Trois dessins au trait, pas un de plus. Même facture que Maintenance :
   trait fin, deux couleurs, aucun aplat, aucune icône de cybersécurité. */

.vue { display: block; width: 100%; height: auto; }
.vue-trait { fill: none; stroke: var(--ardoise); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.vue-trait-pale { fill: none; stroke: rgba(44, 64, 104, 0.34); stroke-width: 1.2; stroke-linecap: round; }
.vue-plein { fill: var(--ardoise); }
.vue-pale { fill: rgba(44, 64, 104, 0.12); }
.vue-texte { fill: var(--muted); font-family: var(--mono); font-size: 10px; letter-spacing: 0.03em; }
.vue-exclu { fill: none; stroke: var(--sev-eleve); stroke-width: 1.4; stroke-dasharray: 4 4; stroke-linecap: round; }

.vue-cadre { overflow-x: auto; overscroll-behavior-x: contain; }
.vue-cadre .vue { min-width: 420px; }

.vue-cadre {
  padding: clamp(22px, 2.6vw, 32px);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--white);
}

.vue-legende { margin: 14px 0 0; color: var(--muted); font-size: 0.88rem; }

/* ── Le mouvement ────────────────────────────────────────────────────── */

/* Rappel de la règle : ça se déclenche, ça révèle, ça s'arrête. Aucune de
   ces animations ne se répète, et aucune n'est infinie. */

@keyframes mandat-ligne-entre {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

@keyframes sev-etire {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@keyframes tampon-pose {
  from { opacity: 0; transform: scale(0.94); }
  to { opacity: 1; transform: none; }
}

/* Le tracé du périmètre. Le trait se dessine une fois, à l'arrivée à
   l'écran, puis reste. C'est « établir une limite », pas « balayer ». */
@keyframes perimetre-trace {
  from { stroke-dashoffset: var(--trace, 660); }
  to { stroke-dashoffset: 0; }
}

/* Le périmètre se retrace : établir la limite est un geste qui se refait à
   chaque mandat, pas une image figée. */
@keyframes perimetre-cycle {
  0% { stroke-dashoffset: var(--trace, 660); }
  20%, 80% { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: var(--trace, 660); }
}

@media (prefers-reduced-motion: no-preference) {
  .mandat.est-vu .mandat-ligne { animation: mandat-ligne-entre 420ms var(--ease-out) backwards; }
  .mandat.est-vu .mandat-ligne:nth-child(1) { animation-delay: 380ms; }
  .mandat.est-vu .mandat-ligne:nth-child(2) { animation-delay: 450ms; }
  .mandat.est-vu .mandat-ligne:nth-child(3) { animation-delay: 520ms; }
  .mandat.est-vu .mandat-ligne:nth-child(4) { animation-delay: 590ms; }
  .mandat.est-vu .mandat-ligne:nth-child(5) { animation-delay: 660ms; }

  .mandat.est-vu .sev-barre { animation: sev-etire 560ms var(--ease-out) 780ms backwards; }

  /* Le tampon ferme la séquence, après la dernière ligne et après les
     barres : la relecture humaine vient en dernier parce qu'elle vient en
     dernier dans le service. */
  .mandat.est-vu .mandat-tampon { animation: tampon-pose 420ms var(--ease-out) 1020ms backwards; }

  .vue-perimetre.est-vu .vue-anime {
    stroke-dasharray: var(--trace, 660);
    animation: perimetre-trace 1100ms var(--ease-out) both;
  }
}

/* ── Les points de rupture ───────────────────────────────────────────── */

@media (min-width: 721px) {
  .autorisation-layout { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); }
}

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

@media (max-width: 720px) {
  .familles { gap: 22px; }
  .mandat-ligne { grid-template-columns: minmax(0, 1fr); }
  .mandat-ligne dt { padding-top: 0; }
}

@media (max-width: 520px) {
  .mandat-tete { flex-direction: column; align-items: flex-start; gap: 8px; }
  .retour-actions { align-items: flex-start; flex-direction: column; gap: 14px; }
}

/* Le respect du calme absolu. Même liste que l'accueil : tout ce que cette
   feuille anime doit y être neutralisé, sinon une préférence système reste
   sans effet sur les objets propres au service. */
@media (prefers-reduced-motion: reduce) {
  .site-header,
  .famille-bande a,
  .etape-jetons li,
  .method-flow > li,
  .hero .eyebrow,
  .hero h1,
  .hero h1 mark,
  .hero-lead,
  .hero-actions,
  .feuille-mention,
  .mandat-ligne,
  .sev-barre,
  .mandat-tampon,
  .hero h1 .ligne > span,
  .hero-copy,
  .passerelle,
  .passerelle-fleche,
  .vue-contour,
  .vue-fermeture,
  .vue-sceau,
  .vue-coche,
  .vue-breche-bords,
  .vue-signature,
  .vue-objet-cible,
  .lecture-lignes span,
  .lecture-lignes b,
  .vp-intrus,
  .vp-intrus-ligne,
  .vp-fuite,
  .vp-absent,
  .hero-securite::after,
  .vue-anime {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    stroke-dashoffset: 0 !important;
  }
}
