Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Scaffolds a complete React/Vite website project from site-config.json. Generates components, styles, and configuration based on the site type and plan data.
.claude/skills/grcengclub-website-build/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | -4% | 0% |
| case-10 | ✗→✓ | ▲ Improved | -12% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 38% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 46% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 46% | 0% |
You are running the /grc-portfolio:build skill. Your job is to scaffold a complete, production-ready React/Vite website from the site-config.json created by /grc-portfolio:plan.
Find site-config.json:
$ARGUMENTS for a project directory pathRead it and validate that status.planComplete === true. If not, tell the user to run /grc-portfolio:plan first.
Read the siteType field to determine which components to generate.
Create the following structure in the project directory:
src/
main.jsx
App.jsx
App.css
index.css
components/
Navbar.jsx
Hero.jsx
Footer.jsx
ContactForm.jsx (if features.contactForm)
... (type-specific components)
assets/
index.html (Vite's entry HTML, references /src/main.jsx)
public/
favicon.svg
package.json
vite.config.js
.env.example
.gitignoreBase it on the toolkit's examples/package.json at $TOOLKIT_DIR/examples/package.json. Customize:
name to the projectName from configCopy from $TOOLKIT_DIR/examples/vite.config.js as-is. It's already well-configured for AWS deployment.
Navbar.jsx -- Navigation bar with:
pages array from configHero.jsx -- Full-width hero section with:
design.ctaPreferenceFooter.jsx -- Footer with:
ContactForm.jsx (if features.contactForm):
VITE_CONTACT_API_ENDPOINT env varCSS reset and base styles. Set CSS custom properties based on design.colorScheme:
navy-slate (GRC default):
css--color-primary: #1e3a5f; --color-primary-dark: #152a45; --color-secondary: #64748b; --color-accent: #3b82f6; --color-bg: #ffffff; --color-bg-alt: #f8fafc; --color-text: #1e293b; --color-text-light: #64748b;
dark-charcoal:
css--color-primary: #818cf8; --color-primary-dark: #6366f1; --color-secondary: #94a3b8; --color-accent: #22d3ee; --color-bg: #0f172a; --color-bg-alt: #1e293b; --color-text: #f1f5f9; --color-text-light: #94a3b8;
white-teal:
css--color-primary: #0d9488; --color-primary-dark: #0f766e; --color-secondary: #64748b; --color-accent: #06b6d4; --color-bg: #ffffff; --color-bg-alt: #f0fdfa; --color-text: #1e293b; --color-text-light: #64748b;
If design.colorScheme is "custom", use design.primaryColor and design.accentColor from config and derive the rest.
Component-level styles. Use the CSS custom properties from index.css. Style should match design.style:
main.jsx:
jsximport React from 'react' import ReactDOM from 'react-dom/client' import App from './App.jsx' import './index.css' ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <App /> </React.StrictMode>, )
App.jsx: Import and compose all generated components in order. Use a single-page layout with sections. Include smooth scrolling.
Write this file at the project root (<projectDir>/index.html), not under public/. Vite resolves the entry HTML from the project root, and /src/main.jsx is referenced as an absolute project-root path:
html<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="description" content="{{site description from config}}" /> <title>{{site title from config}}</title> </head> <body> <div id="root"></div> <script type="module" src="/src/main.jsx"></script> </body> </html>
.env.example:
# Contact Form API endpoint (from /grc-portfolio:infra deployment)
VITE_CONTACT_API_ENDPOINT=.gitignore:
node_modules
dist
.env
.env.local
.DS_Store
*.logIf features.contactForm is true, copy $TOOLKIT_DIR/lambda/contact-form-handler.js into a lambda/ directory in the project.
Run:
bashcd <projectDir> npm install npm run build
If the build fails, fix the errors. Common issues:
Update site-config.json:
status.buildComplete = trueTell the user:
<projectDir>npm run dev to preview locally/grc-portfolio:preflight next to check AWS readiness$TOOLKIT_DIR = read from site-config.json toolkitDir field$ARGUMENTS = arguments passed after /build (expected: project directory path)| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 14,063 | 27,441 | +95% | 1 | 1 | 0% | 2,812 | 2,387 | -15% | 0 | 0 | — |
case-02 | fail→fail | 30,932 | 1,628 | -95% | 1 | 1 | 0% | 6,187 | 2,387 | -61% | 0 | 0 | — |
case-03 | pass→pass | 19,008 | 4,381 | -77% | 1 | 1 | 0% | 3,262 | 2,883 | -12% | 0 | 0 | — |
case-04 | pass→pass | 9,161 | 5,085 | -44% | 1 | 1 | 0% | 1,400 | 2,938 | +110% | 0 | 0 | — |
case-22 | pass→pass | 9,136 | 2,887 | -68% | 1 | 1 | 0% | 1,546 | 2,597 | +68% | 0 | 0 | — |
case-05 | pass→fail | 12,385 | 22,498 | +82% | 1 | 1 | 0% | 2,037 | 2,425 | +19% | 0 | 0 | — |
case-06 | pass→fail | 6,728 | 2,217 | -67% | 1 | 1 | 0% | 1,020 | 2,459 | +141% | 0 | 0 | — |
case-07 | pass→pass | 7,525 | 6,126 | -19% | 1 | 1 | 0% | 1,249 | 3,186 | +155% | 0 | 0 | — |
case-08 | fail→fail | 31,119 | 3,959 | -87% | 1 | 1 | 0% | 6,183 | 2,398 | -61% | 0 | 0 | — |
case-09 | fail→pass | 15,440 | 4,335 | -72% | 1 | 1 | 0% | 3,149 | 3,012 | -4% | 0 | 0 | — |
case-10 | fail→pass | 16,765 | 3,355 | -80% | 1 | 1 | 0% | 3,228 | 2,851 | -12% | 0 | 0 | — |
case-11 | fail→pass | 12,165 | 2,681 | -78% | 1 | 1 | 0% | 1,937 | 2,670 | +38% | 0 | 0 | — |
case-12 | fail→pass | 11,988 | 4,985 | -58% | 1 | 1 | 0% | 2,000 | 2,929 | +46% | 0 | 0 | — |
case-13 | fail→pass | 11,775 | 3,145 | -73% | 1 | 1 | 0% | 1,850 | 2,700 | +46% | 0 | 0 | — |
case-14 | fail→fail | 7,018 | 2,176 | -69% | 1 | 1 | 0% | 1,214 | 2,528 | +108% | 0 | 0 | — |
case-15 | pass→fail | 11,127 | 3,905 | -65% | 1 | 1 | 0% | 1,806 | 2,842 | +57% | 0 | 0 | — |
case-16 | fail→pass | 14,876 | 4,239 | -72% | 1 | 1 | 0% | 2,499 | 2,856 | +14% | 0 | 0 | — |
case-17 | fail→pass | 11,049 | 3,074 | -72% | 1 | 1 | 0% | 1,931 | 2,655 | +37% | 0 | 0 | — |
case-18 | fail→pass | 8,348 | 3,235 | -61% | 1 | 1 | 0% | 1,280 | 2,706 | +111% | 0 | 0 | — |
case-19 | fail→fail | 6,359 | 1,763 | -72% | 1 | 1 | 0% | 934 | 2,394 | +156% | 0 | 0 | — |
case-20 | fail→pass | 9,132 | 1,327 | -85% | 1 | 1 | 0% | 1,416 | 2,378 | +68% | 0 | 0 | — |
case-21 | fail→fail | 10,014 | 5,331 | -47% | 1 | 1 | 0% | 1,883 | 2,944 | +56% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 19 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +27 percentage points is the difference between those two pass rates over the 19 comparable cases. 5 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.