Skip to content

WIP: Redesign livepeer.org - #93

Draft
adamsoffer wants to merge 10 commits into
mainfrom
claude/livepeer-redesign-plan-110a98
Draft

WIP: Redesign livepeer.org#93
adamsoffer wants to merge 10 commits into
mainfrom
claude/livepeer-redesign-plan-110a98

Conversation

@adamsoffer

@adamsoffer adamsoffer commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

🚧 Work in progress — not ready to merge. Opened as a draft for review of direction and shape. See Before this can ship for the blocking items.

Rebuilds the marketing site against Peace Node's Livepeer UI registry. The registry theme is now the only token layer.

Pages

Eight linked pages, all built from the mockup set:

Page Route Notes
Home /
Agent /agent flagship product surface
Ecosystem /ecosystem /[slug], /submit — markdown-driven catalog
Provide GPU compute /compute one page for running + earning
Token /token
Foundation /foundation
Latest /blog nav says "Latest", URL stays /blog
Brand /brand no mockup — designed from design.md + registry Foundations

/primer stays intact and unlinked with its own scoped legacy slice — the one page deliberately left unmigrated.

Content is authored in-repo as typed objects matching the registry's content contracts (lib/site.ts), plus markdown for blog and ecosystem. No CMS, deliberately — the Sanity client stays stubbed.

Cleanup

globals.css 1209 → 585 lines. Removed the second --color-* token layer, the Holographik grid, hero classes, .blog-prose, 19 keyframes and 37 custom properties. Chart/sidebar/radius tokens are kept — unused today, but they're the registry's theme contract.

Deleted ~73 files: components/home/*, components/legacy/*, components/ecosystem/* (superseded by components/livepeer-ui/*), the PascalCase components/ui/* visuals, lib/constants.ts, and the five app/use-cases/* routes — redirects in next.config.ts already served those URLs, so the pages were unreachable.

pnpm lint is now clean at zero warnings.

Share images

Rebuilt on the registry's own og item. / renders the brand card verbatim — the lockup centred on #000000. Every other page renders the same canvas with a page title, from one shared lib/og.tsx.

Two bugs fixed along the way:

  • Only the root had a twitter-image, and metadata files cascade — so /foundation and /blog served their own og:image but the root's Twitter card. Every segment now has a re-export beside its opengraph-image.
  • Ecosystem project pages had no share image at all: their generateMetadata declares an openGraph object without images, which drops the inherited card. All 12 projects now get their own titled card.

Blog posts keep their frontmatter art and are unaffected.

Incidental fixes

  • app/not-found.tsx styled its link text-green — green as an affordance colour, which the design system explicitly rules out. Rebuilt on the registry type scale.
  • sitemap.ts advertised the five dead /use-cases URLs and never listed /agent or /compute. Rewritten, with ecosystem projects added.
  • Instrument Serif was downloaded on every page load with zero consumers. Removed.
  • package-lock.json deleted. Six deps had been added via npm in a pnpm-pinned repo, leaving pnpm-lock.yaml stale — pnpm install --frozen-lockfile was failing, which would have broken the Vercel build. Lockfile regenerated and verified.

Verification

pnpm typecheck, pnpm lint (0 warnings) and pnpm build (84 static pages) all clean. Pages verified in light and dark at 390px, sm, md and wide desktop.

Before this can ship

  • agentAppOrigin still points at livepeer.peaceno.de (lib/site.ts) — this feeds the most prominent CTA on every page. One edit, needs the real URL.
  • Blog art hotlinks Peace Node's Sanity CDN — confirm permanence or vendor the assets.

🤖 Generated with Claude Code

Rebuilds the marketing site against Peace Node's Livepeer UI registry. The
registry theme is now the only token layer; the old hand-rolled --color-*
system, the Holographik grid, .blog-prose and 17 bespoke keyframes are gone.
globals.css goes 1209 -> 585 lines.

Eight pages: home, /agent, /ecosystem (+ detail, submit), /compute, /token,
/foundation, /blog, /brand. /primer stays intact and unlinked with its own
scoped slice. Content is authored in-repo as typed objects matching the
registry contracts (lib/site.ts) plus markdown for blog and ecosystem — no CMS.

Share images are rebuilt on the registry's own og item: / renders the brand
card verbatim (lockup centred on black), every other page the same canvas with
a page title. Each segment carries a twitter-image beside its opengraph-image,
because metadata files cascade and a segment without one serves the root's
Twitter card.

Also fixes package-lock.json: six deps had been added via npm in a
pnpm-pinned repo, leaving pnpm-lock.yaml stale and
`pnpm install --frozen-lockfile` failing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview Aug 10, 2026 7:05pm

Request Review

Two notes were carrying stale expectations that would have sent the next
person looking for work that isn't there: /brand was marked as awaiting CD
review, and the Foundation page's dropped content read as migration loss
worth restoring from git. Both were deliberate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@adamsoffer adamsoffer changed the title WIP: Redesign livepeer.org on the Livepeer UI design system WIP: Redesign livepeer.org Aug 8, 2026
`hover:bg-card` reads as a state change in dark, where --card is
oklch(0.205) over a black background — a 23-byte lift. In light, --card and
--background are both oklch(1 0 0), so the fill painted white on white and
there was no hover at all.

Both card grids now use an alpha over foreground, which is relative to
whatever the page is rather than a fixed surface: measured at a 20-byte lift
in both themes, matching what card gave dark. It is also the value already
used for the header nav items and the hero's Discord button.

Same failure mode as the login dropdown painting bg-accent on a bg-secondary
panel — two tokens that happen to hold identical values in one theme.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The previous fix swapped `card` for a foreground alpha, which removed the
white-on-white case but picked one shared value for both themes on the
reasoning that equal sRGB byte deltas read equally. They don't — oklch L is
steep near black and flat near white, so at 0.08 dark lifts ΔL 0.191 while
light manages 0.060, and light still read as having no hover at all.

Splits the alphas: light 0.15 (ΔL 0.112), dark unchanged at 0.08. These cards
carry no border, so the fill is the only thing that materialises them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0.15 read as too dark. Bisects the two rejected ends — 0.08 (ΔL 0.060) was
absent, 0.15 (ΔL 0.112) was heavy — landing on 0.12 at ΔL 0.087. Dark is
untouched at 0.08.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0.12 still read as too dark. Light now sits at ΔL 0.072, one step above the
0.08 that read as absent. Dark is untouched at 0.08.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The registry's ecosystem-card signals hover twice: a faint `muted/50` fill and
an arrow going muted-foreground -> foreground. An earlier pass here dropped the
arrow — the registry card links off-site so its icon is an external arrow,
while ours goes to a local detail page — and then swapped the fill to `card` to
compensate. That is what broke light mode, where `card` and `background` are
both oklch(1 0 0), and why every attempt to fix it by darkening the fill alone
read as too heavy: one signal was doing two signals' work.

Brings the arrow back as ArrowRight and restores the registry fill for light.
Dark keeps `card`, because `muted/50` there is rgb 7 on pure black and
disappears. Same treatment applied to the /brand resource cards.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Favorit Pro came off all seven page heroes plus the blog card titles and
article headline, leaving Inter as the one voice for headings. The display
scale utilities only ever set size, weight and tracking — they never implied a
typeface — so text-display-* in font-sans is the normal case, and font-display
now survives only in the /brand type specimen (where the face is the subject)
and the registry's mobile nav.

Two weights moved with it, because Favorit's 300 does not translate: blog card
titles go to font-medium at 20px, where Inter's 300 stopped out-weighing the
body copy, and the article headline follows at font-medium so a title carries
the same weight on the card and on the article.

Replaces the /brand clear-space diagram with the symbol construction drawing
recovered from the old token page's specimen card, which the redesign cutover
deleted along with app/token/TokenPageContent.tsx. The old diagram asserted its
rule — a dashed box labelled "= symbol width" around a mark floating in empty
page, with no measure drawn — and sat in a grid cell stretched to 850px by the
rules list beside it. The recovered drawing shows the geometry instead: a
lattice whose every line passes through a real square edge, tick rows carrying
the actual X and 5/6X measures, and the +6u optical correction drawn as a
labelled delta between the optical and geometric centres.

Re-aimed from LPT to the mark: the chain label and live staking figure are
gone, which also drops the stats prop, so /brand no longer reads the subgraph
or needs THEGRAPH_API_KEY. Its corner annotations are hidden below sm — they
are fixed-size HTML while the footer wordmark scales with the viewBox, so at
375px the footer's flanking rules struck through them.

Foundation hero copy is now "Advancing the world's open inference network."

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The panel's cards each carried their own hover:bg-*, so moving between two of
them cross-faded: the one you left dimmed while the one you arrived at lifted,
and two adjacent cards fading in opposite directions reads as a blink rather
than a movement. One highlight now travels between them, the same device the
login dropdown uses vertically.

Both axes are tracked. The grid is 3 columns at lg and 4 at xl, so a four-item
group like Network wraps: along a row it slides laterally, to the row below it
travels down as well, and width and height come along because wrapped rows are
not always the same size.

Position is written to the node rather than held in state, and the transition
is declared unconditionally. A CSS transition only runs when the property was
already transitionable in the *previous* computed style, so a class that turns
the transition on in the same commit that moves the element makes it teleport —
React renders both together, so the declarative version could not animate at
all. Setting the style directly on an element whose transition is already
established does. First appearance still places rather than travels, or the
highlight flies in from the panel's top-left corner.

Also fixes two things found underneath it. The trigger row's hoverable box was
16px of text inside a 64px header, with ~25px of dead space below it, so the
menu closed on small vertical drift; padding makes the hit area the full row
and a negative margin keeps layout unchanged. And the panel's first open
targeted height "auto" and was then re-targeted to a measured pixel value
mid-animation, which restarts the animation — hence a stutter on the first
hover and never afterwards. It now holds "auto" until the open settles.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every card is now one of Peace Node's stock images with the mark over it. Page
cards centre the lockup and say nothing else — the art is what tells /agent from
/token in a feed, and the platform prints the title and hostname as text beside
the image anyway. Blog cards take the post's own art with the wordmark in the
corner and the headline over a scrim weighted to the foot. Wordmark rather than
the lockup there: the symbol is six small squares, and at corner size they land
around 4px each and turn to mush.

Fixes a real softness while it is in here. The art was being served through the
`?fm=webp&q=82` in the blog frontmatter, which measured less than half the
detail of the original on a Laplacian sharpness test — the grain that makes
these read as photographs was being compressed flat. Cards now pull
`fm=jpg&q=95` cropped by the CDN to exactly 1200 × 630, so Satori never
resamples: the same measure roughly doubles, at a fifth of the source PNG's
weight. Blog metadata drops its explicit `images`, which would otherwise beat
the file convention and keep serving the bare art.

The scrim is radial rather than a flat wash, and aims at 3:1. A flat tint heavy
enough to carry white over the brightest of these measured 2.2:1, and the wash
that fixed it drained the darker images and left a visible smudge on the bright
ones. Darkening only the middle clears 3.6:1 at worst with the art intact at the
edges. 3:1 is the bar that applies — the lockup is a graphic, so WCAG 1.4.11
governs, not the 4.5:1 written for body text.

Also puts the gutter and max-width on one element on /brand, /blog and
/ecosystem. Split across two, max-w-page bounds the content box instead of the
padded box, so those three ran 40px wider each side than the header, the footer
and the section rules they sit between.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant