/* ============================================
   Josh Comeau CSS Reset
   ============================================ */

/* 1. Use a more-intuitive box-sizing model */
*, *::before, *::after {
  box-sizing: border-box;
}

/* 2. Remove default margin */
* {
  margin: 0;
}

/* 3. Enable keyword animations */
@media (prefers-reduced-motion: no-preference) {
  html {
    interpolate-size: allow-keywords;
  }
}

body {
  /* 4. Add accessible line-height */
  line-height: 1.5;
  text-rendering: optimizeLegibility;
  /* 5. Improve text rendering */
  -webkit-font-smoothing: antialiased;
}

/* 6. Improve media defaults */
img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}

/* 7. Inherit fonts for form controls */
input, button, textarea, select {
  font: inherit;
}

/* 8. Avoid text overflows */
p, h1, h2, h3, h4, h5, h6 {
  overflow-wrap: break-word;
}

/* 9. Improve line wrapping */
p {
  text-wrap: pretty;
}
h1, h2, h3, h4, h5, h6 {
  text-wrap: balance;
}

/* ============================================
   Design tokens

   Every colour, type size and radius the site uses should come from here.

   Each colour is a light-dark() pair, so the site follows the reader's
   light or dark preference with no per-element overrides. The dark half is
   the astrophotography palette: astrophotography posts force
   color-scheme: dark (astrophotography.css), and sky.js draws the
   night sky behind any page that is dark.
   ============================================ */

:root {
  color-scheme: light dark;

  /* Colour */
  --color-background: light-dark(oklch(0.995 0.01 106), oklch(0.057 0.025 268));
  --color-surface: light-dark(oklch(0.98 0.008 106), oklch(0.1 0.035 268));       /* footer, quiet panels */
  --color-field: light-dark(oklch(1 0 0), oklch(0.1 0.035 268));                  /* form fields */
  --color-headline: light-dark(oklch(0.36 0.09 246), oklch(0.94 0.02 255));       /* titles, article text */
  --color-paragraph: light-dark(oklch(0.5 0.03 252), oklch(0.8 0.03 255));        /* secondary copy */
  --color-muted: light-dark(oklch(0.53 0.02 252), oklch(0.68 0.04 255));          /* dates, meta; 4.5:1 */
  --color-link: light-dark(oklch(0.46 0.16 246), oklch(0.76 0.13 213));
  --color-nav: light-dark(oklch(0.28 0.07 255), oklch(0.86 0.03 255));            /* navbar and footer links */
  --color-on-strong: light-dark(oklch(1 0 0), oklch(0.12 0.03 268));              /* text on headline-filled buttons */
  --color-hover-wash: light-dark(oklch(0.95 0.02 255 / 0.5), oklch(1 0 0 / 0.07));
  --color-rule: light-dark(oklch(0.9 0.01 106), oklch(1 0 0 / 0.12));
  --color-rule-soft: light-dark(oklch(0.93 0.008 106), oklch(1 0 0 / 0.08));
  --color-field-border: light-dark(oklch(0.88 0.01 106), oklch(1 0 0 / 0.18));
  --color-field-border-hover: light-dark(oklch(0.8 0.02 250), oklch(1 0 0 / 0.32));
  --color-focus-wash: light-dark(oklch(0.46 0.16 246 / 0.25), oklch(0.76 0.13 213 / 0.35));
  --color-inline-code: light-dark(oklch(0.95 0.01 106), oklch(1 0 0 / 0.08));
  --color-error: light-dark(oklch(0.52 0.15 22), oklch(0.74 0.14 22));
  --color-error-wash: light-dark(oklch(0.98 0.02 20 / 0.96), oklch(0.22 0.06 20 / 0.96));
  --color-warm: light-dark(oklch(0.46 0.13 44), oklch(0.78 0.12 60));             /* recipes */
  --color-warm-wash: light-dark(oklch(0.95 0.035 62), oklch(0.3 0.06 50));
  --color-error-rule: light-dark(oklch(0.6 0.2 20 / 0.2), oklch(0.74 0.14 22 / 0.3));
  --color-tip: light-dark(oklch(0.6 0.12 160), oklch(0.72 0.12 160));   /* "tip" callouts */

  /* Code blocks are dark in both schemes, a shade deeper at night. */
  --color-code-bg: light-dark(oklch(0.2 0.02 250), oklch(0.09 0.035 268));
  --color-code-header: light-dark(oklch(0.24 0.025 250), oklch(0.12 0.04 270));
  --color-code-rule: light-dark(oklch(0.46 0.04 250 / 0.35), oklch(1 0 0 / 0.12));
  --color-code-text: oklch(0.95 0.01 106);
  --color-code-muted: oklch(0.79 0.07 245);
  --color-code-hover: oklch(1 0 0 / 0.08);
  --color-code-scrollbar: oklch(0.52 0.05 246 / 0.55);

  /* Shadows */
  --shadow-raised: 0 10px 30px oklch(0 0 0 / 0.16);
  --shadow-float: 0 20px 45px oklch(0.19 0.02 245 / 0.14);
  --shadow-sheet: 0 24px 64px oklch(0 0 0 / 0.08), 0 3px 12px oklch(0 0 0 / 0.04);

  /* Type */
  --font-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
  --font-serif: 'Georgia', 'Times New Roman', serif;
  --font-display-editorial: 'Cormorant Garamond', 'Georgia', serif;

  --text-2xs: 0.75rem;    /* code block labels, tooltips */
  --text-xs: 0.8125rem;   /* meta, captions, hints */
  --text-code: 0.875rem;  /* code blocks */
  --text-sm: 0.9375rem;   /* UI: links, buttons, labels */
  --text-base: 1rem;      /* form fields */
  --text-md: 1.0625rem;   /* body copy */
  --text-lg: clamp(1.05rem, 1.4vw, 1.2rem);           /* intros */
  --text-section: clamp(1.75rem, 2.6vw, 2.25rem);     /* section headings */
  --text-title: clamp(2.75rem, 6vw, 4.5rem);          /* page titles */

  /* Weights. IBM Plex Sans: 300 body, 500 UI (links, buttons, labels),
     600 emphasis. Cormorant Garamond is only loaded as 300 italic and
     700 upright, so italic display type is 300 and upright is 700; any
     other pairing makes the browser fake it. */

  /* Space: an 8px-based scale */
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-box: 0.75rem;   /* padding inside buttons, fields and small tiles */
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --space-2xl: 3rem;
  --space-3xl: 4rem;

  /* Breakpoints. Media queries can't read custom properties, so these are
     written out where used; keep to these three:
       40rem  phone        (max-width: 40rem)
       52rem  tablet       (max-width: 52rem) / (min-width: 52rem)
       80rem  wide screen  (min-width: 80rem), room in the margins */

  /* Layout */
  --page-width: 64rem;
  --page-gutter: max(1.25rem, 5vw);
  --measure: 42rem;   /* comfortable line length for article text */

  /* Shape */
  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;

  /* Motion */
  --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);

  /* Keyboard focus ring */
  --focus-ring-width: 2px;
  --focus-ring-offset: 3px;

  /* Navbar */
  --navbar-height: 4rem;
  --navbar-blur: 16px;
}

/* The theme toggle (theme.js) records an explicit choice as data-theme on
   <html>; without one, the reader's system preference decides. */
:root[data-theme="light"] {
  color-scheme: light;
}

:root[data-theme="dark"] {
  color-scheme: dark;
}

/* Paper is light: printing a dark page wastes ink and loses the stars. */
@media print {
  :root,
  :root[data-theme] {
    color-scheme: light;
  }
}

/* Base Styles */
html {
  scroll-behavior: smooth;
}

body {
  font-family: var(--font-sans);
  font-optical-sizing: auto;
  font-weight: 300;
  background-color: var(--color-background);
  color: var(--color-paragraph);
}

/* Self-hosted English font subsets to avoid the Google Fonts stylesheet hop. */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("/assets/fonts/ibm-plex-sans-latin-ext.woff2") format("woff2");
  unicode-range:
    U+0100-02BA,
    U+02BD-02C5,
    U+02C7-02CC,
    U+02CE-02D7,
    U+02DD-02FF,
    U+0304,
    U+0308,
    U+0329,
    U+1D00-1DBF,
    U+1E00-1E9F,
    U+1EF2-1EFF,
    U+2020,
    U+20A0-20AB,
    U+20AD-20C0,
    U+2113,
    U+2C60-2C7F,
    U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("/assets/fonts/ibm-plex-sans-latin.woff2") format("woff2");
  unicode-range:
    U+0000-00FF,
    U+0131,
    U+0152-0153,
    U+02BB-02BC,
    U+02C6,
    U+02DA,
    U+02DC,
    U+0304,
    U+0308,
    U+0329,
    U+2000-206F,
    U+20AC,
    U+2122,
    U+2191,
    U+2193,
    U+2212,
    U+2215,
    U+FEFF,
    U+FFFD;
}

@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url("/assets/fonts/cormorant-garamond-italic-latin-ext.woff2") format("woff2");
  unicode-range:
    U+0100-02BA,
    U+02BD-02C5,
    U+02C7-02CC,
    U+02CE-02D7,
    U+02DD-02FF,
    U+0304,
    U+0308,
    U+0329,
    U+1D00-1DBF,
    U+1E00-1E9F,
    U+1EF2-1EFF,
    U+2020,
    U+20A0-20AB,
    U+20AD-20C0,
    U+2113,
    U+2C60-2C7F,
    U+A720-A7FF;
}

@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url("/assets/fonts/cormorant-garamond-italic-latin.woff2") format("woff2");
  unicode-range:
    U+0000-00FF,
    U+0131,
    U+0152-0153,
    U+02BB-02BC,
    U+02C6,
    U+02DA,
    U+02DC,
    U+0304,
    U+0308,
    U+0329,
    U+2000-206F,
    U+20AC,
    U+2122,
    U+2191,
    U+2193,
    U+2212,
    U+2215,
    U+FEFF,
    U+FFFD;
}

@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/cormorant-garamond-700-latin-ext.woff2") format("woff2");
  unicode-range:
    U+0100-02BA,
    U+02BD-02C5,
    U+02C7-02CC,
    U+02CE-02D7,
    U+02DD-02FF,
    U+0304,
    U+0308,
    U+0329,
    U+1D00-1DBF,
    U+1E00-1E9F,
    U+1EF2-1EFF,
    U+2020,
    U+20A0-20AB,
    U+20AD-20C0,
    U+2113,
    U+2C60-2C7F,
    U+A720-A7FF;
}

@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/cormorant-garamond-700-latin.woff2") format("woff2");
  unicode-range:
    U+0000-00FF,
    U+0131,
    U+0152-0153,
    U+02BB-02BC,
    U+02C6,
    U+02DA,
    U+02DC,
    U+0304,
    U+0308,
    U+0329,
    U+2000-206F,
    U+20AC,
    U+2122,
    U+2191,
    U+2193,
    U+2212,
    U+2215,
    U+FEFF,
    U+FFFD;
}

/* Focus Visible Styles */
:focus-visible {
  outline: 2px solid var(--color-link);
  outline-offset: 2px;
}

/* Skip link: the first focusable thing on every page, visually hidden until
   it takes focus. Without it a keyboard user tabs the brand, the menu toggle
   and every nav link before reaching content, on every page. It is clipped
   rather than display:none / visibility:hidden, both of which would take it
   out of the focus order and defeat the point. */
.skip-link {
  position: absolute;
  inset-inline-start: var(--space-md);
  inset-block-start: var(--space-md);
  z-index: 1000;
  padding: var(--space-box) var(--space-md);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-link);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(calc(-100% - var(--space-md) - 1rem));
  transition: transform var(--transition-fast);
}

/* :focus, not :focus-visible. A skip link is only ever reached by keyboard,
   so there is no mouse-focus ring to suppress, and :focus-visible's heuristic
   does not match programmatic focus - which would leave the link hidden for
   anything that focuses it directly. */
.skip-link:focus {
  transform: translateY(0);
  /* Only while shown: parked above the viewport, the shadow's blur still
     reached down into the top of the page as a grey smudge by the brand. */
  box-shadow: var(--shadow-raised);
}

/* The skip target itself should never draw a focus ring: focus lands there
   programmatically via the link, not by tabbing. */
#main-content:focus {
  outline: none;
}

/* Hidden on screen but still read by screen readers. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ============================================
   Shared type and link styles

   The site's recurring looks, used across pages. A component's own class
   keeps only what is particular to it (its margins, width, any size
   variation); the look itself comes from these.
   ============================================ */

/* The big italic title at the top of a page */
.page-title {
  color: var(--color-headline);
  font-family: var(--font-display-editorial);
  font-size: var(--text-title);
  font-style: italic;
  line-height: 1.04;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

/* A section heading within a page */
.section-title {
  color: var(--color-headline);
  font-family: var(--font-display-editorial);
  font-size: var(--text-section);
  font-style: italic;
  line-height: 1.1;
}

/* The serif paragraph introducing a page */
.page-intro {
  max-width: 52ch;
  color: var(--color-paragraph);
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  line-height: 1.7;
}

/* Small grey details: dates, reading time, tags */
.meta {
  color: var(--color-muted);
  font-size: var(--text-xs);
}

/* A quiet standalone link ("All posts", "RSS feed"): link colour,
   underlined on hover */
.text-link {
  color: var(--color-link);
  font-size: var(--text-sm);
  font-weight: 500;
  text-decoration: none;
}

/* A link within running text: always underlined */
.inline-link {
  color: var(--color-link);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

.text-link:hover,
.text-link:focus-visible {
  color: var(--color-headline);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.inline-link:hover,
.inline-link:focus-visible {
  color: var(--color-headline);
}

/* Selection Styles */
::selection {
  background-color: color-mix(in oklch, var(--color-link) 22%, transparent);
  color: var(--color-headline);
}

/* Buttons, and links that act as one. .button is filled, for a page's main
   action; .button--quiet is outlined, for the actions beside it. */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-box) var(--space-lg);
  border: 1px solid var(--color-headline);
  border-radius: var(--radius-md);
  background: var(--color-headline);
  color: var(--color-on-strong);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.button:hover:not(:disabled),
.button:focus-visible {
  border-color: var(--color-link);
  background: var(--color-link);
}

.button--quiet {
  border-color: var(--color-field-border);
  background: var(--color-field);
  color: var(--color-headline);
}

.button--quiet:hover:not(:disabled),
.button--quiet:focus-visible {
  border-color: var(--color-field-border-hover);
  background: var(--color-field);
}

.button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* When they prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ============================================
   Navbar
   ============================================ */

.site-header {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 100;
  block-size: var(--navbar-height);
}

.navbar {
  position: relative;
  block-size: 100%;
}

/* Frosted strip behind the bar: the page blurred beneath it, fading out
   downwards. The layer is twice the bar's height so the blur has content
   to sample below the bar's edge; the mask cuts it back to the bar. */
.navbar__glass {
  position: absolute;
  inset: 0;
  z-index: 0;
  block-size: 200%;
  background: linear-gradient(to bottom, var(--color-background), transparent 50%);
  backdrop-filter: blur(var(--navbar-blur));
  mask-image: linear-gradient(to bottom, black 0% 50%, transparent 50% 100%);
  pointer-events: none;
}

.navbar__content {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  block-size: var(--navbar-height);
  padding-inline: max(1rem, 3vw);
}

.navbar__brand {
  color: var(--color-headline);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-decoration: none;
  transition: color var(--transition-base);
}

.navbar__brand:hover,
.navbar__brand:focus-visible {
  color: var(--color-link);
}

.navbar__links {
  display: flex;
  gap: var(--space-xs);
  margin-inline-start: auto;
  padding: 0;
  list-style: none;
}

.navbar__item {
  display: contents;
}

.navbar__link {
  display: block;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  color: var(--color-nav);
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition: background-color var(--transition-base), color var(--transition-base);
}

.navbar__link:hover,
.navbar__link:focus-visible {
  background-color: var(--color-hover-wash);
  color: var(--color-headline);
}

/* Icon buttons: the menu toggle (phones) and the theme toggle */
.navbar__toggle,
.theme-toggle {
  display: inline-grid;
  place-items: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-nav);
  cursor: pointer;
  transition: background-color var(--transition-base), color var(--transition-base);
}

.navbar__toggle:hover,
.navbar__toggle:focus-visible,
.theme-toggle:hover,
.theme-toggle:focus-visible {
  background-color: var(--color-hover-wash);
  color: var(--color-headline);
}

.navbar__toggle {
  display: none;
  color: var(--color-headline);
}

.navbar__toggle svg {
  display: block;
  fill: currentColor;
}

.theme-toggle {
  margin-inline-start: var(--space-xs);
}

.theme-toggle[hidden] {
  display: none;
}

/* The moon shows in the light theme (click for dark), the sun in the dark
   one. Dark is the system preference unless light was picked, or an
   explicit dark pick (theme.js). */
.theme-toggle__sun {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle__sun {
    display: block;
  }

  :root:not([data-theme="light"]) .theme-toggle__moon {
    display: none;
  }
}

:root[data-theme="dark"] .theme-toggle__sun {
  display: block;
}

:root[data-theme="dark"] .theme-toggle__moon {
  display: none;
}

/* Astrophotography posts are always dark, so the toggle would do nothing. */
body:has(.post-page--astrophotography) .theme-toggle {
  display: none;
}

/* Tablet and down: the links move into a menu behind the toggle. */
@media (max-width: 52rem) {
  :root {
    --navbar-height: 4.5rem;
  }

  .navbar__brand {
    font-size: 1.125rem;
    letter-spacing: 0.03em;
  }

  .navbar__links {
    display: none;
  }

  /* brand ... theme toggle, menu button */
  .theme-toggle {
    order: 2;
    margin-inline-start: auto;
  }

  .navbar__toggle {
    display: inline-grid;
    order: 3;
  }

  .navbar__links--open {
    position: absolute;
    inset-inline: var(--space-md);
    inset-block-start: calc(100% + var(--space-sm));
    z-index: 1000;
    display: grid;
    gap: var(--space-xs);
    padding: var(--space-sm);
    border: 1px solid var(--color-rule);
    border-radius: var(--radius-lg);
    background: color-mix(in oklch, var(--color-background) 85%, transparent);
    backdrop-filter: blur(var(--navbar-blur));
    animation: slideDown 200ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  .navbar__links--open .navbar__item {
    display: block;
  }

  .navbar__links--open .navbar__link {
    inline-size: 100%;
    padding: var(--space-md);
    letter-spacing: 0.005em;
    color: var(--color-headline);
  }
}

@media (max-width: 40rem) {
  .navbar__brand {
    font-size: 1rem;
    letter-spacing: 0.02em;
  }

  .navbar__links--open {
    inset-inline: var(--space-sm);
  }
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-0.5rem) scale(0.98);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@media (prefers-reduced-transparency: reduce) {
  .navbar__glass,
  .navbar__links--open {
    backdrop-filter: none;
    background: var(--color-background);
  }
}

/* ============================================
   Footer
   ============================================ */

/* The footer sits at the bottom of the viewport on short pages and after the
   content on long ones: body is a column, and the page in between grows to
   fill whatever height the navbar padding and footer leave over. That's why
   the page shells (.home-shell, .posts-page, .post-page) no longer set their
   own min-height: 100svh, which pushed the footer a full screen down. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}

#main-content {
  display: flex;
  flex: 1 0 auto;
  flex-direction: column;
}

#main-content > * {
  flex: 1 0 auto;
}

.site-footer {
  border-block-start: 1px solid var(--color-rule);
  background: var(--color-surface);
  color: var(--color-paragraph);
  font-size: var(--text-sm);
}

.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-lg) var(--space-2xl);
  /* Same column as the home and listing pages above it. */
  max-width: var(--page-width);
  margin-inline: auto;
  padding: var(--space-2xl) var(--page-gutter);
}

.site-footer__about {
  display: grid;
  gap: var(--space-xs);
  max-width: 34rem;
}

.site-footer__brand {
  justify-self: start;
  color: var(--color-headline);
  font-family: var(--font-display-editorial);
  font-size: 1.35rem;
  font-style: italic;
  text-decoration: none;
}

.site-footer__tagline {
  line-height: 1.6;
}

.site-footer__profiles {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-md);
  margin-block-start: var(--space-xs);
  padding: 0;
  list-style: none;
}

.site-footer__profile {
  font-weight: 500;
}

.site-footer__brand:hover,
.site-footer__brand:focus-visible {
  color: var(--color-link);
}

/* ============================================
   Night sky

   Behind every dark page: the whole site under a dark colour-scheme
   preference, and astrophotography posts always (they force dark; see
   astrophotography.css). sky.js mounts Nightfall's canvas, the real
   stars above the reader right now, into the .night-sky host at the top
   of layout.html. This file places the host, shows it only when the page
   is dark, and lets the stars show through the navbar and footer.
   ============================================ */

.night-sky {
  position: fixed;
  inset: 0 0 auto;
  /* The largest viewport, so the sky isn't resized (and redrawn) each
     time a phone's address bar shows or hides. */
  height: 100lvh;
  z-index: -1;
  display: none;
  overflow: hidden;
  pointer-events: none;
  /* Nightfall reads these when it starts and when it comes back on, and
     hands them to a canvas. They are written out rather than taken from
     the tokens: a custom property keeps light-dark() unresolved, which a
     canvas reads as the light colour. The sky is only drawn when the page
     is dark, so these are the dark --color-background and a deep-blue
     glow just above it. */
  --nightfall-background: oklch(0.057 0.025 268);
  --nightfall-glow: oklch(0.1 0.04 268);
}

/* Shown when the page is dark: the reader's system prefers dark and they
   haven't picked light with the theme toggle (theme.js), or they picked
   dark. */
@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .night-sky {
    display: block;
  }
}

@media screen {
  :root[data-theme="dark"] .night-sky {
    display: block;
  }
}

body:has(.post-page--astrophotography) .night-sky {
  display: block;
}

@media (prefers-contrast: more), (forced-colors: active) {
  .night-sky {
    display: none !important;
  }
}

/* Let the stars show through the footer, wherever they show. */
@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .site-footer {
    background: color-mix(in oklch, var(--color-background) 85%, transparent);
  }
}

@media screen {
  :root[data-theme="dark"] .site-footer {
    background: color-mix(in oklch, var(--color-background) 85%, transparent);
  }
}

body:has(.post-page--astrophotography) .site-footer {
  background: color-mix(in oklch, var(--color-background) 85%, transparent);
}

/* Wherever the sky shows, the navbar's frosted glass gives way to a plain
   fade. backdrop-filter makes the browser redraw everything beneath the
   bar into a separate picture to blur it, on every frame of a scroll,
   which costs more than the sky itself. The fade stays solid through most
   of the bar and only thins at its edge, so text scrolling under it is
   hidden as the blur hid it. */
@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .navbar__glass {
    block-size: 100%;
    background: linear-gradient(
      to bottom,
      var(--color-background) 0 55%,
      color-mix(in oklch, var(--color-background) 88%, transparent) 78%,
      transparent
    );
    backdrop-filter: none;
    mask-image: none;
  }
}

@media screen {
  :root[data-theme="dark"] .navbar__glass {
    block-size: 100%;
    background: linear-gradient(
      to bottom,
      var(--color-background) 0 55%,
      color-mix(in oklch, var(--color-background) 88%, transparent) 78%,
      transparent
    );
    backdrop-filter: none;
    mask-image: none;
  }
}

body:has(.post-page--astrophotography) .navbar__glass {
  block-size: 100%;
  background: linear-gradient(
    to bottom,
    var(--color-background) 0 55%,
    color-mix(in oklch, var(--color-background) 88%, transparent) 78%,
    transparent
  );
  backdrop-filter: none;
  mask-image: none;
}

/* Keep navbar.css's solid bar for readers who ask for less transparency;
   the fades above are more specific than its rule, so restate it here. */
@media (prefers-reduced-transparency: reduce) {
  .night-sky ~ .site-header .navbar__glass {
    background: var(--color-background);
  }
}

/* Host layout belongs to the application. Only the owned canvas is styled. */
.nightfall {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
  background: var(--nightfall-background, #05070d);
}

