/* ==========================================================================
   Base -- reset, element defaults, layout primitives, shared utilities.
   ==========================================================================

   Pairs with templates/base.html. Everything here applies site-wide; anything
   that belongs to one component belongs in that component's own stylesheet
   next to its own partial (one partial, one stylesheet -- both or neither).

   Reads tokens.css. Declares no raw hex and no raw px for anything a token
   covers. The exceptions below are deliberate and are each commented.
*/

/* --- reset ---------------------------------------------------------------
   Minimal and targeted, not a vendored normalize. Every rule here exists
   because something in this design needs it. */

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

html {
  /* Anchor jumps and in-page nav should not teleport -- but never override a
     reader who has asked the OS to stop animating. */
  scroll-behavior: smooth;
  /* Keeps a focused target clear of the sticky header. */
  scroll-padding-top: var(--s-8);
  -webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  /* Opt in explicitly rather than relying on the UA default, which differs
     between engines and changes the rhythm of the type scale. */
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  /* The footer must sit at the bottom of short pages, not mid-viewport. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; }

img, picture, svg, video {
  display: block;
  max-width: 100%;
  height: auto;
}

/* Inherit rather than reset: a control that does not inherit the page font is
   the single most common way a hand-written stylesheet looks unfinished. */
button, input, select, textarea {
  font: inherit;
  color: inherit;
}

/* --- headings ------------------------------------------------------------
   Sized here so a heading is correct by default. A page that needs a different
   size sets it on its own class -- never by picking a different heading level,
   which would break the document outline for assistive tech. */

h1, h2, h3, h4 {
  font-weight: 620;
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;  /* progressive: ignored where unsupported */
}

h1 { font-size: var(--fs-2xl); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); line-height: var(--lh-snug); }
h4 { font-size: var(--fs-md); line-height: var(--lh-snug); }

/* --- links ---------------------------------------------------------------
   Underlined by default, on purpose. Colour alone is not an accessible
   affordance, and this design has exactly one accent hue to spend. */

a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: var(--accent-line);
  transition: color var(--dur-fast) var(--ease),
              text-decoration-color var(--dur-fast) var(--ease);
}

a:hover {
  color: var(--accent-hover);
  text-decoration-color: currentColor;
}

/* --- focus ---------------------------------------------------------------
   One visible focus ring for the whole site. :focus-visible only, so a mouse
   click does not leave a ring, but every keyboard path does. Never remove
   this without replacing it. */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* <main> takes tabindex="-1" so the skip link moves focus, not just the
   viewport. That makes it focusable, and a full-page outline around the whole
   main landmark is noise -- suppress only this one. */
main:focus,
main:focus-visible { outline: none; }

/* --- skip link -----------------------------------------------------------
   Off-screen until focused. Deliberately NOT display:none or visibility:hidden
   -- both remove it from the tab order, which defeats the entire purpose. */

.skip-link {
  position: absolute;
  left: var(--s-4);
  top: var(--s-4);
  z-index: 100;
  padding: var(--s-2) var(--s-4);
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: var(--r-md);
  text-decoration: none;
  font-size: var(--fs-sm);
  font-weight: 600;
  box-shadow: var(--shadow-2);
  /* translate rather than `top`, so the transition runs on the compositor */
  transform: translateY(calc(-100% - var(--s-6)));
  transition: transform var(--dur) var(--ease);
}

.skip-link:focus { transform: translateY(0); }

/* --- layout primitives ---------------------------------------------------- */

/* Horizontal gutter + max width. Used by the header, the footer and every page
   section, so they all share one edge. */
.wrap {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--s-5);
}

@media (min-width: 60rem) {
  .wrap { padding-inline: var(--s-6); }
}

/* The main landmark grows so the footer is pushed down on short pages. */
.site-main {
  flex: 1 0 auto;
  /* No horizontal padding here: sections own their own vertical rhythm and use
     .wrap for the gutter, so a full-bleed band is possible without unwinding
     a padding set on an ancestor. */
}

/* Running prose: constrained measure and a consistent vertical rhythm. */
.prose {
  max-width: var(--measure);
}

.prose > * + * { margin-top: var(--s-4); }
.prose h2 { margin-top: var(--s-7); }
.prose h3 { margin-top: var(--s-6); }
.prose ul, .prose ol { padding-left: var(--s-5); }
.prose li + li { margin-top: var(--s-2); }

.prose code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--surface-2);
  border: var(--hairline);
  border-radius: var(--r-sm);
  padding: 0.1em 0.35em;
}

/* --- shared text roles ----------------------------------------------------
   Metadata is mono at --fs-xs everywhere on this site: dates, tags, stack
   names, counts. It is the rule that does most of the work of making the site
   read as an engineer's, so it lives here rather than in one component. */

.meta {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  letter-spacing: 0;
}

/* Small caps label above a heading. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-faint);
}

.lead {
  font-size: var(--fs-md);
  color: var(--text-muted);
  max-width: var(--measure);
}

/* Visually hidden but present for assistive tech. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
