/* BREWL espresso control · stage 7 — the graph. The curves are on a canvas that fills the glass; the legend, the
   time axis and the playhead (a line, two dots and the time) are HTML on top, moved with transforms.

   Sizes are in the design's own pixels. The stage scales the whole panel to the screen (app.js → fit()), so the panel
   keeps the concept's proportions on every screen.

   1 tokens: primitive → semantic → component     2 the page and the stage     3 the panel and its name plate
   4 the dials: shared parts, temperature, knobs   5 temperature states: idle, turning, ready, too hot, steam
   6 the recipe switch     7 the graph and the result     8 the cup's glass     9 PULL SHOT     10 the layout */

/* ---- 1. TOKENS ---- */
/* primitive: the raw values, named for what they are */
:root {
  --cream-50: #FBF7EF; --cream-100: #F6F0E4; --cream-200: #EFE7D8; --cream-300: #E3D8C4; --cream-400: #CFC2AA; --cream-page: #F1E8D8;
  --ink-900: #24211D; --ink-700: #3F3A33; --ink-500: #6C655A; --ink-300: #A39B8D;
  --graphite-950: #101114; --graphite-900: #17191E; --graphite-800: #1F2228; --graphite-700: #2B2F36; --graphite-400: #8B9099; --graphite-200: #C6C9CF;
  --copper-200: #F6C7A2; --copper-300: #EBA275; --copper-400: #DD8250; --copper-500: #C9693A; --copper-600: #A8532B; --copper-700: #7C3A1D; --copper-900: #3A1C0E;
  --chrome-50: #FAFAFA; --chrome-100: #EDEDED; --chrome-200: #D6D6D6; --chrome-300: #BDBDBD; --chrome-500: #8E8E8E; --chrome-700: #5E5E5E;
  --heat-blue: #3F86FF; --heat-sky: #5DB8FF; --heat-ice: #BFE0FF; --heat-amber: #FF9A4A; --heat-red: #FF3B2F;
  --crema: #C9894A;
  --white: #FFFFFF;

  --font-display: 'Anton', 'Oswald', 'Impact', sans-serif;
  --font-cond: 'Oswald', 'Anton', sans-serif;
  --font-ui: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
}

/* semantic: what each value is for */
:root {
  --page: var(--cream-page);
  --panel: var(--cream-100);
  --panel-edge: rgb(60 45 25 / .1);
  --on-panel: var(--ink-900);
  --on-panel-muted: var(--ink-500);
  --tick: rgb(36 33 29 / .55);
  --tick-faint: rgb(36 33 29 / .18);
  --plate: var(--graphite-900);
  --on-plate: var(--graphite-200);
  --accent: var(--copper-500);
  --accent-glow: rgb(235 135 75 / .55);
  --glass: var(--graphite-950);
  --on-glass: #E9E4DC;
  --on-glass-muted: rgb(233 228 220 / .5);
  --pressure-line: #6EC3FF;
  --flow-line: #FFB070;
  --focus: var(--copper-500);
}

/* component: per-part values */
:root {
  --panel-r: 22px;
  --panel-drop: 0 2px 0 rgb(255 255 255 / .9) inset, 0 -2px 0 rgb(60 40 20 / .06) inset, 0 40px 70px -30px rgb(70 45 20 / .35), 0 12px 24px -10px rgb(70 45 20 / .18);
  --chrome-face: radial-gradient(circle at 50% 30%, rgb(255 255 255 / .65), transparent 58%),
                 conic-gradient(from 15deg, #C9C9C9, #F6F6F6 10%, #A7A7A7 22%, #E9E9E9 35%, #B4B4B4 48%, #F4F4F4 60%, #A3A3A3 73%, #E6E6E6 86%, #C9C9C9);
  --knurl: repeating-conic-gradient(#F4F4F4 0deg 1.1deg, #9A9A9A 1.6deg 2.4deg, #F4F4F4 2.9deg 3.6deg);
  --copper-fill: linear-gradient(180deg, #F0A676 0%, #D9763F 48%, #B85A2A 100%);
  --dark-fill: linear-gradient(180deg, #2F333A 0%, #1B1D22 55%, #121317 100%);
  --press: cubic-bezier(.2, .8, .2, 1);
}

/* ---- 2. THE PAGE AND THE STAGE ---- */
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: radial-gradient(120% 90% at 30% 0%, var(--cream-50), var(--page) 60%, #E9DEC9);
  color: var(--on-panel); font-family: var(--font-ui); -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent; overflow: hidden;
}
button { font: inherit; color: inherit; border: 0; background: none; padding: 0; cursor: pointer; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; margin: -1px; }

/* the stage fills the screen; .frame is the panel's scaled footprint; .brewl is the panel at design size, scaled */
.stage { position: relative; height: 100dvh; width: 100%; display: grid; place-items: center; overflow: hidden; }
.frame { position: relative; width: calc(var(--w) * var(--s) * 1px); height: calc(var(--h) * var(--s) * 1px); }
.brewl {
  position: absolute; left: 0; top: 0; width: calc(var(--w) * 1px); height: calc(var(--h) * 1px);
  transform: scale(var(--s)); transform-origin: 0 0;
  background: linear-gradient(180deg, var(--cream-50), var(--panel) 30%, var(--cream-200));
  border-radius: var(--panel-r); box-shadow: var(--panel-drop);
  user-select: none; -webkit-user-select: none;
}
.stage:not(.ready) .brewl { visibility: hidden; }

/* ---- 3. THE NAME PLATE ---- */
.plate { position: absolute; left: 0; top: 0; width: 100%; height: var(--plate-h); }
.plate-shape { position: absolute; left: 0; top: 0; width: 100%; height: calc(var(--plate-h) + var(--tab-h)); overflow: visible; }
.plate-shape { filter: drop-shadow(0 6px 10px rgb(30 20 10 / .25)); }
.badge {
  position: absolute; left: 50%; top: var(--badge-y); width: var(--badge-w); height: var(--badge-h); transform: translateX(-50%);
  border-radius: 12px; padding: 3px;
  background: linear-gradient(180deg, var(--copper-200), var(--copper-500) 45%, var(--copper-700) 100%);
  box-shadow: 0 6px 14px rgb(0 0 0 / .45), 0 0 0 1px rgb(0 0 0 / .5);
}
.badge::before { content: ''; position: absolute; inset: 3px; border-radius: 9px; background: linear-gradient(180deg, #2A2D33, #16181C);
  box-shadow: inset 0 2px 6px rgb(0 0 0 / .7), inset 0 -1px 0 rgb(255 255 255 / .08); }
.badge-word {
  position: relative; margin: 0; height: 100%; display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 400; font-size: var(--badge-font); letter-spacing: .07em; line-height: 1; padding-left: .07em;
  background: linear-gradient(180deg, #FFFFFF 0%, #E3E3E3 38%, #8F8F8F 52%, #D9D9D9 70%, #A9A9A9 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 1px 0 rgb(0 0 0 / .8)) drop-shadow(0 -1px 0 rgb(255 255 255 / .12));
}
.plate-sub {
  position: absolute; left: 50%; top: calc(var(--plate-h) + var(--tab-h) / 2); transform: translate(-50%, -50%); margin: 0;
  font: 500 var(--sub-font)/1 var(--font-ui); letter-spacing: .06em; text-transform: uppercase; color: var(--on-plate); white-space: nowrap;
}

/* ---- 4. THE DIALS ---- */
/* every dial is a square box of side --d; its rings are centred circles sized as fractions of --d */
.dial { position: absolute; width: calc(var(--d) * 1px); height: calc(var(--d) * 1px); border-radius: 50%; touch-action: none; cursor: grab; outline: none; }
.dial.is-turning { cursor: grabbing; }
.dial > * { position: absolute; left: 50%; top: 50%; border-radius: 50%; transform: translate(-50%, -50%); }
.dial .ticks { width: 100%; height: 100%; border-radius: 0; overflow: visible; }
.dial .ticks line { stroke: var(--tick-faint); stroke-linecap: round; }
.dial .ticks line.on { stroke: var(--tick); }
.dial .ticks line.major { stroke-width: 2.2; }
.dial:focus-visible::after { content: ''; position: absolute; inset: -6px; border-radius: 50%; box-shadow: 0 0 0 3px var(--focus); }

.knurl { width: calc(var(--d) * var(--kn) * 1px); height: calc(var(--d) * var(--kn) * 1px); overflow: hidden;
  box-shadow: 0 0 0 1.5px rgb(40 40 40 / .55), 0 6px 14px rgb(0 0 0 / .35), 0 2px 3px rgb(0 0 0 / .3); }
.knurl-spin { position: absolute; inset: 0; border-radius: 50%; background: var(--knurl); will-change: transform; }
.knurl-light { position: absolute; inset: 0; border-radius: 50%;
  background: linear-gradient(155deg, rgb(255 255 255 / .55), rgb(255 255 255 / 0) 42%, rgb(0 0 0 / .1) 60%, rgb(0 0 0 / .42)); }
.face {
  width: calc(var(--d) * var(--fc) * 1px); height: calc(var(--d) * var(--fc) * 1px);
  background: var(--chrome-face);
  box-shadow: inset 0 2px 2px rgb(255 255 255 / .9), inset 0 -3px 6px rgb(0 0 0 / .22), 0 0 0 1px rgb(0 0 0 / .25), 0 3px 6px rgb(0 0 0 / .25);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.face::before { content: ''; position: absolute; inset: 0; border-radius: 50%; opacity: .5;
  background: repeating-radial-gradient(circle, rgb(0 0 0 / .035) 0 1px, rgb(255 255 255 / .04) 1px 2px); }
.face > * { position: relative; }
.face-value { display: flex; align-items: flex-start; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }

/* temperature: the dark bezel carries the heat arc; the marker rides the arc */
.dial--temp .bezel {
  width: calc(var(--d) * var(--bz) * 1px); height: calc(var(--d) * var(--bz) * 1px);
  background: radial-gradient(circle, #24272D 55%, #15171B 70%, #1B1D22 100%);
  box-shadow: 0 0 0 2px #9C9C9C, 0 0 0 3.5px #E8E8E8, 0 0 0 5px #6D6D6D, 0 14px 26px -6px rgb(40 25 10 / .55), inset 0 4px 10px rgb(0 0 0 / .8);
}
.dial--temp .arc { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 50%; }
.marker {
  position: absolute; left: 50%; top: 50%; width: calc(var(--d) * .03 * 1px); height: calc(var(--d) * .068 * 1px); margin: calc(var(--d) * -.034 * 1px) 0 0 calc(var(--d) * -.015 * 1px);
  border-radius: 99px; background: linear-gradient(90deg, #E9E1D2, #FFFBF3 45%, #CFC5B2); box-shadow: 0 1px 3px rgb(0 0 0 / .6), 0 0 8px rgb(255 240 220 / .4);
  will-change: transform;
}
.marker.ghost { opacity: 0; transition: opacity .25s; }
.dial.is-turning .marker.g1 { opacity: .35; }
.dial.is-turning .marker.g2 { opacity: .16; }
.dial--temp .face-label { font-weight: 600; letter-spacing: .02em; text-transform: uppercase; color: #3A3836; text-shadow: 0 1px 0 rgb(255 255 255 / .6); }
.dial--temp .face-label { font-size: calc(var(--d) * .049 * 1px); }
.dial--temp .face-value { margin-top: calc(var(--d) * .01 * 1px); color: #FFFFFF; text-shadow: 0 1px 1px rgb(0 0 0 / .35), 0 2px 8px rgb(0 0 0 / .3); }
.dial--temp .num { font-size: calc(var(--d) * .225 * 1px); font-weight: 700; }
.dial--temp sup { font-size: calc(var(--d) * .075 * 1px); font-weight: 600; margin: calc(var(--d) * .02 * 1px) 0 0 calc(var(--d) * .006 * 1px); }
.face-chip {
  margin-top: calc(var(--d) * .016 * 1px); padding: calc(var(--d) * .009 * 1px) calc(var(--d) * .028 * 1px); border-radius: 99px;
  font-size: calc(var(--d) * .034 * 1px); font-weight: 650; letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
  color: #EDEAE4; background: rgb(24 24 27 / .72); box-shadow: inset 0 1px 0 rgb(255 255 255 / .12);
  transition: background-color .25s, color .25s;
}

/* the halo: a soft light behind the bezel, warm when ready, red and pulsing when too hot */
.halo { width: calc(var(--d) * var(--bz) * 1.24px); height: calc(var(--d) * var(--bz) * 1.24px); opacity: 0; transition: opacity .4s;
  background: radial-gradient(closest-side, rgb(255 140 60 / .5) 70%, rgb(255 140 60 / .16) 85%, transparent); }

/* small knobs: chrome face with the number, a notch that turns, ticks that light up to the value */
.knob-wrap { position: absolute; }
.knob-wrap .dial { position: relative; display: block; margin: 0 auto; }
.knob-label, .knob-unit, .knob-end { position: absolute; left: 50%; transform: translateX(-50%); white-space: nowrap; }
.knob-label { top: 0; font-size: var(--knob-label); font-weight: 600; letter-spacing: .02em; text-transform: uppercase; color: var(--on-panel); }
.knob-unit { bottom: 0; font-size: var(--knob-unit); font-weight: 500; color: var(--on-panel); }
.knob-end { bottom: calc(var(--knob-unit) * .2); font-size: calc(var(--knob-unit) * .72); font-weight: 600; color: var(--on-panel-muted); letter-spacing: .04em; text-transform: uppercase; }
.knob-end.lo { transform: translateX(calc(-50% - var(--d) * .4px)); }
.knob-end.hi { transform: translateX(calc(-50% + var(--d) * .4px)); }
.dial--knob .num { font-size: calc(var(--d) * .2 * 1px); color: #2A2826; text-shadow: 0 1px 0 rgb(255 255 255 / .7); }
.dial--knob .notch { position: absolute; left: 50%; top: 50%; width: calc(var(--d) * .016 * 1px); height: calc(var(--d) * .07 * 1px); border-radius: 2px;
  margin: calc(var(--d) * -.035 * 1px) 0 0 calc(var(--d) * -.008 * 1px); background: #2A2826; box-shadow: 0 1px 0 rgb(255 255 255 / .6); will-change: transform; }

/* ---- 5. TEMPERATURE STATES (component.jpg): idle (cool), turning, ready, too hot ---- */
.brewl[data-temp-state="ready"] .dial--temp .halo { opacity: .55; }
.brewl[data-temp-state="hot"] .dial--temp .halo {
  background: radial-gradient(closest-side, rgb(255 45 35 / .85) 70%, rgb(255 45 35 / .3) 84%, transparent);
  animation: hot-pulse 1.1s ease-in-out infinite alternate;
}
.brewl[data-temp-state="hot"] .face-chip { background: rgb(200 30 25 / .9); color: #FFFFFF; }
.brewl[data-temp-state="idle"] .face-chip { background: rgb(30 60 110 / .75); }
@keyframes hot-pulse { from { opacity: .45; transform: translate(-50%, -50%) scale(.97); } to { opacity: 1; transform: translate(-50%, -50%) scale(1.05); } }

/* steam: four soft wisps rising off the dial when the water is ready (and the cup, while it fills) */
.steam { width: calc(var(--d) * .5px); height: calc(var(--d) * .6px); top: calc(var(--d) * -.05px); border-radius: 0; pointer-events: none; opacity: 0; transition: opacity .8s; }
.brewl[data-temp-state="ready"] .dial--temp .steam { opacity: 1; }
.steam i { position: absolute; bottom: 0; width: 24%; aspect-ratio: 1 / 2.6; border-radius: 50%; opacity: 0;
  background: radial-gradient(closest-side, rgb(255 255 255 / .42), rgb(255 255 255 / .12) 60%, transparent); animation: wisp 4.8s linear infinite; }
.steam i:nth-child(1) { left: 22%; animation-delay: -.4s; }
.steam i:nth-child(2) { left: 40%; animation-delay: -1.6s; animation-duration: 5.4s; }
.steam i:nth-child(3) { left: 56%; animation-delay: -2.8s; }
.steam i:nth-child(4) { left: 34%; animation-delay: -3.9s; animation-duration: 5.8s; }
@keyframes wisp {
  0% { transform: translate(0, 10%) scale(.55, .5); opacity: 0; }
  18% { opacity: .9; }
  55% { transform: translate(14%, -70%) scale(.9, 1) rotate(8deg); opacity: .55; }
  100% { transform: translate(-10%, -150%) scale(1.25, 1.3) rotate(-6deg); opacity: 0; }
}

/* ---- 6. THE RECIPE SWITCH ---- */
.presets {
  position: absolute; display: flex; align-items: stretch; padding: 0 5px; border-radius: 999px;
  background: linear-gradient(180deg, #E9E1D3, #F3EDE2); box-shadow: inset 0 2px 4px rgb(60 40 20 / .16), inset 0 -1px 0 rgb(255 255 255 / .9), 0 0 0 1.5px rgb(60 45 25 / .14), 0 1px 0 rgb(255 255 255 / .9);
}
.preset {
  position: relative; z-index: 1; flex: 1 1 0; border-radius: 999px;
  font-size: var(--preset-font); font-weight: 600; letter-spacing: .03em; text-transform: uppercase; color: var(--ink-700);
  transition: color .3s;
}
.preset[aria-checked="true"] { color: #FFF8F0; text-shadow: 0 1px 1px rgb(90 40 10 / .5); }
.preset:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.presets-dot { flex: 0 0 6px; height: 6px; align-self: center; border-radius: 50%; background: var(--ink-500); opacity: .7; }
.presets-thumb {
  position: absolute; left: 0; top: 5px; bottom: 5px; border-radius: 999px; will-change: transform;
  background: var(--copper-fill);
  box-shadow: 0 0 18px var(--accent-glow), 0 0 0 1px rgb(120 50 15 / .6), inset 0 1px 0 rgb(255 220 190 / .7), inset 0 -2px 4px rgb(90 35 10 / .35);
  transition: transform .45s var(--press), width .45s var(--press);
}

/* ---- 7. THE GRAPH ---- */
.graph {
  position: absolute; margin: 0; border-radius: 16px; overflow: hidden;
  background: radial-gradient(120% 90% at 20% 100%, #1A1B20, #0D0E11 70%);
  box-shadow: 0 0 0 1.5px #050506, inset 0 0 0 1px rgb(255 255 255 / .07), 0 20px 30px -16px rgb(40 25 10 / .6);
}
.graph::after { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(112deg, transparent 52%, rgb(255 255 255 / .065) 52.2%, rgb(255 255 255 / .02) 78%, transparent 78.2%),
              linear-gradient(180deg, rgb(255 255 255 / .05), transparent 18%); }
.graph-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.graph-legend { position: absolute; right: 22px; top: 18px; display: grid; gap: 4px; font-size: var(--legend-font); color: var(--on-glass-muted); }
.lg { display: flex; align-items: center; gap: 7px; }
.lg::before { content: ''; width: 16px; height: 2px; border-radius: 2px; }
.lg-p::before { background: var(--pressure-line); box-shadow: 0 0 6px var(--pressure-line); }
.lg-f::before { background: var(--flow-line); box-shadow: 0 0 6px var(--flow-line); }
.graph-axis span { position: absolute; bottom: var(--axis-y); font-size: var(--axis-font); color: var(--on-glass-muted); transform: translateX(-50%); white-space: nowrap; font-variant-numeric: tabular-nums; transition: opacity .2s; }
.graph-axis span.first { transform: none; }
.graph-axis span.hide { opacity: 0; }
.playhead { position: absolute; left: 0; top: 0; width: 0; height: 100%; will-change: transform; opacity: 0; transition: opacity .3s; }
.playhead.on { opacity: 1; }
.ph-line { position: absolute; left: -1px; width: 2px; top: var(--plot-top); bottom: var(--plot-bottom); background: linear-gradient(180deg, rgb(255 210 160 / .2), #FFD2A0 20%, #FFC089 80%, rgb(255 190 140 / .3)); box-shadow: 0 0 10px rgb(255 170 100 / .7); }
.ph-dot { position: absolute; left: -7px; top: -7px; width: 14px; height: 14px; border-radius: 50%; will-change: transform; }
.ph-p { background: #E6F4FF; box-shadow: 0 0 0 2px rgb(110 195 255 / .6), 0 0 12px var(--pressure-line); }
.ph-f { background: #FFF1E2; box-shadow: 0 0 0 2px rgb(255 176 112 / .6), 0 0 12px var(--flow-line); }
.ph-time { position: absolute; bottom: var(--axis-y); left: 0; transform: translateX(-50%); font-size: var(--axis-font); font-weight: 700; color: #FFC089; text-shadow: 0 0 10px rgb(255 160 80 / .6); font-variant-numeric: tabular-nums; }

/* the verdict, a glass card over the graph's empty corner */
.result {
  position: absolute; left: 18px; top: 46px; max-width: 66%; padding: 12px 16px 13px; border-radius: 12px;
  background: rgb(26 27 32 / .82); box-shadow: inset 0 0 0 1px rgb(255 255 255 / .1), 0 10px 24px rgb(0 0 0 / .4);
  opacity: 0; transform: translateY(-6px); transition: opacity .35s, transform .45s var(--press); pointer-events: none;
}
.result.on { opacity: 1; transform: none; }
.result p { margin: 0; }
.result-title { font-size: var(--result-font); font-weight: 700; color: #FFF4E8; letter-spacing: -.005em; white-space: nowrap; }
.result-advice { margin-top: 3px !important; font-size: calc(var(--result-font) * .8); color: var(--on-glass-muted); }
.result::before { content: ''; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px; border-radius: 0 3px 3px 0; background: var(--verdict, #7DDB8F); }
.result[data-kind="balanced"] { --verdict: #7DDB8F; }
.result[data-kind="under"] { --verdict: var(--pressure-line); }
.result[data-kind="over"] { --verdict: var(--heat-red); }
.result[data-kind="stopped"] { --verdict: var(--graphite-400); }

/* ---- 8. THE CUP'S GLASS (stage 8 draws the cup in it) ---- */
.cup {
  position: absolute; border-radius: 16px; overflow: hidden;
  background: radial-gradient(70% 90% at 45% 62%, #3A2A20, #1A1410 55%, #0C0A09);
  box-shadow: 0 0 0 1.5px #050506, inset 0 0 0 1px rgb(255 255 255 / .07), 0 20px 30px -16px rgb(40 25 10 / .6);
}
.cup::after { content: ''; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(112deg, transparent 60%, rgb(255 255 255 / .05) 60.2%, transparent 85%); }

/* ---- 9. PULL SHOT ---- */
.pull {
  position: absolute; display: flex; border-radius: 20px; padding: 4px; overflow: hidden;
  background: linear-gradient(180deg, #E9A57A, #A8532B); box-shadow: 0 0 0 1px rgb(110 45 15 / .7), 0 0 22px var(--accent-glow), 0 10px 18px -6px rgb(120 50 15 / .55);
  transition: transform .12s var(--press), box-shadow .2s;
}
.pull > span { position: relative; display: grid; place-items: center; height: 100%; font-family: var(--font-cond); font-weight: 600; font-size: var(--pull-font); letter-spacing: .02em; text-transform: uppercase; line-height: 1; }
.pull-a { flex: 0 0 47%; border-radius: 16px 0 0 16px; background: var(--copper-fill); color: #2A1408; text-shadow: 0 1px 0 rgb(255 210 180 / .5);
  box-shadow: inset 0 2px 0 rgb(255 225 200 / .75), inset 0 -3px 6px rgb(90 35 10 / .35); }
.pull-b { flex: 1 1 auto; border-radius: 0 16px 16px 0; background: var(--dark-fill); color: #F4E8DA; box-shadow: inset 0 1px 0 rgb(255 255 255 / .12), inset 0 -3px 6px rgb(0 0 0 / .5); }
.pull:hover { box-shadow: 0 0 0 1px rgb(110 45 15 / .7), 0 0 30px rgb(240 140 75 / .7), 0 10px 18px -6px rgb(120 50 15 / .55); }
.pull:active, .pull.is-pressed { transform: translateY(2px) scale(.992); }
.pull:active .pull-a, .pull.is-pressed .pull-a { box-shadow: inset 0 3px 8px rgb(90 35 10 / .55); }
.pull:focus-visible { outline: 3px solid var(--ink-900); outline-offset: 4px; }

/* ---- 10. THE LAYOUT (design pixels) ---- */
/* desk: the concept's panel, 1160 × 886 (stage 9 adds a phone on its side, and a phone upright) */
.stage[data-layout="desk"] {
  --plate-h: 115px; --tab-h: 44px; --badge-y: 16px; --badge-w: 300px; --badge-h: 82px; --badge-font: 64px; --sub-font: 19px;
  --knob-label: 19px; --knob-unit: 18px; --preset-font: 19px; --legend-font: 13px; --axis-font: 17px; --axis-y: 12px; --result-font: 19px;
  --pull-font: 40px; --plot-top: 52px; --plot-bottom: 44px;
}
.stage[data-layout="desk"] .dial--temp { --d: 346; --bz: .913; --kn: .69; --fc: .63; left: 59px; top: 150px; }
.stage[data-layout="desk"] .knob-wrap { --d: 176; width: 230px; height: 214px; top: 178px; }
.stage[data-layout="desk"] .knob-wrap .dial { --kn: .74; --fc: .65; top: 32px; }
.stage[data-layout="desk"] .knob-wrap--pressure { left: 505px; }
.stage[data-layout="desk"] .knob-wrap--grind { left: 846px; }
.stage[data-layout="desk"] .presets { left: 485px; top: 421px; width: 598px; height: 58px; }
.stage[data-layout="desk"] .graph { left: 24px; top: 513px; width: 762px; height: 339px; }
.stage[data-layout="desk"] .cup { left: 813px; top: 513px; width: 321px; height: 204px; }
.stage[data-layout="desk"] .pull { left: 818px; top: 751px; width: 313px; height: 94px; }
