/* ============ Base / thèmes ============ */
:root {
  --bg: #fafaf7;
  --ink: #171717;
  --muted: #8a8a86;
  --chrome-h: 96px;
  /* Durée d'un cycle complet de la boucle d'animation de la home.
     Toutes les pièces animées partagent cette durée pour rester synchronisées. */
  --loop: 3.6s;
  color-scheme: light;
}
html[data-theme="dark"] {
  --bg: #131316;
  --ink: #f2f2ef;
  --muted: #7d7d84;
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  transition: background 0.35s ease, color 0.35s ease;
}

/* ============ Header commun ============ */
.site-header {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: var(--chrome-h);
  z-index: 90;
  pointer-events: none;
  /* Les entourages rouges débordent de 16 px autour de chaque entrée : sur un
     téléphone, celui du dernier bouton sortirait de l'écran et ferait défiler
     la page en largeur. */
  overflow: clip;
}
.site-header a,
.site-header button { pointer-events: auto; }

.site-nav {
  position: absolute;
  top: 34px; left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 36px;
  white-space: nowrap;
}
.nav-item {
  position: relative;
  display: inline-block;
  padding: 8px 6px;
  color: var(--ink);
  text-decoration: none;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.01em;
}
.nav-underline {
  position: absolute;
  top: -14px; left: -16px;
  width: calc(100% + 32px);
  height: calc(100% + 28px);
  pointer-events: none;
  overflow: visible;
}
.nav-underline path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  opacity: 0;
  transition: stroke-dashoffset 0.6s ease, opacity 0.2s ease;
}
/* Uniquement au survol : l'entourage ne doit pas rester après un clic. */
.nav-item:hover .nav-underline path {
  stroke-dashoffset: 0;
  opacity: 1;
}
/* « Contact me » est un bouton (il ouvre le badge sans changer de page) mais
   doit se fondre parmi les liens du menu. */
button.nav-item {
  background: none;
  border: 0;
  margin: 0;
  font-family: inherit;
  line-height: normal;
  cursor: pointer;
}

/* ============ Contrôles fixes (langue + thème) ============ */
.site-controls {
  position: fixed;
  top: 20px; right: 24px;
  z-index: 200;
  display: flex;
  align-items: center;
  gap: 14px;
}
.ctrl-group {
  display: flex;
  align-items: center;
  gap: 8px;
}
/* Les zones blanches des drapeaux sont transparentes dans les PNG : sur fond
   sombre elles prenaient la couleur du fond (bleu, rouge, noir). Un rectangle
   blanc opaque derrière, dans les deux thèmes, leur rend leurs vraies couleurs.
   Le drapeau lui-même garde ses 30 × 21 px, le rectangle ajoute 2 px autour. */
.flag-btn {
  width: 34px; height: 25px;
  padding: 2px;
  border: none;
  background: #fff;
  border-radius: 3px;
  cursor: pointer;
  opacity: 0.4;
  transition: opacity 0.25s ease, transform 0.15s ease;
  display: block;
}
.flag-btn img { width: 100%; height: 100%; object-fit: contain; display: block; }
.flag-btn:hover { opacity: 0.8; transform: scale(1.1); }
.flag-btn.active { opacity: 1; }
.theme-btn {
  width: 28px; height: 28px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.2s ease;
}
.theme-btn:hover { transform: scale(1.15) rotate(12deg); }
.theme-btn svg { width: 20px; height: 20px; }
.icon-moon { display: none; }
html[data-theme="dark"] .icon-sun { display: none; }
html[data-theme="dark"] .icon-moon { display: block; }

/* ============ Retour à l'accueil (logo, en haut à gauche) ============
   Symétrique des contrôles de droite ; common.js ne l'ajoute pas sur la landing.
   Le PNG du logo a beaucoup de blanc autour du mot : à 34 px de haut, le mot
   lui-même mesure ~15 px, à la taille des icônes voisines. */
.home-btn {
  position: fixed;
  top: 20px; left: 24px;
  z-index: 200;
  display: block;
  height: 34px;
  transition: transform 0.2s ease;
}
.home-btn img { height: 100%; width: auto; display: block; }
.home-btn:hover { transform: scale(1.08); }
/* Le logo est noir : en mode sombre on l'inverse plutôt que de charger une
   seconde image. */
html[data-theme="dark"] .home-btn img { filter: invert(1); }

@media (max-width: 860px) {
  :root { --chrome-h: 132px; }
  .site-nav { top: 74px; gap: 12px; }
  .nav-item { font-size: 12.5px; padding: 6px 3px; }
  .site-controls { top: 14px; right: 14px; }
  .home-btn { top: 14px; left: 14px; }
}

/* ============ Homepage ============ */
.home-root {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}
.home-center {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  padding: 0 40px;
  text-align: center;
}
.home-title {
  margin: 0;
  font-size: min(15vw, 220px);
  line-height: 0.92;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--ink);
  position: relative;
  display: inline-block;
}
.home-title .letter {
  display: inline-block;
  will-change: transform;
}
.home-title .word {
  display: inline-block;
  position: relative;
}
/* L'exclamation est ancrée au dernier mot : elle reste posée au bas du R,
   que « FOR » termine une ligne (bureau) ou occupe la sienne (téléphone). */
.home-title .excla {
  position: absolute;
  bottom: -31%;
  right: -25%;
  height: 128%;
  width: auto;
  pointer-events: none;
  will-change: transform;
}
.home-script {
  position: absolute;
  top: 50%; left: 50%;
  width: min(72vw, 1056px);
  height: auto;
  transform: translate(-50%, -50%);
  z-index: 5;
  pointer-events: none;
}
.home-stars {
  position: absolute;
  bottom: 71px; left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 20px;
}
.home-star {
  display: inline-flex;
  color: var(--ink);
  will-change: transform;
  transition: color 0.2s ease;
}
.home-star:hover { animation: none !important; color: #ff0000; }

/* --- Entrée : la page est nue, chaque élément arrive à son tour --- */
html.intro .home-title .letter,
html.intro .home-title .excla,
html.intro .home-script,
html.intro .home-star,
html.intro .site-header,
html.intro .site-controls {
  opacity: 0;
}
@keyframes letterIn {
  from { opacity: 0; transform: translateY(26px) scale(0.94); filter: blur(9px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes exclaIn {
  0%   { opacity: 0; transform: scale(0.4) rotate(-16deg); }
  70%  { opacity: 1; transform: scale(1.08) rotate(3deg); }
  100% { opacity: 1; transform: none; }
}
@keyframes scriptIn {
  from { opacity: 0; transform: translate(-50%, -50%) scale(1.06); filter: blur(10px); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); filter: blur(0); }
}
@keyframes starIn {
  0%   { opacity: 0; transform: scale(0.3) translateY(12px); }
  65%  { opacity: 1; transform: scale(1.18) translateY(0); }
  100% { opacity: 1; transform: none; }
}
@keyframes chromeIn {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: none; }
}
html.playing .home-title .letter {
  animation: letterIn 0.65s cubic-bezier(0.2, 0.75, 0.25, 1) both;
}
html.playing .home-title .excla {
  animation: exclaIn 0.6s cubic-bezier(0.2, 0.8, 0.25, 1) both;
}
html.playing .home-script {
  animation: scriptIn 0.8s cubic-bezier(0.2, 0.75, 0.25, 1) both;
}
html.playing .home-star {
  animation: starIn 0.55s cubic-bezier(0.2, 0.8, 0.25, 1) both;
}
html.playing .site-header,
html.playing .site-controls {
  animation: chromeIn 0.7s ease both;
}

/* --- Boucle : lettres, puis l'exclamation, puis les étoiles --- */
@keyframes letterBump {
  0%, 12%, 100% { transform: translateY(0); }
  6%            { transform: translateY(-9px); }
}
@keyframes exclaBump {
  0%, 14%, 100% { transform: translateY(0) rotate(0deg); }
  7%            { transform: translateY(-11px) rotate(-4deg); }
}
@keyframes starBump {
  0%, 16%, 100% { transform: translateY(0); }
  8%            { transform: translateY(-10px); }
}
html.loaded .home-title .letter { animation: letterBump var(--loop) ease-in-out infinite; }
html.loaded .home-title .excla  { animation: exclaBump  var(--loop) ease-in-out infinite; }
html.loaded .home-star          { animation: starBump   var(--loop) ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  html.intro .home-title .letter,
  html.intro .home-title .excla,
  html.intro .home-script,
  html.intro .home-star,
  html.intro .site-header,
  html.intro .site-controls { opacity: 1; }
  html.playing .home-title .letter,
  html.playing .home-title .excla,
  html.playing .home-script,
  html.playing .home-star,
  html.playing .site-header,
  html.playing .site-controls,
  html.loaded .home-title .letter,
  html.loaded .home-title .excla,
  html.loaded .home-star { animation: none; }
}

/* ============ Intercalaires (YouTube / Brand) ============ */
.divider-page {
  min-height: 100vh;
  min-height: 100svh;
  width: 100%;
  position: relative;
  display: flex;
  flex-direction: column;
  padding-top: calc(var(--chrome-h) + 64px);
  /* Rogne les débordements décoratifs (grands titres, feuilles inclinées) sans
     empêcher la page de grandir : au-delà de 10 clients c'est le document qui
     défile, pas un conteneur interne. */
  overflow: clip;
}
.dividers-wrap {
  flex: none;
  position: relative;
  display: flex;
  flex-direction: column;
}
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
.divider-slot {
  position: relative;
  flex-basis: 0;
  flex-shrink: 0;
  min-height: 0;
  transition: flex-grow 0.5s cubic-bezier(0.22, 0.8, 0.2, 1);
}
.divider-sheet {
  position: absolute;
  left: -10px; right: -10px;
  border-radius: 3px;
  border: 1.5px solid #ffffff;
  cursor: pointer;
  transition: top 0.2s ease, bottom 0.2s ease, box-shadow 0.3s ease;
}
.divider-tab {
  position: absolute;
  border: 1.5px solid #ffffff;
  border-bottom: none;
  box-shadow: 0 -3px 6px rgba(0, 0, 0, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 19px;
  letter-spacing: 0.06em;
  cursor: pointer;
  overflow: hidden;
  padding: 0 10px;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.divider-toptitle {
  position: absolute;
  top: 0; left: 0; right: 0;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  font-size: clamp(60px, 16vw, 230px);
  line-height: 1;
  cursor: pointer;
  overflow: hidden;
  white-space: nowrap;
}
.divider-clip {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 3px;
  pointer-events: none;
}
/* Le bloc player occupe toute la hauteur de l'intercalaire ouvert et recouvre
   volontairement le grand titre du client qui se trouve derrière. */
.divider-content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Sans effet quand le panneau remplit la hauteur ; sur écran étroit, où le
     16:9 est bridé par la largeur, il est centré plutôt que collé en haut. */
  justify-content: center;
  padding: clamp(6px, 1.6vh, 20px) 16px clamp(8px, 1.8vh, 22px);
  animation: fadeIn 0.4s ease;
  pointer-events: auto;
}
/* Croix de fermeture de l'intercalaire ouvert : pastille de la même matière
   que le panneau (couleur du client assombrie de 10 % et texture, posées par
   dividers.js), au-dessus du panneau et de l'étiquette de rôle. Placée dans
   .divider-content, donc à l'intérieur de la zone rognée par .divider-clip :
   jamais coupée. */
.divider-close {
  position: absolute;
  top: 10px; right: 10px;
  z-index: 4;
  width: 34px; height: 34px;
  padding: 0;
  border: 1.5px solid #ffffff;
  border-radius: 50%;
  font: 700 15px/1 'Helvetica Neue', Helvetica, Arial, sans-serif;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.22);
  transition: transform 0.15s ease, box-shadow 0.2s ease;
}
.divider-close:hover {
  transform: scale(1.1);
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.28);
}
/* Étiquettes de projet : soudées au panneau, mais derrière lui en profondeur. */
.mini-tabs {
  position: relative;
  z-index: 1;
  flex: none;
  display: flex;
  align-items: flex-end;
  gap: 9px;
  flex-wrap: wrap;
  justify-content: center;
  margin-bottom: -6px;
  max-width: 100%;
}
.mini-tab {
  border: 1.5px solid #ffffff;
  border-bottom: none;
  padding: 12px 24px 17px;
  font-size: 19.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  cursor: pointer;
  transition: transform 0.18s ease, box-shadow 0.2s ease;
  transform: translateY(5px);
  /* Ombre interne : l'onglet inactif paraît enfoncé derrière le panneau, sans
     transparence (le grand titre ne doit pas transparaître) ni changement de teinte. */
  box-shadow: inset 0 -7px 11px -7px rgba(0, 0, 0, 0.45), 0 -2px 5px rgba(0, 0, 0, 0.1);
  white-space: nowrap;
  max-width: 360px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mini-tab:hover { transform: translateY(2px); }
/* L'onglet actif affleure le panneau : aucun creux, une ombre portée plus marquée. */
.mini-tab.active {
  transform: translateY(0);
  box-shadow: 0 -5px 12px rgba(0, 0, 0, 0.2);
}
/* Rectangle texturé, même matière que l'intercalaire mais 10 % plus foncé.
   Il remplit la hauteur disponible ; sa largeur découle du 16:9 du player. */
.player-panel {
  --panel-pad: clamp(8px, 1.5vh, 16px);
  position: relative;
  z-index: 2;
  /* Le panneau épouse son contenu ; c'est dividers.js qui dimensionne le player
     en pixels pour qu'il remplisse la hauteur de l'intercalaire en gardant le
     16:9 (flex + aspect-ratio + fit-content forment une dépendance circulaire). */
  flex: none;
  width: fit-content;
  max-width: 100%;
  border: 1.5px solid #ffffff;
  border-radius: 3px;
  padding: var(--panel-pad);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.26);
}
.divider-player {
  flex: none;
  aspect-ratio: 16 / 9;
  background: #101013;
  border: 2px solid #000;
  border-radius: 3px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.divider-player iframe,
.divider-player video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.player-placeholder {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 15px;
  letter-spacing: 0.14em;
  color: #f2f2f2;
  text-align: center;
  padding: 12px;
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}
/* Grosse étiquette de rôle, posée de travers vers le bas du player.
   Inclinaison toujours de 10°, sens et position horizontale tirés au sort par
   projet ; dividers.js ajuste ensuite `bottom` et `left` pour qu'elle tienne
   dans l'intercalaire quelle que soit la longueur du texte. */
.player-role {
  position: absolute;
  z-index: 3;
  bottom: var(--panel-pad);
  margin: 0;
  padding: 15px 36px 20px;
  font-size: clamp(24px, 4.2vh, 51px);
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  /* Bornée par la fenêtre, pas par le panneau : sa taille naturelle doit être
     connue avant de dimensionner le player qui, lui, détermine le panneau. */
  max-width: 76vw;
  overflow: hidden;
  text-overflow: ellipsis;
  border: 1.5px solid #ffffff;
  border-radius: 4px;
  box-shadow: 0 10px 22px rgba(0, 0, 0, 0.32);
  pointer-events: none;
}
.divider-desc {
  margin: 0;
  font-size: 14px;
  opacity: 0.85;
  max-width: 620px;
  text-align: center;
}
.mini-title {
  flex: none;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.9;
  margin: 0;
}

/* ============ Shorts (globe de vidéos) ============ */
:root { --tile-frame: #ffffff; }
html[data-theme="dark"] { --tile-frame: #2a2a30; }
.shorts-page {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}
.shorts-hint {
  position: fixed;
  bottom: 26px; right: 34px;
  z-index: 5;
  text-align: right;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.06em;
  pointer-events: none;
}
/* Scène : toute la zone sous le header. Le globe y est centré. */
.globe-stage {
  position: absolute;
  top: var(--chrome-h); left: 0; right: 0; bottom: 0;
  overflow: hidden;
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  perspective: 1200px;
  perspective-origin: 50% 50%;
}
.globe-stage.grabbing { cursor: grabbing; }
.globe-stage.empty {
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: default;
}
.globe {
  position: absolute;
  left: 50%; top: 50%;
  width: 0; height: 0;
  transform-style: preserve-3d;
  will-change: transform;
}
/* Un écran : posé tangent à la sphère (transform calculé par le JS). La face
   arrière est masquée, et seuls les écrans tournés vers le visiteur (.front)
   répondent au pointeur. */
.tile {
  position: absolute;
  left: 0; top: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  pointer-events: none;
  outline: none;
}
.tile.front { pointer-events: auto; cursor: pointer; }
.tile-inner {
  position: absolute;
  inset: 0;
  padding: 2px;
  border-radius: 4px;
  background: var(--tile-frame);
  box-shadow: 0 10px 24px -12px rgba(20, 20, 25, 0.5), 0 1px 2px rgba(0, 0, 0, 0.12);
  transition: transform 0.28s cubic-bezier(0.22, 0.9, 0.24, 1), box-shadow 0.28s ease;
}
.tile.front:hover .tile-inner,
.tile:focus-visible .tile-inner {
  transform: scale(1.08);
  box-shadow: 0 18px 34px -14px rgba(20, 20, 25, 0.55), 0 2px 4px rgba(0, 0, 0, 0.14);
}
/* Vignette (partagée avec l'aperçu de l'admin) : carte colorée avec le
   titre, recouverte par l'image dès qu'elle est chargée. */
.thumb {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 2px;
  overflow: hidden;
  container-type: inline-size;
}
.thumb-card {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6%;
  text-align: center;
  font-weight: 800;
  text-transform: uppercase;
  line-height: 1.02;
  letter-spacing: 0.02em;
  text-wrap: balance;
  overflow: hidden;
}
.thumb img,
.thumb video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.45s ease;
  pointer-events: none;
}
.thumb.has-media img,
.thumb.has-media video { opacity: 1; }
/* Titre du short, révélé au survol par-dessus l'image (voile sombre en bas).
   Sans image, la carte colorée porte déjà le titre : l'étiquette est masquée. */
.tile-label {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 28% 6% 7%;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0.45) 55%, transparent);
  z-index: 2;   /* l'image, insérée plus tard (vignette asynchrone), passe dessous */
  color: #fff;
  font-size: clamp(10px, 11cqw, 16px);
  font-weight: 800;
  line-height: 1.05;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  text-align: center;
  text-wrap: balance;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.22s ease, transform 0.22s ease;
  pointer-events: none;
}
.tile-label .tile-role {
  display: block;
  margin-top: 3px;
  font-size: 0.72em;
  font-weight: 600;
  letter-spacing: 0.08em;
  opacity: 0.85;
}
.thumb:not(.has-media) .tile-label { display: none; }
/* Fonction (DA, cheffe de projet…) : étiquette inclinée à cheval sur le bas
   du lecteur, dans les couleurs et la police de la vidéo. */
.overlay-role {
  position: absolute;
  bottom: 0; left: 50%;
  z-index: 5;
  margin: 0;
  padding: 8px 16px;
  border: 2px solid var(--tile-frame);
  border-radius: 4px;
  font-size: 14px;
  font-weight: 800;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
  pointer-events: none;
}
.tile.front:hover .tile-label,
.tile:focus-visible .tile-label { opacity: 1; transform: none; }
/* Encoche du lecteur vertical (téléphone) */
.phone-notch {
  position: absolute;
  top: 11px; left: 50%;
  transform: translateX(-50%);
  width: 31%;
  height: clamp(6px, 1.4vh, 13px);
  border-radius: 9px;
  background: #000;
  z-index: 3;
}
/* Overlay lecteur (voile partagé avec le badge Contact) */
.shorts-backdrop,
.contact-backdrop {
  position: fixed;
  inset: 0;
  z-index: 130;
  background: transparent;
  pointer-events: none;
  transition: background 0.5s ease, backdrop-filter 0.5s ease, -webkit-backdrop-filter 0.5s ease;
}
.shorts-backdrop.on,
.contact-backdrop.on {
  background: color-mix(in srgb, var(--bg) 74%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  pointer-events: auto;
}
.shorts-overlay {
  position: fixed;
  z-index: 140;
  display: none;
  transform-origin: 50% 50%;
  transition: transform 0.62s cubic-bezier(0.22, 0.9, 0.24, 1);
  pointer-events: none;
}
.shorts-overlay.open { display: block; }
.overlay-body {
  position: absolute;
  inset: 0;
  border-radius: clamp(16px, 4vh, 36px);
  background: #0c0c0f;
  box-shadow: 0 60px 90px -40px rgba(20, 20, 25, 0.6), inset 0 0 0 1.5px rgba(255, 255, 255, 0.18);
}
.overlay-screen {
  position: absolute;
  inset: clamp(3px, 0.9vh, 8px);
  border-radius: clamp(13px, 3.2vh, 29px);
  overflow: hidden;
  container-type: inline-size;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
}
.overlay-screen iframe,
.overlay-screen video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.overlay-title {
  position: absolute;
  top: 40px; left: 0; right: 0;
  padding: 0 5cqw;
  text-align: center;
  text-transform: uppercase;
  font-weight: 800;
  letter-spacing: 0.02em;
  line-height: 1.05;
  z-index: 2;
  pointer-events: none;
}
.shorts-close {
  position: fixed;
  z-index: 150;
  top: 74px; right: 34px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--ink);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.4s ease 0.15s;
  pointer-events: none;
  background: none;
  border: none;
  padding: 6px;
}
.shorts-close.on { opacity: 1; pointer-events: auto; }

/* ============ Contact : porte-badge en surimpression ============
   Ouvert depuis le menu, par-dessus la page en cours (voile flouté comme le
   lecteur du globe). Attache chromée, chaînette et breloques en SVG inline ;
   pochette plastique translucide et carte blanche en CSS. Tout pend d'un seul
   point (le haut de la languette) et se balance à l'ouverture. Objet clair
   dans les deux thèmes : ses couleurs sont fixes, pas celles du site. */
.contact-overlay {
  position: fixed;
  inset: 0;
  z-index: 140;
  display: none;
  align-items: center;
  justify-content: center;
  padding-top: 24px;
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
  /* Largeur de la pochette : presque tout l'écran sur téléphone, 440 px au
     plus, et moins si l'écran est bas (téléphone en paysage) : attache 134 px
     + pochette 0,7 × largeur doivent tenir en hauteur. */
  --bw: min(92vw, 440px, calc((100vh - 170px) / 0.7));
}
.contact-overlay.open { display: flex; }
.contact-overlay.in { opacity: 1; }
.contact-swing {
  position: relative;
  width: var(--bw);
  transform-origin: 50% 0;
  pointer-events: auto;
  outline: none;
}
/* Entrée : le badge descend au bout de sa chaîne et se balance, pendule
   amorti d'une seconde, puis reste immobile. La chaînette, libre, suit avec un
   temps de retard (contre-rotation). */
.contact-overlay.in .contact-swing { animation: contactDrop 1.1s cubic-bezier(0.3, 0.7, 0.3, 1) both; }
.contact-overlay.in .contact-chain { animation: contactSway 1.3s ease-out 0.05s both; }
@keyframes contactDrop {
  0%   { transform: translateY(-70px) rotate(-9deg); opacity: 0; }
  18%  { opacity: 1; }
  32%  { transform: translateY(0) rotate(6deg); }
  56%  { transform: rotate(-3.5deg); }
  78%  { transform: rotate(1.5deg); }
  100% { transform: none; }
}
@keyframes contactSway {
  0%   { transform: rotate(10deg); }
  30%  { transform: rotate(-8deg); }
  55%  { transform: rotate(4deg); }
  78%  { transform: rotate(-1.5deg); }
  100% { transform: none; }
}
.contact-clip {
  display: block;
  margin: 0 auto;
  width: 160px;
  height: 134px;
  position: relative;
  z-index: 1;
  filter: drop-shadow(0 3px 3px rgba(0, 0, 0, 0.3));
}
/* Accrochée à l'anneau (centre à 66 px du haut), par-dessus la pochette. */
.contact-chain {
  position: absolute;
  top: 66px;
  left: calc(50% - 50px);
  width: 100px;
  height: 150px;
  z-index: 3;
  transform-origin: 41px 9px;
  pointer-events: none;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.3));
}
/* Pochette plastique : dégradés blancs transparents, liseré, ombre portée.
   Remonte de 22 px sous l'attache : la barre du mousqueton traverse la fente. */
.contact-holder {
  position: relative;
  z-index: 2;
  width: var(--bw);
  height: calc(var(--bw) * 0.7);
  margin-top: -22px;
  border-radius: 16px;
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.62) 0%, rgba(255, 255, 255, 0.28) 35%, rgba(255, 255, 255, 0.12) 55%, rgba(255, 255, 255, 0.4) 100%);
  border: 1px solid rgba(90, 95, 105, 0.5);
  box-shadow: 0 34px 60px -24px rgba(0, 0, 0, 0.5), 0 8px 18px -8px rgba(0, 0, 0, 0.25),
    inset 0 0 0 1.5px rgba(255, 255, 255, 0.7), inset 0 0 22px rgba(255, 255, 255, 0.35);
  backdrop-filter: blur(1.5px);
  -webkit-backdrop-filter: blur(1.5px);
}
.contact-slot {
  position: absolute;
  top: 9px; left: 50%;
  width: 66px; height: 9px;
  transform: translateX(-50%);
  border-radius: 5px;
  background: rgba(30, 32, 38, 0.5);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.6), 0 1px 0 rgba(255, 255, 255, 0.65);
}
.contact-gloss {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(118deg, transparent 28%, rgba(255, 255, 255, 0.5) 40%, rgba(255, 255, 255, 0.12) 47%, transparent 56%);
}
/* Carte blanche glissée dans la pochette, sous la bande de la fente. */
.contact-card {
  position: absolute;
  left: 12px; right: 12px; top: 44px; bottom: 12px;
  background: #fff;
  color: #171717;
  border-radius: 8px;
  padding: 10px 16px 12px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), inset 0 0 0 1px rgba(0, 0, 0, 0.06);
  container-type: inline-size;
}
.contact-card [hidden] { display: none; }
/* Clin d'œil « prison » : une toise, fines lignes graduées derrière la photo. */
.contact-card::before {
  content: '';
  position: absolute;
  left: 0; top: 40px; bottom: 0;
  width: 124px;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(to bottom, rgba(23, 23, 23, 0.28) 0 1px, transparent 1px 60px),
    repeating-linear-gradient(to bottom, rgba(23, 23, 23, 0.1) 0 1px, transparent 1px 12px);
  background-size: 16px 100%, 100% 100%;
  background-repeat: no-repeat;
}
.contact-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  height: 24px;
  padding-bottom: 8px;
  border-bottom: 1px solid #e6e6e2;
  font-family: 'IBM Plex Mono', 'Courier New', monospace;
  font-size: 10px;
  letter-spacing: 0.18em;
  color: #8a8a86;
}
.contact-id { color: #171717; }
.contact-body {
  position: relative;
  display: flex;
  gap: 16px;
  align-items: flex-start;
  flex: 1;
  min-height: 0;
  padding-top: 12px;
}
.contact-photo {
  position: relative;
  flex: none;
  width: 96px; height: 96px;
  border-radius: 12px;
  overflow: hidden;
  background: #ececea;
  box-shadow: 0 0 0 2px #fff, 0 2px 6px rgba(0, 0, 0, 0.2);
}
.contact-photo img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
.contact-photo svg { display: block; width: 100%; height: 100%; fill: #bdbdb8; }
.contact-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.contact-name {
  margin: 0;
  font-family: 'Special Elite', 'Courier New', monospace;
  font-size: clamp(19px, 6.8cqw, 27px);
  line-height: 1.05;
  letter-spacing: 0.01em;
  color: #171717;
  overflow-wrap: anywhere;
}
.contact-last { text-transform: uppercase; }
.contact-title {
  margin: 2px 0 6px;
  font-family: 'IBM Plex Mono', 'Courier New', monospace;
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1.35;
  color: #8a8a86;
}
.contact-email,
.contact-phone {
  display: block;
  width: fit-content;
  max-width: 100%;
  color: #171717;
  text-decoration: none;
  font-size: 14px;
  line-height: 1.45;
  border-bottom: 1px solid rgba(23, 23, 23, 0.35);
  overflow-wrap: anywhere;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.contact-email:hover,
.contact-phone:hover { color: #ff0000; border-color: #ff0000; }
.contact-note {
  margin: 8px 0 0;
  font-size: 11.5px;
  font-style: italic;
  line-height: 1.35;
  color: #8a8a86;
}
@media (max-width: 480px) {
  /* Pochette un peu plus haute : toutes les lignes tiennent sur 358 px de large. */
  .contact-holder { height: calc(var(--bw) * 0.84); }
}
@media (max-width: 860px) {
  /* Sous la ligne du menu (celle-ci passe à 74 px sur téléphone). */
  .contact-close { top: 112px; right: 14px; }
}
@media (max-height: 520px) {
  /* Téléphone en paysage : la pochette est rétrécie par la hauteur, la carte
     se resserre (photo plus petite, sans la note) pour rester lisible. */
  .contact-photo { width: 64px; height: 64px; }
  .contact-name { font-size: clamp(16px, 5.5cqw, 20px); }
  .contact-title { margin: 0 0 4px; }
  .contact-email,
  .contact-phone { font-size: 13px; line-height: 1.35; }
  .contact-note { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .contact-overlay.in .contact-swing,
  .contact-overlay.in .contact-chain { animation: none; }
  .contact-overlay,
  .contact-backdrop { transition: none; }
}

/* ============ About ============ */
.about-root {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--chrome-h) 24px 60px;
}
.about-placeholder {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 13px;
  letter-spacing: 0.18em;
  color: var(--muted);
  text-transform: uppercase;
  animation: pulse 2.4s ease-in-out infinite;
}

/* ============ Ajustements téléphone ============
   Placés en fin de feuille : à spécificité égale, ces règles doivent l'emporter
   sur les définitions de base déclarées plus haut. */
@media (max-width: 860px) {
  /* Un mot par ligne, une fois et demie plus grand. */
  .home-title { font-size: min(22.5vw, 220px); }
  .home-title br { display: none; }
  .home-title .line { display: block; }
  .home-title .word {
    display: block;
    width: fit-content;
    margin: 0 auto;
  }
  .home-title .letter.space { display: none; }
  .home-center { padding: 0 16px; }

  /* Étiquettes d'intercalaire plus compactes : elles sont rétrécies par le JS
     sur écran étroit, le texte doit suivre. */
  .divider-tab { font-size: 15px; letter-spacing: 0.04em; padding: 0 8px; }

  /* Étiquette de rôle une fois et demie plus petite. */
  .player-role {
    font-size: clamp(16px, 2.8vh, 34px);
    padding: 10px 24px 13px;
  }

  /* Croix de fermeture à la taille d'un doigt (44 px), un peu plus près du coin. */
  .divider-close {
    top: 8px; right: 8px;
    width: 44px; height: 44px;
    font-size: 18px;
  }
}
