:root{
  --bg:#07090e;
  --bg2:#0d1118;
  --line:#1b212e;
  --txt:#e8edf6;
  --dim:#6d7891;
  --cyan:#2de2c8;
  --blue:#4aa8ff;
  --amber:#ffb02e;
  --red:#ff3b5c;
  --accent:var(--cyan);
  --r:14px;
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{height:100%}
body{
  margin:0;
  background:
    radial-gradient(900px 600px at 50% -10%, #121a28 0%, transparent 60%),
    var(--bg);
  color:var(--txt);
  font:500 16px/1.4 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  overflow:hidden;
  overscroll-behavior:none;
  user-select:none;
}

.app{
  height:100%;
  display:flex;flex-direction:column;
  max-width:560px;margin:0 auto;
  padding:env(safe-area-inset-top) 16px env(safe-area-inset-bottom);
}

/* ---------- top bar ---------- */
.bar{display:flex;align-items:center;gap:12px;padding:14px 2px 6px}
.brand{
  margin:0;font-size:15px;letter-spacing:.42em;font-weight:800;
  color:var(--dim);
}
.status{
  margin-left:auto;display:flex;align-items:center;gap:7px;
  font:600 11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim);
}
.dot{
  width:8px;height:8px;border-radius:50%;background:#394256;
  box-shadow:0 0 0 0 currentColor;
}
body[data-state="live"] .dot{background:var(--cyan);animation:pulse 2s infinite}
body[data-state="wait"] .dot{background:var(--amber);animation:pulse 1s infinite}
body[data-state="error"] .dot{background:var(--red)}
body[data-state="demo"] .dot{background:var(--blue);animation:pulse 2s infinite}
@keyframes pulse{0%{opacity:1}50%{opacity:.25}100%{opacity:1}}

.icon-btn{
  background:var(--bg2);border:1px solid var(--line);color:var(--dim);
  width:34px;height:34px;border-radius:10px;font-size:14px;cursor:pointer;
}
.icon-btn:active{transform:scale(.94)}

/* ---------- stage ---------- */
/* space-evenly puts the leftover height into the gaps instead of letting one
   block stretch into something that looks broken on tall screens */
.stage{
  flex:1;display:flex;flex-direction:column;justify-content:space-evenly;
  gap:10px;min-height:0;padding-bottom:10px;
}

/* ---------- pickers ---------- */
.pickers{flex:0 0 auto;display:flex;flex-direction:column;gap:6px;align-items:center}
.seg{
  display:inline-flex;gap:2px;padding:3px;
  background:var(--bg2);border:1px solid var(--line);border-radius:11px;
}
.seg button{
  background:none;border:0;border-radius:8px;cursor:pointer;
  padding:6px 11px;color:var(--dim);
  font:700 10px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
}
.seg button:hover{color:var(--txt)}
.seg .dec{margin-left:4px;box-shadow:inset 1px 0 0 var(--line);border-radius:0 8px 8px 0;color:var(--amber)}
.seg button.on{background:#1b2333;color:var(--txt);box-shadow:inset 0 0 0 1px #2a3346}

/* ---------- gauge ---------- */
/* fixed-height box; each face's viewBox letterboxes inside it (meet), so the
   readout lives in the SVG and stays centred whatever the aspect ratio */
.dial{
  position:relative;flex:0 0 auto;align-self:center;
  width:100%;max-width:400px;height:clamp(170px,34vh,300px);
}
/* wide faces need less height; the round ones keep the full box */
.dial[data-face="digital"],.dial[data-face="hud"]{height:clamp(130px,24vh,210px)}
.face{display:none;width:100%;height:100%;overflow:visible}
.face.on{display:block}

.arc-track{fill:none;stroke:#141a26;stroke-width:16;stroke-linecap:round}
.arc-live{
  fill:none;stroke:url(#arcGrad);stroke-width:16;stroke-linecap:round;
  stroke-dasharray:612.6;stroke-dashoffset:612.6;
  filter:drop-shadow(0 0 7px rgba(45,226,200,.35));
  transition:stroke-dashoffset .12s linear;
}
.arc-limit{
  fill:none;stroke:var(--red);stroke-width:3;stroke-linecap:butt;opacity:.55;
  stroke-dasharray:0 612.6;stroke-dashoffset:0;
}
.tick{stroke:#2a3346;stroke-width:2;stroke-linecap:round}
.tick.major{stroke:#64718c;stroke-width:2.5}
.tlabel{
  fill:var(--dim);font:700 11px var(--mono);text-anchor:middle;dominant-baseline:middle;
}
.peak{stroke:var(--amber);stroke-width:3;stroke-linecap:round;opacity:.85}
/* a CSS drop-shadow, not an SVG <filter>: a vertical line has a zero-width
   bbox, so an objectBoundingBox filter region collapses and renders nothing */
.needle{
  stroke:var(--txt);stroke-width:3.5;stroke-linecap:round;
  filter:drop-shadow(0 0 6px rgba(232,237,246,.45));
}
.needle-tail{stroke:#3c4660;stroke-width:5;stroke-linecap:round}
.hub{fill:#0f141d;stroke:#2a3346;stroke-width:2}
.hub-in{fill:var(--accent)}

.speed{
  fill:var(--txt);
  font:800 45px var(--mono);
  letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;
  text-anchor:middle;
  pointer-events:none;
  filter:drop-shadow(0 0 14px rgba(74,168,255,.3));
}
.unit{cursor:pointer}
.unit text{
  fill:var(--dim);font:700 11px var(--mono);letter-spacing:.2em;text-anchor:middle;
}
.unit:hover text,.unit:focus-visible text{fill:var(--txt)}

.over .speed{fill:var(--red);filter:drop-shadow(0 0 16px rgba(255,59,92,.55))}

/* ---------- analog face ---------- */
.an-track{fill:none;stroke:#1d2431;stroke-width:3}
.an-limit{fill:none;stroke:var(--red);stroke-width:5;opacity:.8;stroke-dasharray:0 650.3}
.analog .tick{stroke:#6b7488;stroke-width:1.3}
.analog .tick.major{stroke:#eef1f7;stroke-width:3}
.analog .tlabel{fill:#dfe4ee;font:700 15px var(--mono)}
.an-unit{fill:var(--dim);font:700 10px var(--mono);letter-spacing:.2em;text-anchor:middle}
.an-speed{
  fill:var(--txt);font:800 26px var(--mono);text-anchor:middle;
  font-variant-numeric:tabular-nums;
}
.an-odo-box{fill:#020305;stroke:#2a3346}
.an-odo{fill:#e8edf6;font:700 14px var(--mono);letter-spacing:.06em;text-anchor:end;font-variant-numeric:tabular-nums}
.an-odo-u{fill:var(--dim);font:700 8px var(--mono);letter-spacing:.1em;text-transform:uppercase}
.an-needle{fill:#ff4a2e;filter:drop-shadow(0 0 5px rgba(255,74,46,.6))}
.over .an-speed{fill:var(--red)}

/* ---------- digital face ---------- */
.dg-panel{fill:#04070b;stroke:var(--line);stroke-width:1.5}
.dg-seg{fill:#121925}
.dg-seg.lim{fill:#2a121a}
.dg-seg.on.g{fill:var(--cyan)}
.dg-seg.on.a{fill:var(--amber)}
.dg-seg.on.r{fill:var(--red)}
.dg-ghost,.dg-speed{
  font:800 92px var(--mono);text-anchor:end;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;
}
.dg-ghost{fill:#0b1119}
.dg-speed{fill:var(--cyan);filter:drop-shadow(0 0 10px rgba(45,226,200,.45))}
.over .dg-speed{fill:var(--red);filter:drop-shadow(0 0 10px rgba(255,59,92,.55))}
.dg-unit{fill:var(--dim);font:700 12px var(--mono);letter-spacing:.14em}
.dg-rule{stroke:#141a26;stroke-width:1}
.dg-meta{fill:var(--dim);font:700 10px var(--mono);letter-spacing:.16em}
.dg-val{fill:var(--txt);font-size:13px;letter-spacing:.02em}

/* ---------- HUD face ---------- */
.hud{cursor:pointer}
.mirror .hud{transform:scaleX(-1)}
.hud-speed{
  fill:#5dffb4;font:800 124px var(--mono);text-anchor:middle;letter-spacing:-.04em;
  font-variant-numeric:tabular-nums;filter:drop-shadow(0 0 12px rgba(93,255,180,.5));
}
.over .hud-speed{fill:var(--red);filter:drop-shadow(0 0 12px rgba(255,59,92,.6))}
.hud-unit{fill:#5dffb4;opacity:.6;font:700 13px var(--mono);letter-spacing:.3em;text-anchor:middle;text-transform:uppercase}
.hud-track{fill:#101820}
.hud-bar{fill:#5dffb4}
.over .hud-bar{fill:var(--red)}

/* ---------- sparkline ---------- */
.spark-wrap{position:relative;flex:0 0 auto;height:62px;padding-top:12px}
.spark{width:100%;height:50px;display:block}
.spark-line{fill:none;stroke:var(--blue);stroke-width:1.6;vector-effect:non-scaling-stroke}
.spark-fill{fill:rgba(74,168,255,.10);stroke:none}
.spark-cap{
  position:absolute;right:2px;top:0;
  font:600 9px var(--mono);letter-spacing:.14em;color:#3d4659;text-transform:uppercase;
}
.spark-cap.left{right:auto;left:2px;color:#49536b}

/* ---------- stats ---------- */
.stats{
  flex:0 0 auto;
  display:grid;grid-template-columns:repeat(4,1fr);gap:7px;
}
.stat{
  background:linear-gradient(180deg,#0f141d,#0b0f16);
  border:1px solid var(--line);border-radius:var(--r);
  padding:9px 6px;text-align:center;overflow:hidden;
}
.stat b{
  display:block;font:700 17px/1.1 var(--mono);font-variant-numeric:tabular-nums;
  white-space:nowrap;
}
.stat i{
  display:block;margin-top:3px;font:600 9px/1 system-ui;font-style:normal;
  letter-spacing:.1em;text-transform:uppercase;color:var(--dim);
}
.stat u{text-decoration:none}
.hdg{display:flex;align-items:center;justify-content:center;gap:4px}
#compass{width:13px;height:13px;fill:var(--blue);transition:transform .25s ease-out}

/* ---------- controls ---------- */
.controls{flex:0 0 auto;display:flex;gap:8px;align-items:stretch}
.btn{
  flex:1;padding:14px 10px;border-radius:var(--r);cursor:pointer;
  background:var(--bg2);border:1px solid var(--line);color:var(--txt);
  font:700 13px/1 system-ui;letter-spacing:.1em;text-transform:uppercase;
}
.btn:active{transform:scale(.98)}
.btn.primary{
  background:linear-gradient(180deg,#2de2c8,#13b59e);
  border-color:#2de2c8;color:#04140f;
}
body[data-state="live"] .btn.primary,
body[data-state="demo"] .btn.primary,
body[data-state="wait"] .btn.primary{
  background:linear-gradient(180deg,#2a3346,#1b212e);border-color:#39455e;color:var(--txt);
}
.btn.snap{flex:0 0 52px;padding:0;display:grid;place-items:center}
.btn.snap svg{width:22px;height:22px;fill:none;stroke:var(--txt);stroke-width:1.7;stroke-linejoin:round}
.btn.snap:disabled{opacity:.5;cursor:progress}
.limit{
  display:flex;flex-direction:column;justify-content:center;gap:3px;
  background:var(--bg2);border:1px solid var(--line);border-radius:var(--r);
  padding:6px 10px;
}
.limit span{font:600 8px/1 system-ui;letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.limit input{
  width:48px;background:none;border:0;color:var(--txt);
  font:700 16px var(--mono);text-align:center;padding:0;
}
.limit input:focus{outline:none;color:var(--amber)}

/* ---------- misc ---------- */
.hint{
  flex:0 0 auto;margin:0;text-align:center;
  font:500 10px/1.5 system-ui;color:#434c61;
}
kbd{
  font:600 9px var(--mono);background:#121823;border:1px solid var(--line);
  border-radius:4px;padding:1px 4px;color:var(--dim);
}

.flash{
  position:fixed;inset:0;pointer-events:none;opacity:0;
  box-shadow:inset 0 0 120px 20px rgba(255,59,92,.55);
}
body.over .flash{animation:flash 1s infinite}
@keyframes flash{0%,100%{opacity:0}50%{opacity:1}}

.shutter{position:fixed;inset:0;pointer-events:none;background:#fff;opacity:0}
.shutter.go{animation:shutter .35s ease-out}
@keyframes shutter{0%{opacity:.7}100%{opacity:0}}

.toast{
  position:fixed;left:50%;bottom:calc(16px + env(safe-area-inset-bottom));
  transform:translate(-50%,24px);
  background:#151b27;border:1px solid var(--line);border-radius:10px;
  padding:10px 16px;font:600 12px/1.3 system-ui;max-width:80vw;text-align:center;
  opacity:0;pointer-events:none;transition:.22s;
}
.toast.show{opacity:1;transform:translate(-50%,0)}

/* short / landscape screens */
@media (max-height:620px){
  .bar{padding:8px 2px 2px}
  .pickers{flex-direction:row;justify-content:center}
  .seg button{padding:5px 9px}
  .dial,.dial[data-face]{height:clamp(120px,38vh,240px)}
  .spark-wrap{height:40px;padding-top:8px}
  .spark{height:32px}
  .hint{display:none}
  .stats{grid-template-columns:repeat(8,1fr)}
  .stat b{font-size:14px}
  .stat i{font-size:8px}
}
@media (max-height:440px){
  .spark-wrap{display:none}
  .btn{padding:10px}
}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
}
