/* ==========================================================================
   lechaftoisbo.com — feuille de style principale
   Consolidée depuis le prototype (Claude Design canvas) le 21/09/2026.
   Tokens et composants dédupliqués depuis Main/Projets/ProjetDetail/APropos/Contact.
   Breakpoint desktop -> mobile : 860px (sauf grille Projets : 1024px, 3->2 colonnes).
   ========================================================================== */

/* ---- Design tokens ---- */
:root{
  --void:#000000; --obsidian:#0e0f11; --carbon:#141617; --graphite:#1d2023; --slate:#21223a;
      --ash:#303438; --steel:#3a3d40; --fog:#61626b; --smoke:#8d8d96; --cloud:#a1a1aa; --silver:#cfcfd3;
      --bone:#999999; --paper:#ffffff; --offwhite:#fffef7; --violet:#5741e8; --live-wire:#d2e841; --circuit-teal:#00cbaa;
      --canvas:var(--void); --surface:var(--obsidian); --surface-2:var(--carbon); --spotlight:var(--slate);
      --border-strong:var(--steel); --border-soft:var(--ash); --ink:var(--paper); --body:var(--silver);
      --ink-dim:var(--cloud); --ink-faint:var(--bone); --ink-faintest:var(--fog);
      
      /* Couleurs de discipline (01/10/2026, choix de Boris) : Graphic Design =
         silver (neutre du nuancier), Motion Design = teal (inverse de l'etat
         precedent). --acc-*-text = couleur du TEXTE des pastilles : identique
         a la couleur de discipline, sauf UX/UI, eclairci (violet + 35% de
         blanc, #9284f0) pour l'accessibilite : le violet pur n'avait que
         2.9:1 de contraste sur la pastille sombre (seuil WCAG 4.5:1), contre
         5.9:1 maintenant (6.8:1 sur noir). Le point de couleur reste violet pur. */
      --acc-graphicdesign:var(--silver); --acc-motiondesign:var(--circuit-teal); --acc-uxui:var(--violet); --acc-photo:var(--live-wire); --acc-graphicdesign-text:var(--acc-graphicdesign); --acc-motiondesign-text:var(--acc-motiondesign); --acc-uxui-text:#9284f0; --acc-photo-text:var(--acc-photo);

      /* Systeme typo Switzer (30/09, refonte demandee par Boris en reference a
         creativegiants.art / "what we do") : une seule famille, 2 graisses —
         300 pour tout le display/headline (meme aux grandes tailles : c'est
         le choix signature, Archivo 900 est abandonne), 400 pour le corps de
         texte, les metadonnees et les controles UI (ce qui remplace aussi
         Space Mono partout, lui aussi abandonne). Chargee via Fontshare
         (Switzer n'est pas sur Google Fonts) avec Inter en repli reel si
         Fontshare est indisponible — voir le <link> dans head() de
         build_pages.py. */
      --font-switzer:'Switzer','Inter',Arial,sans-serif;
}

*{box-sizing:border-box;}

/* ---- Base ---- */
body{margin:0; background:var(--canvas); color:var(--body); font-family:var(--font-switzer); font-size:17px; line-height:1.5;}
/* Barre de defilement masquee sur tout le site (01/10/2026, Boris) : la page
   reste defilable (molette, trackpad, clavier, tactile), seule la barre est
   cachee. Effet secondaire voulu : a l'ouverture du menu (body en
   overflow:hidden), la barre disparaissait et decalait le bouton Menu de sa
   largeur — plus aucun decalage. Aussi applique au menu plein ecran. */
html, .menu-overlay{scrollbar-width:none; -ms-overflow-style:none;}
html::-webkit-scrollbar, .menu-overlay::-webkit-scrollbar{display:none; width:0; height:0;}
a{color:var(--cloud); text-decoration:underline;}
a:hover{color:var(--ink);}
.mono{font-family:var(--font-switzer);}
/* width:100% ajoute (30/09 soir) : necessaire pour que .wrap continue de
   s'etendre sur toute la largeur disponible (puis se centre/plafonne a
   1440px comme d'habitude) une fois utilisee DANS un conteneur flex —
   .hero-bottom-meta est flex (display:flex; flex-direction:column), et un
   enfant flex sans width explicite se dimensionne par defaut a son contenu
   (shrink-to-fit) plutot qu'a 100% du conteneur, ce qui cassait le
   centrage de .wrap et donc l'alignement de "Toulouse, France" avec le
   reste du site. Sans effet ailleurs (.wrap est presque partout dans un
   contexte de bloc normal, ou un enfant est deja a 100% de large par
   defaut — cet ajout ne fait que le rendre explicite). */
.wrap{max-width:1440px; width:100%; margin:0 auto;}
.pad{padding-left:80px; padding-right:80px;}
.eyebrow{font-family:var(--font-switzer); font-size:12px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint); margin:0 0 16px;}
.h1{font-family:var(--font-switzer); font-weight:300; color:var(--ink); margin:0; letter-spacing:-1px;}
.h2{font-family:var(--font-switzer); font-weight:300; color:var(--ink); margin:0; font-size:40px; letter-spacing:-0.021em;}
.h3{font-family:var(--font-switzer); font-weight:300; color:var(--ink); margin:0; font-size:20px; letter-spacing:-0.018em;}

/* ---- Header / nav ---- */
/* Pas de fond propre : le header est sticky mais transparent, il laisse voir
   ce qu'il y a juste derriere lui — le bandeau blanc du hero sur l'accueil
   (voir .hero-stage plus bas, qui remonte sous le header via margin-top
   negatif), le fond sombre du site partout ailleurs. La pastille noire du
   logo et le bouton Menu (voir plus bas) sont eux-memes opaques et restent
   donc lisibles dans les deux contextes sans changement. */
header.site{position:sticky; top:0; z-index:50; display:flex; align-items:center; justify-content:space-between; padding:20px 80px;}
.wordmark{display:flex; align-items:center; color:var(--ink); text-decoration:none;}
.wordmark svg{height:28px; width:auto; display:block;}
header.site .wordmark{width:44px; height:44px; border-radius:50%; justify-content:center; background:var(--void); border:1px solid var(--border-strong); color:var(--paper); flex:none;}
header.site .wordmark svg{height:18px; width:auto; display:block;}
.menu-btn{display:flex; align-items:center; gap:12px; background:var(--void); border:1px solid var(--border-strong); border-radius:999px; padding:10px 20px; cursor:pointer; color:var(--paper); font-family:var(--font-switzer); font-size:12px; letter-spacing:1px; text-transform:uppercase;}
.menu-btn:hover{border-color:var(--ink-dim);}
.lang{font-family:var(--font-switzer); font-size:12px; color:var(--ink-faint); letter-spacing:1px;}

/* ---- Bandeau clair (.light-band) ---- */
.light-band{background:var(--offwhite); padding-top:0; padding-bottom:0; color:var(--ink); --ink:var(--void); --ink-dim:var(--carbon); --ink-faint:var(--steel); --body:var(--graphite); --border-soft:var(--bone);}
.light-band .marquee-logo img{filter:brightness(0) !important;}
/* Pathe (01/10/2026) : brightness(0) transformait la bulle jaune ET le texte
   blanc "PATHE" / "!" en un meme aplat noir -> texte illisible. Version
   dediee logo-pathe-mono.svg (jaune -> noir, blanc conserve) affichee sans
   filtre : la bulle devient grise et le texte reste en reserve. */
.light-band .marquee-logo img.logo-knockout{filter:none !important;}

/* ---- Boutons ---- */
.get-touch-grid{display:grid; grid-template-columns:260px 1fr; gap:64px; align-items:start;}
.about-teaser-grid{display:grid; grid-template-columns:1fr 1.4fr; gap:64px; align-items:center;}
.about-grid{display:grid; grid-template-columns:1fr 1.4fr; gap:64px; align-items:start;}
/* Titre de la page About en citation (01/10/2026) : attribution en petit,
   a cote du titre, alignee sur sa ligne de base ; passe a la ligne si besoin. */
.about-quote{display:flex; align-items:baseline; flex-wrap:wrap; column-gap:16px; row-gap:4px; margin-bottom:24px;}
.about-quote .quote-by{font-family:var(--font-switzer); font-size:14px; letter-spacing:0.5px; color:var(--ink-faint);}
/* Attribution dans un eyebrow (page Projets, Peter Venkman) : casse normale,
   plus discrete que la citation en capitales. */
.eyebrow .eyebrow-by{text-transform:none; letter-spacing:0.5px; color:var(--ink-faintest); margin-left:6px; white-space:nowrap;}
.contact-grid{display:grid; grid-template-columns:1fr 1.2fr; gap:80px;}
/* Page Contact (01/10/2026, Boris) : le haut du formulaire (label "Name/Nom")
   aligne sur le haut des capitales du titre de la colonne de gauche, et non
   plus sur l'eyebrow "Contact" au-dessus. 46px = ecart mesure entre le haut
   de l'encre du label et celui des capitales du titre (desktop uniquement :
   sur mobile les deux colonnes s'empilent). */
.contact-grid > form{margin-top:46px;}
.projects-grid{display:grid; grid-template-columns:repeat(3,1fr); column-gap:32px; row-gap:56px;}
.get-touch-form{display:grid; grid-template-columns:1fr 1fr; gap:32px 40px;}
.gt-btn{position:relative; display:inline-flex; align-items:center; gap:12px; border:none; border-radius:999px; overflow:hidden; cursor:pointer; padding:6px 6px 6px 24px; height:48px; font-family:var(--font-switzer); font-size:12px; letter-spacing:1px; text-transform:uppercase; color:var(--paper);}
.gt-btn__bg{position:absolute; inset:0; background:var(--void); z-index:0;}
.gt-btn__fill{position:absolute; left:0; right:0; bottom:0; height:0%; background:var(--violet); z-index:1; transition:height .7s cubic-bezier(.625,.05,0,1);}
.gt-btn:hover .gt-btn__fill{height:100%;}
.gt-btn__text{position:relative; z-index:2;}
.gt-btn__icon{position:relative; z-index:2; display:flex; align-items:center; justify-content:center; width:36px; height:36px; border-radius:50%; background:var(--paper); color:var(--void); flex:none; transition:background-color .6s cubic-bezier(.25,.1,.25,1), color .6s cubic-bezier(.25,.1,.25,1);}
.gt-btn__icon svg{width:14px; height:14px; display:block;}
.gt-btn:hover .gt-btn__icon{background:var(--void); color:var(--violet);}
/* Variante en contraste inverse (01/10/2026, page Contact sur fond noir) :
   fond blanc / texte noir / rond noir + fleche blanche. Au survol, meme
   remplissage violet que l'original : le texte repasse en blanc (noir sur
   violet = 3.2:1, illisible ; blanc = 6.3:1), le rond devient blanc avec
   fleche violette (miroir de l'original). */
.gt-btn--inverse{color:var(--void); transition:color .4s ease;}
.gt-btn--inverse .gt-btn__bg{background:var(--paper);}
.gt-btn--inverse .gt-btn__icon{background:var(--void); color:var(--paper);}
.gt-btn--inverse:hover{color:var(--paper);}
.gt-btn--inverse:hover .gt-btn__icon{background:var(--paper); color:var(--violet);}
.gt-btn:disabled{opacity:.6; cursor:wait;}
/* Dans le formulaire de la page Contact (flex en colonne), le bouton garde sa
   largeur naturelle au lieu de s'etirer sur toute la colonne. */
.contact-grid form .gt-btn{align-self:flex-start;}
.btn-link{font-family:var(--font-switzer); font-size:13px; letter-spacing:0.5px; color:var(--ink-dim); text-decoration:underline;}
.btn-link:hover{color:var(--ink);}
.btn{font-family:var(--font-switzer); font-size:13px; letter-spacing:1px; text-transform:uppercase; color:var(--canvas); background:var(--ink); border:none; border-radius:999px; padding:16px 28px; width:fit-content; cursor:pointer; transition:background-color .2s ease;}
/* border-radius:999px (01/10/2026, Boris) : meme rayon que les autres boutons du site (bouton rond du formulaire, bouton Menu). */
.btn:hover{background:var(--ink-dim);}
.btn:active{background:var(--ink-faint);}
.btn.is-disabled, .btn:disabled{background:var(--border-strong); color:var(--ink-faintest); cursor:not-allowed;}

/* ---- Formulaires ---- */
.gt-field input, .gt-field textarea{font-family:var(--font-switzer); font-size:22px; color:var(--ink); background:transparent; border:none; border-bottom:1px solid var(--border-soft); border-radius:0; padding:0 0 12px; outline:none; transition:border-color .2s ease; width:100%;}
.gt-field textarea{resize:none; min-height:56px; line-height:1.4; font-family:inherit;}
.gt-field input::placeholder, .gt-field textarea::placeholder{color:var(--ink-faintest); font-family:var(--font-switzer);}
.gt-field input:hover, .gt-field textarea:hover{border-color:var(--ink-dim);}
.gt-field input:focus, .gt-field textarea:focus{border-color:var(--ink);}
.field{display:flex; flex-direction:column; gap:8px;}
.field label{font-family:var(--font-switzer); font-size:11px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint);}
.field input, .field textarea{font-family:var(--font-switzer); font-size:15px; color:var(--ink); background:var(--surface);
      border:1px solid var(--border-strong); border-radius:0; padding:0 16px; height:48px;
      outline:none; transition:border-color .2s ease; width:100%;}
.field textarea{height:140px; padding:14px 16px; resize:none; font-family:inherit; line-height:1.5;}
.field input::placeholder, .field textarea::placeholder{color:var(--ink-faintest); font-family:var(--font-switzer);}
.field input:hover, .field textarea:hover{border-color:var(--ink-dim);}
.field input:focus, .field textarea:focus{border-color:var(--ink);}
.field.has-error input, .field.has-error textarea{border-color:var(--acc-photo);}
.field .error-msg{font-family:var(--font-switzer); font-size:11px; color:var(--acc-photo); margin:0;}

/* ---- Cartes projet ---- */
.card-project{display:flex; flex-direction:column; gap:22px;}
.card-project .card-link{display:block; text-decoration:none; color:inherit;}
.card-project .thumb{position:relative; aspect-ratio:4/5; overflow:hidden; background:var(--surface-2); border:1px solid var(--border-soft); transition:border-color .3s ease;}
.card-project .thumb::after{content:'VISUEL PROJET'; position:absolute; inset:0; display:flex; align-items:center; justify-content:center; font-family:var(--font-switzer); font-size:11px; letter-spacing:1px; color:var(--ink-faintest); text-transform:uppercase;}
.card-project .thumb::before{content:''; position:absolute; inset:0; background:linear-gradient(160deg, var(--card-tint, var(--surface-2)) 0%, var(--surface-2) 65%); opacity:.55;}
.card-project:hover .thumb{border-color:var(--ink-dim);}
.card-project .cap{display:flex; flex-direction:column; gap:10px;}
.card-project .title{font-family:var(--font-switzer); font-weight:300; font-size:17px; letter-spacing:-0.018em; text-transform:none; color:var(--offwhite); margin:0; line-height:1.3; transition:color .2s ease;}
.card-project:hover .title{color:var(--paper);}
.card-project .tags-row{display:flex; align-items:center; gap:8px; flex-wrap:wrap;}
/* Page Projets (01/10/2026) : sous chaque image, la date en texte simple (plus
   en pastille), puis le titre en grand (34px, palier du token Switzer). */
/* Carte entiere = un seul lien (01/10/2026) : image + legende dans le meme <a>. */
.card-project .card-whole{display:flex; flex-direction:column; gap:22px;}
.card-project .card-whole:focus-visible{outline:1px solid var(--ink); outline-offset:6px;}
/* Disciplines dans la legende : texte gris lisible, la couleur est portee par le
   point seulement (resout aussi le contraste insuffisant du violet UX/UI). */
.card-disc{display:flex; flex-wrap:wrap; gap:6px 18px; margin:4px 0 0; padding:0; list-style:none;}
.card-disc li{display:inline-flex; align-items:center; gap:8px; font-family:var(--font-switzer); font-size:12px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint);}
.card-disc .dot, .tab .dot{width:7px; height:7px; border-radius:50%; flex:none;}
/* Onglets de filtre : meme point de couleur, ils servent de legende. */
.tab{display:inline-flex; align-items:center; gap:8px;}
.card-project .card-date{margin:0; font-family:var(--font-switzer); font-size:12px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint);}
.card-project .cap .title{font-size:34px; line-height:1.05; letter-spacing:-0.02em;}
.more-soon{margin:72px 0 0; padding-top:32px; border-top:1px solid var(--border-soft); color:var(--ink-faint); text-transform:uppercase; letter-spacing:1px; text-align:center;}
.tag-discipline{display:inline-flex; align-items:center; gap:9px; border:1px solid var(--border-strong); border-radius:999px; padding:9px 18px; background:transparent; transition:border-color .2s ease; cursor:pointer; text-decoration:none;}
.tag-discipline:hover{border-color:var(--ink);}
/* Tags du listing "What I've been doing lately?" (01/10/2026) : purement
   informatifs (<span>, pas des liens) -> plus d'eclairage au survol ni de
   curseur main, qui laissaient croire a un lien. */
.h-slide-info .tag-discipline{cursor:default; transition:none;}
.h-slide-info .tag-discipline:hover{border-color:var(--border-strong);}
.tag-discipline .dot{width:7px; height:7px; border-radius:50%; flex:none;}
.tag-discipline .label{font-family:var(--font-switzer); font-weight:400; font-size:11px; letter-spacing:1px; text-transform:uppercase;}
.card-project .thumb.has-photo::after{content:none;}
.card-project .thumb.has-photo::before{opacity:.22;}
.card-project .thumb.has-photo img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block;}
.card-project .thumb > .card-link{position:absolute; inset:0; z-index:1;}
.card-project .thumb-tags{position:absolute; top:14px; right:14px; z-index:2; display:flex; flex-direction:column; align-items:flex-end; gap:8px;}
.card-project .thumb-tags .tag-discipline{background:rgba(14,15,17,.72); border-color:rgba(255,255,255,.18); backdrop-filter:blur(3px); padding:7px 14px;}
.card-project .thumb-tags .tag-discipline .dot{width:6px; height:6px;}
.card-project .thumb-tags .tag-discipline .label{font-size:10px;}
.tag-discipline .sq{width:16px; height:16px; flex:none;}
.tag-discipline .lbl{font-family:var(--font-switzer); font-weight:400; font-size:13px; letter-spacing:0.5px; color:var(--ink);}
.discipline-swatch{display:flex; align-items:center; gap:12px;}
.discipline-swatch .sq{width:16px; height:16px; flex:none;}
.discipline-swatch .lbl{font-family:var(--font-switzer); font-weight:400; font-size:13px; letter-spacing:0.5px; color:var(--ink);}
.selected-projects .card-project .thumb{aspect-ratio:1/1;}

/* Titre a cheval sur l'image, effet "contraste inverse" — mix-blend-mode:
   difference entre le blanc du titre et l'image/couleur en dessous, isole du
   reste de la page via isolation:isolate sur le conteneur (sinon le blend se
   mélangerait avec tout ce qu'il y a derrière .thumb, pas juste l'image). */
.card-project .thumb{isolation:isolate;}
.card-project .thumb-media{position:absolute; inset:0; z-index:0;}
.card-project .title-overlay{position:absolute; left:16px; right:16px; bottom:16px; z-index:2; color:#fff; mix-blend-mode:difference; pointer-events:none;}

/* ---- Hero v5 (28/09, 3e retour de Boris) : reproduction a l'identique du
   mecanisme de creativegiants.art, verifie en direct sur le site (DOM +
   CSS + captures a plusieurs profondeurs de scroll). Le hero n'est plus un
   seul bloc sticky (erreur v4) : 3 pieces independantes qui bougent chacune
   a leur rythme — voir le commentaire HTML dans build_pages.py pour le
   detail du mecanisme. ---- */
/* padding:0 explicite : les regles generiques "section{padding-top/bottom}"
   plus bas dans ce fichier s'appliquent a TOUT element <section>, y compris
   .hero-stage et .h-scroll-section — sans ce reset elles inserent un espace
   involontaire entre le bas du header et le hero. */
/* .hero-stage n'est PLUS sticky lui-meme : c'est un simple conteneur dont
   la hauteur (bandeau + zone meta, mises bout a bout dans le flux normal)
   determine tout le "budget" de scroll du hero — pas de spacer separe.
   IMPORTANT : overflow doit rester visible (jamais hidden/auto), sinon la
   sticky-position de .hero-bottom-meta plus bas serait cassee (regle CSS :
   position:sticky ne fonctionne pas si un ancetre a un overflow different
   de visible). margin-top negatif + hauteur augmentee d'autant : meme
   principe que sur les versions precedentes, le hero remonte pour demarrer
   a y=0 sous le header sticky transparent. 85px = hauteur reelle mesuree de
   header.site en desktop. */
.hero-stage{position:relative; margin-top:-85px; height:calc(140vh + 85px); min-height:760px; overflow:visible; padding:0;}
/* Video en position:fixed, plein ecran, tres en arriere-plan (z-index
   negatif) — EXACTEMENT le mecanisme de .bg-video-wrap sur creativegiants.art
   (confirme via getComputedStyle en direct). Elle ne defile jamais avec la
   page : c'est ce qui permet au bandeau du dessus de defiler normalement
   par-dessus (en revelant de plus en plus de video derriere lui) pendant
   que la zone meta du dessous reste collee au meme endroit — les deux
   zones se comportent comme des fenetres independantes sur un seul fond
   fixe, au lieu d'un bloc unique qui bouge en bloc. */
.hero-video-bg{position:fixed; inset:0; z-index:0; pointer-events:none;}
.hero-video-bg video{width:100%; height:100%; object-fit:cover; display:block;}
/* Bandeau du haut : bloc NORMAL (pas sticky, pas absolute) qui defile a la
   vitesse normale du scroll et disparait par le haut — c'est lui qui
   "remonte" en premier. Passe de 56vh a 66vh le 29/09 (Boris : "le bandeau
   blanc doit prendre plus de place sur la video") — revient vers le ratio
   ~65/70% mesure a l'origine sur creativegiants.art. */
.hero-top-band{position:relative; z-index:2; height:66vh; overflow:hidden; display:flex; align-items:center; justify-content:center; padding:0 40px;}
/* Calque de flou (recette decodee sur creativegiants.art,
   .hero_background-blur) : floute + eclaircit la video fixe juste derriere
   le bandeau — c'est CE calque qu'on voit a travers le trou du logo (voir
   .hero-white-band juste en dessous). backdrop-filter agit sur tout ce qui
   est peint derriere cet element dans l'ordre d'empilement — la video fixe
   marche exactement pareil qu'une video en position:absolute pour ca. */
.hero-blur-layer{position:absolute; inset:0; z-index:0; backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px); background:rgba(255,255,255,.28); pointer-events:none;}
/* Bandeau "blanc" (hero v6, 29/09 — 4e correction sur ce point precis) :
   fond opaque avec un VRAI trou en forme de logo, decoupe via mask SVG
   (#heroBandMask, defini juste avant <section class="hero-stage">).
   Abandon complet du mix-blend-mode:screen : verifie par un test isole,
   cette approche s'aplatissait en gris plat des que le logo translucide
   etait dessine A L'INTERIEUR d'un bandeau qui est lui-meme un contexte
   d'empilement (notre cas) — le "trou" n'etait jamais un vrai trou, juste
   une illusion de couleur qui ne marchait qu'en theorie. Un mask decoupe
   une VRAIE zone de transparence dans le bandeau : a travers, on voit
   directement .hero-blur-layer (juste derriere, meme z-index empile) puis
   la video — exactement la description de Boris ("bandeau blanc, logo qui
   fait un trou dans ce bandeau, dessous une couche qui blur tout et
   en-dessous la video"). mask + -webkit-mask necessaires (Safari). */
/* 02/10/2026 — correctif telephone : le logo n'apparaissait pas sur mobile. L'ancienne
   technique (mask:url(#heroBandMask), un <mask> SVG en ligne dimensionne par JS) n'est pas
   appliquee aux elements HTML par tous les navigateurs mobiles. Remplacee par deux calques
   de masque CSS : le logo (image SVG) et un aplat plein, combines en "exclusion" -> un trou
   en forme de logo, centre, haut de 58% du bandeau. Plus aucun JS. Si un navigateur ne sait
   pas combiner les masques, le logo est affiche en noir sur le bandeau (jamais de bandeau vide). */
.hero-white-band{position:absolute; inset:0; z-index:1; background:var(--offwhite) url(../assets/img/logo-lbo-mask.svg) center / auto 58% no-repeat;}
@supports ((mask-composite:exclude) or (-webkit-mask-composite:xor)){
  .hero-white-band{
    background:var(--offwhite);
    -webkit-mask-image:url(../assets/img/logo-lbo-mask.svg), linear-gradient(#000, #000);
    -webkit-mask-size:auto 58%, 100% 100%;
    -webkit-mask-position:center, center;
    -webkit-mask-repeat:no-repeat, no-repeat;
    -webkit-mask-composite:xor;
    mask-image:url(../assets/img/logo-lbo-mask.svg), linear-gradient(#000, #000);
    mask-size:auto 58%, 100% 100%;
    mask-position:center, center;
    mask-repeat:no-repeat, no-repeat;
    mask-composite:exclude;
  }
}
/* Zone meta du bas : position:sticky + bottom:0 (et NON top:0) — c'est ce
   qui la fait rester collee au bas du viewport tant que .hero-stage n'a pas
   fini de defiler, pendant que .hero-top-band au-dessus continue de defiler
   normalement puis disparait. Hauteur en calc(Xvh + 85px) (et non un simple
   Xvh) : bug corrige le 29/09 — .hero-stage a une hauteur explicite de
   calc(140vh + 85px) (140vh de defilement "utile" + 85px pour compenser le
   margin-top negatif qui fait remonter tout le hero sous le header, voir
   plus haut), mais ses deux enfants (bandeau + zone meta) ne totalisaient
   que 140vh — il restait donc 85px de VIDE en bas du conteneur, non
   couverts par le voile gris de la zone meta ni encore par la section
   suivante. Resultat signale par Boris : "le fond gris ne colle meme pas
   jusqu'a la section suivante", une bande de video brute sans filtre
   restait visible entre les deux. En ajoutant ces 85px directement dans la
   hauteur de la zone meta (qui les couvre avec son propre voile), le total
   des enfants (bandeau + zone meta) correspond exactement a la hauteur du
   conteneur : plus de vide, le voile gris "colle" en continu jusqu'a
   l'arrivee de la section suivante par-dessus. Fond rgba(0,0,0,.18) :
   remplace l'ancien voile ::after sur la video (qui n'existe plus en tant
   que tel puisque la video est maintenant un calque fixe partage) — garde
   le texte meta lisible sur la video crue. */
/* padding horizontal retire (30/09 soir) : porte desormais par le
   .wrap.pad interne (voir build_pages.py) plutot que par un padding fixe
   ici, pour que "Toulouse, France" tombe exactement au meme bord gauche
   que le contenu de #ceQueFais juste en dessous, a toutes les largeurs
   d'ecran (un padding:80px fixe sur ce conteneur plein-largeur ne
   coincidait avec .wrap.pad, max-width:1440 centre, qu'en dessous de
   1440px — au-dela les deux divergeaient, ecart signale par Boris). */
.hero-bottom-meta{position:sticky; bottom:0; z-index:1; height:calc(74vh + 85px); background:rgba(0,0,0,.18); display:flex; flex-direction:column; justify-content:flex-end; padding:0 0 40px; color:var(--paper);}
/* 16px (01/10) : Boris veut "Toulouse, France" a la meme taille que
   "NORMAL DUDE, PLAYFUL EYES." (voir .eyebrow-lg plus bas, meme valeur) —
   inchangee dans ce 2e retour du 01/10, confirmee par Boris ("ne change
   pas"). .hero-meta-role : passee de 18px (16+2, valeur du 1er retour) a
   36px — le double — a la demande explicite de ce 2e retour. */
.hero-meta-loc{font-family:var(--font-switzer); font-size:16px; letter-spacing:1px; text-transform:uppercase; margin:0 0 8px;}
.hero-meta-role{font-family:var(--font-switzer); font-weight:300; font-size:36px; letter-spacing:-0.0203em; margin:0;}
.page-body{position:relative; z-index:1; background:var(--canvas);}

/* ---- Page projet détail ---- */
.folio{font-family:var(--font-switzer); font-weight:400; font-size:12px; letter-spacing:1px;}
.www-row{display:grid; grid-template-columns:220px 1fr; gap:48px; padding:40px 0;}
.www-row:first-child{padding-top:0;}

/* ---- Footer ---- */
footer.site{position:relative; z-index:1; background:var(--canvas); border-top:1px solid var(--border-strong); padding:64px 80px 32px;}
footer.site .footer-top{display:grid; grid-template-columns:1.3fr 1fr; gap:48px; padding-bottom:40px;}
footer.site .footer-brand .wordmark svg{height:22px; width:auto; display:block;}
footer.site .footer-tag{font-family:var(--font-switzer); font-size:13px; color:var(--ink-faint); max-width:32ch; margin:18px 0 0; line-height:1.6;}
footer.site .footer-nav{display:flex; flex-direction:column; gap:10px;}
footer.site .footer-nav a{font-family:var(--font-switzer); font-size:12px; letter-spacing:0.5px; text-transform:uppercase; color:var(--ink-dim); text-decoration:none; transition:color .2s ease; width:fit-content;}
footer.site .footer-nav a:hover{color:var(--ink);}
footer.site .footer-bottom{display:flex; align-items:center; justify-content:space-between; padding-top:24px; border-top:1px solid var(--border-soft); font-family:var(--font-switzer); font-size:11px; color:var(--ink-faint); letter-spacing:0.5px;}

/* ---- Divers / reste des composants ---- */
.gt-field{display:flex; flex-direction:column; gap:10px;}
.gt-field--full{grid-column:1 / -1;}
.gt-field label{font-family:var(--font-switzer); font-size:11px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint);}
.gt-actions{grid-column:1 / -1; margin-top:16px;}
.sr-only{position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;}
.placeholder-img{background:var(--surface-2); border:1px solid var(--border-soft); display:flex; align-items:center; justify-content:center; font-family:var(--font-switzer); font-size:11px; letter-spacing:1px; color:var(--ink-faintest); text-transform:uppercase;}
.stats-row{display:flex; gap:48px; border-top:1px solid var(--border-soft); padding-top:24px;}
.stat{display:flex; flex-direction:column; gap:4px;}
.stat-num{font-family:var(--font-switzer); font-weight:300; font-size:32px; letter-spacing:-0.02em; color:var(--ink);}
.stat-lbl{font-family:var(--font-switzer); font-size:11px; letter-spacing:0.5px; text-transform:uppercase; color:var(--ink-faint);}
/* Taille 16px (30/09 soir, etendue le 01/10) : mesuree en direct sur
   l'eyebrow "What we do" de creativegiants.art (largeur de reference
   1440px, comme .fait-phrase et .fait-para plus bas). Classe .eyebrow-lg
   ajoutee a la main aux seuls eyebrows que Boris a listes explicitement le
   01/10 ("Toulouse, France" via .hero-meta-loc, "What I've been doing
   lately?", "Companies I've worked with", "About" du bloc teaser accueil,
   "Get in touch") — pas sur .eyebrow directement, qui reste a 12px partout
   ailleurs (Projects, page About, Contact, Disciplines...), non demande. */
.eyebrow-lg{font-size:16px;}
/* .fait-phrase sert maintenant de base typo commune aux 3 lignes du bloc
   "Ce que je fais" (30/09 — avant, seules les 2 lignes a mots rotatifs
   avaient cette taille/graisse ; "so that's how I make them." etait plus
   petite/plus fine en .fait-sub). Les 2 premieres lignes etaient
   auparavant un seul <p> avec un <br> — separees en 2 <p>.fait-line
   distincts pour permettre l'entree au scroll indépendante de chaque
   ligne (voir js/main.js). margin:0 sur toutes + line-height 1.3 recree
   le meme rythme vertical qu'avant avec le <br>. */
/* Taille 64px (30/09 soir) : mesuree en direct sur creativegiants.art, sur
   le paragraphe en gras visuel correspondant de l'encart "what we do"
   ("We are artists, designers..."), a une largeur de viewport de 1440px —
   la meme largeur de reference que notre propre .wrap (max-width:1440).
   64px est aussi une valeur telle-quelle de l'echelle du token Switzer de
   Boris, avec son propre palier de letter-spacing (-0.027em), pas besoin
   d'interpoler. Remplace les 44px choisis avant d'avoir cette mesure. */
.fait-phrase{font-family:var(--font-switzer); font-weight:300; color:var(--ink); margin:0; font-size:64px; line-height:1.3; letter-spacing:-0.027em; max-width:900px;}
.fait-phrase .word-swap{display:inline-block; vertical-align:top;}
.fait-phrase .word-current{display:inline-block; text-transform:uppercase; color:var(--violet);}
/* .fait-sub : ne porte plus que margin-top:0 (30/09, retour Boris) : avant,
   28px ici cassait le rythme vertical regulier entre les 3 lignes (l'ecart
   entre cette ligne et la precedente etait donc bien plus grand qu'entre
   les 2 lignes du dessus, qui n'ont elles que le line-height de
   .fait-phrase) — desormais les 3 lignes s'enchainent avec exactement le
   meme espacement, uniquement via line-height:1.3, comme un seul bloc de
   texte. (Le margin-left autrefois pose ici en JS pour aligner sous le mot
   "EYES." a ete retire le 30/09 soir — voir le commentaire HTML dans
   build_pages.py : #faitGroup s'aligne desormais naturellement, plus besoin
   de mesure JS.) */
.fait-sub{margin-top:0;}
/* .fait-para : 4e paragraphe (30/09) sous le bloc des 3 lignes — le pitch
   "16 ans de carriere..." demande par Boris. Typo = le 3e traitement
   typographique releve sur l'encart "what we do" de creativegiants.art
   (mesure en direct via getComputedStyle) : meme famille Switzer que le
   reste, mais en registre "lecture" — plus petit, plus gris/attenue,
   interligne plus genereux — par opposition au registre "display" des 3
   lignes au-dessus (grande taille, encre pleine, interligne serre). Taille
   18px (30/09 soir) : mesuree en direct sur le paragraphe gris
   correspondant ("We go beyond the traditional agency model..."), meme
   largeur de reference 1440px que .fait-phrase ci-dessus — remplace les
   16px choisis avant d'avoir cette mesure. max-width 600px + margin:auto
   (01/10, retour de Boris) : la zone de texte etait jugee trop etroite, et
   plutot que de la garder alignee a gauche comme le reste du groupe (ce
   qui posait probleme), Boris a simplifie : elle est maintenant centree
   horizontalement dans la colonne de contenu, independamment de
   l'alignement du reste de #faitGroup au-dessus. */
.fait-para{font-family:var(--font-switzer); font-weight:300; font-size:18px; line-height:1.43; letter-spacing:-0.018em; color:var(--fog); max-width:600px; margin:32px auto 0;}
.marquee{overflow:hidden; padding:32px 0;}
.marquee-track{display:flex; gap:64px; width:max-content; animation:marquee-scroll 24s linear infinite;}
.marquee-logo{font-family:var(--font-switzer); font-size:14px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint); border:1px solid var(--border-soft); padding:16px 32px; white-space:nowrap; flex:none;}

/* ---- Travaux : scroll horizontal piege (>=901px) — porte depuis
   horizontal-scroll-prototype.html, meme mecanisme que la section piegee de
   creativegiants.art (pin + un seul tween scrub 1:1 sur le scroll vertical).
   Desactive sous 901px, voir regles mobiles plus haut et js/main.js. ---- */
.h-scroll-section{position:relative; height:100vh; overflow:hidden; background:var(--canvas); border-top:1px solid var(--border-soft); padding:0;}
.h-scroll-heading{position:absolute; top:0; left:0; right:0; z-index:2; padding-top:56px;}
.h-scroll-row{display:flex; flex-direction:row; height:100%; width:max-content; will-change:transform;}
/* Mise en page refondue le 01/10/2026, corrigee 2 fois le meme jour.
   3e version (retour avec capture annotee de Boris) : le titre et le bloc
   meta ne sont ni des calques par-dessus l'image (1ere version), ni
   empiles au-dessus/en-dessous du carre (2e version) — Boris a dessine des
   fleches montrant qu'il les voulait sur les COTES du carre : le titre a
   GAUCHE de l'image (aligne en haut du carre), le bloc meta a DROITE de
   l'image (aligne en bas du carre), le carre lui-meme recentre entre
   l'eyebrow du dessus et la ligne de progression du dessous. .h-slide-media
   passe donc en flex ROW (titre | carre | meta), chaque cote "epingle" au
   bord haut ou bas du carre via align-self sur un container stretch. */
/* 4e version (01/10/2026) — parallaxe + titre en contraste inverse, repris
   de creativegiants.art (mecanisme inspecte en direct : voir js/main.js).
   Le carre video est le SEUL element dans le flux de .h-slide-media : le
   titre et le bloc meta sont en position absolue, accroches aux bords du
   carre. Deux raisons :
   1) le carre reste parfaitement centre dans le slide quelle que soit la
      longueur du titre (en flex row, un titre plus long decalait le carre) ;
   2) le titre est ancre par son bord DROIT au carre (right:...) au lieu
      d'etre une boite de largeur fixe calee a gauche : la fin du mot est
      donc toujours a la meme distance du carre pour les 3 projets (bug
      signale par Boris : "e-Learning", court, laissait un vide plus grand
      que les 2 autres titres). main.js resserre en plus la boite du titre a
      sa plus longue ligne (sinon, sur un titre qui passe a la ligne, la
      boite garde la largeur max et le vide reapparait).
   Au repos, le titre mord de --h-title-overlap sur le carre ; pendant
   l'arrivee du slide, le parallaxe (main.js) fait glisser le carre SOUS le
   titre, et mix-blend-mode:difference inverse la couleur du texte la ou il
   passe sur la video — les 2 effets observes sur creativegiants.art. */
.h-slide{flex:none; width:100vw; height:100%; display:flex; align-items:center; justify-content:center; padding:0 80px; --h-title-overlap:1.4em; --h-side-gap:40px;}
.h-slide-media{position:relative; flex:none;}
.h-slide .thumb{position:relative; z-index:1; flex:none; height:min(640px, calc(100vh - 312px), 44vw); width:min(640px, calc(100vh - 312px), 44vw); aspect-ratio:1/1; overflow:hidden; background:var(--surface-2); border:1px solid var(--border-soft); display:block;}
.h-slide .thumb video{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block;}
/* Taille du carre (01/10/2026, Boris, apres challenge UX) : plus de taille
   fixe — le carre prend la hauteur libre entre l'eyebrow et la ligne de
   progression (100vh - 151px) moins ~80px de marge en haut ET en bas
   (d'ou 100vh - 312px), plafonne a 640px (= +1/3 de l'ancien 480px, atteint
   sur grand ecran) et a 44vw. 1440x900 -> ~588px (+23%, ~65% de la hauteur
   comme creativegiants), petits portables -> taille quasi inchangee mais
   l'image respire toujours.
   Titre : 52px -> 60px (01/10/2026, meme proportion que le carre ; tracking
   -0.0254em, interpole sur le token entre 54 et 64px). Le chevauchement
   passe en em (1.4em, = les 72px d'avant a 52px) pour suivre la taille du
   titre. Historique : taille doublee (01/10/2026) — clamp(20px,2vw,26px) ->
   clamp(40px,4vw,52px) ; tracking recale sur le token Switzer (~52px ->
   -0.0227em). max-width : jamais plus large que l'espace libre a gauche du
   carre (moitie de la marge restante du slide, moins le padding de 80px,
   plus le chevauchement) — les % d'un element en absolute se rapportent a
   .h-slide-media, c.-a-d. a la largeur du carre. width:max-content
   indispensable : une boite en absolute ancree seulement par "right" n'a
   que ~72px de largeur "disponible" (celle du chevauchement) et s'effondre
   sinon a un mot par ligne (bug vu en verification). pointer-events:none :
   le clic sur la zone de chevauchement tombe bien sur le lien du carre. */
.h-title-overlay{position:absolute; top:0; right:calc(100% - var(--h-title-overlap)); z-index:2; width:max-content; max-width:min(480px, calc((100vw - 100%) / 2 - 80px + var(--h-title-overlap))); margin:0; font-family:var(--font-switzer); font-weight:300; font-size:clamp(44px,4.2vw,60px); line-height:1; letter-spacing:-0.0254em; color:var(--offwhite); text-align:left; text-wrap:balance; mix-blend-mode:difference; pointer-events:none;}
/* Bloc a DROITE du carre, cale sur son bord bas (3e version, inchange sur
   le principe) — texte aligne a gauche (demande de Boris). Largeur plafonnee
   a l'espace libre a droite du carre, pour ne jamais sortir de l'ecran sur
   un desktop etroit. */
.h-slide-info{position:absolute; bottom:0; left:calc(100% + var(--h-side-gap)); z-index:1; width:min(240px, calc((100vw - 100%) / 2 - 80px - var(--h-side-gap))); display:flex; flex-direction:column; align-items:flex-start; gap:8px; text-align:left;}
.h-slide-info .num{font-family:var(--font-switzer); font-size:11px; letter-spacing:1px; color:var(--ink-faint); margin:0;}
.h-slide-tags{display:flex; gap:8px; flex-wrap:wrap; justify-content:flex-start;}
.h-slide-info .desc{font-size:13px; line-height:1.5; color:var(--body); max-width:30ch; margin:0;}
/* Separateur + barre de progression fusionnes (01/10/2026) : avant, la
   barre de progression etait plaquee tout en bas du viewport (bord a
   bord), sans lien visuel avec la ligne all-link/pager juste au-dessus.
   Maintenant un seul bloc .h-scroll-foot porte les deux, avec le meme
   alignement 80px que le reste du site — la ligne (.progress-track) agit
   a la fois comme separateur ET comme barre de progression (vide au
   depart, se remplit a 100% en fin de scroll piege, meme comportement que
   creativegiants.art). .progress-fill reste pilote par main.js (largeur en
   %), la repositionner ici ne demande aucun changement JS. */
.h-scroll-foot{position:absolute; left:80px; right:80px; bottom:36px; z-index:5;}
.progress-track{position:relative; height:2px; background:var(--border-soft); margin-bottom:16px; overflow:hidden;}
.progress-fill{position:absolute; left:0; top:0; bottom:0; width:0%; background:var(--ink);}
.h-scroll-hud{display:flex; align-items:center; justify-content:space-between; font-family:var(--font-switzer); font-size:11px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint);}
.h-scroll-hud .all-link{color:var(--ink-faint); text-decoration:none; display:flex; align-items:center; gap:8px; transition:color .2s ease;}
.h-scroll-hud .all-link:hover{color:var(--ink);}
.h-scroll-hud .pager .cur{color:var(--ink);}
@keyframes marquee-scroll{from{transform:translateX(0);}
to{transform:translateX(-50%);}
}
    section{padding-top:96px; padding-bottom:96px;}
.tag-sub{display:inline-flex; align-items:center; border:1px solid var(--border-soft); border-radius:999px; padding:7px 14px; background:transparent; transition:border-color .2s ease; cursor:pointer; text-decoration:none;}
.tag-sub:hover{border-color:var(--ink);}
.tag-sub .label{font-family:var(--font-switzer); font-weight:400; font-size:10px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint);}
.tabs-row{border-bottom:1px solid var(--border-soft); padding-bottom:16px; margin-bottom:40px;}
.tabs{display:flex; gap:32px;}
.tab{font-family:var(--font-switzer); font-size:12px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint); text-decoration:none; padding-bottom:16px; margin-bottom:-17px;}
.tab.active{color:var(--ink); border-bottom:2px solid var(--ink);}
.tab:hover{color:var(--ink);}
section{padding-top:64px; padding-bottom:64px;}
.meta-row{display:flex; gap:40px; font-family:var(--font-switzer); font-size:12px; color:var(--ink-faint); letter-spacing:0.5px;}
.meta-row b{color:var(--ink-dim); font-weight:400;}
.factsheet{border:1px solid var(--border-soft); padding:24px; display:flex; flex-direction:column; gap:20px;}
.factsheet .row{display:flex; flex-direction:column; gap:4px;}
.factsheet .label{font-family:var(--font-switzer); font-size:10px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faintest);}
.factsheet .value{font-family:var(--font-switzer); font-size:15px; color:var(--ink);}
.meta-bar{border-top:1px solid var(--border-soft); border-bottom:1px solid var(--border-soft); padding:24px 0; display:flex; flex-wrap:wrap; gap:40px clamp(24px, 2.6vw, 40px);}
.meta-bar .item{display:flex; flex-direction:column; gap:6px;}
.meta-bar .label{font-family:var(--font-switzer); font-size:10px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faintest);}
.meta-bar .value{font-family:var(--font-switzer); font-size:15px; color:var(--ink);}
.www-label{font-family:var(--font-switzer); font-size:12px; letter-spacing:1px; text-transform:uppercase; margin:0;}
.www-body p{max-width:640px; margin:0 0 16px;}
.www-body p:last-child{margin-bottom:0;}
.www-list{list-style:none; margin:0; padding:0; max-width:640px;}
.www-list li{position:relative; padding-left:22px; margin-bottom:12px;}
.www-list li:last-child{margin-bottom:0;}
.www-list li::before{content:"—"; position:absolute; left:0; color:var(--ink-faintest);}
.discipline-row{display:grid; grid-template-columns:220px 1fr; gap:24px; padding:24px 0; border-top:1px solid var(--border-soft);}
/* Page About (01/10/2026) : les 4 disciplines sur une ligne, bouton CV au bout. */
.discipline-line{display:flex; align-items:center; justify-content:space-between; gap:32px; flex-wrap:wrap; padding:24px 0; border-top:1px solid var(--border-soft); margin-top:16px;}
.discipline-list{display:flex; align-items:center; flex-wrap:wrap; gap:16px 48px; margin:0; padding:0; list-style:none;}
.btn-cv{display:inline-block; text-decoration:none; flex:none;}
.discipline-row p{margin:0; max-width:560px;}
.contact-info{display:flex; flex-direction:column; gap:24px;}
.contact-info .row{display:flex; flex-direction:column; gap:4px;}
.contact-info .label{font-family:var(--font-switzer); font-size:11px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faintest);}
.contact-info .value{font-family:var(--font-switzer); font-size:20px; color:var(--ink);}
.projects-page main{padding-bottom:32px;}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 1024px){
  .projects-grid{grid-template-columns:repeat(2,1fr);}
}

@media (max-width: 860px){
  body{margin:0; background:var(--canvas); color:var(--body); font-family:var(--font-switzer); font-size:16px; line-height:1.5;}
  .wrap{max-width:100%; margin:0 auto;}
  .pad{padding-left:20px; padding-right:20px;}
  .h2{font-family:var(--font-switzer); font-weight:300; color:var(--ink); margin:0; font-size:28px; letter-spacing:-0.019em;}
  header.site{display:flex; align-items:center; justify-content:space-between; padding:18px 20px; border-bottom:1px solid transparent;} /* 02/10/2026 : filet sous le header mobile retire (bordure gardee transparente pour ne pas changer la hauteur de 73px) */
  .wordmark svg{height:22px; width:auto; display:block;}
  header.site .wordmark{width:36px; height:36px; border-radius:50%; justify-content:center; background:var(--void); border:1px solid var(--border-strong); color:var(--paper); flex:none;}
  header.site .wordmark svg{height:14px; width:auto; display:block;}
  .menu-btn{display:flex; align-items:center; gap:10px; background:var(--void); border:1px solid var(--border-strong); border-radius:999px; padding:9px 16px; cursor:pointer; color:var(--paper); font-family:var(--font-switzer); font-size:11px; letter-spacing:1px; text-transform:uppercase;}
  footer.site{border-top:1px solid var(--border-strong); padding:48px 24px 28px;}
  footer.site .footer-top{display:flex; flex-direction:column; gap:32px; padding-bottom:28px;}
  footer.site .footer-brand .wordmark svg{height:20px; width:auto; display:block;}
  footer.site .footer-tag{font-family:var(--font-switzer); font-size:13px; color:var(--ink-faint); max-width:36ch; margin:14px 0 0; line-height:1.6;}
  footer.site .footer-nav a{font-family:var(--font-switzer); font-size:12px; letter-spacing:0.5px; text-transform:uppercase; color:var(--ink-dim); text-decoration:none; width:fit-content;}
  footer.site .footer-bottom{display:flex; flex-direction:column; gap:6px; align-items:flex-start; padding-top:20px; border-top:1px solid var(--border-soft); font-family:var(--font-switzer); font-size:11px; color:var(--ink-faint); letter-spacing:0.5px;}
  .get-touch-form{display:flex; flex-direction:column; gap:24px; margin-top:28px;}
  .gt-field{display:flex; flex-direction:column; gap:8px;}
  .gt-field label{font-family:var(--font-switzer); font-size:10px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint);}
  .gt-field input, .gt-field textarea{font-family:var(--font-switzer); font-size:18px; color:var(--ink); background:transparent; border:none; border-bottom:1px solid var(--border-soft); border-radius:0; padding:0 0 10px; outline:none; transition:border-color .2s ease; width:100%;}
  .gt-field textarea{resize:none; min-height:48px; line-height:1.4; font-family:inherit;}
  .gt-actions{margin-top:4px;}
  .gt-btn{position:relative; display:inline-flex; align-items:center; gap:10px; border:none; border-radius:999px; overflow:hidden; cursor:pointer; padding:5px 5px 5px 20px; height:44px; font-family:var(--font-switzer); font-size:11px; letter-spacing:1px; text-transform:uppercase; color:var(--paper);}
  .gt-btn:hover .gt-btn__fill, .gt-btn:active .gt-btn__fill{height:100%;}
  .gt-btn__icon{position:relative; z-index:2; display:flex; align-items:center; justify-content:center; width:34px; height:34px; border-radius:50%; background:var(--paper); color:var(--void); flex:none; transition:background-color .6s cubic-bezier(.25,.1,.25,1), color .6s cubic-bezier(.25,.1,.25,1);}
  .gt-btn__icon svg{width:13px; height:13px; display:block;}
  .gt-btn:hover .gt-btn__icon, .gt-btn:active .gt-btn__icon{background:var(--void); color:var(--violet);}
  .folio{font-family:var(--font-switzer); font-weight:400; font-size:11px; letter-spacing:1px;}
  .meta-row{display:flex; flex-direction:column; gap:8px; font-family:var(--font-switzer); font-size:12px; color:var(--ink-faint); letter-spacing:0.5px;}
  .factsheet{border:1px solid var(--border-soft); padding:20px; display:flex; flex-direction:column; gap:18px;}
  section{padding-top:40px; padding-bottom:40px;}
  .eyebrow{font-family:var(--font-switzer); font-size:11px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint); margin:0 0 14px;}
  .h1{font-family:var(--font-switzer); font-weight:300; color:var(--ink); margin:0; letter-spacing:-0.5px;}
  .tabs-row{border-bottom:1px solid var(--border-soft); margin-bottom:28px;}
  .tabs{display:flex; gap:20px; overflow-x:auto; -webkit-overflow-scrolling:touch; padding-bottom:14px;}
  .tab{flex:none; white-space:nowrap; font-family:var(--font-switzer); font-size:12px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint); text-decoration:none; padding-bottom:14px; margin-bottom:-15px;}
  .card-project{display:flex; flex-direction:column; gap:16px;}
  .card-project .card-whole{gap:16px;}
  .tab{flex:none;}
  .card-project .thumb{position:relative; aspect-ratio:1/1; overflow:hidden; background:var(--surface-2); border:1px solid var(--border-soft); transition:border-color .3s ease;}
  .card-project .thumb-tags{position:absolute; top:12px; right:12px; z-index:2; display:flex; flex-direction:column; align-items:flex-end; gap:6px;}
  .card-project .thumb-tags .tag-discipline{background:rgba(14,15,17,.72); border-color:rgba(255,255,255,.18); backdrop-filter:blur(3px); padding:6px 12px;}
  .card-project .title{font-family:var(--font-switzer); font-weight:300; font-size:16px; letter-spacing:-0.018em; text-transform:none; color:var(--offwhite); margin:0; line-height:1.3; transition:color .2s ease;}
  .card-project .cap .title{font-size:28px; line-height:1.05; letter-spacing:-0.019em;}
  .more-soon{margin-top:48px; padding-top:24px;}
  .tag-discipline{display:inline-flex; align-items:center; gap:9px; border:1px solid var(--border-strong); border-radius:999px; padding:9px 18px; background:transparent; text-decoration:none;}
  .tag-sub{display:inline-flex; align-items:center; border:1px solid var(--border-soft); border-radius:999px; padding:7px 14px; background:transparent; text-decoration:none;}
  .meta-bar{border-top:1px solid var(--border-soft); border-bottom:1px solid var(--border-soft); padding:20px 0; display:flex; flex-direction:column; gap:16px;}
  .meta-bar .item{display:flex; flex-direction:column; gap:4px;}
  .www-row{display:flex; flex-direction:column; gap:12px; padding:28px 0;}
  .www-body p{margin:0 0 14px;}
  .www-list{list-style:none; margin:0; padding:0;}
  .www-list li{position:relative; padding-left:20px; margin-bottom:10px;}
  .discipline-row{display:flex; flex-direction:column; gap:10px; padding:20px 0; border-top:1px solid var(--border-soft);}
  .discipline-line{flex-direction:column; align-items:stretch; gap:24px; padding:20px 0;}
  .discipline-list{display:grid; grid-template-columns:1fr 1fr; gap:16px 20px;}
  .btn-cv{text-align:center;}
  .discipline-row p{margin:0;}
  :root{--void:#000000; --obsidian:#0e0f11; --carbon:#141617; --graphite:#1d2023; --slate:#21223a; --ash:#303438; --steel:#3a3d40; --fog:#61626b; --smoke:#8d8d96; --cloud:#a1a1aa; --silver:#cfcfd3; --bone:#999999; --paper:#ffffff; --violet:#5741e8; --live-wire:#d2e841; --circuit-teal:#00cbaa; --canvas:var(--void); --surface:var(--obsidian); --surface-2:var(--carbon); --spotlight:var(--slate); --border-strong:var(--steel); --border-soft:var(--ash); --ink:var(--paper); --body:var(--silver); --ink-dim:var(--cloud); --ink-faint:var(--bone); --ink-faintest:var(--fog); --acc-graphicdesign:var(--silver); --acc-motiondesign:var(--circuit-teal); --acc-uxui:var(--violet); --acc-photo:var(--live-wire); --acc-graphicdesign-text:var(--acc-graphicdesign); --acc-motiondesign-text:var(--acc-motiondesign); --acc-uxui-text:#9284f0; --acc-photo-text:var(--acc-photo);}
  .btn{font-family:var(--font-switzer); font-size:13px; letter-spacing:1px; text-transform:uppercase; color:var(--canvas); background:var(--ink); border:none; border-radius:999px; padding:16px 28px; width:100%; cursor:pointer; transition:background-color .2s ease;}
  .contact-info{display:flex; flex-direction:column; gap:20px;}
  .contact-info .value{font-family:var(--font-switzer); font-size:18px; color:var(--ink);}
  .h3{font-family:var(--font-switzer); font-weight:300; color:var(--ink); margin:0; font-size:18px; letter-spacing:-0.018em;}
  /* 73px = hauteur reelle mesuree de header.site en mobile (padding 18px*2 +
     bouton menu 36px + bordure 1px). Meme principe qu'en desktop, voir
     .hero-stage plus haut dans ce fichier — ratios legerement reduits pour
     ne pas trop allonger le scroll sur petit ecran. Bandeau agrandi (48->56vh)
     et +73px ajoutes directement sur la hauteur de la zone meta le 29/09,
     meme correctif que desktop (voir .hero-bottom-meta plus haut) — sans
     ca, 73px de video brute restaient visibles sans aucun voile entre la
     zone meta et la section suivante sur mobile aussi. */
  .hero-stage{height:calc(120vh + 73px); margin-top:-73px; min-height:640px;}
  .hero-top-band{height:56vh;}
  .hero-bottom-meta{height:calc(64vh + 73px); padding:0 0 24px;}
  .hero-meta-loc{font-size:11px;}
  .hero-meta-role{font-size:28px;}
  .h-scroll-heading{position:static; padding-top:40px; padding-bottom:28px;} /* 02/10/2026 : en mobile le titre de section reprend sa place dans le flux, sinon le 1er titre de projet passait dessus */
  .h-scroll-row{flex-direction:column; width:100%; height:auto; transform:none !important;}
  .h-scroll-section{height:auto; overflow:visible;}
  .h-slide{width:100%; height:auto; padding:0 20px 56px; display:flex; justify-content:center;}
  /* Sur mobile, pas de place pour le titre/meta a cote du carre (3e version
     desktop, 01/10) — on repasse .h-slide-media en colonne empilee (titre,
     carre, meta), chacun pleine largeur, comme avant le passage en ligne. */
  .h-slide-media{display:flex; flex-direction:column; align-items:stretch; gap:16px; width:100%; max-width:420px;}
  /* Titre : taille doublee aussi sur mobile (clamp(20px,6vw,28px) ->
     clamp(40px,12vw,56px)). Plus de position absolue ni de blend-mode sur
     mobile : empile au-dessus du carre, sans chevauchement (pas de scroll
     horizontal donc pas de parallaxe sous 901px). */
  .h-title-overlay{position:static; align-self:flex-start; width:auto !important; max-width:100%; font-size:clamp(46px,13.8vw,64px); mix-blend-mode:normal;}
  .h-slide .thumb{width:100%; height:auto;}
  .h-slide-info{position:static; align-self:flex-start; width:auto;}
  .h-slide-info .desc{max-width:24ch;}
  .h-scroll-foot{display:none;}
  .stats-row{display:flex; flex-wrap:wrap; gap:28px; border-top:1px solid var(--border-soft); padding-top:20px;}
  .stat-num{font-family:var(--font-switzer); font-weight:300; font-size:28px; letter-spacing:-0.019em; color:var(--ink);}
  .stat-lbl{font-family:var(--font-switzer); font-size:10px; letter-spacing:0.5px; text-transform:uppercase; color:var(--ink-faint);}
  .fait-phrase{font-size:20px; line-height:1.35; letter-spacing:-0.018em;}
  /* Sur mobile, l'eyebrow passe generalement sur plusieurs lignes : le
     decalage horizontal sous "EYES." (voir js/main.js) est desactive sous
     861px, .fait-sub reste alignee a gauche comme les 2 lignes du dessus. */
  .fait-sub{margin-top:0;}
  .fait-para{margin-top:20px;}
  .marquee{overflow-x:auto; -webkit-overflow-scrolling:touch; padding:24px 0;}
  .marquee-track{display:flex; gap:36px; width:max-content;}
  .get-touch-grid{grid-template-columns:1fr; gap:32px;}
  .about-teaser-grid{grid-template-columns:1fr; gap:24px;}
  .about-teaser-grid > div:first-child{max-width:220px;}
  .about-grid{grid-template-columns:1fr; gap:28px;}
  .about-grid > div:first-child{max-width:260px;}
  .contact-grid{grid-template-columns:1fr; gap:40px;}
  .contact-grid > form{margin-top:0;}
  .projects-grid{grid-template-columns:1fr;}
}

/* ==========================================================================
   Menu overlay (vraie superposition JS — remplace l'artboard "MenuOpen" du
   prototype, qui n'était qu'une page séparée sans logique réelle). Reprend
   le visuel de MenuOpen.dc.html/-Mobile.dc.html.
   ========================================================================== */
.menu-overlay{position:fixed; inset:0; z-index:100; background:var(--canvas); display:flex; flex-direction:column; opacity:0; visibility:hidden; transform:translateY(-12px); transition:opacity .3s ease, transform .3s ease, visibility 0s linear .3s;}
.menu-overlay.is-open{opacity:1; visibility:visible; transform:translateY(0); transition:opacity .3s ease, transform .3s ease;}
.menu-panel{flex:1; display:flex; flex-direction:column; justify-content:center; padding:40px 80px 0; min-height:0;}
.menu-list{display:flex; flex-direction:column; gap:4px;}
.menu-item{display:flex; align-items:baseline; gap:20px; text-decoration:none; color:var(--ink-faintest);}
.menu-item .idx{font-family:var(--font-switzer); font-size:14px; color:var(--ink-faint); width:2.5ch; flex:none;}
.menu-item .word{font-family:var(--font-switzer); font-weight:300; font-size:104px; line-height:1.06; letter-spacing:-0.04em; transition:color .2s ease;}
.menu-item:hover, .menu-item.is-active{color:var(--ink);}
.menu-item.is-active .idx{color:var(--circuit-teal);}
.menu-foot{display:flex; align-items:center; justify-content:space-between; padding:20px 80px 40px; font-family:var(--font-switzer); font-size:11px; letter-spacing:0.5px; color:var(--ink-faint); margin-top:32px; border-top:1px solid var(--border-soft);}
.lang-toggle{display:inline-flex; align-items:center; gap:6px; font-family:var(--font-switzer); font-size:11px; letter-spacing:1px;}
/* Bascule FR/EN flottante (01/10/2026) : a gauche du bouton Menu, fixe,
   mix-blend-mode:difference (meme technique que les titres du listing) ->
   texte blanc sur fond sombre, noir sur les bandeaux creme, lisible sur
   tous les fonds au scroll. right/top par defaut approximatifs (sans JS),
   affines au pixel par main.js d'apres la position reelle du bouton Menu.
   z-index au-dessus du menu plein ecran (100) : reste accessible menu ouvert.
   Zone cliquable elargie (padding) pour l'accessibilite tactile. */
.lang-float{position:fixed; top:42px; right:200px; z-index:110; transform:translateY(-50%); mix-blend-mode:difference; color:#fff;}
.lang-float .lang-toggle{font-size:12px; gap:4px;}
.lang-float .lang-toggle .is-current{color:#fff; padding:10px 4px;}
.lang-float .lang-toggle .sep{color:#fff; opacity:.4;}
.lang-float .lang-toggle a{color:#fff; opacity:.55; padding:10px 4px; transition:opacity .2s ease;}
.lang-float .lang-toggle a:hover, .lang-float .lang-toggle a:focus-visible{opacity:1;}
.lang-float .lang-toggle a:focus-visible{outline:1px solid #fff; outline-offset:2px;}
.lang-toggle .is-current{color:var(--ink); font-weight:400;}
.lang-toggle .sep{color:var(--ink-faintest);}
.lang-toggle a{color:var(--ink-faint); text-decoration:none; transition:color .2s ease;}
.lang-toggle a:hover{color:var(--ink);}
body.menu-is-open{overflow:hidden;}
/* Bug corrige le 01/10/2026 (trouve en verifiant la bascule FR/EN) : le menu
   plein ecran (z-index 100) recouvrait le header (z-index 50) -> bouton
   "Close/Fermer" et logo invisibles et non cliquables menu ouvert (seuls
   Echap ou un lien du menu le refermaient). Header remonte au-dessus du menu
   tant qu'il est ouvert ; la bascule FR/EN (110) reste au-dessus des deux. */
body.menu-is-open header.site{z-index:105;}

/* Carte "projet à venir" — placeholder honnête pour les 8 projets pas encore
   renseignés, en attendant le vrai contenu (remplace les gabarits "[Nom du projet]"
   du prototype, qui n'étaient pas montrables tels quels). */
.card-project.is-placeholder{pointer-events:none;}
.card-project.is-placeholder .thumb{display:flex; align-items:center; justify-content:center; aspect-ratio:4/5;}
.card-project.is-placeholder .thumb::after{content:'Projet à venir'; font-family:var(--font-switzer); font-size:11px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faintest);}
.card-project.is-placeholder .title{color:var(--ink-faintest);}

/* Formulaire : champ piège anti-spam (invisible, jamais rempli par un humain) et
   message d'état après envoi (contact.php). */
.hp-field{position:absolute; left:-9999px; width:1px; height:1px; opacity:0; pointer-events:none;}
.form-status{font-family:var(--font-switzer); font-size:12px; letter-spacing:0.3px; margin:12px 0 0; min-height:1.4em;}
.form-status.is-success{color:var(--circuit-teal);}
.form-status.is-error{color:var(--acc-photo);}
@media (max-width: 860px){
  .menu-panel{padding:24px 20px 0;}
  .menu-item .word{font-size:56px;}
  .menu-foot{padding:16px 20px 28px;}
}
/* ============================================================
   GALERIE DES PAGES PROJET (02/10/2026) — mosaique irreguliere + visionneuse
   Grille 12 colonnes a cases carrees (la hauteur d'une rangee = la largeur
   d'une colonne, calculee sur la largeur du conteneur) : chaque vignette
   occupe --c colonnes x --r rangees, les images s'emboitent sans se
   chevaucher. Sous 760px : 2 colonnes, hauteur donnee par le format de la photo.
   ============================================================ */
.project-gallery{padding-top:24px;}
.gallery-head{display:grid; grid-template-columns:220px 1fr; gap:48px; align-items:baseline; margin-bottom:32px;}
.gallery-hint{margin:0; max-width:640px; font-size:14px; color:var(--ink-faint);}
.mosaic-wrap{container-type:inline-size;}
.mosaic{--g:16px; list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(12, minmax(0, 1fr)); grid-auto-rows:calc((100cqw - 11 * var(--g)) / 12); grid-auto-flow:dense; gap:var(--g);}
.mosaic-item{grid-column:span var(--c); grid-row:span var(--r); min-width:0; min-height:0;}
.mosaic-item a{position:relative; display:block; width:100%; height:100%; overflow:hidden; background:var(--surface-2); border:1px solid var(--border-soft); cursor:zoom-in;}
.mosaic-item img, .mosaic-preview{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block;}
.mosaic-item img{transition:transform .6s cubic-bezier(.2,.7,.2,1);}
.mosaic-preview{opacity:0; transition:opacity .35s ease; pointer-events:none;}
.mosaic-item a.is-previewing .mosaic-preview{opacity:1;}
.mosaic-item a:focus-visible{outline:2px solid var(--live-wire); outline-offset:3px;}
.mosaic-badge{position:absolute; left:12px; bottom:12px; z-index:2; padding:5px 10px; border-radius:999px; background:var(--live-wire); color:var(--void); font-family:var(--font-switzer); font-size:11px; font-weight:500; letter-spacing:1px; line-height:1;}
@media (hover:hover){
  .mosaic-item a:hover img{transform:scale(1.03);}
}
@media (max-width:760px){
  .gallery-head{display:flex; flex-direction:column; gap:12px; margin-bottom:24px;}
  .mosaic{--g:10px; grid-template-columns:repeat(2, minmax(0, 1fr)); grid-auto-rows:auto;}
  .mosaic-item{grid-column:span var(--mc); grid-row:auto; aspect-ratio:var(--ratio);}
}
@media (prefers-reduced-motion:reduce){
  .mosaic-item img, .mosaic-preview{transition:none;}
  .mosaic-item a:hover img{transform:none;}
}

/* --- Visionneuse (element <dialog> : Echap, piege du focus et fond geres par le navigateur) --- */
.lightbox{position:fixed; inset:0; width:100vw; height:100vh; height:100dvh; max-width:none; max-height:none; margin:0; padding:0; border:0; background:rgba(0,0,0,.96); color:var(--offwhite); overflow:hidden;}
.lightbox::backdrop{background:rgba(0,0,0,.96);}
.lightbox[open]{display:grid; grid-template-rows:minmax(0, 1fr) auto;}
.lightbox > .lightbox-stage{grid-row:1;} .lightbox > .lightbox-bar{grid-row:2;}
.lightbox-stage{min-height:0; display:flex; align-items:center; justify-content:center; padding:72px 88px 16px;}
.lightbox-img, .lightbox-video{max-width:100%; max-height:100%; width:auto; height:auto; object-fit:contain; display:block;}
.lightbox-img[hidden], .lightbox-video[hidden], .lightbox-btn[hidden]{display:none;}
.lightbox-bar{display:flex; align-items:center; justify-content:space-between; gap:24px; min-height:72px; padding:12px 88px 24px;}
.lightbox-caption{margin:0; display:flex; align-items:baseline; gap:16px; font-family:var(--font-switzer); font-size:16px; color:var(--offwhite);}
.lightbox-count{font-size:13px; color:var(--bone); font-variant-numeric:tabular-nums; white-space:nowrap;}
.lightbox-btn{flex:none; appearance:none; border:1px solid var(--offwhite); background:transparent; color:var(--offwhite); border-radius:999px; padding:11px 20px; font-family:var(--font-switzer); font-size:14px; line-height:1; cursor:pointer; transition:background .2s ease, color .2s ease;}
.lightbox-btn:hover, .lightbox-btn[aria-pressed="true"]{background:var(--offwhite); color:var(--void);}
.lightbox-nav, .lightbox-close{position:absolute; appearance:none; width:48px; height:48px; border-radius:50%; border:1px solid var(--steel); background:rgba(0,0,0,.6); color:var(--offwhite); display:flex; align-items:center; justify-content:center; cursor:pointer; transition:background .2s ease, color .2s ease, border-color .2s ease;}
.lightbox-nav svg, .lightbox-close svg{width:22px; height:22px;}
.lightbox-nav:hover, .lightbox-close:hover{background:var(--offwhite); color:var(--void); border-color:var(--offwhite);}
.lightbox-prev{left:20px; top:50%; transform:translateY(-50%);}
.lightbox-next{right:20px; top:50%; transform:translateY(-50%);}
.lightbox-close{right:20px; top:16px;}
.lightbox button:focus-visible{outline:2px solid var(--live-wire); outline-offset:3px;}
html.lightbox-open{overflow:hidden;}
@media (max-width:760px){
  .lightbox-stage{padding:72px 12px 8px;}
  .lightbox-bar{flex-direction:column; align-items:flex-start; gap:12px; padding:8px 16px 84px; min-height:0;}
  .lightbox-prev{left:16px; top:auto; bottom:20px; transform:none;}
  .lightbox-next{right:16px; top:auto; bottom:20px; transform:none;}
  .lightbox-close{right:12px; top:12px;}
}

/* Citation sous "Get in touch" (02/10/2026) + lien retour en bas des pages projet */
.get-touch-intro .eyebrow{margin-bottom:20px;}
.gt-quote{margin:0; font-family:var(--font-switzer); font-weight:300; font-size:24px; line-height:1.25; letter-spacing:-0.01em; color:var(--ink);}
.gt-quote .quote-by{display:block; margin-top:8px; font-size:14px; letter-spacing:0.5px; color:var(--ink-faint);}
.gt-quote-reply{margin:20px 0 0; font-size:16px; color:var(--body);}

/* 02/10/2026 : citation "Get in touch" en gras ; photo About alignee sur le haut du titre "Hello there" (et non sur l'eyebrow) */
.gt-quote strong{font-weight:600;}
@media (min-width:901px){ .about-photo{margin-top:var(--about-photo-offset, 50px);} }

/* ============================================================
   REFONTE 2026 (page e-Learning) — curseur avant / apres
   ============================================================ */
.project-redesign{padding-top:24px;}
.project-redesign .gallery-hint{font-size:16px; color:var(--body);}
.ba-list{display:grid; gap:56px;}
.ba{margin:0;}
.ba-frame{position:relative; aspect-ratio:16/9; overflow:hidden; border:1px solid var(--border-soft); background:var(--surface-2); user-select:none; -webkit-user-select:none;}
.ba-frame img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; pointer-events:none;}
.ba-before{position:absolute; inset:0; clip-path:inset(0 calc(100% - var(--pos)) 0 0);}
.ba-labels{display:flex; justify-content:space-between; gap:16px; margin-bottom:12px; font-family:var(--font-switzer); font-size:12px; letter-spacing:1px; text-transform:uppercase; color:var(--ink-faint);}
.ba-handle{position:absolute; top:0; bottom:0; left:var(--pos); z-index:3; width:2px; margin-left:-1px; background:var(--offwhite); box-shadow:0 0 0 1px rgba(0,0,0,.35); pointer-events:none;}
.ba-handle svg{position:absolute; top:50%; left:50%; width:44px; height:44px; padding:10px; transform:translate(-50%,-50%); border-radius:50%; background:var(--offwhite); color:var(--void); box-shadow:0 0 0 1px rgba(0,0,0,.35);}
.ba-range{position:absolute; inset:0; z-index:4; width:100%; height:100%; margin:0; opacity:0; cursor:ew-resize; touch-action:pan-y;}
.ba-range:focus-visible ~ .ba-handle, .ba-frame:has(.ba-range:focus-visible) .ba-handle svg{outline:2px solid var(--live-wire); outline-offset:3px;}
.ba figcaption{margin-top:14px; font-family:var(--font-switzer); font-size:14px; letter-spacing:0.5px; color:var(--ink-faint);}
@media (max-width:760px){
  .ba-list{gap:36px;}
  .ba-labels{font-size:10px; margin-bottom:8px;}
  .ba-handle svg{width:36px; height:36px; padding:8px;}
}

/* ============================================================
   02/10/2026 — Refonte 2026 compacte (onglets + 1 curseur), "Autres travaux"
   (e-Learning), affiches groupees par theme (Graphic Design), vignettes generiques
   ============================================================ */
.redesign-row{display:grid; grid-template-columns:220px 1fr; gap:48px;}
.redesign-intro{margin:0 0 28px; max-width:640px;}
.ba-tabs{display:flex; flex-wrap:wrap; gap:8px; margin-bottom:20px;}
.ba-tab{appearance:none; border:1px solid var(--border-strong); background:transparent; color:var(--body); border-radius:999px; padding:9px 16px; font-family:var(--font-switzer); font-size:13px; letter-spacing:0.3px; line-height:1; cursor:pointer; transition:background .2s ease, color .2s ease, border-color .2s ease;}
.ba-tab:hover{border-color:var(--offwhite); color:var(--offwhite);}
.ba-tab[aria-selected="true"]{background:var(--offwhite); border-color:var(--offwhite); color:var(--void);}
.ba-tab:focus-visible{outline:2px solid var(--live-wire); outline-offset:3px;}
.ba[hidden]{display:none;}
.ba-list.has-tabs{gap:0;}
.ba-list.has-tabs figcaption{display:none;}

.group-title{margin:0; font-family:var(--font-switzer); font-weight:400; font-size:14px; letter-spacing:0.3px; color:var(--ink-faint);}
.tile{position:relative; display:block; overflow:hidden; background:var(--surface-2); border:1px solid var(--border-soft); cursor:zoom-in;}
.tile img{width:100%; height:100%; object-fit:cover; display:block; transition:transform .6s cubic-bezier(.2,.7,.2,1);}
.tile:focus-visible{outline:2px solid var(--live-wire); outline-offset:3px;}
.tile-video{cursor:pointer;}
.tile-play{position:absolute; left:50%; top:50%; width:56px; height:56px; margin:-28px 0 0 -28px; border-radius:50%; background:var(--offwhite); color:var(--void); display:flex; align-items:center; justify-content:center; box-shadow:0 0 0 1px rgba(0,0,0,.35);}
.tile-play svg{width:24px; height:24px;}
@media (hover:hover){ .tile:hover img{transform:scale(1.03);} }
@media (prefers-reduced-motion:reduce){ .tile img{transition:none;} .tile:hover img{transform:none;} }

/* e-Learning : video de l'appli (format telephone) + 1 grande image + 2 petites, sur une seule rangee */
.project-extras{padding-top:24px;}
.extras-grid{display:grid; grid-template-columns:0.462fr 1.778fr 0.889fr; grid-template-rows:auto 1fr 1fr; gap:16px;}
.extras-h-a{grid-column:1; grid-row:1;} .extras-h-b{grid-column:2 / 4; grid-row:1;}
.extras-a{grid-column:1; grid-row:2 / 4; aspect-ratio:390 / 844;}
.extras-b{grid-column:2; grid-row:2 / 4;}
.extras-c{grid-column:3; grid-row:2;} .extras-d{grid-column:3; grid-row:3;}
.extras-b, .extras-c, .extras-d{min-height:0;}

/* Graphic Design : grille de 7 colonnes, un groupe = un theme ; "bref." = rangee justifiee (formats varies) */
.poster-grid{display:grid; grid-template-columns:repeat(7, minmax(0, 1fr)); gap:40px 16px;}
.poster-group{grid-column:span var(--span); display:grid; grid-template-columns:subgrid; gap:16px; align-content:start;}
.poster-group .group-title{grid-column:1 / -1;}
.poster-group .tile{aspect-ratio:5 / 7;}
.poster-group-row{display:flex; flex-wrap:wrap; gap:16px;}
.poster-group-row .group-title{flex:0 0 100%;}
.poster-group-row .tile{flex:var(--ratio) 1 0; aspect-ratio:var(--ratio); min-width:0;}

@media (max-width:760px){
  .redesign-row{display:flex; flex-direction:column; gap:12px;}
  .extras-grid{display:flex; flex-direction:column; gap:12px;}
  .extras-a{width:60%; max-width:240px;}
  .extras-b, .extras-c, .extras-d{aspect-ratio:16 / 9;}
  .extras-h-b{margin-top:16px;}
  .poster-grid{grid-template-columns:repeat(3, minmax(0, 1fr)); gap:28px 10px;}
  .poster-group{grid-column:1 / -1; gap:10px;}
  .poster-group-row{gap:10px;}
  .poster-group-row .tile{flex:calc(var(--ratio) * 100) 1 40%;}
}

/* About : meme espace au-dessus et en dessous de la rangee des disciplines (24px de chaque cote, puis le filet suivant) */
.about-disciplines{padding-bottom:0;}

/* ============================================================
   02/10/2026 (2) — Refonte 2026 : rupture + texte sous le titre ; DCI a la hauteur
   de l'image voisine ; affiches : grille de 4 colonnes + carrousels
   ============================================================ */
.project-redesign{margin-top:40px; padding-top:72px; border-top:1px solid var(--border-strong);}
.project-redesign .www-label{margin-bottom:20px;}
.redesign-intro{margin:0 0 12px; max-width:640px;}
.redesign-drag{margin:0 0 32px; font-size:14px; color:var(--ink-faint);}
.project-extras .gallery-head, .project-gallery .gallery-head{margin-bottom:24px;}

/* la grande image (16/9) fixe la hauteur de la rangee ; la video et les 2 petites images s'y ajustent */
.extras-grid .tile{position:relative; min-height:0;}
.extras-grid .tile img{position:absolute; inset:0;}
.extras-a{aspect-ratio:auto; height:100%;}
.extras-b{aspect-ratio:16 / 9;}

.poster-grid{grid-template-columns:repeat(4, minmax(0, 1fr)); gap:48px 16px;}
.poster-carousel{display:block;}
.poster-carousel .group-title{margin-bottom:16px;}
.carousel{position:relative;}
.carousel-track{display:grid; grid-auto-flow:column; grid-auto-columns:calc((100% - 3 * 16px) / 4); gap:16px; margin:0; padding:0; list-style:none; overflow-x:auto; overscroll-behavior-x:contain; scroll-snap-type:x mandatory; scrollbar-width:none; -ms-overflow-style:none;}
.carousel-track::-webkit-scrollbar{display:none;}
.carousel-track > li{scroll-snap-align:start; min-width:0;}
.carousel-track .tile{aspect-ratio:5 / 7;}
.carousel-btn{position:absolute; top:50%; z-index:3; width:48px; height:48px; margin-top:-24px; border-radius:50%; border:1px solid var(--steel); background:rgba(0,0,0,.72); color:var(--offwhite); display:flex; align-items:center; justify-content:center; cursor:pointer; appearance:none; transition:background .2s ease, color .2s ease, border-color .2s ease, opacity .2s ease;}
.carousel-btn[hidden]{display:none;}
.carousel-btn svg{width:22px; height:22px;}
.carousel-prev{left:-24px;} .carousel-next{right:-24px;}
.carousel-btn:hover{background:var(--offwhite); color:var(--void); border-color:var(--offwhite);}
.carousel-btn:disabled{opacity:0; pointer-events:none;}
.carousel-btn:focus-visible{outline:2px solid var(--live-wire); outline-offset:3px;}
@media (prefers-reduced-motion:no-preference){ .carousel-track{scroll-behavior:smooth;} }
@media (max-width:760px){
  .project-redesign{margin-top:24px; padding-top:48px;}
  .extras-a{height:auto; aspect-ratio:390 / 844;}
  .extras-grid .tile img{position:static;}
  .poster-grid{grid-template-columns:repeat(2, minmax(0, 1fr)); gap:32px 10px;}
  .poster-group{grid-column:1 / -1;}
  .carousel-track{grid-auto-columns:calc((100% - 10px) / 2.25); gap:10px;}
  .carousel-prev{left:6px;} .carousel-next{right:6px;}
  .carousel-btn{width:40px; height:40px; margin-top:-20px;}
}
.extras-h-a, .extras-h-b{align-self:end;}

/* 02/10/2026 — Task flow ajoute au prototype Safran : 3 petites images empilees a droite de la grande */
.extras-grid{grid-template-columns:0.462fr 1.778fr 0.593fr; grid-template-rows:auto 1fr 1fr 1fr;}
.extras-a, .extras-b{grid-row:2 / 5;}
.extras-c{grid-row:2;} .extras-d{grid-row:3;} .extras-e{grid-column:3; grid-row:4;}
.extras-e{background:#fffef7;}
.extras-grid .extras-e img{object-fit:contain;}
@media (max-width:760px){ .extras-e{aspect-ratio:2296 / 1570;} }

/* 02/10/2026 — page Contact : memes champs que le formulaire de bas de page, 2 par rangee */
.field-row{display:grid; grid-template-columns:1fr 1fr; gap:24px;}
.field-row .field{min-width:0;}
@media (max-width:900px){ .field-row{grid-template-columns:1fr;} }
