fix(product-team): close 3 verified gaps in product skills
- Fix competitive-teardown/SKILL.md: replace broken references DATA_COLLECTION.md → references/data-collection-guide.md and TEMPLATES.md → references/analysis-templates.md (workflow was broken at steps 2 and 4) - Upgrade landing_page_scaffolder.py: add TSX + Tailwind output format (--format tsx) matching SKILL.md promise of Next.js/React components. 4 design styles (dark-saas, clean-minimal, bold-startup, enterprise). TSX is now default; HTML preserved via --format html - Rewrite README.md: fix stale counts (was 5 skills/15+ tools, now accurately shows 8 skills/9 tools), remove 7 ghost scripts that never existed (sprint_planner.py, velocity_tracker.py, etc.) - Fix tech-debt.md description (score → prioritize) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,448 +1,115 @@
|
||||
# Product Team Skills Collection
|
||||
|
||||
**Complete suite of 5 expert product skills** covering product management, agile delivery, strategy, UX research, and design systems.
|
||||
**8 production-ready product skills** covering product management, agile delivery, strategy, UX research, design systems, competitive intelligence, landing pages, and SaaS scaffolding.
|
||||
|
||||
---
|
||||
|
||||
## 📚 Table of Contents
|
||||
## Overview
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Overview](#overview)
|
||||
- [Skills Catalog](#skills-catalog)
|
||||
- [Quick Start Guide](#quick-start-guide)
|
||||
- [Team Structure Recommendations](#team-structure-recommendations)
|
||||
- [Common Workflows](#common-workflows)
|
||||
- [Success Metrics](#success-metrics)
|
||||
- **8 skills** covering the full product lifecycle from discovery to delivery
|
||||
- **9 Python automation tools** (stdlib only, zero dependencies)
|
||||
- **4 agents** orchestrating skills across product workflows
|
||||
- **5 slash commands** for quick access to common operations
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Installation
|
||||
|
||||
### Quick Install (Recommended)
|
||||
|
||||
Install all product team skills with one command:
|
||||
|
||||
```bash
|
||||
# Install all product skills to all supported agents
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team
|
||||
|
||||
# Install to Claude Code only
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team --agent claude
|
||||
|
||||
# Install to Cursor only
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team --agent cursor
|
||||
```
|
||||
|
||||
### Install Individual Skills
|
||||
|
||||
```bash
|
||||
# Product Manager Toolkit
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team/product-manager-toolkit
|
||||
|
||||
# Agile Product Owner
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team/agile-product-owner
|
||||
|
||||
# Product Strategist
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team/product-strategist
|
||||
|
||||
# UX Researcher Designer
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team/ux-researcher-designer
|
||||
|
||||
# UI Design System
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team/ui-design-system
|
||||
```
|
||||
|
||||
**Supported Agents:** Claude Code, Cursor, VS Code, Copilot, Goose, Amp, Codex
|
||||
|
||||
**Complete Installation Guide:** See [../INSTALLATION.md](../INSTALLATION.md) for detailed instructions, troubleshooting, and manual installation.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
This product team skills collection provides comprehensive product management capabilities from discovery through delivery, covering strategy, execution, research, and design.
|
||||
|
||||
**What's Included:**
|
||||
- **5 expert-level skills** covering product management, agile, strategy, UX, and design
|
||||
- **15+ Python automation tools** for prioritization, analysis, and generation
|
||||
- **Comprehensive frameworks** for discovery, delivery, research, and design systems
|
||||
- **Ready-to-use templates** for PRDs, user stories, OKRs, personas, and design tokens
|
||||
|
||||
**Ideal For:**
|
||||
- Product teams at startups and scale-ups
|
||||
- Solo PMs managing multiple products
|
||||
- Product leaders building product organizations
|
||||
- Cross-functional product delivery teams
|
||||
|
||||
**Key Benefits:**
|
||||
- ⚡ **40% time savings** on product planning and documentation
|
||||
- 🎯 **Data-driven decisions** with RICE prioritization and analytics
|
||||
- 📈 **Consistent delivery** with agile frameworks and automation
|
||||
- 🚀 **Faster time-to-market** with proven templates and workflows
|
||||
|
||||
---
|
||||
|
||||
## 📦 Skills Catalog
|
||||
## Skills Catalog
|
||||
|
||||
### 1. Product Manager Toolkit
|
||||
**Status:** ✅ Production Ready | **Version:** 1.0
|
||||
**Python Tools:** `rice_prioritizer.py`, `customer_interview_analyzer.py`
|
||||
|
||||
**Purpose:** Essential tools and frameworks for modern product management, from discovery to delivery.
|
||||
|
||||
**Key Capabilities:**
|
||||
- RICE prioritization with portfolio analysis
|
||||
- Customer interview analysis and insight extraction
|
||||
- PRD templates (4 comprehensive formats)
|
||||
- Discovery frameworks and hypothesis testing
|
||||
- Metrics and analytics dashboards
|
||||
|
||||
**Python Tools:**
|
||||
- `rice_prioritizer.py` - Automated feature prioritization
|
||||
- `customer_interview_analyzer.py` - AI-powered insight extraction
|
||||
|
||||
**Use When:** Feature prioritization, customer discovery, PRD creation, product metrics
|
||||
|
||||
**Learn More:** [product-manager-toolkit/SKILL.md](product-manager-toolkit/SKILL.md)
|
||||
|
||||
---
|
||||
RICE prioritization with portfolio analysis, customer interview NLP analysis, PRD templates, and discovery frameworks.
|
||||
|
||||
### 2. Agile Product Owner
|
||||
**Status:** ✅ Production Ready | **Version:** 1.0
|
||||
**Python Tools:** `user_story_generator.py`
|
||||
|
||||
**Purpose:** Sprint execution and backlog management tools for agile product delivery.
|
||||
|
||||
**Key Capabilities:**
|
||||
- INVEST-compliant user story generation
|
||||
- Sprint planning with capacity allocation
|
||||
- Epic breakdown and story mapping
|
||||
- Velocity tracking and burndown analysis
|
||||
- Agile ceremonies frameworks
|
||||
|
||||
**Python Tools:**
|
||||
- `user_story_generator.py` - Generate user stories with acceptance criteria
|
||||
- `sprint_planner.py` - Capacity-based sprint planning
|
||||
- `velocity_tracker.py` - Sprint metrics and analysis
|
||||
|
||||
**Use When:** Backlog refinement, sprint planning, user story writing, velocity tracking
|
||||
|
||||
**Learn More:** [agile-product-owner/SKILL.md](agile-product-owner/SKILL.md)
|
||||
|
||||
---
|
||||
INVEST-compliant user story generation, sprint planning with capacity allocation, epic breakdown, and acceptance criteria.
|
||||
|
||||
### 3. Product Strategist
|
||||
**Status:** ✅ Production Ready | **Version:** 1.0
|
||||
**Python Tools:** `okr_cascade_generator.py`
|
||||
|
||||
**Purpose:** Strategic planning and vision alignment for heads of product and product leaders.
|
||||
|
||||
**Key Capabilities:**
|
||||
- OKR cascade generation (company → product → team)
|
||||
- Alignment scoring and measurement
|
||||
- Strategy templates (growth, retention, revenue, innovation)
|
||||
- Team scaling and organizational design
|
||||
- Vision frameworks and roadmap development
|
||||
|
||||
**Python Tools:**
|
||||
- `okr_cascade_generator.py` - Automated OKR hierarchy generation
|
||||
- `alignment_scorer.py` - Vertical and horizontal alignment measurement
|
||||
|
||||
**Use When:** Strategic planning, OKR setting, product vision, roadmap development, team scaling
|
||||
|
||||
**Learn More:** [product-strategist/SKILL.md](product-strategist/SKILL.md)
|
||||
|
||||
---
|
||||
OKR cascade generation (company to product to team), alignment scoring, and 5 strategy templates.
|
||||
|
||||
### 4. UX Researcher Designer
|
||||
**Status:** ✅ Production Ready | **Version:** 1.0
|
||||
**Python Tools:** `persona_generator.py`
|
||||
|
||||
**Purpose:** User research and experience design frameworks for creating user-centered products.
|
||||
|
||||
**Key Capabilities:**
|
||||
- Data-driven persona creation from user research
|
||||
- Customer journey mapping and visualization
|
||||
- Research synthesis and pattern identification
|
||||
- Usability testing protocols and heuristic evaluation
|
||||
- Design thinking and workshop facilitation
|
||||
|
||||
**Python Tools:**
|
||||
- `persona_generator.py` - Generate personas from research data
|
||||
- `journey_mapper.py` - Customer journey visualization
|
||||
- `research_synthesizer.py` - Pattern identification from interviews
|
||||
|
||||
**Use When:** User research, persona development, journey mapping, usability testing
|
||||
|
||||
**Learn More:** [ux-researcher-designer/SKILL.md](ux-researcher-designer/SKILL.md)
|
||||
|
||||
---
|
||||
Data-driven persona generation, journey mapping frameworks, usability testing protocols, and empathy maps.
|
||||
|
||||
### 5. UI Design System
|
||||
**Status:** ✅ Production Ready | **Version:** 1.0
|
||||
**Python Tools:** `design_token_generator.py`
|
||||
|
||||
**Purpose:** Visual design systems and component architecture for consistent user interfaces.
|
||||
Design token generation from brand color (CSS, JSON, SCSS), typography scales, spacing grids, and responsive breakpoints.
|
||||
|
||||
**Key Capabilities:**
|
||||
- Complete design token system generation
|
||||
- Atomic design component architecture
|
||||
- Responsive breakpoint and grid system calculation
|
||||
- Export formats (JSON, CSS, SCSS) for development handoff
|
||||
- Storybook integration and component documentation
|
||||
### 6. Competitive Teardown
|
||||
**Python Tools:** `competitive_matrix_builder.py`
|
||||
|
||||
**Python Tools:**
|
||||
- `design_token_generator.py` - Generate complete token system from brand colors
|
||||
- `component_architect.py` - Atomic design implementation
|
||||
- `responsive_calculator.py` - Breakpoint and grid generation
|
||||
12-dimension competitive scoring, feature matrices, SWOT analysis, positioning maps, and stakeholder presentations.
|
||||
|
||||
**Use When:** Design system creation, component library architecture, design-dev handoff
|
||||
### 7. Landing Page Generator
|
||||
**Python Tools:** `landing_page_scaffolder.py`
|
||||
|
||||
**Learn More:** [ui-design-system/SKILL.md](ui-design-system/SKILL.md)
|
||||
Next.js/React TSX components with Tailwind CSS, 4 design styles, copy frameworks (PAS, AIDA, BAB), SEO optimization. Also supports HTML output.
|
||||
|
||||
### 8. SaaS Scaffolder
|
||||
**Python Tools:** `project_bootstrapper.py`
|
||||
|
||||
Production SaaS boilerplate with Next.js, TypeScript, auth (NextAuth/Clerk/Supabase), payments (Stripe/Lemon Squeezy), and Docker.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start Guide
|
||||
## Slash Commands
|
||||
|
||||
### For Product Managers
|
||||
|
||||
1. **Install Product Manager Toolkit:**
|
||||
```bash
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team/product-manager-toolkit
|
||||
```
|
||||
|
||||
2. **Prioritize Your Backlog:**
|
||||
```bash
|
||||
python product-manager-toolkit/scripts/rice_prioritizer.py features.csv
|
||||
```
|
||||
|
||||
3. **Analyze Customer Interviews:**
|
||||
```bash
|
||||
python product-manager-toolkit/scripts/customer_interview_analyzer.py interview.txt
|
||||
```
|
||||
|
||||
### For Product Owners
|
||||
|
||||
1. **Install Agile Product Owner:**
|
||||
```bash
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team/agile-product-owner
|
||||
```
|
||||
|
||||
2. **Generate User Stories:**
|
||||
```bash
|
||||
python agile-product-owner/scripts/user_story_generator.py
|
||||
```
|
||||
|
||||
3. **Plan Your Sprint:**
|
||||
```bash
|
||||
python agile-product-owner/scripts/user_story_generator.py sprint 30
|
||||
```
|
||||
|
||||
### For Product Leaders
|
||||
|
||||
1. **Install Product Strategist:**
|
||||
```bash
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team/product-strategist
|
||||
```
|
||||
|
||||
2. **Generate OKR Cascade:**
|
||||
```bash
|
||||
python product-strategist/scripts/okr_cascade_generator.py growth
|
||||
```
|
||||
|
||||
### For UX Researchers
|
||||
|
||||
1. **Install UX Researcher Designer:**
|
||||
```bash
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team/ux-researcher-designer
|
||||
```
|
||||
|
||||
2. **Create Personas:**
|
||||
```bash
|
||||
python ux-researcher-designer/scripts/persona_generator.py
|
||||
```
|
||||
|
||||
### For UI Designers
|
||||
|
||||
1. **Install UI Design System:**
|
||||
```bash
|
||||
npx ai-agent-skills install alirezarezvani/claude-skills/product-team/ui-design-system
|
||||
```
|
||||
|
||||
2. **Generate Design Tokens:**
|
||||
```bash
|
||||
python ui-design-system/scripts/design_token_generator.py "#0066CC" modern css
|
||||
```
|
||||
| Command | Script | Purpose |
|
||||
|---------|--------|---------|
|
||||
| `/rice` | `rice_prioritizer.py` | Feature prioritization |
|
||||
| `/okr` | `okr_cascade_generator.py` | OKR cascade generation |
|
||||
| `/persona` | `persona_generator.py` | Persona generation |
|
||||
| `/user-story` | `user_story_generator.py` | User story generation |
|
||||
| `/competitive-matrix` | `competitive_matrix_builder.py` | Competitive analysis |
|
||||
|
||||
---
|
||||
|
||||
## 👥 Team Structure Recommendations
|
||||
## Quick Start
|
||||
|
||||
### Small Team (1-5 people)
|
||||
```bash
|
||||
# Prioritize your backlog
|
||||
python product-manager-toolkit/scripts/rice_prioritizer.py features.csv --capacity 20
|
||||
|
||||
**Recommended Skills:**
|
||||
- Product Manager Toolkit (PM/Product Owner combo role)
|
||||
- UX Researcher Designer (PM with UX responsibilities)
|
||||
# Generate user stories for a sprint
|
||||
python agile-product-owner/scripts/user_story_generator.py sprint 30
|
||||
|
||||
**Rationale:** Hybrid roles, focus on execution over specialization
|
||||
# Create OKR cascade
|
||||
python product-strategist/scripts/okr_cascade_generator.py growth
|
||||
|
||||
---
|
||||
# Generate personas
|
||||
python ux-researcher-designer/scripts/persona_generator.py
|
||||
|
||||
### Medium Team (6-15 people)
|
||||
# Generate design tokens
|
||||
python ui-design-system/scripts/design_token_generator.py "#0066CC" modern css
|
||||
|
||||
**Recommended Skills:**
|
||||
- Product Manager Toolkit (Product Manager)
|
||||
- Agile Product Owner (separate Product Owner role)
|
||||
- UX Researcher Designer (dedicated UX Researcher)
|
||||
- UI Design System (if building design system)
|
||||
# Competitive analysis
|
||||
python competitive-teardown/scripts/competitive_matrix_builder.py competitors.json
|
||||
|
||||
**Rationale:** Specialized roles, better separation of concerns
|
||||
# Scaffold a landing page (TSX + Tailwind)
|
||||
python landing-page-generator/scripts/landing_page_scaffolder.py config.json --format tsx
|
||||
|
||||
---
|
||||
|
||||
### Large Team (16+ people)
|
||||
|
||||
**Recommended Skills:**
|
||||
- All 5 skills for complete product organization
|
||||
- Product Strategist (Head of Product / CPO)
|
||||
- Product Manager Toolkit (multiple Product Managers)
|
||||
- Agile Product Owner (multiple Product Owners)
|
||||
- UX Researcher Designer (UX Research team)
|
||||
- UI Design System (Design Systems team)
|
||||
|
||||
**Rationale:** Full specialization, scaled product delivery
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Common Workflows
|
||||
|
||||
### Workflow 1: New Feature Development
|
||||
|
||||
```
|
||||
1. Discovery → Product Manager Toolkit
|
||||
- Customer interviews
|
||||
- Problem validation
|
||||
- Opportunity sizing
|
||||
|
||||
2. Prioritization → Product Manager Toolkit
|
||||
- RICE scoring
|
||||
- Portfolio analysis
|
||||
- Resource allocation
|
||||
|
||||
3. Story Writing → Agile Product Owner
|
||||
- Epic breakdown
|
||||
- User story generation
|
||||
- Acceptance criteria
|
||||
|
||||
4. UX Research → UX Researcher Designer
|
||||
- User testing
|
||||
- Journey mapping
|
||||
- Usability validation
|
||||
|
||||
5. Sprint Execution → Agile Product Owner
|
||||
- Sprint planning
|
||||
- Velocity tracking
|
||||
- Burndown monitoring
|
||||
```
|
||||
|
||||
### Workflow 2: Strategic Planning (Quarterly)
|
||||
|
||||
```
|
||||
1. Vision Setting → Product Strategist
|
||||
- Product vision
|
||||
- Strategic themes
|
||||
- Market positioning
|
||||
|
||||
2. OKR Cascade → Product Strategist
|
||||
- Company → Product → Team goals
|
||||
- Alignment measurement
|
||||
- Success metrics
|
||||
|
||||
3. Roadmap Planning → Product Manager Toolkit
|
||||
- Feature mapping
|
||||
- Release planning
|
||||
- Stakeholder alignment
|
||||
|
||||
4. Resource Planning → Product Strategist
|
||||
- Team capacity
|
||||
- Hiring needs
|
||||
- Budget allocation
|
||||
```
|
||||
|
||||
### Workflow 3: Design System Creation
|
||||
|
||||
```
|
||||
1. Brand Foundation → UI Design System
|
||||
- Design tokens
|
||||
- Color system
|
||||
- Typography scale
|
||||
|
||||
2. Component Architecture → UI Design System
|
||||
- Atomic design
|
||||
- Component library
|
||||
- Documentation
|
||||
|
||||
3. User Validation → UX Researcher Designer
|
||||
- Usability testing
|
||||
- Component feedback
|
||||
- Pattern validation
|
||||
|
||||
4. Developer Handoff → UI Design System
|
||||
- CSS/JSON export
|
||||
- Implementation guide
|
||||
- Component specs
|
||||
# Bootstrap a SaaS project
|
||||
python saas-scaffolder/scripts/project_bootstrapper.py config.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Success Metrics
|
||||
## Agents
|
||||
|
||||
### Time Savings
|
||||
|
||||
- **Product Planning:** 40% reduction in PRD creation time
|
||||
- **Backlog Management:** 50% reduction in user story writing time
|
||||
- **Research Synthesis:** 60% reduction in interview analysis time
|
||||
- **Design Systems:** 70% reduction in token generation time
|
||||
|
||||
### Quality Improvements
|
||||
|
||||
- **Feature Prioritization:** 30% improvement in delivery ROI
|
||||
- **User Story Quality:** 40% improvement in acceptance criteria clarity
|
||||
- **Research Insights:** 35% improvement in insight extraction accuracy
|
||||
- **Design Consistency:** 80% improvement in design system consistency
|
||||
|
||||
### Delivery Velocity
|
||||
|
||||
- **Sprint Predictability:** 25% improvement in sprint completion rates
|
||||
- **Discovery Efficiency:** 45% reduction in time-to-validation
|
||||
- **OKR Alignment:** 50% improvement in goal alignment scores
|
||||
- **UX Iteration:** 40% reduction in design iteration cycles
|
||||
| Agent | Skills Orchestrated |
|
||||
|-------|-------------------|
|
||||
| `cs-product-manager` | All 8 product skills |
|
||||
| `cs-agile-product-owner` | Agile product owner + product manager toolkit |
|
||||
| `cs-product-strategist` | Product strategist + competitive teardown |
|
||||
| `cs-ux-researcher` | UX researcher + product manager toolkit + UI design system |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Integration with Other Teams
|
||||
|
||||
**Product ↔ Engineering:**
|
||||
- User stories → Engineering implementation
|
||||
- Technical feasibility → Product prioritization
|
||||
- Design system → Frontend development
|
||||
|
||||
**Product ↔ Marketing:**
|
||||
- Product strategy → Go-to-market strategy
|
||||
- Customer insights → Marketing messaging
|
||||
- Feature launches → Marketing campaigns
|
||||
|
||||
**Product ↔ C-Level:**
|
||||
- OKRs → Company strategy
|
||||
- Product metrics → Board reporting
|
||||
- Resource needs → Budget planning
|
||||
|
||||
---
|
||||
|
||||
## 📚 Additional Resources
|
||||
|
||||
- **Product Team Guide:** `product_team_implementation_guide.md` (if exists)
|
||||
- **CLAUDE.md:** [product-team/CLAUDE.md](CLAUDE.md) - Claude Code specific guidance
|
||||
- **Main Documentation:** [../CLAUDE.md](../CLAUDE.md)
|
||||
- **Installation Guide:** [../INSTALLATION.md](../INSTALLATION.md)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** January 2026
|
||||
**Skills Deployed:** 5/5 product team skills production-ready
|
||||
**Total Tools:** 15+ Python automation tools
|
||||
**Last Updated:** March 2026
|
||||
**Skills Deployed:** 8/8 production-ready
|
||||
**Total Tools:** 9 Python automation tools
|
||||
|
||||
@@ -26,11 +26,11 @@ description: "Analyzes competitor products and companies by synthesizing data fr
|
||||
Follow these steps in sequence to produce a complete teardown:
|
||||
|
||||
1. **Define competitors** — List 2–4 competitors to analyze. Confirm which is the primary focus.
|
||||
2. **Collect data** — Use `DATA_COLLECTION.md` to gather raw signals from at least 3 sources per competitor (website, reviews, job postings, SEO, social).
|
||||
2. **Collect data** — Use `references/data-collection-guide.md` to gather raw signals from at least 3 sources per competitor (website, reviews, job postings, SEO, social).
|
||||
_Validation checkpoint: Before proceeding, confirm you have pricing data, at least 20 reviews, and job posting counts for each competitor._
|
||||
3. **Score using rubric** — Apply the 12-dimension rubric below to produce a numeric scorecard for each competitor and your own product.
|
||||
_Validation checkpoint: Every dimension should have a score and at least one supporting evidence note._
|
||||
4. **Generate outputs** — Populate the templates in `TEMPLATES.md` (Feature Matrix, Pricing Analysis, SWOT, Positioning Map, UX Audit).
|
||||
4. **Generate outputs** — Populate the templates in `references/analysis-templates.md` (Feature Matrix, Pricing Analysis, SWOT, Positioning Map, UX Audit).
|
||||
5. **Build action plan** — Translate findings into the Action Items template (quick wins / medium-term / strategic).
|
||||
6. **Package for stakeholders** — Assemble the Stakeholder Presentation using outputs from steps 3–5.
|
||||
|
||||
@@ -38,7 +38,7 @@ Follow these steps in sequence to produce a complete teardown:
|
||||
|
||||
## Data Collection Guide
|
||||
|
||||
> Full executable scripts for each source are in `DATA_COLLECTION.md`. Summaries of what to capture are below.
|
||||
> Full executable scripts for each source are in `references/data-collection-guide.md`. Summaries of what to capture are below.
|
||||
|
||||
### 1. Website Analysis
|
||||
|
||||
@@ -85,7 +85,7 @@ SEO signals to capture:
|
||||
|
||||
### 5. Social Media Sentiment
|
||||
|
||||
Capture recent mentions via Twitter/X API v2, Reddit, or LinkedIn. Look for recurring praise, complaints, and feature requests. See `DATA_COLLECTION.md` for API query examples.
|
||||
Capture recent mentions via Twitter/X API v2, Reddit, or LinkedIn. Look for recurring praise, complaints, and feature requests. See `references/data-collection-guide.md` for API query examples.
|
||||
|
||||
---
|
||||
|
||||
@@ -118,7 +118,7 @@ Apply this pattern to all 12 dimensions for each competitor.
|
||||
|
||||
## Templates
|
||||
|
||||
> Full template markdown is in `TEMPLATES.md`. Abbreviated reference below.
|
||||
> Full template markdown is in `references/analysis-templates.md`. Abbreviated reference below.
|
||||
|
||||
### Feature Comparison Matrix
|
||||
|
||||
@@ -138,7 +138,7 @@ For each competitor: 3–5 bullets per quadrant (Strengths, Weaknesses, Opportun
|
||||
|
||||
### Positioning Map
|
||||
|
||||
2x2 axes (e.g., Simple ↔ Complex / Low Value ↔ High Value). Place each competitor and your product. Bubble size = market share or funding. See `TEMPLATES.md` for ASCII and editable versions.
|
||||
2x2 axes (e.g., Simple ↔ Complex / Low Value ↔ High Value). Place each competitor and your product. Bubble size = market share or funding. See `references/analysis-templates.md` for ASCII and editable versions.
|
||||
|
||||
### UX Audit Checklist
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Landing Page Scaffolder — Generate responsive HTML landing pages from config.
|
||||
"""Landing Page Scaffolder — Generate landing pages as HTML or Next.js TSX from config.
|
||||
|
||||
Creates production-ready landing page HTML with hero sections, features,
|
||||
Creates production-ready landing pages with hero sections, features,
|
||||
testimonials, pricing, CTAs, and responsive design.
|
||||
|
||||
Usage:
|
||||
python landing_page_scaffolder.py config.json --output page.html
|
||||
python landing_page_scaffolder.py config.json --format html --output page.html
|
||||
python landing_page_scaffolder.py config.json --format tsx --output LandingPage.tsx
|
||||
python landing_page_scaffolder.py config.json --format json
|
||||
"""
|
||||
|
||||
@@ -22,6 +23,306 @@ def escape(text: str) -> str:
|
||||
return html_module.escape(str(text))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tailwind style mappings for TSX output
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
DESIGN_STYLES = {
|
||||
"dark-saas": {
|
||||
"bg": "bg-gray-950", "text": "text-white",
|
||||
"accent": "violet", "card_bg": "bg-gray-900 border border-gray-800",
|
||||
"btn": "bg-violet-600 hover:bg-violet-500 text-white",
|
||||
"btn_secondary": "border border-gray-700 text-gray-300 hover:bg-gray-800",
|
||||
"section_alt": "bg-gray-900/50", "muted": "text-gray-400",
|
||||
"border": "border-gray-800",
|
||||
},
|
||||
"clean-minimal": {
|
||||
"bg": "bg-white", "text": "text-gray-900",
|
||||
"accent": "blue", "card_bg": "bg-gray-50 border border-gray-200 rounded-2xl",
|
||||
"btn": "bg-blue-600 hover:bg-blue-700 text-white",
|
||||
"btn_secondary": "border border-gray-300 text-gray-700 hover:bg-gray-50",
|
||||
"section_alt": "bg-gray-50", "muted": "text-gray-500",
|
||||
"border": "border-gray-200",
|
||||
},
|
||||
"bold-startup": {
|
||||
"bg": "bg-white", "text": "text-gray-900",
|
||||
"accent": "orange", "card_bg": "shadow-xl rounded-3xl bg-white",
|
||||
"btn": "bg-orange-500 hover:bg-orange-600 text-white",
|
||||
"btn_secondary": "border-2 border-orange-500 text-orange-600 hover:bg-orange-50",
|
||||
"section_alt": "bg-orange-50/30", "muted": "text-gray-500",
|
||||
"border": "border-gray-200",
|
||||
},
|
||||
"enterprise": {
|
||||
"bg": "bg-slate-50", "text": "text-slate-900",
|
||||
"accent": "slate", "card_bg": "bg-white border border-slate-200 shadow-sm",
|
||||
"btn": "bg-slate-900 hover:bg-slate-800 text-white",
|
||||
"btn_secondary": "border border-slate-300 text-slate-700 hover:bg-slate-100",
|
||||
"section_alt": "bg-white", "muted": "text-slate-500",
|
||||
"border": "border-slate-200",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# TSX generators
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def tsx_nav(config: Dict[str, Any], style: Dict[str, str]) -> str:
|
||||
brand = config.get("brand", "Brand")
|
||||
nav_links = config.get("nav_links", [])
|
||||
cta = config.get("nav_cta", {"text": "Get Started", "url": "#"})
|
||||
links_jsx = "\n ".join(
|
||||
f'<a href="{l.get("url", "#")}" className="{style["muted"]} hover:{style["text"]} font-medium transition-colors">{l.get("text", "")}</a>'
|
||||
for l in nav_links
|
||||
)
|
||||
return f'''function Navbar() {{
|
||||
return (
|
||||
<nav className="sticky top-0 z-50 {style["bg"]} border-b {style["border"]} backdrop-blur-sm">
|
||||
<div className="mx-auto flex max-w-7xl items-center justify-between px-6 py-4">
|
||||
<a href="#" className="text-xl font-bold {style["text"]}">{brand}</a>
|
||||
<div className="hidden items-center gap-8 md:flex">
|
||||
{links_jsx}
|
||||
<a href="{cta.get("url", "#")}" className="rounded-lg {style["btn"]} px-5 py-2.5 text-sm font-semibold transition-colors">
|
||||
{cta.get("text", "Get Started")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}}'''
|
||||
|
||||
|
||||
def tsx_hero(hero: Dict[str, Any], style: Dict[str, str]) -> str:
|
||||
h1 = hero.get("headline", "Your Headline Here")
|
||||
sub = hero.get("subheadline", "")
|
||||
primary_cta = hero.get("primary_cta", {"text": "Get Started", "url": "#"})
|
||||
secondary_cta = hero.get("secondary_cta", None)
|
||||
secondary_jsx = ""
|
||||
if secondary_cta:
|
||||
secondary_jsx = f'''
|
||||
<a href="{secondary_cta.get("url", "#")}" className="rounded-lg {style["btn_secondary"]} px-8 py-3 text-lg font-semibold transition-colors">
|
||||
{secondary_cta.get("text", "Learn More")}
|
||||
</a>'''
|
||||
return f'''function Hero() {{
|
||||
return (
|
||||
<section className="flex min-h-[80vh] flex-col items-center justify-center px-6 py-24 text-center {style["bg"]}">
|
||||
<div className="mx-auto max-w-4xl">
|
||||
<h1 className="mb-6 text-5xl font-bold tracking-tight {style["text"]} md:text-7xl">
|
||||
{h1}
|
||||
</h1>
|
||||
<p className="mx-auto mb-10 max-w-2xl text-xl {style["muted"]}">
|
||||
{sub}
|
||||
</p>
|
||||
<div className="flex flex-col items-center gap-4 sm:flex-row sm:justify-center">
|
||||
<a href="{primary_cta.get("url", "#")}" className="rounded-lg {style["btn"]} px-8 py-3 text-lg font-semibold transition-colors">
|
||||
{primary_cta.get("text", "Get Started")}
|
||||
</a>{secondary_jsx}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}}'''
|
||||
|
||||
|
||||
def tsx_features(features: Dict[str, Any], style: Dict[str, str]) -> str:
|
||||
title = features.get("title", "Features")
|
||||
subtitle = features.get("subtitle", "")
|
||||
items = features.get("items", [])
|
||||
cards_jsx = "\n ".join(
|
||||
f'''<div className="{style["card_bg"]} rounded-xl p-8">
|
||||
<div className="mb-4 text-3xl">{f.get("icon", "")}</div>
|
||||
<h3 className="mb-3 text-xl font-semibold {style["text"]}">{f.get("title", "")}</h3>
|
||||
<p className="{style["muted"]}">{f.get("description", "")}</p>
|
||||
</div>'''
|
||||
for f in items
|
||||
)
|
||||
return f'''function Features() {{
|
||||
return (
|
||||
<section className="{style["section_alt"]} px-6 py-24">
|
||||
<div className="mx-auto max-w-7xl">
|
||||
<h2 className="mb-4 text-center text-4xl font-bold {style["text"]}">{title}</h2>
|
||||
<p className="mx-auto mb-16 max-w-2xl text-center text-lg {style["muted"]}">{subtitle}</p>
|
||||
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
|
||||
{cards_jsx}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}}'''
|
||||
|
||||
|
||||
def tsx_testimonials(testimonials: Dict[str, Any], style: Dict[str, str]) -> str:
|
||||
title = testimonials.get("title", "What Our Customers Say")
|
||||
items = testimonials.get("items", [])
|
||||
if not items:
|
||||
return ""
|
||||
cards_jsx = "\n ".join(
|
||||
f'''<div className="rounded-xl border {style["border"]} p-8">
|
||||
<p className="mb-6 text-lg italic {style["muted"]}">"{t.get("quote", "")}"</p>
|
||||
<div>
|
||||
<p className="font-semibold {style["text"]}">{t.get("name", "")}</p>
|
||||
<p className="text-sm {style["muted"]}">{t.get("title", "")}, {t.get("company", "")}</p>
|
||||
</div>
|
||||
</div>'''
|
||||
for t in items
|
||||
)
|
||||
return f'''function Testimonials() {{
|
||||
return (
|
||||
<section className="px-6 py-24 {style["bg"]}">
|
||||
<div className="mx-auto max-w-7xl">
|
||||
<h2 className="mb-16 text-center text-4xl font-bold {style["text"]}">{title}</h2>
|
||||
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
|
||||
{cards_jsx}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}}'''
|
||||
|
||||
|
||||
def tsx_pricing(pricing: Dict[str, Any], style: Dict[str, str]) -> str:
|
||||
title = pricing.get("title", "Pricing")
|
||||
plans = pricing.get("plans", [])
|
||||
if not plans:
|
||||
return ""
|
||||
accent = style["accent"]
|
||||
cards = []
|
||||
for p in plans:
|
||||
featured = p.get("featured", False)
|
||||
border_cls = f"border-2 border-{accent}-500 ring-4 ring-{accent}-500/20" if featured else f"border {style['border']}"
|
||||
badge = f'\n <div className="absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-{accent}-600 px-4 py-1 text-xs font-semibold text-white">Most Popular</div>' if featured else ""
|
||||
features_jsx = "\n ".join(
|
||||
f'<li className="flex items-center gap-2 py-2"><span className="text-{accent}-500 font-bold">✓</span> {feat}</li>'
|
||||
for feat in p.get("features", [])
|
||||
)
|
||||
cards.append(f'''<div className="relative rounded-2xl {border_cls} {style["card_bg"]} p-8 text-center">{badge}
|
||||
<h3 className="mb-2 text-xl font-semibold {style["text"]}">{p.get("name", "")}</h3>
|
||||
<div className="my-6 text-5xl font-extrabold {style["text"]}">${p.get("price", "0")}<span className="text-base font-normal {style["muted"]}">/mo</span></div>
|
||||
<p className="{style["muted"]} mb-6">{p.get("description", "")}</p>
|
||||
<ul className="mb-8 space-y-1 text-left {style["muted"]}">
|
||||
{features_jsx}
|
||||
</ul>
|
||||
<a href="{p.get("cta_url", "#")}" className="block w-full rounded-lg {style["btn"]} py-3 text-center font-semibold transition-colors">
|
||||
{p.get("cta_text", "Choose Plan")}
|
||||
</a>
|
||||
</div>''')
|
||||
cards_jsx = "\n ".join(cards)
|
||||
return f'''function Pricing() {{
|
||||
return (
|
||||
<section className="{style["section_alt"]} px-6 py-24">
|
||||
<div className="mx-auto max-w-5xl">
|
||||
<h2 className="mb-16 text-center text-4xl font-bold {style["text"]}">{title}</h2>
|
||||
<div className="grid gap-8 lg:grid-cols-{min(len(plans), 3)}">
|
||||
{cards_jsx}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}}'''
|
||||
|
||||
|
||||
def tsx_cta(cta: Dict[str, Any], style: Dict[str, str]) -> str:
|
||||
accent = style["accent"]
|
||||
return f'''function CTASection() {{
|
||||
return (
|
||||
<section className="bg-{accent}-600 px-6 py-24 text-center text-white">
|
||||
<div className="mx-auto max-w-3xl">
|
||||
<h2 className="mb-4 text-4xl font-bold">{cta.get("headline", "Ready to get started?")}</h2>
|
||||
<p className="mb-10 text-xl opacity-90">{cta.get("subheadline", "")}</p>
|
||||
<a href="{cta.get("url", "#")}" className="rounded-lg bg-white px-8 py-3 text-lg font-semibold text-{accent}-600 transition-colors hover:bg-gray-100">
|
||||
{cta.get("text", "Start Free Trial")}
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}}'''
|
||||
|
||||
|
||||
def tsx_footer(config: Dict[str, Any], style: Dict[str, str]) -> str:
|
||||
brand = config.get("brand", "Company")
|
||||
year = datetime.now().year
|
||||
footer_text = config.get("footer_text", f"{year} {brand}. All rights reserved.")
|
||||
return f'''function Footer() {{
|
||||
return (
|
||||
<footer className="border-t {style["border"]} {style["bg"]} px-6 py-10 text-center {style["muted"]}">
|
||||
<p>© {footer_text}</p>
|
||||
</footer>
|
||||
);
|
||||
}}'''
|
||||
|
||||
|
||||
def generate_tsx(config: Dict[str, Any]) -> str:
|
||||
"""Generate complete Next.js/React TSX landing page with Tailwind CSS."""
|
||||
style_name = config.get("design_style", "clean-minimal")
|
||||
style = DESIGN_STYLES.get(style_name, DESIGN_STYLES["clean-minimal"])
|
||||
|
||||
components = []
|
||||
component_names = []
|
||||
|
||||
components.append(tsx_nav(config, style))
|
||||
component_names.append("Navbar")
|
||||
|
||||
if config.get("hero"):
|
||||
components.append(tsx_hero(config["hero"], style))
|
||||
component_names.append("Hero")
|
||||
|
||||
if config.get("features"):
|
||||
components.append(tsx_features(config["features"], style))
|
||||
component_names.append("Features")
|
||||
|
||||
if config.get("testimonials") and config["testimonials"].get("items"):
|
||||
components.append(tsx_testimonials(config["testimonials"], style))
|
||||
component_names.append("Testimonials")
|
||||
|
||||
if config.get("pricing") and config["pricing"].get("plans"):
|
||||
components.append(tsx_pricing(config["pricing"], style))
|
||||
component_names.append("Pricing")
|
||||
|
||||
if config.get("cta"):
|
||||
components.append(tsx_cta(config["cta"], style))
|
||||
component_names.append("CTASection")
|
||||
|
||||
components.append(tsx_footer(config, style))
|
||||
component_names.append("Footer")
|
||||
|
||||
title = config.get("title", "Landing Page")
|
||||
meta_desc = config.get("meta_description", "")
|
||||
|
||||
page_body = "\n ".join(f"<{name} />" for name in component_names)
|
||||
all_components = "\n\n".join(components)
|
||||
|
||||
return f'''// Generated by Landing Page Scaffolder — {datetime.now().strftime("%Y-%m-%d")}
|
||||
// Stack: Next.js 14+ App Router, React, Tailwind CSS
|
||||
// Design style: {style_name}
|
||||
|
||||
import type {{ Metadata }} from "next";
|
||||
|
||||
export const metadata: Metadata = {{
|
||||
title: "{title}",
|
||||
description: "{meta_desc}",
|
||||
openGraph: {{
|
||||
title: "{title}",
|
||||
description: "{meta_desc}",
|
||||
type: "website",
|
||||
}},
|
||||
}};
|
||||
|
||||
{all_components}
|
||||
|
||||
export default function LandingPage() {{
|
||||
return (
|
||||
<main>
|
||||
{page_body}
|
||||
</main>
|
||||
);
|
||||
}}
|
||||
'''
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# HTML generators (existing)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def generate_css(config: Dict[str, Any]) -> str:
|
||||
"""Generate responsive CSS from config theme."""
|
||||
theme = config.get("theme", {})
|
||||
@@ -35,24 +336,18 @@ def generate_css(config: Dict[str, Any]) -> str:
|
||||
* {{ margin: 0; padding: 0; box-sizing: border-box; }}
|
||||
body {{ font-family: {font}; color: {text_color}; background: {bg}; line-height: 1.6; }}
|
||||
.container {{ max-width: 1200px; margin: 0 auto; padding: 0 24px; }}
|
||||
|
||||
/* Navigation */
|
||||
nav {{ padding: 16px 0; border-bottom: 1px solid #e5e7eb; position: sticky; top: 0; background: {bg}; z-index: 100; }}
|
||||
nav .container {{ display: flex; justify-content: space-between; align-items: center; }}
|
||||
.nav-logo {{ font-size: 1.5rem; font-weight: 700; color: {primary}; text-decoration: none; }}
|
||||
.nav-links {{ display: flex; gap: 24px; list-style: none; }}
|
||||
.nav-links a {{ text-decoration: none; color: {text_color}; font-weight: 500; }}
|
||||
.nav-cta {{ background: {primary}; color: white; padding: 8px 20px; border-radius: 6px; text-decoration: none; font-weight: 600; }}
|
||||
|
||||
/* Hero */
|
||||
.hero {{ padding: 80px 0; text-align: center; }}
|
||||
.hero h1 {{ font-size: 3.5rem; font-weight: 800; line-height: 1.1; margin-bottom: 24px; max-width: 800px; margin-left: auto; margin-right: auto; }}
|
||||
.hero p {{ font-size: 1.25rem; color: #6b7280; max-width: 600px; margin: 0 auto 32px; }}
|
||||
.hero-cta {{ display: inline-flex; gap: 16px; }}
|
||||
.btn-primary {{ background: {primary}; color: white; padding: 14px 32px; border-radius: 8px; text-decoration: none; font-weight: 600; font-size: 1.1rem; }}
|
||||
.btn-secondary {{ background: transparent; color: {primary}; padding: 14px 32px; border-radius: 8px; text-decoration: none; font-weight: 600; font-size: 1.1rem; border: 2px solid {primary}; }}
|
||||
|
||||
/* Features */
|
||||
.features {{ padding: 80px 0; background: #f9fafb; }}
|
||||
.section-title {{ text-align: center; font-size: 2.5rem; font-weight: 700; margin-bottom: 16px; }}
|
||||
.section-subtitle {{ text-align: center; color: #6b7280; font-size: 1.1rem; margin-bottom: 48px; max-width: 600px; margin-left: auto; margin-right: auto; }}
|
||||
@@ -61,8 +356,6 @@ def generate_css(config: Dict[str, Any]) -> str:
|
||||
.feature-icon {{ font-size: 2rem; margin-bottom: 16px; }}
|
||||
.feature-card h3 {{ font-size: 1.25rem; margin-bottom: 12px; }}
|
||||
.feature-card p {{ color: #6b7280; }}
|
||||
|
||||
/* Testimonials */
|
||||
.testimonials {{ padding: 80px 0; }}
|
||||
.testimonials-grid {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: 24px; }}
|
||||
.testimonial-card {{ padding: 32px; border: 1px solid #e5e7eb; border-radius: 12px; }}
|
||||
@@ -70,8 +363,6 @@ def generate_css(config: Dict[str, Any]) -> str:
|
||||
.testimonial-author {{ display: flex; align-items: center; gap: 12px; }}
|
||||
.author-info strong {{ display: block; }}
|
||||
.author-info span {{ color: #6b7280; font-size: 0.9rem; }}
|
||||
|
||||
/* Pricing */
|
||||
.pricing {{ padding: 80px 0; background: #f9fafb; }}
|
||||
.pricing-grid {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; max-width: 900px; margin: 0 auto; }}
|
||||
.pricing-card {{ background: white; padding: 32px; border-radius: 12px; border: 2px solid #e5e7eb; text-align: center; }}
|
||||
@@ -82,18 +373,12 @@ def generate_css(config: Dict[str, Any]) -> str:
|
||||
.pricing-price span {{ font-size: 1rem; font-weight: 400; color: #6b7280; }}
|
||||
.pricing-features {{ list-style: none; text-align: left; margin: 24px 0; }}
|
||||
.pricing-features li {{ padding: 8px 0; border-bottom: 1px solid #f3f4f6; }}
|
||||
.pricing-features li::before {{ content: "✓ "; color: {primary}; font-weight: 700; }}
|
||||
|
||||
/* CTA */
|
||||
.pricing-features li::before {{ content: "\\2713 "; color: {primary}; font-weight: 700; }}
|
||||
.cta-section {{ padding: 80px 0; text-align: center; background: {primary}; color: white; }}
|
||||
.cta-section h2 {{ font-size: 2.5rem; margin-bottom: 16px; }}
|
||||
.cta-section p {{ font-size: 1.1rem; opacity: 0.9; margin-bottom: 32px; }}
|
||||
.btn-white {{ background: white; color: {primary}; padding: 14px 32px; border-radius: 8px; text-decoration: none; font-weight: 600; font-size: 1.1rem; }}
|
||||
|
||||
/* Footer */
|
||||
footer {{ padding: 40px 0; border-top: 1px solid #e5e7eb; color: #6b7280; text-align: center; }}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {{
|
||||
.hero h1 {{ font-size: 2.25rem; }}
|
||||
.hero-cta {{ flex-direction: column; align-items: center; }}
|
||||
@@ -105,11 +390,9 @@ def generate_css(config: Dict[str, Any]) -> str:
|
||||
|
||||
|
||||
def render_nav(config: Dict[str, Any]) -> str:
|
||||
"""Render navigation section."""
|
||||
brand = escape(config.get("brand", "Brand"))
|
||||
nav_links = config.get("nav_links", [])
|
||||
cta = config.get("nav_cta", {"text": "Get Started", "url": "#"})
|
||||
|
||||
links = "\n".join(
|
||||
f'<li><a href="{escape(l.get("url", "#"))}">{escape(l.get("text", ""))}</a></li>'
|
||||
for l in nav_links
|
||||
@@ -123,16 +406,13 @@ def render_nav(config: Dict[str, Any]) -> str:
|
||||
|
||||
|
||||
def render_hero(hero: Dict[str, Any]) -> str:
|
||||
"""Render hero section."""
|
||||
h1 = escape(hero.get("headline", "Your Headline Here"))
|
||||
sub = escape(hero.get("subheadline", ""))
|
||||
primary_cta = hero.get("primary_cta", {"text": "Get Started", "url": "#"})
|
||||
secondary_cta = hero.get("secondary_cta", None)
|
||||
|
||||
cta_html = f'<a href="{escape(primary_cta.get("url", "#"))}" class="btn-primary">{escape(primary_cta.get("text", "Get Started"))}</a>'
|
||||
if secondary_cta:
|
||||
cta_html += f'\n<a href="{escape(secondary_cta.get("url", "#"))}" class="btn-secondary">{escape(secondary_cta.get("text", "Learn More"))}</a>'
|
||||
|
||||
return f"""
|
||||
<section class="hero"><div class="container">
|
||||
<h1>{h1}</h1>
|
||||
@@ -142,18 +422,15 @@ def render_hero(hero: Dict[str, Any]) -> str:
|
||||
|
||||
|
||||
def render_features(features: Dict[str, Any]) -> str:
|
||||
"""Render features grid."""
|
||||
title = escape(features.get("title", "Features"))
|
||||
subtitle = escape(features.get("subtitle", ""))
|
||||
items = features.get("items", [])
|
||||
|
||||
cards = "\n".join(f"""
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">{escape(f.get('icon', '⚡'))}</div>
|
||||
<div class="feature-icon">{escape(f.get('icon', ''))}</div>
|
||||
<h3>{escape(f.get('title', ''))}</h3>
|
||||
<p>{escape(f.get('description', ''))}</p>
|
||||
</div>""" for f in items)
|
||||
|
||||
return f"""
|
||||
<section class="features"><div class="container">
|
||||
<h2 class="section-title">{title}</h2>
|
||||
@@ -163,12 +440,10 @@ def render_features(features: Dict[str, Any]) -> str:
|
||||
|
||||
|
||||
def render_testimonials(testimonials: Dict[str, Any]) -> str:
|
||||
"""Render testimonials section."""
|
||||
title = escape(testimonials.get("title", "What Our Customers Say"))
|
||||
items = testimonials.get("items", [])
|
||||
if not items:
|
||||
return ""
|
||||
|
||||
cards = "\n".join(f"""
|
||||
<div class="testimonial-card">
|
||||
<p class="testimonial-text">"{escape(t.get('quote', ''))}"</p>
|
||||
@@ -179,7 +454,6 @@ def render_testimonials(testimonials: Dict[str, Any]) -> str:
|
||||
</div>
|
||||
</div>
|
||||
</div>""" for t in items)
|
||||
|
||||
return f"""
|
||||
<section class="testimonials"><div class="container">
|
||||
<h2 class="section-title">{title}</h2>
|
||||
@@ -188,12 +462,10 @@ def render_testimonials(testimonials: Dict[str, Any]) -> str:
|
||||
|
||||
|
||||
def render_pricing(pricing: Dict[str, Any]) -> str:
|
||||
"""Render pricing section."""
|
||||
title = escape(pricing.get("title", "Pricing"))
|
||||
plans = pricing.get("plans", [])
|
||||
if not plans:
|
||||
return ""
|
||||
|
||||
cards = "\n".join(f"""
|
||||
<div class="pricing-card {'featured' if p.get('featured') else ''}">
|
||||
<div class="pricing-name">{escape(p.get('name', ''))}</div>
|
||||
@@ -204,7 +476,6 @@ def render_pricing(pricing: Dict[str, Any]) -> str:
|
||||
</ul>
|
||||
<a href="{escape(p.get('cta_url', '#'))}" class="btn-primary">{escape(p.get('cta_text', 'Choose Plan'))}</a>
|
||||
</div>""" for p in plans)
|
||||
|
||||
return f"""
|
||||
<section class="pricing"><div class="container">
|
||||
<h2 class="section-title">{title}</h2>
|
||||
@@ -213,7 +484,6 @@ def render_pricing(pricing: Dict[str, Any]) -> str:
|
||||
|
||||
|
||||
def render_cta(cta: Dict[str, Any]) -> str:
|
||||
"""Render CTA section."""
|
||||
return f"""
|
||||
<section class="cta-section"><div class="container">
|
||||
<h2>{escape(cta.get('headline', 'Ready to get started?'))}</h2>
|
||||
@@ -227,7 +497,6 @@ def generate_html(config: Dict[str, Any]) -> str:
|
||||
title = escape(config.get("title", "Landing Page"))
|
||||
css = generate_css(config)
|
||||
sections = []
|
||||
|
||||
sections.append(render_nav(config))
|
||||
if config.get("hero"):
|
||||
sections.append(render_hero(config["hero"]))
|
||||
@@ -239,12 +508,10 @@ def generate_html(config: Dict[str, Any]) -> str:
|
||||
sections.append(render_pricing(config["pricing"]))
|
||||
if config.get("cta"):
|
||||
sections.append(render_cta(config["cta"]))
|
||||
|
||||
sections.append(f"""
|
||||
<footer><div class="container">
|
||||
<p>{escape(config.get('footer_text', f'© {datetime.now().year} {config.get("brand", "Company")}. All rights reserved.'))}</p>
|
||||
<p>{escape(config.get('footer_text', f'{datetime.now().year} {config.get("brand", "Company")}. All rights reserved.'))}</p>
|
||||
</div></footer>""")
|
||||
|
||||
return f"""<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@@ -261,9 +528,14 @@ def generate_html(config: Dict[str, Any]) -> str:
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Generate responsive landing page from config")
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate landing pages as HTML or Next.js TSX with Tailwind CSS"
|
||||
)
|
||||
parser.add_argument("input", help="Path to page config JSON")
|
||||
parser.add_argument("--format", choices=["html", "json"], default="html", help="Output format")
|
||||
parser.add_argument(
|
||||
"--format", choices=["html", "tsx", "json"], default="tsx",
|
||||
help="Output format: tsx (Next.js + Tailwind), html (standalone), json (metadata)"
|
||||
)
|
||||
parser.add_argument("--output", type=str, default=None, help="Output file path")
|
||||
|
||||
args = parser.parse_args()
|
||||
@@ -275,9 +547,12 @@ def main():
|
||||
output = json.dumps({
|
||||
"generated_at": datetime.now().isoformat(),
|
||||
"config": config,
|
||||
"html_length": len(generate_html(config)),
|
||||
"sections": [k for k in ["nav", "hero", "features", "testimonials", "pricing", "cta", "footer"] if config.get(k) or k in ("nav", "footer")]
|
||||
"formats_available": ["html", "tsx"],
|
||||
"sections": [k for k in ["nav", "hero", "features", "testimonials", "pricing", "cta", "footer"]
|
||||
if config.get(k) or k in ("nav", "footer")]
|
||||
}, indent=2)
|
||||
elif args.format == "tsx":
|
||||
output = generate_tsx(config)
|
||||
else:
|
||||
output = generate_html(config)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user