How a theme is measured
One pass, five steps, no model in the loop:
- Render. The URL opens in headless Chromium (
lib/capture.js). Nothing is fetched as raw HTML or guessed from a stylesheet — the page runs, with its fonts and its scripts. - Read the computed styles. A script walks the rendered DOM and tallies what is actually painted: every background and text colour with the number of pixels it covers, every font size, weight and family in use, corner radii, shadows, transitions, the site's own keyframes.
- Cluster and name. The tallies become a palette by frequency and contrast, a type scale
from the sizes that carry real text, a radius scale, a motion set (
lib/author.js). Scales come out named the way a design system names them —sm…3xl, notsize-17. - Derive the component tier. Button, card, input, nav and footer variables are resolved for
every theme, from what the page measured where it measured it and from the primitives above where
it did not (
lib/components.js). - Emit. One W3C design-tokens file, plus plain CSS custom properties, a Tailwind v4
@themeblock, a Tailwind v3 preset and a web-font import.
Every value on a theme's page is labelled with where it came from, and those four words mean exactly this:
- measured
- read off the rendered page.
- token
- the theme's own named token, chosen deliberately by whoever authored it.
- derived
- computed from a measured value by a stated rule — a button's text colour from its background's contrast, say.
- default
- a fallback, because nothing on the page answered. A control height, a padding. A handful per theme at most, and each one says so.
A shadow that was never measured stays none rather than becoming a plausible one.
That is why some themes in the gallery look flat: they are.
What a measurement cannot see
A page renders once, signed out, at one viewport, and that is the whole of what gets measured:
- Anything behind a sign-in, a paywall, a cookie wall or a captcha. What gets measured then is the wall, which is why a few well-known products are missing.
- States nobody triggered: hover, focus, pressed, error, disabled. An accent-hover colour is recorded only when the page declares one in CSS.
- Type and colour drawn inside
<canvas>, inside WebGL, or baked into an image. - Intent. A measurement can tell which blue covers the most pixels; it cannot tell you that the brand blue is the other one. Curated themes are checked against the screenshot by hand for exactly this; a fresh scan is not.
Where a scan had to fill a gap, its own $description lists what it derived rather
than measured, and its theme page prints that list. A theme that admits its guesses is more
useful than one that hides them.
Using it from an agent
The server speaks MCP, which is the point of it. One endpoint, bearer token:
POST https://stylelift.dev/mcp
Four tools: list_themes, get_theme (json, css, tailwind4, tailwind3 or
fonts), apply_theme (the files to write plus the import steps for the detected stack)
and save_theme.
No token and no account needed to read a file — every theme's generated output is open:
curl https://stylelift.dev/t/stripe/tokens.css
Those files are served with Access-Control-Allow-Origin: *, so a browser can fetch
them directly. https://stylelift.dev/use/<theme> is the same thing as instructions, for
pasting into an agent.
What this site stores
Signing in is optional. It exists so that a site you scan yourself stays yours, and so the gallery browser is not an open crawl target — not to build a profile.
- What the provider hands over. Google or GitHub returns an account id, an email address, a display name, and on GitHub a username. Nothing else is requested.
- Where it goes. Into one signed
httpOnly,SameSite=Laxcookie that expires after 30 days. There is no session database — the cookie is the session. Clearing it ends it completely; this server has nothing left to delete. - Saved scans. One JSON file per account, named after
provider:account-idand never after your email, holding the theme name, the URL you scanned, its token document, a token count and a timestamp. A collection holds 100; the 101st is refused rather than quietly dropping one of yours. Remove is remove — the file is rewritten without it. - No analytics, no tracking pixels, no third-party JavaScript. Every script on this site is inline and short enough to read in View Source, including this page's.
- One third-party request. The web-font stylesheet for whichever theme a page is wearing, which is usually Google Fonts. It comes with the design, not with the visitor.
- Request logs go to the server's output, where a host keeps them for a while. They are not collected into a dataset and nothing is joined to an account.
Measuring a page means rendering it, and a render is a picture of whatever that page was showing. Those renders stay on the machine that did the measuring: none is published, none is committed, and no page on this site serves one. What ships is the numbers that came out.
Who runs this
Stylelift is a small, independent project. It is not affiliated with, sponsored by or endorsed by any of the 1137 products it measures; each theme is named after its source so the source is always obvious, and each one says which page it was read from and when.
Write to elvickongolo@gmail.com — a correction, a site worth measuring, or a request to remove one. Removal requests from a site's owner get done; no argument, no form.