/* Site-wide base. Design tokens come from ds/tokens.css (generated from the Anssay design system), loaded first. */
*, *::before, *::after { box-sizing: border-box; }
/* overflow-x: clip stops sideways scroll (e.g. the hero cursor parked off-screen) without cutting shadows */
html { height: 100%; overflow-x: clip; scroll-padding-top: 96px; } /* anchors land below the sticky nav */
body { margin: 0; min-height: 100%; overflow-x: clip; background: var(--paper); color: var(--ink);
  font-family: var(--font-sans); font-size: 17px; line-height: 1.5; -webkit-font-smoothing: antialiased; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
h1, h2, h3, h4 { font-family: var(--font-sans); font-weight: 700; color: var(--ink); margin: 0 0 10px; line-height: 1.1; letter-spacing: -1px; }
p { margin: 0 0 10px; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; vertical-align: middle; border: 0; }
.s-nav { display: contents; } /* so the sticky header sticks to the page, not to its wrapper */

/* Paper texture: grain + a faint woven grid, laid over a section colour (.tex). Reference: rectraa.com. */
:root {
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .22 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --weave: repeating-linear-gradient(0deg, rgba(15,27,61,.035) 0 1px, transparent 1px 4px), repeating-linear-gradient(90deg, rgba(15,27,61,.03) 0 1px, transparent 1px 4px);
}
.tex { position: relative; isolation: isolate; }
.tex::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; border-radius: inherit;
  background-image: var(--grain), var(--weave); opacity: .5; mix-blend-mode: multiply; }

/* Fade in on scroll ([data-fade], site.js) */
.js [data-fade] { opacity: 0; transform: translateY(45px); filter: blur(10px);
  transition: opacity .8s cubic-bezier(.19,1,.22,1), transform .8s cubic-bezier(.19,1,.22,1), filter .8s cubic-bezier(.19,1,.22,1); }
.js [data-fade].is-in { opacity: 1; transform: none; filter: none; }
@media (prefers-reduced-motion: reduce) { .js [data-fade] { opacity: 1; transform: none; filter: none; transition: none; } }
