@font-face {
  font-family: 'JetBrains Mono';
  src: url('/fonts/JetBrainsMono-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}

:root {
  --bg:        #0a0e14;
  --bg-panel:  #11161e;
  --bg-row:    #161c26;
  --bg-hover:  #1e2632;
  --border:    #2a2f38;
  --fg:        #c9d1d9;
  --fg-dim:    #6e7681;
  --amber:     #ffb000;
  --green:     #4ade80;
  --red:       #f87171;
  --cyan:      #60d4ff;
  --magenta:   #d977c5;
  --flash:     rgba(255,176,0,0.35);
  --row-h: 18px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  width: 100%; height: 100%;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px; line-height: 1.4;
  background: var(--bg); color: var(--fg);
  overflow: hidden;
}

body {
  display: grid;
  grid-template-rows: 28px auto 1fr 1fr 56px 200px;
  grid-template-areas:
    "hdr       hdr       hdr       hdr"
    "agg       agg       agg       agg"
    "strategies strategies radar   radar"
    "positions positions  radar   radar"
    "heat      heat       heat    heat"
    "telem     daily      stratum tape";
  grid-template-columns: 1fr 1fr 0.8fr 1.4fr;
  gap: 1px;
  background: var(--border);
}

#hdr {
  grid-area: hdr;
  display: flex; align-items: center; gap: 10px;
  padding: 0 10px;
  background: var(--bg-panel);
  font-size: 12px; font-weight: 400;
  white-space: nowrap;
}

#hdr .brand { color: var(--amber); font-weight: 700; letter-spacing: 0.5px; }
#hdr .sep   { color: var(--fg-dim); }
#hdr .dot   { color: var(--green); }
#hdr.ws-down .dot, #hdr-status.status-down { color: var(--red); }
#hdr.ws-reconn .dot { color: var(--magenta); }
#hdr-mode { color: var(--amber); }
#hdr-clock { color: var(--cyan); }
#hdr-pnl { color: var(--green); }
#hdr-pnl.neg { color: var(--red); }
#hdr-status { margin-left: auto; padding: 2px 8px; color: var(--green); }
#hdr-status.status-stale { color: var(--amber); }
#hdr-status.status-down  { color: var(--red); }

#agg-strip        { grid-area: agg; }
#panel-strategies { grid-area: strategies; }
#panel-positions  { grid-area: positions; }
#radar            { grid-area: radar; }
#heat             { grid-area: heat; }
#telem            { grid-area: telem; }
#daily            { grid-area: daily; }
#stratum          { grid-area: stratum; }
#tape             { grid-area: tape; }

.panel {
  background: var(--bg-panel);
  display: flex; flex-direction: column;
  overflow: hidden;
  min-height: 0;
}
.panel h2 {
  font-size: 10px; font-weight: 700; letter-spacing: 1px;
  color: var(--amber);
  padding: 4px 8px;
  border-bottom: 1px solid var(--border);
  background: #0d1219;
  display: flex; justify-content: space-between; align-items: center;
}
.panel h2 .hint {
  font-weight: 400; color: var(--fg-dim); letter-spacing: 0;
  text-transform: none;
}

/* Tables */
.tbl-wrap { flex: 1; overflow: auto; }
.tbl {
  width: 100%; border-collapse: collapse;
  font-size: 11px;
}
.tbl th {
  position: sticky; top: 0;
  background: #0d1219;
  color: var(--fg-dim);
  text-align: right;
  font-weight: 400;
  padding: 2px 6px;
  border-bottom: 1px solid var(--border);
}
.tbl th.q, .tbl td.q { text-align: left; }
.tbl td {
  padding: 1px 6px;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border-bottom: 1px solid #1a1f29;
  height: var(--row-h);
}
.tbl td.q { max-width: 0; width: 100%; }
.tbl tbody tr:hover { background: var(--bg-hover); }

.num { color: var(--cyan); font-variant-numeric: tabular-nums; }
.num.pos { color: var(--green); }
.num.neg { color: var(--red); }
.t { color: var(--fg-dim); }
.paired.yes { color: var(--green); }
.paired.no  { color: var(--red); }

/* Flash on update */
@keyframes flash {
  0%   { background: var(--flash); }
  100% { background: transparent; }
}
.flash { animation: flash 220ms ease-out; }

/* Heatmap */
#heat { display: flex; flex-direction: column; }
#heat-strip {
  flex: 1;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  grid-template-rows: 1fr;
  gap: 1px;
  padding: 4px 8px;
  background: var(--bg-panel);
}
.cell {
  background: var(--fg-dim);
  cursor: default;
  border-radius: 0;
  transition: filter 120ms;
  min-width: 4px;
}
.cell:hover { filter: brightness(1.4); outline: 1px solid var(--amber); }
.tip {
  position: fixed;
  background: #000; color: var(--fg);
  border: 1px solid var(--amber);
  padding: 4px 8px;
  font-size: 11px; line-height: 1.4;
  pointer-events: none;
  z-index: 10;
  max-width: 360px;
}

/* Definition lists for telem/daily/stratum */
dl { padding: 4px 8px; flex: 1; }
dl > div { display: flex; justify-content: space-between; padding: 2px 0;
           border-bottom: 1px dashed #1a1f29; }
dl dt { color: var(--fg-dim); }
dl dd { color: var(--cyan); font-variant-numeric: tabular-nums; }
dl dd.ok { color: var(--green); }
dl dd.warn { color: var(--amber); }
dl dd.bad { color: var(--red); }

#daily-spark {
  width: 100%; height: 40px;
  padding: 0 8px 6px;
  display: block;
}
#daily-spark .bar { fill: var(--amber); }

/* Tape */
#tape-body {
  list-style: none;
  flex: 1; overflow: auto;
  padding: 2px 0;
  font-size: 11px;
}
#tape-body li {
  display: grid;
  grid-template-columns: 64px 48px 1fr;
  gap: 6px;
  padding: 1px 8px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#tape-body li:hover { background: var(--bg-hover); }
#tape-body li .t    { color: var(--fg-dim); }
#tape-body li .kind { color: var(--magenta); text-transform: uppercase; }
#tape-body li .msg  { color: var(--fg); overflow: hidden; text-overflow: ellipsis; }
#tape-body li.warn  .msg { color: var(--amber); }
#tape-body li.error .msg { color: var(--red); }
#tape-body li.opp   .kind { color: var(--green); }

/* Aggregate strip */
.agg-strip {
  display: flex;
  gap: 1rem;
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg-panel);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.8rem;
}
.agg-cell { display: inline-flex; gap: 0.4rem; align-items: center; }
.agg-l { color: var(--fg-dim); }

/* === Mobile / standalone-PWA layout =======================================
   Triggers on narrow widths and on short (landscape-phone) heights, where the
   dense fixed desktop grid has no room. Replaces the clipped grid with a
   single scrollable column of cards and honours iOS safe-area insets. */
@media (max-width: 820px), (max-height: 540px) {
  html, body {
    height: auto;
    min-height: 100vh;
    min-height: 100dvh;
    overflow: visible;
  }
  body {
    display: flex;
    flex-direction: column;
    gap: 0;
    background: var(--bg);
    /* Side + bottom safe areas (notch in landscape, home indicator). */
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
    padding-bottom: env(safe-area-inset-bottom);
  }

  /* Header becomes a wrapping status bar; clears the translucent iOS status
     bar via the top safe-area inset. */
  #hdr {
    flex-wrap: wrap;
    height: auto;
    row-gap: 2px;
    column-gap: 8px;
    padding: 6px 10px;
    padding-top: calc(6px + env(safe-area-inset-top));
    position: sticky;
    top: 0;
    z-index: 5;
    border-bottom: 1px solid var(--border);
  }
  #hdr .sep { display: none; }
  #hdr-status { margin-left: auto; }

  .agg-strip { flex-wrap: wrap; row-gap: 4px; column-gap: 1rem; }

  /* Panels become natural-height cards; tall ones cap and scroll internally. */
  .panel {
    flex: none;
    overflow: visible;
    border-top: 1px solid var(--border);
  }
  .tbl-wrap { max-height: 60vh; -webkit-overflow-scrolling: touch; }
  #tape-body { max-height: 55vh; -webkit-overflow-scrolling: touch; }

  /* Heatmap reflows from one thin row into a wrapping grid of squares. */
  #heat-strip {
    grid-auto-flow: row;
    grid-template-rows: none;
    grid-auto-rows: 14px;
    grid-template-columns: repeat(auto-fill, minmax(12px, 1fr));
    gap: 2px;
    max-height: 40vh;
    overflow: auto;
    -webkit-overflow-scrolling: touch;
  }
  .cell { min-width: 0; }
}
