/* =========================================================
   HLprodz — Portfolio
   Reproduction du site Framer en HTML / CSS / JS natif
   Styles communs : système, header, menu, boutons, timelines,
   footer, modale, effets.
   ========================================================= */

/* Inter Display (police du site Framer, licence OFL) hébergée localement */
@font-face { font-family: "Inter Display"; src: url("../assets/fonts/inter-display-500.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Inter Display"; src: url("../assets/fonts/inter-display-500-ext.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Inter Display"; src: url("../assets/fonts/inter-display-600.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Inter Display"; src: url("../assets/fonts/inter-display-600-ext.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Inter Display"; src: url("../assets/fonts/inter-display-700.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Inter Display"; src: url("../assets/fonts/inter-display-700-ext.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
/* Titres, texte secondaire et logo : hébergés en local (aucun appel à Google Fonts, RGPD) */
@font-face { font-family: "TASA Orbiter"; src: url("../assets/fonts/tasa-orbiter.woff2") format("woff2"); font-weight: 600 700; font-style: normal; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "TASA Orbiter"; src: url("../assets/fonts/tasa-orbiter-ext.woff2") format("woff2"); font-weight: 600 700; font-style: normal; font-display: swap; unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Poppins"; src: url("../assets/fonts/poppins-400.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Poppins"; src: url("../assets/fonts/poppins-400-ext.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Montserrat"; src: url("../assets/fonts/montserrat-900.woff2") format("woff2"); font-weight: 900; font-style: normal; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

:root {
  /* Charte « GTA VI » (mesurée sur le logo officiel, validée par Hippo le 7 octobre 2026) */
  --c1: #1E5ECB; --c2: #4F46BA; --c3: #8845BE; --c4: #C63FBF; --c5: #FE7592; --c6: #FE8884; --c7: #FF9152;
  --night: #2B0254;           /* fond profond, contours */
  --gold: #F0A000;            /* liseré doré */
  --accent: #C63FBF;          /* secours uni, seulement là où un dégradé est impossible (les petits éléments sont en --gta, choix de Hippo) */
  /* Règle de Hippo : aucun dégradé vertical ou horizontal, uniquement diagonal (115°) ou radial. */
  /* dégradé pur en diagonale : contours et décor fin sans texte (contour des boutons, faisceaux, pellicule) */
  --gta: linear-gradient(115deg, var(--c1) 0%, var(--c2) 16%, var(--c3) 33%, var(--c4) 50%, var(--c5) 67%, var(--c6) 83%, var(--c7) 100%);
  --gta-diag: var(--gta);
  /* dégradé du texte, relevé à la pipette par Hippo : grand texte de l'accueil, mots clés des titres, + et % des chiffres (≥ 3,5:1 sur noir, AA grand texte),
     tête de lecture des timelines, triangle « Showreel 2026 ». Deux familles seulement : --gta (décor fin) et --gta-pick (texte), plus --brand pour les remplissages. */
  --gta-pick: linear-gradient(115deg, #7C47BE, #FD7C93);
  /* texte en dégradé, petit texte (liens au survol) : portion lisible de --gta-pick, depuis 40 % (#B05CAD, 4,98:1 sur noir, AA) */
  --gta-text: linear-gradient(115deg, #B05CAD, #FD7C93);
  /* lueur radiale depuis le coin bas gauche (choix de Hippo) : remplissages (sous voile, --brand) */
  --gta-radial: radial-gradient(150% 170% at 0% 100%, var(--c7) 0%, var(--c5) 25%, var(--c4) 50%, var(--c3) 75%, var(--c2) 100%);
  /* remplissages qui portent du texte blanc : la lueur radiale sous un voile violet nuit à 40 %.
     Contraste du blanc ≥ 4,97:1 sur chaque couleur de la charte (AA) ; sans voile, il tombe à 2,2:1 sur le rose et l'orange. */
  --brand: radial-gradient(rgba(43, 2, 84, .4), rgba(43, 2, 84, .4)), var(--gta-radial);
  --brand-diag: var(--brand);
  --grain: url("../assets/tex/grain.png") 0 0 / 256px 256px repeat;
  /* rythme vertical : écart unique entre deux sections (avant et après une timeline, avant la bande CTA) ; réduit en mobile */
  --sp: calc(100 * var(--u));
  /* mots clés en couleur (titres, comme le Framer) : même dégradé que le grand texte de l'accueil */
  --brand-text: var(--gta-pick);
  --bg: #000;
  --bg-1: #0d0d0d;
  --bg-2: #191919;
  --bg-3: #1b1c1c;
  --w05: rgba(255, 255, 255, .05);
  --w10: rgba(255, 255, 255, .10);
  --w15: rgba(255, 255, 255, .15);
  --w20: rgba(255, 255, 255, .20);
  --w50: rgba(255, 255, 255, .50);
  /* unité de mesure : 1 px jusqu'à 1440 px de large ; au-delà, tout le site grandit en proportion (choix de Hippo, 9 octobre 2026) */
  --u: 1px;
  --m: calc(50 * var(--u));                  /* marge latérale */
  --sbw: 0px;                 /* largeur de la barre de défilement */
  --vw: calc(100vw - var(--sbw));
  --col: calc((var(--vw) - var(--m) * 2) / 4);
  --f-title: "TASA Orbiter", "Inter", sans-serif;
  --f-text: "Inter Display", "Inter", sans-serif;
  --f-mono: "Poppins", sans-serif;
  --ease: cubic-bezier(.22, 1, .36, 1);
  --spring: cubic-bezier(.2, .9, .25, 1);
}

@media (min-width: 1441px) { :root { --u: calc(100vw / 1440); } }

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* scrollbar-gutter : la place de la barre de défilement reste réservée quand le menu bloque le défilement, sinon header et page glissent vers la droite */
html { -webkit-text-size-adjust: 100%; background: #000; overflow-x: clip; scrollbar-gutter: stable; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }
body {
  background: #000;
  color: #fff;
  font-family: var(--f-text);
  font-weight: 500;
  font-size: calc(15 * var(--u));
  line-height: 1.1;
  letter-spacing: calc(-.3 * var(--u));
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
a { color: inherit; text-decoration: none; }
img, video, canvas { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; background: none; border: 0; outline: 0; letter-spacing: inherit; border-radius: 0; }
button { cursor: pointer; }
ul { list-style: none; }
::selection { background: var(--c3); color: #fff; }   /* les dégradés n'y sont pas pris en charge : violet uni, blanc = 5,77:1 */

/* La page défile par-dessus le footer fixe (effet rideau) : fond noir comme le template Framer */
main { position: relative; z-index: 2; background: #000; }

/* Grain fixe plein écran, par-dessus tout (couche « Noise » du Framer, jamais animée) */
.grain { position: fixed; inset: 0; z-index: 140; pointer-events: none; background: var(--grain); opacity: .08; mix-blend-mode: screen; }

/* ---------- Transition de page (reproduite du Framer : balayage de bas en haut + glissement de 20 % + fondu, 1 s) ----------
   View Transitions entre documents : le navigateur garde l'ancienne page à l'écran pendant que la nouvelle se charge.
   Navigateurs sans support (Firefox) : changement de page instantané. */
@view-transition { navigation: auto; }
@property --wipe { syntax: "<number>"; initial-value: 0; inherits: false; }
@keyframes vt-exit { from { opacity: 1; transform: none; --wipe: 0; } to { opacity: 0; transform: translateY(-20%); --wipe: 1; } }
@keyframes vt-enter { from { opacity: 0; transform: translateY(20%); --wipe: 0; } to { opacity: 1; transform: none; --wipe: 1; } }
::view-transition-old(root), ::view-transition-new(root) { mix-blend-mode: normal; backface-visibility: hidden; animation-duration: 1s; animation-fill-mode: both; }
::view-transition-old(root) {
  animation-name: vt-exit; animation-timing-function: cubic-bezier(1, .02, .51, 1);
  -webkit-mask-image: linear-gradient(0deg, transparent calc(100% * var(--wipe)), #000 calc(100% * var(--wipe)));
  mask-image: linear-gradient(0deg, transparent calc(100% * var(--wipe)), #000 calc(100% * var(--wipe)));
}
::view-transition-new(root) {
  animation-name: vt-enter; animation-timing-function: cubic-bezier(.99, .02, .51, 1);
  -webkit-mask-image: linear-gradient(0deg, #000 calc(100% * var(--wipe)), transparent calc(100% * var(--wipe)));
  mask-image: linear-gradient(0deg, #000 calc(100% * var(--wipe)), transparent calc(100% * var(--wipe)));
}

/* ---------- Typo ---------- */
.up { text-transform: uppercase; }
.sr { position: absolute; width: calc(1 * var(--u)); height: calc(1 * var(--u)); overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.t-body { font-size: calc(15 * var(--u)); line-height: 1.3; letter-spacing: calc(-.3 * var(--u)); text-transform: uppercase; }
.t-text { font-size: calc(15 * var(--u)); line-height: 1.1; letter-spacing: calc(-.3 * var(--u)); }
.t-mono { font-family: var(--f-mono); font-weight: 400; font-size: calc(12 * var(--u)); line-height: 1; letter-spacing: calc(.6 * var(--u)); text-transform: uppercase; }
.t-mono-s { font-family: var(--f-mono); font-weight: 400; font-size: calc(10 * var(--u)); line-height: 1; letter-spacing: calc(.5 * var(--u)); text-transform: uppercase; }
.h-80 { font-family: var(--f-title); font-weight: 600; font-size: calc(80 * var(--u)); line-height: .8; letter-spacing: calc(-4 * var(--u)); text-transform: uppercase; }
.h-60 { font-family: var(--f-title); font-weight: 600; font-size: calc(60 * var(--u)); line-height: .9; letter-spacing: calc(-3 * var(--u)); text-transform: uppercase; }
.h-50 { font-family: var(--f-title); font-weight: 600; font-size: calc(50 * var(--u)); line-height: .9; letter-spacing: calc(-2.3 * var(--u)); }
.h-40 { font-family: var(--f-title); font-weight: 600; font-size: calc(40 * var(--u)); line-height: 1; letter-spacing: calc(-2 * var(--u)); text-transform: uppercase; }
.h-30 { font-family: var(--f-title); font-weight: 700; font-size: calc(30 * var(--u)); line-height: 1; letter-spacing: calc(-.6 * var(--u)); text-transform: uppercase; }
.h-22 { font-family: var(--f-title); font-weight: 600; font-size: calc(22 * var(--u)); line-height: 1.1; letter-spacing: calc(-.4 * var(--u)); text-transform: uppercase; }
.h-20 { font-family: var(--f-title); font-weight: 600; font-size: calc(20 * var(--u)); line-height: 1.1; letter-spacing: calc(-.4 * var(--u)); text-transform: uppercase; }
/* Titres de section : blanc pâle (consigne de Hippo, pas tape-à-l'œil), 13,1:1 sur le noir. */
main :is(h1, h2):is(.h-80, .h-60, .h-50):not(.bh-title) { color: rgba(255, 255, 255, .8); }
.c-purple, .c-purple .ch { background: var(--brand-text); -webkit-background-clip: text; background-clip: text; color: transparent; }
.c-purple:has(.ch) { background: none; }   /* titre découpé lettre par lettre : le dégradé passe sur chaque lettre */
/* l'espacement négatif des titres rétrécit la boîte du mot : la fin de la dernière lettre sortait du dégradé (lettre coupée).
   Marge intérieure compensée par une marge négative : le dégradé couvre toute la lettre, la mise en page ne bouge pas. */
.c-purple, .c-purple .ch { padding: 0 .12em; margin: 0 -.12em; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.c-purple:has(.ch) { padding: 0; margin: 0; }
.c-dim { color: var(--w50); }

/* ---------- Grille 4 colonnes ---------- */
.g4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); padding: 0 var(--m); }
.c1 { grid-column: 1 / 2; } .c2 { grid-column: 2 / 3; } .c3 { grid-column: 3 / 4; } .c4 { grid-column: 4 / 5; }
.c12 { grid-column: 1 / 3; } .c23 { grid-column: 2 / 4; } .c34 { grid-column: 3 / 5; }
.c24 { grid-column: 2 / 5; } .c13 { grid-column: 1 / 4; } .c14 { grid-column: 1 / 5; }
.pad { padding-left: calc(20 * var(--u)); padding-right: calc(20 * var(--u)); }

/* lignes verticales de la grille (5 en desktop, 3 tablette, 2 mobile) */
.gridlines {
  position: fixed; inset: 0; z-index: 3; pointer-events: none;
  display: grid; grid-template-columns: repeat(4, 1fr); padding: 0 var(--m);
}
.gridlines i { border-left: calc(1 * var(--u)) solid var(--w10); }
.gridlines i:first-child { border-left-color: var(--w15); }
.gridlines i:last-child { border-right: calc(1 * var(--u)) solid var(--w15); }


/* ---------- Cases grises (à remplacer) ---------- */
.ph {
  position: relative; overflow: hidden; width: 100%; height: 100%;
  background-color: #1c1c1c;
  background-image: repeating-linear-gradient(135deg, rgba(255,255,255,.028) 0 calc(12 * var(--u)), transparent calc(12 * var(--u)) calc(24 * var(--u)));
}
.ph::after {
  content: attr(data-ph);
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  font-family: var(--f-mono); font-size: calc(10 * var(--u)); letter-spacing: calc(.6 * var(--u)); text-transform: uppercase; line-height: 1.3;
  color: rgba(255,255,255,.3); text-align: center; max-width: 86%;
  padding: calc(6 * var(--u)) calc(10 * var(--u)); border: calc(1 * var(--u)) dashed rgba(255,255,255,.14);
}
.ph.no-label::after, .ph[data-ph=""]::after { display: none; }
.media { position: relative; overflow: hidden; background: #1c1c1c; }
.media > img, .media > video { width: 100%; height: 100%; object-fit: cover; }

/* ---------- Loader ---------- */
/* Ouverture du site (première page de la visite uniquement), façon dreamotion-production.com :
   logo + point qui clignote, capsule de chargement (contour en dégradé, liseré noir, remplissage qui se dévoile),
   puis le rideau remonte avec le balayage de la transition Framer et dévoile la page. */
.loader {
  position: fixed; inset: 0; z-index: 300; background: #000;
  display: grid; place-items: center; align-content: center; gap: calc(12 * var(--u));
  clip-path: inset(0 0 0 0); transition: clip-path 1s cubic-bezier(1, .02, .51, 1), visibility 0s 1s;
}
.loader::after { content: ""; position: absolute; inset: 0; background: var(--grain); opacity: .1; mix-blend-mode: screen; pointer-events: none; }
.ld-mask { overflow: hidden; padding: calc(4 * var(--u)) calc(14 * var(--u)); }
.ld-logo { position: relative; transform: translateY(110%); animation: ld-in 1s var(--ease) .25s forwards; }
.ld-logo svg { width: calc(170 * var(--u)); height: auto; }
/* le bas du rond est posé sur la ligne de base des lettres du logo (14,3 unités au-dessus du bas du bloc) */
.ld-dot { position: absolute; right: calc(-11 * var(--u)); bottom: calc(14.3 * var(--u)); width: calc(8 * var(--u)); height: calc(8 * var(--u)); border-radius: 50%; background: var(--gta); animation: ld-blink .5s ease-in-out infinite alternate; }
.ld-bar { position: relative; width: calc(221 * var(--u)); height: calc(20 * var(--u)); border-radius: calc(999 * var(--u)); background: var(--gta); transform: translateY(-110%); animation: ld-in 1s var(--ease) .25s forwards; }
.ld-bar::before { content: ""; position: absolute; inset: calc(1 * var(--u)); border-radius: inherit; background: #000; }
/* remplissage : la capsule glisse dans la piste, le dégradé glisse en sens inverse et reste fixe (transform uniquement) */
.ld-track { position: absolute; inset: calc(2 * var(--u)); border-radius: inherit; overflow: hidden; }
.ld-fill { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; transform: translateX(-100%); }
.ld-fill i { position: absolute; inset: 0; background: var(--gta); transform: translateX(100%); }
@keyframes ld-in { to { transform: none; } }
@keyframes ld-blink { from { opacity: 1; } to { opacity: .2; } }
.loader.done { clip-path: inset(0 0 100% 0); visibility: hidden; }
.loader.skip { display: none; }

/* ---------- Header (barre 600 × 48) ---------- */
.hdr-wrap { position: fixed; top: calc(10 * var(--u)); left: 50%; transform: translateX(-50%); width: calc(600 * var(--u)); max-width: calc(100vw - calc(20 * var(--u))); z-index: 120; pointer-events: none; }
/* seul l'en-tête capte la souris ; le panneau (invisible quand le menu est fermé) laisse passer survols et clics */
.hdr { pointer-events: auto; }
.hdr {
  position: relative; height: calc(48 * var(--u)); display: flex; align-items: center; justify-content: space-between;
  padding: calc(4 * var(--u)) calc(20 * var(--u)); background: var(--bg-1); backdrop-filter: blur(calc(5 * var(--u))); -webkit-backdrop-filter: blur(calc(5 * var(--u)));
  transition: background .6s var(--ease);
}
.menu-open .hdr { background: var(--brand); }
.logo-s { display: flex; align-items: center; height: calc(32 * var(--u)); }
.logo-s svg { height: calc(15 * var(--u)); width: auto; display: block; }
.hdr-btn { display: flex; align-items: center; gap: calc(12 * var(--u)); height: calc(40 * var(--u)); font-size: calc(15 * var(--u)); }
.roll { position: relative; height: calc(17 * var(--u)); overflow: hidden; display: inline-block; }
.roll span { display: block; height: calc(17 * var(--u)); line-height: calc(17 * var(--u)); transition: transform .6s var(--ease); text-align: right; }
.menu-open .roll span { transform: translateY(-100%); }
/* icône : grille 3 × 3 de pixels (croix blanche, coins à 20 %) → X */
.mic { position: relative; width: calc(20 * var(--u)); height: calc(20 * var(--u)); }
.mic i { position: absolute; left: calc(8 * var(--u)); top: calc(8 * var(--u)); width: calc(4 * var(--u)); height: calc(4 * var(--u)); background: #fff; transition: transform .4s cubic-bezier(1, .05, .72, 1), width .4s cubic-bezier(1, .05, .72, 1), height .4s cubic-bezier(1, .05, .72, 1), left .4s cubic-bezier(1, .05, .72, 1), top .4s cubic-bezier(1, .05, .72, 1), opacity .4s cubic-bezier(1, .05, .72, 1); }
.mic i:nth-child(1) { transform: translate(0, calc(-8 * var(--u))); }
.mic i:nth-child(2) { transform: translate(calc(-8 * var(--u)), 0); }
.mic i:nth-child(3) { transform: translate(calc(8 * var(--u)), 0); }
.mic i:nth-child(4) { transform: translate(0, calc(8 * var(--u))); }
.mic i:nth-child(n+6) { opacity: .2; }
.mic i:nth-child(6) { transform: translate(calc(-8 * var(--u)), calc(-8 * var(--u))); }
.mic i:nth-child(7) { transform: translate(calc(8 * var(--u)), calc(-8 * var(--u))); }
.mic i:nth-child(8) { transform: translate(calc(-8 * var(--u)), calc(8 * var(--u))); }
.mic i:nth-child(9) { transform: translate(calc(8 * var(--u)), calc(8 * var(--u))); }
/* menu ouvert : X, sans effet au survol */
.menu-open .mic i:nth-child(-n+5) { left: 0; top: calc(8.5 * var(--u)); width: calc(20 * var(--u)); height: calc(3 * var(--u)); }
.menu-open .mic i:nth-child(-n+5):nth-child(odd) { transform: rotate(45deg); }
.menu-open .mic i:nth-child(-n+5):nth-child(even) { transform: rotate(-45deg); }
.menu-open .mic i:nth-child(n+6) { opacity: 0; transform: none; }

/* panneau du menu */
.menu-panel { display: grid; gap: calc(4 * var(--u)); margin-top: calc(4 * var(--u)); pointer-events: none; }
.menu-open .menu-panel { pointer-events: auto; }
.menu-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: calc(4 * var(--u)); }
.mtile {
  position: relative; height: calc(110 * var(--u)); display: flex; align-items: flex-end; justify-content: space-between;
  padding: calc(20 * var(--u)) calc(20 * var(--u)) calc(22 * var(--u)); background: var(--bg-2); overflow: hidden;
  transition: background .5s var(--ease);
}
.mtile .t-mono-s { position: relative; z-index: 2; color: var(--w50); transition: color .3s; }
.mtile:hover { background: var(--brand); }
.mtile .lbl { position: relative; z-index: 2; text-transform: uppercase; text-align: right; line-height: 1.2; transition: color .3s; }
.mtile:hover .lbl, .mtile:hover .t-mono-s { color: #fff; }
.mcard { position: relative; background: var(--bg-2); padding: calc(34 * var(--u)) calc(20 * var(--u)) calc(30 * var(--u)); overflow: hidden; display: block; transition: background .5s var(--ease); }
.mcard:hover { background: var(--brand); }
.mcard .email { display: flex; align-items: center; gap: calc(16 * var(--u)); position: relative; z-index: 2; }
.mcard .copy { position: relative; width: calc(24 * var(--u)); height: calc(24 * var(--u)); flex: none; }
.mcard .copy i { position: absolute; width: calc(9 * var(--u)); height: calc(10 * var(--u)); background: #fff; }
.mcard .copy i:first-child { left: calc(5 * var(--u)); top: calc(9 * var(--u)); }
.mcard .copy i:last-child { left: calc(9 * var(--u)); top: calc(5 * var(--u)); opacity: .55; }
.mcard .meta { margin-top: calc(14 * var(--u)); display: grid; gap: calc(6 * var(--u)); position: relative; z-index: 2; text-transform: uppercase; font-size: calc(12 * var(--u)); }

.copied { position: absolute; right: calc(20 * var(--u)); top: calc(20 * var(--u)); z-index: 3; padding: calc(4 * var(--u)) calc(8 * var(--u)); background: #000; opacity: 0; transform: scale(.7); transition: opacity .3s, transform .5s var(--spring); }
.copied.show { opacity: 1; transform: none; }
.menu-socials { display: grid; grid-template-columns: repeat(6, 1fr); gap: calc(4 * var(--u)); }
.msoc { position: relative; height: calc(60 * var(--u)); background: var(--bg-2); display: grid; place-items: center; overflow: hidden; transition: background .5s var(--ease); }
.msoc:hover { background: var(--brand); }
.msoc svg { width: calc(18 * var(--u)); height: calc(18 * var(--u)); position: relative; z-index: 2; }
/* apparition en « blocs » */
.menu-panel .mi { opacity: 0; clip-path: inset(0 0 100% 0); transition: opacity .2s steps(2), clip-path .45s steps(4); }
.menu-open .menu-panel .mi { opacity: 1; clip-path: inset(0 0 0 0); }
.menu-veil {
  position: fixed; inset: 0; z-index: 110; background: rgba(0,0,0,.45);
  backdrop-filter: blur(calc(12 * var(--u))); -webkit-backdrop-filter: blur(calc(12 * var(--u)));
  opacity: 0; visibility: hidden; transition: opacity .6s var(--ease), visibility .6s;
}
.menu-open .menu-veil { opacity: 1; visibility: visible; }

/* ---------- Pixel Trail (traînée de carrés de 30 px) ---------- */
.ptrail { position: absolute; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.ptrail b { position: absolute; width: 30px; height: 30px; background: #fff; opacity: .85; animation: pxfade 1s .05s cubic-bezier(.3, 0, .2, 1) forwards; }
@keyframes pxfade { 0% { opacity: .85; background: #fff; } 40% { background: #cfcfcf; } 100% { opacity: 0; background: #9a9a9a; } }
.brk { position: absolute; inset: calc(6 * var(--u)); z-index: 3; pointer-events: none; opacity: 0; transition: opacity .25s; }
.brk::before, .brk::after, .brk b::before, .brk b::after { content: ""; position: absolute; width: calc(8 * var(--u)); height: calc(8 * var(--u)); border-color: #fff; border-style: solid; }
.brk::before { left: 0; top: 0; border-width: calc(1 * var(--u)) 0 0 calc(1 * var(--u)); } .brk::after { right: 0; top: 0; border-width: calc(1 * var(--u)) calc(1 * var(--u)) 0 0; }
.brk b::before { left: 0; bottom: 0; border-width: 0 0 calc(1 * var(--u)) calc(1 * var(--u)); } .brk b::after { right: 0; bottom: 0; border-width: 0 calc(1 * var(--u)) calc(1 * var(--u)) 0; }
.has-px:hover > .brk { opacity: 1; }

/* ---------- Bouton principal (331 × 44) ----------
   Survol : une seule transition de A vers B (le libellé roule vers le haut, l'icône glisse), retour à A à la sortie.
   Deux styles (G2), réglés par la classe du <html> : « btn-fill » (A) ou « btn-line » (B, choisi par Hippo, dégradé diagonal). */
.btn {
  position: relative; display: flex; align-items: center; justify-content: center; gap: calc(10 * var(--u));
  height: calc(44 * var(--u)); width: 100%; color: #fff; text-transform: uppercase;
  font-size: calc(15 * var(--u)); letter-spacing: calc(-.3 * var(--u)); overflow: hidden; isolation: isolate;
}
.btn .bg { position: absolute; inset: 0; z-index: 0; background: var(--brand); transition: transform .6s var(--spring), opacity .4s; }
.btn .bg::after { content: ""; position: absolute; inset: 0; background: rgba(43, 2, 84, .45); opacity: 0; transition: opacity .45s var(--spring); }
.btn:hover .bg::after, .btn:focus-visible .bg::after { opacity: 1; }
.btn .ic { position: relative; z-index: 1; width: calc(19 * var(--u)); height: calc(19 * var(--u)); flex: none; overflow: hidden; }
.btn .ic svg { width: 100%; height: 100%; display: block; transition: transform .5s var(--spring); }
.btn:hover .ic svg { transform: translateX(calc(3 * var(--u))); }
.btn .lb { position: relative; z-index: 1; display: block; height: calc(18 * var(--u)); line-height: calc(18 * var(--u)); overflow: hidden; white-space: nowrap; }
.btn .lb span { display: block; transition: transform .55s var(--spring); }
.btn:hover .lb span, .btn:focus-visible .lb span { transform: translateY(-100%); }
.btn:focus-visible { outline: calc(2 * var(--u)) solid var(--c5); outline-offset: calc(3 * var(--u)); }
/* B : contour en dégradé (1,5 px), fond transparent ; le dégradé remplit le bouton par le bas au survol */
.btn-line .btn::before {
  content: ""; position: absolute; inset: 0; z-index: 2; padding: calc(1.5 * var(--u)); background: var(--gta-diag); pointer-events: none;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
.btn-line .btn .bg { transform: translateY(101%); background: var(--brand-diag); }
.btn-line .btn .bg::after { display: none; }
.btn-line .btn:hover .bg, .btn-line .btn:focus-visible .bg { transform: none; }

/* ---------- Bouton glitch du Framer (Accueil, À propos) ----------
   Copie du composant framer-glitch-effect (mêmes valeurs), aux couleurs du site : fond radial sous voile, sans contour,
   4 coins à 14 % de la hauteur en noir 40 %. Au survol le glitch se joue une seule fois (choix de Hippo), puis le
   voile noir 40 % reste jusqu'à la sortie. */
.btn-fx { --gc: .88s; --sx: calc(10 * var(--u)); --sy: calc(20 * var(--u)); --sr: 10; --sa: 100%; --sb: 100%; --sc: 100%; --sd: 100%; isolation: isolate; }
.btn-line .btn-fx::before { display: none; }
.btn-fx .bg, .btn-line .btn-fx .bg { position: absolute; inset: 0; z-index: 0; transform: none; background: var(--brand); }
.btn-fx .shade { position: absolute; inset: 0; z-index: 0; background: rgba(0, 0, 0, .4); opacity: 0; transition: opacity .25s var(--ease); }
.cn { position: absolute; z-index: 1; width: var(--cn, calc(6 * var(--u))); height: var(--cn, calc(6 * var(--u))); background: rgba(0, 0, 0, .4); pointer-events: none; }
.cn:nth-of-type(1) { left: 0; top: 0; } .cn:nth-of-type(2) { right: 0; top: 0; } .cn:nth-of-type(3) { left: 0; bottom: 0; } .cn:nth-of-type(4) { right: 0; bottom: 0; }
.btn-fx .gl { display: flex; align-items: center; justify-content: center; gap: calc(10 * var(--u)); pointer-events: none; }
.btn-fx .gl-base { position: relative; z-index: 2; }
.btn-fx .gl:not(.gl-base) { position: absolute; inset: 0; z-index: 2; opacity: 0; transform: translate3d(0, 0, 0); }
.btn-fx .lb2 { display: block; height: calc(18 * var(--u)); line-height: calc(18 * var(--u)); white-space: nowrap; }
.btn-fx .ic { position: relative; width: calc(19 * var(--u)); height: calc(19 * var(--u)); flex: none; }
.btn-fx .ic svg, .btn-fx:hover .ic svg { width: 100%; height: 100%; display: block; transform: none; }
:is(.btn-fx:hover, .btn-fx:focus-visible, .cta-home:hover, .cta-home:focus-visible) .shade { opacity: 1; }
:is(.btn-fx:hover, .btn-fx:focus-visible, .cta-home:hover, .cta-home:focus-visible) .gl-red {
  opacity: .72; mix-blend-mode: screen; filter: saturate(180%) hue-rotate(-35deg) drop-shadow(calc(2 * var(--u)) 0 rgba(255, 0, 64, .95));
  animation: glRed var(--gc) steps(2, end) 1 both;
}
:is(.btn-fx:hover, .btn-fx:focus-visible, .cta-home:hover, .cta-home:focus-visible) .gl-cyan {
  opacity: .72; mix-blend-mode: screen; filter: saturate(180%) hue-rotate(145deg) drop-shadow(calc(-2 * var(--u)) 0 rgba(0, 255, 255, .95));
  animation: glCyan var(--gc) steps(2, end) 1 both;
}
:is(.btn-fx:hover, .btn-fx:focus-visible, .cta-home:hover, .cta-home:focus-visible) .gl-slice {
  opacity: .9; mix-blend-mode: lighten; clip-path: inset(var(--sa) 0 calc(100% - var(--sb)) 0);
  animation: glSlice var(--gc) steps(2, end) 1 both;
}
:is(.btn-fx:hover, .btn-fx:focus-visible, .cta-home:hover, .cta-home:focus-visible) .gl-base { animation: glPulse var(--gc) steps(2, end) 1; }
@keyframes glRed {
  0% { transform: translate3d(calc(var(--sx) * -.4), calc(var(--sy) * .18), 0); clip-path: inset(0 0 0 0); }
  8% { transform: translate3d(var(--sx), calc(var(--sy) * -.5), 0); clip-path: inset(var(--sc) 0 calc(100% - var(--sd)) 0); }
  14% { transform: translate3d(calc(var(--sx) * -.75), calc(var(--sy) * .4), 0); clip-path: inset(var(--sa) 0 calc(100% - var(--sb)) 0); }
  22%, 100% { transform: translate3d(0, 0, 0); clip-path: inset(0 0 0 0); }
}
@keyframes glCyan {
  0% { transform: translate3d(calc(var(--sx) * .45), calc(var(--sy) * -.22), 0); clip-path: inset(0 0 0 0); }
  10% { transform: translate3d(calc(var(--sx) * -1), calc(var(--sy) * .35), 0); clip-path: inset(var(--sa) 0 calc(100% - var(--sd)) 0); }
  18% { transform: translate3d(calc(var(--sx) * .8), calc(var(--sy) * -.45), 0); clip-path: inset(var(--sc) 0 calc(100% - var(--sb)) 0); }
  25%, 100% { transform: translate3d(0, 0, 0); clip-path: inset(0 0 0 0); }
}
@keyframes glSlice {
  0% { transform: translate3d(0, 0, 0); clip-path: inset(var(--sa) 0 calc(100% - var(--sb)) 0); }
  9% { transform: translate3d(calc(var(--sx) * .6), 0, 0); clip-path: inset(var(--sc) 0 calc(100% - var(--sd)) 0); }
  17% { transform: translate3d(calc(var(--sx) * -.55), 0, 0); clip-path: inset(var(--sa) 0 calc(100% - var(--sd)) 0); }
  26%, 100% { transform: translate3d(0, 0, 0); clip-path: inset(0 0 0 0); opacity: 0; }
}
@keyframes glPulse {
  0% { transform: translate3d(0, 0, 0) skewX(0deg); filter: none; }
  8% { transform: translate3d(calc(var(--sx) * .14), 0, 0) skewX(calc(var(--sr) * .08deg)); filter: contrast(1.12) saturate(1.08); }
  15% { transform: translate3d(calc(var(--sx) * -.1), 0, 0) skewX(calc(var(--sr) * -.06deg)); filter: contrast(1.2) saturate(1.14); }
  24%, 100% { transform: translate3d(0, 0, 0) skewX(0deg); filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .clap .arm, .clap.fx { animation: none !important; transition: none; }
  .btn-fx .gl, .ch-t .gl { animation: none !important; }
  :is(.btn-fx:hover, .btn-fx:focus-visible, .cta-home:hover, .cta-home:focus-visible) .gl-red { opacity: .35; transform: translate3d(calc(1 * var(--u)), 0, 0); }
  :is(.btn-fx:hover, .btn-fx:focus-visible, .cta-home:hover, .cta-home:focus-visible) .gl-cyan { opacity: .35; transform: translate3d(calc(-1 * var(--u)), 0, 0); }
}


/* étiquette qui suit la souris (« + VOIR LE PROJET », « ▶ JOUER LA VIDÉO ») */
.cursor-tag {
  --cn: calc(4 * var(--u));
  position: fixed; left: 0; top: 0; z-index: 130; pointer-events: none;
  display: flex; align-items: center; gap: calc(8 * var(--u)); height: calc(26 * var(--u)); padding: 0 calc(12 * var(--u));
  background: var(--brand); color: #fff;
  transform: translate(-50%, -50%) scale(.5); opacity: 0; transition: opacity .25s, transform .5s var(--spring);
}
.cursor-tag.dark { background: #0d0d0d; }
.cursor-tag.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.cursor-tag svg { width: calc(10 * var(--u)); height: calc(10 * var(--u)); }

/* ---------- Timeline (en tête de section) ---------- */
.tl { position: relative; z-index: 6; padding: 0 var(--m); }
.tl-ruler {
  height: calc(18 * var(--u)); background: var(--w15);
  -webkit-mask: url("../assets/tex/ruler-mask.png") repeat-x 0 0 / calc(59.3 * var(--u)) calc(22.1 * var(--u));
  mask: url("../assets/tex/ruler-mask.png") repeat-x 0 0 / calc(59.3 * var(--u)) calc(22.1 * var(--u));
}
.tl-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: calc(16 * var(--u)); height: calc(32 * var(--u)); }
.tl-lab {
  display: flex; align-items: center; justify-content: center; height: calc(32 * var(--u)); margin-right: calc(4 * var(--u));
  background: var(--w15); white-space: nowrap; overflow: hidden; opacity: .3;
}
.tl-lab:last-child { margin-right: 0; }
.tl-lab.on { opacity: 1; }
.tl-head { position: absolute; top: 0; left: 0; width: calc(17 * var(--u)); height: calc(60 * var(--u)); z-index: 3; pointer-events: none; will-change: transform; }
.tl-head::before { content: ""; position: absolute; left: 0; top: 0; width: calc(9 * var(--u)); height: calc(12 * var(--u)); background: var(--gta-pick) 0 0 / calc(9 * var(--u)) calc(60 * var(--u)); clip-path: polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%); }
.tl-head::after { content: ""; position: absolute; left: calc(4 * var(--u)); top: calc(10 * var(--u)); width: calc(1 * var(--u)); height: calc(50 * var(--u)); background: var(--gta-pick) calc(-4 * var(--u)) calc(-10 * var(--u)) / calc(9 * var(--u)) calc(60 * var(--u)); }   /* même dégradé que la tête, d'un seul tenant */

/* ---------- Révélations ---------- */
[data-rv] { opacity: 0; transform: translateY(calc(40 * var(--u))); transition: opacity 1s var(--ease), transform 1s var(--ease); transition-delay: var(--rd, 0s); }
[data-rv="up"] { transform: translateY(calc(200 * var(--u))); transition: opacity .9s var(--spring), transform 1.1s var(--spring); transition-delay: var(--rd, 0s); }
[data-rv="fade"] { transform: none; }
[data-rv].in { opacity: 1; transform: none; }
/* texte lettre par lettre (intro hero) */
.chars .ch { display: inline-block; opacity: 0; transform: translateY(calc(10 * var(--u))); transition: opacity 1s var(--ease), transform 1s var(--ease); }
.chars .wd { display: inline-block; white-space: nowrap; }
.chars.in .ch { opacity: 1; transform: none; }
/* révélation au fil du scroll (Scroll Word Reveal) */
.sreveal .ch { display: inline; }

/* ---------- Sections communes ---------- */
section { position: relative; }
.sec { padding: var(--sp) 0; }
.sec-top { padding-top: var(--sp); }

/* Héros des pages internes : faisceau violet animé */
.beam-hero { position: relative; height: 80vh; min-height: calc(620 * var(--u)); overflow: hidden; }
.beam { position: absolute; inset: 0; overflow: hidden; }
.beam canvas { position: absolute; inset: 0; width: 100%; height: 100%; }   /* shader du héros Contact Framer (initShaders) */
.bh-title {
  /* aligné à gauche sur la première colonne de la grille (demande de Hippo, 9 octobre 2026) */
  position: absolute; left: var(--m); width: min(calc(676 * var(--u)), calc(var(--vw) - var(--m) * 2));
  text-align: left; z-index: 2;
  color: rgba(255, 255, 255, .8);   /* blanc pâle comme les autres titres : le mode « différence » du Framer donnait du vert hors charte */
}
.bh-sub { position: absolute; left: calc(var(--m) + var(--col) * 2); width: calc(var(--col) - calc(20 * var(--u))); z-index: 2; }

/* ---------- Bande CTA (avant le footer, toutes les pages) ----------
   Fond : nuit profonde + lueur du dégradé. Pellicule 35 mm : perforations régulières découpées (masque SVG),
   cadres séparés par des inter-images, défilement continu en transform. Bouton au centre. */
/* --gap : même écart au-dessus et au-dessous de la pellicule. Pas de bouton : au survol, l'étiquette du curseur (data-cursor) porte le libellé */
.cta-band { --fh: calc(176 * var(--u)); --gap: calc(48 * var(--u)); position: relative; display: block; height: calc(var(--fh) + 2 * var(--gap)); overflow: hidden; isolation: isolate; }
/* neige de téléviseur (fond « CRT » du Framer) : toute la largeur de la bande, devant le noir du site, derrière la pellicule et le bouton */
.cta-static { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; opacity: .55; filter: blur(calc(.4 * var(--u))); }
/* bande lumineuse derrière la pellicule : elle éclaire les perforations, comme un film sur une table lumineuse */
.film-glow, .film { position: absolute; left: 0; right: 0; top: var(--gap); height: var(--fh); }
/* la lueur est rentrée de 1 unité en haut et en bas : selon la position de la bande dans la page (hauteurs à virgule),
   le masque de la pellicule laissait passer un liseré clair d'un pixel sur son bord */
.film-glow { top: calc(var(--gap) + calc(1 * var(--u))); height: calc(var(--fh) - calc(2 * var(--u))); z-index: 1; background: linear-gradient(115deg, var(--c1), var(--c3), var(--c4), var(--c5), var(--c7), var(--c4), var(--c1)); }
.film {
  z-index: 2; background: #0b0b0b;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='176'%3E%3Cpath fill-rule='evenodd' d='M0 0h24v176H0z M6 8h12v12H6z M6 156h12v12H6z'/%3E%3C/svg%3E") 0 0 / calc(24 * var(--u)) 100% repeat-x;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='176'%3E%3Cpath fill-rule='evenodd' d='M0 0h24v176H0z M6 8h12v12H6z M6 156h12v12H6z'/%3E%3C/svg%3E") 0 0 / calc(24 * var(--u)) 100% repeat-x;
}
.film-track { position: absolute; left: 0; top: calc(28 * var(--u)); bottom: calc(28 * var(--u)); display: flex; gap: calc(8 * var(--u)); width: max-content; animation: marq 40s linear infinite; will-change: transform; }
.cta-band:hover .film-track { animation-duration: 20s; }
.film-track .fr { flex: none; height: 100%; display: grid; place-items: center; overflow: hidden; background: #151515; }
.film-track .fr img { width: 100%; height: 100%; object-fit: cover; filter: saturate(.85) brightness(.75); }
.film-track .fr.ph-img { width: calc(214 * var(--u)); }
.film-track .fr.tx { padding: 0 calc(34 * var(--u)); background: var(--brand-diag); font-family: var(--f-title); font-weight: 600; font-size: calc(64 * var(--u)); letter-spacing: calc(-3 * var(--u)); line-height: 1; text-transform: uppercase; white-space: nowrap; }
@keyframes marq { to { transform: translate3d(-50%, 0, 0); } }
/* libellé fixe de la bande, pour les écrans tactiles seulement (affiché dans pages.css) : même étiquette que celle du curseur */
.cta-tag { display: none; position: absolute; left: 50%; top: 50%; z-index: 3; transform: translate(-50%, -50%); align-items: center; height: calc(30 * var(--u)); padding: 0 calc(14 * var(--u)); background: var(--brand); color: #fff; white-space: nowrap; }
.cta-band:focus-visible { outline: calc(2 * var(--u)) solid var(--c5); outline-offset: calc(-4 * var(--u)); }
/* Page Contact : « clap de fin » à la place de la pellicule (retour à l'accueil). Clap en CSS, mesures en --cu pour le réduire en mobile.
   Le bras est ouvert au repos, claque une fois quand la bande arrive à l'écran (.clap-in, js/main.js) et se referme au survol. */
.ch-in { position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; justify-content: center; gap: calc(44 * var(--u)); padding: 0 var(--m); }
.clap { --cu: var(--u); --stripes: repeating-linear-gradient(115deg, transparent 0 calc(13 * var(--cu)), #0b0b0b calc(13 * var(--cu)) calc(26 * var(--cu))), var(--gta); position: relative; flex: none; width: calc(156 * var(--cu)); height: calc(130 * var(--cu)); }
/* ardoise : bras articulé et barre fixe rayés dans le dégradé de la charte, charnière, plaque sombre à cases (nom, scène, prise, plan) */
.clap .arm, .clap .bar { position: absolute; left: 0; right: 0; background: var(--stripes); }
.clap .arm { top: calc(8 * var(--cu)); height: calc(18 * var(--cu)); transform-origin: calc(4 * var(--cu)) 100%; transform: rotate(-15deg); transition: transform .14s cubic-bezier(.7, 0, 1, .6); }
.clap .bar { top: calc(28 * var(--cu)); height: calc(14 * var(--cu)); }
.clap .hinge { position: absolute; z-index: 1; left: calc(3 * var(--cu)); top: calc(23 * var(--cu)); width: calc(8 * var(--cu)); height: calc(8 * var(--cu)); border-radius: 50%; background: #fff; }
.clap .board { position: absolute; left: 0; right: 0; top: calc(42 * var(--cu)); bottom: 0; display: grid; grid-template-rows: 1fr 1.5fr; background: var(--bg-2); border: calc(1 * var(--cu)) solid rgba(255, 255, 255, .22); color: #fff; }
.clap .board b { display: flex; align-items: center; padding: 0 calc(11 * var(--cu)); font-family: var(--f-title); font-weight: 600; font-size: calc(17 * var(--cu)); letter-spacing: calc(-.5 * var(--cu)); line-height: 1; }
.clap .cells { display: grid; grid-template-columns: repeat(3, 1fr); border-top: calc(1 * var(--cu)) solid rgba(255, 255, 255, .22); }
.clap .cells > span { display: flex; flex-direction: column; justify-content: center; gap: calc(7 * var(--cu)); padding: 0 calc(9 * var(--cu)); font-family: var(--f-title); font-weight: 600; font-size: calc(16 * var(--cu)); line-height: 1; }
.clap .cells > span + span { border-left: calc(1 * var(--cu)) solid rgba(255, 255, 255, .22); }
.clap .cells i { font-family: var(--f-mono); font-weight: 400; font-style: normal; font-size: calc(9 * var(--cu)); letter-spacing: calc(.5 * var(--cu)); text-transform: uppercase; color: rgba(255, 255, 255, .65); }
.clap .cells em { font-style: normal; align-self: flex-start; }
.cta-home:hover .arm, .cta-home:focus-visible .arm { transform: none; }
/* secousse et léger glitch du clap (franges rouge et cyan, décalages brefs) quand la souris entre dans la section et que le bras claque : classe .fx posée par js/main.js, retirée à la sortie */
.clap.fx { animation: clapFx .42s linear 1; }   /* sans délai : part en même temps que le glitch du titre */
@keyframes clapFx {
  0%, 100% { transform: none; filter: none; }
  8% { transform: translate(calc(-4 * var(--cu)), calc(1 * var(--cu))) rotate(-1.6deg) skewX(5deg); filter: drop-shadow(calc(3 * var(--cu)) 0 rgba(255, 0, 64, .9)) drop-shadow(calc(-3 * var(--cu)) 0 rgba(0, 255, 255, .9)); }
  16% { transform: translate(calc(3 * var(--cu)), calc(-1 * var(--cu))) rotate(1.2deg) skewX(-4deg); filter: drop-shadow(calc(-2 * var(--cu)) 0 rgba(255, 0, 64, .9)) drop-shadow(calc(2 * var(--cu)) 0 rgba(0, 255, 255, .9)); }
  26% { transform: translate(calc(-2 * var(--cu)), 0) rotate(-.9deg); filter: drop-shadow(calc(1 * var(--cu)) 0 rgba(255, 0, 64, .7)) drop-shadow(calc(-1 * var(--cu)) 0 rgba(0, 255, 255, .7)); }
  40% { transform: translate(calc(2 * var(--cu)), calc(1 * var(--cu))) rotate(.6deg); filter: none; }
  58% { transform: translate(calc(-1 * var(--cu)), 0) rotate(-.3deg); }
  78% { transform: translate(calc(1 * var(--cu)), 0); }
}
.cta-home.clap-in .arm { animation: clapSnap 1.3s .25s 1; }
@keyframes clapSnap { 0%, 100% { transform: rotate(-15deg); } 12%, 24%, 70% { transform: none; } 18% { transform: rotate(-3deg); } }
/* le titre seul est centré dans la bande : la petite ligne « Clap de fin » est posée au-dessus, hors du calcul (demande de Hippo) */
.ch-tx { position: relative; display: flex; flex-direction: column; --lg: calc(14 * var(--u)); min-width: 0; }
.ch-tx .t-mono-s { position: absolute; left: 0; bottom: calc(100% + var(--lg)); white-space: nowrap; font-size: calc(13 * var(--u)); letter-spacing: calc(.8 * var(--u)); color: rgba(255, 255, 255, .85); }
.ch-t { font-family: var(--f-title); font-weight: 600; font-size: calc(64 * var(--u)); line-height: .9; letter-spacing: calc(-3 * var(--u)); text-transform: uppercase; color: rgba(255, 255, 255, .8); }
/* glitch des boutons sur le titre : mêmes couches, mêmes images clés et mêmes règles de survol que .btn-fx (sélecteurs communs plus haut), déclenché au survol de toute la section, comme le bras du clap ; le clap lui-même ne glitche pas */
.ch-t { position: relative; --gc: .88s; --sx: calc(10 * var(--u)); --sy: calc(20 * var(--u)); --sr: 10; --sa: 100%; --sb: 100%; --sc: 100%; --sd: 100%; }
.ch-t .gl { display: block; }
/* le titre d'origine reste au-dessus des copies rouge et cyan : le dégradé du dernier mot garde ses couleurs, seules les franges dépassent */
.ch-t { isolation: isolate; }
.ch-t .gl-base { position: relative; z-index: 1; }
.ch-t .gl-red, .ch-t .gl-cyan, .ch-t .gl-slice { position: absolute; inset: 0; opacity: 0; pointer-events: none; }

/* ---------- Footer (rideau fixe) ----------
   Grille reprise du Framer (mesurée sur hlprodz.framer.website à 1280 et 1440 px) : liens en colonne 1 (lignes de 40 px),
   réseaux en colonne 4 (3 × 2 cases carrées, carte de 58 px à 1280 avec 20 px de marge), e-mail | téléphone puis ville sur les colonnes 3-4
   (lignes de 60 px), grand logo sur les colonnes 3-4 (116 px), 4 px d'écart, puis la ligne du droit d'auteur (52 px).
   Tout est dans le flux : les blocs ne se chevauchent à aucune largeur. */
.ftr-space { height: calc(534 * var(--u)); position: relative; z-index: 0; pointer-events: none; }
.ftr { position: fixed; left: 0; right: 0; bottom: 0; z-index: 0; overflow: hidden; background: #000; }
.ftr-in { position: relative; z-index: 1; padding-top: calc(50 * var(--u)); }
.ftr-top { position: relative; grid-template-rows: auto calc(116 * var(--u)); row-gap: 0; border-bottom: calc(1 * var(--u)) solid var(--w10); }
/* fond des cases (comme le Framer, blanc 5 %) posé sur un voile noir 38 % (50 % avant, allégé le 10 octobre) : le faisceau passe dessous, blanc ≥ 4,9:1 sur l'orange */
.fnav a, .fcell, .flogo-w { background-color: rgba(0, 0, 0, .38); background-image: linear-gradient(var(--w05), var(--w05)); }
.fnav { align-self: start; grid-row: 1; }
.fnav a {
  display: flex; justify-content: space-between; align-items: center; height: calc(40 * var(--u)); margin-top: calc(-1 * var(--u)); padding: 0 calc(20 * var(--u));
  box-shadow: inset 0 0 0 calc(1 * var(--u)) var(--w05); text-transform: uppercase; font-size: calc(15 * var(--u)); position: relative;
  opacity: 0; transform: translateY(calc(10 * var(--u)));
  transition: padding .5s cubic-bezier(.44, 0, .56, 1), background-color .5s cubic-bezier(.44, 0, .56, 1), opacity .6s var(--ease) var(--rd, 0s), transform .6s var(--ease) var(--rd, 0s);
}
.fnav a:first-child { margin-top: 0; }
.fnav a .arr { font-size: calc(14 * var(--u)); transition: transform .5s cubic-bezier(.44, 0, .56, 1); }
.fnav a:hover { padding-left: calc(30 * var(--u)); padding-right: calc(30 * var(--u)); background-color: rgba(20, 20, 20, .8); }
.fnav a:hover .arr { transform: translateY(calc(2 * var(--u))); }
.fnav a:hover span { background: var(--gta-text); -webkit-background-clip: text; background-clip: text; color: transparent; }
.ftr.in .fnav a { opacity: 1; transform: none; }
.fright { grid-row: 1; display: grid; grid-template-columns: 1fr 1fr; }
/* réseaux : colonne 4, cases carrées de 1/3 de colonne, carte retournable avec 20 px de marge (58 px à 1280, 72 px à 1440) */
.fsoc { grid-column: 2; display: grid; grid-template-columns: repeat(3, 1fr); }
.flip { aspect-ratio: 1; padding: calc(20 * var(--u)); perspective: calc(600 * var(--u)); display: block; box-shadow: inset 0 0 0 calc(.5 * var(--u)) var(--w10); }
.flip-in { display: block; position: relative; width: 100%; height: 100%; transform-style: preserve-3d; transition: transform .7s var(--spring); }
.flip:hover .flip-in { transform: rotateY(180deg); }
.flip-f, .flip-b { position: absolute; inset: 0; display: grid; place-items: center; backface-visibility: hidden; -webkit-backface-visibility: hidden; transform: translateZ(calc(1 * var(--u))); }
.flip-f { background: var(--bg-2); }
.flip-b { background: var(--brand); transform: rotateY(180deg) translateZ(calc(1 * var(--u))); }
.flip svg { width: calc(29 * var(--u)); height: calc(29 * var(--u)); }
.finfo { grid-column: 1 / 3; display: grid; grid-template-columns: 1fr 1fr; }
.fcell { height: calc(60 * var(--u)); display: flex; align-items: center; padding: 0 calc(20 * var(--u)); text-transform: uppercase; font-size: calc(15 * var(--u)); box-shadow: inset 0 0 0 calc(.5 * var(--u)) var(--w10); transition: color .3s, background-color .5s cubic-bezier(.44, 0, .56, 1); }
.fcell.wide { grid-column: 1 / 3; }
/* survol des cases e-mail, téléphone, lieu : fond assombri comme la nav, texte en dégradé qui rétrécit en gardant son alignement à gauche */
.fcell:hover { background-color: rgba(20, 20, 20, .8); }
.fcell span { display: inline-block; transition: color .3s; }
.fcell:hover span { background: var(--gta-text); -webkit-background-clip: text; background-clip: text; color: transparent; }
/* grand logo (colonnes 3-4), centré avec son ® collé à droite (même écart qu'entre les lettres). Toute la case est le lien.
   Survol : comme les liens de la nav (fond assombri, contenu qui rétrécit), le logo et son ® prennent le dégradé des cases
   (dégradé SVG #flg, mêmes couleurs que --gta-text ; le ® prend sa couleur de fin) et rétrécissent autour du centre. */
.flogo-w { grid-row: 2; box-shadow: inset 0 0 0 calc(.5 * var(--u)) var(--w10); transition: background-color .5s cubic-bezier(.44, 0, .56, 1); }
.flogo-w:has(.flogo:hover) { background-color: rgba(20, 20, 20, .8); }
.flogo { display: block; height: 100%; padding: calc(5.5 * var(--u)) calc(20 * var(--u)); }
.flogo-in { display: flex; align-items: flex-start; justify-content: center; gap: calc(2 * var(--u)); transform-origin: 50% 50%; transition: transform .5s cubic-bezier(.44, 0, .56, 1); }
.flogo:hover .flogo-in { transform: scale(.94); }
.flogo svg { display: block; min-width: 0; height: calc(105 * var(--u)); width: auto; max-width: 100%; }
.flogo:hover svg :is(text, path:not([fill="none"])) { fill: url(#flg); }
.flogo:hover svg path[fill="none"] { stroke: url(#flg); }
.reg { flex: none; margin-top: calc(4 * var(--u)); font-family: var(--f-text); font-size: calc(46 * var(--u)); font-weight: 500; line-height: 1; }
.flogo:hover .reg { color: #FD7C93; }
.ftr-bot { height: calc(52 * var(--u)); align-items: center; }
.fcopy { font-family: var(--f-mono); font-size: calc(12 * var(--u)); letter-spacing: calc(.5 * var(--u)); text-transform: uppercase; }

/* ---------- Divers ---------- */
.corners { position: absolute; inset: 0; pointer-events: none; }
.corners::before, .corners::after { content: ""; position: absolute; width: calc(7 * var(--u)); height: calc(7 * var(--u)); border-color: var(--w50); border-style: solid; }
.corners::before { left: 0; top: 0; border-width: calc(1 * var(--u)) 0 0 calc(1 * var(--u)); }
.corners::after { right: 0; bottom: 0; border-width: 0 calc(1 * var(--u)) calc(1 * var(--u)) 0; }
.chip { display: inline-flex; align-items: center; height: calc(32 * var(--u)); padding: 0 calc(20 * var(--u)); background: var(--w05); transition: background .3s; }
.chip:hover { background: var(--w10); }
.chip.on { background: var(--brand); }

/* chiffres qui roulent (NumberFlow) */
.odo { display: inline-flex; overflow: hidden; height: 1em; line-height: 1; vertical-align: top; }
/* chaque colonne prend la largeur de son chiffre final grâce à une copie invisible (juste avec la police réellement chargée) */
.odo .d { position: relative; display: block; height: 1em; overflow: hidden; }
.odo .d > i { display: block; font-style: normal; visibility: hidden; }
.odo .d > span { position: absolute; left: 0; top: 0; display: block; transition: transform 2.2s cubic-bezier(.16, 1, .3, 1); }
.odo .d b { display: block; height: 1em; font-weight: inherit; }

/* puces pixel (listes de prestations) */
.pxb { display: inline-grid; grid-template-columns: repeat(3, calc(2 * var(--u))); grid-auto-rows: calc(2 * var(--u)); gap: calc(1 * var(--u)); margin-right: calc(10 * var(--u)); flex: none; }
.pxb i { background: #fff; opacity: 0; }
.pxb i.o { opacity: 1; }

/* ---------- Grain : uniquement sur les fonds aux couleurs de la charte ---------- */
.wcta::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: var(--grain); opacity: .12; mix-blend-mode: screen;
}
.wcta > * { position: relative; z-index: 1; }
