/* ============================================================
   Design system — Alec McLeod Consulting

   Tokens, fonts, reset, and typography primitives. Shared by the
   landing page and the print artefacts; load this first.

   House rules, all deliberate:
     - no #fff and no #000 — the palette is warm at both ends
     - exactly six tonal steps, and nothing outside them
     - no shadows, gradients, or blurs, in any state
     - nothing scales, bounces, or overshoots
     - amber is rationed: signals, focus, and one accent per block
     - never style a bare element inside a component (`.card p`),
       or it will outrank the class written for that element
   ============================================================ */

/* ---------- 1. Fonts ------------------------------------- */
/* Self-hosted, subset to Latin, optical sizes cut separately.
   Display is instanced at opsz 60 for fine hairlines at large
   sizes; Text at opsz 16 for sturdier strokes in body copy. */

@font-face {
  font-family: 'Newsreader Display';
  src: url('../fonts/newsreader-display.woff2') format('woff2-variations');
  font-weight: 300 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Newsreader Text';
  src: url('../fonts/newsreader-text.woff2') format('woff2-variations');
  font-weight: 380 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Newsreader Text';
  src: url('../fonts/newsreader-text-italic.woff2') format('woff2-variations');
  font-weight: 400 500;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'Plex Mono';
  src: url('../fonts/plexmono-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Plex Mono';
  src: url('../fonts/plexmono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ---------- 2. Tokens ------------------------------------ */

:root {
  /* Six-step tonal scale — "paper". Mimics the coarse greyscale of a
     Carta panel; no value outside this scale is used anywhere.

     Warm throughout, not neutral grey. Every step carries yellow-red bias,
     so the page reads as uncoated stock rather than a dimmed screen.
     Ink is a warm near-black — pure neutral charcoal looks cold
     against a cream substrate. */
  --ink-0: #f8f5ec;   /* page substrate — cream, never white */
  --ink-1: #f0ebdd;   /* recessed panel, hover fill */
  --ink-2: #ded6c4;   /* hairline rules */
  --ink-3: #756d5c;   /* muted / metadata text — 4.7:1 on --ink-0 */
  --ink-4: #3f382c;   /* secondary headings */
  --ink-5: #241f17;   /* primary ink — warm near-black */

  /* The one accent. 4.9:1 on --ink-0, so it is safe on text. */
  --amber: #a2560a;

  --grain-opacity: 0.03;

  /* Type */
  --font-display: 'Newsreader Display', ui-serif, Georgia, serif;
  --font-text: 'Newsreader Text', ui-serif, Georgia, serif;
  --font-mono: 'Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --size-display: clamp(2.6rem, 6vw, 4.25rem);
  --size-h2: clamp(1.55rem, 3vw, 2.05rem);
  --size-h3: 1.1rem;
  --size-body: clamp(1.0625rem, 0.35vw + 1rem, 1.1875rem);
  --size-meta: 0.8125rem;
  --size-label: 0.6875rem;

  /* Spacing — 4px base */
  --s1: 0.25rem;  --s2: 0.5rem;   --s3: 0.75rem;  --s4: 1rem;
  --s5: 1.5rem;   --s6: 2rem;     --s7: 3rem;     --s8: 4rem;
  --s9: 6rem;     --s10: 8rem;

  /* Corner radius. Matches the rx="3" on the workflow figure's node
     boxes, so buttons and the portrait read as the same family of
     object as the diagram. */
  --radius: 3px;

  /* Measure */
  --measure: 34rem;   /* prose, ~66 characters */
  --page: 46rem;      /* main column */
  --wide: 66rem;      /* header, footer, service grid */

  /* Motion.
     The palette and the hairline language carry the e-ink
     reference; motion does not have to be starved to make the
     point. These curves decelerate hard, so movement arrives
     rather than sliding to a stop. */
  --ease: cubic-bezier(0.22, 0.72, 0.24, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);

  --t-fast: 180ms var(--ease);
  --t-med: 420ms var(--ease);
  --t-reveal: 620ms var(--ease);

  color-scheme: light dark;
}

/* Inverted panel — "night mode" on a modern e-reader */
:root[data-theme='dark'] {
  --ink-0: #16130e;
  --ink-1: #201c15;
  --ink-2: #373126;
  --ink-3: #9b9384;
  --ink-4: #cac2b2;
  --ink-5: #f0ebdf;
  --amber: #e39a3f;
  --grain-opacity: 0.022;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --ink-0: #16130e;
    --ink-1: #201c15;
    --ink-2: #373126;
    --ink-3: #9b9384;
    --ink-4: #cac2b2;
    --ink-5: #f0ebdf;
    --amber: #e39a3f;
    --grain-opacity: 0.022;
  }
}

/* ---------- 3. Reset ------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--ink-0);
  color: var(--ink-5);
  font-family: var(--font-text);
  font-size: var(--size-body);
  font-weight: 400;
  line-height: 1.62;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-variant-ligatures: common-ligatures;
  text-rendering: optimizeLegibility;
}

img, svg { max-width: 100%; height: auto; display: block; }

h1, h2, h3, p, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }

button { font: inherit; color: inherit; background: none; border: none; padding: 0; }

/* ---------- 4. Typography primitives --------------------- */

.display {
  font-family: var(--font-display);
  font-size: var(--size-display);
  font-weight: 350;
  line-height: 1.02;
  letter-spacing: -0.021em;
  text-wrap: balance;
}

.h2 {
  font-family: var(--font-display);
  font-size: var(--size-h2);
  font-weight: 400;
  line-height: 1.14;
  letter-spacing: -0.014em;
  text-wrap: balance;
}

.h3 {
  font-family: var(--font-text);
  font-size: var(--size-h3);
  font-weight: 500;
  line-height: 1.34;
  letter-spacing: -0.006em;
}

/* The machine voice. Mono labels read as device chrome against
   the serif's human prose — this contrast carries the whole
   e-reader register, so labels are always mono and always
   tracked wide. */
.label {
  font-family: var(--font-mono);
  font-size: var(--size-label);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-3);
  line-height: 1;
}

.meta {
  font-size: var(--size-meta);
  color: var(--ink-3);
  line-height: 1.5;
}

/* ---------- 5. Links ------------------------------------- */
/* Underline thickens on hover. Still no shadows and no scaling —
   that restraint is worth keeping even now that motion is
   allowed. */

a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: var(--ink-2);
  transition: text-decoration-color var(--t-fast), color var(--t-fast),
              text-decoration-thickness var(--t-fast);
}
a:hover {
  text-decoration-thickness: 2px;
  text-decoration-color: var(--ink-5);
}

/* Amber: focus rings. */
:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 3px;
  border-radius: 1px;
}

.skip-link {
  position: absolute;
  left: var(--s4);
  top: var(--s4);
  z-index: 100;
  padding: var(--s3) var(--s4);
  background: var(--ink-0);
  border: 1px solid var(--ink-5);
  font-family: var(--font-mono);
  font-size: var(--size-label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-decoration: none;
  transform: translateY(-200%);
}
.skip-link:focus { transform: translateY(0); }

/* ---------- 6. Grain ------------------------------------- */
/* Substrate texture. Must stay subliminal — if you can see it
   as noise, the opacity is wrong. */

.grain {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: var(--grain-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- 7. Reduced motion ---------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    /* Delays matter as much as durations here: a staggered reveal
       with its duration zeroed but its delay intact still makes
       content pop in late and unpredictably. */
    transition-delay: 0s !important;
    animation-delay: 0s !important;
  }
}
