/* NOT ME — the censor's readout.
 *
 * The page hides nothing. It shows every word in full and annotates it in the
 * margin the way a scanning system would: timestamp, ingest, classification,
 * verdict. The verdict never changes. Total legibility, zero information.
 *
 * Two deliberate choices carry the argument:
 *   1. The palette is the apparatus's own — EU reflex blue for structure, a
 *      machine magenta for anything flagged as synthetic.
 *   2. Machine text is monospace, human text is sans. You can see at a glance
 *      which words came from a machine.
 *
 * No webfonts, no gradients, no shadows, no remote anything.
 */

:root {
  color-scheme: light dark;

  --paper: #E8EBF0;        /* cold blue-grey, carbonless copy paper */
  --paper-raised: #F4F6F9;
  --ink: #0A0E1A;
  --ink-soft: #4A5265;
  --eu: #003399;           /* EU reflex blue: structure, the censor's colour */
  --flag: #E5006D;         /* machine magenta: flagged, synthetic */
  --rule: #C3C9D6;

  /* --flag is 3.86:1 on --paper: fine for rules and chip fills (>=3:1 for
   * non-text UI), too weak for the small mono text that states a verdict.
   * --flag-ink is the same hue darkened to 5.01:1 on --paper / 5.53:1 on
   * --paper-raised, and is the only value allowed to carry magenta *words*
   * in light mode. In dark mode the two are the same colour (5.76:1).
   * tests/test_site_contrast.py measures every pairing below. */
  --flag-ink: #C4005E;
  --on-flag: #FFFFFF;      /* 4.61:1 on --flag */

  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "DejaVu Sans Mono", monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;

  --shell: 52rem;
  --gutter: 14rem;
  --gutter-gap: 2.5rem;
  --scan-key: 4rem;        /* fits the longest key either language uses: VERDICT / VERDIKT */
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #0A0E1A;
    --paper-raised: #131829;
    --ink: #DDE3EE;
    --ink-soft: #8891A6;
    --eu: #6E9BFF;
    --flag: #FF3D8A;
    --rule: #262D42;
    --flag-ink: #FF3D8A;   /* 5.76:1 on --paper */
    --on-flag: #0A0E1A;    /* 5.76:1 on --flag */
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 0 1.5rem 5rem;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-text-size-adjust: 100%;
}

.masthead,
.cover,
main,
.colophon { max-width: var(--shell); margin-left: auto; margin-right: auto; }

/* ---- machine/utility type ------------------------------------------------ */

.docline,
.scan,
h2,
.chat-head,
.msg .who,
.tier h3,
.tier .policy,
.colophon,
button,
.badge-note { font-family: var(--mono); }

.docline,
.scan,
.chat-head,
.msg .who,
.tier .policy,
.badge-note {
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.6;
}

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

.masthead { border-bottom: 2px solid var(--eu); }

.docline {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  margin: 0;
  padding: 1.5rem 0 0.7rem;
  color: var(--ink-soft);
}

.docline .doc-id { color: var(--eu); font-weight: 700; }
.docline .doc-lang { margin-left: auto; }

/* ---- cover --------------------------------------------------------------- */

.cover { padding: 2.75rem 0 2.5rem; }

.display {
  font-family: var(--mono);
  font-size: clamp(2.4rem, 8.5vw, 5.25rem);
  font-weight: 700;
  letter-spacing: -0.05em;
  line-height: 0.92;
  text-transform: uppercase;
  margin: 0;
}

.rule-line {
  font-family: var(--mono);
  font-size: clamp(0.95rem, 2.6vw, 1.15rem);
  letter-spacing: -0.01em;
  color: var(--eu);
  margin: 1rem 0 0;
  max-width: 46ch;
}

/* ---- the scan gutter ----------------------------------------------------- */
/* Real markup, tied to the block it annotates. On a narrow screen it collapses
 * to a log line above the block rather than disappearing: the gutter is the
 * argument, so it is not the part that gets dropped on a phone. */

.block {
  display: grid;
  grid-template-columns: var(--gutter) minmax(0, 1fr);
  column-gap: var(--gutter-gap);
  padding: 2.5rem 0;
  border-top: 1px solid var(--rule);
}

.block:first-child { border-top: 0; padding-top: 0; }

.scan {
  align-self: start;
  position: sticky;
  top: 1.75rem;
  border-left: 2px solid var(--eu);
  padding-left: 0.85rem;
  color: var(--ink-soft);
}

.scan-row { display: flex; gap: 0.6rem; margin: 0; }
.scan-k { flex: 0 0 var(--scan-key); color: var(--ink-soft); }
.scan-v { color: var(--ink); }
.scan-verdict .scan-v { color: var(--flag-ink); font-weight: 700; }

/* The verdict is the conclusion, so it gets the full width of the gutter
 * rather than the key/value split the other rows use: "SYNTHETIC · NO SIGNAL"
 * does not fit beside its own label. */
.scan-verdict { display: block; }
.scan-verdict .scan-k,
.scan-verdict .scan-v { display: block; }

/* The verdict is written into the HTML, so with scripting off it is simply
 * there. hero-chat.js adds .is-pending on load and removes it a beat after the
 * last message lands, so the machine is seen to conclude. The value keeps its
 * space while hidden, so nothing below it moves when the verdict lands. */
.scan-verdict .scan-v { transition: opacity 260ms linear; }
.scan-verdict.is-pending .scan-v { opacity: 0; }
.scan-verdict.is-pending .scan-k::after { content: " \2026"; }

.block-body > *:first-child { margin-top: 0; }
.block-body p,
.block-body li { max-width: 68ch; }

/* ---- section headings ---------------------------------------------------- */

h2 {
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin: 0 0 1.1rem;
  color: var(--ink);
}

h2 .h2-n {
  color: var(--eu);
  margin-right: 0.7rem;
}

/* ---- hero transcript ----------------------------------------------------- */

.chat {
  display: block;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--flag);
  padding: 0.9rem 1.1rem 1.25rem;
  min-height: 12rem;
}

.chat-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0 0 1.1rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--rule);
  color: var(--ink-soft);
}

.chip {
  background: var(--flag);
  color: var(--on-flag);
  font-weight: 700;
  padding: 0.15rem 0.45rem;
}

.msg {
  margin: 0 0 1rem;
  max-width: 46ch;
  padding-left: 0.75rem;
  border-left: 2px solid var(--rule);
}

.msg:last-child { margin-bottom: 0; }
.msg .who { display: block; color: var(--ink-soft); }
.msg .said { display: block; }

/* Human: sans. */
.msg.them .said {
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.5;
}

/* Machine: mono, and flagged. */
.msg.agent {
  margin-left: auto;
  border-left-color: var(--flag);
}

.msg.agent .who { color: var(--flag-ink); }

.msg.agent .said {
  font-family: var(--mono);
  font-size: 0.84rem;
  line-height: 1.6;
  letter-spacing: -0.01em;
  color: var(--flag-ink);
}

.caption { color: var(--ink-soft); font-size: 0.94rem; margin: 1rem 0 0; }

/* ---- tier register ------------------------------------------------------- */
/* 2 -> 1 -> 0. The count down to zero is the escape, so the flag colour drops
 * off at Tier 0: it is the one row on the page the machine has nothing to say
 * about. */

#tiers { border-top: 1px solid var(--rule); margin-top: 1.75rem; }

.tier {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr);
  column-gap: 1.1rem;
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--rule);
}

.tier-n {
  font-family: var(--mono);
  font-size: 2.6rem;
  font-weight: 700;
  letter-spacing: -0.05em;
  line-height: 0.85;
  margin: 0;
  color: var(--flag-ink);
}

.tier.t0 .tier-n { color: var(--ink); }

.tier h3 {
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin: 0 0 0.55rem;
}

.tier .def { margin: 0 0 0.6rem; }

.tier .channels {
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0;
  color: var(--ink-soft);
  margin: 0 0 0.55rem;
}

.tier .policy { margin: 0; color: var(--flag-ink); }
.tier.t0 .policy { color: var(--ink); }

/* ---- manifesto ----------------------------------------------------------- */

.manifesto-body p { margin: 0 0 1.1rem; }
.manifesto-body p:last-child { margin-bottom: 0; }
.manifesto-body ol { padding-left: 1.4rem; margin: 0 0 1.1rem; }
.manifesto-body li { margin-bottom: 0.5rem; }

code {
  font-family: var(--mono);
  font-size: 0.86em;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  padding: 0.05em 0.35em;
  overflow-wrap: anywhere;
}

/* ---- badge generator ----------------------------------------------------- */

#badge-form { display: flex; flex-wrap: wrap; gap: 0.6rem; margin: 1.2rem 0 0.9rem; }

#badge-input {
  flex: 1 1 15rem;
  font-family: var(--mono);
  font-size: 0.9rem;
  padding: 0.6rem 0.7rem;
  background: var(--paper-raised);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: 0;
}

button {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.6rem 1.1rem;
  background: var(--eu);
  color: var(--paper-raised);
  border: 0;
  border-radius: 0;
  cursor: pointer;
}

#badge-output {
  font-family: var(--mono);
  font-size: 0.9rem;
  line-height: 1.55;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-left: 2px solid var(--flag);
  padding: 0.8rem;
  min-height: 3.2rem;
  overflow-wrap: anywhere;
}

#badge-output:empty::before { content: "\2014"; color: var(--ink-soft); }

/* ---- colophon ------------------------------------------------------------ */

.colophon {
  border-top: 2px solid var(--eu);
  margin-top: 3rem;
  padding-top: 1rem;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
}

.colophon p { margin: 0; max-width: 68ch; }

/* ---- links and focus ----------------------------------------------------- */

a { color: var(--eu); text-underline-offset: 0.2em; text-decoration-thickness: 1px; }

:focus-visible {
  outline: 2px solid var(--flag);
  outline-offset: 3px;
}

/* ---- narrow screens ------------------------------------------------------ */

@media (max-width: 58rem) {
  .block {
    display: block;
    padding: 2rem 0;
  }

  /* The readout becomes a log line above the block it annotates. */
  .scan {
    position: static;
    display: flex;
    flex-wrap: wrap;
    column-gap: 1.1rem;
    row-gap: 0;
    border-left: 0;
    border-top: 2px solid var(--eu);
    padding: 0.5rem 0 0.7rem;
    margin-bottom: 1.5rem;
  }

  /* Collapsed to a log line, the verdict goes back inline with the others. */
  .scan-k { flex: 0 0 auto; }
  .scan-verdict { display: flex; }
  .scan-verdict .scan-k,
  .scan-verdict .scan-v { display: inline; }

  .msg.agent { margin-left: 1.25rem; }
}

@media (max-width: 34rem) {
  body { font-size: 1rem; padding: 0 1rem 3.5rem; }
  .tier { grid-template-columns: 2.5rem minmax(0, 1fr); column-gap: 0.85rem; }
  .tier-n { font-size: 2rem; }
  .msg { max-width: none; }
}

/* ---- reduced motion ------------------------------------------------------ */
/* hero-chat.js already renders the end state immediately in this mode; this
 * makes sure nothing animates even if the class is applied some other way. */

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