/* 23/09/2026 : une copie tronquée de ce fichier a été servie une heure (transfert FTP repris au
   lieu d'être remplacé). Ce commentaire change l'empreinte ?v= : les navigateurs qui l'avaient
   gardée en cache pour 30 jours rechargent le fichier complet. */
/* Drop Music — feuille de style du site statique */
/* Tailles en rem (1rem = 16px). La taille de base reste 16px jusqu'à 1600px de large, puis grandit avec l'écran
   jusqu'à 22px (2560px) : tout le site s'agrandit en proportion. Garder en px : bordures fines, media queries. */
:root{
 /* Le site est sombre et le déclare : sans cette ligne, un navigateur en « forçage du thème
    sombre » (Chrome auto dark, extension type Dark Reader) réécrit les fonds de blocs en gris
    clair mais laisse les photos intactes, ce qui rouvre une couture sous chaque hero. */
 color-scheme:dark;
 --nav-h:4.75rem;
 --rail:max(var(--gutter),calc((100% - var(--wrap))/2 + var(--gutter)));

 /* Fonds. --tile2 est le fond d'une section alternée : à #0c0c0d il valait 1,01:1 contre le
    fond de page, l'alternance ne se voyait pas. À #131315 elle vaut 1,07:1, assez pour qu'on
    la perçoive sans qu'elle découpe la page. */
 --void:#0A0A0B;--tile1:#141416;--tile2:#131315;--tile3:#101011;
 /* Traits. Trois valeurs, pas neuf : une séparation, un contour de surface, et un trait
    posé sur une photo, qui a besoin de plus pour exister. */
 --hairline:rgba(255,255,255,.10);--hair-strong:rgba(255,255,255,.22);
 --hair-contrast:rgba(255,255,255,.35);

 /* Arrondis. Trois rayons, la pilule et le cercle. Un rayon hors de cette liste est un
    oubli : le site en comptait cinq, plus deux écritures de pilule (99px et 999px). */
 --r-s:.5rem;--r-m:.75rem;--r-l:.875rem;--r-pill:999px;
 /* Fond des fiches. --card-0 est le même ton en alpha 0 : un dégradé vers
    transparent partirait du noir dans les moteurs anciens et grisaillerait le fondu. */
 --card:#0f0f11;--card-0:rgba(15,15,17,0);

 /* Texte en couleurs pleines, jamais en opacity : une opacity posée sur un conteneur
    délave aussi ses enfants. Ratios mesurés sur --void / --tile2 / --tile1 / fond de fiche. */
 --text:#FFFFFF;          /* 19,79 à 18,40:1 */
 --text-muted:#C6C6CC;    /* 11,64 à 10,82:1  (remplace --ink-70) */
 --text-subtle:#8A8A90;   /*  5,77 à  5,36:1  (remplace --ink-55 et --muted) */
 --text-title:#f4f4f5;    /* 18,00 à 16,74:1 */
 --accent:#FF3644;        /*  5,53 à  5,14:1, valide en texte courant sur fond plein */
 --accent-hover:#FF6B75;  /*  7,17 à  6,67:1  (remplace --accent-deep, qui assombrissait au survol) */

 /* Espacement, base 4. Neuf échelons, tout est un multiple de 4 px à 1rem = 16px. */
 --space-1:.25rem;   /*  4 */
 --space-2:.5rem;    /*  8 */
 --space-3:.75rem;   /* 12 */
 --space-4:1rem;     /* 16 */
 --space-5:1.25rem;  /* 20 */
 --space-6:1.5rem;   /* 24 */
 --space-7:2rem;     /* 32 */
 --space-8:2.5rem;   /* 40 */
 --space-9:3.5rem;   /* 56 */

 /* Rythme structurel : ces valeurs ne sont pas arrondies sur l'échelle, elles la dépassent.
    --gutter et --section-y remplacent les paires 3rem/1.5rem et 7.5rem/4.5rem des media queries. */
 --gutter:clamp(1.5rem,.75rem + 2vw,3rem);      /* 24 → 48 */
 --section-y:clamp(4.5rem,3rem + 4vw,7.5rem);   /* 72 → 120 */
 --block-y:5rem;                                 /* 80 : footer, bande CTA */
 --hero-y:8.75rem;                               /* hero de l'accueil */
 /* Hero des pages intérieures. Fluide : 150 px sur grand écran, 88 px sur téléphone.
    En valeur fixe, ces 150 px occupaient 28 % d'un hero de 540 px. */
 --hero-short-y:clamp(5.5rem,3rem + 7vw,9.375rem);

 /* Échelle typographique fermée : 8 rôles, et rien d'autre. Chaque règle de texte du site
    pioche ici ; une taille qui n'est pas dans cette liste est un oubli, pas une intention.
    Quatre exceptions assumées, toutes décoratives et uniques : .hero .sign (--fs-display),
    .marquee li (bande de mots), .timeline .num (le chiffre d'étape) et le glyphe × des
    boîtes modales. Le gris #4a4a50 de .video-slot .empty est lui aussi volontaire : ce
    texte d'attente doit rester à peine lisible.
    H1 reste au-dessus de H2 à toutes les largeurs : 26/22 px à 375, 32/30 à 1440, 44/41 à 2560.
    Contrastes sur --void : --text 19,8:1, --text-muted 11,6:1, --text-subtle 5,8:1,
    --accent 5,5:1. Tous au-dessus du seuil AA (4,5:1), y compris en petit corps. */
 --fs-h1:clamp(1.625rem,1rem + 1.4vw,2rem);      /* H1 de hero, un par page */
 --fs-h2:clamp(1.375rem,1rem + .95vw,1.875rem);  /* titre de section */
 --fs-h3:1.125rem;        /* 18 : titre de carte, de fiche, de page légale */
 --fs-lead:1.1875rem;     /* 19 : chapô, sous le H1 seulement */
 --fs-body:1rem;          /* 16 : corps courant */
 --fs-body-sm:.875rem;    /* 14 : corps secondaire, footer, texte de carte */
 --fs-btn:.8125rem;       /* 13 : bouton, et titre des cartes compactes */
 --fs-eyebrow:.75rem;     /* 12 : surtitre de section */
 --fs-label:.6875rem;     /* 11 : label de rubrique, méta, légende */
 --fs-display:clamp(1.5rem,.95rem + 1.5vw,2.25rem);  /* .hero .sign, décoratif */

 --fw-h1:200;--fw-title:300;--fw-body:300;--fw-label:400;--fw-btn:500;
 --ls-h1:.08em;--ls-h2:.18em;--ls-h3:.12em;--ls-eyebrow:.3em;--ls-label:.22em;--ls-btn:.14em;
 --lh-tight:1.25;--lh-body:1.65;

 /* Largeurs. --measure borne la mesure des paragraphes, qui montait à 100 ch dans la timeline. */
 --wrap:77.5rem;--measure:68ch;--measure-lead:60ch;

 /* Zone tactile minimale (44 px) : servie par des pseudo-éléments pour ne pas grossir le visuel. */
 --tap:2.75rem;
}
/* Jost, servie par le site (src/fonts/, copiée par build.py). Un fichier variable par jeu de
   caractères couvre les graisses 200 à 600 ; unicode-range fait qu'une page en français ne
   charge que le latin. */
@font-face{font-family:'Jost';font-style:normal;font-weight:200 600;font-display:swap;src:url(assets/fonts/jost-latin.woff2) format('woff2');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:'Jost';font-style:normal;font-weight:200 600;font-display:swap;src:url(assets/fonts/jost-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
*{box-sizing:border-box}
html{font-size:clamp(16px,calc(6px + .625vw),22px);scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{margin:0;background:var(--void);color:var(--text);font-family:'Jost',ui-sans-serif,system-ui,sans-serif;font-weight:300;line-height:1.5}
a{color:var(--accent);text-decoration:none}
a:hover{color:var(--accent-hover)}
/* Toute image recadrée suit son point d'intérêt. --focal est posé sur l'image par le build,
   d'après FOCALS (content.py) ; sans entrée, le cadre reste centré. Plus aucune règle de
   cadrage par nom de carte dans cette feuille. */
img,video{max-width:100%;display:block}
img{object-position:var(--focal,50% 50%)}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--gutter)}
/* Focus clavier : une seule règle pour tout le site. Avant, huit composants avaient leur
   propre anneau et tout le reste (les cartes, les boutons, la nav, le footer, les champs)
   recevait celui du navigateur, bleu et carré. :where() garde la spécificité à zéro, donc
   un composant peut encore la surcharger s'il a une bonne raison.
   border-radius:inherit : l'anneau suit la forme de ce qu'il entoure, rond sur un bouton rond. */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
 outline:.125rem solid var(--accent);outline-offset:.125rem;border-radius:inherit}

/* En-tête de section : UN composant, DEUX variantes, et pas une de plus.
     .eyebrow    le surtitre seul, en accent
     .label-row  le même surtitre suivi d'un filet qui file jusqu'au bord, en blanc
   Les deux partagent taille, graisse, interlettrage, casse et marge basse : seule change la
   couleur, et la présence du filet. Les deux fonctionnent sans H2 et sans sous-titre derrière
   (leur marge basse est la même, et l'écart au contenu vient de la règle commune --space-8). */
.eyebrow,.label-row .k{font-size:var(--fs-eyebrow);font-weight:var(--fw-label);
 letter-spacing:var(--ls-eyebrow);text-transform:uppercase;white-space:nowrap}
.eyebrow{color:var(--accent);margin:0 0 var(--space-5);text-shadow:0 0 .875rem rgba(255,54,68,.35)}
.eyebrow.muted{color:var(--text-subtle);text-shadow:none}
h1{font-size:var(--fs-h1);font-weight:var(--fw-h1);letter-spacing:var(--ls-h1);text-transform:uppercase;color:var(--text);margin:0;line-height:var(--lh-tight)}
h2{font-size:var(--fs-h2);font-weight:var(--fw-title);letter-spacing:var(--ls-h2);text-transform:uppercase;color:var(--text-title);margin:0 0 var(--space-4);line-height:var(--lh-tight)}
h3{font-size:var(--fs-h3);font-weight:var(--fw-title);letter-spacing:var(--ls-h3);text-transform:uppercase;color:var(--text-title);margin:0 0 var(--space-2)}
p{font-size:var(--fs-body);line-height:var(--lh-body);color:var(--text-muted);margin:0}
.lead{font-size:var(--fs-lead);line-height:1.6;color:var(--text);max-width:45rem}
.sub{font-size:var(--fs-body);line-height:1.6;color:var(--text-muted);max-width:36rem}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* Lien d'évitement : premier arrêt du clavier, invisible tant qu'il n'a pas le focus. */
.evitement{position:fixed;left:var(--space-4);top:var(--space-4);z-index:100;padding:var(--space-3) var(--space-5);border-radius:var(--r-pill);background:var(--accent);color:var(--void);font-size:var(--fs-btn);font-weight:var(--fw-btn);letter-spacing:var(--ls-btn);text-transform:uppercase;transform:translateY(-200%)}
.evitement:focus{transform:none;color:var(--void)}
main:focus{outline:none}
/* Mouvement réduit : les ancres sautent au lieu de glisser. */
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
@media(max-width:900px){.lead{font-size:var(--fs-body)}}

/* Nav */
.site-nav{position:sticky;top:0;z-index:40;height:var(--nav-h);display:flex;align-items:center;justify-content:space-between;padding:0 var(--rail);background:rgba(10,10,11,.82);backdrop-filter:saturate(160%) blur(20px);-webkit-backdrop-filter:saturate(160%) blur(20px);border-bottom:1px solid var(--hairline)}
.site-nav .logo img{width:7rem;height:auto;filter:drop-shadow(0 0 .375rem rgba(255,255,255,.25))}
.nav-links{display:flex;align-items:center;gap:var(--space-5);list-style:none;margin:0;padding:0}
.nav-links a{font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text);white-space:nowrap;padding-bottom:var(--space-1);border-bottom:1px solid transparent;text-shadow:0 1px .75rem rgba(0,0,0,.6)}
.nav-links a:hover{color:var(--accent)}
.nav-links a[aria-current="page"]{color:var(--accent);border-bottom-color:var(--accent)}
.nav-links .lang a{padding:var(--space-2) var(--space-3);border-radius:var(--r-s);border:1px solid var(--accent);color:var(--accent)}
.nav-links .lang a:hover{background:var(--accent);color:var(--void)}
.burger{display:none;background:none;border:none;padding:var(--space-2);cursor:pointer;color:var(--text);min-width:var(--tap);min-height:var(--tap);place-items:center}
.burger svg{width:1.625rem;height:1.625rem}
@media(max-width:980px){.site-nav{padding:0 var(--gutter)}.nav-links{display:none}.burger{display:grid;margin-left:auto;margin-right:calc(var(--space-2) * -1)}
 .nav-links.open{display:flex;flex-direction:column;align-items:stretch;gap:0;position:absolute;top:var(--nav-h);left:0;right:0;height:calc(100vh - var(--nav-h));height:calc(100dvh - var(--nav-h));background:rgba(10,10,11,.98);padding:var(--space-2) var(--space-6) var(--space-8);overflow-y:auto}
 .nav-links.open a{display:block;padding:var(--space-5) var(--space-1);font-size:var(--fs-body-sm);border-bottom:1px solid var(--hairline)}
 .nav-links.open .lang{margin-top:var(--space-5)}
 /* La pastille de langue héritait du padding des liens du menu (20 px en haut et en bas, 4 sur
    les côtés) : un cadre étroit et haut. Elle reprend ici sa forme, à hauteur de zone tactile. */
 .nav-links.open .lang a{display:inline-flex;align-items:center;min-height:var(--tap);padding:0 var(--space-5);border:1px solid var(--accent)}}
/* iPad en paysage : la nav d'ordinateur s'affiche sur un écran tactile, avec des liens de 21 px
   de haut. La zone s'étend par un pseudo-élément, le visuel ne change pas. */
@media(pointer:coarse) and (min-width:981px){.nav-links a{position:relative}.nav-links a::after{content:"";position:absolute;left:0;right:0;top:50%;height:var(--tap);transform:translateY(-50%)}}

/* Sélecteur de typologie : pilule à 3 segments, le même composant dans le hero et dans la barre fixe.
   Ce sont de vrais liens vers 3 URL. Le fond actif est un seul élément qui glisse, déplacé par site.js. */
.seg-pill{position:relative;display:inline-flex;padding:var(--space-1);background:rgba(255,255,255,.08);border-radius:var(--r-pill)}
.seg-pill a{position:relative;z-index:1;display:flex;align-items:center;justify-content:center;padding:var(--space-2) var(--space-5);border-radius:var(--r-pill);font-size:var(--fs-eyebrow);font-weight:var(--fw-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text-muted);white-space:nowrap;border-bottom:0;transition:color .2s}
/* Zone tactile : le segment compact fait 25 px de haut, celui du hero 34. Le pseudo-élément
   porte la zone à 44 px sans grossir la pilule ; les segments se touchent sur les côtés, la
   zone ne s'étend donc qu'en hauteur. */
.seg-pill a::after{content:"";position:absolute;left:0;right:0;top:50%;height:var(--tap);transform:translateY(-50%)}
.seg-pill a:hover,.seg-pill a:focus-visible{color:var(--text)}
.seg-pill a[aria-current="page"]{color:var(--text)}
.seg-glisse{position:absolute;top:.25rem;bottom:.25rem;left:0;z-index:0;width:0;border-radius:var(--r-pill);background:rgba(255,255,255,.14);box-shadow:0 1px 2px rgba(0,0,0,.35);transform:translateX(0);transition:transform .35s cubic-bezier(.4,0,.2,1),width .35s cubic-bezier(.4,0,.2,1)}
/* Sans JavaScript : pas de fond glissant, le segment courant porte son propre fond. */
.seg-pill:not([data-ready]) .seg-glisse{display:none}
.seg-pill:not([data-ready]) a[aria-current="page"]{background:rgba(255,255,255,.14);box-shadow:0 1px 2px rgba(0,0,0,.35)}
.hero .seg-pill{margin-top:var(--space-6)}

/* Barre fixe sous la nav. position:fixed et non sticky : masquée, elle ne réserve aucune place
   dans le flux et ne décale donc pas le contenu. z-index sous la nav (40) et sous le FAB (39). */
.seg-bar{position:fixed;top:var(--nav-h);left:0;right:0;z-index:38;height:3rem;background:rgba(13,13,14,.72);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);border-bottom:1px solid var(--hairline);opacity:0;visibility:hidden;transform:translateY(-.5rem);transition:opacity .25s ease,transform .25s ease,visibility .25s}
.seg-bar.is-on{opacity:1;visibility:visible;transform:translateY(0)}
.seg-bar-in{height:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--space-6);padding:0 var(--rail)}
.seg-bar-k{font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text-subtle);white-space:nowrap}
.seg-pill.compact{padding:var(--space-1)}
.seg-pill.compact a{padding:var(--space-1) var(--space-3);font-size:var(--fs-label)}
@media(max-width:980px){.seg-bar-in{padding:0 var(--gutter)}}
@media(max-width:640px){
 .seg-pill{display:flex;width:100%}
 .seg-pill a{flex:1;padding-left:var(--space-2);padding-right:var(--space-2);letter-spacing:.1em}
 .seg-bar-k{display:none}
 .seg-bar-in{padding:0 var(--gutter)}}
/* « Bar Mitsvah » en toutes lettres : à 320 px la pilule débordait de 25 px. */
@media(max-width:374px){.seg-pill a,.seg-pill.compact a{padding-left:var(--space-1);padding-right:var(--space-1);letter-spacing:.04em}}
@media(prefers-reduced-motion:reduce){.seg-glisse,.seg-bar{transition:none}}

.fab{position:fixed;right:max(1.5rem,env(safe-area-inset-right));bottom:max(1.5rem,env(safe-area-inset-bottom));z-index:39;height:2.75rem;padding:0 var(--space-5);display:flex;align-items:center;justify-content:center;border:1px solid var(--hair-contrast);border-radius:var(--r-pill);background:rgba(10,10,11,.72);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);font-size:var(--fs-btn);font-weight:var(--fw-btn);letter-spacing:var(--ls-btn);text-transform:uppercase;color:var(--text);transition:opacity .25s,transform .25s,visibility .25s}
/* Masqué (site.js) : visibility le retire aussi de l'ordre de tabulation. */
.fab.is-off{opacity:0;visibility:hidden;transform:translateY(.75rem);pointer-events:none}
@media(prefers-reduced-motion:reduce){.fab{transition:none}}
.fab:hover{background:var(--accent);color:var(--void);border-color:var(--accent)}
/* Sur téléphone il rétrécit, mais garde ses 44 px de hauteur : c'est une zone tactile. */
@media(max-width:640px){.fab{right:max(var(--space-4),env(safe-area-inset-right));bottom:max(var(--space-4),env(safe-area-inset-bottom));padding:0 var(--space-4)}}

/* Sections */
/* Arrivée par une ancre (#effets, #artistes...) : sans cette marge, la section se colle
   sous la nav et la barre fixe de typologie lui mange son surtitre. Mesuré avant :
   18 à 19 px recouverts en 1440, 52 px en 390. La barre finit à 124 px du haut. */
section[id]{scroll-margin-top:calc(var(--nav-h) + 3.5rem)}
section.tile{padding:var(--section-y) var(--gutter)}
section.tile.alt{background:var(--tile2)}
/* Chapô de typologie : suivi immédiatement du Line up, on ne double pas la respiration */
/* Le chapô de typologie appartient au titre de la page plus qu'à la section suivante : il
   ferme sur l'écart d'un bloc d'intro (--space-8) et non sur --section-y, pour rester
   rattaché visuellement au hero, sans pour autant coller au premier bloc de contenu. */
section.tile.typ-intro{padding-top:var(--space-7);padding-bottom:var(--space-8)}
/* Une colonne centrée de 62 caractères : le chapô en --fs-lead (qui repasse en --fs-body
   sous 900 px, par la règle de .lead), puis les deux paragraphes en texte courant. */
/* 62ch de texte : .wrap est en border-box et garde sa gouttière, on l'ajoute au plafond. */
.typ-intro .wrap{max-width:calc(62ch + 2 * var(--gutter));margin-inline:auto;text-align:center}
.typ-intro :is(.lead,.sub){max-width:none}
.typ-intro p + p{margin-top:var(--space-4)}
.head-row{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-6);flex-wrap:wrap;margin-bottom:var(--space-8)}
/* Écart unique entre la fin d'un bloc d'introduction (surtitre, titre, sous-titre) et le
   premier contenu de la section. Une seule valeur pour tout le site : --space-8.
   Avant ce commit, la même transition valait 0 px (Artistes), 24 px (Formules, Effets),
   40 px (Études de cas, Composition, Témoignages), 48 px ou 56 px (Déroulé), dont quatre
   écrites en style inline dans build.py.
   :not(:first-child) : quand le contenu ouvre la section, il n'y a rien à espacer. */
.tile > .wrap > :is(.grid,.timeline,.cases,.gallery,.carousel,.video-slot,.teaser-zone):not(:first-child){
 margin-top:var(--space-8)}

/* En-tête de page suivi de son contenu : deux sections qui n'en forment qu'une à l'œil. */
section.tile.entete{padding-bottom:var(--space-8)}
section.tile.enchaine{padding-top:0}

.label-row{display:flex;align-items:center;gap:var(--space-5);margin-bottom:var(--space-5)}
.label-row .k{color:var(--text)}
.label-row .rule{flex:1;height:1px;background:var(--hairline)}
.words{display:flex;gap:var(--space-6);margin-top:var(--space-8);flex-wrap:wrap}
.words span{font-size:var(--fs-btn);font-weight:var(--fw-label);letter-spacing:var(--ls-eyebrow);text-transform:uppercase;color:var(--accent)}
.words i{width:1px;background:var(--hair-strong)}

/* Hero */
/* --hero-fade-to : la couleur dans laquelle le hero se termine. Elle sert deux fois, au
   dernier stop du fondu du bas et au fond du hero lui-même, pour qu'aucun cas limite
   (photo qui ne couvrirait pas, image pas encore décodée) ne laisse voir une autre
   couleur que celle du bloc suivant. Par défaut --void : toutes les sections qui suivent
   un hero sont des .tile sans fond propre, donc ce qu'on voit est le fond de page.
   Un hero suivi d'un bloc à fond propre (.tile.alt, --tile2) se règle en posant
   --hero-fade-to sur ce hero-là, sans toucher au reste. */
.hero{--hero-fade-to:var(--void);position:relative;isolation:isolate;min-height:90vh;min-height:90svh;display:grid;place-items:center;background:var(--hero-fade-to);overflow:hidden;margin-top:calc(var(--nav-h) * -1);padding:var(--hero-y) var(--gutter) var(--section-y)}
.hero.short{min-height:85vh;min-height:85svh;align-items:end;place-items:end stretch;padding:var(--hero-short-y) var(--gutter) var(--block-y)}
.hero .bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;object-position:var(--focal,50% 50%)}
.hero .scrim{position:absolute;inset:0;z-index:1;background:radial-gradient(ellipse 47.5rem 30rem at 50% 50%,rgba(10,10,11,.78) 0%,transparent 70%)}
/* Voile des heros de pages événement : léger, pour que la photo reste lisible sur toute sa
   largeur. Il fonce seulement vers le bas, sous le texte ; le fondu (::after) finit le travail. */
.hero.short .scrim{background:linear-gradient(to top,rgba(10,10,11,.6) 0%,rgba(10,10,11,.2) 50%,rgba(10,10,11,0) 100%)}
.hero .content{position:relative;z-index:3;text-align:center;max-width:58.75rem}
/* Le H1 de l'accueil est une phrase : on borne sa mesure pour choisir où elle casse. */
.hero.home h1{max-width:40ch;margin-inline:auto}
/* Fondu du bas, sur tous les heros (accueil et pages événement) : la photo se fond dans la
   section suivante, qui a le fond de page (--void). z-index 1 comme .scrim, peint après lui,
   sous .content (z-index 2), donc le texte n'est jamais assombri.
   Hauteur : la moitié du hero, jamais moins de 17.5rem (280 px de base), pour qu'un hero court
   (fenêtre large et basse) garde de quoi fondre. Le dégradé atteint --void à 94 % : les 6 %
   restants sont une bande plate à la couleur exacte du bloc suivant, donc aucune arête même
   quand le bas de la photo est clair. */
/* bottom:-2px et +2px de hauteur : le hero a une hauteur fractionnaire (90vh, 64vh...),
   et le pseudo-élément, promu sur sa propre couche par translateZ, est aligné sur la grille
   de pixels physiques. Sans ce débord, 1 à 2 rangées de photo restent non couvertes tout en
   bas du hero : c'est l'arête qu'on voyait sur mobile. overflow:hidden du hero coupe le
   débord, il ne dépasse donc jamais sur la section suivante. */
.hero::after{content:"";position:absolute;left:0;right:0;bottom:-2px;height:calc(max(42%,18rem) + 2px);z-index:2;pointer-events:none;transform:translateZ(0);will-change:transform;background:linear-gradient(to bottom,rgba(10,10,11,0) 0%,rgba(10,10,11,.06) 30%,rgba(10,10,11,.20) 50%,rgba(10,10,11,.45) 65%,rgba(10,10,11,.72) 78%,rgba(10,10,11,.92) 90%,var(--hero-fade-to) 97%)}
.hero.short .content{text-align:left;max-width:var(--wrap);margin:0 auto;width:100%}
/* « Orchestrer l'émotion » : rouge sur photo rouge. Le néon rouge fondait la lettre dans la
   scène ; c'est désormais un halo sombre qui la détache, et il ne reste qu'une lueur rouge
   légère. Rouge plus clair (--accent-hover) et graisse 400 pour que le trait tienne. */
.hero .sign{font-size:var(--fs-display);letter-spacing:.1em;text-transform:uppercase;color:var(--accent-hover);margin:var(--space-6) 0 0;font-weight:var(--fw-label);text-shadow:0 0 .125rem rgba(10,10,11,.9),0 .0625rem 1rem rgba(10,10,11,.85),0 0 2.5rem rgba(10,10,11,.6),0 0 .75rem rgba(255,54,68,.3)}

/* Sur l'accueil, la photo est vive derrière le texte : un voile sombre ovale, borné au bloc
   de texte, lui donne un fond lisible sans assombrir la scène autour. */
.hero.home .content::before{content:"";position:absolute;inset:-4rem -8rem;z-index:-1;pointer-events:none;background:radial-gradient(closest-side,rgba(10,10,11,.6),rgba(10,10,11,.35) 55%,rgba(10,10,11,0))}
.hero .lead{margin:var(--space-5) auto 0;text-shadow:0 1px .75rem rgba(0,0,0,.6)}
.hero .sign + .lead{margin-top:var(--space-6)}
.hero.short .lead{margin:var(--space-5) 0 0}
/* Rangée d'actions : le hero la centre, les pages Contact, Merci et 404 la laissent à gauche. */
.actions{display:flex;gap:var(--space-3);flex-wrap:wrap}
.hero .actions{margin-top:var(--space-8);justify-content:center}
/* Pages sans grille : un wrap plus étroit, et le chapô qui suit le H1 sur l'écart commun. */
.wrap.court{max-width:45rem}
h1 + .lead{margin:var(--space-5) 0 var(--space-8)}
.hero h1,.hero p,.hero .eyebrow{text-shadow:0 1px .75rem rgba(0,0,0,.6)}
.hero .eyebrow{color:var(--text);text-shadow:0 1px .75rem rgba(0,0,0,.7)}
/* Hauteur des heros. 85vh sur les pages événement : à 64vh la photo 16/9 perdait 29 % de sa
   hauteur et coupait les artistes, à 78vh 13 %, à 85vh 6 %. Le contenu est ancré en
   bas (place-items:end), la hauteur gagnée s'ajoute donc en haut, au-dessus du titre, et ni le
   titre ni le sélecteur ne bougent par rapport au bas du hero.
   Sous 900 px le cadre devient vertical et rogne en largeur : l'agrandir aggraverait le
   recadrage (59 % perdus à 64vh, 67 % à 78vh). On y reste donc à 64vh, et c'est la version
   mobile de la photo, cadrée en 4:5 par photos.py, qui fait le travail. */
@media(max-width:900px){.hero{min-height:70vh;min-height:70svh}.hero.short{min-height:64vh;min-height:64svh}}
/* Accueil sur téléphone et tablette : sous le bouton, 72 px de fin de hero puis 72 px de début de
   section laissaient 154 px de noir avant « Drop en une vidéo » (390x699). L'écart d'un bloc
   d'intro (--space-8) de chaque côté suffit : le fondu fait déjà la transition. */
@media(max-width:900px){.hero.home{padding-bottom:var(--space-8)}.hero.home + .tile{padding-top:var(--space-8)}}
/* Cadrage des heros : le point d'intérêt de chaque photo est déclaré dans HEROS (content.py)
   et arrive ici en variable, posée sur l'image par build.py. Plus aucune règle par nom de
   fichier, plus rien à modifier dans cette feuille quand une photo change.
   Sur ordinateur la photo n'est rognée qu'en hauteur : seule la 2e valeur de --focal joue.
   Sur mobile le cadre devient vertical et ne rogne qu'en largeur : c'est la 1re valeur de
   --focal-m qui décide, et --focal sert de repli si aucun réglage mobile n'est donné. */
@media(max-width:900px){.hero .bg{object-position:var(--focal-m,var(--focal,50% 50%))}}
/* Hero à clé `tablette` (HEROS) : au-dessus de 3/5 de rapport, sous 900 px (iPad en portrait,
   fenêtre étroite), build.py sert le 16:9 et non le 9:16 ; il se cadre donc sur --focal-t.
   Même seuil que le <source> du <picture>, écrit en 601/1000 pour ne pas chevaucher 3/5. */
@media(max-width:900px) and (min-aspect-ratio:601/1000){.hero .bg.tablette{object-position:var(--focal-t)}}

/* Buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;height:3rem;padding:0 var(--space-6);border-radius:var(--r-pill);background:var(--accent);color:var(--void);font-size:var(--fs-btn);font-weight:var(--fw-btn);letter-spacing:var(--ls-btn);text-transform:uppercase;border:none;cursor:pointer;font-family:inherit}
.btn:hover{background:var(--accent-hover);color:var(--void)}
.btn-outline{display:inline-flex;align-items:center;justify-content:center;height:3rem;padding:0 var(--space-6);border-radius:var(--r-pill);border:1px solid var(--hair-contrast);color:var(--text);font-size:var(--fs-btn);font-weight:var(--fw-btn);letter-spacing:var(--ls-btn);text-transform:uppercase;background:transparent;cursor:pointer;font-family:inherit}
.btn-outline:hover{border-color:var(--accent);color:var(--accent)}

/* Grids & cards */
.grid{display:grid;gap:var(--space-5)}
.grid-3{grid-template-columns:repeat(3,1fr)}
.grid-2{grid-template-columns:1fr 1fr}
.grid-4{grid-template-columns:repeat(4,1fr)}
/* grid-3 (Artistes, Composition) garde ses 3 colonnes sur tablette : en 2 colonnes, la
   3e carte restait seule sur sa rangée (iPad mini, iPad Air). */
@media(max-width:980px){.grid-4{grid-template-columns:1fr 1fr}}
@media(max-width:720px){.grid-3{grid-template-columns:1fr}}
@media(max-width:640px){.grid-2,.grid-4{grid-template-columns:1fr}}
.card{background:var(--tile1);border:1px solid var(--hairline);border-radius:var(--r-m);overflow:hidden;transition:border-color .2s,transform .2s;cursor:pointer;text-align:left;padding:0;color:inherit;font:inherit;display:flex;flex-direction:column;width:100%}
.card:hover{border-color:rgba(255,255,255,.3);transform:translateY(-.1875rem)}
.card .ph{position:relative;aspect-ratio:16/9;background:linear-gradient(158deg,#1a1a1c 0%,#0c0c0d 100%);overflow:hidden}
.card .ph img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .5s}
/* <picture> transparent pour la mise en page : le <img> reste enfant direct de son bloc */
picture{display:contents}
/* Recadrage des cartes Line up : le 16/9 de la carte rogne le haut et le bas des photos 3/2,
   on décale le cadrage pour garder les artistes entiers. DJ x Orchestre est déjà en 16/9. */
/* Pianiste (Cérémonie religieuse) : les 4 photos du dossier sont verticales, la miniature
   recadre donc une verticale. Le cadre descend pour montrer les pieds du piano et laisser
   au-dessus les barres et projecteurs de la scène. C'est le seul cas restant : partout
   ailleurs la miniature prend la première photo paysage du dossier.
   Un dossier qui n'aurait que des verticales se règle ici, au cas par cas. */
.card:hover .ph img{transform:scale(1.04)}
.card .ph::after{content:"";position:absolute;inset:0;background:linear-gradient(to top,rgba(10,10,11,.75) 0%,transparent 55%)}
/* Les cartes d'une rangée se remplissent inégalement (un titre sur deux lignes, un texte
   plus long). La carte est une colonne, le corps prend la place restante et le lien final
   est poussé en bas : les pieds tombent ensemble, sans min-height qui laisserait du vide
   quand tous les titres tiennent sur une ligne. */
.card .body{padding:var(--space-5);flex:1;display:flex;flex-direction:column;align-items:flex-start}
.card .body > .more{margin-top:auto;padding-top:var(--space-3)}
.card .body h3{margin:0 0 var(--space-2)}
.card .comp{font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--accent);margin:0 0 var(--space-2)}
.card .body p{font-size:var(--fs-body-sm);margin:0 0 var(--space-3)}
.card .more{font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text)}
.card:hover .more{color:var(--accent)}

/* Carte compacte (Effets scéniques, Cérémonie religieuse, Cocktail et dîner) : variante de .card,
   photo 3:2, titre puis lien, toute la carte ouvre la fiche. 4 par ligne, 3 sous 980, 2 sous 640. */
/* En flex et non en grille : une dernière rangée incomplète se centre au lieu de laisser une
   carte seule à gauche. --cols se choisit selon le nombre de cartes (data-n, posé par le
   build) : 5 cartes sur 5 colonnes, 4 sur 4 en tablette plutôt que 3 + 1. */
.grid-compact{--cols:4;display:flex;flex-wrap:wrap;justify-content:center}
.grid-compact > *{flex:0 0 calc((100% - (var(--cols) - 1) * var(--space-5)) / var(--cols));width:auto}
.grid-compact[data-n="5"]{--cols:5}
.compact-next{margin-top:var(--space-9)}
.card.compact .ph{aspect-ratio:3/2}
.card.compact .body{padding:var(--space-3) var(--space-3) var(--space-3)}
.card.compact .body h3{font-size:var(--fs-btn);line-height:1.4;margin:0}
/* Le lien d'une carte compacte est au pied comme partout (margin-top:auto sur .more),
   mais l'écart au titre suit les marges resserrées de cette variante. */
.card.compact .body > .more{padding-top:var(--space-2)}
.card.compact:focus-visible{outline:.125rem solid var(--accent);outline-offset:.1875rem;border-color:rgba(255,255,255,.3)}
/* Tablette : 3 colonnes, sauf 4 et 8 cartes (4 colonnes, rangées pleines) et 5 cartes, qui
   restent sur une rangée de 5 (vérifié à 744 px, iPad mini : titres sur deux lignes au plus). */
@media(max-width:980px){.grid-compact{--cols:3}.grid-compact:is([data-n="4"],[data-n="8"]){--cols:4}.grid-compact[data-n="5"]{--cols:5}}
@media(max-width:640px){.grid-compact,.grid-compact:is([data-n="4"],[data-n="8"]){--cols:2;gap:var(--space-3)}.grid-compact > *{flex-basis:calc((100% - var(--space-3)) / 2)}.card.compact .body{padding:var(--space-3) var(--space-3) var(--space-3)}.card.compact .body h3{font-size:var(--fs-eyebrow);letter-spacing:var(--ls-h3)}.card.compact .todo-box small{display:none}}
/* Bloc Composition (accueil) : centré, et sa sortie reprend l'écart commun. */
.compose > .wrap > .sub{margin-top:var(--space-8)}
.head-row h2{margin:0}
.legal-page h1 + div{margin-top:var(--space-6)}
.compose .card{cursor:default}
.compose .card:hover{transform:none}
.compose .ph{aspect-ratio:16/10}
.compose .ph .title{position:absolute;left:1.5rem;bottom:1.375rem;right:1.5rem;z-index:1}
.compose .ph .title b{display:block;font-size:var(--fs-h3);font-weight:var(--fw-title);letter-spacing:var(--ls-h3);text-transform:uppercase;color:var(--text)}

/* Split tiles (pour qui) */
.split-tile{position:relative;border:1px solid var(--hairline);border-radius:var(--r-l);overflow:hidden;min-height:18.75rem;display:flex;color:inherit}
.split-tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;transition:transform .6s}
.split-tile:hover img{transform:scale(1.04)}
.split-tile .scrim{position:absolute;inset:0;background:linear-gradient(to top,rgba(10,10,11,.92) 0%,rgba(10,10,11,.55) 55%,rgba(10,10,11,.25) 100%);z-index:1}
.split-tile .body{position:relative;z-index:2;padding:var(--space-8);display:flex;flex-direction:column;justify-content:flex-end;min-height:18.75rem;width:100%}
.split-tile h3{font-size:var(--fs-h3);letter-spacing:var(--ls-h3)}
.split-tile p{max-width:28.75rem;margin-bottom:var(--space-3)}
/* Sur une photo, l'accent perd son contraste dès que le fond s'éclaircit : le lien passe en
   --text, et c'est le survol qui l'accentue. Même raison pour le surtitre d'un hero. */
.split-tile .more{font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text)}
.split-tile:hover .more{color:var(--accent)}

/* Concept */
/* Le chapô du Concept est un texte courant, pas une accroche de hero : il prend le gris du
   corps. C'était le dernier style inline de couleur de build.py. */
.concept .lead{color:var(--text-muted)}
/* align-items:start et non center : contre une photo en 4:5, le centrage vertical laissait
   438 px de vide au-dessus du surtitre, pour un rythme de section de 240 px. */
.concept{display:grid;grid-template-columns:1.15fr .85fr;gap:var(--space-9);align-items:start}
.concept .photo{position:relative;aspect-ratio:4/5;border-radius:var(--r-m);overflow:hidden;background:var(--tile1)}
.concept .photo img{width:100%;height:100%;object-fit:cover}
@media(max-width:900px){.concept{grid-template-columns:1fr;gap:var(--space-7)}}
/* Carrousel du concept : photos superposées, fondu enchaîné piloté par site.js */
.carousel .slide{position:absolute;inset:0;opacity:0;transition:opacity 1s ease}
.carousel .slide.is-on{opacity:1}
.carousel .dots{display:flex;justify-content:center;gap:var(--space-1);margin-top:var(--space-3)}
/* Zones tactiles. Le visuel garde sa taille, c'est la zone cliquable qui s'étend, par un
   pseudo-élément centré de --tap (44 px). Points du carrousel, liens du footer, segments.  */
.carousel .dots button:not(.pause){width:var(--tap);height:var(--tap);padding:0;border:0;background:none;cursor:pointer;display:grid;place-items:center}
.carousel .dots button:not(.pause)::before{content:"";width:.4375rem;height:.4375rem;border-radius:50%;background:var(--hair-strong);transition:background .3s,transform .3s}
.carousel .dots button:not(.pause):hover::before{background:var(--text-subtle)}
.carousel .dots button:not(.pause)[aria-current="true"]::before{background:var(--accent);transform:scale(1.25)}
.no-js .carousel .dots{display:none}
/* Bouton pause (carrousel, bande de logos) : rond de 28 px, zone de 44. */
.pause{width:var(--tap);height:var(--tap);padding:0;border:0;background:none;cursor:pointer;display:grid;place-items:center;color:var(--text-muted)}
.pause svg{width:1.75rem;height:1.75rem;padding:.375rem;border:1px solid var(--hairline);border-radius:50%;stroke:currentColor;stroke-width:1.6;fill:none;stroke-linecap:round}
.pause .i-play{display:none;fill:currentColor;stroke:none}
.pause[aria-pressed="true"] .i-pause{display:none}
.pause[aria-pressed="true"] .i-play{display:block}
.pause:hover{color:var(--accent)}
.carousel .dots .pause{margin-left:var(--space-2)}
.marquee{position:relative}
.marquee .pause{position:absolute;right:var(--gutter);bottom:var(--space-2)}
.marquee.is-paused ul{animation-play-state:paused}
/* Rien ne bouge en mouvement réduit ni sans JavaScript : le bouton n'a rien à arrêter. */
@media(prefers-reduced-motion:reduce){.pause{display:none}}
.no-js .pause{display:none}
@media(prefers-reduced-motion:reduce){.carousel .slide,.carousel .dots button:not(.pause)::before{transition:none}}

/* Video slot */
.video-slot{position:relative;width:100%;aspect-ratio:16/9;background:var(--tile3);overflow:hidden;border:1px solid var(--hairline);border-radius:var(--r-m)}
.video-slot video,.video-slot img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.video-une{margin-top:var(--space-7)}
/* Pastille de durée, en haut à droite : les contrôles natifs occupent le bas, et ils
   affichent 0:00 tant que le lecteur n'a rien chargé (preload="none"). Le temps vient de
   DUREES, pas du fichier. Transparente aux clics, pour ne pas manger le bouton de permutation. */
.video-duree{position:absolute;top:var(--space-3);right:var(--space-3);z-index:3;pointer-events:none;
  padding:.125rem .375rem;border-radius:var(--r-s);background:rgba(10,10,11,.72);
  font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:var(--ls-label);
  font-variant-numeric:tabular-nums;color:var(--text)}
.video-slot video+.todo-box{pointer-events:none;background:rgba(10,10,11,.35);justify-content:flex-start;padding-top:var(--space-3)}
.live-clips .todo-box small{display:none}
/* Captation live : grande vidéo + titre, 4 vidéos, lien vers la galerie */
/* Captation live : la grande vidéo tient toute la largeur du wrap, son bord droit tombe donc
   sur celui du 4e petit emplacement. Les 5 emplacements ont le même balisage, site.js permute
   les <figure> ; la légende de celle qui est en grand s'affiche sous le H2, pas dans la figure. */
.live-legende{margin:var(--space-3) 0 0}
.live-main figure,.live-clips figure{margin:0;transition:opacity .2s}
.live-main figcaption{display:none}
.live-echange{opacity:0}
.live-clips .video-slot{transition:filter .2s}
.live-clips figure:hover .video-slot{filter:brightness(1.12)}
.live-swap{position:absolute;inset:0;z-index:2;width:100%;height:100%;padding:0;border:0;background:none;cursor:pointer;-webkit-appearance:none;appearance:none}
.live-swap:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.live-clips{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:var(--space-5);margin-top:var(--space-5)}
.live-clips figcaption{font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text-subtle);margin-top:var(--space-3)}
.live-more{margin:var(--space-6) 0 0;font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase}
@media(max-width:980px){.live-clips{grid-template-columns:1fr 1fr}}
.video-slot .empty{position:absolute;inset:0;display:grid;place-items:center;font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:#4a4a50}

/* Marquee */
.marquee{padding:var(--space-9) 0;overflow:hidden;border-top:1px solid var(--hairline);border-bottom:1px solid var(--hairline)}
.marquee ul{display:flex;gap:calc(var(--space-9) * 2);list-style:none;margin:0;padding:0;white-space:nowrap;width:max-content;animation:logoMarquee 32s linear infinite}
.marquee:hover ul{animation-play-state:paused}
.marquee li{font-size:1.375rem;font-weight:600;color:var(--text);opacity:.55;letter-spacing:.04em}
/* Fond sur la bande elle-même : l'animation (transform) fait de la liste un groupe isolé, et
   mix-blend-mode ne fond un logo que dans le fond de ce groupe. Même raison pour l'opacité,
   portée par l'image et non par le <li>, qui isolerait chaque logo. */
.marquee ul{align-items:center;background:var(--void)}
.marquee li.logo-client{opacity:1}
.marquee li.logo-client img{opacity:.7}
/* Logo de marque, passé en blanc quelle que soit sa couleur d'origine. Tailles à surface égale :
   la hauteur vaut 4rem divisé par la racine du ratio (--arn, posé par le build), donc un logo
   carré (Rituals) monte plus haut qu'un logo en longueur (Accenture), et aucun n'écrase l'autre.
   Bornes : 1.5rem à 3.5rem de haut, 10rem de large. */
.marquee li.logo-client img{height:clamp(1.5rem,calc(4rem / sqrt(var(--arn,3))),3.5rem);width:auto;max-width:10rem;object-fit:contain}
/* Rendu par logo, choisi dans LOGOS_RENDU (content.py). blanc : silhouette blanche. clair : gris,
   et mix-blend-mode:screen efface ce qui est plus sombre que le fond (un fond plein, des
   lettres en réserve). inverse : même chose pour un logo noir sur blanc. */
.marquee li.blanc img{filter:brightness(0) invert(1)}
.marquee li.clair img{filter:grayscale(1) contrast(1.3);mix-blend-mode:screen}
.marquee li.inverse img{filter:grayscale(1) invert(1) contrast(1.3);mix-blend-mode:screen}
@keyframes logoMarquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media(prefers-reduced-motion:reduce){.marquee ul{animation:none}}

/* Timeline */
.timeline{list-style:none;margin:0;padding:0;position:relative;--tl-x:2rem}
.timeline .txt p{max-width:34rem}   /* 91 caractères par ligne mesurés, 64 après */
.timeline li{display:grid;grid-template-columns:4rem 1fr 18.75rem;column-gap:var(--space-7);padding:0 0 var(--space-9);position:relative}
.timeline li::before{content:"";position:absolute;left:1.9375rem;top:.75rem;bottom:0;width:1px;background:var(--hairline)}
.timeline li:last-child::before{display:none}
.timeline .num{font-size:2.125rem;font-weight:200;color:rgba(255,255,255,.5);line-height:1;position:relative;background:var(--void);padding-bottom:var(--space-2);text-align:center}
.timeline .dot{display:block;width:.5625rem;height:.5625rem;border-radius:50%;background:var(--accent);box-shadow:0 0 0 .3125rem rgba(255,54,68,.14);margin:var(--space-3) auto 0}
.timeline .meta{font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text-subtle);margin-bottom:var(--space-2)}
.timeline .tags{display:flex;flex-wrap:wrap;gap:var(--space-2);margin-top:var(--space-3)}
.timeline .tags span{font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text-muted);border:1px solid var(--hairline);border-radius:var(--r-pill);padding:var(--space-2) var(--space-3)}
.timeline .pic{border-radius:var(--r-m);overflow:hidden;height:13.5rem;background:var(--tile1)}
.timeline .pic img{width:100%;height:100%;object-fit:cover}
@media(max-width:980px){.timeline li{grid-template-columns:3rem 1fr}.timeline .pic{grid-column:2;margin-top:var(--space-5);height:12.5rem}.timeline li::before{left:1.4375rem}.timeline{--tl-x:1.5rem}}
/* Timeline : progression au scroll. site.js pose .tl-on et écrit --tl-start, --tl-len (px) et --progress (0 à 1).
   Sans JS, rien ne s'applique : la timeline reste allumée avec son trait d'origine. */
.timeline.tl-on li::before{display:none}
.timeline.tl-on::before,.timeline.tl-on::after{content:"";position:absolute;z-index:0;top:var(--tl-start,0);height:var(--tl-len,0);pointer-events:none}
.timeline.tl-on::before{left:calc(var(--tl-x) - .5px);width:1px;background:var(--hairline)}
.timeline.tl-on::after{left:calc(var(--tl-x) - 1px);width:2px;background:var(--accent);transform:scaleY(var(--progress,0));transform-origin:top}
.timeline.tl-on li{z-index:1}
/* Une étape en attente s'éteint par la COULEUR de son texte, pas par une opacité posée sur
   son conteneur : une opacité délave aussi les titres et les images, et fait tomber le
   contraste sous le seuil sans qu'aucune couleur ne le dise. */
.timeline.tl-on .txt{transition:color .5s ease}
.timeline.tl-on .txt h3{color:var(--text-subtle);transition:color .5s ease}
.timeline.tl-on .txt p{color:var(--text-subtle);transition:color .5s ease}
.timeline.tl-on .num{align-self:start;color:var(--text-subtle);transition:color .5s ease}
.timeline.tl-on .pic{filter:brightness(.45);transition:filter .5s ease}
.timeline.tl-on .dot{transition:transform .5s ease}
.timeline.tl-on li.is-active .txt h3{color:var(--text-title)}
.timeline.tl-on li.is-active .txt p{color:var(--text-muted)}
.timeline.tl-on li.is-active .num{color:var(--text)}
.timeline.tl-on li.is-active .pic{filter:brightness(1)}
.timeline.tl-on li.is-active .dot{transform:scale(1.35)}
.timeline.tl-still .txt,.timeline.tl-still .num,.timeline.tl-still .pic,.timeline.tl-still .dot{transition:none}
@media(prefers-reduced-motion:reduce){.timeline.tl-on .txt,.timeline.tl-on .num,.timeline.tl-on .pic,.timeline.tl-on .dot{transition:none}}

/* Feedback */
.quote{border-left:2px solid var(--accent);padding:var(--space-2) 0 var(--space-2) var(--space-6);max-width:51.25rem;margin:0 0 var(--space-8)}
.quote p{font-size:var(--fs-lead);line-height:1.6;color:var(--text);font-style:italic}
.quote cite{display:block;font-style:normal;font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text-subtle);margin-top:var(--space-3)}
.fb{position:relative;display:block;border-radius:var(--r-m);overflow:hidden;aspect-ratio:9/12;border:1px solid var(--hairline);background:linear-gradient(160deg,#1c1c1f 0%,#0c0c0d 100%);color:inherit;transition:border-color .2s,transform .2s}
.fb:hover{border-color:rgba(255,255,255,.3);transform:translateY(-.1875rem)}
.fb .play{position:absolute;top:50%;left:50%;width:var(--space-9);height:var(--space-9);margin:calc(var(--space-9) / -2) 0 0 calc(var(--space-9) / -2);border-radius:50%;border:1px solid var(--hair-contrast);display:grid;place-items:center;background:rgba(10,10,11,.5)}
.fb .play svg{width:1.125rem;height:1.125rem;fill:#fff;margin-left:var(--space-1)}
.fb .dur{position:absolute;top:.875rem;right:.875rem;font-size:var(--fs-label);letter-spacing:var(--ls-label);color:var(--text-muted)}
.fb .meta{position:absolute;left:1.125rem;right:1.125rem;bottom:1.125rem}
.fb .meta b{display:block;font-size:var(--fs-body-sm);font-weight:var(--fw-label);letter-spacing:var(--ls-h3);text-transform:uppercase;color:var(--text)}
.fb .meta span{font-size:var(--fs-label);color:var(--text-subtle)}

/* Case studies */
.cases{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-5)}
.cases article{border:1px solid var(--hairline);border-radius:var(--r-m);padding:var(--space-7);background:var(--tile1)}
.cases article h3{color:var(--accent);margin-bottom:var(--space-3)}
.cases p{font-size:var(--fs-body-sm)}
@media(max-width:800px){.cases{grid-template-columns:1fr}}

/* Gallery */
.gallery{columns:3 17.5rem;column-gap:var(--space-3)}
.gallery figure,.gallery .gv{margin:0 0 var(--space-3);break-inside:avoid;position:relative;border-radius:var(--r-s);overflow:hidden;background:var(--tile1);cursor:pointer}
.gallery img{width:100%;height:auto;transition:transform .5s;filter:saturate(.85) brightness(.92)}
.gallery figure:hover img{transform:scale(1.03);filter:none}
.gallery figcaption{position:absolute;left:.875rem;bottom:.75rem;font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text);text-shadow:0 1px .5rem rgba(0,0,0,.8)}
.gallery .gv{aspect-ratio:16/9}
.gallery .gv img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.gallery .gv .play{position:absolute;top:50%;left:50%;width:var(--space-9);height:var(--space-9);margin:calc(var(--space-9) / -2) 0 0 calc(var(--space-9) / -2);border-radius:50%;border:1px solid var(--hair-contrast);display:grid;place-items:center;background:rgba(10,10,11,.5)}
.gallery .gv .play svg{width:1.125rem;height:1.125rem;fill:#fff;margin-left:var(--space-1)}
.gallery .gv .tag{position:absolute;top:.75rem;left:.875rem;font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text);border:1px solid var(--hair-contrast);padding:var(--space-1) var(--space-2);border-radius:var(--r-pill)}

/* Forms */
form.contact{display:grid;gap:var(--space-6);max-width:var(--measure)}
label{display:block;font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text-muted);margin-bottom:var(--space-2)}
input,select,textarea{width:100%;background:transparent;border:none;border-bottom:1px solid var(--hair-contrast);color:var(--text);font-family:inherit;font-size:var(--fs-body);padding:var(--space-3) 0;font-weight:var(--fw-body);border-radius:0}
/* Au focus, le filet passe en rouge et s'épaissit (1 px de plus en ombre) : visible sans anneau. */
input:focus,select:focus,textarea:focus{outline:none;border-bottom-color:var(--accent);box-shadow:0 1px 0 0 var(--accent)}
select{color-scheme:dark;-webkit-appearance:none;appearance:none;padding-right:var(--space-6);background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23C6C6CC' stroke-width='1.6'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right center/1rem}
/* Safari ignore le padding d'un select natif et réduit un champ date vide : sans hauteur
   minimale, le premier faisait 27 px et le second 24, contre 48 pour les autres champs. */
input,select{min-height:3rem}
input[type=date]::-webkit-date-and-time-value{text-align:left}
select option{background:#141416;color:var(--text)}
.two-col{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-6)}
@media(max-width:600px){.two-col{grid-template-columns:1fr}}
.hp{position:absolute;left:-9999px;opacity:0;height:0;overflow:hidden}
.contact-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:var(--space-9);align-items:start}
@media(max-width:900px){.contact-grid{grid-template-columns:1fr}}
/* Message d'erreur du formulaire, posé par contact.php via ?err= et révélé par site.js. */
.form-err{border:1px solid var(--accent);border-radius:var(--r-m);padding:var(--space-4) var(--space-5);margin-bottom:var(--space-7);color:var(--text)}
.contact-channels .k{font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text-subtle);margin-bottom:var(--space-1)}
.contact-channels a:not(.btn-wa){display:block;font-size:var(--fs-body);font-weight:var(--fw-body);color:var(--text);padding:var(--space-4) 0;border-top:1px solid var(--hairline)}
.contact-channels a:not(.btn-wa):hover{color:var(--accent)}
/* Bouton WhatsApp de la page Contact : celui de la plaquette (pilule monochrome, icône à
   gauche), aux mesures des boutons du site. Pleine largeur de la colonne à toute largeur. */
.contact-channels .btn-wa{display:flex;width:100%;gap:var(--space-3);margin-bottom:var(--space-8);transition:color .2s,border-color .2s,background-color .2s}
.btn-wa svg{width:1rem;height:1rem;fill:currentColor;flex:none}

/* CTA band */
.cta-band{text-align:center;padding:var(--section-y) var(--gutter);border-top:1px solid var(--hairline)}
.cta-band h2{margin-bottom:var(--space-8)}

/* Footer */
/* Le footer garde sa gouttière et ses colonnes s'alignent sur le contenu des .wrap : même
   largeur utile (--wrap moins deux gouttières), donc le logo du footer tombe sous celui de la nav. */
footer{background:var(--void);border-top:1px solid var(--hairline);padding:var(--block-y) var(--gutter) var(--space-8)}
/* La marque à gauche, le contact calé sur le bord droit du contenu : en deux moitiés égales,
   la colonne Contact flottait au milieu de la page. */
footer .cols{max-width:calc(var(--wrap) - 2 * var(--gutter));margin:0 auto;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--space-9)}
@media(max-width:900px){footer .cols{grid-template-columns:1fr}}
footer img{width:10.5rem;height:auto}
footer .tagline{font-size:var(--fs-body-sm);letter-spacing:normal;color:var(--text-subtle);line-height:1.6;margin-top:var(--space-6)}
footer .social{display:flex;gap:var(--space-3);margin-top:var(--space-6);flex-wrap:wrap}
footer .social a{width:var(--tap);height:var(--tap);display:grid;place-items:center;border:1px solid var(--hairline);border-radius:50%;color:var(--text-muted);transition:color .2s,border-color .2s}
footer .social svg{width:1.25rem;height:1.25rem}
footer .social a:hover{color:var(--accent);border-color:var(--accent)}
footer .social a,footer .legal a,footer .contact-col a{position:relative}
footer .legal a::after,footer .contact-col a::after{content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:100%;min-width:var(--tap);height:var(--tap)}
footer .contact-col{display:grid;gap:var(--space-3);min-width:12.5rem;align-content:start}
footer .contact-col .k{font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text);margin-bottom:var(--space-2)}
footer .contact-col a{color:var(--text-muted);font-size:var(--fs-body-sm)}
footer .contact-col a:hover{color:var(--accent)}
footer .legal{max-width:calc(var(--wrap) - 2 * var(--gutter));margin:var(--space-9) auto 0;padding-top:var(--space-6);border-top:1px solid var(--hairline);display:flex;flex-wrap:wrap;gap:var(--space-6);justify-content:space-between;font-size:var(--fs-label);color:var(--text-subtle)}
footer .legal a{color:var(--text-subtle)}
footer .legal a:hover{color:var(--accent)}

/* Teasers vidéo
   ---------------------------------------------------------------------------
   Repris de la plaquette, sur la bande partagée ci-dessous : un rang qui défile, toutes les
   vignettes à la même hauteur, chacune à son ratio réel. Une vidéo verticale est donc étroite
   et une horizontale large, sans recadrage ni bande noire.
   Le titre suit sa vignette, à sa largeur, et les pieds ne s'alignent pas : c'est la
   disposition de la plaquette. D'où --arn, le ratio en nombre, qui donne sa largeur à
   l'article, sans quoi un titre long l'élargirait. */
.teasers{--bandh:21.875rem}
.teaser-bande{padding-bottom:var(--space-2)}
.teaser{width:calc(var(--bandh) * var(--arn,1.777));margin:0}
.teaser-vue{position:relative;display:block;height:var(--bandh);aspect-ratio:var(--ar,16/9);
 border-radius:var(--r-m);overflow:hidden;background:var(--tile1);
 border:1px solid var(--hairline);transition:border-color .2s,transform .2s}
.teaser-vue img,.teaser-vue video{position:absolute;inset:0;width:100%;height:100%;
 object-fit:cover;border-radius:inherit}
.teaser-vue video{opacity:0;transition:opacity .25s}
.teaser-vue.is-on video{opacity:1}
.teaser-vue:hover{border-color:var(--hair-strong);transform:translateY(-.125rem)}
.teaser-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:2;
 width:3.25rem;height:3.25rem;display:grid;place-items:center;border-radius:50%;
 background:rgba(255,255,255,.14);backdrop-filter:blur(.5rem);-webkit-backdrop-filter:blur(.5rem);
 border:1px solid var(--hair-contrast);transition:opacity .2s,background .2s}
.teaser-play svg{width:1.25rem;height:1.25rem;margin-left:.125rem;fill:var(--text)}
.teaser-vue.is-on .teaser-play{opacity:0}
.teaser-vue:hover .teaser-play{background:rgba(255,255,255,.24)}
.teaser-titre{font-size:var(--fs-body-sm);font-weight:var(--fw-body);letter-spacing:normal;
 text-transform:none;line-height:1.4;color:var(--text-muted);margin:var(--space-3) 0 0}
@media(max-width:900px){
 .teasers{--bandh:16.25rem}
 .teaser-play{width:2.75rem;height:2.75rem}
}
@media(prefers-reduced-motion:reduce){.teaser-vue,.teaser-vue video,.teaser-play{transition:none}}

/* Modale et fiches
   ---------------------------------------------------------------------------
   Un seul composant pour toutes les cartes du site. La fiche vit dans le HTML
   (div.modal-src, masquée) et site.js la clone ici à l'ouverture.
   En haut, la bande de médias ; en dessous, le texte. La bande garde une hauteur
   fixe : tous les médias y sont à la même hauteur, chacun à sa largeur naturelle. */
.modal-bg{position:fixed;inset:0;z-index:60;background:rgba(0,0,0,.78);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);display:flex;align-items:center;justify-content:center;padding:var(--space-6)}
.modal-bg[hidden]{display:none}
/* Jamais plein écran, à aucune largeur : la marge de .modal-bg et le rayon restent visibles.
   La modale ne défile pas elle-même : c'est .fiche qui défile, la croix ne bouge donc jamais. */
.modal{position:relative;display:flex;flex-direction:column;width:min(77.5rem,100%);max-height:90vh;max-height:90dvh;overflow:hidden;background:var(--card);border:1px solid var(--hair-strong);border-radius:var(--r-l);padding:var(--space-7)}
.modal .x{position:absolute;top:.25rem;right:.375rem;z-index:4;width:var(--tap);height:var(--tap);display:grid;place-items:center;padding:0;background:none;border:none;color:var(--text);font-size:1.875rem;line-height:1;cursor:pointer;font-family:inherit}
.modal .x:hover{color:var(--accent)}

/* 1.875rem = 30 px entre la bande et le texte. */
.fiche{flex:1;min-height:0;display:flex;flex-direction:column;gap:1.875rem;overflow-y:auto;overscroll-behavior:contain}

/* Bande de médias. --bandh : 400 px sur un écran de 900 px de haut, bornée à 300 et 440.
   Chaque média prend toute la hauteur et tire sa largeur de son ratio réel (--ar, écrit par
   build.py d'après le fichier) : aucun recadrage, aucune bande noire, aucune déformation. */
/* La bande est un composant à part entière, partagé par les fiches et par les teasers : un
   rang qui défile, des cases toutes à la même hauteur (--bandh) et chacune à SON ratio (--ar),
   des flèches, des fondus latéraux et des points, tous pilotés par site.js. Ce qui change d'un
   emploi à l'autre : la hauteur, ce qu'il y a dans la case, et ce qui suit dessous. */
[data-bande-zone]{position:relative}
[data-bande]{display:flex;align-items:flex-start;gap:.75rem;overflow-x:auto;overflow-y:hidden;
 scroll-snap-type:x mandatory;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;
 scrollbar-width:none}
[data-bande]::-webkit-scrollbar{display:none}
[data-bande] > *{flex:0 0 auto;scroll-snap-align:start}

.fiche-gal{--bandh:clamp(18.75rem,44vh,27.5rem)}
.fmedia{position:relative;height:var(--bandh);aspect-ratio:var(--ar,16/9);margin:0;padding:0;border:0;background:var(--tile1);border-radius:var(--r-l);overflow:hidden;scroll-snap-align:start;cursor:zoom-in}
.fmedia.is-video,.fmedia.is-todo{cursor:default}
/* Le média remplit sa case : la case ayant exactement son ratio, cover ne recadre rien. */
.fmedia img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;border-radius:inherit}
.fmedia.is-todo .todo-box{position:absolute;inset:0;border-radius:inherit}

/* Vidéo : dernier média de la bande, affichée avec son poster. Le lecteur est posé par-dessus
   et ne se montre qu'à la lecture. contain plutôt que cover : si le mp4 n'a pas exactement le
   ratio du poster, on préfère une bande noire dans le lecteur à une image rognée. */
.fmedia video{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;background:#000;border-radius:inherit;opacity:0;pointer-events:none;transition:opacity .2s}
.fmedia.is-playing video{opacity:1;pointer-events:auto}
.fmedia.is-playing img,.fmedia.is-playing .fplay{opacity:0;pointer-events:none}
/* Aperçu au survol (site.js) : la vidéo passe devant son poster, muette ; un clic la lance. */
.fmedia.is-apercu{cursor:pointer}
.fmedia.is-apercu video{opacity:1}
.fmedia.is-apercu .fplay{opacity:0}
.fplay{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:2;width:4rem;height:4rem;display:grid;place-items:center;padding:0;border-radius:50%;background:rgba(255,255,255,.14);backdrop-filter:blur(.5rem);-webkit-backdrop-filter:blur(.5rem);border:1px solid var(--hair-contrast);cursor:pointer;transition:background .2s,opacity .2s}
.fplay svg{width:1.5rem;height:1.5rem;margin-left:.125rem;fill:#fff}
.fplay:hover{background:rgba(255,255,255,.24)}

/* Fondu latéral : signale qu'il y a une suite. Posé par site.js (can-prev / can-next) selon
   la position de défilement, donc absent quand tout tient dans la largeur. */
[data-bande-zone]::before,[data-bande-zone]::after{content:"";position:absolute;top:0;height:var(--bandh);width:5rem;z-index:2;pointer-events:none;opacity:0;transition:opacity .2s}
[data-bande-zone]::before{left:0;background:linear-gradient(to right,var(--card),var(--card-0))}
[data-bande-zone]::after{right:0;background:linear-gradient(to left,var(--card),var(--card-0))}
[data-bande-zone].can-prev::before,[data-bande-zone].can-next::after{opacity:1}

.fnav{position:absolute;top:calc(var(--bandh) / 2);transform:translateY(-50%);z-index:3;width:2.75rem;height:2.75rem;display:grid;place-items:center;padding:0;border-radius:50%;background:rgba(255,255,255,.14);backdrop-filter:blur(.5rem);-webkit-backdrop-filter:blur(.5rem);border:1px solid var(--hair-contrast);cursor:pointer;transition:background .2s}
.fnav[hidden]{display:none}
.fnav.prev{left:.75rem}
.fnav.next{right:.75rem}
.fnav svg{width:1.25rem;height:1.25rem;fill:none;stroke:#fff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.fnav:hover{background:rgba(255,255,255,.24)}

.fdots{display:flex;justify-content:center;gap:.375rem;margin-top:var(--space-3)}
.fdots span{width:.375rem;height:.375rem;border-radius:var(--r-pill);background:rgba(255,255,255,.28);transition:width .2s,background .2s}
.fdots span.is-on{width:1.125rem;background:#fff}

/* Texte sous la bande. À partir de 3 rubriques et en grand écran, il passe sur deux colonnes ;
   le surtitre et le titre restent en pleine largeur au-dessus. */
.fiche-txt{min-width:0}
.fiche-head{margin-bottom:var(--space-5)}
.modal .mmeta{font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--accent);margin:0 0 var(--space-3)}
.modal h3{font-size:var(--fs-h3);margin:0}
.fiche-body{max-width:62ch}
.fiche-txt.cols .fiche-body{max-width:none;columns:2;column-gap:var(--space-8)}
.sect{break-inside:avoid;margin-bottom:var(--space-5)}
.sect:last-child{margin-bottom:0}
.modal .lab{font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text-subtle);margin:0 0 var(--space-1)}
.modal p{font-size:var(--fs-body-sm);margin:0}
.modal .todo-box{border-radius:var(--r-l)}

/* Tablette et mobile : même modale, mêmes marges, mêmes coins. Bande plus basse, texte sur
   une seule colonne, l'ensemble défile dans la modale et la croix reste en place. */
@media(max-width:900px){
 .modal-bg{padding:var(--space-4)}
 .modal{padding:var(--space-5);max-height:90vh;max-height:90dvh}
 .fiche{gap:var(--space-6)}
 .fiche-gal{--bandh:15rem}
 /* Sous 900 px, la bande est plus étroite qu'une photo paysage (360 px pour un 3:2 haut de
    240) : en snap obligatoire, le défilement ne peut se poser qu'au début d'un média et les
    derniers pixels de celui-ci deviennent inatteignables. En proximité, le geste s'arrête où
    il veut et la photo se voit en entier, le snap ne servant plus qu'à recaler. */
 .fband{scroll-snap-type:x proximity}
 .fiche-txt.cols .fiche-body{columns:1;max-width:62ch}
 .fnav{width:2.25rem;height:2.25rem}
 /* 36 px de visuel, 44 de zone. */
 .fnav::before{content:"";position:absolute;inset:-.25rem}
 .fplay{width:3.25rem;height:3.25rem}
}
@media(prefers-reduced-motion:reduce){
 .fband{scroll-behavior:auto}
 .fmedia video,.fiche-gal::before,.fiche-gal::after,.fdots span{transition:none}
}
body.no-scroll{overflow:hidden}
/* Contenu des fiches dans le flux HTML : caché à l'écran, lisible par les robots */
.modal-src{display:none}

/* Lightbox : galerie du site, et photo d'une fiche ouverte en plein écran par-dessus la modale */
.lightbox{position:fixed;inset:0;z-index:70;background:rgba(0,0,0,.92);display:flex;align-items:center;justify-content:center;padding:var(--space-6)}
.lightbox[hidden]{display:none}
.lightbox img,.lightbox video{max-width:min(68.75rem,100%);max-height:88vh;max-height:88dvh;width:auto;height:auto;object-fit:contain;border-radius:var(--r-s)}
.lightbox .x{position:absolute;top:max(.5rem,env(safe-area-inset-top));right:max(1rem,env(safe-area-inset-right));width:var(--tap);height:var(--tap);display:grid;place-items:center;padding:0;background:none;border:none;color:var(--text);font-size:2.125rem;line-height:1;cursor:pointer;font-family:inherit}
.lightbox .nav{position:absolute;top:50%;transform:translateY(-50%);width:2.75rem;height:2.75rem;display:grid;place-items:center;padding:0;border-radius:50%;background:rgba(255,255,255,.14);backdrop-filter:blur(.5rem);-webkit-backdrop-filter:blur(.5rem);border:1px solid var(--hair-contrast);cursor:pointer}
.lightbox .nav[hidden]{display:none}
.lightbox .nav.prev{left:var(--space-6)}
.lightbox .nav.next{right:var(--space-6)}
.lightbox .nav svg{width:1.25rem;height:1.25rem;fill:none;stroke:#fff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.lightbox .nav:hover{background:rgba(255,255,255,.24)}
.lightbox .cap{position:absolute;bottom:1.25rem;left:0;right:0;text-align:center;font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text-muted)}

/* Écran bas (téléphone en paysage, 320 à 430 px de haut) : la nav et la barre du sélecteur
   prenaient 124 px, 39 % de l'écran sur un iPhone SE. La bande d'une fiche suit la hauteur,
   sinon le texte n'apparaît qu'après défilement. */
@media(max-height:500px) and (orientation:landscape){
 :root{--nav-h:3.5rem}
 .site-nav .logo img{width:5.5rem}
 .seg-bar{height:2.5rem}
 .fiche-gal{--bandh:42dvh}}

/* Legal pages */
.legal-page{max-width:51.25rem}
.legal-page h2{font-size:var(--fs-h3);letter-spacing:var(--ls-h3);margin:var(--space-8) 0 var(--space-3)}
.legal-page p{margin-bottom:var(--space-3)}
.legal-page .todo{color:var(--accent)}
/* [À COMPLÉTER] (build.py) : textes en rouge, cadre rayé à la place d'une photo absente */
.todo{color:var(--accent)}
.todo-box{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-4);text-align:center;font-size:.75rem;letter-spacing:.14em;color:var(--accent);border:1px dashed var(--accent);background:repeating-linear-gradient(135deg,#141416 0 .75rem,#19191c .75rem 1.5rem)}
.todo-box small{font-size:var(--fs-label);letter-spacing:.02em;color:var(--text-subtle);word-break:break-all}

/* Reveal on scroll */
.rv{opacity:0;transform:translateY(1.375rem);transition:opacity .9s cubic-bezier(.22,.61,.36,1),transform .9s cubic-bezier(.22,.61,.36,1)}
.rv.in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){.rv{opacity:1;transform:none;transition:none}}
@media(prefers-reduced-motion:reduce){.live-main figure,.live-clips figure,.live-clips .video-slot{transition:none}}
.no-js .rv{opacity:1;transform:none}
