bedrock-flows 0.7.1
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/auth-schema.sql +8 -0
- package/bin/bedrock-flows.mjs +127 -0
- package/lib/setup.mjs +262 -0
- package/package.json +11 -0
- package/template/.storybook/main.js +46 -0
- package/template/.storybook/manager-head.html +963 -0
- package/template/.storybook/preview-head.html +35 -0
- package/template/.storybook/preview.js +23 -0
- package/template/CHANGELOG.md +236 -0
- package/template/README.md +26 -0
- package/template/apps/dashboard/index.html +15 -0
- package/template/apps/dashboard/package.json +22 -0
- package/template/apps/dashboard/src/App.module.css +1318 -0
- package/template/apps/dashboard/src/App.tsx +2716 -0
- package/template/apps/dashboard/src/auth-client.ts +17 -0
- package/template/apps/dashboard/src/changelog.tsx +92 -0
- package/template/apps/dashboard/src/index.css +86 -0
- package/template/apps/dashboard/src/main.tsx +15 -0
- package/template/apps/dashboard/src/theme.ts +31 -0
- package/template/apps/dashboard/src/vite-env.d.ts +4 -0
- package/template/apps/dashboard/vite.config.ts +48 -0
- package/template/apps/worker/.dev.vars.example +50 -0
- package/template/apps/worker/package.json +19 -0
- package/template/apps/worker/src/index.ts +295 -0
- package/template/apps/worker/tsconfig.json +11 -0
- package/template/apps/worker/wrangler.jsonc +29 -0
- package/template/bedrock.config.ts +16 -0
- package/template/design-system/README.md +97 -0
- package/template/design-system/starter-v1/components/button/component.css +42 -0
- package/template/design-system/starter-v1/components/button/danger.html +21 -0
- package/template/design-system/starter-v1/components/button/default.html +21 -0
- package/template/design-system/starter-v1/components/button/disabled.html +21 -0
- package/template/design-system/starter-v1/components/button/ghost.html +21 -0
- package/template/design-system/starter-v1/components/button/macro.njk +14 -0
- package/template/design-system/starter-v1/components/button/primary.html +21 -0
- package/template/design-system/starter-v1/components/button/variants.json +30 -0
- package/template/design-system/starter-v1/ds.json +3 -0
- package/template/design-system/starter-v1/global.css +52 -0
- package/template/design-system/starter-v1/style.css +107 -0
- package/template/gitignore +8 -0
- package/template/package.json +41 -0
- package/template/prototypes/F-001-hello/1-welcome.njk +30 -0
- package/template/prototypes/F-001-hello/2-form.njk +46 -0
- package/template/prototypes/F-001-hello/3-done.njk +29 -0
- package/template/prototypes/F-001-hello/meta.json +6 -0
- package/template/prototypes/_shared/_auth-gate.njk +54 -0
- package/template/prototypes/_shared/delivery.njk +43 -0
- package/template/prototypes/_shared/layout.njk +15 -0
- package/template/prototypes/_shared/screen.njk +1818 -0
- package/template/prototypes/_shared/wireflow.njk +4731 -0
- package/template/public/auth-gate.css +150 -0
- package/template/public/bedrock/color-inspector.js +284 -0
- package/template/public/bedrock/component-overlay.js +219 -0
- package/template/public/bedrock/data/bedrock-config.js +45 -0
- package/template/public/bedrock/font-size-overlay.js +590 -0
- package/template/public/bedrock/grid-overlay.js +379 -0
- package/template/public/bedrock/prototype-navigation.js +974 -0
- package/template/public/cmdk.js +146 -0
- package/template/public/ds-xray.css +112 -0
- package/template/public/ds-xray.js +271 -0
- package/template/public/favicon.svg +4 -0
- package/template/public/icons/bolt-fill.svg +3 -0
- package/template/public/icons/bolt.svg +3 -0
- package/template/public/icons/caret-down-fill.svg +3 -0
- package/template/public/icons/check-double.svg +4 -0
- package/template/public/icons/check.svg +3 -0
- package/template/public/icons/chevron-left.svg +3 -0
- package/template/public/icons/chevron-right.svg +3 -0
- package/template/public/icons/circle-info.svg +6 -0
- package/template/public/icons/grid.svg +6 -0
- package/template/public/icons/message-square-1.svg +3 -0
- package/template/public/icons/message-square.svg +3 -0
- package/template/public/icons/messages.svg +4 -0
- package/template/public/icons/options-horizontal.svg +5 -0
- package/template/public/icons/swatches.svg +6 -0
- package/template/public/icons/workflow.svg +6 -0
- package/template/public/lightbox.js +87 -0
- package/template/public/proto-chrome.css +596 -0
- package/template/public/screen-comments.css +723 -0
- package/template/public/wireflow-client.js +26 -0
- package/template/scripts/build-storybooks.mjs +8 -0
- package/template/scripts/dev-setup.mjs +15 -0
- package/template/scripts/generate-stories.mjs +12 -0
- package/template/scripts/generate-variants.mjs +22 -0
- package/template/tsconfig.base.json +19 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grid Overlay
|
|
3
|
+
*
|
|
4
|
+
* Two modes:
|
|
5
|
+
* 1. Column Grid (Ctrl+Shift+G) — 12-column layout grid, 1440px centered, 40px margin, 24px gutter
|
|
6
|
+
* 2. Section Spacing (Ctrl+Shift+H) — visualizes vertical gaps between direct children of <main>
|
|
7
|
+
*
|
|
8
|
+
* State is persisted in localStorage.
|
|
9
|
+
*/
|
|
10
|
+
(function() {
|
|
11
|
+
const STORAGE_KEY_COL = 'gridOverlayEnabled';
|
|
12
|
+
const STORAGE_KEY_SPACING = 'sectionSpacingEnabled';
|
|
13
|
+
const COL_OVERLAY_ID = 'grid-overlay';
|
|
14
|
+
const TOAST_ID = 'grid-overlay-toast';
|
|
15
|
+
|
|
16
|
+
const GRID_WIDTH = 1440;
|
|
17
|
+
const COLUMNS = 12;
|
|
18
|
+
const MARGIN = 40;
|
|
19
|
+
const GUTTER = 24;
|
|
20
|
+
|
|
21
|
+
let colEnabled = false;
|
|
22
|
+
let spacingEnabled = false;
|
|
23
|
+
let colOverlay = null;
|
|
24
|
+
let spacingMarkers = [];
|
|
25
|
+
|
|
26
|
+
// Returns the main content container (proto-nav wrapper or body)
|
|
27
|
+
function getContainer() {
|
|
28
|
+
return document.getElementById('protoSiteWrapper') || document.body;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Returns the scroll offset of the content container
|
|
32
|
+
function getScrollTop() {
|
|
33
|
+
const wrapper = document.getElementById('protoSiteWrapper');
|
|
34
|
+
return wrapper ? wrapper.scrollTop : window.scrollY;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// --- Styles ---
|
|
38
|
+
function injectStyles() {
|
|
39
|
+
if (document.getElementById('grid-overlay-styles')) return;
|
|
40
|
+
const style = document.createElement('style');
|
|
41
|
+
style.id = 'grid-overlay-styles';
|
|
42
|
+
style.textContent = `
|
|
43
|
+
#${COL_OVERLAY_ID} {
|
|
44
|
+
position: absolute;
|
|
45
|
+
top: 0;
|
|
46
|
+
left: 50%;
|
|
47
|
+
transform: translateX(-50%);
|
|
48
|
+
width: ${GRID_WIDTH}px;
|
|
49
|
+
max-width: 100%;
|
|
50
|
+
min-height: 100%;
|
|
51
|
+
pointer-events: none;
|
|
52
|
+
z-index: 99989;
|
|
53
|
+
display: flex;
|
|
54
|
+
align-items: flex-start;
|
|
55
|
+
padding: 0 ${MARGIN}px;
|
|
56
|
+
box-sizing: border-box;
|
|
57
|
+
gap: ${GUTTER}px;
|
|
58
|
+
}
|
|
59
|
+
#${COL_OVERLAY_ID} .grid-overlay__column {
|
|
60
|
+
flex: 1;
|
|
61
|
+
min-height: 100%;
|
|
62
|
+
background: rgba(220, 38, 38, 0.1);
|
|
63
|
+
border-left: 1px solid rgba(220, 38, 38, 0.3);
|
|
64
|
+
border-right: 1px solid rgba(220, 38, 38, 0.3);
|
|
65
|
+
box-sizing: border-box;
|
|
66
|
+
}
|
|
67
|
+
.section-gap-marker {
|
|
68
|
+
position: absolute;
|
|
69
|
+
left: 0;
|
|
70
|
+
width: 100%;
|
|
71
|
+
pointer-events: none;
|
|
72
|
+
z-index: 99988;
|
|
73
|
+
box-sizing: border-box;
|
|
74
|
+
}
|
|
75
|
+
.section-gap-marker--has-gap {
|
|
76
|
+
border-top: 1px dashed rgba(234, 179, 8, 0.5);
|
|
77
|
+
border-bottom: 1px dashed rgba(234, 179, 8, 0.5);
|
|
78
|
+
}
|
|
79
|
+
.section-gap-marker__part {
|
|
80
|
+
position: absolute;
|
|
81
|
+
left: 0;
|
|
82
|
+
width: 100%;
|
|
83
|
+
}
|
|
84
|
+
.section-gap-marker__part--bottom {
|
|
85
|
+
background: rgba(234, 179, 8, 0.15);
|
|
86
|
+
border-bottom: 1px solid rgba(234, 179, 8, 0.4);
|
|
87
|
+
}
|
|
88
|
+
.section-gap-marker__part--top {
|
|
89
|
+
background: rgba(251, 146, 60, 0.15);
|
|
90
|
+
border-bottom: 1px solid rgba(251, 146, 60, 0.4);
|
|
91
|
+
}
|
|
92
|
+
.section-gap-marker__label {
|
|
93
|
+
position: absolute;
|
|
94
|
+
top: 50%;
|
|
95
|
+
left: 50%;
|
|
96
|
+
transform: translate(-50%, -50%);
|
|
97
|
+
background: rgba(234, 179, 8, 0.95);
|
|
98
|
+
color: #1a1a1a;
|
|
99
|
+
font-size: 11px;
|
|
100
|
+
font-family: monospace;
|
|
101
|
+
font-weight: 600;
|
|
102
|
+
padding: 2px 8px;
|
|
103
|
+
border-radius: 3px;
|
|
104
|
+
white-space: nowrap;
|
|
105
|
+
z-index: 1;
|
|
106
|
+
}
|
|
107
|
+
#${TOAST_ID} {
|
|
108
|
+
position: fixed;
|
|
109
|
+
bottom: 20px;
|
|
110
|
+
left: 50%;
|
|
111
|
+
transform: translateX(-50%) translateY(100px);
|
|
112
|
+
background: #1A1A2E;
|
|
113
|
+
color: white;
|
|
114
|
+
font-size: 13px;
|
|
115
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
116
|
+
padding: 10px 20px;
|
|
117
|
+
border-radius: 6px;
|
|
118
|
+
z-index: 100000;
|
|
119
|
+
pointer-events: none;
|
|
120
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
|
121
|
+
opacity: 0;
|
|
122
|
+
transition: transform 0.3s ease, opacity 0.3s ease;
|
|
123
|
+
white-space: nowrap;
|
|
124
|
+
}
|
|
125
|
+
#${TOAST_ID}.visible {
|
|
126
|
+
opacity: 1;
|
|
127
|
+
transform: translateX(-50%) translateY(0);
|
|
128
|
+
}
|
|
129
|
+
#${TOAST_ID} .toast-status { font-weight: 600; }
|
|
130
|
+
#${TOAST_ID} .toast-status--on { color: #4CAF50; }
|
|
131
|
+
#${TOAST_ID} .toast-status--off { color: #F44336; }
|
|
132
|
+
`;
|
|
133
|
+
document.head.appendChild(style);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// --- Toast ---
|
|
137
|
+
let toastTimeout = null;
|
|
138
|
+
function showToast(label, on) {
|
|
139
|
+
injectStyles();
|
|
140
|
+
let toast = document.getElementById(TOAST_ID);
|
|
141
|
+
if (!toast) {
|
|
142
|
+
toast = document.createElement('div');
|
|
143
|
+
toast.id = TOAST_ID;
|
|
144
|
+
document.body.appendChild(toast);
|
|
145
|
+
}
|
|
146
|
+
const cls = on ? 'toast-status--on' : 'toast-status--off';
|
|
147
|
+
toast.innerHTML = `${label}: <span class="toast-status ${cls}">${on ? 'ON' : 'OFF'}</span>`;
|
|
148
|
+
if (toastTimeout) clearTimeout(toastTimeout);
|
|
149
|
+
requestAnimationFrame(() => toast.classList.add('visible'));
|
|
150
|
+
toastTimeout = setTimeout(() => toast.classList.remove('visible'), 2000);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// --- Column grid ---
|
|
154
|
+
let colResizeObserver = null;
|
|
155
|
+
|
|
156
|
+
function updateColOverlayHeight() {
|
|
157
|
+
if (!colOverlay) return;
|
|
158
|
+
const container = getContainer();
|
|
159
|
+
colOverlay.style.height = container.scrollHeight + 'px';
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function createColOverlay() {
|
|
163
|
+
if (colOverlay) return;
|
|
164
|
+
colOverlay = document.createElement('div');
|
|
165
|
+
colOverlay.id = COL_OVERLAY_ID;
|
|
166
|
+
for (let i = 0; i < COLUMNS; i++) {
|
|
167
|
+
const col = document.createElement('div');
|
|
168
|
+
col.className = 'grid-overlay__column';
|
|
169
|
+
colOverlay.appendChild(col);
|
|
170
|
+
}
|
|
171
|
+
const container = getContainer();
|
|
172
|
+
container.style.position = 'relative';
|
|
173
|
+
container.appendChild(colOverlay);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function enableCol() {
|
|
177
|
+
colEnabled = true;
|
|
178
|
+
injectStyles();
|
|
179
|
+
createColOverlay();
|
|
180
|
+
colOverlay.style.display = 'flex';
|
|
181
|
+
updateColOverlayHeight();
|
|
182
|
+
// Keep height in sync as content resizes
|
|
183
|
+
if (!colResizeObserver) {
|
|
184
|
+
colResizeObserver = new ResizeObserver(updateColOverlayHeight);
|
|
185
|
+
}
|
|
186
|
+
const container = getContainer();
|
|
187
|
+
Array.from(container.children).forEach(child => {
|
|
188
|
+
if (child !== colOverlay) colResizeObserver.observe(child);
|
|
189
|
+
});
|
|
190
|
+
localStorage.setItem(STORAGE_KEY_COL, 'true');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function disableCol() {
|
|
194
|
+
colEnabled = false;
|
|
195
|
+
if (colOverlay) colOverlay.style.display = 'none';
|
|
196
|
+
if (colResizeObserver) colResizeObserver.disconnect();
|
|
197
|
+
localStorage.setItem(STORAGE_KEY_COL, 'false');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function dispatchToggleEvent() {
|
|
201
|
+
const detail = { colEnabled, spacingEnabled };
|
|
202
|
+
window.dispatchEvent(new CustomEvent('gridOverlayToggled', { detail }));
|
|
203
|
+
// If we're inside the proto-nav iframe, notify the parent so its
|
|
204
|
+
// sidebar checkboxes stay in sync.
|
|
205
|
+
if (window.parent && window.parent !== window) {
|
|
206
|
+
try {
|
|
207
|
+
window.parent.postMessage({ type: 'gridOverlayState', ...detail }, '*');
|
|
208
|
+
} catch (e) { /* cross-origin — ignore */ }
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function toggleCol() {
|
|
213
|
+
colEnabled ? disableCol() : enableCol();
|
|
214
|
+
showToast('Column Grid', colEnabled);
|
|
215
|
+
dispatchToggleEvent();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// --- Section spacing ---
|
|
219
|
+
function clearSpacingMarkers() {
|
|
220
|
+
spacingMarkers.forEach(el => el.remove());
|
|
221
|
+
spacingMarkers = [];
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function renderSpacingMarkers() {
|
|
225
|
+
clearSpacingMarkers();
|
|
226
|
+
|
|
227
|
+
const main = document.querySelector('main');
|
|
228
|
+
if (!main) return;
|
|
229
|
+
|
|
230
|
+
const sections = Array.from(main.children).filter(el => {
|
|
231
|
+
const s = window.getComputedStyle(el);
|
|
232
|
+
return s.display !== 'none' && s.visibility !== 'hidden';
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const scrollTop = getScrollTop();
|
|
236
|
+
const container = getContainer();
|
|
237
|
+
container.style.position = 'relative';
|
|
238
|
+
|
|
239
|
+
for (let i = 0; i < sections.length - 1; i++) {
|
|
240
|
+
const rectA = sections[i].getBoundingClientRect();
|
|
241
|
+
const rectB = sections[i + 1].getBoundingClientRect();
|
|
242
|
+
const styleA = window.getComputedStyle(sections[i]);
|
|
243
|
+
const styleB = window.getComputedStyle(sections[i + 1]);
|
|
244
|
+
|
|
245
|
+
const paddingBottomA = parseFloat(styleA.paddingBottom) || 0;
|
|
246
|
+
const paddingTopB = parseFloat(styleB.paddingTop) || 0;
|
|
247
|
+
|
|
248
|
+
// Measure from last content pixel of A to first content pixel of B
|
|
249
|
+
const contentBottomA = Math.round(rectA.bottom + scrollTop - paddingBottomA);
|
|
250
|
+
const contentTopB = Math.round(rectB.top + scrollTop + paddingTopB);
|
|
251
|
+
const space = contentTopB - contentBottomA;
|
|
252
|
+
|
|
253
|
+
if (space < 0) continue; // sections actually overlap in content
|
|
254
|
+
|
|
255
|
+
const marker = document.createElement('div');
|
|
256
|
+
marker.className = 'section-gap-marker section-gap-marker--has-gap';
|
|
257
|
+
marker.style.top = contentBottomA + 'px';
|
|
258
|
+
marker.style.height = Math.max(space, 2) + 'px';
|
|
259
|
+
|
|
260
|
+
// Padding-bottom of section A (yellow)
|
|
261
|
+
if (paddingBottomA > 0) {
|
|
262
|
+
const partBottom = document.createElement('div');
|
|
263
|
+
partBottom.className = 'section-gap-marker__part section-gap-marker__part--bottom';
|
|
264
|
+
partBottom.style.top = '0px';
|
|
265
|
+
partBottom.style.height = paddingBottomA + 'px';
|
|
266
|
+
marker.appendChild(partBottom);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Padding-top of section B (orange)
|
|
270
|
+
if (paddingTopB > 0) {
|
|
271
|
+
const partTop = document.createElement('div');
|
|
272
|
+
partTop.className = 'section-gap-marker__part section-gap-marker__part--top';
|
|
273
|
+
partTop.style.top = (space - paddingTopB) + 'px';
|
|
274
|
+
partTop.style.height = paddingTopB + 'px';
|
|
275
|
+
marker.appendChild(partTop);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const label = document.createElement('div');
|
|
279
|
+
label.className = 'section-gap-marker__label';
|
|
280
|
+
label.textContent = Math.round(space) + 'px';
|
|
281
|
+
marker.appendChild(label);
|
|
282
|
+
|
|
283
|
+
container.appendChild(marker);
|
|
284
|
+
spacingMarkers.push(marker);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function enableSpacing() {
|
|
289
|
+
spacingEnabled = true;
|
|
290
|
+
injectStyles();
|
|
291
|
+
renderSpacingMarkers();
|
|
292
|
+
const wrapper = document.getElementById('protoSiteWrapper');
|
|
293
|
+
if (wrapper) {
|
|
294
|
+
wrapper.addEventListener('scroll', renderSpacingMarkers);
|
|
295
|
+
} else {
|
|
296
|
+
window.addEventListener('scroll', renderSpacingMarkers);
|
|
297
|
+
}
|
|
298
|
+
window.addEventListener('resize', renderSpacingMarkers);
|
|
299
|
+
localStorage.setItem(STORAGE_KEY_SPACING, 'true');
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function disableSpacing() {
|
|
303
|
+
spacingEnabled = false;
|
|
304
|
+
clearSpacingMarkers();
|
|
305
|
+
const wrapper = document.getElementById('protoSiteWrapper');
|
|
306
|
+
if (wrapper) {
|
|
307
|
+
wrapper.removeEventListener('scroll', renderSpacingMarkers);
|
|
308
|
+
} else {
|
|
309
|
+
window.removeEventListener('scroll', renderSpacingMarkers);
|
|
310
|
+
}
|
|
311
|
+
window.removeEventListener('resize', renderSpacingMarkers);
|
|
312
|
+
localStorage.setItem(STORAGE_KEY_SPACING, 'false');
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function toggleSpacing() {
|
|
316
|
+
spacingEnabled ? disableSpacing() : enableSpacing();
|
|
317
|
+
showToast('Section Spacing', spacingEnabled);
|
|
318
|
+
dispatchToggleEvent();
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// --- Keyboard ---
|
|
322
|
+
document.addEventListener('keydown', function(e) {
|
|
323
|
+
if (e.ctrlKey && e.shiftKey && (e.key === 'G' || e.key === 'g')) {
|
|
324
|
+
e.preventDefault();
|
|
325
|
+
toggleCol();
|
|
326
|
+
}
|
|
327
|
+
if (e.ctrlKey && e.shiftKey && (e.key === 'H' || e.key === 'h')) {
|
|
328
|
+
e.preventDefault();
|
|
329
|
+
toggleSpacing();
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// --- Global API ---
|
|
334
|
+
window.GridOverlay = {
|
|
335
|
+
toggleCol, enableCol, disableCol, isColEnabled: () => colEnabled,
|
|
336
|
+
toggleSpacing, enableSpacing, disableSpacing, isSpacingEnabled: () => spacingEnabled
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
// --- Parent → iframe control channel ---
|
|
340
|
+
// Proto-nav posts commands so its sidebar checkbox controls the overlay
|
|
341
|
+
// rendered inside the viewport-preview iframe.
|
|
342
|
+
window.addEventListener('message', function(e) {
|
|
343
|
+
const msg = e.data;
|
|
344
|
+
if (!msg || msg.type !== 'gridOverlay') return;
|
|
345
|
+
switch (msg.action) {
|
|
346
|
+
case 'enableCol': if (!colEnabled) enableCol(); break;
|
|
347
|
+
case 'disableCol': if (colEnabled) disableCol(); break;
|
|
348
|
+
case 'enableSpacing': if (!spacingEnabled) enableSpacing(); break;
|
|
349
|
+
case 'disableSpacing': if (spacingEnabled) disableSpacing(); break;
|
|
350
|
+
case 'requestState': /* fall through to post below */ break;
|
|
351
|
+
default: return;
|
|
352
|
+
}
|
|
353
|
+
if (window.parent && window.parent !== window) {
|
|
354
|
+
window.parent.postMessage(
|
|
355
|
+
{ type: 'gridOverlayState', colEnabled, spacingEnabled }, '*'
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// --- Restore state (deferred so proto-nav has time to set up #protoSiteWrapper) ---
|
|
361
|
+
function restoreState() {
|
|
362
|
+
if (localStorage.getItem(STORAGE_KEY_COL) === 'true') enableCol();
|
|
363
|
+
if (localStorage.getItem(STORAGE_KEY_SPACING) === 'true') enableSpacing();
|
|
364
|
+
// Announce state to parent (no-op when not in an iframe)
|
|
365
|
+
if (window.parent && window.parent !== window) {
|
|
366
|
+
window.parent.postMessage(
|
|
367
|
+
{ type: 'gridOverlayState', colEnabled, spacingEnabled }, '*'
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (document.readyState === 'loading') {
|
|
373
|
+
document.addEventListener('DOMContentLoaded', () => setTimeout(restoreState, 0));
|
|
374
|
+
} else {
|
|
375
|
+
setTimeout(restoreState, 0);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
console.log('[Grid Overlay] Ready. Ctrl+Shift+G = columns, Ctrl+Shift+H = section spacing.');
|
|
379
|
+
})();
|