/* docs/design/foundation.css
 * Generated by scripts/design/generate-palette.mjs on 2026-04-14.
 * Do not hand-edit. Reproduce via: cd scripts/design && bun run generate
 *
 * Scope: palette (light + dark), typography tokens, and RFC-keyword
 * inline rules. This is the generated foundation layer the site builds on.
 * @font-face declarations are NOT emitted here — they belong to the
 * site build or the preview HTML; see the "Typography tokens" comment
 * below for rationale.
 *
 * Selector strategy for color modes:
 *   :root                                              -> light-mode defaults
 *   @media (prefers-color-scheme: dark)
 *     :root:not([data-theme="light"])                  -> dark via OS preference
 *   :root[data-theme="dark"]                           -> dark via explicit toggle
 *   :root[data-theme="light"]                          -> light via explicit toggle
 *
 * Why the :not() inside the media query: a user who picks light via the UI
 * must win over an OS preference of dark. See docs/DESIGN.md §4.9.
 */

:root {
  /* light mode default */
  --bg: oklch(98.80% 0.0030 250.00);
  --bg-raised: oklch(96.50% 0.0060 250.00);
  --bg-code: oklch(96.50% 0.0060 250.00);
  --border: oklch(87.00% 0.0100 250.00);
  --border-subtle: oklch(92.50% 0.0080 250.00);
  --fg-muted: oklch(58.00% 0.0140 250.00);
  --fg-secondary: oklch(46.00% 0.0150 250.00);
  --fg-body: oklch(24.00% 0.0150 250.00);
  --fg-heading: oklch(15.00% 0.0150 250.00);
  --accent: oklch(46.00% 0.1550 250.00);
  --accent-subtle: oklch(92.00% 0.0500 250.00);
  --must: oklch(50.00% 0.1700 28.00);
  --should: oklch(55.00% 0.1300 70.00);
  --may: oklch(52.00% 0.1000 200.00);

  /* raw grays for one-off tuning */
  --g-50: oklch(98.80% 0.0030 250.00);
  --g-100: oklch(96.50% 0.0060 250.00);
  --g-200: oklch(92.50% 0.0080 250.00);
  --g-300: oklch(87.00% 0.0100 250.00);
  --g-400: oklch(74.00% 0.0120 250.00);
  --g-500: oklch(58.00% 0.0140 250.00);
  --g-600: oklch(46.00% 0.0150 250.00);
  --g-700: oklch(34.00% 0.0150 250.00);
  --g-800: oklch(24.00% 0.0150 250.00);
  --g-900: oklch(15.00% 0.0150 250.00);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  /* dark mode via OS preference */
  --bg: oklch(14.00% 0.0120 250.00);
  --bg-raised: oklch(18.00% 0.0140 250.00);
  --bg-code: oklch(18.00% 0.0140 250.00);
  --border: oklch(28.00% 0.0180 250.00);
  --border-subtle: oklch(22.00% 0.0160 250.00);
  --fg-muted: oklch(55.00% 0.0180 250.00);
  --fg-secondary: oklch(68.00% 0.0160 250.00);
  --fg-body: oklch(90.00% 0.0080 95.00);
  --fg-heading: oklch(96.00% 0.0060 95.00);
  --accent: oklch(78.00% 0.1400 250.00);
  --accent-subtle: oklch(22.00% 0.0550 250.00);
  --must: oklch(82.00% 0.1500 28.00);
  --should: oklch(82.00% 0.1200 70.00);
  --may: oklch(80.00% 0.1000 200.00);

  /* raw grays for one-off tuning */
  --g-50: oklch(14.00% 0.0120 250.00);
  --g-100: oklch(18.00% 0.0140 250.00);
  --g-200: oklch(22.00% 0.0160 250.00);
  --g-300: oklch(28.00% 0.0180 250.00);
  --g-400: oklch(38.00% 0.0200 250.00);
  --g-500: oklch(55.00% 0.0180 250.00);
  --g-600: oklch(68.00% 0.0160 250.00);
  --g-700: oklch(80.00% 0.0120 250.00);
  --g-800: oklch(90.00% 0.0080 95.00);
  --g-900: oklch(96.00% 0.0060 95.00);
}

}

:root[data-theme="dark"] {
  /* dark mode via explicit toggle */
  --bg: oklch(14.00% 0.0120 250.00);
  --bg-raised: oklch(18.00% 0.0140 250.00);
  --bg-code: oklch(18.00% 0.0140 250.00);
  --border: oklch(28.00% 0.0180 250.00);
  --border-subtle: oklch(22.00% 0.0160 250.00);
  --fg-muted: oklch(55.00% 0.0180 250.00);
  --fg-secondary: oklch(68.00% 0.0160 250.00);
  --fg-body: oklch(90.00% 0.0080 95.00);
  --fg-heading: oklch(96.00% 0.0060 95.00);
  --accent: oklch(78.00% 0.1400 250.00);
  --accent-subtle: oklch(22.00% 0.0550 250.00);
  --must: oklch(82.00% 0.1500 28.00);
  --should: oklch(82.00% 0.1200 70.00);
  --may: oklch(80.00% 0.1000 200.00);

  /* raw grays for one-off tuning */
  --g-50: oklch(14.00% 0.0120 250.00);
  --g-100: oklch(18.00% 0.0140 250.00);
  --g-200: oklch(22.00% 0.0160 250.00);
  --g-300: oklch(28.00% 0.0180 250.00);
  --g-400: oklch(38.00% 0.0200 250.00);
  --g-500: oklch(55.00% 0.0180 250.00);
  --g-600: oklch(68.00% 0.0160 250.00);
  --g-700: oklch(80.00% 0.0120 250.00);
  --g-800: oklch(90.00% 0.0080 95.00);
  --g-900: oklch(96.00% 0.0060 95.00);
}

:root[data-theme="light"] {
  /* light mode via explicit toggle */
  --bg: oklch(98.80% 0.0030 250.00);
  --bg-raised: oklch(96.50% 0.0060 250.00);
  --bg-code: oklch(96.50% 0.0060 250.00);
  --border: oklch(87.00% 0.0100 250.00);
  --border-subtle: oklch(92.50% 0.0080 250.00);
  --fg-muted: oklch(58.00% 0.0140 250.00);
  --fg-secondary: oklch(46.00% 0.0150 250.00);
  --fg-body: oklch(24.00% 0.0150 250.00);
  --fg-heading: oklch(15.00% 0.0150 250.00);
  --accent: oklch(46.00% 0.1550 250.00);
  --accent-subtle: oklch(92.00% 0.0500 250.00);
  --must: oklch(50.00% 0.1700 28.00);
  --should: oklch(55.00% 0.1300 70.00);
  --may: oklch(52.00% 0.1000 200.00);

  /* raw grays for one-off tuning */
  --g-50: oklch(98.80% 0.0030 250.00);
  --g-100: oklch(96.50% 0.0060 250.00);
  --g-200: oklch(92.50% 0.0080 250.00);
  --g-300: oklch(87.00% 0.0100 250.00);
  --g-400: oklch(74.00% 0.0120 250.00);
  --g-500: oklch(58.00% 0.0140 250.00);
  --g-600: oklch(46.00% 0.0150 250.00);
  --g-700: oklch(34.00% 0.0150 250.00);
  --g-800: oklch(24.00% 0.0150 250.00);
  --g-900: oklch(15.00% 0.0150 250.00);
}


/* ================================================================== */
/* Typography tokens — docs/DESIGN.md §4.3 / §4.4.                          */
/* Body + display: Pangram Pangram's Uncut Sans (OFL).                 */
/* Code: GitHub Next's Monaspace Xenon (OFL).                          */
/* Neither appears in impeccable's reflex-fonts-to-reject list.        */
/*                                                                     */
/* @font-face declarations are deliberately NOT in this file. They     */
/* belong to whichever layer actually ships the fonts:                 */
/*   - the site build (once /fonts/ is populated with the self-hosted  */
/*     woff2 files and metric-override values are calibrated), OR      */
/*   - the preview HTML (via CDN <link> tags for Fontshare + jsdelivr) */
/* Keeping @font-face out of foundation.css means this file is safe to */
/* load from any origin without phantom 404s against missing paths.    */
/* Reference @font-face template lives in docs/DESIGN.md §4.3.              */
/* ================================================================== */

:root {
  /* Fallback stacks pair Uncut Sans with system-ui (closest x-height match)
   * and Monaspace Xenon with ui-monospace (closest rhythm match). */
  --font-sans: "Uncut Sans", ui-sans-serif, system-ui, -apple-system,
               "Segoe UI", Roboto, "Helvetica Neue", sans-serif,
               "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  --font-mono: "Monaspace Xenon", ui-monospace, "SF Mono", "Cascadia Code",
               Menlo, Consolas, "Liberation Mono", monospace;
  --font-display: var(--font-sans);

  /* OpenType feature hints. "kern" always on; ligatures OFF in mono for
   * explicit spec-operator shapes (>=, !=, ->, etc.). */
  --ff-sans: "kern" 1, "liga" 1, "clig" 1;
  --ff-mono: "kern" 1, "liga" 0, "clig" 0, "calt" 0;
  --ff-tabular: "tnum" 1, "kern" 1; /* for version/date stamps, numeric tables */

  /* Modular scale, 1.25 ratio anchored at --text-base.
   * Body fluid 17 -> 18px between 360px and ~1100px viewport.
   * Headings clamp-scale similarly. Captions and secondary stay fixed. */
  --text-base:       1.0625rem; /* 17px */
  --text-body:       clamp(1.0625rem, 0.975rem + 0.4vw, 1.125rem);
  --text-caption:    0.8125rem; /* ~13px */
  --text-secondary:  0.9375rem; /* ~15px */
  --text-h4:         1rem;
  --text-h3:         1.22rem;
  --text-h2:         1.5rem;
  --text-h1:         clamp(1.85rem, 1.6rem + 1.2vw, 2.25rem);
  --text-code:       0.92rem;

  --leading-body:    1.6;
  --leading-heading: 1.25;
  --leading-code:    1.5;

  --measure:         68ch;   /* body line length; cap per Butterick 45-75 rule */
  --tracking-caps:   0.04em; /* small-caps / ALL CAPS labels */
  --tracking-rfc:    0.02em; /* MUST/SHOULD/MAY inline keywords */
}

/* ================================================================== */
/* RFC-keyword treatment — option 7b (docs/DESIGN.md §4.7).                 */
/* Inline keyword color only. The side-stripe and background-wash      */
/* callout variants were rejected because border-left >1px on a        */
/* card/callout is the #1 banned AI-slop pattern per impeccable's      */
/* <absolute_bans>, even for semantic colors. Alternative block-level  */
/* treatments (leading RFC tag, full background tint) are deferred     */
/* to live-site iteration — see docs/DESIGN.md §4.7.                        */
/* ================================================================== */

.rfc-must   { color: var(--must);   font-weight: 600; letter-spacing: var(--tracking-rfc); }
.rfc-should { color: var(--should); font-weight: 600; letter-spacing: var(--tracking-rfc); }
.rfc-may    { color: var(--may);    font-weight: 600; letter-spacing: var(--tracking-rfc); }
