Help us improve
Share bugs, ideas, or general feedback.
From landing
Generates a premium single-page HTML landing page with 3D CSS animations, GSAP scroll effects, and mouse-parallax depth. Forcing intake (product + elevator pitch, audience register, brand overrides, tone) locks down positioning before any copy or markup is written, so the page reflects the actual product rather than generic boilerplate. Use whenever the user says 'landing for X', 'create a landing page', 'build a landing page', 'make a landing page for X', 'I need a web page for Y', or provides product/service details and wants a polished website. Also triggers on 'promotional page', 'product page', 'one-pager', 'web presence', 'sales page'. Outputs a single self-contained HTML file (Claude Code) or HTML artifact (Claude.ai). Supports configurable brand colors via CSS custom property overrides.
npx claudepluginhub msm47/gitskil --plugin landingHow this skill is triggered — by the user, by Claude, or both
Slash command
/landing:landingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Distinct from `product-team/skills/landing-page-generator/`.** That skill outputs Next.js TSX components optimized for conversion / lead-gen. THIS skill outputs a single self-contained `.html` file optimized for premium visual experience with GSAP animations. Pick by use case.
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Explores codebases via GitNexus: discover repos, query execution flows, trace processes, inspect symbol callers/callees, and review architecture.
Share bugs, ideas, or general feedback.
Distinct from
product-team/skills/landing-page-generator/. That skill outputs Next.js TSX components optimized for conversion / lead-gen. THIS skill outputs a single self-contained.htmlfile optimized for premium visual experience with GSAP animations. Pick by use case.
Generate a polished, self-contained .html landing page from a text prompt or brief. The output is ONE HTML file: all CSS inline in <style>, all JS inline in <script>, only external dependencies being Google Fonts + GSAP via CDN. The page is visually distinctive, animated, and production-quality.
In Claude Code CLI, write the file to disk at the specified path. In Claude.ai web, create an HTML artifact with the same content.
Dependency-ordered. Each question carries explicit "why I'm asking". Stop condition: max 4.
What's the product or service? Give me the name + a 1–2 sentence elevator pitch — what does it do, and who's it for?
Why I'm asking: The headline, subtext, and feature copy all derive from this. "App for productivity" produces generic boilerplate; "Async standup tool for remote engineering teams who hate Zoom" produces a landing page that converts.
Refuse mush. If user gives just a name with no pitch, push back once: "What does it do? Who's it for?" If still no pitch after push-back, deliver with explicit "generic positioning" caveat.
Who's the audience? Pick one:
- Technical buyers (engineers, ops, security)
- Business buyers (PMs, execs, ops leaders)
- Consumers (general public, hobbyists)
- Internal (employees, partners — not for public sale)
Why I'm asking: Audience dictates copy register, jargon level, social-proof choices, and CTA framing. Technical buyers want specifics; consumers want benefits; internal pages can skip persuasion.
Forcing choice.
Brand colors / fonts to override the default (dark navy + teal + Inter)? Provide as: primary HEX, accent HEX, optional bg HEX. Or say "default" if you want the polished default.
Why I'm asking: The default is intentionally beautiful, but matching your brand makes the page feel native to your existing site. Even just a primary color override goes a long way.
Accept "default" or partial overrides (e.g., just primary). If only primary provided, derive accent algorithmically (lighten / darken).
Tone — pick one:
- Professional — confident, restrained, B2B-friendly
- Playful — warm, light, occasional humor
- Authoritative — expert, data-forward, trust-building
- Minimal — terse, design-led, low copy density
Why I'm asking: Tone affects every sentence — headlines, microcopy, button text, closing copy. Picking upfront prevents tonal whiplash across sections.
Forcing choice. Recommended default: professional if Q2 = technical/business; playful if Q2 = consumer; minimal if the product is design-led.
Stop condition: After Q4, commit and generate. No follow-up questions during generation.
From Q1's elevator pitch, derive:
Fallback when input is sparse: invent compelling content from product-name semantics + audience register. Flag inferred content with a comment in the HTML source (<!-- inferred: ... -->). Don't stall waiting for more input.
:root {
--navy: #0A1628;
--navy-mid: #0D1F38;
--teal: #00D4AA;
--teal-glow: rgba(0, 212, 170, 0.12);
--amber: #F5A623;
--off-white: #F7F7F2;
--text-muted: rgba(247, 247, 242, 0.68);
--card-bg: rgba(0, 212, 170, 0.06);
--card-border:rgba(0, 212, 170, 0.15);
}
When Q3 provides custom brand values, the skill substitutes them into the :root block:
Brand override:
- primary: #FF6B35 → --navy / hero bg
- accent: #2EC4B6 → --teal / CTA / highlights
- bg: #011627 → --navy-mid / section bg
- text: #FDFFFC → --off-white
If only primary provided, derive accent algorithmically (lighten 15% for accent; darken 8% for navy-mid; convert to rgba at 0.12 alpha for glow). Use scripts/brand_palette_validator.py for the deterministic derivation.
See references/brand_system_design.md for color theory + WCAG + algorithmic palette derivation canon.
.btn-primary — CTA button with hover state (lift + brightness).feature-card — card with hover lift (translateY(-6px) + border-brighten).eyebrow — letter-spaced (0.2em) uppercase category labelmin-height: 100vh, flex-centered content.hero-shapes-back — large blurred circles, absolute-positioned, low opacity.hero-shapes-mid — smaller shapes, sharper edges, higher opacityrepeat(3, 1fr) grid)transform: translateY(-6px)border-color: var(--teal) (brighten from --card-border)transition: 0.3s easebackground: var(--navy-mid)padding: 120px 24px, text-align: centerbackground: radial-gradient(circle, var(--teal-glow) 0%, transparent 70%);
See references/gsap_animation_patterns.md for the canon. Five patterns required:
// MUST use gsap.set() FIRST to prevent FOUC
gsap.set([".eyebrow", ".hero h1", ".hero .subtitle", ".btn-primary", ".scroll-down"], {
opacity: 0,
y: 30
});
const tl = gsap.timeline({ defaults: { ease: "power3.out" } });
tl.to(".eyebrow", { opacity: 1, y: 0, duration: 0.6 })
.to(".hero h1", { opacity: 1, y: 0, duration: 0.8 }, "-=0.3")
.to(".hero .subtitle", { opacity: 1, y: 0, duration: 0.6 }, "-=0.5")
.to(".btn-primary", { opacity: 1, y: 0, duration: 0.5 }, "-=0.3")
.to(".scroll-down", { opacity: 1, y: 0, duration: 0.4 }, "-=0.2");
const hero = document.querySelector(".hero");
hero.addEventListener("mousemove", (e) => {
const x = (e.clientX / window.innerWidth - 0.5) * 2;
const y = (e.clientY / window.innerHeight - 0.5) * 2;
gsap.to(".hero-shapes-back", { x: x * 45, y: y * 22, duration: 0.8 });
gsap.to(".hero-shapes-mid", { x: x * 22, y: y * 11, duration: 0.8 });
gsap.to(".hero .container", { x: x * 8, y: y * 5, duration: 0.8 });
});
gsap.set(".feature-card", { opacity: 0, y: 55, rotateX: 18 });
ScrollTrigger.batch(".feature-card", {
start: "top 80%",
onEnter: batch => gsap.to(batch, {
opacity: 1, y: 0, rotateX: 0,
duration: 0.8,
stagger: 0.11,
ease: "power2.out"
})
});
CSS handles ambient continuous motion (smoother, cheaper than GSAP for indefinite animations):
@keyframes floatA {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
50% { transform: translate(20px, -30px) rotate(8deg); }
}
@keyframes floatB { /* different duration + rotation */ }
@keyframes floatC { /* different duration + rotation */ }
.hero-shapes-back .shape-a { animation: floatA 12s ease-in-out infinite; }
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(8px); }
}
.scroll-down { animation: bounce 2s ease-in-out infinite; }
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
NO other external CSS or JS files. All custom CSS in <style>, all custom JS in <script> blocks within the same HTML file.
See references/single_file_html_discipline.md for the inline-only rationale.
120px 24px (vertical 120, horizontal 24, scales down on mobile)<meta name="viewport" content="width=device-width, initial-scale=1">${OUTPUT_DIR}/<product-name-kebab>.html${OUTPUT_DIR}: ./landing-pages/quill-ai.html). Use scripts/kebab_slug_generator.py for deterministic slug generation + duplicate detection.<style>, all JS in <script>, only Google Fonts + GSAP CDN external.Run scripts/html_validator.py --file ${OUTPUT_DIR}/<slug>.html after generation. Checks:
.hero, .features, .closing-cta)gsap.set() initial states precede any gsap.timeline or gsap.to (FOUC prevention)<link rel="stylesheet"> other than Google Fonts<script src=> other than GSAP CDN<meta name="viewport"> present| Situation | Behavior |
|---|---|
| Input is just a name with no context | Invent compelling content from name semantics + audience register; flag as <!-- inferred --> in HTML source |
| Input file is large or PDF | Read fully before generating; don't truncate |
| Brand colors insufficient (only 1 HEX provided) | Use as primary; derive secondary/accent algorithmically (lighten/darken via brand_palette_validator.py) |
| Features count not specified | Default to 4 |
| Output dir doesn't exist | Create it |
| Existing file at output path | Append timestamp suffix or ask user (kebab_slug_generator.py flags duplicates) |
| html_validator returns FAIL | Regenerate ONLY the failing sections in one targeted pass; do NOT abandon the file |
| Script | Role |
|---|---|
scripts/brand_palette_validator.py | Validates HEX format, checks WCAG AA contrast, generates derived palette from primary (algorithmic lighten/darken). |
scripts/kebab_slug_generator.py | Product name → kebab-case filename + duplicate detection in output dir. |
scripts/html_validator.py | Post-generation structural check: 3 sections, CDN deps, gsap.set() initial states, responsive breakpoints, no external files. |
references/brand_system_design.md — color theory + WCAG + algorithmic palette derivation (7+ sources)references/gsap_animation_patterns.md — entrance timeline + ScrollTrigger reveals + mouse parallax + CSS floats + scroll indicator (7+ sources)references/single_file_html_discipline.md — why inline + CDN-only externals + accessibility minimums + no-build rationale (7+ sources)gsap.set() initial states (causes FOUC)Version: 1.0.0
Source spec: megaprompts/04-landing-megaprompt.md
Build pattern: Path B (direct conversion). Distinct from product-team/skills/landing-page-generator/.