/* ============================================================
   Chewtoy's Dugout — base · "Night Pitch" (2026-09)
   Global element rules for MIGRATED pages only (html.ctd-v3). Legacy
   pages keep css/core/typography.css until they move over; nothing here
   may leak into them, which is why this file is enqueued per page.
   Document scroll: there is no fixed-height shell and no internal
   scroller — the body scrolls, the header is sticky.
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
html { font-size: 16px; -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font-family: var(--font-body); font-size: var(--fs-16); line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; }
a { color: var(--link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.15em; }
a:hover { color: var(--link-hover); }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--r-1); box-shadow: var(--fx-glow-violet); }
h1, h2, h3, h4, p, figure { margin: 0; }
h1, h2, h3, h4 { color: var(--text); text-wrap: balance; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
ul.ctd-list { margin: 0; padding-left: 1.1em; display: flex; flex-direction: column; gap: var(--s-2); }
ul.ctd-list li::marker { color: var(--accent); }


/* Document scroll + sticky chrome */
/* The site is single-theme dark, so say so once at the root. Without this the
   browser paints its own furniture light — a white scrollbar down the side of
   a plum-black page, light select popups, light date pickers — no matter what
   the page itself is painted. It also makes the `color-scheme: dark` on
   individual controls in shop/product/woo.css belt-and-braces rather than the
   only thing holding them dark. Declared here (a v3 page) and not on the
   always-loaded chrome.css, so a legacy route keeps whatever it had. */
html { color-scheme: dark; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
/* --nav-h, NOT --header-h. The sticky thing at the top of the window is the
   facia (.ctd-header, position:sticky in components.css) and it is --nav-h
   tall; --header-h is 64 and sizes the drawer's title row. They were within
   8px of each other until the bar went to 100 on 2026-09-16, and an anchor
   that lands 36px under a sticky bar is an anchor that missed. */
[id] { scroll-margin-top: calc(var(--nav-h) + var(--s-4)); }
body { min-height: 100vh; display: flex; flex-direction: column; } /* lint-allow: vh — footer sits at the bottom of short pages, nothing is locked */
#main-content { flex: 1 0 auto; outline: none; }
p { max-width: none; } /* the legacy 65ch cap is per-component now (.ctd-prose, .ctd-lede) */

/* ---------- The page ground ----------
   Two fixed backdrop layers behind everything, both aria-invisible and
   pointer-transparent. Split in two on purpose: the blooms breathe, and the
   vignette and grain must NOT inherit that animation.

   `position: fixed` is also the safety property here. The hero bloom taught
   this the hard way — an absolutely positioned layer that scales pushes the
   document's scroll width and hands the whole page a horizontal scrollbar.
   A fixed layer never contributes to scrollable overflow, so it cannot. */
body::before,
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
}

/* Blooms — the only moving part, and opacity only. Animating a transform here
   would repaint a viewport-sized layer forever; opacity composites. */
body::before {
  background-image: var(--fx-ground-bloom);
  animation: ctd-ground-breathe var(--t-ground) var(--ease) infinite alternate;
}
@keyframes ctd-ground-breathe {
  from { opacity: 0.7; }
  to   { opacity: 1; }
}

/* Grain and vignette — static. The tooth grids are fixed to the viewport
   rather than the document so they do not crawl as you scroll. */
body::after {
  background-image: var(--fx-vignette), var(--fx-tooth), var(--fx-tooth-2);
  background-size: auto, 3px 3px, 7px 7px;
}

@media (prefers-reduced-motion: reduce) {
  body::before { animation: none; opacity: 1; }
}

/* Skip link */
.skip-link { position: absolute; left: var(--s-4); top: -100px; z-index: calc(var(--z-header) + 1); padding: var(--s-3) var(--s-4); background: var(--bone-100); color: var(--ink-950); border-radius: var(--r-1); font-weight: 700; text-decoration: none; }
.skip-link:focus { top: var(--s-4); }
.screen-reader-text { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; } /* lint-allow: important — WordPress convention, admin bar relies on it */
.screen-reader-text:focus { position: static !important; width: auto; height: auto; margin: 0; clip: auto; white-space: normal; } /* lint-allow: important */

/* Reading defaults for templates not yet componentised */
ul, ol { padding-left: 1.2em; }
table { border-collapse: collapse; }
input, select, textarea { font: inherit; color: inherit; }
::selection { background: var(--gold-300); color: var(--ink-950); }
