# OpenVibe.Design > Make it yours, find the best AI designer. **Live site:** https://openvibe.design · **API docs:** https://openvibe.services · **For AI:** https://openvibe.design/llms.txt **Run it:** `npm ci && npm run dev` (Node 22 or newer) · **Tests:** `npm test` **Status:** v2, the theme studio and the Design Arena (v0.1.0, see [STATUS.json](STATUS.json)). **Domain:** `openvibe.design` · **Port:** 5090 · **Service id:** `design` · **Env prefix:** `DESIGN` **License:** AGPL-3.0-only (the same as every OpenVibe service). OpenVibe.Design is the Design room: the theme studio where a person browses OpenVibe's themes, tries them on previews, edits one with contrast checks, uses it, submits it to the gallery, and rolls back to any earlier setting, and the Design Arena where one prompt goes to three AI models, two outputs are judged blind at phone and desktop sizes, and an Elo leaderboard per category ranks the designers with the cost and time of every generation. Theme selection stays in OpenVibe.Network; this service signs the person in and proxies their calls to the Network's theme API. ## What it is - **Identity:** service id `design`, name OpenVibe.Design, port 5090, host 127.0.0.1. It stores no accounts and no tokens: the person's Network session lives in httpOnly cookies and their theme lives in OpenVibe.Network. The Arena rounds, entries, judgements and ratings live in OpenVibe.Bench. The legacy `arena_*` tables remain for historical account events and migration. - **Sign-in:** an OAuth 2 client of OpenVibe.Network (`design`), authorization code with PKCE S256, a state check and a server-side code exchange. - **The theme API proxy:** every theme read and write goes to OpenVibe.Network's `/api/themes`, with the person's access token from the `design_at` cookie as a Bearer. The proxy never logs, renders or echoes the token. ## The studio - **Gallery:** every theme in the catalogue, filtered by dark or light; picking one paints the previews. - **Previews:** the theme is tried on three sites at once: a Live channel, a Chat room and a shop's grid. They read only theme tokens, so they look exactly as the sites will. *See it as* repaints them as people with protanopia, deuteranopia or tritanopia see them (SVG colour matrices). - **Editor:** six colours (background, surface, text, muted text, accent, lines); [public/js/studio.js](public/js/studio.js) derives the full token set from them, the same tokens Network's validator accepts. - **Checks:** WCAG contrast for text on the background and on cards, muted text, button text and links. Every required check must pass before *Use this theme* is enabled; *Lines against cards* is advisory. - **Use, share, roll back:** *Use* is `PUT /api/me/theme` (source `studio`), *Share it in the gallery* submits the theme for review, and *History* lists the person's earlier looks with a one-tap *Restore*. ## Design Studio v1 `/create` takes one prompt and shows three model variants on `/d/:id`. The variants use the Arena's OpenVibe.AI route pins and HTML sanitizer. The canvas supports phone, tablet and desktop widths, and changing the token theme repaints all frames. A signed-in design belongs to its Network subject. A guest receives a secret link, kept among the last three drafts in a private cookie. Guests can create two designs per day per IP; signed-in people can create ten. Generation progress is polled, and completed frames appear individually. First-party services can request a missing glyph with `POST /api/v1/glyphs/drafts` and a service token for audience `openvibe.design` carrying `design.glyph.draft`. Send `{ "name": "daily-2026-11-09", "sentence": "What this icon should mean" }`. The response names pending draft IDs; repeated requests return the same IDs without drawing again. Reference icons for a draft come from OpenVibe.Exchange (`POST /v1/search/icons`, the Exchange platform API served by OpenVibe.AI) with Design's own Network client-credentials token (`exchange.search.icons`), so no key is needed; `EXCHANGE_SEARCH_KEY` is the owner's override. Without either, or when Exchange fails, Design reads Iconify, applies the same licence filter and sends only names and concepts to the model. Candidates use the cheapest AI preset and wait in the existing `/icons` staff review queue. Only approved drafts appear in `GET /api/v1/glyphs/drafts?status=approved`; a requesting site keeps a bundled glyph until then. Pick one frame with **Use this design**: it becomes the working frame, its HTML becomes version 1 and the pick is recorded as one Arena vote through OpenVibe.Bench (a signed-in person votes once; a guest's pick is saved without a vote). Edit it by chat (`POST /api/v1/designs/:id/edit`) or by clicking an element: the iframe reports `body > …:nth-of-type(n)`, and the floating panel changes its text, theme-token colour, padding or alignment. The server validates the path, tag and values, escapes the text, rebuilds only the inline style and saves a new version; the overlay script is injected at render time and is never stored with the model HTML. Versions are append-only in `design_versions`; undo/redo move the pointer (`design_picks.current_seq`), and an edit after undo appends a new version instead of deleting the old ones. Chat edits cost AI money, so each design has a small AI-edit budget (`DESIGN_CHAT_EDITS_PER_DESIGN`, default 5); a failed attempt spends budget but never replaces the last good version. The API is under `/api/v1/designs`; `/developers` lists the routes. `migrations/0002_design_studio.sql` stores each design and its JSON variants in one row, and `0003_design_working_versions.sql` adds the pick, its Bench vote fields, the AI-edit counter and the version table, using the service's existing PostgreSQL or development PGlite setup. Production needs the existing `DATABASE_URL` and `DATABASE_DIRECT_URL` roles and working OpenVibe.AI and OpenVibe.Bench service credentials (the Bench scope now includes `bench.entry.create` so Design can submit the generated variants to the pick-vote round). Checks, HTML/zip export, preview publishing and MCP remain part C. ## The Design Arena - **A round:** a signed-in person writes one prompt in one of six categories. Design creates a public Bench task of kind `design.page`, or `design.component` for logo, then creates a round. Bench queues and generates three entries through OpenVibe.AI, including their HTML, provider, model, cost, time and tokens. - **Budgets:** Bench enforces its per-person and site daily round limits. - **Safety:** the model's page is text until it is rendered, and then only inside `