// Shared atoms used by both directions
const { useState, useMemo, useEffect } = React;
// A subtle striped placeholder block. Optional label.
function Placeholder({ label, dark, ratio, height, accent, style, children, rounded, bordered }) {
const aspect = ratio || (height ? null : '4 / 3');
const bg = dark ? '#11202E' : '#E1E9F0';
const fg = dark ? 'rgba(255,255,255,.55)' : 'rgba(0,0,0,.55)';
return (
{accent && (
)}
{label && (
{label}
)}
{children}
);
}
// Stock pill (used in product cards / detail)
function StockPill({ status, theme }) {
const colors = {
'In stock': { dot: '#1F7A3D', bg: 'rgba(31,122,61,.08)', fg: '#1F7A3D' },
'Low stock': { dot: '#B07B16', bg: 'rgba(176,123,22,.08)', fg: '#B07B16' },
'Pre-order': { dot: '#0E1A2B', bg: 'rgba(14,26,43,.08)', fg: '#0E1A2B' },
};
const c = colors[status] || colors['In stock'];
return (
{status}
);
}
// Small chevron tab nav for switching pages within an artboard.
function PageTabs({ pages, active, onChange, theme }) {
const ink = theme.ink;
const muted = theme.muted;
return (
{pages.map((p) => {
const on = p.id === active;
return (
);
})}
);
}
// Tiny SVG glyph for cert blocks
function CertGlyph({ code, color }) {
return (
{code}
);
}
window.Placeholder = Placeholder;
window.StockPill = StockPill;
window.PageTabs = PageTabs;
window.CertGlyph = CertGlyph;