/* ---------- the shared room look: each room's shell (wall, baseboard, floor), the lens vignette, the
   help caption, the switch plates (rooms.js and roomshell.js build the parts) ---------- */

/* ---------- the lens ----------
   A still vignette over the whole view (#lens, a body child rooms.js adds after #room): it only
   darkens, and only toward the corners, the way a camera lens falls off. It lies over the furniture
   and the switch plates as much as the wall, so nothing at the edges looks cut out. No warm wash. */
#lens {
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  background: radial-gradient(ellipse 80% 75% at 50% 46%, transparent 58%, rgb(12 6 2 / .2) 100%);
}

/* ---------- the help caption ----------
   rooms.js moves #help out of #room to sit above the lens, sets it in key caps, and fades it out of
   the way (.idle) a few seconds after you walk into a room; the pointer near the bottom, ? or F1
   bring it back. It isn't part of the room, so the dark doesn't fall on it: it just steps back.
   Replaces tv.css's #help footer line and hifi.css's half-dimmed opacity. The scrim is the
   caption's own ::before, so it comes and goes with it; it reaches a little past the text box and
   fades out before its edges, so no straight side shows on the floor. */
#help {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 7;
  width: fit-content;
  max-width: min(1240px, 100vw - 32px);
  margin: 0 auto;
  padding: 20px 32px 8px;
  text-align: center;
  text-wrap: balance;
  font: 400 13px/1.45 'Archivo Narrow', sans-serif;
  letter-spacing: .3px;
  color: rgb(240 228 210 / .68);
  text-shadow: 0 1px 1px rgb(0 0 0 / .5);
  pointer-events: none; /* faded out, it mustn't catch clicks meant for the room under it */
  opacity: calc(1 - var(--here-dark, 0) * .7);
  transition: opacity .35s;
}
#help::before { content: ''; position: absolute; inset: 0 -8%; z-index: -1; background: radial-gradient(ellipse 50% 100% at 50% 100%, rgb(10 6 3 / .5), rgb(10 6 3 / .28) 55%, transparent); }
#help.idle { opacity: 0; transition-duration: 1.4s; }
#help b { font-weight: 700; font-size: 11px; letter-spacing: 1px; text-transform: uppercase; color: rgb(255 210 122 / .85); }
#help kbd {
  display: inline-block;
  min-width: 15px;
  margin: 0 1px;
  padding: 0 4px;
  border-radius: 3px;
  font: 700 10.5px/15px 'Archivo Narrow', sans-serif;
  letter-spacing: .4px;
  text-align: center;
  text-shadow: none;
  color: #e9dcc4;
  background: linear-gradient(#3a332c, #241f1a);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .12), 0 1px 0 #0b0907;
  vertical-align: 1px;
}

/* ---------- each room's own shell: wall, baseboard and floor (roomshell.js) ----------
   Built into each stage under everything (z -2: below the hi-fi's legs at -1 and the rug's shade)
   and sized like the room's .room-dark (105vw/s x 112vh/s, centred on the stage), so it slides with
   its room and takes the room's darkness and light. --fl is the floor line in the shell's own box
   (the shell's middle is the stage's, y 450). The paper, the panels and the floor's picture are set
   by roomshell.js as plain url() backgrounds, never next to a var(). */
.room-shell {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(105vw / var(--s, 1));
  height: calc(112vh / var(--s, 1));
  translate: -50% -50%;
  z-index: -2;
  pointer-events: none;
  --floor-y: 740px;
  --bb: 46px; /* the baseboard's height */
  --fl: calc(56vh / var(--s, 1) + var(--floor-y) - 450px);
}
/* (roomshell.js keeps the booth's floor line level with the TV room's on the screen) */
.room-shell[data-room="dj"] { --floor-y: 760px; --bb: 30px; }
/* tv.js fit() shifts the TV stage 15px right (scale(s) translateX(15px)): its shell and its dark go
   back onto their own 105vw slot. The picture's halo is placed in the dark layer's box, so it moves
   the other way to stay on the set (tv.css had calc(50% - 142px)). Both reach 2px past each side of
   the slot, under the neighbours' (which are clipped to theirs and paint over it), so no hairline of
   the bare background opens at a seam during the slide. */
#stage > .room-shell { translate: calc(-50% - 15px) -50%; width: calc(105vw / var(--s, 1) + 4px); }
#stage > .room-dark { translate: calc(-50% - 15px) -50%; --sx: calc(50% - 127px); width: calc(105vw / var(--s, 1) + 4px); }

/* the wall: the paper (or the booth's panels) from roomshell.js, then the fall of the room's light
   down it as before (the old wall ran #c88a52 to #a96d3d), the lens's slow falloff toward the bottom
   of the view folded in. Anchored to the floor line, so it's the same in any window. */
.rs-wall { position: absolute; left: 0; right: 0; top: 0; height: var(--fl); background: #b98050; }
.rs-wall::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top, rgb(58 24 4 / .17), rgb(58 24 4 / .07) 260px, rgb(58 24 4 / 0) 820px); }
.room-shell[data-room="dj"] .rs-wall { background: #0c0d10; }
.room-shell[data-room="dj"] .rs-wall::after { background: linear-gradient(to top, rgb(0 0 0 / .12), rgb(0 0 0 / 0) 620px); }

/* the floor: its picture (from just above the floor line, under the baseboard) goes on in stage px,
   placed by roomshell.js; until it's drawn, the floor's mean colour */
.rs-floor { position: absolute; left: 0; right: 0; top: var(--fl); bottom: 0; background: #4e3520; }
.rs-floor-img { position: absolute; background: 0 0 / 100% 100% no-repeat; opacity: 0; transition: opacity .6s; }
.rs-floor-img.ready { opacity: 1; }
body.instant .rs-floor-img { transition: none; }
.room-shell[data-room="dj"] .rs-floor { background: linear-gradient(#08080a, #131316 30px, #111114); }

/* the baseboard: stained walnut, its grain along it. From the top: the rounded cap lit from above
   (only a whisper of a joint against the wall: lit from above, the edge catches light, it isn't a line), the cap's shadow on the face, the face falling off a touch
   toward the floor, the shoe moulding's lit round and its foot in shade. Under the room's dark, so
   the lamp and the picture light its cap at their own strength. */
.rs-base {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--fl) - var(--bb));
  height: var(--bb);
  background:
    linear-gradient(rgb(255 228 186 / .42) 0, rgb(255 228 186 / .5) .8px, rgb(255 228 186 / .3) 1.5px, rgb(255 228 186 / .1) 3px, rgb(255 228 186 / 0) 4.5px, rgb(20 10 4 / .03) 5.5px, rgb(20 10 4 / .24) 7px, rgb(20 10 4 / 0) 10px) 0 0 / 100% 10px no-repeat,
    linear-gradient(rgb(255 236 210 / .06), rgb(255 236 210 / 0) 35%, rgb(0 0 0 / .18)) 0 10px / 100% calc(100% - 17px) no-repeat,
    linear-gradient(rgb(0 0 0 / .34) 0, rgb(0 0 0 / 0) 1px, rgb(255 228 186 / .2) 1.5px, rgb(255 228 186 / .05) 3.5px, rgb(0 0 0 / .28) 5.5px, rgb(0 0 0 / .6) 7px) 0 100% / 100% 7px no-repeat,
    linear-gradient(rgb(120 54 14 / .2), rgb(120 54 14 / .2)),
    url(tex/teak-dark.jpg) 50% -296px / 1000px 1000px,
    #4a3220;
}
/* the booth's: black-painted, a dull sheen along its top */
.room-shell[data-room="dj"] .rs-base { background: linear-gradient(rgb(0 0 0 / .6) 0 1px, rgb(200 210 230 / .14) 1px, rgb(200 210 230 / 0) 3px, rgb(0 0 0 / .3) 5px, rgb(0 0 0 / 0) 8px) 0 0 / 100% 8px no-repeat, linear-gradient(#16171a, #0d0e10); }

/* the door casing between rooms: half of it at each side of a room's shell, in the hidden 2.5vw
   margin past the window's edge, so it shows only as you walk through, when the two halves meet.
   A moulded profile (flat face, a lit fillet, the bead, the back band) and its shadow on the wall,
   a plinth block where the baseboard butts into it. The booth's side is painted black. */
.room-shell::before, .room-shell::after {
  content: '';
  position: absolute;
  top: 0;
  height: var(--fl);
  width: calc(min(40px, 2.5vw - 2px) / var(--s, 1));
  z-index: 1;
  --cas: #6e4c30 0, #7a5636 32%, #6a492d 50%, #b58a5c 56%, #d2a877 60%, #8a6440 70%, #5a3c24 80%, #3e2816 88%, rgb(20 10 4 / .5) 89%, rgb(20 10 4 / 0) 100%;
  /* the plinth block: flat, a little proud of the casing, its top edge lit */
  --plinth: linear-gradient(rgb(255 228 186 / .38) 0 1px, rgb(20 10 4 / .35) 1px 2.5px, rgb(20 10 4 / 0) 4px, rgb(20 10 4 / 0) 75%, rgb(20 10 4 / .35)) var(--px, 0) 100% / 89% calc(var(--bb) + 14px) no-repeat, linear-gradient(#654529, #573a22) var(--px, 0) 100% / 89% calc(var(--bb) + 14px) no-repeat;
}
.room-shell::before { left: 0; background: linear-gradient(rgb(58 24 4 / 0) 30%, rgb(58 24 4 / .25)), var(--plinth), linear-gradient(90deg, var(--cas)); }
.room-shell::after { right: 0; --px: 100%; background: linear-gradient(rgb(58 24 4 / 0) 30%, rgb(58 24 4 / .25)), var(--plinth), linear-gradient(-90deg, var(--cas)); }
.room-shell[data-room="dj"]::before, .room-shell[data-room="dj"]::after { --plinth: linear-gradient(rgb(200 210 230 / .14) 0 1px, rgb(0 0 0 / .4) 1px 2.5px, transparent 4px) var(--px, 0) 100% / 87% calc(var(--bb) + 14px) no-repeat, linear-gradient(#1a1b1e, #121315) var(--px, 0) 100% / 87% calc(var(--bb) + 14px) no-repeat; --cas: #18191c 0, #1d1e22 50%, #34363c 58%, #1a1b1e 70%, #0e0f11 86%, rgb(0 0 0 / .5) 88%, rgb(0 0 0 / 0) 100%; }

/* (#room was the shared wall behind all three rooms; each room has its own now, so it's only a dark
   ground, and no longer slides its background) */
#room, body[data-view] #room { transition: none; }

/* the hi-fi stays in its own room too (rooms sit 105vw apart): its shell, its rug's shade and the
   rest are clipped to its slot, so in a narrow window nothing of it shows in the TV room beside it */
#hifi-stage { clip-path: inset(calc(-60vh / var(--s, 1)) calc(500px - 52.5vw / var(--s, 1))); }

/* ---------- the switch plates ----------
   Two cream plates on the wall: a two-gang plate of toggles that take you to the other two rooms,
   and a slide dimmer for this room's lights. Moulded urea with a padded face: domed, its edge
   rolling over (lit along the top, in shade along the bottom), standing a few millimetres off the
   wall on a soft shadow. Slotted screws painted with the plate; tapered bats in the openings, each
   with a little amber neon locator; Dymo labels. rooms.js sizes them for the room's scale (--plate-k)
   and places them (top right; top left in the DJ booth, clear of its monitors), and they darken
   exactly like the wall, through a layer over them in the room's own night colour: only the neon
   locators and the dimmer's light stay lit. Replaces hifi.css's flat plates and their brightness()
   filter (which glowed in the dark, and dimmed the locator light too). */
#viewSwitch, #room-dimmer {
  --screw: radial-gradient(circle 3.4px, #fffdf6 0, #e6dcc4 45%, #b9ac8c 85%, rgb(140 125 95 / .9) 100%, transparent 101%);
  --slot-h: linear-gradient(97deg, transparent 0 41%, rgb(70 52 30 / .8) 41% 59%, transparent 59%);
  --slot-v: linear-gradient(8deg, transparent 0 41%, rgb(70 52 30 / .8) 41% 59%, transparent 59%);
  scale: var(--plate-k, 1);
  transform-origin: 0 0;
  filter: none;
  padding: 0;
  border-radius: 7px;
  box-shadow:
    inset 0 1.5px 1px -.5px rgb(255 255 255 / .95),
    inset 1.5px 0 1.5px -.5px rgb(255 255 255 / .5),
    inset 0 -2.5px 2.5px -1px rgb(110 88 55 / .5),
    inset -2px 0 2px -1px rgb(110 88 55 / .3),
    inset 0 0 0 .5px rgb(150 128 92 / .45),
    1px 2.5px 3px rgb(28 14 4 / calc(.38 * (1 - var(--here-dark, 0)))),
    0 0 0 .5px rgb(70 46 20 / calc(.3 * (1 - var(--here-dark, 0))));
  color: #4a3a28;
  transition: opacity .18s;
}
#viewSwitch.moving, #room-dimmer.moving { opacity: 0; }
/* the room's dark over each plate (the screws, bats, cap and labels all go under it) */
#viewSwitch::before { content: none; }
#viewSwitch::after, #room-dimmer::after {
  content: '';
  position: absolute;
  inset: -1px; /* a pixel past the plate's edge: drawn exactly on it, the two antialiased edges left a lit hairline round the plate in the dark */
  width: auto;
  height: auto;
  margin: 0;
  z-index: 2;
  border-radius: 8px;
  pointer-events: none;
  box-shadow: none;
  background: rgb(var(--here-night, 5 5 5) / var(--here-dark, 0));
  transition: background .4s;
}

/* the two-gang plate: per gang a screw above and below the opening, the bat, the label */
#viewSwitch {
  display: flex;
  gap: 0;
  width: 84px;
  height: 102px;
  background:
    var(--slot-h) 18px 17px / 7px 7px no-repeat, var(--screw) 17.6px 16.6px / 7.8px 7.8px no-repeat,
    var(--slot-v) 60px 17px / 7px 7px no-repeat, var(--screw) 59.6px 16.6px / 7.8px 7.8px no-repeat,
    var(--slot-v) 18px 63px / 7px 7px no-repeat, var(--screw) 17.6px 62.6px / 7.8px 7.8px no-repeat,
    var(--slot-h) 60px 63px / 7px 7px no-repeat, var(--screw) 59.6px 62.6px / 7.8px 7.8px no-repeat,
    radial-gradient(120% 90% at 35% 25%, #fbf5e6, #ece2c9 60%, #d6c9aa);
}
.vs-toggle { position: relative; width: 42px; height: 100%; padding: 0; border: 0; background: none; cursor: pointer; font: inherit; color: inherit; letter-spacing: inherit; }
/* the opening, and the switch's pivot in it */
.vs-toggle .slot {
  position: absolute;
  left: 17px;
  top: 30px;
  width: 8px;
  height: 22px;
  margin: 0;
  border-radius: 2px;
  background: radial-gradient(ellipse 60% 30% at 50% 50%, #e9dfc7 0 45%, #a99a78 70%, transparent 72%), linear-gradient(#16110b, #3a2e20 60%, #2a2016);
  box-shadow: inset 0 1.5px 2px rgb(0 0 0 / .8), 0 .5px 0 rgb(255 255 255 / .7);
}
/* the bat's shadow on the plate, under and to the right of it (under the opening and the bat too) */
.vs-toggle .slot::after { content: ''; position: absolute; z-index: -1; left: -1px; top: 14px; width: 12px; height: 16px; border-radius: 40%; background: radial-gradient(ellipse 50% 50% at 55% 50%, rgb(70 48 20 / .32), rgb(70 48 20 / 0) 100%); pointer-events: none; transition: height .15s; }
/* the bat, pointing down (off: you're not in that room), tapered from its pivot to a rounded tip
   and lit like a cylinder. Lifting it a little (about to throw it), it tips toward you and looks
   shorter. (Its size changes, not a transform. Its neon is beside it, not in it: the bat's taper is
   a clip-path, which makes it a stacking context, and would keep the neon under the plate's dark.) */
.vs-toggle .lever {
  position: absolute;
  left: .5px;
  right: auto;
  top: 9px;
  width: 7px;
  height: 18px;
  border-radius: 2px 2px 3.5px 3.5px / 2px 2px 3px 3px;
  clip-path: polygon(0 0, 100% 0, 84% 100%, 16% 100%);
  background: radial-gradient(ellipse 60% 22% at 50% 92%, rgb(255 255 255 / .8), transparent), linear-gradient(90deg, #b4a582, #fffbf1 36%, #f1e7d0 58%, #a8997a);
  box-shadow: none;
  transition: height .15s;
}
.vs-toggle:hover .lever { top: 9px; height: 13px; }
.vs-toggle:hover .slot::after { height: 11px; }
/* the neon locator in the bat: the one thing on the plate that gives off light */
.vs-toggle .neon { position: absolute; left: 3px; top: 19px; z-index: 3; width: 2px; height: 5px; border-radius: 1px; background: #ff9a3a; box-shadow: 0 0 2px rgb(255 140 50 / .6); opacity: calc(.3 + var(--here-dark, 0) * .7); }
.vs-toggle:hover .neon { top: 16px; height: 3px; }

/* Dymo labels: embossed tape, its letters stretched pale */
.vs-toggle .lbl, #room-dimmer .dim-lbl {
  position: absolute;
  left: 50%;
  display: block;
  width: max-content;
  margin: 0;
  padding: 1.5px 3.5px 1px 4px;
  font: 700 8px/9px 'Archivo Narrow', sans-serif;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: #ece8df;
  background: linear-gradient(rgb(255 255 255 / .18), rgb(255 255 255 / .03) 45%, rgb(0 0 0 / .22)), #1c1c1f;
  border-radius: 1px;
  box-shadow: 0 .5px 1px rgb(30 18 6 / .5), inset 0 .5px 0 rgb(255 255 255 / .14);
  text-shadow: 0 -.5px 0 rgb(0 0 0 / .55), 0 .5px 0 rgb(255 255 255 / .22);
}
.vs-toggle .lbl { top: 78px; translate: -50% 0; rotate: -1.2deg; }
.vs-toggle + .vs-toggle .lbl { rotate: .8deg; }

/* the slide dimmer: a one-gang plate, the locator light above the slot, the slider's cap */
#room-dimmer {
  display: block;
  width: 46px;
  height: calc(var(--dim-slot, 70px) + 72px);
  gap: 0;
  background:
    var(--slot-h) 19.5px 4.5px / 7px 7px no-repeat, var(--screw) 19.1px 4.1px / 7.8px 7.8px no-repeat,
    var(--slot-v) 19.5px calc(100% - 4.5px) / 7px 7px no-repeat, var(--screw) 19.1px calc(100% - 4.1px) / 7.8px 7.8px no-repeat,
    radial-gradient(130% 90% at 35% 22%, #fbf5e6, #ece2c9 60%, #d6c9aa);
}
#room-dimmer .dim-led {
  position: absolute;
  left: 20.5px;
  top: 14.5px;
  z-index: 3;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #ffd9a8, #ff9a3a 55%, #d8661a);
  box-shadow: 0 0 0 1px rgb(120 90 50 / .35), 0 0 2px rgb(255 138 42 / .7);
}
#room-dimmer .dim-slot, body[data-view] #room-dimmer .dim-slot {
  position: absolute;
  left: 19px;
  top: 30px;
  width: 8px;
  height: var(--dim-slot, 70px);
  border-radius: 3px;
  background: linear-gradient(90deg, #120d08, #2c2217 50%, #120d08);
  box-shadow: inset 0 2px 3px rgb(0 0 0 / .85), 0 .5px 0 rgb(255 255 255 / .7), 0 -.5px 0 rgb(120 95 60 / .35);
}
/* the cap: ribbed for the thumb, standing proud on its stem, its shadow on the plate below it */
#room-dimmer .dim-cap {
  left: -8px;
  right: -8px;
  height: 14px;
  margin-top: -7px;
  z-index: auto;
  border-radius: 3px;
  background:
    repeating-linear-gradient(rgb(120 100 70 / 0) 0 2px, rgb(120 100 70 / .28) 2px 2.6px, rgb(255 255 255 / .5) 2.6px 3px) 3px 2px / calc(100% - 6px) 10px no-repeat,
    linear-gradient(#fffbf0, #eee4cc 55%, #c6b896);
  box-shadow: inset 0 1px 0 #fff, inset 0 -1px 1px rgb(110 88 55 / .4), 0 2px 2.5px rgb(50 30 10 / .45);
}
#room-dimmer .dim-cap::after { content: none; }
#room-dimmer .dim-lbl { top: calc(var(--dim-slot, 70px) + 42px); translate: -50% 0; rotate: .9deg; }
