/* ==========================================================================
   EMDR — site vitrine (landing). S'appuie sur les design tokens de
   style.css (thème clair par défaut + sombre via :root[data-theme=dark]).
   ========================================================================== */

.lp { background: var(--color-background); color: var(--color-text); }
.lp-wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px; }
.lp-narrow { max-width: 760px; }
.lp .center { text-align: center; }
.lp .btn { width: auto; }                 /* neutralise le .btn{width:100%} global */
.lp h1, .lp h2, .lp h3 { color: var(--color-primary); line-height: var(--line-height-heading); letter-spacing: -.01em; }
.lp p { line-height: var(--line-height-relaxed); }
.lp a { color: inherit; }

/* ---------- En-tête ---------- */
/* Masqué à l'affichage de la page, révélé dès le début du défilement, puis
   présent en permanence (il se re-masque uniquement de retour tout en haut). */
.lp-header { position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  background: color-mix(in srgb, var(--color-background) 92%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--color-border-light);
  transform: translateY(-100%); transition: transform .28s ease; }
.lp-header.show { transform: translateY(0); }
.lp-header-in { display: flex; align-items: center; gap: 20px; height: 66px; }
.lp-nav { display: flex; gap: 26px; margin-inline-end: auto; }   /* logique : s'inverse en RTL */
.lp-nav a { color: var(--color-text-secondary); text-decoration: none; font-weight: var(--font-weight-medium); font-size: 15px; }
.lp-nav a:hover { color: var(--color-primary); }
.lp-header-cta { display: flex; align-items: center; gap: 14px; margin-left: 8px; }
.lp-link { color: var(--color-primary); text-decoration: none; font-weight: var(--font-weight-semibold); font-size: 15px; }
.lp-header-cta .btn { padding: 10px 18px; font-size: 15px; }

/* ---------- Boutons spécifiques ---------- */
.lp-btn-ghost { background: transparent; border-color: color-mix(in srgb, var(--color-primary) 30%, transparent); color: var(--color-primary); }
.lp-btn-ghost:hover { background: var(--color-primary-soft); }

/* ---------- Hero ---------- */
/* Bandeau sombre à fond PLAT (aucun effet de lumière). L'en-tête étant fixe et
   masqué en haut de page, le bandeau démarre au tout premier pixel. */
.lp-hero { position: relative; overflow: hidden; text-align: center; color: #fff;
  padding: 104px 0 112px; background: var(--color-primary); }
.lp-hero-in { position: relative; z-index: 2; }
.lp-hero-logo { display: block; height: clamp(44px, 6vw, 72px); width: auto; margin: 0 auto 28px; }
.lp-hero .lp-btn-ghost { background: transparent; border-color: rgba(255,255,255,.45); color: #fff; }
.lp-hero .lp-btn-ghost:hover { background: rgba(255,255,255,.12); }
.lp-hero .btn-primary { background: #fff; color: var(--color-primary); border-color: #fff; }
.lp-hero .btn-primary:hover { background: rgba(255,255,255,.88); }
.lp-eyebrow { display: inline-block; font-size: 13px; font-weight: var(--font-weight-semibold); letter-spacing: .06em; text-transform: uppercase; color: var(--color-coral-hover, #b9756c); background: var(--color-surface); border: 1px solid var(--color-border-light); padding: 6px 12px; border-radius: var(--radius-pill); }
.lp-eyebrow.center { display: block; width: max-content; margin: 0 auto 14px; }
.lp-hero h1 { color: #fff; font-size: clamp(30px, 4.4vw, 50px); font-weight: var(--font-weight-bold); margin: 0 0 18px; }
.lp-hero .lp-lead { font-size: 18px; color: rgba(255,255,255,.82); max-width: 40em; margin: 0 auto; }
.lp-hero .lp-lead strong { color: #fff; }
.lp-lead { font-size: 18px; color: var(--color-text-secondary); max-width: 34em; }
.lp-hero-actions { display: flex; gap: 14px; margin: 30px 0 16px; flex-wrap: wrap; }
.lp-hero-actions.center { justify-content: center; }
.lp-hero-reassure { font-size: 14px; color: rgba(255,255,255,.68); }

/* Rond de fond : uniquement DERRIÈRE LE BANDEAU (clippé par son overflow), bords
   nets, quasi transparent. Aucune animation auto : il traverse de GAUCHE à DROITE
   au rythme du défilement du hero. */
.lp-hero-dot { position: absolute; z-index: 1; pointer-events: none;
  top: 46%; left: 50%; width: clamp(120px, 15vw, 200px); aspect-ratio: 1;
  margin-left: calc(clamp(120px, 15vw, 200px) / -2);
  border-radius: 50%; background: rgba(255, 255, 255, .09);
  transform: translate3d(0, 0, 0); will-change: transform; }

/* ---------- Rythme des sections ---------- */
.lp-section { padding: 76px 0; }
.lp-alt { background: var(--color-background-soft); }
.lp-section > .lp-wrap > h2, .lp-adn h2 { font-size: clamp(24px, 3vw, 34px); font-weight: var(--font-weight-bold); margin: 0 0 6px; }
.lp-sub { font-size: 17px; color: var(--color-text-secondary); margin: 0 0 34px; }
/* Une section sans sous-titre (« Pourquoi ») : le titre reprend à son compte
   l'écart que portait le paragraphe retiré. */
.lp-section > .lp-wrap > h2 + .lp-grid { margin-block-start: 34px; }

/* ---------- ADN ---------- */
.lp-adn h2 { font-size: clamp(28px, 4vw, 44px); margin-bottom: 12px; }   /* volontairement plus gros */
.lp-adn-txt { font-size: 19px; line-height: 1.7; color: var(--color-text); text-align: justify; margin-top: 10px; }
.lp-adn-txt strong { color: var(--color-primary); }

/* ---------- Grilles de cartes ---------- */
.lp-grid { display: grid; gap: 20px; }
.lp-grid-4 { grid-template-columns: repeat(4, 1fr); }
.lp-grid-2 { grid-template-columns: repeat(2, 1fr); }
/* Vignettes « Pourquoi » : picto BLANC en filigrane dans le fond de carte,
   texte par-dessus, titre en couleur primaire. */
.lp-card { position: relative; overflow: hidden; border: 0; border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--color-primary) 10%, #fff);
  padding: 76px 24px 26px; box-shadow: none; }
/* Le picto occupe TOUT le fond de la carte, en blanc à 20 %. */
.lp-card-ic { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; filter: brightness(0) invert(1); opacity: .2;
  z-index: 0; pointer-events: none; }
.lp-card h3 { position: relative; z-index: 1; color: var(--color-primary); font-size: 19px; font-weight: var(--font-weight-bold); margin: 0 0 8px; }
.lp-card p { position: relative; z-index: 1; font-size: 14.5px; color: var(--color-text-secondary); margin: 0; }

/* Fonctionnalités : liste éditoriale (ni vignettes, ni émojis, pour ne pas
   répéter la matrice ci-dessus). */
.lp-featlist { max-width: 900px; margin: 34px auto 0; }
.lp-featrow { display: grid; grid-template-columns: 1fr 1.35fr; gap: 28px; padding: 22px 2px; border-top: 1px solid var(--color-border-light); align-items: baseline; }
.lp-featrow:last-child { border-bottom: 1px solid var(--color-border-light); }
.lp-featrow dt { margin: 0; color: var(--color-primary); font-size: 17px; font-weight: var(--font-weight-semibold); }
.lp-featrow dd { margin: 0; color: var(--color-text-secondary); font-size: 15.5px; line-height: var(--line-height-relaxed); }

/* Les cartes « Comment ça marche » (.lp-steps / .lp-step) ont disparu avec la
   section qu'elles habillaient : leurs trois étapes sont désormais les légendes de
   la frise animée (.fa-steps). La boule de fin de page est définie avec le pied de
   page, plus bas. */

/* ---------- Tarifs ---------- */
.lp-notice { max-width: 720px; margin: 0 auto 20px; padding: 12px 16px; border-radius: var(--radius-md); background: var(--color-info-background); border: 1px solid color-mix(in srgb, var(--color-info) 40%, transparent); color: var(--color-text); font-size: 14.5px; text-align: center; }
/* Changement de devise / pays : petit lien discret SOUS la grille tarifaire. */
.lp-region-swap { margin-top: 20px; text-align: center; font-size: 14px; }
.lp-region-swap summary { cursor: pointer; color: var(--color-text-secondary); text-decoration: underline; list-style: none; display: inline-block; }
.lp-region-swap summary::-webkit-details-marker { display: none; }
.lp-region-swap summary:hover { color: var(--color-primary); }
.lp-region-swap form { display: flex; justify-content: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.lp-region-swap select { width: auto; min-width: 240px; }
.lp-plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; align-items: stretch; }
.lp-plan { position: relative; display: flex; flex-direction: column; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 28px 26px; box-shadow: var(--shadow-sm); }
.lp-plan.featured { border-color: #D8A7A0; box-shadow: var(--shadow-md); }
.lp-plan-flag { position: absolute; top: -12px; left: 50%; transform: translateX(-50%); background: #D8A7A0; color: var(--color-primary); font-size: 12px; font-weight: var(--font-weight-semibold); padding: 5px 14px; border-radius: var(--radius-pill); white-space: nowrap; z-index: 2; }

/* L'écart entre les offres est symbolisé par un rond en fond, dont le CENTRE est
   l'angle bas gauche de la carte : seul le quart intérieur est visible. Son rayon
   vaut 10 % (Libre), 20 % (Essentiel), 30 % (Studio) de la hauteur de la carte. */
.lp-plan::before { content: ""; position: absolute; left: 0; bottom: 0; z-index: 0;
  aspect-ratio: 1; width: auto; pointer-events: none;
  border-radius: 0 100% 0 var(--radius-lg); }
.lp-plan-libre::before     { height: 10%; background: rgba(171, 160, 188, .18); }
.lp-plan-essentiel::before { height: 20%; background: rgba(216, 167, 160, .18); }
.lp-plan-studio::before    { height: 30%; background: rgba(216, 167, 160, .18); }
.lp-plan > *:not(.lp-plan-flag) { position: relative; z-index: 1; }
.lp-plan h3 { font-size: 22px; margin: 0; }
.lp-plan-tag { color: var(--color-text-secondary); font-size: 14px; margin: 4px 0 16px; }
.lp-price { margin-bottom: 18px; min-height: 62px; }
.lp-amount { font-size: 34px; font-weight: var(--font-weight-bold); color: var(--color-text); }
.lp-cur { font-size: 14px; color: var(--color-text-secondary); font-weight: var(--font-weight-medium); }
.lp-year { font-size: 13px; color: var(--color-text-secondary); margin-top: 4px; }
.lp-vat-note { font-size: 13px; opacity: .85; max-width: 78ch; margin-left: auto; margin-right: auto; }
.lp-plan-feats { list-style: none; margin: 0 0 22px; padding: 0; display: grid; gap: 10px; flex: 1; }
.lp-plan-feats li { position: relative; padding-left: 26px; font-size: 14.5px; color: var(--color-text); }
.lp-plan-feats li::before { content: "✓"; position: absolute; left: 0; top: 0; color: var(--color-sage, #7fae86); font-weight: var(--font-weight-bold); }
.lp-plan-cta { width: 100%; }

/* ---------- FAQ ---------- */
.lp-faq { display: grid; gap: 12px; margin-top: 26px; }
.lp-qa { background: var(--color-surface); border: 1px solid var(--color-border-light); border-radius: var(--radius-md); padding: 4px 20px; box-shadow: var(--shadow-xs); }
.lp-qa summary { cursor: pointer; padding: 16px 0; font-weight: var(--font-weight-semibold); color: var(--color-primary); list-style: none; position: relative; padding-right: 28px; }
.lp-qa summary::-webkit-details-marker { display: none; }
.lp-qa summary::after { content: "+"; position: absolute; right: 2px; top: 14px; font-size: 20px; color: var(--color-text-secondary); transition: transform var(--transition-fast); }
.lp-qa[open] summary::after { content: "−"; }
.lp-qa p { margin: 0 0 16px; color: var(--color-text-secondary); font-size: 15px; }

/* ---------- CTA final ---------- */
.lp-cta { position: relative; overflow: hidden; padding: 82px 0; text-align: center; background: var(--color-primary-soft); }   /* fond plat */
/* Quart de rond à gauche, rayon = 70 % de la hauteur du bloc, très transparent. */
.lp-cta::before { content: ""; position: absolute; left: 0; bottom: 0; z-index: 0;
  height: 70%; aspect-ratio: 1; width: auto; border-radius: 0 100% 0 0;
  background: rgba(216, 167, 160, .16); pointer-events: none; }
.lp-cta > * { position: relative; z-index: 1; }
.lp-cta h2 { font-size: clamp(26px, 3.2vw, 36px); font-weight: var(--font-weight-bold); margin: 0 0 12px; }
.lp-cta p { font-size: 17px; color: var(--color-text-secondary); max-width: 40em; margin: 0 auto 26px; }

/* ---------- Pied de page ---------- */
.lp-footer { position: relative; overflow: hidden; border-top: 1px solid var(--color-border-light); padding: 34px 0 62px; background: var(--color-background); }
.lp-footer .lp-wrap { position: relative; z-index: 1; }
/* Boule de toute fin de page : 2 allers-retours lents puis arrêt définitif. */
.lp-end-ball { position: absolute; left: 0; bottom: 14px; z-index: 0; pointer-events: none;
  width: 34px; height: 34px; border-radius: 50%; background: #D8A7A0; opacity: .3; }
.lp-end-ball.run { animation: lpEndBall 9s ease-in-out 2 both; }
@keyframes lpEndBall { 0% { left: 0; } 50% { left: calc(100% - 34px); } 100% { left: 0; } }
.lp-footer-in { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.lp-footer-logo { height: 26px; }
.lp-footer-links { display: flex; gap: 22px; margin-left: auto; flex-wrap: wrap; }
.lp-footer-links a { color: var(--color-text-secondary); text-decoration: none; font-size: 14px; }
.lp-footer-links a:hover { color: var(--color-primary); }
.lp-footer-note { width: 100%; color: var(--color-text-muted); font-size: 13px; }

/* ---------- Sélecteur de langue fixe, en bas à droite ---------- */
/* Sélecteur de langue du bandeau.
   Il remplace la pastille flottante en bas d'écran : celle-ci recouvrait le
   contenu sur mobile et arrivait trop tard, après que le visiteur eut décidé
   qu'il ne comprenait pas la page. Ici il est vu avant la première ligne.
   Sans cadre ni fond : c'est un réglage, pas une action — les deux boutons
   voisins doivent rester les seuls éléments appelants du bandeau. */
.lp-lang { display: flex; align-items: center; }
.lp-lang .lang-select { display: flex; align-items: center; gap: 6px; margin: 0; color: var(--color-text-secondary); }
.lp-lang select {
  width: auto; min-width: 0; border: 0; background: transparent; box-shadow: none;
  color: inherit; font-size: 14px; padding: 4px 20px 4px 2px; cursor: pointer;
}
.lp-lang .lang-select:hover { color: var(--color-text); }
/* Sous 640 px le bandeau se resserre : le libellé disparaît, le globe suffit à
   dire ce que fait le menu, et la surface de clic reste entière. */
@media (max-width: 640px) {
  .lp-lang select { padding-inline-end: 16px; text-indent: -9999px; width: 24px; }
}

/* ---------- Responsive ---------- */
@media (max-width: 960px) {
  .lp-grid-4 { grid-template-columns: repeat(2, 1fr); }
  .lp-nav { display: none; }
}
@media (max-width: 720px) {
  .lp-section { padding: 52px 0; }
  .lp-hero { padding: 76px 0 72px; }
  .lp-featrow { grid-template-columns: 1fr; gap: 6px; }
  .lp-grid-2, .lp-plans { grid-template-columns: 1fr; }
  .lp-plan.featured { order: -1; }
  .lp-header-cta .lp-link { display: none; }
}
@media (max-width: 460px) {
  .lp-grid-4 { grid-template-columns: 1fr; }
  .lp-hero-actions .btn { width: 100%; }
}


/* ==========================================================================
   « UN FONCTIONNEMENT SIMPLE » — section id="fonctionnement".
   Trois temps : le schéma animé de la séance, le dessin cabinet/distance,
   puis les écrans réels dans leurs cadres + la galerie.

   Tout est en PROPRIÉTÉS LOGIQUES : la page est servie en arabe (dir="rtl") et
   la composition entière doit se retourner sans une seule règle en plus.
   Aucun JavaScript n'est nécessaire à l'affichage ; le seul script de la
   section transforme le panneau de la galerie en vraie fenêtre modale.
   ========================================================================== */

/* Le rythme interne : chaque temps est une respiration, pas une carte. */
/* La section reste BLANCHE : les panneaux des deux dessins sont peints en
   « background-soft » et disparaîtraient dans un fond doux. Depuis que la section
   « Comment ça marche » a été absorbée ici, c'est « Fonctionnalités » qui porte le
   fond doux juste après, et l'alternance se referme d'elle-même — le filet de
   rattrapage qui séparait deux sections blanches n'a plus lieu d'être.

   Cible d'ancre vide : #usage, l'adresse de la section absorbée, doit continuer
   d'aboutir ici (voir index.php). Elle ne doit rien occuper dans le flux. */
.lp-anchor { display: block; block-size: 0; }
.lp-fonc-beat { margin-block-start: 68px; }
.lp-fonc-beat > h3 { font-size: clamp(19px, 2.2vw, 24px); font-weight: var(--font-weight-bold); margin: 0 0 6px; text-align: center; }
.lp-fonc-lead { font-size: 16.5px; color: var(--color-text-secondary); text-align: center; max-inline-size: 46em; margin: 0 auto 30px; }
@media (max-width: 720px) { .lp-fonc-beat { margin-block-start: 46px; } }


/* ==========================================================================
   FRISE « A » ANIMÉE — schéma du parcours d'une séance.
   SVG en ligne + CSS. Aucun JavaScript, aucune image, aucune dépendance.

   Trois temps en boucle sur un cycle unique (--fa-cycle) :
     1%–27%   le praticien compose la fiche de séance (téléphone ET ordinateur)
     28%–61%  les carrés corail traversent le fil vers le patient
     62%–95%  le point balaie l'écran du patient
   Tout partage la MÊME durée et le MÊME cycle : les phases sont découpées en
   pourcentages plutôt qu'en animation-delay, sinon les décalages dérivent d'une
   itération à l'autre et les trois temps finissent désynchronisés.

   ÉTAT AU REPOS = ÉTAT COMPLET. Le SVG est écrit dans sa position finale
   (fiches remplies, carrés sur le fil, point au bout de la barre) ; ce sont les
   animations qui l'effacent puis le reconstruisent. Conséquence : couper les
   animations (prefers-reduced-motion, CSS partiellement chargé, capture PDF)
   redonne d'office une image complète et lisible des trois temps à la fois,
   sans une seule règle de repli à maintenir.
   ========================================================================== */

.fa {
  --fa-cycle: 12s;

  --fa-bg:          #FBFAF8;
  --fa-frame:       #4D4254;   /* aubergine : la matière des appareils        */
  --fa-screen:      #FFFFFF;
  --fa-line:        #E9E5EF;   /* lavande claire : les lignes d'une fiche     */
  --fa-label:       #AAA0BC;   /* lavande : l'intitulé                        */
  --fa-wire:        #AAA0BC;   /* lavande : le canal, jamais ce qui y circule */
  --fa-coral:       #D8A7A0;   /* corail : ce qui vient du praticien          */
  --fa-coral-light: #F2DEDA;
  --fa-rule:        #E8E1DC;
  --fa-text:        #39363C;
  --fa-text-2:      #777078;

  color: var(--fa-text);
  margin: 0;
}

/* Le thème sombre du site est porté par :root[data-theme="dark"] (assets/style.css).
   Les appareils s'inversent : cadre clair, écran sombre. Le second sélecteur est
   une prise en main directe — data-theme="dark" posé sur la figure elle-même —
   utile pour montrer la version de nuit dans une page de jour. */
:root[data-theme="dark"] .fa,
.fa[data-theme="dark"] {
  --fa-bg:          #211E26;
  --fa-frame:       #C5B9D2;
  --fa-screen:      #2E2A33;
  --fa-line:        #3E3748;
  --fa-label:       #8E82A8;
  --fa-wire:        #8E82A8;
  --fa-coral:       #E0AAA3;
  --fa-coral-light: #4E3C3A;
  --fa-rule:        #39333E;
  --fa-text:        #F7F4F8;
  --fa-text-2:      #BBB3BF;
}

/* --- le dessin ------------------------------------------------------------ */

.fa-svg { display: block; inline-size: 100%; block-size: auto; border-radius: var(--radius-lg); }

/* dir="rtl" : la composition entière se retourne. Le fil part alors de l'autre
   côté, les fiches se remplissent depuis le bord droit et le point balaie dans
   l'autre sens. C'est possible parce qu'AUCUN texte ne vit dans le SVG : il n'y
   a rien à l'intérieur qui se lirait à l'envers. */
[dir="rtl"] .fa-svg { transform: scaleX(-1); }

.fa-bg     { fill: var(--fa-bg); }
.fa-frame  { fill: var(--fa-frame); }
.fa-screen { fill: var(--fa-screen); }
.fa-line   { fill: var(--fa-line); }
.fa-label  { fill: var(--fa-label); }
.fa-pill   { fill: var(--fa-coral-light); }
.fa-seed,
.fa-sq,
.fa-dot    { fill: var(--fa-coral); }
.fa-trail  { fill: var(--fa-coral-light); }
.fa-wire   { fill: none; stroke: var(--fa-wire); stroke-width: 2;
             stroke-linecap: round; stroke-dasharray: 3 15; }

/* --- temps courant : l'actif à pleine force, les autres apaisés ----------- */

.fa-stage--a { animation: fa-stage-a var(--fa-cycle) ease infinite; }
.fa-stage--b { animation: fa-stage-b var(--fa-cycle) ease infinite; }
.fa-stage--c { animation: fa-stage-c var(--fa-cycle) ease infinite; }

@keyframes fa-stage-a { 0%, 27% { opacity: 1 }  33%, 96% { opacity: .48 } 100% { opacity: 1 } }
@keyframes fa-stage-b { 0%, 26% { opacity: .48 } 32%, 61% { opacity: 1 }  67%, 100% { opacity: .48 } }
@keyframes fa-stage-c { 0%, 58% { opacity: .48 } 64%, 95% { opacity: 1 }  100% { opacity: .48 } }

/* --- temps 1 : la fiche se compose --------------------------------------- */

/* transform-box: fill-box → l'origine est le coin de la forme elle-même, donc
   chaque ligne se déplie depuis SON bord de départ. Sous le scaleX(-1) du RTL,
   ce bord est celui de droite : la fiche se remplit dans le sens de lecture. */
.fa-fill { transform-box: fill-box; transform-origin: 0% 50%; }
.fa-fill--1 { animation: fa-fill-1 var(--fa-cycle) cubic-bezier(.2,.7,.3,1) infinite; }
.fa-fill--2 { animation: fa-fill-2 var(--fa-cycle) cubic-bezier(.2,.7,.3,1) infinite; }
.fa-fill--3 { animation: fa-fill-3 var(--fa-cycle) cubic-bezier(.2,.7,.3,1) infinite; }
.fa-fill--4 { animation: fa-fill-4 var(--fa-cycle) cubic-bezier(.2,.7,.3,1) infinite; }
.fa-fill--5 { animation: fa-fill-5 var(--fa-cycle) cubic-bezier(.2,.7,.3,1) infinite; }
.fa-fill--6 { animation: fa-fill-6 var(--fa-cycle) cubic-bezier(.2,.7,.3,1) infinite; }

@keyframes fa-fill-1 { 0%,  1% { opacity: 0; transform: scaleX(.04) }  7%, 95% { opacity: 1; transform: scaleX(1) } 100% { opacity: 0; transform: scaleX(.04) } }
@keyframes fa-fill-2 { 0%,  5% { opacity: 0; transform: scaleX(.04) } 11%, 95% { opacity: 1; transform: scaleX(1) } 100% { opacity: 0; transform: scaleX(.04) } }
@keyframes fa-fill-3 { 0%,  9% { opacity: 0; transform: scaleX(.04) } 15%, 95% { opacity: 1; transform: scaleX(1) } 100% { opacity: 0; transform: scaleX(.04) } }
@keyframes fa-fill-4 { 0%, 13% { opacity: 0; transform: scaleX(.04) } 19%, 95% { opacity: 1; transform: scaleX(1) } 100% { opacity: 0; transform: scaleX(.04) } }
@keyframes fa-fill-5 { 0%, 17% { opacity: 0; transform: scaleX(.04) } 23%, 95% { opacity: 1; transform: scaleX(1) } 100% { opacity: 0; transform: scaleX(.04) } }
@keyframes fa-fill-6 { 0%, 21% { opacity: 0; transform: scaleX(.04) } 27%, 95% { opacity: 1; transform: scaleX(1) } 100% { opacity: 0; transform: scaleX(.04) } }

/* le point corail de la fiche : le réglage, posé une fois la ligne dépliée */
.fa-seed { transform-box: fill-box; transform-origin: 50% 50%; }
.fa-pop--a { animation: fa-pop-a var(--fa-cycle) cubic-bezier(.2,1.2,.4,1) infinite; }
.fa-pop--b { animation: fa-pop-b var(--fa-cycle) cubic-bezier(.2,1.2,.4,1) infinite; }
@keyframes fa-pop-a { 0%, 18% { opacity: 0; transform: scale(.2) } 22%, 95% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(.2) } }
@keyframes fa-pop-b { 0%, 22% { opacity: 0; transform: scale(.2) } 26%, 95% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(.2) } }

/* --- temps 2 : la traversée ---------------------------------------------- */

/* Les pointillés avancent de 6 périodes exactement (6 × 18 = 108) : au bouclage
   le motif retombe sur lui-même, il n'y a pas de saut visible. */
.fa-wire { animation: fa-ants var(--fa-cycle) linear infinite; }
@keyframes fa-ants { 0%, 29% { stroke-dashoffset: 0 } 61%, 100% { stroke-dashoffset: -108px } }

.fa-sq { animation-duration: var(--fa-cycle); animation-timing-function: linear; animation-iteration-count: infinite; }
.fa-sq--a { animation-name: fa-sq-a }
.fa-sq--b { animation-name: fa-sq-b }
.fa-sq--c { animation-name: fa-sq-c }

/* Chaque carré est POSÉ à sa place de repos (358 / 424 / 490) et voyage autour :
   il part du départ du fil et finit à l'écran, en passant par sa position au
   repos. Animation coupée, les trois retombent donc espacés sur le fil. */
@keyframes fa-sq-a { 0%, 28% { transform: translateX(-47px);  opacity: 0 } 31% { opacity: 1 } 50% { opacity: 1 } 53%, 100% { transform: translateX(165px); opacity: 0 } }
@keyframes fa-sq-b { 0%, 32% { transform: translateX(-100px); opacity: 0 } 35% { opacity: 1 } 54% { opacity: 1 } 57%, 100% { transform: translateX(112px); opacity: 0 } }
@keyframes fa-sq-c { 0%, 36% { transform: translateX(-153px); opacity: 0 } 39% { opacity: 1 } 58% { opacity: 1 } 61%, 100% { transform: translateX(59px);  opacity: 0 } }

/* --- temps 3 : le balayage ------------------------------------------------ */

/* La séance s'ouvre chez le patient au moment où les carrés arrivent. */
.fa-arrive { animation: fa-arrive var(--fa-cycle) ease infinite; }
@keyframes fa-arrive { 0%, 56% { opacity: 0 } 62%, 96% { opacity: 1 } 100% { opacity: 0 } }

/* La barre-guide ET les jalons pâles sont la NOTATION d'un mouvement : ils ne
   servent qu'à l'image fixe. Dès que le point balaie pour de bon, ils s'effacent.
   Sans cela, un point corail seul au bout d'une barre grise se lit comme la
   poignée d'un curseur — un objet qu'on tire — et non comme un stimulus qui va
   et vient tout seul. Vu en capture, corrigé. */
.fa-repos { animation: fa-repos var(--fa-cycle) linear infinite; }
@keyframes fa-repos { from, to { opacity: 0 } }

.fa-dot { animation: fa-dot var(--fa-cycle) ease-in-out infinite; }
@keyframes fa-dot {
  0%,  62% { transform: translateX(-168px); opacity: 0 }
  65%      { transform: translateX(-168px); opacity: 1 }
  72%      { transform: translateX(0);      opacity: 1 }
  79%      { transform: translateX(-168px); opacity: 1 }
  86%      { transform: translateX(0);      opacity: 1 }
  93%      { transform: translateX(-168px); opacity: 1 }
  97%, 100%{ transform: translateX(-168px); opacity: 0 }
}

/* --- la légende (HTML : elle se traduit, elle se lit, elle se sélectionne) - */

.fa-steps {
  list-style: none; margin: 26px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px;
}
.fa-step {
  position: relative;
  padding-block-start: 16px;
  border-block-start: 2px solid var(--fa-rule);
  display: flex; align-items: baseline; gap: 10px;
}
.fa-step-bar {
  position: absolute; inset-block-start: -2px; inset-inline-start: 0;
  block-size: 2px; inline-size: 0%;
  background: var(--fa-coral);
}
.fa-step-n {
  flex: none;
  font-size: 13px; font-weight: 600; line-height: 1;
  color: var(--fa-coral);
  font-variant-numeric: tabular-nums;
}
.fa-step-x { font-size: 15px; line-height: 1.5; color: var(--fa-text-2); }
.fa-step-x p { margin: 0; }
/* La couleur vient des jetons de la frise, pas du .lp h3 global : c'est ce qui
   fait suivre le titre au thème sombre comme le reste du dessin. */
.fa-step-t { margin: 0; margin-block-end: 4px; font-size: 15.5px;
  font-weight: var(--font-weight-semibold); line-height: 1.35; color: var(--fa-text); }

@media (max-width: 720px) { .fa-steps { grid-template-columns: 1fr; gap: 14px; } }

/* LE TEXTE DES TROIS TEMPS NE SE MET PLUS EN RETRAIT. Il portait une animation
   d'opacite (.38 hors du temps courant) heritee de l'epoque ou ces trois phrases
   n'etaient qu'une legende : le meme recit vivait a pleine lisibilite dans la
   section « Comment ca marche ». Cette section a fusionne ici, donc ce texte est
   desormais LE SEUL exemplaire. Or a .38 il tombe a 1,65:1 (description) et
   1,97:1 (titre) contre un plancher de 4,5:1, et deux temps sur trois sont dans
   cet etat a chaque instant. Aucune valeur d'opacite ne sauve la description :
   a pleine opacite elle est deja a 4,80:1. Le repere du temps courant est donc
   porte par la seule jauge corail ci-dessous, qui ne porte aucun texte. */

/* La jauge corail avance sur la durée du temps courant : c'est le repère de
   progression. inline-size (et non scaleX) pour qu'elle parte du bord de début
   en RTL sans une seule règle directionnelle en plus. */
.fa-step--1 .fa-step-bar { animation: fa-bar-1 var(--fa-cycle) linear infinite; }
.fa-step--2 .fa-step-bar { animation: fa-bar-2 var(--fa-cycle) linear infinite; }
.fa-step--3 .fa-step-bar { animation: fa-bar-3 var(--fa-cycle) linear infinite; }
@keyframes fa-bar-1 { 0% { inline-size: 0%; opacity: 1 } 27% { inline-size: 100%; opacity: 1 } 33% { inline-size: 100%; opacity: 0 } 34%, 99% { inline-size: 0%; opacity: 0 } 100% { inline-size: 0%; opacity: 1 } }
@keyframes fa-bar-2 { 0%, 28% { inline-size: 0%; opacity: 1 } 61% { inline-size: 100%; opacity: 1 } 67% { inline-size: 100%; opacity: 0 } 68%, 100% { inline-size: 0%; opacity: 0 } }
@keyframes fa-bar-3 { 0%, 62% { inline-size: 0%; opacity: 1 } 95% { inline-size: 100%; opacity: 1 } 98% { inline-size: 100%; opacity: 0 } 99%, 100% { inline-size: 0%; opacity: 0 } }

/* --- mouvement désarmé ---------------------------------------------------- */

/* On coupe, on ne remplace pas : le repos est déjà l'état complet. Les trois
   temps sont alors visibles ensemble (fiches pleines, carrés sur le fil, point
   au bout de sa course) et les trois légendes sont lisibles, jauges pleines. */
@media (prefers-reduced-motion: reduce) {
  .fa *, .fa-steps * { animation: none !important; }
  .fa-step { opacity: 1 !important; }
  .fa-step-bar { inline-size: 100%; opacity: 1; }
}




/* ==========================================================================
   CADRES D'APPAREIL — le châssis est en CSS (fluide, sans viewBox à tenir) ;
   seul le CONTENU de l'écran est une image. Remplacer un dessin de substitution
   par une vraie capture ne touche donc rien d'autre que le fichier déposé.
   ========================================================================== */

.dv { --dv-body: var(--color-primary, #4D4254); margin: 0; }
.dv-screen { position: relative; overflow: hidden; background: #fff; }
.dv-shot { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; object-position: 50% 0; }
.dv-cam { position: absolute; inset-inline: 0; margin-inline: auto; border-radius: 50%; background: var(--color-lavender, #AAA0BC); }

/* Écran de bureau — 16:9, pied central. */
.dv-desk .dv-lid   { background: var(--dv-body); border-radius: 14px; padding: 14px 14px 16px; position: relative; }
.dv-desk .dv-screen{ aspect-ratio: 16 / 9; border-radius: 4px; }
.dv-desk .dv-cam   { inset-block-start: 5px; inline-size: 4px; block-size: 4px; }
.dv-desk .dv-neck  { inline-size: 15%; block-size: 22px; background: var(--dv-body); margin-inline: auto; }
.dv-desk .dv-base  { inline-size: 34%; block-size: 9px; background: var(--dv-body); border-radius: 5px; margin-inline: auto; }

/* Ordinateur portable — 16:10. Le capot est RENTRÉ de 5,5 % de chaque côté et
   le socle occupe toute la largeur : c'est le socle qui doit déborder du capot,
   pas le composant qui doit déborder de sa colonne. Une largeur en 112 % avec
   marge négative fabriquait une barre de défilement horizontale dans les mises
   en page serrées — et sur mobile, la vitrine EST une mise en page serrée. */
.dv-laptop .dv-lid   { position: relative; margin-inline: 5.5%; background: var(--dv-body); border-radius: 12px; padding: 12px 10px 14px; }
.dv-laptop .dv-screen{ aspect-ratio: 16 / 10; border-radius: 4px; }
.dv-laptop .dv-cam   { inset-block-start: 5px; inline-size: 4px; block-size: 4px; }
.dv-laptop .dv-base  { position: relative; inline-size: 100%; block-size: 10px; background: var(--dv-body); border-radius: 0 0 10px 10px; }
.dv-laptop .dv-base::after { content: ""; position: absolute; inset-block-start: 0; inset-inline: 0; margin-inline: auto; inline-size: 18%; block-size: 4px; border-radius: 0 0 4px 4px; background: rgba(255,255,255,.22); }

/* Tablette — 4:3. Prévue par la convention de nommage ; aucun dossier ne
   l'utilise aujourd'hui, elle attend le jour où le client en déposera un. */
.dv-tab .dv-body  { position: relative; background: var(--dv-body); border-radius: 20px; padding: 18px 14px; }
.dv-tab .dv-screen{ aspect-ratio: 4 / 3; border-radius: 6px; }
.dv-tab .dv-cam   { inset-block-start: 7px; inline-size: 5px; block-size: 5px; }

/* Téléphone — 9:19.5 */
.dv-phone .dv-body  { position: relative; background: var(--dv-body); border-radius: 22px; padding: 12px 7px 14px; }
.dv-phone .dv-screen{ aspect-ratio: 9 / 19.5; border-radius: 15px; }
.dv-phone .dv-cam   { inset-block-start: 5px; inline-size: 4px; block-size: 4px; }
.dv-phone .dv-home  { position: absolute; inset-block-end: 5px; inset-inline: 0; margin-inline: auto; inline-size: 42%; block-size: 3px; border-radius: 2px; background: rgba(255,255,255,.28); }

/* Arabe : la composition se retourne, la capture non — sauf si c'est un DESSIN.
   Les dessins de substitution ne contiennent aucun glyphe : les retourner
   présente l'interface comme l'application la présente réellement en RTL. Une
   vraie capture, elle, porte du texte : Captures.php ne lui met jamais cette
   classe (voir la règle « miroir » du fichier). */
[dir="rtl"] .dv-shot--mirror { transform: scaleX(-1); }

/* Les appareils sont alignés par le BAS ; leurs légendes ayant des longueurs
   différentes, une hauteur est réservée pour toutes, sans quoi les châssis ne
   reposent pas sur la même ligne de sol. La rangée elle-même est dimensionnée par
   le visionneur (.sv-row), plus bas. */
.dv-cap { margin: 14px 0 0; min-block-size: 4.4em; text-align: center; font-size: 14px; line-height: 1.45; color: var(--color-text-secondary); }


/* ==========================================================================
   GALERIE — <dialog> natif : le navigateur fournit Échap, le piège au clavier
   et le fond assombri, gratuitement et mieux qu'un script maison.

   SANS JAVASCRIPT, la galerie reste atteignable : le lien pointe sur l'ancre
   #lp-galerie, et :target sort le panneau de son display:none pour l'ouvrir
   EN PLEINE PAGE, dans le flux, sous les appareils. Rien n'est perdu — ni les
   images, ni les légendes, ni la fermeture (le lien « Fermer » ramène à la
   section). Avec JavaScript, la règle :target est neutralisée par la classe
   .lp-js posée sur <html> et le panneau devient une vraie fenêtre modale.
   ========================================================================== */

.lp-gal-more { text-align: center; margin: 28px 0 0; }
.lp-gal-open { display: inline-block; color: var(--color-primary); font-weight: var(--font-weight-semibold);
  font-size: 15.5px; text-decoration: underline; text-underline-offset: 4px; padding: 8px 4px; }
.lp-gal-open:hover { color: var(--color-coral-hover, #b9756c); }

/* Panneau, quelle que soit sa forme. */
.lp-gal { color: var(--color-text); background: var(--color-surface); border: 0; padding: 0; }
.lp-gal-in { padding: 26px clamp(16px, 3vw, 30px) 34px; }
.lp-gal-head { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap;
  padding-block-end: 14px; border-block-end: 1px solid var(--color-border-light); margin-block-end: 22px; }
.lp-gal-head h3 { margin: 0; font-size: 20px; font-weight: var(--font-weight-bold); }
.lp-gal-close { margin-inline-start: auto; color: var(--color-text-secondary); font-size: 15px;
  text-decoration: underline; text-underline-offset: 4px; padding: 6px 8px; }
.lp-gal-close:hover { color: var(--color-primary); }
.lp-gal-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 30px; }
/* margin: 0 SUR LA FIGURE — sans quoi la marge par defaut du navigateur
   (figure { margin: 1em 40px }) mange 80 px de large et « Agrandir » RETRECIT
   l'image sous environ 1000 px : mesure a 390 px, 314 px en ligne contre 240 px
   dans la galerie, soit x0,76. Le visionneur avait sa regle, la galerie non. */
.lp-gal-list figure { margin: 0; }
.lp-gal-list img { display: block; inline-size: 100%; block-size: auto;
  border: 1px solid var(--color-border-light); border-radius: var(--radius-md); background: #fff; }
.lp-gal-list figcaption { margin-block-start: 10px; font-size: 14.5px; color: var(--color-text-secondary); }
.lp-gal-dev { font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-text-muted); }

/* 1. Sans JavaScript : panneau ouvert dans le flux par l'ancre. */
:root:not(.lp-js) .lp-gal:target {
  display: block; position: static; margin-block: 30px 0;
  inline-size: auto; max-inline-size: none; block-size: auto;
  border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
}
/* 2. Avec JavaScript : vraie fenêtre modale. */
.lp-gal[open] { inline-size: min(980px, 92vw); max-block-size: 88vh; overflow: auto;
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg, 0 24px 60px rgba(0,0,0,.28)); }
.lp-gal::backdrop { background: rgba(57, 54, 60, .58); }

/* L'EN-TETE RESTE COLLE QUAND LE PANNEAU DEFILE. Cliquer une capture fait
   maintenant defiler le panneau jusqu'a elle ; sans cette regle l'en-tete — et
   avec lui le SEUL lien « Fermer » — sortait du cadre des le premier defilement.
   Sur un telephone il ne restait alors ni Echap, ni bouton : mesure a 390 px,
   « Fermer » se retrouvait a -549 px. La bande peinte remonte dans le padding de
   .lp-gal-in pour qu'aucune image ne passe derriere un fond transparent. */
.lp-gal[open] .lp-gal-head {
  position: sticky; inset-block-start: 0; z-index: 2;
  background: var(--color-surface);
  margin-block-start: -26px; padding-block-start: 26px;
  margin-block-end: 0;
}
.lp-gal[open] .lp-gal-list { margin-block-start: 22px; }
/* La cible du defilement se pose SOUS l'en-tete colle, sinon elle passe dessous. */
.lp-gal[open] .lp-gal-list > li { scroll-margin-block-start: 88px; }
/* SUR UN TELEPHONE, « Agrandir » doit agrandir pour de bon. A 390 px le panneau
   a 92vw moins ses gouttieres ne rendait l'image que 6 px plus large qu'en ligne
   (314 -> 320) : la promesse du lien n'etait pas tenue. En pleine largeur elle
   passe a 370 px, et le panneau occupe tout l'ecran, ce qui est la vraie valeur
   du geste sur un petit ecran : voir la capture sans le reste de la page. */
@media (max-width: 560px) {
  .lp-gal[open] { inline-size: 100vw; max-inline-size: 100vw; max-block-size: 100vh; border-radius: 0; }
  .lp-gal[open] .lp-gal-in { padding-inline: 10px; }
}


/* ==========================================================================
   « UNE SEULE APPLICATION POUR TOUTES VOS SÉANCES » (.du) — au milieu
   l'application, d'un côté la séance à distance, de l'autre la séance au cabinet.

   ÉQUILIBRE PAR CONSTRUCTION. Un côté n'est pas dessiné deux fois : il est POSÉ
   deux fois (<use href="#du-cote-l">, la seconde en miroir autour de l'axe). Les
   deux usages ont donc le même inventaire de formes, aux mêmes distances de
   l'axe — impossibles à faire diverger. Seules les PIÈCES diffèrent, à surface
   égale : 261 + 121 = 382 de large contre 382 d'un tenant en paysage, 128 + 246
   = 374 de haut contre 374 en portrait. Reste 0,4 % d'écart, qui est le rognage
   de quatre coins arrondis de plus du côté coupé en deux.

   RIEN NE BOUGE : sur un outil de stimulation visuelle, un schéma explicatif se
   lit, il ne s'agite pas. prefers-reduced-motion n'a donc rien à désarmer ici, et
   l'état de repos EST l'état complet.

   AUCUNE COULEUR EN DUR — c'est ce qui manquait au dessin remplacé : tout vient
   des jetons de assets/style.css, qui ont déjà leurs valeurs de nuit.
   ========================================================================== */

.du { margin: 0; }
.du-svg { display: block; inline-size: 100%; block-size: auto; border-radius: var(--radius-lg); }

/* Le dessin raconte un côté et l'autre ; en arabe il se retourne avec la page.
   Aucun glyphe à l'intérieur : le miroir est sans danger, et la légende (grille
   HTML) se retourne avec lui, chaque libellé restant sous sa partie. */
[dir="rtl"] .du-svg { transform: scaleX(-1); }

.du-bg     { fill: var(--color-background-soft); }
.du-room   { fill: color-mix(in srgb, var(--color-lavender) 28%, var(--color-background-soft)); }
.du-card   { fill: var(--color-surface); stroke: color-mix(in srgb, var(--color-lavender) 45%, transparent); stroke-width: 2; }
.du-label  { fill: var(--color-lavender); }
.du-line   { fill: color-mix(in srgb, var(--color-lavender) 28%, var(--color-surface)); }
.du-pill   { fill: var(--color-coral-light); }
.du-knob,
.du-sq,
.du-dot    { fill: var(--color-coral); }
.du-trail  { fill: color-mix(in srgb, var(--color-coral) 35%, var(--color-surface)); }
.du-frame  { fill: var(--color-primary); }
.du-screen { fill: var(--color-surface); }
.du-person { fill: var(--color-lavender); }
.du-wire   { fill: none; stroke: var(--color-lavender); stroke-width: 2;
             stroke-linecap: round; stroke-dasharray: 3 15; }

/* Deux dessins, pas une réorganisation : sous 640 px l'axe se redresse et les deux
   usages descendent sous l'application. Un seul est rendu à la fois — display:none
   le sort du rendu comme de l'arbre d'accessibilité. */
.du-svg--portrait { display: none; }
@media (max-width: 640px) {
  .du-svg--paysage  { display: none; }
  .du-svg--portrait { display: block; max-inline-size: 360px; margin-inline: auto; }
}

/* Trois colonnes sous trois parties : chaque libellé tombe sous ce qu'il nomme. */
.du-legend { list-style: none; margin: 0; margin-block-start: 22px; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.du-legend li { padding-block-start: 14px; border-block-start: 2px solid var(--color-border); }
.du-legend b { display: block; color: var(--color-primary); font-size: 15.5px;
  font-weight: var(--font-weight-semibold); margin-block-end: 4px; }
.du-legend span { color: var(--color-text-secondary); font-size: 15px; line-height: var(--line-height-relaxed); }
@media (max-width: 720px) { .du-legend { grid-template-columns: 1fr; gap: 14px; } }


/* ==========================================================================
   VISIONNEUR DE CAPTURES (.sv) — les écrans du produit, en grand, sous l'ADN.

   Une PAGE = un sujet (mener une séance, tableau de bord…), montré sur tous les
   appareils à la fois. On passe d'une page à l'autre par une ancre : :target, pas
   une ligne de JavaScript. L'adresse #sv-2 est partageable, le bouton Précédent
   revient à la page 1, et le clavier n'a que des liens à parcourir.

   Le format de l'écran vient de la CAPTURE, jamais du châssis : rien n'est rogné,
   et la place est réservée avant même que l'image arrive.

   Ce bloc est le DERNIER du fichier : .sv .dv--ar .dv-screen doit passer après
   les formats canoniques des châssis (.dv-desk, .dv-phone…) pour les remplacer.
   ========================================================================== */

.sv { margin-block-start: clamp(30px, 5vw, 56px); }

/* Une page visible à la fois. La première l'est par défaut — c'est l'état sans
   fragment d'adresse, donc l'état d'arrivée sur la page d'accueil. */
.sv-page { display: none; scroll-margin-block-start: clamp(72px, 11vh, 130px); }
.sv-page:first-child { display: block; }
.sv-page:target      { display: block; }
/* …et la page 1 se retire quand une autre est demandée. Si :has() manque, la page
   1 et la page demandée restent visibles l'une sous l'autre : deux sujets au lieu
   d'un, mais aucune image perdue et aucune commande cassée. */
.sv:has(.sv-page:target) .sv-page:first-child:not(:target) { display: none; }

/* La rangée : le sujet en grand, ses variantes d'appareil à côté, tous posés sur
   la même ligne de sol. Largeurs relatives, jamais fixes — c'est ce qui évite un
   débordement horizontal sur un téléphone. */
.sv-row { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: center;
  gap: clamp(16px, 3vw, 34px); }
.sv-fig { margin: 0; }
.sv-fig--main { inline-size: min(780px, 66%); }
.sv-fig--side { inline-size: min(300px, 27%); }
@media (max-width: 860px) {
  .sv-fig--main { inline-size: 100%; }
  .sv-fig--side { inline-size: min(240px, 48%); }
}

/* FORMAT RÉEL. --dv-ar est posé par PHP d'après les dimensions du fichier, et la
   classe .dv--ar n'est mise QUE si elles ont pu être lues. Un dessin .svg n'en a
   pas : il garde le format canonique de son châssis, sans exception à écrire. */
.sv .dv--ar .dv-screen { aspect-ratio: var(--dv-ar); }
.sv .dv-screen { background: var(--color-surface-sunken, #EDEBF0); }

/* Cliquer une capture ouvre la galerie AU BON ENDROIT. C'est un vrai lien : sans
   JavaScript il mène à l'image en pleine page, avec JavaScript il ouvre la fenêtre
   et la fait défiler jusqu'à elle. */
.sv-zoom { display: block; block-size: 100%; position: relative; }
.sv-zoom:focus-visible { outline: 3px solid var(--color-primary, #4D4254); outline-offset: -3px; }
.sv-zoom-lab { position: absolute; inset-block-end: 10px; inset-inline-end: 10px;
  display: inline-block; padding: 5px 11px; border-radius: var(--radius-pill, 999px);
  font-size: 13px; font-weight: var(--font-weight-semibold, 600); line-height: 1.3;
  color: #fff; background: rgba(45, 40, 50, .82); backdrop-filter: blur(2px);
  opacity: 0; transition: opacity .18s ease; pointer-events: none; }
.sv-zoom:hover .sv-zoom-lab,
.sv-zoom:focus-visible .sv-zoom-lab { opacity: 1; }
/* Sans survol possible (tactile), l'invitation ne peut pas se mériter : elle est là
   d'emblée. Même chose sous prefers-reduced-motion — l'état de repos devient l'état
   COMPLET, jamais l'état vide. */
@media (hover: none) { .sv-zoom-lab { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .sv-zoom-lab { opacity: 1; transition: none; } }

/* Légendes courtes, une ou deux lignes : les châssis restent alignés par le bas
   sans réserver le pavé de trois lignes des anciennes légendes. */
.sv .dv-cap { margin-block-start: 16px; min-block-size: 2.9em; font-size: 15px;
  text-align: center; line-height: 1.45; color: var(--color-text-secondary); }

/* LA PAGINATION. Elle est RECOPIÉE dans chaque page : la seule visible est celle
   de la page affichée, et c'est ce qui permet d'écrire aria-current dans le HTML —
   un état juste, calculé par le serveur, sans énumérer les pages en CSS. */
/* Le texte posé SUR --color-primary. De jour la teinte est sombre et le texte est
   blanc ; de nuit --color-primary devient un lavande clair où le blanc serait
   illisible. La pastille active reprend alors le fond de l'application. */
.sv { --sv-on-primary: #fff; }
:root[data-theme="dark"] .sv { --sv-on-primary: var(--color-app-bg, #131117); }

.sv-pager { display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: 10px; margin-block-start: clamp(20px, 3vw, 30px); }
.sv-pip { display: inline-flex; align-items: center; gap: 9px;
  padding-block: 9px; padding-inline: 14px 18px;
  border: 1px solid var(--color-border, #E8E1DC); border-radius: var(--radius-pill, 999px);
  background: var(--color-surface, #fff); color: var(--color-text-secondary);
  font-size: 15px; line-height: 1.25; text-decoration: none; }
.sv-pip-n { display: inline-flex; align-items: center; justify-content: center;
  inline-size: 24px; block-size: 24px; border-radius: 50%; flex: 0 0 auto;
  background: var(--color-border-light, #F0EBE7); color: var(--color-primary);
  font-size: 13px; font-weight: var(--font-weight-bold, 700); }
/* Le numéro est du TEXTE : il porte le rang de la page. Mesuré, le gris
   secondaire sur le fond de puce tombait à 4,06:1 en thème clair — sous le
   plancher. La teinte primaire remonte à 8,5:1 et vaut dans les deux thèmes. */
a.sv-pip:hover { color: var(--color-primary); border-color: var(--color-primary); }
a.sv-pip:focus-visible { outline: 3px solid var(--color-primary); outline-offset: 2px; }
.sv-pip[aria-current] { background: var(--color-primary, #4D4254); border-color: var(--color-primary, #4D4254);
  color: var(--sv-on-primary); font-weight: var(--font-weight-semibold, 600); cursor: default; }
.sv-pip[aria-current] .sv-pip-n { background: var(--color-surface, #fff); color: var(--color-primary, #4D4254); }

/* GALERIE — arrivée sur UNE image précise, sans JavaScript. Cliquer une capture
   cible son <li> dans le panneau : la règle ci-dessous ouvre le panneau parce
   qu'il CONTIENT la cible, et le navigateur fait le défilement lui-même. */
:root:not(.lp-js) .lp-gal:has(:target) {
  display: block; position: static; margin-block: 30px 0;
  inline-size: auto; max-inline-size: none; block-size: auto;
  border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
}
.lp-gal-list > li { scroll-margin-block-start: 18px; }
.lp-gal-list > li:target figure { outline: 3px solid var(--color-primary); outline-offset: 6px; border-radius: 4px; }
