/* =========================================================
   Alizée Clavaud — site artistique
   SQUELETTE — feuille de style neutre.
   Les variables ci-dessous sont le point d'entrée pour
   appliquer l'esthétique définitive (glitch / aquatique)
   une fois les références reçues. Ne pas redessiner la mise
   en page pour changer le style : changer les variables et
   les règles marquées "TODO esthétique".
   ========================================================= */

/* Michroma — choisie le 27/08/2026 par Alizée parmi 4 pistes
   testées en maquette (Unbounded / Tomorrow / Syne / Michroma),
   pour habiller SON NOM sur la page d'accueil uniquement (voir
   .splash-name plus bas) — pas encore étendue à --font-display /
   au reste du site, qui garde Helvetica Neue pour l'instant.
   Auto-hébergée (fichier woff2, licence OFL dans
   assets/fonts/michroma-LICENSE.txt) plutôt que via Google Fonts,
   pour rester cohérent avec un site 100% autonome sans requête
   externe. Une seule graisse existe pour cette police (400). */
@font-face {
  font-family: 'Michroma';
  src: url('assets/fonts/michroma-latin-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* --- Couleurs (TODO esthétique : remplacer par la palette glitch/aquatique) --- */
  --color-bg: #ffffff;
  --color-text: #111111;
  --color-muted: #666666;
  --color-accent: #111111;
  --color-border: #e5e5e5;

  /* --- Typographie (TODO esthétique : remplacer --font-display par une police Y2K/display) --- */
  --font-display: 'Helvetica Neue', Arial, sans-serif;
  --font-body: 'Helvetica Neue', Arial, sans-serif;
  --font-name: 'Michroma', 'Helvetica Neue', Arial, sans-serif;

  /* Turquoise "onde lumineuse" — première couleur d'accent tirée
     des références DA d'Alizée (27/08/2026), voir .start-btn::after
     plus bas. Pas encore utilisée ailleurs sur le site. */
  --color-accent-turquoise: #45e0d3;

  /* --- Structure --- */
  --nav-height: 76px;
  --max-width: 1100px;
  --gutter: 24px;
  --transition-fast: 0.4s ease;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  transition: opacity var(--transition-fast);
}

body.fade-out {
  opacity: 0;
}

/* Verrou de scroll appliqué au <body> tant que le menu mobile est
   ouvert (voir script.js) — évite que la page défile derrière le
   panneau de navigation plein écran. */
body.nav-locked {
  overflow: hidden;
}

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

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 500;
  margin: 0 0 0.5em 0;
}

p {
  margin: 0 0 1em 0;
}

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

/* =========================================================
   Page d'accueil / splash (à la Oklou) — pas de nav ici.
   Le nom + le bouton start sont la seule porte d'entrée.
   ========================================================= */

body.splash-page {
  height: 100vh;
  overflow: hidden;
}

.splash {
  height: 100vh;
  max-width: none;
  margin: 0;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 48px;
  text-align: center;
  padding: 0 var(--gutter);
  /* max-width/margin réinitialisés le 27/08/2026 : <main> applique
     par défaut max-width:1100px + margin:0 auto (site "intérieur"),
     invisible ici tant que rien ne s'appuyait sur les bords du
     splash — mais ça coupait la nouvelle vidéo de fond en laissant
     des bandes blanches de chaque côté sur les écrans > 1100px. */
}

/* Vidéo de fond en boucle, ajoutée le 27/08/2026 (1re référence de
   DA d'Alizée, "Dégradé 8 Bleu"). Plein écran, recadrée en cover
   sans jamais déformer. Un scrim sombre semi-transparent est posé
   par-dessus (.splash-scrim) pour garantir un contraste stable au
   nom et au bouton quel que soit l'instant du dégradé (les tons du
   bleu vont du marine profond au lavande clair). */
.splash-video-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

.splash-scrim {
  position: absolute;
  inset: 0;
  background: rgba(10, 12, 40, 0.32);
  z-index: 1;
}

/* Respect du confort des personnes sensibles au mouvement : la
   vidéo est masquée et remplacée par un dégradé statique reprenant
   ses tons, le scrim restant inutile dans ce cas. */
@media (prefers-reduced-motion: reduce) {
  .splash-video-bg {
    display: none;
  }

  .splash-scrim {
    display: none;
  }

  .splash {
    background: linear-gradient(135deg, #7a7ce8 0%, #2f2fc9 55%, #c2c8f5 100%);
  }
}

/* Crédit vidéo + copyright, ajoutés le 27/08/2026 à la demande
   d'Alizée : le fond vidéo de la page d'accueil est un extrait
   recadré de l'installation "La Piscine de Harmonie" (Cadmos et
   Harmonie, 2023) — pas un simple motif décoratif, une vraie
   œuvre — d'où le besoin d'un crédit + copyright, même discret.
   Positionné en bas de l'écran (la page splash est en 100vh sans
   footer classique), petit et translucide pour ne pas concurrencer
   le nom/bouton. */
.splash-credit {
  position: absolute;
  bottom: 20px;
  left: 0;
  right: 0;
  z-index: 2;
  text-align: center;
  padding: 0 var(--gutter);
  font-size: 0.7rem;
  letter-spacing: 0.03em;
  color: rgba(255, 255, 255, 0.55);
}

.splash-name {
  position: relative;
  z-index: 2;
  font-family: var(--font-name);
  font-weight: 400;
  color: #ffffff;
  font-size: clamp(2rem, 6.5vw, 4.5rem);
  letter-spacing: 0;
  line-height: 1.25;
  /* Michroma + blanc choisis par Alizée le 27/08/2026 (voir
     @font-face plus haut). Michroma est une police "display"
     très large par caractère (glyphes mono-linéaires écartés) :
     taille réduite par rapport à l'ancien Helvetica (5.5rem →
     4.5rem max) et interlettrage/line-height ajustés (letter-
     spacing à 0, line-height à 1.25 au lieu de 0.02em/1.05) pour
     qu'"Alizée"/"Clavaud" restent lisibles et ne débordent pas
     sur mobile. TODO esthétique : logo custom à la place de ce
     texte, effet glitch. */
}

/* Sur la page d'accueil, le header (logo + nav) est visible dès
   le départ, en surimpression sur le plein écran du splash — comme
   chez Oklou (nav en haut à droite, logo en haut à gauche, par-
   dessus le fond, pas de barre séparée qui pousse le contenu). */
body.splash-page .site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  background: transparent;
  border-bottom: none;
}

/* Header/nav en blanc sur la page d'accueil uniquement, depuis
   l'ajout de la vidéo de fond le 27/08/2026 — les couleurs par
   défaut (--color-text, --color-muted) sont pensées pour un fond
   blanc et n'auraient pas assez de contraste ici. */
body.splash-page .site-header .logo {
  color: #ffffff;
}

body.splash-page .site-nav a {
  color: rgba(255, 255, 255, 0.75);
}

body.splash-page .site-nav a:hover,
body.splash-page .site-nav a:focus-visible,
body.splash-page .site-nav a.active {
  color: #ffffff;
  border-bottom-color: #ffffff;
}

body.splash-page .lang-switch a {
  color: rgba(255, 255, 255, 0.85);
  border-color: rgba(255, 255, 255, 0.5);
}

body.splash-page .lang-switch a:hover,
body.splash-page .lang-switch a:focus-visible {
  color: #ffffff;
  border-color: #ffffff;
}

.start-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 96px;
  height: 96px;
  position: relative;
  z-index: 2;
  border: 1px solid var(--color-text);
  border-radius: 50%;
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  white-space: nowrap;
  animation: btn-breathe 1.8s cubic-bezier(0.45, 0, 0.55, 1) infinite;
  /* Taille de police et interlettrage réduits le 27/08/2026 : à
     0.85rem / 0.15em, "commencer" (FR, plus long que "start")
     débordait du cercle. Ce réglage plus compact tient dans le
     cercle pour les deux langues sans agrandir le bouton.

     Animation revue le 27/08/2026 (retour d'Alizée : "l'animation
     est lente, pas très fluide"). L'ancienne anim ("pulse", 2.4s
     ease-in-out, scale 1→1.05 ET opacity 1→0.75 en même temps)
     cumulait deux défauts : une durée un peu longue pour un point
     d'entrée qui doit donner envie de cliquer, et une easing
     ease-in-out qui ralentit fort aux extrêmes (accélère-décélère
     symétrique), ce qui se sent comme un temps mort à chaque
     sommet/creux. Remplacée par btn-breathe : plus rapide (1.8s),
     scale seul (pas d'opacity, qui ajoutait un effet de "fondu"
     supplémentaire perçu comme du flou/lenteur), cubic-bezier
     symétrique mais plus resserré autour du milieu — un souffle
     net plutôt qu'un battement mou. */
}

/* Anneau "onde" turquoise qui se propage depuis le bouton en
   boucle — ajouté le 27/08/2026 en réponse directe à une des
   références DA d'Alizée : l'onde lumineuse turquoise glowing
   qu'elle a entourée sur ses images (signature du "numérique/
   électronique" dans son univers, en écho au texte de L'Univers).
   Plutôt qu'un pur pulse décoratif, ça rattache le seul élément
   interactif/animé du site à sa DA dès maintenant, sans attendre
   la refonte complète. Le ::after est un cercle qui grandit et
   s'estompe (comme un ping sonar / une onde à la surface de l'eau),
   indépendant du souffle du bouton lui-même — les deux mouvements
   se lisent séparément, ce qui aide aussi la sensation de fluidité. */
.start-btn::after {
  content: '';
  position: absolute;
  inset: -1px;
  border: 1px solid var(--color-accent-turquoise);
  border-radius: 50%;
  opacity: 0;
  animation: btn-ping 2.2s cubic-bezier(0.2, 0.6, 0.4, 1) infinite;
  pointer-events: none;
}

@keyframes btn-breathe {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.045);
  }
}

@keyframes btn-ping {
  0% {
    transform: scale(1);
    opacity: 0.7;
  }
  75%, 100% {
    transform: scale(1.4);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .start-btn {
    animation: none;
  }

  .start-btn::after {
    animation: none;
    display: none;
  }
}

/* Sur la page d'accueil, bouton en blanc depuis l'ajout de la
   vidéo de fond le 27/08/2026 (voir plus haut) — le survol s'inverse
   en blanc plein avec un texte bleu marine proche du dégradé,
   plutôt que le noir/blanc utilisé sur fond blanc ailleurs. */
body.splash-page .start-btn {
  border-color: #ffffff;
  color: #ffffff;
}

body.splash-page .start-btn:hover,
body.splash-page .start-btn:focus-visible {
  background: #ffffff;
  color: #1a1a6e;
}

.start-btn:hover,
.start-btn:focus-visible {
  background: var(--color-text);
  color: var(--color-bg);
}

@keyframes pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.05); opacity: 0.75; }
}

/* =========================================================
   Site "intérieur" — header/nav persistant sur toutes les
   pages sauf la splash.
   ========================================================= */

/* 30/08/2026 : `border-bottom` retiré (elle séparait le header du
   reste de la page) — à la demande d'Alizée, une fois le bandeau
   Pixealizée du haut recadré en deux petits bouts avec un vide au
   milieu (Touche 13/14), cette ligne grise restait visible en
   pleine largeur dans ce vide, comme un trait orphelin déconnecté
   du reste. Universe et l'accueil n'avaient de toute façon déjà
   plus cette bordure (voir leurs overrides plus bas). */
.site-header {
  height: var(--nav-height);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--gutter);
  position: sticky;
  top: 0;
  background: var(--color-bg);
  z-index: 10;
}

.logo {
  font-family: var(--font-display);
  font-size: 1rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 36px;
  flex-wrap: wrap;
}

.site-nav {
  display: flex;
  gap: 28px;
  flex-wrap: wrap;
}

.site-nav a {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-muted);
  padding: 4px 0;
  border-bottom: 1px solid transparent;
}

.site-nav a:hover,
.site-nav a:focus-visible,
.site-nav a.active {
  color: var(--color-text);
  border-bottom-color: var(--color-text);
}

.lang-switch a {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  border: 1px solid var(--color-border);
  padding: 4px 10px;
}

.lang-switch a:hover,
.lang-switch a:focus-visible {
  color: var(--color-text);
  border-color: var(--color-text);
}

/* Bouton "burger" — masqué sur desktop, activé seulement sous
   700px (voir media query plus bas). Trois barres construites en
   CSS pur (pas d'icône externe, cohérent avec un site sans
   dépendance). */
.menu-toggle {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.menu-toggle span {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--color-text);
  transition: transform 0.3s ease, opacity 0.2s ease;
}

/* Transformation en croix quand le panneau est ouvert
   (aria-expanded piloté par script.js — pas de classe dupliquée). */
.menu-toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.menu-toggle[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}

.menu-toggle[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* Voile derrière le panneau de nav mobile, cliquable pour fermer.
   z-index intentionnellement SOUS .site-header (10) : .header-right
   étant un enfant du header (qui devient le panneau lui-même en
   mobile, voir plus bas), il hérite du contexte d'empilement du
   header et doit donc rester au-dessus de ce voile — un z-index
   plus élevé ici peindrait le voile par-dessus le panneau. */
.nav-scrim {
  position: fixed;
  inset: 0;
  background: rgba(10, 10, 15, 0.4);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  z-index: 9;
}

.nav-scrim.visible {
  opacity: 1;
  pointer-events: auto;
}

/* =========================================================
   Correctif mobile 27/08/2026 (retour d'Alizée, captures à
   l'appui) : sous ~700px, "Travaux / CV / L'univers / Contact"
   + le bouton EN ne tenaient plus sur une seule ligne à côté du
   nom. .site-header gardait pourtant une hauteur FIXE (76px) et
   restait "sticky" — le menu qui débordait n'était pas caché,
   il continuait à être peint par-dessus le contenu de la page
   (z-index:10), d'où le bouton "EN" (et parfois des liens du
   menu) flottant au milieu des titres/légendes pendant le scroll.

   Remplacé par un vrai menu mobile "burger" plutôt qu'un simple
   retour à la ligne (demande explicite d'Alizée) : sous 700px,
   .header-right devient un panneau plein écran qui glisse depuis
   la droite (position fixed + transform), ouvert/fermé par
   .menu-toggle via script.js (classe .nav-open + attribut
   aria-expanded). Le header lui-même retrouve sa hauteur fixe et
   tient sur une seule ligne (logo + bouton burger), donc plus
   aucun débordement ne peut se superposer au contenu.
   ========================================================= */
@media (max-width: 700px) {
  .site-header {
    flex-wrap: nowrap;
  }

  .menu-toggle {
    display: inline-flex;
  }

  .header-right {
    position: fixed;
    top: 0;
    right: 0;
    height: 100dvh;
    width: min(80vw, 300px);
    background: var(--color-bg);
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    flex-wrap: nowrap;
    gap: 36px;
    padding: 96px 28px 32px;
    box-shadow: -12px 0 32px rgba(0, 0, 0, 0.12);
    transform: translateX(100%);
    transition: transform 0.35s ease;
    overflow-y: auto;
  }

  .header-right.nav-open {
    transform: translateX(0);
  }

  .site-nav {
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 22px;
    width: 100%;
  }

  .site-nav a {
    display: block;
    font-size: 1rem;
  }

  .lang-switch {
    margin-top: 4px;
  }

  /* Le panneau devient un aplat blanc opaque même sur les pages où
     le header/nav passent en blanc sur une vidéo de fond (accueil,
     et Univers depuis le 30/08/2026 — voir plus haut / plus bas) :
     sans ça, "Travaux/CV/..." en blanc sur un panneau blanc serait
     invisible. Le logo et le bouton burger, eux, restent sur la
     barre du haut par-dessus la vidéo et gardent leur traitement
     blanc. Règles partagées entre .splash-page et .universe-page
     (même bug, même correctif). */
  body.splash-page .header-right .site-nav a,
  body.universe-page .header-right .site-nav a {
    color: var(--color-muted);
  }

  body.splash-page .header-right .site-nav a:hover,
  body.splash-page .header-right .site-nav a:focus-visible,
  body.splash-page .header-right .site-nav a.active,
  body.universe-page .header-right .site-nav a:hover,
  body.universe-page .header-right .site-nav a:focus-visible,
  body.universe-page .header-right .site-nav a.active {
    color: var(--color-text);
    border-bottom-color: var(--color-text);
  }

  body.splash-page .header-right .lang-switch a,
  body.universe-page .header-right .lang-switch a {
    color: var(--color-muted);
    border-color: var(--color-border);
  }

  body.splash-page .header-right .lang-switch a:hover,
  body.splash-page .header-right .lang-switch a:focus-visible,
  body.universe-page .header-right .lang-switch a:hover,
  body.universe-page .header-right .lang-switch a:focus-visible {
    color: var(--color-text);
    border-color: var(--color-text);
  }

  body.splash-page .menu-toggle span,
  body.universe-page .menu-toggle span {
    background: #ffffff;
  }
}

/* Espacements resserrés sous 700px (retour d'Alizée : "soucis
   d'alignement et d'espace" en plus du menu) — les mêmes marges
   verticales généreuses que sur desktop (padding de section à
   88px, main à 64px) prenaient trop de place à l'écran une fois
   la largeur réduite, avec l'impression d'un site mal calé plutôt
   qu'aéré. */
@media (max-width: 700px) {
  main {
    padding: 32px var(--gutter) 64px;
  }

  .work-entry {
    padding: 56px 0;
  }

  .work-entry-header h2 {
    font-size: 1.5rem;
  }

  .cv-list li {
    grid-template-columns: 64px 1fr;
    gap: 12px;
  }
}

main {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 64px var(--gutter) 96px;
}

.site-footer {
  border-top: 1px solid var(--color-border);
  padding: 24px var(--gutter);
  text-align: center;
  font-size: 0.75rem;
  color: var(--color-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* =========================================================
   Travaux / Works — page "journal" qu'on défile (restructurée
   21/08/2026) : une section pleine largeur par travail (chacune
   sa petite "aire"), séparées par une fine ligne noire. Ce
   travail n'étant pas publié ailleurs (pas sur Instagram), cette
   page fait office d'archive plutôt que de simple portfolio.
   Classes neutres (work-*, works-*) partagées entre les versions
   EN (works.html) et FR (fr/travaux.html).
   ========================================================= */

.works-journal {
  display: flex;
  flex-direction: column;
}

.work-entry {
  padding: 88px 0;
}

.work-entry:first-child {
  padding-top: 0;
}

.work-entry:last-child {
  padding-bottom: 0;
}

/* La "fine ligne noire" qui sépare chaque aire du journal.
   TODO esthétique : c'est un bon candidat pour un traitement
   glitch (ligne qui tremble/scintille légèrement) plus tard. */
.work-divider {
  border: none;
  border-top: 1px solid var(--color-text);
  margin: 0;
}

.work-entry-header {
  margin-bottom: 32px;
}

.work-entry-header h2 {
  font-size: 1.9rem;
}

.work-entry-header .meta {
  color: var(--color-muted);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.placeholder-img {
  aspect-ratio: 4 / 5;
  background: repeating-linear-gradient(
    45deg,
    #f2f2f2,
    #f2f2f2 10px,
    #ffffff 10px,
    #ffffff 20px
  );
  border: 1px solid var(--color-border);
}

/* Galerie d'un work-entry, réorganisée le 21/08/2026 : vidéos
   groupées ensemble, puis photos groupées en dessous, chaque
   média gardant SA proportion d'origine (pas de recadrage carré
   forcé) avec son nom affiché en légende. */
.works-gallery {
  margin-bottom: 32px;
}

.media-group {
  margin-bottom: 28px;
}

.media-group:last-child {
  margin-bottom: 0;
}

.media-group-label {
  color: var(--color-muted);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 12px;
}

/* Grille des médias, règle générale du site (26/08/2026) : hauteur
   fixe, largeur libre selon les proportions de chaque photo/vidéo.
   C'est ce qui garantit que toutes les photos portrait et toutes
   les vidéos d'une même grille sont "à la même taille" (même
   échelle verticale), qu'elles viennent d'une prise portrait ou
   paysage — sans jamais recadrer ni déformer le média.

   Correctif alignement 27/08/2026 (retour d'Alizée) : passé de
   align-items:flex-end à flex-start. En flex-end, chaque figure
   (image + légende) était alignée par SON BAS, légende comprise —
   or les légendes n'ont pas toutes la même longueur (une ligne vs
   deux lignes, ex. "Le Soir" vs "La piscine de l'hôtel"), donc les
   images elles-mêmes se retrouvaient décalées verticalement les
   unes par rapport aux autres au lieu d'avoir leurs bords du haut
   alignés. Particulièrement visible sur la rangée vidéo de Cadmos
   et Harmonie, qui mélange 4 vidéos standards et 1 .media-featured
   plus grande dans la même grille. En flex-start, tous les médias
   démarrent à la même hauteur quelle que soit la légende — la
   variante plus grande déborde simplement plus bas avant sa propre
   légende, sans perturber l'alignement des autres. */
.media-grid {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 24px;
}

/* Figure en colonne flex — 27/08/2026 (retour d'Alizée sur les
   vidéos de Cadmos et Harmonie : "alternate view" et "extended
   take" se retrouvaient chacune seule sur sa ligne au lieu d'être
   côte à côte). Cause : une figure `flex: 0 0 auto` sans largeur
   propre se dimensionne sur son contenu le plus large — et une
   légende, tant qu'il reste de la place sur l'écran, s'affiche par
   défaut SANS retour à la ligne pour ce calcul, même si elle finit
   par en faire un fois affichée. Pour une légende longue collée à
   une vidéo étroite (les vidéos verticales de Cadmos et Harmonie
   ne font qu'environ 105px de large à la hauteur mobile standard),
   la légende non coupée était bien plus large que la vidéo — la
   figure entière héritait de cette largeur, et deux figures aussi
   larges ne tenaient plus côte à côte. Passer la figure en colonne
   flex permet à la règle ci-dessous sur figcaption de forcer la
   légende à toujours prendre exactement la largeur du média, quelle
   que soit la longueur du texte. */
.media-grid figure {
  margin: 0;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
}

.media-grid img,
.media-grid video {
  height: 260px;
  width: auto;
  display: block;
  /* pas d'aspect-ratio forcé, pas d'object-fit : chaque média
     garde ses proportions naturelles, seule la hauteur est fixe */
  /* Bordure grise 1px retirée le 27/08/2026 à la demande d'Alizée
     (trop visible autour des œuvres restées sur fond blanc
     Instagram, ex. Le soir biot / La piscine de l'hôtel / Olhão) —
     retirée partout sur Travaux/Works pour rester cohérent. */
}

.media-grid figcaption {
  margin-top: 8px;
  font-size: 0.8rem;
  line-height: 1.4;
  color: var(--color-muted);
  letter-spacing: 0.03em;
  /* Centré — 01/09/2026 (retour d'Alizée : les titres doivent être
     alignés avec l'œuvre visible dans le cadre, pas avec toute la
     largeur de la figure). Sans ceci, une légende courte (ex. "Le
     Soir", "Olhão") restait callée à gauche de la figure au lieu
     d'être centrée sous l'image. */
  text-align: center;
  /* Hauteur réservée pour 2 lignes — 27/08/2026 (retour d'Alizée :
     "les écarts entre les oeuvres ne sont pas les mêmes", vu sur
     Cadmos et Harmonie). Avec align-items:flex-start, toutes les
     images d'une même ligne démarrent bien au même niveau — mais
     la hauteur d'une ligne flex (donc la position de la ligne
     suivante) dépend du plus haut élément de CETTE ligne, légende
     comprise. Or les légendes n'ont pas toutes la même longueur
     ("Cadmos3 Ressenti Tangerine" passe sur 2 lignes à la largeur
     mobile, "Cadmos4 Matière Noire" reste sur 1) : la ligne qui
     contient la légende la plus longue est donc plus haute, et
     l'écart visuel jusqu'à la ligne suivante paraît plus petit que
     pour une ligne aux légendes courtes — même si le `gap` CSS
     entre les lignes reste le même partout. Réserver systématique-
     ment la hauteur de 2 lignes de légende (qu'elle en utilise 1
     ou 2) rend la hauteur de chaque ligne flex indépendante du
     nombre de lignes réel de ses légendes, donc l'écart visuel
     entre les rangées redevient constant sur toute la galerie —
     photos comme vidéos, cette règle étant partagée. */
  min-height: 2.8em;
  /* Largeur forcée à celle du média — 27/08/2026, voir le
     commentaire sur `.media-grid figure` juste au-dessus : `width:
     0` + `min-width: 100%` empêche le texte de la légende de
     déterminer lui-même la largeur de la figure (ce qui l'aurait
     laissée s'étaler sur une seule ligne, aussi large que le texte
     le permette). Avec cette règle, la légende est forcée à occuper
     exactement la largeur de l'image/vidéo au-dessus d'elle, et
     s'enroule sur autant de lignes que nécessaire — la figure reste
     toujours aussi étroite que son média, donc deux figures restent
     côte à côte tant que leurs médias tiennent ensemble, peu importe
     la longueur des légendes. */
  width: 0;
  min-width: 100%;
  box-sizing: border-box;
}

/* Un média qu'on veut voir plus grand que les autres dans la
   grille (ex. la vidéo de documentation complète) : hauteur plus
   importante que le standard. */
.media-featured img,
.media-featured video {
  height: 420px;
}

/* Traitement "hero" pour une œuvre qu'on veut voir vraiment
   claquer — plus grande que .media-featured. Ajouté le 22/08/2026
   pour Soline / La piscine de Soudana (Le Bain), demande explicite
   d'Alizée : "grandes oeuvres contemporaines, ça doit claquer".
   Hauteur ajustée à 520px desktop / 340px mobile le 22/08 (retour
   d'Alizée) une fois les fichiers sources remplacés par des
   exports en bien plus haute résolution — cette taille reste
   nettement plus grande que .media-featured sans dominer la page.
   À utiliser avec parcimonie, pour de vraies pièces phares. */
.media-hero img,
.media-hero video {
  height: 520px;
}

/* Média affiché plus petit que le standard — pour des pièces au
   format physique nettement plus réduit (ex. les 10×10cm du groupe
   "Le Bain"), afin qu'elles paraissent bien plus petites que les
   autres pièces de la page. Ajouté le 02/09/2026 à la demande
   d'Alizée : une fois les 3 photos 10×10 recadrées au plus près de
   l'œuvre (fond blanc Instagram retiré, voir .media-grid figcaption
   plus bas), elles remplissaient toute la hauteur standard de
   260px — exactement comme les pièces 24×16cm — cassant la
   hiérarchie de taille qu'elle appréciait (avant le recadrage, le
   fond blanc laissait l'œuvre n'occuper qu'une petite partie de la
   hauteur affichée, la faisant paraître plus petite). Taille choisie
   par Alizée parmi 3 options comparées (85 / 110 / 140px). */
.media-small img,
.media-small video {
  height: 140px;
}

/* =========================================================
   Correctif débordement horizontal mobile — 27/08/2026 (retour
   d'Alizée : Le Bain, Le Monde/Glossolalie et la vidéo
   d'installation de Cadmos et Harmonie dépassaient du bord droit
   de l'écran sur téléphone, captures à l'appui — puis confirmé par
   Alizée avec une capture "dézoomée" manuellement montrant que les
   images tenaient bien dans le cadre une fois la page rétrécie).

   Cause : .media-grid/.media-featured/.media-hero fixent une
   HAUTEUR et laissent la largeur "auto" (calculée depuis les
   proportions réelles du média, voir plus haut — c'est voulu).
   Mais la figure parente (.media-grid figure { flex: 0 0 auto })
   ne rétrécit jamais, et surtout, comme elle n'a elle-même aucune
   largeur propre (elle épouse simplement la largeur de l'image),
   le "max-width: 100%" appliqué à tous les <img> tout en haut de
   ce fichier ne contraint en réalité rien ici : 100% de la largeur
   de la figure équivaut toujours à la largeur de l'image elle-
   même — c'est un calcul circulaire qui ne bloque jamais rien. Et
   les <video> n'ont même pas ce max-width:100% (il ne cible que
   les <img>). Résultat : un média au format paysage, à hauteur
   fixe de 190/280/340px sur un écran de ~370px de large, peut
   réclamer une largeur bien supérieure à l'écran, sans qu'il y ait
   quoi que ce soit pour l'en empêcher.

   1er essai de correctif (abandonné) : ajouter un simple
   "max-width: calc(100vw - 2*gutter)" en gardant la hauteur FIXE
   telle quelle. Ça supprimait bien le débordement, mais testé en
   rendu réel (Playwright) ça DÉFORMAIT les images larges : la
   hauteur restant fixe pendant que la largeur se faisait plafonner,
   le ratio d'origine n'était plus respecté (une photo 16:9 se
   retrouvait écrasée à un ratio proche de 1:1). La propriété
   'height' n'étant PAS 'auto' au départ (elle a une valeur fixe en
   px), rien ne la fait redescendre automatiquement quand max-width
   s'applique — seule 'width' est recalculée par l'algorithme
   min/max-width, pas 'height'.

   Fix retenu : sous 700px, 'height' ET 'width' passent toutes les
   deux à 'auto', et les tailles voulues (190/280/340px) deviennent
   des 'max-height' au lieu de 'height' fixes, combinées au
   'max-width' calculé depuis l'écran. Avec largeur ET hauteur
   toutes deux 'auto' et un ratio intrinsèque connu, le navigateur
   choisit la plus grande taille qui respecte À LA FOIS max-width
   ET max-height sans déformer le média (comportement standard,
   vérifié en rendu réel) : un média portrait ou modérément large
   atteint sa max-height comme avant, un média très large (paysage)
   est plafonné par max-width et sa hauteur affichée diminue en
   proportion pour garder ses vraies proportions — jamais de
   déformation, jamais de débordement. */
@media (max-width: 700px) {
  .media-grid img,
  .media-grid video,
  .media-featured img,
  .media-featured video,
  .media-hero img,
  .media-hero video {
    width: auto;
    height: auto;
    max-width: calc(100vw - (var(--gutter) * 2));
  }

  .media-grid img,
  .media-grid video {
    max-height: 190px;
  }

  .media-featured img,
  .media-featured video {
    max-height: 280px;
  }

  .media-hero img,
  .media-hero video {
    max-height: 340px;
  }

  .media-small img,
  .media-small video {
    max-height: 100px;
  }
}

/* Paire "côte à côte" forcée sur mobile — 27/08/2026 (demande
   d'Alizée : TechnoFée City et le poème Juptur et Nepter, dans
   Glossolalie, doivent rester côte à côte même sur téléphone).
   Par défaut, .media-grid garde la hauteur de chaque média et
   laisse les figures passer à la ligne si la largeur totale
   dépasse l'écran — ce qui arrivait ici : une image carrée
   (TechnoFée City) + une image portrait (le poème), à la hauteur
   mobile standard de 190px, arrivaient tout juste à dépasser la
   largeur disponible sur les écrans les plus étroits.

   Pour cette paire précise, `.media-pair` abandonne la logique
   "hauteur fixe, largeur libre" au profit d'un partage égal de la
   largeur disponible entre les deux figures (`flex: 1 1 0`),
   chacune affichant son média à 100% de sa part. Les deux médias
   n'ont donc plus la même hauteur affichée entre eux (l'image
   carrée et l'image portrait du poème n'ont de toute façon jamais
   eu vocation à être à la même échelle), mais ils restent
   TOUJOURS côte à côte, quelle que soit la largeur de l'écran —
   contrairement à un simple ajustement de max-height qui resterait
   fragile face à un écran encore plus étroit. */
@media (max-width: 700px) {
  .media-grid.media-pair {
    flex-wrap: nowrap;
  }

  .media-grid.media-pair figure {
    flex: 1 1 0;
    min-width: 0;
  }

  .media-grid.media-pair img,
  .media-grid.media-pair video {
    width: 100%;
    height: auto;
    max-width: none;
    max-height: none;
  }
}

/* Mise en page "encadrée" : une image/vidéo centrale un peu plus
   grande, flanquée de deux médias plus petits de part et d'autre
   (ex. Glossolalie — la peinture "Le Monde" encadrée par les
   vidéos de process). Tailles fixes à l'échelle des autres photos
   du site (même esprit que la grille de Cadmos et Harmonie) : pas
   de mise en page géante qui s'étire sur toute la largeur. */
.media-framed {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 24px;
  margin-bottom: 24px;
}

.media-framed figure {
  margin: 0;
  flex: 0 0 auto;
}

.media-framed .framed-side {
  width: 240px;
}

.media-framed .framed-main {
  width: 520px;
}

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

@media (max-width: 700px) {
  .media-framed .framed-side {
    width: 100%;
    max-width: 220px;
  }

  .media-framed .framed-main {
    width: 100%;
    max-width: 400px;
  }
}

.work-entry .desc {
  max-width: 680px;
  font-size: 1.05rem;
}

/* =========================================================
   L'Univers / Universe — texte long, une seule colonne
   resserrée. Ton poétique mais pas hermétique.
   ========================================================= */

.universe-content {
  max-width: 680px;
}

.statement {
  font-size: 1.15rem;
  line-height: 1.7;
}

/* 30/08/2026 : petit visuel "cascade d'eau" au-dessus du texte,
   à la demande d'Alizée — un détail de l'image de référence DA
   (la même scène glitch/aquatique évoquée à la Touche 6), qu'elle
   avait entouré à la main sur une capture. Recadré plus précisément
   que son cercle (juste la cascade scintillante + la voûte de
   pierre pâle au-dessus, sans les ruines beiges autour). Bordure
   blanche + ombre portée : effet "gif/émoticône" volontairement
   rétro, clin d'œil aux sites perso et à MSN des années 2000,
   assumé comme un décalage avec le reste du site plus épuré.
   Centré avec la colonne de texte, pousse les paragraphes vers le
   bas. Fichier en 2x (192×356) pour rester net en petite taille. */
.universe-waterfall {
  display: block;
  width: 96px;
  height: auto;
  margin: 24px auto 40px;
  border: 4px solid #ffffff;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
}

/* =========================================================
   Fond vidéo fixe orange sur Univers/Universe — ajouté le
   30/08/2026 à la demande d'Alizée : "une vidéo comme pour
   l'accueil, en fond, mais orange cette fois". Même clip source
   que le fond bleu de l'accueil ("La Piscine de Harmonie"),
   régradé du rouge vers l'orange par Alizée dans DaVinci Resolve
   (rotation de teinte sur les roues HDR).

   Différence clé avec .splash-video-bg : ici la vidéo est en
   position FIXED (pas absolute). .splash est un unique écran
   100vh avec overflow:hidden — la vidéo en absolute suffit,
   rien ne défile. Univers/Universe, à l'inverse, est une page
   qu'on fait défiler sur 4 paragraphes : une vidéo en absolute
   défilerait avec le texte et sortirait de l'écran après le
   premier paragraphe. En fixed, la vidéo reste plaquée à la
   fenêtre pendant que .universe-content défile par-dessus —
   un vrai fond permanent, du premier au dernier paragraphe.

   Le header passe aussi en blanc/transparent sur cette page
   (voir body.universe-page .site-header plus bas), pour laisser
   la vidéo visible même derrière la barre de nav en scrollant —
   il reste toutefois "sticky" (pas "fixed" comme sur le splash),
   cohérent avec le comportement du header sur le reste du site
   "intérieur". Le panneau de menu mobile réutilise le même
   correctif que .splash-page (voir le bloc @media 700px plus
   haut, sélecteurs partagés body.splash-page / body.universe-page). */

body.universe-page {
  /* Fond de secours sombre le temps que la vidéo charge — évite un
     flash blanc avant que .universe-video-bg ne s'affiche. */
  background: #1a0a00;
}

.universe-video-bg {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

/* Voile chaud par-dessus la vidéo — allégé le 30/08/2026 (retour
   d'Alizée : "trop foncé, comme un voile dessus"). Un premier essai
   à rgba 0.5 (plus soutenu que l'accueil, à 0.32) partait de l'idée
   qu'un orange clair a besoin de plus de contraste pour porter du
   texte blanc sur 4 paragraphes — mais en le voyant en vrai, ça
   ternissait trop la vidéo elle-même. Ramené à 0.28, sous le niveau
   de l'accueil : la lisibilité du texte blanc est reprise par une
   ombre portée sur .statement ci-dessous plutôt que par un voile
   plus opaque, ce qui laisse l'orange respirer. */
.universe-scrim {
  position: fixed;
  inset: 0;
  background: rgba(20, 8, 0, 0.28);
  z-index: 1;
}

body.universe-page main.universe-content {
  position: relative;
  z-index: 2;
}

body.universe-page .statement {
  color: #ffffff;
  /* Ombre douce plutôt qu'un voile plus opaque, pour garder le texte
     lisible sur les zones les plus claires du dégradé sans assombrir
     la vidéo elle-même (voir .universe-scrim juste au-dessus). */
  text-shadow: 0 1px 6px rgba(20, 8, 0, 0.55);
}

.video-credit {
  margin-top: 8px;
  font-size: 0.75rem;
  letter-spacing: 0.03em;
  color: rgba(255, 255, 255, 0.55);
}

/* Header transparent sur Univers/Universe pour laisser voir la
   vidéo derrière la barre de nav en scrollant (même logique que
   body.splash-page .site-header, mais position:sticky conservée
   plutôt que fixed — voir le commentaire du bloc plus haut). */
body.universe-page .site-header {
  background: transparent;
  border-bottom: none;
}

body.universe-page .site-header .logo {
  color: #ffffff;
}

body.universe-page .site-nav a {
  color: rgba(255, 255, 255, 0.75);
}

body.universe-page .site-nav a:hover,
body.universe-page .site-nav a:focus-visible,
body.universe-page .site-nav a.active {
  color: #ffffff;
  border-bottom-color: #ffffff;
}

body.universe-page .lang-switch a {
  color: rgba(255, 255, 255, 0.85);
  border-color: rgba(255, 255, 255, 0.5);
}

body.universe-page .lang-switch a:hover,
body.universe-page .lang-switch a:focus-visible {
  color: #ffffff;
  border-color: #ffffff;
}

body.universe-page .menu-toggle span {
  background: #ffffff;
}

body.universe-page .site-footer {
  position: relative;
  z-index: 2;
  background: transparent;
  border-top-color: rgba(255, 255, 255, 0.25);
  color: rgba(255, 255, 255, 0.7);
}

body.universe-page .site-footer a {
  color: #ffffff;
}

/* Respect du confort des personnes sensibles au mouvement, même
   traitement que sur l'accueil : la vidéo disparaît au profit d'un
   dégradé statique orange fixe (donc pas d'attribut fixed non plus
   à masquer côté scrim, qui reste — la page garde son contraste). */
@media (prefers-reduced-motion: reduce) {
  .universe-video-bg {
    display: none;
  }

  body.universe-page {
    background: linear-gradient(135deg, #ff8a3d 0%, #c9401a 55%, #ffd9a8 100%);
  }
}

/* =========================================================
   CV (fusionné avec À propos)
   ========================================================= */

/* Petites lignes de repère (formation / lieu de vie et travail),
   en tête du CV. Ajoutées le 27/08/2026 : d'abord posées autour de
   la bio sur la page L'univers, puis déplacées ici à la demande
   d'Alizée — "à la suite en haut de la page CV". Même traitement
   discret, en petites capitales grises, que les intitulés de
   section (.cv-section h2). */
.bio-meta {
  color: var(--color-muted);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 8px;
}

.bio-meta:last-of-type {
  margin-bottom: 40px;
}

.cv-section {
  margin-bottom: 48px;
}

.cv-section h2 {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  margin-bottom: 16px;
}

.cv-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.cv-list li {
  display: grid;
  grid-template-columns: 90px 1fr;
  gap: 16px;
  border-bottom: 1px solid var(--color-border);
  padding-bottom: 12px;
}

.cv-year {
  color: var(--color-muted);
  font-size: 0.9rem;
}

/* Détail d'une entrée de CV riche (ajouté le 22/08/2026, nouveau CV) :
   titre en gras, puis une ligne de contexte discrète en dessous
   (lieu/contexte + précisions), à la manière d'une notice de
   catalogue. Le lien éventuel vers une source de presse/officielle
   reste discret (souligné, pas de couleur d'accent). */
.cv-detail strong {
  font-weight: 600;
}

.cv-detail a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cv-note {
  display: block;
  margin-top: 4px;
  color: var(--color-muted);
  font-size: 0.85rem;
  line-height: 1.5;
}

/* =========================================================
   Contact
   ========================================================= */

.contact-content {
  max-width: 480px;
}

.contact-email {
  display: inline-block;
  font-size: 1.3rem;
  border-bottom: 1px solid var(--color-text);
  margin: 8px 0 32px;
}

.contact-socials {
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* =========================================================
   Pixealizée — fil conducteur
   ========================================================= */

/*
  30/08/2026 : bandeau "Pixealizée" ajouté sur toutes les pages du
  site, à la demande d'Alizée — un fil conducteur visuel. L'oeuvre
  d'origine est une peinture numérique en dégradé (issue de la
  musique "Dragon Rose", Cadmos et Harmonie 2023), reconstituée en
  une bande horizontale continue et étirée à partir du fichier
  source réel ("version petits carrés" — texture pixel visible,
  choisie par Alizée), puis découpée en 5 segments égaux, un par
  page (Accueil, Travaux, Univers, CV, Contact), pour que le
  dégradé se poursuive visuellement quand on navigue de page en
  page. Pas de lignes noires : les schémas montrés par Alizée
  n'étaient que des repères d'emplacement, pas un élément de design
  à garder. Bandeau fin, pleine largeur, image en object-fit:cover
  pour ne jamais déformer le dégradé.

  30/08/2026 (retour d'Alizée après premier essai en ligne) :
  étirement ramené de ×4,0 à ×3,2 ("un peu moins étiré"), et le
  bandeau du HAUT est retiré de la page d'accueil (demande
  explicite — le splash a déjà la vidéo de fond + le nom, pas
  besoin d'un bandeau de plus en haut). Un second bandeau, en BAS
  de chaque page intérieure (Travaux, Univers, CV, Contact), a été
  ajouté juste avant le footer — voir .pixealizee-strip-bottom
  ci-dessous — pour prolonger le fil conducteur, scindé en deux
  "morceaux" avec un espace entre les deux (schémas d'Alizée).

  30/08/2026 (retour suivant, captures annotées) : le bandeau du
  HAUT n'est plus un ruban continu pleine largeur — Alizée voulait
  seulement deux petits bouts, cropés, calés à la même position
  verticale qu'avant mais alignés horizontalement avec le logo
  (haut gauche) et le bouton de langue FR/EN (haut droite), avec
  un vide entre les deux (le header lui-même est vide au milieu).
  Réutilise les MÊMES classes .pixealizee-strip-chunk / --left /
  --right que le bandeau du bas, avec des largeurs mesurées sur le
  logo (~144px) et le bouton de langue (~42px) pour un alignement
  précis.

  30/08/2026 (retour suivant, "je n'ai pas été claire") : précision
  d'Alizée sur ces deux petits bouts — ils ne doivent PAS s'arrêter
  au même endroit que le logo/bouton (bord intérieur du gutter),
  mais déborder jusqu'au bord réel de la page : "Pixealizée doit
  partir des bords de la page et s'arrêter à la fin de Clavaud",
  "en dessous de FR pareil, va jusqu'au bout de la page" — le ruban
  déborde du contenu, contrairement au logo/bouton eux-mêmes, pour
  bien lire "fait le lien entre les pages, comme un ruban". Largeurs
  donc élargies pour inclure le gutter : 168px à gauche (gutter 24px
  + logo ~144px), 66px à droite (bouton ~42px + gutter 24px) — le
  point d'ARRÊT (fin de "Clavaud", début de "FR") reste identique à
  avant, seul le point de DÉPART change (bord de page plutôt que
  bord du gutter). Plus de `padding` sur `.pixealizee-strip` : les
  bouts touchent maintenant les deux bords de la fenêtre.

  30/08/2026 (retour suivant, "ensuite c'est bon") : la page Contact
  a eu un temps une exception (calage sur le gutter comme avant) —
  Alizée a précisé qu'elle voulait en fait exactement le même bord
  de page que les autres pages ici aussi. Exception retirée : Contact
  suit maintenant la même règle que Travaux/Univers/CV.
*/

.pixealizee-strip {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: space-between;
  height: 10px;
  overflow: hidden;
  line-height: 0;
}

.pixealizee-strip .pixealizee-strip-chunk {
  flex: 0 0 auto;
}

/* Bord de page → fin de "Clavaud" (gutter 24px + logo ~144px). */
.pixealizee-strip .pixealizee-strip-chunk--left {
  width: 168px;
}

/* Début de "FR"/"EN" → bord de page (bouton ~42px + gutter 24px). */
.pixealizee-strip .pixealizee-strip-chunk--right {
  width: 66px;
}

/* Sur le splash (position:absolute, un seul écran 100vh), le bandeau
   est calé juste sous le header sticky plutôt que dans le flux
   normal du document. */
body.splash-page .pixealizee-strip {
  position: absolute;
  top: var(--nav-height);
  left: 0;
  right: 0;
  height: 8px;
  z-index: 3;
}

.pixealizee-strip-chunk {
  height: 100%;
  overflow: hidden;
  line-height: 0;
}

.pixealizee-strip-chunk img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pixealizee-strip-chunk--left img {
  object-position: left center;
}

.pixealizee-strip-chunk--right img {
  object-position: right center;
}

/* Bandeau du bas — Travaux, Univers, CV uniquement (pas Contact,
   pas Accueil). Reprend le MÊME fichier image que le bandeau du
   haut de la page, en continu, pleine largeur, sans coupure.

   30/08/2026 : scindé un temps en deux "morceaux" avec un espace
   (schémas d'Alizée), puis 30/08/2026 (retour suivant) : "j'aime
   pas trop que la ligne se sépare finalement en bas" — revenu à une
   bande continue, comme le bandeau du haut avant son propre
   recadrage en coins. */
.pixealizee-strip-bottom {
  position: relative;
  z-index: 2;
  height: 10px;
  overflow: hidden;
  line-height: 0;
}

.pixealizee-strip-bottom img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Page Contact : dernière étape du ruban (Accueil → Travaux →
   Univers → CV → Contact) — pas d'image ici, juste le crédit de
   l'œuvre (titre + copyright), à la demande d'Alizée ("trop de
   Pixealizée" sur cette page).

   30/08/2026 (correctif lisibilité) : ce crédit vivait jusqu'ici
   DANS `.pixealizee-strip-bottom` (hérité de l'époque où cette page
   avait aussi une image dans cette bande) — un conteneur pensé pour
   une image de 10px de haut avec `overflow:hidden`, qui rognait donc
   le texte du crédit et le collait contre la bordure du footer juste
   en dessous ("problème de lisibilité"). Sorti de ce conteneur,
   placé directement dans le flux de la page avec ses propres marges
   (`margin: 24px 0`) pour respirer normalement. */
.pixealizee-credit {
  display: block;
  margin: 24px 0;
  font-size: 0.7rem;
  letter-spacing: 0.03em;
  color: var(--color-muted);
  text-align: right;
}

/* =========================================================
   Vidéo de marge — Travaux uniquement
   ========================================================= */

/*
  30/08/2026 : petite vidéo en marge, à la demande d'Alizée, essayée
  d'abord sur les pages Travaux et CV (voir schémas — rectangles
  violets en marge gauche du CV et marge droite de Travaux). Extrait
  de "Dégradé 2 NB distorsion" (2023, même famille de vidéos-dégradé
  que "Dégradé 8 Bleu" utilisée en fond de l'accueil) — passage noir
  et blanc (demande d'Alizée : "la partie noire et blanche", plutôt
  que le passage coloré essayé au premier essai) vers 8-13s, recadré
  en portrait 240×320, ~250 Ko.

  30/08/2026 (correctif après "je vois pas la vidéo") : largeur
  calculée dynamiquement avec `clamp()` à partir de la marge
  réellement disponible (`calc((100vw - var(--max-width)) / 2 -
  16px)`, bornée 48-140px) plutôt qu'un seuil/une largeur fixes —
  s'affiche dès qu'il y a assez de marge propre, ne peut jamais
  chevaucher la colonne de contenu par construction.

  30/08/2026 (aller-retour) : un temps retirée de Travaux et déplacée
  en bande "format footer" sur Contact ("je n'ai pas été claire, la
  vidéo je la veux que dans le footer de Contact"), puis remise sur
  Travaux au retour suivant : "tu remets la vidéo dans travaux comme
  précédemment alignée avec l'image" — donc les DEUX à la fois
  désormais : vidéo de marge sur Travaux (ci-dessous, position
  mesurée au pixel près sur la première œuvre du Bain), ET bande
  "format footer" sur Contact (voir .footer-video-strip plus bas).
*/
.margin-video {
  display: none;
}

@media (min-width: 1230px) {
  .margin-video {
    display: block;
    position: absolute;
    width: clamp(48px, calc((100vw - var(--max-width)) / 2 - 16px), 140px);
    aspect-ratio: 3 / 4;
    overflow: hidden;
  }

  .margin-video video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  body.works-page {
    position: relative;
  }

  /* Travaux : marge droite, alignée par le haut avec la première
     œuvre (Le Bain, groupe 86×130cm — bord haut mesuré à 315px). */
  body.works-page .margin-video {
    top: 315px;
    right: 16px;
  }
}

/* =========================================================
   Vidéo — footer (Contact)
   ========================================================= */

/*
  30/08/2026 (correctif) : la première version ("footer-video-strip")
  recadrait la vidéo en bande fine de 10px comme les bandeaux
  Pixealizée — mais une vidéo cropée aussi serré perd toute lisibilité
  ("la vidéo en noir et blanc est devenue une ligne"). Remplacée par
  un vrai petit bloc vidéo affiché TEL QUEL (pas de crop, pas
  d'object-fit) : largeur fixe, hauteur automatique selon les
  proportions réelles du fichier. Alizée a aussi demandé de repasser
  sur l'extrait COLORÉ (magenta/bleu/rouge, ~59-63s) plutôt que le
  noir et blanc utilisé sur Travaux — nouveau fichier dédié
  (`footer-video-color.mp4`, même source "Dégradé 2 NB distorsion")
  pour ne pas toucher à la vidéo de Travaux.

  30/08/2026 (correctif suivant, "pourquoi il y a rien dans l'espace
  blanc ?") : le premier recadrage (portrait 240×320, même cadrage
  que l'essai initial sur Travaux) reprenait toute la hauteur de
  l'image source à cet instant précis de la vidéo — or à cet endroit
  du clip, seule la moitié HAUTE du cadre contient le tourbillon
  coloré, la moitié basse est un fond blanc uni (vérifié pixel par
  pixel sur plusieurs frames de l'extrait : coupure nette et stable
  vers 50% de la hauteur). D'où le grand bloc blanc vide sous la
  vidéo. Recadré à nouveau, sur la seule zone active (crop
  810×540, même fenêtre horizontale, hauteur divisée par deux) —
  vérifié sur toute la durée de l'extrait (59 à 63s) qu'elle reste
  bien remplie de mouvement du début à la fin. Nouveau format
  paysage (320×212, ratio ~3:2) plutôt que portrait : largeur
  affichée augmentée en conséquence pour rester lisible. */
.contact-footer-video {
  display: block;
  width: 180px;
  margin: 20px auto 0;
}

.contact-footer-video video {
  display: block;
  width: 100%;
  height: auto;
}

/* =========================================================
   Lightbox — page Works/Travaux, ajouté le 30/08/2026 à la
   demande d'Alizée : "pouvoir cliquer sur les oeuvres (images
   fixes) ... pour qu'elles puissent s'afficher en plus grand sur
   l'écran". Ne s'applique qu'aux <img> de .works-gallery — les
   vidéos ne sont volontairement pas concernées (déjà lisibles/
   jouables en place, un agrandissement n'apporterait rien).

   Un seul bloc de lightbox existe dans le HTML (voir works.html /
   fr/travaux.html, juste avant </body>), rempli dynamiquement par
   script.js au clic sur une image plutôt que dupliqué par oeuvre —
   plus simple à maintenir à chaque ajout d'une nouvelle pièce. */
.works-gallery figure img {
  cursor: pointer;
}

.lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 56px var(--gutter);
  background: rgba(0, 0, 0, 0.92);
  box-sizing: border-box;
}

.lightbox-overlay[hidden] {
  display: none;
}

.lightbox-content {
  margin: 0;
  max-width: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.lightbox-img {
  display: block;
  max-width: 100%;
  max-height: 80vh;
  width: auto;
  height: auto;
  object-fit: contain;
}

.lightbox-caption {
  margin-top: 16px;
  color: #ffffff;
  font-size: 0.8rem;
  letter-spacing: 0.03em;
  text-align: center;
}

.lightbox-caption:empty {
  display: none;
}

.lightbox-close {
  position: absolute;
  top: 16px;
  right: var(--gutter);
  width: 44px;
  height: 44px;
  border: none;
  background: transparent;
  color: #ffffff;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
}

/* Empêche le fond de défiler pendant que le lightbox est ouvert —
   même principe que body.nav-locked (menu mobile), classe dédiée
   pour ne pas coupler les deux comportements entre eux. */
body.lightbox-open {
  overflow: hidden;
}
