/* ============================================================
   SKAND — THE GALLERY HALL
   Replaces the Three.js hero + work ribbon carousel.
   Pure CSS 3D: a long hall the camera walks down as you scroll.
   ============================================================ */

:root {
  /* the site self-hosts only Cormorant + Outfit, so borrow the platform
     mono rather than adding a webfont */
  --gallery-mono: ui-monospace, 'SF Mono', SFMono-Regular, 'JetBrains Mono', Menlo, Consolas, monospace;
}

.gallery {
  --hall-w: 6200px;   /* set by gallery.js from the work count */
  --col-w: 320px;
  --art-w: 264px;
  --wall-h: 504px;    /* set by gallery.js from the pin height */
  --end-w: 460px;     /* width of the terminal panel; the back wall stops here */
  --row-gap: 148px;
  --pad-x: 760px;     /* lead-in before the first bay, trail after the last */

  position: relative;
  /* Fallback before gallery.js sizes the walk and its brief end hold. */
  height: 280vh;
  height: 280dvh;
  /* About follows the full hall: after the camera reaches the end wall,
     normal page scroll moves the entire pinned scene up to reveal it. */
  padding: 0;
  background: var(--black);
}

.gallery-pin {
  position: sticky;
  top: 0;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  min-height: 560px;
  overflow: hidden;
  /* No overflow:hidden on .gallery itself — it would make .gallery the scroll
     container and the sticky pin would attach to a box that never scrolls. */
}

/* ---------- atmospheric light ---------- */
.gallery-pin::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 60% 45% at 46% 42%, rgba(232, 86, 58, .10), transparent 62%),
    radial-gradient(ellipse 50% 40% at 12% 78%, rgba(64, 82, 181, .10), transparent 66%),
    linear-gradient(180deg, #0a0a0a 0%, #101010 42%, #0a0a0a 100%);
}
/* Vignette keeps the eye in the middle of the hall */
/* --end (0..1, from gallery.js) lifts the right-hand shade as the walk nears the
   end wall. The wall sits at the far right of the screen, i.e. exactly where
   this vignette is darkest, so without it "Our Story Starts" was always dim. */
.gallery-pin::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  background:
    linear-gradient(90deg, #0a0a0a 0%, rgba(10, 10, 10, .55) 16%, transparent 38%, transparent 66%, rgba(10, 10, 10, calc(.72 - var(--end, 0) * .68)) 100%),
    linear-gradient(0deg, #0a0a0a 0%, transparent 22%, transparent 74%, rgba(10, 10, 10, .5) 100%);
}

/* ============================================================
   THE ROOM
   ============================================================ */
.gallery-scene {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* The camera math in gallery.js reads these three back off the computed
     style, so the end of the walk lands exactly on the end wall. Keep them
     here rather than as literals in both places. */
  --hall-persp: 1200;
  --hall-origin-x: 42%;
  --hall-tilt: 4deg;
  perspective: calc(var(--hall-persp) * 1px);
  perspective-origin: var(--hall-origin-x) 46%;
  overflow: hidden;
  touch-action: pan-y;
  cursor: grab;
}
.gallery-scene.is-dragging { cursor: grabbing; }

.gallery-room {
  position: absolute;
  top: 44%;
  left: 0;
  width: var(--hall-w);
  height: var(--wall-h);
  transform: translate3d(var(--cam-x, 0px), -50%, 0) rotateY(var(--hall-tilt));
  transform-origin: 0% 50%;
  transform-style: preserve-3d;
}

/* ---------- back wall ---------- */
/* Stops short of the end wall. It used to span the whole hall, which put it
   at z=0 in front of the end wall at z=-40 and painted over its title. */
.hall-wall {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: calc(var(--hall-w) - var(--end-w, 460px));
  background:
    linear-gradient(180deg, rgba(240, 237, 232, .055) 0%, rgba(240, 237, 232, .012) 34%, rgba(240, 237, 232, .03) 78%, rgba(240, 237, 232, .06) 100%),
    linear-gradient(90deg, #131313 0%, #191817 45%, #141413 100%);
  box-shadow: inset 0 0 220px rgba(0, 0, 0, .85);
}
.hall-wall::after {
  /* faint horizontal plaster banding */
  content: '';
  position: absolute;
  inset: 0;
  opacity: .5;
  background: repeating-linear-gradient(180deg, transparent 0 118px, rgba(240, 237, 232, .022) 118px 119px);
}

/* ---------- structural pilasters, one per bay ---------- */
.hall-pilaster {
  position: absolute;
  top: -60px;
  bottom: 0;
  width: 1px;
  background: linear-gradient(180deg, transparent, rgba(240, 237, 232, .11) 22%, rgba(240, 237, 232, .05) 82%, transparent);
}
.hall-pilaster::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 -7px;
  width: 15px;
  background: linear-gradient(90deg, rgba(255, 255, 255, .028), transparent 70%);
}

/* ---------- floor ---------- */
.hall-floor {
  position: absolute;
  left: 0;
  top: var(--wall-h);
  width: 100%;
  height: 1000px;
  transform-origin: top center;
  transform: rotateX(74deg);
  background:
    /* the wall's light spills onto the boards just under the hang */
    linear-gradient(180deg, rgba(232, 86, 58, .10) 0%, transparent 16%),
    repeating-linear-gradient(90deg, transparent 0 159px, rgba(240, 237, 232, .12) 159px 160px),
    repeating-linear-gradient(0deg, transparent 0 159px, rgba(240, 237, 232, .12) 159px 160px),
    linear-gradient(180deg, #2b2825 0%, #161514 38%, #0a0a0a 78%);
  box-shadow: inset 0 30px 70px rgba(0, 0, 0, .55);
}
/* the wall/floor seam, where the two light sources meet */
.hall-seam {
  position: absolute;
  left: 0;
  top: var(--wall-h);
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, transparent, rgba(232, 86, 58, .5) 18%, rgba(240, 237, 232, .3) 50%, rgba(232, 86, 58, .5) 82%, transparent);
  box-shadow: 0 0 26px 5px rgba(232, 86, 58, .3);
}

/* ---------- ceiling light: one lamp per bay, but only the one nearest the
   centre of the screen is lit ---------- */
/* gallery.js sets each beam's opacity from its projected distance to the middle
   of the screen, so the light hands over from bay to bay instead of a fixed
   rhythm of shafts sliding past (which read as a repeating pattern).
   Depth is 34px, not the old 120: the hang sits at z 0-28, and perspective
   pushes anything nearer the camera sideways relative to it (about 44px at 400px
   from the vanishing point), which is what made the shaft miss its work.
   The cone is an angular gradient from the lamp, so its edges are soft by
   construction; no blur filter, no hard box. Width comes from gallery.js
   (--beam-w) because the same number positions it. */
.hall-beam {
  position: absolute;
  top: calc(-1 * var(--wall-h) * 0.55);
  width: var(--beam-w, 540px);
  height: calc(var(--wall-h) * 1.5);
  transform: translateZ(34px);
  pointer-events: none;
  opacity: 0;
}
.hall-beam::before {
  content: '';
  position: absolute;
  inset: 0;
  background: conic-gradient(from 163deg at 50% 0%,
    rgba(255, 238, 214, 0) 0deg,
    rgba(255, 238, 214, .05) 8deg,
    rgba(255, 240, 220, .17) 17deg,
    rgba(255, 238, 214, .05) 26deg,
    rgba(255, 238, 214, 0) 34deg,
    transparent 360deg);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, .7) 40%, transparent 92%);
          mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, .7) 40%, transparent 92%);
}
.hall-beam::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  width: 6px;
  height: 6px;
  margin-left: -3px;
  border-radius: 50%;
  background: #fff3e2;
  box-shadow: 0 0 26px 9px rgba(255, 231, 197, .5);
}

/* ---------- far end wall: where the walk finishes ---------- */
.hall-endwall {
  position: absolute;
  top: -40px;
  right: 0;
  width: var(--end-w, 460px);
  height: calc(var(--wall-h) + 40px);
  transform: translateZ(18px);   /* a shade proud of the back wall, not behind it */
  display: grid;
  place-content: center;
  text-align: center;
  color: var(--white);
  border-left: 1px solid rgba(232, 86, 58, .38);
  background: linear-gradient(160deg, rgba(232, 86, 58, .34), rgba(30, 25, 22, .94) 66%);
  box-shadow: inset 0 0 90px rgba(232, 86, 58, .2), -14px 0 60px rgba(232, 86, 58, .14);
}
.hall-endwall::before {
  content: '';
  position: absolute;
  inset: 18px;
  border: 1px solid rgba(240, 237, 232, .2);
}
.hall-endwall-title {
  position: relative;
  font-family: var(--font-body);
  font-size: clamp(30px, 3.1vw, 46px);
  font-weight: 800;
  line-height: .86;
  letter-spacing: -.05em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 0 34px rgba(255, 190, 160, .35);
}
.hall-endwall-title em {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  text-transform: none;
  color: #ff6b47;
  text-shadow: 0 0 26px rgba(232, 86, 58, .6);
}
.hall-endwall-glow {
  /* a wash of light behind the type, not a bar across the panel */
  position: absolute;
  left: 50%;
  top: 42%;
  width: 150%;
  height: 46%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(232, 86, 58, .46), transparent 68%);
}

/* ---------- compact category heading above the first frame ---------- */
.hall-sign {
  position: absolute;
  top: -16px;
  width: var(--art-w);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(240, 237, 232, .18);
  pointer-events: none;
}
.hall-sign-name {
  margin: 0;
  color: var(--white);
  font: 500 13px var(--font-body);
  line-height: 1.2;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.hall-sign-count {
  flex-shrink: 0;
  color: var(--coral);
  font: 9px var(--gallery-mono);
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* ============================================================
   THE WORKS
   ============================================================ */
.hall-art {
  position: absolute;
  width: var(--art-w);
  transform-style: preserve-3d;
}
.hall-art.is-off { display: none !important; }

.hall-art-btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: var(--white);
  text-align: left;
  font-family: var(--font-body);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* 16:9 — matches every source asset, so nothing is ever cropped on the wall.
   (The demo used .82 + cover, which cut these 16:9 images in half.) */
.hall-art-frame {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  padding: 8px;
  /* a drag that starts on a work must still pan the hall: no native image
     drag, no text selection getting in the way of the pointer */
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
  background: linear-gradient(150deg, #efece5 0%, #b9b5ad 55%, #8f8b83 100%);
  box-shadow:
    0 22px 44px rgba(0, 0, 0, .7),
    0 0 0 1px rgba(255, 255, 255, .22),
    inset 0 0 0 1px rgba(0, 0, 0, .25);
  transition: transform .4s cubic-bezier(.2, .7, .2, 1), box-shadow .4s ease;
}
/* the inner bevel + the picture-light glint along the top edge */
.hall-art-frame::after {
  content: '';
  position: absolute;
  inset: 8px;
  pointer-events: none;
  border: 1px solid rgba(255, 255, 255, .18);
  background: linear-gradient(180deg, rgba(255, 255, 255, .14), transparent 34%);
}
.hall-art-frame img {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background-color: #232220;
  opacity: 0;
  transition: opacity .45s ease;
}
.hall-art-frame.is-loaded img { opacity: 1; }

/* the 20x11 LQIP from IMAGE_MANIFEST, blown up and blurred until the real
   webp lands — reuses the placeholder the old project cards already carried */
.hall-art-lqip {
  position: absolute;
  inset: 8px;
  background-size: cover;
  background-position: center;
  filter: blur(16px) saturate(1.05);
  transform: scale(1.12);
  transition: opacity .45s ease;
}
.hall-art-frame.is-loaded .hall-art-lqip { opacity: 0; }
.hall-art-btn:hover .hall-art-frame,
.hall-art-btn:focus-visible .hall-art-frame {
  transform: translateY(-10px);
  box-shadow:
    0 34px 60px rgba(0, 0, 0, .8),
    0 0 0 1px rgba(255, 255, 255, .4),
    0 0 40px rgba(232, 86, 58, .3);
}
.hall-art-btn:focus-visible {
  outline: 1px solid var(--coral);
  outline-offset: 12px;
}

/* label plate — a wall label, sitting on the work and riding its lift */
.hall-art-tag {
  position: absolute;
  z-index: 2;
  top: 8px;
  left: 8px;
  padding: 3px 7px;
  border-radius: 2px;
  background: rgba(10, 10, 10, .55);
  backdrop-filter: blur(4px);
  color: rgba(240, 237, 232, .72);
  font: 8px var(--gallery-mono);
  letter-spacing: .14em;
  pointer-events: none;
}
.hall-art-tag b {
  margin-left: 7px;
  padding-left: 7px;
  border-left: 1px solid rgba(240, 237, 232, .28);
  color: rgba(240, 237, 232, .5);
  font-weight: 400;
  text-transform: uppercase;
}
.hall-art-caption {
  position: absolute;
  z-index: 2;
  left: 8px;
  right: 8px;
  bottom: 8px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 30px 9px 7px;
  background: linear-gradient(180deg, transparent, rgba(6, 6, 6, .55) 38%, rgba(6, 6, 6, .88));
  pointer-events: none;
  text-align: left;
}
.hall-art-brand {
  color: var(--coral);
  font: 9px var(--gallery-mono);
  letter-spacing: .16em;
  text-transform: uppercase;
}
.hall-art-name {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  font-size: 11.5px;
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: -.005em;
  color: rgba(240, 237, 232, .9);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .7);
}

/* works the camera has already left behind, and ones still far ahead */
.gallery-room .hall-art {
  transition: opacity .5s ease;
}
/* category switch: works go out quickly, then come back on the .5s above.
   The room can't fade as a whole (opacity < 1 flattens preserve-3d). */
.gallery-room.is-out .hall-art,
.gallery-room.is-out .hall-sign { opacity: 0 !important; transition-duration: .2s !important; }
.gallery-room .hall-sign { transition: opacity .5s ease; }

/* ============================================================
   FIRST-SCREEN COPY
   ============================================================ */
/* --walk (0..1) is written by gallery.js from the camera position, so the copy
   dissolves continuously over the first 10% of the walk. No CSS transition on
   purpose: the camera is already eased, a second ease would lag behind it. */
.gallery-copy {
  position: absolute;
  /* above the vignette (.gallery-pin::after, z 6) so the headline and the
     button are not darkened by it; still under the scrim (z 8) so they go
     down with the hall at the end of the walk */
  z-index: 7;
  left: 6vw;
  top: 27%;
  width: min(40vw, 540px);
  pointer-events: none;
  opacity: calc(1 - var(--walk, 0));
  transform: translateY(calc(var(--walk, 0) * -26px));
}
/* fully gone: also take the CTA out of hit-testing and tab order */
.gallery.is-away .gallery-copy { visibility: hidden; }

.gallery-eyebrow {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 0 0 26px;
  color: rgba(240, 237, 232, .55);
  font: 10px var(--gallery-mono);
  letter-spacing: .18em;
  text-transform: uppercase;
}
.gallery-eyebrow::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--coral);
  box-shadow: 0 0 14px var(--coral);
}

.gallery-title {
  margin: 0;
  font-family: var(--font-body);
  font-size: clamp(62px, 8.6vw, 138px);
  font-weight: 800;
  line-height: .82;
  letter-spacing: -.06em;
  text-transform: uppercase;
}
.gallery-title em {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  text-transform: none;
  color: var(--coral);
}

.gallery-sub {
  margin: 32px 0 0;
  max-width: 22ch;
  color: rgba(240, 237, 232, .62);
  font-size: 15px;
  font-weight: 300;
  line-height: 1.75;
}
.gallery-sub span {
  display: block;
  color: rgba(240, 237, 232, .9);
  font-weight: 500;
}

/* ---------- Watch Video Portfolio (the first screen's one call to action) ---------- */
.gallery-video-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 26px;
  padding: 11px 18px;
  border: 1px solid rgba(240, 237, 232, .28);
  border-radius: 100px;
  color: var(--white);
  font-size: 12px;
  letter-spacing: 1.6px;
  text-decoration: none;
  pointer-events: auto;
  cursor: pointer;
  transition: background .3s ease, border-color .3s ease, color .3s ease;
}
.gallery-video-cta:hover {
  background: var(--coral);
  border-color: var(--coral);
  color: var(--black);
}
.gallery-video-cta svg { transition: transform .25s ease; }
.gallery-video-cta:hover svg { transform: translate(3px, -3px); }

/* ============================================================
   HUD
   ============================================================ */
.gallery-hint {
  position: absolute;
  z-index: 4;
  left: 6vw;
  bottom: 42px;
  display: flex;
  align-items: center;
  gap: 10px;
  color: rgba(240, 237, 232, .45);
  font: 10px var(--gallery-mono);
  letter-spacing: .16em;
  text-transform: uppercase;
  transition: opacity .4s ease;
}
.gallery-hint::before {
  content: '';
  width: 6px;
  height: 6px;
  border: 1px solid var(--coral);
  border-radius: 50%;
}
.gallery.is-walking .gallery-hint { opacity: 0; }

/* ---------- category chips: sit directly above the progress rail ---------- */
.gallery-cats {
  position: absolute;
  z-index: 7;   /* above the vignette (6) so they stay legible; under the scrim (8) */
  right: 4vw;
  bottom: 80px;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
  max-width: min(760px, 66vw);
}
.gallery-cat {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  border: 1px solid rgba(240, 237, 232, .16);
  border-radius: 100px;
  background: rgba(10, 10, 10, .5);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: rgba(240, 237, 232, .6);
  font: 10px var(--gallery-mono);
  letter-spacing: .12em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color .25s ease, border-color .25s ease, background .25s ease;
}
.gallery-cat-n { color: rgba(240, 237, 232, .38); transition: color .25s ease; }
.gallery-cat:hover { color: var(--white); border-color: rgba(240, 237, 232, .4); }
.gallery-cat:focus-visible { outline: 1px solid var(--coral); outline-offset: 3px; }
.gallery-cat.is-active {
  color: var(--white);
  border-color: rgba(232, 86, 58, .8);
  background: rgba(232, 86, 58, .16);
}
.gallery-cat.is-active .gallery-cat-n { color: rgba(255, 190, 170, .8); }
/* in the full hall: the chapter the camera is in front of */
.gallery-cat.is-here:not(.is-active) { color: var(--white); }
.gallery-cat.is-here:not(.is-active)::before {
  content: '';
  width: 5px;
  height: 5px;
  margin-right: -1px;
  border-radius: 50%;
  background: var(--coral);
  box-shadow: 0 0 8px var(--coral);
}

/* ---------- progress rail ---------- */
.gallery-rail {
  position: absolute;
  z-index: 5;
  right: 4vw;
  bottom: 42px;
  display: flex;
  align-items: center;
  gap: 16px;
}
.gallery-rail-cat {
  color: var(--coral);
  font: 10px var(--gallery-mono);
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
}
.gallery-rail-track {
  position: relative;
  width: clamp(140px, 22vw, 320px);
  height: 22px;
  display: flex;
  align-items: center;
  cursor: pointer;
}
.gallery-rail-track::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: rgba(240, 237, 232, .18);
}
.gallery-rail-fill {
  position: absolute;
  left: 0;
  height: 1px;
  width: 0;
  background: var(--coral);
  box-shadow: 0 0 10px rgba(232, 86, 58, .7);
}
.gallery-rail-knob {
  position: absolute;
  left: 0;
  width: 7px;
  height: 7px;
  margin-left: -3.5px;
  border-radius: 50%;
  background: var(--coral);
  box-shadow: 0 0 12px 3px rgba(232, 86, 58, .55);
}
.gallery-rail-ticks {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.gallery-rail-ticks i {
  position: absolute;
  top: 50%;
  width: 1px;
  height: 7px;
  margin-top: -3.5px;
  background: rgba(240, 237, 232, .22);
}
/* where a category begins along the walk */
.gallery-rail-ticks i.is-chapter {
  height: 13px;
  margin-top: -6.5px;
  background: rgba(240, 237, 232, .5);
}
.gallery-rail-count {
  min-width: 84px;
  color: rgba(240, 237, 232, .62);
  font: 10px var(--gallery-mono);
  letter-spacing: .14em;
  text-align: right;
}
.gallery-rail-count b {
  color: var(--white);
  font-weight: 500;
}

/* ============================================================
   WORK VIEWER — full-res, never cropped
   ============================================================ */
.viewer {
  position: fixed;
  inset: 0;
  z-index: 10001;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 370px);
  /* opaque: at .97 the hall's picture frames ghosted through the backdrop and
     read as a rendering artefact rather than depth */
  background:
    radial-gradient(ellipse 70% 60% at 42% 46%, #101010, #060606 72%);
  opacity: 0;
  pointer-events: none;
  transition: opacity .32s ease;
}
.viewer.is-open { opacity: 1; pointer-events: auto; }
.viewer[hidden] { display: none; }

.viewer-stage {
  position: relative;
  display: grid;
  place-items: center;
  min-width: 0;
  min-height: 0;
  padding: clamp(56px, 7vh, 92px) clamp(20px, 4vw, 64px);
}

/* the frame is locked to the source ratio, so `contain` never letterboxes
   and never crops — the whole picture is always on screen, edge to edge */
.viewer-frame {
  position: relative;
  width: 100%;
  max-width: min(100%, calc((100dvh - 200px) * 16 / 9));
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #131313;
  box-shadow: 0 30px 100px rgba(0, 0, 0, .8);
}
.viewer-frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;   /* the guarantee: complete image, no crop */
  opacity: 0;
  transition: opacity .45s ease;
}
.viewer-frame img.is-loaded { opacity: 1; }
/* the 20x11 LQIP sits underneath and cross-fades out */
.viewer-lqip {
  position: absolute;
  inset: -6%;
  width: 112%;
  height: 112%;
  object-fit: cover;
  filter: blur(26px) saturate(1.1);
  transform: scale(1.06);
}
.viewer-frame.is-loaded .viewer-lqip { opacity: 0; transition: opacity .45s ease .1s; }

/* the 3840px original takes a moment — say so rather than showing a stall */
.viewer-loading {
  position: absolute;
  left: 50%;
  bottom: -30px;
  transform: translateX(-50%);
  color: rgba(240, 237, 232, .45);
  font: 9px var(--gallery-mono);
  letter-spacing: .2em;
  text-transform: uppercase;
  white-space: nowrap;
}
.viewer-loading[hidden] { display: none; }
.viewer-loading::before {
  content: '';
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 9px;
  border-radius: 50%;
  background: var(--coral);
  animation: viewer-pulse 1.1s ease-in-out infinite;
}
@keyframes viewer-pulse {
  0%, 100% { opacity: .25; }
  50%      { opacity: 1; }
}

/* ---------- side panel ---------- */
.viewer-panel {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  padding: clamp(28px, 4vw, 56px) clamp(24px, 3vw, 44px);
  border-left: 1px solid rgba(240, 237, 232, .11);
  background: linear-gradient(180deg, rgba(240, 237, 232, .022), transparent 40%);
  overflow-y: auto;
  min-height: 0;
}
.viewer-kicker {
  color: var(--coral);
  font: 10px var(--gallery-mono);
  letter-spacing: .2em;
  text-transform: uppercase;
}
.viewer-brand {
  margin-top: 16px;
  color: var(--white);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 4px;
  text-transform: uppercase;
}
.viewer-name {
  margin: 12px 0 0;
  font-family: var(--font-display);
  font-size: clamp(28px, 2.7vw, 44px);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -.015em;
}
.viewer-facts {
  margin-top: 34px;
  border-top: 1px solid rgba(240, 237, 232, .12);
}
.viewer-fact {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 13px 0;
  border-bottom: 1px solid rgba(240, 237, 232, .12);
  font: 11px var(--gallery-mono);
  letter-spacing: .1em;
}
.viewer-fact dt { color: rgba(240, 237, 232, .42); text-transform: uppercase; }
.viewer-fact dd { color: var(--white); text-align: right; }

.viewer-nav {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 34px;
}
.viewer-nav button {
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  border: 1px solid rgba(240, 237, 232, .2);
  border-radius: 50%;
  background: none;
  color: var(--white);
  font-size: 17px;
  cursor: pointer;
  transition: background .22s ease, border-color .22s ease, color .22s ease;
}
.viewer-nav button:hover {
  background: var(--coral);
  border-color: var(--coral);
  color: var(--black);
}
.viewer-nav-count {
  color: rgba(240, 237, 232, .5);
  font: 10px var(--gallery-mono);
  letter-spacing: .14em;
}
.viewer-nav-count b { color: var(--white); font-weight: 500; }

.viewer-close {
  position: absolute;
  z-index: 3;
  top: clamp(16px, 3vh, 32px);
  right: clamp(16px, 3vw, 40px);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 4px;
  border: 0;
  background: none;
  color: var(--white);
  font: 10px var(--gallery-mono);
  letter-spacing: .18em;
  text-transform: uppercase;
  cursor: pointer;
}
.viewer-close span {
  color: var(--coral);
  font-size: 22px;
  line-height: 1;
}

.viewer-footnote {
  position: absolute;
  left: clamp(20px, 4vw, 64px);
  bottom: clamp(16px, 2.5vh, 28px);
  color: #56534e;
  font: 9px var(--gallery-mono);
  letter-spacing: .18em;
  text-transform: uppercase;
}

/* ============================================================
   MOBILE WORK BOOK / COMPLETE INDEX
   ============================================================ */
.mobile-work-heading,
.mobile-work-entry { display: none; }
.work-index[hidden] { display: none; }
.work-index {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  flex-direction: column;
  background: var(--black);
  color: var(--white);
}
.work-index-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: max(16px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) 12px max(20px, env(safe-area-inset-left));
}
.work-index-header h2 {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-family: var(--font-display);
  font-size: clamp(28px, 6vw, 40px);
  font-weight: 400;
  line-height: 1.1;
}
.work-index-total { color: var(--grey); font: 12px var(--font-body); }
.work-index-actions { display: flex; align-items: center; gap: 8px; }
.work-index-language,
.work-index-close,
.work-index-filter,
.work-index-more,
.mobile-work-entry {
  font-family: var(--font-body);
  color: var(--white);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.work-index-language { min-width: 56px; height: 44px; padding: 0 12px; border: 1px solid rgba(240,237,232,.3); border-radius: 100px; background: none; font-size: 12px; }
.work-index-close { width: 44px; height: 44px; border: 0; background: none; font-size: 30px; line-height: 1; }
.work-index-filters {
  display: flex;
  flex: 0 0 auto;
  gap: 8px;
  overflow-x: auto;
  padding: 0 20px 16px;
  border-bottom: 1px solid rgba(240,237,232,.12);
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.work-index-filters::-webkit-scrollbar { display: none; }
.work-index-filter { display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0; min-height: 44px; padding: 0 15px; border: 1px solid rgba(240,237,232,.2); border-radius: 100px; background: none; font-size: 13px; white-space: nowrap; }
.work-index-filter-count { color: rgba(240,237,232,.55); font-size: 11px; }
.work-index-filter.is-active { border-color: var(--coral); background: rgba(232,86,58,.12); }
.work-index-scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior-y: contain; padding: 24px max(20px, env(safe-area-inset-right)) max(32px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left)); }
.work-index-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 14px; max-width: 960px; margin: 0 auto; }
.work-index-card { min-width: 0; padding: 0; border: 0; background: none; color: var(--white); text-align: left; font-family: var(--font-body); cursor: pointer; }
.work-index-frame { display: block; aspect-ratio: 16 / 9; padding: 4px; background: linear-gradient(150deg, #efece5, #8f8b83); }
.work-index-frame img { display: block; width: 100%; height: 100%; object-fit: contain; background: var(--dark); }
.work-index-brand { display: block; margin-top: 10px; font-size: 13px; font-weight: 500; line-height: 1.3; }
.work-index-name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; margin-top: 4px; color: rgba(240,237,232,.7); font-size: 12px; line-height: 1.45; }
.work-index-category { display: block; margin-top: 6px; color: var(--coral); font-size: 11px; line-height: 1.4; }
.work-index-footer { display: flex; flex-direction: column; align-items: center; gap: 16px; padding-top: 36px; }
.work-index-footer p { color: rgba(240,237,232,.65); font-size: 12px; }
.work-index-more { min-height: 48px; padding: 10px 28px; border: 1px solid rgba(240,237,232,.3); border-radius: 100px; background: none; font-size: 14px; }
.work-index-more[hidden] { display: none; }
.work-index button:focus-visible,
.mobile-work-entry:focus-visible { outline: 2px solid var(--coral); outline-offset: 4px; }
@media (hover: hover) {
  .work-index-card:hover .work-index-brand { color: var(--coral); }
  .work-index-more:hover { border-color: var(--white); }
}

/* Below 1024px, the home page is a curated book of at most eight works.
   The complete collection lives in the independently scrolling index. */
@media (max-width: 1023px) {
  .gallery {
    height: auto;
    padding: max(clamp(70px, 12vw, 110px), calc(var(--mobile-nav-height, 0px) + 16px)) 0 clamp(50px, 8vw, 80px);
  }
  .gallery-pin {
    position: static;
    height: auto;
    min-height: 0;
    overflow: visible;
    /* The home page follows its reading and keyboard order on mobile. */
    display: flex;
    flex-direction: column;
  }
  .gallery-copy { order: 1; }
  .gallery-cats { display: none; }
  .mobile-work-heading { order: 2; }
  .gallery-scene { order: 3; }
  .mobile-work-entry-bottom { order: 4; }
  .gallery-pin::before,
  .gallery-pin::after { display: none; }

  .gallery-copy {
    position: static;
    width: auto;
    margin: 0 clamp(20px, 5vw, 40px) clamp(30px, 6vw, 46px);
  }
  .gallery-title { font-size: clamp(52px, 15vw, 92px); }
  .gallery-sub { max-width: none; font-size: 14px; }

  .gallery-cats {
    position: static;
    max-width: none;
    justify-content: flex-start;
    margin: 0 clamp(20px, 5vw, 40px) clamp(24px, 5vw, 36px);
  }
  .gallery-cats { display: none; }
  .gallery-cat { padding: 8px 13px; }
  .gallery-rail-cat { display: none; }

  .gallery-scene {
    position: static;
    perspective: none;
    overflow: visible;
    touch-action: auto;
    cursor: auto;
  }
  .gallery-room {
    position: static;
    width: 100%;
    height: auto;
    transform: none;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: clamp(24px, 4vw, 40px) clamp(16px, 2.5vw, 28px);
    padding: 0 clamp(20px, 5vw, 40px);
  }
  .hall-wall,
  .hall-floor,
  .hall-seam,
  .hall-beam,
  .hall-sign,
  .hall-pilaster,
  .hall-endwall { display: none; }

  .hall-art {
    position: static;
    width: auto;
    transform: none !important;
  }
  .mobile-work-heading { display: flex; justify-content: space-between; align-items: baseline; gap: 20px; margin: 8px clamp(20px, 5vw, 40px) 24px; padding-top: 24px; border-top: 1px solid rgba(240,237,232,.15); }
  .mobile-work-heading h2 { font: 400 28px/1.2 var(--font-display); }
  .mobile-work-heading > span { color: rgba(240,237,232,.65); font-size: 12px; white-space: nowrap; }
  .mobile-work-entry { display: inline-flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 44px; background: none; font-size: 14px; pointer-events: auto; }
  .mobile-work-entry-top { display: flex; width: fit-content; margin-top: 16px; padding: 8px 0; border: 0; border-bottom: 1px solid rgba(240,237,232,.3); }
  .mobile-work-entry-bottom { margin: 32px clamp(20px, 5vw, 40px) 0; padding: 18px 20px; border: 1px solid rgba(240,237,232,.3); border-radius: 4px; }
  .mobile-work-entry-count { color: var(--coral); font-size: 12px; }
  .hall-art-frame img { object-fit: contain; }
  .hall-art-caption { position: static; padding: 14px 0 0; gap: 5px; background: none; text-shadow: none; }
  .hall-art-brand { font: 500 14px/1.3 var(--font-body); letter-spacing: .01em; text-transform: none; }
  .hall-art-name { font-size: 15px; line-height: 1.4; text-shadow: none; }
  .hall-art-btn:hover .hall-art-frame { transform: none; }

  .gallery-hint { display: none; }
  .gallery-rail {
    display: none;
  }

  /* viewer stacks: image on top, panel below */
  .viewer {
    grid-template-columns: 1fr;
    grid-template-rows: minmax(0, 1fr) auto;
  }
  .viewer-stage { padding: clamp(56px, 9vh, 80px) clamp(16px, 4vw, 28px) 20px; }
  .viewer-frame { max-width: 100%; max-height: min(52dvh, 100%); aspect-ratio: 16 / 9; }
  .viewer-panel {
    justify-content: flex-start;
    padding: 22px clamp(20px, 5vw, 28px) clamp(28px, 5vh, 40px);
    border-left: 0;
    border-top: 1px solid rgba(240, 237, 232, .11);
  }
  .viewer-name { font-size: clamp(24px, 6.5vw, 34px); }
  .viewer-facts { margin-top: 20px; }
  .viewer-nav { margin-top: 20px; }
  .viewer-footnote { display: none; }
}

@media (min-width: 600px) {
  .work-index-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 520px) {
  .gallery-room { grid-template-columns: 1fr; }
}

/* A short landscape viewport needs room for both the complete image and details. */
@media (min-width: 600px) and (max-width: 1023px) and (max-height: 520px) {
  .viewer { grid-template-columns: minmax(0, 1fr) minmax(260px, 320px); grid-template-rows: minmax(0, 1fr); }
  .viewer-stage { padding: 56px 20px; }
  .viewer-frame { max-width: min(100%, calc((100dvh - 112px) * 16 / 9)); max-height: 100%; }
  .viewer-panel { padding: 60px 24px 20px; border-top: 0; border-left: 1px solid rgba(240, 237, 232, .11); }
  .viewer-name { font-size: 24px; }
  .viewer-brand { margin-top: 8px; }
  .viewer-facts, .viewer-nav { margin-top: 16px; }
  .viewer-fact { padding: 10px 0; }
}

/* ============================================================
   REDUCED MOTION
   The pan is navigation, not decoration, so it stays — but the
   damping, the parallax tilt and the hover lift all go.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .viewer-loading::before { animation: none; opacity: 1; }
  .hall-art-btn,
  .hall-art-frame,
  .gallery-copy,
  .gallery-hint,
  .viewer,
  .viewer-frame img { transition: none !important; }
}

@media (prefers-reduced-motion: reduce) and (min-width: 1024px) {
  .gallery-room { transform: translate3d(var(--cam-x, 0px), -50%, 0); }
}

/* mono stack lives at the top of this file, next to the rest of the tokens */
