/* ============================================================================
   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; }
}
