:root {
  --bg: #14171c;
  --panel: #1a1e25;
  --panel-2: #21262f;
  --line: #2d343f;
  --text: #dfe4ec;
  --muted: #8f9bad;
  --accent: #4da3ff;
  --accent-dim: #2b6cb0;
  --ok: #58c98a;
  --warn: #e8b04b;
  --err: #ef6b6b;
  --mesh: #7fb2e0;
  --mesh-fill: #2a3b4d;
}

* { box-sizing: border-box; }

/* An author `display` rule outranks the UA rule behind [hidden], and this sheet
   sets display on both .switcher and canvas. Without this the Response tab
   appears before there is anything to show, and switching to it leaves the mesh
   canvas in place with the plot drawn underneath it. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font: 13px/1.45 "Segoe UI", system-ui, sans-serif;
  background: var(--bg);
  color: var(--text);
  height: 100vh;
  display: flex;
  flex-direction: column;
}

header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 10px 18px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}
header h1 { font-size: 15px; margin: 0; font-weight: 600; letter-spacing: .2px; }
header .sub { margin: 0; color: var(--muted); font-size: 12px; }
.status { margin-left: auto; color: var(--muted); font-size: 12px; }
.status.busy { color: var(--accent); }
.status.err { color: var(--err); }
.status.ok { color: var(--ok); }

main { flex: 1; display: flex; min-height: 0; }

/* ---------- left panel ---------- */
#panel {
  width: 340px;
  flex: none;
  overflow-y: auto;
  background: var(--panel);
  border-right: 1px solid var(--line);
  padding-bottom: 40px;
}
#panel details { padding: 10px 16px 14px; border-bottom: 1px solid var(--line); }
#panel summary {
  cursor: pointer;
  margin-bottom: 10px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--muted);
  font-weight: 600;
  user-select: none;
}
#panel summary:hover { color: var(--text); }
#panel details:not([open]) summary { margin-bottom: 0; }

.cards { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.card {
  text-align: left;
  padding: 8px 9px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--text);
  cursor: pointer;
  font: inherit;
}
.card:hover { border-color: var(--accent-dim); }
.card.active { border-color: var(--accent); background: #1d2b3d; }
.card b { display: block; font-size: 12px; }
.card span { display: block; color: var(--muted); font-size: 10.5px; margin-top: 2px; }

.note { margin: -4px 0 10px; color: var(--muted); font-size: 11px; }
.fields { display: grid; gap: 9px; }
label { display: grid; gap: 3px; font-size: 12px; color: var(--muted); }
label .unit { color: var(--muted); font-size: 10.5px; }
label small { color: var(--muted); font-size: 10.5px; opacity: .85; }
input, select {
  width: 100%;
  padding: 5px 7px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
}
input:focus, select:focus { outline: none; border-color: var(--accent); }
code { background: var(--panel-2); padding: 0 3px; border-radius: 3px; font-size: 10.5px; }

.switch { display: flex; flex-direction: row; align-items: center; gap: 8px; margin-bottom: 10px; color: var(--text); }
.switch input { width: auto; }

/* Segmented buttons for the solver choice. A row of buttons rather than a
   dropdown because the third option is not a faster way to do the same thing --
   it runs a different constitutive model -- and that should be visible without
   opening a menu. */
.choiceRow { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.choiceRow .choice {
  padding: 5px 10px; font-size: 11.5px; font-weight: 500;
  background: transparent; color: var(--muted); border-color: var(--line);
}
.choiceRow .choice:hover:not(:disabled) { border-color: var(--accent); }
.choiceRow .choice.on {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
/* The VUMAT option gets the warning colour, because picking it changes the
   physics and not just how long the run takes. */
.choiceRow .choice.warnOn {
  background: var(--warn); border-color: var(--warn); color: #14181d;
}
.choiceRow .choice:disabled { opacity: 0.35; cursor: not-allowed; }

.row { display: flex; gap: 6px; margin-top: 8px; }
.row input { flex: 1; }

button {
  padding: 6px 12px;
  border: 1px solid var(--accent);
  border-radius: 5px;
  background: var(--accent);
  color: #0d1117;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
button:hover { filter: brightness(1.08); }
button.ghost { background: transparent; color: var(--text); border-color: var(--line); font-weight: 500; }
button.ghost:hover { border-color: var(--accent); }

/* ---------- ply stack ---------- */
.stack { display: flex; flex-direction: column-reverse; gap: 1px; margin-top: 10px; }
.ply {
  display: flex;
  justify-content: space-between;
  padding: 2px 7px;
  font-size: 10.5px;
  border-radius: 2px;
  color: #0d1117;
  font-weight: 600;
}
.ply span:last-child { opacity: .7; }

/* ---------- material table ---------- */
.props { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; }
.props label { font-size: 11px; }
.props input { padding: 3px 6px; font-size: 11.5px; }

/* ---------- viewport ---------- */
#viewport { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}
.spacer { flex: 1; }
.stats { display: flex; flex-wrap: wrap; gap: 14px; font-size: 11.5px; color: var(--muted); }
.stats b { color: var(--text); font-weight: 600; }

.canvas-wrap { position: relative; flex: 1; min-height: 0; }
canvas { display: block; width: 100%; height: 100%; cursor: grab; }
canvas:active { cursor: grabbing; }
.canvas-msg {
  position: absolute;
  left: 14px;
  bottom: 12px;
  font-size: 11.5px;
  color: var(--muted);
  pointer-events: none;
}
.canvas-msg.err { color: var(--err); max-width: 70%; }

/* ---------- results ---------- */
.results {
  max-height: 34%;
  overflow-y: auto;
  border-top: 1px solid var(--line);
  background: var(--panel);
  padding: 0 14px;
}
.results:empty { display: none; }
.results table { width: 100%; border-collapse: collapse; font-size: 11.5px; }
.results th {
  text-align: left;
  color: var(--muted);
  font-weight: 600;
  padding: 8px 8px 6px;
  position: sticky;
  top: 0;
  background: var(--panel);
}
.results td { padding: 4px 8px; border-top: 1px solid var(--line); }
.results a { color: var(--accent); text-decoration: none; }
.results a:hover { text-decoration: underline; }
.results pre {
  margin: 8px 0 14px;
  padding: 10px;
  background: var(--panel-2);
  border-radius: 6px;
  font-size: 11px;
  overflow-x: auto;
  color: var(--muted);
}
.results .path { color: var(--muted); font-size: 11.5px; padding: 8px 0 0; }

.deck { margin-top: 3px; display: flex; flex-wrap: wrap; gap: 8px; }
.deck a { color: var(--muted); font-size: 10.5px; }
.deck a:hover { color: var(--accent); }

/* ---------- solve ---------- */
.switcher { display: flex; gap: 0; }
.switcher button { border-radius: 0; }
.switcher button:first-child { border-radius: 5px 0 0 5px; }
.switcher button:last-child { border-radius: 0 5px 5px 0; margin-left: -1px; }
.switcher button.active { border-color: var(--accent); color: var(--accent); }

.progress {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 12px;
  font-size: 11.5px;
  color: var(--muted);
}
.progress-bar {
  height: 4px;
  border-radius: 2px;
  background: var(--panel-2);
  overflow: hidden;
  margin-bottom: 5px;
}
.progress-bar span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
  transition: width .2s linear;
}

/* The verdict block under a finished solve: the numbers, then every reason
   they might not mean what they look like. */
.verdict { display: flex; flex-wrap: wrap; gap: 16px; padding: 10px 0 4px; }
.verdict div { font-size: 11.5px; color: var(--muted); }
.verdict b { display: block; font-size: 15px; color: var(--text); font-weight: 600; }
.verdict b.warn { color: var(--warn); }

.warnings { margin: 4px 0 12px; padding: 0 0 0 16px; }
.warnings li { color: var(--warn); font-size: 11.5px; margin: 3px 0; }
.warnings li.ok { color: var(--ok); }

/* ---------- contour ---------- */
.fieldbar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 7px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
  font-size: 11.5px;
}
.fieldbar label { display: flex; flex-direction: row; align-items: center; gap: 6px; }
.fieldbar label.grow { flex: 1; min-width: 140px; }
.fieldbar select { width: auto; }
.fieldbar input[type="range"] { flex: 1; padding: 0; }
#field-frame-label { color: var(--text); font-variant-numeric: tabular-nums; }

/* The Abaqus rainbow: blue, cyan, green, yellow, red. Perceptually uneven,
   and the convention every contour in this field is read against. */
.colourbar { display: flex; align-items: center; gap: 7px; color: var(--muted); }
.colourbar i {
  display: block;
  width: 150px;
  height: 11px;
  border-radius: 2px;
  border: 1px solid var(--line);
  background: linear-gradient(to right, #0000ff, #00ffff, #00ff00, #ffff00, #ff0000);
}
.colourbar span { font-variant-numeric: tabular-nums; }

#upload-controls label { display: block; margin-top: 10px; }
#upload-controls input[type="file"] { max-width: 100%; }
#upload-status { overflow-wrap: anywhere; }
#download-curve { color: var(--accent); white-space: nowrap; }
