/* ============================================================
   repligraph.org — console stylesheet
   Two voices: Newsreader (the argument) / Spline Sans Mono (the record)
   ============================================================ */

:root {
  --void: #0b1014;
  --panel: #0f171d;
  --raise: #16212a;
  --bone: #e9ece6;
  --prose: #c2ccc9;
  --dim: #93a3a8;
  --faint: #5b6a71;
  --rule: rgba(233, 236, 230, 0.13);
  --rule-soft: rgba(233, 236, 230, 0.07);

  /* the three signals — color is never decorative here */
  --human: #e9b44c;
  /* intent: prompts, English, people */
  --match: #57d6a8;
  /* replayed and identical */
  --flag: #ff6a45;
  /* mismatch, danger, unprovable */

  --serif: "Newsreader", Iowan Old Style, Georgia, serif;
  --mono: "Spline Sans Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --masthead-h: 56px;
  --idx-row: 1.05rem;
  /* one index entry, so groups can wrap predictably */
  --pad-x: clamp(2rem, 4.2vw, 4.5rem);
}

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

html,
body {
  height: 100%;
  overflow: hidden;
  background: var(--void);
  color: var(--bone);
  font-family: var(--serif);
  font-size: clamp(15px, 0.52vw + 12px, 19px);
  -webkit-font-smoothing: antialiased;
}

body {
  background:
    radial-gradient(80% 60% at 78% 8%, rgba(87, 214, 168, 0.055), transparent 60%),
    radial-gradient(60% 50% at 5% 95%, rgba(233, 180, 76, 0.045), transparent 60%),
    var(--void);
}

::selection {
  background: rgba(87, 214, 168, 0.25);
}

.shell {
  display: grid;
  grid-template-rows: var(--masthead-h) auto 1fr;
  height: 100%;
}

/* ---------- masthead ---------- */

.masthead {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  padding: 0 var(--pad-x);
  border-bottom: 1px solid var(--rule);
}

.wordmark {
  font-family: var(--mono);
  transition: color 0.15s ease;
  font-weight: 500;
  font-size: 0.82rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--bone);
  text-decoration: none;
}

/* the twin trace: the site's ornament, its signature, its argument */
.trace {
  display: flex;
  flex-direction: column;
  gap: 3px;
  opacity: 0.85;
}

.trace-row {
  display: flex;
  gap: 3px;
}

.trace-row i {
  display: block;
  width: 3px;
  height: 7px;
  background: var(--faint);
}

.trace-row i.on {
  background: var(--match);
}

/* the wordmark stands in for the main page: current, or pointed at. it does not
   light up as a mere neighbor — the index is full of its neighbors, and a title
   that blinks on half the hovers reads as noise rather than as a signal. */
.wordmark.is-current,
.wordmark.is-pointed {
  color: var(--match);
}

.masthead .spacer {
  flex: 1;
}

.masthead .meta {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}

.masthead .meta a {
  color: var(--dim);
  text-decoration: none;
}

.masthead .meta a:hover {
  color: var(--match);
}

/* ---------- the index: every page, always visible ---------- */

.index {
  position: relative;
  display: flex;
  gap: clamp(1.6rem, 3vw, 3.4rem);
  padding: 0.8rem var(--pad-x) 0.9rem;
  border-bottom: 1px solid var(--rule);
}

.idx-group {
  min-width: 0;
}

/* headings, not entries: the serif marks them as editorial rather than record */
.idx-label {
  font-family: var(--serif);
  font-size: 1rem;
  font-weight: 400;
  font-style: italic;
  letter-spacing: 0;
  text-transform: none;
  color: var(--faint);
  padding-bottom: 0.32rem;
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--rule-soft);
}

/* a group flows into sub-columns rather than making the index tall.
   grid, not flex-wrap: a wrapping flex column reports only its first column's
   width, so the next group would start too early and overlap it. */
.idx-items {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(4, auto);
  grid-auto-columns: max-content;
  column-gap: clamp(1.6rem, 3vw, 3.4rem);
  align-items: start;
}

.idx-link {
  position: relative;
  font-family: var(--mono);
  font-size: 0.7rem;
  line-height: var(--idx-row);
  letter-spacing: 0.03em;
  color: var(--faint);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s ease;
}

.idx-link:hover {
  color: var(--dim);
}

.idx-link:focus-visible {
  outline: 1px solid var(--match);
  outline-offset: 2px;
}

/* the current page — and, only while hovering, someone else's neighborhood */
.idx-link.is-current {
  color: var(--bone);
}

.idx-link.is-pointed {
  color: var(--match);
}

/* a cross-reference is aimed here */
.index.is-hovering .idx-link {
  color: var(--rule);
}

.index.is-hovering .idx-link.is-hot {
  color: var(--dim);
}

.index.is-hovering .idx-link.is-focus {
  color: var(--bone);
}

/* wires drawn between index entries */
.idx-wires {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}

.idx-wires path {
  fill: none;
  stroke: var(--match);
  stroke-width: 1;
}

.idx-wires .hov {
  animation: fade 0.16s ease forwards;
}

.idx-wires .hov path {
  stroke-opacity: 0.5;
}

@keyframes fade {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.idx-link.is-current::before {
  content: "";
  position: absolute;
  left: -0.7rem;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 3px;
  background: var(--match);
}

/* ---------- stage ---------- */

.stage {
  position: relative;
  min-height: 0;
}

.page {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: minmax(400px, 44%) 1fr;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

.page.is-active {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  transition: opacity 0.28s ease;
}

/* ---------- left: one block of prose ---------- */

.read {
  display: flex;
  flex-direction: column;
  gap: calc(1rem * var(--read-scale, 1));
  padding: clamp(1.2rem, 2.6vh, 2rem) clamp(2rem, 3vw, 3.4rem) clamp(1.2rem, 2.6vh, 2rem) var(--pad-x);
  border-right: 1px solid var(--rule);
  overflow-y: auto;
  scrollbar-width: none;
}

/* Centred by auto margins, not justify-content: a centred flex column puts its
   top overflow above scrollTop 0, where the scrollbar cannot reach it, so a long
   page lost its opening lines outright. Auto margins centre the same way while
   leaving both ends reachable. --read-scale is set by fitProse() in app.js. */
.read > :first-child {
  margin-top: auto;
}

.read > :last-child {
  margin-bottom: auto;
}

.read::-webkit-scrollbar {
  display: none;
}

.read p {
  font-size: calc(1rem * var(--read-scale, 1));
  line-height: 1.62;
  color: var(--prose);
  max-width: 56ch;
  text-align: justify;
  text-wrap: pretty;
}

/* `- item` and `1. item` runs; left-ragged, since justifying short items opens gaps */
.read ul,
.read ol {
  max-width: 56ch;
  padding-left: 1.4rem;
  color: var(--prose);
  font-size: calc(1rem * var(--read-scale, 1));
  line-height: 1.62;
}

.read li {
  padding-left: 0.25rem;
}

.read li+li {
  margin-top: calc(0.42rem * var(--read-scale, 1));
}

.read li::marker {
  color: var(--faint);
  font-family: var(--mono);
  font-size: 0.84em;
}

/* **bold** lifts a term out of the prose; *italic* is contrastive stress */
.read strong {
  font-style: normal;
  font-weight: 600;
  color: var(--bone);
}

.read em {
  font-style: italic;
  font-weight: inherit;
  color: inherit;
}

.read .mint {
  color: var(--match);
}

.read .amber {
  color: var(--human);
}

.read .flag {
  color: var(--flag);
}

.read code {
  font-family: var(--mono);
  font-size: 0.82em;
  color: var(--bone);
  background: var(--raise);
  padding: 0.08em 0.34em;
  border-radius: 2px;
}

/* in-article links are the primary navigation (in paragraphs and list items alike) */
.read a {
  color: var(--match);
  text-decoration: none;
  border-bottom: 1px solid rgba(87, 214, 168, 0.3);
  transition: border-color 0.15s ease, background 0.15s ease;
}

.read a:hover {
  border-bottom-color: var(--match);
  background: rgba(87, 214, 168, 0.08);
}

.read a:focus-visible {
  outline: 1px solid var(--match);
  outline-offset: 2px;
}

/* a link that leaves the site says so */
.read a.ext::after {
  content: "↗";
  font-family: var(--mono), sans-serif;
  font-size: 0.68em;
  line-height: 1;
  vertical-align: 0.32em;
  margin-left: 0.14em;
  opacity: 0.75;
}

/* ---------- right: the instrument ---------- */

.view {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.1rem;
  padding: clamp(1.4rem, 3.6vh, 2.8rem) var(--pad-x);
  min-width: 0;
}

/* faint measurement grid — the panel is an instrument, not a canvas */
.view::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image:
    linear-gradient(var(--rule-soft) 1px, transparent 1px),
    linear-gradient(90deg, var(--rule-soft) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: radial-gradient(70% 70% at 50% 45%, #000 20%, transparent 100%);
}

.view svg {
  position: relative;
  width: 100%;
  max-width: 620px;
  max-height: min(62vh, 500px);
  overflow: visible;
}

#adjudication .view {
  padding-inline: 1rem;
}

/* Wider than the other figures: three repligraphs in a triangle. The viewBox
   origin is negative because the frames are scaled about their own centres and
   spill up and left of it; max-width matches the viewBox so a unit stays a pixel
   at full size. Anything narrower simply scales the whole figure down. */
.view .adjudication-figure {
  max-width: 910px;
}

/* Format: the manifest and a readable slice of the transcript. */
#format .view {
  justify-content: flex-start;
  padding: clamp(1.25rem, 3vh, 2rem) clamp(1rem, 2.5vw, 2rem);
  overflow-y: auto;
}

.format-example {
  position: relative;
  flex: 0 0 auto;
  width: 100%;
  max-width: 620px;
  margin-block: auto;
  display: grid;
  gap: 2rem;
}

.format-file-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem 1rem;
  padding-bottom: 0.65rem;
  margin-bottom: 0.85rem;
  border-bottom: 1px solid var(--rule);
  font-family: var(--mono);
}

.format-file-heading h2 {
  color: var(--bone);
  font-size: 13px;
  font-weight: 400;
}

.format-file-heading > span {
  color: var(--dim);
  font-size: 11px;
}

.format-file pre,
.format-file code {
  font-family: var(--mono);
  font-size: clamp(12px, 1.15vw, 14px);
  line-height: 1.6;
  color: var(--bone);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.format-key,
.format-token {
  color: var(--dim);
}

.format-hash {
  display: inline-block;
  max-width: calc(100% - 6ch);
  vertical-align: top;
  word-break: break-all;
  text-wrap: balance;
}

/* ---------- svg primitives ---------- */

/* The opening figure is a two-scene conversation. */
.claim-person,
.claim-furniture {
  fill: none;
  stroke: var(--human);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.claim-head {
  fill: var(--void);
}

.claim-furniture {
  stroke: var(--faint);
  stroke-width: 1.4;
}

.claim-bubble,
.claim-screen {
  fill: var(--panel);
  stroke: var(--faint);
  stroke-width: 1;
  stroke-linejoin: round;
}

.claim-book-pages {
  fill: var(--raise);
  stroke: var(--faint);
  stroke-width: 1;
}

.claim-book-cover {
  fill: #0b0c0d;
  stroke: #b59b6d;
  stroke-width: 1;
}

.claim-cover-title {
  fill: #cbb17e;
  font-family: Georgia, serif;
  font-size: 19px;
  font-weight: 400;
}

.claim-bubble-match {
  stroke: var(--match);
  stroke-opacity: 0.6;
}

.claim-dialogue {
  font-family: var(--serif);
  font-size: 19px;
  fill: var(--bone);
}

.software-comic .claim-dialogue {
  font-size: 22px;
}

/* A specification above two agent repligraphs: implementation and intent audit. */
#formal-verification .view {
  padding-inline: clamp(1rem, 1.6vw, 1.5rem);
}

.formal-mount {
  width: 100%;
  max-width: 720px;
  max-height: min(62vh, 500px);
  aspect-ratio: 720 / 480;
}

.formal-mount .formal-figure {
  display: block;
  width: 100%;
  max-width: none;
  height: 100%;
}

.formal-spec-prompt {
  font-family: var(--serif);
  font-size: 16px;
  font-style: italic;
  fill: var(--bone);
}

.formal-spec-output {
  font-family: var(--mono);
  font-size: 14px;
  fill: var(--bone);
}

.formal-agent .rg-part-label {
  font-size: 12px;
}

.formal-agent .harness-tool-name {
  font-size: 22px;
}

.formal-agent .harness-tool-argument {
  font-size: 18px;
  letter-spacing: 0;
}

.formal-agent .audits-verdict,
.formal-agent .harness-tree text {
  font-size: 20px;
}

/* Anchor playback status to the view corner, clear of the animated interface. */
.diagram-pause-indicator {
  position: absolute;
  top: 1rem;
  right: 1rem;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 7px;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--void);
  color: var(--dim);
  font-family: var(--mono);
  font-size: 11px;
  line-height: 14px;
  pointer-events: none;
}

.diagram-pause-indicator::before {
  display: none;
  content: "";
  width: 7px;
  height: 9px;
  background: linear-gradient(to right, currentColor 0 2px, transparent 2px 5px, currentColor 5px 7px);
}

.diagram-pause-label,
[data-animation-paused="true"] .diagram-pause-hint {
  display: none;
}

[data-animation-paused="true"] > .diagram-pause-indicator::before {
  display: block;
}

[data-animation-paused="true"] .diagram-pause-label {
  display: inline;
}

@media (prefers-reduced-motion: reduce), (hover: none) {
  .diagram-pause-indicator {
    display: none;
  }
}

/* Forecasting: browse a model-and-prompt forecaster's prediction record. */
#forecasting .view {
  padding-inline: clamp(1rem, 2vw, 1.5rem);
}

.forecasting-mount {
  width: 100%;
  max-width: 680px;
  max-height: min(68vh, 520px);
  aspect-ratio: 620 / 430;
}

.forecasting-mount .forecasting-figure {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
}

.forecast-panel {
  fill: var(--panel);
  stroke: var(--faint);
  stroke-width: 1;
}

.forecast-rule {
  fill: none;
  stroke: var(--rule);
}

.forecast-brand,
.forecast-meta,
.forecast-column,
.forecast-model,
.forecast-prompt,
.forecast-count,
.forecast-brier,
.forecast-back,
.forecast-question,
.forecast-date,
.forecast-value,
.forecast-empty,
.forecast-confidence,
.forecast-footnote,
.forecast-outcome {
  font-family: var(--mono);
  fill: var(--bone);
}

.forecast-brand {
  font-size: 11px;
  letter-spacing: 0.12em;
}

.forecast-meta,
.forecast-date {
  font-size: 10px;
  fill: var(--dim);
}

.forecast-title,
.forecast-record-title {
  font-family: var(--serif);
  font-size: 24px;
  fill: var(--bone);
}

.forecast-record-title {
  font-size: 18px;
}

.forecast-column {
  font-size: 10.5px;
  fill: var(--dim);
}

.forecast-footnote {
  font-size: 10.5px;
  fill: var(--dim);
}

.forecast-list-row rect {
  fill: var(--raise);
  fill-opacity: 0.45;
  stroke: var(--rule);
}

.forecast-list-row.is-hovered rect,
.forecast-list-row.is-selected rect {
  fill: var(--raise);
  fill-opacity: 1;
  stroke: var(--dim);
}

.forecast-model,
.forecast-count {
  font-size: 16px;
}

.forecast-prompt,
.forecast-back {
  font-size: 13px;
  fill: var(--dim);
}

.forecast-question {
  font-size: 13px;
}

.forecast-value,
.forecast-brier,
.forecast-outcome,
.forecast-empty {
  font-size: 15px;
}

.forecast-brier,
.forecast-outcome.is-yes {
  fill: var(--match);
}

.forecast-empty {
  fill: var(--faint);
}

.forecast-confidence {
  font-size: 13px;
}

.forecast-brand-icon,
.forecast-chevron,
.forecast-back-icon,
.forecast-sort-icon {
  fill: none;
  stroke: var(--dim);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.forecast-click {
  fill: none;
  stroke: var(--dim);
  stroke-width: 2;
  pointer-events: none;
}

.forecast-cursor {
  pointer-events: none;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.6));
}

.forecast-cursor path {
  fill: var(--bone);
  stroke: var(--void);
  stroke-width: 1.5;
  stroke-linejoin: round;
}

/* Evals: the benchmark's beautiful bicycle, and the one you actually get. */
#evals .view {
  padding-inline: clamp(1rem, 2.4vw, 2rem);
}

.evals-meme {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.65rem, 1.5vw, 1.25rem);
  width: 100%;
  max-width: 720px;
}

.evals-meme-panel {
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--panel);
}

.evals-meme-panel figcaption {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 3.4em;
  padding: 0.6em 0.5em;
  border-bottom: 1px solid var(--rule);
  font-family: var(--serif);
  font-size: clamp(17px, 1.6vw, 23px);
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
  text-wrap: balance;
}

.evals-meme-panel img {
  display: block;
  width: 100%;
  height: auto;
}

/* Eyeballs: a forge score opens the individual audit records behind it. */
.eyeballs-mount {
  width: 100%;
  max-width: 620px;
  max-height: min(62vh, 500px);
  aspect-ratio: 620 / 430;
}

.eyeballs-mount .eyeballs-figure {
  display: block;
  width: 100%;
  height: 100%;
}

.eyeballs-forge,
.eyeballs-file-list {
  fill: var(--panel);
  stroke: var(--rule);
  stroke-width: 1;
}

.eyeballs-forge {
  stroke: var(--faint);
}

.eyeballs-rule {
  fill: none;
  stroke: var(--rule);
  stroke-width: 1;
}

.eyeballs-ui-icon,
.eyeballs-eye-icon,
.eyeballs-download-button use {
  fill: none;
  stroke: var(--dim);
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.eyeballs-brand,
.eyeballs-repository,
.eyeballs-tab,
.eyeballs-tab-active,
.eyeballs-filename,
.eyeballs-commit,
.eyeballs-score text,
.eyeballs-review-count,
.eyeballs-column,
.eyeballs-model,
.eyeballs-prompt-id,
.eyeballs-findings,
.eyeballs-review-score {
  font-family: var(--mono);
  fill: var(--bone);
}

.eyeballs-brand {
  font-size: 11px;
  letter-spacing: 0.18em;
  fill: var(--dim);
}

.eyeballs-avatar {
  fill: var(--raise);
  stroke: var(--faint);
}

.eyeballs-repository {
  font-size: 18px;
}

.eyeballs-tab,
.eyeballs-tab-active,
.eyeballs-filename {
  font-size: 12px;
}

.eyeballs-tab,
.eyeballs-commit,
.eyeballs-review-count,
.eyeballs-column {
  fill: var(--dim);
}

.eyeballs-active-rule {
  stroke: var(--match);
  stroke-width: 2;
}

.eyeballs-commit,
.eyeballs-review-count {
  font-size: 10px;
}

.eyeballs-readme,
.eyeballs-popover-title {
  font-family: var(--serif);
  font-size: 19px;
  fill: var(--bone);
}

.eyeballs-placeholder {
  stroke: var(--faint);
  stroke-width: 3;
  stroke-linecap: round;
  opacity: 0.35;
}

.eyeballs-score rect {
  fill: var(--raise);
  stroke: var(--faint);
  stroke-width: 1;
}

.eyeballs-score text {
  font-size: 17px;
}

.eyeballs-score.is-hovered rect {
  fill: #142c27;
  stroke: var(--match);
}

.eyeballs-score.is-hovered text {
  fill: var(--match);
}

.eyeballs-score.is-hovered .eyeballs-eye-icon {
  stroke: var(--match);
}

.eyeballs-popover {
  filter: drop-shadow(0 7px 12px rgba(0, 0, 0, 0.55));
}

.eyeballs-popover-panel {
  fill: var(--panel);
  stroke: var(--faint);
  stroke-width: 1;
}

.eyeballs-popover-title {
  font-size: 22px;
}

.eyeballs-column {
  font-size: 10px;
}

.eyeballs-model,
.eyeballs-findings,
.eyeballs-review-score {
  font-size: 14px;
}

.eyeballs-prompt-id {
  font-size: 12px;
}

.eyeballs-review-score {
  fill: var(--match);
}

.eyeballs-download-button rect {
  fill: var(--raise);
  stroke: var(--match);
  stroke-opacity: 0.4;
}

.eyeballs-download-button use {
  stroke: var(--match);
}

.eyeballs-cursor {
  pointer-events: none;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.6));
}

.eyeballs-cursor path {
  fill: var(--bone);
  stroke: var(--void);
  stroke-width: 1.5;
  stroke-linejoin: round;
}

.claim-skeptic {
  fill: var(--flag);
}

.claim-confirmation,
.claim-answer,
.claim-ai-label,
.claim-status {
  fill: var(--match);
}

.claim-answer {
  font-family: var(--serif);
  font-size: 13px;
}

.claim-chat-label,
.claim-ai-label {
  font-family: var(--mono);
  font-size: 9px;
}

.claim-chat-label {
  fill: var(--dim);
}

.claim-prompt-box {
  fill: var(--human);
  fill-opacity: 0.07;
  stroke: var(--human);
  stroke-opacity: 0.2;
}

.claim-prompt {
  font-family: var(--mono);
  font-size: 12px;
  fill: var(--human);
}

.fig-box {
  fill: var(--panel);
  stroke: var(--rule);
  stroke-width: 1;
}

.fig-box-raise {
  fill: var(--raise);
  stroke: var(--rule);
  stroke-width: 1;
}

.fig-rule {
  stroke: var(--rule);
  stroke-width: 1;
}

.fig-wire {
  stroke: var(--faint);
  stroke-width: 1;
  fill: none;
}

.fig-wire-match {
  stroke: var(--match);
  stroke-width: 1;
  fill: none;
}

.fig-wire-human {
  stroke: var(--human);
  stroke-width: 1;
  fill: none;
}

.fig-dash {
  stroke-dasharray: 3 4;
}

/* A repligraph encloses the full recorded run: inputs, execution, and answer. */
.rg-frame {
  fill: var(--void);
  stroke: var(--dim);
  stroke-width: 1.25;
}

.rg-seal {
  fill: var(--faint);
}

/* Repligraph signature: a neutral frame with a cyan inset outline. */
.rg-signature {
  opacity: 1;
  fill: none;
  stroke: var(--match);
  stroke-opacity: 0.48;
  stroke-width: 0.75;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}

.rg-divider {
  stroke: var(--rule);
  stroke-width: 1;
}

.rg-port-out {
  fill: var(--match);
  stroke: var(--void);
  stroke-width: 3;
}

.rg-title {
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  fill: var(--bone);
}

.rg-part-label {
  font-family: var(--mono);
  font-size: 7.5px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  fill: var(--dim);
}

.rg-function {
  font-family: var(--serif);
  font-size: 32px;
  font-style: italic;
  fill: var(--bone);
}

.personhood-prompt {
  font-family: var(--serif);
  font-size: 19px;
  font-style: italic;
  fill: var(--bone);
}

.repligraph-prompt-text {
  font-family: var(--serif);
  font-size: 13px;
  font-style: italic;
  fill: var(--bone);
}

.weights-mount {
  position: relative;
  width: 100%;
  max-width: 620px;
  aspect-ratio: 620 / 430;
}

.weights-mount .weights-figure {
  display: block;
  width: 100%;
  height: 100%;
}

.repligraph-input-text,
.repligraph-output-text {
  font-family: var(--mono);
  font-size: 12px;
  fill: var(--bone);
}

.weights-provider-cloud {
  fill: var(--void);
  stroke: var(--faint);
  stroke-width: 1;
}

.weights-provider-function {
  font-size: 20px;
}

.weights-provider-label {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
}

.weights-provider-label.provider-a {
  fill: var(--match);
}

.weights-provider-label.provider-b {
  fill: var(--human);
}

.weights-provider-label.provider-c {
  fill: #7aa7ff;
}

.weights-provider-label.provider-d {
  fill: #d58cff;
}

.adjudication-prompt {
  font-family: var(--serif);
  font-size: 12px;
  font-style: italic;
  fill: var(--bone);
}

.adjudication-file {
  font-family: var(--mono);
  font-size: 10px;
  fill: var(--bone);
}

.adjudication-output {
  font-family: var(--mono);
  font-size: 12px;
  fill: var(--bone);
}

.adjudication-function {
  font-size: 20px;
}

.inference-prompt {
  font-family: var(--serif);
  font-size: 19px;
  font-style: italic;
  fill: var(--bone);
}

.inference-output {
  font-family: var(--mono);
  font-size: 16px;
  fill: var(--bone);
}

.inference-question {
  font-size: 30px;
  font-style: normal;
}

.inference-function {
  font-size: 27px;
}

.application-prompt {
  font-family: var(--serif);
  font-size: 19px;
  font-style: italic;
  fill: var(--bone);
}

.application-prompt-small {
  font-size: 11.5px;
}

#coordination .application-prompt {
  font-size: 14px;
}

.application-input,
.application-output,
.application-tools,
.application-proof,
.application-score,
.application-equals {
  font-family: var(--mono);
  fill: var(--bone);
}

.application-input {
  font-size: 9px;
}

.application-input-small {
  font-size: 7.5px;
}

.application-output {
  font-size: 13px;
}

.application-output-small {
  font-size: 10px;
}

.application-tools {
  font-size: 9px;
  letter-spacing: 0.08em;
  fill: var(--dim);
}

.application-function {
  font-size: 22px;
}

.application-score {
  font-size: 15px;
}

.application-equals {
  font-size: 19px;
}

.application-note {
  font-family: var(--mono);
  font-size: 8px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  fill: var(--dim);
}

.application-proof {
  font-size: 13px;
}

.application-mini-prompt {
  font-family: var(--serif);
  font-size: 11px;
  font-style: italic;
  fill: var(--bone);
}

.application-mini-function {
  font-size: 19px;
}

.application-mini-output {
  font-family: var(--mono);
  font-size: 11px;
  fill: var(--bone);
}

.logs-node-selected {
  stroke: var(--match);
}

.logs-node-selected {
  stroke-width: 1.4;
}

.logs-node-index {
  font-family: var(--mono);
  font-size: 8px;
  letter-spacing: 0.04em;
  fill: var(--dim);
}

.logs-node-hash {
  font-family: var(--mono);
  font-size: 11px;
  fill: var(--bone);
}

.logs-key-glyph {
  fill: none;
  stroke-width: 1.15;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.logs-key-muted {
  stroke: var(--faint);
  opacity: 0.65;
}

.logs-key-selected {
  stroke: var(--match);
  filter: drop-shadow(0 0 2px color-mix(in srgb, var(--match) 55%, transparent));
}

.logs-selected-text {
  fill: var(--match);
}

.logs-detail-title {
  font-family: var(--mono);
  font-size: 13px;
  fill: var(--bone);
}

.logs-detail-copy,
.logs-rg-text {
  font-family: var(--serif);
  font-size: 12px;
  fill: var(--bone);
}

.logs-detail-copy {
  font-style: italic;
}

.logs-rg-function {
  font-size: 18px;
}

.logs-agent-tool-name,
.logs-agent-tool-argument {
  font-family: var(--mono);
  fill: var(--bone);
}

.logs-agent-tool-name {
  font-size: 12px;
}

.logs-agent-tool-argument,
.logs-agent-tree {
  font-size: 10px;
}

.logs-agent-tool-argument {
  fill: var(--dim);
}

.logs-policy-file {
  fill: var(--match);
}

.audits-artifact-line {
  fill: var(--faint);
}

.audits-mount {
  position: relative;
  width: 100%;
  max-width: 620px;
  aspect-ratio: 620 / 430;
}

.audits-mount .audits-figure {
  display: block;
  width: 100%;
  height: 100%;
}

.audits-tree {
  font-size: 12px;
}

.audits-tool-argument {
  font-size: 11px;
}

.verification-mount {
  position: relative;
  width: 100%;
  max-width: 620px;
  aspect-ratio: 620 / 440;
}

.verification-mount .verification-figure {
  display: block;
  width: 100%;
  height: 100%;
}

.verification-stage,
.verification-sentence {
  font-family: var(--mono);
}

.verification-stage {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  fill: var(--bone);
  filter: drop-shadow(0 0 3px rgba(87, 214, 168, 0.22));
}

.verification-frame {
  fill: var(--void);
}

.verification-divider {
  fill: none;
  stroke: var(--rule);
  stroke-width: 1;
}

.verification-sentence.verification-generated-token {
  fill: var(--match);
  filter: drop-shadow(0 0 4px rgba(87, 214, 168, 0.7));
}

.verification-sentence.verification-generated-token.is-settled {
  fill: var(--bone);
  filter: none;
}

.verification-sentence {
  font-size: 15px;
  letter-spacing: 0;
  fill: var(--bone);
}

.verification-appended {
  fill: var(--match);
  filter: drop-shadow(0 0 4px rgba(87, 214, 168, 0.75));
}

.verification-scan {
  fill: var(--match);
  filter: drop-shadow(0 0 3px rgba(87, 214, 168, 0.8));
}

.harness-tree {
  font-family: var(--mono);
  font-size: 15px;
  fill: var(--bone);
}

.harness-tree text {
  opacity: 0.88;
}

.harness-tool-name,
.harness-tool-argument {
  opacity: 1;
}

.harness-tool-name.is-updating,
.harness-tool-argument.is-updating {
  animation: harness-tool-update 520ms ease-out;
}

.harness-file.is-pulsing {
  animation: harness-file-pulse 680ms ease-out;
}

.harness-created-file {
  fill: white;
  font-weight: 500;
  filter: drop-shadow(0 0 2px rgba(233, 236, 230, 0.65));
}

.harness-output {
  opacity: 0;
}

.harness-output.is-complete {
  animation: harness-output-arrive 420ms ease-out forwards;
}

.harness-loop-arrow.fig-wire.is-pulsing,
.harness-filesystem-arrow.fig-wire.is-pulsing,
.harness-output-arrow.fig-wire.is-pulsing {
  animation: personhood-arrow-line-pulse 520ms ease-in-out;
}

.harness-loop-arrow:not(.fig-wire).is-pulsing,
.harness-filesystem-arrow:not(.fig-wire).is-pulsing,
.harness-output-arrow:not(.fig-wire).is-pulsing {
  animation: personhood-arrow-head-pulse 520ms ease-in-out;
}

@keyframes harness-tool-update {
  0% {
    opacity: 0.25;
  }

  100% {
    opacity: 1;
  }
}

@keyframes harness-file-pulse {

  0%,
  100% {
    opacity: 0.88;
    fill: var(--bone);
  }

  45% {
    opacity: 1;
    fill: white;
    filter: drop-shadow(0 0 3px rgba(233, 236, 230, 0.85));
  }
}

@keyframes harness-output-arrive {
  from {
    opacity: 0;
    transform: translateY(4px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.lbl-num.personhood-seed-value {
  opacity: 1;
  fill: var(--bone);
}

.personhood-answer {
  opacity: 1;
}

.steering-output-box,
.steering-answer {
  transition: stroke 180ms ease, fill 180ms ease, filter 180ms ease;
}

.steering-output-box.is-steered {
  stroke: var(--match);
}

.steering-answer.is-steered {
  fill: var(--match);
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--match) 55%, transparent));
}

.personhood-bar {
  transition: y 55ms linear, height 55ms linear;
}

.personhood-bar.is-final {
  fill: var(--bone);
  fill-opacity: 0.18;
  stroke: var(--bone);
}

.personhood-agree-label.is-final {
  fill: var(--bone);
  font-weight: 600;
}

.personhood-latest {
  fill: var(--bone);
}

.personhood-arrow.fig-wire.is-pulsing {
  animation: personhood-arrow-line-pulse 320ms ease-in-out;
}

.personhood-arrow:not(.fig-wire).is-pulsing {
  animation: personhood-arrow-head-pulse 320ms ease-in-out;
}

@keyframes personhood-arrow-line-pulse {

  0%,
  100% {
    stroke: var(--faint);
    stroke-width: 1;
  }

  45% {
    stroke: var(--bone);
    stroke-width: 1.6;
  }
}

@keyframes personhood-arrow-head-pulse {

  0%,
  100% {
    fill: var(--faint);
  }

  45% {
    fill: var(--bone);
  }
}

.lbl {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  fill: var(--faint);
}

.lbl-b {
  fill: var(--dim);
}

.lbl-hi {
  fill: var(--bone);
  letter-spacing: 0.1em;
}

.lbl-match {
  fill: var(--match);
}

.lbl-human {
  fill: var(--human);
}

.lbl-flag {
  fill: var(--flag);
}

.lbl-num {
  font-family: var(--mono);
  font-size: 10px;
  fill: var(--dim);
  letter-spacing: 0.02em;
  text-transform: none;
}

.lbl-big {
  font-family: var(--serif);
  font-size: 26px;
  font-style: italic;
  fill: var(--bone);
}

/* ---------- the concept map (pages without a figure) ---------- */

.egograph .node rect {
  fill: var(--panel);
  stroke: var(--rule);
  transition: stroke 0.15s ease, fill 0.15s ease;
}

.egograph .node text {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  fill: var(--dim);
  transition: fill 0.15s ease;
}

.egograph a {
  cursor: pointer;
}

.egograph a:hover .node rect {
  fill: var(--raise);
  stroke: var(--match);
}

.egograph a:hover .node text {
  fill: var(--bone);
}

.egograph a:focus-visible {
  outline: 1px solid var(--match);
}

.egograph .hub rect {
  fill: var(--raise);
  stroke: var(--match);
}

.egograph .hub text {
  fill: var(--bone);
}

.egograph .edge {
  stroke: rgba(233, 236, 230, 0.22);
  stroke-width: 1;
  fill: none;
}

.egograph .edge.back {
  stroke-dasharray: 2 4;
}

/* ---------- motion (replays on page activation) ---------- */

.page .anim {
  opacity: 0;
}

.page.is-active .anim {
  animation: rise 0.5s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
  animation-delay: var(--d, 0s);
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(6px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* .draw wins the `animation` shorthand over .anim, so it owns opacity too */
.page .draw {
  opacity: 1;
  stroke-dasharray: var(--len, 300);
  stroke-dashoffset: var(--len, 300);
}

.page.is-active .draw {
  animation: draw 0.75s ease forwards;
  animation-delay: var(--d, 0s);
}

@keyframes draw {
  to {
    stroke-dashoffset: 0;
  }
}

@media (prefers-reduced-motion: reduce) {

  .page .anim,
  .page .draw {
    opacity: 1;
    animation: none !important;
    stroke-dashoffset: 0;
  }

  .page.is-active {
    transition: none;
  }

  .personhood-bar,
  .personhood-latest {
    transition: none;
  }

  .personhood-arrow {
    animation: none !important;
  }

  .verification-stage,
  .verification-generated-token,
  .verification-prefix-line,
  .verification-appended,
  .verification-scan {
    transition: none;
  }

}

/* ---------- the pane toggle: narrow screens only ---------- */

.pane-toggle {
  display: none;
  border: 1px solid var(--rule);
  border-radius: 3px;
  overflow: hidden;
}

.pane-toggle button {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 4px 9px;
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  cursor: pointer;
}

.pane-toggle button+button {
  border-left: 1px solid var(--rule);
}

.pane-toggle button[aria-pressed="true"] {
  background: var(--raise);
  color: var(--bone);
}

.pane-toggle button:focus-visible {
  outline: 1px solid var(--match);
  outline-offset: -2px;
}

/* ---------- narrow screens ----------
   The split needs roughly 860px: the prose column alone asks for 400, so below
   that the diagram column is squeezed toward nothing. Stacking the two is no
   better — the diagram inherits whatever height the prose leaves, which is
   almost none, and an <svg> sized only by its viewBox cannot resolve a height
   from a percentage width unless its container has one. So the two panes share
   a single full-height cell and the toggle picks between them: each gets the
   whole stage, and the diagram gets back the definite height it needs. */

@media (max-width: 860px) {
  :root {
    --pad-x: 1.15rem;
  }

  .pane-toggle {
    display: flex;
    flex: 0 0 auto;
  }

  /* ornament, and the first thing worth giving up for the toggle */
  .masthead .trace {
    display: none;
  }

  .masthead {
    gap: 0.7rem;
  }

  /* The index is wider than a phone and cannot usefully be narrower: these are
     titles, and wrapping them mid-phrase reads worse than panning. */
  .index {
    overflow-x: auto;
    overscroll-behavior-x: contain;
  }

  .idx-group {
    flex: 0 0 auto;
  }

  .page {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
  }

  .read,
  .view {
    grid-area: 1 / 1;
    min-height: 0;
  }

  [data-pane="diagram"] .read,
  [data-pane="prose"] .view {
    display: none;
  }

  .read {
    border-right: none;
    padding: 1.2rem var(--pad-x) 1.5rem;
  }

  /* The prose is taller than the pane at this size, so it scrolls from the top
     rather than being centred in a space it does not fit. */
  .read > :first-child {
    margin-top: 0;
  }

  .read > :last-child {
    margin-bottom: 0;
  }

  /* The whole figure fits the pane, which makes its labels small — so it is
     pinch-zoomable instead, like a map. touch-action: none hands the gesture to
     makeZoomable() in app.js rather than letting it scroll the pane, and the
     transform it sets needs a fixed origin to compute against. */
  .view {
    overflow: hidden;
    touch-action: none;
    padding: 1.2rem var(--pad-x) 1.5rem;
  }

  .view > * {
    transform-origin: 0 0;
  }
}
