web.design looks at a website the way a designer would and writes down what makes it look the way it does: the type scale, the colors and what each is for, corner radii, spacing rhythm, shadows, how buttons, inputs, cards, the nav and images are styled, and the order and structure of its sections. It answers with that spec and with things to paste: a Tailwind v4 @theme block, a shadcn/ui theme, plain CSS variables, and a brief in markdown that an agent follows while it builds.
Use it before building or redesigning UI when there is a site to learn from: a site the person likes, or their own existing site.
vibiz design https://example.com --tailwind # writes design.md and design.tailwind.css
vibiz design https://my-shop.com --own --shadcn # your own site: reuse its colors and logoA reference, not a copy
A reference site is a pattern to learn from. The spec and the brief say it in the output itself:
- Reuse the layout patterns, the spacing rhythm, the type scale and the component treatments.
- Use the person's own brand: their colors, logo, copy and images.
- Never copy another company's logo, text, images or trademarks.
own_site: true says the URL is the person's own site. Then usage is "use": its colors, fonts and logo are theirs, the exports use the site's own font files, and (with a project) the logo, favicon and share image are copied to the project's Files. Otherwise usage is "reference": colors are listed as a structure to map onto the person's own brand, licensed fonts are replaced by the closest free font, logos are listed but never copied, and section headings are not returned.
Run it
| Way | Call |
|---|---|
| CLI | vibiz design <url> [--out design.md] [--tailwind] [--shadcn] [--css] [--own] [--pages /pricing,/about] [--fresh] [--json] |
| MCP | vibiz_web_design { url, pages?, viewports?, own_site?, fresh?, detail?: "brief" | "full", project_id? } (also vibiz_run_action with web.design) |
| HTTP | POST /v1/actions/web.design with { "input": { "url": "…" } }, or POST /v1/projects/:id/actions/web.design |
| SDK | vibiz.design.extract({ url }, { projectId }); from a running app, vibiz.actions.run('web.design', { url }) |
| Console | Web data ▸ Extract a site's design; saved specs under the project's Design tab |
Input:
| Field | Default | |
|---|---|---|
url | The page to learn from. | |
pages | none | Up to 5 more pages of the same site, as paths (/pricing) or URLs. |
viewports | ["desktop", "mobile"] | The mobile pass gives the mobile type scale and a mobile screenshot. |
include | everything | tokens, components, layout, assets, exports. Tokens always come back. |
own_site | false | The URL is the caller's own site (see above). |
fresh | false | Read the site again instead of the copy from the last 24 hours. |
It takes 20 to 90 seconds. In a project (project_id, or a linked folder for the CLI) the spec (.json), the brief (.md) and the screenshots are saved to the project's Files in the folder design, and saved has their links.
What comes back
{
"object": "design_spec",
"url": "https://example.com/",
"usage": "reference",
"policy": "Use this as a design reference, not a copy. …",
"cached": false,
"confidence": { "computed_styles": true, "stylesheets": 5, "vision": true, "pages": 1 },
"tokens": {
"colors": { "scheme": "light", "roles": { "background": "#ffffff", "text": "#0a0a0a", "text_muted": "#737373", "primary": "#f38c0d", "surface": "#f6f6f1", "border": "#e5e5e5" }, "dark": { "background": "#0a0a0a" }, "palette": [ { "hex": "#0a0a0a", "count": 4251, "uses": ["text"] } ], "variables": [ { "name": "--primary", "value": "#171717", "dark": "#e5e5e5" } ] },
"typography": {
"families": [ { "family": "Inter", "role": "body", "source": "google", "next_font": "Inter", "google_fonts_url": "https://fonts.googleapis.com/css2?family=Inter…" } ],
"scale": { "h1": { "size": "64px", "weight": "300", "line_height": "1.1", "letter_spacing": "0", "samples": 1 }, "body": { "size": "16px", "weight": "400", "line_height": "1.6" } },
"mobile_scale": { "h1": { "size": "44px", "line_height": "1.1" } }
},
"radii": { "sm": "4px", "md": "16px", "lg": "24px", "full": true, "scale": [ { "value": "24px", "count": 49 } ] },
"shadows": [ { "value": "rgba(0, 0, 0, 0.05) 0px 1px 2px 0px", "count": 2 } ],
"spacing": { "base": 8, "scale": [8, 16, 24, 32, 48, 64, 96], "section_padding": "128px" },
"layout": { "container": "1344px", "breakpoints": [640, 768, 1024, 1366] },
"motion": { "durations": ["150ms", "300ms"], "easings": ["cubic-bezier(0.4, 0, 0.2, 1)"] }
},
"components": {
"button_primary": { "styles": { "background": "#f38c0d", "color": "#171717", "border-radius": "16px", "padding": "0px 32px", "height": "64px", "font-weight": "500" }, "samples": 3, "source": "computed" },
"image": { "styles": { "border-radius": "24px", "object-fit": "cover" }, "samples": 22, "note": "30 images measured: … clipped by a rounded wrapper" }
},
"layout": { "style": { "summary": "…", "layout": "…", "components": "…", "typography": "…", "mood": "…" }, "pages": [ { "url": "…", "sections": [ { "index": 1, "kind": "hero", "description": "Split hero: text left, photo right in a rounded frame, 2 buttons." } ] } ] },
"assets": { "logo": { "source_url": "…", "url": null, "file_id": null }, "screenshots": [ { "viewport": "desktop", "url": "…" } ] },
"exports": { "tailwind_theme": "@import \"tailwindcss\";\n\n@theme { … }", "shadcn_theme": ":root { --background: … }", "css_variables": ":root { … }", "brief": "# Design brief: example.com …" }
}Every measured value says how many elements backed it (count, samples): 1 is a coincidence, 20 is a house style. confidence says how the values were read.
How it reads a site
- The rendered page. The page is opened in a browser at 1440 px (and 390 px for mobile), cookie banners and chat widgets are removed, and it is scrolled through so lazy sections load. Then the browser reports the computed styles of the elements that define a design: headings and body text, buttons, links, inputs, cards, badges, the nav, image and video frames (including the rounded wrapper that clips a photo), how much each color covers, and an outline of the sections with their columns, alignment and media position. Computed styles are what the cascade, media queries, CSS variables and CSS-in-JS resolve to, so they are the main source.
- The stylesheets. The site's own CSS files are read too (public addresses only, size and time capped): custom properties for light and dark mode,
@font-facefiles, breakpoints, and how often each value is declared. Element class names are joined against them to find how the site frames images, video and buttons, with how many rules agree. - A vision pass. A vision model (Google's Gemini Flash, the model behind
vibiz/balanced) looks at the screenshots with the section outline and names each section and the overall style. It describes structure, never colors or copy. If it is unavailable, the spec still comes back with the sections labelled from the page's structure (confidence.vision: false).
When a page cannot be rendered, the spec comes from the markup and the stylesheets alone (confidence.computed_styles: false): coarser, still useful.
Limits. Pages behind a login, a bot wall or heavy client-only rendering read partly or not at all. Hover and focus states are not measured (the brief lists the states to build). Fonts are named from the stylesheet; a licensed font is never loaded in a reference export. One page plus up to five more per call.
Cost
Billed like the other web data actions: what the call cost (cost_micro_usd: one page render per page and viewport, about $0.0008 each, plus the vision pass, about one cent) plus Vibiz's margin, which vibiz_usage shows as billed_usd. A typical call (one page, desktop and mobile) comes to one to three cents. The same URL and options within 24 hours answer from the account's saved copy for free (cached: true); fresh: true reads again.
Without a reference
No site to learn from? The vibiz-design skill carries a short default checklist (type scale, spacing rhythm, contrast, one accent color, real states, mobile first) so a new app still looks considered.
Works on its own: an account key is all it needs, no project or hosting on Vibiz.