@import "tailwindcss";
@import "fumadocs-ui/css/preset.css";
@import "../../../packages/ui/styles/tokens.css";

@custom-variant dark (&:is(.dark *));

@source "../../../packages/ui/**/*.{ts,tsx}";

/* ---------------------------------------------------------------------------
 * Font stack. `--font-inter` is the next/font Inter family (+ synthetic
 * size-adjusted fallback), set on <html> by inter.variable in app/[lang]/layout.tsx.
 * `--font-sans` is composed here in static CSS so it can be overridden per
 * `<html lang>` and stays CSP-safe (no inline <style>). Tailwind's `font-sans`
 * utility resolves `var(--font-sans)`. Mirrors apps/web/app/globals.css.
 *
 * Default (en / zh / ko): Latin → Inter, CJK → Chinese then Korean. Chinese MUST
 * stay before Korean so zh users don't get Korean Hanja glyph shapes.
 * ------------------------------------------------------------------------- */

:root {
  --font-sans: var(--font-inter), -apple-system, BlinkMacSystemFont, "Segoe UI",
    "PingFang SC", "Microsoft YaHei", "Noto Sans CJK SC", "Apple SD Gothic Neo",
    "Malgun Gothic", "Noto Sans CJK KR", sans-serif;
}

/* Japanese: Kanji share the Han Unicode block with Chinese and CSS fallback
   order is not affected by `<html lang>`, so promote a Japanese-first CJK chain
   only for Japanese docs (`<html lang="ja">`). `[lang|="ja"]` is the BCP-47
   language-range selector — matches exactly `ja` or `ja-<region>`, never
   unrelated subtags like `jam`. Inter still leads for Latin. */
html[lang|="ja"] {
  --font-sans: var(--font-inter), "Hiragino Sans", "Hiragino Kaku Gothic ProN",
    "Yu Gothic", "YuGothic", "Meiryo", "Noto Sans CJK JP", "Noto Sans JP",
    -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
    "Microsoft YaHei", "Noto Sans CJK SC", "Apple SD Gothic Neo", "Malgun Gothic",
    "Noto Sans CJK KR", sans-serif;
}

/* ---------------------------------------------------------------------------
 * Multica Docs — editorial visual identity (v2)
 *
 * Docs site is intentionally distinct from the product app: warm-paper
 * background, editorial serif headings (Source Serif 4), indigo accent,
 * ruled dividers. Product app keeps its cool-gray dense Linear-style; docs
 * reads like a literary publication. Same split as Stripe, Cursor, Linear.
 *
 * Implementation: docs-scoped token override on top of Multica tokens
 * (whose @theme inline references read --background / --foreground / etc
 * at runtime, so re-pointing the vars cascades through fumadocs's full
 * --color-fd-* bridge below).
 * ------------------------------------------------------------------------- */

:root {
  --fd-page-width: 1080px;
}

/* ---------------------------------------------------------------------------
 * Editorial palette — light
 * ------------------------------------------------------------------------- */

:root {
  --background: oklch(0.972 0.003 85);          /* near-white, faint warm — matches landing #f7f7f5 */
  --foreground: oklch(0.182 0.012 50);          /* warm ink */
  --muted: oklch(0.955 0.006 85);               /* hairline, slightly warmer than bg */
  --muted-foreground: oklch(0.482 0.012 65);    /* warm muted */
  --card: oklch(0.99 0.002 85);                 /* paper — near white */
  --card-foreground: oklch(0.182 0.012 50);
  --popover: oklch(0.99 0.002 85);
  --popover-foreground: oklch(0.182 0.012 50);
  --primary: oklch(0.55 0.16 255);              /* Multica brand */
  --primary-foreground: oklch(0.985 0.008 85);
  --secondary: oklch(0.945 0.012 85);
  --secondary-foreground: oklch(0.182 0.012 50);
  --accent: oklch(0.945 0.022 255);             /* brand soft wash */
  --accent-foreground: oklch(0.46 0.16 255);    /* brand ink */
  --border: oklch(0.91 0.014 85);               /* ruled lines */
  --input: oklch(0.91 0.014 85);
  --ring: oklch(0.55 0.16 255);
  --sidebar: oklch(0.99 0.002 85);              /* paper — same as card */
  --sidebar-foreground: oklch(0.182 0.012 50);
  --sidebar-accent: oklch(0.945 0.006 85);      /* subtle cream, hover/active fill */
  --sidebar-accent-foreground: oklch(0.182 0.012 50);
  --sidebar-border: oklch(0.91 0.014 85);

  /* Docs-only extras (not bridged to fumadocs slots) */
  --docs-rule: oklch(0.835 0.018 85);           /* heavier rule */
  --docs-faint: oklch(0.72 0.018 75);           /* faintest accent */
  --docs-code-bg: oklch(0.94 0.018 85);         /* warm beige code surface */
  --docs-code-border: oklch(0.89 0.018 85);
  --docs-terminal-bg: oklch(0.18 0.012 50);     /* terminal warm dark */
  --docs-terminal-fg: oklch(0.92 0.012 80);
  --docs-terminal-accent: oklch(0.65 0.16 255);
}

/* ---------------------------------------------------------------------------
 * Editorial palette — dark (warm dark, NOT Multica's cool dark)
 * ------------------------------------------------------------------------- */

.dark {
  --background: oklch(0.18 0.008 50);
  --foreground: oklch(0.95 0.012 85);
  --muted: oklch(0.22 0.008 50);
  --muted-foreground: oklch(0.65 0.012 75);
  --card: oklch(0.21 0.008 50);
  --card-foreground: oklch(0.95 0.012 85);
  --popover: oklch(0.22 0.008 50);
  --popover-foreground: oklch(0.95 0.012 85);
  --primary: oklch(0.7 0.15 255);               /* Multica brand — dark */
  --primary-foreground: oklch(0.18 0.008 50);
  --secondary: oklch(0.24 0.008 50);
  --secondary-foreground: oklch(0.95 0.012 85);
  --accent: oklch(0.3 0.05 255);                /* brand soft wash — dark */
  --accent-foreground: oklch(0.78 0.14 255);    /* brand ink — dark */
  --border: oklch(0.28 0.012 50);
  --input: oklch(0.28 0.012 50);
  --ring: oklch(0.7 0.15 255);
  --sidebar: oklch(0.21 0.008 50);
  --sidebar-foreground: oklch(0.95 0.012 85);
  --sidebar-accent: oklch(0.26 0.01 50);        /* warm neutral, hover/active fill — dark */
  --sidebar-accent-foreground: oklch(0.95 0.012 85);
  --sidebar-border: oklch(0.28 0.012 50);

  --docs-rule: oklch(0.36 0.012 50);
  --docs-faint: oklch(0.42 0.012 50);
  --docs-code-bg: oklch(0.165 0.008 50);
  --docs-code-border: oklch(0.26 0.012 50);
  --docs-terminal-bg: oklch(0.155 0.012 50);
  --docs-terminal-fg: oklch(0.92 0.012 80);
  --docs-terminal-accent: oklch(0.78 0.14 255);
}

/* ---------------------------------------------------------------------------
 * Fumadocs slot bridge
 *
 * Map fumadocs's --color-fd-* slots to our (now warm) Multica tokens.
 * @theme inline keeps the var() reference live so the cascade resolves
 * at runtime — same pattern tokens.css uses.
 * ------------------------------------------------------------------------- */

@theme inline {
  --color-fd-background: var(--background);
  --color-fd-foreground: var(--foreground);
  --color-fd-muted: var(--muted);
  --color-fd-muted-foreground: var(--muted-foreground);
  --color-fd-popover: var(--popover);
  --color-fd-popover-foreground: var(--popover-foreground);
  --color-fd-card: var(--card);
  --color-fd-card-foreground: var(--card-foreground);
  --color-fd-border: var(--border);
  --color-fd-primary: var(--primary);
  --color-fd-primary-foreground: var(--primary-foreground);
  --color-fd-secondary: var(--secondary);
  --color-fd-secondary-foreground: var(--secondary-foreground);
  --color-fd-accent: var(--accent);
  --color-fd-accent-foreground: var(--accent-foreground);
  --color-fd-ring: var(--ring);
}

/* Sidebar uses dedicated --sidebar-* tokens so it sits a hair off the main
 * canvas. Fumadocs renders it as #nd-sidebar (desktop) and
 * #nd-sidebar-mobile (mobile drawer); both IDs need the override. */
#nd-sidebar,
#nd-sidebar-mobile {
  --color-fd-background: var(--sidebar);
  --color-fd-foreground: var(--sidebar-foreground);
  --color-fd-muted: var(--sidebar-accent);
  --color-fd-muted-foreground: var(--sidebar-foreground);
  --color-fd-accent: var(--sidebar-accent);
  --color-fd-accent-foreground: var(--sidebar-accent-foreground);
  --color-fd-border: var(--sidebar-border);
}

/* ---------------------------------------------------------------------------
 * Editorial typography
 *
 * Body keeps Inter for legibility (especially CJK where serif Latin clashes
 * with sans CJK). Headings switch to Source Serif 4 for the editorial
 * signature. Italic is intentionally avoided — Chinese italic is a CSS
 * synthetic slant against upright-designed glyphs and reads as broken.
 * Emphasis is carried by serif/sans contrast, brand color, and weight.
 *
 * Sizing:
 *   - DocsHero h1 (welcome page only): 44px serif, brand-color em accent
 *   - prose h1 (guide / reference pages): 30px serif
 *   - prose h2: 26px serif (no italic)
 *   - prose h3: 13px sans uppercase label
 *   - body: 15.5px (kept from previous build — proven reading size for CN)
 * ------------------------------------------------------------------------- */

article:has(.prose),
.prose {
  font-size: 0.96875rem; /* 15.5px */
  line-height: 1.7;
}

/* DocsTitle h1 (Fumadocs hardcodes text-[1.75em] font-semibold — utility
 * specificity 0,1,0 beats plain article > h1 0,0,2; !important wins). */
article > h1 {
  font-family: var(--font-serif), ui-serif, serif !important;
  font-size: 1.875rem !important; /* 30px guide-page heading */
  font-weight: 400 !important;
  letter-spacing: -0.018em;
  line-height: 1.15;
  margin-bottom: 0.5em;
  color: var(--foreground);
}

/* Lead paragraph below DocsTitle */
article > p.text-lg {
  font-family: var(--font-serif), ui-serif, serif;
  font-size: 1.125rem; /* 18px serif lede */
  line-height: 1.55;
  margin-bottom: 2rem;
  color: var(--muted-foreground);
}

/* Paragraph rhythm */
.prose :where(p):not(:where([class~="not-prose"] *)) {
  margin-top: 0;
  margin-bottom: 0.875rem;
  color: oklch(from var(--foreground) calc(l + 0.06) c h);
}
.prose :where(p):not(:where([class~="not-prose"] *)):last-child {
  margin-bottom: 0;
}
.prose :where(p) strong {
  color: var(--foreground);
  font-weight: 600;
}

.prose :where(ul, ol) {
  margin-top: 0.5rem;
  margin-bottom: 1rem;
}

.prose h1 {
  font-family: var(--font-serif), ui-serif, serif;
  font-size: 1.875rem; /* 30px */
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin-bottom: 0.5em;
  color: var(--foreground);
}
/* Italic is avoided sitewide (Chinese italic = synthetic slant, looks broken).
 * Force any italicized element to non-italic in prose. Tailwind Typography
 * defaults blockquote to italic; we also undo it here. Emphasis is carried
 * by brand color + font-weight in headings, foreground+weight in body. */
.prose em,
.prose i,
.prose cite,
.prose blockquote,
.prose blockquote p {
  font-style: normal;
}
.prose h1 em {
  color: var(--primary);
  font-weight: 500;
}
.prose p em,
.prose li em {
  color: var(--foreground);
  font-weight: 600;
}

.prose h2 {
  font-family: var(--font-serif), ui-serif, serif;
  font-size: 1.625rem; /* 26px */
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.3;
  margin-top: 2em;
  margin-bottom: 0.5em;
  color: var(--foreground);
  scroll-margin-top: 80px;
}

/* h3 = small uppercase sans label, ruled-bottom — v2 editorial signature */
.prose h3 {
  font-family: var(--font-sans), system-ui, sans-serif;
  font-size: 0.8125rem; /* 13px */
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted-foreground);
  margin-top: 2.25em;
  margin-bottom: 0.75em;
  padding-bottom: 0.25em;
  border-bottom: 1px solid var(--border);
}

.prose h4 {
  font-family: var(--font-serif), ui-serif, serif;
  font-size: 1.0625rem; /* 17px */
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.4;
  margin-top: 1.5em;
  margin-bottom: 0.375em;
  color: var(--foreground);
}

/* Description paragraph (fumadocs adds text-lg + muted) */
.prose > p:first-of-type:has(+ *) {
  line-height: 1.6;
}

/* ---------------------------------------------------------------------------
 * Links — Vercel-style hairline underline, reveal brand on hover
 *
 * Markdown-heavy prose can put 4+ inline links in a single sentence; a
 * permanent brand-color underline on every one turns the paragraph into
 * highlighter spam. The trick isn't "no underline" — it's underlining
 * in the hairline border color so the line exists but visually recedes.
 * Hover swaps both text and underline to brand color (no thickness
 * change) — the link "arrives" as a single color shift.
 * ------------------------------------------------------------------------- */

.prose a:not([data-card]):not(.not-prose) {
  color: var(--foreground);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: var(--border);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: text-decoration-color 150ms, color 150ms;
}
.prose a:not([data-card]):not(.not-prose):hover {
  color: var(--primary);
  text-decoration-color: var(--primary);
}

/* Callout already carries four visual signals (left brand bar, brand-wash
 * bg, uppercase NOTE label, body). Another decoration over-loads it — so
 * links inside a callout drop the underline entirely. Color shift on
 * hover is the full affordance. */
.prose div.shadow-md:has(> [role="none"]) a:not([data-card]):not(.not-prose),
.prose div.shadow-md:has(> [role="none"]) a:not([data-card]):not(.not-prose):hover {
  text-decoration: none;
}

/* Inline code — warm beige chip, accent-color text */
.prose :not(pre) > code {
  background: var(--docs-code-bg);
  color: var(--accent-foreground);
  padding: 0.125rem 0.375rem;
  border-radius: 3px;
  font-family: var(--font-mono), ui-monospace, monospace;
  font-size: 0.875em;
  font-weight: 500;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.prose :not(pre) > code::before,
.prose :not(pre) > code::after {
  content: none;
}

/* Lists */
.prose :where(ul, ol) > li {
  margin-top: 0.375em;
  margin-bottom: 0.375em;
  padding-inline-start: 0.375em;
}
.prose :where(ul) > li::marker {
  color: var(--docs-faint);
  content: "—  ";
  font-family: var(--font-serif), serif;
}
.prose :where(ol) > li::marker {
  color: var(--muted-foreground);
}

/* Blockquote — editorial accent rule, serif voice */
.prose blockquote {
  font-family: var(--font-serif), ui-serif, serif;
  font-weight: 400;
  font-size: 1.0625rem;
  line-height: 1.55;
  color: var(--foreground);
  border-inline-start-width: 2px;
  border-inline-start-color: var(--primary);
  padding-inline-start: 1.25em;
  margin-block: 1.5em;
  quotes: none;
}
.prose blockquote p::before,
.prose blockquote p::after {
  content: none;
}

/* Tables — hairline below thead only, no outer frame (Stripe / Linear
 * docs convention). The heavier ink-color top rule v2 used on its API
 * reference block is intentionally not applied here — that treatment is
 * "this is a formal declaration"; regular guide tables want quiet. */
.prose table {
  font-size: 0.9375em;
  border-collapse: collapse;
  margin-block: 1.5em;
}
.prose thead {
  border-bottom: 1px solid var(--border);
}
.prose thead th {
  font-family: var(--font-sans), system-ui, sans-serif;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  padding-block: 0.5rem 0.625rem;
  text-align: start;
}
.prose tbody tr {
  border-bottom: 1px solid var(--border);
}
.prose tbody td {
  padding-block: 0.875rem;
}

/* HR — heavier ruled separator */
.prose hr {
  border: none;
  border-top: 1px solid var(--docs-rule);
  margin-block: 3em;
}

/* ---------------------------------------------------------------------------
 * Callout — editorial 2px accent bar + soft accent wash
 * ------------------------------------------------------------------------- */

.prose div.shadow-md:has(> [role="none"]) {
  box-shadow: none !important;
  border-radius: 0 4px 4px 0 !important;
  background: var(--accent) !important;
  border: none !important;
  border-inline-start: 2px solid var(--primary) !important;
  padding: 0.875rem 1.125rem !important;
  gap: 0.625rem !important;
  align-items: flex-start;
  margin-block: 1.5rem;
}

.prose div.shadow-md:has(> [role="none"]) > [role="none"] {
  display: none;
}

.prose div.shadow-md:has(> [role="none"]) > div:last-child > p {
  font-family: var(--font-sans), system-ui, sans-serif;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--primary);
  margin-bottom: 0.375rem;
}

.prose div.shadow-md:has(> [role="none"]) > div:last-child > div {
  color: var(--foreground) !important;
  font-size: 0.9375rem;
  line-height: 1.6;
}

/* ---------------------------------------------------------------------------
 * Cards — fallback editorial treatment for fumadocs's <Cards>/<Card>
 * (NumberedCards is the showpiece; this keeps non-showpiece pages on tone)
 * ------------------------------------------------------------------------- */

.prose [data-card]:not(.peer) {
  border-radius: 4px !important;
  border: 1px solid var(--border) !important;
  background: var(--card);
  padding: 1.125rem !important;
  transition: border-color 150ms, background-color 150ms !important;
}

.prose [data-card]:not(.peer):hover {
  border-color: var(--primary) !important;
  background: var(--card) !important;
}

.prose [data-card]:not(.peer) > div:first-child {
  box-shadow: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  background: transparent !important;
  border: none !important;
  color: var(--accent-foreground) !important;
  margin-bottom: 0.75rem !important;
}

.prose [data-card]:not(.peer) > div:first-child svg {
  color: var(--accent-foreground);
}

.prose [data-card]:not(.peer) h3 {
  font-family: var(--font-serif), serif !important;
  font-size: 1.125rem !important;
  font-weight: 500 !important;
  font-style: normal !important;
  letter-spacing: -0.01em;
  margin-bottom: 0.25rem !important;
  margin-top: 0 !important;
  text-transform: none !important;
  border-bottom: none !important;
  padding-bottom: 0 !important;
  color: var(--foreground) !important;
}

.prose [data-card]:not(.peer) p {
  color: var(--muted-foreground) !important;
  line-height: 1.6;
  font-size: 0.9375rem !important;
}

/* ---------------------------------------------------------------------------
 * Sidebar — editorial chrome
 *
 * Section headers: small uppercase sans label, ruled bottom border.
 * Items: muted-foreground at rest, foreground on hover.
 * Active: solid background fill (mirrors product app's app-sidebar.tsx —
 * data-active:bg-sidebar-accent / data-active:text-sidebar-accent-foreground).
 * ------------------------------------------------------------------------- */

#nd-sidebar p,
#nd-sidebar-mobile p {
  font-family: var(--font-sans), system-ui, sans-serif;
  font-size: 0.6875rem; /* 11px */
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  height: auto;
  display: block;
  margin-top: 1.5rem;
  margin-bottom: 0.375rem;
  padding-block: 0 0.375rem;
  padding-inline-start: 0.5rem;
  border-bottom: 1px solid var(--border);
}

#nd-sidebar p:first-child,
#nd-sidebar-mobile p:first-child {
  margin-top: 0;
}

#nd-sidebar a[data-active],
#nd-sidebar-mobile a[data-active] {
  height: auto;
  padding: 0.375rem 0.625rem;
  font-size: 0.84375rem; /* 13.5px */
  border-radius: var(--radius-sm);
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: -0.005em;
  display: flex;
  align-items: center;
}

#nd-sidebar a[data-active="false"],
#nd-sidebar-mobile a[data-active="false"] {
  color: var(--muted-foreground);
}

#nd-sidebar a[data-active="false"]:hover,
#nd-sidebar-mobile a[data-active="false"]:hover {
  background: color-mix(in oklab, var(--sidebar-accent) 70%, transparent);
  color: var(--foreground);
}

/* Active — solid background fill, no left mark (matches product app) */
#nd-sidebar a[data-active="true"],
#nd-sidebar-mobile a[data-active="true"] {
  background: var(--sidebar-accent) !important;
  color: var(--sidebar-accent-foreground) !important;
  font-weight: 500;
}

/* Sidebar footer — drop the hard top rule. The scroll viewport already
 * fades content into the footer, so a 1px line on top reads as a
 * double-weight edge. Fumadocs hardcodes `border-t p-4 pt-2` on its
 * SidebarFooter div; target that exact class trio inside the sidebar IDs
 * so we don't touch any other border-t in the app. */
#nd-sidebar .border-t.p-4.pt-2,
#nd-sidebar-mobile .border-t.p-4.pt-2 {
  border-top-width: 0;
}

/* ---------------------------------------------------------------------------
 * Top nav — quiet, ruled bottom
 * ------------------------------------------------------------------------- */

#nd-nav,
#nd-subnav {
  border-bottom: 1px solid var(--border);
  background: var(--card);
}

#nd-nav a,
#nd-subnav a {
  font-size: 0.875rem;
  color: var(--muted-foreground);
  transition: color 150ms;
}

#nd-nav a:hover,
#nd-subnav a:hover {
  color: var(--foreground);
}

/* ---------------------------------------------------------------------------
 * TOC (right rail) — quiet sans, brand-color when active
 * ------------------------------------------------------------------------- */

#nd-toc a {
  font-size: 0.84375rem;
  color: var(--muted-foreground);
  padding-block: 0.3125rem;
  letter-spacing: -0.005em;
  transition: color 150ms;
}

#nd-toc a:hover {
  color: var(--foreground);
}

#nd-toc a[data-active="true"] {
  color: var(--primary);
  font-weight: 500;
}

/* TOC heading (Fumadocs renders "On this page" as an h3 / first p) */
#nd-toc h3,
#nd-toc > p:first-child {
  font-family: var(--font-sans), system-ui, sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  margin-bottom: 0.625rem;
  padding-bottom: 0.375rem;
  border-bottom: 1px solid var(--border);
}

/* ---------------------------------------------------------------------------
 * Code blocks — warm beige (light) / warm dark (dark), NOT pinned
 *
 * Removes the previous "always-dark hero black" treatment. Code surface
 * now follows page theme so it harmonizes with the warm-paper background
 * in light mode and warm-dark in dark mode. Terminal-style blocks
 * (handled by the custom <Terminal> component, not here) stay pinned to
 * the deeper warm dark for the "shell session" feel.
 * ------------------------------------------------------------------------- */

article figure.shiki {
  background: var(--docs-code-bg) !important;
  border: 1px solid var(--docs-code-border) !important;
  border-radius: 4px !important;
  box-shadow: none !important;
  margin-block: 1.25rem !important;
  color: var(--foreground);
}

article figure.shiki pre {
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  color: inherit !important;
  margin: 0 !important;
}

article figure.shiki > div[class*="overflow-auto"] {
  font-size: 0.84375rem !important;
  line-height: 1.7;
  padding: 1rem 1.125rem !important;
}

/* Header bar (filename via ```lang filename="x.ts") */
article figure.shiki > div[class*="border-b"] {
  border-bottom-color: var(--docs-code-border) !important;
  background: var(--muted) !important;
  color: var(--muted-foreground) !important;
  font-family: var(--font-mono), ui-monospace, monospace;
  font-size: 0.75rem;
  letter-spacing: -0.005em;
}

/* Shiki tokens — pick the palette that matches page theme.
 * Default (light): use --shiki-light. Override under .dark to --shiki-dark.
 * Specificity: article figure.shiki code span (0,1,4) beats fumadocs's
 * default, so no !important needed for the light path. */
article figure.shiki code span {
  color: var(--shiki-light);
}

.dark article figure.shiki code span {
  color: var(--shiki-dark);
}

/* Copy button on code blocks */
article figure.shiki button {
  color: var(--muted-foreground) !important;
  background: transparent !important;
}
article figure.shiki button:hover {
  color: var(--foreground) !important;
  background: var(--muted) !important;
}
