:root {
  --bg: #141312;
  --bg-raised: #1c1b19;
  --line: #2e2b28;
  --fg: #e8e4de;
  --muted: #8f8880;
  --accent: #d97757;
  --ok: #6fbf73;
  --warn: #e0a458;
  --bad: #d2585a;
  --bar-h: 38px;
  --radius: 8px;
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 13px/1.5 ui-sans-serif, -apple-system, "Segoe UI", Roboto, sans-serif;
  overscroll-behavior: none;
}

#app {
  display: grid;
  grid-template-rows: var(--bar-h) 1fr auto;
  height: 100dvh;
  /* The folded action menu is positioned against this. */
  position: relative;
}

#app[hidden] {
  display: none;
}

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

.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 10px;
  background: var(--bg-raised);
  border-bottom: 1px solid var(--line);
  padding-top: env(safe-area-inset-top);
  user-select: none;
}

.brand {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  font-size: 12px;
  letter-spacing: 0.02em;
}

.brand strong {
  font-weight: 600;
  color: var(--accent);
}

.sep {
  color: var(--line);
}

.brand .muted {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--muted);
  flex: none;
  transition: background 0.2s;
}

.dot.on {
  background: var(--ok);
  box-shadow: 0 0 8px color-mix(in srgb, var(--ok) 60%, transparent);
}

.dot.pending {
  background: var(--warn);
}

.dot.off {
  background: var(--bad);
}

.bar-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
}

.muted {
  color: var(--muted);
}

button {
  font: inherit;
  cursor: pointer;
  border-radius: 6px;
  border: 1px solid transparent;
  transition:
    background 0.15s,
    border-color 0.15s;
}

button.ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--muted);
  padding: 4px 9px;
  font-size: 11px;
}

button.ghost:hover {
  color: var(--fg);
  border-color: var(--muted);
}

button.primary {
  background: var(--accent);
  color: #1a1512;
  font-weight: 600;
  padding: 9px 16px;
  border: none;
}

button.primary:hover {
  background: color-mix(in srgb, var(--accent) 88%, #fff);
}

/* ---------- terminal ---------- */

#terminal {
  min-height: 0;
  padding: 6px 4px 0 8px;
  background: var(--bg);
}

.xterm .xterm-viewport {
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

.xterm .xterm-viewport::-webkit-scrollbar {
  width: 9px;
}

.xterm .xterm-viewport::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: 5px;
}

/* ---------- key bar ---------- */

#keybar {
  display: none;
  gap: 5px;
  padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
  background: var(--bg-raised);
  border-top: 1px solid var(--line);
  overflow-x: auto;
  scrollbar-width: none;
}

#keybar.show {
  display: flex;
}

#keybar button {
  flex: none;
  min-width: 42px;
  padding: 8px 10px;
  background: #262320;
  border: 1px solid var(--line);
  color: var(--fg);
  font-size: 12px;
}

#keybar button:active,
#keybar button.active {
  background: var(--accent);
  color: #1a1512;
}

@media (hover: none) and (pointer: coarse) {
  #keybar {
    display: flex;
  }
}

/* ---------- overlays ---------- */

.overlay {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 20px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(6px);
  z-index: 20;
}

.overlay[hidden] {
  display: none;
}

.card {
  width: min(420px, 100%);
  max-height: 90dvh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 24px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
}

.card h1 {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.card p {
  margin: 0;
  font-size: 12.5px;
}

.card label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 12px;
  color: var(--muted);
}

.card label.row,
.card div.row {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
}

/* Connected through the app, the token field is not the way in and showing it
   would invite someone to paste one over a working sign-in. */
.card div.row + label[hidden] {
  display: none;
}

.card small {
  font-size: 11px;
  line-height: 1.45;
}

.card code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--accent);
}

input[type="text"],
input[type="password"],
input[type="number"],
select {
  font: inherit;
  padding: 9px 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--fg);
}

input:focus,
select:focus {
  outline: none;
  border-color: var(--accent);
}

.card-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.error {
  color: var(--bad);
  font-size: 12px;
}

.error[hidden] {
  display: none;
}

.pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

@media (max-width: 420px) {
  .pair {
    grid-template-columns: 1fr;
  }
}

/* ---------- wallet sign-in and admin ---------- */

.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.small {
  font-size: 11.5px;
  line-height: 1.5;
}

.card.wide {
  width: min(560px, 100%);
}

.card h2 {
  margin: 6px 0 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.card a {
  color: var(--accent);
}

#admin-token-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.stat-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
}

.stat-label {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.stat-value {
  font-size: 13px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.user-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 200px;
  overflow-y: auto;
}

.user-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
}

@media (max-width: 480px) {
  .stat-row {
    grid-template-columns: 1fr;
  }

  .user-row {
    flex-direction: column;
    gap: 2px;
  }
}

#admin-admins-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

input:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

button.ghost.linked {
  color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 45%, transparent);
}

/* ---------- embedded: one bar, and the rest of the height to the terminal ---------- */

body.embedded {
  --bar-h: 30px;
}

body.embedded .bar {
  padding: 0 6px;
  font-size: 11px;
}

body.embedded .brand strong {
  font-size: 11px;
}

body.embedded #terminal {
  padding: 4px 2px 0 6px;
}

/* The folded actions. Anchored to the bar rather than the button so a narrow
   frame cannot push it off the right edge. */
#more-menu {
  position: absolute;
  top: calc(var(--bar-h) + env(safe-area-inset-top));
  right: 6px;
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
  padding: 6px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}

#more-menu[hidden] {
  display: none;
}

/* A strip of icons rather than a column of words, matching the bar it drops
   out of. */
#more-menu {
  flex-direction: row;
  align-items: center;
  gap: 4px;
}

a.ghost {
  text-decoration: none;
  line-height: 1;
}

/* ---------- icon buttons ---------- */

/* Fixed squares. Labels used to size these, so the row's width changed with
   the words in it and every state change shuffled its neighbours sideways. */
button.ghost.icon,
a.ghost.icon {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 23px;
  padding: 0;
}

body.embedded button.ghost.icon,
body.embedded a.ghost.icon {
  width: 24px;
  height: 20px;
}

.ghost.icon svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* One mark is a filled logo rather than a drawing. */
.ghost.icon svg.solid {
  fill: currentColor;
  stroke: none;
}

/* The buttons arrive as their answers do: the brand, then the account, then the
   container's health. Revealed one at a time they shunted each other left
   across the bar for a second on every load. They are laid out from the start
   and shown together instead, so nothing moves. */
body.settling .bar-actions > button,
body.settling .bar-actions > a {
  visibility: hidden;
}

/* Signing is a wallet round trip; the button says so without losing its icon. */
.ghost.icon.busy { opacity: 0.55; }

button.ghost.attention {
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 55%, transparent);
}

/* ---------- mode switch ----------
   One control that says where you are and moves you to the other place. It
   sits first in the action row because it changes the whole view, and the
   icons beside it only change one thing each. */

.modeswitch {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  margin-right: 6px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
}

.modeswitch button {
  padding: 3px 9px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}

.modeswitch button:hover {
  color: var(--fg);
}

.modeswitch button.on {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent);
}

/* ---------- backtest ---------- */

/* `display: grid` below beats the user agent's [hidden] rule, so the attribute
   has to be honoured explicitly or this view is never hidden at all. */
#backtest[hidden] {
  display: none;
}

#backtest {
  min-height: 0;
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 8px;
  padding: 8px;
  overflow: hidden;
}

.bt-side {
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.bt-card {
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-raised);
}

.bt-card h2,
.bt-card h3 {
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 600;
}

.bt-card label {
  display: block;
  margin-bottom: 3px;
  color: var(--muted);
  font-size: 11px;
}

.bt-card select,
.bt-card input {
  width: 100%;
  margin-bottom: 10px;
  padding: 5px 7px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--bg);
  color: var(--fg);
  font: inherit;
  font-size: 12px;
}

.bt-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.bt-row.three {
  grid-template-columns: 1fr 1fr 1fr;
}

#bt-costs summary {
  margin-bottom: 8px;
  color: var(--muted);
  font-size: 11px;
  cursor: pointer;
}

#bt-run {
  width: 100%;
  margin-top: 4px;
}

/* Runs. Each is a row you can open, with the one number that decides whether
   it is worth opening. */
.bt-runs {
  max-height: 260px;
  overflow-y: auto;
  margin-bottom: 8px;
}

.bt-run {
  display: block;
  width: 100%;
  padding: 5px 6px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.bt-run:hover {
  background: var(--bg);
}

.bt-run.on {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.bt-run .who {
  color: var(--fg);
  font-size: 12px;
}

.bt-run .facts {
  display: flex;
  gap: 8px;
  color: var(--muted);
  font-size: 11px;
}

.bt-result {
  min-height: 0;
  overflow-y: auto;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-raised);
}

.bt-empty {
  display: grid;
  place-content: center;
  gap: 6px;
  height: 100%;
  min-height: 260px;
  text-align: center;
}

.bt-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 12px;
}

.bt-head h2 {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
}

.bt-caveat {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  padding: 8px 10px;
  border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  color: var(--warn);
  font-size: 12px;
}

.bt-group {
  margin-bottom: 12px;
}

.bt-group > h4 {
  margin: 0 0 6px;
  color: var(--muted);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.bt-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 6px;
}

.bt-metric {
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg);
}

.bt-metric .k {
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.bt-metric .v {
  margin-top: 2px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
}

.up {
  color: var(--ok);
}

.down {
  color: var(--bad);
}

.bt-charts {
  margin: 12px 0;
}

.bt-charts .cap {
  display: flex;
  gap: 8px;
  align-items: baseline;
  margin: 6px 0 2px;
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.bt-trades {
  width: 100%;
  border-collapse: collapse;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px;
}

.bt-trades th {
  position: sticky;
  top: 0;
  padding: 5px 8px;
  background: var(--bg-raised);
  color: var(--muted);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-align: left;
  text-transform: uppercase;
}

.bt-trades td {
  padding: 3px 8px;
  border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent);
  color: var(--fg);
}

.bt-trades td.n,
.bt-trades th.n {
  text-align: right;
}

.bt-scroll {
  max-height: 320px;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

@media (max-width: 860px) {
  #backtest {
    grid-template-columns: minmax(0, 1fr);
    overflow-y: auto;
  }

  .bt-side {
    overflow: visible;
  }
}

/* ---------- news feeds, in the admin panel ---------- */

.admin-h2 {
  margin: 18px 0 4px;
  font-size: 13px;
  font-weight: 600;
}

.feed-list {
  margin-top: 8px;
}

.feed {
  padding: 10px;
  margin-bottom: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
}

.feed-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.feed-head strong {
  font-size: 13px;
  color: var(--fg);
}

/* Says what it is doing, not what it was set to: a feed switched on with no key
   reads nothing, and calling that "on" is how a panel comes to disagree with
   the thing it is describing. */
.feed-state {
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.feed-state.on {
  background: color-mix(in srgb, var(--ok) 18%, transparent);
  color: var(--ok);
}

.feed-state.off {
  background: color-mix(in srgb, var(--muted) 18%, transparent);
  color: var(--muted);
}

.feed p {
  margin: 4px 0 8px;
}

.feed-controls {
  display: flex;
  gap: 6px;
}

.feed-controls input {
  flex: 1;
  min-width: 0;
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--bg-raised);
  color: var(--fg);
  font: inherit;
  font-size: 12px;
}

.feed-controls button {
  white-space: nowrap;
}
