/* ☕ THE COFFEE CUP'S COUNTER — the tray (Trym, 19 Sep: the tray, not a card).
 *
 * ⭐ WHY A TRAY AND NOT A CARD, in one line of CSS terms: an open card owns every tap and every key
 * (banana-town.js: `if (!panel.hidden) return;` in the view's pointerdown, `const kb = panel.hidden`
 * in the walk), so behind a card the banana cannot be walked at all — and the one choice the whole
 * café is built on, "serve the next cup, or step out and relight the lamp", could not physically be
 * made. The tray leaves the square alive behind it.
 *
 * ⚠️ IT IS NOT `.tw-tray`. The pocket owns that class, that id and z 901. This is `.tw-cup`.
 * ⚠️ It is a child of #twView, the only positioned, isolated, overflow-clipped box in the town —
 *    .tw-stage and .tw-wrap are position:static, so anything else anchors to the page instead.
 * ⚠️ It is OUTSIDE both `.is-inside` hide lists, so walking into a room does not hide it: the chunk
 *    closes it by hand on enterRoom.
 * ⚠️ Motion is transform and opacity ONLY (design library §21.4) — a @keyframes naming bottom,
 *    height, filter, box-shadow or text-shadow is an instant red build (check-design.mjs).
 *
 * Shared by /town/ and the bench at /dev/cafe/, so the counter is thumbed and shipped from one file.
 */

/* the tray sits on the bottom edge, under the HUD strip and over the world; ≤150px so three
   quarters of the square stays in view and the queue, the lamp and the ghost are all still there */
.tw-cup {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1200;
  box-sizing: border-box; max-height: 150px;
  background: #1a120c; color: #fffdf5;
  border-top: 4px solid #000; box-shadow: 0 -4px 0 rgba(0, 0, 0, 0.45);
  padding: 0.45rem 0.6rem 0.55rem;
  display: grid; gap: 0.4rem;
  transform: translateY(0); transition: transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
  /* ⚠️ the pour is a HOLD, and a vertical drag on a canvas that can scroll gets pointercancel after
     two moves — measured. Nothing in here scrolls, and the canvas takes the pointer outright. */
  touch-action: none; overscroll-behavior: contain;
}
.tw-cup[hidden] { display: none; }
/* folded: you stepped off the counter mark. The customer keeps its ticket; the tray just goes down. */
.tw-cup.is-folded { transform: translateY(100%); }

/* ---- the ticket: the order, as PICTURES. Never words (docs/town-cafe-plan.md §4) -------------- */
.tw-cup__top { display: flex; align-items: center; gap: 0.5rem; min-height: 26px; }
.tw-cup__tick { display: flex; align-items: center; gap: 4px; }
.tw-cup__pip {
  width: 16px; height: 16px; border: 2px solid #000; background: #6b4a2b;
  box-shadow: 1px 1px 0 #000;
}
.tw-cup__pip--milk { background: #f3e6cf; }
.tw-cup__pip--foam { background: #fff; border-radius: 999px; }
.tw-cup__pip--dark { background: #2a1330; }
/* the station you are on, and the two you are not */
.tw-cup__steps { display: flex; gap: 5px; margin-left: auto; }
/* 🪙 the shift's tips so far — a coin and a number, popped a little each time a cup pays */
.tw-cup__tips { display: inline-flex; align-items: center; gap: 4px; margin-left: 0.5rem; padding: 2px 6px; border: 2px solid #000; background: #2a1e12; color: #ffe135; font-style: normal; font-weight: 800; font-size: 0.8rem; line-height: 1; }
.tw-cup__tips svg { display: block; }
.tw-cup__tips[hidden] { display: none; }
.tw-cup__tips.is-pop { animation: tw-tip-pop 320ms ease-out; }
@keyframes tw-tip-pop { 0% { transform: scale(1); } 40% { transform: scale(1.25); } 100% { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .tw-cup__tips.is-pop { animation: none; } }
.tw-cup__step { width: 9px; height: 9px; border: 2px solid #000; background: #3a2a1c; }
.tw-cup__step.is-now { background: #ffe135; }
.tw-cup__step.is-done { background: #7bc35e; }

/* ---- the gauge: one bar, three meanings (a needle, a level, a swell) -------------------------- */
.tw-cup__bar {
  position: relative; height: 34px; border: 3px solid #000; background: #2a1a10;
  box-shadow: inset 0 2px 0 rgba(0, 0, 0, 0.5);
  overflow: hidden;
}
/* the band to land in. ⚠️ a STATIC filter under an opacity pulse — never an animated filter */
.tw-cup__zone {
  position: absolute; top: 0; bottom: 0; background: rgba(123, 195, 94, 0.32);
  border-left: 2px solid #7bc35e; border-right: 2px solid #7bc35e;
  filter: drop-shadow(0 0 4px rgba(123, 195, 94, 0.7));
  animation: twCupZone 1.5s ease-in-out infinite alternate;
}
@keyframes twCupZone { from { opacity: 0.72; } to { opacity: 1; } }
/* the pour fills the bar from the left; the grinder and the milk ride a needle across it */
.tw-cup__zone[hidden] { display: none; }
/* ⚠️ A HORIZONTAL-BAND GRADIENT ONLY. The fill is scaleX'd every frame (town-cafe.js paint), so any
   detail with an x dimension stretches from a sliver to a slab as the cup fills. A band across the top
   is invisible to that — and it is what turns a brown progress bar into coffee with crema on it. */
.tw-cup__fill { position: absolute; left: 0; top: 0; bottom: 0; width: 100%; background: linear-gradient(#e6b072 0 7px, #a86a2e 7px); transform-origin: 0 50%; transform: scaleX(0); }
.tw-cup__needle { position: absolute; top: -2px; bottom: -2px; width: 6px; margin-left: -3px; background: #ffe135; border: 2px solid #000; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6); }
/* the milk wants three taps: each one leaves its mark where it fell, coloured by how it landed, so a
   player can see two down and one to go without a single word on the tray */
.tw-cup__tap { position: absolute; top: 3px; height: 10px; width: 4px; margin-left: -2px; border: 2px solid #000; background: #d64030; }
.tw-cup__tap.is-g1 { background: #f0b428; }
.tw-cup__tap.is-g2 { background: #7bc35e; }
.tw-cup__tap[hidden] { display: none; }

/* ---- the three stations, dressed ---------------------------------------------------------------
 * ⭐ Trym, 20 Sep: "we can probably make the game-part of the coffee making process a bit more visual
 * with some animations and movements and visuals to reflect grinding and foaming and all that." He is
 * right and it was literally true: grind was a yellow line sliding, milk was the same yellow line
 * sliding, and pour was a flat brown block growing. Three different gestures, three identical pictures.
 *
 * Everything below hangs off `[data-st]` on the tray, which mountCounter sets per station — so it costs
 * no per-frame JS, and the bench at /dev/cafe/ dresses itself the same way.
 *
 * ⚠️ THE TRAY HAS NO VERTICAL ROOM AT ALL. Measured at 360×740: it renders at exactly 150px, pinned
 * against its own max-height, while its four rows want 161.7px. The deepest rope mark clears the tray's
 * top edge by 5.7 SCREEN PIXELS. Nothing here may add a row, grow the bar or add padding — every one of
 * these lives inside the 34px gauge that already exists.
 * ⚠️ TRANSFORM AND OPACITY ONLY (design library §21.4). A keyframe naming filter, box-shadow,
 * text-shadow or any box metric is a red build — and note that tools/check-design.mjs walks src/ only,
 * so in THIS file the rule is held by hand.
 */

/* ☕ GRIND — the bar becomes a burr turning under the blade: a field of ground speckle crawling one
   period, and the needle juddering the way a grinder shakes. inset's -8px right keeps the slide from
   ever exposing an edge; the bar's own overflow:hidden clips the rest. */
.tw-cup[data-st="grind"] .tw-cup__bar::before {
  content: ''; position: absolute; inset: 0 -8px 0 0;
  background: repeating-linear-gradient(90deg, #3a2517 0 3px, #2a1a10 3px 7px);
  opacity: 0.85; animation: twCupGrind 420ms linear infinite;
}
@keyframes twCupGrind { to { transform: translateX(-7px); } }
/* ⚠️ the needle's x is written as `left` from JS, so a transform here composes with it instead of fighting */
.tw-cup[data-st="grind"] .tw-cup__needle { animation: twCupJudder 110ms steps(2) infinite alternate; }
@keyframes twCupJudder { from { transform: translateY(-1px); } to { transform: translateY(1px); } }

/* ☕ POUR — a stream falls into the cup, and ONLY while the thumb is actually down, so the hold finally
   has a picture of itself. ⚠️ it hangs off the BAR, never the fill: anything inside the fill is scaleX'd
   with it and a 5px stream would be a 0.1px sliver at the start of a pour. */
.tw-cup[data-st="pour"] .tw-cup__bar::after {
  content: ''; position: absolute; top: 0; left: 50%; width: 7px; height: 100%;
  /* ⚠️ LIGHT, NOT DARK. #8a5423 on the bar's #2a1a10 was a dark-brown sliver on dark brown and did not
     appear in a single one of the four phone crops. Falling coffee catches the light; this is that. */
  margin-left: -3px; background: linear-gradient(#f0c088, #c07a30); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
  opacity: 0; transform-origin: 50% 0;
}
.tw-cup.is-pouring .tw-cup__bar::after { animation: twCupStream 360ms linear infinite; }
@keyframes twCupStream {
  0% { opacity: 0; transform: translateY(-100%) scaleY(0.6); }
  25% { opacity: 1; }
  100% { opacity: 0; transform: translateY(0) scaleY(1); }
}

/* ☕ MILK — foam rises off the bottom of the gauge and the needle becomes the head on it. The bubbles are
   three radial gradients baked into ONE element (the homestead's steam recipe), so the whole swell is a
   single compositor layer rather than three. */
.tw-cup[data-st="milk"] .tw-cup__bar::before {
  content: ''; position: absolute; inset: 0;
  /* ⚠️ BIG ENOUGH TO BE FOAM. At r=2-3 these rendered as faint grey specks in a 34px bar on a phone —
     measured, not guessed. Five bubbles at r=4-6, opaque, is the smallest that reads as milk swelling. */
  background:
    radial-gradient(circle 6px at 14% 86%, rgba(255, 255, 255, 0.96) 0 100%, transparent 100%),
    radial-gradient(circle 4px at 34% 94%, rgba(255, 253, 245, 0.88) 0 100%, transparent 100%),
    radial-gradient(circle 5px at 52% 88%, rgba(255, 255, 255, 0.94) 0 100%, transparent 100%),
    radial-gradient(circle 4px at 71% 95%, rgba(255, 253, 245, 0.86) 0 100%, transparent 100%),
    radial-gradient(circle 6px at 88% 87%, rgba(255, 255, 255, 0.92) 0 100%, transparent 100%);
  animation: twCupFoam 1.4s ease-out infinite;
}
@keyframes twCupFoam {
  0% { opacity: 0; transform: translateY(7px); }
  30% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-28px); }
}
/* ⚠️ THE NEEDLE STAYS YELLOW AT THE MILK. A white dome echoing the foam pip was the idea; on screen it
   landed inside its own pale-green band and cut it into two blocks that read as TWO targets. The needle
   is the one thing in the gauge that must never be mistaken for the target, so it keeps its own colour
   at every station and the foam does the talking. */

/* ☕ and the biggest colour surface in the tray stops being the same yellow at every station. The thumb
   already lives on this button, so it is the one place a station's colour is certainly seen. */
.tw-cup[data-st="grind"] .tw-cup__go { background: linear-gradient(#b98a52, #8a5c30); color: #1d1206; }
.tw-cup[data-st="pour"] .tw-cup__go { background: linear-gradient(#ffc966, #e89a2a); }
.tw-cup[data-st="milk"] .tw-cup__go { background: linear-gradient(#fff6e2, #e8d8b8); }

/* ---- the button the thumb lives on ------------------------------------------------------------ */
.tw-cup__go {
  appearance: none; font: inherit; cursor: pointer; width: 100%;
  border: 3px solid #000; box-shadow: 3px 3px 0 #000;
  background: linear-gradient(#ffe14d, #f2c012); color: #241c00;
  font-family: "Archivo Black", sans-serif; font-size: 0.95rem; letter-spacing: 0.03em;
  padding: 0.5rem 0.6rem; white-space: nowrap;
  touch-action: none;
}
.tw-cup__go:active, .tw-cup__go.is-held { transform: translate(2px, 2px); box-shadow: 1px 1px 0 #000; }
.tw-cup__go[disabled] { opacity: 0.55; cursor: default; }
.tw-cup__go[hidden] { display: none; }

/* the shift's own line: no numbers a clock could read, just where you are.
   ⚠️ IT COLLAPSES WHEN IT IS EMPTY. A permanent `min-height: 1em` left 21px of dead dark band along the
   bottom of the tray whenever a cup was up — it read as an unfinished edge, it pushed the tray's last
   3px outside the clipped view on every phone, and it was what took the tray over 30% of the square on
   the two short ones (31.7% at 360×640). Reserving room for a line that is usually not there costs the
   square the one thing the tray form was chosen to protect. */
.tw-cup__note { margin: 0; font-size: 0.74rem; opacity: 0.8; font-weight: 700; }
.tw-cup__note:empty { display: none; }

/* ---- patience is the BODY, never a bubble, and never a COLOUR either -------------------------- */
/* ⭐ THE SHADOW LADDER IS GONE (Trym, 20 Sep: "the shadow color underneath the banana isn't very
   pedagogic, i don't understand what it means so i don't think that's something we should use for
   anything visually"). It tinted the ellipse a waiting banana stands on green, then amber, then red.
   Nothing else in this world reads a state off the floor, so nobody could learn it — and a shadow
   that turns green makes a banana look like it is standing on grass, not like it is being patient.
   Patience is acted by the body now, in town-folk.js: still, then shifting weight, then turned away
   from the counter. `.tw-wait` survives as the handle a walk selects on and carries no colour. */

/* ⚠️ THE TOAST HAS NOWHERE TO STAND AT THE BOTTOM OF A SHIFT. It is z 2000 and docks at bottom 14,
   so it landed square on the gauge — then raising it to 172 put it square on the barista's face in
   the serving window instead, measured at 360×740: toast 419–495, the banana in the window 455–510.
   Both halves of the screen are spoken for while a shift is on, so the world's voice goes to the TOP
   of the view, under the HUD strip, where the only thing it can cover is sky. */
.tw-toast.is-above-tray { top: var(--tw-toast-top, 44px); bottom: auto; }

@media (prefers-reduced-motion: reduce) {
  .tw-cup { transition: none; }
  .tw-cup__zone { animation: none; opacity: 1; }
  /* ⚠️ EVERY station skin is named here, or it keeps moving for somebody who asked for stillness. The
     colours and the crema stay — they are not motion, and they are most of what makes a station legible. */
  .tw-cup__bar::before, .tw-cup__bar::after, .tw-cup__needle { animation: none; }
  .tw-cup[data-st="pour"] .tw-cup__bar::after { opacity: 0; }
}

/* 🧾 the receipt, at clock-out. A CARD is right here and nowhere else in the café: the shift is over,
   so the square no longer has to be visible behind it. */
.tw-cup__till h2 { font-family: "Archivo Black", sans-serif; color: #ffb347; font-size: 1rem; margin: 0 0 0.4rem; letter-spacing: 0.03em; }
.tw-cup__take { margin: 0 0 0.4rem; font-size: 1.05rem; font-weight: 800; color: #ffe135; }
/* the one cup that came out right, named. The only place the three drinks' names are ever read. */
.tw-cup__best { margin: 0 0 0.4rem; font-size: 0.86rem; font-weight: 700; color: #a8e08a; }

