/* Fairgain demo.
 *
 * This is an INSTRUMENT, not an essay. Somebody arrives to watch a system work,
 * so the system fills the screen: dense, high-contrast, anchored by a dark rail,
 * with the explanation cut to what a person needs before the first offer lands.
 *
 * The one idea the design carries: the agents are language models and the guard
 * is ordinary code, so they have different voices. Agents speak in proportional
 * type. The guard speaks in monospace — verdicts, reason codes, every number.
 *
 * No framework, no webfont: font-src is 'self'.
 */

:root {
  --bg: #0e1116;
  --sheet: #ffffff;
  --sheet-2: #f6f7f9;
  --ink: #0e1116;
  --ink-2: #454d5a;
  --muted: #737d8c;
  --line: #e5e8ec;
  --line-2: #cfd5dd;

  --accent: #2b59ff;
  --accent-deep: #1c3fc4;
  --accent-soft: #eef2ff;

  --pass: #0f7a45;
  --pass-bg: #e8f6ee;
  --pass-line: #8fd0ac;
  --veto: #cc2618;
  --veto-bg: #fdecea;
  --veto-line: #f0a9a1;

  --warn: #9a6b00;
  --warn-bg: #fff8e6;
  --warn-line: #ebd191;

  --prose: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
           "Noto Sans Bengali", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
          "Liberation Mono", monospace;

  --r: 10px;
  --pad: clamp(1.15rem, .6rem + 2vw, 2.4rem);

  /* One measured column, declared once. --edge is the inset that puts a
     full-bleed element's CONTENT back on that column: half of whatever the
     window has spare, never less than the gutter. Percentages resolve against
     the element's own containing block, so this works on <header>, on <footer>
     and on a grid item spanning the full track alike. */
  --band: 78rem;
  --edge: calc((100% - min(100% - 2 * var(--pad), var(--band))) / 2);
}

* { box-sizing: border-box; }

html { background: var(--bg); }
body {
  margin: 0;
  min-height: 100vh; display: flex; flex-direction: column;
  font-family: var(--prose);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--sheet);
  -webkit-font-smoothing: antialiased;
}

/* ------------------------------------------------------------------ rail */

/* A dark bar the full width of the window. It gives the page an anchor and a
   horizon, which is most of what separates a designed page from a document. */
.masthead {
  background: var(--bg); color: #fff;
  border-bottom: 1px solid #202836;
}
header {
  padding: .85rem var(--edge);
  display: flex; align-items: center; gap: 1.1rem;
}
.brand {
  display: flex; align-items: center; gap: .6rem; flex: none;
  text-decoration: none; color: #fff;
}
.brand svg { display: block; flex: none; }
.wordmark {
  font-weight: 640; font-size: 1.05rem; letter-spacing: -.01em;
  color: #fff; text-decoration: none;
}
/* The tagline is one line at any width that can hold it. It used to carry a
   34rem cap, which wrapped it into two ragged lines beside the wordmark on a
   wide screen and made the bar look like an accident. */
.tagline {
  color: #9aa4b2; margin: 0; font-size: .82rem; line-height: 1.45;
  padding-left: 1.1rem; border-left: 1px solid #2a3038;
  min-width: 0; text-wrap: balance;
}
/* A quiet marker on the right, so the bar is composed rather than a logo with
   a sentence trailing off it. */
.mast-tag {
  margin-left: auto; flex: none;
  font-family: var(--mono); font-size: .64rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: #8f9aab;
  border: 1px solid #2f3846; border-radius: 999px; padding: .26rem .7rem;
}
@media (max-width: 62rem) {
  header { flex-wrap: wrap; gap: .5rem 1rem; }
  .tagline { padding-left: 0; border-left: 0; order: 3; flex-basis: 100%; font-size: .8rem; }
  .mast-tag { margin-left: auto; }
}
@media (max-width: 34rem) { .tagline { display: none; } }

/* ----------------------------------------------------------------- sheet */

/* The sheet is full-bleed white; only its CONTENT is measured.
 *
 * The column is a GRID TRACK, not a pair of auto margins. That distinction is
 * the whole point: a track cannot be cancelled by a child. Every component in
 * here legitimately sets `margin: 0` or `margin: 1.5rem 0 0` for its own
 * vertical rhythm, and under auto margins each one of those silently threw its
 * section 300-odd pixels to the left of the heading above it. Under a track
 * they cannot: horizontal placement is the parent's business and stays there.
 *
 * Children therefore carry NO horizontal padding of their own. A band that
 * wants its background to reach the window edge takes `.bleed` and gets the
 * same content column back through --edge.
 */
main {
  background: var(--sheet); flex: 1;
  display: grid; align-content: start;
  grid-template-columns:
    [full-start] minmax(var(--pad), 1fr)
    [band-start] minmax(0, var(--band)) [band-end]
    minmax(var(--pad), 1fr) [full-end];
}
main > * { grid-column: band; min-width: 0; }
main > .bleed { grid-column: full; padding-inline: var(--edge); }

/* ------------------------------------------------------------- step rail */

/* Four words on a hairline read as leftover text. This is the same four steps
   drawn as a rail: a numbered token per step, a connector between them, and
   one of them lit. It tells you where you are without being asked to. */
.steps {
  background: var(--sheet-2); border-bottom: 1px solid var(--line);
}
.steps ol {
  display: flex; align-items: center; flex-wrap: wrap;
  margin: 0; padding: 0; list-style: none;
  font-family: var(--mono); font-size: .7rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
}
.steps li {
  display: flex; align-items: center; gap: .5rem;
  padding: .62rem 0; white-space: nowrap;
}
/* The connector is the rail. It belongs between steps, so it hangs off the
   step that follows rather than trailing the last one. */
.steps li + li::before {
  content: ""; width: clamp(.9rem, 2.4vw, 2.2rem); height: 1px;
  background: var(--line-2); margin: 0 clamp(.55rem, 1.4vw, 1rem);
}
.s-n {
  display: grid; place-items: center; flex: none;
  width: 1.35rem; height: 1.35rem; border-radius: 50%;
  border: 1px solid var(--line-2); background: var(--sheet);
  font-size: .66rem; font-weight: 700; letter-spacing: 0; color: var(--muted);
}
.steps .done .s-n { border-color: var(--line-2); background: var(--sheet); color: var(--ink-2); }
.steps .done { color: var(--ink-2); }
.steps .at { color: var(--accent-deep); font-weight: 700; }
.steps .at .s-n { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ------------------------------------------------------------------ type */

h1 {
  font-size: clamp(1.7rem, 1.15rem + 2.4vw, 2.5rem);
  line-height: 1.08; letter-spacing: -.03em; font-weight: 700;
  margin: clamp(1.3rem, 3vw, 2rem) 0 .5rem; max-width: 22ch;
}
h2 { font-size: 1rem; font-weight: 650; letter-spacing: -.01em; margin: 0 0 .3rem; }
.intro { padding-top: 0; }
.intro p { max-width: 44rem; color: var(--ink-2); margin: .55rem 0; font-size: .96rem; }
.intro p strong { color: var(--ink); font-weight: 640; }
.hint, .counter { color: var(--muted); font-size: .84rem; }

/* ------------------------------------------------------------- two sides */

/* The columns share the heading's left edge. They used to add a gutter of
   their own inside a form that was already padded, so every column heading sat
   one gutter to the right of the h1 above it. The rule between them is a
   border and the space around that rule is padding on the inner edges only. */
.sides {
  display: grid; gap: 0; grid-template-columns: 1fr;
  margin: 1.6rem 0 0; border-top: 1px solid var(--line);
}
@media (min-width: 54rem) { .sides { grid-template-columns: 1fr 1fr; } }

.side { padding: 1.35rem 0 1.6rem; background: var(--sheet); border-bottom: 1px solid var(--line); }
@media (min-width: 54rem) {
  .side { padding-right: clamp(1.4rem, 3vw, 2.6rem); }
  .side + .side {
    border-left: 1px solid var(--line);
    padding-left: clamp(1.4rem, 3vw, 2.6rem); padding-right: 0;
  }
}
.side h2 {
  font-size: .72rem; font-family: var(--mono); letter-spacing: .14em;
  text-transform: uppercase; color: var(--accent); margin-bottom: .55rem;
}

textarea {
  width: 100%; font: inherit; font-size: .94rem; line-height: 1.5;
  padding: .75rem .85rem; border: 1px solid var(--line-2);
  border-radius: 8px; resize: vertical; background: var(--sheet); color: var(--ink);
}
textarea::placeholder { color: #9aa3b0; }
textarea:focus-visible, button:focus-visible, a:focus-visible, input:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

.examples { margin: .55rem 0 .6rem; font-size: .82rem; color: var(--muted); }
button.example {
  font: inherit; font-size: .8rem; padding: .2rem .6rem; margin: 0 .2rem .25rem 0;
  border: 1px solid var(--line-2); border-radius: 6px; background: var(--sheet);
  color: var(--accent-deep); cursor: pointer; transition: background .12s, border-color .12s;
}
button.example:hover { border-color: var(--accent); background: var(--accent-soft); }

/* ------------------------------------------------------------ attack box */

fieldset.attack {
  margin: 1.5rem 0; border: 1px solid var(--warn-line); border-radius: var(--r);
  padding: .95rem 1.05rem; background: var(--warn-bg);
}
fieldset.attack legend {
  padding: 0 .45rem; font-weight: 700; font-size: .68rem; color: var(--warn);
  font-family: var(--mono); letter-spacing: .12em; text-transform: uppercase;
}
fieldset.attack label { display: flex; gap: .6rem; align-items: flex-start; font-size: .92rem; }
fieldset.attack .hint { color: #8a6410; margin-bottom: 0; }

/* -------------------------------------------------------------- controls */

button.primary {
  font: inherit; font-weight: 600; font-size: .95rem;
  padding: .7rem 1.35rem; border: 0; border-radius: 8px;
  background: var(--accent); color: #fff; cursor: pointer;
  transition: background .12s, transform .06s;
}
button.primary:hover { background: var(--accent-deep); }
button.primary:active { transform: translateY(1px); }
button.primary[disabled] { background: #aeb6c2; cursor: not-allowed; }

a.secondary { color: var(--accent-deep); font-size: .9rem; text-underline-offset: 2px; }
.actions { margin: 1.5rem 0 2rem; display: flex; gap: 1.1rem; align-items: center; flex-wrap: wrap; }
/* `display: flex` outranks the UA sheet's [hidden] { display: none }, so the
   restart form was on screen from the first second of a run that had not
   started yet. */
.actions[hidden] { display: none; }

.error {
  color: var(--veto); background: var(--veto-bg); border: 1px solid var(--veto-line);
  border-radius: 8px; padding: .65rem .85rem; margin: 1rem 0;
}

/* ---------------------------------------------------------------- footer */

/* Two grey sentences under a hairline is not a footer, it is the end of the
   text. This one closes the page: it repeats the dark rail from the top, says
   what the mark is, and states the four promises as facts rather than as an
   apologetic paragraph. */
footer {
  background: var(--bg); color: #8f9aab; font-size: .82rem;
  padding: 2.2rem var(--edge) 2.6rem; margin-top: 3rem;
}
.foot-inner {
  display: grid; gap: 1.6rem 3rem; grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 54rem) {
  .foot-inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
}
.foot-brand { display: flex; align-items: center; gap: .55rem; }
.foot-brand .wordmark { font-size: .98rem; }
.foot-line { margin: .6rem 0 0; color: #7c8798; line-height: 1.55; max-width: 26rem; }

.foot-facts { margin: 0; padding: 0; list-style: none; display: grid; gap: .1rem; }
@media (min-width: 40rem) { .foot-facts { grid-template-columns: 1fr 1fr; gap: .1rem 2rem; } }
.foot-facts li {
  position: relative; padding: .3rem 0 .3rem 1.25rem; line-height: 1.5; color: #9aa4b2;
}
/* The mark is the same bar that stands between the two agents upstairs. */
.foot-facts li::before {
  content: ""; position: absolute; left: 0; top: .78em;
  width: 7px; height: 1px; background: #46516210; background: #465162;
}
.foot-note {
  margin: 1.7rem 0 0; padding-top: 1.1rem; border-top: 1px solid #202836;
  color: #6b7686; font-size: .76rem;
}

/* ---------------------------------------------------------- confirm page */

details.written { margin: .2rem 0 .8rem; }
details.written summary {
  cursor: pointer; color: var(--muted); font-size: .72rem;
  font-family: var(--mono); letter-spacing: .1em; text-transform: uppercase;
}
.raw {
  margin: .5rem 0 0; padding: .65rem .8rem; background: var(--sheet-2);
  border-left: 2px solid var(--line-2); white-space: pre-wrap;
  font-size: .89rem; color: var(--ink-2);
}
ul.limits { margin: .5rem 0 .9rem; padding: 0; list-style: none; }
ul.limits li {
  margin: 0; padding: .45rem 0 .45rem 1.5rem; border-bottom: 1px solid var(--line);
  position: relative; font-size: .93rem;
}
ul.limits li:last-child { border-bottom: 0; }
ul.limits li::before {
  content: "\2014"; position: absolute; left: 0; color: var(--accent); font-weight: 700;
}
label.confirm {
  display: flex; gap: .6rem; align-items: flex-start; font-size: .92rem;
  border-top: 1px solid var(--line); padding-top: .8rem; margin-top: .6rem;
}
.review {
  background: var(--veto-bg); border: 1px solid var(--veto-line); border-radius: 8px;
  padding: .75rem .85rem; color: var(--veto); font-size: .9rem;
}
.review ul { margin: .4rem 0; padding-left: 1.1rem; }

/* ----------------------------------------------------------- briefs page */

.brief h3 {
  font-family: var(--mono); font-size: .68rem; margin: 0 0 .4rem;
  text-transform: uppercase; letter-spacing: .14em; font-weight: 700;
}
.block { border-left: 2px solid var(--line-2); padding: .1rem 0 .1rem .85rem; margin: 0 0 1.15rem; }
.block ul { margin: .45rem 0 0; padding-left: 1.1rem; font-size: .93rem; }
.block li { margin: .25rem 0; }
/* Own limits and the other side's public profile are coloured differently on
   purpose: the page is an invitation to check that the second column never
   contains the first kind of thing. */
.block.own { border-left-color: var(--accent); }
.block.own h3 { color: var(--accent); }
.block.prefs { border-left-color: var(--warn-line); }
.block.prefs h3 { color: var(--warn); }
.block.public { border-left-color: var(--pass-line); }
.block.public h3 { color: var(--pass); }

.untrusted {
  margin-top: .65rem; border: 1px dashed var(--line-2); border-radius: 8px;
  padding: .55rem .65rem; background: var(--sheet-2);
}
.untrusted-label {
  margin: 0 0 .35rem; font-size: .68rem; color: var(--muted);
  font-family: var(--mono); letter-spacing: .12em; text-transform: uppercase;
}
/* The prompt is machine-facing text, so it is shown on a machine-facing
   surface rather than dressed up as prose. */
pre.prompt {
  white-space: pre-wrap; font-family: var(--mono); font-size: .73rem; line-height: 1.5;
  background: #0e1116; color: #c9d1d9; border-radius: 8px;
  padding: .85rem; max-height: 26rem; overflow: auto;
}
.attack-note {
  margin: 1.4rem 0; border: 1px solid var(--warn-line); background: var(--warn-bg);
  border-radius: var(--r); padding: .95rem 1.05rem;
}
.attack-note p { margin: .4rem 0; max-width: 44rem; font-size: .92rem; }

/* ---------------------------------------------------- negotiation stream */

/* The ticker is the guard's ledger. It stays with you as the stream grows,
   because the running cost is half the point of watching. */
.ticker {
  position: sticky; top: 0; z-index: 5;
  /* full-bleed via .bleed in the template; content stays on the band */
  display: flex; gap: 1.1rem; align-items: baseline; flex-wrap: wrap;
  padding: .7rem 0; margin: 0;
  background: var(--sheet-2); border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.ticker-label {
  font-family: var(--mono); font-size: .66rem; color: var(--muted);
  text-transform: uppercase; letter-spacing: .14em;
}
.ticker-value {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-weight: 700; font-size: 1.05rem; letter-spacing: -.02em; color: var(--ink);
}
.ticker-note { font-size: .76rem; color: var(--muted); }

/* The stream is a timeline: one rule down the left, cards hanging off it. */
ol.turns { list-style: none; margin: 0; padding: 1.4rem 0 .5rem; position: relative; }
ol.turns::before {
  content: ""; position: absolute; left: 5px; top: 1.7rem; bottom: 1rem;
  width: 2px; background: var(--line);
}
li.turn {
  position: relative; margin: 0 0 .8rem 1.9rem; padding: .8rem .95rem;
  background: var(--sheet); border: 1px solid var(--line); border-radius: var(--r);
}
li.turn::before {
  content: ""; position: absolute; left: -1.95rem; top: 1.1rem;
  width: 12px; height: 12px; border-radius: 50%; background: var(--sheet);
  border: 2px solid var(--line-2);
}
li.turn.pass { border-color: var(--pass-line); }
li.turn.pass::before { border-color: var(--pass); background: var(--pass); }
li.turn.veto { border-color: var(--veto-line); box-shadow: 0 0 0 3px var(--veto-bg); }
li.turn.veto::before { border-color: var(--veto); background: var(--veto); }

.turn-head { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.round, .gate {
  font-family: var(--mono); font-size: .7rem; color: var(--muted); letter-spacing: .06em;
}
.gate { order: 8; }
.who { font-weight: 660; letter-spacing: -.01em; font-size: .98rem; }
.type {
  font-family: var(--mono); font-size: .68rem; letter-spacing: .14em;
  color: var(--muted); text-transform: uppercase;
}

/* The verdict is the guard speaking: the strongest mono on the page, because it
   is the one thing here that no model produced. */
.badge {
  font-family: var(--mono); font-size: .7rem; font-weight: 700; letter-spacing: .14em;
  padding: .2rem .55rem; border-radius: 4px; order: 9; margin-left: auto; color: #fff;
}
li.turn.pass .badge { background: var(--pass); }
li.turn.veto .badge { background: var(--veto); }

dl.terms {
  display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0 1.2rem;
  margin: .7rem 0 0; font-size: .88rem;
  border-top: 1px solid var(--line); padding-top: .6rem;
}
/* An offer is a dozen short terms. In one column across a 78rem card they are
   a thin ribbon with half the card empty beside them; in two they read as the
   spec sheet they are. */
@media (min-width: 62rem) {
  dl.terms {
    grid-template-columns: max-content minmax(0, 1fr) max-content minmax(0, 1fr);
    column-gap: 1.2rem;
  }
  dl.terms dt:nth-of-type(2n) { padding-left: 1.6rem; }
}
dl.terms dt { color: var(--muted); font-size: .8rem; padding: .16rem 0; }
dl.terms dd { margin: 0; padding: .16rem 0; font-variant-numeric: tabular-nums; }
dl.terms dt.changed, dl.terms dd.changed { background: var(--warn-bg); font-weight: 650; }

/* The reason codes are the payoff of the page: the moment deterministic code
   overrules two language models, and says exactly why. */
ul.reasons {
  margin: .75rem -.95rem -.8rem; padding: .6rem .95rem .6rem 2.1rem; list-style: none;
  color: var(--veto); font-size: .8rem; font-family: var(--mono); line-height: 1.6;
  background: var(--veto-bg); border-top: 1px solid var(--veto-line);
  border-radius: 0 0 calc(var(--r) - 1px) calc(var(--r) - 1px);
}
ul.reasons li { position: relative; margin: .35rem 0; }
ul.reasons li::before { content: "\2715"; position: absolute; left: -1.15rem; opacity: .75; }

/* The code is the contract, so it keeps the monospace weight it always had.
   The sentence beside it is prose, and is set as prose: a code nobody can
   read is a veto nobody believes. */
.reason-code { font-family: var(--mono); font-weight: 600; }
.reason-text {
  display: block; margin-top: .15rem;
  font-family: var(--prose); font-size: .88rem; line-height: 1.5;
  color: var(--ink); opacity: .85;
}

/* Whose check refused, said once above the codes. Without it "buyer outbound
   check VETO" reads as the system refusing the buyer, rather than the buyer's
   own limits stopping the buyer's own agent. */
.gate-note {
  font-family: var(--prose);
  margin: .75rem 0 0; font-size: .88rem; line-height: 1.55; color: var(--ink);
}

.status {
  color: var(--muted); margin: 0; padding: .8rem 0 1.2rem;
  font-size: .84rem; font-family: var(--mono);
}

/* The outcome is the guard's last word, stamped rather than titled. */
.outcome {
  margin: 0; padding: 1.4rem 0 1.6rem;
  border-top: 1px solid var(--line); background: var(--sheet-2);
}
/* Until the run ends this element holds nothing. Left visible it drew a bare
   grey strip across the page, which looked like a rendering fault. */
.outcome:empty, .status:empty { display: none; }
.outcome h2 {
  text-transform: uppercase; margin-bottom: .45rem; font-size: .9rem;
  font-family: var(--mono); letter-spacing: .16em; font-weight: 700; color: var(--ink);
}
.outcome > p { max-width: 44rem; color: var(--ink-2); font-size: .94rem; }
.withheld {
  border-left: 2px solid var(--line-2); padding-left: .8rem; color: var(--ink-2);
  font-size: .9rem;
}

pre, table { max-width: 100%; overflow-x: auto; }

/* The negotiation page is a live view, so its heading is small and its standing
   caveat sits below the stream rather than in front of it. */
.intro.live { padding-bottom: .4rem; }
.intro.live h1 { font-size: clamp(1.3rem, 1rem + 1.2vw, 1.6rem); margin: 1.25rem 0 .35rem; }
.intro.live p { font-size: .92rem; margin: .35rem 0 .7rem; }
.caveat {
  margin: 0; padding: .9rem 0 1.2rem; color: var(--muted);
  font-size: .84rem; max-width: 48rem;
}

/* ==================================================================== */
/* Landing page                                                          */
/* ==================================================================== */

/* The front page has one job an inner page does not: make somebody want to
   press a button. So it is allowed colour, scale and depth that the working
   pages are not — those stay quiet because a live view should. */

.hero {
  grid-column: full;
  padding: clamp(2.6rem, 6vw, 4.4rem) var(--edge) clamp(2.4rem, 5vw, 3.6rem);
  background:
    radial-gradient(120rem 40rem at 15% -20%, #24399e 0%, transparent 60%),
    radial-gradient(90rem 40rem at 90% 0%, #0f7a70 0%, transparent 55%),
    linear-gradient(180deg, #131a2b 0%, #0e1116 100%);
  color: #fff;
  display: grid; grid-template-columns: 1fr; gap: 2rem; align-items: center;
  border-bottom: 1px solid #1e2531;
}
@media (min-width: 62rem) {
  .hero { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 3.5rem; }
}
/* The band is the grid's job now, so these are plain blocks. */
.hero-inner, .hero-proof { max-width: none; margin: 0; padding: 0; width: auto; min-width: 0; }
.hero-proof { font-family: var(--mono); }

.eyebrow {
  font-family: var(--mono); font-size: .72rem; letter-spacing: .18em;
  text-transform: uppercase; color: #7de3c8; margin: 0 0 1rem;
}
.hero h1 {
  font-size: clamp(2.1rem, 1.1rem + 4vw, 3.6rem);
  line-height: 1.06; letter-spacing: -.035em; font-weight: 700;
  margin: 0 0 1.15rem; max-width: none; color: #fff;
}
.lede {
  font-size: clamp(1rem, .95rem + .3vw, 1.12rem); line-height: 1.6;
  color: #c3cbd8; max-width: 40rem; margin: 0 0 1rem;
}
.lede-note { font-size: .93rem; color: #8e99a9; max-width: 38rem; margin: 0 0 .4rem; }

/* A small, honest picture of what the visitor is about to watch. */
.hero-proof {
  margin: 0 auto; padding: 0 var(--pad) clamp(2.4rem, 5vw, 3.4rem);
  width: 100%; font-family: var(--mono);
}
@media (min-width: 62rem) { .hero-proof { padding: 0; } }
.proof-row {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  background: rgba(255,255,255,.045); border: 1px solid rgba(255,255,255,.1);
  border-radius: 10px; padding: .6rem .8rem; margin-bottom: .5rem;
}
.proof-row.is-veto { border-color: rgba(255,120,105,.45); background: rgba(204,38,24,.16); }
.proof-who { color: #c3cbd8; font-size: .84rem; }
.proof-badge {
  font-size: .68rem; font-weight: 700; letter-spacing: .14em;
  padding: .16rem .5rem; border-radius: 4px; color: #fff;
}
.proof-badge.pass { background: #12a05c; }
.proof-badge.veto { background: #e0392a; }
.proof-reasons {
  font-size: .72rem; line-height: 1.7; color: #ff9a8d;
  padding: .55rem .8rem; border-radius: 10px;
  background: rgba(204,38,24,.14); border: 1px solid rgba(255,120,105,.28);
}

/* ------------------------------------------------------------- the three */

.picker { padding-top: clamp(2.2rem, 5vw, 3.2rem); }
.picker-head {
  font-family: var(--mono); font-size: .72rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--muted); font-weight: 700;
  margin: 0 0 1.1rem;
}

.cards { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 50rem) { .cards { grid-template-columns: repeat(3, 1fr); } }

.card {
  display: flex; flex-direction: column; gap: .5rem;
  padding: 1.4rem 1.35rem 1.25rem; text-decoration: none; color: inherit;
  background: var(--sheet); border: 1px solid var(--line); border-radius: 14px;
  position: relative; overflow: hidden;
  transition: border-color .14s, transform .14s, box-shadow .14s;
}
.card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 4px;
  background: linear-gradient(90deg, var(--accent), #46b8a4);
}
.card:hover {
  border-color: var(--accent); transform: translateY(-2px);
  box-shadow: 0 12px 30px rgba(20, 30, 60, .12);
}
.card-icon {
  font-size: 1.5rem; line-height: 1; color: var(--accent);
  width: 2.6rem; height: 2.6rem; border-radius: 10px; background: var(--accent-soft);
  display: grid; place-items: center; margin-bottom: .25rem;
}
.card-kicker {
  font-family: var(--mono); font-size: .66rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted);
}
.card-title { font-size: 1.35rem; font-weight: 700; letter-spacing: -.02em; }
.card-body { font-size: .92rem; color: var(--ink-2); line-height: 1.5; }
.card-terms { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .35rem; }
.card-terms em {
  font-style: normal; font-family: var(--mono); font-size: .66rem;
  letter-spacing: .04em; padding: .2rem .45rem; border-radius: 5px;
  background: var(--sheet-2); color: var(--ink-2); border: 1px solid var(--line);
}
.card-go {
  margin-top: auto; padding-top: .9rem; font-weight: 640; font-size: .9rem;
  color: var(--accent-deep);
}

/* Two ways into the same demo. They are stacked rather than side by side
   because they are not equal: the two-party run is the one that lets somebody
   check the claim instead of taking it on trust, so it is first and it is
   heavier. */
.card-ways { margin-top: auto; padding-top: 1rem; display: grid; gap: .5rem; }
.way {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--line); border-radius: 10px; padding: .65rem .8rem;
  transition: border-color .12s, background .12s;
}
.way strong { display: block; font-size: .92rem; font-weight: 640; color: var(--accent-deep); }
.way em {
  display: block; font-style: normal; font-size: .8rem; line-height: 1.45;
  color: var(--muted); margin-top: .15rem;
}
.way:hover { border-color: var(--accent); background: var(--accent-soft); }
.way-main { border-color: var(--line-2); background: var(--sheet-2); }
.way-main strong::after { content: " \2192"; }

/* A demo whose wiring is not finished says so and does not pretend. */
.card-soon { opacity: .72; cursor: default; }
.card-soon::before { background: linear-gradient(90deg, #b6bec9, #d4dae2); }
.card-soon:hover { border-color: var(--line); transform: none; box-shadow: none; }
.card-soon .card-icon { color: var(--muted); background: var(--sheet-2); }
.card-soon .card-go { color: var(--muted); }

/* ----------------------------------------------------------------- how */

.how { padding-top: clamp(2.2rem, 5vw, 3rem); padding-bottom: 1rem; }
.how-steps {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .8rem; grid-template-columns: 1fr;
  counter-reset: none;
}
@media (min-width: 56rem) { .how-steps { grid-template-columns: repeat(4, 1fr); gap: 1rem; } }
.how-steps li {
  font-size: .92rem; color: var(--ink-2); line-height: 1.5;
  padding: 1rem 1rem 1.1rem; border: 1px solid var(--line); border-radius: 12px;
  background: var(--sheet-2);
}
.how-steps strong { display: block; color: var(--ink); font-weight: 650; margin-bottom: .15rem; }
.how-n {
  display: grid; place-items: center; width: 1.7rem; height: 1.7rem;
  border-radius: 50%; background: var(--accent); color: #fff;
  font-family: var(--mono); font-size: .78rem; font-weight: 700;
  margin-bottom: .6rem;
}

/* --------------------------------------------------------- what is missing */

/* The gap panel tells somebody what they did NOT say. It is advice, not a
   demand, so it is quieter than a review error — that one means a side cannot
   be used at all, this one means it could be sharper. */
.gaps {
  margin: .2rem 0 1rem; padding: .8rem .9rem;
  background: var(--sheet-2); border: 1px solid var(--line); border-radius: 10px;
}
.gaps-head {
  margin: 0 0 .5rem; font-family: var(--mono); font-size: .68rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--muted); font-weight: 700;
}
.gap-list { margin: 0 0 .5rem; padding: 0; list-style: none; }
.gap-list li {
  position: relative; padding-left: 1.4rem; margin: .35rem 0;
  font-size: .89rem; line-height: 1.5; color: var(--ink-2);
}
.gap-list li::before { position: absolute; left: 0; font-family: var(--mono); font-size: .8rem; }

/* Needed: without it the negotiation is hollow. Helpful: it would be a better
   one. Two weights, because treating them alike would make the important one
   easy to skim past. */
.gap-need li { color: var(--ink); }
.gap-need li::before { content: "!"; color: var(--warn); font-weight: 700; }
.gap-soft li::before { content: "+"; color: var(--muted); }
.gaps-note { margin: .5rem 0 0; font-size: .78rem; color: var(--muted); line-height: 1.45; }

.revise { margin: 0 0 .9rem; }
.revise summary {
  cursor: pointer; color: var(--accent-deep); font-size: .86rem;
  font-family: var(--mono); letter-spacing: .04em;
}
.revise-form { margin: .6rem 0 0; }
.revise-form textarea { margin-bottom: .4rem; }
.revise-form .hint { margin: 0 0 .6rem; }
button.primary.small { font-size: .86rem; padding: .5rem 1rem; }

/* ==================================================================== */
/* Two-party demo                                                        */
/* ==================================================================== */

/* Every page of a two-party run shows ONE side. The first thing it has to
   answer is "which one am I", because a person who is unsure whose limits they
   are looking at cannot check the one claim the page is making. */
.whoami {
  margin: 1.4rem 0 .2rem; font-size: .82rem; color: var(--ink-2);
  font-family: var(--mono); letter-spacing: .02em;
}
.whoami strong { color: var(--accent-deep); font-weight: 700; }

/* One side, one column. The solo pages are two columns because they hold two
   sides; here the second column would be an empty half-screen. */
.one-side { max-width: 46rem; margin: 1.5rem 0 0; }
.one-side .actions { margin-bottom: 2rem; }
.one-side.brief { max-width: 52rem; }

/* --- the two links --- */

.links { display: grid; gap: 1rem; grid-template-columns: 1fr; margin: 1.7rem 0 0; }
@media (min-width: 54rem) { .links { grid-template-columns: 1fr 1fr; } }
.link-card {
  border: 1px solid var(--line); border-radius: 14px; padding: 1.2rem 1.25rem 1.3rem;
  background: var(--sheet); position: relative; overflow: hidden;
}
.link-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 4px;
  background: linear-gradient(90deg, var(--accent), #46b8a4);
}
.link-card h2 {
  font-family: var(--mono); font-size: .72rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--accent); margin: .3rem 0 .4rem;
}
.link-row { display: flex; gap: .5rem; margin: .8rem 0 .9rem; }
.link-input {
  flex: 1; min-width: 0; font-family: var(--mono); font-size: .78rem;
  padding: .55rem .65rem; border: 1px solid var(--line-2); border-radius: 8px;
  background: var(--sheet-2); color: var(--ink-2);
}
button.copy {
  font: inherit; font-size: .78rem; font-family: var(--mono); flex: none;
  padding: .55rem .8rem; border: 1px solid var(--line-2); border-radius: 8px;
  background: var(--sheet); color: var(--accent-deep); cursor: pointer;
}
button.copy:hover { border-color: var(--accent); background: var(--accent-soft); }
a.primary-link {
  display: inline-block; font-weight: 600; font-size: .9rem;
  padding: .6rem 1.1rem; border-radius: 8px; text-decoration: none;
  background: var(--accent); color: #fff;
}
a.primary-link:hover { background: var(--accent-deep); }

/* --- waiting --- */

/* A wait is not an error and not a dead end, so it gets a calm block rather
   than a spinner: the thing being waited for is another person, and no amount
   of animation makes them type faster. */
.waiting {
  margin: 1.8rem 0 2.4rem; max-width: 40rem;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--sheet-2); padding: 1.6rem 1.5rem;
}
.waiting p { margin: .45rem 0; color: var(--ink-2); font-size: .95rem; }
.waiting strong { color: var(--ink); font-weight: 650; }
.waiting-mark {
  font-size: .7rem; letter-spacing: .5em; color: var(--accent);
  margin: 0 0 .6rem !important; animation: pulse 1.6s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .waiting-mark { animation: none; opacity: .7; }
}

/* ---- Working on it -------------------------------------------------------
   Every wait on this demo is a model call, and every one of them used to look
   like a page that had ignored the click. One spinner, used in three places:
   on the button that started the call, in the card where the answer will
   land, and in the status line before the first offer. */

.spinner {
  display: inline-block; width: .82em; height: .82em; flex: none;
  vertical-align: -.08em; margin-right: .5em;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; opacity: .55;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* A busy button keeps its size and colour and loses its hover, because it is
   still the thing that was clicked — it is not disabled scenery. */
button.busy { cursor: progress; }
button.busy .spinner { opacity: .8; }
button:disabled { cursor: not-allowed; }
/* A busy button keeps the accent it had when it was clicked. Greyed out, it
   reads as "this control is unavailable" — which is the opposite of true: it
   is the one thing on the page that is currently doing something. The
   [disabled] rule above is more specific, so this one has to say so too. */
button.primary.busy[disabled] { background: var(--accent); opacity: 1; }

/* The form dims but is not disabled: a disabled field is not submitted, and
   this form is in the middle of being submitted. */
form.is-busy textarea,
form.is-busy input[type="checkbox"] { opacity: .6; }
form.is-busy { cursor: progress; }

/* The note sits above the button it belongs to, so the click point does not
   move under the cursor the moment it appears. */
.busy-note {
  margin: 0 0 .7rem; max-width: 46ch;
  font-size: .82rem; color: var(--ink-2);
}

/* The pending card is the shape of the card that replaces it, so the page
   does not jump when the answer arrives. Dashed, because there is nothing in
   it yet and a solid border would claim otherwise. */
li.turn.pending {
  border-style: dashed; border-color: var(--line-2); background: var(--sheet-2);
}
li.turn.pending::before { border-color: var(--line-2); background: var(--sheet); }
li.turn.pending .who { color: var(--ink-2); }
.thinking { color: var(--muted); font-size: .88rem; }

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

@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; border-right-color: currentColor; opacity: .35; }
}

/* ---- The ledger ----------------------------------------------------------
   The deals page makes a claim with numbers, so the numbers are the page: set
   large, in the mono the guard's verdicts use, because they come from the same
   place — arithmetic over typed terms, not prose. */

.deals-intro { max-width: 62ch; }
.deals-caveat {
  margin-top: .9rem; padding: .75rem .9rem; border-radius: var(--r);
  background: var(--warn-bg); border: 1px solid var(--warn-line);
  color: var(--ink-2); font-size: .88rem;
}

.ledger { background: var(--sheet-2); border-block: 1px solid var(--line); }
.ledger-inner {
  display: grid; gap: 1.4rem 2.4rem; padding: 1.5rem 0;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.tally { display: flex; flex-direction: column; gap: .3rem; }
.tally-n {
  font-family: var(--mono); font-size: 1.5rem; font-weight: 700;
  letter-spacing: -.02em; color: var(--ink);
}
.tally-lead .tally-n { font-size: 2.1rem; color: var(--accent-deep); }
.tally-l { font-size: .82rem; color: var(--muted); max-width: 30ch; }

.deal-list { list-style: none; margin: 1.6rem 0 0; padding: 0; display: grid; gap: .6rem; }
.deal-link {
  display: grid; gap: .35rem .9rem; padding: .95rem 1.1rem;
  grid-template-columns: 1fr auto; align-items: baseline;
  background: var(--sheet); border: 1px solid var(--line); border-radius: var(--r);
  text-decoration: none; color: inherit;
}
.deal-link:hover { border-color: var(--accent); background: var(--accent-soft); }
.deal-headline { font-family: var(--mono); font-weight: 700; font-size: 1rem; }
.deal-value { font-family: var(--mono); color: var(--ink-2); text-align: right; }
.deal-fee { grid-column: 1 / -1; font-size: .9rem; color: var(--ink-2); }
.deal-fee strong { color: var(--pass); font-family: var(--mono); }
.deal-fee em { color: var(--muted); font-style: normal; font-size: .84rem; }
.deal-meta {
  grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: .8rem;
  font-family: var(--mono); font-size: .7rem; color: var(--muted);
  letter-spacing: .04em;
}
/* A two-party deal is the harder thing to do, so it is the one that is marked. */
.deal-mode.is-pair { color: var(--accent-deep); font-weight: 700; }
.deal-go { grid-column: 1 / -1; font-size: .84rem; color: var(--accent); }
.deals-replay-note { margin-top: 1rem; max-width: 60ch; }
.empty-ledger { padding: 2.4rem 0; color: var(--muted); }
.deals-actions { display: flex; flex-wrap: wrap; gap: .8rem; align-items: center; margin-top: 2rem; }

/* The ledger link on a landing card, under the two ways in. */
.card-ledger {
  display: flex; flex-direction: column; gap: .15rem; margin-top: .7rem;
  padding: .6rem .8rem; border-radius: var(--r);
  background: var(--pass-bg); border: 1px solid var(--pass-line);
  text-decoration: none; color: var(--ink);
}
.card-ledger:hover { border-color: var(--pass); }
.card-ledger strong { font-size: .92rem; }
.card-ledger em { font-style: normal; font-size: .8rem; color: var(--ink-2); }

.replay-intro { max-width: 64ch; }
.replay-kicker {
  font-family: var(--mono); font-size: .7rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--muted); margin-bottom: .3rem;
}
.replay-fee {
  margin-top: .8rem; padding: .75rem .9rem; border-radius: var(--r);
  background: var(--pass-bg); border: 1px solid var(--pass-line);
}
.replay-fee strong { font-family: var(--mono); font-size: 1.05rem; }

/* ---- The example picker --------------------------------------------------
   One button per example became a row of buttons as soon as there was more
   than one outcome to demonstrate. A dropdown says what each one IS, which a
   button labelled "English" never did. */

/* The label sits on the first row and the dropdown gets a row of its own: an
   option that says what the pairing DOES is worth more than a narrow control,
   and a truncated one says nothing. */
.examples {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .6rem;
  margin: 0 0 .8rem;
}
.examples label { flex: 1 0 100%; font-size: .84rem; color: var(--muted); }
.example-pick {
  flex: 1 1 auto; min-width: 0;
  font: inherit; font-size: .84rem; color: var(--ink);
  padding: .4rem .55rem; border: 1px solid var(--line-2); border-radius: 6px;
  background: var(--sheet);
}
.example-pick:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
button.example {
  font: inherit; font-size: .82rem; padding: .4rem .8rem; cursor: pointer;
  color: var(--accent-deep); background: var(--accent-soft);
  border: 1px solid var(--line-2); border-radius: 6px;
}
button.example:hover { border-color: var(--accent); }

/* The one line that explains why there is more than one example per side. */
.pick-note {
  margin: 0 0 1.2rem; max-width: 66ch;
  font-size: .88rem; color: var(--ink-2);
}

/* "Start fresh" sits beside the submit, quieter than it: emptying the form is
   a real thing to want and never the main thing. */
.go { display: flex; flex-wrap: wrap; align-items: center; gap: .9rem; margin: 0; }
a.secondary.clear { font-size: .86rem; }
.pick-note strong { color: var(--ink); }
