Skip to content

Commit 733b74e

Browse files
jwaldripclaude
andcommitted
feat(website): add responsive layout, dark mode, and core pages
- Add ThemeProvider with next-themes for light/dark/system mode support - Create Header with responsive navigation and mobile menu - Create Footer with links to resources and related projects - Redesign homepage with hero section and hat overview cards - Add About page explaining the AI-DLC methodology - Create docs layout with sidebar navigation and markdown rendering - Create blog layout with post listing and individual post pages - Add initial documentation (Introduction, Quick Start, Four Hats) - Add first blog post introducing AI-DLC 2026 - Implement custom prose/typography styles for markdown content - Build produces working static site for GitHub Pages Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 65613ee commit 733b74e

File tree

24 files changed

+2160
-50
lines changed

24 files changed

+2160
-50
lines changed

bun.lock

Lines changed: 388 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

website/app/about/page.tsx

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import type { Metadata } from "next"
2+
3+
export const metadata: Metadata = {
4+
title: "About - AI-DLC 2026",
5+
description:
6+
"Learn about AI-DLC 2026, a methodology for iterative AI-driven development with hat-based workflows.",
7+
}
8+
9+
export default function AboutPage() {
10+
return (
11+
<div className="px-4 py-16">
12+
<div className="mx-auto max-w-3xl">
13+
<h1 className="mb-8 text-4xl font-bold tracking-tight sm:text-5xl">
14+
About AI-DLC
15+
</h1>
16+
17+
<div className="prose prose-gray dark:prose-invert max-w-none">
18+
<p className="lead text-xl text-gray-600 dark:text-gray-400">
19+
AI-DLC 2026 is a methodology for structured, iterative software
20+
development with AI assistants. It provides a framework for
21+
organizing work into focused units with clear phases and
22+
responsibilities.
23+
</p>
24+
25+
<h2>The Problem</h2>
26+
<p>
27+
When working with AI assistants like Claude, it is easy to fall into
28+
unfocused patterns. Context switches happen mid-task, requirements
29+
drift, and quality suffers. Without structure, AI-assisted
30+
development can become chaotic and unproductive.
31+
</p>
32+
33+
<h2>The Solution</h2>
34+
<p>
35+
AI-DLC introduces a hat-based approach to development. Each hat
36+
represents a distinct mindset and set of responsibilities. By
37+
explicitly switching between hats, you maintain focus and ensure
38+
each phase of development gets proper attention.
39+
</p>
40+
41+
<h2>The Four Hats</h2>
42+
43+
<h3>Researcher</h3>
44+
<p>
45+
The Researcher gathers context and understanding before any
46+
implementation begins. This phase involves reading existing code,
47+
understanding requirements, researching patterns, and identifying
48+
constraints. The goal is to build a complete mental model of the
49+
problem space.
50+
</p>
51+
52+
<h3>Planner</h3>
53+
<p>
54+
The Planner designs the implementation approach. This includes
55+
breaking work into steps, identifying dependencies, considering edge
56+
cases, and creating actionable plans. The output is a clear roadmap
57+
for the Builder to follow.
58+
</p>
59+
60+
<h3>Builder</h3>
61+
<p>
62+
The Builder executes the plan. This is where code gets written,
63+
features get implemented, and tests get created. The Builder stays
64+
focused on the task at hand, following the plan without getting
65+
distracted by scope creep or tangential concerns.
66+
</p>
67+
68+
<h3>Reviewer</h3>
69+
<p>
70+
The Reviewer validates quality and completeness. This includes
71+
checking that tests pass, requirements are met, edge cases are
72+
handled, and code quality meets standards. The Reviewer ensures work
73+
is ready for production.
74+
</p>
75+
76+
<h2>Units of Work</h2>
77+
<p>
78+
Work is organized into units. Each unit is a focused piece of
79+
functionality that can be completed in one session. Units have clear
80+
success criteria and acceptance tests. Breaking work into units
81+
ensures progress is measurable and momentum is maintained.
82+
</p>
83+
84+
<h2>Benefits</h2>
85+
<ul>
86+
<li>
87+
<strong>Clear focus</strong>: Know exactly what mode you are in at
88+
all times
89+
</li>
90+
<li>
91+
<strong>Quality built-in</strong>: Review is not an afterthought
92+
</li>
93+
<li>
94+
<strong>Measurable progress</strong>: Units provide natural
95+
checkpoints
96+
</li>
97+
<li>
98+
<strong>AI-native</strong>: Designed for AI-assisted workflows
99+
</li>
100+
<li>
101+
<strong>Reduced context switching</strong>: Stay in one mode until
102+
complete
103+
</li>
104+
</ul>
105+
106+
<h2>Getting Started</h2>
107+
<p>
108+
AI-DLC is distributed as a Claude Code plugin. Install it in your
109+
project and start using the hat-based commands to structure your
110+
development workflow.
111+
</p>
112+
113+
<div className="not-prose my-8 rounded-lg bg-gray-100 p-4 font-mono text-sm dark:bg-gray-800">
114+
<code>/install-plugin thebushidocollective/ai-dlc</code>
115+
</div>
116+
117+
<h2>Part of Han</h2>
118+
<p>
119+
AI-DLC is part of the{" "}
120+
<a
121+
href="https://han.guru"
122+
className="text-blue-600 hover:underline dark:text-blue-400"
123+
>
124+
Han plugin ecosystem
125+
</a>{" "}
126+
for Claude Code. Han provides a curated marketplace of plugins built
127+
on Bushido principles: quality, honor, and mastery.
128+
</p>
129+
</div>
130+
</div>
131+
</div>
132+
)
133+
}

website/app/blog/[slug]/page.tsx

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import type { Metadata } from "next"
2+
import Link from "next/link"
3+
import { notFound } from "next/navigation"
4+
import ReactMarkdown from "react-markdown"
5+
import remarkGfm from "remark-gfm"
6+
import rehypeHighlight from "rehype-highlight"
7+
import rehypeSlug from "rehype-slug"
8+
import { getAllBlogPosts, getBlogPostBySlug } from "@/lib/blog"
9+
10+
interface Props {
11+
params: Promise<{ slug: string }>
12+
}
13+
14+
export async function generateStaticParams() {
15+
const posts = getAllBlogPosts()
16+
return posts.map((post) => ({
17+
slug: post.slug,
18+
}))
19+
}
20+
21+
export async function generateMetadata({ params }: Props): Promise<Metadata> {
22+
const resolvedParams = await params
23+
const post = getBlogPostBySlug(resolvedParams.slug)
24+
25+
if (!post) {
26+
return {
27+
title: "Post Not Found - AI-DLC 2026",
28+
}
29+
}
30+
31+
return {
32+
title: `${post.title} - AI-DLC 2026`,
33+
description: post.description,
34+
}
35+
}
36+
37+
function formatDate(dateString: string): string {
38+
const date = new Date(dateString)
39+
return date.toLocaleDateString("en-US", {
40+
year: "numeric",
41+
month: "long",
42+
day: "numeric",
43+
})
44+
}
45+
46+
export default async function BlogPostPage({ params }: Props) {
47+
const resolvedParams = await params
48+
const post = getBlogPostBySlug(resolvedParams.slug)
49+
50+
if (!post) {
51+
notFound()
52+
}
53+
54+
return (
55+
<article>
56+
<Link
57+
href="/blog/"
58+
className="mb-8 inline-flex items-center gap-2 text-sm text-gray-600 transition hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
59+
>
60+
<svg
61+
className="h-4 w-4"
62+
fill="none"
63+
viewBox="0 0 24 24"
64+
stroke="currentColor"
65+
aria-hidden="true"
66+
>
67+
<path
68+
strokeLinecap="round"
69+
strokeLinejoin="round"
70+
strokeWidth={2}
71+
d="M15 19l-7-7 7-7"
72+
/>
73+
</svg>
74+
Back to blog
75+
</Link>
76+
77+
<header className="mb-8">
78+
<time className="text-sm text-gray-500 dark:text-gray-500">
79+
{formatDate(post.date)}
80+
</time>
81+
<h1 className="mt-2 text-4xl font-bold tracking-tight sm:text-5xl">
82+
{post.title}
83+
</h1>
84+
{post.author && (
85+
<p className="mt-4 text-gray-600 dark:text-gray-400">
86+
By {post.author}
87+
</p>
88+
)}
89+
</header>
90+
91+
<div className="prose prose-gray dark:prose-invert max-w-none">
92+
<ReactMarkdown
93+
remarkPlugins={[remarkGfm]}
94+
rehypePlugins={[rehypeHighlight, rehypeSlug]}
95+
>
96+
{post.content}
97+
</ReactMarkdown>
98+
</div>
99+
</article>
100+
)
101+
}

website/app/blog/layout.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { ReactNode } from "react"
2+
3+
export default function BlogLayout({ children }: { children: ReactNode }) {
4+
return (
5+
<div className="mx-auto max-w-4xl px-4 py-8 lg:py-12">{children}</div>
6+
)
7+
}

website/app/blog/page.tsx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import type { Metadata } from "next"
2+
import Link from "next/link"
3+
import { getAllBlogPosts } from "@/lib/blog"
4+
5+
export const metadata: Metadata = {
6+
title: "Blog - AI-DLC 2026",
7+
description: "News and updates about AI-DLC 2026 and AI-driven development.",
8+
}
9+
10+
function formatDate(dateString: string): string {
11+
const date = new Date(dateString)
12+
return date.toLocaleDateString("en-US", {
13+
year: "numeric",
14+
month: "long",
15+
day: "numeric",
16+
})
17+
}
18+
19+
export default function BlogPage() {
20+
const posts = getAllBlogPosts()
21+
22+
return (
23+
<div>
24+
<h1 className="mb-4 text-4xl font-bold tracking-tight">Blog</h1>
25+
<p className="mb-12 text-lg text-gray-600 dark:text-gray-400">
26+
News and updates about AI-DLC and AI-driven development.
27+
</p>
28+
29+
{posts.length === 0 ? (
30+
<div className="rounded-lg border border-gray-200 bg-gray-50 p-8 text-center dark:border-gray-800 dark:bg-gray-900">
31+
<p className="text-gray-600 dark:text-gray-400">
32+
No blog posts yet. Check back soon!
33+
</p>
34+
</div>
35+
) : (
36+
<div className="space-y-8">
37+
{posts.map((post) => (
38+
<article
39+
key={post.slug}
40+
className="rounded-lg border border-gray-200 p-6 transition hover:border-gray-300 dark:border-gray-800 dark:hover:border-gray-700"
41+
>
42+
<time className="text-sm text-gray-500 dark:text-gray-500">
43+
{formatDate(post.date)}
44+
</time>
45+
<h2 className="mt-2 text-2xl font-semibold">
46+
<Link
47+
href={`/blog/${post.slug}/`}
48+
className="hover:text-blue-600 dark:hover:text-blue-400"
49+
>
50+
{post.title}
51+
</Link>
52+
</h2>
53+
{post.description && (
54+
<p className="mt-2 text-gray-600 dark:text-gray-400">
55+
{post.description}
56+
</p>
57+
)}
58+
{post.author && (
59+
<p className="mt-4 text-sm text-gray-500">By {post.author}</p>
60+
)}
61+
</article>
62+
))}
63+
</div>
64+
)}
65+
</div>
66+
)
67+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"use client"
2+
3+
import Link from "next/link"
4+
import { usePathname } from "next/navigation"
5+
6+
interface NavItem {
7+
title: string
8+
href: string
9+
items?: NavItem[]
10+
}
11+
12+
interface DocsSidebarProps {
13+
navigation: NavItem[]
14+
}
15+
16+
export function DocsSidebar({ navigation }: DocsSidebarProps) {
17+
const pathname = usePathname()
18+
19+
return (
20+
<aside className="sticky top-20 hidden h-[calc(100vh-5rem)] w-64 shrink-0 overflow-y-auto pb-8 lg:block">
21+
<nav className="space-y-6">
22+
{navigation.map((section) => (
23+
<div key={section.title}>
24+
{section.href ? (
25+
<Link
26+
href={section.href}
27+
className={`mb-2 block font-semibold transition hover:text-gray-900 dark:hover:text-white ${
28+
pathname === section.href
29+
? "text-gray-900 dark:text-white"
30+
: "text-gray-600 dark:text-gray-400"
31+
}`}
32+
>
33+
{section.title}
34+
</Link>
35+
) : (
36+
<h4 className="mb-2 font-semibold text-gray-900 dark:text-white">
37+
{section.title}
38+
</h4>
39+
)}
40+
{section.items && (
41+
<ul className="space-y-1 border-l border-gray-200 dark:border-gray-800">
42+
{section.items.map((item) => {
43+
const isActive = pathname === item.href
44+
return (
45+
<li key={item.href}>
46+
<Link
47+
href={item.href}
48+
className={`-ml-px block border-l-2 py-1 pl-4 text-sm transition ${
49+
isActive
50+
? "border-blue-500 font-medium text-blue-600 dark:text-blue-400"
51+
: "border-transparent text-gray-600 hover:border-gray-300 hover:text-gray-900 dark:text-gray-400 dark:hover:border-gray-700 dark:hover:text-white"
52+
}`}
53+
>
54+
{item.title}
55+
</Link>
56+
</li>
57+
)
58+
})}
59+
</ul>
60+
)}
61+
</div>
62+
))}
63+
</nav>
64+
</aside>
65+
)
66+
}

0 commit comments

Comments
 (0)