/* Vanilla CSS, no framework. The page is one column of panels; the only
   layout complexity is the viewer, which must be a fixed-height box so the
   WebGL canvas has something definite to size itself against. */

:root {
  --bg: #0d1117;
  --panel: #161b22;
  --line: #262d38;
  --text: #e6edf3;
  --muted: #8b949e;
  --accent: #58a6ff;
  --traj: #ffb454;
  --kf: #ff6b6b;
  --pts: #7ee787;
  --error: #f85149;
  --radius: 10px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 2rem 1.25rem 4rem;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.55 ui-sans-serif, -apple-system, "Segoe UI", Roboto, sans-serif;
}

header { max-width: 900px; margin: 0 auto 1.75rem; }
h1 { margin: 0 0 .35rem; font-size: 1.5rem; letter-spacing: -.01em; }
h2 { margin: 0 0 .75rem; font-size: 1rem; letter-spacing: .01em; }
.sub { margin: 0; color: var(--muted); max-width: 60ch; }

main { max-width: 900px; margin: 0 auto; display: grid; gap: 1rem; }

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
}

/* ---------- Upload ---------- */

/* Visually hidden but still focusable and still announced by screen readers.
   `display: none` or the `hidden` attribute would remove it from the tab order,
   which would make the upload control keyboard-unreachable. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

#dropzone {
  display: block;
  border: 2px dashed var(--line);
  border-radius: var(--radius);
  padding: 2.5rem 1rem;
  text-align: center;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
#dropzone:hover, #dropzone.over,
/* The input is what receives focus, so the ring is drawn on its sibling label. */
.visually-hidden:focus-visible + #dropzone {
  border-color: var(--accent);
  background: #1b2430;
}
.dz-inner { display: grid; gap: .3rem; }
.dz-inner span { color: var(--muted); font-size: .9rem; }

.hints { margin: 1rem 0 0; padding-left: 1.1rem; color: var(--muted); font-size: .88rem; }
.hints li { margin: .3rem 0; }

/* ---------- Progress ---------- */

.row { display: flex; justify-content: space-between; font-size: .9rem; }
.bar { height: 6px; background: #21262d; border-radius: 3px; margin: .6rem 0 .4rem; overflow: hidden; }
#progress-fill { height: 100%; width: 0; background: var(--accent); transition: width .25s; }

/* ---------- Viewer ---------- */

.viewer-panel { padding: 0; overflow: hidden; }
#viewer { width: 100%; height: 460px; background: #05070a; }
#viewer canvas { display: block; }

.viewer-legend {
  display: flex; flex-wrap: wrap; gap: 1rem;
  padding: .7rem 1.1rem; border-top: 1px solid var(--line);
  font-size: .82rem; color: var(--muted);
}
.viewer-legend span { display: inline-flex; align-items: center; gap: .4rem; }
.swatch { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.swatch.traj { background: var(--traj); }
.swatch.kf { background: var(--kf); }
.swatch.pts { background: var(--pts); }

.units-note {
  margin: 0; padding: .8rem 1.1rem 1rem;
  border-top: 1px solid var(--line);
  color: var(--muted); font-size: .82rem;
}

/* ---------- Stats and timing ---------- */

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: .9rem; margin: 0; }
.stats div { min-width: 0; }
.stats dt { color: var(--muted); font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; }
.stats dd { margin: .15rem 0 0; font-size: 1.15rem; font-variant-numeric: tabular-nums; }

/* Wide tables scroll inside their own box rather than making the page scroll. */
.table-scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: .86rem; font-variant-numeric: tabular-nums; }
th, td { text-align: right; padding: .4rem .55rem; border-bottom: 1px solid var(--line); white-space: nowrap; }
th:first-child, td:first-child { text-align: left; }
th { color: var(--muted); font-weight: 500; font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; }
tr.total td { font-weight: 600; border-bottom: none; }
tr.unaccounted td { color: var(--muted); font-style: italic; }

/* ---------- Flags and errors ---------- */

#flags { margin-top: 1rem; display: grid; gap: .5rem; }
.flag {
  background: #2d2410; border: 1px solid #5a4415; color: #e3b341;
  padding: .55rem .75rem; border-radius: 6px; font-size: .86rem;
}
.panel.error { border-color: #5a2020; background: #1d1414; }
.panel.error h2 { color: var(--error); }

.muted { color: var(--muted); }
.small { font-size: .8rem; }

button.again {
  margin-top: 1rem; background: transparent; color: var(--accent);
  border: 1px solid var(--line); border-radius: 6px;
  padding: .5rem .9rem; font-size: .88rem; cursor: pointer;
}
button.again:hover { border-color: var(--accent); }

/* Shown in place of the canvas when the 3D view cannot start. The numbers are
   still on screen, so this is a degraded view rather than a failed job. */
.viewer-failed {
  margin: 0; padding: 2rem 1.25rem;
  color: var(--muted); font-size: .88rem; text-align: center;
}

/* ---------- Confidence ---------- */

.confidence-heading {
  margin: 1.25rem 0 .5rem; font-size: .78rem; font-weight: 600;
  color: var(--muted); text-transform: uppercase; letter-spacing: .05em;
}
table.confidence { width: 100%; border-collapse: collapse; font-size: .84rem; }
table.confidence td { padding: .4rem .55rem; border-bottom: 1px solid var(--line); text-align: left; }
table.confidence td.value { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.confidence td.why { color: var(--muted); font-size: .78rem; }
/* A concerning signal is marked, not hidden. */
table.confidence tr.concern td { color: #e3b341; }
table.confidence tr.concern td.why { color: #b99230; }
