Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
b9a04ee
Upgrade all dependencies to latest on v2
radiumcoders Sep 26, 2026
f770a1d
Redesign docs layout, sidebar, and content blocks
radiumcoders Sep 26, 2026
fefb523
Rebuild MoviePassButton as a tearing ticket
radiumcoders Sep 26, 2026
2a64eb1
Restyle DoubtButton and HoldButton with neutral theme tokens
radiumcoders Sep 26, 2026
9bfa62d
Rebuild DemonicButton as a hold-to-summon ritual
radiumcoders Sep 26, 2026
4d7f154
Rebuild StickyButton with a wider field and parallax label
radiumcoders Sep 26, 2026
f46c8fa
Rebuild TrollButton to dodge until it tires out
radiumcoders Sep 26, 2026
3368eed
Rebuild HighlightButton with a lit border and click ripples
radiumcoders Sep 26, 2026
4285fbe
Rebuild ClickPowerUp as a themed, bracketed power-up button
radiumcoders Sep 26, 2026
a4764ae
Rebuild FrameButton with springy lock-on corner markers
radiumcoders Sep 26, 2026
a8fbedf
Fix ClickPowerUp animation glitches
radiumcoders Sep 26, 2026
857d81e
Add a click glint to ShinyButton
radiumcoders Sep 26, 2026
31f547c
Redesign CommandButton around live keycaps
radiumcoders Sep 26, 2026
4e3a1e8
Redesign CopyButton to float the copied text off the button
radiumcoders Sep 26, 2026
a51a7d0
Restyle CommandButton and CopyButton to match the house style
radiumcoders Sep 26, 2026
43fdabc
Add a subtle depth shadow to the neutral buttons
radiumcoders Sep 26, 2026
d174a17
Restyle MinimalButton as a ringed dark surface with a chevron
radiumcoders Sep 26, 2026
7e5d40f
Give CommandButton and CopyButton the ringed dark surface
radiumcoders Sep 26, 2026
efae5bb
Smooth the press animation on the ringed dark buttons
radiumcoders Sep 26, 2026
2bc96b2
Play CommandButton's press animation when the shortcut fires
radiumcoders Sep 26, 2026
f451d4e
Sync CommandButton key hints with the button press
radiumcoders Sep 26, 2026
5805ccc
Restyle ConfettiButton and AshBurstButton as ringed dark surfaces
radiumcoders Sep 26, 2026
69a5782
Restyle CaptchaButton as a ringed dark surface with a dark panel
radiumcoders Sep 26, 2026
843b74c
Swap CaptchaButton's emoji tiles for inline line icons
radiumcoders Sep 26, 2026
57266f2
Remove CaptchaButton and DontPressButton
radiumcoders Sep 26, 2026
e8cd370
Give DemonicButton the ringed dark surface and spring press
radiumcoders Sep 26, 2026
e4272dc
Give TrollButton the ringed dark surface and spring press
radiumcoders Sep 26, 2026
0a32370
Give GlitchButton the ringed dark surface and spring press
radiumcoders Sep 26, 2026
174027b
Give HighlightButton the ringed dark surface and spring press
radiumcoders Sep 26, 2026
9bda1fe
Give FrameButton the ringed dark surface and spring press
radiumcoders Sep 26, 2026
1463590
Animate MinimalButton's press on the scale property
radiumcoders Sep 26, 2026
b6b6835
Animate CommandButton's press on the scale property
radiumcoders Sep 26, 2026
04ae1a6
Animate CopyButton's press on the scale property
radiumcoders Sep 26, 2026
eb8dca8
Animate ConfettiButton's press on the scale property
radiumcoders Sep 26, 2026
ed9503c
Animate AshBurstButton's press on the scale property
radiumcoders Sep 26, 2026
c21c4f7
Give MoviePassButton the ringed dark surface and spring press
radiumcoders Sep 26, 2026
b87c21f
Fix the dashed rim on ThreeDButton's face
radiumcoders Sep 26, 2026
803c974
Remove GridButton
radiumcoders Sep 26, 2026
e075ca0
Drop the unused @dotmatrix and @ncdai registries
radiumcoders Sep 26, 2026
55840ff
Rework SlideToDetonate with resistance and smoothness controls
radiumcoders Sep 26, 2026
d1c69cd
Make SlideToDetonate's trail and armed glow monochrome
radiumcoders Sep 26, 2026
e117fa2
Center SlideToDetonate's success label and add a light variant
radiumcoders Sep 26, 2026
f6c4170
Drop SlideToDetonate's success label
radiumcoders Sep 26, 2026
85da698
Replace the playground with live prop controls under each docs preview
radiumcoders Sep 26, 2026
2e66225
Give the docs' inline DialKit controls rounded, raised styling
radiumcoders Sep 26, 2026
32f320e
Give the inline DialKit select menu a solid surface and lighter options
radiumcoders Sep 26, 2026
7b821b8
Give DoubtButton the layered drop shadow used by the docs controls
radiumcoders Sep 26, 2026
b4670cd
Restyle DoubtButton with MinimalButton's graded dark surface
radiumcoders Sep 26, 2026
d89a52d
Restyle HoldButton with MinimalButton's graded dark surface
radiumcoders Sep 26, 2026
fbb8d2b
Expose every button prop in the docs' live controls
radiumcoders Sep 26, 2026
8015fd2
Add reset and copy-as-prompt actions to the docs' live controls
radiumcoders Sep 26, 2026
13868cd
Clean up the inline DialKit segmented toggle and panel chrome
radiumcoders Sep 26, 2026
998743a
Remove HoldConfirmButton
radiumcoders Sep 26, 2026
c7c0652
Restyle CooldownButton with MinimalButton's graded dark surface
radiumcoders Sep 26, 2026
d862fdb
Restyle MorphStatusButton with MinimalButton's graded dark surface
radiumcoders Sep 26, 2026
be0ac53
Restyle RevealButton with MinimalButton's graded dark surface
radiumcoders Sep 26, 2026
898c07f
Add a light variant to RevealButton
radiumcoders Sep 26, 2026
82ab276
Add an Analytics powered by Tracwell card under the docs page TOC
radiumcoders Sep 26, 2026
6cffba3
Simplify the Tracwell card to a single brand-blue wash
radiumcoders Sep 26, 2026
4edd97e
Reduce the Tracwell card to a plain bordered text link
radiumcoders Sep 26, 2026
504a944
Add Tracwell's logo and a soft blue gradient to its credit link
radiumcoders Sep 26, 2026
857fc53
Tag the Tracwell credit link with UTM parameters
radiumcoders Sep 26, 2026
96489e3
Rebuild the landing page as a navbar, hero, and live button showcase
radiumcoders Sep 26, 2026
50d849c
Replace the landing grid with an auto-rotating three-card carousel
radiumcoders Sep 26, 2026
746e787
Trim the landing carousel to Docs and Copy buttons over a soft glow
radiumcoders Sep 26, 2026
b164988
Fit the landing page to one screen with a five-card carousel
radiumcoders Sep 26, 2026
d40a42d
Add the logo's red as a brand accent across the site
radiumcoders Sep 26, 2026
3985d8a
Float the carousel card's Docs and Copy actions as minimal pills
radiumcoders Sep 26, 2026
4771528
Give the landing page a paper-toned sunset gradient backdrop
radiumcoders Sep 26, 2026
8185891
Build the landing backdrop from theme tokens instead of pastels
radiumcoders Sep 26, 2026
ec6a2c1
Make the carousel card's outer shell opaque with a hairline border
radiumcoders Sep 26, 2026
3977142
Add a minimal landing navbar and swap the trap CTA for GitHub
radiumcoders Sep 26, 2026
6685ab7
Render a brand-red WebGPU dither shader behind the landing page
radiumcoders Sep 27, 2026
60dc32e
Port the landing shader from WebGPU to WebGL2
radiumcoders Sep 27, 2026
9762dbf
Fade the top of the landing shader behind the hero text
radiumcoders Sep 27, 2026
2384728
Keep the side carousel cards opaque over the shader
radiumcoders Sep 27, 2026
e53d48e
Curve the showcase carousel around a perspective cylinder
radiumcoders Sep 27, 2026
7041fa5
Bulge the carousel cylinder outward and keep the outer cards readable
radiumcoders Sep 27, 2026
3883d51
Restore the carousel's cylinder curve and fix the sliver outer cards
radiumcoders Sep 27, 2026
88d93d2
Match carousel card heights at their edges so the cylinder reads as o…
radiumcoders Sep 27, 2026
7f9d68a
Tilt and shrink the outer carousel cards for a deeper curve
radiumcoders Sep 27, 2026
56bb46e
Open a small gap before the outer carousel cards
radiumcoders Sep 27, 2026
06615a1
Even out the gaps between carousel cards
radiumcoders Sep 27, 2026
9099b63
Fit the landing carousel to short screens and add swipe to rotate
radiumcoders Sep 27, 2026
7068754
Spread the carousel slots on phones so the side cards keep a gap
radiumcoders Sep 27, 2026
84ab6f7
Keep landing CTAs on one line and widen card gaps on narrow phones
radiumcoders Sep 27, 2026
0d31494
Measure carousel previews without their slot's transform
radiumcoders Sep 27, 2026
eef90c7
Add a live stats section to the landing page
radiumcoders Sep 27, 2026
144aa6c
Inset the landing hero in a rounded, bordered frame
radiumcoders Sep 27, 2026
00670e4
Clip the shader to the hero frame's corners and drop the stats divider
radiumcoders Sep 27, 2026
0a972bd
Tighten the hero frame's outer padding
radiumcoders Sep 27, 2026
1fd485f
Add MinecraftButton that cracks every few taps and breaks into a drop…
radiumcoders Sep 27, 2026
4f2e976
Turn the cursor into a swinging pickaxe over MinecraftButton
radiumcoders Sep 27, 2026
9043c1b
Use the diamond pickaxe sprite for MinecraftButton's cursor
radiumcoders Sep 27, 2026
51faf4d
Flip MinecraftButton's pickaxe so the head leads like a cursor
radiumcoders Sep 27, 2026
e366a9d
Rebuild ChromeButton as a self-contained liquid-metal pill
radiumcoders Sep 27, 2026
2eddd38
Bring back ChromeButton's sweeping liquid chrome bands
radiumcoders Sep 27, 2026
6fb4b82
Redesign ChromeButton as a solid pill in a flowing liquid-metal ring
radiumcoders Sep 27, 2026
bad796a
Fix ChromeButton freezing in dev and make it follow the theme
radiumcoders Sep 27, 2026
4f0ec76
Redesign EvilEyeButton around a smooth, watching eye
radiumcoders Sep 27, 2026
e7bdb62
Redesign PillButton as a themed pill switch with a status light
radiumcoders Sep 27, 2026
7f12e36
Replace PillButton with RealisticSwitch, an illuminated 3D rocker
radiumcoders Sep 27, 2026
4df85a8
Tilt RealisticSwitch into a clean three-quarter view with themed housing
radiumcoders Sep 27, 2026
63b974b
Rebuild RealisticSwitch's depth without stacked slices
radiumcoders Sep 27, 2026
a0dd094
Turn RealisticSwitch into a latching push switch
radiumcoders Sep 27, 2026
6aa1802
Fix docs build: drop the colon from RealisticSwitch's description
radiumcoders Sep 27, 2026
ed6033f
Smooth RealisticSwitch's hover by animating transforms only
radiumcoders Sep 27, 2026
7d099a0
Speed up the landing carousel and hide the stats section
radiumcoders Sep 27, 2026
93dfc9d
Prepare for launch: fix CI's registry check and tidy public surfaces
radiumcoders Sep 27, 2026
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
4 changes: 2 additions & 2 deletions .agents/skills/evil-button-docs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Use this skill to add a new Evil Buttons component to the docs and shadcn regist
2. Create or update `content/docs/<slug>.mdx`.
- Use `scripts/generate-docs.mjs` to scaffold a page when starting from scratch.
- Keep the install command as `<Cmd>@evilbuttons/<registry-name></Cmd>`.
- Include a live `<PreviewCard>` using the real component.
- Include a `<PreviewCard live>` using the real component (swapped for the dial-backed preview with prop controls when one exists in `components/landing/previews`).
3. Add the preview component to `components/mdx-custom-components.tsx` if the MDX page references it.
4. Add the item to `scripts/build-registry.mjs`.
- Read the source file with `readFile`.
Expand All @@ -43,7 +43,7 @@ ComponentName is ...

## Preview

<PreviewCard title="ComponentName" note="Interactive">
<PreviewCard live title="ComponentName" note="Interactive">
<ComponentName>Deploy Doom</ComponentName>
</PreviewCard>

Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/evil-button-docs/scripts/generate-docs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ ${title} is ${description.charAt(0).toLowerCase()}${description.slice(1)}

## Preview

<PreviewCard title="${title}" note="Interactive">
<PreviewCard live title="${title}" note="Interactive">
<${componentName}>Deploy Doom</${componentName}>
</PreviewCard>

Expand Down
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<!-- BEGIN:nextjs-agent-rules -->

# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.

This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.

<!-- END:nextjs-agent-rules -->
12 changes: 8 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Every new button must include:
- **Accessible HTML:** Prefer a real `<button>` unless the component is explicitly link-based. Forward standard button props where reasonable, preserve focus states, and keep labels readable.
- **Motion safety:** Hover, press, and animation states should respect `motion-reduce` when animation is significant.
- **Documentation:** Add a matching MDX page in `content/docs/` with preview, install command, usage example, props table, notes, and registry details.
- **Registry support:** Add the component to `scripts/build-registry.mjs` so `npm run registry:build` generates its `public/r/<name>.json` entry and updates `public/r/index.json`.
- **Registry support:** Add an entry to `registry.components.json` so `pnpm registry:build` generates its `public/r/<name>.json` file and updates `public/r/index.json`. Also register it in `components/mdx-custom-components.tsx` and the landing showcase (`components/landing/showcase.ts` plus a preview in `components/landing/previews/`); `pnpm registry:test` checks all of these.
- **Dependencies declared:** Any runtime dependency must be listed in the registry item. Registry dependencies should be listed separately from npm dependencies.
- **Consistent imports:** Use the project alias and helpers already used in the repo, especially `cn` from `@/lib/utils` when composing classes.

Expand Down Expand Up @@ -45,11 +45,15 @@ Each docs page should include:
Run these checks before handing off:

```bash
npm run registry:build
npm run lint
npm run build
pnpm registry:build
pnpm registry:test
pnpm lint
pnpm typecheck
pnpm build
```

CI runs the same checks on every pull request.

If a command fails because of an existing unrelated issue, mention the exact file and error in your handoff. If `next build` needs network access for Google Fonts, rerun it in an environment where font fetching is available.

## Style Guidance
Expand Down
122 changes: 84 additions & 38 deletions app/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import type { Metadata } from "next";
import type { ComponentProps } from "react";
import { notFound } from "next/navigation";
import { DocsPageActions } from "@/components/docs-page-actions";
import { getMDXComponents } from "@/components/mdx";
import { PreviewCard } from "@/components/preview-card";
import { PageToc } from "@/components/page-toc";
import { TracwellCard } from "@/components/tracwell-card";
import { JsonLd } from "@/components/seo/json-ld";
import { getPageMarkdown } from "@/lib/markdown";
import { DEFAULT_DOCS_SLUG } from "@/lib/docs-categories";
import { source } from "@/lib/source";
import {
absoluteUrl,
Expand Down Expand Up @@ -46,37 +50,66 @@ export default async function DocsPage({ params }: DocsPageProps) {
)}`
: undefined;

const importLine = getUsageImport(page.path);
const liveSource =
registryName !== null && hasRegistryItem && importLine !== null
? {
registryName,
installCommand: `npx shadcn@latest add ${absoluteUrl(`/r/${registryName}.json`)}`,
importLine,
docsUrl: absoluteUrl(page.url),
}
: undefined;

return (
<div className="relative mx-auto w-full max-w-3xl px-6 pb-10 pt-14 md:px-8 md:pt-10 xl:max-w-6xl xl:pr-56">
<JsonLd
data={[
createTechArticleJsonLd({
title: page.data.title,
description: page.data.description,
path: page.url,
}),
createBreadcrumbJsonLd(breadcrumbs),
]}
/>
<div className="mb-8 flex flex-wrap items-center justify-between gap-4">
<h1 className="text-4xl font-semibold tracking-tight text-foreground">
{page.data.title}
</h1>
<DocsPageActions
markdown={markdown}
githubUrl={`${siteConfig.github}/blob/main/content/docs/${page.path}`}
markdownUrl={rawPath}
markdownAbsoluteUrl={absoluteUrl(rawPath)}
v0Url={v0Url}
<div className="flex w-full justify-center gap-10">
<div className="min-h-dvh w-full max-w-4xl min-w-0 px-6 pt-16 pb-24 md:border-x md:border-dashed md:border-border md:px-10 md:pt-12">
<JsonLd
data={[
createTechArticleJsonLd({
title: page.data.title,
description: page.data.description,
path: page.url,
}),
createBreadcrumbJsonLd(breadcrumbs),
]}
/>
<header className="mb-10 flex flex-col gap-3">
<div className="flex flex-wrap items-center justify-between gap-x-6 gap-y-4">
<h1 className="font-heading text-[2.25rem] leading-[1.1] font-semibold tracking-[-0.03em] text-foreground">
{page.data.title}
</h1>
<DocsPageActions
markdown={markdown}
githubUrl={`${siteConfig.github}/blob/main/content/docs/${page.path}`}
markdownUrl={rawPath}
markdownAbsoluteUrl={absoluteUrl(rawPath)}
v0Url={v0Url}
/>
</div>
{page.data.description ? (
<p className="max-w-2xl text-[15px] leading-7 text-muted-foreground">
{page.data.description}
</p>
) : null}
</header>
<article className="docs-content min-w-0">
<MDX
components={getMDXComponents({
PreviewCard: (props: ComponentProps<typeof PreviewCard>) => (
<PreviewCard {...props} source={liveSource} />
),
})}
/>
</article>
</div>
<article className="docs-content min-w-0">
<MDX components={getMDXComponents()} />
</article>
<aside className="fixed top-8 right-6 hidden w-44 xl:block">
<div className="docs-scroll flex max-h-[calc(100dvh-4rem)] flex-col gap-2 overflow-y-auto pl-4">
<p className="text-xs text-muted-foreground">On this page</p>
<aside className="sticky top-3 hidden h-fit w-52 shrink-0 self-start pt-12 xl:block">
<div className="docs-scroll flex max-h-[calc(100dvh-6rem)] flex-col gap-3 overflow-y-auto pr-2">
<p className="text-xs font-medium text-muted-foreground">On this page</p>
<PageToc />
<div className="mt-6">
<TracwellCard />
</div>
</div>
</aside>
</div>
Expand Down Expand Up @@ -126,20 +159,33 @@ function getRegistryItemName(mdxPath: string): string | null {
}
}

/**
* The component import from the page's Usage snippet, e.g.
* `import { HoldButton } from "@/components/evil-buttons/hold-button";`.
*/
function getUsageImport(mdxPath: string): string | null {
try {
const contents = readFileSync(
join(process.cwd(), "content", "docs", mdxPath),
"utf8",
);
const match = contents.match(
/^import .+ from "@\/components\/evil-buttons\/[^"]+";$/m,
);
return match?.[0] ?? null;
} catch {
return null;
}
}

function getDocsPage(slug?: string[]) {
if (slug && slug.length > 0) {
return source.getPage(slug);
}

const defaultPage = source
.getPages()
.filter(
(page) =>
!page.url.startsWith("/docs/icons") &&
!page.url.startsWith("/docs/logos") &&
!page.url.startsWith("/docs/scroll-bars"),
)
.sort((a, b) => a.url.localeCompare(b.url))[0];

return defaultPage ?? source.getPages().sort((a, b) => a.url.localeCompare(b.url))[0] ?? null;
return (
source.getPage([DEFAULT_DOCS_SLUG]) ??
source.getPages().sort((a, b) => a.url.localeCompare(b.url))[0] ??
null
);
}
25 changes: 19 additions & 6 deletions app/docs/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
import type { ReactNode } from "react";
import { DocsShell } from "@/components/docs-shell";
import { DOCS_CATEGORIES } from "@/lib/docs-categories";
import { source } from "@/lib/source";

const UNCATEGORIZED = "Other";

export default function DocsLayout({ children }: { children: ReactNode }) {
const pages = source.getPages().map((page) => ({
title: page.data.title ?? page.slugs.at(-1) ?? "Untitled",
url: page.url,
}));
const componentPages = pages.sort((a, b) => a.title.localeCompare(b.title));
const pages = source
.getPages()
.map((page) => ({
title: page.data.title ?? page.slugs.at(-1) ?? "Untitled",
url: page.url,
category: page.data.category ?? UNCATEGORIZED,
}))
.sort((a, b) => a.title.localeCompare(b.title));

const sections = [...DOCS_CATEGORIES, UNCATEGORIZED]
.map((category) => ({
title: category,
pages: pages.filter((page) => page.category === category),
}))
.filter((section) => section.pages.length > 0);

return (
<DocsShell componentPages={componentPages}>
<DocsShell componentPages={pages} sections={sections}>
{children}
</DocsShell>
);
Expand Down
Loading
Loading