Real CSS, not a computed-style dump
Hover anything, click to lock it, and get the rules that actually matched: their own selectors, their layer, their hover states, their breakpoints, and the tokens behind the values.
Explore Pick elementWorks with Works with OpenAI, Claude, Cursor, Windsurf and VS Code.
A free Chrome extension that copies the real CSS behind anything you point at: hover states, breakpoints and design tokens included. Turn it into a ready-made prompt for ChatGPT or Claude, or connect Cursor and Claude Code over MCP so your agent can read the page itself.
Rather see the output before you install anything? Look at what one pick produces.
The whole toolbar, one keystroke away on any page.
One key each, on a bar that lives in the page rather than in a popup, with a readout of whatever is under the cursor. Every one of them has its own page, and a recording of it working on a real site.
Hover anything, click to lock it, and get the rules that actually matched: their own selectors, their layer, their hover states, their breakpoints, and the tokens behind the values.
Explore Pick elementMargin, border and padding shaded separately, in place, with rulers out to the edges of the viewport and sizes to a tenth of a pixel.
Explore MeasureEvery colour with its role named, the type scale with the weights in use, spacing, radii, shadows, breakpoints, and a contrast check. Out as Tailwind, CSS variables or W3C tokens.
Explore Design systemPalette as custom properties, the fonts and where they come from, the CSS of the components that repeat, every section in order, the assets and the motion.
Explore Design promptThe browser's own eyedropper, so it reads colour out of images, canvas and video. Hex, rgb or oklch.
Explore Sample a colourMeasured, not guessed from the stack, so a page that asks for Inter and renders Helvetica is reported as Helvetica. Every family, size and weight on the page.
Explore Fonts in useImages, inline SVG, CSS backgrounds, masks and video posters, largest first, filterable, packed into one archive in your browser.
Explore Images and SVGsClick any text and type. See how a real headline behaves at the size it ships at, in the layout it ships in.
Explore Edit text in placeCookie banners, sticky headers, chat bubbles. Click to remove them and press Z to bring them back one at a time.
Explore Hide elementsIt moves by transform, so nothing around it reflows and the undo is exact rather than approximate.
Explore Move elementsThe toolbar hides itself and waits for a repaint before the shutter, so it is never in the picture.
Explore ScreenshotBanner dismissed, menu open, tab switched. The current DOM with absolute URLs and its stylesheets beside it, scripts stripped.
Explore Save page HTML
For the pages a headless browser cannot reach. Pick it in your own browser, press G, and Cursor or Claude Code reads it over MCP.
Explore Send to agentTwo more that are not tools: , opens settings, and Esc puts everything back and gets out of the way. Nothing you hide, move or edit survives it.
Copying a design off a live page is a job everyone does by hand and nobody enjoys. Here is what changes the first time you use this, and the part of the tool that does it.
Telling a model “a bit more padding, slightly rounder, that blue” is guesswork on both sides, and the third revision is still wrong. Paste the values instead and there is nothing left to guess at.
Pick element gives you 13.5px, #2f6df6 and var(--radius-md), not an adjectiveThe styles pane shows you what won, one property at a time, with the crossed-out rules you have to read around. Getting a whole component out of it means clicking through a dozen selectors and rebuilding the cascade in your head.
One keystroke for every rule that applies, in cascade order, with the layers intactA site’s full stylesheet runs to hundreds of kilobytes. It fills the context window, the model still has to work out which forty lines matter, and you pay for every token it read on the way to picking the wrong ones.
Design prompt and get_design_context send only what styles the thing you asked aboutA copied component that looks close is the expensive kind of wrong: you build on it, then spend an afternoon on the shadow that never matched. Verbatim renders what it extracted and diffs it against the live element first.
verify_extraction lists every property that differs, before you build on itThe same extraction serves four different jobs. Find yours and the shortest path through this page is the tool named at the end of it.
Your agent cannot see a page it has no reader for, so it writes plausible CSS and you correct it. Give it the resolved cascade instead and the first attempt is the right one. Pick anything in your own browser and press G to hand it over, or let the agent fetch a public URL itself over MCP.
A component from a live site, out as HTML and CSS, or as a React, Vue, Svelte, Astro or Angular component, or as Tailwind utilities with the theme they depend on. The preview underneath renders the extraction in isolation, so you can see it is right before it reaches your branch.
A page’s whole design system in one panel: colours ordered by how much of the screen they actually cover with their roles named, the type scale with the weights in use, spacing, radii, shadows, breakpoints, and a contrast check on the text. Export as Tailwind @theme, CSS variables or W3C tokens.
A client sends a link and says “like this”. Design prompt turns that link into one document: the palette as custom properties, the type and where it is served from, the CSS of the components that repeat, the sections in order, and the motion. Then hand it to whichever tool builds the page.
It can read your code and query your data. Ask it what colour the button is on a site you admire and it is back to guessing from a picture.
Verbatim is that third row. One call and the design stops being a picture and becomes something your agent can read: the rules that actually applied, in the order they applied, with the values it would otherwise invent.
Show it a screenshot and there are no values in it. Paste the stylesheet and there are five thousand rules in it. Either way it guesses, and you find out in review. Every CSS extractor that reads getComputedStyle and dumps the result has the same problem in a different shape: the states, the breakpoints, the layers and the tokens are already gone.
.mt-1 { margin-top: .25rem } .mt-2 { margin-top: .5rem } .mt-3 { margin-top: .75rem } .flex { display: flex } /* 5,768 more rules, 4 of which touch your element */
/* only what applies, in order */ .pricing-card { padding: var(--space-6); background: #0b69ff; } .pricing-card:hover { … } @media (min-width: 768px) { … }
The difference is not a longer feature list. It is what survives the copy, which is the only thing that decides whether the rebuild matches.
| What decides how it looks | A screenshot | The whole stylesheet | Computed style, dumped | Verbatim |
|---|---|---|---|---|
| The exact values | guessed from pixels | present, buried | exact | exact, unrounded |
| Which rules actually applied | no | nothing says which | the winner only | all of them, in cascade order |
@layer precedence |
no | declared, unresolved | flattened away | resolved, layers kept |
| Hover and focus states | no | somewhere in there | not present | matched from selectors |
| Breakpoints that are not active right now | no | unattributed | no | kept as media queries |
| Token names, not just their values | no | declared elsewhere | var() substituted |
name and literal |
| Stylesheets the page cannot read back | no | page cannot read them | values only | refetched and reparsed |
| Shorthands as they were written | no | yes | longhands, some empty | recombined |
| Proof the copy matches the original | eyeballing it | none | none | rendered and diffed |
| What it costs your context window | an image | the whole stylesheet | hundreds of properties | only what touches it |
Columns are approaches rather than brands, because that is where the difference lives: any tool that reads getComputedStyle and prints the result lands in the third column whatever its name is, and so does anything built on a screenshot.
To copy CSS from a website: pin Verbatim, open the site, and hit Alt+Shift+P. A toolbar drops onto the page and stays there while you click around. A popup would close the moment you touched the thing you came for.
The icon or the shortcut, on any page including your own localhost. The toolbar lives in a shadow root, so the site's CSS cannot reach into it and it cannot leak into the site. Drag it out of the way by the grip.
Choose P first: the toolbar opens with nothing armed, so your clicks still belong to the page until you say otherwise. Then hover and the element is outlined, with its selector and its exact size in the readout. Click to lock it. It reads through shadow roots and iframes on the same origin, so web components are pickable too.
A window opens with the code: the markup beside every rule that applies, and the extraction rendered back in an isolated frame underneath, so you can see it is right before you paste it. The same pick is also there as Tailwind classes, as a prompt for a chat, and as the raw inspection. Copy any of it, or press G to send it straight to your coding agent.
Press Esc and it leaves. Anything you hid comes back, anything you moved goes back where it was, and the page is as you found it. Chrome, Edge, Brave and Arc. No account, and no page you visit is sent anywhere.
Pick an element and a window opens over the page: the markup beside the authored CSS, with the extraction rendered back underneath in an isolated frame. Switch the same pick to Tailwind classes, to a prompt for an AI chat, or to the raw inspection. Every mode is the same selection seen differently, and every one copies with a single button.
The markup in one pane, and in the other every rule that applies, in cascade order, with @layer, @media and @supports kept intact, hover and focus states included, and the custom properties the rules read declared alongside. Authored rules, not a dump of computed style. Underneath, the two rendered together in a sandboxed frame.
The markup pane speaks React, Vue, Svelte, Astro, Angular or plain HTML, in JavaScript or TypeScript, chosen in the same window. A depth control runs from the element alone to the entire subtree, and a scope control switches between the whole component and the one element.
The same selection as utility classes, v3 or v4, with an optional theme so the classes point at named tokens instead of repeating raw values.
A written brief for a chat: what the thing is, its values, its states, its breakpoints, the tokens it depends on, its contrast. Rendered as formatted markdown so it is readable before you paste it, and it tells the model to deliver the component and nothing else.
The raw reading. Tag, classes, id, box model to a tenth of a pixel, how many rules matched, which states and breakpoints exist, pseudo-elements, web fonts, animations, and anything the browser's own computed value disagrees with.
Bring your own key, for the two things a model is actually better at. Paste an API key from Anthropic, OpenAI, Gemini or OpenRouter in settings and two buttons appear. Name things turns .css-1x2y3z into .pricing-card, in the markup and the CSS at once. Write the prompt explains the intent behind a component instead of restating its numbers, on the Prompt mode of the same window.
The model is never allowed near a value. After it renames, every declaration is compared with what went in, and an answer that altered one is discarded with the exact output left standing. Requests go from your browser to your provider on your key: not through us, not billed to us, never seen by us. Leave the field empty and nothing is sent anywhere at all. What that means exactly.
Three windows, because a narrow column is the wrong shape for code you actually need to read. Each one drags, resizes, and reopens where you left it.
Where a pick lands. The markup and the styles side by side, the extraction rendered in a sandboxed iframe below them, and the same selection a mode away as Tailwind, as a prompt, or as the raw inspection with anything the browser disagrees with listed by name.
The captured markup and the page's stylesheets in their own panes, with a preview rendered without scripts, and a button that downloads the file.
A grid of every asset with its format and rendered size, filterable, click to select. Copy the URLs, or download the selection as one zip packed in the browser with nothing sent to a server.
Exact values, never rounded to a nearby palette entry. The button below is rendered by the code beneath it, and that code is read from the same stylesheet as the page loads, so the two cannot drift apart.
Export as a Tailwind theme, CSS custom properties, or W3C design tokens. Contrast is measured while it reads, so your agent does not faithfully reproduce someone else's accessibility bug.
Your agent drives a browser with no session and no hands. It cannot log in to your dashboard, and it cannot see a dropdown that only exists while you hold it open. So pick it yourself, in the state you want it, and press G. The extension posts it to the server on your machine and the agent reads it from there.
Nothing is uploaded on the way. The bridge listens on loopback only and accepts the extension on sight, because a web page cannot pretend to be one: Origin is a header a page is not allowed to set. So no site you happen to have open can read your captures or plant one, and there is nothing to paste to make that true.
get_handoff()# Component: .invoice-row from app.yourcompany.com markup, CSS, states, tokens
Everything the toolbar does by hand, your agent can ask for on its own, through the Verbatim MCP server. Same engine, so what it gets back is exactly what you would see picking that element yourself, and any client that speaks MCP works.
Make our pricing card match the one on stripe.com.
the call
get_design_context({ url: "stripe.com", selector: ".pricing-card", task: "rebuild it in our stack" })
what comes back
# Component: .pricing-card # from stripe.com, captured at 1440x900 ## Every rule that applies, in order .pricing-card { padding: var(--space-6); ... } .pricing-card:hover { ... } @media (min-width: 768px) { ... } ## What a stylesheet cannot say hover is triggered by the card, not the button contrast 7.1:1, passes AA and AAA
Buildable markup, every rule that styles it in cascade order with layers preserved, the tokens it reads, its states, its behaviour per breakpoint, its contrast.
Give me their testimonial block as a React component.
the call
get_component({ url: "linear.app", selector: ".testimonial", framework: "react", styling: "tailwind" })
what comes back
export function Testimonial() { return ( <figure className="flex gap-4 rounded-xl p-6"> <blockquote className="text-[17px] leading-6"> ... ) }
One part of a page as HTML and CSS, or as a React, Vue, Svelte, Astro or Angular component. Optionally converted to Tailwind.
Use their palette and type scale for this dashboard.
the call
get_design_system({ url: "linear.app", format: "tailwind" })
what comes back
@theme { --color-background: #08090A; /* 41% of screen */ --color-accent: #5E6AD2; /* 4% */ --text-base: 15px; /* 212 uses */ --radius-lg: 12px; }
Palette ordered by how much of the screen each colour covers, type scale, spacing, radii, shadows, breakpoints, and the site’s own custom properties. As prose, Tailwind, CSS variables or W3C tokens.
Build us a landing page that feels like linear.app.
the call
get_design_prompt({ url: "linear.app", task: "a pricing page for our own product" })
what comes back
## OVERALL AESTHETIC ## FONTS ## COLOR THEME :root { --page-bg: #08090A; /* page background, 41% */ --accent: #5E6AD2; /* primary action */ } ## COMPONENT CSS the ones that repeat ## ASSETS & MEDIA URLS ## SECTION-BY-SECTION BREAKDOWN ## SHAPE, DEPTH & SPACING ## ANIMATION PATTERNS
One prompt for a whole site instead of one element: the palette as custom properties with each colour's role and coverage, the faces it actually renders in and where they are served from, the CSS of the components that repeat, every section in order with its layout and spacing, the assets, and the motion. The same thing the extension's B key produces, so an agent and a person get identical output.
Your agent runs this on its own, before it trusts anything.
the call
verify_extraction({ url: "stripe.com", selector: ".pricing-card" })
what comes back
22 of 22 properties match rendered in isolation, diffed against the live page when something is off, it says which: box-shadow expected 0 1px 2px rgba(0,0,0,.08) got none
Renders the extraction in isolation and reports every computed style that differs from the live page. A model that can check its inputs need not trust them.
Pull their icon set and tell me what is oversized.
the call
get_assets({ url: "vercel.com" })
what comes back
hero-dark.avif 1920x1080 84 KB logo.svg inline 2 KB og-card.png 2400x1260 1.8 MB rendered at 600x315, 4x oversized
Every image, SVG, CSS background and video poster, largest first, with oversized sources flagged.
Show me what it looks like, not just the numbers.
the call
screenshot({ url: "stripe.com", selector: ".pricing-card" })
what comes back
image/png, 345x376, cropped to the element the values tell it what, the picture tells it why. useful alongside the context, not instead of it.
A page or one element as a PNG. Useful alongside the context rather than in place of it.
What did I send you from the browser?
the call
list_handoffs()what comes back
2 .invoice-row app.yourcompany.com 4m ago 1 .nav-dropdown app.yourcompany.com 11m ago open state, captured while the menu was held
Captures sent from the browser extension, for the pages a headless browser cannot reach.
Use the invoice row I just sent.
the call
get_handoff({ id: "2" }) // omit id for the newest
what comes back
# Component: .invoice-row # from app.yourcompany.com, behind your login markup, CSS, states, tokens, contrast everything get_design_context returns, for a page no browser of its own could have reached.
Whatever you picked by hand, in whatever state you picked it, waiting for the agent to read.
Responses are shortened here. The real ones are longer and duller, which is the point.
You never call the tools. You say what you want, in a sentence, and your agent picks. Here are six, playing out.
Make our pricing card look like the one on stripe.com.
get_design_context({ url: "stripe.com", selector: ".pricing-card" })
# every rule that applies, in order padding: var(--space-6) border-radius: 12px :hover, the 768px breakpoint, contrast 7.1:1
verify_extraction before saying it is done.
The one to start with: the whole extraction as a brief.
Pull linear.app’s palette and type scale into our Tailwind theme.
get_design_system({ url: "linear.app", format: "tailwind" })
@theme { --color-background: #08090A; /* 41% of screen */ --color-accent: #5E6AD2; /* 4% */ }
Also emits CSS variables, W3C design tokens, or readable prose.
Rebuild that testimonial as a Svelte component with Tailwind.
get_component({ selector: ".testimonial", framework: "svelte", styling: "tailwind" })
<figure class="flex gap-4 rounded-xl p-[13.5px]"> arbitrary values kept exact, never snapped to a palette
HTML, React, Vue, Svelte, Astro or Angular. CSS or Tailwind.
Does my version actually match theirs?
verify_extraction({ url: "stripe.com", selector: ".pricing-card" })
22 of 22 properties match rendered in isolation, diffed against the live page
The tool that makes the other seven trustworthy.
Use the invoice row I just sent you from our dashboard.
list_handoffs() then get_handoff()
# .invoice-row from app.yourcompany.com, behind your login markup, CSS, states, tokens, contrast
How an agent sees a dashboard, or a menu that only exists while you hold it.
Grab their icon set and tell me what is bloated.
get_assets({ url: "vercel.com" })
og-card.png 2400x1260 1.8 MB rendered at 600x315, four times oversized
Every image, inline SVG, CSS background and video poster, largest first.
Verbatim renders what it copied and compares it against the live page, property by property. If anything is off it says so, before your agent writes a line.
| Property | Live page | Extracted | Result |
|---|---|---|---|
| color | rgb(255, 255, 255) | rgb(255, 255, 255) | match |
| background-color | rgb(11, 105, 255) | rgb(11, 105, 255) | match |
| padding-left | 26px | 26px | match |
| border-radius | 8px | 8px | match |
| letter-spacing | -0.16px | -0.16px | match |
This is not a marketing claim. The same check runs in the test suite on every build, and it has caught real bugs: cascade layers being flattened, and inherited styles outranking the rules they were meant to lose to.
The server speaks MCP over stdio, so anything that speaks MCP can use it. It runs on your machine: nothing is uploaded, and no page you copy from is sent anywhere.
Nothing to install first: npx fetches the server the first time your client starts it. From source is there for anyone who would rather build it themselves, and wants an absolute path to the built file.
One command in your terminal, from any directory.
Check it took with claude mcp list. Verbatim's nine tools then show up in /mcp.
Edit ~/Library/Application Support/Claude/claude_desktop_config.json macOS. On Windows, %APPDATA%\Claude\claude_desktop_config.json
Restart Claude Desktop afterwards. It only reads that file at launch.
Edit ~/.cursor/mcp.json for every project, or .cursor/mcp.json for one.
Then Settings, MCP, and check Verbatim is green.
Edit ~/.codex/config.toml
This is OpenAI's coding agent. ChatGPT itself connects only to MCP servers reachable over HTTP, so a server on your own machine is out of its reach: use Codex for local work.
Edit ~/.codeium/windsurf/mcp_config.json
Then Cascade, the plugins panel, refresh.
Edit .vscode/mcp.json in your project.
For Copilot in agent mode. VS Code names the key servers rather than mcpServers, and wants the transport spelled out.
Any client that speaks MCP over stdio. Give it this command.
No transport to configure, no port to pick, no key to paste. The client starts the process, talks to it over stdin and stdout, and stops it when it is done.
The first 24 hours need no key. The server starts, all nine tools work, and nothing asks you for a card. After that it wants a one time key.
npx verbatim-mcp activate VB1...Or put it in the env block of the config above as VERBATIM_LICENSE, which travels with the config between machines. Checked offline against a signature, so no licence call ever leaves your machine. npx verbatim-mcp status says where you stand.
Then just ask for it. Match the hero on linear.app. Take the palette from our marketing site and apply it to this dashboard.
It is not on the Chrome Web Store yet, so for now you install it the way every extension developer installs one. Same build, same thirteen tools, and it works in Chrome, Edge, Brave and Arc.
One file, 97KB, no installer and no account.
sha256 a84daadf613b83f655bad60bb60822d10495cbc8d2e4e572bcf3017904472135
Open chrome://extensions, turn on Developer mode in the top right, click Load unpacked, and choose the folder you just unzipped.
Or click the icon. The toolbar drops onto the page with nothing armed, so your clicks still belong to the site until you choose a tool. Esc puts everything back.
Working with a coding agent as well? Connect it in one line and it can ask for the same extractions itself.
Installed it already? Getting started has the shortcut, all thirteen keys, and what to do if the shortcut is taken.
Every tool in this category gets the same complaint: a subscription for something you use in bursts. So the extension is free forever with no account, and the server your agent talks to is a single payment. Run it free for a day first, and no card is involved in that day.
How to copy CSS from a website, what makes the output accurate, and what it costs.
Install the Verbatim Chrome extension, open any site, and press Alt+Shift+P. Hover to outline an element, click to lock it, and the panel shows the CSS. Copy it as authored CSS, as Tailwind classes, as a React, Vue, Svelte, Astro or Angular component, or as a written brief for an AI agent. It is free and needs no account.
Most tools read getComputedStyle and dump the result, which throws away the five things that decide what you see. Verbatim resolves the cascade instead: the rules that actually matched with their original selectors and specificity, @layer precedence, hover and focus states found by matching selectors, media queries that do not currently apply, and var() both as the token name and the literal value. It also refetches cross-origin stylesheets the page itself is forbidden to read.
Yes. States are found by matching selectors rather than by whatever the mouse is doing, including ancestor triggers like .card:hover .title. Breakpoints come through as breakpoints, including queries that are not active at your current window size, so the output is responsive rather than a snapshot of one viewport.
Yes, Tailwind v3 or v4, with states as modifiers and breakpoints as prefixes. Colours are never snapped to Tailwind's palette, because bg-sky-500 is not the brand colour the site used: you get the exact value, or a reference to a generated @theme token.
Yes. The extension runs in the page you are already looking at, so anything you can see, it can read, including dashboards behind a login and menus that only exist while you hold them open. For a coding agent, press G to hand that capture to the local MCP server, which is how an agent reaches pages its own headless browser cannot.
Run npx -y verbatim-mcp, or add it with claude mcp add verbatim -- npx -y verbatim-mcp. It speaks MCP over stdio, so Claude Code, Claude Desktop, Cursor, Codex CLI, Windsurf and VS Code all work. Your agent gets nine tools, including get_design_prompt for a whole site’s look, get_design_context for a buildable brief and verify_extraction, which renders what it copied and diffs it against the live page.
The Chrome extension is free forever with no account: thirteen tools, unlimited use, CSS, Tailwind, components, design tokens, fonts, assets and screenshots. The MCP server for coding agents is free for 24 hours, then a one time 29 USD key with no subscription.
Yes. Press D for the whole page at once: the palette ordered by how much of the screen each colour covers with its role named, the type scale with weights and use counts, spacing, radii, shadows, breakpoints, and the site's own custom properties. Export as a Tailwind @theme block, CSS variables, or W3C DTCG design tokens JSON.
No, and there are no servers of ours to send it to. There is no account, no analytics and no telemetry. The only outbound requests are stylesheet refetches to the same origin that already served them, loopback to the Verbatim server on your own machine, and, if you choose to set your own AI key, that provider on your key.
Reading a page you can already open in your browser is what a browser does, and Verbatim does not bypass anything to do it. What you then do with what you read is the part that matters: values like a spacing scale, a radius or a contrast ratio are facts about a page, while a logo, a photo, a font file or a whole page copied wholesale belongs to whoever made it. Verbatim reports asset URLs and font licences rather than bundling them, and its prompts tell a model to write its own copy and use its own imagery. Use it to match a design language, not to clone a site, and take your own advice on anything you would put in front of a client.
The cascade is resolved rather than computed, so states, breakpoints, layers and tokens survive the copy. The output is checked: Verbatim renders what it extracted in isolation and reports any property that differs from the live page. And it is built for coding agents as well as people, with the same engine behind an MCP server.
Free, no account. Thirteen tools on any page.
Add to Chrome, free