:root {
  --ink: #17171a;
  --muted: #6b6b68;
  --accent: #17171a;
}

/* Seul assets/fonts/minion-pro-italic.ttf existe réellement (ni woff2, ni
   woff, ni otf). Un navigateur qui échoue à CHARGER le format qu'il a
   choisi dans une liste src ne retente pas le suivant (il ne bascule que
   si le format n'est pas SUPPORTÉ) — woff2 étant listé en premier et 404,
   la police entière échouait silencieusement et retombait sur Georgia,
   d'où le rendu incohérent (gras, taille) observé jusqu'ici. Un seul src
   pointant vers le fichier qui existe vraiment règle ça. */
@font-face {
  font-family: "Minion Pro";
  src: url("../fonts/minion-pro-italic.ttf") format("truetype");
  font-style: italic;
  font-weight: 400;
  font-display: swap;
}

* { box-sizing: border-box; }

/* Même dégradé gris partout (accueil ET pages projets), calé sur le fond réel
   de rock.jpg. background-attachment: fixed le cale sur la fenêtre plutôt que
   sur la hauteur de la page, pour garder le même dégradé visuel même sur une
   page projet qui défile (comme About, plus longue qu'un écran). */
html, body {
  margin: 0;
  padding: 0;
  background: linear-gradient(to top, #b0a9b1 0%, #c1bbc5 20%, #d5d4dc 50%, #e4e1ec 80%, #f3f2f8 100%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

@media (max-width: 700px) {
  html, body {
    background: linear-gradient(to top, #c0b4c2 0%, #e0dae6 20%, #f2ecf6 40%, #f3f0f7 100%);
    background-attachment: fixed;
  }
}

/* Sur mobile, un léger scroll résiduel peut faire "rebondir" la page (effet
   élastique iOS) et laisser entrevoir un instant le blanc par défaut de
   <html> derrière le contenu. overscroll-behavior coupe ce rebond. */
html {
  overscroll-behavior: none;
}
html.home {
  height: 100%;
}

/* Curseur natif masqué uniquement sur pointeur fin (souris) ;
   sur mobile/tactile on garde le comportement par défaut. */
@media (hover: hover) and (pointer: fine) {
  body.has-custom-cursor,
  body.has-custom-cursor * {
    cursor: none;
  }
}

/* ---------- Page d'accueil : la roche, en pleine page ---------- */

/* Dégradé calé sur le fond réel de rock.jpg (mesuré directement sur le
   fichier, plusieurs points du haut vers le bas) : si un espace apparaît
   malgré tout (barre d'adresse mobile, marge sur petit écran…), il se fond
   dedans au lieu de trancher en blanc. Sous 700px, rock-mobile.jpg a son
   propre dégradé (voir plus bas) : les deux photos n'ont pas exactement le
   même fond. */
body.home {
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  overscroll-behavior: none;
  background: linear-gradient(to bottom, #b0a9b1 0%, #c1bbc5 20%, #d5d4dc 50%, #e4e1ec 80%, #f3f2f8 100%);
}

.stage {
  position: relative;
  height: 100vh;
  height: 100dvh;
  width: 100vw;
  margin: 0;
  overflow: hidden;
}

/* Roche = 2600x1535px. .rock-frame est toujours mis à l'échelle pour
   couvrir tout l'écran EN CONSERVANT ce ratio (comme background-size:cover,
   mais en pur CSS, sans JS) : width/height de base = plein écran, et le
   min-width/min-height calculé à partir du ratio prend le relais dès que
   la base ne suffit plus à couvrir l'autre dimension. Le débordement est
   centré puis rogné par .stage (overflow: hidden). Important : .rock-frame
   DOIT garder exactement le ratio de la photo (pas object-fit:cover sur
   l'image toute seule) car les points chauds sont positionnés en % de ce
   conteneur — si sa forme ne correspond plus exactement à l'image, ils se
   décalent des symboles.
   100dvh (dynamic viewport height) au lieu de 100vh : sur mobile, vh se
   base sur la hauteur "barre d'adresse rétractée", donc quand elle est
   visible ça laissait un vrai espace en haut. dvh suit la hauteur réellement
   visible. Les deux valeurs sont déclarées : les navigateurs qui ne
   connaissent pas dvh gardent simplement la valeur vh juste au-dessus. */
.rock-frame {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  min-width: calc(100vh * 2600 / 1535);
  min-width: calc(100dvh * 2600 / 1535);
  min-height: calc(100vw * 1535 / 2600);
}

.rock-frame img {
  display: block;
  width: 100%;
  height: 100%;
  /* Tant que la photo n'est pas encore chargée (4G lente, cache froid), cette
     couleur remplace le blanc par défaut du navigateur pour une image vide. */
  background: #d5d4dc;
  user-select: none;
  -webkit-user-drag: none;
}

@media (max-width: 700px) {
  .rock-frame img {
    background: #f2ecf6;
  }
}

/* Sous 700px, <picture> charge rock-mobile.jpg (1356x2941, recadrage portrait
   dédié, avec sa propre marge grise sur les côtés) au lieu de rock.jpg : le
   ratio utilisé par la technique "cover" ci-dessus doit changer en même temps,
   sinon .rock-frame continue de calculer sa taille sur le ratio bureau et
   déforme/surcadre la photo mobile. */
@media (max-width: 700px) {
  .rock-frame {
    min-width: calc(100vh * 1356 / 2941);
    min-width: calc(100dvh * 1356 / 2941);
    min-height: calc(100vw * 2941 / 1356);
  }

  /* Dégradé propre à rock-mobile.jpg (mesuré directement dessus) : sa marge
     grise s'éclaircit plus vite que celle de rock.jpg. */
  body.home {
    background: linear-gradient(to bottom, #c0b4c2 0%, #e0dae6 20%, #f2ecf6 40%, #f3f0f7 100%);
  }
}

.hover-caption {
  position: fixed;
  top: 50%;
  margin: 0;
  max-width: 24vw;
  font-family: "Minion Pro", Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: clamp(1.6rem, 3.2vw, 2.8rem);
  line-height: 1.25;
  color: #a8a0ab;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s ease, transform 0.35s ease;
  z-index: 15;
}

.hover-caption-left {
  left: clamp(2rem, 6vw, 6rem);
  text-align: right;
  transform: translateY(-50%) translateX(-10px);
}

.hover-caption-right {
  right: clamp(2rem, 6vw, 6rem);
  text-align: left;
  transform: translateY(-50%) translateX(10px);
}

.hover-caption-left.visible,
.hover-caption-right.visible {
  transform: translateY(-50%) translateX(0);
}

.hover-caption.visible {
  opacity: 1;
}

@media (max-width: 700px) {
  .hover-caption {
    display: none;
  }
}

/* ---------- Points chauds ---------- */

.hotspot {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 6%;
  height: 6%;
  border-radius: 50%;
  background: transparent;
  border: 0;
  padding: 0;
  display: block;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

/* mode calibration (?calibrate) : seul endroit où le contour des points reste visible */
.calibrate .hotspot {
  outline: 1px solid rgba(200, 40, 40, 0.6);
  border-radius: 50%;
}
.calibrate-marker {
  position: absolute;
  width: 10px;
  height: 10px;
  margin-left: -5px;
  margin-top: -5px;
  border-radius: 50%;
  background: red;
  pointer-events: none;
}

/* ---------- Curseur pioche personnalisé ---------- */

#pickaxe-cursor {
  position: fixed;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 9999;
  /* La pointe du pic (coin haut-gauche de la photo) est calée sur le curseur ;
     le pivot du balancement est vers la poignée. Recalcule ces valeurs si tu
     changes d'image. */
  transform: translate(-17px, -8px) rotate(-10deg);
  transform-origin: 33px 59px;
  will-change: transform;
  transition: transform 0.08s ease-out;
  display: none;
}

body.has-custom-cursor #pickaxe-cursor {
  display: block;
}

#pickaxe-cursor img,
#pickaxe-cursor svg {
  display: block;
  height: 80px;
  width: auto;
  pointer-events: none;
  user-select: none;
}

#pickaxe-cursor.swing {
  animation: pickaxe-swing 0.32s ease-in-out;
}

@keyframes pickaxe-swing {
  0%   { transform: translate(-17px, -8px) rotate(-10deg); }
  40%  { transform: translate(-17px, -8px) rotate(30deg); }
  100% { transform: translate(-17px, -8px) rotate(-10deg); }
}

/* ---------- Page projet ---------- */

/* min-height (pas height) + justify-content:center : si le contenu tient sur
   un écran (cas courant : titre + texte court + une seule vidéo), tout se
   centre verticalement et il n'y a rien à scroller. Si le contenu dépasse
   (About, plusieurs vidéos...), le conteneur grandit normalement au-delà du
   min-height et ça défile comme avant : aucun cas n'est cassé par l'autre. */
.project-page {
  max-width: 1100px;
  margin: 0 auto;
  padding: 8vh 6vw;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Détaché du flux centré : reste toujours en haut à gauche de l'écran, peu
   importe si le contenu en dessous est court (centré) ou long (défile). */
.back-link {
  position: fixed;
  top: 28px;
  left: 32px;
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  z-index: 20;
}
.back-link:hover {
  color: var(--ink);
  border-bottom-color: var(--ink);
}

/* Le titre casse volontairement la colonne de 1100px de .project-page pour
   utiliser (presque) toute la largeur de la fenêtre : sinon, quelle que soit
   la taille de police visée ci-dessous, le script qui le force sur une seule
   ligne le rétrécissait pour tenir dans ces 1100px — la vraie police jamais
   atteinte. margin-left: calc(50% - 50vw) est l'astuce "full-bleed" standard
   pour un enfant d'un conteneur centré par margin:auto (contrairement à
   left:50%, qui se base sur la largeur du PARENT et ne marche pas ici). */
.project-title {
  font-family: "Minion Pro", Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: clamp(5rem, 13.5vw, 9rem);
  letter-spacing: -0.01em;
  box-sizing: border-box;
  width: 100vw;
  margin: 0 0 1.2rem calc(50% - 50vw);
  padding: 0 6vw;
}

.project-description {
  font-size: 0.92rem;
  line-height: 1.65;
  color: #333;
  margin: 0 0 2rem;
  white-space: pre-line;
}

.project-media {
  display: grid;
  gap: 1.25rem;
}

.media-placeholder {
  aspect-ratio: 16 / 9;
  background: #eceae6;
  border: 1px dashed #c9c7c2;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 0.85rem;
  text-align: center;
  padding: 1rem;
}

/* Grille de captures presse/réseaux sociaux (screenshots portrait, ratios
   variables) : column-count s'adapte à des hauteurs différentes sans
   étirer les images, contrairement à une grille avec aspect-ratio fixe. */
.press-grid {
  column-count: 4;
  column-gap: 1rem;
  margin-top: 2rem;
}
@media (max-width: 900px) {
  .press-grid { column-count: 2; }
}
.press-shot {
  display: block;
  width: 100%;
  margin-bottom: 1rem;
  border-radius: 4px;
  break-inside: avoid;
}

.video-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
}

.video-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.not-found {
  padding: 20vh 6vw;
  text-align: center;
}

/* ---------- Page About ---------- */

.about-header {
  display: flex;
  align-items: center;
  gap: 2rem;
  margin-bottom: 4rem;
  flex-wrap: wrap;
}

.about-photo {
  width: 160px;
  height: 160px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

.about-photo.media-placeholder {
  aspect-ratio: auto;
  border-radius: 50%;
  font-size: 0.75rem;
}

.about-contact {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  font-size: 1rem;
}

.about-contact a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--muted);
}
.about-contact a:hover {
  border-bottom-color: var(--ink);
}

.about-contact span {
  color: #333;
}

.about-section {
  margin-bottom: 3.5rem;
}

.about-section-title {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 1.5rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid #e2e0da;
}

.exp-item {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.5rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid #ece9e3;
}
.exp-item:last-child { border-bottom: 0; }

.exp-period {
  margin: 0;
  width: 13rem;
  flex-shrink: 0;
  color: var(--muted);
  font-size: 0.9rem;
}

.exp-role {
  margin: 0;
  font-size: 1rem;
}

.exp-company {
  color: var(--muted);
}

.client-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.client-tag {
  font-size: 0.85rem;
  padding: 0.4rem 0.9rem;
  border: 1px solid #d8d5cd;
  border-radius: 999px;
  color: #333;
}

.education-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.education-list li {
  padding: 0.6rem 0;
  border-bottom: 1px solid #ece9e3;
  font-size: 1rem;
}
.education-list li:last-child { border-bottom: 0; }

.awards-photo {
  width: 100%;
  max-width: 420px;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
  margin-bottom: 2rem;
}

.award-groups {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 2rem;
}

.award-org {
  font-size: 0.95rem;
  margin: 0 0 0.75rem;
  font-weight: 600;
}

.award-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.award-list li {
  font-size: 0.9rem;
  color: #333;
}
