:root {
  /* Near-black on white. Borders are genuinely black, not a tinted grey: the
     structure is meant to read as drawn, like a printed spec sheet. */
  --surface: #FFFFFF;
  --surface-2: #F2F2F0;
  --surface-3: #E7E7E2;
  --text: #0A0A0A;
  --text-2: #6B6B66;
  --line: #0A0A0A;
  --line-soft: #D2D2CC;
  --accent: #1B1BFF;
  --accent-deep: #0000C4;

  /* One grotesk, one monospace, and no web fonts: a strict CSP forbids fetching
     any, so these are the heaviest widely-installed faces that hold tight tracking
     at display sizes. Monospace carries every label, count and column. */
  --display: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --sans: var(--display);
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  --s1: 8px;
  --s2: 16px;
  --s3: 24px;
  --s4: 32px;
  --s5: 48px;
  --s6: 64px;
  --s7: 96px;

  /* Solid, unblurred, offset down-right. A soft grey blur would put this back in
     the card-kit idiom the rest of the page is deliberately not in. */
  --shadow: 4px 4px 0 var(--line);

  /* Motion is tokenised so a duration is chosen by what the motion does, not by
     what looked right in the moment. Opening is an invitation and closing should
     get out of the way, so closes are quicker than opens and never overshoot. */
  --duration-stagger: 40ms;
  --duration-micro: 80ms;
  --duration-quick: 150ms;
  --duration-fast: 250ms;
  --duration-medium: 350ms;
  --duration-slow: 400ms;
  --ease-smooth-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out: ease-out;
  --ease-linear: linear;
  --distance-micro: 4px;
  --distance-base: 8px;
  --distance-medium: 12px;
  --ease: var(--ease-smooth-out);
}

@media (prefers-color-scheme: dark) {
  :root {
    --surface: #0A0A0A;
    --surface-2: #151514;
    --surface-3: #1F1F1D;
    --text: #F4F4F0;
    --text-2: #9A9A93;
    --line: #F4F4F0;
    --line-soft: #35352F;
    --accent: #8C8CFF;
    --accent-deep: #B6B6FF;
  }
}

/* A card: black header bar with a monospace label on the left and its count on the
   right, then content. The bar is what makes a group of rows read as a record
   rather than as a list floating on the page. */
.card {
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.card-bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s2);
  padding: 6px var(--s2);
  color: var(--surface);
  background: var(--line);
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.card-bar-count {
  opacity: 0.72;
}

/* Section boundaries are marked with corner ticks rather than a full rule, so the
   edge of a region is legible without drawing a box around everything. */
.tick-rule {
  position: relative;
  height: 1px;
  margin: var(--s6) 0;
  background: var(--line-soft);
}

.tick-rule::before,
.tick-rule::after {
  content: "";
  position: absolute;
  top: -5px;
  width: 1px;
  height: 11px;
  background: var(--line);
}

.tick-rule::before {
  left: 0;
}

.tick-rule::after {
  right: 0;
}

* {
  box-sizing: border-box;
}

html {
  /* Smoothing belongs on the root, once, rather than per-component. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100%;
  color: var(--text);
  background: var(--surface);
}

body {
  min-height: 100vh;
  margin: 0;
  overflow-x: hidden;
  color: var(--text);
  background-color: var(--surface);
  background-image:
    radial-gradient(circle at 34% 18%, color-mix(in oklab, var(--surface-2) 62%, transparent) 0, transparent 48vw),
    radial-gradient(circle at 84% 88%, color-mix(in oklab, var(--line) 13%, transparent) 0, transparent 58vw),
    var(--grain);
  font-family: var(--sans);
  text-rendering: optimizeLegibility;
}

button,
input,
textarea {
  font: inherit;
}

button {
  color: inherit;
}

button:focus-visible,
input:focus-visible,
textarea:focus-visible,
a:focus-visible,
[tabindex]:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 5px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.login-screen {
  min-height: 100vh;
}

.login-scroll {
  width: min(66ch, calc(100vw - 48px));
  margin-left: clamp(2rem, 18vw, 15rem);
  padding-top: 18vh;
}

.login-form {
  display: grid;
  justify-items: start;
  gap: 1.2rem;
}

.login-form h1 {
  margin: 0 0 1.4rem;
  font-family: var(--display);
  font-size: clamp(2rem, 7vw, 4.5rem);
  font-weight: 400;
  letter-spacing: 0;
}

.login-form label {
  width: min(28rem, 100%);
}

.login-form input,
.search-field input {
  flex: 1;
  min-width: 0;
  /* 16px on small screens: anything less and iOS zooms the viewport on focus. */
  font-size: max(16px, 0.8125rem);
  padding: 11px 0;
  color: var(--text);
  border: 0;
  border-radius: 0;
  background: transparent;
  font-family: var(--mono);
}

.search-field input:focus {
  outline: none;
}

.login-submit,
.text-button,
.inline-undo,
.pane-close,
.seam-link,
.capture-tab,
.ink-row {
  border: 0;
  border-radius: 0;
  background: transparent;
}

.login-submit {
  padding: 0.64rem 1.1rem;
  border: 1px solid var(--accent);
  color: var(--accent);
  cursor: pointer;
}

.login-error,
.capture-error {
  min-height: 1.4em;
  margin: 0;
  color: var(--accent);
}

.console-shell {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  column-gap: var(--s6);
  max-width: 1560px;
  margin: 0 auto;
  padding: 0 var(--s5) var(--s7) 0;
  min-height: 100vh;
}

.left-rail {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  padding: clamp(1.5rem, 4vw, 3rem) 0 2rem clamp(1rem, 2vw, 1.8rem);
  display: grid;
  grid-template-rows: auto auto repeat(3, min-content) 1fr;
  gap: 1.8rem;
  color: var(--text-2);
}

.seal {
  display: block;
}

.rail-title {
  margin: 0 0 var(--s5);
  color: var(--text);
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1;
}

.rail-label {
  display: block;
  margin-bottom: var(--s1);
}

.rail-name {
  color: var(--text-2);
  font-size: 0.875rem;
  letter-spacing: 0;
  text-transform: none;
}

.rail-name:hover {
  color: var(--text);
}

.rail-foot,
.rail-foot,
.result-count,
.key-legend,
.pane-kicker,
.collection-legend {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
}

.rail-foot {
  align-self: end;
  display: grid;
  gap: 0.55rem;
}

.text-button,
.pane-close,
.inline-undo {
  width: fit-content;
  padding: 0;
  color: var(--text-2);
  border-bottom: 1px solid var(--line);
  cursor: pointer;
}

.inline-undo {
  font-size: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}

.inline-undo:disabled {
  cursor: default;
  opacity: 0.55;
}

.scroll-column {
  position: relative;
  max-width: 100%;
  padding: var(--s6) 0 var(--s7);
}

/* A prompt, not a form field. The caret is the affordance: this is the place you
   type at. */
.search-field {
  display: flex;
  align-items: center;
  gap: var(--s1);
  width: 100%;
  max-width: 56rem;
  padding: 0 var(--s2);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.search-field::before {
  content: ">";
  color: var(--accent);
  font-family: var(--mono);
  font-size: 0.875rem;
}

.search-field:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The search input carries its own placeholder, so the label is for screen
   readers only rather than a second visible word beside it. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.result-count {
  min-height: 1.5rem;
  margin: 2.1rem 0 0;
  color: var(--text-2);
}

.ink-list {
  margin-top: var(--s5);
}

/* Four columns, shared by the header strip and every row, so the columns line up
   without either knowing about the other. */
.collection .table-head,
.collection .ink-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 11rem 13rem 6rem;
  gap: var(--s3);
  align-items: baseline;
  padding: 10px var(--s2);
  text-align: left;
}

.table-head {
  color: var(--text-2);
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.ink-row {
  width: 100%;
  border-bottom: 1px dotted var(--line-soft);
  cursor: pointer;
}

.ink-row:last-child {
  border-bottom: 0;
}

.ink-row:hover,
.ink-row.is-selected {
  background: var(--surface-2);
}

/* Hover in is quicker than hover out: the highlight should answer the pointer at
   once and then let go without snapping. */
.ink-row {
  transition: background var(--duration-fast) var(--ease-out);
}

.ink-row:hover {
  transition-duration: var(--duration-micro);
}

/* Selection is a solid bar in the left gutter rather than a fill, so the row a
   keyboard is on stays distinguishable from the row a mouse is merely over. */
.ink-row.is-selected {
  box-shadow: inset 3px 0 0 var(--accent);
}

.row-title {
  display: block;
  font-family: var(--display);
  font-size: 1.0625rem;
  font-weight: 600;
  /* Tracking tightens as size grows: a 17px row title needs far less negative
     tracking than a display headline, and over-tightening here costs legibility. */
  letter-spacing: -0.012em;
  line-height: 1.35;
  text-wrap: pretty;
}

.row-slug,
.cell-origin,
.cell-contributors,
.cell-updated {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: -0.02em;
  /* Dates and counts change between rows and between renders. Proportional digits
     make the columns jitter; tabular ones keep them in place. */
  font-variant-numeric: tabular-nums;
}

.row-slug {
  display: block;
  margin-top: 3px;
  color: var(--text-2);
}

.cell-origin,
.cell-updated {
  color: var(--text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cell-contributors {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* Each contributor is a bordered chip. Who taught a page is the kind of fact that
   should be countable at a glance, not read as a sentence. */
.who {
  padding: 1px 5px;
  color: var(--text);
  border: 1px solid var(--line-soft);
}

.who-more {
  padding: 1px 4px;
  color: var(--text-2);
}

.unrecorded {
  color: var(--text-2);
  opacity: 0.65;
}

.snippet {
  display: block;
  max-width: 72ch;
  margin-top: 6px;
  color: var(--text-2);
  font-family: var(--display);
  font-size: 0.875rem;
  line-height: 1.6;
}

.row-sentinel {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s3) var(--s2);
  color: var(--text-2);
  border-top: 1px dotted var(--line-soft);
  font-family: var(--mono);
  font-size: 0.75rem;
}

@media (max-width: 900px) {
  .collection .table-head {
    display: none;
  }

  .collection .ink-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
  }
}

@keyframes ink-bleed {
  from {
    filter: blur(6px);
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    filter: blur(0);
    opacity: 1;
    transform: translateY(0);
  }
}

.inline-loading,
.pane-loading {
  display: inline-flex;
  align-items: center;
  gap: 1rem;
  color: var(--text-2);
}

.pulse {
  width: 44px;
  height: 12px;
  fill: var(--text-2);
}

.pulse circle {
  animation: pulse-fade 1.2s var(--ease) infinite;
}

@keyframes pulse-fade {
  0%,
  100% {
    opacity: 0.2;
  }
  50% {
    opacity: 0.9;
  }
}

/* Legibility floor: the aesthetic may be quiet, but the screen still has to say
   what it is, what the ink means, and which keys do anything. */
.login-blurb {
  max-width: 34ch;
  margin: 0.4rem 0 2.4rem;
  color: var(--text-2);
  font-family: var(--display);
  font-size: 1.02rem;
  line-height: 1.7;
}

.field-label {
  display: block;
}

.field-label > span {
  display: block;
  margin-bottom: 0.5rem;
  color: var(--text-2);
  font-size: 0.78rem;
  letter-spacing: 0.09em;
  text-transform: lowercase;
}

.login-hint {
  margin-top: 1.5rem;
  color: color-mix(in oklab, var(--text-2) 78%, transparent);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: -0.02em;
}

.collection-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.4rem;
  margin-top: 0.35rem;
  color: color-mix(in oklab, var(--text-2) 80%, transparent);
  font-size: 0.74rem;
  letter-spacing: 0.02em;
}

.legend-keys {
  font-family: var(--mono);
  letter-spacing: -0.03em;
}

.tab-label-secondary {
  margin-top: 0.7rem;
  color: var(--text-2);
  font-family: var(--sans);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  writing-mode: horizontal-tb;
  text-orientation: mixed;
}

/* Filter chips: bordered boxes, the active one filled solid. The state is carried
   by fill rather than by a colour change, so it survives being read in greyscale. */
.view-toggle {
  display: flex;
  gap: -1px;
  margin-bottom: var(--s4);
}

.chip {
  padding: 5px var(--s3);
  color: var(--text);
  border: 1px solid var(--line);
  background: var(--surface);
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--duration-micro) var(--ease-out),
    color var(--duration-micro) var(--ease-out);
}

.chip + .chip {
  margin-left: -1px;
}

.chip:hover {
  background: var(--surface-2);
}

.chip.is-on {
  color: var(--surface);
  background: var(--line);
}

.graph-card {
  overflow: hidden;
}

.graph-canvas {
  display: block;
  width: 100%;
  height: clamp(420px, 62vh, 760px);
  touch-action: none;
}

.graph-hint,
.graph-empty {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin: 0;
  padding: var(--s2);
  color: var(--text-2);
  border-top: 1px dotted var(--line-soft);
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
}

.graph-empty {
  border-top: 0;
  padding: var(--s6) var(--s2);
  justify-content: center;
}

/* An agent's mark. Original geometry, not anyone's brand: this console has no
   licence to redraw someone else's trademark, and at 12px the only job a mark has
   is to be told apart from the others. */
.agent-mark {
  display: inline-flex;
  flex: none;
  align-items: center;
  color: var(--text-2);
}

.agent-mark svg {
  display: block;
}

.agent-claude { color: #C1622F; }
.agent-codex { color: #10A37F; }
.agent-openclaw { color: #7A4DD1; }
.agent-hermes { color: #2A7FD4; }
.agent-grok { color: #1F1F1F; }
.agent-cursor { color: #5B5BD6; }

@media (prefers-color-scheme: dark) {
  .agent-grok { color: #E4E4E0; }
}

.who {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

/* A memory someone is using right now. The band travels once every couple of
   seconds rather than continuously: this is a status, and a status that never
   stops moving becomes noise you learn to ignore. */
.row-live {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 5px;
  color: var(--accent);
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: -0.01em;
}

.ink-row.is-live {
  position: relative;
  overflow: hidden;
}

.ink-row.is-live::after {
  position: absolute;
  inset: 0;
  content: "";
  pointer-events: none;
  background: linear-gradient(
    100deg,
    transparent 38%,
    color-mix(in oklab, var(--accent) 14%, transparent) 50%,
    transparent 62%
  );
  transform: translateX(-100%);
  animation: shimmer 2.4s var(--ease-linear) infinite;
}

@keyframes shimmer {
  0% {
    transform: translateX(-100%);
  }
  55%,
  100% {
    transform: translateX(100%);
  }
}

/* Reduced motion gets the same information without the travelling band: a steady
   tint and a rule down the edge. The agent's name is in the row either way, so
   nothing depends on seeing movement. */
@media (prefers-reduced-motion: reduce) {
  .ink-row.is-live::after {
    animation: none;
    transform: none;
    background: color-mix(in oklab, var(--accent) 7%, transparent);
    border-left: 2px solid var(--accent);
  }
}

.review-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--s2);
  padding: var(--s2);
  border-top: 1px solid var(--line-soft);
}

.review-kind {
  margin: 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.review-meta,
.review-body {
  margin: 6px 0 0;
  color: var(--text-2);
  font-size: 14px;
}

.review-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}
