| name | lp-improve |
| description | End-to-end landing-page improvement workflow - structure audit (PASBECONA), persona-spine decision, copy discipline, visual de-templating, and release with readback verification. Covers the i18n traps of exact-key dictionaries and DOM-walker translation, dual dev/prod surfaces, and vendored-package sync. Triggers - "improve the landing page", "LP redesign", "rework the LP copy", "audit the landing page". |
lp-improve — landing-page improvement, end to end
Principle: no copy before ground truth, no release without readback.
Distilled from a full-day LP overhaul (structure redesign → three copy rounds →
visual de-templating → dev/prod sync → a mixed-language regression traced to its
mechanism and closed for good).
Phase 0 — Scout (before any design)
- Locate every deploy surface. Dev and prod may serve different codebases
— e.g. prod consuming the LP as a vendored package snapshot. Probe each
domain's release endpoint (
/releasez or equivalent) and trace revisions
back to their actual source before editing anything.
- Read the i18n mechanism before touching copy. A common shape: English
strings are the source keys; the target language lives in an exact-match
dictionary, with a DOM-walker doing fuzzy segment substitution as fallback.
Two traps:
- Changing one character of an English source string silently detaches its
translation and drops the text to the fuzzy fallback. Always: finalize
the English key first, then add/update the translation pair in the same
change.
- Never let embedded/demo UI depend on the host page's DOM walker. When
the component is later embedded in a host with an older dictionary, exact
lookups miss and segment fallback produces mixed-language output. Demo UIs
must translate themselves (explicit
t() on every string) and carry a
skip marker (data-i18n-skip or equivalent) so no host walker touches them.
- Treat dead code from previous LP versions as copy assets — extract the
knowledge (personas, pain points, proof points) into a docs file before
anything gets deleted.
Phase 1 — Structure (PASBECONA audit)
- Audit the current page against PASBECONA (Problem / Affinity / Solution /
Benefit / Evidence / Contents / Offer / Narrowing-down / Action). The usual
findings: Solution oversupplied across several sections, Problem /
Evidence / Narrowing missing entirely, and neutral "for both teams"
narration that lands with nobody.
- Pick one persona as the spine — the one who actually buys/adopts. Other
personas become characters inside that persona's story (a developer's pains
often arrive in the platform engineer's inbox as tickets). One explicitly
labeled point-of-view-switch section mid-page is a clean way to serve a
secondary persona without splitting the narrative.
- Benefit→Evidence pairing: every benefit claim is followed immediately by
its proof. With no customer logos yet, build Evidence on verifiability:
real product screens, action→receipt tables, the standards you build on,
open source.
- Narrowing-down uses only real constraints. Never invent urgency. If no
real constraint exists, run without the N element.
- Write the design doc in the repo/vault and get owner rulings one question
at a time. Record each ruling in the doc's changelog with strikethroughs —
future sessions can see why things are the way they are.
Phase 2 — Copy discipline
- Imagine the persona's actual day before writing — the tool-picking
fatigue, the upgrade night, the day lost to tickets. The resolution of the
copy equals the resolution of the imagination behind it.
- Headings state the experience, never the category label. Not "challenges
platform teams face" but "Upgrade nights are prayer nights."
- Target-language register matters (Japanese example: no second-person
pronouns — use role nouns and zero-subject phrasing; soften blunt words in
headings; a translated "you/your" voice reads as unnatural).
- Avoid self-defeating claims: "you don't need another tool" invites "but
you are a tool." Frame as replacement of what they already hand-build, not
addition.
- No invented metrics. If the number doesn't exist, delete the slot.
- Cut, don't add. Body copy usually survives a 30% trim; demo-UI captions
too. The guardrail against over-cutting: keep structure and bullet texture.
- Control heading line-breaks in CJK: explicit
\n splits (with the i18n
skip marker) for desktop; word-break: auto-phrase (Chromium BudouX) plus an
overflow-wrap: anywhere guard for mobile. Verify at 375px.
Phase 3 — Visual (de-templating)
- Run a design audit first (e.g. the hallmark skill's
audit verb) and show
the ranked findings to the owner to scope the redesign — which parts are
preserved (nav/footer often are) is an owner call.
- Redesign bounded: copy, section order, information architecture, and
brand tokens preserved; only structural fingerprint and component voice
change. Typical prescriptions: introduce a display face (check for loaded
but unused fonts first), break equal-column grids into asymmetric /
stair / ledger forms, remove fake browser chrome from product mocks, vary
section density.
- Section ids are anchors — treat them as external contracts. Before
renaming or dropping one, audit who references it (other apps' redirects,
inbound links, sitemaps). Pin externally referenced ids with contract
tests on both sides: the LP asserts the contracted ids exist; the
consumer asserts every redirect hash resolves to an id in the package it
ships.
- Verify: typecheck / lint / build plus full-page screenshots in every
language × 1440px and 375px, asserting zero horizontal overflow — and a
full link/anchor crawl of the rendered DOM (every
a[href]: internal
links return 200 without not-found copy, #hash targets exist, and
redirect landings with hashes resolve). Repeat the same crawl as part of
the post-release readback.
Phase 4 — Release (judged by readback, not by CI color)
- Back up the current page wholesale to a separate route
(
/previous-lp-N) before editing in place.
- Known CI traps: flaky e2e suites (reproduce locally first, then rerun);
branches that silently stop spawning workflow runs (recover via rebase +
force-push or a fresh branch); parallel lanes fixing the same issue
(on conflict, integrate on top of the other lane's tested implementation).
- If hot-release workflows are intentionally disabled, the discipline is
enable → dispatch → readback → restore disabled (the disabled state is
someone's decision; put it back).
- A run's failure verdict is not a deploy failure. Activation-latency SLO
steps often fail while the deploy succeeded. Judge by the release endpoint's
revision plus live-bundle/screenshot probes — always.
- When prod consumes the LP as a vendored package: extract the current
tarball as the template, port the latest source into it (relative imports,
a Link shim, a language context instead of host hooks), bump the version,
repack. Update every supply-chain pin in the same change: workflow
SHA-256 env, contract-test tarball paths, and all lockfiles — and run the
contract test locally before pushing.
- After release, probe live output for expected translated strings present
and mixed-language / leak patterns absent.
Phase 5 — Records and closure
- One ledger line per real change (merge/live) using absolute paths; workflow
enable/disable toggles are operational events worth a line too.
- Close tracker issues with receipt comments: revisions, readback results,
and known constraints (e.g. "auto-phrase is Chromium-only").
- Update the design doc's status header. Report with the outcome first.
- When a regression report arrives: identify the mechanism, then choose the
fix that closes the recurrence path itself (cut the dependency), not the
one that patches the symptom.