Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default async function Page(props: PageProps<"/[[...slug]]">) {
return (
<DocsPage toc={page.data.toc} full={page.data.full}>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription className="mb-0">
<DocsDescription className="mb-0 text-fd-foreground">
{page.data.description}
</DocsDescription>
<div className="flex flex-row gap-2 items-center border-b pb-6">
Expand Down
35 changes: 35 additions & 0 deletions src/app/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,41 @@
}
}

/* ── Body copy ── */

/* Fumadocs sets prose body text to `--color-fd-foreground` at 90%, and renders
the page description (DocsDescription, the standfirst under the H1) muted.
We want the reverse: the standfirst leads at full contrast, and the body
copy sits back. Only `--tw-prose-body` moves — headings, links, bold, code,
quotes and captions keep their own variables, so they stay prominent
against the softer paragraph text.

Both values are theme tokens, so light and dark follow the same rule with
no per-mode override. The description's colour is set at the call site in
the two page routes.

Deliberately unlayered. Fumadocs declares `.prose` in `@layer utilities`,
and layer order beats both specificity and source order — the same rule
inside `@layer components` below is silently ignored. Unlayered
declarations outrank every layer, so this wins without `!important`. */
.prose {
--tw-prose-body: var(--color-fd-muted-foreground);
}

/* Callout body sits one step above the muted paragraphs around it: the colour
prose body copy had before the rule above. A callout is already set apart by
its card background, border, accent bar and icon; matching the body copy
exactly made it read flat, and full foreground read as shouting.

Fumadocs puts `text-fd-muted-foreground` directly on the description div, so
inheritance can't reach it — this has to select the element. `data-callout`
is ours (see mdx-components.tsx); `prose-no-margin` is what Fumadocs marks
the description's prose block with. Unlayered for the same reason as the
rule above: the utility class it overrides lives in `@layer utilities`. */
[data-callout] .prose-no-margin {
color: color-mix(in oklab, var(--color-fd-foreground) 90%, transparent);
}

/* ── Fumadocs component overrides ── */

@layer components {
Expand Down
2 changes: 1 addition & 1 deletion src/app/stack/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default async function Page(props: PageProps<"/stack/[[...slug]]">) {
return (
<DocsPage toc={page.data.toc} full={page.data.full}>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription className="mb-0">
<DocsDescription className="mb-0 text-fd-foreground">
{page.data.description}
</DocsDescription>
<div className="flex flex-row gap-2 items-center border-b pb-6">
Expand Down
31 changes: 30 additions & 1 deletion src/mdx-components.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,42 @@
import { Callout } from "fumadocs-ui/components/callout";
import { Callout as FumaCallout } from "fumadocs-ui/components/callout";
import { Step, Steps } from "fumadocs-ui/components/steps";
import defaultMdxComponents from "fumadocs-ui/mdx";
import type { MDXComponents } from "mdx/types";
import type { ComponentProps } from "react";
import { BadExample } from "@/components/bad-example";
import { TrackedCodeBlock } from "@/components/code-block";
import { EqlFn } from "@/components/eql-fn";
import { EqlVersion } from "@/components/eql-version";
import { ZeroKmsRegions } from "@/components/zerokms-regions";

/**
* Callouts keep Fumadocs' own body colour — `text-fd-muted-foreground`, the
* same token the sidebar's resting nav items use — so they sit at the same
* weight as the rest of the chrome rather than shouting. This wrapper only:
*
* - doubles the padding, `p-3 ps-1` → `p-6 ps-2`. `ps` stays proportionally
* small because the accent bar is the container's first child and sits
* near the edge;
* - adds a `data-callout` attribute, which Fumadocs does not emit. global.css
* has had a `[data-callout]` rule since the theme work that consequently
* matched nothing.
*
* Fumadocs' `Callout` still resolves the `warn`/`tip` aliases, picks the icon
* and renders the title, and it spreads unknown props onto the container, so
* there is nothing here to reimplement.
*/
function Callout({ className, ...props }: ComponentProps<typeof FumaCallout>) {
// CalloutContainer runs its own `cn`, so these merge against its defaults;
// a caller's className comes last and still wins.
return (
<FumaCallout
data-callout
className={`p-6 ps-4 ${className ?? ""}`}
{...props}
/>
);
}

export function getMDXComponents(components?: MDXComponents): MDXComponents {
return {
...defaultMdxComponents,
Expand Down