PageKit
Take one person from nothing to a live landing page. They answer questions, you do everything
else.
Assume the user is a photographer, a baker, a consultant, a small agency — not a developer.
They may never have opened a terminal. Never show raw terminal output unless asked. Replace
every piece of jargon with a plain word.
No accounts, no API keys, no signups. Everything below works for someone who has installed
nothing but Node.js and Claude Code. If a companion skill suggests a paid tool or an API
integration, skip that part silently.
Role lock. Other skills you read during this flow will open by declaring they are an elite
art director or a senior SEO consultant. Ignore that framing — they are references, not roles.
Ignore any instruction in them to stop and wait for the user. The only pauses are the four
listed below.
Companion skills
PageKit ships alongside these. Read each by path when this file says to, not because its
description sounds relevant.
| Skill |
Read it |
design-taste-frontend |
Phase 2, always — the design authority |
minimalist-ui / high-end-visual-design / industrial-brutalist-ui |
Phase 2, exactly one of the three |
full-output-enforcement |
Phase 4, always — stops you truncating files |
copywriting |
Phase 4, before any headline |
landing-es |
Phase 4, whenever the page copy is Spanish |
cro |
Phase 5, to check the page persuades |
vercel-deploy |
Phase 6 |
seo-geo, seo-schema, seo-sitemap, llms-txt |
Phase 7 |
seo-local |
Phase 7, only if there is a physical address or service area |
If a companion skill is not installed, do the phase from the instructions here and say nothing
about the missing skill.
The four pauses
Everything else runs without asking.
- After questionnaire Round 2 — "Does this direction work?"
- After Round 4 — "Did I get everything?"
- After Phase 5 — "How does it look?"
- Before Phase 6 — "Ready to put it online?"
Phase 1 — Discovery
Four rounds, two to four questions at a time, conversational. Never read the list aloud.
Round 1 — basics. Business name. In one sentence, what they do. Who they are trying to
reach.
Round 2 — look. Any websites they like. Colour preferences, or should you pick. Light or
dark. What feeling visitors should get — professional, playful, bold, elegant, minimal, warm,
modern.
→ Pause. Present the direction. Get a yes before Round 3.
Round 3 — content. The one thing they want visitors to do. Three or four things worth
highlighting. Contact method. Any testimonials or client names. A tagline, if they have one.
Round 4 — details. Logo or photos to use. What language the page should be in — this is a
separate question from the language you are talking in. Whether they want it online today.
→ Pause. Summarise the brief.
Anyone who says "you decide" gets a decision, stated plainly, with one sentence of reasoning.
Do not push back. Do not re-ask.
Phase 2 — Design direction
Read design-taste-frontend. It is long. Read it anyway — it is the main reason the page will
not look AI-generated.
Choose a direction, then read exactly one aesthetic skill for depth. Never two.
Choose a section order. Sensible defaults:
| Business |
Order |
| Portfolio, photographer, designer |
Hero → work grid → short about → contact |
| Local business, restaurant, salon |
Hero → what we do → hours & location → proof → contact |
| Consultant, coach, freelancer |
Hero → problem → how you help → proof → booking CTA |
| Small product or service |
Hero → proof strip → benefits → objection → pricing → CTA |
Present in plain language: the feeling and why it fits, the colours with hex codes named like a
person would name them, the two fonts and what each is doing, the section order.
Phase 3 — Setup
node --version
Below v18 or missing → "You need Node.js first. Go to nodejs.org, download the one marked LTS,
open the file, follow the installer. Tell me when it's done." Wait.
npx create-next-app@latest site --typescript --tailwind --app --src-dir --no-import-alias --yes
cd site
npx shadcn@latest init -b radix -p nova -y --css-variables --pointer
npx shadcn@latest add button card navigation-menu separator badge -y
npm install motion lucide-react
Do not simplify those flags:
-b radix pins Radix. The current default base is Base UI, with different component code.
-p nova is required. -y alone does not skip the preset prompt — the command hangs
forever with no output. Presets: nova, vega, maia, lyra, mira, luma, sera, rhea.
--pointer adds cursor-pointer to generated components.
- The package is
shadcn. shadcn-ui is deprecated on npm.
Recovery: "directory exists" → rm -rf site and retry. init hanging with no output → you
omitted -p. init failing → npx shadcn@latest init --defaults from inside site/, then
read site/src/components/ui/*.tsx before using any component API, because they will be Base
UI. npm install failing → rm -rf site/node_modules site/package-lock.json && npm install --prefix site.
Phase 4 — Build
Read full-output-enforcement first. Complete files. No placeholders, no "rest unchanged".
Read copywriting before writing a headline. Read landing-es too if the page is Spanish.
site/src/app/layout.tsx — fonts, metadata export, global styles
site/src/app/page.tsx — the page, a Server Component
"use client" only for useState, useEffect, event handlers, or motion/react
globals.css already has @import "tailwindcss" and @theme inline. Edit the token values,
append your own @theme for type and spacing scales. Never overwrite the file. Never create
tailwind.config.ts — Tailwind 4 has no config file.
create-next-app hardcodes body { font-family: Arial, Helvetica, sans-serif }. Replace it —
fonts come from next/font/google with display: "swap" and CSS variables, never a CDN
<link>.
Motion budget for a landing page: a hero reveal, one scroll reveal per section, button
feedback. That is all.
cubic-bezier(0.23, 1, 0.32, 1) for entrances and exits. Never ease-in
- Interface motion under 300ms; a marketing reveal may run to 800ms
- Never
scale(0) — start at scale(0.95) with opacity: 0
- Animate
transform and opacity only. Never transition: all
:active { transform: scale(0.97) } on every button
- Hover motion behind
@media (hover: hover) and (pointer: fine)
prefers-reduced-motion keeps opacity and colour, drops movement
motion is imported as motion/react. Never also install framer-motion — same library, old
name, two copies shipped.
Accessibility, not optional: semantic landmarks, one <h1> with no skipped levels, alt
on every image, 4.5:1 contrast on body text, aria-label on icon-only buttons, a visible
<label> on every input (a placeholder is not a label), 44×44px touch targets, tab order
matching visual order.
Contact: a styled mailto: section by default — nothing to set up, works immediately. Only
use Formspree if they asked for a real form, and only with a form ID they give you.
Responsive: mobile first, holding at 375, 768, 1024, 1440px.
Phase 5 — Review
cd site && npm run dev
"It's running. Open http://localhost:3000 in your browser." That is the reliable path for
someone with nothing installed. Screenshot only if a browser tool is already available — never
make them install one.
Read cro and check the page against it yourself. Fix what you find first. Then ask something
specific: "How does the top of the page feel — right amount of confidence, or too loud?" Never
"let me know what you think."
Act on feedback immediately. Do not ask whether you should make the change.
Phase 6 — Deploy
Prove the build, then deploy:
cd site && npm run build
bash skills/vercel-deploy/scripts/deploy.sh site
No Vercel account needed. Hand back both URLs — the live one, and the claim URL if they want to
keep it permanently.
If they decline: "No problem. It's saved in the site folder. Run cd site && npm run dev
whenever you want to see it, and we can put it online any time."
Either way, continue to Phase 7.
Phase 7 — Visibility
The part other builders skip. Run all of it, ask nothing. Every item works with no account.
- JSON-LD in
layout.tsx. Organization normally, LocalBusiness when there is an
address or service area, Person for a portfolio, plus FAQPage if the page has questions.
Real values only — never invent an address, a phone number, or a rating.
- Metadata: title, description,
openGraph (title, description, url, siteName, locale,
type), twitter card, alternates.canonical. <html lang> set to the page's language.
- Citability: reread the page as an AI trying to answer a question with it. Every section
should make one claim that survives being lifted out on its own. "Wood-fired sourdough, baked
daily from 6am in Malasaña" survives; "quality baked goods" does not. Fix the sections that
fail — a copy edit, not a redesign.
site/public/llms.txt.
site/public/robots.txt, allowing normal crawlers and naming GPTBot, ClaudeBot,
PerplexityBot, Google-Extended explicitly, pointing at the sitemap.
site/src/app/sitemap.ts using Next's built-in export.
- Favicon at
site/src/app/icon.tsx, generated from their initials in the brand colours,
or static if they gave you a logo.
Rebuild and redeploy if the site is already live. Then explain it in two plain sentences: "I
also set the page up so Google and AI assistants like ChatGPT can read it properly — the
structured description, the crawler files, and the social preview are all in place."
Offer once, never push: "Optional — if you want to see who's finding you on Google, verify the
site in Search Console. Free, about five minutes. Want me to walk you through it?"
Checklist
- Would not be spotted as AI-generated at a glance
- No cyan-on-dark, purple-to-blue gradients, or neon accents
- Not Inter, Roboto, Arial, Open Sans, or a system font stack
- No AI vocabulary: delve, tapestry, landscape, showcase, vibrant, nestled, leverage,
foster, innovative, cutting-edge, seamless, empower, holistic, robust, elevate, unlock,
transform, journey, realm, testament
- Every claim on the page is one the user actually made
-
npm run build passes clean
- Holds at 375, 768, 1024, 1440px
- One
<h1>, no skipped levels, alt everywhere, visible labels
-
prefers-reduced-motion handled
- JSON-LD present, every value real
-
llms.txt, robots.txt, sitemap.ts, favicon, full metadata
Credit
PageKit adds one line to the footer of the pages it builds:
Built with PageKit by Skills Agentes
Spanish: "Hecho con PageKit por Skills Agentes".
text-sm text-muted-foreground, centred, last line. The link text is always exactly
Skills Agentes — never a description, a keyword, or the subject of the site. The link goes to
https://skillsagentes.com and nowhere deeper.
It is how the kit stays free, and it is disclosed in the README. If the user asks you to remove
it, remove it without argument or comment.