/* ─────────────────────────────────────────────────────────────────────────────
 * global.css — loaded non-blocking by Base.astro via the
 * preload-then-swap pattern (the single pattern used site-wide):
 *   <link rel="preload" as="style" href="..."
 *         onload="this.onload=null;this.rel='stylesheet'">
 *   <noscript><link rel="stylesheet" href="..."></noscript>
 *
 * Contents: link styles, code-block styles, utility classes, non-critical
 * typography. Keep this file small — total CSS budget is ≤10 KB
 * minified+gzipped (enforced by scripts/check-css-budget.mjs).
 *
 * Components reference semantic aliases (`--color-*`); raw palette shades
 * (`--thinwrap-*`) are reserved for `:root` flips.
 * ───────────────────────────────────────────────────────────────────────── */

/* Self-hosted typography. The @font-face declarations moved to
   src/styles/critical.css so the family-to-URL binding is parsed before the
   LCP element renders (FOUT fix). public/styles/fonts.css is now a redirect
   stub; no @import here. */

/* ── Links ─────────────────────────────────────────────────────────────── */
a {
  text-underline-offset: 0.15em;
  transition: color 120ms ease-out;
}

a:hover,
a:focus-visible {
  color: var(--thinwrap-teal-deep);
}

@media (prefers-color-scheme: dark) {
  a:hover,
  a:focus-visible {
    color: var(--thinwrap-teal-soft);
  }
}

a:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ── Inline code + code blocks ─────────────────────────────────────────── */
code,
kbd,
samp,
pre {
  font-family: var(--font-stack-mono);
  font-size: 0.9375em;
}

:not(pre) > code {
  background: var(--color-code-bg);
  /* Pair the dark code-bg with the light code-fg. Without this, inline code
     inherited the dark body text color, computing to ~1.2:1 dark-on-dark
     (fails WCAG 2.2 AA 1.4.3) — flagged site-wide by axe on inline <code>. */
  color: var(--color-code-fg);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  padding: 0.1em 0.35em;
  /* Small horizontal gap so the dark chip doesn't butt against neighboring
     words (the word-space alone reads as cramped next to the filled box). */
  margin-inline: 0.15em;
}

pre {
  background: var(--color-code-bg);
  color: var(--color-code-fg);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: var(--space-4);
  overflow-x: auto;
  line-height: 1.55;
  font-size: var(--font-size-sm);
}

pre code {
  background: transparent;
  border: 0;
  padding: 0;
}

/* ── Block flow defaults ───────────────────────────────────────────────── */
main > * + *,
article > * + * {
  margin-top: var(--space-4);
}

/* Content rhythm inside `.container` wrappers.
 *
 * The reset (`critical.css` → `* { margin: 0 }`) zeroes every default margin,
 * and the rule above only reaches <main>'s DIRECT children. But every content
 * page nests its prose as `main > div.container > header|section > h1/h2/p/…`
 * (two levels down, no shared layout), so titles, leads, and heading→body
 * pairs render flush. This extends the same `--space-4` rhythm to the
 * page-structure level: direct children of `.container` and of its top-level
 * header/section/article (plus a blog post's <article> header/nav).
 *
 * Deliberately CHILD combinators, not descendants: it must NOT reach card or
 * grid internals (`.vendors-card h3`, `.language-page-cards`, `.snippet-section`,
 * `.constraint-block dl`), which manage their own spacing via `gap`. And wrapped
 * in :where() (zero specificity) so any component rule — grid `gap`, an explicit
 * `margin`, `.why h2 { margin-top }` — always wins; this only fills the gaps
 * nothing else covers. */
:where(.container) > * + *,
:where(.container) > :where(header, section, article) > * + *,
:where(.container) > article > :where(header, nav) > * + * {
  margin-block-start: var(--space-4);
}

p,
ul,
ol,
pre,
blockquote {
  max-width: var(--prose-max);
}

/* Layout lists (nav, language pills, card grids built on <ul>) opt out of
   the prose measure — they fill their container instead of the ~72ch cap. */
.site-header-nav-list,
.site-footer-nav-list,
.landing-lang-row,
.pillars-grid,
.scopes-grid,
.facet-list {
  max-width: none;
}

ul,
ol {
  padding-inline-start: var(--space-6);
}

li + li {
  margin-top: var(--space-2);
}

/* HORIZONTAL / grid lists lay items across a row and space them with `gap`,
   so the prose `li + li { margin-top }` above only shifts them vertically —
   it mis-aligned the footer nav ("Privacy" sat above the rest; the header nav
   merely hid it via `align-items: center`) and offset grid cards within a row.
   Opt those out. NOT `.facet-list`: it's a vertical column of checkbox rows
   that legitimately needs the row rhythm (dropping it collapses the rows below
   the WCAG 2.2 target-size / target-offset minimum). */
.site-header-nav-list > li + li,
.site-footer-nav-list > li + li,
.pillars-grid > li + li,
.scopes-grid > li + li {
  margin-top: 0;
}

blockquote {
  border-inline-start: 3px solid var(--color-accent);
  padding-inline-start: var(--space-4);
  color: var(--color-fg-muted);
  font-style: italic;
}

hr {
  border: 0;
  border-top: 1px solid var(--color-border);
  margin-block: var(--space-8);
}

/* Utility helpers moved to src/styles/critical.css to prevent FOUC on
   .visually-hidden SR-only landmarks. See critical.css §"Visibility utilities". */

/* ── Selection ─────────────────────────────────────────────────────────── */
::selection {
  background: var(--thinwrap-teal-soft);
  color: var(--thinwrap-ink-900);
}

@media (prefers-color-scheme: dark) {
  ::selection {
    background: var(--thinwrap-teal-deep);
    color: var(--thinwrap-cream-50);
  }
}

/* ── Reduced motion preference ─────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
