/* global React */
// Palimpsest — shared UI components (paper × terminal)
const { useState, useEffect, useRef, useMemo } = React;
// ----- ICONS (monoline, 16px, 1.5px stroke) ---------------------------------
const Icon = ({ d, size = 16, stroke = 1.5, ...rest }) => (
);
const Icons = {
Download: (p) => ,
Upload: (p) => ,
Play: (p) => ,
Check: (p) => ,
X: (p) => ,
Plus: (p) => ,
ArrowR: (p) => ,
ArrowL: (p) => ,
Ext: (p) => ,
Search: (p) => ,
ChevD: (p) => ,
ChevR: (p) => ,
More: (p) => ,
Reload: (p) => ,
History: (p) => ,
File: (p) => ,
Settings: (p) => ,
};
// ----- BUTTON ---------------------------------------------------------------
function Button({ variant = "paper", size = "md", children, icon, iconRight, onTerm, ...rest }) {
const cls = [
"btn",
`btn-${variant}`,
size === "lg" && "btn-lg",
size === "sm" && "btn-sm",
onTerm && "on-term",
].filter(Boolean).join(" ");
return (
);
}
// ----- CHIP -----------------------------------------------------------------
function Chip({ variant = "mute", dot, pulse, children, ...rest }) {
return (
{dot && }
{children}
);
}
// ----- STAMP / WAX SEAL / RIBBON --------------------------------------------
function Stamp({ children, style }) {
return {children};
}
function WaxSeal({ children = '✎', size = 'md', style }) {
const cls = size === 'sm' ? 'wax-seal wax-seal-sm' : size === 'lg' ? 'wax-seal wax-seal-lg' : 'wax-seal';
return {children};
}
function Ribbon({ tone = 'ink', children }) {
const cls = "ribbon" + (tone === 'ochre' ? ' ribbon-ochre' : tone === 'rule' ? ' ribbon-rule' : '');
return
{children}
;
}
function FolderTab({ children }) {
return {children}
;
}
// ----- PAPER CARD -----------------------------------------------------------
function PaperCard({ rotate = 0, ribbon, ribbonTone, tab, foldCorner, children, className = '', style = {}, ...rest }) {
return (
{ribbon &&
{ribbon}}
{tab &&
{tab}}
{foldCorner &&
}
{children}
);
}
// ----- TERMINAL PANEL -------------------------------------------------------
function TerminalPanel({ active, children, className = '', style = {}, ...rest }) {
return (
{children}
);
}
// ----- PROGRESS BAR ---------------------------------------------------------
function ProgressBar({ value = 0, tone = "ai", size = "md" }) {
const fill = tone === 'green' ? 'progress-fill-green'
: tone === 'warn' ? 'progress-fill-warn'
: 'progress-fill-ai';
return (
);
}
// ----- STAGE CHIP -----------------------------------------------------------
function StageChip({ name, state = "pending", status }) {
const cls = `stage-chip stage-chip-${state}`;
const glyph = state === 'done' ? '✓' : state === 'failed' ? '!' : state === 'active' ? '◐' : '○';
return (
);
}
// ----- LOG STREAM -----------------------------------------------------------
function LogLine({ time, glyph = ' ', stage, msg, tone = "" }) {
return (
[{time}]
{glyph}
{stage}
{msg}
);
}
// Export all to window
Object.assign(window, {
Icon, Icons, Button, Chip, Stamp, WaxSeal, Ribbon, FolderTab,
PaperCard, TerminalPanel, ProgressBar, StageChip, LogLine,
});