/* typography.css — Base typographic rules
 * Assumes tokens.css is loaded first for CSS custom properties.
 * Font files are loaded via JS imports in Base.astro (commit 2).
 */

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

html {
  font-family: var(--font-body);
  font-size: 100%;              /* respect user root-size preference */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: var(--color-text);
  background: var(--color-bg);
  text-rendering: optimizeLegibility;
}

body {
  font-size: var(--text-base);
  line-height: var(--leading-body);
  margin: 0;
}

/* ===== Paragraph rhythm (Tufte: indent, no parskip) =====
 * No indent on the first paragraph after a heading — standard book rule.
 * Indent every subsequent paragraph. */
p {
  margin: 0 0 var(--space-4) 0;
  text-indent: 1em;
  hanging-punctuation: first last;
}
h1 + p,
h2 + p,
h3 + p,
h4 + p,
h5 + p,
h6 + p,
hr + p,
blockquote + p,
ul + p,
ol + p,
pre + p {
  text-indent: 0;
}

/* ===== Headings — blue italic, distinctive ===== */
h1, h2, h3, h4, h5, h6 {
  font-weight: 500;
  font-style: italic;
  color: var(--color-heading);
  line-height: var(--leading-tight);
  margin: var(--space-8) 0 var(--space-3) 0;
  text-wrap: balance;
}
h1 { font-size: var(--text-4xl); margin-top: 0; }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-2xl); }
h4 { font-size: var(--text-xl); }
h5 { font-size: var(--text-lg); }
h6 { font-size: var(--text-base); font-weight: 600; font-style: normal; }

/* ===== Code ===== */
code {
  font-family: var(--font-code);
  font-size: 0.92em;
  background: var(--color-code-bg);
  padding: 0.1em 0.3em;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-code-border);
}
pre {
  font-family: var(--font-code);
  background: var(--color-code-bg);
  border: 1px solid var(--color-code-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin: var(--space-4) 0;
  overflow-x: auto;
  line-height: var(--leading-normal);
}
pre code {
  background: transparent;
  padding: 0;
  border: 0;
  font-size: var(--text-sm);
}

/* ===== Responsive reading (v4.25.3) — docs/responsive-reading.md =====
 * Code blocks break out past the prose text measure to fit ~80-char lines,
 * capped at --measure-code and centered within .prose. CONTAINER-bounded, not
 * viewport-bounded: the width comes from the .prose column itself, so a left
 * sidebar offset + the scrollbar gutter can never push the block into horizontal
 * PAGE scroll. (The earlier `width: min(100vw - …)` overflowed ~8px at the
 * 1024px sidebar boundary — #171 review finding A1, guarded by
 * gallery/tests/fixtures/layout-overflow.spec.ts.) `.wide`/`.column-page` keep
 * their full-bleed behavior (excluded here). */
.prose > pre:not(.wide):not(.column-page) {
  max-width: var(--measure-code);
  margin-inline: auto;
  /* Lea Verou layered scroll-shadow: bg-colored covers move with content
   * (attachment:local); shadow layers are fixed → shown only when scrollable. */
  background-image:
    linear-gradient(to right, var(--color-code-bg) 30%, rgba(0, 0, 0, 0)),
    linear-gradient(to right, rgba(0, 0, 0, 0), var(--color-code-bg) 70%),
    radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0)),
    radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0));
  background-position: 0 0, 100% 0, 0 0, 100% 0;
  background-repeat: no-repeat;
  background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
  background-attachment: local, local, scroll, scroll;
}
/* Phone (≤40rem): shrink code a touch so more fits before scrolling. Tighter
 * than the 48rem mobile/table breakpoint below — phones benefit from the smaller
 * glyphs; tablets (40–48rem) keep the full size. */
@media (max-width: 40rem) {
  pre code { font-size: 0.75rem; }
}
/* Mobile: scroll a wide table within its own block instead of overflowing the
 * page. Sticky thead intentionally NOT used — it can't stick inside a
 * horizontal-scroll wrapper (CSS limitation; see docs/responsive-reading.md). */
@media (max-width: 48rem) {
  .prose table { display: block; max-width: 100%; overflow-x: auto; }
}

/* ===== Links ===== */
a {
  color: var(--color-link);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}
a:hover {
  text-decoration-thickness: 2px;
}

/* ===== Lists ===== */
ul, ol {
  margin: 0 0 var(--space-4) 0;
  padding-left: var(--space-6);
}
li {
  margin-bottom: var(--space-1);
}

/* ===== Text emphasis ===== */
small { font-size: var(--text-sm); }
em { font-style: italic; }
strong { font-weight: 600; }

/* ===== Blockquotes ===== */
blockquote {
  margin: var(--space-4) 0;
  padding: 0 var(--space-4);
  border-left: var(--border-bar) solid var(--color-border);
  color: var(--color-text-muted);
  font-style: italic;
}

/* ===== Horizontal rule ===== */
hr {
  border: 0;
  border-top: 1px solid var(--color-border);
  margin: var(--space-8) 0;
}

/* ===== Tables ===== */
table {
  border-collapse: collapse;
  margin: var(--space-4) 0;
  font-size: var(--text-sm);
}
th, td {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
}
th {
  font-weight: 600;
  color: var(--color-heading);
}

/* ===== Tufte typographic openers (v4.25.0) =====
 * Ported from the LaTeX book (interview-preamble-tufte.sty): the run-in
 * <Newthought> section opener and the chapter-opening <Epigraph>. Markup is in
 * the matching .astro components; styling stays here so it's always loaded.
 * Token-only colors — recolor with [data-theme] automatically. */

/* <Newthought>: run-in small-caps opener. TRUE small-caps via the smcp OpenType
 * feature (the Roboto variable face ships it) — font-variant: small-caps would
 * synthesize faux small-caps by scaling capitals. Slightly heavier + tracked
 * out for the Tufte look. */
.newthought {
  font-feature-settings: "smcp";
  font-weight: 600;
  letter-spacing: 0.05em;
}

/* <Epigraph>: italic chapter-opening quotation with a right-aligned
 * attribution. Inherits the running measure from .prose / --measure-main rather
 * than forcing a width that would fight the Tufte measure. */
.epigraph {
  margin: 0 0 var(--space-8) 0;
}
.epigraph blockquote {
  /* Override the global blockquote left-bar: an epigraph reads as an opener,
   * not a pull-quote. Keep it italic + muted. */
  border-left: 0;
  padding: 0;
  margin: 0;
  font-style: italic;
  color: var(--color-text-muted);
}
.epigraph .epigraph-attribution {
  margin-top: var(--space-2);
  text-align: right;
  font-style: normal;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
/* The em-dash lead-in is conventional for an attribution; authors may also
 * write it themselves, so it is not auto-inserted. */

/* .heading-accent — OPT-IN colored-italic heading utility (warm-blue italic).
 * The global h1–h6 are already blue-italic (above); this class is for a heading
 * an author wants to force into the accent style outside that cascade (e.g. a
 * heading inside a card whose local styles reset it). Deliberately NOT applied
 * to the global headings — restyling those would churn every page + baseline. */
.heading-accent {
  color: var(--warm-blue);
  font-style: italic;
}

/* ===== Narrow-viewport overflow guards (v4.26.0, #80) =====
 * Defensive: stop a long INLINE-code identifier (e.g. a dotted module path) or a
 * wide table from forcing horizontal PAGE scroll on a phone. `overflow-wrap:
 * anywhere` only breaks when a token would otherwise overflow, so normal prose is
 * untouched; fenced blocks are excluded (`:not(pre) > code`) so they keep their
 * own `pre { overflow-x: auto }` inner scroll. Wide tables scroll within their own
 * box (`display:block; overflow-x:auto`) instead of stretching the page. */
:not(pre) > code {
  overflow-wrap: anywhere;
}
.prose > table {
  display: block;
  overflow-x: auto;
  max-width: 100%;
}
