feat(site-builder): tablet/mobile canvas emulates published hide, stacking and full-width

Frame gets data-device; RenderNode mirrors hide flags and selection onto the
dom; editor.css emulates the exported breakpoints inside the narrowed frame.
Also: data-wsb-overridden counts only set values, responsive scope ids are
zone-prefixed (h-/b-/f-) so ROOT no longer collides, and comment delimiters
are stripped from responsive declarations.

Refs #37
This commit is contained in:
shadowdao committed 2026-10-07 11:39:25 -07:00
1 parent ce3db23506
commit 22c59eb970
14 files changed
+269 -32

No files matched your search

+52
View File
@@ -2232,3 +2232,55 @@ body {
color: var(--color-text-muted);
text-align: center;
}
/* --------------------------------------------------------------------------
#37 device emulation
The exported viewport media queries cannot fire inside a narrowed frame,
so the frame carries data-device and these rules mirror them. Selectors
for stacking match the exporter verbatim. !important: styles are inline.
-------------------------------------------------------------------------- */
.canvas-device-frame[data-device="desktop"] [data-hide-desktop]:not([data-craft-selected]),
.canvas-device-frame[data-device="tablet"] [data-hide-tablet]:not([data-craft-selected]),
.canvas-device-frame[data-device="mobile"] [data-hide-mobile]:not([data-craft-selected]) {
display: none !important;
}
/* A hidden-for-this-device node that is selected stays reachable, dimmed. */
.canvas-device-frame[data-device="desktop"] [data-hide-desktop][data-craft-selected],
.canvas-device-frame[data-device="tablet"] [data-hide-tablet][data-craft-selected],
.canvas-device-frame[data-device="mobile"] [data-hide-mobile][data-craft-selected] {
opacity: 0.35;
outline: 2px dashed var(--color-warning, #f59e0b);
}
.canvas-device-frame[data-device="mobile"] [style*="display: flex"][style*="flex-direction: row"],
.canvas-device-frame[data-device="mobile"] [style*="display:flex"][style*="flex-direction:row"] {
flex-direction: column !important;
}
.canvas-device-frame:not([data-device="desktop"]) [data-fullwidth] {
width: 100% !important;
margin-left: 0 !important;
}
.canvas-device-frame[data-device="tablet"],
.canvas-device-frame[data-device="mobile"] {
position: relative;
}
.canvas-device-frame[data-device="tablet"]::before,
.canvas-device-frame[data-device="mobile"]::before {
position: absolute;
top: 0;
right: 0;
z-index: 5;
padding: 2px 8px;
font-size: 10px;
font-weight: 600;
line-height: 16px;
color: #fff;
background: rgba(15, 23, 42, 0.75);
border-bottom-left-radius: 4px;
pointer-events: none;
}
.canvas-device-frame[data-device="tablet"]::before { content: "Tablet \00b7 768px"; }
.canvas-device-frame[data-device="mobile"]::before { content: "Mobile \00b7 375px"; }