/* Trebuchet web front end.
   Sized for a tablet first: touch targets stay >=44px, the layout is a single
   column until there is genuinely room for two, and nothing depends on hover. */

:root {
  --bg: #12151a;
  --panel: #1a1f27;
  --panel-2: #212836;
  --line: #2c3444;
  --ink: #e6eaf2;
  --ink-dim: #97a2b6;
  --accent: #4c9aff;
  --accent-ink: #08111f;
  --warn: #ffb020;
  --bad: #ff6b6b;
  --good: #4ad991;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
}

/* ---------------------------------------------------------------- header */
.bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 10px 14px;
  background: var(--panel); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 10;
}
.bar h1 { font-size: 16px; margin: 0; font-weight: 600; letter-spacing: .2px; }
.bar-actions { display: flex; align-items: center; gap: 10px; }
.status { color: var(--ink-dim); font-size: 13px; min-height: 1em; }
.status.error { color: var(--bad); }
.status.busy  { color: var(--warn); }

/* ---------------------------------------------------------------- layout */
#layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  padding: 12px;
  align-items: start;
}
/* Two columns only when there is room; below this the inputs stack above the
   output, which is the right order on a phone or a portrait tablet. */
@media (min-width: 900px) {
  #layout { grid-template-columns: minmax(340px, 30%) 1fr; }
  #inputs { position: sticky; top: 64px; max-height: calc(100vh - 76px); overflow-y: auto; }
}

section {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px; padding: 12px;
}
.panel-head { display: flex; align-items: center; justify-content: space-between; }
.panel-head h2 { font-size: 14px; margin: 0 0 2px; text-transform: uppercase;
                 letter-spacing: .08em; color: var(--ink-dim); }
.panel-head-actions { display: flex; gap: 6px; }
.convention { color: var(--ink-dim); font-size: 12px; margin: 6px 0 10px; }

/* ---------------------------------------------------------------- form */
details.group {
  border: 1px solid var(--line); border-radius: 8px;
  margin-bottom: 8px; background: var(--panel-2);
}
details.group > summary {
  cursor: pointer; padding: 10px 12px; font-weight: 600; font-size: 14px;
  list-style: none; user-select: none;
}
details.group > summary::-webkit-details-marker { display: none; }
details.group > summary::before { content: "▸ "; color: var(--ink-dim); }
details.group[open] > summary::before { content: "▾ "; }
.group-body { padding: 4px 12px 12px; }

.field { display: grid; grid-template-columns: 1fr auto; gap: 6px;
         align-items: center; margin-bottom: 9px; }
.field > label { grid-column: 1 / -1; font-size: 13px; color: var(--ink-dim); }
.field input[type=number], .field select {
  background: #0e1218; color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px;
  padding: 9px 8px; font: inherit; min-height: 40px; width: 100%;
}
.field .unit { min-width: 84px; }
.field.wide > input, .field.wide > select { grid-column: 1 / -1; }
.field input:focus, .field select:focus,
button:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.field input.invalid { border-color: var(--bad); }

.diagram { margin: 2px 0 10px; text-align: center; }
.diagram img { max-width: 100%; height: auto; opacity: .92; }

/* ---------------------------------------------------------------- buttons */
button {
  font: inherit; border-radius: 7px; cursor: pointer; min-height: 40px;
  padding: 8px 14px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--ink);
}
button.primary { background: var(--accent); color: var(--accent-ink);
                 border-color: var(--accent); font-weight: 600; }
button.ghost { background: transparent; color: var(--ink-dim); }
button:disabled { opacity: .45; cursor: not-allowed; }

/* ---------------------------------------------------------------- tabs */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line);
        margin: -4px -4px 10px; overflow-x: auto; }
.tab { border: none; background: transparent; color: var(--ink-dim);
       border-bottom: 2px solid transparent; border-radius: 0; white-space: nowrap; }
.tab.active { color: var(--ink); border-bottom-color: var(--accent); }

.view { display: none; }
.view.active { display: block; }

/* ---------------------------------------------------------------- stage */
/* 16:10 is the *starting* shape. On a landscape tablet the output panel is
   wide, so that ratio makes the canvas taller than the screen and the top of
   the machine scrolls off. fitStage() in app.js measures the space actually
   left below the tabs and sets max-height to match, letting the box go
   letterbox rather than overflow. The mechanism is auto-fitted to whatever
   rectangle it gets, so a wider, shorter box costs nothing. */
#stage { width: 100%; aspect-ratio: 16 / 10; display: block;
         min-height: 180px;
         background: #0e1218; border: 1px solid var(--line); border-radius: 8px; }
.transport { display: flex; align-items: center; gap: 10px; margin-top: 10px;
             flex-wrap: wrap; }
.transport input[type=range] { flex: 1 1 200px; min-height: 40px; }
.speed { display: flex; align-items: center; gap: 6px; color: var(--ink-dim);
         font-size: 13px; }
.speed select { background: #0e1218; color: var(--ink); border: 1px solid var(--line);
                border-radius: 6px; padding: 7px; min-height: 36px; }
.mono { font-family: var(--mono); font-size: 13px; color: var(--ink-dim); }
.hint { color: var(--ink-dim); font-size: 12.5px; margin: 8px 0; }

/* ---------------------------------------------------------------- charts */
.chart { margin-bottom: 14px; }
.chart h3 { font-size: 13px; margin: 0 0 4px; color: var(--ink-dim); font-weight: 600; }
.chart canvas { width: 100%; height: 170px; display: block;
                background: #0e1218; border: 1px solid var(--line); border-radius: 8px; }

/* ---------------------------------------------------------------- results */
.result-group { margin-bottom: 14px; }
.result-group h3 { font-size: 13px; margin: 0 0 6px; color: var(--ink-dim);
                   text-transform: uppercase; letter-spacing: .07em; }
table.kv { width: 100%; border-collapse: collapse; font-size: 14px; }
table.kv td { padding: 6px 4px; border-bottom: 1px solid var(--line); }
table.kv td.v { text-align: right; font-family: var(--mono); white-space: nowrap; }
table.kv tr.flag td { color: var(--warn); }
table.kv tr.governs td.v { color: var(--accent); font-weight: 600; }

.notice { border-left: 3px solid var(--warn); background: #241d0d;
          padding: 8px 10px; border-radius: 4px; margin: 8px 0; font-size: 13px; }
.notice.bad { border-left-color: var(--bad); background: #2a1416; }

/* ------------------------------------------------- collapsible design panel */
/* Hidden rather than removed, so the form keeps its state and its widgets stay
   readable to assistive tech in the same order when it comes back. */
body.design-hidden #inputs { display: none; }
@media (min-width: 900px) {
  body.design-hidden #layout { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------ envelope diagnostics */
canvas.pose { width: 100%; height: 200px; display: block;
              background: #0e1218; border: 1px solid var(--line); border-radius: 8px; }
canvas.heat { width: 100%; height: 300px; display: block;
              background: #0e1218; border: 1px solid var(--line); border-radius: 8px; }
