/* COFFEE PROBATION — the offer (js/coffee-offer.js): the parked COFFEE JOB chip, the clerk's card and its STOP FIRST
   flash, linked after parking.css (COFFEE-PROGRESS.md D21, D29). The same stickers as the rest of the car (bone and
   charcoal, the world's 2px ink line and a hard shadow, a little crooked), with the cup's burgundy PROBATION sleeve and a
   coffee ring on the clerk's paper. Only the chip and the card take pointers (the layer passes every touch through to
   the world). Text is at least 14 px and every button at least 48 px tall; everything stays inside the safe area.
   The parking HUD's own coffee pieces (the sixth row, the slip, the receipt, the strip) are in css/parking.css. */

.coffee {
  --coffee-line: #17110f; --coffee-bone: #f0e2bf; --coffee-paper: #ece4cf; --coffee-ink: #1d1a14; --coffee-char: rgba(23, 17, 15, .9);
  --coffee-orange: #e7782b; --coffee-sleeve: #7a1f24; --coffee-brown: #3b2215;
  --coffee-target: 3rem; /* ~48 CSS px */
  --coffee-left: max(var(--gutter, 1rem), calc(env(safe-area-inset-left, 0px) + .25rem));
  --coffee-right: max(var(--gutter, 1rem), calc(env(safe-area-inset-right, 0px) + .25rem));
  --coffee-bottom: max(.75rem, calc(env(safe-area-inset-bottom, 0px) + .25rem));
  /* below the hub's title and its SOUND / SHOP / EXIT VEHICLE row (the parking HUD's own top) */
  --coffee-top: calc(env(safe-area-inset-top, 0px) + clamp(.75rem, 2vw, 1.25rem) + 3.3rem);
  --coffee-vw: calc((100vw - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px)) / 100);
  /* how tall the parking HUD's thumb controls are (css/parking.css --parking-cluster): an engine-on card stays above them */
  --coffee-cluster: 11rem;
  /* the visible screen: parked, the hub keeps its 30rem minimum height (hub.css), taller than a landscape phone */
  color: var(--coffee-bone); height: min(100%, 100svh); inset: 0 0 auto 0; pointer-events: none; position: absolute; z-index: 3;
}
.coffee[hidden], .coffee [hidden] { display: none !important; }
.hub[data-hub-state="fallback"] .coffee { display: none !important; }
.coffee button { cursor: pointer; font: inherit; }
.coffee button:focus-visible { outline: 3px solid var(--orange, #ff4f00); outline-offset: 2px; }

/* ---------- the chip: COFFEE JOB (parked, at rest; D29) ---------- */
.coffee__chip {
  -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; -webkit-user-select: none;
  align-items: center; background: var(--coffee-char); border: 2px solid var(--coffee-line); bottom: max(1rem, calc(env(safe-area-inset-bottom, 0px) + 1rem));
  box-shadow: 3px 3px 0 var(--coffee-line); color: var(--coffee-bone); display: flex; font-size: .875rem; font-weight: 900; gap: .55rem; left: var(--coffee-left);
  letter-spacing: .1em; line-height: 1.1; min-height: var(--coffee-target); padding: .3rem .7rem .3rem .45rem; pointer-events: auto; position: absolute;
  text-align: left; touch-action: none; transform: rotate(-1deg); user-select: none; width: 10.75rem;
}
.coffee__chip:active { box-shadow: 1px 1px 0 var(--coffee-line); translate: 2px 2px; }
@media (hover: hover) { .coffee__chip:hover { background: var(--orange, #ff4f00); color: var(--coffee-line); } }
/* a tiny paper cup with its burgundy sleeve */
.coffee__chip-cup {
  background: linear-gradient(transparent 0 38%, var(--coffee-sleeve) 38% 72%, transparent 72%), #efe3c4; border: 2px solid var(--coffee-line);
  clip-path: polygon(0 0, 100% 0, 82% 100%, 18% 100%); flex: none; height: 1.6rem; width: 1.3rem;
}
.coffee__chip-label { min-width: 0; }
/* short landscape phones: top right, on the second row under the hub's own buttons (bottom left is the steering pad's) */
@media (orientation: landscape) and (max-height: 480px) {
  .coffee__chip { bottom: auto; left: auto; right: var(--coffee-right); top: calc(env(safe-area-inset-top, 0px) + clamp(.75rem, 2vw, 1.25rem) + 6.75rem); }
}
/* desktop: bottom left, wider */
@media (orientation: landscape) and (min-height: 481px) {
  .coffee__chip { bottom: max(1.5rem, calc(env(safe-area-inset-bottom, 0px) + 1rem)); left: max(1.5rem, var(--coffee-left)); width: 13.75rem; }
}

/* ---------- the card: the clerk's offer ---------- */
.coffee__card {
  /* the clerk's paper with a coffee ring where the cup stood on it */
  background:
    radial-gradient(circle at 90% 30%, transparent 0 1.75rem, rgba(110, 68, 28, .2) 1.8rem 2.05rem, transparent 2.15rem),
    radial-gradient(circle at 86% 34%, transparent 0 1.9rem, rgba(110, 68, 28, .1) 1.95rem 2.1rem, transparent 2.2rem),
    var(--coffee-paper);
  box-shadow: 0 0 0 2.5px var(--coffee-line), .5rem .6rem 0 rgba(10, 8, 22, .82); box-sizing: border-box; color: var(--coffee-ink); display: grid; gap: .4rem;
  overflow: auto; overscroll-behavior: contain; padding: 0 1rem; pointer-events: auto; position: absolute; touch-action: pan-y; z-index: 2;
}
.coffee__card p { margin: 0; }
/* the cup's sleeve across the top */
.coffee__sleeve {
  background: var(--coffee-sleeve); color: var(--coffee-bone); font-size: .875rem; font-weight: 900; letter-spacing: .5em; margin: 0 -1rem .15rem !important;
  padding: .3rem 1rem .3rem 1.5rem; position: sticky; text-align: center; top: 0; z-index: 1;
}
.coffee__kicker { color: #6b4f3a; font-size: .875rem; font-weight: 900; letter-spacing: .12em; }
.coffee__card[data-coffee-stage="accepted"] .coffee__kicker { background: var(--coffee-ink); color: var(--coffee-bone); justify-self: start; padding: .15rem .45rem; }
.coffee__title { font-size: clamp(1.4rem, 3.2vw, 1.7rem); font-weight: 900; letter-spacing: -.01em; line-height: 1; }
.coffee__title:focus { outline: none; }
.coffee__route { font-family: 'Courier New', monospace; font-size: 1rem; font-weight: 700; }
.coffee__facts { font-size: .875rem; font-weight: 900; letter-spacing: .14em; }
.coffee__facts b { font-family: 'Courier New', monospace; font-size: 1.15rem; letter-spacing: 0; }
.coffee__min { background: var(--coffee-ink); color: var(--coffee-bone); font-size: .95rem; font-weight: 900; justify-self: start; letter-spacing: .08em; padding: .2rem .5rem; transform: rotate(-.8deg); }
.coffee__line { border-left: 3px solid var(--coffee-sleeve); font-family: 'Courier New', monospace; font-size: .9rem; font-weight: 700; line-height: 1.3; padding-left: .55rem; }
.coffee__best { font-family: 'Courier New', monospace; font-size: .9rem; font-weight: 700; }
.coffee__note { color: #4f4739; font-size: .875rem; font-weight: 700; line-height: 1.3; }
/* the buttons stay in reach while the words scroll above them (a short screen, the accepted card's extra line) */
.coffee__actions {
  background: var(--coffee-paper); bottom: 0; display: grid; gap: .5rem; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: .2rem -1rem 0;
  border-top: 1px dashed rgba(0, 0, 0, .3); padding: .45rem 1rem 1rem; position: sticky; z-index: 1;
}
.coffee__action {
  -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; -webkit-user-select: none;
  background: var(--coffee-ink); border: 2px solid var(--coffee-line); box-shadow: 3px 3px 0 rgba(0, 0, 0, .35); color: var(--coffee-paper); font-size: .875rem; font-weight: 900;
  letter-spacing: .1em; line-height: 1.15; min-height: var(--coffee-target); min-width: 0; padding: .45rem .6rem; touch-action: manipulation; user-select: none;
}
.coffee__action--go { background: var(--coffee-orange); color: var(--coffee-line); }
.coffee__action--off { background: transparent; color: var(--coffee-ink); }
.coffee__action:active { box-shadow: 1px 1px 0 var(--coffee-line); translate: 2px 2px; }
@media (hover: hover) { .coffee__action:hover { background: var(--orange, #ff4f00); border-color: var(--coffee-line); color: var(--coffee-line); } }
@media (prefers-reduced-motion: no-preference) {
  .coffee__card { animation: coffee-in .18s ease-out; }
  @keyframes coffee-in { from { opacity: 0; translate: 0 .75rem; } }
}

/* where it stands. Landscape and desktop: a centred panel (at most 26rem × 19rem) under the hub's top row, scrolling
   inside itself. Upright phones: a bottom sheet. With the engine on it stays in the HUD's space, clear of the thumb
   controls (the car may still be driven: W/S, the pedals and the pad are never captured). */
.coffee__card {
  bottom: var(--coffee-bottom); height: max-content; left: var(--coffee-left); margin: auto; max-height: min(19rem, calc(100% - var(--coffee-top) - var(--coffee-bottom)));
  right: var(--coffee-right); top: var(--coffee-top); transform: rotate(-.6deg); width: min(26rem, calc(100% - var(--coffee-left) - var(--coffee-right)));
}
@media (orientation: portrait) {
  .coffee__card { left: 50%; margin: 0; max-height: calc(100% - var(--coffee-top) - var(--coffee-bottom)); right: auto; top: auto; transform: translateX(-50%) rotate(-.6deg); width: min(calc(100vw - 2rem), 22.5rem); }
}
/* the engine on, with the thumb controls up: above them (upright: where the parking receipt stands) */
.hub:has(.parking[data-parking-controls="touch"]:not([hidden])) .coffee__card[data-coffee-where="engine"] {
  bottom: calc(var(--coffee-bottom) + var(--coffee-cluster) + .75rem); max-height: min(19rem, calc(100% - var(--coffee-top) - var(--coffee-bottom) - var(--coffee-cluster) - .75rem));
}
@media (orientation: portrait) {
  .hub:has(.parking[data-parking-controls="touch"]:not([hidden])) .coffee__card[data-coffee-where="engine"] { max-height: calc(100% - var(--coffee-top) - 7.5rem - var(--coffee-bottom) - var(--coffee-cluster) - .75rem); }
}
@media (orientation: landscape) { .coffee { --coffee-cluster: 8rem; } }
/* short landscape phones: the parked card is the centred panel; with the engine on it takes the band between the steering
   pad (or the assist screen) and D/R, as the parking receipt does (the same sizes as css/parking.css) */
@media (orientation: landscape) and (max-height: 500px) {
  .coffee { --coffee-cluster: 6.75rem; --coffee-top: calc(env(safe-area-inset-top, 0px) + clamp(.75rem, 2vw, 1.25rem) + 3.3rem); }
  .coffee__card { gap: .3rem; max-height: calc(100% - var(--coffee-top) - var(--coffee-bottom)); padding: 0 .85rem; }
  .coffee__actions { margin-inline: -.85rem; padding: .35rem .85rem .8rem; }
  /* the band is short: the sleeve already says PROBATION, and with the engine on the card's own note is the status line's */
  .coffee__card[data-coffee-stage="offer"] .coffee__kicker, .coffee__card[data-coffee-where="engine"] .coffee__note { display: none; }
  .coffee__sleeve { margin: 0 -.85rem .1rem !important; padding-block: .2rem; }
  .coffee__title { font-size: 1.3rem; }
  .hub:has(.parking:not([hidden])) .coffee__card[data-coffee-where="engine"] {
    bottom: calc(var(--coffee-bottom) + 2.75rem); height: auto; left: calc(var(--coffee-left) + min(15rem, calc(28 * var(--coffee-vw))) + .75rem); margin: 0;
    max-height: none; right: var(--coffee-right); top: calc(var(--coffee-top) + 3.6rem); transform: rotate(.5deg); width: auto;
  }
  .hub:has(.parking[data-parking-controls="touch"]:not([hidden])) .coffee__card[data-coffee-where="engine"] {
    bottom: var(--coffee-bottom); left: calc(var(--coffee-left) + clamp(11rem, calc(30 * var(--coffee-vw)), 17rem) + .75rem); max-height: none;
    right: calc(var(--coffee-right) + var(--coffee-target) + 2 * clamp(4.25rem, calc(11 * var(--coffee-vw)), 5.5rem) + 1.5rem);
  }
}

/* (lead, phase 1 gate) the engine-on card in the short-landscape band is narrow: with notch insets the title and the
   minimum wrapped and DELIVER AT LEAST 60% slid under the buttons. One line each, so the route, the limit and the
   minimum are all in view before TAKE THE JOB (D21); still 14 px or more. */
@media (orientation: landscape) and (max-height: 500px) {
  .coffee__card[data-coffee-where="engine"] .coffee__title { font-size: 1.15rem; white-space: nowrap; }
  .coffee__card[data-coffee-where="engine"] .coffee__min { font-size: .875rem; letter-spacing: .03em; white-space: nowrap; }
}

/* (phase 2, the phase-1 carried low) desktop: the engine-on card (row 6) scrolled its last line, the note, under its sticky
   buttons at first view (28 px over 19rem at 1280x720 and 1440x900). Its kicker goes, as in short landscape: the sleeve
   already says PROBATION, and this card comes from the selector, not from the clerk's door. */
@media (orientation: landscape) and (min-height: 501px) {
  .coffee__card[data-coffee-where="engine"][data-coffee-stage="offer"] .coffee__kicker { display: none; }
}

/* STOP FIRST: the engine-on acceptance found the car moving (D21); a sticker over the HUD for a moment */
.coffee__flash {
  background: var(--coffee-orange); border: 2px solid var(--coffee-line); box-shadow: 3px 3px 0 var(--coffee-line); color: var(--coffee-line); font-size: 1rem; font-weight: 900;
  left: 50%; letter-spacing: .16em; margin: 0; padding: .5rem 1rem; pointer-events: none; position: absolute; top: 42%; transform: translate(-50%, -50%) rotate(-2deg); white-space: nowrap;
}

/* ---------- the key fob's TURN THE KEY while a job is pending (D21) ----------
   The button's own text stays (TURN THE KEY · PARKING TEST, in the page); here it reads COFFEE PROBATION instead, and
   js/coffee-offer.js gives it the same accessible name. */
.hub[data-coffee-pending] .hub-doc__action[data-parking-start] { font-size: 0; letter-spacing: 0; }
.hub[data-coffee-pending] .hub-doc__action[data-parking-start]::after { content: 'TURN THE KEY \B7  COFFEE PROBATION'; font-size: .7rem; letter-spacing: .16em; }

/* ---------- the cockpit's captions while the card is up ----------
   The clerk's line is on the card too: a caption must not lie across it. Upright phones (the card is a bottom sheet):
   captions go up under the hub's top row; short landscape has no room beside the card: they wait (the line is on it). */
@media (orientation: portrait) {
  .hub:has(.coffee__card:not([hidden], [data-coffee-where="engine"])) :is(.hub__subtitle, .hub__subtitle.is-on) { bottom: auto; top: calc(env(safe-area-inset-top, 0px) + clamp(.75rem, 2vw, 1.25rem) + 4.4rem); }
  /* (lead, phase 1 review) with the engine on there is no free spot: the top is the HUD's bar and status line, and
     parking.css's own caption places (READY's column above the pedals, the receipt's spot over the thumbs) are more
     specific, so a `top` here only stretched the caption over the card. With the engine on the clerk says nothing aloud
     (L7: his line is only printed on the card), so the cockpit's caption waits while the card is up, as in short
     landscape: hidden at once, so it never lies
     over the route, the limit or the minimum at first view (D21), and back with its usual fade when the card closes. */
  .hub:has(.coffee__card[data-coffee-where="engine"]:not([hidden])) :is(.hub__subtitle, .hub__subtitle.is-on) { opacity: 0; transition: none; }
}
@media (orientation: landscape) and (max-height: 500px) {
  .hub:has(.coffee__card:not([hidden])) :is(.hub__subtitle, .hub__subtitle.is-on) { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .coffee__chip:active, .coffee__action:active { translate: none; }
}

/* ---------- phase 3E (E7): the HUD under the coffee view ----------
   While the coffee view shows (k > 0), the glue sets data-coffee-view on the hub root. Its keep-clear band (js/coffee-camera.js
   band(): race-view's rule at coffee's base pose and 3° rake, from 1.75 m above the road at 15 m down to the road at 8 m) is a
   fixed share of the frame per kind: wide 35-57% of the height, portrait 31-43%, short landscape 35-62%. While the car moves
   no persistent HUD element may lie in it. Everything here is scoped to [data-coffee-view], so a parking test in the lot is
   laid out exactly as before; off the lot the estate view brings the flag and this layout with it (E5, E6).
   Transient cards (pause, help, the receipt, the open list of tests) are exempt and stay where they are. */

/* the slip steps aside on the way to the start (the status line says where to go; the screen's title names the job), on
   every layout: on the estate the way back is long and the slip would stand in the band on smaller frames */
.hub[data-coffee-view] .parking[data-parking-mode="repositioning"] .parking__brief { display: none; }

/* wide frames (desktop): the screen keeps under 58% of the height; the coffee strip stands beside it, bottom-aligned, not
   above it (at 1280x720 the strip above the screen reached 58 rows into the band); keyboard captions sit above the strip's
   height, under the band, clear of the screen at the left */
@media (orientation: landscape) and (min-height: 501px) {
  .hub[data-coffee-view] .parking__assist {
    max-height: min(calc(100% - var(--parking-top) - 3.75rem - var(--parking-bottom) - var(--parking-assist-lift)), calc(42% - var(--parking-bottom) - var(--parking-assist-lift)));
  }
  .hub[data-coffee-view] .parking .parking__coffee { bottom: -2px; left: calc(100% + .75rem); min-width: 13rem; transform: rotate(-.5deg); width: max-content; }
  .hub.hub[data-coffee-view]:has(.parking[data-parking-controls="keys"]:not([hidden])) :is(.hub__subtitle, .hub__subtitle.is-on) {
    bottom: calc(max(.75rem, env(safe-area-inset-bottom, 0px)) + 2.9rem + 4.75rem);
  }
}

/* upright phones: while the car moves, the captions go into the column above the pedals (beside the screen and the strip,
   under the band), as READY's do; parking.css's caption place over the strip (bottom 27rem) lies on the lane at 12-15 m */
@media (orientation: portrait) {
  .hub.hub.hub[data-coffee-view]:has(.parking[data-parking-controls="touch"]:not([hidden]):is([data-parking-mode="driving"], [data-parking-mode="repositioning"])) :is(.hub__subtitle, .hub__subtitle.is-on) {
    bottom: calc(max(.75rem, calc(env(safe-area-inset-bottom, 0px) + .25rem)) + 11.75rem); left: auto; max-width: calc(2 * clamp(4.25rem, 20vw, 5.5rem) + .5rem);
    right: max(var(--gutter, 1rem), calc(env(safe-area-inset-right, 0px) + .25rem)); text-align: left; transform: none;
  }
  /* the status line keeps its message to two lines (the hint is on the screen too), so the head ends above the band; set as
     short landscape's (.7rem, 1.15): at 360x800 the tilted status otherwise reached 0.4 px into the band (3E gate, lead) */
  .hub[data-coffee-view] .parking__msg:not(:empty) { -webkit-box-orient: vertical; -webkit-line-clamp: 2; display: -webkit-box; font-size: .7rem; line-height: 1.15; overflow: hidden; }
  /* (phase-4 review repair: with a notch's top inset, 59 px, the head starts that much lower, and TO START on a row of its own
     pushed the status line into the band at 390x844 and 360x800, up to 13 483 and 16 890 px². TO START stands under the bar's
     first button, beside the status line, which gives up its width: the same target, the same place in the bar's order) */
  .hub[data-coffee-view] .parking[data-parking-controls="touch"] .parking__bar { position: relative; }
  .hub[data-coffee-view] .parking[data-parking-controls="touch"] .parking__bar > [data-parking-cmd="retry"] { left: 0; position: absolute; top: calc(100% + .5rem); }
  .hub[data-coffee-view] .parking[data-parking-controls="touch"] .parking__top:has(> .parking__bar > [data-parking-cmd="retry"]:not([hidden])) > .parking__status {
    margin-left: calc(var(--parking-target) + .5rem); max-width: calc(100% - var(--parking-target) - .5rem);
  }
}

/* short landscape phones (844x390, 915x412): the band is the middle of the screen (35-62%). One row on top (the bar, then
   the status line, its message two lines at most), as the race's top row; while the car moves (and at the pause, whose card
   covers it) the screen goes to the bottom, against the pedals, under the band — without its title while driving (the
   selector is locked then); the coffee strip, compact, above the steering pad; the captions wait while the car is driven
   (no room under the band beside the thumbs: the race's place above the pedals is 36 px tall here). At READY and at the
   result the screen and the slip or the receipt are where they are in a parking test (the car stands still). */
@media (orientation: landscape) and (max-height: 500px) {
  .hub[data-coffee-view] .parking__top { flex-wrap: nowrap; }
  .hub[data-coffee-view] .parking__bar { flex: none; flex-wrap: nowrap; }
  .hub[data-coffee-view] .parking__status { flex: 0 1 auto; flex-wrap: nowrap; max-height: var(--parking-target); min-width: 0; overflow: hidden; }
  .hub[data-coffee-view] .parking__msg:not(:empty) { -webkit-box-orient: vertical; -webkit-line-clamp: 2; display: -webkit-box; font-size: .7rem; line-height: 1.15; min-width: 0; overflow: hidden; }
  /* (the screen stands against the pedals, at most 20% of the width: in the U-turn the look rests on its left clamp and the
     near road, 6 m off, lies low and left of centre, under where a wider screen would reach; P3E.6 V4) */
  /* (3E review repair, lead: in the U-turn the same left clamp puts the near road over the right end of the steering pad and of
     the strip above it: one or two of the lane's 13 points under the pad in 18-21 samples of the driven sweep, clear median
     38 % against P3E.6's 40. While the coffee view shows, the pad and the strip end at 24.5vw (13rem at most, the landscape
     pad's own 11rem at least) instead of 30vw (17rem); the knob and its 48 px target are unchanged. Phase 4 kept that width at
     the fill and READY too. Phase-4 review repair, K4: the width follows its own flag, [data-coffee-pad], at the end of this
     file, so it never changes under a held thumb) */
  .hub[data-coffee-view] .parking[data-parking-controls="touch"]:is([data-parking-mode="driving"], [data-parking-mode="repositioning"], [data-parking-mode="result"], [data-parking-mode="paused"]) {
    --coffee-screen-w: min(13.5rem, calc(20 * var(--parking-vw)));
  }
  /* (phase-4 review repair: not at the result. There the receipt covered the screen, its title — the selector — and the meter's
     picture, so no test and no GRAND PRIX could be chosen from a coffee result on short landscape; at the result the screen
     and the list are where a parking test's are, beside the receipt) */
  .hub[data-coffee-view] .parking[data-parking-controls="touch"]:is([data-parking-mode="driving"], [data-parking-mode="repositioning"], [data-parking-mode="paused"]) .parking__assist {
    bottom: var(--parking-bottom); left: auto; max-height: calc(36% - var(--parking-bottom) - .25rem); right: var(--parking-band-r); width: var(--coffee-screen-w);
  }
  .hub[data-coffee-view] .parking[data-parking-controls="touch"][data-parking-mode="driving"] .parking__assist-head { display: none; }
  /* (the list of tests, opened on the way back or from the result, opens upward from the screen's title and leftward from its
     right edge: the screen stands right of centre here, and the list, wider than the screen, ran off the right edge with GRAND
     PRIX and the activity column out of reach; 3E gate, lead) */
  .hub[data-coffee-view] .parking[data-parking-controls="touch"]:is([data-parking-mode="repositioning"], [data-parking-mode="paused"]) .parking__levels { bottom: 100%; left: auto; margin: 0 0 .4rem; right: 0; top: auto; }
  /* (phase-4 review repair: with a home-indicator inset the pad, and the strip above it, stand 13 px higher, and the strip reached
     7.4 px into the band at 844x390 with insets 59/21. The strip sits closer to the pad (the pad's label moves down to make
     room) and is 6 px shorter, its % at 1.3rem, 20.8 px) */
  .hub[data-coffee-view] .parking[data-parking-controls="touch"]:is([data-parking-mode="driving"], [data-parking-mode="result"], [data-parking-mode="paused"]) .parking__coffee {
    bottom: calc(var(--parking-pad-h) + .9rem); column-gap: .45rem; min-height: 0; padding: .1rem .5rem .1rem .35rem; width: var(--parking-pad-w);
    /* (over the steering pad: from the screen's own box, which now stands at 100vw - band-r - its width) */
    left: calc(var(--parking-left) - 100vw + var(--parking-band-r) + var(--coffee-screen-w)); right: auto;
  }
  .hub[data-coffee-view] .parking[data-parking-controls="touch"] .parking__coffee-cup { height: 1.8rem; width: 1.55rem; }
  .hub[data-coffee-view] .parking[data-parking-controls="touch"] .parking__coffee-pct b { font-size: 1.3rem; }
  .hub[data-coffee-view] .parking[data-parking-controls="touch"]:is([data-parking-mode="driving"], [data-parking-mode="paused"]) .parking__pad :is(.parking__pad-label, .parking__lift) { top: -.75rem; }
  .hub[data-coffee-view] .parking[data-parking-controls="touch"] .parking__coffee-pct small, .hub[data-coffee-view] .parking[data-parking-controls="touch"] .parking__coffee-gate small { font-size: .55rem; }
  .hub[data-coffee-view] .parking[data-parking-controls="touch"] .parking__coffee-gate b { font-size: 1.05rem; }
  /* compact: BELOW DELIVERY MINIMUM shrinks to the label over the figure (BELOW 60%, red), so the strip never grows into the band */
  .hub[data-coffee-view] .parking[data-parking-controls="touch"] .parking__coffee-below { display: none !important; }
  .hub[data-coffee-view] .parking[data-parking-controls="touch"] .parking__coffee.is-below .parking__coffee-pct small { font-size: 0; }
  .hub[data-coffee-view] .parking[data-parking-controls="touch"] .parking__coffee.is-below .parking__coffee-pct small::after { color: #ff6a55; content: 'BELOW 60%'; font-size: .55rem; }
  /* keys on a short frame: the screen bottom left, above the key line, under the band; the strip beside it */
  .hub[data-coffee-view] .parking[data-parking-controls="keys"]:is([data-parking-mode="driving"], [data-parking-mode="repositioning"], [data-parking-mode="result"], [data-parking-mode="paused"]) .parking__assist {
    max-height: calc(36% - var(--parking-bottom) - var(--parking-assist-lift) - .25rem);
  }
  .hub[data-coffee-view] .parking[data-parking-controls="keys"] .parking__coffee { bottom: -2px; left: calc(100% + .75rem); width: max-content; }
  .hub.hub.hub[data-coffee-view]:has(.parking:not([hidden]):is([data-parking-mode="driving"], [data-parking-mode="repositioning"])) :is(.hub__subtitle, .hub__subtitle.is-on) { opacity: 0; transition: none; }
}

/* ---------- phase-4 review repair, K4: the steering pad's width under its own flag ----------
   The coffee view's pad width (24.5vw, 11-13rem; the 3E block) follows data-coffee-pad, which js/world/coffee/index.js sets
   with data-coffee-view but never while a thumb holds the pad: parking reads the thumb against the pad's box at every move,
   so a pad that changed width mid-hold (the flag going on or off: a parking test driven back into the lot at ~2 m/s, the
   estate's first show with a thumb resting on the pad) moved the steer by about a third of lock. The width now changes only
   with no thumb on the pad; with no coffee view a parking test is laid out exactly as before. */
@media (orientation: landscape) and (max-height: 500px) {
  .hub[data-coffee-pad] .parking[data-parking-controls="touch"] { --parking-pad-w: clamp(11rem, calc(24.5 * var(--parking-vw)), 13rem); }
}
