:root {
  --bg: #0e141b;
  --panel: rgba(14, 20, 27, 0.78);
  --panel-border: rgba(255, 255, 255, 0.12);
  --text: #eef3f8;
  --muted: #9fb0c0;
  --accent: #3cf07c;
  --warn: #ffb828;
  --danger: #ff4d4d;
  --battery: linear-gradient(90deg, #22d36b, #7dff9a);
  --hp: linear-gradient(90deg, #ff5b5b, #ff9a7a);
  font-family: "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; background: var(--bg); color: var(--text); }
#scene { position: fixed; inset: 0; width: 100vw; height: 100vh; display: block; touch-action: none; outline: none; }
#labels { position: fixed; inset: 0; pointer-events: none; overflow: hidden; }
.hidden { display: none !important; }
/* The owner's controls (the car picker, Test drive): ?cars=1 puts the class on <html> (js/boot.js). */
html:not(.owner) .owner-only { display: none !important; }

/* ---------- Menu ---------- */
/* The card hangs from a fixed height (about centred for its usual size) and grows downward, so what comes up under its
   buttons (the consent question, item 2) never moves Play; when it does not fit (a short landscape phone, an open
   keyboard), the menu scrolls. */
#menu { position: fixed; inset: 0; display: flex; align-items: flex-start; overflow-y: auto; padding: max(12px, min(calc(50vh - 230px), calc(100vh - 600px))) 16px 12px; background: radial-gradient(ellipse at center, rgba(14,20,27,0.35), rgba(14,20,27,0.8)); z-index: 20; }
.menu-card { margin: 0 auto; width: min(460px, 100%); background: var(--panel); border: 1px solid var(--panel-border); border-radius: 16px; padding: 28px; text-align: center; backdrop-filter: blur(6px); }
.menu-card h1 { margin: 0 0 6px; font-size: clamp(26px, 8.5vw, 44px); letter-spacing: 3px; font-weight: 900; white-space: nowrap; }
.menu-card h1 span { color: var(--accent); }
.tagline { color: var(--muted); margin: 0 0 22px; }
#name { width: 100%; padding: 12px 14px; font-size: 18px; border-radius: 10px; border: 1px solid var(--panel-border); background: rgba(255,255,255,0.06); color: var(--text); margin-bottom: 12px; }
.car-pick { display: flex; align-items: center; gap: 10px; margin: -4px 0 12px; color: var(--muted); font-size: 14px; text-align: left; }
.car-pick select { flex: 1; font: inherit; font-size: 15px; padding: 9px 10px; border-radius: 10px; border: 1px solid var(--panel-border); background: rgba(255,255,255,0.06); color: var(--text); }
.car-pick select option { background: #1b242e; }
button { cursor: pointer; font: inherit; border-radius: 10px; border: 1px solid var(--panel-border); background: rgba(255,255,255,0.08); color: var(--text); padding: 10px 14px; }
button:hover { background: rgba(255,255,255,0.14); }
button.primary { width: 100%; font-size: 20px; font-weight: 800; background: var(--accent); color: #07210f; border: none; padding: 14px; margin-bottom: 10px; }
button.primary:hover { filter: brightness(1.08); }
button.ghost { width: 100%; background: transparent; }
/* A press before the game has loaded: the button says so until the game takes over. */
button.busy { cursor: progress; }
button.busy .btn-label::after { content: ""; display: inline-block; width: 0.75em; height: 0.75em; margin-left: 0.5em; vertical-align: -0.06em; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin 0.7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.menu-row { display: flex; gap: 8px; }
.menu-row button { flex: 1; }
.error { color: var(--danger); margin-top: 8px; }
.error:empty { margin: 0; }
.links { margin: 14px 0 0; font-size: 13px; }
.links:empty { display: none; }
.links a { color: var(--muted); }

/* How to play: a sheet over the menu. It scrolls inside itself, so the page never has to, and Play stays where it is. */
.how { position: fixed; inset: 0; z-index: 2; display: flex; align-items: center; justify-content: center; padding: 12px; background: rgba(8, 12, 17, 0.72); }
.how-sheet { display: flex; flex-direction: column; width: min(520px, 100%); max-height: 100%; background: #16202b; border: 1px solid var(--panel-border); border-radius: 16px; overflow: hidden; }
.how-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 8px 8px 20px; border-bottom: 1px solid var(--panel-border); }
.how-head h2 { margin: 0; font-size: 20px; }
.how-close { flex: none; width: 44px; height: 44px; padding: 0; font-size: 18px; }
.how-body { overflow-y: auto; overscroll-behavior: contain; padding: 14px 20px 18px; text-align: left; color: var(--muted); font-size: 15px; line-height: 1.5; }
.how-body p { margin: 0 0 10px; }
.how-body p:last-child { margin-bottom: 0; }
.how-body b { color: var(--text); }
/* Keys and mouse on a desktop, the stick and the buttons on a touch screen. */
.for-touch { display: none; }
@media (pointer: coarse) {
  .for-touch { display: inline; }
  .for-keys { display: none; }
  #name, .menu-card button { min-height: 44px; }
}
/* A short screen (a phone on its side): the same card, tighter. */
@media (max-height: 520px) {
  #menu { padding: 8px 16px; }
  .menu-card { padding: 10px 22px; }
  .menu-card h1 { font-size: 30px; margin-bottom: 2px; }
  .tagline { margin-bottom: 10px; font-size: 13px; }
  #name { padding: 8px 12px; font-size: 16px; margin-bottom: 8px; }
  .car-pick { margin: 0 0 8px; }
  button.primary { padding: 10px; font-size: 18px; margin-bottom: 8px; }
  .menu-row button { padding: 8px 10px; }
  .error { margin-top: 4px; }
  .links { margin-top: 4px; }
  .how-body { font-size: 14px; }
  /* Wider, so the tagline and the consent question (item 2's visitor.js, styled inline) take fewer lines. */
  .menu-card { width: min(620px, 100%); }
  #count-ask { margin-top: 8px !important; padding: 6px 10px !important; font-size: 13px !important; }
  #count-ask > div + div { margin-top: 4px !important; }
}

/* ---------- HUD ---------- */
#hud { position: fixed; inset: 0; pointer-events: none; z-index: 10; }
/* Behind the menu the HUD is laid out but not shown: its first layout (text shaping, emoji fonts) is paid while the
   game loads, and Play only has to show it. */
#hud.parked { visibility: hidden; }
#hud button, #hud .up-row { pointer-events: auto; }
.pill { position: absolute; top: 14px; left: 50%; transform: translateX(-50%); background: var(--panel); border: 1px solid var(--panel-border); padding: 8px 18px; border-radius: 999px; font-weight: 700; font-size: 18px; white-space: nowrap; }
#minimap { position: absolute; top: 14px; right: 14px; width: 180px; height: 180px; border-radius: 12px; border: 1px solid var(--panel-border); }
/* The lines of #hud-stack: each has its own place on a desktop (a phone stacks them, see below). */
.hud-stack { display: contents; }
#hud.watching .car-only { display: none !important; }
#feed { position: absolute; top: 206px; right: 14px; width: 300px; display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.feed-item { background: var(--panel); border: 1px solid var(--panel-border); border-radius: 8px; padding: 6px 10px; font-size: 14px; transition: opacity 1s; max-width: 300px; }
.feed-item.kill { border-color: rgba(255,77,77,0.6); }
.feed-item.out { border-color: rgba(255,184,40,0.6); }
.feed-item.rev, .feed-item.up { border-color: rgba(60,240,124,0.6); }
.feed-item.fade { opacity: 0; }
.banner { position: absolute; top: 30%; left: 50%; transform: translate(-50%, -50%); font-size: 96px; font-weight: 900; color: var(--accent); text-shadow: 0 6px 30px rgba(0,0,0,0.6); }
/* Between Play and the first picture of your own game: nothing of the match behind the menu, only that it is coming. */
.joining { position: absolute; top: 40%; left: 50%; transform: translate(-50%, -50%); background: var(--panel); border: 1px solid var(--panel-border); border-radius: 12px; padding: 12px 20px; font-size: 18px; font-weight: 700; white-space: nowrap; }
.joining::after { content: ""; display: inline-block; width: 0.75em; height: 0.75em; margin-left: 0.6em; vertical-align: -0.06em; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin 0.7s linear infinite; }
#hud.loading #phase, #hud.loading #minimap, #hud.loading #feed { visibility: hidden; }

#hud-car .gauges { position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%); width: min(460px, calc(100vw - 32px)); display: flex; flex-direction: column; gap: 5px; }
.gauge { background: var(--panel); border: 1px solid var(--panel-border); border-radius: 10px; padding: 5px 10px; display: grid; grid-template-columns: 78px 1fr 118px; align-items: center; gap: 8px; }
.gauge .label { font-size: 11px; font-weight: 800; letter-spacing: 1px; color: var(--muted); white-space: nowrap; }
.gauge .bar { height: 9px; background: rgba(255,255,255,0.08); border-radius: 6px; overflow: hidden; }
.gauge.battery .bar { height: 14px; }
#bat-fill { height: 100%; background: var(--battery); transition: width 0.2s; }
/* The gauge has as many cells as the battery pack on the car (D49): one per 0.25 kWh. */
.gauge.battery .bar { position: relative; }
#bat-cells { position: absolute; inset: 0; pointer-events: none; --cells: 4;
  background: repeating-linear-gradient(90deg, transparent 0 calc(100% / var(--cells) - 2px), rgba(14,20,27,0.92) calc(100% / var(--cells) - 2px) calc(100% / var(--cells))); }
#bat-fill.mid { background: linear-gradient(90deg, #e0c020, #ffe066); }
#bat-fill.low { background: linear-gradient(90deg, #ff3b3b, #ff8a4d); animation: pulse 0.8s infinite alternate; }
#hp-fill { height: 100%; background: var(--hp); transition: width 0.2s; }
.gauge .sub { font-size: 12px; color: var(--muted); text-align: right; white-space: nowrap; }
@keyframes pulse { from { opacity: 0.55; } to { opacity: 1; } }

.station-info { position: absolute; bottom: 104px; left: 50%; transform: translateX(-50%); background: var(--panel); border: 1px solid rgba(60,240,124,0.6); border-radius: 999px; padding: 5px 14px; font-weight: 800; font-size: 14px; white-space: nowrap; }
.station-info.low { border-color: rgba(255,120,60,0.8); color: #ffd0b0; }
/* Rockets (D33): your launcher's lock / reload, and warnings when a laser or a rocket is on you. */
.launcher-status { position: absolute; bottom: 104px; left: 50%; transform: translateX(-50%); min-width: 230px; background: var(--panel); border: 1px solid var(--panel-border); border-radius: 12px; padding: 4px 12px 6px; font-weight: 800; font-size: 13px; white-space: nowrap; text-align: center; }
.launcher-status .ls-bar { height: 5px; margin-top: 4px; background: rgba(255,255,255,0.08); border-radius: 3px; overflow: hidden; }
#ls-fill { height: 100%; width: 0; background: linear-gradient(90deg, #ff6a3d, #ff2a2a); }
.launcher-status.locking { border-color: rgba(255,60,60,0.8); }
/* Asleep in a charging ring (D50): the read-out sits above the charger's pill. */
.launcher-status.asleep { bottom: 140px; color: #bcd3ff; border-color: rgba(140,170,255,0.5); }
.launcher-status.asleep .ls-bar { display: none; }
.threat { position: absolute; top: 62px; left: 50%; transform: translateX(-50%); background: rgba(40,8,8,0.82); border: 2px solid rgba(255,70,70,0.9); border-radius: 12px; padding: 7px 16px; font-weight: 900; font-size: 18px; white-space: nowrap; }
.threat.lock { border-color: rgba(255,184,40,0.9); background: rgba(40,28,6,0.82); }
.threat.rocket.far { border-color: rgba(120,230,90,0.9); }
.threat.rocket.near { border-color: rgba(255,150,40,0.95); animation: pulse 0.45s infinite alternate; }
.threat.rocket.close { border-color: rgba(255,40,40,1); color: #ffd6d6; animation: pulse 0.16s infinite alternate; }
/* "Still there?" before an idle drop (main.js): under the rocket warning's place. */
#idle-warning { top: 124px; white-space: normal; text-align: center; max-width: calc(100vw - 32px); }
/* The hint (js/hints.js, item 9): one line in the rocket warning's place while there is none. It fades in and out; the
   low-battery one pulses. A desktop narrower than 1100 px hangs it under the corner buttons, clear of the minimap. */
.hint { position: absolute; top: 62px; left: 50%; transform: translateX(-50%); width: max-content; max-width: min(620px, calc(100vw - 640px)); background: rgba(12,22,32,0.88); border: 2px solid rgba(120,200,255,0.85); border-radius: 12px; padding: 7px 16px; font-weight: 800; font-size: 18px; line-height: 1.3; text-align: center; opacity: 0; transition: opacity 0.3s; }
.hint.on { opacity: 1; }
.hint.urgent { border-color: rgba(255,80,60,0.95); animation: urgent 0.5s ease-in-out infinite alternate; }
@keyframes urgent { to { box-shadow: 0 0 18px rgba(255,70,50,0.85); border-color: #ff2a2a; } }
#hud.threatened #hint { display: none; }
@media (min-width: 721px) and (max-width: 1100px) and (pointer: fine) { .hint { top: 112px; max-width: calc(100vw - 440px); } }
.speedo { position: absolute; bottom: 24px; right: 24px; background: var(--panel); border: 1px solid var(--panel-border); border-radius: 14px; padding: 10px 16px; text-align: right; }
.speedo span { font-size: 40px; font-weight: 900; }
.speedo small { display: block; color: var(--muted); font-size: 12px; margin-top: -4px; }
.inventory { position: absolute; bottom: 24px; left: 20px; display: flex; gap: 8px; }
.inventory > span { background: var(--panel); border: 1px solid var(--panel-border); border-radius: 10px; padding: 8px 12px; font-size: 18px; font-weight: 800; }
.inventory .inv-label { font-size: 14px; font-weight: 700; color: var(--muted); }
/* A picked-up Gear landed in the car (D48). */
#gears.bump { animation: gearBump 0.5s ease-out; }
@keyframes gearBump { 30% { transform: scale(1.3); background: rgba(245,197,66,0.45); border-color: rgba(245,197,66,0.9); } }
/* The Gear icon (D46): a gold cog with a steel wrench across it, like the pickups in the arena. */
.gear-icon { display: inline-block; width: 1.2em; height: 1.2em; vertical-align: -0.24em; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23f5c542' fill-rule='evenodd' stroke='%237a5a12' stroke-width='0.7' stroke-linejoin='round' d='M13.62 3.86 L14.88 1.80 L17.18 2.75 L16.61 5.10 L17.87 6.13 L18.90 7.39 L21.25 6.82 L22.20 9.12 L20.14 10.38 L20.30 12.00 L20.14 13.62 L22.20 14.88 L21.25 17.18 L18.90 16.61 L17.87 17.87 L16.61 18.90 L17.18 21.25 L14.88 22.20 L13.62 20.14 L12.00 20.30 L10.38 20.14 L9.12 22.20 L6.82 21.25 L7.39 18.90 L6.13 17.87 L5.10 16.61 L2.75 17.18 L1.80 14.88 L3.86 13.62 L3.70 12.00 L3.86 10.38 L1.80 9.12 L2.75 6.82 L5.10 7.39 L6.13 6.13 L7.39 5.10 L6.82 2.75 L9.12 1.80 L10.38 3.86 L12.00 3.70ZM15.40 12.00A3.4 3.4 0 1 0 8.60 12.00A3.4 3.4 0 1 0 15.40 12.00Z'/%3E%3Cg transform='rotate(45 12 12)'%3E%3Cg fill='none' stroke='%231b2530' stroke-width='4.0' stroke-linecap='round'%3E%3Cpath d='M10.03 2.38A3.2 3.2 0 1 0 13.97 2.38'/%3E%3Cpath d='M12 8.3V17.6'/%3E%3Ccircle cx='12' cy='19.9' r='1.9'/%3E%3C/g%3E%3Cg fill='none' stroke='%23dfe5ea' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M10.03 2.38A3.2 3.2 0 1 0 13.97 2.38'/%3E%3Cpath d='M12 8.3V17.6'/%3E%3Ccircle cx='12' cy='19.9' r='1.9'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat; }
.upgrades { position: absolute; bottom: 80px; left: 20px; width: 256px; background: var(--panel); border: 1px solid var(--panel-border); border-radius: 12px; padding: 8px; display: flex; flex-direction: column; gap: 4px; }
/* What the numbers at the ends of the rows are (item 9): the price in Gears. */
.up-title { font-size: 13px; font-weight: 800; padding: 0 6px 2px; }
.up-title small { font-weight: 600; color: var(--muted); }
.up-title .gear-icon { width: 1.05em; height: 1.05em; vertical-align: -0.2em; }
.up-row { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border-radius: 6px; font-size: 14px; border: 1px solid transparent; }
.up-row kbd { font: inherit; font-size: 12px; font-weight: 800; background: rgba(255,255,255,0.12); border-radius: 4px; padding: 0 5px; }
.up-row .up-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.up-row .up-short { display: none; }
.up-row .pips { display: flex; gap: 3px; }
.up-row .pips i { width: 10px; height: 10px; border-radius: 2px; background: rgba(255,255,255,0.15); }
.up-row .pips i.on { background: var(--accent); }
/* Prices (D51): every row shows what an upgrade costs; what you can afford lights up and pulses, the rest is dimmed. */
.up-row .up-price { display: inline-flex; align-items: center; justify-content: flex-end; gap: 1px; min-width: 34px; font-size: 13px; font-weight: 800; color: rgba(255,140,110,0.9); }
.up-row .up-price .gear-icon { width: 1.05em; height: 1.05em; }
.up-row.affordable { background: rgba(60,240,124,0.2); border-color: rgba(60,240,124,0.8); cursor: pointer; animation: canBuy 1.6s ease-in-out infinite; }
.up-row.affordable .up-price { color: var(--accent); }
.up-row.affordable kbd { background: var(--accent); color: #07210f; }
.up-row.short .up-name, .up-row.short .up-short { opacity: 0.75; }
.up-row.maxed .up-name, .up-row.maxed .up-short { color: var(--muted); }
.up-row.maxed .up-price { color: var(--muted); font-size: 11px; letter-spacing: 1px; }
@keyframes canBuy { 50% { box-shadow: 0 0 12px rgba(60,240,124,0.6); } }
.shop { position: absolute; bottom: 124px; right: 24px; width: 220px; background: var(--panel); border: 1px solid rgba(255,184,40,0.6); border-radius: 12px; padding: 10px; display: flex; flex-direction: column; gap: 6px; }
.shop-title { font-weight: 800; font-size: 14px; }
.shop-title small { font-weight: 600; color: var(--muted); }
.shop button.can { border-color: var(--accent); background: rgba(60,240,124,0.16); box-shadow: 0 0 10px rgba(60,240,124,0.35); }
.shop button.owned { border-color: var(--accent); color: var(--accent); }
.shop button { white-space: nowrap; }
.shop .gear-icon { width: 1.05em; height: 1.05em; vertical-align: -0.18em; }
.shop button:disabled { opacity: 0.7; cursor: default; }
.shop button.cant { opacity: 0.5; }
/* What an item does (item 9), a line under its name on a desktop. */
.shop button .what { display: block; font-size: 11px; font-weight: 600; color: var(--muted); white-space: normal; }

.overlay-msg { position: absolute; top: 40%; left: 50%; transform: translate(-50%, -50%); text-align: center; background: var(--panel); border: 1px solid rgba(255,184,40,0.7); border-radius: 14px; padding: 16px 22px; max-width: 520px; }
.overlay-msg .big { font-size: 42px; font-weight: 900; color: var(--warn); margin-bottom: 6px; }
/* Without a car: who you watch and when you drive again. It hangs under the pill. */
.overlay-msg.small { top: 62px; transform: translateX(-50%); border-color: var(--panel-border); font-size: 15px; }

.panel { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: min(720px, calc(100vw - 32px)); max-height: 80vh; overflow: auto; background: rgba(14, 20, 27, 0.94); border: 1px solid var(--panel-border); border-radius: 16px; padding: 18px 22px; pointer-events: auto; }
.panel .short { display: none; }
/* The cars' name tags would show through the results (item 9). */
body.results-up #labels { display: none; }
.panel h2 { margin: 0 0 4px; }
.panel p { color: var(--muted); margin: 0 0 12px; }
.panel table { width: 100%; border-collapse: collapse; font-size: 15px; }
.panel th, .panel td { text-align: left; padding: 6px 8px; border-bottom: 1px solid rgba(255,255,255,0.07); }
.panel tr.me td { color: var(--accent); font-weight: 800; }
.panel small { color: var(--muted); }
.panel #results-sub { margin-bottom: 4px; }
.panel .results-note { margin: 0 0 10px; font-size: 12px; }
/* The end card (item 9): your place, what ended your car and how long it lasted, with Play again beside them (under
   them on an upright phone), above the table. */
.end-card { display: grid; grid-template-columns: 1fr auto; align-items: center; column-gap: 18px; margin: 0 0 12px; padding: 2px 0 12px; border-bottom: 1px solid var(--panel-border); }
.end-card > :not(.rematch) { grid-column: 1; }
.end-card > .rematch { grid-column: 2; grid-row: 1 / span 4; }
.end-place { font-size: 36px; font-weight: 900; line-height: 1.1; }
.end-card.won .end-place { color: var(--accent); }
.end-cause { font-size: 17px; font-weight: 700; margin-top: 3px; }
.end-cause:empty { display: none; }
.end-time { color: var(--muted); font-size: 14px; margin-top: 1px; }
/* #end-profile stays a box while empty (no height): js/profile.js puts the award there only when the slot is laid out. */
/* The results take the screen: what they would cover goes away while they show. */
#hud.show-results #outcharged, #hud.show-results #spectating { display: none; }

.car-label { position: absolute; left: 0; top: 0; text-align: center; font-size: 13px; font-weight: 700; color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,0.9); white-space: nowrap; will-change: transform; }
.car-label.me .name { color: var(--accent); }
.car-label.dead .name { color: var(--warn); }
/* A bot says so under its name tag's name (item 9: the opponents looked like people until the results). */
.car-label.bot .name::after { content: " bot"; font-size: 10px; font-weight: 600; color: #c9d6e2; }
/* Your car's tag (js/guide.js, item 9), in the light blue of its ring. */
.you-tag { position: absolute; left: 0; top: 0; padding: 1px 7px 2px; border-radius: 8px; background: #8ce0ff; color: #08202c; font-size: 12px; font-weight: 900; letter-spacing: 1px; white-space: nowrap; pointer-events: none; will-change: transform; }
.you-tag::after { content: ""; position: absolute; left: 50%; bottom: -5px; margin-left: -5px; border: 5px solid transparent; border-bottom: 0; border-top-color: #8ce0ff; }
.car-label .bars { width: 64px; margin: 2px auto 0; }
.car-label .bars i { display: block; height: 4px; margin-top: 2px; border-radius: 2px; }
.car-label .bars i.hp { background: #ff6b6b; }
.car-label .bars i.bat { background: #3cf07c; }
/* Damage numbers float up from the car that took the hit, in that car's colour. */
.dmg-pop { position: absolute; left: 0; top: 0; font-size: 17px; font-weight: 900; text-shadow: 0 0 3px #000, 0 1px 4px rgba(0,0,0,0.9); white-space: nowrap; pointer-events: none; will-change: transform, opacity; }
.dmg-pop.big { font-size: 24px; }

.corner-buttons { position: absolute; top: 64px; left: 14px; display: flex; gap: 6px; pointer-events: auto; }
.corner-buttons button { width: 38px; height: 38px; padding: 0; font-size: 18px; border-radius: 10px; background: var(--panel); }
.corner-buttons .spectator-only { display: none; }
#hud.watching .corner-buttons .spectator-only { display: inline-block; }
body.test-drive .corner-buttons { top: auto; bottom: 14px; left: auto; right: 150px; }
/* A desktop 1100 px wide or more names the player's three corner buttons beside their icons, while you drive: the
   lines centred at the top (the rocket warning, the hint) stay clear of them, and a spectator's longer row and line
   would not. A touch screen has no room, and its buttons are bigger. */
@media (min-width: 1100px) and (pointer: fine) {
  body:not(.test-drive) #hud:not(.watching) .corner-buttons button:not(.spectator-only) { width: auto; padding: 0 12px 0 9px; }
  body:not(.test-drive) #hud:not(.watching) .corner-buttons button:not(.spectator-only)::after { content: attr(data-label); margin-left: 6px; font-size: 14px; font-weight: 700; vertical-align: 2px; }
}

/* ---------- Touch controls ---------- */
/* The stick's zone takes the left thumb wherever it lands; the base and the knob are drawn in it (js/touch.js). At
   rest the base shows where a thumb goes and which way is forward. BRAKE and FIRE are for the right thumb. The zone
   lies under every panel and button: a tap on an upgrade never starts the stick. */
.touch-zone, .touch-btn { display: none; }
.touch-zone { z-index: 1; }
.upgrades, .bench, .shop, .inventory, .speedo, .corner-buttons, .touch-btn, .panel, #hud-car .gauges { z-index: 3; }
.stick-base { position: absolute; left: 14px; bottom: 8px; width: 120px; height: 120px; border-radius: 50%; border: 2px solid rgba(255,255,255,0.4); background: rgba(14,20,27,0.42); pointer-events: none; will-change: transform; }
.stick-base.held { border-color: rgba(60,240,124,0.75); }
/* Forward is up: an arrowhead on the rim. */
.stick-fwd { position: absolute; left: 50%; top: 7px; width: 0; height: 0; margin-left: -9px; border: 9px solid transparent; border-top: 0; border-bottom: 13px solid rgba(255,255,255,0.75); }
.stick-knob { position: absolute; left: 50%; top: 50%; width: 52px; height: 52px; margin: -26px 0 0 -26px; border-radius: 50%; background: rgba(255,255,255,0.4); border: 2px solid rgba(255,255,255,0.75); will-change: transform; }
.stick-base.held .stick-knob { background: rgba(60,240,124,0.55); border-color: rgba(60,240,124,0.95); }
.touch-btn { position: absolute; border-radius: 50%; align-items: center; justify-content: center; font-weight: 900; pointer-events: auto; touch-action: none; user-select: none; -webkit-user-select: none; }
.touch-fire { background: rgba(110,16,16,0.72); border: 2px solid rgba(255,120,120,0.95); color: #ffd6d6; }
.touch-brake { background: rgba(70,50,8,0.72); border: 2px solid rgba(255,200,90,0.95); color: #ffe08a; font-size: 13px; letter-spacing: 0.5px; }
.touch-btn.down { filter: brightness(1.5); transform: scale(0.94); }
@media (pointer: coarse) {
  /* Any touch screen, a tablet too, has the phone's layout (below); here only what shows and what a thumb can hit. */
  .touch-zone { display: block; position: absolute; pointer-events: auto; touch-action: none; }
  .touch-btn { display: flex; }
  .up-row kbd { display: none; }
  .shop button { min-height: 44px; }
  .how-body { -webkit-overflow-scrolling: touch; }
}
/* Without a car of your own there is nothing to steer; FIRE needs a launcher, and nothing fires inside a charging ring
   (D50); a car that ran dry only steers. */
#hud.no-car .touch-zone, #hud.no-car .touch-btn { display: none; }
#hud:not(.has-launcher) .touch-fire, #hud.at-station .touch-fire { display: none; }
#hud.powerless .touch-btn { display: none; }

/* ---------- Test-drive bench ---------- */
.bench { position: absolute; top: 14px; left: 14px; width: 324px; max-height: calc(100vh - 28px); overflow: auto; background: var(--panel); border: 1px solid var(--panel-border); border-radius: 12px; padding: 10px 12px; pointer-events: auto; font-size: 13px; }
.bench-title { font-weight: 800; font-size: 15px; margin-bottom: 6px; }
.bench-title small { font-weight: 400; color: var(--muted); font-size: 11px; }
.bench-tiers { display: grid; grid-template-columns: 1fr; gap: 3px; margin-bottom: 8px; }
.bench-tier { display: flex; align-items: center; gap: 6px; }
.bench-tier .bt-name { flex: 1; }
.bench-tier button { padding: 0; width: 26px; height: 22px; border-radius: 6px; font-weight: 800; }
.bench-tier .bt-val { width: 22px; text-align: center; font-weight: 800; color: var(--accent); }
.bench-model { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.bench-model label { color: var(--muted); font-size: 12px; }
.bench-model select { flex: 1; font: inherit; font-size: 12px; padding: 5px 8px; border-radius: 7px; border: 1px solid var(--panel-border); background: rgba(255,255,255,0.08); color: var(--text); }
.bench-model select option { background: #1b242e; }
.bench-note { color: var(--muted); font-size: 11px; line-height: 1.35; margin-bottom: 8px; }
.bench-controls { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.bench-controls select, .bench-controls button { font: inherit; font-size: 12px; padding: 5px 8px; border-radius: 7px; border: 1px solid var(--panel-border); background: rgba(255,255,255,0.08); color: var(--text); }
.bench-controls select option { background: #1b242e; }
.bench-tele { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.bench-tele th { font-size: 11px; color: var(--muted); font-weight: 600; text-align: right; padding: 1px 4px; }
.bench-tele td { text-align: right; padding: 1px 4px; border-top: 1px solid rgba(255,255,255,0.05); }
.bench-tele td:first-child { text-align: left; color: var(--muted); }
.bench-tele td.unit { color: var(--muted); font-size: 11px; text-align: left; }
#bench-chart { width: 100%; height: 80px; margin-top: 6px; border-radius: 6px; display: block; }
.bench-pred { color: var(--muted); font-size: 11px; margin-top: 4px; }
/* The bench sets tiers and loadouts directly and fills the left column: no upgrade panel or Gear counters under it. */
body.test-drive .upgrades, body.test-drive .inventory { display: none; }

/* ---------- Phones ---------- */
/* Any touch screen (a phone either way up, a tablet) and any narrow window. Width alone would give a phone on its side
   the desktop's HUD, with its stick under the upgrades. This block is the upright layout; the block after it moves
   things for a screen on its side.
     top      the pill (two lines: the cars left, the goal) and the corner buttons on the left, the minimap on the right
     under it #hud-stack, one column: the line that matters now (a rocket warning, else the charger, else the launcher),
              the garage, who you watch, the newest two feed lines
     bottom   the gauges, above them the upgrades as a strip of tap targets, above that the Gears and the speed
     thumbs   the stick on the left, BRAKE and FIRE on the right, above the bottom rows */
@media (max-width: 720px), (pointer: coarse) {
  .pill { top: 10px; left: 10px; transform: none; max-width: calc(100vw - 134px); padding: 6px 12px; border-radius: 14px; font-size: 13px; line-height: 17px; white-space: normal; }
  .pill .sep { display: none; }
  .pill .goal { display: block; }
  .pill .goal::first-letter { text-transform: uppercase; }
  #minimap { top: 10px; right: 10px; width: 104px; height: 104px; }
  .corner-buttons, body.test-drive .corner-buttons { top: 64px; bottom: auto; left: 10px; right: auto; }
  .corner-buttons button { width: 44px; height: 44px; }

  .hud-stack { position: absolute; top: 120px; left: 10px; right: 10px; display: flex; flex-direction: column; align-items: center; gap: 6px; }
  #hud-stack > * { position: static; transform: none; max-width: 100%; }
  #hud-stack > #shop { max-width: 420px; }
  .threat, .station-info, .launcher-status, .joining, #idle-warning, .hint { white-space: normal; text-align: center; font-size: 13px; padding: 5px 12px; border-radius: 14px; min-width: 0; }
  .hint { width: auto; line-height: 17px; }
  .launcher-status { padding: 4px 12px 6px; }
  .launcher-status.asleep { display: none; }
  /* One line at a time: a rocket warning goes before the charger and the launcher. */
  #hud.threatened .station-info, #hud.threatened .launcher-status { display: none; }
  .overlay-msg.small { font-size: 13px; padding: 8px 12px; }
  .shop { width: 100%; max-width: 420px; flex-direction: row; flex-wrap: wrap; padding: 6px; gap: 4px; }
  .shop-title { flex: 0 0 100%; font-size: 12px; }
  .shop button { flex: 1 1 0; min-width: 0; min-height: 44px; padding: 4px 6px; font-size: 12px; line-height: 1.25; white-space: normal; }
  .shop .cost { display: block; white-space: nowrap; }
  .shop .cost .dot { display: none; }
  #feed { align-self: flex-end; width: auto; max-width: min(78vw, 300px); gap: 4px; }
  .feed-item { font-size: 12px; line-height: 15px; padding: 4px 8px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
  .feed-item:nth-child(n+3) { display: none; }
  .banner { top: max(34%, 290px); font-size: 64px; }
  .overlay-msg { top: 262px; transform: translateX(-50%); width: calc(100vw - 32px); max-width: 420px; padding: 12px 16px; font-size: 14px; }
  .overlay-msg .big { font-size: 28px; margin-bottom: 4px; }
  #hud-stack > .overlay-msg.small { width: auto; }

  #hud-car .gauges { bottom: 10px; width: calc(100vw - 20px); gap: 4px; }
  .gauge { grid-template-columns: 58px 1fr 96px; padding: 4px 8px; gap: 6px; }
  .gauge .label { font-size: 10px; letter-spacing: 0; }
  .gauge .sub { font-size: 11px; }
  /* The upgrades: a strip of tap targets, 44 px tall or more, each with its name, its level and its price. */
  .upgrades { flex-direction: row; left: 8px; right: 8px; width: auto; bottom: 72px; padding: 2px; gap: 2px; transform: none; }
  .up-row { flex: 1 1 0; min-width: 0; min-height: 44px; flex-direction: column; justify-content: center; gap: 3px; padding: 2px 0; }
  .up-row kbd, .up-row .up-name { display: none; }
  .up-row .up-short { display: block; max-width: 100%; overflow: hidden; font-size: 10px; line-height: 12px; letter-spacing: -0.2px; white-space: nowrap; }
  .up-row .pips i { width: 5px; height: 5px; border-radius: 1px; }
  .up-row .up-price { min-width: 0; font-size: 10px; line-height: 11px; }
  .up-row .up-price .gear-icon { width: 0.95em; height: 0.95em; }
  .inventory { bottom: 130px; left: 10px; gap: 6px; }
  .inventory > span { font-size: 14px; padding: 5px 8px; }
  .inventory .inv-label { font-size: 11px; }
  .speedo { bottom: 130px; right: 10px; padding: 3px 10px; display: flex; align-items: baseline; gap: 4px; border-radius: 10px; }
  .speedo span { font-size: 20px; }
  .speedo small { display: inline; margin: 0; font-size: 11px; }

  .touch-zone { left: 0; bottom: 172px; width: 50vw; height: calc(100vh - 426px); max-height: 330px; }
  .touch-brake { right: 14px; bottom: 182px; width: 72px; height: 72px; }
  .touch-fire { right: 14px; bottom: 266px; width: 72px; height: 72px; }

  /* The results and the scoreboard fill the screen under the top bar; the driving HUD waits behind them. */
  .panel { top: 120px; bottom: auto; left: 10px; right: 10px; width: auto; max-height: calc(100vh - 130px); transform: none; padding: 12px 14px; }
  /* Every column fits an upright phone (item 9: Gears and Upgrades were left out), with two shorter headers. */
  .panel table { font-size: 12px; }
  .panel th, .panel td { padding: 5px 3px; }
  .panel .long { display: none; }
  .panel .short { display: inline; }
  #results td:nth-child(2) { white-space: nowrap; }
  #results td .nm { display: inline-block; max-width: 64px; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; }
  /* The scene's bright ramps and cars showed through the HUD's panels (item 9): darker ones. */
  #hud { --panel: rgba(14, 20, 27, 0.9); }
  .touch-brake { background: rgba(70, 50, 8, 0.88); }
  .touch-fire { background: rgba(110, 16, 16, 0.88); }
  .up-title, .shop button .what { display: none; }
  .end-card { display: block; text-align: center; margin-bottom: 10px; padding-bottom: 10px; }
  .end-place { font-size: 30px; }
  .end-cause { font-size: 15px; }
  .end-time { font-size: 13px; }
  #hud #results .end-card .rematch { margin-top: 10px; }
  #hud.show-results .hud-stack, #hud.show-results #hud-car, #hud.show-results .touch-zone, #hud.show-results .touch-btn, #hud.show-results .banner,
  #hud.show-scores .hud-stack, #hud.show-scores #hud-car, #hud.show-scores .touch-zone, #hud.show-scores .touch-btn, #hud.show-scores .banner { display: none; }
  .bench { width: 240px; font-size: 11px; }
}
/* A phone 370 px wide or less: the results table a size smaller, so its eight columns fit (item 9). */
@media (max-width: 370px) {
  .panel { padding: 10px 10px; }
  .panel table { font-size: 11px; }
  .panel th, .panel td { padding: 4px 2px; }
  #results td .nm { max-width: 56px; }
}
/* A short phone upright (up to 680 px tall): the outcharged message sits higher and the stick's ring is smaller, so
   they stay apart. */
@media (orientation: portrait) and (max-height: 680px) and (max-width: 720px), (orientation: portrait) and (max-height: 680px) and (pointer: coarse) {
  .overlay-msg { top: 232px; }
  .stick-base { width: 96px; height: 96px; }
}
/* On its side: the pill, the corner buttons and the minimap share the top row; the column hangs under it in the
   middle, with the feed on its left; the upgrades and the gauges sit between the thumbs; the speed is left out. */
@media (orientation: landscape) and (max-height: 540px) and (max-width: 720px), (orientation: landscape) and (pointer: coarse) {
  #hud { --zone: min(232px, 28vw); --thumb: 96px; }
  .pill { top: 8px; max-width: calc(100vw - 390px); }
  .pill .sep, .pill .goal { display: inline; }
  .pill .goal::first-letter { text-transform: none; }
  #minimap { top: 8px; }
  .corner-buttons, body.test-drive .corner-buttons { top: 8px; left: auto; right: 124px; }

  .hud-stack { top: 60px; }
  #hud-stack > *, #hud-stack > #shop { max-width: min(340px, calc(100vw - 2 * var(--zone) - 40px)); }
  #hud-stack > #feed { position: absolute; top: 0; left: 0; align-items: flex-start; max-width: calc(50% - min(170px, 50vw - var(--zone) - 20px) - 8px); }
  .banner { top: 44%; font-size: 56px; }
  .overlay-msg { top: 116px; width: auto; max-width: min(340px, calc(100vw - 2 * var(--zone) - 40px)); padding: 8px 14px; font-size: 13px; }
  .overlay-msg .big { font-size: 22px; margin-bottom: 2px; }

  #hud-car .gauges { bottom: 8px; left: calc(var(--zone) + 8px); right: var(--thumb); width: auto; max-width: 420px; margin: 0 auto; transform: none; flex-direction: row; gap: 6px; }
  .gauge { flex: 1 1 0; min-width: 0; grid-template-columns: auto 1fr auto; padding: 4px 8px; }
  .gauge .gauge-name { display: none; }
  .upgrades { left: calc(var(--zone) + 8px); right: var(--thumb); bottom: 42px; max-width: 420px; margin: 0 auto; }
  .inventory { bottom: 8px; left: 10px; }
  .speedo { display: none; }

  .touch-zone { bottom: 48px; width: var(--zone); height: calc(100vh - 188px); max-height: none; }
  .stick-base { left: max(8px, calc(var(--zone) / 2 - 80px)); bottom: 6px; }
  .touch-brake { right: 12px; bottom: 10px; }
  .touch-fire { right: 12px; bottom: 94px; }

  .panel { top: 56px; left: 50%; right: auto; width: min(600px, calc(100vw - 244px)); max-height: calc(100vh - 64px); transform: translateX(-50%); }
  .panel .long { display: inline; }
  .panel .short { display: none; }
  .panel table { font-size: 13px; }
  .end-card { display: grid; text-align: left; margin-bottom: 8px; padding: 0 0 8px; }
  .end-place { font-size: 24px; }
  .end-cause { font-size: 14px; margin-top: 2px; }
  .end-time { font-size: 12px; margin-top: 0; }
  #hud #results .end-card .rematch { margin-top: 0; }
}
/* A tablet on its side: the same places, with room to spare. */
@media (orientation: landscape) and (pointer: coarse) and (min-height: 600px) {
  #minimap { width: 160px; height: 160px; }
  .corner-buttons, body.test-drive .corner-buttons { right: 180px; }
  .pill { max-width: calc(100vw - 446px); }
  .upgrades, #hud-car .gauges { max-width: 560px; }
}

/* ---------- Play again (build sprint item 8) ---------- */
/* One button where the player looks: inside the outcharged overlay, in the results' end card (item 9; above the table,
   so a long table never scrolls it away), or on its own in the middle when the car is gone. A thumb-sized target, above
   the touch stick's zone. */
.rematch { display: flex; flex-direction: column; align-items: center; gap: 6px; margin-top: 14px; }
.rematch button.primary { width: auto; min-width: min(260px, calc(100vw - 96px)); min-height: 56px; margin: 0; padding: 12px 28px; font-size: 22px; }
.rematch button.primary:disabled { opacity: 0.7; cursor: default; filter: none; }
.rematch-note { color: var(--muted); font-size: 14px; text-align: center; }
.rematch-note:empty { display: none; }
#results .rematch { margin: 2px 0 14px; }
#results .end-card .rematch { margin: 0; }
.rematch.floating { position: absolute; top: 58%; left: 50%; transform: translate(-50%, -50%); margin: 0; background: var(--panel); border: 1px solid var(--panel-border); border-radius: 14px; padding: 14px 18px; }
.rematch.floating, #hud .rematch-host { z-index: 4; }
/* With the button on the results, the outcharged overlay behind the panel would show through right under it. */
#hud.rematch-results #outcharged { display: none; }
