From 5c38b0ae33ee31a3b8b57a23613da72e6da2a5ad Mon Sep 17 00:00:00 2001
From: saifmohamedsv
Date: Sun, 30 Aug 2026 13:30:33 +0300
Subject: [PATCH 1/3] =?UTF-8?q?feat(docs):=20AI-friendly=20docs=20?=
=?UTF-8?q?=E2=80=94=20llms.txt,=20llms-full.txt,=20Copy-for-AI?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Make the docs site machine/LLM-friendly, all generated from the hook
registry so nothing can drift:
- app/llms.txt — concise llmstxt.org index (H1 + summary + install +
key pages + every hook as a link with one-liner)
- app/llms-full.txt — whole-library dump via the shared Markdown renderer
- app/docs/[slug]/llms.txt — per-hook Markdown twin of each hook page
- lib/hook-markdown.ts — THE single hook→Markdown renderer (registry +
hook-docs + hook-sources), reused by all three surfaces + the button
- lib/llms.ts — index/full builders
- components/hook-ai-actions.tsx — "Copy for AI" (reuses CopyButton) +
View as Markdown + Open in ChatGPT/Claude, wired into hook-page.tsx
- copy-button.tsx — optional labeled pill variant (backward compatible)
- robots.ts / sitemap.ts / layout.tsx — advertise the llms files
- docs index — "Copy all hooks for AI" affordance
Gate green (lint + typecheck + build). Derives from HOOKS; no hardcoded
list or count.
Co-Authored-By: Claude Opus 4.8
Claude-Session: https://claude.ai/code/session_011u9hmtMzmEShNGeBvGXYGL
---
apps/docs/app/docs/[slug]/llms.txt/route.ts | 31 +++++++++
apps/docs/app/docs/page.tsx | 34 ++++++++++
apps/docs/app/layout.tsx | 9 +++
apps/docs/app/llms-full.txt/route.ts | 14 ++++
apps/docs/app/llms.txt/route.ts | 14 ++++
apps/docs/app/robots.ts | 4 +-
apps/docs/app/sitemap.ts | 12 ++++
apps/docs/components/copy-button.tsx | 25 +++++++
apps/docs/components/hook-ai-actions.tsx | 59 ++++++++++++++++
apps/docs/components/hook-page.tsx | 11 ++-
apps/docs/lib/hook-markdown.ts | 75 +++++++++++++++++++++
apps/docs/lib/llms.ts | 52 ++++++++++++++
12 files changed, 336 insertions(+), 4 deletions(-)
create mode 100644 apps/docs/app/docs/[slug]/llms.txt/route.ts
create mode 100644 apps/docs/app/llms-full.txt/route.ts
create mode 100644 apps/docs/app/llms.txt/route.ts
create mode 100644 apps/docs/components/hook-ai-actions.tsx
create mode 100644 apps/docs/lib/hook-markdown.ts
create mode 100644 apps/docs/lib/llms.ts
diff --git a/apps/docs/app/docs/[slug]/llms.txt/route.ts b/apps/docs/app/docs/[slug]/llms.txt/route.ts
new file mode 100644
index 0000000..fc019e2
--- /dev/null
+++ b/apps/docs/app/docs/[slug]/llms.txt/route.ts
@@ -0,0 +1,31 @@
+import { hookToMarkdown } from "@/lib/hook-markdown";
+import { HOOKS, getHook } from "@/lib/hooks-registry";
+
+/* /docs//llms.txt — the machine-readable twin of every hook page: that
+ one hook rendered through the shared Markdown renderer. Prerendered for every
+ hook alongside its HTML page. */
+export function generateStaticParams() {
+ return HOOKS.map(({ slug }) => ({ slug }));
+}
+
+export async function GET(
+ _request: Request,
+ { params }: { params: Promise<{ slug: string }> },
+): Promise {
+ const { slug } = await params;
+ const hook = getHook(slug);
+
+ if (!hook) {
+ return new Response("Not found\n", {
+ status: 404,
+ headers: { "Content-Type": "text/plain; charset=utf-8" },
+ });
+ }
+
+ return new Response(`${hookToMarkdown(hook)}\n`, {
+ headers: {
+ "Content-Type": "text/plain; charset=utf-8",
+ "Cache-Control": "public, max-age=0, must-revalidate",
+ },
+ });
+}
diff --git a/apps/docs/app/docs/page.tsx b/apps/docs/app/docs/page.tsx
index 16b5458..3d2c79c 100644
--- a/apps/docs/app/docs/page.tsx
+++ b/apps/docs/app/docs/page.tsx
@@ -1,6 +1,7 @@
import type { Metadata } from "next";
import { CodeBlock } from "@/components/code-block";
import { HookCard } from "@/components/hook-card";
+import { ArrowRightIcon } from "@/components/icons";
import { InstallCommand } from "@/components/install-command";
import {
CATEGORY_LABELS,
@@ -46,6 +47,39 @@ export default function DocsIndexPage() {
can try it before you install it.
+
+
+
Building with an LLM?
+
+ Every hook — signatures, usage and source — as plain Markdown for AI
+ assistants and coding agents, generated from this site so it never
+ drifts.
+
+
+
+
+
Quick start
diff --git a/apps/docs/app/layout.tsx b/apps/docs/app/layout.tsx
index 797a71d..be2216c 100644
--- a/apps/docs/app/layout.tsx
+++ b/apps/docs/app/layout.tsx
@@ -27,6 +27,15 @@ export const metadata: Metadata = {
default: "hookli — simple React hooks",
},
description: TAGLINE,
+ alternates: {
+ // Advertise the machine-readable llmstxt.org representations of the site.
+ types: {
+ "text/plain": [
+ { url: "/llms.txt", title: "hookli llms.txt" },
+ { url: "/llms-full.txt", title: "hookli llms-full.txt" },
+ ],
+ },
+ },
openGraph: {
type: "website",
siteName: "hookli",
diff --git a/apps/docs/app/llms-full.txt/route.ts b/apps/docs/app/llms-full.txt/route.ts
new file mode 100644
index 0000000..f90b4d2
--- /dev/null
+++ b/apps/docs/app/llms-full.txt/route.ts
@@ -0,0 +1,14 @@
+import { buildLlmsFull } from "@/lib/llms";
+
+/* /llms-full.txt — the whole library in one Markdown document (every hook via
+ the shared renderer). No request input, so it is prerendered at build time. */
+export const dynamic = "force-static";
+
+export function GET(): Response {
+ return new Response(buildLlmsFull(), {
+ headers: {
+ "Content-Type": "text/plain; charset=utf-8",
+ "Cache-Control": "public, max-age=0, must-revalidate",
+ },
+ });
+}
diff --git a/apps/docs/app/llms.txt/route.ts b/apps/docs/app/llms.txt/route.ts
new file mode 100644
index 0000000..e8c126a
--- /dev/null
+++ b/apps/docs/app/llms.txt/route.ts
@@ -0,0 +1,14 @@
+import { buildLlmsIndex } from "@/lib/llms";
+
+/* /llms.txt — the concise, llmstxt.org-standard index. No request input, so it
+ is prerendered to a static file at build time. */
+export const dynamic = "force-static";
+
+export function GET(): Response {
+ return new Response(buildLlmsIndex(), {
+ headers: {
+ "Content-Type": "text/plain; charset=utf-8",
+ "Cache-Control": "public, max-age=0, must-revalidate",
+ },
+ });
+}
diff --git a/apps/docs/app/robots.ts b/apps/docs/app/robots.ts
index 77a1b9b..31e4bd3 100644
--- a/apps/docs/app/robots.ts
+++ b/apps/docs/app/robots.ts
@@ -3,7 +3,9 @@ import { SITE_URL } from "@/lib/site";
export default function robots(): MetadataRoute.Robots {
return {
- rules: { userAgent: "*", allow: "/" },
+ // The llms.txt files are explicitly surfaced (already covered by "/", but
+ // listing them advertises the AI-friendly index and full dump to crawlers).
+ rules: { userAgent: "*", allow: ["/", "/llms.txt", "/llms-full.txt"] },
sitemap: `${SITE_URL}/sitemap.xml`,
};
}
diff --git a/apps/docs/app/sitemap.ts b/apps/docs/app/sitemap.ts
index c64f69f..3af12d8 100644
--- a/apps/docs/app/sitemap.ts
+++ b/apps/docs/app/sitemap.ts
@@ -24,5 +24,17 @@ export default function sitemap(): MetadataRoute.Sitemap {
changeFrequency: "yearly",
priority: 0.4,
},
+ {
+ url: `${SITE_URL}/llms.txt`,
+ lastModified,
+ changeFrequency: "monthly",
+ priority: 0.3,
+ },
+ {
+ url: `${SITE_URL}/llms-full.txt`,
+ lastModified,
+ changeFrequency: "monthly",
+ priority: 0.3,
+ },
];
}
diff --git a/apps/docs/components/copy-button.tsx b/apps/docs/components/copy-button.tsx
index 38ad1ea..6edf5e4 100644
--- a/apps/docs/components/copy-button.tsx
+++ b/apps/docs/components/copy-button.tsx
@@ -6,10 +6,14 @@ import { CheckIcon, CopyIcon } from "@/components/icons";
export function CopyButton({
text,
label = "Copy to clipboard",
+ copyLabel,
className = "",
}: {
text: string;
label?: string;
+ /* When set, renders the labeled pill variant with this visible text (e.g.
+ "Copy for AI") instead of the default icon-only square. */
+ copyLabel?: string;
className?: string;
}) {
const [copied, setCopied] = useState(false);
@@ -32,6 +36,27 @@ export function CopyButton({
timeoutRef.current = setTimeout(() => setCopied(false), 2000);
}
+ if (copyLabel !== undefined) {
+ return (
+
+ {copied ? (
+
+ ) : (
+
+ )}
+ {copied ? "Copied" : copyLabel}
+
+ {copied ? "Copied to clipboard" : ""}
+
+
+ );
+ }
+
return (
/llms.txt twin). Server component: the Markdown is built
+ at render time and handed to the client CopyButton leaf as a string. */
+
+const linkClass =
+ "inline-flex min-h-11 items-center gap-1 rounded-md text-accent underline-offset-4 transition-colors duration-200 hover:text-accent-hover hover:underline";
+
+export function HookAiActions({ hook }: { hook: HookEntry }) {
+ const markdown = hookToMarkdown(hook);
+ const docUrl = hookDocUrl(hook.slug);
+ const prompt = `I'm using the ${hook.name} React hook from the hookli library. Explain what it does and show me how to use it. Reference: ${docUrl}`;
+ const chatgptUrl = `https://chatgpt.com/?q=${encodeURIComponent(prompt)}`;
+ const claudeUrl = `https://claude.ai/new?q=${encodeURIComponent(prompt)}`;
+
+ return (
+
+ );
+}
diff --git a/apps/docs/components/hook-page.tsx b/apps/docs/components/hook-page.tsx
index bab43d3..326d5ba 100644
--- a/apps/docs/components/hook-page.tsx
+++ b/apps/docs/components/hook-page.tsx
@@ -1,6 +1,7 @@
import Link from "next/link";
import { ApiTable } from "@/components/api-table";
import { CodeBlock, HighlightedCode } from "@/components/code-block";
+import { HookAiActions } from "@/components/hook-ai-actions";
import { HookCard } from "@/components/hook-card";
import { HookDemo } from "@/components/hook-demo";
import { ArrowRightIcon, ExternalLinkIcon } from "@/components/icons";
@@ -47,9 +48,13 @@ export function HookPage({ hook }: { hook: HookEntry }) {
return (
- {CATEGORY_LABELS[hook.category]}
- {hook.name}
- {linkifyWebApis(hook.description)}
+
+
+
{doc && (
<>
diff --git a/apps/docs/lib/hook-markdown.ts b/apps/docs/lib/hook-markdown.ts
new file mode 100644
index 0000000..bc47fac
--- /dev/null
+++ b/apps/docs/lib/hook-markdown.ts
@@ -0,0 +1,75 @@
+import type { ApiRow } from "@/components/api-table";
+import { getHookDoc } from "@/lib/hook-docs";
+import { getHookSource } from "@/lib/hook-sources";
+import { CATEGORY_LABELS, type HookEntry } from "@/lib/hooks-registry";
+import { SITE_URL } from "@/lib/site";
+
+/* THE single hook → Markdown renderer. Everything AI-facing goes through here:
+ the per-hook /docs/[slug]/llms.txt route, the whole-library llms-full.txt,
+ and the "Copy for AI" button all render a hook with THIS function — there is
+ exactly one Markdown renderer in the codebase. Data is pulled from the same
+ registry + hook-docs + hook-sources helpers the human pages use, so the
+ Markdown can never drift from what the site shows. */
+
+/* The canonical docs URL for a hook — the same link the Markdown advertises. */
+export function hookDocUrl(slug: string): string {
+ return `${SITE_URL}/docs/${slug}`;
+}
+
+/* Parameters / Returns / type-alias rows → a Markdown bullet list. Mirrors the
+ ApiTable columns (name · type · default · description) in a form an LLM reads
+ cleanly. */
+function rowsToMarkdown(rows: readonly ApiRow[]): string {
+ return rows
+ .map((row) => {
+ const def = row.defaultValue ? ` (default: \`${row.defaultValue}\`)` : "";
+ return `- \`${row.name}\`: \`${row.type}\`${def} — ${row.description}`;
+ })
+ .join("\n");
+}
+
+export function hookToMarkdown(hook: HookEntry): string {
+ const doc = getHookDoc(hook.slug);
+ const source = getHookSource(hook.slug);
+
+ const sections: string[] = [
+ `# ${hook.name}`,
+ `> ${hook.description}`,
+ [
+ `- Category: ${CATEGORY_LABELS[hook.category]}`,
+ `- Package: \`hookli\` (install with \`npm i hookli\`)`,
+ `- Docs: ${hookDocUrl(hook.slug)}`,
+ ].join("\n"),
+ `## Signature\n\n\`\`\`ts\n${hook.signature}\n\`\`\``,
+ ];
+
+ if (doc && doc.parameters.length > 0) {
+ sections.push(`## Parameters\n\n${rowsToMarkdown(doc.parameters)}`);
+ }
+
+ if (doc && doc.returns.length > 0) {
+ sections.push(`## Returns\n\n${rowsToMarkdown(doc.returns)}`);
+ }
+
+ if (doc?.typeAliases?.length) {
+ const aliases = doc.typeAliases
+ .map((alias) => {
+ const description = alias.description ? `${alias.description}\n\n` : "";
+ return `### ${alias.name}\n\n${description}${rowsToMarkdown(alias.rows)}`;
+ })
+ .join("\n\n");
+ sections.push(`## Types\n\n${aliases}`);
+ }
+
+ if (doc?.usage) {
+ sections.push(`## Usage\n\n\`\`\`tsx\n${doc.usage.trim()}\n\`\`\``);
+ }
+
+ if (source) {
+ sections.push(
+ `## Source\n\n\`${source.path}\`\n\n\`\`\`ts\n${source.source.trim()}\n\`\`\``,
+ );
+ }
+
+ return sections.join("\n\n");
+}
diff --git a/apps/docs/lib/llms.ts b/apps/docs/lib/llms.ts
new file mode 100644
index 0000000..b9bf50d
--- /dev/null
+++ b/apps/docs/lib/llms.ts
@@ -0,0 +1,52 @@
+import { hookDocUrl, hookToMarkdown } from "@/lib/hook-markdown";
+import { HOOKS } from "@/lib/hooks-registry";
+import { GITHUB_URL, NPM_URL, SITE_URL, TAGLINE } from "@/lib/site";
+
+/* Builders for the two llmstxt.org files (/llms.txt + /llms-full.txt), derived
+ entirely from the registry so the hook list, count and descriptions can never
+ drift. Kept out of the route handlers so the whole-library dump can also feed
+ the "Copy all hooks for AI" affordance on the docs index — one builder, one
+ source of truth. */
+
+const SUMMARY = `hookli is a zero-dependency, fully-typed, SSR-safe React hooks library — ${HOOKS.length} hooks for state, effects, the DOM and data.`;
+
+/* /llms.txt — the concise index (llmstxt.org format): H1, blockquote summary,
+ install line, a link list of key pages, then every hook as a link + one-liner. */
+export function buildLlmsIndex(): string {
+ const keyPages = [
+ `- [hookli home](${SITE_URL}): ${TAGLINE}`,
+ `- [Documentation](${SITE_URL}/docs): Live docs for all ${HOOKS.length} hooks.`,
+ `- [Full text for LLMs](${SITE_URL}/llms-full.txt): Every hook's signature, usage and source in one file.`,
+ `- [npm](${NPM_URL}): The published package.`,
+ `- [GitHub](${GITHUB_URL}): Source, issues and contributions.`,
+ ].join("\n");
+
+ const hooks = HOOKS.map(
+ (hook) => `- [${hook.name}](${hookDocUrl(hook.slug)}): ${hook.description}`,
+ ).join("\n");
+
+ return [
+ "# hookli",
+ `> ${SUMMARY}`,
+ "Install with `npm i hookli`. Every hook is typed, tree-shakeable and works with React Server Components.",
+ "## Docs",
+ keyPages,
+ "## Hooks",
+ hooks,
+ "",
+ ].join("\n\n");
+}
+
+/* /llms-full.txt — the full-context dump: the same header, then every hook
+ rendered through the shared Markdown renderer, separated by rules. */
+export function buildLlmsFull(): string {
+ const header = [
+ "# hookli — full documentation for LLMs",
+ `> ${SUMMARY}`,
+ "Install with `npm i hookli`. This file contains every hook's name, description, signature, parameters, returns, usage and source — the complete reference in one document.",
+ ].join("\n\n");
+
+ const body = HOOKS.map((hook) => hookToMarkdown(hook)).join("\n\n---\n\n");
+
+ return `${header}\n\n---\n\n${body}\n`;
+}
From 0bcc05d263555d7d65da99f16ddd60e0ea5cc0a0 Mon Sep 17 00:00:00 2001
From: saifmohamedsv
Date: Sun, 30 Aug 2026 15:01:55 +0300
Subject: [PATCH 2/3] feat(docs): add AI-ready landing section
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Surface the AI-friendly features on the home page (they only lived on
the docs pages before). New AiSection after Live Proof:
- "Bring your AI — it speaks hookli" heading
- 3 cards: llms.txt/llms-full.txt, per-hook Copy-for-AI, Open in
ChatGPT/Claude
- action row: Copy llms.txt (reuses CopyButton), View /llms.txt,
Open in ChatGPT / Claude (prefilled prompt + llms-full.txt link)
Reuses SectionHeading + surface cards + existing icons; hook count
from HOOKS. Wired into app/page.tsx. Gate green.
Co-Authored-By: Claude Opus 4.8
Claude-Session: https://claude.ai/code/session_011u9hmtMzmEShNGeBvGXYGL
---
apps/docs/app/page.tsx | 2 +
apps/docs/components/ai-section.tsx | 116 ++++++++++++++++++++++++++++
2 files changed, 118 insertions(+)
create mode 100644 apps/docs/components/ai-section.tsx
diff --git a/apps/docs/app/page.tsx b/apps/docs/app/page.tsx
index 2a4da5e..2153b14 100644
--- a/apps/docs/app/page.tsx
+++ b/apps/docs/app/page.tsx
@@ -5,6 +5,7 @@ import { ArrowRightIcon, GitHubIcon } from "@/components/icons";
import { ComparisonSection } from "@/components/comparison-section";
import { FeaturesSection } from "@/components/features-section";
import { LiveProofSection } from "@/components/live-proof-section";
+import { AiSection } from "@/components/ai-section";
import { HooksIndexSection } from "@/components/hooks-index-section";
import { SupportSection } from "@/components/support-section";
import { BottomCtaSection } from "@/components/bottom-cta-section";
@@ -66,6 +67,7 @@ export default function Home() {
+
diff --git a/apps/docs/components/ai-section.tsx b/apps/docs/components/ai-section.tsx
new file mode 100644
index 0000000..0dc818b
--- /dev/null
+++ b/apps/docs/components/ai-section.tsx
@@ -0,0 +1,116 @@
+import { CopyButton } from "@/components/copy-button";
+import { SectionHeading } from "@/components/section-heading";
+import { BracesIcon, CopyIcon, ExternalLinkIcon } from "@/components/icons";
+import { buildLlmsIndex } from "@/lib/llms";
+import { HOOKS } from "@/lib/hooks-registry";
+import { SITE_URL } from "@/lib/site";
+
+/* Landing section that surfaces the AI-friendly surfaces (llms.txt, per-hook
+ Copy-for-AI, Open-in-ChatGPT/Claude) so visitors know the docs are built to
+ be read by a model, not just a human. Server component: the /llms.txt body
+ is built once from the registry and handed to the client CopyButton leaf. */
+
+const CARDS = [
+ {
+ Icon: BracesIcon,
+ title: "One file, the whole library",
+ body: (
+ <>
+ Point any model at{" "}
+ /llms.txt for the map, or{" "}
+ /llms-full.txt for every signature,
+ usage and source — generated from the same registry the docs use.
+ >
+ ),
+ },
+ {
+ Icon: CopyIcon,
+ title: "Copy any hook for AI",
+ body: (
+ <>
+ Every hook page has a one-click Copy for AI —
+ clean Markdown, ready to paste into your chat and start building.
+ >
+ ),
+ },
+ {
+ Icon: ExternalLinkIcon,
+ title: "Straight into your chat",
+ body: (
+ <>
+ Jump into ChatGPT or Claude prefilled with the hook's context and a
+ live docs link. Your AI pair is in the loop from line one.
+ >
+ ),
+ },
+];
+
+export function AiSection() {
+ const llmsIndex = buildLlmsIndex();
+ const prompt = `I'm using hookli, a zero-dependency, typed, SSR-safe React hooks library (${HOOKS.length} hooks). Full reference: ${SITE_URL}/llms-full.txt — help me pick and use the right hooks for my app.`;
+ const chatgptUrl = `https://chatgpt.com/?q=${encodeURIComponent(prompt)}`;
+ const claudeUrl = `https://claude.ai/new?q=${encodeURIComponent(prompt)}`;
+ const linkClass =
+ "inline-flex min-h-11 items-center gap-1.5 text-sm text-gray-body underline-offset-4 transition-colors duration-200 hover:text-fg hover:underline";
+
+ return (
+
+
+ Vibe-coding with an LLM? hookli ships a machine-readable map of all{" "}
+ {HOOKS.length} hooks, so your assistant recommends and wires them up
+ correctly — no stale copy-paste.
+ >
+ }
+ />
+
+
+ {CARDS.map(({ Icon, title, body }) => (
+
+
+
+
+
{title}
+
{body}
+
+ ))}
+
+
+
+
+ );
+}
From 39d7ec97034e70b87eb1eee60f5d4fec83bf97de Mon Sep 17 00:00:00 2001
From: saifmohamedsv
Date: Sun, 30 Aug 2026 15:09:52 +0300
Subject: [PATCH 3/3] feat(docs): hero trigger that scrolls to the AI section
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add an accent announcement pill in the hero ("New — hookli speaks AI"
with a down arrow) linking to #ai, and give AiSection id="ai" +
scroll-mt-24. Enable smooth in-page scrolling (html scroll-behavior),
still auto under prefers-reduced-motion. Gate green.
Co-Authored-By: Claude Opus 4.8
Claude-Session: https://claude.ai/code/session_011u9hmtMzmEShNGeBvGXYGL
---
apps/docs/app/globals.css | 6 ++++++
apps/docs/app/page.tsx | 10 +++++++++-
apps/docs/components/ai-section.tsx | 2 +-
3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/apps/docs/app/globals.css b/apps/docs/app/globals.css
index 906904a..ff12fd9 100644
--- a/apps/docs/app/globals.css
+++ b/apps/docs/app/globals.css
@@ -266,6 +266,12 @@ body {
animation: donate-bob 3.5s ease-in-out infinite;
}
+/* Smooth in-page anchor scrolling (e.g. the hero → #ai trigger). The
+ reduced-motion block below forces this back to `auto` when requested. */
+html {
+ scroll-behavior: smooth;
+}
+
@media (prefers-reduced-motion: reduce) {
*,
*::before,
diff --git a/apps/docs/app/page.tsx b/apps/docs/app/page.tsx
index 2153b14..edbb0b5 100644
--- a/apps/docs/app/page.tsx
+++ b/apps/docs/app/page.tsx
@@ -26,7 +26,15 @@ export default function Home() {
-
+
+
+ New — hookli speaks AI
+
+
+
{TAGLINE_SHORT}
diff --git a/apps/docs/components/ai-section.tsx b/apps/docs/components/ai-section.tsx
index 0dc818b..f92d534 100644
--- a/apps/docs/components/ai-section.tsx
+++ b/apps/docs/components/ai-section.tsx
@@ -54,7 +54,7 @@ export function AiSection() {
"inline-flex min-h-11 items-center gap-1.5 text-sm text-gray-body underline-offset-4 transition-colors duration-200 hover:text-fg hover:underline";
return (
-