/* Form Coach HUD.
   Read from about three metres away, mid-set: big numerals, high contrast,
   one accent colour that means "measured", amber for "watch this", red for
   "fault". No web fonts -- the page has to work offline at the gym and under
   cross-origin isolation -- so the type is the system's own monospace. */

:root {
  color-scheme: dark;
  --bg: #02070b;
  --cyan: #5df2ff;
  --cyan-dim: rgba(93, 242, 255, .35);
  --cyan-faint: rgba(93, 242, 255, .12);
  --amber: #ffb547;
  --red: #ff4d6d;
  --green: #7dffb2;
  --ink: #e8fbff;
  --muted: #7fa3ad;
  --panel: rgba(4, 18, 26, .92);
  --mono: ui-monospace, "SF Mono", "SFMono-Regular", Menlo, Consolas, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --glow: 0 0 6px rgba(93, 242, 255, .65), 0 0 18px rgba(93, 242, 255, .25);
  --pad: max(14px, env(safe-area-inset-left));
  --top: max(12px, env(safe-area-inset-top));
  --bot: max(12px, env(safe-area-inset-bottom));
}

* { box-sizing: border-box; }

html, body {
  margin: 0; height: 100%; overflow: hidden;
  background: var(--bg); color: var(--ink);
  font: 15px/1.4 var(--sans);
  -webkit-user-select: none; user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* --- stage --------------------------------------------------------------- */

#stage { position: fixed; inset: 0; overflow: hidden; background: #000; }

#stage video, #stage canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
/* The live video is shown only until the first frame is processed. After
   that the picture is the processed frame itself, so the skeleton drawn
   over it is always on the image it came from -- the live video runs a
   frame or more ahead of the model, and a skeleton that trails the body
   reads as a wrong one. */
#picture { filter: saturate(.75) contrast(1.05); }
#stage video { filter: saturate(.75) contrast(1.05); }
body.processing #stage video { opacity: 0; }

.vignette {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse at center, transparent 45%, rgba(0, 10, 16, .78) 100%),
    linear-gradient(to bottom, rgba(0, 10, 16, .55), transparent 18%, transparent 75%, rgba(0, 10, 16, .7));
}

.scan {
  position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background: repeating-linear-gradient(to bottom, transparent 0 3px, rgba(93, 242, 255, .035) 3px 4px);
}

/* corner brackets of the visor */
.frame { position: absolute; inset: calc(var(--top) + 4px) var(--pad) calc(var(--bot) + 4px); pointer-events: none; }
.frame i { position: absolute; width: 26px; height: 26px; border: 2px solid var(--cyan-dim); }
.frame i:nth-child(1) { left: 0; top: 0; border-right: 0; border-bottom: 0; }
.frame i:nth-child(2) { right: 0; top: 0; border-left: 0; border-bottom: 0; }
.frame i:nth-child(3) { left: 0; bottom: 0; border-right: 0; border-top: 0; }
.frame i:nth-child(4) { right: 0; bottom: 0; border-left: 0; border-top: 0; }

/* --- top bar ---------------------------------------------------------------- */

.top {
  position: absolute; top: calc(var(--top) + 10px); left: calc(var(--pad) + 14px); right: calc(var(--pad) + 14px);
  display: flex; align-items: center; gap: 12px;
  font-family: var(--mono); letter-spacing: .14em;
}
.brand { font-weight: 700; font-size: 13px; color: var(--cyan); text-shadow: var(--glow); }
.brand span { color: var(--muted); }

.mode {
  flex: 1; text-align: center; font-size: 12px; font-weight: 600;
  padding: 4px 10px; border: 1px solid currentColor; border-radius: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mode[data-kind="ok"] { color: var(--cyan); text-shadow: var(--glow); }
.mode[data-kind="warn"] { color: var(--amber); animation: blink 1.4s steps(2, start) infinite; }
.mode[data-kind="bad"] { color: var(--red); }
.mode[data-kind="dim"] { color: var(--muted); }

.timer { font-size: 15px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }

.hint {
  position: absolute; top: calc(var(--top) + 46px); left: 72px; right: 72px;
  text-align: center; font: 600 12px var(--mono); letter-spacing: .08em; color: var(--ink);
  text-shadow: 0 1px 3px #000, 0 0 8px #000;
}

/* --- rep counter ------------------------------------------------------------- */

.rep {
  position: absolute; top: calc(var(--top) + 52px); right: calc(var(--pad) + 18px);
  text-align: right; font-family: var(--mono);
}
.rep .label { font-size: 12px; letter-spacing: .3em; color: var(--muted); }
.rep .count {
  font-size: clamp(56px, 15vw, 120px); line-height: .9; font-weight: 700;
  color: var(--cyan); text-shadow: var(--glow); font-variant-numeric: tabular-nums;
}
body.in-rep .rep .count { color: #fff; }

/* --- gauges ------------------------------------------------------------------ */

.gauge {
  position: absolute; top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  font-family: var(--mono);
}
.gauge.left { left: calc(var(--pad) + 14px); }
.gauge.right { right: calc(var(--pad) + 14px); }
.gauge .label, .rep .label { text-shadow: 0 1px 3px #000, 0 0 6px #000; }
.gauge .label { font-size: 11px; letter-spacing: .25em; color: #b9d3da; }
.gauge .track {
  position: relative; width: 14px; height: min(38vh, 300px);
  border: 1px solid var(--cyan-dim); background: rgba(2, 14, 20, .55);
  background-image: repeating-linear-gradient(to top, transparent 0 9.5%, var(--cyan-dim) 9.5% 10%);
}
.gauge .fill {
  position: absolute; left: 1px; right: 1px; bottom: 0; height: 100%;
  transform-origin: bottom; transform: scaleY(0);
  background: var(--cyan); box-shadow: var(--glow);
  transition: transform .08s linear, background-color .2s;
}
.gauge .fill[data-kind="warn"] { background: var(--amber); }
.gauge .fill[data-kind="good"] { background: var(--green); box-shadow: 0 0 8px rgba(125, 255, 178, .7); }
.gauge .fill[data-kind="bad"] { background: var(--red); }
.gauge .line {
  position: absolute; left: -7px; right: -7px; height: 2px; background: #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .6);
}
.gauge .line::after {
  content: attr(data-label); position: absolute; top: -7px; font-size: 10px; color: #fff;
  text-shadow: 0 1px 3px #000, 0 0 6px #000;
}
.gauge.left .line::after { left: 26px; }
.gauge.right .line::after { right: 26px; }
.gauge .peak {
  position: absolute; left: -4px; right: -4px; height: 0;
  border-top: 2px dashed var(--green);
}
.gauge .value {
  font-size: clamp(22px, 6vw, 34px); font-weight: 700; color: var(--ink);
  text-shadow: 0 1px 4px #000, 0 0 10px #000;
  font-variant-numeric: tabular-nums; min-width: 3.2ch; text-align: center;
}

/* --- boot sequence -------------------------------------------------------------- */

.boot {
  position: absolute; left: 50%; top: 38%; transform: translate(-50%, -50%);
  width: min(86vw, 420px); padding: 14px 16px;
  font-family: var(--mono); font-size: 12px; letter-spacing: .08em;
  border: 1px solid var(--cyan-dim); background: rgba(2, 14, 20, .78);
}
.boot div { display: flex; align-items: baseline; gap: 8px; margin: 4px 0; color: var(--muted); }
.boot div i { flex: 1; border-bottom: 1px dotted var(--cyan-dim); }
.boot div b { color: var(--cyan); font-weight: 600; }
.boot div b.ok { color: var(--green); }

/* --- set-up guidance ----------------------------------------------------------
   Large and central, because the person reading it is three metres away
   and turning. It is also spoken; this is for the glance. */

.guide {
  position: absolute; left: 6%; right: 6%; top: 40%;
  padding: 14px 16px; text-align: center;
  font: 800 clamp(22px, 7vw, 44px) var(--mono); letter-spacing: .06em;
  color: var(--amber); border: 2px solid var(--amber); background: rgba(20, 12, 0, .62);
  text-shadow: 0 0 10px rgba(255, 181, 71, .6);
  animation: blink 1.6s steps(2, start) infinite;
}
.guide[data-kind="ok"] { color: var(--green); border-color: var(--green); animation: none;
  text-shadow: 0 0 10px rgba(125, 255, 178, .6); background: rgba(0, 20, 10, .62); }

/* --- cue -------------------------------------------------------------------- */

.cue {
  position: absolute; left: 0; right: 0; top: 58%;
  text-align: center; font-family: var(--mono); font-weight: 800;
  font-size: clamp(40px, 13vw, 96px); letter-spacing: .06em;
  color: var(--amber); opacity: 0; pointer-events: none;
  text-shadow: 0 0 10px rgba(255, 181, 71, .8), 0 0 30px rgba(255, 181, 71, .35);
}
.cue[data-fault="excessive_trunk_lean"] { color: var(--red); text-shadow: 0 0 10px rgba(255, 77, 109, .8), 0 0 30px rgba(255, 77, 109, .35); }
.cue.show { animation: cue 1.9s ease-out forwards; }

@keyframes cue {
  0% { opacity: 0; transform: scale(1.25); }
  6% { opacity: 1; transform: scale(1); }
  12% { opacity: .35; }
  18%, 70% { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes blink { 50% { opacity: .35; } }

.alert {
  position: absolute; left: var(--pad); right: var(--pad); top: 30%;
  margin: 0 14px; padding: 12px 14px; font-family: var(--mono); font-size: 13px;
  color: var(--red); border: 1px solid var(--red); background: rgba(30, 4, 10, .85);
}

/* --- bottom ------------------------------------------------------------------ */

.bottom {
  position: absolute; left: calc(var(--pad) + 14px); right: calc(var(--pad) + 14px);
  bottom: calc(var(--bot) + 14px);
  font-family: var(--mono);
}
.strip { display: flex; gap: 6px; flex-wrap: nowrap; overflow: hidden; margin-bottom: 10px; min-height: 28px; }
.chip {
  flex: none; padding: 4px 8px; font-size: 11px; letter-spacing: .08em;
  border: 1px solid currentColor; background: rgba(2, 14, 20, .6);
}
.chip b { margin-right: 6px; }
.chip[data-kind="ok"] { color: var(--green); }
.chip[data-kind="bad"] { color: var(--red); }
.chip[data-kind="dim"] { color: var(--muted); border-style: dashed; }

.readouts {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  text-shadow: 0 1px 3px #000;
}
.bio {
  display: flex; align-items: center; gap: 6px; padding: 3px 8px; white-space: nowrap;
  color: var(--muted); border: 1px dashed rgba(127, 163, 173, .5); background: rgba(2, 14, 20, .55);
}
.bio .heart { color: var(--red); opacity: .55; }
.bio b { font-size: 15px; letter-spacing: .1em; }
.bio small { font-size: 9px; letter-spacing: .1em; }
.sys { font-size: 10px; letter-spacing: .1em; color: #8fdbe6; text-align: right; white-space: nowrap; }

/* --- controls ----------------------------------------------------------------- */

button { font: inherit; cursor: pointer; }

.engage {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 156px; height: 156px; border-radius: 50%;
  border: 2px solid var(--cyan); background: rgba(2, 14, 20, .55); color: var(--cyan);
  font-family: var(--mono); font-weight: 700; letter-spacing: .3em; font-size: 15px;
  box-shadow: var(--glow), inset 0 0 24px rgba(93, 242, 255, .25);
}
.engage::before {
  content: ""; position: absolute; inset: -12px; border-radius: 50%;
  border: 1px dashed var(--cyan-dim); animation: spin 14s linear infinite;
}
.engage span { position: relative; left: .15em; }
.engage:disabled { opacity: .5; }
body.engaged .engage { display: none; }

@keyframes spin { to { transform: rotate(360deg); } }

.end {
  position: absolute; right: calc(var(--pad) + 14px); bottom: calc(var(--bot) + 64px);
  padding: 10px 14px; font-family: var(--mono); font-size: 12px; letter-spacing: .14em;
  color: var(--red); border: 1px solid var(--red); background: rgba(30, 4, 10, .55);
  display: none;
}
body.engaged .end { display: block; }

.menu {
  position: absolute; left: calc(var(--pad) + 14px); top: calc(var(--top) + 52px);
  width: 40px; height: 40px; font-size: 20px; line-height: 1;
  color: var(--cyan); border: 1px solid var(--cyan-dim); background: rgba(2, 14, 20, .55);
}

/* --- drawer ------------------------------------------------------------------- */

.drawer {
  position: fixed; inset: 0 0 0 auto; width: min(380px, 100vw); z-index: 10;
  padding: calc(var(--top) + 6px) 18px calc(var(--bot) + 18px);
  overflow-y: auto; background: var(--panel); border-left: 1px solid var(--cyan-dim);
  -webkit-user-select: text; user-select: text;
}
.drawer header { display: flex; align-items: center; justify-content: space-between; }
.drawer h1 { font-size: 17px; margin: 6px 0; }
.drawer h1 span { color: var(--muted); font-weight: 400; font-size: 13px; }
.drawer h2 { font: 600 11px var(--mono); letter-spacing: .2em; color: var(--cyan); margin: 20px 0 6px; text-transform: uppercase; }
.warn { color: var(--amber); font-size: 13px; }
.note { color: var(--muted); font-size: 13px; }
.error { color: var(--red); white-space: pre-wrap; font-size: 13px; }
.error .button { display: inline-block; margin-top: 8px; }

.controls { display: flex; gap: 8px; margin: 10px 0; }
.drawer button, .button {
  flex: 1; padding: 11px; border: 1px solid var(--cyan-dim); border-radius: 2px;
  background: rgba(93, 242, 255, .06); color: var(--ink); font-weight: 600;
  text-align: center; text-decoration: none;
}
.drawer button.primary { background: var(--cyan); color: #01212a; border-color: var(--cyan); }
.drawer button.ghost { flex: none; width: 40px; background: none; }

label { display: block; margin: 10px 0 0; color: var(--muted); font-size: 13px; }
label select {
  display: block; width: 100%; margin-top: 4px; padding: 9px; font: inherit;
  background: #06161e; color: var(--ink); border: 1px solid var(--cyan-dim); border-radius: 2px;
}
label.check { display: flex; gap: 8px; align-items: center; color: var(--ink); }

#metrics { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; margin: 0; }
#metrics div { min-width: 0; }
#metrics .wide { grid-column: 1 / -1; }
#metrics dt { color: var(--muted); font-size: 11px; }
#metrics dd { margin: 0; font: 600 13px var(--mono); overflow-wrap: anywhere; }
#summary-list { padding-left: 20px; font-size: 13px; }

/* Landscape phone. Height is the scarce thing, so the controls move into
   the top bar and the gauges get the full height between bar and footer;
   everything else steps inward clear of them. */
@media (orientation: landscape) and (max-height: 500px) {
  .menu { top: calc(var(--top) + 6px); width: 34px; height: 34px; font-size: 18px; }
  .top { left: calc(var(--pad) + 60px); right: calc(var(--pad) + 124px); top: calc(var(--top) + 12px); }
  .end { top: calc(var(--top) + 6px); bottom: auto; padding: 8px 10px; font-size: 11px; }
  .hint { top: calc(var(--top) + 46px); }
  .gauge { top: calc(var(--top) + 56px); bottom: calc(var(--bot) + 64px); transform: none; }
  .gauge .track { height: auto; flex: 1; }
  .gauge .value { font-size: 22px; }
  .rep { top: calc(var(--top) + 52px); right: calc(var(--pad) + 76px); }
  .rep .count { font-size: clamp(44px, 16vh, 84px); }
  .bottom { left: calc(var(--pad) + 76px); right: calc(var(--pad) + 76px); }
  .cue { top: 52%; font-size: clamp(36px, 11vh, 72px); }
}

@media (prefers-reduced-motion: reduce) {
  .engage::before, .mode[data-kind="warn"], .cue.show, .guide { animation: none; }
  .cue.show { opacity: 1; }
}
