/* L'IDENTITÉ ALEXIS VISUAL
   Le site est surtout en noir : #efefef (blanc cassé) pour le fond,
   #121212 (noir cassé) pour le texte, le logo et les surfaces sombres.
   L'indigo de l'identité (#343089) ne reste que dans les teintes d'attente
   des images de projet. Jamais de noir ni de blanc purs. Une seule police,
   Gantari, pour tout : le gras pour les titres, le medium pour les phrases
   mises en avant, le normal pour les textes. */
:root {
  --fond: #EFEFEF;
  --encre: #121212;
  /* gris des textes secondaires : assez foncé pour se lire sur #efefef */
  --gris: #686866;
  /* le nom une fois pâli, et les mots en fond */
  --efface: #DADAD8;
  /* le bleu de l'identité, pour le survol du logo ; le clair sur fond noir */
  --bleu: #343089;
  --bleu-clair: #A6A3E8;
  /* le footer, le header sombre et le menu sombre : le noir cassé */
  --nuit: #121212;
  --nuit-texte: #EFEFEF;
  --nuit-doux: #9A9A98;
  --nuit-ligne: #3A3A3A;
  --sans: "Gantari", "Helvetica Neue", Arial, sans-serif;
  --marge: clamp(20px, 4vw, 64px);
  --courbe: cubic-bezier(0.22, 0.61, 0.36, 1);
  /* le nom et le mot « contact » ont la même taille et la même place */
  --taille-nom: clamp(3rem, 9vw, 9rem);
}

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

html,
body {
  margin: 0;
}

/* le téléphone garde la taille de texte prévue, même tourné. Un lien vers
   une partie de la page (Voir les projets, le menu) y descend en douceur,
   et s'arrête sous le header au lieu de passer dessous. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

[id] {
  scroll-margin-top: calc(clamp(18px, 2.4vw, 28px) * 2 + 48px + 24px);
}

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

body {
  background: var(--fond);
  color: var(--encre);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
}

.invisible {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ALLER AU CONTENU
   Invisible à la souris. Au clavier, le premier Tab le fait apparaître en
   haut à gauche, par-dessus le header : Entrée saute directement au
   contenu de la page. */
.aller-au-contenu {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 30;
  padding: 12px 18px;
  background: var(--encre);
  color: var(--fond);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
  translate: 0 -200%;
  transition: translate 0.2s ease;
}

.aller-au-contenu:focus {
  translate: 0 0;
  outline: 2px solid var(--bleu-clair);
  outline-offset: 2px;
}

/* LE HEADER
   Fixé en haut, fond blanc comme la page. Il descend doucement à
   l'arrivée, et devient sombre quand le footer passe dessous. Logo à
   gauche ; à droite le bouton FR / EN, puis le burger qui déroule le menu
   (voir « LE BURGER » et « LE MENU »). */
.entete {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px clamp(16px, 3vw, 32px);
  padding: clamp(18px, 2.4vw, 28px) var(--marge);
  background: var(--fond);
  transition: opacity 0.8s ease, transform 0.8s var(--courbe), background-color 0.5s ease;
}

.js .entete {
  opacity: 0;
  transform: translateY(-12px);
}

.pret .entete {
  opacity: 1;
  transform: none;
}

/* le logo de l'identité : le signe, et le nom à côté sur deux lignes */
.entete-logo {
  display: flex;
  align-items: center;
  gap: clamp(8px, 1vw, 12px);
  min-height: 44px;
  color: var(--encre);
  text-decoration: none;
  /* quand la souris s'en va, le bleu s'efface lentement */
  transition: color 0.8s ease;
}

.entete-nom {
  font-size: clamp(0.9375rem, 1.3vw, 1.25rem);
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: -0.01em;
}

.entete-logo .mark {
  width: clamp(36px, 3.4vw, 48px);
  height: clamp(36px, 3.4vw, 48px);
}

/* le header sombre : quand le footer passe dessous (le script pose la
   classe entete-sombre sur <body>) */
.entete-sombre .entete {
  background: var(--nuit);
}

.entete-sombre .entete-logo {
  color: var(--nuit-texte);
}

/* LE SURVOL DU LOGO
   Bleu seulement tant que la souris est dessus (ou que le clavier s'y
   pose) : il arrive vite, en 0,2 s, puis repart lentement, en 0,8 s (la
   transition de .entete-logo). Sur le header noir, un bleu plus clair. */
.entete-logo:hover,
.entete-logo:focus-visible {
  color: var(--bleu);
  transition-duration: 0.2s;
}

.entete-sombre .entete-logo:hover,
.entete-sombre .entete-logo:focus-visible {
  color: var(--bleu-clair);
}

/* la partie droite du header : le bouton de langue, puis le burger. Le
   menu déroulant se place par rapport à elle. */
.entete-droite {
  position: relative;
  display: flex;
  align-items: center;
  gap: clamp(12px, 2vw, 24px);
}

/* LE BOUTON DE LANGUE
   « FR EN » : la langue affichée est en noir cassé, l'autre en gris ; un
   clic passe à l'autre. Le script lit et change l'attribut lang de <html>. */
.langue {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--gris);
  font: inherit;
  font-size: clamp(0.8125rem, 1.1vw, 1rem);
  font-weight: 600;
  letter-spacing: 0.04em;
  cursor: pointer;
}

.langue[hidden] {
  display: none;
}

.langue span {
  transition: color 0.2s ease;
}

html[lang="fr"] .langue-fr,
html[lang="en"] .langue-en,
html[lang="fr"] .langue:hover .langue-en,
html[lang="en"] .langue:hover .langue-fr,
html[lang="fr"] .langue:focus-visible .langue-en,
html[lang="en"] .langue:focus-visible .langue-fr {
  color: var(--encre);
}

.entete-sombre .langue {
  color: var(--nuit-doux);
}

html[lang="fr"] .entete-sombre .langue-fr,
html[lang="en"] .entete-sombre .langue-en,
html[lang="fr"] .entete-sombre .langue:hover .langue-en,
html[lang="en"] .entete-sombre .langue:hover .langue-fr,
html[lang="fr"] .entete-sombre .langue:focus-visible .langue-en,
html[lang="en"] .entete-sombre .langue:focus-visible .langue-fr {
  color: var(--nuit-texte);
}

/* LA NAVIGATION
   Ordinateur : Projets, À propos et Contact toujours visibles à droite du
   header, sans passer par un menu. Au survol, un trait fin se dessine
   dessous. Téléphone : ils sont cachés, le burger prend le relais (voir
   « LE BURGER » et « LE MENU »). */
.nav {
  display: flex;
  align-items: center;
  gap: clamp(20px, 2.4vw, 36px);
}

.nav a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--encre);
  font-size: clamp(0.9375rem, 1.1vw, 1.0625rem);
  font-weight: 600;
  text-decoration: none;
  transition: color 0.2s ease;
}

.nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 10px;
  height: 1.5px;
  background: currentColor;
  scale: 0 1;
  transform-origin: right;
  transition: scale 0.35s var(--courbe);
}

.nav a:hover::after,
.nav a:focus-visible::after {
  scale: 1 1;
  transform-origin: left;
}

.entete-sombre .nav a {
  color: var(--nuit-texte);
}

@media (min-width: 861px) {
  .entete .burger,
  .entete .menu {
    display: none;
  }
}

@media (max-width: 860px) {
  .nav {
    display: none;
  }
}

/* LE BURGER
   Trois lignes de 12 × 2 px, espacées de 3 px, dans un carré de 16 px
   agrandi 1,5 fois. À l'ouverture, les deux premières descendent d'un cran
   (5 px : une ligne et son espace) et la troisième remonte de deux : les
   lignes tournent. Chacune part 20 ms après la précédente, bouge en
   0,36 s en ralentissant, et s'allume de 0,55 à 1 en chemin. À la
   fermeture, elles reviennent à leur place. Le bouton fait 44 px pour
   rester facile à toucher. */
.burger {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-right: -10px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--encre);
  cursor: pointer;
  transition: color 0.5s ease;
}

.burger[hidden] {
  display: none;
}

.entete-sombre .burger {
  color: var(--nuit-texte);
}

.burger-icone {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  width: 16px;
  height: 16px;
  scale: 1.5;
}

.burger-ligne {
  display: block;
  width: 12px;
  height: 2px;
  border-radius: 999px;
  background: currentColor;
  opacity: 0.9;
  transition: transform 0.36s ease-out, opacity 0.36s ease-out;
  transition-delay: calc(var(--i) * 20ms);
}

.burger[aria-expanded="true"] .burger-ligne {
  opacity: 1;
  animation: burger-allumage 0.36s ease-out calc(var(--i) * 20ms) both;
}

.burger[aria-expanded="true"] .burger-ligne:nth-child(1),
.burger[aria-expanded="true"] .burger-ligne:nth-child(2) {
  transform: translateY(5px);
}

.burger[aria-expanded="true"] .burger-ligne:nth-child(3) {
  transform: translateY(-10px);
}

@keyframes burger-allumage {
  0% {
    opacity: 0.55;
  }

  50%,
  100% {
    opacity: 1;
  }
}

/* LE MENU
   Une liste déroulante sous le burger, collée au bord droit de l'écran,
   qui commence juste sous le header. Fermée, elle est roulée vers le haut
   (clip-path), invisible, et ses liens ne reçoivent pas le focus. À
   l'ouverture, elle se déroule vers le bas en 0,36 s, comme les lignes du
   burger, et les liens apparaissent l'un après l'autre (--i donne leur
   rang). Elle prend les couleurs du header : blanche, ou ardoise quand le
   footer passe dessous. Les -40px du clip-path laissent voir l'ombre. */
.menu {
  position: absolute;
  top: calc(100% + clamp(18px, 2.4vw, 28px));
  right: calc(var(--marge) * -1);
  min-width: 240px;
  padding: 8px var(--marge) 20px;
  background: var(--fond);
  box-shadow: 0 18px 40px rgba(18, 18, 18, 0.1);
  clip-path: inset(0 -40px 100% -40px);
  visibility: hidden;
  transition: clip-path 0.36s ease-out, visibility 0s linear 0.36s, background-color 0.5s ease;
}

.menu-ouvert .menu {
  clip-path: inset(0 -40px -40px -40px);
  visibility: visible;
  transition: clip-path 0.36s ease-out, visibility 0s, background-color 0.5s ease;
}

.entete-sombre .menu {
  background: var(--nuit);
}

.menu-liens {
  display: grid;
  justify-items: end;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.menu-liens a {
  display: inline-block;
  padding: 10px 0;
  color: var(--encre);
  font-size: clamp(1.125rem, 1.5vw, 1.375rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  text-decoration: none;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 0.3s ease, transform 0.36s ease-out, color 0.2s ease;
}

.menu-ouvert .menu-liens a {
  opacity: 1;
  transform: none;
  transition-delay: calc(60ms + var(--i) * 40ms), calc(60ms + var(--i) * 40ms), 0s;
}

.menu-liens a:hover,
.menu-liens a:focus-visible {
  color: var(--gris);
}

.entete-sombre .menu-liens a {
  color: var(--nuit-texte);
}

.entete-sombre .menu-liens a:hover,
.entete-sombre .menu-liens a:focus-visible {
  color: var(--nuit-doux);
}

/* LE FONDU
   Trois mots sont fixés en bas à gauche de l'écran, exactement au même
   endroit : le nom, « à propos » et « contact ». Ils ne sont pas coupés au
   bord de leur zone : il n'y a aucune ligne de démarcation. Un seul est
   allumé à la fois, celui de la zone qui passe au milieu du mot ; le
   script l'écrit dans data-mot-fond sur <body> (nom, apropos ou contact).
   Quand ça change, l'ancien mot s'éteint pendant que le nouveau s'allume,
   en 0,3 s. Sans script, seul le nom est affiché. */
.hero-signature,
.apropos-mot,
.pied-mot {
  transition: opacity 0.3s ease;
}

.apropos-mot,
[data-mot-fond] .hero-signature,
[data-mot-fond] .pied-mot {
  opacity: 0;
}

/* sans script, « contact » reste éteint lui aussi */
html:not(.js) .pied-mot {
  opacity: 0;
}

[data-mot-fond="nom"] .hero-signature,
[data-mot-fond="apropos"] .apropos-mot {
  opacity: 1;
}

/* « contact » s'allume à l'opacité que lui donne la descente dans le
   footer (voir « LE FOOTER ») */
[data-mot-fond="contact"] .pied-mot {
  opacity: var(--opacite-mot, 1);
}

/* LE HERO
   La signature, fixée en bas à gauche. Elle passe du noir cassé au gris
   clair quand on descend (le script règle --effacement de 0 % à 100 %),
   et les projets passent par-dessus. */
.hero-signature {
  position: fixed;
  left: 0;
  bottom: var(--marge);
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: clamp(14px, 2vw, 32px);
  row-gap: 6px;
  padding: 0 var(--marge);
  color: color-mix(in srgb, var(--encre), var(--efface) var(--effacement, 0%));
  pointer-events: none;
  transition: color 0.5s ease, opacity 0.3s ease;
}

.hero-nom {
  display: grid;
  margin: 0;
  font-size: var(--taille-nom);
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: -0.035em;
}

/* Le nom est découpé en lettres par le script. La couche cache ce qui
   dépasse : à l'arrivée, les lettres y montent l'une après l'autre (--i
   donne leur rang). */
.js .hero-nom:not(.decoupe) {
  visibility: hidden;
}

.nom-couche {
  grid-area: 1 / 1;
  overflow: hidden;
  padding-block: 0.06em;
  margin-block: -0.06em;
  white-space: nowrap;
}

.lettre {
  display: inline-block;
  transform: translateY(110%);
  transition: transform 0.55s var(--courbe);
  transition-delay: calc(var(--i) * 24ms);
}

.pret .hero-nom .lettre {
  transform: none;
}

/* un mot du titre : ses lettres restent ensemble sur la même ligne */
.nom-mot {
  display: inline-block;
  white-space: nowrap;
}

.hero-metier {
  margin: 0;
  font-size: clamp(1rem, 1.6vw, 1.5rem);
  font-weight: 500;
  transition: opacity 0.6s ease, transform 0.6s var(--courbe);
}

.js .hero-metier {
  opacity: 0;
  transform: translateY(12px);
}

.pret .hero-metier {
  opacity: 1;
  transform: none;
  transition-delay: 0.45s;
}

/* LES BOUTONS
   Deux sortes : plein (l'action principale, « Parlons de votre projet »,
   avec sa flèche) et en contour (l'action secondaire). Au moins 48 px de
   haut, pour le pouce. Angles droits, comme le reste du site. */
.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  padding: 12px 22px;
  border: 1.5px solid var(--encre);
  background: transparent;
  color: var(--encre);
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.bouton:hover,
.bouton:focus-visible {
  background: var(--encre);
  color: var(--fond);
}

.bouton-plein {
  background: var(--encre);
  color: var(--fond);
}

.bouton-plein::after {
  content: "→";
  transition: translate 0.25s var(--courbe);
}

.bouton-plein:hover,
.bouton-plein:focus-visible {
  border-color: var(--bleu);
  background: var(--bleu);
}

.bouton-plein:hover::after,
.bouton-plein:focus-visible::after {
  translate: 4px 0;
}

/* sur le footer noir (.pied a donne sinon sa propre couleur aux liens) */
.pied .bouton-clair {
  border-color: var(--nuit-texte);
  background: var(--nuit-texte);
  color: var(--nuit);
}

.bouton-clair::after {
  content: "→";
}

.pied .bouton-clair:hover,
.pied .bouton-clair:focus-visible {
  border-color: var(--bleu-clair);
  background: var(--bleu-clair);
  color: var(--nuit);
}

/* L'INTRODUCTION DU PREMIER ÉCRAN
   Ce que fait Alexis en une phrase, puis un lien vers les projets, avec
   une flèche qui descend doucement. Ordinateur : en haut à gauche, à côté
   du grand logo. Téléphone : sous le logo, au-dessus du nom. Elle défile
   avec la page (le nom, lui, reste fixé). */
.hero-offre {
  position: absolute;
  left: var(--marge);
  z-index: 3;
  display: grid;
  gap: clamp(18px, 2.2vw, 28px);
  justify-items: start;
  transition: opacity 0.8s ease, transform 0.8s var(--courbe);
}

.hero-accroche {
  margin: 0;
  font-size: clamp(1rem, 1.7vw, 1.5rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.45;
  text-wrap: pretty;
}

/* les boutons de la page introuvable */
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.hero-defiler {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  color: var(--encre);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
}

/* le trait sous « Voir les projets » s'efface vers la droite au survol */
.hero-defiler span:first-child {
  padding-bottom: 3px;
  background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1.5px no-repeat;
  transition: background-size 0.35s var(--courbe);
}

.hero-defiler:hover span:first-child,
.hero-defiler:focus-visible span:first-child {
  background-position: 100% 100%;
  background-size: 0 1.5px;
}

.hero-fleche {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1.5px solid currentColor;
  border-radius: 50%;
  font-size: 0.875rem;
  animation: fleche-descend 2.4s var(--courbe) infinite;
}

@keyframes fleche-descend {
  0%,
  60%,
  100% {
    translate: 0 0;
  }

  30% {
    translate: 0 5px;
  }
}

.js .hero-offre {
  opacity: 0;
  transform: translateY(16px);
}

.pret .hero-offre {
  opacity: 1;
  transform: none;
  transition-delay: 0.6s;
}

@media (min-width: 861px) {
  .hero-offre {
    top: calc(clamp(96px, 11vh, 120px) + clamp(32px, 8vh, 96px));
    width: min(32rem, 38vw);
  }
}

@media (max-width: 860px) {
  .hero-offre {
    right: var(--marge);
    top: calc(100svh - 300px + 12px);
  }

  .hero-accroche {
    max-width: 30rem;
  }
}

/* petit téléphone : la phrase laisse la place au lien et au nom */
@media (max-width: 860px) and (max-height: 620px) {
  .hero-accroche {
    display: none;
  }
}

/* LE GRAND LOGO DE L'ACCUEIL
   Énorme, en haut à droite du premier écran : une fois et demie la place
   libre au-dessus du nom, coupé par le haut de l'écran (derrière le header)
   et par le bord droit. Son bas s'arrête toujours 300 px au-dessus du bas
   de l'écran, pour que le nom reste lisible.
   Quand on descend, il s'envole : le script règle --logo-sortie de 0 (en
   haut) à 1 (70 % d'un écran plus bas), et le logo monte plus vite que la
   page, grossit, se floute et s'efface. À l'arrivée, il apparaît
   en grandissant légèrement (voir la classe pret). */
.hero-logo {
  --s: var(--logo-sortie, 0);
  position: absolute;
  --taille-logo: min(110vw, calc((100svh - 300px) * 1.5));
  top: calc(100svh - 300px - var(--taille-logo));
  right: calc(var(--taille-logo) * -0.18);
  z-index: 1;
  width: var(--taille-logo);
  aspect-ratio: 1;
  color: var(--encre);
  pointer-events: none;
  translate: 0 calc(var(--s) * -60vh);
  scale: calc(1 + var(--s) * 0.35);
  opacity: calc(1 - var(--s) * 1.15);
  filter: blur(calc(var(--s) * 28px));
  will-change: translate, scale, opacity, filter;
}

/* ce qui dépasse du bord droit est coupé : pas de défilement horizontal.
   position: relative fait de la scène la boîte du logo, sans quoi la
   coupe ne s'appliquerait pas à lui. */
.scene {
  position: relative;
  overflow-x: clip;
}

/* l'image du logo (le signe indigo et granuleux, sur fond blanc). Le fond
   blanc de l'image se multiplie avec le fond de la page : il disparaît et
   l'ombre violette se pose directement sur le blanc cassé. Le mélange est
   sur .hero-logo et pas sur l'image, parce que le flou de la descente
   isole ce qui est dedans. Sans image, le signe noir prend la place. */
.hero-logo {
  mix-blend-mode: multiply;
}

.hero-logo-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: opacity 1s ease 0.15s, transform 1.2s var(--courbe) 0.15s;
}

.js .hero-logo-image {
  opacity: 0;
  transform: scale(0.82);
}

.pret .hero-logo-image {
  opacity: 1;
  transform: none;
}

/* LE LOGO VIVANT
   Une fois arrivé, le grand logo ne reste pas figé :
   - il respire : il grossit et rétrécit à peine (8 s) ;
   - il suit un peu la souris (le script règle --souris-x et --souris-y
     de -1 à 1).
   Ces mouvements utilisent scale et translate, séparés du
   transform de l'arrivée et des réglages de la descente (.hero-logo) :
   rien ne se contrarie. */
.hero-logo-image {
  translate: calc(var(--souris-x, 0) * 2.5%) calc(var(--souris-y, 0) * 2.5%);
  transition: opacity 1s ease 0.15s, transform 1.2s var(--courbe) 0.15s, translate 1.4s var(--courbe);
  animation:
    logo-souffle 8s ease-in-out infinite;
}

@keyframes logo-souffle {
  0%,
  100% {
    scale: 1;
  }

  50% {
    scale: 1.04;
  }
}

/* LES PROJETS
   Ils commencent sous le premier écran et passent devant le nom. */
.projets {
  position: relative;
  z-index: 2;
  padding: 100vh var(--marge) clamp(80px, 12vw, 200px);
  padding-top: 100svh;
}

/* le titre de la liste : « Projets choisis (03) », au-dessus de la grille */
.projets-entete {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: clamp(48px, 7vw, 112px);
}

.projets-titre {
  margin: 0;
  font-size: clamp(1.75rem, 3.4vw, 3rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
}

.projets-compte {
  color: var(--gris);
  font-size: clamp(0.875rem, 1.2vw, 1.125rem);
  font-weight: 500;
}

/* au survol, une flèche apparaît après le titre du projet */
.projet-titre::after {
  content: " →";
  display: inline-block;
  white-space: pre;
  opacity: 0;
  translate: -6px 0;
  transition: opacity 0.3s ease, translate 0.35s var(--courbe);
}

.projet:hover .projet-titre::after,
.projet:focus-within .projet-titre::after {
  opacity: 1;
  translate: 0 0;
}

.projet.sans-page .projet-titre::after {
  content: none;
}

/* LE CURSEUR « VOIR »
   Sur ordinateur, au-dessus d'un projet, un rond clair « Voir » est centré
   sur la souris (le script le crée et le place). La flèche de la souris
   n'est cachée que pendant que le rond est visible. Au clavier ou au doigt,
   rien ne change. */
.curseur {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 20;
  display: grid;
  place-items: center;
  width: 88px;
  height: 88px;
  margin: -44px 0 0 -44px;
  border-radius: 50%;
  overflow: hidden;
  /* clair : il se lit sur les images de projet, souvent sombres */
  background: var(--fond);
  color: var(--encre);
  font-size: 0.875rem;
  font-weight: 600;
  pointer-events: none;
  opacity: 0;
  scale: 0.4;
  transition: scale 0.3s var(--courbe), opacity 0.2s ease;
}

.curseur-visible .curseur {
  opacity: 1;
  scale: 1;
}

.curseur-visible .projet-ouvrir,
.curseur-visible .bande-rail {
  cursor: none;
}

/* téléphone : une colonne, les projets alternent à gauche et à droite */
.projets-grille {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: clamp(80px, 22vw, 120px);
}

.projet {
  width: 84%;
  margin: 0;
}

.projet:nth-child(even) {
  justify-self: end;
}

/* ordinateur : grille de 12 colonnes. Chaque projet a sa propre rangée et
   sa propre place en largeur : c'est ce qui fait le décalage. Ils ne se
   chevauchent pas en hauteur ; row-gap est l'air entre la fin d'un projet
   et le début du suivant. */
@media (min-width: 861px) {
  .projets-grille {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--marge);
    row-gap: clamp(56px, 7vw, 120px);
    align-items: start;
  }

  .projet,
  .projet:nth-child(even) {
    width: auto;
    justify-self: stretch;
  }

  /* les emplacements se répètent tous les cinq projets. La rangée de
     chaque projet est écrite par le script de construction
     (style="grid-row: …"). */
  .projet-place-1 { grid-column: 1 / span 5; }
  .projet-place-2 { grid-column: 8 / span 5; }
  .projet-place-3 { grid-column: 2 / span 4; }
  .projet-place-4 { grid-column: 7 / span 4; }
  .projet-place-5 { grid-column: 1 / span 5; }
}

/* l'image : cinq formats et cinq teintes d'attente, jamais de noir pur */
.projet-vue {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--teinte);
  color: var(--marque);
}

.projet-vue > * {
  transition: transform 0.8s var(--courbe);
}

.projet:hover .projet-vue > * {
  transform: scale(1.04);
}

/* l'image remplit tout le cadre, centrée : posée par-dessus, elle ne
   prend pas la hauteur de ses attributs width et height */
.projet-vue img,
.projet-vue video {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.projet-vue .mark {
  width: 20%;
  aspect-ratio: 1;
}

/* les cinq formats d'image, liés aux cinq emplacements de la grille */
.projet-place-1 .projet-vue {
  aspect-ratio: 1 / 1;
}

.projet-place-2 .projet-vue {
  aspect-ratio: 5 / 4;
}

.projet-place-3 .projet-vue {
  aspect-ratio: 4 / 5;
}

.projet-place-4 .projet-vue {
  aspect-ratio: 1 / 1;
}

.projet-place-5 .projet-vue {
  aspect-ratio: 16 / 10;
}

/* les teintes d'attente, tant qu'un projet n'a pas d'image : sur l'accueil
   comme sur les pages de projet. Le numéro se choisit dans l'admin. */
.teinte-1 {
  --teinte: linear-gradient(145deg, #2E2E2E, #121212);
  --marque: rgba(239, 239, 239, 0.22);
}

.teinte-2 {
  --teinte: linear-gradient(160deg, #4B47AA, #343089);
  --marque: rgba(239, 239, 239, 0.35);
}

.teinte-3 {
  --teinte: linear-gradient(100deg, #121212, #343089);
  --marque: rgba(239, 239, 239, 0.25);
}

.teinte-4 {
  --teinte: linear-gradient(150deg, #E4E4E2, #D2D2D0);
  --marque: rgba(52, 48, 137, 0.35);
}

.teinte-5 {
  --teinte: linear-gradient(135deg, #343089, #26236B);
  --marque: rgba(239, 239, 239, 0.3);
}

/* la légende, sous l'image */
.projet-legende {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  margin-top: 14px;
  color: var(--gris);
  font-size: 0.875rem;
  font-weight: 500;
}

.projet-titre {
  margin: 0;
  color: var(--encre);
  font-size: 0.9375rem;
  font-weight: 600;
}

/* le lien vers la page du projet : invisible, il recouvre tout le projet */
.projet {
  position: relative;
}

.projet-ouvrir {
  position: absolute;
  inset: 0;
  z-index: 1;
  cursor: pointer;
}

.projet-ouvrir:focus-visible {
  outline: 2px solid var(--encre);
  outline-offset: 6px;
}

/* un projet sans page : rien ne réagit, « À venir » sous la légende */
.projet.sans-page:hover .projet-vue > * {
  transform: none;
}

.projet-bientot {
  margin: 6px 0 0;
  color: var(--gris);
  font-size: 0.8125rem;
  font-weight: 500;
}

/* LE PASSAGE D'UNE PAGE À L'AUTRE
   Entre l'accueil et un projet, ou d'un projet à l'autre, la page glisse
   de côté : l'ancienne part vers la gauche pendant que la nouvelle arrive
   par la droite. Au retour (vers l'accueil ou un projet précédent), c'est
   l'inverse. Le header reste en place. Le sens est choisi dans le haut de
   chaque page (types « avance » et « retour »). Les navigateurs qui ne
   connaissent pas ces transitions changent simplement de page. */
@view-transition {
  navigation: auto;
}

.entete {
  view-transition-name: entete;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.75s;
  animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1);
  animation-fill-mode: both;
}

:active-view-transition-type(avance)::view-transition-old(root) {
  animation-name: glisse-vers-gauche;
}

:active-view-transition-type(avance)::view-transition-new(root) {
  animation-name: arrive-de-droite;
}

:active-view-transition-type(retour)::view-transition-old(root) {
  animation-name: glisse-vers-droite;
}

:active-view-transition-type(retour)::view-transition-new(root) {
  animation-name: arrive-de-gauche;
}

@keyframes glisse-vers-gauche {
  to {
    transform: translateX(-100%);
  }
}

@keyframes arrive-de-droite {
  from {
    transform: translateX(100%);
  }
}

@keyframes glisse-vers-droite {
  to {
    transform: translateX(100%);
  }
}

@keyframes arrive-de-gauche {
  from {
    transform: translateX(-100%);
  }
}

::view-transition-group(entete) {
  animation-duration: 0.4s;
}

/* LES PAGES DE PROJET
   Comme une planche de présentation, sur un écran :
   - en haut, sous le header, une bande d'images qu'on fait glisser de côté
     (à la souris en tirant, au doigt, au pavé tactile, ou aux flèches du
     clavier une fois la bande sélectionnée). Seules les images bougent ;
   - en dessous, dans la moitié droite, le titre, la nature et un résumé
     court ;
   - tout en bas, le projet précédent à gauche, l'année et les outils au
     milieu, le projet suivant à droite.
   Puis le footer, comme partout. Sur téléphone, le texte prend toute la
   largeur et les liens vers les projets voisins passent sous l'année. */
.projet-page {
  display: flex;
  flex-direction: column;
  min-height: 100svh;
  padding-top: calc(clamp(18px, 2.4vw, 28px) * 2 + 48px + clamp(8px, 1vw, 16px));
}

.bande-rail {
  /* la hauteur des images : la moitié de l'écran, un peu plus */
  --haut: clamp(260px, 52svh, 680px);
  --espace: 8px;
  display: flex;
  gap: var(--espace);
  height: var(--haut);
  padding: 0 var(--espace);
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}

.bande-rail::-webkit-scrollbar {
  display: none;
}

.bande-rail.glisse {
  cursor: grabbing;
}

.bande-rail:focus-visible {
  outline: 2px solid var(--encre);
  outline-offset: 4px;
}

/* les images ne se laissent pas attraper par le navigateur : c'est la
   bande entière qui glisse */
.bande-rail img,
.bande-rail video {
  -webkit-user-drag: none;
  pointer-events: none;
}

.bande-diapo {
  flex: none;
  height: 100%;
  margin: 0;
}

/* l'image principale, à sa proportion ; sans image, un aplat 4:3 avec le signe */
.bande-media {
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--teinte);
  color: var(--marque);
}

.bande-media img,
.bande-media video {
  display: block;
  width: auto;
  /* la hauteur écrite en entier : en %, le navigateur prendrait la largeur
     des attributs de l'image pour la diapositive */
  height: var(--haut);
}

.bande-vide {
  aspect-ratio: 4 / 3;
}

.bande-vide .mark {
  width: 20%;
  aspect-ratio: 1;
}

/* le texte, dans la moitié droite */
.projet-infos {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--marge);
  padding: clamp(24px, 3vw, 40px) var(--marge) 0;
}

.projet-infos-texte {
  grid-column: 7 / span 5;
  max-width: 560px;
}

.projet-infos-titre {
  margin: 0;
  font-size: clamp(1.5rem, 2.2vw, 2.25rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.projet-infos-nature {
  margin: 4px 0 0;
  color: var(--gris);
  font-size: clamp(0.9375rem, 1.1vw, 1.0625rem);
  font-weight: 500;
}

.projet-infos-resume {
  margin: clamp(18px, 2.2vw, 28px) 0 0;
  font-size: clamp(0.9375rem, 1.05vw, 1.0625rem);
  line-height: 1.6;
}

/* « Plus de détails » : replié par défaut. Un clic déplie la fiche, les
   notes et l'explication des images ; le + devient un −. */
.projet-details {
  margin-top: clamp(18px, 2.2vw, 28px);
}

.projet-details summary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-size: 0.9375rem;
  font-weight: 600;
  list-style: none;
  cursor: pointer;
}

.projet-details summary::-webkit-details-marker {
  display: none;
}

.projet-details summary::after {
  content: "+";
  display: inline-grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border: 1.5px solid currentColor;
  border-radius: 50%;
  font-size: 1rem;
  line-height: 1;
  transition: rotate 0.3s var(--courbe);
}

.projet-details[open] summary::after {
  content: "−";
}

.projet-details summary:hover,
.projet-details summary:focus-visible {
  color: var(--gris);
}

.projet-details-contenu {
  display: grid;
  gap: 16px;
  padding: 8px 0 12px;
  font-size: 0.9375rem;
  line-height: 1.65;
}

.projet-details-contenu p {
  margin: 0;
}

.details-fiche {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 6px 20px;
  margin: 0 0 8px;
  font-size: 0.875rem;
  line-height: 1.5;
}

.details-fiche dt {
  color: var(--gris);
  font-weight: 500;
}

.details-fiche dd {
  margin: 0;
  font-weight: 500;
}

.details-bloc h2 {
  margin: 8px 0 4px;
  font-size: 0.9375rem;
  font-weight: 700;
}

/* en bas : précédent, année et outils, suivant */
.projet-bas {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--marge);
  align-items: end;
  margin-top: auto;
  padding: clamp(24px, 3vw, 40px) var(--marge) var(--marge);
}

.projet-voisin {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 44px;
  justify-content: flex-end;
  color: var(--encre);
  font-size: 0.9375rem;
  text-decoration: none;
}

.projet-voisin b {
  font-weight: 600;
}

.projet-voisin span {
  color: var(--gris);
  font-weight: 500;
}

.projet-voisin:hover b,
.projet-voisin:focus-visible b {
  text-decoration: underline;
  text-underline-offset: 4px;
}

.projet-voisin-precedent {
  grid-column: 1 / span 4;
  grid-row: 1;
}

.projet-bas-meta {
  grid-column: 7 / span 3;
  grid-row: 1;
  margin: 0;
  color: var(--gris);
  font-size: 0.9375rem;
  font-weight: 500;
}

.projet-voisin-suivant {
  grid-column: 10 / span 3;
  grid-row: 1;
  align-items: flex-end;
  text-align: right;
}

@media (max-width: 860px) {
  /* moins haute que large : l'image suivante dépasse à droite, on voit
     qu'il y en a d'autres */
  .bande-rail {
    --haut: clamp(220px, min(52svh, 76vw), 520px);
  }

  .projet-infos-texte {
    grid-column: 1 / -1;
  }

  .projet-bas {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 28px;
  }

  .projet-bas-meta {
    grid-column: 1 / -1;
  }

  .projet-voisin-precedent {
    grid-column: 1;
    grid-row: 2;
  }

  .projet-voisin-suivant {
    grid-column: 2;
    grid-row: 2;
  }
}

/* la page introuvable : son titre peut passer sur deux lignes */
.page-introuvable .hero-nom {
  font-size: clamp(2.5rem, 7vw, 7rem);
}

.page-introuvable .nom-couche {
  white-space: normal;
}

/* LES BLOCS D'UNE PAGE DE PROJET
   Leur contenu visuel (images, palette, typographies, déclinaisons,
   mockups). Ils sont posés dans la bande d'images : voir « LES BLOCS DANS
   LA BANDE ». Voir outils/construire.mjs pour les types. */
/* les images : une, deux ou trois par ligne */
.bloc-images {
  display: grid;
  grid-template-columns: repeat(var(--colonnes, 2), minmax(0, 1fr));
  gap: clamp(16px, 2vw, 32px);
}

.bloc-images figure {
  margin: 0;
}

.bloc-images img,
.bloc-images video {
  display: block;
  width: 100%;
  height: auto;
}

.bloc-images figcaption {
  margin-top: 10px;
  color: var(--gris);
  font-size: 0.875rem;
  font-weight: 500;
}

/* la palette : un grand aplat par couleur */
.palette {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: clamp(12px, 1.6vw, 24px);
}

.couleur {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 24px;
  min-height: clamp(180px, 22vw, 320px);
  padding: clamp(16px, 2vw, 24px);
  background: var(--couleur);
  color: var(--sur-couleur);
  /* un filet très léger : le blanc cassé ne se perd pas dans le fond */
  box-shadow: inset 0 0 0 1px rgba(18, 18, 18, 0.1);
}

.couleur-nom {
  margin: 0;
  font-size: clamp(1.125rem, 1.6vw, 1.5rem);
  font-weight: 700;
}

.couleur-code {
  margin: 4px 0 0;
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: 0.04em;
}

.couleur-role {
  margin: 0;
  font-size: 0.875rem;
  opacity: 0.75;
}

/* les typographies : « Aa » en grand, dans sa police */
.typos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(16px, 2vw, 32px);
}

.typo {
  padding: clamp(20px, 3vw, 40px);
  background: #E4E4E2;
}

.typo-aa {
  margin: 0;
  font-size: clamp(5rem, 11vw, 10rem);
  line-height: 0.9;
}

.typo-nom,
.typo-role {
  font-family: var(--sans);
}

.typo-nom {
  margin: 16px 0 0;
  font-size: 1.125rem;
  font-weight: 700;
}

.typo-role {
  margin: 4px 0 0;
  color: var(--gris);
  font-size: 0.875rem;
  font-weight: 500;
}

.typo-alphabet {
  margin: 20px 0 0;
  font-size: clamp(1rem, 1.4vw, 1.25rem);
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* les déclinaisons du signe : six tuiles */
.declinaisons {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 24px);
}

.decl {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  margin: 0;
  background: var(--fond-decl);
  color: var(--sur-decl);
}

.decl-clair {
  --fond-decl: #E4E4E2;
  --sur-decl: #121212;
}

.decl-noir {
  --fond-decl: #121212;
  --sur-decl: #EFEFEF;
}

.decl-indigo {
  --fond-decl: #343089;
  --sur-decl: #EFEFEF;
}

.decl > .mark {
  width: 34%;
  aspect-ratio: 1;
}

.decl svg {
  width: 38%;
  height: auto;
  overflow: visible;
}

.decl-pastille {
  display: grid;
  place-items: center;
  width: 44%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: #343089;
  color: #EFEFEF;
}

.decl-pastille .mark {
  width: 60%;
  aspect-ratio: 1;
}

.decl-app {
  display: grid;
  place-items: center;
  width: 44%;
  aspect-ratio: 1;
  border-radius: 22%;
  background: #EFEFEF;
}

.decl-app .decl-pastille {
  width: 78%;
  background: #121212;
}

.decl-nom {
  display: flex;
  align-items: center;
  gap: 0.45em;
  font-size: clamp(1rem, 2.4vw, 2.25rem);
  font-weight: 700;
  line-height: 0.95;
}

.decl-nom .mark {
  width: 2.1em;
  aspect-ratio: 1;
}

.decl figcaption {
  position: absolute;
  left: 14px;
  bottom: 12px;
  font-size: 0.8125rem;
  font-weight: 500;
  opacity: 0.7;
}

/* les mockups : les supports posés sur une surface grise */
.mockups {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(24px, 3vw, 48px);
  padding: clamp(24px, 5vw, 80px);
  background: #DADAD8;
}

.mock {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin: 0;
}

.mock figcaption {
  color: #5A5A58;
  font-size: 0.875rem;
  font-weight: 500;
}

.mock-cartes {
  grid-column: 1 / span 7;
}

.mock-affiche {
  grid-column: 8 / span 5;
  grid-row: 1 / span 2;
}

.mock-icones {
  grid-column: 1 / span 7;
}

.cartes {
  position: relative;
  width: 100%;
  aspect-ratio: 1.35;
}

.carte {
  position: absolute;
  width: 64%;
  aspect-ratio: 85 / 55;
  border-radius: 2px;
  background-position: center;
  background-size: cover;
  box-shadow: 0 24px 50px rgba(18, 18, 18, 0.25), 0 2px 6px rgba(18, 18, 18, 0.15);
  container-type: inline-size;
}

.carte-recto {
  top: 6%;
  left: 2%;
  display: grid;
  place-items: center;
  background-color: #343089;
  color: #EFEFEF;
  rotate: -8deg;
}

.carte-recto .mark {
  width: 28%;
  aspect-ratio: 1;
}

.carte-verso {
  right: 2%;
  bottom: 6%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 7% 8%;
  background-color: #EFEFEF;
  color: #121212;
  rotate: 5deg;
}

.carte-logo {
  display: flex;
  align-items: center;
  gap: 0.45em;
  font-size: 6.5cqw;
  font-weight: 700;
  line-height: 0.95;
}

.carte-logo .mark {
  width: 2.1em;
  aspect-ratio: 1;
}

.carte-infos {
  display: flex;
  flex-direction: column;
  gap: 0.3em;
  font-size: 3.6cqw;
  font-weight: 500;
}

.affiche {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 100%;
  aspect-ratio: 4 / 5;
  padding: 8%;
  background-color: #343089;
  background-position: center;
  background-size: cover;
  color: #EFEFEF;
  box-shadow: 0 24px 50px rgba(18, 18, 18, 0.25), 0 2px 6px rgba(18, 18, 18, 0.15);
  container-type: inline-size;
}

.affiche .mark {
  width: 26%;
  aspect-ratio: 1;
}

.affiche-nom {
  margin: 0;
  font-size: 17cqw;
  font-weight: 700;
  line-height: 0.88;
  letter-spacing: -0.03em;
}

.affiche-pied {
  margin: 0;
  font-size: 4.2cqw;
  font-weight: 500;
}

.icones {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10%;
  width: 100%;
  padding: 4% 0;
}

.icone-app,
.icone-profil {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  color: #EFEFEF;
  box-shadow: 0 16px 36px rgba(18, 18, 18, 0.22);
}

.icone-app {
  width: 30%;
  border-radius: 22%;
  background: #121212;
}

.icone-profil {
  width: 26%;
  border-radius: 50%;
  background-color: #343089;
  background-position: center;
  background-size: cover;
}

.icone-app .mark,
.icone-profil .mark {
  width: 56%;
  aspect-ratio: 1;
}

/* LES BLOCS DANS LA BANDE
   Chaque bloc d'un projet est une diapositive de la bande, à la même
   hauteur que les images (--haut) : ses éléments sont posés en ligne.
   Les légendes des images et des mockups sont cachées, pour garder peu de
   texte ; les étiquettes des déclinaisons et les codes des couleurs
   restent, ils font partie de l'image. */
.bande .bloc-images {
  display: flex;
  gap: var(--espace);
  height: 100%;
}

.bande .bloc-images figure {
  height: 100%;
  margin: 0;
}

.bande .bloc-images img,
.bande .bloc-images video {
  display: block;
  width: auto;
  height: var(--haut);
}

.bande .bloc-images figcaption,
.bande .mock figcaption {
  display: none;
}

.bande .palette {
  display: flex;
  gap: var(--espace);
  height: 100%;
}

.bande .couleur {
  width: clamp(170px, 20vw, 260px);
  min-height: 0;
}

.bande .typos {
  display: flex;
  gap: var(--espace);
  height: 100%;
}

.bande .typo {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  width: min(480px, 84vw);
  overflow: hidden;
}

.bande .declinaisons {
  --case: calc((var(--haut) - var(--espace)) / 2);
  grid-template-columns: repeat(3, calc(var(--case) * 4 / 3));
  grid-template-rows: repeat(2, var(--case));
  gap: var(--espace);
  height: 100%;
}

.bande .decl {
  aspect-ratio: auto;
}

/* les mockups : les supports côte à côte sur la surface grise */
.bande .mockups {
  display: flex;
  align-items: center;
  gap: clamp(32px, 5vw, 80px);
  height: 100%;
  padding: clamp(20px, 4vh, 56px) clamp(32px, 5vw, 80px);
}

.bande .mock {
  height: 100%;
}

.bande .mock-cartes {
  width: calc((var(--haut) - 80px) * 1.35);
}

.bande .mock-affiche {
  width: calc((var(--haut) - 80px) * 0.8);
}

.bande .mock-icones {
  width: calc((var(--haut) - 80px) * 0.9);
}

/* À PROPOS
   Comme les projets : pas de fond, le contenu défile par-dessus un mot
   fixé en bas à gauche. Ici le mot est « à propos », en gris clair comme
   le nom une fois pâli, à sa place exacte (voir « LE FONDU »).
   Le contenu suit la même grille de 12 colonnes que les projets.
   Ordinateur : tout est aligné sur la moitié droite, dans une colonne qui
   part de la 7ᵉ colonne de la grille et ne dépasse pas la largeur de la
   photo (400 px). La moitié gauche reste libre pour le mot « à propos ».
   Dans cette colonne : la présentation, puis la photo centrée, puis les
   expériences et les repères. Téléphone : la même chose sur toute la
   largeur. */
.apropos {
  position: relative;
  padding: clamp(96px, 12vw, 180px) var(--marge);
}

.apropos-mot {
  position: fixed;
  left: 0;
  bottom: var(--marge);
  z-index: 0;
  margin: 0;
  padding: 0 var(--marge);
  color: var(--efface);
  font-size: var(--taille-nom);
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: -0.035em;
  white-space: nowrap;
  pointer-events: none;
}

.apropos-contenu {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--marge);
  row-gap: clamp(36px, 6vw, 56px);
  align-items: start;
}

/* la photo, entre la présentation et les expériences : elle prend toute
   la largeur de la colonne, qui est la sienne */
.apropos-photo {
  width: 100%;
  margin: clamp(36px, 4.4vw, 60px) 0 0;
}

.apropos-photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  /* gris de la photo, visible le temps qu'elle charge */
  background: #8A8A88;
}

/* la colonne : jamais plus large que la photo. Pour élargir la photo et le
   texte ensemble, change seulement cette valeur. */
.apropos-texte {
  grid-column: 7 / span 6;
  max-width: 400px;
}

.apropos-titre {
  margin: 0 0 clamp(20px, 2.4vw, 32px);
  color: var(--gris);
  font-size: 0.9375rem;
  font-weight: 500;
}

.apropos-enonce {
  margin: 0 0 clamp(24px, 2.6vw, 36px);
  font-size: clamp(1.25rem, 1.9vw, 1.75rem);
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.3;
}

.apropos-texte > p:not(.apropos-enonce) {
  margin: 0 0 1em;
  font-size: clamp(0.9375rem, 1vw, 1rem);
  line-height: 1.65;
}

/* formation, outils, langues */
.apropos-faits {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 24px clamp(20px, 3vw, 40px);
  margin: clamp(32px, 4vw, 56px) 0 0;
}

.apropos-faits dt {
  color: var(--gris);
  font-size: 0.875rem;
  font-weight: 500;
}

.apropos-faits dd {
  margin: 8px 0 0;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.5;
}

/* les expériences : la date au-dessus, puis le stage et ce que j'y ai
   fait. Pour en ajouter une, duplique un <li> dans le HTML. */
.apropos-experiences {
  margin-top: clamp(36px, 4.4vw, 60px);
}

.apropos-sous-titre {
  margin: 0 0 20px;
  color: var(--gris);
  font-size: 0.875rem;
  font-weight: 500;
}

.experiences {
  display: grid;
  gap: 24px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.experiences li {
  display: grid;
  gap: 4px;
}

.experience-quand {
  color: var(--gris);
  font-size: 0.8125rem;
  font-weight: 500;
}

.experience-titre {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
}

.experiences p {
  margin: 4px 0 0;
  font-size: 0.875rem;
  line-height: 1.6;
}

/* ce que fait Alexis : une liste courte, comme les expériences */
.apropos-faire {
  margin-top: clamp(36px, 4.4vw, 60px);
}

.faire {
  display: grid;
  gap: 18px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.faire-titre {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
}

.faire p {
  margin: 4px 0 0;
  font-size: 0.875rem;
  line-height: 1.6;
}

@media (max-width: 860px) {
  .apropos-contenu {
    grid-template-columns: minmax(0, 1fr);
  }

  .apropos-texte {
    grid-column: auto;
  }
}

/* LE FOOTER
   En ardoise. Coordonnées à gauche, adresse à droite, et en bas une place
   vide de la hauteur du mot : c'est là que « contact » se pose quand on
   arrive tout en bas. */
.pied {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-areas:
    "infos contact"
    "place place";
  gap: clamp(40px, 5vw, 80px) var(--marge);
  padding: clamp(80px, 9vw, 140px) var(--marge) var(--marge);
  background: var(--nuit);
  color: var(--nuit-texte);
}
/* « contact » : fixé en bas à gauche comme le nom, allumé en fondu quand le
   footer arrive (voir « LE FONDU »), et derrière son contenu (comme le nom
   derrière les projets) */
.pied-mot {
  position: fixed;
  left: 0;
  bottom: var(--marge);
  z-index: 0;
  display: grid;
  margin: 0;
  padding: 0 var(--marge);
  font-size: var(--taille-nom);
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: -0.035em;
  white-space: nowrap;
  pointer-events: none;
  /* plus on descend dans le footer, plus il devient transparent : le
     script règle --opacite-mot de 1 (le footer arrive) à 0,1 (tout en bas),
     appliqué dans « LE FONDU » */
  opacity: var(--opacite-mot, 1);
}

.pied-place {
  grid-area: place;
  height: calc(var(--taille-nom) * 0.95);
}

.pied a {
  color: inherit;
  text-decoration: none;
}

.pied a:hover,
.pied a:focus-visible {
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* les coordonnées, en deux colonnes */
.pied-infos {
  grid-area: infos;
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(32px, 3.4vw, 48px) clamp(24px, 4vw, 64px);
  max-width: 640px;
  margin: 0;
}

.pied-infos dt {
  color: var(--nuit-doux);
  font-size: 0.9375rem;
  font-weight: 500;
}

.pied-infos dd {
  margin: 10px 0 0;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.55;
  overflow-wrap: anywhere;
}

/* le numéro : une cible assez haute pour le doigt, sans décaler le texte */
.pied-infos dd a {
  display: inline-block;
  padding-block: 10px;
  margin-block: -10px;
}

/* la phrase, le bouton et l'adresse, à droite : un clic ouvre la messagerie */
.pied-contact {
  grid-area: contact;
  position: relative;
  z-index: 1;
  max-width: 580px;
}

.pied-contact .bouton {
  display: flex;
  width: fit-content;
  margin-bottom: clamp(12px, 1.6vw, 20px);
}

.pied .bouton:hover,
.pied .bouton:focus-visible {
  text-decoration: none;
}

.pied-appel {
  margin: 0 0 clamp(24px, 2.6vw, 36px);
  font-size: clamp(1.25rem, 1.8vw, 1.625rem);
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.4;
}

.pied .pied-adresse {
  display: inline-block;
  padding-block: 11px;
  font-size: clamp(1.125rem, 1.6vw, 1.375rem);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--nuit-ligne);
  text-decoration-thickness: 1px;
  text-underline-offset: 8px;
  overflow-wrap: anywhere;
  transition: text-decoration-color 0.2s ease;
}

.pied .pied-adresse:hover,
.pied .pied-adresse:focus-visible {
  text-decoration-color: var(--nuit-texte);
}

/* « © 2026 Alexis Visual · Alexis Fabre », en bas à droite du footer, en
   face du mot « contact » */
.pied-signature {
  position: absolute;
  right: var(--marge);
  bottom: var(--marge);
  z-index: 1;
  margin: 0;
  color: var(--nuit-doux);
  font-size: 0.8125rem;
  font-weight: 500;
  text-align: right;
}

/* téléphone : « contact » prend toute la largeur en bas, la signature
   monte en haut à droite du footer */
@media (max-width: 860px) {
  .pied-signature {
    top: var(--marge);
    bottom: auto;
  }
}

/* tablette et téléphone : tout sur une colonne, la place du mot à la fin */
@media (max-width: 860px) {
  .pied {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "infos"
      "contact"
      "place";
  }
}

@media (max-width: 480px) {
  .pied-infos {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* LES APPARITIONS
   Les projets et le contenu du footer montent doucement en entrant dans
   l'écran : le script leur donne la classe est-visible. --retard décale
   un élément par rapport à son voisin. */
.js .projet,
.js [data-apparait] {
  opacity: 0;
  transform: translateY(56px);
  transition: opacity 0.9s ease, transform 0.9s var(--courbe);
  transition-delay: var(--retard, 0ms);
}

.js .est-visible {
  opacity: 1;
  transform: none;
}

/* Moins de mouvement demandé : plus rien ne glisse, les éléments
   apparaissent simplement en fondu. */
@media (prefers-reduced-motion: reduce) {
  .js .entete,
  .js .hero-metier,
  .js .hero-offre,
  .js .projet,
  .js [data-apparait] {
    transform: none;
  }

  .lettre,
  .projet-vue > *,
  .burger-ligne {
    transition: none;
  }

  /* le grand logo s'efface simplement, sans monter, tourner ni flouter */
  .hero-logo {
    translate: none;
    rotate: none;
    scale: none;
    filter: none;
  }

  .js .hero-logo-image {
    transform: none;
    translate: none;
    animation: none;
  }

  .burger[aria-expanded="true"] .burger-ligne,
  .hero-fleche {
    animation: none;
  }

  .menu-liens a {
    transform: none;
  }

  /* d'une page à l'autre, pas de glissement */
  @view-transition {
    navigation: none;
  }

  /* la liste apparaît d'un coup au lieu de se dérouler */
  .menu,
  .menu-ouvert .menu {
    clip-path: none;
  }
}
