@kennethsolomon/shipkit 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -102,7 +102,7 @@ Brainstorm → Plan → Branch → [Schema] → Write Tests → Implement → Co
102
102
  | 19 | `/sk:smart-commit` | Auto-skip if already clean |
103
103
  | 20 | **`/sk:review`** | **GATE** — Review + Simplify — 0 issues including nitpicks |
104
104
  | 21 | `/sk:smart-commit` | Auto-skip if already clean |
105
- | 22 | **`/sk:e2e`** | **GATE** — E2E Tests — all end-to-end tests must pass |
105
+ | 22 | **`/sk:e2e`** | **GATE** — E2E Tests — prefers Playwright CLI when config detected, falls back to agent-browser; all scenarios must pass |
106
106
  | 23 | `/sk:smart-commit` | Auto-skip if already clean |
107
107
  | 24 | `/sk:update-task` | Mark done, log completion |
108
108
  | 25 | `/sk:finish-feature` | Changelog + PR |
@@ -196,6 +196,12 @@ Requirement changes → /sk:change → re-enter at correct step
196
196
  | `/sk:debug` | Structured bug investigation: reproduce → isolate → fix |
197
197
  | `/sk:hotfix` | Emergency fix workflow — skips design and TDD |
198
198
 
199
+ ### Prototyping
200
+
201
+ | Command | Description |
202
+ |---------|-------------|
203
+ | `/sk:mvp` | Generate a complete MVP from a single idea prompt — landing page with waitlist + working app with fake data. Supports Next.js, Nuxt, Laravel, React+Vite. Optional Pencil MCP design phase and Playwright MCP visual validation. |
204
+
199
205
  ### Quality Gates
200
206
 
201
207
  | Command | Description |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kennethsolomon/shipkit",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "A structured workflow toolkit for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: sk:e2e
3
- description: "Run E2E behavioral verification using agent-browser as the final quality gate before finalize. Tests the complete, reviewed, secure implementation from a user's perspective."
3
+ description: "Run E2E behavioral verification as the final quality gate before finalize. Prefers Playwright CLI when playwright.config.ts is detected; falls back to agent-browser otherwise. Tests the complete, reviewed, secure implementation from a user's perspective."
4
4
  ---
5
5
 
6
6
  # /sk:e2e
@@ -22,22 +22,97 @@ Read these files to understand what to test:
22
22
  - `tasks/findings.md` — design decisions and expected behaviors
23
23
  - `tasks/progress.md` — implementation notes
24
24
 
25
- ### 2. Check agent-browser is Available
25
+ ### 2. Detect E2E Runner
26
+
27
+ Check which runner is available, in priority order:
28
+
29
+ **Priority 1 — Playwright (preferred)**
30
+
31
+ ```bash
32
+ ls playwright.config.ts 2>/dev/null || ls playwright.config.js 2>/dev/null
33
+ ```
34
+
35
+ If a Playwright config exists → use Playwright CLI (Step 3a). This is the preferred path because:
36
+ - Uses headless Chromium (no conflict with system Chrome)
37
+ - No additional global install required (`@playwright/test` in devDeps)
38
+ - Test files in `e2e/` or `tests/e2e/` are picked up automatically
39
+ - `webServer` in `playwright.config.ts` auto-starts the dev server
40
+
41
+ **Playwright config requirements** (verify before running):
42
+ - `headless: true` must be set under `use:`
43
+ - `channel: undefined` (or omitted) — must NOT be `'chrome'` or `'msedge'` to avoid system browser conflicts
44
+ - `webServer.reuseExistingServer: true` — avoids double-starting the dev server
45
+
46
+ If config has `channel: 'chrome'` or `headless: false`, warn:
47
+ > "playwright.config.ts uses system Chrome or headed mode — this may conflict with a running browser. Consider setting `headless: true` and `channel: undefined`."
48
+
49
+ **Priority 2 — agent-browser (fallback)**
26
50
 
27
51
  ```bash
28
52
  agent-browser --version
29
53
  ```
30
54
 
31
- If not found, instruct the user:
55
+ Only use `agent-browser` if NO `playwright.config.ts` / `playwright.config.js` exists.
56
+
57
+ If `agent-browser` is also not found, AND no Playwright config exists:
58
+
32
59
  ```
33
- agent-browser is required. Install it:
60
+ Neither Playwright nor agent-browser is configured. To fix permanently:
61
+
62
+ Option A (recommended) — Playwright:
63
+ npm install -D @playwright/test
64
+ npx playwright install chromium
65
+ # Create playwright.config.ts with headless: true, channel: undefined
66
+
67
+ Option B — agent-browser:
34
68
  npm install -g agent-browser
35
- agent-browser install # downloads Chrome (~100MB)
69
+ agent-browser install
70
+
36
71
  Then re-run /sk:e2e.
37
72
  ```
38
- Stop if not available.
73
+ Stop if neither runner is available.
74
+
75
+ ### 3a. Run E2E via Playwright CLI
76
+
77
+ Locate test files:
78
+ ```bash
79
+ ls e2e/ 2>/dev/null
80
+ ls tests/e2e/ 2>/dev/null
81
+ find . -name "*.spec.ts" -not -path "*/node_modules/*"
82
+ ```
83
+
84
+ If spec files exist, run them:
85
+ ```bash
86
+ npx playwright test --reporter=list
87
+ ```
88
+
89
+ To run a specific file:
90
+ ```bash
91
+ npx playwright test e2e/my-feature.spec.ts --reporter=list
92
+ ```
93
+
94
+ To run with visible output on failure:
95
+ ```bash
96
+ npx playwright test --reporter=list 2>&1
97
+ ```
98
+
99
+ **Interpreting results:**
100
+ - Exit code 0 = all tests passed
101
+ - Exit code 1 = one or more tests failed (output includes which tests and why)
102
+ - Each failing test shows: test name, expected vs. actual, screenshot path (if `trace: 'on-first-retry'` is set)
103
+
104
+ If no spec files exist → derive scenarios from `tasks/todo.md` acceptance criteria and write them to `e2e/<feature>.spec.ts` before running. Follow the test file patterns already present in the project (check `e2e/helpers/` for shared utilities).
39
105
 
40
- ### 3. Detect Local Server
106
+ After running, record for each test:
107
+ - Test name / suite
108
+ - Result: PASS or FAIL
109
+ - On FAIL: error message and relevant snapshot
110
+
111
+ Skip to **Step 5 (Report Results)**.
112
+
113
+ ### 3b. Detect Local Server (agent-browser path only)
114
+
115
+ Only needed if using agent-browser (Playwright's `webServer` handles this automatically).
41
116
 
42
117
  Determine what URL to test against:
43
118
  - Check for a dev server command in `package.json` scripts (`dev`, `start`)
@@ -46,7 +121,7 @@ Determine what URL to test against:
46
121
  - If a server is already running (check common ports: 3000, 5173, 8000, 8080), use it
47
122
  - If no server is running, start one in the background and note the URL
48
123
 
49
- ### 4. Locate E2E Test Files
124
+ ### 4. Locate E2E Test Files (agent-browser path only)
50
125
 
51
126
  Find E2E test scenarios written during the Write Tests step:
52
127
  ```bash
@@ -56,7 +131,7 @@ ls tests/e2e/ 2>/dev/null
56
131
 
57
132
  If no E2E test files exist, derive scenarios from `tasks/todo.md` acceptance criteria and `tasks/findings.md`.
58
133
 
59
- ### 5. Run E2E Scenarios
134
+ ### 4b. Run E2E Scenarios via agent-browser
60
135
 
61
136
  For each scenario, use agent-browser following this core pattern:
62
137
 
@@ -90,9 +165,10 @@ For each scenario, record:
90
165
  - Result: PASS or FAIL
91
166
  - On FAIL: what was expected vs. what was found (include snapshot excerpt)
92
167
 
93
- ### 6. Report Results
168
+ ### 5. Report Results
94
169
 
95
170
  ```
171
+ E2E Runner: Playwright CLI (or: agent-browser)
96
172
  E2E Results:
97
173
  PASS [scenario name]
98
174
  PASS [scenario name]
@@ -130,6 +206,81 @@ If failures remain after fixes:
130
206
 
131
207
  ---
132
208
 
209
+ ## Playwright Setup Reference
210
+
211
+ When setting up Playwright for the first time in a project:
212
+
213
+ ```bash
214
+ npm install -D @playwright/test
215
+ npx playwright install chromium
216
+ ```
217
+
218
+ Minimal `playwright.config.ts` (headless, no system Chrome conflict):
219
+
220
+ ```ts
221
+ import { defineConfig, devices } from '@playwright/test'
222
+
223
+ export default defineConfig({
224
+ testDir: './e2e',
225
+ fullyParallel: true,
226
+ retries: process.env.CI ? 2 : 0,
227
+ reporter: 'list',
228
+ use: {
229
+ baseURL: process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:3000',
230
+ headless: true, // REQUIRED — avoids system Chrome conflict
231
+ trace: 'on-first-retry',
232
+ },
233
+ projects: [
234
+ {
235
+ name: 'chromium',
236
+ use: { ...devices['Desktop Chrome'], channel: undefined }, // REQUIRED — use Playwright's Chromium, not system Chrome
237
+ },
238
+ ],
239
+ webServer: {
240
+ command: 'npm run dev', // or 'php artisan serve', 'yarn dev', etc.
241
+ url: 'http://localhost:3000',
242
+ reuseExistingServer: true,
243
+ timeout: 120_000,
244
+ },
245
+ })
246
+ ```
247
+
248
+ E2E test helpers go in `e2e/helpers/`. Auth helper pattern:
249
+
250
+ ```ts
251
+ // e2e/helpers/auth.ts
252
+ import { Page } from '@playwright/test'
253
+
254
+ export async function signIn(page: Page, email: string, password: string) {
255
+ await page.goto('/login')
256
+ await page.getByLabel(/email/i).fill(email)
257
+ await page.getByLabel(/password/i).fill(password)
258
+ await page.getByRole('button', { name: /sign in|log in/i }).click()
259
+ await page.waitForURL('/dashboard', { timeout: 15_000 })
260
+ }
261
+
262
+ export const TEST_USERS = {
263
+ regular: {
264
+ email: process.env.E2E_USER_EMAIL ?? '',
265
+ password: process.env.E2E_USER_PASSWORD ?? '',
266
+ },
267
+ admin: {
268
+ email: process.env.E2E_ADMIN_EMAIL ?? '',
269
+ password: process.env.E2E_ADMIN_PASSWORD ?? '',
270
+ },
271
+ }
272
+ ```
273
+
274
+ Test credentials go in `.env.local` (never hardcoded):
275
+ ```
276
+ E2E_USER_EMAIL=...
277
+ E2E_USER_PASSWORD=...
278
+ E2E_ADMIN_EMAIL=...
279
+ E2E_ADMIN_PASSWORD=...
280
+ ```
281
+
282
+ ---
283
+
133
284
  ## Model Routing
134
285
 
135
286
  Read `.shipkit/config.json` from the project root if it exists.
@@ -0,0 +1,266 @@
1
+ ---
2
+ name: sk:mvp
3
+ description: Generate a complete MVP validation app from a prompt — landing page with waitlist + working app with fake data. Use this skill when the user wants to quickly validate a product idea, build a proof of concept, create a landing page with email collection, scaffold an MVP, build a prototype for market validation, or test if an idea is worth pursuing. Produces a full working codebase locally.
4
+ compatibility: Optional — Pencil MCP (for visual mockups), Playwright MCP (for visual validation)
5
+ ---
6
+
7
+ # /sk:mvp — MVP Validation App Generator
8
+
9
+ Generate a complete, aesthetically polished MVP from a single idea prompt. Outputs a landing page with waitlist email collection + a working app with fake data. Purpose: validate market interest before investing in a full build.
10
+
11
+ ## Hard Rules
12
+
13
+ - Generate ALL code locally — never deploy, push, or publish anything.
14
+ - Landing page is MANDATORY for every MVP. Never skip it.
15
+ - Use FAKE data only — no real databases, no auth systems, no third-party API integrations.
16
+ - Every page must be functional: buttons navigate, forms submit, modals open/close.
17
+ - Design must be distinctive and polished — never use default Tailwind colors or generic layouts. Read `references/design-system.md` for aesthetic guidelines.
18
+ - Keep the app secure enough (no XSS, no open redirects) but don't over-engineer security for a prototype.
19
+
20
+ ---
21
+
22
+ ## Step 1 — Gather the Idea
23
+
24
+ Ask the user to describe their product idea. If not already provided, ask:
25
+
26
+ > **What's your product idea? Describe it in 1-3 sentences — what does it do and who is it for?**
27
+
28
+ Extract from their answer:
29
+ - **Product name** (or ask them to pick one)
30
+ - **One-line value proposition**
31
+ - **Target audience**
32
+ - **Key features** (3-5 core features for the app)
33
+
34
+ Confirm your understanding before proceeding.
35
+
36
+ ---
37
+
38
+ ## Step 2 — Pick a Tech Stack
39
+
40
+ Present these preset options:
41
+
42
+ > **Pick a tech stack:**
43
+ >
44
+ > 1. **Next.js + Tailwind** — React ecosystem, SSR, API routes built-in
45
+ > 2. **Nuxt + Tailwind** — Vue ecosystem, SSR, server routes built-in
46
+ > 3. **Laravel + Blade + Tailwind** — PHP ecosystem, full backend, Blade templates
47
+ > 4. **React + Vite + Tailwind** — Lightweight SPA, no backend (waitlist via Formspree)
48
+ >
49
+ > Or type your own stack (I'll adapt).
50
+
51
+ Once the user picks, note the selection and load the corresponding reference file in Step 6.
52
+
53
+ ---
54
+
55
+ ## Step 3 — Optional Design Phase (Pencil MCP)
56
+
57
+ Check if the user invoked with `--pencil` flag or ask:
58
+
59
+ > **Would you like to design the UI visually in Pencil before coding? (Requires Pencil app + MCP) (y/n)**
60
+ >
61
+ > If no, I'll go straight to code generation with a great default design.
62
+
63
+ ### If YES — Pencil MCP Design Phase
64
+
65
+ Follow this flow (adapted from sk:frontend-design):
66
+
67
+ **3a. Find or create .pen file**
68
+ - Check `docs/design/` for existing `.pen` file matching this MVP.
69
+ - Existing: `open_document(filePath)` → skip to 3c.
70
+ - None: `open_document('new')` → save to `docs/design/{product-slug}.pen`.
71
+
72
+ **3b. Load design context**
73
+ 1. `get_guidelines(topic='landing-page')` — load landing page design rules.
74
+ 2. `get_style_guide_tags` → `get_style_guide(tags)` — pick tags matching the product's tone (e.g., modern, SaaS, minimal, bold).
75
+
76
+ **3c. Set color palette as variables**
77
+ Decide a distinctive color palette based on the product's tone and audience. Call `set_variables` with the palette:
78
+ ```json
79
+ {
80
+ "color-bg": "#xxxxxx",
81
+ "color-fg": "#xxxxxx",
82
+ "color-accent": "#xxxxxx",
83
+ "color-muted": "#xxxxxx"
84
+ }
85
+ ```
86
+
87
+ **3d. Build mockup screens**
88
+ Use `batch_design` to create:
89
+ 1. Landing page frame — hero, features, pricing, waitlist section
90
+ 2. App main screen frame — dashboard or primary view
91
+ 3. App secondary screen frame — detail view or key interaction
92
+
93
+ Work one frame per `batch_design` call. Apply the color variables and typography.
94
+
95
+ **3e. Validate and iterate**
96
+ After each frame: `get_screenshot` to inspect. If off: `snapshot_layout` → fix with `batch_design`. Iterate until the design matches the vision.
97
+
98
+ **3f. Get user approval**
99
+ Present screenshots and ask:
100
+ > **Does this design direction look good? Any changes before I start coding?**
101
+
102
+ Wait for approval. Apply feedback if given. Do not proceed to code without explicit approval.
103
+
104
+ **3g. Record the design**
105
+ Note the `.pen` file path. The design decisions (colors, typography, layout) carry forward into code generation.
106
+
107
+ ### If NO — Skip to Step 4
108
+
109
+ Use the aesthetic guidelines from `references/design-system.md` to make distinctive design choices automatically. Briefly state the design direction chosen (color scheme, typography, layout style) so the user knows what to expect.
110
+
111
+ ---
112
+
113
+ ## Step 4 — Scaffold the Project
114
+
115
+ Read the stack-specific reference file:
116
+ - Next.js → `references/stacks/nextjs.md`
117
+ - Nuxt → `references/stacks/nuxt.md`
118
+ - Laravel → `references/stacks/laravel.md`
119
+ - React + Vite → `references/stacks/react-vite.md`
120
+
121
+ Run the scaffold command from the reference file. Then customize the Tailwind config with the chosen color palette and typography.
122
+
123
+ ---
124
+
125
+ ## Step 5 — Generate the Landing Page
126
+
127
+ Read `references/landing-page.md` for section patterns and structure.
128
+
129
+ Generate a complete landing page with these sections (all mandatory):
130
+
131
+ 1. **Navbar** — logo/product name + nav links (Features, Pricing, Waitlist) + CTA button
132
+ 2. **Hero** — headline (benefit-driven) + subheadline + primary CTA + hero visual/illustration area
133
+ 3. **Social proof bar** — "Trusted by X+" or logo strip (use placeholder logos)
134
+ 4. **Features grid** — 3-6 feature cards with icons, titles, descriptions (based on the key features from Step 1)
135
+ 5. **How it works** — 3-step process with numbered steps and descriptions
136
+ 6. **Pricing** — 2-3 tier cards (Free / Pro / Enterprise) with fake but realistic pricing
137
+ 7. **Testimonials** — 2-3 fake testimonial cards with names, roles, photos (use placeholder avatars)
138
+ 8. **Waitlist / CTA section** — email input + submit button + success message + form validation
139
+ 9. **Footer** — product name, links, copyright
140
+
141
+ ### Waitlist Email Collection
142
+
143
+ **For stacks with backend (Next.js, Nuxt, Laravel):**
144
+ - Create an API route that accepts POST `{ email }`.
145
+ - Validate the email format server-side.
146
+ - Read existing `waitlist.json`, append the new entry with timestamp, write back.
147
+ - Return success/error JSON response.
148
+ - Wire the landing page form to POST to this route via fetch.
149
+ - Show success state ("You're on the list!") and error state on the form.
150
+
151
+ **For static stacks (React + Vite):**
152
+ - Use Formspree: form action points to `https://formspree.io/f/{form_id}`.
153
+ - Add a comment/note telling the user to create a free Formspree account and replace `{form_id}`.
154
+ - Handle success/error states client-side.
155
+
156
+ ---
157
+
158
+ ## Step 6 — Generate the App
159
+
160
+ Generate a working multi-page app with:
161
+
162
+ 1. **Navigation** — sidebar or top nav with links to all pages. Active state highlighting.
163
+ 2. **Dashboard / Home** — summary cards, charts (use simple CSS/SVG charts or placeholder), recent activity list. All fake data.
164
+ 3. **Primary feature page** — the main thing the product does. Functional UI with fake data. Buttons, modals, forms all work (client-side only).
165
+ 4. **Secondary feature page** — a supporting feature. Table or list view with filtering/sorting (client-side).
166
+ 5. **Settings / Profile page** — simple form with fake prefilled data. Save button shows a toast/notification.
167
+
168
+ ### Design Standards (apply to every page)
169
+
170
+ Read `references/design-system.md` and apply:
171
+ - Distinctive color palette — never default Tailwind. Custom `tailwind.config` colors.
172
+ - Thoughtful typography — use Google Fonts. Pair a display font with a body font.
173
+ - Consistent spacing scale — use a rhythm (e.g., 4/8/12/16/24/32/48).
174
+ - Polished components — rounded corners, shadows, hover states, transitions.
175
+ - Responsive — must look good on mobile and desktop.
176
+ - Fake data should feel realistic — use real-sounding names, numbers, dates.
177
+
178
+ ---
179
+
180
+ ## Step 7 — Visual Validation (Playwright MCP)
181
+
182
+ After code generation is complete, validate the output visually.
183
+
184
+ **If Playwright MCP is available:**
185
+
186
+ 1. Start the dev server (use the stack's dev command from the reference file).
187
+ 2. Use Playwright MCP to navigate to each page:
188
+ - Landing page (`/`)
189
+ - Dashboard (`/dashboard`)
190
+ - Each app page
191
+ 3. Take screenshots of each page at desktop (1280px) and mobile (375px) widths.
192
+ 4. Check for:
193
+ - Broken layouts (overlapping elements, overflow, misaligned sections)
194
+ - Missing content (empty sections, broken images, placeholder text not filled)
195
+ - Non-functional interactions (click buttons, submit forms, open modals)
196
+ - Visual consistency (colors match palette, typography is consistent)
197
+ 5. If issues found: fix them and re-validate.
198
+
199
+ **If Playwright MCP is NOT available:**
200
+
201
+ Tell the user:
202
+ > Playwright MCP is not connected — skipping visual validation. Start the dev server with `{dev command}` and check the pages manually.
203
+
204
+ ---
205
+
206
+ ## Step 8 — Quality Loop
207
+
208
+ If visual validation found issues:
209
+
210
+ 1. Fix the identified issues.
211
+ 2. Re-run Playwright validation (Step 7).
212
+ 3. Repeat until all pages pass — no broken layouts, all interactions work, design is consistent.
213
+
214
+ Maximum 3 loop iterations. If issues persist after 3 loops, present remaining issues to the user and ask how to proceed.
215
+
216
+ ---
217
+
218
+ ## Step 9 — Present the Output
219
+
220
+ Summarize what was generated:
221
+
222
+ ```
223
+ ## MVP Generated
224
+
225
+ **Product:** {name}
226
+ **Stack:** {stack}
227
+ **Files:** {count} files generated
228
+
229
+ ### Landing Page
230
+ - URL: http://localhost:{port}/
231
+ - Sections: hero, features, pricing, waitlist, testimonials
232
+ - Waitlist: {API route path or Formspree}
233
+
234
+ ### App Pages
235
+ - Dashboard: http://localhost:{port}/dashboard
236
+ - {Feature 1}: http://localhost:{port}/{path}
237
+ - {Feature 2}: http://localhost:{port}/{path}
238
+ - Settings: http://localhost:{port}/settings
239
+
240
+ ### Start the dev server
241
+ {exact command to run}
242
+
243
+ ### What's next
244
+ - Review the generated code and tweak the design to your liking
245
+ - Replace placeholder content with your real copy
246
+ - Replace fake data with real API integrations when ready
247
+ - Deploy when you're happy with it
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Model Routing
253
+
254
+ Read `.shipkit/config.json` from the project root if it exists.
255
+
256
+ - If `model_overrides["sk:mvp"]` is set, use that model — it takes precedence.
257
+ - Otherwise use the `profile` field. Default: `balanced`.
258
+
259
+ | Profile | Model |
260
+ |---------|-------|
261
+ | `full-sail` | opus (inherit) |
262
+ | `quality` | opus (inherit) |
263
+ | `balanced` | sonnet |
264
+ | `budget` | sonnet |
265
+
266
+ > `opus` = inherit (uses the current session model). When spawning sub-agents via the Agent tool, pass `model: "<resolved-model>"`.
@@ -0,0 +1,136 @@
1
+ # Design System — MVP Aesthetic Guidelines
2
+
3
+ Guidelines for generating visually distinctive MVPs that don't look like generic AI output.
4
+
5
+ ---
6
+
7
+ ## Core Principle
8
+
9
+ Every MVP must look **intentionally designed**, not template-generated. The goal is to make visitors think "this looks legit" — good enough to trust with their email and time.
10
+
11
+ ---
12
+
13
+ ## Typography
14
+
15
+ ### Rules
16
+ - Always use **two fonts**: one display/heading font + one body font.
17
+ - Source from Google Fonts. Never use system fonts, Inter, Roboto, or Arial as the primary choice.
18
+ - Vary choices between projects — do not converge on the same fonts repeatedly.
19
+
20
+ ### Suggested Pairings (rotate, don't default to #1)
21
+ 1. **DM Serif Display** + **DM Sans** — editorial, trustworthy
22
+ 2. **Playfair Display** + **Source Sans 3** — luxury, refined
23
+ 3. **Space Grotesk** + **Inter** — tech, modern (use sparingly, very common)
24
+ 4. **Sora** + **Nunito Sans** — friendly, approachable SaaS
25
+ 5. **Clash Display** + **Satoshi** — bold, contemporary
26
+ 6. **Fraunces** + **Commissioner** — warm, distinctive
27
+ 7. **Cabinet Grotesk** + **General Sans** — clean, startup
28
+ 8. **Bricolage Grotesque** + **Geist** — editorial tech
29
+
30
+ ### Scale
31
+ Use a consistent type scale. Recommended base: `16px`.
32
+
33
+ | Element | Size | Weight | Tracking |
34
+ |---------|------|--------|----------|
35
+ | H1 (hero) | 48-72px | 700-800 | -0.02em |
36
+ | H2 (section) | 32-40px | 600-700 | -0.01em |
37
+ | H3 (card title) | 20-24px | 600 | normal |
38
+ | Body | 16-18px | 400 | normal |
39
+ | Small/caption | 13-14px | 400-500 | 0.01em |
40
+
41
+ ---
42
+
43
+ ## Color
44
+
45
+ ### Rules
46
+ - Never use default Tailwind color names without customization (`blue-500`, `gray-100` raw).
47
+ - Define a custom palette in `tailwind.config` under `extend.colors`.
48
+ - Every palette needs: background, foreground, primary accent, secondary accent, muted, border, success, error.
49
+ - Commit to a mood — don't mix warm and cool randomly.
50
+
51
+ ### Palette Strategies (pick one per project)
52
+ 1. **Dark + neon accent** — dark bg (#0a0a0a), light text (#fafafa), vibrant accent (#6366f1 or #22d3ee)
53
+ 2. **Warm neutral + earth accent** — warm white (#faf9f6), dark text (#1a1a1a), terracotta/amber accent
54
+ 3. **Cool minimal** — pure white (#ffffff), slate text (#334155), single accent color
55
+ 4. **Bold saturated** — deep colored bg (#1e1b4b), contrasting text, bright accent
56
+ 5. **Soft pastel** — light tinted bg (#f0fdf4), dark text, pastel accent palette
57
+
58
+ ### Contrast
59
+ - Text on background must meet WCAG AA (4.5:1 for body text, 3:1 for large text).
60
+ - Test accent colors against both light and dark surfaces.
61
+
62
+ ---
63
+
64
+ ## Spacing
65
+
66
+ Use a **4px base unit** with a consistent scale:
67
+
68
+ | Token | Value | Use for |
69
+ |-------|-------|---------|
70
+ | `xs` | 4px | Icon gaps, tight padding |
71
+ | `sm` | 8px | Inline spacing, compact cards |
72
+ | `md` | 16px | Default padding, form gaps |
73
+ | `lg` | 24px | Card padding, section content |
74
+ | `xl` | 32px | Section gaps |
75
+ | `2xl` | 48px | Between major sections |
76
+ | `3xl` | 64px | Hero padding, page-level spacing |
77
+ | `4xl` | 96px | Landing page section separation |
78
+
79
+ ### Layout Rhythm
80
+ - Sections on the landing page should have `py-20` to `py-28` (80-112px) vertical padding.
81
+ - Cards should have consistent `p-6` to `p-8` padding.
82
+ - The max content width should be `max-w-6xl` or `max-w-7xl`, centered.
83
+
84
+ ---
85
+
86
+ ## Components
87
+
88
+ ### Buttons
89
+ - Primary: filled with accent color, white text, `rounded-lg` or `rounded-xl`, `px-6 py-3`.
90
+ - Secondary: outlined or ghost, accent color border/text.
91
+ - Hover: subtle scale (`hover:scale-105`) or color shift. Add `transition-all duration-200`.
92
+ - Never use default browser button styles.
93
+
94
+ ### Cards
95
+ - Background slightly offset from page bg (e.g., white card on gray bg, or lighter card on dark bg).
96
+ - Consistent `rounded-xl` or `rounded-2xl`.
97
+ - Subtle shadow: `shadow-sm` or `shadow-md`. On dark themes use border instead.
98
+ - Hover state for interactive cards: lift (`hover:-translate-y-1 hover:shadow-lg`).
99
+
100
+ ### Forms / Inputs
101
+ - Inputs: `rounded-lg`, visible border, generous padding (`px-4 py-3`).
102
+ - Focus state: accent-colored ring (`focus:ring-2 focus:ring-accent`).
103
+ - Labels above inputs, not floating.
104
+ - Error states: red border + error message below.
105
+
106
+ ### Navigation
107
+ - Sticky/fixed navbar with blur backdrop (`backdrop-blur-md bg-white/80`).
108
+ - Logo/name on left, links center or right, CTA button far right.
109
+ - Mobile: hamburger menu with slide-in drawer or dropdown.
110
+
111
+ ---
112
+
113
+ ## Anti-Patterns — NEVER Do These
114
+
115
+ 1. **Default Tailwind colors** — `bg-blue-500 text-gray-700` without custom palette
116
+ 2. **System fonts** — `-apple-system, BlinkMacSystemFont` or `font-sans` without override
117
+ 3. **Flat layouts** — sections that all look the same width/padding/structure
118
+ 4. **Missing hover states** — buttons/links that don't respond to hover
119
+ 5. **Placeholder.com images** — use gradient boxes, SVG illustrations, or emoji as placeholders instead
120
+ 6. **Lorem ipsum** — generate realistic fake content based on the product context
121
+ 7. **Inconsistent spacing** — mixing random padding/margin values
122
+ 8. **Tiny click targets** — buttons and links must be minimum 44x44px touch targets
123
+ 9. **No visual hierarchy** — everything same size/weight, no emphasis
124
+ 10. **Generic hero** — "Welcome to [Product]" with no visual interest
125
+
126
+ ---
127
+
128
+ ## Responsive Design
129
+
130
+ - **Mobile-first** approach — design for 375px width, enhance for desktop.
131
+ - Breakpoints: `sm` (640px), `md` (768px), `lg` (1024px), `xl` (1280px).
132
+ - Hero text scales down: 48px desktop → 32px mobile.
133
+ - Feature grids: 3 columns desktop → 1 column mobile.
134
+ - Navigation: full links desktop → hamburger mobile.
135
+ - Cards: horizontal layout desktop → stacked mobile.
136
+ - Always test that nothing overflows horizontally on mobile.