/* The driving HUD. Paired with src/game/hud.js — the class names are created
 * there and nowhere else — and drawn from ui.css's tokens, so the cluster in
 * the corner and the pause card over it are visibly one product.
 *
 * SCALING
 *
 * Everything is a multiple of one custom property, --hud-u, so the whole HUD
 * grows and shrinks as a unit. It is a clamp() of a rem against a vmin: the rem
 * respects a reader who has turned their browser font up, the vmin keeps the
 * cluster from swallowing a phone in landscape or floating as a postage stamp on
 * a 4K panel, and the clamp bounds both ends. Nothing below uses a raw pixel
 * except hairlines.
 *
 * WHERE THINGS SIT. The road ahead is the middle of the screen from the
 * horizon down to the car, and nothing permanent is allowed in it. The four
 * corners and the top edge carry the instruments; the only things that ever
 * cross the middle are moments (a drift score, a countdown) and they leave.
 *
 * Panels are flat near-opaque slabs, not backdrop-filter. A backdrop blur has
 * to re-blur the frame behind it every frame, and behind this HUD is a 4 km
 * world being redrawn at 60 fps — the single most expensive thing that could be
 * asked of the compositor here, for an effect nobody looks at while driving.
 *
 * The layer is pointer-events: none in its entirety. Nothing in the HUD is
 * interactive, so a click always reaches the game underneath, and any control
 * added later must opt back in explicitly.
 */

.hud {
  --hud-u: clamp(0.56rem, 1.25vmin, 1.25rem);
  --hud-gap: calc(var(--hud-u) * 1.15);
  --hud-map: calc(var(--hud-u) * 14);
  --hud-dial: calc(var(--hud-u) * 15);
  --hud-dmg: calc(var(--hud-u) * 6.6);
  /* Capped against the viewport as well as the unit, because the drift dial is
   * the one fixed-width thing in the flexible middle column and it has nothing
   * either side of it to push against. Deriving its height from the same
   * property keeps the canvas's aspect exact whichever term wins. */
  --hud-drift: min(calc(var(--hud-u) * 15), 42vw);
  --hud-lean: -12deg;

  --hud-ink: var(--or-text, #eef2f8);
  --hud-dim: var(--or-text-2, #a9b6c9);
  --hud-faint: var(--or-text-3, #6d7c94);
  --hud-accent: var(--or-signal, #ffc21f);
  --hud-volt: var(--or-volt, #3c8cff);
  --hud-warn: #ff5b4a;
  --hud-good: var(--or-good, #3ddc84);
  --hud-panel: rgba(7, 11, 22, 0.80);
  --hud-edge: rgba(196, 212, 236, 0.20);
  --hud-num: var(--or-f-num, "DIN Alternate", "Bahnschrift", sans-serif);
  --hud-word: var(--or-f-display, "Avenir Next Condensed", "Bahnschrift", sans-serif);
  --hud-halo: 0 0 calc(var(--hud-u) * 0.5) rgba(0, 0, 0, 0.85);

  position: absolute;
  inset: 0;
  z-index: 10;
  overflow: hidden;
  pointer-events: none;
  contain: layout style;
  color: var(--hud-ink);
  font-family: var(--hud-word);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  user-select: none;
  -webkit-user-select: none;
  transition: opacity 220ms ease;
}

.hud.is-hidden { opacity: 0; }

.hud canvas { display: block; }

.hud__grid {
  position: absolute;
  inset: 0;
  display: grid;
  /* The outer columns are content-sized and the middle one takes the slack, so
   * the map and the cluster always get exactly the width they need. With
   * `1fr auto 1fr` the compass — which shares column 2 with the toast — sets the
   * middle column's width for every row, and on a narrow phone it squeezed the
   * cluster clean off the right edge. Grid columns span all rows; the top strip
   * must not be allowed to size the bottom one. And minmax(0, 1fr) rather than
   * a bare 1fr, which has an automatic minimum and so refuses to shrink below
   * the compass's own width — that puts the overflow straight back. */
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: var(--hud-gap);
  padding:
    calc(var(--hud-gap) + env(safe-area-inset-top, 0px))
    calc(var(--hud-gap) + env(safe-area-inset-right, 0px))
    calc(var(--hud-gap) + env(safe-area-inset-bottom, 0px))
    calc(var(--hud-gap) + env(safe-area-inset-left, 0px));
}

/* ---- compass strip and place line, top centre --------------------------- */

.hud__nav {
  grid-area: 1 / 2 / 2 / 3;
  justify-self: center;
  align-self: start;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--hud-u) * 0.35);
  width: min(46vw, calc(var(--hud-u) * 34));
  max-width: 100%;
  min-width: 0;
}

.hud__compass {
  width: 100%;
  height: calc(var(--hud-u) * 2.3);
  /* Fade the ends so headings slide out of view instead of being chopped off. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
}

/* The index mark: a yellow notch hanging from the top edge. A CSS shape, so
 * the compass canvas only ever gets a blit. */
.hud__nav::after {
  content: "";
  position: absolute;
  top: calc(var(--hud-u) * -0.2);
  left: 50%;
  width: calc(var(--hud-u) * 0.34);
  height: calc(var(--hud-u) * 0.95);
  background: var(--hud-accent);
  transform: translateX(-50%) skewX(var(--hud-lean));
}

/* Where you are, as a leaning plate: the district in capitals, the bearing in
 * DIN numerals after a hairline. */
.hud__place {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  gap: calc(var(--hud-u) * 0.7);
  max-width: 100%;
  padding: calc(var(--hud-u) * 0.3) calc(var(--hud-u) * 1.1);
}
.hud__place::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--hud-panel);
  box-shadow: inset 0 1px 0 var(--hud-edge);
  transform: skewX(var(--hud-lean));
}

.hud__district {
  min-width: 0;
  overflow: hidden;
  font-size: calc(var(--hud-u) * 1.1);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.hud__bearing {
  flex: none;
  padding-left: calc(var(--hud-u) * 0.7);
  border-left: 1px solid var(--hud-edge);
  color: var(--hud-dim);
  font-family: var(--hud-num);
  font-size: calc(var(--hud-u) * 1.0);
  font-weight: 700;
}

/* ---- clock and odometer, top right -------------------------------------- */

.hud__status {
  grid-area: 1 / 3 / 2 / 4;
  justify-self: end;
  align-self: start;
  display: flex;
  align-items: baseline;
  gap: calc(var(--hud-u) * 0.9);
  padding: calc(var(--hud-u) * 0.45) calc(var(--hud-u) * 1.0);
  background: var(--hud-panel);
  box-shadow: inset 0 1px 0 var(--hud-edge);
  clip-path: polygon(0 0, calc(100% - var(--hud-u) * 0.8) 0, 100% calc(var(--hud-u) * 0.8), 100% 100%, 0 100%);
}

.hud__clock {
  font-family: var(--hud-num);
  font-size: calc(var(--hud-u) * 1.7);
  font-weight: 700;
  line-height: 1;
}

.hud__colon {
  opacity: 0.55;
  animation: hud-blink 2s steps(1, end) infinite;
}

@keyframes hud-blink { 50% { opacity: 0.15; } }

.hud__odo {
  color: var(--hud-dim);
  font-family: var(--hud-num);
  font-size: calc(var(--hud-u) * 1.0);
  font-weight: 700;
  line-height: 1;
}

.hud__odoU {
  margin-left: 0.3em;
  font-family: var(--hud-word);
  font-size: 0.8em;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.8;
}

/* ---- damage panel, top left ---------------------------------------------
 *
 * Present for the day physics/damage.js turns DAMAGE back on; with it off
 * (the game's rule now) main.js never hands over a damage state and the whole
 * box stays display: none.
 */

.hud__damage {
  grid-area: 1 / 1 / 2 / 2;
  justify-self: start;
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: calc(var(--hud-u) * 0.4);
  width: var(--hud-dmg);
  padding: calc(var(--hud-u) * 0.5);
  background: var(--hud-panel);
  box-shadow: inset 0 1px 0 var(--hud-edge);
}

/* Not merely transparent: until main.js hands over a damage state there is
 * nothing to show, and an empty frame in the corner is worse than no frame. */
.hud__damage.is-off { display: none; }

.hud__damageCanvas {
  width: 100%;
  /* The silhouette is stylised wider than a real car in plan, because at this
   * size a true 0.45 aspect turns the door panels into hairlines. */
  height: calc(var(--hud-dmg) * 1.62);
}

.hud__temp { display: flex; align-items: center; gap: calc(var(--hud-u) * 0.35); }
.hud__temp.is-off { display: none; }
.hud__tempLabel { color: var(--hud-dim); font-size: calc(var(--hud-u) * 0.56); font-weight: 800; letter-spacing: 0.12em; }
.hud__tempTrack { position: relative; flex: 1; height: calc(var(--hud-u) * 0.5); background: rgba(255, 255, 255, 0.1); overflow: hidden; }
/* The bar spans temp 0.60 to 1.00, and the engine starts cooking itself at
 * 0.86 — which lands at 65% of the way along. */
.hud__tempTrack::after { content: ""; position: absolute; top: 0; bottom: 0; left: 65%; width: 1px; background: rgba(255, 255, 255, 0.5); }
.hud__tempFill { display: block; width: 100%; height: 100%; transform-origin: left center; transform: scaleX(0); background: var(--hud-volt); }
.hud__temp.is-warm .hud__tempFill { background: var(--hud-accent); }
.hud__temp.is-hot .hud__tempFill,
.hud__temp.is-crit .hud__tempFill { background: var(--hud-warn); }

.hud__lamps { display: grid; grid-template-columns: repeat(4, 1fr); gap: calc(var(--hud-u) * 0.22); }
.hud__lamp {
  padding: calc(var(--hud-u) * 0.14) 0;
  background: rgba(255, 255, 255, 0.05);
  color: rgba(160, 172, 186, 0.26);
  font-size: calc(var(--hud-u) * 0.55);
  font-weight: 800;
  letter-spacing: 0.04em;
  text-align: center;
}
.hud__lamp.is-warn { background: var(--hud-accent); color: #0b1222; }
.hud__lamp.is-crit { background: #d8322c; color: #fff; }

/* ---- drift, upper centre ------------------------------------------------
 *
 * The only part of the HUD that sits over the road, and it earns that by being
 * gone the instant the chain ends. Upper centre rather than dead centre: high
 * enough to clear the apex the player is actually looking at, central enough
 * that it needs no eye movement at all.
 */

.hud__drift {
  grid-area: 2 / 2 / 3 / 3;
  justify-self: center;
  align-self: start;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--hud-u) * 0.1);
  margin-top: calc(var(--hud-u) * 1.4);
  visibility: hidden;
  opacity: 0;
  transform: translateY(calc(var(--hud-u) * -0.5)) scale(0.94);
  /* visibility is not interpolable, so it is delayed by the length of the fade
   * instead — without that it snaps to hidden on frame one and the fade-out is
   * never seen. On the way in it must not be delayed at all. */
  transition: opacity 130ms ease, transform 130ms ease, visibility 0s linear 130ms;
}

.hud__drift.is-on {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition: opacity 130ms ease, transform 130ms ease, visibility 0s;
}

.hud__driftDial { position: relative; width: var(--hud-drift); height: calc(var(--hud-drift) * 0.54); }
.hud__driftGauge { width: 100%; height: 100%; }

/* In the hub of the arc, where the needle points away from it. */
.hud__driftAngle {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  text-align: center;
  font-family: var(--hud-num);
  font-size: calc(var(--hud-u) * 1.5);
  font-weight: 700;
  line-height: 1;
  text-shadow: var(--hud-halo);
}

.hud__driftRow { display: flex; align-items: baseline; gap: calc(var(--hud-u) * 0.5); }

/* A text-shadow rather than a panel behind the numbers: over a moving road the
 * shadow is enough to hold them, and a translucent slab in the middle of the
 * windscreen is exactly what a drift display must not be. */
.hud__driftScore {
  font-family: var(--hud-num);
  font-size: calc(var(--hud-u) * 2.7);
  font-weight: 700;
  line-height: 1;
  text-shadow: 0 0 calc(var(--hud-u) * 0.8) rgba(0, 0, 0, 0.9);
}

.hud__driftMult {
  color: var(--hud-accent);
  font-family: var(--hud-num);
  font-size: calc(var(--hud-u) * 1.3);
  font-weight: 700;
  text-shadow: var(--hud-halo);
}

.hud__driftTag {
  color: var(--hud-dim);
  font-size: calc(var(--hud-u) * 0.78);
  font-weight: 700;
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  text-shadow: var(--hud-halo);
}

/* Banked swells and turns green. A drift that ends early — spun, too slow,
 * bumped — does NOT shake or flash red: it goes quiet silver and fades, the
 * way the chain meter does. A kid who just spun needs the car back, not a
 * telling-off from the corner of the screen. */
.hud__drift.is-bank .hud__driftScore,
.hud__drift.is-bank .hud__driftTag { color: var(--hud-good); }
.hud__drift.is-bank { animation: hud-bank 520ms ease-out; }
.hud__drift.is-lost .hud__driftScore { color: var(--hud-dim); }
.hud__drift.is-lost .hud__driftTag { color: var(--hud-faint); }
.hud__drift.is-lost { animation: hud-settle 420ms ease-out; }

@keyframes hud-bank { 35% { transform: scale(1.16); } }
@keyframes hud-settle { from { transform: translateY(calc(var(--hud-u) * -0.4)); } }

/* ---- minimap, bottom left ----------------------------------------------- */

.hud__map {
  grid-area: 3 / 1 / 4 / 2;
  justify-self: start;
  align-self: end;
  position: relative;
  width: var(--hud-map);
  height: var(--hud-map);
}

/* A navy bezel with a hairline and, on top, a short yellow bar at twelve
 * o'clock: the way you are pointing, since the map turns and you do not. */
.hud__mapCanvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: rgba(5, 9, 18, 0.72);
  box-shadow:
    0 0 0 calc(var(--hud-u) * 0.3) rgba(7, 11, 22, 0.85),
    0 0 0 calc(var(--hud-u) * 0.3 + 1px) var(--hud-edge),
    inset 0 0 calc(var(--hud-u) * 1.6) rgba(0, 0, 0, 0.55);
}
.hud__map::after {
  content: "";
  position: absolute;
  top: calc(var(--hud-u) * -0.3);
  left: 50%;
  width: calc(var(--hud-u) * 1.6);
  height: calc(var(--hud-u) * 0.3);
  background: var(--hud-accent);
  transform: translateX(-50%);
}

.hud__surface {
  position: absolute;
  left: 50%;
  bottom: calc(var(--hud-u) * -0.6);
  isolation: isolate;
  padding: calc(var(--hud-u) * 0.18) calc(var(--hud-u) * 0.8);
  color: var(--hud-dim);
  font-size: calc(var(--hud-u) * 0.72);
  font-weight: 700;
  letter-spacing: 0.16em;
  white-space: nowrap;
  transform: translateX(-50%);
}
.hud__surface::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(7, 11, 22, 0.92);
  box-shadow: inset 0 0 0 1px var(--hud-edge);
  transform: skewX(var(--hud-lean));
}

.hud__surface.is-loose { color: var(--hud-accent); }
.hud__surface.is-loose::before { box-shadow: inset 0 0 0 1px rgba(255, 194, 31, 0.5); }

/* ---- toast, bottom centre ----------------------------------------------- */

.hud__toast {
  grid-area: 3 / 2 / 4 / 3;
  justify-self: center;
  align-self: end;
  min-width: 0;
  max-width: min(70vw, 44ch);
  margin-bottom: calc(var(--hud-u) * 1.4);
  padding: calc(var(--hud-u) * 0.55) calc(var(--hud-u) * 1.3) calc(var(--hud-u) * 0.55) calc(var(--hud-u) * 1.5);
  background: var(--hud-panel);
  box-shadow: inset calc(var(--hud-u) * 0.3) 0 0 var(--hud-accent), inset 0 1px 0 var(--hud-edge);
  font-size: calc(var(--hud-u) * 1.2);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-align: center;
  opacity: 0;
  transform: translateY(calc(var(--hud-u) * 0.6));
  transition: opacity 180ms ease, transform 180ms ease;
}

.hud__toast.is-on { opacity: 1; transform: none; }

/* ---- cluster, bottom right ---------------------------------------------- */

.hud__cluster {
  grid-area: 3 / 3 / 4 / 4;
  justify-self: end;
  align-self: end;
  display: flex;
  align-items: flex-end;
  gap: calc(var(--hud-u) * 0.7);
}

.hud__tells {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: calc(var(--hud-u) * 0.35);
  margin-bottom: calc(var(--hud-u) * 1.2);
}

/* The one real-world object on the HUD: a speed-limit roundel, drawn the way
 * the road signs are. */
.hud__limit {
  display: grid;
  place-items: center;
  width: calc(var(--hud-u) * 3.4);
  height: calc(var(--hud-u) * 3.4);
  margin-bottom: calc(var(--hud-u) * 0.25);
  border: calc(var(--hud-u) * 0.34) solid #d8322c;
  border-radius: 50%;
  background: #f2f4f6;
  color: #14171c;
  font-family: var(--hud-num);
  font-size: calc(var(--hud-u) * 1.25);
  font-weight: 700;
}

.hud__limit.is-off { display: none; }
.hud__limit.is-over { animation: hud-pulse 0.7s ease-in-out infinite; }

@keyframes hud-pulse {
  50% { box-shadow: 0 0 0 calc(var(--hud-u) * 0.5) rgba(216, 50, 44, 0.5); }
}

/* Telltales: leaning plates that keep their space when off, the way a real
 * cluster does, so nothing reflows when one lights up. */
.hud__tell {
  position: relative;
  isolation: isolate;
  padding: calc(var(--hud-u) * 0.2) calc(var(--hud-u) * 0.6);
  color: rgba(169, 182, 201, 0.32);
  font-size: calc(var(--hud-u) * 0.74);
  font-weight: 800;
  letter-spacing: 0.16em;
  transition: color 90ms linear;
}
.hud__tell::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(7, 11, 22, 0.55);
  transform: skewX(var(--hud-lean));
  transition: background-color 90ms linear;
}

.hud__tell--hand.is-on { color: #fff; }
.hud__tell--hand.is-on::before { background: #d8322c; }
.hud__tell--slip.is-on { color: #0b1222; }
.hud__tell--slip.is-on::before { background: var(--hud-accent); }
.hud__tell--air.is-on { color: #fff; }
.hud__tell--air.is-on::before { background: var(--hud-volt); }

.hud__dial { position: relative; width: var(--hud-dial); height: var(--hud-dial); }

/* The drop shadow lives on a static disc behind the canvas. A filter on the
 * canvas itself would be re-evaluated on every repaint, which is every frame. */
.hud__dial::before {
  content: "";
  position: absolute;
  inset: calc(var(--hud-u) * 0.12);
  border-radius: 50%;
  box-shadow: 0 calc(var(--hud-u) * 0.3) calc(var(--hud-u) * 1.4) rgba(0, 0, 0, 0.45);
}

.hud__dialCanvas { position: absolute; inset: 0; width: 100%; height: 100%; }

.hud__face {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.hud__speed {
  font-family: var(--hud-num);
  font-size: calc(var(--hud-dial) * 0.27);
  font-weight: 700;
  line-height: 0.9;
  letter-spacing: -0.01em;
}

.hud__speedU {
  margin-top: calc(var(--hud-dial) * 0.02);
  color: var(--hud-dim);
  font-size: calc(var(--hud-dial) * 0.066);
  font-weight: 700;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
}

/* The gear in a leaning plate, like a race number. */
.hud__gear {
  position: relative;
  isolation: isolate;
  min-width: calc(var(--hud-dial) * 0.17);
  margin-top: calc(var(--hud-dial) * 0.045);
  padding: calc(var(--hud-dial) * 0.012) calc(var(--hud-dial) * 0.05);
  font-family: var(--hud-num);
  font-size: calc(var(--hud-dial) * 0.11);
  font-weight: 700;
  text-align: center;
}
.hud__gear::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(238, 242, 248, 0.1);
  box-shadow: inset 0 0 0 1px var(--hud-edge);
  transform: skewX(var(--hud-lean));
}

.hud__cluster.is-shift .hud__gear { color: #fff; }
.hud__cluster.is-shift .hud__gear::before { background: var(--hud-warn); box-shadow: none; }

/* ---- small screens ------------------------------------------------------ */

/* Landscape on a phone is the real driving posture and the tightest case: the
 * unit shrinks against vmin so the cluster and map still clear each other. */
@media (max-width: 760px), (max-height: 480px) {
  .hud {
    --hud-u: clamp(0.5rem, 2.1vmin, 0.9rem);
    --hud-map: calc(var(--hud-u) * 12);
    --hud-dial: calc(var(--hud-u) * 13);
    --hud-dmg: calc(var(--hud-u) * 5.2);
    --hud-drift: min(calc(var(--hud-u) * 12), 38vw);
  }

  .hud__nav { width: min(54vw, calc(var(--hud-u) * 28)); }
  .hud__driftScore { font-size: calc(var(--hud-u) * 2.2); }
  .hud__lamp { letter-spacing: 0; }
}

/* Portrait leaves no width for a heading tape; the place line carries on alone.
 * Scoped through .hud so it outranks the `.hud canvas { display: block }` reset,
 * which is a class plus a type and would otherwise win on specificity whatever
 * the media query says. */
@media (orientation: portrait) and (max-width: 600px) {
  .hud .hud__compass { display: none; }
  .hud .hud__nav::after { display: none; }
}

/* ---- touch: the thumbs own the bottom corners ----------------------------
 *
 * On a phone or a tablet the steering wheel sits bottom left and the pedals
 * bottom right (touch.css) — exactly where the minimap and the speedo are on
 * a keyboard, so on touch they were drawn under the player's thumbs. The same
 * test touch.js uses to decide to show the rig (a coarse pointer and no fine
 * one) moves them: the minimap to the top-left corner, which nothing else
 * uses, and the cluster under it, above the wheel. Not the bottom centre,
 * between wheel and pedals, where it went first: that is where the chase
 * camera puts the car, and at 740x360 the dial (x 358-462, y 247-351)
 * covered the lower third of it and the road just behind. */
@media (hover: none) and (pointer: coarse) {
  .hud { --hud-map: calc(var(--hud-u) * 10.5); }
  .hud__map { grid-area: 1 / 1 / 2 / 2; align-self: start; }
  .hud__cluster { grid-area: 2 / 1 / 3 / 2; justify-self: start; align-self: start; flex-direction: row-reverse; align-items: flex-start; }
  .hud__tells { align-items: flex-start; }
  .hud__toast { grid-area: 2 / 2 / 3 / 3; align-self: end; }
}
/* A phone on its side has 92 px between the minimap (ending at 93 on a
 * 360 px screen) and the top of the wheel's touch zone (194): the dial goes
 * from 13 units to 11.5, 98 px to 87, to sit clear of the thumb. */
@media (hover: none) and (pointer: coarse) and (orientation: landscape) and (max-height: 480px) {
  .hud { --hud-dial: calc(var(--hud-u) * 11.5); }
}
/* Upright there is height to spare and no width: the telltales and the limit
 * sign go in a row above the dial instead of beside it. */
@media (hover: none) and (pointer: coarse) and (orientation: portrait) {
  .hud__cluster { flex-direction: column-reverse; }
  .hud__tells { flex-direction: row; align-items: center; margin-bottom: 0; }
  .hud__limit { margin-bottom: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .hud,
  .hud__toast,
  .hud__tell,
  .hud__tell::before { transition: none; }

  /* The drift box still has to appear and disappear, so its opacity keeps a
   * short fade — only the movement goes. */
  .hud__drift {
    transform: none;
    transition: opacity 130ms ease, visibility 0s linear 130ms;
  }

  .hud__colon,
  .hud__limit.is-over,
  .hud__drift.is-bank,
  .hud__drift.is-lost { animation: none; }
}
