211 Commits
Author SHA1 Message Date
Oleg Isonen ab5717c9cf feat: Support CSS properties of every status (#6166)
## Summary

- Make every CSS property in the current MDN dataset available in the
Advanced style workflow, regardless of standards status.
- Mark experimental, nonstandard, and obsolete properties with a yellow
warning icon, status-specific tooltip, and MDN link.
- Add complete CSS anchor-positioning property and value support.
- Update `mdn-data` from 2.28.0 to 2.33.0 and `css-tree` from 3.1.0 to
3.2.1.

## Root cause

Webstudio generated its supported property list from MDN data but
filtered by status and then manually allowed a few experimental and
nonstandard entries. A property could therefore exist in the installed
MDN package without being exposed by the Builder.

Runtime validation had a separate grammar gap. CSS-tree 3.2.1 now
includes the anchor functions and alignment values, but its bundled data
predates the current `position-anchor: normal | match-parent` additions.

## Implementation

- Remove status-based property filtering and the nonstandard-property
allowlist.
- Generate one property-to-status map for 486 standard, 40 experimental,
119 nonstandard, and 15 obsolete properties.
- Show status-specific browser-compatibility guidance for every
non-standard status. Active declarations keep the warning after the
value with 3px left spacing.
- Infer MDN links from existing property metadata and fall back to MDN
search for entries without a direct URL.
- Preserve known vendor prefixes from the generated property inventory
instead of maintaining a prefix allowlist.
- Generate WebKit text fill/stroke longhands directly from MDN instead
of preserving them through parser exceptions.
- Preserve unsupported initial-value shapes as unparsed CSS rather than
excluding their properties.
- Use CSS-tree 3.2.1's native anchor-function and alignment grammars.
Keep one narrow extension for the current `position-anchor` keywords
missing from its bundled MDN data.
- Generate recursively flattened shorthand longhands and initial values
from MDN.
- Expand syntax-defined shorthands generically from CSS-tree's matched
property captures, including function-valued components.
- Decline generic expansion when CSS-tree and MDN disagree about the
longhand set or a longhand repeats.
- Update the font grammar reference and CSS math validation for CSS-tree
3.2.1 compatibility.
- Regenerate CSS metadata and property-variable fixtures.

## Checklist

- [x] Include MDN properties regardless of status.
- [x] Generate status metadata for standard, experimental, nonstandard,
and obsolete properties.
- [x] Show warning icons in Add styles results and active declarations.
- [x] Add status-specific consequences and MDN links.
- [x] Preserve generated vendor-prefixed properties during CSS import.
- [x] Generate WebKit text fill/stroke longhands without parser
exceptions.
- [x] Support `anchor()`, `anchor-size()`, and `anchor-center`.
- [x] Support current `position-anchor` keywords.
- [x] Expand syntax-compatible shorthands through generic MDN metadata
and CSS-tree captures.
- [x] Cover ordered optional, unordered, slash-separated,
function-valued, omitted, CSS-wide, variable, invalid, and
incompatible-data cases.
- [x] Verify new status, warning, prefix, and shorthand tests fail
without their implementations and pass when restored.
- [x] Update to CSS-tree 3.2.1.
- [x] Regenerate CSS metadata and property-variable fixtures.
- [x] Review documentation impact; no authoritative Builder
documentation lists individual supported CSS properties, so no update is
needed.
- [x] Review fixture impact; 668 fixtures and 2,030 valid cases were
regenerated with zero unsupported.

## Verification

- `pnpm --filter @webstudio-is/css-data test` — 4,618 passed, 1 skipped.
- Builder CSS editor and property-status tests — 25 passed.
- CSS data, CSS engine, Project Build, and Builder typechecks passed.
- Lint, formatting, repeated regeneration, and diff checks passed.

## Known limitation

This change covers CSS declarations and values. It does not add a
dedicated Builder editor for the `@position-try` at-rule.

Closes #6162
2026-08-17 14:54:11 +02:00
Oleg Isonen 87968f40ff fix: Improve MCP authoring and preview reliability (#6105)
## Summary

Fix MCP reliability failures reported in ten issues against CLI 0.288.0
and 0.289.0:

- keep every advertised array input schema client-valid, including
compact and tuple schemas
- report a text asset update as successful when its persisted revision
and bytes confirm that the server committed despite a failed response
- preserve standard package import resolution in generated React Router
previews
- upload variable WOFF2 fonts when callers provide the documented static
font metadata shape
- explain unmatched JSX as a stateless fragment syntax error
- distinguish the `animation` component namespace from value helpers and
reject unsupported CSS at-rules with an actionable validation error
- forward optional session tools such as `download-asset` through
top-level CLI shortcuts
- isolate published generated-preview dependencies from parent
workspaces
- return structured screenshot failures when React Router production
builds fail

Sensitive visual regression checks also run automatically for
organization-authored fork PRs. External fork PRs remain gated by
`safe-to-deploy`.

## Root causes and implementation

The MCP handshake compactor retained an array's type but discarded its
`items` schema. Unconstrained and tuple arrays could also be advertised
without `items`. Schema normalization now adds `items: {}` whenever an
array omits it, while focused discovery retains complete constraints.
Catalog coverage rejects every missing array item, including tuple
schemas, and the handshake remains below its 200 KB budget.

Asset content updates previously treated any failed response as a failed
mutation, even when the server had already swapped the revision.
Recovery now reads the current revision, compares the persisted bytes,
and confirms the revision remains stable across the read. It returns the
updated asset only when all evidence agrees. Otherwise it returns
`ASSET_UPDATE_COMMIT_UNCERTAIN` with guidance not to retry blindly.
Definitive 4xx responses retain their original errors.

The generated React Router Vite config replaced the client and SSR
resolver condition lists without explicitly retaining the standard
`import` condition. Both lists now preserve `import`. The regression
test generates a dynamic route, stages the built React Router SDK as a
published dependency without the local `webstudio` source condition, and
runs the generated build.

Variable fonts are detected with `variationAxes`. Merging the documented
static `style` and `weight` upload metadata into that detected variable
shape made validation fail after the binary was read. Font override
validation and shape-aware merging now live in `@webstudio-is/fonts`.
The SDK delegates to that domain function, which validates the complete
override before applying compatible fields, retains the detected
static-or-variable shape, and keeps the detected format.

Fragment parsing is stateless. Unmatched opening and closing tags now
explain that every opening element must use the same closing tag or be
self-closing, and that refreshing the session cannot repair malformed
JSX.

The `animation` binding is a component namespace, not a callable helper.
Tool schema text, evaluation errors, and the MCP manual now separate
component namespaces from value helpers. The MCP JSX `css` binding
parses the final interpolated CSS with CSS-tree and recursively rejects
selectors and unsupported at-rules such as `@keyframes`, while
preserving supported declarations and case-insensitive `@media` rules.
Keeping this validation at the external binding avoids changing internal
component templates.

CLI shortcut discovery previously omitted optional session tools even
though the runtime registered their handlers. Shortcut discovery now
includes the same optional tool categories as the CLI MCP host, while
real top-level CLI commands keep precedence.

Published generated previews could reuse a stale `node_modules` symlink
into a parent source workspace. Only development manifests containing
the local placeholder version may now reuse the CLI dependency tree.
Published manifests replace symlinks with a local install and disable
npm workspace discovery.

React Router could report a bundler failure while its build command
exited successfully outside CI, allowing screenshot startup to terminate
without a structured result. Managed production builds now set `CI=1`,
so the existing MCP error boundary receives the nonzero build failure
and prints structured JSON.

Visual regression authorization now distinguishes repository members
from external contributors. Organization members' fork PRs run on open,
synchronize, and reopen events; external fork code runs only from a
`safe-to-deploy` label event, and a later commit does not reuse that
approval.

## Implementation checklist

- [x] Preserve valid array item schemas in compact MCP discovery
- [x] Normalize tuple input schemas with an `items` fallback
- [x] Keep the MCP handshake below its 200 KB size budget
- [x] Cover the real `update-props` schema and oversized array
compaction
- [x] Reconcile failed asset-update responses against stable persisted
content
- [x] Reject recovery when a concurrent asset revision is detected
- [x] Preserve `import` resolution in generated React Router client and
SSR builds
- [x] Build a generated dynamic route against a staged published SDK
package
- [x] Regenerate and verify affected React Router fixtures
- [x] Preserve detected variable-font axes with documented upload
metadata
- [x] Add actionable unmatched-tag and unsupported-CSS validation
- [x] Correct animation namespace guidance in tool discovery and errors
- [x] Forward optional session tools through top-level CLI shortcuts
- [x] Replace parent-workspace dependency links for published previews
- [x] Disable npm workspace discovery for isolated preview installs
- [x] Make React Router build failures return nonzero in managed
previews
- [x] Run visual regression automatically for organization-authored PRs
- [x] Verify each regression test fails without its corresponding fix
- [x] Review documentation impact and update the authoritative MCP
manual plus generated outputs
- [x] Confirm no database migration or compatibility migration is
required
- [ ] Run `pnpm evaluations` after explicit approval; not run because
repository policy requires approval before agent evaluations

## Verification

- `packages/cli/src/prebuild.test.ts`: 57 tests passed
- `packages/cli/src/commands/schema.test.ts` and `mcp.test.ts`: 51 tests
passed
- `packages/project-build/src/runtime/components.test.ts` and
`mcp.test.ts`: 194 tests passed
- `packages/asset-uploader`: 196 tests passed
- focused font schema, SDK asset schema, CSS parser, and template CSS
tests passed
- `packages/http-client/src/index.test.ts`: 38 tests passed
- relevant CLI, project-build, asset-uploader, fonts, SDK, CSS data,
template, HTTP client, and React Router SDK typechecks passed
- MCP documentation tests, typecheck, generation, and Markdown source
tests passed
- React Router SDK package build passed
- full fixture link, sync, and generation pipeline passed
- affected Docker and Vercel fixture typechecks and locally bootstrapped
production builds passed
- complete CLI suite: 61 test files and 966 tests passed
- CLI typecheck passed
- preserved nested-workspace dynamic preview installed local `0.289.0`
dependencies and completed its production build
- visual-regression workflow YAML parsing and authorization truth table
passed
- repository lint passed with warnings denied
- formatting and `git diff --check` passed

## Tradeoffs and limitations

Deferred array schemas advertise unconstrained `items` in the compact
handshake to remain client-valid without duplicating detailed
constraints. Agents can retrieve the complete item schema through
focused `meta.get-more-tools` discovery.

Asset reconciliation performs three read requests only after an
uncertain 5xx, malformed response, or transport failure. This keeps the
normal successful path unchanged and avoids claiming success if the
revision changes during recovery.

For variable fonts, detected axes define the metadata shape. Static
`style` and `weight` hints are ignored because they cannot be
represented alongside `variationAxes`; compatible fields such as
`family` still override detection.

Native CSS keyframe authoring remains unsupported in fragment `css`
templates. The tool now rejects it before rendering and directs callers
to editable Webstudio Animation components instead of advertising a
nonexistent callable helper.

Published previews perform one isolated npm install when no valid local
dependency tree is cached. Local source development keeps the fast
workspace symlink path for placeholder-version manifests.

Closes #6104
Closes #6099
Closes #6098
Closes #6106
Closes #6107
Closes #6108
Closes #6114
Closes #6115
Closes #6116
Closes #6117
2026-08-12 21:23:35 +02:00
Oleg Isonen 12ad74584a feat: Improve MCP authoring, auditing, and verification (#5886)
## Summary

This improves how coding agents discover, author, verify, and audit
Webstudio projects through the CLI and MCP. The work focuses on making
agents more reliable with less context, while keeping edits semantic and
Builder-editable.

## What changes for users

- Agents can verify dynamic bindings after authoring and receive
actionable diagnostics when expressions, resources, scopes, or component
props do not line up.
- Agents can create complete resource-backed runtime UI through a
semantic operation instead of coordinating fragile low-level edits.
- MCP discovery and command output are compact by default, with
pagination and focused verbose detail when an agent needs more context.
- Asset, style, token, font, page, and component inspection provides
stronger usage context so agents can preserve the existing design
system.
- Rendered audits provide better evidence for responsive behavior,
geometry, contrast, generated-build size, and large-project runs.
- Cross-project MCP workflows can run from a manifest with explicit
mutation approval, isolated failures, resumable progress, and persistent
checkpoints.
- Project-specific agent onboarding is clearer and does not add
telemetry.
- Packaged CLI releases gain stronger smoke verification for install,
MCP startup, authoring, preview, screenshots, and audits.

## Reliability and architecture

- Runtime operation output schemas are generated from the runtime
registry and remain client-compatible.
- Project-build exports are consolidated around architectural boundaries
instead of feature-by-feature convenience entry points.
- HTTP, preview, screenshot, and project-session paths are hardened for
longer autonomous workflows.
- Craft compatibility work is read-only and provenance-aware; it does
not silently opt ordinary projects into Craft behavior.
- A minimal-context evaluation harness exercises key workflows with a
weaker model and stores bounded, privacy-safe evidence.

## Validation

- Rebased on the latest `origin/main`.
- `pnpm lint`
- Repository-wide `oxfmt --check`
- CLI typecheck and full test suite: 773 tests passed.
- Project-build typecheck and full test suite: 1,866 tests passed.
- Protocol typecheck and full test suite: 83 tests passed.
- HTTP client tests: 23 passed.
- CSS data tests: 3,620 passed, 1 skipped.
- Focused Builder tests: 67 passed.
- Package-boundary, generated API, and generated documentation checks
passed.
- Minimal-context agent evaluations passed for authenticated
resource-backed UI and design-system-aware responsive authoring.
2026-07-16 17:53:16 +02:00
Oleg Isonen 82c3d83fd1 fix: optimize CLI import for large data amount (#5831)
## Summary

- Add CLI project import support from synced `.webstudio/data.json` into
another project via a destination share link.
- Move project bundle import/export contract into
`@webstudio-is/protocol`, including bundle versioning, staged upload
constants, schema validation, and fixture coverage.
- Upload project bundle data through staged TUS upload before calling
the import RPC to avoid request body limits.
- Upload referenced assets as binary files through the existing asset
upload route before importing asset rows.
- Add `--skip-assets` and `--ignore-version-check` import options.
- Add retry handling for transient missing imported asset files by
re-uploading only the reported missing assets.
- Share missing-asset import error formatting/parsing through protocol
to avoid duplicated string contracts.
- Preserve browser asset upload behavior while adding API upload
support.
- Normalize schema naming across the branch to lower-case names without
`Schema` suffix.
2026-06-23 18:50:01 +02:00
Oleg Isonen 95dc7f0a75 fix: Validate malformed CSS variable values (#5787)
**Summary**

Validates CSS custom property values as raw CSS token streams before
saving/parsing them.

This prevents malformed values like `#sd'` from being normalized into
`sd` or serialized into broken canvas CSS that invalidates the whole
generated rule.

**Changes**

- Added tokenizer-based validation for custom property values.
- Rejects malformed strings, URLs, comments, unmatched blocks, and
trailing backslashes.
- Preserves raw custom property declaration values before `css-tree` can
repair/normalize them.
- Prevents custom property value editing from coercing invalid input
through fallback parsing like `kebabCase()` or color recovery.
- Added regression tests for advanced panel input and CSS data parsing.

**Verification**

- `pnpm --filter @webstudio-is/css-data test -- parse-css-value.test.ts
parse-css.test.ts`
- `pnpm --filter @webstudio-is/builder test --
parse-intermediate-or-invalid-value.test.ts parse-style-input.test.ts`
2026-06-01 17:03:54 +02:00
Oleg Isonen 5ed7588877 feat: Add tooltip when transforms are unavailable (#5778)
Closes https://github.com/webstudio-is/webstudio/issues/5336
Adds a tooltip to the Transforms section `+` button when transforms are
unavailable for the selected element.

The Transforms section now stays visible but inactive for unsupported
elements, and the tooltip explains that transforms do not work with
`display: inline` and suggests changing display to `inline-block` or
`block`.

Also adds shared CSS data helpers for HTML replaced elements so the
transform availability check can distinguish regular inline elements
from replaced inline elements like `img`.
2026-05-26 23:40:52 +02:00
Oleg Isonen 976ffd33f4 fix: Fix pasted CSS math values (#5759)
## Summary

- Preserve browser-valid CSS math values during CSS value parsing when
`css-tree` can parse the value but cannot fully validate the property
syntax.
- Fix pasted HTML/imported inline styles like nested `clamp()` +
`calc()` font sizes being marked invalid.
- Keep malformed math values and numeric functions in non-numeric
properties invalid.
- Add regression coverage for CSS value parsing and HTML paste/import
behavior.

## Testing

- `pnpm --filter @webstudio-is/css-data test
src/parse-css-value.test.ts`
- `pnpm --filter @webstudio-is/builder test app/shared/html.test.tsx
app/shared/tailwind/tailwind.test.tsx`

## Notes

This prevents valid pasted CSS math expressions from becoming invalid
style values and crashing the builder on import.
2026-05-14 18:55:30 +02:00
Oleg Isonen b4941aaaf1 fix: Tailwind border color arbitrary var (#5717) 2026-04-23 17:18:29 +02:00
Oleg Isonen f052200d07 fix: preserve CSS variable and gradient references on paste (#5716)
Preserve var() references in pasted gradient shorthand
(css-data/parse-css.ts)
When expanding shorthand properties (e.g. background), unresolved var()
tokens were lost. Now they're recovered by probing each longhand with a
placeholder, mapping which longhands the var belongs to, and restoring
it.

Fix border-(--x) Tailwind v4 syntax not recognized (tailwind.ts)
borde
2026-04-23 13:22:33 +02:00
Oleg Isonen 89188bede8 fix: resolve transitive var() references in shorthand expansion (#5705)
## Description

1. What is this PR about (link the issue and add a short description)

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2026-04-18 13:19:08 +02:00
Oleg Isonen 198ae5d65a fix: Cross rule CSS var resolution (#5698)
## Description

Pasting this will now resolve correctly

```html
<style>
.my-parent {
    --clr-red: #f00;
    min-height: 75vh;
}

.my-child {
    background: var(--clr-red);
    min-height: 50%;
}
</style>

<div class="my-parent">
    <div class="my-child"></div>
</div>
```
2026-04-14 18:34:40 +02:00
Oleg Isonen 8de2fd47f6 fix: CSS shorthand properties not saved when value contains var() (#5688)
Shorthand properties like background: var(--color) were silently dropped
when pasting into the CSS editor because the shorthand expander can't
handle unresolved var() references.

Fix: CSS vars from the current element's computed styles are now
resolved before expanding shorthands. Inline and nested fallbacks
(var(--a, var(--b))) are supported. If a var still can't be resolved, a
toast error is shown instead of silently dropping the property.
2026-04-12 17:14:01 +02:00
Oleg Isonen 9e72cc23c0 feat: New color formats and color picker (#5661)
https://github.com/webstudio-is/webstudio/issues/3574
2026-03-27 01:53:57 +01:00
Oleg Isonen 44a5c5f265 feat: Parse color functions with CSS variable alpha channel (#5660)
ref
https://github.com/webstudio-is/webstudio/issues/3574#issuecomment-4116312483

 (e.g. Taillwind's rgb(r g b / var(--tw-opacity)))

- css-engine/schema: extend ColorValue.alpha to number | VarValue
- css-engine/to-value: serialize VarValue alpha using toValue()
- css-data/parse-css-value: add parseColorWithVarAlpha using css-tree
AST substitution (no fragile string replacement); inject fallback: 1
when var has no explicit CSS fallback
- style-object-model: resolve VarValue alpha in substituteVars so the
color picker receives a number when the custom property is defined
- color-control: use VarValue.fallback for the picker when alpha is
still unresolved, falling back to 1 only as a last resort
2026-03-24 14:48:18 +01:00
Oleg Isonen 1784d635c0 feat: Paste HTML with CSS with full selectors and regular syntax support (#5648)
## Description

1. What is this PR about (link the issue and add a short description)

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2026-03-20 19:56:36 +01:00
Oleg Isonen 04188dbbf4 feat: CSS Grid UI (#5614)
## Description

1. What is this PR about (link the issue and add a short description)

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2026-03-08 10:52:21 +01:00
Bogdan Chadkin 942b81b8ff refactor: upgrade colorjs.io to v0.6 and adopt functional API (#5617)
## Summary

Upgrades colorjs.io from v0.5.x to v0.6.x and adopts the new functional
API to fix TypeScript compatibility issues and reduce bundle size.

## Breaking Changes in v0.6

This release includes two major changes from colorjs.io that required
code updates:

1. `null` instead of `NaN` for "none" values — Coordinates now use
`number | null` instead of the custom `Number` instance that previously
used `"none"` strings. This eliminates runtime casting and improves
TypeScript DX.

2. Plain numbers instead of `Number` objects — Coordinates are now plain
number primitives rather than `Number` objects with parsing metadata,
improving performance and bundle size.

## Changes Made

- Upgraded colorjs.io to v0.6.x
- Adopted functional API (`/fn` entry point) for tree-shakeable imports
and reduced bundle size
- Updated coordinate handling to use `number | null` directly instead of
custom `Number` instances with `"none"` values
- Removed runtime casting previously required for TypeScript
compatibility
- Aligned with engramma and hdr-color-input — both already use the
functional style, enabling code deduplication

## Migration Notes

See [colorjs.io v0.6.0 release
notes](https://github.com/color-js/color.js/releases/tag/v0.6.0) for
full details on the breaking changes.
2026-02-16 12:26:56 +03:00
Oleg Isonenandzehjotkah d87142965c feat: Breakpoint simulator (#5608)
## Problem

When defining CSS variables with different values for condition-based
breakpoints (e.g., `prefers-color-scheme:dark` vs
`prefers-color-scheme:light`), designers had no way to preview these
variations without manually changing system preferences.

Example:
```css
:root {
  --primary-color: #000;
  --background: #fff;
}

@media (prefers-color-scheme: dark) {
  :root {
    --primary-color: #fff;
    --background: #000;
  }
}
```

Previously, testing dark mode required switching OS settings back and
forth.

## Solution

Implements runtime CSS media rule manipulation to simulate
condition-based breakpoints without changing system settings. When a
designer selects a condition-based breakpoint, the simulator dynamically
modifies CSS media rules:

- Matching rules (e.g., `prefers-color-scheme:dark` when dark is
selected) → replaced with `(min-width: 0px)` (always true)
- Non-matching rules → appended with `(max-width: 0px)` (always false)
- Original media queries are stored and restored when switching away

## Features

**Core Functionality:**
- Simulates media query conditions by replacing them with
always-true/false queries
- Supports all condition-based media features (`prefers-color-scheme`,
`prefers-reduced-motion`, etc.)
- Handles both spaced and non-spaced formats

**Performance:**
- Caches media rules by feature to avoid repeated DOM traversal
- Debounces rapid breakpoint changes (50ms)
- Uses WeakMap for automatic memory management

**Robustness:**
- Validates restoration success with warning logs
- Handles CORS-restricted stylesheets gracefully
- Proper cleanup on abort signal with cache clearing

## Technical Implementation

**Key Functions:**
- `parseCondition()` - Parses condition strings
- `getMediaRulesForFeature()` - Caches and retrieves relevant media
rules
- `applySimulation()` - Debounced application of media rule
modifications
- `restoreAllRules()` - Restores original media queries
- `subscribeBreakpointSimulator()` - Integrates with nano-states and
lifecycle

**Integration:**
- Subscribes to `$selectedBreakpoint` nano-state
- Runs in design mode only
- Cleanup via AbortSignal

## Testing Instructions

**Setup:**
1. Create CSS variables with condition-based values
2. Configure breakpoints with conditions (e.g.,
`prefers-color-scheme:light`, `prefers-color-scheme:dark`)

**Test Cases:**
- Select condition-based breakpoint → verify canvas reflects correct
theme without changing OS settings
- Rapidly switch between breakpoints → verify smooth transitions
- Switch to width-based breakpoint → verify original media queries are
restored
- Check console for errors (should only see warnings for legitimate
issues)

## Impact

Designers can now preview dark/light themes and other condition-based
styles instantly without changing system settings, significantly
improving the workflow for building modern, accessible interfaces.

---------

Co-authored-by: zehjotkah <111518041+zehjotkah@users.noreply.github.com>
2026-02-05 22:33:20 +01:00
Oleg Isonen c5431eb96e fix: preserve -webkit-text-stroke prefix in CSS parsing (#5584)
When entering -webkit-text-stroke in the advanced style section, it was
incorrectly converted to --text-stroke (CSS variable). This happened
because normalizeProperty() strips vendor prefixes from properties not
in the prefixedProperties allowlist, and then parse-style-input.ts sees
the unknown property 'text-stroke' and converts it to a CSS variable.

Changes:
- Add -webkit-text-stroke, -webkit-text-stroke-color, and
-webkit-text-stroke-width to prefixedProperties list
- Add test for -webkit-text-stroke preservation

## Description

1. What is this PR about (link the issue and add a short description)

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2026-01-26 14:19:49 +01:00
Oleg Isonenandzehjotkah 1f4c53419d feat: Pseudo elements (#5572)
This PR replaces the limited "States" dropdown in the Style Panel with a
flexible input field that supports any CSS selector, pseudo-class, or
pseudo-element. This allows for advanced styling capabilities such as
`:has()`, `:focus-visible`, and complex combinators.

## Key Changes

### Flexible Selector Input
- Replaced the fixed "States" category list with a free-form input
field.
- Supports **any** valid CSS selector (e.g., `:hover`, `::before`,
`:has(:checked)`).
- Validation logic ensures only valid selectors are accepted (triggered
on `Enter` key).

## How to Test
1. Select an element and open the Style Panel.
2. Click on the Local style source or a Token.
3. In the input field (bottom of menu), type a selector like `:hover` or
`:first-child` and press Enter.
4. Verify the selector is added and selected.

---------

Co-authored-by: zehjotkah <111518041+zehjotkah@users.noreply.github.com>
2026-01-19 17:28:47 +01:00
Oleg Isonen e9a3a1ac00 feat: Support any media query condition as a breakpoint (#5547)
## Description

- [x] add a list of conditions
- [x] allow other units for min/max

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2026-01-04 18:48:45 +01:00
Bogdan Chadkin f7d56b8bac fix: parse tailwind colors with css variables correctly (#5479) 2025-12-05 09:49:14 +01:00
Bogdan ChadkinandOleg Isonen 21bce61052 feat: support modern color spaces in color inputs (#5465)
Ref https://github.com/webstudio-is/webstudio/issues/3574

Here improved css value parser to parse and store any color space.
oklch(), hsl(), color() and others can be used in any color input. Color
picker converts to rgb on the fly and do not support any other color
space at the moment.

---------

Co-authored-by: Oleg Isonen <oleg008@gmail.com>
2025-12-01 02:34:46 +03:00
Bogdan Chadkin 7139a35c68 refactor: migrate to colorjs.io (#5463)
colord library we used does not support new color spaces like oklch.
colorjs.io is mature library and handles this stuff just well.
2025-11-26 01:23:24 +03:00
Bogdan Chadkin 8d14d1b5e3 refactor: generate modern color syntax (#5456)
Ref
https://github.com/webstudio-is/webstudio/issues/3574#issuecomment-3529164146

Here added ColorValue to styles schema.
toValue now generates modern syntax like rgb(0 0 0 / 0.5) for both color
and rgb values.
2025-11-23 23:26:37 +03:00
Bogdan Chadkin 02ca084a0c refactor: upgrade to csstree v3 (#5455)
The new version is aware of modern colors and other new css features.
2025-11-23 14:32:12 +03:00
Oleg Isonen dc508445ce feat: Gradients UI (#5449)
## Description

Closes https://github.com/webstudio-is/webstudio/issues/3448

## Todo

- [x] linear gradient
- [x] without stops linear-gradient(red,green)
- [x] delete stops
- [x] support variables
- [x] tweak design
- [x] conic
- [x] one-color
- [x] radial
2025-11-22 14:28:17 +01:00
Jaya Krishna NamburuandOleg Isonen 0484d9c26f experimental: add gradient controller to update color stops using ui (#4159)
## Description

The `GradientControl` helps in displaying the colour stops that are
available in the linear-gradient that users added.

There are two knows issues at the moment.
- The only limitation is. We can't swap the colours when a colour stop
crosses an existing colour stop. In some
tools, the colours are swapped resulting in the swiping of the gradient
too.
This is because of a limitation/bug on the radix side, they pre-sort the
slider stops. So, we can never know which crosses an existing stop and
changed it's value. https://github.com/radix-ui/primitives/issues/2247

## Steps for reproduction

- Passing a linear-gradient should show all the `color-stops` in the
gradient.
- The `color-hints` are displayed at the bottom of the gradient bar.
These can't be moved along, more info about it is in the code component.
Because, this basically changes the whole gradient just by moving.
- The `color-hints` are showed at the bottom of the gradient. Just to
notify users about the existence of the hints.
- Users should be able to move the color-stops along the slider track.
- The color-stops can be moved using the arrow keys from the keyboard.

<img width="299" alt="Screenshot 2024-09-25 at 10 32 47 AM"
src="https://github.com/user-attachments/assets/d65e6af5-bba9-490d-96ff-0e58b8fb93bc">
<img width="289" alt="Screenshot 2024-09-25 at 10 32 43 AM"
src="https://github.com/user-attachments/assets/a3ac83e1-d379-49dc-a5d8-42936960f761">
<img width="560" alt="Screenshot 2024-09-25 at 10 32 38 AM"
src="https://github.com/user-attachments/assets/fef11d9e-2d0c-4d71-8587-227f22551edb">


![color-change-gradients](https://github.com/user-attachments/assets/44f71bc5-1c52-4bf9-8458-c12bd355759f)


## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file

---------

Co-authored-by: Oleg Isonen <oleg008@gmail.com>
2025-11-14 00:29:42 +01:00
Bogdan Chadkin aff636940b chore: drop legacy AI prompts and logic (#5345)
All of this is very outdated and does not make a lot of sense to have in
our code base.
2025-08-03 10:21:10 +02:00
Bogdan Chadkin 4abb7cf3e2 feat: support svg properties in style panel (#5332)
Ref https://github.com/webstudio-is/webstudio/issues/5258

Newer mdn-data contains all stylable svg properties (they finally got
through some documentation and implementation process).

Tweaked all experimental stuff and ditched obsolete properties.

<img width="286" height="538" alt="image"
src="https://github.com/user-attachments/assets/1e579be0-0a12-4013-ab04-09d5e008aeed"
/>
2025-07-18 18:04:26 +02:00
Bogdan Chadkin 310ab3aa1d fix: support max-* breakpoints in tailwind (#5299)
Ref https://github.com/webstudio-is/webstudio/issues/2651

Tailwind has max-sm, max-lg etc endpoints which need to adapt to ours as
well
2025-06-27 16:32:41 +03:00
Bogdan Chadkin de61cffde6 experimental: paste tailwind (#5217)
Ref https://github.com/webstudio-is/webstudio/issues/2651

Added "Paste Html With Tailwind Classes" command.

For now only tailwind 3 is supported.
Also fixed a few issues with css parser.


<img width="547" alt="Screenshot 2025-05-18 at 00 38 01"
src="https://github.com/user-attachments/assets/470b63e0-9b17-4769-8a65-679b90d73a89"
/>
2025-05-23 13:19:04 +03:00
Oleg Isonen 7f50fbe85c fix: Rewrite overflow clip and hidden description (#5201)
## Description

 Rewrite overflow clip and hidden description and move it to css-data

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2025-05-11 17:16:53 +02:00
Bogdan Chadkin fb40632e99 refactor: upgrade uno (#4905)
The new version deprecated "uno" preset in favor of wind3 and wind4
presets to support both tailwind versions. We can switch to wind4 later.
2025-03-27 14:56:51 +07:00
Bogdan Chadkin ccba8d9581 feat: substitute variables in calc and box-shadow (#5049)
Ref https://github.com/webstudio-is/webstudio/issues/4939

Here improved style engine logic to substitute variables in unparsed
values which is essential in cases like box-shadow or calc with
variables.

<img width="334" alt="Screenshot 2025-03-26 at 02 03 03"
src="https://github.com/user-attachments/assets/7b002061-1e83-48d9-abad-70547d1cdfc0"
/>
<img width="554" alt="Screenshot 2025-03-26 at 01 59 40"
src="https://github.com/user-attachments/assets/85597b72-cc74-4be9-9c32-ddc1b6510131"
/>
2025-03-26 18:11:55 +07:00
Bogdan Chadkin 11bb528ed6 feat: support css variables in shadow properties (#5032)
Closes https://github.com/webstudio-is/webstudio/issues/4939

Added css variables support with autocomplete in text-shadow and
box-shadow properties.

Extended our ast with new "shadow" value to properly represent variables
in shadow properties. Though parser still cannot extract variables from
value with variables and falls back to "unparsed" value.

<img width="542" alt="Screenshot 2025-03-23 at 00 45 03"
src="https://github.com/user-attachments/assets/2493d925-3199-4257-b9e8-dc69daa27324"
/>
2025-03-25 23:10:03 +07:00
Bogdan Chadkin 5637e71287 refactor: migrate css-data to hyphenated properties (#5031)
All parsers/generators accept and produce hyphenated css property. Camel
case is only used for StyleProperty type.
2025-03-22 22:38:59 +07:00
Bogdan Chadkin af653fa002 refactor: hyphenate keyword values (#4987)
Regenerated keyword values data with hyphenated properties. Since the
new object is strictly typed we can use it directly without
styleConfigByName utility which I removed.
2025-03-13 22:44:57 +07:00
Bogdan Chadkin 3c8ac56c39 refactor: migrate properties data to hyphen case (#4970)
properties data are now more type safe and can accept any CssProperty
name though in case of custom properties (--string) will return
undefined.

This also removes a lot of `keyof typeof properties` castings.
2025-03-08 20:26:40 +07:00
Bogdan Chadkin 6d00184f93 refactor: accept hyphenated property in css value parser (#4959)
No longer need to use camel cased property in parseCssValue
2025-03-07 02:03:22 +07:00
Bogdan Chadkin ab65d8e2a3 experimental: support linear() easing (#4957)
Now it is parsed as "unparsed" :)
2025-03-06 22:31:14 +07:00
Bogdan Chadkin 85f83b6e48 refactor: accept both camel and hyphen properties everywhere (#4943)
Here improved all reusable logic to accept both camel and hyphen cases
in properties. This will ease migration to hyphen style.
2025-03-05 10:39:02 +07:00
Bogdan Chadkin 0889342c33 refactor: switch to hyphenated preset styles (#4930)
Replaced camel case with kebab in all presets
2025-03-04 17:26:32 +07:00
Oleg Isonen 7b01153f67 experimental: Shorthands autocomplete (#4898)
ref https://github.com/webstudio-is/webstudio/issues/4816

## Description

Shows shorthands in autocomplete when adding properties.

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2025-02-26 16:45:20 +01:00
Ivan Starkov 62a6d939d8 experimental: Animate UI (#4851)
## Description

1. What is this PR about (link the issue and add a short description)

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2025-02-24 14:27:50 +05:00
Bogdan Chadkin 78a0fa98c1 refactor: output hyphenated properties from css parser (#4900)
We are going to switch to hyphenated properties in styles. Here
refactored css parser to output hyphenated property instead of camel
case and added camelCaseProperty utility which does the opposite of
hyphenateProperty.
2025-02-22 18:11:57 +07:00
Ivan StarkovandOleg Isonen 3c42f8ca4b experimental: View Animations support (#4817)
## Description

ref  #2645

- [x] - Add view-timeline-name and scroll-timeline-name support, and
prefixer (use custom property for unsupported browsers)
- [x] - Add initial story

## Steps for reproduction


https://6382151c8b47d4399fb9fc69-uljkhwtbmc.chromatic.com/iframe.html?args=&globals=&id=sdk-components-animation-view-animations--in-out&viewMode=story

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file

---------

Co-authored-by: Oleg Isonen <oleg008@gmail.com>
2025-02-04 06:02:55 +03:00
Oleg Isonen 5fa6c0354f fix: Floating panel and dialog bugs (#4708)
## Description

- [x] fix maximize/minimize size/positioning
   - open, move, maximize, minimize
   - should be in the last position after moving
- [x]  fixes #4681
- [x] fixes #4684

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2025-01-09 17:29:08 +01:00
Bogdan Chadkin 6c5711cf2a refactor: rewrite radix tabs template with jsx (#4668)
- support `&[data-state=active]` as state in css parser
- added more theme values
- migrated radix tabs to jsx templates
2024-12-28 18:21:33 +07:00
Bogdan Chadkin 1f3e8a68b2 refactor: bump uno (#4576)
Nothing critical. Api is not asynchronous. Oklch is used by default
though I opt out into legacy color space which is supported by our
parser.
2024-12-13 18:36:24 +07:00