/* ==========================================================================
   Portfolio — la page formelle, à /portfolio.

   Second langage visuel du site, assumé comme distinct du fly-through : là où
   la page d'accueil est en serif Flecha sur une peinture romaine, celle-ci est
   une grille de développeur, en grotesque, avec des micro-labels aux quatre
   coins.

   Le système est relevé sur jonasreymondin.com (étude de cas Codrops, mars
   2026) : rampe de neutres, 12 colonnes en 1392px, sept tailles fluides bâties
   sur une même interpolation entre 480 et 1440px, une seule approche à -.03em,
   et une révélation par lignes remontant de 110 % sous un masque.

   Deux écarts délibérés :
   - le fond est clair (le paper du site) et non son quasi-noir ;
   - l'accent est le bleu du film et non son orange, qui est sa couleur de
     marque et pas une technique.
   ========================================================================== */

@import url("https://api.fontshare.com/v2/css?f[]=switzer@400,500,600&display=swap");

:root {
  /* --- Rampe de neutres. La sienne, retournée vers le clair. --- */
  --p-bg:     #f2f1ed;
  --p-ink:    #1d1c19;
  --p-ink-2:  #33322d;
  --p-ink-3:  #6d6a67;   /* le sien, gardé tel quel : il tient dans les deux sens */
  --p-rule:   #1d1c1924;
  --p-accent: #0a4c9b;

  --p-max:    1392px;
  --p-gutter: clamp(16px, 3vw, 40px);

  /* --- Échelle fluide. Sa formule, transcrite : chaque taille interpole
         entre 480px et 1440px de large. --- */
  --fs-giant: clamp(6.25rem, 6.25rem + 100/960 * (100vw - 480px), 25rem);
  --fs-xl:    clamp(2rem, 2rem + 28/960 * (100vw - 480px), 5rem);
  --fs-l:     clamp(1.5rem, 1.5rem + 6/960 * (100vw - 480px), 2.3125rem);
  --fs-m:     clamp(1.25rem, 1.25rem + 4/960 * (100vw - 480px), 1.75rem);
  --fs-body:  clamp(.875rem, .875rem + 2/960 * (100vw - 480px), 1.125rem);
  --fs-micro: clamp(.5625rem, .5625rem + 1/960 * (100vw - 480px), .9375rem);
  --fs-nano:  clamp(.45rem, .45rem + .8/960 * (100vw - 480px), .75rem);

  --p-tr: -.03em;        /* une seule approche pour tout le site, comme lui */

  --e-out:   cubic-bezier(.215, .61, .355, 1);
  --e-inout: cubic-bezier(.65, 0, .35, 1);
  --e-quart: cubic-bezier(.76, 0, .24, 1);

  --split-in:  .8s;
  --split-out: .6s;
  --stagger:   .075s;
}

*, *::before, *::after { box-sizing: border-box; }

body.pf {
  margin: 0;
  background: var(--p-bg);
  color: var(--p-ink);
  font-family: "Switzer", "Neue Haas Grotesk", Inter, system-ui, sans-serif;
  font-size: var(--fs-body);
  line-height: 1.35;
  letter-spacing: var(--p-tr);
  -webkit-font-smoothing: antialiased;
}

/* --- Grille ------------------------------------------------------------- */

.pf-wrap {
  max-width: var(--p-max);
  margin: 0 auto;
  padding: 0 var(--p-gutter);
}
.pf-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--p-gutter);
}

/* --- Micro-labels : la signature du coin d'écran ------------------------ */

.pf-micro {
  font-size: var(--fs-nano);
  line-height: 1;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--p-ink-3);
  margin: 0;
}
.pf-micro--ink { color: var(--p-ink); }

.pf-corners {
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
  padding: var(--p-gutter);
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto 1fr auto;
  gap: 8px;
}
.pf-corners > * { pointer-events: auto; }
.pf-corners__bl { grid-column: 1; grid-row: 3; align-self: end; }
.pf-corners__br { grid-column: 2; grid-row: 3; align-self: end; text-align: right; }

/* --- En-tête ------------------------------------------------------------ */

.pf-head {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  padding: var(--p-gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  mix-blend-mode: normal;
}
.pf-nav { display: flex; gap: clamp(14px, 2vw, 30px); }
.pf-nav a {
  font-size: var(--fs-nano);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--p-ink);
  text-decoration: none;
  position: relative;
  padding-bottom: 3px;
}
/* Le filet se déploie depuis la gauche — sa mécanique de survol. */
.pf-nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform .45s var(--e-quart);
}
.pf-nav a:hover::after { transform: scaleX(1); }
.pf-nav a[aria-current]::after { transform: scaleX(1); background: var(--p-accent); }

/* --- Révélation par lignes ----------------------------------------------
   Sa signature : le texte remonte de 110 % sous un masque, décalé par index.
   On réutilise le découpeur de reveal.js, qui pose déjà --i sur chaque
   fragment.
   ------------------------------------------------------------------------ */

.pf-split { overflow: hidden; display: block; }

.pf-split [data-reveal] .wd,
.pf-split [data-reveal] .ln,
[data-reveal].pf-split .wd,
[data-reveal].pf-split .ln {
  display: inline-block;
  transform: translate3d(0, 110%, 0);
  opacity: 1;
  transition: transform var(--split-out) var(--e-quart);
  transition-delay: 0s;
}
[data-reveal].pf-split.is-in .wd,
[data-reveal].pf-split.is-in .ln {
  transform: translate3d(0, 0, 0);
  transition-duration: var(--split-in);
  transition-delay: calc(var(--i, 0) * var(--stagger));
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal].pf-split .wd, [data-reveal].pf-split .ln {
    transform: none; transition: none;
  }
}

/* --- Le nom, en display ------------------------------------------------- */

.pf-hero { min-height: 100svh; display: grid; align-content: center; }
.pf-hero__nom {
  font-size: var(--fs-xl);
  font-weight: 500;
  line-height: .92;
  letter-spacing: var(--p-tr);
  margin: 0;
  text-transform: uppercase;
}
.pf-hero__ligne {
  margin: clamp(18px, 3vh, 34px) 0 0;
  max-width: 46ch;
  color: var(--p-ink-2);
}

/* --- L'index des projets ------------------------------------------------ */

.pf-index { border-top: 1px solid var(--p-ink); margin-top: clamp(70px, 12vh, 150px); }

.pf-row {
  display: grid;
  grid-template-columns: 3rem 1fr auto;
  gap: var(--p-gutter);
  align-items: baseline;
  padding: clamp(18px, 2.6vh, 32px) 0;
  border-bottom: 1px solid var(--p-rule);
  text-decoration: none;
  color: inherit;
  position: relative;
  transition: color .4s var(--e-out);
}
.pf-row:hover { color: var(--p-accent); }

/* Le filet de survol balaie la ligne entière. */
.pf-row::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: var(--p-accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform .55s var(--e-quart);
}
.pf-row:hover::after { transform: scaleX(1); }

.pf-row__num  { font-size: var(--fs-nano); letter-spacing: .16em; color: var(--p-ink-3); }
.pf-row__nom  { font-size: var(--fs-l); font-weight: 500; line-height: 1; }
.pf-row__meta { font-size: var(--fs-nano); letter-spacing: .16em; text-transform: uppercase;
                color: var(--p-ink-3); text-align: right; }
.pf-row__desc { grid-column: 2 / 4; margin: 10px 0 0; color: var(--p-ink-2);
                max-width: 62ch; font-size: var(--fs-body); }

/* --- Blocs de texte ----------------------------------------------------- */

.pf-sec { padding: clamp(70px, 12vh, 150px) 0; }
.pf-sec__titre { font-size: var(--fs-m); font-weight: 500; margin: 0 0 var(--p-gutter); }
.pf-sec__corps { color: var(--p-ink-2); max-width: 62ch; margin: 0 0 1em; }

.pf-qa { border-top: 1px solid var(--p-rule); padding: clamp(16px, 2.4vh, 26px) 0; }
.pf-qa summary { cursor: pointer; list-style: none; display: flex;
                 justify-content: space-between; gap: 20px; align-items: baseline; }
.pf-qa summary::-webkit-details-marker { display: none; }
.pf-qa summary::after { content: "+"; color: var(--p-ink-3); font-size: var(--fs-micro); }
.pf-qa[open] summary::after { content: "–"; }
.pf-qa__q { font-size: var(--fs-m); font-weight: 500; }
.pf-qa__r { color: var(--p-ink-2); margin: 14px 0 0; max-width: 62ch; }

/* --- Pied et passerelle ------------------------------------------------- */

.pf-foot {
  border-top: 1px solid var(--p-ink);
  padding: var(--p-gutter) 0 calc(var(--p-gutter) * 3);
  display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap;
}
.pf-lien {
  color: var(--p-ink); text-decoration: none;
  border-bottom: 1px solid var(--p-rule); padding-bottom: 3px;
  transition: border-color .35s var(--e-out), color .35s var(--e-out);
}
.pf-lien:hover { color: var(--p-accent); border-bottom-color: var(--p-accent); }

/* Sur les écrans étroits, la grille à 12 colonnes n'a plus de sens. */
@media (max-width: 720px) {
  .pf-row { grid-template-columns: 2rem 1fr; }
  .pf-row__meta { grid-column: 2; text-align: left; margin-top: 6px; }
  .pf-row__desc { grid-column: 1 / -1; }
}

/* L'en-tête est fixe : les ancres doivent s'arrêter en dessous, sinon
   l'intertitre de section se cache derrière. */
[id] { scroll-margin-top: calc(var(--p-gutter) * 2 + 2.2rem); }

/* Et le contenu doit cesser de défiler à nu sous lui. */
.pf-head::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: calc(100% + 26px);
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg,
    var(--p-bg) 0%,
    color-mix(in srgb, var(--p-bg) 88%, transparent) 62%,
    transparent 100%);
}

/* ==========================================================================
   La section Work — relevée sur jonasreymondin.com/work

   Ce n'est pas une liste : c'est un feuilletage. Chaque projet occupe 1,5
   hauteur d'écran de scroll ; son texte est en `sticky top:0` dans la moitié
   droite ; derrière, une couche d'images plein cadre s'échange au fil du
   défilement. Une carte de navigation reste en bas, un pourcentage au bord
   droit.

   Géométrie mesurée chez lui : section 1380px pour un écran de 920, bloc
   sticky de 735px soit exactement la moitié de la largeur, titre à 60,9px,
   pastilles et pager à 10px, pourcentage à 16px.
   ========================================================================== */

.pf-work { position: relative; }

/* --- La couche d'images, derrière tout ---------------------------------- */

.pf-work__bg { position: fixed; inset: 0; z-index: 0; background: var(--p-ink); }
.pf-shot {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .7s var(--e-out);
}
.pf-shot.is-on { opacity: 1; }
.pf-shot img { width: 100%; height: 100%; object-fit: cover; display: block;
               /* Calées par le haut : une image 4:3 dans un écran plus large
                  perd du haut et du bas. Centrée, elle remontait l'appareil
                  dans la zone du texte ; calée en haut, il redescend
                  d'environ 90 px et la colonne de droite se libère. */
               object-position: 50% 0%; }
/* Le voile : sans lui le texte crème se perd dans les hautes lumières. */
.pf-shot::after {
  content: "";
  position: absolute; inset: 0;
  /* Les visuels des projets sont clairs — plâtre, papier, verre, acier,
     terre cuite. Le voile sombre du modèle d'origine les éteignait sans
     rendre le texte crème lisible pour autant. On fait l'inverse : texte à
     l'encre, et un voile clair seulement là où il se pose, en haut à droite,
     pour que l'appareil garde toute sa lumière. */
  background:
    radial-gradient(120% 75% at 90% 10%,
      color-mix(in srgb, var(--p-bg) 66%, transparent) 0%,
      color-mix(in srgb, var(--p-bg) 44%, transparent) 38%,
      transparent 68%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--p-bg) 28%, transparent) 0%,
      transparent 22%);
}

/* --- Une fiche projet --------------------------------------------------- */

.pf-proj { position: relative; height: 150vh; z-index: 1; }
.pf-proj__inner {
  position: sticky;
  top: 0;
  height: 100svh;
  display: grid;
  grid-template-columns: 1fr 1fr;          /* sa moitié / moitié */
  align-content: start;
  padding: var(--p-gutter);
  color: var(--p-ink);
  pointer-events: none;
}

/* Le numéro géant, en haut à gauche. */
.pf-proj__num {
  font-size: clamp(4rem, 10vw, 9.5rem);
  font-weight: 400;
  line-height: .8;
  letter-spacing: -.04em;
  margin: 0;
  opacity: .96;
}

/* La colonne de droite : titre + année, pastilles, description. */
.pf-proj__meta { display: flex; flex-direction: column; gap: 18px; }
.pf-proj__head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 20px;
}
.pf-proj__nom { font-size: clamp(2rem, 4.2vw, 3.8rem); font-weight: 400; line-height: 1; margin: 0; }
.pf-proj__an  { font-size: var(--fs-micro); opacity: .8; }

.pf-proj__tags { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.pf-proj__tags li {
  font-size: .63rem;
  line-height: 1;
  padding: 7px 12px;
  border-radius: 999px;            /* les seules pastilles du site : c'est sa grammaire */
  background: var(--p-bg);
  color: var(--p-ink);
  white-space: nowrap;
  /* Sur une image claire, une pastille sans filet se confond avec le fond. */
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--p-ink) 14%, transparent);
}
/* 54ch plutôt que 42 : une ligne de moins par projet, et c'est cette ligne
   qui descendait sur l'appareil dans les visuels où il est placé haut. */
.pf-proj__desc { max-width: 54ch; margin: 0; font-size: var(--fs-body); }

/* --- Le pourcentage, au bord droit -------------------------------------- */

.pf-progress {
  position: fixed;
  right: var(--p-gutter);
  top: 50%;
  transform: translateY(-50%);
  z-index: 20;
  font-size: var(--fs-body);
  color: var(--p-ink);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

/* --- La carte de navigation, en bas ------------------------------------- */

.pf-pager {
  position: fixed;
  left: 50%;
  bottom: calc(var(--p-gutter) * 1.2);
  transform: translateX(-50%);
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 10px 10px 10px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--p-ink) 52%, transparent);
  backdrop-filter: blur(14px);
  color: var(--p-bg);
  text-decoration: none;
  transition: background .35s var(--e-out);
}
.pf-pager:hover { background: color-mix(in srgb, var(--p-ink) 68%, transparent); }
.pf-pager__vign { width: 76px; height: 46px; border-radius: 6px; object-fit: cover; display: block; }
.pf-pager__txt  { display: flex; flex-direction: column; gap: 5px; min-width: 190px; }
.pf-pager__num  { font-size: .63rem; opacity: .72; font-variant-numeric: tabular-nums; }
.pf-pager__nom  { font-size: var(--fs-body); line-height: 1; text-transform: uppercase; }
.pf-pager__fleche {
  width: 30px; height: 30px; flex: none;
  border-radius: 50%;
  background: var(--p-accent);
  display: grid; place-items: center;
  font-size: .7rem;
  transition: transform .4s var(--e-quart);
}
.pf-pager:hover .pf-pager__fleche { transform: translate(2px, -2px); }

@media (max-width: 720px) {
  .pf-proj__inner { grid-template-columns: 1fr; gap: 22px; }
  .pf-pager__txt { min-width: 120px; }
  .pf-progress { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .pf-shot { transition: none; }
}

.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* Au-dessus des images plein cadre, tout le chrome de la page bascule en
   clair — sans quoi la navigation et les mentions de coin, en encre sombre,
   disparaissent. */
/* Les visuels sont clairs : le chrome reste à l'encre au-dessus d'eux.
   (Il passait au crème tant que les images étaient les posters sombres du
   film.) La transition est gardée pour les visuels sombres à venir. */
body.is-on-work .pf-nav a,
body.is-on-work .pf-head .pf-micro,
body.is-on-work .pf-corners .pf-micro {
  color: var(--p-ink);
  transition: color .45s var(--e-out);
}
body.is-on-work .pf-head::before { opacity: 0; transition: opacity .45s var(--e-out); }
.pf-head::before { transition: opacity .45s var(--e-out); }

/* Le bloc de texte doit commencer sous l'en-tête, pas dessous au sens propre :
   sinon le titre du projet passe derrière la navigation. */
.pf-proj__inner { padding-top: calc(var(--p-gutter) * 2 + 2.4rem); }

/* Et la carte de navigation ne doit pas écraser les mentions du bas. */
body.is-on-work .pf-corners { opacity: 0; transition: opacity .4s var(--e-out); }
.pf-corners { transition: opacity .4s var(--e-out); }

/* Le pager et le pourcentage n'existent que dans la section Work. */
.pf-pager, .pf-progress { opacity: 0; pointer-events: none; transition: opacity .45s var(--e-out); }
body.is-on-work .pf-pager { opacity: 1; pointer-events: auto; }
body.is-on-work .pf-progress { opacity: 1; }

/* La couche d'images aussi. Elle est fixe et plein écran : sans cette règle
   elle restait affichée après le dernier projet, et la section Méthode
   s'écrivait par-dessus la dernière image, illisible. */
.pf-work__bg { opacity: 0; transition: opacity .6s var(--e-out); }
body.is-on-work .pf-work__bg { opacity: 1; }

/* L'année vit sur la ligne du titre, pas en note de bas de page : chez lui
   elle a le même poids visuel et ferme la ligne. */
.pf-proj__an {
  font-size: clamp(.9rem, 1.5vw, 1.35rem);
  opacity: .82;
  align-self: flex-start;
  padding-top: .35em;
  white-space: nowrap;
}
/* La colonne de droite ne doit pas s'étirer jusqu'au bord de l'écran. */
.pf-proj__meta { max-width: 44rem; }
