/* ============================================================================
   6b6t tracker — "after the blast"

   Design notes, because the choices are deliberate:
   - The base is a dark, near-black concrete with a film of grain and CRT
     scanlines. That is the "destroyed" half: the surface looks worn, but the
     layout underneath is a tight, orderly grid. Chaos on top of structure is
     what reads as anarchy rather than as a mess.
   - One acid accent (--toxic) and two hazard tones (--amber, --ember) carry
     every highlight. Nothing else is allowed colour, so the eye always knows
     where the important number is.
   - Corners are cut, not rounded, and the cut is only on cards/tabs, never on
     the big panels. Rounded would read "modern app"; cutting everything reads
     "template". Cutting some of it reads "damaged".
   - No web fonts and no external requests: the container is on a LAN and the
     page must not depend on anyone else to render.
   ========================================================================= */

:root {
  /* surface */
  --ink:      #08090a;
  --ink-2:    #0c0d0f;
  --panel:    #101114;
  --panel-2:  #15161a;
  --well:     #0a0b0d;
  --line:     #24262b;
  --line-hot: #3a3d44;
  --char:     #1a1208;   /* burnt edge */

  /* type */
  --bone:     #e7e4dd;
  --ash:      #8d8a82;
  --dust:     #5d5b55;

  /* signal */
  --toxic:    #b8ff2f;
  --amber:    #ffb000;
  --ember:    #ff3d2e;
  --rust:     #8a4a20;

  --mono: ui-monospace, "Cascadia Mono", "JetBrains Mono", Consolas, monospace;
  --sans: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
}

* { box-sizing: border-box; }

::selection { background: var(--toxic); color: #06070a; }

html { scrollbar-color: #2c2f35 var(--ink); }

body {
  margin: 0;
  min-height: 100vh;
  color: var(--bone);
  background-color: var(--ink);
  background-image:
    /* faint toxic bloom in one corner, like a spill */
    radial-gradient(900px 520px at 12% -8%, rgba(184, 255, 47, 0.05), transparent 70%),
    /* ember glow bottom right */
    radial-gradient(760px 420px at 100% 108%, rgba(255, 61, 46, 0.05), transparent 70%),
    /* concrete mottling */
    repeating-linear-gradient(0deg, rgba(255,255,255,0.012) 0 1px, transparent 1px 3px);
  font: 13.5px/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
}

/* ---------------------------------------------------------------- fx layers
   Three fixed, non-interactive sheets over everything. Kept separate from the
   content so no panel has to know about them. */

.fx { position: fixed; inset: 0; pointer-events: none; z-index: 9999; }

.fx.scanlines {
  background: repeating-linear-gradient(
    180deg,
    rgba(0, 0, 0, 0)    0px,
    rgba(0, 0, 0, 0)    2px,
    rgba(0, 0, 0, 0.22) 3px,
    rgba(0, 0, 0, 0)    4px
  );
  opacity: 0.5;
  mix-blend-mode: multiply;
}

.fx.grain {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.05;
  mix-blend-mode: overlay;
}

.fx.vignette {
  background: radial-gradient(120% 90% at 50% 40%, transparent 45%, rgba(0,0,0,0.55) 100%);
}

/* ------------------------------------------------------------------ header */

header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 22px;
  padding: 14px 24px 12px;
  background: linear-gradient(180deg, rgba(8,9,10,0.97), rgba(8,9,10,0.86));
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(8px);
}

h1 {
  margin: 0;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--bone);
  /* the chromatic split is the whole glitch effect: red and cyan copies
     offset by a pixel, only visible as a smear at the edges */
  text-shadow:
    -1px 0 rgba(255, 61, 46, 0.55),
     1px 0 rgba(0, 255, 255, 0.35);
  animation: h1-glitch 9s steps(1) infinite;
}

h1 span { color: var(--toxic); text-shadow: 0 0 14px rgba(184,255,47,0.35); }

/* Long, mostly-idle cycle: it should catch your eye once in a while, not
   strobe. Most frames do nothing at all. */
@keyframes h1-glitch {
  0%, 96%  { transform: translate(0, 0);    text-shadow: -1px 0 rgba(255,61,46,0.55), 1px 0 rgba(0,255,255,0.35); }
  96.5%    { transform: translate(-2px, 1px); text-shadow: 2px 0 rgba(255,61,46,0.9), -2px 0 rgba(0,255,255,0.7); }
  97%      { transform: translate(2px, -1px); text-shadow: -2px 0 rgba(255,61,46,0.9), 2px 0 rgba(0,255,255,0.7); }
  97.5%    { transform: translate(0, 0);    text-shadow: -1px 0 rgba(255,61,46,0.55), 1px 0 rgba(0,255,255,0.35); }
  99%      { transform: translate(1px, 0);  text-shadow: -3px 0 rgba(255,61,46,0.8), 1px 0 rgba(0,255,255,0.5); }
  99.5%    { transform: translate(0, 0);    text-shadow: -1px 0 rgba(255,61,46,0.55), 1px 0 rgba(0,255,255,0.35); }
}

header .sub {
  color: var(--ash);
  font: 11px/1.4 var(--mono);
  letter-spacing: 0.06em;
}
header .grow { flex: 1; }

.live {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 13px;
  font: 10.5px/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bone);
  background: var(--well);
  border: 1px solid var(--line-hot);
  clip-path: polygon(7px 0, 100% 0, calc(100% - 7px) 100%, 0 100%);
}

.dot {
  width: 7px; height: 7px;
  background: var(--toxic);
  box-shadow: 0 0 9px var(--toxic);
  animation: pulse 2.4s ease-in-out infinite;
}
.dot.stale { background: var(--ember); box-shadow: 0 0 9px var(--ember); animation: none; }

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

/* hazard tape under the header — the cheapest, clearest anarchy signal there is */
.tape {
  height: 7px;
  background: repeating-linear-gradient(
    -45deg,
    var(--amber) 0 9px,
    #0b0b0d 9px 18px
  );
  opacity: 0.55;
  border-bottom: 1px solid #000;
}

/* ------------------------------------------------------------------ ticker */

.ticker {
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background: var(--well);
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
}

.ticker-inner {
  display: flex;
  white-space: nowrap;
  animation: marquee 55s linear infinite;
  will-change: transform;
}
/* padding rather than flex gap: two identical copies plus one gap make the
   -50% translate land exactly on a copy boundary, so the loop has no seam */
.ticker-inner span {
  padding: 7px 0 7px 0;
  padding-right: 70px;
  font: 10.5px/1 var(--mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  /* --dust was too dim to read at this size against the well */
  color: var(--ash);
}
.ticker-inner b { color: var(--toxic); font-weight: 700; }
.ticker-inner i { color: var(--amber); font-style: normal; }
.ticker-inner .sep { color: #2c2f35; }

@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* -------------------------------------------------------------------- main */

main {
  max-width: 1560px;
  margin: 0 auto;
  padding: 20px 24px 90px;
}

a { color: var(--toxic); text-decoration: none; border-bottom: 1px dashed rgba(184,255,47,0.4); }
a:hover { background: rgba(184,255,47,0.09); border-bottom-style: solid; }

/* -------------------------------------------------------------- stat cards */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
  gap: 12px;
  margin-bottom: 22px;
}

/* The two site counters get a row of their own on a wide screen. They describe this
   page rather than 6b6t, and at the grid's normal card width they simply wrapped into
   the middle of the bot's numbers, which read as a layout accident instead of a group.
   Below the wide-screen breakpoint they behave like every other card. */
@media (min-width: 900px) {
  .card.site { grid-column: span 4; }
}

.card {
  position: relative;
  padding: 13px 15px 14px;
  background:
    linear-gradient(160deg, var(--panel-2), var(--panel) 65%),
    var(--panel);
  border: 1px solid var(--line);
  border-top-color: #2b2e34;
  /* cut corners instead of rounded ones */
  clip-path: polygon(0 0, calc(100% - 11px) 0, 100% 11px, 100% 100%, 11px 100%, 0 calc(100% - 11px));
  overflow: hidden;
}

/* an acid sliver that grows on hover: the card feels like it is cracking open */
.card::before {
  content: "";
  position: absolute;
  left: 0; top: 12px;
  width: 2px; height: 18px;
  background: var(--toxic);
  box-shadow: 0 0 10px rgba(184,255,47,0.6);
  transition: height 180ms ease;
}
.card:hover::before { height: calc(100% - 24px); }

.card .k {
  color: var(--dust);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.19em;
}
.card .v {
  margin-top: 5px;
  font: 800 25px/1.05 var(--mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--bone);
  text-shadow: 0 0 22px rgba(184,255,47,0.13);
}
.card .n { margin-top: 4px; color: var(--dust); font-size: 10.5px; }

/* ----------------------------------------------------------------- section */

section {
  position: relative;
  padding: 15px 17px 17px;
  margin-bottom: 18px;
  background: var(--panel);
  border: 1px solid var(--line);
}

/* A scorched, uneven strip along the top of every panel. Hard colour stops, not
   a smooth fade: a gradient that eases looks like a design flourish, while hard
   stops read as damage. */
section::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: -1px;
  height: 4px;
  background: linear-gradient(90deg,
    transparent 0 3%,
    #4a2c12 3% 9%,
    transparent 9% 17%,
    rgba(255, 176, 0, 0.75) 20% 25%,
    transparent 25% 38%,
    #33200d 41% 50%,
    transparent 50% 61%,
    rgba(255, 61, 46, 0.5) 65% 69%,
    transparent 69% 80%,
    #4a2c12 84% 91%,
    transparent 91% 100%);
  opacity: 0.9;
}

section > h2 {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 9px;
  margin: 0 0 13px;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--bone);
}

/* the little hazard chip before each heading */
section > h2::before {
  content: "";
  width: 9px; height: 9px;
  background: repeating-linear-gradient(-45deg, var(--toxic) 0 2px, #0b0b0d 2px 4px);
  flex: none;
}

section > h2 .note {
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.02em;
  font-size: 11px;
  color: var(--dust);
}
section > h2 .grow { flex: 1; }

.cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 18px; }

/* Panels in a row share a height, so a short one leaves a hole beside a tall
   neighbour. Making the panel a flex column and letting its last block grow
   fills that space instead — which is why the population chart stretches to
   stand as tall as the two chat charts next to it. */
.cols > section { display: flex; flex-direction: column; }
.cols > section > div:last-child { flex: 1 1 auto; min-height: 0; }
#popChart > div { height: 100%; }
#popChart .chart { height: 100%; min-height: 170px; }

/* ------------------------------------------------------------------ tables */

table { width: 100%; border-collapse: collapse; font-size: 12.5px; }

th, td { padding: 6px 9px; text-align: left; }

th {
  color: var(--dust);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  border-bottom: 1px solid var(--line-hot);
}

tbody tr { border-bottom: 1px dashed #1d1f23; }
tbody tr:hover { background: linear-gradient(90deg, rgba(184,255,47,0.07), rgba(184,255,47,0.01) 40%, transparent); }
tbody tr:hover td:first-child { box-shadow: inset 2px 0 0 var(--toxic); }

td.num, th.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
td.name { font-weight: 700; letter-spacing: 0.01em; }

/* -------------------------------------------------------------------- tags */

.tag {
  display: inline-block;
  padding: 1px 7px;
  font: 700 10.5px/1.6 var(--mono);
  letter-spacing: 0.06em;
  background: var(--well);
  border: 1px solid var(--line-hot);
  clip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%);
}

/* ------------------------------------------------------------------- chips */

.chips { display: flex; flex-wrap: wrap; gap: 6px; }

.chip {
  padding: 3px 10px;
  font: 11.5px/1.5 var(--mono);
  background: var(--well);
  border: 1px solid var(--line);
  border-left: 2px solid var(--line-hot);
}
.chip:hover { border-color: var(--line-hot); border-left-color: var(--toxic); background: #0e1013; }
.chip small { margin-left: 7px; color: var(--dust); }

/* -------------------------------------------------------------- bar charts */

.bars { display: grid; gap: 5px; }

.bar {
  display: grid;
  grid-template-columns: 118px 1fr 52px;
  align-items: center;
  gap: 9px;
  font: 11.5px/1.4 var(--mono);
}
.bar .label { color: var(--bone); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar .track {
  position: relative;
  height: 14px;
  background: var(--well);
  border: 1px solid var(--line);
  overflow: hidden;
}
.bar .fill {
  height: 100%;
  background: linear-gradient(90deg, var(--toxic), var(--amber) 70%, var(--ember));
  box-shadow: 0 0 12px rgba(184,255,47,0.25);
  /* a torn tip rather than a rounded end — one clean notch, not a mess */
  clip-path: polygon(0 0, 100% 0, calc(100% - 5px) 50%, 100% 100%, 0 100%);
}
.bar .n { text-align: right; color: var(--ash); font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------- chat feed */

.feed {
  display: grid;
  gap: 2px;
  max-height: 430px;
  overflow: auto;
  padding-right: 4px;
  font: 12.5px/1.55 var(--mono);
  background: var(--well);
  border: 1px solid var(--line);
  padding: 9px 11px;
}
.feed .line { padding: 2px 5px; border-left: 2px solid transparent; }
.feed .line:hover { background: rgba(255,255,255,0.03); border-left-color: var(--amber); }
.feed .t { margin-right: 8px; color: var(--dust); font-size: 10.5px; font-variant-numeric: tabular-nums; }
.feed .u { font-weight: 700; color: var(--bone); }
.feed .w { color: var(--amber); }
.feed.observe .line.observed .u { color: var(--ember); }

/* ------------------------------------------------------------------- tabs */

.tabs { display: flex; flex-wrap: wrap; gap: 5px; }

.tab {
  cursor: pointer;
  padding: 4px 13px;
  font: 600 10.5px/1.5 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ash);
  background: var(--well);
  border: 1px solid var(--line);
  clip-path: polygon(5px 0, 100% 0, calc(100% - 5px) 100%, 0 100%);
  transition: color 120ms ease, background 120ms ease, border-color 120ms ease;
}
.tab:hover { color: var(--bone); border-color: var(--line-hot); }
.tab.on {
  color: #06070a;
  background: var(--toxic);
  border-color: var(--toxic);
  font-weight: 800;
  box-shadow: 0 0 18px rgba(184,255,47,0.3);
}

/* ------------------------------------------------------------------ charts */

.chart {
  display: block;
  width: 100%;
  height: 190px;
  background: var(--well);
  border: 1px solid var(--line);
}
.chart .grid { stroke: #1e2126; stroke-width: 1; stroke-dasharray: 2 4; }
.chart .area { fill: rgba(184, 255, 47, 0.10); }
.chart .line { fill: none; stroke: var(--toxic); stroke-width: 1.8; filter: drop-shadow(0 0 4px rgba(184,255,47,0.45)); }
.chart text { fill: var(--dust); font: 10px var(--mono); letter-spacing: 0.05em; }

/* ------------------------------------------------------------------ misc */

/* the tape turns from hazard-yellow to alarm-red when the bot is not running,
   which is the one state that makes every number on the page out of date */
body.bot-down .tape {
  background: repeating-linear-gradient(-45deg, var(--ember) 0 9px, #0b0b0d 9px 18px);
  opacity: 0.8;
}

footer {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 24px;
  padding: 14px 2px 0;
  border-top: 1px solid var(--line);
  color: var(--dust);
  font: 10.5px/1.6 var(--mono);
  letter-spacing: 0.13em;
  text-transform: uppercase;
}
footer .sep { color: #2c2f35; }

.muted { color: var(--ash); }
.mono { font-family: var(--mono); }
.empty {
  padding: 7px 0;
  color: var(--dust);
  font: 11.5px/1.5 var(--mono);
  letter-spacing: 0.04em;
}

/* scrollbars: the page is long and the default one looks pasted on */
*::-webkit-scrollbar { width: 11px; height: 11px; }
*::-webkit-scrollbar-track { background: var(--ink); }
*::-webkit-scrollbar-thumb {
  background: #2a2d33;
  border: 2px solid var(--ink);
}
*::-webkit-scrollbar-thumb:hover { background: var(--toxic); }

/* ------------------------------------------------------------ responsive */

@media (max-width: 700px) {
  main { padding: 16px 12px 60px; }
  header { padding: 12px 14px 10px; }
  .cols { grid-template-columns: 1fr; }
  .bar { grid-template-columns: 86px 1fr 42px; }
  .card .v { font-size: 21px; }
}

/* ------------------------------------------------------- motion and print */

@media (prefers-reduced-motion: reduce) {
  h1 { animation: none; }
  .dot { animation: none; }
  .ticker-inner { animation: none; }
  .card::before { transition: none; }
}

@media print {
  .fx, .tape, .ticker { display: none; }
  body { background: #fff; color: #000; }
  section, .card { border-color: #999; background: #fff; }
  section::before { display: none; }
}

/* ------------------------------------------------ server-rendered snapshot

   Only crawlers, unfurlers and clients without JavaScript ever receive this block, and they
   get it INSTEAD of the panels below, which that response leaves empty. So it has to read
   well on its own rather than look like a fallback. app.js deletes it once the live figures
   are drawn, so a person never sees both. */

#ssr { border-color: var(--line-hot); }
#ssr > p { color: var(--dust); font-size: 12px; line-height: 1.65; margin: 10px 0 16px; }
#ssr > h3 {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--bone);
  margin: 20px 0 6px;
}
#ssr ul { margin: 0; padding-left: 18px; }
#ssr li { font-size: 12.5px; line-height: 1.75; }
#ssr li::marker { color: var(--toxic); }
#ssr small { color: var(--dust); font-size: 11px; }
#ssr caption {
  caption-side: top;
  text-align: left;
  color: var(--dust);
  font-size: 11px;
  line-height: 1.5;
  padding: 0 0 8px;
}

/* ------------------------------------------------------------------ views

   One long column of panels is the whole page; a view is a different set of them.
   Only the active one is in the flow, and it animates in rather than swapping, because
   a silent replacement of a screenful of figures reads as a glitch. */

/* Shared SVG defs. Kept rendered (not `display: none`) and out of the flow, because a
   gradient inside a hidden subtree paints as nothing. */
.svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; pointer-events: none; }

.view { display: none; }
.view.on { display: block; animation: view-in 0.34s cubic-bezier(0.2, 0.9, 0.3, 1) both; }

@keyframes view-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------- sidebar

   A drawer, not a docked rail: the page is a column of panels and the views are whole
   pages of figures, so the navigation is something to open, use and get out of the way.
   It slides instead of fading because a slide reads as a panel that was always there and
   got pushed aside, which is what the rest of the surface pretends to be. */

.nav-toggle {
  position: relative;
  z-index: 70;
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 34px;
  height: 30px;
  margin-right: 12px;
  padding: 0 7px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  cursor: pointer;
}
.nav-toggle i {
  display: block;
  height: 2px;
  background: var(--bone);
  transition: transform 0.34s cubic-bezier(0.3, 1.4, 0.4, 1), opacity 0.2s ease, background 0.2s ease;
}
.nav-toggle:hover { border-color: var(--toxic); }
.nav-toggle:hover i { background: var(--toxic); }
.nav-toggle.on i:nth-child(1) { transform: translateY(6px) rotate(45deg); background: var(--toxic); }
.nav-toggle.on i:nth-child(2) { opacity: 0; transform: scaleX(0.2); }
.nav-toggle.on i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); background: var(--toxic); }

.nav {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 60;
  width: min(340px, 88vw);
  padding: 16px 0 14px;
  overflow-y: auto;
  background: linear-gradient(180deg, #0d0e11, #0a0b0e 60%, #0c0d10);
  border-right: 1px solid var(--line-hot);
  box-shadow: 26px 0 60px rgba(0, 0, 0, 0.6);
  transform: translateX(-102%);
  transition: transform 0.42s cubic-bezier(0.16, 1, 0.3, 1);
}
.nav.open { transform: none; }
/* A single toxic sweep down the edge while it opens: the one piece of motion on the page
   that draws the eye, aimed where the new content appears. */
.nav::after {
  content: "";
  position: absolute;
  top: 0;
  right: -1px;
  width: 2px;
  height: 100%;
  background: linear-gradient(180deg, transparent, var(--toxic), transparent);
  opacity: 0;
}
.nav.open::after { animation: nav-sweep 0.9s ease-out 0.1s 1; }
@keyframes nav-sweep {
  0%   { opacity: 0; transform: translateY(-100%); }
  30%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(100%); }
}

.nav-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 4px 18px 14px;
  margin-bottom: 6px;
  border-bottom: 1px dashed #1d1f23;
}
.nav-title { font: 700 15px/1 var(--sans); letter-spacing: 0.02em; }
.nav-title span { color: var(--toxic); }
.nav-sub {
  color: var(--dust);
  font: 10px var(--mono);
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.nav-item {
  position: relative;
  display: grid;
  grid-template-columns: 34px 1fr;
  grid-template-rows: auto auto;
  gap: 0 10px;
  padding: 10px 18px;
  color: var(--ash);
  text-decoration: none;
  border-left: 2px solid transparent;
  opacity: 0;
  transform: translateX(-16px);
  transition: opacity 0.3s ease, transform 0.36s cubic-bezier(0.2, 0.9, 0.3, 1),
    background 0.2s ease, color 0.2s ease;
}
.nav.open .nav-item { opacity: 1; transform: none; }
/* Staggered, so the list arrives as a list rather than as one block. */
.nav.open .nav-item:nth-of-type(1) { transition-delay: 0.05s; }
.nav.open .nav-item:nth-of-type(2) { transition-delay: 0.1s; }
.nav.open .nav-item:nth-of-type(3) { transition-delay: 0.15s; }
.nav.open .nav-item:nth-of-type(4) { transition-delay: 0.2s; }
.nav-item:hover { background: rgba(255, 255, 255, 0.035); color: var(--bone); }
.nav-item .idx {
  grid-row: 1 / span 2;
  align-self: center;
  color: var(--dust);
  font: 11px var(--mono);
  transition: color 0.2s ease;
}
.nav-item .lbl { font-weight: 700; font-size: 13.5px; }
.nav-item .hint {
  grid-column: 2;
  color: var(--dust);
  font: 10.5px/1.5 var(--mono);
  letter-spacing: 0.03em;
}
.nav-item.on { color: var(--bone); border-left-color: var(--toxic); background: rgba(184, 255, 47, 0.05); }
.nav-item.on .idx { color: var(--toxic); }
.nav-item.on .lbl { text-shadow: 0 0 14px rgba(184, 255, 47, 0.35); }

.nav-foot {
  margin-top: auto;
  padding: 14px 18px 0;
  border-top: 1px dashed #1d1f23;
  color: var(--dust);
  font: 10.5px/1.7 var(--mono);
  letter-spacing: 0.06em;
}

.nav-scrim {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: rgba(4, 5, 6, 0.66);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.nav-scrim.on { opacity: 1; }

/* ------------------------------------------------- the big zoomable charts */

.chart.big { height: 340px; }
.chart.big .line { stroke-width: 2.1; }
.chart .band { fill: rgba(184, 255, 47, 0.09); stroke: none; }
.chart .ev-outage { fill: rgba(255, 61, 46, 0.13); stroke: rgba(255, 61, 46, 0.45); stroke-width: 1; }
.chart .ev-unobserved { fill: rgba(255, 255, 255, 0.045); stroke: rgba(255, 255, 255, 0.13); stroke-width: 1; stroke-dasharray: 3 4; }
/* The markers need an explicit fill: an SVG rect with no fill is painted solid black, and a
   solid black column through the middle of a chart is the opposite of a marker. */
.chart .ev-restart { fill: rgba(184, 255, 47, 0.17); stroke: var(--toxic); stroke-width: 1.2; }
.chart .ev-restart.approx { fill: rgba(255, 176, 0, 0.13); stroke: var(--amber); stroke-dasharray: 3 3; }
/* the commands line, over the messages area: different tone, no glow, thinner */
.chart .line.alt { stroke: var(--amber); stroke-width: 1.4; filter: none; opacity: 0.9; }
.chart .ev-dot { fill: var(--toxic); }
.chart .ev-dot.approx { fill: var(--amber); }
.chart .hit { fill: transparent; }
.chart .line.draw {
  stroke-dasharray: var(--len, 0);
  stroke-dashoffset: var(--len, 0);
  animation: draw-line 1.15s cubic-bezier(0.3, 0.9, 0.3, 1) forwards;
}
@keyframes draw-line { to { stroke-dashoffset: 0; } }

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin: 10px 0 0;
  color: var(--ash);
  font: 10.5px var(--mono);
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.legend i { display: inline-block; width: 16px; height: 3px; margin-right: 7px; vertical-align: middle; }
.legend i.restart { background: var(--toxic); }
.legend i.approx { background: repeating-linear-gradient(90deg, var(--amber) 0 3px, transparent 3px 6px); }
.legend i.outage { background: rgba(255, 61, 46, 0.55); }
.legend i.gap { background: repeating-linear-gradient(90deg, rgba(255,255,255,0.25) 0 3px, transparent 3px 6px); }
.legend i.band { background: rgba(184, 255, 47, 0.28); }

.hint {
  margin: 12px 0 0;
  color: var(--dust);
  font: 11px/1.75 var(--mono);
  letter-spacing: 0.03em;
}

/* ------------------------------------------------------- the accounts view */

.acct-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 2px 0 12px; }
.acct-bar input[type="search"] {
  flex: 1 1 220px;
  max-width: 330px;
  padding: 7px 10px;
  color: var(--bone);
  background: var(--well);
  border: 1px solid var(--line);
  font: 12px var(--mono);
}
.acct-bar input[type="search"]:focus {
  outline: none;
  border-color: var(--toxic);
  box-shadow: 0 0 0 1px rgba(184, 255, 47, 0.25);
}
.btn {
  padding: 7px 12px;
  color: var(--ash);
  background: var(--panel-2);
  border: 1px solid var(--line);
  font: 10.5px var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease;
}
.btn:hover { color: var(--bone); border-color: var(--line-hot); }
.btn:disabled { opacity: 0.35; cursor: default; }
.acct-more { margin-top: 12px; }
tr.online-now td:first-child { box-shadow: inset 2px 0 0 var(--toxic); }
td .dot.inline {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--toxic);
  box-shadow: 0 0 7px var(--toxic);
}
.feed.big { max-height: 540px; }

/* --------------------------------------------------- motion and responsive */

@media (max-width: 700px) {
  .chart.big { height: 240px; }
  .legend { gap: 4px 12px; font-size: 9.5px; }
  .nav-toggle { margin-right: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  .nav { transition: none; }
  .nav-item { transition: none; opacity: 1; transform: none; }
  .view.on { animation: none; }
  .chart .line.draw { animation: none; stroke-dasharray: none; stroke-dashoffset: 0; }
  .nav.open::after { animation: none; }
}

@media print {
  .nav, .nav-scrim, .nav-toggle { display: none; }
}
