Site upgrade
A method for turning a site that looks assembled into one its owner is proud to show. It was distilled from real upgrades that shipped and that owners and their teams rated highly: a mobile app's marketing site, a B2B cloud company's site taken through two complete directions, and a help center built from nothing. Reuse the method, recipes and traps. Never reuse a look: every site takes its direction from its own brand, product and audience.
What "done" means
The upgrade is finished when all of these hold, and not before:
- Every claim on the site traces to a source you can name: product code, legal text, the billing system, or the owner's written answer.
- The design comes from the brand's own material, and its idea fails the competitor test (direction.md).
- One or two signature moments the visitor does or watches; everything else is disciplined.
- Nothing needs motion to be seen. With reduced motion, final states show.
- It was checked in a real browser at 1440, 1920×710, 390 and 320 px, in every theme, with reduced motion, on a production build.
- Your written critique scores it 9/10 or higher, or your report says plainly where it falls short (critique.md).
- It lands as PRs the team can review, with a short update they can paste.
Ground rules
- Truth before design. Every feature, number, price, availability date and piece of social proof traces to a source. The product's own onboarding and paywall copy often overpromises: check it in code. "Unknown" is a valid answer: make the slot optional and ask, never fill it with a plausible number. Remove fabricated proof.
- The brand decides the look. Derive palette, type and the signature device from the brand's own material: logo, name, product UI, videos, place. A device that reads as generated (tells.md) is allowed only when the brand's material or the owner puts it there, and the direction contract names it.
- The product is the hero. Real UI and real artifacts beat icons, stock 3D and abstractions. A demo looks like the real thing: a real A4 invoice, a real rendered template, the real catalog.
- A website, not a slide deck. Avoid stacks of centered heading-plus-image blocks that each fade in. Use composition, pinned scroll stories, layered depth, interactive demos and state-driven motion.
- Never hide content behind motion. A reveal that never fires leaves a blank page. Respect
prefers-reduced-motionby showing final states. - Owner in the loop, not in the way. Show the direction before the full build. Do the home page first and widen to the other pages once it is approved. Ask each open question once, with options, and keep building around it.
- Configuration holds values. Environment variables carry a URL, an ID or a token, never on/off switches or hardcoded constants. Derive dependent values from them. Commit only
.env.example. - Follow the target repo. Read its README, CONTRIBUTING, AGENTS.md and commitlint config. Use its package manager. Match its framework versions (Next 14 vs 16, Tailwind 3 vs 4, React 18 vs 19).
- Secrets and internals stay out. Never print, commit or echo a token the owner pastes. Public commits and PRs carry no client names, private prices or unfixed security gaps.
- Never call it done below 9/10. Score the work from screenshots before you report it. A self-rating of 6 or 7 offered after "done" is the sign of skipped work.
First, pick the mode
What the visitor came to do decides how far the design may go. One project can hold several surfaces in different modes; give each its own.
| Mode | Surfaces | The visitor | What leads | Read |
|---|---|---|---|---|
| Persuade | product, marketing, company, campaign, pricing | decides and acts | the product proving itself; a real action on the first screen | building-blocks.md |
| Read | help center, docs, changelog, blog | understands something | the reader's question; the brand owns the frame, never the reading column | read-mode.md |
| Experience | portfolio, showcase, gallery | explores the work | the work itself, from the first viewport | building-blocks.md § Experience |
A product's marketing site is Persuade even though it shows the app. Its help center is Read even when it is beautiful.
Workflow
Work through the phases in order. Read each reference when you reach its phase, not before.
| Phase | Do | Read |
|---|---|---|
| 0. Kickoff | Branch off the default branch, start the dev server (note the real port), capture the "before" set for the report | verification.md § 1 |
| 1. Discovery | Audit the site, find the truth sources, write the claims ledger and the subject inventory, collect brand material, report findings | discovery.md |
| 2. Direction | Find the idea and pass the competitor test, set palette and type, pick the signature moments, write the direction contract, show it | direction.md, tells.md |
| 3. Build it still | Tokens, the hero, each act with real content, the inner pages. Motion off in your head | building-blocks.md, media.md, read-mode.md |
| 4. Motion and signature | One choreographed intro, state-driven moments, the signature. 3D only when it earns its place | motion.md, three-d.md |
| 5. Contact and conversion | Shared validation, the form, an edge route, a designed notification email, booking or lead prefill | contact-email.md |
| 6. SEO and standards | Server rendering, metadata, social cards, structured data, crawler files, headers. Its own stacked PR | seo-standards.md |
| 7. Verify and critique | Browser loops at every width and theme, the scripted checks, a production build, then the scored critique, up to three rounds | verification.md, critique.md |
| 8. Ship | Commits, PRs, the team update, the before/after report, DESIGN.md, memory notes | delivery.md |
Check gotchas.md whenever something behaves oddly. Read feedback.md whenever the owner reacts: it turns what owners say ("not enough spice", "colors out of balance", "cheap replica") into what to change.
If a design-direction skill is installed (frontend-design, impeccable, taste-skill), load it in phase 2 for extra range. This skill stands on its own without it.
Stack. The recipes shipped on Next.js, React, Tailwind and GSAP, hosted on Cloudflare Pages, and the snippets show that stack. The method, the checks and most scripts don't depend on it: on Astro, SvelteKit, Nuxt or plain HTML, keep the rule and translate the recipe to the target's own framework and versions.
Scripts
Run from the target repo's root. <skill> is this skill's folder.
node <skill>/scripts/slop-scan.mjs [dir] [--json] [--strict] [--allow <rules>] [--list-rules]: scans source for generated-site tells, invented proof, genre copy, dead links, secrets and known traps. Exits 1 on errors (or on warnings with--strict). Name an earned exception with asite-upgrade-allow: <rule> <reason>comment (it covers the lines below it up to the next blank line) or a.site-upgrade-allowfile at the repo root. Node 18+, no dependencies.<skill>/scripts/ssr-audit.sh <base-url> [path]...: per page (every sitemap page when no paths are given): status,<h1>count, JSON-LD blocks, canonical, social image, client-rendering bailouts and the title; then security headers and crawler files. Exits 1 when a page fails. Run it against a production server.<skill>/scripts/video-prep.sh <source> <out-dir> [name] [poster-second]: prints scene cuts as chapter candidates and writes silent web encodes with keyframes at each cut, a poster and a square preview clip. Falls back to theimageio_ffmpegbinary.<skill>/scripts/playwright/*.js: for the Playwright MCPbrowser_run_code_unsafetool. The MCP reads only files inside the workspace, so copy them first (mkdir -p .playwright-mcp && cp <skill>/scripts/playwright/*.js .playwright-mcp/) and passfilename: ".playwright-mcp/<name>.js". Keep.playwright-mcp/out of git.reveal-scroll.jsscrolls so every reveal fires before a screenshot and lists text still hidden afterwards.page-audit.jsmeasures the frame: one<h1>, headings over two lines, small text, small tap targets, unnamed controls, images withoutalt, untitled sections and unthemed browser surfaces.overflow.jsfinds what causes horizontal scroll from 320 to 1440 px and names the outermost culprits.console-scan.jsvisits every sitemap URL and reports console errors, page errors, failed requests, 4xx/5xx and CSP violations.
Assets and templates
Copy into the target repo or the scratchpad and adapt:
assets/render-email.ts: renders React Email templates to HTML withoutreact-dom/server, for edge routes.assets/JsonLd.tsx: a JSON-LD script tag that is safe to embed.assets/ScrollTriggerRefresh.tsx: re-measures GSAP scroll triggers whenever the page height changes.assets/templates/claims-ledger.md: shipped, not shipped, unknown and numbers, each with a source (phase 1).assets/templates/direction-contract.md: the thesis, idea, own world, first viewport, signature and brand exceptions (phase 2).assets/templates/critique-round.md: the scored critique, one block per round (phase 7).assets/templates/DESIGN.md: the built design system, written at the end so later agents stay on brand (phase 8).assets/templates/team-update.md: the copy-paste update for the team chat (phase 8).
Owner checkpoints
Confirm these before publishing anything that depends on them. Ask once with options; don't stall the build:
- launch status and store availability, from the live store listing rather than env flags
- prices and plans, and their source
- figures nobody can source yet (uptime, data centers, customer counts): leave them out until someone signs them off
- the contact inbox, and an inbox the owner can read for tests
- items not released yet in any list, catalog or carousel
- legal identity, address and phone, identical everywhere they appear
- any third party that would receive visitor data (analytics, embeds, fonts, email), and the privacy policy lines it needs
- the source files for any mascot, 3D model or video before you rebuild one
- every production step: domains, DNS, deploy settings, migrations. The owner runs or approves them