/* Reset, document defaults and shared utilities. */

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{background:var(--bg);color:var(--ink);font-family:var(--sans);font-size:17px;line-height:1.65;-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}
/* --on-accent, not #fff: the dark accent is a light green, and white on it
   measures 2.14:1. */
::selection{background:var(--accent);color:var(--on-accent)}

/* Theme change is animated, loading is not. theme.js adds this class for the
   length of the toggle and removes it, so the first paint never cross-fades
   from the wrong palette. The reduced-motion block below neutralises it. */
.theme-transition,
.theme-transition *,
.theme-transition *::before,
.theme-transition *::after{
  transition:background-color .28s ease,color .28s ease,
             border-color .28s ease,box-shadow .28s ease !important;
}

/* Keyboard focus must always be visible (WCAG 2.4.7). */
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}

/* The sticky top bar must never cover an anchor target or a focused
   element (WCAG 2.4.11). */
[id]{scroll-margin-top:96px}
a:focus-visible{scroll-margin-top:96px;scroll-margin-bottom:24px}

.wrap{max-width:var(--maxw);margin:0 auto;padding:0 28px}
.mono{font-family:var(--mono)}

/* Available to screen readers, hidden visually. */
.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* Honor the operating-system reduced-motion preference (WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  /* The universal rule above is specificity (0,0,0) and cannot beat
     `.theme-transition *` at (0,1,0) — both are !important, so specificity
     decides. This repeats the selector to match, and wins on source order.
     Without it the theme toggle would animate for a reader who asked for no
     motion, which is the one case that must never happen. */
  .theme-transition,
  .theme-transition *,
  .theme-transition *::before,
  .theme-transition *::after{transition-duration:.01ms !important}
}
