From 0c75f0471b2f93a3b2c8dbf33f4b2b8df091c28a Mon Sep 17 00:00:00 2001 From: Tim Disney Date: Thu, 23 Jul 2026 22:49:05 +0000 Subject: [PATCH] impeccable docs --- AGENTS.md | 1 + DESIGN.md | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ PRODUCT.md | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 file(s) changed, 379 insertion(s)(+), 0 deletion(s)(-) diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,1 @@ +CLAUDE.md \ No newline at end of file diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,282 @@ + +--- +name: Radial +description: Coordination UI for humans commissioning and reviewing coding-agent artifacts on atproto. +colors: + bg: "#ffffff" + surface: "#f6f6f6" + subtle: "#efefef" + border: "#e3e3e3" + border-strong: "#cfcfcf" + ink: "#2b2b2b" + ink-muted: "#6f6f6f" + ink-subtle: "#838383" + primary: "#2d7d57" + primary-strong: "#256a49" + primary-tint: "#e5f3ea" + success-fg: "#1f7d45" + success-bg: "#e2f3e8" + changes-fg: "#b23a2c" + changes-bg: "#f7e4e0" + open-fg: "#8a6a1a" + open-bg: "#f4ead0" +typography: + display: + fontFamily: "IBM Plex Sans, system-ui, -apple-system, sans-serif" + fontSize: "1.75rem" + fontWeight: 600 + lineHeight: 1.2 + letterSpacing: "-0.01em" + headline: + fontFamily: "IBM Plex Sans, system-ui, sans-serif" + fontSize: "1.25rem" + fontWeight: 600 + lineHeight: 1.3 + letterSpacing: "-0.005em" + title: + fontFamily: "IBM Plex Sans, system-ui, sans-serif" + fontSize: "1rem" + fontWeight: 600 + lineHeight: 1.4 + letterSpacing: "normal" + body: + fontFamily: "IBM Plex Sans, system-ui, sans-serif" + fontSize: "0.9375rem" + fontWeight: 400 + lineHeight: 1.55 + letterSpacing: "normal" + label: + fontFamily: "IBM Plex Sans, system-ui, sans-serif" + fontSize: "0.75rem" + fontWeight: 600 + lineHeight: 1.3 + letterSpacing: "0.01em" + code: + fontFamily: "IBM Plex Mono, ui-monospace, SFMono-Regular, monospace" + fontSize: "0.8125rem" + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: "normal" +rounded: + sm: "4px" + md: "6px" + lg: "10px" + pill: "999px" +spacing: + xs: "4px" + sm: "8px" + md: "12px" + lg: "16px" + xl: "24px" + xxl: "32px" +components: + button-primary: + backgroundColor: "{colors.primary}" + textColor: "{colors.bg}" + rounded: "{rounded.md}" + padding: "8px 14px" + button-primary-hover: + backgroundColor: "{colors.primary-strong}" + textColor: "{colors.bg}" + rounded: "{rounded.md}" + padding: "8px 14px" + button-secondary: + backgroundColor: "{colors.subtle}" + textColor: "{colors.ink}" + rounded: "{rounded.md}" + padding: "8px 14px" + input: + backgroundColor: "{colors.bg}" + textColor: "{colors.ink}" + rounded: "{rounded.md}" + padding: "7px 10px" + badge-approve: + backgroundColor: "{colors.success-bg}" + textColor: "{colors.success-fg}" + rounded: "{rounded.pill}" + padding: "1px 8px" + badge-changes: + backgroundColor: "{colors.changes-bg}" + textColor: "{colors.changes-fg}" + rounded: "{rounded.pill}" + padding: "1px 8px" + badge-open: + backgroundColor: "{colors.open-bg}" + textColor: "{colors.open-fg}" + rounded: "{rounded.pill}" + padding: "1px 8px" + uri-chip: + backgroundColor: "{colors.subtle}" + textColor: "{colors.ink-muted}" + typography: "{typography.code}" + rounded: "{rounded.sm}" + padding: "1px 5px" +--- + +# Design System: Radial + +## 1. Overview + +**Creative North Star: "The Signed Ledger"** + +Radial is a coordination surface, not a dashboard. Humans commission typed +artifacts from coding agents, and every artifact, review, and check is a signed +record pinned to an exact version. The UI's whole job is to make that ledger +legible: *who* produced *what*, against *which* version, and what needs a human's +judgment next. The look follows from that — quiet, exact, and honest, with the +authority of a well-kept engineering record rather than the shine of a product +demo. Warmth comes from a single muted sage-green voice and a humanist type +family, never from decoration. + +The reference feel is **Linear-grade precision**: fast, low-chrome, keyboard- +comfortable, tight but never cramped. Reading is the primary act here — plans, +implementations, and reviews are long-form prose and code — so the surface is a +near-pure white that reads like a clean PR or document view, and body contrast is +never sacrificed for elegance. Density is welcome where it serves scanning (a +goal's artifact timeline, a member table); it is never density for its own sake. + +This system **explicitly rejects** three things named in the product brief. It is +not a *generic AI-SaaS dashboard* — no purple gradients, glassy cards, hero-metric +tiles, repeated icon+heading+text grids, or an eyebrow above every section. It is +not a *heavy enterprise tool* — no cluttered toolbars, nested config panels, or +gray-on-gray density-for-density's-sake. And though Radial runs on a decentralized +protocol, it is **not a web3/crypto aesthetic** — no neon-on-black, hexagon +motifs, or blockchain theatrics. It reads as a developer tool built by people who +respect the person using it. + +**Key Characteristics:** +- Near-pure white surface (light default); dark theme is a first-class peer, not an afterthought. +- One accent — muted sage green — on ≤10% of any screen. Everything else is neutral ink and hairlines. +- One humanist sans (IBM Plex Sans) + one mono (IBM Plex Mono). Mono is semantic: it marks machine identifiers (at:// URIs, CIDs, commit hashes, code). +- Provenance is always visible: attribution and exact version are surfaced, never buried. +- Motion is responsive, not choreographed: 150–250 ms state transitions, no page-load sequences, reduced-motion honored. + +## 2. Colors + +A neutral surface carrying a single green voice, plus a small, disciplined +semantic vocabulary for verdicts and status. Chroma is rationed: green is the only +brand hue, and it appears sparingly. + +### Primary +- **Sage** (`oklch(0.52 0.11 148)`): the one brand voice. Primary buttons, the current selection, active navigation, focus accents. On a white surface it carries actions and "where I am" — nothing decorative. +- **Sage Deep** (`oklch(0.45 0.11 148)`): hover/active state of primary controls, and the color of green text on white (links, active labels) where the lighter Sage would miss 4.5:1. +- **Sage Wash** (`oklch(0.95 0.03 148)`): the tint behind a selected row, a hovered list item, or the current artifact in a timeline. A background signal, never text. + +### Neutral +- **Canvas** (`oklch(1 0 0)`): the page background. Pure white — warmth is carried by the accent and type, never by a tinted surface. +- **Surface** (`oklch(0.975 0 0)`): panels, toolbars, the second layer that sits on canvas (member tables, the sign-in card). A pure neutral gray, not a warm tint. +- **Subtle** (`oklch(0.955 0 0)`): code/pre backgrounds, table zebra, inline fills, secondary button rest. +- **Border** (`oklch(0.905 0 0)`): hairline dividers and control strokes at rest. +- **Border Strong** (`oklch(0.82 0 0)`): input focus stroke, emphasized separators. +- **Ink** (`oklch(0.27 0 0)`): primary text. ~12:1 on canvas. +- **Ink Muted** (`oklch(0.52 0 0)`): secondary text and **placeholder text** — held at ≥4.5:1 on canvas deliberately, not lightened for elegance. +- **Ink Subtle** (`oklch(0.58 0 0)`): timestamps and de-emphasized metadata only. Never body copy, never placeholder. + +### Semantic (status & verdicts) +- **Approve / Merged** — text `oklch(0.45 0.12 150)`, wash `oklch(0.95 0.04 150)`: an approving review, a passing check, a merged artifact. +- **Request Changes / Fail** — text `oklch(0.50 0.16 27)`, wash `oklch(0.95 0.05 27)`: a request-changes verdict, a failing check. +- **Open / Awaiting** — text `oklch(0.52 0.10 75)`, wash `oklch(0.94 0.05 80)`: an open request or an awaiting-input state (a *waiting* signal, distinct from failure — do not reuse the red). + +### Named Rules +**The One Voice Rule.** Sage green is the only brand hue and appears on ≤10% of any screen — primary actions, current selection, active nav. Its rarity is what makes "the next action" and "where I am" instantly findable. A screen that is visibly green has failed. + +**The Verdict-Is-Not-Color Rule.** Approve is green, request-changes is red, and roughly 1 in 12 readers cannot reliably tell them apart. Every verdict, check, and status **must** pair its color with a text label and/or a shape (✓ / ✕ / dot). Color is reinforcement, never the sole carrier of meaning. + +**The Honest-Surface Rule.** The background is pure neutral (chroma 0). Warmth lives in the sage accent and the Plex type, never in a tinted "warm white" — that warm-neutral band is the AI cliché this brand rejects. + +## 3. Typography + +**Display / Body Font:** IBM Plex Sans (with `system-ui, -apple-system, sans-serif`) +**Label/Mono Font:** IBM Plex Mono (with `ui-monospace, SFMono-Regular, monospace`) + +**Character:** One humanist superfamily, sans + mono, sharing a skeleton so the two never fight. Plex Sans is technical but warm — a little humanist softness keeps it from feeling like a corporate default — and Plex Mono gives machine identifiers an honest, unmistakable texture. The contrast axis is proportional-vs-monospace, not two lookalike sans. + +### Hierarchy +- **Display** (600, 1.75rem, 1.2): the page/goal title. One per screen. Product UI doesn't shout — this is the ceiling, not a hero. +- **Headline** (600, 1.25rem, 1.3): section headings (Members, Requests, Artifacts, Thread). +- **Title** (600, 1rem, 1.4): card and subsection headings (an artifact card's type line, a project name). +- **Body** (400, 0.9375rem/15px, 1.55): prose, form help, thread messages. Cap prose at **65–75ch**; artifact bodies and data may run denser. +- **Label** (600, 0.75rem, +0.01em, sentence case): form labels, badge text, table headers. **Sentence case, not tracked uppercase.** +- **Code** (400, 0.8125rem, mono): at:// URIs, CIDs, commit hashes, branch names, and artifact/review bodies that contain code. + +### Named Rules +**The Mono-Means-Machine Rule.** Monospace is reserved for strings a machine produced or consumes — URIs, CIDs, commit hashes, code. Never use mono for emphasis or flavor; its job is to signal "this is an exact identifier, copy it verbatim." + +**The No-Eyebrow Rule.** No tiny uppercase letter-spaced kicker above sections. Labels are sentence case. The 2023 eyebrow trope is an AI tell and is prohibited here. + +## 4. Elevation + +Flat by default. Depth is carried by hairline borders and the tonal step between +Canvas and Surface, not by shadows. This is a reading surface; resting shadows add +noise and read as "2014 app." Shadows appear **only** on elements that float above +the page by necessity — dropdowns, dialogs, popovers, toasts — where a soft +shadow communicates "this is temporarily on top." + +### Shadow Vocabulary +- **Overlay** (`box-shadow: 0 8px 24px -6px rgba(0,0,0,0.18), 0 2px 6px -2px rgba(0,0,0,0.10)`): dropdowns, popovers, dialogs. The only shadow most screens ever show. +- **Sticky Edge** (`box-shadow: 0 1px 0 var(--border)`): a sticky header/toolbar's bottom edge on scroll — a hairline, not a drop shadow. + +### Named Rules +**The Flat-By-Default Rule.** Surfaces are flat at rest. A shadow is a response to *floating* (overlay) or *scroll* (sticky edge), never a decoration on a resting card. If a card has a resting drop shadow, delete it. + +## 5. Components + +Every interactive component ships all its states: default, hover, focus-visible, +active, disabled, and — where it applies — loading and error. Half a component is +a bug. + +### Buttons +- **Shape:** gently rounded (6px, `{rounded.md}`). +- **Primary:** Sage background, Canvas text, `8px 14px` padding. The one high-emphasis action per context (Create, Submit, Post review). +- **Hover / Focus:** hover deepens to Sage Deep; `:focus-visible` shows a 2px Sage ring offset 2px. 150 ms ease-out on background; no transform bounce. +- **Secondary:** Subtle background, Ink text — for lower-emphasis actions (Add member, Open, Archive). Ghost (transparent, Ink Muted text) for tertiary/destructive-adjacent actions. +- **Disabled:** Subtle background, Ink Subtle text, no hover. Never a faded Sage. + +### Chips / Badges (signature) +- **Verdict & status badges:** pill (`{rounded.pill}`), `1px 8px`, Label type. Wash background + matching text from the semantic set. **Always carry a word** (approve / changes / open / merged) — and, where two greens could collide (brand vs approve), a leading ✓/✕/dot. +- **URI chip:** the recurring `at://…` / CID / commit affordance. Subtle background, Ink Muted mono text, 4px radius, `1px 5px`. Shows the short rkey/hash; full value in `title` and on click-to-copy. This is Radial's most-repeated element — it must be quiet, scannable, and copyable. + +### Cards / Containers +- **Corner Style:** 10px (`{rounded.lg}`) for panels/artifact cards; 6px for inner controls. +- **Background:** Surface on Canvas. **Never nest a card inside a card** — use a hairline divider or spacing instead. +- **Shadow Strategy:** none at rest (see Elevation). Structure comes from a 1px Border and internal padding (`{spacing.lg}`–`{spacing.xl}`). +- **The Artifact Card (signature):** the core object. A type line (`plan artifact`, `implementation artifact`) + URI chip + inline verdict/check/merged badges, then provenance (revises …, branch/commit/PR), then the body in a mono/prose block, then the per-type request actions. Attribution and exact CID live in the header, never hidden. + +### Inputs / Fields +- **Style:** Canvas background, 1px Border stroke, 6px radius, `7px 10px` padding, Body type. +- **Focus:** border shifts to Sage + a 2px Sage ring (no glow). 150 ms. +- **Placeholder:** Ink Muted (≥4.5:1) — never Ink Subtle. +- **Error:** Request-Changes red stroke + a text message below; color is never the only signal. +- **Textareas** (artifact/message bodies): mono, min 4rem, comfortable measure. + +### Navigation +- **Style:** a slim top bar (Radial mark + current context) over a max-width content column (~900px for reading comfort). Links are Ink at rest, Sage when active; active state also carries a non-color cue (weight or an underline/rail). Keyboard-focusable with a visible Sage ring. +- **Mobile:** the top bar collapses; content is a single column. Responsive behavior is structural (stack, collapse), never fluid heading type. + +### Empty & Loading States +- **Empty states teach the next action** ("No requests yet — request an artifact to start the loop"), not "nothing here." +- **Loading** uses skeleton rows that match the timeline/table shape, not a centered spinner. + +## 6. Do's and Don'ts + +### Do: +- **Do** keep Sage green on ≤10% of any screen — actions, current selection, active nav only (**The One Voice Rule**). +- **Do** pair every verdict/status with a word and/or a ✓/✕/dot, so approve-vs-changes survives color blindness (**The Verdict-Is-Not-Color Rule**). +- **Do** hold body and placeholder text at ≥4.5:1 — use Ink Muted (`oklch(0.52 0 0)`), never a lighter gray "for elegance." +- **Do** reserve mono for machine identifiers (at:// URIs, CIDs, commit hashes, code) — it's a signal, not a style (**The Mono-Means-Machine Rule**). +- **Do** keep surfaces flat at rest; shadows only for floating overlays (**The Flat-By-Default Rule**). +- **Do** make provenance visible on every artifact — author, exact CID, revises-lineage. +- **Do** honor `prefers-reduced-motion`: replace every transition with a crossfade or instant change. + +### Don't: +- **Don't** build a **generic AI-SaaS dashboard**: no purple gradients, glassy/glassmorphic cards, hero-metric tiles, repeated icon+heading+text card grids, or gradient text. +- **Don't** slip toward a **heavy enterprise tool**: no cluttered toolbars, nested config panels, modal-on-modal flows, or gray-on-gray density-for-density's-sake. Exhaust inline/progressive alternatives before reaching for a modal. +- **Don't** adopt a **web3/crypto aesthetic**: no neon-on-black, hexagon motifs, or blockchain theatrics. This is a developer tool, not a token project. +- **Don't** put a tiny uppercase letter-spaced **eyebrow** above sections (**The No-Eyebrow Rule**), and don't number sections as decorative scaffolding. +- **Don't** use `border-left`/`border-right` > 1px as a colored accent stripe on cards, list items, or alerts. Use a full border, a wash background, or a badge. +- **Don't** nest a card inside a card. Use dividers and spacing. +- **Don't** give resting cards a drop shadow, or run page-load animation sequences — users load into a task, not a demo. +- **Don't** let a heading overflow its container at any breakpoint; the fixed rem scale exists so it never does. diff --git a/PRODUCT.md b/PRODUCT.md new file mode 100644 --- /dev/null +++ b/PRODUCT.md @@ -0,0 +1,96 @@ +# Product + +## Register + +product + +## Users + +Software builders coordinating work with coding agents — the humans who +commission and review artifacts, and the operators who run daemons and agent +identities. They are technical: they read at:// URIs, git commits, PR links, and +review verdicts fluently, and they care about correctness and attribution. + +Their context is a working session, not a passive browse: they open the app to +define a goal, request a typed artifact against it (a plan, an implementation, a +review), watch an agent fulfill it, judge the exact version that landed, and ask +for changes or approve. Agents are first-class actors in the system but are *not* +users of this UI — every screen is built for the human on the initiating and +reviewing side of the loop. + +The primary task on any given screen is: **understand the current state of a +goal, and take the next attributable action on it.** + +## Product Purpose + +Radial coordinates humans and coding agents on software goals through +human-initiated, reviewable units of work. Every unit of agent work is requested +by a human and lands as a signed, versioned artifact; reviews pin the exact +version they judged. All coordination state lives in each actor's atproto repo, +so there is no privileged central server — the UI is one materializer of the +record stream, not the source of truth. + +The app's job is to turn that protocol into something a person can drive by +sight: goal timelines, per-type request buttons, artifact cards with their +reviews and checks, review queues, and threads. Success is when a human can see +who produced what, against which version, and what needs their judgment next — +without reading raw records. + +The current `packages/ui` is an explicitly throwaway Phase-6 *preview* (server- +rendered HTML, zero deps, "don't build on it"). The real surface is the planned +Phase-6 SvelteKit app; this document is written to guide that build. + +## Brand Personality + +**Technical but warm.** Rigorous underneath — exact versions, honest state, +visible attribution — but approachable and human on the surface. The voice is +precise and confident, like the design doc that spawned it (opinionated enough to +kill a bad state-machine and say why), yet the copy is plain and friendly, never +cold or intimidating. It should feel like a serious tool built by people who +respect the person using it. Three words: **precise, honest, humane.** + +Emotional goals: *confidence* (I can trust what I'm seeing and who did it), +*clarity* (I always know the next action), and *calm* (the tool doesn't shout or +manufacture urgency). + +## Anti-references + +- **Generic AI-SaaS dashboard.** No purple gradients, glassy cards, hero-metric + tiles, repeated icon+heading+text card grids, or an eyebrow above every + section. This is the "AI made this" look and it is explicitly off-limits. +- **Heavy enterprise tool** (Jira / ServiceNow). No cluttered toolbars, nested + config panels, modal-on-modal flows, or gray-on-gray density-for-density's- + sake. Powerful without being joyless or slow to read. +- **Web3 / crypto aesthetic.** Even though Radial runs on a decentralized + protocol, it must read as a developer tool, not a token project: no neon-on- + black, hexagon motifs, or "blockchain" visual clichés. +- **Consumer social feed** framing (avatars, reactions, infinite algorithmic + feed) — the wrong mental model for an artifact/review tool. + +## Design Principles + +- **Attribution is always visible.** Every action is a signed record by a DID + against an exact version. Who did what, on precisely which artifact CID, must + be legible at a glance — provenance is a feature, not fine print. +- **Reviews annotate, they don't gate.** The protocol enforces no pipeline, so + the UI must not fake one. Surface soft signals (e.g. an implementation + requested off an unapproved plan) as information, never as a hard block. +- **Humans initiate; make the next action obvious.** The "workflow" lives in + human heads and in the templates behind buttons. The UI's job is to present the + right typed action at the right moment on the right version — not to author or + police a state machine. +- **Legible density over dashboard theater.** This is a working tool people drive + in sessions. Favor scannable timelines and honest state badges over decorative + cards and vanity metrics; earn every pixel of chrome. +- **Eventually consistent, honestly.** Coordination converges at network speed + from independent repos. Show freshness and state truthfully rather than + implying a realtime certainty the system doesn't provide. + +## Accessibility & Inclusion + +Target **WCAG 2.2 AA**. Body text ≥4.5:1 against its background (≥3:1 for large +text); no muted-gray-on-tint traps. Full keyboard operability for every action +(request, review, thread, navigate) with visible focus. Honor +`prefers-reduced-motion` on every animation with a crossfade or instant +fallback. Don't encode state in color alone — pair verdict/status color with a +label or icon, since approve/changes distinctions must survive color-blindness. -- tangled.sh