/* Accueil de la refonte. Tokens : css/tokens.css (MASTER.md).
   Une affiche de cinéma par écran, un écran par section, défilement aimanté. */

/* ---------- Base ---------- */
html{ scroll-snap-type:y mandatory; }
*,*::before,*::after{ box-sizing:border-box; }
[hidden]{ display:none !important; }
body{ margin:0; background:var(--creme); color:var(--noir); font:300 var(--t-body)/1.55 var(--ff-body);
  -webkit-font-smoothing:antialiased; overflow-x:clip; }
h1,h2,h3,p,ul,figure{ margin:0; }
ul{ list-style:none; padding:0; }
img{ display:block; max-width:100%; height:auto; }
a{ color:inherit; }
.sr-only{ position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
.skip-link{ position:fixed; z-index:calc(var(--z-nav) + 1); left:var(--s-4); top:var(--s-4); padding:var(--s-3) var(--s-4);
  background:var(--noir); color:var(--jaune); font:700 var(--t-kicker)/1 var(--ff-title); letter-spacing:.16em; text-transform:uppercase;
  text-decoration:none; transform:translateY(-200%); }
.skip-link:focus-visible{ transform:none; outline:3px solid var(--jaune); outline-offset:2px; }

.gut{ padding-left:max(var(--gut),env(safe-area-inset-left,0px)); padding-right:max(var(--gut),env(safe-area-inset-right,0px)); }
.leg{ font:400 var(--t-leg)/1.35 var(--ff-title); letter-spacing:.1em; text-transform:uppercase; }
.kicker{ font:700 var(--t-kicker)/1 var(--ff-title); letter-spacing:.16em; text-transform:uppercase; }
/* Phrase d'accent : Bricolage Grotesque, grotesque chaleureuse à pièges à encre, face à la géométrie d'Outfit. */
.serif{ font-family:var(--ff-serif); font-weight:500; font-optical-sizing:auto; font-size:var(--t-serif); line-height:1.12; letter-spacing:-.02em; text-wrap:balance; }
.title{ font:900 var(--t-xl)/.86 var(--ff-title); text-transform:uppercase; letter-spacing:-.025em; }

/* Un écran = une section. min-height : sur un téléphone très court l'écran s'allonge plutôt que de couper.
   Sur l'accueil, « Derrière la caméra », le portfolio et « On se parle » : 100dvh. Quand la barre du navigateur se replie en descendant
   (Safari, Chrome mobile), l'écran gagne de la hauteur ; la section la suit, sinon le haut de la suivante
   apparaît en bas. */
.screen{ position:relative; min-height:100svh; scroll-snap-align:start; scroll-snap-stop:always; overflow:hidden; }
.about, .work{ min-height:100dvh; }

/* ---------- Tampon : le seul bouton du site ---------- */
.stamp{ --rot:-3deg; --fond:var(--jaune); --encre:var(--noir); --volet:var(--noir); --encre-survol:var(--jaune);
  position:relative; isolation:isolate; overflow:hidden; display:inline-flex; align-items:center; gap:var(--s-2);
  min-height:48px; padding:10px 18px; border:0; background:var(--fond); color:var(--encre); border-radius:var(--r-stamp);
  text-decoration:none; cursor:pointer;
  font:900 var(--t-stamp)/1 var(--ff-title); text-transform:uppercase; letter-spacing:-.02em;
  box-shadow:var(--sh-stamp); transform:rotate(var(--rot)); transition:transform var(--t-survol) var(--sortie); }
.stamp::before{ content:""; position:absolute; inset:0; z-index:-1; background:var(--volet);
  transform:scaleX(0); transform-origin:left; transition:transform var(--t-survol) var(--sortie); }
.stamp span{ transition:color var(--t-survol) var(--sortie); }
.stamp:focus-visible{ transform:rotate(0deg); outline:3px solid var(--noir); outline-offset:9px; }
.stamp:focus-visible::before{ transform:scaleX(1); }
.stamp:focus-visible span{ color:var(--encre-survol); }
@media (hover:hover) and (pointer:fine){
  .stamp:hover{ transform:rotate(0deg); }
  .stamp:hover::before{ transform:scaleX(1); }
  .stamp:hover span{ color:var(--encre-survol); }
}
.stamp:active{ transform:rotate(0deg) translateY(2px); }
.stamp--blanc{ --fond:var(--blanc); --encre:var(--bleu); --volet:var(--noir); --encre-survol:var(--blanc); }
.stamp--bleu{ --fond:var(--bleu); --encre:var(--blanc); --volet:var(--noir); --encre-survol:var(--jaune); }

/* ---------- Entrées : une fois, à l'arrivée de l'écran ---------- */
.line{ display:block; overflow:hidden; padding-bottom:.06em; margin-bottom:-.06em; }
.line > span{ display:block; }
.play .line > span{ animation:monte var(--t-titre) var(--sortie) both; animation-delay:calc(var(--n,0) * var(--t-decal)); }
@keyframes monte{ from{ transform:translateY(108%); } to{ transform:none; } }
.play .rise{ animation:leve var(--t-entree) var(--sortie) both; animation-delay:calc(var(--n,0) * var(--t-decal)); }
@keyframes leve{ from{ transform:translateY(40px); opacity:0; } to{ transform:none; opacity:1; } }
/* Titres cinétiques : chaque ligne traverse l'écran, penchée par sa vitesse, et se redresse en se posant ;
   ses lettres arrivent écartées et se resserrent. Pas de cache, pas de lettre coupée, pas de rebond :
   une seule courbe de sortie, et seules transform et opacity bougent. */
[data-kine] .line{ overflow:visible; }
.ch{ display:inline-block; }
.play [data-kine] .line > span{ animation:none; }
.play [data-kine] .line{ animation:glisse var(--t-titre) var(--sortie) both; animation-delay:calc(var(--n,0) * var(--t-decal)); }
.play [data-kine] .ch{ animation:resserre var(--t-titre) var(--sortie) both; animation-delay:calc(var(--n,0) * var(--t-decal)); }
@keyframes glisse{
  from{ transform:translateX(calc(var(--dir,1) * -70vw)) skewX(calc(var(--dir,1) * 18deg)); opacity:0; }
  30%{ opacity:1; }
  to{ transform:none; opacity:1; }
}
@keyframes resserre{ from{ transform:translateX(calc(var(--off,0) * .45em)); } to{ transform:none; } }
/* Coupe franche : masqué le temps de l'attente, puis visible d'un coup. */
.play .cut{ animation:coupe calc(var(--t-titre) + var(--n,0) * var(--t-decal)) linear; }
@keyframes coupe{ from, to{ visibility:hidden; } }
.volet{ position:relative; }
.volet::after{ content:""; position:absolute; inset:0; z-index:var(--z-volet); background:var(--noir);
  transform:scaleX(0); transform-origin:right; pointer-events:none; }
.play .volet::after{ animation:volet var(--t-entree) var(--sortie) both; animation-delay:calc(var(--n,0) * var(--t-decal)); }
@keyframes volet{ from{ transform:scaleX(1); } to{ transform:scaleX(0); } }

/* ---------- Navigation ----------
   Téléphone et tablette : un burger fixe en haut à droite, qui ouvre le menu plein écran.
   Ordinateur (64em et plus) : les trois tampons en colonne, fixes en haut à droite, sans burger.
   Chaque écran laisse libre la colonne --nav-reserve en haut à droite, pour que rien ne passe dessous. */
:root{ --nav-reserve:calc(44px + var(--s-4) * 2); }
@media (min-width:64em){ :root{ --nav-reserve:calc(var(--nav-w) + var(--nav-r) + var(--s-5)); } }
.topnav{ display:none; }
.burger{ position:fixed; z-index:var(--z-nav); top:max(var(--s-4),env(safe-area-inset-top,0px)); right:max(var(--s-4),env(safe-area-inset-right,0px));
  --rot:3deg; width:44px; height:44px; min-height:44px; padding:0; justify-content:center; }
.burger__bars{ display:grid; gap:5px; width:20px; }
.burger__bars i{ display:block; height:3px; background:currentColor; }
/* Les deux barres deviennent une croix (5 px d'écart + 3 px d'épaisseur : chaque barre glisse de 4 px vers le centre). */
@keyframes croix-haut{ from{ transform:none; } to{ transform:translateY(4px) rotate(45deg); } }
@keyframes croix-bas{ from{ transform:none; } to{ transform:translateY(-4px) rotate(-45deg); } }
@keyframes barre-haut{ from{ transform:translateY(4px) rotate(45deg); } to{ transform:none; } }
@keyframes barre-bas{ from{ transform:translateY(-4px) rotate(-45deg); } to{ transform:none; } }
@media (min-width:64em){
  .burger{ display:none; }
  .topnav{ position:fixed; z-index:var(--z-nav); top:var(--nav-top); right:var(--nav-r); width:var(--nav-w);
    display:grid; justify-items:end; gap:var(--s-4); }
  .topnav .stamp{ min-height:44px; padding:8px 14px; font-size:1rem; }
  .topnav .stamp:nth-child(1){ --rot:-3deg; }
  .topnav .stamp:nth-child(2){ --rot:2deg; margin-right:var(--s-3); }
  .topnav .stamp:nth-child(3){ --rot:-2deg; margin-right:var(--s-1); }
}
.menu{ position:fixed; inset:0; z-index:calc(var(--z-nav) + 1); width:100%; max-width:none; height:100%; max-height:none; margin:0; border:0; padding:0;
  background:var(--noir); color:var(--creme); }
.menu::backdrop{ background:var(--noir); }
.menu__in{ min-height:100%; display:grid; grid-template-rows:1fr auto; gap:0;
  padding-block:calc(max(var(--s-4),env(safe-area-inset-top,0px)) + 64px) max(2.5rem,env(safe-area-inset-bottom,0px)); }   /* mêmes marges que le menu des autres pages */
.menu__close{ justify-self:end; --rot:-2deg; padding:8px 14px; min-height:44px; font-size:var(--t-kicker); letter-spacing:.12em; }
/* Dans le menu, le bouton Fermer est le double exact du burger, posé à la même place : le burger reste au-dessus du
   menu qui s'ouvre, et ses deux barres se croisent. */
.menu .menu__close.burger{ --rot:3deg; padding:0; min-height:44px; }
.menu .menu__close .burger__bars i:first-child{ transform:translateY(4px) rotate(45deg); }
.menu .menu__close .burger__bars i:last-child{ transform:translateY(-4px) rotate(-45deg); }
/* Menu du téléphone, identique sur toutes les pages (css/pages.css reprend les mêmes mesures) : grands tampons
   posés en zigzag (gauche, droite, gauche), et la mention du studio centrée en bas, en bleu clair. */
.menu nav{ display:flex; flex-direction:column; align-items:flex-start; justify-content:center; gap:2.4rem; padding-left:.5rem; }
.menu nav .stamp{ font-size:clamp(1.8rem,7vw,3.4rem); padding:14px 24px; }
.menu nav .stamp:nth-child(1){ --rot:-7deg; margin-left:.5rem; }
.menu nav .stamp:nth-child(2){ --rot:5deg; align-self:flex-end; margin-right:1rem; }
.menu nav .stamp:nth-child(3){ --rot:-4deg; margin-left:2rem; }
.menu nav .stamp:focus-visible{ outline-color:var(--jaune); }
.menu .leg{ text-align:center; font:700 .62rem/1.6 var(--ff-title); letter-spacing:.15em; text-transform:uppercase; color:var(--bleu-clair); }
/* Le burger (et son double dans le menu) garde toujours son aspect : fond jaune, barres ou croix noires,
   même au clavier (le cadre de focus le signale, sans volet noir). */
.burger::before{ display:none; }
.burger:focus-visible .burger__bars, .burger:hover .burger__bars{ color:var(--noir); }
.menu .menu__close:focus-visible{ outline-color:var(--jaune); outline-offset:6px; }
.menu[open] nav .stamp{ animation:leve var(--t-entree) var(--sortie) both; animation-delay:calc(var(--n,0) * var(--t-decal)); }
/* Ouverture : un rectangle Noir Fitou sort de sous le burger (qui reste au-dessus, ses barres se croisent) et
   grandit jusqu'à couvrir l'écran ; puis les tampons se lèvent. Fermeture : le menu se replie dans le burger. js/raccord.js pose la place
   du burger (--m-t, --m-r, --m-b, --m-l) et retarde la fermeture le temps du repli. */
@media (prefers-reduced-motion:no-preference){
  .menu::backdrop{ background:transparent; }
  .menu[open]{ animation:menu-ouvre 520ms cubic-bezier(.65,0,.25,1) both; }
  .menu[open].ferme{ animation:menu-ferme 380ms cubic-bezier(.55,0,.75,.2) both; }
  /* Les tampons sortent de sous le burger (--dx, --dy : du centre du tampon au centre du burger, posés par
     js/raccord.js), puis se balancent doucement comme le sticker de la Bonne Mère ; à la fermeture ils y rentrent. */
  .menu .menu__close.burger{ z-index:2; }   /* au-dessus des tampons : ils passent dessous */
  .menu[open] nav .stamp{ transform-origin:50% 50%;
    animation:menu-sort 560ms cubic-bezier(.2,.9,.3,1.12) calc(200ms + var(--n,0) * 80ms) both,
              menu-balance 5.5s ease-in-out calc(var(--n,0) * -1.9s) infinite; }
  .menu[open].ferme nav .stamp{
    animation:menu-rentre 300ms cubic-bezier(.55,0,.8,.3) calc((2 - var(--n,0)) * 40ms) both,
              menu-balance 5.5s ease-in-out calc(var(--n,0) * -1.9s) infinite; }
  .menu[open] .leg{ animation:menu-fondu 300ms ease 320ms both; }
  .menu.ferme .leg{ animation:menu-fondu-sort 160ms ease both; }
  .menu[open] .menu__close .burger__bars i:first-child{ animation:croix-haut 320ms var(--sortie) 80ms both; }
  .menu[open] .menu__close .burger__bars i:last-child{ animation:croix-bas 320ms var(--sortie) 80ms both; }
  .menu[open].ferme .menu__close .burger__bars i:first-child{ animation:barre-haut 280ms var(--sortie) both; }
  .menu[open].ferme .menu__close .burger__bars i:last-child{ animation:barre-bas 280ms var(--sortie) both; }
}
@keyframes menu-ouvre{
  from{ clip-path:inset(var(--m-t,16px) var(--m-r,16px) var(--m-b,calc(100% - 60px)) var(--m-l,calc(100% - 60px)) round 10px); }
  to{ clip-path:inset(0 0 0 0 round 0px); } }
@keyframes menu-ferme{
  from{ clip-path:inset(0 0 0 0 round 0px); }
  to{ clip-path:inset(var(--m-t,16px) var(--m-r,16px) var(--m-b,calc(100% - 60px)) var(--m-l,calc(100% - 60px)) round 10px); } }
@keyframes menu-fondu{ from{ opacity:0; } to{ opacity:1; } }
@keyframes menu-sort{ from{ translate:var(--dx,0px) var(--dy,0px); scale:.15; opacity:0; } 30%{ opacity:1; } to{ translate:0 0; scale:1; opacity:1; } }
@keyframes menu-rentre{ from{ translate:0 0; scale:1; opacity:1; } 75%{ opacity:1; } to{ translate:var(--dx,0px) var(--dy,0px); scale:.15; opacity:0; } }
@keyframes menu-balance{ 0%,100%{ rotate:-1.8deg; } 50%{ rotate:1.8deg; } }
@keyframes menu-fondu-sort{ to{ opacity:0; } }

/* =============== 1. HERO =============== */
/* --wfs corps du mot, --wh sa hauteur d'encre, --pw largeur du portrait (1400 × 1221, crâne à 22,1 %
   de la largeur). Le portrait est collé au bas de l'écran ; le mot se place pour que la tête
   le croise à 42 % de sa hauteur. */
.hero{ height:100svh; min-height:0; background:var(--creme);
  --edge:max(28px,4vw);
  --tk:calc(clamp(1.2rem,3vw + .4rem,2.3rem) + 24px);
  --wfs:var(--t-display); --wh:calc(var(--wfs) * .78); --pw:min(112vw, 104svh, 1400px);
  --pw0:min(112vw, 104svh, 1400px);   /* taille d'origine du portrait : FIT✳U reste à sa place même si la photo est réduite */
  --wtop:max(calc(var(--gap-top) + 8px), calc(100svh - var(--tk) - var(--pw0) * .651 - var(--wh) * .42)); }
.hero .ticker{ position:absolute; z-index:var(--z-volet); left:0; right:0; bottom:0; }
.crop{ position:absolute; z-index:var(--z-crop); width:22px; height:22px; border:0 solid var(--noir); pointer-events:none; }
.crop--tl{ top:12px; left:12px; border-top-width:1.5px; border-left-width:1.5px; }
.crop--tr{ top:12px; right:12px; border-top-width:1.5px; border-right-width:1.5px; }
.crop--bl{ bottom:calc(var(--tk) + 12px); left:12px; border-bottom-width:1.5px; border-left-width:1.5px; }
.crop--br{ bottom:calc(var(--tk) + 12px); right:12px; border-bottom-width:1.5px; border-right-width:1.5px; }
.hero__word{ position:absolute; z-index:var(--z-titre); left:0; right:0; top:var(--wtop); text-align:center;
  font:900 var(--wfs)/.78 var(--ff-title); letter-spacing:-.035em; color:var(--bleu); }
/* Le cache des lettres déborde de l'interligne serré, pour ne jamais rogner l'encre. */
.hero__word .line{ padding-block:.14em; margin-block:-.14em; }
.hero__pic{ position:absolute; z-index:var(--z-photo); bottom:var(--tk); left:50%; width:var(--pw); translate:-50% 0; }
.hero__pic img{ width:100%; filter:var(--sh-cut); }
/* L'astérisque remplace le O de FITOU et tourne sur lui-même (seule rotation continue du site,
   demandée par Élie). Il s'arrête quand le hero quitte l'écran et en mouvement réduit. */
.sprite{ position:absolute; width:0; height:0; overflow:hidden; }
.ch--aster{ width:.7em; height:.7em; margin-inline:.03em .05em; vertical-align:baseline; }
.ch--aster svg{ display:block; width:100%; height:100%; animation:tourne 18s linear infinite; }
.hero.is-off .ch--aster svg{ animation-play-state:paused; }
@keyframes tourne{ to{ transform:rotate(360deg); } }
/* PRODUCTION : sous FITOU, du bord gauche du F au bord droit du I. js/accueil.js règle sa position et
   son corps ; la graisse est fine, en contrepoint du noir du mot. */
/* Calé sur l'encre, pas sur les boîtes (mesures Outfit Black) : l'encre du F commence à 0,059 em, celle
   du I finit à 0,838 em du mot ; l'encre de PRODUCTION mesure 6,731 em, son P commence à 0,059 em.
   Corps = 0,779 / 6,731 = 0,1157 du mot ; décalage = 0,059 × (1 − 0,1157) = 0,0522 du mot.
   Mot centré (téléphone, tablette) : la boîte du F commence à 1,475 em à gauche du centre. */
.hero__prod{ position:absolute; z-index:var(--z-titre);   /* derrière la photo, comme FIT✳U */
  left:calc(50% - var(--wfs) * 1.475 + var(--wfs) * .0522); top:calc(var(--wtop) + var(--wh)); margin:0;
  margin-top:calc(var(--wfs) * .05); font:900 calc(var(--wfs) * .1157)/.8 var(--ff-title); letter-spacing:0; color:var(--bleu); white-space:nowrap; }
.hero__prod .line{ padding:0; margin:0; }
.hero__pic{ position:absolute; z-index:var(--z-photo); bottom:var(--tk); left:50%; width:var(--pw); translate:-50% 0; }
.hero__pic img{ width:100%; filter:var(--sh-cut); }
/* Le studio, dans le style de l'ancienne accroche et à sa place : bas à droite sur ordinateur,
   au-dessus du mot sur téléphone. Titre cinétique, comme les autres. */
.hero__claim{ position:absolute; z-index:3; right:var(--edge); bottom:calc(var(--tk) + clamp(28px,6svh,80px)); text-align:right;
  font:900 clamp(1.3rem,3.6vw,3.75rem)/.9 var(--ff-title);   /* réduit d'environ 15 % (avant : clamp(1.5rem,4.2vw,4.4rem)) */ text-transform:uppercase; letter-spacing:-.02em; color:var(--bleu); }
/* Les métiers, dans la graisse fine des légendes, à l'ancienne place du « 10 ans » : ordinateur seulement.
   Ils ne passent jamais sur l'épaule (le t-shirt noir les rendrait illisibles). Détourage mesuré : en bas
   du portrait l'épaule commence à 9 % de sa largeur ; au-dessus de 33 % de sa hauteur, à 28,5 %.
   --avail est la place libre entre la marge et l'épaule ; le corps s'y ajuste (23 signes ≈ 17 em). */
@media (min-width:64em){
  /* La colonne de navigation occupe le haut à droite : le mot s'aligne à gauche et s'arrête avant elle. */
  /* Photo réduite d'environ 15 % (avant : min(112vw, 104svh, 1400px)) ; FIT✳U ne bouge pas (--pw0). */
  .hero{ --wfs:min(var(--t-display), (100vw - var(--edge) - var(--nav-reserve)) / 3); --pw:min(95vw, 88svh, 1190px); }
  .hero__word{ left:var(--edge); right:auto; text-align:left; }
  .crop--tr{ display:none; }
  .hero__prod{ left:calc(var(--edge) + var(--wfs) * .0522); top:calc(var(--wtop) + var(--wh) - var(--wfs) * .025); }   /* collé un peu plus haut sous FIT✳U */
  /* Le portrait est décalé vers la gauche : le buste occupe à peu près de 19 % à 67 % de la largeur. */
  /* Portrait un peu réduit (le reste de l'affiche garde ses mesures) : le buste couvre ~22 % à 63 % de la largeur. */
  .hero__pic, .hero .hero__traits{ left:calc(50% - var(--px, 7.5vw)); width:calc(var(--pw) * var(--pk, .87)); }
}
@media (max-width:47.99em){
  /* Téléphone : la place libre est au-dessus du mot. Les métiers en haut, le studio juste au-dessus de FITOU. */
  /* Le haut des lettres du studio s'aligne sur le bas du burger (16 px + 45 px) ; FIT✳U suit, au même écart.
     --cf : corps du studio (4 lignes à .9). .12em : distance entre le haut de la ligne et le haut des capitales. */
  /* Photo et FIT✳U à leur taille et place d'origine ; seul le studio est réduit (--cf ; corps d'origine --cf0,
     qui sert toujours à placer FIT✳U). Le haut des capitales du studio reste aligné sur le bas du burger. */
  .hero{ --pw:min(175vw, 84svh); --edge:28px; --cf:clamp(1.25rem,6.5vw,1.9rem); --cf0:clamp(1.7rem,9vw,2.6rem);
    --wtop:calc(max(var(--s-4),env(safe-area-inset-top,0px)) + 45px - var(--cf0) * .12 + var(--cf0) * .9 * 4 + 18px); }
  .hero__claim{ left:var(--edge); right:var(--edge); text-align:left; font-size:var(--cf);
    bottom:auto; top:calc(max(var(--s-4),env(safe-area-inset-top,0px)) + 45px - var(--cf) * .12); }
  /* Derrière la caméra : sous-titre rapproché du titre, corps de texte plus serré */
  .about__lede{ padding-top:0; margin-top:-14px; }
  .about__paras p{ line-height:1.4; }
  /* La scène commence un peu plus bas : la photo (et ses lignes) descend d'autant, sans toucher le texte. */
  .about__stage{ margin-top:max(2.75rem, 2.75rem + (100svh - 669px) * .14); }   /* plus l'écran est haut, plus la photo grandit : on la décale d'autant */
}
/* Le portrait monte depuis le bas de l'écran, d'abord entièrement caché sous le bandeau. */
.play .hero__pic{ animation:sort var(--t-titre) var(--sortie) both; animation-delay:var(--t-decal); }
@keyframes sort{ from{ transform:translateY(calc(100% + var(--tk))); } to{ transform:none; } }

/* Bandeau des métiers, posé en bas du hero */
.ticker{ overflow:hidden; background:var(--bleu); color:var(--blanc); }   /* bandeau bleu, texte blanc */
.ticker__track{ display:flex; width:max-content; animation:defile 26s linear infinite; }
.ticker:hover .ticker__track, .is-off .ticker__track{ animation-play-state:paused; }
.ticker__row{ font:900 clamp(1.2rem,3vw + .4rem,2.3rem)/1 var(--ff-title); padding-block:12px; white-space:nowrap; }
/* Les métiers sont séparés par un simple espace (plus d'astérisques) ; la marge suit chaque mot,
   pour que les deux rangées identiques s'enchaînent sans à-coup. */
.ticker__row b{ font-weight:inherit; margin-right:2.2em; }
@keyframes defile{ to{ transform:translateX(-50%); } }

/* =============== 2. DERRIÈRE LA CAMÉRA =============== */
/* Titre-affiche sur deux lignes en haut. Téléphone : texte, puis photo posée sur le bas de l'écran.
   Ordinateur : la photo à gauche, en grand, les deux textes à droite. Le texte n'est jamais sur la photo. */
/* Téléphone : titre, texte, puis la photo dans toute la hauteur qui reste. Le haut de l'image est
   transparent sur 20 % : la photo déborde d'autant vers le haut, pour que les mains arrivent juste
   sous le texte. Les côtés sont rognés, c'est voulu. */
.about{ --tfs:11.8vw; background:var(--bleu); color:var(--blanc); display:grid;
  grid-template-areas:"titre" "texte" "photo"; grid-template-rows:auto auto 1fr; }
.about__title{ grid-area:titre; position:relative; z-index:var(--z-titre); padding-top:var(--gap-top); color:var(--blanc);
  font:900 var(--tfs)/1 var(--ff-title); text-transform:uppercase; letter-spacing:-.03em; }
/* Interligne 1 : l'accent du É de CAMÉRA dépasse la capitale d'environ 0,2 em ; à 0,84 il touchait
   le pied de DERRIÈRE. Le corps baisse d'autant pour garder la même hauteur de bloc. */
.about__lede{ grid-area:texte; display:grid; gap:var(--s-3); padding-block:var(--s-5) var(--s-4); }
.about__lede .serif{ max-width:24ch; }
.about__paras{ display:grid; gap:10px; max-width:46ch; font-size:.9375rem; }
/* La scène est un conteneur : la photo prend la plus grande taille qui tient, sans se déformer. */
.about__stage{ grid-area:photo; position:relative; min-height:0; container-type:size; }
.about__fig{ position:absolute; z-index:var(--z-photo); bottom:0; left:50%; translate:-50% 0; margin:0;
  width:min(100cqh / .8 * 1400 / 892, 260vw); aspect-ratio:1400 / 892; }
/* La scène grandit quand la barre du navigateur se replie (100dvh > 100svh) : on retire ce gain, pour que la
   photo garde sa taille et reste simplement posée sur le bas de l'écran, sans zoomer. */
@supports (height:100dvh){ .about__fig{ width:min((100cqh - (100dvh - 100svh)) / .8 * 1400 / 892, 260vw); } }
.about__pic{ width:100%; height:auto; filter:var(--sh-cut); }
/* Le bouton, au centre du t-shirt */
/* Lignes mouvantes autour des portraits (tracées et animées par js/contours.js). Elles montent avec la photo
   et passent derrière les textes (sauf FIT✳U, devant lequel elles passent sur l'affiche). */
.traits{ position:absolute; inset:0; z-index:1; width:100%; height:100%; overflow:visible; pointer-events:none; }
.traits path{ fill:none; stroke-width:6; stroke-linecap:round; stroke-linejoin:round; }
.traits--jaune path{ stroke:var(--jaune); }
/* Affiche : les lignes sont posées à la place exacte de la photo, au même niveau qu'elle : devant FIT✳U,
   derrière « PRODUCTION » et « Studio de production visuelle · Marseille ». Elles montent avec elle. */
.hero__traits{ inset:auto; z-index:var(--z-photo); bottom:var(--tk); left:50%; width:var(--pw); height:auto; aspect-ratio:1400 / 1221; translate:-50% 0; }
.play .hero__traits{ animation:sort var(--t-titre) var(--sortie) both; animation-delay:var(--t-decal); }
.about__title, .about__lede{ position:relative; z-index:3; }
.about__fig .stamp{ position:absolute; z-index:3; left:50%; bottom:14%; translate:-50% 0; }
.about .stamp:focus-visible{ outline-color:var(--blanc); }
@media (min-width:56em){
  .about{ --tfs:min(13.1vw, 17.6svh, (100vw - 2 * var(--nav-reserve)) / 5.7);
    grid-template-columns:minmax(0,1.8fr) minmax(0,1fr); column-gap:clamp(24px,4vw,72px);
    grid-template-areas:"titre titre" "photo texte"; grid-template-rows:auto 1fr; }
  .about__title{ text-align:center; }
  /* La scène couvre toute la hauteur de l'écran : la photo grandit autant que sa colonne le permet
     et passe devant le bas du titre, comme le portrait du hero devant FITOU. */
  .about__stage{ grid-row:1 / 3; grid-column:1; z-index:var(--z-photo); margin:0 0 0 max(var(--gut),env(safe-area-inset-left,0px)); height:auto; min-height:0; }
  /* Un peu plus petit que la scène : le haut de la tête et les coudes tombent dans le cadre voulu. */
  .about__fig{ left:var(--fx, 2.4vw); translate:none; width:calc(min(100cqw, 100cqh * 1400 / 892) * var(--fk, .92)); }
  .about__lede{ align-self:center; padding-block:0; padding-left:0; gap:var(--s-5); max-width:44ch; }
  .about__lede .serif{ font-size:clamp(1.6rem,2.2vw,2.3rem); max-width:18ch; }
  .about__paras{ font-size:var(--t-body); gap:var(--s-3); }
}

/* Téléphone court (moins de 46em de haut) : la photo et le portrait rendent un peu de hauteur au texte. */
@media (max-width:47.99em) and (max-height:46em){
  .hero{ --pw:min(175vw, 78svh); }
  .about{ --tfs:10.5vw; }
}

/* =============== 3. PORTFOLIO =============== */
.work{ background:var(--bleu-pale); color:var(--bleu); display:flex; flex-direction:column; justify-content:center; }
/* Grille : chaque filet est un élément qui se trace à son tour, à vitesse régulière, une fois l'écran
   posé. Les verticales descendent l'une après l'autre, puis les horizontales partent de la gauche,
   de haut en bas. Seules des transformations bougent (étirement sur un axe). */
.work__grid{ position:absolute; inset:0; pointer-events:none; overflow:hidden; }
.gl{ position:absolute; background:var(--bleu-filet); }
.gl--v{ top:0; bottom:0; width:1px; left:var(--x,0); transform-origin:50% 0; }
.gl--v:nth-child(2){ --x:50%; }
.gl--v:nth-child(3){ display:none; }
@media (min-width:48em){ .gl--v:nth-child(2){ --x:33.333%; } .gl--v:nth-child(3){ display:block; --x:66.667%; } }
.gl--h{ left:0; right:0; height:1px; top:calc(var(--i) * 9rem); transform-origin:0 50%; }
.play .gl--v{ animation:trace-v var(--t-trace) var(--trace) both; animation-delay:calc(var(--t-decal) + var(--i) * var(--t-decal)); }
.play .gl--h{ animation:trace-h var(--t-trace) var(--trace) both; animation-delay:calc(var(--t-decal) * 3 + var(--i) * var(--t-decal) / 3); }
@keyframes trace-v{ from{ transform:scaleY(0); } to{ transform:none; } }
@keyframes trace-h{ from{ transform:scaleX(0); } to{ transform:none; } }
.work__in{ position:relative; width:100%; max-width:1240px; margin-inline:auto; padding-block:var(--gap-top); }
.work__head{ margin-bottom:clamp(16px,3svh,32px); }
.work__head .kicker{ margin-bottom:10px; }
.rail{ display:flex; overflow-x:auto; scroll-snap-type:x mandatory; margin-inline:calc(var(--gut) * -1); padding-inline:var(--gut); scrollbar-width:none; }
.rail::-webkit-scrollbar{ display:none; }
.rail:focus-visible{ outline:2px solid var(--bleu); outline-offset:4px; }
@media (min-width:48em){ .rail{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); overflow:visible; margin:0; padding:0; } }
.proj{ position:relative; flex:0 0 min(78vw,20rem); scroll-snap-align:center; display:flex; flex-direction:column; gap:10px;
  padding:clamp(14px,2.4svh,20px); background:var(--bleu-pale); border-inline:1px solid var(--bleu-filet); margin-right:-1px;
  text-decoration:none; transition:background-color var(--t-survol) var(--sortie); }
@media (min-width:48em){ .proj{ flex:none; } }
.proj:focus-visible{ background:var(--blanc); outline:2px solid var(--bleu); outline-offset:-2px; }
.proj__top{ display:flex; justify-content:space-between; gap:var(--s-2); }
.proj__title{ font:900 var(--t-l)/.9 var(--ff-title); text-transform:uppercase; letter-spacing:-.03em; min-height:1.8em; }
.thumb{ position:relative; overflow:hidden; aspect-ratio:16/10; background:var(--noir); border-radius:var(--r); }
.thumb img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
/* Survol : coupe franche sur un second plan du film, sans fondu. */
.thumb img + img{ visibility:hidden; }
.proj:focus-visible .thumb img + img{ visibility:visible; }
@media (hover:hover) and (pointer:fine){
  .proj:hover{ background:var(--blanc); }
  .proj:hover .thumb img + img{ visibility:visible; }
}
.proj__desc{ font-size:.875rem; line-height:1.45; min-height:4.4em; color:var(--noir); }
.tc{ font:400 .75rem/1 var(--ff-title); font-variant-numeric:tabular-nums; letter-spacing:.06em; }
.work__foot{ display:flex; justify-content:center; margin-top:clamp(20px,4svh,40px); }

/* =============== 4. CONTACT =============== */
/* Contact et pied de page tiennent ensemble dans un écran (--foot-h mesuré par js/accueil.js). */
.contact{ min-height:calc(100svh - var(--foot-h, 0px)); min-height:calc(100dvh - var(--foot-h, 0px)); background:var(--creme); display:grid; grid-template-rows:auto 1fr; }
/* Téléphone : le titre s'arrête avant le burger, même quand le pied de page fait remonter l'écran. */
.contact__title{ padding-top:var(--gap-top); text-align:center; font:900 min(21vw, (100vw - 2 * var(--nav-reserve)) / 3.8)/.84 var(--ff-title);
  text-transform:uppercase; letter-spacing:-.03em; color:var(--noir); }
@media (min-width:48em){ .contact__title{ font-size:min(12.6vw, (100vw - 2 * var(--nav-reserve)) / 6.85); } .contact__title .line{ display:inline-block; } }
.contact__body{ display:grid; gap:18px; align-content:center; justify-items:center; text-align:center; padding-block:var(--s-4) var(--gap-top); }
.rig{ position:relative; height:clamp(130px,22svh,620px); aspect-ratio:892/1501; }
.rig img, .fire i{ position:absolute; inset:0; width:100%; height:100%; object-fit:contain; }
.fire i{ background:center/contain no-repeat; opacity:0; animation:flamme calc(var(--t-flamme) * 9) steps(1,end) infinite;
  animation-delay:calc(var(--i) * var(--t-flamme) * -1); }
@keyframes flamme{ 0%{ opacity:1; } 11.11%{ opacity:0; } 100%{ opacity:0; } }
.is-off .fire i{ animation-play-state:paused; }
.play .rig{ animation:leve var(--t-entree) var(--sortie) both; animation-delay:var(--t-decal); }
.contact__col{ display:grid; gap:clamp(14px,2.4svh,24px); justify-items:center; }
/* Mesure de lecture : jamais moins d'une trentaine de signes par ligne. */
.contact .serif{ color:var(--bleu); max-width:30ch; text-wrap:pretty; }
.coord{ display:grid; gap:10px; }
.coord li{ display:grid; gap:2px; }
.coord span{ font:700 var(--t-leg)/1 var(--ff-title); letter-spacing:.16em; text-transform:uppercase; color:var(--bleu); }
.coord a{ font:700 clamp(1rem,.6vw + .85rem,1.3rem)/1.3 var(--ff-title); text-decoration:none;
  background:linear-gradient(var(--jaune),var(--jaune)) 0 100% / 0 40% no-repeat; transition:background-size var(--t-survol) var(--sortie); }
.coord a:hover, .coord a:focus-visible{ background-size:100% 40%; }
.coord a:focus-visible{ outline:2px solid var(--bleu); outline-offset:3px; }
@media (min-width:48em){
  /* Tablette et plus : Notre-Dame à gauche, le texte à droite, centrés ensemble dans l'écran. */
  .contact__body{ grid-template-columns:auto minmax(0,520px); justify-content:center; align-items:center; gap:clamp(32px,6vw,96px); text-align:left; }
  .rig{ height:min(58svh, 620px); }
  .contact__col{ justify-items:start; }
}

/* ---------- Pied de page ---------- */
.foot{ scroll-snap-align:end; background:var(--noir); color:var(--creme); }
.foot__in{ max-width:1240px; margin-inline:auto; padding-block:22px max(22px,env(safe-area-inset-bottom,0px));
  display:flex; flex-wrap:wrap; gap:var(--s-3) var(--s-5); align-items:center; justify-content:space-between; font-size:.875rem; }
.foot nav{ display:flex; flex-wrap:wrap; gap:var(--s-2) 20px; }
.foot a{ text-decoration:none; display:inline-flex; align-items:center; min-height:44px; }
.foot a:focus-visible{ outline:2px solid var(--jaune); outline-offset:3px; }
@media (hover:hover) and (pointer:fine){ .foot nav a:hover{ color:var(--jaune); } }
.foot__logo img{ height:28px; width:auto; }
/* Téléphone : pied de page compact (navigation sur une ligne, mention légale en petit), pour que
   Contact et pied de page tiennent ensemble dans un écran. Les liens gardent 44 px de haut. */
@media (max-width:47.99em){
  .foot__in{ display:grid; gap:0 var(--s-3); grid-template-columns:auto 1fr; align-items:center; padding-block:var(--s-3) max(var(--s-4),env(safe-area-inset-bottom,0px)); font-size:.8125rem; }
  .foot__logo img{ height:22px; }
  .foot nav{ grid-column:1 / -1; grid-row:1; gap:0 var(--s-4); justify-content:space-between; }
  .foot__logo{ grid-row:2; }
  .foot__in > p{ grid-row:2; justify-self:end; text-align:right; font-size:.6875rem; line-height:1.3; opacity:.8; max-width:24ch; }
}

/* ---------- Avant l'entrée : rien n'est montré puis caché ----------
   Tant qu'un écran n'a pas joué son entrée, ce qui va entrer reste à sa position de départ. Sinon on
   voyait le texte en place, puis disparaître, puis arriver. Le mouvement réduit montre tout tout de suite. */
@media (prefers-reduced-motion:no-preference){
  .js [data-play]:not(.play) :is(.rise, .cut, [data-kine] .line){ visibility:hidden; }
  .js .hero:not(.play) :is(.hero__pic, .hero__traits){ transform:translateY(calc(100% + var(--tk))); }
  .js [data-play]:not(.play) .rig{ visibility:hidden; }
  .js [data-play]:not(.play) .volet::after{ transform:scaleX(1); }
  .js .work:not(.play) .gl--v{ transform:scaleY(0); }
  .js .work:not(.play) .gl--h{ transform:scaleX(0); }
}

/* ---------- Mouvement réduit : aucune entrée, boucles à l'arrêt sur une image ---------- */
@media (prefers-reduced-motion:reduce){
  .play .line > span, .play [data-kine] .line, .play [data-kine] .ch, .play .rise, .play .cut, .play .hero__pic, .play .hero__traits, .play .rig, .menu[open] nav .stamp,
  .play .gl, .ch--aster svg{ animation:none; }
  .play .volet::after{ animation:none; transform:scaleX(0); }
  .ticker__track{ animation:none; }
  .fire i{ animation:none; opacity:0; }
  .fire i:first-child{ opacity:1; }
}
