/* =========================================================================
   s2art.fr - front « refonte 2026 »
   Base immersive sombre (direction « wow ») + galerie sobre (esprit
   « editorial ») adaptée au fond foncé. Vanilla, sans framework.
   Le markup est rendu par index.php : la page fonctionne SANS JavaScript
   (filtres, reveals, lightbox et curseur ne sont que des bonus progressifs).
   ========================================================================= */

:root{
  --blue:#3b7ae4; --coral:#E36652; --gold:#E3AD3B; --pink:#E3529F;
  --grad: linear-gradient(110deg, var(--blue), var(--coral) 38%, var(--gold) 66%, var(--pink));
  /* dégradé « vivant » du logo : périodique (même couleur à 0% et 100%) pour
     défiler en boucle sans couture ; piloté par l'animation logoFlow. */
  --logo-grad: linear-gradient(100deg, var(--blue), var(--pink) 22%, var(--coral) 44%, var(--gold) 68%, var(--blue) 100%);
  --bg:#080809; --bg2:#0e0e11; --ink:#f4f1ea; --mut:#9a978f;
  --line:rgba(255,255,255,.10);
  --display:"Syne", sans-serif; --body:"Space Grotesk", sans-serif;
  --ease:cubic-bezier(.22,1,.36,1);
  --wrap:min(1320px,90vw);
  --head-h:54px; /* hauteur approx. du header rétréci - point d'ancrage du filtre */
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  background:var(--bg); color:var(--ink); font-family:var(--body);
  /* « clip » (et non « hidden ») : coupe le débordement horizontal SANS créer
     de conteneur de défilement - indispensable pour que position:sticky des
     filtres se cale sur la fenêtre. */
  overflow-x:clip; -webkit-font-smoothing:antialiased; line-height:1.45;
}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
.wrap{width:var(--wrap);margin-inline:auto}
.grad-text{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
:focus-visible{outline:2px solid var(--blue);outline-offset:3px;border-radius:2px}
.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* Lien d'évitement : masqué hors focus, surgit en haut à gauche au clavier (Tab). */
.skip-link{position:fixed;top:.6rem;left:.6rem;z-index:200;transform:translateY(-160%);
  background:var(--ink,#fff);color:#080809;font-weight:700;font-size:.9rem;
  padding:.6rem 1rem;border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,.4);
  text-decoration:none;transition:transform .2s var(--ease,ease)}
.skip-link:focus{transform:none;outline:2px solid var(--blue,#4ea1ff);outline-offset:2px}

/* Couleur d'accent par catégorie : --c pilote toutes les pastilles et méta
   (features + galerie). Une couleur de la palette s2art par famille de travail. */
[data-category="Print"]{--c:var(--blue)}
[data-category="Pub"]  {--c:var(--coral)}
[data-category="Web"]  {--c:var(--gold)}
[data-category="Logo"] {--c:var(--pink)}

/* curseur personnalisé (desktop pointeur fin uniquement) */
.cursor{position:fixed;top:0;left:0;width:14px;height:14px;border-radius:50%;
  background:var(--ink);pointer-events:none;z-index:9999;mix-blend-mode:difference;
  transform:translate(-50%,-50%);transition:width .3s var(--ease),height .3s var(--ease);display:none}
.cursor.big{width:84px;height:84px;background:#fff}
.cursor.view::after{content:"VOIR";position:absolute;inset:0;display:grid;place-items:center;
  font-family:var(--body);font-size:11px;letter-spacing:.18em;color:#080809;mix-blend-mode:normal}

/* grain léger */
body::after{content:"";position:fixed;inset:0;pointer-events:none;z-index:9998;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

/* ---------- header ---------- */
header{position:fixed;top:0;left:0;right:0;z-index:100;display:flex;align-items:center;
  justify-content:space-between;padding:14px clamp(20px,5vw,56px);
  transition:background .4s,backdrop-filter .4s,padding .4s}
/* Une fois scrollé (donc par-dessus du contenu : galerie, planche-contact et sa
   loupe sticky), l'en-tête devient quasi opaque + flou : aucun visuel ne bave
   au travers quand il glisse dessous (la loupe en fin de planche, notamment).
   Sur le hero (non scrollé) l'en-tête reste totalement transparent. */
header.scrolled{background:rgba(8,8,9,.92);backdrop-filter:blur(16px);
  border-bottom:1px solid var(--line);padding-block:12px}
header .brand{flex:none;position:relative;z-index:1}
header .brand-mark{height:26px;aspect-ratio:1000/440;animation:logoFlow 9s linear infinite}
/* lueur colorée qui suit le curseur dans le header (« la couleur de fond bouge ») */
header::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:0;
  transition:opacity .5s var(--ease);
  background:radial-gradient(220px 160px at var(--hx,50%) var(--hy,50%),
    color-mix(in srgb,var(--coral) 60%,transparent),transparent 70%)}
header:hover::before{opacity:.55}

/* ---------- logo « vivant » : le PNG sert de masque alpha, rempli d'un dégradé
   de marque qui défile en boucle. Le reflet clair qui suit le curseur est porté
   par un ::after et N'APPARAÎT QU'AU SURVOL du logo (sinon il s'efface : plus de
   halo blanc « collé » quand on quitte le logo ou qu'on scrolle). Coupé en
   mouvement réduit. ---- */
.brand-mark,.logo-hero{
  position:relative;
  display:block;
  background:var(--logo-grad);
  background-size:200% 100%;
  background-repeat:repeat;
  background-position:0% 50%;
  -webkit-mask:url(../img/SiteV5.png) center/contain no-repeat;
          mask:url(../img/SiteV5.png) center/contain no-repeat;
}
@keyframes logoFlow{to{background-position:200% 50%}}
/* reflet : masqué à la même forme que le logo, invisible au repos, révélé via
   la classe .lit posée par front.js quand le curseur est SUR le logo. */
.brand-mark::after,.logo-hero::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(42% 60% at var(--mx,50%) var(--my,32%),rgba(255,255,255,.95),rgba(255,255,255,0) 72%);
  -webkit-mask:url(../img/SiteV5.png) center/contain no-repeat;
          mask:url(../img/SiteV5.png) center/contain no-repeat;
  opacity:0;transition:opacity .3s var(--ease);
}
.brand-mark.lit::after,.logo-hero.lit::after{opacity:1}
/* sans JS : le reflet (centré) s'affiche au survol direct du logo. */
html:not(.js) .brand-mark:hover::after,
html:not(.js) .logo-hero:hover::after{opacity:1}
nav{display:flex;gap:30px;font-size:13px;letter-spacing:.14em;text-transform:uppercase}
nav a{color:var(--mut);transition:color .25s;position:relative}
nav a:hover{color:var(--ink)}
nav a::after{content:"";position:absolute;left:0;bottom:-6px;height:2px;width:0;background:var(--grad);transition:width .3s var(--ease)}
nav a:hover::after{width:100%}

/* ---------- burger + menu mobile (CSS-first : fonctionne sans JS via la
   checkbox #nav-toggle ; le JS ne fait qu'ajouter aria-expanded + fermeture
   au clic/Échap). Masqué au-dessus de 760px. ---------- */
.burger{display:none}
@media(max-width:760px){
  .burger{display:flex;flex:none;flex-direction:column;justify-content:center;align-items:center;
    gap:6px;width:46px;height:46px;margin:-12px -8px -12px 0;padding:0;background:transparent;
    border:0;cursor:pointer;position:relative;z-index:101}
  .burger span{display:block;width:26px;height:2px;border-radius:2px;background:var(--ink);
    transition:transform .3s var(--ease),opacity .2s var(--ease)}
  .nav-toggle:checked ~ .burger span:nth-child(1){transform:translateY(8px) rotate(45deg)}
  .nav-toggle:checked ~ .burger span:nth-child(2){opacity:0}
  .nav-toggle:checked ~ .burger span:nth-child(3){transform:translateY(-8px) rotate(-45deg)}

  nav{position:fixed;left:0;right:0;top:var(--head-h,62px);z-index:99;
    flex-direction:column;gap:0;padding:8px clamp(20px,6vw,56px) 26px;
    background:rgba(8,8,9,.92);backdrop-filter:blur(18px);
    border-bottom:1px solid rgba(255,255,255,.08);
    box-shadow:0 24px 48px rgba(0,0,0,.45);
    opacity:0;visibility:hidden;transform:translateY(-14px);pointer-events:none;
    transition:opacity .3s var(--ease),transform .35s var(--ease),visibility .35s}
  .nav-toggle:checked ~ nav{opacity:1;visibility:visible;transform:none;pointer-events:auto}
  nav a{font-size:17px;letter-spacing:.12em;padding:18px 2px;
    border-bottom:1px solid rgba(255,255,255,.07)}
  nav a:last-child{border-bottom:0}
  nav a::after{display:none}
}

/* ---------- hero ---------- */
.hero{position:relative;min-height:100svh;display:flex;flex-direction:column;justify-content:center;
  align-items:center;text-align:center;overflow:hidden;padding:120px 5vw 80px}
.mesh{position:absolute;inset:-25%;z-index:0;filter:blur(72px) saturate(140%);opacity:.92}
.blob{position:absolute;width:48vw;height:48vw;border-radius:50%;mix-blend-mode:screen;animation:float 22s ease-in-out infinite}
.b1{background:var(--blue);top:2%;left:8%}
.b2{background:var(--coral);top:14%;right:4%;animation-delay:-5s;animation-duration:26s}
.b3{background:var(--gold);bottom:2%;left:24%;animation-delay:-11s;animation-duration:30s}
.b4{background:var(--pink);bottom:8%;right:18%;animation-delay:-16s;animation-duration:24s}
@keyframes float{0%,100%{transform:translate(0,0) scale(1)}33%{transform:translate(12%,8%) scale(1.18)}66%{transform:translate(-10%,-6%) scale(.9)}}
.hero-veil{position:absolute;inset:0;z-index:1;background:radial-gradient(120% 80% at 50% 42%,transparent,rgba(8,8,9,.5) 68%,var(--bg))}
/* Desktop : les blobs convergent en plein centre, là où se pose le logo -> fond
   trop clair, titre délavé. Sur mobile ils sont rejetés vers les bords, le centre
   reste sombre et le contraste est parfait. On reproduit ce contraste en
   calmant le mesh sur grand écran (opacité + saturation), SANS forme/halo. */
@media(min-width:761px){ .mesh{opacity:.5;filter:blur(80px) saturate(120%)} }
.hero-inner{position:relative;z-index:2;display:flex;flex-direction:column;align-items:center;gap:36px;perspective:1100px}
/* Effet « wow » au survol : le logo bascule en 3D vers le curseur. Porté par le
   h1 (qui se dimensionne au logo) car .logo-hero garde son intro `rise` + le flux
   du dégradé ; --rx/--ry sont posés par front.js (pointeur fin seulement). */
.hero-inner h1{transform:rotateX(var(--ry,0deg)) rotateY(var(--rx,0deg));
  transform-style:preserve-3d;transition:transform .2s ease-out;will-change:transform}
.hero:hover .logo-hero{filter:drop-shadow(0 16px 26px rgba(0,0,0,.45))}
.eyebrow{font-size:clamp(11px,1.1vw,13px);letter-spacing:.42em;text-transform:uppercase;color:var(--ink);
  opacity:0;animation:rise 1s var(--ease) .2s forwards}
.logo-hero{width:min(76vw,860px);aspect-ratio:1000/440;
  opacity:0;animation:rise 1.1s var(--ease) .35s forwards, logoFlow 11s linear infinite}
.hero p.sub{color:var(--ink);font-size:clamp(15px,1.7vw,20px);max-width:34ch;letter-spacing:.01em;
  opacity:0;animation:rise 1.1s var(--ease) .6s forwards}
@keyframes rise{from{opacity:0;transform:translateY(38px)}to{opacity:1;transform:none}}
/* centrage robuste : on s'étend sur toute la largeur (left:0/right:0) et on
   centre via flexbox, plutôt qu'un translateX fragile sur mobile. Le
   text-indent compense l'espace de letter-spacing qui décale le texte à droite. */
.scrollcue{position:absolute;bottom:28px;left:0;right:0;z-index:2;font-size:11px;
  letter-spacing:.3em;text-indent:.3em;text-transform:uppercase;color:var(--mut);display:flex;
  flex-direction:column;align-items:center;gap:10px;opacity:0;animation:rise 1s 1.1s forwards}
.scrollcue span{width:1px;height:40px;background:linear-gradient(var(--mut),transparent);animation:cue 2s infinite}
@keyframes cue{0%{transform:scaleY(0);transform-origin:top}50%{transform:scaleY(1);transform-origin:top}50.1%{transform-origin:bottom}100%{transform:scaleY(0);transform-origin:bottom}}

/* ---------- marquee ---------- */
.marquee{border-block:1px solid var(--line);overflow:hidden;padding:26px 0;background:var(--bg2)}
.marquee-track{display:flex;white-space:nowrap;width:max-content;animation:scroll 28s linear infinite}
.marquee-track span{font-family:var(--display);font-weight:800;font-size:clamp(2rem,5vw,4rem);
  text-transform:uppercase;letter-spacing:-.01em;padding-inline:.5ch}
.marquee-track .dot{color:transparent;background:var(--grad);-webkit-background-clip:text;background-clip:text}
@keyframes scroll{to{transform:translateX(-50%)}}

/* ---------- en-têtes de section ---------- */
.sec{padding:clamp(90px,13vh,170px) 0}
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;margin-bottom:clamp(50px,8vh,90px);flex-wrap:wrap}
.sec-head h2{font-family:var(--display);font-weight:700;font-size:clamp(2rem,6vw,4.6rem);line-height:.95;letter-spacing:-.02em}
.sec-head .count{font-size:13px;letter-spacing:.2em;text-transform:uppercase;color:var(--mut)}

/* ---------- DERNIERS TRAVAUX (4 features) ---------- */
.showcase{display:flex;flex-direction:column;gap:clamp(80px,15vh,200px)}
.feature{display:grid;grid-template-columns:repeat(12,1fr);align-items:center;gap:clamp(20px,4vw,60px);position:relative}
.feature .fmedia{grid-column:1/8;position:relative}
.feature .fmeta{grid-column:8/13}
.feature.alt .fmedia{grid-column:6/13;order:2}
.feature.alt .fmeta{grid-column:1/6;order:1;text-align:right}
.fnum{font-family:var(--display);font-weight:800;font-size:clamp(5rem,14vw,13rem);line-height:.8;
  color:transparent;-webkit-text-stroke:1.6px color-mix(in srgb, var(--c, var(--ink)) 60%, transparent);
  letter-spacing:-.04em;margin-bottom:-.1em}
.fmeta h3{font-family:var(--display);font-weight:700;font-size:clamp(1.8rem,3.6vw,3.2rem);line-height:1;letter-spacing:-.02em;margin:.2em 0 .35em}
.fmeta .cat{display:inline-block;font-size:11px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--c, var(--mut));font-weight:700;
  border:1px solid color-mix(in srgb, var(--c, var(--line)) 45%, transparent);
  background:color-mix(in srgb, var(--c, transparent) 12%, transparent);
  border-radius:999px;padding:6px 14px;margin-bottom:.4em}
.fmeta .d{color:var(--mut);font-size:15px}
.fmeta .d .wd{color:var(--c, var(--mut));font-weight:600;font-variant-numeric:tabular-nums}
/* Icône « demandeur / commanditaire » placée avant le nom du client.
   fill explicite (pas currentColor) car .client-name est en texte transparent. */
.dmd-ic{width:.92em;height:.92em;vertical-align:-.14em;margin-right:.4em;flex:none;
  fill:var(--c, var(--mut));opacity:.9}
/* Lien vers le site du client */
.client-link{display:inline-block;font-size:.8rem;font-weight:600;letter-spacing:.02em;
  color:var(--ink);background-image:var(--grad);-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;transition:opacity .25s}
.client-link:hover{opacity:.7;text-decoration:none}
.fmeta .client-link{margin-top:.6rem;font-size:.95rem}
figcaption .client-link{white-space:nowrap}
/* lien « nom du client » (œuvres clients) : majuscules, gras, dégradé vivant */
.client-name{font-family:var(--display);font-weight:800;text-transform:uppercase;letter-spacing:.04em;
  background-image:var(--logo-grad);background-size:200% 100%;background-repeat:repeat;
  animation:logoFlow 11s linear infinite}
/* site client dépublié : mention grisée, non cliquable (rendu en <span>) */
.client-offline{background:none;-webkit-text-fill-color:currentColor;color:var(--mut);
  animation:none;cursor:default;opacity:.9}
.client-offline .dmd-ic{fill:var(--mut)}
.ph{position:relative;overflow:hidden;border-radius:20px;aspect-ratio:4/5;background:#111;
  transition:clip-path 1.1s var(--ease)}
.feature.wide .ph{aspect-ratio:16/11}
/* Le voile de révélation n'est posé que si JS est actif : sans JS, l'image
   reste pleinement visible (exigence « fonctionne sans JavaScript »). */
.js .ph{clip-path:inset(100% 0 0 0)}
.js .feature.in .ph{clip-path:inset(0 0 0 0)}
.ph img{position:absolute;top:-9%;left:0;width:100%;height:118%;object-fit:cover;
  transition:transform 1.4s var(--ease);will-change:transform}
.js .ph img{transform:scale(1.14)}
.js .feature.in .ph img{transform:scale(1)}
.feature.contain .ph{aspect-ratio:4/3;background:radial-gradient(120% 120% at 30% 18%,rgba(227,82,159,.18),transparent 60%),var(--bg2);display:grid;place-items:center}
.feature.contain .ph img{position:static;height:auto;width:auto;max-width:78%;max-height:78%;margin:auto;
  transform:scale(1.1);filter:drop-shadow(0 24px 50px rgba(0,0,0,.55))}
/* Affiche verticale en vedette : montrée ENTIÈRE (archive fidèle) sur une scène
   discrète plutôt que rognée en plein cadre. Pas de parallaxe (image fixe, cf. JS). */
.feature.portrait .ph{aspect-ratio:4/5;
  background:radial-gradient(120% 120% at 30% 16%,rgba(59,122,228,.15),transparent 62%),var(--bg2);
  display:grid;place-items:center}
.feature.portrait .ph img{position:static;height:auto;width:auto;max-width:90%;max-height:92%;margin:auto;
  object-fit:contain;transform:scale(1.06);filter:drop-shadow(0 24px 50px rgba(0,0,0,.5))}
.ph .shine{position:absolute;inset:0;opacity:0;transition:opacity .5s;pointer-events:none;z-index:2;
  background:radial-gradient(50% 50% at var(--mx,50%) var(--my,50%),rgba(255,255,255,.16),transparent 70%)}
.feature:hover .shine{opacity:1}
.feature a.fhit{position:absolute;inset:0;z-index:3}
@media(max-width:860px){
  .feature,.feature.alt{display:block}
  .feature .fmeta,.feature.alt .fmeta{text-align:left;margin-top:22px}
  .fnum{font-size:clamp(4rem,20vw,7rem)}
  .ph,.feature.wide .ph{aspect-ratio:4/5}
}

/* ---------- filtres (chips) : barre collante qui « se gripe » au header ----------
   La barre vit à sa place dans la galerie, puis se colle sous l'en-tête fixe
   dès qu'on l'atteint (état .docked posé par front.js via IntersectionObserver).
   Masquée tant que JS n'a pas pris la main (sans JS le filtrage n'agit pas et la
   galerie reste complète) - révélée par la classe .js sur <html>. */
.filter-sentinel{height:1px;margin:0;pointer-events:none}
.filterbar{display:none}
.js .filterbar{display:block;position:sticky;top:var(--head-h);z-index:60;
  /* pleine largeur pour pouvoir se fondre dans le header une fois dockée */
  width:100vw;margin-left:calc(50% - 50vw);margin-bottom:clamp(28px,5vh,52px);
  padding-block:.5rem;border-bottom:1px solid transparent;
  transition:background .35s ease,backdrop-filter .35s ease,border-color .35s ease,
    box-shadow .35s ease,padding .35s ease}
/* état docké : prend l'allure du header (verre dépoli) → effet « grip ». */
.js .filterbar.docked{background:rgba(8,8,9,.62);backdrop-filter:blur(14px);
  border-bottom-color:var(--line);box-shadow:0 14px 34px rgba(0,0,0,.28);padding-block:.7rem}
.filterbar-inner{display:flex;align-items:center;gap:1rem}
.filter-label{flex:none;font-size:.74rem;letter-spacing:.18em;text-transform:uppercase;color:var(--mut)}
.chip-row{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;min-width:0}
.chip{appearance:none;cursor:pointer;font:inherit;font-size:.86rem;line-height:1;border:1px solid var(--line);
  background:rgba(8,8,9,.4);color:var(--mut);padding:.5rem 1rem;border-radius:999px;
  transition:color .25s ease,background-color .25s ease,border-color .25s ease;
  display:inline-flex;align-items:center;gap:.5ch;white-space:nowrap;flex:none}
/* couleur par catégorie - cohérente avec les méta des œuvres */
.chip[data-filter="Print"]{--c:var(--blue)}
.chip[data-filter="Pub"]  {--c:var(--coral)}
.chip[data-filter="Web"]  {--c:var(--gold)}
.chip[data-filter="Logo"] {--c:var(--pink)}
/* pastille de couleur devant chaque catégorie (pas devant « Tous ») */
.chip[data-filter]:not([data-filter="all"])::before{content:"";flex:none;width:.5rem;height:.5rem;
  border-radius:50%;background:var(--c,var(--mut));transition:background .25s ease}
.chip:hover{border-color:var(--c,var(--ink));color:var(--ink)}
/* actif : « Tous » garde le dégradé arc-en-ciel ; chaque catégorie prend sa teinte */
.chip[aria-pressed="true"]{color:#080809;border-color:transparent;background-image:var(--grad)}
.chip[data-filter]:not([data-filter="all"])[aria-pressed="true"]{background-image:none;background-color:var(--c)}
.chip[data-filter]:not([data-filter="all"])[aria-pressed="true"]::before{background:#080809}
/* mobile : les pastilles défilent horizontalement plutôt que de déborder */
@media(max-width:760px){
  header{padding-block:11px}
  header .brand-mark{height:22px}
  .filterbar-inner{gap:.6rem}
  .filter-label{display:none}
  .chip-row{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .chip-row::-webkit-scrollbar{display:none}
  .chip{font-size:.8rem;padding:.45rem .8rem}
}

/* ---------- GALERIE (sobre, esprit editorial, fond sombre) ---------- */
.gallery{display:grid;gap:clamp(2.2rem,4vw,4.2rem) clamp(1.4rem,3vw,3rem);
  grid-template-columns:repeat(12,1fr)}
/* NB : pas de grid-auto-flow:dense - l'ordre visuel doit suivre la
   numérotation (la plus récente d'abord), pas combler les trous. */
.work{margin:0;grid-column:span 12}
/* Largeur en fonction de l'orientation du média : les paysages respirent,
   les panoramiques s'étalent. (ratio calculé côté PHP → .wide / .pano) */
@media(min-width:640px){
  .work{grid-column:span 6}
  .work.wide{grid-column:span 6}
  .work.pano{grid-column:span 12}
}
@media(min-width:1024px){
  .work{grid-column:span 4}
  .work.wide{grid-column:span 6}
  .work.pano{grid-column:span 8}
}
.work[hidden]{display:none}
/* reveal au scroll, uniquement si JS actif (sinon tout est visible d'emblée) :
   léger flou + montée + mise à l'échelle, qui se résorbent à l'apparition. */
.js .work{opacity:0;transform:translateY(28px) scale(.985);filter:blur(6px);
  transition:opacity .8s var(--ease),transform .8s var(--ease),filter .8s var(--ease)}
.js .work.in{opacity:1;transform:none;filter:none}
/* Pendant le filtrage, l'animation FLIP (Web Animations API) pilote seule les
   tuiles : on neutralise la transition de reveal pour éviter tout conflit. */
.js .gallery.filtering .work{transition:none}
.js .gallery.filtering .work{will-change:transform,opacity}

/* ---- Archives (plus de 2 ans) : planche-contact + LOUPE ----
   Perf + wow : des miniatures carrées légères (WebP ~12 Ko, content-visibility
   pour ne rendre que le visible → le scroll de 150 vignettes fond). Au survol/
   focus d'une vignette, l'image pleine se projette dans une LOUPE sticky en
   regard (une seule grande image chargée à la fois, à la demande) et les
   voisines s'effacent (projecteur). L'anneau reprend la couleur de catégorie. */
.archive{grid-column:1/-1;margin-top:clamp(1.4rem,3vw,2.8rem);
  display:grid;grid-template-columns:1fr;gap:clamp(.9rem,2vw,1.3rem)}
.archive-head{display:flex;align-items:baseline;gap:.9rem;flex-wrap:wrap;
  padding-top:clamp(1rem,2vw,1.6rem);border-top:1px solid var(--line)}
.archive-head h3{font-family:var(--display);font-weight:800;letter-spacing:-.01em;font-size:clamp(1.05rem,2.4vw,1.5rem)}
.archive-head .ah-note{font-size:.8rem;color:var(--mut);letter-spacing:.02em}
@media(hover:none){ .archive-head .ah-note{display:none} }

/* Grille dense de la planche-contact (auto-fill : on remplit la largeur). */
.archive-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(78px,1fr));gap:.45rem}
@media(min-width:640px){ .archive-grid{grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:.55rem} }

/* Bandeau d'année : pleine largeur, force un retour à la ligne → les vignettes
   se regroupent par année (la planche est triée du plus récent au plus ancien). */
.archive-year{grid-column:1/-1;display:flex;align-items:center;gap:.7rem;
  margin:.5rem 0 -.1rem;font-family:var(--display);font-weight:800;letter-spacing:.02em;
  font-size:.92rem;color:var(--mut)}
.archive-year:first-child{margin-top:0}
.archive-year span{flex:none;font-variant-numeric:tabular-nums}
.archive-year::after{content:"";flex:1;height:1px;
  background:linear-gradient(90deg,var(--line),transparent)}

/* Vignette compacte : on annule les spans de la grille principale ; perf via
   content-visibility (rendu sauté hors écran) + taille intrinsèque carrée. */
.work.aged{grid-column:auto;position:relative;content-visibility:auto;contain-intrinsic-size:auto 110px}
.work.aged .frame{aspect-ratio:1/1;border-radius:5px}
.work.aged .frame img{width:100%;height:100%;object-fit:cover}
.work.aged .num{font-size:.6rem;top:.35rem;left:.45rem;opacity:.82}
/* Pastille couleur de catégorie : l'identité s2art (bleu/corail/or/rose) reste
   lisible au repos sur la planche-contact, cohérente avec les pastilles galerie. */
.work.aged .frame::before{content:"";position:absolute;top:.4rem;right:.42rem;z-index:3;
  width:7px;height:7px;border-radius:50%;background:var(--c,var(--mut));
  box-shadow:0 0 0 1.5px rgba(8,8,9,.6),0 0 8px color-mix(in srgb,var(--c,#fff) 70%,transparent)}
@media(hover:hover){
  /* Survol vignette = mise en avant légère (le « wow » est dans la loupe) :
     transform/box-shadow uniquement (compositeur), zéro filtre animé. */
  .work.aged .frame{transition:transform .3s var(--ease),box-shadow .3s var(--ease)}
  .work.aged:hover .frame,.work.aged:focus-within .frame,.work.aged.active .frame{
    transform:translateY(-2px) scale(1.045);
    box-shadow:0 0 0 2px var(--c,var(--pink)),0 10px 24px -10px rgba(0,0,0,.6)}
  /* Projecteur : pendant la loupe, les vignettes non visées s'effacent. */
  .archive-grid.spot .work.aged{transition:opacity .3s var(--ease),transform .3s var(--ease),box-shadow .3s var(--ease)}
  .archive-grid.spot .work.aged:not(.active):not(:hover){opacity:.34}
}

/* La LOUPE : carte sticky qui projette l'image pleine + sa légende.
   Affichée seulement là où elle a du sens (large + survol possible). */
.archive-loupe{display:none}
@media(min-width:980px) and (hover:hover){
  .archive{grid-template-columns:1fr clamp(280px,30vw,400px);
    grid-template-areas:"head head" "grid loupe";align-items:start}
  .archive-head{grid-area:head} .archive-grid{grid-area:grid}
  /* parquée SOUS la barre de filtres collante (header ~54px + barre ~49px) :
     sans cette marge la loupe se glisse derrière les chips quand on scrolle. */
  .archive-loupe{grid-area:loupe;display:block;position:sticky;
    top:calc(var(--head-h,54px) + 4.5rem);align-self:start}
  .al-frame{position:relative;display:grid;place-items:center;
    height:clamp(280px,48vh,460px);overflow:hidden;border-radius:12px;
    border:1px solid var(--line);background:linear-gradient(160deg,var(--bg2),#0b0b0d)}
  /* opacité/transform pilotés en JS (pop à chaque changement d'image). */
  .al-frame img{max-width:100%;max-height:100%;object-fit:contain;
    opacity:0;transform:scale(.97);
    transition:opacity .35s var(--ease),transform .55s cubic-bezier(.16,.72,.2,1);
    box-shadow:0 18px 50px -18px rgba(0,0,0,.7)}
  .al-frame::after{content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
    background:radial-gradient(120% 70% at 50% 0,
      color-mix(in srgb,var(--lc,#E3529F) 16%,transparent),transparent 60%);
    opacity:0;transition:opacity .35s ease,background .35s ease}
  .archive-loupe.has-img .al-frame::after{opacity:1}
  .al-hint{position:absolute;color:var(--mut);font-size:.85rem;text-align:center;
    line-height:1.55;letter-spacing:.04em;transition:opacity .3s ease}
  .archive-loupe.has-img .al-hint{opacity:0}
  .al-cap{display:flex;align-items:center;gap:.5rem;margin-top:.7rem;min-height:1.3em;
    font-family:var(--display);font-weight:700;letter-spacing:-.01em;font-size:.92rem;color:var(--ink);
    opacity:0;transform:translateY(.3rem);transition:opacity .3s var(--ease),transform .3s var(--ease)}
  .archive-loupe.has-img .al-cap{opacity:1;transform:none}
  .al-cap .al-dot{flex:none;width:9px;height:9px;border-radius:50%;background:var(--lc,var(--pink));
    box-shadow:0 0 10px color-mix(in srgb,var(--lc,#E3529F) 80%,transparent)}
  .al-cap .al-y{color:var(--lc,var(--mut));font-weight:700;white-space:nowrap}
}
/* .frame est un <a href="img/…"> (repli sans JS : ouvre l'image en grand) que JS
   intercepte pour la vue plein écran. Reset des styles d'ancre/bouton hérités. */
.frame{position:relative;display:block;overflow:hidden;border-radius:8px;background:var(--bg2);
  border:0;padding:0;width:100%;cursor:pointer;color:inherit;text-decoration:none}

/* ---- chrome « fenêtre de navigateur » pour les sites web (proposition) ---- */
/* Barre de titre façon navigateur : 3 pastilles (palette s2art) + adresse.
   Galerie : la barre est dans le flux (l'image suit dessous).
   Feature : posée en surimpression du haut du visuel. */
.browser{display:flex;align-items:center;gap:.55rem;z-index:4;
  height:30px;padding:0 .75rem;background:linear-gradient(180deg,#17171b,#101013);
  border-bottom:1px solid var(--line)}
.frame-web .browser{position:relative}
.ph-web .browser{position:absolute;top:0;left:0;right:0;background:linear-gradient(180deg,rgba(18,18,22,.96),rgba(16,16,19,.74));backdrop-filter:blur(6px)}
.browser .tl{position:relative;flex:none;width:38px;height:9px}
.browser .tl::before{content:"";position:absolute;top:0;left:0;width:9px;height:9px;border-radius:50%;
  background:var(--coral);box-shadow:14px 0 0 var(--gold),28px 0 0 var(--blue)}
.browser .addr{flex:1;min-width:0;font-family:var(--body);font-size:.64rem;letter-spacing:.02em;
  color:var(--mut);background:rgba(255,255,255,.06);border:1px solid var(--line);border-radius:999px;
  padding:.2rem .7rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center}
/* la pastille numéro / ruban ne doit pas chevaucher la barre de navigateur */
.frame-web .num,.frame-web .ribbon,.ph-web .ribbon{top:calc(30px + .55rem)}
.ph-web .browser .addr{color:var(--ink)}
/* ---- vignette « fenêtre » composée 2×2 (œuvres Web : colonne `tiles`) ---- */
.frame::after{content:"";position:absolute;inset:0;box-shadow:inset 0 0 0 1px var(--line);border-radius:8px;pointer-events:none;z-index:3}
.frame img{width:100%;height:auto;display:block;transition:transform .9s var(--ease),filter .5s ease;filter:saturate(.92)}
.work:hover .frame img{transform:scale(1.04);filter:saturate(1.08)}
.num{position:absolute;top:.7rem;left:.9rem;z-index:2;font-family:var(--display);font-weight:800;
  font-size:.85rem;letter-spacing:.04em;color:#fff;mix-blend-mode:difference}
.ribbon{position:absolute;top:.7rem;right:.7rem;z-index:2;font-size:.62rem;letter-spacing:.14em;
  text-transform:uppercase;font-weight:700;color:#080809;background-image:var(--grad);
  padding:.3rem .65rem;border-radius:999px}
.cat-tag{position:absolute;bottom:.7rem;right:.7rem;z-index:2;font-size:.66rem;letter-spacing:.12em;
  text-transform:uppercase;font-weight:700;
  background:color-mix(in srgb, var(--c, #fff) 32%, rgba(8,8,9,.55));backdrop-filter:blur(4px);
  border:1px solid color-mix(in srgb, var(--c, #fff) 55%, transparent);
  padding:.32rem .7rem;border-radius:999px;color:#fff;
  transform:translateY(.4rem);opacity:0;transition:.4s ease}
.work:hover .cat-tag{transform:none;opacity:1}
/* Site client dépublié : pas de grisé ni de badge - l'info « site inactif »
   apparaît uniquement à la place de l'URL (cf. .client-offline / .ss-cta-offline). */
figcaption{padding-top:.9rem;display:flex;justify-content:space-between;gap:1rem;align-items:baseline}
.work-title{font-family:var(--body);font-weight:500;font-size:1.02rem;line-height:1.2;letter-spacing:-.01em;
  position:relative;padding-left:.95rem}
.work-title::before{content:"";position:absolute;left:0;top:.42em;width:.5rem;height:.5rem;border-radius:50%;
  background:var(--c, var(--mut))}
.work-desc{display:block;font-size:.82rem;color:var(--mut);margin-top:.2rem;font-weight:400}
.work-date{font-size:.8rem;color:var(--c, var(--mut));
  white-space:nowrap;font-variant-numeric:tabular-nums;font-weight:600}
.gallery-empty{grid-column:1/-1;color:var(--mut);font-size:1rem;padding:2rem 0}
@media(hover:none){.cat-tag{opacity:1;transform:none}}

/* ---------- footer (« ultra coloré » : écho de l'en-tête) ---------- */
footer{position:relative;overflow:hidden;border-top:1px solid var(--line);
  padding:clamp(70px,12vh,150px) clamp(20px,5vw,56px) 44px;display:grid;gap:clamp(44px,7vh,80px)}
/* halos de la palette s2art en haut du footer - rappellent le mesh du héro */
.foot-glow{position:absolute;left:0;right:0;top:0;height:70%;z-index:0;pointer-events:none;
  opacity:.42;filter:blur(74px) saturate(150%);
  background:
    radial-gradient(42% 70% at 10% 4%,var(--blue),transparent 70%),
    radial-gradient(40% 70% at 40% 0%,var(--coral),transparent 70%),
    radial-gradient(40% 70% at 68% 6%,var(--gold),transparent 70%),
    radial-gradient(44% 70% at 94% 0%,var(--pink),transparent 70%)}
footer>*:not(.foot-glow){position:relative;z-index:1}
.foot-cta{display:flex;flex-direction:column;gap:.5rem}
.foot-kicker{font-size:clamp(11px,1.1vw,13px);letter-spacing:.4em;text-transform:uppercase;color:var(--ink)}
.foot-big{font-family:var(--display);font-weight:800;line-height:1;letter-spacing:-.025em;
  font-size:clamp(1.55rem,5vw,4rem);max-width:100%;overflow-wrap:break-word;
  /* dégradé PÉRIODIQUE (bleu→…→bleu) : la boucle d'animation est sans couture.
     L'ancien --grad (bleu→rose) créait une « cassure » nette en revenant au bleu. */
  background-image:var(--logo-grad);background-size:200% 100%;background-repeat:repeat;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:logoFlow 11s linear infinite;transition:opacity .3s}
.foot-big:hover{opacity:.82}
.foot-sub{font-size:clamp(13px,1.3vw,16px);color:var(--mut);margin-top:.4rem;max-width:36ch}
.foot-top{display:flex;justify-content:space-between;flex-wrap:wrap;gap:30px}
/* colonne contact : le formulaire prend plus de place que les listes */
.foot-col-contact{flex:1 1 320px;max-width:440px}

/* ---------- formulaire de contact ---------- */
.contact-form{display:flex;flex-direction:column;gap:12px;margin-top:2px}
.cf-field{display:flex;flex-direction:column;gap:5px}
.cf-field>span{font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--mut)}
.contact-form input,.contact-form textarea{
  width:100%;font:inherit;color:var(--ink);background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.18);border-radius:9px;padding:11px 13px;
  transition:border-color .25s,background .25s,box-shadow .25s;resize:vertical}
.contact-form input::placeholder,.contact-form textarea::placeholder{color:var(--mut)}
.contact-form input:focus,.contact-form textarea:focus{
  outline:none;border-color:transparent;background:rgba(255,255,255,.06);
  box-shadow:0 0 0 1.5px var(--coral)}
.cf-send{align-self:flex-start;font:inherit;font-weight:700;letter-spacing:.02em;cursor:pointer;
  color:#15110f;border:0;border-radius:999px;padding:12px 30px;
  background-image:var(--logo-grad);background-size:200% 100%;background-repeat:repeat;
  animation:logoFlow 11s linear infinite;transition:transform .2s var(--ease),filter .2s}
.cf-send:hover{transform:translateY(-2px);filter:brightness(1.07)}
.cf-send:active{transform:translateY(0)}
.cf-alt{margin-top:12px;font-size:13px}
/* pot de miel : hors écran, jamais visible/focusable au clavier visuellement */
.contact-form .hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
/* message de statut (succès / erreur) */
.form-msg{border-radius:9px;padding:10px 13px;margin-bottom:14px;font-size:14px;line-height:1.4}
.form-msg-ok{background:rgba(95,200,130,.13);border:1px solid rgba(95,200,130,.4);color:#bff0cc}
.form-msg-err{background:rgba(255,90,90,.12);border:1px solid rgba(255,90,90,.4);color:#ffc9c9}
/* couleur « dans » les champs : un accent de la palette par champ au focus */
.contact-form input[name="name"]:focus{box-shadow:0 0 0 1.6px var(--blue)}
.contact-form input[name="email"]:focus{box-shadow:0 0 0 1.6px var(--coral)}
.contact-form textarea:focus{box-shadow:0 0 0 1.6px var(--gold)}
.contact-form .cf-field>span{color:var(--ink);opacity:.85}

/* ---------- déclencheur + modale de contact (centrée, sans JS via case à cocher) ---------- */
.cf-intro{color:var(--mut);font-size:14px;line-height:1.55;margin-bottom:16px;max-width:34ch}
.cmodal-toggle{position:absolute;opacity:0;width:0;height:0;pointer-events:none}
.cf-open{display:inline-flex;align-items:center;gap:.5em;cursor:pointer;font-weight:700;
  letter-spacing:.02em;color:#15110f;border-radius:999px;padding:12px 26px;
  background-image:var(--logo-grad);background-size:200% 100%;background-repeat:repeat;
  animation:logoFlow 11s linear infinite;transition:transform .2s var(--ease),filter .2s}
.cf-open::before{content:"✎";font-size:1.05em}
.cf-open:hover{transform:translateY(-2px);filter:brightness(1.07)}
.cf-direct{margin-top:18px;font-size:13px;color:var(--mut);display:flex;flex-direction:column;gap:7px}
.cf-direct a{color:var(--ink);border-bottom:1px solid var(--line);width:max-content;transition:border-color .25s}
.cf-direct a:hover{border-color:var(--ink)}

.contact-modal{position:fixed;inset:0;z-index:1200;display:grid;place-items:center;padding:5vh 5vw;
  opacity:0;pointer-events:none;transition:opacity .4s var(--ease)}
.cmodal-toggle:checked ~ .contact-modal{opacity:1;pointer-events:auto}
.cm-backdrop{position:absolute;inset:0;cursor:pointer;background:rgba(5,5,7,.86);backdrop-filter:blur(18px)}
/* carte SOMBRE et lisible + fin liseré multicolore (technique padding-box /
   border-box : seul le bord prend le dégradé, le fond reste sombre et net). */
.cm-card{position:relative;width:min(500px,100%);max-height:90vh;overflow:auto;
  border:2px solid transparent;border-radius:20px;padding:clamp(24px,4vw,38px);
  background:linear-gradient(180deg,#191920,#101015) padding-box,
            var(--logo-grad) border-box;
  box-shadow:0 50px 120px rgba(0,0,0,.6);transform:translateY(18px) scale(.97);
  transition:transform .45s var(--ease)}
.cmodal-toggle:checked ~ .contact-modal .cm-card{transform:none}
.cm-title{font-family:var(--display);font-weight:800;font-size:clamp(1.5rem,3.6vw,2.1rem);
  letter-spacing:-.02em;line-height:1.05;margin-bottom:6px;width:max-content;max-width:100%;
  background-image:var(--logo-grad);background-size:200% 100%;background-repeat:repeat;
  -webkit-background-clip:text;background-clip:text;color:transparent;animation:logoFlow 11s linear infinite}
.cm-sub{color:var(--mut);font-size:14px;line-height:1.55;margin-bottom:22px;max-width:42ch}
.cm-close{position:absolute;top:14px;right:16px;z-index:2;width:40px;height:40px;border-radius:50%;
  display:grid;place-items:center;cursor:pointer;font-size:20px;line-height:1;color:var(--ink);
  border:1px solid var(--line);background:rgba(255,255,255,.05);transition:background .25s,transform .25s var(--ease)}
.cm-close:hover{background:rgba(255,255,255,.14);transform:rotate(90deg)}
.foot-col h2{font-family:var(--display);font-weight:700;font-size:.78rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--mut);margin-bottom:14px}
.foot-col ul{list-style:none}
.foot-col li{margin-bottom:8px}
.foot-col a{color:var(--ink);position:relative;transition:color .25s}
.foot-col a:hover{color:#fff}
.foot-col a::after{content:"";position:absolute;left:0;bottom:-3px;height:1px;width:0;background:var(--grad);transition:width .3s var(--ease)}
.foot-col a:hover::after{width:100%}
.foot-legal{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:14px;
  font-size:12px;letter-spacing:.1em;color:var(--mut);text-transform:uppercase;
  border-top:1px solid var(--line);padding-top:24px}
.foot-legal a{color:var(--mut);position:relative;transition:color .25s}
.foot-legal a:hover{color:var(--ink)}
.foot-legal a::after{content:"";position:absolute;left:0;bottom:-3px;height:1px;width:0;background:var(--grad);transition:width .3s var(--ease)}
.foot-legal a:hover::after{width:100%}

/* ---------- bouton « retour en haut » ---------- */
.to-top{position:fixed;right:clamp(16px,3vw,28px);bottom:clamp(16px,3vw,28px);z-index:90;
  width:48px;height:48px;border-radius:50%;border:0;cursor:pointer;display:grid;place-items:center;
  font-size:20px;line-height:1;color:#080809;background-image:var(--grad);background-size:160% 100%;
  box-shadow:0 12px 30px rgba(0,0,0,.42);opacity:0;transform:translateY(14px) scale(.9);
  transition:opacity .35s var(--ease),transform .35s var(--ease),background-position .5s ease}
.to-top.show{opacity:1;transform:none}
.to-top:hover{transform:translateY(-3px) scale(1.06);background-position:100% 50%}
@media(max-width:760px){.to-top{width:44px;height:44px}}

/* ---------- page « mentions légales » ---------- */
.legal-page{padding-top:clamp(110px,16vh,160px);padding-bottom:clamp(40px,8vh,90px)}
.legal{max-width:760px}
.legal-eyebrow{font-size:clamp(11px,1.1vw,13px);letter-spacing:.4em;text-transform:uppercase;color:var(--mut);margin-bottom:.8rem}
.legal h1{font-family:var(--display);font-weight:800;letter-spacing:-.02em;line-height:1.02;
  font-size:clamp(2.2rem,6vw,3.6rem);margin-bottom:clamp(28px,5vh,48px);
  background-image:var(--logo-grad);background-size:200% 100%;background-repeat:repeat;
  -webkit-background-clip:text;background-clip:text;
  color:transparent;width:max-content;max-width:100%;animation:logoFlow 11s linear infinite}
.legal section{margin-bottom:clamp(26px,4vh,40px)}
.legal h2{font-family:var(--display);font-weight:700;font-size:1.15rem;letter-spacing:.01em;margin-bottom:.7rem;color:var(--ink)}
.legal p{color:var(--mut);line-height:1.65;margin-bottom:.7rem;max-width:62ch}
.legal strong{color:var(--ink);font-weight:600}
.legal ul{list-style:none;display:grid;gap:.45rem;color:var(--mut);line-height:1.5}
.legal a{color:var(--ink);border-bottom:1px solid var(--line);transition:border-color .25s}
.legal a:hover{border-color:var(--ink)}
.legal .todo{color:var(--gold);font-style:italic;border:1px dashed color-mix(in srgb,var(--gold) 50%,transparent);
  padding:0 .4em;border-radius:4px}
.legal-back{margin-top:clamp(30px,5vh,50px)}
.legal-back a{font-size:.95rem;letter-spacing:.02em}

/* ---------- lightbox ---------- */
.lightbox{position:fixed;inset:0;z-index:1000;display:grid;place-items:center;padding:5vh 5vw;
  background:rgba(5,5,7,.92);backdrop-filter:blur(22px);opacity:0;pointer-events:none;transition:opacity .4s}
.lightbox.open{opacity:1;pointer-events:auto}
.lightbox figure{display:flex;flex-direction:column;align-items:center;gap:16px;transform:scale(.96);transition:transform .5s var(--ease)}
.lightbox.open figure{transform:scale(1)}
.lightbox img{max-width:88vw;max-height:80vh;border-radius:8px;box-shadow:0 40px 100px rgba(0,0,0,.65)}
.lightbox figcaption{display:block;font-size:13px;letter-spacing:.05em;color:var(--mut);text-align:center}
.lightbox .close{position:absolute;top:24px;right:30px;width:46px;height:46px;border-radius:50%;
  border:1px solid var(--line);background:rgba(255,255,255,.06);color:var(--ink);font-size:20px;cursor:pointer}

/* ---------- showcase site (projets Web) : vue plein écran « éditoriale ».
   On part d'une SEULE capture (souvent basse déf) : on ne l'agrandit pas, on la
   CADRE. Cadre navigateur qui fait défiler la capture pleine page (révèle le
   haut/milieu/bas du site = ses différents éléments, à taille ~native), mock
   mobile superposé (même image, autre cadrage), fond plein écran flouté (le flou
   masque la basse déf) et grande typo. ---------- */
.siteshow{position:fixed;inset:0;z-index:1100;display:grid;
  grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);align-items:center;gap:clamp(20px,4vw,64px);
  padding:clamp(24px,6vh,72px) clamp(24px,6vw,84px);
  opacity:0;pointer-events:none;transition:opacity .45s var(--ease);--ssc:var(--gold)}
.siteshow.open{opacity:1;pointer-events:auto}
/* fond plein écran flouté = couche la PLUS LOINTAINE (bouge le moins, à l'inverse
   du curseur) ; --px/--py (-0.5..0.5) sont posés par front.js au survol. */
.ss-bg{position:absolute;inset:0;z-index:-2;background-size:cover;background-position:50% 20%;
  filter:blur(58px) saturate(135%) brightness(.62);
  transform:scale(1.28) translate3d(calc(var(--px,0)*-10px),calc(var(--py,0)*-10px),0);
  transition:transform .35s ease-out}
.ss-bg::after{content:"";position:absolute;inset:0;
  background:radial-gradient(120% 90% at 30% 30%,rgba(8,8,9,.35),rgba(5,5,7,.9))}
.siteshow .close{position:absolute;top:24px;right:30px;z-index:3;width:46px;height:46px;border-radius:50%;
  border:1px solid var(--line);background:rgba(255,255,255,.07);color:var(--ink);font-size:20px;cursor:pointer;
  backdrop-filter:blur(8px);transition:background .25s,transform .25s var(--ease)}
.siteshow .close:hover{background:rgba(255,255,255,.16);transform:rotate(90deg)}

/* scène : tilt 3D léger vers le curseur (comme le logo) ; les couches enfants
   ajoutent leur propre translation -> les plus proches bougent plus vite. */
.ss-stage{position:relative;justify-self:center;width:100%;max-width:760px;
  opacity:0;transition:opacity .55s var(--ease) .05s,transform .25s ease-out;
  transform-style:preserve-3d;
  transform:perspective(1600px) rotateY(calc(var(--px,0)*7deg)) rotateX(calc(var(--py,0)*-7deg))}
.siteshow.open .ss-stage{opacity:1}
/* cadre navigateur (couche médiane) */
.ss-browser{position:relative;border-radius:14px;overflow:hidden;background:#101013;
  box-shadow:0 50px 110px rgba(0,0,0,.62),0 0 0 1px var(--line);
  transform:translate3d(calc(var(--px,0)*-16px),calc(var(--py,0)*-16px),0);
  transition:transform .3s ease-out}
.ss-browser .browser{height:38px}
.ss-browser .browser .addr{max-width:60%;margin:0 auto}
.ss-window{position:relative;overflow:hidden;aspect-ratio:16/10;background:#0c0c0f}
.ss-window img{position:absolute;top:0;left:0;width:100%;height:auto;display:block;
  animation:ssPan var(--ss-dur,18s) var(--ease) infinite}
/* part du HAUT, descend lentement (6%..90%), puis repart AUSSITÔT vers le haut (remontée VITE) */
@keyframes ssPan{0%,6%{transform:translateY(0)}90%{transform:translateY(var(--ss-pan,0px))}100%{transform:translateY(0)}}
.ss-window::after{content:"";position:absolute;inset:0;pointer-events:none;box-shadow:inset 0 0 60px rgba(0,0,0,.35)}
/* vignettes flottantes (couches proches, rapides) : chacune cadre une ZONE
   DIFFÉRENTE de la même capture pleine page -> on voit plusieurs parties du site. */
.ss-card{position:absolute;z-index:2;aspect-ratio:4/3;border-radius:10px;overflow:hidden;
  background:#0c0c0f;box-shadow:0 26px 50px rgba(0,0,0,.58),0 0 0 1px var(--line);
  transition:transform .3s ease-out}
.ss-card img{width:100%;height:100%;object-fit:cover}
.ss-card::after{content:"";position:absolute;inset:0;pointer-events:none;box-shadow:inset 0 0 40px rgba(0,0,0,.3)}
/* c1 : haut-gauche -> EN-TÊTE du site */
.ss-c1{left:-30px;top:-28px;width:31%;min-width:128px;max-width:218px;
  transform:rotate(-4deg) translate3d(calc(var(--px,0)*-30px),calc(var(--py,0)*-30px),0)}
.ss-c1 img{object-position:50% 0}
/* c2 : coin haut-droite du navigateur -> HAUT-MILIEU (reste dans la scène) */
.ss-c2{right:3%;top:-30px;width:26%;min-width:112px;max-width:188px;
  transform:rotate(5deg) translate3d(calc(var(--px,0)*-20px),calc(var(--py,0)*-20px),0)}
.ss-c2 img{object-position:50% 34%}
/* c3 : bas-gauche -> BAS-MILIEU */
.ss-c3{left:-22px;bottom:-34px;width:29%;min-width:120px;max-width:200px;
  transform:rotate(-6deg) translate3d(calc(var(--px,0)*-34px),calc(var(--py,0)*-34px),0)}
.ss-c3 img{object-position:50% 70%}
/* mock mobile superposé (couche la plus proche, la plus rapide) : cadrage du BAS */
.ss-phone{position:absolute;right:-14px;bottom:-30px;z-index:2;width:23%;min-width:104px;max-width:158px;
  aspect-ratio:9/19;border-radius:18px;overflow:hidden;background:#000;
  box-shadow:0 26px 54px rgba(0,0,0,.6),0 0 0 4px #161619,0 0 0 5px rgba(255,255,255,.08);
  transform:rotate(5deg) translate3d(calc(var(--px,0)*-38px),calc(var(--py,0)*-38px),0);
  transition:transform .3s ease-out}
.ss-phone img{width:100%;height:100%;object-fit:cover;object-position:50% 100%}
.ss-phone::before{content:"";position:absolute;top:7px;left:50%;transform:translateX(-50%);
  width:34%;height:5px;border-radius:3px;background:rgba(255,255,255,.25);z-index:2}

.ss-meta{max-width:46ch;display:flex;flex-direction:column;gap:14px}
.ss-cat{font-size:12px;letter-spacing:.34em;text-transform:uppercase;color:var(--ssc);font-weight:700}
.ss-title{font-family:var(--display);font-weight:800;line-height:1.02;letter-spacing:-.02em;
  font-size:clamp(1.8rem,4.4vw,3.4rem);margin:0;overflow-wrap:break-word;hyphens:auto;
  background:linear-gradient(100deg,var(--ink),color-mix(in srgb,var(--ssc) 60%,var(--ink)));
  -webkit-background-clip:text;background-clip:text;color:transparent}
.ss-desc{color:var(--ink);opacity:.84;font-size:clamp(14px,1.5vw,17px);line-height:1.55;margin:0}
.ss-foot{display:flex;align-items:center;gap:18px;flex-wrap:wrap;margin-top:6px}
.ss-foot time{color:var(--ssc);font-size:14px;letter-spacing:.04em;font-weight:600}
/* CTA = lien TEXTE (même esprit que « Voir le site » de la galerie), pas un bouton */
.ss-cta{display:inline-flex;align-items:center;gap:.4em;font-weight:700;font-size:15px;letter-spacing:.02em;
  background-image:var(--grad);-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;transition:opacity .25s}
.ss-cta:hover{opacity:.7}
.ss-cta[hidden]{display:none}
/* variante « nom du client » : majuscules, gras, dégradé multicolore vivant */
.ss-cta.ss-cta-client{font-family:var(--display);font-weight:800;font-size:clamp(1.15rem,2.6vw,1.7rem);
  letter-spacing:.05em;text-transform:uppercase;
  background-image:var(--logo-grad);background-size:200% 100%;background-repeat:repeat;
  animation:logoFlow 11s linear infinite}
.ss-cta-client .dmd-ic{fill:var(--ssc);margin-right:0;width:.85em;height:.85em}
/* Site dépublié en plein écran : AUCUN grisé / noir et blanc (demande client
   explicite). L'inactivité se signale UNIQUEMENT par le CTA « Site inactif »
   ci-dessous - le visuel du site reste en pleine couleur. */
.ss-cta.ss-cta-offline{background:none;-webkit-text-fill-color:currentColor;color:var(--mut);
  font-family:var(--body);font-weight:700;text-transform:none;letter-spacing:.02em;
  font-size:15px;animation:none;cursor:default;pointer-events:none;
  border:1px solid var(--line);border-radius:999px;padding:.3rem .8rem}

/* accent (--ssc) par catégorie de l'œuvre affichée en plein écran */
.siteshow[data-category="Print"]{--ssc:var(--blue)}
.siteshow[data-category="Pub"]  {--ssc:var(--coral)}
.siteshow[data-category="Web"]  {--ssc:var(--gold)}
.siteshow[data-category="Logo"] {--ssc:var(--pink)}

/* mode « œuvre » (tout sauf Web) : l'IMAGE en grand, cadrée à SA propre taille
   (pas de cadre navigateur, pas de bandes noires), informations à côté. Le cadre
   épouse l'image (aucun fond visible) ; on garde le tilt 3D et le fond flouté.
   Les miniatures flottantes sont réservées aux sites web. */
.siteshow.ss-art .ss-stage{max-width:none}
.siteshow.ss-art .ss-browser{background:transparent;box-shadow:none;border-radius:0;overflow:visible}
.siteshow.ss-art .ss-browser .browser{display:none}
/* cadre transparent à hauteur d'écran : l'image remplit la hauteur (contain),
   pas de bandes noires (marges transparentes sur le fond flouté) ; l'ombre
   « drop-shadow » épouse le contour réel de l'œuvre. */
.siteshow.ss-art .ss-window{aspect-ratio:auto;overflow:visible;background:transparent;height:82vh}
.siteshow.ss-art .ss-window img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:contain;filter:drop-shadow(0 28px 64px rgba(0,0,0,.55));
  animation:none;transform:none}
.siteshow.ss-art .ss-window::after{display:none}
/* hors Web : image seule (ni vignettes ni mock mobile) */
.siteshow.ss-art .ss-card,.siteshow.ss-art .ss-phone{display:none}

@media(max-width:860px){
  /* overflow-x:hidden indispensable : sinon le fond flouté (scale 1.28) rend la
     vue décalable horizontalement au doigt. On ne défile QUE verticalement. */
  .siteshow{grid-template-columns:1fr;align-content:center;gap:26px;overflow:hidden auto;
    padding:80px 22px 40px}
  .ss-stage{max-width:480px}
  .ss-browser{transform:none}
  .ss-c2,.ss-c3{display:none}
  .ss-phone{width:26%;right:-6px;bottom:-22px}
  .siteshow.ss-art .ss-window{height:58vh}
  .ss-meta{max-width:none;text-align:center;align-items:center}
  .ss-foot{justify-content:center}
}

@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
  .feature .ph{clip-path:none!important}
  .feature .ph img,.feature.in .ph img{transform:none!important;position:static;height:auto;top:auto}
  .feature,.eyebrow,.logo-hero,.hero p.sub,.js .work{opacity:1!important;transform:none!important;filter:none!important}
  .cursor{display:none!important}
  html{scroll-behavior:auto}
}
