/* ==========================================================================
   Base: reset, document defaults, typography scale, motion & a11y
   ========================================================================== */

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

html{
  scroll-behavior:smooth;
  scroll-padding-top:108px;
  -webkit-text-size-adjust:100%;
  /* The ground colour lives on html, not body, so body::before can paint the
     ambient wash above it. color-scheme darkens scrollbars and form chrome. */
  background:var(--bg);
  color-scheme:dark;
}

body{
  font-family:var(--font-sans);
  font-weight:var(--weight-body);
  color:var(--ink);
  line-height:1.6;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

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

/* ---------- Type ---------- */
/* Display: Norwester. The face has no true lowercase (lowercase codepoints
   are drawn as small caps), so uppercase is forced rather than assumed. */
.display{
  font-family:var(--font-display);
  font-weight:400;
  text-transform:uppercase;
  line-height:.9;
  letter-spacing:.005em;
  text-wrap:balance;
}
h1.display{font-size:clamp(2.5rem,5.1vw,4.7rem);line-height:.9}
h2.display{font-size:clamp(2.1rem,4.6vw,3.7rem)}

/* Accent run inside a display heading. The gradient needs a solid fallback
   because background-clip:text leaves the text invisible where unsupported. */
.display em{font-style:normal;color:var(--accent-ink)}
@supports (background-clip:text) or (-webkit-background-clip:text){
  .display em{
    background:var(--grad-ink);
    -webkit-background-clip:text;background-clip:text;
    color:transparent;
  }
}

/* Sub-headings stay in Montserrat, because they are sentence case and would turn
   into small caps in Norwester. */
h3{
  font-family:var(--font-sans);
  font-weight:var(--weight-strong);
  letter-spacing:-.01em;
  line-height:1.25;
}

/* Label face: Kollektif, uppercase at wide tracking, as specified. */
.eyebrow,.label{
  font-family:var(--font-label);
  font-size:.72rem;
  font-weight:400;
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  color:var(--ink-3);
}

/* The eyebrow carries a short accent rule so section openings have a mark
   of their own without needing extra markup. */
.eyebrow{display:inline-flex;align-items:center;gap:12px}
.eyebrow::before{
  content:'';width:26px;height:1px;flex:none;
  background:linear-gradient(90deg,var(--fresh-sky),rgba(0,166,251,.15));
}

.lede{
  font-size:clamp(1.02rem,1.5vw,1.2rem);
  font-weight:var(--weight-body);
  color:var(--ink-2);
  max-width:62ch;
}

/* Retained for markup compatibility. The label face, not a monospace. */
.mono{font-family:var(--font-label)}

/* ---------- Motion & accessibility ---------- */

/* Reveal-on-scroll. JS adds .in when the element enters the viewport.
   The default travel is upward; .from-left slides in from the leading edge
   and is used where a row reads horizontally, such as the timeline. */
.rv{
  opacity:0;
  transform:translateY(22px);
  transition:opacity .7s var(--ease-soft),transform .7s var(--ease-soft);
}
.rv.from-left{transform:translateX(-26px)}
.rv.in{opacity:1;transform:none}

/* Hero entrance. Runs on load rather than on scroll, staggered by the
   --rise-delay each child sets in sections.css. */
@keyframes rise{
  from{opacity:0;transform:translateY(26px)}
  to{opacity:1;transform:none}
}

:focus-visible{outline:2px solid var(--fresh-sky);outline-offset:3px;border-radius:4px}

/* Visually hidden but available to screen readers. */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

@media(prefers-reduced-motion:reduce){
  *{animation:none!important;transition-duration:.01ms!important}
  .rv{opacity:1;transform:none}
  html{scroll-behavior:auto}
}
