**Summary**
Migrates Builder bootstrap data loading from the legacy
`/rest/data/:projectId` endpoint to `build.loadData` tRPC, while keeping
the old REST route as a no-store compatibility shim.
Hardens authenticated Builder/dashboard responses by explicitly sending:
- `Cache-Control: private, no-store, max-age=0`
- `Pragma: no-cache`
- `Expires: 0`
- `Vary: Cookie`
**Details**
- Added `build.loadData` tRPC query for full Builder state.
- Switched Builder client bootstrap loading to tRPC.
- Added shared cache-control helpers for private no-store responses.
- Made tRPC responses private/no-store by default unless anonymous and
explicitly public-cacheable.
- Added no-store headers to
Builder/dashboard/auth/resource/asset-related responses.
- Updated redirect handling to preserve headers while enforcing
no-store.
- Prevented stale dashboard account data from flashing by applying
user-scoped loader data before paint and clearing stores on teardown.
- Added tests for cache headers, tRPC response metadata, and no-store
redirects.
**Validation**
- `pnpm --filter @webstudio-is/builder test --
app/services/cache-control.server.test.ts
app/services/trpc-response-meta.server.test.ts
app/services/no-store-redirect.test.ts app/routes/rest.assets.test.ts
app/shared/sync/project-queue.test.ts app/dashboard/dashboard.test.ts`
- `pnpm exec oxlint ...` on touched files
- `git diff --check`
`pnpm --filter @webstudio-is/builder typecheck` still fails on existing
unrelated Tailwind/css-engine errors.
## 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.
## 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
## Description
1. Related to #5501. This lets user escape exit preview mode when
triggered from the builder UI, while preserving canvas-originated escape
behavior so preview mode remains active when the canvas should handle
the key event.
## Steps for reproduction
1. Open the builder and switch to preview mode.
2. Press Escape from the builder UI.
3. Expect preview mode to exit and the sidebar panel to return to auto.
4. Switch to preview mode again.
5. Press Escape while the focused inside the canvas.
6. Expect preview mode to stay active and canvas/native page behavior to
be preserved.
## 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
- [x] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [x] tested locally and on preview environment (preview dev login:
0000)
- [x] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [x] added tests
- [ ] if any new env variables are added, added them to `.env` file
Treat whitespace-only text nodes between element siblings as part of the
previous element instead of creating a separate text node.
generateFragmentFromHtml now detects when a text node consisting only of
space appears between two elements and appends that space to the
previous instance's last text child (if present), avoiding creation of a
standalone text child. Added a regression test in plugin-html.test.tsx
to verify pasted HTML like `<span>✓</span> <span>text</span>` preserves
the space and results in two span instances (no separate text node),
ensuring text-content control remains correct in the settings panel.
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
## Description
This feature is related to
[#5103](https://github.com/webstudio-is/webstudio/issues/5103). This
adds lock/unlock support for token style sources and prevents editing
locked tokens from the style panel, including keyboard-focus paths,
while keeping token management actions available.
Lock option in token:
<img width="292" height="294" alt="image"
src="https://github.com/user-attachments/assets/29b4119c-16f1-4afc-91df-42815e7d8a5f"
/>
Lock icon for token with properties viewable but not editable:
<img width="269" height="570" alt="image"
src="https://github.com/user-attachments/assets/f2d545f0-690d-4d95-b0d6-203b82ab063f"
/>
Unlock option for locked token:
<img width="302" height="376" alt="image"
src="https://github.com/user-attachments/assets/6b49f0f2-f80b-4eaa-83a3-cfbf91da1db8"
/>
## Steps for reproduction
1. Select an element that uses a token in the Style Sources control.
2. Open the token menu and click `Lock token`.
3. Try editing styles in the style panel with mouse and keyboard.
4. Expect the locked token to stay unchanged: edit controls are
unavailable/inert, focus does not enter locked sections, and token
actions like rename, duplicate, detach, delete, and unlock still work.
## 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
- [x] made a self-review
- [x] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [x] 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
- [x] added tests
- [ ] if any new env variables are added, added them to `.env` file
---------
Co-authored-by: Oleg Isonen <oleg008@gmail.com>
## Problem
Commit cc20991b accidentally changed `itemToString` for `var` type
values to use `toValue(item)`, which produces `var(--variable,
fallback)` instead of the intended short `--variable` label.
This meant the CSS value input (when unfocused, and in the autocomplete
dropdown) showed the full `var(--variable, fallback)` string, which is
too long for small inputs and not how it previously displayed.
## Fix
- Restored `itemToString` to return `--${item.value}` for var types
(short label)
- Updated the `onFocus` handler to explicitly call `toValue(value)` for
var types, so the full `var(--variable, fallback)` is shown when the
user focuses the input to edit it
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.
- Add minSeats/maxSeats to PlanFeatures schema
- listMembers returns DB-backed pending invites (no more client-side
state)
- countAllMembers includes pending invites (billed at invite time, Figma
model)
- Builder-level workspace-router calls payment worker on
addMember/removeMember
- Removed client-side invitedEmails state from manage-members-dialog
- getSeatSuspendedMessage now accepts optional workspace name
- notification-router simplified (accept no longer syncs seats)
## 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
# Description
This updates the navigator to use Figma-style subtree highlighting
instead of relying on vertical depth lines, which makes deeply nested
selections easier to follow. The selected node keeps the primary
selected background, its descendant subtree gets a lighter background,
and the navigator hides depth bars to reduce visual noise.
Related to
([#5206](https://github.com/webstudio-is/webstudio/issues/5206))
## Steps for reproduction
1. Open the Builder and create or expand a deeply nested navigator tree.
2. Select a node that has multiple nested descendants.
3. Expect the selected node to have the active background, its
descendant subtree to have a lighter background, and the navigator to no
longer rely on vertical guide lines for orientation.
https://github.com/user-attachments/assets/c7be9884-43e2-46f1-bb58-68bcf0bad48c
## 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
- [x] made a self-review
- [x] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [x] 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
- [x] added tests
- [ ] if any new env variables are added, added them to `.env` file
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
## 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
- Add new story variants across ~100 files covering previously untested props
- Fix all story titles to use sentence case per UI label guidelines
- Consolidate duplicate card, thumbnail, and value-text stories into parent files
- Add interactive/controlled variants for checkbox, radio, switch, select, etc.
- Add style source, disabled, icon, placeholder, unit options variants to CssValueInput
- Add sub-menu, radio group, destructive, and disabled variants to dropdown/context menus
- Add dialog resize, maximize, actions, and non-draggable variants
- Add popover title, actions, and side placement variants
- Add tooltip side placements and content variant stories
## 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
Show a warning banner when a redirect path matches the current page
path, indicating the redirect will override access to the page.
Changes:
- Add PanelBanner component with warning variant to page settings
- Implement findMatchingRedirect utility to detect redirect conflicts
- Show contextual warning with link to Redirects settings section
- Add comprehensive tests for redirect conflict detection
Code quality:
- Replace 'return undefined' with 'return' per style guide
- Use 'return null' for React components returning nothing