- apps/desktop: electron-vite + React + Tailwind mapped onto design tokens (preflight off; tokens/base.css owns the reset); boots to a Reginald placeholder proving fonts/tokens/core wiring - packages/core: pure TS; gitea label schema (est/*, p/*, deadline/hard) with pessimistic conflict resolution + 15 unit tests - docs/design: full design handoff (tokens, 16 component contracts, interactive 14-screen prototype, Reginald voice rules) - docs/PLAN.md: product plan (purity rule, pm-state repo, deterministic scheduler + Monte Carlo, directive log) - Deliberate deviation from novelpad stack: no ElectricSQL/PGlite — local store is a rebuildable cache over gitea REST/webhooks (better-sqlite3 in main process, arriving in P1) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
76 lines
3.2 KiB
HTML
76 lines
3.2 KiB
HTML
<!-- handoff copy (card tag removed) -->
|
|
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<link rel="stylesheet" href="../../styles.css">
|
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
<script src="../../_ds_bundle.js"></script>
|
|
<style>
|
|
body { padding: 18px 22px; }
|
|
.demo-grid { display: flex; flex-direction: column; gap: 14px; }
|
|
.demo-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="root"></div>
|
|
<script type="text/babel">
|
|
const { Button, IconButton, Badge, Tag, Card, Tabs, Icon } = window.CommiTeaDesignSystem_20e63b;
|
|
|
|
function Demo() {
|
|
const [tab, setTab] = React.useState('board');
|
|
return (
|
|
<div className="demo-grid">
|
|
<div className="demo-row">
|
|
<Button>Approve</Button>
|
|
<Button variant="secondary" icon="sparkles">Brew plan</Button>
|
|
<Button variant="ghost">Defer</Button>
|
|
<Button variant="danger" size="sm">Delete</Button>
|
|
<Button disabled>Approve</Button>
|
|
<Button size="sm" iconRight="arrow-right">Next</Button>
|
|
<IconButton icon="ellipsis" label="More" />
|
|
<IconButton icon="refresh-cw" label="Reconcile" variant="outline" size="sm" />
|
|
</div>
|
|
<div className="demo-row">
|
|
<Badge tone="ok" dot>ahead</Badge>
|
|
<Badge tone="warn" dot>drifting</Badge>
|
|
<Badge tone="danger">blocked</Badge>
|
|
<Badge tone="info">syncing</Badge>
|
|
<Badge tone="jade">forecast</Badge>
|
|
<Badge>neutral</Badge>
|
|
<Tag label="est/3d" />
|
|
<Tag label="p/1" />
|
|
<Tag label="p/3" />
|
|
<Tag label="deadline/hard" />
|
|
<Tag label="est/5d" onRemove={() => {}} />
|
|
</div>
|
|
<Tabs
|
|
items={[
|
|
{ id: 'board', label: 'Board', icon: 'square-kanban', count: 24 },
|
|
{ id: 'gantt', label: 'Gantt', icon: 'chart-no-axes-gantt' },
|
|
{ id: 'deps', label: 'Dependencies', icon: 'network', count: 7 },
|
|
]}
|
|
active={tab}
|
|
onChange={setTab}
|
|
/>
|
|
<Card overline="Now" title="Fix lifecycle inference" jade
|
|
actions={<IconButton icon="ellipsis" label="More" size="sm" />}
|
|
footer={<><Button size="sm">Start</Button><Button size="sm" variant="ghost">Defer</Button></>}>
|
|
<div className="demo-row" style={{ marginBottom: 8 }}>
|
|
<Tag label="est/2d" /><Tag label="p/1" />
|
|
<span style={{ font: 'var(--text-data)', color: 'var(--ink-3)' }}>#87 · steeping 4d</span>
|
|
</div>
|
|
<span style={{ font: 'var(--text-agent)', color: 'var(--ink-2)' }}>
|
|
It blocks #91 and #92. I'd take it first — the critical path agrees with me.
|
|
</span>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|
|
ReactDOM.createRoot(document.getElementById('root')).render(<Demo />);
|
|
</script>
|
|
</body>
|
|
</html>
|