+
+
+
ctx && sid && ctx.patchSection(sid, { title: v })}
+ style={{ fontSize: 28, fontWeight: 600, color: DC.title, letterSpacing: -0.4, marginBottom: 6, display: 'inline-block' }} />
+ {subtitle && {subtitle}
}
+
+
+
+ {order.map((k) => (
+ ctx && ctx.patchSection(sid, (x) => ({ labels: { ...x.labels, [k]: v } }))}
+ onReorder={(next) => ctx && ctx.patchSection(sid, { order: next })}
+ onDelete={() => ctx && ctx.patchSection(sid, (x) => ({
+ hidden: [...(x.srcKey === srcKey ? (x.hidden || []) : []), k],
+ srcKey,
+ }))}
+ onFocus={() => ctx && ctx.setFocus(`${sid}/${k}`)} />
+ ))}
+
+ {rest}
+
+ );
+}
+
+// DCArtboard — marker; rendered by DCArtboardFrame via DCSection.
+function DCArtboard() { return null; }
+
+// Per-artboard export (kind: 'png' | 'html'). Both paths share the same
+// self-contained clone: computed styles baked in, @font-face / ctx.setFocus(null)}
+ onWheel={(e) => e.preventDefault()}
+ style={{ position: 'fixed', inset: 0, zIndex: 100, background: 'rgba(24,20,16,.6)', backdropFilter: 'blur(14px)',
+ fontFamily: DC.font, color: '#fff' }}>
+
+ {/* top bar: section dropdown (left) · close (right) */}
+
e.stopPropagation()}
+ style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 72, display: 'flex', alignItems: 'flex-start', padding: '16px 20px 0', gap: 16 }}>
+
+
+ {ddOpen && (
+
+ {sectionOrder.filter((sid) => sectionMeta[sid].slotIds.length).map((sid) => (
+
+ ))}
+
+ )}
+
+
+
+
+
+ {/* card centered, label + index below — only the card itself stops
+ propagation so any backdrop click (including the margins around
+ the card) exits focus */}
+
+
e.stopPropagation()} style={{ width: width * scale, height: height * scale, position: 'relative' }}>
+
+
+
e.stopPropagation()} style={{ fontSize: 14, fontWeight: 500, opacity: .85, textAlign: 'center' }}>
+ {(sec.labels || {})[aid] ?? artboard.props.label}
+ {idx + 1} / {peers.length}
+
+
+
+
go(-1)} />
+ go(1)} />
+
+ {/* dots */}
+ e.stopPropagation()}
+ style={{ position: 'absolute', bottom: 20, left: '50%', transform: 'translateX(-50%)', display: 'flex', gap: 8 }}>
+ {peers.map((p, i) => (
+
+ ,
+ document.body,
+ );
+}
+
+// ─────────────────────────────────────────────────────────────
+// Post-it — absolute-positioned sticky note
+// ─────────────────────────────────────────────────────────────
+function DCPostIt({ children, top, left, right, bottom, rotate = -2, width = 180 }) {
+ return (
+