efficient-easel 0.101.0 → 0.102.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/dist/LinkPicker-W2Rtxetz.d.ts +111 -0
- package/dist/autosave/index.d.ts +6 -3
- package/dist/autosave/index.js +1 -1
- package/dist/chrome/index.d.ts +3 -2
- package/dist/chrome/index.js +1 -25
- package/dist/chunk-26OOWIJJ.js +1 -0
- package/dist/chunk-2LK54I4E.js +1 -0
- package/dist/chunk-3QVB4AG2.js +3 -0
- package/dist/chunk-3U4GP5VA.js +10 -0
- package/dist/chunk-3WSPDAK2.js +1 -0
- package/dist/chunk-4ES5JGGX.js +1 -0
- package/dist/chunk-5464H65G.js +4 -0
- package/dist/chunk-57DJOKXT.js +1 -0
- package/dist/chunk-5MZ3RNQQ.js +13 -0
- package/dist/chunk-5ZBY24K7.js +1 -0
- package/dist/chunk-6DJHRLCU.js +25 -0
- package/dist/chunk-6FY3PZS3.js +1 -0
- package/dist/chunk-6TZTKAB5.js +1 -0
- package/dist/chunk-6W7WLPZH.js +1 -0
- package/dist/chunk-7F52SZOI.js +2 -0
- package/dist/chunk-7MU3RJ6S.js +1 -0
- package/dist/chunk-7RNTMJER.js +5 -0
- package/dist/chunk-A7ZJII7O.js +1 -0
- package/dist/chunk-AJBJ74ME.js +1 -0
- package/dist/chunk-AKFJK65Z.js +1 -0
- package/dist/chunk-AKZWUV5Z.js +1 -0
- package/dist/chunk-BDTITTMW.js +1 -0
- package/dist/chunk-BSPCSC45.js +1 -0
- package/dist/chunk-BXZ6WLHC.js +22 -0
- package/dist/chunk-D7M6IRPJ.js +8 -0
- package/dist/chunk-DUVRZ456.js +1 -0
- package/dist/chunk-E7GGVILG.js +1 -0
- package/dist/chunk-F2FPZIZV.js +62 -0
- package/dist/chunk-F6CCTEIX.js +1 -0
- package/dist/chunk-FGNR22NY.js +1 -0
- package/dist/chunk-FT35FX7D.js +2 -0
- package/dist/chunk-FUDHI5I4.js +1 -0
- package/dist/chunk-GENAF3P6.js +1 -0
- package/dist/chunk-GOTN2KY4.js +2 -0
- package/dist/chunk-GXQCZJOP.js +1 -0
- package/dist/chunk-GZO72N3Q.js +0 -0
- package/dist/chunk-HMX55DYT.js +1 -0
- package/dist/chunk-HQ4VVRIC.js +1 -0
- package/dist/chunk-HWW4XJOH.js +1 -0
- package/dist/chunk-I54UCYOU.js +1 -0
- package/dist/chunk-IQ5TA7AM.js +1 -0
- package/dist/chunk-IWAPPEL4.js +6 -0
- package/dist/chunk-IYT6NN2J.js +1 -0
- package/dist/chunk-J4RAY75C.js +1 -0
- package/dist/chunk-KCBEE2MC.js +2 -0
- package/dist/chunk-KDYIMJTZ.js +1 -0
- package/dist/chunk-KQMML6JM.js +4 -0
- package/dist/chunk-OM67AJQC.js +1 -0
- package/dist/chunk-OYX47SL7.js +1 -0
- package/dist/chunk-P67FP7PG.js +9 -0
- package/dist/chunk-PP44LCJM.js +1 -0
- package/dist/chunk-PWZOS45R.js +2 -0
- package/dist/chunk-Q3SQBNJB.js +1 -0
- package/dist/chunk-R2HLPNQF.js +1 -0
- package/dist/chunk-R5L2E7JX.js +1 -0
- package/dist/chunk-R5ZVNJLJ.js +2 -0
- package/dist/chunk-RLBXE4EU.js +1 -0
- package/dist/chunk-RW4XBUUW.js +1 -0
- package/dist/chunk-SERF2FAU.js +1 -0
- package/dist/chunk-TEZ6V6PA.js +4 -0
- package/dist/chunk-TTJ54QGG.js +18 -0
- package/dist/chunk-UH7TGWHR.js +1 -0
- package/dist/chunk-UVWVYMMZ.js +1 -0
- package/dist/chunk-VLSTGOVD.js +2 -0
- package/dist/chunk-VV5ADNBR.js +1 -0
- package/dist/chunk-ZE7I3PLX.js +1 -0
- package/dist/chunk-ZZ7VLIHQ.js +1 -0
- package/dist/drag/index.d.ts +3 -41
- package/dist/drag/index.js +1 -18
- package/dist/easel/index.js +1 -9
- package/dist/{words-BMzV04b1.d.ts → engine-DBxp_v6B.d.ts} +1 -58
- package/dist/fields/index.d.ts +2 -109
- package/dist/fields/index.js +1 -22
- package/dist/gold/index.d.ts +4 -2
- package/dist/host-B-byaQxg.d.ts +480 -0
- package/dist/menu/index.js +1 -1
- package/dist/node-ops/index.js +1 -1
- package/dist/panel/index.js +16 -16
- package/dist/panelWidths-D9hTLR25.d.ts +66 -0
- package/dist/screen/components/AddBlockRow.d.ts +14 -0
- package/dist/screen/components/AddBlockRow.js +1 -0
- package/dist/screen/components/AddChildRow.d.ts +39 -0
- package/dist/screen/components/AddChildRow.js +1 -0
- package/dist/screen/components/AddSidePanel.d.ts +54 -0
- package/dist/screen/components/AddSidePanel.js +1 -0
- package/dist/screen/components/MediaSidePanel.d.ts +47 -0
- package/dist/screen/components/MediaSidePanel.js +1 -0
- package/dist/screen/components/NodeContextMenu.d.ts +364 -0
- package/dist/screen/components/NodeContextMenu.js +1 -0
- package/dist/screen/components/PageEditGuardNotices.d.ts +5 -0
- package/dist/screen/components/PageEditGuardNotices.js +1 -0
- package/dist/screen/components/PanelToggleIcon.d.ts +14 -0
- package/dist/screen/components/PanelToggleIcon.js +1 -0
- package/dist/screen/components/PreviewDeviceContext.d.ts +28 -0
- package/dist/screen/components/PreviewDeviceContext.js +1 -0
- package/dist/screen/components/PreviewPartsContext.d.ts +33 -0
- package/dist/screen/components/PreviewPartsContext.js +1 -0
- package/dist/screen/components/ScreenChrome.d.ts +5 -0
- package/dist/screen/components/ScreenChrome.js +1 -0
- package/dist/screen/components/ScreenDocumentContext.d.ts +20 -0
- package/dist/screen/components/ScreenDocumentContext.js +1 -0
- package/dist/screen/components/ScreenMount.d.ts +75 -0
- package/dist/screen/components/ScreenMount.js +1 -0
- package/dist/screen/components/ScreenStoreProvider.d.ts +63 -0
- package/dist/screen/components/ScreenStoreProvider.js +1 -0
- package/dist/screen/components/SectionScreenShell.d.ts +5 -0
- package/dist/screen/components/SectionScreenShell.js +16 -0
- package/dist/screen/components/SidePanelHead.d.ts +81 -0
- package/dist/screen/components/SidePanelHead.js +1 -0
- package/dist/screen/components/SlotChildActionsContext.d.ts +41 -0
- package/dist/screen/components/SlotChildActionsContext.js +1 -0
- package/dist/screen/components/UiIcon.d.ts +52 -0
- package/dist/screen/components/UiIcon.js +1 -0
- package/dist/screen/components/panel-widths.d.ts +37 -0
- package/dist/screen/components/panel-widths.js +1 -0
- package/dist/screen/components/usePartBridge.d.ts +66 -0
- package/dist/screen/components/usePartBridge.js +1 -0
- package/dist/screen/index.d.ts +31 -0
- package/dist/screen/index.js +1 -0
- package/dist/screen/lib/admin-bridge.d.ts +105 -0
- package/dist/screen/lib/admin-bridge.js +1 -0
- package/dist/screen/lib/backend-error.d.ts +106 -0
- package/dist/screen/lib/backend-error.js +1 -0
- package/dist/screen/lib/chrome-theme.d.ts +21 -0
- package/dist/screen/lib/chrome-theme.js +1 -0
- package/dist/screen/lib/client-only.d.ts +24 -0
- package/dist/screen/lib/client-only.js +1 -0
- package/dist/screen/lib/content/view-tiers.d.ts +25 -0
- package/dist/screen/lib/content/view-tiers.js +1 -0
- package/dist/screen/lib/document-addressing.d.ts +20 -0
- package/dist/screen/lib/document-addressing.js +1 -0
- package/dist/screen/lib/document-contract.d.ts +230 -0
- package/dist/screen/lib/document-contract.js +1 -0
- package/dist/screen/lib/document-hooks.d.ts +71 -0
- package/dist/screen/lib/document-hooks.js +0 -0
- package/dist/screen/lib/document-switch.d.ts +74 -0
- package/dist/screen/lib/document-switch.js +1 -0
- package/dist/screen/lib/failure.d.ts +54 -0
- package/dist/screen/lib/failure.js +1 -0
- package/dist/screen/lib/host-chrome.d.ts +181 -0
- package/dist/screen/lib/host-chrome.js +1 -0
- package/dist/screen/lib/host-inbound.d.ts +20 -0
- package/dist/screen/lib/host-inbound.js +1 -0
- package/dist/screen/lib/host.d.ts +20 -0
- package/dist/screen/lib/host.js +1 -0
- package/dist/screen/lib/key-scope.d.ts +23 -0
- package/dist/screen/lib/key-scope.js +1 -0
- package/dist/screen/lib/links/link-filters.d.ts +41 -0
- package/dist/screen/lib/links/link-filters.js +0 -0
- package/dist/screen/lib/load-error.d.ts +29 -0
- package/dist/screen/lib/load-error.js +1 -0
- package/dist/screen/lib/media-panel.d.ts +94 -0
- package/dist/screen/lib/media-panel.js +1 -0
- package/dist/screen/lib/media-picker.d.ts +68 -0
- package/dist/screen/lib/media-picker.js +1 -0
- package/dist/screen/lib/page-lock.d.ts +5 -0
- package/dist/screen/lib/page-lock.js +1 -0
- package/dist/screen/lib/puck/add-target-types.d.ts +55 -0
- package/dist/screen/lib/puck/add-target-types.js +0 -0
- package/dist/screen/lib/puck/block-choice.d.ts +52 -0
- package/dist/screen/lib/puck/block-choice.js +1 -0
- package/dist/screen/lib/puck/block-types-in.d.ts +39 -0
- package/dist/screen/lib/puck/block-types-in.js +1 -0
- package/dist/screen/lib/puck/content-tree.d.ts +196 -0
- package/dist/screen/lib/puck/content-tree.js +1 -0
- package/dist/screen/lib/puck/device-fields.d.ts +126 -0
- package/dist/screen/lib/puck/device-fields.js +1 -0
- package/dist/screen/lib/puck/field-buckets.d.ts +22 -0
- package/dist/screen/lib/puck/field-buckets.js +1 -0
- package/dist/screen/lib/puck/field-markers.d.ts +205 -0
- package/dist/screen/lib/puck/field-markers.js +1 -0
- package/dist/screen/lib/puck/hidable.d.ts +44 -0
- package/dist/screen/lib/puck/hidable.js +1 -0
- package/dist/screen/lib/puck/palette-sections.d.ts +96 -0
- package/dist/screen/lib/puck/palette-sections.js +1 -0
- package/dist/screen/lib/puck/panel-fields.d.ts +47 -0
- package/dist/screen/lib/puck/panel-fields.js +1 -0
- package/dist/screen/lib/puck/panel-no-control-mark.d.ts +74 -0
- package/dist/screen/lib/puck/panel-no-control-mark.js +1 -0
- package/dist/screen/lib/puck/part-id.d.ts +23 -0
- package/dist/screen/lib/puck/part-id.js +1 -0
- package/dist/screen/lib/puck/preview-click.d.ts +49 -0
- package/dist/screen/lib/puck/preview-click.js +1 -0
- package/dist/screen/lib/puck/preview-dom.d.ts +8 -0
- package/dist/screen/lib/puck/preview-dom.js +1 -0
- package/dist/screen/lib/puck/preview-events.d.ts +25 -0
- package/dist/screen/lib/puck/preview-events.js +1 -0
- package/dist/screen/lib/puck/preview-selection-context.d.ts +72 -0
- package/dist/screen/lib/puck/preview-selection-context.js +1 -0
- package/dist/screen/lib/puck/section-doc.d.ts +20 -0
- package/dist/screen/lib/puck/section-doc.js +1 -0
- package/dist/screen/lib/puck/slot-child-name.d.ts +186 -0
- package/dist/screen/lib/puck/slot-child-name.js +1 -0
- package/dist/screen/lib/puck/slot-heal.d.ts +5 -0
- package/dist/screen/lib/puck/slot-heal.js +1 -0
- package/dist/screen/lib/puck/slot-section-spec.d.ts +96 -0
- package/dist/screen/lib/puck/slot-section-spec.js +0 -0
- package/dist/screen/lib/puck/style-clipboard.d.ts +78 -0
- package/dist/screen/lib/puck/style-clipboard.js +1 -0
- package/dist/screen/lib/puck/text-control-kinds.d.ts +71 -0
- package/dist/screen/lib/puck/text-control-kinds.js +1 -0
- package/dist/screen/lib/puck/tree-reveal.d.ts +62 -0
- package/dist/screen/lib/puck/tree-reveal.js +1 -0
- package/dist/screen/lib/puck/use-section-ops.d.ts +86 -0
- package/dist/screen/lib/puck/use-section-ops.js +1 -0
- package/dist/screen/lib/screen-parts.d.ts +727 -0
- package/dist/screen/lib/screen-parts.js +1 -0
- package/dist/screen/lib/section-template-types.d.ts +49 -0
- package/dist/screen/lib/section-template-types.js +0 -0
- package/dist/screen/lib/section-templates.d.ts +23 -0
- package/dist/screen/lib/section-templates.js +1 -0
- package/dist/screen/lib/session-context.d.ts +30 -0
- package/dist/screen/lib/session-context.js +1 -0
- package/dist/screen/lib/session.d.ts +255 -0
- package/dist/screen/lib/session.js +1 -0
- package/dist/screen/screen.css +1088 -0
- package/dist/session-DSQFmIvx.d.ts +43 -0
- package/dist/strings/catalogue.d.ts +4 -2
- package/dist/strings/catalogue.js +1 -1
- package/dist/strings/index.d.ts +4 -2
- package/dist/strings/index.js +1 -1
- package/dist/style-clipboard/index.js +1 -1
- package/dist/{types-DGcCsxs8.d.ts → types-CqY85foL.d.ts} +3 -65
- package/dist/words-D_Lnw1Gr.d.ts +59 -0
- package/package.json +343 -2
- package/dist/chunk-IG3U5NWJ.js +0 -1
|
@@ -0,0 +1,1088 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* efficient-easel/screen.css — the assembled editor screen's own rules: its
|
|
3
|
+
* frame (`.sf-editor`, and the `--sf-*` names it aliases onto easel's `--es-*`
|
|
4
|
+
* tokens), the panels' heads, the add panel and block menu, the media panel,
|
|
5
|
+
* the preview's frame and the gaps between sections, toasts and messages.
|
|
6
|
+
*
|
|
7
|
+
* They came from efficient-web-builder's components/storefront-editor.css with
|
|
8
|
+
* the screen (that repo's doc/adr/0004): a rule is here when every `sf-` class
|
|
9
|
+
* it names is drawn by the screen, so every host that mounts the screen gets
|
|
10
|
+
* it; a rule that names a class only a host draws stays in that host's sheet.
|
|
11
|
+
* The `sf-` names are kept: the hosts' sheets and their guards address them.
|
|
12
|
+
*
|
|
13
|
+
* Load it after the other easel sheets and before a host's own sheet, which is
|
|
14
|
+
* where these rules sat in the builder's; that order is the one the cascade
|
|
15
|
+
* was measured in.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
.sf-editor {
|
|
19
|
+
/* ── Accent (efficient-shell blue) ───────────────────────────────────── */
|
|
20
|
+
--sf-accent: var(--es-accent);
|
|
21
|
+
--sf-accent-tint: var(--es-accent-tint);
|
|
22
|
+
--sf-accent-tint-strong: var(--es-accent-tint-strong);
|
|
23
|
+
--sf-accent-text: var(--es-accent-text);
|
|
24
|
+
--sf-accent-ring: var(--es-accent-ring);
|
|
25
|
+
--sf-accent-shadow: var(--es-accent-shadow);
|
|
26
|
+
--sf-on-accent: var(--es-on-accent);
|
|
27
|
+
|
|
28
|
+
/* ── Surfaces (cool gray ramp) ──────────────────────────────────────── */
|
|
29
|
+
--sf-app-bg: var(--es-app-bg);
|
|
30
|
+
--sf-preview-bg: var(--es-preview-bg);
|
|
31
|
+
--sf-panel: var(--es-panel);
|
|
32
|
+
--sf-raised: var(--es-raised);
|
|
33
|
+
--sf-frame-bg: var(--es-frame-bg);
|
|
34
|
+
--sf-hover: var(--es-hover);
|
|
35
|
+
--sf-hatch: var(--es-hatch);
|
|
36
|
+
--sf-addcard-veil: var(--es-addcard-veil);
|
|
37
|
+
|
|
38
|
+
/* ── Fields ─────────────────────────────────────────────────────────── */
|
|
39
|
+
--sf-field-bg: var(--es-field-bg);
|
|
40
|
+
--sf-track-bg: var(--es-track-bg);
|
|
41
|
+
--sf-input-border: var(--es-input-border);
|
|
42
|
+
--sf-field-text: var(--es-field-text);
|
|
43
|
+
--sf-field-placeholder: var(--es-field-placeholder);
|
|
44
|
+
--sf-knob: var(--es-knob);
|
|
45
|
+
|
|
46
|
+
/* ── Text ───────────────────────────────────────────────────────────── */
|
|
47
|
+
--sf-text: var(--es-text);
|
|
48
|
+
--sf-text-strong: var(--es-text-strong);
|
|
49
|
+
--sf-text-secondary: var(--es-text-secondary);
|
|
50
|
+
--sf-muted: var(--es-muted);
|
|
51
|
+
--sf-icon: var(--es-icon);
|
|
52
|
+
--sf-disabled: var(--es-disabled);
|
|
53
|
+
|
|
54
|
+
/* ── Lines / chips / buttons ────────────────────────────────────────── */
|
|
55
|
+
--sf-divider: var(--es-divider);
|
|
56
|
+
--sf-line: var(--es-line);
|
|
57
|
+
--sf-btn-border: var(--es-btn-border);
|
|
58
|
+
--sf-btn-text: var(--es-btn-text);
|
|
59
|
+
--sf-chip-bg: var(--es-chip-bg);
|
|
60
|
+
--sf-chip-fg: var(--es-chip-fg);
|
|
61
|
+
|
|
62
|
+
/* ── Named chrome literals ──────────────────────────────────────────── */
|
|
63
|
+
--sf-device-border: var(--es-device-border);
|
|
64
|
+
--sf-toast-bg: var(--es-toast-bg);
|
|
65
|
+
--sf-scrollbar: var(--es-scrollbar);
|
|
66
|
+
--sf-scrollbar-hover: var(--es-scrollbar-hover);
|
|
67
|
+
|
|
68
|
+
/* ── Danger / warning / success (shell red / amber / green) ─────────── */
|
|
69
|
+
--sf-danger: var(--es-danger);
|
|
70
|
+
--sf-danger-strong: var(--es-danger-strong);
|
|
71
|
+
--sf-danger-tint: var(--es-danger-tint);
|
|
72
|
+
--sf-warning: var(--es-warning);
|
|
73
|
+
--sf-preview-tint: var(--es-preview-tint);
|
|
74
|
+
|
|
75
|
+
/* ── Radii / shape (tighter, shell-like) ────────────────────────────── */
|
|
76
|
+
/*
|
|
77
|
+
* ┌─ FLAT CHROME (card 66161) — these three do NOT alias the shell. ─────────
|
|
78
|
+
* │
|
|
79
|
+
* │ The panels used to be floating cards: rounded, drop-shadowed, sitting on
|
|
80
|
+
* │ the grey app background with a 10px gap between each pair and a 10px frame
|
|
81
|
+
* │ padding around the lot. The owner asked for lines instead. On a 1280px
|
|
82
|
+
* │ laptop that gave the website preview 50px back — 576px to 626px — because
|
|
83
|
+
* │ gaps, corners and shadows hold nothing. No panel got narrower and no
|
|
84
|
+
* │ vertical measurement changed.
|
|
85
|
+
* │
|
|
86
|
+
* │ WHY THESE STOPPED ALIASING, AND EXACTLY WHAT ENDS IT
|
|
87
|
+
* │
|
|
88
|
+
* │ The `--sf-*` block exists exactly so the shop can pick its own values off
|
|
89
|
+
* │ the shared `--es-*` layer. Flat is the SHOP's decision, not the shell's.
|
|
90
|
+
* │
|
|
91
|
+
* │ Note the ORIGINAL reason is already gone, so do not go looking for it:
|
|
92
|
+
* │ when this was written, card 66160 was mid-release on editor-shell and two
|
|
93
|
+
* │ windows bumping one package version would have collided. That released as
|
|
94
|
+
* │ `editor-shell@0.13.0` the same day, and the shop still declares `^0.12.0`.
|
|
95
|
+
* │ The values stayed local anyway, for a reason that has nothing to do with
|
|
96
|
+
* │ release timing:
|
|
97
|
+
* │
|
|
98
|
+
* │ THE OWNER DECIDED FLAT FOR THE STOREFRONT EDITOR ONLY.
|
|
99
|
+
* │
|
|
100
|
+
* │ Putting these in the shell's defaults would make the campaign editor flat
|
|
101
|
+
* │ too, which nobody has asked for. The campaign editor is also still pinned
|
|
102
|
+
* │ to `editor-shell@0.2.0` and cannot receive shell changes at all until it
|
|
103
|
+
* │ comes off that pin.
|
|
104
|
+
* │
|
|
105
|
+
* │ So this is NOT a half-finished alias block, and it is NOT drift. Do not
|
|
106
|
+
* │ "fix" these back into `var(--es-…)`.
|
|
107
|
+
* │
|
|
108
|
+
* │ IT ENDS WHEN BOTH ARE TRUE:
|
|
109
|
+
* │ 1. the campaign editor comes off its `editor-shell@0.2.0` pin, AND
|
|
110
|
+
* │ 2. the owner decides the campaign editor should go flat as well.
|
|
111
|
+
* │ Then promote the three values into the shell defaults, delete these three
|
|
112
|
+
* │ lines, and drop the matching waiver in `scripts/test-inspector-inherit.tsx`
|
|
113
|
+
* │ in the same change. Either one alone is not enough.
|
|
114
|
+
* │
|
|
115
|
+
* │ `scripts/test-editor-flat-chrome.ts` fails if they are re-aliased.
|
|
116
|
+
* └──────────────────────────────────────────────────────────────────────────
|
|
117
|
+
*/
|
|
118
|
+
--sf-panel-radius: 0;
|
|
119
|
+
--sf-row-radius: var(--es-row-radius);
|
|
120
|
+
--sf-field-radius: var(--es-field-radius);
|
|
121
|
+
/* The editor "frame" gap: the space between the panels and the preview, and
|
|
122
|
+
the padding around the whole framed area (top/bottom + outer left/right).
|
|
123
|
+
One token so the frame tightens in ONE place — .sf-body drives it, and the
|
|
124
|
+
Add-section picker + section-editor top strip track it.
|
|
125
|
+
Flat since 66161 (see the note above). It MUST stay a length rather than a
|
|
126
|
+
bare `0`: it is spent inside calc() below and in the picker's width, and
|
|
127
|
+
`calc(0 + 46px)` is invalid CSS — the whole declaration would be dropped and
|
|
128
|
+
the left grip would land at the frame's edge instead of on its seam. */
|
|
129
|
+
--sf-panel-gap: 0px;
|
|
130
|
+
/* Side-panel widths ride in as editor-shell's --es-left-w / --es-right-w, set
|
|
131
|
+
on the editor ROOT by BOTH editors through components/panel-widths.ts (the
|
|
132
|
+
page chrome per drag; the standalone section editor at the fixed defaults).
|
|
133
|
+
The literal widths deliberately do NOT live here — see that module. */
|
|
134
|
+
/* Top-bar height. ONE source for both the chrome that draws it AND the
|
|
135
|
+
working-area overlay (the Add-section picker) that must clear
|
|
136
|
+
it to sit inside the frame, not cover it.
|
|
137
|
+
Storefront-LOCAL geometry: the top bar is this editor's own chrome
|
|
138
|
+
dimension, not part of the shared token layer. */
|
|
139
|
+
--sf-topbar-h: 52px;
|
|
140
|
+
/* There is no `--sf-rail-w`. Card 66198 moved the icon rail into the top bar,
|
|
141
|
+
where editor-shell's row variant is `width: auto` — the rail is as wide as
|
|
142
|
+
its buttons, so no element has a width for that token to name. It was NOT
|
|
143
|
+
set to 0: a 0 would leave every calc() below arithmetically correct while
|
|
144
|
+
keeping a token still aimed at the content column, so restoring a
|
|
145
|
+
non-zero value would move it. Deleting it means the
|
|
146
|
+
next person has to write the term back on purpose.
|
|
147
|
+
|
|
148
|
+
Where the content column BEGINS. Now the frame padding and nothing else:
|
|
149
|
+
the left panel is `.sf-body`'s first in-flow child, so its box starts at the
|
|
150
|
+
padding edge. Everything drawn against that box — the left resize grip — and
|
|
151
|
+
every overlay framed in the working area reads this one name.
|
|
152
|
+
|
|
153
|
+
Card 66149 is why the name exists: the left grip spent
|
|
154
|
+
`--sf-panel-gap + --es-left-w` while a rail really was in front of the
|
|
155
|
+
panel, and landed 56px inside it where no merchant could reach it. This
|
|
156
|
+
card is the mirror image — the danger now is a pin that keeps PAYING for a
|
|
157
|
+
rail nobody renders — and the guard is the same, because
|
|
158
|
+
`scripts/test-editor-rail-in-topbar.ts` evaluates this at probe values with
|
|
159
|
+
no `--sf-rail-w` in the table at all: a restored rail term throws by name
|
|
160
|
+
rather than quietly reserving 46px of website.
|
|
161
|
+
|
|
162
|
+
Still written as `var(--sf-panel-gap)` and not a bare `0`, for the reason
|
|
163
|
+
given at that token above: it is spent inside calc() and `calc(0 + 288px)`
|
|
164
|
+
is invalid CSS — the whole declaration would be dropped and the left grip
|
|
165
|
+
would land at the frame's edge instead of on its seam. */
|
|
166
|
+
--sf-content-x: var(--sf-panel-gap);
|
|
167
|
+
/* Flat since 66161 — see the note at --sf-panel-radius above. */
|
|
168
|
+
--sf-panel-shadow: none;
|
|
169
|
+
--sf-font: var(--es-font);
|
|
170
|
+
|
|
171
|
+
/* No `--puck-*` names here. Puck read its `--puck-color-azure-*` ramp and
|
|
172
|
+
`--puck-font-family` from editor-shell's shell.css on this same root, and
|
|
173
|
+
they were deliberately never re-declared in this file — one blue is the
|
|
174
|
+
point. Puck and those names left with blueprint 6.1/6.3; the blue is the
|
|
175
|
+
`--es-*` set in efficient-easel/shell.css. */
|
|
176
|
+
|
|
177
|
+
/*
|
|
178
|
+
* Fill the iframe viewport. `100dvh` resolves against the viewport directly,
|
|
179
|
+
* so the editor always fills the embedding iframe with no flex/min-height
|
|
180
|
+
* dependency (percentage heights don't resolve against the app shell's
|
|
181
|
+
* min-height, which otherwise left a gap below the editor). Mounted inside
|
|
182
|
+
* another app's window it fills that window instead — `.sf-embedded`, below.
|
|
183
|
+
*/
|
|
184
|
+
width: 100%;
|
|
185
|
+
height: 100vh;
|
|
186
|
+
height: 100dvh;
|
|
187
|
+
display: flex;
|
|
188
|
+
flex-direction: column;
|
|
189
|
+
overflow: hidden;
|
|
190
|
+
position: relative; /* positioning context for the floating add-section modal + toast */
|
|
191
|
+
background: var(--sf-app-bg);
|
|
192
|
+
color: var(--sf-text);
|
|
193
|
+
font-family: var(--sf-font);
|
|
194
|
+
font-size: 14px;
|
|
195
|
+
-webkit-font-smoothing: antialiased;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.sf-editor *,
|
|
199
|
+
.sf-editor *::before,
|
|
200
|
+
.sf-editor *::after {
|
|
201
|
+
box-sizing: border-box;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* Scrollbars inside the editor panels */
|
|
205
|
+
.sf-scroll::-webkit-scrollbar {
|
|
206
|
+
width: 11px;
|
|
207
|
+
height: 11px;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.sf-scroll::-webkit-scrollbar-thumb {
|
|
211
|
+
background: var(--sf-scrollbar);
|
|
212
|
+
border-radius: 8px;
|
|
213
|
+
border: 3px solid transparent;
|
|
214
|
+
background-clip: content-box;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.sf-scroll::-webkit-scrollbar-thumb:hover {
|
|
218
|
+
background: var(--sf-scrollbar-hover);
|
|
219
|
+
background-clip: content-box;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.sf-scroll::-webkit-scrollbar-track {
|
|
223
|
+
background: transparent;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* Standalone section editor — a slim top strip carrying the "Preview mode"
|
|
227
|
+
switch (left) and the autosave pill (right), above the reused sf-body
|
|
228
|
+
(canvas + inspector). */
|
|
229
|
+
.sf-section-bar {
|
|
230
|
+
flex: none;
|
|
231
|
+
display: flex;
|
|
232
|
+
align-items: center;
|
|
233
|
+
justify-content: space-between;
|
|
234
|
+
gap: 16px;
|
|
235
|
+
/* PINNED at 10px by card 66161, which took `--sf-panel-gap` to 0 to flatten
|
|
236
|
+
the PAGE chrome. This strip belongs to the standalone SECTION editor — a
|
|
237
|
+
different surface — and the 10px here is real padding holding the
|
|
238
|
+
"Preview mode" switch and the autosave pill off the window edge, not a gap
|
|
239
|
+
that existed so a card could float. Following the token to 0 would have
|
|
240
|
+
changed a surface this card was never about, so it is spelled out instead.
|
|
241
|
+
Deliberately its own literal rather than a shared "inset" token: one token
|
|
242
|
+
quietly deciding the padding of a dialog AND a different editor's strip is
|
|
243
|
+
the coupling that made this a question at all. Whether this strip should go
|
|
244
|
+
flat too is its own decision, on its own card. */
|
|
245
|
+
padding: 8px 10px;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/* The save pill (dot, ring, words, the autosave switch around it) is
|
|
249
|
+
editor-shell's `.es-savestate` (efficient-easel/chrome.css), lifted from this
|
|
250
|
+
sheet with its card-66103 quiet state and the countdown ring (redesign 2a). */
|
|
251
|
+
/* ── Body / floating panels ───────────────────────────────────────────── */
|
|
252
|
+
.sf-body {
|
|
253
|
+
flex: 1;
|
|
254
|
+
display: flex;
|
|
255
|
+
gap: var(--sf-panel-gap);
|
|
256
|
+
padding: var(--sf-panel-gap);
|
|
257
|
+
min-height: 0;
|
|
258
|
+
/* Positioning context for the absolutely-placed resize grips (editor-shell's .es-resizer),
|
|
259
|
+
which the chrome pins over each panel↔preview seam. */
|
|
260
|
+
position: relative;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* ── Body / floating panels ───────────────────────────────────────────── */
|
|
264
|
+
/* THE SIDE PANELS AND THEIR GRIPS ARE editor-shell's (efficient-easel/chrome.css):
|
|
265
|
+
`.es-sidepanel` — flush, a hairline on the SEAM side only (card 66161: draw the
|
|
266
|
+
seams, leave the outer edges alone), the size-container context every
|
|
267
|
+
`@container` rule in this sheet asks (card 66212) — and `.es-resizer`, pinned
|
|
268
|
+
over each seam from `--es-left-w` / `--es-right-w`, with the drag's
|
|
269
|
+
`body.es-col-resizing`. Lifted from this sheet (redesign 2a). The panels keep
|
|
270
|
+
`.sf-panel` / `.sf-panel--left|right` as well, which is what this sheet's own
|
|
271
|
+
descendant rules (`.sf-panel--right .sf-insp-body`, …) hang on. */
|
|
272
|
+
.sf-panel-head {
|
|
273
|
+
display: flex;
|
|
274
|
+
align-items: center;
|
|
275
|
+
justify-content: space-between;
|
|
276
|
+
padding: 13px 14px 11px;
|
|
277
|
+
flex: none;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* ── Body / floating panels ───────────────────────────────────────────── */
|
|
281
|
+
/* A panel's own name. It is an `h2` in the views that own their title
|
|
282
|
+
(StylesPanel), so the rule states the three properties a heading element
|
|
283
|
+
would otherwise inherit from the UA sheet — `margin` above all, which is
|
|
284
|
+
`0.83em 0` on an h2 and would push the whole head open. The `--btn` variant
|
|
285
|
+
below re-states its own margin and wins by source order. */
|
|
286
|
+
.sf-panel-title {
|
|
287
|
+
font-size: 13px;
|
|
288
|
+
font-weight: 600;
|
|
289
|
+
color: var(--sf-text);
|
|
290
|
+
margin: 0;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/* In the standalone section editor the title doubles as the SELECT-ROOT control
|
|
294
|
+
(clicking the section name selects the section node → its section-level
|
|
295
|
+
fields), so it renders as a <button>. Reset the UA button chrome back to the
|
|
296
|
+
heading it replaces, then add row-style hover / selected affordance so it
|
|
297
|
+
reads as interactive and shows when the root is the active selection. */
|
|
298
|
+
.sf-panel-title--btn {
|
|
299
|
+
appearance: none;
|
|
300
|
+
border: 0;
|
|
301
|
+
background: transparent;
|
|
302
|
+
font-family: inherit;
|
|
303
|
+
cursor: pointer;
|
|
304
|
+
text-align: left;
|
|
305
|
+
padding: 5px 8px;
|
|
306
|
+
margin: -5px -8px;
|
|
307
|
+
border-radius: var(--sf-row-radius);
|
|
308
|
+
transition: background 0.12s;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.sf-panel-title--btn:hover {
|
|
312
|
+
background: var(--sf-hover);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.sf-panel-title--btn.is-selected {
|
|
316
|
+
color: var(--sf-accent-text);
|
|
317
|
+
background: var(--sf-accent-tint);
|
|
318
|
+
box-shadow: inset 2px 0 0 var(--sf-accent);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/* ── Left panel: section tree (wraps Puck.Outline) ────────────────────── */
|
|
322
|
+
.sf-tree {
|
|
323
|
+
flex: 1;
|
|
324
|
+
overflow-y: auto;
|
|
325
|
+
/* THE TWO SIDES PAY FOR DIFFERENT THINGS, and they always did.
|
|
326
|
+
LEFT 8 — the inset a rounded row needs. The reason WAS "a rounded bar
|
|
327
|
+
cannot bleed to a panel edge"; the bars are gone (One Ladder, 2026-09-04)
|
|
328
|
+
and the reason survives them unchanged, because every row in the tree is
|
|
329
|
+
still a rounded control and an inset control is simply a control.
|
|
330
|
+
RIGHT 11 — this element also carries `.sf-scroll`, and
|
|
331
|
+
`.sf-scroll::-webkit-scrollbar` is `width: 11px` of REAL, space-taking
|
|
332
|
+
gutter, not an overlay. This tree scrolls on almost every page. What used
|
|
333
|
+
to live at the row's right end was the caret; it is the count pill now,
|
|
334
|
+
and a count sitting under a scrollbar thumb is the same defect wearing a
|
|
335
|
+
different glyph.
|
|
336
|
+
Everything inside still starts on the same 11px text column, which is what
|
|
337
|
+
keeps the words aligned down the panel. */
|
|
338
|
+
padding: 0 11px 10px 8px;
|
|
339
|
+
|
|
340
|
+
/* ── THE TREE'S RHYTHM — the shell's names, the tree's own density ─────────
|
|
341
|
+
`efficient-easel` 0.19.0 stopped hiding its spacing inside literals and gave
|
|
342
|
+
each rhythm a name (card 66228, `efficient-easel/panel.css`). The tree reads
|
|
343
|
+
those names. It does NOT read the panel's VALUES and does not compute them:
|
|
344
|
+
|
|
345
|
+
· Copying 28/7 in would be a second source of truth for numbers the shell
|
|
346
|
+
is already the source of — the one rule that sits above a green suite.
|
|
347
|
+
· A scale FACTOR off them would be a lie. Lewis picked the tree's two
|
|
348
|
+
numbers by eye on 2026-08-31 (`mockups/layers-panel-v9-left-only-and-drag.html`
|
|
349
|
+
and `editor-add-and-context-v1.html`): 10 between bars, 6 between rows.
|
|
350
|
+
Against the panel that is 10/36 = 0.28 and 6/28 = 0.21 — TWO factors,
|
|
351
|
+
not one, so there is no single number to scale by. `panel.css` already
|
|
352
|
+
refuses this shape for the same reason, in its own words: 28 was
|
|
353
|
+
measured, it is not "10 plus 18".
|
|
354
|
+
|
|
355
|
+
So what is shared is the VOCABULARY and the RULE, not the values: `-group`
|
|
356
|
+
means "a heading, from what is above it" in both panels and `-between`
|
|
357
|
+
means "one row, from the next" in both, each stated once at its own
|
|
358
|
+
density. A tree at the panel's 28px a row would scroll forever.
|
|
359
|
+
|
|
360
|
+
Declared HERE rather than on `.sf-editor` deliberately — the settings panel
|
|
361
|
+
is a sibling reading the same names from the shell, and an override at the
|
|
362
|
+
editor root would re-rhythm IT too. `scripts/test-tree-rhythm-tokens.ts` is
|
|
363
|
+
the gate. */
|
|
364
|
+
--es-rhythm-group: 10px;
|
|
365
|
+
--es-rhythm-between: 6px;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.sf-chip {
|
|
369
|
+
width: 18px;
|
|
370
|
+
height: 18px;
|
|
371
|
+
border-radius: 5px;
|
|
372
|
+
display: flex;
|
|
373
|
+
align-items: center;
|
|
374
|
+
justify-content: center;
|
|
375
|
+
font-size: 12px;
|
|
376
|
+
flex: none;
|
|
377
|
+
/* NO GROUND AND NO RULE. Every row carries a glyph now, so a filled tile on
|
|
378
|
+
each one is 40 tiles down a page — the chip was a way of picking the icon
|
|
379
|
+
row out of a list that mostly had none, and there is no such list any more.
|
|
380
|
+
The glyph itself is the mark; `--sf-icon` is the same grey the top bar's
|
|
381
|
+
icons wear. */
|
|
382
|
+
background: transparent;
|
|
383
|
+
color: var(--sf-icon);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.sf-row-name {
|
|
387
|
+
flex: 1;
|
|
388
|
+
/* One size at every depth — the tree's three (11 / 10.5 / 11.5) were a second
|
|
389
|
+
way of saying the indent already says. 12px/500 is `.es-group-head`'s size
|
|
390
|
+
at a row's weight, so the tree and the inspector's headings agree on how big
|
|
391
|
+
a name in this editor is. */
|
|
392
|
+
font-size: 12px;
|
|
393
|
+
font-weight: 500;
|
|
394
|
+
color: var(--sf-text);
|
|
395
|
+
white-space: nowrap;
|
|
396
|
+
overflow: hidden;
|
|
397
|
+
text-overflow: ellipsis;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/* THE TWO BAR TIERS ARE GONE (One Ladder, 2026-09-04).
|
|
401
|
+
|
|
402
|
+
`.sf-row--bar` (a 1px outline, 11px/600) and `.sf-row--bar-nested` (a
|
|
403
|
+
`color-mix` ground one shade off the panel, 10.5px/600) were how this tree
|
|
404
|
+
said "a level". Both are deleted, and with them the whole question of which
|
|
405
|
+
tier a row belongs to.
|
|
406
|
+
|
|
407
|
+
THE NESTED BAR IS THE ONE WORTH RECORDING. Its own note said it: at ~2% off
|
|
408
|
+
white the fill alone disappears on a cheap panel, so it needed a hairline
|
|
409
|
+
beside the fill to survive. A difference that has to be said twice to be seen
|
|
410
|
+
once is not carrying its weight — and the indent and the subtree's guide line
|
|
411
|
+
were already saying the same thing, legibly, for free.
|
|
412
|
+
|
|
413
|
+
What replaced them is `.sf-subtree` below: an indent and a 1px rule. Nothing
|
|
414
|
+
in this tree is told apart by a fill any more except the SELECTED row, which
|
|
415
|
+
is the one place a fill is not competing with anything. */
|
|
416
|
+
.sf-add-card {
|
|
417
|
+
display: flex;
|
|
418
|
+
align-items: center;
|
|
419
|
+
gap: 8px;
|
|
420
|
+
width: 100%;
|
|
421
|
+
padding: 6px 9px;
|
|
422
|
+
border: none;
|
|
423
|
+
background: transparent;
|
|
424
|
+
border-radius: 8px;
|
|
425
|
+
cursor: pointer;
|
|
426
|
+
color: var(--sf-accent);
|
|
427
|
+
font-size: 12px;
|
|
428
|
+
font-weight: 500;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.sf-add-card:hover {
|
|
432
|
+
background: var(--sf-accent-tint);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.sf-add-card .sf-plus {
|
|
436
|
+
width: 18px;
|
|
437
|
+
height: 18px;
|
|
438
|
+
border-radius: 5px;
|
|
439
|
+
display: flex;
|
|
440
|
+
align-items: center;
|
|
441
|
+
justify-content: center;
|
|
442
|
+
font-size: 13px;
|
|
443
|
+
flex: none;
|
|
444
|
+
background: var(--sf-accent-tint);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/* ── Footer "Add block" menu — heterogeneous block-type picker ──────────── */
|
|
448
|
+
.sf-blockmenu {
|
|
449
|
+
display: flex;
|
|
450
|
+
flex-direction: column;
|
|
451
|
+
gap: 1px;
|
|
452
|
+
margin: 2px 0 4px;
|
|
453
|
+
padding: 4px;
|
|
454
|
+
border: 1px solid var(--sf-line);
|
|
455
|
+
border-radius: 8px;
|
|
456
|
+
background: var(--sf-panel);
|
|
457
|
+
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/* ── Footer "Add block" menu — heterogeneous block-type picker ──────────── */
|
|
461
|
+
.sf-blockmenu-item {
|
|
462
|
+
display: flex;
|
|
463
|
+
align-items: center;
|
|
464
|
+
gap: 8px;
|
|
465
|
+
width: 100%;
|
|
466
|
+
padding: 7px 9px;
|
|
467
|
+
border: none;
|
|
468
|
+
background: transparent;
|
|
469
|
+
border-radius: 6px;
|
|
470
|
+
cursor: pointer;
|
|
471
|
+
color: var(--sf-text, var(--sf-text));
|
|
472
|
+
font-size: 12.5px;
|
|
473
|
+
text-align: left;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/* ── Footer "Add block" menu — heterogeneous block-type picker ──────────── */
|
|
477
|
+
.sf-blockmenu-item:hover {
|
|
478
|
+
background: var(--sf-accent-tint);
|
|
479
|
+
color: var(--sf-accent);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/* ── Footer "Add block" menu — heterogeneous block-type picker ──────────── */
|
|
483
|
+
/* A group heading inside that menu — drawn only where a choice list carries
|
|
484
|
+
groups (a Box's does; the Footer's and the Slide box's do not, and render
|
|
485
|
+
exactly as before).
|
|
486
|
+
|
|
487
|
+
⚠️ THE SAME TYPE AS `.sf-addgroup-title` BELOW, and deliberately not a second
|
|
488
|
+
look: that is the heading the Add-section panel puts over every one of its
|
|
489
|
+
categories, and this menu is the OTHER door a merchant adds something
|
|
490
|
+
through. One grammar for "these belong together" (rule zero). It is not the
|
|
491
|
+
same CLASS because the two live in different boxes — a 4px-padded floating
|
|
492
|
+
menu and a 20px panel column — so only the spacing differs, and it differs
|
|
493
|
+
because the container does.
|
|
494
|
+
|
|
495
|
+
`role="presentation"` on the row: it is a label, not a menuitem, and a
|
|
496
|
+
keyboard user arrowing through the menu must not land on it. */
|
|
497
|
+
.sf-menugroup-head {
|
|
498
|
+
display: flex;
|
|
499
|
+
align-items: baseline;
|
|
500
|
+
gap: 8px;
|
|
501
|
+
padding: 9px 9px 5px;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/* ── Footer "Add block" menu — heterogeneous block-type picker ──────────── */
|
|
505
|
+
/* No top padding on the first heading — the menu's own 4px inset already sets
|
|
506
|
+
it in, and a second inset would leave the first group sitting lower than the
|
|
507
|
+
rows it names. */
|
|
508
|
+
.sf-menugroup-head:first-child {
|
|
509
|
+
padding-top: 4px;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/* ── Footer "Add block" menu — heterogeneous block-type picker ──────────── */
|
|
513
|
+
.sf-menugroup-title {
|
|
514
|
+
font-size: 11px;
|
|
515
|
+
font-weight: 700;
|
|
516
|
+
letter-spacing: 0.07em;
|
|
517
|
+
text-transform: uppercase;
|
|
518
|
+
color: var(--sf-muted);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/* ── Footer "Add block" menu — heterogeneous block-type picker ──────────── */
|
|
522
|
+
.sf-menugroup-count {
|
|
523
|
+
font-size: 11px;
|
|
524
|
+
color: var(--sf-field-placeholder);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/* ── Footer "Add block" menu — heterogeneous block-type picker ──────────── */
|
|
528
|
+
/* ── Add — a mode over the left panel (components/AddSidePanel) ────────────
|
|
529
|
+
Blueprint step 3.7: the floating `.sf-picker` dialog is gone, and Add is the
|
|
530
|
+
left panel's content while it is open. The search, the headed groups and the
|
|
531
|
+
tiles are efficient-easel/drag's `AddPanel` (drag.css); a section is a CARD
|
|
532
|
+
with its cover there (`.es-add-grid.is-cards`). What is the website's alone
|
|
533
|
+
is the panel's inset and the Live chat row under the groups. */
|
|
534
|
+
.sf-addside {
|
|
535
|
+
flex: 1;
|
|
536
|
+
min-height: 0;
|
|
537
|
+
overflow-y: auto;
|
|
538
|
+
padding: 0 14px 16px;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/* ── Footer "Add block" menu — heterogeneous block-type picker ──────────── */
|
|
542
|
+
/* ── Add — a mode over the left panel (components/AddSidePanel) ────────────
|
|
543
|
+
Blueprint step 3.7: the floating `.sf-picker` dialog is gone, and Add is the
|
|
544
|
+
left panel's content while it is open. The search, the headed groups and the
|
|
545
|
+
tiles are efficient-easel/drag's `AddPanel` (drag.css); a section is a CARD
|
|
546
|
+
with its cover there (`.es-add-grid.is-cards`). What is the website's alone
|
|
547
|
+
is the panel's inset and the Live chat row under the groups. */
|
|
548
|
+
/* The hairline round a section's cover — the one the dialog's cards wore
|
|
549
|
+
(`--sf-thumb-thumb-border`'s value). The cover box is a containing block in
|
|
550
|
+
the engine itself since efficient-easel 0.80.1: a scene drawn to fill it
|
|
551
|
+
painted over the whole panel before. */
|
|
552
|
+
.sf-addside .es-add-tile-cover {
|
|
553
|
+
border: 1px solid #edeff4;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/* ── Footer "Add block" menu — heterogeneous block-type picker ──────────── */
|
|
557
|
+
/* ── Add — a mode over the left panel (components/AddSidePanel) ────────────
|
|
558
|
+
Blueprint step 3.7: the floating `.sf-picker` dialog is gone, and Add is the
|
|
559
|
+
left panel's content while it is open. The search, the headed groups and the
|
|
560
|
+
tiles are efficient-easel/drag's `AddPanel` (drag.css); a section is a CARD
|
|
561
|
+
with its cover there (`.es-add-grid.is-cards`). What is the website's alone
|
|
562
|
+
is the panel's inset and the Live chat row under the groups. */
|
|
563
|
+
/* The Media view's body — the HOST's library (lib/media-panel), drawn
|
|
564
|
+
in whatever the panel leaves under the head. It scrolls itself (its grid
|
|
565
|
+
keeps its own toolbar pinned), so this box only hands it the height. */
|
|
566
|
+
.sf-media-panel {
|
|
567
|
+
flex: 1;
|
|
568
|
+
min-height: 0;
|
|
569
|
+
display: flex;
|
|
570
|
+
flex-direction: column;
|
|
571
|
+
overflow: hidden;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/* Toast — transient confirmation (e.g. after adding a section) */
|
|
575
|
+
.sf-toast {
|
|
576
|
+
position: absolute;
|
|
577
|
+
left: 50%;
|
|
578
|
+
bottom: 34px;
|
|
579
|
+
transform: translateX(-50%);
|
|
580
|
+
z-index: 60;
|
|
581
|
+
display: flex;
|
|
582
|
+
align-items: center;
|
|
583
|
+
gap: 10px;
|
|
584
|
+
padding: 11px 17px;
|
|
585
|
+
border-radius: 11px;
|
|
586
|
+
background: var(--sf-toast-bg);
|
|
587
|
+
color: #fff;
|
|
588
|
+
font-size: 13px;
|
|
589
|
+
box-shadow: 0 12px 30px rgba(15, 23, 42, 0.3);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.sf-toast-check {
|
|
593
|
+
display: inline-flex;
|
|
594
|
+
align-items: center;
|
|
595
|
+
justify-content: center;
|
|
596
|
+
width: 18px;
|
|
597
|
+
height: 18px;
|
|
598
|
+
border-radius: 50%;
|
|
599
|
+
background: var(--sf-accent);
|
|
600
|
+
color: #fff;
|
|
601
|
+
font-size: 11px;
|
|
602
|
+
flex: none;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/* Error variant — same dark pill, red mark instead of the green check. */
|
|
606
|
+
.sf-toast--error .sf-toast-check {
|
|
607
|
+
background: var(--sf-danger);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/* ── Center: device-framed preview (wraps Puck.Preview) ──────────────── */
|
|
611
|
+
.sf-center {
|
|
612
|
+
flex: 1;
|
|
613
|
+
min-width: 0;
|
|
614
|
+
min-height: 0;
|
|
615
|
+
background: var(--sf-preview-bg);
|
|
616
|
+
border-radius: var(--sf-panel-radius);
|
|
617
|
+
box-shadow: var(--sf-panel-shadow);
|
|
618
|
+
overflow: hidden;
|
|
619
|
+
display: flex;
|
|
620
|
+
/* `safe center`: centre the device sizer when it fits, but fall back to
|
|
621
|
+
flex-start when a zoom makes it larger than the well, so the near edge
|
|
622
|
+
stays reachable while the well scrolls (overflow-x set inline per-zoom). */
|
|
623
|
+
justify-content: safe center;
|
|
624
|
+
align-items: safe center;
|
|
625
|
+
/* No inset: the preview frame fills the well so it flows flush with the panels
|
|
626
|
+
at exactly the --sf-panel-gap frame gap (the flex gap between panel and this
|
|
627
|
+
well). Any padding here would ADD to that gap. In tablet/mobile the fixed-width
|
|
628
|
+
device frame still centres, showing the well's tint down its sides. */
|
|
629
|
+
padding: 0;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/* ── Center: device-framed preview (wraps Puck.Preview) ──────────────── */
|
|
633
|
+
.sf-frame {
|
|
634
|
+
width: 100%;
|
|
635
|
+
height: 100%;
|
|
636
|
+
max-height: 100%;
|
|
637
|
+
background: var(--sf-frame-bg);
|
|
638
|
+
/* SQUARE (owner, 2026-10-07: "the website should not have round corners").
|
|
639
|
+
The desktop frame fills the well edge to edge and meets the toolbar and the
|
|
640
|
+
panels directly, and those have been flat since 66161 (--sf-panel-radius:
|
|
641
|
+
0) — so a 10px radius here drew one rounded notch, top-left, where the
|
|
642
|
+
page meets the chrome, and clipped that corner of the website itself. The
|
|
643
|
+
tablet and phone frames below are square for the same reason (owner, the
|
|
644
|
+
same day): their 18px radius read as a device's edge, and it clipped all
|
|
645
|
+
four corners of the page inside. They are told apart from the well by their
|
|
646
|
+
width and their outline, not by a corner. */
|
|
647
|
+
border-radius: 0;
|
|
648
|
+
overflow: hidden;
|
|
649
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 12px 36px rgba(0, 0, 0, 0.1);
|
|
650
|
+
transition: width 0.25s ease;
|
|
651
|
+
display: flex;
|
|
652
|
+
flex-direction: column;
|
|
653
|
+
min-height: 0;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/* ── Center: device-framed preview (wraps Puck.Preview) ──────────────── */
|
|
657
|
+
/* Sizer box for the device frame: its layout size is the frame's *painted*
|
|
658
|
+
(scaled) size, so the .sf-center well centres it when it fits and scrolls it
|
|
659
|
+
when a zoom makes it larger. The frame inside is scaled from its top-left. */
|
|
660
|
+
.sf-frame-scaler {
|
|
661
|
+
flex: none;
|
|
662
|
+
position: relative;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/* The template editor's faux browser bar (dots · page switcher · URL ·
|
|
666
|
+
"Preview mode" toggle) is gone: pages switch from the shared left Pages
|
|
667
|
+
panel, the URL is drawn by the editor WINDOW's title bar (the admin console
|
|
668
|
+
owns that chrome; card 66159), and Preview mode was removed — the canvas
|
|
669
|
+
meets the toolbar directly in both modes. */
|
|
670
|
+
.sf-preview-host {
|
|
671
|
+
flex: 1;
|
|
672
|
+
min-height: 0;
|
|
673
|
+
position: relative;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/* Puck.Preview fills the frame */
|
|
677
|
+
.sf-preview-host > div,
|
|
678
|
+
.sf-preview-host iframe {
|
|
679
|
+
width: 100% !important;
|
|
680
|
+
height: 100% !important;
|
|
681
|
+
border: 0;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/* …but `height: 100%` only means anything when the host's OWN height is
|
|
685
|
+
definite, and that depends on which shell mounted it.
|
|
686
|
+
|
|
687
|
+
The page editor wraps the host in `.sf-frame` — a column flex the chrome
|
|
688
|
+
sizes in pixels (`frameStyle`/`scalerStyle` in ScreenChrome) — so
|
|
689
|
+
the host's `flex: 1` above resolves against a real number and the rule works.
|
|
690
|
+
|
|
691
|
+
The SECTION editor has no device switch, so it drops the host straight into
|
|
692
|
+
the `.sf-center` well (SectionScreenShell). That well is a ROW flex with
|
|
693
|
+
`align-items: safe center`: the host is centred on the cross axis instead of
|
|
694
|
+
stretched, so its height stays `auto`. `height: 100%` then has no definite
|
|
695
|
+
containing block, the iframe falls back to its intrinsic 150px, and a
|
|
696
|
+
`100vh`/`h-screen` section inside the frame measures the viewport as 150px —
|
|
697
|
+
which is how a full-bleed Hero came out as a thin band floating mid-canvas.
|
|
698
|
+
|
|
699
|
+
Stretching the host restores a definite height, so the frame's viewport IS
|
|
700
|
+
the canvas. Scoped to the direct child so the page editor, whose host is a
|
|
701
|
+
child of `.sf-frame`, is untouched. */
|
|
702
|
+
.sf-center > .sf-preview-host {
|
|
703
|
+
align-self: stretch;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/* ── Canvas "Add section" seams (overlay between preview sections) ──────────
|
|
707
|
+
Absolutely positioned over .sf-preview-host (the iframe's box), one band per
|
|
708
|
+
seam between top-level sections, placed at the boundary Y measured from the
|
|
709
|
+
live iframe. The container ignores pointer events so the canvas stays
|
|
710
|
+
interactive; only the slim bands are clickable. On hover a band shows an accent
|
|
711
|
+
insertion line + a dark "Add section" pill; clicking opens the picker targeted
|
|
712
|
+
at that seam. It sits inside the scaled device frame, so it tracks the zoom. */
|
|
713
|
+
.sf-preview-gaps {
|
|
714
|
+
position: absolute;
|
|
715
|
+
inset: 0;
|
|
716
|
+
overflow: hidden;
|
|
717
|
+
pointer-events: none;
|
|
718
|
+
z-index: 6;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/* ── Canvas "Add section" seams (overlay between preview sections) ──────────
|
|
722
|
+
Absolutely positioned over .sf-preview-host (the iframe's box), one band per
|
|
723
|
+
seam between top-level sections, placed at the boundary Y measured from the
|
|
724
|
+
live iframe. The container ignores pointer events so the canvas stays
|
|
725
|
+
interactive; only the slim bands are clickable. On hover a band shows an accent
|
|
726
|
+
insertion line + a dark "Add section" pill; clicking opens the picker targeted
|
|
727
|
+
at that seam. It sits inside the scaled device frame, so it tracks the zoom. */
|
|
728
|
+
/* The full-width band only POSITIONS the affordance over a seam — it is itself
|
|
729
|
+
click-through (pointer-events:none) so it never steals canvas clicks / Puck
|
|
730
|
+
selection near a section boundary. Only the centred pill is interactive. */
|
|
731
|
+
.sf-preview-gap {
|
|
732
|
+
position: absolute;
|
|
733
|
+
left: 0;
|
|
734
|
+
right: 0;
|
|
735
|
+
height: 24px;
|
|
736
|
+
transform: translateY(-50%);
|
|
737
|
+
display: flex;
|
|
738
|
+
align-items: center;
|
|
739
|
+
justify-content: center;
|
|
740
|
+
padding: 0;
|
|
741
|
+
border: 0;
|
|
742
|
+
background: transparent;
|
|
743
|
+
pointer-events: none;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/* ── Canvas "Add section" seams (overlay between preview sections) ──────────
|
|
747
|
+
Absolutely positioned over .sf-preview-host (the iframe's box), one band per
|
|
748
|
+
seam between top-level sections, placed at the boundary Y measured from the
|
|
749
|
+
live iframe. The container ignores pointer events so the canvas stays
|
|
750
|
+
interactive; only the slim bands are clickable. On hover a band shows an accent
|
|
751
|
+
insertion line + a dark "Add section" pill; clicking opens the picker targeted
|
|
752
|
+
at that seam. It sits inside the scaled device frame, so it tracks the zoom. */
|
|
753
|
+
.sf-preview-gap-line {
|
|
754
|
+
position: absolute;
|
|
755
|
+
left: 0;
|
|
756
|
+
right: 0;
|
|
757
|
+
top: 50%;
|
|
758
|
+
height: 2px;
|
|
759
|
+
transform: translateY(-50%);
|
|
760
|
+
background: var(--sf-accent);
|
|
761
|
+
opacity: 0;
|
|
762
|
+
pointer-events: none;
|
|
763
|
+
transition: opacity 0.12s;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
/* ── Canvas "Add section" seams (overlay between preview sections) ──────────
|
|
767
|
+
Absolutely positioned over .sf-preview-host (the iframe's box), one band per
|
|
768
|
+
seam between top-level sections, placed at the boundary Y measured from the
|
|
769
|
+
live iframe. The container ignores pointer events so the canvas stays
|
|
770
|
+
interactive; only the slim bands are clickable. On hover a band shows an accent
|
|
771
|
+
insertion line + a dark "Add section" pill; clicking opens the picker targeted
|
|
772
|
+
at that seam. It sits inside the scaled device frame, so it tracks the zoom. */
|
|
773
|
+
/* The only clickable element: a compact "+" chip that is hidden at rest and
|
|
774
|
+
fades in on hover, expanding to the full "Add section" pill. Keeping it
|
|
775
|
+
invisible until hovered means the canvas carries no persistent affordance,
|
|
776
|
+
while the dead zone stays no larger than this small chip (opacity:0 still
|
|
777
|
+
hit-tests, so the seam remains hoverable). */
|
|
778
|
+
.sf-preview-gap-pill {
|
|
779
|
+
position: relative;
|
|
780
|
+
display: inline-flex;
|
|
781
|
+
align-items: center;
|
|
782
|
+
padding: 4px;
|
|
783
|
+
border-radius: 999px;
|
|
784
|
+
background: var(--sf-toast-bg);
|
|
785
|
+
color: #fff;
|
|
786
|
+
font-family: var(--sf-font);
|
|
787
|
+
font-size: 12px;
|
|
788
|
+
font-weight: 500;
|
|
789
|
+
white-space: nowrap;
|
|
790
|
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.28);
|
|
791
|
+
opacity: 0;
|
|
792
|
+
cursor: pointer;
|
|
793
|
+
pointer-events: auto;
|
|
794
|
+
transition: opacity 0.12s, padding 0.12s;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/* ── Canvas "Add section" seams (overlay between preview sections) ──────────
|
|
798
|
+
Absolutely positioned over .sf-preview-host (the iframe's box), one band per
|
|
799
|
+
seam between top-level sections, placed at the boundary Y measured from the
|
|
800
|
+
live iframe. The container ignores pointer events so the canvas stays
|
|
801
|
+
interactive; only the slim bands are clickable. On hover a band shows an accent
|
|
802
|
+
insertion line + a dark "Add section" pill; clicking opens the picker targeted
|
|
803
|
+
at that seam. It sits inside the scaled device frame, so it tracks the zoom. */
|
|
804
|
+
.sf-preview-gap-pill:hover {
|
|
805
|
+
opacity: 1;
|
|
806
|
+
padding: 4px 12px 4px 4px;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/* ── Canvas "Add section" seams (overlay between preview sections) ──────────
|
|
810
|
+
Absolutely positioned over .sf-preview-host (the iframe's box), one band per
|
|
811
|
+
seam between top-level sections, placed at the boundary Y measured from the
|
|
812
|
+
live iframe. The container ignores pointer events so the canvas stays
|
|
813
|
+
interactive; only the slim bands are clickable. On hover a band shows an accent
|
|
814
|
+
insertion line + a dark "Add section" pill; clicking opens the picker targeted
|
|
815
|
+
at that seam. It sits inside the scaled device frame, so it tracks the zoom. */
|
|
816
|
+
.sf-preview-gap-plus {
|
|
817
|
+
display: inline-flex;
|
|
818
|
+
align-items: center;
|
|
819
|
+
justify-content: center;
|
|
820
|
+
width: 18px;
|
|
821
|
+
height: 18px;
|
|
822
|
+
border-radius: 50%;
|
|
823
|
+
background: var(--sf-accent);
|
|
824
|
+
color: #fff;
|
|
825
|
+
font-size: 13px;
|
|
826
|
+
line-height: 1;
|
|
827
|
+
flex: none;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/* ── Canvas "Add section" seams (overlay between preview sections) ──────────
|
|
831
|
+
Absolutely positioned over .sf-preview-host (the iframe's box), one band per
|
|
832
|
+
seam between top-level sections, placed at the boundary Y measured from the
|
|
833
|
+
live iframe. The container ignores pointer events so the canvas stays
|
|
834
|
+
interactive; only the slim bands are clickable. On hover a band shows an accent
|
|
835
|
+
insertion line + a dark "Add section" pill; clicking opens the picker targeted
|
|
836
|
+
at that seam. It sits inside the scaled device frame, so it tracks the zoom. */
|
|
837
|
+
/* Label collapsed until hover so the resting chip is just the "+". */
|
|
838
|
+
.sf-preview-gap-label {
|
|
839
|
+
max-width: 0;
|
|
840
|
+
margin-left: 0;
|
|
841
|
+
overflow: hidden;
|
|
842
|
+
opacity: 0;
|
|
843
|
+
transition: max-width 0.14s, margin-left 0.14s, opacity 0.12s;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/* ── Canvas "Add section" seams (overlay between preview sections) ──────────
|
|
847
|
+
Absolutely positioned over .sf-preview-host (the iframe's box), one band per
|
|
848
|
+
seam between top-level sections, placed at the boundary Y measured from the
|
|
849
|
+
live iframe. The container ignores pointer events so the canvas stays
|
|
850
|
+
interactive; only the slim bands are clickable. On hover a band shows an accent
|
|
851
|
+
insertion line + a dark "Add section" pill; clicking opens the picker targeted
|
|
852
|
+
at that seam. It sits inside the scaled device frame, so it tracks the zoom. */
|
|
853
|
+
.sf-preview-gap-pill:hover .sf-preview-gap-label {
|
|
854
|
+
max-width: 140px;
|
|
855
|
+
margin-left: 6px;
|
|
856
|
+
opacity: 1;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/* ── Canvas "Add section" seams (overlay between preview sections) ──────────
|
|
860
|
+
Absolutely positioned over .sf-preview-host (the iframe's box), one band per
|
|
861
|
+
seam between top-level sections, placed at the boundary Y measured from the
|
|
862
|
+
live iframe. The container ignores pointer events so the canvas stays
|
|
863
|
+
interactive; only the slim bands are clickable. On hover a band shows an accent
|
|
864
|
+
insertion line + a dark "Add section" pill; clicking opens the picker targeted
|
|
865
|
+
at that seam. It sits inside the scaled device frame, so it tracks the zoom. */
|
|
866
|
+
.sf-preview-gap:has(.sf-preview-gap-pill:hover) .sf-preview-gap-line {
|
|
867
|
+
opacity: 1;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
.sf-msg {
|
|
871
|
+
padding: 24px;
|
|
872
|
+
font-size: 13px;
|
|
873
|
+
color: var(--sf-icon);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
.sf-msg--error {
|
|
877
|
+
color: var(--sf-danger);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/* ── The icon rail: the shared editor-shell EaselRail (`.es-rail`) ───────────
|
|
881
|
+
The rail markup + base styles live in the `efficient-easel` package (imported via
|
|
882
|
+
`efficient-easel/rail.css`); the storefront no longer hand-rolls `.sf-rail`.
|
|
883
|
+
editor-shell ships its own defaults, so we remap the themeable `--es-rail-*`
|
|
884
|
+
custom properties onto the storefront's own `--sf-*` tokens, which is what
|
|
885
|
+
keeps the shared rail reading as this editor's chrome rather than as the
|
|
886
|
+
package's. (One mode only — the editor is deliberately light-only; see the
|
|
887
|
+
note at the top of this file.)
|
|
888
|
+
Scoped `.sf-editor .es-rail` (specificity 0,2,0) so it always beats rail.css's
|
|
889
|
+
base `.es-rail` (0,1,0) whatever order the two stylesheets load in.
|
|
890
|
+
|
|
891
|
+
THREE TOKENS ARE DELIBERATELY NOT REMAPPED HERE, and each absence is load-
|
|
892
|
+
bearing since card 66198 laid the rail into the top bar as a row:
|
|
893
|
+
|
|
894
|
+
--es-rail-w only the COLUMN reads it (`.es-rail { width:
|
|
895
|
+
var(--es-rail-w) }`); the row is `width: auto` and sizes
|
|
896
|
+
to its buttons, so a remap would be config nothing reads.
|
|
897
|
+
--es-rail-bg the row variant re-points these to transparent / none / 0
|
|
898
|
+
--es-rail-shadow ON PURPOSE: the bar already has its own surface, and a
|
|
899
|
+
--es-rail-radius second white card floating inside it is the bug. This
|
|
900
|
+
rule ties with `.es-rail.es-rail-row` on specificity
|
|
901
|
+
(0,2,0 both), so setting them here would silently WIN
|
|
902
|
+
and put that card back. The rail's surface is the bar's.
|
|
903
|
+
|
|
904
|
+
Everything left below is colour the row variant does not touch. */
|
|
905
|
+
.sf-editor .es-rail {
|
|
906
|
+
--es-rail-fg: var(--sf-muted);
|
|
907
|
+
--es-rail-hover-bg: var(--sf-hover);
|
|
908
|
+
--es-rail-hover-fg: var(--sf-text);
|
|
909
|
+
--es-rail-accent: var(--sf-accent);
|
|
910
|
+
--es-rail-accent-tint: var(--sf-accent-tint);
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
/* ── The icon rail: the shared editor-shell EaselRail (`.es-rail`) ───────────
|
|
914
|
+
The rail markup + base styles live in the `efficient-easel` package (imported via
|
|
915
|
+
`efficient-easel/rail.css`); the storefront no longer hand-rolls `.sf-rail`.
|
|
916
|
+
editor-shell ships its own defaults, so we remap the themeable `--es-rail-*`
|
|
917
|
+
custom properties onto the storefront's own `--sf-*` tokens, which is what
|
|
918
|
+
keeps the shared rail reading as this editor's chrome rather than as the
|
|
919
|
+
package's. (One mode only — the editor is deliberately light-only; see the
|
|
920
|
+
note at the top of this file.)
|
|
921
|
+
Scoped `.sf-editor .es-rail` (specificity 0,2,0) so it always beats rail.css's
|
|
922
|
+
base `.es-rail` (0,1,0) whatever order the two stylesheets load in.
|
|
923
|
+
|
|
924
|
+
THREE TOKENS ARE DELIBERATELY NOT REMAPPED HERE, and each absence is load-
|
|
925
|
+
bearing since card 66198 laid the rail into the top bar as a row:
|
|
926
|
+
|
|
927
|
+
--es-rail-w only the COLUMN reads it (`.es-rail { width:
|
|
928
|
+
var(--es-rail-w) }`); the row is `width: auto` and sizes
|
|
929
|
+
to its buttons, so a remap would be config nothing reads.
|
|
930
|
+
--es-rail-bg the row variant re-points these to transparent / none / 0
|
|
931
|
+
--es-rail-shadow ON PURPOSE: the bar already has its own surface, and a
|
|
932
|
+
--es-rail-radius second white card floating inside it is the bug. This
|
|
933
|
+
rule ties with `.es-rail.es-rail-row` on specificity
|
|
934
|
+
(0,2,0 both), so setting them here would silently WIN
|
|
935
|
+
and put that card back. The rail's surface is the bar's.
|
|
936
|
+
|
|
937
|
+
Everything left below is colour the row variant does not touch. */
|
|
938
|
+
/* THE RAIL COLUMN (owner, 2026-09-04: "the top control panel and the panel
|
|
939
|
+
below it" must read as one) — the cluster exactly the left panel's width,
|
|
940
|
+
carrying its hairline up through the bar, the buttons spread across it (his
|
|
941
|
+
option A, spread evenly), and the arrow under the open panel's icon — is editor-shell's
|
|
942
|
+
`.es-cluster--rail` (efficient-easel/chrome.css), lifted from this sheet with its
|
|
943
|
+
`flex: none` and its clip-path triangle (redesign 2a). ⚠️ `MIN_PANEL_W` 220 is
|
|
944
|
+
still load-bearing on it: six 34px buttons fill 204 exactly, and a SEVENTH
|
|
945
|
+
rail button does not fit at 220. `scripts/test-editor-rail-in-topbar.ts`
|
|
946
|
+
holds that arithmetic. */
|
|
947
|
+
/* The "+" is a plain character in a rail button, the way it was a plain
|
|
948
|
+
character in the toolbar button it replaces — every other "+" affordance in
|
|
949
|
+
this editor is one (`.sf-gap-plus`, `.sf-addcard-plus`, `.sf-plus`). The rail
|
|
950
|
+
sizes SVGs and has nothing to say about text, so its one line is here. */
|
|
951
|
+
.sf-rail-plus {
|
|
952
|
+
font-size: 20px;
|
|
953
|
+
line-height: 1;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/* ── NO DIVIDER HAIRLINES IN THIS PANEL (card 66334) ──────────────────────────
|
|
957
|
+
The owner asked for these lines to go twice. Deleting our own was only part of
|
|
958
|
+
it: the rule below is drawn by a PACKAGE, it is the majority of what is
|
|
959
|
+
actually on screen, and it cannot be deleted from here.
|
|
960
|
+
|
|
961
|
+
Puck rules the gap between every pair of top-level fields, so it draws once
|
|
962
|
+
per field for the whole panel — 28 lines in a single section panel, measured.
|
|
963
|
+
That is most of the panel's lines on its own, which is why removing the shop's
|
|
964
|
+
own two heading rules (card 66300) did not change what he saw.
|
|
965
|
+
|
|
966
|
+
⚠️ THERE WERE TWO OF THESE, AND THE OTHER ONE IS GONE. The shell drew
|
|
967
|
+
`.es-drill + .es-drill`, 16 more lines between the rows that list a section's
|
|
968
|
+
text parts. It was held here under a written expiry, because a rule that lives
|
|
969
|
+
in another repo could not be reached from this one. editor-shell 0.29.0 (card
|
|
970
|
+
66350) deleted it AT SOURCE and card 66351 deleted this repo's copy with it —
|
|
971
|
+
the ending the Puck rule below cannot have, since `@measured/puck` is not ours
|
|
972
|
+
to change. That seam is now held from both ends by
|
|
973
|
+
`scripts/test-drill-rows-separated-by-air.ts`: it fails if the shell starts
|
|
974
|
+
drawing on it again, and it fails if a local override for it reappears here.
|
|
975
|
+
|
|
976
|
+
⚠️ SPECIFICITY, NOT `!important`. Puck's rule is (0,3,0) —
|
|
977
|
+
`wrapFields field + field` — so this restates all three parts to match it, and
|
|
978
|
+
wins on order: `storefront-editor.css` is imported after `puck.css` and after
|
|
979
|
+
`panel.css` at every call site. The `[class*=]` form is this file's existing
|
|
980
|
+
idiom for Puck's hashed module names (see the three rules above); a bare class
|
|
981
|
+
would break on the next Puck bump, silently, by putting the lines back.
|
|
982
|
+
|
|
983
|
+
This is an override of a live upstream rule, not dead code:
|
|
984
|
+
`scripts/test-panel-no-divider-lines.tsx` §2 asserts the upstream rule still
|
|
985
|
+
exists before checking it, so if Puck ever drops its own line, the guard says
|
|
986
|
+
to delete the override rather than leave it lying here — which is exactly what
|
|
987
|
+
happened to the drill one above. */
|
|
988
|
+
/* The one line that says WHICH device's settings are on screen. Quiet on
|
|
989
|
+
purpose — it sits above every group, so it earns its space by being read once
|
|
990
|
+
and then ignored. Hidden entirely on desktop, the resting state.
|
|
991
|
+
|
|
992
|
+
It is a SCOPE banner, not a note (card 66121): it does not explain, it says
|
|
993
|
+
what the panel below it is showing, and it is tinted so it reads as a state.
|
|
994
|
+
Nor is it one of this file's chips — those are all small square glyph holders
|
|
995
|
+
(.sf-chip, .sf-insp-chip) or a colour swatch (.sf-readability-chip); this is
|
|
996
|
+
a full-width strip, so it keeps its own rule. */
|
|
997
|
+
.sf-device-scope {
|
|
998
|
+
margin: 8px 0 2px;
|
|
999
|
+
padding: 7px 10px;
|
|
1000
|
+
border-radius: 7px;
|
|
1001
|
+
background: var(--sf-chip-bg);
|
|
1002
|
+
font-size: 11.5px;
|
|
1003
|
+
line-height: 1.35;
|
|
1004
|
+
color: var(--sf-muted);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
/* ─── The strip needs a parent with a WIDTH (card 66248) ──────────────────────
|
|
1008
|
+
The shared strip is `efficient-easel`'s `SettingsSegmented` now, and its outer
|
|
1009
|
+
box `.es-segs-fit` is `container-type: inline-size` — so it takes its inline
|
|
1010
|
+
size FROM its parent and contributes NOTHING to it. `HeaderSettingsPanel`'s
|
|
1011
|
+
`Field` puts the control in a `flex-shrink-0` div, which sizes TO its content.
|
|
1012
|
+
|
|
1013
|
+
A parent sizing to a child that sizes to its parent resolves to ZERO. Measured
|
|
1014
|
+
in a real browser at both panel widths: control 0px, strip 0px, every word
|
|
1015
|
+
clamped to `max-width: 0`, and each button reduced to its own 16px of padding.
|
|
1016
|
+
Seven rows drew a label and no control, and every automated gate we own was
|
|
1017
|
+
green over it — a zero-width box is present in every tree walk and absent to
|
|
1018
|
+
every merchant. Forcing `container-type: normal` restores the strip to
|
|
1019
|
+
104.37px, which is what says the containment is the cause and not a symptom.
|
|
1020
|
+
|
|
1021
|
+
THE RULE HAS TO SIT ABOVE THE CONTAINMENT, so this is not something the strip
|
|
1022
|
+
or a wrapper inside it can fix — a child cannot bootstrap width from a parent
|
|
1023
|
+
that has none. Measured: a full-width wrapper INSIDE the control div leaves
|
|
1024
|
+
all three at 0.
|
|
1025
|
+
|
|
1026
|
+
`:has()` KEEPS IT OFF THE ROWS THIS CARD DID NOT MOVE. `Field`'s control div
|
|
1027
|
+
also carries switches and selects, which ride the LABEL line by card 8801's
|
|
1028
|
+
deliberate design — that is what lets a 308px panel show four settings instead
|
|
1029
|
+
of three. Matching only a control div that actually contains a strip leaves
|
|
1030
|
+
them exactly as they were. Not a new dependency: `efficient-easel`'s own
|
|
1031
|
+
`panel.css` uses `:has()` three times, so the package this panel renders
|
|
1032
|
+
already requires it.
|
|
1033
|
+
|
|
1034
|
+
FULL WIDTH IS THE HOUSE SHAPE, not a compromise — `efficient-easel`'s
|
|
1035
|
+
`SettingsField` stacks its own rows for the same reason ("a 308px panel cannot
|
|
1036
|
+
afford a label column AND a usable slider"). The label moves above the strip
|
|
1037
|
+
and the strip takes the body's width. Scoped to `.sf-panel` because
|
|
1038
|
+
`.flex-shrink-0` is a Tailwind utility used in seven other files, and none of
|
|
1039
|
+
them is this panel. */
|
|
1040
|
+
.sf-panel .flex-shrink-0:has(.es-segs-fit) {
|
|
1041
|
+
flex-basis: 100%;
|
|
1042
|
+
min-width: 0;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
/* ── Side panel heads (components/SidePanelHead) ─────────────────────────
|
|
1046
|
+
Every side panel's head is efficient-easel's `InspectorHead`; these two
|
|
1047
|
+
are the pieces the website editor adds to it. The hairline parts a panel's
|
|
1048
|
+
own tools from the hide button that ends every head, and a mode's way out
|
|
1049
|
+
is a word ("Done", "Cancel") on the engine's ghost button, drawn to the
|
|
1050
|
+
28px of the head's icon buttons so the row keeps one height. */
|
|
1051
|
+
.sf-head-divider {
|
|
1052
|
+
width: 1px;
|
|
1053
|
+
height: 16px;
|
|
1054
|
+
margin: 0 4px;
|
|
1055
|
+
background: var(--sf-line);
|
|
1056
|
+
flex: none;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
/* ── Side panel heads (components/SidePanelHead) ─────────────────────────
|
|
1060
|
+
Every side panel's head is efficient-easel's `InspectorHead`; these two
|
|
1061
|
+
are the pieces the website editor adds to it. The hairline parts a panel's
|
|
1062
|
+
own tools from the hide button that ends every head, and a mode's way out
|
|
1063
|
+
is a word ("Done", "Cancel") on the engine's ghost button, drawn to the
|
|
1064
|
+
28px of the head's icon buttons so the row keeps one height. */
|
|
1065
|
+
.es-btn-ghost.sf-head-textbtn {
|
|
1066
|
+
height: 28px;
|
|
1067
|
+
padding: 0 10px;
|
|
1068
|
+
font-size: 12.5px;
|
|
1069
|
+
border-radius: 7px;
|
|
1070
|
+
white-space: nowrap;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
/* ── Side panel heads (components/SidePanelHead) ─────────────────────────
|
|
1074
|
+
Every side panel's head is efficient-easel's `InspectorHead`; these two
|
|
1075
|
+
are the pieces the website editor adds to it. The hairline parts a panel's
|
|
1076
|
+
own tools from the hide button that ends every head, and a mode's way out
|
|
1077
|
+
is a word ("Done", "Cancel") on the engine's ghost button, drawn to the
|
|
1078
|
+
28px of the head's icon buttons so the row keeps one height. */
|
|
1079
|
+
/* A hidden side panel's strip (components/SidePanelHead `PanelShowStrip`):
|
|
1080
|
+
one Show panel button where the panel was. It IS a side panel — the
|
|
1081
|
+
engine's `.es-sidepanel--left|right` gives it the panels' ground and the
|
|
1082
|
+
hairline on the seam side — only 40px wide, its button level with the
|
|
1083
|
+
heads' buttons (the head's 12px top padding, a 28px button). */
|
|
1084
|
+
.es-sidepanel.sf-panel-strip {
|
|
1085
|
+
width: 40px;
|
|
1086
|
+
align-items: center;
|
|
1087
|
+
padding-top: 12px;
|
|
1088
|
+
}
|