/* Diner Rush v5 — everything is drawn except faces (R9).
   Layout numbers that were measured into shape in v4 are kept; see
   docs/diner-rush-spec.md §9 for what and why. */

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body {
  margin: 0; height: 100%; overflow: hidden;
  /* R-C15: without this the page scrolls behind the frame, and a drag at the
     end of a scroll region drags the whole page with it. */
  overscroll-behavior: none;
  font-family: ui-rounded, "SF Pro Rounded", "Segoe UI", system-ui, sans-serif;
  background: #fff1f2; color: #4a2c2a;
  user-select: none; -webkit-user-select: none;
}
#app {
  height: 100%; height: 100dvh; display: flex; flex-direction: column;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}
button { font-family: inherit; cursor: pointer; }

/* ---------- header (docs/offline-pwa.md chrome contract) ---------- */
#hdr {
  flex: none; display: flex; align-items: center; gap: 6px;
  padding: 6px 8px;
}
#hdrTitle {
  flex: 1; min-width: 0; text-align: center;
  font-weight: 900; font-size: 17px; color: #be123c;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pill {
  flex: none; width: 44px; height: 44px; border-radius: 13px;
  border: 3px solid #fbcfd6; background: #fff; font-size: 18px;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.pill:active { transform: scale(.94); }

.scr { display: none; flex: 1; min-height: 0; overflow-y: auto; padding: 6px 12px 14px; }
.scr.on { display: flex; flex-direction: column; }
#scr-play.on { padding: 0 6px 4px; overflow: hidden; }

h1 { font-size: 30px; margin: 6px 0 2px; text-align: center; color: #be123c; }
h2 { font-size: 20px; margin: 4px 0 6px; }
.sub { text-align: center; color: #9f7a72; font-size: 14px; margin-bottom: 12px; }
.big {
  display: block; width: 100%; margin: 7px 0; padding: 14px;
  font-size: 17px; font-weight: 800; border-radius: 16px;
  border: 3px solid #fbcfd6; background: #fff; color: #4a2c2a; min-height: 52px;
}
.big.primary { background: #e11d48; border-color: #be123c; color: #fff; }
.big:active { transform: scale(.985); }
.small {
  padding: 9px 12px; font-size: 14px; font-weight: 800; border-radius: 12px;
  border: 3px solid #fbcfd6; background: #fff; color: #4a2c2a; width: 100%; margin-top: 8px;
}
#statsLine { text-align: center; font-size: 13px; color: #9f7a72; margin-top: 10px; }

#tierRow { display: flex; gap: 8px; margin-bottom: 10px; }
.tierCard {
  flex: 1; min-width: 0; padding: 10px 4px; border-radius: 16px;
  border: 3px solid #fbcfd6; background: #fff; font-weight: 800; font-size: 13px;
  display: flex; flex-direction: column; align-items: center; gap: 2px; color: #4a2c2a;
}
.tierCard .te { font-size: 22px; line-height: 1; }
.tierCard small { font-weight: 700; font-size: 10.5px; color: #9f7a72; }
.tierCard.sel { border-color: #e11d48; background: #ffe4e9; }

/* ---------- settings (tier sets the default, this overrides — R8) ---------- */
#settings {
  border: 3px solid #fbcfd6; border-radius: 16px; background: #fff;
  margin: 8px 0; padding: 0 12px;
}
#settings > summary {
  list-style: none; cursor: pointer; padding: 13px 0;
  font-weight: 800; font-size: 15px;
}
#settings > summary::-webkit-details-marker { display: none; }
#settings > summary::after { content: ' ▾'; color: #c48b95; }
#settings[open] > summary::after { content: ' ▴'; }
.setBody { padding-bottom: 12px; }
.setRow { display: flex; flex-direction: column; gap: 5px; margin-bottom: 12px; }
.setRow label { font-size: 13.5px; font-weight: 700; color: #7c5a55; }
.setRow select, .setRow input[type=range] {
  width: 100%; font-family: inherit; font-size: 14.5px; font-weight: 700;
  padding: 9px; border-radius: 11px; border: 3px solid #fbcfd6; background: #fff;
  color: #4a2c2a; min-height: 44px;
}
.setRow input[type=range] { padding: 0; border: 0; accent-color: #e11d48; }
/* R8/the disclosure rule: say when you are off the tier's defaults, or a
   setting changed weeks ago silently explains a difficulty nobody can account
   for. */
.setNote { font-size: 12.5px; font-weight: 700; color: #b45309; min-height: 17px; }

.card {
  background: #fff; border: 3px solid #fbcfd6; border-radius: 16px;
  padding: 12px; margin-bottom: 9px; font-size: 14.5px; line-height: 1.45;
}
.card h2 { margin-top: 0; }

/* ---------- the play bar ---------- */
#bar {
  flex: none; display: flex; gap: 6px; align-items: center;
  padding: 4px 2px 6px; font-weight: 800; font-size: 13.5px;
}
.stat {
  background: #fff; border: 2px solid #fbcfd6; border-radius: 10px;
  padding: 4px 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0; flex-shrink: 1;
}
#stHearts { border: 0; background: none; margin-left: auto; letter-spacing: 1px; flex-shrink: 0; white-space: nowrap; }
/* The level and the score must never be the things that get clipped when a
   neighbour grows -- docs/offline-pwa.md R17b/R31b, third product this week. */
#stLevel, #stServed, #stCoins { flex-shrink: 0; }

/* ---------- the room ---------- */
/* The floor is emitted as QUADS from the same projection as everything standing
   on it (R12/R12a of v4). A stripe pattern is a projection where nothing
   converges, and the eye resolves that contradiction as "flat board, stickers
   on it" — which was most of what "the graphics look clunky" meant. */
#room {
  position: relative; flex: none; width: 100%; margin: 0 auto;
  border-radius: 14px; overflow: hidden; background: #f7e6d3;
  --backL: 17%; --backR: 83%; --s: 1; --k: 1; --seat: 72px;
  --wall: 58px; --counter: 34px;
  --vinyl: #d94a5a; --vinylD: #a32c3c;
}
#ground { position: absolute; left: 0; right: 0; bottom: 0; top: calc(var(--wall) + var(--counter)); }
#ground svg { width: 100%; height: 100%; display: block; }

#wall {
  position: absolute; left: 0; right: 0; top: 0; height: var(--wall);
  background: linear-gradient(#ffe1e6, #ffd0d8);
  border-bottom: calc(3px * var(--k)) solid #e9a9b4;
}
#sign {
  position: absolute; left: 50%; top: 46%; transform: translate(-50%, -50%);
  font-weight: 900; letter-spacing: calc(3px * var(--k));
  font-size: calc(15px * var(--k)); color: #fff;
  background: linear-gradient(#f43f5e, #be123c);
  padding: calc(3px * var(--k)) calc(11px * var(--k));
  border-radius: 999px; box-shadow: 0 0 calc(11px * var(--k)) rgba(244, 63, 94, .6);
}
#clock {
  position: absolute; right: calc(9px * var(--k)); top: calc(9px * var(--k));
  width: calc(20px * var(--k)); height: calc(20px * var(--k));
  border-radius: 50%; background: #fff; border: calc(2px * var(--k)) solid #e9a9b4;
}
#clock::before, #clock::after {
  content: ''; position: absolute; left: 50%; top: 50%; background: #9f7a72;
  transform-origin: 0 50%; border-radius: 2px;
}
#clock::before { width: 32%; height: calc(2px * var(--k)); transform: translateY(-50%) rotate(-58deg); }
#clock::after  { width: 24%; height: calc(2px * var(--k)); transform: translateY(-50%) rotate(28deg); }

#counter {
  position: absolute; left: 0; right: 0; top: var(--wall); height: var(--counter);
  background: linear-gradient(#fbf3e6 0 55%, #e3cfb4 55% 100%);
  border-bottom: calc(3px * var(--k)) solid #c9ab8b;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 calc(10px * var(--k));
}
/* the pass — where a finished dish waits to be picked up */
#pass {
  width: calc(46px * var(--k)); height: calc(13px * var(--k));
  border-radius: calc(4px * var(--k));
  background: repeating-linear-gradient(90deg, #d7bd9c 0 calc(5px * var(--k)), #c9ab8b calc(5px * var(--k)) calc(7px * var(--k)));
  box-shadow: inset 0 calc(2px * var(--k)) 0 rgba(255, 255, 255, .5);
}
/* R18 of v4: the kitchen's ration is VISIBLE. Telling the player "kitchen full"
   in a toast asks them to take it on faith. */
#hobs { display: flex; gap: calc(5px * var(--k)); }
#hobs i {
  width: calc(12px * var(--k)); height: calc(12px * var(--k)); border-radius: 50%;
  background: #b9a289; box-shadow: inset 0 0 0 calc(2px * var(--k)) #8f7a63;
}
#hobs i.lit {
  background: radial-gradient(circle at 50% 45%, #fde68a, #f97316 70%, #dc2626);
  box-shadow: 0 0 calc(7px * var(--k)) rgba(249, 115, 22, .85);
}

/* ---------- the door ---------- */
#doors { position: absolute; inset: 0; pointer-events: none; }
.door { position: absolute; transform: translate(-50%, -100%); z-index: 40; }
.door .frame {
  width: calc(30px * var(--s) * var(--k)); height: calc(44px * var(--s) * var(--k));
  border-radius: calc(4px * var(--k)) calc(4px * var(--k)) 0 0;
  background: linear-gradient(#a3714b, #7c5334);
  border: calc(2px * var(--k)) solid #5c3d26;
  box-shadow: inset calc(-4px * var(--k)) 0 0 rgba(0, 0, 0, .16);
  position: relative;
}
.door .frame::after {                       /* the handle */
  content: ''; position: absolute; right: calc(4px * var(--k)); top: 52%;
  width: calc(4px * var(--k)); height: calc(4px * var(--k));
  border-radius: 50%; background: #ffd79a;
}
/* R31c: `width`, NOT `max-width`. An absolutely-positioned box with only `left`
   set shrink-to-fits against containing-block minus left, so a max-width there
   is inert and every party wrapped onto its own row. */
.door .q {
  position: absolute; bottom: 100%; left: 50%;
  margin-bottom: calc(2px * var(--s) * var(--k));
  display: flex; gap: calc(3px * var(--s)); flex-wrap: wrap-reverse;
  align-items: flex-end; align-content: flex-end; justify-content: flex-start;
  width: var(--qmax, 240px);
}
/* A door on the right side of the room has its floor to the LEFT of it, so the
   line has to grow that way or it runs off the edge — the same defect as the
   original queue, mirrored. */
.door.leftward .q { left: auto; right: 50%; justify-content: flex-end; }
.qParty {
  display: flex; align-items: flex-end; gap: calc(1px * var(--s));
  padding: calc(2px * var(--s)) calc(3px * var(--s));
  border-radius: calc(7px * var(--s));
  background: rgba(255, 255, 255, .82);
  border: calc(1.5px * var(--s)) solid #e2c8b6;
}
.qParty.hurry { border-color: #f97316; background: rgba(255, 237, 213, .92); }
.qParty .g { margin: 0; }

/* ---------- a seat ---------- */
/* EVERY PART IS ABSOLUTELY PLACED IN A BAND MEASURED FROM THE FLOOR, and the
   band comes from PARTS in data.js — app.js sets bottom/height from it, this
   file only says what a part looks like.
   As a bottom-aligned flex column (v2) a party of four added a front row and
   pushed the table up: measured at 21.3px when a booth filled and 0px when a
   two-top did. Furniture does not move when somebody sits at it. */
.seat {
  position: absolute; transform: translate(-50%, -100%);
  width: calc(var(--seat) * var(--s) * var(--w, 1));
  height: calc(var(--seat) * var(--s) * 1.34);
  border: 0; background: none; padding: 0; color: inherit;
}
.seat > * { position: absolute; left: 50%; transform: translateX(-50%); }

/* contact shadow — the cheapest cue that a thing stands ON the floor */
.sh {
  width: 84%; border-radius: 50%; z-index: 0;
  background: radial-gradient(rgba(90, 50, 30, .34), rgba(90, 50, 30, 0) 70%);
}

/* SEATING. A booth's bench and a two-top's chairs are FIRST-CLASS PARTS, not
   pseudo-elements of the guest row. In v4 the bench hung off `.row.back::before`
   and an empty row is 0px tall, so an empty booth had no chairs (suppressed
   because "the bench is the seating") and no bench (because there was nobody in
   it) — a bare table top on bare floor, on two of the three tables of Hard's
   opening screen. Furniture that appears when somebody sits at it. */
.bench {
  width: 104%; z-index: 1;
  border-radius: calc(9px * var(--s)) calc(9px * var(--s)) calc(3px * var(--s)) calc(3px * var(--s));
  background: linear-gradient(var(--vinyl), var(--vinylD));
  box-shadow: inset 0 calc(2px * var(--s)) 0 rgba(255, 255, 255, .3),
              0 calc(2px * var(--s)) calc(3px * var(--s)) rgba(90, 50, 30, .25);
}
.bench::after {                              /* buttoned back, so it reads as vinyl */
  content: ''; position: absolute; inset: 12% 8% 46% 8%;
  background-image: radial-gradient(circle, rgba(0, 0, 0, .18) 0 18%, transparent 20%);
  background-size: calc(13px * var(--s)) calc(13px * var(--s));
  border-radius: calc(6px * var(--s));
}
.chairs { width: 64%; z-index: 1; }
.chairs::before, .chairs::after {
  content: ''; position: absolute; bottom: 0; width: 38%; height: 100%;
  border-radius: 32% 32% 12% 12%;
  background: linear-gradient(#c8874f, #a76a3a);
  box-shadow: inset 0 calc(2px * var(--s)) 0 rgba(255, 255, 255, .22);
}
.chairs::before { left: 0; }
.chairs::after { right: 0; }
/* a stool seats one, so it gets one chair, centred */
.seat.cap1 .chairs::after { display: none; }
.seat.cap1 .chairs::before { left: 31%; width: 38%; }

/* the table top: a top with thickness and a pedestal, so it stands on the floor
   rather than lying on it, and it differs from the floor in VALUE not just hue */
.tbl {
  width: 76%; z-index: 3;
  border-radius: 50% / 40%;
  background: linear-gradient(#ffffff 0 42%, #ffe9cf 42% 72%, #f0cfa8 72% 100%);
  border: calc(2px * var(--s)) solid #a8836a;
  box-shadow: 0 calc(5px * var(--s)) 0 calc(-2px * var(--s)) #8f6d57,
              0 calc(9px * var(--s)) calc(7px * var(--s)) calc(-3px * var(--s)) rgba(90, 50, 30, .35);
}
.seat.cap4 .tbl { width: 92%; border-radius: 34% / 40%; }
.seat.cap6 .tbl { width: 96%; border-radius: 46% / 42%; }
.seat.cap1 .tbl { width: 54%; border-radius: 50%; }
.tbl::after {
  content: ''; position: absolute; left: 50%; top: 92%;
  transform: translateX(-50%);
  width: 16%; height: calc(9px * var(--s)); background: linear-gradient(90deg, #a8836a, #cdae95 40%, #8f6d57);
}
.seat.ready .tbl { background: linear-gradient(#eaffd0 0 46%, #86efac 46% 100%); border-color: #4ade80; }
.seat.waiting .tbl { border-color: #fb923c; }
.seat.held .tbl { border-style: dashed; border-color: #0ea5e9; opacity: .85; }
.seat.served .tbl { background: linear-gradient(#faf0ff 0 46%, #ddb8fb 46% 100%); }
.seat.dirty .tbl { background: linear-gradient(#efe6dc 0 46%, #cbb9a6 46% 100%); border-color: #a8927c; }
.seat.pending .tbl { outline: calc(3px * var(--s)) dashed #0ea5e9; outline-offset: calc(3px * var(--s)); }

/* rows of guests */
.row-b, .row-f {
  display: flex; justify-content: center; align-items: flex-end; width: 96%;
}
.row-b { z-index: 2; }
.row-f { z-index: 4; }
.g { display: flex; flex-direction: column; align-items: center; margin: 0 calc(2px * var(--s)); }
.g .hd { font-size: calc(var(--seat) * var(--s) * 0.28); line-height: 1; font-style: normal; }
.g .bd {
  width: calc(var(--seat) * var(--s) * 0.22); height: calc(var(--seat) * var(--s) * 0.12);
  margin-top: calc(var(--seat) * var(--s) * -0.035);
  border-radius: 40% 40% 22% 22%; background: var(--tone, #94a3b8);
  /* Two people in one party wear the same colour, so adjacent shoulders merged
     into a single slab and a party of two read as one torso with two heads. */
  box-shadow: inset 0 calc(-2px * var(--s)) 0 rgba(0, 0, 0, .14),
              0 0 0 calc(1px * var(--s)) rgba(255, 255, 255, .7);
}
.row-f .g .bd { border-radius: 40% 40% 30% 30%; }

/* patience */
.pat {
  width: 70%; border-radius: calc(3px * var(--s));
  background: rgba(0, 0, 0, .18); overflow: hidden; z-index: 5;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .5); min-height: 4px;
}
.pat > i { display: block; height: 100%; width: 0; background: #22c55e; transition: width .12s linear; }
.pat.warn > i { background: #f59e0b; }
.pat.crit > i { background: #ef4444; }
/* A paused bar must LOOK paused, or the fairness rule is invisible and the
   player still believes the clock is running against them. */
.pat.held > i { background: #38bdf8; }
.pat.held { box-shadow: 0 0 0 calc(2px * var(--s)) #bae6fd; }
.pat.off { visibility: hidden; }

/* R6: THE TIP, TICKING DOWN. The gradient existed in v4 and was revealed only
   after the fact, so the decision was there and invisible. */
.tipTag {
  display: flex; align-items: center; justify-content: center; gap: calc(2px * var(--s));
  font-weight: 900; font-size: calc(var(--seat) * var(--s) * 0.17); line-height: 1;
  color: #7a5a2a; background: #fff8e1;
  border: calc(1.5px * var(--s)) solid #e6c86a;
  border-radius: 999px; padding: 0 calc(5px * var(--s)); z-index: 6;
  white-space: nowrap;
}
.tipTag.fading { color: #9a5b2a; border-color: #f0a35e; background: #fff1e0; }
.tipTag.low { color: #9f1239; border-color: #fda4af; background: #fff1f2; }

/* the thought bubble — the help text calls it a thought bubble, so it has to be
   one; a bare glyph in mid-air over a checkerboard floor is a smudge */
.bub {
  width: 76%; display: flex; align-items: center; justify-content: center;
  background: #fffdf8; border: calc(2px * var(--s)) solid #cdb6a4;
  border-radius: 999px; z-index: 7;
  box-shadow: 0 calc(2px * var(--s)) calc(4px * var(--s)) rgba(90, 50, 30, .25);
}
.bub::after {
  content: ''; position: absolute; left: 50%; top: 100%;
  margin-left: calc(-5px * var(--s));
  border-left: calc(5px * var(--s)) solid transparent;
  border-right: calc(5px * var(--s)) solid transparent;
  border-top: calc(7px * var(--s)) solid #fffdf8;
  filter: drop-shadow(0 calc(1.5px * var(--s)) 0 #cdb6a4);
}
.seat.ready .bub { border-color: #4ade80; background: #f2fff0; }
.seat.waiting .bub { border-color: #fb923c; }
.seat.dirty .bub { border-color: #a8927c; background: #f6efe8; }

/* ---------- what a bubble holds: DRAWN dishes, not glyphs (R9) ---------- */
.dish { position: relative; display: block; }
.dish, .plate {
  width: calc(var(--seat) * var(--s) * 0.26); height: calc(var(--seat) * var(--s) * 0.26);
}
.plate { border-radius: 50%; background: radial-gradient(circle at 40% 35%, #fff, #e6dccd 75%, #cfc3b0); }
.d-soup   { border-radius: 50%; background: radial-gradient(circle at 42% 38%, #fff 0 26%, #f6a23a 28%, #d97706 72%, #fff 74%); }
.d-salad  { border-radius: 50%; background: radial-gradient(circle at 34% 30%, #86efac 0 22%, transparent 24%), radial-gradient(circle at 68% 58%, #4ade80 0 20%, transparent 22%), radial-gradient(circle at 46% 72%, #bbf7d0 0 18%, transparent 20%), radial-gradient(circle, #fff 0 70%, #e6dccd 72%); }
.d-fries  { border-radius: 14% 14% 34% 34%; background: linear-gradient(#e2413c 0 46%, #c02f2c 46%), repeating-linear-gradient(88deg, #fbbf24 0 2px, transparent 2px 4px); }
.d-burger { border-radius: 46% 46% 40% 40%; background: linear-gradient(#f0b45e 0 30%, #6b3f22 30% 46%, #86efac 46% 58%, #f0b45e 58% 100%); }
.d-pizza  { border-radius: 50%; background: radial-gradient(circle at 36% 34%, #dc2626 0 16%, transparent 18%), radial-gradient(circle at 66% 62%, #dc2626 0 14%, transparent 16%), radial-gradient(circle, #fcd34d 0 78%, #d69b3f 80%); }
.d-pasta  { border-radius: 50%; background: radial-gradient(circle at 50% 52%, #dc2626 0 24%, transparent 26%), repeating-radial-gradient(circle at 50% 50%, #fde68a 0 2px, #f5d271 2px 4px); }
.d-fish   { border-radius: 58% 22% 58% 22%; background: linear-gradient(120deg, #93c5fd, #3b82f6 70%, #1d4ed8); }
.d-roast  { border-radius: 40% 40% 32% 32%; background: linear-gradient(#b45309 0 40%, #7c2d12 40%), radial-gradient(circle at 70% 26%, rgba(255,255,255,.4) 0 12%, transparent 14%); }
/* the non-dish bubbles, also drawn */
.i-seat   { width: calc(var(--seat)*var(--s)*0.24); height: calc(var(--seat)*var(--s)*0.24); border-radius: 30% 30% 12% 12%; background: linear-gradient(#c8874f, #a76a3a); }
.i-ticket { width: calc(var(--seat)*var(--s)*0.24); height: calc(var(--seat)*var(--s)*0.20); border-radius: 3px; background: repeating-linear-gradient(#fff 0 3px, #e5e0d5 3px 5px); border: 1px solid #c9bda9; }
.i-pot    { width: calc(var(--seat)*var(--s)*0.26); height: calc(var(--seat)*var(--s)*0.22); border-radius: 8% 8% 42% 42%; background: linear-gradient(#94a3b8, #475569); box-shadow: inset 0 2px 0 rgba(255,255,255,.35); }
.i-happy  { width: calc(var(--seat)*var(--s)*0.24); height: calc(var(--seat)*var(--s)*0.24); border-radius: 50%; background: radial-gradient(circle at 50% 120%, #f472b6 0 40%, transparent 42%), #fde68a; }
.i-plates { width: calc(var(--seat)*var(--s)*0.26); height: calc(var(--seat)*var(--s)*0.18); border-radius: 40%; background: linear-gradient(#e6dccd 0 40%, #cfc3b0 40% 70%, #b9ab97 70%); }
/* cook progress, drawn on the pot */
.i-pot { position: relative; overflow: hidden; }
.i-pot > b { position: absolute; left: 0; bottom: 0; width: 100%; background: rgba(253, 224, 71, .75); }

/* ---------- the staff ---------- */
/* SIZED IN ROOM UNITS, like everything else standing on this floor. They were
   in absolute pixels times the perspective scale — 20px heads, a 17x15 torso —
   so when the room grew on a bigger screen the seats grew and the staff did
   not. Measured on a 375px handset: a waiter at the FRONT had a 19px head
   against a seated guest's 17px at the BACK. The one thing on screen that moves
   constantly was the smallest thing on it.
   A standing adult reads bigger than a seated guest, so the head is 0.34 of the
   room's unit against a guest's 0.28. */
.waiter {
  position: absolute; transform: translate(-50%, -100%);
  display: flex; flex-direction: column; align-items: center;
  pointer-events: none; z-index: 45;
}
.waiter .tray {
  height: calc(var(--seat) * var(--s) * 0.24);
  display: flex; align-items: flex-end;
}
.waiter .tray .dish {
  width: calc(var(--seat) * var(--s) * 0.22); height: calc(var(--seat) * var(--s) * 0.22);
}
.waiter .who { display: flex; flex-direction: column; align-items: center; }
.waiter .hd { font-size: calc(var(--seat) * var(--s) * 0.34); line-height: 1; font-style: normal; }
.waiter .bd {
  width: calc(var(--seat) * var(--s) * 0.27); height: calc(var(--seat) * var(--s) * 0.23);
  margin-top: calc(var(--seat) * var(--s) * -0.03);
  border-radius: 42% 42% 26% 26%; background: var(--tone, #0ea5e9);
  position: relative;
  box-shadow: inset 0 calc(-2px * var(--s)) 0 rgba(0, 0, 0, .16);
}
.waiter .apron {
  position: absolute; left: 50%; transform: translateX(-50%); bottom: 0;
  width: 56%; height: 62%; background: #fff8f0; border-radius: 2px 2px 30% 30%;
}
.waiter .shadow {
  width: calc(var(--seat) * var(--s) * 0.30); height: calc(var(--seat) * var(--s) * 0.09);
  border-radius: 50%;
  background: radial-gradient(rgba(90, 50, 30, .32), rgba(90, 50, 30, 0) 70%);
  margin-top: calc(-2px * var(--s));
}
/* Carrying something, or on a job — the two things you want to read at a
   glance about the person you just sent somewhere. */
.waiter.busy .bd {
  box-shadow: inset 0 calc(-2px * var(--s)) 0 rgba(0,0,0,.16),
              0 0 0 calc(2px * var(--s)) rgba(255,255,255,.9),
              0 0 0 calc(4px * var(--s)) rgba(14,165,233,.45);
}

/* ---------- assign / direct: the crew bar (R8) ---------- */
#crewBar {
  flex: none; display: flex; gap: 8px; justify-content: center;
  padding: 5px 2px 0; min-height: 0;
}
#crewBar:empty { display: none; }
.crewBtn {
  display: flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-radius: 13px; min-height: 44px;
  border: 3px solid #fbcfd6; background: #fff; font-weight: 800; font-size: 13px;
  color: #4a2c2a;
}
.crewBtn .dot { width: 13px; height: 13px; border-radius: 50%; background: var(--tone); }
.crewBtn.sel { border-color: #0ea5e9; background: #e0f2fe; }
.crewBtn.busy { opacity: .55; }

/* ---------- shift report ---------- */
#endFace { font-size: 56px; text-align: center; line-height: 1; margin-top: 6px; }
#endTitle { text-align: center; }
#endGauge {
  background: #fff; border: 3px solid #fbcfd6; border-radius: 16px;
  padding: 12px; margin: 8px 0;
}
.gRow { display: flex; justify-content: space-between; align-items: baseline; font-weight: 800; font-size: 15px; }
.gRow.sub { font-size: 13px; color: #9f7a72; font-weight: 700; margin-top: 6px; }
.gRow b { font-size: 24px; }
.gTrack {
  position: relative; height: 16px; border-radius: 999px; margin-top: 7px;
  background: #ffe4e9; overflow: hidden;
}
.gFill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, #fb7185, #e11d48); transition: width .8s cubic-bezier(.2,.9,.3,1); }
/* where a good shift sits — a target, not a ceiling, so the bar can pass it */
.gMark { position: absolute; top: -3px; width: 4px; height: 22px; border-radius: 2px; background: #0f766e; }
#endGrade { text-align: center; font-size: 19px; font-weight: 900; min-height: 26px; }
#endWhy {
  text-align: center; font-size: 13.5px; font-weight: 700; color: #9f7a72;
  min-height: 38px; line-height: 1.4; padding: 2px 6px;
}
#endStars { text-align: center; font-size: 34px; letter-spacing: 6px; min-height: 42px; }
#endCoins { text-align: center; font-weight: 800; color: #8a6a4a; min-height: 22px; margin-bottom: 4px; }

/* ---------- overlays ---------- */
#pauseOv {
  position: fixed; inset: 0; background: rgba(40, 20, 25, .55);
  display: none; align-items: center; justify-content: center; z-index: 90; padding: 20px;
}
#pauseOv.on { display: flex; }
#pauseCard {
  background: #fff1f2; border: 4px solid #fbcfd6; border-radius: 20px;
  padding: 18px; width: min(340px, 100%); text-align: center;
}
#toast {
  position: fixed; left: 50%; bottom: calc(18px + env(safe-area-inset-bottom));
  transform: translateX(-50%) translateY(14px);
  background: #4a2c2a; color: #fff; font-weight: 800; font-size: 14px;
  padding: 9px 15px; border-radius: 999px; opacity: 0; pointer-events: none;
  transition: opacity .18s, transform .18s; z-index: 95; max-width: 90vw; text-align: center;
}
#toast.on { opacity: 1; transform: translateX(-50%) translateY(0); }

#footer { flex: none; text-align: center; padding: 2px 0 4px; }

/* ---------- motion (R11) ---------- */
/* States transition rather than cut. v4's waiter walked and NOTHING else in the
   room moved at all, which is most of what "stiff" meant. */
.seat .bub, .seat .tipTag { transition: opacity .18s ease, transform .18s ease; }
.seat .bub.in, .seat .tipTag.in { animation: popIn .26s cubic-bezier(.3,1.5,.5,1); }
@keyframes popIn {
  0%   { transform: translateX(-50%) scale(.5); opacity: 0; }
  100% { transform: translateX(-50%) scale(1); opacity: 1; }
}
/* The GUESTS pop, not the furniture. v4 put `pop`/`ping` on the whole seat, so
   the table dipped into the floor when you tapped it — scaling about the box
   centre on a bottom-anchored element. Measured at 2.2px, and it is the same
   rule as "furniture does not move when somebody sits at it". */
.row-b.in .g, .row-f.in .g { animation: sitDown .34s cubic-bezier(.3,1.4,.5,1); }
@keyframes sitDown {
  0%   { transform: translateY(-28%) scale(.7); opacity: 0; }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}
.seat.ping .tbl { animation: nudge .22s ease; }
@keyframes nudge {
  50% { box-shadow: 0 calc(5px * var(--s)) 0 calc(-2px * var(--s)) #8f6d57,
                    0 0 0 calc(4px * var(--s)) rgba(14, 165, 233, .5); }
}
.fx {
  position: absolute; transform: translate(-50%, -100%);
  font-weight: 900; font-size: 15px; color: #0f766e; pointer-events: none;
  z-index: 60; animation: floatUp 1s ease-out forwards;
}
.fx.bad { color: #be123c; }
@keyframes floatUp {
  0%   { opacity: 0; transform: translate(-50%, -100%) scale(.7); }
  25%  { opacity: 1; transform: translate(-50%, -140%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -230%) scale(1); }
}
/* A dish TRAVELS from the pass to the table. In v4 it teleported. */
.flying {
  position: absolute; transform: translate(-50%, -50%); z-index: 55;
  pointer-events: none; transition: left .5s ease-in-out, top .5s ease-in-out;
}

@media (prefers-reduced-motion: reduce) {
  .seat.ping .tbl, .row-b.in .g, .row-f.in .g, .fx,
  .seat .bub.in, .seat .tipTag.in { animation: none; }
  .flying, .gFill { transition: none; }
}

/* ---------- the diner: what coins are for ---------- */
.scrTitle { text-align: center; font-size: 22px; margin: 4px 0 8px; }
#shopWallet {
  text-align: center; font-size: 17px; font-weight: 800; color: #8a6a4a;
  background: #fff; border: 3px solid #fbcfd6; border-radius: 14px;
  padding: 9px; margin-bottom: 10px;
}
/* Reserved height whether or not anything is in it, so buying the first palm
   does not shove the whole shelf down the screen. */
#shopRoom {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: center;
  min-height: 76px; background: linear-gradient(#ffe1e6, #ffd0d8);
  border: 3px solid #fbcfd6; border-radius: 16px; padding: 10px; margin-bottom: 12px;
}
#shopRoom .bare { font-size: 14px; font-weight: 700; color: #b0977a; }
#shopShelf {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px;
  overflow-y: auto; align-content: start; min-height: 150px;
}
/* Fixed rows, for the reason the grocer's shelf in Chef Quest has them: left to
   size itself a tile measured one height on one viewport and another on the
   next, and clipped its own price row on the smaller one. */
.decorItem {
  background: #fff; border: 3px solid #fbcfd6; border-radius: 14px;
  display: grid; grid-template-rows: 34px 30px 20px; justify-items: center; align-items: center;
  height: 98px; padding: 4px; text-align: center; font-family: inherit; color: #4a2c2a;
}
.decorItem .nm { font-size: 12.5px; font-weight: 700; line-height: 1.15; overflow: hidden; }
.decorItem .pr { font-size: 13px; font-weight: 800; color: #8a6a4a; }
.decorItem.have { border-color: #7fc98d; background: #f2fbf3; }
.decorItem.have .pr { color: #3f8f52; }
/* Dimmed, not hidden: the ladder IS the thing to play towards, and a locked
   shelf you cannot see is not a goal. */
.decorItem.cant { opacity: .5; }

/* Drawn, like everything else in this game (R9). */
.dc { display: block; width: 30px; height: 30px; position: relative; }
.roomDecor {
  position: absolute; top: calc(var(--wall) * 0.16); z-index: 5;
  transform: translateX(-50%) scale(calc(0.8 * var(--k)));
}
.dc-plant  { border-radius: 0 0 34% 34%; background: linear-gradient(#c8874f 0 100%); }
.dc-plant::before { content: ''; position: absolute; left: 50%; bottom: 55%; transform: translateX(-50%);
  width: 130%; height: 120%; border-radius: 60% 60% 40% 40%;
  background: radial-gradient(circle at 30% 70%, #4ade80 0 40%, transparent 42%),
              radial-gradient(circle at 70% 65%, #22c55e 0 38%, transparent 40%),
              radial-gradient(circle at 50% 30%, #16a34a 0 36%, transparent 38%); }
.dc-neon   { border-radius: 999px; background: linear-gradient(#f43f5e, #be123c);
  box-shadow: 0 0 9px rgba(244,63,94,.9), inset 0 0 5px rgba(255,255,255,.6); height: 16px; margin: 7px 0; }
.dc-juke   { border-radius: 46% 46% 12% 12%; background: linear-gradient(#7c3aed 0 40%, #4c1d95 40%);
  box-shadow: inset 0 3px 0 rgba(255,255,255,.35); }
.dc-juke::after { content: ''; position: absolute; left: 22%; top: 46%; width: 56%; height: 30%;
  border-radius: 3px; background: repeating-linear-gradient(90deg, #fde68a 0 3px, #f59e0b 3px 6px); }
.dc-art    { border-radius: 3px; background: #fff8f0; border: 3px solid #a8836a;
  background-image: radial-gradient(circle at 35% 60%, #60a5fa 0 26%, transparent 28%),
                    radial-gradient(circle at 65% 42%, #fbbf24 0 22%, transparent 24%); }
.dc-rug    { border-radius: 5px; height: 22px; margin: 4px 0;
  background: repeating-conic-gradient(#f9efe0 0 25%, #d9b99b 0 50%) 0 0 / 10px 10px; }
.dc-cat    { border-radius: 48% 48% 40% 40%; background: linear-gradient(#9ca3af, #4b5563); }
.dc-cat::before, .dc-cat::after { content: ''; position: absolute; top: -18%; width: 0; height: 0;
  border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 8px solid #6b7280; }
.dc-cat::before { left: 10%; } .dc-cat::after { right: 10%; }
.dc-trophy { border-radius: 40% 40% 8% 8%; background: linear-gradient(#fde68a, #d97706);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.6); }
.dc-trophy::after { content: ''; position: absolute; left: 50%; bottom: -14%; transform: translateX(-50%);
  width: 60%; height: 16%; border-radius: 2px; background: #92400e; }

/* The tier card's progress. "Lv 12/12" read as a score; a bar plus words says
   what it is, and stops being a number once you have finished. */
.tierCard .prog {
  width: 82%; height: 5px; border-radius: 999px; background: #ffe4e9; overflow: hidden;
}
.tierCard .prog > i { display: block; height: 100%; background: #e11d48; border-radius: 999px; }
.tierCard.sel .prog { background: #fff; }

/* min/max as a pair, and the table sizes as chips */
.dual { display: flex; gap: 8px; }
.dual input[type=range] { flex: 1; min-width: 0; }
.kinds { display: flex; gap: 7px; flex-wrap: wrap; }
.kindChip {
  display: flex; align-items: center; gap: 5px; min-height: 44px;
  padding: 6px 11px; border-radius: 12px; font-weight: 800; font-size: 14px;
  border: 3px solid #fbcfd6; background: #fff; color: #4a2c2a; opacity: .5;
}
.kindChip.on { border-color: #e11d48; background: #ffe4e9; opacity: 1; }
.kindChip .dc { width: 20px; height: 20px; }
.kk-stool { border-radius: 50%; background: linear-gradient(#c8874f, #a76a3a); }
.kk-two   { border-radius: 46% / 38%; background: linear-gradient(#fff 0 45%, #f0cfa8 45%); border: 2px solid #a8836a; }
.kk-booth { border-radius: 6px 6px 34% 34%; background: linear-gradient(var(--vinyl, #d94a5a) 0 46%, #fff 46%); }
.kk-round { border-radius: 50%; background: linear-gradient(#fff 0 44%, #f0cfa8 44%); border: 2px solid #a8836a; }

/* A table the room has not opened yet — roped off, not missing.
   The dim goes on the FURNITURE, not the seat: dimming the whole element took
   the countdown down with it, and the countdown is the one thing on a closed
   table anybody is meant to read. */
.seat.closed .tbl, .seat.closed .bench, .seat.closed .chairs, .seat.closed .sh {
  opacity: .38; filter: saturate(.35);
}
.seat.closed .tbl { border-style: dashed; }

/* ---------- the mode row: segmented, like every other multi-mode game ---------- */
.pickLabel { font-size: 13px; font-weight: 800; color: #9f7a72; margin: 6px 0 5px; }
#modeRow { display: flex; gap: 8px; margin-bottom: 4px; }
.pick {
  flex: 1; min-width: 0; padding: 10px 6px; border-radius: 16px;
  border: 3px solid #fbcfd6; background: #fff; color: #4a2c2a;
  font-weight: 800; font-size: 14px; min-height: 44px;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
}
.pick .pe { font-size: 21px; line-height: 1; }
.pick small { font-weight: 700; font-size: 10.5px; color: #9f7a72; line-height: 1.2; text-align: center; }
.pick.sel { border-color: #e11d48; background: #ffe4e9; }
.pick.sel small { color: #a4565f; }

/* the Relaxed switch — what Sandbox used to be */
.toggle {
  display: flex; align-items: center; gap: 9px; width: 100%; min-height: 44px;
  padding: 9px 11px; border-radius: 12px; border: 3px solid #fbcfd6;
  background: #fff; color: #4a2c2a; font-weight: 800; font-size: 14px; text-align: left;
}
.toggle .tick {
  flex: none; width: 22px; height: 22px; border-radius: 7px;
  border: 3px solid #cdb6a4; background: #fff;
}
.toggle.on { border-color: #e11d48; background: #ffe4e9; }
.toggle.on .tick { border-color: #e11d48; background: #e11d48; position: relative; }
.toggle.on .tick::after {
  content: ''; position: absolute; left: 4px; top: 0px;
  width: 5px; height: 10px; border: solid #fff; border-width: 0 3px 3px 0;
  transform: rotate(42deg);
}

/* Every level you have reached stays reachable. One scrolling row rather than a
   grid, so eighteen levels cost one line instead of three. */
#lvlWrap { margin-bottom: 4px; }
#lvlRow {
  display: flex; gap: 6px; overflow-x: auto; padding-bottom: 4px;
  scrollbar-width: none;
}
#lvlRow::-webkit-scrollbar { display: none; }
.lvl {
  flex: none; min-width: 44px; min-height: 44px; border-radius: 12px;
  border: 3px solid #fbcfd6; background: #fff; color: #4a2c2a;
  font-weight: 800; font-size: 15px;
}
.lvl.sel { border-color: #e11d48; background: #ffe4e9; }
#lvlNote { font-weight: 700; color: #c48b95; }

/* A table the room has not opened yet: the bar sits where the patience bar
   sits, and FILLS instead of draining — the difference between waiting for a
   thing and losing one. */
.lockbar {
  width: 70%; border-radius: calc(3px * var(--s));
  background: rgba(0, 0, 0, .16); overflow: hidden; z-index: 5; min-height: 4px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .5);
}
.lockbar > i { display: block; height: 100%; width: 0; background: #38bdf8; transition: width .3s linear; }
.locktime {
  display: flex; align-items: center; justify-content: center;
  font-weight: 900; font-size: calc(var(--seat) * var(--s) * 0.18); line-height: 1;
  color: #0369a1; background: #e0f2fe;
  border: calc(1.5px * var(--s)) solid #7dd3fc;
  border-radius: 999px; padding: 0 calc(5px * var(--s)); z-index: 6; white-space: nowrap;
}
/* only the imminent one carries a number; an empty pill over nothing is worse
   than no pill (the same rule the thought bubble follows) */
.locktime:empty { display: none; }

/* ---------- the legend: the real classes, at a readable size ---------- */
.lgSub { font-weight: 800; font-size: 13.5px; color: #9f7a72; margin: 10px 0 5px; }
.legend { display: flex; flex-direction: column; gap: 6px; }
.lgRow { display: flex; align-items: center; gap: 10px; }
.lgArt {
  flex: none; width: 46px; height: 40px; display: flex;
  align-items: center; justify-content: center; position: relative;
  --seat: 64px; --s: 1; --k: 1;
}
.lgTxt { display: flex; flex-direction: column; min-width: 0; }
.lgTxt b { font-size: 14px; }
.lgTxt small { font-size: 12.5px; color: #9f7a72; line-height: 1.3; }

/* a miniature table, in the state being explained */
.lgSeat { position: relative; width: 40px; height: 38px; display: block; }
.lgSeat .tbl {
  position: absolute; left: 50%; bottom: 2px; transform: translateX(-50%);
  width: 34px; height: 11px; border-radius: 50% / 40%;
  background: linear-gradient(#ffffff 0 42%, #ffe9cf 42% 72%, #f0cfa8 72% 100%);
  border: 2px solid #a8836a;
}
.lgSeat .bub {
  position: absolute; left: 50%; top: 0; transform: translateX(-50%);
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 20px; background: #fffdf8;
  border: 2px solid #cdb6a4; border-radius: 999px;
}
.lgSeat.ready .tbl { background: linear-gradient(#eaffd0 0 46%, #86efac 46% 100%); border-color: #4ade80; }
.lgSeat.waiting .tbl { border-color: #fb923c; }
.lgSeat.held .tbl { border-style: dashed; border-color: #0ea5e9; }
.lgSeat.served .tbl { background: linear-gradient(#faf0ff 0 46%, #ddb8fb 46% 100%); }
.lgSeat.dirty .tbl { background: linear-gradient(#efe6dc 0 46%, #cbb9a6 46% 100%); border-color: #a8927c; }
.lgSeat.closed .tbl { opacity: .38; border-style: dashed; }

.lgBar { display: block; width: 40px; height: 8px; border-radius: 4px; background: rgba(0,0,0,.18); overflow: hidden; }
.lgBar > i { display: block; height: 100%; background: #22c55e; }
.lgBar.warn > i { background: #f59e0b; }
.lgBar.crit > i { background: #ef4444; }
.lgBar.held > i { background: #38bdf8; }
.lgBar.lockbar { min-height: 0; box-shadow: none; }
.lgBar.lockbar > i { background: #38bdf8; }
.lgArt .tipTag, .lgArt .locktime { position: static; font-size: 12px; padding: 2px 6px; }

.lgDoor {
  width: 20px; height: 30px; border-radius: 3px 3px 0 0;
  background: linear-gradient(#a3714b, #7c5334); border: 2px solid #5c3d26;
}
.lgHob { display: flex; gap: 5px; }
.lgHob i { width: 12px; height: 12px; border-radius: 50%; background: #b9a289; box-shadow: inset 0 0 0 2px #8f7a63; }
.lgHob i.lit { background: radial-gradient(circle at 50% 45%, #fde68a, #f97316 70%, #dc2626); box-shadow: 0 0 6px rgba(249,115,22,.85); }
.lgWaiter { display: flex; flex-direction: column; align-items: center; }
.lgWaiter .hd { font-size: 20px; line-height: 1; font-style: normal; }
.lgWaiter .bd { width: 16px; height: 13px; margin-top: -2px; border-radius: 42% 42% 26% 26%; background: #0ea5e9; }
.lgParty { display: flex; gap: 2px; }
.lgParty i { font-size: 17px; font-style: normal; }
