Designs React sites with hand-made animated components fitted to your brand, then checks each page.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Your Louis Studios agent key, sent as a bearer token. Any account can make one, Free included, under Agent access at https://studios.lou15.com/account.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
The account behind the key, its plan, the coins it has left and the components it has unlocked (each stays open 30 days).
This tool takes no arguments.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http designer https://studios.lou15.com/mcp \ --header 'Authorization: Bearer YOUR_TOKEN'
Headers
Authorization (required): Your Louis Studios agent key, sent as a bearer token. Any account can make one, Free included, under Agent access at https://studios.lou15.com/account.The account behind the key, its plan, the coins it has left and the components it has unlocked (each stays open 30 days).
No arguments.
{
"type": "object",
"properties": {}
}Call this whenever the user wants the look changed after a direction exists, before composing or fitting anything again. Say the change in plain words in "tweak" ("square corners", "slower", "serif headings", "no glow", "more air", "compact", "glass", "grain off", "darker", "warmer", "accent teal", "luxury + sakura", "less playful") or set explicit knobs. Works on any direction_id, including ones made by create_direction. Returns what changed, anything it did not understand, the new description and the new theme CSS to replace the saved file; compose and fit again afterwards so everything follows.
| Argument | Type | Description |
|---|---|---|
| app | string | What the site or app is and does, in a sentence or two. |
| cta | string | The call to action label. |
| mood | string | How it should feel, in the user's words. Naming worlds works too: "luxury + sakura", "brutalist", "Y2K". |
| avoid | string | What the user does not want, for example "playful" or "glow". |
| blend | string | A second world mixed in, or "none". |
| brand | string | Brand or product name. |
| knobs | object | Explicit settings that override the world. Every one can also be said in plain words through "tweak". |
| theme | string | The default theme. Leave out to let the world decide; both themes are always made. |
| tweak | string | The change in plain words. |
| world | string | Force a world instead of letting the brief choose. |
| colors | array | Brand colours as hex or names, most important first. Kept exact. Leave out to let the designer choose. |
| subline | string | One supporting sentence. |
| audience | string | Who it is for. |
| headline | string | The main headline. |
| direction_id* | string | The direction_id from set_direction or create_direction. |
{
"type": "object",
"required": [
"direction_id"
],
"properties": {
"app": {
"type": "string",
"description": "What the site or app is and does, in a sentence or two."
},
"cta": {
"type": "string",
"description": "The call to action label."
},
"mood": {
"type": "string",
"description": "How it should feel, in the user's words. Naming worlds works too: \"luxury + sakura\", \"brutalist\", \"Y2K\"."
},
"avoid": {
"type": "string",
"description": "What the user does not want, for example \"playful\" or \"glow\"."
},
"blend": {
"enum": [
"calm",
"bold",
"playful",
"luxury",
"technical",
"editorial",
"warm",
"sakura",
"brutalist",
"retro",
"noir",
"organic",
"corporate",
"cyber",
"none"
],
"type": "string",
"description": "A second world mixed in, or \"none\"."
},
"brand": {
"type": "string",
"description": "Brand or product name."
},
"knobs": {
"type": "object",
"properties": {
"caps": {
"type": "boolean",
"description": "Headings in capitals."
},
"glow": {
"type": "boolean"
},
"hero": {
"enum": [
"backdrop",
"split",
"kinetic"
],
"type": "string"
},
"align": {
"enum": [
"left",
"center"
],
"type": "string"
},
"depth": {
"type": "number",
"maximum": 3,
"minimum": -3,
"description": "Steps darker (positive) or lighter backgrounds within the theme."
},
"scale": {
"enum": [
"modest",
"regular",
"dramatic"
],
"type": "string",
"description": "How far the type scale climbs."
},
"theme": {
"enum": [
"light",
"dark"
],
"type": "string",
"description": "The default theme. Both themes are always in the tokens."
},
"accent": {
"type": "string",
"description": "Main accent, hex or colour name. Kept exact."
},
"border": {
"enum": [
0,
1,
2
],
"type": "number",
"description": "Border weight in px."
},
"corner": {
"enum": [
"square",
"round",
"pill"
],
"type": "string"
},
"radius": {
"type": "number",
"maximum": 48,
"minimum": 0,
"description": "Corner radius in px."
},
"warmth": {
"type": "number",
"maximum": 3,
"minimum": -3,
"description": "Steps warmer (positive) or cooler (negative)."
},
"accent2": {
"type": "string",
"description": "Second accent, hex or colour name."
},
"accent3": {
"type": "string",
"description": "Third accent, hex or colour name."
},
"density": {
"enum": [
"airy",
"regular",
"compact"
],
"type": "string"
},
"surface": {
"enum": [
"flat",
"glass",
"shadow",
"outline"
],
"type": "string"
},
"texture": {
"enum": [
"none",
"grain",
"dots",
"grid",
"paper"
],
"type": "string"
},
"contrast": {
"enum": [
"soft",
"normal",
"high"
],
"type": "string"
},
"japanese": {
"type": "boolean",
"description": "Japanese text allowed, with Japanese faces in the stacks."
},
"textFont": {
"type": "string",
"description": "Body face, same choices as displayFont."
},
"tracking": {
"type": "number",
"maximum": 0.24,
"minimum": -0.08,
"description": "Heading letter spacing in em."
},
"saturation": {
"type": "number",
"maximum": 3,
"minimum": -3,
"description": "Steps more vivid or more muted, for colours the designer picks."
},
"displayFont": {
"type": "string",
"description": "Heading face: a kind (serif, sans, mono, rounded, slab, condensed, geometric, grotesk, humanist, didone, mincho) or a face name such as \"Didot\" or \"Futura\". Fallbacks are added."
},
"motionSpeed": {
"type": "number",
"maximum": 3,
"minimum": 0.25,
"description": "Multiplier on the world's pace: 0.75 is slower, 1.3 faster."
},
"followSystem": {
"type": "boolean",
"description": "Follow the visitor's system light or dark setting instead of the default theme."
},
"displayWeight": {
"type": "number",
"maximum": 900,
"minimum": 200
},
"motionIntensity": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "0 is nearly still, 1 is the most movement."
},
"textureStrength": {
"type": "number",
"maximum": 1,
"minimum": 0
}
},
"description": "Explicit settings that override the world. Every one can also be said in plain words through \"tweak\".",
"additionalProperties": false
},
"theme": {
"enum": [
"dark",
"light"
],
"type": "string",
"description": "The default theme. Leave out to let the world decide; both themes are always made."
},
"tweak": {
"type": "string",
"description": "The change in plain words."
},
"world": {
"enum": [
"calm",
"bold",
"playful",
"luxury",
"technical",
"editorial",
"warm",
"sakura",
"brutalist",
"retro",
"noir",
"organic",
"corporate",
"cyber"
],
"type": "string",
"description": "Force a world instead of letting the brief choose."
},
"colors": {
"type": "array",
"items": {
"type": "string"
},
"description": "Brand colours as hex or names, most important first. Kept exact. Leave out to let the designer choose."
},
"subline": {
"type": "string",
"description": "One supporting sentence."
},
"audience": {
"type": "string",
"description": "Who it is for."
},
"headline": {
"type": "string",
"description": "The main headline."
},
"direction_id": {
"type": "string",
"description": "The direction_id from set_direction or create_direction."
}
}
}Every room of the studio: the library, the Island Room, the Sakura Collection, the Icon Room, the Dot Room and the Logo Room, with what each is for and how many items it holds. Pass a room (and words to look for) to search inside it. Free.
| Argument | Type | Description |
|---|---|---|
| room | string | Search inside this room. Leave out to list the rooms. |
| limit | integer | How many results (default 12). |
| query | string | Words to look for, for example "timer", "weather", "neon", "heart rate". |
| category | string | Icon Room or Dot Room only: a category, for example "finance" or "Health". |
{
"type": "object",
"properties": {
"room": {
"enum": [
"library",
"island",
"sakura",
"icon-room",
"dot-room",
"logo-room"
],
"type": "string",
"description": "Search inside this room. Leave out to list the rooms."
},
"limit": {
"type": "integer",
"maximum": 60,
"minimum": 1,
"description": "How many results (default 12)."
},
"query": {
"type": "string",
"description": "Words to look for, for example \"timer\", \"weather\", \"neon\", \"heart rate\"."
},
"category": {
"type": "string",
"description": "Icon Room or Dot Room only: a category, for example \"finance\" or \"Health\"."
}
}
}Designs one block as a finished TSX file in the direction's world: nav, hero, features, stats, cta, loading, footer, pricing, faq, testimonials, logos, gallery, timeline, contact, feature-icons, split, banner. Pass variant to choose its layout, component to build around a particular piece. Returns the file, the site layer CSS it relies on and the components to install with fit_component.
| Argument | Type | Description |
|---|---|---|
| copy | object | Override the brief's headline, subline or call to action here. |
| kind* | string | |
| brief | object | Used when there is no direction_id yet: brand, app (required), audience, mood, colors, theme, headline, subline, cta, avoid, and optionally world. |
| title | string | The section title. |
| target | string | next: Next.js app router files (default). vite: Vite React files. |
| content | object | The site's real content, in the user's words. Blocks that need facts (numbers, quotes, prices, names) are only planned when they are given here; nothing is invented. |
| variant | string | Layout variant. nav: bar, float, masthead; hero: backdrop, split, poster, frame, masthead, kinetic, page; features: rows, columns, bento, sticky; stats: band, inline, boxed; cta: panel, type, quiet; loading: center, bar; footer: columns, wordmark, line; pricing: cards, table, menu; faq: accordion, split, grid; testimonials: single, columns, wall; logos: row, grid; gallery: mosaic, strip, grid; timeline: vertical, steps; contact: split, card, details; feature-icons: grid, list; split: media, wide, quote; banner: strip, notice. |
Designs one page as finished TSX files: the page file, one file per block (nav, hero, sections, footer) and the site layer CSS, laid out for the direction's world, responsive from phone to desktop, accessible, tokens only, real copy. Returns the files, the components to install with fit_component, the copy to confirm, and a short page summary. Check the page with review_page before you show it.
| Argument | Type | Description |
|---|---|---|
| copy | object | Override the brief's headline, subline or call to action here. |
| page | string | Which page of the plan, by slug ("" or "home" for the home page, "pricing", "about"...). |
| type | string | The site type from plan_site (default landing). |
| brief | object | Used when there is no direction_id yet: brand, app (required), audience, mood, colors, theme, headline, subline, cta, avoid, and optionally world. |
| blocks | array | Optional: your own block order instead of the plan's. |
| target | string | next: Next.js app router files (default). vite: Vite React files. |
| content | object | The site's real content, in the user's words. Blocks that need facts (numbers, quotes, prices, names) are only planned when they are given here; nothing is invented. |
Designs one finished section of the app (hero, nav, features, stats, cta or loading) around Louis Studios components tailored to the direction: colours, copy, speed and layout set for this user. Returns a ready TSX file and the components to install for it.
| Argument | Type | Description |
|---|---|---|
| copy | object | Text for this part, in the user's words. |
| kind* | string | Which section. |
| items | array | Cards for features or stats: a title (or number) and one line each. |
| button | string | Optional slug of a Louis Studios button for the call to action. |
| component | string | Optional slug to build the section around instead of the designer's pick. |
| import_base | string | Where installed components live, as the import path (default "@/components/ui"). |
| direction_id* | string | The direction_id from create_direction. |
{
"type": "object",
"required": [
"direction_id",
"kind"
],
"properties": {
"copy": {
"type": "object",
"properties": {
"cta": {
"type": "string"
},
"loading": {
"type": "string"
},
"subline": {
"type": "string"
},
"headline": {
"type": "string"
}
},
"description": "Text for this part, in the user's words."
},
"kind": {
"enum": [
"hero",
"features",
"stats",
"cta",
"loading",
"nav"
],
"type": "string",
"description": "Which section."
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"body": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"description": "Cards for features or stats: a title (or number) and one line each."
},
"button": {
"type": "string",
"description": "Optional slug of a Louis Studios button for the call to action."
},
"component": {
"type": "string",
"description": "Optional slug to build the section around instead of the designer's pick."
},
"import_base": {
"type": "string",
"description": "Where installed components live, as the import path (default \"@/components/ui\")."
},
"direction_id": {
"type": "string",
"description": "The direction_id from create_direction."
}
}
}Start here. Turns what the user wants into a design direction for the app: a palette built from their colours or mood, type, radius, motion and layout. Returns a direction_id for the other tools and a theme CSS file of tokens to save in the project.
| Argument | Type | Description |
|---|---|---|
| app* | string | What the app is and does, in a sentence or two. |
| cta | string | The call to action label. |
| mood | string | How it should feel, in the user's words: "calm and premium", "loud and sporty", "playful", "editorial"... |
| avoid | string | Things the user does not want, for example "playful". |
| brand | string | Brand or product name. |
| theme | string | Force a dark or light theme. Leave out to let the mood decide. |
| colors | array | Brand colours as hex ("#ff5a1f") or names ("teal"), most important first. Leave out to let the designer choose. |
| subline | string | One supporting sentence. |
| audience | string | Who it is for. |
Call this first, before any page or component work on a new site, once you know what the site is (ask for the brand, what it does, who it is for, the mood and any brand colours if you cannot read them from the project). Returns three clearly different design directions for the brief (different world, palette, type and shape), each with its palette in light and dark and its type. Saves nothing. Show the user the three in a few lines each and ask which one, then call set_direction with the same brief and the chosen option number.
| Argument | Type | Description |
|---|---|---|
| app* | string | What the site or app is and does, in a sentence or two. |
| cta | string | The call to action label. |
| mood | string | How it should feel, in the user's words. Naming worlds works too: "luxury + sakura", "brutalist", "Y2K". |
| avoid | string | What the user does not want, for example "playful" or "glow". |
| blend | string | A second world mixed in, or "none". |
| brand | string | Brand or product name. |
| knobs | object | Explicit settings that override the world. Every one can also be said in plain words through "tweak". |
Installs a component licensed to the account, fully fitted to the direction: its colours and type become the product's, and its motion speed and intensity, corners, stroke and border weight, density, light or dark build and sample copy change to suit the site. Costs exactly what install_component costs (its price in coins on Pro 30, free on Max, free again for 30 days). By default a one-line shell command; pass as "source" to get the file itself when you cannot run commands. Call fit_preview first to see what will change.
| Argument | Type | Description |
|---|---|---|
| as | string | "command" (default): a curl command, valid for 15 minutes. "source": the licensed, fitted file. |
| dir | string | Project-relative folder (default "components/ui"). |
| slug* | string | The component slug, for example "glow-button". |
| direction_id* | string | The direction_id from set_direction (or create_direction). |
{
"type": "object",
"required": [
"slug",
"direction_id"
],
"properties": {
"as": {
"enum": [
"command",
"source"
],
"type": "string",
"description": "\"command\" (default): a curl command, valid for 15 minutes. \"source\": the licensed, fitted file."
},
"dir": {
"type": "string",
"description": "Project-relative folder (default \"components/ui\")."
},
"slug": {
"type": "string",
"description": "The component slug, for example \"glow-button\"."
},
"direction_id": {
"type": "string",
"description": "The direction_id from set_direction (or create_direction)."
}
}
}Lists, in plain words, what fit_component will change in one component for a direction (colours, motion, corners, stroke, density, light or dark build, copy) and what stays as made and why, plus the JSX to use it with. Never returns source and costs nothing.
| Argument | Type | Description |
|---|---|---|
| copy | object | Optional copy: brand, headline, subline, cta. |
| role | string | The part it plays. |
| slug* | string | The component slug, for example "glow-button". |
| direction_id* | string | The direction_id from set_direction (or create_direction). |
{
"type": "object",
"required": [
"slug",
"direction_id"
],
"properties": {
"copy": {
"type": "object",
"properties": {
"cta": {
"type": "string"
},
"brand": {
"type": "string"
},
"subline": {
"type": "string"
},
"headline": {
"type": "string"
}
},
"description": "Optional copy: brand, headline, subline, cta."
},
"role": {
"enum": [
"hero",
"headline",
"cta",
"action",
"card",
"loader",
"nav"
],
"type": "string",
"description": "The part it plays."
},
"slug": {
"type": "string",
"description": "The component slug, for example \"glow-button\"."
},
"direction_id": {
"type": "string",
"description": "The direction_id from set_direction (or create_direction)."
}
}
}Everything about one component: what it does, every prop with its type, default and meaning, which props the designer can tailor, and the file name.
| Argument | Type | Description |
|---|---|---|
| slug* | string | Component slug, for example "blob-type". Slugs come from recommend_components or search_components. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "Component slug, for example \"blob-type\". Slugs come from recommend_components or search_components."
}
}
}Dot Room dots in the product's palette. As "accent": each dot as its own React file (live and animated) with the brand colours, theme, numeral font and ring weight baked in. As "texture": a quiet repeating background made of the chosen dots in one brand tone, as CSS (a class to put on any section) and the SVG tile. Costs like the Dot Room: 1 coin a dot, 10 for the whole archive, free on Max; open 30 days. preview: true shows the plan and price without spending.
| Argument | Type | Description |
|---|---|---|
| dir | string | Project-relative folder for files (default "components"). |
| use | string | "accent" (default): the dots themselves. "texture": a background made from them. |
| dots* | array | Dot kinds from browse_rooms (room "dot-room"), for example ["heart-rate", "aqi"]. |
| size | number | Dot diameter in px (default: the type scale step nearest 64). |
| tone | string | texture: which token tone it is drawn in (default accent). |
| format | string | accent: "react" (default) or "svg" (a still of each). texture: always CSS plus the SVG tile. |
| preview | boolean | Only show the plan and the price. Spends nothing. |
| strength | number |
Icon Room icons drawn for the product: the stroke weight from the direction's world and borders, the size from its type scale, the accent and quiet parts from its colour tokens (the main stroke is currentColor). Returns ONE React file with a typed, tree-shakeable named export per icon, or SVG strings. Costs like the Icon Room: 1 coin an icon, 10 for the whole archive (taken instead when that is no dearer), free on Max; anything taken stays open 30 days. preview: true shows the look and the price without spending.
| Argument | Type | Description |
|---|---|---|
| all | boolean | Every icon in the archive (10 coins once, free on Max). |
| dir | string | Project-relative folder for the file (default "components"). |
| size | any | Pixel size, or "ui" (default, the type scale step nearest 24) or "feature" (nearest 48). |
| icons | array | Icon names from browse_rooms (room "icon-room"), for example ["bell", "search", "cart"]. |
| format | string | "react" (default): one TSX file. "svg": one standalone SVG per icon, colours resolved to the tokens. |
| stroke | number | Override the stroke width on the 24 grid. |
| preview | boolean | Only show the look, the usage and the price. Spends nothing. |
| direction_id |
Delivers a component licensed to the account. With a direction_id the file arrives restyled for the product: every colour moved into its palette and its type set in the product's faces, so it looks made for this app rather than taken from a catalog. By default a one-line shell command that downloads the file; pass as "source" to get the file itself when you cannot run commands.
| Argument | Type | Description |
|---|---|---|
| as | string | "command" (default): a curl command, valid for 15 minutes. "source": the licensed file. |
| dir | string | Project-relative folder (default "components/ui"). |
| slug* | string | Component slug, for example "blob-type". Slugs come from recommend_components or search_components. |
| direction_id | string | The direction to restyle the file for. Always pass it when the app has a direction. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"as": {
"enum": [
"command",
"source"
],
"type": "string",
"description": "\"command\" (default): a curl command, valid for 15 minutes. \"source\": the licensed file."
},
"dir": {
"type": "string",
"description": "Project-relative folder (default \"components/ui\")."
},
"slug": {
"type": "string",
"description": "Component slug, for example \"blob-type\". Slugs come from recommend_components or search_components."
},
"direction_id": {
"type": "string",
"description": "The direction to restyle the file for. Always pass it when the app has a direction."
}
}
}Draws a mark for the brand from the Logo Room: its initials (or letters you choose) alone or in a circle, rounded or square container, drawn in the direction's colours and weight, flat or with a Logo Room finish that draws as SVG (haze, tube, sign, halftone, topo). Returns the SVG and a React component. Costs like a Logo Room export: 1 coin, free on Max. preview: true returns a tiny text outline and the plan without spending.
| Argument | Type | Description |
|---|---|---|
| dir | string | Project-relative folder for the file (default "components"). |
| name | string | Component name (default "<Brand>Mark"). |
| size | number | Default width in px for the component (default from the type scale). |
| solid | boolean | A solid container with the letters cut out, instead of a line around them. |
| finish | string | Default: flat for most directions, a light finish for neon worlds. |
| letters | string | 1 to 3 letters or digits. Default: the brand's initials. |
| preview | boolean | A tiny outline and the plan only. Spends nothing. |
| container | string | Default: what the direction's world suggests. |
Maps a brief to a whole site: the pages for the site type and, for each, the ordered blocks with the variant the direction's world favours, the Louis Studios component picked for it and why. One statement piece per screen, quiet surroundings. Blocks that need facts the content does not give are left out and listed. Then compose_page each page.
| Argument | Type | Description |
|---|---|---|
| type* | string | What kind of site. |
| brief | object | Used when there is no direction_id yet: brand, app (required), audience, mood, colors, theme, headline, subline, cta, avoid, and optionally world. |
| content | object | The site's real content, in the user's words. Blocks that need facts (numbers, quotes, prices, names) are only planned when they are given here; nothing is invented. |
| direction_id | string | The direction_id from set_direction (or create_direction). |
{
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"enum": [
"landing",
"saas",
"portfolio",
"shop",
"restaurant",
"event",
"docs",
"app"
],
"type": "string",
"description": "What kind of site."
},
"brief": {
"type": "object",
"properties": {
"app": {
"type": "string"
},
"cta": {
"type": "string"
},
"mood": {
"type": "string"
},
"avoid": {
"type": "string"
},
"brand": {
"type": "string"
},
"theme": {
"enum": [
"dark",
"light"
],
"type": "string"
},
"world": {
"type": "string"
},
"colors": {
"type": "array",
"items": {
"type": "string"
}
},
"subline": {
"type": "string"
},
"audience": {
"type": "string"
},
"headline": {
"type": "string"
}
},
"description": "Used when there is no direction_id yet: brand, app (required), audience, mood, colors, theme, headline, subline, cta, avoid, and optionally world."
},
"content": {
"type": "object",
"properties": {
"faq": {
"type": "array",
"items": {
"type": "object",
"properties": {
"a": {
"type": "string"
},
"q": {
"type": "string"
}
}
},
"description": "Questions and answers."
},
"nav": {
"type": "array",
"items": {
"type": "object",
"properties": {
"href": {
"type": "string"
},
"label": {
"type": "string"
}
}
},
"description": "Nav links, when the user has their own."
},
"menu": {
"type": "array",
"items": {
"type": "object",
"properties": {
"group": {
"type": "string"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ja": {
"type": "string"
},
"name": {
"type": "string"
},
"note": {
"type": "string"
},
"price": {
"type": "string"
}
}
},
"description": "Dishes or products."
}
}
},
"description": "A menu or price list in groups."
},
"logos": {
"type": "array",
"items": {
"type": "string"
},
"description": "Names of real customers or partners."
},
"plans": {
"type": "array",
"items": {
"type": "object",
"properties": {
"cta": {
"type": "string"
},
"name": {
"type": "string"
},
"blurb": {
"type": "string"
},
"price": {
"type": "string"
},
"period": {
"type": "string"
},
"features": {
"type": "array"
}
}
},
"description": "Plans or tickets with real prices; features is a list of strings; featured: true marks one."
},
"stats": {
"type": "array",
"items": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"description": "Real numbers only."
},
"story": {
"type": "object",
"properties": {
"body": {
"type": "array",
"items": {
"type": "string"
}
},
"image": {
"type": "object",
"properties": {
"alt": {
"type": "string"
},
"src": {
"type": "string"
}
}
},
"quote": {
"type": "string"
},
"title": {
"type": "string"
}
},
"description": "The about or story section."
},
"banner": {
"type": "string",
"description": "One line of news for an announcement bar."
},
"footer": {
"type": "object",
"properties": {
"note": {
"type": "string"
},
"legal": {
"type": "string"
}
}
},
"intros": {
"type": "object",
"description": "One line under a section title, by block kind."
},
"quotes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"role": {
"type": "string"
},
"quote": {
"type": "string"
}
}
},
"description": "Real quotes from real people."
},
"titles": {
"type": "object",
"description": "Section titles by block kind, for example { \"features\": \"Why teams switch\" }."
},
"closing": {
"type": "object",
"properties": {
"cta": {
"type": "string"
},
"subline": {
"type": "string"
},
"headline": {
"type": "string"
}
},
"description": "The closing call to action."
},
"contact": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"hours": {
"type": "array",
"items": {
"type": "string"
}
},
"phone": {
"type": "string"
},
"address": {
"type": "string"
}
}
},
"ctaHref": {
"type": "string",
"description": "Where the main button goes."
},
"gallery": {
"type": "array",
"items": {
"type": "object",
"properties": {
"alt": {
"type": "string"
},
"src": {
"type": "string"
},
"price": {
"type": "string"
},
"caption": {
"type": "string"
}
}
},
"description": "Images: src (leave empty for a placeholder), alt (required), optional caption and price."
},
"features": {
"type": "array",
"items": {
"type": "object",
"properties": {
"body": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"description": "Reasons to care: a short title and one sentence each."
},
"japanese": {
"type": "object",
"properties": {
"hero": {
"type": "string"
}
},
"description": "Japanese lines, for directions that use Japanese."
},
"timeline": {
"type": "array",
"items": {
"type": "object",
"properties": {
"body": {
"type": "string"
},
"when": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"description": "Steps, a schedule or a history."
},
"secondary": {
"type": "object",
"properties": {
"href": {
"type": "string"
},
"label": {
"type": "string"
}
},
"description": "A quiet second link in the hero."
},
"highlights": {
"type": "array",
"items": {
"type": "object",
"properties": {
"body": {
"type": "string"
},
"icon": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"description": "Short promises shown with drawn icons."
}
},
"description": "The site's real content, in the user's words. Blocks that need facts (numbers, quotes, prices, names) are only planned when they are given here; nothing is invented."
},
"direction_id": {
"type": "string",
"description": "The direction_id from set_direction (or create_direction)."
}
}
}A still image of the component as it looks on the site, with links to its page and video.
| Argument | Type | Description |
|---|---|---|
| slug* | string | Component slug, for example "blob-type". Slugs come from recommend_components or search_components. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "Component slug, for example \"blob-type\". Slugs come from recommend_components or search_components."
}
}
}Picks Louis Studios components for each part of an app (hero, buttons and controls, navigation, data and cards, loading, AI and voice). With a direction_id the picks suit that direction and come back already tailored to it.
| Argument | Type | Description |
|---|---|---|
| app | string | What the app is, when there is no direction yet. |
| colors | array | Optional, without a direction: colours to favour. |
| sections | array | Optional: the parts you need, for example ["hero", "pricing cards", "loading", "settings toggles"]. |
| per_section | integer | Picks per part (default 2). |
| direction_id | string | The direction_id from create_direction. |
{
"type": "object",
"properties": {
"app": {
"type": "string",
"description": "What the app is, when there is no direction yet."
},
"colors": {
"type": "array",
"items": {
"enum": [
"mono",
"red",
"orange",
"yellow",
"green",
"blue",
"purple",
"pink",
"rainbow"
],
"type": "string"
},
"description": "Optional, without a direction: colours to favour."
},
"sections": {
"type": "array",
"items": {
"type": "string"
},
"description": "Optional: the parts you need, for example [\"hero\", \"pricing cards\", \"loading\", \"settings toggles\"]."
},
"per_section": {
"type": "integer",
"maximum": 4,
"minimum": 1,
"description": "Picks per part (default 2)."
},
"direction_id": {
"type": "string",
"description": "The direction_id from create_direction."
}
}
}Checks a page you composed before the user sees it. Pass the direction_id and the files you wrote, each with its content (page file, block files, CSS). Returns findings, each with severity, file and line, the problem and the exact fix: contrast below WCAG AA, colours outside the direction, more than one statement piece on a screen, images without alt, missing landmarks or skipped headings, motion without a reduced-motion fallback, widths that overflow a 375px phone, placeholder copy, missing licence headers. When this server can render, also screenshots at 1440 and 375px and what it measured there (sideways scroll, clipped or overlapping text, small tap targets, real contrast). Free; fix every high finding, then review again.
| Argument | Type | Description |
|---|---|---|
| page | object | Instead of files: an object that holds them, { files: [{ path, content }] }. |
| entry | string | Optional: the path of the file that renders the page, when it is not page.tsx, App.tsx or index.tsx. |
| files | array | The page file, its block files and any CSS it imports. Installed component files are optional (without them each shows as a labelled box in the screenshot). |
| widths | array | Optional screenshot widths in px (default [1440, 375]). |
| direction_id | string | The direction the page was composed for. |
Search Louis Studios components by words, category and colour. Leave everything empty to list the newest.
| Argument | Type | Description |
|---|---|---|
| color | string | |
| limit | integer | How many results (default 10). |
| query | string | Words to look for, for example "countdown", "glass toggle", "liquid chrome". |
| category | string |
{
"type": "object",
"properties": {
"color": {
"enum": [
"mono",
"red",
"orange",
"yellow",
"green",
"blue",
"purple",
"pink",
"rainbow"
],
"type": "string"
},
"limit": {
"type": "integer",
"maximum": 30,
"minimum": 1,
"description": "How many results (default 10)."
},
"query": {
"type": "string",
"description": "Words to look for, for example \"countdown\", \"glass toggle\", \"liquid chrome\"."
},
"category": {
"enum": [
"Backgrounds",
"Text",
"Buttons & controls",
"Loaders",
"Cards & grids",
"Navigation",
"AI & voice",
"Effects & objects"
],
"type": "string"
}
}
}Call this once the user has picked one of the design_options (pass the same brief plus option 1, 2 or 3), or straight away when the user already knows the look (pass world, blend and knobs, or a tweak in plain words). Saves the direction and returns its direction_id, a description to tell the user, and the theme CSS for both light and dark: save it as styles/louis-studios-theme.css and import it once in the root layout. Every other designer tool takes this direction_id.
| Argument | Type | Description |
|---|---|---|
| app* | string | What the site or app is and does, in a sentence or two. |
| cta | string | The call to action label. |
| mood | string | How it should feel, in the user's words. Naming worlds works too: "luxury + sakura", "brutalist", "Y2K". |
| avoid | string | What the user does not want, for example "playful" or "glow". |
| blend | string | A second world mixed in, or "none". |
| brand | string | Brand or product name. |
| knobs | object | Explicit settings that override the world. Every one can also be said in plain words through "tweak". |
| theme | string | The default theme. Leave out to let the world decide; both themes are always made. |
Configures one component for the direction: its colours from the palette, its text from the user's copy, its pace from the motion. Returns the tailored JSX and what was changed, and says when a component's own colours cannot change.
| Argument | Type | Description |
|---|---|---|
| copy | object | Text for this part, in the user's words. |
| role | string | The part it plays. |
| slug* | string | Component slug, for example "blob-type". Slugs come from recommend_components or search_components. |
| direction_id* | string | The direction_id from create_direction. |
{
"type": "object",
"required": [
"direction_id",
"slug"
],
"properties": {
"copy": {
"type": "object",
"properties": {
"cta": {
"type": "string"
},
"loading": {
"type": "string"
},
"subline": {
"type": "string"
},
"headline": {
"type": "string"
}
},
"description": "Text for this part, in the user's words."
},
"role": {
"enum": [
"hero",
"headline",
"cta",
"action",
"card",
"loader",
"nav"
],
"type": "string",
"description": "The part it plays."
},
"slug": {
"type": "string",
"description": "Component slug, for example \"blob-type\". Slugs come from recommend_components or search_components."
},
"direction_id": {
"type": "string",
"description": "The direction_id from create_direction."
}
}
}Changes a direction when the user wants it different. Pass only what changes, and/or a tweak in plain words ("warmer", "more playful", "lighter", "more luxurious"). Returns the new palette, type and tokens; compose sections again afterwards.
| Argument | Type | Description |
|---|---|---|
| app | string | What the app is and does, in a sentence or two. |
| cta | string | The call to action label. |
| mood | string | How it should feel, in the user's words: "calm and premium", "loud and sporty", "playful", "editorial"... |
| avoid | string | Things the user does not want, for example "playful". |
| brand | string | Brand or product name. |
| theme | string | Force a dark or light theme. Leave out to let the mood decide. |
| tweak | string | The change in plain words. |
| colors | array | Brand colours as hex ("#ff5a1f") or names ("teal"), most important first. Leave out to let the designer choose. |
| subline | string | One supporting sentence. |
We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 12, 2026.
| component | string | Optional slug to build the block around. |
| direction_id | string | The direction_id from set_direction (or create_direction). |
{
"type": "object",
"required": [
"kind"
],
"properties": {
"copy": {
"type": "object",
"properties": {
"cta": {
"type": "string"
},
"subline": {
"type": "string"
},
"headline": {
"type": "string"
}
},
"description": "Override the brief's headline, subline or call to action here."
},
"kind": {
"enum": [
"nav",
"hero",
"features",
"stats",
"cta",
"loading",
"footer",
"pricing",
"faq",
"testimonials",
"logos",
"gallery",
"timeline",
"contact",
"feature-icons",
"split",
"banner"
],
"type": "string"
},
"brief": {
"type": "object",
"properties": {
"app": {
"type": "string"
},
"cta": {
"type": "string"
},
"mood": {
"type": "string"
},
"avoid": {
"type": "string"
},
"brand": {
"type": "string"
},
"theme": {
"enum": [
"dark",
"light"
],
"type": "string"
},
"world": {
"type": "string"
},
"colors": {
"type": "array",
"items": {
"type": "string"
}
},
"subline": {
"type": "string"
},
"audience": {
"type": "string"
},
"headline": {
"type": "string"
}
},
"description": "Used when there is no direction_id yet: brand, app (required), audience, mood, colors, theme, headline, subline, cta, avoid, and optionally world."
},
"title": {
"type": "string",
"description": "The section title."
},
"target": {
"enum": [
"next",
"vite"
],
"type": "string",
"description": "next: Next.js app router files (default). vite: Vite React files."
},
"content": {
"type": "object",
"properties": {
"faq": {
"type": "array",
"items": {
"type": "object",
"properties": {
"a": {
"type": "string"
},
"q": {
"type": "string"
}
}
},
"description": "Questions and answers."
},
"nav": {
"type": "array",
"items": {
"type": "object",
"properties": {
"href": {
"type": "string"
},
"label": {
"type": "string"
}
}
},
"description": "Nav links, when the user has their own."
},
"menu": {
"type": "array",
"items": {
"type": "object",
"properties": {
"group": {
"type": "string"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ja": {
"type": "string"
},
"name": {
"type": "string"
},
"note": {
"type": "string"
},
"price": {
"type": "string"
}
}
},
"description": "Dishes or products."
}
}
},
"description": "A menu or price list in groups."
},
"logos": {
"type": "array",
"items": {
"type": "string"
},
"description": "Names of real customers or partners."
},
"plans": {
"type": "array",
"items": {
"type": "object",
"properties": {
"cta": {
"type": "string"
},
"name": {
"type": "string"
},
"blurb": {
"type": "string"
},
"price": {
"type": "string"
},
"period": {
"type": "string"
},
"features": {
"type": "array"
}
}
},
"description": "Plans or tickets with real prices; features is a list of strings; featured: true marks one."
},
"stats": {
"type": "array",
"items": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"description": "Real numbers only."
},
"story": {
"type": "object",
"properties": {
"body": {
"type": "array",
"items": {
"type": "string"
}
},
"image": {
"type": "object",
"properties": {
"alt": {
"type": "string"
},
"src": {
"type": "string"
}
}
},
"quote": {
"type": "string"
},
"title": {
"type": "string"
}
},
"description": "The about or story section."
},
"banner": {
"type": "string",
"description": "One line of news for an announcement bar."
},
"footer": {
"type": "object",
"properties": {
"note": {
"type": "string"
},
"legal": {
"type": "string"
}
}
},
"intros": {
"type": "object",
"description": "One line under a section title, by block kind."
},
"quotes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"role": {
"type": "string"
},
"quote": {
"type": "string"
}
}
},
"description": "Real quotes from real people."
},
"titles": {
"type": "object",
"description": "Section titles by block kind, for example { \"features\": \"Why teams switch\" }."
},
"closing": {
"type": "object",
"properties": {
"cta": {
"type": "string"
},
"subline": {
"type": "string"
},
"headline": {
"type": "string"
}
},
"description": "The closing call to action."
},
"contact": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"hours": {
"type": "array",
"items": {
"type": "string"
}
},
"phone": {
"type": "string"
},
"address": {
"type": "string"
}
}
},
"ctaHref": {
"type": "string",
"description": "Where the main button goes."
},
"gallery": {
"type": "array",
"items": {
"type": "object",
"properties": {
"alt": {
"type": "string"
},
"src": {
"type": "string"
},
"price": {
"type": "string"
},
"caption": {
"type": "string"
}
}
},
"description": "Images: src (leave empty for a placeholder), alt (required), optional caption and price."
},
"features": {
"type": "array",
"items": {
"type": "object",
"properties": {
"body": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"description": "Reasons to care: a short title and one sentence each."
},
"japanese": {
"type": "object",
"properties": {
"hero": {
"type": "string"
}
},
"description": "Japanese lines, for directions that use Japanese."
},
"timeline": {
"type": "array",
"items": {
"type": "object",
"properties": {
"body": {
"type": "string"
},
"when": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"description": "Steps, a schedule or a history."
},
"secondary": {
"type": "object",
"properties": {
"href": {
"type": "string"
},
"label": {
"type": "string"
}
},
"description": "A quiet second link in the hero."
},
"highlights": {
"type": "array",
"items": {
"type": "object",
"properties": {
"body": {
"type": "string"
},
"icon": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"description": "Short promises shown with drawn icons."
}
},
"description": "The site's real content, in the user's words. Blocks that need facts (numbers, quotes, prices, names) are only planned when they are given here; nothing is invented."
},
"variant": {
"type": "string",
"description": "Layout variant. nav: bar, float, masthead; hero: backdrop, split, poster, frame, masthead, kinetic, page; features: rows, columns, bento, sticky; stats: band, inline, boxed; cta: panel, type, quiet; loading: center, bar; footer: columns, wordmark, line; pricing: cards, table, menu; faq: accordion, split, grid; testimonials: single, columns, wall; logos: row, grid; gallery: mosaic, strip, grid; timeline: vertical, steps; contact: split, card, details; feature-icons: grid, list; split: media, wide, quote; banner: strip, notice."
},
"component": {
"type": "string",
"description": "Optional slug to build the block around."
},
"direction_id": {
"type": "string",
"description": "The direction_id from set_direction (or create_direction)."
}
}
}| direction_id | string | The direction_id from set_direction (or create_direction). |
{
"type": "object",
"properties": {
"copy": {
"type": "object",
"properties": {
"cta": {
"type": "string"
},
"subline": {
"type": "string"
},
"headline": {
"type": "string"
}
},
"description": "Override the brief's headline, subline or call to action here."
},
"page": {
"type": "string",
"description": "Which page of the plan, by slug (\"\" or \"home\" for the home page, \"pricing\", \"about\"...)."
},
"type": {
"enum": [
"landing",
"saas",
"portfolio",
"shop",
"restaurant",
"event",
"docs",
"app"
],
"type": "string",
"description": "The site type from plan_site (default landing)."
},
"brief": {
"type": "object",
"properties": {
"app": {
"type": "string"
},
"cta": {
"type": "string"
},
"mood": {
"type": "string"
},
"avoid": {
"type": "string"
},
"brand": {
"type": "string"
},
"theme": {
"enum": [
"dark",
"light"
],
"type": "string"
},
"world": {
"type": "string"
},
"colors": {
"type": "array",
"items": {
"type": "string"
}
},
"subline": {
"type": "string"
},
"audience": {
"type": "string"
},
"headline": {
"type": "string"
}
},
"description": "Used when there is no direction_id yet: brand, app (required), audience, mood, colors, theme, headline, subline, cta, avoid, and optionally world."
},
"blocks": {
"type": "array",
"items": {
"type": "object",
"required": [
"kind"
],
"properties": {
"kind": {
"enum": [
"nav",
"hero",
"features",
"stats",
"cta",
"loading",
"footer",
"pricing",
"faq",
"testimonials",
"logos",
"gallery",
"timeline",
"contact",
"feature-icons",
"split",
"banner"
],
"type": "string"
},
"variant": {
"type": "string"
},
"component": {
"type": "string"
}
}
},
"description": "Optional: your own block order instead of the plan's."
},
"target": {
"enum": [
"next",
"vite"
],
"type": "string",
"description": "next: Next.js app router files (default). vite: Vite React files."
},
"content": {
"type": "object",
"properties": {
"faq": {
"type": "array",
"items": {
"type": "object",
"properties": {
"a": {
"type": "string"
},
"q": {
"type": "string"
}
}
},
"description": "Questions and answers."
},
"nav": {
"type": "array",
"items": {
"type": "object",
"properties": {
"href": {
"type": "string"
},
"label": {
"type": "string"
}
}
},
"description": "Nav links, when the user has their own."
},
"menu": {
"type": "array",
"items": {
"type": "object",
"properties": {
"group": {
"type": "string"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ja": {
"type": "string"
},
"name": {
"type": "string"
},
"note": {
"type": "string"
},
"price": {
"type": "string"
}
}
},
"description": "Dishes or products."
}
}
},
"description": "A menu or price list in groups."
},
"logos": {
"type": "array",
"items": {
"type": "string"
},
"description": "Names of real customers or partners."
},
"plans": {
"type": "array",
"items": {
"type": "object",
"properties": {
"cta": {
"type": "string"
},
"name": {
"type": "string"
},
"blurb": {
"type": "string"
},
"price": {
"type": "string"
},
"period": {
"type": "string"
},
"features": {
"type": "array"
}
}
},
"description": "Plans or tickets with real prices; features is a list of strings; featured: true marks one."
},
"stats": {
"type": "array",
"items": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"description": "Real numbers only."
},
"story": {
"type": "object",
"properties": {
"body": {
"type": "array",
"items": {
"type": "string"
}
},
"image": {
"type": "object",
"properties": {
"alt": {
"type": "string"
},
"src": {
"type": "string"
}
}
},
"quote": {
"type": "string"
},
"title": {
"type": "string"
}
},
"description": "The about or story section."
},
"banner": {
"type": "string",
"description": "One line of news for an announcement bar."
},
"footer": {
"type": "object",
"properties": {
"note": {
"type": "string"
},
"legal": {
"type": "string"
}
}
},
"intros": {
"type": "object",
"description": "One line under a section title, by block kind."
},
"quotes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"role": {
"type": "string"
},
"quote": {
"type": "string"
}
}
},
"description": "Real quotes from real people."
},
"titles": {
"type": "object",
"description": "Section titles by block kind, for example { \"features\": \"Why teams switch\" }."
},
"closing": {
"type": "object",
"properties": {
"cta": {
"type": "string"
},
"subline": {
"type": "string"
},
"headline": {
"type": "string"
}
},
"description": "The closing call to action."
},
"contact": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"hours": {
"type": "array",
"items": {
"type": "string"
}
},
"phone": {
"type": "string"
},
"address": {
"type": "string"
}
}
},
"ctaHref": {
"type": "string",
"description": "Where the main button goes."
},
"gallery": {
"type": "array",
"items": {
"type": "object",
"properties": {
"alt": {
"type": "string"
},
"src": {
"type": "string"
},
"price": {
"type": "string"
},
"caption": {
"type": "string"
}
}
},
"description": "Images: src (leave empty for a placeholder), alt (required), optional caption and price."
},
"features": {
"type": "array",
"items": {
"type": "object",
"properties": {
"body": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"description": "Reasons to care: a short title and one sentence each."
},
"japanese": {
"type": "object",
"properties": {
"hero": {
"type": "string"
}
},
"description": "Japanese lines, for directions that use Japanese."
},
"timeline": {
"type": "array",
"items": {
"type": "object",
"properties": {
"body": {
"type": "string"
},
"when": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"description": "Steps, a schedule or a history."
},
"secondary": {
"type": "object",
"properties": {
"href": {
"type": "string"
},
"label": {
"type": "string"
}
},
"description": "A quiet second link in the hero."
},
"highlights": {
"type": "array",
"items": {
"type": "object",
"properties": {
"body": {
"type": "string"
},
"icon": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"description": "Short promises shown with drawn icons."
}
},
"description": "The site's real content, in the user's words. Blocks that need facts (numbers, quotes, prices, names) are only planned when they are given here; nothing is invented."
},
"direction_id": {
"type": "string",
"description": "The direction_id from set_direction (or create_direction)."
}
}
}| headline | string | The main headline. |
{
"type": "object",
"required": [
"app"
],
"properties": {
"app": {
"type": "string",
"description": "What the app is and does, in a sentence or two."
},
"cta": {
"type": "string",
"description": "The call to action label."
},
"mood": {
"type": "string",
"description": "How it should feel, in the user's words: \"calm and premium\", \"loud and sporty\", \"playful\", \"editorial\"..."
},
"avoid": {
"type": "string",
"description": "Things the user does not want, for example \"playful\"."
},
"brand": {
"type": "string",
"description": "Brand or product name."
},
"theme": {
"enum": [
"dark",
"light"
],
"type": "string",
"description": "Force a dark or light theme. Leave out to let the mood decide."
},
"colors": {
"type": "array",
"items": {
"type": "string"
},
"description": "Brand colours as hex (\"#ff5a1f\") or names (\"teal\"), most important first. Leave out to let the designer choose."
},
"subline": {
"type": "string",
"description": "One supporting sentence."
},
"audience": {
"type": "string",
"description": "Who it is for."
},
"headline": {
"type": "string",
"description": "The main headline."
}
}
}| theme | string | The default theme. Leave out to let the world decide; both themes are always made. |
| world | string | Force a world instead of letting the brief choose. |
| colors | array | Brand colours as hex or names, most important first. Kept exact. Leave out to let the designer choose. |
| subline | string | One supporting sentence. |
| audience | string | Who it is for. |
| headline | string | The main headline. |
{
"type": "object",
"required": [
"app"
],
"properties": {
"app": {
"type": "string",
"description": "What the site or app is and does, in a sentence or two."
},
"cta": {
"type": "string",
"description": "The call to action label."
},
"mood": {
"type": "string",
"description": "How it should feel, in the user's words. Naming worlds works too: \"luxury + sakura\", \"brutalist\", \"Y2K\"."
},
"avoid": {
"type": "string",
"description": "What the user does not want, for example \"playful\" or \"glow\"."
},
"blend": {
"enum": [
"calm",
"bold",
"playful",
"luxury",
"technical",
"editorial",
"warm",
"sakura",
"brutalist",
"retro",
"noir",
"organic",
"corporate",
"cyber",
"none"
],
"type": "string",
"description": "A second world mixed in, or \"none\"."
},
"brand": {
"type": "string",
"description": "Brand or product name."
},
"knobs": {
"type": "object",
"properties": {
"caps": {
"type": "boolean",
"description": "Headings in capitals."
},
"glow": {
"type": "boolean"
},
"hero": {
"enum": [
"backdrop",
"split",
"kinetic"
],
"type": "string"
},
"align": {
"enum": [
"left",
"center"
],
"type": "string"
},
"depth": {
"type": "number",
"maximum": 3,
"minimum": -3,
"description": "Steps darker (positive) or lighter backgrounds within the theme."
},
"scale": {
"enum": [
"modest",
"regular",
"dramatic"
],
"type": "string",
"description": "How far the type scale climbs."
},
"theme": {
"enum": [
"light",
"dark"
],
"type": "string",
"description": "The default theme. Both themes are always in the tokens."
},
"accent": {
"type": "string",
"description": "Main accent, hex or colour name. Kept exact."
},
"border": {
"enum": [
0,
1,
2
],
"type": "number",
"description": "Border weight in px."
},
"corner": {
"enum": [
"square",
"round",
"pill"
],
"type": "string"
},
"radius": {
"type": "number",
"maximum": 48,
"minimum": 0,
"description": "Corner radius in px."
},
"warmth": {
"type": "number",
"maximum": 3,
"minimum": -3,
"description": "Steps warmer (positive) or cooler (negative)."
},
"accent2": {
"type": "string",
"description": "Second accent, hex or colour name."
},
"accent3": {
"type": "string",
"description": "Third accent, hex or colour name."
},
"density": {
"enum": [
"airy",
"regular",
"compact"
],
"type": "string"
},
"surface": {
"enum": [
"flat",
"glass",
"shadow",
"outline"
],
"type": "string"
},
"texture": {
"enum": [
"none",
"grain",
"dots",
"grid",
"paper"
],
"type": "string"
},
"contrast": {
"enum": [
"soft",
"normal",
"high"
],
"type": "string"
},
"japanese": {
"type": "boolean",
"description": "Japanese text allowed, with Japanese faces in the stacks."
},
"textFont": {
"type": "string",
"description": "Body face, same choices as displayFont."
},
"tracking": {
"type": "number",
"maximum": 0.24,
"minimum": -0.08,
"description": "Heading letter spacing in em."
},
"saturation": {
"type": "number",
"maximum": 3,
"minimum": -3,
"description": "Steps more vivid or more muted, for colours the designer picks."
},
"displayFont": {
"type": "string",
"description": "Heading face: a kind (serif, sans, mono, rounded, slab, condensed, geometric, grotesk, humanist, didone, mincho) or a face name such as \"Didot\" or \"Futura\". Fallbacks are added."
},
"motionSpeed": {
"type": "number",
"maximum": 3,
"minimum": 0.25,
"description": "Multiplier on the world's pace: 0.75 is slower, 1.3 faster."
},
"followSystem": {
"type": "boolean",
"description": "Follow the visitor's system light or dark setting instead of the default theme."
},
"displayWeight": {
"type": "number",
"maximum": 900,
"minimum": 200
},
"motionIntensity": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "0 is nearly still, 1 is the most movement."
},
"textureStrength": {
"type": "number",
"maximum": 1,
"minimum": 0
}
},
"description": "Explicit settings that override the world. Every one can also be said in plain words through \"tweak\".",
"additionalProperties": false
},
"theme": {
"enum": [
"dark",
"light"
],
"type": "string",
"description": "The default theme. Leave out to let the world decide; both themes are always made."
},
"world": {
"enum": [
"calm",
"bold",
"playful",
"luxury",
"technical",
"editorial",
"warm",
"sakura",
"brutalist",
"retro",
"noir",
"organic",
"corporate",
"cyber"
],
"type": "string",
"description": "Force a world instead of letting the brief choose."
},
"colors": {
"type": "array",
"items": {
"type": "string"
},
"description": "Brand colours as hex or names, most important first. Kept exact. Leave out to let the designer choose."
},
"subline": {
"type": "string",
"description": "One supporting sentence."
},
"audience": {
"type": "string",
"description": "Who it is for."
},
"headline": {
"type": "string",
"description": "The main headline."
}
}
}| texture: how strong it is, 0.03 to 0.6 (default from the direction, about 0.12). |
| direction_id | string | The direction_id (from set_direction or create_direction). Items are drawn in its stroke weight, sizes and colours. |
{
"type": "object",
"required": [
"dots"
],
"properties": {
"dir": {
"type": "string",
"description": "Project-relative folder for files (default \"components\")."
},
"use": {
"enum": [
"accent",
"texture"
],
"type": "string",
"description": "\"accent\" (default): the dots themselves. \"texture\": a background made from them."
},
"dots": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 24,
"minItems": 1,
"description": "Dot kinds from browse_rooms (room \"dot-room\"), for example [\"heart-rate\", \"aqi\"]."
},
"size": {
"type": "number",
"maximum": 240,
"minimum": 24,
"description": "Dot diameter in px (default: the type scale step nearest 64)."
},
"tone": {
"enum": [
"accent",
"ink",
"muted"
],
"type": "string",
"description": "texture: which token tone it is drawn in (default accent)."
},
"format": {
"enum": [
"react",
"svg",
"css"
],
"type": "string",
"description": "accent: \"react\" (default) or \"svg\" (a still of each). texture: always CSS plus the SVG tile."
},
"preview": {
"type": "boolean",
"description": "Only show the plan and the price. Spends nothing."
},
"strength": {
"type": "number",
"maximum": 0.6,
"minimum": 0.03,
"description": "texture: how strong it is, 0.03 to 0.6 (default from the direction, about 0.12)."
},
"direction_id": {
"type": "string",
"description": "The direction_id (from set_direction or create_direction). Items are drawn in its stroke weight, sizes and colours."
}
}
}| string |
| The direction_id (from set_direction or create_direction). Items are drawn in its stroke weight, sizes and colours. |
{
"type": "object",
"properties": {
"all": {
"type": "boolean",
"description": "Every icon in the archive (10 coins once, free on Max)."
},
"dir": {
"type": "string",
"description": "Project-relative folder for the file (default \"components\")."
},
"size": {
"anyOf": [
{
"type": "number"
},
{
"enum": [
"ui",
"feature"
],
"type": "string"
}
],
"description": "Pixel size, or \"ui\" (default, the type scale step nearest 24) or \"feature\" (nearest 48)."
},
"icons": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 60,
"description": "Icon names from browse_rooms (room \"icon-room\"), for example [\"bell\", \"search\", \"cart\"]."
},
"format": {
"enum": [
"react",
"svg"
],
"type": "string",
"description": "\"react\" (default): one TSX file. \"svg\": one standalone SVG per icon, colours resolved to the tokens."
},
"stroke": {
"type": "number",
"maximum": 3.2,
"minimum": 0.75,
"description": "Override the stroke width on the 24 grid."
},
"preview": {
"type": "boolean",
"description": "Only show the look, the usage and the price. Spends nothing."
},
"direction_id": {
"type": "string",
"description": "The direction_id (from set_direction or create_direction). Items are drawn in its stroke weight, sizes and colours."
}
}
}| direction_id |
| string |
| The direction_id (from set_direction or create_direction). Items are drawn in its stroke weight, sizes and colours. |
{
"type": "object",
"properties": {
"dir": {
"type": "string",
"description": "Project-relative folder for the file (default \"components\")."
},
"name": {
"type": "string",
"description": "Component name (default \"<Brand>Mark\")."
},
"size": {
"type": "number",
"maximum": 512,
"minimum": 16,
"description": "Default width in px for the component (default from the type scale)."
},
"solid": {
"type": "boolean",
"description": "A solid container with the letters cut out, instead of a line around them."
},
"finish": {
"enum": [
"flat",
"haze",
"tube",
"sign",
"halftone",
"topo"
],
"type": "string",
"description": "Default: flat for most directions, a light finish for neon worlds."
},
"letters": {
"type": "string",
"maxLength": 3,
"description": "1 to 3 letters or digits. Default: the brand's initials."
},
"preview": {
"type": "boolean",
"description": "A tiny outline and the plan only. Spends nothing."
},
"container": {
"enum": [
"none",
"circle",
"rounded",
"square"
],
"type": "string",
"description": "Default: what the direction's world suggests."
},
"direction_id": {
"type": "string",
"description": "The direction_id (from set_direction or create_direction). Items are drawn in its stroke weight, sizes and colours."
}
}
}{
"type": "object",
"properties": {
"page": {
"type": "object",
"description": "Instead of files: an object that holds them, { files: [{ path, content }] }."
},
"entry": {
"type": "string",
"description": "Optional: the path of the file that renders the page, when it is not page.tsx, App.tsx or index.tsx."
},
"files": {
"type": "array",
"items": {
"type": "object",
"required": [
"path",
"content"
],
"properties": {
"path": {
"type": "string",
"description": "Project-relative path, for example \"app/page.tsx\"."
},
"content": {
"type": "string"
}
}
},
"maxItems": 40,
"description": "The page file, its block files and any CSS it imports. Installed component files are optional (without them each shows as a labelled box in the screenshot)."
},
"widths": {
"type": "array",
"items": {
"type": "integer",
"maximum": 1920,
"minimum": 320
},
"maxItems": 3,
"description": "Optional screenshot widths in px (default [1440, 375])."
},
"direction_id": {
"type": "string",
"description": "The direction the page was composed for."
}
}
}| tweak | string | Changes in plain words to apply before saving, as in adjust_direction. |
| world | string | Force a world instead of letting the brief choose. |
| colors | array | Brand colours as hex or names, most important first. Kept exact. Leave out to let the designer choose. |
| option | number | Which of the three design_options for this same brief. |
| subline | string | One supporting sentence. |
| audience | string | Who it is for. |
| headline | string | The main headline. |
{
"type": "object",
"required": [
"app"
],
"properties": {
"app": {
"type": "string",
"description": "What the site or app is and does, in a sentence or two."
},
"cta": {
"type": "string",
"description": "The call to action label."
},
"mood": {
"type": "string",
"description": "How it should feel, in the user's words. Naming worlds works too: \"luxury + sakura\", \"brutalist\", \"Y2K\"."
},
"avoid": {
"type": "string",
"description": "What the user does not want, for example \"playful\" or \"glow\"."
},
"blend": {
"enum": [
"calm",
"bold",
"playful",
"luxury",
"technical",
"editorial",
"warm",
"sakura",
"brutalist",
"retro",
"noir",
"organic",
"corporate",
"cyber",
"none"
],
"type": "string",
"description": "A second world mixed in, or \"none\"."
},
"brand": {
"type": "string",
"description": "Brand or product name."
},
"knobs": {
"type": "object",
"properties": {
"caps": {
"type": "boolean",
"description": "Headings in capitals."
},
"glow": {
"type": "boolean"
},
"hero": {
"enum": [
"backdrop",
"split",
"kinetic"
],
"type": "string"
},
"align": {
"enum": [
"left",
"center"
],
"type": "string"
},
"depth": {
"type": "number",
"maximum": 3,
"minimum": -3,
"description": "Steps darker (positive) or lighter backgrounds within the theme."
},
"scale": {
"enum": [
"modest",
"regular",
"dramatic"
],
"type": "string",
"description": "How far the type scale climbs."
},
"theme": {
"enum": [
"light",
"dark"
],
"type": "string",
"description": "The default theme. Both themes are always in the tokens."
},
"accent": {
"type": "string",
"description": "Main accent, hex or colour name. Kept exact."
},
"border": {
"enum": [
0,
1,
2
],
"type": "number",
"description": "Border weight in px."
},
"corner": {
"enum": [
"square",
"round",
"pill"
],
"type": "string"
},
"radius": {
"type": "number",
"maximum": 48,
"minimum": 0,
"description": "Corner radius in px."
},
"warmth": {
"type": "number",
"maximum": 3,
"minimum": -3,
"description": "Steps warmer (positive) or cooler (negative)."
},
"accent2": {
"type": "string",
"description": "Second accent, hex or colour name."
},
"accent3": {
"type": "string",
"description": "Third accent, hex or colour name."
},
"density": {
"enum": [
"airy",
"regular",
"compact"
],
"type": "string"
},
"surface": {
"enum": [
"flat",
"glass",
"shadow",
"outline"
],
"type": "string"
},
"texture": {
"enum": [
"none",
"grain",
"dots",
"grid",
"paper"
],
"type": "string"
},
"contrast": {
"enum": [
"soft",
"normal",
"high"
],
"type": "string"
},
"japanese": {
"type": "boolean",
"description": "Japanese text allowed, with Japanese faces in the stacks."
},
"textFont": {
"type": "string",
"description": "Body face, same choices as displayFont."
},
"tracking": {
"type": "number",
"maximum": 0.24,
"minimum": -0.08,
"description": "Heading letter spacing in em."
},
"saturation": {
"type": "number",
"maximum": 3,
"minimum": -3,
"description": "Steps more vivid or more muted, for colours the designer picks."
},
"displayFont": {
"type": "string",
"description": "Heading face: a kind (serif, sans, mono, rounded, slab, condensed, geometric, grotesk, humanist, didone, mincho) or a face name such as \"Didot\" or \"Futura\". Fallbacks are added."
},
"motionSpeed": {
"type": "number",
"maximum": 3,
"minimum": 0.25,
"description": "Multiplier on the world's pace: 0.75 is slower, 1.3 faster."
},
"followSystem": {
"type": "boolean",
"description": "Follow the visitor's system light or dark setting instead of the default theme."
},
"displayWeight": {
"type": "number",
"maximum": 900,
"minimum": 200
},
"motionIntensity": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "0 is nearly still, 1 is the most movement."
},
"textureStrength": {
"type": "number",
"maximum": 1,
"minimum": 0
}
},
"description": "Explicit settings that override the world. Every one can also be said in plain words through \"tweak\".",
"additionalProperties": false
},
"theme": {
"enum": [
"dark",
"light"
],
"type": "string",
"description": "The default theme. Leave out to let the world decide; both themes are always made."
},
"tweak": {
"type": "string",
"description": "Changes in plain words to apply before saving, as in adjust_direction."
},
"world": {
"enum": [
"calm",
"bold",
"playful",
"luxury",
"technical",
"editorial",
"warm",
"sakura",
"brutalist",
"retro",
"noir",
"organic",
"corporate",
"cyber"
],
"type": "string",
"description": "Force a world instead of letting the brief choose."
},
"colors": {
"type": "array",
"items": {
"type": "string"
},
"description": "Brand colours as hex or names, most important first. Kept exact. Leave out to let the designer choose."
},
"option": {
"enum": [
1,
2,
3
],
"type": "number",
"description": "Which of the three design_options for this same brief."
},
"subline": {
"type": "string",
"description": "One supporting sentence."
},
"audience": {
"type": "string",
"description": "Who it is for."
},
"headline": {
"type": "string",
"description": "The main headline."
}
}
}| audience |
| string |
| Who it is for. |
| headline | string | The main headline. |
| direction_id* | string | The direction_id from create_direction. |
{
"type": "object",
"required": [
"direction_id"
],
"properties": {
"app": {
"type": "string",
"description": "What the app is and does, in a sentence or two."
},
"cta": {
"type": "string",
"description": "The call to action label."
},
"mood": {
"type": "string",
"description": "How it should feel, in the user's words: \"calm and premium\", \"loud and sporty\", \"playful\", \"editorial\"..."
},
"avoid": {
"type": "string",
"description": "Things the user does not want, for example \"playful\"."
},
"brand": {
"type": "string",
"description": "Brand or product name."
},
"theme": {
"enum": [
"dark",
"light"
],
"type": "string",
"description": "Force a dark or light theme. Leave out to let the mood decide."
},
"tweak": {
"type": "string",
"description": "The change in plain words."
},
"colors": {
"type": "array",
"items": {
"type": "string"
},
"description": "Brand colours as hex (\"#ff5a1f\") or names (\"teal\"), most important first. Leave out to let the designer choose."
},
"subline": {
"type": "string",
"description": "One supporting sentence."
},
"audience": {
"type": "string",
"description": "Who it is for."
},
"headline": {
"type": "string",
"description": "The main headline."
},
"direction_id": {
"type": "string",
"description": "The direction_id from create_direction."
}
}
}