Style your site visually in the studio

Embed
Preview of the card
<a href="https://forumulate.com/guides/visual-editing"><img src="https://forumulate.com/guides/_api/public/orgs/046a9bc0-d530-43ae-9bae-af7945008cda/spaces/36aa4df0-1e95-4cef-8ae9-795169441345/pages/2d79d6d5-bb18-4355-8e36-129e0a555e3c/social-card.svg?v=3e7ae33eec8b" alt="Style your site visually in the studio" width="600" height="315"></a>

The studio is your live site with the console around it. Style mode turns that page into a design surface: click anything — the header, a nav item, the call-to-action, a footer column, a heading, a card, a section, any block — and the panel beside it becomes a style editor for exactly that thing. Every change shows on the page at once and is saved to your theme draft, so readers see none of it until you publish.

This page covers the editor. The keys it writes are the ones in Theme your site and Advanced theming, and the draft is the one described in Draft a theme, and preview it.

Pick something

  • Press Style in the studio's top bar, then click anything on the page. While Style mode is on, a click selects instead of following a link.

  • Outside Style mode, Alt+click (Option+click on a Mac) selects too — handy while you are editing words in place.

  • Hovering shows what a click would select, outlined and named.

  • The breadcrumb under the name lists what the selection sits inside — for example header › cta. Click a parent to style that instead.

A click is resolved to the most specific stable thing it can name: one of the published data-fx-* hooks (the header, the logo, a nav item, the CTA, the footer…), a block of your page (by its own hook or anchor), a published component (.btn, .input, .card), or an element role inside one of those — a heading, a link, a paragraph. It never writes a selector against our internal utility classes, which is what keeps your styling working when our markup changes.

With the keyboard

With Style mode on and the page focused:

Key

Does

Tab / Shift+Tab

Walk the selectable things on the page, in order.

Enter

Select the one under the ring.

Esc

Let go of the selection.

Cmd/Ctrl+Z

Undo the last change; add Shift to redo.

Choose what the change applies to

The panel asks rather than guesses. Under Applies to you pick one, and the line beneath says where it will be stored:

Choice

Changes

Stored in

This … (this button, this heading)

just the thing you clicked

an elementStyles rule on its hook, anchor or link address

This block

one block of your page

a rule on the block's own hook — a block without one is given a hook name the first time you style it

This section

one section block

the section's own look (background, padding, radius, border, shadow) in the page draft; anything else, a rule

Every link in the header

that kind of element, inside that part

an elementStyles rule

All buttons / All H2 headings

every one on the site

the theme's component or type setting when one holds the value (components.button, typography.levels.h2); a rule on the published class otherwise

Only on this page

the broad choice, on this page or post only

an elementStyles rule with page set

"All buttons" writes the same setting the Design fold shows, so the two never disagree about what a button looks like.

Edit the style

The controls are grouped the way you would reach for them:

  • Typography — font (your heading, body and code fonts first, then your uploaded faces), size, weight, line height, letter spacing, case, style, alignment, decoration and colour.

  • Spacing — margin and padding, all sides or each side, and gap.

  • Background — colour, a two-colour gradient with an angle, or an image (upload one, or paste a url(…)), with size, position and repeat.

  • Border — width, style, colour, and radius for all corners or each corner.

  • Shadow and effects — a shadow preset or your own, opacity, scale and rotation, and a transition for hover states.

  • Size and picture — height, min and max height, aspect ratio, and how a picture fills its box (fit and focus).

  • Underline — line, style, colour, thickness and offset.

  • Position and layering — relative, sticky, or absolute inside a block; offsets; a layer from 0 to 10; isolation, blend mode and a backdrop filter; and grid placement (area, column, row, order, self-alignment) for overlaps. absolute is offered only when what you picked sits inside a named block — choose an element inside the block, not the block itself — and fixed is never offered: see Size, pictures, underlines and layering for why.

A value the site would refuse is outlined in place and not applied — hover it for the reason — and the editor never saves something the theme rejects.

The element inspector (select an element outside Style mode) has the short version of the same controls: ratio, picture fit, height, underline colour and offset, position, layer and a pull-up margin.

A block's own look

Some looks belong to the block rather than to a rule: a heading's alignment or eyebrow style, a list's marker, when a row of columns stacks, a column hidden on a phone, and a grid cell's card shell (shadow and radius). Set them in the editor — the # beside a block's drag handle, or a grid cell's style popover — and see A block's own look.

Phone, tablet, hover, dark mode

Three rows of tabs choose the variant you are editing:

  • Device — Desktop, Tablet (up to 1024px) or Phone (up to 640px, the same width as the theme's mobile layer). Choosing one also resizes the preview.

  • State — Normal, Hover, Focus (keyboard focus) or Pressed. While a state tab is open the selected element shows that state's look, so you can see it without holding the pointer over it.

  • Colour mode — Both, Light or Dark. Choosing Light or Dark switches the preview to that mode.

Each variant is saved as its own rule, so a phone font size never changes the desktop one. Component and section settings have no variants: a phone or hover edit of "All buttons" is a rule, and the base button setting stays as it is.

Contrast

Whenever the selection has text, the panel measures its colour against what is actually behind it on the page — including a translucent fill over a section — and shows the WCAG ratio. Below AA (4.5:1, or 3:1 for large text) it warns you. Over a background image or gradient there is no single colour to measure, so it says nothing rather than guess.

Undo, reset and the CSS

  • Undo / Redo walk the studio's one history, which also holds block moves, deletions and renames. A colour drag or a typed size is one step, not one per keystroke.

  • Reset to inherited removes what this choice and this variant set, so the element falls back to whatever it inherits.

  • Show CSS prints exactly what your edit compiles to, from the same compiler the site uses, plus the theme settings it wrote.

Publish

Every change goes to the theme draft as you make it. The foot of the panel says whether a draft is waiting:

  • Publish makes it live. If you styled a section's look or named a block, those page drafts are published first, so a rule never points at something the live page does not have yet.

  • If somebody changed the live theme after your draft started, publishing would undo their change; the panel says so and offers Publish anyway.

  • Discard draft throws the theme draft away. The live site is untouched.

The draft is the same one the Design fold edits and the preview links show, so you can still open it on your own domain before publishing.

In the API

Every operation below is also reachable from the other surfaces without a dedicated command. forumulate api <Operation> calls it from the CLI, the JavaScript SDK has a typed method for each one (the last column names it; the Python and Go clients are generated from the same spec), and an agent reaches the organization-scoped ones through the MCP call_api tool. Where a CLI command or MCP tool exists too, the last column names it. Operation names link to the API reference.

Collab

Operation

Request

What it does

Shortcuts

Collab_token

POST /orgs/{orgId}/spaces/{spaceId}/pages/{pageId}/collab-token

Create the collab token in a space

client.pages.collab.token()

Collab_state

GET /orgs/{orgId}/spaces/{spaceId}/pages/{pageId}/collab-state

Get the collab state in a space

client.pages.collab.state()

Comment Moderation

Operation

Request

What it does

Shortcuts

CommentModeration_list

GET /orgs/{orgId}/spaces/{spaceId}/pages/{pageId}/comments

List comments in a space (pages)

client.comments.list()

CommentModeration_moderate

PATCH /orgs/{orgId}/spaces/{spaceId}/comments/{commentId}

Update the comment

client.comments.moderate()

CommentModeration_remove

DELETE /orgs/{orgId}/spaces/{spaceId}/comments/{commentId}

Delete the comment

client.comments.remove()

CommentModeration_resolve

PATCH /orgs/{orgId}/spaces/{spaceId}/comments/{commentId}/resolve

Resolve the comment

client.comments.resolve()

CommentModeration_applySuggestion

POST /orgs/{orgId}/spaces/{spaceId}/comments/{commentId}/apply-suggestion

Apply suggestion in a space

client.comments.applySuggestion()

Docs Render

Operation

Request

What it does

Shortcuts

DocsRender_render

POST /orgs/{orgId}/spaces/{spaceId}/docs/render

Render Markdown as a reader page body (nothing is saved)

client.docsRender.render()

Markdown Dialect

Operation

Request

What it does

Shortcuts

MarkdownDialect_get

GET /docs/markdown-dialect

Get the markdown dialect

client.meta.markdownDialect.get()

Page Access

Operation

Request

What it does

Shortcuts

PageAccess_get

GET /orgs/{orgId}/spaces/{spaceId}/pages/{pageId}/access

Get the access in a space (pages)

client.pages.access.get()

PageAccess_set

PUT /orgs/{orgId}/spaces/{spaceId}/pages/{pageId}/access

Replace the access in a space (pages)

client.pages.access.set()

Public Growth

Operation

Request

What it does

Shortcuts

PublicGrowth_goal

POST /public/orgs/{orgId}/spaces/{spaceId}/pages/{pageId}/goal

Create the goal in a space

client.analytics.publicGrowth.goal()

PublicGrowth_exposure

POST /public/orgs/{orgId}/spaces/{spaceId}/pages/{pageId}/exposure

Create the exposure in a space

client.analytics.publicGrowth.exposure()

Publish All

Operation

Request

What it does

Shortcuts

PublishAll_publishAll

POST /orgs/{orgId}/spaces/{spaceId}/publish-all

Publish all in a space

client.pages.publishAll.publishAll()

Operation

Request

What it does

Shortcuts

ShareLink_list

GET /orgs/{orgId}/spaces/{spaceId}/share-links

List share links in a space

client.spaces.shareLinks.list()

ShareLink_create

POST /orgs/{orgId}/spaces/{spaceId}/share-links

Create a share link in a space

client.spaces.shareLinks.create()

ShareLink_preview

POST /orgs/{orgId}/spaces/{spaceId}/share-links/preview

Preview the share link

client.spaces.shareLinks.preview()

ShareLink_revoke

DELETE /orgs/{orgId}/spaces/{spaceId}/share-links/{id}

Delete the share link

client.spaces.shareLinks.revoke()

The Forumulate teamUpdated