*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

[hidden] { display: none !important; }

html, body {
  width: 100%;
  height: 100%;
  background: #111;
  color: #fff;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  overflow: hidden;
}

/* ── Room ────────────────────────────────────────────── */
/* Gallery wall behind the stage. Corner ambient occlusion darkens
   where the walls meet; floor zone fades down. JS applies a
   micro-parallax translate so the wall moves slower than the image. */

#room {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 50% 42% at 0%   0%,   rgba(0,0,0,0.50) 0%, transparent 100%),
    radial-gradient(ellipse 50% 42% at 100% 0%,   rgba(0,0,0,0.50) 0%, transparent 100%),
    radial-gradient(ellipse 44% 54% at 0%   100%, rgba(0,0,0,0.62) 0%, transparent 100%),
    radial-gradient(ellipse 44% 54% at 100% 100%, rgba(0,0,0,0.62) 0%, transparent 100%),
    linear-gradient(to bottom, transparent 52%, rgba(0,0,0,0.24) 100%),
    #0d0d0d;
}

/* ── Transition label ────────────────────────────────── */
/* Appears on gallery switch: dims/blurs current image, shows destination.
   Fades out once the new image begins its reveal. */

#transition-label {
  position: fixed;
  inset: 0;
  z-index: 102;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.8s ease;
}

#transition-label.visible { opacity: 1; }

#transition-label span {
  font-size: 9px;
  font-weight: 300;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.38);
}

/* ── Stage ───────────────────────────────────────────── */

#stage {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Vignette — gallery ceiling light from above, floor fades to dark */
/* Asymmetric: softer at top-center (light source), heavier at bottom (floor).
   Breathes very slowly — the room feels inhabited. */

@keyframes vignette-breathe {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.76; }
}

#vignette {
  position: fixed;
  inset: 0;
  background:
    radial-gradient(ellipse 78% 64% at var(--vx, 50%) var(--vy, 38%), transparent 0%, rgba(0,0,0,0.75) 100%),
    linear-gradient(to bottom, transparent 36%, rgba(0,0,0,0.30) 100%);
  pointer-events: none;
  z-index: 100;
  animation: vignette-breathe 26s ease-in-out infinite;
}

/* ── Slides ──────────────────────────────────────────── */

.slide {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
}

/* ── Frame ───────────────────────────────────────────── */

.image-frame {
  position: relative;
}

/* ── Slow pull-in ────────────────────────────────────── */
/* Image very slowly grows over the dwell period — the viewer
   is drawn toward the work. Reset per image via JS. */

@keyframes slowzoom {
  from { transform: scale(1.000); }
  to   { transform: scale(1.300); }
}

.image-zoom {
  position: relative;
  animation: slowzoom 50s ease-in forwards;
  will-change: transform;
}

/* Transparent layer above the photo. A long-press / right-click lands on
   this non-image div instead of the <img>, so mobile browsers offer no
   "save / copy image". (Screenshots can't be prevented.) */
.image-shield {
  position: absolute;
  inset: 0;
  z-index: 2;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
}

/* ── Photo + matte ───────────────────────────────────── */
/* Multiple box-shadow layers: thin hard inner core defines the mat
   surface, each subsequent layer adds spread and blur so the white
   dissolves smoothly rather than stopping at a hard edge. */

.photo {
  display: block;
  width: auto;
  height: auto;
  max-height: 56vh;
  user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  pointer-events: none;
  box-shadow:
    0 0 0 42px rgba(248, 245, 241, 0.97),          /* paper mat — near paper white */
    0 10px 44px 6px rgba(0,0,0,0.88),               /* print hangs from wall — shadow below */
    /* glow — many fine, overlapping layers so the falloff steps stay
       narrow and read as smooth rather than banding into rings */
    0 0 55px  16px rgba(220, 214, 206, 0.085),
    0 0 100px 38px rgba(212, 206, 198, 0.060),
    0 0 150px 62px rgba(204, 198, 190, 0.040),
    0 0 210px 96px rgba(196, 191, 182, 0.026),
    0 0 290px 140px rgba(188, 183, 174, 0.015);     /* widest, faintest spill */
}

.slide.matte-grey .photo {
  box-shadow:
    0 0 0 42px rgba(185, 183, 180, 0.97),          /* neutral grey mat */
    0 10px 44px 6px rgba(0,0,0,0.88),
    0 0 55px  16px rgba(152, 150, 146, 0.085),
    0 0 100px 38px rgba(146, 144, 140, 0.060),
    0 0 150px 62px rgba(140, 138, 134, 0.040),
    0 0 210px 96px rgba(134, 132, 128, 0.026),
    0 0 290px 140px rgba(128, 126, 122, 0.015);
}

.slide.size-small  .photo { max-width: min(300px, 68vw); }
.slide.size-medium .photo { max-width: min(500px, 74vw); }
.slide.size-large  .photo { max-width: min(740px, 80vw); }

/* ── HUD layers ──────────────────────────────────────── */
/* Two floating label boxes. JS sets their vertical position per-image
   so the composition shifts slightly with each photograph. */

.layer-info,
.layer-notes {
  position: absolute;
  pointer-events: none;
  will-change: transform;
  background-color: rgba(14, 14, 14, 0.52);
  padding: 6px 10px;
  border-radius: 4px;
  opacity: 0;
  filter: blur(7px);
}

/* Identity box — left side, right edge 32px from image. JS randomises bottom. */
.layer-info {
  right: calc(100% + 32px);
  bottom: 60px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-align: right;
  width: 260px;
}

/* Notes box — right side, left edge 32px from image. JS randomises top. */
.layer-notes {
  left: calc(100% + 32px);
  top: 80px;
  width: 260px;
  text-align: left;
  font-size: 11px;
  font-weight: 300;
  letter-spacing: 0.06em;
  line-height: 2.0;
  font-style: italic;
  color: rgba(255, 255, 255, 0.78);
  overflow-wrap: break-word;
  hyphens: auto;
}

/* ── Text states ─────────────────────────────────────── */

.layer-info.visible,
.layer-notes.visible {
  opacity: 1;
  filter: blur(0);
}

/* ── Typography ──────────────────────────────────────── */


.info-title {
  font-size: 10px;
  font-weight: 300;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.88);
  overflow-wrap: break-word;
  hyphens: auto;
}

.info-dateline {
  font-size: 9px;
  font-weight: 300;
  letter-spacing: 0.20em;
  color: rgba(255, 255, 255, 0.50);
  overflow-wrap: break-word;
  hyphens: auto;
}

.info-medium {
  font-size: 9px;
  font-weight: 300;
  letter-spacing: 0.16em;
  color: rgba(255, 255, 255, 0.42);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  padding-top: 5px;
  margin-top: 2px;
  overflow-wrap: break-word;
  hyphens: auto;
}

/* ── Collection nav ──────────────────────────────────── */

#collections {
  position: fixed;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 101;
  display: flex;
  align-items: center;
  pointer-events: all;
  white-space: nowrap;
}

#collections a {
  font-size: 8px;
  font-weight: 300;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.20);
  text-decoration: none;
  padding: 4px 12px;
  cursor: pointer;
  transition: color 0.3s ease;
}

#collections a:hover  { color: rgba(255, 255, 255, 0.50); }
#collections a.active { color: rgba(255, 255, 255, 0.55); }

#collections .sep {
  width: 1px;
  height: 8px;
  background: rgba(255, 255, 255, 0.12);
  flex-shrink: 0;
}

/* ── Byline ──────────────────────────────────────────── */

#byline {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 101;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  font-size: 8px;
  font-weight: 300;
  letter-spacing: 0.30em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.28);
  white-space: nowrap;
  pointer-events: none;
}

.byline-row {
  display: flex;
  align-items: center;
  gap: 6px;
  justify-content: center;
  pointer-events: all;
}

.byline-dot {
  color: rgba(255, 255, 255, 0.10);
  font-size: 8px;
}

#inquire,
#notify-btn {
  color: rgba(255, 255, 255, 0.16);
  text-decoration: none;
  letter-spacing: 0.28em;
  cursor: pointer;
  transition: color 0.4s ease;
}

#notify-btn {
  background: none;
  border: none;
  font-size: 8px;
  font-family: inherit;
  font-weight: 300;
  text-transform: uppercase;
  padding: 0;
}

#inquire:hover,
#notify-btn:hover {
  color: rgba(255, 255, 255, 0.42);
}

/* ── About button ────────────────────────────────────── */

#about-btn {
  background: none;
  border: none;
  font-size: 8px;
  font-family: inherit;
  font-weight: 300;
  letter-spacing: 0.30em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.28);
  cursor: pointer;
  padding: 0;
  transition: color 0.4s ease;
  display: block;
}

#about-btn { pointer-events: all; }
#about-btn:hover { color: rgba(255, 255, 255, 0.50); }

/* ── About modal ─────────────────────────────────────── */

#about-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.62);
  cursor: default;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.55s ease;
}

#about-modal.visible {
  opacity: 1;
  pointer-events: auto;
}

#about-box {
  background: rgba(14, 14, 14, 0.90);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 6px;
  padding: 36px 40px;
  width: min(500px, 90vw);
  max-height: 78vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

#about-image {
  width: 100%;
  max-height: 280px;
  object-fit: contain;
  border-radius: 3px;
  display: block;
}

#about-heading {
  font-size: 10px;
  font-weight: 300;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.65);
}

#about-body {
  font-size: 11px;
  font-weight: 300;
  letter-spacing: 0.06em;
  line-height: 2.1;
  color: rgba(255, 255, 255, 0.48);
}

#about-body p + p { margin-top: 14px; }

/* ── Signup modal ─────────────────────────────────────── */

#signup-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.70);
  backdrop-filter: blur(4px);
  cursor: default;
}

#signup-box {
  background: #161616;
  border: 1px solid #2a2a2a;
  border-radius: 6px;
  padding: 32px 36px;
  width: min(340px, 90vw);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

#signup-intro {
  font-size: 11px;
  font-weight: 300;
  letter-spacing: 0.10em;
  color: rgba(255,255,255,0.55);
}

#signup-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

#signup-form input {
  background: #0f0f0f;
  border: 1px solid #2a2a2a;
  border-radius: 3px;
  color: rgba(255,255,255,0.80);
  font-size: 12px;
  font-family: inherit;
  padding: 9px 12px;
  outline: none;
  width: 100%;
}
#signup-form input:focus { border-color: #444; }

#signup-actions {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}

#signup-submit {
  background: rgba(255,255,255,0.90);
  border: none;
  border-radius: 3px;
  color: #000;
  cursor: pointer;
  font-size: 11px;
  font-family: inherit;
  font-weight: 500;
  letter-spacing: 0.08em;
  padding: 9px 18px;
  flex: 1;
}

#signup-close {
  background: none;
  border: 1px solid #2a2a2a;
  border-radius: 3px;
  color: rgba(255,255,255,0.35);
  cursor: pointer;
  font-size: 11px;
  font-family: inherit;
  padding: 9px 14px;
}
#signup-close:hover { border-color: #444; color: rgba(255,255,255,0.60); }

#signup-error {
  font-size: 11px;
  color: #c0392b;
}

/* ── Timer bar ───────────────────────────────────────── */

#timer-bar {
  position: fixed;
  bottom: 50px;
  left: 50%;
  transform: translateX(-50%);
  width: 180px;
  height: 4px;
  display: flex;
  align-items: center;
  pointer-events: none;
  z-index: 101;
}

.timer-half {
  height: 1px;
  background: rgba(255, 255, 255, 0.20);
  flex: 1;
}

.timer-left  { transform-origin: right center; }
.timer-right { transform-origin: left center; }

.timer-dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.20);
  flex-shrink: 0;
}

/* ── No-matte variant ────────────────────────────────── */

.slide.no-matte .photo {
  box-shadow: none;
}

/* ── Bodies gate ─────────────────────────────────────── */

#bodies-gate {
  position: fixed;
  inset: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(17, 17, 17, 0.96);
  cursor: default;
  transition: opacity 1.2s ease;
}

#bodies-gate.dismissing {
  opacity: 0;
  pointer-events: none;
}

#bodies-gate-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  max-width: 360px;
  padding: 40px 24px;
  text-align: center;
  user-select: none;
}

.gate-heading {
  font-size: 11px;
  font-weight: 300;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}

.gate-body {
  font-size: 10px;
  font-weight: 300;
  letter-spacing: 0.12em;
  line-height: 2.2;
  color: rgba(255, 255, 255, 0.36);
}

.gate-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  margin-top: 8px;
}

#bodies-enter {
  background: none;
  border: none;
  font-size: 8px;
  font-family: inherit;
  font-weight: 300;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.28);
  cursor: pointer;
  padding: 0;
  transition: color 0.4s ease;
}

#bodies-enter:hover { color: rgba(255, 255, 255, 0.60); }

#bodies-leave {
  background: none;
  border: none;
  font-size: 8px;
  font-family: inherit;
  font-weight: 300;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.14);
  cursor: pointer;
  padding: 0;
  transition: color 0.4s ease;
}

#bodies-leave:hover { color: rgba(255, 255, 255, 0.35); }

/* ── Welcome overlay ─────────────────────────────────── */

#welcome {
  position: fixed;
  inset: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(17, 17, 17, 0.86);
  cursor: default;
  transition: opacity 1.8s ease;
}

#welcome.dismissing {
  opacity: 0;
  pointer-events: none;
}

#welcome-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 28px;
  max-width: 400px;
  padding: 40px 24px;
  text-align: center;
  user-select: none;
}

.welcome-heading {
  font-size: 13px;
  font-weight: 300;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
}

.welcome-body {
  font-size: 10px;
  font-weight: 300;
  letter-spacing: 0.14em;
  line-height: 2.4;
  color: rgba(255, 255, 255, 0.52);
}

.welcome-audio-note {
  font-size: 8px;
  font-weight: 300;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.36);
}

.welcome-enter {
  font-size: 8px;
  font-weight: 300;
  letter-spacing: 0.30em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.28);
  margin-top: 8px;
}

#mute-btn {
  background: none;
  border: none;
  font-size: 10px;
  color: rgba(255, 255, 255, 0.16);
  cursor: pointer;
  padding: 0;
  transition: color 0.3s ease;
  font-family: inherit;
}
#mute-btn:hover { color: rgba(255, 255, 255, 0.42); }
#mute-btn.muted { color: rgba(255, 255, 255, 0.08); }


/* ── Mobile ──────────────────────────────────────────── */
/* On narrow screens there's no room beside or below a portrait photo.
   Nav becomes a scrollable row. Text overlays the bottom of the image
   with a fade-up gradient so it's always visible regardless of image size. */

@media (max-width: 700px) {

  /* Nav: single scrollable row, no wrapping */
  #collections {
    left: 0;
    transform: none;
    width: 100%;
    padding: 0 16px;
    justify-content: flex-start;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 10px;
  }
  #collections::-webkit-scrollbar { display: none; }

  /* Slightly smaller photo so the caption below has room without crowding */
  .photo { max-height: 48vh; }

  /* Info sits BELOW the photo — never over it. Offset clears the mat and
     the slow zoom's downward growth across screen sizes. No gradient since
     it's no longer on the image. */
  .layer-info {
    right: 0;
    left: 0;
    top: calc(100% + 8vh + 48px);
    bottom: auto;
    width: auto !important;
    text-align: center;
    background: none;
    padding: 0 16px;
    border-radius: 0;
  }

  /* Notes: no room, hide them */
  .layer-notes { display: none !important; }
}
