/* Ganymede base: reset, type, layout primitives, a11y defaults.
   Nothing here references a raw ramp step -- only the semantic tokens. */

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

html {
  /* 17px base. The old 16px put captions and control labels near 11px, which
     is where this site was hardest to read. Everything is in rem, so this one
     line lifts the whole scale. */
  font-size: 106.25%;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: var(--fs-0);
  line-height: var(--lh-normal);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 { margin: 0; text-wrap: balance; }
p, ul, ol { margin: 0 0 var(--s-4); }
p { max-width: var(--measure); }
li { margin: var(--s-2) 0; max-width: var(--measure); }
strong { font-weight: 600; }

a { color: var(--signal); text-underline-offset: 2px; text-decoration-thickness: 1px; }
a:hover { color: var(--signal-strong); }

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

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }

/* One focus treatment for the whole site. Never removed, only shaped. */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-1);
}
:focus:not(:focus-visible) { outline: none; }

.skip {
  position: absolute; left: var(--s-3); top: calc(-1 * var(--s-12)); z-index: 100;
  background: var(--signal); color: var(--on-signal);
  padding: var(--s-3) var(--s-5); border-radius: var(--r-2); font-weight: 600;
  transition: top var(--dur) var(--ease-out);
}
.skip:focus { top: var(--s-3); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ---- type roles -------------------------------------------------------- */
.display {
  font-family: var(--font-display); font-weight: 400;
  line-height: var(--lh-tight); letter-spacing: var(--tracking-tight);
  /* Fraunces carries an optical-size axis; let the browser use it so display
     sizes get the display cut and small settings stay readable. */
  font-optical-sizing: auto;
  font-variation-settings: "SOFT" 0, "WONK" 0;
}
.display em { font-style: italic; color: var(--predict); }

.eyebrow {
  font-size: var(--fs--2); letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--faint); font-weight: 600;
}

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.lede { font-size: var(--fs-1); line-height: var(--lh-snug); color: var(--muted); max-width: 60ch; }

/* ---- layout ------------------------------------------------------------ */
.shell { max-width: 1280px; margin: 0 auto; padding-inline: var(--s-6); }
.prose { max-width: 720px; margin: 0 auto; padding-inline: var(--s-6); }
.stack > * + * { margin-top: var(--flow, var(--s-4)); }
.row { display: flex; align-items: center; gap: var(--s-4); }
.row .spacer { flex: 1; }
.grid { display: grid; gap: var(--s-5); }

hr, .rule { border: 0; border-top: 1px solid var(--line); margin: var(--s-9) 0; }

/* Wide content scrolls inside itself; the page body never scrolls sideways. */
.scroll-x { overflow-x: auto; overscroll-behavior-x: contain; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ---- print: the case is a job-application artifact and must print clean -- */
@media print {
  :root { --ground: #fff; --surface: #fff; --text: #000; --muted: #333; }
  body { font-size: 10.5pt; }
  .no-print, .skip, nav, .depth, .themebtn { display: none !important; }
  a { color: #000; text-decoration: underline; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 8pt; color: #555; }
  h2, h3 { break-after: avoid; }
  figure, table, blockquote { break-inside: avoid; }
}
