/* ==========================================================================
   Mijoh Studio — feuille de style principale
   Valeurs reprises telles quelles de la maquette « Atelier Nord v2 clair ».
   ========================================================================== */

/* --- Typographie ---------------------------------------------------------
   Variables fontsource, servies depuis notre domaine. latin-ext n'est
   téléchargé que si un glyphe le réclame (unicode-range).                  */

@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-display: swap;
  font-weight: 400 900;
  src: url('./fonts/schibsted-grotesk-latin-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-display: swap;
  font-weight: 400 900;
  src: url('./fonts/schibsted-grotesk-latin-ext-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}
/* Serif à fort contraste, réservée au titre du hero. */
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url('./fonts/instrument-serif-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url('./fonts/instrument-serif-latin-ext-400-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('./fonts/geist-latin-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('./fonts/geist-latin-ext-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}

/* --- Jetons --------------------------------------------------------------- */

:root {
  --paper: #f5f3ef;
  --ink: #0a0a0a;
  --ink-soft: #3b3934;
  --ink-mute: #5e5c56;
  --rule: #dcd7cc;
  --rule-soft: #cfc9bd;
  --plate: #e7e3da;
  --accent: #1a3a2a;
  /* Courbe du dépliement des réalisations, relevée image par image sur la
     référence : l'essentiel joué en ~390ms, stabilisé à ~760ms. Départ très
     rapide, longue fin douce — un `expo.out`. */
  --deploi: cubic-bezier(0.16, 1, 0.3, 1);

  --display: 'Schibsted Grotesk', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --serif: 'Instrument Serif', 'Times New Roman', Times, serif;
  --body: 'Geist', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --gutter: clamp(20px, 4vw, 64px);
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --- Base ----------------------------------------------------------------- */

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

html {
  scroll-behavior: smooth;
  /* Décale les ancres pour qu'elles ne passent pas sous l'en-tête fixe. */
  scroll-padding-top: 84px;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  min-height: 100vh;
  overflow-x: hidden;
  position: relative;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

::selection {
  background: var(--ink);
  color: var(--paper);
}

a {
  color: var(--ink);
  text-decoration: none;
}

a:hover {
  color: var(--accent);
}

img,
svg {
  max-width: 100%;
  display: block;
}

h1,
h2,
h3,
p {
  margin: 0;
}

/* Visible uniquement pour les lecteurs d'écran. */
.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;
}

/* Anneau de focus homogène et toujours visible au clavier. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 100;
  padding: 14px 18px;
  background: var(--ink);
  color: var(--paper);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transform: translateY(-160%);
  transition: transform 220ms var(--ease);
}

.skip-link:focus-visible {
  transform: translateY(0);
  color: var(--paper);
}

/* --- Utilitaires de la maquette ------------------------------------------ */

.eyebrow {
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.rule-top {
  border-top: 1px solid var(--rule);
}

.section {
  padding: clamp(60px, 12vh, 140px) var(--gutter) clamp(80px, 16vh, 180px);
}

.grid12 {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(16px, 2vw, 32px);
}

/* --- Révélation au scroll -------------------------------------------------
   Le masquage n'existe que si JS a pris la main (classe .js posée en <head>).
   Sans JS, ou si le script échoue, tout le contenu reste lisible.           */

.js [data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 500ms var(--ease), transform 500ms var(--ease);
}

.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* Position finale imposée, sans transition. Le filet de sécurité du script
   pose cette classe pour garantir qu'aucun texte ne reste durablement en
   opacité intermédiaire — un texte à mi-fondu est un texte à faible
   contraste. */
.js [data-reveal].settled {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

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

/* Le fond n'est pas décoratif : sans lui, l'en-tête étant `fixed` et
   transparent, tout le contenu de la page défile *à travers* lui et se
   superpose à ses libellés. Le défaut passait inaperçu en cours de défilement,
   mais en butée de bas de page la dernière ligne du bloc contact s'y fige — on
   lisait « temps ? » par-dessus « MIJOH STUDIO ». Le ton est celui du papier :
   invisible sur la page, opaque pour ce qui passe dessous. */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40;
  background: var(--paper);
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 22px var(--gutter);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* --- Élargissement des zones tactiles -------------------------------------
   Ces liens sont typographiquement petits par choix de maquette. Le couple
   `padding` + `margin` négatif porte la zone touchable à 44px sans déplacer
   quoi que ce soit à l'écran : la boîte grandit, la marge la reprend.       */

.brand,
.nav-desktop a,
.contact-foot a,
.contact-foot span {
  padding: 15px 0;
  margin: -15px 0;
}

.brand {
  font-weight: 500;
  letter-spacing: 0.16em;
}

.nav-desktop {
  display: flex;
  gap: clamp(16px, 2.5vw, 40px);
}

.nav-desktop a {
  opacity: 0.65;
  transition: opacity 300ms var(--ease), color 300ms var(--ease);
}

.nav-desktop a:hover,
.nav-desktop a:focus-visible {
  opacity: 1;
}

.nav-toggle {
  display: none;
  appearance: none;
  background: none;
  border: 0;
  padding: 12px 0 12px 16px;
  min-height: 44px;
  font: inherit;
  color: inherit;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
}

/* --- Panneau de navigation mobile ---------------------------------------- */

.nav-panel {
  position: fixed;
  inset: 0;
  z-index: 39;
  background: var(--paper);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  padding: 96px var(--gutter) var(--gutter);
  /* Fermé : retiré du flux ET de l'ordre de tabulation. */
  visibility: hidden;
  opacity: 0;
  transition: opacity 320ms var(--ease), visibility 0s linear 320ms;
}

.nav-panel[data-open='true'] {
  visibility: visible;
  opacity: 1;
  transition: opacity 320ms var(--ease), visibility 0s;
}

.nav-panel a {
  display: block;
  padding: 14px 0;
  min-height: 44px;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(2rem, 9vw, 3rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
  text-transform: none;
  border-bottom: 1px solid var(--rule);
}

.nav-panel-foot {
  margin-top: auto;
  padding-top: 32px;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

body[data-nav-open='true'] {
  overflow: hidden;
}

/* --- Hero ----------------------------------------------------------------- */

.hero {
  min-height: 100vh;
  display: grid;
  grid-template-rows: 1fr auto;
  padding: 0 var(--gutter) clamp(28px, 4vh, 56px);
}

.hero-main {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-bottom: clamp(24px, 5vh, 72px);
}

.hero-eyebrow {
  margin: 0 0 clamp(24px, 6vh, 64px);
}

/* Serif à fort contraste : bas-de-casse, chasse plus large que la grotesque,
   donc une taille et un interlettrage propres plutôt que ceux de la maquette. */
.hero-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(3.8rem, 15vw, 16.5rem);
  line-height: 0.88;
  letter-spacing: -0.025em;
  text-transform: none;
}

/* Le filtre « goo » fusionne les lettres quand le flou est élevé, puis les
   laisse se détacher à mesure qu'il retombe à zéro. Il n'est appliqué que
   pendant l'animation, puis retiré : un filtre SVG permanent coûte une passe
   de rendu pour rien. */
.hero-title[data-goo='running'] {
  filter: url(#goo);
  will-change: filter;
}

.goo-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.hero-foot {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(24px, 4vw, 64px);
  margin-top: clamp(28px, 5vh, 64px);
  align-items: end;
}

.hero-line {
  height: 1px;
  background: var(--rule-soft);
}

.hero-lede {
  max-width: 34ch;
  font-size: clamp(1rem, 1.35vw, 1.375rem);
  line-height: 1.45;
  color: var(--ink-soft);
}

.hero-meta {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.hero-scroll {
  display: flex;
  align-items: center;
  gap: 14px;
}

.hero-scroll span:last-child {
  display: block;
  width: 1px;
  height: 56px;
  background: linear-gradient(var(--ink-mute), transparent);
}

/* --- Manifeste ------------------------------------------------------------ */

.manifesto {
  padding: clamp(80px, 18vh, 200px) var(--gutter);
}

.manifesto-label {
  grid-column: 1 / 3;
}

.manifesto-lead {
  grid-column: 3 / -1;
  max-width: 22ch;
}

.manifesto-lead p {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.75rem, 4.4vw, 4.25rem);
  line-height: 1.06;
  letter-spacing: -0.03em;
}

.manifesto-body {
  grid-column: 7 / -1;
  margin-top: clamp(40px, 8vh, 96px);
  display: grid;
  gap: clamp(20px, 3vh, 32px);
  max-width: 52ch;
}

.manifesto-body p {
  font-size: clamp(1rem, 1.3vw, 1.25rem);
  line-height: 1.6;
  color: var(--ink-soft);
}

.manifesto-body p + p {
  color: var(--ink-mute);
}

/* --- Services -------------------------------------------------------------- */

.services-label {
  margin: 0 0 clamp(40px, 8vh, 96px);
}

.svc {
  display: block;
  border-top: 1px solid var(--rule);
  padding: clamp(22px, 3.6vh, 44px) 0;
  color: inherit;
}

.svc:last-of-type {
  border-bottom: 1px solid var(--rule);
}

.svc-row {
  display: grid;
  grid-template-columns: clamp(56px, 8vw, 120px) 1.1fr 1fr auto;
  gap: clamp(16px, 2vw, 40px);
  align-items: baseline;
}

.svc-n {
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--ink-mute);
}

.svc-t {
  display: block;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(1.6rem, 3.6vw, 3.5rem);
  line-height: 1;
  letter-spacing: -0.03em;
  transition: transform 320ms var(--ease), color 320ms var(--ease);
}

.svc-d {
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-mute);
}

.svc-a {
  opacity: 0;
  transform: translateX(-10px);
  transition: opacity 320ms var(--ease), transform 320ms var(--ease);
  font-size: 1.25rem;
}

.svc:hover .svc-t,
.svc:focus-visible .svc-t {
  transform: translateX(18px);
  color: var(--accent);
}

.svc:hover .svc-a,
.svc:focus-visible .svc-a {
  opacity: 1;
  transform: translateX(0);
}

/* --- Réalisations ---------------------------------------------------------- */

/* Les projets démarrent 380px à droite de leur place : sans cette coupe, le
   document s'élargit et une barre de défilement horizontale apparaît.
   `clip` plutôt que `hidden` — il coupe sans créer de conteneur de
   défilement, donc sans effet de bord sur le reste. */
#travaux {
  overflow-x: clip;
}

.work-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: clamp(24px, 4vh, 48px);
}

/* --- Réalisations : une ligne par projet -----------------------------------
   Proportions relevées au pixel sur lamalama.com, à 1440px :

     nom            colonnes 1-2, 20px, graisse 400
     étiquettes     colonne 3, 10px monospace, cadre fin, angles vifs
     « Voir plus »  colonne 6
     pellicule      à partir de la colonne 8, débordant de la marge droite
     clichés        120px de haut repliés, 400px dépliés, 8px d'écart,
                    deux formats seulement : 3:2 et 4:5

   Ce qui change, c'est le registre : papier, filets et vert profond au lieu du
   noir plein cadre de la référence. Les clichés sont posés sur une plaque avec
   un filet — chez eux ils se touchent, ici ils sont posés.

   `#travaux` est en `overflow-x: clip` (plus haut) : c'est lui qui contient le
   débordement de la pellicule sans créer de barre horizontale sur la page. */

/* Flux de blocs, surtout pas une grille sur `.work-list` : une piste `auto` se
   dimensionne sur le contenu de ses éléments, et la pellicule en
   `width: max-content` ferait enfler la ligne bien au-delà de la fenêtre. */
.wk {
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 0 clamp(16px, 1.7vw, 24px);
  align-items: start;
  padding-block: 22px 26px;
}

/* Le placement fait tout le travail du dépliement, sans changer le HTML :

   replié   — la description et les boutons sont retirés du flux, la pellicule
              tient donc sur la ligne du nom, en colonnes 8 à 12.
   déplié   — la description prend ces colonnes, les boutons s'installent sur la
              ligne suivante, et la pellicule, passée en pleine largeur, n'a plus
              de place avant la troisième ligne.

   Le saut de position qui en résulte est rattrapé par une inversion FLIP dans
   `motion.js` : le placement change d'un coup, l'œil voit un glissement.     */
.wk-line {
  grid-column: 1 / -1;
  height: 1px;
  background: var(--rule);
  margin-bottom: 22px;
  transform-origin: left center;
}

.wk-name {
  grid-column: 1 / 3;
  overflow: hidden;
  font-size: 20px;
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

/* Le `span` intérieur existe pour l'arrivée : c'est lui qui monte, le `h3` ne
   sert que de fenêtre. */
.wk-name span {
  display: block;
  transition: color 380ms var(--ease);
}

.wk-tags {
  grid-column: 3 / 6;
  margin: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* Angles vifs et cadre fin, pas des pastilles : la référence n'arrondit rien,
   et l'arrondi jurait avec les filets du reste du site. */
.wk-tags li {
  padding: 3px 7px;
  border: 1px solid var(--rule);
  font-family: 'Geist', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-mute);
  transition: border-color 320ms var(--ease), color 320ms var(--ease);
}

.wk-more {
  grid-column: 6 / 8;
  align-self: start;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 0 5px;
  border: 0;
  border-bottom: 1px solid var(--rule);
  background: none;
  font-family: 'Geist', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
  cursor: pointer;
  transition: color 320ms var(--ease), border-color 320ms var(--ease);
}

/* Ouvert, la flèche pivote : elle pointait vers l'extérieur pour « ouvrir »,
   elle rentre pour « replier ». Même signe, deux sens. */
.wk-arrow {
  display: inline-block;
  transition: transform 700ms var(--deploi);
}

.wk.is-open .wk-arrow {
  transform: rotate(180deg);
}

/* --- Le dépliement ---------------------------------------------------------
   Replié, le panneau est retiré du flux : c'est ce qui laisse la pellicule
   remonter sur la ligne du nom. `display` ne s'anime pas — l'apparition est
   portée par l'opacité et une remontée, déclenchées à la frame suivante par
   `motion.js`.                                                              */
.wk-panel {
  display: contents;
}

.wk:not(.is-open) .wk-panel {
  display: none;
}

.wk-desc {
  grid-column: 8 / -1;
  margin: 0;
  max-width: 62ch;
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1.55;
}

.wk-acts {
  grid-column: 1 / 8;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  /* La marge basse est ce qui sépare les boutons de la galerie : sans elle le
     bouton vient toucher le premier cliché, les deux cadres se confondent. */
  margin: 26px 0 28px;
}

.wk-btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 15px 18px;
  border: 1px solid var(--rule);
  font-family: 'Geist', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
  transition: color 320ms var(--ease), border-color 320ms var(--ease),
    background-color 320ms var(--ease);
}

.wk-btn:hover,
.wk-btn:focus-visible {
  color: var(--paper);
  background: var(--accent);
  border-color: var(--accent);
}

/* Apparition du contenu déplié, déclenchée par `motion.js` à la frame qui suit
   la bascule de `display`. */
.js .wk-desc,
.js .wk-acts {
  opacity: 0;
  transform: translateY(12px);
}

.js .wk.is-shown .wk-desc,
.js .wk.is-shown .wk-acts {
  opacity: 1;
  transform: none;
  transition: opacity 620ms var(--deploi) 140ms, transform 620ms var(--deploi) 140ms;
}

/* --- La pellicule ----------------------------------------------------------
   Elle démarre en colonne 8 et sort de la marge droite : c'est ce débordement
   qui signale qu'il reste des clichés, sans bouton ni flèche.

   La référence la met en `pointer-events: none` — les images y sont donc
   inatteignables, seule la dérive au défilement en découvre un peu plus. On
   garde le débordement à l'identique mais le conteneur reste défilant, et
   glissable à la souris : même apparence, images réellement accessibles. */
.wk-band {
  grid-column: 8 / -1;
  margin-right: calc(var(--gutter) * -1);
  padding-right: var(--gutter);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

/* Pas de `scroll-snap` sur la pellicule, et ce n'est pas un oubli.
   La dérive au défilement translate la pellicule à chaque frame ; ses points
   d'ancrage se déplacent donc en continu, et le moteur de calage recalait le
   `scrollLeft` derrière — un tremblement horizontal d'un ou deux pixels sur
   quasiment chaque pas de défilement vertical (mesuré : 39 pas sur 40).
   La bande partait en prime décalée de 17 à 80px selon la ligne, le premier
   cliché n'étant jamais aligné sur sa colonne. */

.wk.is-open .wk-band {
  grid-column: 1 / -1;
}

.wk-band::-webkit-scrollbar {
  display: none;
}

/* La bande est un `tabindex="0"` : elle doit montrer qu'elle a le focus, sinon
   l'utilisateur au clavier pousse les flèches sans savoir ce qu'il pilote. */
.wk-band:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 3px;
}

.wk-strip {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  align-items: stretch;
  gap: 8px;
  width: max-content;
  will-change: transform;
}

.wk-strip li {
  flex: none;
  background: var(--plate);
  border: 1px solid var(--rule);
  overflow: hidden;
  transition: opacity 420ms var(--ease);
}

/* Les proportions étant fixes (3:2 et 4:5), animer la seule hauteur suffit :
   la largeur suit toute seule. C'est ce qui rend le grossissement 120 → 400
   fluide sans toucher à deux propriétés à la fois.

   `user-drag` coupe le glisser-déposer natif de l'image : sans lui, appuyer sur
   un cliché lance le drag-and-drop du navigateur, qui avale la séquence de
   pointeur et rend la bande impossible à faire glisser. */
.wk-strip img {
  -webkit-user-drag: none;
  user-select: none;
  display: block;
  height: 120px;
  width: auto;
  object-fit: cover;
  transition: height 700ms var(--deploi), transform 620ms var(--ease);
}

.wk.is-open .wk-strip img {
  height: 400px;
}

.wk-band.is-drag {
  cursor: grabbing;
  user-select: none;
}

@media (hover: hover) {
  .wk-band {
    cursor: grab;
  }

  /* Survol de la ligne : le nom passe à l'accent, la flèche décolle, les
     étiquettes se raffermissent. */
  .wk:hover .wk-name span {
    color: var(--accent);
  }

  .wk:hover .wk-more {
    color: var(--accent);
    border-color: var(--accent);
  }

  .wk:not(.is-open):hover .wk-arrow {
    transform: translate(3px, -3px);
  }

  .wk:hover .wk-tags li {
    border-color: var(--rule-soft);
    color: var(--ink-soft);
  }

  /* Survol d'un cliché : les autres reculent, celui-ci avance à peine. */
  .wk-band:hover .wk-strip li {
    opacity: 0.42;
  }

  .wk-band .wk-strip li:hover {
    opacity: 1;
  }

  .wk-strip li:hover img {
    transform: scale(1.05);
  }
}

.wk-more:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
}

/* --- Arrivée d'une ligne ---------------------------------------------------
   Une cascade, pas cinq animations séparées : le filet se trace, le nom monte
   derrière sa fenêtre, les étiquettes et le lien remontent, les clichés
   arrivent de la droite en décalé. `--i` porte le rang dans la série, `--d` le
   retard qui en découle.

   État de départ posé uniquement sous `.js` : sans JavaScript, rien n'est
   caché — le contenu ne dépend jamais d'une animation.                     */

.js [data-wk] .wk-line {
  transform: scaleX(0);
  transition: transform 1000ms cubic-bezier(0.22, 1, 0.36, 1);
}

.js [data-wk] .wk-name span,
.js [data-wk] .wk-tags li,
.js [data-wk] .wk-more,
.js [data-wk] .wk-strip li {
  opacity: 0;
  transition: opacity 900ms cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0ms),
    transform 900ms cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0ms);
}

.js [data-wk] .wk-name span {
  transform: translateY(105%);
  --d: 90ms;
}

.js [data-wk] .wk-tags li {
  transform: translateY(10px);
  --d: calc(210ms + var(--i, 0) * 50ms);
}

.js [data-wk] .wk-more {
  transform: translateY(10px);
  --d: 320ms;
}

/* Les clichés arrivent de la droite : la pellicule se pose en glissant dans le
   sens où elle se lit. */
.js [data-wk] .wk-strip li {
  transform: translate3d(40px, 0, 0);
  --d: calc(380ms + var(--i, 0) * 85ms);
}

.wk-tags li:nth-child(1) { --i: 0; }
.wk-tags li:nth-child(2) { --i: 1; }
.wk-tags li:nth-child(3) { --i: 2; }

.wk-strip li:nth-child(1) { --i: 0; }
.wk-strip li:nth-child(2) { --i: 1; }
.wk-strip li:nth-child(3) { --i: 2; }
.wk-strip li:nth-child(4) { --i: 3; }
.wk-strip li:nth-child(5) { --i: 4; }

.js [data-wk].is-in .wk-line {
  transform: scaleX(1);
}

.js [data-wk].is-in .wk-name span,
.js [data-wk].is-in .wk-tags li,
.js [data-wk].is-in .wk-more,
.js [data-wk].is-in .wk-strip li {
  opacity: 1;
  transform: none;
}

/* Une fois la ligne posée, on rend la main aux transitions d'interaction :
   sans cela le survol hériterait de la durée et du retard de l'arrivée, et un
   cliché mettrait une seconde à réagir au pointeur. */
.js [data-wk].is-in .wk-strip li {
  transition: opacity 420ms var(--ease);
}

.js [data-wk].is-in .wk-name span {
  transition: color 380ms var(--ease);
}

.js [data-wk].is-in .wk-more,
.js [data-wk].is-in .wk-tags li {
  transition: color 320ms var(--ease), border-color 320ms var(--ease);
}

/* --- Studio ---------------------------------------------------------------- */

.studio-label {
  grid-column: 1 / 3;
}

.studio-body {
  grid-column: 3 / 10;
  display: grid;
  gap: clamp(20px, 3vh, 32px);
  max-width: 58ch;
}

.studio-lead {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.375rem, 2.4vw, 2.25rem);
  line-height: 1.22;
  letter-spacing: -0.025em;
}

.studio-body p:not(.studio-lead) {
  font-size: clamp(1rem, 1.2vw, 1.125rem);
  line-height: 1.65;
  color: var(--ink-soft);
}

.studio-body p:last-child {
  color: var(--ink-mute);
}

.studio-stats {
  grid-column: 11 / 13;
  display: grid;
  gap: 28px;
  align-content: start;
}

.stat-n {
  display: block;
  font-family: var(--display);
  font-size: 2.25rem;
  font-weight: 500;
  letter-spacing: -0.03em;
}

.stat-l {
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

/* --- Contact --------------------------------------------------------------- */

.contact {
  padding: clamp(80px, 18vh, 200px) var(--gutter) clamp(36px, 5vh, 56px);
  min-height: 82vh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(60px, 12vh, 140px);
}

.contact-label {
  margin: 0 0 clamp(28px, 5vh, 56px);
}

.contact-lead {
  margin: 0 0 clamp(32px, 6vh, 72px);
  max-width: 26ch;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.5rem, 3.2vw, 3rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
}

.contact-mail {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.5rem, 7.4vw, 8rem);
  line-height: 0.95;
  letter-spacing: -0.045em;
  transition: color 320ms var(--ease);
  overflow-wrap: anywhere;
  /* Même compensation : sur petit écran la ligne ne fait que 23px de haut. */
  padding: 12px 0;
  margin: -12px 0;
}

.contact-foot {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  align-items: end;
  border-top: 1px solid var(--rule);
  padding-top: 24px;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.contact-foot-l {
  display: flex;
  flex-wrap: wrap;
  column-gap: clamp(16px, 2vw, 32px);
  /* Assez d'air pour que deux zones tactiles élargies ne se chevauchent pas
     quand la ligne passe à la ligne suivante. */
  row-gap: 34px;
}

.contact-foot-r {
  display: flex;
  justify-content: flex-end;
  gap: clamp(16px, 2vw, 32px);
}

/* --- Formulaire ------------------------------------------------------------ */

.form {
  margin-top: clamp(48px, 9vh, 104px);
  display: grid;
  gap: clamp(18px, 2.4vh, 28px);
  max-width: 62ch;
}

.form-row {
  display: grid;
  gap: 8px;
}

.form-duo {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(18px, 2.4vw, 28px);
}

.form label {
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.form input,
.form textarea {
  width: 100%;
  min-height: 44px;
  padding: 12px 0;
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  border-radius: 0;
  transition: border-color 280ms var(--ease);
}

.form textarea {
  resize: vertical;
  min-height: 108px;
}

.form input:hover,
.form textarea:hover {
  border-bottom-color: var(--ink-mute);
}

.form input:focus,
.form textarea:focus {
  outline: none;
  border-bottom-color: var(--accent);
}

.form input:focus-visible,
.form textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

.form input[aria-invalid='true'],
.form textarea[aria-invalid='true'] {
  border-bottom-color: #8c2f1d;
}

.field-error {
  font-size: 0.8125rem;
  line-height: 1.4;
  letter-spacing: 0;
  text-transform: none;
  color: #8c2f1d;
  min-height: 0;
}

/* Piège à robots : hors écran, hors tabulation, invisible aux lecteurs d'écran. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-submit {
  justify-self: start;
  appearance: none;
  min-height: 48px;
  padding: 14px 32px;
  font-family: var(--body);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 0;
  cursor: pointer;
  transition: background 280ms var(--ease), color 280ms var(--ease),
    transform 280ms var(--ease);
}

.form-submit:hover {
  background: var(--accent);
  border-color: var(--accent);
  transform: translateY(-2px);
}

.form-submit:active {
  transform: translateY(0);
}

.form-submit[disabled] {
  opacity: 0.55;
  cursor: progress;
  transform: none;
}

.form-status {
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.form-status[data-state='error'] {
  color: #8c2f1d;
}

.form-status[data-state='ok'] {
  color: var(--accent);
}

/* --- Curseur --------------------------------------------------------------- */

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 10px;
  height: 10px;
  border: 1px solid var(--ink);
  border-radius: 50%;
  pointer-events: none;
  z-index: 90;
  opacity: 0;
  background: transparent;
  mix-blend-mode: multiply;
  transition: width 260ms var(--ease), height 260ms var(--ease),
    background-color 260ms var(--ease), border-color 260ms var(--ease),
    opacity 260ms var(--ease);
}

/* Au survol, l'anneau s'ouvre au lieu de se remplir : le texte qu'il traverse
   reste lisible. Un disque plein masquait le mot pointé. */
.cursor[data-hot='true'] {
  width: 46px;
  height: 46px;
  border-color: var(--accent);
  background-color: rgba(26, 58, 42, 0.07);
}

/* --- Pages secondaires ------------------------------------------------------ */

.prose {
  padding: clamp(120px, 22vh, 220px) var(--gutter) clamp(80px, 16vh, 160px);
  max-width: 72ch;
  display: grid;
  gap: clamp(16px, 2.2vh, 24px);
}

.prose h1 {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: 1.05;
  letter-spacing: -0.035em;
  margin-bottom: clamp(12px, 2vh, 24px);
}

.prose h2 {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(1.125rem, 1.8vw, 1.375rem);
  letter-spacing: -0.01em;
  margin-top: clamp(20px, 3vh, 32px);
}

.prose p,
.prose li {
  font-size: 1rem;
  line-height: 1.65;
  color: var(--ink-soft);
}

.prose a {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ==========================================================================
   Adaptations — les points de rupture de la maquette, puis le mobile.
   ========================================================================== */

@media (max-width: 820px) {
  .hero-foot,
  .contact-foot {
    grid-template-columns: 1fr;
  }

  .svc-row {
    grid-template-columns: 56px 1fr;
  }

  .svc-d {
    display: none;
  }

  .hide-sm {
    display: none !important;
  }

  /* Bascule vers la navigation en panneau. */
  .nav-desktop {
    display: none;
  }

  .nav-toggle {
    display: block;
  }

  /* Les colonnes de 12 se replient. */
  .manifesto-label,
  .manifesto-lead,
  .manifesto-body,
  .studio-label,
  .studio-body,
  .studio-stats {
    grid-column: 1 / -1;
  }

  .manifesto-lead {
    max-width: 18ch;
  }

  .studio-stats {
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 16px;
    margin-top: clamp(24px, 4vh, 40px);
  }

  /* Douze colonnes ne tiennent plus : tout s'empile sur toute la largeur, la
     pellicule passe dessous — repliée comme dépliée. */
  .wk-name,
  .wk-tags,
  .wk-more,
  .wk-desc,
  .wk-acts,
  .wk-band {
    grid-column: 1 / -1;
  }

  .wk-desc {
    margin-top: 18px;
  }

  .wk-acts {
    margin-top: 18px;
  }

  /* 400px de haut sur un écran étroit mange tout l'espace : on redescend. */
  .wk.is-open .wk-strip img {
    height: 260px;
  }

  .wk-tags {
    margin-top: 14px;
  }

  .wk-more {
    margin-top: 16px;
    justify-self: start;
  }

  .wk-band {
    margin-top: 22px;
  }

  .contact-foot-r {
    justify-content: flex-start;
  }
}

@media (max-width: 560px) {
  .form-duo {
    grid-template-columns: 1fr;
  }

  .work-head {
    display: block;
  }

  .wk {
    padding-block: 20px 24px;
  }
}

/* Le survol n'existe pas au doigt : on montre l'état complet. */
@media (hover: none) {
  .svc-a {
    opacity: 1;
    transform: none;
  }
}

/* ==========================================================================
   Mouvement réduit — on retire l'animation, jamais le contenu.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .js [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }

  /* La cascade des lignes est annulée : filet, nom, étiquettes et clichés sont
     posés d'emblée. Le filet doit être remis à scaleX(1) explicitement, sans
     quoi il resterait invisible. */
  .js [data-wk] .wk-line {
    transform: scaleX(1) !important;
  }

  .js [data-wk] .wk-name span,
  .js [data-wk] .wk-more,
  .js [data-wk] .wk-desc,
  .js [data-wk] .wk-acts,
  .js [data-wk] .wk-tags li,
  .js [data-wk] .wk-strip li,
  .js [data-wk] .wk-strip li img {
    opacity: 1 !important;
    transform: none !important;
  }

  /* La dérive horizontale de la bande est neutralisée. */
  .wk-strip {
    transform: none !important;
    will-change: auto;
  }

  .hero-title[data-goo] {
    filter: none !important;
  }

  .wk-strip li:hover img {
    transform: none;
  }

  .svc:hover .svc-t {
    transform: none;
  }

  .form-submit:hover {
    transform: none;
  }

  .cursor {
    display: none;
  }
}
