:root{
  /* loaded web fonts (see index.html) — same file everywhere, so weight/shape
     render identically on every device instead of depending on which system
     fonts happen to be installed (that's what was making titles look much
     bolder on desktop than on phones that don't have Avenir Next) */
  --mono:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Consolas,monospace;
  --display:'Poppins',-apple-system,'Helvetica Neue',Arial,sans-serif;
  --ink:#1a1a17;
  --paper:#f3f2ec;
  /* overridden from SETTINGS (CMS Réglages) in app.js; defaults here just
     keep the page sane before JS runs */
  --header-color:#1a1a17;
  --header-bg:#f3f2ec;
  --header-line:#1a1a17;
  --header-logo-scale:1;
}
*{box-sizing:border-box;min-width:0}
html{scroll-behavior:smooth;font-size:calc(100% * var(--scale,1))}
body{
  margin:0;
  font-family:var(--display);
  background:var(--paper);
  color:var(--ink);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;border:0;background:none;cursor:pointer;padding:0}
button:focus-visible,a:focus-visible{outline:3px solid currentColor;outline-offset:4px}
img{max-width:100%;display:block}
[hidden]{display:none!important}

/* Mobile first: base rules below target phones in portrait.
   The min-width:720px block near the end adapts the same markup for desktop. */

.screen{min-height:100vh;min-height:100dvh;width:100%}

/* generic tap targets + app-like controls */
.tap{padding:10px 12px;margin:-10px -12px;display:inline-flex;align-items:center}
.burger{font-size:26px;line-height:1;padding:14px;margin:-14px}

/* ---------- swatch motif (cover only) ---------- */
.swatch{width:42px;display:flex;flex-direction:column;position:absolute;top:0;left:0;z-index:2}
.swatch i{display:block;width:100%;aspect-ratio:1/1;transition:background-color 1.2s ease}

/* ---------- COVER ---------- */
#cover{
  background:#41c1f0;
  color:#262626;
  position:relative;
  display:flex;
  flex-direction:column;
  justify-content:space-between;
  padding:22px 20px 28px;
  cursor:pointer;
  /* only used when the theme color carousel (CMS Réglages) is on — a
     plain single theme color never re-triggers this (see paintCover in
     app.js, which skips the transition on its very first, page-load call).
     The text itself (SETTINGS.coverTextColor) stays fixed, so only the
     background actually needs to transition. */
  transition:background-color 1.2s ease;
}
/* "roller blind" cover→sommaire transition (app.js: revealSommaireWithBlind) —
   one continuous motion: a small tug down, then released and swept fully
   off-screen, as if pulling a blind's cord. Per-keyframe timing-functions
   (not just the animation's own) keep the handoff between the two beats
   smooth instead of an abrupt change of speed. Only applied for the
   animation's duration; #cover is normal in-flow content the rest of the
   time. */
@keyframes blind-release{
  0%{transform:translateY(0);animation-timing-function:cubic-bezier(.3,0,.6,1)}
  24%{transform:translateY(3%);animation-timing-function:cubic-bezier(.5,0,.16,1)}
  100%{transform:translateY(-100%)}
}
#cover.blind-animating{
  position:fixed;inset:0;z-index:42;will-change:transform;
  animation:blind-release .78s forwards;
}
#cover .top{display:flex;justify-content:flex-start}
/* margin-left clears the color swatch (which sits at the absolute left
   edge, ignoring #cover's own padding) plus a small gap */
#cover .contact{font-family:var(--mono);font-size:11px;line-height:1.7;text-align:left;margin-left:36px}
#cover .contact .name{
  display:block;font-family:var(--display);font-weight:600;font-size:17px;
  letter-spacing:-.02em;margin-bottom:6px;
}
/* title + "voir le sommaire" live together, centered in the space below
   the top row — same arrangement on phone and desktop alike, the title
   just scales a bit with viewport width via clamp() */
#cover .middle{
  flex:1;min-height:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:22px;
  padding:0 16px;
}
#cover .wordmark{
  font-family:var(--display);
  font-weight:800;
  font-size:clamp(2.25rem,7vw,4.5rem);
  line-height:.95;
  letter-spacing:-.03em;
  text-transform:uppercase;
  text-align:center;
  margin:0;
  max-width:100%;
  overflow:hidden;
}
#cover .enter{
  font-family:var(--mono);font-size:11px;letter-spacing:.03em;
  border:1px solid color-mix(in srgb, var(--cover-text,#fff) 55%, transparent);padding:11px 16px;border-radius:999px;
  display:inline-flex;align-items:center;gap:8px;
}
/* --cover-color and --cover-text are set inline on #cover (app.js,
   paintCover) so these always match the actual background/text colors,
   whatever they're set to (incl. via the CMS) */
#cover .enter:hover{background:var(--cover-text,#262626);color:var(--cover-color,#41c1f0)}
/* sized against .enter's own rendered WIDTH (the button text is fixed,
   so its width barely moves) — a touch narrower than the button, per
   spec; being square, its height follows from that width */
#cover .cover-logo{--eb-size:148px;--eb-color:#fff;--patate-size:148px}
/* applies when the CMS swaps the animated logo (<eb-logo> or
   <patate-fusion>) for a plain <img> (custom logo) — the built-in
   component sizes itself from --eb-size/--patate-size via its own
   shadow-DOM :host rule, a plain <img> needs this explicitly */
img.cover-logo,img.brand-logo{width:var(--eb-size);aspect-ratio:1;object-fit:contain;display:inline-block;vertical-align:middle}

/* ---------- SOMMAIRE ---------- */
/* --sommaire-bg is set from SETTINGS.sommaireColor (CMS Réglages),
   falling back to the same paper tone used everywhere else */
#sommaire{background:var(--sommaire-bg,var(--paper));padding-bottom:50px}
#sommaire header{
  display:flex;justify-content:space-between;align-items:center;gap:12px;
  padding:16px 20px;border-bottom:1px solid var(--header-line);position:sticky;top:0;background:var(--header-bg);z-index:5;
}
#sommaire header .brand-wrap{display:flex;align-items:center;gap:8px}
/* a touch taller than .brand's own line-height on purpose (per explicit
   feedback: "a little bigger, but not much") — the header is allowed
   to grow by the same sliver. --header-logo-scale (CMS Réglages) scales
   this base size up/down without touching the mobile/desktop ratio. */
#sommaire header .brand-logo{--eb-size:calc(19px * var(--header-logo-scale));--eb-color:var(--header-color);--patate-size:calc(19px * var(--header-logo-scale));flex:none}
#sommaire header .brand{font-weight:800;letter-spacing:-.02em;font-size:12px;text-transform:uppercase;color:var(--header-color)}
#sommaire header .back{font-family:var(--mono);font-size:12px;color:var(--header-color);opacity:.55;white-space:nowrap}
#sommaire header .back:hover{opacity:1}
.sommaire-body{background:var(--sommaire-bg,var(--paper));color:inherit}
#sommaire h1{
  font-size:clamp(2.125rem,10vw,4rem);font-weight:800;letter-spacing:-.03em;
  margin:32px 20px 10px;text-transform:uppercase;color:var(--header-color);
}
#sommaire .intro{margin:0 20px 28px;font-family:var(--mono);font-size:12px;color:var(--header-color);opacity:.72;max-width:520px}
.sommaire-preview{display:none}

/* ---------- category bands (sommaire + drawer) ----------
   The whole row — name+count and the chevron alike — just toggles the
   inline project grid open/closed; there's no separate category page to
   link to any more (the contact band is the one exception: its name
   still links through to the full #contact page). */
/* lets a "Gradation accueil" category band's recolor (theme carousel,
   app.js paintCategoryBands) fade smoothly instead of jump-cutting —
   each band already gets its own small stagger on top of this */
.cat-band{transition:background-color .35s ease, color .35s ease}
.band-row{display:flex;align-items:stretch}
.band-link{
  flex:1;min-width:0;display:flex;align-items:center;gap:10px;
  padding:0 20px;text-align:left;
}
.cat-band h2{
  margin:0;padding:13px 0;min-width:0;flex:1;
  font-size:clamp(1.0625rem,4.2vw,1.75rem);font-weight:800;letter-spacing:-.02em;text-transform:uppercase;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.cat-band .count{display:none;font-family:var(--mono);font-size:12px;opacity:.75;white-space:nowrap;flex:0 0 auto}
.chev-btn{flex:0 0 auto;width:64px;display:flex;align-items:center;justify-content:center}
.chev-btn .chev{font-size:24px;transition:transform .35s ease;opacity:.9;display:block}
.cat-band.expanded .chev-btn .chev{transform:rotate(180deg)}

.collapse{display:grid;grid-template-rows:0fr;transition:grid-template-rows .45s cubic-bezier(.4,0,.2,1)}
.collapse-inner{overflow:hidden}
.cat-band.expanded .collapse{grid-template-rows:1fr}

.cat-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));
}
.tile{
  aspect-ratio:1/1;position:relative;padding:12px 12px 4px;display:flex;flex-direction:column;justify-content:flex-end;
  overflow:hidden;
}
.tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .35s ease}
.tile:hover img{transform:scale(1.04)}
.tile .scrim{position:absolute;inset:0;background:linear-gradient(to top,rgba(0,0,0,.45),transparent 45%)}
.tile .meta{position:relative;color:#fff}
/* negative margin eats into the font's own built-in leading (line-height:1
   alone still leaves ~8px of untouchable space) — title→date gap and
   date→bottom-edge gap are kept equal on purpose */
.tile .meta b{display:block;font-size:13px;font-weight:700;letter-spacing:-.01em;line-height:1;margin:0 0 4px;text-shadow:0 1px 4px rgba(0,0,0,.4)}
.tile .meta span{display:block;font-family:var(--mono);font-size:10px;line-height:1;opacity:.9;text-shadow:0 1px 4px rgba(0,0,0,.4)}

/* ---------- CATEGORIE (dedicated mobile page) ---------- */
#categorie{padding-bottom:40px}
#categorie .bar{display:flex;align-items:center;gap:12px;padding:12px 14px;font-family:var(--mono);font-size:12px;position:sticky;top:0;background:inherit;z-index:2}
#categorie h1{
  font-size:clamp(2.125rem,11vw,4rem);font-weight:800;letter-spacing:-.03em;
  margin:18px 20px 18px;text-transform:uppercase;
}
.cat-grid-page{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}

/* ---------- CONTACT (dedicated page + sommaire/drawer preview) ---------- */
#contact{padding-bottom:60px}
#contact .bar{display:flex;align-items:center;padding:12px 14px}
#contact h1{
  font-size:clamp(2.125rem,11vw,4rem);font-weight:800;letter-spacing:-.03em;
  margin:18px 20px 24px;text-transform:uppercase;
}
.contact-lines{padding:20px;display:flex;flex-direction:column;gap:8px}
.contact-lines .line{font-family:var(--mono);font-size:14px;word-break:break-word}
.contact-lines .line.name{font-family:var(--display);font-weight:800;font-size:18px;letter-spacing:-.01em;text-transform:uppercase}
.contact-lines.big{padding:0 20px;gap:14px}
.contact-lines.big .line{font-size:18px}
.contact-lines.big .line.name{font-size:clamp(1.5rem,6vw,2.25rem)}

/* ---------- PROJECT SPREAD ---------- */
#projet{position:relative;display:flex;flex-direction:column}
#projet .bar{
  display:flex;justify-content:space-between;align-items:center;padding:12px 14px;
  font-family:var(--mono);font-size:11px;gap:10px;
}
#projet .bar-left{display:flex;align-items:center;gap:6px}
#projet .bar a:hover,#projet .bar button:hover{opacity:.6}
#projet .crumb{text-decoration:underline;text-underline-offset:3px;text-decoration-color:rgba(255,255,255,.4)}
#projet.dark .crumb{text-decoration-color:rgba(0,0,0,.3)}
#projet .projet-swiper{flex:1;min-height:0;width:100%}
#projet .projet-swiper,#projet .swiper-wrapper,#projet .swiper-slide{height:100%}
#projet .swiper-slide{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:16px;padding:20px 20px 100px;overflow:hidden;
}
#projet .main{max-width:100%;display:flex;flex-direction:column;align-items:center}
#projet .page-img{
  display:block;width:auto;height:auto;max-width:92vw;max-height:58vh;
  border-radius:3px;cursor:zoom-in;
  box-shadow:0 30px 60px -20px rgba(0,0,0,.4);
}
/* video/YouTube projects share .page-img's sizing (same max-width/
   max-height box, same desktop flex:1 override below) — a <video>'s
   own intrinsic ratio (once its metadata loads) overrides the 16/9
   fallback automatically; an <iframe> has no intrinsic ratio ever, so
   it needs one fixed. Neither is "zoomable" like a page image. */
#projet .page-video{aspect-ratio:auto 16/9;cursor:default;background:#000}
#projet .page-video-embed{aspect-ratio:16/9;cursor:default;border:0}
#projet .caption{margin-top:18px;text-align:center}
#projet .caption h1{
  font-size:clamp(1.375rem,6.5vw,2rem);font-weight:800;letter-spacing:-.02em;margin:0 0 6px;
  text-transform:uppercase;
}
#projet .caption .date{font-family:var(--mono);font-size:12px;opacity:.75}
#projet .source-note{
  font-family:var(--mono);font-size:10px;opacity:.55;margin-top:10px;max-width:420px;text-align:center;
}

/* "video-list" project: a normal page (own image, like any other
   project — see buildMedia) with one addition, a link to a dedicated
   gallery screen (#videos) listing every video as its own grid tile.
   Keeping this off the project's own swiper slide — a fixed-height,
   one-screen-per-project carousel — is what actually fixes the
   months-long saga of fighting that slide to also fit a variable-
   length, scrollable list into it; a plain grid page has none of
   that slide's constraints to begin with. */
/* same box as the plain .date line (same tag, same class) — only the
   underline is added, so swapping it in adds zero height anywhere.
   display:block (not inline-block) matters here: an inline-block <a>
   sits in an inline formatting context and picks up a few stray px of
   baseline/strut spacing that a block-level .date div never had */
#projet .video-list-link{
  display:block;text-decoration:underline;text-underline-offset:3px;
}
#projet .video-list-link:hover{opacity:1}

/* the play badge sits on any video thumbnail — the gallery grid here,
   or the project's own page when mediaType is a single "video" */
.play-badge{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,.15);transition:background-color .2s ease;
}
.play-badge svg{width:40px;height:40px;filter:drop-shadow(0 4px 10px rgba(0,0,0,.5))}

/* ---------- VIDEOS gallery (dedicated page, one per video-list project) ---------- */
#videos{padding-bottom:40px}
#videos .bar{display:flex;align-items:center;gap:12px;padding:12px 14px;font-family:var(--mono);font-size:12px;position:sticky;top:0;background:inherit;z-index:2}
#videos .crumb{text-decoration:underline;text-underline-offset:3px}
#videos h1{
  font-size:clamp(2.125rem,11vw,4rem);font-weight:800;letter-spacing:-.03em;
  margin:18px 20px 18px;text-transform:uppercase;
}
.video-gallery-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));
  gap:28px 18px;padding:0 20px;
}
.video-tile{cursor:pointer}
.video-tile .video-thumb{
  position:relative;width:100%;aspect-ratio:16/9;border-radius:3px;overflow:hidden;
  background:#000;box-shadow:0 14px 28px -12px rgba(0,0,0,.4);
}
.video-tile .video-thumb img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .35s ease}
.video-tile:hover .video-thumb img{transform:scale(1.04)}
.video-tile:hover .play-badge{background:rgba(0,0,0,.3)}
.video-tile .video-meta{font-family:var(--mono);font-size:11px;opacity:.7;margin-top:8px;text-align:center}

/* ---------- IMAGES gallery (dedicated page, one per image-list project) ----------
   Same screen/grid pattern as the videos gallery above, just square
   tiles (no fixed 16/9 "video thumbnail" shape makes sense for a mix of
   photos/drawings) and no play badge. */
#images{padding-bottom:40px}
#images .bar{display:flex;align-items:center;gap:12px;padding:12px 14px;font-family:var(--mono);font-size:12px;position:sticky;top:0;background:inherit;z-index:2}
#images .crumb{text-decoration:underline;text-underline-offset:3px}
#images h1{
  font-size:clamp(2.125rem,11vw,4rem);font-weight:800;letter-spacing:-.03em;
  margin:18px 20px 18px;text-transform:uppercase;
}
.image-gallery-grid{
  display:grid;grid-template-columns:repeat(2,1fr);
  gap:20px 14px;padding:0 20px;
}
.image-tile{cursor:pointer}
.image-tile .image-thumb{
  position:relative;width:100%;aspect-ratio:1/1;border-radius:3px;overflow:hidden;
  background:#000;box-shadow:0 14px 28px -12px rgba(0,0,0,.4);
}
.image-tile .image-thumb img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .35s ease}
.image-tile:hover .image-thumb img{transform:scale(1.04)}
.image-tile .image-meta{margin-top:8px;text-align:center}
/* title stays in the display font (same one as every title on the
   site) but small — it's a caption, not a heading; date/médium/format
   stay in the mono font, same as everywhere else that kind of info
   (date, category, tools) appears */
.image-tile .image-meta-title{display:block;font-family:var(--display);font-size:12px;font-weight:600;opacity:.92}
.image-tile .image-meta-sub{display:block;font-family:var(--mono);font-size:11px;opacity:.6;margin-top:3px}

/* ---------- lightbox video (same overlay as the image lightbox) ---------- */
.lightbox-video-wrap{width:min(92vw,960px);aspect-ratio:16/9}
.lightbox-video-wrap iframe{display:block;width:100%;height:100%;border:0;border-radius:2px}

/* ---------- floating prev/next ----------
   The two round arrow buttons sit glued together at the exact
   bottom-center of the screen and never move. Each project title
   floats beside its arrow, growing outward, without ever
   shifting the buttons themselves.
   #float-nav itself is not a positioning container (display:contents) —
   each child is its own independent position:fixed element, centered
   directly against the viewport. Avoids the previous setup where every
   child's left:50% was relative to a shared, zero-width fixed parent;
   that nesting is unusual enough that some mobile engines may mis-place
   it mid-reflow, which is the leading suspect for the reported jump. */
#float-nav{display:contents}
#float-nav .arrow-btn{
  position:fixed;bottom:18px;width:46px;height:46px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:19px;
  background:rgba(18,18,16,.5);color:#fff;z-index:30;
  /* the dark drop-shadow reads fine on a light page but does nothing to
     separate the (also near-black) button from a dark/saturated one —
     the added 1px white ring stays thin/subtle against a light page
     while giving the button a crisp edge to stand out from a dark one */
  box-shadow:0 10px 30px -10px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.85);
}
/* hover:hover only — plain (hover:none) touch devices "stick" a :hover
   state after a tap with no mouse around to ever un-hover it, which is
   exactly what made the just-tapped button stay visibly darker */
@media (hover:hover){
  #float-nav .arrow-btn:hover{background:rgba(44,44,40,.92)}
}
#float-nav #nav-prev{left:50%;transform:translateX(calc(-100% - 3px))}
#float-nav #nav-next{left:50%;transform:translateX(3px)}
#float-nav .ttl{
  position:fixed;bottom:18px;height:46px;line-height:46px;pointer-events:none;z-index:30;
  max-width:34vw;font-family:var(--display);font-size:12px;font-weight:700;letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  /* tracks the current project's own text color (auto or custom), kept
     in sync via #float-nav's own inline color, set in onSlideChange() */
  color:inherit;
}
#prev-ttl{left:50%;transform:translateX(calc(-100% - 3px - 46px - 8px));text-align:right}
#next-ttl{left:50%;transform:translateX(calc(3px + 46px + 8px))}
#float-nav button[hidden],#float-nav span[hidden]{display:none}

/* ---------- menu drawer ---------- */
#menu-drawer{position:fixed;inset:0;z-index:40}
.drawer-scrim{position:absolute;inset:0;background:rgba(10,10,8,0);transition:background .32s ease}
.drawer-panel{
  position:absolute;top:0;left:0;bottom:0;width:100%;background:var(--paper);
  transform:translateX(-100%);transition:transform .32s cubic-bezier(.4,0,.2,1);
  overflow-y:auto;
  /* scrollable, but with no visible scrollbar at all (still fully
     scrollable by trackpad/wheel/touch/keyboard) — avoids both an
     awkward mid-screen bar and the small layout jump a bar appearing
     only once content grows taller (e.g. expanding a band) would cause */
  scrollbar-width:none;-ms-overflow-style:none;
}
.drawer-panel::-webkit-scrollbar{display:none}
#menu-drawer.open .drawer-scrim{background:rgba(10,10,8,.4)}
#menu-drawer.open .drawer-panel{transform:translateX(0)}
.drawer-head{
  display:flex;flex-direction:column;gap:4px;padding:16px 20px;
  border-bottom:1px solid var(--header-line);position:sticky;top:0;background:var(--header-bg);z-index:1;
}
.drawer-head-top{display:flex;align-items:center;justify-content:space-between;gap:10px}
.drawer-head .brand-wrap{display:flex;align-items:center;gap:8px;min-width:0}
.drawer-head .brand-logo{--eb-size:calc(19px * var(--header-logo-scale));--eb-color:var(--header-color);--patate-size:calc(19px * var(--header-logo-scale));flex:none}
.drawer-head .brand{font-weight:800;letter-spacing:-.02em;font-size:12px;text-transform:uppercase;color:var(--header-color)}
#drawer-home{font-family:var(--mono);font-size:12px;color:var(--header-color);opacity:.55;white-space:nowrap}
#drawer-home:hover{opacity:1}
/* mirrors #sommaire h1 / .intro so the drawer shows the exact same heading
   and auto-computed project count as the standalone sommaire page */
.drawer-panel h1{
  font-size:clamp(2.125rem,10vw,4rem);font-weight:800;letter-spacing:-.03em;
  margin:32px 20px 10px;text-transform:uppercase;color:var(--header-color);
}
.drawer-panel .intro{margin:0 20px 28px;font-family:var(--mono);font-size:12px;color:var(--header-color);opacity:.72;max-width:520px}
/* the drawer panel is always narrow, even on desktop — never show the project count there */
#menu-drawer .cat-band .count{display:none}

/* ---------- lightbox ---------- */
#lightbox{position:fixed;inset:0;background:#0d0d0bcc;backdrop-filter:blur(6px);z-index:50;display:flex;align-items:center;justify-content:center;padding:4vh 4vw}
#lightbox-body{width:100%;height:100%;display:flex;align-items:center;justify-content:center}
#lightbox-body img{max-width:100%;max-height:100%;object-fit:contain;border-radius:2px}
#lightbox .close{position:absolute;top:22px;right:26px;color:#fff;font-family:var(--mono);font-size:13px;border:1px solid #ffffff55;padding:10px 16px;border-radius:999px;z-index:2}
#lightbox .close:hover{background:#fff;color:#0d0d0b}

/* prev/next only make sense browsing a gallery (several images) — hidden
   by default, shown once the lightbox is in gallery mode */
#lightbox .lightbox-nav{
  position:absolute;top:50%;transform:translateY(-50%);z-index:2;display:none;
  align-items:center;justify-content:center;width:46px;height:46px;
  border-radius:999px;border:1px solid #ffffff55;background:#00000033;
  color:#fff;font-size:24px;line-height:1;
}
#lightbox.lightbox-gallery .lightbox-nav{display:flex}
#lightbox .lightbox-nav:hover{background:#fff;color:#0d0d0b}
#lightbox .lightbox-nav.prev{left:14px}
#lightbox .lightbox-nav.next{right:14px}

/* optional title/date under a gallery image — only rendered when at
   least one of the two is set on that image */
.lightbox-image-wrap{display:flex;flex-direction:column;align-items:center;gap:12px;max-width:100%;max-height:100%;min-height:0}
.lightbox-image-wrap img{flex:1;min-height:0;max-width:100%;max-height:100%;object-fit:contain;border-radius:2px}
.lightbox-caption{flex:none;text-align:center;color:#fff}
.lightbox-caption-title{display:block;font-family:var(--display);font-size:13px;font-weight:600}
.lightbox-caption-sub{display:block;font-family:var(--mono);font-size:12px;opacity:.7;margin-top:4px}

/* =====================================================
   DESKTOP ADAPTATION — the phone layout above is the
   source of truth; this block re-arranges it for wide
   screens rather than redefining it from scratch.
   ===================================================== */
@media(min-width:720px){
  .swatch{width:68px}

  #cover{padding:28px 34px 40px}
  #cover .contact{font-size:13px;margin-left:48px}
  #cover .contact .name{font-size:20px}
  #cover .enter{font-size:12px;padding:12px 18px}
  #cover .cover-logo{--eb-size:162px;--patate-size:162px}

  /* split sommaire: header stays full-width on top (untouched, always
     paper/white); below it, the list (left) and a random-thumbnail
     crossfade slideshow (right) share the remaining viewport height */
  #sommaire{display:flex;flex-direction:column;height:100vh;height:100dvh;overflow:hidden;padding-bottom:0}
  #sommaire header{padding:22px 30px}
  #sommaire header .brand{font-size:15px}
  #sommaire header .brand-logo{--eb-size:calc(26px * var(--header-logo-scale));--patate-size:calc(26px * var(--header-logo-scale))}
  .sommaire-body{flex:1;min-height:0;display:flex}
  /* no visible scrollbar — still scrollable, just without a bar sitting
     at the boundary between the two halves, and without the small jump
     a bar appearing only once a band is expanded would otherwise cause */
  .sommaire-left{width:50%;height:100%;overflow-y:auto;scrollbar-width:none;-ms-overflow-style:none}
  .sommaire-left::-webkit-scrollbar{display:none}
  /* the thumbnail is a small (max 700px) source image — stretching it
     full-bleed across half a wide/4K screen made it look soft/pixelated,
     so instead it sits contained, at a capped size, inside its own
     square frame with the project color showing all around it. This
     block itself stays the full row height — align-items:flex-start so
     it's not also auto-centered — app.js positions .preview-frame
     inside it via the frame's own margin-top, centered on #cat-list
     (see app.js for why). */
  .sommaire-preview{display:flex;align-items:flex-start;justify-content:center;width:50%;height:100%;padding:clamp(14px,5dvh,40px);overflow:visible}
  /* fills the column's full (padded) width by default — the margin
     around it is just .sommaire-preview's own padding above, not a
     second, much bigger proportional gap on top of it — capped at
     480px AND at the row's real available height (--avail-h, set by
     app.js — NOT this box's own height, which is deliberately
     narrowed to match #cat-list and would otherwise cap the frame
     under ~500px on every screen). The height ceiling only binds once
     the window itself is genuinely short, e.g. a landscape phone. */
  .preview-frame{position:relative;width:min(100%,480px,var(--avail-h,480px));aspect-ratio:1/1;box-shadow:0 10px 28px 2px rgba(0,0,0,.35)}
  .preview-img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;opacity:0;transition:opacity 1.1s ease}
  .preview-img.visible{opacity:1}
  #sommaire h1{margin:40px 30px 10px}
  #sommaire .intro{margin:0 30px 36px;font-size:13px}
  .band-link{gap:20px;padding:0 30px}
  .cat-band h2{padding:8px 0;font-size:clamp(1.25rem,2.9vw,1.875rem)}
  .cat-band .count{display:block}
  .chev-btn{width:80px}
  .cat-grid{grid-template-columns:repeat(auto-fill,minmax(180px,1fr))}
  /* the drawer is a fixed ~420px-wide panel, not half the screen, so it
     gets its own, smaller minimum — tuned for 3 per row instead of 2 */
  #menu-drawer .cat-grid{grid-template-columns:repeat(auto-fill,minmax(110px,1fr))}

  .drawer-panel{max-width:420px;border-right:1px solid #0000001a}

  #categorie .bar{padding:20px 26px;font-size:12px}
  #categorie h1{margin:24px 30px 24px}

  #contact .bar{padding:20px 26px}
  #contact h1{margin:24px 30px 24px}
  .contact-lines.big{padding:0 30px}

  #videos .bar{padding:20px 26px;font-size:12px}
  #videos h1{margin:24px 30px 24px}
  .video-gallery-grid{padding:0 30px}

  #images .bar{padding:20px 26px;font-size:12px}
  #images h1{margin:24px 30px 24px}
  .image-gallery-grid{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:28px 18px;padding:0 30px}

  #projet .bar{padding:20px 26px;font-size:12px}
  /* Desktop: #projet is pinned to exactly one viewport height so nothing
     ever needs to scroll. The slide fills that height, .main is
     flattened out of the box model (display:contents) so the image and
     caption become direct flex children of the slide itself, and the
     image takes flex:1 to absorb all the leftover height — with
     width:auto, a replaced element's width is then derived from that
     height via its own intrinsic aspect ratio, so the box never grows
     wider than the visible picture (no ghost drop-shadow).
     The nav arrows still need app.js (positionNavDesktop): a fixed CSS
     offset only lines up with the image when it happens to render at
     the full 660px max-width, but a tall/narrow image renders much
     thinner than that and leaves the buttons stranded. app.js measures
     the active slide's own image edges instead — see the comment above
     positionNavDesktop() for why that stays decoupled from Swiper's own
     transition and can't reintroduce the old mid-transform drift bug. */
  #projet{height:100vh;height:100dvh;overflow:hidden}
  #projet .swiper-slide{
    flex-direction:column;align-items:center;justify-content:center;
    padding:24px 26px 32px;
  }
  #projet .main{display:contents}
  /* max-height:none overrides the base (mobile) rule's max-height:58vh —
     left unset here before, that ghost rule silently capped the image
     at 58% of the viewport's height no matter how much room flex:1 had
     to give it, which is what was making it look small on desktop.
     max-width is tied to the viewport, not a flat px ceiling, so a
     portrait page fills the available height uninterrupted (the normal
     case) while a rare landscape one still can't run past the screen. */
  #projet .page-img{flex:1;min-height:0;width:auto;max-width:calc(100vw - 80px);max-height:none}
  #projet .caption{margin-top:16px;flex:none}
  #projet .caption h1{font-size:1.75rem}

  /* base/fallback position: edge-pinned arrows, vertically centered on
     the viewport, labels flanking them — used before app.js measures a
     real image's edges (avoids a flash at 0,0), immediately overwritten
     once it does. The .ttl labels used to have no desktop left/right
     rule at all here, only the base (mobile, screen-centered) one —
     invisible as long as JS always overwrote it immediately, until a
     page with nothing for JS to measure (briefly, video-list's own
     slide, since reworked) exposed it as two labels stacked on top of
     each other at screen-center. */
  #float-nav #nav-prev{top:50%;bottom:auto;left:28px;right:auto;transform:translateY(-50%)}
  #float-nav #nav-next{top:50%;bottom:auto;left:auto;right:28px;transform:translateY(-50%)}
  #float-nav .ttl{top:50%;bottom:auto;transform:translateY(-50%);max-width:220px}
  #prev-ttl{left:92px;right:auto;transform:translateY(-50%);text-align:left}
  #next-ttl{right:92px;left:auto;transform:translateY(-50%);text-align:right}
}
