// Shared UI primitives — pill, button, input, etc. // Civic-tech aesthetic: off-white, dark text, navy accent, plain sans-serif. const Pill = ({ tone = "neutral", children, mono = false }) => { const map = { neutral: { bg: "var(--pill-bg)", fg: "var(--pill-fg)", bd: "var(--pill-bd)" }, info: { bg: "var(--pill-info-bg)", fg: "var(--pill-info-fg)", bd: "var(--pill-info-bd)" }, ok: { bg: "var(--pill-ok-bg)", fg: "var(--pill-ok-fg)", bd: "var(--pill-ok-bd)" }, warn: { bg: "var(--pill-warn-bg)", fg: "var(--pill-warn-fg)", bd: "var(--pill-warn-bd)" }, danger: { bg: "var(--pill-danger-bg)", fg: "var(--pill-danger-fg)", bd: "var(--pill-danger-bd)" } }; const c = map[tone] || map.neutral; return ( {tone !== "neutral" && ( )} {children} ); }; const StatusPill = ({ status }) => { const meta = window.STATUS_META[status] || { label: status, tone: "neutral" }; return {meta.label}; }; const Button = ({ variant = "primary", children, onClick, disabled, icon, full, size = "md", type = "button" }) => { const styles = { primary: { bg: "var(--accent)", fg: "#fff", bd: "var(--accent)" }, secondary: { bg: "var(--surface)", fg: "var(--text)", bd: "var(--rule)" }, ghost: { bg: "transparent", fg: "var(--text)", bd: "transparent" }, danger: { bg: "var(--surface)", fg: "var(--danger-fg)", bd: "var(--danger-fg)" } }; const s = styles[variant]; const pad = size === "sm" ? "4px 10px" : "8px 14px"; const fs = size === "sm" ? 13 : 14; return ( ); }; const Field = ({ label, hint, children, error }) => ( ); const TextInput = ({ value, onChange, placeholder, mono, ...rest }) => ( onChange && onChange(e.target.value)} placeholder={placeholder} style={{ width: "100%", padding: "8px 10px", fontSize: 14, fontFamily: mono ? "var(--font-mono)" : "inherit", color: "var(--text)", background: "var(--surface)", border: "1px solid var(--rule)", borderRadius: 2, outline: "none", boxShadow: "inset 0 1px 0 rgba(0,0,0,0.03)" }} onFocus={(e) => e.currentTarget.style.borderColor = "var(--accent)"} onBlur={(e) => e.currentTarget.style.borderColor = "var(--rule)"} {...rest} /> ); const TextArea = ({ value, onChange, placeholder, rows = 6, mono }) => (