/* ─── US-029: Editorial-Grade Article Typography ─────────────── */

/* ─── Post Title ─────────────────────────────────────────────── */
.post-title {
  font-family: var(--font-display);
  /* design spec: clamp(2.8rem, 5vw, 4.5rem) at 1440px canvas */
  font-size: clamp(2.8rem, 5vw, 4.5rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.08;
  margin: 0 0 20px;
}

html:lang(zh) .post-title {
  font-size: clamp(2.25rem, 4.5vw, 3.75rem);
  font-weight: 900;
  letter-spacing: 0.02em;
  line-height: 1.2;
}

/* ─── Post Description — editorial lead-in, no box ───────────── */
.post-description {
  font-family: var(--font-prose, 'Noto Serif', 'Georgia', serif);
  font-style: italic;
  font-size: 1.125rem;
  line-height: 1.7;
  color: var(--color-ink-muted, #5e5e63);
  max-width: 62ch;
  margin: 0.5rem 0 2.25rem;
  padding: 0.1rem 0 0.1rem 1.1rem;
  border-left: 2px solid var(--color-rule, rgba(30, 35, 30, 0.15));
  background: transparent;
  border-radius: 0;
  opacity: 1;
}

html:lang(zh) .post-description {
  font-family: var(--font-display);
  font-style: normal;
  font-size: 1rem;
  line-height: 1.9;
  letter-spacing: 0.005em;
}

body.dark .post-description {
  color: rgba(226, 227, 225, 0.78);
  background: transparent;
  border-left-color: rgba(226, 227, 225, 0.15);
}

/* ─── Post Content Prose Base ────────────────────────────────── */
.post-content {
  line-height: var(--line-height-prose, 1.75);
  letter-spacing: var(--tracking-prose, normal);
}

/* Dark-mode prose base color. Paragraphs, headings, strong/em etc. are each
   given explicit colors elsewhere, but text without an explicit override
   (list items, table cells, dd/dt, captions) inherits this base. Without it
   that text fell back to the light-mode ink and rendered near-black on the
   dark surface. The token resolves per language (#e2e3e1 EN / #f5f3ee ZH). */
body.dark .post-content {
  color: var(--color-ink, #e2e3e1);
}

/* Table cells: ensure readable text + visible hairline rules in dark mode. */
body.dark .post-content table th,
body.dark .post-content table td {
  color: var(--color-ink, #e2e3e1);
  border-bottom-color: var(--color-rule, rgba(226, 227, 225, 0.12));
}

.post-content p {
  line-height: 1.8;
  letter-spacing: var(--tracking-prose, normal);
  margin-bottom: 2rem;
  font-size: 1.125rem;
}

/* EN prose: use Noto Serif for elegant editorial feel (matches design spec) */
html:lang(en) .post-content p {
  font-family: var(--font-prose, 'Noto Serif', 'Georgia', serif);
  color: var(--color-ink, #1a1c1b);
}

/* ─── Drop Cap (first paragraph only) ───────────────────────── */
/* Applied via JS in article-typography-init.js OR ::first-letter */
.post-content .drop-cap::first-letter,
.post-content p.drop-cap::first-letter {
  font-family: var(--font-display);
  font-size: var(--drop-cap-size, 5rem);
  font-weight: 800;
  color: var(--color-ink, #1a1c1b);
  float: left;
  line-height: 0.8;
  margin-right: 0.075em;
  margin-top: 0.5rem;
  padding-right: 0.05em;
  /* Ensures at least 3 lines of clearance */
  padding-bottom: 0.05em;
}

html:lang(zh) .post-content .drop-cap::first-letter,
html:lang(zh) .post-content p.drop-cap::first-letter {
  font-family: var(--font-display);
  font-weight: 900;
  font-style: normal;
  font-size: var(--drop-cap-size, 4.5rem);
  line-height: 0.8;
}

html:lang(en) .post-content .drop-cap::first-letter,
html:lang(en) .post-content p.drop-cap::first-letter {
  font-style: italic;
}

/* ─── H2 in Post Content — accent hairline ───────────────────── */
.post-content h2 {
  font-family: var(--font-display);
  font-size: 1.875rem;
  font-weight: 700;
  margin-top: 4rem;
  margin-bottom: 1.5rem;
  letter-spacing: -0.01em;
  line-height: 1.25;
}

/* Override custom.css fixed dark color with token-based accent */
body.dark .post-content h2 {
  border-left-color: var(--color-accent);
}

/* P1-2: Explicit dark-mode text color for headings so ZH dark (#350003 ink)
   never bleeds through — use the resolved light ink token instead.
   Covers ALL heading levels: h1 in .post-content, h2–h6, and the .post-title
   hero heading (which lives in .post-header, outside .post-content). */
body.dark .post-title {
  color: var(--color-ink, #e2e3e1);
}

body.dark .post-content h1,
body.dark .post-content h2,
body.dark .post-content h3,
body.dark .post-content h4,
body.dark .post-content h5,
body.dark .post-content h6 {
  color: var(--color-ink, #f5f3ee);
}

html:lang(zh) .post-content h2 {
  letter-spacing: 0.02em;
}

/* ─── Blockquote — EN large decorative quote mark ───────────── */
html:lang(en) .post-content blockquote {
  position: relative;
  margin: 3rem 0;
  padding: 1rem 3rem 1rem 2rem;
  border-left: 2px solid var(--color-accent, #2e352e);
  background: rgba(238, 238, 236, 0.3);
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.25rem;
  line-height: 1.65;
  color: rgba(26, 28, 27, 0.8);
  border-radius: 0 var(--radius-sm, 4px) var(--radius-sm, 4px) 0;
}

html:lang(en) .post-content blockquote p {
  font-family: var(--font-display);
  font-size: inherit;
  margin-bottom: 0;
  color: inherit;
}

/* When the decorative blockquote is the very first content block, it sits
   right under the TL;DR panel — the oversized quote glyph (8rem, top:-0.5em
   ≈ -64px) would otherwise punch up into the panel. Give it headroom so the
   glyph clears the panel with a calm gap. */
html:lang(en) .post-content > blockquote:first-child {
  margin-top: 6rem;
}

html:lang(en) .post-content blockquote::before {
  content: '\201C';
  position: absolute;
  left: -0.15em;
  top: -0.5em;
  font-size: 8rem;
  font-family: var(--font-display);
  font-style: normal;
  font-weight: 800;
  color: var(--color-accent, #2e352e);
  opacity: 0.1;
  line-height: 1;
  pointer-events: none;
}

/* ─── Blockquote — ZH (editorial, no 「」 brackets) ──────────── */
/* Decorative 「 」 corner brackets removed — they rendered as huge
   floating marks that fought with Chinese paragraph flow. A calm
   left rule on soft paper background reads better for CJK. */
html:lang(zh) .post-content blockquote {
  position: relative;
  margin: 2rem 0;
  padding: 0.85rem 1.5rem 0.85rem 1.65rem;
  border-left: 2.5px solid var(--color-accent, #862122);
  background: rgba(134, 33, 34, 0.035);
  border-radius: 0 4px 4px 0;
  font-family: 'Noto Serif SC', 'Source Han Serif SC', 'PingFang SC',
               var(--font-body), serif;
  font-size: 1rem;
  line-height: 1.85;
  color: rgba(30, 35, 30, 0.78);
  letter-spacing: 0.01em;
}

html:lang(zh) .post-content blockquote p {
  margin-bottom: 0.75em;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
}

html:lang(zh) .post-content blockquote p:last-child {
  margin-bottom: 0;
}

/* Explicitly clear the old ::before / ::after so cached CSS or
   ordering won't re-inject the corner brackets. */
html:lang(zh) .post-content blockquote::before,
html:lang(zh) .post-content blockquote::after {
  content: none !important;
  display: none !important;
}

html:lang(zh) body.dark .post-content blockquote,
body.dark .post-content blockquote {
  background: rgba(255, 255, 255, 0.03);
  /* Derive the quote ink from the per-language dark --color-ink (cool
     #e2e3e1 for EN, warm #f5f3ee for ZH) at 82% so the quoted passage stays
     tonally matched to its body text instead of a fixed cool grey — the old
     hard-coded value read slightly cold against the warm ZH dark paper.
     color-mix is already used across the codebase; light mode is untouched
     since this rule is gated on body.dark. */
  color: color-mix(in srgb, var(--color-ink, #e2e3e1) 82%, transparent);
}

/* ─── Inline Code — pill style ───────────────────────────────── */
.post-content :not(pre) > code {
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  /* design spec: 0.9em, rgba(0,0,0,0.06) bg, 0.25rem radius */
  font-size: 0.9em;
  background: rgba(0, 0, 0, 0.06);
  color: var(--color-ink, #1a1c1b);
  padding: 0.1em 0.35em;
  border-radius: 0.25rem;
  border: none;
  white-space: nowrap;
}

body.dark .post-content :not(pre) > code {
  background: rgba(255, 255, 255, 0.1);
  color: var(--color-ink, #e2e3e1);
}

/* ─── Inline Links — faint underline → accent on hover ───────── */
.post-content a:not(.footnote-ref):not(.footnote-backref) {
  color: var(--color-ink, #1a1c1b);
  text-decoration: underline;
  text-decoration-color: rgba(26, 28, 27, 0.28);
  text-underline-offset: 0.2em;
  transition: text-decoration-color 0.15s ease;
}

.post-content a:not(.footnote-ref):not(.footnote-backref):hover {
  text-decoration-color: var(--color-accent, #2e352e);
}

body.dark .post-content a:not(.footnote-ref):not(.footnote-backref) {
  color: var(--color-ink, #e2e3e1);
  text-decoration-color: rgba(226, 227, 225, 0.28);
}

body.dark .post-content a:not(.footnote-ref):not(.footnote-backref):hover {
  text-decoration-color: var(--color-accent, #b4bcb2);
}

/* ─── HR — editorial wide-dot ornament (ProPublica / Medium pattern) ──
   Five quietly-spaced tiny dots centered in the column.
   No flanking rules — the whitespace does the dividing work.
   <hr> is a void element, so the dots are painted via radial-gradient
   tiles on the hr's own background. */
.post-content hr,
.post-single .post-content hr {
  --dot-color: rgba(30, 35, 30, 0.32);
  --dot-size: 3px;          /* visual diameter of each dot */
  --dot-pitch: 28px;        /* center-to-center spacing */

  border: none !important;
  background: transparent !important;
  height: 8px !important;
  width: calc(var(--dot-pitch) * 5);   /* 5 dots across */
  margin: 3.25rem auto 2.75rem !important;
  overflow: visible;
  position: relative;

  /* Paint 5 dots via a single radial-gradient tiled at the pitch. */
  background-image: radial-gradient(
    circle at center,
    var(--dot-color) 0,
    var(--dot-color) calc(var(--dot-size) / 2),
    transparent calc(var(--dot-size) / 2 + 0.5px)
  ) !important;
  background-size: var(--dot-pitch) 100% !important;
  background-repeat: repeat-x !important;
  background-position: center center !important;
}

/* Remove any previous ::before/::after ornamentation. */
.post-content hr::before,
.post-content hr::after {
  content: none !important;
}

body.dark .post-content hr {
  --dot-color: rgba(255, 255, 255, 0.32);
}

@media (max-width: 520px) {
  .post-content hr {
    --dot-pitch: 22px;
    --dot-size: 2.5px;
  }
}

/* ─── Code block — per-language light & dark themes ──────────── */
/* Four variants:
   1. Light / English  → GitHub Light (#f6f8fa, crisp red/blue/purple)
   2. Light / Chinese  → Ink editorial (#faf8f5, warm ink palette)
   3. Dark  / English  → GitHub Dark (#0d1117, vivid neon palette)
   4. Dark  / Chinese  → Warm dark ink (#191613, amber-warm palette) */

/* ── Shared layout (all variants) ── */
.post-content .highlight,
.post-content pre:not(.mermaid) {
  position: relative;
  margin: 1.75rem 0 !important;
  border-radius: 10px !important;
  overflow: hidden;
  max-width: 100%;
  background: var(--code-surface) !important;
  border: 1px solid var(--code-border) !important;
  box-shadow: var(--code-shadow) !important;
}

/* ── 1. Light / English (default) — GitHub Light inspired ── */
.post-content .highlight,
.post-content pre:not(.mermaid) {
  --code-surface: #f6f8fa;
  --hljs-bg: var(--code-surface);
  --code-ink: #24292f;
  --code-border: rgba(31, 35, 40, 0.15);
  --code-shadow: 0 1px 3px rgba(31,35,40,0.04),
                 0 4px 12px -8px rgba(31,35,40,0.12);
  --code-scroll: rgba(31, 35, 40, 0.18);
  --code-scroll-hover: rgba(31, 35, 40, 0.32);
  --code-btn-bg: rgba(31, 35, 40, 0.05);
  --code-btn-border: rgba(31, 35, 40, 0.12);
  --code-btn-color: rgba(31, 35, 40, 0.55);
  --code-btn-bg-hover: rgba(31, 35, 40, 0.10);
  --code-btn-color-hover: rgba(31, 35, 40, 0.90);
}

/* ── 2. Light / Chinese — warm editorial ink ── */
html:lang(zh) .post-content .highlight,
html:lang(zh) .post-content pre:not(.mermaid) {
  --code-surface: #faf8f5;
  --hljs-bg: var(--code-surface);
  --code-ink: #350003;
  --code-border: rgba(53, 0, 3, 0.10);
  --code-shadow: 0 1px 2px rgba(53,0,3,0.03),
                 0 6px 16px -12px rgba(53,0,3,0.10);
  --code-scroll: rgba(53, 0, 3, 0.14);
  --code-scroll-hover: rgba(53, 0, 3, 0.26);
  --code-btn-bg: rgba(53, 0, 3, 0.04);
  --code-btn-border: rgba(53, 0, 3, 0.10);
  --code-btn-color: rgba(53, 0, 3, 0.50);
  --code-btn-bg-hover: rgba(53, 0, 3, 0.09);
  --code-btn-color-hover: rgba(53, 0, 3, 0.88);
}

/* ── 3. Dark / English — GitHub Dark ── */
html:not(:lang(zh)) body.dark .post-content .highlight,
html:not(:lang(zh)) body.dark .post-content pre:not(.mermaid) {
  --code-surface: #0d1117;
  --hljs-bg: var(--code-surface);
  --code-ink: #e6edf3;
  --code-border: rgba(240,246,252,0.10);
  --code-shadow: 0 1px 2px rgba(0,0,0,0.12),
                 0 8px 24px -16px rgba(0,0,0,0.50);
  --code-scroll: rgba(240,246,252,0.14);
  --code-scroll-hover: rgba(240,246,252,0.26);
  --code-btn-bg: rgba(240,246,252,0.07);
  --code-btn-border: rgba(240,246,252,0.12);
  --code-btn-color: rgba(240,246,252,0.55);
  --code-btn-bg-hover: rgba(240,246,252,0.13);
  --code-btn-color-hover: #fff;
}

/* ── 4. Dark / Chinese — warm dark ink ── */
html:lang(zh) body.dark .post-content .highlight,
html:lang(zh) body.dark .post-content pre:not(.mermaid) {
  /* Recess the code panel from the page paper. The old value (#1c1917) was
     byte-identical to the ZH dark paper (--color-paper: #1c1917), so code
     blocks dissolved into the page and read as borderless slabs — they
     leaned entirely on the hairline --code-border to be seen. The EN dark
     panel is gently recessed below its paper (#0d1117 on #121413, ~1.02:1),
     which gives code an "inset panel" depth. Mirror that for ZH with a warm
     recessed surface (#191613 → ~1.03:1 below #1c1917), keeping the warm hue
     family so the panel still feels at home on the warm paper while gaining
     the same quiet depth. Gated on html:lang(zh) body.dark — light mode and
     EN dark are untouched. Ink #f5f3ee stays at a 16.6:1 panel contrast. */
  --code-surface: #191613;
  --hljs-bg: var(--code-surface);
  --code-ink: #f5f3ee;
  --code-border: rgba(245,243,238,0.14);
  --code-shadow: 0 1px 2px rgba(0,0,0,0.12),
                 0 8px 24px -16px rgba(0,0,0,0.50);
  --code-scroll: rgba(245,243,238,0.12);
  --code-scroll-hover: rgba(245,243,238,0.24);
  --code-btn-bg: rgba(245,243,238,0.06);
  --code-btn-border: rgba(245,243,238,0.10);
  --code-btn-color: rgba(245,243,238,0.52);
  --code-btn-bg-hover: rgba(245,243,238,0.12);
  --code-btn-color-hover: #f5f3ee;
}

/* ── Inner pre inside .highlight: strip duplicate chrome ── */
.post-content .highlight pre {
  margin: 0 !important;
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}

/* ── Code text area ── */
.post-content pre code,
.post-content .highlight pre code {
  display: block;
  padding: 16px 20px !important;
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 0.82em;
  line-height: 1.7;
  color: var(--code-ink) !important;
  background: transparent !important;
  border-radius: 0 !important;
  overflow-x: auto;
  word-break: normal !important;
  tab-size: 2;
  -webkit-font-smoothing: antialiased;
}

/* ── Scrollbar ── */
.post-content pre code::-webkit-scrollbar { height: 6px; }
.post-content pre code::-webkit-scrollbar-thumb {
  background: var(--code-scroll);
  border-radius: 3px;
}
.post-content pre code::-webkit-scrollbar-thumb:hover {
  background: var(--code-scroll-hover);
}

/* ── Copy button — pill, top-right, theme-aware ── */
.post-content .highlight .copy-code,
.post-content pre .copy-code {
  position: absolute;
  top: 10px;
  right: 10px;
  display: inline-flex !important;
  align-items: center;
  gap: 4px;
  padding: 5px 10px !important;
  margin: 0 !important;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.68rem !important;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--code-btn-color) !important;
  background: var(--code-btn-bg) !important;
  border: 1px solid var(--code-btn-border) !important;
  border-radius: 6px !important;
  cursor: pointer;
  opacity: 0;
  transition: opacity 180ms ease, background 180ms ease,
              color 180ms ease, border-color 180ms ease;
  z-index: 2;
}
.post-content .highlight:hover .copy-code,
.post-content pre:hover .copy-code,
.post-content .highlight .copy-code:focus-visible,
.post-content pre .copy-code:focus-visible { opacity: 1; }
.post-content .highlight .copy-code:hover,
.post-content pre .copy-code:hover {
  color: var(--code-btn-color-hover) !important;
  background: var(--code-btn-bg-hover) !important;
  border-color: var(--code-btn-border) !important;
}

/* ═══════════════════════════════════════════════════════════════
   SYNTAX TOKEN COLORS — four variants
   Chroma: .k/.kd/.kn (keyword)  .s/.s1/.s2 (string)  .c/.c1/.cm (comment)
           .nf/.nx (function)  .nb (builtin)  .mi/.mf (number)  .o (op)
           .na (attribute name)
   hljs:   .hljs-keyword  .hljs-string  .hljs-comment  etc.
   ═══════════════════════════════════════════════════════════════ */

/* ── 1. Light / English syntax — GitHub Light ── */
body:not(.dark):not(:lang(zh)) .post-content .highlight code .k,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .kd,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .kn,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .kr,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .kt { color: #cf222e; font-weight: 500; }

body:not(.dark):not(:lang(zh)) .post-content .highlight code .s,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .s1,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .s2,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .sb,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .sc,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .se,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .sr { color: #0a3069; }

body:not(.dark):not(:lang(zh)) .post-content .highlight code .c,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .c1,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .cm,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .cp,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .cs { color: #6e7781; font-style: italic; }

body:not(.dark):not(:lang(zh)) .post-content .highlight code .nf,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .nx { color: #8250df; }

body:not(.dark):not(:lang(zh)) .post-content .highlight code .nb { color: #116329; }
body:not(.dark):not(:lang(zh)) .post-content .highlight code .mi,
body:not(.dark):not(:lang(zh)) .post-content .highlight code .mf { color: #0550ae; }
body:not(.dark):not(:lang(zh)) .post-content .highlight code .o  { color: #24292f; }
body:not(.dark):not(:lang(zh)) .post-content .highlight code .na { color: #116329; }

body:not(.dark):not(:lang(zh)) .post-content pre:not(.mermaid) code { color: var(--code-ink) !important; }

/* hljs — Light / English */
body:not(.dark):not(:lang(zh)) .post-content pre code.hljs,
body:not(.dark):not(:lang(zh)) .post-content .highlight pre code.hljs { background: transparent !important; color: var(--code-ink) !important; }

body:not(.dark):not(:lang(zh)) .post-content code .hljs-keyword,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-selector-tag,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-tag,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-literal,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-type { color: #cf222e !important; font-weight: 500; }

body:not(.dark):not(:lang(zh)) .post-content code .hljs-string,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-regexp,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-char,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-attr,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-attribute { color: #0a3069 !important; }

body:not(.dark):not(:lang(zh)) .post-content code .hljs-comment,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-quote,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-meta { color: #6e7781 !important; font-style: italic; }

body:not(.dark):not(:lang(zh)) .post-content code .hljs-title,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-section,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-function { color: #8250df !important; }

body:not(.dark):not(:lang(zh)) .post-content code .hljs-built_in,
body:not(.dark):not(:lang(zh)) .post-content code .hljs-params { color: #116329 !important; }

body:not(.dark):not(:lang(zh)) .post-content code .hljs-number { color: #0550ae !important; }

/* ── 2. Light / Chinese syntax — ink editorial palette ── */
body:not(.dark):lang(zh) .post-content .highlight code .k,
body:not(.dark):lang(zh) .post-content .highlight code .kd,
body:not(.dark):lang(zh) .post-content .highlight code .kn,
body:not(.dark):lang(zh) .post-content .highlight code .kr,
body:not(.dark):lang(zh) .post-content .highlight code .kt { color: #862122; font-weight: 500; }

body:not(.dark):lang(zh) .post-content .highlight code .s,
body:not(.dark):lang(zh) .post-content .highlight code .s1,
body:not(.dark):lang(zh) .post-content .highlight code .s2,
body:not(.dark):lang(zh) .post-content .highlight code .sb,
body:not(.dark):lang(zh) .post-content .highlight code .sc,
body:not(.dark):lang(zh) .post-content .highlight code .se,
body:not(.dark):lang(zh) .post-content .highlight code .sr { color: #2d5016; }

body:not(.dark):lang(zh) .post-content .highlight code .c,
body:not(.dark):lang(zh) .post-content .highlight code .c1,
body:not(.dark):lang(zh) .post-content .highlight code .cm,
body:not(.dark):lang(zh) .post-content .highlight code .cp,
body:not(.dark):lang(zh) .post-content .highlight code .cs { color: #8b7355; font-style: italic; }

body:not(.dark):lang(zh) .post-content .highlight code .nf,
body:not(.dark):lang(zh) .post-content .highlight code .nx { color: #5c3d8f; }

body:not(.dark):lang(zh) .post-content .highlight code .nb { color: #1a5276; }
body:not(.dark):lang(zh) .post-content .highlight code .mi,
body:not(.dark):lang(zh) .post-content .highlight code .mf { color: #7d4f00; }
body:not(.dark):lang(zh) .post-content .highlight code .o  { color: #5a4a42; }
body:not(.dark):lang(zh) .post-content .highlight code .na { color: #1a5276; }

body:not(.dark):lang(zh) .post-content pre:not(.mermaid) code { color: var(--code-ink) !important; }

/* hljs — Light / Chinese */
body:not(.dark):lang(zh) .post-content pre code.hljs,
body:not(.dark):lang(zh) .post-content .highlight pre code.hljs { background: transparent !important; color: var(--code-ink) !important; }

body:not(.dark):lang(zh) .post-content code .hljs-keyword,
body:not(.dark):lang(zh) .post-content code .hljs-selector-tag,
body:not(.dark):lang(zh) .post-content code .hljs-tag,
body:not(.dark):lang(zh) .post-content code .hljs-literal,
body:not(.dark):lang(zh) .post-content code .hljs-type { color: #862122 !important; font-weight: 500; }

body:not(.dark):lang(zh) .post-content code .hljs-string,
body:not(.dark):lang(zh) .post-content code .hljs-regexp,
body:not(.dark):lang(zh) .post-content code .hljs-char,
body:not(.dark):lang(zh) .post-content code .hljs-attr,
body:not(.dark):lang(zh) .post-content code .hljs-attribute { color: #2d5016 !important; }

body:not(.dark):lang(zh) .post-content code .hljs-comment,
body:not(.dark):lang(zh) .post-content code .hljs-quote,
body:not(.dark):lang(zh) .post-content code .hljs-meta { color: #8b7355 !important; font-style: italic; }

body:not(.dark):lang(zh) .post-content code .hljs-title,
body:not(.dark):lang(zh) .post-content code .hljs-section,
body:not(.dark):lang(zh) .post-content code .hljs-function { color: #5c3d8f !important; }

body:not(.dark):lang(zh) .post-content code .hljs-built_in,
body:not(.dark):lang(zh) .post-content code .hljs-params { color: #1a5276 !important; }

body:not(.dark):lang(zh) .post-content code .hljs-number { color: #7d4f00 !important; }

/* ── 3. Dark / English syntax — GitHub Dark ── */
html:not(:lang(zh)) body.dark .post-content .highlight code .k,
html:not(:lang(zh)) body.dark .post-content .highlight code .kd,
html:not(:lang(zh)) body.dark .post-content .highlight code .kn,
html:not(:lang(zh)) body.dark .post-content .highlight code .kr,
html:not(:lang(zh)) body.dark .post-content .highlight code .kt { color: #ff7b72; font-weight: 500; }

html:not(:lang(zh)) body.dark .post-content .highlight code .s,
html:not(:lang(zh)) body.dark .post-content .highlight code .s1,
html:not(:lang(zh)) body.dark .post-content .highlight code .s2,
html:not(:lang(zh)) body.dark .post-content .highlight code .sb,
html:not(:lang(zh)) body.dark .post-content .highlight code .sc,
html:not(:lang(zh)) body.dark .post-content .highlight code .se,
html:not(:lang(zh)) body.dark .post-content .highlight code .sr { color: #a5d6ff; }

html:not(:lang(zh)) body.dark .post-content .highlight code .c,
html:not(:lang(zh)) body.dark .post-content .highlight code .c1,
html:not(:lang(zh)) body.dark .post-content .highlight code .cm,
html:not(:lang(zh)) body.dark .post-content .highlight code .cp,
html:not(:lang(zh)) body.dark .post-content .highlight code .cs { color: #8b949e; font-style: italic; }

html:not(:lang(zh)) body.dark .post-content .highlight code .nf,
html:not(:lang(zh)) body.dark .post-content .highlight code .nx { color: #d2a8ff; }

html:not(:lang(zh)) body.dark .post-content .highlight code .nb { color: #7ee787; }
html:not(:lang(zh)) body.dark .post-content .highlight code .mi,
html:not(:lang(zh)) body.dark .post-content .highlight code .mf { color: #79c0ff; }
html:not(:lang(zh)) body.dark .post-content .highlight code .o  { color: #e6edf3; }
html:not(:lang(zh)) body.dark .post-content .highlight code .na { color: #79c0ff; }

/* Additional Chroma tokens — without these, YAML keys (.nt), constants (.kc),
   generic numbers (.m), interpolations (.si), variables (.nv) and class /
   namespace / decorator names fall through to the flat default code ink,
   which reads as washed-out, structureless code on the dark surface
   (very common in this blog's YAML / shell / Python samples). Map each to the
   matching GitHub-Dark hue already used above so highlighted code keeps its
   structure in dark. Gated on body.dark — light mode is never selected. */
html:not(:lang(zh)) body.dark .post-content .highlight code .kc,
html:not(:lang(zh)) body.dark .post-content .highlight code .ow { color: #ff7b72; font-weight: 500; }
html:not(:lang(zh)) body.dark .post-content .highlight code .si,
html:not(:lang(zh)) body.dark .post-content .highlight code .sa,
html:not(:lang(zh)) body.dark .post-content .highlight code .sd,
html:not(:lang(zh)) body.dark .post-content .highlight code .sc { color: #a5d6ff; }
html:not(:lang(zh)) body.dark .post-content .highlight code .m  { color: #79c0ff; }
html:not(:lang(zh)) body.dark .post-content .highlight code .nt { color: #7ee787; }
html:not(:lang(zh)) body.dark .post-content .highlight code .bp { color: #7ee787; }
html:not(:lang(zh)) body.dark .post-content .highlight code .nv,
html:not(:lang(zh)) body.dark .post-content .highlight code .vm,
html:not(:lang(zh)) body.dark .post-content .highlight code .fm { color: #ffa657; }
html:not(:lang(zh)) body.dark .post-content .highlight code .nc,
html:not(:lang(zh)) body.dark .post-content .highlight code .nn,
html:not(:lang(zh)) body.dark .post-content .highlight code .nd,
html:not(:lang(zh)) body.dark .post-content .highlight code .ne,
html:not(:lang(zh)) body.dark .post-content .highlight code .no { color: #d2a8ff; }

/* hljs — Dark / English */
html:not(:lang(zh)) body.dark .post-content pre code.hljs,
html:not(:lang(zh)) body.dark .post-content .highlight pre code.hljs { background: transparent !important; color: var(--code-ink) !important; }

html:not(:lang(zh)) body.dark .post-content code .hljs-keyword,
html:not(:lang(zh)) body.dark .post-content code .hljs-selector-tag,
html:not(:lang(zh)) body.dark .post-content code .hljs-tag,
html:not(:lang(zh)) body.dark .post-content code .hljs-literal,
html:not(:lang(zh)) body.dark .post-content code .hljs-type { color: #ff7b72 !important; font-weight: 500; }

html:not(:lang(zh)) body.dark .post-content code .hljs-string,
html:not(:lang(zh)) body.dark .post-content code .hljs-regexp,
html:not(:lang(zh)) body.dark .post-content code .hljs-char,
html:not(:lang(zh)) body.dark .post-content code .hljs-attr,
html:not(:lang(zh)) body.dark .post-content code .hljs-attribute { color: #a5d6ff !important; }

html:not(:lang(zh)) body.dark .post-content code .hljs-comment,
html:not(:lang(zh)) body.dark .post-content code .hljs-quote,
html:not(:lang(zh)) body.dark .post-content code .hljs-meta { color: #8b949e !important; font-style: italic; }

html:not(:lang(zh)) body.dark .post-content code .hljs-title,
html:not(:lang(zh)) body.dark .post-content code .hljs-section,
html:not(:lang(zh)) body.dark .post-content code .hljs-function { color: #d2a8ff !important; }

html:not(:lang(zh)) body.dark .post-content code .hljs-built_in,
html:not(:lang(zh)) body.dark .post-content code .hljs-params { color: #7ee787 !important; }

html:not(:lang(zh)) body.dark .post-content code .hljs-number { color: #79c0ff !important; }

/* ── 4. Dark / Chinese syntax — warm amber-ink palette ── */
html:lang(zh) body.dark .post-content .highlight code .k,
html:lang(zh) body.dark .post-content .highlight code .kd,
html:lang(zh) body.dark .post-content .highlight code .kn,
html:lang(zh) body.dark .post-content .highlight code .kr,
html:lang(zh) body.dark .post-content .highlight code .kt { color: #ff6b6b; font-weight: 500; }

html:lang(zh) body.dark .post-content .highlight code .s,
html:lang(zh) body.dark .post-content .highlight code .s1,
html:lang(zh) body.dark .post-content .highlight code .s2,
html:lang(zh) body.dark .post-content .highlight code .sb,
html:lang(zh) body.dark .post-content .highlight code .sc,
html:lang(zh) body.dark .post-content .highlight code .se,
html:lang(zh) body.dark .post-content .highlight code .sr { color: #a8d8a8; }

html:lang(zh) body.dark .post-content .highlight code .c,
html:lang(zh) body.dark .post-content .highlight code .c1,
html:lang(zh) body.dark .post-content .highlight code .cm,
html:lang(zh) body.dark .post-content .highlight code .cp,
html:lang(zh) body.dark .post-content .highlight code .cs { color: #b8ada3; font-style: italic; }

html:lang(zh) body.dark .post-content .highlight code .nf,
html:lang(zh) body.dark .post-content .highlight code .nx { color: #c792ea; }

html:lang(zh) body.dark .post-content .highlight code .nb { color: #68d7e4; }
html:lang(zh) body.dark .post-content .highlight code .mi,
html:lang(zh) body.dark .post-content .highlight code .mf { color: #e5c07b; }
html:lang(zh) body.dark .post-content .highlight code .o  { color: #f5f3ee; }
html:lang(zh) body.dark .post-content .highlight code .na { color: #68d7e4; }

/* Additional Chroma tokens (see note in the EN block above) mapped to the
   warm dark palette so YAML keys, constants, variables and class names keep
   their structure in Chinese dark mode. Gated on body.dark — light untouched. */
html:lang(zh) body.dark .post-content .highlight code .kc,
html:lang(zh) body.dark .post-content .highlight code .ow { color: #ff6b6b; font-weight: 500; }
html:lang(zh) body.dark .post-content .highlight code .si,
html:lang(zh) body.dark .post-content .highlight code .sa,
html:lang(zh) body.dark .post-content .highlight code .sd,
html:lang(zh) body.dark .post-content .highlight code .sc { color: #a8d8a8; }
html:lang(zh) body.dark .post-content .highlight code .m  { color: #e5c07b; }
html:lang(zh) body.dark .post-content .highlight code .nt { color: #68d7e4; }
html:lang(zh) body.dark .post-content .highlight code .bp { color: #68d7e4; }
html:lang(zh) body.dark .post-content .highlight code .nv,
html:lang(zh) body.dark .post-content .highlight code .vm,
html:lang(zh) body.dark .post-content .highlight code .fm,
html:lang(zh) body.dark .post-content .highlight code .nc,
html:lang(zh) body.dark .post-content .highlight code .nn,
html:lang(zh) body.dark .post-content .highlight code .nd,
html:lang(zh) body.dark .post-content .highlight code .ne,
html:lang(zh) body.dark .post-content .highlight code .no { color: #c792ea; }

/* hljs — Dark / Chinese */
html:lang(zh) body.dark .post-content pre code.hljs,
html:lang(zh) body.dark .post-content .highlight pre code.hljs { background: transparent !important; color: var(--code-ink) !important; }

html:lang(zh) body.dark .post-content code .hljs-keyword,
html:lang(zh) body.dark .post-content code .hljs-selector-tag,
html:lang(zh) body.dark .post-content code .hljs-tag,
html:lang(zh) body.dark .post-content code .hljs-literal,
html:lang(zh) body.dark .post-content code .hljs-type { color: #ff6b6b !important; font-weight: 500; }

html:lang(zh) body.dark .post-content code .hljs-string,
html:lang(zh) body.dark .post-content code .hljs-regexp,
html:lang(zh) body.dark .post-content code .hljs-char,
html:lang(zh) body.dark .post-content code .hljs-attr,
html:lang(zh) body.dark .post-content code .hljs-attribute { color: #a8d8a8 !important; }

html:lang(zh) body.dark .post-content code .hljs-comment,
html:lang(zh) body.dark .post-content code .hljs-quote,
html:lang(zh) body.dark .post-content code .hljs-meta { color: #b8ada3 !important; font-style: italic; }

html:lang(zh) body.dark .post-content code .hljs-title,
html:lang(zh) body.dark .post-content code .hljs-section,
html:lang(zh) body.dark .post-content code .hljs-function { color: #c792ea !important; }

html:lang(zh) body.dark .post-content code .hljs-built_in,
html:lang(zh) body.dark .post-content code .hljs-params { color: #68d7e4 !important; }

html:lang(zh) body.dark .post-content code .hljs-number { color: #e5c07b !important; }

/* ── Paragraph breathing room ── */
.post-content p + .highlight,
.post-content p + pre {
  margin-top: 1.25rem;
}
