/* The projected surface and the studio world.
   The world is 260×170 stage units (the targets' viewBox). --u is one unit in px,
   chosen so the stage covers the viewport (slice), the same crop as the targets. */

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; background: var(--wall-2); }
body { font-family: var(--font-body); color: var(--ink); -webkit-font-smoothing: antialiased; }

#projected {
  position: fixed; inset: 0; overflow: hidden;
  --u: max(calc(100vw / 260), calc(100vh / 170));
  perspective: 1600px;
}

#world {
  position: absolute; left: 50%; top: 50%;
  width: calc(260 * var(--u)); height: calc(170 * var(--u));
  transform: translate(-50%, -50%);
  transform-style: preserve-3d;
  --drain: 0;      /* 0 thriving … 1 bleeding */
  --slump: 0;      /* posture, 0 upright … 1 collapsed */
  --cam-x: 0px; --cam-y: 0px; --cam-z: 1; --cam-dur: 2.4s;
}

.room {
  position: absolute; inset: 0; overflow: hidden;
  transform: translate(var(--cam-x), var(--cam-y)) scale(var(--cam-z));
  transform-origin: 50% 60%;
  filter: saturate(calc(1 - .42 * var(--drain))) brightness(calc(1 - .07 * var(--drain)));
  transition: transform var(--cam-dur, 2.4s) var(--ease-float), filter var(--mood-dur) ease;
}

.plane { position: absolute; inset: 0; pointer-events: none; }
.plane > svg { position: absolute; display: block; overflow: visible; }
.plane > svg.bg, .plane > svg.crowd { left: 0; top: 0; width: 100%; height: 100%; }

/* a seated desk unit: own svg so the compositor only repaints the one that moves */
.unit {
  left: calc(var(--x) * var(--u));
  top: calc(var(--y) * var(--u));
  width: calc(270 * var(--s) * var(--u));
  height: calc(170 * var(--s) * var(--u));
}

/* cold cast at low effort: a multiply wash, never darkness */
.cold {
  position: absolute; inset: 0; pointer-events: none;
  background: var(--cold); mix-blend-mode: multiply;
  opacity: calc(.24 * var(--drain));
  transition: opacity var(--mood-dur) ease;
}

/* ---- the transition: stage lifts and tilts into the isometric floor, time
   skips, and it settles back. Planes move at their own rates (parallax). ---- */
.room { --lift: 0; }
.plane { transition: transform .65s var(--ease-float); }
.iso { position: absolute; inset: 0; opacity: 0; pointer-events: none; background: var(--wall-2);
  transform: rotateX(-22deg) translateY(10%) scale(1.12); transform-origin: 50% 55%;
  transition: opacity .35s ease, transform .65s var(--ease-float); }
.iso > svg { position: absolute; inset: 0; width: 100%; height: 100%; }
#world.lifting .room, #world.iso-hold .room {
  transform: translate(var(--cam-x), var(--cam-y)) scale(var(--cam-z)) rotateX(38deg) rotateZ(-10deg) translateY(-9%) scale(.9);
  opacity: 0;
  transition: transform .65s var(--ease-float), opacity .32s ease .28s;
}
#world.lifting .plane[data-plane="far"]   { transform: translateY(-2.5%); }
#world.lifting .plane[data-plane="mid"]   { transform: translateY(-5.5%); }
#world.lifting .plane[data-plane="front"] { transform: translateY(-10%); }
#world.lifting .plane[data-plane="over"]  { transform: translateY(-12%); }
#world.lifting .iso, #world.iso-hold .iso { opacity: 1; transform: none; transition: opacity .35s ease .25s, transform .65s var(--ease-float); }
#world.settling .room { transition: transform .65s var(--ease-float), opacity .3s ease .1s; }
#world.settling .iso { opacity: 0; transform: rotateX(-22deg) translateY(10%) scale(1.12); transition: opacity .3s ease .15s, transform .65s var(--ease-float); }
#world.settling .plane { transition: transform .65s var(--ease-float); }

/* the time-skip chip in the iso view */
.skip { position: absolute; left: 50%; top: 9%; transform: translate(-50%, -1.2vw); opacity: 0; transition: opacity .3s ease, transform .5s var(--ease-float); }
#world.iso-hold .skip { opacity: 1; transform: translate(-50%, 0); transition-delay: .05s; }
.skip-label { display: inline-block; font-family: var(--font-display); font-size: clamp(22px, 2.4vw, 56px); letter-spacing: .12em; color: var(--gold);
  background: var(--slate); padding: .35em .9em .4em; border-radius: .5em; }
.skip-label:empty { display: none; }
.iso-clock .clock-hands { transform-box: fill-box; transform-origin: 50% 88%; }
#world.iso-hold .hand-m { animation: hand-spin .9s var(--ease-float) forwards; }
#world.iso-hold .hand-h { animation: hand-spin 1.4s var(--ease-float) forwards; }
@keyframes hand-spin { to { transform: rotate(720deg); } }
.hand-m, .hand-h { transform-box: fill-box; transform-origin: 50% 88%; }
.iso-unit.left .iso-laptop .screen-content { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .room, .cold, .plane, .iso, .skip { transition: none; }
  #world.iso-hold .hand-m, #world.iso-hold .hand-h { animation: none; }
}

/* ---- mood: the studio is the hidden meter ---- */
.clutter { opacity: 0; translate: 0 -2.5px; transition: opacity var(--mood-dur) ease, translate var(--mood-dur) var(--ease-out); }
.clutter.on { opacity: 1; translate: 0 0; }

.leaf { transform-box: fill-box; transform-origin: 0% 50%; rotate: calc(var(--slump) * var(--dd, 1) * 26deg); transition: rotate var(--mood-dur) ease; }

.w-sun, .w-cloud, .w-over { transition: opacity var(--mood-dur) ease; }
.w-cloud { opacity: 0; } .w-over { opacity: 0; }
.mood-steady .w-cloud { opacity: .7; }
.mood-flat .w-cloud { opacity: 1; } .mood-flat .w-sun { opacity: .45; } .mood-flat .w-over { opacity: .3; }
.mood-draining .w-cloud, .mood-bleeding .w-cloud { opacity: 1; }
.mood-draining .w-sun, .mood-bleeding .w-sun { opacity: 0; }
.mood-draining .w-over { opacity: .62; } .mood-bleeding .w-over { opacity: .8; }

.screen-content .bar { transform-box: fill-box; transform-origin: 0% 50%; transition: transform var(--mood-dur) ease; }
.mood-draining .screen-content .bar { transform: scaleX(.62); }
.mood-bleeding .screen-content .bar { transform: scaleX(.42); }
.mood-bleeding .screen-content { opacity: .7; }
.cur { animation: cursor 1.1s steps(1, end) infinite; }
@keyframes cursor { 50% { opacity: 0; } }

.steam path { transform-box: fill-box; transform-origin: 50% 100%; animation: steam 2.8s var(--ease-float) infinite; }
.steam path:nth-child(2) { animation-delay: -.9s; } .steam path:nth-child(3) { animation-delay: -1.8s; }
@keyframes steam { 0%, 100% { transform: translateY(0) scaleY(1); opacity: .45; } 50% { transform: translateY(-1.6px) scaleY(1.15); opacity: .25; } }
.steam { transition: opacity var(--mood-dur) ease; }
.mood-draining .steam, .mood-bleeding .steam { opacity: 0; }

.tw { animation: twinkle 2.2s ease-in-out infinite; }
@keyframes twinkle { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
.mood-draining .tw, .mood-bleeding .tw { animation: none; opacity: .6; }

.lamp-cone { transition: opacity var(--mood-dur) ease; }
.mood-thriving .lamp-cone, .mood-steady .lamp-cone { opacity: 0; }

/* the bug swarm: beetles hatch as effort drains; each drifts, twitches and glitches on its own clock */
.bug { opacity: 0; transition: opacity var(--mood-dur) ease; }
.bug.on { opacity: 1; }
.bug-drift { transform-box: fill-box; transform-origin: 50% 50%; animation: bug-drift var(--dur, 5s) var(--ease-float) var(--ph, 0s) infinite; }
@keyframes bug-drift {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  28%      { transform: translate(3px, -2.4px) rotate(7deg); }
  52%      { transform: translate(-1px, -4px) rotate(-4deg); }
  76%      { transform: translate(-3px, -1px) rotate(5deg); }
}
.bug-legs { transform-box: fill-box; transform-origin: 50% 50%; animation: bug-legs var(--ldur, .6s) steps(2, end) infinite; }
@keyframes bug-legs { 0% { transform: scaleY(1); } 50% { transform: scaleY(.78); } 100% { transform: scaleY(1); } }
.bug-body { animation: bug-jitter var(--gdur, 4s) steps(1, end) var(--gph, 0s) infinite; }
@keyframes bug-jitter { 0%, 91%, 97%, 100% { transform: translate(0, 0); } 92% { transform: translate(1.2px, 0); } 95% { transform: translate(-.9px, .4px); } }
.bug-gl { opacity: 0; animation: bug-gl var(--gdur, 4s) steps(1, end) var(--gph, 0s) infinite; }
@keyframes bug-gl { 0%, 91%, 97%, 100% { opacity: 0; } 92%, 95% { opacity: .9; } }
.bug-body { transform-box: fill-box; transform-origin: 50% 50%; }

/* the door: closed at rest, swings open for the departure and stays bright */
.door-leaf { transform-box: fill-box; transform-origin: 0% 50%; transition: transform 1s var(--ease-out); }
.door.open .door-leaf { transform: scaleX(.42) skewY(-7deg); }
.door-spill { transition: opacity 1s ease; }
.door.open .door-spill { opacity: .22; }
.door.bright .door-spill { opacity: .36; }

@media (prefers-reduced-motion: reduce) {
  .clutter, .leaf, .w-sun, .w-cloud, .w-over, .screen-content .bar, .door-leaf { transition: none; }
  .steam path, .tw, .cur, .bug-drift, .bug-legs, .bug-body, .bug-gl { animation: none; }
  .bug { transition: none; }
}
