/* =========================================================
   URFRNDSCLUBHOUSE: PHOTO VERSION, shared styles
   Every page is one big photo with invisible "tap zones" on top.

   Layers, from back to front:
     .backdrop  a blurred copy of the photo (fills any empty space)
     .sky       (Door only) live canvas sky, drawn by js/sky.js
     .stage     the sharp photo + glows + tap zones (sized by js/scene.js)
     .fx        canvas: twinkling stars + disco-ball light specks
     .haze      drifting smoke
     .grain     film grain + vignette
     .hud       small buttons (Map) and page text
   ========================================================= */

/* ---------- Colors (change the whole palette here) ---------- */
:root {
  --gold: #ffcf70;
  --gold-hot: #ffae3d;
  --purple: #b56cff;
  --blue: #5cb0ff;
  --ink: #050308;
  --paper: #f3e7cf;
  --col-w: 430px;          /* widest phone we design for */
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; background: #000; overflow: hidden; }
body {
  display: flex;
  justify-content: center;
  color: #f4ecff;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* ---------- The phone-width column ----------
   This site is made for phones. On a big screen we just show a
   phone-sized column in the middle. */
.scene {
  position: relative;
  width: 100%;
  max-width: var(--col-w);
  height: 100vh;
  height: 100dvh;            /* "dynamic" height: ignores the phone's address bar */
  overflow: hidden;
  background: var(--ink);
  isolation: isolate;
}
@media (min-width: 600px) {
  body { background: radial-gradient(ellipse at center, #150b24 0%, #000 70%); }
  .scene { box-shadow: 0 0 0 1px rgba(181, 108, 255, .18), 0 0 90px rgba(120, 60, 200, .28); }
}

/* ---------- The photo ---------- */
.backdrop {
  position: absolute;
  inset: -60px;
  background-size: cover;
  background-position: center;
  filter: blur(30px) brightness(.34) saturate(1.2);
}
.backdrop::after {   /* darken the top and bottom so the photo stays the star */
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(5, 3, 8, .6), rgba(5, 3, 8, 0) 32%, rgba(5, 3, 8, 0) 68%, rgba(5, 3, 8, .65));
}
.stage { position: absolute; left: 0; top: 0; container-type: inline-size; }  /* js/scene.js sets size + position */
.kb {                                                 /* "Ken Burns": a very slow zoom */
  position: absolute;
  inset: 0;
  transform-origin: var(--fx, 50%) var(--fy, 50%);
  animation: kenburns 40s ease-in-out infinite alternate;
}
@keyframes kenburns { from { transform: scale(1); } to { transform: scale(1.045); } }
.photo {
  display: block;
  width: 100%;
  height: 100%;
  user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}
/* When the photo doesn't fill the screen, fade its edges into the blurred backdrop */
.stage.fade-y .photo { -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 9%, #000 91%, transparent 100%);
                              mask-image: linear-gradient(to bottom, transparent 0, #000 9%, #000 91%, transparent 100%); }
.stage.fade-x .photo { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%);
                              mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%); }

/* ---------- The Door: live sky behind a see-through photo ---------- */
.sky { position: absolute; inset: 0; display: block; }
canvas.sky[data-rect] { inset: auto; z-index: 1; }
.scene[data-layout="bottom"] { background: #030210; }
.scene[data-layout="bottom"] .kb { transform-origin: 50% 100%; }   /* zoom upward, the ground stays put */
.scene[data-layout="bottom"] .haze {                                  /* haze = low ground mist only, keeps the sky crisp */
  -webkit-mask-image: linear-gradient(to bottom, transparent 40%, #000 80%);
          mask-image: linear-gradient(to bottom, transparent 40%, #000 80%);
}

/* Anything with data-rect="x,y,w,h" (percent of the photo) is placed by js/scene.js */
[data-rect] { position: absolute; }

/* ---------- Neon glow overlays ----------
   A glow is a brightened copy of the SAME photo, cut to the sign's
   rectangle and blended with "screen". Only bright pixels (the neon
   tubes) get brighter, so it looks like the real sign is glowing. */
.glow {
  mix-blend-mode: screen;
  pointer-events: none;
  opacity: .8;
  /* soft edges, so you never see the rectangle */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent),
                      linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent),
              linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
  mask-composite: intersect;
}
.glow::before, .glow::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--bg);
  background-size: var(--bs);
  background-position: var(--bp);
  background-repeat: no-repeat;
}
.glow::before { filter: brightness(1.35) saturate(1.35) contrast(1.15); }
.glow::after  { filter: blur(7px) brightness(1.9) saturate(1.6); opacity: .7; }
.glow.flicker { animation: flicker 7s infinite; }
.glow.flicker.slow { animation-duration: 11s; animation-delay: -3s; }
.glow.breathe { animation: breathe 5s ease-in-out infinite; }
.glow.blink   { animation: blink 2.4s steps(1) infinite; }
@keyframes flicker {
  0%, 38%, 47%, 69%, 73%, 100% { opacity: .85; }
  40% { opacity: .15; } 41% { opacity: .8; } 43% { opacity: .2; } 45% { opacity: .9; }
  71% { opacity: .45; }
}
/* Main Floor signs and the Door sign: one soft dip, then a long rest. */
@keyframes flicker-soft {
  0%, 74%, 100% { opacity: .82; }
  86% { opacity: .48; }
}
.scene[data-name="main-floor"] .glow.flicker,
.scene[data-name="door"] .glow.flicker {
  animation-name: flicker-soft;
  animation-timing-function: ease-in-out;
}
.scene[data-name="door"] .glow.flicker { animation-duration: 18s; }
.scene[data-name="main-floor"] .welcome.neon-text {
  animation: text-flicker-soft 20s ease-in-out infinite;
}
@keyframes text-flicker-soft {
  0%, 76%, 100% { opacity: 1; }
  86% { opacity: .75; }
}
@keyframes breathe { 0%, 100% { opacity: .35; } 50% { opacity: .85; } }
@keyframes blink { 0%, 100% { opacity: .9; } 50% { opacity: .25; } }

/* ---------- Neon text we add with HTML (for signs the photo doesn't have) ---------- */
.neon-text {
  font-family: "Tilt Neon", system-ui, sans-serif;
  color: #fff6e4;
  text-shadow: 0 0 2px #fff, 0 0 6px var(--gold), 0 0 14px var(--gold-hot), 0 0 28px var(--gold-hot);
  letter-spacing: .04em;
  white-space: nowrap;
  animation: text-flicker 9s infinite;
}
.neon-text.purple { color: #f5eaff; text-shadow: 0 0 2px #fff, 0 0 6px var(--purple), 0 0 14px var(--purple), 0 0 30px #7d2cff; }
.neon-text.blue   { color: #eef7ff; text-shadow: 0 0 2px #fff, 0 0 6px var(--blue), 0 0 14px var(--blue), 0 0 30px #2a6dff; }
.neon-text.pink   { color: #fff0f6; text-shadow: 0 0 2px #fff, 0 0 6px #ff5fa8, 0 0 14px #ff3d8e, 0 0 30px #ff2277; }
.neon-text.red    { color: #fff2f2; text-shadow: 0 0 2px #fff, 0 0 6px #ff5a5a, 0 0 14px #ff2222, 0 0 28px #c40000; }
/* Words sitting on the blank neon boards in the photos (Main Floor).
   --fs is the size, in percent of the photo's width. */
.board {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  pointer-events: none;
  z-index: 1;
  font-size: calc(var(--fs, 2.2) * 1cqw);
  line-height: 1.02;
  letter-spacing: .04em;
  white-space: nowrap;
}
.board.wrap { white-space: normal; line-height: 1.05; }

@keyframes text-flicker {
  0%, 60%, 64%, 100% { opacity: 1; }
  61% { opacity: .35; } 62% { opacity: 1; } 63% { opacity: .5; }
}

/* ---------- Tap zones ----------
   Invisible buttons over the things in the photo. When tapped they
   light up with a neon outline, then we go to the next page. */
.zone {
  display: block;
  border-radius: 14px;
  outline: none;
  cursor: pointer;
  z-index: 2;
}
.zone.round { border-radius: 50%; }
.zone::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  opacity: 0;
  transition: opacity .18s ease-out;
  border: 1.5px solid rgba(255, 222, 150, .95);
  box-shadow: 0 0 10px 2px rgba(255, 190, 90, .75), 0 0 28px 6px rgba(255, 160, 60, .35),
              inset 0 0 18px rgba(255, 200, 110, .45);
  background: rgba(255, 205, 130, .07);
}
.zone.purple::after {
  border-color: rgba(230, 200, 255, .95);
  box-shadow: 0 0 10px 2px rgba(181, 108, 255, .8), 0 0 28px 6px rgba(140, 70, 255, .4),
              inset 0 0 18px rgba(190, 130, 255, .45);
  background: rgba(181, 108, 255, .08);
}
.zone.lit::after, .zone:focus-visible::after { opacity: 1; }
/* No lit rectangle on a tap, focus, or hover. The zones still receive the tap. */
.zone::after,
.zone.lit::after,
.zone:focus-visible::after,
.zone:hover::after,
.scene.hinting .zone::after,
.scene.show-zones .zone::after {
  opacity: 0 !important;
  animation: none !important;
  box-shadow: none !important;
  background: none !important;
  border-color: transparent !important;
}
/* Main Floor: a tap must not flash a box. The zones stay invisible. */
.scene[data-name="main-floor"] .zone::after,
.scene[data-name="main-floor"] .zone.lit::after,
.scene[data-name="main-floor"] .zone:focus-visible::after,
.scene[data-name="main-floor"].hinting .zone::after {
  opacity: 0 !important;
  animation: none !important;
  box-shadow: none !important;
  background: none !important;
  border-color: transparent !important;
}
/* The one-time hint: every zone softly pulses twice */
.scene.hinting .zone::after { animation: hint-pulse 1.7s ease-in-out 2; }
@keyframes hint-pulse { 0%, 100% { opacity: 0; } 50% { opacity: .6; } }

/* ---------- Moving overlays ---------- */
.fx, .haze, .grain, .vignette { position: absolute; inset: 0; pointer-events: none; }
.fx { z-index: 3; mix-blend-mode: screen; }
.haze {
  z-index: 3;
  background-image: url("../assets/fx/haze.webp"), url("../assets/fx/haze.webp");
  background-size: 620px 620px, 900px 900px;
  mix-blend-mode: screen;
  opacity: var(--haze, .12);
  animation: drift 70s linear infinite;
}
@keyframes drift {
  from { background-position: 0 0, 0 0; }
  to   { background-position: 620px -120px, -900px 60px; }
}
.vignette { z-index: 4; background: radial-gradient(ellipse 85% 70% at 50% 50%, transparent 55%, rgba(0, 0, 0, .55) 100%); }
.grain {
  z-index: 4;
  inset: -100px;
  background: url("../assets/fx/grain.png");
  opacity: .07;
  mix-blend-mode: overlay;
  animation: grain .9s steps(5) infinite;
}
@keyframes grain {
  0% { transform: translate(0, 0); }       20% { transform: translate(-40px, 25px); }
  40% { transform: translate(30px, -50px); } 60% { transform: translate(-20px, 60px); }
  80% { transform: translate(55px, 10px); }
}

/* ---------- HUD: small controls on top ---------- */
.hud {
  position: absolute;
  z-index: 10;
  left: 0; right: 0; top: 0;
  display: flex;
  justify-content: flex-end;        /* the Map button sits on the right */
  align-items: center;
  padding: calc(var(--safe-top, env(safe-area-inset-top)) + 10px) 12px 0;
  pointer-events: none;
}
.hud > * { pointer-events: auto; }
.scene[data-name="door"] .hud { justify-content: space-between; }
a.pill.staff-door {
  font-size: 10px;
  letter-spacing: .02em;
  text-transform: none;
  padding: 6px 8px;
  margin-right: auto;
}
.pill {
  font: 600 12px/1 system-ui, sans-serif;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--gold);
  text-decoration: none;
  background: rgba(8, 4, 14, .55);
  border: 1px solid rgba(255, 207, 112, .35);
  border-radius: 999px;
  padding: 9px 13px;
  min-height: 34px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.pill:active { background: rgba(255, 207, 112, .15); }
.pill:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* Big neon button (Enter, Sign in) */
.neon-btn {
  font: 400 22px/1 "Tilt Neon", system-ui, sans-serif;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #fff7e6;
  background: rgba(10, 5, 16, .55);
  border: 2px solid var(--gold);
  border-radius: 14px;
  padding: 15px 34px;
  text-decoration: none;
  cursor: pointer;
  text-shadow: 0 0 6px var(--gold), 0 0 16px var(--gold-hot);
  box-shadow: 0 0 10px rgba(255, 190, 90, .55), inset 0 0 12px rgba(255, 190, 90, .35);
  animation: btn-glow 3.2s ease-in-out infinite;
}
.neon-btn:active { transform: scale(.97); background: rgba(255, 190, 90, .15); }
.neon-btn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
@keyframes btn-glow {
  0%, 100% { box-shadow: 0 0 10px rgba(255, 190, 90, .5), inset 0 0 12px rgba(255, 190, 90, .3); }
  50%      { box-shadow: 0 0 22px rgba(255, 190, 90, .8), inset 0 0 16px rgba(255, 190, 90, .45); }
}

/* Bottom area for page buttons */
.bottom {
  position: absolute;
  z-index: 10;
  left: 0; right: 0; bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 0 16px calc(var(--safe-bottom, env(safe-area-inset-bottom)) + 22px);
  pointer-events: none;
}
.bottom > * { pointer-events: auto; }
.text-link {
  color: #e9dcff;
  font-size: 14px;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(233, 220, 255, .4);
  background: none;
  border: 0;
  padding: 8px;
  cursor: pointer;
  text-shadow: 0 1px 6px #000;
}

/* One-time hint caption */
.hint {
  position: absolute;
  z-index: 11;
  left: 50%;
  top: calc(var(--safe-top, env(safe-area-inset-top)) + 58px);
  transform: translateX(-50%);
  font-size: 13px;
  letter-spacing: .04em;
  color: #fff4dc;
  background: rgba(8, 4, 14, .7);
  border: 1px solid rgba(255, 207, 112, .3);
  border-radius: 999px;
  padding: 8px 14px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .5s;
}
.hint.show { opacity: 1; }

/* Little message that pops up at the bottom */
.toast {
  position: absolute;
  z-index: 12;
  left: 50%;
  bottom: calc(var(--safe-bottom, env(safe-area-inset-bottom)) + 96px);
  transform: translate(-50%, 16px);
  width: max-content;
  max-width: calc(100% - 32px);
  font-size: 14px;
  line-height: 1.4;
  text-align: center;
  color: #f7efff;
  background: rgba(12, 6, 20, .88);
  border: 1px solid rgba(181, 108, 255, .5);
  box-shadow: 0 0 18px rgba(181, 108, 255, .35);
  border-radius: 14px;
  padding: 11px 16px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s, transform .25s;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast .eq { display: inline-flex; gap: 2px; align-items: flex-end; height: 12px; margin-right: 8px; vertical-align: -1px; }
.toast .eq i { width: 3px; background: var(--purple); animation: eq .8s ease-in-out infinite alternate; }
.toast .eq i:nth-child(2) { animation-delay: -.3s; } .toast .eq i:nth-child(3) { animation-delay: -.55s; }
@keyframes eq { from { height: 3px; } to { height: 12px; } }
.toast small { display: block; color: #bda9dd; font-size: 12px; margin-top: 2px; }

/* ---------- Pop-up sheets (Map, name tag, guestbook form) ---------- */
dialog.sheet {
  margin: auto auto 0;
  width: 100%;
  max-width: var(--col-w);
  max-height: 85dvh;
  border: 0;
  border-radius: 20px 20px 0 0;
  padding: 20px 20px calc(var(--safe-bottom, env(safe-area-inset-bottom)) + 20px);
  color: #f4ecff;
  background: linear-gradient(#150c22, #0a0612);
  box-shadow: 0 -1px 0 rgba(255, 207, 112, .35), 0 -10px 40px rgba(0, 0, 0, .7);
}
dialog.sheet::backdrop { background: rgba(0, 0, 0, .55); }
dialog.sheet[open] { animation: sheet-up .28s ease-out; }
@keyframes sheet-up { from { transform: translateY(40px); opacity: 0; } to { transform: none; opacity: 1; } }
.sheet h2 { font: 400 22px/1.2 "Tilt Neon", system-ui, sans-serif; color: var(--gold); text-shadow: 0 0 10px rgba(255, 174, 61, .6); margin-bottom: 12px; }
.sheet .close { position: absolute; right: 12px; top: 12px; }
.map-list { list-style: none; display: grid; gap: 6px; }
.map-list a, .map-list button {
  display: flex; width: 100%; justify-content: space-between; align-items: center;
  font: 16px/1.2 system-ui, sans-serif; color: #f4ecff; text-decoration: none; text-align: left;
  background: rgba(255, 255, 255, .04); border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 12px; padding: 13px 14px; cursor: pointer;
}
.map-list a::after, .map-list button::after { content: ">"; color: var(--gold); font-weight: 700; }
.map-list a:active, .map-list button:active { background: rgba(255, 207, 112, .12); }
.map-list .sep { margin-top: 8px; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: #9d8bbd; }

/* ---------- Reduced motion: keep it still ---------- */
@media (prefers-reduced-motion: reduce) {
  .kb, .haze, .grain, .glow, .neon-text, .neon-btn, .toast .eq i,
  .tube b, .tube small, .ball .spin, .bolt, .strip-red,
  .scene[data-name="main-floor"] .spot, .scene[data-name="main-floor"] .glint,
  .scene[data-name="basement"] .spot { animation: none !important; }
  .scene.hinting .zone::after { animation: none; opacity: .5; }
  dialog.sheet[open] { animation: none; }
}

/* ---------- Page text over the photo ---------- */
.hint.low { top: auto; bottom: calc(var(--safe-bottom, env(safe-area-inset-bottom)) + 64px); }
.welcome {
  position: absolute;
  z-index: 9;
  left: 0; right: 0;
  top: calc(var(--safe-top, env(safe-area-inset-top)) + 54px);
  text-align: center;
  font-size: clamp(20px, 6.4vw, 26px);
  pointer-events: none;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 16px;
}
.welcome small { display: block; margin-top: 6px; font: 12px/1.3 system-ui, sans-serif; letter-spacing: .08em;
                 color: #cdbbe9; text-shadow: 0 1px 6px #000; animation: none; }

/* ---------- Coat check name tag ---------- */
.name-tag {
  margin: 4px auto 14px;
  width: min(290px, 100%);
  border-radius: 14px;
  overflow: hidden;
  background: #fbf7ee;
  color: #1a1020;
  text-align: center;
  box-shadow: 0 8px 30px rgba(0, 0, 0, .5), 0 0 0 1px rgba(255, 255, 255, .1);
  transform: rotate(-2deg);
}
.name-tag .top { background: #c9302c; color: #fff; padding: 10px 8px 8px; }
.name-tag .top b { display: block; font: 800 26px/1 system-ui, sans-serif; letter-spacing: .12em; }
.name-tag .top span { font-size: 13px; letter-spacing: .06em; }
.name-tag .who { font: 700 38px/1.1 "Caveat", "Comic Sans MS", cursive; padding: 18px 10px 10px; min-height: 76px; word-break: break-word; }
.name-tag .ticket { font: 600 11px/1 ui-monospace, monospace; letter-spacing: .14em; color: #6b5a77; padding: 0 0 12px; }
.sheet p { color: #cdbbe9; font-size: 14px; line-height: 1.5; margin-bottom: 12px; text-align: center; }
.sheet .row { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* Helper for lining up zones: add ?zones to the page address to see them all */
.scene.show-zones .zone::after { opacity: .9; animation: none; }

/* ---------- Sign-in page ---------- */
.page-title {
  position: absolute;
  z-index: 9;
  left: 0; right: 0;
  top: calc(var(--safe-top, env(safe-area-inset-top)) + 56px);
  text-align: center;
  pointer-events: none;
}
.page-title h1 { font-size: clamp(26px, 8.4vw, 34px); font-weight: 400; line-height: 1.1; }
.page-title p { margin-top: 8px; font-size: 13px; letter-spacing: .05em; color: #e2d4f7; text-shadow: 0 1px 8px #000, 0 0 2px #000; }

/* The guestbook form looks like a cream paper page */
dialog.sheet.paper {
  color: #2a1c14;
  background:
    repeating-linear-gradient(to bottom, transparent 0 31px, rgba(90, 120, 170, .18) 31px 32px),
    radial-gradient(ellipse at 30% 0%, #fff8e6, var(--paper) 60%, #e6d4b0);
  box-shadow: 0 -10px 40px rgba(0, 0, 0, .7), inset 0 0 40px rgba(120, 80, 30, .18);
}
.paper h2 { color: #6b2a0c; text-shadow: none; font-family: "Caveat", cursive; font-size: 34px; font-weight: 700; }
.paper .close { color: #6b2a0c; background: rgba(255, 255, 255, .5); border-color: rgba(107, 42, 12, .35); }
.paper label { display: block; margin-bottom: 14px; }
.paper label span { display: block; font-size: 13px; letter-spacing: .06em; text-transform: uppercase; color: #6d5541; margin-bottom: 2px; }
.paper small { text-transform: none; letter-spacing: 0; }
.paper input {
  width: 100%;
  font: 700 28px/1.2 "Caveat", "Comic Sans MS", cursive;
  color: #1d2a6b;                       /* blue ink */
  background: transparent;
  border: 0;
  border-bottom: 2px solid rgba(60, 40, 20, .35);
  padding: 4px 2px;
  border-radius: 0;
}
.paper input:focus { outline: none; border-bottom-color: #b5541c; }
.paper .ink-btn {
  width: 100%;
  font: 600 17px/1 system-ui, sans-serif;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #fff6e0;
  background: linear-gradient(#2a1a10, #140c08);
  border: 1px solid #b8862f;
  border-radius: 12px;
  padding: 15px;
  margin: 4px 0 12px;
  cursor: pointer;
  box-shadow: 0 0 12px rgba(255, 180, 80, .35);
}
.paper h3 { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: #6d5541; margin: 6px 0 4px; }
.paper ol { list-style: none; font: 700 22px/1.3 "Caveat", cursive; color: #1d2a6b; }
.paper ol li { display: flex; justify-content: space-between; gap: 8px; }
.paper ol .note { color: #5b4a3a; font-weight: 500; }
.paper ol time { font: 12px system-ui, sans-serif; color: #8a735c; align-self: center; white-space: nowrap; }
.paper ol .empty { color: #8a735c; }
.paper .fine { font-size: 12px; color: #7a6450; text-align: left; margin: 10px 0 0; }
.paper .fine button { background: none; border: 0; color: #9a3d12; text-decoration: underline; font-size: 12px; cursor: pointer; }

/* ---------- Back Room: neon room names on the sign mounts ---------- */
.room-sign {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  pointer-events: none;
  z-index: 1;
  font-size: calc(var(--fs, 3.4) * 1cqw);   /* cqw = 1% of the photo's width, so text scales with it */
  line-height: 1.05;
  white-space: normal;
  /* a dark sign box behind the neon tubes */
  background: linear-gradient(rgba(14, 8, 20, .82), rgba(6, 3, 10, .82));
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 3px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .6), 0 0 18px rgba(181, 108, 255, .18);
  padding: .2em .3em;
}
.wall-sign { font-size: 11.5cqw; line-height: 1.08; text-align: center; white-space: normal; pointer-events: none; z-index: 1;
             display: flex; align-items: center; justify-content: center; }
.wall-sub { font: 3.6cqw/1.2 system-ui, sans-serif; letter-spacing: .08em; color: #f2dfb8; text-align: center; pointer-events: none;
            z-index: 1; text-shadow: 0 0 6px rgba(255, 180, 80, .7), 0 1px 3px #000; }
.wall-wash { pointer-events: none; mix-blend-mode: screen; opacity: .5;
             background: radial-gradient(ellipse 50% 45% at 50% 50%, rgba(255, 170, 70, .45), rgba(255, 140, 40, 0) 70%);
             animation: breathe 9s ease-in-out infinite; }
.glow.breathe.soft { animation-name: breathe-soft; }
@keyframes breathe-soft { 0%, 100% { opacity: .08; } 50% { opacity: .3; } }
/* colored light spill around each sign box */
.room-sign.neon-text        { box-shadow: 0 2px 8px rgba(0, 0, 0, .6), 0 0 22px rgba(255, 174, 61, .35); }
.room-sign.neon-text.purple { box-shadow: 0 2px 8px rgba(0, 0, 0, .6), 0 0 22px rgba(181, 108, 255, .45); }
.room-sign.neon-text.pink   { box-shadow: 0 2px 8px rgba(0, 0, 0, .6), 0 0 22px rgba(255, 61, 142, .4); }
.room-sign.neon-text.blue   { box-shadow: 0 2px 8px rgba(0, 0, 0, .6), 0 0 22px rgba(92, 176, 255, .4); }

/* ---------- Main Floor: neon tubes covering the blank boards ----------
   The dark fill hides the empty sign. The words are the glowing tube. */
.tube {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  pointer-events: none;
  z-index: 2;
  background: radial-gradient(ellipse at 50% 40%, #14111c 0%, #07060c 70%);
  border-radius: 4px;
  overflow: hidden;
}
.tube b, .tube small {
  font-family: "Tilt Neon", system-ui, sans-serif;
  font-weight: 400;
  line-height: 1.02;
  color: #fff;
}
.tube b {
  font-size: calc(var(--fs, 2.3) * 1cqw);
  letter-spacing: .04em;
  animation: text-flicker var(--flick, 8s) infinite;
  animation-delay: var(--d, 0s);
}
.tube small {
  font-size: calc(var(--fs2, 1.15) * 1cqw);
  letter-spacing: .06em;
  animation: text-flicker var(--flick, 8s) infinite;
  animation-delay: calc(var(--d, 0s) - 1s);
}
.tube.gold { box-shadow: inset 0 0 12px rgba(0, 0, 0, .75), 0 0 10px rgba(255, 174, 61, .5); }
.tube.gold b { text-shadow: 0 0 1px #fff, 0 0 4px #fff6d8, 0 0 8px var(--gold), 0 0 16px var(--gold-hot); }
.tube.blue { box-shadow: inset 0 0 8px rgba(0, 0, 0, .8), 0 0 8px rgba(80, 160, 255, .6); }
.tube.blue b { text-shadow: 0 0 1px #fff, 0 0 3px #e8f4ff, 0 0 7px var(--blue), 0 0 12px #2a6dff; letter-spacing: .01em; }
.tube.red { box-shadow: inset 0 0 10px rgba(0, 0, 0, .75), 0 0 10px rgba(255, 40, 60, .5); }
.tube.red b, .tube.red small { text-shadow: 0 0 1px #fff, 0 0 4px #ffd0d0, 0 0 8px #ff3344, 0 0 14px #c40020; }
.tube.pink { box-shadow: inset 0 0 8px rgba(0, 0, 0, .8), 0 0 8px rgba(255, 60, 160, .55); }
.tube.pink b { text-shadow: 0 0 1px #fff, 0 0 3px #ffd0ea, 0 0 7px #ff4d9a, 0 0 12px #ff2288; letter-spacing: .01em; }
.tube.ice b { text-shadow: 0 0 1px #fff, 0 0 4px #fff, 0 0 8px #c9dcff, 0 0 14px #7aa2ff; }
.tube.row { flex-direction: row; gap: .3em; }
.tube .chev {
  width: .42em;
  height: .42em;
  border-right: .1em solid #fff;
  border-bottom: .1em solid #fff;
  transform: rotate(-45deg);
  filter: drop-shadow(0 0 2px #ff4466) drop-shadow(0 0 5px #ff2244);
  flex: 0 0 auto;
}

/* The one disco ball: a circular mask of the ball already in the photo.
   .spin is that same patch, rotating. There is no second sphere. */
.ball {
  z-index: 2;
  pointer-events: none;
  border-radius: 50%;
  overflow: hidden;
}
.ball .spin {
  position: absolute;
  inset: 0;
  background-image: var(--bg);
  background-size: var(--bs);
  background-position: var(--bp);
  background-repeat: no-repeat;
  transform-origin: 50% 50%;
  animation: ball-spin 22s linear infinite;
}
@keyframes ball-spin { to { transform: rotate(360deg); } }

/* Main floor: full lounge, as tall as the phone, wider than it.
   Backdrop stays flat dark. Swipe sideways. No blurred room. */
.scene[data-layout="pan"] { touch-action: none; }
/* The lounge photo is punched at the window. Sky is behind that hole.
   Smoke and glows stay in front. */
.scene[data-name="main-floor"] canvas.sky { z-index: 0; pointer-events: none; }
.scene[data-name="main-floor"] .photo { position: relative; z-index: 2; }
.scene[data-name="main-floor"] .glow,
.scene[data-name="main-floor"] canvas.life { z-index: 3; }
.scene[data-name="main-floor"] .zone { z-index: 4; }
.scene[data-layout="pan"].is-dragging { cursor: grabbing; }
.swipe-hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--safe-bottom, env(safe-area-inset-bottom)) + 58px);
  z-index: 6;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  pointer-events: none;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(243, 231, 207, .8);
  text-shadow: 0 1px 6px #000;
  transition: opacity .4s ease;
}
.swipe-hint i {
  width: 7px;
  height: 7px;
  border-left: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
}
.swipe-hint i.r { transform: rotate(-135deg); }
.scene.swiped .swipe-hint { opacity: 0; }
.scene[data-name="main-floor"] .backdrop {
  filter: none;
  background: #050308 !important;
  background-image: none !important;
}
.scene[data-name="main-floor"] .backdrop::after { display: none; }
.scene[data-name="main-floor"] .stage { z-index: 2; }
.scene[data-name="main-floor"] .kb { animation: none; }
.scene[data-name="main-floor"] .stage.fade-y .photo,
.scene[data-name="main-floor"] .stage.fade-x .photo {
  -webkit-mask-image: none;
  mask-image: none;
}
canvas.sky.ceil {
  position: absolute;
  inset: auto;
  top: 0;
  left: 0;
  width: 100%;
  height: calc(var(--photo-top, 108px) + 48px);
  z-index: 3;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 0, #000 calc(100% - 46px), transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0, #000 calc(100% - 46px), transparent 100%);
}
canvas.tiles {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--photo-bottom, 40%) - 2px);
  width: 100%;
  height: calc(100% - var(--photo-bottom, 40%) + 2px);
  z-index: 1;
  pointer-events: none;
}

/* Painted lightning only (stars removed), pulsing on its own */
.bolt {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1;
  mix-blend-mode: screen;
  animation: bolt 6.2s infinite;
}
@keyframes bolt {
  0%, 100% { opacity: .62; }
  5% { opacity: 1; }
  8% { opacity: .35; }
  12% { opacity: .95; }
  20% { opacity: .55; }
  47% { opacity: .6; }
  50% { opacity: 1; }
  53% { opacity: .3; }
  70% { opacity: .7; }
  82% { opacity: .4; }
  88% { opacity: .92; }
}

canvas.life { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; mix-blend-mode: screen; }
.scene.is-paused .tube b,
.scene.is-paused .tube small,
.scene.is-paused .ball .spin,
.scene.is-paused .bolt,
.scene.is-paused .glow,
.scene.is-paused .spot,
.scene.is-paused .glint,
.scene.is-paused .kb { animation-play-state: paused; }

/* Main Floor motion. CSS only. No second disco ball.
   .glint is a small highlight that crosses the ball in the photograph. */
.scene[data-name="main-floor"] canvas.heads {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 3;
  pointer-events: none;
  mix-blend-mode: screen;
}
.scene[data-name="main-floor"] .spots {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  overflow: hidden;
}
.scene[data-name="main-floor"] .spot {
  position: absolute;
  display: block;
  width: 4.6%;
  height: 2.6%;
  border-radius: 50%;
  mix-blend-mode: screen;
  filter: blur(1.5px);
  opacity: .72;
  pointer-events: none;
}
.scene[data-name="main-floor"] .spot.gold {
  background: radial-gradient(ellipse at center, rgba(255, 214, 130, .75) 0%, rgba(255, 180, 60, 0) 70%);
}
.scene[data-name="main-floor"] .spot.purple {
  background: radial-gradient(ellipse at center, rgba(196, 130, 255, .7) 0%, rgba(140, 60, 255, 0) 70%);
}
.scene[data-name="main-floor"] .spot.blue {
  background: radial-gradient(ellipse at center, rgba(130, 186, 255, .7) 0%, rgba(50, 110, 255, 0) 70%);
}
.scene[data-name="main-floor"] .spot.floor {
  width: 6.2%;
  height: 1.15%;
  opacity: .42;
  filter: blur(2px);
}
.scene[data-name="main-floor"] .spot.a { animation: spot-a 9s ease-in-out infinite alternate; }
.scene[data-name="main-floor"] .spot.b { animation: spot-b 11s ease-in-out infinite alternate; }
.scene[data-name="main-floor"] .spot.c { animation: spot-c 8.5s ease-in-out infinite alternate; }
.scene[data-name="main-floor"] .spot.d { animation: spot-d 10s ease-in-out infinite alternate; }
.scene[data-name="main-floor"] .spot.e { animation: spot-e 12s ease-in-out infinite alternate; }
.scene[data-name="main-floor"] .spot.fa { animation: spot-fa 9s ease-in-out infinite alternate; }
.scene[data-name="main-floor"] .spot.fb { animation: spot-fb 11s ease-in-out infinite alternate; }
.scene[data-name="main-floor"] .spot.fc { animation: spot-fc 8.5s ease-in-out infinite alternate; }
.scene[data-name="main-floor"] .spot.fd { animation: spot-fd 10s ease-in-out infinite alternate; }
@keyframes spot-a { from { left: 34%; top: 48%; } to { left: 52%; top: 58%; } }
@keyframes spot-b { from { left: 58%; top: 36%; } to { left: 74%; top: 50%; } }
@keyframes spot-c { from { left: 8%; top: 42%; } to { left: 18%; top: 56%; } }
@keyframes spot-d { from { left: 40%; top: 62%; } to { left: 62%; top: 52%; } }
@keyframes spot-e { from { left: 78%; top: 58%; } to { left: 88%; top: 44%; } }
@keyframes spot-fa { from { left: 32%; top: 78%; } to { left: 50%; top: 86%; } }
@keyframes spot-fb { from { left: 55%; top: 74%; } to { left: 72%; top: 84%; } }
@keyframes spot-fc { from { left: 6%; top: 80%; } to { left: 20%; top: 88%; } }
@keyframes spot-fd { from { left: 70%; top: 82%; } to { left: 86%; top: 74%; } }
.scene[data-name="main-floor"] .glint {
  position: absolute;
  z-index: 3;
  width: 1.15%;
  height: 1.7%;
  pointer-events: none;
  border-radius: 40%;
  background: radial-gradient(ellipse at center, rgba(255, 255, 255, .7), rgba(255, 255, 255, 0) 68%);
  mix-blend-mode: screen;
  filter: blur(0.4px);
  animation: ball-glint 8s ease-in-out infinite;
}
.scene[data-name="main-floor"] .glint.b {
  width: 0.7%;
  height: 1.05%;
  background: radial-gradient(ellipse at center, rgba(255, 220, 150, .55), rgba(255, 200, 80, 0) 70%);
  animation-name: ball-glint-b;
  animation-duration: 8s;
}
@keyframes ball-glint {
  0% { left: 23.7%; top: 17.6%; opacity: 0; }
  14% { opacity: .9; }
  50% { left: 26.1%; top: 21.4%; opacity: .65; }
  86% { opacity: .85; }
  100% { left: 28.6%; top: 25.2%; opacity: 0; }
}
@keyframes ball-glint-b {
  0% { left: 28.2%; top: 18.4%; opacity: 0; }
  18% { opacity: .7; }
  55% { left: 25.4%; top: 22.6%; opacity: .5; }
  100% { left: 23.9%; top: 26.2%; opacity: 0; }
}


/* ---------- Back Room, Basement, Bathroom (v31) ---------- */
.scene[data-layout="pan"] .backdrop {
  filter: none;
  background: #050308 !important;
  background-image: none !important;
}
.scene[data-layout="pan"] .backdrop::after { display: none; }
.scene[data-layout="pan"] .kb { animation: none; }
.scene[data-layout="pan"] .stage.fade-y .photo,
.scene[data-layout="pan"] .stage.fade-x .photo {
  -webkit-mask-image: none;
  mask-image: none;
}
.where-tag {
  position: absolute;
  z-index: 6;
  top: calc(var(--safe-top, env(safe-area-inset-top)) + 0.7rem);
  left: 0.85rem;
  margin: 0;
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #e7d7a4;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .8);
  pointer-events: none;
}
/* Slow single dip. Not the fast strobe flicker. */
.neon-text.soft { animation: text-flicker-soft 18s ease-in-out infinite; }
.board.neon-text { pointer-events: none; }

/* Red bloom sitting only on the thin white strips (mask), screen-blended. */
.scene[data-name="back-room"] .strip-red {
  position: absolute;
  inset: 0;
  background: #ff2438;
  mix-blend-mode: screen;
  pointer-events: none;
  opacity: .62;
  -webkit-mask-image: url("../assets/back-strips-mask.png");
  mask-image: url("../assets/back-strips-mask.png");
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  animation: flicker-soft 16s ease-in-out infinite;
}
.scene[data-name="back-room"] .strip-red.bloom {
  filter: blur(14px);
  opacity: .5;
  animation-delay: -6s;
}

/* Basement ceiling spots. Same idea as the Main Floor, more lights and colors. */
.scene[data-name="basement"] canvas.heads {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 3;
  pointer-events: none;
  mix-blend-mode: screen;
}

/* Back Room Three.js overlays (smoke + island LED wash). Canvas under tubes/beams. */
.scene[data-name="back-room"] canvas.fx-br {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  pointer-events: none;
  mix-blend-mode: screen;
}

.scene[data-name="basement"] .spots {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  overflow: hidden;
}
.scene[data-name="basement"] .spot {
  position: absolute;
  display: block;
  width: 7%;
  height: 3.2%;
  border-radius: 50%;
  mix-blend-mode: screen;
  filter: blur(2px);
  opacity: .7;
  pointer-events: none;
}
.scene[data-name="basement"] .spot.gold {
  background: radial-gradient(ellipse at center, rgba(255, 214, 130, .75) 0%, rgba(255, 180, 60, 0) 70%);
}
.scene[data-name="basement"] .spot.purple {
  background: radial-gradient(ellipse at center, rgba(196, 130, 255, .72) 0%, rgba(140, 60, 255, 0) 70%);
}
.scene[data-name="basement"] .spot.blue {
  background: radial-gradient(ellipse at center, rgba(130, 186, 255, .7) 0%, rgba(50, 110, 255, 0) 70%);
}
.scene[data-name="basement"] .spot.red {
  background: radial-gradient(ellipse at center, rgba(255, 90, 110, .7) 0%, rgba(180, 20, 40, 0) 70%);
}
.scene[data-name="basement"] .spot.ice {
  background: radial-gradient(ellipse at center, rgba(210, 235, 255, .75) 0%, rgba(120, 170, 255, 0) 70%);
}
.scene[data-name="basement"] .spot.floor {
  width: 9%;
  height: 1.5%;
  opacity: .4;
  filter: blur(3px);
}
.scene[data-name="basement"] .spot.a { animation: bspot-a 14s ease-in-out infinite alternate; }
.scene[data-name="basement"] .spot.b { animation: bspot-b 16s ease-in-out infinite alternate; }
.scene[data-name="basement"] .spot.c { animation: bspot-c 13s ease-in-out infinite alternate; }
.scene[data-name="basement"] .spot.d { animation: bspot-d 18s ease-in-out infinite alternate; }
.scene[data-name="basement"] .spot.e { animation: bspot-e 15s ease-in-out infinite alternate; }
.scene[data-name="basement"] .spot.f { animation: bspot-f 17s ease-in-out infinite alternate; }
.scene[data-name="basement"] .spot.g { animation: bspot-g 19s ease-in-out infinite alternate; }
.scene[data-name="basement"] .spot.fa { animation: bspot-fa 14s ease-in-out infinite alternate; }
.scene[data-name="basement"] .spot.fb { animation: bspot-fb 16s ease-in-out infinite alternate; }
.scene[data-name="basement"] .spot.fc { animation: bspot-fc 13s ease-in-out infinite alternate; }
.scene[data-name="basement"] .spot.fd { animation: bspot-fd 18s ease-in-out infinite alternate; }
@keyframes bspot-a { from { left: 28%; top: 18%; } to { left: 48%; top: 36%; } }
@keyframes bspot-b { from { left: 46%; top: 12%; } to { left: 62%; top: 30%; } }
@keyframes bspot-c { from { left: 18%; top: 28%; } to { left: 34%; top: 46%; } }
@keyframes bspot-d { from { left: 60%; top: 20%; } to { left: 78%; top: 40%; } }
@keyframes bspot-e { from { left: 36%; top: 8%; } to { left: 22%; top: 26%; } }
@keyframes bspot-f { from { left: 70%; top: 30%; } to { left: 54%; top: 48%; } }
@keyframes bspot-g { from { left: 8%; top: 34%; } to { left: 20%; top: 52%; } }
@keyframes bspot-fa { from { left: 30%; top: 72%; } to { left: 48%; top: 84%; } }
@keyframes bspot-fb { from { left: 52%; top: 70%; } to { left: 70%; top: 82%; } }
@keyframes bspot-fc { from { left: 12%; top: 76%; } to { left: 28%; top: 88%; } }
@keyframes bspot-fd { from { left: 68%; top: 78%; } to { left: 84%; top: 68%; } }
