/* ─────────────────────────────────────────────────────────────────────────
 * base.css — reset + body defaults
 *
 * Kept minimal so consumers can opt into the body defaults via the .rmd-root
 * class when they don't want global side effects. The bare element reset is
 * safe to apply globally.
 * ───────────────────────────────────────────────────────────────────────── */

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

html,
body {
  margin: 0;
  padding: 0;
}

/* ⚠️ The horizontal scroll-x guard is NOT here on html/body anymore.
 * Putting `overflow-x: clip` (or hidden) on <html> OR <body> turns the root /
 * body into a scroll container, which (a) breaks `position: fixed` descendants
 * like the galaxy backdrop (`.galaxy-bg`) and (b) decouples `window.scrollY` /
 * `documentElement.scrollHeight` from the document scroll — killing the
 * scroll-driven galaxy parallax (regression caught in v47).
 * The guard now lives on the page-content wrapper (`.page`) per surface, which
 * trims any too-wide child WITHOUT stealing the scroll root from the viewport.
 * See the `.page` rule in each page's <style>. */

html {
  scroll-behavior: smooth;
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--type-family-workhorse);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: 'kern' 1, 'liga' 1;
}

a {
  color: inherit;
  text-decoration: none;
}

/* ── Text-flow guards ──────────────────────────────────────────────────────
 * Stop the things that go wrong with big display type in narrow columns:
 *   - no automatic hyphenation (ugly on Coolvetica headlines)
 *   - long unbreakable tokens (URLs, slugs) wrap instead of overflowing
 *   - headings balance their lines (no lonely last word); body wraps "pretty"
 * :where() keeps specificity at 0 so any component/inline style overrides.   */
:where(h1, h2, h3, h4, h5, h6, p, li, blockquote, figcaption, dd, dt) {
  hyphens: manual;
  -webkit-hyphens: manual;
  overflow-wrap: break-word;
}
:where(h1, h2, h3, h4, h5, h6) {
  text-wrap: balance;
}
:where(p, li, figcaption) {
  text-wrap: pretty;
}

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

/* Sienna text selection — the house accent. */
::selection {
  background: var(--cat-sienna);
  color: var(--paper);
}

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

/* ── Dot-matrix animation primitives ───────────────────────────────────────
 * The four brand pattern "moods", as reusable keyframes. DotField (and any
 * dot grid) stagger these per-dot for the wave/constellation/build/chase feel.
 * The hero dot uses `breathe`. All are gated by the reduced-motion block above.
 *   pulse   → Web        · radius+opacity swell, wave-staggered
 *   breathe → Brand      · slow scale+opacity, constellation
 *   rise    → E-commerce · fade in while translating up (build-up)
 *   chase   → Recurring  · quick opacity blink in sequence (orbit/chase)        */
@keyframes breathe {
  0%, 100% { transform: scale(1); opacity: 0.9; }
  50%      { transform: scale(1.08); opacity: 1; }
}
@keyframes dot-pulse {
  0%, 100% { transform: scale(0.72); opacity: 0.28; }
  50%      { transform: scale(1);    opacity: 1; }
}
@keyframes dot-breathe {
  0%, 100% { transform: scale(0.5);  opacity: 0.3; }
  50%      { transform: scale(1);    opacity: 1; }
}
@keyframes dot-rise {
  0%       { transform: translateY(28%) scale(0.8); opacity: 0; }
  20%, 80% { transform: translateY(0)   scale(1);   opacity: 1; }
  100%     { transform: translateY(28%) scale(0.8); opacity: 0; }
}
@keyframes dot-chase {
  0%, 20% { opacity: 1;    transform: scale(1); }
  60%, 100% { opacity: 0.25; transform: scale(0.78); }
}
