/* Adam V1. Tokens taken verbatim from the Clovermind site stylesheet: Geist +
   Geist Mono, monochrome, colour only where it carries information. The one
   place colour is allowed here is the verdict state and the threshold line on
   the bars, because both are the readout saying something and a monochrome
   version of them would be less legible rather than more restrained.

   Geist loads from the font CDN. Offline, the system stack takes over and the
   layout does not move, which is the reason for the fallbacks rather than a
   nicety: this is an installable offline app and the fonts are the one thing
   in it that is not self-contained. */

:root {
  --bg: #0a0a0b;
  --panel: #101013;
  --ink: #ededf0;
  --dim: #85858e;
  --faint: #4a4a52;
  --line: rgba(237, 237, 240, 0.12);
  --line-strong: rgba(237, 237, 240, 0.25);
  --accent: #5e5ce6;
  --live: #7d87e6;
  --warn: #c98a5e;
  --sans: "Geist", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --bar-h: 54px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

.mono-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}

/* ---------- top bar ---------- */
.bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  height: calc(var(--bar-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) 16px 0 16px;
  display: flex; align-items: center; justify-content: space-between;
  background: rgba(10, 10, 11, 0.86);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.bar-left { display: flex; align-items: baseline; gap: 12px; }
.mark { font-size: 16px; font-weight: 500; letter-spacing: -0.01em; }
.bar-right { display: flex; gap: 8px; }
.ctl {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--dim);
  border: 1px solid var(--line); border-radius: 99px;
  padding: 7px 14px; transition: color 150ms, border-color 150ms, background 150ms;
}
.ctl:hover { color: var(--ink); border-color: var(--line-strong); }
.ctl[aria-pressed="true"] {
  color: var(--bg); background: var(--warn); border-color: var(--warn);
}

/* ---------- layout ---------- */
.stage {
  padding: calc(var(--bar-h) + env(safe-area-inset-top) + 14px) 14px
           calc(20px + env(safe-area-inset-bottom));
  max-width: 560px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 14px;
}
.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  padding: 12px;
}
.panel-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 10px;
}
.row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

/* ---------- 1. camera ---------- */
.cam-wrap {
  position: relative; width: 100%; aspect-ratio: 3 / 4;
  background: #0d0d10; overflow: hidden;
}
/* contain, not cover. Cover would crop the camera frame for display while the
   network still received all of it, so the app could lock onto something the
   user cannot see and box it off-screen. The panel is titled "the live frame
   with the detected crop boxed" and it has to be the whole frame for that to be
   true. On a phone held portrait the video is close to 3:4 already, so the
   letterbox is thin where it matters. */
.cam-wrap video, .overlay {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain;
}
.overlay { pointer-events: none; }
.start {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  border: 1px solid var(--line-strong); border-radius: 99px;
  padding: 12px 26px; font-size: 14px; background: rgba(10, 10, 11, 0.55);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.start[hidden] { display: none; }

.verdict {
  position: absolute; left: 12px; bottom: 12px; right: 12px;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; border: 1px solid var(--line);
  background: rgba(10, 10, 11, 0.6);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  transition: border-color 200ms;
}
.verdict-glyph {
  font-size: 34px; font-weight: 600; line-height: 1; min-width: 26px;
  letter-spacing: -0.03em; font-variant-numeric: tabular-nums;
}
.verdict-note { color: var(--dim); }
.verdict[data-state="named"] { border-color: var(--live); }
.verdict[data-state="named"] .verdict-glyph { color: var(--live); }
.verdict[data-state="withheld"] .verdict-glyph { color: var(--faint); font-size: 22px; }
.verdict[data-state="control"] { border-color: var(--warn); }
.verdict[data-state="control"] .verdict-glyph { color: var(--warn); }

/* ---------- 2 and 3. the pixel views ---------- */
/* image-rendering: pixelated is load-bearing. These are 28x28 and 10x10
   canvases blown up; smoothing them would show an interpolation of the data
   rather than the data, and the whole point of the panel is to see exactly what
   the network was handed. */
.pix {
  width: 100%; height: auto; display: block;
  image-rendering: pixelated; image-rendering: crisp-edges;
  background: #000; border: 1px solid var(--line);
}

/* ---------- 4. the bars ---------- */
.bars { display: flex; flex-direction: column; gap: 5px; position: relative; }
.bar-row { display: grid; grid-template-columns: 18px 1fr 46px; align-items: center; gap: 10px; }
.bar-key {
  font-family: var(--mono); font-size: 13px; color: var(--dim);
  font-variant-numeric: tabular-nums; text-align: center;
}
.bar-track { position: relative; height: 12px; background: rgba(237, 237, 240, 0.06); }
.bar-fill { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--faint); transition: width 90ms linear, background 150ms; }
.bar-row.top .bar-fill { background: var(--dim); }
.bar-row.named .bar-fill { background: var(--live); }
.bar-row.named .bar-key { color: var(--live); }
.bar-row.control.named .bar-fill { background: var(--warn); }
.bar-row.control.named .bar-key { color: var(--warn); }
.bar-val {
  font-family: var(--mono); font-size: 10.5px; color: var(--faint);
  font-variant-numeric: tabular-nums; text-align: right;
}
/* The threshold, drawn where it actually sits. A confidence gate the user
   cannot see is a claim they have to take on trust. */
.bar-mark {
  position: absolute; top: 0; bottom: 0; width: 1px;
  background: var(--line-strong); pointer-events: none;
}
.bar-mark::after {
  content: attr(data-label); position: absolute; top: -14px; left: 3px;
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--faint); white-space: nowrap;
}
.foot { margin-top: 12px; line-height: 1.7; text-transform: none; letter-spacing: 0.04em; }

/* ---------- about ---------- */
.about {
  position: fixed; inset: 0; z-index: 60; overflow-y: auto;
  background: var(--bg); -webkit-overflow-scrolling: touch;
}
.about[hidden] { display: none; }
.about-inner {
  max-width: 620px; margin: 0 auto;
  padding: calc(env(safe-area-inset-top) + 28px) 24px
           calc(env(safe-area-inset-bottom) + 48px);
}
.about h1 { font-size: 34px; font-weight: 500; letter-spacing: -0.02em; margin-bottom: 14px; }
.about h2 {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--dim); font-weight: 400;
  margin: 32px 0 10px;
}
.about p { color: #b9b9c0; margin-bottom: 12px; font-size: 15.5px; }
.about .lede { color: var(--ink); font-size: 17px; }
.about .ctl { margin-top: 32px; }
.numbers { border-top: 1px solid var(--line); margin-bottom: 14px; }
.num-row {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 9px 0; border-bottom: 1px solid var(--line);
}
.num-row span:first-child { color: var(--dim); font-size: 14px; }
.num-row span:last-child {
  font-family: var(--mono); font-size: 13px;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* ---------- fatal ---------- */
.fatal {
  position: fixed; inset: 0; z-index: 80; display: flex;
  align-items: center; justify-content: center; padding: 24px;
  background: rgba(10, 10, 11, 0.96);
}
.fatal[hidden] { display: none; }
.fatal-inner { max-width: 460px; border: 1px solid var(--warn); padding: 20px; }
.fatal-inner p { margin-top: 10px; color: #b9b9c0; font-size: 15px; }

@media (min-width: 900px) {
  .stage { max-width: 1080px; display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas: "cam bars" "cam small"; align-items: start; }
  .panel-cam { grid-area: cam; }
  .panel-bars { grid-area: bars; }
  .row { grid-area: small; }
}

@media (prefers-reduced-motion: reduce) {
  .bar-fill, .verdict, .ctl { transition: none; }
}
