/* =============================================================
   FITOU PRODUCTION — feuille de style unique
   Mobile first → tablette (min-width: 48em) → desktop (min-width: 64em)

   Défilement : la page est un diaporama vertical. Chaque section fait
   exactement la hauteur de l'écran et le défilement s'aimante d'une
   section à l'autre (scroll-snap natif, aucun script).

   Navigation : pas de barre d'en-tête. Un burger flottant en haut à
   droite sur mobile ; les stickers du menu fixés en haut à droite en
   desktop, dans la zone laissée libre par le texte de chaque section.
   ============================================================= */

/* ---------- 1. Tokens ---------------------------------------- */
:root{
  /* Charte */
  --bleu:      #007CC1;
  --noir:      #231F20;
  --jaune:     #F8CA10;

  /* Déclinaisons */
  --bleu-clair:  #5FC0EF;
  --bleu-pale:   #E4F1FA;
  --bleu-spectre:#B9DDF4;
  --bleu-filet:  rgba(0,124,193,.26);
  --creme:       #F6F3EC;
  --blanc:       #FFFFFF;

  /* Typo */
  --ff-title: "Outfit", "Helvetica Neue", Arial, sans-serif;
  --ff-body:  "Outfit", "Helvetica Neue", Arial, sans-serif;
  --ff-serif: "DM Serif Display", Georgia, "Times New Roman", serif;

  /* Rythme */
  --gut: 1.25rem;
  --gap-top: 1.2rem;   /* respiration en haut de chaque écran */
  --r:   .5rem;

  /* Taille des très gros titres, exposée en variable pour que
     l'astérisque du contact puisse s'y caler exactement. */
  --t-xl: clamp(2.1rem, 11vw, 5.5rem);

  /* Ombres */
  --sh-stamp: 0 .3rem 0 rgba(35,31,32,.16), 0 .85rem 1.4rem rgba(35,31,32,.2);
  --sh-cut:   drop-shadow(0 1rem 1.4rem rgba(35,31,32,.35));
}

/* ---------- 2. Reset + conteneur de défilement ---------------- */
*,*::before,*::after{ box-sizing:border-box; }

html{
  -webkit-text-size-adjust:100%;
  overflow-x:clip;             /* ne crée PAS de conteneur de défilement */
  scroll-behavior:smooth;
  scroll-snap-type:y mandatory;
  scroll-padding-top:0;
}
body{
  margin:0;
  font-family:var(--ff-body);
  font-weight:300;
  font-size:1rem;
  line-height:1.6;
  color:var(--noir);
  background:var(--creme);
  -webkit-font-smoothing:antialiased;
}
/* posé sur <html> ET <body> : l'un des deux porte le défilement */
.is-locked{ overflow:hidden !important; }

img,svg{ display:block; max-width:100%; }
img{ height:auto; }
a{ color:inherit; }
button{ font:inherit; color:inherit; background:none; border:none; }
h1,h2,h3,p,figure,figcaption,ul{ margin:0; }
ul{ list-style:none; padding:0; }

.sprite{ position:absolute; width:0; height:0; overflow:hidden; }
.sprite symbol{ fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
.sprite #i-aster{ fill:currentColor; stroke:none; }

.sr-only{
  position:absolute; width:1px; height:1px;
  padding:0; margin:-1px; overflow:hidden;
  clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.skip-link{
  position:absolute; left:-9999px; top:0; z-index:99;
  background:var(--jaune); color:var(--noir);
  padding:.6rem 1rem; font-weight:700; border-radius:0 0 var(--r) 0;
}
.skip-link:focus{ left:0; }

:where(a,button,[tabindex]):focus-visible{
  outline:3px solid var(--jaune);
  outline-offset:3px;
  border-radius:.2rem;
}

/* ---------- 3. L'écran ---------------------------------------- */
.snap{
  position:relative;
  height:100svh;
  scroll-snap-align:start;
  scroll-snap-stop:always;   /* un écran par geste, pas deux */
  display:flex;
  flex-direction:column;
  overflow:hidden;
  padding-top:var(--gap-top);
}
/* Conteneur de contenu. Volontairement NON défilant sur un écran normal :
   un conteneur défilant sous le curseur capte la molette et l'empêche
   d'atteindre la page — c'est ce qui rendait la remontée impossible.
   La soupape de secours n'est activée que sur les écrans vraiment courts
   (section 17), là où le contenu risque réellement de ne pas tenir. */
.snap__in{ width:100%; }

/* ---------- 4. Typo partagée --------------------------------- */
.title{
  font-family:var(--ff-title);
  font-weight:900;
  text-transform:uppercase;
  line-height:.88;
  letter-spacing:-.025em;
  hyphens:none;
}
.title--xl{ font-size:var(--t-xl); }

.kicker{
  font-family:var(--ff-title);
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:.16em;
  font-size:.7rem;
  color:var(--bleu);
  margin-bottom:.8rem;
}
.kicker--light{ color:var(--jaune); }

.serif{
  font-family:var(--ff-serif);
  font-weight:400;
  font-size:clamp(1.15rem, 4.6vw, 1.75rem);
  line-height:1.28;
  color:var(--bleu);
}
.serif--light{ color:var(--blanc); }

/* =============================================================
   5. STICKERS — compacts, découpés, façon tampon
   ============================================================= */
.stamp{
  --rot:-4deg;
  --ring:var(--blanc);
  position:relative;
  display:inline-flex;
  align-items:center;
  gap:.45rem;
  padding:.42rem .7rem .48rem;
  background:var(--blanc);
  color:var(--bleu);
  border-radius:.4rem;
  font-family:var(--ff-title);
  font-weight:900;
  font-size:clamp(1.05rem, 4.6vw, 1.3rem);
  line-height:.92;
  text-transform:uppercase;
  letter-spacing:-.025em;
  text-decoration:none;
  white-space:nowrap;
  box-shadow:0 0 0 7px var(--ring), var(--sh-stamp);
  transform:rotate(var(--rot));
  transform-origin:50% 50%;
  will-change:transform;
  transition:transform .28s cubic-bezier(.2,.8,.3,1), box-shadow .28s ease;
  animation:idle 6s ease-in-out infinite;
  animation-delay:var(--delay, 0s);
}
.stamp__icon{
  width:1.35rem; height:1.35rem; flex:none;
  fill:none; stroke:currentColor; stroke-width:1.8;
  stroke-linecap:round; stroke-linejoin:round;
}
.stamp--jaune{ background:var(--jaune); color:var(--noir); }
.stamp--blanc{ background:var(--blanc); color:var(--bleu); }
.stamp--bleu { background:var(--bleu);  color:var(--blanc); }

.stamp:hover,
.stamp:focus-visible{
  transform:rotate(calc(var(--rot) * -.7)) scale(1.08) translateY(-2px);
  box-shadow:0 0 0 7px var(--ring),
             0 .45rem 0 rgba(35,31,32,.18),
             0 1.3rem 1.9rem rgba(35,31,32,.28);
  animation-play-state:paused;
}
.stamp:active{ transform:rotate(var(--rot)) scale(.97); }
.stamp--inline{ --rot:-2.5deg; margin-top:1.4rem; }

@keyframes idle{
  0%,100%{ transform:rotate(var(--rot))                translateY(0); }
  33%    { transform:rotate(calc(var(--rot) + 1.4deg)) translateY(-2px); }
  66%    { transform:rotate(calc(var(--rot) - 1.1deg)) translateY(1px); }
}

/* =============================================================
   6. BURGER FLOTTANT — pas de barre d'en-tête
   Traité comme un petit sticker : lisible sur les quatre fonds
   (crème, noir, bleu pâle, bleu).
   ============================================================= */
.burger{
  position:fixed;
  top:1rem; right:1rem;
  z-index:55;
  width:2.9rem; height:2.9rem;
  display:grid; place-items:center;
  cursor:pointer;
  background:var(--blanc);
  border-radius:.5rem;
  box-shadow:0 0 0 5px var(--blanc), var(--sh-stamp);
  transform:rotate(-3deg);
  transition:transform .25s cubic-bezier(.2,.8,.3,1);
}
.burger__box{ display:grid; gap:.4rem; width:1.55rem; }
.burger__box i{
  display:block; height:.25rem; border-radius:.13rem;
  background:var(--bleu);
  transition:transform .25s ease;
}
.burger:hover{ transform:rotate(2deg) scale(1.06); }
.burger:hover .burger__box i:first-child{ transform:translateX(.16rem); }
.burger:hover .burger__box i:last-child { transform:translateX(-.16rem); }

/* =============================================================
   7. MENU
   Mobile  : panneau plein écran ouvert par le burger.
   Desktop : stickers fixes en HAUT À DROITE — la zone que le texte
             des sections laisse libre.
   ============================================================= */
.menu{
  position:fixed;
  inset:0;
  z-index:60;
  background:var(--bleu-pale);
  display:grid;
  grid-template-rows:auto 1fr auto;
  padding:1rem var(--gut) 2.5rem;
  opacity:0;
  visibility:hidden;
  pointer-events:none;
  transition:opacity .3s ease, visibility .3s;
}
.menu.is-open{ opacity:1; visibility:visible; pointer-events:auto; }

.menu__close{
  justify-self:end;
  width:3.4rem; height:3.4rem;
  display:grid; place-items:center;
  cursor:pointer;
  color:var(--bleu);
}
.menu__close svg{
  width:2.4rem; height:2.4rem;
  fill:none; stroke:currentColor; stroke-width:6; stroke-linecap:round;
}
.menu__close:hover{ transform:scale(1.08); }

.menu .stamps{
  align-self:center;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:2.4rem;
  padding-left:.5rem;
}
.menu .stamps .stamp:nth-child(1){ --rot:-7deg; --delay:0s;    margin-left:.5rem; }
.menu .stamps .stamp:nth-child(2){ --rot: 5deg; --delay:-2s;   align-self:flex-end; margin-right:1rem; }
.menu .stamps .stamp:nth-child(3){ --rot:-4deg; --delay:-3.6s; margin-left:2rem; }

.menu__base{
  text-align:center;
  font-family:var(--ff-title); font-weight:700;
  text-transform:uppercase; letter-spacing:.15em;
  font-size:.62rem; color:var(--bleu); opacity:.75;
}

/* =============================================================
   8. ÉCRAN 1 — HERO
   ============================================================= */
.hero{
  background:var(--creme);
  border-top:6px solid var(--bleu);
  padding-inline:var(--gut);
  padding-bottom:0;
}
.hero__stage{
  /* --rig n'est plus qu'une largeur MAXIMALE. La hauteur, elle, n'est plus
     devinée en svh palier par palier : la première ligne de la grille prend
     toute la place restante (1fr) une fois la baseline et le bandeau servis,
     et la composition ne peut donc plus déborder, sur aucun écran.
     Le vw est préféré au % : le % dépendrait de la piste, et --rig sert
     aussi dans un calcul de hauteur où « 100% » voudrait dire autre chose. */
  --rig: min(calc(100vw - 2 * var(--gut)), 24rem);
  position:relative;
  flex:1;
  min-height:0;
  display:grid;
  grid-template-rows:minmax(0,1fr) auto;
  justify-items:center;
  align-items:center;     /* FITOU centré sur la composition, pas calé en haut */
}

/* Le mot géant et la caméra partagent la même cellule : FITOU passe
   derrière (il est déclaré avant dans le HTML), la baseline dessous. */
.hero__word{
  grid-area:1/1;
  margin:0;
  text-align:center;
  white-space:nowrap;
  font-family:var(--ff-title);
  font-weight:900;
  font-size:clamp(4.5rem, 30vw, 17rem);
  line-height:.8;
  letter-spacing:-.045em;
  color:var(--bleu-spectre);
  user-select:none;
  pointer-events:none;
}

/* --- Notre-Dame + couronne de flammes ------------------------ */
/* Les dix images du hero partagent exactement le même cadre (892 × 1501) :
   flammes et statue se superposent bord à bord, sans aucun décalage à régler. */
.rig{
  grid-area:1/1;
  position:relative;
  /* la hauteur commande, la largeur suit le ratio : le dessin ne déborde
     jamais de la ligne, et --rig reste sa largeur maximale */
  height:min(100%, calc(var(--rig) * 1501 / 892));
  width:auto;
  max-width:100%;
  aspect-ratio:892/1501;
}
/* Les dessins sont déjà au bleu Fitou : on les affiche tels quels.
   Seule l'opacité est animée, une image toutes les 120 ms (~8 im/s). */
.rig__fire{
  position:absolute;
  inset:0;
}
.rig__fire i{
  position:absolute;
  inset:0;
  display:block;
  background-repeat:no-repeat;
  /* `center` et non `center top` : si la boîte n'a pas exactement le ratio
     des sources (écran très court), les dix calques se recadrent alors de
     la même façon que l'<img> en object-fit:contain, et restent alignés. */
  background-position:center;
  background-size:contain;
  opacity:0;
  animation:flamme 1.08s steps(1,end) infinite;
  animation-delay:calc(var(--i) * .12s);
}
.rig__fire i:nth-child(1){ --i:0; background-image:url(../assets/accueil/flammes/flamme-1.png); }
.rig__fire i:nth-child(2){ --i:1; background-image:url(../assets/accueil/flammes/flamme-2.png); }
.rig__fire i:nth-child(3){ --i:2; background-image:url(../assets/accueil/flammes/flamme-3.png); }
.rig__fire i:nth-child(4){ --i:3; background-image:url(../assets/accueil/flammes/flamme-4.png); }
.rig__fire i:nth-child(5){ --i:4; background-image:url(../assets/accueil/flammes/flamme-5.png); }
.rig__fire i:nth-child(6){ --i:5; background-image:url(../assets/accueil/flammes/flamme-6.png); }
.rig__fire i:nth-child(7){ --i:6; background-image:url(../assets/accueil/flammes/flamme-7.png); }
.rig__fire i:nth-child(8){ --i:7; background-image:url(../assets/accueil/flammes/flamme-8.png); }
.rig__fire i:nth-child(9){ --i:8; background-image:url(../assets/accueil/flammes/flamme-9.png); }

@keyframes flamme{ 0%,10.9%{ opacity:1; } 11%,100%{ opacity:0; } }

.rig__idol{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:contain;
}

/* --- Baseline, sous la composition ---------------------------
   Sa taille est calée par le script sur la largeur exacte de FITOU :
   on agit sur le corps de la police, pas sur un scaleX, pour ne pas
   déformer le dessin de la serif. */
.hero__base{
  grid-area:2/1;
  width:100%;
  /* la ligne du haut étant en 1fr, cette marge basse est ce qui décolle
     la baseline du bandeau — elle n'est plus laissée au hasard du calibrage */
  margin:.6rem 0 clamp(.7rem, 2.5svh, 1.6rem);
  font-family:var(--ff-title);   /* la police de FITOU */
  font-weight:900;
  text-transform:uppercase;
  font-size:1.4rem;        /* valeur de repli avant mesure */
  line-height:1;
  letter-spacing:.01em;
  color:var(--bleu);
  text-align:center;
  white-space:nowrap;      /* indispensable : la mesure doit être sur une ligne */
}

/* Bandeau défilant, collé au bas du hero et en pleine largeur */
.ticker{
  flex:none;
  margin-inline:calc(var(--gut) * -1);
  background:var(--bleu);
  color:var(--creme);
  overflow:hidden;
  padding:.45rem 0;
  border-top:3px solid var(--noir);
}
.ticker__track{
  display:flex;
  width:max-content;
  animation:slide 26s linear infinite;
  will-change:transform;
}
.ticker__row{
  font-family:var(--ff-title);
  font-weight:900;
  font-size:clamp(1.3rem, 6vw, 2.4rem);
  text-transform:uppercase;
  letter-spacing:-.02em;
  white-space:nowrap;
  padding-right:.6em;
}
.ticker__row b{ color:var(--jaune); }
@keyframes slide{ to{ transform:translate3d(-50%,0,0); } }

/* Cette règle manquait : `animation: spin` était appelée par l'astérisque du
   contact sans qu'aucune image-clé ne porte ce nom — donc aucune rotation. */
@keyframes spin{ to{ transform:rotate(360deg); } }

/* =============================================================
   9. STICKERS PHOTO DÉCOUPÉS
   ============================================================= */
.cutout{
  --rot:-4deg;
  position:relative;
  transform:rotate(var(--rot));
  transform-origin:50% 60%;
  will-change:transform;
  animation:idle 8s ease-in-out infinite;
  transition:transform .35s cubic-bezier(.2,.8,.3,1);
}
/* Par défaut : simple ombre portée — le PNG porte déjà son liseré
   (c'est le cas du portrait, découpé en amont dans les fichiers de marque). */
.cutout__img{
  width:100%;
  filter:var(--sh-cut);
}
/* Pour un PNG détouré SANS liseré, ajouter .cutout--outline :
   le contour blanc est alors calculé sur l'alpha. */
.cutout--outline .cutout__img{
  filter:
    drop-shadow(3px 0 0 var(--blanc))  drop-shadow(-3px 0 0 var(--blanc))
    drop-shadow(0 3px 0 var(--blanc))  drop-shadow(0 -3px 0 var(--blanc))
    drop-shadow(2px 2px 0 var(--blanc)) drop-shadow(-2px -2px 0 var(--blanc))
    drop-shadow(2px -2px 0 var(--blanc)) drop-shadow(-2px 2px 0 var(--blanc))
    var(--sh-cut);
}
.cutout:hover{
  transform:rotate(calc(var(--rot) * -.5)) scale(1.04);
  animation-play-state:paused;
}

/* Repère affiché si un PNG venait à manquer */
.cutout__slot{
  display:none;
  flex-direction:column; align-items:center; justify-content:center; gap:.5rem;
  aspect-ratio:1/1;
  border:2px dashed var(--bleu);
  border-radius:.6rem;
  color:var(--bleu);
  text-align:center;
  padding:1rem;
}
.cutout__slot em{
  font-style:normal; font-size:.68rem; letter-spacing:.05em;
  font-family:var(--ff-title); font-weight:700;
  word-break:break-all;
}
.cutout__ico{ width:2.4rem; height:2.4rem; fill:none; stroke:currentColor; stroke-width:1.4; }
.cutout--bless .cutout__slot{ aspect-ratio:3/4; }
.cutout.is-missing .cutout__img{ display:none; }
.cutout.is-missing .cutout__slot{ display:flex; }

/* Cartouche blanc du sticker Bonne Mère */
.cutout__cap{
  position:absolute;
  left:50%; bottom:.2rem;
  transform:translateX(-50%) rotate(-5deg);
  background:var(--blanc);
  color:var(--noir);
  font-family:var(--ff-title); font-weight:900;
  font-size:.56rem; line-height:1;
  text-transform:uppercase;
  white-space:nowrap;
  padding:.32rem .48rem .36rem;
  border-radius:.28rem;
  box-shadow:0 0 0 4px var(--blanc), 0 .35rem .8rem rgba(35,31,32,.3);
}

/* =============================================================
   10. ÉCRAN 2 — À PROPOS
   ============================================================= */
.about{
  background:var(--noir);
  color:var(--creme);
  justify-content:center;
  padding-inline:var(--gut);
  /* retrait haut réduit par rapport aux autres écrans : le burger flotte à
     droite, la photo est centrée — rien ne passe dessous, et les pixels
     récupérés servent à aérer le texte. Rétabli dès 48em. */
  /* Rembourrage volontairement ASYMÉTRIQUE. Le contenu est centré entre les
     deux : une réserve plus grande en bas décale donc tout le bloc vers le
     haut — c'est ce qui « consomme » le vide du haut — et laisse de quoi
     afficher le liseré blanc de 7 px du bouton et son ombre portée, qui
     seraient sinon rognés par l'`overflow:hidden` de la section. */
  padding-top:1rem;
  padding-bottom:1.6rem;
}
.about__inner{ max-width:72rem; margin-inline:auto; }
.about .title{ color:var(--creme); margin-bottom:.7rem; }
.about .serif{ color:var(--jaune); margin-bottom:1.25rem; }
/* 1.6 (l'interligne du site) est trop large pour un bloc de cette densité :
   sur onze lignes, 1.45 rend une trentaine de pixels — qui repartent dans la
   photo et dans la réserve sous le bouton. */
.about__text p{ line-height:1.45; }
.about__text p + p{ margin-top:.95rem; color:rgba(246,243,236,.78); font-size:.92rem; }
/* Le texte à la première personne compte quatre paragraphes : sur un téléphone
   de 750 px de haut, l'ancien calibrage débordait de la section et le bouton
   « À propos » était rogné par l'`overflow:hidden`. */
/* Centré en mobile, comme les boutons des autres sections. Accessoirement
   cela règle le rognage latéral : collé au bord gauche, le liseré de 7 px
   sortait de la boîte du conteneur de défilement, qui découpe aussi en
   largeur (une seule valeur d'`overflow` non visible suffit). */
.about .stamp--inline{
  display:flex;
  width:max-content;
  max-width:100%;
  margin:1.8rem auto 0;
}

/* La photo est dimensionnée en hauteur : elle s'adapte à l'écran.
   `--ar` est le rapport du PNG (1200 × 1046) — il sert en desktop à la borner
   aussi en LARGEUR, pour qu'elle ne déborde jamais de sa colonne. */
.cutout--portrait{
  --ar:1.147;
  height:clamp(6rem, 23svh, 16rem);
  width:auto;
  margin:0 auto 1.5rem;
  display:flex;
}
.cutout--portrait .cutout__img{ height:100%; width:auto; max-width:none; }
.cutout--portrait .cutout__slot{ height:100%; aspect-ratio:1/1; }

/* =============================================================
   11. ÉCRAN 3 — PORTFOLIO — trois projets phare, sans défilement
   ============================================================= */
.work{
  background:var(--bleu-pale);
  color:var(--bleu);
  padding-inline:0;
}
.work__grid{
  position:absolute; inset:0;
  pointer-events:none;
  background-image:
    repeating-linear-gradient(to right,  var(--bleu-filet) 0 1px, transparent 1px 50%),
    repeating-linear-gradient(to bottom, var(--bleu-filet) 0 1px, transparent 1px 9rem);
  opacity:.9;
}
.work__head{
  position:relative;
  flex:none;
  padding:.4rem var(--gut) 1.2rem;
  max-width:72rem;
  margin-inline:auto;
  width:100%;
}
.work__head .title{ color:var(--bleu); }

/* Mobile : glissement horizontal aimanté (sans flèches).
   Tablette et plus : grille fixe de trois colonnes, aucun défilement. */
.rail{
  position:relative;
  flex:1;
  min-height:0;
  display:flex;
  align-items:stretch;
  overflow-x:auto;
  overflow-y:hidden;
  scroll-snap-type:x mandatory;
  scroll-behavior:smooth;
  overscroll-behavior-x:contain;
  -webkit-overflow-scrolling:touch;
  scrollbar-width:none;
  /* le retrait vertical est ce qui dégage le blanc autour des cartes */
  padding-block:.9rem;
  padding-inline:var(--gut);
  border-top:1px solid var(--bleu-filet);
  border-bottom:1px solid var(--bleu-filet);
}
.rail::-webkit-scrollbar{ display:none; }

.proj{
  flex:0 0 auto;
  /* sans cela, la taille minimale d'une carte reste celle de son contenu
     et la borne de la rangée ci-dessus resterait sans effet */
  min-height:0;
  width:min(74vw, 19rem);
  scroll-snap-align:center;
  padding:1.1rem 1.2rem 1.3rem;
  border-left:1px solid var(--bleu-filet);
  border-right:1px solid var(--bleu-filet);
  margin-right:-1px;
  display:flex;
  flex-direction:column;
  /* Fond OPAQUE : le quadrillage de la section est fixe, les cartes
     défilent — un fond transparent le laissait passer au travers et il
     semblait glisser par-dessus les cartes. Il reste visible autour. */
  background:var(--bleu-pale);
  transition:background .3s ease;
}
.proj:hover{ background:rgba(255,255,255,.45); }
.proj__kicker{
  flex:none;
  font-family:var(--ff-title); font-weight:700;
  font-size:.6rem; letter-spacing:.16em; text-transform:uppercase;
  opacity:.7; margin-bottom:.4rem;
}
.proj__title{
  flex:none;
  font-family:var(--ff-title); font-weight:900;
  font-size:clamp(1.45rem, 6.5vw, 2rem);
  line-height:.9; letter-spacing:-.03em;
  text-transform:uppercase;
  margin-bottom:.9rem;
}
/* la vignette absorbe la hauteur restante : la carte tient sur l'écran */
.proj__thumb{
  position:relative;
  flex:1;
  min-height:3.5rem;
  margin-bottom:.9rem;
  overflow:hidden;
  background:rgba(0,124,193,.07);
  border:1px solid var(--bleu-filet);
  display:grid; place-items:center;
}
/* `cover` : l'image REMPLIT tout le cartouche, jamais étirée — c'est le
   cadrage qui cède, pas les proportions. Le format des sources ne suit pas
   celui du cartouche, elles sont donc recadrées au centre : choisir des
   images qui supportent ce recadrage (l'Ademe, presque carrée, tient mieux
   en mobile qu'un 16/9). */
.proj__thumb img{ width:100%; height:100%; object-fit:cover; grid-area:1/1; z-index:1; }
.proj__thumb.is-missing img{ display:none; }
/* l'ardoise rayée n'est qu'un repère d'attente : dès qu'une image est là,
   elle ne doit plus apparaître dans les bandes laissées par `contain` */
.proj__thumb:not(.is-missing) .slate{ display:none; }
.slate{
  grid-area:1/1;
  display:grid; place-content:center; justify-items:center; gap:.3rem;
  width:100%; height:100%;
  background:repeating-linear-gradient(135deg, rgba(0,124,193,.10) 0 10px, transparent 10px 20px);
}
.slate b{
  font-family:var(--ff-title); font-weight:900;
  font-size:2.2rem; letter-spacing:-.04em; opacity:.35;
}
.slate svg{ width:1.6rem; height:1.6rem; fill:none; stroke:currentColor;
  stroke-width:1.4; opacity:.45; }
.proj__desc{
  flex:none;
  font-size:.86rem; line-height:1.45;
  color:rgba(0,124,193,.9);
}

.work__foot{
  position:relative;
  flex:none;
  display:flex; justify-content:center;
  /* 1.8rem en bas : le sticker porte un liseré de 7 px et une ombre qui
     descend, et l'`overflow:hidden` de la section les rognerait */
  padding:.9rem var(--gut) 2.3rem;
}
.work__foot .stamp{ margin-top:0; }

/* Enveloppe titre + sticker. En mobile elle ne génère aucune boîte : le
   sticker reste positionné en absolu par rapport à la section, comme avant. */
.work__top{ display:contents; }

/* Sticker Bonne Mère : desktop uniquement. En mobile il recouvrait la
   vignette de la carte et gênait la lecture. */
.cutout--bless{
  display:none;
  --rot:6deg;
  position:absolute;
  z-index:5;
  width:5.5rem;
  right:2.2rem;   /* le cartouche déborde du sticker : on garde de la marge */
  bottom:9.5rem;  /* posé sur la vignette, pas sur le texte de la carte */
  animation-duration:9s;
}

/* =============================================================
   12. ÉCRAN 4 — CONTACT + PIED DE PAGE
   ============================================================= */
.contact{
  background:var(--bleu);
  color:var(--blanc);
  padding-inline:var(--gut);
}
.contact .kicker{ margin-bottom:clamp(.8rem, 2.2svh, 1.8rem); }

.contact__in{
  position:relative;   /* repère pour l'image qui jette un œil */
  flex:1;
  min-height:0;
  display:flex;
  flex-direction:column;
  /* Calé en haut et non centré : le contenu démarre sous le burger flottant,
     ce qui dégage le bas de l'écran pour l'image. */
  justify-content:flex-start;
  align-items:center;
  text-align:center;
  padding-block:2.6rem 1rem;
}

/* Élie qui jette un œil, en bas à droite. Il déborde volontairement sous le
   pied de page, qui le recouvre (z-index) : la coupure franche donne
   l'impression qu'il regarde par-dessus le bord. */
.peek{
  position:absolute;
  z-index:1;
  right:calc(var(--gut) * -1);
  /* Les coudes descendent jusqu'à 91 % de la hauteur de l'image : la
     coupure doit donc rester dans les tout derniers pour-cent, sinon elle
     tranche les bras. */
  bottom:-.6rem;
  width:min(56vw, 17rem);
  height:auto;
  pointer-events:none;
  user-select:none;
}
.foot{ position:relative; z-index:2; }

/* L'astérisque tourne à côté du titre, plus au-dessus.
   Sa hauteur est calée sur la hauteur d'encre du titre sur deux lignes :
   1 ligne (line-height .88) + hauteur de capitale (~.7) ≈ 1.58em.
   Calculé depuis --t-xl, donc il suit le titre à toutes les tailles. */
.contact__head{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:clamp(.9rem, 3.5vw, 2rem);
  margin-bottom:clamp(1rem, 3svh, 2.4rem);
}
.aster--side{
  flex:none;
  width:calc(var(--t-xl) * 1.58);
  height:calc(var(--t-xl) * 1.58);
  color:var(--jaune);
  animation:spin 26s linear infinite;
  transform-origin:50% 50%;
  will-change:transform;
}
.contact .title{ color:var(--blanc); text-align:left; }

.contact .serif--light{ margin-bottom:clamp(1.4rem, 3.6svh, 3rem); max-width:34rem; }
.contact .stamp--inline{ margin-top:clamp(1.4rem, 3svh, 2.6rem); }

/* Chaque filet doit avoir la même respiration au-dessus et en dessous :
   c'est le padding des <li> qui la donne, des deux côtés. Un padding-top
   supplémentaire sur la liste décalait la seule première ligne. */
.coord{
  width:100%;
  max-width:34rem;
  display:grid;
  border-top:1px solid rgba(255,255,255,.3);
}
.coord li{
  display:flex; flex-direction:column; align-items:center; gap:.15rem;
  /* Respiration proportionnelle à la hauteur de l'écran : la section tient
     sur un seul écran, un espacement en dur la ferait déborder sur un écran
     court et resterait avare sur un grand. */
  padding:clamp(.5rem, 1.3svh, 1.05rem) 0;
  border-bottom:1px solid rgba(255,255,255,.18);
}
.coord span{
  font-family:var(--ff-title); font-weight:700;
  font-size:.58rem; letter-spacing:.18em; text-transform:uppercase;
  color:var(--jaune);
}
.coord a{
  font-family:var(--ff-title); font-weight:700;
  font-size:1rem; letter-spacing:-.01em;
  text-decoration:none;
  border-bottom:2px solid transparent;
  transition:border-color .2s ease;
}
.coord a:hover{ border-bottom-color:var(--jaune); }

.foot{
  flex:none;
  margin-inline:calc(var(--gut) * -1);
  background:var(--noir);
  color:var(--creme);
  padding:1.1rem var(--gut);
  display:grid; gap:.7rem; justify-items:center; text-align:center;
}
.brand{ display:block; line-height:0; text-decoration:none; }
.brand--foot img{ height:2rem; width:auto; max-width:none; }
.foot__nav{ display:flex; gap:1.1rem; flex-wrap:wrap; justify-content:center; }
.foot__nav a{
  font-family:var(--ff-title); font-weight:700; font-size:.72rem;
  text-transform:uppercase; letter-spacing:.1em; text-decoration:none;
  color:rgba(246,243,236,.75);
}
.foot__nav a:hover{ color:var(--jaune); }
.foot__legal{ font-size:.66rem; color:rgba(246,243,236,.45); }

/* =============================================================
   13. RÉVÉLATION AU SCROLL
   ============================================================= */
/* Apparition volontairement posée : 1,1 s de fondu et une course un peu plus
   longue (24 px). Le décalage entre éléments voisins est donné par le script
   (--d), à 110 ms — c'est lui qui fait lire la section de haut en bas. */
.reveal{ opacity:0; transform:translateY(24px); }
.reveal.is-in{
  opacity:1; transform:none;
  transition:opacity 1.1s ease, transform 1.1s cubic-bezier(.2,.8,.3,1);
  transition-delay:var(--d, 0ms);
}
/* le sticker photo garde son inclinaison pendant la révélation */
.cutout.reveal{ transform:translateY(24px) rotate(var(--rot)); }
.cutout.reveal.is-in{ transform:rotate(var(--rot)); }

/* =============================================================
   14. TABLETTE — min-width: 48em (768px)
   Le portfolio passe en grille fixe de trois colonnes.
   ============================================================= */
@media (min-width:48em){
  :root{ --gut:2.5rem; --gap-top:1.6rem; }

  .about{ padding-top:var(--gap-top); }

  .burger{ top:1.4rem; right:1.4rem; }
  .hero__stage{ --rig:min(60vw, 26rem); }
  .menu .stamps{ gap:3rem; padding-left:3rem; }

  .about__inner{
    display:grid;
    /* colonnes rééquilibrées : la photo n'était plus bornée par sa hauteur
       mais par sa colonne, trop étroite pour elle */
    grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);
    gap:2.5rem;
    align-items:center;
  }
  /* Dès que le texte passe en colonne, le titre est calé sur la largeur de
     CETTE COLONNE et non sur celle du viewport — c'est elle qui décide s'il
     tient en deux lignes. « LA CAMÉRA » mesure 5,59 fois le corps de la
     police : à 13,5 % de la colonne il en occupe 75 %, jamais plus.
     D'où le `nowrap` : « DERRIÈRE » puis « LA CAMÉRA », deux lignes quelle
     que soit la largeur. Sans conteneur de requête, on retombe sur --t-xl
     et l'ancien comportement, sans casse. */
  @supports (container-type:inline-size){
    .about__text{ container-type:inline-size; }
    .about .title--xl{ font-size:13.5cqw; white-space:nowrap; }
  }

  /* bornée à la fois en hauteur ET par la largeur de sa colonne : sinon
     l'image déborde vers la droite et vient coller le texte. */
  .cutout--portrait{
    height:auto;
    width:min(100%, clamp(12rem, 48svh, 26rem) * var(--ar));
    margin:0;
  }
  .cutout--portrait .cutout__img{ width:100%; height:auto; }

  .rail{
    /* ~10 % de moins dans les deux sens, forme inchangée : c'est le retrait
       de la bande qui recule, pas la composition des cartes */
    padding-block:1.1rem;
    padding-inline:calc(var(--gut) + 3.5%);
    display:grid;
    grid-template-columns:repeat(3, 1fr);
    /* La rangée est bornée à la hauteur disponible. Sans cela elle se
       dimensionne sur le contenu (`auto`) : dès que les vignettes ont porté
       de vraies images, donc une hauteur intrinsèque, les cartes ont grandi
       et sont passées sous le bouton. */
    grid-template-rows:minmax(0, 1fr);
    overflow:visible;
    scroll-snap-type:none;
  }
  .proj{ width:auto; margin-right:0; border-right:0; }
  .proj:last-child{ border-right:1px solid var(--bleu-filet); }
  .proj__title{ font-size:clamp(1.2rem, 2.7vw, 2.1rem); }

  .cutout__cap{ font-size:.64rem; }

  .coord li{ flex-direction:row; justify-content:space-between; align-items:baseline; }
  .coord a{ font-size:1.15rem; }

  .foot{
    /* 1fr auto 1fr : les deux colonnes latérales sont égales, donc le menu
       du milieu est centré sur la PAGE et non entre le logo et les mentions
       (ce que donnait `auto 1fr auto`). */
    grid-template-columns:1fr auto 1fr;
    justify-items:start; align-items:center; text-align:left;
    padding:1.5rem var(--gut);
    gap:1rem;
  }
  .foot__nav{ justify-content:center; }
  .foot__legal{ justify-self:end; }
}

/* =============================================================
   15. DESKTOP — min-width: 64em (1024px)
   Le menu devient un bloc fixe en HAUT À DROITE.
   Les contenus qui pourraient passer dessous reçoivent une
   gouttière droite, pour qu'aucun texte ne soit recouvert.
   ============================================================= */
@media (min-width:64em){
  :root{ --gut:4rem; --gap-top:2.2rem; --t-xl:clamp(3rem, 6vw, 5.5rem); }

  .burger{ display:none; }

  .menu{
    position:fixed;
    inset:2.2rem 2.2rem auto auto;   /* haut droite */
    z-index:40;
    width:auto; height:auto;
    padding:0;
    background:none;
    display:block;
    opacity:1;
    visibility:visible;
    pointer-events:auto;
  }
  .menu__close,
  .menu__base{ display:none; }
  .menu .stamps{
    display:flex;
    flex-direction:column;
    align-items:flex-end;
    gap:1.1rem;
    padding:0;
  }
  .menu .stamps .stamp{ margin:0; align-self:auto; }
  .menu .stamps .stamp:nth-child(1){ --rot:-5deg; margin-right:.9rem; }
  .menu .stamps .stamp:nth-child(2){ --rot: 4deg; margin-right:0; }
  .menu .stamps .stamp:nth-child(3){ --rot:-3deg; margin-right:1.4rem; }

  .hero__stage{ --rig:min(34vw, 28rem); }
  .hero__word{ font-size:clamp(9rem, 21vw, 20rem); }

  /* gouttière droite : le texte s'arrête avant les stickers du menu */
  .about__inner{ gap:5rem; padding-right:12rem; }
  /* en desktop la section est loin d'être pleine : on desserre franchement */
  .about .title{ margin-bottom:1.1rem; }
  .about .serif{ margin-bottom:1.8rem; }
  .about .stamp--inline{ margin:3rem 0 0; }   /* aligné au texte en desktop */
  .about__text p + p{ font-size:1rem; margin-top:1.2rem; }

  /* La Bonne Mère quitte la vignette et vient se coller à côté du titre,
     en haut à gauche. `position:relative` + `z-index` sur l'enveloppe : le
     sticker n'est plus positionné, il passerait sinon sous le quadrillage. */
  .work__top{
    position:relative;
    z-index:1;
    display:flex;
    align-items:flex-end;
    gap:clamp(1.25rem, 3vw, 2.5rem);
    width:100%;
    max-width:72rem;
    margin-inline:auto;
    padding-right:13rem;   /* place réservée aux stickers du menu */
  }
  .work__head{
    flex:0 1 auto;
    max-width:none;
    margin-inline:0;
    /* pas de gouttière à droite ici : c'est le sticker qui vient s'y coller */
    padding:.8rem 0 1.6rem var(--gut);
  }
  .work__grid{
    background-image:
      repeating-linear-gradient(to right,  var(--bleu-filet) 0 1px, transparent 1px 25%),
      repeating-linear-gradient(to bottom, var(--bleu-filet) 0 1px, transparent 1px 11rem);
  }

  .proj{ padding:1.3rem 1.6rem 1.5rem; }
  /* Côte à côte, les cartes n'ont pas le même nombre de lignes de titre ni de
     description : sans plancher, les vignettes — qui absorbent le reste de la
     hauteur — démarraient et finissaient à des niveaux différents. Ces deux
     minimums (2 lignes de titre, 3 de description) les réalignent.
     Exprimés en `em` : ils suivent le corps du texte à toutes les tailles. */
  .proj__title{ font-size:2.2rem; min-height:1.8em; }
  .proj__desc{ font-size:.92rem; min-height:4.35em; }

  /* centré comme les autres boutons du site, et décollé du bord bas */
  .work__foot{ justify-content:center; padding:1.2rem var(--gut) 3.1rem; }
  .cutout--bless{ display:block; position:static; flex:none; width:6.2rem; margin-bottom:1.2rem; }
  .cutout__cap{ font-size:.74rem; padding:.4rem .66rem .44rem; }

  .contact__in{ padding-block:2rem .8rem; }
  /* plus grand et légèrement décollé du bord, comme sur le repère fourni */
  .peek{ width:min(24vw, 24rem); right:.5rem; bottom:-1rem; }
  .contact .serif--light{ margin-bottom:clamp(2rem, 4svh, 3.4rem); }
  .coord{ max-width:38rem; }
  .foot{ padding-block:1.9rem; }
  .foot__nav{ gap:1.6rem; }
}

/* =============================================================
   16. TRÈS GRAND ÉCRAN
   ============================================================= */
@media (min-width:100em){
  .hero__stage{ --rig:28rem; }
  .hero__word{ font-size:22rem; }
  .menu{ inset:2.8rem 3rem auto auto; }
}

/* =============================================================
   16 bis. TÉLÉPHONES UN PEU COURTS — la zone grise
   Entre 44em et 50em de haut, le palier « écrans peu hauts » ne se
   déclenche pas encore alors que la section À propos, avec son texte en
   quatre blocs, arrive à ras bord. On y regagne une vingtaine de pixels.
   Réservé au dessin mobile : au-delà de 48em la photo est dimensionnée
   en largeur, lui réimposer une hauteur casserait son calage.
   ============================================================= */
@media (max-width:47.99em) and (max-height:50em){
  .about{ padding-top:.5rem; }
  .cutout--portrait{ height:clamp(5.5rem, 22svh, 12rem); }
  .about__text p + p{ margin-top:.8rem; }
}

/* =============================================================
   17. ÉCRANS PEU HAUTS (paysage mobile, petits portables)
   ============================================================= */
@media (max-height:44em){
  :root{ --t-xl:clamp(1.9rem, 8vw, 3.2rem); }
  /* soupape : ici seulement, le contenu peut réellement ne pas tenir */
  .snap__in{ max-height:100%; overflow-y:auto; scrollbar-width:none; }
  .snap__in::-webkit-scrollbar{ display:none; }
  .serif{ font-size:clamp(1rem, 3.6vw, 1.25rem); }
  /* Ce palier avait été calibré sur un texte À propos plus long. Depuis qu'il
     a été raccourci il laissait 65 px inutilisés en 373 × 675, avec une photo
     ratatinée à 116 px. On lui rend sa place. */
  .about__text p + p{ font-size:.88rem; margin-top:.5rem; }
  /* Ici .snap__in devient un conteneur de défilement (la soupape), et un
     conteneur en `overflow` DÉCOUPE tout ce qui sort de sa boîte — y compris
     le liseré blanc de 7 px du bouton, qui est une ombre et ne compte donc
     pas dans la mise en page. On lui réserve la place en dur. */
  .about__text{ padding-bottom:1rem; }
  .cutout--portrait{ height:clamp(4.5rem, 22svh, 12rem); margin-bottom:1.4rem; }
  /* Le vide du haut passe en bas : le bloc remonte, le bouton respire.
     `flex-start` plutôt que le centrage : sur ces hauteurs, si le contenu
     venait malgré tout à déborder, le centrage rognerait les DEUX bouts —
     ici il ne peut déborder que vers le bas, là où la soupape de
     défilement le rattrape. */
  .about{ padding-top:.25rem; padding-bottom:2rem; justify-content:flex-start; }
  .about .title{ margin-bottom:.6rem; }
  .about .serif{ margin-bottom:.9rem; }
  .about .stamp--inline{ margin:1rem auto 0; }
  /* plus de bride sur --rig : la composition occupe la place qui reste,
     elle ne se ratatine plus sur un téléphone un peu court */
  .hero__word{ font-size:clamp(3rem, min(30vw, 26svh), 10rem); }
  .hero__base{ margin-top:.5rem; margin-bottom:.6rem; }
  .ticker__row{ font-size:clamp(1.1rem, 4.5vw, 1.6rem); }
  .work__head{ padding-bottom:.8rem; }
  .proj__title{ font-size:1.3rem; margin-bottom:.6rem; }
  .proj__desc{ font-size:.78rem; }
  .foot{ padding-block:.8rem; gap:.45rem; }
  .coord li{ padding:.45rem 0; }
  .menu .stamps{ gap:1.4rem; }
}

/* Le contact échappe à la soupape tant que la hauteur reste raisonnable :
   son contenu est court, et un conteneur en `overflow` découperait l'image
   qui déborde volontairement sous le pied de page. En dessous de 37em
   (téléphone en paysage), le contenu ne tient réellement plus et la soupape
   reprend la main : mieux vaut une image coupée qu'un bouton inatteignable. */
@media (max-height:44em) and (min-height:37em){
  .contact__in{ max-height:none; overflow:visible; }
}

/* =============================================================
   18. TÉLÉPHONES TRÈS COURTS (≤ 41em, soit 656 px)
   Placé APRÈS le palier ci-dessus : à spécificité égale, c'est la
   dernière règle qui gagne. Sous cette hauteur le texte occupe presque
   tout, la photo cède le pas — sinon le liseré du bouton passe sous le
   bord de la section.
   ============================================================= */
@media (max-width:47.99em) and (max-height:41em){
  .cutout--portrait{ height:clamp(3.5rem, 17svh, 8rem); margin-bottom:1rem; }
  .about__text p + p{ font-size:.84rem; margin-top:.45rem; }
  .about .serif{ font-size:1rem; margin-bottom:.7rem; }
}

/* =============================================================
   19. ACCESSIBILITÉ — mouvement réduit
   ============================================================= */
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .reveal{ opacity:1; transform:none; }
  .cutout.reveal{ transform:rotate(var(--rot)); }
  .rail{ scroll-behavior:auto; }
}

/* =============================================================
   20. PAGE À PROPOS (apropos.html)
   Page de lecture, pas de diaporama : pas de `.snap`, donc aucun
   point d'aimantation — le défilement y est normal.
   ============================================================= */
html.page{ scroll-snap-type:none; }

/* Le pied de page est calé sur les gouttières d'une section dans l'accueil ;
   ici il est enfant direct du corps et n'a rien à rattraper. */
.page .foot{ margin-inline:0; }

/* ---------- en-tête : portrait + accroche ---------- */
.intro{
  background:var(--creme);
  padding:calc(var(--gap-top) + 2.6rem) var(--gut) clamp(1.5rem, 4vw, 2.5rem);
}
.intro__in{
  max-width:72rem;
  margin-inline:auto;
  display:grid;
  gap:clamp(1.2rem, 4vw, 2rem);
}
.intro__photo{ margin:0; }
.intro__photo img{ width:min(100%, 22rem); height:auto; display:block; }
.intro .title--xl{
  color:var(--noir);
  /* plus petit et plus aéré que le titre standard : sur trois lignes en
     capitales, le `line-height: .88` du site faisait se toucher les lignes. */
  font-size:clamp(2rem, 8.5vw, 4.4rem);
  line-height:1.05;
  margin-bottom:1.1rem;
}
.intro__salut{ font-size:.75em; }        /* l'emoji ne doit pas peser autant qu'une capitale */
.intro .serif{ max-width:30rem; }
.retour{
  color:var(--bleu); text-decoration:none;
  border-bottom:1px solid rgba(0,124,193,.35);
}
.retour:hover{ border-bottom-color:var(--bleu); }

/* ---------- le texte ---------- */
.prose{
  background:var(--creme);
  padding:0 var(--gut) clamp(2.5rem, 6vw, 4rem);
}
.bloc{
  max-width:46rem;
  margin-inline:auto;
  padding-block:clamp(1.6rem, 4vw, 2.4rem);
  border-top:1px solid var(--bleu-filet);
}
.bloc__titre{
  font-family:var(--ff-title); font-weight:900;
  text-transform:uppercase;
  font-size:clamp(1.3rem, 3.4vw, 1.9rem);
  line-height:1; letter-spacing:-.025em;
  color:var(--bleu);
  margin-bottom:.9rem;
}
.prose p{
  font-size:1rem; line-height:1.6;
  color:rgba(35,31,32,.88);
}
.prose p + p{ margin-top:.9rem; }

/* la liste des métiers et des partenaires */
.metiers{ margin:1.2rem 0 1.4rem; display:grid; gap:.7rem; }
.metiers li{ position:relative; padding-left:1.7rem; line-height:1.5; }
.metiers li::before{
  content:"✳";
  position:absolute; left:0; top:.05em;
  color:var(--jaune); font-size:1.05rem; line-height:1;
}
.metiers b{ font-family:var(--ff-title); font-weight:700; color:var(--bleu); }
.metiers span{ color:rgba(35,31,32,.8); }
.metiers span::before{ content:" — "; color:rgba(35,31,32,.4); }

/* les boutons posés dans le fil du texte, centrés comme partout ailleurs */
.bloc .stamp--inline{
  display:flex; width:max-content; max-width:100%;
  margin:2rem auto 0;
}

/* ---------- ils ont travaillé avec moi ---------- */
.marques{
  background:var(--bleu);
  color:var(--blanc);
  padding:clamp(2.6rem, 7vw, 4.5rem) var(--gut);
}
.marques__in{ max-width:72rem; margin-inline:auto; text-align:center; }
.marques .title--xl{ color:var(--blanc); }
.marques__grille{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(7rem, 1fr));
  align-items:center;
  gap:clamp(1.6rem, 4vw, 3rem);
  margin-top:clamp(1.8rem, 5vw, 3rem);
}
.marques__item{ display:flex; align-items:center; justify-content:center; }
/* Les logos arrivent en couleur et sur fond transparent : `brightness(0)`
   les écrase en noir, `invert(1)` les repasse en blanc — la transparence,
   elle, est conservée. Aucun fichier à retoucher. */
.marques__item img{
  max-width:100%;
  max-height:2.8rem;
  width:auto; height:auto;
  filter:brightness(0) invert(1);
  opacity:.8;
  transition:opacity .25s ease;
}
.marques__item:hover img{ opacity:1; }
/* Les logos en hauteur (Danone, Sun Valley) paraissent deux fois plus petits
   que les logos en largeur à hauteur égale : on leur en donne un peu plus. */
.marques__item--haut img{ max-height:3.6rem; }

@media (min-width:64em){
  .intro__in{
    grid-template-columns:minmax(0, .85fr) minmax(0, 1.15fr);
    /* `end` et non `center` : le bas de la photo tombe exactement sur la
       dernière ligne de l'accroche, les deux colonnes se terminent ensemble. */
    align-items:end;
    gap:4rem;
    padding-right:12rem;   /* les stickers du menu sont fixés en haut à droite */
  }
  .intro__photo img{ width:100%; }
  .marques__item img{ max-height:3.2rem; }
  .marques__item--haut img{ max-height:4.2rem; }
}

/* =============================================================
   21. PAGE CONTACT (contact.html)
   ============================================================= */
.contact-page{
  background:var(--bleu);
  color:var(--blanc);
  padding:calc(var(--gap-top) + 2.2rem) var(--gut) clamp(2.5rem, 6vw, 4rem);
}
.contact-page__in{ max-width:72rem; margin-inline:auto; }
.contact-page__head{ text-align:center; margin-bottom:clamp(1.8rem, 5vw, 2.8rem); }
.contact-page__head .title--xl{ color:var(--blanc); text-align:left; }
.contact-page__head .serif--light{ margin:0 auto; max-width:34rem; }
.retour--light{ color:var(--blanc); border-bottom-color:rgba(255,255,255,.45); }
.retour--light:hover{ border-bottom-color:var(--blanc); }

.contact-page__grille{ display:grid; gap:clamp(1.5rem, 4vw, 3rem); align-items:start; }

/* ---------- la carte du formulaire ---------- */
.carte{
  background:var(--creme);
  color:var(--noir);
  border-radius:1rem;
  padding:clamp(1.3rem, 4vw, 2.3rem);
  box-shadow:0 1.2rem 2.4rem rgba(0,0,0,.18);
}
.carte__titre{
  font-family:var(--ff-title); font-weight:900;
  text-transform:uppercase;
  font-size:clamp(1.25rem, 3.4vw, 1.7rem);
  letter-spacing:-.025em; line-height:1;
  color:var(--bleu);
  margin-bottom:1.3rem;
}
.form__ligne{ display:grid; gap:.35rem; margin-bottom:1.1rem; }
.form__label{
  font-family:var(--ff-title); font-weight:700;
  font-size:.66rem; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(35,31,32,.65);
}
.form__champ{
  font-family:var(--ff-body); font-weight:400; font-size:1rem;
  color:var(--noir);
  background:var(--blanc);
  border:1px solid rgba(35,31,32,.22);
  border-radius:.5rem;
  padding:.7rem .85rem;
  width:100%;
  transition:border-color .2s ease, box-shadow .2s ease;
}
.form__champ::placeholder{ color:rgba(35,31,32,.38); }
.form__champ:focus{
  outline:none;
  border-color:var(--bleu);
  box-shadow:0 0 0 3px rgba(0,124,193,.18);
}
.form__champ--zone{ resize:vertical; min-height:8.5rem; line-height:1.5; }
.form__champ[aria-invalid="true"]{ border-color:#c0392b; box-shadow:0 0 0 3px rgba(192,57,43,.14); }

/* Piège à robots : retiré de l'affichage ET du parcours clavier, mais
   pas en `display:none` — certains robots ignorent les champs masqués. */
.form__miel{
  position:absolute; width:1px; height:1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap;
}

.form__envoi{
  margin-top:.3rem;
  border:0; cursor:pointer;
  display:flex; width:max-content; max-width:100%;
}
.form__etat{
  margin-top:1rem;
  font-size:.92rem; line-height:1.45;
  min-height:1.3em;
  color:rgba(35,31,32,.75);
}
.form__etat[data-ton="ok"]{ color:#15703a; font-weight:700; }
.form__etat[data-ton="ko"]{ color:#c0392b; font-weight:700; }
.form__secours{ color:var(--bleu); font-weight:700; }

/* ---------- la colonne des coordonnées ---------- */
.contact-page__coord{ position:relative; }
.contact-page__coord .kicker{ margin-bottom:1rem; }
.contact-page__coord .coord{ max-width:none; }
/* ici l'image n'est plus un débordement mais une signature de fin de colonne */
.peek--page{
  position:static;
  display:block;
  width:min(72%, 14rem);
  margin:2rem 0 0 auto;
}

@media (min-width:64em){
  .contact-page__grille{ grid-template-columns:minmax(0, 1.2fr) minmax(0, .8fr); }
  .contact-page__head{ padding-right:12rem; }   /* les stickers du menu */
  .peek--page{ width:min(100%, 16rem); }
}

/* =============================================================
   22. PAGE PORTFOLIO (portfolio.html)
   Les cartes reprennent exactement le dessin de la section portfolio
   de l'accueil : filets fins, fond opaque, vignette encadrée. Ici
   elles forment un vrai tableau — les filets du conteneur et ceux des
   cartes ne se doublent jamais (haut + gauche sur le conteneur,
   droite + bas sur chaque carte).
   ============================================================= */
.folio{
  position:relative;
  background:var(--bleu-pale);
  color:var(--bleu);
  padding:calc(var(--gap-top) + 2.2rem) var(--gut) clamp(2.5rem, 6vw, 4rem);
}
.folio > .work__grid{ position:absolute; inset:0; }
.folio__in{ position:relative; max-width:72rem; margin-inline:auto; }

.folio__head{ position:relative; margin-bottom:clamp(1.6rem, 4vw, 2.4rem); }
.folio__head .title--xl{ color:var(--bleu); line-height:1.02; margin-bottom:1rem; }
.folio__head .serif{ max-width:34rem; }
.cutout--folio{ display:none; }

/* ---------- les projets, posés sur la grille ---------- */
.folio__liste{
  display:grid;
  gap:clamp(1.4rem, 3vw, 2.6rem);
  /* `start` et non l'étirement par défaut : une carte décalée vers le bas
     doit garder sa hauteur et descendre en entier, pas se faire raboter
     pour finir sur la même ligne que ses voisines. */
  align-items:start;
}
.projet{
  position:relative;
  display:flex;
  flex-direction:column;
  padding:1.1rem 1.2rem 1.3rem;
  /* chaque carte est un cadre complet : les cartes ne se touchent plus,
     le quadrillage de la page passe entre elles */
  border:1px solid var(--bleu-filet);
  /* opaque, comme sur l'accueil : le quadrillage de fond doit passer
     AUTOUR des cartes, pas au travers */
  background:var(--bleu-pale);
  transition:background .3s ease;
}
.projet:hover{ background:rgba(255,255,255,.45); }

.projet__cat{
  flex:none;
  font-family:var(--ff-title); font-weight:700;
  font-size:.6rem; letter-spacing:.16em; text-transform:uppercase;
  opacity:.7; margin-bottom:.4rem;
}
.projet__titre{
  flex:none;
  font-family:var(--ff-title); font-weight:900;
  font-size:clamp(1.45rem, 4vw, 2rem);
  line-height:.9; letter-spacing:-.03em;
  text-transform:uppercase;
  color:var(--bleu);
  margin-bottom:.9rem;
}
.projet__image{
  position:relative;
  flex:none;
  margin-bottom:.9rem;
  overflow:hidden;
  background:rgba(0,124,193,.07);
  border:1px solid var(--bleu-filet);
}
.projet__image img{
  display:block;
  width:100%; height:100%;
  aspect-ratio:16/9;
  object-fit:cover;
}
.projet__desc{
  flex:1;
  font-size:.86rem; line-height:1.45;
  color:rgba(0,124,193,.9);
  margin-bottom:.9rem;
}
/* les postes tenus : une ligne discrète, dans l'esprit des kickers du site,
   plutôt que des pastilles qui juraient avec les filets */
.projet__faits{
  flex:none;
  display:flex; flex-wrap:wrap;
  font-family:var(--ff-title); font-weight:700;
  font-size:.58rem; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(0,124,193,.6);
}
.projet__faits li + li::before{ content:"·"; margin:0 .4rem; }

/* ---------- l'appel de fin ---------- */
.folio__fin{ margin-top:clamp(2rem, 5vw, 3rem); text-align:center; }
.folio__fin .serif{ margin-bottom:1.2rem; }
.folio__fin .stamp{ display:flex; width:max-content; max-width:100%; margin-inline:auto; }

@media (min-width:48em){
  .folio__liste{ grid-template-columns:repeat(2, minmax(0, 1fr)); }
  /* une colonne sur deux descend : la ligne cesse d'être un alignement
     militaire, on retrouve le décousu du collage */
  .projet:nth-child(2n){ margin-top:clamp(1.5rem, 4vw, 3rem); }
}

@media (min-width:64em){
  .folio__liste{ grid-template-columns:repeat(3, minmax(0, 1fr)); }
  /* en trois colonnes, c'est celle du milieu qui décroche */
  .projet:nth-child(2n){ margin-top:0; }
  .projet:nth-child(3n+2){ margin-top:clamp(2rem, 5vw, 3.6rem); }
  .projet{ padding:1.4rem 1.6rem 1.6rem; }
  /* Les cartes ne s'étirant plus, ce sont ces deux planchers qui leur
     donnent la même hauteur : deux lignes de titre, trois de description. */
  .projet__titre{ font-size:2rem; min-height:1.8em; }
  .projet__desc{ font-size:.92rem; min-height:4.4em; }
  .folio__head{ padding-right:13rem; }   /* les stickers du menu */
  .cutout--folio{
    display:block;
    position:absolute;
    right:0; bottom:0;
    width:7rem;
    --rot:6deg;
  }
}

/* =============================================================
   23. VISUELS — freiner la récupération au clic
   Voir la note dans js/main.js : c'est un garde-fou contre la copie
   de passage, pas une protection. Un fichier servi par le web est
   téléchargeable, toujours.
   ============================================================= */
img, video{
  -webkit-user-drag:none;
  user-select:none;
}
/* Une couche transparente au-dessus des visuels : l'appui long sur
   mobile et le clic droit tombent sur elle, pas sur le fichier.
   `:where()` annule la spécificité : cette règle ne fait qu'assurer un
   contexte de positionnement, elle ne doit JAMAIS écraser un
   positionnement voulu ailleurs — elle avait remis en `relative` le
   sticker du portfolio, qui doit être `absolute`. */
:where(.projet__image, .proj__thumb, .cutout){ position:relative; }
.projet__image::after,
.proj__thumb::after,
.cutout::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:2;
}
/* …sauf là où elle gênerait : le cartouche du sticker doit rester lisible
   au-dessus, et le repère d'image manquante cliquable en développement. */
.cutout__cap{ z-index:3; }

/* =============================================================
   24. PAGE PROJET (projet-solace.html)
   ============================================================= */
/* Carte cliquable : le lien est sur le titre — donc lisible par un
   lecteur d'écran — et sa zone active est étirée à toute la carte.
   z-index 3 : il doit passer AU-DESSUS du calque anti-copie (2). */
.projet__lien{ color:inherit; text-decoration:none; }
.projet__lien::after{ content:""; position:absolute; inset:0; z-index:3; }
.projet:has(.projet__lien):hover{ background:rgba(255,255,255,.7); }
/* Mêmes cartes sur l'accueil (`.proj`) : elles n'étaient pas positionnées,
   la zone active du lien n'aurait eu aucun repère et se serait étirée sur
   l'ancêtre positionné le plus proche — la section entière. */
.proj:has(.projet__lien){ position:relative; }

.projet-page{
  position:relative;
  background:var(--bleu-pale);
  color:var(--bleu);
  padding:calc(var(--gap-top) + 2.2rem) var(--gut) clamp(2.5rem, 6vw, 4rem);
}
.projet-page > .work__grid{ position:absolute; inset:0; }
.projet-page__in{ position:relative; max-width:72rem; margin-inline:auto; }

.projet-page__head{ margin-bottom:clamp(1.6rem, 4vw, 2.4rem); }
.projet-page__cat{
  font-family:var(--ff-title); font-weight:700;
  font-size:.66rem; letter-spacing:.16em; text-transform:uppercase;
  opacity:.7; margin-bottom:.5rem;
}
.projet-page__head .title--xl{ color:var(--bleu); line-height:1; margin-bottom:.9rem; }
.projet-page__client{ color:rgba(0,124,193,.45); }
.projet-page__head .serif{ max-width:36rem; }

/* ---------- les lecteurs ---------- */
.film{ margin:0; }
.film__cadre{
  position:relative;
  background:var(--noir);
  border:1px solid var(--bleu-filet);
  overflow:hidden;
}
/* Lecteur YouTube chargé au clic : d'ici là, l'affiche du film et un bouton lecture.
   Rien n'est demandé à YouTube tant que le visiteur n'a pas cliqué (ni cookie, ni requête). */
.film__lecteur, .film__cadre iframe{ display:block; width:100%; aspect-ratio:16 / 9; border:0; }
.film--vertical .film__lecteur, .film--vertical .film__cadre iframe{ aspect-ratio:4 / 5; }
.film__lecteur{ position:relative; cursor:pointer; background:var(--noir); }
.film__lecteur img{ display:block; width:100%; height:100%; object-fit:cover; }
.film__play{
  position:absolute; left:50%; top:50%; display:grid; place-items:center;
  width:clamp(56px, 9vw, 84px); aspect-ratio:1; translate:-50% -50%;
  background:var(--bleu); color:var(--creme, #fff);
  transition:background-color .18s, scale .18s var(--sortie, ease-out);
}
.film__play svg{ width:44%; fill:currentColor; translate:6% 0; }
.film__lecteur:hover .film__play, .film__lecteur:focus-visible .film__play{ background:var(--jaune); color:var(--noir); scale:1.08; }
.film__lecteur:focus-visible{ outline:3px solid var(--jaune); outline-offset:3px; }
@media (prefers-reduced-motion:reduce){ .film__play{ transition:none; } .film__lecteur:hover .film__play{ scale:none; } }
.film__legende{
  display:flex; flex-wrap:wrap; gap:.5rem 1rem;
  justify-content:space-between; align-items:baseline;
  margin-top:.7rem;
  font-family:var(--ff-title); font-weight:700;
  font-size:.66rem; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(0,124,193,.75);
}
.projet-page__film{ margin-bottom:clamp(1.8rem, 4vw, 2.6rem); }

.prose--projet{ background:none; padding:0; }
.prose--projet .bloc{ border-top-color:var(--bleu-filet); }
.prose--projet .bloc__titre{ color:var(--bleu); }
.prose--projet p{ color:rgba(35,31,32,.85); }
.prose--projet b{ font-weight:700; color:var(--bleu); }

.projet-page__autres{ margin-top:clamp(1.6rem, 4vw, 2.4rem); }
.projet-page__autres .bloc__titre{ margin-bottom:1.2rem; }
.projet-page__duo{ display:grid; gap:clamp(1.4rem, 3vw, 2.4rem); }

/* ---------- le générique ---------- */
.generique{
  margin-top:clamp(2rem, 5vw, 3rem);
  border-top:1px solid var(--bleu-filet);
  /* fond opaque : sans lui, le quadrillage de la page passe derrière le
     tableau et ses lignes traversent les noms */
  position:relative;
  background:var(--bleu-pale);
  padding-block:clamp(1.4rem, 3vw, 2rem) clamp(.8rem, 2vw, 1.2rem);
}
.generique__liste{ display:grid; gap:.55rem; max-width:46rem; }
.generique__liste li{
  display:flex; flex-wrap:wrap; gap:.2rem .8rem;
  justify-content:space-between;
  /* `baseline` : la fonction et le nom n'ont pas le même corps, sans cela
     chacun se posait en haut de sa propre boîte et le petit texte montait */
  align-items:baseline;
  padding-bottom:.55rem;
  border-bottom:1px solid var(--bleu-filet);
}
.generique__liste span{
  font-family:var(--ff-title); font-weight:700;
  font-size:.64rem; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(0,124,193,.65);
}
.generique__liste b{
  font-family:var(--ff-title); font-weight:700;
  font-size:.95rem; color:var(--bleu);
}

@media (min-width:48em){
  /* le format vertical ne doit pas occuper autant de large qu'un 16:9.
     `center` : le 16:9, bien plus court, se cale au milieu du vertical
     plutôt que de s'aligner sur son bord haut. */
  .projet-page__duo{ grid-template-columns:minmax(0, .8fr) minmax(0, 1.2fr); align-items:center; }
}

@media (min-width:64em){
  .projet-page__head{ padding-right:13rem; }   /* les stickers du menu */
  .projet-page__film{ margin-bottom:2.8rem; }
}

/* =============================================================
   25. PAGE MENTIONS LÉGALES (mentions-legales.html)
   ============================================================= */
/* `a{ color:inherit }` s'applique à tout le site : un lien posé dans un
   paragraphe y est invisible. Les mentions légales en contiennent
   plusieurs (contact, exercice des droits RGPD) — il leur faut un
   repère explicite, sinon personne ne les voit. */
.lien{
  color:var(--bleu);
  text-decoration:none;
  border-bottom:1px solid rgba(0,124,193,.45);
}
.lien:hover{ border-bottom-color:var(--bleu); }

/* Le tableau étiquette/valeur est repris du générique des pages projet.
   Posé dans un `.bloc`, qui porte déjà son filet en haut, il ne doit ni
   en ajouter un second ni reprendre sa marge de section. */
.bloc .generique{
  margin-top:0;
  border-top:0;
  padding-block:0;
}
