/* La page /a-propos/ (#162 lot ①) — « Révélation » : ouverture crème, passage d'encre, retour à la
 * lumière. Bucket ③, identité d'île. Chargée par /a-propos/ SEULE, après css/style.css.
 *
 * Tous les sélecteurs commencent par `.ap-` : une règle nue toucherait le jour où la feuille serait
 * chargée ailleurs (leçon `.hero-tag` : une neutralisation ne protège que son fichier). Le sur-titre
 * du H1 sort de `renderH1` avec la classe `.hero-tag` de l'accueil, que la règle globale peint en
 * CRÈME : il est repeint ici PAR PRÉFIXE (`.ap-h1 .hero-tag`, S6). Gardé par a-propos.test.cjs.
 *
 * Sans `.ap-entree` ni `.is-armed` : page IMMOBILE (lot ①) — aucun état de départ, aucune animation ;
 * le seul geste est celui du bouton (`.btn-outline`, style.css). La partition du lot ② est en fin de
 * feuille, entièrement sous ces deux classes (garde : a-propos.test.cjs, G2).
 *
 * Bornes de colonne en `rem` / `em`, jamais `ch` (elles suivraient la police RENDUE, −12 % en repli
 * Jost). Cadres photo : hauteur ≤ 70 % de l'écran de 360 à 1 440 px — largeur plafonnée en `svh`
 * (4:5 → 56svh, 3:2 → 105svh) ; `svh`, jamais `vh` : stable quand la barre d'iOS bouge. Preuve :
 * scripts/chrome/sonde-cadres.mjs.
 *
 * Encres CALCULÉES (contrast-core) : --color-accent 5,43:1 sur --color-bg (sur-titre, titres de blocs
 * crème) ; sur l'encre (--color-text) : crème α .86 = 12,01:1, α .72 = 8,73:1, --color-accent-dark
 * 5,88:1.
 */

/* ── Briques communes ─────────────────────────────────────────────────────────────────────────── */
/* Corps Jost (L8) : 1,0625rem / 1,7 sur tout texte courant de la page. */
.ap-bloc p,
.ap-corps {
  font-size: 1.0625rem;
  line-height: 1.7;
}
.ap-bloc { max-width: 28rem; }
.ap-bloc h2,
.ap-retour h2,
.ap-aparte h2 {
  font-family: var(--font-body);
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  line-height: 1.6;
  color: var(--color-accent);
  margin-bottom: 0.6rem;
}

/* Cadres : UN format par emplacement. Le cadre est un calque isolé (le lot ② y fond ses calques de lumière et de voile). */
.ap-cadre {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--color-surface);
}
.ap-cadre--45 { aspect-ratio: 4 / 5; }
.ap-cadre--32 { aspect-ratio: 3 / 2; }
.ap-cadre img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ap-legende,
.ap-quote-src {
  border-left: 1px solid var(--color-accent);
  padding-left: 0.85rem;
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.6;
  color: var(--color-muted-text);
}
.ap-legende { margin-top: 1rem; }

/* ── Ouverture ─────────────────────────────────────────────────────────────────────────────────── */
.ap-ouverture {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: 1rem;
  row-gap: 2rem;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: clamp(2rem, 6svh, 4.5rem) var(--gutter) clamp(3rem, 9svh, 6rem);
}
.ap-tete { grid-column: 1 / -1; }

/* H1 en lignes (renderH1) : sur-titre, « Joyce », « Martens ». Cormorant 300, plancher C123. */
.ap-h1 {
  margin: 0;
  font-family: var(--font-title);
  font-weight: 300;
  font-size: clamp(min(3.4rem, 14.507vw), 8.5vw, 6.8rem);
  line-height: 0.95;
  color: var(--color-text);
}
.ap-h1 .hero-tag {
  font-family: var(--font-body);
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  line-height: 1.6;
  color: var(--color-accent);
  margin-bottom: 1.1rem;
}
.ap-h1 .word-mask { display: block; overflow: visible; }
.ap-h1 .italic-mask .word-inner {
  font-style: italic;
  color: var(--color-accent);
  padding-left: 0.55em;
}

.ap-lede {
  margin-top: 1.6rem;
  max-width: 27rem;
  font-family: var(--font-title);
  font-weight: 400;
  font-size: clamp(1.35rem, 2.1vw, 1.6rem);
  line-height: 1.45;
}
.ap-tete .ap-bloc { margin-top: 2.2rem; }
/* Bornes réglées au repli (regime.md §conception, controle-page) : à 1440 le chapeau passait de 4 lignes
   (repli) à 5 (Cormorant chargée) à 26rem — 27rem les accorde ; à 360 le chapitre 1 passait de 5 à 6 lignes
   en pleine colonne (312 px) — 19rem (304 px) sous 375 px les accorde. Mesuré sur le contenu livré (#162). */
@media (max-width: 374.98px) {
  .ap-tete .ap-bloc p { max-width: 19rem; }
}

.ap-portrait {
  grid-column: 1 / -1;
  align-self: start;
  /* 26rem ≈ la colonne de droite à 900 px (397 px) : aucune photo ne grossit d'un coup sous la
     bascule (#162 RETOUR 1, R7 ; à 899 px elle passait de 397 à ≈ 570 px). Preuve : sonde-cadres. */
  width: min(100%, 26rem, 56svh);
}

/* ── Passage d'encre ───────────────────────────────────────────────────────────────────────────── */
/* Section pleine largeur. Sous 900 px, le contenu tient sur une colonne plafonnée (--ap-encre-max) :
   la composition A + B reste à l'échelle au lieu de prendre toute la largeur (R7) ; ≥ 900, la colonne
   du site (--max-w, gouttières comprises). 33rem et non 34 : à 34rem, 899 → 900 px réduisait A de
   544 à 466 px (×0,856) et B de 201 à 171 px (×0,851), sous le seuil de 1/1,15 (sonde-cadres, R10). */
.ap-encre {
  --ap-encre-max: 33rem;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: 1rem;
  row-gap: 2.5rem;
  padding: clamp(4.5rem, 11svh, 7.5rem) max(var(--gutter), calc((100% - var(--ap-encre-max)) / 2))
    clamp(5rem, 12svh, 8rem);
  background: var(--color-text);
  color: var(--color-bg);
  border-top-left-radius: 50% 4.5rem;
  border-top-right-radius: 50% 6.5rem;
  border-bottom-left-radius: 50% 5.5rem;
  border-bottom-right-radius: 50% 3.5rem;
}
.ap-encre > * { grid-column: 1 / -1; }
.ap-encre p { color: rgba(247, 244, 239, 0.86); }
/* Cadre sur l'encre, photo pas encore peinte (backstages en `lazy`) : fond sombre, jamais un rectangle crème. */
.ap-encre .ap-cadre { background: rgba(247, 244, 239, 0.06); }
.ap-encre h2 { color: var(--color-accent-dark); }
.ap-encre .ap-legende,
.ap-encre .ap-quote-src {
  color: rgba(247, 244, 239, 0.72);
  border-color: var(--color-accent-dark);
}

/* Citation (R5) : une vraie citation — <figure> > guillemet anglais “ (ornement, aria-hidden),
   <blockquote>, <figcaption> > <cite> sous le trait vertical des légendes.
   L'ornement est HORS FLUX, en haut de la figure ; sa boîte ne garde que le HAUT du glyphe (0,48em,
   le reste est vide), et la figure réserve cette hauteur PLUS un écart réel avant la phrase : il ne
   touche jamais le texte. Preuve : sonde-cadres (`CONTACT`, boîte de l'ornement ∩ 1re ligne). */
.ap-citation {
  --ap-guillemet: clamp(5rem, 9vw, 7.5rem);
  position: relative;
  margin: 0;
  padding-top: calc(var(--ap-guillemet) * 0.48 + clamp(0.6rem, 1.4vw, 1rem));
}
.ap-citation-mark {
  position: absolute;
  top: 0;
  left: 0;
  font-family: var(--font-title);
  font-weight: 400;
  font-style: normal;
  font-size: var(--ap-guillemet);
  line-height: 1;
  height: 0.48em;
  overflow: hidden;
  color: var(--color-accent-dark);
  user-select: none;
}
.ap-quote {
  margin: 0;
  max-width: 20em;
  font-family: var(--font-title);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(2rem, 4.2vw, 3.6rem);
  line-height: 1.14;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
/* `quoteAccent` : terre cuite claire — l'accent SEUL marque la phrase, sans souligné (Luca 08/10, RETOUR 2 Z2). */
.ap-quote-hl { color: var(--color-accent-dark); }
.ap-citation .ap-quote-src {
  display: inline-block;
  margin-top: 1.6rem;
}
.ap-citation cite { font-style: normal; }

.ap-backstage { align-self: start; }
.ap-backstage--a { width: min(100%, 105svh); }
/* B : cadre sur passe-partout d'encre, filet crème. Sous 900 px il chevauche A — seulement quand A
   est rendu (frère précédent) : sans A, rien à chevaucher. B occupe les colonnes 8 à 12 (R7) ; la
   légende de A reste dans les colonnes 1 à 7 (7 colonnes + 6 gouttières), à gauche de B : au
   chevauchement, B la recouvrait (« STUDIO ET EXT… », 390 px, build #162). */
.ap-backstage--a .ap-legende { max-width: calc((100% - 11rem) / 12 * 7 + 6rem); }
.ap-encre .ap-backstage--b {
  grid-column: 8 / -1;
  justify-self: end;
  position: relative;
  z-index: 1;
  width: min(100%, 56svh);
  padding: 0.5rem;
  background: var(--color-text);
}
.ap-encre .ap-backstage--a + .ap-backstage--b { margin-top: -3.5rem; }
.ap-backstage--b .ap-cadre { border: 1px solid rgba(247, 244, 239, 0.16); }
/* Légende de B : AUCUNE marge négative (#162 RETOUR 3, W1) — le trait part du bord gauche VISIBLE de la
   photo, comme le portrait et A, jamais du passe-partout (garde : sonde-cadres, DÉCALÉ). */

.ap-aparte {
  max-width: 26rem;
  padding-top: 1.4rem;
  border-top: 1px solid rgba(247, 244, 239, 0.16);
}
.ap-aparte p {
  font-family: var(--font-title);
  font-style: italic;
  font-weight: 400;
  font-size: 1.35rem;
  line-height: 1.4;
}

/* ── Retour à la lumière ───────────────────────────────────────────────────────────────────────── */
/* La fin parle avec sa voix (R6) : à gauche le titre du chapitre 4 et l'invitation en grand ; à
   droite le corps, le mot de la fin, la signature FIXE sous le trait vertical, le bouton. Sous 900 px,
   empilé dans cet ordre (= ordre du DOM). */
.ap-retour {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: 1rem;
  row-gap: 2rem;
  align-items: start;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: clamp(4.5rem, 11svh, 7.5rem) var(--gutter);
}
.ap-retour-titre,
.ap-retour-corps { grid-column: 1 / -1; }
.ap-retour-corps {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.4rem;
  max-width: 30rem;
}
.ap-invitation {
  margin-top: 0.6rem;
  font-family: var(--font-title);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(2.6rem, 5.2vw, 4.4rem);
  line-height: 1.02;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.ap-fin {
  font-family: var(--font-title);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.4rem, 2.2vw, 1.65rem);
  line-height: 1.35;
  color: var(--color-accent);
}
.ap-signature {
  margin-top: -0.4rem;
  border-left: 1px solid var(--color-accent);
  padding-left: 0.85rem;
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.6;
  color: var(--color-muted-text);
}
.ap-retour .ap-cta { margin-top: 0.6rem; }

/* ── Ordinateur (≥ 900 px) : deux colonnes à l'ouverture, encre composée ───────────────────────── */
@media (min-width: 900px) {
  .ap-ouverture { align-items: center; }
  .ap-tete { grid-column: 1 / 7; }
  .ap-portrait {
    grid-column: 7 / -1;
    justify-self: end;
    width: min(100%, 31rem, 56svh);
  }

  .ap-encre {
    padding-left: max(var(--gutter), calc((100% - var(--max-w)) / 2 + var(--gutter)));
    padding-right: max(var(--gutter), calc((100% - var(--max-w)) / 2 + var(--gutter)));
  }
  .ap-encre .ap-citation { grid-column: 1 / 10; }
  .ap-encre .ap-backstage--a { grid-column: 1 / 8; margin-top: 1rem; }
  .ap-backstage--a .ap-legende { max-width: none; }
  /* B à droite de la citation : rangée 1 (la citation), 1-2 quand A est rendu dessous. */
  .ap-encre .ap-backstage--b {
    grid-column: 10 / -1;
    grid-row: 1;
    margin-top: 1.5rem;
    padding: 0.6rem;
  }
  .ap-encre .ap-backstage--a + .ap-backstage--b { grid-row: 1 / span 2; margin-top: 1.5rem; }
  /* Colonnes NOMMÉES (jamais `span`) : sans A, un bloc à placement libre irait se loger à côté de
     la source de la citation, sous la colonne de B. */
  .ap-encre .ap-bloc { grid-column: 1 / 5; }
  .ap-encre .ap-bloc + .ap-bloc { grid-column: 5 / 9; }
  .ap-encre .ap-aparte {
    grid-column: 9 / -1;
    padding-top: 0.3rem;
    padding-left: 1.4rem;
    border-top: 0;
    border-left: 1px solid rgba(247, 244, 239, 0.16);
  }

  .ap-retour { align-items: end; }
  .ap-retour-titre { grid-column: 1 / 6; }
  .ap-retour-corps { grid-column: 7 / -1; }
}
/* #162 RETOUR 2, Z5 — une bande où le repli avait une ligne de MOINS qu'en polices chargées dans un
   bloc du 1er écran (relevé au pixel 320 → 1 440 px, 3 moteurs, polices refusées contre chargées). La borne est ≥ la plus
   longue ligne en polices chargées sur toute sa bande : coupures finales inchangées, repli accordé. Les bandes où le repli
   a une ligne de PLUS (ou qu'aucune borne n'accorde sans changer les coupures) ne se règlent pas ici. RETOUR 4 : les
   bornes de l'aparté (900-906 et 1123 px) et celle des chapitres 2-3 (X2, 1000-1039 px, RETOUR 1) sont retirées : sans
   elles, controle-page (hub ef95ad8, chaque bloc jugé à son haut) rend 0 rouge de 1000 à 1040 px au pixel, à 900-906,
   970, 1123 et aux largeurs standard, 3 moteurs — leur rouge venait de l'outil (un conteneur héritait des lignes d'un
   sous-bloc sous le pli). */
@media (min-width: 418px) and (max-width: 420.98px) {
  .ap-tete .ap-bloc p { max-width: 22.5rem; }
}

/* ══ Lot ② — la partition (#162 §7) ══════════════════════════════════════════════════════════════
   Tout état de départ vit sous `.ap-entree` (posée AVANT le 1er rendu par le script de tête : 1re visite
   de la session, ni aperçu ni mouvement réduit : la SIGNATURE) ou sous `.is-armed` (posée par js/a-propos.js,
   à CHAQUE chargement, sur le conteneur d'un geste SOUS le pli : la vie de la page — standard O1-O7). Remplissage `backwards` partout : l'état de départ pendant le délai,
   AUCUN reste à la fin (ni clip, ni transform) — l'état final est le rendu du lot ①.
   Bureau = `(min-width: 900px) and (pointer: fine)`, jamais une largeur seule ; sinon le doigt.

   Le RIDEAU (« le bloc monte derrière son filet ») : le geste est un `transform` (hauteur définitive au
   1er rendu, CLS 0) ; le filet est le bas de la boîte, tenu IMMOBILE à l'écran par un `clip-path` lié
   au transform dans la MÊME étape (bas du clip = course − 0,28em, aux deux bouts : la fenêtre ne bouge
   pas). Aucun enveloppant dans le gabarit : `.ap-lede` et l'aparté n'en ont pas. Le clip d'arrivée
   DÉBORDE la boîte (jambages, accents, italique), comme jmpEcritLigne (style.css), réutilisée telle quelle
   pour l'écriture. */
@keyframes apRideau {
  from { transform: translateY(calc(100% + 0.5em)); clip-path: inset(-0.22em -0.08em calc(100% + 0.22em) -0.08em); }
  to   { transform: none; clip-path: inset(-0.22em -0.08em -0.28em -0.08em); }
}

/* Écriture du nom, bureau ET doigt. `fit-content` : l'écriture balaie le texte, pas la colonne. */
.ap-entree .ap-h1 .hero-tag,
.ap-entree .ap-h1 .word-inner { width: fit-content; }
.ap-entree .ap-h1 .hero-tag { animation: jmpEcritLigne 0.35s linear 0.1s backwards; }
.ap-entree .ap-h1 .word-mask:not(.italic-mask) .word-inner { animation: jmpEcritLigne 0.65s linear 0.25s backwards; }
.ap-entree .ap-h1 .italic-mask .word-inner { animation: jmpEcritLigne 0.65s linear 0.55s backwards; }
/* Chapitre 1 : rideau, bureau ET doigt — chaque ligne (titre, texte) derrière son filet. */
.ap-entree .ap-tete .ap-bloc > * { animation: apRideau 1.05s var(--ease-entree) 1.05s backwards; }

/* Portrait — la LUMIÈRE, en CSS, bureau ET doigt (RETOUR 2, Z0, maquette Lumière v2 ; plus aucun WebGL sur la page).
   Deux calques de 3 largeurs glissés ensemble en `transform`, de -66,667 % à 0 : la lumière entre par le HAUT À
   GAUCHE. PÉNOMBRE (`::before`, multiply) : rgb(18 18 18) = l'ambiance 0,07, blanc (neutre) une fois passée ; HALO
   chaud (`::after`, plus-lighter) sur son bord. Présents dès le 1er rendu (état de départ pendant le délai de 1,2 s :
   au doigt, la fin du nom, S8), cachés hors de leur animation : l'état final est la photo du lot ①. Le nom apFilet
   est gardé (sonde-cadres le guette) ; relais [C2] dans js/a-propos.js. */
@keyframes apFilet {
  from { visibility: visible; transform: translateX(-66.667%); }
  to   { visibility: visible; transform: translateX(0); }
}
/* Le HALO poursuit sa course de 6 % de plus, dans le même temps : à `translateX(0)` sa bande (38-50 % du dégradé)
   touchait encore le coin bas droit d'un cadre 4:5 (jusqu'à 42,9 %) et s'éteignait d'un coup à la fin (banc P6 :
   écart de 42/255 entre 4,39 s et la fin, 3 moteurs). 6 % du calque ≥ (42,9 − 38) % × 3,25 / (3 × 0,927). */
@keyframes apHalo {
  from { visibility: visible; transform: translateX(-66.667%); }
  to   { visibility: visible; transform: translateX(6%); }
}
.ap-entree .ap-portrait .ap-cadre::before,
.ap-entree .ap-portrait .ap-cadre::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 300%;
  pointer-events: none;
  visibility: hidden;
  animation: apFilet 3.2s cubic-bezier(0.45, 0.05, 0.3, 0.95) 1.2s backwards;
}
.ap-entree .ap-portrait .ap-cadre::before {
  z-index: 1;
  mix-blend-mode: multiply;
  background: linear-gradient(112deg, #fff 0%, #fff 46%, rgb(222 222 222) 50%, rgb(128 128 128) 55.5%, rgb(52 52 52) 60.5%, rgb(18 18 18) 64%, rgb(18 18 18) 100%);
}
.ap-entree .ap-portrait .ap-cadre::after {
  z-index: 2;
  mix-blend-mode: plus-lighter;
  animation-name: apHalo;
  background: linear-gradient(112deg, rgba(255, 237, 209, 0) 0%, rgba(255, 237, 209, 0) 38%, rgba(255, 237, 209, 0.132) 42%, rgba(255, 237, 209, 0.22) 44.5%, rgba(255, 237, 209, 0.11) 47%, rgba(255, 237, 209, 0) 50%, rgba(255, 237, 209, 0) 100%);
}
@supports not (mix-blend-mode: plus-lighter) {
  .ap-entree .ap-portrait .ap-cadre::after { mix-blend-mode: screen; }
}
/* La PHOTO ne s'anime pas (arbitrage Luca 09/10, A1) : un `transform` animé sur une image laisse WebKit la rendre
   composée après la fin — rééchantillonnage différent du rendu immobile, mesuré au pixel (banc P6). Aucune image de
   la page ne porte d'animation. */

/* Fond de l'ouverture, BUREAU seul : #E6E0D6 (accent 4,53:1, ne s'assombrit pas davantage) → --color-bg,
   avec la Lumière (même délai, même relais [C2]). Chapeau : rideau au BUREAU SEULEMENT —
   au doigt il est l'élément LCP, immobile, visible au 1er rendu (option C) : aucun état de départ hors
   de cette requête. */
@keyframes apFond {
  from { background-color: #E6E0D6; }
  to   { background-color: var(--color-bg); }
}
@media (min-width: 900px) and (pointer: fine) {
  .ap-entree .ap-lede { animation: apRideau 1.05s var(--ease-entree) 0.9s backwards; }
  .ap-entree .ap-ouverture { animation: apFond 3.2s ease 1.2s backwards; }
}

/* Sous le pli, une fois par chargement, à l'entrée de leur conteneur (js/a-propos.js) : l'état de départ
   n'existe que sous `.is-armed` du conteneur ; l'horloge est portée par l'état ENTRÉ (C143). */
/* La citation S'ÉCRIT (RETOUR 2, Z1 ; en BLOC, arbitrage Luca 09/10, A2) : le guillemet se trace, puis la citation entière
   monte derrière son filet, la source suit. Aucun découpage en mots : un mot en `inline-block` ne rend pas au pixel le
   texte nu (Firefox recoupe la phrase équilibrée, Chrome et Safari décalent l'anticrénelage — banc P6, 09/10). */
.ap-encre .ap-citation.is-armed:not(.is-entered) .ap-citation-mark { clip-path: inset(-0.22em 100% -0.28em 0); }
.ap-encre .ap-citation.is-armed:not(.is-entered) .ap-quote,
.ap-encre .ap-citation.is-armed:not(.is-entered) .ap-quote-src {
  transform: translateY(calc(100% + 0.5em));
  clip-path: inset(-0.22em -0.08em calc(100% + 0.22em) -0.08em);
}
.ap-encre .ap-citation.is-armed.is-entered .ap-citation-mark { animation: jmpEcritLigne 0.6s linear backwards; }
.ap-encre .ap-citation.is-armed.is-entered .ap-quote { animation: apRideau 1.1s var(--ease-entree) 0.35s backwards; }
.ap-encre .ap-citation.is-armed.is-entered .ap-quote-src { animation: apRideau 1.05s var(--ease-entree) 0.75s backwards; }
/* Les coulisses SORTENT DE L'OMBRE (RETOUR 2, Z3, maquette encre v2) : un voile d'encre au bord doux — `::after` du cadre
   des coulisses SEULES, jamais du portrait ; 3 largeurs (A) ou 3 hauteurs (B) — se retire en `transform`, A de gauche à
   droite, B de haut en bas ; la photo ne bouge pas (A1). Elle est PEINTE avant le volet (O5 : amorce + garantie, js/a-propos.js).
   Au bureau, B part +0,7 s : il entre avec la citation et la laisse commencer. Hors de son animation, le voile est caché. */
@keyframes apVoletX {
  from { visibility: visible; transform: translateX(-66.667%); }
  to   { visibility: visible; transform: none; }
}
@keyframes apVoletY {
  from { visibility: visible; transform: translateY(-66.667%); }
  to   { visibility: visible; transform: none; }
}
.ap-encre .ap-backstage.is-armed .ap-cadre::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}
.ap-encre .ap-backstage--a.is-armed .ap-cadre::after {
  width: 300%;
  height: 100%;
  background: linear-gradient(90deg, rgba(28, 25, 21, 0) 0%, rgba(28, 25, 21, 0) 33.4%, var(--color-text) 58%, var(--color-text) 100%);
}
.ap-encre .ap-backstage--b.is-armed .ap-cadre::after {
  width: 100%;
  height: 300%;
  background: linear-gradient(180deg, rgba(28, 25, 21, 0) 0%, rgba(28, 25, 21, 0) 33.4%, var(--color-text) 58%, var(--color-text) 100%);
}
.ap-encre .ap-backstage--a.is-armed:not(.is-entered) .ap-cadre::after { transform: translateX(-66.667%); }
.ap-encre .ap-backstage--b.is-armed:not(.is-entered) .ap-cadre::after { transform: translateY(-66.667%); }
.ap-encre .ap-backstage.is-armed.is-entered .ap-cadre::after { visibility: hidden; }
.ap-encre .ap-backstage--a.is-armed.is-entered .ap-cadre::after { animation: apVoletX 1.6s cubic-bezier(0.45, 0.05, 0.3, 0.95) backwards; }
.ap-encre .ap-backstage--b.is-armed.is-entered .ap-cadre::after { animation: apVoletY 1.6s cubic-bezier(0.45, 0.05, 0.3, 0.95) backwards; }
@media (min-width: 900px) and (pointer: fine) {
  .ap-encre .ap-backstage--b.is-armed.is-entered .ap-cadre::after { animation: apVoletY 1.6s cubic-bezier(0.45, 0.05, 0.3, 0.95) 0.7s backwards; }
}
.ap-encre .ap-bloc.is-armed:not(.is-entered) > *,
.ap-encre .ap-aparte.is-armed:not(.is-entered) > * {
  transform: translateY(calc(100% + 0.5em));
  clip-path: inset(-0.22em -0.08em calc(100% + 0.22em) -0.08em);
}
/* Chapitres 2, 3 puis l'aparté, décalés de 0,09 s (au bureau ils entrent ensemble, sur une rangée). */
.ap-encre .ap-bloc.is-armed.is-entered > * { animation: apRideau 1.05s var(--ease-entree) backwards; }
.ap-encre .ap-bloc + .ap-bloc.is-armed.is-entered > * { animation: apRideau 1.05s var(--ease-entree) 0.09s backwards; }
.ap-encre .ap-aparte.is-armed.is-entered > * { animation: apRideau 1.05s var(--ease-entree) 0.18s backwards; }
.ap-retour-titre.is-armed .ap-invitation { width: fit-content; }
.ap-retour-titre.is-armed:not(.is-entered) .ap-invitation { clip-path: inset(-0.22em 100% -0.28em 0); }
.ap-retour-titre.is-armed.is-entered .ap-invitation { animation: jmpEcritLigne 0.9s linear backwards; }

/* Mouvement réduit : le script de tête n'arme rien ; on n'en dépend pas — chaque animation est coupée
   au SHORTHAND (le réglage global de style.css écrase la durée, pas le délai). APRÈS les règles animées :
   à poids égal, la position tranche (css-reduced-motion.test.mjs). */
@media (prefers-reduced-motion: reduce) {
  .ap-entree .ap-h1 .hero-tag,
  .ap-entree .ap-h1 .word-mask:not(.italic-mask) .word-inner,
  .ap-entree .ap-h1 .italic-mask .word-inner,
  .ap-entree .ap-tete .ap-bloc > *,
  .ap-entree .ap-portrait .ap-cadre::before,
  .ap-entree .ap-portrait .ap-cadre::after,
  .ap-entree .ap-lede,
  .ap-entree .ap-ouverture,
  .ap-encre .ap-citation.is-armed.is-entered .ap-citation-mark,
  .ap-encre .ap-citation.is-armed.is-entered .ap-quote,
  .ap-encre .ap-citation.is-armed.is-entered .ap-quote-src,
  .ap-encre .ap-backstage--a.is-armed.is-entered .ap-cadre::after,
  .ap-encre .ap-backstage--b.is-armed.is-entered .ap-cadre::after,
  .ap-encre .ap-bloc.is-armed.is-entered > *,
  .ap-encre .ap-bloc + .ap-bloc.is-armed.is-entered > *,
  .ap-encre .ap-aparte.is-armed.is-entered > *,
  .ap-retour-titre.is-armed.is-entered .ap-invitation { animation: none; }
}
