/* Typed so JS-driven accent swaps (see .accent-swatch) animate smoothly
   through every var(--accent)/var(--accent-on-light) usage site-wide,
   rather than snapping instantly - plain (untyped) custom properties
   can't be interpolated. */
@property --accent {
  syntax: "<color>";
  inherits: true;
  initial-value: #f97316;
}
@property --accent-on-light {
  syntax: "<color>";
  inherits: true;
  initial-value: #c2410c;
}

:root {
  --bg-dark: #0f172a;
  --bg-dark-soft: #14213a;
  --bg-light: #f8fafc;
  --surface: #ffffff;
  --accent: #f97316;
  --accent-on-light: #c2410c;
  --ink-950: #0f172a;
  --ink-700: #47546b;
  --ink-400: #94a3b8;
  --ink-200: #e2e8f0;
  --line: rgba(15, 23, 42, 0.1);
  --radius-lg: 18px;
  --radius-md: 14px;
  --radius-sm: 8px;
  --shadow-card: 0 20px 50px rgba(15, 23, 42, 0.35);
  --container: 1200px;
  --section-pad: 96px;
  transition:
    --accent 400ms ease,
    --accent-on-light 400ms ease;

  @media (prefers-reduced-motion: reduce) {
    transition: none;
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;

  @media (prefers-reduced-motion: reduce) {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  min-width: 320px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg-light);
  color: var(--ink-950);
  font-family: "Inter", sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

main {
  flex: 1 0 auto;
}

/* --- Cross-document view transitions ------------------------------------
   Smooths real navigations between pages. Not document.startViewTransition():
   that animates a DOM mutation within one document, which is an SPA shape this
   site doesn't have. For an actual page load the browser does the work itself,
   given this opt-in in BOTH the outgoing and incoming document - which is why
   it lives in base.css, the only stylesheet every page loads.

   Unsupported browsers navigate normally, so there's nothing to feature-detect
   and no fallback to maintain. */
@view-transition {
  navigation: auto;
}

/* Naming an element gives it its own transition group, captured and animated
   independently of the `root` snapshot. Worth doing for the header: it's
   sticky at top: 0, so it occupies the same viewport box on every page and
   its group animation has nothing to move. Its two snapshots still cross-fade,
   which is what we want - the header isn't quite identical between pages (the
   reading-progress bar and the camera toggle come and go), so a fade reads
   better than a hard swap.

   Nothing else gets a name, and that's the important part. A named group's
   animation interpolates that element's real box between the two documents, so
   a name is only safe on something whose geometry doesn't depend on scroll
   position or page length:

   - <main> was named at first, and it was the bug. Leaving a homepage scrolled
     to 2500px its box measured top: -2435px / height: 3882px, against
     top: 65px / height: 764px on the blog index - so the group was asked to
     slide the whole content area 2500px and shrink it by 3118px inside 250ms.
     Unnamed, the content rides in `root`, whose snapshot is the viewport-sized
     snapshot containing block and so identical in both documents: it
     cross-fades in place instead of flying.
   - The footer, likewise: measured at y=829 on the blog index (short page,
     pushed down by the sticky-footer layout) against y=4028 on a post. */
.site-header {
  view-transition-name: site-header;
}

@keyframes page-out {
  to {
    opacity: 0;
    transform: translateY(-8px);
  }
}

@keyframes page-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

/* Deliberately short: a navigation that animates for much longer than this
   starts to feel like latency rather than polish.

   Overriding root's animation replaces the UA's cross-fade, which pairs its
   fade with mix-blend-mode: plus-lighter so two overlapping snapshots don't
   dip through a visibly lighter frame mid-fade. These keyframes cross-fade the
   same way, so they keep that blend mode. */
::view-transition-old(root),
::view-transition-new(root) {
  mix-blend-mode: plus-lighter;
}

::view-transition-old(root) {
  animation: page-out 180ms ease-in both;
}

::view-transition-new(root) {
  animation: page-in 220ms ease-out both;
}

@media (prefers-reduced-motion: reduce) {
  /* Keeps the transition machinery but drops every animation, so navigation
     lands instantly. The wildcard covers the named groups above and the
     browser's own default cross-fade for anything unnamed. */
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

a {
  color: inherit;
  text-decoration: none;
}
button {
  font: inherit;
  cursor: pointer;
}
img {
  max-width: 100%;
  display: block;
}
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.print-only-header,
.print-only-name {
  display: none;
}

.container {
  width: min(calc(100% - 48px), var(--container));
  margin: 0 auto;
}

.section {
  padding: var(--section-pad) 0;
  scroll-margin-top: 88px;
}

.section-dark {
  background: var(--bg-dark);
  color: var(--ink-200);

  & .eyebrow {
    color: var(--accent);
  }
  & .body-copy {
    color: var(--ink-400);
  }
}
.section-white {
  background: var(--surface);
}
.section-light {
  background: var(--bg-light);
}

.eyebrow {
  display: inline-block;
  margin: 0 0 20px;
  color: var(--accent-on-light);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.title {
  margin: 0;
  font-family: "Space Grotesk", sans-serif;
  font-weight: 700;
  font-size: clamp(2rem, 4vw, 2.75rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
}

.body-copy {
  margin: 0;
  color: var(--ink-700);
  font-size: 17px;
  line-height: 1.7;
}

.site-footer {
  padding: 28px 0;
  background: var(--bg-dark);
  color: var(--ink-400);
  font-size: 13px;
}

.footer-inner {
  text-align: center;
}
