Conflicts: package.json (kept both test:browser:mobile and the colour scripts);
head-parity test (kept E_icons from mobile-parity/main AND the E_brand_swatches /
F_swatches_no_brand cases from color-system; pinned bytes re-derived later
against the merged WHP script).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
npm run test:browser:mobile; MOBILE_PARITY_RECORD/BASELINE compare desktop boxes against a base-commit snapshot.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- <=767px: [class^=cols_] wrappers (every ColumnLayout split) stack; a mobile flexDirection:row override still opts out.
- <=767px: navbars without a hamburger wrap instead of overflowing.
- wrapInDocument emits the same Font Awesome links as the backend sb_font_awesome_link (Preview is a sandboxed srcdoc iframe).
- head-parity pins updated (+ E_icons case).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found by the real-editor e2e: picking over the header or its logo box returned the page colour behind it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
design.swatches [{id,label,hex,brand,slot}]; brand ones are published as
--wsb-brand-N appended inside :root (canvas and export share buildTokenVarDecls).
Sites without brand colours emit identical bytes.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Canvas renders plain text via textToInlineHtml (newline -> <br>); toHtml used escapeHtml,
so line breaks typed in the editor vanished on publish (TTM about page: ~100px shorter).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
React assigns '' for a blank style value and a blank longhand after a shorthand
({padding:'20px', paddingTop:''}) wipes the shorthand in the canvas; the exporter
drops blanks. ResolvedRender is the one place node style reaches React, so
normalise there.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Published pages/Preview ship a head reset (*{margin:0;padding:0}, img block,
a inherit, body line-height 1.6 / #1f2937 / 16px); the editor canvas had none,
so h1-h6/p margins, line-height and inherited size/colour differed.
- editor.css: one commented block scoping the reset to .canvas-device-frame,
every selector zero-specificity (:where) so inline styles / class rules win
exactly as when published; editor chrome untouched (snapshot identical).
- tokens.ts: canvas heading/link token rules made zero-specificity too.
- utils/css-reset.ts: single source for the reset declarations (html-export
imports it; test asserts byte-identity with the backend head and that the
editor.css block carries the same declarations).
- scripts/e2e-canvas-parity.mjs (npm run test:browser:canvas): real editor vs
published HTML in Firefox + Chromium, boxes within 1px + computed styles.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
HeroSimple emitted 'background' together with backgroundImage/Size/Position
that were undefined. React assigns '' for those on first render and Chromium
and Firefox then wipe the shorthand's gradient (background-image: none), so
the canvas hero rendered white. Build the style with only the relevant keys
(shared by render and toHtml); exported HTML is byte-identical.
Adds a real-browser (Chromium+Firefox) regression test: npm run test:browser:bg,
and toHtml byte-identity assertions.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
relayFormWiring always emits captcha="1" for relay-wired forms (legacy captcha prop ignored,
old projects with captcha:false load fine). CaptchaMock always shown for relay-wired forms;
FormStylePanel toggle replaced by a read-only note.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185ukXgKV8v9BUrQWXSUW4P
The Navbar renders logoImage only when logoType === 'image', but the
Logo/Text toggle lived in the settings UI removed in 65a10a1 (2026-07-12);
NavStylePanel kept the image picker and never gained the toggle. A picked
logo was stored and silently ignored (editor and published site showed the
text fallback "MySite"; seen on olsdigital.com).
- Logo Type Text/Image toggle in the Navbar Logo section
- picking an image sets logoImage + logoType:'image' in one undo step
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
client_id per editor load (memory only), already_saved, save warnings via notices,
upload_max_bytes enforced client-side with the server error text on 413,
project_max_bytes warning, headCode in the Preview font scan, pinned backend heads.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The section library now calls closeSheet() after inserting a section (or a
global section). It mounts in CanvasOverlays, beside EditorShell, so it could
not reach the MobileChromeProvider inside the shell; the provider moves up to
App around the shell and the overlays so both share one sheet state.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Esc was only claimed by select.parent for a single node, so a multi-selection
could not be dropped from the keyboard. Add select.clear (Esc, >1 selected)
through the existing dispatcher, which already skips text fields and open
dialogs. The context menu's Duplicate/Delete now run the multi-selection core
commands (edit.duplicate / edit.delete) when the clicked node is part of a
multi-selection, instead of acting on the first node only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The business-profile wizard was forced on an empty canvas even when
Sitesmith was locked (paid addon), capped or switched off. The decision now
waits for the entitlement and skips the wizard unless the user can chat
(OK_MONTHLY / OK_BONUS); a failed entitlement falls back to the modal.
useSitesmith reports an ok:false entitlement as an error so it cannot hang.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Title-length, missing meta description and noindex-landing checks carry
fix: 'page-settings', but Fix only closed the list. It now shows that page's
PageSettingsModal in place of the checklist; closing it finishes the Fix.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On mobile the collapsed topbar had no route to Version history, Export ZIP,
Business profile or the command palette. Add a 'Version history' item (only
when the site.history command is registered, run through the registry) and a
'More commands…' item that opens the command palette.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The zone previews render the exported HTML, whose <style data-wsb-responsive>
@media rules evaluate against the browser viewport, so tablet/mobile modes
showed desktop styling for header/footer. ZonePreview now applies the active
device's override rules unconditionally (applyResponsiveCssForDevice) and
drops the rest.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Published mobile stacking is the global RESPONSIVE_CSS rule matching the
DESKTOP inline style, so un-stacking Columns on mobile under a stacked tablet
(styleMobile.flexDirection 'row') publishes un-stacked. The editor's
device-emulation copy matched the resolved inline style and showed it stacked.
RenderNode now marks nodes with a flexDirection/display override with
data-wsb-base-stack (baseStacksOnMobile) and editor.css keys off it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>