Files
commitea/docs/design/ui_kits/app/FocusScreen.js.txt
Christian LeDoux 7a5cacc54c Scaffold CommiTea: yarn workspaces, Electron shell, core label schema, design system
- 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>
2026-07-07 20:42:46 -04:00

53 lines
2.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Morning service — focus screen
function FocusScreen({ onOpenIssue }) {
const DS = window.CommiTeaDesignSystem_20e63b;
const { Card, Tag, Badge, Button, IconButton } = DS;
const d = window.CT_DATA;
const FocusRow = ({ slot, issue, jade }) => (
<Card overline={slot} jade={jade}
title={<a href="#" onClick={(e) => { e.preventDefault(); onOpenIssue(issue); }}
style={{ color: 'inherit', border: 'none' }}>{issue.title}</a>}
actions={<IconButton icon="ellipsis" label="More" size="sm" />}
footer={jade ? <>
<Button size="sm">Start</Button>
<Button size="sm" variant="ghost">Defer</Button>
<span style={{ marginLeft: 'auto', font: 'var(--text-caption)', color: 'var(--ink-3)' }}>scheduler pick · critical path</span>
</> : null}>
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10, flexWrap: 'wrap' }}>
<span style={{ font: 'var(--text-data)', color: 'var(--ink-3)' }}>#{issue.id}</span>
{issue.labels.map((l) => <Tag key={l} label={l} />)}
{issue.steeping ? <Badge tone="warn" dot>steeping {issue.steeping}</Badge> : null}
</div>
<p style={{ font: 'var(--text-agent)', color: 'var(--ink-2)', margin: 0 }}>{issue.rationale}</p>
</Card>
);
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<header style={{ borderBottom: 'var(--rule-double)', paddingBottom: 14, display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 12 }}>
<div>
<h1 style={{ font: 'var(--text-display)', color: 'var(--ink-1)', margin: 0 }}>Morning service</h1>
<p style={{ font: 'var(--text-data)', color: 'var(--ink-3)', margin: '6px 0 0', whiteSpace: 'nowrap' }}>{d.today} · reconcile 3.2s</p>
</div>
<Badge tone="ok" dot>ahead of forecast</Badge>
</header>
<div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr 1fr', gap: 14, alignItems: 'start' }}>
<FocusRow slot="Now" issue={d.focus.now} jade />
<FocusRow slot="Next" issue={d.focus.next} />
<FocusRow slot="Later" issue={d.focus.later} />
</div>
<Card overline="Milestone · Beta" title={<>80% this lands <span style={{ whiteSpace: 'nowrap' }}>Mar 312</span></>}
actions={<IconButton icon="chart-line" label="Open runway" size="sm" />}>
<window.BurnUpCone />
<p style={{ font: 'var(--text-agent)', color: 'var(--ink-2)', margin: '10px 0 0' }}>
The cone has narrowed since Friday. I'm quietly pleased.
</p>
</Card>
</div>
);
}
Object.assign(window, { FocusScreen });