- 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>
Handoff: CommiTea App
Overview
CommiTea is an AI-project-manager built on Gitea: an Electron desktop app (one window) where an LLM agent persona ("Reginald") captures work via interview, forecasts milestones as Monte Carlo ranges, and manages issues through labels only. This package contains the complete design system plus a fully interactive HTML prototype of the app with 11 screens.
About the Design Files
The files in this bundle are design references created in HTML — prototypes showing intended look and behavior, not production code to copy directly. Your task is to recreate these designs in the target codebase's environment. The product plan specifies Electron + React + Tailwind; if that scaffold doesn't exist yet, that is the intended stack. Map the CSS custom properties in tokens/ to Tailwind theme config; reimplement the components/ primitives as your base component library.
ui_kits/app/index.html opens directly in a browser (via a local static server) — use it as the living spec. Everything is real: navigation, drill-ins, theme toggle, offline simulation.
Fidelity
High-fidelity. Colors, typography, spacing, radii, shadows, copy, and interactions are final. Recreate pixel-perfectly using the token values (all defined in tokens/*.css). The fixture data in ui_kits/app/data.js is demo content — replace with real Gitea/scheduler data.
Design System (source of truth)
design_system_readme.md— brand context, CONTENT FUNDAMENTALS (Reginald's voice rules: dry wit, no emoji, sentence case, forecasts always ranges), VISUAL FOUNDATIONS, ICONOGRAPHY.styles.css→ importstokens/fonts.css(self-hosted woff2 inassets/fonts/),tokens/colors.css(light:root+ dark[data-theme="dark"]),tokens/typography.css,tokens/spacing.css,tokens/base.css.components/{core,forms,feedback}/— 16 React primitives (Button, IconButton, Badge, Tag, Card, Tabs, Icon, Input, Select, Checkbox, Radio, Switch, Dialog, Toast, Tooltip). Each has<Name>.jsx(reference implementation),<Name>.d.ts(props contract),<Name>.prompt.md(usage + rules). Reuse these contracts verbatim._ds_bundle.js— compiled bundle the prototype loads; not for production.
Type voices (strictly cast — never mix)
--text-display/title/hero: Libre Caslon Display — headlines, hero numerals--text-agent(-lg): Libre Caslon Text, upright — ONLY for Reginald's speech--text-body/small/caption: Instrument Sans — all UI--text-data/label: IBM Plex Mono — machine data verbatim:est/3d,p/1,#87, dates, deltas
Key color tokens (light / dark)
- Surfaces:
--paper-0#F0F4F0/#121C18 (app),--paper-1#FAFCF9/#182420 (card),--paper-2inset,--paper-3pressed - Ink:
--ink-1#1D2522/#E4EEE7,--ink-2,--ink-3; hairlines--line-1/2 - Brand:
--accent(spruce #275546/#3A7260), hover/pressed darker steps;--jade#46996F/#6FC694 (small accents + key-card top rule--shadow-jade-lineonly — never large fills) - Status:
--ok --warn --danger --info+*-tintpairs; label chips--label-p1..p4,--label-est-*,--label-hard - Forecast:
--cone-fill,--cone-line,--cone-actual - Radii 4/6/10px; spacing 4px scale (
--space-1..10); motion 120–320ms--ease-out, no bounces; focus = 2px--focus-ringoutline offset 2.
Screens (all in ui_kits/app/, routed by Shell.jsx)
Layout shell: 208px left rail (nav + connection status + theme switch) · main column (max 1120px, 24/28px padding) · 330px right chat panel. Page headers: Caslon display title over a 3px double rule, mono subtitle. One jade (top-ruled) card per view maximum.
- Shell (
Shell.jsx) — nav, routing, dark mode (data-themeon<html>), offline simulation (click connection dot), issue navigation with back-stack of one. - Standup (
StandupScreen.jsx) — morning ritual as a typeset letter: drift report (dot + text + mono delta), per-person plan, stale-blocker nag (warn tint, clickable). Sections fade in once, 90ms stagger, reduced-motion-safe. - Morning service / Focus (
FocusScreen.jsx) — Now/Next/Later cards (Now = jade + footer actions), burn-up cone card (Chart.jsxBurnUpCone SVG). - Inbox (
InboxScreen.jsx) — day-grouped notifications, filter Tabs, unread dots, live rail badge; rows navigate to issue/directives; "Mark all read". - Capture (
CaptureScreen.jsx) — braindump → chip-answered interview (running mm:ss clock, amber past 2:00) → editable tray review with consequence line → filed. State machine: dump | interview | review | filed. - The pot / Board (
BoardScreen.jsx) — 5-column lifecycle kanban (Diagnosis/Triage/Steeping/In review/Done), live search with empty state, Tabs to drill-ins. - Gantt (
GanttView.jsx) — scheduler bars by state, critical rows inset-ruled, dotted 80% tails, today rule (jade), milestone band + due diamond. - Dependencies (
DepsGraph.jsx) — layered DAG, SVG bezier edges w/ arrowheads, critical path in accent, milestone capsule terminal. - Runway (
RunwayScreen.jsx) — milestone range bars (due marker vs 80% band), capacity list, calibration teaser → Calibration (CalibrationScreen.jsx): scatter + honest diagonal + ×1.18 fit, bias-by-label bars, per-person bias, forecast effect. Milestone rows → Milestone detail (MilestoneScreen.jsx): stats strip, cone, grouped issue list. - Issue detail (
IssueScreen.jsx) — human intent left (description, comments, composer "writes to gitea, as you"), machine-derived right (inferred lifecycle timeline, per-issue forecast, dependency chips, provenance note). - Directives (
DirectivesScreen.jsx) — pending consequence diff (before → after mono rows; Make it so / Amend / Withdraw) + append-only ledger (seq, who/when/why, verbatim quote, status badge). - Settings (
SettingsScreen.jsx) — connection, sync switches, model router, read-only label schema, rituals, appearance radios, single danger action. - Onboarding (
OnboardingScreen.jsx, "First run") — full-window: welcome → connect (test gate) → repo pick → propose-approve bootstrap. - States (
StatesGallery.jsx) — EmptyState/OfflineBanner/ModelAwayState components + gallery of all empty & trouble states.
Interactions & Behavior
- Hovers: surfaces step one paper darker; buttons darken (
--accent-hover); never opacity on text. Press: one step darker again, no shrink. - All fake async (connection test ~1.1s, chat reply ~0.9s, bootstrap ticks 700ms) represent real network calls.
- Offline mode: amber banner (copy in
StatesGallery.jsx), chat composer disabled + queue note, red rail dot. Reads work from cache; writes queue. - Issue click anywhere → issue page; Back returns to origin view.
- Chat = the only write path for mutations; destructive ops always propose-approve (Dialog or consequence diff).
State Management (suggested)
viewrouting +prevView(back),dark,offline,issueselection, inboxreadIds, capture state machine, directives pending/ledger. In production: Gitea REST + webhooks fill a local cache (SQLite per plan); scheduler output feeds focus/gantt/runway; all copy rules live in the design-system readme.
Assets
assets/fonts/— Libre Caslon Display/Text, Instrument Sans, IBM Plex Mono (woff2, latin, self-hosted; Google Fonts sources)assets/icons/— 69 Lucide SVGs (lucide-static v0.462.0, ISC). In production use thelucide-reactpackage at strokeWidth 1.5.assets/logo.jpeg(original),assets/logo-icon.png(cropped, rounded) — provided brand mark; never redraw.
Files
ui_kits/app/index.html— entry; open with a static server from this folder's rootui_kits/app/*.jsx— one file per screen (see Screens above);data.js— all fixture datastyles.css,tokens/,components/,assets/— the design systemSKILL.md— agent-facing skill entry (works with Claude Code as an Agent Skill)
Note on file suffixes
Reference source files in this bundle carry a .txt suffix (*.js.txt, *.d-ts.txt) so the design tool's compiler ignores these copies — the originals live in the design project. They are ordinary JSX/TypeScript inside; strip the suffix after copying into your repo. ui_kits/app/index.html still runs as-is (Babel loads the .txt files by src).