/* ── src/refonte/refonte.css ── */
/* ───── Refonte : le site de vente (spec v3 du 15 octobre 2026) ─────
   Les objets du système (00-base, 10-composants, 99-systeme) restent ceux du site ; ce fichier pose la grille, l'échelle
   typographique, les registres de la partition et les objets NOUVEAUX de la refonte (marqués NOUVEAU), à proposer au design
   system après accord de Raphaël. Espacements sur la grille de 6 px. */

/* ── NOUVEAU · jetons de la refonte ── */
.rf-page {
  --rf-marge: 18px; --rf-goutt: 18px; --rf-max: 1344px;
  --rf-e1: 12px; --rf-e2: 24px; --rf-e3: 48px; --rf-e4: 72px; --rf-e5: 96px;   /* espacements (moitié au téléphone) */
  --rf-r-media: 24px; --rf-r-petit: 12px;
  color: var(--ink); background: var(--paper); overflow-x: clip;
}
/* v389 (audit, lot clavier) : l'en-tête fixe ne cache plus l'élément qui reçoit le focus (la page garde sa hauteur dessous) ;
   une ancre de rubrique, elle, pose toujours la rubrique en haut de l'écran (marge négative qui annule la réserve) */
:root:has(.rf-page) { --rf-entete: 72px; scroll-padding-top: var(--rf-entete); }
.rf-page section[id] { scroll-margin-top: calc(-1 * var(--rf-entete)); }
/* v502 : --rf-cuivre est devenu un jeton du système (00-base.css) */
@media (min-width: 768px) { .rf-page { --rf-marge: 24px; --rf-goutt: 24px; --rf-e1: 12px; --rf-e2: 24px; --rf-e3: 48px; --rf-e4: 96px; --rf-e5: 144px; } }
@media (min-width: 1024px) { .rf-page { --rf-marge: 36px; --rf-e5: 192px; } }
@media (min-width: 1440px) { .rf-page { --rf-marge: 48px; } }

/* ── NOUVEAU · la grille de 12 colonnes ── */
.rf-grille { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--rf-goutt);
  width: 100%; max-width: calc(var(--rf-max) + 2 * var(--rf-marge)); margin-inline: auto; padding-inline: var(--rf-marge); box-sizing: border-box; }
.rf-col { grid-column: var(--de, 1) / var(--a, 13); min-width: 0; }
@media (max-width: 767px) { .rf-col { grid-column: 1 / 13; } }

/* ── NOUVEAU · l'échelle typographique (téléphone par défaut, tablette, ordinateur) ── */
.rf-page h1, .rf-page h2, .rf-page h3, .rf-page p { margin: 0; }
.rf-page [hidden] { display: none !important; }
.t-affiche, .t-grand, .t-titre, .t-sous { font-family: var(--font-sans); font-weight: 500; text-wrap: balance; }
h1:has(.rf-rot) { text-wrap: auto; }   /* v486 (audit, CLS) : l'équilibrage des lignes refaisait les coupes à chaque lettre tapée du titre qui tourne, et « à » sautait de ligne */
.t-affiche { font-size: 54px; line-height: 60px; letter-spacing: -.035em; }
.t-grand { font-size: 48px; line-height: 54px; letter-spacing: -.035em; }
.t-titre { font-size: 36px; line-height: 42px; letter-spacing: -.025em; }
.t-sous { font-size: 27px; line-height: 36px; letter-spacing: -.025em; }
.t-accroche { font: 400 20px/30px var(--font-sans); color: var(--ink-2); max-width: 34em; }
.t-texte { font: 400 17px/30px var(--font-sans); color: var(--ink-2); max-width: 38em; }
.t-petit { font: 400 15px/24px var(--font-sans); color: var(--ink-2); }
@media (min-width: 768px) {
  .t-affiche { font-size: 84px; line-height: 90px; } .t-grand { font-size: 66px; line-height: 72px; }
  .t-titre { font-size: 44px; line-height: 48px; } .t-sous { font-size: 30px; line-height: 36px; }
  .t-accroche { font-size: 22px; line-height: 30px; } .t-texte { font-size: 18px; line-height: 30px; }
}
@media (min-width: 1024px) {
  .t-affiche { font-size: 120px; line-height: 120px; } .t-grand { font-size: 84px; line-height: 90px; }
  .t-titre { font-size: 54px; line-height: 60px; } .t-sous { font-size: 36px; line-height: 42px; }
  .t-accroche { font-size: 24px; line-height: 36px; }
}
/* un mot en italique par titre : Playfair, l'interlignage garde la place des jambages */
.rf-page em { font-family: var(--font-serif); font-style: italic; font-weight: 400; letter-spacing: -.01em; }
/* le paragraphe façon Apple : --ink-2, les mots clés en --ink */
.t-accroche b, .t-texte b { color: var(--ink); font-weight: 500; }

/* ── les boutons du système, avec un libellé lisible (15 px, minuscules) : NOUVEAU, à proposer au système ── */
.rf-page .btn-pill, .rf-page .btn-out { cursor: pointer; }   /* v392 : leur libellé (15 px, minuscules) est entré dans le système (10-composants.css) */
.rf-page .link-btn { font: 500 15px/1 var(--font-sans); color: var(--ink-2); text-decoration: none; cursor: pointer; }
.rf-page .link-btn:hover { color: var(--ink); }
.rf-page a, .rf-page button { cursor: pointer; }
.rf-page :focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.rf-page ::selection { background: var(--ink); color: var(--paper); }

/* ── l'en-tête ── */
.rf-page .rf-sauter { position: fixed; z-index: 40; left: var(--rf-marge); top: 12px; transform: translateY(-200%); }   /* v382 : .rf-page, sinon « .curseur .btn-pill » (position: relative) l'emportait : le lien d'évitement, caché, gardait 48 px dans la page et poussait tout le premier écran vers le bas */
.rf-page .rf-sauter:focus { transform: none; }
.rf-entete { position: fixed; z-index: 30; inset: 0 0 auto; height: var(--rf-entete); display: flex; align-items: center; gap: var(--rf-e2);
  padding-inline: var(--rf-marge); background: linear-gradient(var(--paper) 60%, rgba(var(--paper-rgb), 0)); }
.rf-entete .brand { color: var(--ink); text-decoration: none; }
.rf-entete .brand-carre { height: 36px; }
.rf-entete nav { display: flex; gap: var(--rf-e2); margin-left: auto; }
.rf-entete .acts { display: flex; align-items: center; gap: var(--rf-e1); }
.rf-menu-btn { display: none; }
/* NOUVEAU · sous 1024 px, les rubriques s'ouvrent depuis le bouton Menu (un volet sous l'en-tête)
   v384 : sous 1280 px (les noms des offres sont plus longs : à 1024 px, l'en-tête débordait de 127 px) */
@media (max-width: 1279px) {
  .rf-entete .acts { margin-left: auto; } .rf-menu-btn { display: inline-grid; }
  .rf-entete nav { display: none; position: fixed; top: var(--rf-entete); left: var(--rf-marge); right: var(--rf-marge); flex-direction: column; gap: 0;
    padding: var(--rf-e1) var(--rf-e2); border: 1px solid var(--line); border-radius: var(--rf-r-media); background: var(--paper); box-shadow: var(--shadow-float); }
  .rf-entete nav.ouvert { display: flex; }
  .rf-entete nav a { min-height: 48px; display: flex; align-items: center; }
}


/* ── NOUVEAU · les registres de la partition ── */
.rf-ecran { position: relative; box-sizing: border-box; }
.reg-a, .reg-b, .reg-d { min-height: 100vh; min-height: 100svh; }
.reg-a, .reg-d { padding-block: calc(var(--rf-entete) + var(--rf-e3)) var(--rf-e4); }
.reg-b { display: grid; align-content: center; padding-block: var(--rf-e5); text-align: center; }
.reg-b .rf-col { justify-self: center; }
.reg-c { padding-block: var(--rf-e5); }
.rf-accueil .reg-c { padding-block: var(--rf-e4); }   /* v512 : sur l'accueil, les écrans en colonne perdent un pas d'espace en haut et en bas (192 → 96 px dès 1024 px) */
.rf-ecran > .rf-grille + .rf-grille { margin-top: var(--rf-e3); }
.rf-entree { display: grid; gap: var(--rf-e2); align-content: start; }

/* ── NOUVEAU · une case à remplir (média à fournir) ── */
.rf-ph { display: grid; place-items: center; border-radius: var(--rf-r-media); background: var(--paper-2); color: var(--ink-2); font: 400 15px/24px var(--font-sans); text-align: center; padding: var(--rf-e2); }

/* ── NOUVEAU · le grand média : il s'ouvre jusqu'aux bords au défilement (refonte.js pose clip-path) ── */
.rf-media { position: relative; width: 100%; overflow: hidden; margin-top: var(--rf-e3); }
.rf-media > * { width: 100%; height: 100%; }
.rf-media .rf-ph { border-radius: 0; }
/* NOUVEAU (v416) · la scène d'une vidéo défilée : la vidéo se colle sous l'en-tête le temps que la page la fasse avancer (videos-page.js) ;
   même principe que la scène de la vidéo qui grandit (.rf-reel-scene) ; en mouvement réduit, rien n'est collé */
/* v495 (Raphaël, 18 octobre, 11 h 05 : « elle scrolljack trop longtemps ; fais-la défiler quand son bord haut arrive à 50 % de la hauteur,
   et finis quand son bas y est aussi ») : plus de scène collée ; la vidéo défile avec la page et videos-page.js l'avance selon sa place */
.rf-media-scene { position: relative; margin-top: var(--rf-e3); }
.rf-media-colle { margin: 0; }
/* v507 (scène de deux écrans, vidéo collée) retirée en v509 : c'est la lecture de la vidéo qui tient l'écran (videos-page.js, data-tenue) */
/* ── v517 (Raphaël, 20 octobre, 13 h 50) : la vidéo Pavillon tournée en 3D, qui grandit jusqu'à tout l'écran (videos-page.js) ; v520 : elle joue seule ──
   En colonne (ou en mouvement réduit) : la vidéo en 16/9 sous la rubrique, sa légende dessous. Dès que le plan s'applique, sans mouvement réduit
   (data-pivot-on) : collée à l'écran au-dessus du plan, de sa place (--x0, --y0, --w0, --h0) à tout l'écran (--u de 0 à 1) ; la rotation
   (perspective, rotateY et rotateX) et l'arrondi s'effacent en grandissant. La légende est alors celle du plan, sous la place de la vidéo. */
.rf-pivot-scene { position: relative; z-index: 3; pointer-events: none; }
.rf-pivot { position: relative; margin: var(--rf-e3) 0 0; pointer-events: auto; }
.rf-pivot video { display: block; width: 100%; aspect-ratio: 16 / 9; height: auto; object-fit: cover; border-radius: var(--rf-r-media); background: var(--paper-2); }
.rf-pivot .rf-legende { text-align: center; }
.rf-pivot-place { pointer-events: none; }
.rf-pivot-scene[data-pivot-on] { height: 240vh; height: 240svh; }   /* v520 : la hauteur de la scène de la formation (.rf-reel-scene) ; la vidéo joue seule, elle ne défile plus (v517 : 420 %) */
[data-pivot-on] .rf-pivot-colle { position: sticky; top: 0; height: 100svh; overflow: clip; }
[data-pivot-on] .rf-pivot { position: absolute; margin: 0; left: calc(var(--x0) * (1 - var(--u, 0))); top: calc(var(--y0) * (1 - var(--u, 0)));
  width: calc(var(--w0) + (100vw - var(--w0)) * var(--u, 0)); height: calc(var(--h0) + (100svh - var(--h0)) * var(--u, 0));
  transform: perspective(1400px) rotateY(calc(16deg * (1 - var(--u, 0)))) rotateX(calc(4deg * (1 - var(--u, 0)))); transform-origin: 50% 50%; }
[data-pivot-on] .rf-pivot video { height: 100%; aspect-ratio: auto; border-radius: calc(var(--rf-r-media) * (1 - var(--u, 0))); box-shadow: var(--shadow-float); }
[data-pivot-on] .rf-pivot .rf-legende { display: none; }
.rf-pivot-legende { display: none; }
@media (min-width: 1280px) and (min-height: 700px) and (prefers-reduced-motion: no-preference) { .rf-plan .rf-pivot-legende { display: block; } }
.rf-media-colle > .rf-media { margin-top: 0; }   /* v433 (Raphaël, 17 octobre, 13 h 21 : « la vidéo doit faire 100vw ») : toute la largeur, sans la limite de la v418 */
.rf-media-colle > .rf-legende { text-align: center; }
.f-16-9 { aspect-ratio: 16 / 9; } .f-4-5 { aspect-ratio: 4 / 5; } .f-1-1 { aspect-ratio: 1; }

/* ── NOUVEAU · le point (point.js) : le trait suit l'encre du thème, le cœur actif le cuivre ── */
svg.rf-point { display: block; max-width: 100%; height: auto; color: var(--ink); overflow: visible; }
svg.rf-point .porteur { stroke: currentColor; stroke-width: 1.5; opacity: .8; stroke-linecap: round; }
svg.rf-point .decor { stroke: currentColor; stroke-width: 1; opacity: .3; stroke-linecap: round; }
svg.rf-point .rf-etiq { font: 400 15px var(--font-sans); fill: var(--ink-2); }
svg.rf-point [data-allume] { transition: opacity var(--dur-trace) var(--ease-out); }
.rf-scene { display: grid; justify-items: center; margin-top: var(--rf-e3); padding-inline: var(--rf-marge); }
.rf-decor-haut { position: absolute; z-index: 0; right: calc(-1 * var(--rf-e3)); top: 50%; transform: translateY(-40%); pointer-events: none; }
#haut { overflow: clip; }
@media (max-width: 767px) { .rf-decor-haut { display: none; } }

/* ── le haut de page ── */
#haut { display: grid; align-content: center; }
#haut > .rf-grille { position: relative; z-index: 1; }
#haut .rf-entree { gap: var(--rf-e2); }
.rf-sofia-chat { grid-area: auto; }   /* v445, v448 : le champ de Sofia (.esp-chat, qui a sa place nommée dans l'espace du site) dans une colonne de la page : placement seulement */
/* v327 : le titre du haut comme le hero du site — « Raphaël vous aide à » fixe, la fin tapée ; v346 : la fin suit sur la ligne, la place
   réservée est mesurée (refonte.js) */
.rf-rot { display: inline; }
.rf-appels { display: flex; flex-wrap: wrap; gap: var(--rf-e1); margin-top: var(--rf-e1); }

/* ── NOUVEAU · le comparatif des formules : la choisie en trait plein et en cuivre, les autres en pointillés et estompées ── */
.rf-formules { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--rf-goutt); align-items: start; margin-top: var(--rf-e4); }
.rf-formule-col { display: grid; gap: var(--rf-e2); align-content: start; }
.rf-formule { display: grid; gap: var(--rf-e1); justify-items: start; text-align: left; padding: var(--rf-e2); border: 1px solid var(--line); border-radius: var(--rf-r-media);
  background: none; color: var(--ink); font: inherit; transition: border-color var(--dur-respond) var(--ease-out), opacity var(--dur-respond) var(--ease-out); }
.rf-formule svg.rf-point { width: 96px; }
.rf-formule-prix { font: 500 36px/42px var(--font-sans); letter-spacing: -.025em; font-style: normal; }
.rf-formule[aria-pressed="true"] { border-color: var(--ink); }
.rf-formule[aria-pressed="false"] svg.rf-point { opacity: .6; }   /* seul le dessin s'estompe, jamais le texte (contraste) */
.rf-formule:hover svg.rf-point { opacity: 1; }
.rf-formule[aria-pressed="true"] [data-anneau], .rf-formule:hover [data-anneau] { stroke: var(--rf-cuivre); stroke-dasharray: none; opacity: 1; }
.rf-formule[aria-pressed="true"] [data-role="point"] { fill: var(--rf-cuivre); }
.rf-formule-lignes { margin: 0; padding: 0 0 0 var(--rf-e2); list-style: none; display: grid; gap: 6px; }
.rf-formules-note { grid-column: 1 / -1; }
.rf-formules .btn-out { justify-self: start; margin-left: var(--rf-e2); }
@media (max-width: 1023px) { .rf-formules { grid-template-columns: 1fr; margin-top: var(--rf-e3); } }
.rf-formule { width: 100%; box-sizing: border-box; }
.rf-formule-demo { width: 100%; max-width: 288px; aspect-ratio: 16 / 9; margin-left: var(--rf-e2); box-sizing: border-box; }   /* v423 : la place du site de démonstration (la case à remplir du système) */

/* ── NOUVEAU · la réalisation vedette en plein écran, son voile, sa légende ── */
/* l'image n'est jamais agrandie (contain, au plus sa taille réelle) ; autour, le fond de la marque (--fond, posé sur la vedette) */
.rf-vedette { position: relative; margin-inline: calc(50% - 50vw); width: 100vw; margin-top: calc(-1 * (var(--rf-entete) + var(--rf-e3))); }
/* v396 (Raphaël, 17 octobre, 8 h 38 : « le titre Identité visuelle est coupé ou couvert par le rouge ») : en colonne (sous 1280 × 700), le titre
   collait au bord du rouge ; il prend l'écart d'un titre de rubrique. Dans le plan, sa place reste celle de Raphaël. */
@media not ((min-width: 1280px) and (min-height: 700px)) { .rf-vedette + .rf-plan { margin-top: var(--rf-e4); } }
.rf-vedette img { background: var(--fond, var(--paper-2)); display: block; width: 100%; height: auto; max-height: 80svh; aspect-ratio: auto; object-fit: contain; object-position: 50% 50%; }
.rf-voile { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0, 0, 0, 0) 35%, rgba(0, 0, 0, .72) 82%); pointer-events: none; }
.rf-vedette-texte, .rf-vedette-texte .rf-legende { color: var(--on-scrim); }
.rf-vedette-texte { position: absolute; z-index: 1; inset: auto 0 var(--rf-e3) 0; }   /* v510 (Raphaël, 20 octobre, 11 h 32 : « mets un z-index, sinon le texte est recouvert par l'image ») */
.rf-vedette-texte .rf-legende { margin-top: var(--rf-e1); }
/* à partir de 1024 px : le titre à gauche sur le fond de la marque, l'image à droite (fondue dans le fond), jamais l'un sur l'autre */
@media (min-width: 1024px) {
  .rf-vedette { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: minmax(0, 1fr); align-items: center; height: min(800px, 56vw); background: var(--fond, var(--paper-2)); }   /* v371 : la rangée tient dans la hauteur (l'image 16:9 débordait sur le titre suivant) */
  /* v358 : l'image de Cherrie est en 16:9 (1600 × 900), son logo à droite et son fond uni à gauche : elle occupe toute la largeur,
     entière (contain) et calée à droite ; le titre se pose sur son fond uni, jamais sur le logo */
  .rf-vedette img { grid-column: 1 / -1; grid-row: 1; width: 100%; height: 100%; max-height: none; aspect-ratio: auto; object-position: 100% 50%;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 24%); mask-image: linear-gradient(90deg, transparent, #000 24%); }
  .rf-voile { display: none; }
  .rf-vedette-texte { grid-column: 1; grid-row: 1; position: relative; max-width: none; margin: 0; padding: calc(var(--rf-entete) + var(--rf-e3)) var(--rf-e3) var(--rf-e3) max(var(--rf-marge), calc((100vw - var(--rf-max)) / 2)); }   /* aligné sur la grille de la page */
  .rf-vedette-texte > .rf-col { grid-column: 1 / -1; }
  /* v510 : l'image masquée (mask-image) forme sa propre couche et passait devant le texte resté statique ; le texte, positionné, repasse devant */
}
.rf-legende { margin: var(--rf-e1) 0 0; color: var(--ink-2); }
.rf-bande { margin-block: var(--rf-e3); row-gap: var(--rf-e2); }
.rf-tuile-fig { margin: 0; }
/* ── NOUVEAU · la tuile (rayon 24) : elle grandit un peu au survol ── */
.rf-tuile { position: relative; overflow: hidden; border-radius: var(--rf-r-media); background: var(--paper-2);
  transition: transform var(--dur-respond) var(--ease-out); }
.rf-tuile :is(img, video) { display: block; width: 100%; height: 100%; object-fit: cover; }   /* v343 : les vidéos des études et du portfolio, comme les images */
@media (hover: hover) and (prefers-reduced-motion: no-preference) { .rf-tuile:hover { transform: scale(1.02); } }
/* v373 · les trois références de « votre image » : au survol, l'image grandit dans sa tuile et suit un peu la souris (zoom.js pose --mx, --my) */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  #image .rf-tuile-fig .rf-tuile img { transition: transform var(--dur-trace) var(--ease-out); }
  #image .rf-tuile-fig .rf-tuile:hover img { transform: scale(1.12) translate(calc(var(--mx, 0) * -4%), calc(var(--my, 0) * -4%)); transition-duration: var(--dur-respond); }
}
.rf-tuiles { display: grid; grid-template-columns: 1.15fr 1fr 1fr; grid-auto-rows: minmax(264px, auto); gap: var(--rf-goutt); margin-top: var(--rf-e3); }
.rf-tuiles .rf-tuile { display: grid; align-content: start; gap: var(--rf-e1); padding: var(--rf-e2); }
.rf-tuile-a { grid-row: span 2; } .rf-tuile-c { grid-row: span 2; }
.rf-tuile-c { padding: 0 !important; align-content: end !important; }
.rf-tuile-c h3, .rf-tuile-c p { padding-inline: var(--rf-e2); } .rf-tuile-c p { padding-bottom: var(--rf-e2); }
.rf-tuile-media { width: 100%; } .rf-tuile-media img { height: 100%; }
.rf-tuile-dessin { display: grid; place-items: center; margin-top: var(--rf-e2); }
.rf-echange { display: grid; gap: 6px; margin-top: var(--rf-e2); justify-items: start; }
.rf-bulle { padding: 9px 15px; border-radius: var(--rf-r-petit) var(--rf-r-petit) var(--rf-r-petit) 4px; background: var(--paper); color: var(--ink); }
.rf-exemple { font-style: italic; }
@media (max-width: 1023px) { .rf-tuiles { grid-template-columns: 1fr; } .rf-tuile-a, .rf-tuile-c { grid-row: auto; } }
.rf-ph-bande { width: 100%; aspect-ratio: 16 / 9; max-height: 360px; }
.rf-scene-carre { margin-top: var(--rf-e4); }
#equipe .rf-entree { justify-items: center; position: relative; }
#equipe .rf-scene { margin: 0; padding: 0; width: max-content; max-width: 100%; pointer-events: none; }   /* au-dessus du titre, sans le croiser */
#equipe .rf-scene svg { max-width: 100%; }
#equipe .rf-pose.t-texte { margin-inline: auto; }   /* v436 : le texte de la formation (une accroche avant) */

/* ── NOUVEAU · les phrases qui se réécrivent (écran « le tout ») ── */
#tout > .rf-grille { align-items: center; }
#tout .rf-scene { margin: 0; justify-items: start; padding: 0; }
#tout .rf-scene svg { max-width: none; margin-left: -150px; }
#tout { overflow: clip; display: grid; align-content: center; }
@media (max-width: 767px) { #tout .rf-scene svg { max-width: 100%; margin-left: 0; } }
/* v669 (audit design du 22/10, tâche QG t-20261022-ad01) : le lien « Quelques exemples détaillés… » (.link-btn, nowrap dans le système)
   passe à la ligne s'il ne tient pas dans la colonne (375 px : il finissait à 400 px) ; la flèche reste au bout, la cible garde 44 px */
#tout .link-btn { display: inline-block; white-space: normal; max-width: 100%; box-sizing: border-box; padding-block: 12px; line-height: 20px; text-align: left; }
#tout .link-btn svg { display: inline-block; margin-left: .375rem; vertical-align: -3px; }
.rf-frappe-ligne { color: var(--ink); min-height: 180px; }
.rf-curseur { display: inline-block; width: 3px; height: .9em; margin-left: 6px; vertical-align: -.08em; background: var(--rf-cuivre); }
@media (prefers-reduced-motion: no-preference) { .rf-curseur { animation: rf-clin 1s steps(1) infinite; } }
@keyframes rf-clin { 50% { opacity: 0; } }
.rf-traits { display: flex; gap: 9px; margin-top: var(--rf-e2); }
.rf-traits i { width: 24px; height: 3px; border-radius: 2px; background: var(--line-strong); transition: background-color var(--dur-respond) var(--ease-out); }
.rf-traits i.on { background: var(--ink); }
.rf-frappe-fin { display: none; margin: 0; padding: 0; list-style: none; gap: var(--rf-e2); }
@media (prefers-reduced-motion: reduce) { .rf-frappe { display: none; } .rf-frappe-fin { display: grid; } }

/* ── NOUVEAU · les études (une grande carte chacune) et la rangée du portfolio ── */
.rf-etudes { display: grid; gap: var(--rf-e5); margin-top: var(--rf-e4); }
.rf-etude { align-items: center; row-gap: var(--rf-e2); }
.rf-etude-texte { display: grid; gap: var(--rf-e2); align-content: start; justify-items: start; }
.rf-mots { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.rf-etude-media { position: relative; }
/* v330 · le portfolio en détail en volets (volets.js) : sur ordinateur, chaque étude se colle en haut, un cran (--vl) sous la précédente ;
   la suivante la recouvre et n'en laisse que la ligne « 01 CreatorOS » ; les lignes s'empilent sous l'en-tête (comme Expertise).
   Le volet fait 46,7 % de l'écran et laisse 2,7 % jusqu'au suivant (la mise en page de Raphaël). Le fond du volet est le papier de la page. */
.rf-volet-ligne { display: none; }
.rf-volet-grand { display: none; }
@media (min-width: 1024px) {
  .rf-volets { --vl: 48px; display: block; margin-top: var(--rf-e4); }
  .rf-volet { position: sticky; top: calc(var(--rf-entete) + var(--i) * var(--vl)); min-height: 46.7svh; margin-bottom: 2.7svh; box-sizing: border-box;
    background: var(--paper); border-top: 1px solid var(--line-strong); }
  .rf-volet-ligne { display: flex; align-items: center; gap: var(--rf-e2); height: var(--vl); max-width: calc(var(--rf-max) + 2 * var(--rf-marge)); margin: 0 auto; padding-inline: var(--rf-marge);
    box-sizing: border-box; color: var(--ink); opacity: var(--vs, 0); }
  .rf-volet-num { font-variant-numeric: tabular-nums; }
  .rf-volet .rf-etude { padding-bottom: var(--rf-e3); align-items: start; }
  .rf-volet-grand { display: block; grid-column: 1 / 3; font-variant-numeric: tabular-nums; transform-origin: 0 0; color: var(--ink);
    opacity: calc(1 - var(--vs, 0)); transform: scale(calc(1 - .6 * var(--vs, 0))); }
  .rf-volet .rf-etude-texte { grid-column: 3 / 7; }
  .rf-volet .rf-etude-media { grid-column: 7 / 13; }
}
/* v331 · le portfolio en bref : trois rangées qui défilent (bref.js), comme les rangées de nk.studio et de hailstonelabs ;
   la souris ou le focus arrêtent une rangée ; mouvement réduit : les rangées se font défiler à la main (au doigt, à la molette, au clavier) */
.rf-defiles { display: grid; gap: var(--rf-e2); margin-top: var(--rf-e3); }
.rf-defile { --dh: 246px; height: var(--dh); overflow: hidden; }   /* v353 : deux rangées, des images plus grandes */
.rf-defile-piste { display: flex; gap: var(--rf-goutt); height: 100%; width: max-content; will-change: transform; }
.rf-defile .rf-carte { display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: 6px; height: 100%; margin: 0; }
.rf-defile .rf-tuile { height: 100%; aspect-ratio: 4 / 5; border-radius: var(--r-cell); }   /* v353 : coins de 8 px (--r-cell, le jeton du système) */
.pf-box-fig video { display: block; max-width: 100%; max-height: calc(100svh - 15.625rem); border-radius: var(--r-card); border: 1px solid var(--line); background: var(--paper-2); }   /* v344 : la vidéo dans la visionneuse, comme son image (35-sections.css) */
.pf-box-fig canvas { display: block; width: min(86vw, calc((100svh - 15.625rem) * 1.44)); aspect-ratio: 1440 / 1000; border-radius: var(--r-card); border: 1px solid var(--line); background: #0b0c0e; }   /* v447 : une vidéo des outils (une toile, au format des showreels 1440 × 1000) ; les mêmes bords que la vidéo, le fond des showreels (.rf-reel) */
.pf-box-fig video[hidden], .pf-box-fig img[hidden], .pf-box-fig canvas[hidden] { display: none; }   /* v464 : la toile des vidéos des outils (v447), pourtant cachée (hidden), prenait sa place sous les images et les vidéos */
/* v353 : les légendes des rangées ne se voient plus (.sr) : la règle qui les tenait sous l'image est retirée */
@media (prefers-reduced-motion: reduce) { .rf-defile { overflow-x: auto; scrollbar-width: thin; } .rf-defile-piste { will-change: auto; } }
@media (min-width: 1280px) and (min-height: 700px) {
  .rf-plan .rf-defiles { display: block; margin: 0; }
  .rf-plan .rf-defile { height: auto; }   /* la hauteur vient du plan (32 % de l'écran depuis la v353) */
  .rf-plan .rf-pose.rf-plein { left: 0 !important; width: 100% !important; }   /* d'un bord à l'autre de l'écran */
}
.rf-fleche { width: 48px; height: 48px; }
.rf-rangee { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(240px, 22%); gap: var(--rf-goutt); overflow-x: auto; scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--rf-marge); padding: var(--rf-e3) var(--rf-marge) var(--rf-e2); scrollbar-width: thin; scroll-behavior: smooth; }
.rf-rangee:focus-visible { outline-offset: -3px; }
.rf-carte { margin: 0; scroll-snap-align: start; }
@media (prefers-reduced-motion: reduce) { .rf-rangee { scroll-behavior: auto; } }
@media (max-width: 767px) { .rf-rangee { grid-auto-columns: 78%; } }

/* ── comment ça se passe ── */
.rf-etapes { counter-reset: e; list-style: none; margin: var(--rf-e3) 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--rf-goutt); text-align: left; }
/* v461 (Raphaël, 21 h 52 : une frise verticale « avec la barre qui se remplit ; au survol les noms passent en gras ») : chaque étape est
   un bouton sans cadre : son rond (44 px, trait de 1 px, comme le bouton rond du site) et son icône Lucide, son nom (.t-texte), sa phrase
   (.note). Une piste de 2 px relie les centres des ronds (--rf-piste) ; elle se remplit d'encre jusqu'au rond de l'étape en cours
   (--rf-plein, posé par refonte.js). Étapes passées : rond au trait d'encre ; étape en cours : rond plein. Au survol et au focus, le nom
   passe en gras. Le clic (ou Entrée) montre l'étape sur la maquette (scenes-page.js) ; avant le premier clic, le défilement la fait avancer. */
.rf-etapes { position: relative; grid-template-columns: minmax(0, 1fr); gap: var(--rf-e2); }
.rf-etapes::before, .rf-etapes::after { content: ""; position: absolute; left: calc(1.375rem - 1px); top: 1.375rem; width: 2px; height: var(--rf-piste, 0px); background: var(--line-strong); pointer-events: none; }
.rf-etapes::after { height: var(--rf-plein, 0px); background: var(--ink); transition: height var(--dur-fade) var(--ease-out); }
.rf-etapes li { display: block; }
.rf-etape { position: relative; z-index: 1; display: grid; grid-template-columns: 2.75rem minmax(0, 1fr); column-gap: var(--rf-e2); align-items: start; width: 100%; min-height: 2.75rem;
  margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.rf-etape-rond { display: inline-grid; place-items: center; width: 2.75rem; height: 2.75rem; border: 1px solid var(--line-strong); border-radius: var(--r-pill); background: var(--paper); color: var(--ink-2);
  transition: background-color var(--dur-respond) var(--ease-out), border-color var(--dur-respond) var(--ease-out), color var(--dur-respond) var(--ease-out); }
.rf-etape-rond svg { width: 18px; height: 18px; }
.rf-etape-texte { display: grid; gap: .375rem; padding-top: .375rem; }   /* le nom aligné sur le haut du rond, à 6 px */
.rf-etape-nom { color: var(--ink); font-weight: 400; }
.rf-etape .note { margin: 0; max-width: 34em; }
.rf-etape:is(:hover, :focus-visible) .rf-etape-nom { font-weight: 600; }
.rf-etape:is(:hover, :focus-visible) .rf-etape-rond { border-color: var(--ink); color: var(--ink); }
.rf-etape:focus-visible { outline: 2px solid var(--ink); outline-offset: 6px; border-radius: var(--r-cell); }
.rf-etapes li:is(.rf-fait, .rf-courant) .rf-etape-rond { background: var(--ink); border-color: var(--ink); color: var(--paper); }   /* v494 (Raphaël, 11 h 02) : les étapes passées ont le rond plein comme l'étape en cours (avant : au trait) */
@media (prefers-reduced-motion: reduce) { .rf-etapes::after { transition: none; } }
.rf-delais { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--rf-goutt); margin: 0; text-align: left; }
.rf-delais div { display: grid; gap: 6px; align-content: start; } .rf-delais dd { margin: 0; }
/* v378 : un délai = « à partir de » en petit, le nombre de semaines en grand chiffre (le style d'affiche du système), « semaine(s) » en petit, sur la même ligne de base */
/* v400 : une colonne par délai, sous un filet ; le grand chiffre à gauche, à sa droite « à partir de » puis l'unité, en pile, posés sur
   le pied du chiffre ; « selon les disponibilités » tombe sur la même ligne (le pied de la rangée) ; le titre « Délais indicatifs » à gauche */
.rf-delais-bloc { display: grid; gap: var(--rf-e2); width: 100%; text-align: left; }
.rf-delais > div { grid-template-rows: auto 1fr; gap: var(--rf-e2); padding-top: var(--rf-e2); border-top: 1px solid var(--line); }
.rf-delais dt { color: var(--ink); }
.rf-delai { align-self: end; display: grid; grid-template-columns: auto 1fr; grid-template-rows: 1fr auto auto; justify-items: start; align-items: end; column-gap: var(--rf-e1); row-gap: 6px; }
.rf-delai .t-affiche { grid-column: 1; grid-row: 1 / 4; line-height: .74; }
.rf-delai .t-petit { grid-column: 2; grid-row: 2; line-height: 1; }
.rf-delai .rf-delai-unite { grid-column: 2; grid-row: 3; color: var(--ink); font-weight: 500; line-height: 1; }
.rf-delai:not(:has(.t-affiche)) .rf-delai-unite { grid-column: 1 / -1; grid-row: 3; }
.rf-delai-service { margin-top: var(--rf-e4); } .rf-delai-service .rf-delais { grid-template-columns: minmax(0, 1fr); }   /* v427 : un délai seul, dans son service */
.reg-b .rf-delai-service .rf-col { justify-self: stretch; text-align: left; }   /* v427 : à gauche, même dans un écran centré (la formation) */
#comment .rf-entree { justify-items: center; } #comment .rf-etapes, #comment .rf-delais { width: 100%; }
@media (max-width: 1023px) { .rf-delais { grid-template-columns: 1fr 1fr; } }
@media (max-width: 767px) { .rf-delais { grid-template-columns: 1fr; } }

/* ── la FAQ : un accordéon natif ── */
.rf-faq { display: grid; margin-top: var(--rf-e2); border-top: 1px solid var(--line); }
.rf-raphael { align-items: center; row-gap: var(--rf-e3); }   /* v341 : la photo à gauche, l'approche et l'appel à droite */
/* ── NOUVEAU (v358) · le portrait de Raphaël : l'image entière, jamais recadrée, aux coins des médias ── */
.rf-portrait { display: block; width: 100%; height: auto; border-radius: var(--rf-r-media); }
/* ── NOUVEAU (v440) · la coulisse (Raphaël, 17 octobre, 13 h 27) : l’écran Raphaël est derrière la FAQ et le Journal. Sur la nuit du
   système (les valeurs de nuit de 00-base, comme .rf-entete.nuit), quel que soit le thème. À partir de
   1280 × 700 et sans mouvement réduit, il est collé derrière : la FAQ part vers le haut et l’ouvre, il se rapproche (de 92 à 100 %,
   --ouvre posé par refonte.js), reste un temps, puis le Journal remonte devant lui et il repart en profondeur (v450). Les deux écrans de devant ont le papier et
   l’ombre de ce qui flotte (--shadow-float). Ailleurs, la page reste en colonne. ── */
:is(.rf-ecran, .rf-site)[data-fond="nuit"] { background: var(--paper); color: var(--ink); }   /* v488 : les jetons de nuit viennent de 00-base (.zone-nuit, [data-fond="nuit"]) */
.rf-photo { display: block; width: 100%; height: auto; }   /* v441 : la photo de Raphaël, détourée (en colonne : toute la largeur) */
@media (min-width: 1280px) and (min-height: 700px) and (prefers-reduced-motion: no-preference) {   /* v441 : dès 1280 × 700, comme le plan (en dessous, le texte croiserait la table) */
  .rf-coulisse { position: relative; height: 360vh; height: 360svh; margin-top: -100vh; margin-top: -100svh; }   /* 100 derrière la FAQ, 100 pour l’ouvrir, 60 à l’arrêt, 100 pour le Journal */
  .rf-coulisse > .rf-ecran { position: sticky; top: 0; z-index: 0; height: 100vh; height: 100svh; min-height: 0; padding-block: 0; overflow: clip;
    transform: scale(calc(.92 + .08 * var(--ouvre, 1))); }
  .rf-coulisse + .rf-ecran { margin-top: -100vh; margin-top: -100svh; }
  .rf-coulisse-tete { height: 200vh; height: 200svh; margin-top: 0; }   /* v493 : la coulisse en tête de page (le mini-site Raphaël) : rien devant, 100 affiché puis 100 pour que l'écran suivant monte devant */
  .rf-ecran:has(+ .rf-coulisse), .rf-coulisse + .rf-ecran { position: relative; z-index: 1; background: var(--paper); box-shadow: var(--shadow-float); }
  .rf-ecran:has(+ .rf-coulisse) { min-height: 100vh; min-height: 100svh; }   /* l’écran de devant couvre tout l’écran : rien de la coulisse ne dépasse au-dessus */
  .rf-page .rf-coulisse > section[id] { scroll-margin-top: calc(-1 * var(--rf-entete) - 100svh); }   /* une ancre arrive sur l’écran ouvert, pas derrière la FAQ */
  .rf-coulisse .rf-raphael { height: 100%; align-items: start; }
  /* v441 : la photo sur toute la hauteur de l’écran, tenue par le bas et la droite (sur un écran étroit, c’est le bout gauche de la table qui sort) ;
     le texte devant, dans l’espace libre à gauche */
  .rf-coulisse .rf-photo-col { position: absolute; inset: 0; margin: 0; }
  .rf-coulisse .rf-photo { position: absolute; right: 0; bottom: 0; width: auto; height: calc(100% - var(--rf-entete)); max-width: none; translate: 5% 0; }   /* sous l’en-tête ; v449 : la nouvelle photo, Raphaël au centre, à peine décalée vers la droite (la table ne passe pas sous le texte) */
  .rf-coulisse .rf-raphael-texte { position: relative; z-index: 1; padding-top: calc(var(--rf-entete) + var(--rf-e3)); }
}
.rf-plan .rf-fin-appels { justify-content: center; }   /* v342 : les deux appels de la fin, centrés sous le titre */
.rf-faq-corps { align-items: start; row-gap: var(--rf-e3); } .rf-faq-corps .rf-faq { margin-top: 0; }   /* v437 : le titre est dans la grille, plus de marge au-dessus */
.rf-faq-tete { display: grid; gap: var(--rf-e3); align-content: start; justify-items: start; }   /* v437 : le titre et l’appel, en colonne (placement seulement) */
/* (v339 : l'appel à gauche, les questions à droite, sous le titre) */   /* v339 : l'appel à gauche, les questions à droite, sous le titre */

.rf-q { border-bottom: 1px solid var(--line); }
.rf-q summary { min-height: 44px; padding: var(--rf-e1) 0; max-width: none; cursor: pointer; list-style: none; display: flex; justify-content: space-between; gap: var(--rf-e2); }
.rf-q summary::-webkit-details-marker { display: none; }
.rf-q summary::after { content: "+"; font-weight: 400; transition: transform var(--dur-respond) var(--ease-out); }
.rf-q[open] summary::after { transform: rotate(45deg); }
.rf-q p { padding-bottom: var(--rf-e2); }   /* v437 : questions au style d’accroche (sa couleur), sur toute la largeur de la colonne, 12 px de marge au lieu de 24 */
.rf-q-reponse { display: grid; gap: 6px; } .rf-q-reponse > .t-petit { padding-bottom: 0; }   /* v429 : « Sofia répond », au-dessus de sa réponse */

/* ── le visage de Sofia dans l'en-tête du volet (v391 : le bandeau qui le portait est retiré depuis la v335) ── */
.rf-bandeau-face { display: inline-grid; width: 42px; height: 42px; flex: none; } .rf-bandeau-face svg { width: 100%; height: 100%; }

/* ── NOUVEAU · le panneau de conversation (boîte de Sofia) ── */
.rf-sofia-panneau, .rf-site-volet { position: fixed; z-index: 35; top: 12px; right: 12px; bottom: 12px; width: min(480px, calc(100vw - 24px)); display: grid; grid-template-rows: auto 1fr;
  border: 1px solid var(--line); border-radius: var(--rf-r-media); background: var(--paper); box-shadow: var(--shadow-float); overflow: hidden; }
.rf-sofia-panneau[hidden], .rf-site-volet[hidden] { display: none; }
@media (max-width: 767px) { .rf-sofia-panneau, .rf-site-volet { inset: 0; width: auto; border-radius: 0; } }
/* v345 (Raphaël, point 12) : le volet de Sofia en pleine page — il s'ouvre en cercle depuis Sofia (--ox, --oy ; --or de 0 à 150vmax),
   le site flouté derrière (le verre du système : --glass, --glass-blur) ; la conversation au centre, l'en-tête sur toute la largeur */
.rf-sofia-panneau, .rf-site-volet { inset: 0; width: auto; z-index: 45; border: 0; border-radius: 0; box-shadow: none; background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); clip-path: circle(var(--or, 150vmax) at var(--ox, 50%) var(--oy, 50%));
  transition: clip-path var(--dur-eclipse) var(--ease-out), translate var(--dur-respond) var(--ease-out); }
.rf-sofia-panneau .rf-conv { width: min(760px, 100%); margin-inline: auto; box-sizing: border-box; }
.rf-conv-tete { padding-inline: var(--rf-marge); touch-action: none; }
.rf-conv-liens { display: flex; gap: var(--rf-e2); margin-left: auto; }
.rf-conv-liens + .icon-btn { margin-left: 0; }
/* v349 (Raphaël, 18 h 37) : à l'ouverture, Sofia se pose en haut du volet (sa place, .rf-conv-sofia), le sujet, les points, l'accueil
   et la question dessous, puis le champ ; dès que la conversation s'engage, elle passe en petit à gauche du champ (.esp-sofia) */
.rf-sofia-panneau .rf-conv { display: flex; flex-direction: column; gap: var(--rf-e1); min-height: 0; }
.rf-conv-sofia { flex: none; align-self: center; width: 180px; height: 180px; }
.rf-sofia-panneau .rf-conv-fil { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.rf-sofia-panneau:not(.rf-conv-engagee) .rf-conv-fil { flex-grow: 0; }   /* à l'accueil, le champ suit la question ; engagée, il passe en bas */
.rf-conv-chat { flex: none; }
.rf-conv-engagee .rf-conv-sofia, .rf-sofia-panneau:not(.rf-conv-engagee) .rf-conv-chat .esp-sofia { display: none; }
:root:not(.rf-sofia-vivante) .rf-conv-sofia, :root:not(.rf-sofia-vivante) .rf-conv-chat .esp-sofia { display: none; }   /* sans la vraie Sofia (pas de carte graphique), pas de place vide */
:root.rf-sofia-vivante .rf-conv-tete .rf-bandeau-face { display: none; }   /* une seule Sofia : celle de la page, posée dans le volet */
.rf-sofia-panneau { grid-template-columns: minmax(0, 1fr); }   /* la conversation ne dépasse jamais l'écran (téléphone) */
@media (max-width: 599px) { .rf-conv-tete { flex-wrap: wrap; } .rf-conv-liens { order: 3; width: 100%; margin-left: 0; } }   /* au téléphone, Galerie et Bac à sable passent sous le nom */
@media (prefers-reduced-motion: reduce) { .rf-sofia-panneau, .rf-site-volet { transition: none; } }
.rf-conv-tete { display: flex; align-items: center; gap: var(--rf-e1); padding: var(--rf-e1) var(--rf-e2); border-bottom: 1px solid var(--line); }
.rf-conv-tete .icon-btn { margin-left: auto; width: 44px; height: 44px; }
.rf-badge { padding: 0 9px; border: 1px solid var(--line-strong); border-radius: var(--r-pill); }
.rf-conv { display: grid; grid-template-rows: auto auto 1fr auto auto; gap: var(--rf-e1); padding: var(--rf-e2); overflow: auto; }
.rf-conv-points { display: flex; flex-wrap: wrap; gap: 6px 12px; margin: 0; padding: 0; list-style: none; }
.rf-conv-points li::before { content: ""; display: inline-block; width: 6px; height: 6px; margin-right: 6px; border-radius: 50%; border: 1px solid currentColor; vertical-align: middle; }
.rf-conv-points li.on { color: var(--ink); } .rf-conv-points li.on::before { background: var(--rf-cuivre); border-color: var(--rf-cuivre); }
.rf-conv-fil { display: grid; gap: var(--rf-e1); align-content: start; }
.rf-bulle-conv { max-width: 88%; padding: 9px 15px; border-radius: var(--rf-r-petit); background: var(--paper-2); color: var(--ink); }
.rf-bulle-conv.vous { justify-self: end; background: var(--ink); color: var(--paper); }
/* v516 : les réponses à choix de l'estimation (puces du système, .chip) et le détail du prix (placement seulement) */
.rf-conv-choix { display: flex; flex-wrap: wrap; gap: 6px; justify-self: end; justify-content: flex-end; max-width: 92%; }
.rf-conv-detail { display: grid; gap: 6px; max-width: 88%; margin: 0; padding: 0 0 0 var(--rf-e2); color: var(--ink-2); }
/* v525 : sous le champ, la ligne d'information de la vraie Sofia et « Effacer la conversation » (.link-btn du système) : placement seulement */
.rf-conv-info { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--rf-e1); margin: 0; }
.rf-conv-info[hidden] { display: none; }
/* v349 : le champ est celui du site (.esp-chat, .ask, sa zone de texte : 40-espace.css, repris tel quel) */
.rf-conv-fin { display: grid; gap: var(--rf-e1); }
.rf-conv-message { width: 100%; box-sizing: border-box; padding: 12px 15px; border: 1px solid var(--line-strong); border-radius: var(--rf-r-petit); background: none; color: var(--ink); resize: vertical; }
.rf-cr { white-space: pre-line; padding: 12px 15px; border-radius: var(--rf-r-petit); background: var(--paper-2); color: var(--ink); }
.rf-conv-schema { margin: 0; display: grid; gap: 6px; justify-items: start; }

/* ── la page Contact ── */
.rf-contact-page .reg-c { padding-top: calc(var(--rf-entete) + var(--rf-e4)); }
.rf-form { display: grid; gap: var(--rf-e2); }
.rf-champ { display: grid; gap: 6px; }
.rf-champ input, .rf-champ textarea { min-height: 48px; padding: 12px 15px; box-sizing: border-box; width: 100%; border: 1px solid var(--line-strong); border-radius: var(--rf-r-petit);
  background: none; color: var(--ink); font: 400 17px/1.5 var(--font-sans); transition: border-color var(--dur-respond) var(--ease-out); }
.rf-champ input:focus-visible, .rf-champ textarea:focus-visible { border-color: var(--ink); outline: 2px solid var(--ink); outline-offset: 2px; }
.rf-champ [aria-invalid="true"] { border-color: var(--sig-red); }
.rf-erreur { color: var(--sig-red); }
.rf-envoi { display: grid; gap: var(--rf-e1); justify-items: start; }
.rf-reprise { display: flex; gap: var(--rf-e1); }
.rf-contact-page a:not([class]), .rf-conv-detail a, .rf-ed-texte a:not([class]) { color: var(--ink); text-underline-offset: 4px; }   /* v525 : le même lien texte pour les sources de Sofia ; v529 : et pour les sources des articles */

/* ── NOUVEAU · les deux passages épinglés (le haut de page, la scène de Sofia) et Sofia en grand ── */
.rf-epingle { height: 170vh; height: 170svh; padding: 0 !important; display: block !important; align-content: normal !important; }
.rf-colle { position: sticky; top: 0; height: 100vh; height: 100svh; display: grid; align-content: center; overflow: clip;
  padding-block: calc(var(--rf-entete) + var(--rf-e2)) var(--rf-e3); box-sizing: border-box; }
#haut .rf-colle > .rf-grille { position: relative; z-index: 1; }
.rf-sofia-scene { --sofia-l: min(760px, 56vw); }
#haut .rf-sofia-scene { position: absolute; z-index: 0; top: 50%; right: calc(-.25 * var(--sofia-l)); width: var(--sofia-l); transform: translateY(-50%); transform-origin: 70% 60%; }
#sofia .rf-sofia-scene { width: 100%; transform-origin: 50% 50%; }
.rf-sofia-img { display: block; width: 100%; height: auto; }
.rf-jour { display: none; }
:root[data-theme="light"] .rf-nuit { display: none; } :root[data-theme="light"] .rf-jour { display: block; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .rf-nuit { display: none; } :root:not([data-theme="dark"]) .rf-jour { display: block; } }
@media (prefers-reduced-motion: reduce), (max-width: 767px) {
  .rf-epingle { height: auto; } .rf-colle { position: relative; height: auto; min-height: 100svh; }
}
@media (max-width: 767px) { #haut .rf-sofia-scene { position: relative; top: auto; right: auto; width: 118%; margin: var(--rf-e3) 0 0 0; transform: none; } }
/* v669 (audit design du 22/10, tâche QG t-20261022-ad01) : sur tablette, sof·IA tient entière dans l'écran. De 768 à 1023 px, elle reste
   à droite du texte mais s'arrête à la marge (au lieu de déborder d'un quart de sa largeur) ; de 600 à 767 px, sous le texte, elle prend
   la largeur entre les marges (au lieu de 118 % de l’écran). Le téléphone (< 600 px) et l'ordinateur (≥ 1024 px) ne changent pas. */
@media (min-width: 768px) and (max-width: 1023px) { #haut .rf-sofia-scene { --sofia-l: min(560px, 46vw); right: var(--rf-marge); } }
@media (min-width: 600px) and (max-width: 767px) { #haut .rf-sofia-scene { width: calc(100% - 2 * var(--rf-marge)); margin-left: var(--rf-marge); } }
/* v686 (audit design, tâche QG t-20261023-ad12) : de 1024 à 1279 px (sous le plan d'un écran, qui commence à 1280 × 700), sof·IA s'arrête
   à la marge, à droite du texte, au lieu de déborder d'un quart de sa largeur ; sur un écran de moins de 900 px de haut (1024 × 768),
   le titre du haut prend le pas tablette de .t-grand (66/72) pour que le titre, l'accroche et « Faire le point » tiennent sous l'en-tête. */
@media (min-width: 1024px) and (max-width: 1279px) { #haut .rf-sofia-scene { --sofia-l: min(560px, 38vw); right: var(--rf-marge); } }
@media (min-width: 1024px) and (max-width: 1279px) and (max-height: 899px) { #haut h1.t-grand { font-size: 66px; line-height: 72px; } }

/* ── le Journal et le pied de page ── */
.rf-articles { columns: 3; column-gap: var(--rf-goutt); margin-top: var(--rf-e3); }   /* v310 : la mosaïque (masonry) en colonnes */
.rf-article { display: grid; gap: var(--rf-e1); align-content: start; break-inside: avoid; margin-bottom: var(--rf-e4); }
.rf-article a { color: inherit; text-decoration: none; display: grid; gap: var(--rf-e1); }
/* NOUVEAU (v420) · les lignes des services : une grande ligne par service, sous un filet ; le nom en titre, le bénéfice à côté, une
   flèche ; au survol (ou au focus), le filet et le nom passent à l'encre et la flèche descend (comme « Étude suivante », .rf-ed-suivante) */
.rf-services { display: grid; margin-top: var(--rf-e2); border-bottom: 1px solid var(--line); }
.rf-service { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr) 36px; align-items: center; gap: var(--rf-e2) var(--rf-goutt);
  min-height: 44px; padding: var(--rf-e2) 0; border-top: 1px solid var(--line); color: var(--ink-2); text-decoration: none; cursor: pointer;
  transition: border-color var(--dur-respond) var(--ease-out), color var(--dur-respond) var(--ease-out); }
.rf-service .t-titre { color: var(--ink); }
.rf-service .t-texte { color: var(--ink-2); }
.rf-service-fleche svg { width: 36px; height: 36px; transition: translate var(--dur-respond) var(--ease-out); }
.rf-service:is(:hover, :focus-visible) { border-top-color: var(--ink); color: var(--ink); }
@media (prefers-reduced-motion: no-preference) { .rf-service:is(:hover, :focus-visible) .rf-service-fleche svg { translate: 0 6px; } }
.rf-service:focus-visible { outline: 2px solid var(--ink); outline-offset: 6px; }
@media (max-width: 767px) { .rf-service { grid-template-columns: minmax(0, 1fr) 36px; padding: var(--rf-e2) 0; } .rf-service .t-texte { grid-column: 1; grid-row: 2; } .rf-service-fleche { grid-column: 2; grid-row: 1 / 3; } }
/* NOUVEAU (v402, commune depuis v415) · une liste sous filets : un élément par filet (le mini-site, les trois temps de Sofia) */
.rf-liste { display: grid; gap: var(--rf-e2); margin: 0; padding: 0; list-style: none; }
.rf-liste > * { display: grid; gap: 6px; padding-top: var(--rf-e2); border-top: 1px solid var(--line); }
.rf-liste p { margin: 0; }
.rf-liste-bloc { display: grid; gap: var(--rf-e1); }   /* v424 : une liste et son intitulé (« Ce qui est livré ») */
/* v404 (Raphaël, 17 octobre, 8 h 38 et 8 h 45 : « ajoute un effet quand je passe ma souris sur un article ») : la souris n'importe où sur
   l'article (ou le focus clavier) : sa tuile grandit un peu (celle du système, .rf-tuile:hover) et le visuel grandit dedans (le Journal du
   site, 45-journal.css : .jr-card-a:hover .jr-cover) */
.rf-article .jr-cover { transition: transform var(--dur-trace) var(--ease-out); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .rf-article a:is(:hover, :focus-visible) .rf-tuile { transform: scale(1.02); }
  .rf-article a:is(:hover, :focus-visible) .jr-cover { transform: scale(1.03); }
}
@media (max-width: 1023px) { .rf-articles { columns: 2; } }
@media (max-width: 599px) { .rf-articles { columns: 1; } }
.rf-pied { padding: var(--rf-e4) 0 0; border-top: 1px solid var(--line); }   /* v435 (Raphaël, 17 octobre, 13 h 21 : « réduis le padding bottom du footer à 0 ») */
.rf-pied .rf-grille { row-gap: var(--rf-e2); align-items: start; }
.rf-pied-liens { display: flex; flex-wrap: wrap; gap: var(--rf-e1) var(--rf-e2); justify-content: flex-end; }   /* le pied court des études */
@media (max-width: 767px) { .rf-pied-liens { justify-content: flex-start; } }

/* téléphone et tablette : la vedette garde son image entière, le titre passe dessous (sur l'image il cachait le logo) */
@media (max-width: 1023px) {
  .rf-vedette { margin-top: calc(-1 * var(--rf-e3)); }
  .rf-voile { display: none; }
  .rf-vedette-texte { position: static; margin-top: var(--rf-e2); }
  .rf-vedette-texte { color: var(--ink); } .rf-vedette-texte .rf-legende { color: var(--ink-2); }
}

/* ═════ Mouvement (v257–259, 15 octobre) — hors design system pour l'instant, à la demande de Raphaël ═════ */
/* ── v257 · le champ de points (champ.js) : derrière le contenu, devant le fond de la page ── */
.rf-page { isolation: isolate; }
canvas.rf-champ { position: fixed; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; }   /* v386 : la toile seule (.rf-champ est aussi le champ du formulaire de contact) */
.rf-champ-on .rf-decor-haut { display: none; }
.rf-champ-on #equipe .rf-scene svg { visibility: hidden; }   /* le globe de points prend sa place */
/* l'en-tête au-dessus d'une zone sombre (la vedette, « le tout ») : sans fond, en clair */
.rf-entete.nuit { background: none; }   /* v488 : refonte.js pose aussi .zone-nuit (jetons de nuit du système) */
.rf-entete { transition: background-color var(--dur-open) var(--ease-out); }
/* v257 (« le tout » de nuit quel que soit le thème) retiré en v299 : la page garde le thème choisi, le rythme vient des fonds */

/* v350 · sof.IA, le nom (artefact « sof.IA, le nom », retenu par Raphaël le 11 octobre à 17 h 12) : « sof » en Playfair italique,
   un rond plein à mi-hauteur, « IA » en Outfit 800, serré. Nouvel élément, fait des jetons du système (--font-serif, --font-sans,
   currentColor) ; à proposer au design system. Il se dit « Sofia » (aria-label, posé par tools/refonte.mjs et nom.js). */
.nom-sofia { display: inline-flex; align-items: baseline; white-space: nowrap; text-transform: none; }   /* « sof » reste en minuscules, même dans une étiquette en capitales */
.nom-sofia-s { font-family: var(--font-serif); font-style: italic; font-weight: 400; letter-spacing: -.01em; }
.nom-sofia-p { display: inline-block; flex: none; width: .17em; height: .17em; margin: 0 .07em; border-radius: 50%; background: currentColor; transform: translateY(-.26em); }
.nom-sofia-ia { font-family: var(--font-sans); font-style: normal; font-weight: 800; letter-spacing: -.01em; }   /* v674 : « IA » reste droit, même dans un <em> (Outfit n'a pas d'italique : sinon un faux italique) */
.rf-l.nom-sofia { display: inline-flex; }   /* dans un grand titre, le nom monte d'un seul bloc (mouvement.js) */
/* le temps d'ajuster la taille d'un titre (scenes-page.js), à toutes les largeurs (le titre de la FAQ aussi) : sans transition, on lit la vraie taille */
.rf-mesure, .rf-mesure * { transition: none !important; }
/* ── v258 · les titres : chaque lettre monte depuis le masque de son mot, le point final arrive en cuivre ── */
.rf-g { white-space: nowrap; } .rf-g .rf-rot { white-space: normal; }   /* la phrase qui tourne peut couper, pas avant son point */
.rf-m { display: inline-block; overflow: clip; padding: .1em .08em .16em 0; margin: -.1em -.08em -.16em 0; }
.rf-l { display: inline-block; }
.rf-pt { color: var(--rf-cuivre); }
@media (prefers-reduced-motion: no-preference) {
  .rf-decoupe .rf-l { transition: transform .9s cubic-bezier(.16, 1, .3, 1) calc(var(--i) * 22ms); }
  .rf-decoupe .rf-pt { transition: transform .8s cubic-bezier(.34, 1.56, .64, 1) calc(var(--i) * 22ms + 240ms); }
  .rf-decoupe:not(.rf-vu):not(.rf-rot) .rf-l { transform: translateY(115%); transition: none; }
  @keyframes rf-l-monte { from { transform: translateY(115%); } }
}
/* ── v258 · ce qui suit le titre : un fondu montant (les textes avec un léger flou), en retard de --d ── */
@media (prefers-reduced-motion: no-preference) {
  .rf-monte { transition: opacity .9s cubic-bezier(.16, 1, .3, 1) var(--d, 0ms), translate .9s cubic-bezier(.16, 1, .3, 1) var(--d, 0ms),
    filter .9s cubic-bezier(.16, 1, .3, 1) var(--d, 0ms), transform var(--dur-respond) var(--ease-out); }
  .rf-monte:not(.rf-vu) { opacity: 0; translate: 0 36px; transition: transform var(--dur-respond) var(--ease-out); }
  .rf-monte:is(.t-accroche, .t-texte):not(.rf-vu) { filter: blur(8px); }
}
@media (prefers-reduced-motion: reduce) {
  .rf-monte { transition: opacity .3s ease var(--d, 0ms); } .rf-monte:not(.rf-vu) { opacity: 0; transition: none; }
}

/* ── v274 · les maquettes en plâtre dans la page (three.js : maquette.js et ses scènes, montées par scenes-page.js) ──
   Une scène par chapitre ; elle se monte à l'approche et se détruit au loin. Le haut et la fin : la presqu'île ton sur ton, en fond.
   Sans WebGL 2, le bloc disparaît (rf-maquette-sans) et la page reste entière. */
.rf-maquette { position: relative; }
.rf-maquette .mq-gl { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: pan-y; }
.rf-maquette-scene { height: min(78vh, 760px); margin-top: var(--rf-e3); }
.rf-maquette-scene .mq-gl, .rf-maquette-col .mq-gl { cursor: grab; }
.rf-maquette-scene .mq-gl:active, .rf-maquette-col .mq-gl:active { cursor: grabbing; }
.rf-maquette-large { height: min(64vh, 600px); margin-block: var(--rf-e3); }
/* v511 (Raphaël, 20 octobre, 11 h 35) : avec une souris, les maquettes des rubriques sont réduites au repos et s'agrandissent au survol
   (scenes-page.js pose .rf-maquette-survol) ; la toile seule change d'échelle, autour du centre de son bloc : la mise en page ne bouge pas.
   Au doigt, elles gardent leur taille. Mouvement réduit : sans animation. À proposer au design system (jetons --rf-mq-repos et --rf-mq-survol). */
.rf-page { --rf-mq-repos: .78; --rf-mq-survol: 1.06; }
@media (hover: hover) and (pointer: fine) {
  .rf-maquette:is(.rf-maquette-scene, .rf-maquette-col) .mq-gl { transform: scale(var(--rf-mq-repos)); transition: transform var(--dur-trace) var(--ease-out); }
  .rf-maquette:is(.rf-maquette-scene, .rf-maquette-col).rf-maquette-survol .mq-gl { transform: scale(var(--rf-mq-survol)); }
}
@media (prefers-reduced-motion: reduce) { .rf-maquette .mq-gl { transition: none; } }
.rf-maquette-col { min-height: 520px; align-self: stretch; }
.rf-maquette-fond { position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: .5; }   /* « effacée » (15 octobre) : la ville reste derrière le texte */
/* v305 (Raphaël, 12 h 34) : l'aide « Glissez pour tourner la maquette » est retirée : le curseur le dit (« Tourner ») */
.rf-maquette-sans { display: none; }
#haut .rf-sofia-scene { z-index: 1; }
#haut .rf-colle > .rf-grille { z-index: 2; }
#fin { position: relative; overflow: clip; }
#fin > .rf-grille { position: relative; z-index: 1; }
@media (max-width: 767px) { .rf-maquette-fond { display: none; } .rf-maquette-scene { height: 62vh; height: 62svh; } .rf-maquette-col { min-height: 380px; } .rf-maquette-large { height: 52vh; } }

/* ── v291 · le curseur en verre qui dit l'action (curseur.js) : le point du site grandit en rond de verre sur ce qui agit ──
   v293 · les réglages de Raphaël (16 octobre, 11 h 41) : verre givré, diamètre 80 px, 250 ms, voile 0,1, saturation 1, contour 0,6,
   reflet 1, flou 5 px, texte 10 px en capitales espacées. */
.rf-verre { --d: 80px; --t: 250ms; --teinte: .1; --sat: 1; --bord: .6; --reflet: 1; --flou: 5px; --flou-l: 1px;
  position: fixed; left: 0; top: 0; z-index: 9998; width: var(--d); height: var(--d); margin: calc(var(--d) / -2) 0 0 calc(var(--d) / -2); border-radius: 50%;
  display: grid; place-items: center; padding: .75rem; text-align: center; pointer-events: none; opacity: 0; scale: .1;
  transition: scale var(--t) var(--ease-out), opacity calc(var(--t) * .6) ease; will-change: translate, scale; }
.rf-verre.on { opacity: 1; scale: 1; }
.rf-verre span { font: 600 10px/1.15 var(--font-sans); letter-spacing: .16em; text-transform: uppercase; color: var(--ink); text-shadow: 0 0 .375rem rgba(var(--paper-rgb), .95), 0 0 .125rem rgba(var(--paper-rgb), .9); }
.rf-verre[data-mode="givre"] { background: rgba(var(--paper-rgb), var(--teinte)); -webkit-backdrop-filter: blur(var(--flou)) saturate(var(--sat)); backdrop-filter: blur(var(--flou)) saturate(var(--sat));
  box-shadow: inset 0 0 0 1px rgba(var(--ink-rgb), var(--bord)), inset 0 1px 0 rgba(255, 255, 255, var(--reflet)), 0 .75rem 2rem rgba(var(--ink-rgb), .12); }
@media (prefers-reduced-motion: reduce) { .rf-verre { transition: opacity 150ms ease; scale: 1; } }
/* l'indice de défilement du site, en bas du premier écran */
#haut .hint { z-index: 3; }
@media (max-width: 767px) { #haut .hint { display: none; } }

/* ── v276 · le menu qui suit la lecture (idée de hailstonelabs) : les rubriques et les chapitres déjà passés restent allumés ──
   En-tête : une piste (le fond de la pastille du système, très léger) court de la première rubrique à celle où l'on est. */
@media (min-width: 1280px) { #rf-rubriques { position: relative; } }   /* v386 : sous 1280 px, le volet du menu est en position fixe (l'id l'emportait : il s'ouvrait hors de l'écran) */
.rf-piste { position: absolute; z-index: -1; top: 50%; height: 36px; translate: 0 -50%; border-radius: var(--r-pill); background: rgba(var(--ink-rgb), .08); opacity: 0;
  transition: left var(--dur-open) var(--ease-out), width var(--dur-open) var(--ease-out), opacity var(--dur-respond) var(--ease-out); pointer-events: none; }
.rf-piste[data-vu] { opacity: 1; }
#rf-rubriques a[data-passe], #rf-rubriques a[aria-current="location"] { color: var(--ink); }
#rf-rubriques .link-btn { min-width: 44px; justify-content: center; }   /* v346 : des entrées courtes, la cible garde 44 px */
#rf-rubriques a[aria-current="location"]::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--rf-cuivre); }   /* v340 : la rubrique où l'on est, le point des chapitres */
@media (max-width: 1279px) { .rf-piste { display: none; } }
/* NOUVEAU (v421) · le sous-menu des services : un panneau de verre du système (--glass, --glass-blur, --shadow-float, rayon de panneau)
   sous « Services », ouvert au survol et quand le focus y entre (le clavier y passe d'un lien à l'autre) ; sous 1280 px, dans le volet
   du menu, les quatre lignes restent visibles, sous Services */
.rf-sous { position: relative; display: flex; }
.rf-sous-chevron svg { width: 14px; height: 14px; margin-left: 6px; transition: rotate var(--dur-respond) var(--ease-out); }
.rf-sous-liste { display: none; flex-direction: column; }
@media (min-width: 1280px) {
  .rf-sous-liste { position: absolute; top: 100%; left: calc(-1 * var(--rf-e1)); min-width: 228px; padding: var(--rf-e1); border-radius: var(--r-panel);
    background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); box-shadow: var(--shadow-float); }
  .rf-sous-liste::before { content: ""; position: absolute; inset: calc(-1 * var(--rf-e1)) 0 auto; height: var(--rf-e1); }   /* le pont entre le lien et le panneau : le survol ne se perd pas */
  .rf-sous:is(:hover, :focus-within) .rf-sous-liste { display: flex; }
  @media (prefers-reduced-motion: no-preference) { .rf-sous:is(:hover, :focus-within) .rf-sous-chevron svg { rotate: 180deg; } }
  #rf-rubriques .rf-sous-liste .link-btn { min-height: 44px; justify-content: flex-start; padding-inline: var(--rf-e1); }
}
@media (max-width: 1279px) { .rf-sous { flex-direction: column; } .rf-sous-liste { display: flex; } .rf-sous-chevron { display: none; } }

/* ── v299 · le rythme par les fonds (Raphaël, 16 octobre, 11 h 41) : la page garde le thème choisi du début à la fin (plus de passage
   en nuit, v277 retiré) ; certains chapitres passent sur le second papier du système (--paper-2 : un gris un peu plus foncé le jour,
   un noir un peu plus clair la nuit). Le papier est redéfini dans la section : les maquettes, le verre et les cartes le suivent. ── */
.rf-ecran[data-fond="2"] { --paper: var(--paper-2); --paper-rgb: 243, 245, 247; background: var(--paper); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .rf-ecran[data-fond="2"] { --paper-rgb: 15, 20, 27; } }
:root[data-theme="dark"] .rf-ecran[data-fond="2"] { --paper-rgb: 15, 20, 27; }

/* ── v278 · les études de cas en pages éditoriales (comme les pages « work » de nk.studio) ──
   Titre géant terminé par son point de cuivre, métadonnées en « / », grande vidéo avec sa pastille, puis des sections numérotées :
   le titre à gauche, une colonne de lecture à droite ; les figures prennent la largeur. Styles du système (t-*, jetons). */
.rf-ed { max-width: var(--rf-max); margin: 0 auto; padding: calc(var(--rf-entete) + var(--rf-e4)) var(--rf-marge) var(--rf-e5); }
.rf-ed-sur { margin: 0 0 var(--rf-e1); color: var(--ink-3); }
.rf-ed-sur .link-btn { font-size: inherit; color: inherit; }
.rf-ed-tete { max-width: 1020px; }
.rf-ed-tete h1 { margin: 0; }
.rf-ed-meta { display: flex; flex-wrap: wrap; gap: var(--rf-e2) var(--rf-e3); margin: var(--rf-e3) 0 0; }
.rf-ed-meta div { display: grid; gap: 6px; } .rf-ed-meta dd { margin: 0; }
.rf-ed-hero { position: relative; margin: var(--rf-e4) 0 0; border-radius: var(--rf-r-media); overflow: hidden; background: var(--paper-2); }
.rf-ed-hero :is(video, img) { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }   /* v527 : l’image des vrais articles du Journal, comme la vidéo des études */
.rf-ed-pastille { position: absolute; right: var(--rf-e2); bottom: var(--rf-e2); margin: 0; padding: 6px 12px; border-radius: var(--r-pill); background: rgba(var(--paper-rgb), .82); color: var(--ink); }
.rf-ed-part { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--rf-e3); margin-top: var(--rf-e5); }
.rf-ed-col h2 { margin: 0; }
@media (min-width: 1024px) { .rf-ed-col { position: sticky; top: calc(var(--rf-entete) + var(--rf-e2)); align-self: start; } }
.rf-ed-texte { max-width: 66ch; color: var(--ink-2); font: 400 18px/30px var(--font-sans); }
.rf-ed-texte > :first-child { margin-top: 0; }
.rf-ed-texte p { margin: 0 0 var(--rf-e2); } .rf-ed-texte b, .rf-ed-texte strong { color: var(--ink); font-weight: 600; }
.rf-ed-texte .pj-fig { margin: var(--rf-e3) 0; } .rf-ed-texte .pj-fig img, .rf-ed-texte .pj-fig video { display: block; width: 100%; height: auto; border-radius: var(--rf-r-petit); }
.rf-ed-texte figcaption { margin-top: var(--rf-e1); color: var(--ink-3); font: 400 13px/18px var(--font-sans); }
.rf-ed-texte .pj-schema svg { width: 100%; height: auto; }
.rf-ed-texte :is(.pj-steps, .pj-dec, .pts) { margin: 0 0 var(--rf-e2); padding: 0; list-style: none; display: grid; gap: var(--rf-e1); }
.rf-ed-texte .pj-steps { counter-reset: st; } .rf-ed-texte .pj-steps li { counter-increment: st; position: relative; padding-left: var(--rf-e3); }
.rf-ed-texte .pj-steps li::before { content: counter(st, decimal-leading-zero); position: absolute; left: 0; color: var(--rf-cuivre); font-weight: 500; }
.rf-ed-texte .pj-dec li { display: grid; gap: 6px; padding-left: var(--rf-e2); border-left: 2px solid var(--ink); }
.rf-ed-texte :is(.pj-facts, .facts) { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--rf-e2); margin: 0 0 var(--rf-e2); padding-top: var(--rf-e2); border-top: 1px solid var(--line); }
.rf-ed-texte :is(.pj-facts, .facts) dt { color: var(--ink-3); font-size: 13px; } .rf-ed-texte :is(.pj-facts, .facts) dd { margin: 6px 0 0; color: var(--ink); }
.rf-ed-texte .pj-src { color: var(--ink-3); font-size: 13px; }
.rf-ed-texte code { font-family: var(--font-mono, ui-monospace); font-size: .9em; }
.rf-ed-chiffres { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--rf-e2); margin: var(--rf-e3) 0 0; padding-top: var(--rf-e2); border-top: 1px solid var(--line); }
.rf-ed-chiffres dd { margin: 6px 0 0; }
.rf-ed-chiffre { font: 500 36px/42px var(--font-sans); letter-spacing: -.02em; color: var(--ink); }
.rf-ed-suite { margin-top: var(--rf-e5); padding-top: var(--rf-e3); border-top: 1px solid var(--line); }
.rf-ed-suivante { display: inline-flex; align-items: center; gap: var(--rf-e2); color: var(--ink); text-decoration: none; }
.rf-ed-fleche svg { width: 36px; height: 36px; transition: translate var(--dur-respond) var(--ease-out); }
.rf-ed-suivante:hover .rf-ed-fleche svg { translate: 6px 0; }
@media (max-width: 1023px) { .rf-ed-part { grid-template-columns: 1fr; gap: var(--rf-e2); margin-top: var(--rf-e4); } }

/* ── v292 · une seule Sofia sur toute la page (sofia-page.js) : une toile fixe au-dessus de la page, qui ne laisse pas passer la souris ;
   les images de Sofia restent à leur place (ce sont ses repères), invisibles, et reviennent sans WebGL ── */
.rf-sofia-toile { position: fixed; left: 0; top: 0; z-index: 2; width: 560px; height: 560px; pointer-events: none; will-change: transform; }
.rf-sofia-vivante .rf-sofia-img { visibility: hidden; }


/* ── v295 · la page de réglage de la skyline (/?reglages=skyline, reglages-skyline.js) : un outil de travail, aux couleurs du site ── */
.rf-reglage { position: fixed; top: 4.5rem; right: 1.5rem; z-index: 9990; width: min(22.5rem, calc(100vw - 3rem)); max-height: calc(100svh - 6rem); overflow-y: auto; display: grid; gap: .75rem;
  padding: 1.125rem; border: 1px solid var(--line); border-radius: 1.125rem; background: var(--paper); color: var(--ink); box-shadow: var(--shadow-float); }
.rf-reglage p { margin: 0; }
.rf-reglage-choix { display: flex; gap: .375rem; }
.rf-reglage-choix [aria-pressed="true"] { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
.rf-reglage-liste { display: grid; gap: .375rem; }
/* v455 : le menu déroulant du système (.jr-sel) dans le réglage de mise en page : seulement sa place, toute la largeur */
.rf-reglage .jr-sel, .rf-reglage .jr-sel select { width: 100%; }
.rf-reglage label { display: grid; gap: 0; }
.rf-reglage label output { float: right; font-variant-numeric: tabular-nums; color: var(--ink); }
.rf-reglage input[type="range"] { width: 100%; min-height: 2.75rem; accent-color: var(--ink); cursor: pointer; }
.rf-reglage-sortie { margin: 0; padding: .75rem; border-radius: .75rem; background: var(--paper-2); font: 400 .75rem/1.5 ui-monospace, Menlo, monospace; white-space: pre-wrap; }
/* v315, réduit en v361 · le repère du défilement (reglage-sofia.js, /?reglages=sofia) : le rectangle et le panneau des étapes sont retirés */
.rf-sofia-niveau { position: fixed; z-index: 9990; top: 4.5rem; left: 1.5rem; display: grid; gap: .375rem; max-width: min(36rem, calc(100vw - 3rem)); padding: .5rem .75rem;
  border: 1px solid var(--line); border-radius: .75rem; background: var(--paper); color: var(--ink); font-variant-numeric: tabular-nums; pointer-events: none; }
.rf-sofia-niveau-barre { display: block; height: 3px; border-radius: 2px; background: var(--line-strong); overflow: hidden; }
.rf-sofia-niveau-barre i { display: block; height: 100%; background: var(--ink); transform-origin: 0 50%; }
.rf-reglage-choix { flex-wrap: wrap; }
@media (max-width: 767px) { .rf-sofia-niveau { max-width: none; right: 1.5rem; top: auto; bottom: 5.25rem; } }

/* ── v300 · le titre géant (Raphaël, 11 h 13, point 10) : les titres sans maquette prennent la taille des titres peints derrière les
   maquettes (maquette.js : 10,5 % de la largeur, 200 px au plus ; 15 % sur téléphone), centrés, Outfit 500, l'italique en Playfair.
   À proposer au design system (style de texte « titre géant ») ; pour la FAQ, il donne aussi le contraste avec les questions. ── */
.rf-titre-geant { margin: 0 0 var(--rf-e3); padding-inline: 4vw; font: 500 min(10.5vw, 200px)/.92 var(--font-sans); letter-spacing: -.045em; text-align: center; text-wrap: balance; color: var(--ink); }
.rf-titre-geant em { font-family: var(--font-serif); font-weight: 400; letter-spacing: -.02em; }
@media (max-width: 767px) { .rf-titre-geant { font-size: 15vw; } }

/* ── v302 · le pied de page (comme nk.studio) : la marque et l'appel à gauche, le plan du site en trois colonnes, les réseaux, la langue ── */
.rf-pied-haut { row-gap: var(--rf-e4); padding-bottom: var(--rf-e4); }
.rf-pied-marque { display: grid; align-content: start; gap: var(--rf-e2); }
.rf-pied-marque p { margin: 0; max-width: 32ch; color: var(--ink-2); }
.rf-pied-menu { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--rf-e3); }
.rf-pied-menu ul, .rf-reseaux { margin: 0; padding: 0; list-style: none; }
.rf-pied-menu ul { display: grid; }
.rf-pied-menu .link-btn { min-width: 44px; }
.rf-pied-sous { margin: 0; padding: 0 0 0 var(--rf-e2); list-style: none; display: grid; }   /* v421 : les services en retrait sous Services */   /* v412 : « Site », le nom court du menu (v384), garde une cible de 44 px, comme dans l'en-tête (v346) */
.rf-pied-titre { margin: 0 0 var(--rf-e1); color: var(--ink-3); }
.rf-pied-bas { align-items: center; row-gap: var(--rf-e2); padding-block: var(--rf-e3); border-top: 1px solid var(--line); }
.rf-reseaux { display: flex; flex-wrap: wrap; gap: var(--rf-e1); }
.rf-pied-legal { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--rf-e2); }
.rf-pied-legal p { margin: 0; color: var(--ink-3); }
.rf-langue { display: inline-flex; gap: var(--rf-e1); }
.rf-langue [aria-current] { color: var(--ink); }
.rf-langue [aria-disabled] { color: var(--ink-3); }
@media (max-width: 767px) { .rf-pied-menu { grid-template-columns: 1fr 1fr; } .rf-pied-legal { justify-content: flex-start; } }
/* v685 (audit design du 23/10, tâche QG t-20261023-ad11) : de 768 à 1279 px, la moitié droite ne laisse que 100 à 130 px par colonne ;
   « Outils et automatisations » (.link-btn, nowrap) débordait sur la colonne voisine. Le plan du site passe sous la marque, sur toute la largeur
   (placement seulement : mêmes trois colonnes, même écart --rf-e3). Dès 1280 px, rien ne change. */
@media (min-width: 768px) and (max-width: 1279px) { .rf-pied .rf-pied-menu { grid-column: 1 / 13; } }

/* ── v304 · la skyline du haut placée par Raphaël (16 octobre, 12 h 39, page de réglage) : azimut −23°, hauteur 10°, recul 30, point visé 1,3,
   opacité 0,7, décalée de 50 % vers le bas, échelle 2 ; parallaxe : base −3,5°, souris 15°, défilement 0° / 15° (dans vente.html) ── */
#haut .rf-maquette-fond { opacity: .7; transform-origin: 50% 100%; transform: translate(0, 50%) scale(2); }

/* ── v306 · les vidéos de motion design (reels-page.js) : une toile au format des showreels (1440 × 1000), sur fond d'encre (traits clairs) ;
   la vidéo de la formation colle à l'écran et grandit de sa taille de bloc jusqu'à tout l'écran (--u de 0 à 1) ── */
.rf-reel { position: relative; aspect-ratio: 1440 / 1000; border-radius: var(--rf-r-media); overflow: hidden; background: #0b0c0e; }
.rf-reel canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.rf-tuile .rf-reel { margin-bottom: var(--rf-e2); }
/* v374 · l'aimant des vidéos des outils (reels-page.js) : la tuile survolée passe devant et ne coupe plus sa vidéo, qui grandit et suit la souris */
#outils .rf-tuiles .rf-tuile.rf-aimant { overflow: visible; z-index: 3 !important; }
#outils .rf-tuiles .rf-tuile.rf-aimant .rf-reel { position: relative; z-index: 1; box-shadow: var(--shadow-float); }
.rf-reel-scene { position: relative; height: 240vh; height: 240svh; margin-top: var(--rf-e4); }
.rf-reel-colle { position: sticky; top: 0; height: 100vh; height: 100svh; display: grid; place-items: center; overflow: clip; }
.rf-reel-grand { --u: 0; --w0: min(82vw, 1080px); aspect-ratio: auto; width: calc(var(--w0) + (100vw - var(--w0)) * var(--u)); height: calc(var(--h0, var(--w0) * 1000 / 1440) + (100vh - var(--h0, var(--w0) * 1000 / 1440)) * var(--u));   /* v313 : --h0, la hauteur de départ (sinon le format des showreels) */
  border-radius: calc(var(--rf-r-media) * (1 - var(--u))); }
/* v337 : les commandes de la vidéo de la formation, en bas de la vidéo, sur un voile : elles apparaissent quand elle est presque en grand */
.rf-reel-ctl { position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; border-top: 0 !important; background: var(--scrim); color: var(--on-scrim);
  opacity: clamp(0, (var(--u, 0) - .85) * 10, 1); pointer-events: none; transition: opacity var(--dur-respond) var(--ease-out); }
.rf-reel-grand[style*="--u: 1"] .rf-reel-ctl, .rf-reel-grand[style*="--u: 0.9"] .rf-reel-ctl { pointer-events: auto; }
.rf-reel-ctl .icon-btn { color: inherit; }
.rf-reel-ctl { --ink: var(--on-scrim); --line-strong: rgba(255, 255, 255, .35); }   /* sur le voile, la barre et son curseur en clair (contraste) */
@media (prefers-reduced-motion: reduce) { .rf-reel-scene { height: auto; } .rf-reel-colle { position: static; height: auto; } .rf-reel-grand { width: var(--w0); height: auto; aspect-ratio: 1440 / 1000; } }

/* ── v307 · la skyline de la fin placée par Raphaël (12 h 55) : azimut 161°, hauteur 10°, recul 14,5, point visé 1,3, opacité 0,45,
   décalée de −3 % à gauche, échelle 0,9 ; parallaxe : base 5,5°, souris 5°, défilement 0° / 0° (dans vente.html) ── */
#fin .rf-maquette-fond { opacity: .45; transform-origin: 50% 100%; transform: translate(-3%, 0) scale(.9); }

/* ── v313 · les mises en page de Raphaël (16 octobre, 12 h 34, page « Mises en page des rubriques ») ──
   Sur ordinateur (≥ 1280 px de large et ≥ 700 px de haut : à 1024 × 768, les textes ne tiennent plus dans les boîtes), chaque rubrique est un plan : une boîte de (--ecrans × la hauteur de l'écran), et chaque bloc s'y pose
   par ses colonnes de la grille du site (--de → --a, les 12 colonnes, marges et gouttières de .rf-grille) et par sa hauteur dans
   l'écran (--pos-y, en % de la hauteur de l'écran ; --pos-h, la hauteur du bloc, seulement pour les images, les vidéos et les maquettes :
   les textes gardent leur hauteur naturelle). Les enveloppes (.rf-grille, .rf-col, .rf-entree) ne placent plus rien dans un plan.
   Profondeur : le titre derrière (0), la maquette (1), les textes et les actions devant (2).
   En dessous, rien ne change : la page reste en colonne. */
@media (min-width: 1280px) and (min-height: 700px) {
  .rf-ecran:has(> .rf-plan), .rf-colle:has(> .rf-plan) { padding-block: 0 !important; min-height: 0; display: block; }
  .rf-plan { --gw: min(100% - 2 * var(--rf-marge), var(--rf-max)); --col: calc((var(--gw) - 11 * var(--rf-goutt)) / 12);
    position: relative; height: calc(var(--ecrans, 1) * 100vh * var(--rf-plan-k, 1)); height: calc(var(--ecrans, 1) * 100svh * var(--rf-plan-k, 1)); text-align: left; }
  .rf-plan :is(.rf-grille, .rf-col, .rf-entree):not(.rf-pose) { position: static !important; display: block; margin: 0; padding: 0; }
  /* !important : la place du plan passe avant celle des règles propres à chaque rubrique (#haut .rf-sofia-scene…), écrites pour la colonne */
  .rf-plan .rf-pose { position: absolute !important; z-index: 2; box-sizing: border-box; margin: 0; max-width: none;
    left: calc((100% - var(--gw)) / 2 + (var(--de) - 1) * (var(--col) + var(--rf-goutt))) !important;
    width: calc((var(--a) - var(--de)) * var(--col) + (var(--a) - var(--de) - 1) * var(--rf-goutt)) !important;
    top: calc(var(--pos-y) * 1svh * var(--rf-plan-k, 1) + var(--decale, 0px)) !important; }   /* v512 : --decale, refonte.js */
  .rf-plan .rf-pose[style*="--pos-h"] { height: calc(var(--pos-h) * 1svh * var(--rf-plan-k, 1)) !important; }
  .rf-plan .rf-pose.rf-maquette { z-index: 1; margin: 0; min-height: 0; }
  /* v326 (Raphaël, 15 h 28 : « overflow visible partout ») : la toile déborde de 15 % autour de son bloc ; maquette.js ouvre l'angle de la
     caméra d'autant (la maquette garde sa taille et sa place) : ce qui dépasse du bloc se dessine au lieu d'être coupé. Le haut garde
     sa toile au bloc (sa skyline, à l'échelle 2, couvre déjà l'écran). Prix : environ 1,7 fois plus de pixels à dessiner par maquette. */
  .rf-plan .rf-maquette .mq-gl { inset: auto; left: -15%; top: -15%; width: 130%; height: 130%; }   /* v329 : une toile est un élément remplacé, ses bords ne l'étirent pas : sa taille est donnée */
  #haut .rf-plan .rf-maquette .mq-gl { inset: 0; width: 100%; height: 100%; }
  /* v375 (Raphaël, 0 h 08 : « quand elle est éclatée, elle dépasse de sa div : overflow visible ») : les neuf morceaux du tout s'écartent loin ; sa toile déborde de 35 % autour de son bloc */
  .rf-plan .rf-maquette[data-maquette="tout"] .mq-gl { left: -35%; top: -35%; width: 170%; height: 170%; }
  /* v317 : une skyline de fond posée sur toute la grille (1 → 13) va d'un bord à l'autre de l'écran : sinon, au-delà de 1440 px, sa toile
     (peinte du papier de la page) dessine un rectangle sur le fond de la rubrique */
  .rf-plan .rf-pose.rf-maquette-fond[style*="--de: 1; --a: 13"] { left: 0 !important; width: 100% !important; }
  .rf-plan .rf-pose.rf-derriere, .rf-plan .rf-pose.rf-maquette-fond { z-index: 0; }
  .rf-plan .rf-pose.rf-titre-geant { padding-inline: 0; }
  .rf-plan .rf-titre-geant.rf-a-gauche { text-align: left; }
  /* v319 : un bloc tenu par le bas de sa boîte (--pos-bas = --pos-y + --pos-h) : le titre du haut, dont la place est réservée pour la plus
     longue de ses fins (jusqu'à 4 lignes), grandit vers le haut au lieu de passer sur l'accroche ; le texte reste en bas de sa boîte */
  .rf-plan .rf-pose[style*="--pos-bas"] { top: auto !important; bottom: calc((var(--ecrans, 1) * 100svh - var(--pos-bas) * 1svh) * var(--rf-plan-k, 1)); display: flex; flex-direction: column; justify-content: flex-end; }   /* v319 : le titre des offres, à gauche, derrière la maquette et pas derrière les formules */
  /* v486 (audit du 18 octobre, CLS 0,4) : le titre qui tourne garde sa boîte tenue par le bas, mais son texte s'ancre en haut de la place
     réservée : quand une phrase prend une ligne de moins, c'est le vide du bas qui change, pas la position des mots */
  .rf-plan .rf-pose:has(> * > .rf-rot) { justify-content: flex-start; }
  .rf-plan .rf-pose.rf-appels { display: flex; flex-wrap: wrap; gap: var(--rf-e1); }
  /* v372 (Raphaël, 17 octobre, 0 h 08 : « des accroches passent sur les maquettes… blanc sur blanc, parfois, ça ne marche pas ; mettre un
     fond au texte, ça fait de la profondeur ») : dans un écran qui a une maquette, les accroches et les textes posés flottent sur un fond
     de verre du système (--glass, --glass-blur, l'ombre --shadow-float), aux coins des médias ; le fond déborde à gauche de la marge
     intérieure, si bien que le texte garde sa place */
  .rf-plan:has(.rf-maquette-scene, .rf-maquette-col) .rf-pose:is(.t-accroche, .t-texte, .rf-liste, .rf-liste-bloc) {   /* v415 : une liste posée (les trois temps de Sofia) aussi */
    margin-left: calc(-1 * var(--rf-e2)); padding: var(--rf-e1) var(--rf-e2);
    border-radius: var(--rf-r-media); background: var(--glass-texte); -webkit-backdrop-filter: var(--glass-texte-blur); backdrop-filter: var(--glass-texte-blur); box-shadow: var(--shadow-float); }   /* v392 (Raphaël, 17 octobre) : opacité .5, flou 6 px */
  /* le haut : la skyline garde ses réglages (opacité, décalage, échelle) dans sa boîte ; Sofia remplit la sienne ; l'indice est centré dans la sienne */
  .rf-plan .rf-pose.rf-sofia-scene { display: grid; place-items: center; }   /* son mouvement au défilement (refonte.js) reste */
  .rf-plan .rf-sofia-scene .rf-sofia-img { width: 100%; height: 100%; object-fit: contain; }
  .rf-plan .rf-pose.hint { bottom: auto; transform: none; }
  /* v382 (Raphaël, 0 h 11 : « remonte l'indice de défilement, il est quasiment hors champ : à 20 ou 30 px du bas de l'écran ») : tenu par le bas, à 24 px */
  #haut .rf-plan .rf-pose.hint { top: auto !important; bottom: 24px; }
  /* les formules : le point à gauche, le nom et le prix à droite, les lignes et l'action dessous */
  /* les trois formules, l'une sous l'autre à partir de la place de la première : les détails (lignes, action) de la formule choisie
     seulement (un clic sur une autre formule la choisit et montre les siens) ; la note reste à sa place, sous les formules */
  .rf-plan .rf-formules { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--rf-e1); margin: 0; }
  .rf-plan .rf-formules .rf-formules-note { margin-top: 0; }
  .rf-plan .rf-formule-col:has(> .rf-formule[aria-pressed="false"]) > :not(.rf-formule) { display: none; }
  .rf-plan .rf-formule-col { gap: 6px; align-content: start; justify-items: start; }
  .rf-plan .rf-formule-col .rf-formule { grid-template-columns: 96px minmax(0, 1fr); column-gap: var(--rf-e2); row-gap: 0; align-items: center; padding: var(--rf-e1) var(--rf-e2); background: var(--paper); }   /* sur le titre géant : le fond de la page */
  .rf-plan .rf-formule-col .rf-formule > svg { grid-row: 1 / span 3; }
  .rf-plan .rf-formule-lignes { display: block; padding: 0; } .rf-plan .rf-formule-lignes li { display: inline; }
  .rf-plan .rf-formule-lignes li + li::before { content: " · "; }   /* les lignes de la formule se suivent sur une ou deux lignes */
  #haut .rf-plan .rf-sofia-scene { transform: none; }
  /* v351 (Raphaël, 19 h 21 : « dans les écrans il doit y avoir un padding bottom… on est collé à l'écran suivant ; là où on a la vidéo
     en grand de la formation, il y a une bande inutile ») : chaque écran posé garde de l'air en bas (--rf-e4), dans son fond ; celui
     qui finit par la vidéo de la formation (qui grandit jusqu'à tout l'écran) s'arrête sur elle */
  .rf-ecran:has(> .rf-plan) { padding-bottom: var(--rf-e4) !important; }
  .rf-ecran:has(> .rf-plan):has(> .rf-reel-scene:last-child) { padding-bottom: 0 !important; }
  /* v380 (Raphaël, 0 h 08 : « sous la div maquette, un espace de 97 px à supprimer ») : la fin s'arrête sur sa maquette, le pied de page suit */
  #fin.rf-ecran:has(> .rf-plan) { padding-bottom: 0 !important; }
  /* sans mouvement : posée, pas centrée sur son milieu (refonte.js la déplace sinon) */
  /* les images de « votre image » : l'image remplit sa boîte, la légende dessous */
  /* v512 (Raphaël, 20 octobre, 11 h 35 : « réduis la hauteur des sections pour afficher davantage d'informations et limiter le défilement ») :
     sur l'accueil, chaque plan est resserré d'un même facteur (--rf-plan-k) : sa hauteur, la place et la hauteur de chaque bloc posé ;
     les textes gardent leur taille, ils prennent donc plus de place dans l'écran. Les écrans épinglés (le haut, Sofia) gardent leur plan d'un écran. */
  .rf-accueil .rf-ecran:not(.rf-epingle, #image, #outils, #portfolio-bref) > .rf-plan { --rf-plan-k: .85; }   /* Identité visuelle, les outils et les autres réalisations gardent le leur : leurs images et leurs vidéos sont le contenu, elles ne rapetissent pas (et la colonne de textes d'Identité visuelle ne tient déjà plus sur les écrans bas) */
  .rf-plan .rf-tuile-fig.rf-pose { display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: var(--rf-e1); }
  .rf-plan .rf-tuile-fig .rf-tuile { aspect-ratio: auto; height: 100%; }
  /* les tuiles des outils : la vidéo prend la place libre au-dessus du titre */
  .rf-plan .rf-tuiles { display: block; margin: 0; }
  .rf-plan .rf-tuiles .rf-tuile.rf-pose { display: flex; flex-direction: column; gap: var(--rf-e1); padding: var(--rf-e2) !important; }
  .rf-plan .rf-tuiles .rf-tuile .rf-reel { flex: 1 1 auto; min-height: 0; aspect-ratio: auto; margin-bottom: var(--rf-e1); }
  .rf-plan .rf-tuiles .rf-tuile-c h3, .rf-plan .rf-tuiles .rf-tuile-c p { padding: 0; }
  /* le tout : les phrases dans leur boîte, la hauteur de la ligne en mouvement ne pousse rien */
  .rf-plan .rf-frappe-ligne { min-height: 0; }   /* v522 : frappe.js lui donne la hauteur de la plus longue phrase (style), partout */
  #fin .rf-plan h2 { text-align: center; }
  /* comment ça se passe : les étapes l'une sous l'autre, les délais en deux colonnes */
  .rf-plan .rf-etapes { grid-template-columns: 1fr; margin: 0; gap: var(--rf-e2); }
  .rf-plan .rf-delais { grid-template-columns: 1fr 1fr; row-gap: var(--rf-e1); }
  /* la vidéo de la formation, sous le plan de l'équipe : elle part de la largeur de la grille et de 46 % de l'écran (Raphaël), puis grandit */
  #image:has(> .rf-plan) .rf-vedette { margin-top: 0; }
  @media (prefers-reduced-motion: no-preference) { .rf-plan + .rf-reel-scene { margin-top: -25.7vh; margin-top: -25.7svh; } }
  /* v333 (Raphaël, 16 h 12 : « vérifie les limites des maquettes et des sections ») : chaque plan coupe ce qui dépasse de sa rubrique
     (les toiles qui débordent de leur bloc s'arrêtent au bord de la rubrique) ; la vidéo de la formation passe au-dessus de la maquette */
  .rf-plan { overflow: clip; }
  .rf-plan + .rf-reel-scene { z-index: 3; pointer-events: none; }   /* v485 : le cadre de la scène chevauche le plan (−25,7 svh) ; il laisse passer souris et focus, seule la vidéo les garde */
  .rf-plan + .rf-reel-scene .rf-reel-colle { pointer-events: none; }
  .rf-plan + .rf-reel-scene .rf-reel-grand { pointer-events: auto; --w0: min(100vw - 2 * var(--rf-marge), var(--rf-max)); --h0: 46svh; }
}

/* ── v513 (Raphaël, 20 octobre, 12 h 08) puis v521 (15 h 05 : « le titre et la description continuent de défiler, la première carte vient se
   coller directement sous l'en-tête ; les cartes n'ont pas de rebords, elles prennent toute la page ; ce qui reste en haut de la carte quand la
   suivante la recouvre, c'est le nom de la formule ») ── Les offres : le titre, les deux textes et l'appel dans la page ; dessous, une carte par
   site de démonstration, d'un bord à l'autre de l'écran, sans arrondi ni ombre. La carte : la vidéo du site en fond (16/9 sur écran large, la
   version téléphone au-dessous de 768 px), un voile sombre en haut et en bas (--scrim), un flou sous les textes du bas (--glass-deep-blur) ; en
   haut, la formule (sa bande reste visible quand la carte suivante la recouvre) ; en bas à gauche le tarif et la description, à droite « Voir le
   site » (au téléphone, dessous, sur toute la largeur). Toute la carte ouvre le site (v491). Chaque carte se colle sous l'en-tête, un cran (--pas)
   plus bas que la précédente, et va jusqu'en bas de l'écran : quand la dernière est posée, toutes repartent ensemble (comme les études de cas,
   en CSS seul) ; la carte recouverte s'assombrit un peu (--vs, sites-page.js ; mouvement réduit : sans entre-deux). */
.rf-offres-tete { row-gap: var(--rf-e2); align-items: start; }
.rf-offres-tete h2, .rf-offres-tete p { margin: 0; }
.rf-offres-tete .rf-appels { margin: 0; align-self: end; justify-content: flex-end; }
@media (max-width: 1023px) { .rf-offres-tete .rf-appels { justify-content: flex-start; } }
.rf-sites { margin-top: var(--rf-e4); }
/* v606 · les formules en volets, comme les études (.rf-volets, .rf-etude) : les cartes pleine page (v513–v521) sont retirées. Toute la formule ouvre
   son site (sites-page.js). La variante .rf-volet-inverse ne règle que la place : la vidéo du site à gauche, le texte et le bouton à droite, le grand
   numéro au bout (le miroir des études). Sous 768 px, la vidéo du téléphone (portrait) prend une tuile 4:5, cadrée en haut. */
.rf-site { cursor: pointer; }
.rf-site .rf-etude-texte p { margin: 0; }
.rf-site-media { margin: 0; }
.rf-site-media video { object-position: top center; }
@media (max-width: 767px) { .rf-site-media.f-16-9 { aspect-ratio: 4 / 5; } }
@media (min-width: 1024px) {
  .rf-volet-inverse .rf-etude-media { grid-column: 1 / 7; grid-row: 1; }
  .rf-volet-inverse .rf-etude-texte { grid-column: 7 / 11; grid-row: 1; }
  .rf-volet-inverse .rf-volet-grand { grid-column: 11 / 13; grid-row: 1; justify-self: end; transform-origin: 100% 0; }
}
/* le volet du site : celui de Sofia (mêmes règles, ajoutées à ses sélecteurs plus haut ; même ouverture), avec le site dans un cadre sous son en-tête ; la Sofia de la page et
   le curseur du site s'effacent pendant qu'il est ouvert (le site a son propre curseur) */
.rf-site-volet { grid-template-rows: auto minmax(0, 1fr); }
.rf-site-volet .rf-conv-tete { background: var(--paper); }
.rf-site-volet-aide { margin-left: auto; color: var(--ink-2); }
.rf-site-volet-aide + .icon-btn { margin-left: 0; }
/* v474 (Raphaël, 18 octobre, 8 h 35) : le bandeau des tarifs du site passe dans l'en-tête du volet, toujours affiché ; le texte est celui que le site montre
   à cette largeur (variante longue ou courte), « Voir le détail » ouvre le détail du site. Styles du système : t-petit, link-btn ; ici, seulement la place. */
.rf-site-volet-prix { flex: 1 1 0; min-width: 0; margin: 0; color: var(--ink-2); text-wrap: balance; }
.rf-site-volet-prix b { font-weight: 600; color: var(--ink); }
.rf-site-volet-prix:not([hidden]) ~ .rf-site-volet-aide { margin-left: 0; }
.rf-site-cadre { display: block; width: 100%; height: 100%; border: 0; background: var(--paper); }
:root.rf-site-ouvert .rf-sofia-toile, :root.rf-site-ouvert .rf-verre { visibility: hidden; }
/* v477 (Raphaël, 8 h 56 : « dans l'en-tête, je n'ai plus de curseur ») : le point de la page reste sur l'en-tête du volet ; il ne s'efface
   que dans le site (.rf-dans-site, posée par sites-page.js), qui a son propre curseur */
:root.rf-site-ouvert.rf-dans-site #cur { visibility: hidden; }
@media (max-width: 599px) { .rf-site-volet-aide { display: none; } .rf-site-volet-prix { order: 3; flex-basis: 60%; } .rf-site-volet-detail { order: 3; } }

/* v463 : la maison des formules au bac à sable, dans la page d'essai des maquettes en cadre (rayon des médias, filet du système) */
.rf-bas-maison, .rf-bas-appel { display: grid; gap: var(--rf-e2); margin-top: var(--rf-e4); }   /* v674 : l'appel de fin (comme la Galerie), à la même place */
.rf-bas-maison h2, .rf-bas-maison p, .rf-bas-appel h2, .rf-bas-appel p, .rf-bas-appel .rf-appels { margin: 0; }
.rf-bas-cadre { display: block; width: 100%; height: 86vh; height: 86svh; min-height: 32rem; border: 1px solid var(--line); border-radius: var(--rf-r-media); background: var(--paper); }

/* ── v506 · la page 404 (perdu.html) : la mise en page éditoriale (.rf-ed) telle quelle ; ce bloc ne règle que la place : l'écran
   entier pour la seule idée de la page, la source sous la citation, l'accroche sur une mesure courte (grille de 6 px) ── */
.rf-perdu { min-height: 100svh; }
.rf-perdu.rf-ed { padding-left: 0; padding-right: 0; }   /* v508 : la grille porte déjà ses marges : le titre s’aligne sur le logo, comme à l’accueil */
.rf-perdu > .rf-grille { align-items: center; }   /* v508 : le texte à gauche (colonnes 1 à 7), la place de Sofia à droite (7 à 13), centrés en hauteur */
#haut.rf-perdu .rf-sofia-scene { position: relative; top: auto; right: auto; width: 100%; transform: none; }   /* v508 : sa place dans la colonne, au lieu du bord droit de l'accueil (#haut) */
@media (max-width: 767px) { #haut.rf-perdu .rf-sofia-scene { margin-top: var(--rf-e3); } }
.rf-perdu .rf-perdu-src { margin: var(--rf-e1) 0 var(--rf-e3); color: var(--ink-3); }
.rf-perdu .t-accroche { margin: 0; max-width: 42ch; }
.rf-perdu .rf-appels { margin-top: var(--rf-e2); }

/* ───── v537 · Les attentes de Sofia (.rf-attente, src/refonte/attente.js) : dix petites formes en 3D, une au hasard pendant qu'elle réfléchit.
   Au design system depuis le 21 octobre (DESIGN.md, Le site de vente). Encre du thème (currentColor, --line-strong), traits de 1,5 px, aucune lueur.
   --rf-attente-tour (au design system depuis le 21 octobre) : la durée d'un tour ; les --dur-* du système règlent les réponses (150 à 600 ms), pas les boucles.
   Mouvement réduit : rien ne tourne, chaque forme reste posée en 3D. ───── */
.rf-attente { --rf-attente-tour: 2.4s; display: inline-grid; place-items: center; width: 48px; height: 48px; perspective: 180px; color: var(--ink); vertical-align: middle; }
.rf-attente-scene, .rf-attente-pivot { position: relative; display: block; width: 30px; height: 30px; transform-style: preserve-3d; }
.rf-attente i, .rf-attente b { position: absolute; display: block; box-sizing: border-box; transform-style: preserve-3d; }
.rf-attente .anneau { inset: 0; border: 1.5px solid currentColor; border-radius: 50%; }
.rf-attente .pointille { border: 1px dashed var(--line-strong); }
.rf-attente .point { left: 50%; top: 50%; width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%; background: currentColor; }
.rf-attente .bras, .rf-attente .plan, .rf-attente .incline, .rf-attente .ext, .rf-attente .int { inset: 0; }
.rf-attente .bras .point { top: 0; }
.rf-attente .face { --demi: 15px; inset: 0; border: 1.5px solid currentColor; }
.rf-attente .face.petit { --demi: 7.5px; inset: 7.5px; }
.rf-attente .avant { transform: translateZ(var(--demi)); } .rf-attente .arriere { transform: rotateY(180deg) translateZ(var(--demi)); }
.rf-attente .gauche { transform: rotateY(-90deg) translateZ(var(--demi)); } .rf-attente .droite { transform: rotateY(90deg) translateZ(var(--demi)); }
.rf-attente .haut { transform: rotateX(90deg) translateZ(var(--demi)); } .rf-attente .bas { transform: rotateX(-90deg) translateZ(var(--demi)); }
.rf-attente .planete { left: 50%; top: 50%; width: 14px; height: 14px; margin: -7px 0 0 -7px; border: 1.5px solid currentColor; border-radius: 50%; background: linear-gradient(90deg, currentColor 50%, var(--paper-2) 50%); }
.rf-attente .planete.pleine { background: currentColor; }
/* les poses (immobiles) */
[data-forme="orbite"] .rf-attente-scene { transform: rotateZ(-22deg) rotateX(70deg); }
[data-forme="orbite"] .astre { left: 50%; top: 50%; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; background: currentColor; transform: rotateX(-70deg); }
[data-forme="gyroscope"] .rf-attente-scene { transform: rotateX(20deg) rotateZ(-15deg); }
[data-forme="gyroscope"] .anneau.a { transform: rotateX(90deg); } [data-forme="gyroscope"] .anneau.b { transform: rotateY(90deg); }
[data-forme="cube"] .rf-attente-scene, [data-forme="hypercube"] .rf-attente-scene { transform: rotateX(-22deg) rotateY(32deg); }
[data-forme="atome"] .rf-attente-scene { transform: rotateX(18deg); }
[data-forme="atome"] .plan { transform: rotateZ(var(--r)); } [data-forme="atome"] .incline { transform: rotateX(70deg); }
[data-forme="lune"] .rf-attente-scene { transform: rotateZ(-15deg); }
[data-forme="lune"] .incline { inset: -5px; transform: rotateX(74deg); }
[data-forme="helice"] .rf-attente-scene { transform: rotateX(10deg) rotateZ(-20deg); }
[data-forme="helice"] .barreau { left: 3px; right: 3px; top: calc(var(--k) * 4px + 1px); height: 1.5px; background: var(--line-strong); }
[data-forme="helice"] .point { top: 50%; width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px; } [data-forme="helice"] .point.g { left: 0; } [data-forme="helice"] .point.d { left: 100%; }
[data-forme="saturne"] .rf-attente-scene { transform: rotateZ(-20deg); }
[data-forme="saturne"] .incline { inset: -4px; transform: rotateX(76deg); } [data-forme="saturne"] .large { inset: -5px; }
[data-forme="onde"] .rf-attente-scene { transform: rotateX(58deg) rotateZ(45deg); }
[data-forme="onde"] .point { left: calc(var(--x) * 8px + 3px); top: calc(var(--y) * 8px + 3px); margin: 0; width: 4px; height: 4px; }
[data-forme="sphere"] .rf-attente-scene { transform: rotateX(-18deg); }
[data-forme="sphere"] .anneau { border-width: 1px; } [data-forme="sphere"] .meridien { transform: rotateY(var(--r)); } [data-forme="sphere"] .equateur { transform: rotateX(90deg); }
/* le mouvement */
@keyframes rf-att-z { to { transform: rotateZ(360deg); } }
@keyframes rf-att-y { to { transform: rotateY(360deg); } }
@keyframes rf-att-xy { from { transform: rotateX(0) rotateY(0); } to { transform: rotateX(360deg) rotateY(720deg); } }
@keyframes rf-att-yx { from { transform: rotateY(0) rotateX(0); } to { transform: rotateY(-360deg) rotateX(-360deg); } }
@keyframes rf-att-onde { 0%, 100% { transform: translateZ(0); } 50% { transform: translateZ(9px); } }
@media (prefers-reduced-motion: no-preference) {
  [data-forme="orbite"] .bras, [data-forme="lune"] .bras { animation: rf-att-z var(--rf-attente-tour) linear infinite; }
  [data-forme="gyroscope"] .rf-attente-pivot { animation: rf-att-xy calc(var(--rf-attente-tour) * 2) linear infinite; }
  [data-forme="cube"] .rf-attente-pivot { animation: rf-att-xy calc(var(--rf-attente-tour) * 2.5) linear infinite; }
  [data-forme="atome"] .bras { animation: rf-att-z calc(var(--rf-attente-tour) * .6) linear infinite; animation-delay: calc(var(--k) * var(--rf-attente-tour) * -.2); }
  [data-forme="hypercube"] .ext { animation: rf-att-xy calc(var(--rf-attente-tour) * 3) linear infinite; }
  [data-forme="hypercube"] .int { animation: rf-att-yx calc(var(--rf-attente-tour) * 1.5) linear infinite; }
  [data-forme="helice"] .barreau { animation: rf-att-y calc(var(--rf-attente-tour) * .8) linear infinite; animation-delay: calc(var(--k) * var(--rf-attente-tour) * -.08); }
  [data-forme="helice"] .point { animation: rf-att-y calc(var(--rf-attente-tour) * .8) linear infinite reverse; animation-delay: calc(var(--k) * var(--rf-attente-tour) * -.08); }   /* les points restent de face */
  [data-forme="saturne"] .pointille { animation: rf-att-z calc(var(--rf-attente-tour) * 2) linear infinite; } [data-forme="saturne"] .large { animation-direction: reverse; }
  [data-forme="onde"] .point { animation: rf-att-onde calc(var(--rf-attente-tour) * .6) ease-in-out infinite; animation-delay: calc((var(--x) + var(--y)) * var(--rf-attente-tour) * -.075); }
  [data-forme="sphere"] .rf-attente-pivot { animation: rf-att-y calc(var(--rf-attente-tour) * 1.5) linear infinite; }
}
/* dans le fil : la bulle de Sofia garde sa forme, un peu moins haute (placement seulement) */
.rf-bulle-conv.rf-bulle-attente { justify-self: start; padding: 2px 9px; line-height: 0; }
/* v537 : la page d'essai /essais/attente/ (placement seulement) */
.rf-att-revue { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: var(--rf-e2); margin: 0; padding: 0; list-style: none; }
.rf-ed-texte .rf-att-revue li { margin: 0; display: grid; justify-items: center; gap: 6px; padding: var(--rf-e1) 0; border-radius: var(--rf-r-petit); background: var(--paper-2); }

/* ───── v544 · Les schémas de Sofia (.rf-schema, src/refonte/schema.js) : sa partition dessinée au trait, à l'encre du thème, dans le fil.
   Au design system depuis le 21 octobre (DESIGN.md, Le site de vente). Unités du dessin : un carré de 1 000 (le moteur de placement du site). ───── */
.rf-conv-schema.rf-schema { justify-items: stretch; width: 88%; box-sizing: border-box; padding: var(--rf-e2); border-radius: var(--rf-r-petit); background: var(--paper-2); color: var(--ink); }
.rf-conv-schema.rf-vue { justify-items: stretch; width: 88%; box-sizing: border-box; gap: var(--rf-e1); padding: var(--rf-e2); border-radius: var(--rf-r-petit); background: var(--paper-2); color: var(--ink); }   /* v567 : la vue de Sofia, dans la même carte que ses schémas */
.rf-vue-titre { font-weight: 500; color: var(--ink); }   /* .t-petit, en 500 et à l'encre */
.rf-vue-tableau { width: 100%; border-collapse: collapse; }   /* le texte : .t-petit */
.rf-vue-tableau th, .rf-vue-tableau td { padding: 6px 12px 6px 0; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; color: var(--ink-2); }
.rf-vue-tableau thead th { font-weight: 500; color: var(--ink); border-bottom-color: var(--line-strong); }
.rf-vue-tableau tbody th { font-weight: 500; color: var(--ink); }
.rf-vue-etapes { margin: 0; padding: 0; list-style: none; counter-reset: vue; display: grid; gap: var(--rf-e1); }
.rf-vue-etapes li { display: grid; grid-template-columns: 24px 1fr; gap: 6px; counter-increment: vue; }   /* le texte : .t-petit */
.rf-vue-etapes li::before { content: counter(vue); font-family: var(--font-serif); font-style: italic; color: var(--rf-cuivre); }   /* le cuivre marque les numéros des étapes (adopté le 17 octobre) */
.rf-vue-barres { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--rf-e1); }
.rf-vue-barres li { display: grid; grid-template-columns: minmax(0, 9em) 1fr auto; align-items: center; gap: 12px; }   /* le texte : .t-petit */
.rf-vue-barre { height: 6px; border-radius: 999px; background: var(--line); position: relative; overflow: hidden; }
.rf-vue-barre::after { content: ""; position: absolute; inset: 0 auto 0 0; width: calc(var(--part, 0) * 100%); background: var(--ink); border-radius: inherit; }
.rf-vue-valeur { font-variant-numeric: tabular-nums; color: var(--ink); font-weight: 500; }
.rf-vue-calcul { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--rf-e1); }
.rf-vue-resultat { display: grid; gap: 0; margin: 0; padding-top: var(--rf-e1); border-top: 1px solid var(--line); }
.rf-vue-resultat .t-sous { font-variant-numeric: tabular-nums; }
.rf-vue-note { margin: 0; color: var(--ink-2); }   /* v633 : la mention des valeurs d'exemple de la calculette */
@media (max-width: 767px) { .rf-conv-schema.rf-vue { width: 100%; } .rf-vue-barres li { grid-template-columns: 1fr auto; } .rf-vue-barre { grid-column: 1 / -1; grid-row: 2; } }
.rf-schema-dessin { width: 100%; max-width: 420px; justify-self: center; } .rf-schema-dessin.large { max-width: none; }   /* v606 : un dessin à plat (une suite en ligne) prend toute la largeur de la carte */
.rf-schema-svg { display: block; width: 100%; height: auto; overflow: visible; }
.rf-sch-trame { fill: none; stroke: var(--line-strong); stroke-width: 3; } .rf-sch-trame.plein { fill: var(--line); }
.rf-sch-lien { fill: none; stroke: var(--ink-2); stroke-width: 4; } .rf-schema .tirets { stroke-dasharray: 12 12; }
.rf-sch-pointe { fill: var(--ink-2); }
.rf-sch-bulle { fill: var(--paper); stroke: var(--ink); stroke-width: 4; } .rf-sch-el.focus .rf-sch-bulle { stroke-width: 8; }
.rf-sch-icone { fill: none; stroke: var(--ink); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.rf-sch-nom, .rf-sch-legende, .rf-sch-etiquette { fill: var(--ink); font: 500 46px/1 var(--font-sans); text-anchor: middle; paint-order: stroke; stroke: var(--paper-2); stroke-width: 14px; stroke-linejoin: round; }
.rf-sch-legende, .rf-sch-etiquette { fill: var(--ink-2); font-weight: 400; }
.rf-schema-temps { display: grid; gap: 6px; margin: 0; padding-left: 1.4em; color: var(--ink-2); }
.rf-schema-temps li { margin: 0; } .rf-schema-temps li.on { color: var(--ink); }
.rf-schema-revoir { justify-self: start; }
@keyframes rf-sch-entree { from { opacity: 0; } }
@media (prefers-reduced-motion: no-preference) { .rf-schema .neuf { animation: rf-sch-entree var(--dur-reveal) var(--ease-out) both; } }

