/* Office interstitial (COM-237) — the waiting scene for a delegated batch.
   Its own file rather than another 200 lines in the 591KB styles.css, following
   changelog.css / statics.css. Every colour is a production token; only the
   floor and wall of the room are new. */

:root {
  /* Pixel-art palette. These stay in CSS so the drawing follows the single
     warm theme instead of hiding a second colour system in JavaScript. */
  --office-pixel-k: #4a4238;
  --office-pixel-s: #e8c39a;
  --office-pixel-S: #c99f72;
  --office-pixel-h: #6f5a3d;
  --office-pixel-H: #3f3831;
  --office-pixel-y: #b8905a;
  --office-pixel-c: #fffdf6;
  --office-pixel-t: #b8531a;
  --office-pixel-g: #5f8a6e;
  --office-pixel-a: #8b6f47;
  --office-pixel-A: #6f5a3d;
  --office-pixel-w: #a97f4e;
  --office-pixel-W: #8b6f47;
  --office-pixel-p: #ffffff;
  --office-pixel-P: #eceae8;
  --office-pixel-m: #e7d6b0;
  --office-pixel-M: #d8c399;
  --office-pixel-e: #dceef2;
  --office-pixel-L: #fadc78;
  --office-pixel-R: #c96a4a;
  --office-pixel-B: #7c6a4e;
  --office-pixel-b: #9c8a66;
  --office-floor-a: #f3ede1;
  --office-floor-b: #eee7d8;
  --office-wall: #e3d9c4;
  --office-wall-edge: #d3c6ab;
  --office-lamp: rgba(250, 220, 120, 0.4);
  --office-ease: cubic-bezier(0.22, 1, 0.36, 1);
  /* A note is an object on the desk, so it is opaque — the shared --green-dim /
     --amber-dim tokens are 10–12% alpha, which let the pixel floor read straight
     through the bubble. These are those tints flattened. Anything a founder
     reads words off gets a solid surface; only light (--office-lamp) and
     shadows stay translucent. */
  --office-note-done: #e6f4ed;
  --office-note-hiccup: #fff7ed;
}

.chat-log > .office {
  position: relative;
  width: 100%;
  max-width: 720px;
  margin: 4px auto 7px;
  /* The chat log is a flex column, so a tall child gets shrunk to nothing once
     the log is full — the room collapsed to 2px without this. */
  flex: 0 0 auto;
  background: var(--surface);
  border: 1px solid var(--bubble-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

/* The slip is the record and the office is the wait. While the room is on stage
   the slip steps aside rather than being destroyed — it returns on the yield,
   carrying the elapsed time and the summary. */
.chat-log > .work-slip.is-covered { display: none; }

/* ── the header strip: live dot, what's happening, census, clock ── */
.office-top {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--border-light);
  flex-wrap: wrap;
}
.office-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--green);
  animation: officePulse 2.2s var(--office-ease) infinite;
}
.office-dot.is-off { background: #c9c2b8; animation: none; }
.office-doing { font: 600 13.5px/1.4 var(--sans); color: var(--text-dim); }
.office-census {
  font: 400 12.5px/1.4 var(--sans);
  /* --text-muted on --surface2 measures 3.6:1, and this chip carries the one
     number the founder gets out of the whole scene. --text-dim clears AA. */
  color: var(--text-dim);
  background: var(--surface2);
  border-radius: 999px;
  padding: 3px 12px;
}
.office-elapsed {
  margin-left: auto;
  font: 400 12.5px/1.4 var(--sans);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
@keyframes officePulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* ── the room ── */
.office-floor {
  position: relative;
  /* Deep enough for the whole team to stand behind the meeting table without
     the desks they came from being in the shot. */
  height: 440px;
  overflow: hidden;
  background: repeating-conic-gradient(var(--office-floor-a) 0% 25%, var(--office-floor-b) 0% 50%) 0 0 / 40px 40px;
  transition: filter 0.8s var(--office-ease);
}
.office-wall {
  position: absolute;
  inset: 0 0 auto 0;
  height: 44px;
  background: var(--office-wall);
  border-bottom: 4px solid var(--office-wall-edge);
}
.office-window {
  position: absolute;
  top: 8px;
  width: 54px;
  height: 28px;
  background: linear-gradient(180deg, #dceef2, #cfe4da);
  border: 4px solid #c9bb9d;
}

/* ── the three states that are not "working fine" ──────────────────────────
   Each repaints the room, because a sticky note alone is a thing you have to
   read: the founder should know something changed from across the desk, before
   any words. All three retint the same tokens, so there is one mechanism and
   the states cannot drift apart.

   Signal lost  — colour drains out. The room is still there, we just can't see
                  it properly. Cool and washed, and it comes back by itself.
   Cancelled    — lights off. Warm but shut down: you did this on purpose, and
                  nothing is wrong.
   Failed       — warm amber wash. Something went wrong, said in the product's
                  voice rather than in red. */
.office.is-disconnected {
  --office-floor-a: #edecea;
  --office-floor-b: #e7e6e3;
  --office-wall: #dcdad5;
  --office-wall-edge: #cdcac4;
}
.office.is-disconnected .office-floor { filter: saturate(0.55) contrast(0.94) brightness(1.02); }

.office.is-stopped {
  --office-floor-a: #e4ded2;
  --office-floor-b: #ded7c9;
  --office-wall: #cfc6b0;
  --office-wall-edge: #bdb29a;
  --office-lamp: rgba(250, 220, 120, 0.12);
}
.office.is-stopped .office-floor { filter: brightness(0.97); }

.office.is-failed {
  --office-floor-a: #f7e7d9;
  --office-floor-b: #f2decd;
  --office-wall: #e9cdae;
  --office-wall-edge: #d8b68e;
  --office-lamp: rgba(250, 220, 120, 0.12);
}
.office.is-failed .office-floor { filter: saturate(1.04); }

/* The header carries the same signal, so the state reads whether the founder is
   looking at the room or at the line above it. */
.office.is-disconnected .office-census { background: var(--surface3); }
.office.is-stopped .office-census { background: #e4ded2; color: var(--text-dim); }
.office.is-failed .office-census { background: var(--office-note-hiccup); color: var(--warn-amber); }
.office.is-failed .office-dot { background: var(--amber); animation: none; }
.office.is-stopped .office-dot { background: #c9c2b8; animation: none; }

.office-note {
  position: absolute;
  left: 50%;
  top: 44%;
  transform: translateX(-50%) rotate(-2deg);
  background: var(--sticky);
  font: 400 13.5px/1.3 var(--hand);
  color: #6b5d1f;
  padding: 8px 14px;
  border-radius: 3px;
  box-shadow: var(--shadow-sm);
  z-index: 9;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s var(--office-ease);
}
.office.is-disconnected .office-note,
.office.is-stopped .office-note,
.office.is-failed .office-note { opacity: 1; }

/* ── pixel art ── */
.office-px { image-rendering: pixelated; position: absolute; }
.office-px svg { display: block; shape-rendering: crispEdges; }
.office-station .office-px,
.office-worker .office-body.office-px,
.office-spot .office-px { position: relative; display: inline-block; }

/* Everything on the floor is centred on its coordinate rather than starting at
   it, so a long station label ("giving it a second read") grows both ways
   instead of pushing the rightmost desk through the wall on a narrow screen. */
.office-station,
.office-spot { position: absolute; text-align: center; transform: translateX(-50%); }
.office-station .office-lbl,
.office-spot .office-lbl {
  margin-top: 5px;
  font: 700 10px/1.3 var(--sans);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  max-width: 120px;
}
.office-spot .office-lbl {
  font: 400 12px/1.3 var(--hand);
  letter-spacing: 0;
  text-transform: none;
}

/* Lamp glow is the occupancy channel — readable across the room, no words. */
.office-station .office-glow {
  position: absolute;
  left: 50%;
  top: 34%;
  transform: translate(-50%, -50%);
  width: 110px;
  height: 76px;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--office-lamp), transparent 72%);
  opacity: 0;
  transition: opacity 0.9s var(--office-ease);
  pointer-events: none;
}
.office-station.is-lit .office-glow { opacity: 1; }

/* ── the workers ── */
.office-worker {
  position: absolute;
  z-index: 4;
  transform: translateX(-50%);
  transition: left 2.4s steps(16), top 2.4s steps(16);
}
.office-worker .office-body { animation: officeBob 1.15s steps(2, jump-none) infinite; }
.office-worker.is-walking .office-body { animation-duration: 0.45s; }
.office-worker.is-flipped .office-body svg { transform: scaleX(-1); }
.office-worker .office-shadow {
  position: absolute;
  left: 50%;
  bottom: -3px;
  transform: translateX(-50%);
  width: 26px;
  height: 6px;
  border-radius: 50%;
  background: rgba(60, 50, 40, 0.16);
}
@keyframes officeBob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-2px); } }

/* Nobody is obliged to be thinking something. Standing in a briefing holding a
   blank sticky note is worse than standing there listening. */
.office-thought:empty { display: none; }

/* Thought bubbles stay paper — the pixel world never takes over the voice. */
.office-thought {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-28%) rotate(-2deg);
  background: var(--sticky);
  color: #5d5424;
  font: 400 12.5px/1.25 var(--hand);
  padding: 6px 10px 7px;
  border-radius: 3px;
  box-shadow: var(--shadow-sm);
  width: max-content;
  max-width: 140px;
  z-index: 6;
  transition: opacity 0.35s var(--office-ease);
  overflow-wrap: anywhere;
}
.office-thought::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 26%;
  border: 5px solid transparent;
  border-top-color: var(--sticky);
}
/* Near a wall the note tucks back inside instead of hanging off the floor. The
   tail follows it, so it still points at the worker who is thinking it. */
.office-worker.is-right .office-thought {
  left: auto;
  right: -8px;
  transform: translateX(0) rotate(-2deg);
}
.office-worker.is-right .office-thought::after { left: auto; right: 12px; }
.office-worker.is-left .office-thought {
  left: -6px;
  transform: translateX(0) rotate(-2deg);
}
.office-worker.is-left .office-thought::after { left: 14px; }
.office-thought.is-done { background: var(--office-note-done); color: #14735a; }
.office-thought.is-done::after { border-top-color: var(--office-note-done); }
.office-thought.is-hiccup { background: var(--office-note-hiccup); color: var(--warn-amber); }
.office-thought.is-hiccup::after { border-top-color: var(--office-note-hiccup); }

.office-plate {
  position: absolute;
  top: calc(100% + 4px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--cream);
  border: 1px solid rgba(175, 170, 162, 0.4);
  border-radius: 3px;
  font: italic 400 11.5px/1.4 var(--serif);
  color: var(--accent);
  padding: 1px 8px;
  white-space: nowrap;
  box-shadow: var(--shadow-sm);
  z-index: 5;
}

/* ── the arrival: the room opens rather than existing between two frames.
   Deliberately the mirror of officeLeave — a door that swings both ways reads
   as one object; a room that fades out but snaps in reads as a bug. It rises
   slightly as it lands, so it arrives ON the desk rather than over it. ── */
.chat-log > .office {
  animation: officeEnter 340ms var(--office-ease) both;
}
@keyframes officeEnter {
  from { opacity: 0; transform: scale(0.985) translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* ── the yield: real output is arriving, so the room bows out rather than
   blinking away underneath it ── */
.chat-log > .office.is-leaving {
  animation: officeLeave 420ms var(--office-ease) both;
  pointer-events: none;
}
@keyframes officeLeave {
  from { opacity: 1; transform: scale(1); }
  to { opacity: 0; transform: scale(0.985); }
}

/* The note takes the room's colour too, so the paper belongs to the scene it is
   sitting in rather than reading as the same yellow sticky in every state. */
.office.is-stopped .office-note {
  background: var(--cream);
  color: var(--text-dim);
  border: 1px solid var(--office-wall-edge);
}
.office.is-failed .office-note {
  background: #fbe6cf;
  color: var(--warn-amber);
}

/* ── localhost rehearsal controls (?office-demo=1), never reachable in prod ── */
.office-demo-controls {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: center;
  z-index: 999;
}
.office-demo-controls button {
  font: 600 13px/1 var(--sans);
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 8px 16px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 0.25s var(--spring), box-shadow 0.25s var(--office-ease);
}
.office-demo-controls button:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.office-demo-controls button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── small screens: the room gets shorter, never narrower than the column ── */
@media (max-width: 720px) {
  /* Taller than the desktop room, not shorter: the desks pair off into two rows
     on a phone, so the floor needs the depth to hold both, the meeting table
     everyone gathers at, and the rest area. */
  .office-floor { height: 560px; }
  .office-thought { max-width: 110px; font-size: 11.5px; }
  .office-station .office-lbl, .office-spot .office-lbl { font-size: 9px; max-width: 88px; }
}

/* ── reduced motion: the room still says who is working and who has finished,
   it just stops moving to say it ── */
@media (prefers-reduced-motion: reduce) {
  .office-worker { transition: none; }
  .office-worker .office-body,
  .office-dot { animation: none; }
  .office-floor,
  .office-station .office-glow,
  .office-thought,
  .office-note { transition: none; }
  /* The room still arrives and leaves — it just does it without travelling.
     Opacity alone keeps the two states distinguishable for anyone watching a
     screenshot, without motion anyone asked not to see. */
  .chat-log > .office { animation-name: officeEnterStill; }
  .chat-log > .office.is-leaving { animation-name: officeLeaveStill; }
}
@keyframes officeEnterStill { from { opacity: 0; } to { opacity: 1; } }
@keyframes officeLeaveStill { from { opacity: 1; } to { opacity: 0; } }
