/* ============================================================
   Reset, document, layout primitives, chrome (header/footer)
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
}

body {
  min-height: 100dvh;
  /* Column layout so the footer is pinned to the bottom of the viewport
     when the page is short. That leaves no strip of sky below it, so the
     sun rises up out of the footer instead of flashing in a gap first. */
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.6;
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

#app { flex: 1 0 auto; }   /* grow to push the footer down */

img, svg, video, canvas { display: block; max-width: 100%; }
img { height: auto; background: var(--surface-2); }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
ul, ol { list-style: none; padding: 0; }

a { color: inherit; text-decoration: none; }

:where(h1, h2, h3, h4) {
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1.08;
  text-wrap: balance;
}
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); letter-spacing: -0.02em; line-height: 1.25; }
p  { text-wrap: pretty; }

::selection { background: var(--accent); color: var(--accent-ink); }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}
:focus:not(:focus-visible) { outline: none; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: fixed; top: var(--s-3); left: var(--s-3);
  z-index: 200; padding: var(--s-3) var(--s-4);
  background: var(--accent); color: var(--accent-ink);
  border-radius: var(--r-md); font-weight: 500; font-size: var(--t-sm);
  transform: translateY(-160%);
  transition: transform var(--dur) var(--ease-out);
}
.skip-link:focus-visible { transform: translateY(0); }

/* ---- Layout primitives ----------------------------------- */
.shell { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: var(--section-y); }
.section--tight { padding-block: calc(var(--section-y) * 0.6); }
.section + .section { border-top: 1px solid var(--line); }
.lead { font-size: var(--t-lead); color: var(--text-2); max-width: var(--measure); line-height: 1.55; }
.body-2 { color: var(--text-2); max-width: var(--measure); }

.mono {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
}

/* ---- Night sky (fixed, behind content, decorative) -------- */
.sky {
  position: fixed;
  inset: 0;
  z-index: -1;                 /* above the page background, below content */
  pointer-events: none;
  overflow: hidden;
}

.sky__stars {
  position: absolute;
  inset: 0;
  opacity: calc(1 - var(--day, 0));   /* fade out as the page brightens */
}

/* Granim canvas — a slow deep-orange gradient with sweeping white
   highlights, revealed only in daylight. Painted directly (no blend mode)
   so the orange stays orange instead of washing out to peach. */
.sky__day {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  opacity: calc(var(--day, 0) * 0.85);
  pointer-events: none;
}
.star-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: transparent;    /* the stars are its box-shadow dots */
}

/* Two twinkle shapes, spread across many small layers on their own
   clocks (set in JS), so the field shimmers rather than pulsing as one.
   A star that dips to near-zero reads as a real blink. */
@keyframes twinkle-a { 0%, 100% { opacity: 0.2; } 50% { opacity: 1; } }
@keyframes twinkle-b { 0%, 100% { opacity: 0.55; } 30% { opacity: 1; } 65% { opacity: 0.1; } }

@media (prefers-reduced-motion: reduce) {
  .star-layer { animation: none !important; }
}


/* A warm glow that grows along the horizon as day arrives. */
.sky::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(130% 70% at 50% 116%,
    rgba(255, 178, 92, calc(var(--day, 0) * 0.30)), transparent 60%);
}

/* ---- Grain (fixed, never on a scrolling container) -------- */
.grain {
  position: fixed; inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: var(--grain-opacity);
  background-image: var(--grain-url);
  mix-blend-mode: overlay;
}

/* ---- Header ---------------------------------------------- */
.siteheader {
  position: sticky; top: 0;
  z-index: var(--z-header);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur) var(--ease-out), background-color var(--dur) var(--ease-out);
}
.siteheader[data-scrolled="true"] { border-bottom-color: var(--line); }

@media (prefers-reduced-transparency: reduce) {
  .siteheader { background: var(--bg); backdrop-filter: none; -webkit-backdrop-filter: none; }
}

.siteheader__inner {
  height: var(--header-h);
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex; align-items: center; gap: var(--s-5);
}

.brand { display: inline-flex; align-items: center; gap: var(--s-3); flex-shrink: 0; }
.brand__mark { display: grid; place-items: center; transition: transform var(--dur) var(--ease-out); }
.brand:hover .brand__mark { transform: rotate(-6deg) scale(1.05); }
/* The logo art sits on its own black ground, shown as a small rounded
   tile that reads on both the light and dark header. */
.brand__logo {
  width: 36px; height: 36px;
  border-radius: 9px;
  object-fit: cover;
  display: block;
  box-shadow: 0 0 0 1px var(--line), 0 2px 8px rgb(0 0 0 / 0.35);
}
.brand__text { display: grid; gap: 1px; min-width: 0; }

/* Neon wordmark. Core letterform plus three halo rings. Both the
   core colour and the halo are driven by the theme engine, so the
   glow shifts from white at night to the accent by day instead of
   bleaching out against a light page. */
.brand__word {
  font-weight: 600;
  letter-spacing: -0.01em;
  font-size: var(--t-sm);
  color: var(--neon-core);
  line-height: 1.2;
}
.neon {
  text-shadow:
    0 0 4px  rgb(var(--neon-glow) / calc(var(--neon-strength) * 0.90)),
    0 0 12px rgb(var(--neon-glow) / calc(var(--neon-strength) * 0.55)),
    0 0 32px rgb(var(--neon-glow) / calc(var(--neon-strength) * 0.30));
}

/* A slow breath rather than a flicker. Flicker on a wordmark you
   read on every page gets old fast. */
@media (prefers-reduced-motion: no-preference) {
  .neon { animation: neon-breathe 5.5s var(--ease-in-out) infinite; }
  @keyframes neon-breathe {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.88; }
  }
}

.brand__tagline {
  font-size: var(--t-micro);
  letter-spacing: 0.02em;
  color: var(--text-3);
  line-height: 1.3;
  white-space: nowrap;
}
@media (max-width: 700px) { .brand__tagline { display: none; } }
@media (max-width: 420px) { .brand__word { font-size: var(--t-xs); } }

/* The nav is always visible. There is no burger. On narrow screens
   it wraps to its own row under the brand rather than collapsing. */
.nav { display: flex; flex-wrap: wrap; justify-content: center; margin-inline: auto; gap: var(--s-1); }

@media (max-width: 859px) {
  .siteheader__inner {
    flex-wrap: wrap;
    height: auto;
    min-height: var(--header-h);
    padding-block: var(--s-2);
    row-gap: var(--s-1);
  }
  .nav { order: 3; width: 100%; margin: 0; }
}

.nav a {
  position: relative;
  padding: var(--s-2) var(--s-3);
  font-size: var(--t-sm);
  color: var(--text-2);
  border-radius: var(--r-md);
  transition: color var(--dur-fast) var(--ease-out);
}
.nav a:hover { color: var(--text); }
.nav a::after {
  content: ""; position: absolute;
  left: var(--s-3); right: var(--s-3); bottom: 2px; height: 1.5px;
  background: var(--accent); border-radius: var(--r-full);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}
.nav a[aria-current="page"] { color: var(--text); }
.nav a[aria-current="page"]::after { transform: scaleX(1); }

/* Always pushed to the far right, so the brightness slider sits in the
   top-right corner of the page. */
.siteheader__actions { display: flex; align-items: center; gap: var(--s-2); margin-left: auto; }

.iconbtn {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: var(--r-md);
  color: var(--text-2);
  font-size: 1.15rem;
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.iconbtn:hover { background: var(--surface-2); color: var(--text); }
.iconbtn:active { transform: scale(0.94); }

/* Route progress bar: honest feedback while a view resolves */
.siteheader__progress { position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; overflow: hidden; }
.siteheader__progress > span {
  display: block; height: 100%; width: 100%;
  background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform 240ms var(--ease-out), opacity 200ms 160ms linear;
  opacity: 0;
}
.siteheader__progress > span[data-state="loading"] { transform: scaleX(0.7); opacity: 1; transition-delay: 0s; }
.siteheader__progress > span[data-state="done"] { transform: scaleX(1); opacity: 0; }

/* ---- Footer ---------------------------------------------- */
.sitefooter { border-top: 1px solid var(--line); background: var(--bg-sunken); }
.sitefooter__inner {
  max-width: var(--maxw); margin-inline: auto;
  padding: var(--s-8) var(--gutter) var(--s-7);
  display: grid; gap: var(--s-7);
}
@media (min-width: 860px) {
  .sitefooter__inner { grid-template-columns: 1.4fr auto; align-items: start; }
}
.sitefooter__statement { font-size: var(--t-h3); font-weight: 500; letter-spacing: -0.02em; margin-bottom: var(--s-3); }

.maillink {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-lead); color: var(--accent-text);
  border-bottom: 1px solid color-mix(in srgb, var(--accent-text) 35%, transparent);
  padding-bottom: 2px;
  transition: border-color var(--dur-fast) var(--ease-out);
}
.maillink i { transition: transform var(--dur) var(--ease-out); }
.maillink:hover { border-bottom-color: var(--accent-text); }
.maillink:hover i { transform: translate(3px, -3px); }

.sitefooter__social { display: flex; align-items: flex-start; }
.sociallink {
  display: inline-flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  font-size: var(--t-sm);
  color: var(--text-2);
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.sociallink > i:first-child { font-size: 1.25rem; }
.sociallink__out { font-size: 0.95rem; opacity: 0.6; transition: transform var(--dur) var(--ease-out); }
.sociallink:hover { color: var(--text); border-color: var(--line-strong); background: var(--surface); }
.sociallink:hover .sociallink__out { transform: translate(3px, -3px); }

.sitefooter__base {
  max-width: var(--maxw); margin-inline: auto;
  padding: var(--s-4) var(--gutter);
  border-top: 1px solid var(--line);
  display: flex; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap;
  font-size: var(--t-xs); color: var(--text-3);
}

/* ============================================================
   Route transitions
   Native View Transitions where supported, scripted fallback
   everywhere else. Both collapse to instant under reduced motion.
   ============================================================ */

#app { display: block; }

::view-transition-old(page),
::view-transition-new(page) { animation-duration: 380ms; animation-timing-function: var(--ease-out); }
::view-transition-old(page) { animation-name: vt-out; }
::view-transition-new(page) { animation-name: vt-in; }

@keyframes vt-out { to   { opacity: 0; transform: translateY(-10px); } }
@keyframes vt-in  { from { opacity: 0; transform: translateY(14px); } }

/* Fallback for browsers without View Transitions */
#app[data-transition="out"] {
  opacity: 0; transform: translateY(-10px);
  transition: opacity 180ms var(--ease-out), transform 180ms var(--ease-out);
}
#app[data-transition="in"] {
  animation: vt-in 380ms var(--ease-out) both;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  ::view-transition-old(page), ::view-transition-new(page) { animation: none; }
  #app[data-transition="out"], #app[data-transition="in"] { opacity: 1; transform: none; animation: none; transition: none; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
