Style variations

Select one element and choose Variations in its actions. Your agent answers with several looks for that element. You pick the one you want.

Asking for variations

The box asks two things: how many variants to make, 2 to 10, and an optional comment, such as “thinner and darker”. Press Send to agent.

The box then becomes the waiting card. It says Waiting for your agent, names the keyword vartest, and says to say what you want in the same message. An X puts the card away.

In your agent, type vartest and say what you want in the same message. The agent follows your own words as well as the comment. If your agent has no Edityy server yet, add one with npx edityy mcp and ask again.

Answering

Your agent has one job, in two tool calls.

  • get_variation_request returns the number of variations, the comment, the element’s tag, its selector and a few current values. Read it at the start of every vartest: you may have asked again since the last one, and an answer for an old request is refused.
  • place_variations takes the answer. It takes that many variations, each a short label and a list of declarations.

Fewer variations than you asked for is refused, and the message says so. More is not a refusal: the first ones are the ones you see.

thin grey | scrollbar-width: thin; scrollbar-color: #8a8a8a transparent
rose pill | scrollbar-color: #f43f5e #f4f4f5
notched | on: ::-webkit-scrollbar-thumb, background: #f43f5e
narrow | when: (max-width: 640px), padding: 8px

A variation may also change the element’s words. Add text beside the declarations, and the words are set with it.

{ "label": "shorter", "props": [], "text": "Start free" }

Picking one

A strip at the bottom right shows the variations. It names the element it varies, and Keep is grey until one of them is on the element. Keys 1 to 9 pick one, and 0 picks the tenth. Keep puts the strip away.

What is left on the element is an ordinary edit. Save to project and get_visual_changes carry it like any other. Escape or leaving the mode reverts it.

States, pseudo-elements and breakpoints

A declaration that carries on is a state or a pseudo-element of the element itself.

:hover
:focus-visible
::before
::-webkit-scrollbar-thumb

A declaration that carries when is a breakpoint.

(max-width: 640px)

The browser cannot show either in the element’s own inline style, so Edityy writes them into a small stylesheet it adds to the page for that element. It takes the sheet away when the edit is reverted or the mode ends.

They travel with the edit. Save to project and the copied Markdown name the state or the breakpoint beside the property, and your agent writes the rule in your own stylesheet.

A pseudo-element needs content

A ::before or ::after needs a content value to show at all.

Under the hood

The endpoint is POST, GET and DELETE /__edityy/variations. A request and its answer are written to .edityy/variation-request.json and .edityy/variation-response.json, which the MCP server reads.

The page sends only plain values, and an answer is checked before the page shows it. A custom property, an at-rule in place of when, !important or url() is refused.

The X in the waiting card takes the request back. The request stays in the file, marked as taken back, and the agent is told not to answer it. A withdrawal is not the same as a request that was never made. A new request replaces it.

Next.js

Next.js needs one more route file and one more rewrite, next to the one for the edits.

app/edityy/variations/route.ts

import { variationsRoute } from "edityy";

export const { GET, POST, DELETE } = variationsRoute();

next.config.ts

async rewrites() {
  return [{ source: "/__edityy/variations", destination: "/edityy/variations" }];
}