/* forn.al — shared mockup stylesheet
 *
 * Brief: minimalist, functional, borderless. Text and tools only.
 *
 * Three rules, applied without exception:
 *
 * 1. NO BORDERS. No rules, boxes, cards, panels, shadows, or radii anywhere.
 *    Hierarchy comes from whitespace, type size, weight, and indentation.
 *    If a thing needs separating, give it air, not a line.
 *
 * 2. ONE HUE. --reported is the only color on the page. It is the green of a
 *    green check, deliberately desaturated, and it is used exclusively for what
 *    a system claimed or what a document asserts. Anything that is actually true
 *    is set in plain ink. On a site arguing that a green check is not evidence,
 *    the only color should be the color of the thing you should not trust.
 *
 * 3. MONO CARRIES THE PAGE. Anything a machine produced — a count, a command, a
 *    status, a date, a label — is monospace. Serif appears only where a human is
 *    making an argument in sentences. Evidence dominates; prose is the exception.
 *
 * Zero JavaScript. Zero images. Zero external requests.
 */

:root {
  --paper:    #FCFCFC;
  --ink:      #111213;
  --muted:    #5E626A;
  --faint:    #9AA0A8;
  --reported: #4A7C64;  /* the only hue. success you should not trust. */
  --highlight: #F0F0EE; /* used at most once per page, for the true value */
  --bar:      #24262A;  /* magnitude marks. ink, slightly recessive. */

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
          "Liberation Mono", monospace;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua",
           Georgia, serif;

  --measure: 42rem;
  --wide: 52rem;

  --s1: 0.25rem;
  --s2: 0.5rem;
  --s3: 0.875rem;
  --s4: 1.5rem;
  --s5: 2.5rem;
  --s6: 4rem;
  --s7: 6rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper:    #0E0F10;
    --ink:      #E9E9E7;
    --muted:    #9CA1A8;
    --faint:    #656A71;
    --reported: #6FA98B;
    --highlight: #1B1D1F;
    --bar:      #D2D2CE;
  }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 15px;
  line-height: 1.75;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

.page {
  max-width: var(--wide);
  margin: 0 auto;
  padding: var(--s5) var(--s4) var(--s7);
}

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

.top {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s4);
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: var(--s6);
}

.who {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.top nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s3);
  font-size: 0.75rem;
  color: var(--muted);
  /* Flex items default to min-width:auto, which lets the nav refuse to shrink
     and push the whole page wider than the viewport on a phone. */
  min-width: 0;
}

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

h1 {
  font-family: var(--mono);
  font-size: clamp(1.5rem, 4.4vw, 2.375rem);
  font-weight: 600;
  line-height: 1.16;
  letter-spacing: -0.025em;
  margin: 0 0 var(--s4);
  max-width: 24ch;
  text-wrap: balance;
}

h2 {
  font-family: var(--mono);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.4;
  margin: 0 0 var(--s3);
  letter-spacing: -0.01em;
}

/* Section labels. The only structural device on the page — they replace the
   rules and boxes a bordered design would use. */
.label {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 0 0 var(--s4);
}

.label .when {
  float: right;
  letter-spacing: 0.08em;
  text-transform: none;
}

/* Prose is the exception, not the default. Serif signals "a person is making an
   argument here" as distinct from "a machine produced this". */
.prose {
  font-family: var(--serif);
  font-size: 1.0625rem;
  line-height: 1.62;
  color: var(--ink);
  max-width: var(--measure);
  margin: 0 0 var(--s3);
  font-variant-numeric: oldstyle-nums;
}

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

.lede {
  font-family: var(--serif);
  font-size: 1.1875rem;
  line-height: 1.55;
  max-width: var(--measure);
  margin: 0 0 var(--s4);
  font-variant-numeric: oldstyle-nums;
}

section { margin: 0 0 var(--s7); }

/* ---- links ------------------------------------------------------------- */

a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  text-decoration-color: var(--faint);
}
a:hover { text-decoration-thickness: 2px; text-decoration-color: currentColor; }
a:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* Navigation and the masthead are links by position, so they don't need to say so.
   Underlining every one of them makes the top of the page noisier than anything
   below it. */
.top a, .ribbon a { text-decoration: none; }
.top a:hover, .ribbon a:hover { text-decoration: underline; text-decoration-thickness: 1px; }

/* ---- the tools --------------------------------------------------------- */

/* A run of commands with their outputs. Borderless: the alignment does the
   work a box would otherwise do. */
.run {
  font-size: 0.8125rem;
  line-height: 2;
  color: var(--muted);
  margin: 0 0 var(--s4);
  overflow-x: auto;
  /* Capped so the output stays visually paired with the command that produced
     it. Across the full page width the number drifts too far to read as a
     result, which defeats the point of printing them together. */
  max-width: min(100%, 41rem);
}
.run div {
  display: flex;
  gap: var(--s3);
  justify-content: space-between;
  align-items: baseline;
  white-space: nowrap;
  min-width: min(100%, 34rem);
}
.run .cmd { overflow: hidden; text-overflow: ellipsis; }
.run .out { color: var(--ink); font-weight: 500; }
.run .picked .out {
  background: var(--highlight);
  box-decoration-break: clone;
  padding: 0 0.35em;
}
.run .picked .cmd { color: var(--ink); }

/* A borderless data list: label left, value right, aligned. */
.facts {
  font-size: 0.8125rem;
  line-height: 2.1;
  margin: 0 0 var(--s4);
  max-width: min(100%, 34rem);
}
.facts div {
  display: flex;
  gap: var(--s3);
  justify-content: space-between;
  align-items: baseline;
}
.facts dt, .facts .k { color: var(--muted); }
.facts dd, .facts .v { margin: 0; font-weight: 500; }

/* reported / actually — the recurring device. Green is the claim; ink is what
   was true. */
.gap { margin: 0 0 var(--s5); max-width: var(--measure); }
.gap .said,
.gap .was {
  display: block;
  font-size: 0.8125rem;
  line-height: 1.7;
  /* Hanging indent so a wrapped value stays in its column instead of falling
     back under the label. Without this the second line of a long "actually"
     lands at the far left and the two columns stop reading as columns. */
  padding-left: 5.5rem;
  text-indent: -5.5rem;
}
.gap .said { color: var(--reported); }
.gap .was { color: var(--ink); font-weight: 500; }
.gap .said::before,
.gap .was::before {
  display: inline-block;
  width: 5.5rem;
  color: var(--faint);
  font-weight: 400;
  letter-spacing: 0.08em;
  font-size: 0.6875rem;
  text-transform: uppercase;
}
.gap .said::before { content: "reported"; }
.gap .was::before  { content: "actually"; }
.gap.ba .said::before { content: "before"; }
.gap.ba .was::before  { content: "after"; }

.gap h3 {
  font-size: 0.9375rem;
  font-weight: 600;
  margin: 0 0 var(--s2);
  letter-spacing: -0.01em;
}

/* An HTTP trace. Real tool output, used where prose would be weaker. */
.trace {
  font-size: 0.8125rem;
  line-height: 1.95;
  color: var(--muted);
  margin: 0 0 var(--s4);
  white-space: pre-wrap;
  word-break: break-word;
}
.trace b { color: var(--ink); font-weight: 500; }
.trace .green { color: var(--reported); }

/* ---- magnitude bars ----------------------------------------------------
 * One series, so: no legend, no categorical palette, no hue. The bars are ink
 * because they are true; the page's only colour stays reserved for what a
 * system claimed. Marked up as a real table so the values are readable as data
 * without the chart, and every bar is directly labelled — which is also why
 * there is no hover tooltip to add.
 */

.chart {
  width: 100%;
  max-width: min(100%, 40rem);
  border-collapse: collapse;
  font-size: 0.8125rem;
  margin: 0 0 var(--s4);
}
.chart caption {
  caption-side: top;
  text-align: left;
  font-size: 0.6875rem;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--faint);
  padding-bottom: var(--s3);
}
.chart td { padding: 2px 0; vertical-align: middle; }
.chart .lbl { color: var(--muted); white-space: nowrap; padding-right: var(--s3); }
.chart .track { width: 100%; }
.chart .n {
  text-align: right;
  padding-left: var(--s3);
  white-space: nowrap;
  font-weight: 500;
}
.chart .bar {
  height: 10px;
  background: var(--bar);
  border-radius: 0 3px 3px 0;
}

/* The dedupe comparison carries the headline, so its bars are heavier and it
   drops the label column entirely. */
.funnel .bar { height: 22px; }
.funnel .lbl { color: var(--ink); }
.funnel .quiet .bar { background: var(--faint); }

/* roles */
.role { margin: 0 0 var(--s4); max-width: var(--measure); }
.role .rh {
  display: flex;
  gap: var(--s3);
  justify-content: space-between;
  align-items: baseline;
  font-size: 0.875rem;
  font-weight: 600;
}
.role .yr { color: var(--faint); font-weight: 400; font-size: 0.75rem; }
.role p {
  font-family: var(--serif);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--muted);
  margin: var(--s1) 0 0;
  font-variant-numeric: oldstyle-nums;
}

/* footer */
.foot {
  margin-top: var(--s7);
  font-size: 0.75rem;
  color: var(--faint);
  line-height: 2;
}
.foot .stamp { display: block; margin-top: var(--s3); }

/* ---- mockup chrome (not part of the design) ---------------------------- */

.chooser { max-width: var(--wide); margin: 0 auto; padding: var(--s5) var(--s4); }
.chooser h1 { max-width: none; }
.chooser .opt { margin: 0 0 var(--s5); max-width: var(--measure); }
.chooser .opt h2 { margin-bottom: var(--s1); }

.ribbon {
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: var(--s5);
}

@media (max-width: 40rem) {
  body { font-size: 14px; }
  .page { padding: var(--s4) var(--s3) var(--s6); }

  /* The reported/actually labels stop being a left column and become a line of
     their own, so the value gets the full measure. The hanging indent that
     keeps the desktop columns aligned has to come off with them. */
  .gap .said::before, .gap .was::before { display: block; width: auto; }
  .gap .said, .gap .was { padding-left: 0; text-indent: 0; margin-bottom: var(--s2); }

  /* Label/value pairs stack rather than stretching to opposite edges — at this
     width a right-aligned value reads as unrelated to its label. */
  .facts div { display: block; line-height: 1.5; margin-bottom: var(--s3); }
  .facts .k, .facts dt { display: block; font-size: 0.75rem; }
  .facts .v, .facts dd { display: block; margin-left: 0; font-size: 0.875rem; }

  /* The date in a section label sits under the label instead of beside it. */
  .label .when { float: none; display: block; margin-top: var(--s1); }

  /* Commands keep their alignment but scroll within their own strip. */
  .run { max-width: 100%; }
  .run div { min-width: 32rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
