/* ── 00-base.css (système) ── */
/* ───── Système Tournaire, appliqué au site three.js (6 octobre 2026) ─────
   Papier blanc ou nuit, trois encres, des filets ; Outfit pour tout, Playfair Display italique pour le mot mis en valeur.
   Trois tempos : ce qui respire (lent), ce qui répond (150 à 300 ms), ce qui voyage (≈ 1 s, la matière seule).
   Thème selon l'appareil ; le bouton le force (data-theme).
   8 octobre, 10 h 40 : les jetons portent les noms du Système Tournaire (paper, paper-2, font-sans, font-serif, dur-respond, ease-out, shadow-float). */
:root {
  --paper: #ffffff; --paper-rgb: 255, 255, 255;
  --ink: #0b1116; --ink-rgb: 11, 17, 22; --ink-2: #3d4a53; --ink-3: #5b6872;
  --sig-red: #c0262d; --sig-green: #1a7a3c;
  --line: rgba(11, 17, 22, .14); --line-strong: rgba(11, 17, 22, .34);
  --paper-2: #f3f5f7; --field-hover: #f3f5f7;
  --on-ink: #ffffff; --shadow-float: 0 18px 50px rgba(12, 19, 24, .16);
  --font-sans: "Outfit", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-serif: "Playfair Display", "Iowan Old Style", Georgia, serif;
  --dur-respond: 200ms; --ease-out: cubic-bezier(.2, .7, .2, 1);
  /* 10 octobre (ménage, design system) : les durées du système (celles de l'artefact Design System, plus --dur-trace pour les
     filets qui se dessinent et les petits fondus à 300 ms) ; les commandes posées sur une image (voile et encre) */
  --dur-magnet: 160ms; --dur-open: 250ms; --dur-trace: 300ms; --dur-plan: 420ms; --dur-fade: 500ms; --dur-eclipse: 560ms; --dur-reveal: 600ms;
  --scrim: rgba(0, 0, 0, .42); --on-scrim: #fff;
  /* v502 (Raphaël, 20 octobre : jeton du système) : le cuivre de Sofia pour les petits repères de l'interface (point final des titres,
     rubrique en cours, numéros d'étapes) ; jamais un fond, un bouton ou un long texte. Jour #a45f27 (4,95:1 sur papier), nuit #dd9a5e.
     Il suit le thème, pas la zone de nuit (comme avant, quand il vivait dans refonte.css). */
  --rf-cuivre: #a45f27;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #06080d; --paper-rgb: 6, 8, 13; --ink: #edf2f6; --ink-rgb: 237, 242, 246; --ink-2: #b9c5ce; --ink-3: #8e9caa; --sig-red: #ff7a7a; --sig-green: #5fd98b;
    --line: rgba(237, 242, 246, .16); --line-strong: rgba(237, 242, 246, .40);
    --paper-2: #0f141b; --field-hover: #0f141b; --on-ink: #06080d; --shadow-float: 0 18px 50px rgba(0, 0, 0, .55);
    --rf-cuivre: #dd9a5e;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] { --rf-cuivre: #dd9a5e; }   /* v502 : le cuivre de nuit, hors de la zone de nuit (voir plus haut) */
:root[data-theme="dark"],
/* 11 octobre (portfolio, à proposer au design system) : la zone nuit, un bloc posé sur une image sous le voile : il prend les jetons
   de nuit quel que soit le thème, pour que l'encre y reste claire (la roue des marques, 895-portfolio-roue.js).
   18 octobre (v488) : même jeu pour data-fond="nuit" (les écrans et cartes de nuit de /refonte), au lieu d'une copie des valeurs là-bas. */
.zone-nuit, [data-fond="nuit"] {
  --paper: #06080d; --paper-rgb: 6, 8, 13; --ink: #edf2f6; --ink-rgb: 237, 242, 246; --ink-2: #b9c5ce; --ink-3: #8e9caa; --sig-red: #ff7a7a; --sig-green: #5fd98b;
  --line: rgba(237, 242, 246, .16); --line-strong: rgba(237, 242, 246, .40);
  --paper-2: #0f141b; --field-hover: #0f141b; --on-ink: #06080d; --shadow-float: 0 18px 50px rgba(0, 0, 0, .55);
  --glass: rgba(var(--paper-rgb), .9); --glass-texte: rgba(var(--paper-rgb), .5);   /* v489 : le verre se recalcule sur le papier de nuit (sinon il garde celui du thème : sous-menu clair sous une encre claire) */
  color-scheme: dark;
}
.zone-nuit { color: var(--ink); }
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--font-sans); -webkit-font-smoothing: antialiased; }
body { overflow-x: hidden; }
button { font: inherit; color: inherit; cursor: pointer; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* le fond (peint par le script) sous le texte ; Sofia au-dessus de tout le contenu, sans capter le pointeur */
#bgfx { position: fixed; inset: 0; z-index: 0; background: var(--paper); }
#bgfx::after { content: ""; position: absolute; inset: 0; background: #000; opacity: var(--night, 1); }
#gl { position: fixed; inset: 0; width: 100%; height: 100%; display: block; z-index: 6; pointer-events: none; }
/* le noir de l'arrivée : la page apparaît quand la lumière est venue sur Sofia */
.ui { position: relative; z-index: 2; transition: opacity 900ms ease; }
.intro .ui { opacity: 0; }
/* en-tête : le nom à gauche ; le thème et « Le contacter » à droite */
.top { position: fixed; z-index: 5; top: 0; left: 0; right: 0; display: flex; align-items: center; justify-content: space-between; padding: 1.5rem var(--m); pointer-events: none; }
.top > * { pointer-events: auto; }
/* le nom (15 h 23) : en capitales, très espacé, « plus établi, plus statutaire » */
.brand { background: none; border: 0; padding: .75rem 0; font: 500 .7812rem/1.25 var(--font-sans); letter-spacing: .34em; text-transform: uppercase; text-align: left; }
/* le logo carré (11 octobre, Design System, fiche Logo) : RAPH / AELT / OURN / AIRE en vecteur (tools/logo-carre.py),
   48 px de haut, à la couleur du texte ; défini une fois, la roue des marques le pose à gauche (variante de place). */
.brand-carre { display: block; height: 3rem; aspect-ratio: 57.608 / 55.86; color: var(--ink); }
.brand-carre svg { display: block; width: 100%; height: 100%; }
/* 14 h 13 (Raphaël) : « applique le logo partout comme un logo » : l'en-tête montre le logo à toutes les largeurs ; le nom en
   toutes lettres reste pour les lecteurs d'écran (aria-label du bouton) */
.brand { display: inline-flex; align-items: center; min-width: 2.75rem; min-height: 2.75rem; padding: 0; }
.brand .brand-nom { display: none; }

.acts { display: flex; gap: .75rem; align-items: center; }
/* le thème (22 h 24 ; 7 octobre, 8 h 54 : sans le contour de la pilule) : le soleil (cercle plein) derrière la planète (cercle vide). En clair, il en sort à 60 %
   (centres écartés de 10,3 px, vers le haut à gauche) ; en sombre, il passe derrière. Au survol, il amorce le geste. */
.theme-btn { width: 3rem; height: 2.75rem; display: inline-grid; place-items: center; flex: none; padding: 0; border: 0; border-radius: var(--r-pill); background: transparent; color: var(--ink); cursor: pointer; transition: border-color var(--dur-respond) ease; }
.theme-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.theme-btn svg { display: block; overflow: visible; }
.theme-btn .sun { fill: currentColor; transform: translate(-8.4px, -5.9px); transition: transform var(--dur-eclipse) var(--ease-out); }
.theme-btn .planet { fill: var(--paper); stroke: currentColor; stroke-width: 1.6; }
/* 23 h 04 : en nuit, le soleil caché fait une couronne derrière la planète (une éclipse) ; elle s'allume quand il a fini de passer */
.theme-btn .corona { fill: none; stroke: currentColor; stroke-width: 2.6; opacity: 0; transition: opacity var(--dur-trace) ease; }
:root[data-theme="dark"] .theme-btn .corona { opacity: .75; transition: opacity var(--dur-reveal) ease 380ms; }
:root[data-theme="dark"] .theme-btn:hover .corona { opacity: .45; transition-delay: 0s; }
.theme-btn:hover .sun { transform: translate(-6.9px, -4.8px); }
:root[data-theme="dark"] .theme-btn .sun { transform: translate(0, 0); }
:root[data-theme="dark"] .theme-btn:hover .sun { transform: translate(-2.4px, -1.7px); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-btn .sun { transform: translate(0, 0); }
  :root:not([data-theme="light"]) .theme-btn:hover .sun { transform: translate(-2.4px, -1.7px); }
  :root:not([data-theme="light"]) .theme-btn .corona { opacity: .75; transition: opacity var(--dur-reveal) ease 380ms; }
  :root:not([data-theme="light"]) .theme-btn:hover .corona { opacity: .45; transition-delay: 0s; }
}
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; } }


/* ── 10-composants.css (système) ── */
/* ───── Composants du système : repère, boutons, lien, champ ───── */
/* le repère : 11 px, capitales espacées, un filet, un mot fort */
.micro { margin: 0; display: flex; align-items: center; gap: .75rem; }

.micro .sep { width: 1.125rem; height: 1px; background: var(--line-strong); }
/* bouton plein, et bouton au trait (comme « Get started » chez Flareum) */
.btn-pill, .btn-out { min-height: 3rem; display: inline-flex; align-items: center; justify-content: center; gap: .75rem; padding: 0 1.875rem; border: 1px solid var(--ink); border-radius: var(--r-pill); font: 500 var(--fs-button)/1 var(--font-sans); letter-spacing: 0; text-transform: none; white-space: nowrap; transition: background-color var(--dur-respond), color var(--dur-respond), border-color var(--dur-respond); }
.btn-pill { background: var(--ink); color: var(--on-ink); }
.btn-pill:hover { background: transparent; color: var(--ink); }
.btn-out { background: transparent; color: var(--ink); border-color: var(--line-strong); }
a.btn-out, a.btn-pill, a.link-btn { text-decoration: none; } /* 22 h 16 : un lien habillé en bouton n'a pas de soulignement */
.btn-out:hover, .icon-btn:hover { background: var(--ink); color: var(--on-ink); border-color: var(--ink); } /* le survol « encre pleine », une seule règle (ménage du 10 octobre) */
.btn-pill.big, .btn-out.big { min-height: 3.5rem; padding: 0 1.875rem; }   /* 17 octobre (Raphaël) : les boutons parlent en 15 px minuscules, toutes tailles */
.btn-out.sm, .btn-pill.sm { min-height: 2.75rem; padding: 0 1.5rem; }
.btn-pill small, .btn-out small { font: 500 var(--fs-mark)/1 var(--font-sans); letter-spacing: .04em; text-transform: none; opacity: .72; }
/* bouton rond : un cercle au trait de 1 px */
.icon-btn { width: 2.75rem; height: 2.75rem; display: inline-grid; place-items: center; flex: none; padding: 0; border: 1px solid var(--line-strong); border-radius: var(--r-pill); background: transparent; color: var(--ink); transition: background-color var(--dur-respond), color var(--dur-respond), border-color var(--dur-respond); }
/* v355 (16 octobre) : le bouton d'envoi n'a plus sa taille à part (40 px) : il a celle du bouton rond, 44 px, la cible minimale */
/* lien : souligné qui se dessine */
.link-btn { min-height: 2.75rem; display: inline-flex; align-items: center; gap: .375rem; padding: 0 2px; border: 0; background: none; font: 500 .875rem/1 var(--font-sans); color: var(--ink-2); white-space: nowrap; transition: color var(--dur-respond); }
.link-btn:hover { color: var(--ink); }
.link-btn svg { transition: transform var(--dur-respond); }
.link-btn:hover svg { transform: translateY(2px); }

/* ───── Le curseur et les boutons aimantés (souris seulement ; moins de mouvement : le point reste, rien ne se déplace) ───── */
html.curseur, html.curseur * { cursor: none !important; }
#cur { position: fixed; left: 0; top: 0; z-index: 9999; width: .625rem; height: .625rem; margin: -.375rem 0 0 -.375rem; border-radius: 50%; background: #fff; mix-blend-mode: difference; pointer-events: none; opacity: 0; transition: opacity var(--dur-respond) ease, width 240ms var(--ease-out), height 240ms var(--ease-out), margin 240ms var(--ease-out), scale 150ms ease; will-change: translate; }
#cur.in { opacity: 1; }
#cur.in.gone { opacity: 0; }
#cur.big { width: 1.875rem; height: 1.875rem; margin: -.75rem 0 0 -.75rem; }
/* sur l'indice de défilement (rendu de Raphaël, 15 h 18) : le curseur devient un anneau fin, un peu plus grand que la souris
   dessinée ; dedans, le trait gras et la molette */
#cur.lens { width: 2.75rem; height: 2.75rem; margin: -1.5rem 0 0 -1.5rem; background: transparent; mix-blend-mode: normal; box-shadow: inset 0 0 0 1.5px var(--ink); }
#cur.caret { width: 2px; height: 1.625rem; margin: -.75rem 0 0 -1px; border-radius: 2px; }
#cur.down { scale: .7; }
.curseur :is(.btn-pill, .btn-out) { position: relative; }
/* bouton plein : un rond blanc suit le pointeur et inverse le texte (le jour, le bouton reste plein ; la nuit, il se vide) */
.curseur .btn-pill { overflow: hidden; isolation: isolate; }
.curseur .btn-pill:hover { background: var(--ink); border-color: var(--ink); color: var(--on-ink); }
html.curseur[data-theme="dark"] .btn-pill:hover { background: transparent; border-color: var(--ink); color: var(--ink); }
@media (prefers-color-scheme: dark) { html.curseur:not([data-theme="light"]) .btn-pill:hover { background: transparent; border-color: var(--ink); color: var(--ink); } }
/* 18 octobre (v491) : dans une zone de nuit (.zone-nuit, data-fond="nuit"), même règle que la nuit, sinon le rond (blanc en différence) sort brun sur l'encre claire */
.curseur :is(.zone-nuit, [data-fond="nuit"]) .btn-pill:hover { background: transparent; border-color: var(--ink); color: var(--ink); }
.curseur .btn-out:hover { background: transparent; color: var(--ink); }
.disc { position: absolute; left: var(--dx, 50%); top: var(--dy, 50%); width: 0; height: 0; border-radius: var(--r-pill); background: #fff; mix-blend-mode: difference; pointer-events: none; transform: translate(-50%, -50%); transition: width var(--dur-trace) var(--ease-out), height var(--dur-trace) var(--ease-out); }
.disc-on > .disc { width: 7.5rem; height: 7.5rem; }
/* bouton au trait : le contour se resserre et devient le rond ; le texte et l'icône s'inversent exactement sous lui */
@property --px { syntax: '<length>'; inherits: true; initial-value: 0px; }
@property --py { syntax: '<length>'; inherits: true; initial-value: 0px; }
@property --rr { syntax: '<length>'; inherits: true; initial-value: 0px; }
.curseur .ol { isolation: isolate; transition: --px var(--dur-trace) var(--ease-out), --py var(--dur-trace) var(--ease-out), --rr var(--dur-trace) var(--ease-out), border-color 0s linear var(--dur-trace), background-color 0s linear var(--dur-trace), color var(--dur-respond); }
.curseur .ol.disc-on { border-color: transparent; background: transparent; --rr: calc(var(--dd) / 2); transition: --px 260ms var(--ease-out), --py 260ms var(--ease-out), --rr var(--dur-trace) var(--ease-out), border-color 0s, background-color 0s, color var(--dur-respond); }
.ol > .lbl { display: inline-flex; align-items: center; gap: inherit; }
.ol > .lbl2 { position: absolute; left: var(--ox, 0px); top: var(--oy, 0px); z-index: 1; color: var(--paper); white-space: nowrap; pointer-events: none; clip-path: circle(var(--rr) at calc(var(--px) - var(--ox, 0px)) calc(var(--py) - var(--oy, 0px))); }
.ol:not(.disc-on) > .lbl2 { visibility: hidden; transition: visibility 0s linear var(--dur-trace); }
.ol > .disc { z-index: -1; left: var(--px); top: var(--py); width: var(--bw); height: var(--bh); background: transparent; border: 1px solid var(--ink); mix-blend-mode: normal; opacity: 0; transition: width var(--dur-trace) var(--ease-out), height var(--dur-trace) var(--ease-out), background-color 220ms ease, opacity 0s linear var(--dur-trace); }
.ol.disc-on > .disc { width: var(--dd); height: var(--dd); background: var(--ink); opacity: 1; transition: width var(--dur-trace) var(--ease-out), height var(--dur-trace) var(--ease-out), background-color var(--dur-respond) ease 60ms, opacity 0s; }
.ol.disc-on > .disc.from { width: var(--bw); height: var(--bh); background: transparent; }
/* bouton rond : aimanté ; un fond arrive du point de rencontre avec le pointeur et gagne le centre */
.curseur .icon-btn { position: relative; overflow: hidden; isolation: isolate; transition: color 220ms ease, border-color 220ms ease; }
.curseur .icon-btn:hover { background: transparent; }
.curseur .icon-btn > svg { position: relative; z-index: 1; }
.curseur .icon-btn.mg-on { border-color: var(--ink); color: var(--paper); }
.mg-fill { position: absolute; left: 50%; top: 50%; z-index: 0; width: 0; height: 0; border-radius: 50%; background: var(--ink); pointer-events: none; transform: translate(-50%, -50%); transition: left 260ms var(--ease-out), top 260ms var(--ease-out), width 260ms var(--ease-out), height 260ms var(--ease-out); }
.mg-fill.on { width: calc(100% + 2px); height: calc(100% + 2px); }
/* le champ de Sofia : sa ligne s'encre à partir du point de rencontre */
.ask::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: var(--ink); transform: scaleX(0); transform-origin: var(--lx, 50%) 50%; transition: transform var(--dur-trace) var(--ease-out); }
.ask.hov::after, .ask:focus-within::after { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) { #cur, .disc, .ol > .disc, .ol.disc-on > .disc, .mg-fill, .curseur .icon-btn { transition: opacity 150ms ease; } }

/* le panneau de réglages (outil de travail) : aux couleurs du site */
.lil-gui.root.reglages { position: fixed; top: 5rem; right: var(--m); z-index: 9; max-height: calc(100svh - 6.25rem); overflow-y: auto; border: 1px solid var(--line); border-radius: var(--r-card); }
/* lil-gui redonne ses couleurs à chaque dossier : on les impose aussi aux dossiers */
.lil-gui.reglages, .reglages .lil-gui {
  --background-color: rgba(var(--paper-rgb), .9); --text-color: var(--ink); --title-background-color: transparent; --title-text-color: var(--ink);
  --widget-color: var(--paper-2); --hover-color: var(--field-hover); --focus-color: var(--line-strong); --number-color: var(--ink-2); --string-color: var(--ink);
  --font-family: var(--font-sans); --font-size: 12px; --input-font-size: 12px; --widget-height: 22px; --name-width: 48%;
}
.reglages .lil-gui { --background-color: transparent; }
.lil-gui.root.reglages { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); box-shadow: var(--shadow-float); }
.lil-gui.root.reglages .title { font-weight: 600; letter-spacing: .02em; }
/* 12 octobre, 23 h 53 : le panneau se déplace par sa barre de titre (920-reglages.js) : la main « attraper », et le doigt ne fait pas défiler la page */
.lil-gui.root.reglages > .title { cursor: grab; touch-action: none; }
.lil-gui.root.reglages.deplace > .title { cursor: grabbing; }
.lil-gui.root.reglages .controller.function button .name { font-weight: 500; }
@media (max-width: 760px) { .lil-gui.root.reglages { top: 4.5rem; right: .75rem; left: .75rem; width: auto !important; max-height: 58svh; } }

/* ───── La boîte « Sofia » (7 octobre) : Journal (dans l'article) et FAQ (en secours, sous les questions) ─────
   Le petit portrait de Sofia au trait, une phrase, son champ, des questions toutes prêtes (380-sofia-boite.js). */
.sofia-box { display: flex; gap: 1.125rem; align-items: flex-start; padding: 1.5rem 1.5rem 1.5rem; border: 1px solid var(--line-strong); border-radius: var(--r-panel); text-align: left; }
.sb-face { flex: none; width: 3.5rem; height: 3.5rem; overflow: visible; }
.sb-face .gl { fill: var(--ink); fill-opacity: .06; stroke: var(--ink-2); stroke-width: 1.2; }
.sb-face .dr { fill: var(--ink-3); }
/* v233 : le petit soleil (manifeste du 13 octobre) au trait : le cœur plein, deux franges de plasma qui ondulent et tournent lentement en sens contraire, le reflet du verre, des étincelles */
.sb-face .co { fill: var(--ink); }
.sb-face .pl { fill: none; stroke: var(--ink); stroke-width: 1.2; stroke-linejoin: round; transform-box: view-box; transform-origin: 50% 50%; animation: sb-plasma 24s linear infinite; }
.sb-face .pl2 { fill: none; stroke: var(--ink-3); stroke-width: 1; stroke-linejoin: round; transform-box: view-box; transform-origin: 50% 50%; animation: sb-plasma 36s linear infinite reverse; }
.sb-face .rf { fill: none; stroke: var(--ink-3); stroke-width: 1.2; stroke-linecap: round; }
@keyframes sb-plasma { to { transform: rotate(1turn); } }
.sb-in { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .75rem; }


.sofia-box .sb-t { margin: 0; max-width: none; font: 500 clamp(1.05rem, 1.4vw, 1.2rem)/1.4 var(--font-sans); color: var(--ink); text-wrap: balance; }
.sb-f { margin-top: 2px; }
.sb-chips { display: flex; flex-wrap: wrap; gap: .375rem; margin-top: .375rem; }

 /* 16 h 37 : sous le curseur, la puce fait comme les autres boutons (le contour devient le rond) */
@media (max-width: 760px) { .sofia-box { flex-direction: column; gap: .75rem; padding: 1.125rem 1.125rem 1.125rem; } .sb-face { width: 2.875rem; height: 2.875rem; } }
@media (prefers-reduced-motion: reduce) { .sb-face .pl, .sb-face .pl2 { animation: none; } }

/* la grille de vérification (940-grille.js) : au-dessus de tout, sauf le curseur ; ne capte rien */
.dev-grid { position: fixed; inset: 0; z-index: 9000; pointer-events: none; display: none; }
.dev-grid.on { display: block; }
.dg-lines { position: absolute; inset: 0; background-image: linear-gradient(to bottom, rgba(214, 40, 57, .34) 0 1px, transparent 1px), linear-gradient(to bottom, rgba(214, 40, 57, .07) 0 1px, transparent 1px); background-size: 100% var(--dg-b, 30px), 100% var(--dg-s, 6px); }
.dg-cols { position: absolute; top: 0; bottom: 0; left: 50%; translate: -50% 0; display: grid; }
.dg-cols i { background: rgba(40, 110, 214, .07); border-inline: 1px solid rgba(40, 110, 214, .3); }
.dg-lab { position: absolute; left: .5rem; bottom: .5rem; padding: .375rem .375rem; border-radius: var(--r-cell); background: rgba(var(--paper-rgb), .92); color: var(--ink); font: 400 var(--fs-mark)/1.3 var(--font-mono); }

/* ───── L'arrivée (v138 à v140 ; au design system, fiche Arrivee, depuis le 10 octobre au soir) ─────
   Sur le noir de l'arrivée (le même noir que #bgfx), tout est en encre sur voile (--on-scrim). La lumière : un dégradé
   radial centré un peu au-dessus de Sofia, qu'un disque noir (Sofia) cache à l'intérieur. Sous la toile three.js (#gl, 6)
   et au-dessus de la page (.ui, 2) : Sofia en verre passe devant la lumière. */
.arrivee { position: fixed; inset: 0; z-index: 4; pointer-events: none; }
.arrivee svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.arrivee .arr-soleil { opacity: 0; }
.arrivee .arr-disque { fill: #000; } /* le noir de l'arrivée (#bgfx::after) */
.arrivee .arr-s0 { stop-color: var(--on-scrim); stop-opacity: 1; }
.arrivee .arr-s1 { stop-color: var(--on-scrim); }
.arrivee .arr-s2 { stop-color: var(--on-scrim); stop-opacity: 0; }
.arrivee .arr-l { position: absolute; left: 0; top: 0; display: block; overflow: visible; color: var(--on-scrim); opacity: 0; will-change: transform, opacity, filter; } /* 11 octobre : les lettres du logo, en SVG */
/* v140 : en mode clair, l'arrivée en négatif : fond et disque du blanc de la page, lueur, nom et yeux en noir */
.arr-clair #bgfx::after, .arr-clair .arrivee .arr-disque { background: var(--paper); fill: var(--paper); }
.arr-clair .arrivee .arr-l { color: #000; }
.arr-clair .arrivee .arr-s0, .arr-clair .arrivee .arr-s1, .arr-clair .arrivee .arr-s2 { stop-color: #000; }
@media (prefers-reduced-motion: reduce) { .arrivee { display: none; } }

/* ── La pilule de verre (11 octobre, 13 h 46, Raphaël : « la pill en liquid glass ») — nouvelle, à proposer au design system ──
   Pour un nom posé sur une image sous voile (la roue des marques du portfolio). Une approximation web du verre liquide : flou et
   saturation du fond (--glass-blur), un voile clair qui descend, un reflet net en haut et un plus doux en bas, un contour fin,
   une ombre portée courte. Tout vient des jetons (--on-scrim, --scrim, --r-pill, --fs-note, --dur-respond) ; la taille est celle
   de la puce M (42 px, 13,5 px). Survol : le contour et le reflet s'éclairent, la pilule monte de 2 px. Transparence réduite :
   un fond plein. Les gouttes de verre restent à Sofia : ici, le verre est plat, sans goutte. */
.pilule-verre { position: relative; display: inline-flex; align-items: center; gap: .375rem; min-height: 2.625rem; padding: 0 1.125rem; border: 1px solid color-mix(in srgb, var(--on-scrim) 24%, transparent); border-radius: var(--r-pill);
  background: linear-gradient(180deg, color-mix(in srgb, var(--on-scrim) 16%, transparent), color-mix(in srgb, var(--on-scrim) 4%, transparent));
  backdrop-filter: var(--glass-blur) saturate(1.6); -webkit-backdrop-filter: var(--glass-blur) saturate(1.6);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--on-scrim) 42%, transparent), inset 0 -1px 0 color-mix(in srgb, var(--on-scrim) 10%, transparent), 0 .375rem 1.125rem color-mix(in srgb, var(--scrim) 60%, transparent);
  color: var(--on-scrim); font: 500 var(--fs-note)/1.2 var(--font-sans); letter-spacing: 0; text-transform: none; white-space: nowrap; cursor: pointer;
  transition: border-color var(--dur-respond) ease, box-shadow var(--dur-respond) ease, translate 260ms var(--ease-out); }
.pilule-verre::after { content: ""; position: absolute; inset: calc(-1 * var(--sl)) 0; } /* zone de clic : 54 px */
.pilule-verre:hover { border-color: color-mix(in srgb, var(--on-scrim) 48%, transparent); box-shadow: inset 0 1px 0 color-mix(in srgb, var(--on-scrim) 64%, transparent), inset 0 -1px 0 color-mix(in srgb, var(--on-scrim) 16%, transparent), 0 .375rem 1.125rem color-mix(in srgb, var(--scrim) 60%, transparent); translate: 0 -2px; }
.pilule-verre:active { translate: 0 0; }
.pilule-verre:focus-visible { outline: 2px solid var(--on-scrim); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .pilule-verre:hover { translate: 0 0; } }
@media (prefers-reduced-transparency: reduce) { .pilule-verre { background: var(--scrim); backdrop-filter: none; -webkit-backdrop-filter: none; } }

/* ── 99-systeme.css (système) ── */
/* ───── Le système, appliqué au site (8 octobre, 13 h — choix de Raphaël sur l'audit des styles v2) ─────
   Un seul endroit par objet : les classes du site qui jouent le même rôle sont regroupées ici, en unités relatives
   (rem, em, clamp), calées sur la sous-ligne de 6 px (.375rem) et la ligne de base de 30 px (1.875rem).
   Ce fichier passe en dernier : à spécificité égale, il l'emporte sur les anciennes règles (qui ne gardent que la mise en place).
   Ce qui ne change pas, à la demande de Raphaël : les boutons CTA (plein, au trait), les boutons ronds, la souris de défilement,
   leurs survols et le rond qui suit le curseur. */
:root {
  --sl: .375rem; --bl: 1.875rem;
  --r-cell: .5rem; --r-card: .875rem; --r-panel: 1.25rem; --r-pill: 999px;
  --fs-data: .75rem; --fs-label: .75rem; --fs-mark: .75rem; --fs-tab: .75rem;   /* 18 octobre (Raphaël, audit : « passe tout en 12 px mini ») : plus rien sous 12 px ; avant : 9,5 / 10,5 / 11 / 11,5 px */
  --fs-note: .84375rem; --fs-button: .9375rem;   /* 17 octobre (Raphaël) : le libellé des boutons, 15 px, minuscules */
   --fs-text: clamp(.875rem, .8rem + .3vw, .9375rem); --fs-lead: 1.0625rem;
  --lh-s: 1.125rem; --lh-m: 1.5rem; --lh-l: 1.875rem;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --hit: 2.75rem;
  --glass: rgba(var(--paper-rgb), .9); --glass-blur: blur(.75rem);
  --glass-texte: rgba(var(--paper-rgb), .5); --glass-texte-blur: blur(.375rem);   /* 17 octobre (Raphaël) : le verre derrière un texte posé sur une maquette, plus léger */
  --glass-deep: rgba(var(--paper-rgb), .64); --glass-deep-blur: blur(1.625rem) saturate(1.1);
  --hatch: repeating-linear-gradient(135deg, transparent 0 .6875rem, var(--line) .6875rem .75rem);
}
@media (pointer: coarse) { :root { --hit: 3rem; } }

/* ── La grille (8 octobre, 12 h 51 : « on va aligner le site dessus ») ──
   Téléphone : 4 colonnes, gouttière et marge de 3 sous-lignes. Tablette (dès 761 px, comme la mise en page du site) : 8 colonnes,
   gouttière 4, marge 10 (la navigation tient dans la marge). Ordinateur (dès 1024 px) : 12 colonnes de 72 px au plus, gouttière 5,
   marge d'au moins 12 sous-lignes. --m (la marge du site) est la marge de la grille ; --s6 … --s12 : la largeur de 6 à 12 colonnes. */
:root { --g-cols: 4; --g-gut: 1.125rem; --m: 1.125rem; }
@media (min-width: 761px) { :root { --g-cols: 8; --g-gut: 1.5rem; --m: 3.75rem; } }
@media (min-width: 1024px) { :root { --g-cols: 12; --g-gut: 1.875rem; --m: max(4.5rem, (100vw - 74.625rem) / 2); } }
:root {
  --col: calc((100vw - 2 * var(--m) - (var(--g-cols) - 1) * var(--g-gut)) / var(--g-cols));
  --s4: calc(min(4, var(--g-cols)) * var(--col) + (min(4, var(--g-cols)) - 1) * var(--g-gut));
  --s6: calc(min(6, var(--g-cols)) * var(--col) + (min(6, var(--g-cols)) - 1) * var(--g-gut));
  --s8: calc(min(8, var(--g-cols)) * var(--col) + (min(8, var(--g-cols)) - 1) * var(--g-gut));
  --s10: calc(min(10, var(--g-cols)) * var(--col) + (min(10, var(--g-cols)) - 1) * var(--g-gut));
  --s12: calc(var(--g-cols) * var(--col) + (var(--g-cols) - 1) * var(--g-gut));
}
[tabindex="-1"]:focus { outline: none; }

/* ── Titres : Display, Title, Title-s, Heading ; une seule règle pour le mot en italique ── */
h1, .dj-txt h3 { font-family: var(--font-sans); font-weight: 600; font-size: clamp(2rem, .6rem + 3.6vw, 4.125rem); line-height: 1.02; line-height: round(up, 1.02em, var(--sl)); letter-spacing: -.035em; }
.chap h2, .sec h2, .rub h2, .fin h2, .jr-cta h2, .jr-h1, .faqs-head h2 { font-family: var(--font-sans); font-weight: 600; font-size: clamp(1.5rem, .4rem + 3.2vw, 3.375rem); line-height: 1.04; line-height: round(up, 1.04em, var(--sl)); letter-spacing: -.035em; }
.focus h3, .esp-h, .gal-head h2, .jr-text h2, .c-txt h3, .pfl-it h3 { font-family: var(--font-sans); font-weight: 600; font-size: clamp(1.375rem, 1rem + 1.2vw, 2.125rem); line-height: 1.1; line-height: round(up, 1.1em, var(--sl)); letter-spacing: -.025em; }
.jr-card h3, .jr-text h3, .plan h3, .fm-card h4, .faq-owner h3, .gal-meta h3, .sl-sofia h5, .xl-mini { font-family: var(--font-sans); font-weight: 600; font-size: clamp(1rem, .9rem + .35vw, 1.1875rem); line-height: 1.3; line-height: round(up, 1.3em, var(--sl)); letter-spacing: -.012em; }
/* Ouverture (10 octobre, audit Flareum, sur test — style nouveau, à valider avant d'entrer au système) : la phrase qui ouvre
   une rubrique, plus grande que Display (environ 88 px à 1440 au lieu de 61), un cran plus légère (500), le mot en italique gardé.
   La phrase de Parlons-en reste en Title : en plus grand, elle passerait sous Sofia. */
.xp-intro h2, .rub-head h2, .xl-big { font-family: var(--font-sans); font-weight: 500; font-size: clamp(2.125rem, .9rem + 5.25vw, 5.75rem); line-height: 1.02; line-height: round(up, 1.02em, var(--sl)); letter-spacing: -.04em; }

:is(h1, .dj-txt h3, .chap h2, .sec h2, .rub h2, .fin h2, .jr-cta h2, .jr-h1, .xp-intro h2, .focus h3, .esp-h, .gal-head h2, .jr-text h2, .c-txt h3) em { font: italic 400 1.04em/1 var(--font-serif); letter-spacing: -.01em; }
/* ── Ouverture de rubrique (10 octobre, audit Flareum, sur test) : la phrase de la rubrique au style Display (ci-dessus),
   révélée mot à mot (700-ouvertures.js) ; le détail attend la fin de la phrase (.ouv-wait), puis arrive en fondu. ── */
.ouv-w { will-change: opacity; }
:is(.xp-intro, .rub-head, .fin .hero-text) :is(.lead, .xp-toc, .sig, .fin-sub, .cta) { transition: opacity calc(2 * var(--dur-respond)) var(--ease-out); }
:is(.xp-intro, .rub-head, .fin .hero-text).ouv-wait :is(.lead, .xp-toc, .sig, .fin-sub, .cta) { opacity: 0; }

/* ── Texte : note, texte, lead (l'article du Journal prend « texte », choix PA-09) ── */
.note, .tbl-fiche p, .gal-meta p, .faq-owner > p, .esp-mail p, .fm-proto span, .sl-sofia p { font: 400 var(--fs-note)/var(--lh-s) var(--font-sans); color: var(--ink-2); }
.sub, .plan p, .c-txt > p, .pfl-what, .pts span, .items span, .fm-prins span, .esp-cta p, .jr-ctx p, .jr-sources p, .focus p, .acc-body > p, .acc-body .groups p, .jr-text p, .jr-text li { font: 400 var(--fs-text)/var(--lh-m) var(--font-sans); color: var(--ink-2); }
.lead, .dj-txt > p { font: 400 clamp(1rem, .95rem + .25vw, var(--fs-lead))/var(--lh-m) var(--font-sans); color: var(--ink-2); }

/* ── Petits libellés : Repère, Label, Donnée ── */
.micro { font: 500 var(--fs-mark)/var(--lh-s) var(--font-sans); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.micro b { font-weight: 500; color: var(--ink); }
.wl, .lost-code, .dj-card span, .soon, .rt-h, .facts dt, .jr-text .pj-facts dt, .esp-group span, .esp-tlab, .esp-contact .fl span, .esp-report summary, .pts-h, .esp-mail .sec, .jr-note, .jr-count, .jr-meta, .jr-toc summary, .jr-resume h2, .jr-more h2, .sub cite, .hint .h-lab {
  font: 500 var(--fs-label)/var(--lh-s) var(--font-sans); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); }
.wl.core { color: var(--ink); }
.hint .h-lab { margin-right: -.14em; }
.tbl-fiche .t small, .fm-mono, .fm-facts dt, .fm-tele dt, .pfr-n, .pfl-n { font: 300 var(--fs-data)/var(--lh-s) var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }

/* ── Tag : neutre, fort, en attente (option A : 10,5 px, hauteur 24 px) ── */
.tags li, .gal-tags span, .esp-lklab, .chip-soon, .jr-sample, .ph > span {
  display: inline-flex; align-items: center; height: 1.5rem; padding: 0 .75rem; border: 1px solid var(--line); border-radius: var(--r-pill);
  font: 500 var(--fs-label)/1 var(--font-sans); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); white-space: nowrap; }
.chip-soon { border-color: var(--ink); color: var(--ink); font-weight: 600; }
.jr-sample, .ph > span { border-style: dashed; border-color: var(--line-strong); color: var(--ink-3); }

/* ── Chip (puce) : d'après .jr-chip ; M 42 px, S 36 px ; survol : contour plus épais, montée douce ; pressé et actif : plein ── */
.chip, .jr-chip, .tbl-filters button, .gal-tab, .faq-row .acts button, .jr-sel select {
  position: relative; display: inline-flex; align-items: center; gap: .375rem; min-height: 2.75rem; padding: 0 1.125rem; border: 1px solid var(--line-strong); border-radius: var(--r-pill);
  background: transparent; color: var(--ink-2); font: 500 var(--fs-button)/1.2 var(--font-sans); letter-spacing: 0; text-transform: none; text-align: left; cursor: pointer;   /* v414 (Raphaël, 17 octobre : « 15 px minuscules partout ») : le libellé des boutons, puces comprises ; et 44 px de haut (cibles de 44 px) */
  transition: background-color var(--dur-respond) ease, color var(--dur-respond) ease, border-color var(--dur-respond) ease, box-shadow var(--dur-respond) ease, translate 260ms var(--ease-out); }
.tbl-filters button, .gal-tab, .faq-row .acts button { min-height: 2.25rem; padding: 0 .75rem; font-size: .8125rem; height: auto; }
.chip::after, .jr-chip::after, .tbl-filters button::after, .gal-tab::after, .faq-row .acts button::after { content: ""; position: absolute; inset: calc(-1 * var(--sl)) 0; }
:is(.chip, .jr-chip, .tbl-filters button, .gal-tab, .faq-row .acts button):hover { background: var(--paper); color: var(--ink); border-color: var(--ink); box-shadow: inset 0 0 0 .5px var(--ink), 0 .375rem 1.125rem rgba(var(--ink-rgb), .08); translate: 0 -2px; }
.jr-sel select:hover { color: var(--ink); border-color: var(--ink); box-shadow: inset 0 0 0 .5px var(--ink); }
:is(.chip, .jr-chip, .tbl-filters button, .gal-tab, .faq-row .acts button):active, .chip[aria-pressed="true"], .jr-chip[aria-pressed="true"], .tbl-filters button.on, .gal-tab.on {
  background: var(--ink); color: var(--on-ink); border-color: var(--ink); box-shadow: none; translate: 0 0; }
.tbl-filters button.on i { background: var(--on-ink); border-color: var(--on-ink); }
.tbl-filters button small { font: 300 var(--fs-mark)/1 var(--font-mono); opacity: .7; }
:is(.chip, .jr-chip, .tbl-filters button, .gal-tab, .faq-row .acts button):disabled { opacity: .38; cursor: not-allowed; translate: 0 0; box-shadow: none; }
.jr-sel select { padding-right: 2.625rem; color: var(--ink); }
.jr-sel svg { right: 1rem; }
@media (prefers-reduced-motion: reduce) { :is(.chip, .jr-chip, .tbl-filters button, .gal-tab, .faq-row .acts button):hover { translate: 0 0; } }
/* ── Chip en lien (a.chip, 14 octobre, v234) : la même puce posée sur un lien (« Retour au site » du bac à sable) ; seul le soulignement part ── */
a.chip { text-decoration: none; }
/* ── Barre (.bar-g, v234) : une rangée d'éléments qui passe à la ligne ; 12 px entre les lignes, 24 px entre les éléments (grille de 6 px). Placement seul ── */
.bar-g { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1.5rem; }

/* ── TextTab : onglet texte dont le filet se dessine (plans, études de cas, sommaire d'un projet) ── */
.cats button, .dj-tabs button, .pj-quick a, .xp-toc a {
  position: relative; display: inline-flex; align-items: center; min-height: var(--hit); padding: 0 .125rem; border: 0; background: none; text-decoration: none;
  font: 500 var(--fs-note)/1 var(--font-sans); letter-spacing: 0; text-transform: none; color: var(--ink-3); cursor: pointer; transition: color var(--dur-respond) ease; }
/* 10 octobre (audit Flareum, sur test) : les onglets passent en minuscules, à la taille Note (13,5 px) ; les capitales restent
   au repère de rubrique (« 01 — Expertise »). Avant : capitales espacées de 10 à 11,5 px. */
.cats button::after, .dj-tabs button::after, .pj-quick a::after, .xp-toc a::after { content: ""; position: absolute; left: 0; right: 0; bottom: .75rem; height: 1px; background: var(--ink); transform: scaleX(0); transform-origin: 0 50%; transition: transform var(--dur-trace) var(--ease-out); }
.cats button:hover, .cats button.on, .dj-tabs button:hover, .dj-tabs button[aria-selected="true"], .pj-quick a:hover, .pj-quick a[aria-current], .xp-toc a:hover, .xp-toc a[aria-current] { color: var(--ink); }
.cats button.on::after, .dj-tabs button[aria-selected="true"]::after, .pj-quick a[aria-current]::after, .xp-toc a[aria-current]::after { transform: scaleX(1); }
@media (max-width: 760px) { .cats button { min-height: 2.25rem; } }
@media (prefers-reduced-motion: reduce) { .cats button::after, .dj-tabs button::after, .pj-quick a::after, .xp-toc a::after { transition: none; } }

/* ── Rond sur image : 30 px, zone de clic de 44 px ── */
.pf-prev, .pf-next { width: 1.875rem; height: 1.875rem; }
.pf-prev::after, .pf-next::after { content: ""; position: absolute; inset: calc((1.875rem - var(--hit)) / 2); border-radius: 50%; }

/* ── Verre : ce qui flotte sur la page ; verre profond : le volet de Sofia, la barre du téléphone, le voile ── */
.dock-panel, .vis-bar, .pf-box, .tbl-fiche, .dj-card, .wl.core, .lil-gui.root.reglages { background: var(--glass); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur); }
/* la barre de navigation du téléphone : posée en place (30-pages.css) */
.faq-owner-pop, .esp-panel .espace { background: var(--glass-deep); backdrop-filter: var(--glass-deep-blur); -webkit-backdrop-filter: var(--glass-deep-blur); }

/* ── Rayons : case 8, carte 14, panneau 20 — posés en place dans chaque règle (var(--r-cell), var(--r-card), var(--r-panel)) ── */

/* ── Hachure et cadre « à venir » ── */
.ph, .tbl-el.soon { background: var(--hatch); }
.faq-owner, .gal-empty, .jr-sources, .ph { border: 1px dashed var(--line-strong); }

/* ── Figure : coins en L et légende ; les images des études de cas prennent « fig. n » (à la suite des 16 du site) ── */
.pc-fig > i, .rub-frame > i { width: clamp(.625rem, .4rem + .6vw, .75rem); height: clamp(.625rem, .4rem + .6vw, .75rem); }
.tbl-cap { font: italic 400 clamp(.71875rem, .65rem + .3vw, .8125rem)/var(--lh-s) var(--font-serif); color: var(--ink-2); }
.pj-text { counter-reset: fig 17; } /* 9 octobre : fig. 13 à 17 dans les rubriques (portfolio, questions, Raphaël) */
.pj-fig figcaption { font: 400 var(--fs-note)/var(--lh-s) var(--font-sans); color: var(--ink-2); }
.pj-fig figcaption::before { counter-increment: fig; content: "fig. " counter(fig) "\2002—\2002"; font: italic 400 .8125rem/1 var(--font-serif); color: var(--ink); }

/* ── Listes : KeyValue, NumberedSteps, RuleList, KeyFigures ── */
.fm-facts, .fm-tele { display: grid; gap: .75rem; margin: 0; }
.fm-facts div, .fm-tele div { display: grid; grid-template-columns: minmax(0, 6.75rem) 1fr; gap: .75rem; }
.fm-facts dd, .fm-tele dd { margin: 0; font: 400 var(--fs-note)/var(--lh-s) var(--font-sans); color: var(--ink); }
.fm-facts dt, .fm-tele dt { padding-top: .1875rem; }
@media (max-width: 760px) { .fm-facts div, .fm-tele div { grid-template-columns: 1fr; gap: .1875rem; } }
.facts dd, .jr-text .pj-facts dd { font: 600 var(--fs-text)/var(--lh-m) var(--font-sans); color: var(--ink); }
.fm-proto li { grid-template-columns: 1.875rem 1fr; gap: .75rem; padding: .75rem 0; }
.fm-proto li:first-child { padding-top: 0; }
.fm-proto li::before { content: counter(p, decimal-leading-zero); font: italic 400 1.125rem/var(--lh-m) var(--font-serif); color: var(--ink-2); padding-top: 0; }
.fm-proto b, .pts b, .items b, .fm-prins b { display: block; font: 500 var(--fs-text)/var(--lh-m) var(--font-sans); color: var(--ink); margin: 0; }
.pts, .items { gap: 1.125rem; }
.pts li, .items li, .fm-prins li { padding-left: 1.125rem; gap: 0; border-left: 1px solid var(--line-strong); }
.pj-chiffres { gap: 1.5rem; }
.pj-chiffres > div { gap: .375rem; padding-top: 1.125rem; }
.pj-chiffres dt, .c-num b { font: 300 clamp(1.875rem, 1.4rem + 1.5vw, 2.625rem)/1 var(--font-sans); font-variant-numeric: tabular-nums; }
.pj-chiffres dd { font: 400 var(--fs-note)/var(--lh-s) var(--font-sans); color: var(--ink-2); }

/* ── Citation : une taille (un peu plus petite que la proposition, choix QU-01) ── */
blockquote.q p, .jr-text blockquote p { font: italic 400 clamp(1.125rem, .97rem + .55vw, 1.375rem)/1.4 var(--font-serif); color: var(--ink); }

/* ── Points : 3, 6, 8 px ── */
.cnav i, .pf-dots i { width: .375rem; height: .375rem; }
/* au téléphone, le sous-titre de l'accueil se resserre : il partage l'écran avec le champ de Sofia */
@media (max-width: 760px) { .hero .sub { line-height: 1.3125rem; } }

/* ── les visuels au trait des articles du Journal (45-journal.css, .jr-cover), tels quels (v403) ; v455 : et la structure du menu déroulant (.jr-sel, pour le réglage de mise en page) ── */
.jr-sel { position: relative; display: inline-flex; align-items: center; }
.jr-sel select { appearance: none; -webkit-appearance: none; }
.jr-sel select option { background: var(--paper); color: var(--ink); }
.jr-sel svg { position: absolute; pointer-events: none; color: var(--ink-2); }
.jr-cover { display: block; width: 100%; height: auto; }
.jr-cover .bg { fill: var(--paper-2); }
.jr-cover .l { fill: none; stroke: var(--ink); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.jr-cover .t { fill: none; stroke: var(--ink); stroke-width: 6; stroke-linecap: round; }
.jr-cover .c { fill: none; stroke: var(--ink-2); stroke-width: 1.4; }
.jr-cover .g { fill: var(--paper); fill-opacity: .65; stroke: var(--ink); stroke-width: 1.6; }
.jr-cover .d { fill: none; stroke: var(--line-strong); stroke-width: 1.2; stroke-dasharray: 4 6; }
.jr-cover .f { fill: var(--ink); }
/* ── le champ (30-pages.css, règles .ask) ── */
.ask { position: relative; display: flex; align-items: center; gap: .375rem; border-bottom: 1px solid var(--line-strong); transition: border-color var(--dur-respond) ease; }
.ask:focus-within, .ask:hover { border-color: var(--ink); }
.ask input { flex: 1; min-width: 0; height: 3rem; border: 0; background: transparent; color: var(--ink); font: 400 1rem/1 var(--font-sans); outline: none; }
.ask input::placeholder { color: var(--ink-3); }
/* ── l’indice de défilement (30-pages.css, règles .hint) ── */
.hint { position: absolute; left: 50%; bottom: .875rem; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: .75rem;
  padding: .375rem .75rem; border: 0; background: none; color: var(--ink); cursor: pointer; }
.hint .mouse { overflow: visible; }
.hint .m-base { fill: none; stroke: var(--ink-3); stroke-opacity: .55; stroke-width: 1.5; }
.hint .m-glow { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.hint .m-lens rect { fill: none; stroke: currentColor; stroke-width: 2.6; }
.hint .m-lens circle { fill: currentColor; }
.hint .m-dot { fill: currentColor; }
.hint .h-lab { transition: color var(--dur-respond) ease; }
.hint:hover .h-lab, .hint:focus-visible .h-lab { color: var(--ink); }
/* ── le curseur de frappe (30-pages.css, .fx-caret) ── */
.fx-caret::after { content: ""; display: inline-block; width: .06em; height: .9em; margin-left: .06em; vertical-align: -.08em; background: currentColor; animation: caret 900ms steps(1) infinite; }
@keyframes caret { 50% { opacity: 0; } }
/* ── la visionneuse (35-sections.css, .pf-box) ── */
.pf-box { position: fixed; inset: 0; z-index: 40; display: grid; grid-template-columns: 44px minmax(0, 1fr) 44px; grid-template-rows: minmax(0, 1fr) auto; align-items: center; justify-items: center; gap: .75rem clamp(.375rem, 2vw, 1.875rem); padding: clamp(4.5rem, 10svh, 6rem) clamp(.75rem, 3vw, 2.625rem) clamp(1.125rem, 4svh, 2.25rem); opacity: 0; transition: opacity 220ms ease; }
.pf-box[hidden] { display: none; }
.pf-box.on { opacity: 1; }
.pf-box-fig { grid-column: 2; grid-row: 1; margin: 0; min-width: 0; max-height: 100%; display: flex; flex-direction: column; align-items: center; gap: .75rem; }
.pf-box-fig img { display: block; max-width: 100%; max-height: calc(100svh - 15.625rem); width: auto; height: auto; border-radius: var(--r-card); border: 1px solid var(--line); background: var(--paper); box-shadow: var(--shadow-float); }
.pf-box-fig figcaption { display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline; gap: .375rem .75rem; text-align: center; }
.pf-box-t { font: 500 .875rem/1.4 var(--font-sans); color: var(--ink); }
.pf-box-n { font: 300 var(--fs-mark)/1 var(--font-mono); letter-spacing: .08em; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.pf-box-x { position: absolute; right: var(--m); top: 1.375rem; }
.pf-box-prev { grid-column: 1; grid-row: 1; } .pf-box-next { grid-column: 3; grid-row: 1; }
.pf-box-dots { grid-column: 1 / -1; grid-row: 2; display: flex; justify-content: center; gap: .375rem; min-height: .5rem; }
.pf-box-dots i { width: .375rem; height: .375rem; border-radius: 50%; border: 1px solid var(--ink); transition: background-color var(--dur-respond) ease; } .pf-box-dots i.on { background: var(--ink); }
.pf-box.solo .pf-box-prev, .pf-box.solo .pf-box-next, .pf-box.solo .pf-box-dots { visibility: hidden; }
/* ── les commandes vidéo (97-expertise.css, .xp-ctl) ── */
.xp-ctl { display: flex; align-items: center; gap: .75rem; padding: .5rem .75rem; border-top: 1px solid var(--line) }
.xp-ctl[hidden] { display: none }
.xp-scrub { --p: 0%; flex: 1; min-width: 0; height: 2.75rem; margin: 0; background: transparent; appearance: none; -webkit-appearance: none; cursor: pointer }
.xp-scrub::-webkit-slider-runnable-track { height: 2px; border-radius: 2px; background: linear-gradient(to right, var(--ink) var(--p), var(--line-strong) var(--p)) }
.xp-scrub::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: .875rem; height: .875rem; margin-top: calc(1px - .4375rem); border-radius: 50%; background: var(--ink); border: 0; transition: transform var(--dur-respond) }
.xp-scrub::-moz-range-track { height: 2px; border-radius: 2px; background: var(--line-strong) }
.xp-scrub::-moz-range-progress { height: 2px; border-radius: 2px; background: var(--ink) }
.xp-scrub::-moz-range-thumb { width: .875rem; height: .875rem; border-radius: 50%; background: var(--ink); border: 0; transition: transform var(--dur-respond) }
.xp-scrub:hover::-webkit-slider-thumb, .xp-scrub:active::-webkit-slider-thumb { transform: scale(1.25) }
.xp-scrub:hover::-moz-range-thumb, .xp-scrub:active::-moz-range-thumb { transform: scale(1.25) }
/* ── le champ de Sofia (40-espace.css, .esp-chat) ── */
.esp-chat { grid-area: chat; display: flex; align-items: center; gap: 1.125rem; }
.esp-sofia { flex: none; width: 5.75rem; height: 4rem; }
.esp-chat .ask { flex: 1; min-width: 0; }
.esp-chat .ask input { height: 3.375rem; font-size: var(--fs-lead); }
.esp-q { margin: 0 0 .75rem; font: 400 var(--fs-note)/1.45 var(--font-sans); color: var(--ink-3); }
.esp-h { margin: 0 0 1.5rem; text-wrap: balance; }
.esp-chat .ask { align-items: flex-end; }
.esp-chat .ask textarea { flex: 1; min-width: 0; min-height: 3.375rem; max-height: 9.375rem; padding: 1.125rem 0 .75rem; border: 0; background: transparent; color: var(--ink); resize: none;
  font: 400 var(--fs-lead)/1.4 var(--font-sans); outline: none; overflow-y: auto; }
.esp-chat .ask textarea::placeholder { color: var(--ink-3); }
.esp-chat .ask .send { margin-bottom: .375rem; }
.esp-q { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
.esp-note { margin: 0 0 1.125rem; font: 400 .9375rem/1.5 var(--font-sans); color: var(--ink-2); }
.esp-contact { display: grid; gap: .75rem; }
.esp-contact .row { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; }
.esp-contact .fl { display: grid; gap: .375rem; }
.esp-contact .fl em { font-style: normal; letter-spacing: .04em; text-transform: none; color: var(--ink-3); }
.esp-contact input, .esp-contact textarea { width: 100%; box-sizing: border-box; padding: .75rem .75rem; border: 1px solid var(--line-strong); border-radius: var(--r-card); background: transparent; color: var(--ink); font: 400 .9375rem/1.5 var(--font-sans); outline: none; transition: border-color var(--dur-respond) ease; }
.esp-contact textarea { resize: vertical; min-height: 11.25rem; }
.esp-contact input:focus-visible, .esp-contact textarea:focus-visible { border-color: var(--ink); }
.esp-err { margin: 0; min-height: 1em; font: 500 var(--fs-note)/1.4 var(--font-sans); color: var(--ink); }
.esp-err:empty { display: none; }
.esp-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1.125rem; margin-top: .375rem; }
.esp-fine { margin: 0; font: 400 .7812rem/1.45 var(--font-sans); color: var(--ink-3); }
@media (max-width: 760px) { .esp-contact .row { grid-template-columns: 1fr; } }
.esp-report { border: 1px solid var(--line); border-radius: var(--r-card); padding: .75rem 1.125rem; }
.esp-report summary { cursor: pointer; list-style: none; }
.esp-report summary::-webkit-details-marker { display: none; }
.esp-report summary::after { content: '–'; float: right; color: var(--ink-3); }
.esp-report:not([open]) summary::after { content: '+'; }
.esp-report .rep, .esp-mail .rep { margin-top: .75rem; font: 400 .875rem/1.55 var(--font-sans); color: var(--ink-2); }
.esp-report .rep p, .esp-mail .rep p { margin: 0 0 .375rem; }
.esp-report ul, .esp-mail ul { margin: 0; padding-left: 1.125rem; }
.esp-report li, .esp-mail li { margin: 2px 0; }
/* ── vendor/lenis@1.3.21/lenis.css ── */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis:not(.lenis-autoToggle).lenis-stopped {
  overflow: clip;
}

.lenis [data-lenis-prevent],
.lenis [data-lenis-prevent-wheel],
.lenis [data-lenis-prevent-touch],
.lenis [data-lenis-prevent-vertical],
.lenis [data-lenis-prevent-horizontal] {
  overscroll-behavior: contain;
}

.lenis.lenis-smooth iframe {
  pointer-events: none;
}

.lenis.lenis-autoToggle {
  transition-property: overflow;
  transition-duration: 1ms;
  transition-behavior: allow-discrete;
}

