/* ══════════════════════════════════════════════════════════════
   MATÉRIEL — feuille commune aux pages de case study.
   Reprend les tokens de l'index, ajoute la typographie d'article.
   ══════════════════════════════════════════════════════════════ */

@font-face{font-family:'PP Neue Machina';src:url('../fonts/PPNeueMachina-Light.woff2') format('woff2');
  font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:'PP Neue Machina';src:url('../fonts/PPNeueMachina-Regular.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'PP Neue Machina';src:url('../fonts/PPNeueMachina-Ultrabold.woff2') format('woff2');
  font-weight:800;font-style:normal;font-display:swap}

:root{
  --noir:#0A0A0A; --encre:#141414; --rouge:#FF1D2D; --rouge-sourd:#8F0F14;
  --craie:#F2F0EC; --gris:#7A7A7A;
  --marge:clamp(16px,3.5vw,64px);
  --maxw:clamp(980px,74vw,1320px);
  --texte-maxw:68ch;
  --rayon:8px;
  --display:'PP Neue Machina',system-ui,sans-serif;
  --texte:'Space Grotesk',system-ui,sans-serif;
  --mono:'Space Mono',ui-monospace,monospace;
  --ease:cubic-bezier(.7,0,.2,1);
}

*{box-sizing:border-box;margin:0;padding:0}
:focus-visible{outline:2px solid var(--rouge);outline-offset:3px}
html{scroll-behavior:smooth}
body{
  background:var(--noir);color:var(--craie);font-family:var(--texte);
  font-size:clamp(16px,.95vw,20px);line-height:1.7;-webkit-font-smoothing:antialiased;
  overflow-x:hidden;cursor:none;
}
a{color:inherit;text-decoration:none}
img,video{max-width:100%;display:block}

/* ── Grain ────────────────────────────────────────────────── */
.grain{
  position:fixed;inset:-50%;z-index:9998;pointer-events:none;opacity:.045;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:grain 1s steps(4) infinite;
}
@keyframes grain{
  0%{transform:translate(0,0)}25%{transform:translate(-2%,1%)}
  50%{transform:translate(1%,-2%)}75%{transform:translate(-1%,-1%)}
  100%{transform:translate(0,0)}
}
/* Voir index.html : `difference` garde le curseur lisible sur le rouge
   comme sur le noir. Il n'est neutralisé qu'au-dessus d'un visuel importé,
   où le rouge s'inverserait en cyan — classe posée par case.js. */
.cur{
  position:fixed;top:0;left:0;width:10px;height:10px;background:var(--rouge);
  z-index:9999;pointer-events:none;mix-blend-mode:difference;
  transition:width .25s var(--ease),height .25s var(--ease);
  transform:translate(-50%,-50%);
}
.cur.big{width:56px;height:56px}
.cur.sur-visuel{mix-blend-mode:normal}
/* Le `cursor:none` du body est hérité ; la feuille du navigateur pose
   `cursor:pointer` sur les liens et les boutons, et une règle l'emporte
   sur un héritage. Sans ça la flèche native reste visible. */
a,button{cursor:none}
/* Sur un visuel, le clic n'ouvre pas une page : il agrandit l'image.
   Un « + » le dit, comme sur le carrousel de l'accueil. */
.cur::before,.cur::after{
  content:'';position:absolute;top:50%;left:50%;background:var(--noir);
  transform:translate(-50%,-50%) scale(0);
  transition:transform .25s var(--ease);
}
.cur::before{width:18px;height:2px}
.cur::after{width:2px;height:18px}
.cur.zoom::before,.cur.zoom::after{transform:translate(-50%,-50%) scale(1)}

/* ── Visionneuse ──────────────────────────────────────────────
   Construite par case.js pour ne pas la tripler dans les trois pages. */
.loupe{
  position:fixed;inset:0;z-index:200;background:rgba(10,10,10,.94);
  display:grid;place-items:center;padding:clamp(20px,5vw,72px);
  opacity:0;visibility:hidden;
  /* visibility bascule instantanément à l'ouverture (sinon le bouton
     n'est pas focusable) et attend la fin du fondu à la fermeture. */
  transition:opacity .4s var(--ease),visibility 0s linear .4s;
  backdrop-filter:blur(8px);
}
.loupe[open]{opacity:1;visibility:visible;transition:opacity .4s var(--ease),visibility 0s}
.loupe img{
  max-width:100%;max-height:80vh;display:block;object-fit:contain;
  border-radius:var(--rayon);clip-path:inset(0 round var(--rayon));
}
.loupe-barre{
  position:absolute;top:clamp(18px,3vw,34px);left:var(--marge);right:var(--marge);
  display:flex;justify-content:space-between;gap:20px;align-items:flex-start;
  font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--gris);
}
.loupe-barre b{color:var(--craie);font-weight:400}
.loupe button{
  font:inherit;letter-spacing:.14em;color:var(--gris);background:none;
  border:1px solid var(--encre);padding:8px 14px;cursor:none;
  transition:color .3s var(--ease),border-color .3s var(--ease);
}
.loupe button:hover{color:var(--rouge);border-color:var(--rouge)}
.loupe-nav{
  position:absolute;bottom:clamp(18px,3vw,34px);left:50%;transform:translateX(-50%);
  display:flex;gap:10px;
}

/* ── Chrome ───────────────────────────────────────────────── */
/* Même œil que la page d'accueil : c'est lui le retour. */
.logo{
  position:fixed;top:clamp(22px,2.4vw,44px);left:var(--marge);z-index:100;
  width:clamp(30px,2.2vw,40px);aspect-ratio:1;background:var(--rouge);
  display:block;overflow:hidden;
}
.logo .pupille{
  position:absolute;top:50%;left:0;width:32%;height:32%;background:var(--noir);
  animation:scrute 9s cubic-bezier(.16,1,.3,1) infinite;
}
/* Translate relatifs à la pupille (32 % du carré) : ces valeurs suivent
   celles de la page d'accueil, garder les deux en phase. */
@keyframes scrute{
  0%,16%  {transform:translate(40%,-41%)   scaleY(1)}
  19%,29% {transform:translate(170%,-41%)  scaleY(1)}
  30%     {transform:translate(170%,-41%)  scaleY(.115)}
  31%,38% {transform:translate(170%,-41%)  scaleY(1)}
  41%,49% {transform:translate(157%,3%)    scaleY(1)}
  52%,60% {transform:translate(70%,0%)     scaleY(1)}
  63%,72% {transform:translate(94%,-59%)   scaleY(1)}
  73%     {transform:translate(94%,-59%)   scaleY(.115)}
  74%,79% {transform:translate(94%,-59%)   scaleY(1)}
  82%,88% {transform:translate(176%,-9%)   scaleY(1)}
  91%,100%{transform:translate(40%,-41%)   scaleY(1)}
}
.logo:hover .pupille{animation-play-state:paused}
.status{
  position:fixed;top:clamp(22px,2.4vw,44px);right:var(--marge);z-index:100;
  font-family:var(--mono);font-size:clamp(10px,.68vw,12px);letter-spacing:.12em;
  text-transform:uppercase;display:flex;align-items:center;gap:8px;color:var(--craie);
}
.dot{width:7px;height:7px;background:var(--rouge);border-radius:50%;animation:pulse 1.6s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}}
.langue{
  margin-left:6px;font:inherit;letter-spacing:.12em;color:var(--gris);
  background:none;border:1px solid var(--encre);padding:3px 8px;cursor:none;
  transition:color .3s var(--ease),border-color .3s var(--ease);
}
.langue:hover{color:var(--rouge);border-color:var(--rouge)}

/* ── Structure ────────────────────────────────────────────── */
main{max-width:var(--maxw);margin-inline:auto;padding-inline:var(--marge)}
.label{
  font-family:var(--mono);font-size:clamp(11px,.72vw,14px);letter-spacing:.12em;
  text-transform:uppercase;color:var(--gris);
}

/* ── En-tête ──────────────────────────────────────────────── */
.entete{padding:clamp(96px,14vh,150px) 0 clamp(32px,4.5vh,54px)}
.entete h1{
  font-family:var(--display);font-weight:800;color:var(--rouge);
  font-size:clamp(36px,4.8vw,104px);line-height:.9;letter-spacing:-.035em;
  text-transform:uppercase;margin-top:clamp(12px,1.6vh,24px);
}
.chapo{font-size:clamp(17px,1.45vw,25px);line-height:1.45;max-width:38ch;
  margin-top:clamp(18px,2.4vh,30px);color:var(--craie)}

/* fiche technique */
.fiche{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
  gap:1px;background:var(--encre);margin-top:clamp(30px,4vh,52px);
  border:1px solid var(--encre);
}
.fiche > div{background:var(--noir);padding:20px 22px}
.fiche dt{font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--gris);margin-bottom:7px}
.fiche dd{font-size:.98rem;line-height:1.5}

/* ── Corps ────────────────────────────────────────────────── */
.bloc{padding:clamp(48px,7vh,96px) 0;border-top:1px solid var(--encre)}
.bloc h2{
  font-family:var(--display);font-weight:800;text-transform:uppercase;
  font-size:clamp(24px,3vw,52px);letter-spacing:-.03em;line-height:1;
  margin-top:clamp(14px,2vh,26px);
}
.bloc p{max-width:var(--texte-maxw);margin-top:clamp(16px,2.2vh,26px)}
.bloc p + p{margin-top:1.1em}
.bloc strong{color:var(--rouge);font-weight:500}

/* liste à puces carrées rouges */
.bloc ul{max-width:var(--texte-maxw);margin-top:22px;list-style:none}
.bloc li{padding-left:26px;position:relative;margin-top:12px}
.bloc li::before{
  content:'';position:absolute;left:0;top:.62em;width:9px;height:9px;
  background:var(--rouge);
}

/* encadré : décision, contrainte, arbitrage */
.encadre{
  border-left:3px solid var(--rouge);padding:20px 0 20px 24px;
  margin-top:clamp(26px,3.4vh,42px);max-width:var(--texte-maxw);
  background:linear-gradient(90deg,rgba(255,29,45,.06),transparent 70%);
}
.encadre .label{margin-bottom:8px}
.encadre p{margin-top:0}

/* chiffres */
.chiffres{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  gap:1px;background:var(--encre);margin-top:clamp(30px,4vh,52px);
  border:1px solid var(--encre);
}
.chiffres > div{background:var(--noir);padding:26px 24px}
.chiffres b{
  display:block;font-family:var(--display);font-weight:800;color:var(--rouge);
  font-size:clamp(34px,4.4vw,72px);line-height:1;letter-spacing:-.035em;
}
.chiffres span{display:block;margin-top:10px;color:var(--gris);font-size:.92rem;line-height:1.4}

/* ── Visuels ──────────────────────────────────────────────── */
/* Par défaut un visuel suit la colonne de texte. Sortir de cette
   largeur est un choix explicite : .plein, .duo ou .cote.
   Sans ça, une capture d'écran de téléphone en 1146×2000 s'affichait
   sur toute la largeur de page et faisait deux écrans de haut. */
figure{margin-top:clamp(30px,4vh,56px);max-width:var(--texte-maxw)}
/* Le visuel se redimensionne lui-même au lieu d'être posé dans une boîte
   figée. L'ancienne version combinait `width:100%`, une hauteur plafonnée
   et `object-fit:contain` : la boîte gardait sa taille pleine, l'image
   flottait en haut et laissait une grande zone d'encre vide en dessous —
   et comme l'arrondi découpait la boîte et non l'image, le visuel gardait
   ses angles droits à l'intérieur du cadre. Avec largeur et hauteur libres,
   la boîte épouse l'image : plus de vide, et l'arrondi rogne le visuel. */
/* `clip-path` en plus du `border-radius` : la révélation au scroll pose un
   clip-path et une transition d'opacité sur les blocs, ce qui place leur
   contenu sur une couche de composition. Le rognage arrondi y est alors
   appliqué par le compositeur, qui ne lisse pas les bords — les angles
   ressortent en escalier. `clip-path` reste antialiasé. */
figure img,figure video{
  display:block;max-width:100%;width:auto;height:auto;margin-inline:auto;
  background:var(--encre);border-radius:var(--rayon);
  clip-path:inset(0 round var(--rayon));
}
figure img{max-height:76vh}
.plein,.duo figure,.cote figure{max-width:none}
/* .plein est plus large que la colonne de texte mais reste en retrait des
   bords : sans arrondi, ses angles droits jurent au milieu de visuels tous
   arrondis. Le rayon vient donc de figure img, on ne l'annule pas. */
.plein img{max-height:none;width:100%}
.duo img,.cote figure img{max-height:58vh}
figcaption{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--gris);margin-top:12px;
}
/* Texte et visuel côte à côte : une photo verticale empilée sous un
   paragraphe mange tout l'écran pour rien. */
.cote{
  display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(26px,4vw,72px);
  align-items:start;margin-top:clamp(20px,2.6vh,32px);
}
.cote > div > p:first-child{margin-top:0}
.cote figure{margin-top:0}

/* pleine largeur, hors colonne de texte */
.plein{margin-inline:calc(-1 * var(--marge))}
/* La respiration passe de la figure au conteneur : les figures internes
   sont remises à zéro, donc sans marge ici le duo se collait au paragraphe
   au-dessus. C'était le seul bloc de contenu à ne pas en avoir. */
.duo{display:grid;grid-template-columns:1fr 1fr;gap:10px;
  margin-top:clamp(30px,4vh,56px)}
.duo figure{margin-top:0}

/* ── Sommaire fixe ────────────────────────────────────────────
   Réduit à ses numéros pour tenir dans la gouttière ; le libellé se
   déplie au survol par-dessus le contenu. */
.sommaire{
  position:fixed;left:calc(var(--marge) - 4px);top:50%;transform:translateY(-50%);
  z-index:90;display:none;flex-direction:column;gap:2px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
}
.sommaire a{
  display:flex;align-items:center;gap:10px;padding:7px 8px;
  color:var(--gris);white-space:nowrap;
  transition:color .3s var(--ease),background .3s var(--ease);
}
.sommaire a::before{
  content:'';width:12px;height:1px;background:currentColor;flex:0 0 auto;
  transition:width .3s var(--ease);
}
.sommaire .n{flex:0 0 auto}
.sommaire a > span:not(.n){
  max-width:0;overflow:hidden;opacity:0;
  transition:max-width .4s var(--ease),opacity .3s var(--ease);
}
.sommaire:hover a > span:not(.n){max-width:220px;opacity:1}
.sommaire:hover{background:rgba(10,10,10,.86);backdrop-filter:blur(6px)}
.sommaire a:hover{color:var(--craie)}
.sommaire a[aria-current]{color:var(--rouge)}
.sommaire a[aria-current]::before{width:22px}
@media(min-width:1180px){.sommaire{display:flex}}

/* ── Pied : projet suivant ────────────────────────────────── */
.suivant{
  display:block;border-top:1px solid var(--encre);padding:clamp(56px,9vh,110px) 0;
  transition:background .35s var(--ease),padding-left .35s var(--ease);
  position:relative;
}
.suivant:hover{background:var(--rouge);color:var(--noir);padding-left:24px}
/* Flèche dessinée et non un caractère : les glyphes fléchés ne partagent
   pas les métriques du texte, centrer leur boîte ne les centre pas.
   Le tracé remplit son viewBox, donc centrer la boîte suffit, et
   `currentColor` la fait passer au noir sur le survol rouge. */
.suivant::after{
  content:'';position:absolute;top:50%;right:clamp(16px,2.4vw,34px);
  transform:translateY(-50%);
  width:clamp(30px,3.4vw,52px);aspect-ratio:1;background-color:currentColor;
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.9' stroke-linecap='square'%3E%3Cpath d='M3 12h18M13.5 4.5L21 12l-7.5 7.5'/%3E%3C/svg%3E");
  mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.9' stroke-linecap='square'%3E%3Cpath d='M3 12h18M13.5 4.5L21 12l-7.5 7.5'/%3E%3C/svg%3E");
  -webkit-mask-size:contain;mask-size:contain;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:center;mask-position:center;
  transition:transform .35s var(--ease);
}
.suivant:hover::after{transform:translateY(-50%) translateX(10px)}
.suivant h3{
  font-family:var(--display);font-weight:800;text-transform:uppercase;
  font-size:clamp(30px,5vw,96px);letter-spacing:-.035em;line-height:1;margin-top:14px;
}
.suivant:hover .label{color:var(--noir)}

/* ── Contact ──────────────────────────────────────────────── */
.contact{
  background:var(--rouge);color:var(--noir);
  padding:clamp(56px,9vh,120px) max(var(--marge),calc((100% - var(--maxw))/2 + var(--marge)));
}
/* .6 donnait #6c1218 sur le rouge, soit 3.15:1 — sous le seuil pour du
   11 px. .85 monte à 4.61:1 en gardant le label en retrait. */
.contact .label{color:var(--noir);opacity:.85}
.contact h2{
  font-family:var(--display);font-weight:800;text-transform:uppercase;
  font-size:clamp(36px,5.4vw,110px);line-height:.9;letter-spacing:-.035em;margin-top:18px;
}
.contact .liens{display:flex;gap:clamp(16px,2.4vw,34px);flex-wrap:wrap;margin-top:38px;
  font-family:var(--mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase}
.contact .liens a{border-bottom:2px solid var(--noir);padding-bottom:3px}
.contact .liens a:hover{background:var(--noir);color:var(--rouge);border-color:transparent}

/* ── Révélation ───────────────────────────────────────────── */
.js-reveal .bloc > *,.js-reveal .entete > *{
  clip-path:inset(0 0 100% 0);opacity:0;
  transition:clip-path .8s var(--ease),opacity .6s ease;
}
.js-reveal .in > *{clip-path:inset(-30% -10% -10% -10%);opacity:1}
.js-reveal .in > *:nth-child(2){transition-delay:.06s}
.js-reveal .in > *:nth-child(3){transition-delay:.12s}
.js-reveal .in > *:nth-child(4){transition-delay:.18s}
.js-reveal .in > *:nth-child(5){transition-delay:.24s}

/* ── Mobile ───────────────────────────────────────────────── */
@media(max-width:860px){
  :root{--marge:20px}
  .entete{padding-top:clamp(100px,18vh,150px)}
  .entete h1{font-size:clamp(40px,11vw,72px)}
  .chapo{font-size:clamp(17px,4.4vw,22px);max-width:none}
  .duo,.cote{grid-template-columns:1fr}
  .cote figure img{max-height:none}
  .status{font-size:10px;gap:6px}
  body{font-size:17px}
  .retour i{width:14px}
}
@media(hover:none){
  body{cursor:auto}
  .cur{display:none}
  a,button{cursor:auto}
  .langue{cursor:pointer}
}
@media(prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
  .js-reveal .bloc > *,.js-reveal .entete > *{clip-path:none;opacity:1}
}

/* ── Transition d'une page à l'autre ──────────────────────────
   Reprise à l'identique du bloc de index.html : une transition entre
   documents n'a lieu que si les deux déclarent la règle. Garder les deux
   en phase. */
@view-transition{navigation:auto}

.logo{view-transition-name:logo}
.status{view-transition-name:statut}

::view-transition-old(root),::view-transition-new(root){
  animation-duration:.42s;animation-timing-function:var(--ease);
}
::view-transition-old(root){animation-name:page-sort}
::view-transition-new(root){animation-name:page-entre}
@keyframes page-sort {to  {opacity:0;transform:translateY(-14px)}}
@keyframes page-entre{from{opacity:0;transform:translateY(22px)}}

/* Le `*` du bloc « reduce » ci-dessus ne descend pas dans l'arbre des
   pseudo-éléments de transition : il faut les viser explicitement. */
@media(prefers-reduced-motion:reduce){
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*){animation:none!important}
}
