diff --git a/.planning/phases/21-chat-foundation/21-UI-SPEC.md b/.planning/phases/21-chat-foundation/21-UI-SPEC.md index b5e95472..be1462a5 100644 --- a/.planning/phases/21-chat-foundation/21-UI-SPEC.md +++ b/.planning/phases/21-chat-foundation/21-UI-SPEC.md @@ -5,6 +5,7 @@ status: draft shadcn_initialized: true preset: new-york / neutral / cssVariables created: 2026-04-01 +revised: 2026-04-01 --- # Phase 21 — UI Design Contract @@ -33,6 +34,12 @@ None required — all necessary primitives are available. `Textarea` covers `Cha --- +## Focal Point + +The primary focal point of this phase is the **chat input** at the bottom of the ChatPanel. When the panel opens, focus moves immediately to the `ChatInput` textarea. All surrounding elements (conversation list, message thread, header) are secondary supporting surfaces. + +--- + ## Spacing Scale Declared values (multiples of 4 only). Source: 8-point scale, confirmed via existing `p-4 md:p-6` usage in `Layout.tsx`. @@ -41,15 +48,16 @@ Declared values (multiples of 4 only). Source: 8-point scale, confirmed via exis |-------|-------|-------| | xs | 4px | Icon gaps (`gap-1`), inline icon + label spacing | | sm | 8px | Compact padding inside list items (`px-2 py-1`), badge padding | -| md | 16px | Default element padding (`p-4`), conversation list item padding | -| lg | 24px | Section padding on desktop (`p-6`), chat panel header padding | +| sm+ | 12px | Conversation list item vertical padding (`py-3`) — named exception; follows existing `EntityRow` pattern; sits between sm and md | +| md | 16px | Default element padding (`p-4`), chat panel header padding | +| lg | 24px | Section padding on desktop (`p-6`) | | xl | 32px | Gap between major UI zones | | 2xl | 48px | Empty-state vertical padding (`py-12`) | | 3xl | 64px | Page-level section breaks (not applicable in panel context) | Exceptions: +- `sm+` (12px) is a named token for conversation list item vertical padding. Justification: follows the existing `EntityRow` pattern throughout the codebase. It is not a one-off magic number — it is a deliberate in-between value that keeps list items readable without wasting vertical space. Only use `sm+` for list item vertical padding. - Touch targets on coarse-pointer devices: `min-height: 44px` (already enforced globally in `index.css` `@media (pointer: coarse)`) -- Sidebar conversation list item: 12px vertical padding (`py-3`) — between sm and md — acceptable as it follows existing `EntityRow` pattern - Chat input bottom padding: `pb-[calc(env(safe-area-inset-bottom)+16px)]` on mobile to clear the home indicator --- @@ -58,19 +66,22 @@ Exceptions: All sizes use Tailwind utility classes mapped to the project's system-UI font stack. Source: observed usage in `Layout.tsx`, `EmptyState.tsx`, `MarkdownBody.tsx`. +Two weights only: regular (400) and semibold (600). Medium (500) is not used in this phase. + | Role | Size | Weight | Line Height | Tailwind Class | |------|------|--------|-------------|----------------| | Body | 14px | 400 (regular) | 1.5 | `text-sm` | -| Label | 13px | 500 (medium) | 1.4 | `text-[13px] font-medium` | +| Label | 13px | 400 (regular) | 1.4 | `text-[13px]` | | Heading | 16px | 600 (semibold) | 1.25 | `text-base font-semibold` | | Meta / Timestamp | 12px | 400 (regular) | 1.4 | `text-xs text-muted-foreground` | Rules: -- Conversation titles in the sidebar use Label (13px / medium). +- Conversation titles in the sidebar use Label (13px / regular). Do not apply `font-medium` or `font-semibold` to conversation titles — regular weight at 13px provides sufficient legibility without visual noise. - Agent message content renders inside `MarkdownBody` which applies `prose prose-sm` — do not override prose typography for markdown content. -- The chat input `Textarea` uses body (14px / regular). +- The chat input `Textarea` uses Body (14px / regular). - Section headers inside the chat panel (e.g. "Conversations") use Heading (16px / semibold). - Timestamps and message count badges use Meta (12px / regular / muted-foreground). +- Active conversation title in the sidebar: do NOT use `font-semibold` to indicate active state. Use the left-border accent indicator instead (see Color contract). --- @@ -89,7 +100,7 @@ All colors reference CSS custom properties already declared for all three themes | Border | `--border` | — | Dividers between message groups, chat panel border, input border | Accent (`--primary`) is reserved for exactly these elements: -1. The "Send" / "New conversation" primary action button background +1. The "Send message" / "New conversation" primary action button background 2. The active conversation in the sidebar (left-border indicator: `border-l-2 border-primary`) 3. Filled pin icon on pinned conversations @@ -118,10 +129,10 @@ Components to build for this phase. Each references the design token contract ab ### ChatConversationList (inside ChatPanel left column, width: 240px) - Background: `bg-sidebar` (secondary surface) -- Item height: 48px (`py-3 px-3`) +- Item height: 48px (`py-3 px-3`) — uses `sm+` (12px) vertical padding token - Active item: `border-l-2 border-primary bg-sidebar-accent` - Hover item: `bg-sidebar-accent/50` -- Title: Label (13px / medium), truncated with `truncate` +- Title: Label (13px / regular), truncated with `truncate` - Timestamp: Meta (12px / muted-foreground), right-aligned - Pin icon: 14px, `text-primary` when active - Archive icon: 14px, `text-muted-foreground` @@ -147,7 +158,7 @@ Components to build for this phase. Each references the design token contract ab - Component: `