/* BoBo Sensor Lab - black + red, translucent glass, no external assets (works offline). */
:root {
  --bg: #050506;
  --red: #ff2d3d;
  --red-soft: #ff7a85;
  --red-dim: #7a1020;
  --amber: #ff9f0a;
  --ok: #32d74b;
  --text: #f5f5f7;
  --text-2: rgba(245, 245, 247, .62);
  --text-3: rgba(245, 245, 247, .38);
  --glass: rgba(20, 20, 23, .62);
  --glass-edge: rgba(255, 255, 255, .10);
  --hair: rgba(255, 255, 255, .07);
  --radius: 22px;
  --gap: 12px;
  --pad: 14px;
  --bar-h: 54px;
  --ease: cubic-bezier(.22, 1, .36, 1);
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Inter", system-ui, "Segoe UI", sans-serif;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--text); font: 15px/1.45 var(--font); -webkit-font-smoothing: antialiased; }
body {
  min-height: 100vh; overflow-x: hidden;
  padding: calc(var(--bar-h) + var(--gap) * 2 + env(safe-area-inset-top)) var(--gap) calc(var(--gap) + env(safe-area-inset-bottom));
  background:
    radial-gradient(900px 520px at 85% -10%, rgba(255, 45, 61, .16), transparent 60%),
    radial-gradient(700px 480px at -5% 105%, rgba(255, 45, 61, .08), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}
h1, h2, p { margin: 0; }
button { font: inherit; color: inherit; }
canvas { display: block; width: 100%; height: 100%; }
[hidden] { display: none !important; }
.muted { color: var(--text-2); }
.small { font-size: .78rem; }

.glass {
  background: var(--glass);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  backdrop-filter: blur(24px) saturate(160%);
  border: 1px solid var(--glass-edge);
  border-top-color: rgba(255, 255, 255, .20);
  border-radius: var(--radius);
  box-shadow: 0 18px 50px rgba(0, 0, 0, .55);
}

/* ---------- top bar ---------- */
.bar {
  position: fixed; z-index: 10; top: calc(var(--gap) + env(safe-area-inset-top)); left: var(--gap); right: var(--gap);
  height: var(--bar-h); padding: 0 var(--pad);
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
}
.brand { display: flex; align-items: center; gap: 14px; min-width: 0; }
.brand > div { min-width: 0; }
.brand img.logo { width: 36px; height: 36px; object-fit: contain; flex: none; }
.brand h1 { font-size: 1.12rem; font-weight: 600; letter-spacing: -.02em; white-space: nowrap; }
.brand h1 b { color: var(--red); font-weight: 700; }
.brand p { font-size: .74rem; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dot { width: 12px; height: 12px; border-radius: 50%; background: var(--text-3); flex: none; transition: background .3s, box-shadow .3s; }
.dot.live { background: var(--red); box-shadow: 0 0 18px var(--red); animation: pulse 2.6s ease-in-out infinite; }
.dot.demo { background: var(--amber); box-shadow: 0 0 14px rgba(255, 159, 10, .6); }
@keyframes pulse { 50% { opacity: .5; box-shadow: 0 0 6px var(--red); } }

.health { display: flex; gap: 6px; flex-wrap: nowrap; overflow: hidden; }
.h-chip {
  display: flex; align-items: center; gap: 6px; padding: 5px 10px; border-radius: 999px;
  background: rgba(255, 255, 255, .06); font-size: .72rem; font-weight: 600; color: var(--text-2); white-space: nowrap;
  transition: background .25s, color .25s;
}
.h-chip i { width: 7px; height: 7px; border-radius: 50%; background: var(--text-3); transition: background .25s, box-shadow .25s; }
.h-chip.ok { color: var(--text); }
.h-chip.ok i { background: var(--ok); box-shadow: 0 0 8px var(--ok); }
.h-chip.bad { color: var(--red-soft); background: rgba(255, 45, 61, .12); }
.h-chip.bad i { background: var(--red); box-shadow: 0 0 8px var(--red); }

.bar-right { display: flex; align-items: center; gap: 8px; flex: none; }
.pill { padding: 5px 12px; border-radius: 999px; font-size: .72rem; font-weight: 700; letter-spacing: .02em; background: rgba(255, 255, 255, .08); color: var(--text-2); white-space: nowrap; transition: background .25s, color .25s; }
.pill-red, .pill.warn { background: rgba(255, 45, 61, .16); color: var(--red); }
.pill.ok { background: rgba(50, 215, 75, .16); color: var(--ok); }
.pill.amber { background: rgba(255, 159, 10, .16); color: var(--amber); }

.btn {
  font-weight: 600; font-size: .85rem; background: rgba(255, 255, 255, .09); border: 1px solid var(--glass-edge);
  padding: 9px 16px; border-radius: 999px; cursor: pointer; white-space: nowrap;
  transition: transform 120ms var(--ease), background 200ms;
}
a.btn { display: inline-flex; align-items: center; color: var(--text); text-decoration: none; }
.btn:hover { background: rgba(255, 255, 255, .15); }
.btn:active { transform: scale(.96); }
.btn-red { background: var(--red); border-color: transparent; box-shadow: 0 6px 24px rgba(255, 45, 61, .35); }
.btn-red:hover { background: #ff4452; }

/* ---------- connection sheet ---------- */
.sheet {
  position: fixed; z-index: 20; top: calc(var(--bar-h) + var(--gap) * 2 + env(safe-area-inset-top)); right: var(--gap);
  width: min(380px, calc(100vw - var(--gap) * 2)); padding: var(--pad); display: grid; gap: 12px;
  transform-origin: top right; animation: sheetIn 360ms var(--ease);
}
@keyframes sheetIn { from { opacity: 0; transform: scale(.94) translateY(-6px); filter: blur(8px); } }
.sheet h2 { font-size: 1.05rem; letter-spacing: -.01em; }
.field { display: grid; gap: 6px; font-size: .78rem; color: var(--text-2); }
.field input {
  font: inherit; font-family: var(--mono); font-size: .95rem; color: var(--text); background: rgba(0, 0, 0, .4);
  border: 1px solid var(--glass-edge); border-radius: 12px; padding: 11px 13px; outline: none;
}
.field input:focus { border-color: var(--red); box-shadow: 0 0 0 3px rgba(255, 45, 61, .2); }
.row { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- grid: everything on ONE screen (desktop / tablet landscape) ---------- */
.grid {
  display: grid; gap: var(--gap); max-width: 2200px; margin: 0 auto;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, .7fr);
  height: calc(100vh - var(--bar-h) - var(--gap) * 3 - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  height: calc(100dvh - var(--bar-h) - var(--gap) * 3 - env(safe-area-inset-top) - env(safe-area-inset-bottom));
}
.card { padding: var(--pad); display: flex; flex-direction: column; gap: 8px; min-width: 0; min-height: 0; overflow: hidden; animation: cardIn 640ms var(--ease) both; transition: opacity .4s, filter .4s; }
.card:nth-child(2) { animation-delay: 60ms; } .card:nth-child(3) { animation-delay: 120ms; } .card:nth-child(4) { animation-delay: 180ms; }
.card:nth-child(5) { animation-delay: 240ms; } .card:nth-child(6) { animation-delay: 300ms; } .card:nth-child(7) { animation-delay: 360ms; }
@keyframes cardIn { from { opacity: 0; transform: translateY(14px) scale(.985); filter: blur(6px); } }
.card > header { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 26px; flex: none; }
.card h2 { font-size: .95rem; font-weight: 600; letter-spacing: -.015em; white-space: nowrap; }
.card h2 .part { font-size: .68rem; font-weight: 500; color: var(--text-3); margin-left: 8px; letter-spacing: .01em; }
.cap { position: absolute; left: 0; right: 0; bottom: 0; font-size: .6rem; color: var(--text-3); text-align: center; letter-spacing: .04em; text-transform: uppercase; pointer-events: none; }
.card.stale { opacity: .55; filter: saturate(.4); }
.fill { position: relative; flex: 1 1 0; min-height: 0; min-width: 0; }
.fill > canvas { position: absolute; inset: 0; }

.c-radar { grid-column: 1 / span 4; grid-row: 1; }
.c-ultra { grid-column: 5 / span 3; grid-row: 1; }
.c-cam   { grid-column: 8 / span 3; grid-row: 1; }
.c-drive { grid-column: 11 / span 2; grid-row: 1; }
.c-chart { grid-column: 1 / span 8; grid-row: 2; }
.c-imu   { grid-column: 9 / span 4; grid-row: 2; }
.c-gps   { grid-column: 1 / span 4; grid-row: 3; }
.c-rover { grid-column: 5 / span 4; grid-row: 3; }
.c-nav   { grid-column: 9 / span 4; grid-row: 3; }
.c-3d    { grid-column: 1 / span 12; grid-row: 4; }
.model3d { display: block; flex: 1 1 0; min-height: 0; width: 100%; border-radius: 12px; background: #050506; }
/* the 3D row exists only where the card is shown (demo copy); the Sensor Lab on the robot keeps its three rows */
.grid:has(.c-3d:not([hidden])) {          /* demo: the page scrolls, every row has its own height */
  height: auto;
  grid-template-rows: var(--demo-row-1, 300px) var(--demo-row-2, 280px) var(--demo-row-3, 300px) var(--demo-row-4, 460px);
}

.chips { display: flex; align-items: center; gap: 8px; }
.chip { font-size: .7rem; font-weight: 600; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--glass-edge); background: rgba(255, 255, 255, .05); color: var(--text-2); cursor: pointer; transition: transform 120ms var(--ease), background .2s, color .2s; }
.chip:active { transform: scale(.95); }
.chip.on { background: rgba(255, 45, 61, .16); color: var(--red-soft); border-color: rgba(255, 45, 61, .35); }
.chip-val { font-family: var(--mono); font-size: .76rem; color: var(--red-soft); white-space: nowrap; }
.seg { display: inline-flex; padding: 3px; border-radius: 999px; background: rgba(255, 255, 255, .06); }
.seg button { border: 0; background: transparent; padding: 3px 10px; border-radius: 999px; font-size: .7rem; font-weight: 600; color: var(--text-2); cursor: pointer; transition: background .2s, color .2s; }
.seg button.on { background: rgba(255, 255, 255, .16); color: var(--text); }

.stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; align-items: end; flex: none; }
.stats > div { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.stats b { font-size: 1.05rem; font-weight: 600; letter-spacing: -.02em; font-variant-numeric: tabular-nums; white-space: nowrap; }
.stats span { font-size: .6rem; color: var(--text-3); text-transform: uppercase; letter-spacing: .05em; white-space: nowrap; }

/* radar: stats in a column next to the scan */
.rb { display: flex; gap: 12px; flex: 1 1 0; min-height: 0; }
.rb .stats { grid-template-columns: 1fr; align-content: center; gap: 14px; width: 92px; flex: none; }
.rb .stats b { font-size: 1.15rem; }

/* ultrasonic list */
.ulist { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; flex: none; }
.ulist li { display: grid; grid-template-columns: 70px 1fr 50px 56px; align-items: center; gap: 8px; font-size: .74rem; }
.ulist .nm { color: var(--text-2); font-weight: 600; font-size: .62rem; letter-spacing: .03em; white-space: nowrap; }
.ulist .bar-t { height: 6px; border-radius: 99px; background: rgba(255, 255, 255, .07); overflow: hidden; }
.ulist .bar-t i { display: block; height: 100%; width: 0; border-radius: 99px; background: linear-gradient(90deg, var(--red), var(--red-soft)); }
.ulist .vl { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.ulist .sp { height: 16px; }
.ulist canvas { width: 100%; height: 100%; }

/* chart */
.legend { display: flex; flex-wrap: wrap; gap: 6px; flex: none; }
.lg { display: flex; align-items: center; gap: 7px; padding: 4px 10px; border-radius: 999px; background: rgba(255, 255, 255, .05); font-size: .7rem; cursor: pointer; color: var(--text-2); user-select: none; transition: transform 120ms var(--ease), background .2s, opacity .2s; }
.lg:active { transform: scale(.96); }
.lg i { width: 8px; height: 8px; border-radius: 50%; background: var(--c); box-shadow: 0 0 8px var(--c); }
.lg b { font-family: var(--mono); font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; min-width: 4.6em; text-align: right; }
.lg.off { opacity: .4; } .lg.off i { box-shadow: none; background: var(--text-3); }

/* imu */
.imu-grid { display: grid; grid-template-columns: 1fr 1fr 1.25fr; gap: 10px; flex: 1 1 0; min-height: 0; }
.imu-cell { position: relative; min-height: 0; min-width: 0; }
.imu-cell canvas { position: absolute; inset: 0; }
.imu-acc canvas { bottom: 14px; }
.cal { display: flex !important; flex-direction: row !important; gap: 6px; align-items: flex-end; }
.cal div { flex: 1; display: flex; flex-direction: column; gap: 3px; align-items: stretch; min-width: 0; }
.cal em { font-style: normal; font-size: .56rem; color: var(--text-3); text-align: center; letter-spacing: .05em; }
.cal u { display: flex; gap: 2px; height: 7px; text-decoration: none; }
.cal u s { flex: 1; border-radius: 2px; background: rgba(255, 255, 255, .1); transition: background .3s; }
.cal u s.f { background: var(--red); }

/* gps */
.gps-top { display: grid; grid-template-columns: 84px minmax(0, 1fr) minmax(0, 1fr); gap: 12px; align-items: stretch; flex: 1 1 0; min-height: 0; }
.sat-ring { position: relative; align-self: center; width: 84px; height: 84px; }
.sat-ring canvas { position: absolute; inset: 0; }
.sat-num { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; }
.sat-num b { font-size: 1.5rem; font-weight: 600; letter-spacing: -.04em; line-height: 1; font-variant-numeric: tabular-nums; }
.sat-num span { font-size: .56rem; color: var(--text-3); text-transform: uppercase; letter-spacing: .06em; }
.gps-info { display: flex; flex-direction: column; justify-content: center; gap: 6px; min-width: 0; }
.meter-head { display: flex; justify-content: space-between; font-size: .62rem; color: var(--text-3); text-transform: uppercase; letter-spacing: .06em; margin-bottom: 4px; }
.meter-head b { color: var(--text); font-family: var(--mono); font-size: .78rem; }
.meter-bar { height: 6px; border-radius: 99px; background: rgba(255, 255, 255, .07); overflow: hidden; }
.meter-bar i { display: block; height: 100%; width: 0; border-radius: 99px; background: linear-gradient(90deg, var(--red), var(--amber)); }
.kv { display: grid; grid-template-columns: auto 1fr; gap: 1px 10px; margin: 0; font-size: .72rem; }
.kv dt { color: var(--text-3); } .kv dd { margin: 0; font-family: var(--mono); text-align: right; font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trail-wrap { position: relative; border-radius: 12px; background: rgba(0, 0, 0, .35); border: 1px solid var(--hair); overflow: hidden; min-height: 0; }
.trail-wrap canvas { position: absolute; inset: 0; }

/* camera */
.cam-view { border-radius: 12px; overflow: hidden; background: #000; border: 1px solid var(--hair); }
.cam-view img, .cam-view canvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.zones { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; flex: none; }
.zone { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 6px; }
.zone .zb { height: 6px; border-radius: 99px; background: rgba(255, 255, 255, .08); position: relative; overflow: hidden; grid-column: 1 / -1; order: 3; }
.zone .zb i { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: linear-gradient(90deg, var(--red), var(--red-soft)); }
.zone b { font-family: var(--mono); font-size: .72rem; font-variant-numeric: tabular-nums; text-align: right; }
.zone span { font-size: .6rem; color: var(--text-3); text-transform: uppercase; letter-spacing: .05em; }

/* drive pad */
.c-drive { gap: 8px; }
.dpad { flex: 1 1 0; min-height: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: repeat(3, minmax(0, 1fr)); gap: 6px; aspect-ratio: 1; align-self: center; max-width: 100%; }
.dp { display: grid; place-items: center; border: 1px solid var(--glass-edge); border-radius: 16px; background: rgba(255, 255, 255, .07); cursor: pointer; padding: 0; touch-action: none; user-select: none; -webkit-user-select: none; transition: transform 90ms var(--ease), background .15s, box-shadow .15s, opacity .2s; }
.dp svg { width: 46%; height: 46%; fill: var(--text); pointer-events: none; }
.dp.up { grid-area: 1 / 2; } .dp.left { grid-area: 2 / 1; } .dp.stop { grid-area: 2 / 2; } .dp.right { grid-area: 2 / 3; } .dp.down { grid-area: 3 / 2; }
.dp.stop i { width: 34%; height: 34%; border-radius: 6px; background: var(--red); pointer-events: none; }
.dp.active { background: var(--red); transform: scale(.94); box-shadow: 0 0 22px rgba(255, 45, 61, .55); }
.dp.active svg { fill: #fff; }
.c-drive:not(.armed) .dp:not(.stop) { opacity: .4; }
.speed { display: flex; align-items: center; gap: 8px; font-size: .68rem; color: var(--text-3); text-transform: uppercase; letter-spacing: .05em; flex: none; }
.speed input { flex: 1; accent-color: var(--red); min-width: 0; }
.speed b { font-family: var(--mono); color: var(--text); text-transform: none; letter-spacing: 0; }
#driveMsg { flex: none; font-size: .66rem; line-height: 1.3; }
.c-drive.armed #btnArm { background: rgba(255, 45, 61, .2); color: var(--red-soft); border-color: rgba(255, 45, 61, .45); }

/* rover */
.rover-grid { display: grid; grid-template-columns: 110px minmax(0, 1fr) minmax(0, 1fr); gap: 12px; align-items: stretch; flex: 1 1 0; min-height: 0; }
.gauge { position: relative; align-self: center; width: 100px; height: 100px; }
.gauge canvas { position: absolute; inset: 0; }
.gauge-num { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; }
.gauge-num b { font-size: 1.05rem; font-weight: 600; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.gauge-num span { font-size: .56rem; color: var(--text-3); text-transform: uppercase; letter-spacing: .06em; }
.wheels { position: relative; min-height: 0; }
.wheels canvas { position: absolute; inset: 0; }
.rtt { display: flex; flex-direction: column; gap: 6px; justify-content: center; min-height: 0; }
.spark-row { display: flex; justify-content: space-between; font-size: .62rem; color: var(--text-3); text-transform: uppercase; letter-spacing: .05em; }
.spark-row b { color: var(--text); font-family: var(--mono); text-transform: none; letter-spacing: 0; font-size: .76rem; }
.spark { flex: 1; min-height: 28px; position: relative; }
.spark canvas { position: absolute; inset: 0; }

/* nav */
.tiles { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, 1fr); gap: 8px; flex: 1 1 0; min-height: 0; }
.tile { padding: 6px 10px; border-radius: 12px; background: rgba(255, 255, 255, .05); display: flex; flex-direction: column; justify-content: center; gap: 1px; min-width: 0; }
.tile b { font-size: 1.15rem; font-weight: 600; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.tile span { font-size: .58rem; color: var(--text-3); text-transform: uppercase; letter-spacing: .05em; white-space: nowrap; }
.fault { padding: 6px 12px; border-radius: 10px; background: rgba(255, 45, 61, .14); color: var(--red-soft); font-size: .76rem; flex: none; }

/* ---------- compact heights (laptops 768 px) ---------- */
@media (max-height: 820px) {
  :root { --pad: 12px; --gap: 10px; --bar-h: 50px; }
  .stats b { font-size: .95rem; } .tile b { font-size: 1rem; }
  .gauge { width: 84px; height: 84px; } .rover-grid { grid-template-columns: 94px minmax(0, 1fr) minmax(0, 1fr); }
  .sat-ring { width: 72px; height: 72px; } .gps-top { grid-template-columns: 72px minmax(0, 1fr) minmax(0, 1fr); }
}

/* ---------- tablets (landscape 1024 px) ---------- */
@media (max-width: 1250px) and (min-width: 1001px) {
  .c-radar { grid-column: 1 / span 3; } .c-ultra { grid-column: 4 / span 3; } .c-cam { grid-column: 7 / span 3; } .c-drive { grid-column: 10 / span 3; }
  .rb .stats { width: 70px; } .rb .stats b { font-size: .95rem; }
  .card h2 .part, #imuTxt { display: none; }
  .gps-top { grid-template-columns: 72px minmax(0, 1fr); } .trail-wrap { display: none; }
}

/* ---------- narrow or short screens: normal scrolling stack ---------- */
@media (max-width: 1000px), (max-height: 560px) {
  .grid { display: flex; flex-direction: column; height: auto; }
  .card { overflow: visible; }
  .fill { flex: none; }
  .rb { flex-direction: column; flex: none; } .rb .stats { grid-template-columns: repeat(4, 1fr); width: auto; } .c-radar .fill { aspect-ratio: 1.15 / 1; }
  .c-radar .fill { aspect-ratio: 1.15 / 1; } .c-ultra .fill { aspect-ratio: 1.4 / 1; } .c-cam .fill { aspect-ratio: 4 / 3; } .c-chart .fill { height: 240px; }
  .imu-grid { flex: none; height: 170px; } .gps-top { flex: none; height: 110px; } .rover-grid { flex: none; height: 110px; } .tiles { flex: none; }
  .tile { min-height: 58px; } .dpad { flex: none; width: min(70vw, 240px); }
  .health { display: none; } .card h2 .part { display: none; }
}

/* ---------- accessibility ---------- */
@media (prefers-reduced-motion: reduce) {
  .card, .sheet { animation: none; }
  .dot.live { animation: none; }
}
@media (prefers-reduced-transparency: reduce) {
  .glass { -webkit-backdrop-filter: none; backdrop-filter: none; background: #121214; }
}
@media (prefers-contrast: more) {
  .glass { border-color: rgba(255, 255, 255, .45); background: #0c0c0e; }
  :root { --text-2: rgba(245, 245, 247, .85); --text-3: rgba(245, 245, 247, .65); }
}

/* phones: keep the title, the mode and the button on one line */
@media (max-width: 560px) {
  .brand h1 { font-size: 1rem; }
  .brand p { display: none; }
  #rateTxt, #modeTxt { display: none; }
  .c-3d .model3d { flex: none; height: 300px; }
}
