/* Typography for rich-text bodies (blog articles, project case studies).
   Loaded only on detail pages; custom.css stays untouched. Uses the theme's
   CSS variable tokens exclusively, so light/dark flip automatically.
   Border-radius stays 0 everywhere, per the design system. */

.rich-text {
  font-family: Inter, ui-sans-serif, sans-serif;
  font-size: 16px;
  line-height: 1.75;
  color: rgb(var(--c-muted));
}

.rich-text h2,
.rich-text h3,
.rich-text h4 {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: rgb(var(--c-fg));
  margin: 2.25em 0 0.75em;
}

.rich-text h2 { font-size: 24px; }
.rich-text h3 { font-size: 19px; }
.rich-text h4 { font-size: 16px; }

.rich-text p { margin: 1em 0; }

.rich-text a {
  color: rgb(var(--c-accent));
  text-decoration: underline;
  text-underline-offset: 3px;
}

.rich-text strong { color: rgb(var(--c-fg)); font-weight: 500; }

.rich-text ul,
.rich-text ol {
  margin: 1em 0;
  padding-left: 1.4em;
}

.rich-text ul { list-style: square; }
.rich-text li { margin: 0.4em 0; }
.rich-text li::marker { color: rgb(var(--c-accent)); }

.rich-text blockquote {
  border-left: 2px solid rgb(var(--c-accent));
  padding: 0.25em 0 0.25em 1.25em;
  margin: 1.5em 0;
  color: rgb(var(--c-fg));
}

.rich-text pre {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 13px;
  line-height: 1.6;
  color: rgb(var(--c-fg));
  background: rgb(var(--c-surface));
  border: 1px solid rgb(var(--c-line));
  padding: 1em 1.25em;
  margin: 1.5em 0;
  overflow-x: auto;
}

.rich-text code {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.85em;
  color: rgb(var(--c-fg));
  background: rgb(var(--c-surface));
  border: 1px solid rgb(var(--c-line));
  padding: 0.1em 0.35em;
}

.rich-text pre code {
  background: none;
  border: 0;
  padding: 0;
  font-size: inherit;
}

.rich-text hr {
  border: 0;
  border-top: 1px solid rgb(var(--c-line));
  margin: 2em 0;
}

.rich-text figure { margin: 2em 0; }

.rich-text img {
  width: 100%;
  border: 1px solid rgb(var(--c-line));
}

.rich-text figcaption {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: rgb(var(--c-muted));
  margin-top: 0.6em;
}

/* ---------------------------------------------------------------------------
   Narrow-viewport hardening. Every rule below is inert at desktop widths: each
   only bites when content would otherwise overflow the 760px article column.
   Loaded only by the two detail pages, neither of which the pixel gate shoots.
   --------------------------------------------------------------------------- */

/* Bare URLs, package names and long German compounds break instead of pushing the
   document sideways. overflow-wrap is inherited, so p / li / h2-h4 / blockquote /
   figcaption all inherit it. `pre` is unaffected (white-space: pre never wraps)
   and keeps its own overflow-x: auto. */
.rich-text {
  overflow-wrap: break-word;
}

/* An inline <code> span or a bare-URL link is usually one unbreakable token.
   `anywhere` also lowers its min-content contribution, which is what stops it
   from widening an ancestor. */
.rich-text :not(pre) > code,
.rich-text a {
  overflow-wrap: anywhere;
}

/* Code blocks scroll inside their own box; keep the longest line from stretching
   the article, and keep the swipe from chaining to the page behind. */
.rich-text pre {
  max-width: 100%;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

/* sanitize.py's ALLOWED_ATTRIBUTES lets the editor put width/height on an uploaded
   <img>. With the existing `width: 100%`, a height attribute would pin the image to
   a fixed pixel height and distort it at every viewport. */
.rich-text img {
  height: auto;
}

/* Defense-in-depth: table tags are NOT in sanitize.py's ALLOWED_TAGS, so nh3 strips
   them today and no table can reach a page. If that allowlist ever grows, these make
   a pasted table scroll inside its own box instead of widening the document.
   display:block wraps the rows in an anonymous table box that border-collapse cannot
   reach, so cell borders are drawn single-sided instead. */
.rich-text table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: separate;
  border-spacing: 0;
  margin: 1.5em 0;
  font-size: 14px;
}

.rich-text th,
.rich-text td {
  border-right: 1px solid rgb(var(--c-line));
  border-bottom: 1px solid rgb(var(--c-line));
  padding: 0.5em 0.75em;
  text-align: left;
  vertical-align: top;
}

.rich-text tr > *:first-child { border-left: 1px solid rgb(var(--c-line)); }

.rich-text thead th {
  border-top: 1px solid rgb(var(--c-line));
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: rgb(var(--c-fg));
  background: rgb(var(--c-surface));
}

/* Phone + small-tablet type steps. 767.98px is the exact complement of Tailwind's
   `md` (min-width: 768px); a whole-pixel 767px would leave a dead band on
   fractional-width viewports. Body copy stays 16px — smaller is a readability
   regression on a phone, and 16px is also what iOS wants in order not to auto-zoom. */
@media (max-width: 767.98px) {
  .rich-text h2 { font-size: 21px; }
  .rich-text h3 { font-size: 17px; }
  .rich-text h4 { font-size: 15px; }
  .rich-text blockquote { padding-left: 1em; }
  /* Wrapping code at 390px beats a hidden horizontal scroller inside a vertically
     scrolling page (a known touch-gesture trap). */
  .rich-text pre { font-size: 12px; padding: 0.85em 1em; white-space: pre-wrap; }
}
