* { box-sizing: border-box; }

/* Defensive default: a long unbroken string (a URL, a filename) inside
   any normal text flow shouldn't be able to force its container wider
   than available space — combined with the grid-track/main-width fix
   just below, this is belt-and-suspenders against the same class of
   layout bug reappearing wherever new content gets added later. Tables
   are explicitly excluded (see .table-scroll's own intentional
   horizontal scroll for wide tabular data — those should NOT wrap). */
main, .panel, .note {
  overflow-wrap: anywhere;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: "Sora", "Avenir Next", "Segoe UI", -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.mono {
  font-family: "IBM Plex Mono", "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
}

a { color: inherit; }

.shell {
  display: grid;
  /* minmax(0, 1fr), not bare 1fr — a bare 1fr track's implicit min-width
     is `auto` (i.e. big enough for its content), so a wide child can
     still force the track wider than available space. minmax(0, 1fr)
     is what actually lets main's own max-width/overflow-wrap rules take
     over instead of the grid track fighting them. */
  grid-template-columns: 236px minmax(0, 1fr);
  min-height: 100vh;
}

/* Only animate the column resize once the page has finished loading —
   applied by JS after first paint (see api.js) so the initial render
   with a persisted collapsed state never shows a spurious 0.18s
   expand-then-collapse animation on page load. */
.shell.transitions-enabled {
  transition: grid-template-columns 0.18s ease;
}

.shell.sidebar-collapsed {
  grid-template-columns: 64px minmax(0, 1fr);
}

h1 {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: 0 0 4px;
  text-wrap: balance;
}

.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 26px;
  gap: 20px;
}

.page-sub {
  color: var(--ink-dim);
  font-size: 13.5px;
  margin: 0;
}

main {
  padding: 30px 36px 60px;
  /* max-width (not a fixed width) — this is a grid item, and a 1fr grid
     track's default min-width is `auto`, not 0, so it won't shrink below
     its content's intrinsic size on its own. A FIXED width here forced
     main to demand 1180px regardless of how much room the grid track
     actually had once the sidebar's column was accounted for, and with
     nothing to reveal the overflow (page-wide horizontal scroll is
     avoided deliberately — see body's overflow-x), it just silently
     clipped instead of shrinking. Confirmed live: content cut off
     mid-word on a viewport too narrow for sidebar + 1180px + padding. */
  max-width: 1180px;
  width: 100%;
  min-width: 0;
  margin: 0 auto;
}

::selection { background: var(--accent-soft); color: var(--accent); }

/* Mobile responsive overrides for THIS file's own rules (.shell, main,
   .grid-2) are deliberately kept in components.css, not here — that
   stylesheet loads AFTER base.css (see base.html's <link> order), and
   with equal selector specificity the LATER stylesheet always wins the
   cascade regardless of which file's media query actually matches.
   Confirmed live: an earlier version of these overrides lived here and
   was silently beaten by components.css's unrelated, non-media-queried
   .stats rule (4-column grid) at every width, since components.css
   loaded second. See components.css's own "Mobile responsive overrides"
   section near the end of the file. */
