/*
  Design tokens - palette revised 2026-07-05 at the user's request (the
  original muted Tract Blue/Green/Contrast Gold system read as too flat -
  "nothing makes the page stand out apart from content"). Confirmed
  through three rounds of a side-by-side comparison artifact, not
  guessed at in place. Every color/type decision elsewhere in the CSS
  should trace back to a variable defined here, not a new hard-coded
  value.

  Palette rationale (kept here, not just in memory, so it survives a
  fresh read of the codebase):
    --color-field-white   the cool white of a radiology light table (unchanged)
    --color-bone-ink      the near-black read at a CT bone window (unchanged)
    --color-soft-tissue   the mid-grey soft tissue reads at on T1 (unchanged)
    --color-navy-deep     primary UI chrome - nav bar, primary buttons, site anchor color
    --color-navy-mid      cranial axis (blue = brain, the conventional read); secondary UI, links
    --color-teal          spine axis - muted, grounded in real CSF-flow/myelin-contrast false-color imaging (not neon)
    --color-oxblood       pain axis - red = nociception/inflammation, an intuitive rather than arbitrary mapping
    --color-brass         NOT an axis color - hairline rules and small captions only, deliberately
                          low-contrast against the other accents so it never reads as a fourth "loud" color

  Nav breakpoint is 1024px (see nav.css) - not a variable here because
  it's consumed inside @media, where custom properties can't be used.
*/

@font-face {
  font-family: 'Alegreya';
  font-style: normal;
  font-weight: 500 700;
  font-display: swap;
  unicode-range: U+0000-00FF, U+2018-2019, U+2013-2014;
  src: url('../fonts/alegreya-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Alegreya';
  font-style: normal;
  font-weight: 500 700;
  font-display: swap;
  unicode-range: U+0370-03FF;
  src: url('../fonts/alegreya-greek.woff2') format('woff2');
}
@font-face {
  font-family: 'Alegreya';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  unicode-range: U+0000-00FF, U+2018-2019, U+2013-2014;
  src: url('../fonts/alegreya-italic-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Alegreya';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  unicode-range: U+0370-03FF;
  src: url('../fonts/alegreya-italic-greek.woff2') format('woff2');
}
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0000-00FF, U+2018-2019, U+2013-2014;
  src: url('../fonts/noto-sans-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0370-03FF;
  src: url('../fonts/noto-sans-greek.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0000-00FF;
  src: url('../fonts/ibm-plex-mono-400.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  unicode-range: U+0000-00FF;
  src: url('../fonts/ibm-plex-mono-500.woff2') format('woff2');
}

:root {
  /* palette */
  --color-field-white: #F3F5F6;
  --color-field-raised: #EAEDEE;
  --color-bone-ink: #141A21;
  --color-ink-soft: #2A323B;
  --color-soft-tissue: #5C6670;
  --color-tissue-line: rgba(92, 102, 112, 0.22);
  --color-navy-deep: #12294D;
  --color-navy-deep-wash: rgba(18, 41, 77, 0.08);
  --color-navy-mid: #2C4A73;
  --color-navy-mid-wash: rgba(44, 74, 115, 0.09);
  --color-teal: #1F5C52;
  --color-teal-wash: rgba(31, 92, 82, 0.09);
  --color-oxblood: #6B1F2A;
  --color-oxblood-wash: rgba(107, 31, 42, 0.08);
  --color-brass: #856231;

  /* type families */
  --font-display: 'Alegreya', serif;
  --font-body: 'Noto Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Consolas, monospace;

  /* fluid type scale */
  --fs-2xl: clamp(2.75rem, 2.05rem + 3.1vw, 4.75rem);
  --fs-xl: clamp(2.15rem, 1.8rem + 1.5vw, 3.1rem);
  --fs-l: clamp(1.55rem, 1.35rem + 0.85vw, 2.15rem);
  --fs-m: clamp(1.2rem, 1.1rem + 0.4vw, 1.45rem);
  --fs-body-l: clamp(1.1rem, 1.05rem + 0.2vw, 1.25rem);
  --fs-body: 1rem;
  --fs-body-s: 0.875rem;
  --fs-label: 0.72rem;
  --fs-mono: 0.8rem;
}

/* specialty-axis color mapping - the single source of truth SpecialtyAxis::colorToken()
   points at conceptually; nav/wayfinder/content-tag CSS reads these classes
   rather than hard-coding a color per feature. */
.axis-cranial { --axis-color: var(--color-navy-mid); --axis-wash: var(--color-navy-mid-wash); }
.axis-spine { --axis-color: var(--color-teal); --axis-wash: var(--color-teal-wash); }
.axis-pain { --axis-color: var(--color-oxblood); --axis-wash: var(--color-oxblood-wash); }

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

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

body {
  margin: 0;
  background: var(--color-field-white);
  color: var(--color-bone-ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

::selection {
  background: var(--color-navy-mid-wash);
  color: var(--color-bone-ink);
}

a {
  color: var(--color-navy-mid);
}

/* Visible keyboard focus throughout (PAGE.md accessibility requirement) -
   defined once here so no component needs to re-declare it. Oxblood
   rather than an axis color since focus rings need one unambiguous
   sitewide meaning, not one that changes per content axis. */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--color-oxblood);
  outline-offset: 3px;
}

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

/*
  Scroll-reveal system (reveal.js, IntersectionObserver-driven, per
  PAGE.md's vanilla-JS requirement). [data-reveal] is the opt-in marker
  any template can add to any element - not homepage-specific. Starts
  visible-by-default (progressive enhancement: content isn't hidden if
  JS fails to load) - reveal.js is what adds .js-reveal-ready, and only
  once that's present does the pre-reveal state actually apply.
  data-reveal-delay="1"/"2" staggers a second/third element slightly
  behind the first without needing per-element inline styles.
*/
.js-reveal-ready [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.js-reveal-ready [data-reveal-delay="1"] {
  transition-delay: 0.12s;
}
.js-reveal-ready [data-reveal-delay="2"] {
  transition-delay: 0.24s;
}
.js-reveal-ready [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .js-reveal-ready [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
