/* screen: room (Focus Lounge social hub). */

/* ============================================================
   LAYOUT: 3 columns desktop (260 / fluid / 300), stacked mobile
   ============================================================ */

.room-layout {
  display: grid;
  grid-template-columns: minmax(200px, 240px) minmax(0, 1fr) minmax(240px, 280px);
  gap: 16px;
  align-items: start;
}

.room-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

/* the shell's own 264px sidebar is still in play above 980px, so three columns
   here squeezed the scene down to ~90px before this breakpoint hit. */
@media (max-width: 1180px) {
  .room-layout { grid-template-columns: 1fr; }
  .room-col-left { order: 2; }
  .room-col-center { order: 1; }
  .room-col-right { order: 3; }
}

/* consistency pass: 20px card padding, 12px internal list gaps (D-imposed rhythm) */
.room-col .card { padding: 20px; }

/* ============================================================
   LEFT COLUMN
   ============================================================ */

.room-lounge-card { display: flex; flex-direction: column; gap: 4px; }
.room-title { font-size: 19px; font-weight: 900; color: var(--ink); margin-top: 2px; }
.room-subtitle { font-size: 12.5px; font-weight: 700; color: var(--muted); }

.room-active-banner {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; border-radius: var(--r-md);
  background: color-mix(in srgb, var(--success) 15%, transparent);
  color: var(--success);
  font-weight: 800; font-size: 13.5px;
  border: 1px solid color-mix(in srgb, var(--success) 28%, transparent);
}

.room-code-card { display: flex; flex-direction: column; gap: 2px; }
.room-code {
  font-family: var(--font);
  font-size: 20px; letter-spacing: .06em;
  color: var(--ink);
}

.room-members-card .room-member-list {
  list-style: none; display: flex; flex-direction: column; gap: 12px;
  margin-top: 10px;
}
.room-member {
  display: flex; align-items: center; gap: 10px;
}
.room-member-info { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.room-member-name {
  font-weight: 800; font-size: 13.5px; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.room-member-status {
  font-size: 11px; font-weight: 700;
}
.room-crown { font-size: 12px; margin-left: 2px; }

.room-status-dot {
  width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; margin-left: auto;
  box-shadow: 0 0 0 3px var(--card);
}
.room-status-dot.tone-green { background: var(--success); }
.room-status-dot.tone-gold { background: var(--gold); }
.room-status-dot.tone-blue { background: var(--blue); }
.room-status-dot.tone-idle { background: var(--muted); }
.room-status-dot.tone-warm { background: var(--warm); }
.room-status-dot.tone-violet { background: var(--violet); }

.room-member-status.tone-green { color: var(--success); }
.room-member-status.tone-gold { color: var(--gold); }
.room-member-status.tone-blue { color: var(--blue); }
.room-member-status.tone-idle { color: var(--muted); }
.room-member-status.tone-warm { color: var(--warm); }
.room-member-status.tone-violet { color: var(--violet); }

.room-tagline { text-align: center; font-size: 12px; font-weight: 700; font-style: italic; }

/* ============================================================
   SCENE: the lounge is now a real voxel scene (app/js/voxel/scenes/
   lounge.js, mounted by room.js via mountVoxel, D-009/VOXEL.md).

   The hand-drawn diorama below (back: wall + window + bookshelf; mid:
   fireplace + rug + table + seated crew; front: plants + lamp) is kept
   exactly as it was and wrapped in .room-scene-art (D-013 rule 1: the CSS
   scene stays underneath as the repli, in case the canvas fails, and it
   doubles for free as the ui-fluide token placeholder while the scene bakes,
   since it is already 100% tokens with a [data-theme="dark"] variant, zero
   hex). local --scene-* vars, softened variant in [data-theme="dark"].

   The floating name+status badges (.room-scene-badge-anchor) and the morning
   banner (.scene-float) are NOT part of .room-scene-art: they stay direct
   children of .room-scene so D-013 rule 2 (below) can raise them above
   whatever the canvas becomes (engine.js appends it last, with no z-index of
   its own).
   ============================================================ */

.room-scene {
  --scene-wall-1: var(--gold-soft);
  --scene-wall-2: var(--warm-soft);
  --scene-floor: var(--bg-2);
  --scene-sky-1: var(--blue-soft);
  --scene-sky-2: var(--card);
  --scene-cloud: var(--card);
  --scene-wood: var(--ink-soft);
  --scene-wood-dark: var(--ink);
  --scene-fire-1: var(--warm);
  --scene-fire-2: var(--gold);
  --scene-fire-surround: var(--ink-soft);
  --scene-neon: var(--violet);
  --scene-neon-glow: var(--violet-soft);
  --scene-rug: color-mix(in srgb, var(--blue) 40%, var(--ink-soft) 60%);
  --scene-rug-line: color-mix(in srgb, var(--card) 35%, transparent);
  --scene-shelf-body: var(--ink-soft);
  --scene-shelf-line: color-mix(in srgb, var(--ink) 35%, transparent);
  --scene-sofa-a: color-mix(in srgb, var(--success) 16%, transparent); --scene-sofa-a-edge: var(--success);
  --scene-sofa-b: var(--gold-soft); --scene-sofa-b-edge: var(--gold);
  --scene-sofa-c: var(--blue-soft); --scene-sofa-c-edge: var(--blue);
  --scene-sofa-d: var(--warm-soft); --scene-sofa-d-edge: var(--warm);
  --scene-sofa-e: var(--violet-soft); --scene-sofa-e-edge: var(--violet);
  --scene-sofa-f: var(--line-soft); --scene-sofa-f-edge: var(--muted);
  --scene-plant-pot: var(--ink-soft);
  --scene-plant-leaf: var(--accent);
  --scene-plant-leaf-2: var(--success);
  --scene-steam: var(--line-soft);
  --scene-lamp-shade: var(--gold-soft);
  --scene-lamp-glow: var(--gold);
  --scene-monitor: var(--blue-soft);
  --scene-monitor-edge: var(--violet);
  min-height: 480px;
}
/* atmosphere, the layer in FRONT of the CSS diorama only: hearth light
   pooling in the middle, the corners falling away. Gives the repli its third
   depth reading without adding a single element to the DOM.
   Scoped to .room-scene-art (not .room-scene) on purpose (plan risk #6): the
   real voxel scene bakes its own vignette (lounge.js V.fx({ vignette: ... }),
   D-012/D-016), so this synthetic one must never land on top of it or of the
   floating badges/banner (both z-index:2, see D-013 rule 2 below) once the
   canvas is mounted. .room-scene-art already establishes its own stacking
   context (components.css: position:absolute + z-index:-1), so z-index:4 here
   only orders this pseudo-element against its OWN siblings inside the repli
   (bg, window, fireplace, etc.), never against the canvas or the UI floats. */
.room-scene-art::after {
  content: '';
  position: absolute; inset: 0; z-index: 4;
  pointer-events: none;
  background:
    radial-gradient(120% 85% at 46% 62%, color-mix(in srgb, var(--scene-fire-2) 12%, transparent) 0%, transparent 52%),
    radial-gradient(130% 100% at 50% 45%, transparent 52%, color-mix(in srgb, var(--ink) 16%, transparent) 100%);
}
[data-theme="dark"] .room-scene-art::after {
  background:
    radial-gradient(120% 85% at 46% 62%, color-mix(in srgb, var(--scene-fire-2) 14%, transparent) 0%, transparent 54%),
    radial-gradient(130% 100% at 50% 45%, transparent 46%, color-mix(in srgb, var(--bg) 62%, transparent) 100%);
}

[data-theme="dark"] .room-scene {
  --scene-wall-1: var(--card-2);
  --scene-wall-2: var(--panel);
  --scene-floor: var(--bg-2);
  --scene-sky-2: var(--panel);
  --scene-cloud: color-mix(in srgb, var(--card) 65%, var(--ink-soft) 35%);
  --scene-wood: var(--line);
  --scene-wood-dark: var(--bg);
  --scene-fire-surround: var(--card-2);
  --scene-neon: var(--accent);
  --scene-neon-glow: var(--accent-soft);
  --scene-rug: color-mix(in srgb, var(--blue) 35%, var(--bg) 65%);
  --scene-rug-line: color-mix(in srgb, var(--ink) 25%, transparent);
  --scene-shelf-body: var(--card-2);
  --scene-shelf-line: color-mix(in srgb, var(--bg) 55%, transparent);
  --scene-plant-pot: var(--card-2);
  --scene-monitor-edge: var(--accent);
  /* full-strength --gold / --warm haloes read as neon at night: the lamp shade
     and the hearth get bled toward the panel so the room glows, never glares. */
  --scene-lamp-glow: color-mix(in srgb, var(--gold) 45%, transparent);
  --scene-fire-1: color-mix(in srgb, var(--warm) 78%, var(--bg) 22%);
  --scene-fire-2: color-mix(in srgb, var(--gold) 74%, var(--bg) 26%);
}

/* ---- voxel mount: masked reveal (ui-fluide pass, layer 1) ----
   The canvas (engine.js: <canvas class="scene-canvas">) bakes synchronously
   (200-340ms, D-012) inside mountVoxel(); room.js defers the mount itself
   (rAF + setTimeout(0)) and only adds .is-baked to .room-scene once
   mountVoxel() has actually returned -- by then the canvas already holds
   real painted pixels (engine.js's mountVoxel ends with the synchronous
   `rebuild(); start();`). Until then this rule keeps the canvas invisible so
   the CSS diorama (.room-scene-art) shows through as the placeholder. */
.room-scene .scene-canvas {
  opacity: 0;
  transition: opacity .22s cubic-bezier(0, 0, 0.2, 1);
}
.room-scene.is-baked .scene-canvas {
  opacity: 1;
}

/* D-013 rule 2: engine.js appends the canvas as the LAST child of the frame
   with no z-index of its own (z-index:auto), which would otherwise silently
   cover any float added earlier in the DOM. .room-scene has isolation:isolate
   (components.css .scene-frame), so raising these two direct children above
   that auto layer is enough regardless of DOM order: the morning banner and
   each member's floating name+status badge (room-scene-badge-anchor, see
   below) both need to read over the mounted scene. Pattern identical to
   trip-train.css / trip-plane.css's own `.scene > .scene-float { z-index: 2 }`. */
.room-scene > .scene-float,
.room-scene > .room-scene-badge-anchor {
  z-index: 2;
}

.room-scene-bg {
  position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(120% 90% at 50% 0%, var(--scene-wall-1), transparent 62%),
    linear-gradient(180deg, transparent 58%, var(--scene-floor) 58%),
    linear-gradient(160deg, var(--scene-wall-2), var(--scene-wall-1));
}

/* ---- back layer : window + bookshelf ---- */

.room-scene-window {
  position: absolute; top: 8%; left: 5%; width: 25%; height: 36%;
  border-radius: var(--r-lg);
  background: linear-gradient(180deg, var(--scene-sky-2), var(--scene-sky-1));
  border: 6px solid var(--scene-wood);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.room-scene-window::before,
.room-scene-window::after { content: ''; position: absolute; background: var(--scene-wood); }
.room-scene-window::before { left: 50%; top: 0; bottom: 0; width: 4px; transform: translateX(-50%); }
.room-scene-window::after { top: 50%; left: 0; right: 0; height: 4px; transform: translateY(-50%); }
/* was a perpetual drift (room-cloud-drift, infinite): the placeholder repli
   is on screen for a few hundred ms at most before the voxel canvas covers
   it (D-012), so a background sky detail gained nothing by looping forever
   underneath. Parked at rest inside the window frame (doctrine: purely
   decorative, out of the field of attention, becomes a static state). */
.room-scene-cloud {
  position: absolute; background: var(--scene-cloud); border-radius: 50%; opacity: .85;
}
.room-scene-cloud.c1 { width: 36%; height: 24%; top: 16%; left: 8%; }
.room-scene-cloud.c2 { width: 26%; height: 18%; top: 42%; left: 48%; }

.room-scene-shelf {
  position: absolute; top: 18%; right: 3%; width: 13%; height: 48%;
  background: var(--scene-shelf-body);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-1);
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 8% 10%;
}
.room-shelf-row { display: flex; align-items: flex-end; gap: 8%; height: 24%; border-bottom: 2px solid var(--scene-shelf-line); padding-bottom: 6%; }
.room-shelf-book { flex: 1; min-width: 2px; border-radius: 2px 2px 0 0; }

/* ---- mid layer : fireplace ---- */

.room-scene-fireplace {
  position: absolute; top: 14%; left: 39%;
  width: clamp(90px, 15%, 180px); height: clamp(160px, 32%, 240px);
}
.room-scene-fireplace-mantle {
  position: absolute; top: 0; left: -14%; width: 128%; height: 9%;
  background: var(--scene-wood-dark);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-1);
}
.room-scene-fireplace-surround {
  position: absolute; top: 7%; left: 4%; right: 4%; bottom: 0;
  background: var(--scene-fire-surround);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-1);
  display: flex; align-items: flex-end; justify-content: center;
  padding: 12% 10% 0;
}
.room-scene-fireplace-opening {
  position: relative; width: 100%; height: 72%;
  background: var(--scene-wood-dark);
  border-radius: var(--r-sm) var(--r-sm) 4px 4px;
  overflow: hidden;
  box-shadow: inset 0 8px 16px rgba(0, 0, 0, .4);
}
.room-scene-log {
  position: absolute; left: 50%; bottom: 6%; transform: translateX(-50%);
  width: 64%; height: 12%;
  background: var(--scene-wood);
  border-radius: 999px;
  box-shadow: var(--shadow-1);
}
.room-scene-flame {
  position: absolute; left: 50%; bottom: 14%; width: 48%; aspect-ratio: .65;
  transform: translateX(-50%);
  background: radial-gradient(circle at 50% 100%, var(--scene-fire-2), var(--scene-fire-1) 55%, transparent 78%);
  border-radius: 50% 50% 40% 40%;
  animation: room-flame 2.4s ease-in-out infinite;
}
/* the second tongue of flame no longer runs its own loop (room-flame-2):
   two elements pulsing over the same hearth read as one flame anyway, so
   only the front one (.room-scene-flame) still animates; this one rests at
   a fixed mid-flicker pose (doctrine: several elements pulsing alike collapse
   to a single animation). */
.room-scene-flame-2 {
  width: 28%; bottom: 18%; opacity: .82;
  transform: translateX(-50%) scaleY(1.1) scaleX(.9);
  animation: none;
}
@keyframes room-flame {
  0%, 100% { transform: translateX(-50%) scaleY(1) scaleX(1); opacity: .9; }
  45% { transform: translateX(-50%) scaleY(1.16) scaleX(.92); opacity: 1; }
  70% { transform: translateX(-50%) scaleY(.94) scaleX(1.05); opacity: .85; }
}

/* the light the fire throws on the room (gives the hearth its glow) */
/* ambient hearth light held at a fixed mid-glow instead of breathing forever
   (room-fire-glow removed): the flame itself (.room-scene-flame) already
   carries the one flicker cue this corner needs. */
.room-scene-fire-glow {
  position: absolute; left: 50%; bottom: -10%;
  width: 260%; aspect-ratio: 1;
  transform: translateX(-50%) scale(1.03);
  border-radius: 50%;
  background: radial-gradient(circle,
    transparent 0%,
    color-mix(in srgb, var(--scene-fire-2) 20%, transparent) 30%,
    transparent 65%);
  pointer-events: none;
  opacity: .8;
}

/* ---- mid layer : rug + coffee table ---- */

.room-scene-rug {
  position: absolute; left: 50%; bottom: 5%; width: 58%; height: 26%;
  transform: translateX(-50%);
  background: var(--scene-rug);
  border-radius: 50%;
  box-shadow: inset 0 0 0 8px var(--scene-rug-line);
}

.room-scene-table {
  position: absolute; left: 50%; bottom: 9%;
  transform: translateX(-50%);
  display: flex; gap: 10px; align-items: flex-end;
  padding: 8px 16px 6px;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--scene-wood) 55%, transparent);
  font-size: clamp(16px, 2vw, 20px);
  box-shadow: var(--shadow-1);
}
.room-scene-cup { position: relative; }
.room-scene-steam {
  position: absolute; top: -6px; left: 38%;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--scene-steam);
}
.room-scene-steam-2 { left: 60%; width: 4px; height: 4px; animation-delay: 1s; }

/* ---- mid layer : the crew, seated (decor only: avatar disc + cushion) ----
   Lives inside .room-scene-art now (the D-013 repli): once the voxel canvas
   is baked, these sit behind it (z-index:-1) and are only ever seen in the
   CSS fallback / placeholder phase. The name+status badge used to live in
   this same flex column (see .room-scene-badge-anchor below for its own,
   separate positioning now that it floats above the canvas instead). */

.room-scene-seat {
  position: absolute;
  display: flex; flex-direction: column; align-items: center;
}

/* ---- the floating name+status badge, positioned independently of the decor
   above (MEMBER_BADGE_POS in room.js, calibrated against the voxel scene's
   own geometry) so it can sit over the mounted canvas instead of the old CSS
   armchair. .room-scene-badge-anchor is the direct child .room-scene raises
   above the canvas (D-013 rule 2); it shrink-wraps to the badge's own size
   (only `top`/`left` set, no width), and the transform below re-centers that
   box on the anchor point and lifts it a further 6px clear of the head, so
   the badge's own rendered width/height (name length, font clamp) never
   throws off the alignment the way a fixed margin would. ---- */
.room-scene-badge-anchor {
  position: absolute;
  transform: translate(-50%, calc(-100% - 6px));
}
/* `position: relative` overrides the shared .scene-float's `position:
   absolute`: left absolute, the badge would be taken out of flow entirely,
   and .room-scene-badge-anchor (which has no explicit width/height of its
   own) would shrink-wrap to nothing, collapsing the whole anchor to 0x0 and
   breaking the transform above. Same fix as the original 2026-08-12
   integration review, re-applied to the new anchor wrapper. */
.room-scene-badge { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 6px 10px; }
.room-scene-badge b { font-size: 11.5px; font-weight: 900; color: var(--ink); }
.room-scene-badge-status { display: inline-flex; align-items: center; gap: 4px; font-size: 9.5px; font-weight: 800; white-space: nowrap; }
.room-scene-badge-status .room-status-dot { width: 6px; height: 6px; margin-left: 0; box-shadow: none; }
.room-scene-badge-status.tone-green { color: var(--success); }
.room-scene-badge-status.tone-gold { color: var(--gold); }
.room-scene-badge-status.tone-blue { color: var(--blue); }
.room-scene-badge-status.tone-idle { color: var(--muted); }
.room-scene-badge-status.tone-warm { color: var(--warm); }
.room-scene-badge-status.tone-violet { color: var(--violet); }

.room-scene-seat-avatar {
  position: relative;
  width: clamp(28px, 3.2vw, 38px); height: clamp(28px, 3.2vw, 38px);
  border-radius: 50%;
  display: grid; place-items: center;
  font-weight: 900; font-size: clamp(12px, 1.3vw, 15px);
  border: 2px solid var(--card);
  box-shadow: var(--shadow-1);
  margin-bottom: -10px;
}
.room-scene-seat-avatar.tone-green { background: var(--accent-soft); color: var(--success); }
.room-scene-seat-avatar.tone-gold { background: var(--gold-soft); color: var(--gold); }
.room-scene-seat-avatar.tone-blue { background: var(--blue-soft); color: var(--blue); }
.room-scene-seat-avatar.tone-idle { background: var(--line-soft); color: var(--muted); }
.room-scene-seat-avatar.tone-warm { background: var(--warm-soft); color: var(--warm); }
.room-scene-seat-avatar.tone-violet { background: var(--violet-soft); color: var(--violet); }

.room-crown-scene { position: absolute; top: -13px; left: 50%; transform: translateX(-50%); font-size: 12px; }

.room-scene-seat-cushion {
  width: clamp(48px, 7vw, 78px); height: clamp(30px, 4.2vw, 44px);
  border-radius: var(--r-md) var(--r-md) var(--r-sm) var(--r-sm);
  box-shadow: var(--shadow-1), inset 0 -6px 10px rgba(0, 0, 0, .08);
  border: 2px solid transparent;
}
.room-scene-seat-cushion[data-sofa="a"] { background: var(--scene-sofa-a); border-color: var(--scene-sofa-a-edge); }
.room-scene-seat-cushion[data-sofa="b"] { background: var(--scene-sofa-b); border-color: var(--scene-sofa-b-edge); }
.room-scene-seat-cushion[data-sofa="c"] { background: var(--scene-sofa-c); border-color: var(--scene-sofa-c-edge); }
.room-scene-seat-cushion[data-sofa="d"] { background: var(--scene-sofa-d); border-color: var(--scene-sofa-d-edge); }
.room-scene-seat-cushion[data-sofa="e"] { background: var(--scene-sofa-e); border-color: var(--scene-sofa-e-edge); }
.room-scene-seat-cushion[data-sofa="f"] { background: var(--scene-sofa-f); border-color: var(--scene-sofa-f-edge); }

.room-scene-seat-round .room-scene-seat-cushion {
  border-radius: 50%; width: clamp(40px, 5.6vw, 60px); height: clamp(40px, 5.6vw, 60px);
}

.room-scene-seat-monitor {
  position: absolute; left: 50%; bottom: 54px; transform: translateX(-50%);
  width: clamp(30px, 4vw, 44px); height: clamp(20px, 2.6vw, 30px);
  border-radius: 6px;
  background: var(--scene-monitor);
  border: 2px solid var(--scene-monitor-edge);
  box-shadow: 0 0 14px var(--scene-monitor);
}

/* ---- foreground layer : plants + lamp ---- */

.room-scene-plant { position: absolute; bottom: 2%; display: flex; flex-direction: column; align-items: center; }
.room-scene-plant-l { left: 1.5%; }
.room-scene-plant-r { right: 1.5%; }

.room-plant-leaves { position: relative; width: clamp(46px, 6vw, 70px); height: clamp(46px, 6vw, 70px); margin-bottom: -6px; }
.room-plant-leaf { position: absolute; width: 62%; height: 62%; border-radius: 50% 50% 50% 6px; transform-origin: bottom center; }
/* background foliage held at its resting mid-sway angle instead of swaying
   forever (room-leaf-sway-1/2/3 removed): six leaves pulsing at once behind
   a placeholder that is on screen for a few hundred ms was pure decoration
   outside the field of attention (doctrine). */
.room-plant-leaf:nth-child(1) { left: 8%; bottom: 0; background: var(--scene-plant-leaf); transform: rotate(-1deg); }
.room-plant-leaf:nth-child(2) { left: 30%; bottom: 14%; background: var(--scene-plant-leaf-2); transform: rotate(15deg); }
.room-plant-leaf:nth-child(3) { left: -6%; bottom: 10%; background: var(--scene-plant-leaf); opacity: .9; transform: rotate(-23deg); }

.room-plant-pot {
  width: clamp(26px, 3.4vw, 40px); height: clamp(18px, 2.4vw, 28px);
  background: var(--scene-plant-pot);
  border-radius: 4px 4px 12px 12px;
  box-shadow: var(--shadow-1);
}

.room-scene-lamp {
  position: absolute; right: 5%; bottom: 3%;
  width: 6px; height: clamp(70px, 10vw, 120px);
  background: var(--scene-wood);
  border-radius: 999px;
}
.room-scene-lamp::after {
  content: ''; position: absolute; top: -14px; left: 50%; transform: translateX(-50%);
  width: 34px; height: 20px;
  background: var(--scene-lamp-shade);
  border-radius: 40% 40% 60% 60% / 30% 30% 70% 70%;
  box-shadow: 0 0 18px var(--scene-lamp-glow);
}

/* ---- UI overlay : morning banner (top-left), a real .room-scene direct
   child raised above the canvas (D-013 rule 2). The neon sign below is NOT
   part of this overlay any more: it now lives inside .room-scene-art
   (decor-only), since lounge.js's own voxel scene bakes a real
   "Focus / Create / Explore" neon on the fireplace chimney breast (D-012);
   floating this CSS one above the canvas as well would just double it. ---- */

.room-scene-banner {
  position: absolute; top: 5%; left: 4%; max-width: 240px;
  display: flex; flex-direction: column; gap: 2px;
}
.room-scene-banner-title { font-weight: 800; font-size: 13px; color: var(--ink); line-height: 1.3; }
.room-scene-banner-sub { font-weight: 700; font-size: 11px; color: var(--muted); line-height: 1.3; }

.room-scene-neon {
  position: absolute; top: 5%; right: 5%;
  display: flex; flex-direction: column; align-items: flex-end;
  font-weight: 900; letter-spacing: .08em; text-transform: uppercase;
  font-size: clamp(12px, 1.8vw, 19px);
  line-height: 1.18;
  color: var(--scene-neon);
  text-shadow: 0 0 8px var(--scene-neon-glow), 0 0 20px var(--scene-neon-glow);
}
.room-scene-neon span { display: block; }
/* the flicker (room-neon-flicker) is gone: this sign is decor-only inside the
   D-013 repli, already noted as redundant with lounge.js's own baked neon,
   so it never needed a loop of its own on top of that. */

.room-scene-fly-layer { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 5; }
.room-fly-emoji {
  position: absolute; bottom: 8%;
  font-size: 22px;
  animation: room-fly-up 1.5s ease-out forwards;
}
@keyframes room-fly-up {
  0% { transform: translate(0, 0) scale(.7); opacity: 0; }
  15% { opacity: 1; transform: translate(0, -10%) scale(1); }
  100% { transform: translate(var(--room-fly-drift, 0), -220%) scale(1.1); opacity: 0; }
}

@media (max-width: 720px) {
  .room-scene { min-height: 380px; }
  .room-scene-shelf { display: none; }
  .room-scene-banner { max-width: 58%; }
  .room-scene-banner-title { font-size: 11.5px; }
  .room-scene-banner-sub { font-size: 10px; }
}

/* ============================================================
   REACTIONS + CONTROLS
   ============================================================ */

.room-reactions {
  display: flex; flex-wrap: wrap; gap: 8px;
  justify-content: center;
}
.room-reaction-btn {
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center; font-size: 19px;
  background: var(--card); border: 1px solid var(--line-soft);
  box-shadow: var(--shadow-1);
  transition: transform .15s ease, background .2s ease;
}
.room-reaction-btn:hover { transform: translateY(-2px); background: var(--bg-2); }
.room-reaction-btn:active { transform: scale(.92); }
.room-reaction-add { color: var(--muted); font-size: 17px; }

.room-controls {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  justify-content: center;
}
.room-ambience-pill { color: var(--ink-soft); }
.room-ctrl-icon.is-off { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
.room-start-btn { flex: 1 1 200px; max-width: 260px; }

@media (max-width: 480px) {
  .room-controls { justify-content: stretch; }
  .room-start-btn { flex-basis: 100%; max-width: none; order: -1; }
}

/* ============================================================
   RIGHT COLUMN: trips + chat
   ============================================================ */

.room-trips-card { display: flex; flex-direction: column; gap: 10px; }

.room-tabs { display: flex; gap: 6px; }
.room-tab {
  flex: 1;
  padding: 7px 8px; border-radius: var(--r-sm);
  font-size: 12px; font-weight: 800; color: var(--muted);
  background: var(--bg-2);
  transition: background .2s ease, color .2s ease;
}
.room-tab.active { background: var(--accent-soft); color: var(--accent); }

.room-trip-list { list-style: none; display: flex; flex-direction: column; gap: 12px; min-height: 40px; }
.room-trip-row {
  display: flex; flex-direction: column; gap: 6px;
  padding: 10px 12px; border-radius: var(--r-sm);
  background: var(--bg-2);
}
.room-trip-top { display: flex; align-items: center; gap: 8px; }
/* figures ride the shared .timer-digits class (added in room.js): this only
   sizes them; tabular-nums and weight come from components.css */
.room-trip-time { font-size: 12px; color: var(--ink-soft); letter-spacing: 0; flex-shrink: 0; }
.room-trip-name { font-weight: 800; font-size: 13.5px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.room-trip-bottom { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.room-trip-status {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 800;
}
.room-trip-status .room-status-dot { margin-left: 0; box-shadow: none; }
.room-trip-status.tone-green { color: var(--success); }
.room-trip-status.tone-gold { color: var(--gold); }
.room-trip-status.tone-idle { color: var(--muted); }
.room-trip-join { flex-shrink: 0; padding: 5px 12px; font-size: 11.5px; }
.room-trip-empty {
  text-align: center; color: var(--muted); font-size: 12.5px; font-weight: 700;
  padding: 14px 4px;
}

.room-chat-card { display: flex; flex-direction: column; gap: 10px; }
.room-chat-list {
  display: flex; flex-direction: column; gap: 12px;
  max-height: 260px; overflow-y: auto;
  margin-top: 6px; padding-right: 2px;
}
.room-chat-msg { display: flex; gap: 8px; }
.room-chat-body { min-width: 0; flex: 1; }
.room-chat-head { display: flex; align-items: baseline; gap: 6px; }
.room-chat-who { font-weight: 800; font-size: 12.5px; }
.room-chat-at { font-size: 10.5px; color: var(--muted); font-weight: 700; }
.room-chat-text {
  font-size: 13px; color: var(--ink-soft); margin-top: 1px;
  word-break: break-word;
}
.room-chat-hearts {
  display: inline-flex; margin-top: 3px;
  font-size: 11px; font-weight: 800; color: var(--warm);
}

.room-chat-input-row { display: flex; gap: 8px; align-items: center; }
.room-chat-input {
  flex: 1; min-width: 0;
  padding: 10px 13px; border-radius: var(--r-md);
  background: var(--bg-2); border: 1.5px solid var(--line-soft);
  font-size: 13.5px;
  transition: border-color .2s ease;
}
.room-chat-input:focus { outline: none; border-color: var(--accent); }
.room-chat-send { flex-shrink: 0; }

@media (prefers-reduced-motion: reduce) {
  /* only two loops are left running on this screen at all (see the doctrine
     comments above each removed one: cloud drift, the second flame tongue,
     the fire-glow breathe, the leaf sway and the neon flicker are all static
     now). room-fly-emoji is a one-shot (`forwards`, JS-triggered on a
     reaction click), not a loop, but it is still motion the user asked to
     avoid, so it is silenced here too. */
  .room-scene-flame,
  .room-fly-emoji {
    animation: none !important;
  }
  /* L-032-style bug this pass fixes: .room-scene-steam / -steam-2 carry the
     shared .puff class (components.css, out of this screen's perimeter),
     whose own @keyframes puff has NO reduced-motion guard of its own. Left
     alone, the coffee steam kept looping under prefers-reduced-motion,
     reading as a stroboscope for a user who explicitly asked for less
     motion. Same specificity as .puff (one class each), later in the
     cascade (screens/*.css loads after components.css), so this rule wins
     on source order alone, and !important removes any doubt. */
  .room-scene-steam,
  .room-scene-steam-2 {
    animation: none !important;
  }
  /* the global net (base.css) clamps transition-duration to .01ms already,
     but never touches a residual transition-delay; this screen sets none on
     its one JS-gated reveal, so appearance is immediate the instant
     .is-baked lands, no fade, no residual delay left to the net (same
     reasoning as shop.css's identical rule). */
  .room-scene .scene-canvas {
    transition: none;
  }
}
