/* THE LOUNGE — every lamp has been on since before anyone here arrived. */

:root {
  --lg-wall: #2a1428;
  --lg-carpet-a: #7a2f8f;
  --lg-carpet-b: #ff8a2f;
  --lg-carpet-c: #2fe0ff;
}

body.lounge {
  background: radial-gradient(ellipse at 50% 0%, #4a1f4a 0%, var(--lg-wall) 65%);
  color: #f4e6ff;
  min-height: 100vh;
  overflow-x: hidden;
  padding: 3rem 1.5rem 5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.lg-header {
  text-align: center;
  margin-bottom: 2.5rem;
  position: relative;
  z-index: 2;
}
.lg-header h1 {
  font-family: Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 1.8rem;
  color: #ffd9f4;
  text-shadow: 0 0 18px rgba(255, 138, 214, 0.5);
}
.lg-header p {
  max-width: 42ch;
  margin: 0.75rem auto 0;
  font-size: 0.8rem;
  opacity: 0.8;
}

/* THE LAMPS — each one is a glass capsule with 3-4 blurred blobs inside
   it. blur() softens every blob into a glowing halo, and the extreme
   contrast() right after it snaps those soft edges back to hard ones —
   except where two halos are close enough to overlap, where the combined
   softness survives the contrast threshold and reads as a bridge. that
   bridging *is* the lava-lamp merge/split effect, and it's the whole
   trick — no blob ever touches another, the filter just makes it look
   that way. */
.lamps {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 2.5rem;
  flex-wrap: wrap;
  cursor: pointer;
}

.lamp {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.lamp .cap {
  width: 34px;
  height: 14px;
  border-radius: 6px 6px 2px 2px;
  background: linear-gradient(180deg, #d8d0c0, #8a8070);
  box-shadow: 0 -1px 0 rgba(255,255,255,0.3) inset;
}

.tube {
  width: 76px;
  height: 200px;
  border-radius: 38px 38px 30px 30px / 90px 90px 30px 30px;
  overflow: hidden;
  position: relative;
  border: 2px solid rgba(255,255,255,0.15);
  box-shadow:
    inset 0 0 20px rgba(255,255,255,0.08),
    inset -8px 0 16px rgba(0,0,0,0.35),
    0 0 30px 4px var(--glow, rgba(255,138,47,0.4));
}

.liquid {
  position: absolute;
  inset: 0;
  background: var(--liquid, #2a0e33);
}

.blobs {
  position: absolute;
  inset: -20% -10%;
  filter: blur(9px) contrast(26);
}

.blob {
  position: absolute;
  width: 46%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--wax, #ff8a2f);
  animation-name: drift;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

@keyframes drift {
  0%   { transform: translate(0, 0) scale(1); }
  50%  { transform: translate(var(--dx, 10px), var(--dy, -120px)) scale(0.85); }
  100% { transform: translate(calc(var(--dx, 10px) * -0.6), var(--dy2, -180px)) scale(1.1); }
}

.base {
  width: 46px;
  height: 26px;
  border-radius: 4px 4px 10px 10px;
  background: linear-gradient(180deg, #b8ac8c, #6b5c3a);
  position: relative;
  z-index: 1;
}
.base::after {
  /* contact shadow, cast onto the shelf rather than the bare wall */
  content: '';
  position: absolute;
  top: 100%;
  left: 10%;
  right: 10%;
  height: 8px;
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.5) 0%, transparent 75%);
}

/* the shelf — the lamps were just floating over the wall color with a
   drawn-on shadow standing in for "sitting on something." this is an
   actual mounted plank, wide enough to run the full row, with each
   lamp's base contact-shadow now falling onto real wood instead of the
   empty wall behind it. */
.shelf-wrap {
  position: relative;
  z-index: 2;
  width: min(100%, 620px);
  margin: 0 auto;
}
.shelf {
  height: 20px;
  border-radius: 2px 2px 3px 3px;
  background: repeating-linear-gradient(
    100deg,
    #9a7440 0 10px,
    #8a6636 10px 18px,
    #7a5a2e 18px 26px
  );
  box-shadow:
    0 10px 18px rgba(0, 0, 0, 0.55),
    inset 0 2px 0 rgba(255, 220, 180, 0.25),
    inset 0 -3px 4px rgba(0, 0, 0, 0.4);
}
.shelf-bracket {
  position: absolute;
  top: 100%;
  width: 10px;
  height: 26px;
  background: linear-gradient(180deg, #6b5028, #3a2a12);
  clip-path: polygon(0 0, 100% 0, 100% 30%, 15% 100%, 0 100%);
}
.shelf-bracket.left { left: 8%; }
.shelf-bracket.right { right: 8%; }

/* four lamps, four palettes — none of them repeat */
.lamp.l1 .liquid { --liquid: #241033; }
.lamp.l1 .blob { --wax: #ff5fd6; }
.lamp.l1 .tube { --glow: rgba(255, 95, 214, 0.45); }

.lamp.l2 .liquid { --liquid: #0e2f33; }
.lamp.l2 .blob { --wax: #2fe0ff; }
.lamp.l2 .tube { --glow: rgba(47, 224, 255, 0.45); }

.lamp.l3 .liquid { --liquid: #33240e; }
.lamp.l3 .blob { --wax: #ffe62f; }
.lamp.l3 .tube { --glow: rgba(255, 230, 47, 0.45); }

.lamp.l4 .liquid { --liquid: #0e3316; }
.lamp.l4 .blob { --wax: #6dff2f; }
.lamp.l4 .tube { --glow: rgba(109, 255, 47, 0.45); }

/* timing, drift distance, and starting position are all set per blob,
   inline, in the HTML — not here. the first version keyed all of this
   off :nth-child, which meant every lamp's "first blob" shared the
   exact same duration and delay as every other lamp's first blob: four
   different colors moving in identical, silent lockstep. randomizing
   per lamp too (not just per blob within a lamp) needed 16 independent
   values, which is what inline style attributes are for. */

/* click a lamp — one good shake, like the table it's sitting on got
   bumped, then it settles back into its usual drift. --dur is set
   inline per blob (same value as that blob's own animation-duration),
   so the combined list below preserves each blob's actual drift speed
   instead of resetting it to a shared default. */
.lamp.jostled .blob {
  animation-name: drift, jostle;
  animation-duration: var(--dur, 9s), 0.5s;
  animation-iteration-count: infinite, 1;
  animation-timing-function: ease-in-out, ease-out;
}
@keyframes jostle {
  0%   { margin-left: 0; }
  25%  { margin-left: -6px; }
  50%  { margin-left: 5px; }
  75%  { margin-left: -3px; }
  100% { margin-left: 0; }
}

.lg-hint {
  position: relative;
  z-index: 2;
  max-width: 42ch;
  margin: 2rem auto 0;
  text-align: center;
  font-size: 0.75rem;
  opacity: 0.75;
}

/* THE CARPET — long fuzzy strands, not a flat pattern. each strand is a
   thin gradient sliver with its own tiny sway, offset per column so the
   whole floor ripples like it's being stepped through rather than
   sitting still. same perspective trick as every other floor in this
   building, fuzzed up with blur(). */
.shag {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 42vh;
  margin-top: auto;
  overflow: hidden;
  perspective: 400px;
}

/* the base weave — the wide vivid color bands from the very first pass.
   turns out these were never the problem; a flat printed pattern
   reading as "not quite shag" was about the *carpet having no pile*,
   not about the colors, which is why the fix below adds actual strands
   on top of this instead of replacing it. */
.shag .strands {
  position: absolute;
  inset: -10% -5%;
  z-index: 0;
  background-image: repeating-linear-gradient(
    90deg,
    var(--lg-carpet-a) 0 28px,
    var(--lg-carpet-b) 28px 56px,
    var(--lg-carpet-c) 56px 84px,
    var(--lg-carpet-a) 84px 112px
  );
  background-size: 112px 100%;
  filter: blur(3px) saturate(1.3);
  transform: rotateX(62deg) scale(1.8);
  transform-origin: bottom center;
  animation: sway 5s ease-in-out infinite;
}

@keyframes sway {
  0%, 100% { background-position: 0 0; }
  50%      { background-position: 14px 0; }
}

/* the fade has to out-stack the pile beneath it (z-index: 2 vs the
   pile's 1) or the strands near the top edge would just sit on top of
   the "this recedes into the wall" gradient instead of fading with it */
.shag::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(to top, transparent 0%, var(--lg-wall) 92%);
}

/* THE PILE — ~800 independent strands, each rotating around its own
   rooted base on its own duration/delay, so the whole carpet moves like
   kelp in a current instead of a rigid comb. covers the *entire* floor
   — each strand's `bottom` percentage doubles as its depth cue, scaled
   and dimmed smaller/fainter the further back it sits.

   .seaweed carries the *same* rotateX/scale as .strands (the color
   floor) rather than sitting flat on top of it — without that, every
   strand's root point was positioned in flat, untilted 2D space while
   the carpet underneath was a tilted 3D plane, so nothing was actually
   *planted* in the floor, it was just laid over it like a decal. with
   the matching transform here, each strand's root sits in the same
   tilted coordinate space as the weave beneath it, and the per-strand
   sway (a plain rotate()) then happens *inside* that already-tilted
   space — exactly like something rooted in a surface that's angled
   away from you. */
/* back to a flat, untilted overlay — matching the carpet's own
   rotateX/scale here was meant to "root" the strands in the tilted
   plane, but it stretched every blade along the tilt direction into a
   big flat diagonal streak instead, losing the individual-blade look
   entirely. upright and unscaled reads as far more like pile than
   "correctly projected" did. */
.seaweed {
  position: absolute;
  inset: 0;
  z-index: 1;
}

.strand {
  position: absolute;
  border-radius: 50% 50% 10% 10% / 22% 22% 6% 6%;
  transform-origin: bottom center;
  animation-name: sway-strand;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  filter: blur(0.3px);
}

@keyframes sway-strand {
  0%, 100% { transform: rotate(calc(var(--amp, 10deg) * -1)); }
  50%      { transform: rotate(var(--amp, 10deg)); }
}

/* THE FURNITURE — actually standing on the carpet at its near edge
   (highest z-index in .shag, above both the pile and the distance
   fade), not floating over it the way the lamps used to float over
   the bare wall before they got a shelf. */
.furniture {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: 16%;
  transform: translateX(-50%) scale(1.35);
  transform-origin: bottom center;
  display: flex;
  align-items: flex-end;
  gap: 2.5rem;
}

/* --- a Barcalounger --- */
.lounger {
  position: relative;
  width: 108px;
  height: 150px;
}
.lounger .back {
  position: absolute;
  bottom: 46px;
  left: 12px;
  width: 84px;
  height: 96px;
  border-radius: 20px 20px 6px 6px;
  background: linear-gradient(160deg, var(--vinyl-light, #e0a83f), var(--vinyl-dark, #a86a1f));
  box-shadow: inset 0 -10px 16px rgba(0,0,0,0.2), inset 0 8px 10px rgba(255,255,255,0.15);
}
.lounger .back::before {
  /* button tufting */
  content: '';
  position: absolute;
  inset: 14px 10px;
  background-image: radial-gradient(circle, rgba(0,0,0,0.25) 0 2px, transparent 3px);
  background-size: 20px 20px;
  background-position: 0 0, 10px 10px;
}
.lounger .seat {
  position: absolute;
  bottom: 30px;
  left: 4px;
  width: 100px;
  height: 30px;
  border-radius: 6px;
  background: linear-gradient(180deg, var(--vinyl-light, #e0a83f), var(--vinyl-dark, #a86a1f));
  box-shadow: 0 4px 6px rgba(0,0,0,0.3);
}
.lounger .arm {
  position: absolute;
  bottom: 28px;
  width: 18px;
  height: 60px;
  border-radius: 10px;
  background: linear-gradient(180deg, var(--vinyl-light, #e0a83f), var(--vinyl-dark, #a86a1f));
  box-shadow: 0 4px 6px rgba(0,0,0,0.3);
}
.lounger .arm.l { left: 0; }
.lounger .arm.r { right: 0; }
.lounger .footrest {
  position: absolute;
  bottom: 0;
  left: 14px;
  width: 80px;
  height: 22px;
  border-radius: 6px;
  background: linear-gradient(180deg, var(--vinyl-dark, #a86a1f), #6b4410);
  box-shadow: 0 6px 10px rgba(0,0,0,0.4);
}
.lounger.l1 { --vinyl-light: #ffce5f; --vinyl-dark: #c98a1f; }
.lounger.l2 { --vinyl-light: #ff8f6f; --vinyl-dark: #c9401f; }

/* --- the record cabinet ---
   the first version put a perfectly circular turntable flat in the
   middle of a straight-on front face — a top-down disc and a
   front-elevation box sharing one drawing with no shared vanishing
   point, which is exactly what reads as "wrong angle." fix: give the
   cabinet an actual horizontal top surface (tilted back in 3D, same
   perspective()+rotateX trick as the shelf's lid), and put the
   turntable and vinyl *inside* that surface as plain flat circles —
   nested inside a transformed parent, they inherit its tilt for free
   and come out as correctly foreshortened ellipses automatically,
   the same trick that now roots the carpet's pile to its own tilted
   plane. the lid opens up from the top surface's own back edge, and
   the front face stays a plain straight-on panel below — one
   consistent convention (tilted top, flat front) instead of two
   different, disagreeing ones. */
.record-cabinet {
  position: relative;
  width: 230px;
  cursor: pointer;
}
.record-cabinet .top {
  position: relative;
  width: 100%;
  height: 64px;
  background: linear-gradient(200deg, #a8804a, #7a5a2e);
  transform: perspective(360px) rotateX(55deg);
  transform-origin: bottom center;
  z-index: 2;
}
.record-cabinet .lid {
  position: absolute;
  bottom: 100%;
  left: 4%;
  width: 92%;
  height: 54px;
  background: linear-gradient(200deg, #9a7440, #6b4c22);
  transform-origin: bottom center;
  transform: rotateX(-42deg);
  box-shadow: inset 0 2px 0 rgba(255, 220, 180, 0.2);
}
.turntable {
  position: absolute;
  top: 50%;
  left: 36%;
  transform: translate(-50%, -50%);
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background: #17120d;
  box-shadow: inset 0 0 12px rgba(0, 0, 0, 0.7), 0 2px 4px rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
}
.vinyl {
  width: 86px;
  height: 86px;
  border-radius: 50%;
  background: repeating-radial-gradient(circle, #0c0906 0 2px, #221c14 2px 4px);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: spin-vinyl 2.6s linear infinite;
  animation-play-state: paused;
}
.record-cabinet.playing .vinyl {
  animation-play-state: running;
}
.vinyl .label {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #ffcf6f, #b8590f 85%);
}
@keyframes spin-vinyl {
  to { transform: rotate(360deg); }
}
.tonearm {
  position: absolute;
  top: 14%;
  right: 14%;
  width: 4px;
  height: 54px;
  border-radius: 2px;
  background: linear-gradient(180deg, #d8c8a0, #9a8a68);
  transform-origin: top center;
  transform: rotate(30deg);
  transition: transform 0.7s cubic-bezier(.3, .7, .3, 1);
  box-shadow: -1px 0 0 rgba(0, 0, 0, 0.3);
}
/* the needle actually comes down onto the record when it's playing,
   instead of just resting off to the side forever */
.record-cabinet.playing .tonearm {
  transform: rotate(7deg);
}
.tonearm::after {
  content: '';
  position: absolute;
  bottom: -3px;
  left: -4px;
  width: 11px;
  height: 7px;
  border-radius: 1px;
  background: #2a2418;
}
.record-cabinet .body {
  position: relative;
  width: 100%;
  height: 110px;
  background: linear-gradient(180deg, #8a6234, #5c3f1e);
  border-radius: 0 0 4px 4px;
  box-shadow: 0 14px 22px rgba(0, 0, 0, 0.5), inset 0 2px 0 rgba(255, 255, 255, 0.08);
  z-index: 1;
}
.record-cabinet .body .knob {
  position: absolute;
  bottom: 12px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #d8c8a0, #6b5230 70%);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), inset 0 1px 1px rgba(255, 255, 255, 0.3);
  z-index: 1;
}
.record-cabinet .body .knob.l { left: 30px; }
.record-cabinet .body .knob.r { right: 30px; }

/* the speaker grills — a perforated cloth panel on either side of the
   front face, dots small and dense enough to read as woven mesh
   rather than a polka-dot pattern */
.record-cabinet .grill {
  position: absolute;
  top: 12px;
  width: 74px;
  height: 62px;
  border-radius: 3px;
  background-color: #241c14;
  background-image: radial-gradient(circle, #4a3624 0 1.4px, transparent 1.6px);
  background-size: 7px 7px;
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.65), inset 0 0 0 2px rgba(0, 0, 0, 0.3);
}
.record-cabinet .grill.l { left: 16px; }
.record-cabinet .grill.r { right: 16px; }
.record-cabinet .legs {
  position: absolute;
  bottom: -20px;
  left: 12px;
  right: 12px;
  display: flex;
  justify-content: space-between;
}
.record-cabinet .legs span {
  width: 7px;
  height: 22px;
  background: linear-gradient(180deg, #6b4c22, #3a2810);
  transform: rotate(6deg);
}
.record-cabinet .legs span:last-child { transform: rotate(-6deg); }
