/* ==========================================================================
   Scryglass site — reset, fonts, page shell and the two keyframes.
   Depends on tokens.css, which must be loaded first.
   ========================================================================== */

/* --- Self-hosted fonts ----------------------------------------------------
   Space Grotesk 400/500/700 and JetBrains Mono 400/500, latin subset,
   served from /assets/fonts/. font-display:swap so first paint is never
   blocked on the font file; the fallback stacks live in tokens.css.        */

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/space-grotesk-400.woff2') format('woff2');
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/space-grotesk-500.woff2') format('woff2');
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/space-grotesk-700.woff2') format('woff2');
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/jetbrains-mono-400.woff2') format('woff2');
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/jetbrains-mono-500.woff2') format('woff2');
}

/* --- Reset ---------------------------------------------------------------- */

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

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

body,
h1,
h2,
h3,
h4,
p,
figure,
blockquote,
dl,
dd,
ul,
ol {
  margin: 0;
}

ul,
ol {
  padding: 0;
}

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

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

/* Components below set `display` on elements that also ship hidden, so the
   attribute has to outrank them. */
[hidden] {
  display: none !important;
}

/* --- Base ----------------------------------------------------------------- */

body {
  background: var(--bg-surround);
  font-family: var(--font-ui);
  color: var(--text-body);
  font-weight: 400;
  /* `normal`, not a ratio: in the handoff every text component states its own
     line-height, and the pieces that state none — buttons, nav, headings in
     cards — are measured against the browser default. Setting a ratio here
     would silently inflate all of them. */
  line-height: normal;
  -webkit-font-smoothing: antialiased;
}

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

a:hover {
  text-decoration: underline;
}

/* --- Page shell -----------------------------------------------------------
   Every page is a fixed 1240px card on the surround. Responsive behaviour
   below 1240px is WP9; this stays pixel-exact at and above it.             */

.page-card {
  position: relative;
  /* content-box, deliberately: the artboards are 1240px of content inside a
     1px outline, so every gutter and column below is measured against 1240
     and not 1238. This is the one place the global border-box is wrong. */
  box-sizing: content-box;
  width: var(--page-width);
  margin: 0 auto;
  background: var(--bg-page);
  color: var(--text-primary);
  border: 1px solid var(--border);
  overflow: hidden; /* clips the home hero sigil, as the artboards do */
}

/* --- Motion ---------------------------------------------------------------
   The only two keyframes in the design. psPulse drives live status dots;
   psDrift rotates the logo sigil's spark layer.                            */

@keyframes psPulse { 0%,100% { opacity:.55 } 50% { opacity:1 } }
@keyframes psDrift { from { transform:rotate(0deg) } to { transform:rotate(360deg) } }

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

/* ==========================================================================
   WP9 — responsive
   --------------------------------------------------------------------------
   The design is a fixed 1240px card and nothing below it, so everything from
   here down is additive and lives inside a `max-width: 1239px` media query or
   narrower. 1239 rather than 1280: the artboard's own width is 1240, and the
   brief is that the page is pixel-identical at and above it. Nothing in this
   file, or in any other sheet's WP9 section, can match at 1240px or wider.

   The breakpoints, once, so the other sheets can name the same numbers:

     1239  the card stops being a fixed slab and goes fluid; display type
           starts scaling (every clamp is written so its upper bound is still
           the artboard value at 1239, so the step across the boundary is nil)
     1080  four-across strips fold to two
      900  three-across grids and two-column pairs fold to one; the article
           sidebar moves above the body
      860  the header's fixed 82px row becomes a wrapping auto-height one
      760  the 44px gutter steps down to 26
      700  the nav takes a row of its own; wide tables start scrolling
      620  the last two-across grids fold; hero art is dropped
      480  the gutter steps down again, to 20
   ========================================================================== */

/* --- The page card ---------------------------------------------------------
   `width:auto` retires the 1240px measurement without disturbing the
   content-box sizing above: with an auto width the box-sizing mode has no
   effect, so the border still sits outside whatever the viewport leaves.
   The margin is what keeps the surround visible on both sides — without it
   the card would read as the page, and the design's card-on-a-ground
   relationship is the one thing there is to preserve down here.           */

@media (max-width: 1239px) {
  .page-card {
    width: auto;
    margin: 0 16px;
  }
}

/* --- Gutter steps ----------------------------------------------------------
   Every section on every page pads itself with --page-gutter, so the whole
   site tightens from these two rules rather than from a hundred. Redefining
   the token here rather than in tokens.css keeps the design's own value the
   only one that file states.                                              */

@media (max-width: 760px) {
  :root { --page-gutter: 26px; }

  .page-card { margin: 0 12px; }
}

@media (max-width: 480px) {
  :root { --page-gutter: 20px; }

  .page-card { margin: 0 8px; }
}
