/* =========================================================================
   GUÉNO — sections
   ========================================================================= */

.section{padding-block:var(--block)}
.section__head{
  display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--gap) clamp(20px,3vw,60px);flex-wrap:wrap;
  padding-bottom:clamp(18px,2vw,28px);
  border-bottom:1px solid var(--line);
  margin-bottom:clamp(24px,3vw,44px);
}
.section__head .label{padding-bottom:.6em}

/* ---------- Le hero -----------------------------------------------------
   Le sujet occupe le tiers droit du cadre et regarde vers la gauche : la
   moitié gauche accueille le contenu, et il le regarde. Aucun miroir.

   La vie ne dépend pas du défilement : l'image se pose à l'arrivée, le texte
   monte en cascade, et le cadre dérive en continu — très lentement — tout en
   suivant le pointeur. Un seul transform, écrit par une seule boucle.
   ------------------------------------------------------------------------- */

.hero{position:relative;height:calc(100svh + 55vh)}
.hero__stick{position:sticky;top:0;height:100svh;overflow:hidden}

.hero__frame{
  position:absolute;inset:0;overflow:hidden;
  transform:scale(calc(1 - var(--p,0) * .065));
  border-radius:calc(var(--p,0) * var(--r-lg));
  will-change:transform;
}

/* Le mouvement est autonome : une dérive lente en CSS, sans rien à faire et
   sans suivre le pointeur. L'image respire, elle ne réagit pas. */
.hero__pan{
  position:absolute;inset:-5%;
  will-change:transform;
  animation:drift 34s ease-in-out infinite;
}
@keyframes drift{
  0%   {transform:translate3d(-1.1%, .5%, 0) scale(1.02)}
  50%  {transform:translate3d(1.1%, -.6%, 0) scale(1.06)}
  100% {transform:translate3d(-1.1%, .5%, 0) scale(1.02)}
}
.hero__img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:52% 50%;
}
/* la pose à l'arrivée, séparée du reste pour ne pas se disputer le transform */
.js .hero__img{transform:scale(1.07);transition:transform 2.2s var(--ease-out)}
.js .hero.is-ready .hero__img{transform:none}

.hero__frame::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  /* Deux nappes. La première suit le sens de lecture : sombre à gauche, où
     vit le texte, transparente à droite où le sujet se détache.
     La seconde est elliptique et calée sur le bloc de texte. Elle est devenue
     nécessaire quand le nom est passé en condensée grasse : plus haut d'un
     tiers, il montait dans la bande claire du ciel et le contraste tombait à
     4,1:1. Elle n'assombrit que ce coin — le ciel de droite reste intact. */
  background:
    radial-gradient(94% 104% at 0% 52%,
      rgba(8,7,6,.74) 0%, rgba(8,7,6,.42) 46%, transparent 78%),
    linear-gradient(to right,
      rgba(8,7,6,.62) 0%, rgba(8,7,6,.42) 30%, rgba(8,7,6,.16) 54%, transparent 74%);
}

/* ---------- Le repérage ---------------------------------------------------
   Le viseur du curseur n'est pas une décoration : c'est un système. À
   l'arrivée, un second viseur se pilote tout seul, balaie la photographie,
   s'arrête sur trois éléments et annonce ce qu'il a reconnu — une machine qui
   lit l'image, sur le site de quelqu'un qui travaille avec une machine.

   Il ne joue qu'une fois. Au premier geste — souris, molette, défilement,
   touche — il s'efface et rend la main. Le reste du site est calme.
   ------------------------------------------------------------------------- */

.scan{
  position:absolute;inset:0;z-index:4;pointer-events:none;
  opacity:0;transition:opacity .5s var(--ease);
}
.scan.is-on{opacity:1}

.scan__box{
  position:absolute;left:0;top:0;
  width:var(--sw,120px);height:var(--sh,120px);
  transform:translate3d(var(--sx,0px),var(--sy,0px),0);
  transition:transform .62s var(--ease-out),
             width .62s var(--ease-out), height .62s var(--ease-out);
}
.scan__box > i{
  position:absolute;width:15px;height:15px;
  border:1.5px solid rgba(247,244,238,.92);
}
.scan__box > i:nth-child(1){top:0;left:0;border-right:0;border-bottom:0}
.scan__box > i:nth-child(2){top:0;right:0;border-left:0;border-bottom:0}
.scan__box > i:nth-child(3){bottom:0;right:0;border-left:0;border-top:0}
.scan__box > i:nth-child(4){bottom:0;left:0;border-right:0;border-top:0}

/* La fiche : même matière que les pilules de la barre haute — voile sombre,
   flou d'arrière-plan, filet clair. Elle ne se montre qu'une fois le cadre
   arrivé sur sa cible. */
/* Largeur et hauteur minimales fixes : la fiche est posée par le script,
   qui a besoin d'une taille stable avant de savoir où la mettre. */
.scan__card{
  position:absolute;left:var(--kx,0px);top:var(--ky,0px);
  width:268px;min-height:118px;
  padding:12px 15px 14px;
  background:rgba(12,11,10,.92);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  border:1px solid rgba(247,244,238,.18);border-radius:14px;
  opacity:0;transform:translateY(7px);
  transition:opacity .28s var(--ease),transform .28s var(--ease-out),
             left .52s var(--ease-out),top .52s var(--ease-out);
}
.scan.is-read .scan__card{opacity:1;transform:none}

.scan__kind{
  display:flex;align-items:baseline;justify-content:space-between;gap:1.4em;
  font-size:var(--t-label);letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-dim);
}
.scan__kind b{font-weight:500;color:var(--accent)}
.scan__name{
  font-family:var(--font-fat);font-weight:800;
  font-size:1.4rem;line-height:.94;letter-spacing:.005em;text-transform:uppercase;
  color:#F7F4EE;min-height:1.32em;
}
.scan__note{font-size:var(--t-small);line-height:1.45;color:var(--text-dim);padding-top:5px;min-height:1.45em}

/* La vignette, découpée dans la zone que le viseur vient de cadrer. */
.scan__row{display:flex;gap:12px;align-items:flex-start;padding-top:10px}
.scan__vue{
  width:66px;height:66px;flex:none;border-radius:9px;object-fit:cover;
  border:1px solid rgba(247,244,238,.16);
  transition:filter .5s var(--ease),opacity .5s var(--ease);
}
.scan__txt{min-width:0;flex:1}

/* L'état « analyse » : la machine cherche avant de répondre. Deux barres
   balayées, la vignette encore floue, le taux pas encore tombé. */
.scan__card.is-think .scan__vue{filter:blur(7px);opacity:.55}
.scan__bars{display:none;flex-direction:column;gap:8px;padding-top:3px}
.scan__card.is-think .scan__bars{display:flex}
.scan__card.is-think .scan__txt{display:none}
.scan__bars i{
  display:block;height:11px;border-radius:4px;
  background:linear-gradient(90deg,
    rgba(247,244,238,.09) 0%, rgba(247,244,238,.28) 42%, rgba(247,244,238,.09) 82%);
  background-size:280% 100%;
  animation:scanwipe 1.15s linear infinite;
}
.scan__bars i:nth-child(1){width:86%}
.scan__bars i:nth-child(2){width:56%;height:9px}
@keyframes scanwipe{0%{background-position:130% 0}100%{background-position:-70% 0}}

/* Le curseur d'écriture, tant que la ligne se compose. */
.scan__name.is-typing::after,
.scan__note.is-typing::after{
  content:"";display:inline-block;width:.46em;height:.86em;
  margin-left:.1em;vertical-align:-.09em;
  background:currentColor;animation:scancaret .9s steps(1) infinite;
}
@keyframes scancaret{0%,49%{opacity:1}50%,100%{opacity:0}}

/* Sur petit écran, le cadre est trop étroit pour qu'une fiche flotte à côté
   du viseur sans le masquer. Elle devient un bandeau au bas de la photo : le
   viseur balaie au-dessus, la fiche reste toujours lisible et toujours en
   place. C'est la même idée, dans le format du téléphone. */
@media (max-width:860px){
  .scan__card{
    left:10px;right:10px;top:auto;bottom:10px;
    width:auto;min-height:0;padding:10px 12px 12px;
    transition:opacity .28s var(--ease),transform .28s var(--ease-out);
  }
  .scan__vue{width:52px;height:52px;border-radius:8px}
  .scan__row{gap:10px;padding-top:8px}
  .scan__name{font-size:1.12rem}
  .scan__bars i{height:10px}
  .scan__bars i:nth-child(2){height:8px}
}
@media (prefers-reduced-motion:reduce){ .scan{display:none} }

.hero__over{
  position:absolute;inset:0;z-index:2;pointer-events:none;
  display:grid;align-content:center;
  padding:clamp(76px,10vh,120px) var(--pad) clamp(24px,4vh,56px);
  max-width:var(--maxw);margin-inline:auto;
}
.hero__col{
  pointer-events:auto;
  display:flex;flex-direction:column;gap:clamp(14px,1.8vh,26px);
  max-width:min(46ch, 52%);
}
/* L'interlignage serré de la condensée (.84) collait la ligne de rôle au
   nom : il lui faut une respiration que la graisse précédente n'exigeait pas. */
.hero__over .name{color:#F7F4EE;margin-bottom:.16em}
.hero__over .small{color:rgba(247,244,238,.94)}
.hero__over .lead{color:#F7F4EE;max-width:20ch}
.hero__acts{display:flex;flex-wrap:wrap;gap:8px;padding-top:clamp(4px,1vh,12px)}

/* la signature, posée en bas du cadre */
/* Le coin droit est de l'herbe claire, hors du voile : le tampon se pose à
   gauche, dans la zone que le voile protège déjà. */
.hero__stamp{
  position:absolute;left:var(--pad);bottom:clamp(24px,4vh,52px);z-index:2;
  --stamp:rgba(247,244,238,.66);--tilt:-3.5deg;
}
@media (max-width:860px){ .hero__stamp{display:none} }
.hero__acts .pill{border-color:rgba(247,244,238,.34);color:#F7F4EE}
.hero__acts .pill:hover{background:var(--cream);color:var(--on-cream);border-color:var(--cream)}
.hero__acts .pill--solid{background:var(--cream);color:var(--on-cream);border-color:var(--cream)}

/* le texte monte en cascade dès l'arrivée — rien à faire pour le déclencher */
.js .hero__col > *{
  opacity:0;transform:translate3d(0,16px,0);
  transition:opacity .9s var(--ease-out), transform .9s var(--ease-out);
}
.js .hero.is-ready .hero__col > *{opacity:1;transform:none}
.js .hero.is-ready .hero__col > *:nth-child(1){transition-delay:.20s}
.js .hero.is-ready .hero__col > *:nth-child(2){transition-delay:.34s}
.js .hero.is-ready .hero__col > *:nth-child(3){transition-delay:.48s}

@media (prefers-reduced-motion:reduce){
  .hero__pan{animation:none;transform:none}
  .js .hero__img{transform:none}
  .js .hero__col > *{opacity:1;transform:none}
}

@media (max-width:860px){
  .hero{height:auto}
  .hero__stick{position:static;height:auto;overflow:visible}
  .hero__frame{
    position:relative;height:min(62svh,520px);
    transform:none;border-radius:var(--r-lg);
  }
  .hero__img{object-position:62% 46%}
  .hero__frame::after{display:none}
  .hero__over{
    position:static;inset:auto;
    padding:clamp(20px,5vw,32px) var(--pad) clamp(28px,6vw,44px);
  }
  .hero__col{max-width:none}
  .hero__over .name,.hero__over .lead{color:var(--text)}
  .hero__over .small{color:var(--text-dim)}
  .hero__acts .pill:not(.pill--solid){border-color:var(--line);color:var(--text)}
}

/* ---------- Ce que je fais ----------------------------------------------
   Structure reprise d'Ilja : le titre occupe la colonne de gauche (il n'est
   pas collant chez lui non plus), les quatre tuiles la colonne de droite, le
   bouton dessous. La ligne concevoir → livrer descend ici : elle n'a plus à
   charger la section À propos.
   ------------------------------------------------------------------------- */

.skills{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,2fr);
  gap:clamp(28px,4vw,90px);
  align-items:start;
}
.skills__head{display:flex;flex-direction:column;gap:clamp(16px,1.8vw,26px)}
.skills__head .body{max-width:34ch}

.flow{
  display:flex;align-items:center;flex-wrap:wrap;gap:clamp(8px,1vw,14px);
  padding-block:clamp(14px,1.6vw,20px);
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
}
.flow span{font-size:var(--t-small);font-weight:500;letter-spacing:.02em}
.flow i{display:block;width:clamp(14px,1.8vw,26px);height:1px;background:var(--line);flex:none}

.skills__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--gap)}

.skill{
  display:flex;flex-direction:column;gap:clamp(14px,1.6vw,20px);
  min-height:clamp(230px,24vw,300px);
}
.skill__ic{
  width:50px;height:50px;border-radius:14px;flex:none;
  background:var(--cream);color:var(--accent);
  display:grid;place-items:center;
}
.skill__ic svg{width:24px;height:24px}
.skill h3{font-size:var(--t-body);font-weight:500;letter-spacing:-.01em}
.skill__b{margin-top:auto;display:flex;flex-direction:column;gap:12px}
.skill__b p{font-size:var(--t-small);color:var(--text-dim);line-height:1.55}
.skill__tags{display:flex;flex-wrap:wrap;gap:6px}

.skills__cta{display:flex;justify-content:center;padding-top:clamp(24px,3vw,44px)}

/* ---- Le défilé des outils ------------------------------------------------
   Deux groupes identiques dans la piste : la translation de -50 % ramène le
   second exactement là où le premier commençait, la boucle est invisible.
   Les bords s'estompent par un masque plutôt que par un dégradé posé dessus,
   pour que le fond de section reste libre. ------------------------------- */
/* La section borne le débordement : 100vw dépasse la zone visible de la largeur
   de la barre de défilement sur les postes à barres classiques. `clip` coupe sans
   créer de conteneur de défilement — il ne casserait pas un position:sticky, et
   #faire n'en contient de toute façon aucun. */
#faire{overflow-x:clip}
.tools{
  /* pleine largeur : on sort de la gouttière et du max-width du .wrap */
  width:100vw;margin-inline:calc(50% - 50vw);
  margin-top:clamp(30px,4vw,56px);
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:clamp(15px,1.7vw,23px) 0;
  overflow:hidden;
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 7%,#000 93%,transparent 100%);
          mask-image:linear-gradient(to right,transparent 0,#000 7%,#000 93%,transparent 100%);
}
.tools__track{display:flex;width:max-content;animation:defile 42s linear infinite}
.tools:hover .tools__track,.tools:focus-within .tools__track{animation-play-state:paused}
.tools__grp{
  display:flex;align-items:center;
  gap:clamp(30px,3.6vw,60px);padding-right:clamp(30px,3.6vw,60px);
  margin:0;padding-left:0;list-style:none;
}
.tools__i{display:inline-flex;align-items:center;gap:10px;color:var(--text-dim);white-space:nowrap}
.tools__i svg{width:19px;height:19px;flex:none;color:var(--text-dim)}
.tools__i span{font-size:var(--t-small);font-weight:500;letter-spacing:.015em}
@keyframes defile{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}

@media (prefers-reduced-motion:reduce){
  .tools__track{animation:none}
  .tools{overflow-x:auto;-webkit-mask-image:none;mask-image:none}
}

@media (max-width:1080px){ .skills{grid-template-columns:1fr;gap:clamp(24px,4vw,40px)} }
@media (max-width:620px){ .skills__grid{grid-template-columns:1fr} }

/* Les lignes servent encore à la timeline d'À propos */
.rows{border-top:1px solid var(--line)}
.rows__r{
  display:grid;
  grid-template-columns:3.5rem minmax(0,10rem) minmax(0,1fr);
  gap:var(--gap);
  padding-block:clamp(16px,1.8vw,26px);
  border-bottom:1px solid var(--line);
  align-items:baseline;
}
.rows__r > .label:first-child{color:var(--text-dim)}
.rows__r h3{font-size:var(--t-body);font-weight:500;letter-spacing:-.01em}
.rows__r p{color:var(--text-dim);max-width:46ch}
@media (max-width:760px){
  .rows__r{grid-template-columns:2.5rem minmax(0,1fr);row-gap:6px}
  .rows__r p{grid-column:2}
}

/* ---------- Le travail : image à gauche, projet à droite -----------------
   Les tuiles s'empilent : `position: sticky; top: 0` sur des frères de même
   hauteur — aucun JavaScript derrière.
   ------------------------------------------------------------------------- */

.stack{position:relative;padding-bottom:var(--block)}

.stack__card{
  position:sticky;top:0;height:100svh;
  display:grid;
  padding:clamp(10px,1.4vw,22px);
  padding-top:clamp(58px,7vh,86px);
}
.stack__inner{
  position:relative;
  min-height:0;
  background:var(--proj);color:var(--proj-fg);
  border-radius:var(--r-lg);
  overflow:hidden;
  display:grid;
  grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);
  box-shadow:0 -1px 0 0 rgba(255,255,255,.09), 0 -30px 60px -34px rgba(0,0,0,.7);
}

/* En grille, `max-height:100%` sur l'image ne résout pas contre la piste et
   l'artwork déborde. En flex, il résout. */
.stack__stage{
  min-width:0;min-height:0;
  display:flex;align-items:center;justify-content:center;
  padding:clamp(18px,2.6vw,44px);
}
.stack__stage img,
.stack__stage video{
  max-width:100%;max-height:100%;width:auto;height:auto;min-height:0;
  border-radius:8px;
  box-shadow:0 24px 60px -32px rgba(0,0,0,.7);
}
/* Un projet web se montre en mouvement : la tuile accepte une vidéo à la
   place de l'image, avec le même traitement que les bobines d'Autres pratiques —
   rien avant l'approche, pause hors du champ, contrôles rendus sans script. */
.stack__v{display:block;background-size:cover;background-position:center}

.stack__side{
  min-width:0;
  display:flex;flex-direction:column;justify-content:center;
  gap:clamp(12px,1.6vw,20px);
  padding:clamp(22px,3vw,52px) clamp(22px,3vw,52px) clamp(22px,3vw,52px) 0;
  border-left:1px solid var(--proj-line);
  margin-left:clamp(4px,1vw,16px);
  padding-left:clamp(22px,3vw,52px);
}
.stack__no{font-size:var(--t-label);letter-spacing:.14em;opacity:.6}
.stack__name{font-family:var(--font-fat);font-weight:800;
             font-size:clamp(2rem,3.6vw,3.5rem);line-height:.86;
             letter-spacing:.005em;text-transform:uppercase}
.stack__said{opacity:.76;max-width:34ch;font-size:var(--t-small);line-height:1.55}
.stack__tags{display:flex;flex-wrap:wrap;gap:6px;padding-top:clamp(2px,.6vw,8px)}
/* Les outils, que les pastilles ne disaient pas : avec quoi le projet a été
   réellement fabriqué. */
.stack__tools{display:flex;gap:.8em;align-items:baseline;font-size:var(--t-small)}
.stack__tools b{
  font-size:var(--t-label);letter-spacing:.14em;text-transform:uppercase;
  font-weight:500;opacity:.72;flex:none;
}
.stack__stamp{
  position:absolute;top:clamp(18px,2.6vw,34px);right:clamp(18px,2.6vw,34px);z-index:2;
  --stamp:color-mix(in srgb, var(--proj-fg) 62%, transparent);--tilt:3deg;
}
.stack__tags .tag{border-color:var(--proj-line);color:var(--proj-fg);opacity:.9}
/* Le bouton du projet emprunte les couleurs de sa tuile : il ne peut pas
   garder les jetons du site, qui sont ceux du fond sombre. */
.stack__go{
  margin-top:clamp(6px,1vw,12px);
  border-color:var(--proj-line);color:var(--proj-fg);
}
.stack__go:hover{
  background:var(--proj-fg);color:var(--proj);border-color:var(--proj-fg);
}

@media (max-width:900px), (max-height:600px){
  .stack__card{position:static;height:auto;min-height:0;padding-top:clamp(10px,1.4vw,22px)}
  .stack__inner{grid-template-columns:1fr;box-shadow:0 18px 40px -26px rgba(0,0,0,.6)}
  .stack__stage{padding-bottom:0}
  .stack__side{
    border-left:0;border-top:1px solid var(--proj-line);
    margin-left:0;padding:clamp(20px,4vw,30px);
  }
  .stack__card + .stack__card{margin-top:var(--gap)}
}

/* Une couleur par projet : c'est elle qui peint la tuile. Celles des quatre
   derniers sont de moi — les vraies dominantes restent à fournir. */
#banquiz  {--proj:#2C2C7F;--proj-fg:#EFEFFA;--proj-line:rgba(239,239,250,.28)}
#mas      {--proj:#390504;--proj-fg:#F8E9D8;--proj-line:rgba(248,233,216,.28)}
#kairos   {--proj:#232120;--proj-fg:#EFEBE6;--proj-line:rgba(239,235,230,.28)}
#flower   {--proj:#3B1526;--proj-fg:#FBEAF1;--proj-line:rgba(251,234,241,.28)}
#sol      {--proj:#043333;--proj-fg:#E7F4EE;--proj-line:rgba(231,244,238,.28)}
#hws      {--proj:#0E1A3A;--proj-fg:#E9EFFD;--proj-line:rgba(233,239,253,.28)}
/* ---------- À propos ----------------------------------------------------
   Pas de dégradé : un dégradé sombre → clair ne produit qu'une bande grise.
   La section est une FEUILLE claire qui glisse par-dessus le fond, et la
   section suivante glisse par-dessus elle. Des arêtes nettes, des angles
   généreux, aucune bouillie.
   ------------------------------------------------------------------------- */

.sheet{
  position:relative;z-index:1;
  border-radius:var(--sheet,clamp(26px,3.4vw,54px)) var(--sheet,clamp(26px,3.4vw,54px)) 0 0;
  margin-top:calc(-1 * var(--sheet,clamp(26px,3.4vw,54px)));
}

.about{
  --sheet:clamp(26px,3.4vw,54px);
  --text:var(--on-cream);
  --text-dim:var(--on-cream-dim);
  --line:rgba(18,17,16,.16);
  color:var(--on-cream);
  background:var(--cream);
  padding-block:clamp(72px,9vw,140px);
  box-shadow:0 -24px 60px -40px rgba(0,0,0,.8);
}

/* la section sombre qui suit remonte par-dessus la feuille claire */
.after-sheet{
  --sheet:clamp(26px,3.4vw,54px);
  background:var(--ground);
}

.about__grid{
  display:grid;grid-template-columns:repeat(12,minmax(0,1fr));
  gap:var(--gap);align-items:start;
}
.about__story{grid-column:1/7;display:flex;flex-direction:column;gap:clamp(16px,1.8vw,26px)}
.about__story .lead span{display:block}
.about__me{
  grid-column:8/-1;
  border-radius:var(--r-lg);overflow:hidden;
  aspect-ratio:4/5;position:relative;
}
.about__me img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:52% 30%}

.about__time{margin-top:clamp(40px,5vw,80px)}
.about__cv{margin-top:clamp(26px,3.2vw,44px)}
/* .about redéfinit --text et --line pour le fond crème : le survol par défaut
   poserait du crème sur du crème. On inverse, comme dans le pied de page. */
.about .pill:hover{background:var(--on-cream);color:var(--cream);border-color:var(--on-cream)}
.about .pill--solid{background:var(--on-cream);color:var(--cream);border-color:var(--on-cream)}
.about .pill--solid:hover{background:var(--accent);border-color:var(--accent);color:#140D08}
.about__stamp{
  margin-top:clamp(28px,3.4vw,44px);
  --stamp:rgba(18,17,16,.62);--tilt:-2.5deg;
}

@media (max-width:900px){
  .about__story{grid-column:1/-1}
  .about__me{grid-column:1/-1;aspect-ratio:5/4;margin-top:clamp(24px,4vw,36px)}
}

/* ---------- Autres pratiques --------------------------------------------
   Calme au repos, comme demandé : trois tuiles, un titre chacune. Le
   désordre n'apparaît qu'à l'interaction — la tuile se soulève et pivote
   d'un cheveu, et la note se découvre.

   Les trois portent une bobine. Les fichiers sont recadrés en 4/5 à
   l'encodage — la fente est en portrait, autant ne pas transporter ce qui
   serait rogné. La bobine web fait exception : ses maquettes sont en pleine
   largeur et un recadrage centré n'en gardait qu'une tranche illisible, elle
   est donc recomposée entière sur un agrandissement flou d'elle-même.
   ------------------------------------------------------------------------- */

.quests{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--gap)}
.quest{
  display:flex;flex-direction:column;gap:var(--gap);
  min-height:250px;
  transition:transform .45s var(--ease-out), border-color .45s var(--ease);
}
/* `.js [data-in].is-in{transform:none}` est plus spécifique que `.quest:hover`
   et écrasait le mouvement : la règle de survol doit reprendre la main. */
.quest:hover,.quest:focus-within,
.js .quest[data-in].is-in:hover,
.js .quest[data-in].is-in:focus-within{
  transform:translateY(-6px) rotate(var(--tilt,-.7deg));
  border-color:color-mix(in srgb, var(--text) 26%, transparent);
}
.quest:nth-child(2n){--tilt:.8deg}
.quest:nth-child(3n){--tilt:-1.1deg}
.quest__img{border-radius:var(--r);overflow:hidden;aspect-ratio:4/5;background:var(--ground)}
.quest__img img,
.quest__img video{width:100%;height:100%;object-fit:cover;object-position:var(--focus,50% 40%)}
/* Deux tuiles portent une bobine plutôt qu'une image. Les fichiers sont
   recadrés en 4/5 à l'encodage — la fente est en portrait, autant ne pas
   transporter les 55 % de largeur qui seraient rognés à l'affichage. Sans
   son, en boucle, et elles ne tournent que dans le champ de vision. */
.quest__v{display:block;background-size:cover;background-position:center}
.quest__b{margin-top:auto;display:flex;flex-direction:column;gap:6px}
.quest h3{font-size:var(--t-body);font-weight:500;letter-spacing:-.01em}
.quest p{font-size:var(--t-small);color:var(--text-dim);max-width:30ch}
/* la note se découvre au survol — au toucher elle reste lisible */
.quest__note{
  opacity:0;transform:translateY(4px);
  transition:opacity .4s var(--ease),transform .4s var(--ease-out);
}
.quest:hover .quest__note,.quest:focus-within .quest__note{opacity:1;transform:none}
@media (hover:none){ .quest__note{opacity:1;transform:none} }
@media (prefers-reduced-motion:reduce){
  .quest:hover,.quest:focus-within{transform:none}
  .quest__note{opacity:1;transform:none}
}
/* Trois tuiles : une grille à deux colonnes en laisserait une orpheline.
   On tient donc les trois colonnes jusqu'aux tablettes — 237 px par tuile à
   768 px, ça tient — puis on passe d'un coup à une seule colonne. */
@media (max-width:620px){ .quests{grid-template-columns:1fr} }

/* ---------- En ce moment ------------------------------------------------- */

.now{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 clamp(24px,5vw,96px)}
.now dl{border-top:1px solid var(--line)}
.now div{display:flex;align-items:baseline;justify-content:space-between;gap:var(--gap);
         padding-block:12px;border-bottom:1px solid var(--line)}
.now dt{font-size:var(--t-small);color:var(--text-dim)}
.now dd{margin:0;font-size:var(--t-small);font-weight:500;text-align:right}
.now dd .live{color:var(--accent);font-variant-numeric:tabular-nums}
@media (max-width:760px){ .now{grid-template-columns:1fr} }

/* ---------- Le chargeur -------------------------------------------------
   Il n'existe que si le JavaScript tourne (`display:none` par défaut), et il
   se retire tout seul. Sous `prefers-reduced-motion` il ne s'affiche pas.
   ------------------------------------------------------------------------- */

.loader{display:none}
.js .loader{
  display:grid;grid-template-rows:auto 1fr auto;
  position:fixed;inset:0;z-index:400;
  background:var(--ground);color:var(--text);
  padding:var(--pad);
  transition:transform .85s var(--ease-out);
  will-change:transform;
}
.loader.is-done{transform:translate3d(0,-101%,0)}
.loader__top{display:flex;justify-content:space-between;gap:var(--gap);align-items:flex-start}
.loader__mid{display:grid;align-content:center;justify-items:end}
.loader__count{
  font-family:var(--font-fat);font-weight:800;
  font-size:clamp(5rem,26vw,26rem);line-height:.8;
  letter-spacing:.005em;font-variant-numeric:tabular-nums;
}
.loader__count sup{font-size:.28em;vertical-align:super;margin-left:.06em;opacity:.5}
.loader__foot{display:flex;flex-direction:column;gap:var(--gap)}
.loader__bar{position:relative;height:1px;background:var(--line);overflow:hidden}
.loader__bar i{
  position:absolute;inset:0 auto 0 0;display:block;
  width:calc(var(--pct,0) * 1%);background:var(--accent);
  transition:width .25s linear;
}
.loader__row{display:flex;justify-content:space-between;gap:var(--gap)}
@media (prefers-reduced-motion:reduce){ .js .loader{display:none} }

/* ---------- Pied --------------------------------------------------------
   Panneau clair inversé, presque plein écran : trois zones — informations en
   haut, l'invitation en grand au centre, liens et mentions en bas.
   ------------------------------------------------------------------------- */

.foot{
  --text:var(--on-cream);
  --text-dim:var(--on-cream-dim);
  --line:rgba(18,17,16,.16);
  background:var(--cream);color:var(--on-cream);
  border-radius:var(--r-lg);
  margin:var(--block) clamp(10px,1.4vw,22px) clamp(10px,1.4vw,22px);
  min-height:min(94svh,940px);
  /* la barre est fixe : la rangée du haut doit passer dessous */
  padding:clamp(72px,7vw,110px) clamp(22px,2.6vw,42px) clamp(22px,2.6vw,42px);
  display:grid;grid-template-rows:auto 1fr auto;
  gap:clamp(28px,4vw,60px);
}

.foot__top{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--gap)}
.foot__mark{
  font-family:var(--font-fat);font-weight:800;
  font-size:clamp(1rem,1.5vw,1.375rem);line-height:1;
  letter-spacing:.02em;text-transform:uppercase;
  display:inline-flex;align-items:flex-start;gap:.2em;
}
.foot__mark sup{font-size:.5em;line-height:1.4}
.foot__top div:last-child{text-align:right}
@media (max-width:760px){ .foot__top .foot__mark{display:none} }

.foot__mid{display:grid;align-content:center;justify-items:center;gap:clamp(20px,3vw,42px);text-align:center}
.foot__mid .blast{max-width:14ch}
.foot__mail{display:flex;flex-direction:column;align-items:center;gap:6px}
.foot__mail a{
  font-size:clamp(1.25rem,2.6vw,2.25rem);font-weight:500;letter-spacing:-.025em;
  display:inline-flex;align-items:center;gap:.4em;
  border-bottom:1px solid transparent;
  transition:border-color .3s var(--ease),color .3s var(--ease);
}
.foot__mail a:hover{border-color:currentColor;color:var(--accent-ink,#B33F0C)}
.foot__mail svg{width:.5em;height:.5em}

.foot__bottom{
  display:flex;justify-content:space-between;align-items:flex-end;
  gap:var(--gap) clamp(20px,3vw,48px);flex-wrap:wrap;
  border-top:1px solid var(--line);padding-top:clamp(18px,2vw,26px);
}
.foot__links{display:flex;flex-wrap:wrap;gap:8px}
.foot__bottom > div:last-child{text-align:right;margin-left:auto}
.foot__up{display:inline-flex;align-items:center;gap:.4em}
.foot__up svg{width:10px;height:10px;transform:rotate(-45deg)}
@media (max-width:760px){
  .foot__bottom > div:last-child{text-align:left;margin-left:0}
}

/* ---------- Le panneau CV -------------------------------------------------
   Ouvert par :target, fermé par un lien vers #top. Pas de JavaScript, donc il
   tient aussi dans le lien partagé et sans script. `visibility` plutôt que
   `display` pour que la transition existe, et pour que le contenu reste hors
   de l'ordre de tabulation tant qu'il est fermé.
   ------------------------------------------------------------------------- */
.cv{
  /* au-dessus de la barre (120) et du menu (130), sous le curseur (350)
     et le chargeur (400).
     `display:none` et non `visibility:hidden` : une boîte masquée est quand
     même générée, et le navigateur télécharge alors l'image du CV sur toutes
     les visites — 69 ko pour un panneau que personne n'a ouvert. */
  display:none;
  position:fixed;inset:0;z-index:200;
  place-items:center;padding:clamp(14px,3vw,40px);
}
.cv:target{display:grid}
.cv__fond{position:absolute;inset:0;background:rgba(8,7,6,.82);cursor:zoom-out}

.cv__boite{
  position:relative;
  width:min(760px,100%);height:100%;min-height:0;
  display:flex;flex-direction:column;gap:clamp(10px,1.4vw,16px);
  animation:cv-entre .34s var(--ease-out) both;
}
@keyframes cv-entre{from{opacity:0;transform:translateY(12px) scale(.987)}to{opacity:1;transform:none}}

.cv__barre{
  display:flex;align-items:center;justify-content:space-between;
  gap:clamp(10px,2vw,24px);flex-wrap:wrap;color:var(--text);
}
.cv__acts{display:flex;gap:8px;flex-wrap:wrap}
.cv .pill{border-color:rgba(247,244,238,.34);color:#F7F4EE}
.cv .pill:hover{background:var(--cream);color:var(--on-cream);border-color:var(--cream)}
.cv .pill--solid{background:var(--cream);color:var(--on-cream);border-color:var(--cream)}
.cv .pill--solid:hover{background:var(--accent);border-color:var(--accent);color:#140D08}

/* La barre garde sa hauteur, la vue prend le reste : l'image se contraint
   alors par la HAUTEUR disponible et non par la largeur, sinon une page A4
   déborde de l'écran dès que la fenêtre est plus large que haute. */
.cv__barre{flex:0 0 auto}
.cv__vue{flex:1 1 auto;min-height:0;display:flex;justify-content:center;align-items:flex-start}
.cv__page{
  display:block;width:auto;height:auto;
  max-width:100%;max-height:100%;
  border-radius:clamp(6px,.8vw,12px);
  box-shadow:0 40px 90px -40px rgba(0,0,0,.9);
}
@media (prefers-reduced-motion:reduce){
  .cv__boite{animation:none}
}
