/* ==========================================================================
   ATHERION - BASE
   Reset, landmarks, focus, accessibility. Concept-agnostic.
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  background: var(--ground);
  scroll-behavior: smooth;
}

body {
  background: var(--ground);
  color: var(--ink-2);
  font-family: var(--font);
  font-size: var(--t-body);
  font-weight: var(--w-rg);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;              /* clip, not hidden: keeps position:sticky working */
}

main, section, footer { min-width: 0; }

img, video, svg, canvas { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }

h1, h2, h3, h4, h5, h6 { font-weight: var(--w-lt); color: var(--ink); text-wrap: balance; }
p, li, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }

/* ---- Focus: legible on black, blue and white ---------------------------- */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--white);
  outline-offset: 3px;
  box-shadow: 0 0 0 5px var(--blue);
}
.t-light :focus-visible {
  outline-color: var(--blue);
  box-shadow: 0 0 0 5px rgba(1,41,229,.22);
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--white); color: var(--black);
  padding: 14px 22px; font-size: var(--t-cap); font-weight: var(--w-md);
}
.skip:focus { left: 0; }

.vh {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ==========================================================================
   MOTION ENGINE - CSS SIDE

   Progressive enhancement contract:
   base CSS renders EVERYTHING visible. The .js class (set synchronously in
   <head>) opts into the hidden-then-revealed state, so a script failure or a
   blocked script can never leave the page blank.

   Scroll-linked animation is expressed entirely in CSS. JS writes a single
   custom property --p (0 → 1) per tracked element; every transform below is
   derived from it with calc(). That keeps the JS to one rAF write per frame.
   ========================================================================== */

[data-anim] { opacity: 1; transform: none; }

/* One reveal, used sparingly on headlines and lede copy only.
   NOTHING clips text: no overflow:hidden, no clip-path on type. That is what
   cut the descender off "engineering", and a masked reveal is not worth the
   risk on a heading whose line-height is below 1. */
.js [data-anim] {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
  transition-delay: var(--d, 0ms);
}
.js [data-anim].in { opacity: 1; transform: none; }

/* Hairline that draws itself - the only non-text motion kept globally */
.js [data-anim="line"]  { opacity: 1; transform: scaleX(0); transform-origin: left center; }
.js [data-anim="line"].in { transform: scaleX(1); }

/* ---- Reduced motion -----------------------------------------------------
   The engine also checks this query before arming, so this is belt-and-braces
   and additionally neutralises any scroll-linked transform. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .js [data-anim] { opacity: 1 !important; transform: none !important; }
  [data-track] { --p: 0 !important; }
  [data-wire] { --p: 1 !important; }   /* wire renders complete, but static */
}
