/* UI primitives — exported to window for cross-file use */ // ---- Icon (lucide) ---- function Icon({ name, size = 20, sw = 2, className = '', style }) { const ref = React.useRef(null); React.useEffect(() => { const host = ref.current; if (!host || !window.lucide) return; const node = window.lucide.icons?.[name]; let svg; if (node && window.lucide.createElement) { svg = window.lucide.createElement(node); } if (!svg) { // fallback host.innerHTML = ``; window.lucide.createIcons({ nameAttr: 'data-lucide' }); svg = host.querySelector('svg'); if (!svg) return; } else { host.replaceChildren(svg); } svg.setAttribute('width', size); svg.setAttribute('height', size); svg.setAttribute('stroke-width', sw); }, [name, size, sw]); return ; } // ---- Status badge ---- function StatusBadge({ status, size = 'sm' }) { const s = CK.STATUS[status]; if (!s) return null; const pad = size === 'sm' ? 'text-[11px] px-2 py-0.5' : 'text-xs px-2.5 py-1'; return ( {s.th} ); } function DayStatusBadge({ status, size='sm' }) { const s = CK.DAYSTATUS[status]; if (!s) return null; const pad = size === 'sm' ? 'text-[11px] px-2 py-0.5' : 'text-xs px-2.5 py-1'; return {s.th}; } // ---- Buttons ---- function Btn({ children, variant = 'primary', size = 'md', icon, iconRight, className = '', ...rest }) { const sizes = { sm:'text-xs px-3 py-1.5 gap-1.5', md:'text-sm px-4 py-2.5 gap-2', lg:'text-base px-5 py-3 gap-2', xl:'text-base px-6 py-4 gap-2.5' }; const variants = { primary: 'bg-brand-600 hover:bg-brand-700 text-white shadow-sm', dark: 'bg-slate-900 hover:bg-slate-800 text-white', outline: 'bg-white hover:bg-slate-50 text-slate-700 ring-1 ring-slate-300', ghost: 'hover:bg-slate-100 text-slate-600', softred: 'bg-brand-50 hover:bg-brand-100 text-brand-700 ring-1 ring-brand-200', danger: 'bg-white hover:bg-brand-50 text-brand-700 ring-1 ring-brand-200', }; return ( ); } // ---- Card ---- function Card({ children, className = '', as: As = 'div', ...rest }) { return {children}; } // ---- Section title ---- function SectionTitle({ icon, children, hint }) { return (
{icon && }

{children}

{hint && {hint}}
); } // ---- Form fields ---- function Field({ label, required, hint, children }) { return ( ); } const inputCls = 'w-full rounded-xl ring-1 ring-slate-300 bg-white px-3.5 py-2.5 text-[15px] font-light text-slate-800 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-brand-500'; function TextInput(props){ return ; } function TextArea(props){ return