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

/* Overscan padding so drifting backgrounds never expose empty edges */
:root {
  --drift-overscan: 220px; /* >= max drift distance (we drift ~60px) */
  /* Default accent (matches the star card). Each project card overrides via its --<color> modifier class below. */
  --accent-rgb: 99, 179, 237;
  /* Type scale. Eight steps, tightest at the bottom because nearly all of the
     UI text lives between 0.78 and 1rem: the small end needs fine gradations
     to separate a label from body copy, while the display end only needs a few
     widely spaced sizes. Steps climb by roughly 1.09x through --fs-md, then
     open up.

     Every rem-valued font-size in the CSS resolves to one of these. Three
     declarations deliberately stay in em and are NOT tokens, because they are
     sized against whatever they sit inside rather than against the page:
     .site-nav__brand::before, .source-viewer > summary::before, and inline
     .section code. .site-title keeps its own fluid clamp() for the same
     reason. */
  --fs-2xs: 0.78rem;
  --fs-xs: 0.84rem;
  --fs-sm: 0.92rem;
  --fs-md: 1rem;
  --fs-lg: 1.1rem;
  --fs-xl: 1.4rem;
  --fs-2xl: 1.6rem;
  --fs-3xl: 2rem;

  /* Height of the sticky primary nav. .site-nav pins itself to this so the
     project-page .section-nav can stack flush underneath it, and so anchor
     jumps can be offset by a known amount. Keep the two in sync. */
  --site-nav-h: 3.5rem;
}

/* Per-card accent palette. Used by the rgba(var(--accent-rgb), ...) rules
   throughout the stylesheets to tint icon glows, hover halos, and media-band
   gradients. Each project card carries one of these modifier classes. */
.project-card--teal {
  /* Drone card — aqua-cyan; kept distinct from AspireCURES's green-teal. */
  --accent-rgb: 34, 211, 238;
}
.project-card--blue {
  --accent-rgb: 99, 179, 237;
}
.project-card--green {
  --accent-rgb: 30, 158, 150;
}
.mini-project-card--amber {
  --accent-rgb: 246, 173, 85;
}
.mini-project-card--red {
  --accent-rgb: 252, 129, 129;
}
.mini-project-card--purple {
  --accent-rgb: 183, 148, 244;
}
.mini-project-card--indigo {
  --accent-rgb: 129, 140, 248;
}
.mini-project-card--gold {
  --accent-rgb: 246, 213, 92;
}
.mini-project-card--lime {
  --accent-rgb: 163, 230, 53;
}

/* Hidden honeypot field on the contact form (visually offscreen,
   skipped by AT, never reachable via Tab). Formspree drops any
   submission where this field is filled in. */
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
}

html,
body {
  min-height: 100%;
}

html {
  background: #05060c;
  overflow-x: hidden;
  /* Anchor jumps clear the sticky primary nav instead of hiding under it.
     Derived from --site-nav-h rather than restated, so growing the nav moves
     this with it; the extra 0.75rem is the breathing gap under the bar. */
  scroll-padding-top: calc(var(--site-nav-h) + 0.75rem);
}

body {
  position: relative;
  font-family:
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    sans-serif;

  /* Deep-space backdrop + vignette.

     Deliberately much darker than a UI background wants to be. Stars and the
     galaxy are drawn as additive (screen) layers on top, so every level of
     brightness spent here is contrast taken away from them: the previous,
     lighter wash washed the sky out until the star layers read as haze. The
     nebula tints are correspondingly weak and pushed to the corners, away
     from the reading column. */
  background:
    radial-gradient(1250px 780px at 12% -12%, rgba(40, 92, 168, 0.13), transparent 62%),
    radial-gradient(1000px 700px at 88% 6%, rgba(28, 70, 140, 0.1), transparent 58%),
    radial-gradient(950px 660px at 72% 92%, rgba(96, 66, 190, 0.06), transparent 64%),
    radial-gradient(
      1500px 1050px at 50% 35%,
      rgba(0, 0, 0, 0) 0%,
      rgba(0, 0, 0, 0.28) 68%,
      rgba(0, 0, 0, 0.62) 100%
    ),
    linear-gradient(180deg, #050a18 0%, #06070e 55%, #04050b 100%);
  background-color: #05060c;

  color: #f5f5f5;
  line-height: 1.6;
  min-height: 100vh;
}
