/* ====================================================
   Reusable full-page starfield background
   ----------------------------------------------------
   GENERATED FILE - edit tools/make_starfield.py and re-run it
   instead of editing this file by hand.

   Usage: set `body-class: starry` in a page's front matter
   (base.html renders it onto <body>).

   Pure CSS: the sky is tiled radial-gradients, so there is no
   image request and no JavaScript. Three tile sizes give depth,
   and the colour mix is white with rare blue and red accents.

   The pattern lives in custom properties so other fixed layers
   (notably the navbar) can reuse it and stay seamlessly aligned.
   ==================================================== */
/* 44 stars: 41 white (93%), 2 blue (5%), 1 red (2%) */

:root {
  --sky-image:
    radial-gradient(0.63px 0.63px at 57.9px 81.1px, rgba(255, 255, 255, 0.3) 50%, transparent 51%),
    radial-gradient(0.82px 0.82px at 4.2px 95.2px, rgba(255, 255, 255, 0.32) 50%, transparent 51%),
    radial-gradient(0.65px 0.65px at 7.7px 14.2px, rgba(255, 255, 255, 0.34) 50%, transparent 51%),
    radial-gradient(0.62px 0.62px at 23.7px 43.2px, rgba(111, 192, 255, 0.4) 50%, transparent 51%),
    radial-gradient(0.84px 0.84px at 21.4px 17.1px, rgba(255, 255, 255, 0.41) 50%, transparent 51%),
    radial-gradient(0.62px 0.62px at 57.9px 69.8px, rgba(255, 255, 255, 0.4) 50%, transparent 51%),
    radial-gradient(0.78px 0.78px at 95.9px 78.7px, rgba(255, 255, 255, 0.34) 50%, transparent 51%),
    radial-gradient(0.64px 0.64px at 103.7px 10.3px, rgba(255, 255, 255, 0.3) 50%, transparent 51%),
    radial-gradient(0.85px 0.85px at 18.3px 50.5px, rgba(255, 255, 255, 0.28) 50%, transparent 51%),
    radial-gradient(0.61px 0.61px at 19.0px 63.1px, rgba(255, 255, 255, 0.29) 50%, transparent 51%),
    radial-gradient(0.7px 0.7px at 52.1px 38.2px, rgba(255, 255, 255, 0.31) 50%, transparent 51%),
    radial-gradient(0.77px 0.77px at 85.6px 4.8px, rgba(255, 255, 255, 0.26) 50%, transparent 51%),
    radial-gradient(0.8px 0.8px at 110.0px 37.9px, rgba(255, 255, 255, 0.34) 50%, transparent 51%),
    radial-gradient(0.87px 0.87px at 87.1px 28.6px, rgba(255, 255, 255, 0.41) 50%, transparent 51%),
    radial-gradient(0.95px 0.95px at 50.7px 144.7px, rgba(255, 255, 255, 0.79) 50%, transparent 51%),
    radial-gradient(1.05px 1.05px at 11.8px 5.3px, rgba(255, 255, 255, 0.53) 50%, transparent 51%),
    radial-gradient(1.04px 1.04px at 118.8px 11.2px, rgba(255, 255, 255, 0.72) 50%, transparent 51%),
    radial-gradient(1.13px 1.13px at 194.8px 154.7px, rgba(255, 255, 255, 0.76) 50%, transparent 51%),
    radial-gradient(1.12px 1.12px at 134.7px 125.2px, rgba(255, 255, 255, 0.76) 50%, transparent 51%),
    radial-gradient(1.03px 1.03px at 56.6px 16.8px, rgba(255, 255, 255, 0.52) 50%, transparent 51%),
    radial-gradient(1.12px 1.12px at 59.5px 88.7px, rgba(255, 255, 255, 0.57) 50%, transparent 51%),
    radial-gradient(1.0px 1.0px at 38.6px 170.5px, rgba(255, 255, 255, 0.7) 50%, transparent 51%),
    radial-gradient(0.95px 0.95px at 177.0px 51.9px, rgba(255, 255, 255, 0.7) 50%, transparent 51%),
    radial-gradient(1.12px 1.12px at 53.7px 147.3px, rgba(255, 255, 255, 0.59) 50%, transparent 51%),
    radial-gradient(1.12px 1.12px at 157.1px 80.5px, rgba(255, 255, 255, 0.61) 50%, transparent 51%),
    radial-gradient(1.01px 1.01px at 103.3px 43.7px, rgba(255, 255, 255, 0.63) 50%, transparent 51%),
    radial-gradient(0.97px 0.97px at 65.5px 32.3px, rgba(255, 255, 255, 0.67) 50%, transparent 51%),
    radial-gradient(0.93px 0.93px at 27.3px 174.8px, rgba(255, 255, 255, 0.52) 50%, transparent 51%),
    radial-gradient(1.02px 1.02px at 77.3px 8.3px, rgba(255, 122, 138, 0.51) 50%, transparent 51%),
    radial-gradient(1.07px 1.07px at 52.9px 99.3px, rgba(255, 255, 255, 0.55) 50%, transparent 51%),
    radial-gradient(1.03px 1.03px at 131.1px 97.6px, rgba(255, 255, 255, 0.7) 50%, transparent 51%),
    radial-gradient(1.1px 1.1px at 5.5px 176.0px, rgba(255, 255, 255, 0.77) 50%, transparent 51%),
    radial-gradient(1.29px 1.29px at 260.7px 85.1px, rgba(255, 255, 255, 0.98) 50%, transparent 51%),
    radial-gradient(1.32px 1.32px at 189.0px 263.1px, rgba(255, 255, 255, 0.96) 50%, transparent 51%),
    radial-gradient(1.59px 1.59px at 153.7px 190.4px, rgba(255, 255, 255, 0.88) 50%, transparent 51%),
    radial-gradient(1.48px 1.48px at 56.8px 225.2px, rgba(255, 255, 255, 0.94) 50%, transparent 51%),
    radial-gradient(1.56px 1.56px at 278.0px 277.1px, rgba(255, 255, 255, 0.99) 50%, transparent 51%),
    radial-gradient(1.47px 1.47px at 304.4px 317.6px, rgba(255, 255, 255, 0.99) 50%, transparent 51%),
    radial-gradient(1.62px 1.62px at 304.1px 54.9px, rgba(255, 255, 255, 0.83) 50%, transparent 51%),
    radial-gradient(1.56px 1.56px at 29.3px 117.8px, rgba(111, 192, 255, 0.88) 50%, transparent 51%),
    radial-gradient(1.51px 1.51px at 299.2px 81.5px, rgba(255, 255, 255, 0.93) 50%, transparent 51%),
    radial-gradient(1.57px 1.57px at 287.0px 269.4px, rgba(255, 255, 255, 0.96) 50%, transparent 51%),
    radial-gradient(1.55px 1.55px at 144.7px 215.9px, rgba(255, 255, 255, 0.91) 50%, transparent 51%),
    radial-gradient(1.48px 1.48px at 77.0px 15.9px, rgba(255, 255, 255, 0.88) 50%, transparent 51%);
  --sky-size:
    110px 100px,
    110px 100px,
    110px 100px,
    110px 100px,
    110px 100px,
    110px 100px,
    110px 100px,
    110px 100px,
    110px 100px,
    110px 100px,
    110px 100px,
    110px 100px,
    110px 100px,
    110px 100px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    200px 180px,
    360px 320px,
    360px 320px,
    360px 320px,
    360px 320px,
    360px 320px,
    360px 320px,
    360px 320px,
    360px 320px,
    360px 320px,
    360px 320px,
    360px 320px,
    360px 320px;
  /* stars per px^2 of the tiled sky + what fraction twinkles; the JS reads
     these to size the twinkling layer for the current viewport */
  --sky-density: 0.00187689;
  --sky-twinkle-pct: 0.0500;
}

body.starry {
  background-color: #000000;
  background-image: none;
}

body.starry::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-color: #000000;
  background-image: var(--sky-image);
  background-size: var(--sky-size);
  background-repeat: repeat;
}

/* very slow, subtle breathing of the whole sky */
@media (prefers-reduced-motion: no-preference) {
  body.starry::before { animation: sky-breathe 9s ease-in-out infinite; }
}
@keyframes sky-breathe {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.9; }
}

/* --- twinkling stars ---
   A subset of the stars are added as individual elements by
   initSkyTwinkleStars() so each can carry its own delay and duration. The
   tiled layer above stays still; these sit on top and pulse. */
.starry-twinkle-layer {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.starry-twinkle {
  position: absolute;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 0 2px rgba(255, 255, 255, 0.85);
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .starry-twinkle { animation: star-twinkle 2.6s ease-in-out infinite; }
}
@keyframes star-twinkle {
  0%, 100% { opacity: 0.05; transform: scale(0.7); }
  50%      { opacity: 1;    transform: scale(1.2); }
}
/* a few twinkling stars inherit the palette accents so the sparkle is not
   all white */
.starry-twinkle--blue {
  background: #6fc0ff;
  box-shadow: 0 0 3px rgba(111, 192, 255, 0.9);
}
.starry-twinkle--red {
  background: #ff7a8a;
  box-shadow: 0 0 3px rgba(255, 122, 138, 0.9);
}
/* respect users who ask for less motion: keep the stars, drop the pulsing */
@media (prefers-reduced-motion: reduce) {
  .starry-twinkle { opacity: 0.7; }
}

/* keep page content above the sky */
body.starry .intro-header,
body.starry [role="main"],
body.starry footer {
  position: relative;
  z-index: 1;
}

/* --- make the navbar part of the same sky ---
   The navbar ships with its own opaque black background plus its own randomly
   scattered twinkling stars (injected by initNavbarStars), which reads as a
   separate panel sitting above the page.

   Rather than painting a second sky, we let the page's sky show through: it
   lives on `body::before`, is `position: fixed` and spans the whole viewport,
   so the navbar area is already covered by it. Making the navbar transparent
   therefore reveals the very same stars, and because both are anchored to the
   viewport they stay aligned while scrolling.

   Scoped to body.starry, so every non-starry page keeps its opaque navbar. */
body.starry .navbar-custom {
  background-color: transparent;
  background-image: none;
  border-bottom: 0;
  box-shadow: none;
}
/* drop the navbar's own star layers (JS-injected spans + the two static
   ::before/::after stars), otherwise two different star patterns overlap */
body.starry .navbar-custom .navbar-star {
  display: none;
}
body.starry .navbar-custom::before,
body.starry .navbar-custom::after {
  content: none;
}

/* --- footer blends into the night sky --- */
body.starry footer {
  margin-top: 0;
  background-color: transparent;
  background-image: none;
  /* the theme draws a light 1px rule on top of the footer, which reads as a
     stray white line against the dark sky */
  border-top: 0;
}
body.starry footer a,
body.starry footer p.text-muted {
  color: rgba(246, 217, 224, 0.78) !important;
}
body.starry footer a:hover,
body.starry footer a:focus {
  color: #f6d9e0 !important;
}

/* --- page title block on the dark sky --- */
/* the default header assumes a white page, so re-tone it */
body.starry .intro-header.no-img {
  background: none;
}
body.starry .intro-header.no-img .page-heading h1 {
  color: #f6d9e0;
  text-shadow: 0 0 24px rgba(246, 217, 224, 0.28);
}
body.starry .intro-header.no-img .page-heading .page-subheading {
  color: rgba(246, 217, 224, 0.85);
}
body.starry .intro-header .page-heading hr.small {
  background: linear-gradient(90deg,
    rgba(246, 217, 224, 0) 0%,
    rgba(246, 217, 224, 0.85) 30%,
    rgba(255, 255, 255, 0.9) 55%,
    rgba(246, 217, 224, 0.5) 80%,
    rgba(246, 217, 224, 0) 100%);
  box-shadow: 0 0 10px rgba(246, 217, 224, 0.35);
}
