/* Dead Filth v2. Shared chrome, scene furniture, components.
   Nothing is rounded. Shadows are pure black. No glow. */

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

/* A display value in our own CSS outranks the UA rule for [hidden], which
   would leave the registry form on screen after it has been submitted. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  background: var(--ink);
  color: var(--cream);
  overflow-x: hidden;
}
body {
  font-family: var(--font-ui);
  font-size: var(--size-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  color: var(--cream);
  margin: 0;
  text-wrap: pretty;
}
h1 { font-size: var(--size-display-2); }
.display-1 { font-size: var(--size-display-1); }

p { margin: 0; }
.lede {
  font-size: var(--size-body);
  line-height: var(--lh-body);
  color: var(--grey-2);
  max-width: 46ch;
  margin-top: var(--space-4);
}

.kicker {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: var(--size-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-label);
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 60;
  background: var(--cream); color: var(--ink);
  padding: 12px 18px;
  font-size: var(--size-label); letter-spacing: var(--ls-nav); text-transform: uppercase;
}
.skip-link:focus { left: 0; }

/* ---------- nav ---------- */

.site-nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: 14px var(--gutter);
  background: linear-gradient(180deg, rgba(10,8,6,0.92) 0%, rgba(10,8,6,0) 100%);
}
.site-nav a {
  font-family: var(--font-ui); font-weight: 500;
  font-size: var(--size-label); letter-spacing: var(--ls-nav);
  text-transform: uppercase; color: var(--text-label); text-decoration: none;
  padding: 12px 10px; min-height: var(--tap-min);
  display: inline-flex; align-items: center;
  transition: color var(--dur-hover) var(--ease-heavy);
}
.site-nav a:hover { color: var(--accent); }
.site-nav a:focus-visible { outline: 1px solid var(--focus-ring); outline-offset: 2px; color: var(--cream); }
.site-nav a[aria-current="page"] { color: var(--cream); }
/* The brand is the label's own wordmark now, so the nav carries no separate
   mark and no typeset name beside it. Height drives the size; the file is
   4.3:1 so the width follows. */
.site-nav .brand { display: flex; align-items: center; padding: 6px 0; }
.site-nav .brand img { height: 28px; width: auto; display: block; }
@media (max-width: 480px) { .site-nav .brand img { height: 24px; } }
.site-nav ul { display: flex; gap: var(--space-1); list-style: none; margin: 0; padding: 0; }

/* At 390px the wordmark and three links do not both fit at full tracking,
   and the brand is the thing that buckles. Tighten the links, not the name. */
@media (max-width: 480px) {
  .site-nav { padding: 14px 14px; }
  .site-nav a { letter-spacing: 0.14em; padding: 12px 6px; }
  .site-nav ul { gap: 0; }
}
/* Below the 390px target the wordmark and three links cannot both fit. */
@media (max-width: 359px) {
  .site-nav .brand img { height: 20px; }
  .site-nav { padding: 14px 10px; }
}

/* ---------- footer ---------- */

.site-footer {
  position: relative; z-index: 2;
  background: var(--ink); color: var(--cream);
  border-top: var(--border-hair);
  padding: var(--space-5) var(--gutter);
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-3);
  font-size: var(--size-label); letter-spacing: 0.22em; text-transform: uppercase;
}
.site-footer span { opacity: 0.78; }
.site-footer a { color: var(--cream); text-decoration: none; opacity: 0.78; }
.site-footer a:hover { color: var(--accent); opacity: 1; }
.site-footer a:focus-visible { outline: 1px solid var(--focus-ring); outline-offset: 2px; }

/* ---------- scene furniture ---------- */

.scene { position: relative; min-height: 100vh; overflow: hidden; background: var(--night); }
.scene-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* A backdrop that holds still while the column scrolls over it.
   It lives OUTSIDE <main> on purpose: main carries the page transition
   transform, and a transformed ancestor makes position:fixed anchor to that
   element instead of the viewport, which stretches the scene over the whole
   document. Keep these layers a sibling of main, never a child. */
.backdrop { position: fixed; inset: 0; z-index: 0; overflow: hidden; background: var(--night); }
.backdrop > * { position: absolute; inset: 0; }
.backdrop img { width: 100%; height: 100%; object-fit: cover; }
.over-backdrop { position: relative; z-index: 1; min-height: 100vh; }

.scrim, .vignette, .grain { position: absolute; inset: 0; }
.vignette { background: var(--vignette); pointer-events: none; }
.grain {
  background-image: var(--grain-url);
  opacity: var(--grain-opacity);
  mix-blend-mode: overlay;
  pointer-events: none;
}

.scene-copy { position: relative; z-index: 2; }

/* ---------- buttons ---------- */

.cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: var(--tap-min); padding: 14px 26px;
  border: none; border-radius: var(--radius); cursor: pointer; text-decoration: none;
  font-family: var(--font-ui); font-weight: 500; font-size: var(--size-body-sm);
  letter-spacing: var(--ls-price); text-transform: uppercase;
  transition: background var(--dur-hover) var(--ease-heavy), color var(--dur-hover) var(--ease-heavy);
}
.cta .dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--navy);
  transition: background var(--dur-hover) var(--ease-heavy);
}
.cta.plate { background: var(--bg-plate); color: var(--text-on-plate); box-shadow: var(--shadow-plate); }
.cta.plate:hover { background: var(--navy); color: var(--cream); }
.cta.plate:hover .dot { background: var(--cream); }
.cta.quiet { background: transparent; color: var(--text-body); border: 1px solid var(--line-strong); }
.cta.quiet .dot { background: var(--lavender-2); }
.cta.quiet:hover { background: var(--navy-deep); border-color: var(--lavender-2); color: var(--cream); }
.cta:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }

/* ---------- altar hotspots ---------- */

.hotspot {
  position: absolute; z-index: 8; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 160px; min-height: var(--tap-min); padding: 12px 14px;
  text-decoration: none; border: 1px solid transparent; background: transparent;
  transition: background var(--dur-hover) var(--ease-heavy), border-color var(--dur-hover) var(--ease-heavy);
}
.hotspot span {
  font-family: var(--font-ui); font-weight: 500; font-size: var(--size-label);
  letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--text-label);
  transition: color var(--dur-hover) var(--ease-heavy);
}
.hotspot::after {
  content: ""; width: 100%; height: 1px; background: var(--lavender-2);
  opacity: 0.35; margin-top: 8px;
  transition: opacity var(--dur-hover) var(--ease-heavy);
}
.hotspot:hover { background: rgba(6,16,42,0.55); border-color: var(--lavender-2); }
.hotspot:hover span { color: var(--cream); }
.hotspot:hover::after { opacity: 1; }
.hotspot:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; background: rgba(6,16,42,0.75); }
.hotspot:focus-visible span { color: var(--cream); }

/* ---------- catacombs: the frames ---------- */

.shelf {
  list-style: none; padding: 0; margin: var(--space-8) 0 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--space-7) 44px;
}
.shelf > li { display: flex; flex-direction: column; align-items: center; }
.frame-wrap { perspective: var(--perspective); width: 100%; max-width: 520px; }

/* The frames alternate which way they lean. The lean is held in a custom
   property rather than a transform on the nth-child selector, because that
   selector would outrank .frame:hover and the lift would never play. */
.frame {
  --lean: rotateY(6deg) translateZ(-10px);
  display: block; position: relative; aspect-ratio: 1 / 1;
  transform: var(--lean);
  transform-style: preserve-3d;
  transition: transform var(--dur-frame) var(--ease-heavy);
  outline: none;
}
.shelf > li:nth-child(even) .frame { --lean: rotateY(-6deg) translateZ(-10px); }
.frame:hover, .frame:focus-visible {
  transform: translateZ(60px) rotateY(0deg) scale(1.04);
  z-index: 5;
}
.frame:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 6px; }

/* the paper backing, inside the frame's window */
.frame .paper, .frame .paper-shade, .frame .candle {
  position: absolute; left: 24.5%; top: 27.5%; width: 51%;
}
.frame .paper, .frame .paper-shade { height: 50%; }
.frame .paper {
  background: var(--ink) url("../assets/paper-texture.webp") center / cover;
  /* Four of the eight garments are black. At 0.55 the paper was darker than
     they are and they disappeared into it. This lifts the wall behind the
     cloth without lighting the room. */
  filter: saturate(0.6) brightness(0.78);
  box-shadow: inset 0 0 0 1px rgba(10,8,6,0.9), inset 0 0 40px rgba(0,0,0,0.85);
}
.frame .paper-shade {
  background: radial-gradient(ellipse at 50% 60%, rgba(0,0,0,0) 40%, rgba(0,0,0,0.55) 100%);
}
/* dark at the crown, lit from below */
.frame .candle {
  height: 28%; pointer-events: none;
  background: linear-gradient(180deg, rgba(10,8,6,0.5) 0%, rgba(10,8,6,0) 100%);
  mix-blend-mode: multiply;
}
.frame .moulding {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 24px 40px rgba(0,0,0,0.85)) brightness(0.9);
}
.frame .garment {
  position: absolute; left: 26.5%; width: 47%; top: 52.5%;
  transform: translateY(-50%);
  filter: drop-shadow(0 14px 18px rgba(0,0,0,0.8)) saturate(0.95) contrast(1.06) brightness(1.06);
}
.frame .garment.back {
  opacity: 0;
  transition: opacity var(--dur-frame) var(--ease-heavy);
}
.frame:hover .garment.back, .frame:focus-visible .garment.back,
.frame.flipped .garment.back { opacity: 1; }
/* A phone has no hover, so a tap turns the piece around instead. */
.frame.flipped { transform: translateZ(60px) rotateY(0deg) scale(1.04); z-index: 5; }

.on-touch { display: none; }
@media (hover: none) {
  .on-hover { display: none; }
  .on-touch { display: inline; }
}

.plaque {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  margin-top: var(--space-5); text-align: center;
}
.plaque h2 { font-size: var(--size-display-3); }
.plaque .price {
  font-size: var(--size-price); font-weight: 500;
  letter-spacing: var(--ls-price); text-transform: uppercase; color: var(--lavender-2);
}
.plaque .status { font-size: var(--size-body-sm); color: var(--grey-1); }

/* ---------- registry: the poster ---------- */

.poster {
  position: relative; width: 100%; max-width: 560px;
  padding: 44px 30px 40px;
  color: #241910;
  transform: rotate(-1.5deg);
  transition: transform var(--dur-frame) var(--ease-heavy);
  background:
    radial-gradient(ellipse at 12% 10%, rgba(60,40,20,0.30) 0%, transparent 22%),
    radial-gradient(ellipse at 90% 92%, rgba(50,30,18,0.34) 0%, transparent 26%),
    url("../assets/paper-texture.webp"),
    linear-gradient(175deg, #eee5bc 0%, #e2d7a6 55%, #c9bc83 100%);
  background-size: auto, auto, cover, auto;
  background-blend-mode: multiply, multiply, normal, normal;
  filter: drop-shadow(0 24px 38px rgba(20,10,3,0.85));
}
.poster:hover { transform: rotate(0deg) translateY(-10px); }
.poster .stamp {
  position: absolute; top: 18px; right: 20px; width: 84px; height: 84px;
  border: 2px solid var(--navy); border-radius: 50%;
  display: flex; align-items: center; justify-content: center; text-align: center;
  transform: rotate(-12deg); color: var(--navy);
  font-family: var(--font-ui); font-weight: 500; font-size: 9px;
  letter-spacing: var(--ls-nav); text-transform: uppercase; line-height: 1.35; opacity: 0.75;
}
.poster .poster-kicker {
  font-size: var(--size-label); letter-spacing: var(--ls-label); text-transform: uppercase;
  color: var(--navy); margin: 0 0 14px; max-width: calc(100% - 100px);
}
.poster h2 { font-size: var(--size-display-2); color: var(--ink); margin: 0 0 16px; }
.poster .rule {
  height: 2px; width: 82%; opacity: 0.75; margin-bottom: 20px;
  background: linear-gradient(90deg, var(--ink) 0%, var(--ink) 72%, transparent 100%);
}
.poster p { font-size: var(--size-body-sm); line-height: var(--lh-body); color: #241910; }

.registry-form { display: flex; flex-direction: column; gap: var(--space-5); margin-top: var(--space-5); }
.field label {
  display: block; font-size: var(--size-label); letter-spacing: var(--ls-label);
  text-transform: uppercase; color: var(--navy); margin-bottom: 8px;
}
.field input {
  width: 100%; min-height: var(--tap-min);
  background: transparent; border: none; border-bottom: 1.5px solid var(--line-on-plate);
  padding: 8px 2px; font-family: var(--font-ui); font-size: 16px; color: var(--ink);
  outline: none; transition: border-color var(--dur-fast) var(--ease-heavy);
}
.field input::placeholder { color: rgba(10,8,6,0.35); }
.field input:focus { border-bottom-color: var(--navy); }
.field input:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 4px; }

.recorded { font-family: var(--font-display); font-size: var(--size-display-3); line-height: var(--lh-display); color: var(--ink); margin-top: var(--space-5); }
.recorded + p { color: var(--grey-3); margin-top: var(--space-3); }

/* ---------- scene motion ---------- */

/* the night slowly pushes in on the building */
@keyframes df-push {
  from { transform: scale(1); }
  to   { transform: scale(1.06); }
}
/* the Reaper settles into the room */
@keyframes df-settle {
  from { transform: translateY(-4%) scale(1.1); }
  to   { transform: translateY(0) scale(1); }
}

/* Everything below is hidden only when JavaScript is running to reveal it.
   With JS off the page renders complete and still. */
.js [data-night] { opacity: 0; }
.js [data-night].on { opacity: 1; }
.js [data-copy-in] { opacity: 0; }
.js [data-copy-in].on { opacity: 1; }
.js [data-shelf] > li { opacity: 0; }
.js [data-shelf] > li.on { opacity: 1; }

[data-night] { transition: opacity 4s var(--ease-heavy); }
[data-copy-in] { transition: opacity var(--dur-reveal) var(--ease-heavy); }
[data-shelf] > li { transition: opacity var(--dur-reveal) var(--ease-heavy); }

/* ---------- page transitions ---------- */

main {
  position: relative; z-index: 1;
  background: transparent; min-height: 100vh;
  transform-origin: center 45%;
  transition: transform var(--dur-reveal) var(--ease-heavy), opacity var(--dur-reveal) var(--ease-heavy);
}
/* JS marks the document so a no-script visitor never gets a hidden page */
.js main { transform: scale(1.04); opacity: 0; }
.js main.entered { transform: scale(1); opacity: 1; }
.js main.leaving  { transform: scale(1.12); opacity: 0; }

/* the Reaper descent, only leaving the door */
.descent {
  position: fixed; inset: 0; z-index: 30; pointer-events: none; overflow: hidden;
  background: var(--ink); opacity: 0;
  transition: opacity var(--dur-reveal) var(--ease-heavy);
}
.descent.on { opacity: 1; }
.descent img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 0%;
  transform-origin: 50% 0%; transform: translateY(0) scale(1);
  transition: transform 3s var(--ease-heavy);
  filter: saturate(0.7) contrast(1.05) brightness(0.5);
}
.descent.on img { transform: translateY(18%) scale(1.08); }
.descent .close {
  position: absolute; inset: 0; background: var(--ink); opacity: 0;
  transition: opacity 0.8s var(--ease-heavy);
}
.descent.sealed .close { opacity: 1; }
