/* tbq-observe dashboard. One page, no build step, served by the API it reads. */
:root {
  /* Sampled from the reference: a near-black with a red cast rather than a
     neutral grey, which is what makes the crimson read as part of the surface
     instead of sitting on top of it. */
  --bg: #08060A;
  --bg-glow: #1A0B12;
  --panel: #100C11;
  --panel-2: #151016;
  --line: #241C26;
  --line-soft: #1B151D;
  --text: #EDE9EC;
  --dim: #9B8F98;
  --faint: #6A5F68;
  --accent: #F2385A;
  --accent-wash: rgba(242, 56, 90, .10);
  --ok: #2FD3A5;
  --warn: #E8A33D;
  --strip: 60px;
  --rail: 258px;
  color-scheme: dark;
}

* { box-sizing: border-box; }

body {
  margin: 0; background: var(--bg); color: var(--text);
  font-family: "Be Vietnam Pro", ui-sans-serif, system-ui, -apple-system, sans-serif;
  font-size: 14px; line-height: 1.55; -webkit-font-smoothing: antialiased;
}

/* The glow behind the top of every page. Decorative, and the single thing
   that stops a very dark UI from reading as flat. */
body::before {
  content: ""; position: fixed; inset: 0 0 auto 0; height: 420px; pointer-events: none; z-index: 0;
  background:
    radial-gradient(900px 380px at 18% -12%, rgba(242,56,90,.13), transparent 70%),
    radial-gradient(700px 300px at 78% -18%, rgba(242,56,90,.08), transparent 70%);
}

.shell {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: var(--strip) var(--rail) minmax(0, 1fr);
  min-height: 100vh;
}

/* --------------------------------------------------------------- icon strip */
.strip {
  border-right: 1px solid var(--line); display: flex; flex-direction: column;
  align-items: center; gap: 6px; padding: 14px 0; background: rgba(0,0,0,.25);
}
.strip-mark { color: var(--accent); margin-bottom: 14px; }
.strip-btn {
  width: 34px; height: 34px; display: grid; place-items: center; cursor: pointer;
  border: 1px solid transparent; border-radius: 9px; background: none; color: var(--faint);
}
.strip-btn:hover { color: var(--text); background: var(--panel); }
.strip-btn.on { color: var(--accent); background: var(--accent-wash); border-color: rgba(242,56,90,.22); }

/* --------------------------------------------------------------------- rail */
.rail {
  border-right: 1px solid var(--line); padding: 16px 12px 14px;
  display: flex; flex-direction: column; gap: 2px;
  position: sticky; top: 0; align-self: start; max-height: 100vh; overflow-y: auto;
}
.rail .crumb {
  display: flex; align-items: center; gap: 4px; padding: 2px 10px 16px;
  font-family: "IBM Plex Mono", monospace; font-size: .62rem;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
}
.rail .crumb b { color: var(--accent); font-weight: 500; }
.rail .crumb .ic { opacity: .5; transform: rotate(-90deg); }

.rail-link {
  display: flex; align-items: center; gap: 11px; padding: 7px 11px;
  border-radius: 9px; color: var(--dim); cursor: pointer; border: 1px solid transparent;
  font-family: "IBM Plex Mono", monospace; font-size: .69rem;
  letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
  background: none; width: 100%; text-align: left;
}
/* A fixed box, not the glyph's own width. Line icons differ in how much of
   their viewBox they fill, so sizing to the drawing made the labels sit at
   four different distances from the edge. */
.rail-link .ic { flex: none; width: 17px; height: 17px; opacity: .72; }
.rail-link:hover { color: var(--text); background: var(--panel); }
.rail-link.on {
  color: var(--accent); background: var(--accent-wash);
  border-color: rgba(242,56,90,.26);
}
.rail-link.on .ic { opacity: 1; }
.rail-head { color: var(--dim); }
.rail-head .ic:last-child { margin-left: auto; opacity: .5; }
/* Indented under ACTIVITY, with no icons: the group header carries the icon
   and repeating one on every child turns a list into a wall. */
.rail-sub { display: flex; flex-direction: column; gap: 1px; padding-left: 22px; }
.rail-sub .rail-link { padding-left: 14px; }
.rail-foot { margin-top: auto; padding-top: 14px; border-top: 1px solid var(--line-soft); }
.rail-foot .count {
  margin-left: auto; font-style: normal; font-size: .62rem; color: var(--faint);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 5px; padding: 0 6px;
}

/* ------------------------------------------------------------------- topbar */
main { min-width: 0; display: flex; flex-direction: column; }
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 26px; border-bottom: 1px solid var(--line-soft);
}
.search { display: flex; align-items: center; gap: 9px; color: var(--faint); flex: 1; max-width: 520px; }
.search input {
  background: none; border: 0; color: var(--text); font: inherit; font-size: .92rem;
  outline: none; width: 100%;
}
.topbar-r { display: flex; align-items: center; gap: 12px; color: var(--faint); }
.icon-btn { background: none; border: 0; color: var(--faint); cursor: pointer; padding: 4px; }
.icon-btn:hover { color: var(--text); }
.avatar {
  width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center;
  background: linear-gradient(140deg, var(--accent), #7A1630); color: #fff;
  font-size: .76rem; font-weight: 600;
}

/* --------------------------------------------------------------- page head */
.page { padding: 26px 26px 80px; display: flex; flex-direction: column; gap: 18px; }
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.page-id { display: flex; align-items: center; gap: 15px; }
.page-avatar {
  width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--accent); flex: none;
}
.page-id h1 { margin: 0; font-size: 1.85rem; font-weight: 700; letter-spacing: -.025em; }
.page-id p {
  margin: 2px 0 0; color: var(--dim); font-family: "IBM Plex Mono", monospace; font-size: .8rem;
}

.controls { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.picker { position: relative; display: flex; align-items: center; }
.picker select {
  appearance: none; background: var(--panel); border: 1px solid var(--line);
  color: var(--text); border-radius: 8px; padding: 8px 34px 8px 13px;
  font: inherit; font-size: .84rem; cursor: pointer; min-width: 190px;
}
.picker .ic { position: absolute; right: 11px; pointer-events: none; color: var(--faint); }

.live {
  display: flex; align-items: center; gap: 7px; cursor: pointer;
  background: none; border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 13px; color: var(--faint);
  font-family: "IBM Plex Mono", monospace; font-size: .68rem; letter-spacing: .1em;
}
.live i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.live.on { color: var(--ok); border-color: rgba(47,211,165,.35); }
.live.on i { box-shadow: 0 0 8px rgba(47,211,165,.8); }

.ranges { display: flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.ranges button {
  background: none; border: 0; border-right: 1px solid var(--line); cursor: pointer;
  padding: 8px 13px; color: var(--faint);
  font-family: "IBM Plex Mono", monospace; font-size: .68rem; letter-spacing: .06em;
}
.ranges button:last-child { border-right: 0; }
.ranges button:hover { color: var(--text); }
.ranges button.on { color: var(--text); background: var(--panel-2); }
.ranges .cal { display: grid; place-items: center; }

/* -------------------------------------------------------------- filter chips */
.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  background: none; border: 1px dashed var(--line); border-radius: 8px;
  padding: 6px 12px; color: var(--dim); font: inherit; font-size: .82rem;
}
.chip i { font-style: normal; color: var(--faint); }
.chip:hover { border-style: solid; color: var(--text); }

/* The mark sits on the wordmark's baseline, not its box: optically centred on
   a lowercase x-height rather than vertically centred on the line. */
.lockup { display: flex; align-items: center; gap: 9px; }
.mark { color: var(--accent); flex: none; }
.brand span {
  font-family: "IBM Plex Mono", monospace; font-size: .62rem;
  letter-spacing: .13em; text-transform: uppercase; color: var(--accent);
}
/* ---- main ---- */
.top {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; padding: 26px 0 20px; border-bottom: 1px solid var(--line);
}
.top h1 { margin: 0; font-size: 1.85rem; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; }
.top p { margin: 4px 0 0; color: var(--dim); font-size: .92rem; }
.ranges { display: flex; gap: 3px; }
.ranges button {
  background: var(--panel); border: 1px solid var(--line); color: var(--dim);
  font-family: "IBM Plex Mono", monospace; font-size: .7rem; letter-spacing: .06em;
  padding: 6px 11px; cursor: pointer; text-transform: uppercase;
}
.ranges button:first-child { border-radius: 6px 0 0 6px; }
.ranges button:last-child { border-radius: 0 6px 6px 0; }
.ranges button.on { color: var(--accent); border-color: rgba(240,67,94,.35); background: var(--accent-wash); }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 11px; margin: 20px 0; }
.tile { background: var(--panel); border: 1px solid var(--line); border-radius: 9px; padding: 13px 15px; }
.tile .v { font-size: 1.5rem; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.tile .v.hot { color: var(--accent); }
.tile .v.good { color: var(--ok); }
.tile .k {
  font-family: "IBM Plex Mono", monospace; font-size: .61rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--faint); margin-top: 2px;
}

.card { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; margin: 14px 0; }
.card > h2 {
  margin: 0; padding: 14px 16px; border-bottom: 1px solid var(--line-soft);
  font-size: .98rem; font-weight: 600; display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
}
.card > h2 .sub {
  font-family: "IBM Plex Mono", monospace; font-size: .62rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--faint); font-weight: 400;
}
.card .body { padding: 14px 16px; }
.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 14px; }

/* ---- tables ---- */
.tw { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; font-size: .88rem; }
th {
  text-align: left; padding: 9px 14px; font-size: .61rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--faint); font-weight: 500;
  background: var(--panel-2); border-bottom: 1px solid var(--line); white-space: nowrap;
}
td { padding: 9px 14px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr.click { cursor: pointer; }
tbody tr.click:hover { background: var(--panel-2); }
td.n { text-align: right; font-variant-numeric: tabular-nums; font-family: "IBM Plex Mono", monospace; font-size: .83rem; white-space: nowrap; }
td.k { font-family: "IBM Plex Mono", monospace; font-size: .83rem; }
td.hot { color: var(--accent); }
.muted { color: var(--faint); }

.pill {
  display: inline-block; font-family: "IBM Plex Mono", monospace; font-size: .62rem;
  letter-spacing: .08em; padding: 2px 7px; border-radius: 4px; border: 1px solid; white-space: nowrap;
}
.pill.ok { color: var(--ok); border-color: rgba(53,214,160,.3); background: rgba(53,214,160,.08); }
.pill.bad { color: var(--accent); border-color: rgba(240,67,94,.32); background: var(--accent-wash); }
.pill.warn { color: var(--warn); border-color: rgba(232,163,61,.3); background: rgba(232,163,61,.08); }
.pill.flat { color: var(--dim); border-color: var(--line); background: var(--panel-2); }

/* proportion bar behind a number */
.bar { position: relative; background: var(--panel-2); border-radius: 3px; height: 5px; margin-top: 4px; overflow: hidden; }
.bar i { position: absolute; inset: 0 auto 0 0; background: var(--accent); border-radius: 3px; }
.bar i.calm { background: var(--ok); }

/* ---- charts ---- */
.chart { width: 100%; height: 150px; display: block; }
.chart.tall { height: 210px; }

/* ---- waterfall ---- */
.wf-row { display: grid; grid-template-columns: minmax(180px, 34%) 1fr minmax(96px, auto); gap: 12px; align-items: center; padding: 3px 0; }
.wf-name { font-family: "IBM Plex Mono", monospace; font-size: .78rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wf-track { position: relative; height: 17px; background: var(--panel-2); border-radius: 3px; }
.wf-bar { position: absolute; top: 2px; bottom: 2px; border-radius: 2px; background: #5A7FA8; min-width: 2px; }
.wf-bar.self { background: var(--accent); }
.wf-bar.database { background: #8A6BB8; }
.wf-bar.http { background: #3F8F7A; }
.wf-bar.manual { background: var(--warn); }
.wf-bar.err { background: var(--accent); box-shadow: 0 0 0 1px rgba(240,67,94,.5); }
.wf-ms { font-family: "IBM Plex Mono", monospace; font-size: .74rem; color: var(--text); text-align: right; font-variant-numeric: tabular-nums; }
.wf-self { display: block; font-size: .64rem; color: var(--faint); }

.legend { display: flex; gap: 14px; flex-wrap: wrap; font-family: "IBM Plex Mono", monospace; font-size: .64rem; color: var(--faint); letter-spacing: .06em; }
.legend span::before { content: ""; display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }
.legend .f::before { background: #5A7FA8; }
.legend .d::before { background: #8A6BB8; }
.legend .h::before { background: #3F8F7A; }
.legend .m::before { background: var(--warn); }

pre.stack {
  margin: 8px 0 0; padding: 12px; background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 7px; overflow-x: auto; font-family: "IBM Plex Mono", monospace;
  font-size: .74rem; line-height: 1.7; color: var(--dim); white-space: pre-wrap; word-break: break-word;
}

.empty { padding: 44px 16px; text-align: center; color: var(--faint); font-size: .9rem; }
.back { background: none; border: 0; color: var(--accent); cursor: pointer; font-family: "IBM Plex Mono", monospace; font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; padding: 0; margin-bottom: 12px; }

input.search {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
  color: var(--text); padding: 7px 11px; font: inherit; font-size: .86rem; min-width: 220px;
}
input.search:focus { outline: none; border-color: rgba(240,67,94,.4); }

.gate { max-width: 420px; margin: 14vh auto; }
.gate .card .body { display: flex; flex-direction: column; gap: 10px; }
.gate label { font-family: "IBM Plex Mono", monospace; font-size: .63rem; letter-spacing: .12em; text-transform: uppercase; color: var(--faint); }
.gate button {
  background: var(--accent-wash); border: 1px solid rgba(240,67,94,.35); color: var(--accent);
  border-radius: 6px; padding: 9px; cursor: pointer;
  font-family: "IBM Plex Mono", monospace; font-size: .74rem; letter-spacing: .1em; text-transform: uppercase;
}
.err-banner { background: var(--accent-wash); border: 1px solid rgba(240,67,94,.3); color: var(--accent); border-radius: 7px; padding: 11px 14px; margin: 14px 0; font-size: .88rem; }

@media (max-width: 860px) {
  .shell { grid-template-columns: 1fr; }
  .strip { display: none; }
  .rail { position: static; max-height: none; border-right: 0; border-bottom: 1px solid var(--line);
          display: flex; overflow-x: auto; padding: 12px 0; align-items: center; }
  .rail .crumb, .rail-foot, .rail-sub { display: none; }
  .rail-link { width: auto; white-space: nowrap; }
  main { padding-inline: 14px; }
  .wf-row { grid-template-columns: 1fr; gap: 3px; }
  .wf-ms { text-align: left; }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* ---- service map ----
   Columns, not a force-directed graph: a physics layout moves every node on
   every refresh, so nothing is where it was a moment ago. */
.map-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px; }
.map-head {
  font-family: "IBM Plex Mono", monospace; font-size: .62rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--faint); margin-bottom: 9px;
}
.map-node {
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2);
  padding: 11px 13px; margin-bottom: 9px; position: relative;
}
.map-name { font-family: "IBM Plex Mono", monospace; font-size: .86rem; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.map-meta { font-size: .78rem; color: var(--dim); margin-top: 3px; }
.map-kind {
  position: absolute; top: 10px; right: 12px;
  font-family: "IBM Plex Mono", monospace; font-size: .58rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--faint);
}
.map-link {
  display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  padding: 7px 0; border-top: 1px solid var(--line-soft); font-size: .84rem;
}
.map-link:first-of-type { border-top: 0; }
.map-arrow { color: var(--accent); }

/* The one place a secret is ever on screen. Loud on purpose: it exists once,
   and a person who scrolls past it has lost it. */
.note-secret {
  border: 1px solid var(--accent); background: var(--accent-wash);
  border-radius: 10px; padding: 16px; margin-bottom: 16px;
}
.note-secret .k {
  font-family: "IBM Plex Mono", monospace; font-size: .68rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 10px;
}
.note-secret pre { user-select: all; }
.inline-form { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.inline-form input {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px;
  padding: 7px 11px; color: var(--text); font-family: "IBM Plex Mono", monospace;
  font-size: .82rem; min-width: 220px;
}
.inline-form button { border: 1px solid var(--line); background: var(--panel-2); }
.card-hd-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.card-hd-row .grow { flex: 1; }
