## Theming with DaisyUI

dioxus-docs-kit uses **Tailwind CSS 4** and **DaisyUI 5** for styling. The default theme is `dark`, but you can configure light/dark toggle via `DocsConfig`:

```rust
DocsConfig::new(nav_json, content_map)
    .with_theme_toggle("light", "dark", "dark") // (light theme, dark theme, default)
    .build()
```

DaisyUI themes control all component colors automatically. To use a different built-in theme (e.g. `cupcake`, `dracula`), just change the theme names passed to `with_theme_toggle`.

> **Tip:** See the full list of built-in DaisyUI themes at [daisyui.com/docs/themes](https://daisyui.com/docs/themes/).

## Density Variants

`DocsLayout` accepts a `variant` prop with two built-in density presets:

```rust
use dioxus_docs_kit::{DocsLayout, DocsVariant};

DocsLayout { variant: DocsVariant::Reference, Outlet::<Route> {} }
```

| Variant | Feel | `--dk-article-width` |
|---------|------|----------------------|
| `Prose` (default) | Wide margins, serif-friendly, long-form reading | `72ch` |
| `Reference` | Tighter column, smaller type, denser headings | `64ch` |

The variant emits a class on `dk-root` (`dk-variant-prose` / `dk-variant-reference`) so you can layer further CSS tweaks per variant.

## CSS Token Surface

Visual identity lives in a flat set of `--dk-*` custom properties on `dk-root`. Override any subset to retheme without touching DaisyUI — useful when you need a brand look that DaisyUI's palette doesn't cover:

```css
.dk-root {
  --dk-article-width: 68ch;
  --dk-font-heading: "Inter Tight", system-ui, sans-serif;
  --dk-accent: oklch(0.65 0.20 250);
  --dk-radius: 0.25rem;
}
```

### Pre-built theme presets

The crate ships drop-in presets in `crates/dioxus-docs-kit/examples/themes/`:

- `warm-editorial.css` — amber accent, serif headings, cream surfaces
- `brutalist-light.css` — high contrast, zero radius, monospace
- `shadcn-light.css` / `shadcn-dark.css` — shadcn-style neutrals
- `default.css` — baseline (nothing overridden)

Copy any of them into your `assets/` and import via `document::Stylesheet`. See `crates/dioxus-docs-kit/THEMING.md` for the full token reference.

## SEO Meta

Auto meta is on by default. The kit emits `<title>`, `<meta name="description">`, OpenGraph, and Twitter Card tags from each page's frontmatter:

```rust
let docs_ctx = DocsContext::new(current_path, "/docs", navigate)
    .with_site_url("https://your-site.com");
```

- Title and description tags emit unconditionally while auto meta is on.
- Canonical URLs (`<link rel="canonical">`) and `og:url` only emit when a site URL is set via `.with_site_url()`.
- Call `.with_auto_meta(false)` if your app already manages `<head>` (custom OG images, JSON-LD, etc.) and you want to avoid duplicate tags.

## Sitemaps, robots.txt & llms.txt

Enable the `server` feature and mount `SeoRouter` — it generates all crawler-facing routes: per-page raw Markdown (`<page>.md`), `llms.txt` / `llms-full.txt`, per-surface sitemaps plus a `sitemap.xml` index, blog RSS, and a robots.txt with explicit AI-crawler entries.

Do **not** serve these as `#[get(...)]` server functions — a server function JSON-encodes its `String` return value (quoted body, `application/json` content type), which crawlers can't parse. `SeoRouter` registers plain Axum routes with the correct content types:

```rust
use dioxus_docs_kit::server::SeoRouter;

dioxus::server::serve(|| async {
    let seo = SeoRouter::new("https://your-site.com", "My Docs", "Documentation for My Product")
        .with_docs(&DOCS, "/docs")
        .with_blog(&BLOG, "/blog") // optional
        .into_router();
    Ok(dioxus::server::router(App).merge(seo))
});
```

In your app's `Cargo.toml`, forward the feature: `server = ["dioxus/server", "dioxus-docs-kit/server"]`. See `src/main.rs` in the example for the full pattern.

## Configuring Navigation

Navigation is defined in `docs/_nav.json`. The structure supports **tabs**, **groups**, and **pages**:

```json
{
  "tabs": ["Docs", "Guides", "API Reference"],
  "groups": [
    {
      "group": "Getting Started",
      "tab": "Docs",
      "pages": ["getting-started/introduction", "getting-started/quickstart"]
    },
    {
      "group": "Guides",
      "tab": "Guides",
      "pages": ["guides/basic-usage", "guides/customization"]
    }
  ]
}
```

- **tabs** — Top-level navigation tabs shown in the docs header
- **groups** — Sidebar sections, each assigned to a tab
- **pages** — Paths relative to the `docs/` directory (without `.mdx` extension)

> **Note:** Each page path must correspond to a `.mdx` file in the `docs/` directory. The `build.rs` script reads `_nav.json` to generate `include_str!()` calls at compile time.

### Adding a New Page

1. **Create the MDX file**
Create `docs/my-section/my-page.mdx` with frontmatter:

```mdx
---
title: My Page
description: A brief description
sidebarTitle: My Page
icon: file-text
---

Your content here.
```

2. **Add to _nav.json**
Add `"my-section/my-page"` to the appropriate group's `pages` array.

3. **Rebuild**
Run `dx serve` — the build script re-generates the content map automatically.

## Adding OpenAPI Specs

dioxus-docs-kit can render interactive API reference pages from OpenAPI 3.x YAML specs. Each endpoint gets its own page with a Mintlify-style two-column layout.

```rust
static DOCS: LazyLock<DocsRegistry> = LazyLock::new(|| {
    DocsConfig::new(nav_json, content_map)
        .with_openapi(
            "api-reference",
            include_str!("../docs/api-reference/petstore.yaml"),
        )
        .build()
});
```

- The first argument (`"api-reference"`) is the URL prefix for API pages
- The second argument is the OpenAPI YAML content
- Endpoint slugs are derived from `operationId` values (camelCase → kebab-case)
- Sidebar entries are generated automatically, grouped by tag

> **Note:** You also need an `api-reference/overview` page in `_nav.json`. The individual endpoint pages are generated dynamically from the spec.

## Styling Prose Content

Documentation content is rendered inside Tailwind's `prose` class via the `@tailwindcss/typography` plugin. You can customize prose styles in your `tailwind.css`:

```css
@import "tailwindcss";
@plugin "@tailwindcss/typography";
@plugin "daisyui";

/* Custom prose overrides */
.prose {
  --tw-prose-body: oklch(0.85 0 0);
  --tw-prose-headings: oklch(0.95 0 0);
}
```

### MDX Components

All content pages support Mintlify-style MDX components out of the box:

**Callouts**
Tip, Note, Warning, and Info callout boxes

**Cards & Card Groups**
Linked card grids with icons

**Steps**
Numbered step-by-step instructions

**Code Groups**
Tabbed code blocks with syntax highlighting

See the [Basic Usage](/docs/guides/basic-usage) guide for a full component reference.

