/* Pages intérieures (portfolio, projets…) : la mise en page de css/style.css est gardée telle quelle.
   Ce fichier ne remplace que les animations et la police d'accent, avec le langage validé sur l'accueil (MASTER.md) :
   titre cinétique, grille tracée trait par trait, cartes qui se lèvent, volet noir sur les vignettes,
   coupes franches. Plus de fondu lent ni d'oscillation. Tokens de mouvement : css/tokens.css. */

/* ---------- Police d'accent de l'accueil : Bricolage Grotesque, graisse moyenne ----------
   Seule la police change : taille et interlignage restent ceux de style.css. */
:root{ --ff-serif:"Bricolage Grotesque","Avenir Next","Segoe UI",system-ui,sans-serif; }
.serif{ font-weight:500; font-optical-sizing:auto; letter-spacing:-.02em; }

/* ---------- Plus d'oscillation : tampons, sticker ---------- */
.stamp, .cutout{ animation:none; }

/* ---------- Tampons : le survol de l'accueil ----------
   Le tampon se redresse, un volet noir le remplit de gauche à droite, l'encre change. */
.stamp{ --volet:var(--noir); --encre-survol:var(--jaune); isolation:isolate; overflow:hidden;
  transition:transform var(--t-survol) var(--sortie), color var(--t-survol) var(--sortie); }
.stamp--blanc{ --encre-survol:var(--blanc); }
.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:hover, .stamp:focus-visible{ transform:rotate(0deg); box-shadow:0 0 0 7px var(--ring), var(--sh-stamp); color:var(--encre-survol); }
.stamp:hover::before, .stamp:focus-visible::before{ transform:scaleX(1); }
.stamp:active{ transform:rotate(0deg) translateY(2px); }

/* Sticker : se redresse au survol, sans grossir */
.cutout{ transition:transform var(--t-survol) var(--sortie); }
.cutout:hover{ transform:rotate(0deg); }

/* ---------- Menu mobile : coupe franche, puis les tampons se lèvent ---------- */
.menu{ transition:none; }
.menu.is-open .stamps .stamp{ animation:leve var(--t-entree) var(--sortie) backwards; }
.menu.is-open .stamps .stamp:nth-child(2){ animation-delay:var(--t-decal); }
.menu.is-open .stamps .stamp:nth-child(3){ animation-delay:calc(var(--t-decal) * 2); }
@media (min-width:64em){ .menu .stamps .stamp{ animation:none; } }
/* Téléphone et tablette : le même burger que sur l'accueil (tampon jaune, deux barres noires), et le même menu
   Noir Fitou. Le burger reste au-dessus du menu et sert aussi à le fermer : ses deux barres se croisent. */
@media (max-width:63.99em){
  .burger{ top:max(1rem,env(safe-area-inset-top,0px)); right:max(1rem,env(safe-area-inset-right,0px)); z-index:70;
    width:44px; height:44px; background:var(--jaune); color:var(--noir); border-radius:.375rem;
    box-shadow:0 0 0 6px var(--blanc), 0 6px 0 rgba(35,31,32,.14); transform:rotate(3deg); }
  .burger:hover{ transform:rotate(0deg); }
  .burger__box{ width:20px; gap:5px; }
  .burger__box i{ height:3px; border-radius:0; background:currentColor; transition:transform 320ms var(--sortie); }
  .burger:hover .burger__box i:first-child, .burger:hover .burger__box i:last-child{ transform:none; }
  .burger[aria-expanded="true"] .burger__box i:first-child{ transform:translateY(4px) rotate(45deg); }
  .burger[aria-expanded="true"] .burger__box i:last-child{ transform:translateY(-4px) rotate(-45deg); }
  .menu{ background:var(--noir); grid-template-rows:1fr auto; padding-top:calc(max(1rem,env(safe-area-inset-top,0px)) + 64px); }
  .menu__close{ display:none; }   /* c'est le burger qui ferme */
  /* Mêmes tampons que le menu de l'accueil (taille, liseré, sans icône), dans le zigzag de cette page. */
  .menu .stamps{ gap:2.4rem; padding-left:.5rem; }
  .menu .stamps .stamp{ font-size:clamp(1.8rem,7vw,3.4rem); line-height:1; letter-spacing:-.02em; padding:14px 24px;
    border-radius:.375rem; box-shadow:0 0 0 6px var(--blanc), 0 6px 0 rgba(35,31,32,.14); }
  .menu .stamps .stamp__icon{ display:none; }
  .menu__base{ color:var(--bleu-clair); opacity:1; }
}
/* Ouverture : un rectangle Noir Fitou sort de sous le burger et grandit jusqu'à couvrir l'écran, puis les tampons
   se lèvent ; à la fermeture, il se replie sous le burger. js/raccord.js pose la place du burger (--m-*). */
@media (max-width:63.99em) and (prefers-reduced-motion:no-preference){
  .menu{ opacity:1;
    clip-path:inset(var(--m-t,16px) var(--m-r,16px) var(--m-b,calc(100% - 60px)) var(--m-l,calc(100% - 60px)) round 6px);
    transition:clip-path 380ms cubic-bezier(.55,0,.75,.2), visibility 0s linear 380ms; }
  .menu.is-open{ clip-path:inset(0 0 0 0 round 0px); transition:clip-path 520ms cubic-bezier(.65,0,.25,1), visibility 0s; }
  .menu > :not(.stamps){ opacity:0; transition:opacity 160ms ease; }
  .menu.is-open > :not(.stamps){ opacity:1; transition:opacity 300ms ease 300ms; }
  /* Les tampons sortent de sous le burger (--dx, --dy posés par js/raccord.js), puis se balancent doucement comme le
     sticker de la Bonne Mère ; à la fermeture ils y rentrent. #menu : passe devant les règles d'entrée « leve-incline ». */
  #menu .stamps .stamp, #menu.is-open .stamps .stamp{ transform-origin:50% 50%;
    animation:menu-balance 5.5s ease-in-out infinite; }
  #menu .stamps .stamp{ translate:var(--dx,0px) var(--dy,0px); scale:.15; opacity:0;
    transition:translate 300ms cubic-bezier(.55,0,.8,.3), scale 300ms cubic-bezier(.55,0,.8,.3), opacity 120ms ease 180ms; }
  #menu.is-open .stamps .stamp{ translate:0 0; scale:1; opacity:1;
    transition:translate 560ms cubic-bezier(.2,.9,.3,1.12) var(--d), scale 560ms cubic-bezier(.2,.9,.3,1.12) var(--d), opacity 160ms ease var(--d); }
  #menu .stamps .stamp:nth-child(1){ --d:200ms; animation-delay:0s; }
  #menu .stamps .stamp:nth-child(2){ --d:280ms; animation-delay:-1.9s; }
  #menu .stamps .stamp:nth-child(3){ --d:360ms; animation-delay:-3.8s; }
}
@media (prefers-reduced-motion:reduce){ .burger__box i{ transition:none; } }
@keyframes menu-balance{ 0%,100%{ rotate:-1.8deg; } 50%{ rotate:1.8deg; } }

/* ---------- Entrées : une fois, à l'arrivée de chaque bloc ----------
   --b : décalage donné par js/pages.js aux cartes qui arrivent ensemble. --n : ordre dans le bloc. */
.page__main{ overflow-x:clip; }
.line{ display:block; }
.line > span{ display:block; }
.ch{ display:inline-block; }
.play .rise, .play.rise{ animation:leve var(--t-entree) var(--sortie) backwards;
  animation-delay:calc(var(--b,0ms) + var(--n,0) * var(--t-decal)); }
@keyframes leve{ from{ transform:translateY(40px); opacity:0; } to{ transform:none; opacity:1; } }
/* backwards et non both : une fois posé, l'élément rend la main à ses survols */
/* le sticker et les tampons gardent leur inclinaison en se levant */
.play .cutout.rise, .play .stamp.rise, .menu.is-open .stamps .stamp{ animation-name:leve-incline; }
@keyframes leve-incline{ from{ transform:translateY(40px) rotate(var(--rot)); opacity:0; } to{ transform:rotate(var(--rot)); opacity:1; } }

/* Titre cinétique : la ligne traverse l'écran, penchée, ses lettres se resserrent en se posant */
.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 : caché le temps de l'attente, puis visible d'un coup */
.play .cut, .play.cut{ animation:coupe calc(var(--t-titre) + var(--b,0ms) + var(--n,0) * var(--t-decal)) linear; }
/* Générique : les lignes tombent l'une après l'autre, comme un générique de fin, sans attendre un titre */
.play .generique__liste .cut{ animation-duration:calc(var(--t-decal) * 2 + var(--n,0) * var(--t-decal)); }
@keyframes coupe{ from, to{ visibility:hidden; } }

/* Volet noir sur les vignettes et les lecteurs (.volet) : il couvre l'image puis se retire vers la droite.
   ::before, car ::after porte déjà la couche anti-copie des vignettes. */
.volet{ position:relative; }
.volet::before{ content:""; position:absolute; inset:0; z-index:1; background:var(--noir);
  transform:scaleX(0); transform-origin:right; pointer-events:none; }
.play .volet::before{ animation:volet var(--t-entree) var(--sortie) both;
  animation-delay:calc(var(--b,0ms) + var(--n,0) * var(--t-decal)); }
@keyframes volet{ from{ transform:scaleX(1); } to{ transform:scaleX(0); } }

/* ---------- Grille : tracée trait par trait (comme l'accueil) ----------
   Classe .trace et non .play : .play sur la page ferait partir toutes les cartes d'un coup.
   js/pages.js remplace le dégradé par des filets, autant que la page en demande. */
.js .page__main > .work__grid{ background-image: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(n+3){ display:none; }
.gl--h{ left:0; right:0; height:1px; top:calc(var(--i) * 9rem); transform-origin:0 50%; }
@media (min-width:64em){
  .gl--v:nth-child(2){ --x:25%; }
  .gl--v:nth-child(3){ display:block; --x:50%; }
  .gl--v:nth-child(4){ display:block; --x:75%; }
  .gl--h{ top:calc(var(--i) * 11rem); }
}
.trace .gl--v{ animation:trace-v var(--t-trace) var(--trace) both; animation-delay:calc(var(--t-decal) + var(--i) * var(--t-decal)); }
.trace .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; } }

/* ---------- Avant l'entrée : tout reste à sa position de départ ----------
   La classe js est posée dans le <head> : rien n'apparaît puis ne disparaît. */
@media (prefers-reduced-motion:no-preference){
  .js [data-play]:not(.play) :is(.rise, .cut, [data-kine] .line),
  .js [data-play]:is(.rise, .cut):not(.play){ visibility:hidden; }
  .js [data-play]:not(.play) .volet::before{ transform:scaleX(1); }
  .js .page__main:not(.trace) .gl--v{ transform:scaleY(0); }
  .js .page__main:not(.trace) .gl--h{ transform:scaleX(0); }
}

/* ---------- Mouvement réduit : tout est posé d'emblée ---------- */
@media (prefers-reduced-motion:reduce){
  .play .rise, .play.rise, .play [data-kine] .line, .play [data-kine] .ch, .play .cut, .play.cut, .trace .gl,
  .play .volet::before, .menu.is-open .stamps .stamp{ animation:none; }
  .volet::before{ transform:scaleX(0); }
}

/* ---------- Retouches de mise en page demandées par Élie ----------
   Générique sur téléphone : chaque ligne sur deux lignes (fonction, puis nom), pour toutes,
   plutôt qu'un mélange de lignes simples et de lignes repliées quand le texte est long. */
@media (max-width:47.99em){
  .generique__liste li{ flex-direction:column; align-items:flex-start; }
}

/* Ordinateur : la même colonne de tampons que sur l'accueil, À propos et Contact (css/accueil.css, .topnav) :
   même place, même taille, mêmes inclinaisons, sans icône, et même survol (un volet noir glisse sous le mot). */
@media (min-width:64em){
  .menu{ inset:var(--nav-top) var(--nav-r) auto auto; width:var(--nav-w); }
  .menu .stamps{ align-items:flex-end; gap:var(--s-4); }
  .menu .stamps .stamp{ --volet:var(--noir); --encre-survol:var(--jaune);
    min-height:44px; padding:8px 14px; gap:var(--s-2); font-size:1rem; line-height:1; letter-spacing:-.02em;
    border-radius:.375rem; box-shadow:0 0 0 6px var(--blanc), 0 6px 0 rgba(35,31,32,.14);
    overflow:hidden; isolation:isolate; animation:none; transition:transform var(--t-survol) var(--sortie); }
  .menu .stamps .stamp__icon{ display:none; }
  .menu .stamps .stamp:nth-child(1){ --rot:-3deg; margin-right:0; }
  .menu .stamps .stamp:nth-child(2){ --rot:2deg; margin-right:var(--s-3); }
  .menu .stamps .stamp:nth-child(3){ --rot:-2deg; margin-right:var(--s-1); }
  .menu .stamps .stamp--blanc{ --encre-survol:var(--blanc); }
  .menu .stamps .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); }
  .menu .stamps .stamp span{ transition:color var(--t-survol) var(--sortie); }
  .menu .stamps .stamp:hover, .menu .stamps .stamp:focus-visible{ transform:rotate(0deg);
    box-shadow:0 0 0 6px var(--blanc), 0 6px 0 rgba(35,31,32,.14); }
  .menu .stamps .stamp:hover::before, .menu .stamps .stamp:focus-visible::before{ transform:scaleX(1); }
  .menu .stamps .stamp:hover span, .menu .stamps .stamp:focus-visible span{ color:var(--encre-survol); }
  .menu .stamps .stamp:active{ transform:rotate(0deg) translateY(2px); }
}

