/* The instrument.
 *
 * One palette, one type scale, one set of primitives, shared by every page
 * this project serves. It was inline in concord.html until the conformance
 * suite and the verifier needed the same tokens, and a palette copied into
 * three files is three palettes that agree until someone edits one.
 *
 * app/contrast.test.mjs reads this file and puts every colour that carries
 * meaning through the WCAG formula against both grounds in both themes.
 */

/* ── faces ─────────────────────────────────────────────────────────────────
   Self-hosted. A project whose pitch is about who you trust should not open
   its front page with a request to a third party. */
@font-face{font-family:"Source Serif 4";src:url(/ui/fonts/serif-400.woff2)format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Source Serif 4";src:url(/ui/fonts/serif-600.woff2)format("woff2");
  font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"IBM Plex Mono";src:url(/ui/fonts/mono-400.woff2)format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"IBM Plex Mono";src:url(/ui/fonts/mono-600.woff2)format("woff2");
  font-weight:600;font-style:normal;font-display:swap}

/* ── tokens ────────────────────────────────────────────────────────────────
   The three rung colours are a REVERSIBILITY ramp and are never reused for
   status. Green does not mean success anywhere here; it means "can be
   reversed". An irreversible step that succeeded is still red-orange, because
   what matters about it is that nobody can take it back. */
:root{
  color-scheme: light dark;

  --paper:      oklch(98.5% 0.004 95);
  --paper-sunk: oklch(96.2% 0.006 95);
  --ink:        oklch(23%   0.015 250);
  --ink-2:      oklch(46%   0.014 250);
  --ink-3:      oklch(53%   0.012 250);
  --rule:       oklch(88%   0.008 250);
  --rule-firm:  oklch(78%   0.010 250);

  /* The ramp. These are edges -- 3px rules down the left of a row -- and never
     text, so they are free to carry chroma. */
  --reservable:   oklch(62% 0.13 235);
  --compensable:  oklch(68% 0.12 155);
  --irreversible: oklch(56% 0.20  35);

  /* The same three meanings as *ink*. A colour picked to read as a coloured
     edge at 3px is not the colour that reads as words at 13px: every value
     below was solved for >= 4.5:1 against both grounds, in both themes, rather
     than chosen and hoped for. Separating them is what lets the edge stay
     saturated while the text stays legible. */
  --reservable-ink:   oklch(52% 0.13 235);
  --compensable-ink:  oklch(52% 0.12 155);
  --irreversible-ink: oklch(56% 0.20  35);

  /* A refusal is the instrument working. It is not an error colour. */
  --refusal:    oklch(38% 0.03 250);
  --refusal-bg: oklch(94% 0.012 250);
  --fail:       oklch(52% 0.19 25);
  --seal:       oklch(45% 0.16 15);

  --display:"Source Serif 4",Georgia,"Times New Roman",serif;
  --mono:"IBM Plex Mono",ui-monospace,Menlo,Consolas,monospace;

  --t-hero: clamp(2rem, 1.3rem + 3.4vw, 3.5rem);
  --t-lead: clamp(1.1rem, 0.98rem + 0.6vw, 1.35rem);
  --t-body: 1rem;
  --t-data: 0.875rem;
  --t-cap:  0.8125rem;

  --ease-out: cubic-bezier(0.16,1,0.3,1);
  --ease-set: cubic-bezier(0.65,0,0.35,1);
  --fast:140ms; --base:260ms; --slow:520ms;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --paper:      oklch(19% 0.012 250);
    --paper-sunk: oklch(16% 0.012 250);
    --ink:        oklch(93% 0.008 95);
    --ink-2:      oklch(74% 0.010 250);
    --ink-3:      oklch(60% 0.012 250);
    --rule:       oklch(30% 0.014 250);
    --rule-firm:  oklch(38% 0.016 250);
    --refusal:    oklch(84% 0.02 250);
    --refusal-bg: oklch(24% 0.02 250);
    --reservable-ink:   oklch(60% 0.13 235);
    --compensable-ink:  oklch(59% 0.12 155);
    --irreversible-ink: oklch(62% 0.18  35);
    --fail:       oklch(62% 0.17 25);
    --seal:       oklch(62% 0.13 15);
  }
}
:root[data-theme="dark"]{
  --paper:oklch(19% 0.012 250); --paper-sunk:oklch(16% 0.012 250);
  --ink:oklch(93% 0.008 95); --ink-2:oklch(74% 0.010 250); --ink-3:oklch(60% 0.012 250);
  --rule:oklch(30% 0.014 250); --rule-firm:oklch(38% 0.016 250);
  --refusal:oklch(84% 0.02 250); --refusal-bg:oklch(24% 0.02 250);
  --reservable-ink:oklch(60% 0.13 235); --compensable-ink:oklch(59% 0.12 155);
  --irreversible-ink:oklch(62% 0.18 35);
  --fail:oklch(62% 0.17 25); --seal:oklch(62% 0.13 15);
}

/* ── base ──────────────────────────────────────────────────────────────── */
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--paper); color:var(--ink);
  font:var(--t-body)/1.6 var(--display);
  font-variant-numeric:tabular-nums;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3{margin:0;font-weight:600;line-height:1.15;letter-spacing:-0.011em}
p{margin:0}
code,.mono{font-family:var(--mono);font-size:var(--t-data)}

/* Marginalia: sentence case, in the margin, where a clause reference goes. */
.margin{font-size:var(--t-cap);color:var(--ink-3);letter-spacing:0;font-family:var(--display)}

.skip{position:absolute;left:-9999px;top:0;z-index:20;background:var(--ink);color:var(--paper);
  padding:10px 16px;font-weight:600}
.skip:focus{left:12px;top:12px}
:focus-visible{outline:2px solid var(--reservable);outline-offset:3px;border-radius:2px}

/* ── masthead ──────────────────────────────────────────────────────────── */
.masthead{
  display:flex;align-items:baseline;gap:20px;flex-wrap:wrap;
  padding:14px clamp(20px,5vw,64px); border-bottom:1px solid var(--rule-firm);
  max-width:1080px;margin-inline:auto;width:100%;
}
.wordmark{font-size:1.0625rem;font-weight:600;letter-spacing:-0.02em;
  display:inline-flex;align-items:center;gap:9px}
/* The mark takes the page's ink and the page's irreversible red, so it
   follows the theme without a second file or a second request. */
.wordmark .mark{flex:none;transform:translateY(-1px)}
.masthead nav{margin-left:auto;display:flex;gap:18px;align-items:baseline}
.masthead a,.masthead button.link{
  font-size:var(--t-cap);color:var(--ink-3);text-decoration:none;
  background:none;border:0;padding:0;cursor:pointer;font-family:var(--display);
}
.masthead a:hover,.masthead button.link:hover{color:var(--ink);text-decoration:underline}
.masthead a[aria-current]{color:var(--ink);font-weight:600}
/* A participant that did not turn up is worth noticing, and is not an error. */
.margin.short{color:var(--irreversible-ink)}

main{padding:clamp(28px,5vw,56px) clamp(20px,5vw,64px) 80px;max-width:1080px;margin-inline:auto}

/* ── the two buttons ───────────────────────────────────────────────────── */
.primary{
  font:600 var(--t-body)/1 var(--display);
  background:var(--ink);color:var(--paper);border:0;border-radius:2px;
  padding:13px 26px;cursor:pointer;transition:background var(--fast) var(--ease-out);
}
.primary:hover{background:var(--reservable)}
.primary:disabled{opacity:.45;cursor:default}
.quiet{
  font:400 var(--t-cap)/1 var(--display);color:var(--ink-3);background:none;border:0;
  padding:0;cursor:pointer;text-decoration:underline;text-underline-offset:3px;
}
.quiet:hover{color:var(--ink)}

.field{
  font:var(--t-body)/1.5 var(--display);
  background:var(--paper-sunk);color:var(--ink);
  border:1px solid var(--rule-firm);border-radius:2px;padding:12px 14px;
}
.field::placeholder{color:var(--ink-3)}
.field:focus{outline:none;border-color:var(--reservable);
  box-shadow:0 0 0 3px oklch(62% 0.13 235/.16)}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
}
