/*
  COLD PIPE COLLECTIVE — Museum Walk
  First-person corridor built with CSS 3D transforms. No libraries.
  Palette and type come from :root in style.css.
*/

:root {
  --hall-w: 1000px;   /* wall to wall; walls sit at +/- half this */
  --hall-h: 760px;    /* floor to ceiling */
  --art-h: 440px;     /* artwork frame height */
  --corridor-len: 16800px;

  --wall: #101013;
}

/* ---------------------------------------------------------------
   Stage
   Fixed rather than sticky: iOS Safari flattens preserve-3d
   children inside a sticky ancestor.
   --------------------------------------------------------------- */

.museum-stage {
  position: fixed;
  inset: 0;
  /* main carries margin-top: 75px for the old document layout. On a
     fixed box with top and bottom both pinned that margin is not
     ignored — it shifted the whole corridor down and shortened it, so
     the perspective origin no longer sat at eye level. */
  margin: 0;
  z-index: 2;
  overflow: hidden;
  perspective: 1000px;
  perspective-origin: 50% 50%;
  /* Transparent on purpose: an opaque stage would bury the ambient
     canvas (z-index 0). The void past the walls falls through to the
     body background, which is the same near-black. */
  background: transparent;
}

/* Grain belongs on top of the corridor, not underneath it. */
.film-grain {
  z-index: 30;
}

.museum-world {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
  will-change: transform;
}

/* Every 3D child is placed from the world origin (screen centre). */
.museum-world > * {
  position: absolute;
  transform-style: preserve-3d;
}

/* Scroll height driver. The stage is fixed, so scroll length lives
   here: museum.js fills this with one .snap per stop, and scroll
   snapping is what makes a single gesture land on exactly one work. */
.museum-scroll {
  position: relative;
  z-index: 1;
  pointer-events: none;
}

/* svh, not dvh. dvh is deliberately *dynamic*: on iOS it grows and
   shrinks as the address bar collapses, so every snap section silently
   changed height mid-gesture and the scroll offset stopped matching the
   stop it was supposed to land on — the corridor jumped and settled
   between works. svh is the stable toolbar-visible height. vh is the
   fallback; JS still measures the element rather than trusting either. */
.snap {
  height: 100vh;
  height: 100svh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

/* If museum.js never runs, the page must still be scrollable rather
   than a single frozen screen. */
.museum-scroll {
  min-height: 100vh;
}

/* Snapping lives on the scrolling element itself. Flat view turns it
   off via .no-snap — html cannot be selected from a body class. */
html {
  scroll-snap-type: y mandatory;
}

html.no-snap {
  scroll-snap-type: none;
}

/* ---------------------------------------------------------------
   Architecture: floor, ceiling, two walls
   --------------------------------------------------------------- */

.plane {
  transform-origin: 50% 50%;
  backface-visibility: hidden;
}

.floor,
.ceiling {
  width: var(--hall-w);
  height: var(--corridor-len);
  margin-left: calc(var(--hall-w) / -2);
  margin-top: calc(var(--corridor-len) / -2);
}

/* These planes are enormous — a wall layer is --corridor-len wide.
   Gradients and repeating patterns at that size are expensive to
   rasterize and were the main source of stutter, so the surfaces are
   flat colour. Depth comes from the fog overlay and the spot pools. */

.floor {
  background: #0a0a0c;
  transform: translateY(calc(var(--hall-h) / 2))
             translateZ(calc(var(--corridor-len) / -2))
             rotateX(90deg);
}

.ceiling {
  background: #060607;
  transform: translateY(calc(var(--hall-h) / -2))
             translateZ(calc(var(--corridor-len) / -2))
             rotateX(-90deg);
}

.wall {
  width: var(--corridor-len);
  height: var(--hall-h);
  margin-left: calc(var(--corridor-len) / -2);
  margin-top: calc(var(--hall-h) / -2);
  background: var(--wall);
}

.wall-left {
  transform: translateX(calc(var(--hall-w) / -2))
             translateZ(calc(var(--corridor-len) / -2))
             rotateY(90deg);
}

.wall-right {
  transform: translateX(calc(var(--hall-w) / 2))
             translateZ(calc(var(--corridor-len) / -2))
             rotateY(-90deg);
}

/* Far end cap so the corridor does not open into nothing */
.end-wall {
  width: var(--hall-w);
  height: var(--hall-h);
  margin-left: calc(var(--hall-w) / -2);
  margin-top: calc(var(--hall-h) / -2);
  background: #0e0e12;
  transform: translateZ(calc(var(--corridor-len) * -1));
}

/* ---------------------------------------------------------------
   Artwork bays
   --------------------------------------------------------------- */

/* Bays sit on the corridor axis and face the visitor square-on, so
   the work is met head-on with no looking around. */
.bay {
  width: 620px;
  height: var(--hall-h);
  margin-left: -310px;
  margin-top: calc(var(--hall-h) / -2);
  display: flex;
  align-items: center;
  justify-content: center;
}

.artwork {
  appearance: none;
  border: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  display: block;
  position: relative;
  transform: translateZ(2px);
  transition: filter 0.4s ease;
}

/* Shadow blur is kept modest on purpose: a 60px blur on a element
   that moves every frame is repainted every frame. */
/* inline-block is load-bearing: the frame is a <span>, and height and
   vertical padding do not apply to an inline box. It was wrapping a
   block-level <img>, which browsers split differently — WebKit left the
   frame collapsed so the canvas sat lower than --art-h predicted and
   ran into the plaque below it. */
.artwork-frame {
  display: inline-block;
  position: relative;
  height: var(--art-h);
  padding: 14px;
  background: #131317;
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 14px 28px rgba(0, 0, 0, 0.7);
}

.artwork-frame img {
  display: block;
  height: calc(var(--art-h) - 28px);
  width: auto;
  object-fit: cover;
}

/* Spot wash falling down the wall behind the canvas */
.bay-spot {
  position: absolute;
  left: 50%;
  top: 0;
  width: 560px;
  height: var(--hall-h);
  margin-left: -280px;
  pointer-events: none;
  background: radial-gradient(
    ellipse 46% 40% at 50% 34%,
    rgba(200, 169, 126, 0.16) 0%,
    rgba(200, 169, 126, 0.05) 45%,
    transparent 72%
  );
}

/* Wall label beside each piece */
.plaque {
  position: absolute;
  top: calc(50% + var(--art-h) / 2 + 26px);
  left: 50%;
  transform: translateX(-50%);
  width: 420px;
  text-align: center;
  font-family: var(--font-mono);
  pointer-events: none;
}

.plaque-cat {
  display: block;
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  color: var(--text-accent);
  margin-bottom: 0.45rem;
}

.plaque-title {
  display: block;
  font-family: var(--font-serif);
  font-size: 1.05rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--text-primary);
  margin: 0 0 0.5rem;
  line-height: 1.35;
}

.plaque-meta {
  display: block;
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  color: var(--text-muted);
  line-height: 1.7;
}

/* Light pool cast on the floor under each piece */
.floor-pool {
  width: 520px;
  height: 760px;
  margin-left: -260px;
  margin-top: -380px;
  pointer-events: none;
  background: radial-gradient(
    ellipse 50% 50% at 50% 50%,
    rgba(200, 169, 126, 0.1) 0%,
    transparent 70%
  );
}

/* ---------------------------------------------------------------
   Text panels (entrance hall, manifesto room)
   --------------------------------------------------------------- */

.panel {
  width: 760px;
  margin-left: -380px;
  margin-top: -240px;
  padding: 0 1rem;
  text-align: center;
  pointer-events: none;
}

.panel-eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.32em;
  color: var(--text-accent);
  margin-bottom: 1.4rem;
}

.panel h1 {
  font-family: var(--font-display);
  font-size: 3.6rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  line-height: 1.02;
  margin-bottom: 1.2rem;
}

.panel h2 {
  font-family: var(--font-display);
  font-size: 2.4rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  margin-bottom: 1rem;
}

.panel p {
  font-family: var(--font-mono);
  font-size: 0.9rem;
  font-weight: 300;
  color: var(--text-secondary);
  line-height: 1.9;
}

.panel-quote {
  font-family: var(--font-serif);
  font-size: 1.5rem;
  line-height: 1.6;
  color: var(--text-primary);
}

.panel-quote span {
  color: var(--text-accent);
  font-style: italic;
}

/* The three surfaces, met at one stop rather than strung along the
   side walls — side-wall copy would need a head turn to read. */
.panel-wide {
  width: 1000px;
  margin-left: -500px;
}

.pillar-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.4rem;
  text-align: left;
}

.pillar h3 {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  color: var(--text-accent);
  margin-bottom: 0.85rem;
}

.pillar p {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 0.9rem;
  line-height: 1.8;
  color: var(--text-secondary);
}

/* Invisible anchor used only to register a named zone position */
.zone-marker {
  width: 0;
  height: 0;
  pointer-events: none;
}

/* Doorway ring marking the threshold into the corridor */
.threshold {
  width: var(--hall-w);
  height: var(--hall-h);
  margin-left: calc(var(--hall-w) / -2);
  margin-top: calc(var(--hall-h) / -2);
  pointer-events: none;
  border: 1px solid rgba(200, 169, 126, 0.16);
  box-shadow: inset 0 0 120px rgba(0, 0, 0, 0.9);
}

/* ---------------------------------------------------------------
   Depth fog + vignette, painted over the stage
   --------------------------------------------------------------- */

.museum-fog {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  background:
    radial-gradient(ellipse 62% 62% at 50% 50%,
      transparent 0%,
      rgba(5, 5, 6, 0.28) 55%,
      rgba(5, 5, 6, 0.82) 100%);
}

/* ---------------------------------------------------------------
   HUD: progress rail and floor-plan marker
   --------------------------------------------------------------- */

.museum-hud {
  position: fixed;
  left: 2rem;
  bottom: 2rem;
  z-index: 60;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  color: var(--text-muted);
  pointer-events: none;
  user-select: none;
}

.hud-zone {
  color: var(--text-accent);
  margin-bottom: 0.55rem;
  display: block;
}

.hud-rail {
  position: relative;
  width: 190px;
  height: 1px;
  background: rgba(255, 255, 255, 0.14);
}

.hud-dot {
  position: absolute;
  top: -2.5px;
  left: 0;
  width: 6px;
  height: 6px;
  margin-left: -3px;
  border-radius: 50%;
  background: var(--text-accent);
  box-shadow: 0 0 10px rgba(200, 169, 126, 0.8);
}

.hud-tick {
  position: absolute;
  top: -2px;
  width: 1px;
  height: 5px;
  background: rgba(255, 255, 255, 0.28);
}

/* Scroll hint, fades out once the visitor starts walking */
.walk-hint {
  position: fixed;
  left: 50%;
  bottom: 2.4rem;
  transform: translateX(-50%);
  z-index: 60;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.28em;
  color: var(--text-muted);
  pointer-events: none;
  transition: opacity 0.6s ease;
}

.walk-hint.hidden {
  opacity: 0;
}

/* ---------------------------------------------------------------
   Zone 4 — registry desk
   The form leaves 3D entirely: a flat overlay above the stage.
   Keeping it inside preserve-3d breaks mobile keyboards, autofill
   and focus scrolling.
   --------------------------------------------------------------- */

/* The registry is the last section of the document, not an overlay.
   As a fixed panel it had no scroll of its own that the page would
   respect: dragging up inside it scrolled the page instead, walking
   the camera backwards and closing the panel. In normal flow it
   simply scrolls up over the corridor and owns its own space. */
.registry {
  position: relative;
  z-index: 40;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6rem 1.5rem 4rem;
  background: linear-gradient(180deg,
    rgba(5, 5, 6, 0.55) 0%,
    var(--bg-primary) 18%,
    var(--bg-primary) 100%);
}

.registry-inner {
  width: 100%;
  max-width: 860px;
  min-width: 0;
  /* Centres vertically when it fits, top-aligns when it does not. */
  margin: auto 0;
}

/* Nothing inside the registry may push the page sideways. */
.registry,
.registry-inner {
  overflow-x: hidden;
}

/* The last snap section sits under the registry; snapping is released
   there by museum.js so a tall form is not fought by the scroller. */

/* Honeypot. Kept out of view without display:none, which some bots
   detect and skip. */
.botcheck-field {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.inquiry-privacy {
  margin-top: 1.5rem;
  max-width: 52ch;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  line-height: 1.8;
  color: var(--text-muted);
}

/* ---------------------------------------------------------------
   Flat view — 3D off, classic vertical document.
   Driven by body.flat-view (toggle or reduced-motion).
   --------------------------------------------------------------- */

.view-toggle {
  background: transparent;
  border: 1px solid var(--border-light);
  color: var(--text-secondary);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  padding: 0.5rem 0.8rem;
  cursor: pointer;
  transition: var(--transition);
  white-space: nowrap;
}

.view-toggle:hover {
  border-color: var(--text-accent);
  color: var(--text-accent);
}

/* Flat view is not a fallback dump of the 3D markup — it is the
   editorial layout the site reads as without the walk: a full-bleed
   hero, alternating image/caption rows, then manifesto and registry. */

body.flat-view .museum-stage {
  position: relative;
  inset: auto;
  height: auto;
  overflow: visible;
  perspective: none;
  padding: 0;
  background: var(--bg-primary);
}

body.flat-view .museum-world {
  position: static;
  transform: none !important;
  transform-style: flat;
  width: auto;
  height: auto;
  display: block;
}

body.flat-view .museum-world > * {
  position: static;
  transform: none !important;
  transform-style: flat;
  margin: 0;
  width: auto;
  height: auto;
  opacity: 1 !important;
  visibility: visible !important;
}

/* Architecture, lighting and walk chrome mean nothing without depth */
body.flat-view .plane,
body.flat-view .end-wall,
body.flat-view .threshold,
body.flat-view .zone-marker,
body.flat-view .bay-spot,
body.flat-view .floor-pool,
body.flat-view .museum-fog,
body.flat-view .museum-hud,
body.flat-view .walk-hint,
body.flat-view .museum-scroll {
  display: none;
}

/* --- Hero --- */

body.flat-view #hero {
  min-height: calc(100vh - 70px);
  max-width: 1400px;
  margin: 0 auto;
  padding: 9rem 4rem 5rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: left;
  border-bottom: 1px solid var(--border-light);
}

body.flat-view #hero h1 {
  font-size: clamp(2.6rem, 8vw, 6rem);
  margin-bottom: 1.6rem;
}

body.flat-view #hero p {
  font-family: var(--font-serif);
  font-size: 1.15rem;
  color: var(--text-secondary);
  max-width: 40ch;
}

/* --- Works: alternating image / caption rows --- */

body.flat-view .bay {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4rem;
  align-items: center;
  max-width: 1400px;
  margin: 0 auto;
  padding: 6rem 4rem;
  border-bottom: 1px solid var(--border-light);
}

/* Bays are the only <article> siblings in the world, so nth-of-type
   alternates them reliably. */
body.flat-view .bay:nth-of-type(even) .artwork { order: 2; }

body.flat-view .artwork {
  filter: none !important;
  opacity: 1 !important;
  width: 100%;
  transform: none;
}

body.flat-view .artwork-frame {
  display: block;
  height: auto;
  padding: 12px;
}

body.flat-view .artwork-frame img {
  width: 100%;
  height: auto;
}

body.flat-view .plaque {
  position: static;
  transform: none;
  width: 100%;
  text-align: left;
  pointer-events: auto;
}

body.flat-view .plaque-title {
  font-size: 1.9rem;
  line-height: 1.2;
  margin-bottom: 1rem;
}

body.flat-view .plaque-cat {
  font-size: 0.72rem;
  margin-bottom: 1rem;
}

body.flat-view .plaque-meta {
  font-size: 0.76rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border-light);
  display: block;
}

/* --- Manifesto, pillars, rights --- */

body.flat-view .panel {
  max-width: 1400px;
  margin: 0 auto;
  padding: 6rem 4rem;
  text-align: left;
}

body.flat-view #manifesto {
  border-bottom: 1px solid var(--border-light);
}

body.flat-view .panel-quote {
  font-size: clamp(1.3rem, 3vw, 2.1rem);
  max-width: 26ch;
  line-height: 1.5;
}

body.flat-view .pillar-row {
  gap: 3rem;
}

body.flat-view .pillar {
  border-top: 1px solid var(--border-light);
  padding-top: 1.5rem;
}

/* Rights notice reads as a bordered legal box, like the old layout */
body.flat-view .panel:last-of-type {
  max-width: 1100px;
}

body.flat-view .panel:last-of-type p {
  border: 1px solid var(--border-light);
  padding: 2rem;
  font-size: 0.82rem;
  line-height: 1.9;
}

/* --- Registry --- */

body.flat-view .registry {
  position: static;
  min-height: 0;
  background: none;
  padding: 0 2rem 4rem;
  display: block;
  overflow: visible;
}

body.flat-view .registry-inner {
  max-width: 900px;
  margin: 0 auto;
}

/* ---------------------------------------------------------------
   Responsive — the walk stays 3D on phones, the hall just narrows
   so the walls do not swallow the frame.
   --------------------------------------------------------------- */

@media (max-width: 1024px) {
  :root {
    --hall-w: 780px;
    --hall-h: 640px;
    --art-h: 340px;
  }

  .panel h1 { font-size: 2.6rem; }
  .panel h2 { font-size: 1.9rem; }

  .panel-wide {
    width: 860px;
    margin-left: -430px;
  }

  .pillar-row { gap: 1.7rem; }
  .pillar p { font-size: 0.84rem; }

  /* Flat view: rows stack before the gutters get cramped.
     Declared here, ahead of the 768px block, so the narrower rules
     below win rather than being overridden by source order. */
  body.flat-view .bay {
    grid-template-columns: 1fr;
    gap: 2.5rem;
    padding: 4rem 2.5rem;
  }

  body.flat-view .bay:nth-of-type(even) .artwork { order: 0; }

  body.flat-view #hero { padding: 8rem 2.5rem 4rem; }
  body.flat-view .panel { padding: 4rem 2.5rem; }
  body.flat-view .pillar-row { grid-template-columns: 1fr; }
}

@media (max-width: 768px) {
  /* Hall narrows and the frame shrinks, but the corridor keeps its
     length so the authored z positions stay valid. */
  :root {
    --hall-w: 560px;
    --hall-h: 520px;
    --art-h: 250px;
  }

  .museum-stage { perspective: 700px; }

  .panel {
    width: 340px;
    margin-left: -170px;
  }

  .panel h1 { font-size: 1.9rem; }
  .panel h2 { font-size: 1.4rem; }
  .panel p { font-size: 0.78rem; line-height: 1.75; }
  .panel-quote { font-size: 1.05rem; }

  .panel-wide {
    width: 340px;
    margin-left: -170px;
  }

  /* Three columns will not fit a phone; stack them. */
  .pillar-row {
    grid-template-columns: 1fr;
    gap: 1.4rem;
  }

  .pillar p { font-size: 0.78rem; line-height: 1.7; }

  .bay {
    width: 340px;
    margin-left: -170px;
  }

  .bay-spot {
    width: 340px;
    margin-left: -170px;
  }

  .plaque {
    width: 300px;
    top: calc(50% + var(--art-h) / 2 + 18px);
  }

  .plaque-title { font-size: 0.86rem; }
  .plaque-meta { font-size: 0.58rem; }

  .museum-hud {
    left: 1.2rem;
    bottom: 1.2rem;
  }

  .hud-rail { width: 130px; }

  .walk-hint { font-size: 0.58rem; letter-spacing: 0.2em; }

  /* Flat view on a phone: one column, tighter gutters. */
  body.flat-view #hero {
    padding: 7rem 1.5rem 3rem;
    min-height: auto;
  }

  body.flat-view .bay {
    grid-template-columns: 1fr;
    gap: 2rem;
    padding: 3.5rem 1.5rem;
  }

  /* Image always above its caption once stacked */
  body.flat-view .bay:nth-of-type(even) .artwork { order: 0; }

  body.flat-view .plaque-title { font-size: 1.3rem; }

  body.flat-view .panel {
    padding: 3.5rem 1.5rem;
  }

  body.flat-view .pillar-row { gap: 2rem; }

  body.flat-view .panel:last-of-type p { padding: 1.25rem; }

  body.flat-view .registry { padding: 0 1.5rem; }

  /* Walk-mode registry on a phone: less chrome, more form. */
  .registry { padding: 4.5rem 1rem 2rem; }

  .registry .inquiry-wrapper { padding: 1.75rem 1.25rem; }

  .registry .inquiry-form-grid {
    grid-template-columns: 1fr;
    gap: 1.25rem;
    margin-top: 1.75rem;
  }

  .registry .inquiry-input,
  .registry .inquiry-select,
  .registry .inquiry-textarea {
    padding: 0.8rem 0.9rem;
    /* 16px stops iOS Safari zooming in on focus, which was throwing
       the fixed panel off-centre. */
    font-size: 16px;
  }

  .registry .inquiry-textarea { min-height: 110px; }

  .registry #submit-inquiry-btn {
    width: 100%;
    justify-content: center;
    padding: 0.9rem 1rem !important;
  }

  .inquiry-privacy { font-size: 0.62rem; margin-top: 1rem; }
}

/* ---------------------------------------------------------------
   Reduced motion — a moving first-person camera is exactly the
   thing this setting exists to switch off.
   --------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .museum-world {
    transition: none !important;
  }
}
