Redesign: one story, told on a phone - #130
Merged
Merged
Conversation
The v3 direction is a quieter, warmer site: one type scale instead of per-component sizes, a light and dark palette defined as tokens in one place, and spacing that comes from a rhythm rather than from whatever each section needed. Everything after this commit reads from these tokens, so it lands first. Comfortaa goes with the old look and Nunito replaces it. sweetalert2 leaves with the last dialog that used it — nothing on the new site opens one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Avatar, LevelBars, Segmented and UiIcon are what the new sections are built out of — a person, a proficiency, a two-way switch, an icon that takes its colour from the text around it. Button, Image, Logo and Tag move onto the tokens from the previous commit. The sparkle set goes: Sparkles, SingleSparkle and the three highlight molecules that wrapped text in them were the old site's idea of emphasis, and the new one gets emphasis from type and space instead. Card goes with them — every surface that used it now has its own shape. inview.ts is the one primitive the scroll-told story needs: an IntersectionObserver action that fires once. cta.ts keeps the call to action the reader last saw, so the sticky bar and the closing section agree on what they are offering. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The site's job is to show what using LangX is like, and screenshots age badly and read as marketing. These are the app's own screens rebuilt in Svelte inside a frame — feed, chat, discover, tokens, paywall, me, welcome back — so the story can move between them as the reader scrolls, and so a copy change on the app does not leave a stale PNG behind. languages.ts is the list they are populated from; the faces in static/images/people are the demo cast, not real users. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The old homepage was a stack of unrelated blocks — features, about, Discord, sponsors, token, newsletter, recent posts — each explaining itself to a reader who had not yet been given a reason to care. The new one is a single narrative: meet someone who speaks what you are learning, talk to them, and the app carries the rest. Story drives the phone from the previous commit as it scrolls; Anywhere and LanguageMarquee say how far it reaches; FinalCta closes. SiteShell replaces the (waves) route group, and with it the wave decoration those pages were named after — the new layout separates sections with space, not with a shape drawn between them. The route group is now (site), which says what it is. Sponsors, Discord and the token block are not gone from the site; they belong to the pages that are about them, not to a reader's first ten seconds. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Pricing, pro, welcome back, the blog, the error page and the four legal pages were all built against the old tokens and the old shell, so they inherit the new ones here: PageHeader for their tops, the shared type scale for their bodies, markdown styling for the legal text. features.ts loses the copy the old feature grid needed and keeps what the pricing table still reads. meta.ts follows the store listing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
DESIGN.md records the tokens, the type scale and the component rules the previous commits established, derived from what shipped rather than from what was intended — the next change to this site should read it before inventing a new value. PRODUCT.md is the claim list: what the site says LangX does, and which plan each claim belongs to. The README's cross-repo table said `langx2`; that checkout is gone and the sources of truth live in `langx`. .impeccable/ keeps the design record and the surface notes; its screenshots, build state and cache stay out of the repo. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
main already made this change (#132) and it is what langx.io serves; this branch redrew the form after that fix branched off and still posted to v1's /api/mail, which api.langx.io has not answered since 3 September 2026. Same URL, same `status: 'ok'` check, so nothing else on the form moves — and the redesign no longer reintroduces the broken form when it ships. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The page promised the streak was "held for you and can be restored by spending tokens". The app stopped charging for it: a returning v1 user's streak is restored alive along with their profile, and the product that sold it back was removed. This claim and the rule behind it are kept in step by hand — the app is in `langx/`, the sentence is here — so a change on that side is only half done until this one moves too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Keeps main's newsletter endpoint (v2's /public/newsletter) inside the redesigned form. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The homepage was a stack of blocks — features, about, Discord, sponsors, token, newsletter, recent posts — each explaining itself to a reader who had not yet been given a reason to care. This replaces it with a single narrative: meet someone who speaks what you are learning, talk to them, and the app carries the rest.
The app is shown as its own screens rebuilt in Svelte inside a phone frame, driven by scroll, rather than as screenshots — so a copy change in the app does not leave a stale PNG behind here.
What is in it, commit by commit
refactor(style)— the design foundation: one type scale, light/dark palette as tokens in one place, spacing from a rhythm. Comfortaa and sweetalert2 out, Nunito in.feat(components)— new atoms (Avatar, LevelBars, Segmented, UiIcon),inviewaction,ctastore. The sparkle set, the three highlight molecules and Card are removed; emphasis now comes from type and space.feat(phone)— nine app screens in a frame, plus the language list and the demo cast.feat(home)— Story, Anywhere, LanguageMarquee, FinalCta. The(waves)route group and its wave decoration become(site)with a sharedSiteShell.feat(pages)— pricing, pro, welcome back, blog, error and the four legal pages onto the new tokens.docs— DESIGN.md (the system as shipped) and PRODUCT.md (what the site claims, and which plan each claim belongs to). The README's cross-repo table saidlangx2; that checkout is gone, the sources of truth live inlangx.Sponsors, Discord and the token block are not gone from the site — they belong to the pages that are about them, not to a reader's first ten seconds.
Checks
vite build,eslint .andprettier --check .are clean on the branch tip (Node 24, sovite builddirectly — thepostbuildimage step still breaks there).The intermediate commits were not built individually: the checks above ran on the final tree, so a
git bisectthrough this branch may hit a commit that does not compile.Not verified here
langx/packages/shared— the limits and token rules mirrored insrc/lib/datawere not re-checked against the app in this pass.🤖 Generated with Claude Code