/*
 * The dashboard's whole stylesheet. One reader, no framework, and no
 * JavaScript anywhere — the Gemfile leaves out importmap, turbo and stimulus
 * deliberately, because this surface is read rather than operated.
 */

:root {
  --ink: #1c1c1c;
  --muted: #6b6b6b;
  --rule: #ddd;
  --bad: #a11;
  --warn: #8a6d1f;
  --ask: #1a6ea8;
  --assert: #2f7d4f;
  --bad-bg: #fdf0f0;
  --paper: #fff;
  --bar-bg: #f4f4f6;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #e6e6e6;
    --muted: #9a9a9a;
    --rule: #3a3a3a;
    --bad: #ff8a80;
    --warn: #d8b45a;
    --ask: #6fb6e8;
    --assert: #6cc48c;
    --bad-bg: #2a1717;
    --paper: #161616;
    --bar-bg: #1e1e22;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 15px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

header {
  padding: 1rem 1.5rem;
  border-bottom: 1px solid var(--rule);
  display: flex;
  align-items: baseline;
  gap: 1.5rem;
}

/* One archive per page, named. The current one is underlined as well as
   brightened, so the distinction does not rest on colour alone. */
header nav {
  display: flex;
  gap: 1rem;
}

header nav a {
  color: var(--muted);
  text-decoration: none;
}

header nav a[aria-current="page"] {
  color: inherit;
  text-decoration: underline;
}

main {
  padding: 1.5rem;
}

a { color: inherit; }

h1 { font-size: 1.4rem; margin: 0 0 .5rem; }
h2 { font-size: 1.1rem; margin: 2rem 0 .5rem; }
h3 { font-size: 1rem; margin: 1.5rem 0 .5rem; }

/* Prose rather than a table cell, so it wraps — `th, td` sets nowrap. */
.note { max-width: 60rem; font-size: .85rem; }

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

table {
  border-collapse: collapse;
  width: 100%;
  margin-bottom: 1rem;
}

th, td {
  border-bottom: 1px solid var(--rule);
  padding: .35rem .6rem;
  text-align: left;
  white-space: nowrap;
}

th { color: var(--muted); font-weight: normal; }

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

td.error { white-space: normal; color: var(--bad); }

tr.bad { background: var(--bad-bg); }
tr.bad td { color: var(--bad); }

.totals {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin: 0 0 1rem;
}

.totals dt { color: var(--muted); font-size: .85rem; }
.totals dd { margin: 0; }

.last-run.bad { color: var(--bad); }

.pages { display: flex; gap: 1rem; }

article {
  border-left: 2px solid var(--rule);
  padding-left: 1rem;
  margin-bottom: 1rem;
  max-width: 60rem;
}

article p { white-space: pre-wrap; }

figure { margin: .5rem 0; }

/* Archived media is bounded rather than shown at whatever size it claims: one
   4claw SVG with a huge intrinsic size should not be able to push the rest of
   the page out of view. */
figure img {
  display: block;
  max-width: 24rem;
  max-height: 24rem;
  border: 1px solid var(--rule);
  background: #fff;
}

/* The agents page. Distribution bars are text rather than sized elements
   because `style-src 'self'` blocks an inline `style` attribute, so a bar whose
   width is data cannot be a div — block glyphs in the monospace this surface is
   already set in cost nothing and line up in a column for free. */
.bar { letter-spacing: -.05em; white-space: nowrap; }

/* One hue per tag value. The prefix is `act-` for every vocabulary, not just
   speech-act's: the values across the six keys in docs/design/vocabularies/ do
   not collide, so one namespace is one rule per value rather than a class name
   that has to carry its key. The bar is never the only way to read a row — the
   "Mostly" column names the same values in words, because eight colours is more
   than anyone should have to decode.

   speech-act.v0, in the order speech-act.md introduces them. Asking and
   asserting are the two that page is about, so they take the two strongest
   colours; the low-information residue is deliberately quiet. */
.act-question { color: var(--ask); }
.act-claim { color: var(--assert); }
.act-agreement { color: var(--muted); }
.act-disagreement { color: var(--bad); }
.act-advice { color: var(--assert); opacity: .7; }
.act-joke { color: var(--warn); }
.act-meta { color: var(--muted); opacity: .7; }
.act-filler { color: var(--rule); }

/* hostility.v0, which is ordinal (hostility.md §1) — so unlike the set above
   this is a ramp rather than a palette, quietest to loudest, and reading one
   bar left to right is reading the scale in order. */
.act-none { color: var(--rule); }
.act-snark { color: var(--warn); }
.act-insult { color: var(--bad); opacity: .7; }
.act-slur { color: var(--bad); }
.act-threat { color: var(--ink); }

/* The trail — one labelled comment at a time, in its thread. The one being
   read is marked with a heavier rule rather than a background, so it stays
   legible in both themes without a second colour to keep in step. */
.trail-nav { align-items: baseline; }

article.trail-here {
  border-left: 2px solid var(--ink);
  background: var(--bar-bg);
}

/* The masthead's right-hand end: who is signed in, and the way out. An `auto`
   margin rather than a grid column, so it sits at the far end whether or not
   the nav beside it is there. */
.whoami {
  margin-left: auto;
  display: flex;
  align-items: baseline;
  gap: .75rem;
}
