/* Punk Dog Surfers: layout and game states only. Fonts, colours and control appearance come from
   shared/ui/hud-tokens.css and shared/ui/hud-components.css. */
/* Never double-tap zoom: sticks, canvases and the HUD override this with touch-action:none.
   engine/touch-zoom.js also blocks the pinch and double-tap gestures Safari keeps to itself. */
* { touch-action: manipulation; }
/* Four things Space Wars learned about phones that this game had not:
   - iOS inflates text on its own when you rotate to landscape, which pulls a fixed HUD apart;
   - a swipe that starts on the HUD must not pull-to-refresh or rubber-band the page behind it;
   - the browser paints form controls light unless the page declares it is dark;
   - and a tap should not leave the mobile tap flash on a button you are holding to fire. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; color-scheme: dark; }
html, body { margin: 0; height: 100%; overflow: hidden; overscroll-behavior: none; background: var(--hud-surface-canvas); color: var(--hud-text); font-family: var(--hud-font-body); }
body { -webkit-tap-highlight-color: transparent; }
.pds-stage { position: fixed; inset: 0; }
.pds-stage canvas { display: block; width: 100%; height: 100%; }

.pds-hud { position: fixed; inset: 0; pointer-events: none; z-index:4; }
/* The crosshair carries the two facts that decide a shot, because a mouse player is looking at it and
   not at the bottom of the screen: is the slingshot loaded, and is anything actually in reach. Reach
   runs from 20 metres to 80 depending on the dog, so "in reach" is not something you can eyeball. */
.pds-crosshair { position: absolute; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px; transition: opacity var(--hud-motion-fast) linear, transform 70ms linear; }
.pds-crosshair::before, .pds-crosshair::after { content: ''; position: absolute; background: var(--hud-text); box-shadow: 0 0 0 1px #000a; transition: background var(--hud-motion-fast) linear, box-shadow var(--hud-motion-fast) linear; }
.pds-crosshair::before { left: 10px; top: 0; width: 2px; height: 22px; }
.pds-crosshair::after { top: 10px; left: 0; height: 2px; width: 22px; }
/* still reloading: the cross fades, so the gap is felt without reading a bar */
.pds-crosshair.is-loading { opacity: .35; }
/* a dog in the cone, in reach, in sight and not spawn-protected — this one lands */
.pds-crosshair.is-on-target::before, .pds-crosshair.is-on-target::after { background: var(--hud-accent); box-shadow: 0 0 8px var(--hud-accent), 0 0 0 1px #000a; }
.pds-aim-name { position: absolute; left: 50%; top: calc(50% + 20px); transform: translateX(-50%); white-space: nowrap; font-family: var(--hud-font-label); font-weight: var(--hud-weight-label); font-size: var(--hud-text-sm); letter-spacing: var(--hud-tracking-label); color: var(--hud-accent); text-shadow: 0 1px 3px #000; opacity: 0; transition: opacity var(--hud-motion-fast) linear; }
.pds-aim-name.is-on { opacity: 1; }
.pds-debug { position: absolute; left: var(--hud-space-3); bottom: var(--hud-space-3); margin: 0; padding: var(--hud-space-2) var(--hud-space-3); background: var(--hud-surface-glass); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); font-family: var(--hud-font-pixel); font-size: var(--hud-text-xs); line-height: 1.6; color: var(--hud-text-muted); white-space: pre; }

[hidden] { display: none !important; }
/* ---- hero pick, online row, lobby, shop ---- */
/* ---- the menu ----------------------------------------------------------------------------------
   Laid out like the Space Wars 3 home screen: one shell pinned to the viewport that never scrolls,
   three panes inside it, and only the lists scroll. Everything else about it is deliberately silly:
   the panes sit crooked, the logo will not sit still, and nothing is called a "lobby". */
.pds-menu { padding: 0; align-items: stretch; }
.pds-shell {
  position: fixed; inset: 0; display: grid; grid-template-rows: auto minmax(0, 1fr) auto;
  gap: clamp(6px, 1.4vh, 14px);
  padding: clamp(8px, 2vh, 18px) clamp(10px, 2.5vw, 26px);
  padding-top: max(clamp(8px, 2vh, 18px), env(safe-area-inset-top));
  padding-bottom: max(clamp(8px, 2vh, 18px), env(safe-area-inset-bottom));
  overflow: hidden;
}
.pds-top { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--hud-space-3); }
.pds-menu .pds-logo { margin: 0; font-size: clamp(22px, 3.6vw, 44px); line-height: .92; transform: rotate(-2.5deg); animation: pds-wobble 3.4s ease-in-out infinite; }
.pds-menu .pds-logo span { display: block; font-size: clamp(26px, 4.6vw, 56px); margin-top: -.08em; }
.pds-menu .pds-tagline { margin: 0; align-self: center; font-family: var(--hud-font-label); font-size: clamp(11px, 1.3vw, 15px); color: var(--hud-accent); transform: rotate(-1deg); }
.pds-tin { padding: var(--hud-space-1) var(--hud-space-3); background: var(--hud-accent); color: var(--hud-text-on-accent); border-radius: var(--hud-radius); font-family: var(--hud-font-display); font-size: var(--hud-text-count); transform: rotate(3deg); box-shadow: 0 3px 0 #0006; }
@keyframes pds-wobble { 0%, 100% { transform: rotate(-2.5deg); } 50% { transform: rotate(-.6deg) translateY(-2px); } }

/* The dog is the point. It gets the widest column, and the picker column is only as wide as the
   cards it holds, so a big screen spends its extra pixels on the dog instead of on a void. */
.pds-main { display: grid; grid-template-columns: minmax(0, 1.9fr) minmax(300px, 1fr) minmax(210px, 280px); gap: clamp(8px, 1.4vw, 16px); min-height: 0; }
.pds-pane { display: flex; flex-direction: column; gap: var(--hud-space-2); min-height: 0; padding: clamp(8px, 1.4vh, 14px); background: var(--hud-panel-fill); border: var(--hud-border-width) solid var(--hud-border); border-radius: var(--hud-radius); box-shadow: var(--hud-shadow); }
.pds-pane-dog { transform: rotate(-.6deg); }
/* vertical only: the pane is a couple of pixels wider than its box because it is rotated, and that
   was enough to put a horizontal scrollbar across the bottom of it */
.pds-pane-pick { transform: rotate(.35deg); overflow-x: hidden; overflow-y: auto; }
.pds-pane-go { transform: rotate(.8deg); justify-content: center; }
.pds-pane-title { margin: 0; font-family: var(--hud-font-label); font-weight: var(--hud-weight-label); font-size: var(--hud-text-xs); letter-spacing: .2em; text-transform: uppercase; color: var(--hud-edge-glow); }
.pds-preview-wrap { position: relative; display: flex; flex: 1 1 auto; min-height: 120px; }
/* the badge that says the dog is yours to turn: it pulses until you have turned him once, then goes */
.pds-preview-hint { position: absolute; left: 50%; bottom: var(--hud-space-2); transform: translateX(-50%); padding: 3px var(--hud-space-2); border-radius: 999px; background: color-mix(in srgb, var(--hud-surface-inset) 82%, transparent); border: var(--hud-border-hairline) solid var(--hud-border-subtle); color: var(--hud-edge-glow); font-family: var(--hud-font-label); font-size: var(--hud-text-caption); letter-spacing: .14em; white-space: nowrap; pointer-events: none; animation: pds-nudge 2.4s ease-in-out infinite; }
.pds-preview-wrap.is-turned .pds-preview-hint { opacity: 0; animation: none; transition: opacity .4s ease; }
@keyframes pds-nudge { 0%, 100% { transform: translate(-50%, 0); opacity: .75; } 50% { transform: translate(-50%, -3px); opacity: 1; } }
@media (prefers-reduced-motion: reduce){ .pds-preview-hint { animation: none; } }
.pds-preview { cursor: grab; touch-action: none; width: 100%; flex: 1 1 auto; min-height: 120px; background: radial-gradient(ellipse at 50% 72%, #2a2331 0%, var(--hud-surface-inset) 70%); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); }
.pds-detail { flex: 0 0 auto; min-width: 0; text-align: left; font-family: var(--hud-font-label); font-size: var(--hud-text-xs); color: var(--hud-text-muted); overflow-wrap: anywhere; }
.pds-detail * { min-width: 0; overflow-wrap: anywhere; }
.pds-detail h3 { margin: 0; font-family: var(--hud-font-display); font-size: var(--hud-text-body); color: var(--hud-text); letter-spacing: .06em; }
.pds-detail p { margin: 2px 0 var(--hud-space-1); }
.pds-heroes { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: var(--hud-space-2); align-content: start; overflow: auto; min-height: 0; padding: 2px; }
/* the picker pane fills its height instead of leaving a hole under the maps */
.pds-pane-pick { justify-content: flex-start; }
/* The pane scrolls as one column rather than clipping its last section: the dog list, the map and
   the house rules all have to be reachable, and only the pane knows how much room there is. */
.pds-pane-pick .pds-heroes { flex: 0 0 auto; overflow: visible; }
.pds-maps { display: grid; grid-template-columns: 1fr 1fr; gap: var(--hud-space-2); flex: 0 0 auto; }
.pds-map { display: flex; flex-direction: column; gap: 2px; padding: var(--hud-space-2); background: var(--hud-surface-control); border: var(--hud-border-hairline) dashed var(--hud-border-subtle); border-radius: var(--hud-radius); color: var(--hud-text); font-family: var(--hud-font-label); font-size: var(--hud-text-xs); text-align: left; cursor: pointer; }
.pds-map b { font-family: var(--hud-font-display); font-size: var(--hud-text-sm); letter-spacing: .06em; }
.pds-map small { color: var(--hud-text-muted); }
.pds-map.is-on { border-style: solid; border-color: var(--hud-accent); box-shadow: inset 0 0 0 1px var(--hud-accent); }
.pds-go { font-family: var(--hud-font-display); font-size: clamp(18px, 2.2vw, 28px); line-height: 1; padding: var(--hud-space-3); }
.pds-go small { display: block; margin-top: 4px; font-family: var(--hud-font-label); font-size: var(--hud-text-caption); letter-spacing: .1em; opacity: .75; }
.pds-bottom { display: flex; align-items: center; justify-content: space-between; gap: var(--hud-space-3); flex-wrap: wrap; }
.pds-bottom .pds-keys { display: flex; flex-wrap: wrap; gap: var(--hud-space-1) var(--hud-space-3); margin: 0; padding: 0; list-style: none; font-size: var(--hud-text-xs); color: var(--hud-text-muted); }
.pds-bottom .pds-keys li { display: flex; align-items: center; gap: 4px; }
.pds-bottom .pds-studio { margin: 0; }
.pds-bottom .pds-feedback { margin: 0; font-size: var(--hud-text-xs); color: var(--hud-text-muted); text-underline-offset: 3px; }
@media (max-width: 1040px){
  .pds-main { grid-template-columns: minmax(0, 1fr) minmax(190px, 250px); grid-template-rows: minmax(0, 1fr) auto; }
  .pds-pane-dog { grid-row: 1; grid-column: 1; flex-direction: row; }
  .pds-pane-dog .pds-preview-wrap { flex: 0 0 auto; max-width: 45%; }
  /* side by side, the text column has to be allowed to shrink or it pushes the pane wider than the
     screen: flex items default to min-width:auto, which is the width of their longest word */
  .pds-pane-dog .pds-detail { flex: 1 1 0; min-width: 0; overflow: hidden; }
  .pds-pane-pick { grid-row: 1; grid-column: 2; }
  .pds-pane-go { grid-row: 2; grid-column: 1 / -1; display: grid; grid-template-columns: 1fr 1fr; align-items: start; }
}
@media (max-width: 720px){
  /* A phone gets one column, and that column is far longer than the screen. The shell stays pinned to
     the viewport and scrolls INSIDE itself: it used to be laid out `absolute` with no top or bottom,
     so it grew past the overlay, everything below the fold was clipped away, and the button that
     starts the match could not be reached at all. GO sticks to the bottom edge, so it is one tap away
     however far down the dog list you are. */
  .pds-shell { position: fixed; inset: 0; grid-template-rows: none; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
  .pds-main { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; }
  .pds-pane-dog, .pds-pane-pick, .pds-pane-go { grid-row: auto; grid-column: auto; transform: none; }
  .pds-pane-dog { flex-direction: column; }
  .pds-pane-dog .pds-preview-wrap { max-width: none; height: 180px; }
  .pds-heroes { overflow: visible; }
  .pds-bottom .pds-keys { display: none; }
  .pds-pane-go { position: sticky; bottom: 0; z-index: 2; box-shadow: 0 -8px 18px #0008, var(--hud-shadow); }
}
/* A phone on its side is about 350px tall once the browser bars are in: three grid rows cannot fit
   the panes into that either, so it scrolls there too, with the same sticky GO. */
@media (min-width: 721px) and (max-height: 560px){
  .pds-shell { grid-template-rows: none; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; }
  .pds-main { grid-template-rows: none; }
  .pds-pane-dog .pds-preview-wrap { height: 150px; }
  .pds-pane-go { position: sticky; bottom: 0; z-index: 2; box-shadow: 0 -8px 18px #0008, var(--hud-shadow); }
}
/* Reduced motion: the crooked panes and the wobbling logo are jokes, not information, so they are
   the first thing to go. The game itself still moves — that is the game. */
@media (prefers-reduced-motion: reduce){
  .pds-menu .pds-logo { animation: none; }
  .pds-pane-dog, .pds-pane-pick, .pds-pane-go, .pds-tin { transform: none; }
  .pds-bones-pop { animation-duration: .01ms; }
  .pds-tbtn:active { transform: none; }
}
.pds-kit { font-size: var(--hud-text-caption); letter-spacing: .08em; color: var(--hud-focus); text-transform: uppercase; }
.pds-kit-skill { color: var(--hud-accent); }
.pds-stats { display: flex; align-items: center; gap: 3px; margin-top: 2px; font-size: var(--hud-text-caption); color: var(--hud-text-muted); }
.pds-bar { display: inline-block; width: 26px; height: 5px; margin-right: var(--hud-space-1); background: var(--hud-surface-inset); border-radius: 3px; overflow: hidden; }
.pds-bar s { display: block; height: 100%; background: var(--hud-edge-glow); }
.pds-wallet { margin-left: var(--hud-space-2); padding: 0 var(--hud-space-2); border-radius: var(--hud-radius); background: var(--hud-surface-inset); color: var(--hud-accent); }
/* the shop shows the dog wearing whatever you are pointing at, plus a painted thumbnail per item */
/* The shop is one rack at a time: tabs across the top, the dog and the one button that spends bones
   down the left, the rack itself scrolling on the right. */
.pds-racks { display: flex; flex-wrap: wrap; gap: var(--hud-space-1); margin: var(--hud-space-3) 0 0; }
.pds-rack { flex: 1 1 auto; min-height: var(--hud-control-compact); padding: 0 var(--hud-space-3); background: var(--hud-surface-inset); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); color: var(--hud-text-muted); font-family: var(--hud-font-label); font-size: var(--hud-text-xs); letter-spacing: .14em; text-transform: uppercase; cursor: pointer; }
.pds-rack.is-on { background: var(--hud-surface-raised); border-color: var(--hud-accent); color: var(--hud-text); }
.pds-rack:focus-visible { outline: 2px solid var(--hud-focus); outline-offset: var(--hud-focus-offset); }
.pds-shop-layout { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: var(--hud-space-3); align-items: start; }
.pds-shop-preview { position: sticky; top: 0; display: grid; gap: var(--hud-space-2); }
.pds-shop-preview .pds-preview-wrap { height: 240px; }
/* The name of what is on the dog right now, then the button that commits it. Picking a tile never
   spends anything: this is the only control in the shop that does. */
.pds-shop-pick { font-family: var(--hud-font-display); font-size: var(--hud-text-body); letter-spacing: .06em; color: var(--hud-text); text-align: center; }
.pds-shop-buy { margin-top: 0; }
.pds-shop-buy[data-act="short"], .pds-shop-buy[data-act="worn"] { background: var(--hud-surface-control); border-color: var(--hud-border-subtle); color: var(--hud-text-muted); cursor: default; }
.pds-shop-note { min-height: 1.2em; margin: 0; font-family: var(--hud-font-label); font-size: var(--hud-text-xs); text-align: center; color: var(--hud-accent); opacity: 0; transition: opacity var(--hud-motion-fast) linear; }
.pds-shop-note.is-on { opacity: 1; }
.pds-shop-note.is-bad { color: var(--hud-danger, #ff6b6b); }
.pds-shop { display: grid; gap: var(--hud-space-3); margin: var(--hud-space-3) 0; text-align: left; max-height: 46vh; overflow: auto; }
.pds-thumb { width: 64px; height: 48px; flex: 0 0 auto; border-radius: 4px; background: var(--hud-surface-inset); border: var(--hud-border-hairline) solid var(--hud-border-subtle); }
@media (max-width: 720px){
  .pds-shop-layout { grid-template-columns: 1fr; }
  .pds-shop-preview { position: static; }
  .pds-shop-preview .pds-preview-wrap { height: 180px; }
  .pds-rack { flex: 1 1 40%; }
}
.pds-shop-title { margin: 0 0 var(--hud-space-1); font-family: var(--hud-font-label); font-size: var(--hud-text-xs); letter-spacing: .18em; text-transform: uppercase; color: var(--hud-text-muted); }
.pds-shop-group { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--hud-space-1); }
.pds-shop-group .pds-shop-title { grid-column: 1 / -1; }
.pds-shop-item { position: relative; display: flex; align-items: center; gap: var(--hud-space-2); padding: var(--hud-space-2); background: var(--hud-surface-control); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); color: var(--hud-text); font-family: var(--hud-font-label); font-size: var(--hud-text-sm); text-align: left; cursor: pointer; }
.pds-shop-name { display: grid; gap: 1px; min-width: 0; }
.pds-shop-name b { font-size: var(--hud-text-sm); letter-spacing: .04em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pds-shop-name small { color: var(--hud-accent); font-size: var(--hud-text-xs); letter-spacing: .06em; }
.pds-shop-item.is-owned .pds-shop-name small { color: var(--hud-text-muted); }
/* Picked is where you are looking; worn is what the dog has on. They are different things and the
   shop says so, because the old one only ever showed the second and bought on a single click. */
.pds-shop-item.is-picked { border-color: var(--hud-accent); box-shadow: inset 0 0 0 1px var(--hud-accent); }
.pds-shop-item.is-on { background: var(--hud-surface-raised); }
.pds-shop-flag { position: absolute; top: 4px; right: 6px; color: var(--hud-accent); font-size: var(--hud-text-xs); font-style: normal; }
.pds-shop-item:focus-visible { outline: 2px solid var(--hud-focus); outline-offset: var(--hud-focus-offset); }
.pds-swatch { width: 16px; height: 16px; border-radius: 50%; border: var(--hud-border-hairline) solid var(--hud-border-subtle); }
/* Grooming: the free half of the shop. A labelled rack of swatches per part, big enough to hit with
   a thumb, and the whole rack wraps rather than scrolling sideways on a phone. */
.pds-groom-group { display: grid; gap: var(--hud-space-2); }
.pds-groom-hint { margin: 0; font-size: var(--hud-text-xs); color: var(--hud-text-muted); }
.pds-groom-row { display: flex; align-items: flex-start; gap: var(--hud-space-2); flex-wrap: wrap; }
.pds-groom-label { flex: 0 0 96px; padding-top: 6px; font-family: var(--hud-font-label); font-size: var(--hud-text-xs); letter-spacing: .12em; text-transform: uppercase; color: var(--hud-text-muted); }
.pds-groom-rack { display: flex; flex-wrap: wrap; gap: var(--hud-space-1); flex: 1 1 200px; }
.pds-groom-pick { display: grid; place-items: center; width: 34px; height: 34px; padding: 0; background: var(--hud-surface-control); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); cursor: pointer; }
.pds-groom-pick.is-on { border-color: var(--hud-accent); box-shadow: inset 0 0 0 2px var(--hud-accent); }
.pds-groom-pick:focus-visible { outline: 2px solid var(--hud-focus); outline-offset: var(--hud-focus-offset); }
.pds-groom-swatch { width: 26px; height: 26px; }
@media (max-width: 720px){ .pds-groom-label { flex-basis: 100%; padding-top: 0; } }
/* Just ride sits under WALKIES! as the quieter of the two doors into the park. */
.pds-ride { margin-top: var(--hud-space-2); }
.pds-safe { margin: var(--hud-space-2) 0 0; font-size: var(--hud-text-xs); line-height: 1.45; color: var(--hud-text-muted); }
.pds-swatch-none { background: repeating-linear-gradient(45deg, var(--hud-surface-inset), var(--hud-surface-inset) 3px, var(--hud-surface-raised) 3px, var(--hud-surface-raised) 6px); }
.pds-bones-line { margin-top: var(--hud-space-2); font-family: var(--hud-font-label); font-size: var(--hud-text-sm); color: var(--hud-accent); }
.pds-hero { display: flex; flex-direction: column; gap: 2px; padding: var(--hud-space-2); background: var(--hud-surface-control); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); color: var(--hud-text); font-family: var(--hud-font-label); cursor: pointer; text-align: left; }
.pds-hero b { font-family: var(--hud-font-display); font-size: var(--hud-text-body); letter-spacing: .06em; }
.pds-hero small { color: var(--hud-text-muted); font-size: var(--hud-text-xs); }
.pds-hero.is-on { border-color: var(--hud-accent); box-shadow: inset 0 0 0 1px var(--hud-accent); }
.pds-hero:focus-visible { outline: 2px solid var(--hud-focus); outline-offset: var(--hud-focus-offset); }
.pds-online { margin-top: var(--hud-space-4); padding-top: var(--hud-space-3); border-top: var(--hud-border-hairline) solid var(--hud-border-subtle); }
.pds-online-row { display: flex; gap: var(--hud-space-2); align-items: center; margin-top: var(--hud-space-2); }
.pds-online-row .pds-btn { width: auto; flex: 0 0 auto; margin-top: 0; }
.pds-field { display: flex; align-items: center; gap: var(--hud-space-2); font-family: var(--hud-font-label); font-size: var(--hud-text-sm); color: var(--hud-text-muted); }
.pds-input { flex: 1 1 auto; min-width: 0; min-height: var(--hud-control-compact); padding: 0 var(--hud-space-3); background: var(--hud-surface-inset); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); color: var(--hud-text); font-family: var(--hud-font-label); font-size: var(--hud-text-body); }
.pds-code { flex: 0 1 110px; text-transform: uppercase; letter-spacing: .2em; text-align: center; }
.pds-code-big { font-family: var(--hud-font-display); color: var(--hud-accent); letter-spacing: .25em; }

/* ---- touch controls (phones): a carve stick on the left, a look pad on the right, thumb buttons ---- */
.pds-touch { position: fixed; inset: 0; z-index: 3; pointer-events: none; touch-action: none; }
.pds-touch > * { pointer-events: auto; touch-action: none; }
/* One band of thumb space along the bottom. Everything the HUD shows is kept above it, so nothing
   ever ends up under a hand or off the edge of a phone. */
.pds-touch { --pds-thumb: 190px; --pds-safe-b: max(var(--hud-space-4), env(safe-area-inset-bottom)); }
.pds-look { position: absolute; inset: 0 0 var(--pds-thumb) 0; }
/* the stick is planted wherever the thumb lands inside this quarter, not at a fixed spot */
.pds-stick-zone { position: absolute; left: 0; bottom: 0; width: 46%; height: var(--pds-thumb); }
.pds-stick { position: absolute; left: 96px; top: 50%; width: 132px; height: 132px; margin: -66px 0 0 -66px; border-radius: 50%; background: var(--hud-surface-slot); border: var(--hud-border-width) solid var(--hud-border-subtle); opacity: .45; transition: opacity var(--hud-motion-fast) linear; }
.pds-stick.is-held { opacity: 1; border-color: var(--hud-accent); }
.pds-stick-nub { position: absolute; left: 50%; top: 50%; width: 58px; height: 58px; margin: -29px 0 0 -29px; border-radius: 50%; background: var(--hud-surface-raised); border: var(--hud-border-hairline) solid var(--hud-border); transform: translate(-50%, -50%); }
/* Buttons in a fan, biggest and lowest where the thumb rests. Fixed widths, because a button that
   grows with its label is a button that walks off the side of the screen. */
.pds-buttons { position: absolute; right: max(var(--hud-space-3), env(safe-area-inset-right)); bottom: var(--pds-safe-b); display: grid; grid-template-columns: repeat(3, 62px); grid-template-areas: 'skill skill2 brake' 'dash hop fire'; gap: var(--hud-space-2); align-items: end; justify-items: center; }
.pds-tbtn { position: relative; width: 62px; height: 62px; padding: 0; border-radius: 50%; background: var(--hud-surface-glass); border: var(--hud-border-width) solid var(--hud-border-subtle); color: var(--hud-text); }
/* Weapon and skill names are whatever the dog happens to carry — ESTILINGUE does not fit across a
   circle at ten pixels. Wrap it, squeeze the tracking, and cap it at two lines. */
.pds-tbtn-label { position: absolute; inset: 0; display: grid; place-items: center; padding: 0 5px; font-family: var(--hud-font-label); font-weight: var(--hud-weight-label); font-size: 9px; line-height: 1.02; letter-spacing: 0; text-align: center; overflow: hidden; overflow-wrap: anywhere; hyphens: auto; }
.pds-tbtn:active { background: var(--hud-surface-raised); border-color: var(--hud-accent); transform: scale(.94); }
/* --ring is 0..1 of charge, swept clockwise around the rim */
.pds-tbtn-ring { position: absolute; inset: -3px; border-radius: 50%; background: conic-gradient(var(--hud-accent) calc(var(--ring, 1) * 360deg), transparent 0); opacity: .34; mask: radial-gradient(circle, transparent 0 calc(50% - 4px), #000 calc(50% - 4px)); -webkit-mask: radial-gradient(circle, transparent 0 calc(50% - 4px), #000 calc(50% - 4px)); }
.pds-tbtn.is-ready .pds-tbtn-ring { opacity: .95; }
.pds-tbtn-fire { grid-area: fire; width: 88px; height: 88px; border-color: var(--hud-accent); color: var(--hud-accent); }
.pds-tbtn-fire .pds-tbtn-label { font-size: 10px; padding: 0 8px; }
/* dragging FIRE aims the shot: the button lights up so the thumb knows it is steering, not shooting */
.pds-tbtn-fire.is-aiming { background: var(--hud-surface-raised); box-shadow: 0 0 0 3px var(--hud-accent), 0 0 18px var(--hud-accent); }
.pds-tbtn-hop, .pds-tbtn-jump { grid-area: hop; width: 72px; height: 72px; }
.pds-tbtn-brake { grid-area: brake; }
.pds-tbtn-skill { grid-area: skill; border-color: var(--hud-resource); color: var(--hud-resource); }
.pds-tbtn-skill .pds-tbtn-ring { background: conic-gradient(var(--hud-resource) calc(var(--ring, 1) * 360deg), transparent 0); }
.pds-tbtn-bark { position: fixed; left: max(16px, env(safe-area-inset-left)); bottom: calc(var(--pds-safe-b) + var(--pds-thumb, 180px)); width: 54px; height: 54px; }
.pds-tbtn-skill2 { grid-area: skill2; border-color: var(--hud-resource); color: var(--hud-resource); }
.pds-tbtn[hidden] { display: none; }
.pds-tbtn-dash { grid-area: dash; border-color: var(--hud-edge-glow); color: var(--hud-edge-glow); }
.pds-tbtn-dash .pds-tbtn-ring { background: conic-gradient(var(--hud-edge-glow) calc(var(--ring, 1) * 360deg), transparent 0); }
.pds-tbtn-pause { position: absolute; right: max(var(--hud-space-3), env(safe-area-inset-right)); top: max(var(--hud-space-3), env(safe-area-inset-top)); width: 46px; height: 46px; }
/* Portrait works, but this game wants a wide screen: say so once, over the menu.
   This rule used to sit directly after a stray closing brace left behind by a deleted media block,
   and Chrome threw it away as part of recovering from that brace — so ''turn your phone sideways''
   was on screen on every desktop, under a 1440px-wide menu. */
.pds-rotate { display: none; }
@media (pointer: coarse) and (orientation: portrait){
  .pds-rotate { display: block; margin-top: var(--hud-space-2); color: var(--hud-accent); font-size: var(--hud-text-sm); }
  /* portrait has the height to spare and less width: give the thumbs more room, stack the fan tighter */
  .pds-touch { --pds-thumb: 210px; }
  .pds-buttons { grid-template-columns: repeat(3, 56px); }
  .pds-tbtn { width: 56px; height: 56px; }
  .pds-tbtn-fire { width: 78px; height: 78px; }
  .pds-tbtn-hop, .pds-tbtn-jump { width: 64px; height: 64px; }
}
/* landscape on a short screen: everything shrinks so the fan still clears the bottom edge */
@media (max-height: 420px){
  .pds-touch { --pds-thumb: 150px; }
  .pds-stick { width: 104px; height: 104px; margin: -52px 0 0 -52px; }
  .pds-buttons { grid-template-columns: repeat(3, 52px); gap: var(--hud-space-1); }
  .pds-tbtn { width: 52px; height: 52px; }
  .pds-tbtn-fire { width: 70px; height: 70px; }
  .pds-tbtn-hop, .pds-tbtn-jump { width: 58px; height: 58px; }
  .pds-tbtn-bark { width: 46px; height: 46px; }
}

/* ---- in-match HUD ---- */
.pds-timer { position: absolute; top: var(--hud-space-3); left: 50%; transform: translateX(-50%); padding: var(--hud-space-1) var(--hud-space-4); background: var(--hud-surface-glass); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); font-family: var(--hud-font-display); font-weight: var(--hud-weight-strong); font-size: var(--hud-title-lg); line-height: 1.1; letter-spacing: .04em; }
.pds-timer.is-big { font-size: calc(var(--hud-title-xl) * 1.6); background: none; border: none; text-shadow: var(--hud-title-shadow); }
.pds-timer.is-low { color: var(--hud-danger); }
.pds-scores { position: absolute; top: var(--hud-space-3); left: var(--hud-space-3); display: flex; flex-direction: column; gap: 2px; min-width: 190px; }
.pds-score { display: flex; justify-content: space-between; gap: var(--hud-space-3); padding: 2px var(--hud-space-2); background: var(--hud-surface-glass); border-left: 3px solid var(--hud-border-subtle); font-family: var(--hud-font-label); font-weight: var(--hud-weight-label); font-size: var(--hud-text-sm); letter-spacing: var(--hud-tracking-label); }
.pds-score.is-me { border-left-color: var(--hud-accent); color: var(--hud-accent); }
.pds-score-value { font-family: var(--hud-font-display); font-size: var(--hud-text-count); line-height: 1; }
.pds-feed { position: absolute; top: var(--hud-space-3); right: var(--hud-space-3); display: flex; flex-direction: column; gap: 2px; align-items: flex-end; }
.pds-kill { display: flex; align-items: center; gap: var(--hud-space-2); padding: 2px var(--hud-space-2); background: var(--hud-surface-glass); border-right: 3px solid var(--hud-edge-glow); font-family: var(--hud-font-label); font-size: var(--hud-text-sm); transition: opacity var(--hud-motion-fast) linear; }
.pds-kill.is-out { opacity: 0; }
.pds-kill-by { color: var(--hud-accent); }
.pds-kill-icon { color: var(--hud-edge-glow); }
.pds-kill-self, .pds-kill-tag { color: var(--hud-text-muted); }
.pds-announce { position: absolute; top: 24%; left: 50%; transform: translate(-50%, -6px); font-family: var(--hud-font-display); font-weight: var(--hud-weight-strong); font-size: var(--hud-title-xl); letter-spacing: .06em; text-shadow: var(--hud-title-shadow); opacity: 0; transition: opacity 140ms linear, transform 140ms ease-out; }
.pds-announce.is-on { opacity: 1; transform: translate(-50%, 0); }
/* Fire and skill sit in one centred row on the bottom edge, the same height as each other. The fill
   is a wash behind the label rather than a bar the label fights with: `mix-blend-mode: difference`
   over a moving fill is what made the weapon's name an unreadable smudge. */
.pds-actions { position: absolute; bottom: var(--hud-space-4); left: 50%; transform: translateX(-50%); display: flex; gap: var(--hud-space-2); }
.pds-slot { position: relative; height: var(--hud-control-comfortable); padding: 0 var(--hud-space-3); display: grid; align-content: center; justify-items: center; gap: 1px; background: var(--hud-surface-slot); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); overflow: hidden; }
.pds-cooldown { min-width: 168px; }
.pds-skill { min-width: 108px; }
.pds-dash .pds-skill-fill { background: var(--hud-edge-glow); }
.pds-dash.is-ready { border-color: var(--hud-edge-glow); }
.pds-dash.is-ready .pds-skill-fill { background: var(--hud-edge-glow); }
.pds-dash.is-ready .pds-slot-name { color: var(--hud-edge-glow); }
.pds-slot-key { position: relative; font-family: var(--hud-font-label); font-weight: var(--hud-weight-label); font-size: var(--hud-text-xs); letter-spacing: .16em; color: var(--hud-text-muted); }
.pds-slot-name { position: relative; font-family: var(--hud-font-display); font-weight: var(--hud-weight-strong); font-size: var(--hud-text-count); line-height: 1; letter-spacing: .04em; color: var(--hud-text); }
.pds-cooldown-fill { position: absolute; inset: 0; background: var(--hud-text-muted); opacity: .2; transform-origin: left center; transform: scaleX(0); }
.pds-cooldown.is-ready { border-color: var(--hud-accent); }
.pds-cooldown.is-ready .pds-cooldown-fill { background: var(--hud-accent); opacity: .28; }
.pds-cooldown.is-ready .pds-slot-name { color: var(--hud-accent); }
.pds-hud.is-hit .pds-crosshair::before, .pds-hud.is-hit .pds-crosshair::after { background: var(--hud-edge-glow); box-shadow: 0 0 6px var(--hud-edge-glow); }
/* class skill charge, trick readout and the bone tin */
.pds-skill-fill { position: absolute; inset: 0; background: var(--hud-resource); transform-origin: bottom center; transform: scaleY(0); opacity: .35; }
.pds-skill.is-ready { border-color: var(--hud-accent); }
.pds-skill.is-ready .pds-skill-fill { background: var(--hud-accent); opacity: .28; }
.pds-skill.is-ready .pds-slot-name { color: var(--hud-accent); }
.pds-trick { position: absolute; top: 34%; left: 50%; transform: translateX(-50%); font-family: var(--hud-font-display); font-weight: var(--hud-weight-strong); font-size: var(--hud-title-lg); letter-spacing: .04em; color: var(--hud-focus); text-shadow: var(--hud-title-shadow); opacity: 0; transition: opacity 120ms linear; }
.pds-trick.is-on { opacity: 1; }
.pds-trick.is-landed { color: var(--hud-accent); }
.pds-trick.is-bail { color: var(--hud-danger); }
.pds-bones { position: absolute; bottom: var(--hud-space-3); right: var(--hud-space-3); padding: var(--hud-space-1) var(--hud-space-3); background: var(--hud-surface-glass); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); font-family: var(--hud-font-label); font-weight: var(--hud-weight-label); color: var(--hud-accent); }
.pds-bones-pop { margin-left: var(--hud-space-2); color: var(--hud-status-online); animation: pds-pop 1.2s ease-out forwards; }
/* the always-there control legend, and the card that explains the game over the countdown */
/* 10px in the corner of a 1440px screen is a wall of small print nobody reads. It is bigger now, and
   it lets go: each row dims the first time that control is used and the panel fades once they all have. */
.pds-legend { position: absolute; left: var(--hud-space-3); bottom: var(--hud-space-3); display: grid; gap: 2px; padding: var(--hud-space-2); background: var(--hud-surface-glass); border-left: 3px solid var(--hud-border-subtle); border-radius: var(--hud-radius); font-family: var(--hud-font-label); font-size: var(--hud-text-sm); opacity: .82; transition: opacity 600ms linear; }
.pds-legend.is-off { opacity: 0; }
.pds-legend-row { display: flex; gap: var(--hud-space-2); align-items: baseline; transition: opacity 400ms linear; }
.pds-legend-row.is-used { opacity: .35; }
.pds-legend-key { min-width: 76px; color: var(--hud-accent); letter-spacing: .06em; }
.pds-legend-what { color: var(--hud-text-muted); }
.pds-intro { position: absolute; left: 50%; top: 34%; transform: translate(-50%, 8px); width: min(560px, 86vw); padding: var(--hud-space-4); background: var(--hud-surface-glass); border: var(--hud-border-width) solid var(--hud-accent); border-radius: var(--hud-radius); box-shadow: var(--hud-shadow); text-align: center; opacity: 0; pointer-events: none; transition: opacity 180ms linear, transform 180ms ease-out; }
.pds-intro.is-on { opacity: 1; transform: translate(-50%, 0); }
.pds-intro-title { font-family: var(--hud-font-display); font-weight: var(--hud-weight-strong); font-size: var(--hud-title-lg); letter-spacing: .06em; color: var(--hud-accent); }
.pds-intro-line { margin-top: var(--hud-space-2); font-family: var(--hud-font-label); font-size: var(--hud-text-body); color: var(--hud-text); }
@media (pointer: coarse), (max-width: 720px){
  .pds-legend { bottom: calc(max(var(--hud-space-4), env(safe-area-inset-bottom)) + 150px); font-size: var(--hud-text-caption); }
  .pds-legend-key { min-width: 48px; }
  .pds-intro { top: 24%; padding: var(--hud-space-3); }
  .pds-intro-title { font-size: var(--hud-text-count); }
  .pds-intro-line { font-size: var(--hud-text-sm); }
}
@keyframes pds-pop { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-14px); } }
.pds-results { display: flex; flex-direction: column; gap: var(--hud-space-1); margin: var(--hud-space-4) 0; }
/* points for a hit, stacked just right of the crosshair so the number lands where you are looking */
.pds-points { position: absolute; top: 50%; left: 50%; margin: -34px 0 0 30px; display: grid; gap: 2px; pointer-events: none; }
.pds-point { font-family: var(--hud-font-display); font-weight: var(--hud-weight-strong); font-size: var(--hud-text-count); letter-spacing: .04em; color: var(--hud-accent); text-shadow: var(--hud-title-shadow); white-space: nowrap; animation: pds-pop 1s ease-out forwards; }
.pds-point.is-big { font-size: var(--hud-title-lg); color: var(--hud-status-online); }
@media (prefers-reduced-motion: reduce){ .pds-point { animation-name: pds-fade; } }
/* being hit: a wedge on a ring round the crosshair pointing at the dog that did it, their name and weapon
   under it, and the edges of the screen flash — the three things that say WHY you are suddenly flying */
.pds-struck { position: absolute; left: 50%; top: 50%; width: 0; height: 0; opacity: 0; pointer-events: none; }
.pds-struck.is-on { animation: pds-struck 1.3s ease-out forwards; }
.pds-struck-arrow { position: absolute; left: -16px; top: -13px; width: 0; height: 0; border-left: 16px solid transparent; border-right: 16px solid transparent; border-bottom: 26px solid var(--hud-danger); filter: drop-shadow(0 0 6px var(--hud-danger)); transform-origin: 16px 13px; }
.pds-struck-text { position: absolute; left: 0; top: 46px; transform: translateX(-50%); white-space: nowrap; font-family: var(--hud-font-display); font-weight: var(--hud-weight-strong); font-size: var(--hud-text-count); letter-spacing: .05em; color: var(--hud-danger); text-shadow: var(--hud-title-shadow); }
@keyframes pds-struck { 0% { opacity: 0; } 8% { opacity: 1; } 70% { opacity: 1; } 100% { opacity: 0; } }
.pds-hud::after { content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 240ms linear; background: radial-gradient(ellipse at center, transparent 55%, color-mix(in srgb, var(--hud-danger) 55%, transparent) 100%); }
.pds-hud.is-struck::after { opacity: 1; transition: none; }
@media (prefers-reduced-motion: reduce){ .pds-hud.is-struck::after { opacity: .5; } }
/* hype: under the clock, out of the way until there is some */
.pds-hype { position: absolute; top: 64px; left: 50%; transform: translateX(-50%); display: grid; gap: 3px; justify-items: center; opacity: 0; transition: opacity 200ms linear; pointer-events: none; }
.pds-hype.is-on { opacity: 1; }
.pds-hype-label { font-family: var(--hud-font-display); font-weight: var(--hud-weight-strong); font-size: var(--hud-text-count); letter-spacing: .06em; color: var(--hud-accent); text-shadow: var(--hud-title-shadow); }
.pds-hype.is-hot .pds-hype-label { color: var(--hud-edge-glow); }
.pds-hype.is-max .pds-hype-label { color: var(--hud-danger); }
.pds-hype-bar { width: 132px; height: 5px; border-radius: 3px; background: var(--hud-surface-inset); overflow: hidden; }
.pds-hype-fill { height: 100%; background: var(--hud-accent); transform-origin: left center; }
.pds-hype.is-hot .pds-hype-fill { background: var(--hud-edge-glow); }
.pds-hype.is-max .pds-hype-fill { background: var(--hud-danger); }
.pds-hype.is-bump .pds-hype-label { animation: pds-bump 260ms ease-out; }
@keyframes pds-bump { from { transform: scale(1.35); } to { transform: scale(1); } }
@media (prefers-reduced-motion: reduce){ .pds-hype.is-bump .pds-hype-label { animation: none; } }
/* the heat's three jobs: quiet, top right under the feed; the same rows sit on the results card */
.pds-missions { position: absolute; right: var(--hud-space-3); top: 132px; display: grid; gap: 2px; padding: var(--hud-space-2); background: var(--hud-surface-glass); border-right: 3px solid var(--hud-border-subtle); border-radius: var(--hud-radius); font-family: var(--hud-font-label); font-size: var(--hud-text-sm); opacity: .85; pointer-events: none; }
.pds-missions:empty { display: none; }
.pds-missions.is-card { position: static; opacity: 1; margin: var(--hud-space-2) 0; border-right: 0; background: var(--hud-surface-inset); }
.pds-mission { display: flex; gap: var(--hud-space-2); align-items: baseline; }
.pds-mission-tick { min-width: 34px; color: var(--hud-text-muted); letter-spacing: .04em; }
.pds-mission-text { flex: 1; text-align: left; }
.pds-mission-reward { color: var(--hud-accent); }
.pds-mission.is-done { opacity: .55; }
.pds-mission.is-done .pds-mission-tick { color: var(--hud-status-online); }
.pds-mission.is-close .pds-mission-tick { color: var(--hud-accent); }
@media (max-width: 760px){ .pds-missions:not(.is-card) { display: none; } }
@keyframes pds-fade { 0%, 70% { opacity: 1; } 100% { opacity: 0; } }
.pds-result { display: flex; justify-content: space-between; align-items: center; gap: var(--hud-space-3); padding: var(--hud-space-2) var(--hud-space-3); background: var(--hud-surface-inset); border-left: 3px solid var(--hud-border-subtle); font-family: var(--hud-font-label); font-weight: var(--hud-weight-label); text-align: left; }
.pds-result-left { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pds-award { font-size: var(--hud-text-xs); font-weight: var(--hud-weight-regular); color: var(--hud-accent); letter-spacing: var(--hud-tracking-label); }
.pds-card-wide { width: min(720px, 100%); }
.pds-result.is-me { border-left-color: var(--hud-accent); color: var(--hud-accent); }

.pds-overlay { position: fixed; inset: 0; z-index:5; display: grid; place-items: center; padding: var(--hud-space-4); background: radial-gradient(ellipse at center, #0b0a0d99, #0b0a0de6); }
.pds-card { width: min(460px, 100%); padding: var(--hud-space-6); background: var(--hud-panel-fill); border: var(--hud-border-width) solid var(--hud-border); border-radius: var(--hud-radius); box-shadow: var(--hud-shadow); text-align: center; }
.pds-logo { margin: 0; font-family: var(--hud-font-display); font-weight: var(--hud-weight-strong); font-size: var(--hud-title-xl); line-height: var(--hud-leading-title); letter-spacing: .02em; color: var(--hud-text); text-shadow: var(--hud-title-shadow); }
.pds-logo span { display: block; color: var(--hud-edge-glow); font-size: calc(var(--hud-title-xl) * 1.2); }
.pds-title { margin: 0 0 var(--hud-space-4); font-family: var(--hud-font-display); font-size: var(--hud-title-lg); }
.pds-tagline { margin: var(--hud-space-2) 0 var(--hud-space-4); color: var(--hud-text-muted); }
.pds-hint { margin: var(--hud-space-3) 0 0; font-size: var(--hud-text-sm); color: var(--hud-text-muted); }
.pds-keys { list-style: none; margin: 0 0 var(--hud-space-4); padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: var(--hud-space-1) var(--hud-space-4); text-align: left; font-size: var(--hud-text-sm); }
.pds-keys li { display: flex; align-items: center; gap: var(--hud-space-1); }
.pds-keys span { margin-left: var(--hud-space-1); color: var(--hud-text-muted); }
kbd { display: inline-block; min-width: 18px; padding: 1px 6px; border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-bottom-width: 2px; border-radius: var(--hud-radius); background: var(--hud-surface-control); font-family: var(--hud-font-label); font-weight: var(--hud-weight-label); font-size: var(--hud-text-xs); text-align: center; color: var(--hud-text); }
.pds-btn { width: 100%; min-height: var(--hud-control-comfortable); padding: 0 var(--hud-space-4); border: var(--hud-border-hairline) solid var(--hud-border); border-radius: var(--hud-radius); background: var(--hud-surface-control); color: var(--hud-text); font-family: var(--hud-font-label); font-weight: var(--hud-weight-label); font-size: var(--hud-text-body); letter-spacing: var(--hud-tracking-label); text-transform: uppercase; cursor: pointer; }
.pds-btn + .pds-btn { margin-top: var(--hud-space-2); }
.pds-primary { background: var(--hud-accent); border-color: var(--hud-launch-edge); color: var(--hud-text-on-accent); }
.pds-primary:hover { background: var(--hud-accent-hover); }
.pds-btn:disabled { opacity: var(--hud-disabled-opacity); cursor: not-allowed; }
.pds-btn:focus-visible, .pds-setting input:focus-visible { outline: 2px solid var(--hud-focus); outline-offset: var(--hud-focus-offset); }
.pds-setting { display: flex; align-items: center; justify-content: space-between; gap: var(--hud-space-3); margin: 0 0 var(--hud-space-3); font-size: var(--hud-text-body); text-align: left; }
.pds-studio { display: flex; align-items: center; justify-content: center; gap: var(--hud-space-2); margin-top: var(--hud-space-4); font-size: var(--hud-text-xs); color: var(--hud-text-muted); }
.pds-studio img { width: 22px; height: 22px; }
/* the map, seen from above, drawn from the arena's own triangles */
.pds-mapshot { width: 100%; height: auto; min-height: 92px; flex: 0 1 auto; max-height: 26vh; object-fit: contain; aspect-ratio: 7 / 5; background: var(--hud-surface-inset); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); }
.pds-howto { margin: 0; padding-left: 1.2em; display: grid; gap: 2px; font-family: var(--hud-font-label); font-size: var(--hud-text-xs); color: var(--hud-text-muted); text-align: left; }
.pds-howto b { color: var(--hud-accent); }
/* the weapon picker: same card as the maps, three across */
.pds-weapons { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: var(--hud-space-2); flex: 0 0 auto; }
.pds-weapon { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: var(--hud-space-2); background: var(--hud-surface-control); border: var(--hud-border-hairline) dashed var(--hud-border-subtle); border-radius: var(--hud-radius); color: var(--hud-text); font-family: var(--hud-font-label); font-size: var(--hud-text-caption); text-align: left; cursor: pointer; }
.pds-weapon b { font-family: var(--hud-font-display); font-size: var(--hud-text-xs); letter-spacing: .06em; overflow-wrap: anywhere; }
.pds-weapon small { color: var(--hud-text-muted); overflow-wrap: anywhere; }
.pds-weapon.is-on { border-style: solid; border-color: var(--hud-accent); box-shadow: inset 0 0 0 1px var(--hud-accent); }
/* the hall of fame: personal bests, filling the space under the buttons */
.pds-records { display: grid; gap: 2px; margin: 0; min-width: 0; font-family: var(--hud-font-label); font-size: var(--hud-text-xs); }
.pds-record { display: flex; justify-content: space-between; align-items: baseline; gap: var(--hud-space-2); padding: 2px var(--hud-space-1); border-bottom: var(--hud-border-hairline) solid var(--hud-border-subtle); }
.pds-record dt { min-width: 0; color: var(--hud-text-muted); overflow-wrap: anywhere; }
.pds-record dd { margin: 0; flex: 0 0 auto; font-family: var(--hud-font-display); color: var(--hud-accent); }
.pds-record.is-empty dd { color: var(--hud-text-muted); opacity: .6; }
.pds-records-none { padding: var(--hud-space-2) var(--hud-space-1); color: var(--hud-text-muted); }
.pds-record-new { margin-left: var(--hud-space-2); color: var(--hud-status-online); font-family: var(--hud-font-label); font-size: var(--hud-text-caption); }

.pds-studio { text-decoration: none; }
.pds-studio:hover { color: var(--hud-text); text-decoration: underline; text-underline-offset: 3px; }

/* ---- pointer and selection -------------------------------------------------------------------
   Nothing here is a document. Dragging the mouse to aim, mashing a thumb button or double-clicking
   a dog tile used to paint a blue text selection across the HUD, so selection is off everywhere
   except the two fields you actually type into. The pointer is the shared one from Space Wars
   (assets/shared/ui/cursors), and over the canvas it becomes the crosshair, same as the MOBA. */
body, body * { -webkit-user-select: none !important; user-select: none !important; -webkit-touch-callout: none; }
body input, body textarea, body [contenteditable="true"] { -webkit-user-select: text !important; user-select: text !important; }
body, body * { cursor: url('shared/ui/cursors/hud-pointer.png') 4 4, pointer; }
.pds-stage, .pds-stage canvas { cursor: url('shared/ui/cursors/target-cursor.png') 16 16, crosshair; }
/* while the pointer is locked the crosshair is drawn in the HUD, so the OS one is just in the way */
body:has(.pds-hud:not([hidden])) .pds-stage canvas { cursor: none; }
input, textarea { cursor: text !important; }

/* ---- the rolled name tag, the welcome present, and the results card's next heat ----------------
   A game for children has no free-text field in it (js/game/names.js), so the name tag is a chip
   with a dice next to it rather than an input. The results card grew a countdown and a park picker,
   because the next heat starting on its own is what keeps a session going. */
.pds-nametag { display: flex; align-items: center; gap: var(--hud-space-2); flex: 1 1 auto; min-width: 0; }
.pds-nametag b { flex: 1 1 auto; min-width: 0; min-height: var(--hud-control-compact); display: flex; align-items: center; padding: 0 var(--hud-space-3); background: var(--hud-surface-inset); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); color: var(--hud-text); font-family: var(--hud-font-display); font-size: var(--hud-text-body); letter-spacing: .04em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pds-roll { flex: 0 0 auto; min-height: var(--hud-control-compact); min-width: var(--hud-control-compact); padding: 0 var(--hud-space-2); background: var(--hud-surface-control); border: var(--hud-border-hairline) solid var(--hud-border-subtle); border-radius: var(--hud-radius); font-size: var(--hud-text-body); cursor: pointer; }
.pds-roll:hover, .pds-roll:focus-visible { border-color: var(--hud-accent); }
.pds-gift { margin: var(--hud-space-2) 0 0; font-family: var(--hud-font-label); font-size: var(--hud-text-sm); color: var(--hud-accent); }
.pds-bones-line.is-daily { color: var(--hud-text); opacity: .85; }
.pds-next-label { margin-top: var(--hud-space-3); font-family: var(--hud-font-label); font-size: var(--hud-text-xs); letter-spacing: .12em; text-transform: uppercase; color: var(--hud-text-muted); }
.pds-next-maps { display: flex; gap: var(--hud-space-2); margin-top: var(--hud-space-1); }
.pds-map-mini { flex: 1 1 0; align-items: center; text-align: center; }
.pds-btn.pds-quiet { background: none; border-style: dashed; }

/* the auto-aim reticle: whichever dog the phone's fire button is pointing at */
.pds-lock { position: absolute; left: 0; top: 0; width: 0; height: 0; pointer-events: none; }
.pds-lock-ring { position: absolute; left: -26px; top: -26px; width: 52px; height: 52px; border: 2px solid var(--hud-focus); border-radius: 50%; opacity: .75; transition: transform 90ms ease-out, border-color 90ms linear; transform: scale(1.25); }
.pds-lock.is-ready .pds-lock-ring { border-color: var(--hud-accent); opacity: 1; transform: scale(1); }
.pds-lock-name { position: absolute; left: 0; top: 30px; transform: translateX(-50%); white-space: nowrap; font-family: var(--hud-font-label); font-size: var(--hud-text-caption); color: var(--hud-accent); text-shadow: 0 1px 2px #000; }

/* ---- phone HUD ---------------------------------------------------------------------------------
   Last in the file on purpose. These override the in-match HUD rules above at the same specificity,
   so they only win by coming after them — when this block sat earlier, `bottom` from the base rule
   won and stretched the bone tin into a 738px column down the side of the screen. */
@media (pointer: coarse), (max-width: 720px){
  /* One column down the left, in the order you need it, none of it overlapping: score, then the
     kill feed under it, then the thumb band. The bone tin and pause share the top right, and the
     control legend is gone entirely — the buttons are labelled, so it was only covering the park. */
  .pds-actions, .pds-legend, .pds-aim-name { display: none; }
  .pds-scores { top: max(var(--hud-space-2), env(safe-area-inset-top)); left: max(var(--hud-space-2), env(safe-area-inset-left)); min-width: 0; max-width: 44vw; font-size: var(--hud-text-caption); }
  .pds-score { padding: 1px var(--hud-space-1); gap: var(--hud-space-2); }
  .pds-score-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .pds-score-value { font-size: var(--hud-text-sm); }
  .pds-timer { top: max(var(--hud-space-2), env(safe-area-inset-top)); font-size: var(--hud-text-count); padding: 2px var(--hud-space-2); }
  /* the feed sits UNDER the scoreboard rather than across it: six dogs means six rows, and the
     scoreboard is as tall as it gets, so the feed is pinned to the bottom of the safe area instead */
  .pds-feed { top: auto; bottom: calc(var(--pds-thumb) + var(--hud-space-2)); right: auto; left: max(var(--hud-space-2), env(safe-area-inset-left)); align-items: flex-start; max-width: 58vw; }
  .pds-kill { font-size: var(--hud-text-caption); border-right: 0; border-left: 3px solid var(--hud-edge-glow); }
  /* the tin tucks under the pause button, both out of the fan's way */
  .pds-bones { top: calc(max(var(--hud-space-2), env(safe-area-inset-top)) + 54px); bottom: auto; right: max(var(--hud-space-2), env(safe-area-inset-right)); padding: 2px var(--hud-space-2); font-size: var(--hud-text-caption); }
  .pds-trick { top: 20%; font-size: var(--hud-text-count); width: 84vw; text-align: center; }
  /* the crosshair is dead weight when the fire button aims for you */
  .pds-crosshair { opacity: .25; }
}

/* Match readouts form three quiet groups around an unobstructed aiming area. */
.pds-scores{padding:var(--hud-space-1);min-width:200px;max-width:30vw;gap:0;}
.pds-score{background:none;padding:var(--hud-space-1) var(--hud-space-2);border-bottom:var(--hud-border-hairline) solid var(--hud-border-subtle);}
.pds-score:last-child{border-bottom:0;}
.pds-score.is-me{background:var(--hud-surface-raised);}
.pds-score-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.pds-score-value{font-variant-numeric:tabular-nums;flex:none;}
.pds-timer{min-width:100px;text-align:center;}
.pds-slot{min-width:88px;}
.pds-slot-key{letter-spacing:var(--hud-tracking-label);}
.pds-missions{opacity:1;max-width:30vw;}
.pds-bones.hud-readout{color:var(--hud-accent);}
.pds-standings{display:contents;}
@media(pointer:coarse),(max-width:720px){
 .pds-standings{display:grid;position:absolute;left:max(var(--hud-space-2),env(safe-area-inset-left));top:max(var(--hud-space-2),env(safe-area-inset-top));width:min(220px,32vw);gap:var(--hud-space-1);}
 .pds-standings .pds-scores{position:static;width:100%;max-width:none;box-sizing:border-box;}
 .pds-standings .pds-feed{position:static;max-width:100%;}
 .pds-standings .pds-kill{max-width:100%;}
}
@media(max-height:420px){.pds-standings .pds-kill:not(:first-child){display:none;}}
/* Size grid tracks to the actual thumb buttons: the larger fire circle used
   to overflow a 56px column into Jump and the right safe area. */
.pds-buttons{grid-template-columns:62px 72px 88px;}
@media(pointer:coarse) and (orientation:portrait){.pds-buttons{grid-template-columns:64px 78px;grid-template-areas:'skill skill2' 'dash brake' 'hop fire';}}
@media(max-height:420px){.pds-buttons{grid-template-columns:52px 58px 70px;}}
@media(pointer:coarse),(max-width:720px){
 .pds-scores{min-width:0;width:30vw;left:max(var(--hud-space-2),env(safe-area-inset-left));top:max(var(--hud-space-2),env(safe-area-inset-top));}
 .pds-score{font-size:var(--hud-text-xs);padding:var(--hud-space-1);gap:var(--hud-space-1);}
 .pds-score-value{font-size:var(--hud-text-body);}
 .pds-timer{min-width:0;padding:var(--hud-space-1) var(--hud-space-2);font-size:var(--hud-space-6);top:max(var(--hud-space-2),env(safe-area-inset-top));}
 .pds-missions{font-size:var(--hud-text-xs);right:max(var(--hud-space-2),env(safe-area-inset-right));}
}
.pds-tbtn-fire .pds-tbtn-label{padding-inline:var(--hud-space-1);font-size:var(--hud-text-caption);}

/* Keep touch actions in two thumb zones. The centre belongs to the dog. */
.pds-touch{--pds-thumb:190px;--pds-safe-b:max(16px,env(safe-area-inset-bottom));}
.pds-buttons{grid-template-columns:64px 80px;grid-template-areas:'dash skill' 'hop fire';gap:10px;align-items:center;}
.pds-buttons.has-skill2{grid-template-areas:'. skill2' 'dash skill' 'hop fire';}
.pds-touch .pds-tbtn{width:64px;height:64px;background:var(--hud-surface-glass);}
.pds-touch .pds-tbtn-fire{width:80px;height:80px;}
.pds-touch .pds-tbtn-jump{width:64px;height:64px;}
.pds-touch .pds-tbtn-label{font-size:var(--hud-text-sm);line-height:1.15;padding:0 2px;overflow-wrap:normal;hyphens:none;}
.pds-touch .pds-tbtn-fire .pds-tbtn-label{inset:12px 0 30px;font-size:var(--hud-text-body);}
.pds-tbtn-detail{position:absolute;left:6px;right:6px;bottom:18px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-align:center;font-family:var(--hud-font-label);font-size:var(--hud-text-xs);color:var(--hud-text-muted);pointer-events:none;}
.pds-tbtn-ring{mask:radial-gradient(closest-side,transparent calc(100% - 3px),#000 0);-webkit-mask:radial-gradient(closest-side,transparent calc(100% - 3px),#000 0);}
.pds-touch .pds-tbtn-pause{width:44px;height:44px;}
.pds-touch-utility{position:absolute;left:max(16px,env(safe-area-inset-left));bottom:calc(var(--pds-safe-b) + 128px);display:flex;gap:10px;}
.pds-touch-utility .pds-tbtn{position:relative;left:auto;bottom:auto;width:48px;height:48px;}
.pds-touch-utility .pds-tbtn-label{font-size:var(--hud-text-xs);}
.pds-stick{left:50%;top:50%;width:112px;height:112px;margin:-56px 0 0 -56px;}
.pds-stick-zone{left:max(8px,env(safe-area-inset-left));bottom:var(--pds-safe-b);width:136px;height:116px;}
.pds-stick-nub{width:46px;height:46px;margin:0;}
.pds-score-rank{display:none;}
/* Let mobile menu panes take their actual height instead of overlapping the
   dog preview when a picker is scrolled into view. Keep just Play pinned. */
@media(max-width:720px),(max-height:560px){
 .pds-shell{display:block;overflow-y:auto;padding-bottom:calc(84px + env(safe-area-inset-bottom));}
 .pds-top{margin-bottom:var(--hud-space-3);}
 .pds-main{align-items:start;}
 .pds-pane-pick{overflow:visible;}
 .pds-pane-go{position:static;transform:none;}
 .pds-main>.pds-pane{min-height:max-content;}
 #pdsPlay{position:fixed;z-index:6;bottom:max(12px,env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);width:min(380px,calc(100vw - 24px));min-height:54px;margin:0;box-shadow:var(--hud-shadow);}
 .pds-bottom{margin-top:var(--hud-space-3);}
}
@media(max-width:720px){
 .pds-main{display:flex;flex-direction:column;}
 .pds-main>.pds-pane{width:100%;box-sizing:border-box;flex-shrink:0;}
 .pds-top{grid-template-columns:1fr auto;}
 .pds-top .pds-tagline{grid-row:2;grid-column:1 / -1;}
}
@media(pointer:coarse),(max-width:720px){
 .pds-standings{width:min(200px,calc(50vw - 50px));grid-template-columns:minmax(0,1fr);gap:4px;}
 .pds-standings .pds-scores,.pds-standings .pds-feed{min-width:0;}
 .pds-score:not(.is-me):not(.is-leader){display:none;}
 .pds-score{font-size:var(--hud-text-sm);min-height:22px;gap:4px;}
 .pds-score-rank{display:block;font-size:var(--hud-text-xs);color:var(--hud-text-muted);flex:none;}
 .pds-score-name{flex:1;min-width:0;}
 .pds-score-value{font-size:18px;}
 .pds-bones{font-size:var(--hud-text-sm);}
 .pds-timer{font-size:26px;}
 .pds-feed .pds-kill{font-size:var(--hud-text-xs);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
 .pds-feed .pds-kill:not(:first-child){display:none;}
 .pds-hype{top:54px;}
 .pds-hype-label{font-size:var(--hud-text-sm);}
 .pds-hype-bar{width:76px;height:3px;}
 .pds-announce{top:30%;width:88vw;font-size:24px;text-align:center;}
 .pds-trick{top:24%;font-size:20px;}
 .is-learning .pds-hype,.is-learning .pds-announce,.is-learning .pds-trick{visibility:hidden;}
}
@media(max-height:500px){
 .pds-touch{--pds-thumb:156px;--pds-safe-b:max(10px,env(safe-area-inset-bottom));}
 .pds-buttons{grid-template-columns:60px 72px;gap:8px;}
 .pds-touch .pds-tbtn{width:60px;height:60px;}
 .pds-touch .pds-tbtn-fire{width:72px;height:72px;}
 .pds-touch .pds-tbtn-jump{width:56px;height:56px;}
 .pds-touch .pds-tbtn-pause{width:44px;height:44px;}
 .pds-touch-utility{bottom:calc(var(--pds-safe-b) + 106px);}
 .pds-touch-utility .pds-tbtn{width:44px;height:44px;}
 .pds-stick-zone{width:116px;height:100px;}
 .pds-stick{width:96px;height:96px;margin:-48px 0 0 -48px;}
 .pds-stick-nub{width:40px;height:40px;}
 .pds-tbtn-detail{bottom:14px;}
 .pds-touch .pds-tbtn-fire .pds-tbtn-label{inset:10px 0 26px;}
}

/* Teach one action at a time, with the ramp and crosshair left in view. */
.pds-coach{position:absolute;z-index:4;top:78px;left:50%;transform:translateX(-50%);width:min(380px,calc(100vw - 32px));box-sizing:border-box;padding:var(--hud-space-3);background:var(--hud-surface-glass);border:var(--hud-border-width) solid var(--hud-accent);border-radius:var(--hud-radius);}
.pds-coach[hidden]{display:none;}
.pds-coach-label{font-family:var(--hud-font-label);font-size:var(--hud-text-sm);letter-spacing:var(--hud-tracking-label);color:var(--hud-accent);}
.pds-coach-title{margin-top:var(--hud-space-1);font-family:var(--hud-font-display);font-size:calc(var(--hud-text-body) * 1.4);font-weight:var(--hud-weight-strong);color:var(--hud-text);}
.pds-coach-detail{margin-top:var(--hud-space-1);font-family:var(--hud-font-label);font-size:var(--hud-text-body);line-height:1.45;color:var(--hud-text);}
.pds-coach-skip{display:block;margin:var(--hud-space-2) 0 0 auto;padding:var(--hud-space-1) var(--hud-space-2);min-height:32px;border:var(--hud-border-hairline) solid var(--hud-border-subtle);border-radius:var(--hud-radius);background:var(--hud-surface-raised);color:var(--hud-text-muted);font:inherit;font-size:var(--hud-text-sm);cursor:pointer;pointer-events:auto;}
.pds-coach-skip:focus-visible{outline:2px solid var(--hud-accent);outline-offset:2px;}
.is-learning .pds-legend,.is-learning .pds-intro,.is-learning .pds-missions:not(.is-card){display:none;}
@media(pointer:coarse),(max-width:720px){
 .is-learning .pds-score:not(.is-me):not(.is-leader){display:none;}
 .is-learning .pds-feed{display:none;}
 .pds-coach{top:calc(max(var(--hud-space-2),env(safe-area-inset-top)) + 82px);}
 .pds-coach-skip{min-height:44px;}
}
@media(max-height:500px){
 .pds-coach{top:58px;width:min(340px,46vw);padding:var(--hud-space-2);}
 .pds-coach-label{font-size:var(--hud-text-xs);}
 .pds-coach-title{font-size:var(--hud-text-body);}
 .pds-coach-detail{font-size:var(--hud-text-sm);line-height:1.3;}
 .pds-coach-copy{padding-right:88px;}
 .pds-coach-title{line-height:1.15;}
 .pds-coach-skip{position:absolute;top:var(--hud-space-2);right:var(--hud-space-2);width:80px;margin:0;}
}
