mirror of
https://github.com/bmad-code-org/BMAD-METHOD.git
synced 2026-01-30 04:32:02 +00:00
feat(docs): Diataxis restructure + Astro/Starlight migration (#1263)
* feat(docs): add Diataxis folder structure and update sidebar styling - Create tutorials, how-to, explanation, reference directories with subdirectories - Add index.md files for each main Diataxis section - Update homepage with Diataxis card navigation layout - Implement clean React Native-inspired sidebar styling - Convert sidebar to autogenerated for both Diataxis and legacy sections - Update docusaurus config with dark mode default and navbar changes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(docs): migrate Phase 1 files to Diataxis structure Move 21 files to new locations: - Tutorials: quick-start guides, agent creation guide - How-To: installation, customization, workflows - Explanation: core concepts, features, game-dev, builder - Reference: merged glossary from BMM and BMGD Also: - Copy images to new locations - Update internal links via migration script (73 links updated) - Build verified successfully 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(docs): add category labels for sidebar folders Add _category_.json files to control display labels and position for autogenerated sidebar categories. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * style(docs): improve welcome page and visual styling - Rewrite index.md with React Native-inspired welcoming layout - Add Diataxis section cards with descriptions - Remove sidebar separator, add spacing instead - Increase navbar padding with responsive breakpoints - Add rounded admonitions without left border bar - Use system font stack for better readability - Add lighter chevron styling in sidebar - Constrain max-width to 1600px for wide viewports 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: use baseUrl in meta tag paths for correct deployment URLs * feat(docs): complete Phase 2 - split files and fix broken links Phase 2 of Diataxis migration: - Split 16 large legacy files into 42+ focused documents - Created FAQ section with 7 topic-specific files - Created brownfield how-to guides (3 files) - Created workflow how-to guides (15+ files) - Created architecture explanation files (3 files) - Created TEA/testing explanation files - Moved remaining legacy module files to proper Diataxis locations Link fixes: - Fixed ~50 broken internal links across documentation - Updated relative paths for new file locations - Created missing index files for installation, advanced tutorials - Simplified TOC anchors to fix Docusaurus warnings Cleanup: - Removed legacy sidebar entries for deleted folders - Deleted duplicate and empty placeholder files - Moved workflow diagram assets to tutorials/images 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(build): use file glob instead of sidebar parsing for llms-full.txt Replace brittle sidebar.js regex parsing with recursive file glob. The old approach captured non-file strings like 'autogenerated' and category labels, resulting in only 5 files being processed. Now correctly processes all 86+ markdown files (~95k tokens). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(seo): use absolute URLs in AI meta tags for agent discoverability AI web-browsing agents couldn't follow relative paths in meta tags due to URL security restrictions. Changed llms-full.txt and llms.txt meta tag URLs from relative (baseUrl) to absolute (urlParts.origin + baseUrl). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(docs): recategorize misplaced files per Diataxis analysis Phase 2.5 categorization fixes based on post-migration analysis: Moved to correct Diataxis categories: - tutorials/installation.md → deleted (duplicate of how-to/install-bmad.md) - tutorials/brownfield-onboarding.md → how-to/brownfield/index.md - reference/faq/* (8 files) → explanation/faq/ - reference/agents/barry-quick-flow.md → explanation/agents/ - reference/agents/bmgd-agents.md → explanation/game-dev/agents.md Created: - explanation/agents/index.md Fixed all broken internal links (14 total) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(docs): add Getting Started tutorial and simplify build script - Add comprehensive Getting Started tutorial with installation as Step 1 - Simplify build-docs.js to read directly from docs/ (no consolidation) - Remove backup/restore dance that could corrupt docs folder on build failure - Remove ~150 lines of unused consolidation code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(css): use fixed width layout to prevent content shifting Apply React Native docs approach: set both width and max-width at largest breakpoint (1400px) so content area maintains consistent size regardless of content length. Switches to fluid 100% below 1416px breakpoint. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(docs): restructure tutorials with renamed entry point - Rename index.md to bmad-tutorial.md for clearer navigation - Remove redundant tutorials/index.md - Update sidebar and config references 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(docs): add tutorial style guide and AI agent announcement bar - Add docs/_contributing/ with tutorial style guide - Reformat quick-start-bmm.md and bmad-tutorial.md per style guide - Remove horizontal separators, add strategic admonitions - Add persistent announcement bar for AI agents directing to llms-full.txt - Fix footer broken link to tutorials 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(docs): add markdown demo page and UI refinements - Add comprehensive markdown-demo.md for style testing - Remove doc category links from navbar (use sidebar instead) - Remove card buttons from welcome page - Add dark mode styling for announcement bar - Clean up index.md card layout 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(docs): apply unified tutorial style and update references - Reformat create-custom-agent.md to follow tutorial style guide - Update tutorial-style.md with complete unified structure - Update all internal references to renamed tutorial files - Remove obsolete advanced/index.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(docs): migrate from Docusaurus to Astro+Starlight Replace Docusaurus with Astro and the Starlight documentation theme for improved performance, better customization, and modern tooling. Build pipeline changes: - New build-docs.js orchestrates link checking, artifact generation, and Astro build in sequence - Add check-doc-links.js for validating internal links and anchors - Generate llms.txt and llms-full.txt for LLM-friendly documentation - Create downloadable source bundles (bmad-sources.zip, bmad-prompts.zip) - Suppress MODULE_TYPELESS_PACKAGE_JSON warning in Astro build - Output directly to build/site for cleaner deployment Website architecture: - Add rehype-markdown-links.js plugin to transform .md links to routes - Add site-url.js helper for GitHub Pages URL resolution with strict validation (throws on invalid GITHUB_REPOSITORY format) - Custom Astro components: Banner, Header, MobileMenuFooter - Symlink docs/ into website/src/content/docs for Starlight Documentation cleanup: - Remove Docusaurus _category_.json files (Starlight uses frontmatter) - Convert all docs to use YAML frontmatter with title field - Move downloads.md from website/src/pages to docs/ - Consolidate style guide and workflow diagram docs - Add 404.md and tutorials/index.md --------- Co-authored-by: forcetrainer <bryan@inagaki.us> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
76
website/README.md
Normal file
76
website/README.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# BMAD Method Documentation Site
|
||||
|
||||
This directory contains the Astro + Starlight configuration for the BMAD Method documentation site.
|
||||
|
||||
## Architecture
|
||||
|
||||
The documentation uses a symlink architecture to keep content in `docs/` at the repo root while serving it through Astro:
|
||||
|
||||
```
|
||||
bmad2/
|
||||
├── docs/ # Content lives here (repo root)
|
||||
│ ├── index.md
|
||||
│ ├── tutorials/
|
||||
│ ├── how-to/
|
||||
│ ├── explanation/
|
||||
│ └── reference/
|
||||
└── website/
|
||||
├── astro.config.mjs # Astro + Starlight config
|
||||
├── src/
|
||||
│ ├── content/
|
||||
│ │ └── docs -> ../../docs # Symlink to content
|
||||
│ └── styles/
|
||||
│ └── custom.css # Custom styling
|
||||
└── public/ # Static assets
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# From repo root
|
||||
npm run docs:dev # Start dev server
|
||||
npm run docs:build # Build for production
|
||||
npm run docs:preview # Preview production build
|
||||
```
|
||||
|
||||
## Platform Notes
|
||||
|
||||
### Windows Symlink Support
|
||||
|
||||
The `website/src/content/docs` symlink may not work correctly on Windows without Developer Mode enabled or administrator privileges.
|
||||
|
||||
**To enable symlinks on Windows:**
|
||||
|
||||
1. **Enable Developer Mode** (recommended):
|
||||
- Settings → Update & Security → For developers → Developer Mode: On
|
||||
- This allows creating symlinks without admin rights
|
||||
|
||||
2. **Or use Git's symlink support**:
|
||||
```bash
|
||||
git config core.symlinks true
|
||||
```
|
||||
Then re-clone the repository.
|
||||
|
||||
3. **Or create a junction** (alternative):
|
||||
```cmd
|
||||
# Run as Administrator
|
||||
mklink /J website\src\content\docs ..\..\docs
|
||||
```
|
||||
|
||||
**If symlinks don't work**, you can copy the docs folder instead:
|
||||
```bash
|
||||
# Remove the symlink
|
||||
rm website/src/content/docs
|
||||
|
||||
# Copy the docs folder
|
||||
cp -r docs website/src/content/docs
|
||||
```
|
||||
|
||||
Note: If copying, remember to keep the copy in sync with changes to `docs/`.
|
||||
|
||||
## Build Output
|
||||
|
||||
The build pipeline (`npm run docs:build`) produces:
|
||||
- Static HTML site in `build/site/`
|
||||
- LLM-friendly files: `llms.txt`, `llms-full.txt`
|
||||
- Downloadable ZIP bundles in `downloads/`
|
||||
125
website/astro.config.mjs
Normal file
125
website/astro.config.mjs
Normal file
@@ -0,0 +1,125 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import starlight from '@astrojs/starlight';
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
import rehypeMarkdownLinks from './src/rehype-markdown-links.js';
|
||||
import { getSiteUrl } from './src/lib/site-url.js';
|
||||
|
||||
const siteUrl = getSiteUrl();
|
||||
const urlParts = new URL(siteUrl);
|
||||
// Normalize basePath: ensure trailing slash so links can use `${BASE_URL}path`
|
||||
const basePath = urlParts.pathname === '/' ? '/' : urlParts.pathname.endsWith('/') ? urlParts.pathname : urlParts.pathname + '/';
|
||||
|
||||
export default defineConfig({
|
||||
site: `${urlParts.origin}${basePath}`,
|
||||
base: basePath,
|
||||
outDir: '../build/site',
|
||||
|
||||
// Disable aggressive caching in dev mode
|
||||
vite: {
|
||||
optimizeDeps: {
|
||||
force: true, // Always re-bundle dependencies
|
||||
},
|
||||
server: {
|
||||
watch: {
|
||||
usePolling: false, // Set to true if file changes aren't detected
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
markdown: {
|
||||
rehypePlugins: [rehypeMarkdownLinks],
|
||||
},
|
||||
|
||||
integrations: [
|
||||
sitemap(),
|
||||
starlight({
|
||||
title: 'BMAD Method',
|
||||
tagline: 'AI-driven agile development with specialized agents and workflows that scale from bug fixes to enterprise platforms.',
|
||||
|
||||
logo: {
|
||||
src: './public/img/logo.svg',
|
||||
alt: 'BMAD Logo',
|
||||
},
|
||||
favicon: '/favicon.ico',
|
||||
|
||||
// Social links
|
||||
social: [
|
||||
{ icon: 'discord', label: 'Discord', href: 'https://discord.gg/gk8jAdXWmj' },
|
||||
{ icon: 'github', label: 'GitHub', href: 'https://github.com/bmad-code-org/BMAD-METHOD' },
|
||||
{ icon: 'youtube', label: 'YouTube', href: 'https://www.youtube.com/@BMadCode' },
|
||||
],
|
||||
|
||||
// Show last updated timestamps
|
||||
lastUpdated: true,
|
||||
|
||||
// Custom head tags for LLM discovery
|
||||
head: [
|
||||
{
|
||||
tag: 'meta',
|
||||
attrs: {
|
||||
name: 'ai-terms',
|
||||
content: `AI-optimized documentation: ${siteUrl}/llms-full.txt (plain text, ~100k tokens, complete BMAD reference). Index: ${siteUrl}/llms.txt`,
|
||||
},
|
||||
},
|
||||
{
|
||||
tag: 'meta',
|
||||
attrs: {
|
||||
name: 'llms-full',
|
||||
content: `${siteUrl}/llms-full.txt`,
|
||||
},
|
||||
},
|
||||
{
|
||||
tag: 'meta',
|
||||
attrs: {
|
||||
name: 'llms',
|
||||
content: `${siteUrl}/llms.txt`,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
// Custom CSS
|
||||
customCss: ['./src/styles/custom.css'],
|
||||
|
||||
// Sidebar configuration (Diataxis structure)
|
||||
sidebar: [
|
||||
{ label: 'Welcome', slug: 'index' },
|
||||
{
|
||||
label: 'Tutorials',
|
||||
collapsed: false,
|
||||
autogenerate: { directory: 'tutorials' },
|
||||
},
|
||||
{
|
||||
label: 'How-To Guides',
|
||||
collapsed: true,
|
||||
autogenerate: { directory: 'how-to' },
|
||||
},
|
||||
{
|
||||
label: 'Explanation',
|
||||
collapsed: true,
|
||||
autogenerate: { directory: 'explanation' },
|
||||
},
|
||||
{
|
||||
label: 'Reference',
|
||||
collapsed: true,
|
||||
autogenerate: { directory: 'reference' },
|
||||
},
|
||||
],
|
||||
|
||||
// Credits in footer
|
||||
credits: false,
|
||||
|
||||
// Pagination
|
||||
pagination: true,
|
||||
|
||||
// Custom components
|
||||
components: {
|
||||
Header: './src/components/Header.astro',
|
||||
MobileMenuFooter: './src/components/MobileMenuFooter.astro',
|
||||
},
|
||||
|
||||
// Table of contents
|
||||
tableOfContents: { minHeadingLevel: 2, maxHeadingLevel: 3 },
|
||||
}),
|
||||
],
|
||||
});
|
||||
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* BMAD Documentation Custom Styles
|
||||
*/
|
||||
|
||||
:root {
|
||||
--ifm-color-primary: #0d9488;
|
||||
--ifm-color-primary-dark: #0b847a;
|
||||
--ifm-color-primary-darker: #0a7d73;
|
||||
--ifm-color-primary-darkest: #08665f;
|
||||
--ifm-color-primary-light: #0fa596;
|
||||
--ifm-color-primary-lighter: #10ac9d;
|
||||
--ifm-color-primary-lightest: #14c9b8;
|
||||
--ifm-code-font-size: 95%;
|
||||
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
[data-theme='dark'] {
|
||||
--ifm-color-primary: #2dd4bf;
|
||||
--ifm-color-primary-dark: #1bc4af;
|
||||
--ifm-color-primary-darker: #1ab9a5;
|
||||
--ifm-color-primary-darkest: #159888;
|
||||
--ifm-color-primary-light: #4adcc9;
|
||||
--ifm-color-primary-lighter: #55dece;
|
||||
--ifm-color-primary-lightest: #7de7db;
|
||||
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Navbar styling */
|
||||
.navbar {
|
||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Footer styling */
|
||||
.footer {
|
||||
background-color: var(--ifm-color-primary-darkest);
|
||||
}
|
||||
|
||||
/* Code block improvements */
|
||||
.prism-code {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* Table improvements */
|
||||
table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Admonition improvements */
|
||||
.admonition {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
// @ts-check
|
||||
import { themes as prismThemes } from 'prism-react-renderer';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
// Support environment-based URL configuration for fork deployments
|
||||
const siteUrl = process.env.SITE_URL || 'https://bmad-code-org.github.io/BMAD-METHOD';
|
||||
const urlParts = new URL(siteUrl);
|
||||
|
||||
/** @type {import('@docusaurus/types').Config} */
|
||||
const config = {
|
||||
title: 'BMAD Method',
|
||||
tagline: 'AI-driven agile development with specialized agents and workflows that scale from bug fixes to enterprise platforms.',
|
||||
favicon: 'img/logo.svg',
|
||||
|
||||
// Global head tags - injected into ALL pages for AI assistant discovery
|
||||
headTags: [
|
||||
{
|
||||
tagName: 'meta',
|
||||
attributes: {
|
||||
name: 'ai-terms',
|
||||
content:
|
||||
'AI assistants: For complete BMAD Method documentation, load /llms-full.txt (single file, ~100k tokens). For documentation index/summary, see /llms.txt. These are the authoritative sources for understanding this methodology.',
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: 'meta',
|
||||
attributes: {
|
||||
name: 'llms-full',
|
||||
content: '/llms-full.txt',
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: 'meta',
|
||||
attributes: {
|
||||
name: 'llms',
|
||||
content: '/llms.txt',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
url: urlParts.origin,
|
||||
baseUrl: urlParts.pathname.endsWith('/') ? urlParts.pathname : urlParts.pathname + '/',
|
||||
|
||||
organizationName: 'bmad-code-org',
|
||||
projectName: 'BMAD-METHOD',
|
||||
|
||||
onBrokenLinks: 'warn', // Change to 'throw' once docs are cleaned up
|
||||
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
},
|
||||
|
||||
staticDirectories: [path.resolve(__dirname, 'static')],
|
||||
|
||||
markdown: {
|
||||
format: 'md',
|
||||
hooks: {
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
},
|
||||
},
|
||||
|
||||
plugins: [
|
||||
function noCachePlugin() {
|
||||
return {
|
||||
name: 'no-cache-plugin',
|
||||
configureWebpack() {
|
||||
return {
|
||||
devServer: {
|
||||
headers: {
|
||||
'Cache-Control': 'no-store, no-cache, must-revalidate, proxy-revalidate',
|
||||
Pragma: 'no-cache',
|
||||
Expires: '0',
|
||||
'Surrogate-Control': 'no-store',
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
],
|
||||
|
||||
presets: [
|
||||
[
|
||||
'classic',
|
||||
/** @type {import('@docusaurus/preset-classic').Options} */
|
||||
({
|
||||
docs: {
|
||||
sidebarPath: path.resolve(__dirname, 'sidebars.js'),
|
||||
exclude: ['**/templates/**', '**/reference/**', 'installers-bundlers/**', '**/images/**'],
|
||||
},
|
||||
blog: false,
|
||||
pages: {
|
||||
path: path.resolve(__dirname, 'src/pages'),
|
||||
},
|
||||
theme: {
|
||||
customCss: path.resolve(__dirname, 'css/custom.css'),
|
||||
},
|
||||
}),
|
||||
],
|
||||
],
|
||||
|
||||
themeConfig:
|
||||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
||||
({
|
||||
navbar: {
|
||||
title: 'BMAD Method',
|
||||
logo: {
|
||||
alt: 'BMAD Logo',
|
||||
src: 'img/logo.svg',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'docSidebar',
|
||||
sidebarId: 'mainSidebar',
|
||||
position: 'left',
|
||||
label: 'Docs',
|
||||
},
|
||||
{
|
||||
to: '/downloads',
|
||||
label: 'Downloads',
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'pathname:///llms.txt',
|
||||
label: 'llms.txt',
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/bmad-code-org/BMAD-METHOD',
|
||||
label: 'GitHub',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
style: 'dark',
|
||||
links: [
|
||||
{
|
||||
title: 'Docs',
|
||||
items: [
|
||||
{ label: 'Quick Start', to: '/docs/modules/bmm/quick-start' },
|
||||
{ label: 'Installation', to: '/docs/getting-started/installation' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Community',
|
||||
items: [{ label: 'Discord', href: 'https://discord.gg/bmad' }],
|
||||
},
|
||||
{
|
||||
title: 'More',
|
||||
items: [
|
||||
{
|
||||
label: 'GitHub',
|
||||
href: 'https://github.com/bmad-code-org/BMAD-METHOD',
|
||||
},
|
||||
{ label: 'llms.txt', href: 'pathname:///llms.txt' },
|
||||
{ label: 'llms-full.txt', href: 'pathname:///llms-full.txt' },
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} BMAD Code Organization.`,
|
||||
},
|
||||
prism: {
|
||||
theme: prismThemes.github,
|
||||
darkTheme: prismThemes.dracula,
|
||||
},
|
||||
colorMode: {
|
||||
defaultMode: 'light',
|
||||
disableSwitch: false,
|
||||
respectPrefersColorScheme: true,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 284 B After Width: | Height: | Size: 284 B |
@@ -1,134 +0,0 @@
|
||||
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
|
||||
const sidebars = {
|
||||
mainSidebar: [
|
||||
'index',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Core Concepts',
|
||||
items: [
|
||||
'bmad-core-concepts/index',
|
||||
'bmad-core-concepts/agents',
|
||||
'bmad-core-concepts/workflows',
|
||||
'bmad-core-concepts/modules',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Installing',
|
||||
collapsed: true,
|
||||
items: ['bmad-core-concepts/installing/index', 'bmad-core-concepts/installing/upgrading'],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Customization',
|
||||
collapsed: true,
|
||||
items: [
|
||||
'bmad-core-concepts/bmad-customization/index',
|
||||
'bmad-core-concepts/bmad-customization/agents',
|
||||
'bmad-core-concepts/bmad-customization/workflows',
|
||||
],
|
||||
},
|
||||
'bmad-core-concepts/web-bundles/index',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'BMM - Method',
|
||||
items: [
|
||||
'modules/bmm-bmad-method/index',
|
||||
'modules/bmm-bmad-method/quick-start',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Quick Flows',
|
||||
collapsed: true,
|
||||
items: [
|
||||
'modules/bmm-bmad-method/bmad-quick-flow',
|
||||
'modules/bmm-bmad-method/quick-flow-solo-dev',
|
||||
'modules/bmm-bmad-method/quick-spec-flow',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Workflows',
|
||||
collapsed: true,
|
||||
items: [
|
||||
'modules/bmm-bmad-method/workflows-planning',
|
||||
'modules/bmm-bmad-method/workflows-solutioning',
|
||||
'modules/bmm-bmad-method/workflows-analysis',
|
||||
'modules/bmm-bmad-method/workflows-implementation',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Advanced Topics',
|
||||
collapsed: true,
|
||||
items: [
|
||||
'modules/bmm-bmad-method/party-mode',
|
||||
'modules/bmm-bmad-method/agents-guide',
|
||||
'modules/bmm-bmad-method/brownfield-guide',
|
||||
'modules/bmm-bmad-method/test-architecture',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Reference',
|
||||
collapsed: true,
|
||||
items: [
|
||||
'modules/bmm-bmad-method/workflow-document-project-reference',
|
||||
'modules/bmm-bmad-method/troubleshooting',
|
||||
'modules/bmm-bmad-method/faq',
|
||||
'modules/bmm-bmad-method/glossary',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'BMB - Builder',
|
||||
collapsed: true,
|
||||
items: [
|
||||
'modules/bmb-bmad-builder/index',
|
||||
'modules/bmb-bmad-builder/agent-creation-guide',
|
||||
'modules/bmb-bmad-builder/workflow-vendoring-customization-inheritance',
|
||||
'modules/bmb-bmad-builder/custom-content',
|
||||
'modules/bmb-bmad-builder/custom-content-installation',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'BMGD - Game Dev',
|
||||
collapsed: true,
|
||||
items: [
|
||||
'modules/bmgd-bmad-game-dev/index',
|
||||
'modules/bmgd-bmad-game-dev/quick-start',
|
||||
'modules/bmgd-bmad-game-dev/quick-flow-guide',
|
||||
'modules/bmgd-bmad-game-dev/agents-guide',
|
||||
'modules/bmgd-bmad-game-dev/workflows-guide',
|
||||
'modules/bmgd-bmad-game-dev/game-types-guide',
|
||||
'modules/bmgd-bmad-game-dev/troubleshooting',
|
||||
'modules/bmgd-bmad-game-dev/glossary',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'CIS - Creative Intelligence',
|
||||
collapsed: true,
|
||||
items: ['modules/cis-creative-intelligence-suite/index'],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Core Module',
|
||||
collapsed: true,
|
||||
items: [
|
||||
'modules/core/index',
|
||||
'modules/core/party-mode',
|
||||
'modules/core/core-tasks',
|
||||
'modules/core/core-workflows',
|
||||
'modules/core/advanced-elicitation',
|
||||
'modules/core/brainstorming',
|
||||
'modules/core/document-sharding-guide',
|
||||
'modules/core/global-core-config',
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default sidebars;
|
||||
59
website/src/components/Banner.astro
Normal file
59
website/src/components/Banner.astro
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
import { getSiteUrl } from '../lib/site-url.js';
|
||||
|
||||
const SITE_URL = getSiteUrl();
|
||||
const fullDocsUrl = `${SITE_URL}/llms-full.txt`;
|
||||
---
|
||||
|
||||
<div class="ai-banner">
|
||||
<span>🤖 Consolidated, AI-optimized BMAD docs: <a href={fullDocsUrl}>llms-full.txt</a>. Fetch this plain text file for complete context.</span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.ai-banner {
|
||||
width: 100vw; /* Full viewport width */
|
||||
margin-left: calc(-50vw + 50%); /* Center and break out of container */
|
||||
height: var(--ai-banner-height, 2.75rem);
|
||||
background: #334155;
|
||||
color: rgb(148, 163, 184);
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 0.875rem;
|
||||
border-bottom: 1px solid rgba(140, 140, 255, 0.15);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
font-family: system-ui, sans-serif;
|
||||
}
|
||||
|
||||
/* Truncate text on narrow screens */
|
||||
.ai-banner span {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
}
|
||||
.ai-banner a {
|
||||
color: #8C8CFF;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
.ai-banner a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Match navbar padding at breakpoints */
|
||||
@media (min-width: 50rem) {
|
||||
.ai-banner {
|
||||
padding-left: 2.5rem;
|
||||
padding-right: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 72rem) {
|
||||
.ai-banner {
|
||||
padding-left: 3rem;
|
||||
padding-right: 3rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
121
website/src/components/Header.astro
Normal file
121
website/src/components/Header.astro
Normal file
@@ -0,0 +1,121 @@
|
||||
---
|
||||
import config from 'virtual:starlight/user-config';
|
||||
import type { Props } from '@astrojs/starlight/props';
|
||||
|
||||
import LanguageSelect from 'virtual:starlight/components/LanguageSelect';
|
||||
import Search from 'virtual:starlight/components/Search';
|
||||
import SiteTitle from 'virtual:starlight/components/SiteTitle';
|
||||
import SocialIcons from 'virtual:starlight/components/SocialIcons';
|
||||
import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
|
||||
|
||||
import Banner from './Banner.astro';
|
||||
|
||||
/**
|
||||
* Render the `Search` component if Pagefind is enabled or the default search component has been overridden.
|
||||
*/
|
||||
const shouldRenderSearch =
|
||||
config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro';
|
||||
---
|
||||
|
||||
<Banner />
|
||||
<div class="header sl-flex">
|
||||
<div class="title-wrapper sl-flex">
|
||||
<SiteTitle {...Astro.props} />
|
||||
</div>
|
||||
<div class="sl-flex print:hidden">
|
||||
{shouldRenderSearch && <Search {...Astro.props} />}
|
||||
</div>
|
||||
<div class="sl-hidden md:sl-flex print:hidden right-group">
|
||||
<nav class="sl-flex nav-links">
|
||||
<a href={`${import.meta.env.BASE_URL}downloads/`}>Downloads</a>
|
||||
</nav>
|
||||
<div class="sl-flex social-icons">
|
||||
<SocialIcons {...Astro.props} />
|
||||
</div>
|
||||
<ThemeSelect {...Astro.props} />
|
||||
<LanguageSelect {...Astro.props} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.header {
|
||||
gap: var(--sl-nav-gap);
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.title-wrapper {
|
||||
/* Prevent long titles overflowing and covering the search and menu buttons on narrow viewports. */
|
||||
overflow: clip;
|
||||
/* Avoid clipping focus ring around link inside title wrapper. */
|
||||
padding: 0.25rem;
|
||||
margin: -0.25rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.right-group,
|
||||
.social-icons,
|
||||
.nav-links {
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: var(--sl-color-white);
|
||||
text-decoration: none;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
transition: color 0.15s ease, background-color 0.15s ease;
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: var(--sl-color-accent);
|
||||
background-color: rgba(140, 140, 255, 0.1);
|
||||
}
|
||||
|
||||
.nav-links::after {
|
||||
content: '';
|
||||
height: 2rem;
|
||||
border-inline-end: 1px solid var(--sl-color-gray-5);
|
||||
}
|
||||
|
||||
.social-icons::after {
|
||||
content: '';
|
||||
height: 2rem;
|
||||
border-inline-end: 1px solid var(--sl-color-gray-5);
|
||||
}
|
||||
|
||||
@media (min-width: 50rem) {
|
||||
:global(:root[data-has-sidebar]) {
|
||||
--__sidebar-pad: calc(2 * var(--sl-nav-pad-x));
|
||||
}
|
||||
:global(:root:not([data-has-toc])) {
|
||||
--__toc-width: 0rem;
|
||||
}
|
||||
.header {
|
||||
--__sidebar-width: max(0rem, var(--sl-content-inline-start, 0rem) - var(--sl-nav-pad-x));
|
||||
--__main-column-fr: calc(
|
||||
(
|
||||
100% + var(--__sidebar-pad, 0rem) - var(--__toc-width, var(--sl-sidebar-width)) -
|
||||
(2 * var(--__toc-width, var(--sl-nav-pad-x))) - var(--sl-content-inline-start, 0rem) -
|
||||
var(--sl-content-width)
|
||||
) / 2
|
||||
);
|
||||
display: grid;
|
||||
grid-template-columns:
|
||||
/* 1 (site title): runs up until the main content column’s left edge or the width of the title, whichever is the largest */
|
||||
minmax(
|
||||
calc(var(--__sidebar-width) + max(0rem, var(--__main-column-fr) - var(--sl-nav-gap))),
|
||||
auto
|
||||
)
|
||||
/* 2 (search box): all free space that is available. */
|
||||
1fr
|
||||
/* 3 (right items): use the space that these need. */
|
||||
auto;
|
||||
align-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
53
website/src/components/MobileMenuFooter.astro
Normal file
53
website/src/components/MobileMenuFooter.astro
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
import LanguageSelect from 'virtual:starlight/components/LanguageSelect';
|
||||
import SocialIcons from 'virtual:starlight/components/SocialIcons';
|
||||
import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
|
||||
import type { Props } from '@astrojs/starlight/props';
|
||||
---
|
||||
|
||||
<div class="mobile-preferences sl-flex">
|
||||
<div class="sl-flex social-icons">
|
||||
<SocialIcons {...Astro.props} />
|
||||
</div>
|
||||
<nav class="sl-flex nav-links">
|
||||
<a href={`${import.meta.env.BASE_URL}downloads/`}>Downloads</a>
|
||||
</nav>
|
||||
<ThemeSelect {...Astro.props} />
|
||||
<LanguageSelect {...Astro.props} />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.social-icons {
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
padding-block: 1rem;
|
||||
}
|
||||
.social-icons:empty {
|
||||
display: none;
|
||||
}
|
||||
.mobile-preferences {
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
border-top: 1px solid var(--sl-color-gray-6);
|
||||
column-gap: 1rem;
|
||||
padding: 0.5rem 0;
|
||||
align-items: center;
|
||||
}
|
||||
.nav-links {
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
.nav-links a {
|
||||
color: var(--sl-color-white);
|
||||
text-decoration: none;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 4px;
|
||||
transition: color 0.15s ease, background-color 0.15s ease;
|
||||
}
|
||||
.nav-links a:hover {
|
||||
color: var(--sl-color-accent);
|
||||
background-color: rgba(140, 140, 255, 0.1);
|
||||
}
|
||||
</style>
|
||||
6
website/src/content/config.ts
Normal file
6
website/src/content/config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { defineCollection } from 'astro:content';
|
||||
import { docsSchema } from '@astrojs/starlight/schema';
|
||||
|
||||
export const collections = {
|
||||
docs: defineCollection({ schema: docsSchema() }),
|
||||
};
|
||||
1
website/src/content/docs
Symbolic link
1
website/src/content/docs
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../docs
|
||||
25
website/src/lib/site-url.js
Normal file
25
website/src/lib/site-url.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Resolve the site's base URL using cascading environment defaults.
|
||||
*
|
||||
* Preference order: use SITE_URL if set; otherwise derive a GitHub Pages URL from GITHUB_REPOSITORY; otherwise use the local development URL.
|
||||
* @returns {string} The resolved site URL (SITE_URL override, or `https://{owner}.github.io/{repo}`, or `http://localhost:3000`).
|
||||
*/
|
||||
export function getSiteUrl() {
|
||||
// Explicit override (works in both local and GitHub Actions)
|
||||
if (process.env.SITE_URL) {
|
||||
return process.env.SITE_URL;
|
||||
}
|
||||
|
||||
// GitHub Actions: compute from repository context
|
||||
if (process.env.GITHUB_REPOSITORY) {
|
||||
const parts = process.env.GITHUB_REPOSITORY.split('/');
|
||||
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
||||
throw new Error(`Invalid GITHUB_REPOSITORY format: "${process.env.GITHUB_REPOSITORY}". Expected "owner/repo".`);
|
||||
}
|
||||
const [owner, repo] = parts;
|
||||
return `https://${owner}.github.io/${repo}`;
|
||||
}
|
||||
|
||||
// Local development: use dev server
|
||||
return 'http://localhost:3000';
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
# Downloads
|
||||
|
||||
Download BMAD Method resources for offline use, AI training, or integration.
|
||||
|
||||
## LLM-Optimized Files
|
||||
|
||||
These files are designed for AI consumption - perfect for loading into Claude, ChatGPT, or any LLM context window.
|
||||
|
||||
| File | Description | Use Case |
|
||||
| ----------------------------------- | ----------------------------------- | -------------------------- |
|
||||
| **[llms.txt](/llms.txt)** | Documentation index with summaries | Quick overview, navigation |
|
||||
| **[llms-full.txt](/llms-full.txt)** | Complete documentation concatenated | Full context loading |
|
||||
|
||||
### Using with LLMs
|
||||
|
||||
**Claude Projects:**
|
||||
|
||||
```
|
||||
Upload llms-full.txt as project knowledge
|
||||
```
|
||||
|
||||
**ChatGPT:**
|
||||
|
||||
```
|
||||
Paste llms.txt for navigation, or sections from llms-full.txt as needed
|
||||
```
|
||||
|
||||
**API Usage:**
|
||||
|
||||
```python
|
||||
import requests
|
||||
docs = requests.get("https://bmad-code-org.github.io/BMAD-METHOD/llms-full.txt").text
|
||||
# Include in your system prompt or context
|
||||
```
|
||||
|
||||
## Installation Options
|
||||
|
||||
### NPM (Recommended)
|
||||
|
||||
```bash
|
||||
npx bmad-method@alpha install
|
||||
```
|
||||
|
||||
## Version Information
|
||||
|
||||
- **Current Version:** See [CHANGELOG](https://github.com/bmad-code-org/BMAD-METHOD/blob/main/CHANGELOG.md)
|
||||
- **Release Notes:** Available on [GitHub Releases](https://github.com/bmad-code-org/BMAD-METHOD/releases)
|
||||
|
||||
## API Access
|
||||
|
||||
For programmatic access to BMAD documentation:
|
||||
|
||||
```bash
|
||||
# Get documentation index
|
||||
curl https://bmad-code-org.github.io/BMAD-METHOD/llms.txt
|
||||
|
||||
# Get full documentation
|
||||
curl https://bmad-code-org.github.io/BMAD-METHOD/llms-full.txt
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Want to improve BMAD Method? Check out:
|
||||
|
||||
- [Contributing Guide](https://github.com/bmad-code-org/BMAD-METHOD/blob/main/CONTRIBUTING.md)
|
||||
- [GitHub Repository](https://github.com/bmad-code-org/BMAD-METHOD)
|
||||
@@ -1,50 +0,0 @@
|
||||
import React from 'react';
|
||||
import Layout from '@theme/Layout';
|
||||
import Link from '@docusaurus/Link';
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
|
||||
export default function Home() {
|
||||
const llmsFullUrl = useBaseUrl('/llms-full.txt');
|
||||
|
||||
return (
|
||||
<Layout title="Home" description="BMAD Method - AI-driven agile development">
|
||||
<main
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
minHeight: 'calc(100vh - 200px)',
|
||||
textAlign: 'center',
|
||||
padding: '2rem',
|
||||
}}
|
||||
>
|
||||
<h1 style={{ fontSize: '3rem', marginBottom: '0.5rem' }}>BMAD Method</h1>
|
||||
<p
|
||||
style={{
|
||||
fontSize: '1.5rem',
|
||||
color: 'var(--ifm-color-emphasis-600)',
|
||||
marginBottom: '2rem',
|
||||
}}
|
||||
>
|
||||
Under Construction
|
||||
</p>
|
||||
|
||||
<Link to="/docs/" className="button button--primary button--lg" style={{ marginBottom: '3rem' }}>
|
||||
View Documentation
|
||||
</Link>
|
||||
|
||||
<a
|
||||
href={llmsFullUrl}
|
||||
title="Complete BMAD documentation in a single file for AI assistants"
|
||||
style={{
|
||||
fontSize: '0.875rem',
|
||||
color: 'var(--ifm-color-emphasis-500)',
|
||||
}}
|
||||
>
|
||||
🤖 AI Context: llms-full.txt
|
||||
</a>
|
||||
</main>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
88
website/src/rehype-markdown-links.js
Normal file
88
website/src/rehype-markdown-links.js
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Rehype plugin to transform relative markdown file links (.md) to page routes
|
||||
*
|
||||
* Transforms:
|
||||
* ./path/to/file.md → ./path/to/file/
|
||||
* ./path/index.md → ./path/ (index.md becomes directory root)
|
||||
* ../path/file.md#anchor → ../path/file/#anchor
|
||||
* ./file.md?query=param → ./file/?query=param
|
||||
*
|
||||
* Only affects relative links (./, ../) - absolute and external links are unchanged
|
||||
*/
|
||||
|
||||
import { visit } from 'unist-util-visit';
|
||||
|
||||
/**
|
||||
* Convert relative Markdown file links (./ or ../) into equivalent page route-style links.
|
||||
*
|
||||
* The returned transformer walks the HTML tree and rewrites anchor `href` values that are relative paths pointing to `.md` files. It preserves query strings and hash anchors, rewrites `.../index.md` to the directory root path (`.../`), and rewrites other `.md` file paths by removing the `.md` extension and ensuring a trailing slash. Absolute, external, non-relative, non-string, or links without `.md` are left unchanged.
|
||||
*
|
||||
* @returns {function} A HAST tree transformer that mutates `a` element `href` properties as described.
|
||||
*/
|
||||
export default function rehypeMarkdownLinks() {
|
||||
return (tree) => {
|
||||
visit(tree, 'element', (node) => {
|
||||
// Only process anchor tags with href
|
||||
if (node.tagName !== 'a' || !node.properties?.href) {
|
||||
return;
|
||||
}
|
||||
|
||||
const href = node.properties.href;
|
||||
|
||||
// Skip if not a string (shouldn't happen, but be safe)
|
||||
if (typeof href !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only transform relative paths starting with ./ or ../
|
||||
if (!href.startsWith('./') && !href.startsWith('../')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract path portion (before ? and #) to check if it's a .md file
|
||||
const firstDelimiter = Math.min(
|
||||
href.indexOf('?') === -1 ? Infinity : href.indexOf('?'),
|
||||
href.indexOf('#') === -1 ? Infinity : href.indexOf('#'),
|
||||
);
|
||||
const pathPortion = firstDelimiter === Infinity ? href : href.substring(0, firstDelimiter);
|
||||
|
||||
// Don't transform if path doesn't end with .md
|
||||
if (!pathPortion.endsWith('.md')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Split the URL into parts: path, anchor, and query
|
||||
let urlPath = pathPortion;
|
||||
let anchor = '';
|
||||
let query = '';
|
||||
|
||||
// Extract query string and anchor from original href
|
||||
if (firstDelimiter !== Infinity) {
|
||||
const suffix = href.substring(firstDelimiter);
|
||||
const anchorInSuffix = suffix.indexOf('#');
|
||||
if (suffix.startsWith('?')) {
|
||||
if (anchorInSuffix !== -1) {
|
||||
query = suffix.substring(0, anchorInSuffix);
|
||||
anchor = suffix.substring(anchorInSuffix);
|
||||
} else {
|
||||
query = suffix;
|
||||
}
|
||||
} else {
|
||||
// starts with #
|
||||
anchor = suffix;
|
||||
}
|
||||
}
|
||||
|
||||
// Transform .md to /
|
||||
// Special case: index.md → directory root (e.g., ./tutorials/index.md → ./tutorials/)
|
||||
if (urlPath.endsWith('/index.md')) {
|
||||
urlPath = urlPath.replace(/\/index\.md$/, '/');
|
||||
} else {
|
||||
urlPath = urlPath.replace(/\.md$/, '/');
|
||||
}
|
||||
|
||||
// Reconstruct the href
|
||||
node.properties.href = urlPath + query + anchor;
|
||||
});
|
||||
};
|
||||
}
|
||||
483
website/src/styles/custom.css
Normal file
483
website/src/styles/custom.css
Normal file
@@ -0,0 +1,483 @@
|
||||
/**
|
||||
* BMAD Method Documentation - Custom Styles for Starlight
|
||||
* Electric Blue theme optimized for dark mode
|
||||
*
|
||||
* CSS Variable Mapping:
|
||||
* Docusaurus → Starlight
|
||||
* --ifm-color-primary → --sl-color-accent
|
||||
* --ifm-background-color → --sl-color-bg
|
||||
* --ifm-font-color-base → --sl-color-text
|
||||
*/
|
||||
|
||||
/* ============================================
|
||||
COLOR PALETTE - Light Mode
|
||||
============================================ */
|
||||
:root {
|
||||
--ai-banner-height: 2.75rem;
|
||||
--sl-nav-height: 6.25rem; /* Base nav height (~3.5rem) + banner height (2.75rem) */
|
||||
|
||||
/* Primary accent colors - purple to match Docusaurus */
|
||||
--sl-color-accent-low: #e0e0ff;
|
||||
--sl-color-accent: #8C8CFF;
|
||||
--sl-color-accent-high: #4141FF;
|
||||
|
||||
/* Text colors */
|
||||
--sl-color-white: #1e293b;
|
||||
--sl-color-gray-1: #334155;
|
||||
--sl-color-gray-2: #475569;
|
||||
--sl-color-gray-3: #64748b;
|
||||
--sl-color-gray-4: #94a3b8;
|
||||
--sl-color-gray-5: #cbd5e1;
|
||||
--sl-color-gray-6: #e2e8f0;
|
||||
--sl-color-black: #f8fafc;
|
||||
|
||||
/* Font settings */
|
||||
--sl-font: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue',
|
||||
Arial, sans-serif;
|
||||
--sl-text-base: 1rem;
|
||||
--sl-line-height: 1.7;
|
||||
|
||||
/* Code highlighting */
|
||||
--sl-color-bg-inline-code: rgba(140, 140, 255, 0.1);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
COLOR PALETTE - Dark Mode (Primary Focus)
|
||||
============================================ */
|
||||
:root[data-theme='dark'] {
|
||||
/* Primary accent colors - purple to match Docusaurus */
|
||||
--sl-color-accent-low: #2a2a5a;
|
||||
--sl-color-accent: #8C8CFF;
|
||||
--sl-color-accent-high: #B9B9FF;
|
||||
|
||||
/* Background colors */
|
||||
--sl-color-bg: #1b1b1d;
|
||||
--sl-color-bg-nav: #1b1b1d;
|
||||
--sl-color-bg-sidebar: #1b1b1d;
|
||||
--sl-color-hairline-light: rgba(140, 140, 255, 0.1);
|
||||
--sl-color-hairline: rgba(140, 140, 255, 0.15);
|
||||
|
||||
/* Text colors */
|
||||
--sl-color-white: #f8fafc;
|
||||
--sl-color-gray-1: #e2e8f0;
|
||||
--sl-color-gray-2: #cbd5e1;
|
||||
--sl-color-gray-3: #94a3b8;
|
||||
--sl-color-gray-4: #64748b;
|
||||
--sl-color-gray-5: #475569;
|
||||
--sl-color-gray-6: #334155;
|
||||
--sl-color-black: #1b1b1d;
|
||||
|
||||
/* Code highlighting */
|
||||
--sl-color-bg-inline-code: rgba(140, 140, 255, 0.15);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
TYPOGRAPHY
|
||||
============================================ */
|
||||
.sl-markdown-content h1 {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.sl-markdown-content h2 {
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.sl-markdown-content h3 {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.sl-markdown-content p {
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
SIDEBAR & NAVIGATION
|
||||
Clean styling inspired by React Native docs
|
||||
============================================ */
|
||||
|
||||
/* Base transition for all sidebar links */
|
||||
.sidebar-content a {
|
||||
transition:
|
||||
background-color 0.15s ease,
|
||||
color 0.15s ease,
|
||||
border-color 0.15s ease;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Top-level sidebar items (Diataxis categories) */
|
||||
.sidebar-content > ul > li > details > summary,
|
||||
.sidebar-content > ul > li > a {
|
||||
font-weight: 700;
|
||||
font-size: 0.9375rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
}
|
||||
|
||||
/* Nested sidebar items */
|
||||
.sidebar-content ul ul a {
|
||||
font-weight: 500;
|
||||
font-size: 0.875rem;
|
||||
padding: 0.375rem 0.75rem;
|
||||
padding-left: 1.5rem;
|
||||
border-left: 3px solid transparent;
|
||||
}
|
||||
|
||||
/* Deep nested items */
|
||||
.sidebar-content ul ul ul a {
|
||||
font-weight: 400;
|
||||
font-size: 0.8125rem;
|
||||
padding-left: 2.25rem;
|
||||
}
|
||||
|
||||
/* Active state - thin left accent bar */
|
||||
.sidebar-content a[aria-current='page'] {
|
||||
background-color: rgba(140, 140, 255, 0.08);
|
||||
color: var(--sl-color-accent);
|
||||
border-left-color: var(--sl-color-accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .sidebar-content a[aria-current='page'] {
|
||||
background-color: rgba(140, 140, 255, 0.1);
|
||||
color: var(--sl-color-accent-high);
|
||||
border-left-color: var(--sl-color-accent);
|
||||
}
|
||||
|
||||
/* Hover states */
|
||||
.sidebar-content a:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .sidebar-content a:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
/* Section spacing */
|
||||
.sidebar-content > ul > li {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
.sidebar-content > ul > li:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* Lighter chevrons/carets */
|
||||
.sidebar-content summary::marker,
|
||||
.sidebar-content details > summary::after {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.sidebar-content summary:hover::marker,
|
||||
.sidebar-content details > summary:hover::after {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
LAYOUT - Fixed width at large viewport
|
||||
============================================ */
|
||||
.content-panel {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Main content area */
|
||||
main {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.sl-markdown-content {
|
||||
min-width: 0;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/* Hide breadcrumbs if desired */
|
||||
/* Uncomment to hide:
|
||||
nav[aria-label="Breadcrumb"] {
|
||||
display: none;
|
||||
}
|
||||
*/
|
||||
|
||||
/* ============================================
|
||||
NAVBAR
|
||||
============================================ */
|
||||
header.header {
|
||||
padding: 0 !important; /* Remove all padding for full-width banner */
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
height: var(--sl-nav-height) !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
header.header .header.sl-flex {
|
||||
padding: 0 1.5rem;
|
||||
height: calc(var(--sl-nav-height) - var(--ai-banner-height));
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] header.header {
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Logo sizing - constrain to reasonable size */
|
||||
.site-title img {
|
||||
height: 2.5rem;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* Social links styling */
|
||||
.social-icons a {
|
||||
padding: 0.5rem;
|
||||
transition:
|
||||
background-color 0.15s ease,
|
||||
color 0.15s ease;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.social-icons a:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .social-icons a:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
CARDS
|
||||
============================================ */
|
||||
.card {
|
||||
border-radius: 12px;
|
||||
border: 2px solid var(--sl-color-gray-5);
|
||||
background-color: var(--sl-color-bg);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
transition:
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease,
|
||||
border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-3px);
|
||||
border-color: var(--sl-color-accent);
|
||||
box-shadow: 0 8px 24px rgba(140, 140, 255, 0.15);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .card {
|
||||
background: linear-gradient(145deg, rgba(30, 41, 59, 0.6), rgba(15, 23, 42, 0.8));
|
||||
border-color: rgba(140, 140, 255, 0.2);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .card:hover {
|
||||
border-color: rgba(140, 140, 255, 0.5);
|
||||
box-shadow:
|
||||
0 8px 32px rgba(140, 140, 255, 0.2),
|
||||
0 0 0 1px rgba(140, 140, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Starlight card grid */
|
||||
.sl-link-card {
|
||||
border-radius: 12px;
|
||||
border: 2px solid var(--sl-color-gray-5);
|
||||
transition:
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease,
|
||||
border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.sl-link-card:hover {
|
||||
transform: translateY(-3px);
|
||||
border-color: var(--sl-color-accent);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .sl-link-card {
|
||||
border-color: rgba(140, 140, 255, 0.2);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .sl-link-card:hover {
|
||||
border-color: rgba(140, 140, 255, 0.5);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
BUTTONS
|
||||
============================================ */
|
||||
.sl-flex a[href],
|
||||
button {
|
||||
transition:
|
||||
background-color 0.2s ease,
|
||||
transform 0.1s ease;
|
||||
}
|
||||
|
||||
.sl-flex a[href]:hover,
|
||||
button:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
MISC ENHANCEMENTS
|
||||
============================================ */
|
||||
|
||||
/* Smooth scrolling */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Better link underlines */
|
||||
.sl-markdown-content a:not(.sl-link-card) {
|
||||
text-decoration-thickness: 1px;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Table styling */
|
||||
table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] table {
|
||||
border-color: rgba(140, 140, 255, 0.1);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] table th {
|
||||
background-color: rgba(140, 140, 255, 0.05);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] table tr:nth-child(2n) {
|
||||
background-color: rgba(140, 140, 255, 0.02);
|
||||
}
|
||||
|
||||
/* Blockquotes */
|
||||
blockquote {
|
||||
border-left-color: var(--sl-color-accent);
|
||||
background-color: rgba(140, 140, 255, 0.05);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1rem 1.25rem;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
ADMONITIONS (Starlight Asides)
|
||||
Rounded, no left border bar
|
||||
============================================ */
|
||||
.starlight-aside {
|
||||
margin-bottom: 1.5rem;
|
||||
padding: 1.25rem 1.5rem;
|
||||
border-radius: 12px;
|
||||
border: none;
|
||||
border-left: 0;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
/* Tip aside */
|
||||
.starlight-aside--tip {
|
||||
background-color: rgba(16, 185, 129, 0.08);
|
||||
}
|
||||
|
||||
.starlight-aside--tip .starlight-aside__title {
|
||||
color: #059669;
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .starlight-aside--tip {
|
||||
background-color: rgba(16, 185, 129, 0.12);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .starlight-aside--tip .starlight-aside__title {
|
||||
color: #34d399;
|
||||
}
|
||||
|
||||
/* Note aside */
|
||||
.starlight-aside--note {
|
||||
background-color: rgba(140, 140, 255, 0.08);
|
||||
}
|
||||
|
||||
.starlight-aside--note .starlight-aside__title {
|
||||
color: #8C8CFF;
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .starlight-aside--note {
|
||||
background-color: rgba(140, 140, 255, 0.12);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .starlight-aside--note .starlight-aside__title {
|
||||
color: #8C8CFF;
|
||||
}
|
||||
|
||||
/* Caution aside */
|
||||
.starlight-aside--caution {
|
||||
background-color: rgba(245, 158, 11, 0.1);
|
||||
}
|
||||
|
||||
.starlight-aside--caution .starlight-aside__title {
|
||||
color: #d97706;
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .starlight-aside--caution {
|
||||
background-color: rgba(245, 158, 11, 0.15);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .starlight-aside--caution .starlight-aside__title {
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
/* Danger aside */
|
||||
.starlight-aside--danger {
|
||||
background-color: rgba(239, 68, 68, 0.1);
|
||||
}
|
||||
|
||||
.starlight-aside--danger .starlight-aside__title {
|
||||
color: #dc2626;
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .starlight-aside--danger {
|
||||
background-color: rgba(239, 68, 68, 0.15);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] .starlight-aside--danger .starlight-aside__title {
|
||||
color: #f87171;
|
||||
}
|
||||
|
||||
/* Aside icon styling */
|
||||
.starlight-aside__icon svg {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
FOOTER - Minimal styling
|
||||
============================================ */
|
||||
footer {
|
||||
background-color: var(--sl-color-black);
|
||||
border-top: 1px solid var(--sl-color-hairline);
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] footer {
|
||||
background-color: #020617;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
RESPONSIVE ADJUSTMENTS
|
||||
============================================ */
|
||||
@media (max-width: 72rem) {
|
||||
.content-panel {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive padding on navbar row only - banner stays full-width */
|
||||
@media (min-width: 50rem) {
|
||||
header.header .header.sl-flex {
|
||||
padding-left: 2.5rem;
|
||||
padding-right: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 72rem) {
|
||||
header.header .header.sl-flex {
|
||||
padding-left: 3rem;
|
||||
padding-right: 3rem;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user