Configure Your Layout

Straight Run

Drag modules from the catalog into the run below, or click a card to drop it into the active run. Click a run's header to make it active.

`; const win = window.open('', '_blank', 'width=900,height=700'); if (!win) { showToast('Allow popups to export PDF', 'err'); return; } win.document.write(html); win.document.close(); win.focus(); setTimeout(() => { win.print(); }, 600); } // Export button: show dropdown for PDF vs CSV const btnExport = document.querySelector('#btnExport'); if (btnExport) { btnExport.addEventListener('click', function(e) { // Toggle a small dropdown let existing = document.getElementById('exportDropdown'); if (existing) { existing.remove(); return; } const dropdown = document.createElement('div'); dropdown.id = 'exportDropdown'; dropdown.style.cssText = 'position:absolute;z-index:9999;background:var(--bg-card);border:1px solid var(--border-subtle);border-radius:4px;box-shadow:0 8px 24px rgba(0,0,0,.12);overflow:hidden;min-width:160px;'; const rect = btnExport.getBoundingClientRect(); dropdown.style.top = (rect.bottom + 4) + 'px'; dropdown.style.left = rect.left + 'px'; const itemStyle = 'display:block;width:100%;padding:10px 16px;background:none;border:none;text-align:left;font-family:var(--sans);font-size:12px;font-weight:600;color:var(--text-primary);cursor:pointer;transition:.1s;'; dropdown.innerHTML = ` `; document.body.appendChild(dropdown); document.getElementById('exportCSVBtn').onclick = () => { exportCSV(); dropdown.remove(); }; document.getElementById('exportPDFBtn').onclick = () => { exportPDF(); dropdown.remove(); }; // Close on outside click setTimeout(() => { document.addEventListener('click', function handler(ev) { if (!dropdown.contains(ev.target) && ev.target !== btnExport) { dropdown.remove(); document.removeEventListener('click', handler); } }); }, 50); }); } // ── Handle SUNSTONE_LOAD_DESIGN from parent page (gallery lightbox) ────────── window.addEventListener('message', function(e) { if (!e.data || e.origin !== CONFIG.siteBaseUrl) return; if (e.data.type === 'SUNSTONE_PRICE_MAP') { const incoming = e.data.prices; if (!incoming || typeof incoming !== 'object') return; Object.entries(incoming).forEach(([id, price]) => { const normalized = Number(price); if (Number.isFinite(normalized) && normalized >= 0 && byId(id)) state.prices[id] = normalized; }); renderCatalog(); renderRuns(); updateQuote(); return; } if (e.data.type !== 'SUNSTONE_LOAD_DESIGN') return; const config = e.data.config; if (!config || !config.shape || !config.runs) return; try { const normRuns = config.runs.map(function(r, ri) { return Object.assign({}, r, { items: (r.items || []).map(function(it, idx) { return { id: it.id || (r.id + '-' + idx + '-' + Date.now()), catId: it.catId }; }) }); }); state.shape = config.shape; state.runs = normRuns; state.activeRun = 0; renderAll(); showToast('Design loaded from gallery!'); if (window.parent && window.parent !== window) { window.parent.postMessage({ type: 'SUNSTONE_GALLERY_DESIGN_LOADED' }, CONFIG.siteBaseUrl); } } catch(err) { showToast('Could not load design'); } });