/* =====================================================================
   CATEGORY GALLERY PAGE — master template for every category
   Editorial gallery: the work is the hero, animation only supports it.
   Self-contained. Does NOT touch homepage / menu / carousel / main.js.
   Loaded only by site/universe/index.html.
   ===================================================================== */

:root{
  /* tokens mirrored 1:1 from the homepage (css/styles.css) so the category
     pages read as a continuation of it, not a separate skin */
  --black:#070707; --ink:#0d0d0d; --white:#F6F4F0;
  --dim:rgba(246,244,240,.6); --faint:rgba(246,244,240,.32);
  --ghost:rgba(246,244,240,.06);
  --line:rgba(246,244,240,.13);
  --orange:#FF5A1F; --orange-soft:#FF7A45;
  --accent:#FF5A1F;                      /* per-category tint, set by JS */
  --ease:cubic-bezier(.22,1,.36,1);
  --pad:clamp(20px,5vw,90px);
  --maxw:1720px;                         /* matches homepage --maxw */
  --gmaxw:1720px;                        /* gallery shares the homepage measure */
  --glass:rgba(7,7,7,.42);               /* homepage frosted-glass fill */
  --font:'Poppins',system-ui,sans-serif;
}
*{margin:0;padding:0;box-sizing:border-box}
html{scrollbar-width:none}
html::-webkit-scrollbar{display:none}
body{
  background:var(--black); color:var(--white); font-family:var(--font);
  font-weight:400; line-height:1.5; -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility; overflow-x:hidden;
}
a{color:inherit; text-decoration:none}
img,video{display:block; max-width:100%}
::selection{background:var(--accent); color:#0a0a0a}

/* ---------- custom cursor (matches site identity) ---------- */
.cursor{position:fixed; top:0; left:0; z-index:9999; pointer-events:none;
  transform:translate(-50%,-50%); mix-blend-mode:difference}
.cursor__dot{display:block; width:8px; height:8px; border-radius:50%;
  background:var(--white); transition:width .35s var(--ease),height .35s var(--ease)}
.cursor.is-hover .cursor__dot{width:44px; height:44px}
.cursor.is-view .cursor__dot{width:60px; height:60px; background:var(--accent)}
@media (hover:none){.cursor{display:none}}

/* =====================================================================
   AMBIENT WORLD — cinematic gradient background (never solid black)
   ===================================================================== */
.atmos{position:fixed; inset:0; z-index:-2; overflow:hidden}
.atmos__img{position:absolute; inset:-6%; width:112%; height:112%;
  object-fit:cover; filter:blur(58px) saturate(1.1) brightness(.6);
  opacity:.5; transform:scale(1.05)}
.atmos__tint{position:fixed; inset:0; z-index:-1; pointer-events:none;
  background:
    radial-gradient(120% 90% at 50% -10%,color-mix(in srgb,var(--accent) 14%,transparent),transparent 60%),
    linear-gradient(180deg,rgba(7,7,7,.55),rgba(7,7,7,.86) 60%,var(--black))}
.grain{position:fixed; inset:0; z-index:1000; opacity:.18; mix-blend-mode:overlay;
  pointer-events:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E")}

/* =====================================================================
   AMBIENT CINEMATIC ENVIRONMENT
   Slow drifting light, atmospheric haze, a breathing bloom and a fine
   particle drift. All CSS-driven (compositor-friendly), all long-period
   and low-contrast so it reads as atmosphere, never as motion graphics.
   Sits above the tint, below the page content. JS adds gentle parallax.
   ===================================================================== */
.amb{position:fixed; inset:0; z-index:-1; pointer-events:none; overflow:hidden;
  will-change:transform}

/* soft coloured light pools that slowly wander */
.amb__blob{position:absolute; display:block; border-radius:50%;
  filter:blur(90px); mix-blend-mode:screen; will-change:transform}
.amb__blob--1{width:44vw; height:44vw; left:-10vw; top:-12vh; opacity:.42;
  background:radial-gradient(circle,color-mix(in srgb,var(--accent) 62%,transparent),transparent 68%);
  animation:ambDrift1 42s ease-in-out infinite alternate}
.amb__blob--2{width:38vw; height:38vw; right:-8vw; top:22vh; opacity:.3;
  background:radial-gradient(circle,color-mix(in srgb,var(--accent) 40%,transparent),transparent 70%);
  animation:ambDrift2 55s ease-in-out infinite alternate}
.amb__blob--3{width:52vw; height:52vw; left:26vw; bottom:-22vh; opacity:.22;
  background:radial-gradient(circle,rgba(255,214,170,.5),transparent 72%);
  animation:ambDrift3 64s ease-in-out infinite alternate}

/* wide atmospheric haze sheet */
.amb__haze{position:absolute; inset:-25%; display:block; opacity:.5;
  background:
    radial-gradient(48% 34% at 22% 30%,rgba(255,255,255,.055),transparent 70%),
    radial-gradient(42% 30% at 76% 66%,rgba(255,255,255,.04),transparent 72%);
  filter:blur(30px); will-change:transform;
  animation:ambHaze 78s ease-in-out infinite alternate}

/* slow cinematic light bloom breathing at the top of the frame */
.amb__bloom{position:absolute; left:50%; top:-18vh; display:block;
  width:80vw; height:60vh; transform:translateX(-50%);
  background:radial-gradient(closest-side,color-mix(in srgb,var(--accent) 26%,transparent),transparent 74%);
  filter:blur(60px); opacity:.3; mix-blend-mode:screen;
  animation:ambBloom 24s ease-in-out infinite}

/* fine drifting particles (built by JS) */
.amb__particles{position:absolute; inset:0}
.amb__p{position:absolute; bottom:-8vh; width:2px; height:2px; border-radius:50%;
  background:rgba(255,236,214,.7); opacity:0; will-change:transform,opacity;
  animation-name:ambRise; animation-timing-function:linear; animation-iteration-count:infinite}

@keyframes ambDrift1{
  0%  {transform:translate3d(0,0,0) scale(1)}
  100%{transform:translate3d(9vw,7vh,0) scale(1.16)}
}
@keyframes ambDrift2{
  0%  {transform:translate3d(0,0,0) scale(1.1)}
  100%{transform:translate3d(-8vw,-6vh,0) scale(1)}
}
@keyframes ambDrift3{
  0%  {transform:translate3d(0,0,0) scale(1)}
  100%{transform:translate3d(-7vw,-5vh,0) scale(1.12)}
}
@keyframes ambHaze{
  0%  {transform:translate3d(0,0,0) scale(1)}
  100%{transform:translate3d(4%,-3%,0) scale(1.08)}
}
@keyframes ambBloom{
  0%,100%{opacity:.22; transform:translateX(-50%) scale(1)}
  50%    {opacity:.38; transform:translateX(-50%) scale(1.08)}
}
@keyframes ambRise{
  0%  {opacity:0; transform:translate3d(0,0,0)}
  12% {opacity:.55}
  88% {opacity:.4}
  100%{opacity:0; transform:translate3d(var(--dx,14px),-118vh,0)}
}

/* =====================================================================
   TOP NAV
   ===================================================================== */
.dnav{position:fixed; top:0; left:0; width:100%; z-index:120;
  display:flex; align-items:center; justify-content:space-between;
  padding:clamp(18px,2.4vw,30px) var(--pad);
  transition:background .5s var(--ease),backdrop-filter .5s}
.dnav.is-stuck{background:rgba(7,7,7,.55); backdrop-filter:blur(16px)}  /* == homepage .nav.is-scrolled */
.back{display:inline-flex; align-items:center; gap:.7em; font-size:.82rem;
  letter-spacing:.14em; text-transform:uppercase; font-weight:600; color:var(--white)}
.back__txt{font-weight:inherit}
.back span{display:inline-flex; width:36px; height:36px; border:1px solid var(--line);
  border-radius:50%; align-items:center; justify-content:center; font-size:1rem;
  transition:border-color .4s,color .4s,transform .4s var(--ease)}
.back:hover span{border-color:var(--accent); color:var(--accent); transform:translateX(-3px)}
/* signature wordmark — same asset & treatment as the site header */
.dnav__mark{display:flex; align-items:center}
.dnav__logo{height:clamp(46px,3.4vw,62px); width:auto; display:block;
  transition:opacity .4s var(--ease)}
.dnav__mark:hover .dnav__logo{opacity:.72}

/* =====================================================================
   PAGE
   ===================================================================== */
/* The page paints VISIBLE from frame one — the hero image (handed over from the
   homepage card) must already be on screen so the navigation seam is invisible.
   Only the copy fades in (via .is-live), and only the exit fades out. */
.page{position:relative; z-index:2; opacity:1;
  transition:opacity .5s var(--ease),transform .6s var(--ease),filter .6s var(--ease)}
.page.is-leaving{opacity:0; transform:scale(.96); filter:blur(6px)}

/* =====================================================================
   CINEMATIC FULLSCREEN HERO
   The SAME landscape image the homepage card showed continues here full-screen
   (shared-element handoff). data-fit="cover" = a true landscape image fills the
   frame; data-fit="blur" = a portrait placeholder is shown WHOLE (contained,
   never cropped) over a soft blurred backdrop — swap the src for a wide file and
   flip to cover when it's ready. The title fades in over it; gallery lives below.
   ===================================================================== */
.uhero{position:relative; width:100%; height:100vh; height:100svh; min-height:560px;
  display:flex; align-items:flex-end; overflow:hidden}
.uhero__media{position:absolute; inset:0; z-index:0; background:var(--ink)}
.uhero__bg{position:absolute; inset:0; background-size:cover; background-position:center;
  filter:blur(40px) saturate(1.15) brightness(.5); transform:scale(1.2); opacity:0}
.uhero__media[data-fit="blur"] .uhero__bg{opacity:1}
/* a gentle continuation of the portal's camera push: settles 1.1 → 1.0 on load */
.uhero__img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  object-position:center; transform:scale(1.1); animation:heroSettle 2.6s var(--ease) forwards}
.uhero__media[data-fit="blur"] .uhero__img{object-fit:contain}
@keyframes heroSettle{to{transform:scale(1)}}
.uhero__scrim{position:absolute; inset:0; pointer-events:none;
  background:
    linear-gradient(180deg,rgba(7,7,7,.34) 0%,rgba(7,7,7,0) 24%,rgba(7,7,7,.10) 52%,rgba(7,7,7,.72) 86%,var(--black) 100%),
    radial-gradient(130% 80% at 50% 118%,color-mix(in srgb,var(--accent) 13%,transparent),transparent 60%)}

.uhero__copy{position:relative; z-index:2; width:100%; max-width:var(--gmaxw); margin:0 auto;
  padding:0 var(--pad) clamp(9vh,13vh,16vh)}
.uhero__no,.uhero__title,.uhero__blurb{opacity:0; transform:translateY(18px);
  transition:opacity .9s var(--ease),transform .9s var(--ease)}
.page.is-live .uhero__no{opacity:1; transform:none; transition-delay:.15s}
.page.is-live .uhero__title{opacity:1; transform:none; transition-delay:.28s}
.page.is-live .uhero__blurb{opacity:1; transform:none; transition-delay:.42s}
.uhero__no{display:block; font-size:.72rem; font-weight:700; letter-spacing:.32em;
  color:var(--accent); margin-bottom:1.1em}
.uhero__title{font-size:clamp(2.8rem,8vw,7rem); font-weight:800; letter-spacing:-.03em;
  line-height:.98; max-width:16ch}
.uhero__blurb{margin-top:.9em; max-width:54ch; font-size:clamp(1rem,1.35vw,1.24rem);
  color:var(--dim); line-height:1.6}

/* scroll indicator — invites the gallery below, never auto-jumps */
.uhero__scroll{position:absolute; left:50%; bottom:clamp(18px,3.2vh,38px); z-index:3;
  transform:translateX(-50%); display:inline-flex; flex-direction:column; align-items:center; gap:.75em;
  background:none; border:0; cursor:pointer; color:var(--dim); font-family:inherit;
  font-size:.58rem; font-weight:700; letter-spacing:.26em; text-transform:uppercase;
  opacity:0; transition:opacity 1s var(--ease) .8s,color .3s}
.page.is-live .uhero__scroll{opacity:1}
.uhero__scroll:hover{color:var(--white)}
.uhero__scroll i{position:relative; width:1px; height:40px; overflow:hidden;
  background:linear-gradient(color-mix(in srgb,var(--accent) 60%,transparent),transparent)}
.uhero__scroll i::after{content:""; position:absolute; left:0; top:0; width:100%; height:42%;
  background:var(--white); animation:scrollPulse 1.9s var(--ease) infinite}
@keyframes scrollPulse{0%{transform:translateY(-110%)}62%,100%{transform:translateY(280%)}}

/* =====================================================================
   EDITORIAL GALLERY — magazine row rhythm: 4/row, alternating □□▭□ / ▭□□□
   10-unit grid; narrow slots keep the photo's own aspect ratio (never
   cropped), the one wide slot per row is the deliberate editorial beat.
   ===================================================================== */
.gallery{max-width:var(--gmaxw); margin:0 auto; padding:clamp(7vh,10vh,13vh) var(--pad) clamp(8vh,10vh,12vh);
  columns:4; column-gap:clamp(18px,2vw,30px)}
.g-item{position:relative; break-inside:avoid;
  margin:0 0 clamp(28px,3.4vw,54px);
  opacity:0; transform:translateY(18px);
  transition:opacity .5s var(--ease),transform .5s var(--ease)}
.g-item.is-in{opacity:1; transform:translateY(0)}
/* breathing wrapper — kept separate from .g-item (which owns the reveal
   transform) and from .g-item__frame (which owns the hover lift) so the
   three motions never fight over `transform` */
.g-item__lift{display:block; width:100%; will-change:transform;
  animation:cardFloat var(--float-dur,9s) ease-in-out infinite alternate;
  animation-delay:var(--float-delay,0s)}
/* ARTWORK IS NEVER CROPPED.
   The frame reserves each image's OWN ratio (set inline from the real pixel
   dimensions) purely to prevent layout shift while loading; the image then
   fills it at natural height. There is no object-fit:cover anywhere, so
   9:16 stays 9:16, 4:5 stays 4:5, 1:1 stays 1:1, 16:9 stays 16:9.
   This is the same approach the homepage's .media blocks use. */
.g-item__frame{position:relative; width:100%; overflow:hidden; border-radius:2px;
  background:var(--ink); cursor:pointer;
  transition:box-shadow .45s var(--ease),transform .45s var(--ease)}
@keyframes cardFloat{
  0%  {transform:translate3d(0,0,0)}
  100%{transform:translate3d(0,-6px,0)}
}
.g-item__frame img,.g-item__frame video{width:100%; height:auto; display:block;
  transition:transform .5s var(--ease)}
.g-item__frame::after{content:""; position:absolute; inset:0; pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(246,244,240,.07)}
.g-item__frame:hover{transform:translate3d(0,-7px,0);
  box-shadow:0 28px 64px rgba(0,0,0,.5),0 0 0 1px color-mix(in srgb,var(--accent) 22%,transparent)}
/* same lift as the homepage's .media:hover */
.g-item__frame:hover img,.g-item__frame:hover video{transform:scale(1.045)}
.g-item__cap{margin-top:.9em; font-size:.7rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--faint); display:flex; gap:.75em; align-items:baseline}
.g-item__cap b{color:var(--accent); font-weight:700}
.g-item .play{position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  width:56px; height:56px; border-radius:50%; border:1px solid rgba(246,244,240,.4);
  display:flex; align-items:center; justify-content:center; backdrop-filter:blur(4px);
  background:rgba(255,90,31,.16); pointer-events:none;      /* == homepage .film__play */
  transition:border-color .4s,background .4s,transform .5s var(--ease)}
.g-item .play::before{content:""; border-left:12px solid var(--white);
  border-top:7px solid transparent; border-bottom:7px solid transparent; margin-left:3px}
.g-item__frame:hover .play{border-color:var(--accent); background:var(--accent); transform:translate(-50%,-50%) scale(1.06)}
.g-item__frame:hover .play::before{border-left-color:#0a0a0a}

/* --- minimal hover/tap overlay (Change 2): Favourite + View, no metadata --- */
.g-ov{position:absolute; inset:0; z-index:3; display:flex; align-items:flex-end; justify-content:flex-end;
  gap:10px; padding:14px; opacity:0; pointer-events:none;
  transition:opacity .4s var(--ease);
  background:linear-gradient(180deg,transparent 52%,rgba(7,7,7,.5))}
.g-item__frame:hover .g-ov{opacity:1; pointer-events:auto}
.g-ov__btn{width:42px; height:42px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center;
  color:#fff; background:rgba(10,10,10,.42); border:1px solid rgba(246,244,240,.28); backdrop-filter:blur(8px);
  cursor:pointer; transform:translateY(9px);
  transition:transform .45s var(--ease),background .3s,border-color .3s,color .3s}
.g-item__frame:hover .g-ov__btn{transform:translateY(0)}
.g-ov__btn:nth-child(2){transition-delay:.04s}
.g-ov__btn:hover{background:var(--accent); border-color:var(--accent); color:#0a0a0a}
.g-ov__btn svg{display:block}
.g-fav.is-fav{color:var(--accent); border-color:color-mix(in srgb,var(--accent) 55%,transparent)}
.g-fav.is-fav svg path{fill:var(--accent); stroke:var(--accent)}
.g-fav.is-fav:hover{color:#0a0a0a}
.g-fav.is-fav:hover svg path{fill:#0a0a0a; stroke:#0a0a0a}
/* touch devices: overlay is always visible + tappable */
@media (hover:none){
  .g-ov{opacity:1; pointer-events:auto; background:linear-gradient(180deg,transparent 60%,rgba(7,7,7,.42))}
  .g-ov__btn{transform:none; width:40px; height:40px}
}

/* --- Branded Content badge (verification pill) -----------------------------
   Premium top-right marker on any asset flagged branded. Purely an additive
   overlay layer — it does not alter grid layout, image sizing or spacing. --- */
.bbc-badge{position:absolute; top:11px; right:11px; z-index:4;
  display:inline-flex; align-items:center; gap:5px;
  padding:5px 9px 5px 5px; border-radius:999px;
  font-family:var(--font); font-size:10.5px; font-weight:600; letter-spacing:.02em;
  line-height:1; color:#fff; white-space:nowrap; pointer-events:none;
  background:rgba(12,12,14,.5); border:1px solid rgba(255,255,255,.15);
  -webkit-backdrop-filter:blur(9px) saturate(1.25); backdrop-filter:blur(9px) saturate(1.25);
  box-shadow:0 2px 10px rgba(0,0,0,.28)}
.bbc-badge svg{flex:0 0 auto; color:#fff; background:#FF5A1F; border-radius:50%;
  width:16px; height:16px; padding:2.5px; box-sizing:border-box;
  box-shadow:0 1px 3px rgba(255,90,31,.5)}

/* --- count + Apparel sub-category pills, above the grid --- */
.gwrap{max-width:var(--gmaxw); margin:clamp(3vh,5vh,7vh) auto 0; padding:0 var(--pad);
  display:flex; align-items:center; justify-content:space-between; gap:16px}
.gwrap__count{flex:0 0 auto; font-size:.72rem; font-weight:600; letter-spacing:.18em;
  text-transform:uppercase; color:var(--faint)}
.subtabs{display:flex; gap:10px; flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch;
  scrollbar-width:none; min-width:0}
.subtabs::-webkit-scrollbar{display:none}
.pill{flex:0 0 auto; padding:.62em 1.35em; border-radius:100px; font-size:.78rem; font-weight:600;
  color:var(--dim); border:1px solid var(--line); background:rgba(246,244,240,.03); cursor:pointer;
  white-space:nowrap; transition:color .3s,border-color .3s,background .3s}
.pill:hover{color:var(--white); border-color:color-mix(in srgb,var(--accent) 40%,transparent)}
.pill.is-active{color:#0a0a0a; background:var(--accent); border-color:var(--accent)}
@media(max-width:560px){
  .gwrap{flex-direction:column; align-items:flex-start; gap:12px}
}

/* --- closing CTA --- */
.outro{max-width:var(--maxw); margin:clamp(8vh,10vh,12vh) auto clamp(8vh,10vh,12vh);
  padding:0 var(--pad); text-align:center;
  opacity:0; transform:translateY(18px);
  transition:opacity .5s var(--ease),transform .5s var(--ease)}
.outro.is-in{opacity:1; transform:translateY(0)}
.outro__k{font-size:.66rem; font-weight:700; letter-spacing:.3em; text-transform:uppercase;
  color:var(--accent); margin-bottom:1.4em; display:block}
.outro__h{font-size:clamp(2rem,5.5vw,4.6rem); font-weight:800; letter-spacing:-.03em;
  line-height:1.02; max-width:18ch; margin:0 auto}
.outro__actions{margin-top:2.6em; display:flex; justify-content:center}
/* Same pill geometry + motion as the homepage's primary CTA (.btn-dark):
   100px radius, 1.15em/1.9em padding, .95rem, lift + gap-opening on hover,
   arrow nudging right. Filled orange here because it sits on black. */
.btn{display:inline-flex; align-items:center; gap:.7em; font-weight:600; font-size:.95rem;
  padding:1.15em 1.9em; border-radius:100px;
  transition:transform .5s var(--ease),gap .4s var(--ease),background .4s,color .4s}
.btn--primary{background:var(--accent); color:#0a0a0a}
.btn--primary:hover{transform:translateY(-3px); gap:1.1em; background:var(--orange-soft)}
.btn svg{transition:transform .4s var(--ease)}
.btn:hover svg{transform:translateX(3px)}

/* --- footer wordmark --- */
.dfoot{position:relative; z-index:2; padding:clamp(6vh,9vh,11vh) var(--pad) 5vh;
  text-align:center; overflow:hidden}
.dfoot__word{font-size:clamp(3rem,18vw,15rem); font-weight:800; letter-spacing:-.04em;
  line-height:.8; color:rgba(246,244,240,.05); text-transform:uppercase;
  user-select:none; pointer-events:none; white-space:nowrap}
.dfoot__meta{margin-top:2vh; font-size:.7rem; letter-spacing:.18em; text-transform:uppercase;
  color:var(--faint)}

/* =====================================================================
   PREMIUM IMAGE VIEWER (lightbox) — FLIP zoom-open, pan/zoom, filmstrip
   ===================================================================== */
.viewer{position:fixed; inset:0; z-index:300; display:none; pointer-events:none}
.viewer.is-open{display:block; pointer-events:auto}
.viewer__bg{position:absolute; inset:0; background:rgba(5,5,5,0); backdrop-filter:blur(0px);
  transition:background .5s var(--ease),backdrop-filter .5s var(--ease)}
.viewer.is-open .viewer__bg{background:rgba(5,5,5,.96); backdrop-filter:blur(14px)}

/* stage = FLIP layer (left/top/width/height animate open→close) — stays
   opaque throughout so the SAME image continuously morphs, no cross-fade */
.viewer__stage{position:fixed; overflow:hidden; border-radius:3px}
.viewer__zoom{position:absolute; inset:0; transform-origin:50% 50%; cursor:grab}
.viewer__zoom.is-zoomed{cursor:grab}
.viewer__zoom.is-dragging{cursor:grabbing}
.viewer__zoom img,.viewer__zoom video{width:100%; height:100%; object-fit:contain;
  border-radius:2px; pointer-events:none; user-select:none}

.viewer__counter{position:fixed; top:clamp(18px,2.4vw,30px); right:var(--pad); z-index:2;
  font-size:.72rem; font-weight:600; letter-spacing:.14em; color:var(--dim);
  opacity:0; transition:opacity .4s ease .15s; font-variant-numeric:tabular-nums}
.viewer.is-open .viewer__counter{opacity:1}

.viewer__arrow{position:fixed; top:50%; transform:translateY(-50%); z-index:2;
  width:52px; height:52px; border-radius:50%; border:1px solid var(--line);
  display:flex; align-items:center; justify-content:center; color:var(--white);
  background:rgba(7,7,7,.4); opacity:0; transition:opacity .4s ease .1s,border-color .3s,color .3s,transform .3s var(--ease)}
.viewer.is-open .viewer__arrow{opacity:1}
.viewer__arrow:hover{border-color:var(--accent); color:var(--accent)}
.viewer__arrow--prev{left:clamp(16px,3vw,48px)}
.viewer__arrow--prev:hover{transform:translateY(-50%) translateX(-3px)}
.viewer__arrow--next{right:clamp(16px,3vw,48px)}
.viewer__arrow--next:hover{transform:translateY(-50%) translateX(3px)}
.viewer__cap{position:fixed; left:var(--pad); bottom:clamp(20px,4vh,40px); z-index:2;
  font-size:.74rem; letter-spacing:.14em; text-transform:uppercase; color:var(--dim);
  opacity:0; transition:opacity .4s ease .15s; max-width:40vw}
.viewer.is-open .viewer__cap{opacity:1}
.viewer__cap b{color:var(--accent); font-weight:700}

/* --- bottom cluster: filmstrip + frosted control bar --- */
.viewer__bottom{position:fixed; left:0; bottom:clamp(14px,2.6vh,28px); width:100%; z-index:2;
  display:flex; flex-direction:column; align-items:center; gap:.9em;
  opacity:0; transform:translateY(14px);
  transition:opacity .4s ease .1s,transform .4s var(--ease) .1s}
.viewer.is-open .viewer__bottom{opacity:1; transform:translateY(0)}

.viewer__filmstrip{display:flex; gap:.5em; max-width:min(92vw,900px); overflow-x:auto;
  padding:.3em; scrollbar-width:none}
.viewer__filmstrip::-webkit-scrollbar{display:none}
.vfilm{flex:0 0 auto; width:52px; height:52px; border-radius:3px; overflow:hidden;
  cursor:pointer; opacity:.45; border:1.5px solid transparent;
  transition:opacity .3s ease,border-color .3s ease,transform .25s var(--ease)}
.vfilm img{width:100%; height:100%; object-fit:cover; display:block}
.vfilm:hover{opacity:.75}
.vfilm.is-current{opacity:1; border-color:var(--accent); transform:translateY(-3px)}

.viewer__bar{display:flex; align-items:center; gap:.35em;
  padding:.55em .6em; border-radius:99px;
  background:var(--glass); backdrop-filter:blur(16px) saturate(1.2);
  -webkit-backdrop-filter:blur(16px) saturate(1.2);
  border:1px solid rgba(246,244,240,.1);
  box-shadow:0 20px 50px rgba(0,0,0,.45)}
.vbar__btn{display:flex; align-items:center; justify-content:center;
  width:38px; height:38px; border-radius:50%; border:none; background:transparent;
  color:var(--dim); font-size:1.15rem; line-height:1; cursor:pointer;
  transition:background .3s ease,color .3s ease}
.vbar__btn:hover{background:rgba(246,244,240,.1); color:var(--white)}
.vbar__btn.is-active{color:var(--accent)}
.vbar__btn--text{width:auto; padding:0 .9em; font-size:.68rem; font-weight:700;
  letter-spacing:.08em; text-transform:uppercase}
.vbar__sep{width:1px; height:20px; background:var(--line); margin:0 .15em}

/* --- closing (reverse FLIP): stage animates back to the source thumbnail
   while everything else fades out — is-open stays so display:block holds
   through the animation; is-closing overrides to the "closed" look --- */
.viewer.is-closing .viewer__bg{background:rgba(5,5,5,0); backdrop-filter:blur(0px)}
.viewer.is-closing .viewer__arrow,
.viewer.is-closing .viewer__counter,
.viewer.is-closing .viewer__cap,
.viewer.is-closing .viewer__bottom{opacity:0}

/* =====================================================================
   FULLSCREEN adjustments
   ===================================================================== */
.viewer:fullscreen{background:var(--black)}
.viewer:fullscreen .viewer__bg{background:var(--black)}

/* =====================================================================
   RESPONSIVE
   ===================================================================== */
@media (max-width:1180px){
  .gallery{columns:3}
}
@media (max-width:860px){
  .gallery{columns:2; column-gap:18px}
  .uhero__blurb{max-width:none}
  .viewer__arrow{width:44px; height:44px}
}
@media (max-width:600px){
  /* the full label wraps to two lines and crowds the signature on a phone —
     shorten it to "Back"; the circled arrow already carries the meaning */
  .back__txt{font-size:0}
  .back__txt::after{content:"Back"; font-size:.82rem}
  .gallery{columns:1}
  .outro__actions .btn{justify-content:center}
  .viewer__arrow--prev{left:8px}
  .viewer__arrow--next{right:8px}
  .viewer__bar{gap:.2em; padding:.5em .7em}
  .vbar__btn{width:36px; height:36px}
}
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001s !important; transition-duration:.12s !important}
  .g-item,.outro,.uhero__no,.uhero__title,.uhero__blurb,.uhero__scroll{opacity:1 !important; transform:none !important}
  .uhero__img{animation:none !important; transform:none !important}
  /* hold the atmosphere completely still, but keep its lighting */
  .amb__blob,.amb__haze,.amb__bloom,.g-item__lift{animation:none !important; transform:none !important}
  .amb__particles{display:none}
}
